/*
 * DESIGN TOKENS — the swappable vocabulary for the whole app.
 *
 * WHY: this file is the single source of truth for the values a theme can
 * change (colors, corner radius, border weight, elevation, display/mono fonts).
 * Components should reference these tokens instead of hardcoding values, so a
 * theme becomes "redefine a handful of `:root` variables" rather than "edit 62
 * stylesheets". See docs/theming.md for the full model and the Phase 2/3/4 plan.
 *
 * WHAT: named primitives (`--lch-*`) -> semantic color abstractions
 * (`--color-*`), plus non-color scales (radius, border width, shadow, fonts).
 *
 * HOW (light/dark switching): the `[data-theme]` attribute on <html> forces a
 * theme; with no attribute we follow the OS via `prefers-color-scheme`. See the
 * "THEME SWITCH" section below for the precedence rules.
 */

:root {
  /* -------------------------------------------------------------------------
   * Named color values (light / default). Dark values are redefined in the
   * THEME SWITCH section below — NOT inline here — so the same dark palette is
   * reachable both from the OS media query and from a forced `data-theme`.
   * ------------------------------------------------------------------------- */
  --lch-black: 0% 0 0;
  --lch-white: 100% 0 0;
  --lch-gray: 96% 0.005 96;
  --lch-gray-dark: 92% 0.005 96;
  --lch-gray-darker: 75% 0.005 96;
  --lch-blue: 54% 0.23 255;
  --lch-blue-light: 95% 0.03 255;
  --lch-blue-dark: 80% 0.08 255;
  --lch-orange: 70% 0.2 44;
  --lch-red: 51% 0.2 31;
  --lch-green: 65.59% 0.234 142.49;
  --lch-always-black: 0% 0 0;

  /* Semantic color abstractions */
  --color-negative: oklch(var(--lch-red));
  --color-positive: oklch(var(--lch-green));
  --color-bg: oklch(var(--lch-white));
  --color-message-bg: oklch(var(--lch-gray));
  --color-text: oklch(var(--lch-black));
  --color-text-reversed: oklch(var(--lch-white));
  --color-link: oklch(var(--lch-blue));
  --color-border: oklch(var(--lch-gray));
  --color-border-dark: oklch(var(--lch-gray-dark));
  --color-border-darker: oklch(var(--lch-gray-darker));
  --color-selected: oklch(var(--lch-blue-light));
  --color-selected-dark: oklch(var(--lch-blue-dark));
  --color-alert: oklch(var(--lch-orange));

  /* -------------------------------------------------------------------------
   * Radius scale. Corner rounding for chrome/components.
   *
   * NOTE: `--border-radius` (no default; used only as `var(--border-radius, X)`
   * fallbacks elsewhere) is intentionally NOT defined here — defining it would
   * change every current fallback site. It stays a component-level opt-in knob.
   * ------------------------------------------------------------------------- */
  --radius-sm: 0.3em;   /* code chips, version badges, small tags */
  --radius-md: 0.5em;   /* the common component radius */
  --radius-lg: 0.8em;   /* panels, cards, larger surfaces */
  --radius-pill: 2em;   /* pills / capsule buttons / switches */
  --radius-full: 50%;   /* circles (avatars, dots) */
  --radius: var(--radius-md); /* base alias */

  /* -------------------------------------------------------------------------
   * Border weight.
   * ------------------------------------------------------------------------- */
  --border-width: 1px;
  --border-width-thick: 2px;

  /* -------------------------------------------------------------------------
   * Elevation shadows (theme-flippable; dark stacks defined in THEME SWITCH).
   *
   * `--shadow-md` is the app's 6-layer floating-surface elevation (previously
   * duplicated verbatim in utilities.css `.shadow` and panels.css). It flips
   * between the light and dark stacks below.
   *
   * `--shadow-sm` is a light single-layer surface shadow. It is defined here as
   * vocabulary only — no foundation file uses it in Phase 1. Its value mirrors a
   * real small elevation that lives in a Phase-2 component file
   * (messages.css `.reactions`: `0 1px 2px rgba(0,0,0,0.25)`). It does NOT flip.
   * ------------------------------------------------------------------------- */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25);

  --shadow-md:
    0 0 0 1px oklch(var(--lch-always-black) / 0.02),
    0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.2),
    0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.3),
    0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.4),
    0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.5),
    0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 0.6);

  /* `--shadow-panel` is the .panel card elevation — the SAME 6-layer light stack
     as `--shadow-md`'s :root value, but intentionally a SEPARATE, NON-flipping
     token. Unlike `--shadow-md` (and `.shadow`), `.panel` has never had a
     dark-mode shadow variant, so it must stay identical in light AND dark;
     routing panels through the theme-flipping `--shadow-md` would VISIBLY darken
     them in dark mode (the Phase-1 trap). This gives the `shadow` theme knob a
     token it can drive on panels (shadow:none/hard) WITHOUT reintroducing that
     dark-mode divergence. Do NOT add a dark override for this token. */
  --shadow-panel:
    0 0 0 1px oklch(var(--lch-always-black) / 0.02),
    0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.2),
    0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.3),
    0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.4),
    0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.5),
    0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 0.6);

  /* -------------------------------------------------------------------------
   * Typography. `--font-family` (the sans body stack) is defined in base.css.
   * These route headings and monospace through swappable tokens; defaults are
   * exactly the current values so nothing changes.
   * ------------------------------------------------------------------------- */
  --font-display: var(--font-family);
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monaco, monospace;
}

/* ===========================================================================
 * THEME SWITCH — precedence: forced `[data-theme]` (user/admin) ▸ OS default.
 *
 *   no attribute        -> follow the OS (prefers-color-scheme)
 *   data-theme="light"  -> force light, even if the OS is dark
 *   data-theme="dark"   -> force dark,  even if the OS is light
 *
 * The dark values below are duplicated across the media query and the explicit
 * `[data-theme="dark"]` rule ON PURPOSE — plain CSS cannot combine "OS is dark
 * AND not forced-light" with "forced dark" into one selector list without the
 * media query poisoning the whole list. Keep them in sync by hand.
 *
 * Server-driven per-user / per-account defaults come in Phase 3: the server
 * will set `data-theme` on <html> (and/or inject whitelisted `:root` overrides
 * via the existing `custom_styles_tag` head hook). See docs/theming.md.
 * =========================================================================== */

/* OS dark — applies only when the user has NOT forced light. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --lch-black: 100% 0 0;
    --lch-white: 0% 0 0;
    --lch-gray: 25.2% 0 0;
    --lch-gray-dark: 30.12% 0 0;
    --lch-gray-darker: 44.95% 0 0;
    --lch-blue: 72.25% 0.16 248;
    --lch-blue-light: 28.11% 0.053 248;
    --lch-blue-dark: 42.25% 0.07 248;
    --lch-red: 73.8% 0.184 29.18;
    --lch-green: 75% 0.21 141.89;

    /* Elevation gains opacity in dark mode (was `.shadow`'s dark media query). */
    --shadow-md:
      0 0 0 1px oklch(var(--lch-always-black) / 0.42),
      0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.6),
      0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.7),
      0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.8),
      0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.9),
      0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 1);
  }
}

/* Forced dark — identical dark values, reachable regardless of OS. */
:root[data-theme="dark"] {
  --lch-black: 100% 0 0;
  --lch-white: 0% 0 0;
  --lch-gray: 25.2% 0 0;
  --lch-gray-dark: 30.12% 0 0;
  --lch-gray-darker: 44.95% 0 0;
  --lch-blue: 72.25% 0.16 248;
  --lch-blue-light: 28.11% 0.053 248;
  --lch-blue-dark: 42.25% 0.07 248;
  --lch-red: 73.8% 0.184 29.18;
  --lch-green: 75% 0.21 141.89;

  --shadow-md:
    0 0 0 1px oklch(var(--lch-always-black) / 0.42),
    0 .2em 1.6em -0.8em oklch(var(--lch-always-black) / 0.6),
    0 .4em 2.4em -1em oklch(var(--lch-always-black) / 0.7),
    0 .4em .8em -1.2em oklch(var(--lch-always-black) / 0.8),
    0 .8em 1.2em -1.6em oklch(var(--lch-always-black) / 0.9),
    0 1.2em 1.6em -2em oklch(var(--lch-always-black) / 1);
}
