/* ============================================================================
   Phoenix — design tokens.  DRAFT, not yet wired into the app.

   Every value here was COMPUTED, not chosen by eye:
     · text/border/status pairs were measured for WCAG contrast against the
       real surfaces this product uses (#ffffff, #f8fafc, #0f172a, #1e293b);
       the ratio is written beside each one so it can be re-checked.
     · the chart palettes passed a colour-blind separation, lightness-band,
       chroma and surface-contrast check in BOTH modes.
     · the sequential ramps passed monotonic-lightness, step-spacing,
       light-end contrast and single-hue checks in BOTH modes.

   The identity does not change.  Indigo #4f46e5 stays the brand, the slate
   ramp stays the neutral.  What changes is that each colour now has a surface
   it is allowed on: the greys this app already uses are correct on the dark
   navy and wrong on white, and that single mistake accounts for most of the
   contrast failures (#94a3b8 as body text: 2.56:1 on white, 6.96:1 on navy).
   ============================================================================ */

:root {
  color-scheme: light;

  /* ---- neutral ramp (unchanged - this is the existing slate) ---- */
  --slate-50:  #f8fafc;
  --slate-100: #f1f5f9;
  --slate-200: #e2e8f0;
  --slate-300: #cbd5e1;
  --slate-400: #94a3b8;
  --slate-500: #64748b;
  --slate-600: #475569;
  --slate-700: #334155;
  --slate-800: #1e293b;
  --slate-900: #0f172a;

  /* ---- surfaces ---- */
  --surface-page:      #f8fafc;  /* the ground the app sits on        */
  --surface-card:      #ffffff;  /* raised panel                      */
  --surface-sunken:    #f1f5f9;  /* wells, table headers, inset areas */
  --surface-inverse:   #0f172a;  /* nav bar, dark panels              */
  --surface-inverse-2: #1e293b;  /* raised panel INSIDE a dark area   */

  /* ---- borders ---- */
  --border-subtle:  #e2e8f0;     /* hairline between rows        */
  --border-default: #cbd5e1;     /* card and control outline     */
  --border-strong:  #94a3b8;     /* focused / selected outline   */

  /* ---- text.  ratio = contrast on --surface-card (#ffffff) ---- */
  --text-primary:   #0f172a;     /* 17.85  AAA */
  --text-secondary: #475569;     /*  7.58  AAA */
  --text-muted:     #64748b;     /*  4.76  AA   <- replaces #94a3b8 (2.56, FAILS) */
  --text-on-accent: #ffffff;     /*  6.29 against --accent */

  /* ---- brand ---- */
  --accent:        #4f46e5;      /*  6.29  AA on white - the existing indigo */
  --accent-strong: #4338ca;      /*  7.90  AAA - hover / pressed */
  --accent-tint:   #eef2ff;      /* selected-row wash, NEVER text */

  /* ---- status.  Two tokens per state, because a colour that is right as a
         FILL is not right as TEXT.  #f59e0b is a fine badge ground and an
         unreadable label (2.15:1); that conflation is why "warning" is the
         least legible thing on the screen today. ---- */
  --danger-text:  #b91c1c;       /*  6.47  AA */
  --danger-fill:  #dc2626;
  --danger-tint:  #fef2f2;
  --warn-text:    #b45309;       /*  5.02  AA   <- replaces #f59e0b (2.15, FAILS) */
  --warn-fill:    #f59e0b;
  --warn-tint:    #fffbeb;
  --success-text: #15803d;       /*  5.02  AA   <- replaces #10b981 (2.54, FAILS) */
  --success-fill: #16a34a;
  --success-tint: #f0fdf4;
  --info-text:    #1d4ed8;       /*  6.70  AA */
  --info-fill:    #2563eb;
  --info-tint:    #eff6ff;

  /* ---- charts.  Brand indigo leads; the rest is Okabe-Ito, the reference
         colour-blind-safe categorical set.  Validated on lightness band,
         chroma floor, adjacent CVD separation, normal-vision separation and
         surface contrast.  CVD lands in the 6-8 "floor" band, which is legal
         ONLY with secondary encoding - so every chart MUST carry a legend or
         direct labels.  Today 137 of 189 charts carry neither. ---- */
  --chart-1: #4f46e5;  --chart-2: #d55e00;  --chart-3: #009e73;  --chart-4: #cc79a7;
  --chart-5: #0072b2;  --chart-6: #e69f00;  --chart-7: #56b4e9;  --chart-8: #8f4fbf;

  /* ---- magnitude ramp (heatmaps, density, call volume): ONE hue, light to
         dark, even steps, lightest step still 2.68:1 on white ---- */
  --ramp-1: #959cc3; --ramp-2: #7a83c6; --ramp-3: #6169c7; --ramp-4: #4b4bc7; --ramp-5: #3b22c5;

  /* ---- type scale.  8 steps, all rem, so the root-size knob in base.html
         finally moves ALL text.  Today 1,853 sizes are hard px and do not
         move, which makes that knob a half-truth. ---- */
  --text-2xs: 0.6875rem;
  --text-xs:  0.75rem;
  --text-sm:  0.875rem;
  --text-md:  1rem;
  --text-lg:  1.125rem;
  --text-xl:  1.375rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.25rem;

  /* ---- spacing: 4px base, 7 steps (replaces 28 ad-hoc padding values) ---- */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 24px; --space-6: 32px; --space-7: 48px;

  /* ---- radius: 4 steps (replaces 22 values) ---- */
  --radius-sm: 4px; --radius-md: 8px; --radius-lg: 12px; --radius-pill: 999px;

  /* ---- elevation: 4 steps (replaces 247 distinct box-shadows) ---- */
  --shadow-1: 0 1px 2px rgba(15,23,42,.06);
  --shadow-2: 0 2px 6px rgba(15,23,42,.08);
  --shadow-3: 0 8px 20px rgba(15,23,42,.12);
  --shadow-4: 0 16px 40px rgba(15,23,42,.18);
}

/* ============================================================================
   DARK.  Chosen, not flipped.  Each token is re-measured against the dark
   ground; the greys the app already uses (#94a3b8, #cbd5e1) are correct HERE,
   which is exactly why the light theme must stop borrowing them.
   ============================================================================ */
:root[data-theme="dark"] {
  color-scheme: dark;

  --surface-page:      #0b1220;
  --surface-card:      #0f172a;
  --surface-sunken:    #111c30;
  --surface-inverse:   #f8fafc;
  --surface-inverse-2: #ffffff;

  --border-subtle:  #1e293b;
  --border-default: #334155;
  --border-strong:  #475569;

  --text-primary:   #f1f5f9;     /* 16.30  AAA on #0f172a */
  --text-secondary: #cbd5e1;     /* 12.02  AAA */
  --text-muted:     #94a3b8;     /*  6.96  AA   - correct on THIS ground */
  --text-on-accent: #0b1220;

  --accent:        #818cf8;      /*  5.98  AA */
  --accent-strong: #a5b4fc;
  --accent-tint:   #1e1b4b;

  --danger-text:  #f87171;       /*  6.45  AA */
  --danger-fill:  #dc2626;
  --danger-tint:  #2a1215;
  --warn-text:    #fbbf24;       /* 10.69  AAA */
  --warn-fill:    #b45309;
  --warn-tint:    #2a1f0a;
  --success-text: #34d399;       /*  9.29  AAA */
  --success-fill: #15803d;
  --success-tint: #0c2a1c;
  --info-text:    #60a5fa;       /*  7.02  AAA */
  --info-fill:    #1d4ed8;
  --info-tint:    #0f1e3d;

  /* same hues, re-solved for the dark lightness band (L 0.48-0.67) */
  --chart-1: #563bff;  --chart-2: #df3400;  --chart-3: #009864;  --chart-4: #c45596;
  --chart-5: #0076cf;  --chart-6: #d17200;  --chart-7: #0095dc;  --chart-8: #9a37da;

  --ramp-1: #c2c8e9; --ramp-2: #a6b1f1; --ramp-3: #8c98f6; --ramp-4: #747dfb; --ramp-5: #605efe;

  --shadow-1: 0 1px 2px rgba(0,0,0,.5);
  --shadow-2: 0 2px 6px rgba(0,0,0,.55);
  --shadow-3: 0 8px 20px rgba(0,0,0,.6);
  --shadow-4: 0 16px 40px rgba(0,0,0,.7);
}

/* ============================================================================
   The reader's OS preference, honoured only when they have not chosen for
   themselves. Three states, not two:
     - explicit choice  -> data-theme="dark" | "light" on <html>
     - no choice (the default) -> nothing stamped, so only this query separates them
   The :not([data-theme="light"]) guard is what lets an explicit LIGHT choice beat
   a dark OS setting; without it the query would win and the toggle would look broken
   for anyone whose system is dark.

   Nothing in this product read prefers-color-scheme before today.
   ============================================================================ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  color-scheme: dark;

  --surface-page:      #0b1220;
  --surface-card:      #0f172a;
  --surface-sunken:    #111c30;
  --surface-inverse:   #f8fafc;
  --surface-inverse-2: #ffffff;

  --border-subtle:  #1e293b;
  --border-default: #334155;
  --border-strong:  #475569;

  --text-primary:   #f1f5f9;     /* 16.30  AAA on #0f172a */
  --text-secondary: #cbd5e1;     /* 12.02  AAA */
  --text-muted:     #94a3b8;     /*  6.96  AA   - correct on THIS ground */
  --text-on-accent: #0b1220;

  --accent:        #818cf8;      /*  5.98  AA */
  --accent-strong: #a5b4fc;
  --accent-tint:   #1e1b4b;

  --danger-text:  #f87171;       /*  6.45  AA */
  --danger-fill:  #dc2626;
  --danger-tint:  #2a1215;
  --warn-text:    #fbbf24;       /* 10.69  AAA */
  --warn-fill:    #b45309;
  --warn-tint:    #2a1f0a;
  --success-text: #34d399;       /*  9.29  AAA */
  --success-fill: #15803d;
  --success-tint: #0c2a1c;
  --info-text:    #60a5fa;       /*  7.02  AAA */
  --info-fill:    #1d4ed8;
  --info-tint:    #0f1e3d;

  /* same hues, re-solved for the dark lightness band (L 0.48-0.67) */
  --chart-1: #563bff;  --chart-2: #df3400;  --chart-3: #009864;  --chart-4: #c45596;
  --chart-5: #0076cf;  --chart-6: #d17200;  --chart-7: #0095dc;  --chart-8: #9a37da;

  --ramp-1: #c2c8e9; --ramp-2: #a6b1f1; --ramp-3: #8c98f6; --ramp-4: #747dfb; --ramp-5: #605efe;

  --shadow-1: 0 1px 2px rgba(0,0,0,.5);
  --shadow-2: 0 2px 6px rgba(0,0,0,.55);
  --shadow-3: 0 8px 20px rgba(0,0,0,.6);
  --shadow-4: 0 16px 40px rgba(0,0,0,.7);
  }
}

/* ── the theme control itself ─────────────────────────────────────────────── */
.theme-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: var(--radius-md, 8px);
  border: 1px solid var(--border-default, #cbd5e1);
  background: var(--surface-card, #ffffff);
  color: var(--text-secondary, #475569);
  font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; line-height: 1;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.theme-toggle:hover { color: var(--accent, #4f46e5); border-color: var(--accent, #4f46e5); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent, #4f46e5); outline-offset: 2px; }
/* Inside the dark navigation bar the control sits on ITS ground, not the page's,
   so it takes the inverse surface rather than the card. */
.nav-bar .theme-toggle {
  background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.14); color: #cbd5e1;
}
.nav-bar .theme-toggle:hover { color: #a5b4fc; border-color: rgba(165,180,252,.5); }
/* Standalone pages have no navigation to sit in. */
.theme-toggle--floating {
  position: fixed; right: 14px; bottom: 14px; z-index: 9998;
  box-shadow: var(--shadow-3, 0 8px 20px rgba(15,23,42,.12));
}
@media (max-width: 640px) { .theme-toggle-label { display: none; } }

/* The page itself. Without this the body keeps the browser default white and
   only the panels change, which reads as a half-applied theme. */
body { background: var(--surface-page); color: var(--text-primary); }
