:root {
  --bg: oklch(0.18 0.012 250);
  --bg-deep: oklch(0.13 0.014 252);
  --surface: oklch(0.22 0.014 252 / 0.78);
  --surface-solid: oklch(0.22 0.014 252);
  --surface-raised: oklch(0.27 0.014 252 / 0.85);
  --border: oklch(1 0 0 / 0.07);
  --border-strong: oklch(1 0 0 / 0.13);
  --divider: oklch(1 0 0 / 0.05);

  --fg: oklch(0.96 0.005 250);
  --fg-2: oklch(0.78 0.012 252);
  --fg-3: oklch(0.58 0.014 252);
  --fg-4: oklch(66.906% 0.01817 251.009);

  --c-cyan:   oklch(0.78 0.13 215);
  --c-red:    oklch(0.68 0.20 25);
  --c-yellow:  oklab(81.89% -0.00166 0.13191);
  --c-amber:  oklch(0.74 0.18 50);
  --c-mint:   oklch(0.78 0.14 165);
  --c-violet: oklch(0.72 0.14 295);

  --c-cyan-soft:   oklch(0.78 0.13 215 / 0.14);
  --c-red-soft:    oklch(0.68 0.20 25 / 0.16);
  --c-amber-soft:  oklch(0.80 0.15 75 / 0.16);
  --c-mint-soft:   oklch(0.78 0.14 165 / 0.16);
  --c-violet-soft: oklch(0.72 0.14 295 / 0.16);

  --radius-s: 6px;
  --radius:   10px;
  --radius-l: 14px;

  --shadow: 0 10px 40px -10px oklch(0 0 0 / 0.6), 0 2px 6px oklch(0 0 0 / 0.4);

  /* ---------- Surfaces ---------- */
  --strip-bg:             oklch(0.16 0.012 252 / 0.55);
  --chip-bg:              oklch(0.16 0.012 252 / 0.6);
  --surface-elevated:     oklch(0.25 0.014 252);
  --surface-hover:        oklch(0.27 0.014 252);
  --surface-muted:        oklch(0.30 0.014 252);
  --row-hover:            oklch(0.22 0.014 252 / 0.5);
  --row-hover-strong:     oklch(0.22 0.014 252 / 0.6);
  --meta-cell-bg:         oklch(0.13 0.012 252 / 0.6);
  --inset-bg:             oklch(0.13 0.012 252);
  --modal-overlay:        oklch(0 0 0 / 0.6);
  --mobile-head-bg:       oklch(0.20 0.014 252 / 0.6);
  --mobile-head-expanded: oklch(0.24 0.014 252 / 0.85);

  /* ---------- Map / markers ---------- */
  --popup-bg:        oklch(0.18 0.012 252 / 0.95);
  --popup-tip-bg:    oklch(0.18 0.012 252);
  --popup-shadow:    oklch(0.15 0.012 252 / 0.8);
  --label-bg:        oklch(0.13 0.012 252 / 0.85);
  --deep-ink:        oklch(0.15 0.012 252);
  --selected-bg:     oklch(0.20 0.03 215 / 0.4);

  /* d3-geo basemap (dark) */
  --ocean:            oklch(0.16 0.018 252);  /* original water color (dark mode) */
  --land:             oklch(0.23 0.015 242);
  --map-bg:           oklch(0% 0 0);  /* globe/space backdrop = original water color (kept distinct from --ocean) */
  --map-coast:        oklch(0.46 0.020 250);
  --map-border:       oklch(0.36 0.016 250);
  --map-graticule:    oklch(0.30 0.010 250 / 0.5);
  --map-route:        #557099;
  --map-runway:       oklch(0.80 0.010 250);
  --map-runway-unpaved: oklch(0.58 0.040 80);

  /* ---------- Brand mark ---------- */
  --brand-mark-from: oklch(0.32 0.05 220);
  --brand-mark-to:   oklch(0.20 0.03 250);

  /* ---------- Progress / bars ---------- */
  --bar-tick:    oklch(0.15 0.012 252 / 0.6);
  --cure-bar-to: oklch(0.85 0.10 180);

  /* ---------- Vignette ---------- */
  --vignette-edge:   oklch(0.08 0.014 252 / 0.55);
  --vignette-top:    oklch(0.10 0.014 252 / 0.35);
  --vignette-bottom: oklch(0.10 0.014 252 / 0.55);

  /* ---------- Color accents ---------- */
  --c-red-glow:           oklch(0.68 0.20 25 / 0.5);
  --c-red-border:         oklch(0.68 0.20 25 / 0.3);
  --c-mint-border:        oklch(0.78 0.14 165 / 0.3);
  --c-mint-glow:          oklch(0.78 0.14 165 / 0.6);
  --c-amber-border:       oklch(0.80 0.15 75 / 0.3);
  --c-cyan-border:        oklch(0.78 0.13 215 / 0.25);
  --c-cyan-border-strong: oklch(0.78 0.13 215 / 0.3);
  --c-cyan-halo:          oklch(0.78 0.13 215 / 0.35);
  --c-cyan-ring:          oklch(0.78 0.13 215 / 0.5);
  --c-cyan-light:         oklch(0.85 0.13 215);

  --pilot-text-shadow: 0 1px 2px oklch(0 0 0 / 0.85);
}

body.light-mode {
  --bg:             oklch(96.704% 0.00837 169.488);
  --bg-deep:        oklch(0.92 0.008 252);
  --surface:        oklch(0.99 0.003 250 / 0.82);
  --surface-solid:  oklch(0.98 0.004 250);
  --surface-raised: oklch(0.96 0.006 250 / 0.90);

  --border:        oklch(100% 0.00011 271.152 / 0.09);
  --border-strong: oklch(100% 0.00011 271.152 / 0.16);
  --divider:       oklch(60.67% 0.24714 29.058 / 0.06);

  --fg:   oklch(0.14 0.010 252);
  --fg-2: oklch(0.30 0.014 252);
  --fg-3: oklch(70.091% 0.15031 250.627);
  --fg-4: oklch(56.457% 0.00721 255.649);

  --c-cyan:   oklch(63.099% 0.10617 222.982);
  --c-red:    oklch(56.713% 0.20164 20.905);
  --c-yellow:  oklab(75.10900000000001% -0.00191 0.12096);
  --c-amber:  oklch(0.58 0.18 50);
  --c-mint:   oklch(70.11% 0.13234 163.183);
  --c-violet: oklch(54.892% 0.17631 291.081);

  --c-cyan-soft:  oklch(61.31% 0.10248 223.358);
  --c-red-soft:   oklch(51.267% 0.1814 20.965);
  --c-amber-soft: oklch(72.304% 0.15168 161.114);
  --c-mint-soft:  oklch(74.085% 0.14521 162.848 / 0.12);
  --c-violet-soft: oklch(46.343% 0.20558 290.53);

  --shadow: 0 8px 32px -8px oklch(80.304% 0.13679 223.532 / 0.486), 0 2px 6px oklch(100% 0.00011 271.152 / 0.08);

  /* ---------- Surfaces ---------- */
  --strip-bg:             oklch(0 0 0 / 0.04);
  --chip-bg:              oklch(0 0 0 / 0.05);
  --surface-elevated:     oklch(0.88 0.008 252);
  --surface-hover:        oklch(0.85 0.008 252);
  --surface-muted:        oklch(0.82 0.008 252);
  --row-hover:            oklch(0 0 0 / 0.04);
  --row-hover-strong:     oklch(0 0 0 / 0.05);
  --meta-cell-bg:         oklch(0 0 0 / 0.04);
  --inset-bg:             oklch(90% 0.00006 271.152);
  --mobile-head-bg:       oklch(0.90 0.008 252 / 0.8);
  --mobile-head-expanded: oklch(0.87 0.008 252 / 0.95);

  /* ---------- Map / markers ---------- */
  --popup-bg:        oklch(0.99 0.003 250 / 0.97);
  --popup-tip-bg:    oklch(0.99 0.003 250);
  --popup-shadow:    oklch(0 0 0 / 0.15);
  --label-bg:        oklch(0.96 0.006 250 / 0.9);
  --deep-ink:        oklch(0.14 0.010 252);
  --selected-bg:     oklch(0.20 0.03 215 / 0.08);
  --bar-tick:        oklch(0.96 0.006 250 / 0.6);

  /* d3-geo basemap (light) */
  --ocean:            oklch(0.82 0.025 252);  /* darker, clearer blue water in light mode */
  --land:             oklch(0.97 0.006 240);
  --map-bg:           oklch(0.93 0.012 240);  /* globe/space backdrop = original water color */
  --map-coast:        oklch(0.62 0.020 250);
  --map-border:       oklch(0.72 0.016 250);
  --map-graticule:    oklch(0.80 0.010 250 / 0.6);
  --map-route:        #557099;
  --map-runway:       oklch(0.42 0.012 250);
  --map-runway-unpaved: oklch(0.60 0.045 80);

  /* ---------- Color accents ---------- */
  --c-red-glow: oklch(0.68 0.20 25 / 0.25);
  --c-mint-glow: oklch(0.78 0.14 165 / 0.25);

--pilot-text-shadow: -1px -1px 4px rgb(221, 221, 221), 1px -1px 4px rgb(221, 221, 221), -1px 1px 4px rgb(221, 221, 221), 1px 1px 4px rgb(221, 221, 221);
}

body.light-mode .sample-chip { background: oklch(0.75 0 0); border-color: oklch(56.713% 0.20164 20.905); }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg-deep);
  color: var(--fg);
  font-family: "Inter", system-ui, sans-serif;
  font-feature-settings: "ss01", "ss02", "cv11";
}

.mono {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-feature-settings: "zero";
}

.pilot-type,
.pilot-body {
  text-shadow: var(--pilot-text-shadow);
}

/* ============ map (MapLibre GL + OpenFreeMap vector tiles) ============ */
/* Basemap (land/ocean/borders) and the route/pilot/runway lines are MapLibre GL
   layers; only the airport/pilot HTML markers + popup are overlay DOM here. */
.d3map { position: relative; overflow: hidden; }
.maplibregl-canvas { outline: none; }
.d3map-markers, .d3map-popups { position: absolute; inset: 0; pointer-events: none; overflow: visible; z-index: 3; }

/* attribution (OSM/OpenFreeMap) — required; themed + compact */
.maplibregl-ctrl-attrib {
  background: var(--leaflet-attr-bg, rgba(0,0,0,0.5)) !important;
  color: var(--fg-4) !important; font-size: 9px !important;
  font-family: "JetBrains Mono", monospace; border-radius: var(--radius-s) !important;
}
.maplibregl-ctrl-attrib a { color: var(--fg-3) !important; }
body.mobile .maplibregl-ctrl-attrib { display: none; }

/* HTML marker wrappers (positioned by JS via transform; clickable) */
.ap-wrap, .pilot-wrap { position: absolute; left: 0; top: 0; pointer-events: auto; cursor: pointer; will-change: transform; }
/* Stacking by kind, not by DOM order: board airports under off-board dots under
   aircraft. The markers are created as they first appear, so by DOM order a dot
   that appeared later sat over the planes and took the click meant for one. */
.ap-wrap { z-index: 1; }
.offmap-wrap { z-index: 2; }
.pilot-wrap { z-index: 3; }

/* Off-board airport dot (js/offmap.js) — a real airport a tracked pilot is at or
   filed to that is NOT part of the game board. Deliberately inert: no rings, no
   lab badge, no level colour, and pointer-events:none so it never intercepts a
   map click or swallows the wheel. --fg-4 is this app's established "off /
   unknown" tone (see .clock-conn .dot) and stays near-neutral in both themes.
   Unscoped on purpose: index.html and admin.html both load this file, and unlike
   .ap-marker — which is duplicated in index.html's inline <style> AND under
   `body.admin` below — one definition serves both. */
.offmap-wrap { position: absolute; left: 0; top: 0; pointer-events: none; will-change: transform; }
/* Added by offmap.js only when the page passes an onSelect (index.html, whose
   popup carries the ground manifest); admin.html's dots stay inert. */
.offmap-wrap.offmap-clickable { pointer-events: auto; cursor: pointer; }
/* An off-board core is 7px against a board core's 14-26px, so the board's
   chevron and tally offsets would read as much wider gaps here. Both values
   stay 2px apart, which is what keeps the tally clear of the chevron's top
   edge. See .parked-tally / .ap-chevron below. */
.offmap-marker {
  position: relative; display: grid; place-items: center;
  --chevron-top: -13px; --parked-gap: 15px;
}
.offmap-core {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--fg-4);
  box-shadow: 0 0 0 1px var(--popup-shadow);
}
.offmap-label {
  position: absolute; top: 11px; left: 50%; transform: translateX(-50%);
  font-family: "JetBrains Mono", monospace; font-size: 9px; font-weight: 500;
  color: var(--fg-4); white-space: nowrap;
  background: var(--label-bg);
  padding: 1px 4px; border-radius: 3px;
  border: 1px solid var(--border);
}

/* Parked-aircraft tally (js/parked.js) — a green plane, then how many aircraft
   are on the ground at this airport: cure carriers, sample carriers, deadheads,
   each number in the color of that aircraft's pilot marker (cyan, red, mint).
   All three are always in the markup (Parked.counts), a zero classed `zero`.
   Normally color says which is which, so zeros are hidden and an airport of
   deadheads reads "✈ 8". Color-vision mode (body.cvd-mode) cannot lean on
   color, so there every zero shows — "✈ 0 0 8" — and a number's place says
   what it counts. One badge is the same size at 3 aircraft or 30, and it gets
   the airport label's backing because digits have to be read against the map.
   It sits just above the airport. Only the marker the local pilot is at —
   classed `here` by index.html and js/offmap.js — lifts it by --parked-gap, to
   clear the "you are here" chevron below.
   Unscoped on purpose, like the .offmap-* block above: board markers
   (index.html) and off-board dots share one definition, and only --parked-gap
   differs between them. */
.parked-tally {
  position: absolute; left: 50%; bottom: calc(100% + 6px);
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 4px;
  font-family: "JetBrains Mono", monospace; font-size: 13px; font-weight: 700; line-height: 1;
  white-space: nowrap;
  background: var(--label-bg);
  padding: 2px 5px; border-radius: 4px;
  border: 1px solid var(--border);
  pointer-events: none;
}
/* An off-board dot keeps its (empty) box between aircraft; no badge then. */
.parked-tally:empty { display: none; }
.parked-tally .plane { color: var(--c-mint); font-size: 14px; font-variant-emoji: text; }
.parked-tally b { font-weight: inherit; color: var(--c-cyan); }
.parked-tally b.sample   { color: var(--c-red); }
.parked-tally b.deadhead { color: var(--c-mint); }
.parked-tally b.zero { display: none; }
body.cvd-mode .parked-tally b.zero { display: inline; }
.ap-marker.here > .parked-tally,
.offmap-marker.here > .parked-tally { bottom: calc(100% + var(--parked-gap)); }

/* "You are here" chevron — same cyan as the lab badge — points down at the
   airport the local pilot is currently at. Board markers (index.html) and
   off-board dots (js/offmap.js, index.html only) both draw it, so like
   .parked-tally above it is defined once, unscoped: admin.html loads this file
   but never emits the element, on the board or off it.
   --chevron-top places it; the default suits a board core, and the smaller
   off-board dot pulls it in below. */
.ap-chevron {
  position: absolute; top: var(--chevron-top, -16px); left: 50%; transform: translateX(-50%);
  width: 16px; height: 10px;
  fill: none; stroke: var(--c-cyan); stroke-width: 2.5px;
  stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 3px var(--c-cyan));
  pointer-events: none;
}

/* How far a tally lifts to clear the chevron on a board marker. A custom
   property so the single .parked-tally rule serves both contexts — .ap-marker
   itself is declared twice (index.html's inline <style> and `body.admin`
   below) and neither copy has to change. */
.ap-marker { --parked-gap: 18px; }
/* The off-board pair lives on .offmap-marker above, next to the dot it sizes. */

/* custom popup (reuses .leaflet-popup-* styling; this adds positioning) */
.map-popup {
  position: absolute; left: 0; top: 0;
  transform: translate(-50%, calc(-100% - 16px));
  min-width: 200px; max-width: 340px;
  padding: 6px 8px; pointer-events: auto; z-index: 6;
}
.map-popup-close {
  position: absolute; top: 2px; right: 6px;
  background: none; border: none; font-size: 16px; line-height: 1;
  cursor: pointer; padding: 2px 4px;
}
.map-popup-tip {
  position: absolute; left: 50%; bottom: -7px; width: 13px; height: 13px;
  transform: translateX(-50%) rotate(45deg); border-top: none; border-left: none;
}

/* ── Consent Notice Overlay ── */
#consent-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: oklch(0 0 0 / 0.80);
  backdrop-filter: blur(6px) saturate(0.6);
  -webkit-backdrop-filter: blur(6px) saturate(0.6);
  align-items: center;
  justify-content: center;
  padding: 5dvh 5vw;
}

html.consent-pending #consent-overlay { display: flex; }

.consent-panel {
  background: var(--bg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow);
  max-width: 660px;
  width: 100%;
  max-height: 90dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.consent-hd {
  padding: 18px 24px 15px;
  border-bottom: 1px solid var(--divider);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.consent-badge {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--c-cyan);
  background: var(--c-cyan-soft);
  border: 1px solid var(--c-cyan-border);
  border-radius: var(--radius-s);
  padding: 2px 8px;
  flex-shrink: 0;
}

.consent-hd h2 {
  font-size: 14px;
  font-weight: 700;
  color: var(--fg);
  margin: 0;
  letter-spacing: 0.03em;
}

.consent-bd {
  padding: 18px 24px;
  overflow-x: auto;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  font-size: 13px;
  line-height: 1.65;
  color: var(--fg-2);
}

.consent-bd h3 {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-cyan);
  margin: 20px 0 8px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--divider);
}

.consent-bd h3:first-child { margin-top: 0; }
.consent-bd p  { margin: 0 0 9px; }
.consent-bd ul { margin: 0 0 9px; padding-left: 18px; }
.consent-bd li { margin-bottom: 5px; }
.consent-bd a  { color: var(--c-cyan); text-decoration: none; }
.consent-bd a:hover { text-decoration: underline; }
.consent-bd strong { color: var(--fg); font-weight: 600; }

.consent-bd code {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  background: var(--inset-bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1px 5px;
  color: var(--c-yellow);
}

.consent-tbl {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--border);
  border-radius: var(--radius-s);
  overflow: hidden;
  margin-bottom: 14px;
  font-size: 12px;
}

.consent-tbl th,
.consent-tbl td {
  padding: 7px 11px;
  text-align: left;
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}

.consent-tbl thead tr { background: var(--strip-bg); }
.consent-tbl th { font-size: 11px; font-weight: 600; color: var(--fg-3); letter-spacing: 0.04em; }
.consent-tbl td { color: var(--fg-2); }
.consent-tbl tbody tr:last-child td { border-bottom: none; }
.consent-tbl td:first-child { white-space: nowrap; }

.consent-ft {
  padding: 14px 24px;
  border-top: 1px solid var(--divider);
  flex-shrink: 0;
  background: var(--strip-bg);
}

.consent-choice {
  font-size: 12px;
  color: var(--fg-3);
  margin: 0 0 11px;
  line-height: 1.5;
}

.consent-btns { display: flex; gap: 10px; justify-content: flex-end; }

.consent-btn {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  border: none;
  border-radius: var(--radius-s);
  padding: 9px 20px;
  cursor: pointer;
  transition: opacity 0.15s, transform 0.1s;
  letter-spacing: 0.01em;
}

.consent-btn:hover { opacity: 0.82; transform: translateY(-1px); }

.consent-btn-leave {
  background: var(--surface-raised);
  color: var(--fg-2);
  border: 1px solid var(--border-strong);
}

.consent-btn-accept {
  background: var(--c-cyan);
  color: oklch(0.12 0.01 252);
}

/* ============================================================
   ADMIN PAGE (admin.html) — all rules scoped under body.admin
   ============================================================ */

body.admin {
  font-family: "Inter", system-ui, sans-serif;
  font-feature-settings: "ss01", "ss02", "cv11";
  margin: 0;
  background: var(--bg-deep);
  color: var(--fg);
}

body.admin #admin-map {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: var(--map-bg, var(--bg-deep));
  pointer-events: none;
}

body.admin .map-blur {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  backdrop-filter: blur(2px) saturate(180%);
  -webkit-backdrop-filter: blur(2px) saturate(180%);
  background:
    linear-gradient(180deg, var(--vignette-top) 0%, transparent 14%, transparent 86%, var(--vignette-bottom) 100%);
}

body.admin .admin-shell {
  position: relative;
  z-index: 2;
  max-width: 1400px;
  margin: 0 auto;
  padding: 20px 16px 40px;
}

body.admin .admin-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

body.admin .admin-title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--fg);
  border-left: 3px solid var(--c-cyan);
  padding-left: 14px;
}

body.admin .admin-title span {
  font-size: 12px;
  font-weight: 400;
  color: var(--fg-3);
  margin-left: 8px;
  font-family: "JetBrains Mono", monospace;
}

body.admin .admin-exit {
  background: var(--surface-raised);
  color: var(--fg-2);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-s);
  padding: 8px 16px;
  font-size: 0.85rem;
  font-family: inherit;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

body.admin .admin-exit:hover {
  background: var(--surface-hover);
  color: var(--fg);
}

body.admin .admin-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

body.admin .card {
  background: var(--surface);
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow);
  padding: 22px;
  margin-bottom: 16px;
}

body.admin .card h3 {
  margin: 0 0 16px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-2);
}

body.admin .card h4 {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  color: var(--fg-3);
  white-space: nowrap;
}

body.admin .card h4 sup {
  color: var(--fg-4);
  font-size: 0.75em;
}

body.admin label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--fg-3);
  margin-bottom: 4px;
  letter-spacing: 0.03em;
}

body.admin input,
body.admin select {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 11px;
  margin: 4px 0;
  font-size: 0.92rem;
  font-family: inherit;
  background: var(--inset-bg);
  color: var(--fg);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-s);
  outline: none;
  transition: border-color 0.15s;
}

body.admin input:focus,
body.admin select:focus {
  border-color: var(--c-cyan);
}

body.admin input[style*="text-transform"] { text-transform: uppercase; }

body.admin button {
  padding: 9px 16px;
  cursor: pointer;
  font-weight: 600;
  font-family: inherit;
  font-size: 0.88rem;
  border-radius: var(--radius-s);
  border: 1px solid var(--border-strong);
  background: var(--surface-raised);
  color: var(--fg);
  transition: background 0.15s, color 0.15s, opacity 0.15s;
}

body.admin button:hover { background: var(--surface-hover); }

body.admin .action-btn {
  background: var(--c-cyan-soft);
  color: var(--c-cyan);
  border-color: var(--c-cyan-border);
}

body.admin .action-btn:hover {
  background: var(--c-cyan-soft);
  opacity: 0.8;
}

body.admin .lab-btn {
  background: var(--c-mint-soft);
  color: var(--c-mint);
  border-color: var(--c-mint-border);
}

body.admin .lab-btn:hover { opacity: 0.8; }

body.admin .danger {
  background: var(--c-red-soft);
  color: var(--c-red);
  border-color: var(--c-red-border);
}

body.admin .danger:hover { opacity: 0.8; }

body.admin .full-width { width: 100%; }
body.admin .mt-10 { margin-top: 10px; }
body.admin .mt-15 { margin-top: 15px; }
body.admin .mb-15 { margin-bottom: 15px; }
/* align-items: center is load-bearing — inputs/selects carry `margin: 4px 0`
   and buttons carry none, so the flex default (stretch) grows a button's box
   by those 8px and it overhangs the control next to it. */
body.admin .gap-row { display: flex; gap: 10px; align-items: center; }
body.admin .input-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 15px; }
body.admin .input-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 10px; }
body.admin .flex-between { display: flex; justify-content: space-between; align-items: center; }
body.admin .flex-end { display: flex; gap: 8px; justify-content: flex-end; }
body.admin .flex-col { display: flex; flex-direction: column; }
body.admin .wrap { flex-wrap: wrap; }

body.admin .plane-box {
  background: var(--strip-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  margin-top: 14px;
}

body.admin .plane-box-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

body.admin .plane-box-title { font-weight: 700; color: var(--fg); }

body.admin .admin-tag {
  font-family: "JetBrains Mono", monospace;
  font-size: 0.75rem;
  padding: 2px 8px;
  border-radius: 999px;
  font-weight: 600;
  background: var(--surface-muted);
  color: var(--fg-3);
  border: 1px solid var(--border);
}

body.admin .admin-tag.airborne {
  background: var(--c-cyan-soft);
  color: var(--c-cyan);
  border-color: var(--c-cyan-border);
}

body.admin .admin-tag.ground {
  background: var(--c-mint-soft);
  color: var(--c-mint);
  border-color: var(--c-mint-border);
}

body.admin .admin-tag.transport {
  background: var(--c-amber-soft);
  color: var(--c-amber);
  border-color: var(--c-amber-border);
}

body.admin .admin-tag.invalid {
  background: var(--c-red-soft);
  color: var(--c-red);
  border-color: var(--c-red-border);
}

/* INVALID, a Pilot status (the rule-violation penalty). Deliberately louder than
   the Flight status tags: an INVALID aircraft earns nothing until it is back on
   the ground at its return field. */
body.admin .invalid-badge {
  background: var(--c-red-soft);
  color: var(--c-red);
  border: 1px solid var(--c-red-border);
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  margin-left: 10px;
  font-family: "JetBrains Mono", monospace;
}

body.admin .cure-badge {
  background: var(--c-cyan-soft);
  color: var(--c-cyan);
  border: 1px solid var(--c-cyan-border);
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  margin-left: 10px;
  font-family: "JetBrains Mono", monospace;
}

body.admin .samples-line {
  font-size: 0.88rem;
  margin-bottom: 8px;
  color: var(--fg-3);
}

body.admin .samples-line .sample-val {
  color: var(--c-red);
  font-weight: 700;
}

body.admin .plane-inputs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 5px;
}

body.admin .plane-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
}

body.admin .inject-btn {
  background: var(--surface-elevated);
  color: var(--fg-2);
  font-size: 0.8rem;
  padding: 6px 12px;
  border-color: var(--border);
}

body.admin .inject-btn:hover { background: var(--surface-hover); color: var(--fg); }

body.admin .plane-btn-group { display: flex; gap: 8px; }

body.admin .plane-btn-group button { font-size: 0.8rem; padding: 6px 12px; }

body.admin .no-planes {
  color: var(--fg-3);
  font-style: italic;
  font-size: 0.9rem;
}

body.admin .audit-log {
  flex: 1;
  overflow-y: auto;
  background: var(--inset-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.80rem;
  color: var(--fg-2);
  white-space: pre-wrap;
  min-height: 200px;
}

body.admin .audit-log em {
  color: var(--fg-4);
  font-family: "Inter", system-ui, sans-serif;
  font-style: italic;
}

body.admin .log-card {
  flex: 1;
  min-height: 300px;
  display: flex;
  flex-direction: column;
}

/* Infection deck peek */
body.admin .deck-counts {
  float: right;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--fg-3);
}

body.admin .deck-peek {
  display: grid;
  /* minmax(0,…) so a long airport name ellipsises instead of widening the column */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  margin-top: 14px;
}

body.admin .deck-list {
  max-height: 320px;
  overflow-y: auto;
  background: var(--inset-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 6px 8px;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  color: var(--fg-2);
}

body.admin .deck-list em {
  color: var(--fg-4);
  font-family: "Inter", system-ui, sans-serif;
  font-style: italic;
}

body.admin .deck-card {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 2px;
  border-bottom: 1px solid var(--divider);
}

body.admin .deck-card:last-child { border-bottom: none; }

body.admin .deck-idx {
  flex: 0 0 2.2em;
  text-align: right;
  color: var(--fg-4);
}

body.admin .deck-icao {
  flex-shrink: 0;
  font-weight: 600;
  color: var(--fg);
}

body.admin .deck-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: "Inter", system-ui, sans-serif;
  color: var(--fg-3);
}

body.admin .deck-tag { flex-shrink: 0; font-size: 0.7rem; }

body.admin .deck-lvl {
  flex-shrink: 0;
  padding: 1px 6px;
  border-radius: var(--radius-s);
  font-size: 0.68rem;
  background: var(--chip-bg);
  color: var(--fg-3);
}

body.admin .deck-lvl.lvl-1 { background: var(--c-amber-soft); color: var(--c-amber); }
body.admin .deck-lvl.lvl-2 { background: var(--c-red-soft);   color: var(--c-amber); }
body.admin .deck-lvl.lvl-3 { background: var(--c-red-soft);   color: var(--c-red); }
body.admin .deck-lvl.gone  { background: var(--chip-bg);      color: var(--fg-4); }

body.admin .deck-card.outbreak .deck-icao { color: var(--c-red); }
body.admin .deck-card.immune .deck-icao   { color: var(--c-mint); }

/* Auth overlay */
body.admin .auth-overlay {
  position: fixed;
  inset: 0;
  background: var(--modal-overlay);
  backdrop-filter: blur(8px) saturate(0.7);
  -webkit-backdrop-filter: blur(12px) saturate(0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

body.admin .auth-modal {
  background: var(--surface-solid);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow);
  padding: 40px;
  min-width: 320px;
  width: 100%;
  max-width: 380px;
  text-align: center;
}

body.admin .auth-modal h2 {
  margin: 0 0 6px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--fg);
}

body.admin .auth-modal p {
  color: var(--fg-3);
  margin: 0 0 22px;
  font-size: 0.88rem;
}

body.admin .auth-error {
  color: var(--c-red);
  font-size: 0.85rem;
  margin-bottom: 12px;
  display: none;
}

body.admin .auth-submit {
  width: 100%;
  margin-top: 4px;
}

/* MAP MARKERS (scoped to admin) */
body.admin .ap-marker { position: relative; display: grid; place-items: center; }
body.admin .ap-core {
  border-radius: 50%;
  border: 2px solid white;
  box-shadow: 0 0 0 1px var(--popup-shadow);
}
body.admin .ap-ring {
  position: absolute; border-radius: 50%;
  border: 1.5px solid currentColor;
  opacity: 0.7;
  animation: ringpulse 5s infinite;
}
@keyframes ringpulse {
  0%   { transform: scale(0.6); opacity: 0.85; }
  70%  { transform: scale(2.2); opacity: 0; }
  100% { transform: scale(2.2); opacity: 0; }
}
body.admin .ap-lab {
  position: absolute; top: -4px; right: -4px;
  width: 12px; height: 12px; border-radius: 3px;
  background: var(--c-cyan); border: 1.5px solid var(--deep-ink);
  display: grid; place-items: center;
  font-size: 8px; color: var(--deep-ink); font-weight: 700;
  font-family: "JetBrains Mono", monospace;
}
body.admin .ap-label {
  position: absolute; top: 18px; left: 50%; transform: translateX(-50%);
  font-family: "JetBrains Mono", monospace; font-size: 10px; font-weight: 600;
  color: var(--fg); white-space: nowrap;
  background: var(--label-bg);
  padding: 2px 6px; border-radius: 4px;
  border: 1px solid var(--border);
  pointer-events: none;
}

/* PILOT MARKERS (scoped to admin) */
body.admin .pilot-marker-icon { background: transparent; border: none; }
body.admin .pilot {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  pointer-events: none;
}
body.admin .pilot-icon { width: 20px; height: 20px; position: relative; flex-shrink: 0; }
body.admin .pilot-square {
  width: 10px; height: 10px;
  background: var(--inset-bg);
  border: 2px solid var(--c-cyan);
  box-sizing: border-box;
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
}
body.admin .pilot-heading {
  width: 14px; height: 2px;
  position: absolute; left: 50%; top: 50%;
  transform-origin: left center;
}
body.admin .pilot-body {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  font-family: "JetBrains Mono", monospace; line-height: 1.1;
}
body.admin .pilot-cs {
  font-size: 11px; font-weight: 700;
  letter-spacing: 0.02em; display: flex; align-items: baseline; gap: 5px;
}
body.admin .pilot-type { font-size: 9px; font-weight: 400; color: var(--fg-2); letter-spacing: 0.04em; }
body.admin .pilot-sub  { font-size: 9px; color: var(--fg-2); margin-top: 1px; letter-spacing: 0.02em; }

/* LOG FILTER DROPDOWN (scoped to admin) */
body.admin .log-type-btn {
  width: 100%; text-align: left;
  background: var(--inset-bg); color: var(--fg);
  border: 1px solid var(--border-strong); border-radius: var(--radius-s);
  font-family: inherit; font-size: 0.85rem;
  padding: 6px 8px; margin: 4px 0;
  display: flex; justify-content: space-between; align-items: center;
  cursor: pointer;
}
body.admin .log-type-btn:hover { border-color: var(--c-cyan); }
body.admin .log-type-menu {
  display: none; position: absolute;
  top: calc(100% + 2px); left: 0; min-width: 100%;
  background: var(--surface-solid); border: 1px solid var(--border-strong);
  border-radius: var(--radius-s);
  padding: 4px 0; z-index: 200;
  box-shadow: var(--shadow);
}
body.admin .log-type-menu label {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 10px; font-size: 0.85rem;
  cursor: pointer; white-space: nowrap;
  color: var(--fg-2); font-weight: 400;
}
body.admin .log-type-menu label:hover { background: var(--row-hover); color: var(--fg); }
body.admin .log-type-menu input[type="checkbox"] { width: auto; margin: 0; accent-color: var(--c-cyan); }
body.admin .log-pending-pill {
  display: none; font-size: 0.75rem;
  background: var(--c-amber-soft); color: var(--c-yellow);
  border: 1px solid var(--c-amber-border);
  padding: 2px 6px; border-radius: 4px; font-weight: 700;
}

/* ============================================================
   TRANSPARENCY & BLUR KNOBS — tune these to adjust admin overlay
   ============================================================

   CARD FROSTED GLASS:
     .card { backdrop-filter: blur(20px) saturate(140%) }   ← card blur intensity
     --surface            0.78 alpha  ← card background opacity (dark mode)
     --surface-raised     0.85 alpha  ← raised/elevated surfaces

   MAP BLUR LAYER (.map-blur):
     backdrop-filter: blur(4px) saturate(120%)              ← global map defocus
     vignette uses --vignette-top / --vignette-bottom

   AUTH OVERLAY (.auth-overlay):
     backdrop-filter: blur(8px) saturate(0.7)               ← login screen blur
     --modal-overlay      0.60 alpha  ← auth backdrop darkness

   PLANE-BOX / STRIP BACKGROUNDS:
     --strip-bg           0.55 alpha  ← plane-box fill

   CONNECTION LINES (renderAdminMapMarkers):
     opacity: 0.35  ← route line opacity (hard-coded in JS)

   PILOT FLIGHT-PATH LINES:
     opacity: 0.55  ← dashed destination line (hard-coded in JS)

   ============================================================ */
