/* ─────────────────────────────────────────────────────────────────────────────
   ACCOMPANIED™ HYDRA v6 — Cinematic Operator Interface (Path B)
   Doctrine: the PNG IS the interface. HTML reacts, never decorates.
   - Plate at NATIVE aspect ratio (1672:941). Letterbox if needed. Never cropped.
   - Zero overlays competing with art's existing title / legend / labels.
   - All operator controls in ONE slide-out drawer triggered by a single tab.
   - Status overlays use mix-blend-mode so reactions live INSIDE the scene.
   ───────────────────────────────────────────────────────────────────────────── */

:root {
  --black: #000;
  --plate-frame: rgba(0, 0, 0, 0.92);

  /* Art-matched accents — sampled from the PNG's actual palette */
  --gold:   #f2c75e;
  --gold-2: #d49b35;
  --violet: #b794f6;
  --cyan:   #6ee9ff;
  --red:    #ff334f;
  --green:  #65ff9c;

  --text:  #f3eddc;
  --muted: #97a8c2;

  --font: "JetBrains Mono", "SF Mono", ui-monospace, Menlo, Consolas, monospace;
  --display: "Cormorant Garamond", "Times New Roman", serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  width: 100%;
  height: 100%;
  background: var(--black);
  color: var(--text);
  font-family: var(--font);
  overflow: hidden;
}

a { color: inherit; text-decoration: none; }

/* ───────── PLATE — native aspect, letterboxed ───────── */
.stage {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--black);
}

.plate {
  position: relative;
  width: min(100vw, calc(100vh * 1672 / 941));
  aspect-ratio: 1672 / 941;
  background-color: var(--black);
  overflow: hidden;
  /* The native art geometry — everything overlays in % of this box */
}

.plate-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  user-select: none;
  pointer-events: none;
  z-index: 1;
}

/* ───────── LAYERED PLATE — Path C compositing ─────────
   Three transparent PNG layers sliced by scripts/plate-layer-slicer.py:
     .plate-bg  z:1  chamber/environment, opaque base
     .plate-mg  z:7  glow lines, connection arcs — additive (screen blend)
     .plate-fg  z:9  worker stations, core, hot highlights — additive (screen)
   Operator HTML (hotspots, daemon chip, drawer trigger) lives at z:4-6, so it
   appears between the chamber and the glow — IN the depth of the scene.   */
.plate-bg,
.plate-mg,
.plate-fg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  user-select: none;
  pointer-events: none;
}
.plate-bg { z-index: 1; }
.plate-mg { z-index: 7; mix-blend-mode: screen; }
.plate-fg { z-index: 9; mix-blend-mode: screen; }

/* ───────── HOTSPOT — invisible click target over a seat ───────── */
.hotspot {
  position: absolute;
  z-index: 4;
  cursor: pointer;
  border-radius: 50%;
  background: transparent;
  transition: background .25s ease, box-shadow .25s ease;
}
.hotspot:hover, .hotspot:focus {
  background: radial-gradient(circle, rgba(242,199,94,0.22) 0%, transparent 70%);
  box-shadow: 0 0 0 1px rgba(242,199,94,0.4) inset;
  outline: none;
}
.hotspot::after {
  /* Tiny label that appears on hover, BELOW the hotspot so it never covers seat art */
  content: attr(data-label);
  position: absolute;
  bottom: -22px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font: 9px/1 var(--font);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  text-shadow: 0 0 8px rgba(0,0,0,0.95), 0 0 4px rgba(0,0,0,0.95);
  opacity: 0;
  transition: opacity .15s ease;
  pointer-events: none;
}
.hotspot:hover::after, .hotspot:focus::after { opacity: 1; }

/* ───────── SVG RING OVERLAY — real seat nodes + connection lines + core ─── */
.ring-overlay {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 5;                /* above hotspots (4), below mg glow (7) */
  pointer-events: none;       /* seat groups re-enable below */
  overflow: visible;
}

/* ── HYDRA Command Core ──
   Animations use `r` and `stroke-dashoffset` (no `transform`) so they compose
   cleanly with the parent `<g transform="translate(836 470)">` attribute. */
.hydra-core .core-glow {
  fill: url(#coreGradient);
  opacity: 0.85;
  animation: core-breathe 4.5s ease-in-out infinite;
}
.hydra-core .core-ring-outer {
  fill: none;
  stroke: rgba(242, 199, 94, 0.55);
  stroke-width: 1.5;
  stroke-dasharray: 14 18;
  animation: core-ring-rotate 32s linear infinite;
}
.hydra-core .core-ring-inner {
  fill: none;
  stroke: rgba(110, 233, 255, 0.45);
  stroke-width: 1;
  stroke-dasharray: 6 10;
  animation: core-ring-rotate-rev 24s linear infinite;
}
.hydra-core.alert .core-glow { fill: url(#coreGradientAlert); animation-duration: 1.2s; }

@keyframes core-breathe {
  0%, 100% { r: 70; opacity: 0.55; }
  50%      { r: 96; opacity: 0.95; }
}
@keyframes core-ring-rotate {
  to { stroke-dashoffset: -160; }
}
@keyframes core-ring-rotate-rev {
  to { stroke-dashoffset: 160; }
}

/* ── Connection lines — core to each seat ── */
.conn-line {
  fill: none;
  stroke: rgba(242, 199, 94, 0.0);     /* hidden until activated */
  stroke-width: 2.2;
  stroke-dasharray: 10 14;
  stroke-linecap: round;
  filter: drop-shadow(0 0 4px currentColor);
  transition: stroke .35s ease, opacity .35s ease;
}
.conn-line.active {
  stroke: rgba(242, 199, 94, 0.85);
  color: rgba(242, 199, 94, 0.85);
  animation: packet-flow 1.4s linear infinite;
}
.conn-line.active.status-retrying {
  stroke: rgba(183, 148, 246, 0.85);
  color: rgba(183, 148, 246, 0.85);
}
.conn-line.active.status-failed {
  stroke: rgba(255, 51, 79, 0.85);
  color: rgba(255, 51, 79, 0.85);
}
.conn-line.active.status-completed {
  stroke: rgba(101, 255, 156, 0.7);
  color: rgba(101, 255, 156, 0.7);
  animation: none;
}

@keyframes packet-flow {
  to { stroke-dashoffset: -48; }
}

/* ── Seat nodes ──
   IMPORTANT: do NOT apply CSS `transform` to .seat-node. The element already
   has a `transform="translate(x y)"` attribute and CSS transform overrides it,
   snapping the node to (0,0) and creating a hover-flicker loop.
   Hover feedback lives in stroke/opacity changes ONLY.
*/
.seat-node {
  pointer-events: auto;
  cursor: pointer;
}
.seat-node:hover .seat-ring-outer,
.seat-node:focus .seat-ring-outer {
  stroke: var(--gold);
  stroke-opacity: 1;
  stroke-width: 2.4;
}
.seat-node:hover .seat-ring-inner,
.seat-node:focus .seat-ring-inner {
  stroke-width: 3.4;
}
.seat-node:hover .seat-label-bg,
.seat-node:focus .seat-label-bg { opacity: 1; }
.seat-node:hover .seat-label,
.seat-node:focus .seat-label    { opacity: 1; }

.seat-ring-outer {
  fill: none;
  stroke: rgba(242, 199, 94, 0.0);     /* invisible by default — the PNG art shows the seat already */
  stroke-width: 1.4;
  transition: stroke .25s ease, stroke-width .25s ease;
}
.seat-ring-inner {
  fill: none;
  stroke: transparent;
  stroke-width: 2.4;
  filter: drop-shadow(0 0 6px currentColor);
  transition: stroke .3s ease;
}
.seat-pulse {
  fill: transparent;
  opacity: 0;
  transition: opacity .3s ease;
  /* No transform-origin/transform-box: animations now use `r`, not `transform`. */
}
.seat-label-bg, .seat-label {
  pointer-events: none;
  opacity: 0;
  transition: opacity .15s ease;
}
.seat-label-bg {
  fill: rgba(0, 0, 0, 0.92);
  stroke: rgba(242, 199, 94, 0.55);
  stroke-width: 0.5;
}
.seat-label {
  fill: var(--gold);
  font: 600 11px/1 var(--font);
  letter-spacing: 2px;
  text-transform: uppercase;
  text-anchor: middle;
  dominant-baseline: middle;
}

/* ── Live status states (set via JS on the .seat-node).
   `color` matches stroke so `drop-shadow(currentColor)` glows in the same hue. ── */
.seat-node.status-dispatched {
  color: rgba(110, 233, 255, 0.85);
}
.seat-node.status-dispatched .seat-ring-inner {
  stroke: rgba(110, 233, 255, 0.85);
  stroke-dasharray: 4 5;
  animation: seat-rotate 5s linear infinite;
}
.seat-node.status-dispatched .seat-pulse {
  opacity: 0.5;
  fill: rgba(110, 233, 255, 0.35);
  animation: seat-pulse 2.4s ease-in-out infinite;
}
.seat-node.status-running {
  color: rgba(242, 199, 94, 1);
}
.seat-node.status-running .seat-ring-inner {
  stroke: rgba(242, 199, 94, 1);
}
.seat-node.status-running .seat-pulse {
  opacity: 0.75;
  fill: rgba(242, 199, 94, 0.55);
  animation: seat-pulse 1.4s ease-in-out infinite;
}
.seat-node.status-retrying {
  color: rgba(183, 148, 246, 0.95);
}
.seat-node.status-retrying .seat-ring-inner {
  stroke: rgba(183, 148, 246, 0.95);
  stroke-dasharray: 3 3;
  animation: seat-rotate 1.6s linear infinite;
}
.seat-node.status-retrying .seat-pulse {
  opacity: 0.65;
  fill: rgba(183, 148, 246, 0.45);
  animation: seat-pulse 0.9s ease-in-out infinite;
}
.seat-node.status-completed {
  color: rgba(101, 255, 156, 0.95);
}
.seat-node.status-completed .seat-ring-inner {
  stroke: rgba(101, 255, 156, 0.95);
}
.seat-node.status-completed .seat-pulse {
  opacity: 0.5;
  fill: rgba(101, 255, 156, 0.35);
}
.seat-node.status-failed {
  color: rgba(255, 51, 79, 1);
}
.seat-node.status-failed .seat-ring-inner {
  stroke: rgba(255, 51, 79, 1);
  stroke-dasharray: 2 3;
  animation: seat-jitter 0.5s ease-in-out infinite;
}
.seat-node.status-failed .seat-pulse {
  opacity: 0.7;
  fill: rgba(255, 51, 79, 0.55);
  animation: seat-pulse 0.6s ease-in-out infinite;
}

/* Pulse via radius animation — avoids the transform attribute/CSS conflict
   that SVG <g transform="translate(x y)"> elements have with CSS transform.  */
@keyframes seat-pulse {
  0%, 100% { r: 28; opacity: 0.35; }
  50%      { r: 50; opacity: 0.85; }
}
/* Dashed-ring "rotation" via stroke-dashoffset — looks like the dashes are
   travelling around the circumference. No transform conflict. */
@keyframes seat-rotate {
  to { stroke-dashoffset: -120; }
}
/* Failed-state jitter via stroke-opacity flicker (no transforms). */
@keyframes seat-jitter {
  0%, 100% { stroke-opacity: 1.0; }
  25%      { stroke-opacity: 0.55; }
  50%      { stroke-opacity: 1.0; }
  75%      { stroke-opacity: 0.45; }
}

/* ───────── (legacy) REACTION via mix-blend-mode — kept for non-overlay pages ─── */
.seat-react {
  position: absolute;
  z-index: 3;             /* between art (1) and hotspot (4) */
  width: 6%;
  height: 11%;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity .25s ease;
}
.seat-react.status-running {
  opacity: 1;
  background: radial-gradient(circle, rgba(242,199,94,0.55) 0%, rgba(242,199,94,0) 65%);
  animation: react-pulse 1.6s ease-in-out infinite;
}
.seat-react.status-retrying {
  opacity: 1;
  background: radial-gradient(circle, rgba(183,148,246,0.55) 0%, rgba(183,148,246,0) 65%);
  animation: react-pulse 1.0s ease-in-out infinite;
}
.seat-react.status-completed {
  opacity: 1;
  background: radial-gradient(circle, rgba(101,255,156,0.45) 0%, rgba(101,255,156,0) 65%);
}
.seat-react.status-failed {
  opacity: 1;
  background: radial-gradient(circle, rgba(255,51,79,0.6) 0%, rgba(255,51,79,0) 65%);
  animation: react-fail 0.8s ease-in-out infinite;
}
.seat-react.status-dispatched {
  opacity: 1;
  background: radial-gradient(circle, rgba(110,233,255,0.45) 0%, rgba(110,233,255,0) 65%);
  animation: react-pulse 2.0s ease-in-out infinite;
}
@keyframes react-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(0.85); }
  50%      { transform: translate(-50%, -50%) scale(1.15); }
}
@keyframes react-fail {
  0%, 100% { transform: translate(-50%, -50%) scale(1.0); }
  50%      { transform: translate(-50%, -50%) scale(1.3); }
}

/* ───────── DAEMON CHIP — tiny, top-right of plate, doesn't fight title ─── */
.daemon-chip {
  position: absolute;
  top: 1.3%;
  right: 1.3%;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  background: rgba(0,0,0,0.78);
  border: 1px solid rgba(110,233,255,0.4);
  border-radius: 3px;
  font: 9px/1 var(--font);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--cyan);
  pointer-events: none;
}
.daemon-chip .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 6px var(--green);
}
.daemon-chip.alert { color: var(--red); border-color: rgba(255,51,79,0.45); }
.daemon-chip.alert .dot { background: var(--red); box-shadow: 0 0 6px var(--red); }

/* ───────── DRAWER TAB — single discrete trigger on right edge ───────── */
.drawer-tab {
  position: absolute;
  top: 50%;
  right: 0;
  z-index: 8;
  transform: translateY(-50%);
  appearance: none;
  background: rgba(0,0,0,0.85);
  border: 1px solid rgba(242,199,94,0.55);
  border-right: none;
  color: var(--gold);
  padding: 18px 8px;
  font: 10px/1 var(--font);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
  cursor: pointer;
  transition: background .15s ease;
}
.drawer-tab:hover { background: rgba(242,199,94,0.18); }

/* ───────── DRAWER — slides in from right, art-styled ───────── */
.drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 36%;
  max-width: 480px;
  min-width: 320px;
  z-index: 9;
  transform: translateX(100%);
  transition: transform .32s cubic-bezier(.4, 0, .2, 1);
  background:
    linear-gradient(180deg, rgba(8,5,2,0.97) 0%, rgba(3,2,1,0.97) 100%);
  border-left: 1px solid rgba(242,199,94,0.45);
  box-shadow: -18px 0 60px rgba(0,0,0,0.7);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.drawer.open { transform: translateX(0); }
.drawer header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid rgba(242,199,94,0.25);
}
.drawer header h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 18px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
  font-weight: 600;
}
.drawer header button {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(242,199,94,0.4);
  color: var(--gold);
  padding: 4px 10px;
  font: 9px/1 var(--font);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  cursor: pointer;
}
.drawer header button:hover { background: rgba(242,199,94,0.15); }
.drawer .body {
  flex: 1;
  overflow-y: auto;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.drawer section {
  border: 1px solid rgba(242,199,94,0.22);
  background: rgba(0,0,0,0.4);
  padding: 14px;
}
.drawer section h3 {
  margin: 0 0 10px;
  color: var(--gold);
  font: 10px/1 var(--font);
  letter-spacing: 0.28em;
  text-transform: uppercase;
}
.drawer section p {
  margin: 0 0 8px;
  color: var(--muted);
  font: 10px/1.5 var(--font);
}

.drawer label.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.drawer label.field span.lbl {
  color: var(--muted);
  font: 9px/1 var(--font);
  letter-spacing: 0.24em;
  text-transform: uppercase;
}
.drawer input,
.drawer select,
.drawer textarea {
  background: rgba(0,0,0,0.6);
  border: 1px solid rgba(242,199,94,0.25);
  color: var(--text);
  padding: 8px 10px;
  font: 11px/1.4 var(--font);
  outline: none;
  transition: border-color .15s ease;
}
.drawer input:focus,
.drawer select:focus,
.drawer textarea:focus { border-color: var(--gold); }
.drawer textarea { min-height: 70px; resize: vertical; }

.drawer .btn {
  appearance: none;
  cursor: pointer;
  background: linear-gradient(180deg, #ffe08a, #b77b16);
  color: #0b0700;
  border: 1px solid rgba(242,199,94,0.5);
  padding: 9px 16px;
  font: 10px/1 var(--font);
  font-weight: 700;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  transition: filter .12s ease;
}
.drawer .btn:hover { filter: brightness(1.1); }
.drawer .btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.drawer .btn.ghost {
  background: transparent;
  color: var(--gold);
}
.drawer .btn.ghost:hover { background: rgba(242,199,94,0.12); }
.drawer .btn.danger {
  background: linear-gradient(180deg, #ff6c80, #b81b30);
  color: #1a0006;
  border-color: rgba(255,51,79,0.5);
}

.drawer .feedback {
  margin-top: 6px;
  padding: 7px 10px;
  font: 10px/1.4 var(--font);
  letter-spacing: 0.08em;
  display: none;
}
.drawer .feedback.ok   { display: block; color: var(--green); border: 1px solid rgba(101,255,156,0.4); background: rgba(101,255,156,0.06); }
.drawer .feedback.err  { display: block; color: var(--red);   border: 1px solid rgba(255,51,79,0.4);  background: rgba(255,51,79,0.06); }
.drawer .feedback.info { display: block; color: var(--cyan);  border: 1px solid rgba(110,233,255,0.3); background: rgba(110,233,255,0.05); }

.kv-grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px 12px;
  font: 10px/1.2 var(--font);
}
.kv-grid span:nth-child(odd)  { color: var(--muted); text-transform: uppercase; letter-spacing: 0.18em; }
.kv-grid span:nth-child(even) { color: var(--gold); text-align: right; }

.seat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.seat-list li {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 5px 8px;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(242,199,94,0.1);
  font: 10px/1.2 var(--font);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  cursor: pointer;
}
.seat-list li:hover { border-color: rgba(242,199,94,0.4); }
.seat-list li .swatch {
  width: 8px; height: 8px; border-radius: 50%; background: var(--muted);
}
.seat-list li .swatch.running   { background: var(--gold); box-shadow: 0 0 6px var(--gold); }
.seat-list li .swatch.retrying  { background: var(--violet); box-shadow: 0 0 6px var(--violet); }
.seat-list li .swatch.completed { background: var(--green);  box-shadow: 0 0 6px var(--green); }
.seat-list li .swatch.failed    { background: var(--red);    box-shadow: 0 0 6px var(--red); }
.seat-list li code {
  color: var(--gold-2);
  font-size: 9px;
}

/* ───────── NAV DOCK — minimal, bottom-center, off the art ─────────────── */
.nav-dock {
  position: fixed;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  gap: 2px;
  padding: 4px;
  background: rgba(0,0,0,0.78);
  border: 1px solid rgba(242,199,94,0.3);
  backdrop-filter: blur(8px);
}
.nav-dock a {
  color: var(--muted);
  padding: 5px 11px;
  font: 9px/1 var(--font);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  border: 1px solid transparent;
  transition: all .15s ease;
}
.nav-dock a:hover, .nav-dock a.active {
  color: var(--gold);
  border-color: rgba(242,199,94,0.4);
  background: rgba(242,199,94,0.08);
}

/* ───────── MODAL — for raw job JSON, used by mission-board ─────────────── */
.modal-back {
  position: fixed; inset: 0;
  z-index: 200;
  display: none;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.84);
  backdrop-filter: blur(6px);
}
.modal-back.open { display: flex; }
.modal {
  width: min(820px, 92vw);
  max-height: 86vh;
  background: rgba(8,5,2,0.97);
  border: 1px solid rgba(242,199,94,0.5);
  display: flex;
  flex-direction: column;
}
.modal header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid rgba(242,199,94,0.25);
}
.modal header h3 {
  margin: 0;
  color: var(--gold);
  font: 13px/1 var(--font);
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.modal header button {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(242,199,94,0.4);
  color: var(--gold);
  padding: 4px 10px;
  font: 9px/1 var(--font);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  cursor: pointer;
}
.modal pre {
  margin: 0;
  padding: 18px 22px;
  overflow: auto;
  flex: 1;
  font: 11px/1.55 var(--font);
  color: var(--text);
  background: rgba(0,0,0,0.4);
}
.modal pre .k { color: var(--gold); }
.modal pre .s { color: var(--cyan); }
.modal pre .n { color: var(--violet); }

/* ───────── TABLE used in mission-board / result-viewer drawer ─────────── */
.mission-table {
  width: 100%;
  border-collapse: collapse;
  font: 10px/1.4 var(--font);
}
.mission-table th, .mission-table td {
  padding: 7px 10px;
  text-align: left;
  border-bottom: 1px solid rgba(242,199,94,0.08);
}
.mission-table th {
  color: var(--muted);
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.mission-table td.jid { color: var(--gold); cursor: pointer; }
.mission-table td.completed { color: var(--green); }
.mission-table td.failed    { color: var(--red); }
.mission-table td.blocked   { color: var(--gold-2); }
.mission-table tr:hover td { background: rgba(242,199,94,0.05); }
