/* ============================================================================
   theme.css — THIS IS THE FILE TO EDIT TO RESTYLE THE DASHBOARD.

   Every colour, size, radius, font and shadow in the whole dashboard is
   declared here as a custom property. app.css contains layout and component
   structure and references these tokens only; it never names a colour or a
   pixel font-size directly. So a redesign is a change to this file, and the
   markup and JavaScript do not move.

   The palette is the validated reference set: eight categorical hues in a
   fixed order that clears the colour-blind separation gates in both light and
   dark mode, plus a reserved four-colour status set. Do not reorder the
   categorical slots — the order IS the safety mechanism; slot 4 beside slot 2
   is the pair that was measured. If you swap in your own hues, re-run the
   palette validator rather than eyeballing them.
   ========================================================================= */

:root {
  color-scheme: light;

  /* --- surfaces & ink ---------------------------------------------------- */
  --plane: #f9f9f7;         /* the page behind everything */
  --surface: #fcfcfb;       /* cards, tables, the filter bar */
  --surface-sunk: #f2f2ef;  /* wells: inputs, table headers, chips */
  --ink: #0b0b0b;
  --ink-2: #52514e;         /* secondary text */
  --ink-muted: #898781;     /* axis labels, timestamps, units */
  --rule: #e1e0d9;          /* hairlines between rows */
  --edge: rgba(11, 11, 11, 0.10);
  --shadow: 0 1px 2px rgba(11, 11, 11, 0.06), 0 4px 16px rgba(11, 11, 11, 0.05);
  --focus: #2a78d6;

  /* --- status ------------------------------------------------------------
     Reserved. Never reused as a category colour. Always shipped with a glyph
     and a number beside them, never carrying meaning on their own — which is
     also what lets gain/loss use the conventional green/red here instead of
     the blue/red diverging pair: the arrow and the figure carry it. */
  --good: #0ca30c;
  --good-ink: #006300;      /* the same signal as text, for contrast on light */
  --warning: #fab219;
  --serious: #ec835a;
  --critical: #d03b3b;
  --critical-ink: #b02c2c;
  --good-wash: #e7f5e7;
  --critical-wash: #fbeaea;

  /* --- categorical slots -------------------------------------------------
     Assigned to user-made categories by creation order and never recycled by
     rank, so filtering the table cannot repaint a category. Past slot 8 a
     category falls back to --cat-x and is told apart by its name, which is
     printed on every chip anyway. */
  --cat-1: #2a78d6;  /* blue */
  --cat-2: #eb6834;  /* orange */
  --cat-3: #1baf7a;  /* aqua */
  --cat-4: #eda100;  /* yellow */
  --cat-5: #e87ba4;  /* magenta */
  --cat-6: #008300;  /* green */
  --cat-7: #4a3aa7;  /* violet */
  --cat-8: #e34948;  /* red */
  --cat-x: #898781;  /* ninth onwards */

  /* --- magnitude ---------------------------------------------------------
     One hue, light to dark, for the share-of-calls bars. Sequential encoding
     is a single hue by definition; a rainbow here would imply categories that
     do not exist. */
  --bar: #86b6ef;
  --bar-strong: #2a78d6;
  --bar-track: #eceae4;

  /* The win bands in the donut, deepening with magnitude. Steps 250-650 of the
     same blue ramp: an ordered quantity gets an ordered ramp, not five
     unrelated hues, which would imply five unrelated things. Step 250 is the
     documented floor for ordinal use on a light surface — anything lighter
     stops separating from the paper. Losses do not take a ramp step; they take
     the reserved --critical, because "went wrong" is a different kind of fact
     from "went right by this much". */
  --win-1: #86b6ef;
  --win-2: #5598e7;
  --win-3: #2a78d6;
  --win-4: #1c5cab;
  --win-5: #104281;

  /* --- type --------------------------------------------------------------- */
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --fs-hero: 1.75rem;
  --fs-lg: 1.0625rem;
  --fs-md: 0.875rem;
  --fs-sm: 0.8125rem;
  --fs-xs: 0.75rem;

  /* --- metrics ------------------------------------------------------------ */
  --gap: 0.75rem;
  --gap-lg: 1.25rem;
  --pad: 0.875rem;
  --radius: 10px;
  --radius-sm: 6px;
  --radius-pill: 999px;
  --row-h: 2.25rem;
  --control-h: 2rem;

  /* Below this the tables become stacked cards. Change it in one place. */
  --mobile: 900px;
}

/* The dark values are declared twice on purpose: the media query follows the
   operating system, the [data-theme] block is the manual toggle, and the
   toggle has to win in both directions. :where() keeps the media block at zero
   specificity so [data-theme="dark"] beats it, and the :not() means an
   explicit "light" choice survives an OS set to dark.

   These are re-stepped for the dark surface, not flipped. */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    --plane: #0d0d0d;
    --surface: #1a1a19;
    --surface-sunk: #242422;
    --ink: #ffffff;
    --ink-2: #c3c2b7;
    --ink-muted: #898781;
    --rule: #2c2c2a;
    --edge: rgba(255, 255, 255, 0.10);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 4px 16px rgba(0, 0, 0, 0.35);
    --focus: #3987e5;

    --good-ink: #0ca30c;
    --critical-ink: #e66767;
    --good-wash: #122a12;
    --critical-wash: #2e1515;

    --cat-1: #3987e5;
    --cat-2: #d95926;
    --cat-3: #199e70;
    --cat-4: #c98500;
    --cat-5: #d55181;
    --cat-6: #008300;
    --cat-7: #9085e9;
    --cat-8: #e66767;

    --bar: #256abf;
    --bar-strong: #3987e5;
    --bar-track: #2c2c2a;

    /* Re-stepped for the dark surface, not flipped: on dark the ramp runs the
       other way, and step 600 is the documented floor before it stops
       separating from the background. */
    --win-1: #9ec5f4;
    --win-2: #6da7ec;
    --win-3: #3987e5;
    --win-4: #256abf;
    --win-5: #184f95;
  }
}
:root[data-theme="dark"] {
  --plane: #0d0d0d;
  --surface: #1a1a19;
  --surface-sunk: #242422;
  --ink: #ffffff;
  --ink-2: #c3c2b7;
  --ink-muted: #898781;
  --rule: #2c2c2a;
  --edge: rgba(255, 255, 255, 0.10);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 4px 16px rgba(0, 0, 0, 0.35);
  --focus: #3987e5;

  --good-ink: #0ca30c;
  --critical-ink: #e66767;
  --good-wash: #122a12;
  --critical-wash: #2e1515;

  --cat-1: #3987e5;
  --cat-2: #d95926;
  --cat-3: #199e70;
  --cat-4: #c98500;
  --cat-5: #d55181;
  --cat-6: #008300;
  --cat-7: #9085e9;
  --cat-8: #e66767;

  --bar: #256abf;
  --bar-strong: #3987e5;
  --bar-track: #2c2c2a;

  --win-1: #9ec5f4;
  --win-2: #6da7ec;
  --win-3: #3987e5;
  --win-4: #256abf;
  --win-5: #184f95;
}
