/* =============================================================================
   orbita — Tactical Earth Observation | Operator Console
   Defense-grade C2 UI. Vanilla CSS, no build step. All assets vendored locally
   (fonts + Leaflet). The ONLY runtime external dependency is the documented
   basemap tile service (see app.js SAT_URL / TILE_URL).

   DESIGN LANGUAGE (WS-UI-2 "INSTRUMENT")
   - Engineered tactical instrument: matte, dense, structural. The MAP stays the
     full-bleed hero; everything around it is a precision instrument cluster —
     opaque carbon panels, hairline structure, sharp radii. Glass blur survives
     ONLY on true map-overlay HUD elements (coords strip, legend, temporal bar),
     and lighter than before.
   - Restrained palette: matte graphite-carbon neutrals, ONE disciplined brand
     accent (orbita teal — interactive / selected / own-asset / brand, never
     decoration), and crisp semantic severity colors used sparingly:
         teal       = system / interactive / brand / own-asset (friendly)
         red→blue   = threat severity (CRITICAL / HIGH / MEDIUM / LOW)
     Red is reserved for CRITICAL and the commit-to-action (armed) state only.
   - Type system: IBM Plex Sans (UI body) + IBM Plex Sans Condensed 600 (placard
     labels — uppercase, tracked) + IBM Plex Mono (all machine data — coords,
     IDs, UIDs, timestamps, CoT). Legible at a glance for a 3am operator.
   - Signature device: HUD target corner brackets (two L-ticks) on the dock,
     the active module, the login card and CRITICAL alert cards.
   - Subtle, purposeful motion. Honors prefers-reduced-motion.
   ========================================================================== */

/* ---- Vendored fonts (no network at runtime) ----------------------------- */
@font-face {
  font-family: "Plex Sans";
  src: url("vendor/fonts/plex-sans-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Plex Sans";
  src: url("vendor/fonts/plex-sans-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("vendor/fonts/plex-mono-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Plex Mono";
  src: url("vendor/fonts/plex-mono-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
/* Placard/label face (WS-UI-2): IBM Plex Sans Condensed SemiBold, latin. */
@font-face {
  font-family: "Plex Cond";
  src: url("vendor/fonts/plex-sans-cond-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}

/* ---- Design tokens ------------------------------------------------------ */
:root {
  /* surfaces — matte graphite carbon, near-neutral with a faint cool cast */
  --bg-0: #060709;
  --bg-1: #0a0c10;
  --surface-1: #0d1014;
  --surface-2: #12161c;
  --surface-3: #1a2028;

  /* hairline structure — translucent so it reads on matte + solid alike */
  --line: rgba(158, 180, 200, 0.14);
  --line-2: rgba(158, 180, 200, 0.28);

  /* "glass" tokens are matte now: nearly opaque, subtle blur only (true
     map-overlay HUD elements keep a light blur; panels are opaque carbon). */
  --glass: rgba(10, 12, 16, 0.90);
  --glass-strong: rgba(9, 11, 14, 0.97);
  --glass-edge: rgba(170, 195, 220, 0.16);
  --glass-blur: saturate(120%) blur(10px);
  --glass-blur-lite: saturate(115%) blur(6px);

  /* ink */
  --text: #eef3f8;
  --muted: #93a6b8;
  --faint: #5d7185;

  /* single tactical/brand accent */
  --accent: #34e0cf;
  --accent-2: #19b9ac;
  --accent-ink: #022b27;
  --accent-dim: rgba(52, 224, 207, 0.13);
  --accent-line: rgba(52, 224, 207, 0.42);
  --accent-glow: rgba(52, 224, 207, 0.55);

  /* severity scale (threat only) */
  --crit: #ff414d;
  --high: #ff9142;
  --med: #ffc943;
  --low: #5aa8ff;
  --crit-ink: #2a0306;
  --high-ink: #2a1402;
  --med-ink: #2a2102;
  --low-ink: #021526;

  --ok: #34d8a0;
  --bad: #ff5d6c;

  /* geometry — sharp instrument edges */
  --r-sm: 3px;
  --r-md: 4px;
  --r-lg: 6px;
  --rail-w: 392px;
  --ab-w: 60px;       /* activity-bar (icon rail) width — GAP-UI-03 */
  --bar-h: 54px;
  --gap: 14px;

  --shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  --shadow-soft: 0 8px 24px rgba(0, 0, 0, 0.4);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  --mono: "Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --sans: "Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* placard/label face (WS-UI-2) */
  --cond: "Plex Cond", "Plex Sans", var(--sans);
  /* hairline rule gradient + HUD bracket signature color */
  --hair: linear-gradient(90deg, transparent, var(--line-2), transparent);
  --bracket-line: rgba(52, 224, 207, 0.6);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg-0);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* The [hidden] attribute must always win over component display rules
   (e.g. .modal{display:flex}) — otherwise hidden modals still render. */
[hidden] { display: none !important; }

/* Mono utility for machine data: coordinates, IDs, UIDs, timestamps. */
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* Reusable uppercase micro-label (C2 system convention). */
.micro {
  font-family: var(--mono); font-size: 9.5px;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--faint);
}

/* ---- Focus: visible, consistent, keyboard-only -------------------------- */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---- Brand wordmark ----------------------------------------------------- */
.wordmark {
  font-weight: 600;
  letter-spacing: -0.015em;
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  color: var(--text);
}
.wordmark .mark-o { color: var(--accent); }
.wordmark .tick {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  display: inline-block;
  margin-left: 4px;
  box-shadow: 0 0 10px var(--accent-glow);
  animation: tickPulse 3.2s var(--ease) infinite;
}
@keyframes tickPulse {
  0%, 100% { box-shadow: 0 0 8px var(--accent-line); opacity: 0.9; }
  50% { box-shadow: 0 0 14px var(--accent-glow); opacity: 1; }
}

/* =============================================================================
   LOGIN GATE
   ========================================================================== */
.login-screen {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; overflow: hidden;
  /* faint graticule grid + center crosshair (pure CSS gradients) */
  background:
    linear-gradient(90deg, transparent calc(50% - 1px), rgba(52,224,207,0.05) calc(50% - 1px), rgba(52,224,207,0.05) 50%, transparent 50%),
    linear-gradient(0deg, transparent calc(50% - 1px), rgba(52,224,207,0.05) calc(50% - 1px), rgba(52,224,207,0.05) 50%, transparent 50%),
    radial-gradient(1100px 640px at 50% -12%, #0b1418 0%, transparent 62%),
    repeating-linear-gradient(0deg, transparent 0 39px, rgba(52,224,207,0.02) 39px 40px),
    repeating-linear-gradient(90deg, transparent 0 39px, rgba(52,224,207,0.02) 39px 40px),
    var(--bg-0);
}
/* slow sweeping radar aura behind the card — thin wedge, deliberate pace */
.login-aura {
  position: absolute; width: 980px; height: 980px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 90%, rgba(52,224,207,0.09) 97%, transparent 100%);
  filter: blur(4px);
  animation: sweep 22s linear infinite;
  pointer-events: none; opacity: 0.7;
}
@keyframes sweep { to { transform: rotate(360deg); } }
.login-card {
  position: relative;
  width: 372px; max-width: 100%;
  /* matte carbon + a subtle accent top hairline (background strip — both
     pseudo-elements are spent on the corner brackets; no glow) */
  background-color: var(--surface-1);
  background-image: linear-gradient(90deg, transparent, var(--accent-line), transparent);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: top center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  padding: 32px 30px 28px;
  box-shadow: var(--shadow);
}
/* HUD target brackets (signature): two L-shaped corner ticks, accent —
   strong enough to register at 1x (11px arms, 1.5px, high alpha). */
.login-card::before {
  content: ""; position: absolute; top: -1.5px; left: -1.5px;
  width: 11px; height: 11px; pointer-events: none;
  border-top: 1.5px solid rgba(52, 224, 207, 0.8);
  border-left: 1.5px solid rgba(52, 224, 207, 0.8);
}
.login-card::after {
  content: ""; position: absolute; bottom: -1.5px; right: -1.5px;
  width: 11px; height: 11px; pointer-events: none;
  border-bottom: 1.5px solid rgba(52, 224, 207, 0.8);
  border-right: 1.5px solid rgba(52, 224, 207, 0.8);
}
.login-card .wordmark { font-size: 32px; }
.login-eyebrow {
  font-family: var(--cond); font-weight: 600;
  font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent); margin: 18px 0 2px;
}
.login-sub { color: var(--muted); margin: 0 0 22px; font-size: 13px; }
.login-card label {
  display: block; margin: 14px 0 6px;
  color: var(--muted);
  font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
}
.login-card input {
  width: 100%; padding: 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--bg-1); color: var(--text);
  font-family: var(--mono); font-size: 14px;
  transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.login-card input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
#login-btn {
  width: 100%; margin-top: 24px; padding: 13px;
  background: var(--accent);
  color: var(--accent-ink);
  border: 0; border-radius: 3px;
  font-family: var(--cond); font-weight: 600; font-size: 13px;
  letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer;
  transition: filter 0.12s var(--ease), transform 0.05s var(--ease);
}
#login-btn:hover { filter: brightness(1.08); }
#login-btn:active { transform: translateY(1px); }
#login-btn:disabled { opacity: 0.55; cursor: progress; }
/* PAL-L-27: enterprise SSO button — shown when GET /api/v1/auth/config reports OIDC on. */
.login-sso-btn {
  width: 100%; margin-top: 4px; padding: 13px;
  background: rgba(52,224,207,0.08);
  color: var(--accent);
  border: 1px solid rgba(52,224,207,0.45);
  border-radius: 3px;
  font-family: var(--cond); font-weight: 600; font-size: 13px;
  letter-spacing: 0.14em; text-transform: uppercase; cursor: pointer;
  transition: filter 0.12s var(--ease), border-color 0.12s var(--ease), background 0.12s var(--ease);
}
.login-sso-btn:hover {
  filter: brightness(1.08);
  border-color: var(--accent);
  background: rgba(52,224,207,0.14);
}
.login-sso-btn:active { transform: translateY(1px); }
.login-sso-btn:disabled { opacity: 0.55; cursor: progress; }
.login-divider {
  margin: 18px 0 6px;
  color: var(--faint);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  position: relative;
}
.login-divider::before,
.login-divider::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 28%;
  height: 1px;
  background: var(--line);
}
.login-divider::before { left: 0; }
.login-divider::after { right: 0; }
.login-error {
  color: var(--bad); margin: 14px 0 0; font-size: 13px;
  border-left: 2px solid var(--bad); padding-left: 10px;
}
.login-foot {
  margin: 24px 0 0; padding-top: 16px;
  border-top: 1px solid var(--line);
  color: var(--faint); font-family: var(--mono);
  font-size: 10.5px; letter-spacing: 0.06em;
  display: flex; justify-content: space-between;
}

/* =============================================================================
   APP SHELL — full-bleed map + floating glass surfaces
   ========================================================================== */
.app { position: relative; height: 100%; overflow: hidden; }

/* ---- Map stage (the hero base layer) ----------------------------------- */
.stage { position: absolute; inset: 0; z-index: 0; background: var(--bg-1); }
.map { position: absolute; inset: 0; background: var(--bg-1); }

/* ---- MapLibre GL 3D globe (PAL-L-15) — toggle-guarded sibling of #map ------- */
.globe {
  position: absolute; inset: 0; z-index: 2;
  display: none; background: var(--bg-1);
}
.app.globe-active .globe { display: block; }
.app.globe-active .map { visibility: hidden; pointer-events: none; }
.app.globe-active .stage-veil { display: none; }

/* ---- PAL-L-36: linked 2D↔3D split layout — both surfaces visible side by side ---- */
.app.globe-split .map {
  left: 0; right: 50%;
  visibility: visible; pointer-events: auto;
}
.app.globe-split .globe {
  left: 50%; right: 0;
  display: block;
}
.app.globe-split .stage-veil { display: none; }
.app.globe-split .globe::before {
  content: "";
  position: absolute; top: 0; bottom: 0; left: 0; width: 1px;
  background: linear-gradient(180deg, transparent, var(--accent-line), transparent);
  z-index: 3; pointer-events: none;
}
.app.globe-split .globe { z-index: 2; }
.app.globe-split .nav-shell { z-index: 700; }
.app.globe-split .statusbar { z-index: 710; }
.app.globe-split .temporal-bar {
  left: calc(var(--nav-w) + var(--gap));
  right: calc(50% + var(--gap));
}
.app.globe-split.nav-collapsed .temporal-bar {
  left: var(--gap);
  right: calc(50% + var(--gap));
}
/* MapLibre GL fills its container; keep its canvas full-bleed and the attribution subtle. */
.globe .maplibregl-map,
.globe .maplibregl-canvas {
  width: 100% !important; height: 100% !important;
}
.globe .maplibregl-ctrl-attrib { opacity: 0.55; font-size: 9px; }
.globe .maplibregl-ctrl-bottom-left,
.globe .maplibregl-ctrl-logo { display: none; }

/* Track/entity globe markers (PAL-L-15): DOM markers (no symbol/glyph layers → no
   external glyph fetch). Dot + monospace label, selection + peer-view emphasis. */
.globe-marker { display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.globe-marker-dot {
  width: 11px; height: 11px; border-radius: 50%;
  border: 1px solid rgba(2, 43, 39, 0.9);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.globe-marker-dot.selected {
  width: 14px; height: 14px;
  border-color: var(--linked-selection);
  box-shadow: 0 0 0 2px var(--linked-selection-glow);
}
.globe-marker-dot.peer {
  border-color: #e0aaff;
  box-shadow: 0 0 0 2px rgba(224, 170, 255, 0.7);
}
.globe-marker-label {
  margin-top: 2px;
  font-family: var(--mono); font-weight: 500; font-size: 11px;
  color: #eef3f8; white-space: nowrap;
  text-shadow: 0 1px 2px #000, 0 0 2px #000;
  pointer-events: none;
}
.globe-marker-label.selected { color: #fff; }
.globe-marker-label.peer { color: #e0aaff; }

/* ---- WS-GLOBE-3 globe COP markers + cue lines -----------------------------
   Alerts, drones, cameras (cluster cap), hazards on the MapLibre globe. Severity
   colours mirror the 2D alert-marker tokens; cue arcs are MapLibre line layers. */
.globe-cop-marker { display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.globe-cop-dot {
  width: 12px; height: 12px; border-radius: 50%;
  border: 1px solid rgba(2, 43, 39, 0.9);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}
.globe-cop-dot.crit { animation: pulsering 1.8s var(--ease) infinite; }
.globe-alert-marker.dv .globe-cop-dot { border-radius: 2px; transform: rotate(45deg); }
.globe-alert-marker.m-CRITICAL .globe-cop-dot { box-shadow: 0 0 8px var(--crit); }
.globe-drone-marker .globe-drone-chassis {
  font-size: 14px; color: #34e0cf; text-shadow: 0 0 6px rgba(52, 224, 207, 0.6);
  line-height: 1;
}
.globe-drone-marker.live .globe-drone-chassis { color: #7ef0e2; }
.globe-camera-marker .globe-cop-dot.cam { background: #ffb454; width: 9px; height: 9px; }
.globe-camera-marker.stale .globe-cop-dot.cam { opacity: 0.45; }
.globe-camera-cluster {
  min-width: 22px; height: 22px; border-radius: 11px;
  background: rgba(255, 180, 84, 0.22); border: 1px solid #ffb454;
  align-items: center; justify-content: center;
}
.globe-cop-cluster-count {
  font-family: var(--mono); font-size: 10px; font-weight: 600; color: #ffb454;
}
.globe-hazard-marker .globe-cop-dot.hazard { background: #ff9142; width: 10px; height: 10px; }
.globe-popup { font-size: 12px; max-width: 260px; }
.globe-selection-popup .globe-selection-actions {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px;
}
.globe-selection-popup .popup-btn.ghost { opacity: 0.82; }
/* WS-GLOBE-4/8: camera FOV frustum, globe measure line, terrain hint, viewshed legend. */
.globe-terrain-hint { font-size: 11px; color: var(--muted); margin-top: 4px; }
.globe-viewshed-ctl { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); }
.globe-viewshed-ctl .btn { margin-top: 6px; width: 100%; }
.globe-viewshed-legend {
  display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; font-size: 11px; color: var(--muted);
}
.globe-viewshed-legend-visible::before,
.globe-viewshed-legend-occluded::before {
  content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 5px;
  border-radius: 2px; vertical-align: -1px;
}
.globe-viewshed-legend-visible::before { background: rgba(52, 224, 207, 0.55); }
.globe-viewshed-legend-occluded::before { background: rgba(26, 36, 51, 0.65); }

/* ---- WS-GLOBE-2 satellite layer -----------------------------------------
   Globe DOM markers for propagated satellites + the subsolar sun marker, plus
   the roster / next-pass panel. Category colors (sar amber / optical cyan /
   station white / other grey) are applied inline from app.js; red is never used
   for satellites (rationed to CRITICAL). Instrument system: matte carbon, Plex
   Cond placard labels, Plex Mono machine data. */
.sat-marker { display: flex; flex-direction: column; align-items: center; cursor: pointer; }
.sat-marker-dot {
  width: 8px; height: 8px; border-radius: 50%;
  border: 1px solid rgba(2, 8, 12, 0.9);
}
.sat-marker-label {
  margin-top: 2px;
  font-family: var(--mono); font-weight: 500; font-size: 10px;
  color: #eef3f8; white-space: nowrap;
  text-shadow: 0 1px 2px #000, 0 0 2px #000;
  pointer-events: none;
}
.sat-sun-marker {
  width: 14px; height: 14px; border-radius: 50%;
  background: radial-gradient(circle, #fff7d6 0%, #ffd76b 55%, rgba(255,201,67,0) 75%);
  box-shadow: 0 0 12px rgba(255, 215, 107, 0.85);
  pointer-events: none;
}

/* SDA-4 / WS-GLOBE-9: sovereign celestial backdrop canvas.
   The canvas holds the WHOLE sky — stars, constellation lines, and the
   Sun/Moon/planet bodies (all painted with the 2D context, no DOM markers) —
   clipped to the space OUTSIDE the earth disc. It must be TRANSPARENT: the old
   dark radial-gradient darkened/covered the globe (it sits at z-index:1, in front
   of the globe at z-index:0). MapLibre renders its own space/globe cleanly behind. */
.celestial-starfield {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 1;
  background: transparent;
}
.app.globe-active .celestial-starfield,
.app.globe-split .celestial-starfield { display: block; }
.app:not(.globe-active):not(.globe-split) .celestial-starfield { display: none; }
.space-shell-label {
  display: block; font-size: 11px; color: var(--muted); margin: 0 0 4px 0;
}
.space-shell-select {
  width: 100%; max-width: 280px;
  font-family: var(--mono); font-size: 12px;
  padding: 6px 8px; border-radius: 3px;
  border: 1px solid var(--line-2); background: rgba(0,0,0,0.25);
  color: var(--text);
}
.panel-body-space .space-shell-select { margin-bottom: 6px; }

/* Roster + next-pass rows (Plex Cond labels, Plex Mono data). */
.panel-body-satellites .sat-attribution {
  padding: 8px 13px 12px 16px; color: var(--faint);
}
.sat-row, .sat-pass-row {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 11px; cursor: pointer;
}
.sat-pass-row { cursor: default; }
.sat-swatch {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.35);
}
.sat-row .grow, .sat-pass-row .grow { min-width: 0; }
.sat-name, .sat-pass-title {
  font-family: var(--cond); font-weight: 600; font-size: 13px;
  letter-spacing: 0.01em; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sat-meta, .sat-pass-meta {
  font-size: 11px; color: var(--muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sat-cat-badge {
  flex: 0 0 auto;
  font-family: var(--cond); font-weight: 600; font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 2px;
  border: 1px solid var(--line-2); background: rgba(0,0,0,0.18);
}
.sat-eta {
  flex: 0 0 auto;
  font-size: 12px; font-weight: 500; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* ---- SDA-2 Space module ---------------------------------------------------
   Conjunction / reentry / new-object lists + scope note. Category colors on
   the globe circle layer are set in app.js (payload cyan, rocket-body amber,
   debris muted grey — NO CRITICAL red). Instrument system matches satellites. */
.panel-body-space .space-attribution {
  padding: 8px 13px 12px 16px; color: var(--faint);
}
.space-scope-note { font-size: 11px; color: var(--muted); margin: 0 0 10px 0; line-height: 1.45; }
.space-row, .space-conj-row, .space-reentry-row, .space-new-row {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 11px; cursor: pointer;
}
.space-conj-row .grow, .space-reentry-row .grow, .space-new-row .grow { min-width: 0; }
.space-name, .space-conj-title {
  font-family: var(--cond); font-weight: 600; font-size: 13px;
  letter-spacing: 0.01em; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.space-meta, .space-conj-meta {
  font-size: 11px; color: var(--muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.space-cat-badge {
  flex: 0 0 auto;
  font-family: var(--cond); font-weight: 600; font-size: 9.5px;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 2px;
  border: 1px solid var(--line-2); background: rgba(0,0,0,0.18);
}
.space-miss, .space-perigee {
  flex: 0 0 auto;
  font-size: 12px; font-weight: 500; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.space-swatch {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.35);
}
.sat-eta.none { color: var(--faint); }
.sat-pass-row.none .sat-pass-title { color: var(--muted); }

/* ---- WS-GLOBE-6 satellite detail readout --------------------------------
   A floating instrument panel opened by clicking a satellite marker/roster row.
   Same top-level .app-child overlay pattern as #drone-flight-hud / #mind-query-panel
   (z-720, right-anchored below the command bar). Instrument system: matte carbon,
   Plex Cond placard labels, Plex Mono machine data. No red (rationed to CRITICAL). */
.sat-detail {
  position: absolute; top: calc(var(--bar-h) + var(--gap)); right: var(--gap); left: auto;
  z-index: 720; width: min(300px, calc(100vw - 24px));
  max-height: min(70vh, 560px); overflow: auto;
  padding: 10px 12px 12px;
  background: var(--glass-strong);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: 0 10px 28px rgba(0,0,0,0.38);
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
}
.sat-detail[hidden] { display: none !important; }
.sat-detail-head {
  display: flex; align-items: center; gap: 7px;
  padding-bottom: 8px; margin-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.sat-detail-eyebrow {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--accent);
  border: 1px solid var(--accent-line); border-radius: 2px; padding: 2px 5px;
}
.sat-detail-badge { margin-left: 0; }
.sat-detail-close { margin-left: auto; }
.sat-detail-name {
  font-family: var(--cond); font-weight: 600; font-size: 15px;
  letter-spacing: 0.01em; color: var(--text);
  margin-bottom: 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sat-detail-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 7px 12px;
}
.sat-detail-cell { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sat-detail-cell-wide { grid-column: 1 / -1; }
.sat-detail-k {
  font-family: var(--cond); font-weight: 600;
  font-size: 8.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
}
.sat-detail-v {
  font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sat-detail-passes-h {
  font-family: var(--cond); font-weight: 600;
  font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
  margin: 11px 0 5px; padding-top: 9px; border-top: 1px solid var(--line);
}
.sat-detail-passes { list-style: none; margin: 0; padding: 0; }
.sat-detail-pass {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  padding: 5px 0; font-size: 12px;
  border-bottom: 1px solid var(--line);
}
.sat-detail-pass:last-child { border-bottom: 0; }
.sat-detail-pass-sector {
  color: var(--text); min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sat-detail-pass-eta {
  flex: 0 0 auto; color: var(--accent); font-variant-numeric: tabular-nums;
}
.sat-detail-pass.none { color: var(--faint); justify-content: flex-start; }
.sat-detail-actions {
  display: flex; flex-wrap: wrap; gap: 8px; margin-top: 11px;
}

/* ---- PAL-L-15 BUG-2 fix — 3D globe (globe-active) chrome layering -----------
   In globe mode the MapLibre canvas is the full-bleed base layer. Every command
   surface (nav rail, dock, top command bar, time-scrub/LIVE bar, map-symbols
   legend, MGRS/cursor readout) must sit cleanly ABOVE it and clear of one another.
   All rules are scoped to `.app.globe-active` so the 2D layout is byte-for-byte
   unchanged. The high z-index on the chrome also guards against any position:fixed
   MapLibre control escaping the .stage stacking context. */
.app.globe-active .globe { z-index: 0; }                 /* globe = base layer */
.app.globe-active .nav-shell { z-index: 700; }           /* rail + dock on top */
.app.globe-active .statusbar { z-index: 710; }           /* command bar on top */

/* The tactical tools + LAYER MANAGER (#tac) is a Leaflet control inside .map, which is
   visibility:hidden in full 3D. But its Layers flyout drives the GLOBE layers (satellites,
   SDA catalog, celestial, terrain, COP overlays, MIL-SYM…), so it must stay reachable in 3D.
   Lift .map's stacking context above the globe (it stays invisible + pointer-events:none, so
   the globe remains fully click/drag-through) and re-show + re-enable ONLY #tac over it. The
   nav rail (700, outside .stage) stays above everything. */
.app.globe-active .map { z-index: 650; }
.app.globe-active #tac { visibility: visible; pointer-events: auto; }
/* Full 3D: the 2D-only draw tools (measure / range-rings / AOI / MGRS grid) operate on the Leaflet
   map, not the globe — hide them so the 3D tools strip shows only the LAYERS manager (which drives
   the globe layers). The layers flyout + LYRS button stay. */
.app.globe-active #tac-btn-measure,
.app.globe-active #tac-btn-rings,
.app.globe-active #tac-btn-aoi,
.app.globe-active #tac-btn-mgrs { display: none; }

/* Time-scrub / LIVE bar abutted the dock's right edge (it used --gap*2 where the
   cursor readout uses --gap*3), so its LIVE button overlapped the dock. Add the
   missing --gap of clearance so it clears the dock in globe mode. */
.app.globe-active .temporal-bar {
  left: calc(var(--ab-w) + var(--rail-w) + var(--gap) * 3);
}
.app.globe-active.nav-collapsed .temporal-bar {
  left: calc(var(--ab-w) + var(--gap) * 3);
}

/* 2D/3D mode toggle in the command bar */
.sb-globe {
  display: flex; align-items: center; gap: 2px;
  padding: 2px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2);
  background: rgba(8, 12, 18, 0.45);
}
.globe-mode-btn {
  font-family: var(--mono);
  font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 5px 10px; border: 0; border-radius: 5px;
  background: transparent; color: var(--muted); cursor: pointer;
}
.globe-mode-btn:hover { color: var(--text); background: rgba(255,255,255,0.04); }
.globe-mode-btn.active {
  color: var(--accent-ink); background: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-line);
}
.globe-mode-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* PAL-L-39: one-click globe investor demo control */
.globe-demo-btn {
  font-family: var(--mono);
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 6px 12px; border-radius: 5px;
  border: 1px solid var(--accent-line);
  background: rgba(52, 224, 207, 0.08);
  color: var(--accent); cursor: pointer;
  white-space: nowrap;
}
.globe-demo-btn:hover { background: rgba(52, 224, 207, 0.16); color: var(--text); }
.globe-demo-btn.active {
  color: var(--accent-ink); background: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-line);
}
.globe-demo-btn:disabled { opacity: 0.45; cursor: wait; }

/* PAL-L-17: MIND NL query bar in the command bar (read-only Q&A). */
.sb-mind {
  display: flex; align-items: center; gap: 6px;
  flex: 1 1 180px; min-width: 0; max-width: 360px;
  padding: 2px 6px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2);
  background: rgba(8, 12, 18, 0.45);
}
.mind-query-input {
  flex: 1 1 auto; min-width: 0;
  border: none; background: transparent;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--text); padding: 4px 2px;
}
.mind-query-input::placeholder { color: var(--faint); }
.mind-query-input:focus { outline: none; }
.mind-query-submit {
  flex: 0 0 auto; font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; white-space: nowrap;
}

/* LOC-SEARCH: client-side "go to coordinate / MGRS" — top-center map overlay, glass HUD.
   Top-level .app child so it stacks above the nav-shell (700) + status bar (710) in every
   mode and never hides behind the nav rail; centred so it's clear of the left rail/dock. */
.loc-search {
  position: absolute;
  top: calc(var(--bar-h) + var(--gap));
  /* Centre over the MAP region (clear of the left rail + dock), mirroring the
     .map-hud-row / .temporal-bar anchoring: left = map-left, right = map-right,
     fixed width + auto inline margins -> centred between them. */
  left: calc(var(--ab-w) + var(--rail-w) + var(--gap) * 2);
  right: var(--gap);
  margin-inline: auto;
  z-index: 720;
  display: flex; align-items: center; gap: 6px;
  width: min(360px, calc(100vw - 32px));
  padding: 5px 8px;
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-sm);
  background: var(--glass-strong);
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
  box-shadow: var(--shadow-soft);
  font-family: var(--mono);
}
.app.nav-collapsed .loc-search {
  left: calc(var(--ab-w) + var(--gap) * 2);
}
.loc-search[hidden] { display: none !important; }
.loc-search-icon {
  flex: 0 0 auto; color: var(--accent);
  font-size: 13px; line-height: 1; opacity: 0.9;
}
.loc-search-input {
  flex: 1 1 auto; min-width: 0;
  border: none; background: transparent;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--text); padding: 4px 2px;
}
.loc-search-input::placeholder { color: var(--faint); }
.loc-search-input:focus { outline: none; }
.loc-search-go {
  flex: 0 0 auto; font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; white-space: nowrap;
}
/* Inline invalid-input hint — breaks onto its own row under the field. */
.loc-search-hint {
  flex: 1 1 100%; order: 3;
  margin: 2px 2px 0;
  font-family: var(--cond); font-weight: 600;
  font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--crit);
}
.loc-search-hint[hidden] { display: none !important; }
/* Offline place-name results dropdown (GeoNames gazetteer). Anchored under the
   search field; inherits the overlay's z-720 stacking so it floats above the nav. */
.loc-search-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  max-height: 320px;
  overflow-y: auto;
  display: flex; flex-direction: column;
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-sm);
  background: var(--glass-strong);
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
  box-shadow: var(--shadow-soft);
}
.loc-search-results[hidden] { display: none !important; }
.loc-result {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  width: 100%;
  padding: 6px 9px;
  border: none; border-bottom: 1px solid var(--glass-edge);
  background: transparent; text-align: left; cursor: pointer;
  font-family: var(--mono);
}
.loc-result:last-of-type { border-bottom: none; }
.loc-result:hover, .loc-result:focus {
  background: var(--glass-edge); outline: none;
}
.loc-result-name {
  color: var(--text); font-size: 11px; letter-spacing: 0.03em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.loc-result-meta {
  flex: 0 0 auto;
  color: var(--muted); font-size: 9px; letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* Source-mandated credit line (GeoNames CC-BY 4.0 ToS). */
.loc-search-attrib {
  padding: 4px 9px;
  border-top: 1px solid var(--glass-edge);
  font-family: var(--cond);
  font-size: 9px; letter-spacing: 0.05em;
  color: var(--faint);
}
.loc-search-attrib a { color: var(--muted); text-decoration: underline; }
/* Nudge the readout cluster clear if the search ever overlaps on very narrow maps. */

/* PAL-L-17: floating MIND answer panel + temporary map pin overlay */
.mind-query-panel {
  /* Top-level .app overlay, right-anchored over the map. z-index above the nav-shell (700) and
     status bar (710) in globe modes so it's never trapped behind them; clear of the left nav/dock. */
  position: absolute; top: calc(var(--bar-h) + var(--gap)); right: var(--gap); left: auto; z-index: 720;
  width: min(380px, calc(100vw - 24px));
  max-height: min(52vh, 420px); overflow: auto;
  padding: 10px 12px 12px;
  background: var(--glass-strong);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: 0 10px 28px rgba(0,0,0,0.38);
}
.mind-query-panel[hidden] { display: none !important; }
.mind-query-head {
  display: flex; align-items: flex-start; gap: 8px;
  margin-bottom: 8px;
}
.mind-query-head h3 { margin: 0; font-size: 14px; }
.mind-query-readonly {
  margin-left: auto;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent);
  border: 1px solid rgba(52,224,207,0.28);
  border-radius: 2px; padding: 3px 6px;
}
.mind-query-status {
  margin: 0 0 8px;
  font-size: 11px; color: var(--med);
}
.mind-query-status.err { color: var(--bad); font-weight: 600; }
.mind-query-summary {
  margin: 0 0 10px;
  font-size: 12px; line-height: 1.45; color: var(--text);
}
.mind-query-facts {
  margin: 0 0 10px; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 6px;
}
.mind-query-fact {
  font-size: 11px; line-height: 1.4; color: var(--muted);
  padding: 6px 8px;
  border-left: 2px solid var(--accent);
  background: rgba(0,0,0,0.16);
  border-radius: 0 4px 4px 0;
}
.mind-query-fact-empty,
.mind-query-cite-empty {
  font-size: 11px; color: var(--faint); font-style: italic;
}
.mind-query-citations-wrap .k {
  font-size: 10px; color: var(--faint);
  text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 6px;
}
.mind-query-citations {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.mind-query-cite {
  font-family: var(--mono); font-size: 10px;
  padding: 4px 8px; border-radius: 2px;
  border: 1px solid var(--line);
  background: var(--surface-2); color: var(--text);
  cursor: pointer;
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mind-query-cite:hover { border-color: var(--accent); color: var(--accent); }
.mind-query-cite.mind-cite-alert { border-top: 2px solid var(--high); }
.mind-query-cite.mind-cite-entity { border-top: 2px solid #a8842f; }
.mind-query-map-pin {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 0 8px rgba(0,0,0,0.55);
}
.mind-query-map-pin.mind-pin-entity { background: #ffc943; }
.mind-query-map-pin.mind-pin-alert { background: var(--high); }

/* PAL-L-25: mission template selector in the command bar */
.sb-template {
  display: flex; align-items: center; gap: 6px;
  padding: 2px 6px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2);
  background: rgba(8, 12, 18, 0.45);
}
.mission-template-select {
  min-width: 118px; max-width: 156px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase;
}
.mission-template-org {
  font-size: 10px; letter-spacing: 0.06em; white-space: nowrap;
}
.template-reveal {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--muted); cursor: pointer;
  user-select: none;
}
.template-reveal input { accent-color: var(--accent); }
.template-reveal-lbl { line-height: 1; }
.ab-btn.template-hidden { display: none !important; }


/* Tactical texture over the map: corner vignette + faint scanlines. Pointer-
   transparent so it never intercepts map interaction. Kept very subtle. */
.stage-veil {
  position: absolute; inset: 0; z-index: 450; pointer-events: none;
  /* WS-UI-2: matte world = cleaner map — vignette/scanlines at half strength */
  background:
    radial-gradient(130% 120% at 50% 50%, transparent 60%, rgba(2,5,9,0.28) 100%),
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0,0,0,0.02) 2px 3px);
  mix-blend-mode: multiply;
}

/* ---- ATAK-first degraded banner (PAL-L-33) -------------------------------- */
.cop-degraded-banner {
  position: absolute; top: var(--bar-h); left: 0; right: 0; z-index: 29;
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px;
  padding: 7px 16px;
  background: linear-gradient(180deg, rgba(255,153,0,0.20), rgba(255,120,0,0.10));
  border-bottom: 1px solid rgba(255,180,60,0.38);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
  color: var(--text);
  box-shadow: 0 6px 18px rgba(0,0,0,0.22);
  pointer-events: none;
}
.cop-degraded-banner[hidden] { display: none !important; }
.cop-degraded-icon { color: var(--med); font-size: 10px; }
.cop-degraded-text {
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.12em;
  color: #ffc943;
}
.cop-degraded-sub {
  color: var(--muted); font-size: 10px; letter-spacing: 0.03em;
}

/* ---- Top command bar (matte instrument strip) --------------------------- */
.statusbar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 30;
  display: flex; align-items: center;
  height: var(--bar-h);
  padding: 0 20px; gap: 20px;
  background: var(--glass-strong);
  border-bottom: 1px solid var(--line-2);
  box-shadow: 0 6px 20px rgba(0,0,0,0.3);
}
.statusbar::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--hair);
  opacity: 0.55;
}
/* instrument clusters read as separate gauges: hairline vertical separators */
.sb-health, .tallies, .sb-op {
  border-left: 1px solid var(--line);
  padding-left: 18px;
  margin-left: 2px;
}
.sb-left { display: flex; align-items: center; gap: 12px; }
.sb-left .wordmark { font-size: 19px; }
.classification {
  font-family: var(--cond); font-weight: 600;
  font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line-2); border-radius: 2px;
  padding: 3px 8px;
}
.sb-spacer { flex: 1; }

.sb-health { display: flex; align-items: center; gap: 8px; }
.pill {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--cond); font-weight: 600;
  font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 2px; padding: 4px 10px 4px 8px;
  transition: border-color 0.12s var(--ease), color 0.12s var(--ease);
}
.pill .dot {
  width: 7px; height: 7px; border-radius: 1px;   /* square LED */
  background: var(--faint); position: relative;
  transition: background 0.12s var(--ease);
}
.pill.ok .dot { background: var(--ok); box-shadow: 0 0 9px rgba(52,216,160,0.7); }
.pill.bad .dot { background: var(--bad); box-shadow: 0 0 9px rgba(255,93,108,0.7); }
.pill.ok { color: var(--text); border-color: rgba(52,216,160,0.28); }
.pill.bad { color: var(--text); border-color: rgba(255,93,108,0.4); }
.pill.bad .dot { animation: hbeat 1.1s steps(2, jump-none) infinite; }
@keyframes hbeat { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }
.pill .lbl { color: var(--faint); }
.pill.ok .lbl, .pill.bad .lbl { color: var(--muted); }

/* mission clock (UTC / zulu) — an instrument readout */
.sb-clock-wrap {
  display: inline-flex; align-items: baseline; gap: 5px;
  border-left: 1px solid var(--line); padding-left: 14px;
}
.sb-clock {
  font-family: var(--mono);
  font-size: 15px; font-weight: 500; color: var(--text);
  letter-spacing: 0.06em; font-variant-numeric: tabular-nums;
}
.sb-clock-z {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.16em;
  color: var(--accent);
}

.sb-updated {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  white-space: nowrap;
}
.sb-updated .lbl { color: var(--faint); }
.sb-updated b { color: var(--text); font-weight: 500; }

/* severity tallies — segmented counter blocks: flat cells, 2px severity
   top-rule, mono count, condensed label; zero-state dimmed. */
.tallies { display: flex; align-items: center; gap: 4px; }
.tally {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 11px;
  padding: 3px 9px; border-radius: 2px;
  border: 1px solid var(--line);
  border-top: 2px solid var(--line-2);
  background: var(--surface-2);
  transition: opacity 0.12s var(--ease), border-color 0.12s var(--ease);
}
.tally .glyph {
  width: 7px; height: 7px; border-radius: 1px; transform: rotate(45deg);
}
.tally .n {
  font-weight: 500; font-size: 15px; color: var(--text);
  min-width: 1ch; text-align: right; font-variant-numeric: tabular-nums;
  line-height: 1;
}
.tally .k {
  font-family: var(--cond); font-weight: 600; font-size: 10px;
  color: var(--faint); letter-spacing: 0.12em; text-transform: uppercase;
}
.tally.t-crit { border-top-color: var(--crit); }
.tally.t-high { border-top-color: var(--high); }
.tally.t-med  { border-top-color: var(--med); }
.tally.t-low  { border-top-color: var(--low); }
.tally.t-crit .glyph { background: var(--crit); }
.tally.t-high .glyph { background: var(--high); }
.tally.t-med  .glyph { background: var(--med); }
.tally.t-low  .glyph { background: var(--low); }
.tally.zero { opacity: 0.35; }
.tally.zero .glyph { box-shadow: none; }
/* a live CRITICAL count earns a quiet heartbeat */
.tally.t-crit:not(.zero) { animation: critGlow 2s var(--ease) infinite; }
@keyframes critGlow {
  0%,100% { border-color: rgba(255,65,77,0.4); }
  50% { border-color: rgba(255,65,77,0.85); }
}

.sb-op { display: flex; align-items: center; gap: 12px; padding-left: 4px; }
.sb-locale { display: flex; align-items: center; }
.locale-select {
  min-width: 6.5rem;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(12, 18, 28, 0.55);
  border: 1px solid rgba(120, 150, 190, 0.22);
  color: var(--text-secondary, #9eb4cc);
}
.op-id {
  display: flex; flex-direction: column; align-items: flex-end; line-height: 1.25;
}
.op-id .op-name { font-size: 12px; color: var(--text); font-weight: 500; }
.op-id .op-org {
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  letter-spacing: 0.06em;
}

/* =============================================================================
   COMMAND NAVIGATION (GAP-UI-03) — activity-bar icon rail + single docked panel
   The VS Code / Lattice pattern: a thin always-on icon rail (status at a glance)
   plus ONE docked module panel. Selecting a module swaps the dock; re-clicking the
   active icon collapses the dock for a full-bleed map (the rail stays).
   ========================================================================== */
.nav-shell {
  position: absolute; z-index: 20;
  top: calc(var(--bar-h) + var(--gap));
  left: var(--gap);
  bottom: var(--gap);
  display: flex; flex-direction: row; align-items: stretch;
  gap: var(--gap);
  pointer-events: none; /* children re-enable — keeps the gap click-through to map */
}
.nav-shell > * { pointer-events: auto; }

/* ---- Activity bar (the icon rail) — flat carbon, no blur ---------------- */
.activity-bar {
  position: relative;
  flex: 0 0 var(--ab-w); width: var(--ab-w);
  display: flex; flex-direction: column; align-items: center;
  padding: 10px 0 12px;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  /* overflow visible so hover tooltips + the active edge-marker escape the rail */
  overflow: visible;
}
.activity-bar::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: var(--hair);
  opacity: 0.8; pointer-events: none;
}
.ab-brand {
  position: relative; width: 34px; height: 34px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 10px;
  border-radius: var(--r-md);
  border: 1px solid var(--glass-edge);
  background: rgba(52,224,207,0.08);
}
.ab-brand .ab-mark {
  font-family: var(--sans); font-weight: 600; font-size: 20px;
  color: var(--accent); line-height: 1;
}
.ab-brand .ab-mark-tick {
  position: absolute; top: 7px; right: 7px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 10px var(--accent-glow);
  animation: tickPulse 3.2s var(--ease) infinite;
}
.ab-modules {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 100%; overflow: visible; /* visible so the hover tooltip is never clipped */
}
.ab-divider {
  flex: 0 0 auto; width: 26px; height: 1px; margin: 4px 0;
  background: linear-gradient(90deg, transparent, var(--glass-edge), transparent);
  opacity: 0.85;
}
.ab-glabel {
  flex: 0 0 auto;
  font-family: var(--cond); font-size: 8px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--faint); margin: 3px 0 5px; line-height: 1;
  user-select: none;
}
.ab-action {
  position: relative; flex: 0 0 auto;
  width: 44px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--muted);
  border: 1px dashed var(--glass-edge); border-radius: var(--r-md);
  cursor: pointer;
  transition: background 0.12s var(--ease), color 0.12s var(--ease), border-color 0.12s var(--ease);
}
.ab-action:hover, .ab-action.active {
  background: rgba(255,255,255,0.05); color: var(--accent);
  border-color: var(--accent-line);
}
.ab-action.active { border-style: solid; background: var(--accent-dim); }

.ab-btn {
  position: relative; flex: 0 0 auto;
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--muted);
  border: 1px solid transparent; border-radius: var(--r-md);
  cursor: pointer;
  transition: background 0.12s var(--ease), color 0.12s var(--ease), border-color 0.12s var(--ease);
}
.ab-btn:hover { background: rgba(255,255,255,0.05); color: var(--accent); }
.ab-btn.active {
  background: var(--accent-dim); color: var(--accent);
  border-color: var(--accent-line);
}
/* active module: 2px accent left rule outside the rail edge */
.ab-btn.active::before {
  content: ""; position: absolute; left: -8px; top: 9px; bottom: 9px;
  width: 2px;
  background: var(--accent);
}
/* HUD target brackets (signature): two L-shaped accent corner ticks drawn
   with one pseudo via corner-anchored gradients (::before is the left rule). */
.ab-btn.active::after {
  content: ""; position: absolute; inset: -1px; pointer-events: none;
  background:
    linear-gradient(var(--bracket-line), var(--bracket-line)) top left / 9px 1px,
    linear-gradient(var(--bracket-line), var(--bracket-line)) top left / 1px 9px,
    linear-gradient(var(--bracket-line), var(--bracket-line)) bottom right / 9px 1px,
    linear-gradient(var(--bracket-line), var(--bracket-line)) bottom right / 1px 9px;
  background-repeat: no-repeat;
}
.ab-ico {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}

/* hover tooltip flag to the right of the rail — matte */
.ab-tip {
  position: absolute; left: calc(100% + 12px); top: 50%;
  transform: translateY(-50%) translateX(-4px);
  white-space: nowrap; pointer-events: none;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: 5px 9px; box-shadow: var(--shadow-soft);
  opacity: 0; visibility: hidden;
  transition: opacity 0.12s var(--ease), transform 0.12s var(--ease);
  z-index: 40;
}
.ab-btn:hover .ab-tip, .ab-btn:focus-visible .ab-tip {
  opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0);
}

/* count badge (alerts / assets / taskings) — hard rectangle. Pinned to the
   button's top-right INSIDE the rail; shrink-wraps wide counts (5 digits) via
   max-width so it never reaches the icon center or the group label above. */
.ab-badge {
  position: absolute; top: 2px; right: 2px;
  min-width: 15px; height: 14px; padding: 0 3px;
  max-width: 36px; overflow: visible;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 8.5px; font-weight: 600; line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text); background: var(--surface-3);
  border: 1px solid var(--line-2); border-radius: 2px;
}
.ab-badge.alarm {
  color: #fff; background: var(--crit); border-color: var(--crit);
  animation: critGlow 2s var(--ease) infinite;
}

/* status dot (feed / system) */
.ab-dot {
  position: absolute; bottom: 4px; right: 5px;
  width: 8px; height: 8px; border-radius: 999px;
  background: var(--faint); border: 1.5px solid var(--bg-1);
}
.ab-dot.ok, .ab-dot.live { background: var(--ok); box-shadow: 0 0 7px rgba(52,216,160,0.7); }
.ab-dot.bad { background: var(--bad); box-shadow: 0 0 7px rgba(255,93,108,0.7);
  animation: hbeat 1.1s steps(2, jump-none) infinite; }
.ab-dot.wait { background: var(--med); }
.ab-dot.off { background: var(--faint); }
.ab-dot.cop-live { animation: fmvPulse 1.6s ease infinite; }

/* ---- Dock (the single docked module panel) — THE matte-carbon statement --
   Fully opaque instrument housing: no backdrop-filter, hairline border, sharp
   radius, deep shadow, quiet line-colored HUD corner brackets. -------------- */
.dock {
  position: relative; z-index: 1;
  flex: 0 0 var(--rail-w); width: var(--rail-w); min-width: 0;
  display: flex; flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.dock::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 2px; z-index: 3;
  background: var(--accent); opacity: 0.55; pointer-events: none;
}
/* HUD target brackets (signature, structural line color — quiet) */
.dock::after {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  background:
    linear-gradient(var(--line-2), var(--line-2)) top left / 9px 1px,
    linear-gradient(var(--line-2), var(--line-2)) top left / 1px 9px,
    linear-gradient(var(--line-2), var(--line-2)) bottom right / 9px 1px,
    linear-gradient(var(--line-2), var(--line-2)) bottom right / 1px 9px;
  background-repeat: no-repeat;
}
.dock[data-module="sectors"],
.dock[data-module="alerts"] { --dock-accent: var(--accent); }
.dock[data-module="rules"],
.dock[data-module="infra"] { --dock-accent: #2fd6c3; }
.dock[data-module="dispatch"],
.dock[data-module="assets"],
.dock[data-module="taskings"] { --dock-accent: #5aa8ff; }
.dock[data-module="feed"] { --dock-accent: var(--ok); }
.dock[data-module="system"] { --dock-accent: var(--med); }
.dock::before { background: var(--dock-accent, var(--accent)); }

.dock-top {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 13px 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.dock-crumb {
  display: flex; align-items: baseline; gap: 7px; min-width: 0;
}
.dock-group {
  font-family: var(--cond); font-weight: 600; font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--faint); flex: 0 0 auto;
}
.dock-sep { color: var(--faint); font-size: 11px; flex: 0 0 auto; opacity: 0.7; }
.dock-module {
  font-family: var(--cond); font-weight: 600;
  font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.dock-close {
  position: static; flex: 0 0 auto;
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.22); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  color: var(--muted); cursor: pointer; transition: color .12s, border-color .12s, background .12s;
}
.dock-close:hover { color: var(--accent); border-color: var(--accent-line); background: rgba(52, 224, 207, 0.08); }
.dock-close:active { transform: translateY(1px); }

/* Panel chrome is in .dock-top — hide duplicate titles, keep module-specific widgets. */
.dock .panel-head {
  padding: 8px 13px 6px 16px; min-height: 0;
  border-bottom: 0; background: transparent; justify-content: flex-end; gap: 8px;
}
.dock .panel-head h2 {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.dock .panel-head .count {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
/* Breadcrumb is the title — drop empty panel-head rows (widgets-only panels keep it). */
.dock .panel-head:not(:has(.hstat, .fmv-pill, .fmv-expand-btn)) { display: none; }
/* only the active module renders; others are display:none */
.dock .panel { display: none; }
.dock .panel.active {
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0; height: 100%;
}
.dock.dock-swap .panel.active {
  animation: dockSwapIn 0.16s var(--ease) both;
}
@keyframes dockSwapIn {
  from { opacity: 0; transform: translateX(-10px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .dock.dock-swap .panel.active { animation: none; }
}

/* ---- Panels (collapsible cards within the rail) ------------------------ */
.panel {
  background: rgba(255,255,255,0.018);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color 0.12s var(--ease);
}
.panel:hover { border-color: var(--line-2); }
.panel-head {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 11px 13px;
  background: transparent; border: 0; cursor: pointer;
  color: var(--text); text-align: left;
  border-bottom: 1px solid var(--line);
  transition: background 0.12s var(--ease);
}
.panel-head:hover { background: rgba(255,255,255,0.035); }
.panel-head .chev {
  color: var(--accent); font-size: 11px;
  transition: transform 0.12s var(--ease);
  width: 12px;
}
.panel.collapsed .panel-head .chev { transform: rotate(-90deg); color: var(--muted); }
.panel.collapsed .panel-head { border-bottom-color: transparent; }
.panel-head h2 {
  margin: 0; font-family: var(--cond); font-size: 12px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text);
  flex: 1;
}
.panel-head .count {
  font-family: var(--mono); font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums;
  background: rgba(0,0,0,0.35); border: 1px solid var(--line);
  border-radius: 2px; padding: 1px 9px; min-width: 22px; text-align: center;
}
.panel-head .count.alarm {
  color: var(--crit); border-color: rgba(255,65,77,0.5);
  background: rgba(255,65,77,0.08);
}
.panel-body { display: block; }
.panel.collapsed .panel-body { display: none; }

/* ---- Panel inside the dock (GAP-UI-03) --------------------------------- */
/* The dock owns the frame; each panel is a flush, full-height, scrolling view.
   The activity-bar icon does the show/hide, so the header is a static label. */
.dock .panel {
  background: transparent; border: 0; border-radius: 0; overflow: visible;
}
.dock .panel:hover { border-color: transparent; }
.dock .panel-head { cursor: default; flex: 0 0 auto; }
.dock .panel-head:hover { background: transparent; }
.dock .panel-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent;
}
.dock .panel-body::-webkit-scrollbar { width: 9px; }
.dock .panel-body::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 99px;
  border: 3px solid transparent; background-clip: padding-box;
}
.dock .panel-body::-webkit-scrollbar-track { background: transparent; }
/* lists grow with the body — the panel-body is the single scroll container */
.dock .panel .list { max-height: none; overflow: visible; }
.dock .panel .health-list { max-height: none; }

.panel-tools {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 13px 10px 16px; border-bottom: 1px solid var(--line);
  background: rgba(0,0,0,0.14);
}

/* Reusable dock subsections (infra, health, etc.) */
.panel-section { padding: 0 13px 14px 16px; }
/* the placard head carries the hairline top rule — no doubled section border */
.panel-section + .panel-section {
  padding-top: 12px;
}
.panel-section-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-bottom: 8px;
  border-top: 1px solid var(--line);
  padding-top: 8px;
}
.panel-section-head h3 {
  margin: 0; font-family: var(--cond); font-size: 11px; font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}
.panel-section-count { display: none; }
.panel-filter-note {
  font-family: var(--mono); font-size: 10px; color: var(--faint);
  margin-left: auto; flex: 0 0 auto; white-space: nowrap;
}
.panel-filter-note[hidden] { display: none; }
.panel-callout {
  margin: 4px 13px 14px 16px; padding: 11px 12px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(47,214,195,0.22);
  background: linear-gradient(135deg, rgba(47,214,195,0.07), rgba(0,0,0,0.18));
}
.panel-callout-title {
  display: block; font-family: var(--cond); font-weight: 600; font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase; color: #2fd6c3; margin-bottom: 6px;
}
.panel-callout p {
  margin: 0; font-size: 11.5px; line-height: 1.55; color: var(--muted);
}
.panel-callout strong { color: var(--text); font-weight: 600; }

/* Shared KPI strip across dock modules — flat instrument cells */
.dock-kpis {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  padding: 12px 13px 12px 16px;
  border-bottom: 1px solid var(--line);
  background: rgba(0,0,0,0.12);
}
.dock-kpi {
  padding: 8px 10px; border-radius: 2px;
  border: 1px solid var(--line); border-top: 1px solid var(--line-2);
  background: var(--surface-2);
  display: flex; flex-direction: column; gap: 4px; min-width: 0;
}
.dock-kpi .k {
  font-family: var(--cond); font-weight: 600; font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--faint);
}
.dock-kpi .v {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 19px; font-weight: 500; color: var(--accent); line-height: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dock-kpi-warn { border-top: 2px solid var(--med); }
.dock-kpi-warn .v { color: var(--high); }
.dock-kpi-warn.dock-kpi-crit { border-top-color: var(--crit); }
.dock-kpi-warn.dock-kpi-crit .v { color: var(--crit); }
.dock-kpis-2 { grid-template-columns: repeat(2, 1fr); }

.panel-body-dispatch .panel-callout-dispatch { margin-top: 10px; }
.panel-body-rules .panel-callout,
.panel-body-taskings .panel-callout { margin-bottom: 0; }

.dock .list-cards { padding: 0; max-height: none; }
.dock .list-cards > li {
  margin-bottom: 8px; border: 1px solid var(--line); border-radius: 3px;
  background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.dock .list-cards > li:last-child { margin-bottom: 0; }
.dock .list-cards > li:hover {
  background: var(--surface-3); border-color: var(--line-2);
  box-shadow: inset 2px 0 0 var(--accent-line);
}
.dock .list-cards > li.state {
  border-style: dashed; background: rgba(0,0,0,0.12); cursor: default;
}
/* Card lists: preserve severity/priority rails inside bordered rows */
.dock .list-cards > li.sector-row::before {
  left: 0; top: 8px; bottom: 8px; border-radius: 0 2px 2px 0;
}
.dock .list-cards > li.alert-row {
  overflow: hidden;
}
.dock .list-cards > li.alert-row .sev-bar {
  margin: -10px 3px -10px -11px;
}
.dock .list-cards > li.rule-row,
.dock .list-cards > li.hq-row,
.dock .list-cards > li.hs-row,
.dock .list-cards > li.tasking-row,
.dock .list-cards > li.asset-row,
.dock .list-cards > li.validation-row {
  border-bottom: 0;
}

/* ---- Lists (sectors / alerts / taskings) ------------------------------- */
.list { list-style: none; margin: 0; padding: 0; max-height: 340px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
.list::-webkit-scrollbar { width: 8px; }
.list::-webkit-scrollbar-thumb {
  background: var(--line-2); border-radius: 99px;
  border: 2px solid transparent; background-clip: padding-box;
}
.list li {
  position: relative;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  display: flex; align-items: center; gap: 10px;
  transition: background 0.12s var(--ease);
}
.list li:last-child { border-bottom: 0; }
.list li:hover { background: rgba(255,255,255,0.04); }
.list li:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.list .grow { flex: 1; min-width: 0; }
.list .title {
  font-weight: 600; font-size: 13px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.list .meta {
  color: var(--muted); font-size: 11px; margin-top: 3px;
  font-family: var(--mono); letter-spacing: 0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* sector priority rail-stripe — 2px severity edge */
.sector-row { padding-left: 17px; }
.sector-row::before {
  content: ""; position: absolute; left: 0; top: 9px; bottom: 9px;
  width: 2px; background: var(--accent);
}
.sector-row.p-high::before { background: var(--high); }
.sector-row.p-med::before { background: var(--med); }
.sector-row.p-low::before { background: var(--accent); }
.sector-row.off { opacity: 0.5; }
.sector-row .pchip {
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  border: 1px solid var(--line-2); border-radius: 5px; padding: 1px 7px;
  flex: 0 0 auto;
}

/* mission-category badge (WS-MISSION-01) — sector type at a glance */
.mbadge {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.04em;
  border: 1px solid var(--line-2); border-radius: 5px; padding: 1px 6px;
  flex: 0 0 auto; text-transform: uppercase; color: var(--muted);
}
.mbadge.mt-general        { color: var(--faint); border-color: var(--line-2); }
.mbadge.mt-maritime       { color: #4ea1ff; border-color: rgba(78,161,255,0.42); }
.mbadge.mt-border         { color: #ff9142; border-color: rgba(255,145,66,0.42); }
.mbadge.mt-disaster       { color: #ff5d5d; border-color: rgba(255,93,93,0.42); }
.mbadge.mt-infrastructure { color: #c98bff; border-color: rgba(201,139,255,0.42); }
/* slightly smaller select used inside panel-tools (e.g. sector mission filter) */
.select.small { font-size: 11px; padding: 4px 8px; }
.popup-h .mbadge { margin-left: 7px; }

/* alert rows — severity as a precise 2px instrument edge */
.alert-row { padding-left: 14px; }
.alert-row .sev-bar {
  width: 2px; align-self: stretch;
  margin: -10px 3px -10px -14px;
  flex: 0 0 2px;
}
.alert-row.s-CRITICAL { background: linear-gradient(90deg, rgba(255,65,77,0.06), transparent 42%); }
.alert-row.s-CRITICAL .sev-bar { background: var(--crit); }
/* HUD target brackets (signature): CRITICAL contact cards get crit corner ticks */
.alert-row.s-CRITICAL::after {
  content: ""; position: absolute; inset: -1px; pointer-events: none;
  background:
    linear-gradient(rgba(255,65,77,0.65), rgba(255,65,77,0.65)) top left / 9px 1px,
    linear-gradient(rgba(255,65,77,0.65), rgba(255,65,77,0.65)) top left / 1px 9px,
    linear-gradient(rgba(255,65,77,0.65), rgba(255,65,77,0.65)) bottom right / 9px 1px,
    linear-gradient(rgba(255,65,77,0.65), rgba(255,65,77,0.65)) bottom right / 1px 9px;
  background-repeat: no-repeat;
}
.alert-row.s-HIGH .sev-bar { background: var(--high); }
.alert-row.s-MEDIUM .sev-bar { background: var(--med); }
.alert-row.s-LOW .sev-bar { background: var(--low); }
.alert-row .when { font-family: var(--mono); font-size: 11px; color: var(--muted); }

/* severity tag */
.sev-tag {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: 0.08em;
  padding: 2px 8px; border-radius: 6px;
  border: 1px solid transparent; flex: 0 0 auto;
}
.sev-tag .g { width: 7px; height: 7px; border-radius: 2px; transform: rotate(45deg); }
.sev-tag.s-CRITICAL { color: var(--crit); background: rgba(255,65,77,0.12); border-color: rgba(255,65,77,0.38); }
.sev-tag.s-CRITICAL .g { background: var(--crit); }
.sev-tag.s-HIGH { color: var(--high); background: rgba(255,145,66,0.11); border-color: rgba(255,145,66,0.34); }
.sev-tag.s-HIGH .g { background: var(--high); }
.sev-tag.s-MEDIUM { color: var(--med); background: rgba(255,201,67,0.11); border-color: rgba(255,201,67,0.32); }
.sev-tag.s-MEDIUM .g { background: var(--med); }
.sev-tag.s-LOW { color: var(--low); background: rgba(90,168,255,0.11); border-color: rgba(90,168,255,0.32); }
.sev-tag.s-LOW .g { background: var(--low); }

.dispatched-chip {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.07em;
  color: var(--ok); margin-left: 6px;
}

/* ---- Geofence rules (GAP-UI-04) --------------------------------------- */
/* Tier chip: WARNING=crit red, CAUTION=med amber, ADVISORY=low blue. Shared by
   rule rows and tripped-alert rows. */
.tier-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.07em; padding: 1px 7px; border-radius: 6px;
  border: 1px solid transparent; flex: 0 0 auto; margin-left: 6px;
}
.tier-chip .g { width: 6px; height: 6px; border-radius: 2px; transform: rotate(45deg); }
.tier-chip.tier-WARNING { color: var(--crit); background: rgba(255,65,77,0.12); border-color: rgba(255,65,77,0.38); }
.tier-chip.tier-WARNING .g { background: var(--crit); }
.tier-chip.tier-CAUTION { color: var(--med); background: rgba(255,201,67,0.11); border-color: rgba(255,201,67,0.32); }
.tier-chip.tier-CAUTION .g { background: var(--med); }
.tier-chip.tier-ADVISORY { color: var(--low); background: rgba(90,168,255,0.11); border-color: rgba(90,168,255,0.32); }
.tier-chip.tier-ADVISORY .g { background: var(--low); }

/* PAL-L-16: pattern-of-life badge + MIND advisory priority (display-only hint). */
.pattern-badge {
  display: inline-flex; align-items: center;
  font-family: var(--mono); font-size: 9px; font-weight: 700;
  letter-spacing: 0.12em;
  color: #1a1030;
  background: linear-gradient(180deg, #b58cff, #8a5fd6);
  border-radius: 4px; padding: 2px 6px; margin-left: 7px;
  box-shadow: 0 0 10px rgba(181,140,255,0.35);
  flex: 0 0 auto;
}
.advisory-priority-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.06em; padding: 1px 7px; border-radius: 6px;
  border: 1px dashed rgba(150, 162, 188, 0.55);
  background: rgba(110, 120, 145, 0.1);
  color: var(--muted); flex: 0 0 auto; margin-left: 6px;
}
.advisory-priority-chip .advisory-lbl {
  font-weight: 700; letter-spacing: 0.1em; color: var(--muted);
}
.advisory-priority-chip .advisory-val { font-weight: 600; }
.advisory-priority-chip .advisory-val.tier-WARNING { color: var(--crit); }
.advisory-priority-chip .advisory-val.tier-CAUTION { color: var(--med); }
.advisory-priority-chip .advisory-val.tier-ADVISORY { color: var(--low); }
.popup-kv .advisory-priority-chip { margin-left: 0; margin-top: 4px; }

.rule-row { display: flex; align-items: center; gap: 9px; }
.rule-row.off { opacity: 0.55; }
.rule-title { display: flex; align-items: center; gap: 4px; min-width: 0; }
.rule-title span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rule-toggle { accent-color: var(--accent); cursor: pointer; flex: 0 0 auto; }
.rule-del { flex: 0 0 auto; }
.rule-del.armed {
  color: var(--crit); border-color: rgba(255,65,77,0.5);
  background: rgba(255,65,77,0.1);
}

.rule-form { padding: 13px; border-top: 1px solid var(--line); }
.rule-form-head {
  font-family: var(--cond); font-weight: 600; font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent); margin-bottom: 6px;
}
.rule-aoi { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-top: 4px; }
.rule-aoi-info { font-family: var(--mono); font-size: 10.5px; color: var(--muted); flex: 1; min-width: 0; }
.rule-aoi-info.ok { color: var(--ok); }
.rule-msg {
  margin: 9px 0 0; font-size: 11.5px; color: var(--muted);
}
.rule-msg.err { color: var(--bad); }
/* Geofence map labels: dashed tier-colored polygons carry a centered rule name. */
.rule-label { opacity: 0.92; }

/* ---- Imagery collection tasking (PAL-L-05) ------------------------------- */
.imgtask-row { display: flex; align-items: flex-start; gap: 9px; }
.imgtask-title { display: flex; align-items: center; gap: 6px; min-width: 0; }
.imgtask-title span:first-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.imgtask-sub { font-family: var(--mono); font-size: 10px; color: var(--faint); }
.imgtask-form { padding: 13px; border-top: 1px solid var(--line); }
/* Order-status pill — one color per lifecycle state. */
.imgtask-badge {
  flex: 0 0 auto;
  font-family: var(--cond); font-weight: 600; font-size: 9.5px;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 3px;
  border: 1px solid var(--line); color: var(--muted);
  background: rgba(158, 180, 200, 0.08);
}
.imgtask-badge.imgtask-pending,
.imgtask-badge.imgtask-queued {
  color: var(--low); border-color: rgba(90, 168, 255, 0.42);
  background: rgba(90, 168, 255, 0.1);
}
.imgtask-badge.imgtask-submitted {
  color: var(--accent); border-color: var(--accent-line);
  background: var(--accent-dim);
}
.imgtask-badge.imgtask-fulfilled {
  color: var(--ok); border-color: rgba(52, 216, 160, 0.42);
  background: rgba(52, 216, 160, 0.1);
}
.imgtask-badge.imgtask-failed {
  color: var(--crit); border-color: rgba(255, 65, 77, 0.5);
  background: rgba(255, 65, 77, 0.1);
}
.imgtask-badge.imgtask-expired {
  color: var(--faint); border-color: var(--line);
  background: rgba(158, 180, 200, 0.06);
}

/* ---- Tip-and-cue rules (PAL-L-03) ---------------------------------------- */
.panel-section-tipcue .panel-section-head .count.small {
  font-size: 10px;
  margin-left: 6px;
}
.tipcue-row .tipcue-actions-meta {
  color: var(--accent);
  letter-spacing: 0.04em;
}
.tipcue-form fieldset.tipcue-actions-field {
  border: none;
  margin: 10px 0 0;
  padding: 0;
}
.tipcue-form fieldset.tipcue-actions-field legend {
  font-size: 11px;
  color: var(--muted);
  margin-bottom: 6px;
  padding: 0;
}
.tipcue-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
}
.tipcue-action-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  cursor: pointer;
}
.tipcue-action-opt input { accent-color: var(--accent); cursor: pointer; }
.muted-hint { color: var(--faint); font-weight: 400; font-size: 10px; }
.cue-log-row { display: flex; align-items: center; gap: 9px; }
.cue-chip {
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  color: var(--muted);
  background: rgba(0,0,0,0.25);
}
.cue-chip.cue-await { color: var(--med); border-color: rgba(255,201,67,0.45); }
.cue-chip.cue-ok { color: var(--ok); border-color: rgba(52,216,160,0.45); }
.cue-chip.cue-bad { color: var(--bad); border-color: rgba(255,65,77,0.45); }
.panel-section-cuelog .panel-section-head {
  align-items: center;
  gap: 8px;
}
.panel-section-cuelog .panel-section-head .btn { margin-left: auto; }

/* ---- Live FMV tile (WS-6) ---------------------------------------------- */
/* Header pill mirrors the system-health pills: green dot = LIVE. */
.fmv-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em;
  padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--line-2); color: var(--muted);
  background: rgba(0,0,0,0.35); flex: 0 0 auto;
}
.fmv-pill .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--faint); flex: 0 0 auto;
}
.fmv-pill.live { color: var(--ok); border-color: rgba(52,216,160,0.5); background: rgba(52,216,160,0.08); }
.fmv-pill.live .dot { background: var(--ok); box-shadow: 0 0 8px rgba(52,216,160,0.8); animation: fmvPulse 1.6s ease infinite; }
.fmv-pill.wait { color: var(--med); border-color: rgba(255,201,67,0.45); }
.fmv-pill.wait .dot { background: var(--med); }
.fmv-pill.off { color: var(--faint); }

@keyframes fmvPulse { 0%,100% { opacity: 0.55; } 50% { opacity: 1; } }

/* The video stage: 16:9 glass tile inside the panel body. */
.fmv-tile {
  position: relative;
  margin: 11px; border-radius: var(--r-sm);
  aspect-ratio: 16 / 9; overflow: hidden;
  background: #02050a;
  border: 1px solid var(--line-2);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.4), var(--shadow-soft);
}
.fmv-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; background: #02050a; display: block;
}
/* subtle scanline/vignette so the feed reads as a tactical surface */
.fmv-veil {
  position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    radial-gradient(120% 120% at 50% 40%, transparent 60%, rgba(0,0,0,0.45)),
    repeating-linear-gradient(0deg, rgba(0,0,0,0.12) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply; opacity: 0.5;
}

/* On-tile HUD overlay (only shown when live). */
.fmv-overlay { position: absolute; inset: 0; z-index: 3; pointer-events: none; opacity: 0; transition: opacity 0.25s var(--ease); }
.fmv-tile[data-state="live"] .fmv-overlay { opacity: 1; }
.fmv-tl { position: absolute; top: 7px; left: 8px; display: flex; align-items: center; gap: 7px; }
.fmv-tr { position: absolute; top: 9px; right: 9px; font-size: 9px; letter-spacing: 0.12em; color: rgba(255,255,255,0.78); text-shadow: 0 1px 3px rgba(0,0,0,0.9); }
.fmv-asset { font-size: 10px; color: rgba(255,255,255,0.85); text-shadow: 0 1px 3px rgba(0,0,0,0.9); letter-spacing: 0.08em; }
.fmv-live {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0.12em;
  color: #fff; padding: 1px 7px; border-radius: 4px;
  background: rgba(255,65,77,0.85); text-shadow: 0 1px 2px rgba(0,0,0,0.6);
}
.fmv-live .lv-dot { width: 6px; height: 6px; border-radius: 50%; background: #fff; animation: fmvPulse 1.2s ease infinite; }

/* Center crosshair — GAP-UI-06: faint, clearly-decorative ONLY (no corner "lock"
   brackets). Real ML detection boxes (the .fmv-detect-canvas overlay) now carry the
   tracking semantics, so this is just a subtle framing aid, dimmed so it never reads
   as a weapons/sensor lock. */
.fmv-reticle { position: absolute; left: 50%; top: 50%; width: 96px; height: 96px; transform: translate(-50%,-50%); }
.fmv-reticle .r-h, .fmv-reticle .r-v { position: absolute; background: rgba(52,224,207,0.18); }
.fmv-reticle .r-h { left: 42%; right: 42%; top: 50%; height: 1px; }
.fmv-reticle .r-v { top: 42%; bottom: 42%; left: 50%; width: 1px; }

/* FMV object-detection overlay (GAP-UI-06, WS-7) — a canvas inside .fmv-tile drawn
   exactly over the <video>. Reparents with the tile on expand/collapse. The detection
   cyan is distinct from the warm severity palette + the teal map tools. */
.fmv-detect-canvas {
  position: absolute; inset: 0; z-index: 5;
  width: 100%; height: 100%;
  pointer-events: none;
}
.fmv-tile[data-state="live"] .fmv-detect-canvas { opacity: 1; }
/* No live video -> no meaningful boxes; the canvas is cleared in JS, but hide it too. */
.fmv-tile:not([data-state="live"]) .fmv-detect-canvas { opacity: 0; }

/* NO SIGNAL state — shown unless the tile is live. */
.fmv-nosignal {
  position: absolute; inset: 0; z-index: 4;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 7px; text-align: center; padding: 14px;
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,0.018) 0 2px, transparent 2px 4px),
    radial-gradient(120% 120% at 50% 50%, #0a121b, #03070c);
}
.fmv-tile[data-state="live"] .fmv-nosignal { display: none; }
.fmv-nosignal .ns-title {
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: 0.22em; color: var(--muted);
}
.fmv-tile[data-state="connecting"] .fmv-nosignal .ns-title { color: var(--med); }
.fmv-nosignal .ns-sub { font-size: 10.5px; color: var(--faint); max-width: 240px; line-height: 1.5; }
.fmv-tile[data-state="connecting"] .fmv-nosignal .ns-sub { color: var(--muted); }
.fmv-nosignal .ns-bars { display: flex; gap: 4px; align-items: flex-end; height: 18px; }
.fmv-nosignal .ns-bars span {
  width: 4px; background: var(--line-2); border-radius: 1px;
  animation: nsBars 1.1s ease infinite;
}
.fmv-nosignal .ns-bars span:nth-child(1) { height: 8px; animation-delay: 0s; }
.fmv-nosignal .ns-bars span:nth-child(2) { height: 14px; animation-delay: 0.18s; }
.fmv-nosignal .ns-bars span:nth-child(3) { height: 18px; animation-delay: 0.36s; }
.fmv-tile[data-state="connecting"] .fmv-nosignal .ns-bars span { background: var(--med); }
@keyframes nsBars { 0%,100% { opacity: 0.3; } 50% { opacity: 0.9; } }

.fmv-tools { justify-content: space-between; }
.fmv-meta { font-size: 10px; color: var(--faint); letter-spacing: 0.05em; }
/* WS7-FILTER-01: "Show all classes" debug toggle in the FMV tools row. */
.fmv-showall {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; color: var(--faint); letter-spacing: 0.04em;
  cursor: pointer; user-select: none; white-space: nowrap;
}
.fmv-showall input { margin: 0; cursor: pointer; }

/* Asset picker — switch which asset feed the tile plays (WS-6b). */
.fmv-assetbar { align-items: center; gap: 8px; }
.fmv-assetbar-lbl {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--faint); flex: 0 0 auto;
}
.fmv-asset-select { font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; }

/* ---- Expand-to-map FMV overlay (GAP-UI-05) ----------------------------- */
/* A large floating glass player anchored over the map (right-docked). It sits ABOVE
   the Leaflet panes + controls but BELOW any modal (z 1200), and is geometrically
   clear of the top status bar + the left activity-bar/dock — the map stays fully
   interactive behind it (not a blocking modal). The SAME player surface is reparented
   in (see reparentFmv), so there is only ever one <video> / hls.js instance. */
.fmv-expand-btn { margin-left: auto; padding: 2px 9px; line-height: 1.5; font-size: 13px; }
.fmv-expand-btn[aria-pressed="true"] { color: var(--accent); border-color: var(--accent-line); }

.fmv-stage {
  position: absolute;
  top: calc(var(--bar-h) + var(--gap));
  right: var(--gap);
  bottom: var(--gap);
  width: min(68vw, 1120px);
  max-width: calc(100vw - var(--ab-w) - var(--rail-w) - var(--gap) * 3);
  z-index: 1100; /* above Leaflet controls (~1000), below the modal layer (1200) */
  display: flex; flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
/* GAP-UI-06: while the feed is expanded, hide the whole left dock so the map + feed
   get the space (the player lives in the over-map overlay) and the dock's "Live Feed"
   header no longer duplicates the overlay's title. The activity-bar icon rail stays.
   `!important` so this wins over the nav state machine (applyNavState sets dock.hidden).
   Restore the feed via the overlay's ✕ (fmv-collapse) / the activity-bar feed icon. */
.app.fmv-expanded .dock { display: none !important; }
/* With the dock gone, let the over-map overlay reclaim that width. */
.app.fmv-expanded .fmv-stage {
  max-width: calc(100vw - var(--ab-w) - var(--gap) * 2);
}

.fmv-stage-head {
  display: flex; align-items: center; gap: 10px;
  flex: 0 0 auto; padding: 9px 12px;
  border-bottom: 1px solid var(--glass-edge);
  /* GAP-UI-07: the head is the drag handle — grab cursor + no text selection or
     touch-scroll so a pointer drag repositions the floating feed cleanly. The ✕ /
     any interactive control keeps its own cursor and is excluded from the drag in JS. */
  cursor: grab; user-select: none; touch-action: none;
}
.fmv-stage-head button,
.fmv-stage-head a,
.fmv-stage-head input,
.fmv-stage-head select { cursor: pointer; touch-action: auto; }
/* While a drag/resize is live, suppress selection + show the active cursor globally. */
body.fmv-dragging { cursor: grabbing !important; user-select: none; }
body.fmv-resizing { cursor: nwse-resize !important; user-select: none; }
body.fmv-dragging .fmv-stage-head { cursor: grabbing; }

/* GAP-UI-07: custom bottom-right resize grip. The stage already has overflow:hidden,
   so the grip sits in the bottom-right corner above the body. Pointer-driven resize
   clamps to min 320x200 / the viewport and re-aligns the detection-box overlay. */
.fmv-stage-resize {
  position: absolute; right: 0; bottom: 0;
  width: 18px; height: 18px;
  z-index: 6; /* above the stage body + reparented tile */
  cursor: nwse-resize; touch-action: none;
  background:
    linear-gradient(135deg, transparent 0 50%, var(--accent-line) 50% 60%,
                    transparent 60% 72%, var(--accent-line) 72% 82%, transparent 82%);
  opacity: 0.8;
}
.fmv-stage-resize:hover { opacity: 1; }
.fmv-stage-title {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent);
}
.fmv-stage-spacer { flex: 1 1 auto; }
.fmv-stage-body {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  padding: 11px 12px 12px;
}
/* In the expanded stage the asset bar + tools stay compact; the tile fills the rest. */
.fmv-stage-body .fmv-assetbar { margin: 0 0 10px; }
.fmv-stage-body .fmv-tile {
  flex: 1 1 auto; min-height: 0; margin: 0;
  aspect-ratio: auto; width: 100%; height: 100%;
}
.fmv-stage-body .fmv-tools { margin: 10px 0 0; }
/* Larger reticle reads better at full size (purely cosmetic). */
.fmv-stage-body .fmv-reticle { width: 160px; height: 160px; }

/* ---- WS4-5b: 2-up compare split (Feed A | Feed B) ----------------------- */
/* The stage body is the split container. Pane A (the ONE reparented single-feed surface) fills
   it in single mode; the descendant `.fmv-stage-body .fmv-*` rules above still style the tile /
   asset bar through this transparent wrapper, so single-feed layout is unchanged. Toggling
   compare turns the body into two equal columns and reveals Feed B. The cross-feed re-ID accent
   (the Gxx label + deterministic hue) is drawn on the detection canvas in JS (drawFmvBox), not
   here — so a matching global_id reads as the same color in both panes. */
.fmv-pane { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.fmv-pane-a { flex: 1 1 auto; }
.fmv-pane-b { flex: 1 1 0; }
.fmv-stage.compare .fmv-stage-body { flex-direction: row; gap: 10px; }
.fmv-stage.compare .fmv-pane { flex: 1 1 0; }
/* Feed B's asset selector matches Pane A's compact expanded asset bar. */
.fmv-b-assetbar { margin: 0 0 10px; }

.fmv-compare-btn { padding: 2px 10px; line-height: 1.5; font-size: 11px; }
.fmv-compare-btn[aria-pressed="true"] { color: var(--accent); border-color: var(--accent-line); }

/* Dock placeholder shown while the feed is expanded over the map. */
.fmv-dock-placeholder { padding: 11px; }
.fmv-restore-tile {
  width: 100%; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 28px 16px; cursor: pointer;
  background: var(--glass); color: var(--muted);
  border: 1px dashed var(--glass-edge); border-radius: var(--r-sm);
  font: inherit; text-align: center;
  transition: border-color 0.12s var(--ease), color 0.12s var(--ease);
}
.fmv-restore-tile:hover { border-color: var(--accent-line); color: var(--text); }
.fmv-ph-icon { font-size: 22px; color: var(--accent); }
.fmv-ph-title { font-size: 12px; letter-spacing: 0.04em; }
.fmv-ph-sub { font-size: 10.5px; color: var(--faint); }

/* Responsive: on smaller windows the overlay shrinks toward the available width,
   anchored clear of the activity-bar icon rail. */
@media (max-width: 1100px) {
  .fmv-stage {
    width: auto; max-width: none;
    left: calc(var(--ab-w) + var(--gap) * 2);
  }
}

/* ---- Empty / loading / error states ------------------------------------ */
.state {
  padding: 24px 16px; text-align: center;
  color: var(--muted); font-size: 12.5px;
}
.state .state-title { color: var(--text); font-weight: 600; margin-bottom: 5px; }
.state .state-sub { font-size: 11.5px; color: var(--muted); line-height: 1.55; }
.state.err { color: var(--bad); }
.state.err .state-title { color: var(--bad); }
.state .retry { margin-top: 12px; }

/* WS-GLOBE-10: dock-list render-cap hint row (appended when a list exceeds
   DOCK_LIST_MAX rendered rows). Non-interactive, muted, hairline-topped. */
.list-cap-hint {
  padding: 10px 14px; text-align: center; list-style: none;
  border-top: 1px solid var(--line, rgba(255,255,255,0.08));
  color: var(--muted); cursor: default;
}
.list-cap-hint .list-cap-hint-title {
  color: var(--text); font-weight: 600; font-size: 11.5px;
}
.list-cap-hint .list-cap-hint-sub {
  font-size: 11px; color: var(--muted); margin-top: 3px; line-height: 1.5;
}

/* PERF-COP-RENDER-01: non-blocking map badge shown when the 2D COP entity/track
   layers are viewport-culled / capped beyond what's drawn. Top-centre of the map,
   never intercepts map interaction. */
.cop-cap-hint {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
  background: var(--glass-strong);
  border: 1px solid var(--glass-edge);
  border-radius: 4px;
  padding: 4px 10px;
  pointer-events: none;
  z-index: 5;
}
.cop-cap-hint .cch-ico { color: var(--acc, #4ea1ff); font-size: 11px; }
.cop-cap-hint[hidden] { display: none; }
.skeleton-row {
  height: 14px; margin: 12px 13px; border-radius: 5px;
  background: linear-gradient(90deg, rgba(255,255,255,0.04) 25%, rgba(255,255,255,0.1) 37%, rgba(255,255,255,0.04) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}
.skeleton-row.short { width: 55%; }
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* ---- Buttons + selects — flat, hairline, condensed placard labels ------- */
.btn {
  font-family: var(--cond); font-weight: 600; font-size: 11px;
  letter-spacing: 0.1em; text-transform: uppercase;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line-2); border-radius: 3px;
  padding: 7px 12px; cursor: pointer;
  transition: background 0.12s var(--ease), border-color 0.12s var(--ease), color 0.12s var(--ease);
}
.btn:hover { background: var(--surface-3); border-color: var(--accent-line); }
.btn.small { padding: 5px 10px; font-size: 10px; }
.btn.ghost { background: transparent; border-color: var(--line-2); }
.btn.ghost:hover { background: rgba(255,255,255,0.06); }
.btn:disabled { opacity: 0.5; cursor: default; }

.select {
  font-family: var(--sans); font-size: 12px;
  background: var(--bg-1); color: var(--text);
  border: 1px solid var(--line-2); border-radius: 3px;
  padding: 6px 10px; cursor: pointer;
  transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.select:hover { border-color: var(--accent-line); }
.select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim); }

/* ---- Dispatch form ------------------------------------------------------ */
.dispatch-form { padding: 13px; }
.dispatch-form label {
  display: block; margin: 12px 0 5px;
  color: var(--muted);
  font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase;
}
.dispatch-form label:first-child { margin-top: 0; }
.dispatch-form input,
.dispatch-form select,
.dispatch-form textarea {
  width: 100%; padding: 10px;
  border-radius: 3px;
  border: 1px solid var(--line);
  background: var(--bg-1); color: var(--text);
  font-family: var(--mono); font-size: 13px;
  transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.dispatch-form select { font-family: var(--sans); }
.dispatch-form textarea { resize: vertical; min-height: 44px; font-family: var(--sans); }
.dispatch-form input:focus,
.dispatch-form select:focus,
.dispatch-form textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.dispatch-form input:invalid:not(:placeholder-shown) {
  border-color: rgba(255,93,108,0.55);
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.hint {
  color: var(--faint); font-size: 11px; margin: 8px 0 0;
  font-family: var(--mono); letter-spacing: 0.01em;
}
.hint .key {
  border: 1px solid var(--line-2); border-radius: 3px; padding: 0 4px;
  color: var(--muted);
}

/* armed dispatch action — the "commit to action" moment: flat, weighted,
   RED armed semantics kept, 1px inner hairline instead of gradient/glow */
.dispatch-action {
  width: 100%; margin-top: 16px; padding: 13px;
  border: 1px solid var(--line-2); border-radius: 3px;
  background: var(--surface-2); color: var(--text);
  box-shadow: inset 0 0 0 1px rgba(170,195,220,0.08);
  font-family: var(--cond); font-weight: 600; font-size: 12.5px;
  letter-spacing: 0.12em; text-transform: uppercase; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  transition: all 0.12s var(--ease);
}
.dispatch-action:hover { border-color: var(--accent-line); background: rgba(52,224,207,0.07); }
.dispatch-action:disabled { opacity: 0.6; cursor: progress; }
.dispatch-action .lockicon { font-size: 11px; color: var(--accent); }
.dispatch-action.armed {
  background: rgba(255,65,77,0.14);
  border-color: var(--crit); color: #ffd9dc;
  box-shadow: inset 0 0 0 1px rgba(255,65,77,0.35);
  letter-spacing: 0.16em;
  animation: armPulse 1.3s var(--ease) infinite;
}
.dispatch-action.armed .lockicon { color: var(--crit); }
@keyframes armPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,65,77,0.0); }
  50% { box-shadow: 0 0 0 4px rgba(255,65,77,0.22); }
}
.dispatch-cancel {
  width: 100%; margin-top: 9px; padding: 7px;
  background: transparent; border: 0; color: var(--muted);
  font-size: 11.5px; cursor: pointer; letter-spacing: 0.04em;
}
.dispatch-cancel:hover { color: var(--text); }

/* WS-UI-2 follow-up: the dispatch COMMIT control reads armed-capable at idle —
   flat crit-tinted carbon (still no gradient/glow). Scoped to the dispatch
   module's button ONLY: the rule-builder's generic .dispatch-action ("Create
   rule") stays accent-neutral. */
#dispatch-btn,
.panel-body-dispatch .dispatch-action {
  border: 1px solid rgba(255, 65, 77, 0.55);
  background: rgba(255, 65, 77, 0.08);
  color: #ffb4ba;
  box-shadow: inset 0 0 0 1px rgba(255, 65, 77, 0.16);
}
#dispatch-btn .lockicon,
.panel-body-dispatch .dispatch-action .lockicon { color: var(--crit); }
#dispatch-btn:hover,
.panel-body-dispatch .dispatch-action:hover {
  border-color: var(--crit);
  background: rgba(255, 65, 77, 0.15);
}
/* armed/confirm = solid crit block with dark ink (armPulse ring kept) */
#dispatch-btn.armed,
.panel-body-dispatch .dispatch-action.armed {
  background: var(--crit);
  border-color: var(--crit);
  color: var(--crit-ink);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}
#dispatch-btn.armed .lockicon,
.panel-body-dispatch .dispatch-action.armed .lockicon { color: var(--crit-ink); }

/* =============================================================================
   MAP — Leaflet dark integration + controls
   ========================================================================== */
.leaflet-container { background: var(--bg-1); font-family: var(--sans); }

/* push the in-map controls clear of the floating command bar */
.leaflet-top { top: calc(var(--bar-h) + var(--gap)); }
.leaflet-right { right: var(--gap); }

.leaflet-bar {
  border: 1px solid var(--glass-edge) !important;
  box-shadow: var(--shadow-soft);
  border-radius: var(--r-sm); overflow: hidden;
}
.leaflet-control-zoom a {
  background: var(--surface-1); color: var(--text);
  border-color: var(--line) !important;
  transition: background 0.12s var(--ease), color 0.12s var(--ease);
}
.leaflet-control-zoom a:hover { background: var(--surface-3); color: var(--accent); }
.leaflet-control-attribution {
  background: rgba(9,11,14,0.88) !important;
  color: var(--faint) !important;
  font-family: var(--mono); font-size: 9.5px;
  border-top-left-radius: 3px;
}
.leaflet-control-attribution a { color: var(--muted) !important; }

/* ---- Leaflet layers control (basemap switcher) — glass theme ----------- */
.leaflet-control-layers {
  background: var(--surface-1);
  border: 1px solid var(--line-2) !important;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-soft);
  color: var(--text);
}
.leaflet-control-layers-toggle {
  width: 34px; height: 34px;
  filter: invert(0.82) brightness(1.15);
}
.leaflet-control-layers-expanded {
  padding: 10px 13px 10px 11px;
  font-family: var(--sans); font-size: 12px; color: var(--text);
}
.leaflet-control-layers-list { margin: 0; }
.leaflet-control-layers label {
  display: flex; align-items: center; gap: 8px;
  margin: 4px 0; color: var(--text); font-size: 12px; cursor: pointer;
}
.leaflet-control-layers label span { display: inline-flex; align-items: center; gap: 8px; }
.leaflet-control-layers-base label:hover { color: var(--accent); }
.leaflet-control-layers-selector { margin: 0; accent-color: var(--accent); }
.leaflet-control-layers-separator { border-top: 1px solid var(--line); }

/* offline grid fallback tint */
.orbita-grid { background: var(--bg-1); }

/* sector polygon labels */
.sector-label {
  background: transparent; border: 0; box-shadow: none;
  color: var(--text); font-family: var(--mono);
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  text-shadow: 0 1px 5px #000, 0 0 3px #000;
  padding: 0; white-space: nowrap;
}
.sector-label::before { display: none; }

/* ---- Map overlays (HUD) ------------------------------------------------- */
.hud {
  position: absolute; z-index: 600;
  pointer-events: none;
  font-family: var(--mono);
}
/* Bottom-left floating cluster, ABOVE the temporal replay bar (bottom: var(--gap),
   ~38px tall): the cursor/MGRS readout + the relocated MIND ask, side by side.
   Positioning lives here (not on .hud-coords) so both children align on one row. */
.map-hud-row {
  position: absolute; z-index: 630;
  /* Left edge aligns with the temporal replay bar (same left as .temporal-bar). */
  left: calc(var(--ab-w) + var(--rail-w) + var(--gap) * 2);
  bottom: calc(var(--gap) * 2 + 44px);
  display: flex; align-items: center; gap: 8px;
  max-width: calc(100% - var(--ab-w) - var(--rail-w) - var(--gap) * 4);
  font-family: var(--mono);
  pointer-events: none;  /* readout is display-only; the MIND pill re-enables below */
}
.app.nav-collapsed .map-hud-row {
  left: calc(var(--ab-w) + var(--gap) * 2);
  max-width: calc(100% - var(--ab-w) - var(--gap) * 4);
}
.hud-coords {
  /* Box only — positioning handled by the parent .map-hud-row. */
  flex: 0 0 auto;
  background: var(--glass-strong);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-sm);
  padding: 8px 12px;
  font-size: 11px; color: var(--muted);
  letter-spacing: 0.04em;
  display: inline-flex; align-items: center; gap: 5px;
  white-space: nowrap;
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
  box-shadow: var(--shadow-soft);
}
/* The MIND ask, floating over the map beside the readout (was a header cluster). */
.map-hud-row .sb-mind {
  pointer-events: auto;
  flex: 0 1 300px; max-width: 320px; min-width: 0;
  padding: 5px 8px;
  border: 1px solid var(--glass-edge);
  background: var(--glass-strong);
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
  box-shadow: var(--shadow-soft);
}
.hud-coords .v { color: var(--accent); font-variant-numeric: tabular-nums; }
.hud-coords .lbl {
  font-family: var(--cond); font-weight: 600; font-size: 10px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint); margin-right: 3px;
}
.hud-coords .sep { color: var(--faint); }

/* PAL-L-12 + PAL-L-38: temporal replay slider + AAR playback transport. */
.temporal-bar {
  position: absolute;
  left: calc(var(--ab-w) + var(--rail-w) + var(--gap) * 2);
  right: var(--gap);
  bottom: var(--gap);
  z-index: 620;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--r-sm);
  background: var(--glass-strong);
  border: 1px solid var(--glass-edge);
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
  box-shadow: var(--shadow-soft);
  pointer-events: auto;
}
.app.nav-collapsed .temporal-bar {
  left: calc(var(--ab-w) + var(--gap) * 2);
}
.temporal-transport {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.temporal-transport-btn,
.temporal-live-btn {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 5px 8px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex: 0 0 auto;
  line-height: 1;
}
.temporal-transport-btn:hover,
.temporal-live-btn:hover { color: var(--text); background: rgba(255,255,255,0.04); }
.temporal-transport-btn.active,
.temporal-live-btn.active {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent-line);
  box-shadow: 0 0 0 1px var(--accent-line);
}
.temporal-speed {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  padding: 4px 6px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: rgba(0,0,0,0.25);
  color: var(--muted);
  cursor: pointer;
  flex: 0 0 auto;
}
.temporal-speed:hover { color: var(--text); border-color: var(--line-3); }
.temporal-timeline {
  position: relative;
  flex: 1 1 auto;
  min-width: 140px;
  display: flex;
  align-items: flex-end;
  padding-top: 14px;
}
.temporal-ticks {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 10px;
  pointer-events: none;
}
.temporal-tick {
  position: absolute;
  top: 2px;
  width: 2px;
  height: 6px;
  margin-left: -1px;
  border-radius: 1px;
  opacity: 0.45;
  transition: opacity 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;
}
.temporal-tick-alert { background: var(--high); }
.temporal-tick-detection { background: #2dd4ff; }
.temporal-tick.passed { opacity: 0.85; }
.temporal-tick.active {
  opacity: 1;
  transform: scaleY(1.35);
  box-shadow: 0 0 6px currentColor;
}
.temporal-playhead {
  position: absolute;
  top: 0;
  bottom: 4px;
  width: 2px;
  margin-left: -1px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  pointer-events: none;
  z-index: 2;
  transition: left 0.05s linear;
}
.temporal-slider {
  position: relative;
  z-index: 1;
  width: 100%;
  min-width: 120px;
  height: 4px;
  accent-color: var(--accent);
  cursor: pointer;
}
.temporal-label {
  flex: 0 0 auto;
  min-width: 7.5em;
  font-size: 10px;
  letter-spacing: 0.06em;
  color: var(--accent);
  text-align: right;
}
.app.temporal-active .temporal-live-btn:not(.active) {
  color: var(--high);
  border-color: rgba(255, 201, 67, 0.45);
}
.app.temporal-playing .temporal-timeline {
  border-color: rgba(45, 212, 191, 0.25);
}
/* Empty/unavailable replay hint — reads an empty replay as *empty*, not broken.
   Centered over the timeline, never intercepts pointer events on the slider. */
.temporal-empty-hint {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--glass-strong);
  border: 1px solid var(--glass-edge);
  border-radius: 4px;
  padding: 3px 8px;
  pointer-events: none;
  z-index: 3;
}
.temporal-empty-hint[hidden] { display: none; }

.hud-legend {
  right: var(--gap); bottom: 72px;
  background: var(--glass-strong);
  border: 1px solid var(--glass-edge);
  border-radius: var(--r-sm);
  padding: 11px 13px;
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
  box-shadow: var(--shadow-soft);
}
.hud-legend .lh {
  font-family: var(--cond); font-weight: 600;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.hud-legend .legend-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px;
}
.hud-legend .row {
  display: flex; align-items: center; gap: 7px;
  font-size: 10px; color: var(--muted); margin-top: 0;
}
.hud-legend .sw {
  width: 9px; height: 9px; border-radius: 2px; transform: rotate(45deg);
}
.hud-legend .sw.c { background: var(--crit); }
.hud-legend .sw.h { background: var(--high); }
.hud-legend .sw.m { background: var(--med); }
.hud-legend .sw.l { background: var(--low); }

/* UI-DRONE-HUD: read-only flight-info MFD for the active own-asset drone.
   Top-level .app overlay (z-720 like #mind-query-panel), bottom-right, sitting
   above the map legend (legend is right/bottom:72px, ~140px tall). 2D-map only. */
.drone-flight-hud {
  position: absolute; right: var(--gap); bottom: 236px; left: auto; z-index: 720;
  width: min(258px, calc(100vw - 24px));
  padding: 9px 11px 10px;
  background: var(--glass-strong);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: 0 10px 28px rgba(0,0,0,0.38);
  backdrop-filter: var(--glass-blur-lite);
  -webkit-backdrop-filter: var(--glass-blur-lite);
}
.drone-flight-hud[hidden] { display: none !important; }
.dfh-head {
  display: flex; align-items: center; gap: 7px;
  padding-bottom: 7px; margin-bottom: 7px;
  border-bottom: 1px solid var(--line);
}
.dfh-eyebrow {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--accent);
  border: 1px solid var(--accent-line); border-radius: 2px; padding: 2px 5px;
}
.dfh-asset { font-size: 12px; font-weight: 600; color: var(--text); }
.dfh-status { margin-left: auto; }
.dfh-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px;
}
.dfh-cell { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.dfh-k {
  font-family: var(--cond); font-weight: 600;
  font-size: 8.5px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--faint);
}
.dfh-v {
  font-size: 11.5px; color: var(--text); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dfh-tgt {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px;
  margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--line);
  font-size: 10.5px; color: var(--muted);
}
.dfh-tgt .dfh-v { font-size: 10.5px; }
.dfh-mgrs { color: var(--accent); }

/* cursor MGRS readout (appended to hud-coords) */
.hud-coords .mgrs { color: var(--accent); letter-spacing: 0.02em; }
.hud-coords .mgrs-sep { margin: 0 2px; }

/* =============================================================================
   TACTICAL TOOLS (GAP-MAP-01) — palette, flyout, measure/ring/AOI/MGRS, layers
   ========================================================================== */
/* The whole control is a Leaflet control in the top-right corner; it stacks below
   the zoom + basemap controls automatically. The flyout opens to the LEFT of the
   button strip so it grows toward the map center, never off-screen. */
.tac { display: flex; flex-direction: row; align-items: flex-start; gap: 8px; }

.tac-tools {
  display: flex; flex-direction: column; gap: 1px;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm); overflow: hidden;
  box-shadow: var(--shadow-soft);
}
.tac-btn {
  width: 44px; padding: 8px 0;
  background: transparent; color: var(--muted);
  border: 0; border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  cursor: pointer; text-align: center;
  transition: background 0.12s var(--ease), color 0.12s var(--ease);
}
.tac-tools .tac-btn:last-child { border-bottom: 0; }
.tac-btn:hover { background: rgba(255,255,255,0.06); color: var(--accent); }
.tac-btn.active {
  background: var(--accent-dim); color: var(--accent);
  box-shadow: inset 2px 0 0 var(--accent);
}

.tac-flyout {
  width: 244px; max-height: 62vh; overflow-y: auto;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  color: var(--text);
}
.tac-sec { padding: 11px 13px 13px; }
.tac-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 9px; padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.tac-title {
  font-family: var(--cond); font-weight: 600; font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--accent);
}
.tac-close {
  background: transparent; border: 0; color: var(--faint);
  font-size: 17px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.tac-close:hover { color: var(--text); }

.tac-ro {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin: 5px 0;
}
.tac-ro .k {
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint);
}
.tac-ro b { color: var(--accent); font-size: 12.5px; }

.tac-label {
  display: block; margin: 4px 0 5px;
  font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.tac-input {
  width: 100%; padding: 8px 9px;
  border-radius: var(--r-sm); border: 1px solid var(--line-2);
  background: rgba(4,7,11,0.6); color: var(--text);
  font-size: 12.5px;
  transition: border-color 0.12s var(--ease), box-shadow 0.12s var(--ease);
}
.tac-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim); }

.tac-actions { display: flex; gap: 7px; margin-top: 11px; }
.tac-modes { display: flex; gap: 7px; margin-bottom: 9px; }
.tac-modes .btn.active,
.tac-aoi-row .btn.active {
  border-color: var(--accent-line); background: var(--accent-dim); color: var(--accent);
}
.tac-hint {
  margin: 10px 0 0; color: var(--faint);
  font-family: var(--mono); font-size: 10.5px; line-height: 1.45; letter-spacing: 0.01em;
}

.tac-list { list-style: none; margin: 9px 0 0; padding: 0; }
.tac-empty { color: var(--faint); font-size: 11.5px; padding: 4px 0; }
.tac-aoi-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; border-bottom: 1px solid var(--line);
  font-size: 12px; cursor: pointer;
}
.tac-aoi-row:last-child { border-bottom: 0; }
.tac-aoi-row .k { color: var(--accent); font-size: 13px; width: 14px; text-align: center; }
.tac-aoi-row .grow { flex: 1; font-family: var(--mono); letter-spacing: 0.02em; }

/* layer manager */
.tac-layers { list-style: none; margin: 0; padding: 0; }
.tac-layer-row {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 0; font-size: 12.5px; color: var(--text);
}
.tac-layer-row input { accent-color: var(--accent); width: 14px; height: 14px; cursor: pointer; }
.tac-layer-row label { cursor: pointer; }
.tac-layer-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tac-layer-attrib {
  font-size: 10px; line-height: 1.35; color: var(--faint);
  font-family: var(--mono); letter-spacing: 0.02em;
}

/* PAL-L-14: per-org WMS/WMTS tile layers in the layer manager */
.tac-tile-layers-head {
  margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted);
}
.tac-tile-layers { margin-top: 4px; }
.tac-tile-row { align-items: flex-start; }
.tac-tile-empty {
  padding: 6px 0 2px; font-size: 11.5px; color: var(--faint); list-style: none;
}
.tac-tile-form {
  margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line);
}
.tac-tile-form-title {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 8px;
}
.tac-tile-form .tac-label { margin-top: 8px; }
.tac-tile-form .tac-input { width: 100%; margin-top: 4px; }
.tac-tile-form .tac-actions { margin-top: 10px; }

/* SAR scene display control (WS-SAR-CONTRAST-01) */
.tac-sar-ctl {
  margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--line);
}
.tac-sar-ctl-title {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 8px;
}
.tac-sar-row { margin: 7px 0; }
.tac-sar-row-head { display: flex; align-items: baseline; justify-content: space-between; }
.tac-sar-lbl {
  font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--faint);
}
.tac-sar-val { font-family: var(--mono); font-size: 11px; color: var(--accent); }
.tac-sar-range { width: 100%; margin: 4px 0 0; accent-color: var(--accent); cursor: pointer; }
.tac-sar-toggle {
  display: flex; align-items: center; gap: 9px;
  margin: 9px 0 0; font-size: 12.5px; color: var(--text);
}
.tac-sar-toggle input { accent-color: var(--accent); width: 14px; height: 14px; cursor: pointer; }
.tac-sar-toggle label { cursor: pointer; }
.tac-sar-actions { margin-top: 10px; }

/* map-tool divIcon labels */
.meas-seg {
  font-family: var(--mono); font-size: 10px; line-height: 1.2;
  color: var(--accent); white-space: nowrap; text-align: center;
  text-shadow: 0 1px 4px #000, 0 0 3px #000;
}
.meas-seg .cum { display: block; color: var(--muted); font-size: 9px; }
.ring-label, .mgrs-label {
  font-family: var(--mono); white-space: nowrap; text-align: center;
  color: var(--accent); text-shadow: 0 1px 4px #000, 0 0 3px #000;
}
.ring-label { font-size: 10px; }
.mgrs-label.gzd { font-size: 11px; letter-spacing: 0.06em; color: var(--accent); opacity: 0.92; }
.mgrs-label.sq { font-size: 9.5px; color: var(--muted); opacity: 0.85; }

/* crosshair cursor while a draw/measure tool is armed */
.tac-armed.leaflet-container,
.tac-armed .leaflet-grab { cursor: crosshair; }

/* ---- Alert markers (divIcon) — UNKNOWN contacts ------------------------ */
.alert-marker {
  position: relative;
  width: 16px; height: 16px;
}
.alert-marker .core {
  position: absolute; inset: 3px;
  border-radius: 50%;
  border: 1.5px solid rgba(0,0,0,0.85);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.5), 0 1px 3px rgba(0,0,0,0.6);
}
.alert-marker .ring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 1.5px solid currentColor; opacity: 0;
}
.alert-marker.m-CRITICAL { color: var(--crit); }
.alert-marker.m-HIGH { color: var(--high); }
.alert-marker.m-MEDIUM { color: var(--med); }
.alert-marker.m-LOW { color: var(--low); }
.alert-marker .core { background: currentColor; }
.alert-marker:hover .core { box-shadow: 0 0 0 2px rgba(255,255,255,0.5), 0 0 10px currentColor; }
/* CRITICAL always pulses; new alerts pulse briefly */
.alert-marker.m-CRITICAL .ring { animation: pulsering 1.8s var(--ease) infinite; }
.alert-marker.is-new .ring { animation: pulsering 1.1s var(--ease) 3; }
@keyframes pulsering {
  0% { transform: scale(0.7); opacity: 0.9; }
  100% { transform: scale(2.7); opacity: 0; }
}

/* cluster marker — intentional ring + tally, not a red blob */
.cluster-marker {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  color: var(--text);
  background: radial-gradient(circle at 50% 50%, rgba(10,16,23,0.95), rgba(6,10,15,0.9));
  border: 1.5px solid currentColor;
  box-shadow: 0 0 0 4px rgba(8,12,18,0.5), 0 4px 14px rgba(0,0,0,0.6);
  transition: transform 0.12s var(--ease);
}
.cluster-marker:hover { transform: scale(1.08); }
.cluster-marker.m-CRITICAL { color: var(--crit); }
.cluster-marker.m-HIGH { color: var(--high); }
.cluster-marker.m-MEDIUM { color: var(--med); }
.cluster-marker.m-LOW { color: var(--low); }

/* ---- Dispatch reticle (signature element) ------------------------------ */
.reticle {
  width: 46px; height: 46px; position: relative; color: var(--accent);
}
.reticle .rring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 1.5px solid currentColor; opacity: 0.85;
}
.reticle .rring.r2 {
  inset: 12px; opacity: 0.5;
  animation: retpulse 2.4s var(--ease) infinite;
}
.reticle .cross-h, .reticle .cross-v {
  position: absolute; background: currentColor;
}
.reticle .cross-h { left: 50%; top: 0; width: 1.5px; height: 100%; transform: translateX(-50%); opacity: 0.8; }
.reticle .cross-v { top: 50%; left: 0; height: 1.5px; width: 100%; transform: translateY(-50%); opacity: 0.8; }
.reticle .dot {
  position: absolute; inset: 21px; border-radius: 50%; background: currentColor;
  box-shadow: 0 0 10px var(--accent-glow);
}
@keyframes retpulse {
  0% { transform: scale(0.85); opacity: 0.6; }
  70% { transform: scale(1.25); opacity: 0; }
  100% { opacity: 0; }
}

/* ---- Leaflet popups (matte carbon) -------------------------------------- */
.leaflet-popup-content-wrapper {
  background: var(--surface-1); color: var(--text);
  border: 1px solid var(--line-2); border-radius: var(--r-md);
  box-shadow: var(--shadow);
}
.leaflet-popup-tip { background: var(--surface-1); border: 1px solid var(--line-2); }
.leaflet-popup-content { margin: 13px 15px; font-family: var(--sans); }
.leaflet-popup-close-button { color: var(--muted) !important; }
.popup-h {
  display: flex; align-items: center; gap: 8px; margin-bottom: 7px;
  font-weight: 600;
}
.popup-kv {
  font-family: var(--mono); font-size: 11.5px; color: var(--muted);
  line-height: 1.7;
}
.popup-kv b { color: var(--text); font-weight: 500; }
.popup-actions { margin-top: 11px; display: flex; flex-wrap: wrap; gap: 8px; }
.popup-btn {
  background: var(--accent);
  color: var(--accent-ink); border: 0;
  border-radius: 3px; padding: 8px 12px; cursor: pointer;
  font-family: var(--cond); font-weight: 600; font-size: 11px;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.popup-btn:hover { filter: brightness(1.07); }
.popup-btn.ghost {
  background: transparent; color: var(--accent);
  border: 1px solid var(--accent-line); box-shadow: none;
}
.popup-btn.ghost:hover { background: var(--accent-dim); filter: none; }

/* =============================================================================
   PHASE 2 — DARK VESSEL (WS-2) + DRONE CROSS-CUE (WS-1)
   ========================================================================== */

/* ---- Dark-vessel badge + AIS evidence ---------------------------------- */
.dark-badge {
  display: inline-flex; align-items: center;
  font-family: var(--mono); font-size: 9px; font-weight: 700;
  letter-spacing: 0.12em;
  color: #1a0b00;
  background: linear-gradient(180deg, var(--high), #e8721f);
  border-radius: 4px; padding: 2px 6px; margin-left: 7px;
  box-shadow: 0 0 10px rgba(255,145,66,0.5);
}
/* Asset-watch trip badge (WS-INFRA-01) — distinct teal from the amber DARK badge. */
.asset-badge {
  display: inline-flex; align-items: center;
  font-family: var(--mono); font-size: 9px; font-weight: 700;
  letter-spacing: 0.12em;
  color: #04201d;
  background: linear-gradient(180deg, #2fd6c3, #16a89a);
  border-radius: 4px; padding: 2px 6px; margin-left: 7px;
  box-shadow: 0 0 10px rgba(47,214,195,0.45);
  flex: 0 0 auto;
}
.alert-title { display: flex; align-items: center; gap: 0; min-width: 0; }
.alert-title > span:first-child {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.alert-title .dark-badge { flex: 0 0 auto; }
.alert-row.is-dark { background: linear-gradient(90deg, rgba(255,145,66,0.07), transparent 46%); }
.alert-row.is-dark .sev-bar {
  background: repeating-linear-gradient(
    45deg, var(--high) 0 4px, var(--crit) 4px 8px) !important;
  box-shadow: 0 0 10px rgba(255,145,66,0.5) !important;
}
.ais-chip {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.04em;
  color: var(--high); margin-left: 6px;
}
.ais-block {
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line);
}
.ais-title {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--high);
}

/* dark-only filter toggle */
.dark-toggle {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 11px; border-bottom: 1px solid var(--line);
  background: rgba(0,0,0,0.16); cursor: pointer;
  font-size: 11.5px; color: var(--muted);
  transition: color 0.12s var(--ease);
}
.dark-toggle:hover { color: var(--text); }
.dark-toggle input { accent-color: var(--high); cursor: pointer; }
.panel-tools .dark-toggle-inline {
  flex: 0 0 auto; margin-left: auto;
  padding: 4px 8px; border: 1px solid var(--line); border-radius: var(--r-sm);
  border-bottom: 1px solid var(--line); background: rgba(0,0,0,0.22);
  font-size: 10.5px; gap: 5px;
}
.panel-tools .dark-toggle-inline .dark-toggle-lbl { color: var(--faint); }

/* dark-vessel map marker: a diamond so it reads differently from the round
   contact dot at a glance. Severity color kept (floored HIGH). */
.alert-marker.dv { transform: rotate(45deg); }
.alert-marker.dv .core { border-radius: 2px; }
.alert-marker.dv .ring {
  border-radius: 2px;
  border-color: var(--high);
  animation: pulsering 1.8s var(--ease) infinite;
  opacity: 0.9;
}
.alert-marker.dv:hover .core { box-shadow: 0 0 0 2px rgba(255,255,255,0.5), 0 0 12px var(--high); }

/* ---- Drone taskings panel ---------------------------------------------- */
.tasking-row { gap: 9px; }
.tasking-row .confirm-btn {
  flex: 0 0 auto; border-color: var(--accent-line); color: var(--accent);
}
.tasking-row .confirm-btn.armed {
  background: linear-gradient(180deg, rgba(255,65,77,0.18), rgba(255,65,77,0.1));
  border-color: var(--crit); color: #ffd9dc;
  animation: armPulse 1.3s var(--ease) infinite;
}

/* mission-status chip — one band per lifecycle state (state-machine viz) */
.mstatus {
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: 0.08em; white-space: nowrap; flex: 0 0 auto;
  padding: 3px 8px; border-radius: 6px;
  border: 1px solid var(--line-2); color: var(--muted); background: rgba(255,255,255,0.03);
}
.mstatus.m-recorded  { color: var(--faint); }
.mstatus.m-requested { color: var(--med); border-color: rgba(255,201,67,0.42);
  background: rgba(255,201,67,0.07); }
.mstatus.m-accepted  { color: var(--accent); border-color: var(--accent-line); }
.mstatus.m-enroute   { color: var(--accent); border-color: var(--accent-line); background: var(--accent-dim); }
.mstatus.m-on_station { color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
  box-shadow: 0 0 10px rgba(52,224,207,0.4); }
.mstatus.m-returned  { color: var(--ok); border-color: rgba(52,216,160,0.42); }
.mstatus.m-failed    { color: var(--bad); border-color: rgba(255,93,108,0.48);
  background: rgba(255,93,108,0.07); }
.mstatus.m-cancelled { color: var(--faint); }

/* ---- Asset roster panel (WS-6c) ---------------------------------------- */
/* Unified Lattice-style list of own assets: a type tag, name, status badge and a
   quick action per row. Reuses the shared .list / .btn / .mstatus vocabulary. */
.asset-row { gap: 9px; padding-left: 13px; }

/* type tag — DRONE (teal/own-asset) vs FEED (neutral) */
.atype {
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: 0.09em; flex: 0 0 auto;
  padding: 2px 6px; border-radius: 5px;
  border: 1px solid var(--line-2); color: var(--muted); background: rgba(255,255,255,0.03);
}
.atype.a-drone { color: var(--accent); border-color: var(--accent-line); background: var(--accent-dim); }

/* feed status badge — mirrors the sev-tag / fmv-pill language */
.astatus {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 9px; font-weight: 600;
  letter-spacing: 0.08em; white-space: nowrap; flex: 0 0 auto;
  padding: 3px 8px; border-radius: 6px;
  border: 1px solid var(--line-2); color: var(--muted); background: rgba(255,255,255,0.03);
}
.astatus .g { width: 6px; height: 6px; border-radius: 999px; background: var(--faint); }
.astatus.a-live { color: var(--ok); border-color: rgba(52,216,160,0.42); background: rgba(52,216,160,0.07); }
.astatus.a-live .g { background: var(--ok); box-shadow: 0 0 8px rgba(52,216,160,0.7); }
.astatus.a-nosignal { color: var(--faint); }

.asset-row .asset-act { flex: 0 0 auto; }
.asset-row .asset-act:disabled { opacity: 0.4; cursor: not-allowed; }

/* ---- Friendly own-asset (drone) marker — the one known affiliation ------ */
.drone-marker {
  position: relative; width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
}
.drone-marker .dchassis {
  font-size: 15px; line-height: 1; color: var(--accent);
  text-shadow: 0 0 7px var(--accent-glow), 0 1px 2px #000;
}
.drone-marker .dring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 1.5px dashed var(--accent-line); opacity: 0.8;
}
.drone-marker.live .dring { animation: retpulse 2.4s var(--ease) infinite; }
.drone-marker.commanded .dring {
  border-style: solid; border-color: #fff;
  animation: commandedRing 0.9s var(--ease) 2;
}
@keyframes commandedRing {
  0% { transform: scale(0.6); opacity: 1; }
  100% { transform: scale(1.45); opacity: 0; }
}
.drone-marker:hover .dchassis { filter: brightness(1.2); }
.tasking-row.highlight {
  outline: 1px solid var(--accent-line);
  background: rgba(52, 224, 207, 0.08);
  border-radius: var(--r-sm);
}

/* ---- Analyst validation queue (PAL-L-21) -------------------------------- */
.validation-card {
  align-items: flex-start !important;
  padding: 12px !important;
  gap: 11px !important;
  flex-wrap: wrap;
}
.validation-card.highlight {
  outline: 1px solid var(--accent-line);
  background: rgba(52, 224, 207, 0.08);
  border-radius: var(--r-sm);
}
.val-chip {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
}
.val-chip-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.val-chip-placeholder {
  color: #8aa0b8;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: rgba(90, 168, 255, 0.08);
}
.validation-card-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
}
.validation-card-title .name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.val-type-badge {
  font-family: var(--mono);
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 2px 6px;
  border-radius: 4px;
  color: #9ec8ff;
  background: rgba(90, 168, 255, 0.12);
  border: 1px solid rgba(90, 168, 255, 0.28);
}
.validation-card .meta {
  margin-top: 3px;
  font-size: 11px;
  color: var(--muted);
}
.validation-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  flex: 1 1 100%;
  justify-content: flex-end;
}
.val-confirm-btn {
  border-color: var(--accent-line);
  color: var(--accent);
}
.val-confirm-btn.armed,
.val-reject-btn.armed,
.val-merge-btn.armed {
  background: linear-gradient(180deg, rgba(255, 65, 77, 0.18), rgba(255, 65, 77, 0.1));
  border-color: var(--crit);
  color: #ffd9dc;
  animation: armPulse 1.3s var(--ease) infinite;
}
.val-merge-select {
  margin-top: 8px;
  width: 100%;
}
.validation-map-pin {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #ffc943;
  border: 2px solid #fff;
  box-shadow: 0 0 0 2px rgba(255, 201, 67, 0.45);
}
.alert-row.highlight {
  outline: 1px solid var(--accent-line);
  background: rgba(52, 224, 207, 0.08);
  border-radius: var(--r-sm);
}

/* Infrastructure sensor point marker (tower/camera at AOI centroid) */
.infra-tower {
  position: relative; width: 22px; height: 26px;
  display: flex; align-items: flex-end; justify-content: center;
  color: #2fd6c3; filter: drop-shadow(0 1px 3px rgba(0,0,0,0.75));
}
.infra-tower.off { color: rgba(47,214,195,0.45); }
.infra-tower .tower-svg {
  width: 22px; height: 26px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.infra-tower .tower-svg .fill { fill: currentColor; stroke: none; }

/* ---- Infrastructure panel (WS-INFRA-01) -------------------------------- */
.panel-body-infra { padding-bottom: 4px; }
#infra-kpis .dock-kpi .v { color: #2fd6c3; }

.infra-card { align-items: flex-start !important; padding: 12px !important; gap: 11px !important; }
.infra-card.off { opacity: 0.58; }
.infra-card-ico {
  flex: 0 0 auto; width: 34px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm); color: #2fd6c3;
  background: rgba(47,214,195,0.1); border: 1px solid rgba(47,214,195,0.25);
}
.infra-card-ico svg { width: 20px; height: 24px; }
.infra-card-title {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  font-weight: 600; font-size: 13px; color: var(--text);
}
.infra-card-title .name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.infra-status {
  font-family: var(--mono); font-size: 8.5px; font-weight: 700; letter-spacing: 0.1em;
  padding: 2px 6px; border-radius: 4px;
  color: #2fd6c3; background: rgba(47,214,195,0.12); border: 1px solid rgba(47,214,195,0.3);
}
.infra-status.off {
  color: var(--faint); background: rgba(255,255,255,0.04); border-color: var(--line);
}
.infra-card .meta { margin-top: 3px; font-size: 11px; color: var(--muted); }
.infra-card .btn { flex: 0 0 auto; align-self: center; }

.infra-hit {
  align-items: center !important; padding: 11px 12px !important;
}
.infra-hit .infra-hit-badge {
  font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: 0.08em;
  padding: 3px 7px; border-radius: 4px; flex: 0 0 auto;
  color: var(--text); background: rgba(255,255,255,0.06); border: 1px solid var(--line);
}
.infra-hit.s-CRITICAL .infra-hit-badge { color: var(--crit); border-color: rgba(255,65,77,0.45); }
.infra-hit.s-HIGH .infra-hit-badge { color: var(--high); border-color: rgba(255,145,66,0.4); }
.infra-hit.s-MEDIUM .infra-hit-badge { color: var(--med); border-color: rgba(255,201,67,0.4); }
.infra-hit.s-LOW .infra-hit-badge { color: var(--low); border-color: rgba(90,168,255,0.4); }
.infra-hit .title { font-size: 12.5px; }

.own-badge {
  font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--accent-ink); background: var(--accent);
  border-radius: 4px; padding: 2px 7px;
}

/* legend swatches for the new contact types */
.hud-legend .sw.dv { background: var(--high); border-radius: 1px; }
.hud-legend .sw.own { background: var(--accent); border-radius: 50%; transform: none; }
.hud-legend .sw.trail {
  background: linear-gradient(90deg, transparent, var(--accent));
  height: 3px; border-radius: 2px; transform: translateY(4px);
}
.hud-legend .sw.goto {
  background: repeating-linear-gradient(90deg, var(--accent) 0 4px, transparent 4px 8px);
  height: 3px; transform: translateY(4px);
}
.hud-legend .sw.ent {
  background: transparent; border: 1.5px solid #9b7bff; border-radius: 50%; transform: none;
}
.hud-legend .sw.gf {
  background: transparent; border: 1.5px dashed #ff414d; transform: rotate(0);
}
.hud-legend .sw.mil {
  background: #ffc943; border-radius: 50%; transform: none;
  box-shadow: 0 0 0 2px rgba(255,201,67,0.25);
}
.hud-legend .sw.aw {
  background: rgba(47,214,195,0.2); border: 1.5px solid #2fd6c3; transform: rotate(0);
}
.hud-legend .sw.twr {
  background: var(--accent); border-radius: 1px; transform: none;
  clip-path: polygon(50% 0, 68% 38%, 68% 100%, 32% 100%, 32% 38%);
}
.hud-legend .sw.wt {
  background: transparent; border: 1.5px solid #7eb8ff; border-radius: 2px; transform: none;
  box-shadow: inset 0 -3px 0 #7eb8ff;
}
.hud-legend .sw.hz {
  background: transparent; border: 1.5px solid #f28c28; border-radius: 999px; transform: none;
  box-shadow: 0 0 5px rgba(242,140,40,0.55);
}

/* ---- Authoritative hazard feeds (WS-DISASTER-2) ------------------------- */
/* Round hazard glyph markers, colour-coded by severity (border + glyph colour set
   inline from a fixed app-controlled ramp; no feed data reaches the DOM as HTML). */
.hazard-marker {
  width: 22px; height: 22px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid #3aa0ff; background: rgba(8,12,18,0.82);
  filter: drop-shadow(0 1px 3px rgba(0,0,0,0.75));
}
.hazard-marker.sev-extreme { box-shadow: 0 0 8px rgba(229,72,77,0.65); }
.hazard-marker.sev-high { box-shadow: 0 0 7px rgba(242,140,40,0.5); }
.hazard-marker .hazard-glyph { font-size: 12px; line-height: 1; }

.hazard-popup { min-width: 190px; }
.hazard-popup .popup-h { display: flex; align-items: center; gap: 7px; }
.hazard-popup-glyph { font-size: 14px; }
.hazard-popup-title { font-weight: 600; color: var(--text); }
.hazard-popup-kv { margin-top: 6px; display: flex; flex-direction: column; gap: 3px; }
.hazard-kv-row { display: flex; align-items: center; gap: 8px; }
.hazard-kv-row .k {
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint); min-width: 68px;
}
.hazard-kv-row .v { color: var(--text); font-size: 12px; }
.hazard-sev-badge {
  font-family: var(--mono); font-size: 8px; font-weight: 700; letter-spacing: 0.1em;
  padding: 2px 6px; border-radius: 4px; color: #0a0e14; text-transform: uppercase;
}
.hazard-popup-link {
  display: inline-block; margin-top: 7px; font-size: 11px; color: var(--accent);
  text-decoration: none;
}
.hazard-popup-link:hover { text-decoration: underline; }
.hazard-attribution {
  margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--line-2);
  font-size: 9px; color: var(--faint); line-height: 1.35;
}

/* ---- Virtual watch towers (WS3-8b) ------------------------------------- */
.watchtower-marker {
  position: relative; width: 24px; height: 28px;
  display: flex; align-items: flex-end; justify-content: center;
  color: #7eb8ff; filter: drop-shadow(0 1px 3px rgba(0,0,0,0.75));
}
.watchtower-marker.stale { color: #ffc943; }
.watchtower-marker.unknown { color: rgba(126,184,255,0.55); }
.watchtower-marker .wt-cam-svg {
  width: 24px; height: 28px; fill: none; stroke: currentColor;
  stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round;
}
.watchtower-marker .wt-fresh-dot {
  position: absolute; right: 0; top: 2px; width: 6px; height: 6px; border-radius: 999px;
  background: var(--ok); box-shadow: 0 0 6px rgba(52,216,160,0.55);
}
.watchtower-marker.stale .wt-fresh-dot {
  background: var(--med); box-shadow: 0 0 6px rgba(255,201,67,0.45);
}
.watchtower-marker.unknown .wt-fresh-dot { background: var(--faint); box-shadow: none; }

.cam-fresh-badge {
  font-family: var(--mono); font-size: 8px; font-weight: 700; letter-spacing: 0.1em;
  padding: 2px 6px; border-radius: 4px; flex: 0 0 auto;
  border: 1px solid rgba(52,216,160,0.35); color: var(--ok); background: rgba(52,216,160,0.08);
}
.cam-fresh-badge.stale {
  border-color: rgba(255,201,67,0.45); color: var(--med); background: rgba(255,201,67,0.08);
}
.cam-fresh-badge.unknown {
  border-color: var(--line-2); color: var(--faint); background: rgba(255,255,255,0.03);
}

.panel-body-watchtowers { padding-bottom: 4px; }
#watchtower-kpis .dock-kpi .v { color: #7eb8ff; }
.dock-hint {
  margin: 0 0 8px; padding: 6px 9px; font-size: 11.5px; line-height: 1.35;
  color: #cfe0f5; background: rgba(126,184,255,0.08);
  border: 1px solid rgba(126,184,255,0.22); border-radius: 6px;
}
.watchtower-card { align-items: flex-start !important; padding: 12px !important; }
.watchtower-card.is-stale { background: rgba(255,201,67,0.04); }
.watchtower-card-title {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  font-weight: 600; font-size: 13px; color: var(--text);
}
.watchtower-card-title .name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}

.popup-nearby { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-2); }
.popup-nearby-title {
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px;
}
.popup-nearby-loading, .popup-nearby-empty, .popup-nearby-err {
  font-size: 11.5px; color: var(--muted); padding: 4px 0;
}
.popup-nearby-err { color: var(--bad); }
.popup-nearby-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.popup-nearby-row {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  border: 1px solid var(--line-2); border-radius: var(--r-sm); background: rgba(255,255,255,0.02);
}
.popup-nearby-row.is-stale { border-color: rgba(255,201,67,0.28); }
.popup-nearby-row .title { font-size: 12px; font-weight: 600; color: var(--text); }
.popup-nearby-row .meta { font-size: 10.5px; color: var(--muted); }

.camera-modal-card { width: min(860px, 94vw); }
.camera-viewer-body { padding: 0 16px 16px; display: flex; flex-direction: column; gap: 10px; }
.camera-tile {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: #05080d; border: 1px solid var(--line-2); border-radius: var(--r-md); overflow: hidden;
}
.camera-still, .camera-video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #05080d;
}
.camera-detect-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2;
  opacity: 0; transition: opacity 0.12s ease;
}
.camera-tile[data-state="still"] .camera-detect-canvas,
.camera-tile[data-state="live"] .camera-detect-canvas,
.camera-tile[data-state="hls"] .camera-detect-canvas { opacity: 1; }
.camera-detect-row { display: flex; align-items: center; gap: 8px; min-height: 18px; }
.camera-detect-status { font-size: 11px; color: var(--muted); font-family: var(--mono); }
.camera-nosignal {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; padding: 16px; text-align: center;
  background: rgba(5,8,13,0.92);
}
.camera-nosignal .ns-title {
  font-family: var(--mono); font-size: 12px; font-weight: 700; letter-spacing: 0.14em; color: var(--med);
}
.camera-nosignal .ns-sub { font-size: 11.5px; color: var(--muted); max-width: 36ch; }
.camera-meta { font-size: 11px; color: var(--muted); word-break: break-all; }
/* Source-mandated credit line (e.g. Windy attribution ToS) */
.camera-attribution { font-size: 11px; color: var(--muted); margin-top: 2px; }
.camera-attribution a { color: var(--muted); text-decoration: underline; }

/* ---- WS3-8-UI: inline sensor stage (watch-tower dock) ------------------- */
.sensor-stage {
  margin: 0 0 12px; border: 1px solid rgba(126, 184, 255, 0.28);
  border-radius: var(--r-md); background: var(--surface-2); overflow: hidden;
}
.sensor-stage-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px; border-bottom: 1px solid var(--line);
  background: rgba(126, 184, 255, 0.06);
}
.sensor-stage-head .eyebrow {
  font-family: var(--cond); font-size: 9px; letter-spacing: 0.14em;
  text-transform: uppercase; color: #7eb8ff; width: 100%;
}
.sensor-stage-head h4 {
  margin: 0; font-size: 13px; font-weight: 600; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sensor-tile-wrap { padding: 8px 10px 0; }
.sensor-tile-wrap .camera-tile { aspect-ratio: 16 / 10; }
.sensor-tile-wrap .camera-still {
  filter: saturate(0.85) brightness(0.72);
}
.sensor-actions {
  display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 10px;
  border-top: 1px solid var(--line);
}
.sensor-actions .btn.dispatch { background: var(--crit); color: #fff; border-color: var(--crit); }
.sensor-actions .btn.dispatch.armed {
  box-shadow: 0 0 0 2px rgba(255, 65, 77, 0.45);
  animation: sensorCotPulse 1.2s ease infinite;
}
@keyframes sensorCotPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.82; } }
.sensor-detections {
  padding: 0 10px 8px; display: flex; flex-direction: column; gap: 6px;
}
.sensor-det-row {
  display: flex; align-items: center; gap: 8px; padding: 7px 8px;
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  background: rgba(255,255,255,0.02); font-size: 11.5px;
}
.sensor-det-row.pending { border-left: 2px solid var(--med); }
.sensor-det-row .cls { font-weight: 600; color: var(--text); }
.sensor-det-row .conf { font-family: var(--mono); color: var(--muted); font-size: 10px; }
.sensor-det-row .grow { flex: 1; min-width: 0; }
.sensor-context {
  padding: 0 10px 10px; display: flex; flex-direction: column; gap: 8px;
}
.sensor-ctx-block {
  padding: 7px 9px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: rgba(0,0,0,0.2); font-size: 11px; line-height: 1.4;
}
.sensor-ctx-block .k {
  display: block; font-family: var(--cond); font-size: 9px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}
.sensor-ctx-block .v { color: var(--text); }
.sensor-ctx-block .v.mono { font-family: var(--mono); font-size: 10.5px; }
.sensor-ctx-block .mgrs { color: var(--accent); }
.sensor-nearby-list { list-style: none; margin: 4px 0 0; padding: 0; }
.sensor-nearby-list li {
  display: flex; justify-content: space-between; gap: 8px;
  padding: 3px 0; border-top: 1px solid var(--line); font-size: 10.5px;
}
.sensor-nearby-list li:first-child { border-top: none; padding-top: 0; }
.sensor-hazard-pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px; border-radius: 999px; font-size: 10px; font-family: var(--mono);
  border: 1px solid rgba(255, 145, 66, 0.45); color: var(--high);
  background: rgba(255, 145, 66, 0.1); margin-right: 6px; margin-bottom: 4px;
}
.watchtower-card.is-selected {
  outline: 1px solid rgba(126, 184, 255, 0.45);
  background: rgba(126, 184, 255, 0.06) !important;
}

/* =============================================================================
   PERSISTENT TRACKS + SYSTEM HEALTH (GAP-UI-01)
   ========================================================================== */

/* ---- Track marker — hollow teal hexagon (a durable entity, NOT a point alert,
   so it must read differently from the filled severity dots / own-asset triangle) */
.track-marker {
  position: relative; width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
}
.track-marker .thex {
  width: 24px; height: 24px; overflow: visible;
}
.track-marker .thex polygon {
  fill: rgba(8, 12, 18, 0.45);
  stroke: currentColor; stroke-width: 1.6px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.7));
}
.track-marker .tlabel {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 2px; font-size: 8.5px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--accent); white-space: nowrap;
  text-shadow: 0 1px 3px #000, 0 0 6px rgba(4,7,11,0.9);
  pointer-events: none;
}
.track-marker.t-active { color: var(--accent); }
.track-marker.t-active .thex polygon { stroke-width: 1.8px; }
.track-marker.t-active::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 1.5px solid var(--accent-line); opacity: 0;
  animation: pulsering 2.6s var(--ease) infinite;
}
.track-marker.t-stale { color: var(--faint); }
.track-marker.t-stale .thex polygon { stroke-dasharray: 3 3; opacity: 0.85; }
.track-marker.t-stale .tlabel { color: var(--faint); }
.track-marker:hover .thex polygon { stroke: #7af3e6; }

/* ---- PAL-L-36: linked 2D↔3D selection highlight (shared entity id emphasis) ----
   White ring + glow matches the globe marker selected outline (#fff). */
:root {
  --linked-selection: #ffffff;
  --linked-selection-glow: rgba(255, 255, 255, 0.82);
}
.track-marker.linked-selected,
.entity-marker.linked-selected,
.milsym-marker.linked-selected {
  filter: drop-shadow(0 0 8px var(--linked-selection-glow));
}
.track-marker.linked-selected .thex polygon,
.entity-marker.linked-selected .ediamond polygon,
.milsym-marker.linked-selected .ms-frame {
  stroke: var(--linked-selection);
  stroke-width: 2.5px;
  fill: rgba(255, 255, 255, 0.08);
}
.track-marker.linked-selected::before,
.entity-marker.linked-selected::before,
.milsym-marker.linked-selected::before {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 2px solid var(--linked-selection);
  box-shadow: 0 0 10px var(--linked-selection-glow);
  pointer-events: none;
  animation: linkedSelectionPulse 2.4s var(--ease) infinite;
}
@keyframes linkedSelectionPulse {
  0%, 100% { opacity: 0.95; }
  50% { opacity: 0.45; }
}

/* track popup badge — teal own-picture language, dimmed when stale */
.track-badge {
  font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: 0.12em;
  color: var(--accent-ink); background: var(--accent);
  border-radius: 4px; padding: 2px 7px;
}
.track-badge.stale { color: var(--bg-0); background: var(--faint); }

/* ---- Fused multi-sensor entity marker (WS3-4) ------------------------------
   A hollow amber DIAMOND, distinct from the teal track hexagon. A >=2-sensor
   ("fused") entity gets a small filled accent dot to flag the fusion. Active vs
   stale mirror the track status styling. Affiliation is always UNKNOWN. */
:root { --entity-amber: #f7c948; }
.entity-marker {
  position: relative; width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  color: var(--entity-amber);
}
.entity-marker .ediamond { width: 24px; height: 24px; overflow: visible; }
.entity-marker .ediamond polygon {
  fill: rgba(8, 12, 18, 0.45);
  stroke: currentColor; stroke-width: 1.6px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.7));
}
.entity-marker .tlabel {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 2px; font-size: 8.5px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--entity-amber); white-space: nowrap;
  text-shadow: 0 1px 3px #000, 0 0 6px rgba(4,7,11,0.9);
  pointer-events: none;
}
.entity-marker.e-active .ediamond polygon { stroke-width: 1.9px; }
.entity-marker.e-stale { color: var(--faint); }
.entity-marker.e-stale .ediamond polygon { stroke-dasharray: 3 3; opacity: 0.85; }
.entity-marker.e-stale .tlabel { color: var(--faint); }
.entity-marker.e-multi .ediamond::after { content: ""; }
.entity-marker.e-multi::after {
  content: ""; position: absolute; width: 5px; height: 5px; border-radius: 50%;
  background: var(--entity-amber); box-shadow: 0 0 4px var(--entity-amber);
}
.entity-marker:hover .ediamond polygon { stroke: #ffe08a; }

/* entity popup observation timeline (newest first) */
.entity-timeline { margin-top: 6px; border-top: 1px solid var(--accent-line); padding-top: 5px; }
.entity-timeline .etl-h {
  font-size: 9px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 3px;
}
.entity-timeline .etl-row {
  display: flex; gap: 6px; align-items: baseline; font-size: 10px; line-height: 1.5;
}
.entity-timeline .etl-sensor {
  font-family: var(--mono); font-weight: 700; color: var(--entity-amber);
  min-width: 46px;
}
.entity-timeline .etl-cls { flex: 1; color: var(--ink); }
.entity-timeline .etl-t { color: var(--faint); }
.entity-timeline .etl-loading,
.entity-timeline .etl-empty,
.entity-timeline .etl-err { font-size: 10px; color: var(--faint); }

/* ---- MIL-STD-2525 symbology (GAP-SYM-01) — opt-in tracks render mode -------
   SAFETY: affiliation is always UNKNOWN, so we only ever draw the 2525 UNKNOWN
   affiliation frame: the amber quatrefoil. The per-class inner glyph carries the
   function/dimension. dark_vessel gets a distinct "suspect" strobe + dashed accent
   since it is the high-value cue. Active/stale mirror the hexagon's status styling. */
:root { --milsym-amber: #f7c948; }
.milsym-marker {
  position: relative; width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  color: var(--milsym-amber);
}
.milsym-marker .ms-svg { width: 32px; height: 32px; overflow: visible; }
.milsym-marker .ms-frame {
  fill: rgba(247, 201, 72, 0.10);
  stroke: currentColor; stroke-width: 1.7px; stroke-linejoin: round;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.75));
}
.milsym-marker .ms-glyph {
  fill: none; stroke: currentColor; stroke-width: 1.6px;
  stroke-linejoin: round; stroke-linecap: round;
}
.milsym-marker .ms-hull { fill: rgba(247, 201, 72, 0.30); }
.milsym-marker .ms-q {
  fill: currentColor; stroke: none;
  font-family: var(--mono); font-size: 11px; font-weight: 700;
}
.milsym-marker .tlabel {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 2px; font-size: 8.5px; font-weight: 600; letter-spacing: 0.04em;
  color: var(--milsym-amber); white-space: nowrap;
  text-shadow: 0 1px 3px #000, 0 0 6px rgba(4,7,11,0.9);
  pointer-events: none;
}
/* Active: brighter, thicker frame + a pulse ring (own-picture liveness). */
.milsym-marker.ms-active .ms-frame { stroke-width: 2px; }
.milsym-marker.ms-active::after {
  content: ""; position: absolute; inset: -2px; border-radius: 50%;
  border: 1.5px solid rgba(247, 201, 72, 0.5); opacity: 0;
  animation: pulsering 2.6s var(--ease) infinite;
}
/* Stale: dimmed + dashed frame (mirrors the hexagon's stale treatment). */
.milsym-marker.ms-stale { opacity: 0.8; filter: saturate(0.7); }
.milsym-marker.ms-stale .ms-frame { stroke-dasharray: 3 3; }
.milsym-marker:hover .ms-frame { stroke: #ffe08a; }
/* dark_vessel — high-value SUSPECT cue: warmer amber-red, dashed suspect ring,
   filled hull, and a slow strobe so it stands out from a benign vessel. */
.milsym-marker.ms-dark { color: #ffae42; }
.milsym-marker.ms-dark .ms-frame {
  fill: rgba(255, 96, 64, 0.16); stroke-dasharray: 4 2.5;
}
.milsym-marker.ms-dark .ms-hull { fill: rgba(255, 96, 64, 0.45); }
.milsym-marker.ms-dark::before {
  content: ""; position: absolute; inset: -3px; border-radius: 8px;
  border: 1.4px dashed #ff6040; opacity: 0.0;
  animation: milsymStrobe 1.4s steps(1, end) infinite;
  pointer-events: none;
}
@keyframes milsymStrobe { 0%, 60% { opacity: 0.9; } 61%, 100% { opacity: 0.15; } }

/* legend swatch (optional) */
.hud-legend .sw.trk {
  background: transparent; border: 1.5px solid var(--accent); border-radius: 2px; transform: rotate(45deg);
}

/* ---- System health panel ----------------------------------------------- */
/* header status chip mirrors the .pill language (dot + label) */
.hstat {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 9px; font-weight: 600; letter-spacing: 0.08em;
  padding: 3px 8px; border-radius: 6px;
  border: 1px solid var(--line-2); color: var(--muted); background: rgba(255,255,255,0.03);
}
.hstat .dot { width: 7px; height: 7px; border-radius: 999px; background: var(--faint); }
.hstat.ok { color: var(--text); border-color: rgba(52,216,160,0.3); }
.hstat.ok .dot { background: var(--ok); box-shadow: 0 0 9px rgba(52,216,160,0.7); }
.hstat.bad { color: var(--text); border-color: rgba(255,93,108,0.42); }
.hstat.bad .dot { background: var(--bad); box-shadow: 0 0 9px rgba(255,93,108,0.7);
  animation: hbeat 1.1s steps(2, jump-none) infinite; }
.hstat .lbl { color: var(--muted); }

/* COP live-stream chip (GAP-UI-02): green + pulsing dot when the WebSocket is open,
   amber while reconnecting, dim when offline. Mirrors the .hstat / .fmv-pill language. */
.cop-chip.live { color: var(--text); border-color: rgba(52,216,160,0.45); background: rgba(52,216,160,0.07); }
.cop-chip.live .dot { background: var(--ok); box-shadow: 0 0 9px rgba(52,216,160,0.8);
  animation: fmvPulse 1.6s ease infinite; }
.cop-chip.wait { color: var(--text); border-color: rgba(255,201,67,0.42); }
.cop-chip.wait .dot { background: var(--med); animation: hbeat 1.1s steps(2, jump-none) infinite; }
.cop-chip.off { color: var(--faint); }
.cop-chip.off .dot { background: var(--faint); }

/* Shared COP co-presence (PAL-L-13): peer selection ring + viewport rectangle + label.
   Purple accent distinguishes collaborator focus from own-picture teal track markers. */
.peer-presence-highlight {
  box-shadow: 0 0 0 2px rgba(199, 125, 255, 0.55), 0 0 14px rgba(199, 125, 255, 0.35);
  border-radius: 50%;
}
.track-marker.peer-presence-highlight,
.entity-marker.peer-presence-highlight,
.milsym-marker.peer-presence-highlight {
  color: #e0aaff;
}
.track-marker.peer-presence-highlight .thex polygon,
.entity-marker.peer-presence-highlight .ediamond polygon {
  stroke: #e0aaff;
  stroke-width: 2px;
  filter: drop-shadow(0 0 6px rgba(199, 125, 255, 0.65));
}
.track-marker.peer-presence-highlight::after,
.entity-marker.peer-presence-highlight::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1.5px solid rgba(199, 125, 255, 0.75);
  animation: peerPresencePulse 2.2s var(--ease) infinite;
  pointer-events: none;
}
@keyframes peerPresencePulse {
  0%, 100% { opacity: 0.35; transform: scale(0.92); }
  50% { opacity: 0.95; transform: scale(1.04); }
}
.peer-presence-viewport path {
  stroke: #c77dff !important;
  stroke-width: 1.5px !important;
  stroke-dasharray: 6 4 !important;
  fill: rgba(199, 125, 255, 0.06) !important;
}
.peer-viewed-by-label {
  display: inline-block;
  margin-top: 2px;
  padding: 1px 5px;
  border-radius: 4px;
  font-family: var(--mono);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: #e0aaff;
  background: rgba(199, 125, 255, 0.14);
  border: 1px solid rgba(199, 125, 255, 0.38);
  white-space: nowrap;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
  pointer-events: none;
}
.leaflet-tooltip.peer-viewed-by-label {
  padding: 3px 7px;
  font-size: 9px;
  color: #e0aaff;
  background: rgba(12, 10, 22, 0.92);
  border: 1px solid rgba(199, 125, 255, 0.45);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.55);
}

/* shared status dot for system row / queue rows */
.hdot { width: 8px; height: 8px; border-radius: 999px; flex: 0 0 auto; background: var(--faint); }
.hdot.up { background: var(--ok); box-shadow: 0 0 8px rgba(52,216,160,0.55); }
.hdot.down { background: var(--bad); box-shadow: 0 0 8px rgba(255,93,108,0.55); }

.panel-body-health { padding-bottom: 4px; }
.panel-body-health .health-system { margin: 0; }

/* system row: ML engine + DB + broker, as compact glass cells */
.health-system {
  display: grid; grid-template-columns: 1fr 1fr; gap: 7px; margin: 2px 0 4px;
}
.health-system .hstat-cell:first-child { grid-column: 1 / -1; }
.hstat-cell {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 9px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: rgba(255,255,255,0.02);
}
.hstat-cell .k { color: var(--faint); font-size: 11px; }
.hstat-cell .v { margin-left: auto; color: var(--text); font-size: 11px; }
.hstat-cell.bad { border-color: rgba(255,93,108,0.32); background: rgba(255,93,108,0.05); }
.hstat-cell.bad .v { color: var(--bad); }
.hstat-cell.ok .v { color: var(--ok); }

.health-list { max-height: none; }
.dock .list-cards > li.hq-row,
.dock .list-cards > li.hs-row { padding: 10px 12px; }

/* queue rows: name + backlog + consumers; warn band on depth/down */
.hq-row { gap: 9px; padding-left: 12px; }
.hq-row .title { font-size: 12px; color: var(--text); }
.hq-metric { font-size: 10.5px; color: var(--muted); flex: 0 0 auto; }
.hq-metric b { color: var(--text); font-weight: 600; }
.hq-metric .u { color: var(--faint); }
.hq-row.warn { background: rgba(255,201,67,0.05); }
.hq-row.warn .hq-metric b { color: var(--med); }

/* sector freshness rows: a fresh/stale indicator dot + a STALE/FRESH tag */
.hs-row { gap: 9px; padding-left: 12px; }
.hs-fresh {
  width: 8px; height: 8px; border-radius: 999px; flex: 0 0 auto;
  background: var(--ok); box-shadow: 0 0 8px rgba(52,216,160,0.5);
}
.hs-fresh.stale { background: var(--med); box-shadow: 0 0 8px rgba(255,201,67,0.45); }
.hs-row .title { font-size: 12.5px; display: flex; align-items: center; gap: 6px; }
.hs-off {
  font-family: var(--mono); font-size: 8px; font-weight: 700; letter-spacing: 0.1em;
  color: var(--faint); border: 1px solid var(--line-2); border-radius: 3px; padding: 1px 4px;
}
.hs-tag {
  font-size: 9px; font-weight: 600; letter-spacing: 0.08em; flex: 0 0 auto;
  padding: 2px 7px; border-radius: 5px;
  border: 1px solid rgba(52,216,160,0.32); color: var(--ok); background: rgba(52,216,160,0.06);
}
.hs-row.stale .hs-tag {
  border-color: rgba(255,201,67,0.4); color: var(--med); background: rgba(255,201,67,0.07);
}

.health-loading { color: var(--faint); font-size: 11.5px; padding: 6px 2px; }
.health-err { color: var(--bad); font-size: 12px; font-weight: 600; padding: 6px 2px 2px; }
.health-err-sub { color: var(--muted); font-size: 11px; padding-bottom: 4px; word-break: break-word; }

/* Per-source freshness (PAL-L-31): camera/imagery/AIS/ML queue rollups */
.health-sources { display: flex; flex-direction: column; gap: 10px; }
.health-src-block { display: flex; flex-direction: column; gap: 4px; }
.health-src-head {
  margin: 0; padding: 0 2px;
  font-family: var(--cond); font-size: 10px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--faint);
}
.dock .list-cards > li.hs-src-row { padding: 9px 12px; gap: 9px; }
.hs-src-row .title { font-size: 12px; color: var(--text); }
/* WS-UI-2 follow-up: two-line freshness/source rows top-align so the status dot
   sits ON the title line (not vertically centered across the card, which read
   as detached). Single-line queue rows (.hq-row alone) are untouched. */
.dock .list-cards > li.hs-row,
.dock .list-cards > li.hs-src-row { align-items: flex-start; }
.hs-row .hs-fresh,
.hs-src-row .hdot { margin-top: 5px; }
.hs-row .hs-tag,
.hs-src-row .hs-tag,
.hs-src-row .health-src-badge { margin-top: 1px; }
.hs-src-row .hq-metric { margin-top: 2px; }
.hs-src-row.stale { background: rgba(255,201,67,0.05); }
.hs-src-row.unknown { background: rgba(255,255,255,0.02); }
.health-src-badge.fresh {
  border-color: rgba(52,216,160,0.32); color: var(--ok); background: rgba(52,216,160,0.06);
}
.health-src-badge.stale {
  border-color: rgba(255,201,67,0.4); color: var(--med); background: rgba(255,201,67,0.07);
}
.health-src-badge.unknown {
  border-color: var(--line-2); color: var(--faint); background: rgba(255,255,255,0.03);
}

/* =============================================================================
   ENTITY DOSSIER DRAWER (PAL-L-37) — Gotham Object View
   Dock-consistent right-side investigation panel; opened from entity clicks.
   ========================================================================== */
.entity-dossier-drawer {
  --dock-accent: #ffc943;
  position: fixed;
  z-index: 25;
  top: calc(var(--bar-h) + var(--gap));
  right: var(--gap);
  bottom: var(--gap);
  width: min(380px, 42vw);
  display: flex;
  flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  /* `forwards` (not `both`): the entrance animates 0->1 and fills the end state, but the RESTING
     state uses the default opacity:1 — so if the one-shot animation doesn't re-trigger on the
     hidden->shown toggle, the drawer is still visible (was stuck at opacity:0 with `both`, showing
     only after a globe repaint). */
  animation: dossierIn 0.18s var(--ease) forwards;
}
@keyframes dossierIn {
  /* Slide only — opacity is NOT animated, so the drawer's resting opacity is always the default 1
     and can never get stuck at 0 when the one-shot animation fails to re-trigger on a hidden toggle. */
  from { transform: translateX(12px); }
  to { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .entity-dossier-drawer { animation: none; }
}
.entity-dossier-drawer::before {
  content: "";
  position: absolute;
  inset: 0 0 0 auto;
  width: 3px;
  z-index: 3;
  background: var(--dock-accent);
  opacity: 0.55;
  pointer-events: none;
  border-radius: 0 var(--r-lg) var(--r-lg) 0;
}
.dossier-top {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 13px 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.dossier-crumb {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}
.dossier-module {
  font-family: var(--cond);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dossier-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 10px 12px 12px;
}
.dossier-body::-webkit-scrollbar { width: 9px; }
.dossier-body::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.12);
  border-radius: 6px;
}
.dossier-body::-webkit-scrollbar-track { background: transparent; }
.dossier-kpis { margin-bottom: 10px; }
.dossier-loading,
.dossier-error {
  font-size: 11.5px;
  padding: 8px 4px;
}
.dossier-loading { color: var(--faint); }
.dossier-error { color: var(--bad); font-weight: 600; }
.dossier-meta {
  margin: 0;
  padding: 0 2px 4px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  font-size: 11.5px;
}
.dossier-meta dt {
  margin: 0;
  color: var(--faint);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.dossier-meta dd {
  margin: 0;
  color: var(--text);
  word-break: break-word;
}
.dossier-timeline { display: flex; flex-direction: column; gap: 6px; }
.dossier-tl-row {
  display: grid;
  grid-template-columns: 58px 1fr auto;
  gap: 8px;
  align-items: baseline;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255,255,255,0.02);
  font-size: 11px;
}
.dossier-tl-sensor {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  color: var(--accent);
  text-transform: uppercase;
}
.dossier-tl-cls { color: var(--ink); }
.dossier-tl-time { color: var(--faint); font-size: 10px; }
.dossier-tl-empty { font-size: 10px; color: var(--faint); padding: 4px 2px; }
/* PAL-P-04 time-travel contract — point-in-time entity view (console) */
.dossier-asof-badge {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--line);
}
.dossier-asof-badge.current { color: var(--ok); border-color: rgba(52,216,160,0.4); }
.dossier-asof-badge.historical { color: var(--med); border-color: rgba(255,197,67,0.45); }
.dossier-asof-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.dossier-asof-label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}
.dossier-asof-status {
  font-size: 10px;
  color: var(--med);
  margin: 0 0 8px;
}
.dossier-asof-compare { margin-top: 4px; }
.dossier-asof-caption {
  font-size: 10px;
  color: var(--faint);
  margin-bottom: 6px;
}
.dossier-asof-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 10.5px;
}
.dossier-asof-table th,
.dossier-asof-table td {
  padding: 5px 7px;
  border: 1px solid var(--line);
  text-align: left;
}
.dossier-asof-table th {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  background: rgba(0,0,0,0.14);
}
.dossier-asof-table tr.dossier-asof-diff td {
  background: rgba(255,197,67,0.08);
}
.dossier-asof-field { color: var(--muted); }
.dossier-asof-hist { color: var(--med); }
.dossier-obslog { display: flex; flex-direction: column; gap: 6px; }
.dossier-obslog-row {
  display: grid;
  grid-template-columns: 34px 72px 52px 1fr auto;
  gap: 6px;
  align-items: baseline;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255,255,255,0.02);
  font-size: 11px;
}
.dossier-obslog-row.correction {
  border-color: rgba(255,138,61,0.35);
  background: rgba(255,138,61,0.06);
}
.dossier-obslog-ver { color: var(--accent); font-size: 10px; }
.dossier-obslog-kind {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}
.dossier-obslog-corrects {
  grid-column: 1 / -1;
  font-size: 9.5px;
  color: var(--high);
}
.dossier-citations { display: flex; flex-direction: column; gap: 8px; }
.dossier-citation-block {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255,255,255,0.02);
  padding: 8px 9px;
}
.dossier-citation-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 10.5px;
}
.dossier-citation-kind {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.dossier-citation-time { color: var(--faint); font-size: 10px; }
.dossier-citation-ref {
  margin-top: 4px;
  font-size: 10px;
  color: var(--muted);
  word-break: break-all;
}
.dossier-citation-sources {
  margin: 6px 0 0;
  padding-left: 16px;
  font-size: 10px;
  color: var(--text);
}
.dossier-provenance { display: flex; flex-direction: column; gap: 10px; }
.dossier-prov-block {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255,255,255,0.02);
  overflow: hidden;
}
.dossier-prov-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 9px;
  border-bottom: 1px solid var(--line);
  font-size: 10.5px;
  color: var(--muted);
  background: rgba(0,0,0,0.14);
}
.dossier-prov-chain { padding: 6px 9px 8px; display: flex; flex-direction: column; gap: 5px; }
.dossier-prov-step {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: 8px;
  align-items: baseline;
  font-size: 10.5px;
}
.dossier-prov-stage {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 2px 5px;
  border-radius: 4px;
  border: 1px solid var(--line);
  text-align: center;
}
.dossier-prov-stage.sensor { color: var(--accent); border-color: rgba(52,224,207,0.35); }
.dossier-prov-stage.model { color: var(--med); border-color: rgba(255,197,67,0.35); }
.dossier-prov-stage.analyst { color: var(--high); border-color: rgba(255,138,61,0.35); }
.dossier-prov-stage.action { color: var(--ok); border-color: rgba(52,216,160,0.35); }
.dossier-prov-label { color: var(--text); word-break: break-word; }
.dossier-prov-time { color: var(--faint); font-size: 10px; }
.dossier-notes > li,
.dossier-attachments > li {
  padding: 8px 10px;
  font-size: 11px;
}
.dossier-link-type {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.dossier-note-author {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--faint);
}
.dossier-note-body {
  margin-top: 4px;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
}
.dossier-attach-name { color: var(--text); font-weight: 500; }
.dossier-attach-meta { color: var(--faint); font-size: 10px; margin-top: 2px; }
.dossier-note-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}
.dossier-note-form textarea {
  width: 100%;
  min-height: 64px;
  resize: vertical;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: rgba(0,0,0,0.22);
  color: var(--text);
  font-family: var(--sans);
  font-size: 12px;
}
.dossier-note-form textarea:focus {
  outline: none;
  border-color: var(--accent-line);
}
.dossier-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--line);
  background: rgba(0,0,0,0.16);
}
.entity-popup .dossier-open-btn { margin-top: 8px; width: 100%; }
.entity-popup .change-report-open-btn { margin-top: 6px; width: 100%; }
.dossier-change-reports > li {
  display: flex;
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
}
.dossier-change-reports .cr-row-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.dossier-change-reports .cr-status {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.dossier-change-reports .cr-status.ready { color: var(--ok); }
.dossier-change-reports .cr-status.pending { color: var(--med); }
.dossier-change-reports .cr-epochs {
  font-size: 10px;
  color: var(--faint);
  word-break: break-all;
}

/* ---- Change report modal (PAL-L-04) -------------------------------------- */
.change-report-card { max-width: 520px; width: min(96vw, 520px); }
.change-report-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0 14px 10px;
}
.change-report-context {
  margin: 0;
  font-size: 10.5px;
  color: var(--faint);
  word-break: break-word;
}
.change-report-msg {
  margin: 0;
  font-size: 11px;
  color: var(--bad);
  font-weight: 600;
}
.change-report-msg.ok { color: var(--ok); }
.change-report-picker {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  align-items: end;
}
.change-report-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.change-report-field .k {
  font-size: 10px;
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
#change-report-refresh-stac { grid-column: 1 / -1; justify-self: start; }
.change-report-status {
  padding: 8px 10px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  font-size: 11px;
  color: var(--med);
  background: rgba(0,0,0,0.12);
}
.change-report-status.err { color: var(--bad); border-color: rgba(255,65,77,0.35); }
.change-report-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 10px;
  font-size: 11px;
}
.change-report-summary dt {
  margin: 0;
  font-size: 10px;
  color: var(--faint);
  text-transform: uppercase;
}
.change-report-summary dd {
  margin: 0 0 4px;
  color: var(--ink);
  font-weight: 500;
}
.change-report-thumbs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.change-report-thumb {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: rgba(0,0,0,0.2);
}
.change-report-thumb img {
  display: block;
  width: 100%;
  height: 110px;
  object-fit: cover;
  background: rgba(0,0,0,0.35);
}
.change-report-thumb figcaption {
  padding: 4px 6px;
  font-size: 10px;
  color: var(--faint);
  text-align: center;
  border-top: 1px solid var(--line);
}
.change-report-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.change-report-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--line);
}
.tac-aoi-row .change-report-aoi-btn { flex: 0 0 auto; }

/* ---- Entity link graph panel (PAL-L-06) ---------------------------------- */
.dossier-graph-section .graph-hint {
  margin: 0 2px 8px;
  font-size: 10.5px;
  color: var(--faint);
}
.graph-view-wrap {
  margin-bottom: 10px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(0,0,0,0.18);
}
.graph-view-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 10.5px;
}
.graph-depth-label {
  color: var(--faint);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.dossier-graph-canvas {
  display: block;
  width: 100%;
  height: 180px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: rgba(0,0,0,0.28);
  cursor: pointer;
}
.graph-neighbors-head h4 {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.dossier-graph-neighbors > li,
.dossier-graph-neighbor {
  padding: 8px 10px;
  font-size: 11px;
}
.dossier-graph-peer {
  display: inline-block;
  margin: 2px 0;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  font-family: var(--mono);
  font-size: 11px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.dossier-graph-peer:hover { color: var(--ink); }
.dossier-graph-neighbor-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 6px;
}
.dossier-link-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.dossier-link-form-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.dossier-link-form-row label {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
}

@media (max-width: 900px) {
  .entity-dossier-drawer {
    width: min(340px, calc(100vw - 2 * var(--gap)));
  }
}

/* =============================================================================
   COT MODAL
   ========================================================================== */
.modal {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(2,5,9,0.72);
  animation: fade 0.16s var(--ease);
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.modal-card {
  width: min(780px, 94vw); max-height: 84vh;
  display: flex; flex-direction: column;
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  overflow: hidden; box-shadow: var(--shadow);
  animation: cardIn 0.2s var(--ease);
}
@keyframes cardIn { from { transform: translateY(8px) scale(0.99); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
  background: rgba(0,0,0,0.2);
}
.modal-head .eyebrow {
  font-family: var(--cond); font-weight: 600; font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--accent);
}
.modal-head h3 {
  margin: 2px 0 0; font-size: 13px; font-weight: 600;
  font-family: var(--mono); color: var(--text);
}
.modal-head .grow { flex: 1; }
.cot-xml {
  margin: 0; padding: 16px; overflow: auto;
  font-family: var(--mono); font-size: 12px; line-height: 1.65;
  white-space: pre; color: var(--text);
  background:
    repeating-linear-gradient(0deg, transparent 0 27px, rgba(255,255,255,0.014) 27px 28px);
}
.cot-xml .tag { color: var(--accent); }
.cot-xml .attr { color: var(--high); }
.cot-xml .val { color: var(--low); }
.cot-xml .txt { color: var(--text); }
.cot-empty { padding: 30px; text-align: center; color: var(--muted); }

/* =============================================================================
   TOASTS
   ========================================================================== */
.toast-stack {
  position: fixed; right: 18px; bottom: 18px; z-index: 1400;
  display: flex; flex-direction: column; gap: 10px;
  max-width: 380px;
}
.toast {
  background: var(--surface-1);
  border: 1px solid var(--line-2);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-md);
  box-shadow: var(--shadow);
  padding: 12px 14px;
  animation: toastIn 0.22s var(--ease);
}
.toast.out { animation: toastOut 0.2s var(--ease) forwards; }
.toast.ok { border-left-color: var(--ok); }
.toast.err { border-left-color: var(--bad); }
/* PERF-HARDEN-01: contained background-error signal — amber, non-alarming. */
.toast.warn { border-left-color: #f2b23a; }
.toast .t-head {
  display: flex; align-items: center; gap: 8px;
  font-weight: 600; font-size: 13px; margin-bottom: 3px;
}
.toast .t-head .ic { color: var(--accent); }
.toast.ok .t-head .ic { color: var(--ok); }
.toast.err .t-head .ic { color: var(--bad); }
.toast.warn .t-head .ic { color: #f2b23a; }
.toast .t-body {
  font-family: var(--mono); font-size: 11.5px; color: var(--muted);
  line-height: 1.65; white-space: pre-wrap; word-break: break-word;
}
.toast .t-body b { color: var(--text); font-weight: 500; }
@keyframes toastIn { from { transform: translateX(20px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes toastOut { to { transform: translateX(20px); opacity: 0; } }

/* =============================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 1180px) {
  .sb-updated { display: none; }
}
@media (max-width: 1024px) {
  .classification { display: none; }
}
@media (max-width: 860px) {
  :root { --rail-w: 320px; }
  .tally .k { display: none; }
  .sb-clock-wrap { display: none; }
}
@media (max-width: 720px) {
  :root { --rail-w: 260px; }
  /* the dock may shrink so the map keeps room; the icon rail stays fixed */
  .dock { flex: 0 1 var(--rail-w); }
  .statusbar { flex-wrap: wrap; height: auto; padding: 8px 12px; gap: 10px; }
  .sb-spacer { display: none; }
  .sb-health, .tallies { order: 3; }
  .hud-legend { display: none; }
  .leaflet-top { top: 96px; }
}

/* ---- Orchestrated reveal (WS-UI-2) --------------------------------------
   ONE staged moment: on login → shell, the command bar and the instrument
   cluster (rail + dock) fade/rise 220ms, staggered 60ms. CSS only — plays
   when the [hidden] attribute is removed from #app. */
.app:not([hidden]) .statusbar {
  animation: shellReveal 0.22s var(--ease) both;
}
.app:not([hidden]) .nav-shell {
  animation: shellReveal 0.22s var(--ease) 0.06s both;
}
@keyframes shellReveal {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* ---- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  /* WS-UI-2: explicitly disable the shell reveal + the login radar sweep */
  .app:not([hidden]) .statusbar,
  .app:not([hidden]) .nav-shell { animation: none !important; }
  .login-aura { animation: none !important; }
}
