/* tokens.css — the single source of colour, shape, motion and type values.
 *
 * The language is Apple's: warm-neutral surfaces rather than cool grey, one
 * saturated blue carrying every action, hairline separators instead of drawn
 * borders, translucent chrome over the content that scrolls beneath it,
 * generously rounded shapes, and shadows that are wide and almost invisible
 * rather than dark and tight.
 *
 * Themes: the light palette is defined on bare :root, so it is also the
 * fallback when nothing else matches. Dark is then declared twice:
 *   1. under prefers-color-scheme, guarded by :not([data-theme="light"]),
 *      so the OS setting wins when the user has not chosen explicitly;
 *   2. under [data-theme="dark"], so an explicit choice wins in both
 *      directions — including forcing dark on a light OS.
 * core/theme.js stamps data-theme on <html>; "system" removes the attribute.
 *
 * Rule: never give a colour its only definition inside a theme block, and
 * never hardcode a hex value outside this file. The scalar tokens at the top —
 * type, shape, motion, material — are deliberately theme-independent and are
 * listed as such in tests/tokens.test.mjs. */

:root {
  color-scheme: light;

  /* --- type ---------------------------------------------------------------
     The real thing where it exists and the closest substitute where it does
     not: -apple-system resolves to SF Pro on Apple hardware, Inter is the
     near-metric-compatible fallback everywhere else, and the mono stack asks
     the system for its own rather than paying for a second webfont. */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Segoe UI", Roboto, system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "Cascadia Mono", "Segoe UI Mono", monospace;

  /* --- shape --------------------------------------------------------------
     One ladder, used everywhere. Corners grow with the surface: a glyph button
     is barely rounded, a sheet is nearly a squircle. */
  --r-xs: 6px;
  --r-sm: 8px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 18px;
  --r-2xl: 22px;
  --r-pill: 999px;

  /* --- motion -------------------------------------------------------------
     --ease is the standard change curve, --ease-out the one things enter on,
     and --ease-spring the iOS sheet curve: a long, almost-flat tail that reads
     as weight settling rather than a value being interpolated. */
  --t: 200ms cubic-bezier(.4, 0, .2, 1);
  --t-fast: 130ms cubic-bezier(.4, 0, .2, 1);
  --t-slow: 340ms cubic-bezier(.32, .72, 0, 1);
  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --ease-spring: cubic-bezier(.32, .72, 0, 1);

  /* --- material -----------------------------------------------------------
     The backdrop filter behind every translucent surface. Saturation is
     boosted as well as blurred, which is what keeps frosted chrome from
     looking like grey fog laid over colourful content. */
  --blur: saturate(180%) blur(20px);

  /* brand */
  --accent: #0071e3;
  --accent-dark: #0058b8;
  --accent-soft: #eaf3fe;
  --accent-badge: #dfecfd;
  --on-accent: #fff;        /* text and glyphs sitting on an accent fill */

  /* surfaces */
  --bg: #f5f5f7;
  --surface: #fff;
  --surface-alt: #fafafb;
  --raised: #fff;          /* popovers, fields and other lifted surfaces */
  --hover: #f0f0f3;        /* nav items, ghost buttons, table rows */
  --hover-soft: #f7f7f9;   /* barely-there hover on inline inputs */

  /* Translucent chrome. --glass is what content scrolls under (the topbar,
     menus, the toast); --glass-strong is what content sits beside and has to
     stay opaque enough to read against (the sidebar, a sheet). */
  --glass: rgba(255, 255, 255, .72);
  --glass-strong: rgba(255, 255, 255, .86);
  --glass-line: rgba(0, 0, 0, .07);

  /* lines */
  --line: #e5e5ea;
  --line-soft: #f1f1f4;
  --line-mid: #ebebf0;
  --field: #d8d8e0;
  --field-hover: #b8b8c2;
  --dashed: #c9c9d2;

  /* text — the ladder is spaced so that every step clears WCAG AA (4.5:1) on
     the lightest surface it lands on. That leaves little room below --muted,
     which is why --muted-2 is only slightly lighter than it rather than the
     much paler grey a purely visual palette would use. */
  --ink: #1d1d1f;
  --ink-2: #2c2c30;
  --ink-3: #494950;
  --ink-4: #55555d;
  --nav-ink: #3c3c43;
  --muted: #67676f;
  --muted-2: #6e6e77;
  --faint: #8e8e96;        /* × buttons and other low-priority glyphs */

  /* semantic */
  --warn: #b8761c;
  --danger: #c9384a;
  --danger-hover: #d8465a;

  /* the oversized status number on the standalone error page. It is decoration
     rather than text, so it sits below the contrast the ink ladder holds: the
     sentence under it is what has to be readable. */
  --error-figure: #dfe4ee;

  /* status badges */
  --s-open-bg: #e8f1fd;    --s-open-fg: #0058b8;  --s-open-line: #d3e4fa;
  --s-prog-bg: #fff3e0;    --s-prog-fg: #8a5a12;  --s-prog-line: #f7e3c4;
  --s-res-bg: #e9f6ed;     --s-res-fg: #1f6b41;   --s-res-line: #d3ead9;
  --s-clo-bg: #f2f2f5;     --s-clo-fg: #65656e;   --s-clo-line: #e4e4e9;

  /* Ticket rows are tinted by status, so the queue can be read at a glance
     rather than badge by badge. Far weaker than the badge fills above — the
     badge sits on the row and has to stay separable from it — and each carries
     its own hover, because the plain --surface-alt hover would wipe the tint
     out from under the cursor. */
  --row-open: #eef4fd;     --row-open-hover: #e6effc;
  --row-prog: #fff6e9;     --row-prog-hover: #fdefd8;
  --row-res: #ecf7ef;      --row-res-hover: #e2f2e7;
  --row-clo: #f4f4f6;      --row-clo-hover: #ebebef;

  /* elevation and focus — wide, faint and layered. A single tight shadow reads
     as a drawn outline; two soft ones read as a surface floating above paper. */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 3px rgba(0, 0, 0, .03);
  --shadow-sm: 0 2px 6px rgba(0, 0, 0, .05), 0 8px 20px rgba(0, 0, 0, .05);
  --shadow-md: 0 4px 10px rgba(0, 0, 0, .06), 0 16px 40px rgba(0, 0, 0, .10);
  --shadow-lg: 0 8px 20px rgba(0, 0, 0, .10), 0 30px 70px rgba(0, 0, 0, .18);
  --focus-ring: 0 0 0 3.5px rgba(0, 113, 227, .16);
  --focus-ring-strong: 0 0 0 3.5px rgba(0, 113, 227, .22);
  --btn-glow: 0 3px 12px rgba(0, 113, 227, .28);

  --scrim: rgba(28, 28, 30, .40);   /* behind the mobile nav drawer and sheets */

  /* inverted surface, used by the toast */
  --inverse-bg: #1d1d1f;
  --inverse-ink: #f5f5f7;
}

/* Dark palette. Surfaces climb from near-black in even steps; borders and
   hovers become lighter rather than darker; the accent is lifted so it stays
   legible on a dark ground, which flips --on-accent to a dark ink. Badge fills
   are low-saturation tints of their own hue. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --accent: #6cb0f5;
    --accent-dark: #8fc6fa;
    --accent-soft: #16283d;
    --accent-badge: #1c3550;
    --on-accent: #0d1520;

    --bg: #131316;
    --surface: #1c1c1f;
    --surface-alt: #222226;
    --raised: #26262b;
    --hover: #2c2c32;
    --hover-soft: #232328;

    --glass: rgba(28, 28, 31, .72);
    --glass-strong: rgba(24, 24, 27, .86);
    --glass-line: rgba(255, 255, 255, .08);

    --line: #33333a;
    --line-soft: #26262c;
    --line-mid: #2c2c33;
    --field: #3d3d46;
    --field-hover: #55555f;
    --dashed: #45454e;

    --ink: #f2f2f5;
    --ink-2: #dcdce1;
    --ink-3: #b4b4bd;
    --ink-4: #a5a5ae;
    --nav-ink: #b9b9c2;
    --muted: #94949e;
    --muted-2: #8a8a94;
    --faint: #77777f;

    --warn: #e0a95e;
    --danger: #ff453a;
    --danger-hover: #ff6961;

    --error-figure: #2c3a4d;

    --s-open-bg: #17293c;    --s-open-fg: #7cb8f2;  --s-open-line: #24405c;
    --s-prog-bg: #332711;    --s-prog-fg: #e0a95e;  --s-prog-line: #4a3a1b;
    --s-res-bg: #152b1f;     --s-res-fg: #6ec48f;   --s-res-line: #224431;
    --s-clo-bg: #26262c;     --s-clo-fg: #a0a0aa;   --s-clo-line: #35353d;

    --row-open: #162436;     --row-open-hover: #1b2b3e;
    --row-prog: #2b2413;     --row-prog-hover: #332a17;
    --row-res: #142519;      --row-res-hover: #182d21;
    --row-clo: #212127;      --row-clo-hover: #2a2a31;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, .40), 0 1px 3px rgba(0, 0, 0, .30);
    --shadow-sm: 0 2px 6px rgba(0, 0, 0, .40), 0 8px 20px rgba(0, 0, 0, .38);
    --shadow-md: 0 4px 10px rgba(0, 0, 0, .45), 0 16px 40px rgba(0, 0, 0, .55);
    --shadow-lg: 0 8px 20px rgba(0, 0, 0, .50), 0 30px 70px rgba(0, 0, 0, .65);
    --focus-ring: 0 0 0 3.5px rgba(108, 176, 245, .22);
    --focus-ring-strong: 0 0 0 3.5px rgba(108, 176, 245, .30);
    --btn-glow: 0 3px 12px rgba(108, 176, 245, .24);

    --scrim: rgba(0, 0, 0, .55);
    --inverse-bg: #f2f2f5;
    --inverse-ink: #1d1d1f;
  }
}

/* Same palette again, this time for an explicit choice. Duplicated on purpose:
   a CSS variable cannot be aliased across a media-query boundary. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --accent: #6cb0f5;
  --accent-dark: #8fc6fa;
  --accent-soft: #16283d;
  --accent-badge: #1c3550;
  --on-accent: #0d1520;

  --bg: #131316;
  --surface: #1c1c1f;
  --surface-alt: #222226;
  --raised: #26262b;
  --hover: #2c2c32;
  --hover-soft: #232328;

  --glass: rgba(28, 28, 31, .72);
  --glass-strong: rgba(24, 24, 27, .86);
  --glass-line: rgba(255, 255, 255, .08);

  --line: #33333a;
  --line-soft: #26262c;
  --line-mid: #2c2c33;
  --field: #3d3d46;
  --field-hover: #55555f;
  --dashed: #45454e;

  --ink: #f2f2f5;
  --ink-2: #dcdce1;
  --ink-3: #b4b4bd;
  --ink-4: #a5a5ae;
  --nav-ink: #b9b9c2;
  --muted: #94949e;
  --muted-2: #8a8a94;
  --faint: #77777f;

  --warn: #e0a95e;
  --danger: #ff453a;
  --danger-hover: #ff6961;

  --error-figure: #2c3a4d;

  --s-open-bg: #17293c;    --s-open-fg: #7cb8f2;  --s-open-line: #24405c;
  --s-prog-bg: #332711;    --s-prog-fg: #e0a95e;  --s-prog-line: #4a3a1b;
  --s-res-bg: #152b1f;     --s-res-fg: #6ec48f;   --s-res-line: #224431;
  --s-clo-bg: #26262c;     --s-clo-fg: #a0a0aa;   --s-clo-line: #35353d;

  --row-open: #162436;     --row-open-hover: #1b2b3e;
  --row-prog: #2b2413;     --row-prog-hover: #332a17;
  --row-res: #142519;      --row-res-hover: #182d21;
  --row-clo: #212127;      --row-clo-hover: #2a2a31;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .40), 0 1px 3px rgba(0, 0, 0, .30);
  --shadow-sm: 0 2px 6px rgba(0, 0, 0, .40), 0 8px 20px rgba(0, 0, 0, .38);
  --shadow-md: 0 4px 10px rgba(0, 0, 0, .45), 0 16px 40px rgba(0, 0, 0, .55);
  --shadow-lg: 0 8px 20px rgba(0, 0, 0, .50), 0 30px 70px rgba(0, 0, 0, .65);
  --focus-ring: 0 0 0 3.5px rgba(108, 176, 245, .22);
  --focus-ring-strong: 0 0 0 3.5px rgba(108, 176, 245, .30);
  --btn-glow: 0 3px 12px rgba(108, 176, 245, .24);

  --scrim: rgba(0, 0, 0, .55);
  --inverse-bg: #f2f2f5;
  --inverse-ink: #1d1d1f;
}
