/* Mini Stack Bros Register.
   Dark on purpose: half of these events run after sunset and a cream screen at a
   night market is a flashlight in the customer's face. Brand colors carry over
   from ministackbros.com, brightened where the site's caramel would go muddy. */

@import url('https://fonts.googleapis.com/css2?family=Alfa+Slab+One&family=Outfit:wght@400;500;600;700&display=swap');

:root {
  --bg:        #16110E;
  --surface:   #211913;
  --surface-2: #2C211A;
  --surface-3: #3A2B21;
  --line:      rgba(245, 229, 211, 0.13);
  --text:      #F5E5D3;
  --text-dim:  rgba(245, 229, 211, 0.60);
  --text-faint:rgba(245, 229, 211, 0.38);
  --accent:    #D9903F;
  --accent-hi: #EBA75C;
  --accent-ink:#1A120C;
  --good:      #63C083;
  --danger:    #E0685C;
  --warn:      #E8B04B;

  --font-display: 'Alfa Slab One', Georgia, serif;
  --font-body: 'Outfit', system-ui, -apple-system, sans-serif;

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

  --radius: 14px;
  --tap: 56px;        /* every button, choice and row you tap: one height */
  --tap-sm: 44px;     /* the small ones: tabs and in-row buttons */
  --safe-b: env(safe-area-inset-bottom, 0px);
  /* THE one bottom-inset dial. Every element that sits against the bottom of the
     screen rides this: the tab bar, the cart foot, the sheet foot, the login
     card and the toast. They used to each add the raw `--safe-b` themselves, so
     "reduce the space at the bottom" meant four separate edits and the Settings
     control only reached one of them.

     Default is the full inset MINUS 30px, which is what Carlos settled on
     (2026-08-17, "minimum works out fine") after trying the range. The full
     inset is too much here because iOS already reserves its own band outside the
     web view for the home indicator — see the theme-color note in index.html —
     so paying the inset again inside the page double-counts it.

     Settings > Bottom spacing overrides this at runtime via an inline style on
     the root, so the value below is only the default a fresh install gets. */
  --tabbar-pad: max(0px, calc(var(--safe-b) - 30px));
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body {
  /* --appvh is measured in JS from the real visible viewport (see index.html),
     the same way [[Forge]] does it, because every vh unit is wrong somewhere on
     iOS: 100vh overshoots in Safari and clips the tab bar, 100dvh under-reports
     in an installed PWA and leaves a band of dead space under it. The two values
     before it are only the pre-script fallbacks, in ascending order of accuracy.

     This replaced a `position: fixed; inset: 0` shell that was my own attempt at
     the same problem on 2026-08-17. It was wrong: `inset: 0` sizes to the LAYOUT
     viewport, which is the very thing iOS misreports here, so it inherited the
     bug it was meant to fix. Measuring beats asserting. Do not put a bare vh/dvh
     height back. */
  height: 100dvh;
  height: 100vh;
  height: var(--appvh, 100dvh);
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
/* Normal flow, sized by --appvh above. `.view` and `.item-grid` own their own
   scrolling, so nothing here relies on the document scrolling. */
body { display: flex; flex-direction: column; }

/* The canvas — everything outside the layout viewport — is painted from `html`,
   NOT from body. That band is what Carlos was seeing on 2026-08-17: "there's a
   line and then there's darker space below it." The line was the tab bar's
   --surface background ending; the darker space was this canvas in --bg showing
   through underneath it.
   Painting the canvas --surface makes the band continuous with the two things
   that actually touch it: the header at the top and the tab bar at the bottom
   are both --surface, so whatever iOS refuses to let the page draw into now
   matches the furniture on either side instead of reading as a hole. Body keeps
   --bg, so the content area is unchanged. */
html { background: var(--surface); }
[hidden] { display: none !important; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 400; letter-spacing: 0.4px; line-height: 1.1; }

/* =============================================================== BUTTONS */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 20px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface-2); color: var(--text);
  font-weight: 600; cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 160ms ease, opacity 160ms ease;
}
.btn:active:not(:disabled) { transform: scale(0.97); }
.btn:disabled { opacity: 0.4; cursor: default; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-ghost { background: transparent; }
.btn-danger { background: transparent; border-color: rgba(224, 104, 92, 0.5); color: var(--danger); }
.btn-block { width: 100%; }
.btn-sm { min-height: var(--tap-sm); padding: 0 14px; font-size: 0.95rem; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border: 0; border-radius: 12px;
  background: transparent; color: var(--text-dim); cursor: pointer;
  transition: transform 160ms var(--ease-out), color 160ms ease;
}
.icon-btn:active { transform: scale(0.94); }
/* The sheet's close X specifically. 46px was under the 48px floor and it sits in
   the top corner, which is the hardest spot on a phone to hit accurately with
   the hand you are holding it in — Carlos, 2026-08-17: "there is an X at the top
   right-hand corner, but it's very difficult to tap it." The negative margin
   keeps it looking the same size while the touch target grows to 56px, and the
   sheets also close by tapping the scrim and, for Settings, by a full-width Done
   button at the bottom where a thumb already is. */
#sheet-close { width: 56px; height: 56px; margin: -5px -5px -5px 0; }
.link-btn {
  border: 0; background: none; color: var(--text-dim);
  font-size: 0.92rem; font-weight: 600; text-decoration: underline; cursor: pointer;
  padding: 8px; min-height: 40px;
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover:not(:disabled) { background: var(--surface-3); }
  .btn-primary:hover:not(:disabled) { background: var(--accent-hi); }
  .icon-btn:hover { color: var(--text); }
}
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* ================================================================= LOGIN */
.login {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 24px; padding-bottom: calc(24px + var(--tabbar-pad));
}
.login-card { width: 100%; max-width: 380px; text-align: center; }
.login-logo { width: 110px; height: auto; margin: 0 auto 18px; border-radius: 18px; }
.login h1 { font-size: 2.1rem; text-transform: uppercase; }
.login-sub { color: var(--text-dim); margin-bottom: 26px; font-size: 0.95rem; letter-spacing: 1.5px; text-transform: uppercase; }
.field { display: block; text-align: left; margin-bottom: 14px; }
.field > span { display: block; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); margin-bottom: 7px; }
.field input, .field select, .field textarea {
  width: 100%; min-height: var(--tap); padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); color: var(--text);
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--accent); outline: none; }
.login-error { color: var(--danger); font-size: 0.92rem; margin-bottom: 12px; }

/* ============================================================= APP SHELL */
/* body is the flex column; #app is one of its two children (the other is the
   login screen, which already claims flex:1). Without this, #app collapses to
   its content height, .view's flex:1 has no flex parent to grow into, and the
   tab bar lands wherever the content ends instead of at the bottom. */
#app {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column;
  /* The tab bar is `position: fixed` now (see .tabbar), so it no longer takes up
     space in this column. Reserve its height here or the last row of every view
     hides behind it. 61px is the bar's own height; --tabbar-pad is its safe-area
     padding on top of that. */
  padding-bottom: calc(61px + var(--tabbar-pad));
}

/* ================================================================ TOPBAR */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 10px 8px 12px;
  padding-top: calc(8px + env(safe-area-inset-top, 0px));
  background: var(--surface); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.chip {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  min-height: 46px; padding: 5px 14px; max-width: 62vw;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
  cursor: pointer; text-align: left;
  transition: transform 160ms var(--ease-out);
}
.chip:active { transform: scale(0.97); }
.chip-label { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text-faint); }
.chip-value { font-size: 0.98rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55vw; }
.topbar-right { display: flex; align-items: center; gap: 4px; }
.net-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--good); transition: background-color 200ms ease; }
.net-dot.off { background: var(--warn); }
.pending {
  min-width: 26px; height: 26px; padding: 0 7px; border-radius: 13px;
  background: var(--warn); color: var(--accent-ink);
  font-size: 0.78rem; font-weight: 700; display: grid; place-items: center;
}

/* ================================================================== VIEW */
.view { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
/* The tab bar is a sibling below the scroll area now, not an overlay, so this
   only needs breathing room at the end of a list — not clearance for the bar. */
.pad { padding: 16px 16px 24px; max-width: 900px; margin: 0 auto; }
.view-title { font-size: 1.5rem; text-transform: uppercase; }
.view-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.hint { color: var(--text-dim); font-size: 0.9rem; margin-bottom: 16px; }
.empty-note { color: var(--text-faint); text-align: center; padding: 40px 20px; }

/* ============================================================== REGISTER */
.register-layout { display: flex; min-height: 100%; }
.menu-pane { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.kind-tabs {
  display: flex; gap: 8px; padding: 12px 14px;
  overflow-x: auto; scrollbar-width: none; position: sticky; top: 0;
  background: var(--bg); z-index: 10;
}
.kind-tabs::-webkit-scrollbar { display: none; }
.kind-tab {
  flex: 0 0 auto; min-height: var(--tap-sm); padding: 0 18px;
  border: 1px solid var(--line); border-radius: 22px;
  background: transparent; color: var(--text-dim); font-weight: 600; cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 160ms ease, color 160ms ease;
}
.kind-tab:active { transform: scale(0.97); }
.kind-tab[aria-selected="true"] { background: var(--text); color: var(--bg); border-color: var(--text); }

.item-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-auto-rows: 120px;   /* one card size for the whole menu, however long the name */
  gap: 10px; padding: 0 14px 20px;
}
.item-card {
  position: relative; display: flex; flex-direction: column; justify-content: space-between; gap: 6px;
  height: 100%; min-width: 0; padding: 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  text-align: left; cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 160ms ease;
}
.item-card:active { transform: scale(0.97); }
.item-card .top { min-width: 0; }
.item-card .name {
  font-family: var(--font-display); font-size: 1.12rem; line-height: 1.15;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.item-card .sub { font-size: 0.82rem; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 1.2em; }
.item-card .bottom { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.item-card .price { font-weight: 700; color: var(--accent); font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.item-card.is-off { opacity: 0.45; }
.item-card .off-flag {
  font-size: 0.66rem; letter-spacing: 1px;
  text-transform: uppercase; color: var(--warn); border: 1px solid var(--warn);
  border-radius: 6px; padding: 1px 5px;
}

/* ------------------------------------------------------------------ cart */
.cart-pane {
  display: flex; flex-direction: column;
  background: var(--surface); border-left: 1px solid var(--line);
  width: 360px; flex: 0 0 360px; position: sticky; top: 0; align-self: flex-start;
  max-height: 100%;
}
.cart-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 6px; }
.cart-head h2 { font-size: 1.15rem; text-transform: uppercase; }
.cart-lines { list-style: none; overflow-y: auto; padding: 0 16px; flex: 1; }
.cart-line {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px 0; border-bottom: 1px solid var(--line);
  animation: line-in 220ms var(--ease-out);
}
@keyframes line-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.cart-line .body { flex: 1; min-width: 0; }
.cart-line .nm { font-weight: 600; }
.cart-line .mods { font-size: 0.84rem; color: var(--text-dim); }
.cart-line .amt { font-weight: 700; white-space: nowrap; }
.cart-line .rm {
  border: 0; background: none; color: var(--text-faint); cursor: pointer;
  width: 34px; height: 34px; font-size: 1.3rem; line-height: 1;
}
.cart-empty { color: var(--text-faint); padding: 22px 16px; font-size: 0.95rem; }
.cart-foot { padding: 12px 16px calc(14px + var(--tabbar-pad)); border-top: 1px solid var(--line); }
.name-input {
  width: 100%; min-height: var(--tap); padding: 8px 14px; margin-bottom: 10px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
}
.total-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; }
.total-row span { color: var(--text-dim); text-transform: uppercase; font-size: 0.8rem; letter-spacing: 1.4px; }
.total-row strong { font-family: var(--font-display); font-size: 2rem; }
.pay-row { display: grid; grid-template-columns: 1fr; gap: 10px; }
.btn-tender { font-size: 1.05rem; }

@media (max-width: 819px) {
  .register-layout { flex-direction: column; }
  .menu-pane { padding-bottom: 8px; }
  /* Clearance for the fixed cart panel. It was a flat 250px, but the panel
     grows to 52vh as lines are added — taller than that on any modern phone —
     so the last row of items sat under it with no way to scroll them clear.
     app.js measures the panel into --cart-h on every cart render. */
  .item-grid { padding-bottom: calc(var(--cart-h, 250px) + 28px); }
  .cart-pane {
    /* top:auto is load-bearing. The desktop rule above sets `position:sticky;
       top:0` to park the cart beside the menu. Switching to `fixed` here keeps
       that `top:0`, and a fixed box anchored at BOTH edges resolves to the top
       one — so the cart rendered over the menu, hiding the category tabs and
       every stack but the last. Clear top before setting bottom. */
    position: fixed; top: auto; left: 0; right: 0; bottom: calc(64px + var(--tabbar-pad) + var(--vhgap, 0px));
    width: auto; flex: none; max-height: 52vh; z-index: 20;
    border-left: 0; border-top: 1px solid var(--line);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -18px 40px rgba(0, 0, 0, 0.45);
  }
  .cart-lines { max-height: 26vh; }
  .cart-foot { padding-bottom: 14px; }
}

/* ====================================================== CONFIRM THE ORDER */
.confirm-lines { list-style: none; margin-bottom: 14px; }
.confirm-lines li { padding: 10px 0; border-bottom: 1px solid var(--line); }
.confirm-lines .row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.confirm-lines .nm { font-weight: 600; }
.confirm-lines .amt { font-weight: 700; white-space: nowrap; }
.confirm-lines .m { font-size: 0.86rem; color: var(--text-dim); margin-top: 3px; }
.sheet-body .name-input { margin: 4px 0 16px; }
.confirm-total { display: flex; justify-content: space-between; align-items: baseline; }
.confirm-total span { color: var(--text-dim); text-transform: uppercase; font-size: 0.8rem; letter-spacing: 1.4px; }
.confirm-total strong { font-family: var(--font-display); font-size: 2rem; }
.sheet-foot .btn-block + .btn-block { margin-top: 8px; }

/* ========================================================= TAX AND PAYING */
.tax-note { color: var(--text-dim); font-size: 0.84rem; margin: -6px 0 12px; text-align: right; }
.tax-note:empty { display: none; }
.confirm-sub { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.sheet-body .tax-note { margin: 4px 0 0; }

/* The amount being paid: the one number everybody at the counter looks at. */
.pay-due { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin: 4px 0 14px; }
.pay-due .k, .cash-got .k, .change-big .k {
  color: var(--text-dim); text-transform: uppercase; font-size: 0.8rem; letter-spacing: 1.4px;
}
.pay-due strong { font-family: var(--font-display); font-size: 2.4rem; line-height: 1; font-variant-numeric: tabular-nums; }

.pay-status {
  display: grid; gap: 6px; padding: 18px 16px; margin-bottom: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.pay-status strong { font-size: 1.2rem; }
.pay-status span { color: var(--text-dim); }
.pay-status.is-tap { border-color: var(--accent); background: rgba(217, 144, 63, 0.10); }
.pay-status.is-tap strong { font-family: var(--font-display); font-weight: 400; font-size: 1.45rem; line-height: 1.15; }
.pay-status.is-bad { border-color: rgba(224, 104, 92, 0.55); background: rgba(224, 104, 92, 0.08); }
.pay-status.is-bad strong { color: var(--danger); }
.pay-status.is-good { border-color: rgba(99, 192, 131, 0.55); background: rgba(99, 192, 131, 0.08); }
.pay-status.is-good strong { color: var(--good); }

.receipt-row { display: grid; grid-template-columns: 1fr auto; gap: 8px; margin-top: 14px; }
.receipt-row .name-input { margin: 0; min-height: var(--tap); }

/* Cash: quick bills, the keypad, and the change in big type. Every key is the
   one .btn, so heights and corners match the rest of the app. */
.quick-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.quick-row .btn { padding: 0 6px; font-variant-numeric: tabular-nums; }
.cash-got { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin: 4px 0 10px; }
.cash-got strong { font-size: 1.5rem; font-variant-numeric: tabular-nums; }
.cash-got strong.dim { color: var(--text-faint); font-size: 1rem; font-weight: 500; }
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 12px; }
.keypad .btn { font-size: 1.35rem; font-variant-numeric: tabular-nums; }
.change-big {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 14px 16px; border-radius: var(--radius);
  background: rgba(99, 192, 131, 0.10); border: 1px solid rgba(99, 192, 131, 0.45);
}
.change-big strong { font-family: var(--font-display); font-size: 2.6rem; line-height: 1; color: var(--good); font-variant-numeric: tabular-nums; }
.change-big.is-short { background: rgba(224, 104, 92, 0.08); border-color: rgba(224, 104, 92, 0.5); }
.change-big.is-short strong { color: var(--danger); }
.change-big.is-empty { background: var(--surface); border-color: var(--line); }
.change-big.is-empty strong { color: var(--text-faint); }

/* Scan to pay: the amount huge, the code on white (cameras need the contrast,
   and the dark theme would fight it), and a quiet live status line. */
.qr-amount { font-family: var(--font-display); font-size: 3.2rem; line-height: 1; text-align: center; margin: 2px 0 4px; font-variant-numeric: tabular-nums; }
.qr-sub { text-align: center; color: var(--text-dim); margin-bottom: 6px; }
.qr-box { width: min(76vw, 320px); aspect-ratio: 1; margin: 12px auto 10px; background: #fff; border-radius: var(--radius); padding: 6px; }
.qr-box svg { display: block; width: 100%; height: 100%; }
.qr-box.is-empty { background: var(--surface); border: 1px solid var(--line); }
.qr-help { text-align: center; font-weight: 600; font-size: 1.1rem; }
.qr-wait { text-align: center; color: var(--text-dim); margin: 6px 0 2px; }
.qr-wait::before { content: ''; display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); margin-right: 8px; vertical-align: 1px; animation: qr-pulse 1.4s ease-in-out infinite; }
.qr-wait.is-checking::before { background: var(--warn); }
@keyframes qr-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
.qr-paid { display: grid; justify-items: center; gap: 6px; padding: 10px 0 6px; text-align: center; }
.qr-paid svg { width: 120px; height: 120px; }
.qr-paid strong { font-family: var(--font-display); font-weight: 400; font-size: 2.4rem; color: var(--good); }
.qr-order { font-family: var(--font-display); font-size: 1.4rem; }
.tip-grid { display: grid; grid-template-columns: 1fr; grid-auto-rows: var(--tap); gap: 8px; }
.tip-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  height: 100%; min-width: 0; padding: 0 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); font-size: 1.05rem; cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 160ms ease, border-color 160ms ease;
}
.tip-opt:active { transform: scale(0.97); }
.tip-opt .tip-l { font-weight: 600; white-space: nowrap; }
.tip-opt .tip-v { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-dim); }
.tip-opt[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.tip-opt[aria-pressed="true"] .tip-v { color: var(--accent-ink); }
@media (min-width: 600px) {
  .tip-grid { grid-template-columns: repeat(5, 1fr); grid-auto-rows: 104px; }
  .tip-opt { flex-direction: column; justify-content: center; gap: 6px; padding: 0 6px; text-align: center; }
  .tip-opt .tip-l { font-family: var(--font-display); font-weight: 400; font-size: 1.35rem; white-space: normal; line-height: 1.1; }
}

/* Card in the Stripe app: the amount ready to paste, then one link out. */
.copy-row { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; gap: 10px; margin: 10px 0 14px; min-height: var(--tap); }
.copy-row .copy-ok { grid-column: 1 / -1; align-self: center; text-align: center; }
.copy-row .copy-text {
  display: flex; align-items: center; justify-content: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.copy-ok { color: var(--good); font-weight: 600; font-size: 1.05rem; }
.copy-text { font-family: var(--font-display); font-size: 1.6rem; user-select: all; -webkit-user-select: all; font-variant-numeric: tabular-nums; }
a.btn { text-decoration: none; }
.app-steps { text-align: center; color: var(--text-dim); margin: 12px 0 8px; font-size: 0.95rem; }
.btn.is-confirm { border-color: var(--warn); color: var(--warn); }
.sheet-row .btn-sm + .btn-sm { margin-left: 2px; }
.link-pick { margin-top: 12px; }

/* Reports: Count the cash / Close out, side by side, one width each. */
.report-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.count-scope { font-family: var(--font-display); font-size: 1.15rem; margin: 2px 0 10px; }
.count-result { margin: 4px 0 14px; display: grid; gap: 8px; }
.close-grid { grid-template-columns: repeat(2, 1fr); margin: 4px 0 12px; }
.sheet-row:disabled { opacity: 0.45; cursor: default; }
.sheet-row .pill { margin-left: 0; }

/* ================================================================= QUEUE */
.queue-list { display: grid; gap: 12px; }
.queue-card {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 16px; background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.queue-card .no { font-family: var(--font-display); font-size: 1.9rem; line-height: 1; min-width: 52px; }
.queue-card .who { font-weight: 600; margin-bottom: 4px; }
.queue-card .what { font-size: 0.95rem; color: var(--text-dim); }
.queue-card .what li { list-style: none; padding: 3px 0; }
.queue-card .what .m { color: var(--text-faint); }
.queue-card .ago { font-size: 0.78rem; color: var(--text-faint); margin-top: 6px; }
.queue-card .acts { display: flex; flex-direction: column; gap: 8px; }

/* =============================================================== REPORTS */
.range-tabs { display: flex; gap: 8px; overflow-x: auto; margin-bottom: 16px; scrollbar-width: none; }
.range-tabs::-webkit-scrollbar { display: none; }
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 18px; }
.stat {
  padding: 16px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.stat .k { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 1.3px; color: var(--text-dim); }
.stat .v { font-family: var(--font-display); font-size: 1.85rem; margin-top: 4px; }
.stat .v.sm { font-size: 1.3rem; }
.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; margin-bottom: 14px;
}
.panel h3 { font-size: 1.05rem; text-transform: uppercase; margin-bottom: 12px; }
.panel:empty { display: none; }
.bar-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: center; padding: 7px 0; }
.bar-row .lbl { font-size: 0.94rem; }
.bar-row .val { font-weight: 700; font-variant-numeric: tabular-nums; }
.bar-track { grid-column: 1 / -1; height: 7px; background: var(--surface-3); border-radius: 4px; overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: 4px; transform-origin: left; }
.rank { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.rank:last-child { border-bottom: 0; }
.rank .n { color: var(--text-faint); width: 26px; flex: 0 0 26px; }
.rank .l { flex: 1; }
.rank .r { font-weight: 700; font-variant-numeric: tabular-nums; }
.hours-chart { width: 100%; height: auto; display: block; }

/* ================================================================= DATES */
.event-list { display: grid; gap: 10px; }
.event-row {
  display: flex; gap: 12px; align-items: center;
  padding: 14px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.event-row.past { opacity: 0.55; }
.event-row .when { text-align: center; min-width: 54px; }
.event-row .when .d { font-family: var(--font-display); font-size: 1.5rem; line-height: 1; }
.event-row .when .m { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 1px; color: var(--text-dim); }
.event-row .info { flex: 1; min-width: 0; }
.event-row .nm { font-weight: 600; }
.event-row .meta { font-size: 0.86rem; color: var(--text-dim); }
.pill {
  display: inline-block; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 1px;
  padding: 2px 7px; border-radius: 6px; border: 1px solid var(--line); color: var(--text-dim);
  margin-left: 6px;
}
.pill.live { color: var(--good); border-color: rgba(99, 192, 131, 0.45); }

/* ================================================================== TABS */
.tabbar {
  /* Pinned the way Forge pins its bottom panel, rather than riding at the end of
     the body flex column. A flex child lands at the bottom of the BODY BOX; a
     fixed element with `bottom: var(--vhgap)` lands at the bottom of what is
     actually VISIBLE. Those are the same place only when the layout viewport and
     the visible viewport agree, and on an installed iOS PWA they do not — which
     is the whole bug. Forge has been doing it this way and reaching the bottom of
     the screen on the same phone all along.
     `#app` gets matching bottom padding below so the last row of content is not
     hidden behind this. */
  position: fixed; left: 0; right: 0; bottom: var(--vhgap, 0px);
  display: flex; background: var(--surface); border-top: 1px solid var(--line);
  padding-bottom: var(--tabbar-pad); flex-shrink: 0; z-index: 40;
}
.tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  min-height: 60px; padding: 8px 4px 2px; border: 0; background: none;
  color: var(--text-faint); font-size: 0.72rem; font-weight: 600; cursor: pointer;
  position: relative; transition: color 160ms ease;
}
.tab svg { width: 23px; height: 23px; }
.tab[aria-selected="true"] { color: var(--accent); }
.tab-badge {
  position: absolute; top: 5px; left: 50%; margin-left: 7px;
  min-width: 19px; height: 19px; padding: 0 5px; border-radius: 10px;
  background: var(--accent); color: var(--accent-ink);
  font-size: 0.68rem; font-style: normal; font-weight: 700;
  display: grid; place-items: center;
}

/* ================================================================ SHEETS */
.sheet-scrim {
  position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); z-index: 50;
  opacity: 1; transition: opacity 240ms var(--ease-out);
}
.sheet-scrim.closing { opacity: 0; }
.sheet {
  position: fixed; left: 0; right: 0; bottom: var(--vhgap, 0px); z-index: 60;
  display: flex; flex-direction: column;
  max-height: 92vh; background: var(--surface-2);
  border-radius: 20px 20px 0 0; border-top: 1px solid var(--line);
  transform: translateY(0);
  transition: transform 300ms var(--ease-drawer);
}
.sheet.closing { transform: translateY(100%); }
@starting-style { .sheet { transform: translateY(100%); } }
.sheet-grab { width: 40px; height: 4px; border-radius: 2px; background: var(--surface-3); margin: 9px auto 2px; }
.sheet-head { display: flex; align-items: center; justify-content: space-between; padding: 6px 12px 6px 18px; }
.sheet-head h2 { font-size: 1.25rem; text-transform: uppercase; }
.sheet-body { overflow-y: auto; padding: 6px 18px 12px; -webkit-overflow-scrolling: touch; }
.sheet-foot { padding: 12px 18px calc(16px + var(--tabbar-pad)); border-top: 1px solid var(--line); }
@media (min-width: 820px) {
  .sheet { left: 50%; right: auto; bottom: auto; top: 50%; width: 560px;
           transform: translate(-50%, -50%); border-radius: 20px; max-height: 86vh; }
  .sheet.closing { transform: translate(-50%, -46%); opacity: 0; }
  @starting-style { .sheet { transform: translate(-50%, -46%); opacity: 0; } }
  .sheet-grab { display: none; }
}

.mod-group { margin-bottom: 20px; }
.mod-group-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 9px; }
.mod-group-head h3 { font-size: 1rem; text-transform: uppercase; }
.mod-group-head .count { font-size: 0.82rem; color: var(--text-dim); }
.mod-group-head .count.over { color: var(--warn); }
.mod-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); grid-auto-rows: var(--tap); gap: 8px; }
.mod-btn {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px;
  height: 100%; min-width: 0; padding: 0 12px; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 160ms ease, border-color 160ms ease;
}
.mod-btn:active { transform: scale(0.97); }
.mod-btn[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.mod-btn .nm { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 1.2; }
.mod-btn .up { font-size: 0.78rem; font-weight: 600; line-height: 1.1; font-variant-numeric: tabular-nums; }
.mod-btn .up:empty { display: none; }
.mod-btn.is-off { opacity: 0.4; }
.qty-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin: 6px 0 18px; }
.qty-ctl { display: flex; align-items: center; gap: 14px; }
.qty-ctl button { width: var(--tap); height: var(--tap); border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface); color: var(--text); font-size: 1.4rem; cursor: pointer; transition: transform 160ms var(--ease-out); }
.qty-ctl button:active { transform: scale(0.94); }
.qty-ctl .q { font-family: var(--font-display); font-size: 1.5rem; min-width: 32px; text-align: center; }
.sheet-list { display: grid; gap: 8px; }
.sheet-row {
  display: flex; align-items: center; gap: 12px; width: 100%;
  min-height: var(--tap); padding: 10px 14px; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--text); cursor: pointer;
  transition: transform 160ms var(--ease-out);
}
.sheet-row:active { transform: scale(0.98); }
.sheet-row[aria-pressed="true"] { border-color: var(--accent); background: rgba(217, 144, 63, 0.14); }
.sheet-row .grow { flex: 1; min-width: 0; }
.sheet-row .sub { font-size: 0.84rem; color: var(--text-dim); }
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.warn-note {
  display: flex; gap: 10px; padding: 12px 14px; margin-bottom: 16px;
  background: rgba(232, 176, 75, 0.10); border: 1px solid rgba(232, 176, 75, 0.35);
  border-radius: var(--radius); font-size: 0.9rem; color: var(--text);
}
.section-label {
  font-size: 0.74rem; text-transform: uppercase; letter-spacing: 1.4px;
  color: var(--text-faint); margin: 20px 0 8px;
}

/* ================================================================ TOASTS */
.toast {
  position: fixed; left: 50%; bottom: calc(88px + var(--tabbar-pad) + var(--vhgap, 0px));
  transform: translateX(-50%); z-index: 80;
  padding: 12px 20px; border-radius: 999px;
  background: var(--text); color: var(--bg); font-weight: 600;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.toast.closing { opacity: 0; transform: translateX(-50%) translateY(8px); }
@starting-style { .toast { opacity: 0; transform: translateX(-50%) translateY(8px); } }

/* The one animation that earns its keep: after a sale, the person at the counter
   needs the order number readable from arm's length while they hand the phone over. */
.ticket-flash {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
  background: rgba(22, 17, 14, 0.86);
  transition: opacity 200ms var(--ease-out);
}
.ticket-flash.closing { opacity: 0; }
.ticket-card {
  display: grid; justify-items: center; gap: 2px;
  padding: 34px 54px; background: var(--accent); color: var(--accent-ink);
  border-radius: 22px;
  transform: scale(1);
  transition: transform 260ms var(--ease-out);
}
.ticket-flash.closing .ticket-card { transform: scale(0.96); }
@starting-style { .ticket-card { transform: scale(0.94); } }
.ticket-label { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 2px; }
.ticket-no { font-family: var(--font-display); font-size: 5rem; line-height: 1; }
.ticket-total { font-weight: 700; font-size: 1.3rem; }
.ticket-extra { margin-top: 8px; font-family: var(--font-display); font-size: 1.6rem; }

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

/* ======================================================= SIGN IN, PASSWORDS */
/* One login per person since 2026-10-16 (lib/auth.js). Shared by the sign-in screen, set-password.html and
   Settings, Your password. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { padding-right: 76px; }
.pw-show {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  min-height: 44px; padding: 0 12px; border: 0; border-radius: 10px;
  background: transparent; color: var(--text-dim); font-size: 0.88rem; font-weight: 600; cursor: pointer;
}
.login-switch { display: block; margin: 14px auto 0; }
.login-ok { color: var(--good); font-size: 0.92rem; margin-bottom: 12px; }
.login-sub.login-sub-plain { text-transform: none; letter-spacing: 0; font-size: 1rem; }
