/* Cockpit design system — shared token layer + primitives.
 *
 * Loaded via <link rel="stylesheet" href="/lib/cockpit.css"> from app.html,
 * activate.html and reset-password.html (CSP styleSrc allows 'self').
 * Precedent: /lib/nav.js — one copy, no drift.
 *
 * index.html is NOT yet on this file: it shipped in PR #5 with its own inline
 * copy of these tokens, so the two can drift. Migrating it is deliberately left
 * out of this change to avoid regressing the live landing page.
 *
 * Token NAMES are frozen: app.html has ~400 var() references against them.
 * Renaming orphans those references silently, so values move and names do not.
 *
 * THE CHROME / SEMANTIC BOUNDARY
 * This file themes CHROME only. It deliberately contains no flight-category
 * color. VFR/MVFR/IFR/LIFR and the route/waypoint magenta are semantic — a
 * pilot reads them by FAA convention — and they stay in app.html where they
 * are rendered. The old chrome accent shared its hex with MVFR; that hex
 * appears nowhere in this file, so grepping it finds only semantic sites.
 *
 * MINIMUM BROWSERS
 * Tints use color-mix(): Chrome/Edge 111+, Safari 16.2+, Firefox 113+.
 * Older browsers drop those declarations and show the plain surface
 * underneath (a missing tint, never missing text or controls). The few
 * opaque mixes (map layer buttons, the prog-chart panel) carry a plain
 * var() fallback declared just before them in app.html.
 */

/* ── Tokens ─────────────────────────────────────────────── */

:root {
  /* Ground ladder. Raised is lighter; recessed is darker. */
  --sky:#0c0e10;
  --sky-card:#15181b;
  --sky-card2:#101316;
  --sky-mid:#0a0c0e;
  --panel-deep:#0a0c0e;

  --accent:#f0a93b;
  --accent-bright:#ffba4d;
  --accent-dim:rgba(240,169,59,.12);
  /* Label ink for a solid accent fill. White on amber is 1.8:1 — unreadable.
   * The theme that inverts the ground must invert this too. */
  --accent-on:#0c0e10;
  --gold:var(--accent);

  --green:#5fd08a;
  --red:#ff5252;
  /* Caution. Sits ~11 degrees hotter than --accent so it is not brand amber.
   * Hue alone does not carry this — see the .val ladder note below. */
  --amber:#ff7a1a;

  --text:#f3f1ec;
  --text-muted:#9aa0a4;
  --text-dim:#6d7378;

  /* Three border tiers by JOB, not by opacity taste:
   * --border       decorative hairline (WCAG-exempt)
   * --border-mid   panel edge / divider
   * --border-strong component boundary — inputs, focus. Solved for 3:1 on the
   *                worst ground (0.38 -> 3.51:1), not on the easiest. */
  --border:rgba(255,255,255,.08);
  --border-mid:rgba(255,255,255,.12);
  --border-strong:rgba(255,255,255,.38);

  /* Outline that separates a semantic marker/chip from its ground without
   * touching the semantic fill. Inverts with the ground. */
  --marker-ring:rgba(255,255,255,.9);

  /* Ground for controls floating ON the chart raster. Opaque enough to scrim
   * the sectional beneath; five sites hand-inlined this before it was a token. */
  --scrim:rgba(12,14,16,.88);

  /* Ported by contrast ratio (1.04:1), not by alpha, so it whispers equally
   * in both themes. */
  --grid:rgba(255,255,255,.022);

  --font-mono:'Space Mono',monospace;
  --font-display:'Archivo',sans-serif;
  /* The system has two faces. These aliases keep existing call sites valid. */
  --font-body:var(--font-display);
  --font-sans:var(--font-display);

  --r-sm:6px; --r-md:8px; --r-lg:10px; --r-xl:14px; --r-2xl:16px;

  /* Flight category (owner answer 28; conventions §F.1): the dot, the letter
   * on it and the word's text colour. Mirrors wx-display.js CATEGORY_TOKENS,
   * pinned by test/wx-display.test.js. Dots and letters are the same in both
   * themes; the text colour follows the ground. */
  --cat-vfr-dot:#17a054;  --cat-vfr-letter:#0f2040;  --cat-vfr-text:#28d47a;
  --cat-mvfr-dot:#1a60d4; --cat-mvfr-letter:#ffffff; --cat-mvfr-text:#3d9fff;
  --cat-ifr-dot:#cc1111;  --cat-ifr-letter:#ffffff;  --cat-ifr-text:#ff5252;
  --cat-lifr-dot:#8a22cc; --cat-lifr-letter:#ffffff; --cat-lifr-text:#c45af5;
  --cat-unk-dot:#5f6b78;  --cat-unk-letter:#ffffff;  --cat-unk-text:#9aa5b1;
  /* The airport layer's marker (D-33): one blue for every airport, no
   * letter. Mirrors wx-display.js AIRPORT_MARKER. */
  --ap-dot:#2f80ed;
}

[data-theme="light"] {
  /* Sectional paper, not white: one warm ink hue (43,34,20) at varying
   * dilution. Raised-is-lighter is preserved; only the ground inverts. */
  --sky:#f5f0e6;
  --sky-card:#fdfbf7;
  --sky-card2:#efe9dc;
  --sky-mid:#e8e1d2;
  --panel-deep:#e8e1d2;

  /* #b06800 (the previously shipped light gold) is 4.35:1 on white and 4.21:1
   * on this panel — under 4.5 for the 11px eyebrow it colors. Darkened one
   * step to clear AA on the WORST ground: a mid-dark amber's worst ground is
   * the darkest panel, not the lightest. */
  --accent:#8f5200;
  /* Inverted semantic, not an inverted value: on a light ground "brighter"
   * would mean less contrast, so hover goes deeper. */
  --accent-bright:#7d4700;
  --accent-dim:rgba(143,82,0,.12);
  --accent-on:#ffffff;
  --gold:var(--accent);

  --green:#127038;
  --red:#b3271f;
  --amber:#a33d00;

  --text:#1c1a15;
  --text-muted:#5c574c;
  --text-dim:#7d7768;

  /* White-alpha borders are invisible on paper; these are ink-alpha.
   * --border-strong solved at 0.56 -> 3.45:1 worst. The dark theme's 0.50
   * does not port: different ink, different ground. */
  --border:rgba(43,34,20,.14);
  --border-mid:rgba(43,34,20,.24);
  --border-strong:rgba(43,34,20,.56);

  --marker-ring:#1c1a15;
  --grid:rgba(43,34,20,.030);
  --scrim:rgba(245,240,230,.90);

  --cat-vfr-text:#0a7a3a;
  --cat-mvfr-text:#1a6fd4;
  --cat-ifr-text:#cc2222;
  --cat-lifr-text:#7a1fb8;
  --cat-unk-text:#5f6b78;
}

/* ── Page ground ────────────────────────────────────────── */

.ck-grid {
  background-color:var(--sky);
  background-image:
    repeating-linear-gradient(0deg,var(--grid) 0 1px,transparent 1px 48px),
    repeating-linear-gradient(90deg,var(--grid) 0 1px,transparent 1px 48px);
}

/* ── Eyebrow ────────────────────────────────────────────── */

.ck-eyebrow {
  font-family:var(--font-mono);
  font-size:11px;
  text-transform:uppercase;
  letter-spacing:.22em;
  color:var(--accent);
}
.ck-eyebrow::before { content:"// "; }

/* Muted section heading (sidebar groups, panel headers). The quiet sibling of
 * the amber eyebrow: same mono/uppercase language, no accent, tighter tracking.
 * Type only — callers add their own layout (margin, flex row, gap). */
.ck-section-label {
  font-family:var(--font-mono);
  font-size:11px;
  font-weight:500;
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--text-muted);
}

/* ── Buttons ────────────────────────────────────────────── */

.btn, .form-btn {
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  padding:7px 14px;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  font-family:var(--font-mono);
  font-size:12px;
  line-height:1;
  cursor:pointer;
  text-decoration:none;
  transition:background .12s,border-color .12s,color .12s;
}
.btn:focus-visible, .form-btn:focus-visible, .form-input:focus-visible {
  outline:2px solid var(--accent);
  outline-offset:2px;
}

.btn-primary, .form-btn {
  background:var(--accent);
  color:var(--accent-on);
}
.btn-primary:hover, .form-btn:hover { background:var(--accent-bright); }

/* Amber is now the accent, so a solid gold button would be a duplicate
 * .btn-primary. This is the outlined amber tier instead. */
.btn-gold {
  background:transparent;
  color:var(--accent);
  border-color:var(--accent);
}
.btn-gold:hover { background:var(--accent-dim); }

.btn-ghost {
  background:transparent;
  color:var(--text-muted);
  border-color:var(--border-strong);
}
.btn-ghost:hover { background:var(--accent-dim); color:var(--text); }

.btn-red   { background:color-mix(in srgb,var(--red) 15%,transparent);   color:var(--red);   border-color:color-mix(in srgb,var(--red) 30%,transparent); }
.btn-red:hover   { background:color-mix(in srgb,var(--red) 25%,transparent); }
.btn-green { background:color-mix(in srgb,var(--green) 15%,transparent); color:var(--green); border-color:color-mix(in srgb,var(--green) 30%,transparent); }
.btn-green:hover { background:color-mix(in srgb,var(--green) 25%,transparent); }

.btn:disabled, .form-btn:disabled { opacity:.5; cursor:not-allowed; }

/* ── Forms ──────────────────────────────────────────────── */

.form-label {
  display:block;
  margin-bottom:6px;
  font-family:var(--font-mono);
  font-size:10px;
  text-transform:uppercase;
  letter-spacing:.06em;
  color:var(--text-muted);
}

.form-input {
  width:100%;
  padding:8px 10px;
  /* Neutral, not accent-tinted: an amber-washed field reads as a warning. */
  background:color-mix(in srgb,var(--text) 4%,transparent);
  border:1px solid var(--border-strong);
  border-radius:var(--r-sm);
  color:var(--text);
  font-family:var(--font-mono);
  font-size:12px;
}
.form-input::placeholder { color:var(--text-dim); }
/* Scoped to :not(:focus-visible) so pointer focus stays quiet without also
   suppressing the keyboard focus ring declared above — a bare `outline:none`
   here wins on source order and removes it for keyboard users too. */
.form-input:focus:not(:focus-visible) {
  outline:none;
}
.form-input:focus {
  border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-dim);
}

/* Inline form error. Hidden until a caller sets display:block (inline style
 * wins over this rule's display:none), matching the existing show/hide JS. */
.form-err {
  display:none;
  margin-top:8px;
  font-family:var(--font-mono);
  font-size:12px;
  color:var(--red);
}

/* ── Card ───────────────────────────────────────────────── */

.ck-card {
  background:var(--sky-card);
  border:1px solid var(--border);
  border-radius:var(--r-xl);
  padding:16px;
}
.ck-card-alt { background:var(--sky-card2); }
.ck-card-deep { background:var(--panel-deep); }

/* ── Modal ──────────────────────────────────────────────── */

.ck-modal-backdrop {
  position:fixed; inset:0; z-index:2000;
  display:flex; align-items:center; justify-content:center;
  padding:16px;
  /* Neutral black scrim works over either ground. */
  background:rgba(0,0,0,.6);
  -webkit-backdrop-filter:blur(4px);
  backdrop-filter:blur(4px);
}
.ck-modal {
  width:100%; max-width:520px;
  max-height:85vh; overflow-y:auto;
  background:var(--sky-card);
  border:1px solid var(--border-mid);
  border-radius:var(--r-2xl);
  /* Matches the blur/spread of index.html's frozen modal so the same component
   * reads identically landing-to-app; only the scrim alpha differs. */
  box-shadow:0 24px 80px rgba(0,0,0,.6);
}
.ck-modal-header {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px;
  padding:14px 16px;
  border-bottom:1px solid var(--border);
}
.ck-modal-title {
  font-family:var(--font-display);
  font-size:15px;
  font-weight:700;
  color:var(--text);
}
.ck-modal-close {
  background:color-mix(in srgb,var(--text) 6%,transparent);
  border:none;
  border-radius:var(--r-sm);
  width:26px; height:26px;
  color:var(--text-muted);
  cursor:pointer;
}
.ck-modal-close:hover { color:var(--text); }
.ck-modal-body { padding:16px; }
.ck-modal-footer {
  display:flex; justify-content:flex-end; gap:8px;
  padding:14px 16px;
  border-top:1px solid var(--border);
}

/* ── Scrollbars ─────────────────────────────────────────── */

::-webkit-scrollbar { width:8px; height:8px; }
::-webkit-scrollbar-track { background:transparent; }
::-webkit-scrollbar-thumb {
  background:var(--border-strong);
  border-radius:var(--r-sm);
}
::-webkit-scrollbar-thumb:hover { background:var(--text-dim); }

/* ── Keyframes ──────────────────────────────────────────── */

@keyframes ckPulse {
  0%,100% { opacity:1; box-shadow:0 0 0 0 var(--accent-dim); }
  50%     { opacity:.75; box-shadow:0 0 0 6px transparent; }
}
@keyframes ckSweep {
  from { background-position:-140% 0; }
  to   { background-position:240% 0; }
}
.ck-sweep {
  background-image:linear-gradient(90deg,transparent 0%,var(--accent-dim) 50%,transparent 100%);
  background-size:60% 100%;
  background-repeat:no-repeat;
  animation:ckSweep 1.6s linear infinite;
}

@media (prefers-reduced-motion:reduce) {
  .ck-sweep { animation:none; }
  *, *::before, *::after { animation-duration:.01ms !important; animation-iteration-count:1 !important; }
  /* A busy indicator reports state rather than decorating, so the blanket rule
     above must not freeze it into a static ring. Slowed, not stopped. */
  .spinner { animation-duration:1.6s !important; animation-iteration-count:infinite !important; }
}
