/*
 * Design tokens — the single source of truth for color/spacing/type across
 * the whole site. Server-rendered pages (site.css, templates/*.html) and the
 * React dashboard island (frontend/src/styles.css) both reference these
 * custom properties rather than hardcoding values, so the two stay visually
 * consistent without being the same codebase.
 *
 * The palette is the "warm maker" brand direction (see docs/REBRAND_PLAN.pdf):
 * warm paper neutrals rather than cool slate, with orange promoted from a
 * hover-only wash to a real call-to-action fill. Every text/background pair
 * below was checked against WCAG AA (4.5:1) in both themes before landing —
 * see the "contrast" notes on the individual tokens that were forced to move.
 *
 * To add a theme: add another selector block overriding the same variable
 * names and something that sets data-theme on <html>. Nothing else in the
 * codebase needs to change — every rule already reads through these names.
 */

:root {
  color-scheme: light;

  /* Warm paper neutrals. --color-surface deliberately stays pure white: cards
   * lift off the warm page background, and it keeps the chart series palette
   * (validated against #ffffff) valid without re-derivation. */
  --color-bg: #faf7f2;
  --color-surface: #ffffff;
  --color-border: #e9e2d8;
  --color-text: #1c1917;
  --color-text-muted: #6f6862;
  --color-muted: #a29a92;

  /* Brand navy, sampled from static/images/DIYesp_logo_full.png. Keeps the
   * high-frequency roles — links, active nav, focus rings — so the orange
   * below stays reserved for "do this thing". */
  --color-primary: #123a6e;
  --color-primary-text: #ffffff;

  /* Brand orange, vivid. DECORATIVE ONLY — gradients, illustration strokes,
   * washes, highlights. It is too light to carry white text (2.79:1), so
   * anything with a label on it uses --color-accent-strong instead. */
  --color-accent: #f47800;
  --color-accent-text: #ffffff;

  /* The same orange darkened until white text clears AA (4.50:1). This is the
   * primary call-to-action fill — "Register a device", "Create", "Save". */
  --color-accent-strong: #c2570a;
  --color-accent-strong-text: #ffffff;

  /* Low-opacity accent wash for hover/active backgrounds (nav, icon buttons,
   * avatar chip) — a themed token rather than a hardcoded color-mix() percent
   * because the same percentage reads very differently on white vs. a dark
   * surface (see the dark override below). */
  --accent-wash: color-mix(in srgb, var(--color-accent) 10%, transparent);

  /* Status colors stay conventional — green/red/amber, never rebranded.
   * Two were forced to move for contrast, not for looks:
   *   success  #16a34a scored 3.30:1 on white (a pre-existing AA failure)
   *   warning  #d97706 scored 3.19:1 on white, AND sat only dE 4.9 from the
   *            accent orange, which is what made "orange means CTA" and
   *            "orange means warning" ambiguous. Now dE 10.0 apart.
   * Warning UI is always icon- or text-labeled as well, never color alone. */
  --color-success: #15803d;
  --color-danger: #dc2626;
  --color-warning: #8f6800;

  /* Text sitting ON a solid --color-danger / --color-success fill (the
   * confirm-delete button, the alert-rule badges). Per-theme like
   * --color-primary-text, because this theme's red and green are dark enough
   * for white text (4.83:1 and 5.02:1) and the dark theme's are not. */
  --color-danger-text: #ffffff;
  --color-success-text: #ffffff;
  --color-warning-text: #ffffff;

  /* Space Grotesk is self-hosted (static/fonts, see NOTICE.md) and used for
   * headings and the brand wordmark only; body copy stays on the system UI
   * stack, which renders more comfortably at small sizes on every platform. */
  --font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --font-size-sm: 0.85rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.25rem;
  --font-size-xl: 1.75rem;

  /* Display scale — headings only. Paired with --font-display and a tighter
   * line-height than body copy, which needs the extra leading and these do not. */
  --font-size-h1: 2rem;
  --font-size-h2: 1.5rem;
  --font-size-h3: 1.125rem;
  --line-height-display: 1.18;
  --letter-spacing-display: -0.015em;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;

  --radius-sm: 6px;
  --radius: 12px;

  /* Soft elevation, so a card reads as a raised surface rather than a boxed
   * outline. Tinted with the warm ink color, not neutral black — a pure-black
   * shadow over warm paper reads gray and slightly dirty. */
  --shadow-sm: 0 1px 2px rgba(28, 25, 23, 0.05);
  --shadow: 0 1px 3px rgba(28, 25, 23, 0.06), 0 4px 12px rgba(28, 25, 23, 0.05);
  --shadow-lg: 0 8px 28px rgba(28, 25, 23, 0.10);

  /* Chart marks (fleet overview / overview sparklines) — series colors
   * validated for contrast + CVD separation against --color-surface in both
   * themes; grid/axis are one step off the surface, per-theme. */
  --chart-line: #2563eb;
  --chart-bad: #dc2626;
  --chart-grid: #f2ede5;
  --chart-axis: #d8cfc2;

  /* Categorical series slots for multi-series charts (dashboard line charts).
   * The ORDER is the colorblind-safety mechanism, not cosmetic — slots are
   * assigned 1..8 in fixed order and never cycled or reassigned by rank, so a
   * series keeps its color when another is toggled off. Validated as a set
   * against this theme's --color-surface (#ffffff): every adjacent pair clears
   * CVD ΔE 9.1 and normal-vision ΔE 19.6 (OKLab x100). Slots 3/4/5 sit below
   * 3:1 contrast on white, which is why the chart always ships a text legend
   * and a table view — identity is never carried by color alone. Re-run the
   * palette validator against both surfaces before changing any of these.
   * (Unchanged by the warm rebrand: --color-surface stayed #ffffff here.) */
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-8: #e34948;

  /* Sketch-source syntax highlighting (static/js/vendor/codemirror/, wired up
   * by static/js/code-editor.js on the firmware-authoring page's
   * .code-textarea) — a CodeMirror theme reads these, not raw CodeMirror
   * theme CSS, so it stays in sync with the rest of the site automatically
   * on a theme toggle instead of needing its own light/dark CSS files. */
  --code-keyword: #7c3aed;
  --code-string: #b45309;
  --code-comment: #64748b;
  --code-number: #0891b2;
  --code-def: #1d4ed8;
  --code-builtin: #0f766e;

  /* "Highlight every occurrence of this identifier" overlay
   * (static/js/vendor/codemirror/addon-match-highlighter.js). Built from
   * --color-primary, not --color-warning (tried first) or --accent-wash:
   * warning/danger/success stay reserved for their conventional meaning
   * elsewhere on the site (tokens.css's own rule, above) and amber sat too
   * close to the string-literal color to read cleanly as a background under
   * it; --accent-wash already means "this is the active text selection"
   * (.CodeMirror-selected below) — reusing it here would make "the range you
   * dragged" and "the other places that same identifier appears" the same
   * color. Blue reads as its own distinct "related occurrences" signal
   * against both the orange selection wash and every syntax token color. */
  --code-highlight: color-mix(in srgb, var(--color-primary) 20%, transparent);
}

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

  /* Warm charcoal rather than the previous blue-slate — the blue cast
   * desaturated the orange accent toward gray. These are darker than the
   * surfaces they replace, which also lifted the worst series-vs-surface
   * contrast from 2.96:1 to 3.46:1. */
  --color-bg: #13100e;
  --color-surface: #1f1b18;
  --color-border: #37312c;
  --color-text: #f5f1ec;
  --color-text-muted: #a8a09a;
  --color-muted: #78706a;

  /* Lightened well past the old #3d7fd6, which failed twice over on this
   * darker surface: 4.24:1 as link text, and 4.03:1 for white text sitting on
   * it as a button fill (already an AA failure before the rebrand). Now 5.91:1
   * as text, and it takes DARK text when used as a fill, same as the accent. */
  --color-primary: #5b9be5;
  --color-primary-text: #0d1b2a;

  /* Bright enough to glow against the dark surface, so it needs no separate
   * darkened variant the way the light theme does — --color-accent-strong is
   * the same value here, paired with dark text (7.80:1). */
  --color-accent: #ff9142;
  --color-accent-text: #241000;
  --color-accent-strong: #ff9142;
  --color-accent-strong-text: #241000;

  /* Needs a much higher percentage than the light theme — the dark surface
   * already carries its own hue, so a low-opacity orange mix desaturates
   * toward neutral gray before it reads as warm. Sampled/tuned against a real
   * screenshot: 8% here was indistinguishable from a plain hover gray. */
  --accent-wash: color-mix(in srgb, var(--color-accent) 24%, transparent);

  /* Success and danger keep their original dark-theme values (7.50:1 and
   * 4.54:1 on the new surface — no reason to touch them). Warning moved for
   * the same collision as the light theme, and it was worse here: the old
   * #f59e0b sat only dE 4.9 from this theme's bright accent orange. */
  --color-success: #22c55e;
  --color-danger: #ef4444;
  --color-warning: #fbbf24;

  /* This theme's red and green are bright, so they take dark text on a fill
   * (4.85:1 and 6.54:1); white would only reach 3.76:1 and 2.28:1. */
  --color-danger-text: #2b0a0a;
  --color-success-text: #052e16;
  --color-warning-text: #2a1c00;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 4px 12px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 8px 28px rgba(0, 0, 0, 0.5);

  --chart-line: #3b82f6;
  --chart-bad: #ef4444;
  --chart-grid: #2b2521;
  --chart-axis: #453d36;

  /* Same eight hues, re-stepped for a dark surface — not an automatic
   * lightening of the light values, but their own validated set: worst
   * adjacent CVD ΔE 8.4, normal-vision ΔE 19.3. Unchanged by the warm
   * rebrand: OKLab ΔE between two opaque colors doesn't depend on what's
   * behind them, and the surface-dependent part (contrast) improved. */
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #9085e9;
  --series-8: #e66767;

  --code-keyword: #c084fc;
  --code-string: #fbbf24;
  --code-comment: #94a3b8;
  --code-number: #22d3ee;
  --code-def: #60a5fa;
  --code-builtin: #2dd4bf;

  /* --color-primary's dark-theme variant is already a brighter, more
   * saturated blue than the light theme's navy — needs less of a bump than
   * --accent-wash's light-to-dark jump does, just enough to stay visible
   * against the dark surface. */
  --code-highlight: color-mix(in srgb, var(--color-primary) 28%, transparent);
}
