/*
 * The design tokens (Phase 19), moved out of index.html on 2026-09-29 so the utilities' pages
 * under /utils draw from the same file as the shell. Nothing here changed in the move: the
 * webfonts, the three token layers, the dark steps under both the OS setting and the theme
 * toggle, and the narrow gutter. The shell's own rules — box-sizing, body, print — stay inline.
 */
/* BrandExtract webfonts, self-hosted (public/fonts): Public Sans for UI and headings,
   Space Grotesk for eyebrows and captions. Same faces as Ziggy, so the two tools read
   as one family. */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/public-sans.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/space-grotesk.woff2') format('woff2');
}

/*
 * ---------------------------------------------------------------------------------------
 * Design tokens (Phase 19)
 * ---------------------------------------------------------------------------------------
 * Three layers, in this order:
 *   1. Brand scales    the BrandExtract palette, transcribed from the Figma style guide.
 *                      Never used directly by a component; semantic aliases point at them.
 *   2. Semantic tokens surfaces, ink, borders, controls. Defined light first, then
 *                      redefined for dark under both the OS setting and the theme toggle.
 *   3. Encoding tokens the chart vocabulary PRD 7.3 reserves: project-type hues (seven
 *                      plus Other), the four status colours, and the chart chrome. Every
 *                      value here was chosen with the data-viz validator, not by eye; see
 *                      Design Documents/UI Client.md for the runs and the numbers.
 *
 * Dark is a selected palette, not an inversion: each hue has its own dark step, chosen
 * for the dark surface and validated as a set.
 */
:root {
  /* --- Eggplant (primary brand) --- */
  --eggplant-50: #f1eef7;
  --eggplant-100: #e4dcef;
  --eggplant-200: #c8b9df;
  --eggplant-300: #ad97ce;
  --eggplant-400: #9274be;
  --eggplant-500: #33234b; /* Primary */
  --eggplant-600: #5f418b;
  --eggplant-700: #473168;
  --eggplant-800: #2a1d3f;
  --eggplant-900: #181023;

  /* --- Sky Blue (secondary) --- */
  --sky-50: #e8f5fc;
  --sky-100: #d2ebf9;
  --sky-200: #a5d8f3;
  --sky-300: #77c4ee;
  --sky-400: #4ab1e8;
  --sky-500: #177cb3; /* Primary */
  --sky-600: #177eb5;
  --sky-700: #115e88;
  --sky-800: #0c3f5a;
  --sky-900: #061f2d;

  /* --- Chartreuse (accent / CTA) --- */
  --chartreuse-bg: #f9faea;
  --chartreuse-100: #f3f6d5;
  --chartreuse-200: #e7edab;
  --chartreuse-300: #dbe481;
  --chartreuse-400: #d0db57;
  --chartreuse-500: #c5d230; /* Primary */
  --chartreuse-600: #9da824;
  --chartreuse-700: #757e1b;
  --chartreuse-800: #4e5412;
  --chartreuse-900: #272a09;

  /* --- Neutral --- */
  --white: #ffffff;
  --neutral-50: #f2f2f2;
  --neutral-100: #e6e6e6;
  --neutral-200: #cccccc;
  --neutral-300: #b3b3b3;
  --neutral-400: #999999;
  --neutral-500: #808080;
  --neutral-600: #666666;
  --neutral-700: #4d4d4d;
  --neutral-800: #333333;
  --neutral-900: #1a1a1a;
  --neutral-950: #0d0d0d;

  /* --- Typography --- */
  --font-sans:
    'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
    sans-serif;
  --font-eyebrow: 'Space Grotesk', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  /* --- Shape --- */
  --radius-sm: 2px;
  --radius-card: 10px;
  --radius-pill: 999px;
  --shadow-card: 0 1px 2px rgba(51, 35, 75, 0.06), 0 8px 24px rgba(51, 35, 75, 0.08);
  --shadow-menu: 0 10px 40px rgba(51, 35, 75, 0.22);
  --page-max: 1600px;
  --page-gutter: 28px;

  /* ----- Semantic: light ----- */
  color-scheme: light;
  --page: var(--neutral-50);
  --surface: var(--white);
  --surface-2: #f9f9f7;
  --surface-sunken: #eceaf1;
  --ink: var(--neutral-800);
  --ink-strong: var(--eggplant-500);
  --ink-muted: var(--neutral-600);
  --ink-faint: #898781;
  --ink-on-brand: var(--neutral-50);
  --border: var(--neutral-200);
  --border-soft: var(--neutral-100);
  --bar: var(--eggplant-500); /* app bar */
  --bar-ink: var(--neutral-50);
  --accent: var(--chartreuse-500);
  --accent-ink: var(--eggplant-500);
  --link: var(--eggplant-600);
  --focus: var(--sky-500);
  --control-bg: var(--white);
  --control-border: #d9d9d9;

  /* ----- Encoding: project-type hues, light steps -----
     Fixed order, assigned by open-project volume and never re-assigned when a filter
     removes a type (PRD 7.3). Validated adjacent-pair: worst CVD ΔE 9.2, worst
     normal-vision ΔE 19.6 on white. Aqua (2.82:1) and magenta (2.69:1) sit below 3:1
     on the light surface, so every chart that uses them ships a legend, direct labels,
     and the table view. */
  --type-1: #2a78d6; /* blue */
  --type-2: #eb6834; /* orange */
  --type-3: #1baf7a; /* aqua */
  --type-4: #4a3aa7; /* violet */
  --type-5: #eda100; /* yellow */
  --type-6: #e87ba4; /* magenta */
  --type-7: #008300; /* green */
  --type-other: #898781; /* Other: the one neutral slot */

  /* ----- Encoding: status, light steps -----
     Reserved (PRD 7.3): never a project type, never a series. Green and red cannot be
     separated by hue under deuteranopia at any usable pair of steps, so these were
     picked for lightness separation (worst all-pairs CVD ΔE 11.3) and every use pairs
     the colour with an icon and a label. */
  --status-healthy: #0ca30c;
  --status-caution: #fab219;
  --status-overloaded: #a81f1f;
  --status-underload: #6d7f8f;
  --status-healthy-tint: #e8f6e8;
  --status-caution-tint: #fdf3dd;
  --status-overloaded-tint: #f8e7e6;
  --status-underload-tint: #eceff2;
  /* Ink for text drawn ON a solid status colour (the heatmap's cells, Phase 23). Chosen
     for contrast against each step: dark ink clears 4.2:1 on under-utilized, 5.2:1 on
     healthy and 9.5:1 on caution; only overloaded is dark enough for white (7.3:1). */
  --status-healthy-ink: var(--neutral-900);
  --status-caution-ink: var(--neutral-900);
  --status-overloaded-ink: #ffffff;
  --status-underload-ink: var(--neutral-900);

  /* ----- Encoding: chart chrome ----- */
  --grid: #e1e0d9;
  --axis: #c3c2b7;
  --tick-ink: #6f6d68;
  --plot-bg: transparent;
  --tooltip-bg: var(--eggplant-500);
  --tooltip-ink: var(--neutral-50);
  --hatch-ink: rgba(255, 255, 255, 0.72); /* pattern strokes drawn over a type fill */
  --dot-ink: rgba(255, 255, 255, 0.82);
}

/* Dark: same tokens, dark steps. Declared twice on purpose — once for the OS setting
   (guarded so an explicit light choice still wins) and once for the theme toggle. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    color-scheme: dark;
    --page: #12101a;
    --surface: #1b1626;
    --surface-2: #241e31;
    --surface-sunken: #171222;
    --ink: #ece8f3;
    --ink-strong: #f6f3fb;
    --ink-muted: #b3abc4;
    --ink-faint: #8e86a1;
    --ink-on-brand: #f1eef7;
    --border: #3a3150;
    --border-soft: #2a2339;
    --bar: #221a33;
    --bar-ink: #f1eef7;
    --accent: var(--chartreuse-400);
    --accent-ink: var(--eggplant-900);
    --link: var(--chartreuse-300);
    --focus: var(--sky-300);
    --control-bg: #241e31;
    --control-border: #453b5e;

    --type-1: #3987e5;
    --type-2: #d95926;
    --type-3: #199e70;
    --type-4: #9085e9;
    --type-5: #c98500;
    --type-6: #d55181;
    --type-7: #008300;
    --type-other: #9a92a8;

    --status-healthy: #2fb84f;
    --status-caution: #ffc53d;
    --status-overloaded: #d03b3b;
    --status-underload: #8b9aa8;
    --status-healthy-tint: #16301c;
    --status-caution-tint: #332713;
    --status-overloaded-tint: #331a1a;
    --status-underload-tint: #222733;
    /* On the dark steps: dark ink 7.2:1 healthy, 11.7:1 caution, 6.5:1 under-utilized
       (white would be 2.9:1 there); white 4.8:1 on overloaded. */
    --status-healthy-ink: #12101a;
    --status-caution-ink: #12101a;
    --status-overloaded-ink: #ffffff;
    --status-underload-ink: #12101a;

    --grid: #2e2740;
    --axis: #4a4060;
    --tick-ink: #a59bba;
    --tooltip-bg: #0f0b18;
    --tooltip-ink: #f1eef7;
    --hatch-ink: rgba(10, 8, 16, 0.66);
    --dot-ink: rgba(10, 8, 16, 0.76);
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-menu: 0 10px 40px rgba(0, 0, 0, 0.55);
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;
  --page: #12101a;
  --surface: #1b1626;
  --surface-2: #241e31;
  --surface-sunken: #171222;
  --ink: #ece8f3;
  --ink-strong: #f6f3fb;
  --ink-muted: #b3abc4;
  --ink-faint: #8e86a1;
  --ink-on-brand: #f1eef7;
  --border: #3a3150;
  --border-soft: #2a2339;
  --bar: #221a33;
  --bar-ink: #f1eef7;
  --accent: var(--chartreuse-400);
  --accent-ink: var(--eggplant-900);
  --link: var(--chartreuse-300);
  --focus: var(--sky-300);
  --control-bg: #241e31;
  --control-border: #453b5e;

  --type-1: #3987e5;
  --type-2: #d95926;
  --type-3: #199e70;
  --type-4: #9085e9;
  --type-5: #c98500;
  --type-6: #d55181;
  --type-7: #008300;
  --type-other: #9a92a8;

  --status-healthy: #2fb84f;
  --status-caution: #ffc53d;
  --status-overloaded: #d03b3b;
  --status-underload: #8b9aa8;
  --status-healthy-tint: #16301c;
  --status-caution-tint: #332713;
  --status-overloaded-tint: #331a1a;
  --status-underload-tint: #222733;
  --status-healthy-ink: #12101a;
  --status-caution-ink: #12101a;
  --status-overloaded-ink: #ffffff;
  --status-underload-ink: #12101a;

  --grid: #2e2740;
  --axis: #4a4060;
  --tick-ink: #a59bba;
  --tooltip-bg: #0f0b18;
  --tooltip-ink: #f1eef7;
  --hatch-ink: rgba(10, 8, 16, 0.66);
  --dot-ink: rgba(10, 8, 16, 0.76);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.35);
  --shadow-menu: 0 10px 40px rgba(0, 0, 0, 0.55);
}

@media (max-width: 640px) {
  :root {
    --page-gutter: 16px;
  }
}
