/* prism/tokens.css — the design tokens every Prism component is built from.
 *
 * THE RULE: components style themselves using ONLY the semantic tokens in the
 * "Semantic" sections below. A component must never reference a raw ramp step
 * (--prism-blue-450) or a bare hex. That indirection is what lets an app
 * re-skin the whole library by overriding a dozen variables.
 *
 * Load this once, before any component CSS:
 *   <link rel="stylesheet" href="/prism/tokens.css">
 *
 * THEMING. Dark mode is a *selected* set of steps, not an automatic flip. Both
 * the OS setting and an explicit toggle are honoured, and the toggle wins in
 * both directions:
 *   <html data-theme="dark">   forces dark
 *   <html data-theme="light">  forces light, even when the OS is dark
 *   (no attribute)             follows the OS
 *
 * The colour values are the dataviz reference palette, which is validated for
 * colour-vision-deficiency separation, lightness band and contrast in BOTH
 * modes. If you replace them with brand colours you MUST re-run the validator —
 * see docs/THEMING.md. Do not hand-pick series colours.
 */

:root {
  color-scheme: light;

  /* ============================================================ *
   * RAMPS — raw values. Components never use these directly.
   * ============================================================ */

  /* Blue: the sequential hue, and categorical slot 1. */
  --prism-blue-100: #cde2fb;
  --prism-blue-150: #b7d3f6;
  --prism-blue-200: #9ec5f4;
  --prism-blue-250: #86b6ef;
  --prism-blue-300: #6da7ec;
  --prism-blue-350: #5598e7;
  --prism-blue-400: #3987e5;
  --prism-blue-450: #2a78d6;
  --prism-blue-500: #256abf;
  --prism-blue-550: #1c5cab;
  --prism-blue-600: #184f95;
  --prism-blue-650: #104281;
  --prism-blue-700: #0d366b;

  /* Neutrals. */
  --prism-neutral-000: #ffffff;
  --prism-neutral-025: #fcfcfb;
  --prism-neutral-050: #f9f9f7;
  --prism-neutral-100: #f0efec;
  --prism-neutral-200: #e1e0d9;
  --prism-neutral-300: #c3c2b7;
  --prism-neutral-400: #898781;
  --prism-neutral-600: #52514e;
  --prism-neutral-800: #2c2c2a;
  --prism-neutral-850: #1a1a19;
  --prism-neutral-900: #0d0d0d;
  --prism-neutral-950: #0b0b0b;

  /* ============================================================ *
   * SEMANTIC — surfaces and ink.
   * ============================================================ */

  --prism-surface-page: #f9f9f7;    /* the plane the app sits on */
  --prism-surface-1: #fcfcfb;       /* cards, grid body, chart surface */
  --prism-surface-2: #f0efec;       /* raised: headers, toolbars, menus */
  --prism-surface-sunken: #f0efec;  /* wells, inset areas */
  --prism-surface-hover: rgba(11, 11, 11, 0.04);
  --prism-surface-active: rgba(11, 11, 11, 0.08);
  --prism-surface-selected: #cde2fb;
  --prism-surface-overlay: rgba(11, 11, 11, 0.32);

  --prism-ink-primary: #0b0b0b;
  --prism-ink-secondary: #52514e;
  --prism-ink-muted: #898781;       /* axis labels, placeholders, disabled */
  --prism-ink-on-accent: #ffffff;
  --prism-ink-link: #256abf;

  --prism-border: rgba(11, 11, 11, 0.10);
  --prism-border-strong: #c3c2b7;
  --prism-border-hairline: #e1e0d9; /* gridlines, row rules */

  --prism-accent: #2a78d6;
  --prism-accent-hover: #256abf;
  --prism-accent-subtle: #cde2fb;

  --prism-focus-ring: #2a78d6;
  --prism-focus-ring-width: 2px;
  --prism-focus-ring-offset: 1px;

  /* ============================================================ *
   * SEMANTIC — status. Fixed, never themed, never reused as a
   * series colour. Always shipped with an icon + label so meaning
   * is never carried by colour alone.
   * ============================================================ */

  --prism-status-good: #0ca30c;
  --prism-status-warning: #fab219;
  --prism-status-serious: #ec835a;
  --prism-status-critical: #d03b3b;

  /* Directional value cues — financial cells, deltas, candlesticks.
   * Distinct from status: these encode sign, not state. */
  --prism-value-up: #006300;
  --prism-value-down: #d03b3b;
  --prism-value-flat: #898781;

  /* ============================================================ *
   * SEMANTIC — comparison. What the diff view tints a changed line
   * with, and what it tints the changed words inside it with.
   *
   * The hues are the directional pair above (--prism-value-up /
   * --prism-value-down), lightened to a background tint rather than
   * re-picked, so a green cell in a grid and a green line in a diff
   * are the same idea. The pairs are deliberately far apart in
   * lightness as well as hue — but nothing here is load-bearing on
   * its own: every changed row also carries a literal + or − glyph
   * and a visually-hidden label, because red/green is the single
   * worst colour pair to make meaning depend on.
   *
   * Conflict sides use blue and violet, NOT the add/remove pair:
   * "your version" and "their version" are two alternatives, not a
   * gain and a loss, and reusing green/red would say the wrong
   * thing about which one is the good outcome.
   * ============================================================ */

  --prism-diff-add-bg: #e6f4e6;
  --prism-diff-add-emphasis: #b7e3b7;
  --prism-diff-del-bg: #fbe9e9;
  --prism-diff-del-emphasis: #f5c2c2;

  --prism-diff-conflict-ours-bg: #e3eefc;
  --prism-diff-conflict-theirs-bg: #ece7fa;
  --prism-diff-conflict-border: #c07a10;

  /* ============================================================ *
   * SEMANTIC — data visualisation.
   * Charts are phase 3, but the slots are defined here so a grid
   * badge, a sparkline and a pie chart in the same app agree.
   *
   * CATEGORICAL: assign in fixed order 1..8, by entity, NEVER
   * cycled and NEVER by rank. A 9th series folds into "Other".
   * Slots 1-3 are the only ones safe for all-pairs forms
   * (scatter, bubble, choropleth) — see docs/THEMING.md.
   * ============================================================ */

  --prism-series-1: #2a78d6;  /* blue */
  --prism-series-2: #eb6834;  /* orange */
  --prism-series-3: #1baf7a;  /* aqua */
  --prism-series-4: #eda100;  /* yellow */
  --prism-series-5: #e87ba4;  /* magenta */
  --prism-series-6: #008300;  /* green */
  --prism-series-7: #4a3aa7;  /* violet */
  --prism-series-8: #e34948;  /* red */

  /* SEQUENTIAL: one hue, light -> dark, for continuous magnitude
   * (heat cells, choropleths). For ORDINAL marks start no lighter
   * than step 250 on this surface — below that fails 2:1. */
  --prism-seq-100: #cde2fb;
  --prism-seq-200: #9ec5f4;
  --prism-seq-300: #6da7ec;
  --prism-seq-400: #3987e5;
  --prism-seq-500: #256abf;
  --prism-seq-600: #184f95;
  --prism-seq-700: #0d366b;

  /* DIVERGING: two opposed hues with a NEUTRAL GREY midpoint.
   * Never a hue at the middle, never a rainbow. */
  --prism-diverging-low: #2a78d6;
  --prism-diverging-mid: #f0efec;
  --prism-diverging-high: #d03b3b;

  /* Chart chrome — recessive by design. */
  --prism-chart-surface: #fcfcfb;
  --prism-chart-grid: #e1e0d9;
  --prism-chart-axis: #c3c2b7;

  /* ============================================================ *
   * SPACE — 4px base. Components use these, never bare pixels.
   * ============================================================ */

  --prism-space-0: 0;
  --prism-space-1: 2px;
  --prism-space-2: 4px;
  --prism-space-3: 8px;
  --prism-space-4: 12px;
  --prism-space-5: 16px;
  --prism-space-6: 24px;
  --prism-space-7: 32px;
  --prism-space-8: 48px;

  /* ============================================================ *
   * TYPE — the system sans, everywhere. No display or serif face.
   * ============================================================ */

  --prism-font-sans: system-ui, -apple-system, "Segoe UI", sans-serif;
  --prism-font-mono: ui-monospace, "Cascadia Mono", "Consolas", monospace;

  --prism-text-xs: 11px;
  --prism-text-sm: 12px;
  --prism-text-md: 13px;   /* the data-dense default */
  --prism-text-lg: 15px;
  --prism-text-xl: 20px;
  --prism-text-2xl: 28px;

  --prism-leading-tight: 1.2;
  --prism-leading-normal: 1.45;

  --prism-weight-normal: 400;
  --prism-weight-medium: 500;
  --prism-weight-bold: 600;

  /* Columns that must align vertically get tabular figures. Large
   * standalone numbers keep proportional figures. */
  --prism-figures-tabular: tabular-nums;

  /* ============================================================ *
   * SHAPE, DEPTH, MOTION
   * ============================================================ */

  --prism-radius-sm: 3px;
  --prism-radius-md: 5px;
  --prism-radius-lg: 8px;
  --prism-radius-pill: 999px;

  --prism-shadow-1: 0 1px 2px rgba(11, 11, 11, 0.08);
  --prism-shadow-2: 0 2px 8px rgba(11, 11, 11, 0.12);
  --prism-shadow-3: 0 8px 24px rgba(11, 11, 11, 0.16);

  --prism-duration-fast: 100ms;
  --prism-duration-base: 160ms;
  --prism-duration-slow: 240ms;
  --prism-ease: cubic-bezier(0.2, 0, 0.2, 1);

  /* ============================================================ *
   * LAYERS — one scale, so a grid menu and a chart tooltip in the
   * same app cannot fight.
   * ============================================================ */

  --prism-z-base: 0;
  --prism-z-sticky: 10;     /* pinned rows/columns, sticky headers */
  --prism-z-dropdown: 100;  /* column menus, filter popovers */
  --prism-z-overlay: 200;   /* scrims */
  --prism-z-modal: 300;
  --prism-z-tooltip: 400;   /* always above everything it describes */

  /* ============================================================ *
   * CONTROLS — shared sizing so a grid toolbar button and a chart
   * legend toggle are the same height.
   * ============================================================ */

  --prism-control-height-sm: 24px;
  --prism-control-height-md: 30px;
  --prism-control-height-lg: 36px;
  --prism-control-padding-x: var(--prism-space-4);

  /* Row density. Components read these; a host sets them by putting
   * data-prism-density on any ancestor. */
  --prism-row-height: 32px;
  --prism-row-padding-x: var(--prism-space-4);

  /* One line of compared text. Much tighter than a data row: a diff is
   * read as a block of prose, and grid-height rows would halve how much
   * of it fits on screen. Its own token rather than a calc() inside the
   * component, so density reaches it by plain inheritance — which is
   * also what keeps it working through a shadow boundary. */
  --prism-diff-line-height: 20px;
}

/* Density variants — the grid is the main consumer, but trees, lists
 * and legends honour them too. */
[data-prism-density="compact"] {
  --prism-row-height: 26px;
  --prism-row-padding-x: var(--prism-space-3);
  --prism-diff-line-height: 17px;
}
[data-prism-density="comfortable"] {
  --prism-row-height: 42px;
  --prism-row-padding-x: var(--prism-space-5);
  --prism-diff-line-height: 24px;
}

/* ================================================================ *
 * DARK MODE
 * Selected steps, validated against the dark surface (#1a1a19) —
 * not an inversion of the light values. Declared twice on purpose:
 * the media query follows the OS, the attribute selector follows
 * the app's toggle, and the toggle must be able to win both ways.
 * ================================================================ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --prism-surface-page: #0d0d0d;
    --prism-surface-1: #1a1a19;
    --prism-surface-2: #2c2c2a;
    --prism-surface-sunken: #0d0d0d;
    --prism-surface-hover: rgba(255, 255, 255, 0.06);
    --prism-surface-active: rgba(255, 255, 255, 0.10);
    --prism-surface-selected: #184f95;
    --prism-surface-overlay: rgba(0, 0, 0, 0.56);

    --prism-ink-primary: #ffffff;
    --prism-ink-secondary: #c3c2b7;
    --prism-ink-muted: #898781;
    --prism-ink-on-accent: #ffffff;
    --prism-ink-link: #6da7ec;

    --prism-border: rgba(255, 255, 255, 0.10);
    --prism-border-strong: #383835;
    --prism-border-hairline: #2c2c2a;

    --prism-accent: #3987e5;
    --prism-accent-hover: #5598e7;
    --prism-accent-subtle: #184f95;

    --prism-focus-ring: #5598e7;

    --prism-value-up: #0ca30c;
    --prism-value-down: #e66767;

    /* Selected against #1a1a19, not inverted: a lightened tint of the
     * light-mode value would glow, and the emphasis step has to stay
     * clearly darker than the ink that sits on it. */
    --prism-diff-add-bg: #16301c;
    --prism-diff-add-emphasis: #1f5a2c;
    --prism-diff-del-bg: #3a1a1c;
    --prism-diff-del-emphasis: #6b2229;

    --prism-diff-conflict-ours-bg: #16283f;
    --prism-diff-conflict-theirs-bg: #241f45;
    --prism-diff-conflict-border: #e0a54a;

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

    --prism-diverging-mid: #383835;

    --prism-chart-surface: #1a1a19;
    --prism-chart-grid: #2c2c2a;
    --prism-chart-axis: #383835;

    --prism-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --prism-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.5);
    --prism-shadow-3: 0 8px 24px rgba(0, 0, 0, 0.6);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --prism-surface-page: #0d0d0d;
  --prism-surface-1: #1a1a19;
  --prism-surface-2: #2c2c2a;
  --prism-surface-sunken: #0d0d0d;
  --prism-surface-hover: rgba(255, 255, 255, 0.06);
  --prism-surface-active: rgba(255, 255, 255, 0.10);
  --prism-surface-selected: #184f95;
  --prism-surface-overlay: rgba(0, 0, 0, 0.56);

  --prism-ink-primary: #ffffff;
  --prism-ink-secondary: #c3c2b7;
  --prism-ink-muted: #898781;
  --prism-ink-on-accent: #ffffff;
  --prism-ink-link: #6da7ec;

  --prism-border: rgba(255, 255, 255, 0.10);
  --prism-border-strong: #383835;
  --prism-border-hairline: #2c2c2a;

  --prism-accent: #3987e5;
  --prism-accent-hover: #5598e7;
  --prism-accent-subtle: #184f95;

  --prism-focus-ring: #5598e7;

  --prism-value-up: #0ca30c;
  --prism-value-down: #e66767;

  --prism-diff-add-bg: #16301c;
  --prism-diff-add-emphasis: #1f5a2c;
  --prism-diff-del-bg: #3a1a1c;
  --prism-diff-del-emphasis: #6b2229;

  --prism-diff-conflict-ours-bg: #16283f;
  --prism-diff-conflict-theirs-bg: #241f45;
  --prism-diff-conflict-border: #e0a54a;

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

  --prism-diverging-mid: #383835;

  --prism-chart-surface: #1a1a19;
  --prism-chart-grid: #2c2c2a;
  --prism-chart-axis: #383835;

  --prism-shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --prism-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.5);
  --prism-shadow-3: 0 8px 24px rgba(0, 0, 0, 0.6);
}

/* Respect a stated preference for less motion — every component's
 * transitions are written against these two tokens so this works
 * library-wide without each component opting in. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --prism-duration-fast: 0ms;
    --prism-duration-base: 0ms;
    --prism-duration-slow: 0ms;
  }
}
