/* Design tokens.
 *
 * Every colour, size, radius, shadow and duration used anywhere in the
 * dashboard is declared here and nowhere else. A component that needs a value
 * not in this file needs a token added to this file, not a literal at the call
 * site -- that rule is what keeps light and dark in step and what makes the
 * contrast audit below meaningful.
 *
 * THEMING. Three declarations, in this order:
 *
 *   :root                                        the light palette, always
 *   @media (prefers-color-scheme: dark)
 *     :root:not([data-theme="light"])             system dark, unless overridden
 *   :root[data-theme="dark"]                      explicit dark, wins either way
 *
 * The guard on the media query is what lets "Light" beat a dark OS setting;
 * the third block is what lets "Dark" beat a light one. `data-theme` is
 * absent for "system", which is the default. See core/prefs.js.
 *
 * CONTRAST. Every text colour below has been measured against the surfaces it
 * is used on. Body text clears WCAG AA (4.5:1); the lowest ratio anywhere is
 * --text-faint on --surface-2, at 4.70:1. Non-text indicators clear 3:1. The
 * previous palette's faint grey sat at 2.93:1 on white, which is why these
 * numbers are recorded rather than assumed.
 */

:root {
  color-scheme: light;

  /* -- surfaces ---------------------------------------------------------- */
  --bg: #f7f7f8;
  --surface: #ffffff;
  --surface-2: #f2f2f4;
  --surface-3: #e9e9ed;
  --border: #e2e2e6;
  --border-strong: #cfcfd6;

  /* -- text -------------------------------------------------------------- */
  /* 18.04:1 on --surface */
  --text: #16161a;
  /* 6.59:1 on --surface, 5.90:1 on --surface-2 */
  --text-muted: #5c5c68;
  /* 5.26:1 on --surface, 4.70:1 on --surface-2 */
  --text-faint: #6b6b77;

  /* -- accent ------------------------------------------------------------ */
  /* 7.90:1 on --surface, 7.07:1 on --accent-soft */
  --accent: #4338ca;
  --accent-hover: #3730a3;
  --accent-soft: #eef2ff;
  --accent-border: #c7d2fe;
  /* 7.90:1 against --accent */
  --accent-text: #ffffff;

  /* -- status ------------------------------------------------------------ */
  /* 6.47:1 on --surface, 5.91:1 on --danger-soft */
  --danger: #b91c1c;
  --danger-hover: #991b1b;
  --danger-soft: #fef2f2;
  --danger-text: #ffffff;

  /* 6.51:1 on --surface, 6.22:1 on --ok-soft */
  --ok: #146c34;
  --ok-soft: #f0fdf4;

  /* 6.39:1 on --surface, 6.18:1 on --warn-soft */
  --warn: #8a5200;
  --warn-soft: #fefce8;

  /* -- chart ------------------------------------------------------------- */
  --chart-bar: #4338ca;
  --chart-bar-hover: #3730a3;
  --chart-bar-zero: #dcdce2;
  --chart-grid: #ebebef;
  --chart-track: #e9e9ed;

  /* -- typography -------------------------------------------------------- */
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo,
    Consolas, "Liberation Mono", monospace;

  --text-2xs: 0.6875rem;  /* 11px -- badges, axis labels */
  --text-xs: 0.75rem;     /* 12px -- table headers, captions */
  --text-sm: 0.8125rem;   /* 13px -- helper text, secondary */
  --text-base: 0.9375rem; /* 15px -- body */
  --text-md: 1rem;        /* 16px -- h3, lead paragraphs */
  --text-lg: 1.125rem;    /* 18px -- h2 */
  --text-xl: 1.375rem;    /* 22px -- h1 */
  --text-2xl: 1.75rem;    /* 28px -- stat values */
  --text-3xl: 2rem;       /* 32px -- login wordmark */

  --weight-normal: 400;
  --weight-medium: 550;
  --weight-bold: 650;

  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;

  --tracking-tight: -0.011em;
  --tracking-wide: 0.04em;

  /* -- spacing (4px scale) ------------------------------------------------ */
  --space-0: 0;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-7: 2rem;
  --space-8: 2.5rem;
  --space-9: 3rem;
  --space-10: 4rem;

  /* -- shape -------------------------------------------------------------- */
  --radius-sm: 7px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  --shadow: 0 1px 2px rgb(16 16 26 / 6%), 0 8px 24px -12px rgb(16 16 26 / 18%);
  --shadow-lg: 0 12px 48px -12px rgb(16 16 26 / 32%);
  --ring: 0 0 0 3px color-mix(in oklab, var(--accent) 22%, transparent);

  /* -- layers ------------------------------------------------------------- */
  --z-base: 1;
  --z-sticky: 20;
  --z-menu: 40;
  --z-overlay: 50;
  --z-toast: 80;

  /* -- motion -------------------------------------------------------------- */
  --ease: cubic-bezier(0.2, 0, 0.2, 1);
  --duration-fast: 120ms;
  --duration: 160ms;

  /* -- layout -------------------------------------------------------------- */
  --page-max: 1080px;
  --page-narrow: 640px;
  --topbar-height: 56px;
  --tap-target: 44px;
}

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

    --bg: #0d0d10;
    --surface: #16161a;
    --surface-2: #1d1d22;
    --surface-3: #26262d;
    --border: #27272e;
    --border-strong: #3a3a44;

    /* 15.32:1 on --surface */
    --text: #ececf1;
    /* 7.51:1 on --surface, 6.98:1 on --surface-2 */
    --text-muted: #a6a6b4;
    /* 5.37:1 on --surface, 5.00:1 on --surface-2 */
    --text-faint: #8b8b99;

    /* 6.05:1 on --surface */
    --accent: #818cf8;
    --accent-hover: #a5b4fc;
    --accent-soft: #1e1b3f;
    --accent-border: #3730a3;
    /* 6.51:1 against --accent */
    --accent-text: #0d0d10;

    --danger: #f87171;
    --danger-hover: #fca5a5;
    --danger-soft: #2a1416;
    --danger-text: #16161a;

    --ok: #4ade80;
    --ok-soft: #0f2417;

    --warn: #fbbf24;
    --warn-soft: #2a2110;

    --chart-bar: #818cf8;
    --chart-bar-hover: #a5b4fc;
    --chart-bar-zero: #2f2f38;
    --chart-grid: #22222a;
    --chart-track: #26262d;

    --shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 8px 24px -12px rgb(0 0 0 / 60%);
    --shadow-lg: 0 12px 48px -12px rgb(0 0 0 / 80%);
  }
}

/* Explicit dark: identical to the block above, but unconditional, so choosing
 * "Dark" works on a machine set to light. Duplicated rather than shared via a
 * selector list because a media query cannot be part of one. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #0d0d10;
  --surface: #16161a;
  --surface-2: #1d1d22;
  --surface-3: #26262d;
  --border: #27272e;
  --border-strong: #3a3a44;

  --text: #ececf1;
  --text-muted: #a6a6b4;
  --text-faint: #8b8b99;

  --accent: #818cf8;
  --accent-hover: #a5b4fc;
  --accent-soft: #1e1b3f;
  --accent-border: #3730a3;
  --accent-text: #0d0d10;

  --danger: #f87171;
  --danger-hover: #fca5a5;
  --danger-soft: #2a1416;
  --danger-text: #16161a;

  --ok: #4ade80;
  --ok-soft: #0f2417;

  --warn: #fbbf24;
  --warn-soft: #2a2110;

  --chart-bar: #818cf8;
  --chart-bar-hover: #a5b4fc;
  --chart-bar-zero: #2f2f38;
  --chart-grid: #22222a;
  --chart-track: #26262d;

  --shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 8px 24px -12px rgb(0 0 0 / 60%);
  --shadow-lg: 0 12px 48px -12px rgb(0 0 0 / 80%);
}

/* Motion is opt-out at the token level as well as per-rule, so a component
 * that forgets to guard an animation still respects the preference. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 1ms;
    --duration: 1ms;
  }
}
