/* Preia POS terminal, phone and tablet only.

   Built for a night-market counter: a cashier who may be older, a phone that
   may be small, light that may be bad. Text starts at 18px, every control is
   at least 56px tall, the next step is one big button at the bottom, and
   the order in hand is always at the top. Same colour tokens as the
   workspace; one stylesheet, no framework, no remote resources. */

:root {
  color-scheme: light;
  --ground: #f6f6f4;
  --surface: #ffffff;
  --surface-sunken: #f0f0ed;
  --line: #d9d8d2;
  --line-strong: #b4b3ab;
  --ink: #1d1d1b;
  --ink-soft: #4f4f4a;
  --ink-faint: #76756d;
  --accent: #1f4f7a;
  --accent-ink: #ffffff;
  --accent-soft: #e7eef5;
  --pending: #8a5a00;
  --pending-soft: #fbf0dc;
  --danger: #9a2a20;
  --danger-soft: #fbe9e7;
  --good: #1f6135;
  --good-soft: #e6f1e9;
  --lit: #c98a00;
  --lit-soft: #fff3d6;
  --radius: 10px;
  --touch: 56px;
  --gap: 0.75rem;
  /* Depth, not lines: sections are told apart by tone and the shadow each
     surface casts. Three heights: a resting card, a floating control, and
     the round buttons that float above everything. */
  --lift: 0 1px 2px rgba(0, 0, 0, 0.05), 0 4px 14px rgba(0, 0, 0, 0.07);
  --lift-2: 0 2px 4px rgba(0, 0, 0, 0.08), 0 10px 24px rgba(0, 0, 0, 0.12);
  --lift-3: 0 4px 8px rgba(0, 0, 0, 0.12), 0 18px 40px rgba(0, 0, 0, 0.18);
  --lift-up: 0 -1px 3px rgba(0, 0, 0, 0.05);
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --ground: #17181a;
    --surface: #1f2123;
    --surface-sunken: #191b1d;
    --line: #34373a;
    --line-strong: #555a5f;
    --ink: #ececea;
    --ink-soft: #bfc1c0;
    --ink-faint: #949796;
    --accent: #7fb3de;
    --accent-ink: #10222f;
    --accent-soft: #23323f;
    --pending: #e0b25a;
    --pending-soft: #3a2f16;
    --danger: #e08a82;
    --danger-soft: #3d1f1c;
    --good: #7cc48f;
    --good-soft: #1d3324;
    --lit: #f0b433;
    --lit-soft: #3d2f10;
    --lift: 0 1px 2px rgba(0, 0, 0, 0.4), 0 4px 14px rgba(0, 0, 0, 0.45);
    --lift-2: 0 2px 4px rgba(0, 0, 0, 0.5), 0 10px 24px rgba(0, 0, 0, 0.55);
    --lift-3: 0 4px 8px rgba(0, 0, 0, 0.55), 0 18px 40px rgba(0, 0, 0, 0.6);
    --lift-up: 0 -1px 3px rgba(0, 0, 0, 0.4);
  }
}

* { box-sizing: border-box; }
/* Double-tap must never zoom: a cashier taps plus fast. Pinch still works. */
html, body { height: 100%; touch-action: manipulation; }
button, .line, .item, .nav-btn, .stepper, .keys, .numgrid { touch-action: manipulation; -webkit-user-select: none; user-select: none; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 18px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}
@media (min-width: 600px) { body { font-size: 19px; } }
@media (min-width: 900px) { body { font-size: 20px; } }
html[lang^="zh"] body { font-family: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif; line-height: 1.55; }
html[lang^="ja"] body { font-family: "Noto Sans JP", "Hiragino Sans", "Yu Gothic", "Meiryo", system-ui, sans-serif; line-height: 1.55; }
[hidden] { display: none !important; }
button { font: inherit; cursor: pointer; color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 700; line-height: 1.25; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.125rem; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.small { font-size: 0.875rem; }
.spacer { flex: 1 1 auto; }
.grow { flex: 1 1 auto; }
.contract { color: var(--ink-faint); font-size: 0.875rem; }
.error { color: var(--danger); font-size: 0.9375rem; margin: 0.5rem 0 0; min-height: 1.2em; }
.plain { list-style: none; padding: 0; margin: 0; }

/* ---- controls ---- */
button.primary, button.secondary, button.destructive {
  min-height: var(--touch); padding: 0.5rem 1.125rem; border-radius: var(--radius);
  border: 2px solid var(--line-strong); background: var(--surface); color: var(--ink); font-weight: 700; font-size: 1.0625rem;
}
button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
button.destructive { color: var(--danger); border-color: var(--danger); }
button.small { min-height: 44px; padding: 0.25rem 0.875rem; font-size: 0.9375rem; font-weight: 600; }
button.big { min-height: 64px; font-size: 1.25rem; }
button.wide { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 0.125rem; }
button.wide .small { font-weight: 400; }
button:disabled { opacity: 0.45; cursor: not-allowed; }
input[type="text"], input[type="password"], input[type="number"], input[type="search"], select {
  width: 100%; min-height: var(--touch); padding: 0.5rem 0.875rem; border: 2px solid var(--line-strong);
  border-radius: var(--radius); background: var(--surface); color: var(--ink); font: inherit; font-size: 1.125rem;
}
.pick { width: auto; }
.langpick { width: auto; }
.field { margin-bottom: 0.875rem; }
.field label { display: block; font-weight: 700; margin-bottom: 0.25rem; }
.field .hint { display: block; color: var(--ink-faint); font-size: 0.875rem; margin-top: 0.25rem; }
.chip { display: inline-block; padding: 0.125rem 0.75rem; border: 1.5px solid var(--line-strong); border-radius: 999px; font-size: 0.9375rem; font-weight: 600; white-space: nowrap; line-height: 1.6; }
.chip.pending { color: var(--pending); border-color: var(--pending); background: var(--pending-soft); }
.chip.good { color: var(--good); border-color: var(--good); background: var(--good-soft); }
.chip.bad { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }
.chip.voice-off { color: var(--ink-faint); }
.toggle { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--ink-soft); }
.toggle input { width: 1.5rem; height: 1.5rem; }
.switch { width: 2rem; height: 2rem; accent-color: var(--accent); }
.rowgap { display: flex; flex-wrap: wrap; gap: 0.625rem; align-items: flex-end; }
.rowgap .field { margin: 0; flex: 1 1 10rem; }
.rowgap input, .rowgap select { width: auto; flex: 1 1 10rem; }

/* ---- sign-in ---- */
.centered { min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 1.25rem; gap: 1rem; }
.card { width: 100%; max-width: 26rem; background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); padding: 1.5rem; }
.card h1 { font-size: 1.75rem; margin-bottom: 0.125rem; }
.card .muted { margin: 0 0 1.25rem; }
.card button.primary { width: 100%; }

/* ---- frame: header, one view, footer ---- */
.terminal { height: 100%; display: flex; flex-direction: column; position: relative; }
.top { flex: 0 0 auto; background: none; position: relative; z-index: 2; padding-top: env(safe-area-inset-top); }
.nav { display: flex; justify-content: space-evenly; align-items: center; padding: 0.75rem 0.5rem 0.25rem; }
.nav-btn {
  position: relative; width: 64px; height: 64px; border-radius: 50%; padding: 0;
  border: 0; background: var(--surface); color: var(--ink-soft); box-shadow: var(--lift-2);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.nav-btn .ico { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.nav-btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.nav-btn:active { transform: translateY(2px); box-shadow: var(--lift); }
.badge { position: absolute; top: -4px; right: -6px; background: var(--danger); color: #fff; border: 2px solid var(--surface); border-radius: 999px; padding: 0 0.4rem; font-size: 0.875rem; font-weight: 800; min-width: 1.6rem; height: 1.6rem; line-height: 1.35rem; text-align: center; }
.nav-btn[aria-pressed="true"] .badge { background: var(--danger); }
.netbar { display: flex; align-items: center; gap: 0.75rem; padding: 0.375rem 0.75rem; background: var(--pending-soft); flex-wrap: wrap; }
.netbar .chip.bad { background: var(--danger-soft); }

.view { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: 9.5rem; }
.view.list { padding: var(--gap); display: flex; flex-direction: column; gap: var(--gap); }

/* ---- the order screen ---- */
.view.order { display: flex; flex-direction: column; gap: var(--gap); padding: var(--gap); padding-bottom: 9.5rem; }

/* 1. the order in hand */
.info { background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); padding: 0.75rem; display: flex; flex-direction: column; gap: 0.625rem; }
.info-row { display: flex; align-items: center; gap: 0.625rem; flex-wrap: wrap; }
.info-row.head { flex-wrap: nowrap; }
.call { display: inline-flex; align-items: baseline; margin: 0; }
.call-part { border: 0; background: none; padding: 0 0.125rem; font-size: 2.25rem; font-weight: 800; line-height: 1.15; letter-spacing: -0.01em; color: var(--ink); min-height: var(--touch); border-radius: var(--radius); }
.call-part.num { font-variant-numeric: tabular-nums; margin-left: 0.25rem; }
.call-part:active { background: var(--surface-sunken); }
.call-part:disabled { opacity: 1; cursor: default; }
.icon-btn .ico { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pick-grid { display: grid; grid-template-columns: 1fr; gap: 0.625rem; }
.pick-grid button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.numgrid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 0.5rem; }
.numgrid button { min-height: var(--touch); border: 2px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; padding: 0; }
.numgrid button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.numgrid button:disabled { opacity: 0.3; }
.states { display: inline-flex; gap: 0.375rem; flex-wrap: wrap; }
.icon-btn { min-width: var(--touch); min-height: var(--touch); border: 2px solid var(--line-strong); background: var(--surface); border-radius: var(--radius); font-size: 1.5rem; font-weight: 700; line-height: 1; }
.seg { display: inline-flex; border: 2px solid var(--line-strong); border-radius: var(--radius); overflow: hidden; flex: 1 1 auto; }
.seg-btn { flex: 1 1 0; min-height: var(--touch); border: 0; background: var(--surface); font-weight: 700; font-size: 1.0625rem; padding: 0.25rem 0.5rem; }
.seg-btn + .seg-btn { border-left: 2px solid var(--line-strong); }
.seg-btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }
.info .table-input { width: 7rem; flex: 0 0 7rem; text-align: center; font-weight: 700; }
.info .seg { flex: 1 1 14rem; }
.voice { gap: 0.5rem; }
.ask { display: inline-flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
.ask-prompt { font-weight: 700; flex: 1 1 100%; }
.rec { display: inline-flex; align-items: center; gap: 0.375rem; color: var(--danger); font-weight: 700; font-size: 0.9375rem; }
.rec .dot { width: 0.75rem; height: 0.75rem; border-radius: 50%; background: var(--danger); animation: blink 1.2s infinite; }
@keyframes blink { 50% { opacity: 0.25; } }
.heard { font-size: 1rem; color: var(--ink-soft); min-height: 1.4em; }
.heard .speaker { font-weight: 700; color: var(--ink); margin-right: 0.375rem; }
.heard .outcome { margin-left: 0.5rem; font-weight: 700; }
.heard .outcome.accepted { color: var(--good); }
.heard .outcome.corrected { color: var(--pending); }
.heard .outcome.miss { color: var(--danger); }

/* 2. the lines */
.lines-wrap { background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); display: flex; flex-direction: column; }
.lines { display: flex; flex-direction: column; }
.line { position: relative; overflow: hidden; touch-action: pan-y; }
.line.fresh { animation: float-in 520ms cubic-bezier(0.2, 0.8, 0.2, 1) both; }
@keyframes float-in { from { opacity: 0; transform: translateY(22px) scale(0.98); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .line.fresh { animation: none; } }
.line:first-child { border-radius: var(--radius) var(--radius) 0 0; }
.line .lcontent { position: relative; z-index: 1; display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem 0.75rem; background: var(--surface); transition: transform 160ms ease-out; cursor: pointer; }
.line .lcontent.dragging { transition: none; }
.line .lcontent:active { background: var(--surface-sunken); }
.line .swipe-delete { position: absolute; top: 0; right: 0; bottom: 0; width: 96px; border: 0; background: var(--danger); color: #fff; font-size: 1.125rem; font-weight: 800; opacity: 0; }
/* Hidden until a swipe reveals it, so no red shows under a rounded corner. */
.line.open .swipe-delete, .line:has(.lcontent.dragging) .swipe-delete { opacity: 1; }
.line .ltop, .line .lbottom { display: flex; align-items: center; gap: 0.75rem; }
.line .ltop { cursor: pointer; }
.line .lname { flex: 1 1 auto; font-size: 1.25rem; font-weight: 700; min-width: 0; }
.line .ltotal { font-size: 1.125rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.line .ldesc { flex: 1 1 auto; min-width: 0; color: var(--ink-soft); font-size: 1rem; min-height: 1.4em; cursor: pointer; }
/* Every option on a row is a chip of one geometry (border, padding,
   margin). A chosen option is filled; one not yet made is an empty slot,
   dashed and named after its group, a required one a shade darker. */
.line .ldesc { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3em 0.35em; }
.line .opt { display: inline-block; padding: 0 0.5em; border: 1px solid transparent; border-radius: 6px; background: var(--surface-sunken); color: var(--ink-soft); font-size: 0.9375rem; font-weight: 600; line-height: 1.5; }
.line .opt.open { background: none; border-style: dashed; border-color: var(--line-strong); color: var(--ink-faint); font-weight: 500; }
.line .opt.open.req { border-color: var(--ink-faint); color: var(--ink-soft); font-weight: 600; }
/* An option the stall assumed (the usual, nothing said): named, but dashed like an open slot. */
.line .opt.assumed { background: var(--surface); border-style: dashed; border-color: var(--line-strong); color: var(--ink-soft); }
/* One group's options, right under the row, after a tap on its chip. */
.group-pick { display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0.5rem 0 0.25rem; }
.pick-opt { min-height: 44px; padding: 0 0.875rem; border: 2px solid var(--line-strong); border-radius: 999px; background: var(--surface); color: var(--ink); font-size: 1rem; font-weight: 600; }
.pick-opt.on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
/* 聽錯 on the newest heard line. */
.line .wrong { margin-left: 0.5rem; min-height: 32px; padding: 0 0.6rem; border: 1.5px solid var(--line-strong); border-radius: 999px; background: var(--surface); color: var(--ink-soft); font-size: 0.875rem; font-weight: 600; }
.wrong-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; }
/* the readback, turned to the customer */
.sheet-back.readback { align-items: center; background: var(--surface); cursor: pointer; }
.readback-card { width: 100%; max-width: 40rem; padding: 1.25rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom)); font-size: 1.75rem; display: flex; flex-direction: column; gap: 1rem; }
.rb-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin: 0; font-size: 1.5rem; }
.rb-head .faint { font-size: 1rem; }
.rb-lines { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.875rem; }
.rb-lines li { display: grid; grid-template-columns: auto 1fr; gap: 0.125rem 0.75rem; align-items: baseline; }
.rb-qty, .rb-name { font-weight: 800; }
.rb-opts { grid-column: 2; font-size: 1.25rem; color: var(--ink-soft); }
.rb-total { margin: 0; text-align: right; font-size: 1.5rem; }
.rb-total strong { font-size: 2.5rem; }
/* the totals row is the readback's handle */
.totals[role="button"] { cursor: pointer; }
.totals[role="button"]:active { opacity: 0.7; }
/* a recalled order, or its number, lit for a moment */
@keyframes recalled { 0% { box-shadow: 0 0 0 0 rgba(31, 79, 122, 0.55); } 100% { box-shadow: 0 0 0 14px rgba(31, 79, 122, 0); } }
.recalled { animation: recalled 0.8s ease-out 3; }
/* a card swiped right takes its first action */
.order-card { touch-action: pan-y; transition: transform 0.15s ease, box-shadow 0.15s ease; }
.order-card.swiping { transition: none; }
.order-card.armed { box-shadow: var(--lift-2); outline: 3px solid var(--good); }
.order-card.mine { outline: 2px solid var(--accent); }
.chip.accent { background: var(--accent-soft); color: var(--accent); }
.line .lnote { color: var(--ink-soft); font-size: 0.9375rem; }
/* an option the system just set flashes blue, then settles */
.line .opt.flash { animation: chip-flash 1.4s ease-out both; }
@keyframes chip-flash { 0% { background: var(--accent); color: var(--accent-ink); } 35% { background: var(--accent); color: var(--accent-ink); } 100% { background: var(--surface-sunken); color: var(--ink-soft); } }
@media (prefers-reduced-motion: reduce) { .line .opt.flash { animation: none; } }
.line.incomplete .ltotal { opacity: 0.65; }
.transcript .note.tools { color: var(--ink-faint); }
.stepper { display: inline-flex; align-items: center; gap: 0.25rem; flex: 0 0 auto; }
.stepper .step { width: 48px; height: 48px; border-radius: 50%; border: 2px solid var(--line-strong); background: var(--surface); font-size: 1.5rem; font-weight: 700; line-height: 1; display: inline-flex; align-items: center; justify-content: center; padding: 0; color: var(--ink); }
.line.readonly .swipe-delete { display: none; }
.line.pending .ltotal, .line.pending .lname { opacity: 0.65; }
.stepper .step:disabled { opacity: 0.3; }
.stepper .n { min-width: 3rem; min-height: 48px; border: 0; background: var(--surface-sunken); border-radius: var(--radius); text-align: center; font-size: 1.375rem; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink); padding: 0 0.25rem; }
.stepper .n:disabled { background: none; opacity: 1; }
.qty-n { min-width: 3.5rem; min-height: var(--touch); border: 0; background: var(--surface-sunken); border-radius: var(--radius); font-size: 1.75rem; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink); }
.sheet.keypad .qty-display { font-size: 2.5rem; font-weight: 800; font-variant-numeric: tabular-nums; min-width: 3.5rem; text-align: right; }
.keys { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; }
.keys button { min-height: 68px; border: 2px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); font-size: 1.625rem; font-weight: 700; color: var(--ink); }
.keys button.ok { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-size: 1.25rem; }
.keys button.ok:disabled { opacity: 0.45; }
.line.readonly .stepper { display: none; }
.line.readonly .ldesc::after { content: ""; }
.empty { padding: 1.25rem 0.75rem; text-align: center; color: var(--ink-faint); font-size: 1.0625rem; }
.totals { display: flex; align-items: baseline; gap: 0.75rem; padding: 0.625rem 0.75rem; color: var(--ink-soft); font-size: 1rem; background: var(--surface-sunken); border-radius: 0 0 var(--radius) var(--radius); }
.totals .subtotal strong { font-size: 1.5rem; color: var(--ink); margin-left: 0.25rem; font-variant-numeric: tabular-nums; }

/* the menu sheet */
.sheet.menu { max-height: 92%; }
.picker { display: flex; flex-direction: column; gap: 0.625rem; }
.tabs { display: flex; gap: 0.5rem; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.tabs::-webkit-scrollbar { display: none; }
.tabs button { flex: 0 0 auto; min-height: var(--touch); padding: 0.25rem 1.25rem; border-radius: var(--radius); border: 2px solid var(--line-strong); background: var(--surface); font-weight: 700; font-size: 1.0625rem; white-space: nowrap; }
.tabs button[aria-selected="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.items { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.625rem; }
.item { position: relative; min-height: 96px; border: 2px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); padding: 0.75rem; display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start; text-align: left; gap: 0.25rem; }
.item:active { background: var(--accent-soft); }
.item .name { font-size: 1.25rem; font-weight: 800; line-height: 1.25; }
.item .price { font-size: 1.0625rem; color: var(--ink-soft); font-weight: 600; }
.item.soldout { opacity: 0.45; }
.item.soldout .price { color: var(--danger); }
.item .count { position: absolute; top: 0.5rem; right: 0.5rem; background: var(--accent); color: var(--accent-ink); border-radius: 999px; min-width: 1.75rem; height: 1.75rem; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 0.9375rem; padding: 0 0.4rem; }

/* the floating cluster, bottom right: the next step as a round button with
   its label beside it, a second round button when the kitchen step also
   applies, and ＋ 加點. Nothing here is a bar; the list scrolls beneath. */
.next { position: absolute; left: var(--gap); right: var(--gap); bottom: calc(var(--gap) + env(safe-area-inset-bottom)); z-index: 5; pointer-events: none; display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem; }
.next > * { pointer-events: auto; }
.next-row { display: flex; align-items: center; gap: 0.75rem; }
.fab-group { display: inline-flex; align-items: center; gap: 0.5rem; }
button.fab { width: 72px; height: 72px; min-height: 0; border-radius: 50%; border: 0; padding: 0; display: inline-flex; align-items: center; justify-content: center; background: var(--surface); color: var(--ink); box-shadow: var(--lift-3); transition: transform 120ms ease, box-shadow 120ms ease; }
button.fab .ico { width: 32px; height: 32px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
button.fab.primary { background: var(--accent); color: var(--accent-ink); }
button.fab.second { width: 56px; height: 56px; }
button.fab.second .ico { width: 26px; height: 26px; }
button.fab.add { width: 64px; height: 64px; color: var(--accent); }
button.fab.park { width: 56px; height: 56px; color: var(--ink-soft); }
button.fab.park .ico { width: 24px; height: 24px; stroke-width: 2.6; }
/* the kitchen boundary, one chip on the order head */
.chip.kitchen { margin-left: 0.5rem; }
.cards .group-title { grid-column: 1 / -1; margin: 0.25rem 0 0; font-size: 1rem; color: var(--ink-soft); }
button.fab:disabled { background: var(--surface-sunken); color: var(--ink-faint); box-shadow: var(--lift); opacity: 1; }
button.fab:active { transform: translateY(2px); box-shadow: var(--lift); }
.fab-label { background: var(--surface); box-shadow: var(--lift-2); border-radius: 999px; padding: 0.45rem 0.9rem; font-size: 1.0625rem; font-weight: 800; color: var(--ink); white-space: nowrap; cursor: pointer; }
.fab-label.primary-label { font-size: 1.25rem; }
.fab-label.off { color: var(--ink-faint); box-shadow: var(--lift); }
.fab-label:empty { display: none; }
/* one tap pays: the cash choices unfold beside the cluster; the exact amount
   is the filled one, 其他金額 keeps the tender for odd sums */
.cash-row { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem; max-width: 100%; animation: float-in 260ms ease-out both; }
.cash-row button { min-height: 56px; padding: 0 1.1rem; border-radius: 999px; border: 2px solid var(--accent); background: var(--surface); color: var(--accent); font-size: 1.125rem; font-weight: 800; box-shadow: var(--lift-2); white-space: nowrap; }
.cash-row button.exact { background: var(--accent); color: var(--accent-ink); }
.cash-row button.quiet { border-color: var(--line-strong); color: var(--ink-soft); font-weight: 700; }
.cash-row button:active { transform: translateY(2px); box-shadow: var(--lift); }
/* a line added out of view: a pill that brings it into view */
.new-pill { border: 0; border-radius: 999px; background: var(--accent); color: var(--accent-ink); box-shadow: var(--lift-2); padding: 0.45rem 1rem; font-size: 1rem; font-weight: 700; animation: float-in 360ms ease-out both; }

/* tablet: the menu on the left, the order on the right, the next step under the order */
.picker-slot { display: none; }
@media (min-width: 744px) {
  .view.order { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); grid-template-areas: "picker info" "picker lines"; overflow: hidden; }
  .picker-slot { display: block; grid-area: picker; min-height: 0; overflow-y: auto; }
  .picker-slot .picker { min-height: 100%; }
  .info { grid-area: info; }
  .lines-wrap { grid-area: lines; min-height: 0; overflow-y: auto; }
  .add-item { display: none; }
}

/* ---- lists: in progress, history, incoming, more ---- */
.list-head { display: flex; align-items: center; gap: 0.75rem; }
.list-head h2 { flex: 1 1 auto; }
.list-head .back { flex: 0 0 auto; }
.list-tools { display: flex; gap: 0.625rem; }
.list-tools .search { flex: 1 1 auto; }
.cards { display: grid; gap: var(--gap); grid-template-columns: 1fr; }
@media (min-width: 720px) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.order-card { background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); padding: 0.875rem; display: flex; flex-direction: column; gap: 0.5rem; }
.card-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.card-head strong { font-size: 1.5rem; font-weight: 800; }
.card-lines { font-size: 1.0625rem; }
.card-total { font-size: 1.25rem; font-weight: 800; }
.actions { display: flex; gap: 0.625rem; }
.actions.wrap { flex-wrap: wrap; }
.actions.wrap button { flex: 1 1 10rem; }
.actions.wrap button.more { flex: 0 0 var(--touch); font-size: 1.5rem; line-height: 1; }
.actions > .primary { flex: 1 1 auto; }
.facts { display: grid; grid-template-columns: auto 1fr; gap: 0.125rem 0.75rem; margin: 0; font-size: 1rem; }
.facts dt { color: var(--ink-faint); }
.facts dd { margin: 0; }

.menu-rows { background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); overflow: hidden; }
.menu-rows li + li .row-btn { padding-top: 0.5rem; }
.row-btn { width: 100%; min-height: 68px; display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; border: 0; background: none; text-align: left; font-size: 1.125rem; font-weight: 700; }
.row-btn .row-side { margin-left: auto; font-weight: 400; color: var(--ink-faint); font-size: 0.9375rem; text-align: right; max-width: 55%; }
.row-btn .chev { color: var(--ink-faint); font-size: 1.5rem; }
.row-btn .pick { min-height: 48px; }
.about { padding: 0.5rem 0.25rem; }

.panel { background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); padding: 0.875rem; display: flex; flex-direction: column; gap: 0.625rem; }
.panel h3 { margin-top: 0.5rem; }
.summary { display: grid; grid-template-columns: repeat(auto-fill, minmax(7rem, auto) minmax(6rem, 1fr)); gap: 0.25rem 1rem; margin: 0; align-items: baseline; }
.summary dt { color: var(--ink-faint); font-size: 0.9375rem; }
.summary dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; }
.blocker { color: var(--danger); }
.menu-items li.menu-item { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0; min-height: 64px; font-size: 1.0625rem; }
.menu-item.out .grow { color: var(--ink-faint); text-decoration: line-through; }
#menu-list h3 { margin: 0.75rem 0 0.25rem; }
.events { font-size: 0.9375rem; color: var(--ink-soft); padding-left: 1.2rem; margin: 0.25rem 0 0.75rem; list-style: decimal; }
.receipt-lines li { padding: 0.25rem 0; font-size: 1.0625rem; }
#detail-sheet h4 { font-size: 1rem; margin: 0.75rem 0 0.25rem; }

/* ---- sheets ---- */
.sheet-back { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); display: flex; align-items: flex-end; justify-content: center; z-index: 20; }
.sheet { width: 100%; max-width: 36rem; max-height: 92%; overflow-y: auto; background: var(--surface); border-radius: var(--radius) var(--radius) 0 0; padding: 1rem 1rem calc(1rem + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 0.875rem; }
@media (min-width: 720px) { .sheet-back { align-items: center; } .sheet { border-radius: var(--radius); } }
.sheet-head { display: flex; align-items: center; gap: 0.75rem; }
.sheet-head h3 { flex: 1 1 auto; font-size: 1.375rem; }
.sheet .actions { margin-top: 0.25rem; }
.sheet .actions .primary { flex: 2 1 auto; }
.group .glabel { display: flex; gap: 0.5rem; align-items: baseline; font-weight: 700; margin-bottom: 0.375rem; }
.group .req { font-size: 0.875rem; color: var(--pending); font-weight: 600; }
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chips button { min-height: var(--touch); padding: 0.25rem 1rem; border-radius: var(--radius); border: 2px solid var(--line-strong); background: var(--surface); font-weight: 700; font-size: 1.0625rem; }
.chips button[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.qty { display: flex; align-items: center; gap: 0.75rem; font-weight: 700; }

.qty .step { min-width: 64px; font-size: 1.5rem; }
.line-total { text-align: right; font-size: 1.375rem; }
.total, .change { display: flex; justify-content: space-between; align-items: baseline; font-size: 1.125rem; }
.total strong, .change strong { font-size: 1.75rem; font-variant-numeric: tabular-nums; }
.quick { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }
.quick button { min-height: 60px; border-radius: var(--radius); border: 2px solid var(--line-strong); background: var(--surface); font-weight: 800; font-size: 1.25rem; }
.quick button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.sheet.paid { text-align: center; align-items: stretch; }
.sheet.paid .total { justify-content: center; gap: 1rem; }
.sheet.paid .total strong { font-size: 2.5rem; color: var(--good); }
.sheet.demo .transcript { max-height: 14rem; overflow-y: auto; background: var(--surface-sunken); border-radius: var(--radius); padding: 0.5rem 0.75rem; font-size: 1rem; }
.transcript li { padding: 0.25rem 0; color: var(--ink-faint); }
.transcript li.current { color: var(--ink); font-weight: 700; }
.transcript li.done { color: var(--ink-soft); }
.transcript .speaker { font-weight: 700; margin-right: 0.375rem; }
.transcript .note { display: block; font-size: 0.9375rem; color: var(--accent); font-weight: 400; }
.feed button[aria-pressed="true"] { border-color: var(--danger); color: var(--danger); }

/* ---- the highlight: amber heartbeat on the button the words point at ---- */
.lit { position: relative; z-index: 1; border-color: var(--lit) !important; box-shadow: 0 0 0 3px var(--lit), 0 0 22px 6px rgba(201, 138, 0, 0.45); animation: heartbeat 1.1s ease-in-out infinite; }
@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  14% { transform: scale(1.03); }
  28% { transform: scale(1); }
  42% { transform: scale(1.015); }
  70% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .lit { animation: none; } }
button.primary.lit, .next-btn.lit { color: var(--ink); background: var(--lit-soft); }
.caption { position: absolute; left: 0.5rem; bottom: -0.75rem; background: var(--lit); color: #1d1d1b; font-size: 0.8125rem; font-weight: 700; padding: 0.125rem 0.5rem; border-radius: 999px; white-space: nowrap; }

/* ---- toast ---- */
.toast { position: fixed; left: 50%; bottom: calc(7.5rem + env(safe-area-inset-bottom)); transform: translateX(-50%); background: var(--ink); color: var(--ground); padding: 0.625rem 1.125rem; border-radius: 999px; font-size: 1.0625rem; font-weight: 600; z-index: 30; max-width: 92%; text-align: center; display: inline-flex; align-items: center; gap: 0.75rem; }
.toast[hidden] { display: none; }
.toast-action { min-height: 44px; padding: 0 1rem; border-radius: 999px; border: 2px solid var(--ground); background: none; color: var(--ground); font-weight: 800; font-size: 1.0625rem; }

@media print {
  body > * { display: none !important; }
  #terminal, #detail, #detail-sheet { display: block !important; }
  #terminal > :not(#detail) { display: none !important; }
  .sheet-back { position: static; background: none; }
  #detail-actions, #detail-close { display: none !important; }
}


/* demo switches inside the demo sheet */
.demo .toggle { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 1rem; }
.demo .toggle input { width: 1.25rem; height: 1.25rem; }

/* ---------------- the visual system (2026-10-09) ----------------
   Three type sizes: 18px body, 20px line names and labels, 36px the call
   number. One chip geometry (.opt, .chip). Three elevations (--lift,
   --lift-2, --lift-3), no borders except on controls. Two tones beside
   neutral: blue for what the POS does by itself, green for the cashier's
   confirmations. An 8px grid for spacing. Phone first: the top nav and the
   stepper give the lines their room. */
.nav { padding: 0.5rem 0.5rem 0; }
.nav-btn { width: 52px; height: 52px; box-shadow: var(--lift); }
.nav-btn .ico { width: 26px; height: 26px; }
.nav-btn[aria-pressed="true"] { box-shadow: var(--lift-2); }
.icon-btn { border: 0; border-radius: 50%; width: var(--touch); box-shadow: var(--lift); color: var(--ink-soft); }
.call-part { font-size: 2.25rem; }
.stepper .step { width: 40px; height: 40px; font-size: 1.25rem; border-width: 1.5px; }
.stepper .n { min-width: 2.5rem; min-height: 40px; font-size: 1.125rem; }
.line .lname { font-size: 1.25rem; }
.line .wrong { margin-left: 0; min-height: 0; padding: 0 0.5em; border: 1px dashed var(--line-strong); border-radius: 6px; background: none; color: var(--ink-faint); font-size: 0.9375rem; font-weight: 500; line-height: 1.5; }
.fab-text { font-size: 1rem; font-weight: 800; letter-spacing: 0.02em; }
button.fab.park { color: var(--ink); }
.row-btn .row-side { max-width: 45%; }
/* a switch is a switch */
.switch { appearance: none; -webkit-appearance: none; width: 3.25rem; height: 2rem; border-radius: 999px; background: var(--line-strong); position: relative; margin: 0; cursor: pointer; transition: background 150ms ease; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: calc(2rem - 6px); height: calc(2rem - 6px); border-radius: 50%; background: #fff; box-shadow: var(--lift); transition: left 150ms ease; }
.switch:checked { background: var(--accent); }
.switch:checked::after { left: calc(100% - 2rem + 3px); }

#cash-row .cash.method { background: var(--surface); color: var(--accent); border: 2px solid var(--accent); }
/* setup: the workflow questions, one answer each */
.setup-q { background: var(--surface); box-shadow: var(--lift); border-radius: var(--radius); padding: 0.875rem 1rem; display: flex; flex-direction: column; gap: 0.625rem; }
.setup-q h3 { margin: 0; font-size: 1.125rem; font-weight: 700; }
.setup-opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.setup-opt { min-height: 48px; padding: 0 1rem; border-radius: 999px; border: 2px solid var(--line-strong); background: var(--surface); color: var(--ink); font-size: 1.0625rem; font-weight: 700; }
.setup-opt[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ---------------- the finish (2026-10-10) ----------------
   Why the terminal felt cheap, and the answer to each cause: one typeface
   carrying both the CJK and the digits; three weights (400 body, 500/600
   names and labels, 700 the one number that matters); no 2px outlines,
   secondary controls are tonal fills and selection is a fill; two radii
   (12px surfaces and buttons, pill chips and round buttons); a warmer
   ground with tighter shadows so cards read as objects; receipt density;
   words on the nav; a glow for lit, never a beige fill. */
:root {
  --ground: #ebeae4; --surface: #ffffff; --surface-sunken: #f2f1ec;
  --line: #e3e2dc; --line-strong: #d0cfc8;
  --accent: #1f4f9f; --accent-soft: #e4ecf8;
  --radius: 12px;
  --lift: 0 1px 2px rgba(20, 20, 16, 0.05), 0 6px 18px rgba(20, 20, 16, 0.06);
  --lift-2: 0 2px 4px rgba(20, 20, 16, 0.07), 0 10px 26px rgba(20, 20, 16, 0.10);
  --lift-3: 0 3px 6px rgba(20, 20, 16, 0.10), 0 16px 36px rgba(20, 20, 16, 0.16);
}
body, html[lang^="zh"] body { font-family: "PingFang TC", "Noto Sans TC", "Noto Sans CJK TC", "Microsoft JhengHei", system-ui, sans-serif; font-weight: 400; font-variant-numeric: tabular-nums; line-height: 1.5; }
html[lang^="ja"] body { font-family: "Hiragino Sans", "Noto Sans JP", "Noto Sans CJK JP", "Yu Gothic", system-ui, sans-serif; }
html[lang="en"] body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
h2, h3, .sheet-head h3 { font-weight: 600; }
.call-part { font-weight: 700; }
.chip { border: 0; font-weight: 500; padding: 0.2rem 0.75rem; background: var(--surface-sunken); color: var(--ink-soft); }
.chip.pending { background: var(--pending-soft); color: var(--pending); }
.chip.good { background: var(--good-soft); color: var(--good); }
.chip.bad { background: var(--danger-soft); color: var(--danger); }
.chip.accent { background: var(--accent-soft); color: var(--accent); }
.line .lname { font-weight: 500; font-size: 1.125rem; }
.line .ltotal { font-weight: 500; font-size: 1.0625rem; color: var(--ink-soft); }
.line .opt { font-weight: 500; border-radius: 999px; padding: 0 0.7em; }
.line .opt.open, .line .opt.assumed, .line .wrong { border-radius: 999px; }
.totals { font-weight: 400; padding: 0.5rem 0.875rem; }
.totals .subtotal strong { font-weight: 700; }
.info { padding: 0.625rem 0.875rem; }
.line .lcontent { padding: 0.6rem 0.875rem; }
/* no outlines: tonal fills, selection is a fill */
button.primary, button.secondary, button.destructive, .tabs button, .chips button, .item, .pick-grid button, .pick-opt, .setup-opt, .stepper .step, .cash-row button, .icon-btn { border: 0; }
button.secondary, .tabs button, .chips button, .pick-grid button, .pick-opt, .setup-opt, .stepper .step { background: var(--surface-sunken); color: var(--ink); font-weight: 600; }
button.primary { font-weight: 600; }
button.destructive { background: var(--danger-soft); color: var(--danger); font-weight: 600; }
button.secondary.back { background: none; color: var(--ink-soft); font-weight: 500; padding-left: 0.25rem; }
.chips button[aria-pressed="true"], .tabs button[aria-selected="true"], .pick-grid button[aria-pressed="true"], .setup-opt[aria-pressed="true"], .pick-opt.on { background: var(--accent); color: var(--accent-ink); }
.item { background: var(--surface-sunken); font-weight: 500; }
.item:active { background: var(--accent-soft); }
.item strong { font-weight: 500; }
.item .price, .item small { font-weight: 400; color: var(--ink-soft); }
.stepper .n { background: none; font-weight: 600; }
.stepper .step:disabled { opacity: 0.35; }
.fab-label { font-weight: 600; }
.fab-label.primary-label { font-weight: 700; }
.cash-row button { font-weight: 600; background: var(--surface); color: var(--accent); }
.cash-row button.exact { background: var(--accent); color: var(--accent-ink); }
.cash-row button.quiet { color: var(--ink-soft); }
#cash-row .cash.method { background: var(--accent-soft); color: var(--accent); }
.row-btn { font-weight: 500; }
.menu-rows li + li .row-btn { border-top: 1px solid var(--line); }
.sheet { border-radius: 16px 16px 0 0; }
/* lit: a glow around the button, not a fill */
button.primary.lit, .next-btn.lit, button.fab.lit { background: var(--surface); color: var(--ink); }
/* cards: a receipt line, not five rows */
.order-card { padding: 0.75rem 0.875rem; gap: 0.5rem; }
.card-head { gap: 0.5rem; }
.card-head strong { font-weight: 600; font-size: 1.375rem; }
.card-head .states { margin-left: auto; }
.card-mid { display: flex; align-items: baseline; gap: 0.75rem; }
.card-mid .card-lines { flex: 1 1 auto; margin: 0; font-size: 1rem; color: var(--ink-soft); }
.card-mid .card-total { margin: 0; white-space: nowrap; font-weight: 600; font-size: 1.125rem; }
.cards .group-title { font-weight: 500; font-size: 0.9375rem; }
/* the nav says what it is */
.nav { gap: 0.5rem; justify-content: center; padding-top: 0.625rem; }
.nav-btn { width: auto; height: 44px; padding: 0 1.1rem; border-radius: 999px; font-size: 1rem; font-weight: 600; gap: 0.4rem; }
.nav-btn .ico { display: none; }
.badge { position: static; margin-left: 0.15rem; border: 0; min-width: 1.5rem; font-size: 0.8125rem; line-height: 1.5rem; padding: 0 0.4rem; }
.nav-btn[aria-pressed="true"] .badge { background: rgba(255, 255, 255, 0.28); }
/* an order with nothing on it shows nothing */
.lines-wrap.blank { display: none; }
/* the paid sheet shows change only when there is some */
.paid .total[hidden] { display: none; }
.item > *:first-child, .item .name { font-weight: 500; }
.order-card .actions.wrap { flex-wrap: nowrap; }
.order-card .actions.wrap button { flex: 1 1 0; min-width: 0; }
.order-card .actions.wrap button.more { flex: 0 0 var(--touch); }

/* ---------------- the bar (2026-10-11) ----------------
   Owner: the buttons at the bottom were the largest issue. One row, one
   geometry: every action is 64px tall; the primary is a pill that holds its
   own words and takes the width that is left, every other action is a
   64px circle with its word or glyph inside. One colour means one thing:
   blue is the single action that moves the order forward, white is
   everything else, grey is a primary that cannot go yet, a glow is the
   customer having asked. 12px between buttons, 16px to the edges, nothing
   past the viewport. */
.next { left: 0; right: 0; bottom: 0; padding: 0 16px calc(12px + env(safe-area-inset-bottom)); align-items: stretch; gap: 10px; }
.next-row { display: flex; align-items: center; gap: 12px; min-width: 0; }
.next-row .act { height: 64px; min-height: 64px; border: 0; border-radius: 999px; background: var(--surface); color: var(--ink); box-shadow: var(--lift-2); display: inline-flex; align-items: center; justify-content: center; padding: 0; font-size: 1.0625rem; font-weight: 600; white-space: nowrap; transition: transform 120ms ease, box-shadow 120ms ease, background 120ms ease; }
.next-row .act:active { transform: translateY(2px); box-shadow: var(--lift); }
.next-row .act .ico { display: none; }
.next-row .act.primary { flex: 1 1 auto; min-width: 0; padding: 0 1.25rem; background: var(--accent); color: var(--accent-ink); font-size: 1.25rem; font-weight: 700; justify-content: center; }
.next-row .act.primary .act-label { overflow: hidden; text-overflow: ellipsis; }
.next-row .act.primary:disabled { background: var(--surface-sunken); color: var(--ink-faint); box-shadow: var(--lift); opacity: 1; }
/* a 390px phone: 結帳並送單 NT$1,000 must fit beside two circles, so the pill gives up padding before letters */
@media (max-width: 400px) { .next-row .act.primary { font-size: 1.125rem; padding: 0 0.625rem; letter-spacing: -0.01em; } }
.next-row .act.round { flex: 0 0 64px; width: 64px; font-size: 1rem; }
.next-row .act.round .glyph { font-size: 1.75rem; font-weight: 500; line-height: 1; }
.next-row .act-slot { display: contents; }
/* lit: a glow on the primary, same geometry */
.next-row .act.primary.lit, .next-btn.lit { background: var(--accent); color: var(--accent-ink); }
.cash-row { justify-content: flex-start; }
.new-pill { align-self: center; }
/* on a tablet the bar sits under the order column, never across the menu */
.tablet .next-row, .tablet .cash-row { max-width: 36rem; margin-left: auto; width: 100%; }
.tablet .cash-row { justify-content: flex-end; }

/* the cash chips on a card under 進行中 */
.card-cash { justify-content: flex-start; animation: none; margin-top: 0.25rem; }
.card-cash button { min-height: 48px; font-size: 1rem; padding: 0 0.9rem; box-shadow: none; background: var(--accent-soft); }
.card-cash button.exact { background: var(--accent); color: var(--accent-ink); }
.card-cash button.quiet { background: var(--surface-sunken); }
