/* ==========================================================================
   Horton Wholesale — design system
   Derived from the approved mockups, with the brand navy replacing the
   original forest green so the logo sits naturally in the header.

   Light is the designed look: warm ivory ground, navy, gold.
   Dark is a true counterpart, not an inversion — the warmth is carried by
   desaturated umber-greys rather than neutral slate, so it still reads Horton.
   ========================================================================== */

/* ---------- tokens ------------------------------------------------------- */
:root {
  --navy:        #011936;
  --navy-2:      #0a2748;
  --navy-3:      #143458;
  --gold:        #c19a4e;
  --gold-soft:   #d8b878;
  --gold-dim:    #a8843f;
  --sage:        #c0dfa1;   /* logo green — fills and badges only, never text on light */
  --rose:        #c08a72;

  --ink:         #241f18;
  --ink-2:       #4a4238;
  --muted:       #847c6d;
  --faint:       #a79f8f;
  --line:        #e7dfce;
  --line-2:      #f0e9dc;
  --card:        #fffdf8;
  --card-2:      #fbf8f0;
  --page:        #f6f1e6;

  --ok:          #3f6b4b;
  --ok-bg:       rgba(63,107,75,.12);
  --warn:        #bf6a2a;
  --warn-bg:     rgba(191,106,42,.13);
  --danger:      #b0503b;
  --danger-bg:   rgba(176,80,59,.10);
  --info:        #3b6ea5;
  --info-bg:     rgba(59,110,165,.12);

  --shadow-card: 0 14px 34px -22px rgba(80,66,40,.32);
  --shadow-tile: 0 6px 16px -14px rgba(80,66,40,.5);
  --shadow-pop:  0 40px 90px -20px rgba(30,24,16,.55);
  --shadow-btn:  0 16px 30px -14px rgba(1,25,54,.45);

  --r-lg: 18px;
  --r-md: 13px;
  --r-sm: 11px;
  --r-pill: 100px;

  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --serif: 'Playfair Display', Georgia, serif;

  --page-bg:
    radial-gradient(1200px 600px at 85% -10%, #fbf7ee 0%, transparent 60%),
    linear-gradient(160deg, #f6f1e6 0%, #efe7d7 100%);
}

/* Dark: warm, not slate. Ink becomes parchment; the ground is a deep umber-navy. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --navy:      #7fa8d8;
    --navy-2:    #6d97c8;
    --navy-3:    #5b86b6;
    --gold:      #d8b878;
    --gold-soft: #e6cd9a;
    --gold-dim:  #b99a5e;

    --ink:       #f2ece0;
    --ink-2:     #d6cec0;
    --muted:     #a49a89;
    --faint:     #7d7466;
    --line:      #35302a;
    --line-2:    #2b2722;
    --card:      #232019;
    --card-2:    #1c1a15;
    --page:      #151310;

    --ok:        #7fbc90;
    --ok-bg:     rgba(127,188,144,.14);
    --warn:      #e0ad5c;
    --warn-bg:   rgba(224,173,92,.15);
    --danger:    #e08c76;
    --danger-bg: rgba(224,140,118,.14);
    --info:      #85b0dd;
    --info-bg:   rgba(133,176,221,.14);

    --shadow-card: 0 14px 34px -22px rgba(0,0,0,.8);
    --shadow-tile: 0 6px 16px -12px rgba(0,0,0,.7);
    --shadow-pop:  0 40px 90px -20px rgba(0,0,0,.85);
    --shadow-btn:  0 16px 30px -16px rgba(0,0,0,.7);

    --page-bg:
      radial-gradient(1100px 560px at 85% -10%, #201d17 0%, transparent 62%),
      linear-gradient(160deg, #17150f 0%, #100e0b 100%);
  }
}

/* Explicit choice always wins over the device setting, in both directions. */
:root[data-theme="dark"] {
  --navy:#7fa8d8; --navy-2:#6d97c8; --navy-3:#5b86b6;
  --gold:#d8b878; --gold-soft:#e6cd9a; --gold-dim:#b99a5e;
  --ink:#f2ece0; --ink-2:#d6cec0; --muted:#a49a89; --faint:#7d7466;
  --line:#35302a; --line-2:#2b2722; --card:#232019; --card-2:#1c1a15; --page:#151310;
  --ok:#7fbc90; --ok-bg:rgba(127,188,144,.14);
  --warn:#e6944f; --warn-bg:rgba(230,148,79,.16);
  --danger:#e08c76; --danger-bg:rgba(224,140,118,.14);
  --info:#85b0dd; --info-bg:rgba(133,176,221,.14);
  --shadow-card:0 14px 34px -22px rgba(0,0,0,.8);
  --shadow-tile:0 6px 16px -12px rgba(0,0,0,.7);
  --shadow-pop:0 40px 90px -20px rgba(0,0,0,.85);
  --shadow-btn:0 16px 30px -16px rgba(0,0,0,.7);
  --page-bg:
    radial-gradient(1100px 560px at 85% -10%, #201d17 0%, transparent 62%),
    linear-gradient(160deg, #17150f 0%, #100e0b 100%);
}

/* ---------- reset -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--page-bg);
  background-attachment: fixed;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--navy); text-decoration: none; }
a:hover { text-decoration: underline; }

.serif { font-family: var(--serif); }
.tnum  { font-variant-numeric: tabular-nums; }

::selection { background: rgba(193,154,78,.28); }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 4px;
}

.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;
}

/* ---------- app shell ---------------------------------------------------- */
.app { min-height: 100vh; display: flex; flex-direction: column; }
/* Only the register pins itself to the viewport; every other page scrolls
   normally. 100dvh rather than 100vh so mobile browser chrome doesn't crop it. */
.app:has(.main--flush) { height: 100dvh; min-height: 0; overflow: hidden; }

.topbar {
  display: flex; align-items: center; gap: 20px;
  padding: 14px 26px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--card) 72%, transparent);
  backdrop-filter: saturate(140%) blur(12px);
  position: sticky; top: 0; z-index: 30;
}

.brand { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.brand__logo { height: 30px; width: auto; }
.brand__logo--dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn--primary { background: linear-gradient(180deg, #34649c, #274f80); color: #f4efe2; }
  :root:not([data-theme="light"]) .btn--primary:hover { background: linear-gradient(180deg, #3b6fab, #2b578c); }
  :root:not([data-theme="light"]) .brand__logo--light { display: none; }
  :root:not([data-theme="light"]) .brand__logo--dark  { display: block; }
}
:root[data-theme="dark"] .btn--primary { background: linear-gradient(180deg, #34649c, #274f80); color: #f4efe2; }
:root[data-theme="dark"] .btn--primary:hover { background: linear-gradient(180deg, #3b6fab, #2b578c); }
:root[data-theme="dark"] .brand__logo--light { display: none; }
:root[data-theme="dark"] .brand__logo--dark  { display: block; }
:root[data-theme="light"] .brand__logo--light { display: block; }
:root[data-theme="light"] .brand__logo--dark  { display: none; }
.brand__mark {
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--navy); color: var(--gold-soft);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 18px; font-weight: 700;
}
.brand__name { font-family: var(--serif); font-size: 18px; font-weight: 600; color: var(--navy); }

.nav { display: flex; gap: 2px; flex: 1; flex-wrap: nowrap; min-width: 0; }
.nav__extras { display: none; }   /* drawer only — duplicates the header cluster */

/* Hamburger — hidden until the nav actually stops fitting. */
.nav-toggle {
  display: none; width: 40px; height: 40px; flex-shrink: 0;
  align-items: center; justify-content: center;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-sm); cursor: pointer; padding: 0;
}
.nav-toggle:hover { background: var(--card-2); }
.nav-toggle__bars { display: block; width: 17px; }
.nav-toggle__bars span {
  display: block; height: 2px; border-radius: 2px; background: var(--ink);
  transition: transform .2s cubic-bezier(.2,.7,.3,1), opacity .15s;
}
.nav-toggle__bars span + span { margin-top: 4px; }
/* Bars fold into an X while the drawer is open. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
.nav__link {
  padding: 8px 12px; border-radius: var(--r-pill);
  font-size: 13.5px; font-weight: 600; color: var(--muted);
  white-space: nowrap; transition: background .12s, color .12s;
}
.nav__link:hover { background: var(--card-2); color: var(--ink); text-decoration: none; }
.nav__link.is-active { background: var(--navy); color: #f4efe2; }

.who { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.who__user {
  display: flex; align-items: center; gap: 10px; padding: 3px 10px 3px 3px;
  border-radius: var(--r-pill); color: inherit; border: 1px solid transparent;
}
.who__user:hover { background: var(--card-2); border-color: var(--line); text-decoration: none; }
.who__user .who__meta { text-align: left; }
.who__user .who__name, .who__user .who__role { display: block; }
.helddrop__meta { display: block; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-scrim { display: none; }
.who__meta { text-align: right; line-height: 1.25; }
.who__name { font-size: 13.5px; font-weight: 600; }
.who__role { font-size: 11px; color: var(--muted); letter-spacing: .04em; text-transform: capitalize; }
.avatar {
  width: 38px; height: 38px; border-radius: 50%;
  background: linear-gradient(150deg, var(--gold-soft), var(--gold-dim));
  display: flex; align-items: center; justify-content: center;
  /* Fixed dark ink, not --navy: that token lightens in dark mode and the
     initials washed out against the gold. */
  font-weight: 700; color: #2a2115; font-size: 13.5px; flex-shrink: 0;
}

.main { flex: 1; padding: 26px; width: 100%; max-width: 1600px; margin: 0 auto; }
.main--flush {
  /* The register is a fixed-height screen: the catalog and the ticket scroll
     inside themselves so the totals and the pay button never leave the view.
     Chasing a Pay button down the page is exactly the friction a counter
     cannot afford. */
  padding: 18px 22px; max-width: none;
  display: flex; flex-direction: column;
  /* min-height:0 matters — a flex item defaults to min-height:auto, which grows
     it to fit its content and would push the totals and Pay button off-screen.
     The height comes from the flex parent rather than a hard-coded topbar
     offset, so it survives the header changing height. */
  flex: 1; min-height: 0; overflow: hidden;
}
.main--flush ~ .app-footer { display: none; }

.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; margin-bottom: 22px; flex-wrap: wrap;
}
.page-title { font-family: var(--serif); font-size: 27px; font-weight: 700; color: var(--ink); line-height: 1.15; }
.page-sub { font-size: 13.5px; color: var(--muted); margin-top: 4px; }

.app-footer {
  padding: 18px 26px 26px; text-align: center;
  font-size: 11.5px; color: var(--faint);
  display: flex; align-items: center; justify-content: center; gap: 8px;
}
.app-footer__brand { font-weight: 600; }
.app-footer__version { font-variant-numeric: tabular-nums; }

/* ---------- cards -------------------------------------------------------- */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.card__pad { padding: 20px 22px; }
.card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 17px 22px; border-bottom: 1px solid var(--line);
}
.card__title { font-size: 15px; font-weight: 700; }
.card__sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.grid { display: grid; gap: 18px; }
.grid--2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
@media (max-width: 1100px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0,1fr)); } .grid--3 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  /* A lone last card fills the row instead of leaving a hole beside it. */
  .grid--3 > :last-child:nth-child(odd), .grid--4 > :last-child:nth-child(odd) { grid-column: span 2; }
}
@media (max-width: 720px)  { .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; } }

/* ---------- stat tiles --------------------------------------------------- */
.stat { padding: 18px 20px; }
.stat__label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.stat__value {
  font-family: var(--sans); font-size: 30px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  color: var(--navy); margin-top: 8px; line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.stat__value--sm { font-size: 24px; }
.stat__foot { font-size: 12px; color: var(--muted); margin-top: 7px; }

.hero { padding: 26px 28px; }
.hero__value {
  font-family: var(--sans); font-size: 50px; font-weight: 700; letter-spacing: -.02em;
  color: var(--navy); line-height: 1; font-variant-numeric: tabular-nums;
}
@media (max-width: 720px) { .hero__value { font-size: 40px; } }

.delta { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600;
  padding: 3px 10px; border-radius: var(--r-pill); }
.delta--up   { color: var(--ok); background: var(--ok-bg); }
.delta--down { color: var(--danger); background: var(--danger-bg); }
.delta--flat { color: var(--muted); background: var(--card-2); }

/* ---------- buttons ------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--line); background: var(--card);
  border-radius: var(--r-sm); padding: 10px 16px;
  font-size: 13.5px; font-weight: 600; color: var(--ink);
  cursor: pointer; transition: background .12s, border-color .12s, transform .06s;
  text-decoration: none; white-space: nowrap;
}
.btn:hover { background: var(--card-2); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled], .btn.is-disabled { opacity: .5; cursor: not-allowed; }

.btn--primary {
  background: linear-gradient(180deg, var(--navy-3), var(--navy));
  color: #f4efe2; border: 0; box-shadow: var(--shadow-btn);
}
.btn--primary:hover { background: linear-gradient(180deg, var(--navy-2), var(--navy)); }

.btn--gold { background: linear-gradient(180deg, var(--gold-soft), var(--gold)); color: #2a2115; border: 0; }
.btn--ok   { background: linear-gradient(180deg, #498a5f, #2f6043); color: #f4efe2; border: 0; box-shadow: 0 16px 30px -14px rgba(47,96,67,.55); }
.btn--danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); background: var(--card); }
.btn--danger:hover { background: var(--danger-bg); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn--ghost:hover { background: var(--card-2); color: var(--ink); }

.btn--lg { padding: 15px 22px; font-size: 15px; border-radius: var(--r-md); }
.btn--sm { padding: 6px 11px; font-size: 12.5px; border-radius: 9px; }
.btn--block { width: 100%; }
.btn--xl { padding: 17px; font-size: 16px; font-weight: 700; border-radius: 14px; width: 100%; }

.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---------- forms -------------------------------------------------------- */
.field { margin-bottom: 17px; }
.label {
  display: block; font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); font-weight: 700; margin-bottom: 8px;
}
.input, .select, .textarea {
  width: 100%; border: 1.5px solid var(--line); background: var(--card-2);
  border-radius: var(--r-md); padding: 11px 14px; font-size: 14.5px;
  color: var(--ink); transition: border-color .12s, background .12s;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--gold); background: var(--card);
}
.input::placeholder { color: var(--faint); }
.textarea { min-height: 92px; resize: vertical; }
.select { appearance: none; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(1em + 2px), calc(100% - 14px) calc(1em + 2px);
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 38px; }
.hint { font-size: 11.5px; color: var(--muted); margin-top: 7px; }
.error-text { font-size: 12px; color: var(--danger); margin-top: 6px; font-weight: 500; }
.input.has-error { border-color: var(--danger); }

.check { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; padding: 7px 0; }
.check input { width: 17px; height: 17px; margin-top: 1px; accent-color: var(--navy); cursor: pointer; flex-shrink: 0; }
.check__body { flex: 1; }
.check__label { font-size: 13.5px; font-weight: 600; }
.check__hint { font-size: 12px; color: var(--muted); margin-top: 1px; }

.search-bar {
  display: flex; align-items: center; gap: 12px;
  border: 1.5px solid var(--line); background: var(--card-2);
  border-radius: var(--r-md); padding: 0 16px; height: 52px;
}
.search-bar:focus-within { border-color: var(--gold); background: var(--card); }
.search-bar svg { flex-shrink: 0; color: var(--muted); }
.search-bar input { border: 0; background: transparent; outline: 0; font-size: 15.5px; width: 100%; }
.search-bar__clear {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 0; background: var(--line-2); color: var(--muted); cursor: pointer;
  transition: background .12s, color .12s, transform .1s;
}
.search-bar__clear:hover { background: var(--line); color: var(--ink); }
.search-bar__clear:active { transform: scale(.92); }
.search-bar__clear[hidden] { display: none; }

.switch {
  width: 42px; height: 24px; border-radius: var(--r-pill); background: var(--line);
  position: relative; flex-shrink: 0; cursor: pointer; border: 0; transition: background .15s;
}
.switch::after {
  content: ""; position: absolute; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; top: 3px; left: 3px; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: left .15s;
}
.switch[aria-checked="true"] { background: var(--ok); }
.switch[aria-checked="true"]::after { left: 21px; }

.stepper { display: flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r-md); width: fit-content; overflow: hidden; }
.stepper button { width: 48px; height: 46px; border: 0; background: var(--card-2); font-size: 21px; color: var(--navy); cursor: pointer; }
.stepper button:hover { background: var(--line-2); }
.stepper .val { width: 64px; text-align: center; font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }

.pricefield { display: flex; align-items: center; gap: 5px; border: 1.5px solid var(--gold); background: var(--card); border-radius: var(--r-md); padding: 0 15px; height: 50px; }
.pricefield .cur { font-size: 16px; color: var(--muted); font-weight: 600; }
.pricefield input { border: 0; outline: 0; background: transparent; font-size: 18px; font-weight: 700; width: 100%; font-variant-numeric: tabular-nums; }

/* Segmented radio group — two or three exclusive choices read better as one
   control than as a dropdown you have to open to see the options. */
.tenders { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tenders .btn { justify-content: center; }
.segmented { display: inline-flex; gap: 3px; padding: 3px; background: var(--card-2);
  border: 1px solid var(--line); border-radius: var(--r-md); flex-wrap: wrap; }
.segmented--wrap { flex-wrap: wrap; }
.segmented--wrap .segmented__opt span { padding: 10px 18px; font-size: 14px; }
.segmented__opt { position: relative; }
.segmented__opt input { position: absolute; opacity: 0; pointer-events: none; }
.segmented__opt span {
  display: block; padding: 8px 15px; border-radius: 9px; cursor: pointer;
  font-size: 13.5px; font-weight: 600; color: var(--muted); white-space: nowrap;
  transition: background .12s, color .12s;
}
.segmented__opt input:checked + span { background: var(--navy); color: #f4efe2; }
.segmented__opt input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 2px; }
.segmented__opt:hover input:not(:checked) + span { color: var(--ink); background: var(--line-2); }
@media (max-width: 560px) { .segmented { width: 100%; } .segmented__opt { flex: 1; }
  .segmented__opt span { text-align: center; padding: 9px 8px; } }

/* ---------- chips & badges ---------------------------------------------- */
.chips { display: flex; gap: 9px; flex-wrap: wrap; }
.chip {
  font-size: 12.5px; font-weight: 600; padding: 7px 15px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--card); color: var(--muted);
  cursor: pointer; transition: .12s; text-decoration: none;
}
.chip:hover { border-color: var(--gold); color: var(--ink); text-decoration: none; }
.chip.is-on { background: var(--navy); color: #f4efe2; border-color: var(--navy); }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 6px; white-space: nowrap;
}
.badge--ok     { color: var(--ok);     background: var(--ok-bg); }
.badge--warn   { color: var(--warn);   background: var(--warn-bg); border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent); }
.badge--danger { color: var(--danger); background: var(--danger-bg); }
.badge--info   { color: var(--info);   background: var(--info-bg); }
.badge--muted  { color: var(--muted);  background: var(--card-2); }

/* ---------- tags: matte glass pills -------------------------------------
   Two deliberately different objects, not two colours of the same thing.

   .tag      descriptive vocabulary (rose, red, wedding) — matte frosted glass,
             recessive, many per product.
   .tag--qb  the QuickBooks category bucket — exactly ONE per product and it
             decides where the money lands. Given real presence: warmer glass,
             a gold rim, a leading diamond, and a soft glow. It should be
             obvious at a glance which pill is load-bearing.
   ------------------------------------------------------------------------ */
.tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
  padding: 4px 12px; border-radius: var(--r-pill);
  color: var(--ink-2); text-decoration: none;
  /* matte glass: soft translucent body, hairline rim, inner top highlight */
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--card) 88%, transparent),
                            color-mix(in srgb, var(--card-2) 78%, transparent));
  border: 1px solid color-mix(in srgb, var(--line) 88%, transparent);
  backdrop-filter: blur(9px) saturate(125%);
  -webkit-backdrop-filter: blur(9px) saturate(125%);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 62%, transparent),
    inset 0 -1px 0 color-mix(in srgb, var(--line) 45%, transparent),
    0 1px 2px rgba(60,48,28,.06);
  transition: transform .14s cubic-bezier(.2,.7,.3,1), box-shadow .14s, border-color .14s;
}
a.tag:hover, button.tag:hover {
  transform: translateY(-1px); border-color: var(--gold); text-decoration: none;
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 70%, transparent),
              0 5px 12px -6px rgba(60,48,28,.32);
}
:root[data-theme="dark"] .tag {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 8%, transparent),
              inset 0 -1px 0 rgba(0,0,0,.3), 0 1px 2px rgba(0,0,0,.4);
}

.tag--qb {
  font-weight: 700; letter-spacing: .02em; color: var(--gold-dim);
  padding: 4px 13px 4px 11px;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--gold) 22%, transparent),
                            color-mix(in srgb, var(--gold) 9%,  transparent));
  border-color: color-mix(in srgb, var(--gold) 62%, transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 55%, transparent),
    inset 0 0 14px color-mix(in srgb, var(--gold) 14%, transparent),
    0 2px 7px -3px color-mix(in srgb, var(--gold) 45%, transparent);
}
.tag--qb::before {
  content: "◆"; font-size: 7.5px; opacity: .85; transform: translateY(-.5px);
}
:root[data-theme="dark"] .tag--qb {
  color: var(--gold-soft);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 12%, transparent),
              inset 0 0 16px color-mix(in srgb, var(--gold) 16%, transparent),
              0 2px 8px -4px rgba(0,0,0,.6);
}
a.tag--qb:hover, button.tag--qb:hover {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 60%, transparent),
              inset 0 0 18px color-mix(in srgb, var(--gold) 20%, transparent),
              0 6px 14px -6px color-mix(in srgb, var(--gold) 55%, transparent);
}

.tag--sm { font-size: 10.5px; padding: 2px 9px; }
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; }

/* Customer note on the register — visible without being loud, and one tap to
   edit. Empty state invites the first note rather than hiding the feature. */
.custnote {
  display: flex; align-items: flex-start; gap: 9px; width: 100%;
  text-align: left; cursor: pointer; margin-bottom: 14px;
  padding: 10px 12px; border-radius: var(--r-sm); font-size: 12.5px; line-height: 1.45;
  color: var(--ink-2); background: color-mix(in srgb, var(--gold) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 30%, transparent);
}
.custnote:hover { background: color-mix(in srgb, var(--gold) 16%, transparent); }
.custnote svg { flex-shrink: 0; color: var(--gold-dim); margin-top: 1px; }
.custnote__text { flex: 1; }
.custnote--empty { color: var(--muted); background: transparent; border-style: dashed; }
.custnote--empty svg { color: var(--faint); }

/* Inline price editing: a tight field that keeps the column readable as a
   column, plus a bar that only offers Save once something actually changed. */
.priceedit { display: inline-flex; align-items: center; gap: 3px; justify-content: flex-end; }
.priceedit__cur { color: var(--muted); font-size: 12.5px; }
.priceedit__input {
  width: 96px; padding: 6px 8px; font-size: 13.5px; text-align: right;
  font-variant-numeric: tabular-nums;
}
.priceedit__input.is-changed {
  border-color: var(--gold); background: color-mix(in srgb, var(--gold) 12%, var(--card));
  font-weight: 700;
}
.pricebar {
  position: sticky; bottom: 0; z-index: 10;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 13px 20px; border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--card) 94%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}
.pricebar__count { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.pricebar__count.is-active { color: var(--gold-dim); }
:root[data-theme="dark"] .pricebar__count.is-active { color: var(--gold); }

/* Create-a-product, folded away until wanted — most items get matched to
   something that already exists. */
.resolve-new { margin-top: 12px; border-top: 1px solid var(--line-2); padding-top: 10px; }
.resolve-new__toggle {
  cursor: pointer; list-style: none; font-size: 12.5px; font-weight: 600;
  color: var(--navy); display: inline-flex; align-items: center; gap: 6px;
}
.resolve-new__toggle::-webkit-details-marker { display: none; }
.resolve-new__toggle::before { content: "+"; font-size: 15px; line-height: 1; }
.resolve-new[open] .resolve-new__toggle::before { content: "\2212"; }
.resolve-new__toggle:hover { text-decoration: underline; text-underline-offset: 3px; }
.resolve-new__body {
  margin-top: 12px; padding: 14px; border-radius: var(--r-md);
  background: var(--card-2); border: 1px solid var(--line);
}
.resolve-new__grid { display: grid; grid-template-columns: 2fr 1fr 1.2fr; gap: 12px; align-items: start; }
.resolve-new__name { display: flex; gap: 8px; }
.resolve-new__name .input { flex: 1; min-width: 0; }
/* Big enough to read what was typed on a tablet: 16px text also stops iOS
   zooming the page when the field is tapped. */
.resolve-new__body .input, .resolve-new__body .select { font-size: 16px; min-height: 46px; padding: 10px 13px; }
.resolve-new__tidy { flex: none; white-space: nowrap; min-height: 46px; padding: 0 14px; font-size: 13.5px; font-weight: 600;
  color: var(--navy); border: 1.5px solid var(--navy); background: var(--card); }
.resolve-new__tidy:hover { background: color-mix(in srgb, var(--navy) 8%, var(--card)); }
/* Inside a sheet or on a tablet the three columns squeeze the name to nothing:
   the name takes the whole first row, price and category share the second. */
@media (max-width: 1100px) {
  .resolve-new__grid { grid-template-columns: 1fr 1.2fr; }
  .resolve-new__grid > :first-child { grid-column: 1 / -1; }
}
@media (max-width: 560px) { .resolve-new__grid { grid-template-columns: 1fr; } }
.modal .resolve-new__grid { grid-template-columns: 1fr 1.2fr; }
.modal .resolve-new__grid > :first-child { grid-column: 1 / -1; }

/* Review row: the whole thing is the affordance, because the useful action is
   "show me this on its ticket", not "edit this string". */
.reviewrow {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 12px 13px; margin-bottom: 8px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-sm);
  transition: border-color .13s, transform .13s, background .13s;
}
.reviewrow:hover {
  border-color: var(--warn); transform: translateX(2px);
  background: color-mix(in srgb, var(--warn) 7%, var(--card));
}
.reviewrow__what { display: block; font-size: 13.5px; font-weight: 600; color: var(--ink); }
.reviewrow__meta { display: block; font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.reviewrow__go {
  display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0;
  font-size: 11.5px; font-weight: 700; color: var(--warn); white-space: nowrap;
}

/* Inside a modal the receipt block is already framed by the dialog. */
.modal .reviewgroup { box-shadow: none; border: 0; background: transparent; }
.modal .reviewgroup .card__head { padding: 0 0 12px; }
.modal .reviewgroup .card__pad { padding: 0; }

/* Compact review row on the dashboard — heading, then the controls. */
.reviewquick { padding: 11px 0; border-bottom: 1px solid var(--line-2); }
.reviewquick:last-of-type { border-bottom: 0; }
.reviewquick__what { margin-bottom: 9px; font-size: 13.5px; }
.reviewquick .resolve-line { padding: 0; border-bottom: 0; grid-template-columns: 1fr; }
.reviewquick .resolve-line__actions { justify-content: flex-start; }
.reviewquick .select--compact { min-width: 150px; }

/* ---------- signature pad ------------------------------------------------
   Sized for a fingertip on a tablet, with a ruled baseline so people sign on
   the line rather than wherever they land. */
.sigpad {
  position: relative; height: 230px; border-radius: var(--r-md);
  background: #fffdf8; border: 1.5px dashed var(--line); overflow: hidden;
}
.sigpad__canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  cursor: crosshair;
  /* Without this a finger drag scrolls the page instead of drawing — the one
     thing that makes a signature pad useless on a tablet. */
  touch-action: none;
}
.sigpad__hint {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 20px; color: #cfc6b4; pointer-events: none;
}
.sigpad__hint[hidden] { display: none; }
.sigpad__baseline {
  position: absolute; left: 8%; right: 8%; bottom: 54px; height: 1px;
  background: repeating-linear-gradient(90deg, #d9d0bd 0 8px, transparent 8px 14px);
  pointer-events: none;
}
/* The captured image is dark ink; keep the plate light in dark mode so it
   stays legible rather than becoming black-on-black. */
:root[data-theme="dark"] .sigpad { background: #f6f2e8; border-color: #4a443b; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sigpad { background: #f6f2e8; border-color: #4a443b; }
}

.sigshow {
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 10px; text-align: center;
}
.sigshow img { max-height: 90px; margin: 0 auto; }
:root[data-theme="dark"] .sigshow { background: #f6f2e8; border-color: #4a443b; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sigshow { background: #f6f2e8; border-color: #4a443b; }
}

.custlist { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; max-height: 44vh; overflow: auto; }
.custlist__item { display: flex; justify-content: space-between; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--card); color: var(--ink); font-family: inherit; font-size: 14px; cursor: pointer; }
.custlist__item:hover { border-color: var(--gold); background: var(--card-2); }
.custlist__item.is-current { border-color: var(--navy); }
.custlist__name { font-weight: 600; }
.custlist__meta { font-size: 12px; color: var(--muted); white-space: nowrap; }
.custlist__none { padding: 12px; font-size: 13px; }
kbd { display: inline-block; padding: 2px 7px; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 6px; background: var(--card-2); font-family: var(--sans); font-size: 12px; font-weight: 600; }
tr.is-dim td { opacity: .55; }
.table--compact td, .table--compact th { padding: 7px 10px; font-size: 12.5px; }

/* ---------- month calendar ----------------------------------------------- */
.cal { display: grid; grid-template-columns: repeat(7, minmax(0,1fr)); border-top: 1px solid var(--line); }
.cal__dow { padding: 8px 10px; font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--line); }
.cal__cell { min-height: 108px; padding: 8px; border-right: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2); display: flex; flex-direction: column; gap: 4px; }
.cal__cell:nth-child(7n) { border-right: 0; }
.cal__cell--pad { background: var(--card-2); }
.cal__cell.is-past { background: var(--card-2); }
.cal__cell.is-past .cal__num { color: var(--faint); }
.cal__cell[data-cal-day] { cursor: pointer; }
.cal__cell[data-cal-day]:hover { background: var(--card-2); }
.cal__cell.is-today .cal__num { background: var(--navy); color: #f4efe2; }
.cal__num { width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; font-variant-numeric: tabular-nums; }
.cal__item { display: flex; justify-content: space-between; gap: 6px; padding: 4px 7px; border-radius: 7px; font-size: 12px; background: var(--card-2); border: 1px solid var(--line); color: var(--ink); text-decoration: none; min-width: 0; }
.cal__item:hover { border-color: var(--gold); }
.cal__item.is-delivery { border-left: 3px solid var(--navy); }
.cal__who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal__amt { color: var(--muted); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.cal__more { font-size: 11px; color: var(--muted); padding-left: 4px; }
.cal__key { display: inline-block; width: 12px; height: 12px; border-radius: 3px; border: 1px solid var(--line); background: var(--card-2); vertical-align: -2px; }
.cal__key--delivery { border-left: 3px solid var(--navy); }
@media (max-width: 860px) { .cal__cell { min-height: 84px; padding: 5px; } .cal__amt { display: none; } }

/* ---------- catalog tag filter ------------------------------------------- */
.chip--action { border-style: dashed; color: var(--gold-dim); font-weight: 700; gap: 6px; }
.chip--action:hover { background: color-mix(in srgb, var(--gold) 10%, transparent); }
:root[data-theme="dark"] .chip--action { color: var(--gold); }

.tagfilter-active {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px;
}
.tagfilter-active[hidden] { display: none; }
.tagfilter-active__label {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
}
.tagfilter-active__clear {
  border: 0; background: none; cursor: pointer; padding: 2px 4px;
  font-size: 11.5px; font-weight: 600; color: var(--danger); text-decoration: underline;
  text-underline-offset: 3px;
}
/* Small, so the filters read as a footnote to the category row rather than
   competing with it. */
.tagchip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; padding: 3px 5px 3px 10px;
  border-radius: var(--r-pill); color: var(--ink-2);
  background: var(--card); border: 1px solid var(--line);
}
.tagchip__x {
  width: 17px; height: 17px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--line-2); color: var(--muted); font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.tagchip__x:hover { background: var(--danger); color: #fff; }

.tagpick { display: flex; flex-wrap: wrap; gap: 8px; }
.tagpick__chip.is-on { background: var(--navy); color: #f4efe2; border-color: var(--navy); }

.heldstrip {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 12px; padding: 9px 11px;
  background: var(--card-2); border: 1px dashed var(--line); border-radius: var(--r-md);
}
.heldstrip__label {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
}

/* ---------- tables ------------------------------------------------------- */
.table-wrap { overflow-x: auto; border-radius: var(--r-lg); }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
  text-align: left; font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
  padding: 12px 16px; border-bottom: 1px solid var(--line); white-space: nowrap;
  background: var(--card-2); position: sticky; top: 0; z-index: 1;
}
.table th a { color: inherit; display: inline-flex; align-items: center; gap: 5px; }
.table th a:hover { color: var(--ink); text-decoration: none; }
.table th .sort-ind { opacity: .45; font-size: 9px; }
.table th.is-sorted { color: var(--ink); }
.table th.is-sorted .sort-ind { opacity: 1; color: var(--gold); }
.table td { padding: 13px 16px; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--card-2); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .strong { font-weight: 600; }
.table a.rowlink { color: var(--ink); font-weight: 600; }
.table a.rowlink:hover { color: var(--navy); }

.empty { padding: 56px 24px; text-align: center; color: var(--muted); }
.empty__title { font-family: var(--serif); font-size: 19px; color: var(--ink-2); margin-bottom: 6px; }
.empty__body { font-size: 13.5px; max-width: 420px; margin: 0 auto; }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 20px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--muted); }

/* ---------- modal -------------------------------------------------------- */
.backdrop {
  position: fixed; inset: 0; background: rgba(20,16,10,.5);
  display: flex; align-items: center; justify-content: center; z-index: 90;
  padding: 20px; backdrop-filter: blur(3px);
}
.backdrop[hidden] { display: none; }
.modal {
  width: 100%; max-width: 460px; background: var(--card);
  border-radius: 20px; border: 1px solid var(--line);
  box-shadow: var(--shadow-pop); overflow: hidden;
  max-height: 90vh; display: flex; flex-direction: column;
}
.modal--wide { max-width: 720px; }
.modal__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; padding: 22px 24px 0; }
.modal__title { font-family: var(--serif); font-size: 20px; font-weight: 700; }
.modal__sub { font-size: 13.5px; color: var(--muted); margin-top: 3px; }
.modal__x { background: none; border: 0; color: var(--muted); font-size: 24px; cursor: pointer; line-height: 1; padding: 0 4px; }

/* ---------- report visuals -----------------------------------------------
   Aging bands are a SEQUENTIAL ramp, not a categorical palette: they have a
   fixed order and each step means "worse than the last". Adjacent steps are
   deliberately close in hue — what carries the reading is lightness, which
   descends monotonically, plus two channels that never depend on colour at
   all: the bar is ordered left to right, and every band's exact amount is
   printed in the key and again in the table. "Within terms" sits outside the
   ramp in green because it isn't a degree of late, it's the absence of it.
   -------------------------------------------------------------------------- */
:root {
  --age-current: #4A7C59;
  --age-1:       #D9A441;
  --age-2:       #C4772F;
  --age-3:       #AA4B33;
  --age-4:       #7E2A20;
}
:root[data-theme="dark"] {
  --age-current: #7FBC90;
  --age-1:       #E8BC63;
  --age-2:       #DB9250;
  --age-3:       #C9694E;
  --age-4:       #B4503F;
}
.age--current { --age: var(--age-current); }
.age--1 { --age: var(--age-1); }
.age--2 { --age: var(--age-2); }
.age--3 { --age: var(--age-3); }
.age--4 { --age: var(--age-4); }

.agebar {
  display: flex; height: 30px; border-radius: 9px; overflow: hidden;
  background: var(--card-2); gap: 2px;      /* 2px surface gap between fills */
}
.agebar__seg { display: block; background: var(--age); min-width: 3px; transition: filter .16s; }
.agebar__seg:hover { filter: brightness(1.08); }

.agekey { display: grid; gap: 9px; margin-top: 16px; }
.agekey__item { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.agekey__dot { width: 11px; height: 11px; border-radius: 3px; background: var(--age); flex: none; }
.agekey__label { color: var(--muted); }
.agekey__val { margin-left: auto; font-weight: 650; font-variant-numeric: tabular-nums; }

/* In the table the colour is a hint on an already-labelled column, so it is
   carried by a left rule rather than by tinting the number itself. */
.agecell { box-shadow: inset 2px 0 0 var(--age); font-variant-numeric: tabular-nums; }

/* An icon beside a card title, so a page of cards is scanned by shape. */
.card__headline { display: flex; align-items: center; gap: 12px; min-width: 0; }

.legend__pct { color: var(--faint); font-weight: 500; margin-left: 6px; font-size: 12px; }

/* Year against year: last year behind, this year in front, sharing a baseline
   — the gap between the two IS the reading. */
.yoy { display: flex; align-items: flex-end; gap: 8px; }
.yoy__month { flex: 1; min-width: 0; text-align: center; }
.yoy__pair { position: relative; height: 170px; display: flex; align-items: flex-end; justify-content: center; }
.yoy__bar { position: absolute; bottom: 0; border-radius: 4px 4px 0 0; transition: filter .16s; }
.yoy__bar--prev {
  width: 78%; background: color-mix(in srgb, var(--faint) 45%, transparent);
  border: 1px solid color-mix(in srgb, var(--faint) 55%, transparent);
}
.yoy__bar--now {
  width: 46%; background: linear-gradient(180deg, var(--gold-dim), color-mix(in srgb, var(--gold-dim) 78%, var(--navy)));
  box-shadow: 0 0 0 2px var(--card);        /* 2px surface ring on the overlap */
  transform-origin: bottom; animation: hw-grow .55s cubic-bezier(.2,.8,.3,1) both;
}
:root[data-theme="dark"] .yoy__bar--now { background: linear-gradient(180deg, var(--gold), color-mix(in srgb, var(--gold) 70%, #000)); }
.yoy__bar:hover { filter: brightness(1.1); }
.yoy__label { font-size: 11.5px; color: var(--muted); margin-top: 8px; }
.yoy__delta { font-size: 11px; font-weight: 650; margin-top: 2px; min-height: 15px; }
.yoy__delta.is-up   { color: var(--ok); }
.yoy__delta.is-down { color: var(--danger); }
.yoykey { display: flex; gap: 14px; font-size: 12px; color: var(--muted); }
.yoykey__item { display: flex; align-items: center; gap: 6px; }
.yoykey__dot { width: 10px; height: 10px; border-radius: 3px; }
.yoykey__dot--now { background: var(--gold-dim); }
:root[data-theme="dark"] .yoykey__dot--now { background: var(--gold); }
.yoykey__dot--prev { background: color-mix(in srgb, var(--faint) 45%, transparent); border: 1px solid var(--faint); }

/* Week x hour heatmap: one hue, opacity carries magnitude. Every cell has a
   title with the exact figure, so the colour never has to be decoded. */
.heat-wrap { overflow-x: auto; }
.heat { border-collapse: separate; border-spacing: 3px; width: 100%; table-layout: fixed; }
.heat tbody th, .heat thead th:first-child { width: 46px; }
.heat th {
  font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase;
  letter-spacing: .05em; padding: 2px 4px; white-space: nowrap;
}
.heat tbody th { text-align: right; }
.heat__cell {
  display: block; width: 100%; min-width: 34px; height: 26px; border-radius: 6px;
  background: color-mix(in srgb, var(--navy) calc(var(--w) * 88%), var(--card-2));
  transition: transform .14s;
}
:root[data-theme="dark"] .heat__cell { background: color-mix(in srgb, var(--gold) calc(var(--w) * 82%), var(--card-2)); }
.heat__cell:hover { transform: scale(1.09); }
.heatkey { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: 12px; }
.heatkey__ramp {
  flex: none; width: 120px; height: 10px; border-radius: 999px;
  background: linear-gradient(90deg, var(--card-2), var(--navy));
}
:root[data-theme="dark"] .heatkey__ramp { background: linear-gradient(90deg, var(--card-2), var(--gold)); }

/* A tinted left edge on a stat tile, matching its icon chip. */
.stat--accent { position: relative; overflow: hidden; }
.stat--accent::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--chip, var(--navy)); opacity: .8;
}


/* ---------- billed vs collected ------------------------------------------
   Two series of the SAME measure, so they share one axis — a second scale
   would misrepresent their relative size, which is the entire point of the
   chart. Colours validated against both surfaces (CVD separation, chroma,
   contrast) and never the only channel: there is a legend, a hover figure on
   every bar, and the same numbers as a table below.
   -------------------------------------------------------------------------- */
:root {
  --ser-billed:    #1F6FB2;
  --ser-collected: #A8822F;
}
:root[data-theme="dark"] {
  --ser-billed:    #4187C4;
  --ser-collected: #A87B33;
}

.serieskey { display: flex; gap: 16px; font-size: 12.5px; color: var(--muted); flex-wrap: wrap; }
.serieskey__item { display: flex; align-items: center; gap: 7px; }
.serieskey__dot { width: 11px; height: 11px; border-radius: 3px; flex: none; }
.serieskey__dot--billed    { background: var(--ser-billed); }
.serieskey__dot--collected { background: var(--ser-collected); }

/* Four figures that let the chart be read without decoding any bar. */
.minifig { padding: 12px 14px; border-radius: var(--r-md); background: var(--card-2); border: 1px solid var(--line); }
.minifig__label { font-size: 11px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.minifig__value { font-family: var(--sans); font-size: 22px; letter-spacing: -.01em; font-weight: 700; margin-top: 5px; font-variant-numeric: tabular-nums; }
.minifig__value.is-short { color: var(--warn); }
.minifig__value.is-ahead { color: var(--ok); }

.bvc { display: flex; gap: 12px; }

/* The axis is its own column so gridlines and bars cannot drift apart as the
   card resizes — they are laid out against the same box. */
.bvc__axis {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 260px; padding-bottom: 26px; text-align: right; flex: none;
  font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums;
}
.bvc__tick { line-height: 1; transform: translateY(-50%); }
.bvc__tick:first-child { transform: none; }
.bvc__tick:last-child  { transform: translateY(-100%); }

.bvc__plot { position: relative; flex: 1; min-width: 0; height: 260px; }
.bvc__grid {
  position: absolute; inset: 0 0 26px 0;
  display: flex; flex-direction: column-reverse; justify-content: space-between;
}
.bvc__rule { height: 1px; background: var(--line); opacity: .75; }
.bvc__rule:first-child { background: var(--line-2); opacity: 1; }

.bvc__months { position: absolute; inset: 0; display: flex; gap: 2px; }
.bvc__month {
  flex: 1; min-width: 0; display: flex; flex-direction: column;
  border-radius: 8px 8px 0 0; transition: background .15s;
}
.bvc__month:hover { background: color-mix(in srgb, var(--navy) 4%, transparent); }
.bvc__month.is-latest { background: color-mix(in srgb, var(--gold) 8%, transparent); }

/* Bars are capped so a short series doesn't inflate into slabs — five months
   of data should read as five months, not as five walls. */
.bvc__cols {
  flex: 1; display: flex; align-items: flex-end; justify-content: center;
  gap: 3px; padding: 0 4px; min-height: 0;
}
.bvc__bar {
  flex: 1; max-width: 22px; min-height: 3px; border-radius: 4px 4px 0 0;
  transform-origin: bottom;
  animation: hw-grow .55s cubic-bezier(.2,.8,.3,1) both; animation-delay: var(--d, 0ms);
  transition: filter .15s;
}
.bvc__bar--billed    { background: var(--ser-billed); }
.bvc__bar--collected { background: var(--ser-collected); }
.bvc__bar:hover { filter: brightness(1.12); }
.bvc__bar.is-zero { min-height: 0; background: none; }
.bvc__label {
  height: 26px; display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; color: var(--muted); white-space: nowrap;
}
.bvc__month.is-latest .bvc__label { color: var(--ink); font-weight: 650; }

.bvc__note { margin-top: 16px; font-size: 13px; color: var(--muted); line-height: 1.6; }
.bvc__note strong { color: var(--ink); }

.bvc__table { border-top: 1px solid var(--line); }
.bvc__table > summary {
  padding: 14px 22px; cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--muted);
  list-style: none;
}
.bvc__table > summary::-webkit-details-marker { display: none; }
.bvc__table > summary::before { content: "▸ "; }
.bvc__table[open] > summary::before { content: "▾ "; }
.bvc__table > summary:hover { color: var(--navy); }
:root[data-theme="dark"] .bvc__table > summary:hover { color: var(--gold); }
.is-short { color: var(--warn); }

.agekey__item--total {
  border-top: 1px solid var(--line); padding-top: 9px; margin-top: 2px; font-weight: 700;
}
.agekey__item--total .agekey__label { color: var(--ink); }

@media (max-width: 720px) {
  .bvc__axis, .bvc__plot { height: 200px; }
  .bvc__label { font-size: 10px; }
}

/* A small square action inside a table row — reachable without being loud. */
.iconbtn {
  display: inline-grid; place-items: center; width: 28px; height: 28px;
  border-radius: 8px; color: var(--muted); vertical-align: middle;
  transition: background .15s, color .15s;
}
.iconbtn:hover { background: var(--card-2); color: var(--navy); }
:root[data-theme="dark"] .iconbtn:hover { color: var(--gold); }
.iconbtn + .iconbtn { margin-left: 2px; }

/* An icon in the modal head so a destructive question reads as one before a
   word of it is read. */
.modal__icon {
  flex: none; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center; margin-right: -4px;
}
.modal__icon--danger { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.modal__icon--warn   { background: color-mix(in srgb, var(--warn) 18%, transparent);   color: var(--warn-ink, var(--warn)); }
.modal__head .modal__icon + div { flex: 1; }

/* Leaving-an-unfinished-ticket choices: two big targets, not a sentence with
   two links in it. */
.leave-opts { display: grid; gap: 10px; }
.leave-opt { display: block; }
.leave-opt__btn {
  width: 100%; display: flex; align-items: flex-start; gap: 13px; text-align: left;
  padding: 14px 15px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card); cursor: pointer; transition: border-color .16s, background .16s, transform .16s;
}
.leave-opt__btn:hover { border-color: var(--navy); background: var(--card-2); transform: translateY(-1px); }
.leave-opt__btn--danger:hover { border-color: var(--danger); }
.leave-opt__ico { flex: none; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; }
.leave-opt__ico--hold    { background: color-mix(in srgb, var(--navy) 12%, transparent);   color: var(--navy); }
.leave-opt__ico--discard { background: color-mix(in srgb, var(--danger) 13%, transparent); color: var(--danger); }
:root[data-theme="dark"] .leave-opt__ico--hold { background: color-mix(in srgb, var(--gold) 15%, transparent); color: var(--gold); }
.leave-opt__title { display: block; font-weight: 650; font-size: 14.5px; }
.leave-opt__sub { display: block; font-size: 12.5px; color: var(--muted); margin-top: 2px; line-height: 1.45; }

/* A quiet Discard until you hover it — it sits beside Hold and must never be
   the button a hurried hand reaches for first. */
.btn--ghostdanger { color: var(--muted); }
.btn--ghostdanger:hover { color: var(--danger); border-color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, transparent); }

.modal__body { padding: 20px 24px; overflow-y: auto; flex: 1; }
.modal__foot { display: flex; gap: 10px; align-items: center; padding: 16px 24px; background: var(--card-2); border-top: 1px solid var(--line); }
.modal__foot .spacer { margin-left: auto; }

/* ---------- flash / toast ------------------------------------------------ */
.flash { display: flex; align-items: flex-start; gap: 11px; padding: 13px 17px; border-radius: var(--r-md); margin-bottom: 18px; font-size: 13.5px; font-weight: 500; border: 1px solid transparent; }
.flash--ok     { background: var(--ok-bg);     color: var(--ok);     border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
.flash--warn   { background: var(--warn-bg);   color: var(--warn);   border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
.flash--danger { background: var(--danger-bg); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.flash--info   { background: var(--info-bg);   color: var(--info);   border-color: color-mix(in srgb, var(--info) 25%, transparent); }

/* ---------- auth --------------------------------------------------------- */
.auth { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.auth__card { width: 100%; max-width: 396px; }
.auth__brand { text-align: center; margin-bottom: 26px; }
.auth__brand img { height: 44px; margin: 0 auto 14px; }
.auth__tag { font-size: 13px; color: var(--muted); }

.pinpad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 11px; margin-top: 4px; }
.pinpad button {
  height: 62px; border: 1px solid var(--line); background: var(--card);
  border-radius: var(--r-md); font-size: 22px; font-weight: 600; color: var(--ink);
  cursor: pointer; font-variant-numeric: tabular-nums; transition: background .1s, transform .06s;
}
.pinpad button:hover { background: var(--card-2); }
.pinpad button:active { transform: translateY(1px); background: var(--line-2); }
.pinpad button.is-util { font-size: 14px; font-weight: 600; color: var(--muted); }
.pindots { display: flex; gap: 13px; justify-content: center; margin: 20px 0 22px; }
.pindot { width: 15px; height: 15px; border-radius: 50%; border: 1.5px solid var(--line); background: var(--card-2); transition: .12s; }
.pindot.is-filled { background: var(--navy); border-color: var(--navy); transform: scale(1.06); }

/* ---------- POS ---------------------------------------------------------- */
.pos { flex: 1; display: flex; gap: 22px; min-height: 0; }
.pos__catalog { flex: 1.7; display: flex; flex-direction: column; padding: 20px 22px; min-height: 0; }
.pos__ticket  { flex: 0 0 452px; display: flex; flex-direction: column; padding: 20px 22px; min-height: 0; }
@media (max-width: 1280px) {
  .pos { gap: 14px; }
  .pos__ticket { flex-basis: 372px; padding: 16px; }
  .pos__catalog { padding: 16px; }
  .tilegrid { grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); gap: 10px; }
}
@media (max-width: 900px) {
  /* Stacked, so pinning to the viewport would squeeze both panels to nothing.
     Let the page scroll instead. */
  .app:has(.main--flush) { height: auto; min-height: 100vh; overflow: visible; }
  .main--flush { height: auto; overflow: visible; }
  .pos { flex-direction: column; }
  .pos__ticket { flex: none; }
  .tilegrid { overflow: visible; }
}

.tilegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); gap: 13px; overflow: auto; align-content: start; flex: 1; padding-bottom: 4px; }
/* Each tile is its own little form so tapping posts without JS. The form is a
   real grid item rather than display:contents — that shortcut breaks form
   submission in some engines and drops the element from the accessibility tree. */
.tile-form { display: flex; }
.tile-form .tile { width: 100%; }

.tile {
  border: 1px solid var(--line); background: var(--card); border-radius: var(--r-md);
  padding: 14px 15px; min-height: 88px; display: flex; flex-direction: column;
  justify-content: space-between; cursor: pointer; text-align: left;
  transition: border-color .1s, transform .06s, box-shadow .12s; box-shadow: var(--shadow-tile);
}
.tile:hover { border-color: var(--gold); box-shadow: 0 10px 22px -14px rgba(80,66,40,.55); }
.tile:active { transform: translateY(1px); }
.tile__name { font-size: 13.5px; font-weight: 600; line-height: 1.3; }
.tile__price { font-size: 15px; font-weight: 700; color: var(--navy); margin-top: 10px; font-variant-numeric: tabular-nums; }
.tile--custom { border: 1.5px dashed var(--gold); background: color-mix(in srgb, var(--gold) 7%, transparent); align-items: center; justify-content: center; text-align: center; color: var(--gold-dim); font-weight: 700; gap: 6px; }
:root[data-theme="dark"] .tile--custom { color: var(--gold-soft); }
.tile--custom .plus { font-size: 24px; line-height: 1; }

.ticket__top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.ticket__id { font-size: 12.5px; color: var(--muted); }
.ticket__id b { color: var(--ink); font-weight: 700; }

.cust-pill { display: flex; align-items: center; gap: 11px; border: 1px solid var(--line); background: var(--card-2); border-radius: var(--r-md); padding: 11px 14px; margin-bottom: 14px; }
.cust-pill__icon { width: 34px; height: 34px; border-radius: 50%; background: var(--line-2); display: flex; align-items: center; justify-content: center; color: var(--navy); flex-shrink: 0; }
.cust-pill__name { flex: 1; font-size: 14px; font-weight: 600; }
.cust-pill__meta { font-size: 11.5px; color: var(--muted); margin-top: 1px; font-weight: 500; }
.cust-pill__action { font-size: 12.5px; font-weight: 600; color: var(--gold-dim); background: none; border: 0; cursor: pointer; }
:root[data-theme="dark"] .cust-pill__action { color: var(--gold); }

.lines { flex: 1; overflow: auto; margin: 0 -6px; padding: 0 6px; min-height: 80px; }
.line { display: grid; grid-template-columns: 32px 1fr auto 24px; gap: 11px; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--line-2); }
.line__qty { width: 32px; height: 32px; border-radius: 9px; border: 1px solid var(--line); background: var(--card); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13.5px; color: var(--navy); font-variant-numeric: tabular-nums; }
.line__desc { font-size: 13.5px; font-weight: 600; line-height: 1.3; }
.line__unit { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.line__amt { font-size: 14px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
button.line__qty { cursor: pointer; padding: 0; font-family: inherit; transition: background .15s, border-color .15s; }
button.line__qty:hover { border-color: var(--gold); background: var(--card-2); }
.stepper--lg { margin: 0 auto; }
.stepper--lg button { width: 64px; height: 60px; font-size: 26px; }
.stepper--lg .val { width: 96px; font-size: 26px; }
.quickqty { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 16px; }
.quickqty button { height: 46px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card-2); color: var(--navy); font-weight: 700; font-size: 15px; cursor: pointer; font-family: inherit; }
.quickqty button:hover { border-color: var(--gold); background: var(--card); }
.modal--narrow { max-width: 380px; }
.line__edit { color: var(--faint); background: none; border: 0; cursor: pointer; padding: 4px; }
.line__edit:hover { color: var(--navy); }

.totals { border-top: 1.5px solid var(--line); padding-top: 13px; margin-top: 6px; }
.totals__row { display: flex; justify-content: space-between; font-size: 13.5px; color: var(--muted); margin-bottom: 7px; }
.totals__row b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.totals__row--grand { font-size: 15px; color: var(--ink); margin-top: 8px; margin-bottom: 0; align-items: baseline; }
.totals__grand { font-family: var(--sans); font-size: 28px; letter-spacing: -.02em; font-weight: 700; color: var(--navy); font-variant-numeric: tabular-nums; }

.delrow { display: flex; justify-content: space-between; align-items: center; border: 1px solid var(--line); background: var(--card-2); border-radius: var(--r-sm); padding: 11px 15px; margin: 14px 0 12px; font-size: 13.5px; font-weight: 600; width: 100%; color: var(--ink); font-family: inherit; cursor: pointer; text-align: left; }
.delrow > span:first-child { display: inline-flex; align-items: center; gap: 8px; }
.delrow:hover { border-color: var(--gold); }
.delrow__state { color: var(--muted); font-weight: 500; }
.delrow--on { border-color: var(--navy); }
.delrow--on .delrow__state { color: var(--navy); font-weight: 600; }

/* ---------- misc --------------------------------------------------------- */
.stack > * + * { margin-top: 18px; }
.muted { color: var(--muted); }
.mono-num { font-variant-numeric: tabular-nums; }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.divider { height: 1px; background: var(--line); border: 0; margin: 20px 0; }

.bar { height: 8px; border-radius: var(--r-pill); background: var(--line-2); overflow: hidden; }
.bar__fill { display: block; height: 100%; border-radius: var(--r-pill); background: linear-gradient(90deg, var(--navy-3), var(--navy)); }

.weekbars { display: flex; align-items: flex-end; gap: 10px; height: 130px; padding-top: 8px; }
.weekbar { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; height: 100%; justify-content: flex-end; }
.weekbar__col { width: 100%; border-radius: 7px 7px 3px 3px; background: linear-gradient(180deg, var(--navy-3), var(--navy)); min-height: 3px; }
.weekbar__col--today { background: linear-gradient(180deg, var(--gold-soft), var(--gold)); }
.weekbar__label { font-size: 10.5px; color: var(--muted); font-weight: 600; }

.legend { display: flex; flex-direction: column; gap: 11px; }
.legend__item { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.legend__dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.legend__name { flex: 1; }
.legend__val { font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---------- print -------------------------------------------------------- */
@media print {
  .topbar, .app-footer, .no-print, .btn, .nav { display: none !important; }
  body { background: #fff !important; color: #000; font-size: 12px; }
  .main { padding: 0; max-width: none; }
  .card { box-shadow: none; border: 0; background: #fff; }
  .receipt { max-width: 100%; }
  @page { margin: 14mm; }
}

/* The printed receipt doubles as the emailed PDF, so it is styled for paper
   rather than screen: no colour dependencies, generous leading, tabular figures. */
.receipt { max-width: 760px; margin: 0 auto; background: var(--card); padding: 40px 44px; }
.receipt__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; padding-bottom: 22px; border-bottom: 2px solid var(--line); }
.receipt__logo { height: 46px; }
.receipt__meta { text-align: right; font-size: 12.5px; color: var(--muted); line-height: 1.7; }
.receipt__doctype {
  font-size: 11px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 2px;
}
.receipt__due {
  /* display:table so it drops onto its own line and still hugs the right
     edge of the right-aligned meta block. */
  margin-top: 8px; display: table; margin-left: auto; padding: 5px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--warn) 16%, transparent);
  font-size: 12px; font-weight: 650; color: var(--ink);
}
.receipt__note {
  margin-top: 22px; padding: 14px 16px; border-radius: 10px;
  background: color-mix(in srgb, var(--navy) 6%, transparent);
  border: 1px solid var(--line);
  font-size: 12.5px; line-height: 1.6; color: var(--muted);
}
.receipt__paid {
  margin-top: 12px; text-align: right;
  font-size: 11.5px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ok);
}
.receipt__no { font-family: var(--serif); font-size: 21px; font-weight: 700; color: var(--ink); }
.receipt__parties { display: flex; gap: 40px; padding: 22px 0; }
.receipt__table { width: 100%; border-collapse: collapse; margin-top: 8px; }
.receipt__table th { text-align: left; font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); padding: 9px 0; border-bottom: 1px solid var(--line); }
.receipt__table td { padding: 10px 0; border-bottom: 1px solid var(--line-2); font-size: 13px; vertical-align: top; }
.receipt__totals { margin-left: auto; width: 290px; margin-top: 18px; }
.receipt__foot { margin-top: 34px; padding-top: 18px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--muted); text-align: center; }
.receipt__sig { margin-top: 30px; padding-top: 14px; border-top: 1px solid var(--line); }
.receipt__sig img { max-height: 82px; }

/* ==========================================================================
   CHART PALETTE
   Four categorical hues, validated for colourblind separation and contrast
   against both surfaces rather than chosen by eye. Order is fixed and tied to
   the entity, never to rank — a filter that drops a bucket must not repaint
   the survivors. Dark is its own set of steps, not an automatic flip.
   ========================================================================== */
:root {
  --cat-flowers:  #C4553D;
  --cat-supplies: #1F6FB2;
  --cat-rentals:  #C98A1E;
  --cat-fuel:     #7B4B9E;
  --grid-line:    color-mix(in srgb, var(--line) 80%, transparent);
  /* People, in fixed order (validated: all checks pass; gold carries the usual
     contrast warning, relieved by the legend). A sixth person folds into Other. */
  --ppl-1: #C4553D; --ppl-2: #1F6FB2; --ppl-3: #C98A1E; --ppl-4: #7B4B9E; --ppl-5: #1F8A70;
  --ppl-other: var(--faint);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --cat-flowers:  #DE7059;
    --cat-supplies: #4A90D9;
    --cat-rentals:  #BC8C2A;
    --cat-fuel:     #A67BC8;
    --ppl-1: #DE7059; --ppl-2: #4A90D9; --ppl-3: #BC8C2A; --ppl-4: #A67BC8; --ppl-5: #2E9C7E;
  }
}
:root[data-theme="dark"] {
  --cat-flowers:#DE7059; --cat-supplies:#4A90D9; --cat-rentals:#BC8C2A; --cat-fuel:#A67BC8;
  --ppl-1: #DE7059; --ppl-2: #4A90D9; --ppl-3: #BC8C2A; --ppl-4: #A67BC8; --ppl-5: #2E9C7E;
}

/* ---------- donut -------------------------------------------------------- */
.donut-wrap { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }
.donut { position: relative; flex-shrink: 0; }
.donut svg { transform: rotate(-90deg); overflow: visible; }
/* 2px surface-coloured gap between segments so adjacent fills never touch */
.donut circle { fill: none; stroke-linecap: butt; }
.donut__track { stroke: var(--line-2); }
.donut__center {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
}
.donut__value { font-family: var(--sans); font-size: 24px; letter-spacing: -.02em; font-weight: 700; color: var(--ink); line-height: 1; font-variant-numeric: tabular-nums; }
.donut__label { font-size: 10px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin-top: 5px; font-weight: 700; }

/* Segmented control for the hero's three trend shapes. */
.trendtabs {
  display: inline-flex; gap: 2px; margin-top: 16px; padding: 3px;
  background: rgba(255,255,255,.08); border: 1px solid rgba(244,239,226,.18);
  border-radius: var(--r-pill);
}
.trendtab {
  padding: 6px 14px; border-radius: var(--r-pill); font-size: 12.5px; font-weight: 600;
  color: rgba(244,239,226,.72); text-decoration: none; white-space: nowrap;
  transition: background .13s, color .13s;
}
.trendtab:hover { color: #fff; background: rgba(255,255,255,.08); text-decoration: none; }
.trendtab.is-on { background: var(--gold); color: #2a2115; }
@media (max-width: 620px) { .trendtabs { width: 100%; justify-content: space-between; }
  .trendtab { flex: 1; text-align: center; padding: 7px 8px; font-size: 11.5px; } }

/* Twelve months need less width per bar than twelve hours of labels. */
.hourbars--wide { gap: 6px; }
.hourbars--wide .hourbar__label { font-size: 10px; }

/* ---------- hourly bars (on the dark hero) ------------------------------
   Same idea as the week bars, tuned for a dark surface and for many thin
   columns. Empty hours stay visible as a faint baseline — a gap would read as
   missing data rather than a quiet hour. */
.hourbars { display: flex; align-items: flex-end; gap: 4px; height: 104px; }
.hourbar {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: flex-end; gap: 5px; height: 100%; min-width: 0;
}
.hourbar__value {
  font-size: 9.5px; font-weight: 700; color: rgba(244,239,226,.9);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.hourbar__col {
  width: 100%; border-radius: 4px 4px 2px 2px; min-height: 2px;
  background: linear-gradient(180deg, var(--gold-soft), var(--gold-dim));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3);
  transform-origin: bottom;
  animation: hw-grow .5s cubic-bezier(.22,.72,.28,1) both;
}
.hourbar__col--empty { background: rgba(244,239,226,.16); box-shadow: none; }
.hourbar__label {
  font-size: 9.5px; color: rgba(244,239,226,.55); white-space: nowrap;
}
.hourbar:hover .hourbar__col { filter: brightness(1.15); }

/* Held-ticket dropdown in the header. Reuses the range picker's panel so
   there's one popover style in the app rather than two that nearly match. */
.helddrop { position: relative; flex-shrink: 0; }
.helddrop__trigger {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: var(--r-pill); cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--warn);
  background: var(--warn-bg);
  border: 1px solid color-mix(in srgb, var(--warn) 34%, transparent);
  list-style: none; white-space: nowrap;
}
.helddrop__trigger::-webkit-details-marker { display: none; }
.helddrop__trigger:hover { background: color-mix(in srgb, var(--warn) 22%, transparent); }
.helddrop__count { font-variant-numeric: tabular-nums; font-weight: 700; }
.helddrop__panel { width: 300px; right: 0; }
@media (max-width: 720px) { .helddrop__word { display: none; } }

/* ---------- breadcrumbs --------------------------------------------------
   Deep pages otherwise give no sense of where you are or how to get back one
   level — the browser Back button is not a navigation design. */
.crumbs {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--muted); margin-bottom: 14px;
}
.crumbs a { color: var(--muted); text-decoration: none; padding: 2px 0; }
.crumbs a:hover { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }
.crumbs [aria-current="page"] { color: var(--ink-2); font-weight: 600; }
.crumbs__sep { display: inline-flex; color: var(--faint); }

/* ---------- icons & nav cards -------------------------------------------
   A grid of white rectangles gives the eye nothing to land on. Each
   destination gets a tinted icon chip in its own hue, so the page is scanned
   by colour and shape rather than by reading every heading.
   -------------------------------------------------------------------------- */
.icon { display: block; flex-shrink: 0; }

.icon-chip {
  width: 44px; height: 44px; border-radius: 13px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--chip, var(--navy));
  background: color-mix(in srgb, var(--chip, var(--navy)) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--chip, var(--navy)) 26%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 45%, transparent);
  transition: transform .16s cubic-bezier(.2,.7,.3,1), background .16s;
}
.icon-chip--sm { width: 34px; height: 34px; border-radius: 10px; }
:root[data-theme="dark"] .icon-chip { box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }

.chip-navy     { --chip: var(--navy); }
.chip-gold     { --chip: var(--gold-dim); }
.chip-green    { --chip: var(--ok); }
.chip-blue     { --chip: var(--cat-supplies); }
.chip-purple   { --chip: var(--cat-fuel); }
.chip-rose     { --chip: var(--cat-flowers); }
.chip-amber    { --chip: var(--warn); }
:root[data-theme="dark"] .chip-gold { --chip: var(--gold); }

.navcard {
  display: flex; gap: 15px; align-items: flex-start;
  padding: 20px 21px; text-decoration: none; color: inherit;
  position: relative; overflow: hidden;
}
.navcard::after {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--chip, var(--navy)); opacity: .85;
}
.navcard:hover { text-decoration: none; }
.navcard:hover .icon-chip {
  transform: scale(1.06);
  background: color-mix(in srgb, var(--chip, var(--navy)) 22%, transparent);
}
.navcard__title { font-family: var(--serif); font-size: 17.5px; font-weight: 700; line-height: 1.2; }
.navcard__body { font-size: 13px; color: var(--muted); margin-top: 6px; line-height: 1.5; }
.navcard__go {
  margin-left: auto; align-self: center; color: var(--faint);
  transition: transform .16s, color .16s;
}
.navcard:hover .navcard__go { transform: translateX(3px); color: var(--chip, var(--navy)); }

/* Stat tiles that are also links. */
.stat-link { display: block; text-decoration: none; color: inherit; }
.stat-link:hover { text-decoration: none; }
.stat__head { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; }

/* Scheduled-order rows: a date block you can read at a glance, and the two
   things you actually want to do with one. */
.upnext {
  display: grid; grid-template-columns: auto 1fr auto; gap: 13px; align-items: center;
  padding: 11px 0; border-bottom: 1px solid var(--line-2);
}
.upnext:last-child { border-bottom: 0; }
.upnext__when {
  width: 44px; height: 46px; border-radius: 11px; flex-shrink: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--card-2); border: 1px solid var(--line); line-height: 1.1;
}
.upnext__when.is-urgent {
  background: color-mix(in srgb, var(--warn) 15%, transparent);
  border-color: color-mix(in srgb, var(--warn) 42%, transparent);
}
.upnext__day { font-family: var(--serif); font-size: 17px; font-weight: 700; color: var(--ink); }
.upnext__mon { font-size: 9.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); }
.upnext__when.is-urgent .upnext__mon { color: var(--warn); }
.upnext__who {
  display: block; font-size: 13.5px; font-weight: 600; color: var(--ink);
  text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.upnext__who:hover { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }
.upnext__meta { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.upnext__actions { display: flex; gap: 6px; flex-shrink: 0; }
@media (max-width: 620px) {
  .upnext { grid-template-columns: auto 1fr; }
  .upnext__actions { grid-column: 2; margin-top: 4px; }
}

/* ---------- range picker -------------------------------------------------
   One control rather than a chip row plus two date fields — the period is
   changed occasionally, so it shouldn't occupy a quarter of the hero. Built on
   <details> so it opens without JavaScript.
   -------------------------------------------------------------------------- */
.rangepicker { position: relative; flex-shrink: 0; }

.rangepicker__trigger {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: var(--r-sm); cursor: pointer;
  font-size: 13px; font-weight: 600; color: #f4efe2;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(244,239,226,.24);
  list-style: none; user-select: none; white-space: nowrap;
  transition: background .13s, border-color .13s;
}
.rangepicker__trigger::-webkit-details-marker { display: none; }
.rangepicker__trigger:hover { background: rgba(255,255,255,.17); border-color: var(--gold-soft); }
.rangepicker[open] .rangepicker__trigger { background: rgba(255,255,255,.19); border-color: var(--gold-soft); }
.rangepicker__caret { transition: transform .16s cubic-bezier(.2,.7,.3,1); opacity: .8; }
.rangepicker[open] .rangepicker__caret { transform: rotate(180deg); }
.rangepicker__label { font-variant-numeric: tabular-nums; }

.rangepicker__panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 40;
  width: 236px; padding: 8px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-pop);
  animation: hw-pop .16s cubic-bezier(.22,.72,.28,1) both;
}
.rangepicker__list { display: flex; flex-direction: column; }
.rangepicker__item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 11px; border-radius: 8px; font-size: 13.5px; font-weight: 500;
  color: var(--ink); text-decoration: none;
}
.rangepicker__item:hover { background: var(--card-2); text-decoration: none; }
.rangepicker__item.is-on { background: color-mix(in srgb, var(--gold) 16%, transparent);
  color: var(--gold-dim); font-weight: 700; }
:root[data-theme="dark"] .rangepicker__item.is-on { color: var(--gold-soft); }

.rangepicker__custom { margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.rangepicker__customLabel {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted); margin: 0 3px 8px;
}
.rangepicker__fields { display: flex; align-items: center; gap: 6px; }
/* Inside the light popover the fields are on a light surface again, so the
   on-dark treatment has to be undone. */
.rp-field {
  background: var(--card-2); border-color: var(--line); color: var(--ink);
  flex: 1; min-width: 0; padding: 7px 8px; font-size: 12px;
}
.rp-field:focus { background: var(--card); border-color: var(--gold); }

/* On a light card the trigger has to read as a control against ivory, not
   against navy. */
.rangepicker--light .rangepicker__trigger {
  color: var(--ink-2); background: var(--card-2);
  border-color: var(--line); font-weight: 600;
}
.rangepicker--light .rangepicker__trigger:hover { background: var(--line-2); border-color: var(--gold); }
.rangepicker--light[open] .rangepicker__trigger { background: var(--line-2); border-color: var(--gold); }

@media (max-width: 720px) {
  .rangepicker { width: 100%; }
  .rangepicker__trigger { width: 100%; justify-content: space-between; }
  .rangepicker__panel { left: 0; right: 0; width: auto; }
}

/* Form controls sitting on the dark hero. */
.hero-range { flex-shrink: 0; }
.input--onDark {
  width: auto; padding: 7px 10px; font-size: 13px;
  background: rgba(255,255,255,.09); border-color: rgba(244,239,226,.26); color: #f4efe2;
}
.input--onDark:focus { background: rgba(255,255,255,.16); border-color: var(--gold-soft); }
.input--onDark::-webkit-calendar-picker-indicator { filter: invert(1) opacity(.65); cursor: pointer; }
.card--feature .chip {
  background: rgba(255,255,255,.08); border-color: rgba(244,239,226,.22); color: rgba(244,239,226,.85);
}
.card--feature .chip:hover { border-color: var(--gold-soft); color: #fff; }
.card--feature .chip.is-on { background: var(--gold); border-color: var(--gold); color: #2a2115; }
@media (max-width: 720px) {
  .hero-range { width: 100%; }
  .hero-range .chips { justify-content: flex-start !important; }
  .hero-range > div:last-child { justify-content: flex-start !important; flex-wrap: wrap; }
}

/* Compact figures beneath a chart — the numbers you'd otherwise hover for. */
.ministats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line-2);
}
.ministat__label {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
}
.ministat__value {
  font-family: var(--sans); font-size: 19px; letter-spacing: -.01em; font-weight: 700;
  color: var(--ink); margin-top: 4px; font-variant-numeric: tabular-nums;
}
.ministat__foot { font-size: 11px; color: var(--muted); margin-top: 2px; }

/* ---------- sparkline ---------------------------------------------------- */
.spark { display: block; width: 100%; height: 42px; overflow: visible; }
.spark__line { fill: none; stroke: var(--navy); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.spark__area { fill: url(#sparkGrad); opacity: .16; }
.spark__dot  { fill: var(--gold); stroke: var(--card); stroke-width: 2; }

/* ---------- bars --------------------------------------------------------- */
.weekbars { display: flex; align-items: flex-end; gap: 10px; height: 150px; padding-top: 4px; }
.weekbar { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; position: relative; }
.weekbar__col {
  width: 100%; border-radius: 5px 5px 3px 3px; min-height: 3px;
  background: linear-gradient(180deg, var(--navy-3), var(--navy));
  transform-origin: bottom; transition: filter .15s;
}
.weekbar:hover .weekbar__col { filter: brightness(1.12); }
.weekbar__col--today { background: linear-gradient(180deg, var(--gold-soft), var(--gold)); }
.weekbar__label { font-size: 10.5px; color: var(--muted); font-weight: 600; }
.weekbar__tip {
  position: absolute; bottom: 100%; left: 50%; transform: translate(-50%,-8px);
  background: var(--ink); color: var(--card); font-size: 11.5px; font-weight: 600;
  padding: 5px 9px; border-radius: 7px; white-space: nowrap; pointer-events: none;
  opacity: 0; transition: opacity .13s, transform .13s; font-variant-numeric: tabular-nums; z-index: 5;
}
.weekbar:hover .weekbar__tip { opacity: 1; transform: translate(-50%,-4px); }

/* horizontal ranked bars — the "cards with graphics" workhorse */
.rank { display: flex; flex-direction: column; gap: 13px; }
.rank__row { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; align-items: baseline; }
.rank__name { font-size: 13px; font-weight: 600; }
.rank__val { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
.rank__track { grid-column: 1 / -1; height: 7px; border-radius: var(--r-pill); background: var(--line-2); overflow: hidden; }
.rank__fill {
  /* display:block matters — these are <span>s, and an inline box ignores
     width and height entirely, which silently rendered every ranked bar in
     the app as an empty track. */
  display: block; height: 100%; border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--navy-3), var(--navy)); transform-origin: left;
}

/* ---------- progress ring ------------------------------------------------ */
.ring { position: relative; width: 74px; height: 74px; flex-shrink: 0; }
.ring svg { transform: rotate(-90deg); }
.ring__bg { fill: none; stroke: var(--line-2); }
.ring__fg { fill: none; stroke: var(--ok); stroke-linecap: round; }
.ring__txt { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   MOTION
   Subtle and purposeful: motion that confirms an action or reveals structure.
   Nothing loops, nothing decorates. All of it yields to reduced-motion.
   ========================================================================== */
@keyframes hw-rise   { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes hw-fade   { from { opacity: 0; } to { opacity: 1; } }
@keyframes hw-pop    { 0% { transform: scale(.94); opacity: 0; } 60% { transform: scale(1.015); } 100% { transform: scale(1); opacity: 1; } }
@keyframes hw-grow   { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes hw-wipe   { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes hw-shimmer{ 100% { background-position-x: -200%; } }
@keyframes hw-slide  { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }
@keyframes hw-spin   { to { transform: rotate(360deg); } }

/* Cards reveal in a short stagger — reads as "the page assembled for you"
   rather than "the page appeared". Depth is capped so nothing feels slow. */
.anim-rise { animation: hw-rise .42s cubic-bezier(.22,.72,.28,1) both; }
.anim-fade { animation: hw-fade .3s ease both; }
.anim-pop  { animation: hw-pop .26s cubic-bezier(.22,.72,.28,1) both; }
.stagger > * { animation: hw-rise .42s cubic-bezier(.22,.72,.28,1) both; }
.stagger > *:nth-child(1) { animation-delay: .02s; }
.stagger > *:nth-child(2) { animation-delay: .06s; }
.stagger > *:nth-child(3) { animation-delay: .10s; }
.stagger > *:nth-child(4) { animation-delay: .14s; }
.stagger > *:nth-child(5) { animation-delay: .18s; }
.stagger > *:nth-child(6) { animation-delay: .22s; }
.stagger > *:nth-child(7) { animation-delay: .26s; }
.stagger > *:nth-child(8) { animation-delay: .30s; }
.stagger > *:nth-child(n+9) { animation-delay: .34s; }

/* Charts draw themselves in — the bar growing from the axis and the donut
   sweeping round make the number feel measured rather than asserted. */
.weekbar__col { animation: hw-grow .55s cubic-bezier(.22,.72,.28,1) both; }
.weekbar:nth-child(2) .weekbar__col { animation-delay: .05s; }
.weekbar:nth-child(3) .weekbar__col { animation-delay: .10s; }
.weekbar:nth-child(4) .weekbar__col { animation-delay: .15s; }
.weekbar:nth-child(5) .weekbar__col { animation-delay: .20s; }
.weekbar:nth-child(6) .weekbar__col { animation-delay: .25s; }
.weekbar:nth-child(7) .weekbar__col { animation-delay: .30s; }
.rank__fill { animation: hw-wipe .6s cubic-bezier(.22,.72,.28,1) both; }
.donut__seg { animation: hw-donut 900ms cubic-bezier(.22,.72,.28,1) both; }
@keyframes hw-donut { from { stroke-dasharray: 0 9999; } }
.ring__fg { animation: hw-donut 800ms cubic-bezier(.22,.72,.28,1) both; }
.spark__line { stroke-dasharray: 1400; animation: hw-draw 1.1s cubic-bezier(.3,.7,.3,1) both; }
@keyframes hw-draw { from { stroke-dashoffset: 1400; } to { stroke-dashoffset: 0; } }

/* Interaction feedback */
.card--interactive { transition: transform .16s cubic-bezier(.2,.7,.3,1), box-shadow .16s, border-color .16s; }
.card--interactive:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--gold) 55%, var(--line)); box-shadow: 0 20px 40px -24px rgba(80,66,40,.45); }
.flash { animation: hw-slide .3s cubic-bezier(.22,.72,.28,1) both; }
.modal { animation: hw-pop .22s cubic-bezier(.22,.72,.28,1) both; }
.backdrop { animation: hw-fade .16s ease both; }
.table tbody tr { transition: background .1s; }
.nav__link { position: relative; }

/* Skeleton for anything fetched after paint */
.skeleton {
  background: linear-gradient(90deg, var(--line-2) 25%, var(--line) 37%, var(--line-2) 63%);
  background-size: 200% 100%; animation: hw-shimmer 1.3s linear infinite;
  border-radius: 7px; color: transparent !important;
}
.spinner {
  width: 16px; height: 16px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid color-mix(in srgb, currentColor 25%, transparent);
  border-top-color: currentColor; animation: hw-spin .7s linear infinite;
}

/* Count-up numbers get tabular figures so the width never jitters mid-animation */
.countup { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .card--interactive:hover { transform: none; }
}

/* ==========================================================================
   EMPHASIS
   The page, the cards and the tiles were all ivory, so nothing anchored the
   eye. These give the dashboard a hierarchy: one dark hero that owns the
   page, colour-coded accents on the supporting numbers, and richer marks.
   ========================================================================== */

/* The one card that should own the screen. Cream on navy is ~15:1, so the
   number is easier to read here than it was on ivory. */
.card--feature {
  background:
    radial-gradient(620px 300px at 88% -30%, rgba(193,154,78,.30) 0%, transparent 62%),
    linear-gradient(150deg, var(--navy-3) 0%, var(--navy) 62%);
  border-color: transparent;
  color: #f4efe2;
  box-shadow: 0 22px 46px -26px rgba(1,25,54,.75);
  position: relative; overflow: hidden;
}
.card--feature .stat__label { color: var(--gold-soft); }
.card--feature .hero__value,
.card--feature .stat__value { color: #fdfaf3; }
.card--feature .stat__foot,
.card--feature .muted,
.card--feature .hint { color: rgba(244,239,226,.72); }
.card--feature a { color: var(--gold-soft); text-decoration: underline; text-underline-offset: 3px; }
.card--feature .spark__line { stroke: var(--gold-soft); }
.card--feature .delta--up   { color: #bfe6c6; background: rgba(191,230,198,.16); }
.card--feature .delta--down { color: #f0b8a8; background: rgba(240,184,168,.16); }
.card--feature .delta--flat { color: rgba(244,239,226,.8); background: rgba(244,239,226,.12); }

/* A colour-coded rule above the label ties each figure to its meaning and
   stops four identical ivory tiles reading as one grey block. */
/* Full-bleed stripe clipped by the card's own radius. Inset it instead and a
   3px bar floats above the curve, reading as detached from the card. */
.stat--accent { position: relative; overflow: hidden; }
.stat--accent::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--accent, var(--navy));
}
/* When a tile carries an icon-chip hue, the accent follows it, so the bar and
   the icon can never disagree about what kind of number this is. */
.stat-link.chip-blue   { --accent: linear-gradient(90deg, var(--cat-supplies), var(--navy)); }
.stat-link.chip-navy   { --accent: linear-gradient(90deg, #2c5b91, var(--navy)); }
.stat-link.chip-gold   { --accent: linear-gradient(90deg, var(--gold-soft), var(--gold)); }
.stat-link.chip-amber  { --accent: linear-gradient(90deg, var(--warn), var(--gold-dim)); }
.stat-link.chip-green  { --accent: linear-gradient(90deg, #6fae82, var(--ok)); }
.stat-link.chip-purple { --accent: linear-gradient(90deg, var(--cat-fuel), var(--navy)); }
.stat-link.chip-rose   { --accent: linear-gradient(90deg, var(--cat-flowers), var(--gold-dim)); }
.stat--money   { --accent: linear-gradient(90deg, var(--gold-soft), var(--gold)); }
.stat--owed    { --accent: linear-gradient(90deg, var(--warn), var(--gold-dim)); }
.stat--count   { --accent: linear-gradient(90deg, var(--cat-supplies), var(--navy)); }
.stat--good    { --accent: linear-gradient(90deg, #6fae82, var(--ok)); }

/* Card headers get a hairline of brand colour so sections read as designed
   rather than as a stack of boxes. */
.card__head { position: relative; }
.card--tinted .card__head::after {
  content: ""; position: absolute; left: 0; bottom: -1px; width: 96px; height: 2px;
  background: linear-gradient(90deg, var(--chip, var(--gold)), transparent);
}

/* Richer marks */
.weekbar__col {
  background: linear-gradient(180deg, #2c5b91 0%, var(--navy) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);
}
.weekbar__col--today {
  background: linear-gradient(180deg, var(--gold-soft) 0%, var(--gold-dim) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 4px 14px -6px rgba(193,154,78,.7);
}
.rank__fill {
  background: linear-gradient(90deg, #2c5b91, var(--navy));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.16);
}
.rank__track { background: color-mix(in srgb, var(--navy) 9%, var(--line-2)); }
.bar__fill { background: linear-gradient(90deg, #2c5b91, var(--navy)); }

/* Slightly more separation between the page and the cards it holds. */
.card { border-color: color-mix(in srgb, var(--line) 88%, var(--navy) 12%); }
.legend__dot { box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 0%, transparent); }
.donut__value { color: var(--navy); }

/* Empty states shouldn't be the loudest thing on a quiet day. */
.empty__title { color: var(--muted); }

/* Chart legends & direct labels.
   Values sit ON the marks rather than only in a tooltip — a hover-only value
   is useless on a printout, on a wall display, or to anyone using a keyboard. */
.chart-legend {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-2);
  font-size: 11.5px; color: var(--muted);
}
.chart-legend__item { display: inline-flex; align-items: center; gap: 7px; }
.chart-legend__swatch { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.chart-legend__swatch--series { background: linear-gradient(180deg, #2c5b91, var(--navy)); }
.chart-legend__swatch--today  { background: linear-gradient(180deg, var(--gold-soft), var(--gold-dim)); }
.chart-legend__swatch--line   { height: 2px; border-radius: 2px; background: var(--gold-soft); }
.chart-legend__sep { margin-left: auto; font-variant-numeric: tabular-nums; }

.weekbar__value {
  font-size: 10.5px; font-weight: 700; color: var(--ink-2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.weekbar__value--zero { color: var(--faint); font-weight: 500; }

/* Scale markers on the sparkline, so the shape has a magnitude. */
.spark-wrap { position: relative; }
.spark-scale {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 11px; margin-top: 6px; font-variant-numeric: tabular-nums;
}

/* Nested inside the daily report the group is already in a card, so it drops
   its own shadow and lifted look. */
.card .reviewgroup { box-shadow: none; border-color: var(--line); }
.card .reviewgroup .card__head { padding: 14px 16px; }
.card .reviewgroup .card__pad { padding: 14px 16px; }

/* ---------- receipt-context review --------------------------------------
   The basket is shown first and reads as a receipt; the items needing a
   decision sit underneath, so the context stays on screen while you choose.
   -------------------------------------------------------------------------- */
.reviewgroup__basket {
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 12px 14px;
}
.basketline {
  display: grid; grid-template-columns: 44px 1fr auto; gap: 10px;
  align-items: baseline; padding: 5px 0; font-size: 13px;
}
.basketline + .basketline { border-top: 1px dashed var(--line); }
.basketline__qty { color: var(--muted); font-variant-numeric: tabular-nums; text-align: right; }
.basketline__amt { font-weight: 600; font-variant-numeric: tabular-nums; }
.basketline.is-pending { background: color-mix(in srgb, var(--warn) 9%, transparent);
  margin: 0 -8px; padding: 6px 8px; border-radius: 7px; }
.basketline.is-pending + .basketline { border-top: 0; }
.basketline.is-pending .basketline__desc { font-weight: 600; }

.reviewgroup__resolve { margin-top: 16px; }
.reviewgroup__item { padding: 14px 0; border-top: 1px solid var(--line); }
.reviewgroup__item:first-child { border-top: 0; padding-top: 6px; }
.reviewgroup__itemHead {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px;
}
.reviewgroup__suggest { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 11px; }
.reviewgroup__suggestLabel {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
}
.reviewgroup__suggest .chip { font-weight: 600; }
.reviewgroup__suggest .chip:hover { background: var(--navy); color: #f4efe2; border-color: var(--navy); }

/* Shared inline resolver for unmatched clerk-typed items. */
.resolve-line {
  display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: start;
  padding: 14px 0; border-bottom: 1px solid var(--line-2);
}
.resolve-line:last-child { border-bottom: 0; }
/* The new-product form is a third child of the row; without this it drops into
   the narrow right-hand column beside the picker when the item's own heading
   is not drawn (inside a receipt sheet). */
.resolve-line > .resolve-new { grid-column: 1 / -1; }
.resolve-line__actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.resolve-line__actions form { display: flex; gap: 8px; }
.select--compact {
  min-width: 190px; padding: 8px 30px 8px 11px; font-size: 13px;
  background-position: calc(100% - 17px) 17px, calc(100% - 12px) 17px;
}
@media (max-width: 860px) {
  .resolve-line { grid-template-columns: 1fr; }
  .resolve-line__actions { justify-content: flex-start; }
  .resolve-line__actions form { flex: 1; }
  .select--compact { min-width: 0; flex: 1; }
}

/* Makes the Review badge look like the control it actually is. */
.badge-action { border: 0; cursor: pointer; font-family: inherit; text-decoration: none; }
.badge-action:hover { filter: brightness(.94); text-decoration: none; }

/* ---------- dashboard sparkle -------------------------------------------
   Colour used structurally rather than decoratively: a card's icon, its head
   accent and its marks all draw from one hue, so the eye can tell cards apart
   without reading them.
   -------------------------------------------------------------------------- */

/* A whisper of the card's hue in the corner — enough to tint the surface
   without tinting the text sitting on it. */
.card--tinted {
  background:
    radial-gradient(340px 150px at 100% 0%,
      color-mix(in srgb, var(--chip, var(--gold)) 9%, transparent) 0%, transparent 70%),
    var(--card);
}

/* Top 10 bars keep one hue — colour follows the entity, never its rank — but
   gain a highlight so the row reads as a bar and not a rule. */
.rank__fill {
  background: linear-gradient(90deg, color-mix(in srgb, var(--cat-supplies) 55%, var(--navy)), var(--navy));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22);
}
.rank__row:hover .rank__fill { filter: brightness(1.15); }

/* The donut sits on the surface rather than floating on it. */
.donut svg { filter: drop-shadow(0 6px 14px rgba(80,66,40,.16)); }
:root[data-theme="dark"] .donut svg { filter: drop-shadow(0 6px 16px rgba(0,0,0,.55)); }
.legend__item { padding: 3px 0; border-radius: 6px; transition: background .12s; }
.legend__item:hover { background: var(--card-2); }

/* Table rows pick up the card's hue on hover instead of flat grey. */
.card--tinted .table tbody tr:hover {
  background: color-mix(in srgb, var(--chip, var(--navy)) 6%, var(--card-2));
}

/* The hero gets a slow highlight sweep once on load — a hint of life, not a
   loop, and it yields to reduced-motion like everything else. */
.card--feature::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 30%,
              rgba(244,239,226,.10) 45%, rgba(244,239,226,.02) 58%, transparent 70%);
  transform: translateX(-100%);
  animation: hw-sheen 1.5s cubic-bezier(.3,.7,.4,1) .35s both;
}
@keyframes hw-sheen { to { transform: translateX(100%); } }

/* Stat tiles: the figure takes the card's hue so four tiles aren't four
   identical navy numbers. */
.stat-link.chip-amber .stat__value,
.stat.chip-amber .stat__value { color: var(--warn); }
.stat-link.chip-green .stat__value { color: var(--ok); }
.stat-link.chip-blue  .stat__value { color: var(--cat-supplies); }
.stat.chip-gold .stat__value { color: var(--gold-dim); }
:root[data-theme="dark"] .stat.chip-gold .stat__value { color: var(--gold); }

/* ---------- more impact -------------------------------------------------
   Depth and motion used to make structure legible, not for decoration. Every
   rule here still answers to prefers-reduced-motion.
   -------------------------------------------------------------------------- */

/* Cards lift on hover so the grid feels like objects rather than a wall. */
.card { transition: transform .18s cubic-bezier(.2,.7,.3,1), box-shadow .18s, border-color .18s; }
.card--tinted:hover {
  transform: translateY(-2px);
  box-shadow: 0 22px 44px -26px rgba(80,66,40,.5);
  border-color: color-mix(in srgb, var(--chip, var(--gold)) 40%, var(--line));
}
:root[data-theme="dark"] .card--tinted:hover { box-shadow: 0 22px 44px -24px rgba(0,0,0,.85); }

/* The hero gets real depth: a soft coloured glow beneath it rather than a
   flat drop shadow. */
.card--feature {
  box-shadow:
    0 26px 55px -28px rgba(1,25,54,.85),
    0 0 0 1px rgba(244,239,226,.06) inset;
}
/* A slow gold aura in the corner, so the darkest card on the page still feels
   warm rather than a black hole. */
.card--feature::before {
  content: ""; position: absolute; top: -40%; right: -12%;
  width: 420px; height: 420px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(193,154,78,.22) 0%, transparent 62%);
}

/* Big figures get a subtle gradient rather than flat ink. */
.hero__value {
  background: linear-gradient(160deg, #fffdf8 0%, #e8dfc8 78%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Bars: a highlight along the top edge reads as a lit surface. */
.hourbar__col::after, .weekbar__col::after {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 40%;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,.22), transparent);
  pointer-events: none;
}
.hourbar__col, .weekbar__col { position: relative; }
.weekbar__col:hover, .hourbar__col:hover { filter: brightness(1.16) saturate(1.05); }

/* Icon chips get a light source, so they read as objects not flat squares. */
.icon-chip {
  background:
    linear-gradient(160deg,
      color-mix(in srgb, var(--chip, var(--navy)) 20%, transparent) 0%,
      color-mix(in srgb, var(--chip, var(--navy)) 9%,  transparent) 100%);
}
.card--interactive:hover .icon-chip { transform: scale(1.08) rotate(-3deg); }

/* Tag pills lift slightly on the qb ones, since they carry more weight. */
.tag--qb { transform: translateZ(0); }

/* Section rhythm: a hairline rule that fades, rather than a hard divider. */
.divider {
  background: linear-gradient(90deg, var(--line) 0%, var(--line) 40%, transparent 100%);
}

/* Badges get a touch of dimension. */
.badge { box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent); }
:root[data-theme="dark"] .badge { box-shadow: inset 0 1px 0 rgba(255,255,255,.06); }

/* Primary buttons: a brighter top edge and a deeper press. */
.btn--primary, .btn--ok, .btn--gold {
  box-shadow: var(--shadow-btn), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn--primary:active, .btn--ok:active, .btn--gold:active {
  transform: translateY(1px);
  box-shadow: 0 6px 14px -8px rgba(1,25,54,.6), inset 0 1px 0 rgba(255,255,255,.12);
}

/* The page itself gets a faint warm vignette so content floats on something. */
body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(120% 80% at 50% -20%,
              rgba(193,154,78,.10) 0%, transparent 55%);
}
.app { position: relative; z-index: 1; }

/* Numbers that count up settle with a tiny scale, so the eye catches them. */
.countup { display: inline-block; animation: hw-settle .8s cubic-bezier(.2,.7,.3,1) both; }
@keyframes hw-settle { from { transform: scale(.97); opacity: .55; } to { transform: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .card--tinted:hover, .card--interactive:hover .icon-chip { transform: none; }
  .countup { animation: none; }
  .card--feature::after { animation: none; opacity: 0; }
}

/* ---------- responsive header -------------------------------------------
   The breakpoint is where the nav stops fitting on one line, not a device
   width. Below it the links move into a drawer so the header stays a single
   row — which also keeps the register's height predictable.
   -------------------------------------------------------------------------- */
@media (max-width: 1440px) {
  /* Compact tier: every section stays one tap away on a laptop. */
  .topbar { gap: 10px; padding: 12px 16px; }
  .nav__link { padding: 7px 8px; font-size: 12px; }
  .who { gap: 8px; }
  .helddrop__word { display: none; }
}
@media (max-width: 1360px) { .who__meta { display: none; } }
/* Eleven sections do not fit an iPad in landscape (1180px) beside the header
   cluster, so tablets get the drawer; laptops from 1280px keep the full row. */
@media (max-width: 1220px) {
  .nav-toggle { display: flex; }

  .nav {
    position: absolute; top: calc(100% + 8px); left: 12px; right: 12px;
    flex-direction: column; flex-wrap: nowrap; gap: 2px;
    background: var(--card); border: 1px solid var(--line);
    border-radius: var(--r-lg); box-shadow: var(--shadow-pop);
    padding: 10px; z-index: 40; max-height: 70vh; overflow-y: auto;
  }
  .topbar:not(.is-open) .nav { display: none; }
  .nav__link { padding: 12px 14px; border-radius: var(--r-sm); font-size: 15px; }

  .nav__extras {
    display: flex; flex-direction: column; gap: 2px;
    margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--line);
  }

  /* Tapping outside closes it. */
  .topbar.is-open ~ .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 20;
    background: rgba(20,16,10,.28);
  }

  .main { padding: 20px 18px; }
}

@media (max-width: 720px) {
  /* The avatar still identifies who is signed in; the rest is in the drawer. */
  .who__hide-sm { display: none; }
  .brand__logo { height: 26px; }
  .page-title { font-size: 23px; }
  .main { padding: 16px 14px; }
  .card__pad, .stat { padding: 16px 17px; }
  .hero { padding: 20px 20px; }
}

/* ==== audit-2026-09-09: POS / sales / customers (agent 1) ==== */

/* The picker's "recents until you type" never worked: display:flex beat the
   hidden attribute, so every customer always showed. */
.custlist__item[hidden] { display: none; }
.custlist { max-height: 36vh; }
.text-danger { color: var(--danger); }
/* Filters as one row that wraps on a tablet. */
.filterbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: end; }
.filterbar .field { margin: 0; flex: 1 1 150px; }
.filterbar .field:first-child { flex: 2 1 220px; }
.filterbar .btn--block { width: 100%; }
/* Balances: two column sets on one table. hidden must win over display rules. */
.balmode[hidden], .flash.balmode[hidden], .card.balmode[hidden] { display: none; }
/* Register pay row: full / part / on account read as one set. */
.payset { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.payset .btn { width: 100%; }
/* Tendered / change on the cash sheet. */
.change { display: flex; justify-content: space-between; align-items: baseline; margin-top: 10px; font-size: 14px; }
.change__val { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.change--short .change__val { color: var(--danger); }
.tenders .btn.is-on { outline: 2px solid var(--navy); outline-offset: 2px; }
[data-customer-form] .divider { background: var(--line); }
[data-customer-form] [hidden] { display: none; }
/* Open receipts table on the customer page. */
.table--compact td, .table--compact th { padding-top: 8px; padding-bottom: 8px; }

/* ==== audit-2026-09-09: reports / catalog / review (agent 2) ==== */


.page-head__tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.inline-form { display: inline-flex; align-items: center; gap: 8px; margin: 0; }
.select--sm { padding: 7px 30px 7px 10px; font-size: 13px; min-height: 36px; }
.table__total td { border-top: 2px solid var(--line-strong, var(--line)); font-weight: 600; }
tr.is-more[hidden] { display: none; }

.section-label { font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 4px 0 10px; }

/* Dashboard at tablet width: the hero keeps the row, the two tiles sit side
   by side under it, and the lower cards stack full-width instead of leaving
   a half-width orphan. */
.dash-hero__main { grid-column: span 2; }
.dash-hero__side { display: flex; flex-direction: column; gap: 18px; }
.dash-lower__main { grid-column: span 2; }
@media (max-width: 1100px) {
  .dash-hero__main, .dash-lower__main { grid-column: 1 / -1; }
  .dash-hero__side { grid-column: 1 / -1; flex-direction: row; }
  .dash-hero__side > * { flex: 1; }
  .dash-lower > * { grid-column: 1 / -1; }
}
@media (max-width: 720px) { .dash-hero__side { flex-direction: column; } }

/* Year-over-year chart: a money axis and round gridlines, matching the
   financial chart. The pair height (170px) is the plot height; labels and
   deltas hang below it, so the axis is padded by the same 42px. */
.yoy-wrap { display: flex; gap: 10px; }
.yoy-axis {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 170px; text-align: right; flex: none; min-width: 34px;
  font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums;
}
.yoy-axis__tick { line-height: 1; transform: translateY(-50%); }
.yoy-axis__tick:first-child { transform: none; }
.yoy-axis__tick:last-child  { transform: translateY(-100%); }
.yoy-plot { position: relative; flex: 1; min-width: 0; }
.yoy-grid { position: absolute; left: 0; right: 0; top: 0; height: 170px; display: flex; flex-direction: column-reverse; justify-content: space-between; pointer-events: none; }
.yoy-grid__line { height: 1px; background: var(--line); opacity: .75; }
.yoy-grid__line:first-child { background: var(--line-2); opacity: 1; }
.yoy { position: relative; }
.yoy__value { position: absolute; left: 0; right: 0; text-align: center; font-size: 10.5px; font-weight: 650; color: var(--ink-2); font-variant-numeric: tabular-nums; pointer-events: none; }

/* Review queue rows, grouped by typed text. */
.rq { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--card); padding: 14px 16px; }
.rq__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 8px; }
.rq__what strong { font-size: 15px; }
.rq__meta { display: block; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.rq__tools { flex: none; }
.rq__receipts { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 8px; display: flex; flex-direction: column; gap: 6px; font-size: 13px; }
.rq__receipt { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.chip--remembered { border-color: var(--gold); box-shadow: 0 0 0 2px color-mix(in srgb, var(--gold) 25%, transparent); }

.catalog-filter { display: flex; flex-direction: column; gap: 12px; }
.catalog-filter .input { max-width: 420px; }
.chip--qb { border-color: color-mix(in srgb, var(--gold) 55%, var(--line)); }

.segmented.is-invalid { border-color: var(--danger); box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 25%, transparent); }

.tagrow { display: flex; gap: 10px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--line-2); flex-wrap: wrap; }
.tagrow .input { flex: 1; min-width: 140px; padding: 7px 11px; font-size: 13px; }
.tagrow__active { padding: 0; margin: 0; }
.tagrow__active .check__body { padding: 0; }

/* ==== audit-2026-09-09: layout / admin (agent 3) ==== */
.loadbar {
  position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 1000;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft, var(--gold)));
  box-shadow: 0 0 8px rgba(193,154,78,.55);
  opacity: 0; pointer-events: none;
  transition: width 4s cubic-bezier(.1,.7,.2,1), opacity .2s;
}
.loadbar.is-on { opacity: 1; }
@media print { .loadbar { display: none; } }
.stat__value.is-warn { color: var(--warn); }
/* A lone card in a two-column grid fills the row. */
@media (min-width: 721px) { .grid--2 > :last-child:nth-child(odd) { grid-column: span 2; } }
.page-head .btn-row form { display: inline; }
.filterbar__check { margin: 0 0 8px; }



/* hidden always wins over any display rule */
[hidden] { display: none !important; }

/* Bars inside table cells: the track is a <span>; inline boxes have no width. */
td > .rank__track { display: block; width: 100%; min-width: 80px; }

/* ==== daily report: QuickBooks entry sheet (2026-09-14) ==== */
.qb-sheet__table th, .qb-sheet__table td { white-space: nowrap; }
.qb-sheet__table th { position: sticky; top: 0; }
.qb-sheet__table thead th:first-child, .qb-sheet__table tbody td:first-child,
.qb-sheet__table tfoot td:first-child { position: sticky; left: 0; background: var(--card-2); z-index: 2; }
.qb-sheet__table thead th:first-child { z-index: 3; }
.qb-sheet__table tbody td:first-child { background: var(--card); }
.qb-sheet__table tbody tr:hover td:first-child { background: var(--card-2); }
.qb-sheet__cust { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
.qb-sheet__time { opacity: .6; font-size: 11.5px; }
.qb-sheet__cat { border-left: 1px solid var(--line-2); }
.qb-sheet__cat--none { background: color-mix(in srgb, var(--warn) 8%, transparent); }
.qb-sheet__dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: 1px; }
.qb-zero { color: var(--line); }
.qb-sheet__totals td { border-top: 2px solid var(--line); background: var(--card-2); }
@media print {
  .qb-sheet { page-break-inside: auto; }
  .qb-sheet__table { font-size: 11px; }
  .qb-sheet__table th, .qb-sheet__table td { padding: 4px 6px; }
  .qb-sheet__table tr { page-break-inside: avoid; }
  .qb-sheet__table thead th:first-child, .qb-sheet__table tbody td:first-child { position: static; }
  .qb-zero { color: #bbb; }
}

/* ==== print after payment (2026-09-14) ==== */
.printopt { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-2); font-size: 13px; color: var(--muted); }
.printopt input:checked + span { color: var(--ink); }

/* ==== daily report: receipt modals (2026-09-14) ==== */
.qb-sheet__open { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; }
button.badge.qb-sheet__open { font: inherit; font-size: 10.5px; }
.qb-sheet__open:hover { text-decoration: underline; }
.reviewgroup--bare .reviewgroup__basket { margin-top: 0; }
.qb-modal__totals { margin-left: auto; width: 260px; margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line); }
.qb-modal__totals .totals__grand { font-size: 20px; }
@media print { .backdrop { display: none !important; } }

/* ==== POS ticket on a short screen (2026-09-14) ====
   The ticket column is pinned to the viewport height. When its fixed parts
   (customer, totals, delivery, the pay buttons) alone outgrow it — an iPad
   in landscape with Safari's bars up — the leftovers used to hang out below
   the card. Now the card scrolls instead, so the pay button always sits
   inside it and the buttons under it stay reachable. */
.pos__ticket { overflow-y: auto; overscroll-behavior: contain; }
.pos__ticket > .lines { flex: 1 0 96px; }
/* The pay button stays in view while the card scrolls: it is the one thing
   the clerk is reaching for. */
.pos__ticket > .btn--ok.btn--xl { position: sticky; bottom: -1px; z-index: 5; box-shadow: 0 -10px 16px -6px var(--card); }

/* ==== account payment: choose the receipts (2026-09-14) ==== */
.payrows { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--r-md, 10px); overflow: hidden; max-height: 280px; overflow-y: auto; }
.payrow { display: grid; grid-template-columns: 20px 74px 1fr auto 128px; gap: 10px; align-items: center; padding: 9px 12px; border-bottom: 1px solid var(--line-2); cursor: pointer; font-size: 13px; }
.payrow:last-child { border-bottom: 0; }
.payrow input[type=checkbox] { width: 17px; height: 17px; accent-color: var(--navy); margin: 0; }
.payrow__no { font-weight: 600; }
.payrow__meta { color: var(--muted); font-size: 12px; }
.payrow__late { color: var(--warn); font-weight: 600; }
.payrow__bal { font-variant-numeric: tabular-nums; color: var(--muted); font-size: 12.5px; }
.payrow__amt input { padding: 6px 8px; font-size: 13.5px; text-align: right; font-variant-numeric: tabular-nums; }
.payrow.is-off { opacity: .55; }
.payrow.is-off .payrow__amt { visibility: hidden; }
@media (max-width: 560px) { .payrow { grid-template-columns: 20px 1fr auto; } .payrow__meta { grid-column: 2 / span 2; } .payrow__amt { grid-column: 2 / span 2; justify-self: end; } }
.payrow__amt { height: 36px; padding: 0 10px; border-color: var(--line); }
.payrow__amt .cur { font-size: 13px; }
.payrow__amt input { font-size: 14px; font-weight: 600; }

/* ==== tag filter: any / all (2026-09-14) ==== */
.tagmatch { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 999px; padding: 2px; margin-left: 6px; background: var(--card); vertical-align: middle; }
.tagmatch__opt { padding: 5px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600; color: var(--muted); border: 0; background: none; cursor: pointer; text-decoration: none; }
.tagmatch__opt:hover { color: var(--ink); text-decoration: none; }
.tagmatch__opt.is-on { background: var(--navy); color: #fff; }
.tagmatch--block { margin: 0 0 12px; }

/* ==== catalog as a spreadsheet (2026-09-14) ==== */
.editrow td { padding: 8px 10px; vertical-align: middle; }
.cellin { padding: 6px 8px; font-size: 13.5px; height: auto; min-height: 34px; }
.cellin--name { width: 100%; min-width: 180px; font-weight: 600; }
.cellin--sku  { width: 100%; min-width: 120px; margin-top: 4px; font-size: 12px; color: var(--muted); }
.cellin--cat  { min-width: 120px; }
.cellin--tags { width: 100%; min-width: 180px; }
.cellin--check { width: 18px; height: 18px; accent-color: var(--navy); }
.cellin.is-changed, select.cellin.is-changed { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 12%, var(--card)); }
.editrow .priceedit__input { width: 96px; }
.table .center { text-align: center; }

/* ==== click a heading to sort (2026-09-14) ==== */
.table th.is-sortable { cursor: pointer; user-select: none; }
.table th.is-sortable:hover { color: var(--ink); }
.table th.is-sortable::after { content: ""; display: inline-block; width: 0; height: 0; margin-left: 6px; vertical-align: 2px; border-left: 3.5px solid transparent; border-right: 3.5px solid transparent; border-bottom: 5px solid currentColor; opacity: 0; transition: opacity .12s; }
.table th.is-sortable:hover::after { opacity: .35; }
.table th.is-sortable[aria-sort="ascending"]::after { opacity: 1; color: var(--gold); }
.table th.is-sortable[aria-sort="descending"]::after { opacity: 1; color: var(--gold); border-bottom: 0; border-top: 5px solid currentColor; }
.table th.num.is-sortable::after { margin-left: 5px; }

/* ==== estimate sheet: customer row (2026-09-14) ==== */
.estcust { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card-2); font-size: 13.5px; }
.estcust--none { border-color: color-mix(in srgb, var(--warn) 55%, var(--line)); background: color-mix(in srgb, var(--warn) 9%, var(--card)); }
.estcust__name { flex: 1; }

/* ==== scheduled orders: stock step (2026-09-14) ==== */
.stockpanel__row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.toorder > summary { list-style: none; cursor: pointer; }
.toorder > summary::-webkit-details-marker { display: none; }
.toorder__head { display: flex; justify-content: space-between; align-items: center; }
.toorder__head .card__title::before { content: "▸ "; color: var(--muted); font-size: 12px; }
.toorder[open] > summary .card__title::before { content: "▾ "; }
@media print { .toorder > summary .btn { display: none; } .chips { display: none; } }
.payrow--po { grid-template-columns: 20px 1fr auto auto; }

/* ==== dashboard hero in dark mode (2026-09-14) ====
   Dark mode lightens --navy so navy TEXT stays readable on a dark ground; the
   hero borrowed the same variable for its BACKGROUND and turned periwinkle.
   The hero keeps a deep navy of its own here. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card--feature {
    background:
      radial-gradient(620px 300px at 88% -30%, rgba(216,184,120,.16) 0%, transparent 62%),
      linear-gradient(150deg, #16294a 0%, #0b1a33 62%);
    box-shadow: 0 26px 55px -28px rgba(0,0,0,.85), 0 0 0 1px rgba(244,239,226,.06) inset;
  }
  :root:not([data-theme="light"]) .card--feature::before { background: radial-gradient(circle, rgba(216,184,120,.14) 0%, transparent 62%); }
}
:root[data-theme="dark"] .card--feature {
  background:
    radial-gradient(620px 300px at 88% -30%, rgba(216,184,120,.16) 0%, transparent 62%),
    linear-gradient(150deg, #16294a 0%, #0b1a33 62%);
  box-shadow: 0 26px 55px -28px rgba(0,0,0,.85), 0 0 0 1px rgba(244,239,226,.06) inset;
}
:root[data-theme="dark"] .card--feature::before { background: radial-gradient(circle, rgba(216,184,120,.14) 0%, transparent 62%); }

/* ==== hero: let the range picker escape (2026-09-14) ====
   The hero hid its overflow to keep the gold aura and the load-time sheen
   inside its corners, and that clipped the range picker's dropdown. The aura
   and the sheen now fit inside the card by themselves, so the card can let
   the picker hang below it. */
.card--feature { overflow: visible; }
.card--feature::before {
  inset: 0; top: 0; right: 0; width: auto; height: auto; border-radius: inherit;
  background: radial-gradient(420px circle at 100% -20%, rgba(193,154,78,.22) 0%, transparent 62%);
}
.card--feature::after {
  border-radius: inherit; transform: none;
  background: linear-gradient(105deg, transparent 30%, rgba(244,239,226,.10) 45%, rgba(244,239,226,.02) 58%, transparent 70%);
  background-size: 300% 100%; background-position: 0% 0;
  animation: hw-sheen-bg 1.5s cubic-bezier(.3,.7,.4,1) .35s both;
}
@keyframes hw-sheen-bg { to { background-position: 100% 0; } }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card--feature::before { background: radial-gradient(420px circle at 100% -20%, rgba(216,184,120,.14) 0%, transparent 62%); }
}
:root[data-theme="dark"] .card--feature::before { background: radial-gradient(420px circle at 100% -20%, rgba(216,184,120,.14) 0%, transparent 62%); }

/* ==== deliveries (2026-09-14) ==== */
.dlv { display: grid; grid-template-columns: 1fr 200px; gap: 18px; padding: 18px 20px; align-items: start; }
.dlv--signed { opacity: .82; }
.dlv__name { font-size: 18px; font-weight: 700; }
.dlv__meta { color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.dlv__addr { display: flex; gap: 8px; align-items: flex-start; margin-top: 12px; font-size: 16px; line-height: 1.4; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.dlv__addr--none { color: var(--warn); text-decoration: none; }
.dlv__phone { display: inline-block; margin-top: 8px; font-size: 16px; font-weight: 600; }
.dlv__items { margin-top: 10px; font-size: 13px; color: var(--muted); }
.dlv__note { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: color-mix(in srgb, var(--warn) 10%, var(--card)); font-size: 13px; }
.dlv__side { display: flex; flex-direction: column; gap: 8px; align-items: stretch; text-align: center; }
.dlv__sign { padding: 20px; font-size: 18px; }
.dlv__signed img { max-height: 64px; max-width: 100%; background: #fff; border-radius: 8px; padding: 4px; }
@media (max-width: 640px) { .dlv { grid-template-columns: 1fr; } .dlv__side { text-align: left; } }

.dlvsum { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: -6px 0 14px; font-size: 13px; color: var(--muted); }
.dlvsum__item b { color: var(--ink); font-weight: 700; }
.dlvsum__item--warn b { color: var(--warn); }
.dlvsum__item--info b { color: var(--info); }
.dlv__status { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* ==== catalog archive (2026-09-14) ==== */
.table tr.is-archived td { color: var(--muted); }
.table tr.is-picked td { background: color-mix(in srgb, var(--gold) 10%, var(--card)); }
.bulkbar[hidden] { display: none; }
.table td form { display: inline; }

/* ==== deliveries map (2026-09-14) ==== */
.dlvmap { height: 380px; border-radius: 0 0 var(--r-lg) var(--r-lg); background: var(--card-2); }
.dlvpin { background: none; border: 0; }
.dlvpin span { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg); color: #fff; font: 700 12px/1 var(--sans); box-shadow: 0 3px 8px rgba(0,0,0,.35); border: 2px solid #fff; }
.dlvpin span > * { transform: rotate(45deg); }
.dlvpin--open span { background: #1F6FB2; } .dlvpin--owing span { background: #C98A1E; } .dlvpin--unrung span { background: #7B4B9E; } .dlvpin--signed span { background: #2E8B57; }
.dlvpin span { text-indent: 0; }
.dlvpin span::before { content: ""; }
.dlvkey { display: inline-block; width: 10px; height: 10px; border-radius: 50%; vertical-align: -1px; margin-right: 3px; }
.dlvkey--open { background: #1F6FB2; } .dlvkey--owing { background: #C98A1E; } .dlvkey--unrung { background: #7B4B9E; } .dlvkey--signed { background: #2E8B57; }
.dlv__num { display: inline-flex; align-items: center; justify-content: center; min-width: 26px; height: 26px; padding: 0 6px; border-radius: 999px; color: #fff; font-size: 13px; font-weight: 700; margin-right: 6px; vertical-align: 2px; }
.dlv__num--open { background: #1F6FB2; } .dlv__num--owing { background: #C98A1E; } .dlv__num--unrung { background: #7B4B9E; } .dlv__num--signed { background: #2E8B57; }
.leaflet-container { font-family: var(--sans); }
.leaflet-popup-content { font-size: 13px; line-height: 1.45; }
.dlvpin--shop span { background: #4a4740; border-radius: 6px; transform: none; } .dlvpin--shop span > * { transform: none; }
.dlvkey--shop { background: #4a4740; border-radius: 2px; }
.dlv__drive { background: color-mix(in srgb, var(--navy) 10%, var(--card)); color: var(--ink); }

/* ==== deliveries: runs and assignment (2026-09-14) ==== */
.dlvrun { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 6px 4px 2px; margin-top: 8px; }
.dlvrun__who { font-weight: 700; font-size: 15px; }
.dlv__pick { float: right; margin: -4px -4px 0 8px; }
.dlv__pick input { width: 22px; height: 22px; }
.dlv.is-picked { outline: 2px solid var(--gold); outline-offset: -2px; }
.dlvassign .select--compact { min-width: 160px; }
.planstop { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 9px 0; border-top: 1px solid var(--line-2); }
.planstop:first-child { border-top: 0; }

/* ==== register on a phone (2026-09-14) ====
   The ticket is the page; the catalog is a picker that slides over it.
   Phones only: tablets and laptops keep the side-by-side (or stacked) register. */
.pos__pickhead { display: none; }
.pos__add { display: none; }
@media (max-width: 720px) {
  .pos__catalog { display: none; }
  .pos--pick .pos__catalog {
    display: flex; position: fixed; inset: 0; z-index: 60; border-radius: 0; padding: 14px 16px;
    background: var(--card); overflow: hidden;
  }
  .pos--pick .tilegrid { overflow: auto; }
  .pos--pick { overflow: hidden; }
  .pos__pickhead { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
  .pos__pickhead-title { font-family: var(--serif); font-size: 20px; font-weight: 700; }
  .pos__add {
    display: flex; align-items: center; justify-content: center;
    position: fixed; right: 18px; bottom: 18px; z-index: 50;
    width: 60px; height: 60px; border-radius: 50%; border: 0; cursor: pointer;
    background: var(--navy); color: #f4efe2; font-size: 34px; line-height: 1; font-weight: 300;
    box-shadow: 0 10px 24px -8px rgba(1,25,54,.6);
  }
  .pos--pick .pos__add { display: none; }
  .pos__ticket { padding-bottom: 90px; }
}

/* ==== catalog: the delivery item, apart (2026-09-14) ==== */
.dlvitem { border-color: color-mix(in srgb, var(--gold) 55%, var(--line)); }
.dlvitem__row { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; }
.dlvitem__name { font-size: 16px; font-weight: 700; margin-top: 4px; }
.dlvitem__side { display: flex; align-items: center; gap: 12px; }

/* ==== an open range picker sits above the cards below it (2026-09-14) ====
   The rise animation leaves a transform on every card, which makes each one
   a stacking context; a dropdown hanging out of one card was painted under
   the next. */
.card:has(details.rangepicker[open]), .page-head:has(details.rangepicker[open]) { position: relative; z-index: 45; }
.card--feature:has(details.rangepicker[open]) { z-index: 45; }
