/* ============================================
   scene.css — Maven scene (SceneRenderer)
   Shared by the game (index.html) and the test suite (suite.html).
   Self-contained: defines its own vars so the suite
   (shared.css + scene.css only) renders identically.
   Layout: chrome topbar 32px, chrome-left 252px (LAYERS v2), HUD cards
   in edge lanes (left: feed / viewer / list / asset detail, right: POI).
   ============================================ */

/* Palantir typefaces: Alliance 2 = body/UI face, Alliance 1 = title face.
   Self-hosted from fonts/ (Degarism Studio's Alliance No.1/No.2). The family
   has no Bold — its heavy cut is Black. CSS weight matching then resolves:
   body 400/500/600 → Alliance 2 Medium, 700 → Alliance 2 Black;
   title 400 → Alliance 1 Regular, 600/700 → Alliance 1 Black. */
@font-face {
  font-family: 'Alliance 2';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../../fonts/alliance2-light.otf') format('opentype');
}
@font-face {
  font-family: 'Alliance 2';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../../fonts/alliance2-medium.otf') format('opentype');
}
@font-face {
  font-family: 'Alliance 2';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('../../fonts/alliance2-black.otf') format('opentype');
}
@font-face {
  font-family: 'Alliance 1';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../../fonts/alliance1-light.otf') format('opentype');
}
@font-face {
  font-family: 'Alliance 1';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../../fonts/alliance1-regular.otf') format('opentype');
}
@font-face {
  font-family: 'Alliance 1';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('../../fonts/alliance1-black.otf') format('opentype');
}

:root {
  --mv-title: 'Alliance 1', 'Alliance 2', -apple-system, system-ui, sans-serif;
  --mv-body: 'Alliance 2', -apple-system, system-ui, sans-serif;
  --scene-mono: var(--mv-body);
  --scene-bg: #0a0a0c;
  /* Palantir Foundry dark theme (Maven chrome + panels) */
  --mv-bg: #1e1e1e;          /* app background / top bar */
  --mv-panel: #252525;       /* panel surface */
  --mv-panel-2: #2d2d2d;     /* raised surface / hover / active */
  --mv-border: #3a3a3a;      /* 1px border */
  --mv-border-soft: #2f2f2f; /* inner dividers */
  --mv-text: #e6e6e6;        /* primary text */
  --mv-text-2: #a0a0a0;      /* secondary text */
  --mv-text-3: #6e6e6e;      /* tertiary / muted */
  --mv-accent: #3b82f6;      /* Foundry blue (interactive) */
  --mv-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

#scene-host {
  position: absolute;
  inset: 0;
  background: var(--scene-bg);
  overflow: hidden;
  z-index: 1; /* stacking context: contains Leaflet panes (z-index 200-650)
                   so they don't paint over the playback bar, messenger, etc. */
  --spd: 1; /* playback-rate multiplier for loop animations */
}
#scene-host .scene-map {
  position: absolute;
  inset: 0;
  background: var(--scene-bg);
}
#scene-host .scene-map .leaflet-tile {
  image-rendering: auto;
}
#scene-host .scene-map .leaflet-marker-pane,
#scene-host .scene-map .leaflet-tooltip-pane { z-index: 400; }
#scene-host .scene-hud {
  position: absolute;
  inset: 0;
  pointer-events: none;
  font-family: var(--mono, var(--scene-mono), monospace);
  z-index: 800; /* above Leaflet panes (max 650) within #scene-host's context */
}
/* POI engagement ring (2026-10-06): a constant-size screen-space circle,
   positioned every frame in _applyState in Leaflet LAYER points so it
   tracks the map exactly (a canvas/SVG Leaflet layer lags the marker pane
   during the per-frame `_move` flight) and keeps a fixed px size — the ring
   cancels the zoom animation's pane scale with its own transform. Size /
   border / fill are set inline per frame; only the shape lives here.
   The rings live in their own layer INSIDE the Leaflet map pane, below the
   marker + tooltip panes (400): the map pane is a stacking context, so a
   ring in .scene-hud (z 800) sat above the whole map and painted every POI
   hover label UNDERNEATH its square. */
#scene-host .poi-ring-layer {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 250; /* above the tile pane (200), below the marker/tooltip panes */
  pointer-events: none;
}
#scene-host .poi-ring-layer .poi-ring {
  position: absolute;
  width: 152px; /* 2 × POI_RING.radiusPx (76) */
  height: 152px;
  border-radius: 50%;
  border: 2px solid;
  box-sizing: border-box;
  pointer-events: none;
  display: none;
}

/* common HUD card — neutral Maven surface (Foundry dark). Individual
   panels override as needed; the single-class event flashes
   (.hud-nodet/.hud-impact/.hud-bda/.hud-cloud) rely on source order to
   override this default, so keep this rule LOW specificity (no #scene-host). */
.hud {
  position: absolute;
  color: var(--mv-text-2);
  font-size: 11px;
  letter-spacing: 0.06em;
  background: var(--mv-panel);
  border: 1px solid var(--mv-border);
  border-radius: 4px;
  padding: 8px 10px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
}

/* ============ Maven chrome (flat dark Palantir) ============ */

#scene-host .chrome {
  position: absolute;
  background: var(--mv-panel);
  border: 1px solid var(--mv-border);
  font-family: var(--scene-mono), sans-serif;
  font-size: 10px;
  color: var(--mv-text-2);
  user-select: none;
}

/* top bar */
/* top bar — the one [C1] chrome top bar SceneRenderer builds (single
   variant, shared by game and suite); the bar stays 32px tall so no
   other chrome reflows. All icons are inline SVG in scene-renderer.js;
   decorative ones carry no data-element-id (the Recorder ignores them). */
#scene-host .chrome-topbar {
  left: 0; top: 0; right: 0;
  height: 32px;
  border-left: none; border-right: none; border-top: none;
  border-bottom: 1px solid #090a0b; /* subtle darker bottom edge */
  background: #111214;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 10px;
  overflow: visible; /* NOT hidden: the mode dropdown (.mv-mode-menu) hangs
                         below the 32px bar — clipping here hid it behind the
                         map (the bar's content fits the 1920 stage anyway) */
  font-size: 12px;
  color: #e6e6e6;
}

/* shared icon-slot wrapper (bare items 1, 3, 4, 5, 9, 10, 12) */
#scene-host .mv-i {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}

/* 1. account button — wordmark + chevron, bare (no border) */
#scene-host .mv-acct {
  gap: 4px;
  padding-right: 5px;
}
#scene-host .mv-logo {
  display: block;
  height: 28px;
  width: auto;
  border-radius: 2px;
}

/* 2. "Scenario Map" pill */
#scene-host .mv-pill {
  gap: 6px;
  padding: 3px 8px;
  background: #1e2024;
  border-radius: 5px;
}
#scene-host .mv-pill-label {
  color: #e6e6e6;
  font-size: 12px;
  white-space: nowrap;
}

/* 7. static app menu — no separators, no dropdowns */
#scene-host .mv-menu {
  display: inline-flex;
  gap: 14px;
  padding: 0 4px;
  color: #cfcfcf;
  font-size: 12px;
  white-space: nowrap;
  cursor: default;
}

/* 6. chat button — the AIP Agent tab. Keeps class tb-tab + data-element-id
   tab_agent so _applyActionEffect('tab'), _syncAgentBadge (NOTICE badge) and
   _syncPanelTabs keep working; overrides the generic .tb-tab text-tab
   styling. */
#scene-host .tb-tab.mv-chat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 22px;
  padding: 0;
  background: #26282c;
  border: none;
  border-radius: 7px;
  color: #fff;
}
#scene-host .tb-tab.mv-chat:hover,
#scene-host .tb-tab.mv-chat.is-hover {
  background: #2f3238;
  color: #fff;
}
#scene-host .tb-tab.mv-chat:active,
#scene-host .tb-tab.mv-chat.is-active {
  background: #33363c;
  color: #fff;
}
#scene-host .tb-tab.mv-chat.active {
  color: #fff;
  background: #2f3238;
  box-shadow: inset 0 -2px 0 var(--mv-accent);
}
/* The NOTICE badge (.tb-tab.has-badge::after, 6px dot at top/right 2px
   below) lands inside this pill's top-right corner as-is. */

/* 8. mode selector — a custom dropdown (a native <select> popup cannot be
   shown during replay). Button + option list; the open state is DOM-only
   (_styleMenuOpen in js/scene-renderer.js), toggled by clicks in the suite
   and derived from the recorded press/action events in replay. Globe +
   chevron painted as backgrounds, same as the old select. */
#scene-host .mv-mode {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 22px 0 26px;
  background-color: #1a1c20; /* slightly lighter than the bar */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9aa0' stroke-width='1.8'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3c2.5 2.5 3.9 5.6 3.9 9s-1.4 6.5-3.9 9c-2.5-2.5-3.9-5.6-3.9-9s1.4-6.5 3.9-9z'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9aa0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 7px center, right 7px center;
  background-size: 14px 14px, 10px 10px;
  border: 1px solid #3a3d42;
  border-radius: 5px;
  color: #e6e6e6;
  font-size: 12px;
  cursor: default;
  user-select: none;
}
#scene-host .mv-mode:hover,
#scene-host .mv-mode.is-hover { border-color: #555; }
#scene-host .mv-mode.is-active { background-color: #22242a; }
#scene-host .mv-mode-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  padding: 3px 0;
  background: #1e2024;
  border: 1px solid #3a3d42;
  border-radius: 5px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  z-index: 40;
}
#scene-host .mv-mode-opt {
  display: block;
  width: 100%;
  padding: 3px 12px;
  text-align: left;
  background: none;
  border: 0;
  color: #e6e6e6;
  font: inherit;
  cursor: default;
}
#scene-host .mv-mode-opt:hover,
#scene-host .mv-mode-opt.is-hover { background: #2f3238; }
#scene-host .mv-mode-opt.sel { color: var(--mv-accent); }

/* the asset select — compact, just before the search box; same
   data-element-id + .tb-select so _hostChange (_selectAsset) keeps working */
#scene-host .mv-asset {
  -webkit-appearance: none;
  appearance: none;
  height: 24px;
  max-width: 170px;
  padding: 0 20px 0 8px;
  background-color: #17191d;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9aa0' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 10px 10px;
  border: 1px solid #33363b;
  border-radius: 5px;
  color: #e6e6e6;
  font-size: 12px;
  cursor: default;
}
#scene-host .mv-asset option {
  background: #1e2024;
  color: #e6e6e6;
}

/* 13. Share text button — no border/background */
#scene-host .mv-share {
  flex: 0 0 auto;
  color: #4d9fff;
  font-size: 13px;
  padding: 2px 4px;
}

/* 14. search box — decorative magnifier + real focusable input */
#scene-host .mv-searchwrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 1 180px;
  min-width: 90px;
  height: 24px;
  padding: 0 8px;
  background: #1a1c1f;
  border: 1px solid #33363b;
  border-radius: 5px;
}
#scene-host .mv-searchwrap:focus-within {
  border-color: #4d9fff;
}
#scene-host .mv-search {
  width: 132px; /* fixes the box at ~168px incl. magnifier+padding (spec 160–200) */
  min-width: 0;
  padding: 0;
  background: transparent;
  border: none;
  outline: none;
  color: #e6e6e6;
  font-size: 12px;
  font-family: inherit;
  cursor: text;
}
#scene-host .mv-search::placeholder {
  color: #6e6e6e;
}

/* right-aligned cluster (10–14 + asset select) */
#scene-host .mv-right {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-left: auto;
  flex: 0 0 auto;
}
#scene-host .mv-signal {
  gap: 5px;
}
#scene-host .mv-signal-text {
  color: #e6e6e6;
  font-size: 12px;
  white-space: nowrap;
}

/* left sidebar — LAYERS panel v2: a decorative three-button strip
   (Map layers pinned active / Data sources / Tools — inert, for show)
   + a live search filter + a collapsible folder tree. Shared by game
   and suite; folders/search are inert in replay (no scene-interactive
   opt-in there). The strip is ~51px tall — the old LAYERS title bar
   + tab strip measured 52px, so recorded cursor positions over the
   tree keep pointing at the same rows. */
.chrome-left {
  left: 0; top: 32px; bottom: 0;
  width: 252px;
  border-left: none; border-bottom: none;
  border-top: 1px solid rgba(255, 208, 0, 0.28); /* thin gold top border */
  overflow-y: auto;
  padding: 8px;
}
/* decorative tab strip across the top of the panel (2026-10-25): the
   LAYERS title bar + the old glyph tabs became three icon buttons —
   Map layers pinned active (blue symbol + underline), Data sources
   and Tools inert (no data-element-id; the panes below render stacked
   regardless, so the tabs never gated the body). data-tab is retained
   for the _resetDynamic default-tab pin. Labels wrap at a tight line
   gap; the strip's ~51px total height matches the old title+tabs 52px,
   so recorded cursor positions over the tree keep their targets. */
.chrome-left .cl-tabs {
  display: flex;
  margin: 2px 0 6px;
  border-bottom: 1px solid var(--mv-border-soft);
}
.chrome-left .cl-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  flex: 1 1 0;
  padding: 7px 4px;
  font-size: 13px;
  line-height: 14px; /* tight: wrapped two-line labels stay compact */
  letter-spacing: 0.02em;
  color: #8f949c;
  box-shadow: inset 0 -2px 0 transparent;
}
.chrome-left .cl-tab svg { flex: 0 0 auto; color: #8f949c; }
.chrome-left .cl-tab.active {
  color: var(--mv-text);
  box-shadow: inset 0 -2px 0 var(--mv-accent);
}
.chrome-left .cl-tab.active svg { color: var(--mv-accent); }
/* search field row */
.chrome-left .cl-search {
  position: relative;
  display: flex;
  align-items: center;
  margin: 0 0 6px;
  border: 1px solid var(--mv-border);
  border-radius: 2px;
  background: var(--mv-panel);
}
.chrome-left .cl-search-ic {
  padding-left: 6px;
  color: var(--mv-text-3);
  font-size: 13px;
  flex-shrink: 0;
}
.chrome-left .cl-search-input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  color: var(--mv-text);
  font-size: 13px;
  line-height: 15px; /* pinned: Roboto-era line box (see .cl-title) */
  font-family: inherit;
  letter-spacing: 0.02em;
  padding: 4px 6px;
}
.chrome-left .cl-search-input::placeholder { color: var(--mv-text-3); }
/* tree rows: folders (headers) + indented leaves */
.chrome-left .cl-section { margin-bottom: 3px; }
.chrome-left .cl-folder {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 4px 6px;
  color: var(--mv-text);
  font-size: 13px;
  line-height: 15px; /* pinned: Roboto-era line box (see .cl-title) */
  font-weight: 600;
  letter-spacing: 0.05em;
  border-radius: 2px;
  margin: 0;
  white-space: nowrap;
}
.chrome-left .cl-arrow {
  width: 9px;
  flex-shrink: 0;
  font-size: 11px;
  color: var(--mv-text-3);
  transition: transform 0.12s ease;
}
.chrome-left .cl-section.collapsed .cl-arrow { transform: rotate(-90deg); }
.chrome-left .cl-section.collapsed .cl-children { display: none; }
.chrome-left .cl-glyph {
  width: 12px;
  flex-shrink: 0;
  text-align: center;
  font-size: 12px;
  color: var(--mv-text-3);
}
.chrome-left .cl-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chrome-left .cl-count { color: var(--mv-text-3); font-weight: 400; }
.chrome-left .cl-row {
  display: flex;
  align-items: center;
  padding: 3px 6px;
  color: var(--mv-text-2);
  line-height: 15px; /* pinned: Roboto-era line box (see .cl-title) */
  border-radius: 2px;
  margin: 0; /* 2026-09-07: 1px 0 → 0 — the +3pt row scale-up pushed the
                 tree ~25px past the 1044px panel viewport; the rows' own
                 3px padding keeps them readable with no inter-row gap */
  white-space: nowrap;
  overflow: hidden;
}
/* child rows indent under their folder */
.chrome-left .cl-children .cl-row {
  margin-left: 14px;
  position: relative;
  font-size: 13px;
  letter-spacing: 0.02em;
}
.chrome-left .cl-children .cl-row::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--mv-border-soft); /* indent guide */
}
.chrome-left .cl-row.active {
  background: rgba(255, 208, 0, 0.13);
  color: var(--mv-text);
  box-shadow: inset 2px 0 0 var(--mv-accent); /* selected: gold band + left rule */
}
.chrome-left .cl-row.filter-hidden { display: none; }
.chrome-left .cl-section.filter-hidden { display: none; }
/* right-side affordances: stream/share glyph, gear, status dot (last) */
.chrome-left .cl-stream {
  margin-left: auto;
  color: var(--mv-text-3);
  font-size: 12px;
  flex-shrink: 0;
}
.chrome-left .cl-aff {
  margin-left: 5px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
}
.chrome-left .cl-gear {
  color: var(--mv-text-3);
  font-size: 12px;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.chrome-left .cl-row:hover .cl-gear,
.chrome-left .cl-row.is-hover .cl-gear { opacity: 0.8; }
.chrome-left .cl-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  margin-left: 5px;
  flex-shrink: 0;
}
.chrome-left .cl-dot.green { background: #4ade80; }
.chrome-left .cl-dot.grey { background: #9ca3af; }
.chrome-left .cl-dot.red { background: #f87171; }


/* ship detail panel (chrome-styled, data-driven) — selection popup.
   Left lane, immediately right of the Friendly Assets folder in the
   LAYERS panel (chrome-left, left 0, width 252): left 260 = the
    lane's 8px gutter (same as the other left-lane cards). Static
    top 575px = the folder's default position (re-measured 2026-09-12
    after the Alliance typeface swap: the pinned row line-heights
    (scene.css .cl-row/.cl-folder) compact the tree 21px vs the
    Roboto-era metrics, so the folder — and the live anchor — moved
    597 → 575; 531 pre-dated the 2026-09-07 row scale-up). The renderer
    re-anchors the inline top to the folder's live rect each time the
    panel opens (see SceneRenderer._anchorAssetDetail).
    Content-height, viewport-aware (min): the 508px constant = the
    tallest card's measured content height (DDG-116, 506px scrollHeight)
    + 2px border; the calc term (602) keeps every card's bottom inside
    the frame floor — at 1080 the cap is 478, so the three shorter cards
    (≤449 content) show in full with no in-card scroll and the DDG-116
    card (506 content) scrolls inside the card instead of clipping the
    frame. The 602 cap is kept at its Roboto-baseline value so the card
    size is unchanged by the font swap (the 575 anchor just adds 27px of
    headroom below the card). */
.asset-detail {
  left: 260px;
  top: 575px;
  width: 232px;
  padding: 10px 12px;
  border-radius: 4px;
  max-height: min(508px, calc(100% - 602px));
  overflow-y: auto;
}
.asset-detail .ad-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
  padding-right: 14px; /* clear the corner close button */
}
.asset-detail .ad-name {
  color: var(--mv-text);
  font-family: var(--mv-title);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.asset-detail .ad-type {
  color: var(--mv-accent);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  font-family: var(--mv-mono);
  white-space: nowrap;
}
.asset-detail .ad-photo {
  margin-bottom: 4px;
  border: 1px solid var(--mv-border-soft);
  border-radius: 3px;
  overflow: hidden;
  background: #000;
}
.asset-detail .ad-photo img {
  display: block;
  width: 100%;
  height: 120px;
  object-fit: cover;
}
.asset-detail .ad-sec {
  color: var(--mv-text-3);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  margin: 9px 0 4px;
  padding-top: 7px;
  border-top: 1px solid var(--mv-border-soft);
}
.asset-detail .ad-row {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  line-height: 1.7;
  color: var(--mv-text-3);
}
.asset-detail .ad-row span:last-child {
  color: var(--mv-text-2);
  font-family: var(--mv-mono);
}
.asset-detail .ad-row .ok { color: #4ade80; }
.asset-detail .ad-div { border-top: 1px solid var(--mv-border-soft); margin: 5px 0; }

/* ============ Maven content panels (Foundry dark) ============ */

/* shared panel surface (overrides the gold .hud glass) */
#scene-host .hud.mv-panel {
  background: var(--mv-panel);
  border: 1px solid var(--mv-border);
  border-radius: 4px;
  color: var(--mv-text-2);
  font-family: var(--scene-mono), sans-serif;
  font-size: 10px;
  letter-spacing: 0.02em;
  padding: 10px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5);
}
#scene-host .hud.mv-panel .ok { color: #4ade80; }

/* corner close button (top-right) for toggleable panels */
.mv-close {
  position: absolute;
  top: 5px;
  right: 6px;
  width: 16px;
  height: 16px;
  line-height: 15px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: var(--mv-text-3);
  font-size: 12px;
  cursor: pointer;
  z-index: 2;
}
.mv-close:hover, .mv-close.is-hover { color: var(--mv-text); border-color: var(--mv-border); background: var(--mv-panel-2); }

/* [C6] AIP agent panel - bottom left, in the left lane
   Restyled after the original Maven AIP window: neutral --mv-* palette,
   two-line header, visual-only toolbar row, right-aligned user bubble,
   square logo + uppercase agent label, icon step rows, plain paragraph +
   bulleted detection fields (no card), chat-like input row.
   Shape: plain right-angled rectangle (border-radius 0) to match the other
   Maven windows — the former chamfered top-left/bottom-right clip-path is
   gone, so the 1px frame + elevation are a normal border + box-shadow.
   Docked, not floating: left 260 is the left lane's 8px gutter right of the
   LAYERS panel (0–252 + 1px host border — same gutter as .asset-detail), so
   the panel sits beside the sidebar instead of overlapping it. bottom 80
   clears the tribunal playbar band (bar bottom 20 + 54 controls = 74px of
   the stage's foot at k=1) and the 20px status bar; the 830px height then
   tops out at 170, clear of the 32px topbar. */
#scene-host .hud-agent {
  left: 260px;
  bottom: 80px;
  width: 300px;
  z-index: 2; /* above the map-icon clusters (built later in .scene-hud, so DOM order would paint them over the panel); still below the scripted cursor (801) */
  background: var(--mv-bg);
  border: 1px solid var(--mv-border);
  border-radius: 0;
  padding: 14px;
  color: var(--mv-text-2);
  font-family: var(--mv-body);
  font-size: 13px;
  letter-spacing: 0.01em;
  line-height: 1.5;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
  /* Fixed-height docked chat window: the × close button sits at a stable
     stage position (top-right) so the recorded cursor lands on it exactly,
     independent of how much transcript content is present. The transcript
     area scrolls; the input row stays pinned to the bottom. */
  height: 830px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.hud-agent .ag-head,
.hud-agent .ag-iconrow,
.hud-agent .ag-input-row { flex: 0 0 auto; }
.hud-agent [data-ag="conv"] { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.hud-agent .mv-close { top: 9px; right: 9px; }
/* identity header - two lines */
.hud-agent .ag-head {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 10px;
  padding-right: 16px; /* room for the close button */
}
.hud-agent .ag-head-text { flex: 1; min-width: 0; }
.hud-agent .ag-name { color: var(--mv-text); font-family: var(--mv-title); font-size: 14px; font-weight: 700; }
.hud-agent .ag-sub { color: var(--mv-text-3); font-size: 12px; margin-top: 2px; }
/* decorative toolbar row - sits directly under the identity header, with no
   card of its own (no data-action - not recorded) */
.hud-agent .ag-iconrow {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 12px;
}
.hud-agent .ag-ic {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--mv-text-3);
  padding: 1px;
}
.hud-agent .ag-ic-spacer { flex: 1; }
/* transcript turns: agent text sits on the panel background */
.hud-agent .ag-turn { display: flex; gap: 9px; margin-bottom: 14px; }
.hud-agent .ag-turn-user { justify-content: flex-end; }
.hud-agent .ag-turn-body { flex: 1; min-width: 0; }
.hud-agent .ag-user {
  display: inline-block;
  max-width: 100%;
  background: var(--mv-panel-2);
  border: 1px solid var(--mv-border);
  border-radius: 10px;
  padding: 7px 11px;
  color: var(--mv-text);
  font-size: 13px;
}
/* agent identity: square logo mark + uppercase label */
.hud-agent .ag-id { display: flex; align-items: center; gap: 7px; margin-bottom: 8px; }
.hud-agent .ag-logo {
  flex-shrink: 0;
  width: 20px;
  height: 14px;
  background: var(--mv-text-2);
  -webkit-mask: url('../../data/maven/anthropic-mark.png') center / contain no-repeat;
          mask: url('../../data/maven/anthropic-mark.png') center / contain no-repeat;
}
.hud-agent .ag-id-label { color: var(--mv-text-3); font-size: 11px; font-weight: 600; letter-spacing: 0.12em; }
/* agent thinking steps - icon + text + trailing chevron */
.hud-agent .ag-steps { margin-bottom: 8px; }
.hud-agent .ag-step {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--mv-text-2);
  font-size: 12px;
  line-height: 1.9;
}
.hud-agent .ag-step-ic { width: 12px; text-align: center; color: var(--mv-text-3); font-size: 12px; flex-shrink: 0; }
.hud-agent .ag-step-ch { margin-left: auto; color: var(--mv-text-3); font-size: 11px; }
/* detection output: paragraph + bulleted fields, no card */
.hud-agent .ag-answer { color: var(--mv-text); font-size: 13px; line-height: 1.6; }
.hud-agent .ag-fields { margin: 8px 0 0; padding: 0; list-style: none; }
.hud-agent .ag-fields li {
  position: relative;
  display: flex;
  gap: 8px;
  padding-left: 12px;
  font-size: 12px;
  line-height: 1.8;
}
.hud-agent .ag-fields li::before { content: '·'; position: absolute; left: 2px; color: var(--mv-text-3); }
.hud-agent .ag-bk { color: var(--mv-text-3); flex-shrink: 0; }
.hud-agent .ag-bv { color: var(--mv-text); font-family: var(--mv-mono); word-break: break-all; }
/* composer - a taller chat box; image + send sit in its bottom-right */
.hud-agent .ag-input-row { margin-top: 14px; }
.hud-agent .ag-composer {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--mv-panel-2);
  border: 1px solid var(--mv-border);
  border-radius: 10px;
  padding: 9px 9px 7px;
}
.hud-agent .ag-input {
  width: 100%;
  min-height: 34px;
  resize: none;
  background: transparent;
  border: none;
  outline: none;
  color: var(--mv-text);
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
}
.hud-agent .ag-input::placeholder { color: var(--mv-text-3); }
.hud-agent .ag-composer-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
}
.hud-agent .ag-image {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  color: var(--mv-text-3);
}
.hud-agent .ag-send {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: #7da2e0;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

.hud-imageviewer {
  left: 260px;
  top: 97px;
  width: 220px;
  max-height: 250px;
  overflow-y: auto;
}
.hud-imageviewer .iv-head {
  color: var(--mv-text);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.hud-imageviewer .iv-sub {
  color: var(--mv-text-3);
  font-size: 8px;
  letter-spacing: 0.08em;
  margin: 3px 0 6px;
}
.hud-imageviewer .iv-row {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border: 1px solid var(--mv-border-soft);
  border-radius: 3px;
  padding: 5px 7px;
  margin-bottom: 4px;
  cursor: default;
}
.hud-imageviewer .iv-row.sel {
  border-color: var(--mv-accent);
  background: var(--mv-panel-2);
}
.hud-imageviewer .iv-sensor { color: var(--mv-text); font-size: 9px; font-weight: 600; }
.hud-imageviewer .iv-id {
  color: var(--mv-text-2);
  font-family: var(--mv-mono);
  font-size: 8px;
  word-break: break-all;
  line-height: 1.4;
}
.hud-imageviewer .iv-meta { color: var(--mv-text-3); font-size: 8px; }
.hud-imageviewer .iv-actions { display: flex; gap: 4px; margin-top: 6px; }
.hud-imageviewer .iv-btn {
  flex: 1;
  background: var(--mv-panel-2);
  color: var(--mv-text-2);
  border: 1px solid var(--mv-border);
  border-radius: 3px;
  font: inherit;
  font-size: 9px;
  padding: 3px 4px;
  white-space: nowrap;
}

/* [C8] detection targets panel - top left (TARGET stage) */
.hud-dettargets {
  left: 200px;
  top: 44px;
  width: 216px;
}
.hud-dettargets .dt-head {
  color: var(--mv-text);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-bottom: 6px;
}
.hud-dettargets .dt-card {
  border: 1px solid var(--mv-border);
  border-radius: 4px;
  background: var(--mv-bg);
  padding: 7px 8px;
  margin-bottom: 8px;
}
.hud-dettargets .dt-label {
  color: var(--mv-text);
  font-size: 9px;
  font-weight: 600;
  margin-bottom: 4px;
  line-height: 1.4;
}
.hud-dettargets .dt-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 9px;
  line-height: 1.7;
}
.hud-dettargets .dt-row span:first-child { color: var(--mv-text-3); }
.hud-dettargets .dt-row span:last-child { color: var(--mv-text-2); font-family: var(--mv-mono); }
.hud-dettargets .dt-nominate {
  background: var(--mv-accent);
  color: #fff;
  border: none;
  border-radius: 3px;
  font: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-align: center;
  padding: 5px 0;
}

/* [C9] bottom status bar */
.chrome-statusbar {
  left: 0; right: 0; bottom: 0;
  height: 20px;
  border-left: none; border-right: none; border-bottom: none;
  background: var(--mv-bg);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 10px;
  font-size: 9px;
  color: var(--mv-text-3);
}
.chrome-statusbar .sb-item { white-space: nowrap; }
.chrome-statusbar .sb-spacer { flex: 1; }
.chrome-statusbar .ok { color: #4ade80; font-weight: 600; }

/* ============ HUD widgets (positions clear the chrome) ============ */

/* [UI-14] asset panel — right upper (Maven chrome, Foundry dark) */
#scene-host .hud-asset {
  right: 196px;
  top: 108px;
  width: 200px;
  font-family: var(--scene-mono), sans-serif;
}
.hud-asset .ap-head {
  font-size: 13px;
  font-weight: 600;
  color: var(--mv-text);
  letter-spacing: 0.1em;
  margin-bottom: 6px;
}
.hud-asset .ap-row {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  line-height: 1.7;
  color: var(--mv-text-2);
}
.hud-asset .ap-row span:first-child { color: var(--mv-text-3); }
.hud-asset .ap-status span:last-child { color: #4ade80; }

/* POI detail — the Maven "Selection" card: floating icon rail (bell /
   burger / messenger), black Selection header (burger + collapse
   buttons), the POI's still with its CV boxes (in-image labels), the
   Nominate target dropdown (opens the firing-solution menu for the
   detected stockpile — the ENGAGE step) and an inert Details row.
   Right-edge lane: FIRST card in the top-right, its RIGHT edge aligned
   with the top bar's asset dropdown (mv-asset): 10px top-bar padding +
   168px search box + 9px mv-right gap = 187px gutter (measured stage-
    local, stable across the take), then nudged 20px further right (189 ->
    169), then a further 80px (169 -> 89). Y unchanged at top 44; the
    .pd-rail hangs off the card's left edge (child, left -34px) and travels
    with it, keeping its proximity. The card auto-grows downward (no height
    cap — see .pd-body); it lives in the right-edge lane, clear of the
    left-lane asset-detail card. */
 #scene-host .hud-poidetail {
   right: 89px;
  top: 44px;
  width: 400px;
  padding: 0;
  overflow: visible;
  background: #1e1e20;
  border: 1px solid #333;
  border-radius: 4px;
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: #e8e8e8;
}
/* The card grows to fit its content — no scroll cap. The Details dropdown
   (strike report) must be fully readable during playback, where the card is
   click-through and a scrollbar is unreachable; the card extends downward as
   each landed salvo appends its block (the right-edge lane is clear of the
   left-lane asset-detail card, so growth never collides). */
#scene-host .hud-poidetail .pd-body {
  overflow: visible;
}
#scene-host .hud-poidetail .pd-rail {
  position: absolute;
  left: -34px;
  top: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
#scene-host .hud-poidetail .pd-ric {
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #1e1e20;
  border: 1px solid #333;
  border-radius: 4px;
  color: #9a9a9a;
}
#scene-host .hud-poidetail .pd-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: #0d0d0f;
  border-bottom: 1px solid #2a2a2a;
}
#scene-host .hud-poidetail .pd-title {
  color: #f7f7ef;
  font-family: var(--mv-title);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
#scene-host .hud-poidetail .pd-hbtns {
  margin-left: auto;
  display: flex;
  gap: 4px;
}
#scene-host .hud-poidetail .pd-hbtn {
  background: none;
  border: none;
  color: #8a8a8a;
  font-size: 16px;
  line-height: 1;
  padding: 2px 3px;
  cursor: pointer;
}
#scene-host .hud-poidetail .pd-photo {
  position: relative;
  background: #0b0303;
  margin: 0;
  overflow: hidden;
}
#scene-host .hud-poidetail .pd-photo.hidden { display: none; }
#scene-host .hud-poidetail .pd-photo-inner {
  position: relative;
  width: 100%;
  height: 220px;
  transition: transform 0.15s ease-out;
  transform-origin: center;
}
#scene-host .hud-poidetail .pd-photo img {
  display: block;
  width: 100%;
  height: 100%;
  /* contain: the whole satellite still is visible (letterboxed in the
     well's dark background) — never cropped. Boxes are positioned in the
     image's own coordinate space (see _drawPdBoxes). */
  object-fit: contain;
}
#scene-host .hud-poidetail .pd-boxes {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
#scene-host .hud-poidetail .pd-box {
  position: absolute;
  pointer-events: none;
}
#scene-host .hud-poidetail .pd-box.cyan,
#scene-host .hud-poidetail .pd-box.orange {
  /* 2026-10-06 design: solid CV lines in the scene yellow #ffe92b — chosen
     for legibility on the satellite stills, deliberately NOT the tribunal's
     --gold #ffd000 (that stays unique to the tribunal chrome). The 1px dark
     casing is what keeps a yellow line readable over bright terrain. */
  border: 1.5px solid #ffe92b;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55);
}
#scene-host .hud-poidetail .pd-box span {
  position: absolute;
  top: -14px;
  left: -1px;
  background: rgba(4, 4, 4, 0.85);
  color: #ffe92b;
  font-size: 11px;
  font-family: var(--mv-mono);
  letter-spacing: 0.05em;
  padding: 1px 4px;
  white-space: nowrap;
}
/* flagged as the military stockpile → red lines + red label */
#scene-host .hud-poidetail.pd-flagged .pd-box.cyan,
#scene-host .hud-poidetail.pd-flagged .pd-box.orange { border-color: #e0222b; }
#scene-host .hud-poidetail.pd-flagged .pd-box span { color: #e0222b; }
#scene-host .hud-poidetail .pd-box.pd-box-in span { top: 2px; left: 2px; }
#scene-host .hud-poidetail .pd-photo-ctl {
  position: absolute;
  top: 6px; right: 6px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  z-index: 2;
}
#scene-host .hud-poidetail .pd-photo-ctl.hidden { display: none; }
#scene-host .hud-poidetail .pd-nav { display: flex; gap: 4px; }
#scene-host .hud-poidetail .pd-nav button {
  width: 18px; height: 18px;
  border-radius: 3px;
  border: 1px solid #3a3a3a;
  background: rgba(10, 10, 10, 0.85);
  color: #cfcfcf;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
#scene-host .hud-poidetail .pd-thumb {
  width: 74px; height: 40px;
  object-fit: cover;
  display: block;
  border: 1.5px solid #3a3a3a;
  background: #0b0303;
  cursor: pointer;
  padding: 0;
}
#scene-host .hud-poidetail .pd-zoom {
  position: absolute;
  right: 6px; bottom: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: 2;
}
#scene-host .hud-poidetail .pd-zoom button {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: none;
  background: rgba(28, 28, 28, 0.92);
  color: #e8e8e8;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}


/* Map context menu (right-click, interactive mode) */
.map-menu {
  min-width: 170px;
  padding: 4px;
  z-index: 900;
}
.map-menu .mm-item {
  color: var(--mv-text-2);
  font-size: 10px;
  padding: 4px 8px;
  border-radius: 2px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.map-menu .mm-subitem { padding-left: 18px; }
.map-menu .mm-chev { color: var(--mv-text-3); }
.map-menu .mm-sub { display: none; }
.map-menu .mm-sub.open { display: block; }

/* [UI-6]+[UI-7] cross-check — top center (Maven chrome, Foundry dark) */
#scene-host .hud-crosscheck {
  left: 50%;
  top: 84px;
  transform: translateX(-50%);
  text-align: center;
  padding: 6px 14px;
  font-family: var(--scene-mono), sans-serif;
}
.hud-crosscheck .cc-close {
  position: absolute;
  top: 4px;
  right: 8px;
  color: var(--mv-text-3);
  font-size: 12px;
}
.hud-crosscheck .cc-title {
  font-family: var(--mv-title);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--mv-text-2);
}
.hud-crosscheck .cc-age {
  font-size: 10px;
  color: var(--mv-text-3);
  margin-top: 3px;
}

/* NO DETECTION chip — center */
.hud-nodet {
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  font-size: 12px;
  letter-spacing: 0.2em;
  color: #f87171;
  border: 1px dashed rgba(248, 113, 113, 0.7);
  background: rgba(30, 10, 12, 0.72);
}

/* [UI-4] track line — center right (Maven chrome, Foundry dark) */
#scene-host .hud-track {
  right: 196px;
  top: 44%;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--mv-text-3);
  padding: 6px 10px;
  font-family: var(--scene-mono), sans-serif;
}
.hud-track .tk-refresh { color: var(--mv-accent); }

/* cloud haze — full-screen sweep */
.hud-cloud {
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  padding: 0;
  border: none;
  background: radial-gradient(ellipse at 55% 45%, rgba(220, 228, 240, 0.5), rgba(220, 228, 240, 0.12) 55%, rgba(220, 228, 240, 0) 75%);
  animation: cloud-drift calc(3s / var(--spd, 1)) ease-in-out;
}
@keyframes cloud-drift {
  0% { opacity: 0; }
  30% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; }
}

/* [UI-8] COA panel — right middle (Maven chrome, Foundry dark) */
#scene-host .hud-coa {
  right: 196px;
  top: 56%;
  width: 210px;
  font-family: var(--scene-mono), sans-serif;
}
.hud-coa .coa-head {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--mv-text-2);
  margin-bottom: 2px;
}
.hud-coa .coa-src {
  color: var(--mv-text-3);
  font-size: 9px;
  margin-bottom: 6px;
}
.hud-coa .coa-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 10px;
  line-height: 1.7;
  color: var(--mv-text-2);
  border: 1px solid transparent;
  border-radius: 3px;
  padding: 2px 6px;
}
.hud-coa .coa-row b { color: var(--mv-text); }
.hud-coa .coa-row .coa-name { color: var(--mv-text-2); }
.hud-coa .coa-row.hl {
  color: var(--mv-text);
  background: var(--mv-panel-2);
  box-shadow: inset 0 -2px 0 var(--mv-accent);
}
.hud-coa .coa-row.hl b { color: var(--mv-text); }
.hud-coa .coa-row.hl .coa-name { color: var(--mv-text); }
.hud-coa .coa-gate {
  color: var(--mv-text-3);
  font-size: 8px;
  margin-top: 5px;
  line-height: 1.4;
}
.hud-coa .coa-analyze {
  margin-top: 5px;
  padding: 4px 0;
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--mv-text-2);
  background: var(--mv-panel-2);
  border: 1px solid var(--mv-border);
  border-radius: 3px;
}

/* [UI-9] status line — bottom center (Maven chrome, Foundry dark) */
#scene-host .hud-status {
  left: 50%;
  bottom: 64px;
  transform: translateX(-50%);
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--mv-text-2);
  padding: 6px 14px;
  font-family: var(--scene-mono), sans-serif;
}

/* [UI-10] strike sequence — right lower (Maven chrome, Foundry dark) */
#scene-host .hud-seq {
  right: 196px;
  bottom: 76px;
  width: 190px;
  font-family: var(--scene-mono), sans-serif;
}
.hud-seq .seq-head {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--mv-text-2);
  margin-bottom: 6px;
}
.hud-seq .seq-step {
  font-size: 10px;
  line-height: 1.9;
  letter-spacing: 0.1em;
  color: var(--mv-text-3);
}
.hud-seq .seq-step.checked { color: #4ade80; }
.hud-seq .seq-step.checked::before { content: '\2713 '; }
.hud-seq .seq-note { color: var(--mv-text-3); }
.hud-seq .seq-fire {
  margin-top: 8px;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.2em;
  color: #0a0a0c;
  background: #ef4444;
  border-radius: 4px;
  padding: 6px 0;
}

/* [UI-11] impact + BDA — center */
.hud-impact {
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: #fbbf24;
  border-color: rgba(251, 191, 36, 0.6);
  background: rgba(28, 20, 8, 0.8);
  animation: impact-flash 0.7s ease-out;
}
@keyframes impact-flash {
  0% { transform: translate(-50%, -50%) scale(1.6); opacity: 0; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
.hud-bda {
  left: 50%;
  top: 52%;
  transform: translateX(-50%);
  font-size: 10px;
  letter-spacing: 0.12em;
  color: #f87171;
  border-color: rgba(248, 113, 113, 0.5);
}

/* ============ scripted cursor (arrow + grab glyphs, click ring) ============ */

#scene-host .scene-cursor {
  position: absolute;
  width: 0;
  height: 0;
  z-index: 801; /* above the HUD within #scene-host's context */
  pointer-events: none;
}
#scene-host .scene-cursor svg {
  position: absolute;
  left: -2px;
  top: -2px;
  overflow: visible;
  display: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.7));
}
#scene-host .scene-cursor[data-glyph="arrow"] .cs-arrow { display: block; }
#scene-host .scene-cursor[data-glyph="grab"] .cs-grab { display: block; }
/* Click ring (2026-10-05) — the screen-share click affordance. A sibling of
   the cursor in .scene-hud, anchored at the CLICK point in host % (the same
   coordinate space as the cursor, so it scales with --stage-k). A plain
   translucent WHITE DISC, no outline — the scripted cursor glyph is already a
   white shape with its own dark drop shadow, so a ring around it reads as a
   second object; the disc is the screen-share convention (Screen Studio /
   Cursor Spotlight style) and it is the Maven HUD's own white-on-dark chrome
   language, not a new hue. js/maven/renderer/hud.js drives
   left/top/opacity/transform every frame as a pure function of t off the
   recorded press-downs — no CSS animation, so a seek lands mid-bloom and 2×
   playback stays glued to the click. */
#scene-host .scene-click-ring {
  position: absolute;
  width: 34px;
  height: 34px;
  border: none;
  background: rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.55);
  opacity: 0;
  pointer-events: none;
  z-index: 800; /* under the cursor glyph (801) */
}

/* ============ entity markers ============ */

/* asset markers (friendly fleet): divIcon silhouettes rotated toward the
   target (the stockpile) by _buildAssets — surface = ship hull, air = the
   MQ-9A planform. The state classes land on the wrapper div (like the POI
   bullseye), so hover/press/focus paint as glows, not SVG strokes */
#scene-host .asset-marker {
  cursor: default;
  /* must stay absolute: Leaflet positions marker icons with translate3d
     relative to the marker pane (same contract as .poi-bullseye) */
  position: absolute;
  width: 22px;
  height: 22px;
  background: none;
  border: none;
}
#scene-host .asset-marker .asset-ico { width: 100%; height: 100%; }
#scene-host .asset-marker .asset-ico svg { display: block; width: 100%; height: 100%; }
#scene-host .asset-marker:hover,
#scene-host .asset-marker.is-hover { filter: drop-shadow(0 0 2.5px rgba(124, 192, 255, 0.9)); }
#scene-host .asset-marker.is-active { filter: drop-shadow(0 0 3.5px rgba(255, 208, 0, 0.95)); }
#scene-host .asset-marker.is-focus { outline: 1px dashed rgba(153, 153, 153, 0.8); outline-offset: 2px; }

/* POI bullseye icon (divIcon): a black disc carrying a state-coloured
   ring + solid core (--poi-c: white default, amber threat, red confirmed
   target — set per frame by SceneRenderer._setPoiIconColor). Proportions
   follow the reference capture: ~2px black margin past the ring, ring and
   core gap ~2px, core ≈ ⅓ of the ring's diameter. */
 #scene-host .poi-bullseye {
   width: 16px;
   height: 16px;
   /* must stay absolute: Leaflet positions marker icons with translate3d
      relative to the marker pane — position:relative would offset every
      icon from its bbox/marker geometry */
   position: absolute;
  border-radius: 50%;
  background: #000;
}
#scene-host .poi-bullseye::before {
  content: '';
  position: absolute;
  inset: 2px;
  border: 2px solid var(--poi-c, #fff);
  border-radius: 50%;
}
#scene-host .poi-bullseye::after {
  content: '';
  position: absolute;
  inset: 6px;
  background: var(--poi-c, #fff);
  border-radius: 50%;
}

/* POI selection ring (interactive + replay) — the bullseye icon is a div,
   so the gold ring is a box-shadow hugging the black disc */
#scene-host .poi-selected {
  box-shadow: 0 0 0 2px #ffd000;
}

/* entity labels (Leaflet tooltips) — neutral base; POI labels are
   white in the suite and blue asset labels override below, so this
   default only guards against a gold fallback. */
#scene-host .scene-ent-label {
  background: rgba(8, 10, 14, 0.82);
  border: 1px solid var(--mv-border);
  border-radius: 3px;
  color: var(--mv-text);
  font-family: var(--mono, var(--scene-mono), monospace);
  font-size: 12px; /* 2026-09-07: 9 → 12, author scale-up of the POI
                     description labels (asset ship labels pin 9px below) */
  letter-spacing: 0.08em;
  padding: 2px 6px;
  box-shadow: none;
}
#scene-host .scene-ent-label::before { display: none; }
/* suite (interactive): POI labels appear on hover only — white on the
   black box, no outline. The recorded game keeps the yellow labels. */
#scene-host.interactive .scene-ent-label:not(.scene-asset-label) {
  border: none;
  color: #fff;
}
#scene-host .scene-asset-label {
  border-color: rgba(74, 158, 255, 0.55);
  color: #6db3ff;
  font-size: 9px; /* friendly-asset ship labels keep the pre-scale-up size —
                   the 2026-09-07 bump covers POI description labels only */
}

/* ============ interactive mode (suite) ============ */

/* in replay mode .scene-hud is pointer-events:none; the suite opts in
   per-element so the operator can actually operate the interface */
#scene-host.interactive .scene-interactive {
  pointer-events: auto;
}
#scene-host.interactive .scene-interactive,
#scene-host.interactive .scene-interactive * {
  cursor: default;
}
#scene-host.interactive .scene-interactive[data-action] {
  cursor: pointer;
}

/* map cursor: standard arrow by default; grabbing hand only while the
   map is actually being dragged (overrides Leaflet's .leaflet-grab,
   which puts a grab hand on the whole container when dragging is on).
   Note: Leaflet marks the drag state on document.body, not the container.
   NOT mode-gated (2026-10-08): the suite gets the hand from Leaflet's own
   drag state, and the game replay gets it from the same class stamped by
   `renderer/hud.js _applyCursor` off the recorded map drag — one rule,
   both hosts, so playback shows the hand the operator really had (the
   one-HUD contract; `.scene-map` is a direct child of #scene-host and
   keeps pointer-events, so its cursor is what the viewer's pointer shows
   through the pointer-events:none HUD). */
#scene-host .scene-map { cursor: default; }
body.leaflet-dragging #scene-host .scene-map { cursor: grabbing; }

/* symmetric hover/active/focus states:
   :hover/:active/:focus fire in interactive mode;
   .is-hover/.is-active/.is-focus are replayed on the same elements
   so a recorded take looks identical to a live session */

.chrome-topbar .tb-tab:hover, .chrome-topbar .tb-tab.is-hover { color: var(--mv-text-2); background: var(--mv-panel-2); }
.chrome-topbar .tb-tab:active, .chrome-topbar .tb-tab.is-active { background: #363636; color: var(--mv-text); }
.chrome-topbar .tb-select:hover, .chrome-topbar .tb-select.is-hover { border-color: #555; }
.chrome-topbar .tb-select:focus, .chrome-topbar .tb-select.is-focus { outline: none; border-color: var(--mv-accent); }
.chrome-left .cl-row:hover, .chrome-left .cl-row.is-hover { background: var(--mv-panel-2); }
.chrome-left .cl-row:active, .chrome-left .cl-row.is-active { background: #363636; }
.chrome-left .cl-row:focus, .chrome-left .cl-row.is-focus { outline: 1px solid #555; outline-offset: -1px; }
.chrome-left .cl-folder:hover, .chrome-left .cl-folder.is-hover,
.chrome-left .cl-tab:hover, .chrome-left .cl-tab.is-hover { color: var(--mv-text); background: var(--mv-panel-2); }
.chrome-left .cl-folder:active, .chrome-left .cl-folder.is-active,
.chrome-left .cl-tab:active, .chrome-left .cl-tab.is-active { background: #363636; }
.chrome-left .cl-search:hover, .chrome-left .cl-search:focus-within { border-color: #555; }
#scene-host .cl-search-input { pointer-events: none; } /* inert in replay */
#scene-host.interactive .cl-search-input { pointer-events: auto; }
.hud-poidetail .pd-nav button:hover, .hud-poidetail .pd-nav button.is-hover { border-color: #666; color: #fff; }
.hud-poidetail .pd-nav button:active, .hud-poidetail .pd-nav button.is-active { background: #2a2a2a; }
.hud-poidetail .pd-thumb:hover, .hud-poidetail .pd-thumb.is-hover { border-color: #add621; }
.hud-poidetail .pd-zoom button:hover, .hud-poidetail .pd-zoom button.is-hover { background: #3a3a3a; }
.hud-poidetail .pd-hbtn:hover, .hud-poidetail .pd-hbtn.is-hover { color: #fff; }
.hud-poidetail .pd-nomrow:hover:enabled, .hud-poidetail .pd-nomrow.is-hover:enabled { background: #333944; }
.hud-poidetail .fs-row:hover, .hud-poidetail .fs-row.is-hover { background: #23262c; }
.map-menu .mm-item:hover, .map-menu .mm-item.is-hover { background: var(--mv-panel-2); color: var(--mv-text, #e8e8e8); }
.hud-coa .coa-row:hover, .hud-coa .coa-row.is-hover { border-color: #555; }
.hud-coa .coa-row:active, .hud-coa .coa-row.is-active { background: var(--mv-panel-2); }
.hud-coa .coa-analyze:hover, .hud-coa .coa-analyze.is-hover { border-color: var(--mv-accent); color: var(--mv-text); }
.hud-coa .coa-analyze:active, .hud-coa .coa-analyze.is-active { background: #363636; }
.hud-seq .seq-fire:hover, .hud-seq .seq-fire.is-hover { background: #ff6a5e; }
.hud-seq .seq-fire:active, .hud-seq .seq-fire.is-active { background: #c73a30; }
.hud-crosscheck .cc-close:hover, .hud-crosscheck .cc-close.is-hover { color: var(--mv-text-2); }
.hud-crosscheck .cc-close:active, .hud-crosscheck .cc-close.is-active { color: var(--mv-text); }
.hud-imageviewer .iv-row:hover { border-color: #555; }
.hud-imageviewer .iv-row.is-hover { border-color: #555; }
.hud-imageviewer .iv-row:active, .hud-imageviewer .iv-row.is-active { background: var(--mv-panel-2); }
.hud-imageviewer .iv-btn:hover, .hud-imageviewer .iv-btn.is-hover { color: var(--mv-text); border-color: var(--mv-accent); }
.hud-imageviewer .iv-btn:active, .hud-imageviewer .iv-btn.is-active { background: #363636; }
.hud-dettargets .dt-nominate:hover, .hud-dettargets .dt-nominate.is-hover { background: #2563eb; }
.hud-dettargets .dt-nominate:active, .hud-dettargets .dt-nominate.is-active { background: #1d4ed8; }
.hud-agent .ag-input:focus, .hud-agent .ag-input.is-focus { outline: none; }
.hud-agent .ag-composer:focus-within { border-color: var(--mv-text-3); }
.hud-agent .ag-send:hover, .hud-agent .ag-send.is-hover { color: #a9c4ff; }
.hud-agent .ag-send:active, .hud-agent .ag-send.is-active { opacity: 0.7; }

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

/* ============ AIP agent notification badge ============ */
/* red dot on a topbar tab while the agent has a pending notice */
.chrome-topbar .tb-tab.has-badge { position: relative; }
.chrome-topbar .tb-tab.has-badge::after {
  content: '';
  position: absolute;
  top: 2px;
  right: 2px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #ff3b30;
  box-shadow: 0 0 5px rgba(255, 59, 48, 0.8);
  animation: blink 1.6s ease-in-out infinite;
}

/* ============ threat / confirmed POI labels ============ */
#scene-host .scene-ent-label.threat { color: #d97706; }

/* ============ strike marks + incoming badge ============ */
.strike-x {
  color: #ff3b30;
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  text-shadow: 0 0 6px rgba(255, 59, 48, 0.9);
  text-align: center;
}
.hud-strikein {
  position: absolute;
  z-index: 30;
  background: rgba(60, 10, 10, 0.92);
  border: 1px solid #ff3b30;
  border-radius: 3px;
  color: #ffb4ae;
  font-family: var(--mv-mono, monospace);
  font-size: 10px;
  letter-spacing: 0.08em;
  padding: 3px 8px;
  white-space: nowrap;
  pointer-events: none;
}


/* ============ agent transcript additions ============ */
/* the agent's proactive notification turn reads alert-coloured */
.hud-agent .ag-notice .ag-answer { color: #ffb4ae; }
/* per-turn status lines (context / prompt) are quieter than DSL steps */
.hud-agent .ag-status { color: var(--mv-text-3); }
/* ============ Selection card actions ============
   Nominate target — dropdown-style row, wired only for the confirmed
   (detected) stockpile; opens the firing-solution menu (the ENGAGE
   step). Details — inert dropdown-style row (DOM-only). */
#scene-host .hud-poidetail .pd-nomrow {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 12px;
  background: #0d0d0f;
  border: none;
  border-top: 1px solid #20232a;
  color: #f7f7ef;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-align: left;
  cursor: pointer;
}
#scene-host .hud-poidetail .pd-nomrow:disabled { color: #6a7282; cursor: default; }
#scene-host .hud-poidetail .pd-nom-ic { width: auto; height: auto; background: none; border: none; color: inherit; }
#scene-host .hud-poidetail .pd-chev { margin-left: auto; font-size: 12px; color: #8a8a8a; }
#scene-host .hud-poidetail .pd-firesol {
  padding: 6px 10px 8px;
  background: #17181c;
  border-top: 1px solid #20232a;
}
#scene-host .hud-poidetail .pd-vfrow {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 12px;
  background: #0d0d0f;
  border-top: 1px solid #20232a;
  color: #f7f7ef;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: default;
}
#scene-host .hud-poidetail .pd-vf-ic { width: auto; height: auto; background: none; border: none; color: inherit; }
#scene-host .hud-poidetail .pd-videofeed { display: none; }
#scene-host .hud-poidetail .pd-videofeed.on {
  display: block;
  width: 100%;
  aspect-ratio: 400/310;
  background: #000;
  border-top: 1px solid #20232a;
  position: relative;
}
#scene-host .hud-poidetail .pd-videofeed canvas { display: block; width: 100%; height: auto; }
#scene-host .hud-poidetail .fs-label {
  color: #8a8a8a;
  font-size: 12px;
  letter-spacing: 0.08em;
  margin-bottom: 4px;
}
#scene-host .hud-poidetail .fs-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 8px;
  background: none;
  border: none;
  border-radius: 3px;
  color: #cfcfcf;
  font-size: 13px;
  letter-spacing: 0.02em;
  text-align: left;
  cursor: pointer;
}
#scene-host .hud-poidetail .fs-row.sel { color: #ffd000; }
#scene-host .hud-poidetail .fs-row.arming .fs-readout { color: #ffd000; }
#scene-host .hud-poidetail .fs-row.incoming .fs-readout { color: #ff4d55; }
#scene-host .hud-poidetail .fs-readout {
  margin-left: auto;
  font-family: var(--mv-mono, monospace);
  font-size: 12px;
  letter-spacing: 0.05em;
  white-space: nowrap;
}
#scene-host .hud-poidetail .pd-detrow {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  background: #0d0d0f;
  border-top: 1px solid #20232a;
  color: #f7f7ef;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
}
#scene-host .hud-poidetail .pd-detrow .pd-chev { transition: transform 0.15s ease; }
#scene-host .hud-poidetail .pd-detrow.open .pd-chev { transform: rotate(180deg); }
/* Strike report (Details dropdown body): one three-line block per landed
   salvo, appended under the Details row (see _syncStrikeDetails). */
#scene-host .hud-poidetail .pd-detdata {
  border-top: 1px solid #20232a;
  padding: 7px 12px 10px;
}
#scene-host .hud-poidetail .pd-strike { padding: 2px 0; }
#scene-host .hud-poidetail .pd-strike + .pd-strike {
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px dashed #262a33;
}
#scene-host .hud-poidetail .pd-strike-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  line-height: 1.8;
}
#scene-host .hud-poidetail .pd-strike-row span:first-child {
  color: #8a8a8a;
  letter-spacing: 0.05em;
}
#scene-host .hud-poidetail .pd-strike-row span:last-child {
  color: #cfcfcf;
  font-family: var(--mv-mono, monospace);
  font-size: 12px;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
/* ============ live satellite downlink (LiveFeed) ============
   Session-visual overlay for the SATELLITE view only (js/live-feed.js,
   instantiated by BOTH index.html and suite.html — the downlink was on
   screen during capture, so the game's replay shows the same scene chrome
   the suite records). The readout chips sit at the stage's bottom-center;
   the canvas over-effects that once washed the imagery (cloud shadows,
   grain, the frame-push sweep, the sync glitch) are removed. */

.live-feed-hud {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  z-index: 802;
  display: flex;
  gap: 5px;
  pointer-events: none;
  font-family: var(--mv-mono), monospace;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.09em;
  white-space: nowrap;
}
.live-feed-hud.hidden { display: none; }

.lf-chip {
  padding: 3px 7px;
  background: rgba(10, 10, 14, 0.68);
  border: 1px solid rgba(160, 175, 190, 0.22);
  border-radius: 3px;
  color: var(--mv-text-2);
  backdrop-filter: blur(4px);
}

.lf-live { color: #4ade80; }
.lf-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 5px;
  border-radius: 50%;
  background: #4ade80;
  animation: lf-pulse 1.4s ease-in-out infinite;
}
@keyframes lf-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

.lf-link.lf-warn {
  color: #f59e0b;
  border-color: rgba(245, 158, 11, 0.4);
}

/* ============ map icon clusters (cosmetic) ============ */
/* The two real-Maven map-edge clusters: bottom-left stack (expand / pin /
   monitor / grid / eraser / upload-ghost / camera) + compass circle, and
   the bottom-right stack (route / legend / zoom group / clock /
   broadcast). Purely decorative — no data-element-id, no handlers, no
   host gating (one-HUD contract: both hosts get them). Geometry is
   1920×1080 stage px; the containers sit inside .scene-hud (z-index 800
   band — above .scene-map, below the scripted cursor at 801) and inherit
   its pointer-events:none. */

.mi-left {
  position: absolute;
  left: 268px; /* hugs the LAYERS panel's right edge (panel is 0–252) */
  bottom: 30px;
  display: flex;
  align-items: flex-end; /* compass bottom-aligned with the camera slot */
  gap: 8px;
}
.mi-stack {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.mi-btn {
  width: 30px;
  height: 30px;
  background: #3a3f46;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mi-btn svg { display: block; }
.mi-ghost { background: transparent; } /* upload slot — no background */
.mi-compass {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
}

.mi-right {
  position: absolute;
  right: 10px;
  bottom: 12px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px; /* between groups */
}
.mi-group {
  display: flex;
  flex-direction: column;
  gap: 4px; /* within a group */
}
.mi-zoomgrp {
  width: 30px;
  align-items: center; /* dots centered on the zoom container */
  gap: 0;
}
.mi-dot {
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: #8a8f96;
  margin: 4px 0; /* ~4px above / below the container */
}
.mi-zoom {
  display: flex;
  flex-direction: column;
  background: #3a3f46;
  border-radius: 3px;
}
.mi-zoom .mi-btn {
  background: transparent;
  border-radius: 0;
}

/* ==== SPEAKER BADGE (voice cue, 2026-10-24 — the one appended block) ====
   While a `Cmdr*`-speaker voice window (data/maven/audio.json — the
   Roosevelt's crew, the soldier's voice on this case's radio) is ACTIVE,
   js/app.js onTimeUpdate stamps `.speaking` on the uss_roosevelt map-label
   tooltip element + the asset_uss_roosevelt LAYERS row — a pure fn of t,
   change-gated, converging per tick. The Asgard .speaking badge pattern
   ported (css/asgard/asgard.css): the glyph is fixed by its own colour (a
   ::after background-image, never the scheme's), so no hover/selection
   state can hide it — the map glyph is the asset blue #4a9eff (the
   ship-icon blue), the list glyph is white. */
/* Map label (the permanent Leaflet tooltip above the ship icon): the glyph
   sits to the RIGHT of the label text, inside the label box. */
#scene-host .scene-asset-label.speaking::after {
  content: "";
  display: inline-block;
  width: 12px; height: 12px;
  margin-left: 4px;
  vertical-align: -2px;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%234a9eff' d='M1.5 5.5h3.4L9 2.2v11.6L4.9 10.5H1.5z'/%3E%3Cpath fill='none' stroke='%234a9eff' stroke-width='1.6' stroke-linecap='round' d='M11.3 5.4a3.5 3.5 0 0 1 0 5.2M13.4 3.5a6.3 6.3 0 0 1 0 9'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* LAYERS panel — the Friendly Assets row: the glyph sits to the RIGHT of
   the name (inline flow in the label cell — the other rows stay clean). */
#scene-host .cl-row[data-element-id="asset_uss_roosevelt"].speaking .cl-label::after {
  content: "";
  display: inline-block;
  width: 12px; height: 12px;
  margin-left: 9px;
  vertical-align: -2px;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23ffffff' d='M1.5 5.5h3.4L9 2.2v11.6L4.9 10.5H1.5z'/%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='1.6' stroke-linecap='round' d='M11.3 5.4a3.5 3.5 0 0 1 0 5.2M13.4 3.5a6.3 6.3 0 0 1 0 9'/%3E%3C/svg%3E") center / contain no-repeat;
}
