:root {
  --green: #2e7d32;
  --green-dark: #1b5e20;
  --red: #d32f2f;
  --bg: #f4f6f4;
  --border: #d7ddd7;
  --text: #1c241c;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: "Segoe UI", Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
}
.hidden { display: none !important; }

/* login */
.login-wrap {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.login-copy { margin-top: 14px; text-align: center; font-size: 12px; color: #666; }
.login-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 32px;
  width: 100%;
  max-width: 380px;
  box-shadow: 0 8px 24px rgba(0,0,0,.08);
}
.login-card h1 { margin: 0 0 4px; font-size: 20px; color: var(--green-dark); }
.login-logo { width: 120px; display: block; margin: 0 auto 10px; }
.bar-logo { height: 36px; width: auto; border-radius: 50%; background: #fff; }
.bar-logo.logo-admin { border-radius: 8px; padding: 2px; box-sizing: border-box; object-fit: contain; }
.login-card p.sub { margin: 0 0 20px; font-size: 13px; color: #666; }
.linkish { background: none; border: none; color: var(--green-dark); font-size: 13px; cursor: pointer; padding: 0; text-decoration: underline; }
.linkish:hover { opacity: .75; }
.login-help { margin-top: 14px; padding: 10px 12px; border: 1px solid #e6c76a; background: #fdf8e7; border-radius: 8px; }
.login-help p { margin: 0 0 8px; font-size: 12.5px; line-height: 1.45; color: #5b4708; }
.login-help .btn { display: block; width: 100%; }

/* layout */
.topbar {
  background: var(--green-dark);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 20px;
  flex-wrap: wrap;
}
.topbar .brand { font-weight: 700; font-size: 16px; }
.topbar nav { display: flex; gap: 4px; flex-wrap: wrap; }
.topbar nav button, .topbar nav a {
  background: transparent;
  color: #e8f5e9;
  border: none;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}
.topbar nav a { text-decoration: none; display: inline-block; font-family: inherit; line-height: normal; }
.topbar nav button.active, .topbar nav button:hover, .topbar nav a.active, .topbar nav a:hover { background: var(--green); color: #fff; }
/* The header is allowed to wrap, so the right-hand controls have to travel as one unit: a bell that
   lands on the next line is no longer beside Logout. */
.topbar .bar-right { display: flex; align-items: center; gap: 10px; flex-wrap: nowrap; margin-left: auto; }
.topbar .company-switch {
  background: #fff; color: #222; border: 1px solid rgba(255,255,255,.4);
  border-radius: 6px; padding: 5px 8px; font-size: 13px; max-width: 220px;
}

main { padding: 20px; max-width: none; margin: 0; }
.card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 18px;
  margin-bottom: 18px;
}
.card h2 { margin: 0 0 14px; font-size: 17px; color: var(--green-dark); }

/* forms */
label { display: block; font-size: 12px; font-weight: 600; margin: 8px 0 4px; color: #444; }
input, select, textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  font-family: inherit;
}
input:focus, select:focus, textarea:focus { outline: 2px solid #a5d6a7; border-color: var(--green); }
input.invalid { border-color: #e57373; background: #fff5f5; }
input[readonly], select:disabled { background: #eef1ee; color: #555; cursor: not-allowed; }
/* A derived total is shown rather than typed, so it reads as the month's answer line - a green
   figure, not a box somebody locked. It must sit under the readonly rule above to win on it. */
input.calcout { background: #eaf5ec; border-color: #b8d9bf; color: var(--green-dark); font-weight: 700; cursor: default; }
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; appearance: textfield; }
input[list] {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23555' stroke-width='2'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 30px;
}
.combo { position: relative; }
.combo input { padding-right: 34px; }
.combo-toggle { position: absolute; top: 1px; right: 1px; bottom: 1px; width: 30px; padding: 0; border: none; background: transparent; color: #555; font-size: 12px; line-height: 1; cursor: pointer; border-radius: 0 6px 6px 0; }
.combo-toggle:hover { background: #eef1ee; }
.combo-pop { position: absolute; top: calc(100% + 3px); left: 0; right: 0; z-index: 70; background: #fff; border: 1px solid #c8c8c8; border-radius: 6px; max-height: 220px; overflow: auto; box-shadow: 0 4px 14px rgba(0,0,0,.18); }
.combo-opt { display: block; width: 100%; text-align: left; padding: 8px 12px; border: none; background: #fff; font: inherit; font-size: 14px; color: var(--text); cursor: pointer; }
.combo-opt:hover { background: #eaf5ea; }
.combo-empty { padding: 9px 12px; font-size: 12.5px; color: #666; line-height: 1.45; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0 14px; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

button.btn, a.btn {
  background: var(--green);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 9px 16px;
  font-size: 14px;
  cursor: pointer;
}
a.btn { text-decoration: none; display: inline-block; font-family: inherit; line-height: normal; text-align: center; }
button.btn:hover, a.btn:hover { background: var(--green-dark); }
button.btn.secondary, a.btn.secondary { background: #607d8b; }
button.btn.danger, a.btn.danger { background: var(--red); }
button.btn.small, a.btn.small { padding: 5px 10px; font-size: 12px; }
button.btn:disabled { opacity: .5; cursor: not-allowed; }

.searchbar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.searchbar input { flex: 1; min-width: 130px; }
.mspop input[type="checkbox"] { flex: 0 0 auto; min-width: auto; width: auto; }
/* The permission editor's switches sit beside their words, not stretched across the row like a text box. */
#permModal input[type="checkbox"] { width: auto; min-width: auto; flex: 0 0 auto; margin: 0; }

#glDateRow { align-items: flex-end; margin-bottom: 14px; }
#view-guestlist .searchbar { margin-bottom: 6px; }
#view-guestlist .searchbar .hint { margin: 0; }
.gl-search { flex: 1 1 320px; min-width: 300px; }
.gl-search .searchfields { margin: 0 0 4px; }
.gl-search-box { display: flex; gap: 10px; align-items: stretch; }
.gl-search-box input { flex: 1; min-width: 120px; }
.gl-search-box .btn { flex: none; }
.searchfields { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; margin: -4px 0 12px; font-size: 13px; }
.searchfields label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.searchfields .sf-lbl { font-weight: 600; color: #555; }

/* table */
.table-wrap { overflow-x: auto; }
.tw-float { position: relative; }
.tw-scrollbtn { position: fixed; top: 50%; transform: translateY(-50%); z-index: 100; width: 38px; height: 38px; border: none; border-radius: 50%; background: rgba(17, 40, 17, .85); color: #fff; font-size: 24px; line-height: 36px; text-align: center; cursor: pointer; opacity: .9; padding: 0; box-shadow: 0 2px 8px rgba(0,0,0,.3); }
.tw-scrollbtn:hover { opacity: 1; background: rgba(17, 40, 17, 1); }
.tw-scrollbtn.left { left: 12px; }
.tw-scrollbtn.right { right: 12px; }
.page-endbtn { position: fixed; right: 16px; bottom: 16px; z-index: 100; width: 44px; height: 44px; border: none; border-radius: 50%; background: rgba(17, 40, 17, .85); color: #fff; font-size: 22px; line-height: 42px; text-align: center; cursor: pointer; opacity: .9; padding: 0; box-shadow: 0 2px 8px rgba(0,0,0,.3); }
.page-endbtn:hover { opacity: 1; background: rgba(17, 40, 17, 1); }
.page-endbtn.hidden { display: none; }
/* Guest cells hold text the desk copies all day, so the pointer must read as text. The row is only
   draggable after a hold, and that is when the hand appears - see enableGuestRowDrag in app.js. */
table.data tbody tr[data-gid] { cursor: text; }
table.data tbody tr[data-gid].drag-armed { cursor: grab; }
table.data tbody tr[data-gid].drag-armed button { cursor: grabbing; }
table.data tbody tr[data-gid] button { cursor: pointer; }
table.data tbody tr.dragging { cursor: grabbing; }
/* Guest Name / Cell No. / NRIC are copied all day: a press that starts in one of those cells is
   never handed to the row drag, so it always reads and behaves as selectable text. */
table.data tbody td.copyable { cursor: text; user-select: text; -webkit-user-select: text; }
/* One press on a guest name copies it, so the cell asks for the pointer; the flash is the receipt. */
table.data tbody td.click-copy { cursor: pointer; }
table.data tbody td.click-copy.copied { background: #dff0d8; }
.draghandle { cursor: grab; color: #9aa79a; font-size: 15px; letter-spacing: -1px; user-select: none; padding: 0 4px; }
.draghandle:hover { color: var(--green); }
.draghandle.disabled { cursor: default; opacity: .25; }
table.data tbody tr.dragging { opacity: .45; }
table.data tbody tr.drop-above td { box-shadow: inset 0 3px 0 #1b5e20; }
table.data tbody tr.drop-below td { box-shadow: inset 0 -3px 0 #1b5e20; }
@media print { .tw-scrollbtn, .page-endbtn, .draghandle { display: none !important; } }
table.data { border-collapse: collapse; width: 100%; font-size: 13px; }
table.data th, table.data td { border: 1px solid var(--border); padding: 7px 9px; text-align: left; white-space: nowrap; }
table.data thead th { background: var(--green); color: #fff; position: sticky; top: 0; }
table.data tbody tr:nth-child(even) { background: #f7faf7; }
table.data tbody tr:hover { background: #e8f5e9; }
/* The row the desk last clicked stays marked on every page until they click another one. It has to
   beat the zebra and the hover, so it wins on specificity and paints the cells, not the row. */
table.data tbody tr.row-selected, table.data tbody tr.row-selected:nth-child(even),
table.data tbody tr.row-selected:hover { background: #ffe9b3; }
table.data tbody tr.row-selected > td:first-child { box-shadow: inset 4px 0 0 var(--green); }
@media print { table.data tbody tr.row-selected, table.data tbody tr.row-selected:hover { background: transparent; } table.data tbody tr.row-selected > td:first-child { box-shadow: none; } }
td.num, th.num { text-align: right; }
.entered { font-size: 11px; color: #8a8a8a; margin-top: 2px; white-space: nowrap; }
.empty { padding: 20px; color: #777; font-style: italic; }
.thumb { width: 38px; height: 38px; object-fit: cover; border-radius: 4px; border: 1px solid var(--border); display: block; }
#gPhotoPreview { max-width: 140px; max-height: 140px; margin-top: 8px; border-radius: 6px; border: 1px solid var(--border); object-fit: cover; }
.entryblock { border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; margin: 10px 0; }
/* Fixed 4 equal columns so every stay/extra box matches the first row's size (the extra row
   leaves its 4th cell empty instead of stretching its 3 boxes wider). */
.entryblock .grid { grid-template-columns: repeat(4, 1fr); }
.entryhead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; }
.entrytitle { font-weight: 600; font-size: 13px; color: var(--green-dark); }
.totalrow { display: flex; justify-content: flex-end; align-items: center; gap: 12px; margin: 6px 0 2px; font-size: 14px; }
.totalrow strong { font-size: 16px; color: var(--green-dark); min-width: 110px; text-align: right; }
/* Extra charges (Admin Setup) + the automatic strip on the New Guest form */
.charge-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 14px 0 8px; }
.charge-count { font-size: 12px; font-weight: 700; color: var(--green-dark); background: #e7f2e8; border-radius: 999px; padding: 3px 11px; }
.charge-count.zero { color: #666; background: #ececec; }
.charge-who { font-size: 12.5px; color: #5c665c; }
.charge-status { display: inline-flex; align-items: center; gap: 7px; border: 0; background: none; padding: 0; font-size: 13px; font-weight: 600; cursor: pointer; }
.charge-dot { width: 26px; height: 15px; border-radius: 999px; background: #c9cfc9; position: relative; transition: background .15s; }
.charge-dot::after { content: ""; position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 50%; background: #fff; transition: left .15s; }
.charge-status.on { color: var(--green-dark); }
.charge-status.on .charge-dot { background: var(--green); }
.charge-status.on .charge-dot::after { left: 13px; }
.charge-status.off { color: #777; }
.charge-tag { font-size: 11px; font-weight: 700; color: #5c665c; background: #eef1ee; border-radius: 6px; padding: 1px 6px; margin-left: 6px; vertical-align: 1px; }
.autobox { border: 1px solid var(--border); background: #fafbfa; border-radius: 8px; padding: 8px 12px; margin: 10px 0 2px; font-size: 13px; }
.autobox .auto-title { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #6a746a; margin-bottom: 4px; }
.auto-line { display: flex; justify-content: space-between; gap: 12px; padding: 2px 0; }
.auto-line .auto-name { flex: 1; }
.auto-line .auto-qty { color: #6a746a; white-space: nowrap; }
.auto-line .auto-amt { min-width: 86px; text-align: right; font-variant-numeric: tabular-nums; }
/* Per-charge quantity boxes on New Guest / Edit Guest (one per ACTIVE charge). */
.chargebox-hint { margin: 0 0 8px; font-size: 12px; }
.chargebox-note { font-size: 11.5px; color: #6a746a; margin-top: 4px; line-height: 1.4; }
.chargebox-note.off { color: #9a9f9a; }
.reqnote { margin-top: 6px; font-size: 12px; font-weight: 700; color: #b3261e; }
#gPhotoName { display: block; margin-top: 4px; font-size: 12px; color: #555; }
a.pdflink { font-size: 11px; font-weight: 700; color: var(--green-dark); }
button.photobtn { background: none; border: none; padding: 0; cursor: pointer; }
button.photobtn:hover { outline: 2px solid var(--green); border-radius: 4px; }
button.photobtn.pdflink { font-size: 11px; font-weight: 700; color: var(--green-dark); text-decoration: underline; }
.icmodal { max-width: 760px; }
.icimg { display: block; margin: 0 auto; max-width: 100%; max-height: 68vh; object-fit: contain; border: 1px solid var(--border); border-radius: 6px; }
.icframe { width: 100%; height: 68vh; border: 1px solid var(--border); border-radius: 6px; }
.icview { margin: 10px 0; }
/* An expense row whose slip is already on file reads differently from one nobody has proved yet. */
.data td button.has-file { border-color: var(--green); color: var(--green-dark); font-weight: 700; }
#printArea img { display: block; margin: 0 auto; max-width: 100%; max-height: 180mm; object-fit: contain; }

/* modal */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.45);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 30px 16px; overflow-y: auto; z-index: 50;
}
#companyModal { z-index: 60; }
.modal {
  background: #fff; border-radius: 10px; padding: 22px;
  width: 100%; max-width: 760px;
}
.modal h3 { margin: 0 0 14px; color: var(--green-dark); }
.modal .actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
/* The staff card carries statutory numbers, contact details and its documents in one place, so it
   gets a wider sheet than the two-box dialogs. */
.modal.modal-wide { max-width: 1000px; }
/* The leave popup is the paper sheet itself, so inside the modal the sheet gives up its own frame and
   lets the modal be the card - one border, one padding, the same boxes as on the page. */
#leaveFormModal .modal { max-width: 830px; }
#leaveFormModal .lf-sheet { max-width: none; border: 0; border-radius: 0; padding: 0; background: transparent; }

/* per-room checkout picker — whole row is the tap target so a desk with a phone never aims at a box */
#checkoutModal .modal { max-width: 520px; }
.corooms { display: grid; gap: 8px; margin-top: 6px; }
.coroom {
  display: grid; grid-template-columns: 22px minmax(0, 1fr) minmax(0, 1.6fr) auto;
  align-items: center; gap: 10px; min-height: 44px;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
}
.coroom:hover { border-color: var(--green); }
.coroom:has(input:checked) { border-color: var(--green); background: #e8f5e9; }
.coroom input { width: 20px; height: 20px; margin: 0; cursor: pointer; }
.coroom input:focus-visible { outline: 2px solid var(--green-dark); outline-offset: 2px; }
.coroom-no { font-weight: 700; }
.coroom-dates, .coroom-deposit { font-size: 13px; color: #4a554a; }
.coroom-deposit { text-align: right; white-space: nowrap; }
@media (max-width: 600px) {
  .coroom { grid-template-columns: 22px 1fr auto; }
  .coroom-dates { grid-column: 2 / 4; }
}

.msg { padding: 9px 12px; border-radius: 6px; margin: 10px 0; font-size: 13px; }
.msg.error { background: #ffebee; color: #b71c1c; border: 1px solid #ef9a9a; }
.msg.ok { background: #e8f5e9; color: #1b5e20; border: 1px solid #a5d6a7; }

.stat-row { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 6px; }
.stat {
  background: var(--green); color: #fff; border-radius: 8px;
  padding: 12px 20px; min-width: 160px;
}
.stat .v { font-size: 20px; font-weight: 700; }
.stat .l { font-size: 12px; opacity: .9; }

/* receipt print */
#printArea { display: none; }
@media print {
  /* margin:0 suppresses the browser's printed date/title/URL/page-number band;
     the inset is re-applied as #printArea padding so layout is unchanged.
     Padding = the user's measured sheet margins: top 0.25in, sides 0.71in, bottom 0.30in. */
  @page { size: A5 landscape; margin: 0; }
  html, body { height: auto !important; overflow: visible !important; margin: 0; padding: 0; background: #fff; }
  body > *:not(#printArea) { display: none !important; }
  /* A5 landscape sheet (210x148mm); the receipt fills the 6.85in x 5.28in content box and
     scales down only if the data is too tall to fit, however many stays/extras there are. */
  #printArea { display: flex; position: absolute; inset: 0; padding: 0.25in 0.71in 0.30in; margin: 0; align-items: flex-start; justify-content: center; box-sizing: border-box; }
  #printArea .receipt { zoom: 1; width: 100%; max-width: 100%; display: flex; flex-direction: column; }
  #printArea .receipt > * { flex: 0 0 auto; }
  /* signing zone sits 0.8in below the content (user: "bring the sign down a bit") */
  #printArea .receipt .sign { margin-top: 0.8in; }
  /* The payslip is a different sheet on different paper: it asks for A4 portrait with a 10mm @page
     margin of its own. Stacking the receipt's measured 0.71in side inset on top of that leaves a box
     narrower than the 534pt slip, so the AMOUNT column and the RECEIVED BY rule run off the edge of
     the paper. On that sheet the margin is the page's job - the inset goes to zero and the slip,
     which centres itself with auto margins, stands whole in the middle of the A4. */
  #printArea.ps-print { padding: 0; }
  /* The payment voucher is its own sheet on its own paper, and its @page rule already carries the
     10mm/8mm margin. Adding the receipt's measured inset on top of that made the sheet too narrow to
     fit and pushed the signing block off page 1, so on this sheet the page margin is the inset.
     Centring is side to side only - the left and right gaps must match - while the letterhead stays at
     the top of the paper the way a voucher form reads, rather than floating in the middle. */
  #printArea.pv-print { padding: 0; align-items: flex-start; justify-content: center; }
  /* Several copies of one receipt (branch setting): each copy starts a fresh sheet inside the SAME
     print job, so pressing F9 once never opens the print dialog a second time. */
  #printArea.multi { display: block; position: static; padding: 0; }
  /* The measured inset belongs to EVERY sheet, not the stack: padding on the container is spent on
     page 1 only, which left the second copy's letterhead flush against the top edge of the paper.
     The sheet carries the zoom that fits the receipt, and zoom shrinks fixed lengths too, so the
     inset is divided by it through --iz - otherwise every copy loses top space as soon as the
     receipt is scaled down. */
  #printArea.multi .receipt {
    padding: calc(0.25in * var(--iz, 1)) calc(0.71in * var(--iz, 1)) calc(0.30in * var(--iz, 1));
    box-sizing: border-box; break-after: page; page-break-after: always;
  }
  #printArea.multi .receipt:last-child { break-after: auto; page-break-after: auto; }
}
.receipt { --iz: 1; font-family: "Segoe UI", Arial, sans-serif; color: #000; max-width: 780px; margin: 0 auto; font-size: 13.33pt; }
.receipt .rhead { position: relative; min-height: 68.16px; }
.receipt .rlogo { position: absolute; left: 0; top: 0; width: calc(103.68px * var(--iz)); height: calc(68.16px * var(--iz)); object-fit: contain; }
.receipt .rcenter { text-align: center; line-height: 1.35; }
.receipt .co-name { font-size: 18.66pt; font-weight: 700; max-width: calc(357.07px * var(--iz)); margin: 0 auto; }
.receipt .co-addr { font-size: 13.33pt; white-space: pre-line; }
.receipt .co-line { font-size: 13.33pt; }
.receipt .co-email { margin-top: 10px; }
.receipt .no { text-align: right; font-weight: 700; font-size: 16pt; margin-top: 6px; }
.receipt .no .no-val { color: #d32f2f; font-size: 16pt; margin-left: 12px; }
.receipt .title { text-align: right; font-weight: 700; font-size: 16pt; margin: 6px 0 10px; }
.receipt table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 14.66pt; }
.receipt td { padding: 3px 6px; vertical-align: top; }
.receipt table.plain { margin: 4px 0 8px; table-layout: fixed; }
.receipt table.plain td { border: none; padding: 4px 2px; }
.receipt table.plain td.lbl { font-weight: 700; white-space: nowrap; }
.receipt table.plain td.lbl.rl { text-align: right; }
.receipt table.plain td.coln { font-weight: 700; }
.receipt table.plain td.val { border-bottom: 1px dotted #000; padding: 0 6px 2px; }
.receipt table.plain td.val.off { border-bottom: none; }
.receipt table.plain td.gap { width: 28px; }
.receipt table.box { table-layout: fixed; }
.receipt table.box td { border: 1px solid #000; }
.receipt table.box td.bh { text-align: center; font-weight: 700; white-space: nowrap; }
.receipt table.box td.money { height: 33px; }
.receipt table.box td.fi { text-align: center; font-weight: 700; }
.receipt table.box td.ctr { text-align: center; }
.receipt table.box td.depl { text-align: right; font-weight: 700; }
.receipt table.box td.spanr { text-align: right; font-weight: 700; }
.receipt table.box td.amt { text-align: center; font-weight: 700; }
.receipt table.box td.thanks { border: none; font-style: italic; font-size: 12pt; }
.receipt td.leftcell { padding: 0; }
.receipt .lc-inner { display: flex; flex-direction: column; height: 100%; min-height: 132px; padding: 12px 8px 10px 42px; }
.receipt .lc-line { margin: 4px 0; }
.receipt .lc-lbl { font-weight: 700; display: inline-block; width: 66px; }
.receipt .u { font-weight: 700; border-bottom: 1px solid #000; display: inline-block; min-width: 84px; padding: 0 8px 1px; margin-left: 6px; }
.receipt .lc-to { font-weight: 700; margin: 0 2px 0 8px; }
.receipt .lc-checkout { margin-top: auto; padding-top: 26px; text-align: center; font-weight: 700; font-size: 14.66pt; }
.receipt .lc-checkout + .lc-checkout { margin-top: 2px; padding-top: 0; }
.receipt .fine { font-size: 12pt; line-height: 1.55; margin: 2px 0 0; }
.receipt .remrow { display: flex; font-weight: 700; font-size: 12pt; margin: 8px 0 4px; }
.receipt .rem-l { flex: 1; text-decoration: underline; }
.receipt .rem-r { flex: 1; }
.receipt .remarkline { font-size: 12pt; font-weight: 700; margin-top: 6px; }
.receipt .sign { display: flex; justify-content: space-between; margin-top: calc(76.8px * var(--iz)); padding: 0 6px 0 40px; font-size: 13.33pt; font-weight: 700; }
.receipt .sigline { width: 130px; border-bottom: 1px solid #000; margin: 0 0 6px 6px; }

/* settings, logs, permissions, data */
.hint { font-size: 12.5px; color: #555; margin: 0 0 12px; line-height: 1.5; }
.searchbar select { width: auto; min-width: 180px; }
.mswrap { position: relative; display: inline-block; }
.mspop { position: absolute; top: calc(100% + 4px); left: 0; z-index: 60; background: #fff; border: 1px solid #c8c8c8; border-radius: 6px; padding: 8px 12px; min-width: 200px; max-height: 220px; overflow-y: auto; overflow-x: hidden; box-shadow: 0 4px 14px rgba(0,0,0,.15); text-align: left; color: var(--text); }
.mspop::-webkit-scrollbar { width: 8px; }
.mspop::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 4px; }
.mspop::-webkit-scrollbar-thumb { background: #bbb; border-radius: 4px; }
.mspop::-webkit-scrollbar-thumb:hover { background: #999; }
/* The permission summary is a preview, never a column of its own size: what does not fit is hidden
   and the whole list is only read by opening Permissions on the user or the role. The clipping is
   done by a block inside the cell because a max-width on the cell itself is ignored while the text
   cannot wrap, which is exactly how the list came to run over the Actions buttons.
   The block is 20px NARROWER than the cell it lives in: the cell's 320px is measured from border to
   border, and 9px of padding plus 1px of border on each side belongs to the cell, not to the text.
   Ask the block for the full 320 and it ends 11px past the column line, over the next column. */
table.data td.permcell { width: 320px; max-width: 320px; font-size: 12px; }
table.data td.permcell .permclip { display: block; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
td.detail { white-space: normal; min-width: 200px; }
.logoprev { max-width: 120px; max-height: 90px; margin-top: 8px; border-radius: 6px; border: 1px solid var(--border); object-fit: contain; background: #fff; display: block; }
#cLogoName { font-size: 12px; color: #555; }
.permlist { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 8px 18px; margin-top: 6px; }
.permrow { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; color: var(--text); margin: 0; padding: 7px 9px; border: 1px solid var(--border); border-radius: 6px; background: #fbfcfb; }
.permrow input { width: 16px; height: 16px; flex: none; }
/* A feature with no such action (a read-only page has no add, Printing has no delete) keeps its
   slot visible but greyed out, so every feature shows the same four choices. A future feature gets
   all four rows from the same loop, with nothing to add here. */
.permrow.na { color: #9aa3a8; background: #f4f5f4; border-style: dashed; cursor: not-allowed; }
.permrow.na input { opacity: .45; }
.permgroup { grid-column: 1 / -1; font-weight: 700; font-size: 12.5px; text-transform: uppercase; letter-spacing: .4px; color: #445; margin: 10px 0 -2px; padding-bottom: 4px; border-bottom: 1px solid var(--border); }

/* settings sub-nav, footer, dashboard chart */
.subnav { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 18px 0; }
.subnav button, .subnav a { border: 1px solid var(--border); background: #fff; color: var(--text); font: inherit; font-size: 13px; font-weight: 600; padding: 7px 13px; border-radius: 999px; cursor: pointer; }
.subnav a { text-decoration: none; display: inline-block; line-height: normal; }
.subnav button:hover, .subnav a:hover { border-color: var(--green); }
.subnav button.active, .subnav a.active { background: var(--green); border-color: var(--green); color: #fff; }
/* Eleven pills on one HR row: the tab being read has to stand out from the ten that are not.
   The Leave Application page carries the same row, so it styles from the same rule. */
#hrTabs a.btn.active, #laTabs a.btn.active { background: var(--green); }
/* The pills sit directly above a panel that opens with its own row of buttons — Payroll's Statutory
   Rates / Print Register / Save Sheet. With no gap the two rows read as one long tab bar, so the
   space under the tabs stays empty. */
#hrTabs, #laTabs { margin-bottom: 14px; }
.footer { padding: 14px 18px 20px; text-align: center; font-size: 12px; color: #666; }


/* ---------- group menu bar: hover-open dropdowns ---------- */
/* The bar reads as one line of menu titles; pointing at a title drops its panel open underneath it,
   the way the hotel systems the desk already uses behave. A tap does the same on a phone. */
#settingsSubnav.subnav { position: relative; z-index: 40; gap: 2px; padding: 4px 18px 0; }
.menu-group { position: relative; display: inline-block; }
#settingsSubnav .menu-btn {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 14px;
  border: none; border-bottom: 3px solid transparent; border-radius: 0; background: transparent;
  color: var(--text); font: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer;
}
#settingsSubnav .menu-btn:hover, #settingsSubnav .menu-group.open .menu-btn { color: var(--green); border-color: transparent transparent var(--green); }
#settingsSubnav .menu-btn.active { color: var(--green); border-bottom-color: var(--green); }
.menu-caret { width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; opacity: .65; }
#settingsSubnav .menu-pop {
  display: none; position: absolute; top: 100%; left: 0; min-width: 236px; z-index: 70;
  background: #16233a; border-radius: 0 0 10px 10px; box-shadow: 0 12px 28px rgba(10, 20, 40, .3);
  padding: 6px 0;
}
#settingsSubnav .menu-pop a {
  display: block; min-height: 44px; padding: 11px 18px; line-height: 1.4;
  border: none; border-radius: 0; background: transparent; color: #fff;
  font-size: 13.5px; font-weight: 600; text-decoration: none;
}
#settingsSubnav .menu-pop a:hover, #settingsSubnav .menu-pop a:focus { background: rgba(255, 255, 255, .14); border: none; color: #fff; }
#settingsSubnav .menu-pop a.active { background: transparent; color: #8fe3b3; font-weight: 700; box-shadow: inset 3px 0 0 #8fe3b3; }
/* The closed rule above is scoped to #settingsSubnav, so every rule that opens a panel has to be
   scoped the same way or it loses the specificity fight and the panel never shows. */
#settingsSubnav .menu-group.open .menu-pop { display: block; }
@media (hover: hover) and (pointer: fine) {
  #settingsSubnav .menu-group:hover .menu-pop, #settingsSubnav .menu-group:focus-within .menu-pop { display: block; }
}
#settingsSubnav .subnav-plain { display: inline-flex; align-items: center; min-height: 44px; padding: 8px 14px; border: none; border-bottom: 3px solid transparent; border-radius: 0; background: transparent; color: var(--text); font-size: 13.5px; font-weight: 700; line-height: normal; text-decoration: none; cursor: pointer; }
#settingsSubnav .subnav-plain:hover { border-color: transparent transparent var(--green); color: var(--green); }
#settingsSubnav .subnav-plain.active { background: transparent; color: var(--green); border-color: var(--green); }

/* ---------- payment voucher sheet (the hotel's paper book) ---------- */
/* The voucher is a form the desk signs, not a screen panel: it is set in the serif the paper book
   uses, and it is given the width of the branch's own receipt paper (A5 landscape / A4 portrait) by
   printVoucher(), which then scales it down only if the writing overflows that page. */
.pv-sheet { width: 100%; font-family: "Times New Roman", Times, serif; color: #000; font-size: 12pt; }
.pv-head { display: flex; align-items: flex-start; gap: 14px; border-bottom: 3px double #000; padding-bottom: 10px; }
/* The paper book's letterhead ends on whitespace - the heavy double rule was the one thing on the
   screen sheet that is not on the form. The logo is lifted out of the flow so the company block
   spans the whole page and centres on it, instead of centring in the space left of the logo. */
.pv-sheet .pv-head { position: relative; min-height: 76px; border-bottom: 0; padding-bottom: 0; }
.pv-logo { width: 110px; height: 72px; object-fit: contain; flex: 0 0 auto; }
.pv-sheet .pv-logo { position: absolute; left: 0; top: 0; }
.pv-sheet .pv-co { width: 100%; }
/* The letterhead is the same block the receipt prints, just scoped to the sheet. */
.pv-co { flex: 1; text-align: center; line-height: 1.35; }
.pv-co-name { font-size: 16pt; font-weight: 700; }
.pv-sheet .pv-co-name { font-size: 15pt; }
.pv-co-addr { white-space: pre-line; }
.pv-doc { text-align: right; font-size: 15pt; font-weight: 700; letter-spacing: 1px; text-decoration: underline; margin: 16px 0 8px; }
.pv-sheet .pv-doc { margin: 10px 0 6px; font-size: 14pt; }
.pv-daterow { text-align: right; margin-bottom: 12px; }
.pv-sheet .pv-daterow { margin-bottom: 5px; }
.pv-payrow { display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; margin-bottom: 12px; }
/* The paper form has a clear gap between the Pay To line and the particulars table - the two are not
   meant to run into each other once the sheet is filled in by hand. */
.pv-sheet .pv-payrow { margin-bottom: 26px; }
.pv-datelbl { font-weight: 700; }
/* A dotted underline is where the paper form is signed or written on, so the value sits on it - and
   starts at the left of it, the moment the label ends. Without this the value inherits the row's
   alignment and a right-hand line reads as "DATE: ----------18/10/2026". */
.pv-fill { display: inline-block; min-width: 170px; padding: 0 6px 1px; border-bottom: 1px dotted #000; font-weight: 700; text-align: left; }
.pv-payto .pv-fill { min-width: 250px; }
.pv-items { width: 100%; border-collapse: collapse; table-layout: fixed; max-width: 100%; }
.pv-items th, .pv-items td { border: 1px solid #000; padding: 6px 8px; height: 26px; vertical-align: top; }
.pv-sheet .pv-items th, .pv-sheet .pv-items td { padding: 3px 6px; height: 24px; }
.pv-items th { text-align: center; font-weight: 700; }
.pv-items .pv-cno { width: 8%; text-align: center; }
.pv-items .pv-camt { width: 26%; text-align: center; }
.pv-total td { font-weight: 700; }
.pv-totlbl { text-align: right; }
.pv-meta { font-size: 10.5pt; margin-top: 8px; }
.pv-sheet .pv-meta { font-size: 10pt; margin-top: 6px; }
/* On the paper form the line is signed first and the role is printed under it, so the box is drawn
   that way round. */
.pv-sign { display: flex; gap: 40px; margin-top: 56px; }
.pv-sheet .pv-sign { margin-top: 40px; }
.pv-signbox { flex: 1; }
.pv-signbox:last-child { text-align: right; }
.pv-signlbl { font-size: 11pt; font-weight: 700; }
.pv-signline { height: 34px; border-bottom: 1px solid #000; }
.pv-sheet .pv-signline { width: 55%; height: 26px; }
.pv-sheet .pv-signbox:last-child .pv-signline { margin-left: auto; }
@media print { .pv-sheet { page-break-inside: avoid; } }
/* ---------- the on-screen voucher preview (the very sheet Print puts on paper, laid under the list) ----------
   It sits inside the app, and the print stylesheet already hides everything but #printArea, so the
   preview never rides along on the printed page. */
.vch-preview { margin-top: 16px; }
.vch-preview-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.vch-preview-title { font-weight: 700; font-size: 14px; }
.vch-preview-bar .btn { margin-left: auto; }
.vch-preview-stage { overflow-x: auto; padding: 16px; background: #eef1ee; border: 1px solid var(--border); border-radius: 10px; }
.vch-preview-stage .pv-page { background: #fff; box-shadow: 0 1px 8px rgba(0, 0, 0, .16); padding: 10px 14px; margin: 0 auto; }
table.data tbody tr.vch-picked, table.data tbody tr.vch-picked:nth-child(even),
table.data tbody tr.vch-picked:hover { background: #d7ecd9; }
table.data tbody tr.vch-picked > td:first-child { box-shadow: inset 4px 0 0 var(--green); }
.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; margin-top: 14px; }
.chart-card { background: transparent; border: none; border-radius: 0; padding: 0 4px; }
.chart-card .chart-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.chart-card .chart-title { font-size: 13px; font-weight: 700; }
.chart-card .chart-total { font-size: 12px; font-weight: 600; color: #555; }
.chart-card canvas { width: 100%; display: block; }
.stats { display: flex; flex-wrap: wrap; gap: 12px; margin: 12px 0; }
.stats .stat { flex: 1; min-width: 150px; background: #fbfcfb; color: var(--text); border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; }
.stats .stat .lbl { font-size: 12px; color: #555; font-weight: 600; }
.stats .stat .val { font-size: 20px; font-weight: 700; margin-top: 4px; }
.stats .stat .sub { font-size: 12px; color: #555; margin-top: 4px; }
.sales-summary { margin-top: 18px; border-top: 2px solid var(--border); padding-top: 10px; }
.sales-summary .sum-title { font-size: 16px; font-weight: 700; margin-bottom: 4px; }
.sales-summary .sum-group { margin-bottom: 6px; }
.sales-summary .sum-head { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #555; margin: 10px 0 2px; }
.sales-summary .stats { margin: 6px 0; }
.sheet-sum { border-collapse: collapse; margin: 12px 0; background: #fff; width: 100%; max-width: 760px; }
.sheet-sum td { border: 1px solid #c9c9c9; padding: 6px 12px; font-size: 14px; }
.sheet-sum td.sl { text-align: right; font-weight: 600; color: #222; width: 40%; }
.sheet-sum td.sv { text-align: center; font-weight: 700; color: #222; width: 26%; }
.sheet-sum td.sg { width: 4%; }
.sheet-sum td.sr { width: 30%; text-align: center; }
.sheet-sum td.sr.month { font-weight: 700; }
.sheet-sum td.st-title { text-align: center; font-weight: 700; font-size: 15px; }
.sheet-sum td.sv.m1 { background: #ffff00; }
.sheet-sum td.sv.m2 { background: #00ff00; }
.sheet-sum td.sv.m3 { background: #00ffff; }
.sheet-sum td.sv.m4 { background: #ffa500; }
.sheet-sum td.sv.m5 { background: #4472c4; color: #fff; }
.sheet-sum td.sv.m6 { background: #f4cccc; }
.sheet-sum td.sv.m7 { background: #ff0000; color: #fff; }
.sheet-sum td.sv.m8 { background: #fff2cc; }
.sheet-sum td.sv.m9 { background: #fce5cd; }
table.data tr.total-row td { font-weight: 700; background: #f2f2f2; border-top: 2px solid #999; }
table.data tr.total-row td.t-green { background: #00ff00; color: #111; }
table.data tr.total-row td.t-pink { background: #f4cccc; color: #111; }
table.data tr.total-row td.t-blue { background: #4472c4; color: #fff; }
table.data tr.more-row td { text-align: center; padding: 10px; background: #fafafa; }
table.data tr.more-row td .btn { margin: 0; }
.inhouse-toolbar { align-items: center; }
.inhouse-toolbar h2 { margin: 0; }
.inhouse-toolbar .inhouse-filter-wrap { display: flex; align-items: center; gap: 8px; }
.inhouse-toolbar .inhouse-filter-wrap .sf-lbl { font-weight: 600; color: #555; }
.inhouse-toolbar .inhouse-filter-wrap select { width: auto; min-width: 140px; }
.inhouse-toolbar input { flex: 0 1 280px; min-width: 160px; margin-left: auto; }
#view-inhouse .btn { min-height: 44px; }
.inhouse-undo { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 8px 0 0; }
.inhouse-undo:empty { display: none; }
.inhouse-undo .hint { margin: 0; }
#view-inhouse .stat { min-width: 0; overflow-wrap: anywhere; }
#inHouseTable .inhouse-name { white-space: normal; min-width: 130px; overflow-wrap: anywhere; }
.inhouse-stay + .inhouse-stay { margin-top: 6px; }
#inHouseDeposits { font-variant-numeric: tabular-nums; }
#inHouseDepositNote { overflow-wrap: anywhere; }
#view-inhouse :focus-visible { outline: 2px solid var(--green-dark); outline-offset: 3px; }
table.data td.strong, table.data th.strong { font-weight: 700; }
.muted { color: #8a8f8a; font-size: 12px; }
table.data input.cellinp { width: 100%; box-sizing: border-box; padding: 4px 6px; border: 1px solid #d7dbd7; border-radius: 4px; font: inherit; background: #fff; }
table.data input.cellinp.num { text-align: right; }

/* ---------- phone / installed-app layout ----------
   Screen-only: the @media print block above must keep full control of the A5 receipt,
   and A4 portrait (794px) would otherwise match a plain max-width query. */
@media screen and (max-width: 820px) {
  main { padding: 12px; }
  .topbar { padding: 8px 12px; gap: 8px; }
  .topbar nav { order: 10; width: 100%; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; -webkit-overflow-scrolling: touch; }
  .topbar nav button, .topbar nav a { flex: 0 0 auto; padding: 10px 14px; min-height: 40px; }
  .topbar .company-switch { max-width: 150px; }
  .card { padding: 12px; margin-bottom: 12px; }
  .entryblock .grid { grid-template-columns: repeat(2, 1fr); }
  .modal-backdrop { padding: 0; }
  .modal { width: 100%; max-width: none; min-height: 100vh; border-radius: 0; padding: 14px; }
  button.btn, a.btn { padding: 11px 16px; }
  button.btn.small, a.btn.small { padding: 8px 12px; }
  .subnav button, .subnav a { min-height: 38px; }
  /* On a phone the groups stack and their panel opens in line under the title, so nothing gets
     clipped by the card edge and every item stays a comfortable tap. */
  #settingsSubnav.subnav { padding: 2px 12px 0; }
  .menu-group { display: block; width: 100%; }
  #settingsSubnav .menu-pop { position: static; width: 100%; min-width: 0; border-radius: 8px; margin: 2px 0 6px; box-shadow: none; }
  .searchbar input { min-width: 110px; }
  .searchbar select { min-width: 130px; }
  .table-wrap { -webkit-overflow-scrolling: touch; }
}
@media screen and (max-width: 520px) {
  .topbar .brand { display: none; }
  .grid { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
  .entryblock .grid { grid-template-columns: 1fr 1fr; gap: 0 10px; }
  .stats .stat { min-width: 46%; }
  .totalrow { justify-content: space-between; }
  .totalrow strong { min-width: 90px; }
  table.data { font-size: 12px; }
  table.data th, table.data td { padding: 6px 7px; }
}
@media screen and (display-mode: standalone) {
  .topbar { padding-top: calc(8px + env(safe-area-inset-top, 0px)); }
  main { padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
}

/* New Guest form: long names, phone numbers and passport IDs need room to be read */
.guestgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.guestgrid .f-wide { grid-column: span 2; }
/* New Voucher form: Date / Paid To / Amount / Method / Ref share the top rows, Purpose takes the
   whole width below them because it is the line that prints on the voucher. */
#vchForm .f-wide { grid-column: 1 / -1; }
#vchForm .f-wide input { height: 42px; font-size: 15px; }
/* A voucher row is one printed line: the amount takes a money-box width and the particulars run all the
   way to the right edge, because that is the column the desk writes the longest text into. */
.vchline .grid { grid-template-columns: minmax(150px, 220px) minmax(0, 1fr); }
@media screen and (max-width: 520px) {
  .vchline .grid { grid-template-columns: 1fr; }
}
@media screen and (max-width: 520px) {
  .guestgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- HR: payroll sheet, register & payslip ----------
   The payroll grid is the desk's old spreadsheet, so the money boxes are typed straight into the
   cells and stay right-aligned like the columns they came from. */
table.data td.num input.cellinp { text-align: right; width: 84px; }
table.data td.num input.cellinp[type=date] { width: 130px; text-align: left; }
table.data.sheet th { white-space: nowrap; font-size: 11px; padding: 6px 5px; }
table.data.sheet td { padding: 3px 4px; font-size: 12px; }
table.data.sheet td.copyable, table.data.sheet td:nth-child(2), table.data.sheet td:nth-child(3) { white-space: nowrap; }
.t-green { color: var(--green-dark); }
.t-pink { color: #b3261e; }
.t-amber { color: #8a5a00; }
/* Staff card: the documents sit under the details, so the upload row keeps its own block. */
#stDocsWrap { margin-top: 16px; border-top: 1px solid var(--border); padding-top: 6px; }
#stDocsWrap .row > div { flex: 1; min-width: 150px; }

.prn-sheet { width: 100%; font-family: "Segoe UI", Arial, sans-serif; color: #000; font-size: 9pt; }
.prn-title { text-align: center; font-size: 13pt; font-weight: 700; letter-spacing: .5px; text-decoration: underline; margin: 10px 0 8px; }
.prn-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.prn-table th, .prn-table td { border: 1px solid #000; padding: 3px 4px; font-size: 7.5pt; overflow: hidden; }
.prn-table th { text-align: center; font-weight: 700; }
.prn-table td.num { text-align: right; }
.prn-total td { font-weight: 700; background: #eee; }
.prn-sign { margin-top: 18px; font-size: 9pt; }
.prn-legend { font-size: 8pt; margin: 0 0 5px; }
/* Leave boards: both sheets are wider than a laptop, so the name column stays put while the days
   scroll under it. Row banding is dropped - the calendar is read by line, not by stripe. */
.lv-month { margin-bottom: 18px; }
.lv-cal, .lv-laster { border-collapse: collapse; }
.lv-cal tbody tr, .lv-laster tbody tr { background: #fff; }
.lv-cal th, .lv-cal td { padding: 3px 0; text-align: center; font-size: 11px; }
/* A day box carries the leave code (AL, MC, UL, MAT...), so it has to be wide enough for the longest
   one on a single line - a box that wraps "MAT" into two lines reads as a blank to a manager scanning
   the year. The head-count line under the month stays a plain figure. */
.lv-cal .lv-day { width: 28px; min-width: 28px; white-space: nowrap; }
.lv-cal .lv-wknd { background: #eef2ee; }
.lv-cal .lv-on { font-weight: 700; color: var(--green-dark); background: #dcefdd; }
.lv-cal .lv-pending { opacity: .58; }
.lv-cal .lv-total { background: var(--green); color: #fff; }
table.lv-cal th.lv-name, table.lv-cal td.lv-name, table.lv-laster th.lv-name, table.lv-laster td.lv-name,
table.lv-laster th.lv-note {
  text-align: left; position: sticky; left: 0; background: #fff; z-index: 1; min-width: 180px; padding-left: 8px;
}
.lv-cal tfoot th, .lv-cal tfoot td { background: #f0f4f0; font-weight: 700; }
/* A header cell on these sheets is green with white figures, so every rule that repaints one pale
   has to take the text with it - otherwise the label is white on white and simply vanishes. */
.lv-cal thead th.lv-wknd { color: var(--green-dark); }
.lv-cal thead th.lv-name, .lv-laster thead th.lv-name { color: var(--green-dark); background: #f4f8f4; }
.lv-laster th, .lv-laster td { padding: 5px 6px; text-align: center; font-size: 12px; white-space: nowrap; }
.lv-laster .lv-type { font-weight: 700; }
.lv-laster .lv-sumrow th, .lv-laster .lv-sumrow td { background: #eef3ee; font-weight: 700; }
/* The all-staff line closes the sheet, so it is the one row on the register the branch colour is for -
   a manager scanning the page should not have to look for it among the per-person footers. */
.lv-laster .lv-grand th, .lv-laster .lv-grand td { background: var(--green); color: #fff; }
/* The label cell of a block is the sticky first column, and that rule (table.lv-laster th.lv-note)
   carries a white background of its own at a higher specificity - so the all-staff label has to
   restate BOTH the colour and the background, or the line closes the sheet in blank white. */
table.lv-laster tr.lv-grand th.lv-note { background: var(--green); color: #fff; }
.lv-laster .lv-note { text-align: left; font-size: 11px; font-weight: 600; color: var(--green-dark); }
/* Click-to-highlight on the two leave sheets. Every cell on a marked line carries a background of
   its own - the sticky name column, the weekend tint, the leave-code boxes, the green total boxes and
   the per-person foot - so the mark has to restate each one or the line breaks into patches the
   moment it is followed across a month. */
table.data tbody tr.lv-sel { background: #ffe9b3; cursor: pointer; }
table.data tbody tr.lv-sel > td.lv-name, table.data tbody tr.lv-sel > th.lv-name,
table.data tbody tr.lv-sel > th.lv-note { background: #ffe9b3; color: var(--green-dark); }
table.data tbody tr.lv-sel > td.lv-wknd { background: #ffe9b3; }
table.data tbody tr.lv-sel > td.lv-on { background: #ffdf8a; color: #7a4b00; }
table.data tbody tr.lv-sel > td.lv-total { background: var(--green-dark); color: #fff; }
table.data tbody tr.lv-sel > td:first-child, table.data tbody tr.lv-sel > th:first-child { box-shadow: inset 4px 0 0 var(--green); }
table.lv-cal tbody tr[data-lvstaff], table.lv-laster tbody tr[data-lvstaff] { cursor: pointer; }
/* My Applications names whoever has already signed, under the stage the row is waiting at. The cell
   itself carries the stage colour, so the names stay plain and small rather than joining it. */
table.data td .lv-signed { display: block; font-size: 11px; font-weight: 400; color: #444; }
/* The expense search sits in the page heading between the title and Download Report. The base input
   rule is width:100%, so the box has to be given a flex basis of its own or it shoves the heading
   onto three lines on a laptop. */
#mrecExpBox { flex: 1 1 300px; justify-content: flex-end; min-width: 0; }
#mrecExpSearch { flex: 1 1 230px; min-width: 170px; max-width: 420px; }
@media (max-width: 720px) {
  #mrecExpBox { flex: 1 1 100%; justify-content: flex-start; }
  #mrecExpSearch { max-width: none; }
}
@media print {
  .prn-table.lv-cal th, .prn-table.lv-cal td { padding: 1px 0; font-size: 6.5pt; }
  /* The screen gives a day box room for "MAT"; a month across A4 landscape cannot, so the printed
     board keeps the same codes at a width that still fits 31 days plus the name column on one page. */
  .prn-table.lv-cal .lv-day { width: 22px; min-width: 22px; }
  .lv-cal .lv-on, .lv-cal .lv-wknd, .lv-cal .lv-total { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
/* The payslip is copied from the hotel's own sheet, so the paper is built on the same five-column
   grid the spreadsheet uses - label, colon, value, label, value - and every block below shares it.
   The grid is 534pt wide - a little wider than the sheet it was copied from, filling the A4's
   10mm margins - which is why this sheet is measured in points rather than millimetres. */
.ps-sheet { width: 534pt; margin: 0 auto; font-family: Arial, "Segoe UI", sans-serif; color: #000; font-size: 10pt; }
/* The hotel's sheet has no rule drawn under its letterhead, and its logo stands in the corner with
   the company block centred across the whole paper - so the logo comes out of the flow, the same way
   the voucher sheet does it. */
.ps-sheet .pv-head { position: relative; min-height: 52pt; border-bottom: 0; padding-bottom: 0; gap: 0; }
.ps-sheet .pv-logo { position: absolute; left: 0; top: 0; width: 68pt; height: 52pt; }
.ps-sheet .pv-co { width: 100%; }
.ps-sheet .pv-co { font-size: 10pt; line-height: 1.3; }
.ps-sheet .pv-co-name { font-size: 14pt; font-weight: 700; }
.ps-title { text-align: center; font-size: 18pt; font-weight: 700; margin: 20pt 0 14pt; }
.ps-grid { width: 100%; border-collapse: collapse; table-layout: fixed; }
.ps-grid td { border: 1px solid #000; padding: 4.5pt 3pt; font-size: 10pt; line-height: 1.2;
  vertical-align: middle; overflow: hidden;
  -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.ps-lb, .ps-cl, .ps-dl { text-align: left; }
/* "TOTAL DEDUCTION" has the 88pt deduction column to itself and nothing else in it, so the money
   labels are set a half point under the figures and never break onto a second row of their own. */
.ps-money td.ps-lb, .ps-money td.ps-dl { font-size: 9pt; padding-left: 2.5pt; padding-right: 2.5pt; white-space: nowrap; }
/* TOTAL DEDUCTION is the longest string on the money table: at the full size it loses its last
   letter to the net-pay cell beside it. */
.ps-money td.ps-tdl { font-size: 7.5pt; padding-left: 2pt; padding-right: 1pt; }
.ps-vl { font-weight: 700; }
.ps-hr { text-align: center; font-size: 11pt; }
.ps-am { font-size: 11pt; font-variant-numeric: tabular-nums; }
/* The sheet's header band and its total lines are grey, and the two boxes a person fills in by hand -
   the month's annual leave and the total income - are yellow. Both survive onto the paper. */
.ps-mh { text-align: center; background: #ccc; }
.ps-gy { background: #ccc; }
.ps-ylo { background: #ff0; }
.ps-bd { font-weight: 700; }
.ps-yl { background: #ff0; font-size: 9pt; white-space: pre-wrap; }
.ps-wd { font-size: 11pt; }
.ps-netval { font-weight: 700; }
/* The hand-keyed unpaid-day deduction is written in red on the paper. */
.ps-red { color: #f00; }
/* The identity block is one rectangle with a single divider between its two halves - the sheet draws
   no line between the four rows, so the borders are restated per cell instead of inherited. */
.ps-who { border: 1px solid #000; margin-bottom: 13pt; }
/* The sheet's label column is exactly wide enough for "EMPLOYEE IC/PASSPORT NO" on one line, and the
   paper it was drawn on uses a narrower face than Arial - so the block is set two points smaller with
   no side padding, and no label is allowed to break or lose its tail. */
.ps-who td { border: 0; font-size: 9pt; padding: 4.5pt 0 4.5pt 2.5pt; white-space: nowrap; }
.ps-who td.ps-vl { font-size: 10pt; }
.ps-who td.ps-lb2 { border-left: 1px solid #000; }
.ps-cl2 { float: right; font-weight: 400; }
/* The hotel's paper leaves the long blank space left of the net pay open along its bottom and left
   edges - the table's edge stops at TOTAL INCOME - while the NET PAY label and figure close with a
   rule. The margin keeps the total net payable band below where it sits on the sample. */
.ps-money td.ps-nbb { border-bottom: 0; border-left: 0; }
.ps-money { margin-bottom: 20pt; }
/* The two spare lines under the annual-leave band are there for a figure written by hand, so they are
   rows on the paper - an empty cell would otherwise collapse to a fraction of their height. */
.ps-money td { height: 17pt; }
.ps-words { margin-bottom: 15pt; }
/* The leave lines sit over on the right, with the kind written outside the box - so the label cell
   carries no border at all and the two figures keep theirs. */
.ps-grid td.ps-lvname { border: 0; text-align: right; font-size: 12pt; }
.ps-lvt { text-align: center; font-size: 12pt; }
.ps-lvb { text-align: left; font-size: 12pt; }
/* The signature lines are the label sitting on a short rule, with the name and IC written underneath
   and centred on it. The sheet leaves a hand's width of paper between the leave box and the rules. */
.ps-foot { position: relative; height: 52pt; margin-top: 107pt; font-size: 11pt; }
.ps-sig { position: absolute; top: 0; text-align: center; }
.ps-sig-a { left: 35pt; width: 70pt; }
.ps-sig-r { left: 404pt; width: 61pt; }
/* The rule is the width of the label written on it, and the name under RECEIVED BY is centred on the
   same rule and overhangs both ends of it - so nothing here is allowed to break. */
.ps-siglbl { display: block; border-bottom: 1px solid #000; white-space: nowrap; }
.ps-sigval { font-weight: 700; font-size: 10pt; line-height: 15.5pt; white-space: nowrap; }
@media print { .prn-sheet, .ps-sheet { page-break-inside: avoid; } }

/* The WhatsApp row button opens this over the table: a plain chat, or the chat with the receipt.
   Fixed, because the actions cell sits inside a table that scrolls both ways - and above 100 so the
   floating scroll arrows and the page-end button cannot cover a choice mid-click. */
.wa-pop {
  position: fixed; z-index: 110; display: flex; flex-direction: column; gap: 6px; min-width: 236px;
  padding: 8px; background: #fff; border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .22);
}
.wa-pop-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left;
  min-height: 44px; padding: 7px 10px; font: inherit; cursor: pointer;
  background: #f6f8f6; border: 1px solid var(--border); border-radius: 8px;
}
.wa-pop-item:hover, .wa-pop-item:focus { background: #eaf5ec; border-color: var(--green); outline: 2px solid var(--green); outline-offset: 1px; }
.wa-pop-label { font-weight: 700; color: var(--green-dark); }
.wa-pop-hint { font-size: 12px; color: #55604f; }

/* ---------- the bell beside Logout ----------
   The panel is fixed rather than absolutely placed inside the header: the top bar wraps on a phone,
   and a child of a wrapping flex row would be pushed off the bottom of the screen. */
.bell-wrap { position: relative; display: inline-flex; }
.bell-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; min-width: 40px; min-height: 34px; padding: 5px 9px; }
.bell-btn svg { display: block; }
.bell-count {
  position: absolute; top: -7px; right: -7px; min-width: 19px; height: 19px; padding: 0 4px;
  border-radius: 999px; background: var(--red); color: #fff; font-size: 11px; font-weight: 700;
  line-height: 19px; text-align: center; pointer-events: none;
}
.bell-pop {
  position: fixed; z-index: 120; width: min(400px, calc(100vw - 24px));
  background: #fff; border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .24);
}
.bell-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--border); }
.bell-head strong { font-size: 14px; color: var(--green-dark); }
/* overscroll-behavior keeps the wheel inside the list at either end: without it the page scrolls on
   and the fixed panel would be closed mid-read. */
.bell-list { max-height: min(58vh, 460px); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 6px; }
.bell-empty { padding: 18px 12px; text-align: center; color: #66705f; font-size: 13px; }
.bell-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px; width: 100%; text-align: left;
  padding: 9px 10px; margin: 2px 0; font: inherit; cursor: pointer; border-radius: 9px;
  background: #fff; border: 1px solid var(--border); border-left: 4px solid #b9c4b7;
}
.bell-item:hover, .bell-item:focus { background: #f2f8f2; outline: 2px solid var(--green); outline-offset: -2px; }
/* Unread carries a mark as well as colour — a bell row that only changes shade is invisible to a
   colour-blind desk and to a screen printed in greyscale. */
.bell-item.unread { background: #f4f9f4; border-left-color: var(--green); }
.bell-item.unread .bell-title::after { content: " • NEW"; color: var(--green-dark); font-size: 11px; font-weight: 700; }
.bell-item.lv-alert { border-left-color: var(--red); }
.bell-item.lv-action { border-left-color: #e08a00; }
.bell-tag { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: #5b6757; }
.bell-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.bell-body { font-size: 12.5px; color: #404b3c; line-height: 1.45; white-space: pre-line; }
.bell-time { font-size: 11.5px; color: #6b7566; }
.bell-item .btn { margin-top: 4px; }
@media (max-width: 520px) {
  .bell-btn { min-height: 44px; min-width: 46px; }
  .bell-pop { width: calc(100vw - 16px); }
}

/* ---------- the account chip and the menu behind it ----------
   Same fixed panel as the bell: the top bar wraps on a phone, and a child of a wrapping flex row
   would be pushed off the bottom of the screen. */
.acc-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; min-height: 34px; padding: 3px 6px; }
.acc-face { display: inline-flex; align-items: center; justify-content: center; width: 27px; height: 27px; border-radius: 999px; overflow: hidden; background: var(--green); color: #fff; font-size: 14px; font-weight: 700; line-height: 1; }
.acc-face.big { width: 44px; height: 44px; font-size: 21px; }
.acc-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.acc-pop {
  position: fixed; z-index: 120; width: min(268px, calc(100vw - 24px));
  background: #fff; border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .24);
}
.acc-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.acc-id { display: flex; flex-direction: column; min-width: 0; }
.acc-id strong { font-size: 14px; color: var(--green-dark); overflow-wrap: anywhere; }
.acc-id > span { font-size: 12px; color: #5b6757; overflow-wrap: anywhere; }
.acc-role { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #78836f; }
.acc-list { padding: 6px; }
.acc-item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 10px;
  margin: 2px 0; font: inherit; font-size: 13.5px; font-weight: 600; color: var(--text);
  cursor: pointer; border: 0; border-radius: 9px; background: none;
}
.acc-item svg { flex: 0 0 auto; color: var(--green-dark); }
.acc-item:hover, .acc-item:focus { background: #f2f8f2; outline: 2px solid var(--green); outline-offset: -2px; }
/* Signing out is the one action here that ends the session, so it is separated and coloured for it. */
.acc-sep { height: 1px; background: var(--border); margin: 6px 4px; }
.acc-item.danger { color: #b3261e; }
.acc-item.danger svg { color: #b3261e; }
.acc-item.danger:hover, .acc-item.danger:focus { background: #fdeceb; }
@media (max-width: 520px) {
  .acc-btn { min-height: 44px; min-width: 46px; }
  .acc-item { min-height: 44px; }
}
.acc-photo-row { display: flex; align-items: flex-start; gap: 12px; margin: 0 0 12px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.acc-photo-side { flex: 1 1 auto; min-width: 0; }
/* The person's own pay, opened from the menu rather than the payroll sheet. */
.mp-table { border-collapse: collapse; width: 100%; margin: 4px 0 2px; font-size: 13px; }
.mp-table td { border-bottom: 1px solid var(--border); padding: 7px 8px; }
.mp-lb { color: #5b6757; }
.mp-v { text-align: right; font-variant-numeric: tabular-nums; }
.mp-v.mp-net { font-weight: 800; color: var(--green-dark); }
.mp-none { padding: 14px 6px; color: #66705f; font-size: 13px; font-style: italic; }

/* Set by head office or by whoever created the account, so the owner has to replace it before the
   desk is trusted with the ledger. It is a bar, not a wall: the account still works, and the bar
   only disappears when the person changes the password themselves. */
.pwd-banner {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px; justify-content: space-between;
  margin: 10px 18px 0; padding: 10px 14px; font-size: 13px;
  background: #fff4e5; color: #7a4b00; border: 1px solid #f0c98a; border-left: 5px solid #e08a00;
  border-radius: 8px;
}

/* The Companies and Branches rows carry one of four states, and colour alone cannot be the signal —
   each word is different, so a desk reading it in grey still knows whether it says Closed or
   Waiting approval. "Rejected" carries the head-office note on hover. */
.co-tag {
  display: inline-block; padding: 3px 9px; font-size: 12px; font-weight: 700;
  border: 1px solid var(--border); border-radius: 999px; background: #f2f4f2; color: #444;
  white-space: nowrap;
}
.co-tag.on { background: #eaf5ec; border-color: var(--green); color: #1f5e23; }
.co-tag.off { background: #fbeceb; border-color: var(--red); color: #9a2622; }
.co-tag.pending { background: #fff4e5; border-color: #e08a00; color: #7a4b00; }

/* ---------- The Leave Apply sheet ----------
   The hotel's own paper (BORANG PERMOHONAN CUTI) is a label, a colon and a ruled line to write on,
   three cyan section heads and a bordered approval block - so the form is built the same way instead
   of as a grid of boxes. The answers that come off the staff card are printed ON the rule rather than
   keyed into a greyed-out input, because nobody types them. */
.lf-sheet { max-width: 780px; background: #fff; color: #111; border: 1px solid var(--border);
  border-radius: 10px; padding: 22px 26px 24px; }
.lf-title { margin: 0 0 20px; text-align: center; font-size: 19px; font-weight: 800;
  letter-spacing: .4px; text-transform: uppercase; }
.lf-line { display: grid; grid-template-columns: 190px 10px 1fr; column-gap: 6px;
  align-items: center; margin-bottom: 10px; }
.lf-line.lf-top { align-items: flex-start; }
.lf-line > label, .lf-line > .lf-lb { margin: 0; font-size: 13.5px; font-weight: 600; color: #222; }
.lf-cl { font-size: 13.5px; font-weight: 600; color: #222; }
.lf-line input, .lf-line select { border: 0; border-radius: 0; border-bottom: 1px solid #111;
  background: transparent; padding: 4px 2px; font-size: 14px; }
.lf-line input:focus, .lf-line select:focus { outline: 2px solid #a5d6a7; outline-offset: 2px; }
.lf-printed { border-bottom: 1px solid #111; min-height: 25px; padding: 4px 2px; font-size: 14px;
  font-weight: 700; overflow-wrap: anywhere; }
.lf-with { display: flex; align-items: baseline; gap: 8px; }
.lf-unit { font-size: 13.5px; color: #222; }
.lf-sec { margin: 22px 0 10px; font-size: 14.5px; font-weight: 800; letter-spacing: .3px;
  text-transform: uppercase; color: #0e7ea8; }
.lf-lead { margin: 0 0 10px; font-size: 13.5px; color: #222; }
.lf-note { margin: 16px 0 0; font-size: 12.5px; line-height: 1.55; color: #333; }
/* One kind per application, so the boxes answer like radios - but drawn as the square the paper
   prints, and the whole label is the target so a thumb does not have to find 16px. */
.lf-kinds { display: flex; flex-wrap: wrap; gap: 4px 20px; }
.lf-kind { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; margin: 0;
  font-size: 13.5px; font-weight: 600; color: #222; cursor: pointer; }
.lf-kind input[type=radio] { -webkit-appearance: none; appearance: none; width: 16px; height: 16px;
  margin: 0; padding: 0; border: 1.5px solid #111; border-radius: 2px; background: #fff;
  display: inline-grid; place-content: center; cursor: pointer; }
.lf-kind input[type=radio]:checked::after { content: ""; width: 10px; height: 10px;
  background: #111; border-radius: 1px; }
.lf-kind input[type=radio]:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
/* The supporting document the branch can ask for on HR Setting. The paper sheet prints the line, so
   the file box and the words saying whether this kind needs one sit together under it. */
.lf-doc { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.lf-doc input[type=file] { border: 0; padding: 2px 0; font-size: 13px; }
.lf-doc input[type=file]:focus-visible { outline: 2px solid #a5d6a7; outline-offset: 2px; }
.lf-doc .muted { font-size: 12px; line-height: 1.45; }
.lf-doc .la-doc-need { color: #b3261e; font-weight: 700; }
.lf-doc .la-doc-have { color: #1b5e20; font-weight: 600; }
td .doc-none { margin-right: 6px; }
.lf-apprwrap { overflow-x: auto; }
.lf-appr { width: 100%; min-width: 480px; border-collapse: collapse; table-layout: fixed; }
.lf-appr th, .lf-appr td { border: 1px solid #111; padding: 8px 10px; font-size: 13px;
  text-align: left; vertical-align: top; }
.lf-appr th { font-weight: 700; }
.lf-appr td.lf-sign { height: 74px; }
.lf-signval { display: block; margin-top: 42px; min-height: 20px; border-bottom: 1px solid #111;
  font-weight: 700; overflow-wrap: anywhere; }
.lf-blank { color: #666; }
@media (max-width: 620px) {
  .lf-sheet { padding: 16px 14px 18px; }
  .lf-line { grid-template-columns: 1fr; row-gap: 2px; margin-bottom: 12px; }
  .lf-cl { display: none; }
  .lf-kind { min-height: 44px; }
}
/* A sale keyed with F2 from another page has no message box of its own, so its confirmation floats. */
#appToast { position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 10px); z-index: 4000;
  background: var(--green-dark); color: #fff; font-weight: 600; font-size: 13.5px; padding: 9px 18px;
  border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,.22); opacity: 0; pointer-events: none;
  transition: opacity .16s ease, transform .16s ease; }
#appToast.show { opacity: 1; transform: translate(-50%, 0); }
