/* ============================================================
   BackSight — fieldwork design system
   Field-service management demo app. No external assets.

   Architecture (cascade layers, first declaration wins on order):
     reset → tokens → base → components → utilities
   Unlayered at the end: reduced-motion kill-switch, print styles.

   Theming: the semantic palette flips via the system preference
   (@media prefers-color-scheme) unless the user forces a theme,
   which lands on <html data-theme="light|dark">. The dark token
   block intentionally appears twice (media query + explicit
   override) because plain CSS cannot share a declaration block
   between an at-rule and an attribute selector.
   ============================================================ */
@layer reset, tokens, base, components, utilities;

/* ------------------------------------------------------------
   Reset
   ------------------------------------------------------------ */
@layer reset {
  *, ::before, ::after { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; }
  :where(button, input, select, textarea) { font: inherit; }
}

/* ------------------------------------------------------------
   Tokens
   ------------------------------------------------------------ */
@layer tokens {
  :root {
    color-scheme: light;

    /* -- light palette primitives: the single source for light,
       on-screen print-preview and @media print colours --------- */
    --o-surface: #f3f4f5;
    --o-raised: #ffffff;
    --o-sunken: #f5f6f7;
    --o-tint: #fff3ea;
    --o-field: #ffffff;
    --o-text: #182027;
    --o-text-2: #39454f;
    --o-muted: #586570;
    --o-border: #dde2e5;
    --o-border-strong: #c7cfd5;
    --o-input-border: #77848f;
    --o-brand: #a84212;
    --o-brand-strong: #87320d;
    --o-brand-soft: #fbe6d8;
    --o-focus-ring: #a84212;
    --o-success: #15803d;
    --o-success-strong: #15803d;
    --o-warning: #d97706;
    --o-warning-strong: #b45309;
    --o-danger: #dc2626;
    --o-danger-strong: #b91c1c;
    --o-info: #0284c7;
    --o-info-strong: #0369a1;
    --o-violet: #7c3aed;
    --o-status-neutral: #475569;       --o-status-neutral-bg: #e2e8f0;
    --o-status-brand: #1d4ed8;         --o-status-brand-bg: #dbeafe;
    --o-status-success: #15803d;       --o-status-success-bg: #dcfce7;
    --o-status-warning: #b45309;       --o-status-warning-bg: #fef3c7;
    --o-status-danger: #b91c1c;        --o-status-danger-bg: #fee2e2;
    --o-status-violet: #6d28d9;        --o-status-violet-bg: #ede9fe;
    --o-status-info: #0369a1;          --o-status-info-bg: #e0f2fe;
    --o-status-gold: #a16207;          --o-status-gold-bg: #fef9c3;    --o-status-gold-border: #fde68a;
    --o-status-slate: #334155;         --o-status-slate-bg: #e2e8f0;   --o-status-slate-border: #cbd5e1;
    --o-overlay: rgb(15 23 42 / 50%);
    --o-shadow-1: 0 2px 5px rgb(15 23 42 / .025);
    --o-shadow-2: 0 8px 28px rgb(15 23 42 / .14);
    --o-shadow-3: 0 24px 60px rgb(2 6 23 / .35);
    --o-shadow-drawer: 10px 0 40px rgb(2 6 23 / .35);
    --o-sidebar-bg: #141a1f;
    --o-sidebar-hover: #252d34;
    --o-sidebar-line: #2c343b;
    --o-on-success-fill: #ffffff;

    /* -- semantic tokens (theme-dependent) -------------------- */
    --surface: var(--o-surface);
    --surface-raised: var(--o-raised);
    --surface-sunken: var(--o-sunken);
    --surface-tint: var(--o-tint);
    --field-bg: var(--o-field);
    --text: var(--o-text);
    --text-secondary: var(--o-text-2);
    --text-muted: var(--o-muted);
    --border: var(--o-border);
    --border-strong: var(--o-border-strong);
    --border-input: var(--o-input-border);
    --brand: var(--o-brand);
    --brand-strong: var(--o-brand-strong);
    --brand-soft: var(--o-brand-soft);
    --focus-ring: var(--o-focus-ring);
    --success: var(--o-success);
    --success-strong: var(--o-success-strong);
    --warning: var(--o-warning);
    --warning-strong: var(--o-warning-strong);
    --danger: var(--o-danger);
    --danger-strong: var(--o-danger-strong);
    --info: var(--o-info);
    --info-strong: var(--o-info-strong);
    --violet: var(--o-violet);
    --overlay: var(--o-overlay);
    --shadow-1: var(--o-shadow-1);
    --shadow-2: var(--o-shadow-2);
    --shadow-3: var(--o-shadow-3);
    --shadow-drawer: var(--o-shadow-drawer);
    --sidebar-bg: var(--o-sidebar-bg);
    --sidebar-hover: var(--o-sidebar-hover);
    --sidebar-line: var(--o-sidebar-line);

    /* Job-status colours (badge fg / tinted bg), one pair
       per documented status + the enquiry/quote/priority hues */
    --status-neutral: var(--o-status-neutral);        --status-neutral-bg: var(--o-status-neutral-bg);
    --status-brand: var(--o-status-brand);           --status-brand-bg: var(--o-status-brand-bg);
    --status-success: var(--o-status-success);       --status-success-bg: var(--o-status-success-bg);
    --status-warning: var(--o-status-warning);      --status-warning-bg: var(--o-status-warning-bg);
    --status-danger: var(--o-status-danger);        --status-danger-bg: var(--o-status-danger-bg);
    --status-violet: var(--o-status-violet);        --status-violet-bg: var(--o-status-violet-bg);
    --status-info: var(--o-status-info);           --status-info-bg: var(--o-status-info-bg);
    --status-gold: var(--o-status-gold);           --status-gold-bg: var(--o-status-gold-bg);
    --status-gold-border: var(--o-status-gold-border);
    --status-slate: var(--o-status-slate);          --status-slate-bg: var(--o-status-slate-bg);
    --status-slate-border: var(--o-status-slate-border);

    /* theme-static tokens (identical in both themes) */
    --brand-solid: #ae4615;
    --brand-solid-hover: #90370e;
    --brand-accent: #f18446;
    --on-solid: #ffffff;
    --success-solid: #15803d;
    --danger-solid: #b91c1c;
    --danger-solid-hover: #991b1b;
    --inverse: #0f172a;
    --on-inverse: #f8fafc;
    /* ink on success-filled buttons: modules outside the CSS
       scope paint those fills with var(--green), which resolves
       to a light green in dark mode and needs dark ink */
    --on-success-fill: #ffffff;
    --sidebar-ink: #c6cdd2;
    --sidebar-muted: #929fa9;

    /* -- type scale -------------------------------------------- */
    --font-sans: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
    --font-display: "Bahnschrift", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
    --font-mono: "Cascadia Code", "SFMono-Regular", Consolas, monospace;
    --fs-root: 16px;
    --fs-2xs: .75rem;
    --fs-xs: .8125rem;
    --fs-sm: .875rem;
    --fs-md: .875rem;
    --fs-base: 1rem;
    --fs-lg: 1rem;
    --fs-xl: 1.125rem;
    --fs-2xl: clamp(1.375rem, 1vw + 1rem, 1.75rem);
    --fs-3xl: clamp(1.75rem, 1.5vw + 1rem, 2.25rem);
    /* unitless so it scales with the step and inherits; `normal` is
       font-dependent (~1.16–1.36 across the stack) and would make the
       app's vertical rhythm change with the host OS */
    --leading-body: 1.5;

    /* -- 8pt spacing scale (4/12/20 are half steps) ------------- */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    --space-9: 48px;
    --space-content: clamp(16px, 2vw, 28px);
    --space-icon: 34px;

    /* -- radii -------------------------------------------------- */
    --radius-sm: 5px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-pill: 999px;

    /* -- border widths ------------------------------------------ */
    --bw: 1px;
    --bw-thick: 2px;
    --bw-accent: 3px;

    /* -- motion: one shared duration/easing pair, applied to
       state changes only (hover / focus / open / close) -------- */
    --dur: 160ms;
    --dur-slow: 240ms;
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --transition:
      color var(--dur) var(--ease),
      background-color var(--dur) var(--ease),
      border-color var(--dur) var(--ease),
      box-shadow var(--dur) var(--ease),
      opacity var(--dur) var(--ease);

    /* -- z scale ------------------------------------------------ */
    --z-sticky: 40;
    --z-pop: 60;
    --z-backdrop: 90;
    --z-drawer: 95;
    --z-modal: 100;
    --z-toast: 200;
    --z-skip: 300;

    /* -- layout widths ------------------------------------------ */
    --w-content: 1280px;
    --w-sidebar: 232px;
    --w-search: 340px;
    --w-search-min: 220px;
    --w-when: 92px;
    --w-linetotal: 90px;
    --w-menu: 200px;
    --w-login: 420px;
    --w-modal: 560px;
    --w-modal-wide: 760px;
    --w-sched-side: 280px;
    --w-sched-user-col: 180px;
    --w-sched-min: 900px;
    --w-roster-col: 48px;
    --w-wb-col: 240px;
    --w-gantt-label: 180px;
    --w-gantt-day: 30px;
    --w-totals: 320px;
    --w-print: 820px;
    --w-avatar: 30px;
    --w-avatar-lg: 44px;
    --size-mark: 38px;
    --size-mark-sm: 34px;
    --size-empty-icon: 34px;

    /* -- component dimensions ------------------------------------ */
    --max-pop: 380px;
    --h-sched-cell: 64px;
    /* callers paint their bars 8px tall; the token must match so bars
       without a caller override (job list) share the same weight */
    --h-bar: 8px;
    --h-textarea: 74px;
    --skip-offset: -60px;
    --size-ic-sm: 15px;
    --size-ic: 17px;
    --size-ic-lg: 20px;
    --size-icon-btn: 36px;
    --size-touch: 40px;
    --size-touch-lg: 42px;
    --col-min-k4: 220px;
    --col-min-k3: 260px;
    --col-min-k2: 320px;

    /* login splash gradient (brand chrome, identical in themes) */
    --grad-from: #0f172a;
    --grad-mid: #1e3a8a;
    --grad-to: #2563eb;

    /* legacy aliases — read via getComputedStyle by reports.js
       canvas code and referenced from inline styles in modules
       outside this round's scope; keep names, values now live */
    --primary: var(--brand);
    --primary-dark: var(--brand-strong);
    --primary-soft: var(--brand-soft);
    --ink: var(--text);
    --ink-2: var(--text-secondary);
    --muted: var(--text-muted);
    --line: var(--border);
    --bg: var(--surface);
    --card: var(--surface-raised);
    --green: var(--success);
    --red: var(--danger);
    --amber: var(--warning);
  }

  /* -- dark palette: applied by system preference, unless the
     user forces light ------------------------------------------- */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      color-scheme: dark;
      --surface: #101418;
      --surface-raised: #191f25;
      --surface-sunken: #20272e;
      --surface-tint: #30231d;
      --field-bg: #141a20;
      --text: #eef1f3;
      --text-secondary: #c0c9d0;
      --text-muted: #a0aeb9;
      --border: #343e47;
      --border-strong: #485762;
      --border-input: #71828e;
      --brand: #f6a474;
      --brand-strong: #ffbe96;
      --brand-soft: #4b2d1e;
      --focus-ring: #f6a474;
      --success: #4ade80;
      --success-strong: #4ade80;
      --warning: #f59e0b;
      --warning-strong: #fcd34d;
      --danger: #f87171;
      --danger-strong: #fca5a5;
      --info: #38bdf8;
      --info-strong: #7dd3fc;
      --violet: #a78bfa;
      --overlay: rgb(2 6 23 / 70%);
      --shadow-1: 0 1px 3px rgb(0 0 0 / 40%), 0 4px 14px rgb(0 0 0 / 30%);
      --shadow-2: 0 8px 28px rgb(0 0 0 / 55%);
      --shadow-3: 0 24px 60px rgb(0 0 0 / 65%);
      --shadow-drawer: 10px 0 40px rgb(0 0 0 / 60%);
      --sidebar-bg: #070d19;
      --sidebar-hover: #142036;
      --sidebar-line: #142036;
      --inverse: #e9eef7;
      --on-inverse: #0b1220;
      --on-success-fill: #052e16;
      --status-neutral: #cbd5e1;        --status-neutral-bg: #26334a;
      --status-brand: #93c5fd;         --status-brand-bg: #1c2f55;
      --status-success: #6ee7b7;       --status-success-bg: #113b2b;
      --status-warning: #fbbf24;      --status-warning-bg: #3a2b0c;
      --status-danger: #fca5a5;        --status-danger-bg: #43191c;
      --status-violet: #c4b5fd;        --status-violet-bg: #2e2354;
      --status-info: #7dd3fc;         --status-info-bg: #0c2c44;
      --status-gold: #fde047;         --status-gold-bg: #3a3010;
      --status-gold-border: #6b5a14;
      --status-slate: #cbd5e1;         --status-slate-bg: #1e293b;
      --status-slate-border: #475569;
    }
  }

  /* -- dark palette: explicit user override (duplicate of the
     media-query block above; pure CSS cannot share declarations
     between an at-rule and an attribute selector) -------------- */
  :root[data-theme="dark"] {
    color-scheme: dark;
    --surface: #101418;
    --surface-raised: #191f25;
    --surface-sunken: #20272e;
    --surface-tint: #30231d;
    --field-bg: #141a20;
    --text: #eef1f3;
    --text-secondary: #c0c9d0;
    --text-muted: #a0aeb9;
    --border: #343e47;
    --border-strong: #485762;
    --border-input: #71828e;
    --brand: #f6a474;
    --brand-strong: #ffbe96;
    --brand-soft: #4b2d1e;
    --focus-ring: #f6a474;
    --success: #4ade80;
    --success-strong: #4ade80;
    --warning: #f59e0b;
    --warning-strong: #fcd34d;
    --danger: #f87171;
    --danger-strong: #fca5a5;
    --info: #38bdf8;
    --info-strong: #7dd3fc;
    --violet: #a78bfa;
    --overlay: rgb(2 6 23 / 70%);
    --shadow-1: 0 1px 3px rgb(0 0 0 / 40%), 0 4px 14px rgb(0 0 0 / 30%);
    --shadow-2: 0 8px 28px rgb(0 0 0 / 55%);
    --shadow-3: 0 24px 60px rgb(0 0 0 / 65%);
    --shadow-drawer: 10px 0 40px rgb(0 0 0 / 60%);
    --sidebar-bg: #070d19;
    --sidebar-hover: #142036;
    --sidebar-line: #142036;
    --inverse: #e9eef7;
    --on-inverse: #0b1220;
    --on-success-fill: #052e16;
    --status-neutral: #cbd5e1;        --status-neutral-bg: #26334a;
    --status-brand: #93c5fd;         --status-brand-bg: #1c2f55;
    --status-success: #6ee7b7;       --status-success-bg: #113b2b;
    --status-warning: #fbbf24;      --status-warning-bg: #3a2b0c;
    --status-danger: #fca5a5;        --status-danger-bg: #43191c;
    --status-violet: #c4b5fd;        --status-violet-bg: #2e2354;
    --status-info: #7dd3fc;         --status-info-bg: #0c2c44;
    --status-gold: #fde047;         --status-gold-bg: #3a3010;
    --status-gold-border: #6b5a14;
    --status-slate: #cbd5e1;         --status-slate-bg: #1e293b;
    --status-slate-border: #475569;
  }

  /* printing always uses the light palette, whatever the screen
     theme is (specificity ties with the dark blocks and wins by
     source order) ------------------------------------------------ */
  @media print {
    :root:not([data-theme="light"]) {
      color-scheme: light;
      --surface: var(--o-surface);
      --surface-raised: var(--o-raised);
      --surface-sunken: var(--o-sunken);
      --surface-tint: var(--o-tint);
      --field-bg: var(--o-field);
      --text: var(--o-text);
      --text-secondary: var(--o-text-2);
      --text-muted: var(--o-muted);
      --border: var(--o-border);
      --border-strong: var(--o-border-strong);
      --border-input: var(--o-input-border);
      --brand: var(--o-brand);
      --brand-strong: var(--o-brand-strong);
      --brand-soft: var(--o-brand-soft);
      --focus-ring: var(--o-focus-ring);
      --success: var(--o-success);
      --success-strong: var(--o-success-strong);
      --warning: var(--o-warning);
      --warning-strong: var(--o-warning-strong);
      --danger: var(--o-danger);
      --danger-strong: var(--o-danger-strong);
      --info: var(--o-info);
      --info-strong: var(--o-info-strong);
      --violet: var(--o-violet);
      --overlay: var(--o-overlay);
      --shadow-1: var(--o-shadow-1);
      --shadow-2: var(--o-shadow-2);
      --shadow-3: var(--o-shadow-3);
      --shadow-drawer: var(--o-shadow-drawer);
      --sidebar-bg: var(--o-sidebar-bg);
      --sidebar-hover: var(--o-sidebar-hover);
      --sidebar-line: var(--o-sidebar-line);
      --inverse: var(--o-text);
      --on-inverse: var(--o-raised);
      --on-success-fill: var(--o-on-success-fill);
      --status-neutral: var(--o-status-neutral);        --status-neutral-bg: var(--o-status-neutral-bg);
      --status-brand: var(--o-status-brand);           --status-brand-bg: var(--o-status-brand-bg);
      --status-success: var(--o-status-success);       --status-success-bg: var(--o-status-success-bg);
      --status-warning: var(--o-status-warning);       --status-warning-bg: var(--o-status-warning-bg);
      --status-danger: var(--o-status-danger);        --status-danger-bg: var(--o-status-danger-bg);
      --status-violet: var(--o-status-violet);        --status-violet-bg: var(--o-status-violet-bg);
      --status-info: var(--o-status-info);           --status-info-bg: var(--o-status-info-bg);
      --status-gold: var(--o-status-gold);            --status-gold-bg: var(--o-status-gold-bg);
      --status-gold-border: var(--o-status-gold-border);
      --status-slate: var(--o-status-slate);          --status-slate-bg: var(--o-status-slate-bg);
      --status-slate-border: var(--o-status-slate-border);
    }
  }
}

/* ------------------------------------------------------------
   Base
   ------------------------------------------------------------ */
@layer base {
  html {
    font-size: var(--fs-root);
    scrollbar-gutter: stable;
  }
  body {
    font-family: var(--font-sans);
    background: var(--surface);
    color: var(--text);
    line-height: var(--leading-body);
    -webkit-font-smoothing: antialiased;
  }
  a { color: var(--brand); text-decoration: none; }
  a:hover { text-decoration: underline; }
  /* links inside muted text need a non-colour distinction (brand vs muted is ~1.2:1) */
  .muted a { text-decoration: underline; text-underline-offset: 2px; }
  ::selection { background: var(--brand-soft); color: var(--text); }
  :where(input, select, textarea) {
    accent-color: var(--brand);
    caret-color: var(--brand);
  }
  :where(input[type="checkbox"], input[type="radio"], input[type="range"]) {
    accent-color: var(--brand);
  }
  /* icon spans wrap inline SVGs: they size from font-size, so the
     optional per-call font-size style on .ic scales the glyph */
  :where(.ic) svg { inline-size: 1em; block-size: 1em; }
  :focus-visible {
    outline: var(--bw-thick) solid var(--focus-ring);
    outline-offset: var(--bw-thick);
  }
  :where(#main-content, .modal):focus { outline: none; }
}

/* ------------------------------------------------------------
   Components
   ------------------------------------------------------------ */
@layer components {

  /* ---------- Login ---------- */
  .login-wrap {
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, var(--grad-from) 0%, var(--grad-mid) 60%, var(--grad-to) 100%);
    padding: var(--space-6);
  }
  .login-card {
    background: var(--surface-raised);
    color: var(--text);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-3);
    width: var(--w-login);
    max-width: 100%;
    padding: var(--space-7) var(--space-7) var(--space-6);
  }
  .login-logo { display: flex; align-items: center; gap: var(--space-2); margin-block-end: var(--space-1); }
  .login-logo .mark {
    inline-size: var(--size-mark); block-size: var(--size-mark); border-radius: var(--radius-sm);
    background: var(--brand-solid); color: var(--on-solid); font-weight: 800;
    display: flex; align-items: center; justify-content: center; font-size: var(--fs-3xl);
  }
  .login-logo .name { font-weight: 800; font-size: var(--fs-2xl); letter-spacing: .04em; }
  .login-sub { color: var(--text-muted); font-size: var(--fs-sm); margin-block-end: var(--space-5); }
  .login-kicker {
    font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .12em;
    color: var(--brand); font-weight: 700;
  }
  .login-title { font-size: var(--fs-3xl); font-weight: 800; margin: var(--space-1) 0 var(--space-1); }
  .login-lede { color: var(--text-muted); font-size: var(--fs-base); margin: 0 0 var(--space-5); }
  .sso-row { display: flex; gap: var(--space-2); margin-block-end: var(--space-3); }
  .sso-row .btn { flex: 1; }
  .divider {
    display: flex; align-items: center; gap: var(--space-2);
    color: var(--text-muted); font-size: var(--fs-2xs); margin-block: var(--space-3);
  }
  .divider::before, .divider::after { content: ""; flex: 1; block-size: var(--bw); background: var(--border); }
  .login-error {
    background: var(--status-danger-bg); color: var(--status-danger); border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3); font-size: var(--fs-sm); margin-block-end: var(--space-3); display: none;
  }
  .login-hint {
    margin-block-start: var(--space-4); font-size: var(--fs-sm); color: var(--text-muted);
    background: var(--surface); border: var(--bw) dashed var(--border); border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3);
  }
  .login-foot { margin-block-start: var(--space-4); font-size: var(--fs-sm); color: var(--text-muted); text-align: center; }

  /* ---------- App shell ---------- */
  .shell { display: flex; min-height: 100vh; }
  .sidebar {
    inline-size: var(--w-sidebar); flex-shrink: 0;
    background: var(--sidebar-bg); color: var(--sidebar-ink);
    display: flex; flex-direction: column;
    position: sticky; inset-block-start: 0; block-size: 100vh;
    border-inline-end: var(--bw) solid var(--sidebar-line);
  }
  .sidebar .brand { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-4) var(--space-4) var(--space-3); color: var(--on-solid); }
  .sidebar .brand .mark {
    inline-size: var(--size-mark-sm); block-size: var(--size-mark-sm); border-radius: var(--radius-sm); background: var(--brand-solid);
    display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: var(--fs-xl);
  }
  .sidebar .brand .name { font-weight: 800; font-size: var(--fs-lg); line-height: 1.05; }
  .sidebar .brand .tag { font-size: var(--fs-2xs); letter-spacing: .14em; color: var(--sidebar-muted); text-transform: uppercase; }
  .nav { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: var(--space-1) var(--space-2) var(--space-2); }
  /* .nav-label is also reused on cards (dashboard task list), so the
     sidebar tint is scoped; the base colour must pass AA on --surface-raised */
  .nav-label {
    font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .14em;
    color: var(--text-muted); margin: var(--space-3) var(--space-2) var(--space-1);
  }
  .sidebar .nav-label { color: var(--sidebar-muted); }
  .nav a {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-2); border-radius: var(--radius-sm);
    color: var(--sidebar-ink); font-size: var(--fs-base); margin-block-end: var(--bw);
    transition: var(--transition);
    & svg { inline-size: var(--size-ic); block-size: var(--size-ic); flex-shrink: 0; opacity: .85; }
    &:hover { background: var(--sidebar-hover); color: var(--on-solid); text-decoration: none; }
    &:hover svg { opacity: 1; }
    &.active { background: var(--brand-solid); color: var(--on-solid); font-weight: 600; }
  }
  .sidebar .foot {
    padding: var(--space-3) var(--space-4); font-size: var(--fs-2xs);
    color: var(--sidebar-muted); border-block-start: var(--bw) solid var(--sidebar-line);
  }

  .main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
  .topbar {
    background: var(--surface-raised);
    border-block-end: var(--bw) solid var(--border);
    display: flex; align-items: center; gap: var(--space-3);
    /* gutters track the centred content column (.content is capped at
       --w-content and padded --space-content) so the topbar title and
       the page H1 beneath it share an edge at every viewport width;
       below the cap the fluid --space-content wins */
    padding: var(--space-3) max(var(--space-content), calc((100% - var(--w-content)) / 2 + var(--space-content)));
    position: sticky; inset-block-start: 0; z-index: var(--z-sticky);
  }
  /* titles are user data (e.g. "Client — <long name>") and must truncate
     instead of squeezing the search out of the bar */
  .topbar .title {
    font-size: var(--fs-xl); font-weight: 800; margin-inline-end: auto; white-space: nowrap;
    min-inline-size: 0; overflow: hidden; text-overflow: ellipsis;
  }
  .global-search {
    position: relative; flex-shrink: 0;
    inline-size: clamp(var(--w-search-min), 26vw, var(--w-search));
  }
  .global-search input { inline-size: 100%; padding-inline-start: var(--space-icon); }
  .global-search .mag {
    position: absolute; inset-inline-start: var(--space-2); inset-block-start: 50%;
    transform: translateY(-50%); color: var(--text-muted); pointer-events: none;
  }
  .global-search:has(.gs-results.open) input { border-color: var(--brand); }
  .gs-results {
    position: absolute; inset-block-start: calc(100% + var(--space-1)); inset-inline: 0;
    background: var(--surface-raised);
    border: var(--bw) solid var(--border); border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
    max-block-size: var(--max-pop); overflow-y: auto; overscroll-behavior: contain;
    display: none; z-index: var(--z-pop);
    &.open { display: block; animation: pop-in var(--dur) var(--ease); }
    & .gs-item {
      padding: var(--space-2) var(--space-3); border-block-end: var(--bw) solid var(--surface);
      cursor: pointer; transition: var(--transition);
      &:last-child { border-block-end: none; }
      &:hover { background: var(--surface); }
    }
    & .gs-kind {
      font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted);
    }
    & .gs-name { font-weight: 600; font-size: var(--fs-base); }
    & .gs-meta { font-size: var(--fs-xs); color: var(--text-muted); }
  }
  .gs-empty { padding: var(--space-3); color: var(--text-muted); font-size: var(--fs-sm); text-align: center; }

  .user-menu { position: relative; }
  .user-chip {
    display: flex; align-items: center; gap: var(--space-2); cursor: pointer;
    padding: var(--space-1) var(--space-1); border-radius: var(--radius-sm); transition: var(--transition);
    &:hover { background: var(--surface); }
    & .who { text-align: end; line-height: 1.15; }
    & .who .nm { font-size: var(--fs-sm); font-weight: 700; }
    & .who .rl { font-size: var(--fs-2xs); color: var(--text-muted); }
  }
  .dropdown {
    position: absolute; inset-inline-end: 0; inset-block-start: calc(100% + var(--space-2));
    background: var(--surface-raised); min-inline-size: var(--w-menu);
    border: var(--bw) solid var(--border); border-radius: var(--radius-md);
    box-shadow: var(--shadow-2); padding: var(--space-1); display: none; z-index: var(--z-pop);
    &.open { display: block; animation: pop-in var(--dur) var(--ease); }
    & :is(a, button.dlink) {
      display: flex; align-items: center; gap: var(--space-2); inline-size: 100%; text-align: start;
      padding: var(--space-2) var(--space-2); border-radius: var(--radius-sm);
      color: var(--text-secondary); font-size: var(--fs-base);
      background: none; border: none; cursor: pointer; transition: var(--transition);
      &:hover { background: var(--surface); text-decoration: none; }
    }
    & .sep { block-size: var(--bw); background: var(--border); margin: var(--space-1) var(--space-1); }
  }

  .content {
    padding: var(--space-content);
    max-inline-size: var(--w-content);
    inline-size: 100%; margin-inline: auto;
  }

  /* ---------- Buttons / inputs ---------- */
  .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    background: var(--brand-solid); color: var(--on-solid);
    border: var(--bw) solid var(--brand-solid);
    padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
    font-size: var(--fs-md); font-weight: 600;
    cursor: pointer; line-height: 1.2; white-space: nowrap;
    transition: var(--transition);
    &:hover { background: var(--brand-solid-hover); border-color: var(--brand-solid-hover); }
    &:disabled { opacity: .55; cursor: not-allowed; }
    & svg { inline-size: var(--size-ic-sm); block-size: var(--size-ic-sm); }
    &.secondary {
      background: var(--surface-raised); color: var(--text-secondary); border-color: var(--border);
      &:hover { background: var(--surface); }
    }
    &.danger {
      background: var(--danger-solid); border-color: var(--danger-solid); color: var(--on-solid);
      &:hover { background: var(--danger-solid-hover); border-color: var(--danger-solid-hover); }
    }
    &.ghost {
      background: transparent; border-color: transparent; color: var(--text-secondary);
      &:hover { background: var(--surface); }
    }
    &.sm { padding: var(--space-1) var(--space-3); font-size: var(--fs-sm); border-radius: var(--radius-sm); }
  }
  /* success-filled buttons are painted var(--green) by module
     code outside the stylesheet; their ink must adapt per theme */
  .btn[style*="var(--green)"] { color: var(--on-success-fill); }

  .icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    inline-size: var(--size-icon-btn); block-size: var(--size-icon-btn); padding: 0; flex-shrink: 0;
    background: var(--surface-raised); border: var(--bw) solid var(--border);
    border-radius: var(--radius-sm); color: var(--text-secondary);
    cursor: pointer; transition: var(--transition);
    &:hover { background: var(--surface); }
    & svg { inline-size: var(--size-ic); block-size: var(--size-ic); }
  }

  :is(.input, .select, .textarea) {
    inline-size: 100%; padding: var(--space-2) var(--space-3);
    border: var(--bw) solid var(--border-input); border-radius: var(--radius-sm);
    font-size: var(--fs-base); color: var(--text); background: var(--field-bg);
    caret-color: var(--brand);
    &:focus {
      outline: var(--bw-thick) solid var(--brand-soft); border-color: var(--brand);
    }
    &:focus-visible { outline: var(--bw-thick) solid var(--brand-soft); outline-offset: 0; }
    &::placeholder { color: var(--text-muted); }
    /* the explicit bg/color above beat the UA stylesheet's disabled
       greying, so locked fields need their own affordance — without
       this a disabled input is pixel-identical to an editable one */
    &:is(:disabled, [readonly]) {
      background: var(--surface-sunken); color: var(--text-muted); border-color: var(--border);
    }
    &:disabled { cursor: not-allowed; }
  }
  .textarea { resize: vertical; min-block-size: var(--h-textarea); }
  label.fld { display: block; font-size: var(--fs-sm); font-weight: 600; color: var(--text-secondary); margin-block-end: var(--space-1); }
  .field { margin-block-end: var(--space-3);
    & .err-msg { color: var(--danger-strong); font-size: var(--fs-xs); margin-block-start: var(--space-1); display: none; }
    &.invalid .err-msg { display: block; }
    &.invalid :is(.input, .select, .textarea) { border-color: var(--danger-strong); }
    /* :has() focus feedback: tint the label while its control is focused */
    &:has(:focus-visible) > .fld { color: var(--brand); }
  }
  .form-row { display: flex; gap: var(--space-3);
    & .field { flex: 1; }
  }
  .help { font-size: var(--fs-xs); color: var(--text-muted); margin-block-start: var(--space-1); }
  /* non-blocking warning inside a form (e.g. the Book dialog's
     double-booking notice) — the audited warning badge token pair */
  .warn-note {
    font-size: var(--fs-sm); line-height: 1.5;
    background: var(--status-warning-bg); color: var(--status-warning);
    border-inline-start: var(--bw-accent) solid var(--warning);
    border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
    margin-block-start: var(--space-2);
  }

  /* ---------- Cards / layout ---------- */
  .card {
    background: var(--surface-raised);
    border: var(--bw) solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-1);
    container: card / inline-size;
    & .card-head {
      display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
      padding: var(--space-3) var(--space-4); border-block-end: var(--bw) solid var(--border);
      & h3 { margin: 0; font-size: var(--fs-lg); }
    }
    & .card-body { padding: var(--space-4); }
  }
  /* container queries: dense widgets adapt inside narrow columns */
  @container card (max-width: 420px) {
    .card .card-head { padding: var(--space-3); }
  }
  @container card (max-width: 340px) {
    .kpi .kpi-value { font-size: var(--fs-2xl); }
    .statline { gap: var(--space-4); }
    .statline .stat .v { font-size: var(--fs-md); }
  }

  .page-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3); margin-block-end: var(--space-4); flex-wrap: wrap;
    & h1 { margin: 0; font-size: var(--fs-2xl); font-weight: 800; }
    & .sub { color: var(--text-muted); font-size: var(--fs-md); margin-block-start: var(--space-1); }
  }
  .page-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }

  .grid { display: grid; gap: var(--space-4);
    &.k4 { grid-template-columns: repeat(auto-fit, minmax(var(--col-min-k4), 1fr)); }
    &.k3 { grid-template-columns: repeat(auto-fit, minmax(var(--col-min-k3), 1fr)); }
    &.k2 { grid-template-columns: repeat(auto-fit, minmax(var(--col-min-k2), 1fr)); }
  }

  .kpi { padding: var(--space-4) var(--space-5);
    & .kpi-label { font-size: var(--fs-sm); color: var(--text-muted); font-weight: 600; }
    & .kpi-value { font-size: var(--fs-3xl); font-weight: 800; margin-block-start: var(--space-1); }
    & .kpi-delta { font-size: var(--fs-xs); margin-block-start: var(--space-1); color: var(--text-muted);
      &.up { color: var(--success-strong); }
      &.down { color: var(--danger-strong); }
    }
  }

  /* ---------- Tables ---------- */
  .table-wrap { overflow-x: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  table.tbl { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-md); }
  .tbl th {
    text-align: start; padding: var(--space-2) var(--space-4);
    font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .07em;
    color: var(--text-muted); border-block-end: var(--bw) solid var(--border);
    white-space: nowrap; background: var(--surface-sunken);
  }
  .tbl td { padding: var(--space-3) var(--space-4); border-block-end: var(--bw) solid var(--border); vertical-align: middle; }
  /* long unbroken runs (URLs, pasted 200-char names) must wrap inside their
     container instead of stretching the page wider than the viewport */
  .detail-title h1, .id-line, .page-head .sub, .card-body, .tbl td,
  .notes-list .note, .task-row .tx, .activity li div, .gs-name, .gs-meta,
  .unsched-item .t, .unsched-item .m, .print-doc td, .print-doc p { overflow-wrap: anywhere; }
  .tbl tr:last-child td { border-block-end: none; }
  .tbl tbody tr.rowlink { cursor: pointer; transition: var(--transition); }
  .tbl tbody tr.rowlink:hover { background: var(--surface-sunken); }
  .tbl :is(.num, .actions) { text-align: end; font-variant-numeric: tabular-nums; }
  .tbl .actions { white-space: nowrap; }
  /* timesheets.js paints today's cell inline with a light tint;
     !important re-themes it without touching that module */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .tbl td[style*="f0f7ff"] { background: var(--surface-tint) !important; }
  }
  :root[data-theme="dark"] .tbl td[style*="f0f7ff"] { background: var(--surface-tint) !important; }
  /* one shared empty-state treatment: icon + one-line reason */
  .tbl .empty-row td {
    text-align: center; color: var(--text-muted); padding: var(--space-7) var(--space-3); font-size: var(--fs-md);
    &::before {
      content: "";
      display: block; inline-size: var(--space-6); block-size: var(--space-6);
      margin-inline: auto; margin-block-end: var(--space-2);
      background: currentColor; opacity: .5;
      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5h18v12a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5z'/%3E%3Cpath d='M3 5l6.2 6.2a4 4 0 0 0 5.6 0L21 5'/%3E%3C/svg%3E") center / contain no-repeat;
    }
  }

  /* ---------- Badges / chips / avatars ---------- */
  .badge {
    display: inline-flex; align-items: center; gap: var(--space-1);
    padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill);
    font-size: var(--fs-xs); font-weight: 700; letter-spacing: .02em; white-space: nowrap;
  }
  .badge.gray   { background: var(--status-neutral-bg); color: var(--status-neutral); }
  .badge.blue   { background: var(--status-brand-bg); color: var(--status-brand); }
  .badge.green  { background: var(--status-success-bg); color: var(--status-success); }
  .badge.amber  { background: var(--status-warning-bg); color: var(--status-warning); }
  .badge.red    { background: var(--status-danger-bg); color: var(--status-danger); }
  .badge.purple { background: var(--status-violet-bg); color: var(--status-violet); }
  .badge.sky    { background: var(--status-info-bg); color: var(--status-info); }
  .badge.slate  { background: var(--status-slate-bg); color: var(--status-slate); border: var(--bw) solid var(--status-slate-border); }
  .badge.gold   { background: var(--status-gold-bg); color: var(--status-gold); border: var(--bw) solid var(--status-gold-border); }

  .chips { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
  .chip {
    border: var(--bw) solid var(--border); background: var(--surface-raised);
    color: var(--text-secondary); border-radius: var(--radius-pill);
    padding: var(--space-1) var(--space-3); font-size: var(--fs-sm); font-weight: 600;
    cursor: pointer; transition: var(--transition);
    &:hover { background: var(--surface); }
    &.active { background: var(--brand-solid); border-color: var(--brand-solid); color: var(--on-solid); }
  }

  .avatar {
    inline-size: var(--w-avatar); block-size: var(--w-avatar);
    border-radius: 50%; color: var(--on-solid); font-size: var(--fs-xs); font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    &.lg { inline-size: var(--w-avatar-lg); block-size: var(--w-avatar-lg); font-size: var(--fs-lg); }
  }
  .avatar-stack { display: flex;
    & .avatar { margin-inline-start: calc(-1 * var(--space-2)); border: var(--bw-thick) solid var(--surface-raised); }
    & .avatar:first-child { margin-inline-start: 0; }
  }

  /* ---------- Toolbar / filters ---------- */
  .toolbar { display: flex; gap: var(--space-3); align-items: center; margin-block-end: var(--space-3); flex-wrap: wrap; }
  #ts-week-metrics { margin-inline-start: auto; flex-wrap: wrap; min-inline-size: 0; max-inline-size: 100%; }
  #ts-week-metrics .badge { white-space: normal; }
  .toolbar .search { position: relative; flex: 1; min-inline-size: var(--w-search-min); max-inline-size: var(--max-pop);
    & input { padding-inline-start: var(--space-icon); }
    & .mag {
      position: absolute; inset-inline-start: var(--space-2); inset-block-start: 50%;
      transform: translateY(-50%); color: var(--text-muted); pointer-events: none;
    }
  }
  .toolbar .count { color: var(--text-muted); font-size: var(--fs-sm); margin-inline-start: auto; white-space: nowrap; }

  /* ---------- Tabs ---------- */
  .tabs {
    display: flex; gap: var(--space-1); border-block-end: var(--bw) solid var(--border);
    margin-block-end: var(--space-4); overflow-x: auto; overscroll-behavior: contain;
    & button {
      background: none; border: none; padding: var(--space-2) var(--space-4);
      font-size: var(--fs-base); font-weight: 600; color: var(--text-muted);
      cursor: pointer; border-block-end: var(--bw-accent) solid transparent; transition: var(--transition);
      &:hover { color: var(--text); }
      &.active { color: var(--brand); border-block-end-color: var(--brand); }
    }
  }

  /* ---------- Modal ---------- */
  .modal-overlay {
    position: fixed; inset: 0; background: var(--overlay); z-index: var(--z-modal);
    display: flex; align-items: flex-start; justify-content: center;
    padding: var(--space-9) var(--space-4); overflow-y: auto; overscroll-behavior: contain;
  }
  .modal {
    background: var(--surface-raised); border: var(--bw) solid var(--border);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
    inline-size: var(--w-modal); max-inline-size: 100%;
    min-inline-size: 0; display: flex; flex-direction: column;
    max-block-size: calc(100dvh - var(--space-9) - var(--space-9));
    &.wide { inline-size: var(--w-modal-wide); }
  }
  .modal-head {
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-4) var(--space-5); border-block-end: var(--bw) solid var(--border);
    & h3 { margin: 0; font-size: var(--fs-lg); }
  }
  .modal-body { padding: var(--space-5); min-block-size: 0; overflow-y: auto; }
  .modal-foot {
    flex-shrink: 0;
    display: flex; justify-content: flex-end; gap: var(--space-2);
    padding: var(--space-3) var(--space-5); border-block-start: var(--bw) solid var(--border);
  }
  .x-btn {
    background: none; border: none; font-size: var(--fs-2xl); color: var(--text-muted);
    cursor: pointer; line-height: 1; padding: var(--space-1); transition: var(--transition);
    &:hover { color: var(--text); }
  }

  /* ---------- Toast ---------- */
  #toast-root {
    position: fixed;
    inset-block-end: var(--space-6); inset-inline-end: var(--space-6);
    z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--space-2);
  }
  .toast {
    background: var(--inverse); color: var(--on-inverse); border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-5); font-size: var(--fs-md);
    box-shadow: var(--shadow-2); display: flex; align-items: center; gap: var(--space-2);
    max-inline-size: var(--max-pop);
    animation: toast-in var(--dur-slow) var(--ease);
    &.success { background: var(--success-solid); color: var(--on-solid); }
    &.error { background: var(--danger-solid); color: var(--on-solid); }
  }
  /* Undo affordance appended to a toast (e.g. job deletion) — inherits the
     toast's own ink/fill pair, so it clears contrast in every theme */
  .toast-undo {
    margin-inline-start: var(--space-2); flex-shrink: 0;
    background: transparent; color: inherit; border: var(--bw) solid currentColor;
    border-radius: var(--radius-sm); padding: 2px var(--space-2);
    font: inherit; font-size: var(--fs-xs); font-weight: 700; cursor: pointer;
    &:hover { text-decoration: underline; }
  }
  /* entrance slides without opacity, mirroring the transform-based exit:
     a translucent toast composites against the page behind it, and a sample
     taken mid-entrance blends fg/bg below the AA threshold */
  @keyframes toast-in {
    from { transform: translateY(var(--space-2)); }
    to { transform: none; }
  }
  @keyframes pop-in {
    from { opacity: 0; transform: translateY(calc(-1 * var(--space-1))); }
    to { opacity: 1; transform: none; }
  }

  /* ---------- Scheduler ---------- */
  .sched-layout { display: flex; gap: var(--space-4); align-items: flex-start; }
  .sched-side { inline-size: var(--w-sched-side); flex-shrink: 0; }
  .sched-grid-wrap { flex: 1; min-inline-size: 0; overflow-x: auto; overscroll-behavior: contain; }
  .sched-grid {
    display: grid;
    grid-template-columns: var(--w-sched-user-col) repeat(7, 1fr);
    font-size: var(--fs-sm); min-inline-size: var(--w-sched-min);
  }
  .sched-cell {
    border-inline-start: var(--bw) solid var(--border);
    border-block-start: var(--bw) solid var(--border);
    padding: var(--space-1); min-block-size: var(--h-sched-cell); background: var(--surface-raised);
    &.droppable-hover { background: var(--brand-soft); }
    &.today { background: var(--surface-tint); }
  }
  .sched-head-row {
    display: grid; background: var(--surface-sunken);
    border-inline-start: var(--bw) solid var(--border);
  }
  .sched-head {
    background: var(--surface-sunken); font-weight: 700; font-size: var(--fs-sm);
    padding: var(--space-2) var(--space-2);
    border-inline-start: var(--bw) solid var(--border); border-block-start: var(--bw) solid var(--border);
    color: var(--text-secondary);
    & .dow { text-transform: uppercase; letter-spacing: .06em; font-size: var(--fs-2xs); color: var(--text-muted); }
    &.today { background: var(--brand-soft); color: var(--brand-strong); }
  }
  .sched-user {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    padding: var(--space-2); background: var(--surface-sunken);
    border-block-start: var(--bw) solid var(--border);
    font-weight: 600; font-size: var(--fs-md);
  }
  .job-chip {
    background: var(--st-bg, var(--status-brand-bg)); color: var(--st-fg, var(--status-brand));
    border-inline-start: var(--bw-accent) solid var(--st-line, var(--brand));
    border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2);
    font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
    margin-block-end: var(--space-1); overflow: hidden; text-overflow: ellipsis;
    transition: var(--transition);
    /* draggable scheduler objects share one hover language — a brand
       edge, same as .wb-card / .unsched-item. brightness() would be a
       light-mode-only cue: darkening a dark-mode tint is invisible */
    &:hover { outline: var(--bw) solid var(--brand); outline-offset: calc(-1 * var(--bw)); }
    &.dragging { opacity: .45; }
  }
  .unsched-item {
    background: var(--surface-raised); border: var(--bw) solid var(--border);
    border-inline-start: var(--bw-accent) solid var(--warning);
    border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
    margin-block-end: var(--space-2); cursor: grab; font-size: var(--fs-sm);
    transition: var(--transition);
    &:hover { border-color: var(--brand); }
    & .unsched-link { cursor: pointer; }
    & .btn { margin-block-start: var(--space-2); }
    & .t { font-weight: 700; font-size: var(--fs-md); }
    & .m { color: var(--text-muted); font-size: var(--fs-xs); margin-block-start: var(--space-1); }
  }

  /* status tints shared by the Roster bars, Gantt bars, Whiteboard columns
     and Map clusters — one pair per documented job status, sourced from
     the audited badge token pairs */
  .st-unscheduled    { --st-bg: var(--status-warning-bg); --st-fg: var(--status-warning); --st-line: var(--warning); }
  .st-booked         { --st-bg: var(--status-success-bg); --st-fg: var(--status-success); --st-line: var(--success); }
  .st-inprogress     { --st-bg: var(--status-brand-bg);   --st-fg: var(--status-brand);   --st-line: var(--brand); }
  .st-deferred       { --st-bg: var(--status-violet-bg);  --st-fg: var(--status-violet);  --st-line: var(--violet); }
  .st-cancelled      { --st-bg: var(--status-danger-bg);   --st-fg: var(--status-danger);   --st-line: var(--danger); }
  .st-readytoinvoice { --st-bg: var(--status-gold-bg);    --st-fg: var(--status-gold);    --st-line: var(--status-gold); }
  .st-completed      { --st-bg: var(--status-slate-bg);   --st-fg: var(--status-slate);   --st-line: var(--status-slate); }
  .st-closed         { --st-bg: var(--status-neutral-bg); --st-fg: var(--status-neutral); --st-line: var(--text-muted); }

  /* ---------- Roster (one day: staff × hours) ---------- */
  .roster-wrap { flex: 1; min-inline-size: 0; overflow-x: auto; overscroll-behavior: contain; }
  .roster-grid { display: grid; font-size: var(--fs-sm); }
  .roster-head {
    display: grid; background: var(--surface-sunken);
    border-inline-start: var(--bw) solid var(--border);
    & > div {
      padding: var(--space-2); font-weight: 700; font-size: var(--fs-2xs);
      color: var(--text-muted); text-transform: uppercase; letter-spacing: .05em;
      border-inline-start: var(--bw) solid var(--border); border-block-start: var(--bw) solid var(--border);
      white-space: nowrap;
      &:first-child { border-inline-start: none; }
    }
  }
  .roster-user {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    padding: var(--space-2); background: var(--surface-sunken);
    border-block-start: var(--bw) solid var(--border);
    font-weight: 600; font-size: var(--fs-md);
  }
  .roster-track {
    position: relative; min-block-size: 52px;
    border-inline-start: var(--bw) solid var(--border);
    border-block-start: var(--bw) solid var(--border);
    background: repeating-linear-gradient(
      to right, var(--border) 0, var(--border) var(--bw),
      transparent var(--bw), transparent var(--w-roster-col));
  }
  .roster-bar {
    position: absolute; inset-block: var(--space-2);
    display: flex; align-items: center; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
    background: var(--st-bg); color: var(--st-fg);
    border-inline-start: var(--bw-accent) solid var(--st-line);
    border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2);
    font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
    transition: var(--transition);
    &:hover { outline: var(--bw) solid var(--brand); outline-offset: calc(-1 * var(--bw)); }
    /* a job with no stored start time is sequenced, not booked — dashed
       accent marks it (the bar text also says "no set time") */
    &.no-time { border-inline-start-style: dashed; }
  }

  /* ---------- Whiteboard (status columns) ---------- */
  .wb-board {
    display: flex; gap: var(--space-3); align-items: flex-start;
    overflow-x: auto; overscroll-behavior: contain;
    padding-block-end: var(--space-2);
  }
  .wb-col {
    flex: 0 0 var(--w-wb-col); display: flex; flex-direction: column;
    background: var(--surface-raised);
    border: var(--bw) solid var(--border);
    border-block-start: var(--bw-accent) solid var(--st-line);
    border-radius: var(--radius-sm); min-block-size: 180px;
  }
  .wb-col-head {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--surface-sunken);
    border-block-end: var(--bw) solid var(--border);
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    & h3 { margin: 0; font-size: var(--fs-sm); flex: 1; min-inline-size: 0; overflow-wrap: anywhere; }
  }
  .wb-dot { inline-size: 10px; block-size: 10px; border-radius: 50%; background: var(--st-line); flex-shrink: 0; }
  .wb-count {
    font-size: var(--fs-2xs); font-weight: 700; flex-shrink: 0;
    background: var(--st-bg); color: var(--st-fg);
    border-radius: 999px; padding: 1px var(--space-2);
  }
  .wb-cards {
    display: flex; flex-direction: column; gap: var(--space-2);
    padding: var(--space-2); flex: 1;
    border-radius: 0 0 var(--radius-sm) var(--radius-sm);
    transition: var(--transition);
    &:focus-visible { outline: var(--bw) solid var(--focus-ring); outline-offset: -2px; }
    &.droppable-hover { background: var(--brand-soft); }
  }
  .wb-card {
    background: var(--surface-raised); border: var(--bw) solid var(--border);
    border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
    cursor: grab; transition: var(--transition);
    &:hover { border-color: var(--brand); }
    &.dragging { opacity: .45; }
  }
  .wb-num { font-size: var(--fs-2xs); font-weight: 700; color: var(--st-fg); }
  .wb-title { font-weight: 600; font-size: var(--fs-sm); margin-block: var(--space-1); overflow-wrap: anywhere; }
  .wb-meta { font-size: var(--fs-xs); color: var(--text-muted); }
  .wb-move { margin-block-start: var(--space-2); }
  .wb-empty { padding: var(--space-3) var(--space-2); text-align: center; }

  /* ---------- Gantt (month bars by customer) ---------- */
  .gantt-wrap { overflow-x: auto; overscroll-behavior: contain; }
  .gantt-grid { display: grid; font-size: var(--fs-sm); }
  .gantt-head {
    display: grid; background: var(--surface-sunken);
    border-inline-start: var(--bw) solid var(--border);
    & > div {
      padding: var(--space-2) 4px; font-weight: 700; font-size: var(--fs-2xs);
      color: var(--text-muted); text-align: center; white-space: nowrap;
      border-inline-start: var(--bw) solid var(--border); border-block-start: var(--bw) solid var(--border);
      &:first-child {
        border-inline-start: none; text-align: start; padding-inline: var(--space-2);
        text-transform: uppercase; letter-spacing: .05em;
      }
      &.today { background: var(--brand-soft); color: var(--brand-strong); }
    }
  }
  .gantt-client {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    padding: var(--space-2); background: var(--surface-sunken);
    border-block-start: var(--bw) solid var(--border);
    font-weight: 600; font-size: var(--fs-sm); overflow-wrap: anywhere;
  }
  .gantt-track {
    position: relative;
    border-inline-start: var(--bw) solid var(--border);
    border-block-start: var(--bw) solid var(--border);
    background: repeating-linear-gradient(
      to right, var(--border) 0, var(--border) var(--bw),
      transparent var(--bw), transparent var(--w-gantt-day));
  }
  .gantt-today { position: absolute; inset-block: 0; inline-size: var(--bw); background: var(--brand); }
  .gantt-bar {
    position: absolute; block-size: 24px;
    display: flex; align-items: center; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
    background: var(--st-bg); color: var(--st-fg);
    border-inline-start: var(--bw-accent) solid var(--st-line);
    border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2);
    font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
    transition: var(--transition);
    &:hover { outline: var(--bw) solid var(--brand); outline-offset: calc(-1 * var(--bw)); }
  }

  /* ---------- Map (offline suburb schematic) ---------- */
  .map-layout { display: flex; gap: var(--space-4); align-items: flex-start; }
  .map-canvas { flex: 1; min-inline-size: 0; }
  .map-svg { display: block; max-inline-size: 100%; block-size: auto; }
  .map-cluster { cursor: pointer; transition: var(--transition);
    & circle { fill: var(--st-bg); stroke: var(--st-line); stroke-width: var(--bw-accent); }
    /* thickening the status ring reads in both themes; a brightness
       filter would only read on light tints */
    &:hover circle { stroke-width: 4px; }
    &:focus-visible { outline: none;
      & circle { stroke: var(--focus-ring); stroke-width: 3px; } }
    &.selected circle { stroke: var(--focus-ring); stroke-width: 3px; }
  }
  .map-count { fill: var(--st-fg); font-size: 20px; font-weight: 800; text-anchor: middle; }
  .map-name { fill: var(--text-secondary); font-size: 12px; font-weight: 600; text-anchor: middle; }

  /* ---------- Detail pages ---------- */
  .detail-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--space-4); flex-wrap: wrap; margin-block-end: var(--space-4);
    & .id-line { color: var(--text-muted); font-size: var(--fs-md); margin-block-start: var(--space-1); }
    /* the client link sits inline with this muted line — underline it so
       colour isn't the only distinction (axe link-in-text-block, WCAG 1.4.1) */
    & .id-line a { text-decoration: underline; text-underline-offset: 2px; }
  }
  .detail-title { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
    & h1 { margin: 0; font-size: var(--fs-2xl); }
  }
  .statline { display: flex; gap: var(--space-6); flex-wrap: wrap; margin: 0 0 var(--space-4);
    & .stat .l {
      font-size: var(--fs-xs); color: var(--text-muted); text-transform: uppercase;
      letter-spacing: .07em; font-weight: 600;
    }
    & .stat .v { font-size: var(--fs-lg); font-weight: 700; margin-block-start: var(--bw-thick); }
  }
  /* a stat whose value is a stack of lines (e.g. every invoice on a job) */
  .stat-lines { display: flex; flex-direction: column; gap: var(--space-1); align-items: flex-start;
    & .small { font-weight: 400; }
  }

  .item-row { display: flex; gap: var(--space-2); margin-block-end: var(--space-2); align-items: flex-start;
    & :is(.input, .select) { padding: var(--space-1) var(--space-2); }
  }

  /* ---------- Custom forms: designer rows, fill controls, signatures ---------- */
  .form-field-row {
    display: flex; gap: var(--space-2); align-items: center; flex-wrap: wrap;
    padding: var(--space-2); border: var(--bw) solid var(--border);
    border-radius: var(--radius-sm); margin-block-end: var(--space-2); background: var(--surface);
    & :is(.input, .select) { padding: var(--space-1) var(--space-2); }
  }
  .chk-line {
    display: inline-flex; align-items: center; gap: var(--space-2);
    font-size: var(--fs-sm); font-weight: 600; color: var(--text-secondary); cursor: pointer;
    & input[type="checkbox"] { inline-size: var(--size-ic); block-size: var(--size-ic); accent-color: var(--brand); cursor: pointer; }
  }
  .sig-pad canvas {
    inline-size: 100%; block-size: 130px; display: block;
    border: 2px dashed var(--border); border-radius: var(--radius-sm);
    background: var(--o-raised); touch-action: none; cursor: crosshair;
  }
  .sig-img {
    display: inline-block; max-inline-size: 260px; max-block-size: 76px;
    background: var(--o-raised); border: var(--bw) solid var(--border);
    border-radius: var(--radius-sm); padding: 2px var(--space-2);
  }
  .form-answers .form-answer {
    display: grid; grid-template-columns: minmax(150px, 38%) 1fr; gap: var(--space-3);
    padding: var(--space-2) 0; border-block-end: var(--bw) solid var(--surface);
    &:last-child { border-block-end: none; }
    & .fa-label { font-weight: 600; font-size: var(--fs-sm); color: var(--text-secondary); }
    & .fa-value { font-size: var(--fs-base); overflow-wrap: anywhere; }
  }

  /* ---------- Document templates: merge-field chips + preview ---------- */
  .chip.sm { padding: var(--space-1) var(--space-2); font-size: var(--fs-xs); font-family: ui-monospace, monospace; }
  .tpl-chips {
    border: var(--bw) solid var(--border); border-radius: var(--radius-sm);
    padding: var(--space-3); display: grid; gap: var(--space-3); background: var(--surface);
  }
  .tpl-chip-group { display: grid; gap: var(--space-1); }
  .tpl-preview {
    border: var(--bw) dashed var(--border); border-radius: var(--radius-sm);
    padding: var(--space-3); background: var(--surface); color: var(--text-secondary);
  }
  .line-total { text-align: end; font-variant-numeric: tabular-nums; padding-block-start: var(--space-2); font-size: var(--fs-base); min-inline-size: var(--w-linetotal); }
  .totals-box { margin-inline-start: auto; inline-size: var(--w-totals); font-size: var(--fs-base);
    & .trow { display: flex; justify-content: space-between; padding-block: var(--space-1); }
    & .trow.grand {
      border-block-start: var(--bw-thick) solid var(--text);
      font-weight: 800; font-size: var(--fs-lg);
      padding-block-start: var(--space-2); margin-block-start: var(--space-1);
    }
  }

  .task-row {
    display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-1);
    border-block-end: var(--bw) solid var(--surface);
    &:last-child { border-block-end: none; }
    & input[type="checkbox"] { inline-size: var(--size-ic); block-size: var(--size-ic); accent-color: var(--brand); cursor: pointer; }
    & .tx { flex: 1; font-size: var(--fs-base); }
    &.done .tx { text-decoration: line-through; color: var(--text-muted); }
  }

  .activity { list-style: none; margin: 0; padding: 0;
    & li { display: flex; gap: var(--space-3); padding: var(--space-2) 0; border-block-end: var(--bw) solid var(--surface); font-size: var(--fs-sm);
      &:last-child { border-block-end: none; }
    }
    & .when { color: var(--text-muted); white-space: nowrap; font-size: var(--fs-xs); min-inline-size: var(--w-when); text-align: end; }
  }

  .progressbar { block-size: var(--h-bar); background: var(--surface); border-radius: var(--radius-pill); overflow: hidden;
    & > div { block-size: 100%; background: var(--success); border-radius: var(--radius-pill); }
  }

  .notes-list .note {
    border: var(--bw) solid var(--border); border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-3); margin-block-end: var(--space-2); font-size: var(--fs-md);
    & .meta { color: var(--text-muted); font-size: var(--fs-xs); margin-block-end: var(--space-1); }
  }

  /* ---------- Empty states (block variant) ---------- */
  .empty-state { text-align: center; padding: var(--space-8) var(--space-5); color: var(--text-muted);
    & .big { font-size: var(--size-empty-icon); margin-block-end: var(--space-2); }
  }

  /* ---------- Accessibility ---------- */
  .skip-link {
    position: fixed; inset-inline-start: var(--space-2); inset-block-start: var(--skip-offset);
    z-index: var(--z-skip);
    background: var(--brand-solid); color: var(--on-solid); border-radius: var(--radius-sm);
    padding: var(--space-2) var(--space-4); font-size: var(--fs-md); font-weight: 700;
    transition: inset-block-start var(--dur) var(--ease);
    &:focus { inset-block-start: var(--space-2); text-decoration: none; }
  }

  /* ---------- Off-canvas nav toggle (shown ≤899px only) ---------- */
  .nav-toggle { display: none; }
  .nav-backdrop { display: none; }

  /* ---------- Small-screen shell (≤899px); desktop ≥900px unchanged ---------- */
  @media (max-width: 899px) {
    .nav-toggle { display: inline-flex; }
    .sidebar {
      position: fixed; inset-block: 0; inset-inline-start: 0; z-index: var(--z-drawer);
      block-size: 100vh; block-size: 100dvh;
      border-inline-end: none;
      padding-block-end: env(safe-area-inset-bottom, 0px);
      transform: translateX(-100%);
      transition: transform var(--dur-slow) var(--ease), visibility 0s linear var(--dur-slow);
      visibility: hidden;
      box-shadow: var(--shadow-drawer);
    }
    body.nav-open .sidebar {
      transform: none;
      transition: transform var(--dur-slow) var(--ease);
      visibility: visible;
    }
    body.nav-open .nav-backdrop {
      display: block; position: fixed; inset: 0; z-index: var(--z-backdrop);
      background: var(--overlay);
    }

    .topbar {
      flex-wrap: wrap;
      padding-block: max(var(--space-2), env(safe-area-inset-top, 0px));
      padding-inline: var(--space-3);
      gap: var(--space-2);
    }
    .topbar .title { font-size: var(--fs-lg); }
    .global-search { order: 3; inline-size: 100%; }
    .user-chip { min-block-size: var(--size-touch); }
    .user-chip .who { display: none; }
    .content { padding: var(--space-3); }

    /* comfortable touch targets */
    .nav a { padding-block: var(--space-3); }
    .btn, .chip { min-block-size: var(--size-touch); }
    .tabs button { min-block-size: var(--size-touch); }
    .icon-btn { inline-size: var(--size-touch-lg); block-size: var(--size-touch-lg); }
    .x-btn { inline-size: var(--size-touch); block-size: var(--size-touch); font-size: var(--fs-3xl); }
    .task-row input[type="checkbox"] { inline-size: var(--size-ic-lg); block-size: var(--size-ic-lg); }
    .sso-row { flex-wrap: wrap; }

    /* stretch so the .card board panes cannot shrink-to-fit to their
       borders (inline-size container containment) — see mid-width tier */
    .sched-layout { flex-direction: column; align-items: stretch; }
    .sched-side { inline-size: 100%; }
    .wb-board { flex-direction: column; overflow-x: visible; }
    .wb-col { flex-basis: auto; inline-size: 100%; }
    .map-layout { flex-direction: column; align-items: stretch; }
    .map-canvas { flex: none; }
    .form-row { flex-direction: column; }
    .toolbar .search { min-inline-size: 100%; }
    .totals-box { inline-size: 100%; }
    .form-field-row { align-items: stretch; flex-direction: column;
      & .select { inline-size: 100%; }
    }
    .form-answers .form-answer { grid-template-columns: 1fr; gap: var(--space-1); }
    .sig-pad canvas { block-size: 110px; }
    .modal-overlay {
      padding-inline: var(--space-2);
      padding-block-start: max(var(--space-4), env(safe-area-inset-top, 0px));
      padding-block-end: var(--space-4);
    }
    #toast-root {
      inset-block-end: calc(var(--space-6) + env(safe-area-inset-bottom, 0px));
      inset-inline-end: calc(var(--space-6) + env(safe-area-inset-right, 0px));
    }
  }

  /* ---------- Mid-width tier (900–1471px) ------------------------
     The week board is min 900px wide. Beside the 232px sidebar, the
     gutters and the 280px rail it only stops scrolling at ~1472px of
     viewport; in a row layout a 900–1471px laptop would scrub the
     board through a ~336px keyhole — narrower than a phone. So the
     rail stacks above the board (as on small screens) and the board
     takes the full content width. -------------------------------- */
  @media (min-width: 900px) and (max-width: 1471px) {
    /* stretch, not flex-start: every pane here is a .card, and .card
       runs inline-size container containment, so a non-stretched pane
       would shrink-to-fit to its borders and collapse */
    .sched-layout { flex-direction: column; align-items: stretch; }
    .sched-side { inline-size: 100%; }
    .map-layout { flex-direction: column; align-items: stretch; }
    .map-canvas { flex: none; }
  }

  /* ---------- Printable quote / invoice document ----------
     The paper metaphor stays light in both themes; the token
     pins below re-point the handful of semantics this document
     uses at the light primitives. ------------------------------ */
  .print-wrap { background: var(--bg); min-block-size: 100vh; padding: var(--space-6); }
  .print-doc {
    /* Preserve document pagination when the working UI type scale changes. */
    --fs-2xs: 10.5px; --fs-xs: 11.5px; --fs-sm: 12.5px;
    --fs-md: 13.5px; --fs-base: 14px; --fs-lg: 15.5px;
    --fs-xl: clamp(16px, 0.3vw + 15.6px, 18px);
    --fs-2xl: clamp(19px, 0.4vw + 18.2px, 22px);
    --fs-3xl: clamp(21px, 0.6vw + 20px, 26px);
    font-size: 14px;
    --text: var(--o-text);
    --text-secondary: var(--o-text-2);
    --text-muted: var(--o-muted);
    --border: var(--o-border);
    --brand: var(--o-brand);
    --success: var(--o-success);
    background: var(--o-raised);
    max-inline-size: var(--w-print); margin-inline: auto;
    /* the on-screen preview is the sheet the user proofs before
       printing: it keeps the paper margins (14mm) and the printed row
       rhythm, so what they read is what comes out — @media print must
       not re-lay this document out. The paper sheet carries its own
       compact leading (a deliberate exception to the 1.5 body copy):
       a 15-line wrapped document only fits one A4 sheet at this
       rhythm, and the preview shows the same compact lines */
    padding: 14mm;
    line-height: 1.35;
    & h1 { font-size: var(--fs-3xl); margin: 0 0 var(--bw-thick); }
    & .doc-meta {
      display: flex; justify-content: space-between;
      margin-block-end: var(--space-3); font-size: var(--fs-md); color: var(--text-secondary);
    }
    & table { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-base); margin-block-start: var(--space-3);
      & th {
        text-align: start; border-block-end: var(--bw-thick) solid var(--text);
        padding: var(--space-1); font-size: var(--fs-xs);
        text-transform: uppercase; letter-spacing: .06em;
      }
      & td { border-block-end: var(--bw) solid var(--border); padding: var(--space-1); }
    }
    & .grand { font-weight: 800; font-size: var(--fs-xl); }
    /* each completed form starts on a fresh sheet of the job paperwork */
    &.page-break { break-before: page; margin-block-start: var(--space-6); }
  }
}

/* BackSight screen composition. Layered so utilities, focus, reduced motion
   and the existing paper-document contract keep their intended precedence. */
@layer components {
  @media screen {
    .mark { flex-shrink: 0; }
    .mark svg { display: block; width: 100%; height: 100%; }
    .sidebar { background: #141a1f; border-color: #2c343b; }
    .sidebar .brand { gap: 10px; padding: 28px 18px 26px; color: #f3f5f6; }
    .sidebar .brand .mark { width: 42px; height: 42px; background: transparent; color: var(--brand-accent); }
    .sidebar .brand .name { font-family: var(--font-display); font-size: 1.6rem; font-weight: 600; letter-spacing: -.04em; }
    .sidebar .brand .tag { font-size: .75rem; line-height: 1.4; letter-spacing: 0; margin-top: 5px; text-transform: none; }
    .nav { padding: 0 12px 20px; }
    .sidebar .nav-label { margin: 20px 12px 9px; font: .75rem var(--font-mono); letter-spacing: .1em; }
    .nav a { min-height: 42px; padding: 10px 12px; gap: 12px; font-size: .875rem; border: 1px solid transparent; margin-bottom: 3px; }
    .nav a.active { background: #33261f; color: #ffb58b; border-color: #62402d; box-shadow: inset 3px 0 var(--brand-accent); }
    .nav a:hover { background: #252d34; color: #fff; }
    .nav a svg { width: 18px; height: 18px; }
    .sidebar .foot { padding: 18px 24px; color: #a5b0b9; font-size: .75rem; line-height: 1.8; }
    .workspace-label { font-family: var(--font-mono); font-size: .75rem; letter-spacing: .06em; color: #c6cdd2; }
    .topbar { min-height: 76px; }
    .topbar .title { font-size: .875rem; font-weight: 600; }
    .global-search .input { background: var(--surface-sunken); font-size: .8125rem; min-height: 39px; border-color: var(--border-strong); }
    .user-chip { gap: 10px; }
    .user-chip .who { text-align: start; line-height: 1.4; }
    .user-chip .who .nm { font-size: .8125rem; font-weight: 600; }
    .user-chip .who .rl { font-size: .75rem; }
    .user-chip .avatar { width: 34px; height: 34px; border-radius: 7px; }
    .content { padding-block: 28px 40px; }
    .page-head { margin-bottom: 26px; gap: 16px; align-items: end; }
    .page-head h1, .detail-title h1 { font-family: var(--font-display); font-size: clamp(1.75rem, 1.6vw + 1rem, 2.25rem); font-weight: 600; letter-spacing: -.035em; line-height: 1.18; }
    .page-head .sub { font-size: .9375rem; line-height: 1.55; margin-top: 8px; }
    .page-eyebrow { font: .75rem var(--font-mono); letter-spacing: .11em; color: var(--brand); margin-bottom: 10px; }
    .dashboard-date { display: flex; align-items: center; gap: 9px; padding-bottom: 3px; color: var(--text-muted); font: .8125rem var(--font-mono); }
    .dashboard-date svg { width: 17px; height: 17px; }
    .card { box-shadow: var(--shadow-1); }
    .card .card-head { padding: 17px 20px; min-height: 63px; gap: 12px; flex-wrap: wrap; }
    .card .card-head h3 { font-weight: 600; letter-spacing: -.02em; font-size: 1rem; }
    .card .card-body { padding: 20px; }
    .dashboard-primary { gap: 20px; }
    .dashboard-secondary, .dashboard-feed { margin-top: 20px; gap: 20px; }
    .dashboard-time { border-top: 3px solid var(--brand-accent); }
    .dashboard-time .card-head { min-height: 61px; }
    #time-summary > div { margin-bottom: 17px !important; }
    #time-summary .progressbar { border-radius: 2px; }
    #time-summary .progressbar > div { border-radius: 2px; }
    .dashboard-money .statline { gap: 20px; }
    .dashboard-money .stat .v { font-family: var(--font-display); font-size: 1.65rem; font-weight: 600; letter-spacing: -.035em; }
    .dashboard-money .stat .l { font-size: .8125rem; }
    .task-row { padding-block: 12px; }
    .task-row .tx { font-size: .875rem; line-height: 1.5; }
    .task-row.done .tx { color: var(--text-muted); }
    .card-body a:not(.btn):not(.chip) { text-decoration: underline; text-underline-offset: 3px; }
    .activity li { padding-block: 13px; }
    .activity .when { font-family: var(--font-mono); font-size: .75rem; }
    .btn { min-height: 39px; padding: 10px 15px; font-weight: 600; }
    .btn.sm { min-height: 32px; padding: 6px 11px; }
    .btn.secondary { border-color: var(--border-strong); }
    .input, .select, .textarea { min-height: 40px; padding: 10px 12px; font-size: .9375rem; }
    .field { margin-bottom: 18px; }
    label.fld { margin-bottom: 7px; }
    .toolbar { gap: 12px; margin-bottom: 18px; }
    .toolbar .input, .toolbar .select { font-size: .875rem; }
    .tbl th { font-size: .75rem; font-weight: 500; font-family: var(--font-mono); letter-spacing: .05em; padding-block: 14px; }
    .tbl td { padding-block: 16px; line-height: 1.5; }
    .tbl tbody tr.rowlink:hover { background: var(--surface-tint); }
    .tbl .num { font-family: var(--font-mono); font-size: .8125rem; }
    .badge { font-size: .75rem; line-height: 1.5; border-radius: 4px; font-weight: 500; padding: 3px 7px; }
    .chip { border-radius: 5px; font-size: .8125rem; padding: 6px 10px; }
    .tabs { gap: 4px; margin-bottom: 20px; }
    .tabs button { padding: 12px 16px; font-weight: 500; font-size: .875rem; }
    .kpi { padding: 20px 22px; border-top: 2px solid var(--border-strong); }
    .kpi .kpi-value { font-family: var(--font-display); font-weight: 600; letter-spacing: -.04em; }
    .modal { border-radius: 10px; }
    .modal-head { padding: 20px 24px; }
    .modal-head h2, .modal-head h3 { font-family: var(--font-display); font-weight: 600; letter-spacing: -.02em; }
    .modal-body { padding: 24px; }
    .modal-foot { padding: 16px 24px; background: var(--surface-sunken); }
    .sched-head, .roster-head, .gantt-head { font-family: var(--font-mono); }
    .job-chip, .wb-card { border-radius: 5px; }
    .detail-head { padding-bottom: 22px; margin-bottom: 24px; }

    /* A typographic entry surface with the form visible immediately. */
    .login-wrap { display: grid; grid-template-columns: 1fr 1fr; padding: 0; align-items: stretch; background: var(--surface-raised); }
    .login-intro { min-height: 100dvh; display: flex; flex-direction: column; padding: clamp(30px, 4.8vw, 78px); color: #f4f6f7; background-color: #141a1f; background-image: linear-gradient(#a9b4bc09 1px, transparent 1px), linear-gradient(90deg, #a9b4bc09 1px, transparent 1px); background-size: 52px 52px; position: relative; overflow: hidden; }
    .intro-brand { display: flex; gap: 12px; align-items: center; font-family: var(--font-display); font-size: 2rem; letter-spacing: -.04em; }
    .intro-brand .mark { width: 52px; height: 52px; color: var(--brand-accent); }
    .intro-message { margin-block: auto; padding: 70px 0; position: relative; }
    .brand-eyebrow { color: #afb9c1; font: .75rem var(--font-mono); letter-spacing: .13em; margin: 0 0 28px; }
    .intro-title { font: 600 clamp(3.4rem, 6.2vw, 6.4rem)/1.06 var(--font-display); letter-spacing: -.055em; margin: 0 0 28px; }
    .intro-title span { color: var(--brand-accent); }
    .intro-copy { font-size: 1rem; color: #b6c1ca; line-height: 1.8; margin: 0; }
    .intro-baseline { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 16px; border-top: 1px solid #404b54; padding-top: 22px; color: #aeb9c1; font: .75rem var(--font-mono); letter-spacing: .06em; }
    .login-panel { display: flex; align-items: center; justify-content: center; padding: 48px 36px; min-width: 0; }
    .login-card { width: 430px; padding: 0; box-shadow: none; border: 0; border-radius: 0; background: transparent; }
    .login-logo { gap: 10px; margin-bottom: 5px; }
    .login-logo .mark { background: transparent; color: var(--brand); width: 38px; height: 38px; }
    .login-logo .name { font: 600 1.6rem var(--font-display); letter-spacing: -.04em; }
    .login-sub { margin-bottom: 38px; font-size: .8125rem; }
    .login-kicker { font: .75rem var(--font-mono); letter-spacing: .1em; margin-bottom: 10px; }
    .login-title { font: 600 clamp(1.75rem, 2.4vw, 2.25rem)/1.2 var(--font-display); letter-spacing: -.035em; margin: 0 0 12px; }
    .login-lede { font-size: 1rem; line-height: 1.6; margin-bottom: 26px; }
    .sso-row { gap: 10px; }
    .sso-row .btn { white-space: normal; font-size: .8125rem; padding-inline: 8px; min-height: 44px; }
    .divider { font-size: .8125rem; margin-block: 20px; }
    .login-card .input { min-height: 48px; font-size: 1rem; }
    .login-card #li-submit, .login-card #tfa-submit { min-height: 46px; }
    .login-foot { border-top: 1px solid var(--border); padding-top: 20px; margin-top: 26px; font-size: .75rem; line-height: 1.7; text-align: start; }
    #li-links { gap: 16px; align-items: start; flex-wrap: wrap; font-size: .875rem !important; }
    #li-links > span { max-width: 230px; text-align: end; }
    @media (min-width: 1200px) {
      .grid.dashboard-primary { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); }
      .grid.dashboard-secondary { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 1fr); }
      .grid.dashboard-feed { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); }
    }
    @media (max-width: 1100px) {
      .login-intro { padding: 38px; }
      .intro-baseline span:last-child { display: none; }
    }
    @media (max-width: 899px) {
      .content { padding: 22px 16px 32px; }
      .topbar { min-height: auto; }
      .page-head { margin-bottom: 22px; }
      .sidebar .brand { padding-block: 24px; }
      .nav a { min-height: 44px; }
      .toolbar .count { white-space: normal; max-inline-size: 100%; }
      .btn, .btn.sm, .chip { min-height: 40px; }
      .card .card-head { padding: 15px 16px; }
      .card .card-body { padding: 16px; }
      .grid.k2, .grid.k3, .grid.k4 { grid-template-columns: minmax(0, 1fr); }
      .login-wrap { grid-template-columns: 1fr; }
      .login-intro { display: none; }
      .login-panel { min-height: 100dvh; padding: 38px 24px; border-top: 5px solid var(--brand-accent); }
      .login-sub { margin-bottom: 30px; }
      .dashboard-date { margin-top: 3px; }
    }
    @media (max-width: 420px) {
      .login-panel { padding-inline: 20px; }
      .login-title { font-size: 1.7rem; }
      #li-links > span { text-align: start; max-width: none; }
      .card .card-head { gap: 10px; }
      .modal-body { padding: 18px; }
    }
    @media (prefers-reduced-motion: no-preference) {
      .login-card, .intro-message { animation: backsight-enter 420ms ease-out both; }
      @keyframes backsight-enter { from { transform: translateY(8px); } to { transform: none; } }
    }
  }
}

/* ------------------------------------------------------------
   Utilities
   ------------------------------------------------------------ */
@layer utilities {
  .muted { color: var(--text-muted); }
  .small { font-size: var(--fs-sm); }
  .mt0 { margin-block-start: 0; } .mt8 { margin-block-start: var(--space-2); }
  .mt16 { margin-block-start: var(--space-4); } .mt24 { margin-block-start: var(--space-6); }
  .mb0 { margin-block-end: 0; } .mb8 { margin-block-end: var(--space-2); }
  .mb16 { margin-block-end: var(--space-4); }
  .flex { display: flex; } .flex-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
  .gap8 { gap: var(--space-2); } .gap12 { gap: var(--space-3); }
  .right { text-align: end; }
  .nowrap { white-space: nowrap; }
  .breadcrumb { font-size: var(--fs-sm); color: var(--text-muted); margin-block-end: var(--space-2); }
  /* the link sits inside muted text — underline it so colour isn't the only
     thing distinguishing it (axe link-in-text-block, WCAG 1.4.1) */
  .breadcrumb a { text-decoration: underline; text-underline-offset: 2px; }
}

/* Demo controls use normal flow, above the toolbar and away from PWA notices. */
@layer components {
  .demo-entry { margin-block: var(--space-4); padding-block-start: var(--space-4); border-top: var(--bw) solid var(--border); }
  .demo-entry[hidden] { display: none; }
  .demo-entry h2 { font-size: var(--fs-md); margin: 0 0 var(--space-3); }
  .demo-primary { width: 100%; white-space: normal; min-height: 44px; }
  .demo-team { margin-block-start: var(--space-2); font-size: var(--fs-sm); color: var(--text-secondary); }
  .demo-team > div { display: flex; align-items: center; flex-wrap: wrap; }
  .demo-team .btn { min-height: 44px; padding-inline: var(--space-2); }
  .demo-banner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-2) var(--space-content); border-bottom: var(--bw) solid var(--border); background: var(--surface-sunken); color: var(--text-secondary); font-size: var(--fs-sm); }
  .demo-banner-actions { display: flex; gap: var(--space-2); }
  .demo-banner .btn { min-height: 44px; }
}
@media print { .demo-banner { display: none; } }

/* Persistent PWA notices stay outside the route-owned shell. */
@layer components {
  body { padding-block-end: var(--pwa-status-height, 0px); }
  #pwa-status {
    position: fixed; inset-inline: 0; bottom: 0; z-index: var(--z-pop);
    max-block-size: 40vh; overflow: auto; background: var(--surface-raised);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }
  #pwa-status:empty { display: none; }
  .pwa-notice {
    display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
    gap: var(--space-2); padding: var(--space-2) var(--space-3);
    background: var(--surface-raised); color: var(--text-secondary);
    border-top: var(--bw) solid var(--border); font-size: var(--fs-sm);
  }
  .pwa-notice > span { max-inline-size: 70ch; }
  #pwa-install { min-block-size: 44px; }
}
@media print { #pwa-status, #pwa-install { display: none; } body { padding-block-end: 0; } }

/* ------------------------------------------------------------
   Reduced motion: disable every transition/animation
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------
   Print
   ------------------------------------------------------------ */
@media print {
  .no-print { display: none !important; }
  body { background: var(--o-raised); }
  /* the screen wrapper's 100vh + padding pushes tall documents onto a
     spurious, near-blank second page — on paper only the document remains */
  .print-wrap { min-block-size: 0; padding: 0; background: none; }
  /* the sheet's on-screen paper margins hand over to the print
     pipeline's page margins; the row rhythm already lives on .print-doc
     and must not be re-laid-out here */
  .print-doc { padding: 0; }
  /* a line item must never be sliced in half across a page break */
  .print-doc tr { break-inside: avoid; }
}
/* Account entry shares the login design and remains usable at 360px. */
.account-wrap { min-height:100dvh; display:grid; place-items:center; padding:24px 16px; }
.account-card { width:100%; max-width:440px; min-width:0; }
.account-card .input { width:100%; min-width:0; box-sizing:border-box; }
.account-card h1 { font-size:1.6rem; }
.account-card #account-error { color:var(--danger-strong, #b42318); overflow-wrap:anywhere; }
.account-accept { display:block; margin:16px 0; line-height:1.6; }
.account-notice { font-size:12px; max-width:220px; overflow-wrap:anywhere; }
#account-readonly[hidden] { display:none; }
#account-readonly { flex-wrap:wrap; }
.account-status { display:flex; flex-direction:column; gap:4px; max-width:260px; min-width:0; }
.billing-plans { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr)); gap:16px; margin-top:16px; }
.billing-plans > .card, #billing-summary { padding:20px; }
.account-trial-chip { display:inline-flex; border:1px solid currentColor; border-radius:999px; padding:2px 8px; font-size:12px; line-height:1.5; }
#account-writer-notice { font-size:11px; overflow-wrap:anywhere; }
#account-writer-notice:empty { display:none; }
.account-conflict-json { white-space:pre-wrap; overflow-wrap:anywhere; max-width:100%; font-size:12px; }
#account-sync-time { display:none; font-size:11px; }
.account-status:focus-within #account-sync-time, .account-status:hover #account-sync-time { display:block; }
@media (max-width:600px) { .account-status { order:2; flex-basis:100%; max-width:none; } .account-status .account-notice { max-width:none; width:100%; } }
@media (max-width:600px) { .account-notice { max-width:105px; font-size:11px; } }
/* Account verification forms retain comfortable touch targets at 360 px. */
.account-card input.input, .account-card .btn, .account-card a { min-height: 44px; }
.account-card a { display: inline-flex; align-items: center; }
.account-card { overflow-wrap: anywhere; }
.account-code-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.account-code-actions .btn { flex: 1 1 140px; }
