/* ═══════════════════════════════════════════════════════════════════════════
   ROSHEN KSA — CANONICAL DESIGN TOKENS
   ═══════════════════════════════════════════════════════════════════════════

   The single scale every surface in this product draws from. Before this file
   the platform shipped nine independent palettes: five different brand accents
   (#4F46E5, #C2263B, #B01C2E, #C41230, #B01116), six page backgrounds, five
   text inks and five border greys — each page having reinvented the same
   decisions slightly differently.

   The values below are the `--bi-*` set from index.html, which is the most
   recent and the only accessibility-tuned one ("Indigo-on-slate SaaS, adopted
   2026"). Nothing here is a new colour: this file is where those values now
   live, and every other page points at them.

   ── How pages consume this ─────────────────────────────────────────────────
   Satellite pages link this file and then declare a short BRIDGE block that
   re-points their own historical token names at the canonical ones:

       <link rel="stylesheet" href="../src/styles/tokens.css?v=1">
       :root { --accent: var(--bi-accent); --card: var(--bi-surface); ... }

   That keeps every existing selector and every piece of markup untouched — the
   names a page already uses keep working, they just resolve to shared values.
   It is also trivially revertible: delete the bridge, restore the old literals.

   ── index.html is deliberately NOT linked to this file ─────────────────────
   The main shell keeps its own inline copy of these tokens. It has to: it is a
   no-build single file that must also survive being saved as a self-contained
   "Save & Share" bundle, where an external stylesheet would not travel with it
   and the app would render unstyled. To stop the two copies drifting — the
   exact failure this file exists to end — `scripts/smoke/validate-design-tokens.mjs`
   parses both and fails CI on any divergence.

   ── Theming ────────────────────────────────────────────────────────────────
   Light is the default on :root. Dark is opt-in via [data-theme="dark"] on
   <html>, matching how index.html already persists the user's choice. Pages
   that are light-only (print/report surfaces) simply never set the attribute
   and inherit light.

   Changing a colour here changes it everywhere. That is the point.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Typography ─────────────────────────────────────────────────────────
     Inter FIRST on every surface, so the platform renders in one face on
     every OS instead of falling back to Segoe/system while Inter loads. */
  --bi-font: 'Inter', 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', Arial, sans-serif;
  --bi-font-num: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --bi-font-mono: 'SF Mono', ui-monospace, 'Cascadia Code', Consolas, monospace;
  /* Arabic-bearing surfaces (catalogue, RTL views) need the Naskh fallback in
     the stack or Arabic drops to a system face mid-paragraph. */
  --bi-font-ar: 'Inter', 'Segoe UI', system-ui, 'Noto Naskh Arabic', 'Noto Sans Arabic', Arial, sans-serif;
  --bi-font-size: 13.5px;
  --bi-line: 1.45;

  /* ── Radii ──────────────────────────────────────────────────────────────
     Pages had shipped 6/7/8/10/12/14/16px. Three steps + a pill cover every
     real use; the aliases below map the old names onto them. */
  --bi-radius-sm: 8px;
  --bi-radius: 8px;
  --bi-radius-lg: 12px;
  --bi-radius-xl: 16px;
  --bi-radius-pill: 999px;

  /* ── Spacing ────────────────────────────────────────────────────────────
     A 4px scale. --bi-gap / --bi-pad are the component defaults index.html
     already used and are kept as the named aliases. */
  --bi-space-1: 4px;
  --bi-space-2: 8px;
  --bi-space-3: 12px;
  --bi-space-4: 16px;
  --bi-space-5: 20px;
  --bi-space-6: 24px;
  --bi-gap: 12px;
  --bi-pad: 16px;
  /* Minimum comfortable touch target — the mobile viewport in the UI guard
     fails controls smaller than this. */
  --bi-tap: 44px;
  --bi-gutter: clamp(14px, 2.4vw, 26px);

  /* ── Motion ─────────────────────────────────────────────────────────────*/
  --bi-dur: .16s;
  --bi-ease: cubic-bezier(.4, 0, .2, 1);

  /* ══ LIGHT THEME ══════════════════════════════════════════════════════ */

  /* Surfaces, back to front. --bi-canvas sits behind the page, --bi-page is
     the page itself, --bi-surface is a card, --bi-surface-2/3 are the raised
     and inset fills inside one. */
  --bi-page: #F6F7F9;
  --bi-canvas: #EEF1F6;
  --bi-surface: #FFFFFF;
  --bi-surface-2: #F1F5F9;
  --bi-surface-3: #E9EDF3;
  --bi-border: #E2E8F0;
  --bi-border-strong: #CBD5E1;

  /* Text. --bi-text-muted is #5F6F84 rather than the more obvious #64748B:
     that lighter slate measures 4.37:1 on the panel surface it is used over,
     just under AA. This one clears 4.7:1 there and is still clearly lighter
     than --bi-text-sec. */
  --bi-text: #0F172A;
  --bi-text-sec: #475569;
  --bi-text-muted: #5F6F84;
  --bi-text-faint: #94A3B8;
  /* Text that sits ON --bi-accent. */
  --bi-text-on-accent: #FFFFFF;

  /* Brand accent — ROSHEN burgundy, AAA on white. --bi-accent-rgb exists so
     pages can build accent-tinted shadows and washes at any alpha —
     rgba(var(--bi-accent-rgb), .28) — instead of hard-coding the channels,
     which is how the old per-page reds leaked into box-shadows and gradients
     long after the :root literal was changed.

     #8C1526 rather than the brand's own #4F0000: the base is the right colour
     for a full-bleed brand moment (the login hero uses it, and --bi-accent-deep
     below IS it), but as the working UI accent it is so near black that a page
     of buttons and active states reads as mourning stationery. This is the same
     hue two steps up — unmistakably the brand, 9.33:1 on white, and far enough
     from --bi-neg #DC2626 (4.83:1) that a primary action never reads as a
     destructive one. */
  --bi-accent: #8C1526;
  --bi-accent-rgb: 140, 21, 38;
  /* Near-flat, and deliberately so. This token feeds the FAB, the export
     actions and every other primary fill; as a 135deg two-tone from #8C1526 to
     #4F0000 it read as a glossy button from another decade. A 6% vertical
     step gives a solid fill just enough depth to look intentional. */
  --bi-accent-grad: linear-gradient(180deg, #8C1526 0%, #7C1121 100%);
  --bi-accent-hover: #6E0F1D;
  --bi-accent-deep: #4F0000;   /* darkest stop — full-bleed covers and hero bands */
  --bi-accent-soft: rgba(140, 21, 38, 0.09);
  --bi-accent-soft-2: rgba(140, 21, 38, 0.14);   /* stronger tint: selected rows, focus fills */
  --bi-accent-softer: rgba(140, 21, 38, 0.05);
  --bi-accent-wash: #FBF1F2;                     /* opaque wash for banded/zebra brand fills */

  /* Status. Each has a soft companion for chip/badge fills. */
  --bi-blue: #0284C7;
  --bi-blue-soft: rgba(2, 132, 199, 0.10);
  --bi-pos: #16A34A;
  --bi-pos-soft: rgba(22, 163, 74, 0.10);
  --bi-neg: #DC2626;
  --bi-neg-soft: rgba(220, 38, 38, 0.09);
  --bi-warn: #D97706;
  --bi-warn-soft: rgba(217, 119, 6, 0.10);

  /* Theme-safe soft fill for hovers and zebra rows — darkens in light,
     lightens in dark, so a single rule works in both. */
  --overlay-soft: rgba(15, 23, 42, 0.045);
  --bi-stripe: rgba(15, 23, 42, 0.02);
  /* Native date-picker glyph: dark themes must invert it or it vanishes. */
  --bi-cal-filter: none;
  /* Translucent chrome. A sticky masthead that hard-codes rgba(255,255,255,…)
     stays white in dark mode and the page looks broken, so the glass fill is a
     token like everything else. --bi-shimmer is the skeleton-loader sweep. */
  --bi-glass: rgba(255, 255, 255, 0.82);
  --bi-shimmer: rgba(255, 255, 255, 0.65);

  /* Elevation. 1 = resting card, 2 = raised/hover, modal = dialog. */
  --bi-shadow-1: 0 1px 2px rgba(15, 23, 42, 0.05), 0 1px 3px rgba(15, 23, 42, 0.04);
  --bi-shadow-2: 0 2px 4px rgba(15, 23, 42, 0.05), 0 6px 16px rgba(15, 23, 42, 0.06);
  --bi-shadow-modal: 0 12px 32px rgba(15, 23, 42, 0.14);

  /* Focus ring — the one visible-focus treatment for the whole platform. */
  --bi-focus: 0 0 0 3px rgba(140, 21, 38, 0.32);

  /* Chart series — the categorical scale, blue-led, restrained, CVD-aware.
     These ten ARE the colours the dashboard has been drawing with: they were
     living inside PREMIUM_DS_CSS, a stylesheet injected from a JS string after
     sign-in, where no file-reading guard could see them. Moving them here did
     not change a single chart — validate-runtime-tokens.mjs proves that by
     measuring a signed-in browser. The legacy --c-* names now resolve to them.

     Ten, not eight, because the legacy set had ten names and collapsing two of
     them would have made two series share a colour. */
  --bi-series-1: #2563EB;   /* blue    (--c-blue)    */
  --bi-series-2: #0EA5A4;   /* teal    (--c-teal)    */
  --bi-series-3: #6366F1;   /* purple  (--c-purple)  */
  --bi-series-4: #E08600;   /* orange  (--c-orange)  */
  --bi-series-5: #16A34A;   /* green   (--c-green)   */
  --bi-series-6: #8B5CF6;   /* magenta (--c-magenta) */
  --bi-series-7: #0891B2;   /* cyan    (--c-cyan)    */
  --bi-series-8: #E11D48;   /* pink    (--c-pink)    */
  --bi-series-9: #CA8A04;   /* yellow  (--c-yellow)  */
  --bi-series-10: #DC2626;  /* red     (--c-red)     */
  --bi-chart-track: #E2E8F0;

  /* ── Document surface ───────────────────────────────────────────────────
     The Memorandum of Development Action Plan renders as a page, not a screen,
     and had grown its own warm cream/gold palette (--paper/--gold/--wine).
     Those names now live here and resolve to the platform scale, so the
     document preview is the same product as the rest of the app.

     The two serif faces DO survive, because they are content typography
     rather than UI: a memorandum set in Inter reads as a web page, and the
     printed output is Arial 11pt regardless (the @media print block in
     development-plan.css hard-codes it to match the Word reference). */
  --bi-font-display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --bi-font-doc: Georgia, 'Times New Roman', serif;
  --bi-doc-paper: #FFFFFF;
  --bi-doc-paper-2: #F1F5F9;
  --bi-doc-edge: #E2E8F0;
  --bi-doc-edge-2: #CBD5E1;
  --bi-doc-accent: #8C1526;
  --bi-doc-accent-deep: #4F0000;
  --bi-doc-accent-tint: #FBF1F2;
}

/* ══ DARK THEME ═════════════════════════════════════════════════════════
   Linear-style blue-slate. Never pure black: #000 surfaces make elevation
   unreadable and halo against light text on OLED. */
[data-theme="dark"] {
  --bi-page: #0E1117;
  --bi-canvas: #0A0D12;
  --bi-surface: #161B26;
  --bi-surface-2: #1C2230;
  --bi-surface-3: #212A36;
  --bi-border: #242B3A;
  --bi-border-strong: #303950;

  --bi-text: #E6EAF2;
  --bi-text-sec: #B4BCCC;
  /* #8B94A7 measured 4.47:1 on --bi-surface — a hair under AA, and three real
     controls landed on it. #949DB0 is the same slate at 5.0:1 there. */
  --bi-text-muted: #949DB0;
  --bi-text-faint: #64748B;
  --bi-text-on-accent: #FFFFFF;

  /* The burgundy has to come UP to survive a dark surface, and the binding
     constraint is the one the old indigo was tuned against: white text on a
     solid accent fill (buttons, the avatar seal) must clear AA. #C2495A puts it
     at 4.78:1 — better than the #6265EF it replaces (4.54:1) — while reading
     3.95:1 against the page, which is the same ballpark as that indigo's 4.16:1.
     Go lighter and white stops clearing; go darker and the accent disappears
     into the surface. */
  --bi-accent: #C2495A;
  --bi-accent-rgb: 194, 73, 90;
  --bi-accent-grad: linear-gradient(180deg, #C2495A 0%, #B23F50 100%);
  --bi-accent-hover: #D97684;
  --bi-accent-deep: #8C1526;
  --bi-accent-soft: rgba(194, 73, 90, 0.14);
  --bi-accent-soft-2: rgba(194, 73, 90, 0.22);
  --bi-accent-softer: rgba(194, 73, 90, 0.08);
  --bi-accent-wash: rgba(194, 73, 90, 0.16);

  --bi-blue: #38BDF8;
  --bi-blue-soft: rgba(56, 189, 248, 0.16);
  --bi-pos: #4ADE80;
  --bi-pos-soft: rgba(74, 222, 128, 0.16);
  --bi-neg: #F87171;
  --bi-neg-soft: rgba(248, 113, 113, 0.16);
  --bi-warn: #FBBF24;
  --bi-warn-soft: rgba(251, 191, 36, 0.16);

  --overlay-soft: rgba(255, 255, 255, 0.05);
  --bi-stripe: rgba(255, 255, 255, 0.02);
  --bi-cal-filter: invert(0.85);
  --bi-glass: rgba(22, 27, 38, 0.82);
  --bi-shimmer: rgba(255, 255, 255, 0.08);

  --bi-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.35);
  --bi-shadow-2: 0 2px 6px rgba(0, 0, 0, 0.35), 0 8px 20px rgba(0, 0, 0, 0.28);
  --bi-shadow-modal: 0 16px 40px rgba(0, 0, 0, 0.55);

  --bi-focus: 0 0 0 3px rgba(194, 73, 90, 0.45);

  /* Series lightened for dark surfaces — the light-theme values sit at
     roughly 2:1 on #161B26 and read as muddy. Same provenance as the light
     set: these are the values the dashboard already drew in dark mode. */
  --bi-series-1: #60A5FA;
  --bi-series-2: #2DD4BF;
  --bi-series-3: #818CF8;
  --bi-series-4: #FBBF24;
  --bi-series-5: #34D399;
  --bi-series-6: #A78BFA;
  --bi-series-7: #22D3EE;
  --bi-series-8: #FB7185;
  --bi-series-9: #FCD34D;
  --bi-series-10: #F87171;
  --bi-chart-track: #242B3A;
}

/* ══ PRINT ══════════════════════════════════════════════════════════════
   Paper has no theme. Printing from dark mode used to put near-black cards
   (luminance 22) behind black text — every KPI tile and every table cell on
   the page came out unreadable, because the print rules reset <body> but the
   surfaces kept reading --bg-card.

   Flattening the TOKENS rather than chasing selectors fixes it once for
   everything that reads them. Surfaces go white, ink goes black, elevation
   disappears; the accent and the categorical series survive, so a printed
   chart is still legible and still branded.

   Pages with their own hand-tuned print block (the memorandum, quote.html,
   report.html) hard-code their values and are unaffected by this — their
   parity tests still pass byte-for-byte. */
@media print {
  /* The selector list is not decoration. The runtime layers declare their dark
     tokens on `:root:not([data-theme="light"])`, which is specificity (0,2,0);
     a plain `:root` reset is (0,1,0) and loses to it no matter how late it
     appears — which is exactly how the first attempt at this failed, silently.
     Matching their strongest selector puts this on equal footing, and being
     later in the document decides the tie. */
  :root,
  [data-theme="light"],
  [data-theme="dark"],
  :root:not([data-theme="light"]) {
    --bi-page: #FFFFFF;
    --bi-canvas: #FFFFFF;
    --bi-surface: #FFFFFF;
    --bi-surface-2: #FFFFFF;
    --bi-surface-3: #FFFFFF;
    --bi-border: #9AA3B2;
    --bi-border-strong: #6B7280;
    --bi-text: #000000;
    --bi-text-sec: #1F2937;
    --bi-text-muted: #374151;
    --bi-text-faint: #4B5563;
    --bi-shadow-1: none;
    --bi-shadow-2: none;
    --bi-shadow-modal: none;
    --overlay-soft: transparent;
    --bi-stripe: transparent;
    --bi-chart-track: #D1D5DB;
    /* the legacy names index.html's own components still read */
    --bg-deep: #FFFFFF;
    --bg-card: #FFFFFF;
    --bg-card-hover: #FFFFFF;
    --bg-elevated: #FFFFFF;
    --bg-input: #FFFFFF;
    --bg-subtle: #FFFFFF;
    --border: #9AA3B2;
    --border-light: #C7CDD6;
    --border-strong: #6B7280;
    --text-primary: #000000;
    --text-secondary: #1F2937;
    --text-muted: #374151;
    --table-stripe: transparent;
    --hover-overlay: transparent;
    --shadow: none;
    --shadow-sm: none;
  }
}

/* ── A note on the document surfaces ──────────────────────────────────────
   The print block above flattens the SCREEN surfaces. It deliberately does not
   touch the printing surfaces that already carry a hand-tuned @media print
   block of their own — the memorandum, report.html, quote.html — because those
   hard-code ink, paper and rules to match a Word/PDF reference byte-for-byte,
   and two CI parity tests hold them to it. Their rules are more specific and
   come later, so they win; this reset only reaches what they leave alone. */
