/* © 2026 Qder.ai (Itay Funes). All rights reserved. Proprietary and confidential; see LICENSE. */
/* ==========================================================================
   Qder.ai - signed-in panels.

   Same language as the landing: light ground, navy ink, one cobalt accent,
   dense rather than airy. A panel is scanned and operated, so summary comes
   before detail and state is encoded in shape as well as number.
   ========================================================================== */

/*
 * The faces and the design tokens, self-hosted.
 *
 * This used to fetch Heebo, Assistant and Readex Pro from fonts.googleapis.com
 * on every panel load — a third-party request on a screen a venue keeps open
 * all day, and one more thing between a shift manager and their floor. It is
 * now /next.css: Instrument Sans and IBM Plex Sans Hebrew from our own origin,
 * plus the `--n-*` tokens the new design is written in.
 */

:root {
  --cobalt:     #0B3FD9;
  --cobalt-700: #0830A8;
  --cobalt-300: #6E92F2;
  --cobalt-100: #DEE7FD;
  --cobalt-50:  #F1F5FE;

  --navy:   #0A1330;
  --ink:    #111A33;
  --body:   #4A5578;
  --muted:  #78829E;
  --line:   #E3E8F2;
  --line-2: #EFF2F8;
  --bg:     #FFFFFF;
  --bg-alt: #F7F9FC;
  /* The names the older floor and bill styles reach for, and the dark set overrides. */
  --surface:   #FFFFFF;
  --hair:      #E4E9F4;
  --hair-2:    #EDF1F8;
  --ink-soft:  #5B678A;
  --ink-faint: #8C96B2;
  /* A filled control: the accent as a ground with white on it. In the dark
     set the accent brightens for text and links but the fill stays deep, so
     white on it keeps its contrast. */
  --btn:       var(--cobalt);
  --btn-hover: var(--cobalt-700);

  --teal:  #067A6E;
  --teal-bg: #E6F4F1;
  --teal-line: #B9E0D8;
  --teal-ink: #06584F;
  --amber: #9A6100;
  --amber-bg: #FBF1E0;
  --amber-line: #E8D3AC;
  --amber-ink: #7A4B00;
  --rose:  #B32748;
  --rose-bg: #FCEBEF;
  --rose-line: #F3C9D3;
  --rose-ink: #8C1C36;

  --f:  "Assistant", "Segoe UI", system-ui, sans-serif;
  --fd: "Heebo", "Arial Hebrew", system-ui, sans-serif;

  --r: 8px;
  --r-lg: 14px;
  --s1: 0 1px 2px rgba(10,19,48,.06);
  --s2: 0 4px 14px -4px rgba(10,19,48,.10), 0 1px 3px rgba(10,19,48,.05);
  --s3: 0 18px 48px -20px rgba(10,19,48,.28);

  /* One scale, so nothing invents its own stacking order. */
  --z-sticky: 10;
  --z-nav: 20;
  --z-drop: 30;
  --z-modal: 50;

  --e: cubic-bezier(.22,.61,.36,1);

  color-scheme: light;
}

/* ------------------------------------------------------------------ dark
   The same navy the brand stands on, lifted one step for surfaces. Text and
   links brighten; filled buttons keep a deep ground so white stays legible on
   them; the status tints go from pastel grounds with dark ink to dark grounds
   with pastel ink. Applied by theme.js, which stamps data-theme before the
   first paint, and by the system preference when nothing was chosen. */

/* The toggle itself: an icon button in the top bar, sun when it is dark and
   moon when it is light, that is, the thing you would get by pressing. */

* { box-sizing: border-box; }
body { margin: 0; background: var(--bg-alt); color: var(--ink); font-family: var(--f); font-size: 16px; line-height: 1.6; -webkit-font-smoothing: antialiased; min-height: 100dvh; display: flex; flex-direction: column; }
h1,h2,h3,h4 { font-family: var(--fd); font-weight: 800; color: var(--navy); margin: 0; line-height: 1.16; letter-spacing: -.025em; }
p { margin: 0; }
a { color: var(--cobalt); text-decoration: none; }
a:hover { color: var(--cobalt-700); }
button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 2px; border-radius: 4px; }
svg { flex: 0 0 auto; }

.wrap { width: 100%; max-width: 1240px; margin: 0 auto; padding-inline: 1.15rem; }

/* -------------------------------------------------------------- top bar */

/*
 * The panels hand over to each other, and to the pages outside them.
 *
 * poster.css has carried `@view-transition` since the public floor was built,
 * and its own comment says the browser does the work "once BOTH documents
 * carry this rule". The panels never did — so every navigation from a page
 * that opts in to one that does not threw
 * "InvalidStateError: Transition was aborted ... ViewTransition opt-in
 * disabled" into the console. /login is on poster.css and /account and /chain
 * are here, which is the ordinary way into this app: signing in produced the
 * error every time. Found in the live QA of 19 September.
 *
 * The bar carries the same name as the public one so it morphs rather than
 * cross-fades, which is what makes the two halves feel like one place.
 */
@view-transition { navigation: auto; }

.top { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: var(--z-nav); view-transition-name: qder-topbar; }
.top .row { display: flex; align-items: center; gap: .9rem; height: 58px; }
/* The mark sits to the left of the wordmark, as in the brand's LTR lockup, whatever the page direction. */
.brand { direction: ltr; display: inline-flex; align-items: center; gap: .5rem; font-family: "Readex Pro", var(--fd); font-weight: 600; font-size: 1.02rem; color: var(--navy); letter-spacing: -.035em; }
.brand .mark-img { width: .92em; height: .92em; flex: 0 0 auto; }
.scope { display: inline-flex; align-items: center; gap: .35rem; font-family: var(--fd); font-weight: 700; font-size: .78rem; padding: .22rem .6rem; border-radius: 100px; background: var(--cobalt-50); color: var(--cobalt-700); border: 1px solid var(--cobalt-100); }
.top .end { margin-inline-start: auto; display: flex; align-items: center; gap: .6rem; }
.who { display: flex; flex-direction: column; line-height: 1.25; text-align: start; }
.who b { font-family: var(--fd); font-weight: 700; font-size: .87rem; color: var(--navy); }
.who span { font-size: .76rem; color: var(--muted); }
@media (max-width: 620px) { .who { display: none; } }

/* -------------------------------------------------------------- tabs */

.tabs { background: var(--surface); border-bottom: 1px solid var(--line); position: sticky; top: 58px; z-index: var(--z-sticky); }
.tabs .row { display: flex; gap: .25rem; overflow-x: auto; }
.tabs a, .tabs button { display: inline-flex; align-items: center; gap: .4rem; padding: .85rem .85rem .7rem; font-family: var(--fd); font-weight: 700; font-size: .92rem; color: var(--body); border-bottom: 2px solid transparent; white-space: nowrap; transition: color .16s var(--e), border-color .16s var(--e); }
.tabs a:hover, .tabs button:hover { color: var(--navy); }
.tabs [aria-current="true"], .tabs [aria-selected="true"] { color: var(--cobalt); border-bottom-color: var(--cobalt); }
.tabs svg { width: 16px; height: 16px; }

main { flex: 1 1 auto; padding-block: 1.5rem 3.5rem; }

/* ------------------------------------------------------------- headers */

.head { display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.head h1 { font-size: clamp(1.4rem, 2.6vw, 1.85rem); }
.head .sub { color: var(--body); font-size: .92rem; margin-top: .25rem; }
.head .side { margin-inline-start: auto; display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }

/*
 * [hidden] means hidden, once, for everything.
 *
 * The user agent's `[hidden] { display: none }` is an ordinary rule and any
 * `display` a component sets outranks it — so an element the code has marked
 * hidden keeps rendering. This file had already been patched for it five
 * separate times (.seg, .banner, .scrim, .turn, #tblGuest), each time for
 * whichever component had just been caught.
 *
 * The sixth was found in the live QA on 20 September and was not cosmetic:
 * branch.js:42 says `$("backChain").hidden = !asChain`, meaning only a chain
 * admin gets the "חזרה לרשת" link. `.btn-quiet { display: flex }` beat the
 * attribute, so a branch manager saw a 100×42 button in the top bar leading to
 * /chain — which her own account is refused with a 403. The intent was right
 * and the stylesheet undid it.
 *
 * One rule, so there is no seventh. `!important` because outranking every
 * component's display is exactly the job; the specific rules below are left
 * where they are, being harmless and now redundant.
 */
[hidden] { display: none !important; }

/* [hidden] sets display:none, but a CSS display rule outranks it, so the range
   control kept showing on tabs that have no date range. */
.seg[hidden] { display: none; }
.seg { display: flex; gap: .2rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: .2rem; }
.seg button { font-family: var(--fd); font-weight: 700; font-size: .84rem; padding: .35rem .7rem; border-radius: 6px; color: var(--body); transition: background .15s var(--e), color .15s var(--e); }
.seg button[aria-pressed="true"] { background: var(--btn); color: #fff; }

/* ------------------------------------------------------------ controls */

.btn { display: inline-flex; align-items: center; justify-content: center; gap: .4rem; background: var(--btn); color: #fff; font-family: var(--fd); font-weight: 700; font-size: .92rem; padding: .55rem 1.05rem; border-radius: var(--r); box-shadow: var(--s1); transition: background .16s var(--e); }
.btn:hover { background: var(--btn-hover); color: #fff; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn svg { width: 15px; height: 15px; }
.btn-quiet { display: inline-flex; align-items: center; justify-content: center; gap: .4rem; background: var(--surface); color: var(--navy); font-family: var(--fd); font-weight: 700; font-size: .9rem; padding: .52rem .9rem; border-radius: var(--r); border: 1px solid var(--line); transition: border-color .16s var(--e), background .16s var(--e); }
.btn-quiet:hover { border-color: var(--cobalt-300); background: var(--cobalt-50); color: var(--navy); }
/* The class is used on links as well as buttons; a link keeps its underline
   unless told otherwise, and an underlined button reads as broken. */
a.btn-quiet, a.btn { text-decoration: none; }
.btn-danger { color: var(--rose); }
.btn-danger:hover { border-color: var(--rose); background: var(--rose-bg); color: var(--rose); }

.field { display: flex; flex-direction: column; gap: .3rem; }
.field label { font-family: var(--fd); font-weight: 700; font-size: .82rem; color: var(--navy); }
.field input, .field select, .field textarea { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: .58rem .75rem; font-size: .95rem; color: var(--ink); transition: border-color .15s var(--e), box-shadow .15s var(--e); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--cobalt); box-shadow: 0 0 0 3px var(--cobalt-50); }
.field .hint { font-size: .8rem; color: var(--muted); }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }
.pad { padding: 1.15rem 1.2rem; }
.card > header { display: flex; align-items: baseline; gap: .7rem; padding: 1rem 1.2rem; border-bottom: 1px solid var(--line-2); }
.card > header h2 { font-size: 1.02rem; }
.card > header .hint { margin-inline-start: auto; font-size: .82rem; color: var(--muted); }

/* --------------------------------------------------------------- tiles */

.tiles { display: grid; gap: .8rem; grid-template-columns: repeat(4,1fr); margin-bottom: 1rem; }
@media (max-width: 1000px) { .tiles { grid-template-columns: repeat(2,1fr); } }
@media (max-width: 520px) { .tiles { grid-template-columns: 1fr; } }
.tile { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: .95rem 1.05rem; display: flex; flex-direction: column; gap: .1rem; }
.tile .k { font-family: var(--fd); font-weight: 700; font-size: .76rem; color: var(--muted); letter-spacing: .04em; }
.tile .v { font-family: var(--fd); font-weight: 900; font-size: clamp(1.5rem,2.4vw,1.95rem); letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--navy); }
.tile .n { font-size: .8rem; color: var(--muted); }
.tile.accent .v { color: var(--cobalt); }
.tile.live { border-color: var(--cobalt-300); background: var(--cobalt-50); }

.grid { display: grid; gap: .8rem; grid-template-columns: 1.55fr 1fr; align-items: start; }
/* Cards stacked straight in a view breathe like the ones in a grid do. On a
   phone the overview's cards sat edge to edge (founder's screenshot, 16 Sep). */
.view > .card + .card, .view > .card + .grid, .view > .grid + .card, .view > .tiles + .card { margin-top: 1rem; }
@media (max-width: 1000px) { .grid { grid-template-columns: 1fr; } }
.grid > * { min-width: 0; }

/* --------------------------------------------------------------- chart */

.chart { width: 100%; height: 180px; display: block; }
.chart .bar { fill: var(--cobalt); }
.chart .bar:hover { fill: var(--cobalt-700); }
.chart .bar.empty { fill: var(--line); }
.chart .grid-line { stroke: var(--line-2); stroke-width: 1; }
.chart .lbl { fill: var(--muted); font-size: 10px; font-family: var(--f); }

.bars { display: flex; flex-direction: column; gap: .65rem; }
.barrow { display: flex; flex-direction: column; gap: .25rem; }
/* Not .top: that name is the sticky header, and a row that borrows it becomes sticky too and rides over the bar. */
.barrow .row-head { display: flex; align-items: baseline; gap: .5rem; font-size: .9rem; }
.barrow .row-head b { font-family: var(--fd); font-weight: 700; }
.barrow .row-head .val { margin-inline-start: auto; font-variant-numeric: tabular-nums; font-weight: 700; color: var(--cobalt); }
.barrow .track { height: 7px; border-radius: 99px; background: var(--line-2); overflow: hidden; }
.barrow .fill { height: 100%; border-radius: 99px; background: var(--btn); }

/* --------------------------------------------------------------- table */

.tbl-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: start; padding: .68rem .9rem; border-bottom: 1px solid var(--line-2); font-size: .92rem; }
th { font-family: var(--fd); font-weight: 800; font-size: .76rem; color: var(--muted); letter-spacing: .05em; background: var(--bg-alt); white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--bg-alt); }
td b { font-family: var(--fd); color: var(--navy); }
.num { font-variant-numeric: tabular-nums; }

.pill { display: inline-flex; align-items: center; gap: .3rem; font-family: var(--fd); font-weight: 700; font-size: .74rem; padding: .16rem .5rem; border-radius: 100px; background: var(--cobalt-50); color: var(--cobalt-700); }
.pill.ok { background: var(--teal-bg); color: var(--teal); }
.pill.warn { background: var(--amber-bg); color: var(--amber); }
.pill.crit { background: var(--rose-bg); color: var(--rose); }

/* A gap from the chain's median, next to the number it qualifies. Colour says
   whether the gap is welcome, the sign and figure say how big; never colour
   alone, so the label always carries the number. */
.delta { display: inline-block; direction: ltr; unicode-bidi: isolate; font-family: var(--fd); font-weight: 700; font-size: .7rem; padding: .08rem .38rem; border-radius: 6px; margin-inline-start: .3rem; white-space: nowrap; vertical-align: middle; }
.delta.good { background: var(--teal-bg); color: var(--teal); }
.delta.bad { background: var(--rose-bg); color: var(--rose); }
.delta.flat { background: var(--cobalt-50); color: var(--muted); }
td.actions { white-space: nowrap; }
td.actions .btn-quiet + .btn-quiet { margin-inline-start: .35rem; }

.chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.chips button { font-family: var(--fd); font-weight: 700; font-size: .85rem; padding: .35rem .8rem; border-radius: 100px; background: var(--surface); border: 1px solid var(--line); color: var(--body); transition: border-color .16s var(--e), background .16s var(--e), color .16s var(--e); }
.chips button:hover { border-color: var(--cobalt-300); }
.chips button[aria-pressed="true"] { background: var(--btn); border-color: var(--cobalt); color: #fff; }

.banner { padding: .7rem .9rem; border-radius: var(--r); font-size: .9rem; font-weight: 600; display: flex; gap: .5rem; align-items: flex-start; }
.banner.err { background: var(--rose-bg); border: 1px solid var(--rose-line); color: var(--rose-ink); }
.banner.ok { background: var(--teal-bg); border: 1px solid var(--teal-line); color: var(--teal-ink); }
.banner[hidden] { display: none; }

.empty { color: var(--muted); text-align: center; padding: 2.2rem 1rem; font-size: .92rem; line-height: 1.6; }

/* --------------------------------------------------------------- modal */

.scrim { position: fixed; inset: 0; background: rgba(10,19,48,.42); z-index: var(--z-modal); display: grid; place-items: center; padding: 1.25rem; }
.scrim[hidden] { display: none; }
.modal { background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--s3); width: 100%; max-width: 30rem; max-height: 90dvh; overflow-y: auto; }
.modal header { display: flex; align-items: center; gap: .7rem; padding: 1.05rem 1.2rem; border-bottom: 1px solid var(--line-2); }
.modal header h2 { font-size: 1.05rem; }
.modal header button { margin-inline-start: auto; color: var(--muted); font-size: 1.3rem; line-height: 1; padding: .1rem .35rem; border-radius: 6px; }
.modal header button:hover { background: var(--bg-alt); color: var(--navy); }
.modal .body { padding: 1.2rem; display: flex; flex-direction: column; gap: .9rem; }
.modal .foot { padding: 1rem 1.2rem; border-top: 1px solid var(--line-2); display: flex; gap: .5rem; justify-content: flex-end; }

.secret { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 1.05rem; letter-spacing: .06em; background: var(--bg-alt); border: 1px dashed var(--cobalt-300); border-radius: var(--r); padding: .7rem .85rem; word-break: break-all; color: var(--navy); }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (prefers-reduced-motion: reduce) { *,*::before,*::after { animation-duration:.001ms !important; transition-duration:.001ms !important; } }

/* ------------------------------------------------------------ usage meter */

/*
 * A venue should see its cap coming, not discover it from a guest saying the
 * screen stopped answering. So this is a plain bar with the real numbers on it
 * and the consequence written out, rather than a percentage the reader has to
 * translate into "what happens to my dinner service".
 */
.usage { display: flex; flex-direction: column; gap: .55rem; }
/* Full width and shallow: it is a status line above the charts, not a panel
   competing with them for the reader's attention. */
.usage-card { margin-bottom: .8rem; }
.usage-card .pad { padding: .9rem 1.2rem 1rem; }
.usage .row { display: flex; align-items: baseline; gap: .6rem; }
.usage .plan {
  font-family: var(--fd); font-weight: 800; font-size: .78rem; letter-spacing: .04em;
  color: var(--cobalt); background: var(--cobalt-50); border: 1px solid var(--cobalt-300);
  border-radius: 999px; padding: .12rem .6rem;
}
.usage .count {
  font-family: var(--fd); font-weight: 900; font-size: 1.5rem; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; color: var(--navy);
}
.usage .count small { font-weight: 700; font-size: .95rem; color: var(--muted); }
.usage .meter {
  height: 9px; border-radius: 999px; background: var(--line); overflow: hidden;
}
.usage .meter > i {
  display: block; height: 100%; border-radius: 999px; background: var(--btn);
  transition: width .4s var(--e);
}
.usage[data-state="warn"] .meter > i { background: var(--amber); }
.usage[data-state="over"] .meter > i { background: var(--rose); }
.usage .note { font-size: .85rem; color: var(--body); line-height: 1.5; }
.usage[data-state="warn"] .note { color: var(--amber); }
.usage[data-state="over"] .note { color: var(--rose); font-weight: 600; }

@media (prefers-reduced-motion: reduce) { .usage .meter > i { transition: none; } }

/* --------------------------------------------------------------- floor plan */

/*
 * The dining room, seen from above and slightly forward.
 *
 * A manager glancing at this needs one thing in under a second: which tables
 * are taken. So occupancy is carried by the tabletop itself rather than by a
 * badge — a warm amber top reads as occupied from across a room, pale wood as
 * free. Colour is never the only signal: every occupied table also carries the
 * diner's name or the word תפוס, so the plan survives colour blindness and a
 * monochrome print of the shift handover.
 *
 * The room is one tilted plane with the tables standing on it, rather than a
 * grid of cards with shadows. That is what makes it read as a floor: the
 * chairs, the table thickness and the cast shadows all share one light and one
 * vanishing point.
 */

.floor-room {
  /*
   * A deeper camera and a gentler tilt than the single-band room had.
   *
   * With three bands stacked, 1500px of perspective at 42 degrees made the
   * near band roughly twice the size of the far one: the bar looked like a
   * different restaurant from the dining room. Pulling the camera back and
   * lowering the tilt keeps the floor reading as a floor while making a table
   * the same table wherever it stands.
   */
  perspective: 2800px;
  perspective-origin: 50% 46%;
  padding: 2.2rem 1rem 2.6rem;
  overflow-x: auto;
}

.floor-plane {
  position: relative;
  max-width: 44rem;
  margin-inline: auto;
  padding: 2.6rem 2.2rem;
  border-radius: 18px;
  transform: rotateX(27deg);
  transform-style: preserve-3d;
  transition: transform .55s var(--e);

  /* Floorboards running away from the viewer, plus the room's own edge. */
  background:
    repeating-linear-gradient(90deg,
      #EFE3D2 0 46px, #EAD9C4 46px 48px),
    linear-gradient(180deg, #F3E9DA, #E4D3BC);
  border: 1px solid #D6C3A8;
  box-shadow:
    inset 0 0 60px rgba(122, 92, 52, .18),
    0 30px 50px rgba(10, 19, 48, .18);
}
.floor-room:hover .floor-plane { transform: rotateX(20deg); }

.floor { display: grid; gap: 1.4rem; transform-style: preserve-3d; }

/* One band per area. Each keeps its own ground, because a pavement is not the
   same surface as a dining room and the difference is most of what tells a
   shift manager which part of the room they are looking at. */
.floor-band {
  display: grid;
  gap: 1.9rem 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(7.2rem, 1fr));
  transform-style: preserve-3d;
  padding: 1.1rem 1rem 1.3rem;
  border-radius: 14px;
}
.floor-band[data-kind="outdoor"] {
  /* Paving, not floorboards, and a cooler light on it. */
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.5) 0 2px, transparent 2px 62px),
    repeating-linear-gradient(0deg, rgba(255,255,255,.5) 0 2px, transparent 2px 62px),
    linear-gradient(180deg, #D9DDE2, #C6CBD2);
  box-shadow: inset 0 0 40px rgba(60, 72, 92, .16);
}
.floor-band[data-kind="bar"] {
  /* The counter itself: one dark run of wood the stools stand against. */
  background: linear-gradient(180deg, #4A3527 0%, #3A2A1E 62%, #2E2117 100%);
  box-shadow: inset 0 8px 18px rgba(0, 0, 0, .35);
}
.floor-band-name {
  font-family: var(--fd); font-weight: 800; font-size: .82rem;
  color: #6B5636; padding-inline-start: .4rem;
  transform: translateZ(2px);
}
.floor-band-name b { color: #4A3A21; }

/* --------------------------------------------------------------- one table */

.tbl {
  position: relative;
  aspect-ratio: 1;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transform-style: preserve-3d;
  transition: transform .22s var(--e);
}
.tbl:hover, .tbl:focus-visible { transform: translateZ(26px); }
.tbl:focus-visible { outline: 3px solid var(--cobalt); outline-offset: 6px; border-radius: 50%; }

/* Chairs. Four of them, tucked in at the compass points, sitting flat on the
   floor so the tabletop floats above them. */
.tbl .chair {
  position: absolute;
  width: 30%; height: 22%;
  background: linear-gradient(180deg, #8C6A45, #6E5133);
  border-radius: 5px;
  box-shadow: 0 2px 3px rgba(60, 40, 16, .4);
  transform: translateZ(6px);
}
.tbl .chair:nth-child(1) { top: -6%;  left: 35%; }
.tbl .chair:nth-child(2) { bottom: -6%; left: 35%; }
.tbl .chair:nth-child(3) { left: -5%;  top: 39%; width: 22%; height: 30%; }
.tbl .chair:nth-child(4) { right: -5%; top: 39%; width: 22%; height: 30%; }

/* The tabletop: a real disc with thickness, lifted off the floor on its leg.
   The stacked shadows are the edge of the top, then the shadow it casts. */
.tbl .top {
  position: absolute;
  inset: 14%;
  border-radius: 50%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: .1rem;
  text-align: center;
  padding: .3rem;
  font-family: var(--fd);
  /* The top is pale in both themes, so the ink is fixed: theme tokens turned
     it near-white on the dark panel and the numbers vanished. */
  color: #0B1220;
  background: radial-gradient(circle at 34% 28%, #FFFFFF 0%, #F4EFE6 62%, #E7DECE 100%);
  border: 1px solid #D9CDB8;
  box-shadow:
    0 7px 0 #CDBEA4,
    0 9px 2px rgba(80, 58, 26, .28),
    0 22px 24px rgba(10, 19, 48, .28);
  transform: translateZ(30px);
  transition: background .25s var(--e), box-shadow .25s var(--e);
}

/* Occupied. Amber, not red: a full table is the goal, not an alarm. */
.tbl[data-state="busy"] .top {
  background: radial-gradient(circle at 34% 28%, #FFC46B 0%, #F79E28 58%, #E2861A 100%);
  border-color: #C9740F;
  color: #33200A;
  box-shadow:
    0 7px 0 #B4670C,
    0 9px 2px rgba(90, 52, 6, .34),
    0 22px 26px rgba(120, 70, 10, .34);
}

.tbl .no {
  font-weight: 900;
  font-size: clamp(1.1rem, 2.6vw, 1.5rem);
  line-height: 1;
  letter-spacing: -.03em;
}
.tbl .who {
  font-weight: 700; font-size: .66rem; line-height: 1.2;
  max-width: 92%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: #1B2333;
  /*
   * Said out loud, because something else was hiding it.
   *
   * There is an unrelated `.who` in this stylesheet — a list row elsewhere in
   * the panel — and it is hidden under 620px. That bare selector also matches
   * the label on a table, and `.tbl .who` never declared a display of its own,
   * so specificity had nothing to win with: on a phone the floor plan showed
   * numbers and minutes and never "תפוס", "חשבון פתוח" or the diner's name.
   * Those labels are most of why the map exists, and a phone mid-service is
   * where it is actually read.
   */
  display: block;
  flex: 0 0 auto;
}
.tbl .mins { flex: 0 0 auto; font-weight: 700; font-size: .6rem; color: #3B4658; font-variant-numeric: tabular-nums; }
.tbl[data-state="busy"] .who,
.tbl[data-state="busy"] .mins { color: #4A2E06; }

/* ------------------------------------------------- outside, and at the bar

   The tabletop rules above are the indoor table, and stay the default. These
   two say only what differs, so a change to the shared material — the lift,
   the cast shadow, the busy colour — reaches all three. */

/* Outside: a square top under a parasol. Squares read as garden furniture at a
   glance, which is the whole job of the shape. */
.tbl[data-kind="outdoor"] .top { border-radius: 12px; }
.tbl[data-kind="outdoor"] .chair {
  background: linear-gradient(180deg, #9AA3AE, #767F8B);
  box-shadow: 0 2px 3px rgba(40, 48, 60, .4);
}
/*
 * No parasol.
 *
 * A canopy floating above the table covered the one thing the tile exists to
 * show — its number — and at any opacity low enough to see through, it read as
 * fog rather than as shade. The square top, the grey garden chairs and the
 * paving under them already say "outside" without hiding anything, so the
 * element is kept in the markup for nothing and drawn as nothing.
 */
.tbl[data-kind="outdoor"] .parasol { display: none; }

/* The bar: a stool, not a table. One seat, a small round top, standing on the
   counter's own dark ground. */
.tbl[data-kind="bar"] .top {
  /*
   * Size and shadow only, never the fill.
   *
   * Setting a background here sat after the busy rule in the cascade and quietly
   * won it, so an occupied stool stayed pale while every other occupied table
   * turned amber — the one signal the whole map is scanned for, broken on a
   * third of the room. The stool differs by being smaller and standing higher;
   * what it is made of is the same table it has always been.
   */
  inset: 26%;
  box-shadow:
    0 5px 0 #B9A98C,
    0 7px 2px rgba(50, 34, 12, .34),
    0 16px 18px rgba(0, 0, 0, .34);
  transform: translateZ(38px);
}
.tbl[data-kind="bar"] .chair {
  top: auto; bottom: 4%; left: 50%;
  width: 34%; height: 16%;
  transform: translate(-50%, 0) translateZ(6px);
  border-radius: 50%;
  background: linear-gradient(180deg, #6E5133, #4E3823);
}
.tbl[data-kind="bar"] .no { font-size: clamp(.95rem, 2.2vw, 1.25rem); }
.tbl[data-kind="bar"] .who,
.tbl[data-kind="bar"] .mins { font-size: .58rem; }

/* An unpaid bill: a ring around the top, so it layers on top of occupancy
   rather than competing with the one signal being scanned for. */
/* A day heading in the ticket list. A rule either side so it reads as a
   divider rather than as another ticket. */
/* A card payment that was started and never confirmed. Amber rather than red:
   the likely truth is that the money arrived and the browser closed, which is
   something to check before acting, not an error. */
.guest-card.warn { border-color: var(--amber-line); background: var(--amber-bg); }
.guest-card.warn h3 { color: var(--amber-ink); }

/* ------------------------------------------------------- stopping the plan

   Deliberately quiet. A venue looking for the way out should find it without
   asking us, and a venue not looking for it should not have a red button in
   the corner of its eye all month. */
.stop .pad p { margin: 0 0 .8rem; color: var(--body); line-height: 1.6; }
.stop .pad p:last-child { margin-bottom: 0; }
.stop-when { background: var(--amber-bg, #FFF7E8); border: 1px solid var(--amber-line, #F0D9A8); border-radius: var(--r); padding: .9rem 1.1rem; }
.stop-when b { color: var(--ink); }
.stop-row { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; margin-top: 1rem; }
.stop-reason { flex: 1 1 18rem; min-height: 40px; padding: .4rem .7rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); font: inherit; color: var(--ink); }
.stop-said { font-size: .88rem; color: var(--body); }
.stop-said.warn { color: var(--red, #C0341D); }

/* --------------------------------------------------- recent bills

   Read down a column of money, so the amounts are tabular and right where the
   eye lands. Everything else is context for the one row being looked for. */
.bill {
  display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap;
  padding: .65rem 0; border-top: 1px solid var(--hair-2, #EDF1F8);
}
.bill:first-child { border-top: 0; }
.bill .when { font-size: .86rem; color: var(--ink-soft, #5B678A); min-width: 8.5rem; }
.bill .tbl {
  font-family: var(--sc-font-display), system-ui, sans-serif; font-weight: 700;
  font-size: .88rem; min-width: 4.5rem;
}
.bill .sum {
  font-family: var(--sc-font-display), system-ui, sans-serif; font-weight: 800;
  font-variant-numeric: tabular-nums; min-width: 5rem;
}
.bill .how {
  font-size: .74rem; padding: .12rem .5rem; border-radius: 999px;
  border: 1px solid var(--hair, #E4E9F4); color: var(--ink-soft, #5B678A);
}
.bill .how.card { border-color: var(--cobalt-100); background: var(--cobalt-50); color: var(--cobalt); }
.bill .what { font-size: .85rem; color: var(--ink-soft, #5B678A); flex: 1 1 12rem; }
.bill .ref {
  font-family: ui-monospace, monospace; font-size: .7rem;
  color: var(--ink-faint, #8C96B2); direction: ltr; unicode-bidi: isolate;
}
.bill .allerg { font-size: .78rem; color: var(--rose-ink); }
.bill .how.refunded { border-color: #E8D48A; background: #FFF8E1; color: #6B5210; }
.bill .refund-btn { margin-inline-start: auto; padding: .3rem .7rem; font-size: .8rem; }
.bill .refund-form { flex-basis: 100%; display: flex; flex-direction: column; gap: .5rem; margin-top: .5rem; padding: .7rem .8rem; border-radius: var(--r); background: var(--bg-alt); border: 1px solid var(--line); }
.bill .refund-line { display: grid; grid-template-columns: 1fr 7rem 1fr auto; gap: .5rem; align-items: center; font-size: .85rem; }
.bill .refund-line input { padding: .45rem .6rem; border: 1px solid var(--line); border-radius: var(--r-sm); font: inherit; font-size: .85rem; min-width: 0; }
.bill .refund-line input[type="number"] { text-align: left; direction: ltr; }
.bill .refund-line .btn { padding: .45rem .8rem; font-size: .85rem; }
@media (max-width: 720px) { .bill .refund-line { grid-template-columns: 1fr 1fr; } .bill .refund-line > span { grid-column: 1 / -1; } }

/* -------------------------------------------------- closing the day

   The checklist half of the shift summary. Styled as things to act on rather
   than figures to admire: an open table at closing time is a job, not a
   statistic, so it gets a warning ground and a count you cannot miss. */
.shift-open { margin-top: .9rem; }
.shift-open h3 {
  font-family: var(--sc-font-display), system-ui, sans-serif;
  font-weight: 800; font-size: .92rem; margin: 0 0 .5rem;
}
.shift-list { display: flex; flex-wrap: wrap; gap: .4rem; }
.shift-chip {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .4rem .7rem; border-radius: 999px;
  border: 1px solid var(--rose-line); background: var(--rose-bg); color: var(--rose-ink);
  font-size: .85rem; font-weight: 700;
}
.shift-chip .n { font-variant-numeric: tabular-nums; }
.shift-clear {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .4rem .75rem; border-radius: 999px;
  border: 1px solid var(--teal-line); background: var(--teal-bg); color: var(--teal-ink);
  font-size: .85rem; font-weight: 700;
}
.shift-dishes { margin-top: .9rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.shift-dish {
  padding: .3rem .65rem; border-radius: 999px;
  border: 1px solid var(--hair, #E4E9F4); background: var(--surface, #fff);
  font-size: .83rem; color: var(--ink-soft, #5B678A);
}
.shift-dish b { color: var(--ink, #0A1330); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------- table turn, live

   Three readings of the same room: how long a table usually takes here, how
   full the room is now, and what those two together say about the wait. The
   third is the one a host repeats out loud, so it gets the emphasis. */
.turn {
  display: flex; flex-wrap: wrap; gap: .5rem;
  padding: 0 1rem 1rem;
}
.turn[hidden] { display: none; }
.turn .t {
  flex: 1 1 8rem; min-width: 8rem;
  padding: .7rem .85rem;
  border: 1px solid var(--hair, #E4E9F4); border-radius: 12px;
  background: var(--surface, #fff);
}
.turn .t .k {
  display: block; font-size: .72rem; letter-spacing: .04em;
  color: var(--ink-soft, #5B678A); font-weight: 700;
}
.turn .t .v {
  display: block; margin-top: .15rem;
  font-family: var(--sc-font-display), system-ui, sans-serif;
  font-weight: 800; font-size: 1.32rem; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.turn .t .sub { display: block; font-size: .74rem; color: var(--ink-soft, #5B678A); }
/* The answer to the question at the door. */
.turn .t.wait { border-color: var(--cobalt); background: var(--cobalt-50); }
.turn .t.wait .k, .turn .t.wait .v, .turn .t.wait .sub { color: var(--cobalt); }
.turn .t.open { border-color: var(--teal); background: var(--teal-bg); }
.turn .t.open .k, .turn .t.open .v, .turn .t.open .sub { color: var(--teal-ink); }

/* The kitchen screen has gone stale. Fixed to the bottom rather than the top:
   the top of that screen is where the open-order count lives, and covering the
   number somebody is working from to tell them the screen is stale would be a
   poor trade. */
.offline {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 60;
  background: #8B1D1D; color: #fff;
  padding: .85rem 1rem; text-align: center;
  font-family: var(--sc-font-display); font-weight: 700; font-size: .95rem;
  box-shadow: 0 -6px 20px -8px rgba(10,19,48,.5);
}

.dayline {
  /* The ticket list is a grid; without this the heading takes one cell and
     sits beside a ticket instead of dividing the rows above and below it. */
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: .7rem;
  margin: 1.1rem .1rem .5rem;
}
.dayline:first-child { margin-top: .2rem; }
.pager {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  margin: 1rem 0 .4rem; color: var(--ink-soft); font-size: .92rem;
}
.pager button[disabled] { opacity: .35; pointer-events: none; }
.dayline span { flex: 1 1 auto; height: 1px; background: var(--line-2); }
.dayline b {
  flex: 0 0 auto;
  font-family: var(--sc-font-display); font-weight: 800; font-size: .78rem;
  letter-spacing: .04em; color: var(--sc-ink-soft);
}

/* A settled ticket is history, not work. Muted so the eye skips it, and it
   carries no controls at all — see kitchen.js. */
/*
 * A table that is calling, on the plan of the room.
 *
 * A dot with the wait in it, pinned to the corner of the tile. Amber rather
 * than the red already used for a stuck payment: two reds on one map and
 * neither means anything. It pulses, and stops at prefers-reduced-motion,
 * because the point is to be caught by the corner of an eye crossing a busy
 * room, not to be a light show.
 */
.tbl .calling {
  position: absolute; inset-block-start: 6px; inset-inline-end: 6px;
  min-width: 20px; height: 20px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: #F59E0B; color: #23180A;
  font: 700 11px/1 var(--fd, inherit);
  box-shadow: 0 0 0 3px rgba(245, 158, 11, .25);
  /* .top is z-index 20 and covers most of the tile; the badge sits above it. */
  z-index: 30;
  animation: callpulse 1.6s ease-in-out infinite;
}
@keyframes callpulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(245, 158, 11, .25); }
  50%      { box-shadow: 0 0 0 7px rgba(245, 158, 11, .08); }
}
@media (prefers-reduced-motion: reduce) { .tbl .calling { animation: none; } }

/* The reason and the two presses, inside the table sheet. */
.guest-card.call li { display: flex; align-items: center; justify-content: space-between; gap: .6rem; flex-wrap: wrap; }
.guest-card.call .call-acts { display: inline-flex; gap: .4rem; flex: 0 0 auto; }

/*
 * The three rooms, on the seating card.
 *
 * A row per room, the count in the middle, the one button on the end. It
 * replaced a form with a name field and a save button; there is nothing to
 * save, because an area's size is the tables pointing at it.
 */
.area-room {
  display: flex; align-items: center; gap: .8rem;
  padding: .7rem .2rem;
  border-bottom: 1px solid var(--line);
}
.area-room:last-child { border-bottom: 0; }
.area-room-name { font-weight: 700; min-width: 5.5rem; }
.area-room-count { color: var(--muted); flex: 1; }
@media (max-width: 480px) {
  .area-room { flex-wrap: wrap; gap: .4rem .8rem; }
  .area-room-count { flex: 1 0 100%; order: 3; }
}

.order.paid { opacity: .62; }
.order.paid .pill.ok { background: var(--teal-bg); border-color: var(--teal-line); color: var(--teal-ink); }

.tbl[data-bill="1"] .top::after {
  content: "";
  position: absolute; inset: -7px;
  /* Inherited, so a square top gets a square ring and a stool a round one. */
  border-radius: inherit;
  border: 2.5px solid var(--cobalt);
}

/* -------------------------------------------------------------- the legend */

.floor-legend {
  display: flex; flex-wrap: wrap; gap: 1.1rem; justify-content: center;
  margin-top: 1.1rem; font-size: .82rem; color: var(--body);
}
.floor-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.floor-legend i {
  width: 15px; height: 15px; border-radius: 50%;
  background: #F4EFE6; border: 1px solid #D9CDB8;
}
.floor-legend i.busy { background: #F79E28; border-color: #C9740F; }
.floor-legend i.bill { background: #F4EFE6; border: 2px solid var(--cobalt); }

/* A phone is held upright and the tilt costs legibility at that width, so the
   room flattens to a true overhead view rather than shrinking the perspective. */
@media (max-width: 640px) {
  .floor-plane, .floor-room:hover .floor-plane { transform: none; }
  .floor { gap: 1.1rem .8rem; grid-template-columns: repeat(auto-fit, minmax(5.4rem, 1fr)); }
  .tbl:hover, .tbl:focus-visible { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .floor-plane, .floor-room:hover .floor-plane { transition: none; }
  .tbl, .tbl:hover, .tbl:focus-visible { transform: none; transition: none; }
}

/* ------------------------------------------------------------- table QR */

.qr-block { display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.qr { width: 172px; height: 172px; }
.qr svg { width: 100%; height: 100%; display: block; border-radius: 6px; }
.qr-block .hint { font-size: .82rem; color: var(--muted); text-align: center; margin: 0; }

/*
 * The printed sticker.
 *
 * Everything except the sticker is hidden, because a manager printing table
 * codes wants paper with codes on it, not a screenshot of a dashboard. The
 * code is printed under the symbol as well: a scratched sticker still has to
 * be usable by typing.
 */
@media print {
  body > *:not(.print-sheet) { display: none !important; }
  .print-sheet { display: block !important; }
}
.print-sheet { display: none; }
.print-sheet .sticker {
  width: 62mm; padding: 6mm 4mm; text-align: center;
  border: 1px dashed #999; border-radius: 4mm; margin: 4mm auto;
  page-break-inside: avoid; font-family: var(--fd);
}
.print-sheet .sticker svg { width: 42mm; height: 42mm; }
.print-sheet .sticker .t { font-weight: 900; font-size: 5mm; margin-top: 2mm; }
.print-sheet .sticker .c {
  font-family: ui-monospace, Menlo, monospace; font-size: 6mm;
  letter-spacing: .12em; margin-top: 1mm;
}
.print-sheet .sticker .n { font-size: 3.2mm; color: #444; margin-top: 1.5mm; }

/* ------------------------------------------------------------- cost grid */

/*
 * What a venue actually needs from cost reporting: the ceiling first.
 *
 * Tokens are meaningless to a restaurant. "The most one guest can cost you"
 * is a number an owner can put next to a cover charge and reason about, so it
 * leads, and the monthly total follows it.
 */
.cost-grid {
  display: grid; gap: .55rem;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line-2);
}
.cost-cell { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.cost-cell .k {
  font-family: var(--fd); font-weight: 700; font-size: .72rem;
  color: var(--muted); letter-spacing: .03em;
}
.cost-cell .v {
  font-family: var(--fd); font-weight: 900; font-size: 1.15rem;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--navy);
}
.cost-cell:first-child .v { color: var(--cobalt); }
.cost-cell .n { font-size: .72rem; color: var(--muted); line-height: 1.3; }

/* ══════════════════════════════════════════════ who is sitting at the table

   Inside the table sheet on the branch floor. A manager taps a table because
   somebody is waiting at it, so this is ordered the way the question is asked:
   who they are, whether they called, and what is on the pass.

   The allergy line is the one thing on this screen that can hurt somebody, so
   it is the one thing given a colour. */

#tblGuest { display: flex; flex-direction: column; gap: .6rem; }
#tblGuest[hidden] { display: none; }

.guest-card {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--bg-alt); padding: .75rem .85rem;
}
.guest-card h3 {
  font-family: var(--fd); font-weight: 800; font-size: .84rem;
  color: var(--ink); margin: 0 0 .5rem;
}
.guest-card .hint { margin: 0; font-size: .84rem; color: var(--muted); }
.guest-card ul { margin: 0; padding-inline-start: 1.1rem; font-size: .88rem; }
.guest-card li { margin-bottom: .2rem; }
.guest-card li em { color: var(--muted); font-style: normal; font-size: .84rem; }

/* A definition list, so a screen reader reads "טלפון" with the number rather
   than two loose strings. */
.guest-facts {
  margin: 0; display: grid; grid-template-columns: auto 1fr;
  gap: .3rem .8rem; font-size: .88rem;
}
.guest-facts dt { color: var(--muted); font-weight: 600; }
.guest-facts dd { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.guest-facts dd.flag {
  background: var(--rose-bg); color: var(--rose); font-weight: 700;
  border-radius: 6px; padding: .05rem .45rem; justify-self: start;
}

.guest-card.call { background: var(--amber-bg); border-color: var(--amber-line); }
.guest-card.call h3 { color: var(--amber); }

.guest-order + .guest-order { margin-top: .6rem; padding-top: .6rem; border-top: 1px solid var(--line-2); }
.o-status {
  display: inline-block; margin-bottom: .3rem;
  font-size: .74rem; font-weight: 800; border-radius: 999px; padding: .1rem .55rem;
  background: var(--cobalt-100); color: var(--cobalt-700);
}
.o-status[data-s="preparing"] { background: var(--amber-bg); color: var(--amber); }
.o-status[data-s="served"]    { background: var(--teal-bg);  color: var(--teal); }
.o-allergy {
  margin: .4rem 0 0; font-size: .84rem; font-weight: 700;
  background: var(--rose-bg); color: var(--rose);
  border-radius: 6px; padding: .3rem .5rem;
}
.o-allergy.o-age { background: #FFF4D6; color: #6B4400;
}

/* ------------------------------------------------------- payment settings */
.lede { color: var(--body); font-size: .93rem; line-height: 1.65; max-width: 68ch; margin-bottom: .7rem; }
.lede a { color: var(--cobalt); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
#payForm { margin-top: 1rem; display: flex; flex-direction: column; gap: .85rem; max-width: 560px; }
.payfields { display: flex; flex-direction: column; gap: .85rem; }
.hint.where { color: var(--muted); font-size: .84rem; margin: -.35rem 0 0; }
/* A checkbox is a target as much as a button is, so the whole row is one. */
.chk { display: flex; align-items: center; gap: .55rem; min-height: 44px; cursor: pointer; font-size: .9rem; color: var(--body); }
.chk input { width: 18px; height: 18px; accent-color: var(--cobalt); cursor: pointer; }
.chk[hidden] { display: none; }
.payactions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.payactions button { min-height: 44px; }
/* "Already on file": says the field is set without showing what it is set to. */
.onfile { font-size: .78rem; font-weight: 700; color: var(--teal); }
/* A saved payment field: locked, with its own "שינוי" (js/payments.js). */
.lockrow { display: flex; align-items: center; gap: .5rem; }
.lockrow > input, .lockrow > select { flex: 1 1 auto; min-width: 0; }
.lockrow > .lock-edit { flex: 0 0 auto; }
.field input:disabled, .field select:disabled { color: var(--muted); cursor: not-allowed; opacity: 1; }

/* ------------------------------------------------------------ assistant */
/* A launcher in the corner and a panel over the page. Fixed, so it is there on
   the floor, the menu and the overview alike; inline-start, which in this RTL
   layout is the bottom-RIGHT — where the eye starts, since the whole site
   reads right to left. */
.asst-host { position: fixed; inset-inline-start: 1.1rem; bottom: 1.1rem; z-index: 60; display: flex; flex-direction: column; align-items: flex-start; gap: .7rem; }
/* Qubi (2026-10-18): the launcher is Qubi with its name; the panel is a calm white chat, Qubi's face at the top. */
.asst-launch { display: inline-flex; align-items: center; gap: .55rem; min-height: 54px; padding: 0 1.15rem 0 .6rem; border-radius: 100px; background: #fff; color: var(--navy); border: 1px solid var(--line); font-family: var(--fd); font-weight: 700; font-size: .98rem; box-shadow: 0 12px 30px rgba(11,63,217,.18); cursor: pointer; transition: transform .16s var(--e), box-shadow .16s var(--e); }
.asst-launch:hover { box-shadow: 0 14px 34px rgba(11,63,217,.26); transform: translateY(-1px); }
.asst-launch-qubi { width: 34px; height: 32px; image-rendering: pixelated; }
/* Open, the panel has its own close: the launcher steps aside rather than float above the chat. */
.asst-host.open .asst-launch { display: none; }
.asst-panel { width: min(430px, calc(100vw - 2.2rem)); max-height: min(74dvh, 700px); display: flex; flex-direction: column; background: #fff; border: 1px solid #E8ECF4; border-radius: 22px; box-shadow: 0 28px 70px rgba(9,20,60,.24); overflow: hidden; }
.asst-panel[hidden] { display: none; }
.asst-head { display: flex; align-items: center; gap: .7rem; padding: .85rem 1rem; border-bottom: 1px solid #EEF1F7; background: linear-gradient(180deg, #F3F6FE, #fff); }
.asst-head-qubi { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 14px; background: #fff; border: 1px solid #E3E9F8; display: grid; place-items: center; }
.asst-head-qubi img { width: 36px; height: 34px; image-rendering: pixelated; }
.asst-head div { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.asst-head b { font-family: var(--fd); font-size: 1.05rem; color: var(--navy); }
.asst-head span { font-size: .8rem; color: var(--muted); }
.asst-close { margin-inline-start: auto; width: 40px; height: 40px; border-radius: 50%; font-size: 1.35rem; line-height: 1; color: var(--body); cursor: pointer; transition: background .16s var(--e); }
.asst-close:hover { background: #F1F4FA; }
.asst-log { flex: 1; min-height: 120px; overflow-y: auto; display: flex; flex-direction: column; gap: .5rem; padding: .9rem .9rem .3rem; }
/*
 * Nothing in the log is allowed to shrink.
 *
 * This is a column flexbox with a bounded height, and a flex item shrinks
 * before its container overflows. So a thread of proposal cards — 107px each
 * of text plus an אישור / ביטול row — was squeezed to 33px each until the
 * whole conversation "fitted": 1016px of content crushed into 531px. Two
 * things followed, and they looked like two separate bugs.
 *
 * The cards clip their own overflow, so the buttons were squeezed out of
 * existence and could not be pressed. And because nothing overflowed, the log
 * had nothing to scroll — scrollHeight equalled clientHeight — so the thread
 * was frozen with its own middle missing.
 *
 * `flex: 0 0 auto` is the whole fix: every message and every card keeps the
 * height it actually needs, the log overflows, and overflow-y does its job.
 */
.asst-log > * { flex: 0 0 auto; }
/*
 * Yesterday, at the top of the assistant.
 *
 * Deliberately not a chat bubble. It is a report rather than something the
 * assistant said, and a manager scanning it at seven in the morning should be
 * able to tell the two apart without reading. The jobs that need a person are
 * the only part in colour, because they are the only part that changes what
 * anybody does today.
 */
.asst-brief { align-self: stretch; background: var(--card, #fff); border: 1px solid var(--hair, #E4E9F4); border-radius: 14px; padding: .7rem .85rem; font-size: .88rem; line-height: 1.55; }
.asst-brief.off { color: var(--muted, #6B7590); font-size: .84rem; text-align: center; }
.asst-brief-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; margin-bottom: .45rem; }
.asst-brief-head b { font-size: .92rem; }
.asst-brief-off { background: none; border: 0; padding: 0; cursor: pointer; color: var(--muted, #6B7590); font: inherit; font-size: .8rem; text-decoration: underline; }
.asst-brief ul { margin: .2rem 0 0; padding-inline-start: 1.05rem; }
.asst-brief li { margin: .12rem 0; }
.asst-brief-todo { background: var(--amber-bg, #FFF4E0); color: var(--amber-ink, #8A5300); border-radius: 10px; padding: .45rem .6rem; margin-bottom: .5rem; }
.asst-brief-lines { list-style: none; padding-inline-start: 0; }
.asst-brief-rank { margin: .4rem 0 0; color: var(--muted, #6B7590); }
.asst-brief-per { margin-top: .5rem; padding-top: .5rem; border-top: 1px solid var(--hair, #E4E9F4); }

/* Messages: yours in cobalt on your side; Qubi's white with a soft line, Qubi beside the last of a run. */
.asst-msg { position: relative; max-width: 86%; padding: .6rem .85rem; border-radius: 18px; font-size: .93rem; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.asst-msg.you { align-self: flex-start; background: var(--btn); color: #fff; border-end-start-radius: 6px; }
.asst-msg.them, .asst-msg.bad { align-self: flex-end; margin-inline-end: 40px; background: #F5F7FC; color: var(--ink); border: 1px solid #E8ECF4; border-end-end-radius: 6px; }
.asst-msg.bad { background: var(--rose-bg); color: var(--rose-ink); border-color: transparent; }
.asst-qubi { position: absolute; bottom: -2px; inset-inline-end: -40px; width: 30px; height: 29px; image-rendering: pixelated; }
.asst-qubi.thinking { width: 32px; height: 29px; }
.asst-msg.them:has(+ .asst-msg.them) > .asst-qubi, .asst-msg.them:has(+ .asst-msg.bad) > .asst-qubi { visibility: hidden; }
.asst-msg.thinking { padding: .7rem .9rem; }
.asst-dots { display: inline-flex; gap: 4px; }
.asst-dots i { width: 7px; height: 7px; border-radius: 50%; background: #9AA7C7; animation: asst-dot 1.1s infinite ease-in-out; }
.asst-dots i:nth-child(2) { animation-delay: .15s; } .asst-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes asst-dot { 0%, 80%, 100% { opacity: .35; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }
/* The proposal: the one element in this panel that changes data. */
.asst-card { align-self: stretch; border: 1px solid #C9D6FB; border-radius: 18px; background: #fff; overflow: hidden; box-shadow: 0 6px 18px rgba(11,63,217,.08); }
.asst-card.off { opacity: .55; }
.asst-card-tag { padding: .5rem .9rem 0; font-size: .74rem; font-weight: 700; color: var(--cobalt-700); letter-spacing: .01em; }
.asst-card-body { padding: .35rem .9rem .75rem; font-size: .92rem; line-height: 1.55; color: var(--ink); max-height: 240px; overflow-y: auto; }
.asst-card-actions { display: flex; gap: .5rem; padding: .6rem .8rem; border-top: 1px solid #EEF1F7; background: #F8FAFE; align-items: center; }
.asst-card-actions button { min-height: 42px; border-radius: 12px; }
.asst-done { font-size: .86rem; font-weight: 700; color: var(--muted); }
.asst-done.ok { color: var(--teal); }
.asst-done.bad { color: var(--rose); }
.asst-chips { display: flex; flex-wrap: wrap; gap: .35rem; padding: .3rem .9rem .5rem; }
.asst-chips[hidden] { display: none; }
.asst-chip { font-size: .82rem; padding: .5rem .8rem; min-height: 36px; border-radius: 100px; border: 1px solid #DCE3F2; background: #fff; color: var(--body); cursor: pointer; text-align: start; transition: border-color .16s var(--e), background .16s var(--e); }
.asst-chip:hover { border-color: var(--cobalt-300); background: var(--cobalt-50); }
.asst-files { display: flex; flex-wrap: wrap; gap: .4rem; padding: 0 .9rem .4rem; }
.asst-file { display: inline-flex; align-items: center; gap: .3rem; font-size: .8rem; padding: .22rem .6rem; border-radius: 100px; background: var(--cobalt-50); color: var(--cobalt-700); }
.asst-file button { font-size: 1rem; line-height: 1; color: inherit; cursor: pointer; padding: 0 .1rem; }
.asst-file.kept { background: transparent; border: 1px dashed var(--cobalt-700); opacity: .85; }
.asst-compose { display: flex; gap: .45rem; align-items: flex-end; margin: .2rem .7rem .75rem; padding: .35rem; border: 1px solid #DCE3F2; border-radius: 20px; background: #fff; }
.asst-compose:focus-within { border-color: var(--cobalt); box-shadow: 0 0 0 3px var(--cobalt-50); }
.asst-compose textarea { flex: 1; min-height: 44px; resize: none; background: transparent; border: 0; border-radius: 14px; padding: .6rem .75rem; font-size: .93rem; color: var(--ink); line-height: 1.45; }
.asst-compose textarea:focus { outline: none; }
.asst-compose .btn { width: 44px; height: 44px; padding: 0; border-radius: 50%; }
.asst-compose .btn svg { width: 18px; height: 18px; }
.asst-attach { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 50%; border: 0; background: #F3F6FC; color: var(--body); cursor: pointer; flex: 0 0 auto; transition: border-color .16s var(--e), color .16s var(--e); }
.asst-attach:hover { border-color: var(--cobalt-300); color: var(--cobalt); }
.asst-attach svg { width: 20px; height: 20px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (max-width: 560px) {
  .asst-host { inset-inline-start: .6rem; bottom: .6rem; }
  /* dvh, not vh: on a phone `vh` is measured with the browser's own bars
     hidden, so 80vh of a real screen reaches under them. */
  .asst-panel { width: calc(100vw - 1.2rem); max-height: 80dvh; }
}
@media (prefers-reduced-motion: reduce) { .asst-launch { transition: none; } .asst-dots i { animation: none; } }

/* ---------------------------------------------------------- reservations */
.resv-bar { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; padding-bottom: .6rem; }
.resv-bar .seg button { min-width: 40px; min-height: 36px; }
.resv-date input { min-height: 38px; padding: .3rem .55rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); font: inherit; color: var(--ink); }
.resv-day { font-family: var(--fd); font-weight: 700; color: var(--navy); }
.resv-search { flex: 1 1 220px; max-width: 360px; }
.resv-search input { width: 100%; min-height: 38px; padding: .3rem .7rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); font: inherit; color: var(--ink); }
.resv-search input:focus { outline: 2px solid var(--cobalt); outline-offset: 1px; }
.resv-scope { font-size: .8rem; color: var(--body); margin-inline-start: auto; }
.resv-list { display: flex; flex-direction: column; }

/* The evening by the hour: a row of columns that scrolls sideways on a phone,
   because a shift manager reads this standing up with one hand. The fill is
   how full that hour is, so a glance finds the wall before the numbers do. */
/* The card holds one strip for the branch and, when the room is split, one
   more per area; each strip scrolls sideways on its own. */
.resv-load { padding-bottom: .9rem; }
/* When a booking's table is kept and given back (worker/seating.ts). */
.resv-keep { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1rem; padding-top: 0; font-size: .88rem; color: var(--muted); }
.resv-keep label { display: inline-flex; align-items: center; gap: .4rem; }
.resv-keep select { min-height: 40px; }
.resv-load-row { display: flex; gap: .35rem; overflow-x: auto; scrollbar-width: thin; padding-bottom: .3rem; }
.resv-load .hour { flex: 0 0 auto; min-width: 3.6rem; display: flex; flex-direction: column; align-items: center; gap: .25rem; padding: .35rem .3rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.resv-load .hour.full { border-color: var(--red, #C0341D); }
.resv-load .hour.peak { border-color: var(--cobalt); box-shadow: inset 0 0 0 1px var(--cobalt); }
.resv-load .hr { font-family: var(--fd); font-weight: 800; font-size: .84rem; color: var(--navy); font-variant-numeric: tabular-nums; }
/* A bar drawn from the tables actually taken, never from a percentage we made up. */
.resv-load .bar { width: 100%; height: 40px; border-radius: 3px; background: var(--line-2); display: flex; align-items: flex-end; overflow: hidden; }
.resv-load .bar i { display: block; width: 100%; background: var(--cobalt); border-radius: 3px 3px 0 0; }
.resv-load .hour.full .bar i { background: var(--red, #C0341D); }
.resv-load .n { font-size: .74rem; color: var(--body); font-variant-numeric: tabular-nums; text-align: center; line-height: 1.25; }
.resv-load .n b { color: var(--ink); font-weight: 700; }
.resv-load-none { font-size: .84rem; color: var(--body); margin: 0; padding-bottom: .8rem; }
.resv-area-name { font-family: var(--fd); font-weight: 700; font-size: .82rem; color: var(--body); padding: .5rem 0 .2rem; }
.resv-area-name b { color: var(--ink); }

/* Adding a table: the question and its three answers, on one line. */
.add-table { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; padding-bottom: .9rem; }
.add-table[hidden] { display: none; }
.add-table-q { font-family: var(--fd); font-weight: 700; font-size: .9rem; color: var(--ink); }
.add-table button { min-height: 40px; }
.add-table-said { font-size: .85rem; color: var(--body); }
.add-table-said.warn { color: var(--red, #C0341D); }

/* ------------------------------------------------------------- seating areas */
.areas-why { margin: 0 0 .8rem; font-size: .88rem; line-height: 1.6; color: var(--body); }
.areas-rows { display: flex; flex-direction: column; gap: .5rem; }
.area-row { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.area-row input { min-height: 40px; padding: .3rem .7rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); font: inherit; color: var(--ink); }
.area-row input:focus { outline: 2px solid var(--cobalt); outline-offset: 1px; }
.area-row .area-name { flex: 1 1 12rem; }
.area-row .area-kind { min-height: 40px; padding: .3rem .6rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); font: inherit; color: var(--ink); }
.area-row .area-count { font-variant-numeric: tabular-nums; color: var(--body); min-width: 6.5rem; }
.area-row label { font-size: .82rem; color: var(--body); }
.areas-actions { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; padding-top: .9rem; }
.areas-said { font-size: .85rem; color: var(--body); }
.areas-said.warn { color: var(--red, #C0341D); }
.resv-empty { padding: 0 1.2rem 1.1rem; color: var(--body); font-size: .92rem; line-height: 1.6; margin: 0; }
.resv { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: .9rem; padding: .75rem 1.2rem; border-top: 1px solid var(--line-2); }
.resv-time { font-family: var(--fd); font-weight: 800; font-size: 1.1rem; color: var(--navy); min-width: 3.2rem; font-variant-numeric: tabular-nums; }
.resv-who { display: flex; flex-direction: column; gap: .12rem; min-width: 0; }
.resv-who b { font-family: var(--fd); font-size: .95rem; color: var(--ink); }
.resv-meta { font-size: .84rem; color: var(--body); }
.resv-meta a { color: var(--cobalt); text-decoration: none; }
.resv-note { font-size: .84rem; color: var(--muted); }
.resv-actions { display: flex; gap: .4rem; flex-wrap: wrap; justify-content: flex-end; }
.resv-actions button { min-height: 40px; padding-inline: .8rem; font-size: .86rem; }
/* The party the host is about to greet. */
.resv.next { background: var(--cobalt-50); }
.resv.next .resv-time { color: var(--cobalt); }
/* Written off or done: still on the page, no longer in the way. */
.resv.cancelled, .resv.no_show { opacity: .55; }
.resv.late .resv-time { color: var(--amber); }
@media (max-width: 720px) {
  .resv { grid-template-columns: auto 1fr; }
  .resv .pill { grid-column: 2; justify-self: start; }
  .resv-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

/* ================================================================ phones
   The panels are desk screens first; nothing above changes for a desk. Below
   760px the same markup reflows: the top bar wraps instead of overflowing
   (which was widening the whole page to 478px), tabs stay reachable, the
   range picker stretches, tiles pair up, cards lose some padding, and the
   modal's four buttons wrap. Tables keep their own horizontal scroll. */
@media (max-width: 760px) {
  .wrap { padding-inline: .8rem; }
  .top { position: static; }
  .top .row { height: auto; min-height: 56px; flex-wrap: wrap; gap: .45rem .6rem; padding-block: .5rem; }
  .top .end { flex-wrap: wrap; justify-content: flex-end; gap: .4rem; }
  .top .end .btn-quiet, .top .end select.btn-quiet { padding: .4rem .65rem; font-size: .84rem; }
  .tabs { top: 0; }
  .tabs a, .tabs button { padding: .7rem .7rem .55rem; font-size: .88rem; }
  main { padding-block: 1rem 5.5rem; }
  .head { gap: .6rem; margin-bottom: .9rem; }
  .head .side { margin-inline-start: 0; width: 100%; }
  .head .side .seg { width: 100%; }
  .head .side .seg button { flex: 1 1 0; text-align: center; }
  .tiles { grid-template-columns: repeat(2, 1fr); gap: .55rem; }
  .tile { padding: .75rem .8rem; }
  .tile .v { font-size: 1.35rem; }
  .card > header { flex-wrap: wrap; gap: .35rem .7rem; padding: .8rem .9rem; }
  .card > header .hint { flex-basis: 100%; margin-inline-start: 0; }
  .card > header .btn-quiet { margin-inline-start: 0 !important; }
  .pad { padding: .9rem; }
  th, td { padding: .5rem .6rem; font-size: .86rem; }
  .bill { flex-wrap: wrap; row-gap: .3rem; }
  .bill .when, .bill .how, .bill .sum { min-width: 0; }
  .scrim { padding: .5rem; align-items: end; }
  .modal { max-height: 94dvh; }
  .modal .foot { flex-wrap: wrap; }
  .modal .foot .btn, .modal .foot .btn-quiet { flex: 1 1 45%; }
  .qr { width: 150px; height: 150px; }
  .board { grid-template-columns: 1fr; }
  .colhead { flex-wrap: wrap; }
}
@media (max-width: 400px) {
  .tiles { grid-template-columns: 1fr 1fr; }
  .tile .v { font-size: 1.2rem; }
  .top .end .btn-quiet { padding: .35rem .5rem; font-size: .8rem; }
}

/* The inline SMS code box under a phone field. */
.pv { margin-top: .6rem; padding: .8rem .9rem; border: 1px solid var(--cobalt-100, #DEE7FD); border-radius: 10px; background: var(--cobalt-50, #F1F5FE); display: grid; gap: .55rem; }
.pv[hidden] { display: none; }
.pv-lead { margin: 0; font-size: .9rem; color: var(--body, #4A5578); }
.pv-lead b { direction: ltr; unicode-bidi: embed; }
.pv-row { display: flex; gap: .5rem; }
.pv-code { flex: 1 1 auto; min-width: 0; font: 700 1.25rem ui-monospace, monospace; letter-spacing: .25em; text-align: center; direction: ltr; padding: .5rem .6rem; border: 1px solid var(--line, #E3E8F2); border-radius: 8px; min-height: 46px; }
.pv-acts { display: flex; gap: .8rem; }
.pv-acts button { background: none; border: 0; padding: 0; font: 700 .84rem inherit; color: var(--cobalt, #0B3FD9); cursor: pointer; }
.pv-acts button:disabled { color: var(--muted, #78829E); cursor: default; }
.pv-err { margin: 0; font-size: .86rem; color: var(--rose, #B32748); }

/* ---- the waitlist at the door (branch panel) ---- */
.wl-add { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; padding-bottom: .8rem; }
.wl-add input { min-height: 40px; padding: .3rem .7rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); font: inherit; color: var(--ink); }
.wl-add input:focus { outline: 2px solid var(--cobalt); outline-offset: 1px; }
.wl-add #wlName { flex: 1 1 160px; }
.wl-add #wlPhone { flex: 1 1 140px; }
.resv.wl.notified { background: var(--teal-bg); }
.resv.wl.left, .resv.wl.cancelled { opacity: .55; }

/* ---- importing a menu (chain panel) ---- */
.imp-modal { max-width: 60rem; }
.imp-drop { display: flex; align-items: center; justify-content: center; min-height: 96px; margin-top: .6rem; border: 2px dashed var(--cobalt-300); border-radius: var(--r-lg); background: var(--cobalt-50); color: var(--cobalt-700); font-family: var(--fd); font-weight: 700; cursor: pointer; }
.imp-drop:hover { background: var(--surface); }
.imp-table td { vertical-align: top; }
.imp-table input, .imp-table select { min-height: 34px; padding: .2rem .5rem; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); font: inherit; font-size: .9rem; color: var(--ink); max-width: 100%; }
.imp-table input[type="checkbox"] { width: 18px; height: 18px; min-height: 0; accent-color: var(--cobalt); }
.imp-table .sub { font-size: .78rem; color: var(--muted); margin-top: .2rem; max-width: 22rem; }
.imp-table tr.dropped { opacity: .4; }

/* -------------------------------------------- left without paying

   A bill with nobody behind it is the one row on a closing screen that has a
   person's name and phone number on it. Given the amber ground the rest of
   the "before you go home" list uses, and a table rather than chips: this is
   read and acted on one row at a time, not counted. */
.walkouts {
  border: 1px solid var(--amber-line); background: var(--amber-bg);
  border-radius: 12px; padding: .75rem .85rem;
}
.walkouts h3 { color: var(--amber-ink); }
/* The chain's list is a table of five columns: on a phone it scrolls inside
   its card rather than pushing the text past the card's edge. */
.walkout-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.walkout-wrap .walkout-table { min-width: 34rem; }
.walkout-wrap + .hint { margin: .7rem 0 0; font-size: .82rem; color: var(--muted); }
.walkout-table { width: 100%; border-collapse: collapse; font-size: .87rem; }
.walkout-table th {
  text-align: start; font-weight: 700; font-size: .78rem;
  color: var(--amber-ink); padding: 0 .5rem .35rem 0; white-space: nowrap;
}
.walkout-table td { padding: .35rem .5rem .35rem 0; vertical-align: top; border-top: 1px solid var(--amber-line); }
.walkout-table td:first-child { font-weight: 800; font-variant-numeric: tabular-nums; }
.walkout-table a { color: inherit; font-weight: 700; }
.walkouts .hint { color: var(--amber-ink); }   /* no opacity: at .8 it read 4.2:1 on the amber (axe, 2026-09-23) */
.contact-list { margin: .3rem 0 .5rem; padding-inline-start: 1.1rem; display: grid; gap: .3rem; }
.contact-list em { font-style: normal; opacity: .7; font-size: .8rem; }

/* ==========================================================================
   Liquid glass.

   Built to the four rules of the playbook the founder set, and each rule is
   a line you can point at:

     1. blur(20px) saturate(190%) paired with a THIN pane, .22  --lg-bg, --lg-blur, --lg-sat
     2. a 1px inner border, white at .25, as the refracted edge --lg-inner
     3. GPU promotion: translate3d on panes, will-change on the
        three that repaint under scroll (bar, tabs, rail)
     4. 4.5:1 for text on a moving ground                       --lg-haze + the blur

   Rules 1 and 4 pull against each other and the blur is what reconciles
   them: a thin pane over a coloured ground keeps its text legible only when
   what is behind the text has been smoothed to a single tone. 20px does
   that; the haze adds a margin on top.

   THIN GLASS (founder, 14 Sep, second pass). The playbook's .40 pane read
   as a slab; the ask was a thin sheet. So: the pane is .22, the rim is a
   1px hairline rather than 1.5px, the thickness shadow inside the bottom
   edge is half as deep, the bloom is a hint rather than a flare, the drop
   shadow sits closer, and the radii tighten a little (22/16/12). Because
   more of the ground now shows through, two things keep rule 4: the mesh
   blobs are paler than before, and the secondary text colour is darkened
   here (--muted #4F5A7C). The base #78829E was 3.8:1 even on plain white,
   so it was under the line before the glass and would have been well under
   it behind a thin one. Computed bounds on /account: ink about 12:1, muted
   about 4.9:1 on the brightest blob.

   What makes it Apple rather than merely transparent: the edge is a
   specular RIM (bright along the top and lit side, dim along the bottom),
   not a border; a bloom sits where light lands on the curve, painted behind
   the content; the pane has thickness, a shadow inside its bottom edge; and
   controls are capsules with a soft spring on press. The ground is a vivid
   mesh that drifts, because a lens over a flat page bends nothing.

   Blur and pseudo-elements live on containers only — bar, tabs, cards,
   tiles, modals, controls — never on table rows. Cards are NOT overflow
   hidden: the bloom clips to its own inherited radius, so a dropdown or a
   date picker inside a card can still open past the edge.
   ========================================================================== */

:root {
  --lg-bg:      linear-gradient(160deg, rgba(255, 255, 255, .62) 0%, rgba(255, 255, 255, .42) 50%, rgba(255, 255, 255, .34) 100%);   /* white glass: lit at the top-start */
  --lg-bg-hi:   linear-gradient(160deg, rgba(255, 255, 255, .76) 0%, rgba(255, 255, 255, .58) 50%, rgba(255, 255, 255, .52) 100%);
  --lg-inner:   rgba(255, 255, 255, .25);   /* rule 2 */
  --lg-haze:    rgba(255, 255, 255, .05);
  --lg-rim-a:   rgba(255, 255, 255, .92);   /* the lit edge, a hairline */
  --lg-rim-b:   rgba(255, 255, 255, .18);   /* the far edge */
  --lg-edge:    rgba(10, 19, 48, .10);      /* outer contour, ink-tinted so it shows on light */
  --lg-bloom:   rgba(255, 255, 255, .28);
  --lg-depth:   rgba(10, 19, 48, .10);
  --lg-shadow:  0 14px 36px -22px rgba(10, 19, 48, .24), 0 1px 2px rgba(10, 19, 48, .04);
  --lg-blur:    24px;
  --lg-sat:     1.5;
  --lg-tint:    rgba(11, 63, 217, .10);
  --lg-r:       22px;
  --lg-r-sm:    16px;
  --lg-r-in:    12px;
  --lg-pill:    999px;
  --lg-spring:  cubic-bezier(.2, .8, .2, 1);
  --mesh-0:     #EEF2FB;
  --mesh-1:     rgba(11, 63, 217, .34);
  --mesh-2:     rgba(11, 63, 217, .18);
  --mesh-3:     rgba(11, 63, 217, .14);
  --mesh-4:     rgba(11, 63, 217, .08);
  --muted:      #4F5A7C;                    /* rule 4 behind a thin pane; see the note above */
}

/* The ground. A fixed pseudo-element drifted by background-position, which
   the compositor moves without a repaint. */
body { position: relative; isolation: isolate; background: var(--mesh-0); }
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(55rem 40rem at 82% -8%,  var(--mesh-1), transparent 60%),
    radial-gradient(48rem 42rem at -6% 30%,  var(--mesh-2), transparent 62%),
    radial-gradient(44rem 34rem at 60% 110%, var(--mesh-3), transparent 60%),
    radial-gradient(36rem 30rem at 20% 95%,  var(--mesh-4), transparent 62%),
    var(--mesh-0);
  background-size: 130% 130%;
  animation: lg-drift 46s ease-in-out infinite alternate;
  transform: translate3d(0, 0, 0);
}
@keyframes lg-drift { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }

/* The lens: rules 1, 2 and 3 on every pane. Inputs are on this list because
   they cannot host a ::before, and the rim alone already reads as glass. */
body > .top, body .tabs, body .rail,
body .card, body .tile, body .modal, body .mystat, body .attention a,
body .btn-quiet, body .picker button, body .planPick, body .search,
body .field input, body .field select, body .field textarea, body .modal .field input {
  background: var(--lg-bg);
  border: 1px solid var(--lg-edge);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-sat));
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-sat));
  box-shadow:
    inset 0 0 0 1px var(--lg-inner),
    inset 0 1px 0 var(--lg-rim-a),
    inset 1px 0 0 var(--lg-rim-b),
    inset 0 -1px 0 var(--lg-rim-b),
    inset 0 -8px 16px -14px var(--lg-depth),
    inset 0 0 0 100vmax var(--lg-haze),
    var(--lg-shadow);
  transform: translate3d(0, 0, 0);
}
body > .top, body .tabs, body .rail { will-change: backdrop-filter; }
body > .top, body .tabs, body .rail, body .search,
body .field input, body .field select, body .field textarea, body .modal .field input { background: var(--lg-bg-hi); }

/* The bloom: light landing on the curve, behind the content. Clipped by its
   own inherited radius, so the pane itself stays free to overflow. */
body .card, body .tile, body .modal, body .mystat, body .attention a { position: relative; isolation: isolate; }
body .btn, body .btn-quiet, body .picker button { position: relative; overflow: hidden; isolation: isolate; }
body .card::before, body .tile::before, body .modal::before, body .mystat::before, body .attention a::before,
body .btn::before, body .btn-quiet::before, body .picker button::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: inherit;
  background:
    radial-gradient(120% 70% at 30% -20%, var(--lg-bloom), transparent 55%),
    linear-gradient(180deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, 0) 40%);
}

/* Shape. A lens is round-cornered; controls are capsules. */
body .card, body .modal { border-radius: var(--lg-r); }
body .tile, body .mystat, body .attention a { border-radius: var(--lg-r-sm); }
body .btn, body .btn-quiet, body .picker button, body .planPick, body .search, body .pill { border-radius: var(--lg-pill); }
body .field input, body .field select, body .field textarea, body .modal .field input { border-radius: var(--lg-r-in); }
body .card > header, body .modal header, body .modal .foot { border-color: var(--lg-edge); }
body > .top { border-width: 0 0 1px; box-shadow: inset 0 0 0 1px var(--lg-inner), inset 0 -1px 0 var(--lg-edge), 0 12px 40px -24px var(--lg-depth); }
body .tabs { border-width: 0 0 1px; box-shadow: inset 0 0 0 1px var(--lg-inner); }
body .rail { border-width: 0; box-shadow: inset 0 0 0 1px var(--lg-inner), inset -1px 0 0 var(--lg-edge); }
body .tile.live { background: var(--lg-tint); border-color: var(--cobalt-300); }

/* Controls. The filled button is the one opaque thing on the screen, since
   the white on it needs the cobalt, but it is cut from the same lens: inner
   border, rim, bloom, depth, and a cobalt glow instead of a grey drop. A
   short spring on hover and press is the part people call "feel". */
body .btn {
  position: relative; overflow: hidden; border-radius: var(--lg-pill);
  background: var(--btn);
  border: 1px solid rgba(255, 255, 255, .22);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .18),
    inset 0 1px 0 rgba(255, 255, 255, .50),
    inset 0 -1px 0 rgba(0, 0, 0, .16),
    inset 0 -8px 16px -14px rgba(0, 0, 0, .25),
    0 10px 26px -12px rgba(11, 63, 217, .55);
  transition: transform .22s var(--lg-spring), box-shadow .22s var(--lg-spring), background .18s var(--e);
  will-change: transform;
}
body .btn::before { background: radial-gradient(120% 80% at 30% -30%, rgba(255, 255, 255, .40), transparent 55%); }
body .btn:hover { background: var(--btn-hover); transform: translate3d(0, -1px, 0); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .2), inset 0 1px 0 rgba(255, 255, 255, .55), inset 0 -1px 0 rgba(0, 0, 0, .18), inset 0 -8px 16px -14px rgba(0, 0, 0, .25), 0 14px 30px -12px rgba(11, 63, 217, .65); }
body .btn:active { transform: translate3d(0, 0, 0) scale(.98); }
body .btn:disabled { transform: none; }
body .btn-quiet, body .picker button { transition: transform .22s var(--lg-spring), background .18s var(--e), border-color .18s var(--e); will-change: transform; }
body .btn-quiet:hover, body .picker button:hover, body .attention a:hover { background: var(--lg-tint); border-color: var(--cobalt-300); }
body .btn-quiet:active, body .picker button:active { transform: scale(.98); }
body .field input:focus, body .field select:focus, body .field textarea:focus { background: var(--lg-bg-hi); border-color: var(--cobalt); box-shadow: inset 0 0 0 1px var(--lg-inner), inset 0 1px 0 var(--lg-rim-a), 0 0 0 4px var(--lg-tint); }
body .pill { -webkit-backdrop-filter: none; backdrop-filter: none; }

/* Where the lens stands down, by resetting the tokens so the rules above
   stay one set. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :root { --lg-bg: var(--surface); --lg-bg-hi: var(--surface); --lg-haze: transparent; --lg-bloom: transparent; }
}
@media (prefers-reduced-transparency: reduce) {
  :root { --lg-bg: var(--surface); --lg-bg-hi: var(--surface); --lg-haze: transparent; --lg-bloom: transparent; --lg-blur: 0px; }
  body::before { background: var(--bg-alt); animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
  body .btn, body .btn:hover, body .btn:active, body .btn-quiet:active, body .picker button:active { transform: none; transition: none; }
}
/* The kitchen screen: a tablet on the pass, read at arm's length mid-service. */
body[data-solid] { --lg-bg: var(--surface); --lg-bg-hi: var(--surface); --lg-haze: transparent; --lg-bloom: transparent; --lg-blur: 0px; --lg-shadow: var(--s1); --lg-rim-a: transparent; --lg-rim-b: transparent; --lg-inner: transparent; }
body[data-solid]::before { background: var(--bg-alt); animation: none; }
body[data-solid] .top, body[data-solid] .tabs, body[data-solid] .card, body[data-solid] .tile, body[data-solid] .modal,
body[data-solid] .btn-quiet, body[data-solid] .field input, body[data-solid] .field select, body[data-solid] .field textarea {
  -webkit-backdrop-filter: none; backdrop-filter: none; will-change: auto;
}
@media print {
  body::before { display: none; }
  body > .top, body .tabs, body .rail, body .card, body .tile, body .modal, body .mystat, body .attention a, body .btn-quiet,
  body .picker button, body .planPick, body .search, body .field input, body .field select, body .field textarea {
    background: #fff; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; border-color: #ccc; transform: none;
  }
}

/* ==========================================================================
   The bell. See public/js/notices.js.

   A count on the bell, a list under it, toasts in the bottom corner. Levels
   are a colour on the start edge: urgent is the chain's red, action is
   cobalt, info is the hairline. Same glass as everything else; the toasts
   are the one thing that sits ABOVE the modal layer, because a waiter call
   during a refund dialog is still a waiter call.
   ========================================================================== */
.bell { position: relative; width: 40px; padding: 0; }
.bell svg { width: 19px; height: 19px; }
.bell .bell-n {
  position: absolute; top: -6px; inset-inline-end: -6px; min-width: 19px; height: 19px; padding: 0 5px;
  border-radius: 999px; background: #D92D20; color: #fff; font-size: .7rem; font-weight: 800; line-height: 19px;
  text-align: center; font-family: var(--fd); box-shadow: 0 0 0 2px var(--surface);
}
.bell.has svg { animation: bell-swing 1.6s var(--e) 1; transform-origin: 50% 8%; }
@keyframes bell-swing { 0%,100% { transform: rotate(0); } 15% { transform: rotate(14deg); } 35% { transform: rotate(-12deg); } 55% { transform: rotate(8deg); } 75% { transform: rotate(-5deg); } }

.bellpop {
  position: fixed; z-index: var(--z-drop); max-height: min(70vh, 560px); display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--lg-r-sm, 16px);
  box-shadow: 0 24px 60px -24px rgba(10,19,48,.45), 0 2px 8px rgba(10,19,48,.08);
}
.bellpop[hidden] { display: none; }   /* `hidden` loses to the flex above without this; it has bitten twice before */
.bellpop-head { display: flex; align-items: center; justify-content: space-between; gap: .6rem; padding: .7rem .9rem; border-bottom: 1px solid var(--line); }
.bellpop-head b { font-family: var(--fd); font-size: .95rem; color: var(--navy); }
.bellpop-tools { display: flex; gap: .3rem; }
.btn-quiet.sm { padding: .3rem .55rem; font-size: .85rem; min-height: 32px; }
.sound-toggle { width: 40px; padding: 0; font-size: 1.05rem; }
.sound-banner { background: var(--amber-bg, #FFF4E0); color: var(--amber, #8A5A00); border-bottom: 1px solid var(--amber-line, #F2D28A); text-align: center; font-weight: 700; font-size: .9rem; padding: .5rem .9rem; }
/* The one-time ask for browser notifications, under the bar until the browser has an answer. */
.push-ask { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .5rem .9rem; padding: .5rem .9rem; background: var(--lg-tint, rgba(11,63,217,.10)); color: var(--ink); border-bottom: 1px solid var(--lg-edge, rgba(10,19,48,.10)); font-weight: 700; font-size: .9rem; }
.push-ask .ntoast-x { margin-inline-start: .2rem; }
.btn.sm { padding: .32rem .8rem; font-size: .85rem; min-height: 32px; }
.bellpop-list { overflow: auto; overscroll-behavior: contain; padding: .35rem; display: grid; gap: .2rem; }
.bellpop-empty { margin: 0; padding: 1rem .9rem 1.1rem; }
.nrow {
  display: grid; grid-template-columns: 26px 1fr auto; gap: .55rem; align-items: start; width: 100%;
  text-align: start; padding: .55rem .6rem; border: 0; border-radius: 12px; background: transparent; color: var(--ink);
  border-inline-start: 3px solid var(--line); cursor: pointer; font: inherit;
}
.nrow:hover { background: var(--bg-alt); }
.nrow.new { background: var(--cobalt-50, #EEF3FF); }
.nrow.urgent { border-inline-start-color: #D92D20; }
.nrow.action { border-inline-start-color: var(--cobalt); }
.nrow-ic { font-size: 1rem; line-height: 1.4; text-align: center; }
.nrow-txt { display: grid; gap: .1rem; min-width: 0; }
.nrow-txt b { font-family: var(--fd); font-size: .9rem; color: var(--navy); }
.nrow-txt span { font-size: .84rem; color: var(--ink); overflow-wrap: anywhere; }
.nrow-txt em { font-style: normal; font-size: .76rem; color: var(--muted); }
.nrow time { font-size: .74rem; color: var(--muted); white-space: nowrap; padding-top: .15rem; }

.ntoasts {
  /* inline-END: the assistant's floating button owns the inline-start corner. */
  position: fixed; bottom: 16px; inset-inline-end: 16px; z-index: calc(var(--z-modal) + 5);
  display: flex; flex-direction: column; gap: .5rem; width: min(380px, calc(100vw - 32px)); pointer-events: none;
}
/* On a phone the accessibility button floats in this corner (a11y.js); the
   toasts stack above it rather than on it. */
html.qa11y-floating .ntoasts { bottom: 76px; }
.ntoast {
  pointer-events: auto; display: grid; grid-template-columns: 26px 1fr auto auto; gap: .55rem; align-items: center;
  padding: .7rem .75rem .7rem .85rem; border-radius: 16px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-inline-start: 4px solid var(--line);
  box-shadow: 0 20px 48px -20px rgba(10,19,48,.5), 0 2px 8px rgba(10,19,48,.08);
  opacity: 0; transform: translate3d(0, 10px, 0); transition: opacity .22s var(--e), transform .22s var(--e); cursor: pointer;
}
.ntoast.in { opacity: 1; transform: translate3d(0, 0, 0); }
.ntoast.urgent { border-inline-start-color: #D92D20; }
.ntoast.action { border-inline-start-color: var(--cobalt); }
.ntoast-txt { display: grid; gap: .1rem; min-width: 0; }
.ntoast-txt b { font-family: var(--fd); font-size: .92rem; color: var(--navy); }
.ntoast-txt span { font-size: .85rem; overflow-wrap: anywhere; }
.ntoast-txt em { font-style: normal; font-size: .76rem; color: var(--muted); }
.ntoast-acts:empty { display: none; }
.ntoast-x { border: 0; background: transparent; color: var(--muted); font-size: 1.2rem; line-height: 1; padding: .2rem .35rem; cursor: pointer; border-radius: 8px; }
.ntoast-x:hover { background: var(--bg-alt); color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .bell.has svg { animation: none; } .ntoast { transition: none; } }
@media print { .bell, .bellpop, .ntoasts { display: none !important; } }

/* ==========================================================================
   More panes, same lens (founder, 14 Sep: "everything in the dashboards,
   and the kitchen"). What was still solid: the segment picker, chips, the
   assistant's panel and cards, the reservation and area inputs, the bell's
   list and toasts, and the kitchen's tickets and calls now that the pass is
   no longer a solid screen. State colours on tickets and calls are kept on
   top: a new ticket is still cobalt, a call is still amber.
   ========================================================================== */
body .seg, body .chips button, body .stop-reason, body .asst-panel, body .asst-card, body .asst-chip,
body .asst-compose textarea, body .asst-attach, body .resv-date input, body .resv-search input,
body .resv-load .hour, body .area-row input, body .area-row .area-kind, body .bellpop, body .ntoast,
body .order, body .call {
  background: var(--lg-bg);
  border: 1px solid var(--lg-edge);
  -webkit-backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-sat));
  backdrop-filter: blur(var(--lg-blur)) saturate(var(--lg-sat));
  box-shadow:
    inset 0 0 0 1px var(--lg-inner),
    inset 0 1px 0 var(--lg-rim-a),
    inset 1px 0 0 var(--lg-rim-b),
    inset 0 -1px 0 var(--lg-rim-b),
    inset 0 -8px 16px -14px var(--lg-depth),
    inset 0 0 0 100vmax var(--lg-haze),
    var(--lg-shadow);
  transform: translate3d(0, 0, 0);
}
body .asst-panel, body .asst-compose textarea, body .stop-reason, body .resv-date input, body .resv-search input,
body .area-row input, body .area-row .area-kind, body .bellpop, body .ntoast, body .order, body .call { background: var(--lg-bg-hi); }
body .bellpop, body .ntoast, body .asst-panel, body .asst-card, body .order, body .call { border-radius: var(--lg-r-sm); }
body .chips button, body .asst-chip, body .asst-attach { border-radius: var(--lg-pill); }
body .ntoast { border-inline-start-width: 4px; }
body .nrow.new { background: var(--lg-tint); }
/* The kitchen: state rings survive the lens. */
body .order { border-width: 2px; overflow: hidden; }
body .order.new { border-color: var(--cobalt); box-shadow: inset 0 0 0 1px var(--lg-inner), 0 0 0 4px var(--lg-tint), var(--lg-shadow); }
body .order.preparing { border-color: var(--amber); }
body .order-head { background: rgba(255, 255, 255, .22); border-bottom-color: var(--lg-edge); }
body .call { border-width: 2px; border-color: var(--amber); }
body .call.acked { border-color: var(--cobalt-300); }
body .call.resolved { border-color: var(--lg-edge); }

/* ==========================================================================
   DARK SMOKED GLASS — the panels (founder's reference, 14 Sep, second pass).

   REMOVED 2026-09-22: the founder had the dark skin taken out of every
   dashboard. The [data-theme="dark"] rules and the prefers-color-scheme
   blocks are gone; js/theme.js pins "light". What follows below this
   header is the description of a material that no longer ships, kept as
   the record of what the light glass was designed against.

   The material, in one sentence: a near-black room lit from behind by a
   huge, soft cobalt light, with sheets of smoked glass floating in it. The
   glass is NOT blue. It is neutral, slightly milky, and it darkens what is
   behind it (the smoke) while catching a little white light on its upper
   edge (the reflection). Cobalt reaches the eye only as the light behind the
   sheet, diffused by the blur, and as the brand accent on the one filled
   button. Everything that is text is white, at three strengths.

   How that is built, and where to change it:

     THE ROOM      body::before — three static radial lights of the brand
                   cobalt (#0B3FD9), the big one behind the top of the page.
                   No animation: environmental light does not drift.
     THE SMOKE     --lg-haze — an inset shadow the size of the pane, in a
                   dark tint, so the pane is darker than what is behind it.
     THE MILK      --lg-bg — a diagonal white gradient at ~8% → ~3%, so the
                   sheet is lighter where the light lands and neutral below.
     THE EDGE      a 1px hairline (--lg-edge) plus a masked gradient ring on
                   cards and modals: bright white at the top-start corner,
                   fading, with a faint cobalt at the far corner.
     THE LEVELS    bars .55 dark / cards the milk / controls white .07 →
                   .11 on hover / inputs darker (--g-in) / modals and the
                   bell's list denser (--g4) with more blur. Each level is a
                   different amount of light through the sheet.

   Everything below re-tokenises the light glass layer above it; the rules
   there stay in force and read these values. What is new here: the ring,
   the table and chart treatment, the smoke, the room.
   ========================================================================== */

/* The brand colour is the source of every blue on the page. The lighter
   blues are the same hue with white light in it (color-mix), never a
   second colour. */

/* ---------------------------------------------------------------- the room */

/* ------------------------------------------------------------- the sheets */
/* The bars are dense and dark, so the content reads under them. */

/* The ring: a masked gradient border, bright where the light lands. On the
   sheets that carry content; controls keep the plain hairline. */

/* not .bellpop: see above */

/* The kitchen's tickets and calls keep their state ring instead. */

/* Modals and the bell's list: denser glass, more blur — this is where the
   page behind should visibly diffuse through the sheet. */

/* Controls: a touch of white light, more on hover; a cobalt ring on focus. */

/* Tables belong to the sheet: no white header, hairline rows, a breath of light on hover. */

/* Charts: the bars are the brand, the empty ones are glass. */

/* The bell: rows on the dense sheet, the new ones lit by cobalt. */

/* The tile that is live keeps its cobalt wash, brighter here. */

/* Where the glass stands down. */
@media (prefers-reduced-transparency: reduce) {

}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  
}
@media print {
  
}

/* The brand is white on the dark bar; the mark is the same file, lit. */

/* Blur only where it buys something. Controls, chips and inputs sit on a
   sheet that is already blurred; a second blur under each of them is a
   GPU layer per button for no visible gain (103 layers on the branch
   page before this). The bars, the sheets, the modals and the bell keep it. */

/* ==========================================================================
   THE WHITE ROOM (founder, 14 Sep: "the white version too"). The same
   material as the dark: a room lit by the brand cobalt, sheets of glass with
   a lit edge. Here the room is bone, the sheets are white light, the ink is
   navy. The tokens above carry it; what follows is what the light skin
   needed that the dark block only gives to itself: the still room and the
   ring. Everything is theme-keyed by the dark block, so the two never mix.
   ========================================================================== */
body::before {
  background:
    radial-gradient(84rem 52rem at 72% -18%, var(--mesh-1), transparent 64%),
    radial-gradient(64rem 52rem at 4% 60%,   var(--mesh-2), transparent 64%),
    radial-gradient(70rem 28rem at 54% 108%, var(--mesh-3), transparent 62%),
    radial-gradient(36rem 30rem at 96% 46%,  var(--mesh-4), transparent 62%),
    var(--mesh-0);
  background-size: 100% 100%;
  animation: none;                /* environmental light does not drift, in either room */
}
body .card, body .tile, body .modal, body .mystat, body .bellpop, body .ntoast, body .asst-panel { border-color: transparent; }
/*
 * The rim overlay needs a positioned box, and every surface here gets one —
 * except the bell's list, which must keep the `fixed` its own layout depends
 * on. It is placed under the bell in viewport coordinates by notices.js; made
 * relative it kept those coordinates and landed a page and a half further
 * down, so clicking the bell appeared to do nothing at all. A fixed box is
 * already a containing block for ::after, so it loses nothing by staying out.
 */
body .card, body .tile, body .modal, body .mystat, body .ntoast, body .asst-panel { position: relative; }
body .card::after, body .tile::after, body .modal::after, body .mystat::after, body .bellpop::after, body .ntoast::after, body .asst-panel::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(135deg, rgba(255,255,255,.98) 0%, rgba(255,255,255,.55) 30%, rgba(255,255,255,.30) 62%, rgba(11,63,217,.30) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
html[dir="rtl"] body .card::after, html[dir="rtl"] body .tile::after, html[dir="rtl"] body .modal::after, html[dir="rtl"] body .mystat::after,
html[dir="rtl"] body .bellpop::after, html[dir="rtl"] body .ntoast::after, html[dir="rtl"] body .asst-panel::after {
  background: linear-gradient(225deg, rgba(255,255,255,.98) 0%, rgba(255,255,255,.55) 30%, rgba(255,255,255,.30) 62%, rgba(11,63,217,.30) 100%);
}
body .bellpop, body .ntoast, body .asst-panel, body .modal { background: var(--lg-bg-hi); }
body .btn-quiet, body .picker button, body .planPick, body .search, body .field input, body .field select, body .field textarea, body .modal .field input,
body .seg, body .chips button, body .stop-reason, body .asst-card, body .asst-chip, body .asst-compose textarea, body .asst-attach, body .resv-date input,
body .resv-search input, body .resv-load .hour, body .area-row input, body .area-row .area-kind, body .attention a, body .refund-line input, body .mystat {
  -webkit-backdrop-filter: none; backdrop-filter: none; will-change: auto;
}
th { background: rgba(255,255,255,.35); }
tbody tr:hover { background: rgba(11,63,217,.05); }
.brand .mark-img { filter: none; }

/* ==========================================================================
   THE FLOOR, IN THE ROUND (founder, 14 Sep: "make the tables 3D even
   better, more realistic"). One light, top-left and a little in front, and
   everything on the floor agrees with it: the plank grain runs away from
   the viewer under a vignette; a table is a beveled top with a specular
   highlight, a pedestal under it, and an elliptical shadow it casts to the
   bottom-right; a chair is a seat with a backrest on its outer edge and its
   own small shadow. Occupancy stays the amber top and the bill the cobalt
   ring, because those are the two things the map is scanned for, and a
   number on a table stays as legible as it was.

   In the dark room the floor is walnut under cobalt light and the tops stay
   pale, which is what makes the numbers readable at arm's length.
   ========================================================================== */
.floor-room { perspective: 2400px; perspective-origin: 50% 42%; }
.floor-plane {
  transform: rotateX(30deg);
  border-radius: 20px;
  border: 1px solid #CDB894;
  background:
    /* the grain: fine lines within each plank */
    repeating-linear-gradient(90deg, rgba(120, 86, 46, .06) 0 1px, transparent 1px 7px),
    /* the plank seams, with a lit and a shaded edge */
    repeating-linear-gradient(90deg, #EFE2CF 0 44px, #E3D2B8 44px 46px, #F6ECDD 46px 47px, transparent 47px 48px),
    /* the vignette and the light from the top-left */
    radial-gradient(120% 90% at 22% 0%, rgba(255, 250, 240, .55), transparent 60%),
    linear-gradient(180deg, #F1E6D5 0%, #E6D6BF 60%, #D9C6A9 100%);
  box-shadow:
    inset 0 0 80px rgba(110, 80, 40, .22),
    inset 0 1px 0 rgba(255, 255, 255, .7),
    0 14px 0 -4px #C6AE86,                        /* the front edge of the slab */
    0 22px 6px -6px rgba(60, 40, 12, .35),
    0 46px 70px -20px rgba(10, 19, 48, .45);
}
.floor-room:hover .floor-plane { transform: rotateX(25deg); }
.floor-band[data-kind="indoor"] { background: none; }

/* --- the table ---------------------------------------------------------- */
/* The cast shadow: an ellipse on the floor, thrown down-right, softened. */
.tbl::before {
  content: ""; position: absolute; left: 20%; top: 24%; width: 66%; height: 62%;
  border-radius: 50%; background: rgba(40, 26, 8, .32);
  filter: blur(7px); transform: translateZ(1px); pointer-events: none;
  transition: transform .22s var(--e), opacity .22s var(--e);
}
/* The pedestal: a dark foot on the floor and a column up to the top. */
.tbl::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 30%; height: 18%;
  transform: translate(-50%, -30%) translateZ(3px);
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, #6F5538, #3B2A18 70%);
  box-shadow: 0 3px 4px rgba(30, 18, 4, .45), 0 -22px 0 -8px #4E3A24;   /* the column, foreshortened */
  pointer-events: none;
}
.tbl .top {
  inset: 13%;
  border: 0;
  background:
    radial-gradient(circle at 32% 24%, rgba(255, 255, 255, .95) 0%, rgba(255, 255, 255, 0) 38%),   /* the specular */
    radial-gradient(circle at 50% 50%, #FBF7F0 0%, #F2EBE0 60%, #E4DACA 100%);
  box-shadow:
    inset 0 2px 3px rgba(255, 255, 255, .9),        /* the lit edge of the bevel */
    inset 0 -4px 8px rgba(120, 100, 70, .18),        /* the shaded edge of the bevel */
    inset 0 0 0 1px rgba(160, 140, 110, .25),
    0 8px 0 #D2C3A9,                                 /* the thickness */
    0 9px 0 1px #B8A688,
    0 12px 3px rgba(80, 58, 26, .22);
  transform: translateZ(32px);
}
.tbl:hover .top, .tbl:focus-visible .top { box-shadow: inset 0 2px 3px rgba(255,255,255,.9), inset 0 -4px 8px rgba(120,100,70,.18), inset 0 0 0 1px rgba(160,140,110,.25), 0 8px 0 #D2C3A9, 0 9px 0 1px #B8A688, 0 14px 4px rgba(80,58,26,.26); }
.tbl:hover::before, .tbl:focus-visible::before { transform: translateZ(1px) scale(1.12); opacity: .85; }
.tbl[data-state="busy"] .top {
  background:
    radial-gradient(circle at 32% 24%, rgba(255, 244, 220, .95) 0%, rgba(255, 244, 220, 0) 38%),
    radial-gradient(circle at 50% 50%, #FFC873 0%, #F79E28 58%, #DD831A 100%);
  box-shadow:
    inset 0 2px 3px rgba(255, 240, 210, .85),
    inset 0 -4px 8px rgba(120, 60, 0, .22),
    inset 0 0 0 1px rgba(150, 90, 10, .35),
    0 8px 0 #B9690D,
    0 9px 0 1px #8F5008,
    0 12px 3px rgba(90, 52, 6, .3);
}
/* The bill ring glows a little, so it reads through the amber too. */
.tbl[data-bill="1"] .top::after { inset: -8px; border-width: 3px; box-shadow: 0 0 14px rgba(11, 63, 217, .55), inset 0 0 10px rgba(11, 63, 217, .25); }

/* --- the chairs --------------------------------------------------------- */
.tbl .chair {
  border-radius: 6px;
  background:
    radial-gradient(circle at 35% 30%, rgba(255, 255, 255, .28), transparent 55%),   /* the sheen on the cushion */
    linear-gradient(180deg, #9A7650, #6F5233);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25), inset 0 -2px 3px rgba(40,24,6,.35), 0 3px 4px rgba(40, 26, 8, .45), 0 8px 10px -4px rgba(40, 26, 8, .35);
  transform: translateZ(8px);
}
/* The backrest: a darker bar on the outer edge of the chair, standing a little higher. */
.tbl .chair::before {
  content: ""; position: absolute; border-radius: 4px;
  background: linear-gradient(180deg, #7A5A3A, #4E3823);
  box-shadow: 0 2px 3px rgba(30, 18, 4, .45);
  transform: translateZ(10px);
}
.tbl .chair:nth-child(1)::before { left: 6%; right: 6%; top: -28%; height: 30%; }     /* above the table: back at the top */
.tbl .chair:nth-child(2)::before { left: 6%; right: 6%; bottom: -28%; height: 30%; }  /* below: back at the bottom */
.tbl .chair:nth-child(3)::before { top: 6%; bottom: 6%; left: -28%; width: 30%; }     /* start side */
.tbl .chair:nth-child(4)::before { top: 6%; bottom: 6%; right: -28%; width: 30%; }    /* end side */

/* --- outside ------------------------------------------------------------ */
.floor-band[data-kind="outdoor"] {
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.55) 0 2px, transparent 2px 62px),
    repeating-linear-gradient(0deg, rgba(255,255,255,.55) 0 2px, transparent 2px 62px),
    radial-gradient(120% 90% at 22% 0%, rgba(255, 255, 255, .45), transparent 60%),
    linear-gradient(180deg, #DDE1E6, #C3C9D1);
  box-shadow: inset 0 0 50px rgba(60, 72, 92, .22), inset 0 1px 0 rgba(255,255,255,.6);
}
.tbl[data-kind="outdoor"] .top {
  border-radius: 14px;
  background:
    radial-gradient(circle at 32% 24%, rgba(255, 255, 255, .9) 0%, rgba(255, 255, 255, 0) 38%),
    repeating-linear-gradient(0deg, rgba(120, 100, 70, .10) 0 1px, transparent 1px 9px),   /* slats */
    linear-gradient(180deg, #F6F1E8, #E6DCCB);
}
.tbl[data-kind="outdoor"]::after { background: radial-gradient(circle at 40% 35%, #8A939F, #4E5663 70%); box-shadow: 0 3px 4px rgba(30, 36, 48, .45), 0 -22px 0 -8px #5F6874; }
.tbl[data-kind="outdoor"] .chair {
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, .35), transparent 55%), linear-gradient(180deg, #A9B2BD, #7C8794);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -2px 3px rgba(40,48,60,.35), 0 3px 4px rgba(40, 48, 60, .45);
}
.tbl[data-kind="outdoor"] .chair::before { background: linear-gradient(180deg, #8F99A5, #5F6874); }

/* --- the bar ------------------------------------------------------------ */
.floor-band[data-kind="bar"] {
  background:
    repeating-linear-gradient(90deg, rgba(0,0,0,.10) 0 1px, transparent 1px 9px),
    radial-gradient(120% 90% at 22% 0%, rgba(255, 220, 170, .18), transparent 60%),
    linear-gradient(180deg, #4E3828 0%, #3A2A1E 62%, #2C2016 100%);
  box-shadow: inset 0 8px 18px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 220, 170, .15);
}
.tbl[data-kind="bar"]::after { width: 22%; height: 12%; }
.tbl[data-kind="bar"]::before { left: 30%; top: 34%; width: 46%; height: 42%; }
.tbl[data-kind="bar"] .top {
  box-shadow:
    inset 0 2px 3px rgba(255,255,255,.9), inset 0 -3px 6px rgba(120,100,70,.18), inset 0 0 0 1px rgba(160,140,110,.25),
    0 6px 0 #D2C3A9, 0 7px 0 1px #B8A688, 0 10px 3px rgba(0, 0, 0, .35);
  transform: translateZ(40px);
}
.tbl[data-kind="bar"] .chair::before { display: none; }
.tbl[data-kind="bar"] .chair {
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, .22), transparent 55%), linear-gradient(180deg, #7A5A3A, #4E3823);
}

/* --- the dark room ------------------------------------------------------ */

/* On a phone the room is overhead and flat; the shadows and the pedestal keep the depth. */
@media (max-width: 640px) {
  .floor-plane, .floor-room:hover .floor-plane { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .floor-room:hover .floor-plane { transform: rotateX(30deg); }
  .tbl::before, .tbl .top { transition: none; }
}

/*
 * Taking a dish off a bill, from the table sheet.
 *
 * Green, because on this screen it is the one action that gives something away
 * rather than taking it: it must not be mistaken at a glance for the refund
 * and void controls it sits near. The form opens inside the list item so the
 * dish it belongs to is never in doubt on a busy screen.
 */
.o-comped { color: #0E7C4A; font-weight: 700; font-size: 12px; }
.comp-btn { color: #0E7C4A; font-weight: 700; }
.comp-undo { color: #7A849C; font-weight: 600; font-size: 12px; }
.comp-form { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0 2px; }
.comp-form select, .comp-form input { font: inherit; padding: 6px 8px; border: 1px solid var(--line, #E4E9F4); border-radius: 8px; background: #fff; color: inherit; min-width: 0; }
.comp-form input[type="number"] { width: 92px; }
.comp-form input[type="text"] { flex: 1 1 160px; }
.comp-form .btn { background: #0E7C4A; border-color: #0E7C4A; color: #fff; }

/* ==========================================================================
   THE NEW DESIGN (founder, 17-18 Sep: "restyle everything with the new
   design, look for what's outdated and change it with the new style").

   The panels were glass: a drifting cobalt mesh behind thin blurred panes,
   a specular rim on every card, a bloom where the light would land, a glow
   under the filled button. It was built to a playbook the founder set on 14
   September and it did what it said. The new design says the opposite thing
   — a white sheet, a hairline, a shadow you only notice if you look for it,
   pill controls, restrained type — and on an operator's screen that is not
   only a matter of taste: a blur is a compositing pass on every scroll of a
   ticket list, on a tablet that has been open since eleven in the morning.

   WHY THIS IS A LAYER AND NOT A DELETION

   Every glass rule above is driven by tokens, and the file already has two
   places that stand the lens down by resetting them — `prefers-reduced-
   transparency` and `body[data-solid]`, the kitchen screen. So the cheapest
   correct move is the third one: reset the tokens for everybody, and state
   the type, the radii and the flat surfaces here. Not one layout rule moves,
   which on a shift manager's screen mid-service is the whole point; the
   glass decorations that are left are inert (transparent gradients on
   pseudo-elements) and can be deleted in a quiet hour with nothing on the
   line.

   THE DARK ROOM STAYS. A panel is read at 23:40 as well as at 11:00, and
   the toggle is a feature the founder asked for, not decoration. It is the
   same flat design in the dark palette: surfaces instead of smoke.
   ========================================================================== */

:root {
  /* The type. Both names point at one family now: Instrument Sans carries
     the Latin, IBM Plex Sans Hebrew the Hebrew, and a mixed line — "₪1,190
     לסניף" — comes out as one voice. */
  --f:  var(--n-font);
  --fd: var(--n-font);

  /* Neutrals, from the new palette. `--muted` is the one that matters: it is
     the colour of every "3 מתוך 12" and every timestamp on the floor, so it
     is set at about 5:1 on white rather than at the 3.8:1 the old #78829E
     gave. */
  --line:      #E4E9F4;
  --line-2:    #F0F3FA;
  --bg:        #FFFFFF;
  --bg-alt:    #F7F9FE;
  --surface:   #FFFFFF;
  --hair:      #E4E9F4;
  --hair-2:    #F0F3FA;
  --ink:       #080D1C;
  --navy:      #080D1C;
  --body:      #4A5570;
  --muted:     #5F6A85;
  --ink-soft:  #4A5570;
  --ink-faint: #5F6A85;

  --r:    10px;
  --r-lg: 16px;
  --s1: 0 1px 2px rgba(8, 13, 28, .04);
  --s2: 0 8px 24px -16px rgba(8, 13, 28, .18);
  --s3: 0 24px 60px -30px rgba(8, 13, 28, .30);

  /* The lens stands down. The rules above stay one set; these say "flat". */
  --lg-bg:     #FFFFFF;
  --lg-bg-hi:  #FFFFFF;
  --lg-inner:  transparent;
  --lg-haze:   transparent;
  --lg-rim-a:  transparent;
  --lg-rim-b:  transparent;
  --lg-bloom:  transparent;
  --lg-depth:  transparent;
  --lg-edge:   #E4E9F4;
  --lg-shadow: 0 1px 2px rgba(8, 13, 28, .04);
  --lg-blur:   0px;
  --lg-sat:    1;
  --lg-tint:   var(--n-cobalt-wash);
  --lg-r:      16px;
  --lg-r-sm:   14px;
  --lg-r-in:   12px;
}

/* And the same, for the moment before theme.js stamps the attribute. */

/* The ground: one wash at the top and nothing moving. The mesh drifted for
   46 seconds at a time behind a screen somebody stares at all day. */
body { background: var(--bg-alt); }
body::before {
  background:
    radial-gradient(1200px 560px at 50% -190px, var(--n-cobalt-wash), transparent 72%),
    var(--bg-alt);
  background-size: auto;
  animation: none;
}

/* Type. 600 for the small headings a panel is full of, 500 for the one page
   title, and no negative tracking — the new faces are already tight. */
h1, h2, h3, h4 { font-family: var(--f); font-weight: 600; letter-spacing: 0; }
.head h1 { font-weight: 500; }
.tile .v { font-weight: 600; letter-spacing: 0; }
.tile .k { font-weight: 500; letter-spacing: .02em; }
.brand { font-family: "Readex Pro", var(--f); }

/* No lens, no blur, no compositing layers to keep warm. */
body > .top, body .tabs, body .rail, body .card, body .tile, body .modal, body .mystat,
body .attention a, body .btn, body .btn-quiet, body .picker button, body .planPick, body .search,
body .field input, body .field select, body .field textarea, body .modal .field input,
body .bellpop, body .ntoast, body .asst-panel, body .asst-card, body .order, body .call,
body .area-row input, body .area-row .area-kind, body .chips button, body .seg {
  -webkit-backdrop-filter: none; backdrop-filter: none; will-change: auto;
}
/* The bloom and the specular ring: the two decorations the new design has no
   use for. Hidden rather than unpicked from eleven selector lists. */
body .card::before, body .tile::before, body .modal::before, body .mystat::before,
body .attention a::before, body .btn::before, body .btn-quiet::before, body .picker button::before,
body .card::after, body .tile::after, body .modal::after, body .mystat::after,
body .bellpop::after, body .ntoast::after, body .asst-panel::after { display: none; }

/* The filled button keeps the cobalt and loses the glow. */
body .btn {
  border: 1px solid transparent; box-shadow: none;
  transition: background .15s var(--e), transform .12s var(--e);
}
body .btn:hover { box-shadow: none; transform: none; background: var(--btn-hover); }
body .btn:active { transform: translateY(1px); }
body .btn:disabled { transform: none; }
body .btn-quiet { border-color: var(--line); box-shadow: none; }
body .btn-quiet:hover, body .picker button:hover, body .attention a:hover { background: transparent; border-color: var(--n-cobalt-line); }

/* Capsules, and a 12px field. */
body .seg, body .seg button { border-radius: 999px; }
body .card, body .modal { border-radius: var(--lg-r); }
body .tile, body .mystat, body .attention a { border-radius: var(--lg-r-sm); }

/*
 * The hairline, said out loud.
 *
 * The glass layer set the border on cards, tiles and modals to transparent,
 * because their edge was drawn by a masked gradient ring on ::after. With the
 * ring gone, the border has to come back — otherwise every card on the panel
 * is a white rectangle on a near-white ground with nothing marking where it
 * ends, which is exactly the check that caught this.
 */
body .card, body .tile, body .modal, body .mystat, body .attention a,
body .bellpop, body .ntoast, body .asst-panel, body .asst-card, body .order, body .call {
  border: 1px solid var(--line);
}
body .card > header, body .modal header, body .modal .foot { border-color: var(--line-2); }

/* Controls at 500, like everything else in the new design. */
body .btn, body .btn-quiet, body .seg button, body .tabs a, body .tabs button, body .pill,
body .field label, body .tile .k { font-weight: 500; }
/* A field a thumb can hit, without the airiness of the public pages: a panel
   is dense on purpose, so 42 rather than the 48 the doors use. */
body .field input, body .field select, body .field textarea { min-height: 42px; padding: .55rem .75rem; }

/* A table head is a label, not a surface. */
th { background: var(--bg-alt); font-weight: 500; }
tbody tr:hover { background: var(--n-cobalt-wash); }

/* ==========================================================================
   THE FLOOR, FLAT.

   The room was built in the round on 14 September, and it worked: walnut
   boards, a tilted plane, tabletops with thickness and a cast shadow. Next
   to the new design it is the one screen that still looks like another
   product, and the depth was never what the map is read for. A shift manager
   glances at this for one thing — which tables are taken — and the number
   plus the name is what answers it.

   So: no perspective, no wood, no chairs, no cast shadows. What stays is
   every signal, in the same places:

     the number      large, and now at 600 instead of 900
     occupied        the same amber, as a tinted tile rather than a disc
     an open bill    the same cobalt ring, still layered ON TOP of occupancy
                     rather than competing with it
     the shape       a rounded square indoors, a dashed edge outside, a
                     circle at the bar — so the kind of seat is still legible
                     without a label and without a texture
     the zone        the band's name, which is what actually tells you which
                     part of the room you are looking at; the paving and the
                     dark counter run were decoration on top of that name.

   If the 3D room is wanted back, everything above this block still draws it:
   delete this one section.
   ========================================================================== */

.floor-room { perspective: none; padding: 1rem .7rem 1.2rem; }
.floor-plane, .floor-room:hover .floor-plane {
  transform: none; max-width: none; padding: .9rem;
  background: var(--bg-alt);
  border: 1px solid var(--line); border-radius: 14px;
  box-shadow: none;
}
.floor-band, .floor-band[data-kind="outdoor"], .floor-band[data-kind="bar"] {
  background: transparent; box-shadow: none;
  border: 1px dashed var(--line); border-radius: 12px;
  padding: .7rem .8rem 1rem;
  /*
   * A table is a table, not a billboard.
   *
   * The band's columns were `minmax(7.2rem, 1fr)`, so the tiles divided
   * whatever width was going: a zone with two tables drew them at 300px each,
   * and a bar area with one stool drew a single circle the width of the card.
   * Capped at 8.5rem and packed from the reading edge, a floor of four tables
   * and a floor of forty are drawn at the same scale — which is the only way
   * the plan is comparable between branches.
   */
  grid-template-columns: repeat(auto-fill, minmax(6.6rem, 8.5rem));
  justify-content: start;
  gap: .9rem;
}
.floor-band-name, .floor-band-name b { font-weight: 500; font-size: .78rem; color: var(--muted); transform: none; }
.floor-band-name b { color: var(--ink); font-weight: 600; }

.tbl, .tbl:hover, .tbl:focus-visible { transform: none; }
.tbl:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 3px; border-radius: 14px; }
.tbl .chair, .tbl .parasol, .tbl::before, .tbl::after { display: none; }

.tbl .top {
  inset: 0; gap: 2px; padding: .35rem;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: none;
  transform: none;
  color: var(--ink);
  font-family: var(--f);
}
.tbl[data-state="busy"] .top {
  background: var(--amber-bg); border-color: var(--amber-line); color: var(--amber-ink);
  /* Said again here on purpose: the 3D rule above gives an occupied top its
     own stack of shadows, and without this the flat amber tile kept a brown
     edge under it. */
  box-shadow: none;
}
/* The ring sits inside the edge, so it reads on the amber tile as well as on
   the pale one. */
.tbl[data-bill="1"] .top { box-shadow: inset 0 0 0 2px var(--cobalt); }

.tbl .no { font-weight: 600; font-size: clamp(1.1rem, 2.4vw, 1.4rem); letter-spacing: 0; }
.tbl .who  { font-weight: 500; font-size: .7rem; color: inherit; }
.tbl .mins { font-weight: 500; font-size: .66rem; color: inherit; opacity: .78; }
.tbl[data-state="busy"] .who, .tbl[data-state="busy"] .mins { color: inherit; }
/* At .66rem on the amber tile, the .78 fade took the minutes under 4.5:1 (axe, 2026-09-26). */
.tbl[data-state="busy"] .mins { opacity: 1; }

.tbl[data-kind="outdoor"] .top { border-radius: 14px; border-style: dashed; }
.tbl[data-kind="bar"] .top { inset: 12%; border-radius: 50%; box-shadow: none; transform: none; }
.tbl[data-kind="bar"][data-bill="1"] .top { box-shadow: inset 0 0 0 2px var(--cobalt); }

/* In the dark room the tile is a surface, and the amber is the dark-set amber
   the rest of the panel already uses. */

/* The dark room's own edges. The dark block above hands cards a transparent
   border and paints the ground from the mesh, and both of those outrank a
   plain `body .card` — so they are answered here in the same key. */

/* And the dark room's floor: the walnut boards and the pavement are keyed to
   the theme, so they outrank the flat plane above and had to be answered in
   the same key. Flat there too. */

/* A destructive control is a ghost with rose ink in both rooms; the dark set
   filled it solid red, which in the new design reads as the primary action on
   the screen. The one place solid red is right is the foot of a modal, where
   the whole dialog exists to confirm the destruction — so that one stays. */

/* The legend says what the tiles say, so it is cut from the same cloth: a
   rounded square in the tile's colours, not a wooden disc. */
.floor-legend { color: var(--muted); font-size: .8rem; }
.floor-legend i { width: 14px; height: 14px; border-radius: 4px; background: var(--surface); border: 1px solid var(--line); }
.floor-legend i.busy { background: var(--amber-bg); border-color: var(--amber-line); }
.floor-legend i.bill { background: var(--surface); border: 2px solid var(--cobalt); }

/* ==========================================================================
   The dark theme, on the September design.

   "Make it look similar to the website design" -- and the website has no dark
   mode, so what carries over is its language: a flat ground, flat surfaces, a
   hairline between them, one accent, nothing lit. The rules above built the
   older thing instead: a room lit by four cobalt gradients, cards whose border
   was replaced by a masked gradient ring, and 34px of blur under every sheet.

   This stands that down. The tokens above are already the right set, so most
   of it is naming the flat value; the rest undoes what was written as literals
   and therefore could not be reached by a token.

   The floor map's chairs and tables keep their gradients on purpose: those
   draw furniture rather than chrome.
   ========================================================================== */

/* The ground is one colour, the way --ground is one colour on the site. */

/* Cards get their real border back, and the ring that replaced it goes. */

/* Nothing diffuses through anything. */

/* The top bar sits on the page rather than floating over it. */

/* ==========================================================================
   A table the venue is keeping.

   Its own state, not a shade of "busy". A held table is unavailable like an
   occupied one, but what a host does about it is the opposite: an occupied
   table you leave alone, a held one you hand over the moment the booking
   arrives or fails to. Amber rather than the occupied colour, because the
   room should be readable from across it.
   ========================================================================== */

.tbl[data-state="held"] { border-color: #E8A317; }
.tbl[data-state="held"] .m { color: #A15C00; font-weight: 700; }
.tbl[data-state="held"]::after {
  content: "";
  position: absolute; inset-inline-end: 8px; top: 8px;
  width: 8px; height: 8px; border-radius: 50%;
  background: #E8A317;
}

/* Dish photos in the chain's menu table (chain.js photoCell). */
#menuTable td.ph { width: 7.5rem; }
.dish-thumb { width: 56px; height: 56px; object-fit: cover; border-radius: 10px; display: block; margin-bottom: .35rem; background: #EEF1F7; }
.ph-acts { display: flex; flex-wrap: wrap; gap: .3rem; }

/* Remote control (js/support-banner.js). */
.support-bar {
  position: sticky; top: 0; z-index: 60; display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  padding: .55rem 1rem; font-size: .9rem; line-height: 1.45; font-weight: 600;
}
.support-bar.is-owner { background: #FFE8A3; color: #3A2A00; border-bottom: 2px solid #C98A00; }
.support-bar.is-business { background: #E4ECFF; color: #0B1F5C; border-bottom: 1px solid #9DB3F2; }
.support-bar.is-request { background: #FFF4D6; color: #3A2A00; border-bottom: 1px solid #E0B84A; }
.support-bar button.primary { background: #0B3FD9; color: #fff; border-color: #0B3FD9; }
.support-bar span { flex: 1 1 18rem; }
.support-bar button {
  min-height: 40px; padding: 0 .9rem; border-radius: 999px; border: 1px solid currentColor;
  background: #fff; color: inherit; font: inherit; cursor: pointer;
}
.support-bar button:focus-visible { outline: 3px solid #0B3FD9; outline-offset: 2px; }
.support-log { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.support-log li { display: grid; gap: .15rem; padding: .6rem .7rem; border: 1px solid var(--hair, #E3E7F0); border-radius: 12px; }
.support-log .hint { overflow-wrap: anywhere; }

/* --------------------------------------------------------------------------
   Taking an order at the table (js/take-order.js, 2026-09-26). A phone in one
   hand: one column, big rows, the basket and the send button at the bottom.
   -------------------------------------------------------------------------- */
.take-scrim { z-index: calc(var(--z-modal) + 1); }
.modal.take { max-width: 36rem; height: min(52rem, 94dvh); display: flex; flex-direction: column; overflow: hidden; }
.take > header { flex: 0 0 auto; }
.take-top { flex: 0 0 auto; padding: .8rem 1rem .4rem; display: flex; flex-direction: column; gap: .55rem; border-bottom: 1px solid var(--line-2); }
.take-find { width: 100%; min-height: 46px; font: inherit; font-size: 1rem; padding: .5rem .8rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.take-cats { display: flex; gap: .4rem; overflow-x: auto; padding-bottom: .35rem; scrollbar-width: thin; }
.take-cats button { flex: 0 0 auto; min-height: 40px; padding: .3rem .85rem; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--navy); font-family: var(--fd); font-weight: 700; font-size: .9rem; }
.take-cats button[aria-pressed="true"] { background: var(--cobalt); border-color: var(--cobalt); color: #fff; }
.take-list { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: .4rem .6rem; }
.take-dish { border-bottom: 1px solid var(--line-2); }
.take-dish.open { background: var(--bg-alt); border-radius: 10px; }
.take-row { display: flex; align-items: center; gap: .6rem; width: 100%; min-height: 52px; padding: .45rem .5rem; text-align: start; background: none; border: 0; color: var(--ink); font: inherit; font-size: 1rem; }
.take-row .nm { flex: 1 1 auto; font-weight: 600; }
.take-row .pr { color: var(--body); font-variant-numeric: tabular-nums; }
.take-row .plus { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: var(--cobalt); color: #fff; font-weight: 800; font-size: 1.2rem; }
.take-row:disabled { cursor: default; }
.take-row:disabled .nm { color: var(--body); }
.take-tag { font-family: var(--fd); font-weight: 800; font-size: .75rem; padding: .05rem .45rem; border-radius: 99px; background: var(--amber-bg); color: var(--amber-ink); }
.take-tag.off { background: var(--rose-bg); color: var(--rose-ink); }
.take-opts { padding: .3rem .6rem .8rem; display: flex; flex-direction: column; gap: .6rem; }
.take-group { border: 0; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.take-group legend { font-family: var(--fd); font-weight: 800; font-size: .9rem; color: var(--navy); margin-bottom: .3rem; }
.take-choice { display: inline-flex; align-items: center; gap: .35rem; min-height: 44px; padding: .3rem .75rem; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); font-size: .95rem; cursor: pointer; }
.take-choice:has(input:checked) { border-color: var(--cobalt); background: var(--cobalt-50); }
.take-field { display: flex; flex-direction: column; gap: .3rem; font-size: .88rem; font-weight: 600; color: var(--body); }
.take-field input { min-height: 44px; font: inherit; font-size: 1rem; padding: .45rem .7rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.take-add { align-self: flex-start; min-height: 46px; }
.take-basket { flex: 0 1 auto; max-height: 42%; overflow-y: auto; overscroll-behavior: contain; padding: .7rem 1rem .4rem; border-top: 1px solid var(--line); background: var(--surface); display: flex; flex-direction: column; gap: .6rem; box-shadow: 0 -8px 20px -16px rgba(10,19,48,.35); }
.take-foot { flex: 0 0 auto; padding: .5rem 1rem 1rem; background: var(--surface); }
.take-lines:empty { display: none; }
.take-line { display: flex; align-items: center; gap: .6rem; padding: .25rem 0; }
.take-line .nm { flex: 1 1 auto; display: flex; flex-direction: column; line-height: 1.3; }
.take-line .nm small { color: var(--body); }
.take-line .qty { display: inline-flex; align-items: center; gap: .35rem; }
.take-line .qty button { width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--line); background: var(--surface); color: var(--navy); font-size: 1.2rem; font-weight: 800; }
.take-line .qty b { min-width: 1.4rem; text-align: center; font-variant-numeric: tabular-nums; }
.take-line .pr { min-width: 3.5rem; text-align: end; font-variant-numeric: tabular-nums; color: var(--body); }
.take-age { display: flex; align-items: center; gap: .5rem; min-height: 44px; padding: .4rem .6rem; border-radius: 10px; background: var(--amber-bg); color: var(--amber-ink); font-weight: 700; font-size: .92rem; }
.take-age[hidden] { display: none; }
.take-age input { width: 20px; height: 20px; }
.take-err { margin: 0; color: var(--rose-ink); background: var(--rose-bg); border-radius: 8px; padding: .45rem .7rem; font-size: .92rem; font-weight: 600; }
.take-err[hidden] { display: none; }
.take-send { min-height: 52px; font-size: 1.05rem; width: 100%; }
@media (max-width: 560px) {
  .take-scrim { padding: 0; align-items: end; }
  .modal.take { height: 96dvh; max-height: 96dvh; border-radius: 16px 16px 0 0; }
  /* The accessibility and assistant buttons float over every page on a phone; the send button sits above them. */
  .take-foot { padding-bottom: calc(.5rem + 76px + env(safe-area-inset-bottom)); }
}

/* --------------------------------------------------------------------------
   A waiter's account on the branch page (worker/waiters.ts, 2026-09-26): the
   floor, today's bookings and the waitlist; the manager's cards and buttons
   are not offered (the server refuses them regardless).
   -------------------------------------------------------------------------- */
.as-waiter .tabs, .as-waiter .head .side, .as-waiter #tiles, .as-waiter #kitchenLink, .as-waiter #backChain,
.as-waiter main section.card:not([data-waiter]), .as-waiter main > .wrap > .grid,
.as-waiter #addTable, .as-waiter #printAll, .as-waiter #addTableRow,
.as-waiter #tblPrint, .as-waiter #tblRotate, .as-waiter #tblEnd, .as-waiter .comp-btn { display: none !important; }
/* A waiter's first screen is the room: the floor map above the bookings and the waitlist. */
.as-waiter main > .wrap { display: flex; flex-direction: column; }
.as-waiter main > .wrap > .head { order: -2; }
.as-waiter main > .wrap > [data-waiter="floor"] { order: -1; margin-top: 0 !important; }

/* The branch's waiters card (js/waiters-settings.js). */
.waiters-what { margin: 0 0 .8rem; }
.waiters-list { display: flex; flex-direction: column; gap: .2rem; margin-bottom: 1rem; }
.waiter-row { display: flex; align-items: center; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid var(--line-2); flex-wrap: wrap; }
.waiter-row .nm { flex: 1 1 12rem; display: flex; flex-direction: column; line-height: 1.35; }
.waiter-row .nm small { color: var(--muted); }
.waiters-add { display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-end; }
.waiters-add label { display: flex; flex-direction: column; gap: .25rem; font-size: .85rem; font-weight: 600; color: var(--body); flex: 1 1 11rem; }
.waiters-add input { min-height: 42px; font: inherit; padding: .45rem .7rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.waiters-add .btn { min-height: 42px; }
.waiters-said { margin: .6rem 0 0; font-size: .9rem; color: var(--teal-ink); }
.waiters-said.bad { color: var(--rose-ink); }
.waiters-said:empty { display: none; }

/* Who took an order at the table (migration 077). */
.guest-order .o-by { font-size: .8rem; color: var(--ink-soft); margin-inline-start: .5rem; }

/* The customer on a waiter's order (js/take-order.js, worker/guests.ts). */
.take-guest { border: 1px solid var(--line); border-radius: 12px; padding: .55rem .75rem .7rem; margin: 0; display: flex; flex-direction: column; gap: .5rem; }
.take-guest legend { font-family: var(--fd); font-weight: 800; font-size: .88rem; color: var(--navy); padding: 0 .3rem; }
.take-guest-row { display: flex; gap: .5rem; flex-wrap: wrap; }
.take-guest-row .take-field { flex: 1 1 9rem; }
.take-guest-say { margin: 0; font-size: .82rem; color: var(--ink-soft); }
.take-known { display: flex; flex-direction: column; gap: .2rem; padding: .5rem .7rem; border-radius: 10px; background: var(--teal-bg); color: var(--teal-ink); font-size: .92rem; }
.take-known[hidden] { display: none; }
.take-known.new { background: var(--bg-alt); color: var(--body); }
.take-known .warn { color: var(--rose-ink); font-weight: 800; }
.take-known .note { color: var(--body); }
.take-remember { display: flex; align-items: center; gap: .5rem; min-height: 40px; font-size: .92rem; font-weight: 600; color: var(--body); }
.take-remember[hidden] { display: none; }
.take-remember input { width: 20px; height: 20px; }

/* The guest book card (js/guest-book.js). */
.gb-what { margin: 0 0 .7rem; }
.gb-find { width: 100%; max-width: 26rem; min-height: 42px; font: inherit; padding: .45rem .75rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); margin-bottom: .6rem; }
.gb-list { display: flex; flex-direction: column; }
.gb-row { border-bottom: 1px solid var(--line-2); }
.gb-row summary { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; padding: .6rem .2rem; cursor: pointer; list-style: none; min-height: 44px; }
.gb-row summary::-webkit-details-marker { display: none; }
.gb-row .nm { flex: 1 1 12rem; display: flex; flex-direction: column; line-height: 1.35; }
.gb-row .nm small { color: var(--muted); }
.gb-row .meta { font-size: .88rem; color: var(--body); }
.gb-allergy { font-size: .82rem; font-weight: 800; color: var(--rose-ink); background: var(--rose-bg); padding: .1rem .55rem; border-radius: 99px; }
.gb-edit { display: flex; flex-wrap: wrap; gap: .6rem; padding: .2rem .2rem .9rem; }
.gb-edit label { display: flex; flex-direction: column; gap: .25rem; flex: 1 1 13rem; font-size: .85rem; font-weight: 600; color: var(--body); }
.gb-edit input { min-height: 40px; font: inherit; padding: .4rem .65rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.gb-acts { display: flex; align-items: center; gap: .5rem; flex-basis: 100%; }
.gb-said { font-size: .88rem; color: var(--teal-ink); }

/* The guide from a panel's top bar (2026-10-03): a "?" beside the accessibility
   button, off on a phone, where the bar is already full (one more button there
   cost a whole second row). */
.guide-link { min-width: 40px; padding-inline: .7rem; font-weight: 800; text-align: center; }
@media (max-width: 599px) { .guide-link { display: none; } }

/* The branch's place on the concierge's card and its diners' ratings (js/branch-place.js). */
.banner.warn { background: #FFF6E0; color: #6B4A00; border: 1px solid #F1D48A; }
.place-ask { flex-direction: column; gap: .2rem; margin-bottom: .8rem; }
.place-ask span { font-weight: 500; }
.place-form > .btn { min-height: 48px; }
.rate-sum { margin: 0 0 .3rem; font-size: 1rem; }
.rate-sum b { font-size: 1.15rem; }
.rate-list { list-style: none; margin: .6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.rate-list li { border-top: 1px solid var(--hair, #D9E0EF); padding-top: .5rem; }
.rate-list p { margin: .25rem 0 0; }
.rate-stars-ro { color: #8A5A00; letter-spacing: .05em; }
.rate-stars-ro .off { color: #C3CDDF; }

/* "על המקום" and the menu-quality gate (js/venue-profile-form.js, js/menu-gate.js, 2026-10-14). Phone-first: 44px toggles. */
.vp-form { display: flex; flex-direction: column; gap: .8rem; }
.vp { display: flex; flex-direction: column; gap: .8rem; }
.vp .label { font-family: var(--fd); font-weight: 500; font-size: .82rem; color: var(--navy); }
.vp .chips button, .gate-allerg button { min-height: 44px; }
.vp-foot { display: flex; align-items: center; justify-content: flex-end; gap: .8rem; flex-wrap: wrap; }
.vp-foot .hint { margin: 0; flex: 1 1 12rem; }
.gate-list { list-style: none; margin: .8rem 0 0; padding: 0; display: flex; flex-direction: column; gap: .6rem; }
.gate-row { border: 1px solid var(--line); border-radius: var(--r); padding: .7rem .8rem; display: flex; flex-direction: column; gap: .5rem; }
.gate-miss { display: flex; flex-wrap: wrap; gap: .3rem; }
.gate-fix { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.gate-fix input, .gate-fix select { flex: 1 1 14rem; min-height: 44px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .7rem; font-size: .95rem; color: var(--ink); }
.gate-fix-allerg { flex-direction: column; align-items: stretch; }
.gate-fix-allerg .btn { align-self: flex-start; min-height: 44px; }
/* The venue study (js/venue-study.js): steps, the report's tiles, proposals and the house sheet. */
.study-status { display: flex; flex-direction: column; gap: .55rem; }
.study-steps { list-style: none; margin: .4rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; counter-reset: st; }
.study-steps li { counter-increment: st; font-family: var(--fd); font-weight: 700; font-size: .8rem; padding: .3rem .7rem; border-radius: 100px; background: var(--surface); border: 1px solid var(--line); color: var(--muted); }
.study-steps li::before { content: counter(st) ". "; }
.study-steps li.done { background: var(--teal-bg); border-color: var(--teal-line); color: var(--teal-ink); }
.study-steps li.now { background: var(--cobalt-50); border-color: var(--cobalt-300); color: var(--cobalt-700); }
.study-steps li.failed { background: var(--rose-bg); border-color: var(--rose-line); color: var(--rose-ink); }
.study-status progress { width: 100%; height: .6rem; accent-color: var(--cobalt); }
.study-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.study-actions .btn, .study-actions .btn-quiet, .study-actions select { min-height: 44px; }
.study-report, .study-sugg, .study-house { margin-top: 1rem; display: flex; flex-direction: column; gap: .6rem; }
.study-report h3, .study-sugg h3, .study-house h3 { margin: .4rem 0 0; font-size: 1rem; color: var(--navy); }
.study-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .6rem; }
.study-tile { border: 1px solid var(--line); border-radius: var(--r); padding: .7rem .8rem; display: flex; flex-direction: column; gap: .2rem; }
.study-tile b { font-family: var(--fd); font-size: 1.5rem; color: var(--navy); }
.study-tile span { font-size: .82rem; color: var(--muted); }
.study-dishes { margin: 0; padding-inline-start: 1.1rem; }
.study-fails summary { cursor: pointer; font-weight: 700; color: var(--navy); min-height: 44px; display: flex; align-items: center; }
.study-fail { border-top: 1px solid var(--line); padding: .5rem 0; }
.study-fail p { margin: .2rem 0; }
.study-guest { color: var(--muted); }
.study-reply { color: var(--ink); }
.study-row { flex-direction: column; align-items: stretch; }
.study-row p { margin: 0; }
.study-row textarea { min-height: 44px; border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .7rem; font: inherit; }
.study-house .field input, .study-house select { min-height: 44px; border: 1px solid var(--line); border-radius: var(--r); padding: .5rem .7rem; background: var(--surface); }
.study-house .chips button { min-height: 44px; }
.study-pairs, .study-faq { display: flex; flex-direction: column; gap: .4rem; }
.study-faq-row { display: grid; grid-template-columns: 1fr 1.4fr auto; gap: .4rem; }
@media (max-width: 600px) { .study-faq-row { grid-template-columns: 1fr; } }
/* Ready for the first evening (js/go-live.js). */
.golive-list { list-style: none; margin: .6rem 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.golive-row { border: 1px solid var(--line); border-radius: var(--r); padding: .6rem .8rem; display: grid; grid-template-columns: auto 1fr; gap: .3rem .7rem; align-items: start; }
.golive-row.done { background: var(--teal-bg); border-color: var(--teal-line); }
.golive-row .study-actions, .golive-row [role="status"] { grid-column: 1 / -1; }
.golive-text { display: flex; flex-direction: column; gap: .15rem; }
#goLiveCard .banner { justify-content: space-between; flex-wrap: wrap; }
#goLiveCard .banner p { margin: .2rem 0 0; font-weight: 500; }
.vp .two { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: .8rem; }

/* Managers open on service work; configuration and reporting have their own routes. */
body[data-branch-page] [data-branch-page] { display: none; }
body[data-branch-page="settings"] [data-branch-page="settings"],
body[data-branch-page="reports"] [data-branch-page="reports"] { display: revert; }
body[data-branch-page="reports"] .grid[data-branch-page="reports"] { display: grid; }
body[data-branch-page="reports"] .tiles[data-branch-page="reports"] { display: grid; }
body[data-branch-page="settings"] main .wrap > .card:not([data-branch-page]),
body[data-branch-page="reports"] main .wrap > .card:not([data-branch-page]) { display: none; }
body.as-waiter #tabSettings, body.as-waiter .tabs a[href="#reports"] { display: none; }
.house-preview { max-width: 70ch; line-height: 1.7; }
.house-preview p { margin: .4rem 0; }
.house-edit { margin: 1rem 0; }
.house-edit summary { cursor: pointer; color: var(--blue); padding: .6rem 0; }

/* Compact preparation: explicit disclosure rows, with native closed-details behavior. */
details.study-house { display: block; }
.study-progress > details > summary, details.study-house > summary { cursor: pointer; min-height: 44px; padding-block: .7rem; font-weight: 600; }

.study-dish-review { width: 100%; }
.study-dish-review > summary { cursor: pointer; font-weight: 600; min-height: 44px; padding-block: .6rem; }

/* Settings grouped by what the owner is doing (2026-10-17): a row of jumps, then one group per job, the rarely
   touched folded. Shared by the branch and chain panels. */
.set-nav { display: flex; flex-wrap: wrap; gap: .45rem; margin: .4rem 0 1.1rem; }
body[data-branch-page="settings"] .set-nav { display: flex; }
.set-nav a { display: inline-flex; align-items: center; min-height: 44px; padding: .45rem .95rem; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink); font-weight: 600; font-size: .92rem; text-decoration: none; }
.set-nav a:hover, .set-nav a:focus-visible { border-color: var(--cobalt); color: var(--cobalt-700); }
.set-group { margin: 0 0 1.6rem; scroll-margin-top: 1rem; }
.set-group-h { font-size: 1.2rem; margin: 0 0 .25rem; }
.set-why { margin: 0 0 .7rem; color: var(--body); font-size: .93rem; line-height: 1.55; max-width: 70ch; }
.set-group > .card, .set-group > details.card { margin-top: .7rem; }
.set-group > .set-group-h + .card, .set-group > .set-group-h + details.card { margin-top: .5rem; }
.set-link { margin: .6rem .2rem 0; font-size: .92rem; }
.card > header h3 { font-size: 1.02rem; margin: 0; }
.settings-fold > summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: .2rem .8rem; min-height: 44px; padding: .9rem 1.2rem; cursor: pointer; }
.settings-fold > summary .fold-t { font-weight: 700; color: var(--ink); }
.settings-fold > summary .fold-h { font-size: .84rem; color: var(--muted); }
.settings-fold[open] > summary { border-bottom: 1px solid var(--line-2); }
.settings-fold .digest-prefs { margin-top: 0; padding-top: 0; border-top: 0; }
.settings-fold .digest-prefs h3 { display: none; }
.settings-fold > summary .fold-h.fold-due { color: var(--amber-ink); font-weight: 700; }
.golive-pick { margin: 0 0 .7rem; }
.golive-pick button { min-height: 44px; }
.screens-card .hint a { text-decoration: underline; }
.set-group .hint a, .set-why a, .set-link a { text-decoration: underline; }
#defaultsCard .pad > p { margin: 0 0 .45rem; }
#defaultsCard .pad > p:has(> .btn-quiet) { margin-bottom: 1.1rem; }
#suggestCard .chk { display: flex; align-items: center; gap: .6rem; min-height: 44px; font-weight: 600; }
#suggestCard .chk input { width: 20px; height: 20px; accent-color: var(--cobalt); }

/* Qubi's chat (2026-10-18) sits above the glass pass: a white panel, a borderless text box inside the rounded
   composer, soft attach and chip grounds. Later and more specific than the glass rules above, so no !important. */
body .asst-panel { background: #fff; border: 1px solid #E8ECF4; -webkit-backdrop-filter: none; backdrop-filter: none; }
body .asst-card { background: #fff; border: 1px solid #C9D6FB; -webkit-backdrop-filter: none; backdrop-filter: none; }
body .asst-chip { background: #fff; border: 1px solid #DCE3F2; -webkit-backdrop-filter: none; backdrop-filter: none; }
body .asst-compose textarea { background: transparent; border: 0; box-shadow: none; scrollbar-width: none; font-family: inherit; letter-spacing: normal; -webkit-backdrop-filter: none; backdrop-filter: none; }
body .asst-attach { background: #F3F6FC; border: 0; -webkit-backdrop-filter: none; backdrop-filter: none; }
