/* TableManagement app-specific styles. The platform design system (tokens, cards,
   buttons, nav, hamburger, .field-group/.field-row forms, .badge, .section-title, .btn-*)
   lives in the shared style.css, copied on deploy. Reuse those; keep this file for genuinely
   app-local rules only. */

/* SEATED-but-not-yet-ordered chip: deliberately its own colour, not .badge-warning -- that class is
   already used for the guest-note flag and pending_confirmation, so reusing it here would make a
   forgotten table blend in with an unrelated "has a note" flag on the same row. Dark-theme-pale /
   light-theme-deep pattern matches the platform's other status colours (style.css :root vs
   html.light-theme), contrast-checked against the card surface both ways. */
.badge-awaiting-order { background: #64d2ff; color: #1c1c1e; }
html.light-theme .badge-awaiting-order { background: #0077a8; color: #ffffff; }

/* ---------- Public booking flow (Step 4) ---------- */

/* Centred venue title on public screens (guests have no hamburger). Matches SunbedManagement app.css.
   Top padding cut 24px -> 8px (05 Sep 2026): stacked on #content's own 16px padding, 24px reserved 40px
   total before the heading even starts, measured live as excessive; the earlier h1 margin:0 fix (same
   session) was real but only removed the browser's incidental default heading margin (~13px), not this
   deliberate value -- this is the actual dominant contributor. #content's 16px is a global, shared rule
   used on every screen in every app, so it is not touched here; this page-scoped value is. */
.public-header { text-align: center; padding: 8px 16px 16px; }
.public-header h1 { font-size: 1.5rem; font-weight: 800; margin: 0; }
.public-header p { color: var(--text2); font-size: 0.9rem; margin-top: 6px; }

/* Booking summary threaded through the steps (2 guests · Fri 8 Aug · 19:30 · Terrace). NEW. */
.summary-line { text-align: center; color: var(--text2); font-size: 0.85rem; margin: -6px 0 16px; }

/* Date field rendered as a button (opens the calendar popover) but reads like a .field-row control. NEW. */
.datebtn {
    flex: 1; background: transparent; border: none; color: var(--text); font-size: 0.95rem;
    font-family: inherit; text-align: left; padding: 4px 0; cursor: pointer;
    display: flex; align-items: center; justify-content: space-between;
}
.datebtn::after { content: "\25BE"; color: var(--text2); font-size: 0.8rem; }

/* Available-time chips. NEW component (no shared time-chip); state names follow the house
   convention used by Sunbed's .sunbed-slot (.available/.selected/.unavailable). */
.slots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.slot { text-align: center; font-size: 0.95rem; font-weight: 600; padding: 11px 0; border-radius: 10px;
    background: var(--surface); color: var(--text); border: 1px solid var(--border); cursor: pointer;
    font-variant-numeric: tabular-nums; }
.slot:hover { border-color: var(--accent); }
.slot.unavailable { color: var(--text3); opacity: 0.45; text-decoration: line-through; cursor: not-allowed;
    border-color: transparent; }
.slot.selected { background: var(--accent); border-color: var(--accent); color: #fff; }
.slot-msg { text-align: center; color: var(--text2); font-size: 0.85rem; margin: 14px 0 0; }
/* .slot-msg loads after the house .flash/.flash-error rules (style.css, then app.css) and shares their
   specificity, so its own color/font-size/text-align would silently win over the white-on-red toast --
   pin them back here whenever the "no times" state adds .flash-error onto the same element. */
.slot-msg.flash-error { text-align: left; color: #fff; font-size: 0.9rem; }

/* Ordinary bottom breathing room. Was 80px, reserved as clearance above the sticky .booking-bar --
   no longer needed now that .booking-bar is an ordinary in-flow row (05 Sep 2026), not a floating panel. */
.pstep { padding-bottom: 16px; }
.slot-hint { text-align: center; color: var(--text2); font-size: 0.8rem; margin: 12px 2px 4px; }
.slot-hint a { color: var(--accent); text-decoration: underline; white-space: nowrap; }

/* Area option cards. NEW (no shared option-card). */
.radio-card { display: flex; gap: 12px; align-items: flex-start; background: var(--surface);
    border: 1px solid var(--border); border-radius: 12px; padding: 14px; margin-bottom: 10px; cursor: pointer; }
.radio-card.on { border-color: var(--accent); }
.radio-card .dot { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--border);
    flex: 0 0 auto; margin-top: 1px; position: relative; }
.radio-card.on .dot { border-color: var(--accent); }
.radio-card.on .dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
.radio-card .rc-title { font-size: 0.95rem; font-weight: 600; color: var(--text); }
.radio-card .rc-note { font-size: 0.8rem; color: var(--text2); margin-top: 2px; }

.privacy { text-align: center; color: var(--text2); font-size: 0.8rem; margin: 4px 0 16px; }

/* Review step: one row per entered field, each with a Change link back to its step. */
.review-row { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.review-row:last-child { border-bottom: none; }
.review-row .rv-label { color: var(--text2); font-size: 0.78rem; min-width: 84px; }
.review-row .rv-val { flex: 1; color: var(--text); font-size: 0.95rem; word-break: break-word; }

/* Phone field: country dialling-code select + national number, side by side under one label. NEW. */
.phone-input { display: flex; gap: 10px; align-items: center; }
/* The select shows only the dialling code (e.g. +34) once chosen - see the collapse script on each form
   that swaps the selected option's text to its code - so it is sized to a code, not the country name. */
.phone-input select { flex: 0 0 auto; width: 6em; }
.phone-input input { flex: 1; }

/* Booking-form action row (Cancel/Back/Continue/Confirm). Was a sticky bottom panel; changed to an
   ordinary in-flow row (05 Sep 2026) -- on a phone, position:sticky means it floats over WHATEVER
   content is currently scrolled underneath it (time slots, area cards, hint text), not just the very
   end of the page; no amount of bottom clearance fixes that, since the overlap happens mid-scroll, not
   only at the bottom. These screens are short enough that losing the always-visible pinning (Continue
   included) costs little, and this now behaves exactly like the SHOW MENUS button: same .btn-row, no
   special box. */
.booking-bar { margin-top: 4px; }

/* Month calendar popover (guest date picker). NEW component (you signed this off as new). */
.pcal { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 50;
    width: min(360px, 92vw); background: var(--surface2); border: 1px solid var(--border);
    border-radius: 16px; padding: 16px; box-shadow: 0 24px 60px rgba(0,0,0,0.5); }
.pcal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.pcal-head b { font-size: 0.95rem; }
.pcal-nav { background: none; border: none; color: var(--accent); font-size: 1.4rem; cursor: pointer; width: 36px; }
/* Same look as .pcal-nav but its own class -- the month-nav click handler binds by .pcal-nav and would
   misfire (NaN month jump) if the menu popover's close button shared that class. */
.pcal-close { background: none; border: none; color: var(--accent); font-size: 1.4rem; cursor: pointer; width: 36px; }
/* Menus popover: unlike the calendar (always a fixed small grid), a business's menu can be far taller
   than the screen. Without this the whole popover -- including its close button in .pcal-head -- could
   overflow the viewport with no way to scroll back up to close it. The header stays put; only the menu
   list scrolls. */
/* :not([hidden]) matters here: an ID selector setting display outranks the browser's own
   [hidden]{display:none} rule, so a bare "display:flex" would show the popover on every page load
   regardless of the hidden attribute -- confirmed live on PROD, 30 Aug 2026. */
#menuPopover:not([hidden]) { max-height: 80vh; display: flex; flex-direction: column; }
/* One menu item row: name left (wraps freely), price right (never wraps -- flex:0 0 auto plus
   white-space:nowrap stops a long name from squeezing the price column down to nothing, which used to
   wrap the price itself character-by-character). Same font-size on both sides -- price is not a
   secondary/muted value here, it's exactly as important as the name. Tighter padding than .review-row
   (which this used to reuse): a dense menu list needs less air between lines than a 4-row booking
   summary does. */
.menu-item { padding: 6px 14px; border-bottom: 1px solid var(--border); }
.menu-item:last-child { border-bottom: none; }
.menu-item .mi-name { color: var(--text); font-size: 0.85rem; }
.menu-item .mi-price { color: var(--text); font-size: 0.85rem; flex: 0 0 auto; white-space: nowrap;
    font-variant-numeric: tabular-nums; }
.menu-item .mi-allerg { color: var(--warning); font-size: 0.72rem; margin-top: 2px; }
#menuPopover .pcal-head { flex: 0 0 auto; }
#menuBody { overflow-y: auto; }
.pcal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.pcal-grid > span { text-align: center; font-size: 0.65rem; color: var(--text2); text-transform: uppercase; padding: 2px 0; }
.pcal-day { text-align: center; font-size: 0.9rem; padding: 9px 0; border-radius: 8px; color: var(--text);
    background: transparent; border: none; cursor: pointer; font-variant-numeric: tabular-nums; font-family: inherit; }
.pcal-day:hover { background: var(--surface); }
.pcal-day.off { color: var(--text3); opacity: 0.3; cursor: not-allowed; }
.pcal-day.sel { background: var(--accent); color: #fff; }
.pcal-day.empty { visibility: hidden; }

/* Confirmation block — copied verbatim from EventManagement app.css (the established house pattern). */
.confirmation-box { background: var(--surface); border-radius: 14px; padding: 24px; text-align: center; margin: 20px 0; }
.confirmation-ref { font-size: 2rem; font-weight: 700; color: var(--accent); letter-spacing: 2px; margin: 16px 0; }
.confirmation-detail { font-size: 0.9rem; color: var(--text2); margin: 6px 0; }

/* Embed mode (iframe on the venue website) — no header, full-height content. Mirrors the established
   EventManagement app.css convention. */
.embed-mode #header { display: none; }
.embed-mode #content { min-height: 100dvh; }

/* POS-mode (the one physical POS terminal, 1920x1080 landscape — opted in via a device-only cookie,
   see app.py _set_pos_mode_cookie): reflow the New/Edit Booking screen into multiple columns so it
   fits the full landscape width with no vertical scrolling. #bkform is unique to booking_form.html,
   so this cannot match any other screen. :has() scopes it to plain label+input field-groups (WHEN AND
   WHERE, GUEST, STATUS) — the Choose a Table candidate list (#cand-list, gridded separately below) and
   the Area radio-cards (.tm-area-cards, also below) have no .field-row children, so they're untouched
   by this rule. */
.pos-mode #bkform .field-group:has(> .field-row) {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 16px;
}
.pos-mode #bkform .field-group:has(> .field-row) > .field-row {
    border-bottom: none;
}

/* POS-mode Area picker: same .radio-card component as public/book.html, just gridded (that form
   stacks them single-column on a phone-width screen; the POS terminal has room to lay them out). */
.pos-mode .tm-area-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px;
    margin-bottom: 16px;
}
.pos-mode .tm-area-cards .radio-card { margin-bottom: 0; }

/* POS-mode candidate list ("doom scroll" fix, 10 Sep 2026): with every table shown (Show all free
   tables), a busy venue can have 25-30+ rows in one stacked column. Grid it instead -- same data, same
   "Show all free tables" logic untouched, just laid out to use the terminal's width instead of its
   height. The !important overrides the per-row border-bottom the JS sets inline (render() in
   booking_form.html's scripts block) -- a leftover separator from the old single-column list that
   reads as a stray partial rule once rows sit side by side. */
.pos-mode #cand-list {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0 14px;
}
.pos-mode #cand-list label { border-bottom: none !important; }

/* ---- Diary / run sheet (backlog 97/98/101/102) ---- */
.print-only{display:none;}
.tm-datenav{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
/* .btn-back's page-level margin-bottom:16px (meant for a lone Back button above content) otherwise
   pushes the TODAY button off this row's shared centre line - .btn-row already neutralises it, this
   row needs the same. */
.tm-datenav .btn-back{margin-bottom:0;}
.tm-navbtn{width:34px;height:34px;display:grid;place-items:center;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text);text-decoration:none;font-size:18px;}
.tm-navbtn:hover{background:var(--border);}
.tm-curdate{font-weight:600;font-variant-numeric:tabular-nums;min-width:9.5em;text-align:center;}
.tm-tabs{display:flex;gap:4px;background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:4px;flex-wrap:wrap;margin-bottom:14px;}
.tm-tab{background:none;border:0;color:var(--text2);font:inherit;font-weight:600;padding:7px 14px;border-radius:7px;cursor:pointer;}
.tm-tab:hover{color:var(--text);}
.tm-tab.active{background:var(--border);color:var(--text);}
.tm-panel{display:none;}
.tm-panel.active{display:block;}
.tm-totstrip{color:var(--text2);font-size:13px;margin-bottom:12px;}
.tm-totstrip b{color:var(--text);font-variant-numeric:tabular-nums;}
.tm-toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:14px;}
.tm-search,.tm-select{background:var(--surface);border:1px solid var(--border);border-radius:9px;color:var(--text);font:inherit;padding:8px 12px;}
.tm-search{min-width:210px;flex:1;}
/* Floating search box (Resos-style): a rounded bar that slides down from the top over the screen, opened
   by the hamburger Search entry and the Bookings top-bar Search button. */
.tm-searchoverlay{display:none;position:fixed;inset:0 0 auto 0;z-index:100;padding:14px 16px;}
.tm-searchoverlay.open{display:block;animation:tmSearchDrop .16s ease;}
@keyframes tmSearchDrop{from{opacity:0;transform:translateY(-14px);}to{opacity:1;transform:translateY(0);}}
.tm-searchbar{display:flex;align-items:center;gap:10px;max-width:680px;margin:0 auto;background:var(--surface);
  border:1px solid var(--border);border-radius:12px;padding:12px 14px;box-shadow:0 10px 30px rgba(0,0,0,.45);}
.tm-searchicon{width:20px;height:20px;color:var(--text2);flex:0 0 auto;}
.tm-searchbar input{flex:1;min-width:0;background:transparent;border:0;outline:none;color:var(--text);font:inherit;padding:2px 0;}
.tm-searchclose{flex:0 0 auto;background:transparent;border:0;color:var(--text2);font-size:22px;line-height:1;cursor:pointer;padding:0 2px;}
.tm-searchclose:hover{color:var(--text);}
.tm-searchscope{flex:0 0 auto;padding:8px 10px;}
.tm-sheet{border:1px solid var(--border);border-radius:12px;overflow:hidden;margin-bottom:12px;}
.tm-band{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--surface);border-bottom:1px solid var(--border);font-weight:650;}
.tm-band-tot{margin-left:auto;font-size:12px;color:var(--text2);font-weight:500;font-variant-numeric:tabular-nums;}
table.tm-run{width:100%;border-collapse:collapse;}
table.tm-run th{text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--text2);font-weight:650;padding:9px 12px;border-bottom:1px solid var(--border);}
table.tm-run td{padding:11px 12px;border-bottom:1px solid var(--border);vertical-align:middle;}
table.tm-run tr:last-child td{border-bottom:0;}
.tm-runrow{cursor:pointer;}
.tm-runrow:hover{background:var(--surface);}
.tm-rtime{font-variant-numeric:tabular-nums;font-weight:600;white-space:nowrap;}
.tm-end{color:var(--text2);font-weight:400;}
.tm-rname{font-weight:600;}
.tm-rcov{text-align:center;font-weight:700;font-variant-numeric:tabular-nums;}
.tm-rnote{color:var(--accent);}
.src{color:var(--text2);}
.src svg{width:24px;height:24px;display:block;}
.tm-soon{color:var(--text2);padding:24px;text-align:center;border:1px dashed var(--border);border-radius:12px;}

@media print{
  #header,.nav-links,.no-print,.tm-tabs,.tm-datenav,.tm-toolbar,.flash{display:none !important;}
  .print-only{display:block;}
  body,#app,#content{background:#fff !important;color:#111 !important;}
  .tm-printhead h2{color:#111;margin:0 0 2px;}
  .tm-pmeta{color:#555;font-size:12px;margin-bottom:14px;}
  .tm-sheet{border:1px solid #ccc;margin-bottom:14px;page-break-inside:avoid;}
  .tm-band{background:#eee !important;color:#111 !important;border-bottom:1px solid #ccc;}
  .tm-band-tot{color:#555;}
  table.tm-run th{color:#fff;background:#333;}
  table.tm-run td{color:#222;border-bottom:1px solid #ddd;}
  .tm-end{color:#777;}
  .badge{border:1px solid #bbb;color:#222 !important;background:#f3f3f3 !important;}
  .src{color:#555;}
}

/* run-sheet: FIXED column layout so every service band and day group lines up on one grid (a report is
   viewed on a wide 27" restaurant touchscreen; auto-width tables drift band to band). Guest column has
   no width so it absorbs the remaining space; all others are explicit and identical on every table. */
table.tm-run{table-layout:fixed;min-width:760px;}
table.tm-run th,table.tm-run td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
table.tm-run th:nth-child(1),table.tm-run td:nth-child(1){width:130px;}                     /* Time */
table.tm-run th:nth-child(2),table.tm-run td:nth-child(2){width:40px;text-align:center;padding-left:4px;padding-right:4px;} /* Source */
table.tm-run th:nth-child(4),table.tm-run td:nth-child(4){width:90px;text-align:center;}    /* People */
table.tm-run th:nth-child(5),table.tm-run td:nth-child(5){width:220px;white-space:normal;}  /* Table */
table.tm-run th:nth-child(6),table.tm-run td:nth-child(6){width:150px;white-space:normal;} /* Notes */
.tm-rnotes{white-space:normal;vertical-align:middle;}
.tm-rnotes .badge{display:inline-block;margin:2px 4px 2px 0;}
table.tm-run th:nth-child(7),table.tm-run td:nth-child(7){width:150px;}                      /* Status */
.tm-run .src{display:inline-flex;}
.tm-tablescroll{overflow-x:auto;}
/* Bookings run sheet (table.tm-bk): Guest is a fixed column sized for the 30 characters the template shows;
   Table is the column that absorbs the spare width and holds four table slugs per row before wrapping. Slugs
   share one minimum width, so a wrapped row lines up under the row above it. min-width = the fixed columns
   plus room for four slugs; narrower screens scroll sideways inside .tm-tablescroll. */
table.tm-bk{min-width:1200px;}
table.tm-bk th:nth-child(3),table.tm-bk td:nth-child(3){width:calc(30ch + 24px);}
table.tm-bk th:nth-child(5),table.tm-bk td:nth-child(5){width:auto;}
.tm-tchips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.tm-tchips .badge{min-width:74px;text-align:center;margin:0;}
/* Guests directory: fixed column widths so Guest + Phone are never truncated and Email is constrained
   (ellipsis) instead of dominating; sortable headers show the active direction. */
.tm-gtbl{table-layout:fixed;min-width:640px;}
.tm-gtbl col.c-name{width:26%;}
.tm-gtbl col.c-phone{width:150px;}
.tm-gtbl col.c-book{width:130px;}
.tm-gtbl col.c-last{width:150px;}
.tm-gtbl td.c-phone{white-space:nowrap;}
.tm-gtbl td.c-email{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tm-gtbl th.sortable{cursor:pointer;user-select:none;white-space:nowrap;}
.tm-gtbl th.sortable[data-dir="asc"]::after{content:" \25B2";}
.tm-gtbl th.sortable[data-dir="desc"]::after{content:" \25BC";}
/* The current-status chip in the booking form's top action bar: a badge, not a button - keep its own
   small height instead of stretching to the button row. */
.btn-row .status-chip{align-self:center;}
/* Meet & Greet arrivals list: full-width tappable rows, two columns (time, name), big touch targets, no
   table so it never overflows a phone. Selected row is outlined in the accent. */
/* Capped width so the screen is tidy on a PC (and can sit beside the keytag window); still fills a phone. */
.tm-greet{max-width:760px;}
/* Icon-only action buttons (Walk-in = Indalo man, Phone) - compact so all four buttons fit one phone line. */
.btn-ico{padding-left:14px;padding-right:14px;}
.btn-ico svg{width:20px;height:20px;display:block;}
.tm-greetlist{display:flex;flex-direction:column;gap:2px;}
.tm-greetrow{display:flex;align-items:center;gap:16px;width:100%;text-align:left;background:var(--surface);
  border:1px solid transparent;border-radius:10px;padding:16px;color:var(--text);font:inherit;cursor:pointer;}
.tm-greetrow:active{background:var(--surface2,#2c2c2e);}
.tm-greetrow.selected{border-color:var(--accent);background:var(--surface2,#2c2c2e);}
.tm-greettime{font-weight:700;font-variant-numeric:tabular-nums;font-size:1.1rem;flex:0 0 auto;min-width:3.6em;}
.tm-greetname{font-weight:600;font-size:1.05rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Status chip sits at the right of the row; seated/paid/left rows are informational (not tap-to-seat). */
.tm-greetrow .badge{margin-left:auto;flex:0 0 auto;}
.tm-greetrow.done{cursor:default;}
.tm-greetrow.done:active{background:var(--surface);}

/* ---- Current service board (Phase 3a) ---- */
.tm-svchead{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:14px;}
.tm-svchead h2{font-size:20px;margin:0;}
.tm-svcwin{color:var(--text2);font-variant-numeric:tabular-nums;}
.tm-metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px;}
@media (max-width:900px){.tm-metrics{grid-template-columns:repeat(2,1fr);}}
.tm-metric{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:14px 16px;}
.tm-metric .lbl{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--text2);font-weight:600;}
.tm-metric .big{font-size:30px;font-weight:680;margin-top:4px;font-variant-numeric:tabular-nums;}
.tm-metric .big small{font-size:15px;color:var(--text2);font-weight:500;}
.tm-metric .sub{font-size:12px;color:var(--text2);margin-top:2px;min-height:1.2em;}
.tm-bar{height:6px;border-radius:999px;background:var(--border);margin-top:10px;overflow:hidden;}
.tm-bar>span{display:block;height:100%;}
.tm-cardhead{padding:12px 16px;border-bottom:1px solid var(--border);font-weight:650;}
.tm-arr{display:flex;gap:12px;padding:12px 14px;border-bottom:1px solid var(--border);align-items:center;cursor:pointer;}
.tm-arr:last-child{border-bottom:0;}
.tm-arr:hover{background:var(--bg);}
.tm-arr-t{font-weight:600;min-width:46px;font-variant-numeric:tabular-nums;}
.tm-arr-who{flex:1;min-width:0;}
.tm-arr-nm{font-weight:600;}
.tm-arr-meta{margin-top:2px;}
.tm-arr-cov{font-weight:700;font-variant-numeric:tabular-nums;min-width:1.6em;text-align:center;}
.tm-arr-due{background:color-mix(in srgb,var(--warning) 10%,transparent);}

/* ---- POS home: Coming up + Floor right now side by side (admin_pos only) ---- */
.tm-csgrid{display:grid;grid-template-columns:1.15fr 1fr;gap:16px;align-items:start;}
.tm-csgrid.tm-csgrid-single{grid-template-columns:1fr;}
@media (max-width:920px){.tm-csgrid{grid-template-columns:1fr;}}

/* ---- Floor right now (live occupancy, tabbed by area) ----
   A responsive tile grid in table-label order (NOT the physical floor-plan layout) so it fills whatever
   width is available instead of scaling one fixed-aspect canvas down to nothing on a small window. */
.fpn-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:10px;padding:14px;}
.fpn-tile{background:var(--surface2, var(--surface));border:2px solid var(--border);border-radius:10px;
    padding:12px 6px;min-height:76px;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:3px;text-align:center;color:var(--text);text-decoration:none;cursor:default;}
a.fpn-tile{cursor:pointer;}
.fpn-tile.fpn-occ{background:color-mix(in srgb,var(--accent2) 22%,var(--surface2));border-color:var(--accent2);}
.fpn-tile.fpn-soon{background:color-mix(in srgb,var(--warning) 22%,var(--surface2));border-color:var(--warning);}
.fpn-tile-label{font-weight:700;font-size:1.05rem;}
.fpn-tile-sub{font-size:0.78rem;color:var(--text2);}
.fpn-tile-bill{font-size:0.7rem;font-weight:700;letter-spacing:.05em;color:var(--accent);}
.fpn-legend{display:flex;gap:18px;flex-wrap:wrap;margin:12px 14px;font-size:0.85rem;color:var(--text2);}
.fpn-legend span{display:inline-flex;align-items:center;gap:6px;}
.fpn-legend i{width:12px;height:12px;border-radius:3px;display:inline-block;border:2px solid var(--border);}
.fpn-legend i.occ{background:var(--accent2);border-color:var(--accent2);}
.fpn-legend i.soon{background:var(--warning);border-color:var(--warning);}

/* ---- Month calendar (Phase 4) ---- */
.tm-monthnav{display:flex;align-items:center;gap:8px;margin-bottom:10px;}
.tm-cal{border:1px solid var(--border);border-radius:12px;overflow:hidden;}
.tm-cal-head,.tm-cal-row{display:grid;grid-template-columns:repeat(7,1fr);}
.tm-cal-head div{padding:8px 10px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--text2);font-weight:650;border-bottom:1px solid var(--border);}
.tm-cell{min-height:92px;border-right:1px solid var(--border);border-bottom:1px solid var(--border);padding:7px 8px;display:flex;flex-direction:column;gap:5px;}
.tm-cell:nth-child(7n){border-right:0;}
.tm-cell.out{background:color-mix(in srgb,var(--bg) 45%,transparent);}
.tm-cell.out .tm-dn{color:var(--text3, var(--text2));opacity:.5;}
.tm-cell.closed{background:repeating-linear-gradient(135deg,transparent 0 7px,color-mix(in srgb,var(--border) 45%,transparent) 7px 8px);}
.tm-cell[onclick]{cursor:pointer;}
.tm-cell[onclick]:hover{background:var(--surface);}
.tm-dn{font-weight:650;font-variant-numeric:tabular-nums;}
.tm-cell.today .num{background:var(--text);color:var(--bg);width:22px;height:22px;border-radius:50%;display:inline-grid;place-items:center;}
.tm-daytot{font-variant-numeric:tabular-nums;font-size:13px;}
.tm-daytot b{font-weight:700;}
.tm-split{display:flex;flex-wrap:wrap;gap:8px;margin-top:auto;font-size:11px;color:var(--text2);}
.tm-split span{display:inline-flex;align-items:center;gap:4px;font-variant-numeric:tabular-nums;}
.tm-split i{width:8px;height:8px;border-radius:2px;}
.tm-closed{font-size:11px;color:var(--warning);font-weight:600;align-self:flex-start;}
@media (max-width:700px){.tm-cell{min-height:64px;font-size:12px;}.tm-split{display:none;}}

/* ---- Schedule timeline (Phase 5) ---- */
.tm-tlscroll{overflow-x:auto;border:1px solid var(--border);border-radius:12px;}
.tm-tl{min-width:900px;position:relative;}
.tm-tl-head,.tm-tl-heat,.tm-tl-row{display:grid;grid-template-columns:120px 1fr;}
.tm-tl-head{border-bottom:1px solid var(--border);position:sticky;top:0;background:var(--surface);z-index:3;}
.tm-tl-lbl{padding:8px 10px;border-right:1px solid var(--border);display:flex;align-items:center;gap:8px;}
.tm-rn{font-weight:700;font-variant-numeric:tabular-nums;}
.tm-cap{font-size:10.5px;color:var(--text2);}
.tm-tl-axis{position:relative;height:32px;}
.tm-tk{position:absolute;top:0;bottom:0;border-left:1px solid var(--border);padding-left:4px;font-size:10.5px;color:var(--text2);display:flex;align-items:center;font-variant-numeric:tabular-nums;}
.tm-tl-heat{background:var(--surface);border-bottom:1px solid var(--border);}
.tm-tl-heat .tm-tl-lbl{font-size:10.5px;color:var(--text2);text-transform:uppercase;}
.tm-heat{position:relative;height:26px;display:flex;align-items:flex-end;}
.tm-hc{flex:1;display:flex;align-items:flex-end;justify-content:center;border-left:1px solid color-mix(in srgb,var(--border) 40%,transparent);}
.tm-hc>i{display:block;width:66%;border-radius:2px 2px 0 0;background:var(--accent);opacity:.85;min-height:1px;}
.tm-tl-zone{background:var(--surface);padding:6px 12px;font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--text2);font-weight:650;border-top:1px solid var(--border);border-bottom:1px solid var(--border);}
.tm-tl-row{border-bottom:1px solid var(--border);}
.tm-tl-row:hover{background:color-mix(in srgb,var(--surface) 50%,transparent);}
.tm-lane{position:relative;height:42px;}
.tm-gl{position:absolute;top:0;bottom:0;border-left:1px solid color-mix(in srgb,var(--border) 45%,transparent);}
.tm-blk{position:absolute;top:6px;height:30px;border-radius:7px;padding:0 8px;display:flex;align-items:center;gap:6px;font-size:12px;overflow:hidden;white-space:nowrap;cursor:pointer;}
.tm-blk .tm-bn{font-weight:600;overflow:hidden;text-overflow:ellipsis;}
.tm-blk .tm-bc{font-weight:700;opacity:.9;margin-left:auto;}
.tm-blk.svc-lunch{background:color-mix(in srgb,var(--accent2) 22%,var(--surface));border:1px solid color-mix(in srgb,var(--accent2) 55%,transparent);}
.tm-blk.svc-dinner{background:color-mix(in srgb,var(--accent) 22%,var(--surface));border:1px solid color-mix(in srgb,var(--accent) 55%,transparent);}
.tm-blk.svc-other{background:var(--surface);border:1px solid var(--border2, var(--border));}
.tm-blk.seated{box-shadow:inset 3px 0 0 var(--accent2);}
.tm-nowline{position:absolute;top:0;bottom:0;width:2px;background:var(--warning);z-index:4;pointer-events:none;}
.tm-nowline::before{content:attr(data-now);position:absolute;top:0;left:2px;font-size:10px;color:var(--bg);background:var(--warning);padding:1px 4px;border-radius:0 4px 4px 0;font-weight:700;font-variant-numeric:tabular-nums;}

/* Availability preview timeline (sittings.html) -- same .tm-tl component as the POS Schedule tab above,
   with slot-availability colouring and last-slot/close markers instead of booking blocks and a now-line. */
.tm-blk.av-ok{background:color-mix(in srgb,var(--accent2) 22%,var(--surface));border:1px solid color-mix(in srgb,var(--accent2) 55%,transparent);}
.tm-blk.av-full{background:color-mix(in srgb,var(--danger) 16%,var(--surface));border:1px solid color-mix(in srgb,var(--danger) 45%,transparent);}
.tm-lastline{position:absolute;top:0;bottom:0;width:2px;background:var(--accent2);z-index:4;pointer-events:none;}
.tm-lastline::before{content:attr(data-label);position:absolute;top:0;left:2px;font-size:10px;color:var(--bg);background:var(--accent2);padding:1px 4px;border-radius:0 4px 4px 0;font-weight:700;white-space:nowrap;}
.tm-closeline{position:absolute;top:0;bottom:0;width:2px;background:var(--text2);z-index:3;pointer-events:none;}
.tm-closeline::before{content:attr(data-label);position:absolute;bottom:0;left:2px;font-size:10px;color:var(--bg);background:var(--text2);padding:1px 4px;border-radius:4px 4px 0 0;font-weight:700;white-space:nowrap;}
/* "Guests leave by" -- the cutoff that actually drives the last bookable slot, distinct from
   .tm-closeline (the real, unchanged Core close_time / kitchen close). Amber: this is now the
   economically load-bearing marker. */
.tm-leavebyline{position:absolute;top:0;bottom:0;width:2px;background:var(--warning);z-index:4;pointer-events:none;}
.tm-leavebyline::before{content:attr(data-label);position:absolute;top:0;left:2px;font-size:10px;color:var(--bg);background:var(--warning);padding:1px 4px;border-radius:0 4px 4px 0;font-weight:700;white-space:nowrap;}
.tm-tl-dead{position:absolute;top:0;bottom:0;background:color-mix(in srgb,var(--text2) 8%,transparent);z-index:1;pointer-events:none;}
.tm-leg-dot{width:12px;height:12px;border-radius:3px;display:inline-block;border:2px solid var(--border);}
.tm-leg-dot.av-ok{background:var(--accent2);border-color:var(--accent2);}
.tm-leg-dot.av-full{background:var(--danger);border-color:var(--danger);}
.tm-leg-line{width:12px;height:3px;display:inline-block;border-radius:2px;}
.tm-leg-line.tm-lastline{position:static;background:var(--accent2);}
.tm-leg-line.tm-closeline{position:static;background:var(--text2);}

/* Evidentiary timeline (booking_form.html) -- a simple vertical line of dots, oldest event at the top. */
.tm-vtimeline{position:relative;padding-left:18px;}
.tm-vtimeline::before{content:'';position:absolute;left:4px;top:4px;bottom:4px;width:2px;background:var(--border);}
.tm-vt-row{position:relative;padding:0 0 14px;}
.tm-vt-row:last-child{padding-bottom:0;}
.tm-vt-dot{position:absolute;left:-18px;top:4px;width:10px;height:10px;border-radius:50%;background:var(--accent2);border:2px solid var(--surface);}
.tm-vt-meta{font-size:0.75rem;color:var(--text2);margin-bottom:2px;}
.tm-vt-summary{font-size:0.88rem;color:var(--text);}
/* Indented order-item lines under a kind='order' timeline row (Full Booking Record / complaint record,
   05 Sep 2026) -- same row, one line per item, quieter than the summary above it. */
.tm-vt-detail{font-size:0.8rem;color:var(--text2);margin:2px 0 0 10px;}
.tm-leg-line.tm-leavebyline{position:static;background:var(--warning);}

/* ---- Week view (per-service detail for rota planning) ---- */
.tm-week{display:grid;grid-template-columns:repeat(7,1fr);gap:8px;}
@media (max-width:1100px){.tm-week{grid-template-columns:repeat(4,1fr);}}
@media (max-width:760px){.tm-week{grid-template-columns:repeat(2,1fr);}}
@media (max-width:460px){.tm-week{grid-template-columns:1fr;}}
.tm-wday{border:1px solid var(--border);border-radius:10px;padding:9px 10px;display:flex;flex-direction:column;gap:7px;min-height:120px;background:var(--surface);}
.tm-wday.closed{background:repeating-linear-gradient(135deg,transparent 0 7px,color-mix(in srgb,var(--border) 45%,transparent) 7px 8px);}
.tm-wday[onclick]{cursor:pointer;}
.tm-wday[onclick]:hover{border-color:var(--accent);}
.tm-wday.today{border-color:var(--accent);}
.tm-wdate{display:flex;align-items:baseline;justify-content:space-between;gap:6px;border-bottom:1px solid var(--border);padding-bottom:5px;}
.tm-wdate .num{font-weight:650;font-variant-numeric:tabular-nums;}
.tm-wtot{font-size:11px;color:var(--text2);font-variant-numeric:tabular-nums;}
.tm-wsvc{background:var(--bg);border-radius:7px;padding:5px 7px;}
.tm-wsvc-top{display:flex;align-items:baseline;justify-content:space-between;gap:6px;}
.tm-wsvc-n{font-weight:600;font-size:12.5px;}
.tm-wsvc-w{font-size:10.5px;color:var(--text2);font-variant-numeric:tabular-nums;}
.tm-wsvc-c{font-size:12px;color:var(--text2);font-variant-numeric:tabular-nums;margin-top:1px;}
.tm-wsvc-c b{color:var(--text);font-weight:700;}
.tm-wempty{color:var(--text2);}

/* Week view: published-rota staff under each service */
.tm-wstaff{margin-top:5px;border-top:1px dashed var(--border);padding-top:5px;display:flex;flex-direction:column;gap:3px;}
.tm-wperson{display:flex;align-items:baseline;justify-content:space-between;gap:6px;font-size:11.5px;}
.tm-wp-n{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tm-wp-r{color:var(--text2);font-size:10.5px;white-space:nowrap;flex:none;}

/* Week view: keytag scan status dot behind each staff name */
.tm-scan{width:9px;height:9px;border-radius:50%;display:inline-block;margin-right:5px;flex:none;vertical-align:middle;}
.tm-scan-grey{background:var(--text2);}
.tm-scan-green{background:var(--accent2);}
.tm-scan-amber{background:var(--warning);}
.tm-scan-red{background:var(--danger);}

/* ============================================================================
   ORDERS (table service): waiter home, order picker, kitchen/bar/serve queues.
   App-specific classes (the master style.css is never edited). Tokens only.
   ============================================================================ */

/* Small muted meta line reused across the order screens. */
.tmo-meta{font-size:12px;color:var(--text2);}
.tmo-empty{text-align:center;padding:52px 20px;color:var(--text2);}
.tmo-refreshdot{width:8px;height:8px;border-radius:50%;background:var(--warning);display:inline-block;}
/* Sticky order header: keeps actions + table/server + cover buttons in view while the menu scrolls.
   Mirrors the global .btn-row.is-sticky-top pin (top:-16px against #content's 16px padding, full-width
   band via negative side margins). */
.tmo-sticky-head{position:sticky;top:-16px;z-index:20;background:var(--bg);margin:-16px -16px 8px;padding:16px 16px 8px;}
.tmo-strip{display:flex;justify-content:flex-start;align-items:center;flex-wrap:wrap;gap:10px;margin-top:10px;margin-bottom:8px;}
.tmo-serversel{flex:0 1 auto;max-width:220px;padding:6px 10px;}
.tmo-strip-meta{margin-left:auto;}

/* Queue card (kitchen / bar / serve) - always open, not a collapsible .card. */
/* Each order card reads as one physical order slip: a subtle top-lit paper shade over the surface, a
   ruled left "margin" in the accent colour, and a soft drop shadow lifting it off the page. CSS only, so
   it stays theme-aware (the neutral overlay lightens the dark surface and darkens the light one). */
.tmo-order{background:linear-gradient(180deg,rgba(127,127,127,0.06),rgba(127,127,127,0) 64px),var(--surface);
    border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:12px;
    padding:12px 14px 14px 16px;margin-bottom:12px;box-shadow:0 6px 14px rgba(0,0,0,0.18);}
.tmo-order.late{border-color:var(--danger);border-left-color:var(--danger);}
.tmo-order.is-drink{border-left-color:#ff9f0a;}          /* DRINKS ticket = amber left bar (vs blue food) */
.tmo-order.is-drink .tmo-ctitle{color:#ff9f0a;}
.tmo-ohead{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:8px;}
.tmo-readyt{margin-left:auto;font-weight:600;color:var(--text2);font-variant-numeric:tabular-nums;}
.tmo-elapsed{display:none;}                               /* revealed by the "Mins" toggle on Serve */
body.show-elapsed .tmo-elapsed{display:inline;}
.tmo-table{font-size:1.1rem;font-weight:700;color:var(--text);}
.tmo-ref{font-size:11px;color:var(--text2);}
.tmo-course{border-top:1px dashed var(--border);padding-top:8px;margin-top:8px;}
.tmo-course:first-of-type{border-top:0;margin-top:0;}
.tmo-ctitle{font-size:12px;font-weight:700;letter-spacing:0.6px;text-transform:uppercase;color:var(--accent);margin-bottom:6px;}
.tmo-course.is-held{opacity:0.5;}
.tmo-course.is-held .tmo-ctitle{color:var(--text2);}
.tmo-hold{font-weight:600;font-size:11px;letter-spacing:0;text-transform:none;color:var(--text2);}
.tmo-dish{display:flex;align-items:baseline;gap:8px;padding:3px 0;}
.tmo-qty{font-weight:700;color:var(--text);min-width:26px;}
.tmo-dname{color:var(--text);flex:1;}
.tmo-covers{font-size:11px;color:var(--text2);white-space:nowrap;}
.tmo-diet{display:inline-block;font-size:10.5px;font-weight:700;letter-spacing:0.4px;color:#000;background:var(--warning);border-radius:5px;padding:1px 6px;margin-left:4px;}
.tmo-cook{display:inline-block;font-size:10.5px;font-weight:700;color:#fff;background:var(--accent);border-radius:5px;padding:1px 6px;margin-left:4px;text-transform:uppercase;}
.tmo-swap{font-size:12px;color:var(--warning);font-weight:600;margin:1px 0 4px 30px;text-transform:uppercase;}   /* alternate-ingredient note */
/* AV/AGF "available vegan/GF" toggle: GREEN (distinct from the amber info slugs), clickable. Dashed
   outline when off, solid green fill when the waiter has selected it. Black text on green passes WCAG on
   both themes; the off-state text uses --text so it stays legible on light and dark. */
.tmo-swapbtn{cursor:pointer;font-family:inherit;vertical-align:middle;background:transparent;color:var(--text);border:1px dashed var(--accent2);}
.tmo-swapbtn.is-on{background:var(--accent2);color:#000;border-style:solid;}
/* Missing-cover warning overlay */
.tmo-modal{position:fixed;inset:0;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;z-index:50;padding:20px;}
.tmo-modal[hidden]{display:none;}
.tmo-modal-box{background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:20px;max-width:360px;width:100%;}
.tmo-modal-title{font-size:1.05rem;font-weight:700;margin-bottom:8px;color:var(--text);}
.tmo-modal-msg{font-size:0.95rem;color:var(--text2);margin-bottom:16px;}
/* Manager Override covers-cap modal (220926) - reuses .tmo-modal above */
/* Two caps (service + interval) can trip in the same save; each renders as its own line. */
.tmo-modal-msg div + div{margin-top:6px;}
.override-hint{margin-bottom:8px;}
.override-pin-input{width:100%;box-sizing:border-box;margin-bottom:10px;}
/* POS keytag operator lock (090826) */
.pos-lock-box{text-align:center;}
.pos-keytag-input{position:absolute;opacity:0;width:1px;height:1px;border:0;pointer-events:none;}
.pos-operator-bar{margin-bottom:8px;}
/* .btn-row sets display:flex at the same specificity as the browser's default [hidden]{display:none},
   so the author rule wins the cascade tie and hidden has no visual effect unless overridden here
   (found live 090826: the operator bar and the lock overlay were both visible at once). */
.pos-operator-bar[hidden]{display:none;}
/* Once moved into #header (see _pos_lock.html) it must lose .btn-row's own block-layout margins
   (margin-top:12px, flex-wrap:wrap) and instead sit centred as a flex-row middle child — margin:0 auto
   splits #header's space-between slack evenly on both sides regardless of the two siblings' widths. */
.pos-header-slot{margin:0 auto;flex-wrap:nowrap;}
/* .badge is display:inline-block with no flex centering, at 0.7rem — .btn-sm is inline-flex with
   align-items:center at 0.8rem. Side by side (the operator name next to the Lock button) that reads as
   two different sizes with mismatched vertical alignment. Scoped to this one badge instance only —
   .badge itself is used all over the platform and must not change. */
.pos-header-slot .badge{display:inline-flex;align-items:center;font-size:0.8rem;gap:0.3em;}
/* flexbox trims the trailing space off the "Signed in as" text node at the flex-item boundary
   (the gap above restores it) — caused by the inline-flex change just above, fixed same commit. */
.tmo-note{font-size:12.5px;color:var(--text);background:rgba(255,159,10,0.14);border-left:3px solid #ff9f0a;border-radius:6px;padding:5px 8px;margin-top:8px;}
.tmo-cookrow{display:flex;align-items:center;gap:8px;margin:2px 0 8px 30px;}
.tmo-cook-sel.is-missing,.tm-select.is-missing{border-color:var(--danger);}
.tmo-notes{margin:14px 0;display:flex;flex-direction:column;gap:6px;}
.tmo-notes-ta{background:var(--surface);border:1px solid var(--border);border-radius:9px;color:var(--text);font:inherit;padding:8px 12px;min-height:56px;resize:vertical;width:100%;box-sizing:border-box;}
.tmo-courseact{margin-top:8px;}

/* Order-taking picker: per-cover sections, dish rows with a quantity stepper. */
.tmo-server{margin-bottom:14px;}
.tmo-cover{margin-top:6px;}
/* Course (section) sub-heading inside a menu's collapsible body. */
.tmo-secname{font-size:12px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:.04em;padding:12px 0 2px;}
.tmo-secname:first-child{padding-top:2px;}
.tmo-pick{display:flex;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--border);}
.tmo-pick:last-child{border-bottom:0;}
.tmo-pk-name{flex:1;color:var(--text);}
.tmo-pk-price{color:var(--text2);font-size:12px;white-space:nowrap;}
/* Tight on purpose: 99% of quantities are 1-9, so the qty needs one digit of room, not three. The
   space reclaimed here is what makes room for the per-line note button without the row growing. */
.tmo-step{display:flex;align-items:center;gap:4px;}
.tmo-stepbtn{width:30px;height:30px;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text);font-size:18px;line-height:1;cursor:pointer;}
.tmo-stepbtn:active{background:var(--border);}
.tmo-stepqty{width:20px;text-align:center;background:transparent;border:0;color:var(--text);font-size:15px;font-weight:700;}
.tmo-offsvc{opacity:0.5;}
.tmo-sent{background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:10px 12px;margin-top:8px;}
.tmo-billline{display:flex;justify-content:space-between;gap:10px;padding:2px 0;color:var(--text);}
.tmo-billtotal{display:flex;justify-content:space-between;gap:10px;padding-top:6px;margin-top:6px;border-top:1px solid var(--border);font-weight:700;}
.tmo-billgroup{font-weight:700;color:var(--accent);text-transform:uppercase;font-size:12px;letter-spacing:.04em;margin:12px 0 4px;}
.tmo-billsub{display:flex;justify-content:space-between;gap:10px;padding-top:4px;margin-top:4px;border-top:1px dashed var(--border);color:var(--text2);}
.tmo-billcourse{font-weight:600;color:var(--text2);font-size:12px;margin:6px 0 2px;}

/* Order picker: the cover selector (segmented custom control, not platform .btn). */
.tmo-covsel{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:4px 0 0;}
/* Table OR covers: two modes, not a filter. The word is what tells the waiter that. */
.tmo-covor{color:var(--text2);font-size:13px;padding:0 2px;}
.tmo-covbtn:disabled{opacity:.3;cursor:default;}
.tmo-covbtn{min-width:38px;width:auto;padding:0 10px;height:34px;}
.tmo-covbtn.is-on{background:var(--accent);color:#fff;border-color:var(--accent);}
/* A cover that already has items in this round goes DARK GREEN, so a waiter taking four covers can see
   at a glance who is done without tapping through each one. Dark rather than the bright --accent2:
   these sit next to the blue selected state and must not compete with it for attention. */
.tmo-covbtn.has-order{background:#14532d;border-color:#2e7d4f;color:#fff;}
/* Selected AND ordered: keep the green fill (the fact) and mark selection with a ring (the state), so
   the two signals never overwrite each other. */
.tmo-covbtn.has-order.is-on{background:#14532d;border-color:var(--accent);
                            box-shadow:0 0 0 2px var(--accent) inset;}

/* ============================================================================
   KITCHEN TICKET WALL (/admin/kds): a read-only pass TV. Big, glanceable, dark,
   oldest ticket first in a horizontally scrolling row (fast-food KDS style).
   ============================================================================ */
.tmk-page{height:100vh;display:flex;flex-direction:column;background:var(--bg);color:var(--text);overflow:hidden;}
.tmk-top{display:flex;align-items:baseline;justify-content:space-between;padding:10px 20px;border-bottom:1px solid var(--border);flex:none;}
.tmk-venue{font-size:1.4rem;font-weight:800;letter-spacing:0.5px;}
.tmk-clock{font-size:1.4rem;font-weight:800;color:var(--text2);font-variant-numeric:tabular-nums;}
.tmk-count{font-size:1.1rem;color:var(--text2);}

/* The wall: one horizontal row, oldest ticket leftmost, scrolls right as it fills. */
.tmk-wall{flex:1;display:flex;gap:14px;padding:16px 20px;overflow-x:auto;overflow-y:hidden;align-items:stretch;}
/* The wall ticket is the same "order slip": paper shade + a ruled left margin (an inset shadow so the
   warn/late border-colour swap below never eats it) + a lift shadow. */
.tmk-ticket{position:relative;flex:0 0 auto;width:340px;background:linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0) 96px),var(--surface);border:2px solid var(--border);border-radius:14px;display:flex;flex-direction:column;overflow:hidden;box-shadow:inset 5px 0 0 var(--accent),0 8px 18px rgba(0,0,0,0.35);}
/* An older, still-unmade ticket shouts louder the longer it waits. */
.tmk-ticket.warn{border-color:var(--warning);}
.tmk-ticket.late{border-color:var(--danger);}
/* DONE: every food line cooked, waiting to be served -> green ticket, pushed to the right, big green tick. */
.tmk-ticket.done{border-color:var(--accent2);box-shadow:inset 5px 0 0 var(--accent2),0 8px 18px rgba(0,0,0,0.35);opacity:0.92;}
.tmk-done{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:11rem;line-height:1;color:var(--accent2);opacity:0.85;pointer-events:none;z-index:2;text-shadow:0 2px 14px rgba(0,0,0,0.55);}
.tmk-thead{padding:12px 16px;border-bottom:2px solid var(--border);display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
.tmk-tbl{font-size:2.6rem;font-weight:900;line-height:1;}
.tmk-wait{font-size:1.6rem;font-weight:800;color:var(--text2);font-variant-numeric:tabular-nums;}
.tmk-sub{padding:2px 16px 10px;font-size:1.05rem;color:var(--text2);}
.tmk-tbody{padding:6px 16px 14px;overflow-y:auto;}
.tmk-course{margin-top:12px;}
.tmk-course:first-child{margin-top:2px;}
.tmk-cname{font-size:1.05rem;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:var(--accent);border-bottom:1px solid var(--border);padding-bottom:3px;margin-bottom:6px;}
.tmk-line{display:flex;align-items:baseline;gap:10px;padding:5px 0;font-size:1.7rem;font-weight:700;line-height:1.15;}
.tmk-q{min-width:2.4rem;font-weight:900;}
.tmk-name{flex:1;}
.tmk-covers{font-size:1rem;color:var(--text2);font-weight:600;white-space:nowrap;}
/* A dish the kitchen has readied turns green -- the burger-joint "bumped item" cue. */
.tmk-line.ready .tmk-q,.tmk-line.ready .tmk-name{color:var(--accent2);}
.tmk-line.ready .tmk-name{text-decoration:line-through;text-decoration-thickness:2px;}
.tmk-diet{display:inline-block;font-size:1rem;font-weight:900;letter-spacing:0.5px;color:#000;background:var(--warning);border-radius:6px;padding:0 8px;margin-left:6px;vertical-align:middle;}
.tmk-cook{display:inline-block;font-size:0.95rem;font-weight:800;color:#fff;background:var(--accent);border-radius:6px;padding:0 8px;margin-left:6px;vertical-align:middle;text-transform:uppercase;}
.tmk-swap{font-size:1rem;color:var(--warning);font-weight:700;margin:2px 0 6px 10px;text-transform:uppercase;}
/* SELECTED av/agf swap on the pass (kitchen/bar/serve + KDS wall): prominent green-accented block so
   the kitchen sees the requested change, distinct from an informational dietary note. Text uses --text
   so it passes contrast on both themes. */
.tmo-swap-sel{color:var(--text);background:rgba(48,209,88,0.16);border-left:3px solid var(--accent2);border-radius:6px;padding:4px 8px;font-weight:800;text-transform:uppercase;}
.tmk-swap-sel{color:var(--text);background:rgba(48,209,88,0.16);border-left:4px solid var(--accent2);border-radius:8px;padding:6px 10px;font-weight:900;text-transform:uppercase;margin-left:10px;}
.tmk-note{font-size:1rem;color:var(--text);background:rgba(255,159,10,0.16);border-left:4px solid #ff9f0a;border-radius:6px;padding:6px 10px;margin-top:8px;}
.tmk-empty{flex:1;display:flex;align-items:center;justify-content:center;font-size:2.2rem;font-weight:800;color:var(--text2);}

/* Per-line kitchen note (covers mode only). Same 30px touch target as the steppers so the row reads as
   one control group; muted until a note exists, then accent-filled so a glance down the menu shows
   which lines carry an instruction. Disabled (not hidden) in table mode: a control that vanishes is a
   control waiters stop trusting. */
.tmo-notebtn{width:30px;height:30px;border:1px solid var(--border);border-radius:8px;
             background:var(--surface);color:var(--text2);font-size:15px;line-height:1;cursor:pointer;
             padding:0;flex:0 0 auto;}
.tmo-notebtn.has-note{background:var(--accent);border-color:var(--accent);color:#fff;}
.tmo-notebtn:disabled{opacity:.3;cursor:default;}
.tmo-linenote,.tmk-linenote,.tk-linenote{font-style:normal;}
/* Note editor: INLINE, directly under the dish it annotates. A bottom sheet put the box a screen away
   from the item on a long menu, so the waiter lost their place. Indented and accent-edged so it reads
   as belonging to the row above it rather than to the next dish. */
.tmo-noteedit{margin:0 0 8px 12px;padding:10px 12px;background:var(--bg);
              border-left:3px solid var(--accent);border-radius:0 10px 10px 0;}
.tmo-noteedit-title{font-size:13px;color:var(--text2);margin-bottom:8px;}
.tmo-noteedit-in{width:100%;box-sizing:border-box;padding:10px;border-radius:8px;
                 border:1px solid var(--border);background:var(--surface);color:var(--text);
                 font-size:16px;}   /* 16px: anything smaller makes iOS zoom the page on focus */
