/* Self-hosted fonts (NATOware pass, JUL03): B612 is the Airbus cockpit family;
   Saira Condensed is the chassis stencil face. No external font requests. */
@font-face {
  font-family: "B612 Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/B612Mono-400.woff2") format("woff2");
}

@font-face {
  font-family: "B612 Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/B612Mono-700.woff2") format("woff2");
}

@font-face {
  font-family: "B612";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/B612-400.woff2") format("woff2");
}

@font-face {
  font-family: "B612";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/B612-700.woff2") format("woff2");
}

@font-face {
  font-family: "Saira Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/SairaCondensed-400.woff2") format("woff2");
}

@font-face {
  font-family: "Saira Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/SairaCondensed-600.woff2") format("woff2");
}

:root {
  /* ── NATOware material layer (docs/spec/blueprints/Completed/JUL03_NATOWARE_DESIGN_GUIDE_PASS.md) ──
     Every element is either CHASSIS (grey-green polymer, room-lit, never glows)
     or GLASS (emissive phosphor display); the boundary is always a bezel/gasket. */
  --chassis-950: #0a0d0b;
  --chassis-900: #101511;
  --chassis-850: #161c17;
  --chassis-800: #1c231d;
  --chassis-700: #242c25;
  --chassis-600: #2d372e;
  --chassis-500: #38443a;
  --keycap-500: #4a4d4b;
  --keycap-600: #3b3e3c;
  --keycap-700: #2d302e;
  --keycap-800: #202221;
  --gasket: #060807;
  --bezel-hi: rgba(255, 255, 255, 0.09);
  --bezel-lo: rgba(0, 0, 0, 0.72);
  --stencil: rgba(216, 226, 217, 0.8);
  --stencil-dim: rgba(216, 226, 217, 0.48);
  --glass-bg: #141416;
  --phos-green: #9ef0b4;
  --phos-green-hot: #46e88c;
  --phos-green-dim: rgba(122, 214, 156, 0.4);
  --phos-amber: #ffc46b;
  --phos-amber-hot: #feb300;
  --lamp-green: #3dff7c;
  --lamp-amber: #ffb300;
  --lamp-red: #ff4f4f;

  /* Ordnance paints — munition-card painted bodies only. The one sanctioned painted
     chassis family: flat matte purpose-coded paint (design guide §5, Munition card). */
  --paint-anti-craft: #55401f;
  --paint-strike: #37481f;
  --paint-defense: #2b4050;
  --paint-deployable: #4b3024;
  --paint-support: #443053;

  /* Faction symbology channel — map/Gantt markers only, never UI chrome. */
  --side-blue: #00daf3;
  --side-blue-rgb: 0, 218, 243;
  /* OCT23 Blue player colors: one fixed color per Blue seat (P1 is side blue). */
  --blue-player-2: #3d7cff;
  --blue-player-2-rgb: 61, 124, 255;
  --blue-player-3: #9a8cff;
  --blue-player-3-rgb: 154, 140, 255;
  /* Teal sits closest to P1 cyan, so it goes to the rarest seat. */
  --blue-player-4: #14b88f;
  --blue-player-4-rgb: 20, 184, 143;
  --owner-rgb: var(--side-blue-rgb);

  /* ── Semantic layer (legacy names re-pointed at the NATOware ramp) ── */
  --background-obsidian: var(--chassis-950);
  --background-deep: #0e120f;
  --surface: #151a16;
  --surface-lowest: #0e120f;
  --surface-low: #1a201b;
  --surface-mid: #202722;
  --surface-high: #2a332c;
  --surface-highest: #364039;
  --border: #2b352d;
  --outline: #93a296;
  --outline-soft: #48544b;
  --text: #d8e2d9;
  --muted: #9fae9f;
  --primary: var(--phos-green);
  --primary-hot: var(--phos-green-hot);
  --primary-fill: #3de391;
  --secondary: #ffd799;
  --secondary-hot: #feb300;
  --green: #00e676;
  --red: #ff5252;
  --purple: #a855f7;
  --panel: rgba(19, 24, 20, 0.92);
  --panel-strong: rgba(13, 17, 14, 0.96);
  --mono: "B612 Mono", "Cascadia Mono", "Consolas", "Courier New", monospace;
  --body: "B612", "Segoe UI", Arial, sans-serif;
  --display: "Saira Condensed", "Segoe UI Semibold", "Arial Narrow", sans-serif;

  /* Sensor Band Hues */
  --friendly-sensor-x: hsla(190, 100%, 50%, 0.20); /* Cyan */
  --friendly-sensor-w: var(--friendly-sensor-x);
  --friendly-sensor-y: var(--friendly-sensor-x);

  --enemy-sensor-w: hsla(345, 100%, 60%, 0.15);    /* Crimson */
  --enemy-sensor-x: hsla(30, 100%, 55%, 0.20);     /* Orange */
  --enemy-sensor-y: hsla(55, 100%, 50%, 0.25);     /* Yellow */

  /* ── Cabinet Backdrop Gradient ──
     Allows swapping the ambient backdrop theme.
     - NATOware Green (original): top #121713, bottom var(--chassis-950)
     - Deep Khaki (active):       top #24211a, bottom #12100c
     - Alternate Warm Khaki:     top #29241b, bottom #14120d
     - Alternate Subtle Khaki:   top #1d1b14, bottom #0f0e0a
  */
  --backdrop-top: #24211a;
  --backdrop-bottom: #12100c;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  min-height: 100%;
}

body {
  color: var(--text);
  font-family: var(--body);
  background: var(--background-obsidian);
  overflow-x: hidden;
}

button,
input,
select,
textarea {
  font: inherit;
}

/* Momentary key: molded keycap on the chassis. Bevel out at rest, seated and
   inverted on :active. Legend is stencil ink, not phosphor — keys are chassis. */
button,
.console-link {
  border: 1px solid var(--gasket);
  color: var(--stencil);
  background: linear-gradient(180deg, var(--keycap-500), var(--keycap-600) 55%, var(--keycap-700));
  border-radius: 3px;
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 -2px 3px rgba(0, 0, 0, 0.4),
    0 1px 2px rgba(0, 0, 0, 0.55);
  cursor: pointer;
  letter-spacing: 0.08em;
  min-height: 36px;
  padding: 0.55rem 0.75rem;
  text-transform: uppercase;
  text-decoration: none;
  font-family: var(--mono);
  font-size: 0.72rem;
}

button:hover,
.console-link:hover {
  color: #f2f7f2;
  background: linear-gradient(180deg, #545755, var(--keycap-500) 55%, var(--keycap-600));
}

button:active:not(:disabled),
.console-link:active {
  background: linear-gradient(180deg, var(--keycap-700), var(--keycap-800));
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.65),
    inset 0 -1px 0 var(--bezel-hi);
  transform: translateY(1px);
}

/* Backlit key: a selected/latched key lights its legend (MFD convention). */
button.active,
button[aria-pressed="true"] {
  color: var(--phos-green-hot);
  text-shadow: 0 0 7px rgba(70, 232, 140, 0.7);
}

button:disabled,
input:disabled,
select:disabled,
textarea:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Data-entry fields read as small glass chips inset into the chassis:
   phosphor text on near-black, recessed under a gasket edge. */
input,
select,
textarea {
  width: 100%;
  min-height: 34px;
  border: 1px solid var(--gasket);
  color: var(--phos-green);
  background: var(--glass-bg);
  border-radius: 2px;
  box-shadow:
    inset 0 2px 5px rgba(0, 0, 0, 0.7),
    0 1px 0 var(--bezel-hi);
  padding: 0.5rem 0.6rem;
  font-family: var(--mono);
  font-size: 0.82rem;
}

input:focus,
select:focus,
textarea:focus {
  outline: 1px solid var(--phos-green-dim);
  outline-offset: 1px;
}

input::placeholder,
textarea::placeholder {
  color: var(--phos-green-dim);
}

textarea {
  resize: vertical;
}

label {
  display: grid;
  gap: 0.25rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

::-webkit-scrollbar {
  width: 7px;
  height: 7px;
}

::-webkit-scrollbar-track {
  background: var(--surface-lowest);
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border: 1px solid var(--surface-high);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--primary-hot);
}

.command-shell {
  min-height: 100vh;
  position: relative;
  isolation: isolate;
}

/* Cabinet backdrop: matte polymer under overhead room light — no starfield. */
.space-backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(ellipse at 50% -10%, rgba(255, 255, 255, 0.05), transparent 55%),
    linear-gradient(180deg, var(--backdrop-top), var(--backdrop-bottom));
}

.space-backdrop::before,
.space-backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.space-backdrop::before {
  /* fine molded-polymer grain */
  opacity: 0.5;
  background-image:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.012) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 4px);
}

.space-backdrop::after {
  opacity: 0.35;
  background: radial-gradient(ellipse at 50% 115%, rgba(0, 0, 0, 0.55), transparent 60%);
}

.brand-lockup,
.toolbar,
.row,
.button-pair {
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

.login-brand {
  padding: 0 0 1.25rem;
}

.brand-mark {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
}

.brand-mark svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Engraved chassis headings: condensed stencil face, light catch below the cut. */
.brand-lockup h1,
.panel h2,
.login-card h2,
.lobby-panel h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stencil);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.85), 0 2px 1px rgba(255, 255, 255, 0.05);
}

.brand-lockup h1 {
  font-size: 1.35rem;
  text-transform: uppercase;
}

.brand-lockup p {
  margin: 0.1rem 0 0;
  color: var(--primary-hot);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Readout chips: small glass windows set into the chassis. */
.badge,
.meta-chip,
.data-readout {
  border: 1px solid var(--gasket);
  background: var(--glass-bg);
  color: var(--phos-green-dim);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.7), 0 1px 0 var(--bezel-hi);
  border-radius: 2px;
  padding: 0.42rem 0.65rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.meta-chip strong,
.badge:not(.muted) {
  color: var(--primary);
}

.badge.side-blue {
  color: var(--side-blue);
  border-color: rgba(var(--side-blue-rgb), 0.4);
}

.badge.side-red {
  color: var(--red);
  border-color: rgba(255, 82, 82, 0.4);
}

/* T2 instrument panel: flat-molded chassis plate, no translucency, no garnish. */
.panel {
  border: 1px solid var(--gasket);
  background: linear-gradient(180deg, var(--chassis-800), var(--chassis-850));
  border-radius: 4px;
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 2px 8px rgba(0, 0, 0, 0.45);
  padding: 0.9rem;
  min-width: 0;
}

.panel-heading {
  display: grid;
  gap: 0.2rem;
  margin-bottom: 0.75rem;
}

.panel-heading.split {
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
}

/* Stencil placard: screen-printed caption on the chassis. */
.eyebrow {
  color: var(--stencil-dim);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.hint {
  color: var(--muted);
  margin: 0 0 0.65rem;
  font-size: 0.86rem;
}

.player-login {
  width: min(1520px, calc(100vw - 2rem));
  min-height: 100vh;
  margin: 0 auto;
  padding: 2rem 0 5.5rem;
}

.player-select-panel {
  min-height: calc(100vh - 7.5rem - 65px);
  display: flex;
  flex-direction: column;
}

.login-state-field {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.player-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  flex: 1;
  align-content: start;
}

.player-column {
  display: grid;
  gap: 0.75rem;
  align-content: start;
}

.player-column h3 {
  margin: 0;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--outline-soft);
  color: var(--primary);
  background: rgba(10, 15, 11, 0.72);
  border-radius: 3px;
  font-family: var(--display);
  font-size: 0.92rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.player-column.red-force h3 {
  color: var(--red);
}

.player-slot {
  min-width: 0;
}

.player-card {
  width: 100%;
  min-height: 78px;
  display: grid;
  grid-template-columns: 54px minmax(0, 1fr) auto;
  gap: 0.8rem;
  align-items: center;
  text-align: left;
  color: var(--text);
  background:
    linear-gradient(90deg, rgba(0, 218, 243, 0.16), transparent 42%),
    linear-gradient(180deg, rgba(21, 27, 22, 0.95), rgba(10, 15, 11, 0.95));
}

.player-card.hostile {
  background:
    linear-gradient(90deg, rgba(255, 82, 82, 0.16), transparent 42%),
    linear-gradient(180deg, rgba(21, 27, 22, 0.95), rgba(10, 15, 11, 0.95));
}

.player-card span {
  display: grid;
  place-items: center;
  justify-self: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--primary-hot);
  color: var(--primary);
  background: rgba(0, 218, 243, 0.08);
  clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
}

.player-card.hostile span {
  border-color: rgba(255, 82, 82, 0.72);
  color: var(--red);
  background: rgba(255, 82, 82, 0.08);
}

.player-card strong,
.player-card em,
.slot-code {
  min-width: 0;
  overflow-wrap: anywhere;
}

.player-card strong {
  display: block;
  color: var(--primary);
  font-family: var(--display);
  font-size: 1rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.player-card.hostile strong {
  color: var(--red);
}

.player-card em,
.slot-code {
  color: var(--muted);
  font-style: normal;
  font-size: 0.68rem;
}

.player-card em {
  justify-self: end;
  white-space: nowrap;
}

.player-card .slot-code {
  color: var(--secondary-hot);
}

.player-slot.selected .player-card {
  border-color: var(--primary-hot);
  box-shadow: 0 0 0 1px rgba(70, 232, 140, 0.28), inset 0 0 24px rgba(70, 232, 140, 0.08);
}

.player-slot.selected .player-card.hostile {
  border-color: rgba(255, 82, 82, 0.78);
  box-shadow: 0 0 0 1px rgba(255, 82, 82, 0.28), inset 0 0 24px rgba(255, 82, 82, 0.08);
}

.password-drawer {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  border: 1px solid var(--border);
  border-top: 0;
  background: rgba(10, 15, 11, 0.82);
  border-radius: 0 0 3px 3px;
  padding: 0 0.75rem;
  transition: max-height 180ms ease, opacity 180ms ease, padding 180ms ease;
}

.player-slot.selected .password-drawer {
  max-height: 96px;
  opacity: 1;
  padding: 0.75rem;
}

.password-drawer label {
  margin: 0;
}

/* Login-screen lobby readout: live scenario/phase in the panel heading. */
.lobby-readout {
  display: grid;
  gap: 0.2rem;
  text-align: right;
  min-width: 0;
}

.lobby-readout strong {
  color: var(--primary);
  font-family: var(--display);
  font-size: 1.2rem;
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
}

.lobby-readout span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Slot occupancy pill riding the top-right edge of a player card. */
.player-slot {
  position: relative;
}

.slot-presence {
  position: absolute;
  top: -0.45rem;
  right: 0.6rem;
  z-index: 1;
  padding: 0.1rem 0.45rem;
  border: 1px solid var(--outline-soft);
  border-radius: 2px;
  background: var(--chassis-950);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.slot-presence[data-presence="online"] {
  color: var(--lamp-green);
  border-color: rgba(61, 255, 124, 0.5);
}

.slot-presence[data-presence="joined"] {
  color: var(--phos-amber);
  border-color: rgba(255, 196, 107, 0.4);
}

/* Server-connectivity lamp + game version in the login action bar. */
.lobby-meta {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.server-indicator {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.server-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--lamp-red);
  box-shadow: 0 0 6px rgba(255, 79, 79, 0.55);
}

.server-dot[data-state="online"] {
  background: var(--lamp-green);
  box-shadow: 0 0 6px rgba(61, 255, 124, 0.55);
}

.game-version {
  color: var(--secondary-hot);
}

.login-action-bar {
  position: sticky;
  bottom: 1rem;
  z-index: 5;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto minmax(220px, 320px);
  gap: 1rem;
  align-items: center;
  margin-top: 1rem;
  padding: 0.9rem;
  border: 1px solid var(--border);
  background: rgba(8, 11, 9, 0.94);
  backdrop-filter: blur(12px);
  border-radius: 3px;
}

.login-grid {
  width: min(1520px, calc(100vw - 2rem));
  min-height: 100vh;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(320px, 480px) minmax(0, 1fr);
  gap: 1rem;
  align-items: stretch;
  padding: 2rem 0;
}

.login-card,
.lobby-panel {
  min-height: 680px;
  display: flex;
  flex-direction: column;
}

.login-card {
  justify-content: center;
}

.danger-action {
  color: var(--red);
  background: transparent;
  border-color: var(--red);
  font-weight: 700;
}

.danger-action[data-armed="true"] {
  color: #1f0000;
  background: var(--red);
}

.primary-action {
  width: 100%;
  color: #001f24;
  background: linear-gradient(180deg, var(--primary), var(--primary-hot));
  border-color: var(--primary);
  font-weight: 700;
}

.telemetry-box,
.summary-card,
.slot,
.stat-card {
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  padding: 0.75rem;
  border-radius: 3px;
}

.telemetry-box {
  display: flex;
  justify-content: space-between;
  margin-top: 1rem;
  color: var(--muted);
  font-family: var(--mono);
  text-transform: uppercase;
}

.telemetry-box strong,
.slot em {
  color: var(--green);
  font-style: normal;
}

.force-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}

.force-grid h3 {
  color: var(--primary);
  border-bottom: 1px solid var(--outline-soft);
  margin: 0 0 0.8rem;
  padding-bottom: 0.55rem;
  font-family: var(--display);
  text-transform: uppercase;
}

.force-grid h3.hostile,
.slot.hostile strong {
  color: var(--red);
}

.slot {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) auto;
  gap: 0.75rem;
  align-items: center;
  margin-bottom: 0.7rem;
  font-family: var(--mono);
  text-transform: uppercase;
}

.slot span {
  display: grid;
  place-items: center;
  height: 34px;
  border: 1px solid var(--outline);
  color: var(--primary);
}

.slot strong {
  min-width: 0;
  overflow-wrap: anywhere;
}

.slot.open {
  opacity: 0.48;
  border-style: dashed;
}

.workstation {
  min-height: 100vh;
  height: 100vh;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  position: relative;
}

.side-rail {
  border-right: 2px solid var(--gasket);
  background: linear-gradient(90deg, var(--chassis-800), var(--chassis-850));
  box-shadow: inset -1px 0 0 var(--bezel-hi);
  padding: 0.75rem 0.55rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  position: sticky;
  top: 0;
  height: 100vh;
}

/* Brand mark relocated from the retired top app bar: sits above the MFD keys. */
.rail-brand {
  margin: 0 auto 0.35rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--gasket);
  width: 44px;
  height: auto;
}

.rail-brand svg {
  width: 38px;
  height: 38px;
  margin: 0 auto;
}

.rail-tabs,
.rail-actions {
  display: grid;
  gap: 0.5rem;
}

.rail-actions {
  margin-top: auto;
}

.rail-button {
  width: 44px;
  min-height: 44px;
  padding: 0;
  display: grid;
  place-items: center;
}

.rail-actions .rail-button {
  font-size: 0.66rem;
}

/* Logout key: same red polymer casting as the RDY arm key. */
.logout-rail {
  color: #ffd7d7;
  background: linear-gradient(180deg, #83322b, #6b241f 55%, #521915);
  font-size: 0.58rem;
  line-height: 1.3;
  padding: 0.3rem 0.15rem;
  text-align: center;
  white-space: normal;
}

.logout-rail:hover {
  color: #ffe9e9;
  background: linear-gradient(180deg, #96423a, #83322b 55%, #6b241f);
}

.logout-rail:active:not(:disabled) {
  background: linear-gradient(180deg, #521915, #3d100d);
}

/* Rail = the canonical backlit MFD key column. Unlit legend at rest (standby),
   lit phosphor-green legend + faint cap glow when the view is selected. */
.rail-button {
  color: var(--stencil-dim);
}

.rail-button.active {
  color: var(--phos-green-hot);
  text-shadow: 0 0 8px rgba(70, 232, 140, 0.8);
  background: linear-gradient(180deg, var(--keycap-600), var(--keycap-700));
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 0 12px rgba(70, 232, 140, 0.16),
    0 1px 2px rgba(0, 0, 0, 0.55);
}

.rail-button.hostile-rail {
  color: rgba(255, 122, 122, 0.6);
}

.rail-button.hostile-rail.active {
  color: var(--lamp-red);
  text-shadow: 0 0 8px rgba(255, 82, 82, 0.8);
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 0 12px rgba(255, 82, 82, 0.16),
    0 1px 2px rgba(0, 0, 0, 0.55);
}

.ready-toggle {
  width: 44px;
  min-height: 44px;
  display: grid;
  place-items: center;
  gap: 0;
  border: 1px solid rgba(255, 82, 82, 0.7);
  color: var(--red);
  background: rgba(255, 82, 82, 0.1);
  border-radius: 3px;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
}

.ready-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.ready-toggle.ready {
  border-color: rgba(0, 230, 118, 0.7);
  color: var(--green);
  background: rgba(0, 230, 118, 0.1);
}

.command-content {
  padding: 0.75rem;
  display: grid;
  gap: 0.75rem;
  min-width: 0;
  min-height: 0;
  align-content: start;
  overflow: auto;
}

.command-strip {
  padding: 0.65rem;
}

.command-status {
  justify-content: space-between;
}

.admin-panel {
  border-color: rgba(254, 179, 0, 0.42);
}

.admin-slot-control {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.admin-slot-control .panel-heading {
  margin-bottom: 0;
}

.admin-slot-control h3 {
  margin: 0;
  font-size: 1rem;
}

.map-diameter-field {
  max-width: 150px;
}

.toolbar.wrap,
.row.wrap {
  flex-wrap: wrap;
}

.toolbar label,
.row label {
  min-width: 150px;
}

.status-row {
  display: grid;
  gap: 0.25rem;
  margin-top: 0.4rem;
}

.status {
  min-height: 1.1rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.78rem;
}

.status.ok {
  color: var(--green);
}

.status.bad {
  color: var(--red);
}

.phase-status-banner {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) minmax(280px, auto) auto;
  gap: 0.75rem;
  align-items: center;
  margin: 0.75rem 0;
  padding: 0.75rem;
  border: 1px solid rgba(254, 179, 0, 0.36);
  background: rgba(18, 22, 28, 0.78);
  border-radius: 3px;
}

.phase-status-banner.ok {
  border-color: rgba(0, 230, 118, 0.42);
}

.live-sync-banner {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  justify-content: space-between;
  margin: 0.75rem 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid rgba(254, 179, 0, 0.5);
  background: rgba(38, 30, 12, 0.85);
  font-size: 0.85rem;
  border-radius: 3px;
}

.live-sync-banner button {
  flex: 0 0 auto;
}

.draft-sync-indicator {
  margin: 0.4rem 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.74rem;
  text-align: right;
  text-transform: uppercase;
}

/* The draft state belongs with the current player identity, not in its own
   command-content row. Keep it compact enough to read as a third bezel chip. */
.bezel-session-strip .draft-sync-indicator {
  margin: 0;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  line-height: 1;
  white-space: nowrap;
}

.draft-sync-indicator[data-state="conflict"] {
  color: var(--red);
}

.draft-sync-indicator[data-state="recovered"] {
  color: var(--green);
}

.draft-conflict-banner {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  margin: 0.75rem 0;
  padding: 0.75rem;
  border: 1px solid rgba(255, 82, 82, 0.65);
  background: rgba(46, 16, 16, 0.9);
  font-size: 0.82rem;
  border-radius: 3px;
}

.draft-conflict-banner[hidden] {
  display: none;
}

.draft-conflict-banner > div:first-child {
  min-width: 0;
  flex: 1;
}

.draft-conflict-banner strong,
.draft-conflict-banner span {
  display: block;
  margin-bottom: 0.3rem;
}

.draft-conflict-actions {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.draft-conflict-compare {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.draft-conflict-compare pre {
  max-height: 14rem;
  margin: 0.2rem 0 0;
  padding: 0.45rem;
  overflow: auto;
  background: rgba(0, 0, 0, 0.28);
  white-space: pre-wrap;
}

.phase-status-main {
  display: grid;
  gap: 0.24rem;
}

.phase-status-main strong {
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 500;
}

.phase-status-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(70px, 1fr));
  gap: 0.4rem;
}

.phase-status-grid span {
  display: grid;
  gap: 0.2rem;
  min-width: 0;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.72rem;
  overflow-wrap: anywhere;
}

.phase-status-grid b {
  color: var(--muted);
  font-size: 0.64rem;
  font-weight: 400;
  text-transform: uppercase;
}

.tab-panel {
  display: none;
  min-width: 0;
}

.tab-panel.active {
  display: block;
}

#tab-operations.active {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  height: calc(100vh - 1.5rem);
  min-height: 0;
  overflow: hidden;
}

.ops-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(300px, 26vw, 380px);
  gap: 0.75rem;
  flex: 1 1 auto;
  height: auto;
  min-height: 0;
}

.system-preview-layout {
  display: grid;
  grid-template-columns: minmax(560px, 1fr) minmax(280px, 360px);
  gap: 0.75rem;
  height: clamp(520px, calc(100vh - 210px), 860px);
  min-height: 0;
}

.detail-panel {
  max-height: 100%;
  overflow: auto;
}

.map-panel {
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.map-toolbar {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: start;
}

.system-preview-toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: end;
  gap: 0.45rem;
  align-items: end;
}

.system-preview-toolbar label {
  display: grid;
  gap: 0.25rem;
  min-width: 180px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
}

.system-preview-toolbar .button-pair button.active {
  border-color: var(--primary-hot);
  background: rgba(70, 232, 140, 0.16);
  color: var(--primary);
}

.map-frame {
  flex: 1;
  min-height: 380px;
  border: 1px solid var(--border);
  background:
    repeating-linear-gradient(0deg, transparent 0 3px, rgba(0, 0, 0, 0.38) 3px 4px),
    var(--background-obsidian);
  overflow: hidden;
  position: relative;
}

#tab-operations .map-frame,
#tab-operations .hex-map {
  min-height: 0;
}

.map-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(60deg, rgba(26, 38, 52, 0.38) 1px, transparent 1px),
    linear-gradient(120deg, rgba(26, 38, 52, 0.38) 1px, transparent 1px);
  background-size: 44px 44px;
  opacity: 0.6;
  pointer-events: none;
}

.hex-map {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 380px;
  touch-action: none;
  cursor: grab;
}

.hex-map.panning {
  cursor: grabbing;
}

.map-content-layer {
  transform-box: fill-box;
  transform-origin: 0 0;
  will-change: transform;
}

.system-preview-map {
  cursor: default;
}

.hex-cell {
  fill: rgba(20, 20, 22, 0.5);
  stroke: rgba(122, 214, 156, 0.22);
  stroke-width: 1;
  cursor: pointer;
}

.hex-cell-route-candidate:hover {
  fill: rgba(70, 232, 140, 0.1);
  stroke: var(--phos-green-hot);
}

.hex-cell-route-blocked {
  fill: rgba(20, 20, 22, 0.45);
  cursor: grab;
  opacity: 0.45;
}

/* ── T1 cabinet: the OPS theater monitor (NATOware pass, JUL03) ──
   Physical CRT housing: beveled polymer bezel, corner fasteners, stencil
   placard, power lamp. The .map-frame inside is the glass. */
.theater-panel {
  position: relative;
  padding: 30px 24px 58px;
  border: 1px solid var(--gasket);
  border-radius: 6px;
  background:
    radial-gradient(circle 5px at 13px 13px, #0d110e 0 1.6px, #454f47 2.2px, #10140f 3.2px, var(--chassis-700) 4.4px, transparent 5px),
    radial-gradient(circle 5px at calc(100% - 13px) 13px, #0d110e 0 1.6px, #454f47 2.2px, #10140f 3.2px, var(--chassis-700) 4.4px, transparent 5px),
    radial-gradient(circle 5px at 13px calc(100% - 13px), #0d110e 0 1.6px, #454f47 2.2px, #10140f 3.2px, var(--chassis-700) 4.4px, transparent 5px),
    radial-gradient(circle 5px at calc(100% - 13px) calc(100% - 13px), #0d110e 0 1.6px, #454f47 2.2px, #10140f 3.2px, var(--chassis-700) 4.4px, transparent 5px),
    linear-gradient(135deg, var(--chassis-700) 0%, var(--chassis-850) 100%);
  box-shadow:
    inset 0 2px 0 var(--bezel-hi),
    inset 2px 0 0 rgba(255, 255, 255, 0.05),
    inset 0 -3px 0 var(--bezel-lo),
    inset -3px 0 0 rgba(0, 0, 0, 0.5),
    0 4px 14px rgba(0, 0, 0, 0.55);
}

.theater-panel::before {
  content: "COMMAND HORIZON \00b7 TYPE 88-M";
  position: absolute;
  top: 7px;
  left: 50%;
  transform: translateX(-50%);
  color: var(--stencil-dim);
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.66rem;
  letter-spacing: 0.34em;
  white-space: nowrap;
  pointer-events: none;
}

/* Session identity chips: small glass windows set into the top-right of the
   theater bezel, clear of the corner fastener. */
.bezel-session-strip {
  position: absolute;
  top: 5px;
  right: 26px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  pointer-events: none;
}

.bezel-session-strip .badge {
  padding: 0.14rem 0.45rem;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
}

.theater-panel::after {
  content: "";
  position: absolute;
  right: 13px;
  bottom: 12px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--lamp-green);
  animation: ledPulse 4s infinite ease-in-out;
  pointer-events: none;
}

@keyframes ledPulse {
  0%,
  100% {
    box-shadow: 0 0 7px 1px rgba(61, 255, 124, 0.75);
  }
  50% {
    box-shadow: 0 0 3px 0 rgba(61, 255, 124, 0.3);
  }
}

/* Glass viewport: phosphor screen recessed behind a molded gasket. */
.theater-panel .map-frame {
  border: 6px solid #10130f;
  border-top-color: #0a0d0a;
  border-left-color: #0b0e0b;
  border-bottom-color: #1d241e;
  border-right-color: #1a201b;
  border-radius: 4px;
  background: var(--glass-bg);
  box-shadow:
    inset 0 12px 26px rgba(0, 0, 0, 0.8),
    inset 0 0 44px rgba(0, 0, 0, 0.65),
    0 1px 0 var(--bezel-hi);
}

.theater-panel .map-frame::before {
  background-image:
    linear-gradient(60deg, rgba(64, 110, 80, 0.22) 1px, transparent 1px),
    linear-gradient(120deg, rgba(64, 110, 80, 0.22) 1px, transparent 1px);
}

/* CRT filter: vignette + glare + scanlines + faint refresh flicker, drawn over
   the map SVG but under the floating controls (z 5/6). Never captures input. */
.theater-panel .map-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, transparent 56%, rgba(0, 0, 0, 0.4) 100%),
    linear-gradient(115deg, rgba(255, 255, 255, 0.045) 0%, transparent 32%),
    repeating-linear-gradient(0deg, transparent 0 3px, rgba(0, 0, 0, 0.2) 3px 4px);
  animation: crtFlicker 0.15s infinite alternate;
}

@keyframes crtFlicker {
  from {
    opacity: 1;
  }
  to {
    opacity: 0.96;
  }
}

/* Key cluster pod: a small chassis plate mounted over the glass. */
.map-controls {
  position: absolute;
  top: 0.55rem;
  right: 0.55rem;
  z-index: 5;
  display: flex;
  gap: 0.35rem;
  padding: 0.3rem;
  border: 1px solid var(--gasket);
  background: linear-gradient(180deg, var(--chassis-700), var(--chassis-800));
  box-shadow: inset 0 1px 0 var(--bezel-hi), 0 2px 6px rgba(0, 0, 0, 0.6);
  border-radius: 4px;
}

.map-controls button {
  width: 34px;
  min-height: 34px;
  padding: 0;
  display: grid;
  place-items: center;
  font-size: 0.68rem;
}

#mapLayersBtn {
  width: auto;
  min-width: 58px;
  padding: 0 0.5rem;
}

.map-controls-sep {
  width: 1px;
  align-self: stretch;
  margin: 4px 0;
  background: rgba(0, 0, 0, 0.55);
  box-shadow: 1px 0 0 var(--bezel-hi);
}

.theater-panel > .map-controls {
  top: auto;
  right: auto;
  bottom: 9px;
  left: 24px;
  z-index: 8;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

/* Execution dock: shared two-sided playback overlay (top-left of the map). */
.execution-dock {
  position: absolute;
  top: 0.55rem;
  left: 0.55rem;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.55rem 0.3rem 0.3rem;
  border: 1px solid var(--gasket);
  background: linear-gradient(180deg, var(--chassis-700), var(--chassis-800));
  box-shadow: inset 0 1px 0 var(--bezel-hi), 0 2px 6px rgba(0, 0, 0, 0.6);
  border-radius: 4px;
  transition: transform 160ms ease, opacity 160ms ease;
}

.execution-dock[hidden] {
  display: none;
}

.dock-play-wrap {
  position: relative;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
}

/* Circular countdown around the play button: depletes over one tick interval
   while the group is auto-advancing, hidden when paused/idle. */
.dock-timer-ring {
  position: absolute;
  inset: 0;
  width: 44px;
  height: 44px;
  transform: rotate(-90deg);
  pointer-events: none;
  opacity: 0;
  transition: opacity 160ms ease;
}

.dock-timer-ring.running {
  opacity: 1;
}

.dock-timer-track {
  fill: none;
  stroke: rgba(216, 226, 217, 0.14);
  stroke-width: 2.5;
}

.dock-timer-progress {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  /* dasharray/offset set inline (2*pi*r); offset 0 = full, = circumference = empty */
}

.execution-dock[data-color="green"] .dock-timer-progress {
  color: #4cd964;
}

.dock-play-pause {
  position: relative;
  z-index: 1;
  width: 38px;
  min-height: 38px;
  padding: 0;
  display: grid;
  place-items: center;
  font-size: 0.9rem;
  line-height: 1;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: rgba(4, 14, 8, 0.6);
  transition: color 160ms ease, box-shadow 160ms ease, background 160ms ease;
}

.dock-play-pause:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.execution-dock[data-color="red"] .dock-play-pause {
  color: #ff5a5a;
  box-shadow: 0 0 8px rgba(255, 90, 90, 0.45);
}

.execution-dock[data-color="orange"] .dock-play-pause {
  color: #ffb347;
  box-shadow: 0 0 8px rgba(255, 179, 71, 0.5);
}

.execution-dock[data-color="green"] .dock-play-pause {
  color: #4cd964;
  box-shadow: 0 0 10px rgba(76, 217, 100, 0.6);
}

.dock-hour {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  color: var(--phos-green);
}

.dock-intervention-stock {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  font-size: 0.68rem;
  color: var(--phos-amber);
  border-left: 1px solid rgba(216, 226, 217, 0.2);
  padding-left: 0.5rem;
}

.dock-intervene {
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  padding: 0.25rem 0.55rem;
  border: 1px solid rgba(255, 179, 71, 0.55);
  background: rgba(40, 22, 2, 0.82);
  color: #ffce8a;
  cursor: pointer;
}

.dock-intervene:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Scoped intervention session panel (JUL02 pass): floats over the map beside the
   dock while the frontier is paused for authoring. */
.intervention-panel {
  position: absolute;
  top: 3.4rem;
  left: 0.55rem;
  z-index: 7;
  width: min(21rem, calc(100% - 1.2rem));
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.65rem;
  border: 1px solid rgba(255, 179, 71, 0.45);
  background: rgba(8, 5, 2, 0.92);
  backdrop-filter: blur(8px);
  border-radius: 3px;
}

.intervention-panel[hidden] {
  display: none;
}

.intervention-target-row select {
  width: 100%;
}

.intervention-summary dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.6rem;
  font-size: 0.72rem;
  margin: 0;
}

.intervention-summary dt {
  color: rgba(158, 240, 180, 0.65);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.62rem;
}

.intervention-summary dd {
  margin: 0;
}

.intervention-hint {
  font-size: 0.7rem;
  color: #ffce8a;
  margin: 0.3rem 0 0;
}

.intervention-issues {
  margin: 0.2rem 0 0;
  padding-left: 1rem;
  font-size: 0.68rem;
  color: #ff9d8a;
  max-height: 7rem;
  overflow-y: auto;
}

.intervention-commit {
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  padding: 0.4rem;
  border: 1px solid rgba(255, 179, 71, 0.75);
  background: rgba(64, 34, 4, 0.9);
  color: #ffce8a;
  cursor: pointer;
}

.intervention-commit:disabled {
  opacity: 0.5;
  cursor: wait;
}

.intervention-commit.confirming {
  background: rgba(122, 25, 20, 0.9);
  border-color: rgba(255, 120, 100, 0.85);
  color: #ffd6cc;
}

.execution-banner {
  position: absolute;
  top: 0.55rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  padding: 0.3rem 0.85rem;
  border: 1px solid rgba(255, 179, 71, 0.45);
  background: rgba(40, 22, 2, 0.82);
  backdrop-filter: blur(8px);
  color: #ffce8a;
  letter-spacing: 0.08em;
  font-size: 0.78rem;
  text-transform: uppercase;
  border-radius: 3px;
}

.execution-banner[hidden] {
  display: none;
}

/* Map-anchored toasts (OCT21 proc visibility): float up from their origin hex in
   map units, so they track pan and zoom. Only a toast pinned to the view edge takes
   clicks (it pans to its origin); a floating one never steals a hex click. */
.map-toast {
  pointer-events: none;
}

/* Screen-reader echo of released map toasts; SVG text is not a live region. */
.map-toast-announcer {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.map-toast.pinned {
  pointer-events: auto;
  cursor: pointer;
}

.map-toast-body {
  /* The camera keeps --map-label-size at a constant on-screen size; the float
     below is in em so it scales with it. */
  font-size: calc(var(--map-label-size, 10px) * 1.1);
  animation: map-toast-life 7s ease-out forwards;
}

.map-toast-label,
.map-toast-arrow {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: 0.06em;
  text-anchor: middle;
  dominant-baseline: central;
  paint-order: stroke;
  stroke: rgba(2, 10, 18, 0.92);
  stroke-width: 0.3em;
  stroke-linejoin: round;
  fill: #9fe6ff;
}

.map-toast:not(.pinned) .map-toast-arrow {
  display: none;
}

.map-toast.comint .map-toast-label,
.map-toast.comint .map-toast-arrow {
  fill: #e2c4ff;
}

.map-toast.failed .map-toast-label,
.map-toast.failed .map-toast-arrow {
  fill: #ff8f86;
}

.map-toast.warn .map-toast-label,
.map-toast.warn .map-toast-arrow {
  fill: #ffd27a;
}

.map-toast.ok .map-toast-label,
.map-toast.ok .map-toast-arrow {
  fill: #8ff0a4;
}

@keyframes map-toast-life {
  0% { opacity: 0; transform: translateY(0.4em); }
  6% { opacity: 1; transform: none; }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-1.4em); }
}

/* COMINT launch-origin markers: historical, never interactive. */
.marker-comint {
  pointer-events: none;
}

.marker-comint-glyph {
  fill: rgba(206, 150, 255, 0.25);
  stroke: #ce96ff;
  stroke-width: 1.4;
}

.marker-comint-label {
  fill: #e2c4ff;
  font-size: 8px;
}

@media (prefers-reduced-motion: reduce) {
  .map-toast-body {
    animation: map-toast-fade 7s step-end forwards;
  }
}

@keyframes map-toast-fade {
  to { opacity: 0; }
}

/* GO/NO-GO cluster: station-ready lamps and arm key mounted on the bottom
   bezel of the theater cabinet — chassis hardware, not glass. Sits opposite
   the map key cluster, clear of the power lamp at the corner. */
.op-plan-controls {
  position: absolute;
  right: 30px;
  bottom: 9px;
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.op-plan-controls > button {
  min-height: 34px;
  padding: 0 0.5rem;
  font-size: 0.68rem;
}

.readiness-lights {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.readiness-light-bank {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}

/* Jewel lamp seated in a drilled socket, stencil caption engraved beneath. */
.readiness-light {
  display: grid;
  justify-items: center;
  gap: 3px;
}

.readiness-light .lamp {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--gasket);
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.14), transparent 45%);
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.85),
    0 1px 0 var(--bezel-hi);
}

.readiness-light .light-label {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.52rem;
  letter-spacing: 0.14em;
  line-height: 1;
  color: var(--stencil-dim);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.06);
}

/* Dead lens: tinted jewel glass, unlit. */
.readiness-light.blue .lamp {
  background-color: #0a2226;
}

.readiness-light.red .lamp {
  background-color: #260c0c;
}

/* Lit lens: hot core, specular bead, halo bleeding onto the bezel. */
.readiness-light.ready.blue .lamp {
  background:
    radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.85), transparent 42%),
    radial-gradient(circle, #aef4fd 0%, var(--side-blue) 55%, #036d7a 100%);
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.35),
    0 0 8px 1px rgba(var(--side-blue-rgb), 0.65);
}

.readiness-light.ready.red .lamp {
  background:
    radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.85), transparent 42%),
    radial-gradient(circle, #ffc2b3 0%, var(--lamp-red) 55%, #7a1010 100%);
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.35),
    0 0 8px 1px rgba(255, 79, 79, 0.65);
}

.readiness-light.ready .light-label {
  color: var(--stencil);
}

/* Arm key: same molded keycap as its neighbors, cast in red polymer. Armed
   state lights the legend green (base aria-pressed rule) plus a lamp bleed. */
.rdy-button {
  min-width: 58px;
  color: #ffd7d7;
  background: linear-gradient(180deg, #83322b, #6b241f 55%, #521915);
}

.rdy-button:hover {
  color: #ffe9e9;
  background: linear-gradient(180deg, #96423a, #83322b 55%, #6b241f);
}

.rdy-button:active:not(:disabled) {
  background: linear-gradient(180deg, #521915, #3d100d);
}

.rdy-button.armed,
.rdy-button.armed:hover {
  color: var(--phos-green-hot);
  text-shadow: 0 0 7px rgba(70, 232, 140, 0.7);
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 -2px 3px rgba(0, 0, 0, 0.4),
    inset 0 0 10px rgba(61, 255, 124, 0.2),
    0 1px 2px rgba(0, 0, 0, 0.55);
}

.plan-issues,
.admin-diagnostics {
  width: 100%;
}

.plan-issues > summary,
.admin-diagnostics > summary {
  cursor: pointer;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(158, 240, 180, 0.78);
}

.admin-execution {
  margin-top: 0.85rem;
  padding-top: 0.6rem;
  border-top: 1px solid rgba(122, 214, 156, 0.16);
}

.admin-execution[hidden] {
  display: none;
}

.admin-dev {
  margin-top: 0.85rem;
  padding-top: 0.6rem;
  border-top: 1px dashed rgba(243, 180, 0, 0.32);
}

.admin-dev[hidden] {
  display: none;
}

.map-layer-panel {
  position: absolute;
  top: 3.45rem;
  right: 0.55rem;
  z-index: 6;
  width: min(260px, calc(100% - 1.1rem));
  display: grid;
  gap: 0.7rem;
  padding: 0.75rem;
  border: 1px solid rgba(122, 214, 156, 0.3);
  background: rgba(8, 11, 9, 0.92);
  box-shadow: 0 18px 42px rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(10px);
  border-radius: 3px;
}

.map-layer-panel[hidden] {
  display: none;
}

.theater-panel > .map-layer-panel {
  top: auto;
  right: auto;
  bottom: 3.65rem;
  left: 24px;
  z-index: 9;
}

.layer-control-group {
  display: grid;
  gap: 0.35rem;
  min-width: 0;
}

.layer-control-group > span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
}

.layer-control-buttons {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(58px, 1fr));
  gap: 0.35rem;
}

.layer-control-buttons button {
  min-height: 30px;
  padding: 0 0.3rem;
  font-size: 0.64rem;
  letter-spacing: 0.03em;
  overflow-wrap: anywhere;
}

.layer-control-buttons button.active {
  color: var(--phos-green-hot);
  text-shadow: 0 0 7px rgba(70, 232, 140, 0.7);
  background: rgba(70, 232, 140, 0.1);
}

.sensor-range-cell {
  pointer-events: none;
  stroke-linejoin: round;
  stroke-width: 0.75;
}

.sensor-range-friendly {
  fill: rgba(0, 218, 243, 0.1);
  stroke: rgba(0, 218, 243, 0.18);
}

.sensor-range-friendly.sensor-range-boundary {
  fill: rgba(0, 218, 243, 0.16);
  stroke: rgba(0, 218, 243, 0.52);
  stroke-width: 1.35;
}

.sensor-range-enemy {
  fill: rgba(255, 78, 78, 0.09);
  stroke: rgba(255, 78, 78, 0.18);
}

.sensor-range-enemy.sensor-range-boundary {
  fill: rgba(255, 78, 78, 0.14);
  stroke: rgba(255, 78, 78, 0.55);
  stroke-width: 1.35;
}

/* Fixed concentric sensor zones (docs/adr/0001-sensor-coverage-annuli): Y the
   inner disc, X the middle annulus, W the outer annulus. Geometry (evenodd hex
   rings) is built in JS; colors carry their own alpha for the semi-transparent
   wash. Friendly fills its zones; enemy strokes the same zones dashed so a
   contested hex shows both. */
.sensor-range-zone {
  pointer-events: none;
  stroke-linejoin: round;
  transition: all 0.2s ease;
}

/* Both sides fill their zones (so enemy-only / site coverage — the common case —
   stays visible without a friendly wash beneath it); the enemy's dashed outline
   is the side-distinguisher and keeps contested hexes legible. */
.sensor-range-zone.friendly { stroke: none; }
.sensor-range-zone.enemy { stroke-width: 1.25; stroke-dasharray: 3 2; }

.sensor-range-zone-w.friendly { fill: var(--friendly-sensor-w); }
.sensor-range-zone-x.friendly { fill: var(--friendly-sensor-x); }
.sensor-range-zone-y.friendly { fill: var(--friendly-sensor-y); }

.sensor-range-zone-w.enemy { fill: var(--enemy-sensor-w); stroke: var(--enemy-sensor-w); }
.sensor-range-zone-x.enemy { fill: var(--enemy-sensor-x); stroke: var(--enemy-sensor-x); }
.sensor-range-zone-y.enemy { fill: var(--enemy-sensor-y); stroke: var(--enemy-sensor-y); }


/* Patrol area-occupancy zones (JUN08 patrol area-occupancy pass): the
   on-station footprint painted as filled coverage hexes. The .projected register
   is the focus-hour axis — the currently-evaluated hour is solid, any
   future/planned hour is ghosted (low-opacity fill, dashed outline). */
.patrol-zone-cell {
  pointer-events: none;
  stroke-linejoin: round;
  stroke-width: 1.4;
}

/* Capability overlay cells (ADR 0009 / JUN16 capability panel pass) */
.capability-overlay-cell {
  pointer-events: none;
  stroke-linejoin: round;
  stroke-width: 2.0;
  stroke-dasharray: 4 3;
}
.capability-overlay-cell.marker-blue {
  fill: rgba(var(--owner-rgb), 0.22);
  stroke: rgba(var(--owner-rgb), 0.85);
}
.capability-overlay-cell.marker-red {
  fill: rgba(255, 82, 82, 0.22);
  stroke: rgba(255, 82, 82, 0.85);
}

/* Self-propelled weapon routes (HSRD probe): dash-dot, so they never read as a
   dashed Transit leg (even dashes) or a ship course (dots). */
.weapon-route {
  --weapon-route: rgb(var(--owner-rgb));
  pointer-events: none;
}
.weapon-route.marker-red {
  --weapon-route: var(--red);
}
.weapon-route-line {
  fill: none;
  stroke: var(--weapon-route);
  stroke-width: 2.4;
  stroke-dasharray: 9 4 2 4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.weapon-route-node {
  fill: var(--weapon-route);
  stroke: rgba(5, 15, 28, 0.9);
  stroke-width: 1;
}
.weapon-route-launch {
  fill: rgba(5, 15, 28, 0.85);
  stroke: var(--weapon-route);
  stroke-width: 2;
}
.weapon-route-end circle,
.weapon-route-end line {
  fill: none;
  stroke: var(--weapon-route);
  stroke-width: 1.8;
  stroke-linecap: round;
}
.weapon-route-line.is-flown,
.weapon-route-node.is-flown {
  opacity: 0.3;
}
.weapon-route.is-ghost {
  opacity: 0.55;
}

/* Ranged strikes: the weapon route in strike orange, release hex to target reticle.
   The selected Strike's and a played release draw at full strength. */
.weapon-route.strike-release-line {
  --weapon-route: #ff9a3c;
  opacity: 0.75;
}
.weapon-route.strike-release-line.is-selected,
.weapon-route.strike-release-line.is-played {
  opacity: 1;
}
.weapon-route.strike-release-line.is-selected .weapon-route-line {
  stroke-width: 2.8;
}
.weapon-route.strike-release-line.is-played.acknowledged {
  opacity: 0.55;
}
/* Incoming strikes on own assets (OCT28): the same line in red, from the
   attacker's track. */
.weapon-route.strike-release-line.is-incoming {
  --weapon-route: var(--red);
}

/* ── Capability markers (JUL10 capability marker pass) ──
   One uniform off-centre badge per spatial capability order, distinguished only
   by its two-letter code. Non-interactive (clicks pass through to the hex like
   the LRI reticle / painted area). The selected mission/strike's badges stay
   bright; the rest dim via .cap-marker-dim, and a resolved-hour or ended-mission
   badge dims further via .cap-marker-resolved. */
.capability-marker {
  pointer-events: none;
}
.cap-marker-body {
  stroke-width: 1;
}
.cap-marker-code {
  font-size: 6px;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
  letter-spacing: 0.2px;
}
.capability-marker.marker-blue .cap-marker-body {
  fill: rgba(6, 26, 33, 0.82);
  stroke: rgba(var(--owner-rgb), 0.95);
}
.capability-marker.marker-blue .cap-marker-code {
  fill: rgba(214, 248, 255, 0.98);
}
.capability-marker.marker-red .cap-marker-body {
  fill: rgba(33, 8, 8, 0.82);
  stroke: rgba(255, 82, 82, 0.95);
}
.capability-marker.marker-red .cap-marker-code {
  fill: rgba(255, 224, 224, 0.98);
}
.capability-marker.cap-marker-dim {
  opacity: 0.5;
}
.capability-marker.cap-marker-resolved {
  opacity: 0.32;
}

/* Faded footprint + badge that follows the cursor while a capability order is
   in hex-select mode; pointer-events stays off so hit-testing and the
   committing click always land on the hex underneath. */
.capability-placement-ghost {
  pointer-events: none;
  opacity: 0.45;
}
#hexMap.capability-armed {
  cursor: crosshair;
}

/* ── LRI emitter reticles (JUL03; Y-band emitters since OCT26) ── */
#hexMap.lri-armed {
  cursor: crosshair;
}
.lri-reticle {
  pointer-events: none;
}
.lri-reticle.lri-resolved {
  opacity: 0.4;
}
/* Armed placement ghost: same crosshair, faded and gently pulsing so it reads
   as a preview rather than a committed tasking. */
.lri-reticle.lri-reticle-ghost {
  opacity: 0.5;
  animation: lri-armed-pulse 1.1s ease-in-out infinite;
}
.lri-reticle-ring {
  fill: none;
  stroke-width: 1.4;
}
.lri-reticle-tick {
  stroke-width: 1.4;
  stroke-linecap: round;
}
.lri-reticle.marker-blue .lri-reticle-ring,
.lri-reticle.marker-blue .lri-reticle-tick {
  stroke: rgba(var(--owner-rgb), 0.9);
}
.lri-reticle.marker-red .lri-reticle-ring,
.lri-reticle.marker-red .lri-reticle-tick {
  stroke: rgba(255, 82, 82, 0.9);
}
.lri-reticle-label {
  font-size: 5px;
}
.lri-reticle.marker-blue .lri-reticle-label {
  fill: rgba(var(--owner-rgb), 0.9);
}
.lri-reticle.marker-red .lri-reticle-label {
  fill: rgba(255, 82, 82, 0.9);
}

.chaff-cloud-cell {
  pointer-events: none;
  stroke-linejoin: round;
  stroke-width: 1.5;
  stroke-dasharray: 5 3;
}

.chaff-cloud-cell.is-friendly,
.chaff-cloud-cell.marker-blue {
  fill: rgba(240, 226, 120, 0.2);
  stroke: rgba(240, 226, 120, 0.78);
}

.chaff-cloud-cell.is-enemy,
.chaff-cloud-cell.marker-red {
  fill: rgba(245, 132, 84, 0.18);
  stroke: rgba(245, 132, 84, 0.78);
}

.chaff-cloud-cell.is-stale {
  opacity: 0.55;
}

.chaff-cloud-cell.is-preview {
  stroke-width: 2;
  opacity: 0.82;
}

/* Authored Patrol areaHexes. Always visible for the selected mission;
   the .painting register brightens the area while it is editable. */
.painted-area-cell {
  pointer-events: none;
  stroke-linejoin: round;
  stroke-width: 1.6;
  stroke-dasharray: 3 2;
}

.painted-area-cell.marker-blue {
  fill: rgba(var(--owner-rgb), 0.14);
  stroke: rgba(var(--owner-rgb), 0.7);
}

.painted-area-cell.marker-red {
  fill: rgba(255, 82, 82, 0.14);
  stroke: rgba(255, 82, 82, 0.7);
}

.painted-area-cell.painting {
  stroke-dasharray: none;
  stroke-width: 2.2;
}

.painted-area-cell.marker-blue.painting {
  fill: rgba(var(--owner-rgb), 0.26);
}

.painted-area-cell.marker-red.painting {
  fill: rgba(255, 82, 82, 0.26);
}

.patrol-zone-cell.marker-blue {
  fill: rgba(var(--owner-rgb), 0.18);
  stroke: rgba(var(--owner-rgb), 0.65);
}

.patrol-zone-cell.marker-red {
  fill: rgba(255, 82, 82, 0.18);
  stroke: rgba(255, 82, 82, 0.65);
}

.patrol-zone-cell.projected {
  stroke-dasharray: 5 4;
  stroke-width: 1.1;
}

.patrol-zone-cell.marker-blue.projected {
  fill: rgba(var(--owner-rgb), 0.07);
  stroke: rgba(var(--owner-rgb), 0.4);
}

.patrol-zone-cell.marker-red.projected {
  fill: rgba(255, 82, 82, 0.07);
  stroke: rgba(255, 82, 82, 0.4);
}

.route-blue,
.route-red,
.route-ingress,
.route-selected,
.route-vessel {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.route-blue,
.route-red,
.route-ingress {
  stroke-width: 2.4;
}

.route-blue {
  stroke: rgb(var(--owner-rgb));
}

.route-red {
  stroke: var(--red);
}

.route-ingress {
  stroke: var(--muted);
  stroke-dasharray: 5 5;
  opacity: 0.76;
}

/* OCT28 track trails: an enemy track's sighted hexes, drawn like a Transit route in the
   enemy colour. Pointer-transparent; dimmer once the track is stale. */
.track-trail {
  pointer-events: none;
  --trail-color: var(--red);
}

.track-trail.marker-blue {
  --trail-color: var(--side-blue);
}

.track-trail-line {
  fill: none;
  stroke: var(--trail-color);
  stroke-width: 2.4;
  stroke-dasharray: 5 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.7;
}

.track-trail-point {
  fill: color-mix(in srgb, var(--trail-color) 34%, transparent);
  stroke: var(--trail-color);
  stroke-width: 1.2;
  opacity: 0.8;
}

.track-trail.stale {
  opacity: 0.45;
}

/* Standoff strike range rings (JUN15 per-munition range): orange outline of the
   hexes a selected strike's munitions can deliver from. Solid for a single range,
   dashed when the loadout mixes ranges. */
.strike-range-ring {
  fill: none;
  stroke: #ff9a3c;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
  pointer-events: none;
}

.strike-range-ring-dashed {
  stroke-dasharray: 5 4;
  opacity: 0.78;
}

/* Reticle marking every strike's target hex — the only always-present "where
   is this aimed" cue (the range ring needs painted munitions to draw at all,
   so it can't carry this alone). Plain = assigned to a mission but not
   selected; .is-selected reads brighter; .is-unassigned (a draft with no
   Strike Mission yet) reads dashed/dimmer since it isn't committed. */
.strike-target-marker circle,
.strike-target-marker line {
  stroke: #ff9a3c;
  fill: none;
  stroke-width: 2;
  pointer-events: none;
}

.strike-target-marker circle {
  opacity: 0.9;
}

.strike-target-marker line {
  stroke-linecap: round;
  opacity: 0.95;
}

.strike-target-marker.is-selected circle,
.strike-target-marker.is-selected line {
  stroke-width: 2.6;
  opacity: 1;
}

.strike-target-marker.is-unassigned circle,
.strike-target-marker.is-unassigned line {
  stroke-dasharray: 3 3;
  opacity: 0.55;
}

/* Incoming strike on an own asset (OCT28): the target crosshair in red for the
   strike hour; an opened strike ping dims it like the ping. */
.strike-target-marker.is-incoming circle,
.strike-target-marker.is-incoming line {
  stroke: var(--red);
  stroke-width: 2.6;
}

.strike-target-marker.is-incoming.acknowledged {
  opacity: 0.6;
}

.route-on-station {
  stroke-dasharray: none;
  opacity: 1;
}

.route-selected {
  stroke: var(--secondary-hot);
  stroke-width: 6.2;
  opacity: 0.38;
}

.route-vessel {
  stroke: #9bf06c;
  stroke-width: 3;
  stroke-dasharray: 2 7;
  filter: drop-shadow(0 0 4px rgba(155, 240, 108, 0.35));
}

.route-vessel-selected {
  stroke-width: 4.4;
  opacity: 0.95;
}

.route-point {
  stroke-width: 1.2;
  fill: rgba(255, 255, 255, 0.12);
  pointer-events: all;
  cursor: context-menu;
}

.route-point-ingress {
  fill: rgba(186, 201, 204, 0.34);
  stroke: var(--muted);
}

/* A Patrol's arrival node: drag it to move the whole station. Player colored
   via --owner-rgb (seat) or the Red side color. */
.route-move-handle {
  pointer-events: all;
  cursor: move;
  --handle-color: rgb(var(--owner-rgb));
}

.route-move-handle.marker-red {
  --handle-color: var(--red);
}

.route-move-handle-disc {
  fill: rgba(5, 15, 28, 0.82);
  stroke: var(--handle-color);
  stroke-width: 1.8;
}

.route-move-handle-glyph {
  fill: var(--handle-color);
}

.route-station-start {
  stroke: var(--secondary-hot);
  stroke-width: 2;
}

.route-vessel-point {
  fill: rgba(155, 240, 108, 0.88);
  stroke: rgba(5, 15, 28, 0.95);
  stroke-width: 1.2;
  pointer-events: all;
  cursor: context-menu;
}

.route-vessel-start {
  fill: var(--secondary-hot);
}

.marker-carrier,
.marker-complex,
.marker-vessel {
  pointer-events: all;
  cursor: context-menu;
}

.marker-carrier {
  stroke: var(--side-blue);
  stroke-width: 1.8;
}

/* Blue symbology reads its color from --owner-rgb (side blue, set on :root);
   seats 2-4 override it with data-blue-player (render_common.bluePlayerAttrs)
   and descendants inherit. Never redeclare the default on a class. */
[data-blue-player="2"] {
  --owner-rgb: var(--blue-player-2-rgb);
}
[data-blue-player="3"] {
  --owner-rgb: var(--blue-player-3-rgb);
}
[data-blue-player="4"] {
  --owner-rgb: var(--blue-player-4-rgb);
}

.marker-blue {
  fill: rgb(var(--owner-rgb));
}

.marker-red {
  fill: var(--red);
}

/* Complex site rows inherit the target channel via currentColor. */
.complex-slot {
  color: var(--secondary);
}

/* Stale sites remain dimmed at their last-known position. */
.marker-complex.is-stale .complex-slot {
  opacity: 0.42;
}

/* Site knocked out through disabledUntilHour: dim the glyph, slash it. */
.complex-slot.is-disabled use {
  opacity: 0.38;
}

.complex-slot-slash {
  stroke: var(--red);
  stroke-width: 1.3;
  stroke-linecap: round;
  fill: none;
}

.complex-slot-pip {
  fill: var(--secondary);
}

.complex-slot-count,
.complex-slot-unknown {
  fill: var(--secondary);
  text-anchor: middle;
  font-family: var(--mono);
}

.complex-slot-unknown {
  font-weight: 700;
}

/* Below the glyph zoom threshold the row collapses to a site count. */
.complex-collapsed-count {
  fill: var(--secondary-hot);
  text-anchor: middle;
  font-family: var(--mono);
  font-weight: 700;
  font-size: 9px;
}

.marker-label-stale {
  fill: var(--secondary);
  opacity: 0.75;
  font-size: 0.7em;
}

/* Deployables (Sensorbuoy, ADR 0013): a dark diamond, distinct from the target square, that
   carries the kind's glyph (M7 Q5). Friendly = primary; enemy = red; stale enemy contact
   dims + dashes. */
.marker-deployable {
  pointer-events: all;
  cursor: context-menu;
  stroke-width: 1.3;
}

.marker-deployable.is-friendly {
  fill: rgba(3, 22, 30, 0.88);
  stroke: var(--primary);
}

.marker-deployable.is-enemy {
  fill: rgba(30, 6, 12, 0.88);
  stroke: var(--red);
}

.marker-deployable.is-enemy.is-stale {
  fill: rgba(30, 6, 12, 0.5);
  stroke-dasharray: 3 2;
}

.deployable-glyph {
  pointer-events: none;
}

.deployable-glyph.is-friendly {
  fill: var(--primary);
}

.deployable-glyph.is-enemy {
  fill: var(--red);
}

.deployable-glyph.is-stale {
  opacity: 0.55;
}

.deployable-glyph.chaff-cloud-glyph.is-friendly {
  fill: rgba(255, 242, 164, 0.95);
}

.deployable-glyph.chaff-cloud-glyph.is-enemy {
  fill: rgba(245, 132, 84, 0.95);
}

/* Strike planner: section divider between complexes and deployables in the target tree. */
.strike-tree-section-label {
  margin: 0.6rem 0 0.2rem;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted, rgba(255, 255, 255, 0.55));
}

.marker-vessel {
  fill: rgba(155, 240, 108, 0.72);
  stroke: #9bf06c;
  stroke-width: 1.6;
}

/* Combat hex ping (detection ping pass): a pulsing "!" both sides click to
   open/observe the engagement. */
.marker-combat {
  pointer-events: all;
  cursor: pointer;
}

.marker-combat-pulse {
  fill: rgba(255, 82, 82, 0.28);
  stroke: rgba(255, 82, 82, 0.55);
  stroke-width: 1;
  transform-box: fill-box;
  transform-origin: center;
  animation: combat-ping-pulse 1.6s ease-out infinite;
}

.marker-combat-badge {
  fill: rgba(28, 6, 8, 0.92);
  stroke: var(--red);
  stroke-width: 1.6;
}

.marker-combat-glyph {
  fill: #ff8a8a;
  font-family: var(--display);
  font-size: 13px;
  font-weight: 800;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

/* The viewer owes a decision here — burn hotter and pulse a touch faster. */
.marker-combat.urgent .marker-combat-pulse {
  fill: rgba(255, 193, 7, 0.32);
  stroke: rgba(255, 193, 7, 0.7);
  animation-duration: 1s;
}

.marker-combat.urgent .marker-combat-badge {
  stroke: #ffc107;
}

.marker-combat.urgent .marker-combat-glyph {
  fill: #ffe08a;
}

/* Already opened this beat — stop demanding attention but stay on the map. */
.marker-combat.acknowledged {
  opacity: 0.55;
}

.marker-combat.acknowledged .marker-combat-pulse {
  animation: none;
  opacity: 0;
}

@keyframes combat-ping-pulse {
  0% { transform: scale(0.7); opacity: 0.9; }
  70% { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .marker-combat-pulse {
    animation: none;
    opacity: 0.4;
  }
}

/* Strike hex ping (OCT21 strike encounter parity): a pulsing crosshair the
   striker (amber) and the target's owner (red, hotter) click to open the strike
   report. */
.marker-strike {
  pointer-events: all;
  cursor: pointer;
}

.marker-strike-pulse {
  fill: rgba(255, 170, 40, 0.28);
  stroke: rgba(255, 170, 40, 0.6);
  stroke-width: 1;
  transform-box: fill-box;
  transform-origin: center;
  animation: combat-ping-pulse 1.6s ease-out infinite;
}

.marker-strike-badge {
  fill: rgba(28, 16, 4, 0.92);
  stroke: #ffaa28;
  stroke-width: 1.6;
}

.marker-strike-glyph {
  stroke: #ffd08a;
  stroke-width: 2.2;
  stroke-linecap: round;
  fill: none;
  pointer-events: none;
}

.marker-strike.defender .marker-strike-pulse {
  fill: rgba(255, 82, 82, 0.32);
  stroke: rgba(255, 82, 82, 0.7);
  animation-duration: 1s;
}

.marker-strike.defender .marker-strike-badge {
  fill: rgba(28, 6, 8, 0.92);
  stroke: var(--red);
}

.marker-strike.defender .marker-strike-glyph {
  stroke: #ff8a8a;
}

.marker-strike.acknowledged {
  opacity: 0.55;
}

.marker-strike.acknowledged .marker-strike-pulse {
  animation: none;
  opacity: 0;
}

@media (prefers-reduced-motion: reduce) {
  .marker-strike-pulse {
    animation: none;
    opacity: 0.4;
  }
}

/* Defensive Alert scramble warning triangle (JUN13 execution-decision UI). Rides a
   detected target hex the suspended decision batch can scramble against; urgent
   while the controlling viewer owes a choice, dimmed once a launch is staged. */
/* OCT26: the encounter ping (.marker-combat) drawn as a triangle. */
.marker-scramble {
  pointer-events: all;
  cursor: pointer;
}

.marker-scramble-pulse {
  fill: rgba(255, 82, 82, 0.28);
  stroke: rgba(255, 82, 82, 0.55);
  stroke-width: 1;
  stroke-linejoin: round;
  transform-box: fill-box;
  transform-origin: center 62%;
  animation: combat-ping-pulse 1.6s ease-out infinite;
}

.marker-scramble-tri {
  fill: rgba(28, 6, 8, 0.92);
  stroke: var(--red);
  stroke-width: 1.6;
  stroke-linejoin: round;
}

.marker-scramble-glyph {
  fill: #ff8a8a;
  font-family: var(--display);
  font-size: 13px;
  font-weight: 800;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.marker-scramble.urgent .marker-scramble-pulse {
  fill: rgba(255, 193, 7, 0.32);
  stroke: rgba(255, 193, 7, 0.7);
  animation-duration: 1s;
}

.marker-scramble.urgent .marker-scramble-tri {
  stroke: #ffc107;
}

.marker-scramble.urgent .marker-scramble-glyph {
  fill: #ffe08a;
}

/* A staged launch stops asking for attention, like an acknowledged ping. */
.marker-scramble.staged {
  opacity: 0.55;
}

.marker-scramble.staged .marker-scramble-pulse {
  animation: none;
  opacity: 0;
}

.marker-scramble.staged .marker-scramble-tri {
  stroke: rgba(155, 240, 108, 0.8);
}

@media (prefers-reduced-motion: reduce) {
  .marker-scramble-pulse {
    animation: none;
    opacity: 0.4;
  }
}

/* ADM engagement cues (ADM site-launch pass): a transient, non-interactive map
   flourish for site fire. FIRING rises over the launcher hex, a tracer streaks to
   the target, then the outcome lands over the target — coloured by result. */
.marker-adm {
  pointer-events: none;
}

.marker-adm-label {
  font-family: var(--display);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-anchor: middle;
  dominant-baseline: central;
  paint-order: stroke;
  stroke: rgba(4, 8, 14, 0.9);
  stroke-width: 3;
  stroke-linejoin: round;
  animation: adm-cue-rise 0.35s ease-out both;
}

.marker-adm.firing .marker-adm-label {
  fill: #ffd27a;
}

.marker-adm.outcome.miss .marker-adm-label {
  fill: #c9d4e0;
}

.marker-adm.outcome.return-fire-blocked .marker-adm-label {
  fill: #ffd27a;
}

.marker-adm.outcome.no-effect .marker-adm-label {
  fill: #9fb4c6;
}

.marker-adm.outcome.hit .marker-adm-label {
  fill: #ff9d4d;
}

.marker-adm.outcome.kill .marker-adm-label {
  fill: #ff5a5a;
}

.marker-adm.outcome.disabled .marker-adm-label {
  fill: #75d99b;
}

.marker-adm.outcome.fire-director-hit .marker-adm-label {
  fill: #ffdf6e;
}

.marker-adm-tracer {
  fill: none;
  stroke: #ffd27a;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 5 6;
  opacity: 0.85;
  animation: adm-tracer-streak 0.45s linear both;
}

.marker-adm-tracer.arm {
  stroke: #75d99b;
  stroke-dasharray: 2 5;
}

@keyframes adm-cue-rise {
  0% { opacity: 0; transform: translateY(4px); }
  100% { opacity: 1; transform: translateY(0); }
}

@keyframes adm-tracer-streak {
  0% { stroke-dashoffset: 22; opacity: 0.2; }
  60% { opacity: 0.9; }
  100% { stroke-dashoffset: 0; opacity: 0.85; }
}

@media (prefers-reduced-motion: reduce) {
  .marker-adm-label,
  .marker-adm-tracer {
    animation: none;
  }
}

/* Floating scramble decision dialogue. The summary waits in the corner; a hex
   detail opens beside its warning triangle (see .is-anchored). */
.scramble-dialog-root {
  position: fixed;
  right: 1rem;
  bottom: 5.5rem;
  z-index: 26;
  width: min(360px, calc(100vw - 2rem));
  max-height: min(70vh, 640px);
  overflow: auto;
}

/* Anchored beside the clicked "!" warning; left/top are set inline per frame. */
.scramble-dialog-root.is-anchored {
  right: auto;
  bottom: auto;
}

.scramble-dialog-shell {
  border: 1px solid rgba(255, 193, 7, 0.45);
  border-radius: 10px;
  background:
    linear-gradient(rgba(8, 18, 30, 0.96), rgba(6, 14, 24, 0.98)),
    var(--background-deep);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  padding: 0.7rem 0.8rem;
}

.scramble-dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
}

.scramble-dialog-header span {
  font-family: var(--display);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  color: #ffc107;
}

.scramble-dialog-header h3 {
  margin: 0.1rem 0 0;
  font-size: 0.95rem;
}

.scramble-summary {
  margin: 0.4rem 0 0.2rem;
  font-size: 0.78rem;
  color: var(--text-muted, #9fb3c8);
}

.scramble-hint {
  margin: 0.2rem 0 0.4rem;
  font-size: 0.75rem;
  color: #ffe08a;
}

.scramble-empty {
  font-size: 0.78rem;
  color: var(--text-muted, #9fb3c8);
}

.scramble-hex-detail h4 {
  margin: 0.5rem 0 0.35rem;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
}

.scramble-alert {
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  padding: 0.5rem 0.55rem;
  margin-bottom: 0.5rem;
  background: rgba(255, 255, 255, 0.03);
}

.scramble-alert.is-held {
  opacity: 0.7;
}

.scramble-alert-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.4rem;
}

.scramble-alert-head strong {
  font-size: 0.82rem;
}

.scramble-chip {
  font-family: var(--display);
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  padding: 0.1rem 0.35rem;
  border-radius: 999px;
  white-space: nowrap;
}

.scramble-chip.pending {
  background: rgba(255, 193, 7, 0.16);
  color: #ffe08a;
}

.scramble-chip.launch {
  background: rgba(155, 240, 108, 0.18);
  color: #c7f5a3;
}

.scramble-chip.hold {
  background: rgba(255, 255, 255, 0.1);
  color: #cfd9e3;
}

/* An ally's decision, shown read-only (ADR 0016 ownership). */
.scramble-chip.owner {
  background: rgba(120, 180, 255, 0.16);
  color: #b9d6ff;
}

.scramble-alert-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.1rem 0.6rem;
  margin: 0.4rem 0;
  font-size: 0.74rem;
}

.scramble-alert-facts dt {
  color: var(--text-muted, #9fb3c8);
}

.scramble-alert-facts dd {
  margin: 0;
}

.scramble-alert-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.3rem;
}

.scramble-alert-actions button {
  flex: 1;
  padding: 0.32rem 0.4rem;
  font-size: 0.74rem;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text, #e6eef6);
  cursor: pointer;
}

.scramble-alert-actions button:disabled {
  opacity: 0.4;
  cursor: default;
}

.scramble-launch.active {
  border-color: rgba(155, 240, 108, 0.8);
  background: rgba(155, 240, 108, 0.18);
}

.scramble-hold.active {
  border-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.14);
}

.scramble-dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.scramble-back {
  background: none;
  border: none;
  color: #9fb3c8;
  cursor: pointer;
  font-size: 0.76rem;
  padding: 0.2rem 0;
}

.scramble-commit {
  padding: 0.4rem 0.7rem;
  font-family: var(--display);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  border-radius: 6px;
  border: 1px solid rgba(155, 240, 108, 0.7);
  background: rgba(155, 240, 108, 0.16);
  color: #d6f7bd;
  cursor: pointer;
}

.scramble-commit:disabled {
  opacity: 0.4;
  cursor: default;
  border-color: rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.05);
  color: #9fb3c8;
}

.ship-preview-marker {
  pointer-events: none;
  filter: drop-shadow(0 0 5px rgba(155, 240, 108, 0.45));
}

.ship-preview-marker .marker-vessel {
  fill: rgba(155, 240, 108, 0.9);
  stroke: rgba(5, 15, 28, 0.95);
  stroke-width: 1.5;
}

.ship-preview-marker.ingress .marker-vessel {
  opacity: 0.72;
}

.ship-preview-marker.on-station .marker-vessel {
  stroke: var(--secondary-hot);
  stroke-width: 2;
}

/* Flight markers (JUN03 map craft markers pass): a heading-rotated chevron
   formation (1-4 chevrons = craft count) that points the way a flight last
   travelled. The outer <g> translates between hexes with a CSS transition (the
   tween); the inner .map-marker-rotate rotates to heading instantly. Markers are
   decorative — pointer-events:none so they never steal route/hex interactions. */
.map-marker {
  pointer-events: none;
  transition: transform var(--marker-tween, 250ms) ease-out;
}

.map-marker-rotate {
  transform-box: fill-box;
  transform-origin: center;
}

.flight-chevron {
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.flight-chevron.lead {
  stroke-width: 2.9;
}

.flight-marker.marker-blue .flight-chevron {
  stroke: rgb(var(--owner-rgb));
}

.flight-marker.marker-red .flight-chevron {
  stroke: var(--red);
}

.flight-marker.execution {
  filter: drop-shadow(0 0 3px rgba(8, 11, 9, 0.85));
}

.flight-marker.preview {
  opacity: 0.9;
  filter: drop-shadow(0 0 5px rgba(254, 179, 0, 0.4));
}

.flight-marker.observed .flight-chevron {
  stroke-width: 3;
  stroke-dasharray: 0;
}

.flight-marker.observed.projected {
  opacity: 0.55;
}

.flight-marker.observed.projected .flight-chevron {
  stroke-dasharray: 4 3;
}

.flight-marker.ingress {
  opacity: 0.78;
}

.flight-marker.on-station .flight-chevron {
  stroke-width: 3.2;
}

/* Loiter glyph (patrol area-occupancy pass): orbit ring + tangential chevrons at
   the coverage centroid. Non-directional, so it never rotates or tweens. A
   .projected (future/planned hour) marker renders hollow/dimmed; the focus hour
   renders solid whether the evaluation is real or projected. */
.flight-marker.loiter .flight-chevron {
  stroke-width: 2;
}

.flight-marker.loiter .flight-chevron.lead {
  stroke-width: 2.6;
}

.loiter-orbit {
  fill: rgba(8, 11, 9, 0.55);
  stroke-width: 1.2;
}

.flight-marker.marker-blue .loiter-orbit {
  stroke: rgba(var(--owner-rgb), 0.75);
}

.flight-marker.marker-red .loiter-orbit {
  stroke: rgba(255, 82, 82, 0.75);
}

.flight-marker.loiter.projected {
  opacity: 0.62;
}

.flight-marker.loiter.projected .loiter-orbit {
  fill: none;
  stroke-dasharray: 4 3;
}

@media (prefers-reduced-motion: reduce) {
  .map-marker {
    transition: none;
  }
}

.marker-label {
  fill: var(--text);
  font-size: 8px;
  font-family: var(--mono);
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.ship-preview-label {
  fill: #9bf06c;
  paint-order: stroke;
  stroke: rgba(8, 11, 9, 0.88);
  stroke-width: 2.5px;
}

.system-hex-cell {
  fill: rgba(14, 20, 15, 0.5);
  stroke: rgba(0, 218, 243, 0.18);
  cursor: default;
}

.system-feature-belt {
  fill: rgba(186, 201, 204, 0.2);
  stroke: rgba(186, 201, 204, 0.22);
  stroke-width: 0.8;
  pointer-events: none;
}

.system-feature-field {
  fill: rgba(168, 85, 247, 0.15);
  stroke: rgba(168, 85, 247, 0.35);
  stroke-width: 0.9;
  pointer-events: none;
}

.system-feature-anomaly {
  fill: rgba(254, 179, 0, 0.2);
  stroke: rgba(254, 179, 0, 0.5);
  stroke-width: 1;
  pointer-events: none;
}

/* The Oort is dual terrain (asteroid belt + particle field): blend the belt grey
   and field purple so the outer ring reads as both. */
.system-feature-oort {
  fill: rgba(177, 143, 225, 0.18);
  stroke: rgba(186, 201, 204, 0.4);
  stroke-width: 0.9;
  pointer-events: none;
}

.system-oort-boundary {
  fill: none;
  stroke: rgba(254, 179, 0, 0.7);
  stroke-width: 3;
  stroke-dasharray: 12 8;
  pointer-events: none;
}

.system-star-glow {
  fill: rgba(254, 179, 0, 0.18);
  stroke: rgba(254, 179, 0, 0.55);
  stroke-width: 1.4;
  pointer-events: none;
}

.system-star {
  fill: var(--secondary-hot);
  stroke: rgba(255, 255, 255, 0.78);
  stroke-width: 1.3;
  pointer-events: none;
}

.system-planet-sprite {
  pointer-events: none;
}

.system-marker-label {
  fill: var(--primary);
  font-size: 9px;
  paint-order: stroke;
  stroke: rgba(8, 11, 9, 0.88);
  stroke-width: 3;
}

.system-legend {
  display: grid;
  gap: 0.45rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--muted);
}

.system-legend span {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.system-legend i {
  width: 14px;
  height: 14px;
  border: 1px solid var(--outline-soft);
  display: inline-block;
}

.legend-star {
  background: var(--secondary-hot);
}

.legend-planet {
  background: var(--primary);
  border-radius: 50%;
}

.legend-belt {
  background: rgba(186, 201, 204, 0.32);
}

.legend-field {
  background: rgba(168, 85, 247, 0.22);
}

.legend-anomaly {
  background: rgba(254, 179, 0, 0.28);
}

.context-menu {
  position: fixed;
  z-index: 30;
  min-width: 220px;
  display: grid;
  gap: 0.25rem;
  padding: 0.35rem;
  border: 1px solid var(--primary-hot);
  background: rgba(8, 11, 9, 0.96);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.42), 0 0 0 1px rgba(70, 232, 140, 0.14);
  backdrop-filter: blur(12px);
  border-radius: 3px;
}

.context-menu button {
  width: 100%;
  text-align: left;
  justify-content: start;
  background: rgba(21, 27, 22, 0.86);
}

/* Ctrl-hover hex inspection tooltip (JUN16). Purely passive: never captures the
   pointer so it can't interfere with pan / route-drag underneath. */
.map-hex-tooltip {
  position: fixed;
  z-index: 31;
  pointer-events: none;
  max-width: 260px;
  display: grid;
  gap: 0.4rem;
  padding: 0.45rem 0.55rem;
  font-size: 0.78rem;
  border: 1px solid var(--primary-hot);
  background: rgba(8, 11, 9, 0.96);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.42), 0 0 0 1px rgba(70, 232, 140, 0.14);
  backdrop-filter: blur(12px);
  border-radius: 3px;
}

.map-hex-tooltip .hex-tip-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  border-bottom: 1px solid rgba(122, 214, 156, 0.22);
  padding-bottom: 0.3rem;
}

.map-hex-tooltip .hex-tip-coord {
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--primary-hot);
}

.map-hex-tooltip .hex-tip-terrain {
  color: var(--muted, #8aa);
  font-size: 0.72rem;
  text-align: right;
}

.map-hex-tooltip .hex-tip-feature {
  color: var(--primary, #7ad69c);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.03em;
}

.map-hex-tooltip .hex-tip-title {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.64rem;
  color: var(--muted, #8aa);
  margin-bottom: 0.15rem;
}

.map-hex-tooltip .hex-tip-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.map-hex-tooltip .hex-tip-secondary {
  color: var(--muted, #8aa);
  font-size: 0.72rem;
  text-align: right;
  white-space: nowrap;
}

/* OCT28 Q14: a track's revealed count/frames on its own line, art beside it. */
.map-hex-tooltip .hex-tip-track {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.15rem;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
}

.map-hex-tooltip .hex-tip-craft-art {
  display: inline-flex;
  width: 2.4rem;
  height: 2.4rem;
  color: inherit;
}

.map-hex-tooltip .hex-tip-craft-art :is(.combat-craft-art, .combat-chevron) {
  width: 100%;
  height: 100%;
  filter: none;
}

.map-hex-tooltip .hex-tip-more {
  color: var(--muted, #8aa);
  font-size: 0.68rem;
  font-style: italic;
}

/* Nested site readiness rows under a complex (JUL08). Indented, and the pair
   sits in a tabular-figure secondary so ??/?? and M/N line up. */
.map-hex-tooltip .hex-tip-subrow {
  padding-left: 0.75rem;
}

.map-hex-tooltip .hex-tip-subrow .hex-tip-secondary {
  font-variant-numeric: tabular-nums;
}

/* Staleness axis (JUL08): a stale site/complex row dims without changing its
   readiness pair — freshness is orthogonal to SRI-completeness. */
.map-hex-tooltip .hex-tip-stale {
  opacity: 0.62;
}

.mission-selector {
  margin-bottom: 0.75rem;
}

.form-grid {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.form-grid .check {
  display: flex;
  align-items: center;
  gap: 0.45rem;
}

.form-grid .check input {
  width: auto;
}

/* Inline hint under a form field (e.g. available-craft count on the new
   mission dialogue). */
.field-hint {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.05em;
  color: rgba(158, 240, 180, 0.6);
}

/* Performance status reads as a small glass window set into the plate. */
.mission-capability {
  margin: 0.6rem 0;
  border: 1px solid var(--gasket);
  background: var(--glass-bg);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.7), 0 1px 0 var(--bezel-hi);
  padding: 0.55rem;
}

.detail-panel {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* The active tabpanel fills whatever height the tab strip leaves; only the
   itinerary section inside it scrolls (see .itinerary-scroll) — everything
   else (Sortie Details card, Clone / Delete, the New Sortie bar) stays put. */
#missionDetailsPane {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* Last resort on a very short screen: scroll rather than let the New
     Sortie bar overlap the itinerary's minimum. */
  overflow-y: auto;
}

/* (Sensor bands moved into the Mission Details card's stat rail — JUL12 pass.) */

/* Compact per-band sensor chips shared by the OOB frame card and mission
   details pane: monospace pill with the band letter in bold and its reach. */
.sensor-band-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  vertical-align: middle;
}

.sensor-band-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.15rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--gasket);
  border-radius: 999px;
  background: var(--chassis-850, rgba(255, 255, 255, 0.04));
  font-family: var(--mono);
  font-size: 0.72rem;
  line-height: 1.4;
  color: var(--text, inherit);
}

.sensor-band-chip b {
  color: var(--primary, currentColor);
  font-weight: 700;
}

.sensor-band-chips.is-blind .hint {
  font-family: var(--mono);
  font-size: 0.72rem;
}

/* Create-mission sub-plate: recessed chassis section, no colored trim. */
.mission-create-panel {
  border: 1px solid var(--gasket);
  background: linear-gradient(180deg, var(--chassis-850), var(--chassis-900));
  border-radius: 3px;
  box-shadow: inset 0 1px 0 var(--bezel-hi);
  padding: 0.75rem;
  margin: 0.7rem 0;
}

/* While the create form is open it replaces the selected Sortie's content;
   the craft card stays as a preview of the squadron being picked. */
#missionDetailsPane.is-creating-sortie .itinerary-section,
#missionDetailsPane.is-creating-sortie #selectedMissionSummary,
#missionDetailsPane.is-creating-sortie .mdc-action-bar,
#missionDetailsPane.is-creating-sortie #loadoutPane,
#missionDetailsPane.is-creating-sortie #capabilitiesPane,
#missionDetailsPane.is-creating-sortie #strikePane,
#missionDetailsPane.is-creating-sortie #intelPane,
#missionDetailsPane.is-creating-sortie .new-sortie-bar {
  display: none;
}

#missionDetailsPane.is-creating-sortie .mdc-name-input {
  visibility: hidden;
}

.compact-heading {
  margin-bottom: 0.6rem;
}

/* Engraved chassis headings (same cut as .panel h2). */
.compact-heading h3,
.loadout-pane-header h3 {
  margin: 0;
  color: var(--stencil);
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.85), 0 2px 1px rgba(255, 255, 255, 0.05);
}

.readout-field {
  display: grid;
  gap: 0.25rem;
  border: 1px solid var(--border);
  background: rgba(10, 15, 11, 0.72);
  padding: 0.55rem;
  min-height: 56px;
}

.readout-field span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
}

.readout-field strong {
  color: var(--primary);
  font-family: var(--mono);
  font-size: 0.78rem;
  overflow-wrap: anywhere;
}

/* Slide-over service hatch: opaque chassis plate covering the instrument. */
.loadout-pane {
  position: absolute;
  inset: 0;
  z-index: 5;
  overflow-y: auto;
  border-left: 1px solid var(--gasket);
  background: linear-gradient(180deg, var(--chassis-800), var(--chassis-850));
  padding: 0.85rem;
  box-shadow:
    inset 1px 0 0 var(--bezel-hi),
    -18px 0 34px rgba(0, 0, 0, 0.45);
}

.loadout-pane-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.loadout-pane-body {
  display: grid;
  gap: 0.75rem;
}

.compact-summary {
  margin-bottom: 0;
}

.loadout-table input {
  width: 72px;
}

/* Derived-mission readout: glass window, phosphor data. */
.derived-card {
  border-color: var(--gasket);
  background: var(--glass-bg);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.7), 0 1px 0 var(--bezel-hi);
}

.derived-card dt {
  color: rgba(158, 240, 180, 0.6);
}

.derived-card dd {
  color: var(--phos-green);
}

.derived-warnings {
  margin: 0.65rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.35rem;
  list-style: none;
  color: var(--secondary-hot);
  font-family: var(--mono);
  font-size: 0.74rem;
}

.derived-warnings li {
  border-left: 2px solid var(--secondary-hot);
  padding-left: 0.45rem;
}

/* --- Strike summary (mission editor) --- */
.strike-summary {
  border-top: 1px solid var(--border);
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  display: grid;
  gap: 0.5rem;
}

.strike-summary-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.strike-summary-head h3 {
  color: var(--secondary-hot);
  font-family: var(--display);
  margin: 0;
  text-transform: uppercase;
  font-size: 0.92rem;
}

.strike-summary-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  align-items: center;
}

.strike-summary-actions select {
  min-width: 12rem;
  flex: 1 1 14rem;
}

.strike-chip-list {
  display: grid;
  gap: 0.35rem;
}

.strike-chip-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  min-height: 0;
  padding: 0.4rem 0.5rem;
}

.strike-chip-row.selected {
  border-color: var(--primary-hot);
  box-shadow: 0 0 0 1px rgba(70, 232, 140, 0.2);
}

.strike-chip-target {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--text);
  flex: 1 1 auto;
  overflow-wrap: anywhere;
}

.strike-chip-packet {
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--muted);
}

.ghost-btn {
  background: transparent;
  min-height: 0;
  padding: 0.28rem 0.5rem;
  font-size: 0.66rem;
}

.ghost-btn.danger {
  color: var(--red);
  border-color: rgba(255, 82, 82, 0.4);
}

.strike-add-btn {
  justify-self: start;
  min-height: 0;
  padding: 0.35rem 0.6rem;
  font-size: 0.68rem;
}

.strike-planner-grid {
  display: grid;
  grid-template-columns: minmax(330px, 420px) minmax(0, 1fr);
  gap: 0.75rem;
}

.strike-planner-list {
  display: grid;
  gap: 0.6rem;
  align-content: start;
  border-right: 1px solid var(--border);
  padding-right: 0.75rem;
}

.strike-planner-list-head,
.strike-packet-head,
.strike-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.strike-list-group {
  display: grid;
  gap: 0.4rem;
}

.strike-list-card {
  display: grid;
  gap: 0.3rem;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  min-height: 0;
  padding: 0.55rem 0.6rem;
}

.strike-list-card.selected {
  border-color: var(--primary-hot);
  box-shadow: 0 0 0 1px rgba(70, 232, 140, 0.2);
}

.strike-list-title {
  font-family: var(--display);
  color: var(--primary);
  font-size: 0.82rem;
  overflow-wrap: anywhere;
}

.strike-list-meta {
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--muted);
}

.strike-planner-detail {
  display: grid;
  gap: 0.75rem;
  align-content: start;
}

.strike-detail-head-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.strike-name-input {
  font-family: var(--display);
  font-size: 0.95rem;
  min-width: 220px;
}

.strike-id-readout {
  display: block;
  font-family: var(--mono);
  font-size: 0.64rem;
  color: var(--muted);
  margin-top: 0.2rem;
}

.strike-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.6rem;
}

.strike-detail-grid label,
.strike-detail-grid .readout-field {
  display: grid;
  gap: 0.25rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}

/* Warning banner: every noteworthy thing about the selected strike (real
   validation failures, authoring gaps, timing drift), one row each, most
   severe first — a chip was too easy to miss next to the status chip. */
.strike-warning-banner {
  display: grid;
  gap: 0.3rem;
}

.strike-warning-row {
  padding: 0.4rem 0.6rem;
  border-left: 3px solid var(--border);
  background: rgba(255, 255, 255, 0.03);
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}

.strike-warning-row.tone-bad {
  border-left-color: var(--red);
  color: var(--red);
  background: rgba(255, 82, 82, 0.08);
}

.strike-warning-row.tone-warn {
  border-left-color: var(--secondary-hot);
  color: var(--secondary-hot);
  background: rgba(254, 179, 0, 0.08);
}

.strike-warning-row.tone-good {
  border-left-color: var(--green);
  color: var(--green);
  background: rgba(0, 230, 118, 0.06);
}

.strike-warning-row.tone-info {
  border-left-color: var(--border);
  color: var(--muted);
}

.readout-field strong.is-good {
  color: var(--green);
}

.readout-field strong.is-warn {
  color: var(--secondary-hot);
}

/* --- Munition palette (the painting brush) --- */
.strike-palette {
  display: grid;
  gap: 0.4rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
}

.strike-brush-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.strike-brush {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface-low);
}

.strike-brush.armed {
  border-color: var(--primary-hot);
  box-shadow: 0 0 0 1px rgba(70, 232, 140, 0.35);
}

.strike-brush-chip {
  border: none;
  background: transparent;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.7rem;
  padding: 0.25rem 0.5rem;
  cursor: pointer;
}

.strike-brush.armed .strike-brush-chip {
  color: var(--primary);
}

.strike-brush-remove {
  border: none;
  border-left: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0 0.4rem;
  line-height: 1;
}

.strike-brush-remove:hover {
  color: var(--red);
}

.strike-brush-add {
  justify-self: start;
  font-family: var(--mono);
  font-size: 0.7rem;
}

/* --- Target tree --- */
.strike-tree {
  display: grid;
  gap: 0.25rem;
  margin-top: 0.25rem;
}

.strike-tree-row {
  display: flex;
  align-items: stretch;
  gap: 0.3rem;
}

.strike-tree-arrow {
  flex: 0 0 auto;
  width: 1.4rem;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 0.7rem;
}

.strike-tree-arrow-empty {
  cursor: default;
}

.strike-tree-children {
  display: grid;
  gap: 0.25rem;
  margin-left: 1.7rem;
  padding-left: 0.5rem;
  border-left: 1px solid var(--border);
}

/* A targetable cell: blue untargeted, red by this strike, orange by another. */
.strike-node {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 0.45rem;
  text-align: left;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border);
  border-left-width: 3px;
  border-radius: 4px;
  background: var(--surface-low);
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.strike-node[data-paint-node] {
  cursor: pointer;
}

.strike-node[data-paint-node]:hover {
  background: var(--surface-mid);
}

.strike-node.inert {
  opacity: 0.5;
}

.strike-node.tgt-none {
  border-left-color: var(--primary-hot);
}

.strike-node.tgt-self {
  border-left-color: var(--red);
  background: rgba(255, 82, 82, 0.12);
}

.strike-node.tgt-other {
  border-left-color: var(--secondary-hot);
  background: rgba(254, 179, 0, 0.1);
}

.strike-node-complex {
  padding: 0.75rem 0.8rem;
  min-height: 52px;
}

.strike-node-complex .strike-node-name {
  font-family: var(--display);
  color: var(--primary);
  font-size: 0.95rem;
}

.strike-node-complex .strike-node-hex {
  font-size: 0.8rem;
}

.strike-node-complex .strike-tree-art {
  width: 26px;
  height: 26px;
}

.strike-node-complex .strike-assigned-pin {
  font-size: 1.1rem;
}

.strike-node-complex .strike-node-count {
  font-size: 0.9rem;
}

.strike-node-complex .strike-over {
  font-size: 0.9rem;
}

.strike-node-complex .strike-stale {
  font-size: 0.75rem;
}

.strike-tree-row:has(.strike-node-complex) .strike-tree-arrow {
  font-size: 1rem;
}

.strike-node-name {
  flex: 1 1 auto;
  overflow-wrap: anywhere;
}

.strike-intact {
  color: var(--muted);
}

.strike-node-hex {
  color: var(--muted);
  font-size: 0.66rem;
}

/* stale_last_known hex: last-known position, carrier may have moved. Warm tint +
   dotted underline echo the map's dashed stale marker so it reads as uncertain. */
.strike-node-hex.is-stale {
  color: var(--secondary-hot);
  text-decoration: underline dotted;
}

.strike-tree-art {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 3px;
  background-size: cover;
  background-position: center;
}

.strike-tree-art-fallback {
  background: linear-gradient(135deg, var(--surface-high), var(--surface-mid));
  border: 1px solid var(--border);
}

.strike-assigned-pin {
  color: var(--primary-hot);
}

.strike-node-count {
  flex: 0 0 auto;
  font-weight: 600;
  color: var(--primary);
}

.strike-over {
  flex: 0 0 auto;
  color: var(--secondary-hot);
}

.strike-stale {
  flex: 0 0 auto;
  font-size: 0.62rem;
  color: var(--muted);
}

.strike-stale.is-stale {
  color: var(--secondary-hot);
}

.strike-detail-empty {
  padding: 1.5rem;
  border: 1px dashed var(--border);
  text-align: center;
}

@media (max-width: 1100px) {
  .strike-planner-grid {
    grid-template-columns: 1fr;
  }

  .strike-planner-list {
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding-right: 0;
    padding-bottom: 0.75rem;
  }
}

.summary-card {
  display: grid;
  gap: 0.45rem;
  margin-bottom: 0.75rem;
}

.summary-card dl,
.summary-card p {
  margin: 0;
}

.summary-card dl {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: 0.35rem 0.55rem;
  font-family: var(--mono);
  font-size: 0.78rem;
}

.summary-card dt {
  color: var(--muted);
}

.summary-card dd {
  margin: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* Annunciator plate: per-slot session telemetry as recessed indicator lamps. */
.annunciator {
  display: grid;
  grid-template-columns: minmax(0, 1fr) repeat(3, 2.2rem) auto;
  align-items: center;
  row-gap: 0.4rem;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: rgba(4, 6, 5, 0.6);
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.55),
    inset 0 -1px 0 rgba(255, 255, 255, 0.04);
}

.annunciator-row {
  display: contents;
}

.annunciator-header span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-align: center;
  text-transform: uppercase;
}

.annunciator-label {
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
}

.annunciator .lamp {
  justify-self: center;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: radial-gradient(
    circle at 35% 30%,
    rgba(255, 255, 255, 0.14),
    rgba(10, 12, 10, 0.95) 65%
  );
  box-shadow:
    inset 0 1px 2px rgba(0, 0, 0, 0.8),
    0 1px 0 rgba(255, 255, 255, 0.06);
}

.annunciator .lamp[data-state="green"] {
  background: radial-gradient(circle at 35% 30%, #b6ffd2, var(--lamp-green) 60%, #0f5a2c);
  box-shadow:
    0 0 7px rgba(61, 255, 124, 0.55),
    inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

.annunciator .lamp[data-state="amber"] {
  background: radial-gradient(circle at 35% 30%, #ffe2a3, var(--lamp-amber) 60%, #7a5200);
  box-shadow:
    0 0 7px rgba(255, 179, 0, 0.55),
    inset 0 1px 1px rgba(255, 255, 255, 0.4);
  animation: annunciator-await 1.6s steps(2, jump-none) infinite;
}

.annunciator .lamp[data-state="red"] {
  background: radial-gradient(circle at 35% 30%, #ffc2c2, var(--lamp-red) 60%, #6e1414);
  box-shadow:
    0 0 7px rgba(255, 79, 79, 0.55),
    inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

@keyframes annunciator-await {
  50% {
    opacity: 0.35;
  }
}

@media (prefers-reduced-motion: reduce) {
  .annunciator .lamp[data-state="amber"] {
    animation: none;
  }
}

.annunciator-na {
  justify-self: center;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.7rem;
}

.annunciator-action {
  justify-self: end;
  min-height: 1px;
}

.annunciator-action button {
  padding: 0.1rem 0.4rem;
  font-size: 0.62rem;
}

/* Directive readout: the next-action line that replaced the Phase 1 banner. */
.annunciator-directive {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  color: var(--phos-amber);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.annunciator-directive.ok {
  color: var(--lamp-green);
}

.annunciator-directive button {
  flex: 0 0 auto;
}

.gantt-panel {
  flex: 0 0 auto;
  margin-top: 0;
  padding: 0.55rem;
  overflow: hidden;
}

.gantt-window-controls {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.25rem;
  width: 100%;
}

.gantt-window-controls button {
  min-height: 18px;
  height: 18px;
  padding: 0 0.42rem;
  font-size: 0.64rem;
}

.gantt-window-controls .data-readout {
  min-width: 0;
  padding: 0 0.36rem;
  line-height: 16px;
  text-align: center;
  white-space: nowrap;
}

/* Gantt grid is glass: phosphor schedule readout behind a gasket edge. */
.gantt-grid {
  --gantt-mission-col: 190px;
  --gantt-hour-min: 720px;
  display: grid;
  grid-template-columns: var(--gantt-mission-col) minmax(var(--gantt-hour-min), 1fr);
  grid-template-rows: 42px minmax(0, auto);
  border: 1px solid var(--gasket);
  border-radius: 2px;
  overflow: auto;
  background: var(--glass-bg);
  box-shadow: inset 0 4px 14px rgba(0, 0, 0, 0.6), 0 1px 0 var(--bezel-hi);
}

/* Ownership controls share the existing 42px header; no additional dock row. */
.gantt-ownership-filters {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 3px;
  width: 100%;
}

.gantt-ownership-filters button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  white-space: nowrap;
  letter-spacing: 0;
  min-height: 18px;
  height: 18px;
  padding: 0 3px;
  font-size: 0.62rem;
  line-height: 16px;
}

.gantt-ownership-filters button[aria-pressed="true"] {
  background: var(--chassis-500);
  box-shadow: inset 0 -2px 0 var(--stencil);
}

.gantt-ownership-filters [data-gantt-ownership="mine"]::before,
.gantt-ownership-filters [data-gantt-ownership="allied"]::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  flex: 0 0 5px;
  background: rgb(var(--owner-rgb));
}

/* Allies span several seats, so their dot stays neutral (OCT23). */
.gantt-ownership-filters [data-gantt-ownership="allied"]::before {
  background: var(--stencil);
}

.gantt-window-cell,
.gantt-hours {
  min-height: 42px;
  align-items: center;
  border-bottom: 1px solid rgba(122, 214, 156, 0.14);
  font-family: var(--mono);
  color: rgba(158, 240, 180, 0.6);
  font-size: 0.72rem;
  text-transform: uppercase;
}

.gantt-window-cell {
  position: sticky;
  left: 0;
  z-index: 4;
  display: grid;
  grid-template-rows: 18px 18px;
  gap: 2px;
  padding: 2px 0.35rem;
  border-right: 1px solid rgba(122, 214, 156, 0.14);
  background: #071409;
}

.gantt-hours {
  position: relative;
  min-width: var(--gantt-hour-min);
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  padding: 0 10px;
  box-sizing: border-box;
}

.gantt-hours span {
  display: grid;
  place-items: center;
  height: 100%;
  border-left: 1px solid rgba(122, 214, 156, 0.12);
  pointer-events: none;
  z-index: 1;
}

@keyframes lri-armed-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.45;
  }
}

.gantt-preview-track {
  position: absolute;
  inset: 4px 10px;
  z-index: 2;
  display: flex;
  align-items: center;
  padding: 0;
  background: transparent;
  box-sizing: border-box;
}

.gantt-preview-track input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 24px;
  background: transparent;
  margin: 0;
  padding: 0;
  cursor: ew-resize;
  border: none;
}

.gantt-preview-track input[type="range"]:focus {
  outline: none;
}

.gantt-preview-track input[type="range"]::-webkit-slider-runnable-track {
  width: 100%;
  height: 24px;
  background: rgba(8, 11, 9, 0.55);
  border: 1px solid rgba(122, 214, 156, 0.2);
  border-radius: 3px;
}

.gantt-preview-track input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 8.333%;
  height: 22px;
  background: rgba(254, 179, 0, 0.2);
  border: 1px solid var(--secondary-hot);
  box-shadow: 0 0 8px rgba(254, 179, 0, 0.5);
  border-radius: 2px;
  cursor: ew-resize;
}

.gantt-preview-track input[type="range"]::-moz-range-track {
  width: 100%;
  height: 24px;
  background: rgba(8, 11, 9, 0.55);
  border: 1px solid rgba(122, 214, 156, 0.2);
  border-radius: 3px;
}

.gantt-preview-track input[type="range"]::-moz-range-thumb {
  width: 8.333%;
  height: 22px;
  background: rgba(254, 179, 0, 0.2);
  border: 1px solid var(--secondary-hot);
  box-shadow: 0 0 8px rgba(254, 179, 0, 0.5);
  border-radius: 2px;
  cursor: ew-resize;
}

.gantt-body {
  grid-column: 1 / -1;
  max-height: 200px;
  min-width: calc(var(--gantt-mission-col) + var(--gantt-hour-min));
  overflow-y: auto;
}

.gantt-row {
  display: grid;
  grid-template-columns: var(--gantt-mission-col) minmax(var(--gantt-hour-min), 1fr);
  min-height: 40px;
  border-bottom: 1px solid rgba(122, 214, 156, 0.14);
}

.gantt-row.selected {
  background: rgba(70, 232, 140, 0.08);
  border-left: 4px solid var(--primary-hot);
}

.gantt-flight {
  position: sticky;
  left: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0 0.65rem;
  border-right: 1px solid var(--border);
  background: var(--surface-lowest);
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--primary);
}

.gantt-mission-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gantt-issue-marker {
  flex: 0 0 auto;
  color: var(--red);
  font-weight: 800;
  letter-spacing: 0;
  text-shadow: 0 0 8px rgba(255, 82, 82, 0.5);
  cursor: help;
}

.gantt-flight.has-issues {
  color: var(--text);
}

.gantt-row.selected .gantt-flight {
  background: rgba(21, 27, 22, 0.9);
  color: var(--text);
  font-weight: 700;
}

.gantt-track {
  position: relative;
  margin: 8px 10px;
  min-height: 24px;
  overflow: visible;
  background: repeating-linear-gradient(90deg, transparent 0 calc(8.333% - 1px), rgba(122, 214, 156, 0.14) calc(8.333% - 1px) 8.333%);
}

.gantt-preview-line {
  position: absolute;
  top: -8px;
  bottom: -8px;
  width: 2px;
  z-index: 1;
  transform: translateX(-50%);
  pointer-events: none;
  background: var(--secondary-hot);
  box-shadow: 0 0 8px rgba(254, 179, 0, 0.55);
}

/* Hours already resolved by the server during execution ("real"), dimmed apart
   from the pre-plan still ahead. The right border is the live "now" boundary. */
.gantt-executed-overlay {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  z-index: 0;
  pointer-events: none;
  background: rgba(6, 12, 20, 0.42);
  border-right: 2px solid rgba(70, 232, 140, 0.85);
  box-shadow: 0 0 8px rgba(70, 232, 140, 0.35);
}

.gantt-bar {
  position: absolute;
  top: 2px;
  bottom: 2px;
  min-width: 28px;
  display: grid;
  place-items: center;
  border: 1px solid var(--primary-hot);
  color: var(--primary);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(0, 218, 243, 0.18);
  font-family: var(--mono);
  font-size: 0.7rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: grab;
  user-select: none;
  touch-action: none;
  z-index: 3;
  transition: box-shadow 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}

.gantt-bar:active {
  cursor: grabbing;
}

.gantt-bar.selected {
  box-shadow: 0 0 12px rgba(70, 232, 140, 0.65);
  border-width: 1.5px;
}

.gantt-row.preview-active .gantt-flight {
  color: var(--secondary);
}

.gantt-bar.preview-active {
  box-shadow: 0 0 14px rgba(254, 179, 0, 0.55);
  border-color: var(--secondary-hot);
}

.gantt-bar.dragging {
  opacity: 0.8;
  z-index: 10;
  cursor: grabbing;
}

.gantt-bar-text {
  position: relative;
  z-index: 4;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

.gantt-phase {
  position: absolute;
  top: 0;
  bottom: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  padding: 0 0.35rem;
  text-overflow: ellipsis;
}

.gantt-phase-ingress {
  color: var(--muted);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(148, 163, 184, 0.22);
}

.gantt-phase-station {
  color: var(--primary);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(0, 218, 243, 0.22);
}

.gantt-bar.strike .gantt-phase-station {
  color: var(--red);
  background-color: rgba(255, 82, 82, 0.22);
}

.gantt-bar.patrol .gantt-phase-station,
.gantt-bar.passive .gantt-phase-station {
  color: var(--green);
  background-color: rgba(0, 230, 118, 0.2);
}

.gantt-bar.defensive .gantt-phase-station,
.gantt-bar.defensive-alert .gantt-phase-station {
  color: var(--secondary);
  background-color: rgba(254, 179, 0, 0.22);
}

/* Sortie itinerary segments (JUL15 §2.4): one Gantt row per Sortie, its legs
   placed by the server-compiled schedule; Transit display stops before a
   following Mission takes over its arrival hour.
   Transit reuses the grey ingress fill; each mission leg takes its type color.
   A click on any segment selects (sortieId, entryId), so all segments are
   pointer-interactive — including the locked prefix. */
.sortie-row .gantt-phase,
.alert-row .gantt-phase {
  border: 1px solid rgba(122, 214, 156, 0.35);
  border-radius: 2px;
  font-family: var(--mono);
  font-size: 0.68rem;
  z-index: 2;
  cursor: pointer;
}

/* Mission fills retain task meaning; ownership uses the gutter and edges. */
/* OCT23: the owner color is the controlling Blue seat (see --owner-rgb). */
.sortie-row[data-ownership],
.alert-row[data-ownership] {
  --gantt-owner-color: rgb(var(--owner-rgb));
  --gantt-owner-tint: rgba(var(--owner-rgb), 0.08);
}

.sortie-row[data-ownership] .gantt-flight,
.alert-row[data-ownership] .gantt-flight {
  border-left: 3px solid var(--gantt-owner-color);
  background: linear-gradient(var(--gantt-owner-tint), var(--gantt-owner-tint)), var(--surface-lowest);
}

.gantt-owner-tag {
  flex: 0 0 auto;
  color: var(--gantt-owner-color);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: 0 3px;
  font-size: 0.6rem;
  line-height: 1.4;
}

.sortie-row[data-ownership] .gantt-phase,
.alert-row[data-ownership] .gantt-phase {
  border-color: var(--gantt-owner-color);
}

.sortie-row[data-ownership="allied"].selected,
.alert-row[data-ownership="allied"].selected {
  border-left-color: var(--gantt-owner-color);
  background: var(--gantt-owner-tint);
}

.sortie-row .gantt-phase.is-resizing {
  z-index: 9;
  overflow: visible;
  box-shadow: 0 0 12px rgba(70, 232, 140, 0.65);
}

.sortie-row .gantt-duration-handle {
  right: 0;
  transform: none;
}

.sortie-row .gantt-phase-strike {
  color: var(--red);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(255, 82, 82, 0.22);
}

.sortie-row .gantt-phase-patrol,
.sortie-row .gantt-phase-passive {
  color: var(--green);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(0, 230, 118, 0.2);
}

.sortie-row .gantt-phase-mission {
  color: var(--primary);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(0, 218, 243, 0.22);
}

/* A Transit inside its Mission's arrival hour: a sliver over the left of the
   Mission bar (OCT24 polish Q4), opaque so the Mission fill does not show through. */
.sortie-row .gantt-phase.is-folded {
  z-index: 3;
  padding: 0;
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgb(74, 84, 98);
}

/* Resolved/live prefix: locked (§2.4). Dimmed and dashed so it reads as
   "already flown — selectable for view, not editable". */
.sortie-row .gantt-phase.is-immutable {
  opacity: 0.5;
  border-style: dashed;
  filter: saturate(0.5);
}

/* Hours not yet confirmed by the server after a local edit (§2.5): a hatched,
   pulsing treatment distinct from .is-immutable — this reads as "recomputing",
   not "locked" or "broken". Covers both a fixed-width placeholder segment (a
   structurally-new/moved entry with no compiled hours at all yet) and a
   segment still showing its pre-edit hours while a fresh schedule is in flight. */
.sortie-row .gantt-phase.is-pending {
  border-style: dashed;
  background: repeating-linear-gradient(
    45deg,
    rgba(159, 174, 159, 0.18) 0 6px,
    rgba(159, 174, 159, 0.32) 6px 12px
  );
  animation: gantt-phase-pending-pulse 1.6s ease-in-out infinite;
}

@keyframes gantt-phase-pending-pulse {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 0.85;
  }
}

/* Intervention splice lock line (JUL15 §2.8, ADR 0021): the straddling entry
   an intervention truncates in place stays one real, immutable segment, but a
   vertical line through it marks where "already flown" ends and the seeded
   remainder (a separate, later segment) begins. */
.sortie-row .gantt-phase .gantt-lock-line {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  background: #ffce8a;
  box-shadow: 0 0 4px rgba(255, 179, 71, 0.8);
  pointer-events: none;
}

/* OP boundary chip: hours a clipped segment runs past the window edge, plus
   Patrol duration steppers so the edge isn't a drag target. */
.sortie-row .gantt-boundary-chip,
.alert-row .gantt-boundary-chip {
  position: absolute;
  top: 1px;
  bottom: 1px;
  z-index: 4;
  display: flex;
  align-items: stretch;
  gap: 1px;
  pointer-events: none;
  font-family: var(--mono);
  font-size: 0.62rem;
}

.sortie-row .gantt-boundary-end,
.alert-row .gantt-boundary-end {
  right: 0;
}

.sortie-row .gantt-boundary-chip.is-pending {
  opacity: 0.75;
}

.sortie-row .gantt-boundary-count,
.alert-row .gantt-boundary-count {
  display: grid;
  place-items: center;
  padding: 0 3px;
  color: var(--text);
  background: rgba(6, 12, 20, 0.78);
  border: 1px solid var(--gantt-owner-color, var(--border));
  border-radius: 2px;
  pointer-events: auto;
  cursor: help;
}

.sortie-row .gantt-boundary-step {
  width: 15px;
  padding: 0;
  font: inherit;
  font-weight: 800;
  line-height: 1;
  color: var(--primary-hot);
  background: rgba(6, 12, 20, 0.85);
  border: 1px solid var(--primary-hot);
  border-radius: 2px;
  pointer-events: auto;
  cursor: pointer;
}

.sortie-row .gantt-boundary-step:hover:not(:disabled) {
  background: rgba(70, 232, 140, 0.25);
}

.sortie-row .gantt-boundary-step:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.gantt-handle {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 18px;
  z-index: 8;
  transform: translateX(-50%);
  cursor: ew-resize;
  touch-action: none;
}

.gantt-handle::after {
  content: "";
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 8px;
  border-left: 2px solid rgba(255, 255, 255, 0.75);
  box-shadow: 0 0 6px rgba(70, 232, 140, 0.5);
}

.gantt-handle-station::after {
  border-left-style: dashed;
}

.gantt-handle-end {
  transform: translateX(-100%);
}

.gantt-bar-overflow-mask {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    45deg,
    rgba(0, 0, 0, 0.15),
    rgba(0, 0, 0, 0.15) 6px,
    transparent 6px,
    transparent 12px
  );
}

.continues-next-op {
  border-right-style: dashed;
}

.continues-from-previous-op {
  border-left-style: dashed;
}

.continues-next-op .gantt-bar-overflow-mask {
  border-right: 1px dashed rgba(255, 255, 255, 0.35);
}

.continues-from-previous-op .gantt-bar-overflow-mask {
  border-left: 1px dashed rgba(255, 255, 255, 0.35);
}

.gantt-bar.strike {
  border-color: var(--red);
  color: var(--red);
  background-color: rgba(255, 82, 82, 0.18);
}

.gantt-bar.patrol,
.gantt-bar.passive {
  border-color: var(--green);
  color: var(--green);
  background-color: rgba(0, 230, 118, 0.14);
}

.gantt-bar.defensive,
.gantt-bar.defensive-alert {
  border-color: var(--secondary-hot);
  color: var(--secondary);
  background-color: rgba(254, 179, 0, 0.16);
}

.playback-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 420px);
  gap: 0.75rem;
}

.combat-summary-list {
  display: grid;
  gap: 0.35rem;
}

.mission-activity-list {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mission-activity-list li {
  display: grid;
  gap: 0.12rem;
  padding: 0.38rem 0.5rem;
  border: 1px solid rgba(122, 214, 156, 0.18);
  background: rgba(70, 232, 140, 0.06);
}

.mission-activity-list strong {
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.35;
}

.mission-activity-meta {
  color: rgba(195, 245, 255, 0.68);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.combat-reopen {
  width: 100%;
  min-height: 30px;
  padding: 0.35rem 0.5rem;
  text-align: left;
  color: var(--primary-hot);
  border-color: rgba(122, 214, 156, 0.5);
  background: rgba(70, 232, 140, 0.08);
  font-size: 0.68rem;
}

.combat-window-root {
  position: fixed;
  inset: 0 0 0 64px;
  z-index: 24;
  padding: 0.55rem 0.7rem;
  overflow: auto;
  background:
    linear-gradient(rgba(10, 15, 11, 0.78), rgba(10, 15, 11, 0.92)),
    radial-gradient(circle at 50% 10%, rgba(70, 232, 140, 0.08), transparent 36%),
    var(--background-deep);
  opacity: 0;
  transition: opacity 0.22s ease;
}

.combat-window-root.is-open {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .combat-window-root {
    transition: none;
  }
}

.combat-window-root::before {
  content: "";
  position: fixed;
  inset: 0 0 0 64px;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0.025) 1px, transparent 1px, transparent 4px),
    url("data:image/svg+xml,%3Csvg width='60' height='104' viewBox='0 0 60 104' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M30 0l30 17.32v34.64L30 69.28 0 51.96V17.32L30 0zm0 104l30-17.32V51.96L30 34.64 0 51.96v34.64L30 104z' fill='%231a2634' fill-opacity='.17'/%3E%3C/svg%3E");
  opacity: 0.7;
}

.combat-window-shell {
  position: relative;
  z-index: 1;
  min-height: calc(100vh - 75px);
  max-height: calc(100vh - 75px);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 0.5rem;
}

.combat-window-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.55rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid rgba(122, 214, 156, 0.35);
  background: rgba(8, 11, 9, 0.78);
  border-radius: 3px;
}

.combat-window-header span,
.combat-command header span,
.combat-meter span,
.combat-state span,
.combat-slot-label,
.combat-raw summary,
.combat-encounter-select {
  font-family: var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.combat-window-header h2 {
  margin: 0.1rem 0 0;
  font-family: var(--display);
  font-size: clamp(1rem, 2vw, 1.45rem);
  letter-spacing: 0;
}

.combat-window-header > div:first-child > span {
  color: var(--primary-hot);
  font-size: 0.72rem;
}

.combat-header-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.combat-header-chip {
  min-height: 32px;
  display: inline-grid;
  place-items: center;
  padding: 0.35rem 0.65rem;
  border: 1px solid var(--border);
  color: var(--muted);
  background: rgba(10, 15, 11, 0.82);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
}

.combat-encounter-select {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--muted);
  font-size: 0.68rem;
}

.combat-encounter-select select {
  min-height: 32px;
  min-width: 220px;
}

.combat-close {
  border-color: rgba(255, 82, 82, 0.45);
  color: var(--red);
}

.combat-window-grid {
  display: grid;
  grid-template-columns: minmax(200px, 260px) minmax(200px, 1fr) 36px minmax(200px, 1fr) minmax(200px, 260px);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 0.75rem;
  align-items: stretch;
  min-height: 0;
}

.combat-slot-rail {
  display: grid;
  grid-template-rows: repeat(4, minmax(118px, 1fr));
  gap: 0.55rem;
  min-height: 0;
}

.combat-slot {
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(42px, 1fr) 34px;
  min-height: 118px;
  padding: 0;
  overflow: hidden;
  border-color: rgba(122, 214, 156, 0.42);
  color: var(--primary-hot);
  background: rgba(10, 15, 11, 0.82);
  text-align: left;
}

.combat-slot.red {
  border-color: rgba(255, 82, 82, 0.46);
  color: var(--red);
}

.combat-slot.selected {
  box-shadow: 0 0 18px rgba(70, 232, 140, 0.28);
}

.combat-slot.red.selected {
  box-shadow: 0 0 18px rgba(255, 82, 82, 0.26);
}

.combat-slot.empty {
  opacity: 0.52;
  color: var(--outline);
  border-color: rgba(26, 38, 52, 0.72);
}

.combat-slot-label {
  padding: 0.55rem 0.65rem 0;
  font-size: 0.72rem;
  font-weight: 700;
}

.combat-slot-art {
  display: grid;
  place-items: center;
  gap: 0.2rem;
  min-height: 0;
  padding: 0.35rem 0.5rem;
}

.combat-slot-art img {
  width: min(62%, 96px);
  aspect-ratio: 1;
  object-fit: contain;
  filter: drop-shadow(0 0 10px rgba(70, 232, 140, 0.26));
}

.combat-slot.red .combat-slot-art img {
  filter: drop-shadow(0 0 10px rgba(255, 82, 82, 0.25));
}

.combat-fallback-icon,
.combat-empty-mark {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-family: var(--mono);
  font-size: 0.8rem;
  opacity: 0.72;
}

.combat-empty-copy {
  margin-top: 0.25rem;
  color: var(--outline);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  text-align: center;
  text-transform: uppercase;
}

.combat-slot-footer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 58px;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--text);
}

.combat-slot-footer span,
.combat-slot-footer strong {
  display: grid;
  place-items: center;
  min-width: 0;
  padding: 0 0.4rem;
}

.combat-slot-footer span {
  border-right: 1px solid var(--border);
}

.combat-slot-footer strong {
  font-weight: 700;
}

.combat-slot-footer strong.ok {
  color: var(--green);
}

.combat-slot-footer strong.damaged,
.combat-slot-footer strong.destroyed {
  color: var(--red);
}

.combat-slot-footer strong.empty {
  color: var(--outline);
}

.combat-command {
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(112px, 1fr) minmax(104px, 0.8fr) auto;
  gap: 0.55rem;
  padding: 0.9rem 1rem;
  overflow: hidden;
  border: 1px solid rgba(122, 214, 156, 0.35);
  background:
    linear-gradient(rgba(255, 255, 255, 0.018), rgba(255, 255, 255, 0.018) 1px, transparent 1px, transparent 4px),
    rgba(10, 15, 11, 0.86);
  border-radius: 3px;
}

.combat-command.red {
  border-color: rgba(255, 82, 82, 0.36);
}

.combat-command-accent {
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: var(--primary-hot);
}

.combat-command.red .combat-command-accent {
  background: var(--red);
}

.combat-command header {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
}

.combat-command header span {
  color: var(--primary-hot);
  font-size: 0.76rem;
  font-weight: 700;
}

.combat-command.red header span {
  color: var(--red);
}

.combat-command header h3 {
  margin: 0.25rem 0 0;
  color: var(--text);
  font-family: var(--display);
  font-size: clamp(1.1rem, 2.1vw, 1.75rem);
  line-height: 1.05;
  letter-spacing: 0;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.combat-command header b {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.8rem;
}

.combat-meter,
.combat-state {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 104px;
  border: 1px solid var(--border);
  background: rgba(8, 11, 9, 0.52);
}

.combat-meter span,
.combat-state span {
  position: absolute;
  top: 0.55rem;
  left: 0.6rem;
  color: var(--outline);
  font-size: 0.72rem;
}

.combat-meter strong {
  color: var(--primary-hot);
  font-family: var(--display);
  font-size: clamp(2.5rem, 5vw, 4.1rem);
  line-height: 1;
  text-shadow: 0 0 16px rgba(70, 232, 140, 0.45);
}

.combat-command.red .combat-meter strong {
  color: var(--red);
  text-shadow: 0 0 16px rgba(255, 82, 82, 0.42);
}

.combat-state {
  border-color: rgba(122, 214, 156, 0.56);
  box-shadow: inset 0 0 18px rgba(70, 232, 140, 0.08), 0 0 14px rgba(70, 232, 140, 0.15);
}

.combat-command.red .combat-state {
  border-color: rgba(255, 82, 82, 0.58);
  box-shadow: inset 0 0 18px rgba(255, 82, 82, 0.08), 0 0 14px rgba(255, 82, 82, 0.14);
}

.combat-state strong {
  color: var(--text);
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.8vw, 1.65rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
}

.combat-actions {
  display: grid;
  gap: 0.45rem;
}

.combat-actions button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 38px;
  padding: 0.45rem 0.75rem;
  color: var(--primary-hot);
  border-color: rgba(122, 214, 156, 0.5);
  background: rgba(10, 15, 11, 0.72);
}

.combat-command.red .combat-actions button {
  color: var(--red);
  border-color: rgba(255, 82, 82, 0.38);
}

.combat-actions button i {
  color: var(--muted);
  font-style: normal;
  font-size: 0.7rem;
}

.combat-actions.disabled {
  opacity: 0.54;
}

.combat-afterburner {
  display: grid;
  gap: 0.35rem;
  padding: 0.55rem;
  border: 1px solid rgba(245, 184, 75, 0.36);
  background: rgba(41, 25, 6, 0.3);
}

.combat-afterburner > span {
  color: var(--warning, #f5b84b);
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 700;
}

.combat-afterburner > div {
  display: grid;
  gap: 0.35rem;
}

.combat-afterburner button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 32px;
  padding: 0.35rem 0.55rem;
  color: var(--warning, #f5b84b);
  border-color: rgba(245, 184, 75, 0.42);
  background: rgba(10, 15, 11, 0.7);
}

.combat-afterburner button.active {
  color: #10140c;
  background: var(--warning, #f5b84b);
}

.combat-afterburner button small {
  color: inherit;
  font-family: var(--mono);
  font-size: 0.66rem;
}

.combat-afterburner.disabled {
  opacity: 0.54;
}

/* An ally's flight: read-only mirror of its owner's selection. */
.combat-afterburner button.peer {
  border-style: dashed;
  opacity: 0.6;
}

/* Round-by-round animation timeline (MAY31 combat dialogue pass) */
.combat-timeline-controls {
  display: inline-flex;
  gap: 0.4rem;
}

.combat-timeline-btn {
  min-height: 28px;
  padding: 0.2rem 0.7rem;
  color: var(--primary-hot);
  border: 1px solid rgba(122, 214, 156, 0.5);
  background: rgba(10, 15, 11, 0.72);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
}

/* AGI box: base score chip + win/lose settle colour (Phase 2 refines easing). */
.combat-agi-base {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.82rem;
  opacity: 0.8;
}

.combat-agi-value.rolling {
  opacity: 0.85;
}

.combat-agi-value.agi-win {
  color: var(--green);
  text-shadow: 0 0 16px rgba(63, 224, 138, 0.5);
}

.combat-agi-value.agi-lose {
  color: #ff8a3d;
  text-shadow: 0 0 16px rgba(255, 138, 61, 0.45);
}

/* Craft-box callouts (Phase 4 refines the rise/fade motion). */
.combat-callout {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  padding: 2px 9px;
  border: 1px solid currentColor;
  background: rgba(8, 11, 9, 0.86);
  font-family: var(--mono);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  white-space: nowrap;
  pointer-events: none;
  animation-name: combat-callout-rise;
  animation-timing-function: cubic-bezier(0.2, 0.8, 0.2, 1);
  animation-fill-mode: both;
}

.combat-callout.shooting {
  color: var(--primary-hot);
}

.combat-callout.hit {
  color: #ff8a3d;
}

.combat-callout.miss {
  color: var(--muted);
}

.combat-callout.kill {
  color: var(--red);
}

.combat-callout.evading,
.combat-callout.disengaging {
  color: var(--secondary-hot);
}

.combat-callout.backslide {
  color: var(--primary-hot);
  border-color: var(--primary-hot);
}

/* Encounter procs (OCT21 proc visibility). */
.combat-callout.intercept {
  color: #8ff0a4;
  border-color: #8ff0a4;
}

.combat-callout.killbox,
.combat-callout.kickback,
.combat-callout.afterburner {
  color: var(--secondary-hot);
  border-color: var(--secondary-hot);
}

/* Fogged enemy craft shown as a generic CONTACT. */
.combat-slot.contact .combat-slot-art img {
  filter: grayscale(1) brightness(0.7);
}

.combat-slot.effect-shake .combat-slot-art,
.combat-slot.effect-kill-fade .combat-slot-art {
  animation-name: combat-slot-shake;
  animation-play-state: var(--effect-play-state, running);
  animation-delay: var(--effect-delay, 0ms);
  animation-duration: 400ms;
  animation-timing-function: linear;
  animation-iteration-count: 1;
}

.combat-slot.effect-kill-fade .combat-slot-art img,
.combat-slot.effect-kill-fade .combat-fallback-icon {
  animation-name: combat-kill-fade;
  animation-play-state: var(--effect-play-state, running);
  animation-delay: var(--effect-delay, 0ms);
  animation-duration: 2000ms;
  animation-timing-function: ease-out;
  animation-fill-mode: both;
}

.combat-slot.effect-backfill {
  animation: combat-backfill-slide 600ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes combat-callout-rise {
  0% {
    opacity: 0;
    transform: translate(-50%, 8px) scale(0.92);
  }
  18% {
    opacity: 1;
    transform: translate(-50%, 0) scale(1);
  }
  72% {
    opacity: 1;
    transform: translate(-50%, -8px) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -18px) scale(0.98);
  }
}

@keyframes combat-slot-shake {
  0%, 100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-7px);
  }
  40% {
    transform: translateX(7px);
  }
  60% {
    transform: translateX(-5px);
  }
  80% {
    transform: translateX(5px);
  }
}

@keyframes combat-kill-fade {
  0% {
    opacity: 1;
    filter: saturate(1.2) brightness(1.2);
  }
  55% {
    opacity: 0.8;
    filter: saturate(0.7) brightness(0.9);
  }
  100% {
    opacity: 0.22;
    filter: grayscale(1) brightness(0.55);
  }
}

@keyframes combat-backfill-slide {
  0% {
    opacity: 0.65;
    transform: translateY(14px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .combat-callout,
  .combat-slot.effect-shake .combat-slot-art,
  .combat-slot.effect-kill-fade .combat-slot-art,
  .combat-slot.effect-kill-fade .combat-slot-art img,
  .combat-slot.effect-kill-fade .combat-fallback-icon,
  .combat-slot.effect-backfill {
    animation-duration: 1ms !important;
  }
}

/* "ENCOUNTER COMPLETE" flash shown for ~2.5s once an encounter resolves */
.combat-complete-overlay {
  position: absolute;
  inset: 0;
  z-index: 12;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: radial-gradient(circle at center, rgba(4, 9, 18, 0.55), rgba(4, 9, 18, 0.82));
  animation: combat-complete-fade 2.5s ease forwards;
}

.combat-complete-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 18px 42px;
  border-radius: 14px;
  border: 1px solid rgba(120, 220, 170, 0.6);
  background: linear-gradient(150deg, rgba(11, 30, 24, 0.95), rgba(6, 16, 13, 0.96));
  box-shadow: 0 18px 44px rgba(2, 6, 16, 0.6);
  animation: combat-complete-pop 2.5s ease forwards;
}

.combat-complete-card strong {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  color: #aef3cf;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
}

.combat-complete-subtitle {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: #cfe6dd;
}

@keyframes combat-complete-fade {
  0% { opacity: 0; }
  12% { opacity: 1; }
  82% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes combat-complete-pop {
  0% { opacity: 0; transform: scale(0.9); }
  12% { opacity: 1; transform: scale(1.04); }
  20% { transform: scale(1); }
  82% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.96); }
}

@media (prefers-reduced-motion: reduce) {
  .combat-complete-overlay,
  .combat-complete-card {
    animation-timing-function: steps(1, end);
  }
}

/* Mid-combat decision handshake (MAY30 pass) */
.combat-decision-body {
  display: grid;
  grid-template-rows: auto auto auto 1fr;
  gap: 0.7rem;
  padding: 0.7rem;
  border: 1px solid rgba(255, 193, 7, 0.4);
  background: rgba(8, 11, 9, 0.78);
  border-radius: 3px;
  overflow: auto;
}

.combat-decision-rosters {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.7rem;
}

.combat-decision-roster {
  border: 1px solid var(--border);
  background: rgba(10, 15, 11, 0.55);
  padding: 0.5rem 0.6rem;
}

.combat-decision-roster.foe {
  border-color: rgba(255, 82, 82, 0.38);
}

.combat-decision-roster h4 {
  margin: 0 0 0.45rem;
  font-family: var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.72rem;
  color: var(--primary-hot);
}

.combat-decision-roster.foe h4 {
  color: var(--red);
}

.combat-decision-roster ul {
  display: grid;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.combat-decision-roster li {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-auto-rows: auto;
  gap: 0.1rem 0.5rem;
  font-family: var(--mono);
  font-size: 0.74rem;
}

.combat-decision-roster li span {
  color: var(--text);
}

.combat-decision-roster li b {
  color: var(--muted);
  font-weight: 500;
  text-align: right;
}

.combat-decision-roster li em {
  font-style: normal;
  text-transform: uppercase;
  font-size: 0.66rem;
}

.combat-decision-roster li em.ok {
  color: var(--primary-hot);
}

.combat-decision-roster li em.damaged,
.combat-decision-roster li em.destroyed {
  color: var(--red);
}

.combat-decision-roster li small {
  color: var(--muted);
  text-align: right;
}

.combat-decision-prompt {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--text);
}

.combat-decision-controls {
  display: flex;
  align-items: stretch;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.combat-decision-choices {
  display: flex;
  gap: 0.45rem;
  flex: 1 1 auto;
}

.combat-decision-action {
  flex: 1 1 0;
  min-height: 44px;
  padding: 0.5rem 0.8rem;
  font-family: var(--mono);
  letter-spacing: 0.06em;
  color: var(--primary-hot);
  border: 1px solid rgba(122, 214, 156, 0.5);
  background: rgba(10, 15, 11, 0.72);
}

.combat-decision-action.selected {
  color: var(--background-obsidian);
  background: var(--primary-hot);
  border-color: var(--primary-hot);
}

.combat-decision-action:disabled {
  opacity: 0.5;
}

.combat-commit {
  min-width: 130px;
  min-height: 44px;
  padding: 0.5rem 1rem;
  font-family: var(--mono);
  letter-spacing: 0.1em;
  color: var(--primary-hot);
  border: 1px solid rgba(122, 214, 156, 0.6);
  background: rgba(10, 15, 11, 0.72);
}

.combat-commit.go,
.combat-commit:disabled.go {
  color: var(--background-obsidian);
  background: var(--green);
  border-color: var(--green);
  opacity: 1;
}

.combat-commit-status {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-content: flex-start;
}

.combat-commit-flag {
  display: inline-grid;
  place-items: center;
  padding: 0.3rem 0.6rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  border: 1px solid var(--border);
  color: var(--muted);
}

.combat-commit-flag.go {
  color: var(--green);
  border-color: rgba(0, 230, 118, 0.5);
}

.combat-commit-flag.wait {
  color: var(--muted);
}

.combat-vs {
  grid-column: 3;
  display: grid;
  grid-template-rows: 1fr auto 1fr;
  place-items: center;
  min-height: 0;
  color: var(--outline);
  font-family: var(--mono);
  opacity: 0.72;
}

.combat-vs span {
  width: 1px;
  height: 100%;
  background: var(--border);
}

.combat-raw {
  grid-column: 1 / -1;
  border: 1px solid var(--border);
  background: rgba(8, 11, 9, 0.68);
  border-radius: 3px;
}

.combat-raw summary {
  cursor: pointer;
  padding: 0.45rem 0.65rem;
  color: var(--primary-hot);
  font-size: 0.72rem;
}

.combat-raw ol {
  display: grid;
  gap: 0.35rem;
  max-height: 110px;
  margin: 0;
  padding: 0 0.65rem 0.55rem 1.75rem;
  overflow: auto;
  font-family: var(--mono);
  font-size: 0.72rem;
}

.combat-raw li span {
  color: var(--outline);
  margin-right: 0.55rem;
}

.combat-raw li b {
  color: var(--text);
  font-weight: 500;
}

.combat-raw p {
  margin: 0;
  padding: 0 0.65rem 0.55rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.76rem;
}

.loadout-layout,
.carrier-layout,
.raw-layout {
  display: grid;
  gap: 0.75rem;
}

.oob-toolbar {
  align-items: center;
}

.oob-stats-panel {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-left: auto;
}

.oob-stats-panel .separator {
  opacity: 0.4;
  color: var(--gasket);
}

.oob-stats-panel .status {
  min-height: auto;
  font-size: inherit;
  color: inherit;
  font-family: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}

.oob-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
  gap: 0.75rem;
  align-items: start;
}

#oobBuilder {
  display: grid;
  gap: 0.75rem;
}

.oob-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

.oob-squadron,
.oob-munitions,
.oob-sidecar {
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  padding: 0.8rem;
}

.oob-squadron h3,
.oob-munitions h3,
.oob-sidecar h3 {
  margin: 0;
  color: var(--primary);
  font-family: var(--display);
}

.oob-squadron label {
  display: grid;
  gap: 0.3rem;
  margin: 0.65rem 0;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
}

/* EQP slot cards: the assignment targets at the top of each squadron. */
.oob-slots-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 0.75rem;
}

.oob-slots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.45rem;
  margin-top: 0.4rem;
}

.oob-slot {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 2.2rem;
  padding: 0.4rem 0.5rem;
  font-family: var(--mono);
  font-size: 0.72rem;
}

.oob-slot.empty {
  border: 1px dashed var(--outline-soft);
  background: rgba(0, 0, 0, 0.12);
  color: var(--muted);
  justify-content: center;
  text-transform: uppercase;
  font-size: 0.66rem;
}

.oob-slot.filled {
  border: 1px solid var(--primary);
  background: rgba(70, 232, 140, 0.08);
  color: var(--text);
}

.oob-slot.filled.over {
  border-color: var(--secondary-hot);
  background: rgba(255, 90, 90, 0.12);
}

.oob-slot-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.oob-slot-origin {
  color: var(--secondary-hot);
  font-style: normal;
  font-size: 0.62rem;
  text-transform: uppercase;
}

.oob-slot-remove {
  flex: 0 0 auto;
  width: 1.3rem;
  height: 1.3rem;
  padding: 0;
  line-height: 1;
  border: 1px solid var(--outline-soft);
  background: rgba(0, 0, 0, 0.3);
  color: var(--text);
  cursor: pointer;
}

.oob-slot-remove:disabled {
  opacity: 0.4;
  cursor: default;
}

/* The TL ladder: locked -> unlocked -> assigned, one row per unlock. */
.oob-tl-ladder {
  display: grid;
  gap: 0.4rem;
  margin-top: 0.75rem;
}

.oob-tl-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.5rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  border-left-width: 3px;
  padding: 0.4rem 0.5rem;
  background: rgba(0, 0, 0, 0.18);
  position: relative;
  overflow: hidden;
}

.oob-tl-info-btn {
  background: transparent;
  border: 1px solid var(--outline-soft);
  color: var(--stencil-dim);
  width: 1.8rem;
  height: 1.8rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 2px;
  font-size: 0.84rem;
  padding: 0;
  flex: 0 0 auto;
  font-family: inherit;
  margin-left: 0.25rem;
  transition: all 0.15s ease-in-out;
}

.oob-tl-info-btn:hover {
  border-color: var(--phos-green);
  color: var(--phos-green);
  box-shadow: 0 0 4px rgba(158, 240, 180, 0.3);
}

.oob-tl-description-plate {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  background: var(--surface-low);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.5rem;
  box-sizing: border-box;
  transform: translateX(100%);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 10;
}

.oob-tl-row.show-desc .oob-tl-description-plate {
  transform: translateX(0);
}

.oob-tl-description-text {
  font-size: 0.68rem;
  line-height: 1.25;
  color: var(--stencil);
  overflow-y: auto;
  max-height: 100%;
  padding-right: 0.25rem;
  font-family: var(--mono);
}

.oob-tl-info-close-btn {
  background: transparent;
  border: 1px solid var(--outline-soft);
  color: var(--stencil-dim);
  width: 1.8rem;
  height: 1.8rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 2px;
  font-size: 1.1rem;
  padding: 0;
  flex: 0 0 auto;
  font-family: inherit;
  transition: all 0.15s ease-in-out;
}

.oob-tl-info-close-btn:hover {
  border-color: var(--phos-green);
  color: var(--phos-green);
  box-shadow: 0 0 4px rgba(158, 240, 180, 0.3);
}

.oob-tl-row.locked {
  border-left-color: var(--outline-soft);
  opacity: 0.85;
}

.oob-tl-row.unlocked {
  border-left-color: var(--primary);
}

.oob-tl-row.assigned {
  border-left-color: var(--secondary-hot);
}

.oob-tl-meta {
  display: grid;
  gap: 0.1rem;
  min-width: 0;
}

.oob-tl-name {
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.74rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.oob-tl-tags {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
}

.oob-tl-control {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
}

/* Fixed-width key bay at the row's right edge: rendered on every row (empty on
   munition rows) so the fader position is identical whatever the row state. */
.oob-tl-bay {
  flex: 0 0 auto;
  width: 2.9rem;
  display: grid;
  place-items: center;
}

/* Backlit MFD key at small scale (rail-button recipe): stencil legend on a
   molded keycap — dim standby when assignable, lit green when seated. */
.oob-eqp-key {
  width: 2.9rem;
  min-height: 28px;
  padding: 0.25rem 0;
  display: grid;
  place-items: center;
  font-size: 0.6rem;
  color: var(--stencil-dim);
}

.oob-eqp-key[aria-pressed="true"] {
  background: linear-gradient(180deg, var(--keycap-600), var(--keycap-700));
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 0 12px rgba(70, 232, 140, 0.16),
    0 1px 2px rgba(0, 0, 0, 0.55);
}

/* Pooled but no free slot: amber caution legend behind the disabled dimming. */
.oob-eqp-key.blocked {
  color: var(--phos-amber);
}

/* Craft symbol plate: glass viewport recipe (mirrors .mission-craft-card).
   frame.*_symbol.svg art is transparent white line art (docs/spec/
   CRAFT_ART_STYLE_GUIDE.md); #0d1724 is the plate's own glass color. */
.oob-craft-plate {
  position: relative;
  height: 240px;
  margin: 0.5rem 0 0.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0d1724;
  border: 1px solid var(--gasket);
  border-radius: 2px;
  box-shadow: 0 1px 0 var(--bezel-hi);
  overflow: hidden;
}

/* Recess vignette overlays the artwork too, so the square asset edge stays
   invisible under the shadowed rim. */
.oob-craft-plate::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow:
    inset 0 6px 18px rgba(0, 0, 0, 0.7),
    inset 0 0 30px rgba(0, 0, 0, 0.45);
}

.oob-craft-symbol {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Unlock fader: a chassis control — recessed groove, ridged polymer cap,
   screen-printed ticks and LOCK/ARM stencils. State stays on the row border;
   the fader itself is unlit metal per the material rules. */
.oob-fader {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.oob-fader-label {
  font-family: var(--display);
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stencil-dim);
  user-select: none;
}

.oob-slide {
  appearance: none;
  -webkit-appearance: none;
  width: 6.5rem;
  height: 26px;
  margin: 0;
  cursor: ew-resize;
  /* Screen-printed tick marks above the groove. */
  background: repeating-linear-gradient(
      90deg,
      var(--stencil-dim) 0 1px,
      transparent 1px 20px
    )
    top center / calc(100% - 14px) 4px no-repeat;
}

.oob-slide::-webkit-slider-runnable-track {
  height: 8px;
  border-radius: 2px;
  background: linear-gradient(180deg, #030404 0 45%, var(--gasket) 45% 55%, #0d100e 55% 100%);
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.9),
    inset 0 -1px 0 rgba(0, 0, 0, 0.8),
    0 1px 0 var(--bezel-hi);
}

.oob-slide::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 15px;
  height: 22px;
  margin-top: -7px;
  border: 1px solid var(--gasket);
  border-radius: 2px;
  /* Center index line over vertical grip ridges over the polymer cap. */
  background:
    linear-gradient(90deg, transparent 44%, var(--stencil) 44% 56%, transparent 56%),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px 3px),
    linear-gradient(180deg, var(--keycap-500), var(--keycap-800));
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    0 2px 3px rgba(0, 0, 0, 0.65);
}

.oob-slide::-moz-range-track {
  height: 8px;
  border-radius: 2px;
  background: linear-gradient(180deg, #030404 0 45%, var(--gasket) 45% 55%, #0d100e 55% 100%);
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.9),
    inset 0 -1px 0 rgba(0, 0, 0, 0.8),
    0 1px 0 var(--bezel-hi);
}

.oob-slide::-moz-range-thumb {
  width: 15px;
  height: 22px;
  border: 1px solid var(--gasket);
  border-radius: 2px;
  background:
    linear-gradient(90deg, transparent 44%, var(--stencil) 44% 56%, transparent 56%),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px 3px),
    linear-gradient(180deg, var(--keycap-500), var(--keycap-800));
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    0 2px 3px rgba(0, 0, 0, 0.65);
}

.oob-slide:focus-visible {
  outline: 1px solid var(--phos-green-dim);
  outline-offset: 2px;
}

.oob-slide:disabled {
  opacity: 0.4;
  cursor: default;
}

.oob-tl-instore,
.oob-tl-prereq,
.oob-tl-foreign {
  font-family: var(--mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  white-space: nowrap;
}

.oob-tl-instore {
  color: var(--primary);
}

.oob-tl-prereq {
  color: var(--muted);
}

.oob-tl-foreign {
  color: var(--secondary-hot);
}

.carrier-view,
.carrier-grid,
.carrier-logistics-grid {
  display: grid;
  gap: 0.75rem;
}

.production-authoring {
  border: 1px solid var(--border);
  background: rgba(14, 20, 15, 0.55);
  padding: 0.6rem 0.75rem;
  margin-bottom: 0.75rem;
}

.production-authoring-header {
  margin-bottom: 0.4rem;
}

.production-capacity {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.2rem;
}

.production-scope-picker {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.production-authoring-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 0.75rem;
  align-items: start;
}

.production-sources {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.production-list h4,
.production-queue h4 {
  margin: 0 0 0.3rem;
}

.production-kind-icon {
  display: inline-block;
  width: 1.1em;
  color: var(--primary);
}

.production-cut-line td {
  text-align: center;
  color: var(--secondary-hot);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  border-top: 1px dashed var(--secondary-hot);
  border-bottom: 1px dashed var(--secondary-hot);
}

.production-row-carry {
  opacity: 0.62;
}

.production-queue .badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.02rem 0.32rem;
  font-size: 0.7rem;
  border: 1px solid var(--outline-soft);
  border-radius: 2px;
  color: var(--muted);
}

.production-queue .badge.bad {
  border-color: var(--red);
  color: var(--red);
}

@media (max-width: 900px) {
  .production-authoring-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.red-defense-view {
  gap: 0.75rem;
}

.red-defense-summary-row {
  display: grid;
  grid-template-columns: minmax(260px, 420px);
  gap: 0.75rem;
}

.carrier-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.carrier-card {
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  padding: 0.8rem;
}

.carrier-wide {
  grid-column: 1 / -1;
}

.carrier-card h3,
.carrier-card h4 {
  margin: 0;
  color: var(--primary);
  font-family: var(--display);
}

.carrier-card h4 {
  margin-bottom: 0.45rem;
  color: var(--secondary-hot);
  font-size: 0.82rem;
  text-transform: uppercase;
}

.carrier-form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
  margin-top: 0.75rem;
}

.carrier-form-grid label {
  display: grid;
  gap: 0.3rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
}

.carrier-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.75rem;
}

.carrier-logistics-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

.carrier-summary-footer {
  margin-top: 0.75rem;
  margin-bottom: 0;
}

.red-oob-shell,
.red-oob-panel {
  min-width: 0;
}

.red-oob-toolbar {
  align-items: center;
}

.red-oob-budget {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin-right: auto;
}

.data-readout.bad {
  border-color: rgba(255, 82, 82, 0.65);
  color: var(--red);
}

.red-oob-layout {
  display: grid;
  grid-template-columns: minmax(560px, 1fr) minmax(320px, 440px);
  gap: 0.75rem;
  align-items: start;
}

.red-oob-map-column,
.red-oob-side,
.red-oob-palette,
.red-oob-hierarchy,
.red-oob-inventory,
.red-oob-inspector {
  display: grid;
  gap: 0.75rem;
  min-width: 0;
}

.red-oob-map-frame {
  min-height: 520px;
}

.red-oob-map {
  cursor: crosshair;
}

.red-oob-hex-cell {
  cursor: pointer;
}

.red-oob-hex-cell:hover {
  fill: rgba(255, 82, 82, 0.12);
  stroke: rgba(255, 82, 82, 0.78);
}

.red-oob-hex-cell.selected {
  fill: rgba(255, 82, 82, 0.28);
  stroke: var(--red);
  stroke-width: 2;
}

.red-oob-complex-marker {
  cursor: pointer;
}

.red-oob-complex-marker circle {
  fill: rgba(255, 82, 82, 0.72);
  stroke: rgba(255, 255, 255, 0.82);
  stroke-width: 1.4;
}

.red-oob-complex-marker.selected circle {
  fill: var(--secondary-hot);
  stroke: var(--primary);
  stroke-width: 2.2;
}

.red-oob-complex-marker.invalid circle {
  stroke: var(--red);
  stroke-width: 3;
}

.red-oob-marker-label {
  fill: var(--red);
  paint-order: stroke;
  stroke: rgba(8, 11, 9, 0.92);
  stroke-width: 3;
}

/* --- Ingress phase (side selection + carrier spawn placement) --- */
.ingress-layout {
  display: grid;
  grid-template-columns: minmax(560px, 1fr) minmax(280px, 360px);
  gap: 0.75rem;
  align-items: start;
}

.ingress-controls {
  display: grid;
  gap: 0.6rem;
  margin-bottom: 0.75rem;
}

.ingress-side-grid,
.ingress-carrier-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.ingress-side-btn.selected,
.ingress-carrier-btn.selected {
  border-color: var(--primary);
  background: rgba(70, 232, 140, 0.18);
  color: var(--primary);
}

.ingress-primary {
  justify-self: start;
}

.ingress-edge-hex {
  cursor: pointer;
  fill: rgba(0, 218, 243, 0.1);
  stroke: rgba(0, 218, 243, 0.55);
  stroke-width: 1.2;
}

.ingress-edge-hex:hover {
  fill: rgba(0, 218, 243, 0.24);
}

.ingress-edge-hex.selected {
  fill: rgba(0, 218, 243, 0.42);
  stroke: var(--primary);
  stroke-width: 2;
}

.ingress-spawn-hex {
  cursor: pointer;
  fill: rgba(0, 218, 243, 0.12);
  stroke: rgba(0, 218, 243, 0.6);
  stroke-width: 1.2;
}

.ingress-spawn-hex:hover {
  fill: rgba(0, 218, 243, 0.28);
}

.ingress-spawn-hex.selected {
  fill: rgba(0, 218, 243, 0.45);
  stroke: var(--primary);
  stroke-width: 2;
}

.ingress-spawn-hex.occupied {
  cursor: not-allowed;
  fill: rgba(255, 82, 82, 0.3);
  stroke: rgba(255, 82, 82, 0.78);
}

.ingress-spawn-hex.mine {
  fill: rgba(120, 255, 160, 0.32);
  stroke: rgba(120, 255, 160, 0.85);
}

.ingress-carrier-marker circle {
  fill: rgba(var(--owner-rgb), 0.82);
  stroke: rgba(255, 255, 255, 0.85);
  stroke-width: 1.4;
}

.ingress-marker-label {
  fill: var(--primary);
  paint-order: stroke;
  stroke: rgba(8, 11, 9, 0.92);
  stroke-width: 3;
}

.ingress-roster {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
}

.ingress-roster li {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
}

.ingress-roster li.placed {
  border-color: rgba(120, 255, 160, 0.55);
}

.ingress-roster li.mine {
  border-left: 3px solid var(--primary);
}

.red-oob-palette,
.red-oob-hierarchy,
.red-oob-inventory,
.red-oob-inspector,
.red-defense-complex-list {
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  padding: 0.75rem;
}

.red-oob-palette-tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.red-oob-palette-tabs button.active {
  border-color: rgba(255, 82, 82, 0.78);
  color: var(--red);
  background: rgba(255, 82, 82, 0.12);
}

.red-oob-palette-list,
.red-oob-squadron-tree,
.red-oob-tree-components {
  display: grid;
  gap: 0.45rem;
}

.red-oob-palette-item {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 0.55rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  background: rgba(10, 15, 11, 0.72);
  padding: 0.55rem;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.74rem;
  text-align: left;
}

.red-oob-tree-row {
  width: 100%;
  display: grid;
  grid-template-columns: 1.9rem minmax(0, 1fr) auto auto;
  gap: 0.45rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  background: rgba(10, 15, 11, 0.72);
  padding: 0.35rem;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.74rem;
  text-align: left;
}

.red-oob-palette-item.readonly {
  grid-template-columns: minmax(0, 1fr) auto;
}

.red-oob-palette-item strong,
.red-oob-tree-row strong,
.red-oob-palette-item span,
.red-oob-tree-row span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.red-oob-palette-item strong,
.red-oob-tree-row strong {
  color: var(--primary);
}

.red-oob-palette-item span,
.red-oob-tree-row span,
.red-oob-palette-item em {
  color: var(--muted);
  font-style: normal;
}

.red-oob-palette-item .red-oob-statblock {
  display: block;
  margin-top: 0.2rem;
  color: var(--text);
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  opacity: 0.85;
}

.red-oob-tree-complex,
.red-oob-tree-site {
  display: grid;
  gap: 0.4rem;
}

.red-oob-tree-row {
  clip-path: none;
  min-height: 0;
  text-transform: none;
  letter-spacing: 0;
}

.red-oob-tree-row.selected {
  border-color: var(--secondary-hot);
  background: rgba(254, 179, 0, 0.12);
}

.red-oob-tree-site {
  margin-left: 0.6rem;
}

.red-oob-tree-row.component {
  grid-template-columns: minmax(0, 1fr) auto;
  margin-left: 1.2rem;
  color: var(--muted);
}

.red-oob-component-state {
  justify-self: end;
  border: 1px solid var(--outline-soft);
  padding: 0.12rem 0.35rem;
  color: var(--muted);
  font-size: 0.66rem;
  white-space: nowrap;
}

.red-oob-component-state.intact {
  border-color: rgba(122, 214, 156, 0.38);
  color: var(--primary);
}

.red-oob-component-state.destroyed {
  border-color: rgba(255, 82, 82, 0.5);
  color: var(--red);
}

.red-oob-tree-row.squadron {
  grid-template-columns: minmax(0, 1fr) auto auto;
}

.red-oob-caret,
.red-oob-tree-main {
  clip-path: none;
  min-height: 0;
  text-transform: none;
  letter-spacing: 0;
}

.red-oob-caret {
  width: 1.55rem;
  height: 1.55rem;
  padding: 0;
  display: inline-grid;
  place-items: center;
}

.red-oob-tree-main {
  width: 100%;
  display: grid;
  gap: 0.18rem;
  border: 0;
  background: transparent;
  padding: 0;
  color: inherit;
  font: inherit;
  text-align: left;
}

.red-oob-tree-main:hover,
.red-oob-tree-main:focus-visible {
  border: 0;
  color: var(--secondary-hot);
  box-shadow: none;
}

.red-oob-row-remove {
  clip-path: none;
  min-height: 0;
  width: 1.45rem;
  height: 1.45rem;
  padding: 0;
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--outline-soft);
  background: transparent;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.9rem;
  line-height: 1;
  text-transform: none;
  letter-spacing: 0;
  cursor: pointer;
}

.red-oob-row-remove:hover:not(:disabled),
.red-oob-row-remove:focus-visible:not(:disabled) {
  border-color: var(--danger, #ff5a5a);
  color: var(--danger, #ff5a5a);
}

.red-oob-row-remove:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.red-oob-subhead {
  margin-top: 0.75rem;
}

.red-oob-inspector label {
  margin-bottom: 0.65rem;
}

.red-oob-loadout-table input {
  min-width: 76px;
}

.muted-row {
  opacity: 0.55;
}

.red-oob-issues tr[data-red-oob-issue-path] {
  cursor: pointer;
}

.red-oob-issues tr[data-red-oob-issue-path]:hover {
  background: rgba(255, 82, 82, 0.08);
}

.system-generator-card {
  display: grid;
  gap: 0.6rem;
}

.system-seed-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.45rem;
}

.system-candidates {
  display: grid;
  gap: 0.45rem;
}

.system-candidate {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.5rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  background: rgba(0, 0, 0, 0.18);
  padding: 0.5rem;
}

.system-candidate.selected {
  border-color: var(--primary);
  background: rgba(79, 209, 197, 0.12);
}

.system-candidate strong,
.system-candidate span {
  display: block;
}

.system-candidate span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.oob-munitions input {
  min-width: 72px;
}

/* M6A S1: the purchaser is a purchase-card grid. Its header stays pinned so funds and
   carrier MUN stay in view while scrolling the cards. */
.oob-munitions > .panel-heading {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 0.3rem 0;
  background: rgba(21, 27, 22, 0.96);
}

.oob-munitions .munition-card__count {
  min-width: 0;
}

.oob-munitions__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin: 0.5rem 0;
}

.oob-munitions__filters .chip-toggle {
  min-height: 0;
  padding: 0.25rem 0.55rem;
  font-size: 0.66rem;
}

.oob-munitions__carriable {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.68rem;
}

.oob-munitions__group {
  margin-top: 0.6rem;
}

.oob-munitions__group > .eyebrow {
  display: block;
  margin: 0 0 0.35rem;
}

.raw-layout {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.squadron-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0.75rem;
}

.red-sqn-shell {
  display: grid;
  gap: 0.75rem;
}

.draft-force-list {
  display: grid;
  gap: 0.75rem;
}

.draft-force-slot {
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  border-radius: 3px;
  padding: 0.8rem;
}

.draft-force-slot.self {
  border-color: rgba(0, 230, 118, 0.35);
}

.draft-force-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.draft-force-head h3 {
  margin: 0;
  color: var(--primary);
  font-family: var(--display);
  overflow-wrap: anywhere;
}

.draft-sqn-rows {
  list-style: none;
  margin: 0.55rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.45rem;
}

.draft-sqn-row {
  display: grid;
  grid-template-columns: minmax(160px, 0.8fr) minmax(0, 1.2fr);
  gap: 0.45rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  background: rgba(10, 15, 11, 0.72);
  padding: 0.5rem;
}

.draft-sqn-row .chip-row {
  margin: 0;
}

.draft-sqn-id {
  display: grid;
  gap: 0.15rem;
  min-width: 0;
}

.draft-sqn-id strong {
  overflow-wrap: anywhere;
}

.draft-sqn-id span {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.chip.draft-eqp {
  border-style: dashed;
  color: var(--primary);
}

.red-sqn-command {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 0.75rem;
  border: 1px solid var(--outline-soft);
  background: rgba(10, 15, 11, 0.72);
  padding: 0.75rem;
}

.red-sqn-command label {
  min-width: min(100%, 360px);
}

.red-sqn-layout {
  display: grid;
  grid-template-columns: minmax(360px, 1.1fr) minmax(300px, 0.9fr);
  gap: 0.75rem;
  align-items: start;
}

.red-sqn-roster,
.red-sqn-detail {
  display: grid;
  gap: 0.5rem;
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  padding: 0.75rem;
}

.red-sqn-row {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(120px, 1.25fr) minmax(100px, 1fr) minmax(70px, 0.55fr) minmax(130px, 1.15fr) minmax(80px, 0.7fr) auto;
  gap: 0.45rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  background: rgba(10, 15, 11, 0.72);
  padding: 0.5rem;
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.72rem;
  text-align: left;
  clip-path: none;
  text-transform: none;
  letter-spacing: 0;
}

.red-sqn-row.selected {
  border-color: var(--secondary-hot);
  background: rgba(254, 179, 0, 0.12);
}

.red-sqn-row strong,
.red-sqn-row span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.red-sqn-head {
  color: var(--muted);
  text-transform: uppercase;
}

.flight-card {
  border: 1px solid var(--border);
  background: rgba(21, 27, 22, 0.72);
  border-radius: 3px;
  padding: 0.8rem;
}

.flight-card h3 {
  margin: 0 0 0.45rem;
  color: var(--primary);
  font-family: var(--display);
  overflow-wrap: anywhere;
}

.data-table,
.issues {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 0.75rem;
}

.data-table th,
.data-table td,
.issues th,
.issues td {
  border: 1px solid var(--border);
  padding: 0.42rem 0.5rem;
  text-align: left;
  vertical-align: top;
}

.data-table th,
.issues th {
  color: var(--muted);
  font-weight: 400;
  text-transform: uppercase;
}

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.55rem 0;
}

.chip {
  border: 1px solid var(--outline-soft);
  color: var(--muted);
  padding: 0.24rem 0.42rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
}

.chip.good {
  border-color: rgba(0, 230, 118, 0.55);
  color: var(--green);
}

.chip.warn {
  border-color: rgba(254, 179, 0, 0.55);
  color: var(--secondary-hot);
}

.chip.bad {
  border-color: rgba(255, 82, 82, 0.55);
  color: var(--red);
}

.json {
  margin: 0;
  white-space: pre-wrap;
  border: 1px solid var(--border);
  padding: 0.65rem;
  background: rgba(0, 0, 0, 0.26);
  max-height: 520px;
  overflow: auto;
  font-family: var(--mono);
  font-size: 0.76rem;
}

.json.small {
  max-height: 320px;
}

@media (max-width: 1260px) {
  .combat-window-root,
  .combat-window-root::before {
    left: 64px;
  }

  .combat-window-grid {
    grid-template-columns: 1fr;
  }

  .combat-slot-rail {
    grid-template-columns: repeat(4, minmax(180px, 1fr));
    grid-template-rows: minmax(140px, auto);
    overflow-x: auto;
  }

  .combat-vs {
    grid-column: 1;
    grid-template-columns: 1fr auto 1fr;
    grid-template-rows: auto;
    min-height: 26px;
  }

  .combat-vs span {
    width: 100%;
    height: 1px;
  }

  .system-preview-layout,
  .playback-layout,
  .raw-layout,
  .oob-layout,
  .red-oob-layout,
  .red-sqn-layout,
  .oob-grid,
  .carrier-grid,
  .carrier-form-grid,
  .carrier-logistics-grid,
  .player-grid,
  .login-grid {
    grid-template-columns: 1fr;
  }

  .system-preview-layout {
    height: auto;
  }

  .detail-panel {
    max-height: none;
  }

  .phase-status-banner {
    grid-template-columns: 1fr;
  }

  .lobby-panel {
    min-height: auto;
  }
}

@media (max-width: 980px) {
  #tab-operations.active {
    height: auto;
    overflow: visible;
  }

  .ops-layout {
    grid-template-columns: 1fr;
  }

  .gantt-grid {
    --gantt-mission-col: 160px;
  }
}

@media (max-width: 760px) {
  .combat-window-root {
    inset: 0;
    padding: 0.5rem;
  }

  .combat-window-root::before {
    inset: 0;
  }

  .combat-window-shell {
    min-height: calc(100vh - 12px);
  }

  .combat-window-header {
    align-items: stretch;
    flex-direction: column;
  }

  .combat-header-controls {
    justify-content: flex-start;
  }

  .combat-encounter-select {
    width: 100%;
    align-items: stretch;
    flex-direction: column;
  }

  .combat-encounter-select select {
    min-width: 0;
  }

  .combat-raw {
    grid-column: 1;
  }

  .combat-command {
    grid-template-rows: auto minmax(124px, auto) minmax(120px, auto) auto;
  }

  .combat-slot-rail {
    grid-template-columns: repeat(4, minmax(160px, 1fr));
  }

  .workstation {
    height: auto;
    grid-template-columns: 1fr;
  }

  .side-rail {
    position: sticky;
    top: 0;
    z-index: 9;
    height: auto;
    flex-direction: row;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }

  .rail-brand {
    margin: 0;
    width: auto;
    padding: 0 0.6rem 0 0;
    border-bottom: 0;
    border-right: 1px solid var(--gasket);
  }

  .rail-tabs,
  .rail-actions {
    display: flex;
    flex-direction: row;
    gap: 0.5rem;
  }

  .phase-status-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .rail-actions {
    margin-top: 0;
    margin-left: auto;
  }

  .red-ai-panel {
    left: 0.5rem;
    top: 4rem;
    bottom: auto;
    width: calc(100vw - 1rem);
  }

  .command-content {
    padding: 0.5rem;
  }

  .player-login {
    width: min(100vw - 1rem, 1520px);
    padding: 0.5rem 0 1rem;
  }

  .player-card {
    grid-template-columns: 42px minmax(0, 1fr) auto;
    gap: 0.55rem;
    min-height: 70px;
  }

  .player-card strong {
    font-size: 0.88rem;
  }

  .player-card em {
    font-size: 0.58rem;
  }

  .login-action-bar {
    position: static;
    grid-template-columns: 1fr;
  }

  .form-grid,
  .force-grid {
    grid-template-columns: 1fr;
  }

  .red-sqn-row,
  .draft-sqn-row {
    grid-template-columns: 1fr;
  }

  .map-toolbar,
  .panel-heading.split {
    grid-template-columns: 1fr;
    display: grid;
  }

  .map-frame,
  .hex-map {
    min-height: 360px;
  }

  .brand-lockup h1 {
    font-size: 1.05rem;
  }
}

/* Visual Mission Craft Card & HUD Styles (NATOware: card = T3 glass viewport,
   HUD chips are drawn on the phosphor, chrome around it stays chassis). */
.mission-visual-card-container {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.75rem;
}

/* Name/type row sits on the panel plate itself — no extra card box. */
.card-flight-select {
  width: 100%;
  font-size: 0.85rem;
}

/* Mission Details card (JUL12 pass): glass viewport split into three flow
   regions — stat rail (left), art (centre), action bar (bottom). Readouts are
   phosphor drawings on the glass; no more absolute-positioned HUD boxes. */
.mission-craft-card {
  position: relative;
  width: 100%;
  /* Grows past 270px when the CAPABILITIES row wraps, so the row never
     squeezes the stat rail or the art. */
  min-height: 270px;
  background: var(--glass-bg);
  border: 1px solid var(--gasket);
  border-radius: 2px;
  box-shadow:
    inset 0 6px 18px rgba(0, 0, 0, 0.7),
    inset 0 0 30px rgba(0, 0, 0, 0.45),
    0 1px 0 var(--bezel-hi);
  overflow: hidden;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(118px, auto) 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "name name"
    "rail art"
    "bar bar";
}

/* Top banner across the glass: Mission Name (editable, left) and the frame
   type/name readout (right). Mission Name moved here (JUL-sortie-dialogue
   pass) so the leg the player is editing reads as the header, not a box
   buried below the card; frame name shifted right to make room. */
.mdc-frame-name {
  grid-area: name;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.6rem 0.35rem;
  border-bottom: 1px solid rgba(122, 214, 156, 0.25);
  background: rgba(20, 20, 22, 0.55);
  min-width: 0;
}

.mdc-name-input {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.78rem;
}

/* Never shrunk by the flex layout — the frame name always renders in full
   up to max-width; Mission Name (flex-grow, min-width: 0) yields the space. */
.mdc-frame-name-text {
  flex: 0 0 auto;
  max-width: 45%;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: bold;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--phos-green);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
}

.mdc-stat-rail {
  grid-area: rail;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  gap: 0.3rem;
  padding: 0.45rem 0.5rem 0.45rem 0.6rem;
  min-width: 0;
  min-height: 0;
}

.mdc-rail-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

/* Rail glyphs stay dim phosphor even when a value goes amber — the warning
   colour is scoped to the value text (.text-warning), not the icon. */
.mdc-rail-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: inline-flex;
  color: rgba(158, 240, 180, 0.55);
}

.mdc-rail-icon svg {
  width: 100%;
  height: 100%;
}

.mdc-rail-readout {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

.mdc-sensor-slot .sensor-band-chips {
  flex-wrap: wrap;
}

.mdc-art {
  grid-area: art;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0.6rem 0.6rem 0.6rem 0;
  border: 1px solid rgba(122, 214, 156, 0.18);
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

/* Craft stencil art keeps faction blue — symbology channel, not chrome. */
.craft-card-image {
  max-width: 75%;
  max-height: 75%;
  object-fit: contain;
  opacity: 0.55;
  filter: drop-shadow(0 0 10px rgba(var(--side-blue-rgb), 0.3));
}

.mdc-action-bar {
  grid-area: bar;
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: 1px solid rgba(122, 214, 156, 0.25);
  background: rgba(20, 20, 22, 0.55);
}

.mdc-bar-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.45rem 0.5rem;
  min-width: 0;
  box-sizing: border-box;
}

.mdc-bar-cell + .mdc-bar-cell {
  border-left: 1px solid rgba(122, 214, 156, 0.18);
}

/* Interactive cells light their legend on hover (MFD convention) — never
   recolor or glow the box. */
.mdc-bar-btn {
  cursor: pointer;
  transition:
    background 0.15s ease-in-out,
    border-color 0.15s ease-in-out;
}

.mdc-bar-btn:hover {
  background: rgba(6, 26, 14, 0.92);
}

.mdc-bar-btn:hover .hud-value {
  color: var(--phos-green-hot);
  text-shadow: 0 0 7px rgba(70, 232, 140, 0.7);
}

.mdc-bar-btn:active .hud-value {
  transform: scale(0.96);
}

/* CAPABILITIES: a full-width row under CRAFT COUNT / MUN LOAD. Label and
   ADD/EDIT cue on one line, then the names across the whole card width; a
   name never splits, the row wraps between names. */
.mdc-cap-row {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  justify-items: start;
  gap: 0.3rem 0.6rem;
  border-top: 1px solid rgba(122, 214, 156, 0.18);
}

.mdc-bar-cell + .mdc-cap-row {
  border-left: 0;
}

.mdc-cap-row:not(.is-reachable) {
  cursor: default;
}

.mdc-cap-row:not(.is-reachable):hover {
  background: none;
}

.mdc-cap-row .hud-label {
  margin: 0;
}

.mdc-cap-row.is-reachable .hud-label {
  color: var(--phos-green);
}

.mdc-cap-row:focus-visible {
  outline: 1px solid var(--phos-green);
  outline-offset: -2px;
}

.mdc-cap-cue {
  font-family: var(--mono);
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  color: rgba(245, 184, 75, 0.9);
}

.mdc-cap-names {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.8rem;
  min-width: 0;
}

.mdc-cap-name {
  font-family: var(--mono);
  font-size: 0.65rem;
  white-space: nowrap;
  color: rgba(158, 240, 180, 0.4);
}

.mdc-cap-name.is-ordered {
  color: var(--phos-green-hot);
  font-weight: bold;
}

.mdc-cap-row.is-reachable:hover .mdc-cap-name.is-ordered {
  text-shadow: 0 0 7px rgba(70, 232, 140, 0.7);
}

.hud-label {
  font-size: 0.6rem;
  color: rgba(158, 240, 180, 0.6);
  font-family: var(--mono);
  letter-spacing: 0.08em;
  margin-bottom: 0.15rem;
  text-transform: uppercase;
}

.hud-value {
  font-size: 0.85rem;
  color: var(--phos-green);
  font-family: var(--mono);
  font-weight: bold;
}

.hud-reserve {
  color: rgba(245, 184, 75, 0.9);
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: bold;
  line-height: 1.2;
  margin-top: 0.15rem;
}

/* Compact momentary key — inherits the global keycap recipe, sizing only. */
.btn-cap {
  font-size: 0.68rem;
  padding: 0.3rem 0.55rem;
  min-height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

/* Mission ID: faint corner watermark on the art. */
.hud-id-watermark {
  position: absolute;
  right: 8px;
  bottom: 5px;
  z-index: 1;
  pointer-events: none;
}

.hud-id-text {
  font-size: 1rem;
  font-family: var(--display);
  font-weight: 900;
  color: rgba(158, 240, 180, 0.14);
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

/* Spinner widgets */
.craft-count-widget {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.1rem;
}

/* Spinner steppers are drawn on the glass too: flat phosphor squares. */
.hud-btn {
  width: 18px;
  height: 18px;
  min-height: 0;
  padding: 0;
  line-height: 16px;
  background: rgba(122, 214, 156, 0.12);
  border: 1px solid rgba(122, 214, 156, 0.45);
  color: var(--phos-green);
  border-radius: 0;
  box-shadow: none;
  cursor: pointer;
  font-family: var(--mono);
  font-weight: bold;
  font-size: 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease-in-out;
}

.hud-btn:hover:not(:disabled) {
  background: rgba(122, 214, 156, 0.25);
  border-color: var(--phos-green);
  color: var(--phos-green-hot);
  text-shadow: 0 0 6px rgba(70, 232, 140, 0.6);
}

.hud-btn:active:not(:disabled) {
  background: rgba(122, 214, 156, 0.12);
  box-shadow: none;
  transform: none;
}

.hud-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
  border-color: rgba(122, 214, 156, 0.2);
  background: transparent;
}

/* Feasibility cautions are amber phosphor, not hostile red. */
.text-warning {
  color: var(--phos-amber-hot) !important;
  text-shadow: 0 0 6px rgba(254, 179, 0, 0.35);
}

/* A value awaiting server confirmation after a local edit (JUL15 §2.5) —
   distinct from .text-warning, which flags an actual feasibility problem. */
.text-pending {
  color: var(--muted) !important;
  font-style: italic;
}

.mission-selector-row {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.mission-select-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.mission-selector-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--stencil-dim);
  text-transform: uppercase;
}

.itinerary-footer-actions button {
  min-height: 34px;
  height: 34px;
  padding: 0.4rem 0.65rem;
  font-size: 0.72rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.itinerary-footer-actions button[hidden] {
  display: none;
}

/* Clone Sortie bottom-left and Delete Sortie bottom-right of the itinerary
   card, below the leg list — outside .itinerary-scroll, so they never scroll
   away with a long itinerary. */
.itinerary-footer-actions {
  display: flex;
  flex-shrink: 0;
  gap: 0.4rem;
  margin-top: 0.4rem;
}

.itinerary-footer-actions #deleteSortieBtn {
  margin-left: auto;
}

/* New Sortie: a full-width bar at the foot of the Sortie Details panel,
   divided from the itinerary so it never reads as a leg action. */
.new-sortie-bar {
  flex-shrink: 0;
  margin-top: auto;
  padding-top: 0.6rem;
}

.new-sortie-bar button {
  width: 100%;
  min-height: 34px;
  font-size: 0.72rem;
}

/* Itinerary list: the Sortie's ordered legs (JUL15 §2.2). Sized to its legs
   and shrinks into whatever height #missionDetailsPane leaves above the New
   Sortie bar; only .itinerary-scroll inside it actually scrolls. */
.itinerary-section {
  margin: 0.4rem 0;
  flex: 0 1 auto;
  display: flex;
  flex-direction: column;
}

.itinerary-head {
  display: flex;
  flex-shrink: 0;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

/* A guaranteed minimum (~2 rows) so a very short viewport never collapses
   this to nothing and lets the footer bar visually overlap it — it just
   scrolls sooner instead. */
.itinerary-scroll {
  flex: 1;
  min-height: 64px;
  overflow-y: auto;
}

.itinerary-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

/* Trailing row-shaped add control (below the last leg): a type picker paired
   with a "+" that submits it, sized/shaped like the rows above it rather than
   living in the header. */
.itinerary-row.itinerary-row-add {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: default;
}

.itin-add-type {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 9rem;
  font-family: var(--mono);
  font-size: 0.72rem;
}


.itin-add-btn {
  flex-shrink: 0;
  margin-left: auto;
  min-width: 1.8rem;
  height: 1.7rem;
  padding: 0;
  font-size: 1rem;
  font-weight: bold;
  line-height: 1;
  color: var(--phos-green);
  border: 1px solid rgba(122, 214, 156, 0.4);
  background: var(--surface-low);
}

.itin-add-btn:hover {
  background: var(--surface-mid);
}

.itinerary-row {
  display: grid;
  grid-template-columns: 1.4rem 1fr auto auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.55rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--stencil);
  border: 1px solid var(--border);
  border-left: 2px solid transparent;
  background: var(--surface-low);
  cursor: pointer;
}

.itinerary-row:hover {
  background: var(--surface-mid);
}

.itinerary-row.itinerary-row-implicit {
  color: var(--warning, #f5b84b);
  border-color: rgba(245, 184, 75, 0.55);
  border-left-color: var(--warning, #f5b84b);
  background: rgba(245, 184, 75, 0.08);
  cursor: default;
}

.itinerary-row.itinerary-row-implicit .itin-index,
.itinerary-row.itinerary-row-implicit .itin-hours {
  color: var(--warning, #f5b84b);
}

.itinerary-row.itinerary-row-implicit .itin-actions button {
  width: auto;
  color: var(--warning, #f5b84b);
  border-color: rgba(245, 184, 75, 0.65);
}

/* Resolved/locked leg (§2.4/§2.8): the same "already flown — view, not edit"
   treatment the Gantt gives its immutable prefix, so the itinerary list carries
   the lock state too rather than leaving the Gantt as the only signal. */
/* Pending because the server *rejected* the itinerary, not because a round trip
   is in flight (§2.5/§6): same hatching, warning-toned, so a stall reads as an
   invalid edit rather than a slow one. */
.itinerary-row .itin-hours.is-uncompiled {
  color: var(--warning, #f5b84b);
}

.itinerary-row.is-immutable {
  opacity: 0.55;
  filter: saturate(0.5);
  border-left-style: dashed;
}

.itinerary-row.is-immutable .itin-actions {
  visibility: hidden;
}

.itinerary-row.selected {
  border-left-color: var(--primary-hot);
  background: var(--surface-mid);
  box-shadow: inset 0 0 0 1px rgba(70, 232, 140, 0.18);
}

.itinerary-row .itin-index {
  color: var(--stencil-dim);
  text-align: right;
}

.itinerary-row .itin-kind {
  text-transform: uppercase;
}

/* A Transit bar whose particle penalty a package beacon waived (M3B). */
.sortie-row .gantt-phase.has-beacon {
  border-top-style: dashed;
}

/* Navigation Beacon waivers on a Transit leg (M3B). The hint form is unconfirmed. */
.itinerary-row .itin-beacon {
  margin-left: 0.35rem;
  color: var(--stencil-dim);
  font-size: 0.65rem;
  letter-spacing: 0.04em;
}

.itinerary-row .itin-beacon.is-hint {
  color: var(--muted);
  font-style: italic;
}

.itinerary-row .itin-hours {
  color: var(--stencil-dim);
  font-size: 0.7rem;
}

/* Hours not yet confirmed by the server after a local edit (§2.5) — pairs with
   .sortie-row .gantt-phase.is-pending. */
.itinerary-row .itin-hours.is-pending {
  color: var(--muted);
  font-style: italic;
}

.itinerary-row .itin-actions {
  display: flex;
  gap: 0.15rem;
}

.itinerary-row .itin-actions button {
  min-width: 1.4rem;
  padding: 0.1rem 0.25rem;
  border: 1px solid var(--border);
  color: var(--stencil-dim);
  background: var(--surface-low);
}

.itinerary-empty {
  list-style: none;
  padding: 0.4rem 0.55rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--stencil-dim);
}

/* Swappable entry-detail region below the persistent Sortie header. */
.entry-detail-region {
  margin-top: 0.4rem;
}

.stat-top-center {
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  min-width: 140px;
  background: rgba(20, 20, 22, 0.92);
  border: 1px solid rgba(122, 214, 156, 0.4);
}

.hud-select-value {
  min-height: 0;
  background: transparent;
  border: none;
  box-shadow: none;
  color: var(--phos-green);
  font-family: var(--mono);
  font-size: 0.85rem;
  font-weight: bold;
  text-transform: uppercase;
  text-align: center;
  text-align-last: center;
  cursor: pointer;
  outline: none;
  padding: 0;
  margin: 0;
  width: 100%;
}

.hud-select-value option {
  background: var(--glass-bg);
  color: var(--phos-green);
}

/* Caution stack floats over the art box: amber phosphor, hard corners.
   Scrolls rather than blowing out the box when warnings stack up. */
.hud-warnings-overlay {
  position: absolute;
  right: 8px;
  top: 8px;
  max-width: 65%;
  max-height: calc(100% - 16px);
  overflow-y: auto;
  background: rgba(20, 13, 3, 0.92);
  border: 1px solid rgba(254, 179, 0, 0.5);
  border-radius: 0;
  padding: 0.4rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  z-index: 3;
  pointer-events: auto;
  box-sizing: border-box;
}

.hud-warning-item {
  color: var(--phos-amber-hot);
  font-family: var(--mono);
  font-size: 0.65rem;
  line-height: 1.25;
  text-transform: uppercase;
  display: flex;
  align-items: flex-start;
  gap: 0.25rem;
  text-shadow: 0 0 4px rgba(254, 179, 0, 0.35);
}

.hud-warning-item::before {
  content: "⚠";
  color: var(--phos-amber-hot);
  flex-shrink: 0;
}

/* --- Munition cards (M6A card v2 on the JUL03 painted-block chassis) ------- */
/* One card component with four variants (compact, purchase, inventory, chip),
   all fed by the server's munitionView. Card bodies are CHASSIS blocks painted
   flat matte ordnance paint by purpose (--paint-*); dual-role is anti-craft paint
   with a strike-olive band at the foot. Layout is an 88×40 art slot, the face
   (name + purpose, one stat line, badges) and the control station on the right.
   Warnings are an amber lamp in the station, never an extra row. */

.munition-card-stack {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  max-height: 60vh;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0.2rem 0.1rem;
}

.munition-card-stack--strike {
  max-height: none;
}

/* Purchase and inventory cards tile; compact cards stack. */
.munition-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17.5rem, 1fr));
  gap: 0.45rem;
}

.munition-card {
  position: relative;
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0.55rem;
  border: 1px solid var(--gasket);
  border-radius: 4px;
  background: var(--chassis-700);
  padding: 0.35rem 0.5rem 0.35rem 0.4rem;
  box-shadow:
    inset 1px 1px 0 var(--bezel-hi),
    inset -1px -1px 0 var(--bezel-lo),
    0 2px 5px rgba(0, 0, 0, 0.45);
  transition:
    box-shadow 0.12s ease,
    filter 0.12s ease,
    transform 0.12s ease;
}

.munition-card--anti_craft,
.munition-card--dual_role {
  background: var(--paint-anti-craft);
}

/* Dual-role: anti-craft paint body with a strike-olive code band at the foot. */
.munition-card--dual_role::after {
  content: "";
  position: absolute;
  left: 1px;
  right: 1px;
  bottom: 1px;
  height: 5px;
  border-radius: 0 0 3px 3px;
  background: var(--paint-strike);
  box-shadow: inset 0 1px 0 var(--bezel-lo);
  pointer-events: none;
}

.munition-card--strike {
  background: var(--paint-strike);
}

.munition-card--defense {
  background: var(--paint-defense);
}

.munition-card--deployable {
  background: var(--paint-deployable);
}

.munition-card--support {
  background: var(--paint-support);
}

.munition-card--strike-mode {
  cursor: pointer;
}

.munition-card--strike-mode:hover:not(.is-armed) {
  filter: brightness(1.08);
}

/* Armed = latched key: inverted bevel, pressed in, darkened. The glow lives in
   the amber ARM lamp, never on the card body (no colored shadows on chassis). */
.munition-card.is-armed {
  box-shadow:
    inset 1px 1px 0 var(--bezel-lo),
    inset -1px -1px 0 var(--bezel-hi),
    inset 0 3px 8px rgba(0, 0, 0, 0.5);
  filter: brightness(0.88);
  transform: translateY(1px);
}

/* A purchase card the squadron filter cannot load. */
.munition-card.is-dimmed {
  filter: saturate(0.4) brightness(0.75);
}

/* The card's own keys opt out of the global keycap size (36px min-height). */
.munition-card__remove,
.munition-card__info,
.munition-card__step {
  min-height: 0;
  letter-spacing: 0;
  text-transform: none;
}

.munition-card__remove {
  position: absolute;
  top: 0.15rem;
  left: 0.15rem;
  width: 1.1rem;
  height: 1.1rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: none;
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  z-index: 1;
}

.munition-card__remove:hover {
  color: var(--red);
  background: rgba(255, 82, 82, 0.12);
}

/* The art column: symbol line art as stenciled ink, or the purpose glyph. The
   paint carries the purpose color; the art never does. */
.munition-card__art {
  width: 88px;
  height: 40px;
  display: grid;
  place-items: center;
  color: var(--stencil);
  pointer-events: none;
}

/* Munition art as stencil ink (M7 Q3): the white file masks the --stencil color. The
   slot is wide (M7 Q1), so the mask is sized to the slot's width and centered: the
   square canvas's empty top and bottom fall outside the slot (style guide §3b). */
.munition-ink {
  display: block;
  background-color: var(--stencil);
  -webkit-mask: var(--art) center / var(--ink-size, contain) no-repeat;
  mask: var(--art) center / var(--ink-size, contain) no-repeat;
}

.munition-card__ink {
  --ink-size: 88px 88px;
  width: 100%;
  height: 100%;
}

.munition-card__glyph {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  opacity: 0.85;
}

.munition-card__glyph svg {
  width: 38px;
  height: 38px;
}

/* Name row on top; the stat line and the badges share the wrapping row below, so
   a badge only adds a row when it does not fit. */
.munition-card__face {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 0.6rem;
}

.munition-card__face > .munition-card__head {
  flex-basis: 100%;
}

.munition-card__face--open {
  cursor: pointer;
}

.munition-card__head {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  min-width: 0;
}

/* The name keeps its room; the purpose label gives way first. */
.munition-card__name {
  flex: 0 1 auto;
  min-width: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.86rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--stencil);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.55);
}

.munition-card__purpose {
  flex: 0 1000 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--display);
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--stencil-dim);
}

/* The ⓘ key: opens the details panel under the card. */
.munition-card__info {
  margin-left: auto;
  flex-shrink: 0;
  align-self: center;
  width: 1.05rem;
  height: 1.05rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--stencil-dim);
  border-radius: 50%;
  background: transparent;
  color: var(--stencil);
  font-family: var(--display);
  font-size: 0.62rem;
  font-style: italic;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.munition-card__info:hover,
.munition-card__info:active,
.munition-card__info[aria-expanded="true"] {
  background: var(--stencil);
  color: var(--chassis-900);
}

.munition-card__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem 0.6rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  color: var(--stencil-dim);
}

.munition-card__stat {
  white-space: nowrap;
}

.munition-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

/* Printed markings, not lamps: flat ink, no glow. */
.munition-card__badge {
  padding: 0.02rem 0.3rem;
  border: 1px solid var(--stencil-dim);
  border-radius: 2px;
  font-family: var(--mono);
  font-size: 0.56rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--stencil);
}

.munition-card__badge.is-warn {
  border-color: var(--phos-amber);
  color: var(--phos-amber);
}

/* Control station mounted on the right end, split off by a grooved separator. */
.munition-card__station {
  position: relative;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.12rem;
  min-width: 3.2rem;
  padding-left: 0.5rem;
  border-left: 1px solid rgba(0, 0, 0, 0.55);
  box-shadow: inset 1px 0 0 var(--bezel-hi);
}

/* Warning lamp (Q1): the text lives in the tooltip and the details panel. */
.munition-card__lamp {
  position: absolute;
  top: 0;
  right: -0.15rem;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--lamp-amber);
  box-shadow: 0 0 6px 1px rgba(255, 179, 0, 0.7);
}

.munition-card__stepper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.12rem;
}

/* Miniature momentary keycaps (global key recipe, shrunk). */
.munition-card__step {
  width: 1.6rem;
  padding: 0.06rem 0;
  border: 1px solid var(--gasket);
  border-radius: 3px;
  background: linear-gradient(180deg, var(--keycap-500), var(--keycap-700));
  color: var(--stencil);
  font-size: 0.52rem;
  line-height: 1;
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    0 1px 2px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}

.munition-card__step:hover:not(:disabled) {
  filter: brightness(1.15);
}

.munition-card__step:active:not(:disabled) {
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.6);
  transform: translateY(1px);
}

.munition-card__step:disabled {
  color: var(--stencil-dim);
  opacity: 0.55;
  cursor: not-allowed;
  filter: none;
}

/* Recessed mechanical counter window (CSS-only; real drum counters are parked).
   The purchase count is the same window, typeable. */
.munition-card__percraft,
.munition-card__count {
  min-width: 1.9rem;
  padding: 0 0.2rem;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.2;
  color: #e9eeea;
  background: #0c0e0c;
  border: 1px solid var(--gasket);
  border-radius: 2px;
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.7),
    0 1px 0 var(--bezel-hi);
}

.munition-card__count {
  box-sizing: border-box;
  width: 2.8rem;
  height: 1.45rem;
  min-height: 0;
  padding: 0 0.2rem;
  appearance: textfield;
  -moz-appearance: textfield;
}

.munition-card__count::-webkit-inner-spin-button,
.munition-card__count::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.munition-card__total,
.munition-card__stock {
  font-family: var(--mono);
  font-size: 0.62rem;
  white-space: nowrap;
  color: var(--stencil-dim);
}

.munition-card__total--solo {
  font-size: 0.8rem;
  color: var(--stencil);
}

/* ARM lamp cluster (strike mode). The lamp is the only glow on the card. */
.munition-card__arm {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.18rem;
}

.munition-card__arm-lamp {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #3a2c10;
  border: 1px solid var(--gasket);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.6);
}

.munition-card.is-armed .munition-card__arm-lamp {
  background: var(--lamp-amber);
  box-shadow: 0 0 7px 1px rgba(255, 179, 0, 0.75);
}

.munition-card__arm-caption {
  font-family: var(--display);
  font-size: 0.5rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--stencil-dim);
}

/* Inventory: the compact face at about 56px, with smaller art. */
.munition-card--inventory {
  grid-template-columns: 40px minmax(0, 1fr) auto;
  padding: 0.2rem 0.45rem 0.2rem 0.3rem;
}

.munition-card--inventory .munition-card__art {
  width: 40px;
  height: 18px;
}

.munition-card--inventory .munition-card__ink {
  --ink-size: 40px 40px;
}

.munition-card--inventory .munition-card__glyph svg {
  width: 22px;
  height: 22px;
}

/* Details panel (Q14): inline under a card in a stack. */
.munition-card__details {
  margin-top: -0.3rem;
  padding: 0.55rem 0.7rem 0.6rem;
  border: 1px solid var(--gasket);
  border-top: none;
  border-radius: 0 0 4px 4px;
  background: var(--chassis-900);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.5);
}

.munition-details {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.76rem;
  color: var(--text);
}

.munition-details__head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.munition-details__art {
  --ink-size: 120px 120px;
  width: 120px;
  height: 54px;
  flex: none;
}

.munition-details__name {
  margin: 0;
  font-family: var(--display);
  font-size: 0.9rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.munition-details__kind,
.munition-details__targets,
.munition-details__loadable {
  margin: 0;
  color: var(--muted);
}

.munition-details__does,
.munition-details__notes {
  margin: 0;
  padding-left: 1.1rem;
}

.munition-details__notes {
  color: var(--phos-amber);
}

.munition-details__behavior,
.munition-details__rules p {
  margin: 0;
}

.munition-details__rules {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  color: var(--muted);
}

.munition-details__stats {
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 0.7rem;
}

.munition-details__stats th {
  padding: 0.05rem 0.8rem 0.05rem 0;
  font-weight: 400;
  text-align: left;
  color: var(--muted);
}

.munition-details__stats td {
  text-align: right;
  white-space: nowrap;
}

.munition-details__stats tr.is-default td {
  color: var(--muted);
}

/* Mark chip: the 16–24px mark and the name inline, with a purpose tick on the
   left edge instead of a painted body (it sits on glass). */
.munition-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0 0.3rem 0 0.25rem;
  border-left: 3px solid var(--paint-support);
  line-height: 1.3;
  white-space: nowrap;
}

.munition-chip--anti_craft,
.munition-chip--dual_role {
  border-left-color: var(--paint-anti-craft);
}

.munition-chip--strike {
  border-left-color: var(--paint-strike);
}

.munition-chip--defense {
  border-left-color: var(--paint-defense);
}

.munition-chip--deployable {
  border-left-color: var(--paint-deployable);
}

.munition-chip__mark {
  width: 30px;
  height: 14px;
  display: inline-grid;
  place-items: center;
  opacity: 0.85;
}

.munition-chip__mark svg {
  width: 16px;
  height: 16px;
}

/* The mark's band (y 9…23 of 32) fills the 30×14 slot. Chips sit on glass as well as
   chassis, so the mark takes the chip's text color, like the fallback glyph. */
.munition-chip__ink {
  --ink-size: 30px 30px;
  background-color: currentColor;
  width: 100%;
  height: 100%;
}

.munition-chip__count {
  font-family: var(--mono);
}

/* Empty rack socket: the add-munition slot is an unpainted recess. */
.munition-card--add {
  border: 1px dashed var(--outline-soft);
  border-radius: 4px;
  background: var(--chassis-900);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.5);
  display: grid;
  place-items: center;
  padding: 0.5rem;
}

.munition-card__add-select {
  width: 100%;
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  background: transparent;
  color: var(--muted);
  border: none;
  text-align: center;
  cursor: pointer;
}

/* Loadout pane (M6A Q7/Q16): a one-line header above the cards, and the ammunition
   forecast collapsed to one line at the foot of the pane. */
.loadout-pane-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem 0.7rem;
  margin: 0 0 0.5rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}

.loadout-pane-summary__mode {
  margin-left: auto;
  padding: 0.02rem 0.35rem;
  border: 1px solid var(--outline-soft);
  border-radius: 2px;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
}

.loadout-forecast:empty {
  display: none;
}

.loadout-forecast__details {
  margin-top: 0.9rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--outline-soft);
}

.loadout-forecast__details > summary {
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}

/* Production cards (M6A S6): the Queue key in the station, shrunk from the global
   keycap size. */
.munition-card__queue {
  min-height: 0;
  padding: 0.25rem 0.5rem;
  font-size: 0.64rem;
}

/* Magazine inventory (M6A Q15): one grid per complex above the bin meters. */
.logistics-inventory {
  margin-bottom: 0.75rem;
}

.logistics-stock-line {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.74rem;
}

/* The ADD socket is a key that opens the card picker (S11). */
.munition-picker__key {
  display: block;
  width: 100%;
  min-height: 0;
  text-align: center;
  padding: 0.45rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: var(--chassis-900);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.5);
}

.munition-picker__key:hover,
.munition-picker__key[aria-expanded="true"] {
  color: var(--stencil);
  background: var(--chassis-900);
  border-color: var(--stencil-dim);
}

/* The picker tray: pick cards grouped by purpose, filtered as you type. */
.munition-picker {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.45rem;
  border: 1px solid var(--gasket);
  border-radius: 4px;
  background: var(--chassis-900);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.5);
}

.munition-picker__filter {
  width: 100%;
  padding: 0.3rem 0.45rem;
  font-family: var(--mono);
  font-size: 0.74rem;
}

.munition-picker__group {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.munition-picker__heading {
  margin: 0.2rem 0 0;
  font-family: var(--display);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.munition-card--pick {
  cursor: pointer;
}

.munition-card--pick:hover,
.munition-card--pick:focus-visible {
  filter: brightness(1.12);
  outline: 1px solid var(--stencil-dim);
  outline-offset: 1px;
}

/* Details slide-over (S12): the grid placement of the details panel. Fixed above any
   tab; the OOB page has no right panel and the OPS right column belongs to M6B. */
.munition-details-panel {
  position: fixed;
  top: 4.5rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 40;
  width: min(24rem, calc(100vw - 2rem));
  overflow-y: auto;
  padding: 0.9rem 1rem 1rem;
  border: 1px solid var(--gasket);
  border-radius: 4px;
  background: var(--chassis-900);
  box-shadow:
    inset 1px 1px 0 var(--bezel-hi),
    0 8px 24px rgba(0, 0, 0, 0.6);
}

.munition-details-panel[hidden] {
  display: none;
}

.munition-details-panel__close {
  float: right;
  min-height: 0;
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  font-size: 0.9rem;
}


/* --- Strike report window (JUL04 strike display pass) ---------------------- */
/* Rides the combat-window chrome (root backdrop, shell, header, command panes,
   slot cards) but swaps the two facing craft rails for flight-vs-complex: the
   striking flight on the left, the target's surveyed sites/components on the
   right, and the hour's chronological impact results across the bottom. */

.strike-window-root {
  /* Below the combat window (24): when both panels have reason to be open the
     live encounter wins and the strike report waits behind it. */
  z-index: 23;
}

.strike-window-grid {
  display: grid;
  grid-template-columns: minmax(200px, 260px) minmax(200px, 1fr) 36px minmax(240px, 1.6fr);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 0.75rem;
  align-items: stretch;
  min-height: 0;
}

.strike-vs {
  grid-column: 3;
}

.strike-slot-rail .combat-slot {
  cursor: default;
}

/* The strike rail packs four slots into the height it shares with the target
   pane, so each art cell is shorter than the combat window's. Cap the craft art
   to its cell (height-bound, keeping its aspect ratio) rather than letting the
   width-driven square overrun into the slot's label and footer. Flex (not the
   base grid) gives the image a definite-height container to size against. */
.strike-slot .combat-slot-art {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}

.strike-slot .combat-slot-art img {
  width: auto;
  height: auto;
  aspect-ratio: auto;
  max-width: min(62%, 96px);
  max-height: 100%;
}

.strike-slot.is-strike-shooter {
  border-color: var(--amber, #ffb300);
  box-shadow: 0 0 0 1px rgba(255, 179, 0, 0.35), inset 0 0 18px rgba(255, 179, 0, 0.12);
}

.strike-target-pane {
  grid-column: 4;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.strike-site-list {
  display: grid;
  gap: 0.55rem;
  align-content: start;
  overflow: auto;
  min-height: 0;
  padding: 0.55rem 0.65rem;
}

.strike-site {
  border: 1px solid var(--border);
  background: rgba(8, 11, 9, 0.68);
  border-radius: 3px;
  overflow: hidden;
}

.strike-site-toggle {
  width: 100%;
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto auto;
  gap: 0.45rem;
  align-items: center;
  padding: 0.5rem 0.55rem;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  text-align: left;
}

/* Per-release markers stacked against a site: red × hit, grey square no-effect,
   circle point-defense intercept. Wraps at ~20 marks/row, capped at three rows,
   sitting just left of the caret. */
.strike-site-tally {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: flex-end;
  gap: 1px 2px;
  max-width: 180px;
  max-height: 25px;
  overflow: hidden;
}

.strike-tally-mark {
  width: 7px;
  height: 7px;
  display: inline-grid;
  place-items: center;
  font-style: normal;
}

.strike-tally-mark.hit::before {
  content: "×";
  color: var(--red);
  font: 700 10px/1 var(--mono);
}

.strike-tally-mark.square::before {
  content: "";
  width: 5px;
  height: 5px;
  background: var(--outline);
}

.strike-tally-mark.pd::before {
  content: "";
  width: 5px;
  height: 5px;
  border: 1px solid var(--primary-hot);
  border-radius: 50%;
}

.strike-tally-mark.is-fresh {
  animation: strike-tally-pop 0.28s ease-out both;
}

@keyframes strike-tally-pop {
  from {
    opacity: 0;
    transform: scale(0.35);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.strike-site-toggle:hover,
.strike-site.is-expanded .strike-site-toggle {
  background: rgba(0, 218, 243, 0.06);
  color: var(--text);
}

.strike-site-toggle:focus-visible {
  outline: 1px solid var(--primary-hot);
  outline-offset: -2px;
}

.site-category-glyph {
  width: 16px;
  height: 16px;
  color: var(--secondary-hot);
  fill: none;
  stroke: currentColor;
}

.site-category-glyph.unknown {
  display: grid;
  place-items: center;
  font: 700 0.9rem var(--mono);
}

.strike-site-caret {
  color: var(--primary-hot);
  transition: transform 0.14s ease;
}

.strike-site.is-expanded .strike-site-caret {
  transform: rotate(90deg);
}

.strike-site-name {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.strike-site ul {
  margin: 0;
  padding: 0.15rem 0.55rem 0.55rem;
  list-style: none;
  display: grid;
  gap: 0.3rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.strike-component {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.55rem;
  font-family: var(--mono);
  font-size: 0.72rem;
}

.strike-component-state {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.strike-component-state strong.ok {
  color: var(--green);
}

.strike-component-state strong.damaged {
  color: var(--amber, #ffb300);
}

.strike-component-state strong.destroyed {
  color: var(--red);
}

.strike-hit-flag {
  font-style: normal;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  padding: 0.1rem 0.35rem;
  border-radius: 2px;
  border: 1px solid var(--red);
  color: var(--red);
}

.strike-hit-flag.deflected {
  border-color: var(--border);
  color: var(--muted);
}

.strike-no-intel {
  margin: 0.4rem 0.2rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}

.strike-impact-log {
  grid-column: 1 / -1;
  border: 1px solid var(--border);
  background: rgba(8, 11, 9, 0.68);
  border-radius: 3px;
  padding: 0.45rem 0.65rem 0.55rem;
}

.strike-impact-heading {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--primary-hot);
}

/* Release cue inside the firing craft's frame, at center-right. Keeping it away
   from the top edge prevents a long munition name from being clipped by the
   slot's overflow boundary. */
.strike-callout {
  position: absolute;
  top: 50%;
  right: 4px;
  z-index: 5;
  max-width: 54%;
  padding: 2px 6px;
  border: 1px solid var(--secondary-hot);
  background: rgba(8, 11, 9, 0.9);
  color: var(--secondary-hot);
  font-family: var(--display);
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.06em;
  text-align: center;
  text-transform: uppercase;
  white-space: normal;
  pointer-events: none;
  animation: strike-callout-pop 1000ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes strike-callout-pop {
  0% {
    opacity: 0;
    transform: translate(-4px, -50%) scale(0.92);
  }
  18% {
    opacity: 1;
    transform: translate(0, -50%) scale(1);
  }
  72% {
    opacity: 1;
    transform: translate(0, -50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(4px, -50%) scale(0.98);
  }
}

/* Impact reaction on the struck site's title bar: a sharp jolt while the border
   flashes red and fades back through green to its resting phosphor tone. Both
   flashes end on the resting border/no-shadow frame, so dropping the class on
   the next beat re-render leaves nothing to snap back from. */
.strike-site.is-strike-hit {
  animation: strike-site-hit-flash 0.85s ease-out both;
}

.strike-site.is-strike-deflected {
  animation: strike-site-deflect-flash 0.7s ease-out both;
}

.strike-site.is-strike-hit .strike-site-toggle,
.strike-site.is-strike-deflected .strike-site-toggle {
  animation: strike-site-hit-shake 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

@keyframes strike-site-hit-flash {
  0% {
    border-color: var(--red);
    box-shadow: 0 0 0 1px var(--red), 0 0 16px rgba(255, 82, 82, 0.55);
  }
  28% {
    border-color: var(--red);
    box-shadow: 0 0 0 1px rgba(255, 82, 82, 0.55), 0 0 12px rgba(255, 82, 82, 0.35);
  }
  62% {
    border-color: var(--green);
    box-shadow: 0 0 0 1px rgba(0, 230, 118, 0.5), 0 0 12px rgba(0, 230, 118, 0.3);
  }
  100% {
    border-color: var(--border);
    box-shadow: 0 0 0 1px transparent, 0 0 0 transparent;
  }
}

@keyframes strike-site-deflect-flash {
  0% {
    border-color: var(--secondary-hot);
    box-shadow: 0 0 0 1px var(--secondary-hot), 0 0 10px rgba(254, 179, 0, 0.4);
  }
  100% {
    border-color: var(--border);
    box-shadow: 0 0 0 1px transparent, 0 0 0 transparent;
  }
}

@keyframes strike-site-hit-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(2px); }
  30%, 50%, 70% { transform: translateX(-4px); }
  40%, 60% { transform: translateX(4px); }
}

.strike-impact-log ol {
  display: grid;
  gap: 0.35rem;
  max-height: 130px;
  margin: 0.4rem 0 0;
  padding: 0 0 0 1.75rem;
  overflow: auto;
  font-family: var(--mono);
  font-size: 0.72rem;
}

.strike-impact-meta {
  color: var(--outline);
  margin-right: 0.55rem;
}

.strike-impact b {
  color: var(--text);
  font-weight: 500;
}

.strike-impact.component_destroyed b,
.strike-impact.deployable_destroyed b {
  color: var(--red);
}

.strike-impact.component_damaged b {
  color: var(--amber, #ffb300);
}

.strike-impact.strike_pd_absorbed b,
.strike-impact.strike_no_penetration b,
.strike-impact.engagement_blocked b,
.strike-impact.strike_target_missed b {
  color: var(--muted);
}

.combat-header-chip.strike-outcome-effect_on_target {
  border-color: var(--red);
  color: var(--red);
}

.combat-header-chip.strike-outcome-no_damage,
.combat-header-chip.strike-outcome-missed,
.combat-header-chip.strike-outcome-blocked {
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  .strike-callout,
  .strike-site.is-strike-hit,
  .strike-site.is-strike-deflected,
  .strike-site.is-strike-hit .strike-site-toggle,
  .strike-site.is-strike-deflected .strike-site-toggle,
  .strike-tally-mark.is-fresh {
    animation: none;
  }
}

/* --- Combat Log printer reel (JUL10_COMBAT_LOG_PASS) --------------------------
   The OPS detail panel becomes tabbed (Mission Details | Combat Log); the log
   is a reel of green-bar continuous-feed paper fed from a print-head slot at
   the top — newest report on top, older reports flowing down. The paper is the
   one warm-light surface in the dark console: chassis/tabs stay on app tokens,
   everything on the paper is monospace ink. No sound, no paper physics
   (JUL10_COMBAT_LOG_VISUAL_GUIDE). The console stays lit in both themes — a
   committed single-world device, not a missing theme. */

.detail-tab-strip {
  display: flex;
  flex-shrink: 0;
  gap: 0.35rem;
  margin-bottom: 0.6rem;
  border-bottom: 1px solid var(--gasket);
  padding-bottom: 0.45rem;
}

.detail-tab {
  flex: 1;
  font-family: var(--display);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.32rem 0.5rem;
  background: var(--chassis-850);
  border: 1px solid var(--gasket);
  color: var(--muted);
  box-shadow: inset 0 1px 0 var(--bezel-hi);
  cursor: pointer;
}

.detail-tab.active {
  color: rgba(158, 240, 180, 0.92);
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 0 8px rgba(61, 255, 124, 0.16);
}

.detail-tab.has-issues {
  color: var(--red);
  border-color: rgba(255, 82, 82, 0.7);
  background: rgba(120, 22, 22, 0.45);
}

.detail-tab.has-issues.active {
  color: #ff8a80;
  box-shadow:
    inset 0 1px 0 var(--bezel-hi),
    inset 0 0 8px rgba(255, 82, 82, 0.28);
}

.detail-tab:focus-visible {
  outline: 2px solid var(--lamp-green);
  outline-offset: 1px;
}

.combat-log-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.combat-log-pane[hidden] {
  display: none;
}

/* Planning uses the same physical printer and continuous paper as the Combat
   Log. Only the document printed onto it changes: a validation slip is
   actionable, while execution telemetry is archival. */
.plan-report-pane,
.plan-report-body,
.plan-report-shell {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.plan-report-pane[hidden] {
  display: none;
}

.plan-report-actions {
  display: flex;
  flex-shrink: 0;
  margin-top: 0.5rem;
}

.plan-report-recheck {
  flex: 1;
}

/* The reel scrolls inside itself; its cap gives up room for the Recheck row
   below so Recheck stays on screen under a long report. */
.log-reel-frame.plan-report-frame {
  max-height: calc(62vh - 3.5rem);
}

.plan-report-head-state {
  color: rgba(158, 240, 180, 0.78);
}

.plan-report-lamp {
  background: #687060;
}

.plan-report-shell.is-clear .plan-report-lamp {
  background: var(--lamp-green);
  box-shadow: 0 0 5px rgba(61, 255, 124, 0.6);
}

.plan-report-shell.is-stale .plan-report-lamp {
  background: var(--lamp-amber);
  box-shadow: 0 0 5px rgba(255, 179, 0, 0.55);
}

.plan-report-shell.is-blocked .plan-report-lamp {
  background: var(--lamp-red);
  box-shadow: 0 0 5px rgba(255, 79, 79, 0.55);
}

/* Print-head slit: the mouth the paper feeds out of. It spans exactly the
   paper's width; the reel frame pulls up over its lower half (negative top
   margin on the frame), so the paper edge sits in the middle of the groove —
   emerging from it, not sitting under it. */
.log-slot-slit {
  height: 8px;
  background: var(--gasket);
  border-radius: 3px;
  box-shadow:
    inset 0 2px 3px rgba(0, 0, 0, 0.8),
    0 1px 0 var(--bezel-hi);
}

/* Ready/printing lamps live in the stencil row beside the hour readout — the
   amber lamp blinks only while a record is printing (.printing rides the
   pane). */
.log-head-status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.log-lamp {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #1c2420;
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.7);
}

.log-lamp-ready {
  background: var(--lamp-green);
  box-shadow: 0 0 5px rgba(61, 255, 124, 0.6);
}

.log-lamp-printing {
  background: #4a3a10;
}

.combat-log-pane.printing .log-lamp-printing {
  background: var(--lamp-amber);
  box-shadow: 0 0 6px rgba(255, 179, 0, 0.7);
  animation: log-lamp-blink 0.5s steps(2, start) infinite;
}

@keyframes log-lamp-blink {
  to {
    opacity: 0.35;
  }
}

.log-head-stencil {
  display: flex;
  justify-content: space-between;
  font-family: var(--display);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.15rem 0.2rem 0.4rem;
}

.log-head-hour {
  color: rgba(158, 240, 180, 0.78);
}

/* Reel frame: chassis showing through punched sprocket margins on both sides;
   a short top haze so fresh lines look newly emerged from the slot. */
.log-reel-frame {
  position: relative;
  display: flex;
  flex: 1;
  min-height: 260px;
  max-height: 62vh;
  /* Ride up over the slit's lower half — being positioned and later in the
     DOM, the paper paints on top, emerging from the middle of the groove. */
  margin-top: -4px;
  overflow-y: auto;
  border: 1px solid var(--gasket);
  /* The paper's top edge catches light as it exits the groove — without this
     bright lip the edge fuses with the dark slit and the emergence is lost. */
  border-top-color: rgba(255, 253, 240, 0.55);
  background: #d9d5c0;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.45);
}

.log-reel-frame::before {
  content: "";
  position: sticky;
  top: 0;
  height: 10px;
  flex: none;
  width: 100%;
  /* The frame is a row flex container, so this pseudo-element is a flex item;
     the negative margin cancels its width so it overlays the row instead of
     pushing the sprockets and paper sideways. */
  margin-right: -100%;
  /* The print head's cast shadow: the paper shades as it disappears up into
     the slit. Kept lighter than the groove so the paper edge stays visible
     against it. Sticky, because the head is fixed to the chassis while the
     paper scrolls beneath it. */
  background: linear-gradient(rgba(12, 15, 11, 0.28), rgba(12, 15, 11, 0));
  pointer-events: none;
  z-index: 1;
}

.log-sprocket {
  flex: none;
  width: 13px;
  background-color: #d9d5c0;
  /* Punched holes: the chassis shows through. */
  background-image: radial-gradient(circle at 50% 50%, var(--gasket) 2.5px, transparent 3px);
  background-size: 13px 18px;
  border-right: 1px dashed rgba(35, 41, 31, 0.25);
}

.log-sprocket-right {
  border-right: none;
  border-left: 1px dashed rgba(35, 41, 31, 0.25);
}

/* The paper. Green-bar banding is painted on the scrolling content layer
   (background-attachment: local) at 2x the line rhythm so the bands move with
   the text — banding that stays put while text scrolls reads as
   misregistration (visual guide §5.1).
   Registration contract: every block on the paper must be an exact multiple
   of --log-line tall (line-height: var(--log-line), vertical padding in
   half-line steps), and must not use layout-affecting vertical borders — the
   browser snaps border widths to device pixels (1px renders as 0.571px at
   1.75x dpr), so any border in the flow drifts the bands off the text. */
.log-reel {
  --log-line: 1.15rem;
  flex: 1;
  min-width: 0;
  padding: calc(var(--log-line) * 0.5) 0.6rem;
  background-color: #e9e6d4;
  background-image: repeating-linear-gradient(
    rgba(96, 150, 104, 0.14) 0,
    rgba(96, 150, 104, 0.14) var(--log-line),
    transparent var(--log-line),
    transparent calc(var(--log-line) * 2)
  );
  background-attachment: local;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  line-height: var(--log-line);
  color: #23291f;
}

.log-empty {
  font-family: var(--display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7c8271;
  text-align: center;
  line-height: var(--log-line);
  padding: var(--log-line) 0;
}

.log-report {
  position: relative;
  padding: calc(var(--log-line) * 0.5) 0;
}

/* Tear rule between reports: painted as an overlay, not a border, so it takes
   no layout space (see the registration contract above). */
.log-report::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-top: 1px dashed rgba(35, 41, 31, 0.28);
}

.log-report:last-child::after {
  content: none;
}

/* Plan Report printout. It follows the reel's line rhythm and tear rules, but
   uses its own headings and full-width correction buttons. */
.plan-report-reel {
  --log-line: 1.2rem;
}

.plan-print-report {
  position: relative;
  padding: calc(var(--log-line) * 0.5) 0;
}

.plan-print-report::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  border-top: 1px dashed rgba(35, 41, 31, 0.28);
}

.plan-print-report:last-child::after {
  content: none;
}

.plan-print-headline {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  font-weight: 700;
}

.plan-print-stamp,
.plan-print-count {
  color: #4f5647;
  font-family: var(--display);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.plan-print-count {
  color: #a5352a;
  font-family: var(--mono);
  font-size: 0.78rem;
}

.plan-print-leader {
  flex: 1;
  min-width: 0.6rem;
  border-bottom: 2px dotted rgba(79, 86, 71, 0.55);
  transform: translateY(-3px);
}

.plan-print-report p {
  margin: 0;
  color: #3d4538;
}

.plan-print-status.clear .plan-print-stamp { color: #3f6b3a; }
.plan-print-status.stale .plan-print-stamp { color: #8a5c16; }
.plan-print-status.neutral .plan-print-stamp { color: #6f7566; }
.plan-print-status.refused .plan-print-stamp { color: #a5352a; }

.plan-print-group h3 {
  margin: 0;
  color: #23291f;
  font-family: var(--display);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  line-height: var(--log-line);
  text-transform: uppercase;
}

.plan-print-owner {
  color: #4f5647;
  font-size: 0.68rem;
  font-weight: 700;
  line-height: var(--log-line);
}

.plan-print-issue {
  display: grid;
  width: 100%;
  margin: 0;
  padding: 0.1rem 0.25rem;
  border: 1px solid transparent;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: #23291f;
  font: inherit;
  line-height: var(--log-line);
  text-align: left;
}

.plan-print-issue small {
  color: #6f7566;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  line-height: var(--log-line);
}

.plan-print-issue:not(:disabled) {
  cursor: pointer;
}

.plan-print-issue:not(:disabled):hover,
.plan-print-issue:not(:disabled):focus-visible {
  border-color: rgba(63, 107, 58, 0.7);
  background: rgba(96, 150, 104, 0.16);
  color: #1b2419;
  outline: none;
}

.plan-print-issue:disabled {
  cursor: default;
  opacity: 0.82;
}

.log-headline {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  font-weight: 700;
}

.log-hour {
  color: #4f5647;
}

.log-headline-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Dot leader between the headline and its outcome chip. */
.log-leader {
  flex: 1;
  min-width: 0.6rem;
  border-bottom: 2px dotted rgba(79, 86, 71, 0.55);
  transform: translateY(-3px);
}

.log-anchor {
  color: #4f5647;
  white-space: nowrap;
}

/* Outcome chips: boxed ribbon-color ink (guide §5.2 default). */
.log-chip {
  flex: none;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  /* Keep the chip box (line + 3px of borders) under --log-line so it can't
     stretch the headline row off the banding rhythm. */
  line-height: calc(var(--log-line) - 6px);
  padding: 0 0.3rem;
  border: 1.5px solid currentColor;
  border-radius: 2px;
}

.log-chip-kill {
  color: #a5352a;
}

.log-chip-hit {
  color: #8a5c16;
}

.log-chip-good {
  color: #3f6b3a;
}

.log-chip-flat {
  color: #6f7566;
}

.log-chip-info {
  color: #4f5647;
}

.log-subline {
  padding-left: 20px;
  color: #4f5647;
}

.log-tone-kill {
  color: #a5352a;
  font-weight: 700;
}

.log-tone-hit {
  color: #8a5c16;
}

.log-actions {
  display: flex;
  gap: 0.7rem;
  padding-left: 20px;
}

/* On-paper toggles read as printed marks, not console buttons — reset the
   full global keycap treatment (min-height, shadow, uppercase), not just
   background and border; the 36px keycap min-height also broke the banding
   rhythm. */
.log-action {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  min-height: 0;
  padding: 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: var(--log-line);
  letter-spacing: normal;
  text-transform: none;
  color: #4f5647;
  text-decoration: underline dotted;
  cursor: pointer;
}

.log-action:hover {
  color: #23291f;
}

.log-action:focus-visible {
  outline: 2px solid #3f6b3a;
  outline-offset: 1px;
}

/* The torn-open detail strip: god's-eye per-roll rows. The reel never scrolls
   sideways — wide rows scroll inside the strip (guide §5.4). */
.log-detail {
  margin: 0 0 0 20px;
  /* Full-line top padding keeps the strip's text on the band grid; the bottom
     half-line of padding plus the half-line scrollbar below completes the
     rhythm. overflow-x is `scroll` (not `auto`) so the scrollbar's space is
     reserved whether or not a row overflows — a sometimes-there scrollbar
     would knock everything below off the bands. */
  padding: var(--log-line) 0.45rem calc(var(--log-line) * 0.5);
  background: rgba(35, 41, 31, 0.06);
  border-left: 3px solid rgba(79, 86, 71, 0.45);
  font-size: 0.66rem;
  line-height: var(--log-line);
  color: #23291f;
  white-space: pre;
  overflow-x: scroll;
}

.log-detail::-webkit-scrollbar {
  height: calc(var(--log-line) * 0.5);
  background: transparent;
}

.log-detail::-webkit-scrollbar-thumb {
  background: rgba(79, 86, 71, 0.45);
  border-radius: 2px;
}

/* Hovering a report pulses its impact / own-craft hex on the map (never a
   launcher hex — ADR 0019 §2). */
.marker-log-anchor-pulse {
  fill: rgba(255, 179, 0, 0.22);
  stroke: rgba(255, 179, 0, 0.65);
  stroke-width: 1.2;
  transform-box: fill-box;
  transform-origin: center;
  animation: combat-ping-pulse 1.2s ease-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .combat-log-pane.printing .log-lamp-printing {
    animation: none;
  }

  .marker-log-anchor-pulse {
    animation: none;
    opacity: 0.5;
  }
}

/* Whole-Sortie timing and compact itinerary hour controls. */
.sortie-row .gantt-phase.is-launch-editable {
  cursor: grab;
  touch-action: none;
  user-select: none;
}
.itin-timing {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.itin-hour-controls {
  display: flex;
  gap: 2px;
}
.itin-hour-controls button {
  min-width: 20px;
  min-height: 18px;
  height: 18px;
  padding: 0 3px;
  line-height: 16px;
  font-size: 12px;
}

.system-result-panel {
  display: grid;
  gap: 1rem;
  margin-bottom: 1rem;
  padding: 1.25rem;
}

.system-result-panel[hidden] {
  display: none;
}

.system-result-carriers,
.system-result-losses {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 0.75rem;
}

.system-result-carriers article,
.system-result-side {
  display: grid;
  gap: 0.4rem;
  padding: 0.8rem;
  border: 1px solid var(--border);
}

.system-result-carriers article small {
  color: var(--muted);
}

.system-result-panel details {
  overflow-wrap: anywhere;
}

.departure-summary {
  min-width: 0;
  padding: 0.7rem;
  background: var(--glass-bg);
  color: var(--phos-green);
  font-family: var(--mono);
}
.departure-summary summary { cursor: pointer; }
.departure-summary h4, .departure-summary > details { margin-top: 0.8rem; }
.departure-summary ul { padding-left: 1.3rem; }

.system-result-op-log {
  max-height: 25rem;
  overflow: auto;
}

/* Operational carrier schematic: HVS-approved red/orange condition exception. */
.production-feedback { padding:.8rem 1rem; margin:.75rem 0; border:1px solid var(--border); background:var(--glass-bg); }
.production-forecast-stats { display:flex; flex-wrap:wrap; gap:.6rem 1.5rem; font:.8rem var(--mono); }
.production-forecast-stats strong { color:var(--phos-green); font-size:1.1rem; }
.production-blocked { color:#ffb366; margin:.8rem 0 0; }
.production-receipt { border-top:1px solid var(--border); margin-top:.8rem; padding-top:.8rem; }
.production-receipt summary { cursor:pointer; font:.8rem var(--mono); }
.production-work-detail { display:block; margin-top:.3rem; font:.7rem var(--mono); color:var(--muted); }
.logistics-resources { display:flex; flex-wrap:wrap; gap:1.5rem; padding:1rem; margin:.75rem 0; border:1px solid var(--border); background:var(--glass-bg); }
.logistics-resources span { display:block; color:var(--muted); font:.7rem var(--mono); }
.logistics-resources strong { display:block; margin-top:.4rem; font:1.5rem var(--mono); }
.logistics-resources p { flex-basis:100%; margin:0; }
.logistics-locked { color:#ffb366; }
.logistics-storage { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr)); gap:.75rem; margin:.75rem 0; }
.logistics-bin { min-width:0; padding:1rem; border:1px solid var(--border); background:var(--glass-bg); }
.logistics-bin header { display:flex; align-items:center; justify-content:space-between; gap:1rem; }
.logistics-bin header h3 { margin:0; }
.logistics-bin header span { font:.7rem var(--mono); color:var(--phos-green); }
.logistics-bin.destroyed { border-color:#ff8585; }
.logistics-bin.destroyed header span { color:#ff8585; }
.logistics-bin.damaged { border-color:#ffb366; }
.logistics-bin.damaged header span { color:#ffb366; }
.logistics-meter { display:flex; height:.5rem; margin:1rem 0; background:var(--gasket); overflow:hidden; }
.logistics-meter > span { background:var(--phos-green); }
.logistics-meter > .reserved { background:repeating-linear-gradient(135deg,#ffb366 0 3px,transparent 3px 6px); }
.logistics-usage { display:flex; flex-wrap:wrap; justify-content:space-between; gap:.75rem; font:.75rem var(--mono); }
.logistics-usage dt { color:var(--muted); }
.logistics-usage dd { margin:.3rem 0; }
.logistics-bin td { overflow-wrap:anywhere; }
.logistics-complex { margin:1rem 0; }
.cv-operational { --cv-destroyed: #ff8585; --cv-damaged: #ffb366; }
.cv-tabs { display:flex; gap:.5rem; overflow:auto; position:sticky; top:0; z-index:2; background:var(--chassis-900); padding:.5rem 0; }
.cv-tabs > button { flex:1; min-width:10rem; position:relative; }
.cv-tabs strong,.cv-tabs span { display:block; }
.cv-tabs span { font-family:var(--mono); font-size:.7rem; margin-top:.4rem; }
.cv-alert { color:var(--phos-amber); }
.cv-sections { display:flex; gap:.4rem; margin:.6rem 0; flex-wrap:wrap; }
.cv-status-workspace { display:grid; grid-template-columns:minmax(0,1fr) 16rem; gap:.75rem; align-items:start; }
.cv-viewport { border:2px solid var(--gasket); background:var(--glass-bg); overflow:auto; }
.cv-viewport > svg { display:block; width:100%; min-width:740px; }
.cv-hull { fill:none; stroke:var(--phos-green); stroke-width:2; opacity:.4; }
.cv-cell { position:relative; height:100%; border:1px solid var(--phos-green); color:var(--phos-green); background:var(--glass-bg); }
.cv-cell.critical { border-width:2px; }
.cv-cell.damaged { color:var(--cv-damaged); border-color:var(--cv-damaged); background:repeating-linear-gradient(135deg,transparent 0 6px,#ffb36618 6px 7px),var(--glass-bg); }
.cv-cell.destroyed { color:var(--cv-destroyed); border-color:var(--cv-destroyed); background:linear-gradient(20deg,transparent 49%,#ff858538 50%,transparent 51%),linear-gradient(-20deg,transparent 49%,#ff858538 50%,transparent 51%),var(--glass-bg); }
.cv-cell.selected { outline:2px solid currentColor; outline-offset:-3px; }
.cv-cell.muted { opacity:.25; }
.cv-cell button.cv-cell-select { width:100%; height:100%; display:block; border:0; border-radius:0; padding:2px 4px; box-shadow:none; background:transparent; color:inherit; text-align:left; font:9px var(--mono); }
.cv-cell-select > span:first-child { display:block; white-space:nowrap; font-size:8px; }
.cv-cell-content { display:flex; align-items:center; gap:3px; height:calc(100% - 12px); padding-bottom:8px; }
.cv-cell-content > svg { width:20px; height:20px; flex-shrink:0; fill:none; stroke:currentColor; stroke-width:1.4; }
.cv-cell-repair { position:absolute; top:0; right:0; }
.cv-cell-repair button { min-width:14px; padding:0 2px; border:1px solid currentColor; border-radius:0; font:10px var(--mono); color:inherit; background:var(--glass-bg); box-shadow:none; }
.cv-stored { position:absolute; bottom:1px; right:4px; font:7px/8px var(--mono); }
.cv-craft-marks { display:grid; grid-template-columns:repeat(9,8px); gap:1px; }
.cv-craft-marks svg { width:8px; height:9px; fill:none; stroke:currentColor; stroke-width:1.5; }
.cv-inspector-data { padding:.6rem; background:var(--glass-bg); font-family:var(--mono); color:var(--phos-green); }
.cv-inspector-data > svg { width:40px; height:40px; fill:none; stroke:currentColor; }
.cv-inspector > button { width:100%; margin-top:.5rem; }
.cv-focus { display:grid; grid-template-columns:repeat(auto-fit,minmax(11rem,1fr)); gap:.4rem; margin:.7rem 0; }
.cv-focus > div { padding:.5rem; background:var(--glass-bg); }
@media(max-width:1000px) { .cv-status-workspace { grid-template-columns:minmax(0,1fr); } }

/* UI05: compact supply forecasts and actual sortie accounting. */
.ammunition-feedback { margin-top: 12px; padding: 12px; border: 1px solid var(--border, #35424d); min-width: 0; }
.ammunition-feedback h4 { margin: 0 0 8px; letter-spacing: .12em; }
.ammo-forecast, .ammo-record summary { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 16px; padding: 8px 0; }
.ammo-forecast small { display: block; opacity: .65; }
.ammo-warning { color: #f2ab55; }
.ammo-details { margin-top: 10px; }
.ammo-details > summary, .ammo-record > summary { cursor: pointer; }
.ammo-record { border-top: 1px solid #35424d; padding: 4px 0; overflow-wrap: anywhere; }
.ammo-record p { margin: 6px 0; }
.ammo-record summary::before { content: "+"; }
.ammo-record[open] summary::before { content: "-"; }
.ammo-record summary > span { flex: 1; min-width: 120px; }
.ammo-quantities > div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 16px; padding: 4px 0; }
.ammo-quantities > div > span:first-child { opacity: .7; }

/* OCT28 resource collection: carrier collection line and the Resource map layer. */
.cv-collection, .resource-nodes .hint { margin: 8px 0; color: var(--phos-green); font: .78rem/1.5 var(--mono); }
.resource-node { pointer-events: none; }
.resource-node-belt { fill: var(--phos-amber); fill-opacity: .55; stroke: none; }
.resource-node-giant { fill: none; stroke: var(--phos-amber); stroke-width: 2; stroke-dasharray: 4 3; }
.resource-node-empty { opacity: .25; }
.resource-node-label { fill: var(--phos-amber); font: 700 9px var(--mono); text-anchor: middle; paint-order: stroke; stroke: var(--chassis-900, #000); stroke-width: 3px; }
/* Shared encounter flight theater. Scoped to avoid changing strike cards. */
.combat-flight-layout .combat-window-grid {
  grid-template-columns: minmax(165px, 205px) minmax(0, 1fr) minmax(165px, 205px);
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 0.6rem;
}

.combat-flight-layout .combat-command {
  grid-template-rows: auto minmax(100px, 1fr) minmax(90px, 0.8fr) auto;
  padding: 0.85rem;
  gap: 0.8rem;
  border: 1px solid var(--chassis-500);
  border-radius: 3px;
  background: linear-gradient(115deg, var(--chassis-800), var(--chassis-900));
  box-shadow: inset 1px 1px var(--bezel-hi), inset -1px -1px var(--bezel-lo);
}

.combat-flight-layout .combat-command header { flex-direction: column; gap: 0.4rem; }
.combat-flight-layout .combat-command header h3 { font-size: clamp(1rem, 1.5vw, 1.4rem); }
.combat-flight-layout .combat-command header b { font-size: 0.68rem; }
.combat-flight-layout .combat-command.blue header span { color: var(--side-blue); }
.combat-flight-layout .combat-command-accent { height: 2px; opacity: 0.6; }
.combat-flight-layout .combat-command.blue .combat-command-accent { background: var(--side-blue); }
.combat-flight-layout .combat-meter strong { color: var(--text); text-shadow: none; font-size: clamp(3rem, 6vw, 6rem); }
.combat-flight-layout .combat-state { box-shadow: none; border-color: var(--border); }
.combat-flight-layout .combat-state strong { font-size: clamp(1rem, 1.5vw, 1.6rem); color: var(--phos-green); }
.combat-flight-layout .combat-command.red .combat-state strong { color: var(--phos-amber); }
.combat-flight-layout .combat-agi-value.agi-win { color: var(--phos-green); }
.combat-flight-layout .combat-agi-value.agi-lose { color: var(--phos-amber); }

.combat-flight-scene {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: clamp(1rem, 5vh, 3.5rem);
  min-width: 0;
  min-height: 480px;
  padding: 3.5rem 1.1rem 2rem;
  overflow: hidden;
  border: 1px solid var(--chassis-600);
  background: radial-gradient(ellipse at 50% 45%, #101b19 0%, #080d0d 55%, #040807 100%);
  box-shadow: inset 0 0 55px #0009, 0 0 0 3px var(--gasket);
}

.combat-flight-caption {
  position: absolute;
  inset: 1rem 1.1rem auto;
  display: flex;
  justify-content: space-between;
  gap: 0.6rem;
  color: var(--stencil-dim);
  font: 0.6rem var(--mono);
  letter-spacing: 0.14em;
  pointer-events: none;
}

.combat-starfield { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.combat-starfield::before,
.combat-starfield::after {
  content: "";
  position: absolute;
  inset: 0;
  background-repeat: repeat;
  animation: combat-stars-down 28s linear infinite;
  /* Match a shared clock when AGI updates rebuild the panel: no restart flicker. */
  animation-delay: var(--star-phase, 0ms);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='480' viewBox='0 0 400 480'%3E%3Cg fill='%23d8e2d9'%3E%3Ccircle cx='31' cy='44' r='1'/%3E%3Ccircle cx='124' cy='206' r='.7'/%3E%3Ccircle cx='298' cy='108' r='.7'/%3E%3Ccircle cx='212' cy='356' r='.9'/%3E%3Ccircle cx='365' cy='319' r='1'/%3E%3Ccircle cx='66' cy='429' r='.6'/%3E%3Ccircle cx='177' cy='74' r='.5'/%3E%3Ccircle cx='346' cy='465' r='.5'/%3E%3C/g%3E%3Cg stroke='%239ebbb5' stroke-opacity='.25'%3E%3Cpath d='M31 44v20M212 356v32M365 319v13'/%3E%3C/g%3E%3C/svg%3E");
  opacity: 0.7;
}
.combat-starfield::after {
  background-size: 640px 768px;
  animation-name: combat-stars-distant;
  animation-duration: 42s;
  opacity: 0.25;
}
.combat-starfield.paused::before,
.combat-starfield.paused::after { animation-play-state: paused; }
@keyframes combat-stars-down { from { background-position: 0 0; } to { background-position: 0 480px; } }
@keyframes combat-stars-distant { from { background-position: 120px 0; } to { background-position: 120px 768px; } }

.combat-flight-formation {
  --formation-depth: clamp(44px, 9vh, 90px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}
.combat-flight-layout .combat-slot {
  --craft-color: var(--side-blue);
  position: relative;
  display: grid;
  grid-template-rows: 70px auto;
  align-content: center;
  gap: 0.55rem;
  min-width: 0;
  width: 100%;
  max-width: 190px;
  justify-self: center;
  min-height: 155px;
  padding: 0.4rem;
  overflow: visible;
  color: var(--craft-color);
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  box-shadow: none;
  text-align: left;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.combat-flight-layout .combat-slot.red { --craft-color: var(--red); }
/* Finger-four silhouette: the second craft leads, with a short left wing and
   a longer two-craft right wing. Depth belongs to the formation, not the icon. */
.combat-flight-layout .combat-slot:nth-child(1) { top: calc(var(--formation-depth) * 0.3); }
.combat-flight-layout .combat-slot:nth-child(2) { top: calc(var(--formation-depth) * -0.85); }
.combat-flight-layout .combat-slot:nth-child(3) { top: calc(var(--formation-depth) * 0.1); }
.combat-flight-layout .combat-slot:nth-child(4) { top: calc(var(--formation-depth) * 0.85); }
.combat-flight-layout .combat-slot:hover,
.combat-flight-layout .combat-slot.selected { border-color: color-mix(in srgb, var(--craft-color) 30%, transparent); background: #09131088; box-shadow: none; }
.combat-flight-layout .combat-slot:focus-visible { outline: 2px solid var(--craft-color); outline-offset: 2px; }
.combat-flight-layout .combat-slot-art { padding: 0; min-height: 0; display: grid; place-items: center; }
.combat-chevron { width: clamp(40px, 4.7vw, 70px); height: 64px; overflow: visible; color: var(--craft-color); filter: drop-shadow(0 0 5px color-mix(in srgb, currentColor 28%, transparent)); }
.combat-chevron path { fill: none; stroke: currentColor; stroke-width: 4; stroke-linecap: square; stroke-linejoin: miter; }
/* Packaged frame art (fixed 200x200 line art); keeps its own detail stroke widths. */
.combat-craft-art { width: clamp(52px, 5.6vw, 84px); height: auto; aspect-ratio: 1; overflow: visible; color: var(--craft-color); filter: drop-shadow(0 0 5px color-mix(in srgb, currentColor 28%, transparent)); }
.combat-flight-layout .combat-slot.destroyed :is(.combat-chevron, .combat-craft-art) { opacity: 0.25; filter: grayscale(1); }
.combat-flight-layout .combat-slot.effect-kill-fade :is(.combat-chevron, .combat-craft-art) { animation: combat-kill-fade 2000ms ease-out both; animation-delay: var(--effect-delay, 0ms); animation-play-state: var(--effect-play-state, running); }
.combat-flight-layout .combat-slot.empty { opacity: 0.3; }
.combat-flight-empty { font: 1.5rem var(--mono); color: var(--stencil-dim); }
.combat-flight-layout .combat-slot-footer { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.35rem; width: fit-content; min-width: 100px; max-width: 100%; justify-self: center; border: 0; padding: 0.4rem 0.35rem; background: #060b0cc4; font: 0.68rem var(--mono); color: var(--text); }
.combat-flight-layout .combat-slot-footer span { padding: 0; border: 0; min-width: 0; }
.combat-flight-layout .combat-slot-footer > span,
.combat-flight-layout .combat-slot-footer > strong { display: block; padding: 0; border: 0; min-width: 0; }
.combat-flight-layout .combat-slot-label { font-size: 0.78rem; font-weight: 400; letter-spacing: 0.025em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combat-flight-layout .combat-slot-footer strong { font-size: 0.72rem; letter-spacing: 0.06em; }
.combat-flight-layout .combat-slot-footer .ok { color: var(--phos-green); }
.combat-flight-layout .combat-slot-footer .damaged { color: var(--phos-amber); }
.combat-flight-layout .combat-slot-footer .empty { color: var(--muted); }
.combat-flight-layout .combat-slot.contact .combat-slot-footer strong { color: var(--muted); }
.combat-flight-layout .combat-slot-footer .combat-missiles { display: flex; align-items: center; gap: 0.65rem; }
.combat-missile-label, .combat-ammo-unknown, .combat-ammo-empty { font-size: 0.7rem; color: var(--muted); }
.combat-flight-layout .combat-slot-footer .combat-missile-notches { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; min-height: 13px; }
.combat-missile-notch { display: block; width: 4px; height: 12px; border-radius: 1px; background: var(--craft-color); box-shadow: 0 0 6px color-mix(in srgb, var(--craft-color) 55%, transparent); }
.combat-missile-notches small { color: var(--muted); font-size: 0.6rem; }
/* M6A S8: the rest of a known slot's stock — Tercio's END-fire pip and mark chips. */
.combat-slot-ammo { display: flex; flex-wrap: wrap; align-items: center; gap: 0.2rem 0.45rem; font-size: 0.66rem; color: var(--text); }
.combat-end-fire { padding: 0 0.3rem; border: 1px solid var(--craft-color, currentColor); border-radius: 2px; font-size: 0.6rem; letter-spacing: 0.08em; }
.combat-flight-layout .combat-callout { top: 10px; font-size: 0.65rem; padding: 3px 5px; }

@media (max-width: 1100px) {
  .combat-flight-layout .combat-window-grid { grid-template-columns: minmax(135px, 165px) minmax(0, 1fr) minmax(135px, 165px); }
  .combat-flight-layout .combat-command { padding: 0.6rem; }
  .combat-flight-scene { padding-left: 0.4rem; padding-right: 0.4rem; }
  .combat-flight-layout .combat-slot-footer { font-size: 0.6rem; padding: 0.3rem 0.1rem; }
  .combat-flight-layout .combat-slot-label { font-size: 0.58rem; }
}
@media (max-width: 760px) {
  .combat-flight-layout { max-height: none; }
  .combat-flight-layout .combat-window-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto auto; }
  .combat-flight-scene { grid-column: 1 / -1; grid-row: 1; min-height: 520px; }
  .combat-flight-formation { --formation-depth: 44px; }
  .combat-flight-layout .combat-command { grid-row: 2; grid-template-rows: auto 100px 80px auto; }
  .combat-flight-layout .combat-raw { grid-column: 1 / -1; }
  .combat-flight-caption { font-size: 0.5rem; }
  .combat-flight-layout .combat-slot-label { font-size: 0.56rem; }
  .combat-flight-layout .combat-slot-footer { min-width: 0; width: 100%; }
  .combat-flight-layout .combat-slot-footer strong { font-size: 0.55rem; }
}
@media (prefers-reduced-motion: reduce) {
  .combat-starfield::before, .combat-starfield::after { animation: none; }
  .combat-flight-layout .combat-slot.effect-kill-fade :is(.combat-chevron, .combat-craft-art) { animation-duration: 1ms; }
}

/* Pair-level combat choreography; labels travel but never rotate. */
.combat-craft-heading { display: grid; place-items: center; transform: rotate(0deg); }
.combat-slot.red .combat-craft-heading { transform: rotate(180deg); }
.combat-flight-formation.red .combat-slot:nth-child(1) { top: calc(var(--formation-depth) * -0.3); }
.combat-flight-formation.red .combat-slot:nth-child(2) { top: calc(var(--formation-depth) * 0.85); }
.combat-flight-formation.red .combat-slot:nth-child(3) { top: calc(var(--formation-depth) * -0.1); }
.combat-flight-formation.red .combat-slot:nth-child(4) { top: calc(var(--formation-depth) * -0.85); }
.combat-flight-scene.pair-active .combat-slot:not(.duel-active) { opacity: 0.26; }
.combat-flight-layout .combat-slot.duel-active {
  z-index: 8;
  border-color: transparent;
  background: transparent;
  animation-duration: var(--duel-duration);
  animation-delay: var(--duel-delay);
  animation-timing-function: ease-in-out;
  animation-fill-mode: both;
  animation-play-state: var(--duel-play-state);
}
.combat-flight-layout .duel-active .combat-craft-heading {
  animation-duration: var(--duel-duration);
  animation-delay: var(--duel-delay);
  animation-fill-mode: both;
  animation-timing-function: ease-in-out;
  animation-play-state: var(--duel-play-state);
}
.combat-flight-layout .duel-maneuver { animation-name: combat-duel-jockey; }
.combat-flight-layout .duel-maneuver .combat-craft-heading { animation-name: combat-duel-settle; }
.combat-flight-layout .duel-departing { animation-name: combat-duel-return; }
.combat-flight-layout .duel-departing .combat-craft-heading { animation-name: combat-duel-settle; }
.combat-flight-layout .duel-position { animation-name: combat-duel-position; }
.combat-flight-layout .duel-position.duel-target .combat-craft-heading { animation-name: combat-duel-turn; }
.combat-flight-layout .duel-attacker.red .combat-callout.shooting { color: var(--red); }
.combat-flight-layout .duel-active .combat-slot-art,
.combat-flight-layout .duel-active .combat-chevron,
.combat-flight-layout .duel-active .combat-craft-art,
.combat-flight-layout .duel-active .combat-callout {
  animation-delay: var(--duel-delay);
  animation-play-state: var(--duel-play-state);
}
.combat-flight-layout .duel-pursue { animation-name: combat-duel-pursue; }
.combat-flight-layout .duel-pursue .combat-craft-heading { animation-name: combat-duel-pursue-turn; }
.combat-flight-layout .duel-break { animation-name: combat-duel-break; }
.combat-flight-layout .duel-fire,
.combat-flight-layout .duel-hit,
.combat-flight-layout .duel-miss { transform: translate(var(--chase-x), var(--chase-y)); }
.combat-flight-layout .duel-fire .combat-craft-heading,
.combat-flight-layout .duel-hit .combat-craft-heading,
.combat-flight-layout .duel-miss .combat-craft-heading { transform: rotate(var(--heading-to)); }
.combat-flight-layout .duel-miss.duel-target { animation-name: combat-duel-evade; }
.combat-flight-layout .duel-reform { animation-name: combat-duel-reform; }
.combat-flight-layout .duel-reform .combat-craft-heading { animation-name: combat-duel-faceoff; }
.combat-flight-layout .duel-reform.duel-no-shot { animation-name: combat-duel-reform-break; }
.combat-flight-layout .duel-hit.duel-target .combat-slot-art::after {
  content: "";
  position: absolute;
  width: 80px;
  height: 80px;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, #fff3c8b3, #ffb34744 25%, transparent 65%);
  animation: combat-duel-impact var(--duel-duration) ease-out both;
  animation-delay: var(--duel-delay);
  animation-play-state: var(--duel-play-state);
}
.combat-projectile {
  position: absolute;
  z-index: 10;
  width: 4px;
  height: 16px;
  margin: -8px 0 0 -2px;
  border-radius: 3px;
  pointer-events: none;
  background: #eaffff;
  box-shadow: 0 0 7px var(--side-blue), 0 0 16px var(--side-blue);
  animation: combat-duel-shot var(--duel-duration) linear both;
  animation-delay: var(--duel-delay);
  animation-play-state: var(--duel-play-state);
}
.combat-projectile.red { background: #fff1e6; box-shadow: 0 0 7px var(--red), 0 0 16px var(--red); }
.combat-projectile.miss { animation-name: combat-duel-shot-miss; }
/* OCT27: the maneuver contest reads out in the gap left of the formations. */
.combat-maneuver-readout { position: absolute; left: .8rem; top: 50%; z-index: 8; transform: translateY(-50%); display: grid; gap: 4px; min-width: 6.4rem; padding: 6px 8px; border: 1px solid var(--chassis-600); background: rgba(4, 8, 7, 0.86); font: .6rem var(--mono); letter-spacing: .08em; color: var(--muted); text-align: center; pointer-events: none; }
.combat-maneuver-readout > div { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.combat-maneuver-readout > div strong { font-size: 1.05rem; color: var(--text); font-variant-numeric: tabular-nums; }
.combat-maneuver-readout > div.red small { color: var(--red); }
.combat-maneuver-readout > div.blue small { color: var(--side-blue); }
.combat-maneuver-readout > div.won strong { text-decoration: underline; text-underline-offset: 3px; }
.combat-maneuver-readout > b { font-size: .7rem; letter-spacing: .12em; }
.combat-maneuver-readout > b.red { color: var(--red); }
.combat-maneuver-readout > b.blue { color: var(--side-blue); }
.combat-maneuver-readout.pending strong { animation: combat-readout-roll .25s steps(2) infinite; }
@keyframes combat-readout-roll { 50% { opacity: .35; } }
/* OCT27 volleys: a target's HIT / MISS sits below its own SHOOTING call. */
.combat-callout.incoming { top: -18px; }
.combat-callout.intercepted { color: var(--side-blue); }
/* OCT27 volleys: every shot of a round flies at once, shooter to target. */
.combat-volley-shot {
  position: absolute;
  z-index: 10;
  width: 4px;
  height: 14px;
  margin: -7px 0 0 -2px;
  border-radius: 3px;
  pointer-events: none;
  background: #eaffff;
  box-shadow: 0 0 7px var(--side-blue), 0 0 16px var(--side-blue);
  animation: combat-volley-shot var(--duel-duration) ease-in both;
  animation-delay: var(--duel-delay);
  animation-play-state: var(--duel-play-state);
}
.combat-volley-shot.red { background: #fff1e6; box-shadow: 0 0 7px var(--red), 0 0 16px var(--red); }
.combat-volley-shot.miss { animation-name: combat-volley-shot-miss; }
@keyframes combat-volley-shot {
  0% { opacity: 0; transform: translate(0, 0) rotate(var(--shot-angle)); }
  10% { opacity: 1; }
  90% { opacity: 1; transform: translate(var(--dx), var(--dy)) rotate(var(--shot-angle)); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) rotate(var(--shot-angle)); }
}
@keyframes combat-volley-shot-miss {
  0% { opacity: 0; transform: translate(0, 0) rotate(var(--shot-angle)); }
  10% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(var(--dx) * 1.25 + 24px), calc(var(--dy) * 1.25)) rotate(var(--shot-angle)); }
}
/* A continuing pair's next maneuver starts from its --from pose; fresh pairs from formation. */
@keyframes combat-duel-jockey {
  0% { transform: translate(var(--from-x, 0px), var(--from-y, 0px)); }
  25% { transform: translate(calc(var(--meet-x) - 13px), var(--meet-y)); }
  48% { transform: translate(calc(var(--meet-x) + 15px), calc(var(--meet-y) - 6px)); }
  73% { transform: translate(calc(var(--meet-x) - 10px), calc(var(--meet-y) + 5px)); }
  100% { transform: translate(var(--meet-x), var(--meet-y)); }
}
@keyframes combat-duel-position {
  0% { transform: translate(var(--meet-x), var(--meet-y)); }
  50% { transform: translate(calc(var(--chase-x) + 26px), var(--chase-y)); }
  100% { transform: translate(var(--chase-x), var(--chase-y)); }
}
@keyframes combat-duel-pursue {
  0% { transform: translate(var(--from-x, 0px), var(--from-y, 0px)); }
  60% { transform: translate(calc(var(--chase-x) + 26px), var(--chase-y)); }
  100% { transform: translate(var(--chase-x), var(--chase-y)); }
}
@keyframes combat-duel-pursue-turn {
  from { transform: rotate(var(--from-heading, var(--rest-heading))); }
  to { transform: rotate(var(--heading-to)); }
}
@keyframes combat-duel-return {
  from { transform: translate(var(--from-x), var(--from-y)); }
  to { transform: translate(0, 0); }
}
@keyframes combat-duel-settle {
  0% { transform: rotate(var(--from-heading, var(--rest-heading))); }
  25%, 100% { transform: rotate(var(--rest-heading)); }
}
@keyframes combat-duel-turn {
  from { transform: rotate(var(--heading-from)); }
  to { transform: rotate(var(--heading-to)); }
}
@keyframes combat-duel-break {
  from { transform: translate(var(--meet-x), var(--meet-y)); }
  to { transform: translate(var(--break-x), var(--break-y)); }
}
@keyframes combat-duel-evade {
  0% { transform: translate(var(--chase-x), var(--chase-y)); }
  40%, 65% { transform: translate(calc(var(--chase-x) + 60px), var(--chase-y)); }
  100% { transform: translate(var(--chase-x), var(--chase-y)); }
}
@keyframes combat-duel-reform {
  from { transform: translate(var(--chase-x), var(--chase-y)); }
  to { transform: translate(0, 0); }
}
@keyframes combat-duel-reform-break {
  from { transform: translate(var(--break-x), var(--break-y)); }
  to { transform: translate(0, 0); }
}
@keyframes combat-duel-faceoff {
  from { transform: rotate(var(--heading-to)); }
  to { transform: rotate(var(--heading-from)); }
}
@keyframes combat-duel-shot {
  0%, 10% { opacity: 0; transform: translateY(0); }
  20% { opacity: 1; }
  90% { opacity: 1; transform: translateY(calc(var(--shot-travel) * 0.9)); }
  100% { opacity: 0; transform: translateY(var(--shot-travel)); }
}
@keyframes combat-duel-shot-miss {
  0% { opacity: 1; transform: translateY(var(--shot-travel)); }
  80%, 100% { opacity: 0; transform: translateY(calc(var(--shot-travel) * 2.2)); }
}
@keyframes combat-duel-impact {
  0% { opacity: 0; transform: scale(0.35); }
  15% { opacity: 1; }
  100% { opacity: 0; transform: scale(1.5); }
}
@media (prefers-reduced-motion: reduce) {
  .combat-flight-layout .combat-slot.duel-active,
  .combat-flight-layout .duel-active .combat-craft-heading,
  .combat-flight-layout .duel-hit.duel-target .combat-slot-art::after { animation: none; }
  .combat-flight-layout .combat-slot.duel-active { transform: none; }
  .combat-projectile { display: none; }
}

/* Optional lab variant: opposite points on a shared pursuit circle. The paired
   counter-rotation keeps the entire readout upright while the craft turn. */
.combat-flight-layout .duel-maneuver.duel-orbit { animation-name: combat-duel-orbit; }
.combat-flight-layout .duel-maneuver.duel-orbit .combat-craft-heading { animation-name: combat-duel-orbit-heading; }
@keyframes combat-duel-orbit {
  0% { transform: translate(var(--from-x, 0px), var(--from-y, 0px)) rotate(0deg) translateX(0) rotate(0deg); }
  18% { transform: translate(var(--orbit-cx), var(--orbit-cy)) rotate(0deg) translateX(var(--orbit-offset)) rotate(0deg); }
  100% { transform: translate(var(--orbit-cx), var(--orbit-cy)) rotate(-360deg) translateX(var(--orbit-offset)) rotate(360deg); }
}
@keyframes combat-duel-orbit-heading {
  0% { transform: rotate(var(--from-heading, var(--orbit-heading))); }
  18% { transform: rotate(var(--orbit-heading)); }
  100% { transform: rotate(var(--orbit-heading-end)); }
}

/* OCT16 Q8: the Red AI lamp (login-card strip, rail key) and its flyout panel. */
.red-ai-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 12px;
  border: 1px solid rgba(216, 226, 217, 0.18);
  background: rgba(10, 18, 16, 0.85);
  font-size: 0.85rem;
  cursor: pointer;
}
.red-ai-strip .red-ai-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #6b7470;
  flex: none;
}
.red-ai-strip[data-lamp="orange"] .red-ai-dot { background: #e89a2c; box-shadow: 0 0 6px #e89a2c; }
.red-ai-strip[data-lamp="green"] .red-ai-dot { background: #4fd18b; box-shadow: 0 0 6px #4fd18b; }
.red-ai-strip[data-lamp="red"] .red-ai-dot { background: #ff4d4d; box-shadow: 0 0 6px #ff4d4d; }
.red-ai-strip[data-lamp="red"] { border-color: rgba(255, 77, 77, 0.6); }
.red-ai-ready-marks { display: flex; gap: 8px; }
.red-ai-ready-marks [data-ready="yes"] { color: #4fd18b; }

/* Rail key: lamp dot over a two-line stencil legend; detail lives in the tooltip. */
.rail-actions .red-ai-rail-key {
  gap: 2px;
  padding: 0.3rem 0;
  font-size: 0.52rem;
  line-height: 1.1;
  text-align: center;
}
.red-ai-rail-key .red-ai-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #6b7470;
}
.red-ai-rail-key .red-ai-key-state { color: var(--stencil-dim); white-space: nowrap; }
.red-ai-rail-key[data-lamp="orange"] .red-ai-dot { background: #e89a2c; box-shadow: 0 0 6px #e89a2c; }
.red-ai-rail-key[data-lamp="green"] .red-ai-dot { background: #4fd18b; box-shadow: 0 0 6px #4fd18b; }
.red-ai-rail-key[data-lamp="red"] .red-ai-dot { background: #ff4d4d; box-shadow: 0 0 6px #ff4d4d; }
.red-ai-rail-key[data-lamp="red"] .red-ai-key-state { color: var(--lamp-red); }
.red-ai-rail-key[data-lamp="await"] .red-ai-dot {
  background: var(--lamp-amber);
  box-shadow: 0 0 6px var(--lamp-amber);
  animation: annunciator-await 1.6s steps(2, jump-none) infinite;
}
.red-ai-rail-key[data-lamp="await"] .red-ai-key-state { color: var(--phos-amber); }
.red-ai-rail-key[aria-expanded="true"] { color: var(--phos-green-hot); }

/* Flyout beside the rail, so opening it never pushes the workspace down. */
.red-ai-panel {
  position: fixed;
  left: 72px;
  bottom: 0.75rem;
  z-index: 40;
  width: min(560px, calc(100vw - 88px));
  max-height: 70vh;
  overflow: auto;
}
.red-ai-panel .red-ai-history { width: 100%; font-size: 0.8rem; }
.red-ai-panel .red-ai-log { max-height: 220px; overflow: auto; font-size: 0.8rem; }
.red-ai-panel .red-ai-error { color: #ff8a8a; }
.player-card.ai-commander { opacity: 0.55; cursor: not-allowed; }
.skirmish-controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 8px 0; }
.red-ai-strip[hidden],
.red-ai-rail-key[hidden],
.red-ai-panel[hidden],
.skirmish-controls [hidden] {
  display: none;
}

/* The migrated preview owns picking; legacy map sprites retain their hit policy. */
.isometric-system-preview {
  touch-action: none;
}
.isometric-system-preview .system-planet-sprite,
.isometric-system-preview .system-star,
.isometric-system-preview .system-star-glow {
  pointer-events: auto;
  cursor: pointer;
}
.isometric-system-preview:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

.isometric-field-map { touch-action: none; }
.isometric-field-map:focus-visible { outline: 2px solid var(--primary); }

.marker-carrier-object { color: #78cddd; cursor: pointer; }
.marker-carrier-object.side-red { color: #e29180; }
.flight-ground-anchor { pointer-events: none; }
#hexMap:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }

/* Keep operational readouts legible as the plotting plane zooms out. */
#hexMap .marker-label,
.isometric-system-preview .marker-label { font-size: var(--map-label-size, 10px); }
.flight-marker.marker-blue { color: rgb(var(--owner-rgb)); }
.flight-marker.marker-red { color: var(--red); }
.marker-carrier-object.marker-red { color: var(--red); }
/* P1 carriers keep their muted cyan; seats 2-4 take their seat color. */
.marker-carrier-object.marker-blue[data-blue-player] { color: rgb(var(--owner-rgb)); }
@media (prefers-reduced-motion: reduce) {
  .map-marker { transition: none !important; }
}

/* Object selection stays attached to the planet; ground tools expose the grid. */
#hexMap .map-planet-object .system-planet-sprite {
  pointer-events: auto;
  cursor: pointer;
}
#hexMap .map-planet-object.is-object-active .system-planet-sprite {
  filter: drop-shadow(0 0 3px var(--secondary-hot));
}
#hexMap .marker-complex.is-object-active .complex-slot {
  color: var(--secondary-hot);
  filter: drop-shadow(0 0 2px var(--secondary));
}
#hexMap.map-ground-mode .map-planet-object,
#hexMap.map-ground-mode .marker-complex {
  opacity: 0.18;
  pointer-events: none;
}
#hexMap.map-ground-mode .map-planet-object *,
#hexMap.map-ground-mode .marker-complex * {
  pointer-events: none;
}
.planet-interaction-highlight {
  fill: rgba(254, 179, 0, 0.12);
  stroke: var(--secondary-hot);
  stroke-width: 1.6;
  pointer-events: none;
}
.map-target-heading {
  padding: 0.6rem;
  color: var(--secondary-hot);
  font-family: var(--mono);
}

.flight-craft-icon {
  overflow: visible;
  pointer-events: none;
}

/* M6B: the Strike pane stays beside the map and above the Gantt. */
@media (min-width: 981px) {
  .ops-layout {
    transition: grid-template-columns 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .ops-layout.has-strike-pane,
  .ops-layout.has-intel-pane {
    grid-template-columns: minmax(0, 1fr) clamp(420px, 34vw, 560px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ops-layout { transition: none; }
}
.strike-pane .loadout-pane-header {
  position: sticky;
  top: -0.85rem;
  z-index: 6;
  padding-block: 0.6rem;
  background: var(--chassis-800);
}
.strike-pane .strike-mode-control {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
}
.strike-pane .strike-detail-head {
  flex-wrap: wrap;
}
.strike-pane .strike-name-input {
  min-width: 0;
  width: 100%;
}
.strike-pane .strike-detail-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.strike-pane .strike-context {
  overflow-wrap: anywhere;
}
.strike-pane .strike-tree {
  margin-top: 1rem;
  min-width: 0;
}
.strike-pane .strike-node {
  min-width: 0;
  flex-wrap: wrap;
}
.strike-pane .strike-node-name {
  overflow-wrap: anywhere;
}
.strike-pane .strike-payload-row {
  min-width: 0;
}
/* M6B visual target overview: hour, complex/site arc, allocated silhouettes. */
.strike-target-card { display: grid; grid-template-columns: 72px minmax(0, 1fr) 112px; gap: 0.6rem; min-height: 205px; padding: 0.8rem; margin-bottom: 0.65rem; border: 1px solid var(--gasket); background: radial-gradient(ellipse at 44% 45%, #22372c, #111b19 76%); box-shadow: inset 0 1px 0 var(--bezel-hi); }
.strike-target-identity { min-width: 0; text-align: center; }
.strike-target-identity .strike-detail-head { justify-content: center; gap: 0.4rem; }
.strike-target-identity h3 { font-size: 1.05rem; margin: 0; overflow-wrap: anywhere; }
.strike-target-identity .chip { font-size: 0.55rem; }
.strike-target-art { border: 0; border-radius: 0; padding: 0; background: transparent; box-shadow: none; position: relative; width: 156px; max-width: 100%; height: 155px; margin: 0 auto; display: grid; place-items: start center; }
.strike-target-art > img { width: 145px; max-width: 100%; height: 132px; object-fit: contain; filter: drop-shadow(0 6px 12px #0009); }
.strike-target-art > svg { width: 108px; height: 108px; color: var(--primary); }
.strike-target-art[data-paint-node] { cursor: crosshair; border-radius: 12px; }
.strike-target-art[data-paint-node]:hover { box-shadow: inset 0 0 0 1px #9ddbb277; }
.strike-target-sites { position: absolute; z-index: 2; inset: 0; pointer-events: none; color: #d4c28b; }
.strike-overview-site { position: absolute; left: calc(50% + var(--site-x)); top: var(--site-y); transform: translate(-50%, -50%); width: 18px; height: 18px; pointer-events: auto; }
.strike-overview-site .site-category-glyph { width: 100%; height: 100%; }
.strike-overview-site small { display: block; font: 9px var(--mono); }
.strike-overview-site.is-disabled { opacity: 0.4; }
.strike-mode-toggle { display: inline-flex; border: 1px solid var(--gasket); }
.strike-mode-toggle button { border: 0; border-radius: 0; box-shadow: none; padding: 0.45rem 0.85rem; }
.strike-mode-toggle button[aria-pressed="true"] { opacity: 1; background: #294b36; color: var(--primary); box-shadow: inset 0 -2px var(--primary); }
.strike-mode-control { margin-bottom: 0.8rem; }
.strike-sortie-capacity { margin: 0.7rem 0 0.75rem; font: 0.7rem var(--mono); }
.strike-sortie-capacity > div:first-child { display: flex; justify-content: space-between; align-items: center; }
.strike-capacity-meter { height: 5px; margin: 0.4rem 0; background: var(--gasket); }
.strike-capacity-meter span { display: block; height: 100%; background: var(--primary); }
.strike-capacity-meta { display: flex; justify-content: space-between; color: var(--muted); }
.strike-source-caption { margin: 0.35rem 0 0.75rem; }
.strike-options { margin: 0.6rem 0 0.9rem; }
.strike-options > summary { cursor: pointer; font-size: 0.8rem; }
.strike-options[open] { display: grid; gap: 0.5rem; }
.strike-target-breakdown { margin-top: 1rem; }
.strike-pane .strike-target-breakdown .strike-tree { margin-top: 0.4rem; }
#hexMap.is-strike-target-picking { cursor: crosshair; }
#hexMap.is-strike-target-picking [data-hit="target"],
#hexMap.is-strike-target-picking [data-hit="deployable"] { cursor: crosshair; }
#hexMap.is-strike-target-picking .marker-complex { filter: drop-shadow(0 0 5px #b1edc0); }
/* OCT22 Strike drafting: one scrim over the map, the lit set redrawn above it. */
#hexMap.is-release-hex-picking { cursor: crosshair; }
.map-pick-scrim { fill: #04070a; opacity: 0.72; }
.map-pick-lit .pick-lit-target-hex { fill: rgba(177, 237, 192, 0.12); stroke: #b1edc0; stroke-width: 1.2; }
.map-pick-lit .release-basket-hex {
  fill: rgba(255, 170, 64, 0.32);
  stroke: #ffaa40;
  stroke-width: 1;
  animation: release-basket-pulse 1.1s ease-in-out infinite alternate;
}
@keyframes release-basket-pulse { from { fill-opacity: 0.35; } to { fill-opacity: 1; } }
.map-pick-lit.is-release-guide .release-basket-hex { fill: rgba(255, 170, 64, 0.16); stroke-dasharray: 4 3; }
@media (prefers-reduced-motion: reduce) { .map-pick-lit .release-basket-hex { animation: none; } }
.strike-release-hex { margin: 0.6rem 0; display: grid; gap: 0.35rem; font: 0.75rem var(--mono); }
.strike-release-hex p { margin: 0; }
.strike-auto-munitions { margin: 0 0 0.55rem; padding-left: 1rem; font: 0.72rem var(--mono); }
.field-fixed { display: block; padding: 0.35rem 0; font-family: var(--mono); }
@media (max-width: 1350px) {
  .strike-target-card { grid-template-columns: 58px minmax(0, 1fr) 88px; gap: 0.4rem; padding: 0.65rem; }
}

.strike-target-timing {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0.5rem 0 0.75rem;
}
.strike-hour { align-self: start; display: inline-flex; align-items: center; gap: 0.35rem; color: var(--primary); font-family: var(--mono); font-size: 0.9rem; }
.strike-hour svg { width: 19px; height: 19px; flex: none; }
.strike-contact-stale { color: var(--warning); font-family: var(--mono); font-size: 0.65rem; }
.strike-target-payload { --stack-columns: 5; min-width: 0; padding: 0; }
.strike-target-payload > .eyebrow { display: block; font-size: 0.6rem; line-height: 1.4; margin-bottom: 0.35rem; }
/* Round ink is 40px in 36px cells; the padding holds that spill so the stack only scrolls when it is genuinely taller than its cap. */
.strike-allocated-stack { display: flex; flex-direction: column; gap: 8px; max-height: 150px; padding: 3px; overflow-x: hidden; overflow-y: auto; scrollbar-width: thin; }
.strike-munition-pile { display: grid; grid-template-columns: repeat(var(--stack-columns), minmax(0, 1fr)); grid-auto-rows: var(--stack-pitch); column-gap: 1px; padding-bottom: calc(36px - var(--stack-pitch)); }
.strike-allocated-round { position: relative; display: block; height: 36px; min-width: 0; color: var(--stencil); border-radius: 2px; }
.strike-allocated-round:hover, .strike-allocated-round:focus-visible { z-index: 2; background: #1b2a20; outline: 1px solid var(--primary); outline-offset: -1px; }
.strike-round-ink, .strike-allocated-round > svg { position: absolute; left: 50%; top: 50%; width: 40px; height: 40px; transform: translate(-50%, -50%) rotate(90deg); pointer-events: none; filter: drop-shadow(0 -1px #14201a) drop-shadow(0 1px #14201a); }
.strike-round-ink { --ink-size: contain; }
@media (max-width: 1350px) { .strike-target-payload { --stack-columns: 4; } }

/* Manual Strike counts live inside the card's existing count station. */
.munition-card__total--strike-counts { font-size: 0.75rem; font-variant-numeric: tabular-nums; }
.munition-card__total.is-over { color: var(--danger, #ff5a5a); }
.strike-kamikaze-toggle { display: flex; align-items: center; gap: 0.4rem; margin: 0 0 0.55rem; font: 0.72rem var(--mono); text-transform: uppercase; cursor: pointer; }
.strike-kamikaze-toggle .hint { text-transform: none; }
.munition-card__total--solo:focus-visible { outline: 1px solid var(--stencil); outline-offset: 2px; }

/* Site-selected component tray: one physical component per badge. */
.strike-target-stage { position: relative; width: 156px; max-width: 100%; margin: 0 auto; }
button.strike-overview-site { min-height: 0; display: grid; place-items: center; box-sizing: content-box; padding: 5px; border: 1px solid transparent; border-radius: 50%; background: #17251d; box-shadow: none; color: #d4c28b; }
button.strike-overview-site:hover, button.strike-overview-site:focus-visible, button.strike-overview-site.is-selected { border-color: var(--primary); color: var(--primary); background: #284032; outline: none; }
.strike-pane .strike-tree-complex { display: grid; gap: 0.55rem; }
.strike-pane .strike-node-complex { display: flex; min-height: 32px; padding: 0.35rem 0.55rem; font-size: 0.7rem; justify-content: space-between; }
.strike-component-tray { min-width: 0; border: 1px solid #42604c; background: linear-gradient(135deg, #1d3025, #141e19); padding: 10px; box-shadow: inset 0 1px 0 #6c8a6233; }
.strike-component-tray-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.strike-component-tray-head h4 { font: 0.75rem var(--mono); color: var(--primary); margin: 0; }
.strike-whole-site { font: 0.65rem var(--mono); white-space: nowrap; padding: 5px 7px; background: #223829; border: 1px solid #526b4f; box-shadow: none; border-radius: 3px; color: #dac98e; }
.strike-component-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(48px, 1fr)); gap: 6px; max-height: 254px; overflow-y: auto; padding: 2px; scrollbar-width: thin; }
.strike-component-grid > .hint { grid-column: 1 / -1; margin: 0.5rem 0; }
.strike-component-badge { position: relative; display: grid; place-items: center; min-width: 0; height: 54px; padding: 0 7px 8px; border: 1px solid #59715b; border-radius: 3px; background: linear-gradient(#2d4031, #202e24); color: #c4cbb0; box-shadow: inset 0 1px 0 #9dac8133, 0 2px 3px #0005; cursor: crosshair; }
.strike-component-badge .component-symbol { width: 36px; height: 36px; }
.component-symbol.component-art { display: block; background-color: currentColor; mask-image: var(--component-art); mask-size: contain; mask-position: center; mask-repeat: no-repeat; -webkit-mask-image: var(--component-art); -webkit-mask-size: contain; -webkit-mask-position: center; -webkit-mask-repeat: no-repeat; }
.strike-component-badge:hover, .strike-component-badge:focus-visible { border-color: #d5e4b5; outline: 1px solid #d5e4b5; outline-offset: 1px; background: #3a503b; z-index: 1; }
.strike-component-badge.is-allocated { border-color: #dfaa67; color: #e9d3a0; background: linear-gradient(#51402a, #332b20); }
.strike-component-badge.is-other-target:not(.is-allocated) { border-color: #bc9c54; }
.component-armor { position: absolute; right: 3px; bottom: 5px; width: 14px; height: 16px; display: grid; place-items: center; font: 10px var(--mono); color: #c0c7ae; }
.component-armor svg { position: absolute; width: 100%; height: 100%; fill: #152119; stroke: currentColor; stroke-width: 1; }
.component-armor b { position: relative; font-weight: 500; font-size: 9px; line-height: 1; margin-top: -2px; }
.component-rounds { position: absolute; left: 3px; top: 2px; color: #f2c57c; font: 10px var(--mono); }
.component-condition { position: absolute; bottom: 0; left: 5px; right: 5px; height: 2px; background: #80956c; }
.is-damaged .component-condition { background: #dfaa67; width: 40%; }
.is-destroyed .component-symbol { opacity: 0.28; }
.is-destroyed .component-condition { background: #ad6759; }
.is-destroyed::after { content: ""; position: absolute; width: 31px; height: 1px; background: #ad6759; transform: rotate(-45deg); }
.strike-component-tooltip { position: fixed; inset: auto; margin: 0; max-width: min(290px, calc(100vw - 32px)); padding: 10px 12px; border: 1px solid #b6b88e; background: #101a15; color: #dbe3c6; white-space: pre-line; font: 12px/1.6 var(--mono); box-shadow: 0 6px 20px #000a; pointer-events: none; }
.strike-partial-intel { display: block; color: #b9aa77; margin-top: 8px; font: 10px var(--mono); }
.strike-site-prompt { margin: 0.1rem 0 0.5rem; }
button.strike-overview-site:active:not(:disabled) { transform: translate(-50%, calc(-50% + 1px)); }

/* Status stacks preserve exact members while reducing the component field. */
.strike-component-grid.is-stacked { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 18px 12px; padding: 9px 5px 8px; }
.strike-component-family { display: flex; flex-wrap: wrap; gap: 10px; max-width: 100%; padding-right: 10px; border-right: 1px solid #48604655; }
.strike-component-family:last-child { border-right: 0; }
.component-stack-shell { --component-card-size: 54px; --component-stack-offset: 3px; position: relative; width: calc(var(--component-card-size) + 2 * var(--component-stack-offset)); padding-top: calc(2 * var(--component-stack-offset)); margin-bottom: 19px; }
.component-stack-shell.has-third-layer::before, .component-stack-shell.has-depth::after { content: ""; position: absolute; box-sizing: border-box; width: var(--component-card-size); height: var(--component-card-size); border: 1px solid #59715b; border-radius: 3px; background: #233629; }
.component-stack-shell.has-third-layer::before { top: 0; left: calc(2 * var(--component-stack-offset)); }
.component-stack-shell.has-depth::after { top: var(--component-stack-offset); left: var(--component-stack-offset); }
.component-stack-shell:has(> .is-allocated)::before, .component-stack-shell:has(> .is-allocated)::after { border-color: #dfaa67; background: linear-gradient(#51402a, #332b20); }
.component-stack-shell .strike-component-stack { position: relative; z-index: 1; box-sizing: border-box; width: var(--component-card-size); height: var(--component-card-size); }
.component-stack-count { position: absolute; top: calc(100% + 4px); left: 0; width: 100%; color: #cdd8b8; text-align: center; font: 12px var(--mono); letter-spacing: 0; }
.component-stack-rounds { display: inline-flex; gap: 2px; align-items: center; top: 1px; left: 3px; }
.component-stack-rounds svg { width: 7px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1; }
.strike-component-stack.is-allocated .component-stack-count { color: #f2c57c; }

/* Strike report target pane: every site of the struck complex as its own
   Intel-style badge tray, with the strike's assigned rounds on the badges. */
.strike-site-trays { --border: #42604c; gap: 0.65rem; }
.strike-site-trays .strike-site { overflow: visible; }
.strike-site-trays .strike-site { position: relative; }
.strike-site-trays .strike-component-tray-head { justify-content: flex-start; width: 100%; min-height: 0; margin: 0 0 4px; padding: 0; border: 0; background: none; box-shadow: none; color: inherit; text-align: left; cursor: pointer; }
.strike-site-trays .strike-component-tray-head:focus-visible { outline: 1px solid var(--primary-hot); outline-offset: 2px; }
.strike-site-trays .strike-site.is-collapsed { padding: 6px 10px; }
.strike-site-trays .strike-component-tray-head .strike-whole-site { text-transform: none; letter-spacing: normal; }
.strike-site-trays .strike-site.is-collapsed .strike-component-tray-head { margin-bottom: 0; }
.strike-site-trays .strike-site-caret { transform: rotate(90deg); }
.strike-site-trays .strike-site.is-collapsed .strike-site-caret { transform: none; }
.strike-site-toast { position: absolute; left: 42%; top: 50%; z-index: 2; padding: 3px 8px; border: 1px solid var(--red); background: #1a0f0e; color: #ffb4a8; font: 0.68rem var(--mono); letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap; pointer-events: none; animation: strike-site-toast 1.6s ease-out both; }
.strike-site-toast.deflected { border-color: var(--secondary-hot); background: #1d170b; color: #ffd98a; }
@keyframes strike-site-toast {
  0% { opacity: 0; transform: translateY(-50%) scale(0.9); }
  12% { opacity: 1; transform: translateY(-50%) scale(1); }
  75% { opacity: 1; transform: translateY(-90%); }
  100% { opacity: 0; transform: translateY(-120%); }
}
.strike-site-trays .strike-component-tray-head h4 { flex: 1 1 auto; min-width: 0; text-transform: uppercase; letter-spacing: 0.08em; }
.strike-site-trays .strike-site-glyph { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: #17251d; border: 1px solid #42604c; }
.strike-site-trays .strike-site-glyph .site-category-glyph { color: #d4c28b; }
.strike-site-trays .strike-whole-site b { color: #f2c57c; font-weight: 500; }
.strike-site-trays .strike-component-grid.is-stacked { max-height: none; overflow: visible; }
.strike-site-trays .strike-component-badge { cursor: default; }
.strike-target-pane > .strike-whole-complex { align-self: flex-start; margin: 0.55rem 0.65rem 0; }
.strike-site.is-strike-hit .strike-component-tray-head,
.strike-site.is-strike-deflected .strike-component-tray-head { animation: strike-site-hit-shake 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }
.strike-component-badge.is-fresh-hit { animation: strike-badge-hit 0.9s ease-out both; }
@keyframes strike-badge-hit {
  0% { border-color: var(--red); box-shadow: 0 0 0 2px var(--red), 0 0 14px rgba(255, 82, 82, 0.6); }
  60% { border-color: var(--red); box-shadow: 0 0 0 1px rgba(255, 82, 82, 0.5), 0 0 8px rgba(255, 82, 82, 0.3); }
  100% { box-shadow: inset 0 1px 0 #9dac8133, 0 2px 3px #0005; }
}
@media (prefers-reduced-motion: reduce) {
  .strike-site.is-strike-hit .strike-component-tray-head,
  .strike-site.is-strike-deflected .strike-component-tray-head,
  .strike-component-badge.is-fresh-hit,
  .strike-site-toast { animation: none; }
}

/* Strike editing belongs to its itinerary leg; ordinary row selection stays separate. */
.itinerary-row .itin-edit-strike { min-height: 24px; padding: 0.2rem 0.35rem; font-size: 0.6rem; letter-spacing: 0.03em; flex: none; color: var(--primary); }

.itinerary-row:has(> .itin-edit-strike) { grid-template-columns: 1.4rem minmax(0, 1fr) auto auto auto; }

/* Contextual patrols (OCT22 D11/D14): Patrol posture toggle, "extend station" re-up
   and the shared passive marker (Gantt bar, map flight marker). */
.itinerary-row:has(> .itin-posture) { grid-template-columns: 1.4rem minmax(0, 1fr) auto auto auto auto; }
.itinerary-row .itin-posture,
.itinerary-row .itin-extend { min-height: 22px; padding: 0.15rem 0.35rem; font-size: 0.6rem; letter-spacing: 0.04em; flex: none; border: 1px solid var(--border); background: var(--surface-low); color: var(--stencil-dim); }
.itinerary-row .itin-posture.is-auto { color: var(--green); }
.itinerary-row .itin-posture.is-passive { color: var(--secondary-hot); border-color: var(--secondary-hot); }
.gantt-scratch-tag {
  flex: 0 0 auto;
  color: var(--danger, #ff5a5a);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: 0 3px;
  font-size: 0.6rem;
  line-height: 1.4;
}
.sortie-row.is-scratched .gantt-phase { opacity: 0.35; text-decoration: line-through; }
.sortie-row .gantt-phase-label { white-space: nowrap; }
.sortie-row .gantt-passive-marker { margin-left: 0.3rem; color: #ff9a3c; font-weight: 700; letter-spacing: 0.04em; }
.sortie-row .gantt-harvest-marker { margin-left: 0.3rem; color: var(--phos-amber, #ffc857); font-weight: 700; letter-spacing: 0.04em; }
.sortie-row .gantt-harvest-marker.is-underway { text-decoration: underline; }
.flight-marker .flight-passive-marker { fill: var(--secondary-hot); font-weight: 700; }

/* Vessel course selection and map editing. */
.vessel-route-hit {
  stroke: transparent;
  stroke-width: 14px;
  vector-effect: non-scaling-stroke;
  pointer-events: stroke;
  cursor: grab;
}
.route-vessel-point { cursor: grab; pointer-events: all; }
.vessel-selected { filter: drop-shadow(0 0 5px #f7cf72); }
.vessel-route-undo { cursor: pointer; pointer-events: all; }
.vessel-route-undo rect { fill: #182b24; stroke: #f7cf72; stroke-width: 1; }
.vessel-route-undo text { fill: #f7cf72; font: 10px monospace; pointer-events: none; }
.vessel-route-undo:hover rect, .vessel-route-undo:focus rect { fill: #34473a; }


/* Encounter viewer: resolved rolls travel with craft; side progress stays put. */
.combat-flight-layout .combat-command { grid-template-rows: auto auto minmax(90px, 1fr) auto; }
.combat-base-agi { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: .5rem 0; font: .7rem var(--mono); color: var(--muted); }
.combat-base-agi strong { font-size: 1.4rem; color: var(--text); }
.combat-contest { position: relative; width: 100%; box-sizing: border-box; display: grid; gap: .4rem; padding: .65rem .4rem; text-align: center; background: #080d0dee; border-top: 1px solid var(--phos-amber); border-bottom: 1px solid var(--chassis-500); font: .73rem/1.4 var(--mono); color: var(--text); pointer-events: none; }
.combat-flight-layout .combat-contest > strong { color: var(--phos-amber); font-size: .82rem; letter-spacing: .08em; }
.combat-contest > small { color: var(--muted); }
.combat-flight-layout .combat-roll { position: absolute; top: -35px; left: 50%; transform: translateX(-50%); display: grid; gap: 2px; min-width: 70px; padding: 4px 8px; color: var(--text); background: #080d0df5; border-left: 2px solid var(--craft-color, var(--phos-amber)); text-align: center; font-family: var(--mono); pointer-events: none; z-index: 9; }
.combat-roll small { font-size: .6rem; white-space: nowrap; color: var(--muted); }
.combat-flight-layout .combat-roll strong { font-size: 1.55rem; line-height: 1; font-variant-numeric: tabular-nums; }
.combat-side-rolls { display: grid; grid-template-columns: 1fr 1fr; gap: .4rem; }
.combat-side-rolls > div > small { font-size: .6rem; }
.combat-side-rolls .blue { color: var(--side-blue); }
.combat-side-rolls .red { color: var(--red); }
.combat-flight-layout .combat-side-rolls .combat-roll { position: static; transform: none; min-width: 0; padding: 3px; border: 0; background: transparent; }
.combat-escape-tracker { position: absolute; left: .8rem; right: .8rem; z-index: 7; display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem .65rem; font: .65rem var(--mono); color: var(--muted); pointer-events: none; }
.combat-escape-tracker.red { top: 3.9rem; }
.combat-escape-tracker.blue { bottom: .6rem; }
.combat-escape-tracker strong { color: var(--text); font-size: 1rem; font-variant-numeric: tabular-nums; }
.combat-escape-tracker.red > span { color: var(--red); }
.combat-escape-tracker.blue > span { color: var(--side-blue); }
/* OCT27 position encounters (branch-only): bypass timer pips and the position bar. */
.combat-bypass-pips { display: inline-flex; gap: 3px; }
.combat-bypass-pips i { width: 8px; height: 8px; border: 1px solid currentColor; border-radius: 50%; background: currentColor; }
.combat-bypass-pips i.spent { background: transparent; opacity: .45; }
.combat-escape-tracker.red .combat-bypass-pips { color: var(--red); }
.combat-escape-tracker.blue .combat-bypass-pips { color: var(--side-blue); }
.combat-position-bar { position: absolute; left: 50%; top: 2.1rem; z-index: 8; transform: translateX(-50%); display: grid; grid-template-columns: repeat(5, minmax(2.1rem, 1fr)); gap: 2px; padding: 2px; border: 1px solid var(--chassis-600); background: rgba(4, 8, 7, 0.82); font: .58rem var(--mono); letter-spacing: .06em; pointer-events: none; }
.combat-position-cell { padding: 2px 4px; text-align: center; color: var(--muted); border: 1px solid transparent; }
.combat-position-cell.red { color: rgba(255, 82, 82, .7); }
.combat-position-cell.blue { color: rgba(var(--blue-player-2-rgb), .85); }
.combat-position-cell.active { color: var(--text); font-weight: 700; border-color: currentColor; }
.combat-position-cell.red.active { background: rgba(255, 82, 82, .28); border-color: var(--red); }
.combat-position-cell.blue.active { background: rgba(var(--blue-player-2-rgb), .3); border-color: var(--side-blue); }
.combat-position-cell.neutral.active { background: rgba(159, 174, 159, .18); }
.combat-flight-tallies { grid-column: 1 / -1; display: flex; justify-content: space-between; gap: .5rem; padding: 2px 4px 0; font-size: .55rem; }
.combat-flight-tally.red { color: var(--red); }
.combat-flight-tally.blue { color: var(--side-blue); }
.combat-actions .combat-autofight { color: var(--muted); border-style: dashed; }
.combat-actions .combat-autofight.active { color: var(--primary-hot); border-style: solid; background: rgba(122, 214, 156, .14); }
@media (max-width: 700px) {
  .combat-position-bar { top: 1.8rem; grid-template-columns: repeat(5, minmax(1.6rem, 1fr)); font-size: .5rem; }
}
.combat-flight-layout .combat-slot:has(.combat-roll) { z-index: 9; }
@media (max-width: 700px) {
  .combat-contest { font-size: .65rem; padding: .5rem .3rem; }
  .combat-flight-layout .combat-contest > strong { font-size: .7rem; }
  .combat-escape-tracker small { display: none; }
  .combat-flight-layout .combat-command { grid-template-rows: auto auto minmax(80px, auto) auto; }
}
/* Keep explanatory text in clear space around the active pair. */
.combat-status-stack { display: grid; align-content: start; gap: .6rem; min-width: 0; }
.combat-flight-layout .duel-active .combat-slot-footer { position: absolute; top: 8px; left: calc(50% + 48px); min-width: 90px; max-width: 120px; background: #080d0d; }
.combat-flight-layout .duel-active .combat-roll { top: 10px; left: auto; right: calc(50% + 48px); transform: none; }
.combat-flight-scene.pair-active .combat-slot:not(.duel-active) .combat-slot-footer { visibility: hidden; }
.combat-flight-scene.side-contest .combat-flight-formation { --formation-depth: 0px; }
.combat-flight-scene.side-contest .combat-flight-formation.red { align-self: start; }
.combat-flight-scene.side-contest .combat-flight-formation.blue { align-self: end; }
.combat-flight-layout .side-contest .combat-slot { min-height: 100px; }
.combat-flight-layout .side-contest .combat-slot-footer > :not(.combat-slot-label) { display: none; }
@media (max-width: 700px) {
  .combat-flight-layout .duel-active .combat-slot-footer { left: calc(50% + 32px); min-width: 70px; max-width: 85px; }
  .combat-flight-layout .duel-active .combat-roll { right: calc(50% + 32px); min-width: 60px; }
}

/* Keep labels toward the interior while craft leave their formation slots. */
.combat-flight-layout .duel-active .combat-roll { top: -8px; left: calc(50% + 48px); right: auto; }
.combat-flight-layout .duel-active .combat-slot-footer { top: 44px; }
.combat-flight-layout .duel-active:is([data-combat-slot-index="2"], [data-combat-slot-index="3"]) :is(.combat-roll, .combat-slot-footer) { left: auto; right: calc(50% + 48px); }
@media (max-width: 700px) {
  .combat-flight-layout .duel-active .combat-roll { left: calc(50% + 32px); right: auto; }
  .combat-flight-layout .duel-active:is([data-combat-slot-index="2"], [data-combat-slot-index="3"]) :is(.combat-roll, .combat-slot-footer) { left: auto; right: calc(50% + 32px); }
}

/* OCT23 Target Intel pane: the Strike drawer's target card, read-only. */
.intel-pane .strike-target-card.intel-target-card { grid-template-columns: minmax(0, 1fr); min-height: 0; }
.intel-pane .intel-chips { justify-content: center; margin-bottom: 0.5rem; }
.intel-pane .intel-sri-balance { margin: 0 0 0.5rem; text-align: center; }
.intel-switcher { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.6rem; }
.intel-switch { min-height: 0; padding: 0.25rem 0.55rem; font: 0.68rem var(--mono); }
.intel-switch.is-active { border-color: var(--primary); color: var(--primary); background: #284032; }
.intel-strikes { margin-top: 0.85rem; }
.intel-strike-list { list-style: none; margin: 0.4rem 0 0; padding: 0; display: grid; gap: 0.4rem; }
.intel-strike-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 0.5rem; padding: 0.45rem 0.55rem; border: 1px solid var(--gasket); border-left: 3px solid rgb(var(--owner-rgb)); background: #141e19; }
.intel-strike-text { display: grid; min-width: 0; }
.intel-strike-text strong { font: 0.74rem var(--mono); color: var(--primary); overflow-wrap: anywhere; }
.intel-strike-text small { color: var(--muted); font-size: 0.66rem; overflow-wrap: anywhere; }
.intel-footer { margin-top: 0.85rem; display: flex; justify-content: flex-end; }

/* OCT23 Carrier Command Bloom: rack plate of squadron petals over a carrier. */
.carrier-bloom { position: absolute; inset: 0; z-index: 7; pointer-events: none; overflow: hidden; }
.carrier-bloom[hidden] { display: none; }
.carrier-bloom-anchor { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.carrier-bloom-stem { position: absolute; left: 0; top: 0; width: 1px; height: 1px; overflow: visible; transition: opacity 180ms; }
.carrier-bloom-stem line { stroke: rgba(var(--owner-rgb), 0.6); stroke-width: 1.2; stroke-dasharray: 3 3; }
.carrier-bloom-plate { position: absolute; border: 1px solid var(--gasket); background: linear-gradient(180deg, rgba(28, 35, 29, 0.96), rgba(16, 21, 17, 0.96)); box-shadow: inset 0 1px 0 var(--bezel-hi), 0 8px 22px rgba(0, 0, 0, 0.6); transform-origin: 50% 100%; transition: transform 260ms cubic-bezier(0.2, 1.2, 0.4, 1), opacity 180ms; }
.carrier-bloom-petal {
  --size: 52px;
  position: absolute; left: 0; top: 0; width: var(--size); height: var(--size); min-height: 0; margin: 0; padding: 0;
  display: grid; place-items: center; pointer-events: auto; cursor: pointer;
  border: 1px solid rgba(var(--owner-rgb), 0.7); border-radius: 6px;
  background: linear-gradient(180deg, var(--chassis-800), #121914);
  box-shadow: inset 0 1px 0 var(--bezel-hi), 0 4px 14px rgba(0, 0, 0, 0.55);
  color: rgb(var(--owner-rgb));
  transform: translate(calc(var(--x) - 50%), calc(var(--y) - 50%)) scale(1);
  transition: transform 300ms cubic-bezier(0.2, 1.35, 0.4, 1), opacity 200ms ease-out, box-shadow 160ms, border-color 160ms;
  transition-delay: var(--delay, 0ms);
}
.carrier-bloom-petal img { width: 64%; height: 64%; object-fit: contain; pointer-events: none; filter: drop-shadow(0 0 3px rgba(var(--owner-rgb), 0.55)); }
.carrier-bloom-petal svg { width: 56%; height: 56%; pointer-events: none; }
.carrier-bloom-petal:hover:not(:disabled), .carrier-bloom-petal:focus-visible { border-color: rgb(var(--owner-rgb)); box-shadow: inset 0 1px 0 var(--bezel-hi), 0 0 0 3px rgba(var(--owner-rgb), 0.22), 0 4px 14px rgba(0, 0, 0, 0.55); outline: none; }
.carrier-bloom-petal:disabled { cursor: not-allowed; filter: grayscale(0.85) brightness(0.6); }
.carrier-bloom-petal.is-command { --size: 40px; border-style: dashed; color: var(--primary); border-color: rgba(158, 240, 180, 0.6); }
.carrier-bloom-petal.is-lri-placed { color: var(--phos-green); border-color: rgba(158, 240, 180, 0.6); }
.carrier-bloom-petal.is-lri-unplaced { color: #ff9a3c; border-color: rgba(255, 154, 60, 0.85); box-shadow: inset 0 1px 0 var(--bezel-hi), 0 0 10px rgba(255, 154, 60, 0.55), 0 0 22px rgba(255, 154, 60, 0.3); }
.carrier-bloom-petal.is-lri-unplaced svg { filter: drop-shadow(0 0 3px rgba(255, 154, 60, 0.9)); }
.carrier-bloom-petal.is-lri:disabled { cursor: default; filter: none; opacity: 0.75; }
.carrier-bloom-count { position: absolute; left: 50%; top: calc(100% + 3px); transform: translateX(-50%); padding: 0 0.3rem; font: 600 0.72rem var(--mono); color: var(--text); background: rgba(8, 12, 10, 0.85); border: 1px solid var(--gasket); white-space: nowrap; pointer-events: none; }
.carrier-bloom-petal.is-armed { border-color: rgb(var(--owner-rgb)); box-shadow: 0 0 0 2px rgba(var(--owner-rgb), 0.9), 0 0 18px rgba(var(--owner-rgb), 0.6); }
.carrier-bloom-petal.is-armed::after { content: ""; position: absolute; inset: -7px; border-radius: 9px; border: 1px solid rgba(var(--owner-rgb), 0.8); animation: carrier-bloom-armed 1.2s ease-out infinite; pointer-events: none; }
@keyframes carrier-bloom-armed { from { transform: scale(0.92); opacity: 1; } to { transform: scale(1.3); opacity: 0; } }
.carrier-bloom-petal.is-dimmed { filter: grayscale(0.85) brightness(0.6); }
#hexMap.is-bloom-armed { cursor: crosshair; }
#hexMap .bloom-armed-preview { pointer-events: none; stroke-width: 1.6; }
#hexMap .bloom-armed-preview.is-patrol { fill: rgba(158, 240, 180, 0.14); stroke: rgba(158, 240, 180, 0.85); }
#hexMap .bloom-armed-preview.is-strike { fill: rgba(255, 86, 86, 0.16); stroke: rgba(255, 96, 96, 0.9); }
#hexMap .bloom-armed-preview.is-alert { fill: rgba(255, 196, 77, 0.16); stroke: rgba(255, 196, 77, 0.9); }
/* Second bloom: the mission choice at the clicked hex. */
.carrier-bloom-petal.is-mission { --size: 46px; border-radius: 8px; color: var(--primary); border-color: rgba(158, 240, 180, 0.7); }
.carrier-bloom-petal.is-mission img { width: 58%; height: 58%; object-fit: contain; filter: none; }
.carrier-bloom-label { position: absolute; left: 50%; top: calc(100% + 3px); transform: translateX(-50%); padding: 0 0.25rem; font: 0.62rem var(--mono); letter-spacing: 0.04em; color: var(--primary); background: rgba(8, 12, 10, 0.85); white-space: nowrap; pointer-events: none; text-transform: uppercase; }
.carrier-bloom-reason { position: absolute; z-index: 2; transform: translate(-50%, -100%); padding: 0.2rem 0.45rem; font: 0.66rem var(--mono); color: var(--text); background: rgba(8, 12, 10, 0.92); border: 1px solid var(--gasket); white-space: nowrap; pointer-events: none; }
.carrier-bloom-pin { position: absolute; left: -7px; top: -7px; width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--primary); background: rgba(158, 240, 180, 0.2); pointer-events: none; }
/* Bloom Patrol area-draw: hexes that may join the area pulse. */
#hexMap .hex-cell.hex-cell-draw-candidate { fill: rgba(158, 240, 180, 0.08); stroke: rgba(158, 240, 180, 0.7); stroke-width: 1.4; stroke-dasharray: 4 3; animation: hex-draw-candidate 1.4s ease-in-out infinite; }
@keyframes hex-draw-candidate { 50% { stroke-opacity: 0.25; } }
#hexMap .hex-cell.hex-cell-refused { fill: rgba(243, 155, 137, 0.3); stroke: rgba(243, 155, 137, 0.95); stroke-width: 1.6; animation: hex-refused 480ms ease-out; }
@keyframes hex-refused { 0% { fill: rgba(243, 155, 137, 0.55); } 100% { fill: rgba(243, 155, 137, 0); } }
.carrier-bloom.is-closed .carrier-bloom-petal { transform: translate(-50%, -50%) scale(0.25); opacity: 0; transition-delay: 0ms; }
.carrier-bloom.is-closed .carrier-bloom-plate { transform: scaleY(0.1); opacity: 0; }
.carrier-bloom.is-closed .carrier-bloom-stem { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .carrier-bloom-petal, .carrier-bloom-plate, .carrier-bloom-stem { transition: none; }
  .carrier-bloom-petal.is-armed::after, #hexMap .hex-cell.hex-cell-draw-candidate, #hexMap .hex-cell.hex-cell-refused { animation: none; }
}

/* OCT23 bloom Stage 4: the selected Sortie's "×N" tag under its marker (or a grey
   ghost formation at its destination when the marker is off the map); clicking the
   tag opens it into − ×N +. */
.sortie-craft-controls { position: absolute; inset: 0; z-index: 6; pointer-events: none; overflow: hidden; }
.sortie-craft-controls[hidden] { display: none; }
.sortie-craft-anchor { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.sortie-craft-pill { position: absolute; left: 0; top: 24px; display: flex; align-items: center; gap: 3px; transform: translateX(-50%); pointer-events: none; }
.sortie-craft-pill > button { pointer-events: auto; min-height: 0; margin: 0; box-shadow: 0 3px 10px rgba(0, 0, 0, 0.55); }
.sortie-craft-tag { padding: 0 0.35rem; height: 18px; font: 600 0.68rem var(--mono); line-height: 1; border-radius: 9px; background: rgba(8, 12, 10, 0.88); border: 1px solid rgba(var(--owner-rgb), 0.55); color: var(--text); }
.sortie-craft-pill.is-open .sortie-craft-tag { border-color: rgb(var(--owner-rgb)); }
.sortie-craft-step { width: 24px; height: 24px; padding: 0; display: grid; place-items: center; border-radius: 50%; font: 700 0.95rem var(--mono); line-height: 1; }
.sortie-craft-step:disabled { opacity: 0.35; cursor: not-allowed; }
/* Bloom petals keep their position when pressed: the global button:active nudge
   (translateY) would replace their transform and move them from under the pointer. */
.carrier-bloom-petal:active:not(:disabled) { transform: translate(calc(var(--x) - 50%), calc(var(--y) - 50% + 1px)); }
.sortie-ghost { position: absolute; left: 0; top: 0; width: 0; height: 0; }
.sortie-ghost-craft { position: absolute; width: 22px; height: 22px; transform: translate(-50%, -50%); filter: grayscale(1) brightness(1.25); opacity: 0.6; pointer-events: none; transition: left 160ms, top 160ms; }

/* Blue squadron callsign: input + Random (OCT23_SQUADRON_CALLSIGNS_PASS). */
.oob-callsign-row {
  display: flex;
  gap: 0.4rem;
}
.oob-callsign-row input {
  flex: 1;
  text-transform: uppercase;
}
.oob-callsign-warning {
  color: var(--phos-amber);
  text-transform: none;
}

.sqn-live-card .oob-slots-head .data-readout {
  white-space: nowrap;
}

/* The ADD key sits in a capped-height flex column; never let an open tray squash it. */
.munition-picker__key {
  flex-shrink: 0;
}

/* SQN tab once compiled: one section per carrier, then squadron cards. */
.sqn-live {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.sqn-carrier {
  border: 1px solid var(--border);
  background: var(--surface-lowest);
  padding: 0.75rem;
}

.sqn-carrier > .squadron-grid {
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
}

/* The Sortie Details glass, reused per squadron: four bar cells, pips over the art. */
.mission-craft-card.sqn-craft-card {
  height: 340px;
  margin-bottom: 0.6rem;
}

.sqn-craft-card .craft-card-image {
  max-width: 88%;
  max-height: 88%;
}

.sqn-callsign {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mdc-action-bar.sqn-action-bar {
  grid-template-columns: repeat(4, 1fr);
}

.sqn-air {
  font-size: 0.65rem;
  color: var(--muted);
}

.sqn-craft-card .sqn-lost {
  color: var(--lamp-red);
}

.sqn-pips {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin: 0.3rem 0;
}

.sqn-pip {
  width: 12px;
  height: 12px;
  border: 1px solid var(--lamp-green);
  background: var(--lamp-green);
}

.sqn-pip.damaged {
  border-color: var(--lamp-amber);
  background: var(--lamp-amber);
}

.sqn-pip.airborne {
  background: transparent;
}

.sqn-pip.lost {
  border-color: var(--lamp-red);
  background: transparent;
  background-image: linear-gradient(45deg, transparent 44%, var(--lamp-red) 44%, var(--lamp-red) 56%, transparent 56%);
}

.sqn-craft-card .sqn-pips {
  position: absolute;
  left: 6px;
  bottom: 6px;
  right: 6px;
  margin: 0;
}

.sqn-eqp-list {
  display: grid;
  gap: 0.35rem;
  margin: 0.4rem 0 0.2rem;
}

.sqn-eqp-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.4rem 0.5rem;
  align-items: center;
  border: 1px solid var(--outline-soft);
  border-left: 3px solid var(--secondary-hot);
  padding: 0.4rem 0.5rem;
  background: rgba(0, 0, 0, 0.18);
}

.sqn-eqp-row.open .oob-tl-info-btn {
  border-color: var(--phos-green);
  color: var(--phos-green);
}

.sqn-eqp-text {
  grid-column: 1 / -1;
  margin: 0;
  padding-top: 0.35rem;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.35;
  color: var(--stencil);
}

.sqn-lock {
  margin: 0.3rem 0;
}

.sqn-live-card.locked .munition-card-stack {
  opacity: 0.85;
}

/* OCT25 packages: co-located flights at the shown hour. */
.package-cue { color: rgb(var(--owner-rgb)); }
.package-cue.marker-red { color: var(--red); }
.package-ring {
  fill: currentColor;
  fill-opacity: 0.08;
  stroke: currentColor;
  stroke-width: 1;
  stroke-dasharray: 3 2;
  opacity: 0.9;
}
.package-badge { fill: rgba(8, 12, 18, 0.88); stroke: currentColor; stroke-width: 0.7; }
.package-badge-text {
  fill: currentColor;
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-anchor: middle;
}
.flight-marker .flight-count-label.package-count { font-size: 7px; font-weight: 700; fill: currentColor; }
.map-hex-tooltip:has(.hex-tip-package) { max-width: 340px; }
.gantt-package-tick {
  position: absolute;
  bottom: 1px;
  height: 10px;
  background: rgba(var(--owner-rgb), 0.28);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  border-bottom: 2px solid rgb(var(--owner-rgb));
  color: #fff;
  font-size: 8px;
  font-weight: 700;
  line-height: 1;
}
.gantt-package-tick::before { content: "PKG\00a0"; opacity: 0.75; }

/* OCT26 Defensive Alerts share the Sortie row and itinerary styling; the segment
   takes the defensive amber, and a standing alert's open end is dashed. */
.alert-row .gantt-phase-alert {
  color: var(--secondary);
  background:
    repeating-linear-gradient(0deg, transparent 0 2px, rgba(0, 0, 0, 0.22) 2px 3px),
    rgba(254, 179, 0, 0.22);
}
.alert-row .gantt-phase-alert.is-standing {
  border-right-style: dashed;
}
.itinerary-row:has(> .itin-standdown) { grid-template-columns: 1.4rem minmax(0, 1fr) auto auto auto; }
.itinerary-row .itin-standdown { display: flex; align-items: center; gap: 0.3rem; font-size: 0.6rem; letter-spacing: 0.04em; color: var(--stencil-dim); }
.itinerary-row:has(> .itin-standdown) .itin-kind { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.itinerary-row .itin-standdown input { width: 2.8rem; min-height: 22px; padding: 0.1rem 0.3rem; font-size: 0.68rem; }
#hudMunitionsButton.is-unavailable { opacity: 0.4; pointer-events: none; }

/* --- Bubble burst (OCT26 prototype, src/views/bubble_burst.js) ---------------
   The round anime / 16-bit explosion. Discs are circles whose stroke is as wide
   as their diameter; animating r + stroke-width swells, hollows and pops them.
   Every delay adds --bb-step (a chained sub-burst) and --bb-elapsed (negative,
   so a map layer rebuilt mid-burst resumes instead of restarting). */
.bubble-burst-float {
  position: fixed;
  z-index: 9000;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.bubble-burst-float svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.bubble-burst {
  pointer-events: none;
}

.bubble-burst circle,
.bubble-burst line,
.bubble-burst path,
.bubble-burst rect {
  fill: none;
  animation-fill-mode: both;
  --bb-at: calc(var(--bb-step, 0ms) + var(--bb-elapsed, 0ms));
}

/* Anime: flash, white-hot core, swelling disc that hollows to a ring, a thin
   shock ring racing ahead, and spark streaks. */
.bubble-burst .bb-flash {
  fill: #fff;
  animation: bb-flash 0.3s ease-out var(--bb-at) both;
}

.bubble-burst .bb-core {
  stroke: #fffbe8;
  animation: bb-core 0.76s ease-out var(--bb-at) both;
}

.bubble-burst .bb-disc {
  animation: bb-disc 0.76s cubic-bezier(0.2, 0.75, 0.35, 1) var(--bb-at) both;
}

.bubble-burst .bb-shock {
  stroke: #fff;
  animation: bb-shock 0.56s cubic-bezier(0.1, 0.7, 0.3, 1) calc(var(--bb-at) + 60ms) both;
}

.bubble-burst .bb-spark {
  stroke: #ffe6a0;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-dasharray: 14 200;
  animation: bb-spark 0.5s cubic-bezier(0.15, 0.7, 0.35, 1) calc(var(--bb-at) + 40ms) both;
}

@keyframes bb-flash {
  0% { r: 2px; opacity: 1; }
  30% { r: 30px; opacity: 1; }
  100% { r: 34px; opacity: 0; }
}

@keyframes bb-core {
  0% { r: 1px; stroke-width: 2px; opacity: 1; }
  22% { r: 10px; stroke-width: 20px; }
  45% { r: 23px; stroke-width: 6px; opacity: 1; }
  62% { r: 28px; stroke-width: 0; opacity: 0; }
  100% { r: 28px; stroke-width: 0; opacity: 0; }
}

@keyframes bb-disc {
  0% { r: 1px; stroke-width: 2px; stroke: #fff; opacity: 1; }
  18% { r: 13px; stroke-width: 26px; stroke: #fff6d0; }
  40% { r: 18px; stroke-width: 36px; stroke: #ffc451; }
  62% { r: 34px; stroke-width: 16px; stroke: #ff8a2a; }
  82% { r: 44px; stroke-width: 4px; stroke: #ff5a1f; opacity: 1; }
  100% { r: 48px; stroke-width: 0; stroke: #ff3a14; opacity: 0; }
}

@keyframes bb-shock {
  0% { r: 8px; stroke-width: 3px; opacity: 0; }
  4% { opacity: 0.95; }
  100% { r: 54px; stroke-width: 0.4px; opacity: 0; }
}

@keyframes bb-spark {
  0% { stroke-dashoffset: -12; opacity: 0; }
  6% { opacity: 1; }
  70% { opacity: 1; }
  100% { stroke-dashoffset: -92; opacity: 0; }
}

/* Impact frame: two hard frames (white-out, then a dark inverted silhouette
   with a hot rim) before the anime bubble; a second shock ring follows. */
.bubble-burst-impact .bb-impact-frame {
  animation: bb-impact-frame 0.9s step-end var(--bb-at) both;
}

.bubble-burst-impact .bb-disc,
.bubble-burst-impact .bb-core,
.bubble-burst-impact .bb-flash,
.bubble-burst-impact .bb-spark {
  animation-delay: calc(var(--bb-at) + 120ms);
}

.bubble-burst-impact .bb-shock {
  animation-delay: calc(var(--bb-at) + 120ms);
}

.bubble-burst-impact .bb-shock-late {
  animation-delay: calc(var(--bb-at) + 260ms);
}

@keyframes bb-impact-frame {
  0% { fill: #fff; stroke: #fff; stroke-width: 2px; opacity: 1; }
  7% { fill: #1a0806; stroke: #ff7a2e; stroke-width: 3px; opacity: 1; }
  14% { opacity: 0; }
  100% { opacity: 0; }
}

/* 16-bit: stepped growth, palette-cycled colours, chunky debris pixels. */
.bubble-burst-retro {
  shape-rendering: crispEdges;
}

.bubble-burst-retro .bb-retro-disc {
  animation: bb-retro-disc 0.82s step-end var(--bb-at) both;
}

.bubble-burst-retro .bb-retro-core {
  stroke: #fff;
  animation: bb-retro-core 0.82s step-end var(--bb-at) both;
}

.bubble-burst-retro .bb-retro-bit {
  fill: #ffd23c;
  animation: bb-retro-bit 0.56s steps(5, end) calc(var(--bb-at) + 200ms) both;
}

.bubble-burst-retro .bb-retro-bit.is-late {
  animation-delay: calc(var(--bb-at) + 300ms);
}

@keyframes bb-retro-disc {
  0% { r: 4px; stroke-width: 8px; stroke: #fff; opacity: 1; }
  12% { r: 9px; stroke-width: 18px; stroke: #fff8a0; }
  24% { r: 14px; stroke-width: 28px; stroke: #ffd23c; }
  36% { r: 18px; stroke-width: 36px; stroke: #ff9a1e; }
  50% { r: 30px; stroke-width: 20px; stroke: #ff5a14; }
  64% { r: 38px; stroke-width: 12px; stroke: #d8301c; }
  78% { r: 44px; stroke-width: 6px; stroke: #8a1c18; }
  90% { r: 47px; stroke-width: 2px; stroke: #5a1414; opacity: 1; }
  100% { opacity: 0; }
}

@keyframes bb-retro-core {
  0% { r: 2px; stroke-width: 4px; opacity: 1; }
  12% { r: 5px; stroke-width: 10px; }
  24% { r: 8px; stroke-width: 16px; }
  36% { r: 14px; stroke-width: 10px; stroke: #fff8a0; }
  50% { r: 20px; stroke-width: 4px; opacity: 1; }
  60% { opacity: 0; }
  100% { opacity: 0; }
}

@keyframes bb-retro-bit {
  0% { transform: translate(calc(var(--dx) * 0.4), calc(var(--dy) * 0.4)); fill: #fff8a0; opacity: 0; }
  1% { opacity: 1; }
  60% { fill: #ff5a14; opacity: 1; }
  100% { transform: translate(calc(var(--dx) * 1.45), calc(var(--dy) * 1.45)); fill: #8a1c18; opacity: 0; }
}

/* Phosphor: the NATOware HUD take, green vector rings on the glass, no fire. */
.bubble-burst-phosphor {
  filter: drop-shadow(0 0 3px rgba(70, 232, 140, 0.85));
}

.bubble-burst-phosphor .bb-ph-fill {
  fill: rgba(70, 232, 140, 0.4);
  animation: bb-ph-fill 0.5s ease-out var(--bb-at) both;
}

.bubble-burst-phosphor .bb-ph-ring {
  stroke: var(--phos-green-hot, #46e88c);
  animation: bb-ph-ring 0.72s cubic-bezier(0.1, 0.7, 0.3, 1) var(--bb-at) both;
}

.bubble-burst-phosphor .bb-ph-ring.is-late {
  animation-delay: calc(var(--bb-at) + 180ms);
}

.bubble-burst-phosphor .bb-ph-tick {
  stroke: var(--phos-green, #9ef0b4);
  stroke-width: 2.4;
  animation: bb-ph-tick 0.9s step-end var(--bb-at) both;
}

.bubble-burst-phosphor .bb-ph-dot {
  fill: #fff;
  animation: bb-ph-dot 0.6s ease-out var(--bb-at) both;
}

@keyframes bb-ph-fill {
  0% { r: 2px; opacity: 1; }
  100% { r: 40px; opacity: 0; }
}

@keyframes bb-ph-ring {
  0% { r: 2px; stroke-width: 6px; opacity: 1; }
  100% { r: 50px; stroke-width: 0.6px; opacity: 0; }
}

@keyframes bb-ph-tick {
  0% { opacity: 0; }
  10% { opacity: 1; }
  20% { opacity: 0.2; }
  30% { opacity: 1; }
  70% { opacity: 0; }
  100% { opacity: 0; }
}

@keyframes bb-ph-dot {
  0% { r: 6px; fill: #fff; opacity: 1; }
  100% { r: 2px; fill: #46e88c; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .bubble-burst,
  .bubble-burst-float {
    display: none;
  }
}

.bubble-burst-float.is-local {
  position: absolute;
  z-index: 2;
}

/* Strike dialog target art (OCT26 bubble burst prototype): impacts pop on it. */
.strike-target-art {
  position: relative;
  width: 132px;
  height: 132px;
  margin: 0.2rem auto 0.6rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 140, 60, 0.08), transparent 68%);
  flex: none;
}

.strike-target-art img,
.strike-target-art > svg {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
}

.strike-target-art-hex {
  fill: rgba(158, 240, 180, 0.05);
  stroke: rgba(158, 240, 180, 0.35);
  stroke-width: 1.2;
}

.strike-target-art-complex {
  fill: rgba(216, 226, 217, 0.55);
}

/* Marlin refuels: a fuel tick over the service hour on the tanker's (RF›) and
   the recipient's (›RF) Gantt rows, and a fuel line between the two markers on
   the OPS map at that hour. Cyan while planned (amber when the planned positions
   sit outside boom range); green done, red failed. */
.gantt-refuel-tick {
  --refuel-rgb: 79, 209, 255;
  position: absolute;
  top: -7px;
  height: 13px;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  border: 1px dashed rgb(var(--refuel-rgb));
  border-radius: 6px;
  background: rgba(8, 12, 18, 0.9);
  color: rgb(var(--refuel-rgb));
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.04em;
  box-shadow: 0 0 6px rgba(var(--refuel-rgb), 0.45);
}
.gantt-refuel-tick.is-complete { --refuel-rgb: 122, 230, 140; border-style: solid; }
.gantt-refuel-tick.is-failed { --refuel-rgb: 255, 99, 99; border-style: solid; text-decoration: line-through; }
.refuel-link { --refuel-rgb: 79, 209, 255; color: rgb(var(--refuel-rgb)); pointer-events: none; }
.refuel-link.is-complete { --refuel-rgb: 122, 230, 140; }
.refuel-link.is-failed { --refuel-rgb: 255, 99, 99; }
.gantt-refuel-tick.is-planned.is-out-of-range,
.refuel-link.is-planned.is-out-of-range { --refuel-rgb: 254, 179, 0; }
.refuel-link-line {
  stroke: currentColor;
  stroke-width: 2;
  stroke-dasharray: 5 3;
  fill: none;
  opacity: 0.9;
}
.refuel-link.is-complete .refuel-link-line { stroke-dasharray: none; }
.refuel-link-badge { fill: rgba(8, 12, 18, 0.9); stroke: currentColor; stroke-width: 0.8; }
.refuel-link-text {
  fill: currentColor;
  font-size: 7px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-anchor: middle;
}
