/* Callback List — design tokens. THE single source of truth for colour and type.
 *
 * Loaded by BOTH the static marketing pages (<link href="/tokens.css">) and the React app
 * (linked from index.html, not bundled) — deliberately, so there is exactly one file to
 * change and the two surfaces cannot drift apart again. They used to: the app was blue
 * (#4f8cff) while marketing, the preview hub and both approved mockups were teal. Teal won,
 * because it is what every approved design artifact already used.
 *
 * ── THEMING ──────────────────────────────────────────────────────────────────────────
 * Every token is declared ONCE as light-dark(<light>, <dark>). Writing the two themes as
 * separate blocks meant every value existed twice and had to be edited twice; that is how
 * the light theme silently rotted (see below). light-dark() resolves against the element's
 * used `color-scheme`, so a manual override is just a different color-scheme — no second
 * copy of the palette. Baseline newly available since May 2024; the codebase already
 * assumes that vintage (color-mix, text-wrap:balance, backdrop-filter).
 *
 * ── CONTRAST ─────────────────────────────────────────────────────────────────────────
 * Our bar is WCAG 2.2 AA (docs/DESIGN_PROCESS.md §5): 4.5:1 for text. Every pairing below
 * is measured, not eyeballed — `node scripts/check-contrast.mjs` proves it and fails CI-
 * style if a value regresses. The light theme inherited from the mockups was failing badly
 * (--waiting on its own chip was 2.89:1, white on the accent fill 3.74:1); the light values
 * here are the solved, passing ones. If you change a colour, run the script.
 *
 * Colour on the triage board means URGENCY and nothing else. --needs / --waiting / --fyi /
 * --ignore are semantic and load-bearing. Do not spend them on decoration.
 */

:root {
  /* Follow the OS by default. [data-theme] below overrides it. */
  color-scheme: light dark;

  /* surfaces */
  --ground: light-dark(#f1f0ec, #141719);
  --surface: light-dark(#ffffff, #1c2125);
  --surface-2: light-dark(#f5f6f8, #232a2f);
  --surface-3: light-dark(#eceef1, #2b333a);

  /* text */
  --ink: light-dark(#1a2027, #e9eef2);
  --muted: light-dark(#5a6570, #9aa6b2);
  --faint: light-dark(#636d78, #7f8b98); /* light was #66707c — 4.41:1, a near-miss */

  /* Decorative lines — card edges, dividers. Low contrast is CORRECT here: these carry no
   * information and WCAG 1.4.11 does not reach them. Do not use them on a control. */
  --line: light-dark(#e4e7eb, #2a323a);
  --line-2: light-dark(#eef0f3, #232a30);
  --line-strong: light-dark(#d0d6dd, #3a444e);

  /* The boundary of an INTERACTIVE control (text inputs, secondary buttons). Here the border
   * is the only thing telling you where the control is, so WCAG 1.4.11 demands 3:1 against
   * the surface behind it. --line-strong is 1.5:1 — invisible to a lot of people, and it was
   * what the inputs used. This is a separate token precisely so a decorative divider and a
   * control edge cannot be confused again. */
  --line-control: light-dark(#85898d, #656c74);

  /* brand.
   * --accent must work BOTH as a fill (white text on it) and as text (on --ground).
   * The old light accent #0d9488 did neither: 3.74:1 as a fill, 3.28:1 as text.
   * #0f766e clears both (5.47:1 / 4.80:1). --on-accent is the only legal foreground
   * on an accent fill — never #fff in dark mode, where it lands at 1.86:1. */
  --accent: light-dark(#0f766e, #2dd4bf);
  --accent-2: light-dark(#0b5f58, #14b8a6);
  --accent-ink: light-dark(#0a5e57, #8fe9de);
  --accent-soft: light-dark(#d7efec, #123b38);
  --on-accent: light-dark(#ffffff, #04211e);

  /* semantic — urgency only. Each is used as text on its own -soft chip, and each light
   * value was raised until that pairing clears 4.5:1. */
  --needs: light-dark(#b33d36, #ef6f66); /* they are waiting on you */
  --needs-soft: light-dark(#f7e2e0, #3a1e1c);
  --waiting: light-dark(#925f07, #e0a53c); /* you are waiting on them */
  --waiting-soft: light-dark(#f6ecd3, #332714);
  --fyi: light-dark(#336d9d, #5fa4dd);
  --fyi-soft: light-dark(#e2edf6, #152a3b);
  --ignore: light-dark(#5f6a78, #838e9b);
  --ignore-soft: light-dark(#edeff2, #20272e);
  --vip: light-dark(#8a6510, #dcb85f);
  --go: light-dark(#267748, #3fb46b);
  --go-soft: light-dark(#dcefe2, #123322);
  --danger: light-dark(#b33d36, #ef6f66);

  /* elevation: single-layer shadows can use light-dark(); the multi-layer ones cannot
   * (their commas would parse as extra light-dark arguments) and live further down. */
  --shadow-sm: light-dark(0 1px 2px rgb(20 32 52 / 0.06), 0 1px 2px rgb(0 0 0 / 0.35));

  /* type + shape */
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;
  --r: 16px;
  --r-sm: 10px;
}

/* An explicit user choice beats the OS: flipping color-scheme re-resolves every
 * light-dark() above. This is the whole reason the palette is declared once. */
:root[data-theme="light"] {
  color-scheme: light;
}
:root[data-theme="dark"] {
  color-scheme: dark;
}

/* light-dark() cannot carry a comma-separated shadow list (the commas would read as extra
 * arguments), so the multi-layer shadows stay conventional. Two small blocks, not a palette. */
:root {
  --shadow: 0 1px 2px rgb(0 0 0 / 0.4), 0 12px 30px -14px rgb(0 0 0 / 0.7);
  --shadow-lg: 0 2px 8px rgb(0 0 0 / 0.5), 0 28px 56px -20px rgb(0 0 0 / 0.85);
  --glow: radial-gradient(60% 120% at 80% -10%, rgb(45 212 191 / 0.16), transparent 60%);
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --shadow: 0 1px 2px rgb(20 32 52 / 0.05), 0 10px 26px -12px rgb(20 32 52 / 0.16);
    --shadow-lg: 0 2px 8px rgb(20 32 52 / 0.07), 0 22px 48px -18px rgb(20 32 52 / 0.26);
    --glow: radial-gradient(60% 120% at 80% -10%, rgb(13 148 136 / 0.08), transparent 60%);
  }
}
:root[data-theme="light"] {
  --shadow: 0 1px 2px rgb(20 32 52 / 0.05), 0 10px 26px -12px rgb(20 32 52 / 0.16);
  --shadow-lg: 0 2px 8px rgb(20 32 52 / 0.07), 0 22px 48px -18px rgb(20 32 52 / 0.26);
  --glow: radial-gradient(60% 120% at 80% -10%, rgb(13 148 136 / 0.08), transparent 60%);
}

/* Accessibility floor. WCAG 2.2 adds 2.4.11 Focus Not Obscured and 2.4.13 Focus Appearance;
 * a visible, offset ring in brand satisfies both and costs nothing. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}
:focus:not(:focus-visible) {
  outline: none;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
