/* Gulwathe Supplied Ltd ERP mockup — app.css (FOUNDATION): tokens, shell and shared components.
 * R6 "calm and clear" (research/erp-redesign/REDESIGN-SPEC.md): one figure leads each screen, lists are hairline rows,
 * blue only means "act here". Somali-flag light blue + white, built for outdoor sunlight. No gradients, no emoji.
 * Helper API with examples: research/erp-redesign/R6-COMPONENTS.md. Dashboard-only rules live in css/dashboard.css.
 *
 * Shared classes for module builders (reuse these; add only module-specific rules in your own css file):
 *  tokens   type --t-hero --t-title --t-h2 --t-h3 --t-body --t-meta --t-label --t-key (use as `font: var(--t-h3)`)
 *           space --s-1 4 · --s-2 8 · --s-3 12 · --s-4 16 · --s-5 20 · --s-6 24 · --s-8 32 · --s-10 40
 *           radius --r-plate 6 · --r-input 12 · --r-card 16 · --r-sheet 20 · --r-pill 999 (old --r-1/2/3 alias onto these)
 *           motion (R8, Emil Kowalski rules) --ease-out (enter, press release) · --ease-in-out (on-screen movement) ·
 *                  --ease-drawer (sheets, side panel, phone chat) · --d-press 140 · --d-fast 160 · --d-pop-in 180 / --d-pop-out 140 ·
 *                  --d-sheet-in 260 / --d-sheet-out 200 · --d-panel-in 260 / --d-panel-out 200 · --d-msg 200 · --d-row 240.
 *                  Animate transform and opacity only; exits are faster than entrances; no motion on tab switches,
 *                  typing, keypad or filter Apply; money never counts up. Reduced motion: ONE global block at the end.
 *  R10      "Cut Stone" (research/erp-r10/FOUNDATION-API.md): tokens --hero* --ledge --stone-* --chip-* --strata --font-display
 *           --t-hero --t-page-title --t-display --t-h2-display, motion --d-tap/tick/indicator/rise/collapse/stamp/draw/count/
 *           blast/skel-pulse --spring-settle/stamp/sheet --ease-exit. Classes .q-hero .q-display .seal .qload .skel .illo
 *           .empty__art .tabs__ind .toast__act/__bar .q-fresh .q-blast; html.no-motion (reduced motion: system OR switch).
 *  R6       .stats (Q.ui.statStrip) · .lrow .lrows (Q.ui.listRow / list) · .glist (Q.ui.groupedList) · .abar (Q.ui.actionBar)
 *           .taskh (Q.ui.taskHeader) · .fpill (Q.ui.filterPill) · .fsheet (Q.ui.filterSheet) · .inotice (Q.ui.notice)
 *           .kpad (Q.ui.keypad) · .stxt (Q.ui.statusText) · .ph__info (Q.ui.infoButton) · .btn--quiet
 *  layout   .page-head .page-title .page-sub .page-tools .ph__toolbar · .stack .row .spacer · .grid-2 .grid-3 · .toolbar
 *  surfaces .card .card__head .card__title .card__body · .notice (.notice--warn/--danger/--ok) · .empty
 *  buttons  .btn + --primary --secondary --quiet --ghost --danger --info --block --sm --xl (all pills) · .icon-btn · .backlink
 *  forms    .field .field__label .field__hint .field__error .input .input--xl .input-group · .check · .form-grid
 *  status   .pill (via Q.ui.pill, detail screens) · .stxt (rows) · .badge (--danger --warn) · .tag (--muted) · .chip · .prov · .plate
 *  data     .tbl/.table/.tcards (via Q.ui.table) · .kv (key/value list) · .totals (summary strip) · .num .mono
 *  control  .seg (Q.ui.segmented, sliding thumb) · .tabs (Q.ui.tabs) · .weekpick · .stepper (Q.ui.stepper) · .paypick (Q.ui.methodPicker)
 *  R1       .entry-card (centred ~560px form card on desktop, plain column on phone) · .rec-sheet · .viewas · .pstage
 *  text     .muted .small .tone-ok .tone-warn .tone-danger .tone-info .sr-only
 *  chrome   html.is-task (task mode: no phone tab bar) · html.no-branch-pill (the screen has its own branch control)
 * Elevation: cards and lists are flat (1 px --line, no shadow); --shadow-up only on fixed chrome (tab bar, sticky
 * action bar); --shadow-2 only on sheets, modals, popovers and toasts.
 */

/* ------------------------------------------------------------------ tokens
 * R5: the ONE colour set — Somali-flag light blue + white, sunlight first. Every colour in every css file comes from
 * here; qa/r5-contrast.cjs reads these three blocks, checks every pair the screens use and lints for literals.
 *   --brand        the flag light blue #4189DD — graphics only (logo, bars): white on it is 3.6:1, too low for small text
 *   --accent       the darker brand blue for white-text buttons, current tab, ticks (white on it 6.4:1)
 *   --accent-text  brand-blue TEXT on white or the light tint
 *   --accent-soft  the light tint for selected rows, chips and avatars
 * Status colours (ok / warn / danger) stay apart from the brand, and every status keeps its label and icon.
 * R6 adds the non-colour tokens (type, space, radius, motion) at the end of this block; colour values are unchanged. */
:root {
  color-scheme: light;
  --bg: #F4F2ED; --surface: #FFFFFF; --surface-2: #E8E4DC; --surface-3: #F8F6F2;   /* R10 §2.1: limestone ground */
  --ink: #0F1B2D; --ink-2: #33445A; --ink-3: #4A5A70;
  --line: #D8D2C6; --line-strong: #6B7F97;
  --brand: #4189DD; --logo-bg: #4189DD; --logo-ink: #FFFFFF; --logo-ring: rgba(255, 255, 255, .6);
  --nav: #1F5FA8; --nav-2: #184C87; --nav-ink: #FFFFFF; --nav-ink-2: #DCE9F8; --nav-mark: #FFFFFF;
  --nav-active: #133F72; --nav-veil: rgba(255, 255, 255, .12); --nav-line: rgba(255, 255, 255, .22); --nav-focus: #FFFFFF;
  --accent: #1F5FA8; --accent-hover: #184C87; --on-accent: #FFFFFF; --accent-text: #1F5FA8; --accent-soft: #EAF3FC;
  --on-accent-veil: rgba(255, 255, 255, .16); --on-accent-line: rgba(255, 255, 255, .35);
  --info: #1F5FA8; --info-strong: #1F5FA8; --info-soft: #EAF3FC; --on-info: #FFFFFF;
  --ok: #1B7340; --ok-soft: #E5F3EA;
  --warn: #8A4F00; --warn-soft: #FDF0D9; --warn-bar: #B87711;
  --danger: #B42318; --danger-strong: #B42318; --danger-hover: #9A1D14; --danger-soft: #FCE9E7; --on-danger: #FFFFFF;
  --neutral: #3F4C5E; --neutral-soft: #EAEFF5;
  --badge-warn-bg: #F2B65C; --badge-warn-ink: #2A1C00;
  --focus: #123E70;
  --bar-sales: #4189DD; --bar-exp: #B87711;
  --shadow-1: 0 1px 2px rgba(15, 27, 45, .06), 0 1px 1px rgba(15, 27, 45, .04);
  --shadow-2: 0 12px 32px rgba(15, 27, 45, .18), 0 2px 6px rgba(15, 27, 45, .08);
  --shadow-up: 0 -6px 18px rgba(15, 27, 45, .08);
  --backdrop: rgba(8, 15, 28, .5);
  --plate-bg: #FFFFFF; --plate-ink: #0F1B2D; --plate-line: #0F1B2D;
  --toast-bg: #0F1B2D; --toast-ink: #F2F6FB;
  --toast-ic-ok: #6BCF95; --toast-ic-warn: #F2B65C; --toast-ic-danger: #FF8E82; --toast-ic-info: #8CBDF2;
  --fab-bg: #0F1B2D; --fab-ink: #F2F6FB; --fab-line: rgba(255, 255, 255, .25); --fab-hover: #1C2C44;
  --frame-bg: #05080F; --frame-line: #2A3647;
  --mask: #000000;
  /* R10 §2.1 "Cut Stone": the hero card, the primary-pill ledge, stone (illustration fills only, never meaning),
     the Pay all blast chips, the strata lines */
  --hero: #1F5FA8; --hero-deep: #17508F; --hero-ink: #FFFFFF; --hero-ink-2: #D6E6F8;
  --ledge: #123F72; --ledge-danger: #7E1810;
  --stone-1: #F1EEE7; --stone-2: #E2DDD2; --stone-3: #C9C1B2; --stone-ink: #5B5547;
  --chip-1: var(--brand); --chip-2: var(--stone-3);
  --strata: rgba(255, 255, 255, .07);
  --skel-hero: rgba(255, 255, 255, .6);
  /* R6 §1.3 radius: five values. The R5 names alias onto them so every module sheet moves with the scale. */
  --r-plate: 6px; --r-input: 12px; --r-card: 16px; --r-sheet: 20px; --r-pill: 999px;
  --r-1: var(--r-plate); --r-2: var(--r-input); --r-3: var(--r-card);
  /* R6 §1.1 type: IBM Plex Sans + Plex Mono (Condensed dropped: --font-cond now means the same face). Use as `font: var(--t-…)`.
     Figures are always tabular (body sets font-variant-numeric). */
  --font: "IBM Plex Sans", Roboto, system-ui, -apple-system, "Segoe UI", Arial, sans-serif;   /* R9: Roboto first after Plex (Android) */
  --font-cond: var(--font);
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, "Roboto Mono", "Droid Sans Mono", monospace;
  /* R10 §3: Archivo (display) for the hero figure, page titles, big success figure and empty-state titles ONLY.
     Width: the shorthand takes keywords only, so hero = semi-expanded (112.5%); the title and display widths are set
     with font-stretch next to the shorthand (.page-title, .q-display). Entry surfaces never change face. */
  --font-display: "Archivo", "Archivo Fallback", var(--font);
  --t-hero: 800 semi-expanded 40px/44px var(--font-display);   /* the one lead figure */
  --t-title: 700 28px/34px var(--font);   /* 28 px figures and titles in module sheets: stays Plex (R10: display face only where named) */
  --t-page-title: 800 28px/34px var(--font-display);   /* the page title <h1> (.page-title, sign-in title) + font-stretch: var(--fs-title) */
  --t-display: 800 semi-expanded 44px/48px var(--font-display);   /* Pay all / save sheet figure (font-stretch: var(--fs-display)) */
  --t-h2-display: 700 20px/26px var(--font-display);   /* empty-state title */
  --fs-hero: 112.5%; --fs-title: 106%; --fs-display: 118%;
  --t-h2: 600 20px/26px var(--font);      /* section title */
  --t-h3: 600 17px/22px var(--font);      /* card / row title, stat value */
  --t-body: 400 16px/24px var(--font);    /* body and inputs (16 px: no zoom on iPhone) */
  --t-meta: 500 14px/20px var(--font);    /* meta lines, desktop table cells */
  --t-label: 600 13px/16px var(--font);   /* group labels, table heads, stat labels: uppercase, +0.04em */
  --t-key: 600 28px/32px var(--font);     /* keypad keys; with --font-mono for the plate field */
  /* R6 §1.2 spacing (4-pt) */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;
  /* R6 §1.5 motion, R8 §2.14 (Emil Kowalski): custom curves only, exit faster than enter */
  --ease-out: cubic-bezier(.23, 1, .32, 1); --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --ease-drawer: cubic-bezier(.32, .72, 0, 1);
  --d-press: 140ms;
  --d-fast: 160ms;
  --d-pop-in: 180ms;
  --d-pop-out: 140ms;
  --d-sheet-in: 260ms; --d-sheet-out: 200ms;
  --d-panel-in: 260ms;
  --d-panel-out: 200ms;
  --d-msg: 200ms;
  --d-row: 240ms;
  /* R10 §5.2 "Cut Stone" motion: commitment, not activity. Springs are CSS linear() (see the @supports block below);
     here they hold their ease fallbacks for browsers without linear(). */
  --d-tap: 90ms; --d-tick: 160ms; --d-indicator: 180ms; --d-rise: 240ms; --d-collapse: 240ms;
  --d-stamp: 480ms; --d-draw: 260ms; --d-count: 700ms; --d-blast: 620ms; --d-skel-pulse: 1200ms;
  --d-sheet-spring: 380ms; --d-toast-out: 140ms;
  --stagger: 30ms; --stagger-max: 150ms;
  --ease-exit: cubic-bezier(.4, 0, 1, 1);
  --spring-settle: var(--ease-out); --spring-stamp: var(--ease-out); --spring-sheet: var(--ease-drawer);
  --motion: 1;   /* 0 under prefers-reduced-motion (the global block below): movement off, fades kept */
  --ease: var(--ease-out); --dur: var(--d-fast);
  --tap: 48px;
  --gutter-l: max(20px, env(safe-area-inset-left));
  --gutter-r: max(20px, env(safe-area-inset-right));
  --view-pt: var(--s-5);
  /* R5: notch / status bar (only non-zero once the page opts into viewport-fit=cover, e.g. installed on an iPhone) */
  --safe-top: env(safe-area-inset-top, 0px); --safe-bottom: env(safe-area-inset-bottom, 0px);
  --topbar-h: 56px; --tabbar-h: 64px; --strip-h: 28px;
  /* where a sticky header strip sits: under the top bar, which itself sits under the status bar */
  --stick-top: calc(var(--topbar-h) + var(--safe-top));
  /* how far the round Record button rises above the tab bar: every sticky Save bar on a phone sits above it (UX-04) */
  --tabbar-rise: 16px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0B1220; --surface: #131C2C; --surface-2: #1D2939; --surface-3: #172233;
    --ink: #EAF1FA; --ink-2: #C0CCDC; --ink-3: #A0B1C6;
    --line: #2B3A50; --line-strong: #6A7F9C;
    --brand: #4189DD; --logo-bg: #4189DD; --logo-ink: #FFFFFF; --logo-ring: rgba(255, 255, 255, .6);
    --nav: #0D2445; --nav-2: #163563; --nav-ink: #FFFFFF; --nav-ink-2: #B9CFEA; --nav-mark: #8CBDF2;
    --nav-active: rgba(255, 255, 255, .12); --nav-veil: rgba(255, 255, 255, .1); --nav-line: rgba(255, 255, 255, .16); --nav-focus: #8CBDF2;
    --accent: #2A6DBA; --accent-hover: #1F5FA8; --on-accent: #FFFFFF; --accent-text: #8CBDF2; --accent-soft: #142B4C;
    --on-accent-veil: rgba(255, 255, 255, .16); --on-accent-line: rgba(255, 255, 255, .35);
    --info: #8CBDF2; --info-strong: #1F5FA8; --info-soft: #142B4C; --on-info: #FFFFFF;
    --ok: #6BCF95; --ok-soft: #12301F;
    --warn: #F2B65C; --warn-soft: #33270F; --warn-bar: #D99A2B;
    --danger: #FF8E82; --danger-strong: #B42318; --danger-hover: #9A1D14; --danger-soft: #3A1714; --on-danger: #FFFFFF;
    --neutral: #C0CCDC; --neutral-soft: #222E40;
    --badge-warn-bg: #F2B65C; --badge-warn-ink: #2A1C00;
    --focus: #8CBDF2;
    --bar-sales: #5C9DE6; --bar-exp: #D99A2B;
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-2: 0 14px 36px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .4);
    --shadow-up: 0 -6px 18px rgba(0, 0, 0, .35);
    --backdrop: rgba(0, 0, 0, .62);
    --plate-bg: #FFFFFF; --plate-ink: #0F1B2D; --plate-line: #FFFFFF;
    --toast-bg: #EAF1FA; --toast-ink: #0F1B2D;
    --toast-ic-ok: #1B7340; --toast-ic-warn: #8A4F00; --toast-ic-danger: #B42318; --toast-ic-info: #1F5FA8;
    --fab-bg: #0F1B2D; --fab-ink: #F2F6FB; --fab-line: rgba(255, 255, 255, .25); --fab-hover: #1C2C44;
    --frame-bg: #05080F; --frame-line: #2A3647;
    --hero: #163563; --hero-deep: #0D2445; --hero-ink: #FFFFFF; --hero-ink-2: #C9DCF3;
    --ledge: #0D2445;
    --stone-1: #1A2230; --stone-2: #253042; --stone-3: #3A4659; --stone-ink: #B9B2A3;
    --strata: rgba(255, 255, 255, .08);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0B1220; --surface: #131C2C; --surface-2: #1D2939; --surface-3: #172233;
  --ink: #EAF1FA; --ink-2: #C0CCDC; --ink-3: #A0B1C6;
  --line: #2B3A50; --line-strong: #6A7F9C;
  --brand: #4189DD; --logo-bg: #4189DD; --logo-ink: #FFFFFF; --logo-ring: rgba(255, 255, 255, .6);
  --nav: #0D2445; --nav-2: #163563; --nav-ink: #FFFFFF; --nav-ink-2: #B9CFEA; --nav-mark: #8CBDF2;
  --nav-active: rgba(255, 255, 255, .12); --nav-veil: rgba(255, 255, 255, .1); --nav-line: rgba(255, 255, 255, .16); --nav-focus: #8CBDF2;
  --accent: #2A6DBA; --accent-hover: #1F5FA8; --on-accent: #FFFFFF; --accent-text: #8CBDF2; --accent-soft: #142B4C;
  --on-accent-veil: rgba(255, 255, 255, .16); --on-accent-line: rgba(255, 255, 255, .35);
  --info: #8CBDF2; --info-strong: #1F5FA8; --info-soft: #142B4C; --on-info: #FFFFFF;
  --ok: #6BCF95; --ok-soft: #12301F;
  --warn: #F2B65C; --warn-soft: #33270F; --warn-bar: #D99A2B;
  --danger: #FF8E82; --danger-strong: #B42318; --danger-hover: #9A1D14; --danger-soft: #3A1714; --on-danger: #FFFFFF;
  --neutral: #C0CCDC; --neutral-soft: #222E40;
  --badge-warn-bg: #F2B65C; --badge-warn-ink: #2A1C00;
  --focus: #8CBDF2;
  --bar-sales: #5C9DE6; --bar-exp: #D99A2B;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-2: 0 14px 36px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .4);
  --shadow-up: 0 -6px 18px rgba(0, 0, 0, .35);
  --backdrop: rgba(0, 0, 0, .62);
  --plate-bg: #FFFFFF; --plate-ink: #0F1B2D; --plate-line: #FFFFFF;
  --toast-bg: #EAF1FA; --toast-ink: #0F1B2D;
  --toast-ic-ok: #1B7340; --toast-ic-warn: #8A4F00; --toast-ic-danger: #B42318; --toast-ic-info: #1F5FA8;
  --fab-bg: #0F1B2D; --fab-ink: #F2F6FB; --fab-line: rgba(255, 255, 255, .25); --fab-hover: #1C2C44;
  --frame-bg: #05080F; --frame-line: #2A3647;
  --hero: #163563; --hero-deep: #0D2445; --hero-ink: #FFFFFF; --hero-ink-2: #C9DCF3;
  --ledge: #0D2445;
  --stone-1: #1A2230; --stone-2: #253042; --stone-3: #3A4659; --stone-ink: #B9B2A3;
  --strata: rgba(255, 255, 255, .08);
}

/* R6: the desktop steps (hero 40/44, wider gutters, taller top bar) */
@media (min-width: 720px) {
  :root {
    --t-hero: 800 semi-expanded 48px/52px var(--font-display);
    --gutter-l: max(24px, env(safe-area-inset-left)); --gutter-r: max(24px, env(safe-area-inset-right));
    --view-pt: var(--s-6); --topbar-h: 64px;
  }
}
/* the full desktop gutter (--s-8) from 1280; tablets and small laptops keep 24 so the R5 entry grids still fit */
@media (min-width: 1280px) { :root { --gutter-l: max(32px, env(safe-area-inset-left)); --gutter-r: max(32px, env(safe-area-inset-right)); } }

/* R10 §5.2 springs: generated from a damped spring (zeta .72 / .5 / .86); do not hand-edit. settle 360 ms (3.8%
   overshoot), stamp 480 ms (seal .6 → 1 peaks ~1.06), sheet 380 ms (near-critical). */
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    --spring-settle: linear(0, 0.063, 0.206, 0.379, 0.549, 0.698, 0.818, 0.907, 0.968, 1.007, 1.028, 1.037, 1.038, 1.034, 1.028, 1.021, 1.015, 1.01, 1.006, 1.003, 1.001, 0.999, 0.999, 0.999, 1);
    --spring-stamp: linear(0, 0.097, 0.319, 0.579, 0.815, 0.994, 1.106, 1.157, 1.16, 1.133, 1.092, 1.051, 1.016, 0.991, 0.978, 0.973, 0.975, 0.981, 0.988, 0.994, 0.999, 1.003, 1.004, 1.004, 1);
    --spring-sheet: linear(0, 0.042, 0.14, 0.262, 0.39, 0.511, 0.618, 0.71, 0.785, 0.846, 0.892, 0.928, 0.954, 0.972, 0.985, 0.994, 0.999, 1.003, 1.004, 1.005, 1.005, 1.005, 1.004, 1.003, 1);
  }
}
/* R10 §3: Archivo arrives from Google Fonts (swap); until then this local face stands in with metrics tuned so the
   swap does not move the hero (acceptance A4/A6). Arial on desktop/iOS, Roboto on Android. Bold weights map to the
   bold files so nothing is synthesised. */
@font-face { font-family: "Archivo Fallback"; font-weight: 100 600; font-stretch: 50% 200%; src: local("Arial"), local("ArialMT"), local("Roboto"), local("Roboto-Regular"); size-adjust: 100%; ascent-override: 87.8%; descent-override: 21.0%; line-gap-override: 0%; }
/* Archivo's vertical metrics are ascent .878 / descent .21 em; the overrides are divided by size-adjust so the text
   box sits exactly where Archivo's will (no glyph shift on swap). Bold: one face per Archivo width in use (measured width ratios Archivo ÷ Arial Bold: 100% → 0.99, 106% → 1.11, 112.5–118% → 1.23) */
@font-face { font-family: "Archivo Fallback"; font-weight: 700 900; font-stretch: 50% 104%; src: local("Arial Bold"), local("Arial-BoldMT"), local("Roboto Bold"), local("Roboto-Bold"); size-adjust: 99%; ascent-override: 88.7%; descent-override: 21.2%; line-gap-override: 0%; }
@font-face { font-family: "Archivo Fallback"; font-weight: 700 900; font-stretch: 104.1% 110%; src: local("Arial Bold"), local("Arial-BoldMT"), local("Roboto Bold"), local("Roboto-Bold"); size-adjust: 111%; ascent-override: 79.1%; descent-override: 18.9%; line-gap-override: 0%; }
@font-face { font-family: "Archivo Fallback"; font-weight: 700 900; font-stretch: 110.1% 200%; src: local("Arial Bold"), local("Arial-BoldMT"), local("Roboto Bold"), local("Roboto-Bold"); size-adjust: 123%; ascent-override: 71.4%; descent-override: 17.1%; line-gap-override: 0%; }

/* ------------------------------------------------------------------ base */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; touch-action: manipulation; scroll-padding-top: calc(var(--stick-top) + 16px); scroll-padding-bottom: 16px; }
/* Sticky bottom bars: browsers only scroll a focused field into view when it is off-screen, not when a sticky bar
   covers it, so the bottom scroll padding must equal the sticky stack (WCAG 2.4.11). --sticky-foot is measured by the
   page that owns a sticky footer (e.g. the sale form's total bar). */
html:has(.sale-bar) { scroll-padding-bottom: calc(var(--sticky-foot, 96px) + 16px); }
html:has(.abar) { scroll-padding-bottom: calc(var(--sticky-foot, 88px) + 16px); }
@media (max-width: 719px) {
  html { scroll-padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 16px); }
  html:has(.sale-bar) { scroll-padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--tabbar-rise) + var(--sticky-foot, 190px) + 22px); }
  html:has(.abar) { scroll-padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--tabbar-rise) + var(--sticky-foot, 88px) + 16px); }
}
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: var(--t-body); font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
/* R5: installed on an iPhone (viewport-fit=cover) the status bar overlays the page; this band keeps scrolled content
   from showing through it. Zero height everywhere else. */
body::before { content: ""; position: fixed; inset: 0 0 auto; height: var(--safe-top); background: var(--surface); z-index: 60; pointer-events: none; }
body:has(.app--signin)::before { background: var(--nav); }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure { margin: 0; }
/* R4 §C: zero specificity, so a component class (.mylist, .cl-orows …) can set its own padding */
:where(ul[role="list"], ol[role="list"]) { list-style: none; padding: 0; }
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
a { color: var(--info); }
svg.ic { flex: none; display: inline-block; vertical-align: middle; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
[tabindex="-1"]:focus { outline: none; }
[hidden] { display: none !important; }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.num { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); font-size: inherit; }   /* R6 §1.1: no in-between size (.95em made 13.3 px) */
.muted { color: var(--ink-3); }
.small { font-size: 14px; }
.tone-ok { color: var(--ok); } .tone-warn { color: var(--warn); } .tone-danger { color: var(--danger); } .tone-info { color: var(--info); }
.stack { display: grid; gap: var(--gap, var(--s-4)); }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap, var(--s-3)); }
.spacer { flex: 1 1 auto; }
.grid-2 { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.grid-3 { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

/* ------------------------------------------------------------------ shell */
.app { min-height: 100dvh; }
.skip { position: absolute; left: var(--s-3); top: -60px; z-index: 200; display: inline-flex; align-items: center; min-height: var(--tap); background: var(--surface); color: var(--ink); padding: var(--s-3) var(--s-4); border-radius: var(--r-pill); box-shadow: var(--shadow-2); font-weight: 600; }   /* R5: 48 px like every target */
.skip:focus { top: var(--s-2); }
.skip:not(:focus) { box-shadow: none; }   /* R8: the off-screen link's shadow showed as a grey smudge top-left */
.demo-strip {
  display: flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: var(--strip-h);
  padding: calc(4px + var(--safe-top)) var(--gutter-r) 4px var(--gutter-l); background: var(--surface-2); color: var(--ink-2);
  font-size: 13px; font-weight: 500; border-bottom: 1px solid var(--line);
}
.shell { display: grid; grid-template-columns: minmax(0, 1fr); min-height: calc(100dvh - var(--strip-h)); }
.sidebar { display: none; }
.main { min-width: 0; display: flex; flex-direction: column; }
/* R6 §3.9 top bar: white, a bottom hairline (e1); phone = logo mark · branch pill · bell · avatar */
.topbar {
  position: sticky; top: 0; z-index: 40; height: var(--topbar-h);   /* pwa.css adds the status-bar inset as padding, so the bar covers it */
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: 0 var(--gutter-r) 0 var(--gutter-l);
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.topbar__left { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.topbar__mark { display: inline-grid; place-items: center; width: 32px; height: 32px; flex: none; }
.topbar__mark .logo { width: 32px; height: 32px; }
/* the brand mark (Q.ui.logo): "GS" on the flag light blue */
.logo { display: block; flex: none; }
.logo__bg { fill: var(--logo-bg); }
.logo__txt { fill: var(--logo-ink); font: 700 30px var(--font); letter-spacing: -1px; }
.topbar__page { font: var(--t-h3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar__right { display: flex; align-items: center; gap: var(--s-2); flex: none; }
.topbar__branch { display: inline-flex; min-height: 40px; padding: 0 var(--s-3); }
/* one branch control per screen: where the page has its own, the top-bar pill steps aside (Q.shell.chrome) */
html.no-branch-pill .topbar__branch { display: none; }
@media (max-width: 719px) { .topbar__page { display: none; } .topbar__right { gap: var(--s-1); } }
@media (max-width: 379px) { .topbar__branch > span[data-short] { font-size: 0; } .topbar__branch > span[data-short]::after { content: attr(data-short); font-size: 14px; } }
.bell { position: relative; }
.bell__count {
  position: absolute; top: 2px; right: 0; min-width: 22px; height: 22px; padding: 0 var(--s-1); border-radius: var(--r-pill);
  background: var(--danger-strong); color: var(--on-danger); font: 700 13px/22px var(--font); text-align: center; border: 2px solid var(--surface);
  box-sizing: content-box;
}
.userchip {
  display: flex; align-items: center; gap: var(--s-3); min-height: var(--tap); padding: var(--s-1);
  border: 1px solid transparent; border-radius: var(--r-pill); background: transparent; text-align: left;
}
.userchip__text { display: none; }
.userchip__chev { display: none; color: var(--ink-3); }
.avatar {
  display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-pill); flex: none;
  background: var(--accent-soft); color: var(--accent-text); font: 700 14px/1 var(--font); letter-spacing: .02em;
}
.avatar--lg { width: 48px; height: 48px; font-size: 16px; }
.view {
  width: 100%; max-width: 1280px; margin: 0 auto;
  padding: var(--view-pt) var(--gutter-r) calc(var(--tabbar-h) + var(--s-8) + env(safe-area-inset-bottom)) var(--gutter-l);
}
/* R10: a row leaving (X +24 px) never widens the page mid-moment. Only WHILE one leaves: a real overflow must stay visible
   (and scrollable) the rest of the time. clip is not a scroll box, so sticky bars keep working. */
.view:has(.q-leaving, .is-leaving, .cl-gone) { overflow-x: clip; }
.view:focus { outline: none; }

/* R6 §3.9 phone tab bar: solid white, top hairline, 64 px + safe area. Current tab = a tint pill behind the icon +
   the label in accent at 600, plus the R5 bar on top (never colour alone). The centre Record = a 56 px accent circle. */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  background: var(--surface); border-top: 1px solid var(--line); box-shadow: var(--shadow-up);
  padding: 0 max(var(--s-1), env(safe-area-inset-right)) env(safe-area-inset-bottom) max(var(--s-1), env(safe-area-inset-left));
}
.tabbar ul { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); height: calc(var(--tabbar-h) - 1px); align-items: stretch; }   /* + the 1 px hairline = 64 */
.tabbar li { display: flex; position: relative; min-width: 0; }
.tabbar__item {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-1);
  min-height: var(--tap); padding: var(--s-1) 0; border: 0; background: none; color: var(--ink-3);
  font: 500 13px/16px var(--font); text-decoration: none; text-align: center;
}
.tabbar__item > span:not(.nav__badge) { max-width: 100%; white-space: nowrap; }
.tabbar__item .ic { box-sizing: content-box; padding: var(--s-1) var(--s-4); border-radius: var(--r-pill); transition: background-color var(--d-fast) var(--ease-out); }
.tabbar__item[aria-current="page"] { color: var(--accent-text); font-weight: 600; }
.tabbar__item[aria-current="page"] .ic { background: var(--accent-soft); stroke-width: 2.4; }
/* the current tab is marked by a bar as well as colour (sunlight, dark mode, colour blindness), like the sidebar's */
.tabbar__item[aria-current="page"]::before { content: ""; position: absolute; top: 0; inset-inline: 22%; height: 3px; border-radius: 0 0 3px 3px; background: var(--accent); }
.tabbar .nav__badge { position: absolute; top: 2px; left: calc(50% + 8px); }
.tabbar__center { flex-direction: column; align-items: center; justify-content: flex-start; }
.tabbar__new {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 2px;
  padding: 0 0 var(--s-1); border: 0; background: none; color: inherit; font: inherit; border-radius: var(--r-input);
}
.tabbar__plus {
  width: 56px; height: 56px; margin-top: calc(-1 * var(--tabbar-rise)); border-radius: var(--r-pill); border: 4px solid var(--surface);
  background: var(--accent); color: var(--on-accent); display: grid; place-items: center;
  transition: transform var(--d-press) var(--ease-out);
}
.tabbar__new:active .tabbar__plus { transform: scale(.97); transition-duration: var(--d-tap); }
/* R10 §6: while the Record sheet is open the + turns 45° into an × */
.tabbar__plus .ic { transition: transform var(--d-indicator) var(--ease-out); }
html.is-recording .tabbar__plus .ic { transform: rotate(45deg); }
.tabbar__plus-label { font: 600 13px/16px var(--font); color: var(--ink-2); white-space: nowrap; }
.demo-fab { display: none; }
/* R6 task mode (entry routes, Q.ui.taskHeader): the form owns the screen, so the tab bar goes and every bar that sat
   above it (they all add --tabbar-h and --tabbar-rise) drops to the bottom edge */
html.is-task { --tabbar-h: 0px; --tabbar-rise: 0px; }
html.is-task .tabbar { display: none; }

/* R6 §3.9 desktop: a white, full-height sidebar (the column carries the background and hairline; its content sticks
   at the top), grouped Daily · Weekly · Admin. Current item = tint pill + accent text + a 3 px accent bar. */
@media (min-width: 720px) {
  .tabbar { display: none; }
  .view { padding: var(--view-pt) var(--gutter-r) 96px var(--gutter-l); }
  .shell { grid-template-columns: 92px minmax(0, 1fr); }
  .sidebar { display: block; background: var(--surface); border-right: 1px solid var(--line); color: var(--ink); }
  .sidebar__in {
    position: sticky; top: 0; height: 100dvh; overflow-y: auto; display: flex; flex-direction: column;
    padding: var(--s-4) var(--s-2) 96px max(var(--s-2), env(safe-area-inset-left));
  }
  .brand { display: flex; align-items: center; justify-content: center; gap: var(--s-3); padding: 0 var(--s-1) var(--s-5); }
  .brand__mark { display: inline-grid; place-items: center; width: 40px; height: 40px; flex: none; }
  .brand__text { display: none; }
  .nav__group { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .nav ul { display: grid; gap: var(--s-1); }
  .nav ul + .nav__group + ul { margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--line); }
  .nav__item {
    position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--s-1); padding: var(--s-2) var(--s-1); min-height: 64px;
    border-radius: var(--r-input); color: var(--ink-2); text-decoration: none; font: 500 13px/16px var(--font); text-align: center;
    transition: background-color var(--d-fast) var(--ease-out);
  }
  .nav__item .ic { color: var(--ink-3); }
  .nav__item[aria-current="page"] { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; }
  .nav__item[aria-current="page"] .ic { color: var(--accent-text); }
  .nav__item[aria-current="page"]::before { content: ""; position: absolute; left: calc(-1 * var(--s-2)); top: var(--s-3); bottom: var(--s-3); width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); }
  .nav .nav__badge { position: absolute; top: var(--s-1); right: var(--s-3); }
  /* R10 §8.1 the gliding highlight (core navGlide): one element travels between items (translate only, --d-indicator);
     while it plays, the new item's own fill and bar stand aside so there is only ever one highlight */
  .nav { position: relative; }
  .nav ul { position: relative; z-index: 1; }
  .nav__glide { position: absolute; left: 0; top: 0; z-index: 0; pointer-events: none; background: var(--accent-soft); }
  .nav__glide::before { content: ""; position: absolute; left: calc(-1 * var(--s-2)); top: var(--s-3); bottom: var(--s-3); width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); }
  .nav.is-gliding .nav__item[aria-current="page"] { background: transparent; }
  /* the highlight never fades in or out on its own: it glides (motion on) or is simply there (reduced motion) */
  .nav__item[aria-current="page"], .nav.is-gliding .nav__item { transition: none; }
  .nav.is-gliding .nav__item[aria-current="page"]::before { opacity: 0; }
  .sidebar__foot { display: none; }
  .topbar__mark { display: none; }
  .topbar__branch { display: inline-flex; }
  .demo-fab {
    display: inline-flex; align-items: center; gap: var(--s-2); position: fixed; left: var(--s-3); bottom: var(--s-4); z-index: 50;
    min-height: 44px; padding: 0 var(--s-4); border-radius: var(--r-pill); border: 1px solid var(--fab-line);
    background: var(--fab-bg); color: var(--fab-ink); font: 600 14px/1 var(--font); box-shadow: var(--shadow-2);
  }
}
@media (min-width: 1024px) {
  .shell { grid-template-columns: 248px minmax(0, 1fr); }
  .sidebar__in { padding: var(--s-5) var(--s-3) 96px max(var(--s-3), env(safe-area-inset-left)); }
  .brand { justify-content: flex-start; padding: 0 var(--s-2) var(--s-5); }
  .brand__text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
  .brand__name { font: 600 16px/20px var(--font); color: var(--ink); }
  .brand__app { font: var(--t-label); color: var(--ink-3); letter-spacing: .04em; text-transform: uppercase; }
  .nav__group { position: static; width: auto; height: auto; overflow: visible; clip: auto; font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); padding: var(--s-4) var(--s-3) var(--s-2); }
  .nav__group:first-child { padding-top: 0; }
  .nav ul + .nav__group + ul { margin-top: 0; padding-top: 0; border-top: 0; }
  .nav__item { flex-direction: row; gap: var(--s-3); min-height: var(--tap); padding: 0 var(--s-4); font: 500 16px/20px var(--font); text-align: left; border-radius: var(--r-pill); }
  .nav__item[aria-current="page"] { font-weight: 600; }
  .nav__item[aria-current="page"]::before, .nav__glide::before { left: calc(-1 * var(--s-3)); }
  .nav .nav__badge { position: static; margin-left: auto; }
  .sidebar__foot { display: block; margin-top: auto; padding: var(--s-4) var(--s-2) 0; border-top: 1px solid var(--line); font-size: 13px; color: var(--ink-3); }
  .sidebar__foot p:first-child { color: var(--ink-2); font-weight: 600; }
  .userchip { padding-right: var(--s-3); border-color: var(--line); }
  .userchip__text { display: flex; flex-direction: column; line-height: 1.15; }
  .userchip__name { font-weight: 600; font-size: 14px; }
  .userchip__role { font-size: 13px; color: var(--ink-3); }
  .userchip__chev { display: inline-block; }
  .demo-fab { left: var(--s-5); bottom: var(--s-5); }
}
.nav__badge {
  min-width: 22px; height: 22px; padding: 0 var(--s-2); border-radius: var(--r-pill); background: var(--badge-warn-bg); color: var(--badge-warn-ink);
  font: 700 13px/22px var(--font); text-align: center;
}

/* ------------------------------------------------------------------ page head (Q.ui.pageHead / pageHeader) */
.page-head { display: grid; gap: var(--s-2); margin-bottom: var(--s-6); }
.page-head__main { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--s-3) var(--s-5); }
.page-head__text { min-width: 0; }
.ph__titlerow { display: flex; align-items: center; gap: var(--s-1); min-width: 0; }
.page-title { font: var(--t-page-title); font-stretch: var(--fs-title); letter-spacing: -.01em; min-width: 0; }
.page-sub { color: var(--ink-3); margin-top: var(--s-1); font: var(--t-meta); }
.page-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.ph__info { color: var(--ink-3); margin-block: calc(-1 * var(--s-2)); }
.ph__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.ph__toolbar > .input, .ph__toolbar > .field, .ph__toolbar > .ph__grow { flex: 1 1 200px; min-width: 0; }
.info-body { display: grid; gap: var(--s-3); max-inline-size: 60ch; color: var(--ink-2); }
.popover__body { padding: var(--s-3) var(--s-3) var(--s-2); }
.backlink { display: inline-flex; align-items: center; gap: var(--s-1); min-height: 44px; padding: 0 var(--s-2) 0 0; border: 0; background: none; color: var(--info); font-weight: 600; justify-self: start; }
@media (max-width: 719px) {
  .page-head { margin-bottom: var(--s-5); }
  .page-tools { width: 100%; }
  .page-tools .weekpick { width: 100%; }
  .page-tools .weekpick__btn { flex: 1; }
  /* VIS-04: equal cells, but never narrower than their own words (the selected "All branches" with its dot was 101 px
     against 107 px of content at 360, so the dot sat on the pill's outline and the "s" ran past it) */
  .page-tools .seg { width: 100%; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(max-content, 1fr); }
  .page-tools .seg__btn { padding: 0 var(--s-2); }
}

/* ------------------------------------------------------------------ cards, notices (flat: §1.4 e0) */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); min-width: 0; }
.card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-5) var(--s-5) 0; }
.card__title { display: flex; align-items: center; gap: var(--s-2); font: var(--t-h3); }
.card__body { padding: var(--s-4) var(--s-5) var(--s-5); }
@media (max-width: 719px) { .card__head { padding: var(--s-4) var(--s-4) 0; } .card__body { padding: var(--s-3) var(--s-4) var(--s-4); } }
.notice {
  display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-3) var(--s-4); margin-bottom: var(--s-4); border-radius: var(--r-input);
  background: var(--info-soft); color: var(--ink); border: 1px solid color-mix(in srgb, var(--info) 30%, transparent); font-size: 16px;
}
.notice > .ic { color: var(--info); margin-top: 2px; }
.notice--warn { background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 35%, transparent); } .notice--warn > .ic { color: var(--warn); }
.notice--danger { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 35%, transparent); } .notice--danger > .ic { color: var(--danger); }
.notice--ok { background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 35%, transparent); } .notice--ok > .ic { color: var(--ok); }

/* ------------------------------------------------------------------ buttons: pills (§2 Buttons). One primary per view. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: var(--tap);
  padding: 0 var(--s-5); border-radius: var(--r-pill); border: 1px solid transparent; font: 600 16px/20px var(--font);
  text-decoration: none; white-space: nowrap; user-select: none; -webkit-user-select: none;
  transition: background-color var(--d-fast) var(--ease-out), border-color var(--d-fast) var(--ease-out), color var(--d-fast) var(--ease-out), transform var(--d-press) var(--ease-out);
}
.btn:active:not(:disabled) { transform: scale(.97); transition-duration: var(--d-tap); }
/* R10 §1/§6 the LEDGE: primary (and danger) pills sit on a hard 3 px edge — a solid layer behind the pill, never a
   shadow. Pressing sinks the pill 2 px onto it (the layer rises 1 px with it, so 1 px of ledge stays). Transform only. */
.btn--primary, .btn--danger { position: relative; isolation: isolate; }
.btn--primary::before, .btn--danger::before {
  content: ""; position: absolute; inset: -1px; z-index: -2; border-radius: inherit; background: var(--ledge);
  transform: translateY(3px); transition: transform var(--d-press) var(--ease-out); pointer-events: none;
}
/* the pill's face is repainted above the ledge (inside the pill's own stacking context the ledge would otherwise cover
   the pill's background); it inherits the background, so hover and pressed colours still apply */
.btn--primary::after, .btn--danger::after { content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; background: inherit; pointer-events: none; }
.btn--danger::before { background: var(--ledge-danger); }
.btn--primary:active:not(:disabled), .btn--danger:active:not(:disabled) { transform: translateY(2px); }
.btn--primary:active:not(:disabled)::before, .btn--danger:active:not(:disabled)::before { transform: translateY(1px); transition-duration: var(--d-tap); }
.btn--primary:disabled::before, .btn--danger:disabled::before, .btn--primary[aria-disabled="true"]::before { display: none; }
/* R10 §6 "Saved" state (Q.ui.saved): the label cross-fades to the seal + "Saved"; the button keeps its width */
.btn__saved { display: inline-flex; align-items: center; gap: var(--s-2); animation: q-fade var(--d-tick) var(--ease-out) both; }
.btn__saved .seal { flex: none; }
/* on a filled pill the seal takes the pill's ink (the green seal is ~2:1 on blue); the old leading icon steps aside */
.btn--primary .btn__saved .seal, .btn--danger .btn__saved .seal { color: currentColor; }
.is-saved > .ic { display: none; }
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--secondary { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn--quiet { background: transparent; color: var(--accent-text); padding-inline: var(--s-3); }
.btn--ghost { background: transparent; color: var(--ink); }
.btn--danger { background: var(--danger-strong); color: var(--on-danger); }
.btn--info { background: var(--info-strong); color: var(--on-info); }
.btn--block { width: 100%; }
.btn--sm { min-height: 40px; padding: 0 var(--s-4); font-size: 14px; }
.btn--xl { min-height: 56px; font-size: 17px; padding: 0 var(--s-6); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
@media (pointer: coarse) { .btn--sm { min-height: var(--tap); } }   /* UX-03: 48 px on touch (SPEC: targets ≥ 48 px) */
.icon-btn {
  display: inline-grid; place-items: center; width: var(--tap); height: var(--tap); padding: 0; flex: none;
  border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink-2);
  transition: background-color var(--d-fast) var(--ease-out), transform var(--d-press) var(--ease-out);
}
.icon-btn:active { transform: scale(.97); transition-duration: var(--d-tap); }
.icon-btn--sm { width: 40px; height: 40px; }
@media (pointer: coarse) { .icon-btn--sm { width: var(--tap); height: var(--tap); } }
@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover:not(:disabled) { background: var(--accent-hover); }
  .btn--secondary:hover:not(:disabled), .btn--ghost:hover:not(:disabled), .btn--quiet:hover:not(:disabled) { background: var(--surface-2); }
  .btn--danger:hover:not(:disabled) { background: var(--danger-hover); }
  .icon-btn:hover, .userchip:hover { background: var(--surface-2); }
  .nav__item:hover:not([aria-current="page"]) { background: var(--surface-3); color: var(--ink); }
  .backlink:hover { text-decoration: underline; }
  .demo-fab:hover { background: var(--fab-hover); }
}

/* ------------------------------------------------------------------ status bits */
.pill {
  display: inline-flex; align-items: center; gap: var(--s-1); min-height: 26px; padding: 2px var(--s-2); border-radius: var(--r-pill);
  font-size: 13px; font-weight: 600; line-height: 1.2; white-space: nowrap; border: 1px solid transparent; vertical-align: middle;
}
.pill--ok { background: var(--ok-soft); color: var(--ok); border-color: color-mix(in srgb, var(--ok) 28%, transparent); }
.pill--warn { background: var(--warn-soft); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
.pill--danger { background: var(--danger-soft); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.pill--info { background: var(--info-soft); color: var(--info); border-color: color-mix(in srgb, var(--info) 28%, transparent); }
.pill--neutral { background: var(--neutral-soft); color: var(--neutral); border-color: var(--line); }
/* R6: in list rows the status is icon + word in its ink, no pill (Q.ui.statusText) */
.stxt { display: inline-flex; align-items: center; gap: var(--s-1); font: var(--t-meta); font-weight: 600; white-space: nowrap; vertical-align: middle; }
.stxt--ok { color: var(--ok); } .stxt--warn { color: var(--warn); } .stxt--danger { color: var(--danger); } .stxt--info { color: var(--info); } .stxt--neutral { color: var(--ink-2); }
.badge {
  display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 var(--s-2); margin-left: var(--s-2); border-radius: var(--r-pill);
  background: var(--neutral-soft); color: var(--ink-2); font: 700 13px/1 var(--font);
}
.badge--danger { background: var(--danger-strong); color: var(--on-danger); }
.badge--warn { background: var(--badge-warn-bg); color: var(--badge-warn-ink); }
.tag { display: inline-flex; align-items: center; min-height: 22px; padding: 0 var(--s-2); border-radius: var(--r-pill); background: var(--accent-soft); color: var(--accent-text); font-size: 13px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.tag--muted { background: var(--surface-2); color: var(--ink-2); }
.chip { display: inline-flex; align-items: center; gap: var(--s-2); min-height: 36px; padding: 0 var(--s-3); border-radius: var(--r-pill); border: 1px solid var(--line); background: var(--surface); font-size: 14px; font-weight: 600; color: var(--ink-2); white-space: nowrap; }
.chip--locked { background: var(--surface-2); min-height: 44px; }
.prov { display: inline-flex; align-items: center; gap: var(--s-1); padding: 2px var(--s-2); border-radius: var(--r-pill); font-size: 13px; font-weight: 600; white-space: nowrap; }
.prov--sheet { background: var(--ok-soft); color: var(--ok); }
.prov--assumption { background: var(--warn-soft); color: var(--warn); }
.prov--brief { background: var(--info-soft); color: var(--info); }
.plate {
  display: inline-block; padding: 2px var(--s-2); border-radius: var(--r-plate); border: 1.5px solid var(--plate-line);
  background: var(--plate-bg); color: var(--plate-ink); font: 600 14px/1.3 var(--font-mono); letter-spacing: .03em; white-space: pre; vertical-align: middle;
}

/* ------------------------------------------------------------------ forms */
.field { display: grid; gap: var(--s-2); min-width: 0; }
.field__label { font: 600 16px/22px var(--font); color: var(--ink); }
.field__req { color: var(--danger); }
.field__opt { font-weight: 400; color: var(--ink-3); }
.field__hint { font: var(--t-meta); font-weight: 400; color: var(--ink-3); }
.field__error { font: var(--t-meta); color: var(--danger); display: flex; gap: var(--s-2); align-items: flex-start; }
.field__error:empty { display: none; }
.field__error .ic { margin-top: 2px; }
.input {
  width: 100%; min-height: var(--tap); padding: var(--s-3) var(--s-4); border: 1px solid var(--line-strong); border-radius: var(--r-input);
  background: var(--surface); color: var(--ink); font-size: 16px; line-height: 1.3;
}
textarea.input { min-height: 96px; resize: vertical; }
select.input { appearance: none; -webkit-appearance: none; padding-right: var(--s-10);
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 20px) 52%, calc(100% - 15px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }   /* the chevron, drawn: not a gradient fill */
.input::placeholder { color: var(--ink-3); opacity: 1; }
.input:focus-visible { outline: 3px solid var(--focus); outline-offset: 0; border-color: var(--focus); }
.input[readonly] { background: var(--surface-3); }
.input--xl { min-height: 56px; font: var(--t-key); font-family: var(--font-mono); letter-spacing: .04em; text-transform: uppercase; }
.has-error .input { border-color: var(--danger); box-shadow: 0 0 0 1px var(--danger); }
.input-group { display: flex; align-items: stretch; min-width: 0; }
.input-group .input { border-radius: 0; min-width: 0; flex: 1; }
.input-group .input:first-child { border-radius: var(--r-input) 0 0 var(--r-input); }
.input-group .input:last-child { border-radius: 0 var(--r-input) var(--r-input) 0; }
.input-group .input:focus, .input-group .input:focus-visible { position: relative; z-index: 1; }
.input-group__affix { display: inline-flex; align-items: center; padding: 0 var(--s-3); background: var(--surface-2); border: 1px solid var(--line-strong); color: var(--ink-2); font-size: 16px; font-weight: 600; white-space: nowrap; }
.input-group__affix:first-child { border-right: 0; border-radius: var(--r-input) 0 0 var(--r-input); }
.input-group__affix:last-child { border-left: 0; border-radius: 0 var(--r-input) var(--r-input) 0; }
.check { display: flex; gap: var(--s-3); align-items: center; min-height: var(--tap); font-weight: 500; cursor: pointer; }
.check input { width: 22px; height: 22px; accent-color: var(--accent); flex: none; }
.form-grid { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }

/* ------------------------------------------------------------------ segmented (sliding thumb), tabs, week picker */
.seg { position: relative; isolation: isolate; display: inline-flex; flex-wrap: wrap; gap: var(--s-1); padding: var(--s-1); border-radius: var(--r-pill); background: var(--surface-2); max-width: 100%; }
/* R8 (Emil: no animation on 100×/day actions): the thumb JUMPS to the chosen option; tab and filter switches never slide */
.seg__thumb {
  position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 0; pointer-events: none; opacity: 0;
  border-radius: var(--r-pill); background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong);
  transition: none; transform-origin: 0 0;   /* R10 §6: no CSS transition — Q.motion.slide moves it (WAAPI, 180 ms) */
}
.seg.has-thumb > .seg__thumb { opacity: 1; }
.seg__btn {
  position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: 40px; padding: 0 var(--s-4);
  border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink-2); font-size: 16px; font-weight: 500; white-space: nowrap;
  transition: color var(--d-fast) var(--ease-out);
}
@media (pointer: coarse) { .seg__btn { min-height: var(--tap); } }
.seg__btn[aria-checked="true"] { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: inset 0 0 0 1px var(--line-strong); }
.seg.has-thumb > .seg__btn[aria-checked="true"] { background: transparent; box-shadow: none; }
.seg__btn[aria-checked="true"]::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--accent); }
.seg__btn:disabled { opacity: .5; cursor: not-allowed; }
.seg__sub { font-weight: 400; font-size: 13px; color: var(--ink-3); }
/* R4 §C: a segment label is one line ("Cross-check" never breaks at its hyphen); the button sizes to it */
.seg__label { white-space: nowrap; }
.seg--lg { border-radius: var(--r-card); }
.seg--lg > .seg__thumb { border-radius: var(--r-input); box-shadow: inset 0 0 0 2px var(--accent); }
.seg--lg .seg__btn { min-height: 56px; flex-direction: column; gap: 2px; padding: var(--s-2) var(--s-4); border-radius: var(--r-input); }
.seg--lg .seg__btn[aria-checked="true"]::before { display: none; }
.seg--lg .seg__btn[aria-checked="true"] { box-shadow: inset 0 0 0 2px var(--accent); }
.seg--lg.has-thumb > .seg__btn[aria-checked="true"] { box-shadow: none; }
.seg--block { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 96px), 1fr)); width: 100%; }
@media (hover: hover) and (pointer: fine) { .seg__btn:hover:not([aria-checked="true"]):not(:disabled) { color: var(--ink); } }
.tabs { position: relative; display: flex; gap: 2px; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; margin-bottom: var(--s-4); }
/* R10 §6: ONE underline (.tabs__ind) slides between tabs (transform, 180 ms); the content swaps instantly. Until
   Q.ui.syncTabs places it, the selected tab draws its own underline, so nothing is ever missing. */
.tabs__ind { position: absolute; left: 0; bottom: 0; width: 0; height: 3px; background: var(--accent); pointer-events: none; opacity: 0; transform-origin: 0 0; }
.tabs.has-ind > .tabs__ind { opacity: 1; }
.tabs.has-ind > .tabs__btn[aria-selected="true"] { box-shadow: none; }
.tabs::-webkit-scrollbar { display: none; }
/* UX-06: a sideways strip with items off-screen fades at that edge, so it reads as scrollable (Q.ui.revealTabs sets the classes) */
.is-more-end:is(.tabs, [data-reveal]) { -webkit-mask-image: linear-gradient(to right, var(--mask) calc(100% - 36px), transparent); mask-image: linear-gradient(to right, var(--mask) calc(100% - 36px), transparent); }
.is-more-start:is(.tabs, [data-reveal]) { -webkit-mask-image: linear-gradient(to right, transparent, var(--mask) 36px); mask-image: linear-gradient(to right, transparent, var(--mask) 36px); }
.is-more-start.is-more-end:is(.tabs, [data-reveal]) { -webkit-mask-image: linear-gradient(to right, transparent, var(--mask) 36px, var(--mask) calc(100% - 36px), transparent); mask-image: linear-gradient(to right, transparent, var(--mask) 36px, var(--mask) calc(100% - 36px), transparent); }
.tabs__btn {
  display: inline-flex; flex: none; align-items: center; justify-content: center; min-height: var(--tap); min-width: var(--tap); padding: 0 var(--s-4); border: 0; background: none;
  color: var(--ink-2); font-weight: 600; font-size: 16px; white-space: nowrap; box-shadow: inset 0 -3px 0 transparent;
  transition: color var(--d-fast) var(--ease-out);
}
.tabs__btn[aria-selected="true"] { color: var(--ink); box-shadow: inset 0 -3px 0 var(--accent); }
.tabs__btn:focus-visible { outline-offset: -3px; }
/* R6 final check: the 20 px phone gutter left Sales/Reports/Expenses tabs clipped at 390; tighter tabs fit as in R5 */
@media (max-width: 719px) { .tabs { gap: 0; } .tabs__btn { padding: 0 var(--s-3); } }   /* UX-04: the strip scrolls (overflow: auto), so an outer ring was clipped to a sliver */
.weekpick { display: inline-flex; gap: var(--s-2); flex-wrap: nowrap; }
.weekpick__btn { padding: 0 var(--s-3); }
.weekpick__now[aria-pressed="true"] { border-color: var(--accent); color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent); }
.weekpick__label { color: var(--ink-2); margin-top: var(--s-2); }

/* ------------------------------------------------------------------ tables → cards */
.tbl { min-width: 0; }
.tbl-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-card); background: var(--surface); max-height: none; }
.table { width: 100%; border-collapse: separate; border-spacing: 0; font: var(--t-meta); font-weight: 400; }
.table th { position: sticky; top: 0; z-index: 1; background: var(--surface-3); color: var(--ink-3); font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); white-space: nowrap; }
.table td { height: 56px; padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tfoot td { border-top: 2px solid var(--line-strong); border-bottom: 0; font-weight: 700; background: var(--surface-3); }
.table tr.is-clickable { cursor: pointer; }
.ta-right { text-align: right; } .ta-center { text-align: center; } .ta-left { text-align: left; }
.tcards { display: none; }
@media (hover: hover) and (pointer: fine) { .table tr.is-clickable:hover td { background: var(--surface-3); } }
/* R8 MOT-02: a touch tablet has no hover, so the row answers the press itself (background only, never transform) */
.table tr.is-clickable td { transition: background-color var(--d-fast) var(--ease-out); }
.table tr.is-clickable:active td { background: var(--surface-3); }
@media (max-width: 719px) {
  .tbl .tbl-wrap { display: none; }
  .tcards { display: grid; gap: var(--s-3); list-style: none; padding: 0; margin: 0; }
  .tcards > li { border-radius: var(--r-card); }
  .tcard { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s-4); }
  .tcards > li.is-clickable { cursor: pointer; }
  .tcards > li.is-clickable:active .tcard { background: var(--surface-3); }
  .tcard__title { font-weight: 700; margin-bottom: var(--s-2); }
  .tcard__dl { display: grid; gap: var(--s-2); }
  .tcard__dl > div { display: flex; justify-content: space-between; gap: var(--s-3); align-items: baseline; }
  .tcard__dl dt { color: var(--ink-3); font-size: 14px; }
  .tcard__dl dd { text-align: right; font-weight: 500; min-width: 0; overflow-wrap: anywhere; }
  .tcards__foot { padding: var(--s-3) var(--s-4); border-radius: var(--r-card); background: var(--surface-2); font-weight: 700; }
}
.kv { display: grid; gap: var(--s-3); }
.kv > div { display: flex; justify-content: space-between; gap: var(--s-4); align-items: baseline; padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.kv > div:last-child { border-bottom: 0; padding-bottom: 0; }
.kv dt { color: var(--ink-3); } .kv dd { font-weight: 600; text-align: right; overflow-wrap: anywhere; }
.totals { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-8); padding: var(--s-4) var(--s-5); border-radius: var(--r-card); background: var(--surface); border: 1px solid var(--line); margin-bottom: var(--s-4); }
.totals > div { display: grid; gap: 2px; }
.totals dt, .totals .totals__label { font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.totals dd, .totals .totals__value { font: var(--t-h2); }

/* ------------------------------------------------------------------ R6 stat strip (Q.ui.statStrip): no boxes, hairline dividers */
.stats { display: flex; margin: 0 0 var(--s-5); padding: 0; }
/* min-width: min-content: cells share the row equally but never shrink below their own (nowrap) figure, so a long
   amount ("KES 1,769,540") takes room from its neighbours instead of spilling past the strip */
.stats__cell { flex: 1 1 0; display: grid; align-content: start; gap: var(--s-1); min-width: min-content; padding-inline: var(--s-4); border-inline-start: 1px solid var(--line); }
.stats__cell--lead { flex: 0 0 auto; }   /* the hero figure takes its own width; the other cells share the rest */
.stats__cell:first-child { padding-inline-start: 0; border-inline-start: 0; }
.stats__label { font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.stats__value { font: var(--t-h3); white-space: nowrap; margin: 0; }
.stats__cell--lead .stats__value { font: var(--t-hero); font-variant-numeric: tabular-nums lining-nums; letter-spacing: -.01em; }
.stats__meta { font: var(--t-meta); color: var(--ink-3); margin: 0; }
@media (max-width: 379px) { .stats__cell { padding-inline: var(--s-3); } }

/* ------------------------------------------------------------------ R6 list rows (Q.ui.listRow / list) and grouped lists */
.lrows { list-style: none; margin: 0; padding: 0; }
.lrows:not(.glist__box) > li + li > * { border-top: 1px solid var(--line); }
.lrow {
  width: 100%; display: flex; align-items: center; gap: var(--s-3); min-height: 64px; padding: var(--s-2) var(--s-4);
  border: 0; border-radius: 0; background: transparent; color: var(--ink); text-align: left; font: inherit; text-decoration: none;
  transition: background-color var(--d-fast) var(--ease-out), transform var(--d-press) var(--ease-out);
}
.lrow--2 { min-height: 72px; }
button.lrow, .lrow__main { cursor: pointer; }
button.lrow:active, .lrow__main:active { background: var(--surface-3); transform: scale(.97); }
.lrow:focus-visible, .lrow__main:focus-visible { outline-offset: -3px; }
.lrow.is-current { background: var(--accent-soft); }
.lrow__lead { flex: none; display: inline-grid; place-items: center; min-width: 24px; color: var(--ink-2); }
.lrow__body { flex: 1; min-width: 0; display: grid; gap: 2px; }
.lrow__l1 { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.lrow__code { flex: none; }
.lrow__title { font: var(--t-h3); min-width: 0; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.lrow__meta { font: var(--t-meta); color: var(--ink-3); min-width: 0; overflow-wrap: anywhere; }
.lrow__st { white-space: nowrap; }   /* the separator travels with the status word, never dangles at a line end */
.lrow__end { flex: none; display: grid; justify-items: end; gap: 2px; text-align: right; }
.lrow__value { font: var(--t-h3); white-space: nowrap; }
.lrow__vsub { font: var(--t-meta); color: var(--ink-3); white-space: nowrap; }
.lrow__chev { flex: none; color: var(--ink-3); }
.lrow--danger, .lrow--danger .lrow__lead { color: var(--danger); }
.lrow--split { padding: 0 var(--s-4) 0 0; gap: var(--s-2); }
.lrow__main { flex: 1; min-width: 0; align-self: stretch; display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) 0 var(--s-2) var(--s-4); border: 0; background: transparent; color: inherit; font: inherit; text-align: left; }
.lrow__btn { flex: none; }
@media (hover: hover) and (pointer: fine) { button.lrow:hover, .lrow__main:hover { background: var(--surface-3); } button.lrow:hover .lrow__chev { color: var(--ink); } }
.glist { display: grid; gap: var(--s-6); }
.glist__group { min-width: 0; }
.glist__label { display: flex; align-items: center; gap: var(--s-2); margin: 0 0 var(--s-2); padding-inline: var(--s-4); font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.glist__sub { margin-inline-start: auto; font: var(--t-meta); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
.glist__box { list-style: none; margin: 0; padding: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; }
.glist__box > li { position: relative; }
.glist__box > li + li::before { content: ""; position: absolute; top: 0; inset-inline: var(--s-4) 0; height: 1px; background: var(--line); z-index: 1; }
/* inside a popover or sheet the group box is the surface itself */
.popover .glist, .modal .glist { gap: var(--s-4); }
.popover .glist__box { border: 0; border-radius: 0; background: transparent; }
.popover .glist__label { padding-inline: var(--s-3); margin-top: var(--s-2); }
.popover .lrow { padding-inline: var(--s-3); border-radius: var(--r-input); }
.modal .glist__label { padding-inline: var(--s-1); }
.nstatus { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-2); width: 100%; min-height: var(--tap); padding: var(--s-2) var(--s-3); margin-top: var(--s-2); border: 0; border-top: 1px solid var(--line); background: transparent; color: var(--ink-2); font: var(--t-meta); text-align: left; }
.nstatus__txt { flex: 1; min-width: 0; }
@media (hover: hover) and (pointer: fine) { button.nstatus:hover { background: var(--surface-3); } }
.more__logout { margin-top: var(--s-6); }

/* ------------------------------------------------------------------ R6 sticky action bar (Q.ui.actionBar): ONE primary */
.abar {
  position: sticky; z-index: 30; bottom: calc(var(--tabbar-h) + var(--tabbar-rise) + env(safe-area-inset-bottom));
  margin: var(--s-6) calc(-1 * var(--gutter-r)) 0 calc(-1 * var(--gutter-l));
  padding: var(--s-3) var(--gutter-r) var(--s-3) var(--gutter-l);
  background: var(--surface); border-top: 1px solid var(--line); box-shadow: var(--shadow-up);
}
/* fill the --tabbar-rise strip under the bar so rows don't show through between it and the tab bar */
.abar::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; height: var(--tabbar-rise); background: var(--surface); pointer-events: none; }
html.is-task .abar { bottom: 0; padding-bottom: calc(var(--s-3) + env(safe-area-inset-bottom)); }
html.is-task:has(.abar) .view { padding-bottom: 0; }
.abar__in { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); max-width: 1280px; margin-inline: auto; }
.abar__sum { display: grid; min-width: 0; }
.abar__label { font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.abar__total { font: var(--t-h2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.abar__sub { font: var(--t-meta); color: var(--ink-3); }
.abar__reason { font: var(--t-meta); color: var(--ink-3); }
.abar__btn { flex: none; min-width: 160px; }
.abar__btnlabel { display: inline-flex; align-items: center; gap: var(--s-2); }
.abar__btn.is-done .ic { animation: q-pop var(--d-fast) var(--ease-out) both; }
@media (min-width: 720px) {
  .abar { bottom: var(--s-4); margin-inline: 0; padding: var(--s-3) var(--s-3) var(--s-3) var(--s-5); border: 1px solid var(--line); border-radius: var(--r-card); }
  html.is-task .abar { bottom: var(--s-4); padding-bottom: var(--s-3); }
  .abar::after { display: none; }
  html.is-task:has(.abar) .view { padding-bottom: 96px; }
}

/* ------------------------------------------------------------------ R6 task header (Q.ui.taskHeader) */
.taskh {
  position: sticky; top: var(--stick-top); z-index: 35; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center;
  height: 56px; margin: calc(-1 * var(--view-pt)) calc(-1 * var(--gutter-r)) var(--s-4) calc(-1 * var(--gutter-l)); padding: 0 var(--s-2);
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.taskh__start { justify-self: start; } .taskh__end { justify-self: end; }
.taskh__title { font: var(--t-h3); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 56vw; }
.taskh__btn { min-height: var(--tap); padding: 0 var(--s-3); border: 0; border-radius: var(--r-pill); background: none; color: var(--accent-text); font: 600 16px/20px var(--font); white-space: nowrap; transition: background-color var(--d-fast) var(--ease-out); }
.taskh__btn:disabled { opacity: .5; cursor: not-allowed; }
.taskh__ctx { display: flex; align-items: center; gap: var(--s-1); margin: 0 0 var(--s-4); font: var(--t-meta); color: var(--ink-2); }
.taskh__ctx--btn { min-height: var(--tap); margin-top: calc(-1 * var(--s-3)); padding: 0; border: 0; background: none; text-align: left; }
@media (hover: hover) and (pointer: fine) { .taskh__btn:hover:not(:disabled) { background: var(--surface-2); } .taskh__ctx--btn:hover { color: var(--ink); } }

/* ------------------------------------------------------------------ R6 filter pill + sheet */
.fpill {
  display: inline-flex; align-items: center; gap: var(--s-2); min-height: var(--tap); max-width: 100%; padding: 0 var(--s-3) 0 var(--s-4);
  border: 1px solid var(--line-strong); border-radius: var(--r-pill); background: var(--surface); color: var(--ink); font: 600 16px/20px var(--font); white-space: nowrap;
  transition: background-color var(--d-fast) var(--ease-out), transform var(--d-press) var(--ease-out);
}
.fpill:active { transform: scale(.97); }
.fpill__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.fpill__chev { color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { .fpill:hover { background: var(--surface-2); } }
.fsheet__top { display: flex; justify-content: flex-end; margin: calc(-1 * var(--s-2)) 0 var(--s-2); }
.fsheet__opts { display: grid; }
.fsheet__opt {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); width: 100%; min-height: 56px; padding: var(--s-2) var(--s-1);
  border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--ink); text-align: left; font-size: 16px;
}
.fsheet__opt:last-child { border-bottom: 0; }
.fsheet__txt { display: grid; min-width: 0; }
.fsheet__sub { font: var(--t-meta); color: var(--ink-3); }
.fsheet__check { color: var(--accent-text); opacity: 0; }
.fsheet__opt[aria-checked="true"] { font-weight: 600; }
.fsheet__opt[aria-checked="true"] .fsheet__check { opacity: 1; }
.modal--fsheet .modal__foot .btn { flex: 1 1 100%; }

/* ------------------------------------------------------------------ R6 inline notice (Q.ui.notice) */
.inotice {
  display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--s-2); min-height: var(--tap); padding: 0 var(--s-1) 0 var(--s-3);
  border-radius: var(--r-input); background: var(--info-soft); color: var(--ink); font: var(--t-meta); font-weight: 400;
}
.inotice--warn { background: var(--warn-soft); } .inotice--danger { background: var(--danger-soft); } .inotice--ok { background: var(--ok-soft); }
.inotice__ic { color: var(--info); }
.inotice--warn .inotice__ic { color: var(--warn); } .inotice--danger .inotice__ic { color: var(--danger); } .inotice--ok .inotice__ic { color: var(--ok); }
.inotice__line { flex: 1 1 0; min-width: 0; padding-block: var(--s-3); }
.inotice__btn { display: inline-flex; align-items: center; gap: var(--s-1); min-height: var(--tap); padding: 0 var(--s-2); border: 0; border-radius: var(--r-pill); background: none; color: var(--ink); font: 600 14px/20px var(--font); text-decoration: underline; text-underline-offset: 3px; }
.inotice__btn .ic { transition: transform var(--d-fast) var(--ease-out); }
.inotice__btn[aria-expanded="true"] .ic { transform: rotate(180deg); }
.inotice__details { flex-basis: 100%; padding: 0 var(--s-3) var(--s-3) 26px; }

/* ------------------------------------------------------------------ R6 keypad (Q.ui.keypad): borderless keys on a hairline grid */
.kpad { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--line); border-block: 1px solid var(--line); }
.kpad__key {
  min-height: 56px; border: 0; border-radius: 0; background: var(--surface); color: var(--ink); font: var(--t-key);
  user-select: none; -webkit-user-select: none; touch-action: manipulation; transition: background-color var(--d-press) linear;
}
.kpad__key:active { background: var(--surface-2); }
.kpad__key:focus-visible { outline-offset: -3px; }   /* UX-02: keys sit 1 px apart, so the next key painted over an outer ring */
.kpad__key--back { display: grid; place-items: center; color: var(--ink-2); }

/* ------------------------------------------------------------------ empty state */
.empty { display: grid; justify-items: center; gap: var(--s-3); text-align: center; padding: var(--s-10) var(--s-5); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); }
.empty__icon { display: grid; place-items: center; width: 56px; height: 56px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--ink-2); }
/* R10 §4/§6: the illustration (112 px; 128 px on a desktop; 72 px inside a card) and an Archivo title */
.empty__art { display: grid; place-items: center; color: var(--ink); }
.empty__art .illo { width: 112px; height: auto; }
@media (min-width: 720px) { .empty__art .illo { width: 128px; } }
.card .empty__art .illo, .modal .empty__art .illo { width: 72px; }
.empty.is-enter .empty__art { animation: q-rise var(--d-rise) var(--ease-out) both; }
.empty.is-enter > :not(.empty__art) { animation: q-rise var(--d-rise) var(--ease-out) 40ms both; }
.empty.is-enter .mv-settle { animation: q-settle var(--d-rise) var(--ease-out) 200ms both; }
.empty.is-enter .mv-turn { transform-box: fill-box; transform-origin: center; animation: q-turn 600ms var(--ease-out) 200ms both; }
.empty.is-enter :is(.mv-arc, .mv-fade) { animation: q-fade var(--d-rise) var(--ease-out) 200ms both; }
.empty.is-enter .mv-stamp { transform-box: fill-box; transform-origin: center; animation: q-popin var(--d-rise) var(--spring-settle) 200ms both; }
/* the illustration grammar (js/illos.js): 2 px ink outline, flat stone facets, one brand area, the strata ground */
.illo { display: block; overflow: visible; color: var(--ink); }
.illo :is(path, rect, circle, ellipse) { stroke: currentColor; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.illo .s1 { fill: var(--stone-1); } .illo .s2 { fill: var(--stone-2); } .illo .s3 { fill: var(--stone-3); }
.illo .b { fill: var(--brand); } .illo .n { fill: none; }
.illo .k { fill: none; stroke: var(--stone-ink); stroke-width: 1.5; }
.illo .illo__g { fill: none; stroke: var(--stone-3); stroke-width: 1.5; }
.illo .bl, .illo .bw { fill: none; stroke: var(--brand); stroke-width: 3; }
.illo .ck { fill: none; stroke: var(--hero-ink); stroke-width: 2; }
.illo .illo-level { transform-box: fill-box; transform-origin: 50% 100%; stroke: none; }
.illo .illo-level.is-low { fill: var(--warn-bar); }
.illo .illo-low { stroke-dasharray: 4 3; }
.empty--danger .empty__art { color: var(--ink); }
.empty--danger .empty__icon { background: var(--danger-soft); color: var(--danger); }
.empty__title { font: var(--t-h2-display); max-width: 32ch; }
.empty__body { color: var(--ink-2); max-width: 52ch; }
.empty .btn { margin-top: var(--s-2); }

/* ------------------------------------------------------------------ activity timeline */
.tl { list-style: none; padding: 0; display: grid; }
.tl__item { display: grid; grid-template-columns: 16px minmax(0, 1fr); gap: var(--s-3); position: relative; padding-bottom: var(--s-4); }
.tl__item::before { content: ""; position: absolute; left: 7px; top: 16px; bottom: 0; width: 2px; background: var(--line); }
.tl__item:last-child { padding-bottom: 0; } .tl__item:last-child::before { display: none; }
.tl__dot { width: 16px; height: 16px; border-radius: var(--r-pill); margin-top: var(--s-1); background: var(--surface); border: 3px solid var(--ink-3); }
.tl__dot--ok { border-color: var(--ok); } .tl__dot--danger { border-color: var(--danger); }
.tl__head { font-size: 16px; } .tl__time { font-size: 13px; color: var(--ink-3); }
.tl__reason { margin-top: var(--s-1); padding: var(--s-2) var(--s-3); border-left: 3px solid var(--line-strong); background: var(--surface-3); font-size: 14px; border-radius: 0 var(--r-plate) var(--r-plate) 0; }
.tl__changes { list-style: none; padding: 0; margin-top: var(--s-1); font-size: 14px; color: var(--ink-2); }
.tl__k { color: var(--ink-3); }

/* ------------------------------------------------------------------ modal / bottom sheet (e2) — sheets rise, never pop */
/* minmax(0, 1fr): the one grid column never grows to a wide table's min-content (a sheet must never exceed the screen) */
.modal-root { position: fixed; inset: 0; z-index: 100; display: grid; grid-template-columns: minmax(0, 1fr); place-items: center; padding: var(--s-6); }
.modal-root.is-leaving { pointer-events: none; }
.modal-backdrop { position: absolute; inset: 0; background: var(--backdrop); animation: q-fade var(--d-rise) var(--ease-out) both; }
.modal {
  position: relative; display: flex; flex-direction: column; width: min(560px, 100%); max-height: calc(100dvh - 48px);
  background: var(--surface); color: var(--ink); border-radius: var(--r-sheet); box-shadow: var(--shadow-2); outline: none;
  animation: q-modal var(--d-sheet-in) var(--ease-out) both;   /* centred: fade + scale from .96, origin centre */
}
.modal--sm { width: min(440px, 100%); }
.modal--lg { width: min(960px, 100%); }
.modal--sheet { width: min(520px, 100%); }
.modal__grab { display: none; }
/* R9 §2.11: the handle is a 24 px drag zone (the bar is drawn inside it); swipe down closes the sheet */
.modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); padding: var(--s-4) var(--s-3) var(--s-3) var(--s-5); border-bottom: 1px solid var(--line); }
.modal__title { font: var(--t-h2); padding-top: var(--s-3); }
.modal__sub { color: var(--ink-3); font: var(--t-meta); font-weight: 400; }
.modal__body { padding: var(--s-5); overflow-y: auto; overscroll-behavior: contain; min-height: 0; }
.modal__foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s-3); padding: var(--s-4) var(--s-5); border-top: 1px solid var(--line); }
.modal-root.is-leaving .modal, .modal-root.is-leaving .modal-backdrop { animation: q-fade-out var(--d-sheet-out) var(--ease-out) both; }
.confirm__msg { color: var(--ink-2); margin-bottom: var(--s-3); }
@media (max-width: 719px) {
  .modal-root { place-items: end stretch; padding: 0; padding-top: calc(40px + var(--safe-top)); }
  /* R9 §2.11: 48 px from the top on any phone, whatever the Android nav bar reports (safe-area-inset-bottom is 0 there) */
  .modal, .modal--sm, .modal--lg, .modal--sheet { width: 100%; max-height: calc(100dvh - 48px); border-radius: var(--r-sheet) var(--r-sheet) 0 0; animation: q-sheet var(--d-sheet-spring) var(--spring-sheet) both; }   /* R10 §6: the sheet spring, 380 ms */
  .modal__grab { display: block; width: 100%; height: 24px; touch-action: none; cursor: grab; position: relative; flex: none; }
  .modal__grab::before { content: ""; position: absolute; left: 50%; top: var(--s-2); width: 36px; height: 4px; margin-left: -18px; border-radius: var(--r-pill); background: var(--line-strong); }
  .modal__head { touch-action: none; }
  .modal__head { padding: var(--s-1) var(--s-2) var(--s-3) var(--s-5); }
  .modal__body { padding: var(--s-4) var(--s-5); }
  .modal__foot { padding: var(--s-3) var(--s-5) calc(var(--s-3) + env(safe-area-inset-bottom)); }
  .modal__foot .btn { flex: 1 1 140px; }
  .modal-root.is-leaving .modal { animation: q-sheet-out var(--d-sheet-out) var(--ease-exit) both; }
}
@keyframes q-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes q-fade-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes q-pop { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes q-sheet { from { transform: translateY(100%); } to { transform: none; } }
@keyframes q-modal { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes q-popin { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes q-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes q-sheet-out { from { transform: none; } to { transform: translateY(100%); } }
/* R10 */
@keyframes q-pill { from { transform: scale(.85); } to { transform: none; } }
@keyframes q-settle { from { transform: translateY(-2px); } to { transform: none; } }
@keyframes q-turn { from { transform: rotate(-90deg); } to { transform: none; } }
@keyframes q-toast-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(6px); } }
@keyframes q-pulse { from { opacity: 1; } to { opacity: .55; } }
@keyframes q-stack { 0% { transform: translateY(-12px); opacity: 0; } 14% { transform: none; opacity: 1; } 80% { transform: none; opacity: 1; } 100% { transform: none; opacity: 0; } }

/* ------------------------------------------------------------------ popover (bell, user menu, "?" on desktop) */
.popover {
  position: fixed; z-index: 90; width: min(400px, calc(100vw - 24px)); max-height: min(72dvh, 620px); overflow-y: auto;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-card); box-shadow: var(--shadow-2);
  padding: var(--s-2); animation: q-popin var(--d-pop-in) var(--ease-out) both;
  transform-origin: top right;   /* the bell and the user menu open from the top bar's right end */
}
@media (max-width: 719px) { .popover { width: auto; } }
.popover__head { display: flex; align-items: center; gap: var(--s-3); justify-content: space-between; padding: var(--s-3) var(--s-3) var(--s-3); border-bottom: 1px solid var(--line); margin-bottom: var(--s-1); }
.popover__head > div { flex: 1; min-width: 0; }
.popover__title { font: var(--t-h3); }
/* R9 §2.8 bell: the Notifications section (unseen rows bold), and the one banner under the top bar (owner) */
.bellnt { margin-bottom: var(--s-2); }
.bellnt__row .lrow__title { font-weight: 500; }
.bellnt__row.is-unseen .lrow__title { font-weight: 700; }
.bellnt__row .lrow__lead { color: var(--warn); }
.qbanner { padding: var(--s-3) var(--gutter-r) 0 var(--gutter-l); }
.qbanner[hidden] { display: none; }
.qbanner__in { max-width: 1280px; margin-inline: auto; align-items: center; padding-inline: var(--s-3) var(--s-1); }
.qbanner__ctx { color: var(--ink-2); font-weight: 400; }
.qbanner__x { flex: none; }
/* R10 §8.1 the still copy of a dismissed banner, fading where it stood (core dismissBanner); never takes a tap */
.qbanner--gone { position: fixed; z-index: 40; margin: 0; pointer-events: none; }
html.is-task .qbanner { display: none; }
.popover__section { font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); padding: var(--s-3) var(--s-3) var(--s-1); }
.popover__empty { display: flex; gap: var(--s-2); align-items: center; padding: var(--s-4) var(--s-3); color: var(--ok); font-weight: 500; }
.popover__foot { padding: var(--s-2) var(--s-1) var(--s-1); border-top: 1px solid var(--line); margin-top: var(--s-2); }

/* attention rows (R5 shape, Q.ui.attnRow: claims and daily expenses still use it; the bell uses Q.ui.needsRow) */
.attn__list { display: grid; gap: 2px; }
.attn__item {
  width: 100%; display: flex; align-items: center; gap: var(--s-3); min-height: 64px; padding: var(--s-3); border: 0; border-radius: var(--r-input);
  background: transparent; text-align: left; color: var(--ink);
}
.attn__count { display: inline-grid; place-items: center; min-width: 40px; height: 40px; padding: 0 var(--s-2); border-radius: var(--r-input); font: 700 17px/1 var(--font); flex: none; }
.attn__count--warn { background: var(--warn-soft); color: var(--warn); }
.attn__count--danger { background: var(--danger-soft); color: var(--danger); }
.attn__count--info { background: var(--info-soft); color: var(--info); }
.attn__count--ok { background: var(--ok-soft); color: var(--ok); }
.attn__text { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-1); flex: 1; min-width: 0; }
.attn__label { font-weight: 600; font-size: 16px; line-height: 1.3; }
.attn__chev { color: var(--ink-3); flex: none; }
.attn__none { display: flex; gap: var(--s-2); align-items: center; padding: var(--s-3) var(--s-5) var(--s-5); color: var(--ok); font-weight: 500; }
.attn__none--muted { color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { .attn__item:hover { background: var(--surface-3); } .attn__item:hover .attn__chev { color: var(--ink); } }
/* a Needs-you row is a list row; these restore the list-row shape over the R5 .attn__item one */
.lrow.attn__item { min-height: 56px; padding: var(--s-2) var(--s-4); border-radius: 0; gap: var(--s-3); }
.popover .lrow.attn__item { padding-inline: var(--s-3); border-radius: var(--r-input); }

/* user lists (menu, demo, sign-in) */
.userlist { display: grid; gap: 2px; }
.userlist--grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: var(--s-2); }
.userlist__btn {
  width: 100%; display: flex; align-items: center; gap: var(--s-3); min-height: 56px; padding: var(--s-2) var(--s-3); border: 1px solid transparent; border-radius: var(--r-input);
  background: transparent; text-align: left; color: var(--ink);
}
.userlist--grid .userlist__btn { border-color: var(--line); }
.userlist__btn > span:nth-child(2) { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.userlist__name { font-weight: 600; }
.userlist__role { font-size: 13px; color: var(--ink-3); }
.userlist__btn[aria-pressed="true"] { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.userlist__check { color: var(--accent-text); flex: none; }
@media (hover: hover) and (pointer: fine) { .userlist__btn:hover { background: var(--surface-3); } }
.morelist .lrow { min-height: 56px; }
.morelist .lrow__title { font-weight: 600; font-size: 16px; }

/* ------------------------------------------------------------------ toasts (e2) */
.toasts {
  position: fixed; z-index: 150; display: grid; gap: var(--s-2); pointer-events: none;
  left: var(--gutter-l); right: var(--gutter-r); bottom: calc(var(--tabbar-h) + var(--s-4) + env(safe-area-inset-bottom));
}
@media (min-width: 720px) { .toasts { left: auto; right: var(--s-6); bottom: var(--s-6); width: min(420px, calc(100vw - 48px)); } }
/* While a dialog or sheet is open its buttons sit at the bottom: toasts move to the top so they never cover them. */
.has-modal .toasts { top: calc(12px + env(safe-area-inset-top)); bottom: auto; }
/* An entry form's sticky Save bar sits where the toasts would: they come down from under the top bar instead. */
html:has(.sale-bar:not([hidden]), .exp-bar:not([hidden]), .cons-bar:not([hidden]), .cl-dock:not([hidden]), .abar:not([hidden])):not(.has-modal) .toasts { top: calc(var(--stick-top) + var(--strip-h) + 8px); bottom: auto; }
@media (min-width: 720px) { .has-modal .toasts { left: 50%; right: auto; transform: translateX(-50%); } }
.toast {
  display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) var(--s-4); border-radius: var(--r-input); background: var(--toast-bg); color: var(--toast-ink);
  box-shadow: var(--shadow-2); font-weight: 500; font-size: 16px; pointer-events: auto; animation: q-rise var(--d-msg) var(--ease-out) both;
  position: relative; overflow: hidden; min-height: 56px; align-items: center;
}
.toast__text { flex: 1; min-width: 0; display: grid; gap: var(--s-1); }
/* R10 §6: the Undo action, the countdown line (Q.ui.toast runs it; the timer pauses on hover/focus), the mini seal */
.toast__act { flex: none; min-height: var(--tap); margin-block: calc(-1 * var(--s-2)); padding: 0 var(--s-3); border: 0; border-radius: var(--r-pill); background: transparent; color: var(--toast-ink); font: 700 16px/20px var(--font); text-decoration: underline; text-underline-offset: 3px; }
.toast__x { flex: none; color: var(--toast-ink); margin-block: calc(-1 * var(--s-2)); }
.toast__bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--toast-ic-ok); transform-origin: 0 50%; }
.toast .seal { flex: none; color: var(--toast-ic-ok); }
html.no-motion .toast__bar { display: none; }

.toast .ic { margin-top: 2px; }
.toast--ok .ic { color: var(--toast-ic-ok); } .toast--warn .ic { color: var(--toast-ic-warn); } .toast--error .ic { color: var(--toast-ic-danger); } .toast--info .ic { color: var(--toast-ic-info); }
.toast.is-leaving { animation: q-toast-out var(--d-toast-out) var(--ease-exit) both; }
.toast[role] { animation: none; }   /* the rise is played by Q.ui.toast (spring); CSS keeps the exit */
.toast.is-leaving[role] { animation: q-toast-out var(--d-toast-out) var(--ease-exit) both; }

/* ------------------------------------------------------------------ money card base (shared: dashboard, daily expenses) */
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s-4) var(--s-5) var(--s-5); display: grid; gap: var(--s-2); align-content: start; min-width: 0; }
.kpi__head { display: flex; align-items: center; gap: var(--s-3); min-height: 40px; }
.kpi__icon { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-input); flex: none; }
.kpi__icon--sales { background: var(--accent-soft); color: var(--accent-text); }
.kpi__icon--exp { background: var(--warn-soft); color: var(--warn); }
.kpi__icon--profit { background: var(--info-soft); color: var(--info); }
.kpi__label { font: var(--t-h3); color: var(--ink-2); flex: 1; }
.kpi__value { font: var(--t-hero); font-variant-numeric: tabular-nums lining-nums; letter-spacing: -.01em; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-3); overflow-wrap: anywhere; }
.kpi__sub { color: var(--ink-2); font: var(--t-meta); font-weight: 400; }
.kpis__foot { font-size: 13px; color: var(--ink-3); margin: var(--s-2) 0 var(--s-5); }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s-4); }
.stat__value { font: var(--t-title); }
.stat__label { color: var(--ink-2); font-size: 14px; }

/* ------------------------------------------------------------------ presenter panel */
.demo-note { display: flex; gap: var(--s-2); align-items: center; padding: var(--s-3); border-radius: var(--r-input); background: var(--warn-soft); color: var(--ink); font-weight: 600; font-size: 14px; margin-bottom: var(--s-5); }
.demo-note .ic { color: var(--warn); }
.demo-sec { padding: var(--s-4) 0; border-top: 1px solid var(--line); display: grid; gap: var(--s-3); }
.demo-sec:first-of-type { border-top: 0; padding-top: 0; }
.demo-sec__title { font: var(--t-h3); }
.disclosure > summary { cursor: pointer; min-height: 44px; display: flex; align-items: center; gap: var(--s-2); list-style: none; }
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before { content: ""; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform var(--d-fast) var(--ease-out); flex: none; margin-right: var(--s-1); }
.disclosure[open] > summary::before { transform: rotate(45deg); }
.progress { height: 8px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.progress > span { display: block; height: 100%; width: 100%; background: var(--accent); border-radius: var(--r-pill); transform: scaleX(var(--pn, 0)); transform-origin: 0 50%; transition: transform var(--d-rise) var(--ease-out), background-color var(--d-tick) var(--ease-out); }
.progress.is-full > span { background: var(--ok); }   /* R10 §6: at 100 % the fill turns --ok; set --pn (0…1) on the span */
.steps { display: grid; gap: 2px; counter-reset: s; }
@media (min-width: 900px) { .steps { display: block; columns: 2; column-gap: var(--s-4); } .steps > li { break-inside: avoid; } }
.steps__btn { width: 100%; display: flex; align-items: center; gap: var(--s-3); min-height: 44px; padding: var(--s-1) var(--s-2); border: 0; border-radius: var(--r-input); background: transparent; color: var(--ink); text-align: left; font-size: 16px; }
.steps__n { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: var(--r-pill); border: 2px solid var(--line-strong); font-size: 13px; font-weight: 700; color: var(--ink-2); flex: none; }
.steps__btn.is-done .steps__n { background: var(--ok); border-color: var(--ok); color: var(--surface); }
.steps__btn.is-done .steps__label { color: var(--ink-2); }
.steps__label { flex: 1; }
.steps__go { color: var(--ink-3); }
@media (hover: hover) and (pointer: fine) { .steps__btn:hover { background: var(--surface-3); } }
.questions { padding-left: var(--s-6); display: grid; gap: var(--s-2); color: var(--ink); font-size: 16px; }
.selftest { display: grid; gap: var(--s-2); font-size: 14px; }
.selftest li { display: flex; gap: var(--s-2); align-items: flex-start; }
.selftest li span { color: var(--ink); }

/* ------------------------------------------------------------------ sign-in (keeps the flag blue: it is the brand page) */
.app--signin { background: var(--nav); }
.signin { min-height: 100dvh; display: grid; place-items: center; padding: var(--s-8) var(--gutter-r) var(--s-8) var(--gutter-l); }
.signin__col { width: min(440px, 100%); display: grid; gap: var(--s-4); }
.brand--light { display: flex; align-items: center; gap: var(--s-3); color: var(--nav-ink); padding-bottom: var(--s-2); }
.brand--light .brand__mark { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: var(--r-input); box-shadow: 0 0 0 2px var(--logo-ring); }
.brand--light .brand__text { display: flex; flex-direction: column; line-height: 1.2; }
.brand--light .brand__name { font: var(--t-h3); color: var(--nav-ink); }
.brand--light .brand__app { font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--nav-ink-2); }
.signin__card { padding: var(--s-6); }
.signin__title { font: var(--t-page-title); font-stretch: var(--fs-title); margin-bottom: var(--s-4); }
.signin__demo { padding: var(--s-4) var(--s-3) var(--s-3); }
.signin__sub { font: var(--t-h3); padding: 0 var(--s-2) var(--s-2); }
.signin__foot { text-align: center; color: var(--nav-ink-2); font-size: 13px; }

/* ------------------------------------------------------------------ R1: phone-first entry components */
/* centred form card for Record sale / Record expense: ~560px on desktop, the full column on a phone */
.entry-card { width: 100%; max-width: 560px; margin-inline: auto; }
@media (min-width: 720px) { .entry-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-card); padding: var(--s-5) var(--s-6) var(--s-6); } }

/* big −/+ number field (Q.ui.stepper): one control height (56) for the −/+ buttons, the field and the quick chips */
.stepper { gap: var(--s-2); }
.stepper__label { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px var(--s-3); font-size: 17px; }
.stepper__sub { font-weight: 500; font-size: 14px; color: var(--ink-3); }
.stepper__row { display: grid; grid-template-columns: 56px minmax(0, 1fr) 56px; gap: var(--s-2); align-items: stretch; }
.stepper__btn {
  display: grid; place-items: center; min-height: 56px; border-radius: var(--r-input); border: 1px solid var(--line-strong);
  background: var(--surface-2); color: var(--ink); user-select: none; -webkit-user-select: none; touch-action: manipulation;
  transition: transform var(--d-press) var(--ease-out), background-color var(--d-fast) var(--ease-out);
}
.stepper__btn:active:not(:disabled) { transform: scale(.97); background: var(--line); }
.stepper__btn:disabled { opacity: .45; cursor: not-allowed; }
.stepper__box { position: relative; display: block; min-width: 0; }
.stepper__input { height: 100%; min-height: 56px; padding-right: 52px; text-align: center; font: var(--t-key); }
.stepper__unit { position: absolute; right: var(--s-4); top: 50%; transform: translateY(-50%); color: var(--ink-3); font-size: 16px; font-weight: 600; pointer-events: none; }
.stepper__chips { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: var(--s-2); }
.stepper__chip {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-1);
  min-height: 56px; border-radius: var(--r-pill); border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-2);
  font-weight: 600; font-size: 16px; user-select: none; -webkit-user-select: none; touch-action: manipulation; transition: transform var(--d-press) var(--ease-out);
}
.stepper__chip:active { transform: scale(.97); }
.stepper__chip .stepper__chk { display: none; }   /* beats svg.ic's inline-block */
.stepper__chip[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); box-shadow: inset 0 0 0 1px var(--accent); }
.stepper__chip[aria-pressed="true"] .stepper__chk { display: inline-block; }
@media (hover: hover) and (pointer: fine) { .stepper__btn:hover:not(:disabled) { background: var(--line); } .stepper__chip:hover:not([aria-pressed="true"]) { background: var(--surface-2); } }

/* payment at the gate (Q.ui.methodPicker) */
.paypick { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: var(--s-3); }
.paypick__legend { padding: 0; margin-bottom: var(--s-2); font-size: 17px; }
.paypick__way { display: grid; gap: var(--s-3); min-width: 0; }
.paypick__way + .paypick__way { padding-top: var(--s-3); border-top: 1px solid var(--line); }
.paypick__wayt { font: var(--t-label); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.paypick__methods { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); }
.paypick__m {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-1); min-height: 64px; padding: var(--s-2) var(--s-1);
  border-radius: var(--r-input); border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-2);
  font-weight: 600; font-size: 16px; user-select: none; -webkit-user-select: none; touch-action: manipulation; transition: transform var(--d-press) var(--ease-out);
}
.paypick__m:active { transform: scale(.97); }
.paypick__m[aria-checked="true"] { background: var(--accent-soft); color: var(--accent-text); border-color: var(--accent); box-shadow: inset 0 0 0 2px var(--accent); }
.paypick__ref .input--xl { font-size: 20px; }
.paypick__amt { font-size: 16px; }
.paypick__amt .num { font: var(--t-h2); color: var(--ink); }
.paypick__split { justify-self: start; display: inline-flex; align-items: center; gap: var(--s-2); min-height: 44px; padding: 0 var(--s-1); border: 0; background: none; color: var(--info); font-weight: 600; font-size: 16px; text-decoration: underline; text-underline-offset: 3px; }
@media (hover: hover) and (pointer: fine) { .paypick__m:hover:not([aria-checked="true"]) { background: var(--surface-2); } }

/* the Record sheet (centre button). R10 §8.2: 72 px rows, the verb's icon in a 40 px tile; Record sale keeps its filled
   accent row (the 100×-a-day choice). No stagger: the rows are live from frame 1. */
.rec-sheet { display: grid; gap: var(--s-2); padding-bottom: var(--s-1); }
.rec-sheet__btn {
  width: 100%; display: flex; align-items: center; gap: var(--s-3); min-height: 72px; padding: var(--s-3) var(--s-4); border-radius: var(--r-card);
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink); text-align: left;
  user-select: none; -webkit-user-select: none; touch-action: manipulation; transition: transform var(--d-press) var(--ease-out);
}
.rec-sheet__btn:active { transform: scale(.97); }
.rec-sheet__btn--sale { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.rec-sheet__icon { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-input); background: var(--accent-soft); color: var(--accent-text); flex: none; }
.rec-sheet__btn--sale .rec-sheet__icon { background: var(--on-accent-veil); color: var(--on-accent); }
.rec-sheet__icon--exp { background: var(--warn-soft); color: var(--warn); }
.rec-sheet__icon--eod { background: var(--accent-soft); color: var(--accent-text); }
.rec-sheet__text { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.rec-sheet__title { font: var(--t-h3); }
.rec-sheet__sub { font-size: 14px; line-height: 20px; }   /* solid: faded white on the dark-mode --accent fell to 4.3:1 */
.rec-sheet__btn:not(.rec-sheet__btn--sale) .rec-sheet__sub { color: var(--ink-2); }
.rec-sheet__go { flex: none; opacity: .8; }

.viewas--demo { justify-self: start; }
.answered { display: grid; gap: var(--s-2); font-size: 16px; }
.answered li { display: flex; gap: var(--s-2); align-items: flex-start; }
.answered .ic { color: var(--ok); margin-top: var(--s-1); }

/* presenter: View as Desktop | Phone */
.viewas .seg__btn { min-height: 40px; padding: 0 var(--s-3); font-size: 14px; }
.viewas .seg__btn[aria-checked="true"]::before { display: none; }
.viewas--top { display: none; }
@media (min-width: 900px) { .viewas--top { display: inline-flex; flex-wrap: nowrap; margin-right: var(--s-2); } }
.is-frame .viewas { display: none !important; }
.pstage {
  position: fixed; inset: 0; z-index: 120; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: var(--s-3);
  padding: calc(16px + var(--safe-top)) var(--s-5) calc(16px + var(--safe-bottom)); background: var(--nav); color: var(--nav-ink); animation: q-fade var(--d-fast) var(--ease-out) both;
}
.pstage__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3) var(--s-4); max-width: 960px; width: 100%; margin-inline: auto; }
.pstage__title { display: flex; align-items: center; gap: var(--s-2); font: var(--t-h3); color: var(--nav-ink); }
.pstage__title .ic { color: var(--nav-mark); }
.pstage__dim { font: 500 14px/1.2 var(--font); color: var(--nav-ink-2); }
.pstage .seg { background: var(--nav-veil); }
.pstage .seg__btn { color: var(--nav-ink); }   /* --nav-ink-2 on the veiled blue was 4.0:1 */
.pstage .seg__btn[aria-checked="true"] { background: var(--surface); color: var(--ink); }
.pstage :focus-visible { outline-color: var(--nav-focus); }
.pstage__fit { min-height: 0; display: grid; place-items: start center; overflow: hidden; }
/* the device frame mimics a phone's own corners (presenter only, not part of the product's radius scale) */
.pframe {
  --s: 1; position: relative; width: 414px; height: 868px; padding: 12px; border-radius: 52px; background: var(--frame-bg);
  box-shadow: 0 0 0 2px var(--frame-line), var(--shadow-2); transform: scale(var(--s)); transform-origin: top center;
}
.pframe__screen { display: block; width: 390px; height: 844px; border: 0; border-radius: 40px; background: var(--bg); }
.pframe__fallback { position: absolute; inset: 12px; display: grid; place-content: center; justify-items: center; gap: var(--s-3); padding: var(--s-8); text-align: center; border-radius: 40px; background: var(--surface); color: var(--ink); font-size: 17px; font-weight: 500; }
.pframe__fallback .ic { color: var(--info); }
.pstage__note { text-align: center; font-size: 14px; color: var(--nav-ink-2); }

/* R4 §C: every text control that is 44 px with a mouse is 48 px on touch (SPEC: targets ≥ 48 px) — back links,
   "Paid two ways", summaries, chips and the demo checklist rows */
@media (pointer: coarse) {
  .backlink, .paypick__split, .chip--locked, .disclosure > summary, .steps__btn, .stepper__chip, .demo-fab { min-height: var(--tap); }
}

/* ------------------------------------------------------------------ R10 "Cut Stone" shared pieces (§1, §6)
   seal (Q.ui.seal) · loading glyph (Q.ui.loader / Q.ui.loading) · skeleton (Q.ui.skeleton) · fresh highlight, blast chips,
   digit settle (Q.motion). Helper API: research/erp-r10/FOUNDATION-API.md */
.q-display { font: var(--t-display); font-stretch: var(--fs-display); font-variant-numeric: tabular-nums lining-nums; letter-spacing: -.01em; }   /* Pay all / save-sheet figure */
.q-hero { font: var(--t-hero); font-variant-numeric: tabular-nums lining-nums; letter-spacing: -.01em; }   /* the one hero figure on a screen */
.seal { display: inline-block; flex: none; color: var(--ok); vertical-align: middle; }
.seal__check { stroke-dasharray: 1; stroke-dashoffset: 0; }
.qload { display: inline-flex; align-items: center; gap: var(--s-3); font: var(--t-meta); color: var(--ink-2); }
.qload__blocks { display: inline-grid; grid-template-rows: repeat(3, 10px); gap: 2px; width: 14px; }
.qload__b { display: block; width: 14px; height: 10px; border-radius: 3px; background: var(--brand); animation: q-stack 1200ms var(--spring-settle) 8 both; }   /* 8 × 1.2 s: stops before 10 s */
.qload__b:nth-child(1) { animation-delay: 320ms; } .qload__b:nth-child(2) { animation-delay: 160ms; }
.qload.is-stalled .qload__b { animation: none; opacity: 1; }
.skel { display: grid; gap: var(--s-2); }
.skel__b { display: block; border-radius: var(--r-plate); background: var(--surface-2); animation: q-pulse calc(var(--d-skel-pulse) / 2) ease-in-out 16 alternate both; }   /* 16 × 0.6 s = 9.6 s, then still */
.skel__hero { height: 40px; width: 60%; }
.skel--hero .skel__b { background: var(--skel-hero); }
.skel__row { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); min-height: 74px; padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); }
.skel__b--a { height: 18px; width: 55%; } .skel__b--b { height: 18px; width: 22%; }
.q-fresh { position: absolute; inset: 0; background: var(--accent-soft); pointer-events: none; z-index: 0; border-radius: inherit; }
.q-blast { position: fixed; z-index: 160; width: 0; height: 0; pointer-events: none; }
.q-chip { position: absolute; left: 0; top: 0; display: block; background: var(--chip-1); clip-path: polygon(10% 0, 100% 20%, 80% 100%, 0 70%); }
.q-chip--2 { background: var(--chip-2); }
.q-dig { display: inline-block; }

/* ------------------------------------------------------------------ reduced motion (R8 §2.14, R10 §5.4): ONE global block.
   html.no-motion is set by core (Q.motion.sync) when the system asks for reduced motion OR Settings → This device →
   Reduce motion is on, so every rule below keys on that one class. Every translate / scale stops; opacity and colour
   fades stay; count-ups land on their final value; stamps appear landed; no blast, pulse or loader loop. Module
   sheets add overrides only for their own keyframes (and should key on html.no-motion too). */
@media (prefers-reduced-motion: reduce) { :root { --motion: 0; } }
html.no-motion { --motion: 0; }
html.no-motion *, html.no-motion *::before, html.no-motion *::after { transition-property: opacity, color, background-color, border-color, box-shadow, fill, stroke !important; }
html.no-motion :is(.modal, .popover, .toast, .modal-root.is-leaving .modal) { animation-name: q-fade !important; }
html.no-motion :is(.modal-root.is-leaving .modal, .toast.is-leaving) { animation-name: q-fade-out !important; animation-duration: 120ms !important; }
html.no-motion :is(.btn:active:not(:disabled), .icon-btn:active, .fpill:active, .tabbar__new:active .tabbar__plus, .stepper__btn:active:not(:disabled), .stepper__chip:active,
  .paypick__m:active, .rec-sheet__btn:active, button.lrow:active, .lrow__main:active) { transform: none; }
html.no-motion :is(.btn--primary, .btn--danger):active:not(:disabled)::before { transform: translateY(3px); }
html.no-motion :is(.seg__thumb, .seg__btn, .inotice__btn .ic, .tabs__ind) { transition: none; }   /* the segment label swaps colour at once too */
html.no-motion .abar__btn.is-done .ic { animation-name: q-fade; }
html.no-motion .pstage { animation-name: q-fade; }
html.no-motion .progress > span { transition: none; }
html.no-motion.is-recording .tabbar__plus .ic { transition: none; }
html.no-motion :is(.empty.is-enter .empty__art, .empty.is-enter > *, .empty.is-enter .mv-settle, .empty.is-enter .mv-turn, .empty.is-enter .mv-stamp) { animation: q-fade 120ms linear both; }
html.no-motion :is(.qload__b, .skel__b) { animation: none; }
html.no-motion .q-blast { display: none; }
html.no-motion .nav__glide { display: none; }
