/* Self-hosted Geist (SIL OFL 1.1 — see assets/fonts/OFL.txt). Variable woff2,
   upright only — ethos §4 prefers weight changes over italics. */
@font-face {
  font-family: "Geist";
  src: url("../assets/fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("../assets/fonts/GeistMono-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}

/* Ford Antenna (proprietary — licensed Ford brand face, dealer use). The MAX
   brand display face (sheet labels it "Ford Antique"; the licensable face is
   Ford Antenna). MAX (= Dark) wordmark + hero numerals only; tables stay Geist. */
@font-face { font-family: "FordAntenna"; src: url("../assets/fonts/FordAntenna-Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "FordAntenna Cond"; src: url("../assets/fonts/FordAntennaCond-Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "FordAntenna Cond"; src: url("../assets/fonts/FordAntennaCond-Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "FordAntenna Comp"; src: url("../assets/fonts/FordAntennaComp-Black.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: swap; }

/* KG MAX design-bible faces (parity with design-bible/ ui_kits): Saira (display),
   Hanken Grotesk (text/UI), JetBrains Mono (data/mono), Michroma (the MAX wordmark).
   All SIL OFL 1.1 (see assets/fonts/OFL.txt). Variable woff2 (Michroma static 400),
   upright only. Geist + Ford Antenna @font-face kept above: still consumed by the
   crm/meeting.js print sheet (separate pass — design-bible-migration/SKIPPED.md). */
@font-face {
  font-family: "Saira";
  src: url("../assets/fonts/Saira-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Hanken Grotesk";
  src: url("../assets/fonts/HankenGrotesk-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../assets/fonts/JetBrainsMono-Variable.woff2") format("woff2");
  font-weight: 100 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Michroma";
  src: url("../assets/fonts/Michroma-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}

/* ============================================================================
   THEMES (2026-06-04): Light · Dark · Auto.  **Dark IS the MAX "Performance
   Layer"** (deep black/graphite/silver). Auto follows the OS (light or MAX-dark).
   Two accents: --accent (informational BLUE — pace/pivot/links/data cadence) and
   --brand (Energy Red — only brand chrome: active nav, CTAs, the X). Red
   never colors neutral numbers; it's reserved for genuinely-bad semantics (--red).
   ============================================================================ */
:root {
  /* Shared height for header-level clickable controls (store selector, stock
     pills, pace toggle, …) — uniform so the eye/muscle memory lands on the
     same band across the chrome. ~20% shorter than the old 32–36px pills.
     Drilldown/table controls are intentionally exempt. */
  --ctl-h: 28px;
  /* Masthead control band (operator-ratified 2026-07-28): the destination
     selector and the universal-search field share ONE height + radius source
     so they cannot drift apart. 32px pins the search input's established
     intrinsic height (6px pad ×2 + 13px/1.4 line + 1px border ×2); the radius
     follows the input's --r-sm. Store pills keep --ctl-h inside their track. */
  --masthead-ctl-h: 32px;
  --masthead-ctl-r: var(--r-sm);
  /* Design-bible type: Saira (display) · Hanken Grotesk (text) · JetBrains Mono
     (data) · Michroma (the MAX wordmark). */
  --font-sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-display: "Saira", var(--font-sans);
  --font-brand: "Saira", var(--font-sans);
  --font-hero: "Saira", var(--font-sans);
  --font-wordmark: "Michroma", "Saira", var(--font-sans);
  --font-label: var(--font-sans);

  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-7: 32px; --sp-8: 40px;
  /* Radii — design-bible scale (rounder: control 12, card 16). */
  --r-xs: 4px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 20px; --r-pill: 999px;
  /* The standalone `ma`+`x` wordmark is ONE size everywhere it appears (Aaron
     2026-07-25: "any time it is the standalone max, they need to be the same
     size globally"). 30px is Max AI's drawer mark — the operator pointed at it
     as correct — and matches native's fs['2xl'] / WORDMARK_SIZE in theme.ts.
     This does NOT govern the `--d`-scaled .max-lockup, which survives ONLY as
     Max AI's loading vocabulary (.max-spinner boot/thinking states) — the ring
     lockup is retired as a static logo everywhere (operator ruling 2026-07-28);
     static marks are the flat wordmark (.max-wordmark / .dw-masthead-mark).
     The First Login splash wordmark keeps its own --d display scale
     (styles/splash.css branding slot). */
  /* Header-control diameter — the web mirror of native's
     headerChrome.buttonSize (theme.ts). .max-chrome-btn consumes it, and so
     does --dw-topbar-height, so the shell's top offset can never fall out of
     step with the control that sets the header's height. */
  --chrome-btn-size: 44px;
  --wordmark-size: 30px;
  /* `ma`+`x` is x-height-only type — no ascenders, no descenders — so centring
     its line box leaves the visible ink below the row's centre, and the mark
     reads low beside a glyph that fills its box. Apply this lift wherever the
     mark shares a line with other chrome. Mirrors native's
     WORDMARK_OPTICAL_LIFT (measured on device at --wordmark-size 30). */
  --wordmark-optical-lift: -5px;
  /* Type scale (2026-06-05 UI refresh): a deliberate set that collapses the ~25
     ad-hoc font sizes drifting across the stylesheets. Adopt incrementally —
     existing px sizes still work; map onto these as files are touched. */
  --fs-2xs: 10.5px; --fs-xs: 11.5px; --fs-sm: 12.5px; --fs-base: 14px;
  --fs-md: 15px;    --fs-lg: 18px;   --fs-xl: 22px;    --fs-2xl: 30px;
  --fw-medium: 500; --fw-semi: 600;  --fw-bold: 700;
  --sh-1: 0 1px 3px rgba(20, 20, 30, 0.08);
  --sh-2: 0 4px 14px rgba(20, 20, 30, 0.10);
  --sh-3: 0 1px 2px rgba(20,20,30,0.05), 0 3px 6px rgba(20,20,30,0.06), 0 8px 20px rgba(20,20,30,0.08), 0 16px 36px rgba(20,20,30,0.06);
  --sh-4: 0 2px 4px rgba(20,20,30,0.06), 0 6px 12px rgba(20,20,30,0.07), 0 14px 32px rgba(20,20,30,0.10), 0 28px 60px rgba(20,20,30,0.10);

  /* Hover-motion standard — THE timing for every interactive hover (the original
     .crm-card feel). One token so nothing drifts slower; see STYLE.md §9 +
     styles/interactions.css. Snappy, no overshoot. */
  --hover-dur: 0.15s;
  --hover-ease: var(--ease-out);   /* 2026-07-04: was `ease`; the bible's expo-out now drives every hover/transition */

  /* ============================================================================
     DESIGN-BIBLE TOKENS (design-bible/tokens/*). Brand layer adopted UI-wide:
     bible motion + easings, Energy-Red flares/focus, gradients, type tracking +
     leading. Surfaces + the functional blue --accent are kept
     (operational data cadence); Energy Red (--brand) is the brand accent. */
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
  --dur-instant: 80ms; --dur-fast: 120ms; --dur-base: 200ms; --dur-slow: 320ms;
  --dur-stream-caret: 1800ms;
  --lh-tight: 1.05; --lh-snug: 1.18; --lh-normal: 1.5; --lh-relaxed: 1.65;
  --tracking-tight: -0.015em; --tracking-wide: 0.04em; --tracking-eyebrow: 0.2em;
  /* Energy glow — LIGHT default: a TIGHT red elevation (the 24px neon halo reads
     muddy on white), paired with a 1px accent edge so the lift stays crisp. The
     dark/MAX blocks below re-override to the luminous halo. */
  --glow-red-sm: 0 1px 5px rgba(226, 46, 21, 0.30);
  --glow-red: 0 2px 10px rgba(226, 46, 21, 0.28), 0 0 0 1px rgba(226, 46, 21, 0.22);
  --glow-red-lg: 0 4px 18px rgba(226, 46, 21, 0.30), 0 0 0 1px rgba(226, 46, 21, 0.20);
  --glow-red-ring: 0 0 0 1px rgba(226, 46, 21, 0.55), 0 1px 8px rgba(226, 46, 21, 0.22);
  --ring-focus: 0 0 0 2px var(--bg), 0 0 0 4px color-mix(in srgb, var(--user-accent) 75%, transparent);
  --gradient-energy: linear-gradient(90deg, #7A0D03 0%, #D21A0A 50%, #FF6A3D 100%);
  --gradient-energy-diag: linear-gradient(135deg, #D21A0A 0%, #FF6A3D 100%);
  --gradient-graphite: linear-gradient(180deg, #1F1F23 0%, #121214 100%);
  --gradient-ember: radial-gradient(120% 140% at 50% -10%, rgba(255,56,31,0.30) 0%, rgba(210,26,10,0.08) 34%, transparent 68%);
  /* Canvas ember v2 (2026-07-02) — the dark/MAX page-canvas glow, redesigned off the flag
     revert. Two fixed-px radials (not %-sized, so they don't smear at 2560 or blob at 390)
     anchored off-canvas at the top corners, feathering out well before mid-viewport. Deepest
     stop is --kg-red-700 (#7A0D03) at low alpha — reads as heat behind a blacked-out machine,
     not a red wash (Energy Red is never a background wash — bible rule). --gradient-ember
     itself is untouched (auth.css login canvas still uses the original single-radial wash). */
  --gradient-ember-v2:
    radial-gradient(900px 640px at -6% -14%, rgba(122,13,3,0.24) 0%, rgba(122,13,3,0.10) 40%, transparent 72%),
    radial-gradient(560px 420px at 106% 8%, rgba(255,106,61,0.05) 0%, transparent 60%);
  --canvas-glow: none;   /* page canvas bloom — none for light; the ember in dark/MAX (set per-theme below) */

  --max-deep-black: #0b0b0c; --max-graphite: #1a1a1d; --max-silver: #c7c7c8;
  --max-gunmetal: var(--max-graphite); --max-aluminum: var(--max-silver);
  --max-red: #ff381f;
  --max-ember: #ff6a3d;   /* the energy gradient's warm terminal — "ember accent" for soft focus/heat */
  /* Brand accent — fixed Max Red (the Ford-paint accent picker was retired
     2026-07-02; MAX stays visually consistent, Light/Dark is the only choice).
     Everything "Max red" routes through this — chat surface, mark, MAX-dark
     brand chrome. The informational blue --accent is NOT affected. Kept as a
     token indirection so the ~15 var(--user-accent) call sites need no churn. */
  --user-accent: var(--max-red);
  /* Text color on --user-accent fills (bubble, CTAs). Always white now that the
     accent is fixed to Max Red. */
  --user-accent-text: #fff;
  --max-aluminum-grad: linear-gradient(180deg, #e4e5e7 0%, #9a9b9e 45%, #6e7074 100%);

  /* LIGHT chrome (default). */
  color-scheme: light;
  --bg: #f7f7f7;
  --panel: #ffffff;
  --panel-2: #ececec;
  --border: #d8dde3;
  --text: #1a1f26;
  --text-dim: #555c66;
  --text-muted: #8b929c;

  --accent: #0066b3;             /* informational blue — pace/pivot/links/data */
  /* MAX Overview pane re-scope target (build spec §C): the pane sits inside
     .chat-body, which scopes --accent to red for the chat product — Overview
     re-scopes its own --accent back to this blue data-cadence token. */
  /* DATA ACCENT — Energy Red, not blue. Aaron 2026-07-27, on the blue:
     "i feel like blue throws off the feel don't you?" He is right, and the
     palette says why: --red and --brand are the SAME value here ("danger =
     brand per brandbook"), so the whole surface is one warm family and the
     data layer was the only thing speaking a cool one. It read as borrowed
     from another product.

     THE DISCIPLINE THAT MAKES THIS SAFE: with data and danger sharing a hue,
     "something is wrong" can no longer be signalled by color alone. Alert
     states must keep their TREATMENT — the hard-floor ring, the glow, the
     badge — which is how .kpi-card.is-alert already works, and how the
     reference Aaron supplied distinguishes ok/warn/fault (chips, not line
     color). Do not add a state that reads only as "it went red".

     Supersedes the two-accent doctrine's data half (STYLE.md §0). --brand
     and chrome are unchanged; this token is only the data cadence. */
  --data-accent: #d21a0a;        /* Energy Red 500 — matches --red in this theme */
  --sort-desc: #d98a2b;          /* descending-sort header (amber) */
  --brand: var(--user-accent);   /* Energy Red brand chrome (bible — red in BOTH themes) */
  --green: #2d8a4e;
  --red: #d21a0a;                /* genuinely-bad only — Energy-Red 500 (2026-07 remap off legacy Race Red; 5.4:1 on panel, 5.0:1 on bg) */
  --orange: #d97706;
  --warn: #c9821a;               /* amber caution / data-quality (absorbs #c9a227, #d4a017, #ea580c one-offs) */
  --new: #14b8a6;
  --used: #d97706;
  --fctp: #8b5cf6;
  /* Transit status = light purple, deliberately distinct from recon (red) and
     a shade lighter than FCTP's violet so the two don't read the same. */
  --transit: #a78bfa;
  --prior: #6b7280;
  --total: #1a1f26;
  --store-buena-park: #2563eb;
  --store-carlsbad: #bf0a30;
  --store-redlands: #2d8a4e;

  /* ══ DEPARTMENTAL PALETTE — the workspace rail's nav zone ═══════════════════
     RATIFIED BY THE OPERATOR 2026-07-30, verbatim: "Maybe reserve the ember for
     the app youre on, and color the tiles based off the actual colors we chose
     (teal for new, orangeish for used.. need to come up for a unique color for
     each one)." Recorded here as a design-bible deviation by operator
     instruction, per the REBASE-1 rule that spec changes are attributed.

     THE RULE IT ESTABLISHES: Energy Red (--brand) is RESERVED for the APP ZONE
     — it means "the app you are in", nothing else. Each of the eight business
     pillars carries its own department colour instead. This also fixes a live
     defect: before it, the active app tile and the active pillar tile both wore
     Energy Red plus a red earmark, so the rail showed two competing "you are
     here" markers of equal weight.

     COLOUR MARKS SELECTION ONLY (operator, 2026-07-30, correcting the same
     day's first pass: "Oh, also, I only want it colored if it IS selected").
     The palette originally painted every pillar at rest AND active, on the
     theory that a department colour is a stable identity. It is a STATE: a
     tile at rest is the plain --text-muted the rail carried before this
     palette existed, and the department colour appears only on the SELECTED
     tile. So the rail shows exactly two colours at any moment — Energy Red on
     the app you are in, one department colour on the pillar you are in.
     Everything else is neutral. Same tokens, fewer places they are read.
     Consumers: the .dw-rail-nav ACTIVE tile and the destination panel's
     ACTIVE row (styles/dashboard-workspaces.css).

     THE PALETTE IS ISO-LUMINANT BY CONSTRUCTION, and that is the whole trick.
     Every coloured code sits at L* 45 (light) / L* 68 (dark) — measured, not
     eyeballed — so all seven carry the SAME contrast against the rail ground
     (5.4:1 light · 5.3–5.9:1 hybrid · 6.4–7.1:1 dark). Only HUE varies down the
     column, which is what keeps eight colours reading as calm chrome rather
     than as a fruit salad: a rail looks loud when tiles differ in LIGHTNESS,
     not when they differ in hue.

     ONE MEASUREMENT FROM THE FIRST PASS IS RETIRED, NOT INHERITED. It said the
     colour had to be full strength at rest because muting it toward
     --text-muted measured 5.4:1 → ~4.0:1 in light, under the AA floor. That was
     an argument about DIMMING A HUE, and it is moot now that rest is not a hue
     at all: an unselected tile is literally --text-muted, the value the rail
     shipped before this palette existed and which already cleared AA on every
     ground. Do not resurrect it as a reason to colour a resting tile.

     Selectedness never rides on colour alone (WCAG 1.4.1): the tile SURFACE
     (--panel-2), the 2px earmark, the rim/glow and aria-current all carry it
     too, so a colour-blind reader still sees "you are here".

     THE PER-THEME SPLIT IS NOT DECORATION. --new (#14b8a6) measures 2.49:1 on
     the light rail's white ground and --used (#d97706) 3.19:1 — both illegible.
     Light needs L* ≤ 45.3 to clear 4.5:1 on the active tile's #ececec, dark
     needs L* ≥ 66.9 to clear it on hybrid's #3a3a3a, so the two bands cannot be
     one value. Existing tokens are aliased wherever they land in the band
     (--new, --used and --accent all do, in dark) and a named value is added
     only where none does. Warm hues in LIGHT read brown/olive because a legible
     amber on white IS dark amber; that is arithmetic, not a choice.

     Overview is DELIBERATELY UNCOLOURED (--text): it is the roll-up ACROSS
     departments, not a department, so exactly one tile carries no hue and it is
     the "everything" tile.

     Measured pairwise separation: min ΔE00 14.0 (light, USED/BDC) and 13.7
     (dark, OVR/RPT) across all 28 pairs — every pair is distinguishable at the
     44px tile's ~27px of 14px mono. Red-adjacency floor: USED, the deliberate
     warm limit, sits ΔE00 20.1/25.1 from Energy Red; nothing is warmer.
     Consumed by .dw-rail-nav's ACTIVE tile and by .dw-destination.is-active in
     styles/dashboard-workspaces.css — the tile reads the colour as INK, the
     panel row reads it as a TINTED SURFACE (see --dw-row-tint-strength there).
     Separation still matters at rest, because two pillars can be selected at
     once: one on the rail, one in the panel it opened. */
  --dept-overview: var(--text);      /* the roll-up: neutral by design, not a department */
  --dept-new: #00786c;               /* --new's teal at the light band (--new itself is 2.49:1 on white) */
  /* THE TWO WARM HUES RUN RICHER THAN THE OTHERS, AND THAT IS A RATIFIED
     DEVIATION — not an oversight, and not to be "fixed" by a later pass.
     Amber and gold are the only hues in this palette whose legible-on-white
     value reads as a DIFFERENT COLOUR rather than a darker one: at 5.38:1 they
     render brown (#9f5900) and olive (#826701), which is arithmetic, not taste.
     Shown both ways to the operator on 2026-07-30 with the numbers, his answer:
     "q2 - richer is good".
     THE COST, stated plainly and MEASURED (an earlier note here quoted 4.65 /
     3.93 — those numbers were wrong, recomputed directly from the hex):
       #bd6a00 amber  4.02:1 on white, 3.40:1 on the selected tile
       #9c7c02 gold   3.96:1 on white, 3.36:1 on the selected tile
     Both are UNDER the 4.5 floor in BOTH states, not just when selected. Every
     other department colour clears 4.5 everywhere; these two do not, by
     operator instruction, because a warm hue that reads as mud communicates
     less than a warm hue that reads as warm. The compliant values are #9f5900
     and #826701 (5.38 / 5.40 on white) and a middle rung exists at #ab5f00 /
     #8c7002 (4.81 / 4.74) if this is ever revisited.
     Do NOT darken these back without asking him. Do NOT apply the same
     reasoning to the other six — they have no such trade to make. */
  --dept-used: #bd6a00;              /* amber, kept amber (the 5.38:1 value #9f5900 reads brown) */
  --dept-service: var(--accent);     /* the service drive takes the house blue — it already sits in the band */
  --dept-parts: #784dde;             /* violet (--fctp is 4.23:1 on white) */
  --dept-bdc: #9c7c02;               /* gold, kept gold (the 5.40:1 value #826701 reads olive); h 88 still separates it from USED */
  --dept-financials: #2b7a28;        /* money green (--green is 4.32:1 on white) */
  --dept-reports: #606b81;           /* slate — the least-coloured of the coloured ones */

  /* Affordance: the header 'clickable' warm orange (rest / active) — wayfinding, not brand/--warn. */
  --affordance: #ef7c00;
  --affordance-active: #ff8f1a;
  /* Data-viz: deliberately OFF the semantic palette (gauge bands, board-stage tags, KBB/age/pin markers) — named, not scattered literals. */
  --gauge-band-blue: #1e40af;
  --gauge-band-blue-deep: #172554;
  --gauge-behind-deep: #991b1b;
  --gauge-needle: #4b535d;        /* slate graphite — softer than ink on white */
  --dv-bdc: #e0a45b;
  --dv-fleet: #ff9f1c;
  --dv-flag-warn: #ffd58a;
  --dv-flag-bad: #ffb4b4;
  --dv-kbb-mid: #e8c400;
  --dv-teal: #38a99a;
  --dv-understock: #5aa9e6;
  --dv-pin: #6b7280;
  --dv-age-0: #77d995; --dv-age-1: #8ee0a7; --dv-age-2: #ffd76d; --dv-age-3: #ffb15c; --dv-age-4: #ff9292;  /* recon age ramp fresh->stale */
  --fin-new: var(--store-buena-park);
  --fin-used: var(--used);
  --fin-fni: var(--fctp);
  --fin-service: #4338ca;
  --fin-parts: var(--green);
  --fin-body: #475569;
  /* Sales Tracker team-row solid fill (reports.css .reports-mgr-tinted,
     screen-only — 2026-07-02) — how much black to color-mix into a manager's
     hue (one of the fin-new/fin-used/fin-fni/fin-service/fin-parts family,
     fin-body, or text-muted) so WHITE row text clears 4.5:1 (WCAG AA) on
     every hue. Verified worst-case per theme (light: text-muted 3.14:1 base
     -> needs 19% black; dark: fin-used 2.71:1 base -> needs 25% black) —
     this is the flat per-theme % with margin above both. */
  --mgr-fill-mix: 20%;
  --fin-kept: var(--green);
  --fin-burned: var(--warn);
  --fin-statement-bg: #f6f7f9;
  --fin-band-bg: #4a4f57;

  --row-tint: rgba(0, 0, 0, 0.04);
  --subheader-bg: rgba(0, 0, 0, 0.04);
  --accent-tint: rgba(0, 102, 179, 0.12);
  --brand-tint: color-mix(in srgb, var(--user-accent) 12%, transparent);
  --error-tint: rgba(210, 26, 10, 0.08);
  --hover-bg: #e0e5eb;
  --hover-border: #b8c0c8;
  --dot: rgba(20, 20, 45, 0.14);   /* canvas dot-field (light) — legacy strength; account/admin-plane canvases */
  /* Canvas grain (2026-07-03) — the dot-field readmitted as MATERIAL, not pattern:
     a much fainter dot on a tighter pitch, painted only near the top of the
     viewport (app.css fades it out by mid-screen) so it reads as machined texture
     caught in the header light, not dot-grid wallpaper. One formula for all
     themes; the per-theme --dot-grain carries the color. Neutral only — never red
     (Energy Red is never a background wash). */
  --dot-grain: rgba(20, 20, 45, 0.09);
  --canvas-texture: radial-gradient(var(--dot-grain) 1px, transparent 1.1px);
  /* How the dot field FADES. One token because this mask was copy-pasted into
     six stylesheets (app, auth, admin-plane, boards, recon-shell, settings) and
     had already drifted — settings.css used var(--bg) where the rest used #000,
     which is not even a valid mask colour intent.
     It WAS `linear-gradient(to bottom, #000 18%, transparent 66%)`: solid at the
     top edge, gone by two-thirds down. Operator, 2026-07-29: "I thought it was a
     gradient from center to left and right, but it also appears to be a gradient
     from top to bottom. I want the dot gradient to be consistent from vertical
     center to outside edges." So it is now symmetric about the CENTRE and fades
     outward equally in every direction — densest at the middle of the viewport,
     clear at all four edges. Ellipse (not circle) so the falloff tracks the
     viewport's aspect instead of pooling in a circle on a wide monitor. */
  --canvas-texture-mask: radial-gradient(ellipse 78% 78% at 50% 50%, #000 0%, #000 30%, transparent 100%);
  /* Light-theme additions for bible feedback components (hairline ramp).
     Dark already defines --border-subtle/-strong. */
  --border-subtle: rgba(0, 0, 0, 0.06);
  --border-strong: rgba(0, 0, 0, 0.20);
}

/* DARK = MAX "Performance Layer". Explicit ([data-theme="dark"]) or via Auto
   (system dark). --accent stays BLUE (data cadence); --brand is Energy Red
   (brand chrome only). [data-theme="max"] kept as a back-compat alias. */
:root[data-theme="dark"],
:root[data-theme="max"] {
  color-scheme: dark;
  --font-brand: "Saira", var(--font-sans);
  --font-hero: "Saira", var(--font-sans);
  --bg: var(--max-deep-black);
  --panel: var(--max-graphite);
  --panel-2: #222226;
  --border: rgba(255, 255, 255, 0.10);     /* bible glassy hairline (was #303034) */
  --border-subtle: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(255, 255, 255, 0.18);
  --text: var(--max-aluminum);
  --text-dim: #a6a8ad;
  --text-muted: #92949a;
  --accent: #4d9fff;             /* bright informational blue on graphite */
  --data-accent: #ff381f;        /* Energy Red base — see the :root note above */
  --sort-desc: #e0a34a;          /* descending-sort header (amber) */
  --brand: var(--user-accent);   /* Energy Red — active nav / CTAs / brand */
  --green: #2fa85a;
  --red: #ff381f;                /* bad (90+ buckets, negative deltas) — Energy-Red base, = --brand (danger = brand per brandbook); 5.5:1 on --bg, 4.8:1 on --panel */
  --orange: #e0890f;
  --warn: #e0a83a;               /* amber caution / data-quality (MAX) */
  --used: #e0890f;
  --fctp: #9b75f0;
  --transit: #b9a3fb;
  --prior: #7a7d82;
  --total: var(--text);
  --store-buena-park: #3b82f6;
  --store-carlsbad: #e0344a;
  --store-redlands: #34b364;

  /* Departmental palette, DARK band (L* 68) — see the :root block's ratification
     note. Three of the eight need no new value here: --new and --used already
     land in the band (4.57:1 / 4.20:1 on the hardest ground), which is the
     operator's "the actual colors we chose" honoured literally, and --accent
     carries Service. */
  --dept-overview: var(--text);
  --dept-new: var(--new);            /* #14b8a6 — legible as-is on graphite */
  --dept-used: var(--used);          /* #e0890f — the operator's amber, legible as-is on graphite */
  --dept-service: var(--accent);
  --dept-parts: #b991ff;
  --dept-bdc: #c9a101;
  --dept-financials: #6bb760;
  --dept-reports: #9ba6bf;

  --gauge-band-blue: #3b5bdb;
  --gauge-band-blue-deep: #2f4bb3;
  --gauge-behind-deep: #ff3b57;
  --gauge-needle: var(--max-silver);   /* brand silver on graphite — instrument, not flashlight */
  --fin-new: var(--store-buena-park);
  --fin-used: var(--used);
  --fin-fni: var(--fctp);
  --fin-service: #6670e8;
  --fin-parts: var(--green);
  --fin-body: #8b96a8;
  --mgr-fill-mix: 28%;   /* dark hues are brighter — see the light block's comment */
  --fin-kept: var(--green);
  --fin-burned: var(--warn);
  --fin-statement-bg: #f6f7f9;
  --fin-band-bg: #4a4f57;
  --row-tint: rgba(255, 255, 255, 0.03);
  --subheader-bg: rgba(255, 255, 255, 0.045);
  --accent-tint: rgba(77, 159, 255, 0.16);
  --brand-tint: color-mix(in srgb, var(--user-accent) 18%, transparent);
  --error-tint: rgba(255, 56, 31, 0.12);
  --hover-bg: #2a2a2a;
  --hover-border: #3a3a3a;
  --dot: rgba(255, 255, 255, 0.10);   /* canvas dot-field (MAX/dark) — legacy strength; account/admin-plane canvases */
  --dot-grain: rgba(255, 255, 255, 0.07);   /* canvas grain (MAX) — under the legacy 0.10 dot; texture, not pattern */
  --canvas-glow: var(--gradient-ember-v2);   /* MAX canvas = ember v2, corner heat behind the header (2026-07-02) */
  --sh-1: 0 1px 2px rgba(0,0,0,0.45);
  --sh-2: 0 2px 8px rgba(0,0,0,0.50);
  --sh-3: 0 1px 2px rgba(6,6,7,0.5), 0 3px 6px rgba(6,6,7,0.4), 0 8px 16px rgba(6,6,7,0.32), 0 16px 32px rgba(6,6,7,0.24);
  --sh-4: 0 2px 4px rgba(6,6,7,0.5), 0 6px 12px rgba(6,6,7,0.42), 0 14px 28px rgba(6,6,7,0.34), 0 28px 56px rgba(6,6,7,0.26);
  --edge-highlight: inset 0 1px 0 rgba(255,255,255,0.06);
  /* Energy glow — MAX/dark: the luminous halo (overrides the light tight-shadow). */
  --glow-red-sm: 0 0 12px rgba(255, 59, 31, 0.45);
  --glow-red: 0 0 24px rgba(255, 59, 31, 0.45);
  --glow-red-lg: 0 0 48px rgba(255, 59, 31, 0.50);
  --glow-red-ring: 0 0 0 1px rgba(255, 59, 31, 0.55), 0 0 22px rgba(255, 59, 31, 0.35);
  --ring-focus: 0 0 0 2px var(--bg), 0 0 0 4px color-mix(in srgb, var(--user-accent) 75%, transparent);
}

/* AUTO (no cookie / 'auto') follows the OS: system-dark → MAX. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --font-brand: "Saira", var(--font-sans);
    --font-hero: "Saira", var(--font-sans);
    --bg: var(--max-deep-black);
    --panel: var(--max-graphite);
    --panel-2: #222226;
    --border: rgba(255, 255, 255, 0.10);     /* bible glassy hairline (was #303034) */
    --border-subtle: rgba(255, 255, 255, 0.06);
    --border-strong: rgba(255, 255, 255, 0.18);
    --text: var(--max-aluminum);
    --text-dim: #a6a8ad;
    --text-muted: #92949a;
    --accent: #4d9fff;
    --data-accent: #ff381f;        /* Energy Red base — see the :root note above */
    --sort-desc: #e0a34a;
    --brand: var(--user-accent);
    --green: #2fa85a;
    --red: #ff381f;                /* = --brand (danger = brand); see :root[data-theme="dark"] note */
    --orange: #e0890f;
    --warn: #e0a83a;               /* amber caution / data-quality (MAX) */
    --used: #e0890f;
    --fctp: #9b75f0;
    --transit: #b9a3fb;
    --prior: #7a7d82;
    --total: var(--text);
    --store-buena-park: #3b82f6;
    --store-carlsbad: #e0344a;
    --store-redlands: #34b364;

    /* Departmental palette, DARK band — the [data-theme="dark"] block's values verbatim. */
    --dept-overview: var(--text);
    --dept-new: var(--new);
    --dept-used: var(--used);
    --dept-service: var(--accent);
    --dept-parts: #b991ff;
    --dept-bdc: #c9a101;
    --dept-financials: #6bb760;
    --dept-reports: #9ba6bf;

    --gauge-band-blue: #3b5bdb;
    --gauge-band-blue-deep: #2f4bb3;
    --gauge-behind-deep: #ff3b57;
    --gauge-needle: var(--max-silver);
    --fin-new: var(--store-buena-park);
    --fin-used: var(--used);
    --fin-fni: var(--fctp);
    --fin-service: #6670e8;
    --fin-parts: var(--green);
    --fin-body: #8b96a8;
    --mgr-fill-mix: 28%;   /* dark hues are brighter — see the light block's comment */
    --fin-kept: var(--green);
    --fin-burned: var(--warn);
    --fin-statement-bg: #f6f7f9;
    --fin-band-bg: #4a4f57;
    --row-tint: rgba(255, 255, 255, 0.03);
    --subheader-bg: rgba(255, 255, 255, 0.045);
    --accent-tint: rgba(77, 159, 255, 0.16);
    --brand-tint: color-mix(in srgb, var(--user-accent) 18%, transparent);
    --error-tint: rgba(255, 56, 31, 0.12);
    --hover-bg: #2a2a2a;
    --hover-border: #3a3a3a;
    --dot: rgba(255, 255, 255, 0.10);   /* canvas dot-field (auto → MAX) — legacy strength; account/admin-plane canvases */
    --dot-grain: rgba(255, 255, 255, 0.07);   /* canvas grain (auto → MAX) — under the legacy 0.10 dot; texture, not pattern */
    --canvas-glow: var(--gradient-ember-v2);   /* auto-dark canvas = ember v2, corner heat behind the header */
    --sh-1: 0 1px 2px rgba(0,0,0,0.45);
    --sh-2: 0 2px 8px rgba(0,0,0,0.50);
    --sh-3: 0 1px 2px rgba(6,6,7,0.5), 0 3px 6px rgba(6,6,7,0.4), 0 8px 16px rgba(6,6,7,0.32), 0 16px 32px rgba(6,6,7,0.24);
    --sh-4: 0 2px 4px rgba(6,6,7,0.5), 0 6px 12px rgba(6,6,7,0.42), 0 14px 28px rgba(6,6,7,0.34), 0 28px 56px rgba(6,6,7,0.26);
    --edge-highlight: inset 0 1px 0 rgba(255,255,255,0.06);
    /* Energy glow — auto-dark: the luminous halo (overrides the light tight-shadow). */
    --glow-red-sm: 0 0 12px rgba(255, 59, 31, 0.45);
    --glow-red: 0 0 24px rgba(255, 59, 31, 0.45);
    --glow-red-lg: 0 0 48px rgba(255, 59, 31, 0.50);
    --glow-red-ring: 0 0 0 1px rgba(255, 59, 31, 0.55), 0 0 22px rgba(255, 59, 31, 0.35);
    --ring-focus: 0 0 0 2px var(--bg), 0 0 0 4px color-mix(in srgb, var(--user-accent) 75%, transparent);
  }
}

/* ============================================================================
   HYBRID chrome scope (operator-ratified 2026-07-28 — light canvas, DARK
   header + sidebar chrome, per the Tekion reference). app_theme=hybrid keeps
   the root LIGHT (data-theme="light") and adds html.chrome-dark (shell.html
   anti-flash bootstrap + core.js setTheme). This block re-declares ONLY the
   surface tokens, with the DARK block's values verbatim, on the chrome
   containers: the workspace sidebar (.dw-shell — rail + APPS flyout panel +
   identity), the top bar (header.app-header, which also hosts the
   destination/level-2 dropdown and the .am-popover apps menu on non-dashboard
   shells), the admin control-plane sidebar (.ap-side —
   admin.ai-kgf.org has its own chrome, not .dw-shell), and the chrome-owned
   portals.
   NOT THE SHELL FOOTER (operator, 2026-07-30: "this footer on hybrid does not
   need to be gray"). It left this scope and now takes the LIGHT --panel in
   hybrid, while dark and max keep it graphite through their own blocks below.
   The reasoning holds with the rest of the doctrine rather than against it:
   the chrome that must read as one material is the FRAME the content sits
   inside — the sidebar and the top bar, which the eye tracks as a continuous
   L. The footer is a terminal rule under the canvas, not part of that frame,
   and a graphite band under a light page reads as a second surface rather
   than as chrome. Fixed by moving which container carries the scope, per the
   HARD RULE below — NOT by adding a per-component hybrid override.
   PORTAL GOTCHA: the notifications/inbox drawer (.gear-menu) is
   portaled to <body> by core.js openGear(), so it must be listed here
   explicitly or it would open LIGHT over its dark trigger.
   HARD RULE: hybrid is a token remap ONLY — no per-component hybrid styles,
   ever. If something inside the chrome looks wrong in hybrid, fix which
   container carries the scope or fix that component's token usage; never add
   a `html.chrome-dark .thing` component rule.
   --ring-focus needs no re-declare: every theme's formula spaces with
   `0 0 0 2px var(--bg)`, and var(--bg) resolves at the focused element, so
   inside this scope the spacer is already the dark chrome bg. */
html.chrome-dark .dw-shell,
html.chrome-dark header.app-header,
html.chrome-dark .gear-menu,
html.chrome-dark .am-popover,
html.chrome-dark .ap-side {
  color-scheme: dark;
  /* Chrome ground: ONE RUNG ABOVE dark's graphite (operator, 2026-07-28, in
     two steps). First he rejected the #0b0b0c deep-black ground as "a little
     too stark of a contrast" against the light canvas and asked for dark's
     graphite. Measured after that change, hybrid and dark chrome were provably
     the SAME paint (both rgb(26,26,29)) — but the same grey reads far darker
     beside a #f7f7f7 canvas than beside a #0b0b0c one, so hybrid still looked
     heavier. That is simultaneous contrast, not a token bug. Ruling: "we can
     lighten hybrid then, just slightly though" — so the ground steps up
     exactly ONE rung of the existing dark family, to root dark's #202024.
     Deliberately NOT #222226 (two rungs); "slightly" is the spec.
     This is the ONE place hybrid and dark chrome differ, and it is on purpose:
     the material is matched to how it READS against its own canvas, not to a
     hex equality that the eye never sees. No new hex — #202024 is root dark's
     --bg-elevated. Elevation order still holds: 202024 < 222226 < 2a2a2a. */
  /* 2026-07-30, third pass: "i still feel like hybrid is too dark lol". The
     one-rung step above was measured and correct against the spec he gave at
     the time ("just slightly") and it still read heavy, so the whole chrome
     family shifts up one FULL step instead of the ground alone — otherwise the
     ground closes on --panel and the rail tiles lose their lift. Every value
     below already exists in this file (#2a2a2a is dark --hover-bg, #303034 and
     #3a3a3a are the next neutral rungs); no new hex. Elevation order holds:
     2a2a2a < 303034 < 3a3a3a. Dark chrome is UNCHANGED and still grounds on
     --max-graphite — hybrid and dark are deliberately different materials
     because each is tuned to the canvas it sits against, not to hex equality. */
  --bg: #2a2a2a;
  --panel: #303034;
  --panel-2: #3a3a3a;
  --border: rgba(255, 255, 255, 0.10);
  --border-subtle: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(255, 255, 255, 0.18);
  --text: var(--max-aluminum);
  --text-dim: #a6a8ad;
  --text-muted: #92949a;
  /* Moves up WITH the ground — at #2a2a2a it would now equal --bg and hover
     would be invisible. */
  --hover-bg: #3a3a3a;
  --sh-1: 0 1px 2px rgba(0,0,0,0.45);
  --sh-2: 0 2px 8px rgba(0,0,0,0.50);
  --sh-3: 0 1px 2px rgba(6,6,7,0.5), 0 3px 6px rgba(6,6,7,0.4), 0 8px 16px rgba(6,6,7,0.32), 0 16px 32px rgba(6,6,7,0.24);
  --sh-4: 0 2px 4px rgba(6,6,7,0.5), 0 6px 12px rgba(6,6,7,0.42), 0 14px 28px rgba(6,6,7,0.34), 0 28px 56px rgba(6,6,7,0.26);
  --edge-highlight: inset 0 1px 0 rgba(255,255,255,0.06);
  /* Semantic-layer surface aliases (see the DESIGN-BIBLE SEMANTIC LAYER block
     below): their :root declarations resolve their var() indirection AT :root
     with light values, so the chrome scope must re-declare them too — the
     values are the dark semantic-layer block's, verbatim. */
  /* Elevated must stay ≥ the ground. It rose with the family on 2026-07-30 —
     at #222226 it would now sit BELOW the #2a2a2a ground and read as a dent. */
  --bg-elevated: #303034;
  --bg-sunken: #060607;
  --text-primary: #f4f4f5;
  /* Departmental palette (2026-07-30 ratification, see :root): hybrid's root is
     data-theme="light", so without this the rail would resolve the LIGHT band —
     values built for a WHITE ground — against a #2a2a2a one. Measured: --dept-used
     would read 1.9:1 there, --dept-reports 1.9:1. The DARK block's values,
     verbatim, exactly as the surface tokens above do it. --dept-service resolves
     through --accent, which this scope does NOT re-declare, so it is named
     literally here rather than left pointing at the light blue. */
  --dept-overview: var(--text);
  --dept-new: #14b8a6;
  --dept-used: #e0890f;
  --dept-service: #4d9fff;
  --dept-parts: #b991ff;
  --dept-bdc: #c9a101;
  --dept-financials: #6bb760;
  --dept-reports: #9ba6bf;
}

/* ============================================================================
   DARK chrome elevation — CHROME IS GRAPHITE IN EVERY THEME (operator-ratified
   2026-07-28, off his dark-mode report: "the sidebar and header just do not
   look separate from the background"). The frame — the workspace sidebar, the
   top bar, the shell footer, and the chrome-owned drawers/portals — is ONE
   material in every theme; only the canvas changes per theme. In dark the
   chrome moves ONE ELEVATION STEP LIGHTER than the #0b0b0c canvas: the ground
   takes --max-graphite and each surface token shifts up one rung of the
   EXISTING dark family (no new hex — every value below already lives in this
   file's dark blocks: #222226 is dark --panel-2, #2a2a2a is dark --hover-bg).
   This is the SAME mechanism as the hybrid chrome scope above — one container
   list, token remap only: in hybrid the scope holds dark values over a light
   canvas; in dark it holds these elevated-graphite values over black. The
   chrome/canvas boundary reads via the existing hairline (--border, carried by
   header border-bottom and --dw-shell-edge) + --edge-highlight. Light
   (non-hybrid) is untouched. HARD RULE unchanged: never add a per-component
   theme style — fix the container list or the component's token usage. */
:root[data-theme="dark"] .dw-shell,
:root[data-theme="dark"] header.app-header,
:root[data-theme="dark"] footer.app-footer,
:root[data-theme="dark"] .gear-menu,
:root[data-theme="dark"] .am-popover,
:root[data-theme="dark"] .ap-side,
:root[data-theme="max"] .dw-shell,
:root[data-theme="max"] header.app-header,
:root[data-theme="max"] footer.app-footer,
:root[data-theme="max"] .gear-menu,
:root[data-theme="max"] .am-popover,
:root[data-theme="max"] .ap-side {
  --bg: var(--max-graphite);   /* chrome ground: one step above the canvas */
  --panel: #222226;            /* the dark --panel-2 rung — footer/drawer panels keep their lift */
  --panel-2: #2a2a2a;          /* the dark --hover-bg rung — rail tiles keep their step off the ground */
  --bg-elevated: #222226;      /* keeps elevated ≥ the new ground (root dark #202024 would sink) */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .dw-shell,
  :root:not([data-theme]) header.app-header,
  :root:not([data-theme]) footer.app-footer,
  :root:not([data-theme]) .gear-menu,
  :root:not([data-theme]) .am-popover,
  :root:not([data-theme]) .ap-side {
    --bg: var(--max-graphite);
    --panel: #222226;
    --panel-2: #2a2a2a;
    --bg-elevated: #222226;
  }
}

/* Store cue: the whole name reads in the store color, bold — the strongest,
   cleanest at-a-glance read (chip + underline both tried and reverted). */
.store-tag {
  font-weight: 700; text-decoration: none;
}
.store-tag.store-buena-park { color: var(--store-buena-park); }
.store-tag.store-carlsbad  { color: var(--store-carlsbad); }
.store-tag.store-redlands  { color: var(--store-redlands); }
/* Short label (BP/CB/RD/GRP) shown on phones; full name on larger screens. */
.store-tag .st-short { display: none; }
@media (max-width: 600px) {
  .store-tag .st-long  { display: none; }
  .store-tag .st-short { display: inline; }
}

/* ============================================================================
   DESIGN-BIBLE SEMANTIC LAYER — extra surfaces / brand-red tints / effects the
   bible component recipes (styles/bible.css + the restyled component classes)
   consume. Resolves per Light/Dark/Auto on top of the palette above. The
   functional blue --accent and the locked store/type/state colors are untouched;
   Energy Red (--user-accent / --brand) is the brand accent.
   ============================================================================ */
:root {
  --bg-elevated: var(--panel);
  --bg-sunken: var(--panel-2);
  --text-primary: var(--text);
  /* Signed period comparisons are small text, so their semantic foregrounds
     must clear AA independently of the larger KPI values. */
  --delta-positive-text: color-mix(in srgb, var(--green) 75%, var(--text-primary));
  --delta-negative-text: var(--red);
  /* ---- THE RATIFIED INVENTORY STATUS PALETTE (operator, 2026-08-01) --------
     ONE mapping, five buckets, and this band is its ONLY source:

       Frontline  green   ·  Recon      orange  ·  Pend Trade  blue
       Transit    purple  ·  Other      grey

     It exists because the mapping used to live in seven places that disagreed:
     Recon printed --red on the inventory pill/stack/tab/recon board and
     --orange on the mix table and one search row (red and orange side by side
     in the SAME row), Transit printed purple in five places and orange in the
     search flags, and Pend Trade had no colour at all except an amber that
     nothing else shared. Every one of those sites now reads a token from here.

     -fill  is the mapping itself, for pill/dot/arc/tab FILLS. Pure aliases of
            existing category tokens, so they re-theme with them and are
            declared once rather than per theme block.
     -text  is the same mapping as a FOREGROUND. Light's base category colors
            are suitable as fills but several miss AA as text on --bg-sunken,
            so the light companions mix toward ink; dark/MAX aliases back to
            the bright category colors below.
     Recall is deliberately NOT in this band: it is a defect state, not an
     inventory status bucket, and it keeps --red. Recon losing --red is the
     point — a car in recon is a caution, not a failure. */
  --inv-status-frontline-fill: var(--green);
  --inv-status-recon-fill: var(--orange);
  --inv-status-pendtrade-fill: var(--accent);
  --inv-status-transit-fill: var(--transit);
  --inv-status-other-fill: var(--text-muted);
  --inv-status-frontline-text: color-mix(in srgb, var(--green) 75%, var(--text-primary));
  --inv-status-recon-text: color-mix(in srgb, var(--orange) 70%, var(--text-primary));
  --inv-status-pendtrade-text: var(--accent);
  --inv-status-transit-text: color-mix(in srgb, var(--transit) 55%, var(--text-primary));
  --inv-status-other-text: var(--text-muted);
  /* Aging severity is FOREGROUND ONLY (operator, 2026-08-01: "we can just
     color the text instead… I basically never want a bar when it's single-row
     info"). One car's age has no sibling scale, so it never gets a bar and it
     no longer gets a background wash either — the numeral carries the band. */
  --inv-age-fresh-text: var(--text-primary);
  --inv-age-watch-text: color-mix(in srgb, var(--warn) 60%, var(--text-primary));
  --inv-age-risk-text: color-mix(in srgb, var(--orange) 60%, var(--text-primary));
  --inv-age-critical-text: var(--red);
  --brand-subtle: color-mix(in srgb, var(--user-accent) 12%, transparent);
  --brand-muted:  color-mix(in srgb, var(--user-accent) 20%, transparent);
  --brand-border: color-mix(in srgb, var(--user-accent) 42%, transparent);
  --backdrop-glass: saturate(130%) blur(16px);
  --gradient-ember-cta: radial-gradient(70% 120% at 50% 100%, color-mix(in srgb, var(--user-accent) 26%, transparent), transparent 62%);
  --gradient-scrim: linear-gradient(180deg, transparent 0%, rgba(11, 11, 13, 0.85) 100%);
  --gradient-chrome: linear-gradient(145deg, #f4f4f6 0%, #b9b9bf 26%, #65656c 52%, #dadadd 70%, #9a9aa1 100%);
  --edge-highlight: inset 0 1px 0 rgba(255, 255, 255, 0.7);   /* light rim; dark blocks override */
}
:root[data-theme="dark"], :root[data-theme="max"] {
  --bg-elevated: #202024;   /* raised surface — a touch lighter than --panel */
  --bg-sunken: #060607;     /* deepest well */
  --text-primary: #f4f4f5;  /* headline: stepped off pure #fff (2026-07-04) to kill dark-mode halation; still brighter than the silver --text */
  --delta-positive-text: var(--green);
  --delta-negative-text: var(--red);
  --inv-status-frontline-text: var(--green);
  --inv-status-recon-text: var(--orange);
  --inv-status-pendtrade-text: var(--accent);
  --inv-status-transit-text: var(--transit);
  --inv-status-other-text: var(--text-muted);
  --inv-age-fresh-text: var(--text-primary);
  --inv-age-watch-text: var(--warn);
  --inv-age-risk-text: var(--orange);
  --inv-age-critical-text: var(--red);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg-elevated: #202024;
    --bg-sunken: #060607;
    --text-primary: #f4f4f5;
    --delta-positive-text: var(--green);
    --delta-negative-text: var(--red);
    --inv-status-frontline-text: var(--green);
    --inv-status-recon-text: var(--orange);
    --inv-status-pendtrade-text: var(--accent);
    --inv-status-transit-text: var(--transit);
    --inv-status-other-text: var(--text-muted);
    --inv-age-fresh-text: var(--text-primary);
    --inv-age-watch-text: var(--warn);
    --inv-age-risk-text: var(--orange);
    --inv-age-critical-text: var(--red);
  }
}

/* ============================================================================
   CHART SERIES BAND — App.chart (shared/chart.js + styles/chart.css)
   ----------------------------------------------------------------------------
   Four tokens, no more. Every other chart tone reuses a token that already
   exists (store identity, --green/--red, --dept-new, --fctp).

     --dv-series  the DEFAULT series fill. An ALIAS, not a new hue: it is the
                  surface's own data cadence. This is the mechanism that stops
                  series colour becoming a third accent system — a default
                  series has no colour of its own at all, so it inherits the
                  ratified Overview exception instead of restating it.
     --dv-track   the unfilled bar/donut rail. Held to 1.4-2.4:1 against BOTH
                  --bg and --panel: perceivable as a container, never
                  mistakable for a filled datum.
     --dv-other   the folded remainder / "Other". A neutral, never a category.
     --dv-amber   the chart-band amber BOTH 'warn' and 'used' resolve to. Light
                  is darkened off --warn #c9821a (2.93:1 on --bg, under the 3.0
                  non-text floor) to #b17217 (3.71:1); dark needs no
                  correction. Same precedent as --dept-new #00786c, which
                  exists because --new is 2.49:1 on white.

   Solved numerically against WCAG 2.1 relative luminance, not eyeballed:
   fill vs surface >= 3.0:1 (SC 1.4.11), track vs surface 1.4-2.4:1, fill vs
   track >= 2.5:1. The extent of a bar is never carried by the fill/track hue
   step alone — the track is a bounded rail and the exact value is mandatory
   beside every mark (see shared/chart.js).
   ========================================================================= */
:root {
  --dv-series: var(--accent);
  --dv-track: #d1d3d4;
  --dv-other: #808187;
  --dv-amber: #b17217;
}
:root[data-theme="dark"], :root[data-theme="max"] {
  --dv-track: #343438;
  --dv-other: #8a8c93;
  --dv-amber: #e0a83a;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --dv-track: #343438;
    --dv-other: #8a8c93;
    --dv-amber: #e0a83a;
  }
}
/* The ONE ratified data-cadence exception (STYLE.md 2.1): on the Overview
   board the data cadence is Energy Red. Charts follow the surface they are on;
   they never carry a cadence decision of their own. */
.ov-body { --dv-series: var(--data-accent); }
