/* ════════════════════════════════════════════════════════════════════════
   TRUST SLATE v3 — shared token source for the satellite pages
   (admin console, sign-in, signup, members, activity, reset, /check).

   app.css carries its own embedded copy of this block (its END-of-sheet
   v3 zone, 2026-08-09) — the two must stay in step. This file exists so
   the non-SPA pages stop keeping private palettes: each page <link>s it
   AFTER its own stylesheet, and because :root / [data-theme] blocks are
   equal-specificity, source order lets these declarations supersede every
   per-page token generation without touching the page sheets' layout CSS.

   That ordering also bridges polarity: index.css / signup.css declare
   light values in :root and dark in [data-theme="dark"] (the old v2
   mirror). This sheet's :root (dark) outranks both by source order, and
   its [data-theme="light"] block wins whenever the html attribute says
   light — so both page conventions converge on the same v3 behaviour.

   Rules enforced here (same as the app):
   · Gold = identity + at most ONE primary action per screen. Old yellow
     accent names (--yellow, --yellow-soft, --yellow-hi) alias to blue;
     gold is only reachable through --gold / --gold-fill / --cta.
   · Semantic colour is diagnostic, never decorative.
   · No neutral greys — every neutral carries the ~212° blue hue.
   · Inter for prose; JetBrains Mono for measured values.
   · One elevation level: cards sit on canvas via --card-shadow.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Self-hosted fonts (same files the app ships — one cache entry) ───── */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/static/fonts/inter-latin-var.woff2?v=20260809a') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/jetbrains-mono-latin-var.woff2?v=20260809a') format('woff2');
}

/* ── Tokens: three tiers (Trust Slate: Chrome, 2026-08-27) ────────────
   Mirrors app.css's END-of-sheet token zone — the two must stay in step.
   Tier 1 = spec-named canonical (chrome/canvas/ink/gold/viz); tier 2 =
   the v3 names re-pointed as aliases; tier 3 = the satellite legacy
   union below, unchanged, chaining through. Chrome is theme-invariant. */
:root {
  /* Chrome (frame — theme-invariant) */
  --chrome-900: #0F1330;
  --chrome-800: #171C42;
  --chrome-600: #4A55A2;
  --chrome-500: #5D68B4;
  --chrome-on: #FFFFFF;
  --chrome-on-muted: #B7BDDD;
  --chrome-hair: rgba(183,189,221,.16);
  --chrome-ok: #9CCB8C;
  --chrome-warn: #ECA96B;
  --chrome-crit: #F0A296;

  /* Canvas (dark) — indigo-tinted, shared hue axis with the chrome */
  --canvas: #0A0D1F;
  --surface: #12162E;
  --surface-sunken: #181D3C;
  --border: #262C55;
  --border-strong: #363E75;
  --tint-info: #1B2150;

  /* Ink (dark) */
  --ink-900: #E9EBF5;
  --ink-700: #CBD0E8;
  --ink-500: #A6AECB;
  --ink-300: #5A628A;

  /* Brand */
  --gold: #E2B75C;
  --gold-hover: #EDC97C;
  --gold-on: #1A1204;

  /* Viz — diagnostic; dark fills are AA as text so -text == fill */
  --viz-critical: #D98876;  --viz-critical-text: #D98876;
  --viz-warn: #E29A3F;      --viz-warn-text: #E29A3F;
  --viz-ok: #8FBF7F;        --viz-ok-text: #8FBF7F;
  --viz-neutral: #9AA3BD;   --viz-neutral-text: #9AA3BD;
  --viz-info: #97A0DC;      --viz-info-text: #97A0DC;
  --blue-hi: #B4BCEA;

  --crit-wash: rgba(217,136,118,.13);  --crit-bd: rgba(217,136,118,.32);
  --warn-wash: rgba(226,154,63,.13);   --warn-bd: rgba(226,154,63,.32);
  --ok-wash:   rgba(143,191,127,.13);  --ok-bd:   rgba(143,191,127,.32);
  --unk-wash:  rgba(154,163,189,.13);  --unk-bd:  rgba(154,163,189,.32);
  --blue-bd: rgba(151,160,220,.34);

  --card-shadow: 0 14px 32px -22px rgba(0,0,0,.9);
  --pop-shadow: 0 1px 2px rgba(0,0,0,.35), 0 20px 44px -14px rgba(0,0,0,.70);

  /* Shape — card/chip/tile 4 (Chrome spec) · control 6 */
  --radius-ctl: 6px;
  --radius-card: 4px;
  --radius-chip: 4px;
  --radius-tile: 4px;
  --radius-sm: 6px; --radius-md: 6px; --radius-lg: 4px;
  --radius-pill: 100px;

  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Page-treatment tokens (theme-forked; re-hued onto viz-info) */
  --row-zebra: rgba(233,235,245,.03);
  --focus-ring: rgba(151,160,220,.22);
  --glow: rgba(151,160,220,.10);
  --top-grad: linear-gradient(180deg, rgba(151,160,220,.06) 0%, transparent 32%);
  --dot: rgba(180,188,234,.10);
  --cta-on: var(--gold-on);

  /* ── Tier 2: v3 names → canonical ─────────────────────────────────── */
  --surface-2: var(--surface-sunken);
  --track: var(--surface-sunken);
  --line: var(--border);
  --line-strong: var(--border-strong);
  --ink-1: var(--ink-900);
  --ink-2: var(--ink-700);
  --ink-3: var(--ink-500);
  --blue: var(--viz-info);
  --blue-wash: var(--tint-info);
  --gold-fill: var(--gold);
  --crit: var(--viz-critical-text);
  --warn: var(--viz-warn-text);
  --ok:   var(--viz-ok-text);
  --unk:  var(--viz-neutral-text);

  /* ── Legacy alias table (union across the satellite pages + the old
        the retired skyqon-ui.css) — declared as var() references so the light flip
        propagates without re-assertion. ─────────────────────────────── */
  /* Ink */
  --text: var(--ink-1);
  --text-1: var(--ink-1);
  --text-primary: var(--ink-1);
  --ink: var(--ink-1);
  --input-text: var(--ink-1);
  --text-secondary: var(--ink-2);
  --text-2: var(--ink-2);
  --ink-soft: var(--ink-2);
  --text-caption: var(--ink-3);
  --text-3: var(--ink-3);
  --text-muted: var(--ink-3);
  --muted: var(--ink-3);
  --input-placeholder: var(--ink-3);
  /* Surfaces */
  --navy: var(--canvas);
  --paper: var(--canvas);
  --canvas-top: var(--canvas);
  --canvas-bot: var(--canvas);
  --navy-2: var(--surface-2);
  --navy-mid: var(--surface-2);
  --navy-deep: var(--canvas);
  --surface-sub: var(--surface-2);
  --input-bg: var(--surface-2);
  --chip-bg: var(--surface-2);
  --card-bg: var(--surface);
  --card: var(--surface);
  --surface-1: var(--surface);
  /* ⚠️ --border / --border-strong are CANONICAL (defined above) — they must
     never be re-aliased here: `--border: var(--line)` after
     `--line: var(--border)` is a cycle, and a cyclic custom property is
     INVALID at computed-value time. Shipped that way, every dark-mode border
     on the satellite pages fell back to currentColor (full-strength ink)
     instead of the hairline. Caught by spa_chrome_check.js (B6). */
  --line-soft: var(--line);
  --card-bd: var(--line);
  --border-bright: var(--line-strong);
  --card-bd-hover: var(--line-strong);
  --input-border: var(--line-strong);
  /* Gold discipline: the old yellow accent names become system blue.
     Gold is applied only through --gold / --gold-fill / --cta. */
  --yellow: var(--blue);
  --yellow-soft: var(--blue);
  --cyan: var(--blue);
  --accent: var(--blue);
  --link: var(--blue);
  --yellow-hi: var(--blue-hi);
  --blue-700: var(--blue-hi);
  --blue-strong: var(--blue-hi);
  --blue-tint: var(--blue-wash);
  --blue-line: var(--blue-bd);
  --yellow-text: #FFFFFF;    /* ink on what is now a blue fill */
  /* Gold family */
  --gold-strong: var(--gold);
  --cta: var(--gold-fill);
  /* Semantic */
  --crit-bg: var(--crit-wash);
  --crit-tx: var(--crit);
  --crit-ln: var(--crit-bd);
  --red: var(--crit);
  --red-bg: var(--crit-wash);
  --err: var(--crit);
  --bad: var(--crit);
  --danger: var(--crit);
  --warn-bg: var(--warn-wash);
  --warn-tx: var(--warn);
  --warn-ln: var(--warn-bd);
  --warn-strong: var(--warn);
  --warn-bold: var(--warn);
  --amber: var(--warn);
  --ok-bg: var(--ok-wash);
  --ok-tx: var(--ok);
  --ok-ln: var(--ok-bd);
  --green: var(--ok);
  --green-bright: var(--ok);
  --green-bg: var(--ok-wash);
  --good: var(--ok);
  --neutral: var(--unk);
  --neutral-bg: var(--unk-wash);
  --neutral-bd: var(--unk-bd);
  /* Type + shape + depth */
  --font: var(--font-sans);
  --mono: var(--font-mono);
  --radius-control: var(--radius-ctl);
  --shadow-card: var(--card-shadow);
  --shadow: var(--card-shadow);
  --shadow-1: var(--card-shadow);
  --shadow-2: var(--card-shadow);
  --shadow-lg: var(--pop-shadow);
  --shadow-pop: var(--pop-shadow);
  --shadow-btn: none;        /* v3: no glow under buttons — one elevation level */
  --shadow-btn-hi: none;
}

/* ── Tokens: LIGHT (canonical only — every alias re-resolves) ─────────── */
[data-theme="light"] {
  --canvas: #FFFFFF;
  --surface: #FFFFFF;
  --surface-sunken: #F6F7FA;
  --border: #E2E5EC;
  --border-strong: #C8CDD8;
  --tint-info: #EEF1FA;

  --ink-900: #14161C;
  --ink-700: #1C2637;
  --ink-500: #2F3A4D;
  --ink-300: #98A0B0;

  --gold: #B98A22;
  --gold-hover: #A2761A;

  --viz-critical: #A34A38;  --viz-critical-text: #A34A38;
  --viz-warn: #B87333;      --viz-warn-text: #9A5F08;
  --viz-ok: #6F9A5E;        --viz-ok-text: #41703A;
  --viz-neutral: #8A93A8;   --viz-neutral-text: #5D6675;
  --viz-info: #4A55A2;      --viz-info-text: #4A55A2;
  --blue-hi: #3A4485;

  --crit-wash: #F6ECE9;  --crit-bd: #E5C7BF;
  --warn-wash: #F9EFE2;  --warn-bd: #EAD7BC;
  --ok-wash:   #ECF3E9;  --ok-bd:   #CFDFC8;
  --unk-wash:  #EFF1F5;  --unk-bd:  #D6DBE4;
  --blue-bd: #C9CFE8;

  --card-shadow: 0 1px 2px rgba(16,24,40,.05);
  --pop-shadow: 0 1px 2px rgba(16,24,40,.06), 0 18px 40px -12px rgba(16,24,40,.18);

  --row-zebra: rgba(20,22,28,.025);
  --focus-ring: rgba(74,85,162,.20);
  --glow: rgba(74,85,162,.09);
  --top-grad: linear-gradient(180deg, #EEF1FA 0%, transparent 30%);
  --dot: rgba(74,85,162,.14);
  --yellow-text: #FFFFFF;
  /* Chrome tokens deliberately NOT re-declared: one indigo frame, both themes. */
}

/* ── Base surface + type — flat canvas, 14px/1.5, Inter ───────────────── */
body,
[data-theme="light"] body {
  background: var(--canvas);
  background-image: none;
  background-attachment: initial;
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-1);
  transition: background-color .25s ease, color .25s ease;
}

/* Rule 4 as one import: every measured value gets `.mono`. */
.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "zero" 1;
}

/* ── One elevation level ──────────────────────────────────────────────── */
.card,
[data-theme="light"] .card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
}

/* ── Shared chrome cleanup (classes common to the satellite pages) ────── */
/* Eyebrows are structure, not identity: ink-3, sans, tracked caps. */
.eyebrow, .page-eyebrow,
[data-theme="light"] .eyebrow,
[data-theme="light"] .page-eyebrow {
  font-family: var(--font-sans); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}
/* Theme toggle active: blue wash (was a yellow tint on every page). */
.theme-toggle button.active,
[data-theme="light"] .theme-toggle button.active {
  background: var(--blue-wash); color: var(--blue);
}
/* Selection checkboxes + focus: system blue. */
input[type="checkbox"] { accent-color: var(--blue); }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* ── a11y: skip link + visually-hidden ────────────────────────────────────
   Matches the pattern already used on the marketing sites
   (web/services-site/src/skyqon-services.css). The skip link is off-screen
   until it takes keyboard focus, so it costs nothing visually but gives
   keyboard users a way past the header/nav on every page. */
.skip-link {
  position: fixed; left: -9999px; top: 0; z-index: 200;
  background: var(--accent); color: #fff; font-weight: 600; font-size: 0.9rem;
  padding: 10px 16px; border-radius: 0 0 10px 0;
}
.skip-link:focus { left: 0; }
/* text present for assistive tech, invisible on screen */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
