/*
 * 80s/90s war-room — docs/architecture §6.1.
 * Black ground, thin white vector outlines, monospace type, a NORAD command
 * centre that happens to be rendering a corporate war.
 */

:root {
  --ink: #e8f2ec;
  --dim: #7c9188;
  --faint: #37453f;
  --bg: #050706;
  --panel: #080c0a;
  --line: #1e2a25;
  --accent: #6dffb0;
  --alert: #ff5a4a;
  --gridline: rgba(109, 255, 176, 0.045);
  --grid: 11px;
}

/* Every token above is re-hued to the acting player's colour each turn — see
   applyTheme() in app.js. The tone (saturation and lightness) is fixed; only
   the hue moves, so the room always reads the same, just in their colour. */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font: 12px/1.5 ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: 0.04em;
  overflow: hidden;
}

/* Column layout rather than a height calc, so the top bar can be any height. */
body { display: flex; flex-direction: column; }

/* CRT scanlines and a faint phosphor vignette. */
#scanlines {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 100;
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,0.28) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse at center, transparent 55%, rgba(0,0,0,0.55) 100%);
  mix-blend-mode: multiply;
}

button, select, input { font: inherit; color: inherit; letter-spacing: inherit; }

/* ── top bar ─────────────────────────────────────────────────────────────── */

#topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}

.brand { display: flex; align-items: baseline; gap: 10px; }
.brand .glyph { color: var(--accent); font-size: 16px; }
.brand .title { font-size: 15px; font-weight: 700; letter-spacing: 0.24em; }
.brand .sub { color: var(--dim); letter-spacing: 0.3em; font-size: 10px; }

.controls { display: flex; align-items: center; gap: 18px; }
.field { display: flex; flex-direction: column; gap: 3px; }
.field span { font-size: 9px; color: var(--dim); letter-spacing: 0.22em; }
.field select {
  background: #000;
  border: 1px solid var(--line);
  padding: 4px 8px;
  min-width: 190px;
  border-radius: 0;
  appearance: none;
}
.field select:focus { outline: 1px solid var(--accent); }

.clock { text-align: right; border-left: 1px solid var(--line); padding-left: 18px; }
#turn-readout { display: block; font-size: 17px; letter-spacing: 0.18em; }
#actor-readout { display: block; font-size: 10px; color: var(--dim); }

/* ── layout ──────────────────────────────────────────────────────────────── */

#layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 420px;
  flex: 1;
  min-height: 0;
}

/* min-height:0 is what stops the map from pushing the scrubber off-screen. */
#board { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

/* ── phase rail ──────────────────────────────────────────────────────────── */

/* The nine phases of a turn, lit one at a time as the broadcast walks through
   them. In scrub mode it is a legend; in broadcast mode it is the clock. */
#phase-rail {
  display: flex;
  gap: 1px;
  padding: 0 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}
#phase-rail .phase {
  flex: 1;
  min-width: 0;
  padding: 5px 6px;
  font-size: 8px;
  letter-spacing: 0.16em;
  text-align: center;
  color: var(--faint);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 160ms linear, border-color 160ms linear;
}
/* A phase that produced something this turn — worth looking at. */
#phase-rail .phase.live { color: var(--dim); border-bottom-color: var(--line); }
#phase-rail .phase.active {
  color: #000;
  background: var(--accent);
  border-bottom-color: var(--accent);
}
#phase-rail .phase.done { color: var(--dim); }

/* ── narration caption ───────────────────────────────────────────────────── */

#narration-caption {
  position: absolute;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  max-width: min(760px, 76%);
  padding: 12px 20px;
  background: rgba(0, 0, 0, 0.82);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  text-align: center;
  pointer-events: none;
  animation: caption-in 220ms ease-out;
}
#narration-caption[hidden] { display: none; }
@keyframes caption-in {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to { opacity: 1; transform: translateX(-50%); }
}
#caption-speaker {
  display: block;
  font-size: 9px;
  letter-spacing: 0.26em;
  color: var(--accent);
  margin-bottom: 5px;
}
#caption-text {
  display: block;
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink);
  text-shadow: 0 0 18px rgba(0, 0, 0, 0.9);
}

#btn-broadcast, #btn-record { letter-spacing: 0.14em; font-size: 10px; }
#btn-broadcast.on { background: var(--accent); color: #000; border-color: var(--accent); }
#btn-record.on { background: var(--alert); color: #000; border-color: var(--alert); }
#btn-record[hidden] { display: none; }

/* Broadcast is a performance — the chrome gets out of the way. */
body.broadcasting #tabs,
body.broadcasting #panel-body { opacity: 0.45; transition: opacity 300ms linear; }
body.broadcasting #scrubber { opacity: 0.5; }

#map-wrap {
  /* The narration caption anchors to this box, not the viewport. */
  position: relative;
  flex: 1;
  min-height: 0;
  padding: 12px;
  background-image:
    linear-gradient(var(--gridline) 1px, transparent 1px),
    linear-gradient(90deg, var(--gridline) 1px, transparent 1px);
  background-size: var(--grid) var(--grid);
}

/* ── the acting player's emblem ──────────────────────────────────────────── */

/* Sits at the foot of the panel column, off the board — a dossier plate for
   whoever currently has the turn. */
#avatar-card {
  margin: 0;
  flex-shrink: 0;
  padding: 16px;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.5));
  display: grid;
  grid-template-columns: 184px minmax(0, 1fr);
  gap: 16px;
  align-items: center;
  /* Re-announces itself each time the turn passes to a new player. */
  animation: avatar-in 420ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes avatar-in {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to { opacity: 1; transform: none; }
}

#avatar-art {
  width: 184px;
  height: 184px;
  border: 1px solid var(--line);
  background: #000;
  box-shadow: 0 0 30px -8px var(--accent), inset 0 0 46px -20px var(--accent);
  display: grid;
  place-items: center;
}
#avatar-art svg { width: 100%; height: 100%; display: block; }

#avatar-card figcaption { min-width: 0; }
#avatar-org {
  font-size: 17px;
  letter-spacing: 0.1em;
  color: var(--ink);
  line-height: 1.3;
  text-shadow: 0 0 14px var(--accent);
  overflow-wrap: anywhere;
}
#avatar-model {
  font-size: 9px;
  letter-spacing: 0.18em;
  color: var(--dim);
  margin-top: 3px;
}
#avatar-concept {
  font-size: 10px;
  color: var(--faint);
  margin-top: 10px;
  line-height: 1.6;
  font-style: italic;
  /* The agent writes this line itself, so cap it rather than let it push the
     plate taller on a long one. */
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
#avatar-card.hidden { display: none; }

#map { width: 100%; height: 100%; display: block; }

/* Unowned terrain stays dark but has to be readable — which tiles are worth
   taking is the first thing a viewer wants off the board. */
.hex { stroke: #24322c; stroke-width: 0.6; transition: fill 120ms linear; }
.hex.water { fill: #061019; stroke: #12222e; }
/* Terrain has to survive a translucent team wash on top of it, which compresses
   whatever separation these colours have. Held apart by hue as well as value so
   the resource under a territory stays legible in anyone's colour. */
.hex.arid { fill: #3b342a; stroke: #554c3e; }
.hex.fertile { fill: #123d20; stroke: #2c5138; }
.hex.mineral { fill: #573914; stroke: #7a5220; }
.hex.owned { stroke: rgba(0,0,0,0.35); }
/* The edge and the glyph are what mark a hub. */
.hex.hub { stroke: rgba(255,255,255,0.85); stroke-width: 1.2; }
.hex.focus { stroke: var(--accent); stroke-width: 1.6; }
.hex:hover { stroke: #ffffff; stroke-width: 1.4; cursor: crosshair; }

/* Ownership: a translucent team-coloured wash. `fill: none` is the default that
   matters — an SVG polygon with no fill set paints solid black, which would
   blank the terrain on every unowned tile. */
.hex-tint { fill: none; fill-opacity: 0.42; stroke: none; pointer-events: none; }

/* Only the outermost edges of a territory are drawn, so each empire reads as a
   single shape rather than a cluster of hexes. Struck at double width on the
   tile boundary and clipped to the owner's ground, so the visible line is half
   this — 1.2 — and lies just inside the border. Round caps overrun each corner
   far enough to close the turn; the overrun outside the territory is clipped. */
.border-edge {
  stroke-width: 2.4;
  stroke-linecap: round;
  fill: none;
  pointer-events: none;
}

.hub-glyph { fill: none; stroke: #ffffff; stroke-width: 1.05; pointer-events: none; }
.hub-glyph.filled { fill: #ffffff; stroke: none; }
.garrison { fill: var(--ink); font-size: 6px; text-anchor: middle; pointer-events: none; opacity: 0.85; }
.flash { animation: flash 900ms ease-out; }
@keyframes flash {
  0% { stroke: var(--alert); stroke-width: 3; }
  100% { stroke: rgba(0,0,0,0.55); stroke-width: 0.6; }
}

/* ── scrubber ────────────────────────────────────────────────────────────── */

#scrubber {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-top: 1px solid var(--line);
  background: var(--panel);
}
#scrubber button {
  background: #000;
  border: 1px solid var(--line);
  padding: 3px 9px;
  cursor: pointer;
}
#scrubber button:hover { border-color: var(--accent); color: var(--accent); }
#turn-range { flex: 1; accent-color: var(--accent); background: transparent; }
#scrub-label { color: var(--dim); min-width: 76px; text-align: right; }

#ticker {
  height: 26px;
  border-top: 1px solid var(--line);
  background: #000;
  overflow: hidden;
  position: relative;
}
#ticker-rail {
  display: flex;
  gap: 40px;
  align-items: center;
  height: 100%;
  padding-left: 14px;
  white-space: nowrap;
  color: var(--dim);
}
#ticker-rail .hit { color: var(--alert); }
#ticker-rail .win { color: var(--accent); }

/* ── side panel ──────────────────────────────────────────────────────────── */

#panel {
  border-left: 1px solid var(--line);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* The avatar plate's entrance animation is paint-only, but a transform still
     counts toward scrollable overflow — and a backgrounded tab pauses it at
     frame 0, leaving it permanently displaced. Clip it here instead. */
  overflow: hidden;
}

#tabs { display: flex; border-bottom: 1px solid var(--line); }
.tab {
  flex: 1;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--line);
  padding: 9px 4px;
  font-size: 9px;
  letter-spacing: 0.16em;
  color: var(--dim);
  cursor: pointer;
}
.tab:last-child { border-right: 0; }
.tab:hover { color: var(--ink); }
.tab.active { color: #000; background: var(--accent); }

#panel-body { flex: 1; overflow-y: auto; min-height: 0; }
.pane { display: none; padding: 14px; }
.pane.active { display: block; }

.row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  gap: 8px;
  align-items: baseline;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
}
.row .swatch { width: 10px; height: 10px; border: 1px solid rgba(255,255,255,0.35); }
.row .name { color: var(--ink); }
.row .meta { color: var(--dim); font-size: 10px; }
.row.dead .name { color: var(--faint); text-decoration: line-through; }

h3 {
  margin: 18px 0 8px;
  font-size: 9px;
  letter-spacing: 0.26em;
  color: var(--dim);
  border-bottom: 1px solid var(--line);
  padding-bottom: 5px;
}
h3:first-child { margin-top: 0; }

.card { border: 1px solid var(--line); padding: 9px; margin-bottom: 9px; background: #000; }
.card .head { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 5px; }
.card .type { color: var(--accent); font-size: 10px; letter-spacing: 0.12em; }
.card .why { color: var(--dim); }
.card.bad { border-color: #4a2320; }
.card.bad .type { color: var(--alert); }

.kv { display: grid; grid-template-columns: 96px 1fr; gap: 4px 10px; }
.kv dt { color: var(--dim); font-size: 10px; }
.kv dd { margin: 0; }

.msg { border-left: 2px solid var(--line); padding: 4px 0 4px 9px; margin-bottom: 9px; }
.msg .from { color: var(--accent); font-size: 10px; }
.msg .body { color: var(--ink); }

.evt { padding: 3px 0; color: var(--dim); border-bottom: 1px solid rgba(30,42,37,0.5); }
.evt.has-duel { cursor: pointer; }
.evt.has-duel:hover { color: var(--ink); }
.evt .open { display: block; font-size: 8px; letter-spacing: 0.2em; color: var(--alert); margin-top: 2px; }
.evt.hl { color: var(--ink); }
.evt .t { color: var(--faint); margin-right: 6px; }

/* ── the tech tree ───────────────────────────────────────────────────────── */

/* One sub-tab per branch: six branches side by side was a wall of chips, and
   only one of them is ever the question you are asking. */
.subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-bottom: 10px;
  border-bottom: 1px solid var(--faint);
}
.subtab {
  background: none;
  border: 1px solid transparent;
  border-bottom: none;
  color: var(--faint);
  font: inherit;
  font-size: 9px;
  letter-spacing: 0.12em;
  padding: 4px 8px;
  cursor: pointer;
}
.subtab:hover { color: var(--ink); }
.subtab.active { color: var(--accent); border-color: var(--faint); background: rgba(255,255,255,0.03); }
.subtab-count { color: var(--faint); margin-left: 6px; }
.subtab.active .subtab-count { color: var(--ink); }

/* Grows upward: foundational on the bottom row, frontier at the top. */
.tech-tree { position: relative; padding: 4px 0; }
.tech-links { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.tech-link { fill: none; stroke: var(--faint); stroke-width: 1; opacity: 0.55; }
/* "One of these" rather than "all of these". */
.tech-link.any { stroke-dasharray: 3 3; opacity: 0.35; }

.tech-tier { display: flex; align-items: center; gap: 8px; margin-bottom: 18px; }
.tech-tier:last-child { margin-bottom: 0; }
.tier-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 8px;
  letter-spacing: 0.18em;
  color: var(--faint);
  text-transform: uppercase;
  flex: 0 0 auto;
}
.tier-nodes { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; position: relative; z-index: 1; }

.tech-node {
  border: 1px solid var(--faint);
  color: var(--faint);
  background: #000;
  padding: 5px 8px;
  font-size: 10px;
  line-height: 1.3;
  cursor: help;
  max-width: 140px;
}
.tech-node .tech-name { display: block; }
.tech-progress { color: var(--ink); font-size: 9px; }
/* Held, being worked on, affordable next, or out of reach. */
.tech-node.done { border-color: var(--accent); color: var(--accent); background: rgba(255,255,255,0.05); }
.tech-node.researching { border-color: var(--ink); color: var(--ink); border-style: dashed; }
.tech-node.available { border-color: var(--ink); color: var(--ink); opacity: 0.75; }
.tech-node.locked { opacity: 0.4; }
.tech-node:hover { border-color: var(--ink); color: var(--ink); opacity: 1; }

#tooltip .tip-effects { color: var(--ink); margin-top: 4px; }
#tooltip .tip-cost { color: var(--faint); margin-top: 4px; letter-spacing: 0.06em; }
#tooltip .tip-locked { color: var(--faint); margin-top: 4px; font-style: italic; }

/* ── active bonuses ──────────────────────────────────────────────────────── */

.bonus { border-left: 2px solid var(--accent); padding: 3px 0 3px 7px; margin-bottom: 6px; }
.bonus-head { display: flex; justify-content: space-between; gap: 8px; }
.bonus-name { color: var(--ink); font-size: 10px; }
.bonus-branch { color: var(--faint); font-size: 8px; letter-spacing: 0.1em; text-transform: uppercase; }
.bonus-effects { color: var(--faint); font-size: 9px; line-height: 1.5; }
.none { color: var(--faint); font-size: 10px; font-style: italic; }

/* ── special operations ──────────────────────────────────────────────────── */

/* What this player can actually do, under the map where the board is. */
#specials-bar {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 5px 8px;
  border-top: 1px solid var(--faint);
  min-height: 30px;
  flex: 0 0 auto;
  overflow-x: auto;
}
.specials-empty { color: var(--faint); font-size: 9px; letter-spacing: 0.1em; }
.special {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--faint);
  color: var(--faint);
  font: inherit;
  font-size: 9px;
  padding: 3px 8px;
  cursor: help;
  white-space: nowrap;
}
.special-glyph { font-size: 12px; line-height: 1; }
.special-status { color: var(--faint); font-size: 8px; letter-spacing: 0.1em; }
.special.ready { border-color: var(--accent); color: var(--accent); }
.special.ready .special-status { color: var(--accent); }
.special.cooling { opacity: 0.5; }
.special.fired { border-color: var(--ink); color: var(--ink); background: rgba(255,255,255,0.08); }

/* A special going off takes the screen for a beat — it is a thing that happened,
   not a line to find later in the log. */
#special-popup {
  position: absolute;
  top: 18%;
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  background: #000;
  border: 1px solid var(--accent);
  padding: 12px 20px;
  text-align: center;
  max-width: 70%;
  pointer-events: none;
}
#special-popup.show { animation: special-in 4.2s ease-out forwards; }
.special-pop-name {
  color: var(--accent);
  font-size: 15px;
  letter-spacing: 0.2em;
  margin-bottom: 5px;
}
.special-pop-text { color: var(--ink); font-size: 10px; line-height: 1.6; }

@keyframes special-in {
  0% { opacity: 0; transform: translateX(-50%) scale(0.9); }
  8% { opacity: 1; transform: translateX(-50%) scale(1); }
  85% { opacity: 1; }
  100% { opacity: 0; }
}

/* ── the fight card ──────────────────────────────────────────────────────── */

/* Combat is the most dramatic thing the engine does, so it gets the screen.
   Both emblems, both strengths, what each side said, then the verdict. */
#duel-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.86), rgba(0, 0, 0, 0.97));
  backdrop-filter: blur(2px);
  animation: duel-in 320ms ease-out;
}
#duel-overlay[hidden] { display: none; }
@keyframes duel-in { from { opacity: 0; } to { opacity: 1; } }

#duel-card {
  width: min(1080px, 92vw);
  border: 1px solid var(--line);
  border-top: 2px solid var(--alert);
  background: linear-gradient(180deg, rgba(255, 90, 74, 0.06), transparent 40%);
  padding: 20px 26px 24px;
}

#duel-banner { text-align: center; margin-bottom: 20px; }
#duel-kind {
  display: block;
  font-size: 10px;
  letter-spacing: 0.44em;
  color: var(--alert);
  margin-bottom: 6px;
}
#duel-prize { display: block; font-size: 13px; letter-spacing: 0.1em; color: var(--dim); }

#duel-body {
  display: grid;
  grid-template-columns: 1fr 176px 1fr;
  gap: 20px;
  align-items: start;
}

.duel-side { text-align: center; min-width: 0; }
.duel-side .duel-art {
  width: 148px;
  height: 148px;
  margin: 0 auto 12px;
  border: 1px solid var(--line);
  background: #000;
  display: grid;
  place-items: center;
}
.duel-side .duel-art svg { width: 100%; height: 100%; display: block; }
#duel-attacker .duel-art { box-shadow: 0 0 34px -8px var(--duel-attacker, #fff); animation: duel-slide-l 420ms cubic-bezier(0.2, 0.8, 0.3, 1); }
#duel-defender .duel-art { box-shadow: 0 0 34px -8px var(--duel-defender, #fff); animation: duel-slide-r 420ms cubic-bezier(0.2, 0.8, 0.3, 1); }
@keyframes duel-slide-l { from { opacity: 0; transform: translateX(-46px); } to { opacity: 1; transform: none; } }
@keyframes duel-slide-r { from { opacity: 0; transform: translateX(46px); } to { opacity: 1; transform: none; } }

.duel-org { font-size: 16px; letter-spacing: 0.1em; line-height: 1.3; overflow-wrap: anywhere; }
#duel-attacker .duel-org { color: var(--duel-attacker, var(--ink)); }
#duel-defender .duel-org { color: var(--duel-defender, var(--ink)); }
.duel-role { font-size: 8px; letter-spacing: 0.3em; color: var(--faint); margin-top: 4px; }

.duel-power { margin-top: 10px; }
.duel-power .n { font-size: 30px; letter-spacing: 0.04em; color: var(--ink); }
.duel-power .u { font-size: 8px; letter-spacing: 0.28em; color: var(--dim); margin-left: 7px; }

.duel-bar { height: 5px; background: #000; border: 1px solid var(--line); margin: 10px auto 0; max-width: 260px; }
.duel-bar i { display: block; height: 100%; width: 0; transition: width 620ms cubic-bezier(0.2, 0.8, 0.3, 1); }
#duel-attacker .duel-bar i { background: var(--duel-attacker, #fff); }
#duel-defender .duel-bar i { background: var(--duel-defender, #fff); }

.duel-word {
  margin-top: 16px;
  min-height: 46px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--faint);
  font-style: italic;
  opacity: 0;
  transition: opacity 260ms linear, color 260ms linear;
}
.duel-word.said { opacity: 1; color: var(--ink); }

#duel-center { text-align: center; padding-top: 42px; }
#duel-vs {
  font-size: 34px;
  letter-spacing: 0.16em;
  color: var(--alert);
  text-shadow: 0 0 22px rgba(255, 90, 74, 0.5);
}
#duel-odds { font-size: 9px; letter-spacing: 0.2em; color: var(--faint); margin-top: 8px; }
#duel-outcome {
  margin-top: 20px;
  font-size: 17px;
  letter-spacing: 0.24em;
  min-height: 26px;
  opacity: 0;
}
#duel-outcome.stamped { opacity: 1; animation: duel-stamp 420ms cubic-bezier(0.2, 1.4, 0.4, 1); }
#duel-outcome.win { color: var(--alert); }
#duel-outcome.held { color: var(--accent); }
@keyframes duel-stamp {
  from { opacity: 0; transform: scale(1.6); letter-spacing: 0.5em; }
  to { opacity: 1; transform: scale(1); }
}

#duel-toll {
  margin-top: 22px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  text-align: center;
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--dim);
  min-height: 16px;
  opacity: 0;
  transition: opacity 260ms linear;
}
#duel-toll.shown { opacity: 1; }

@media (max-width: 900px) {
  #duel-body { grid-template-columns: 1fr; gap: 12px; }
  #duel-center { padding-top: 0; }
  .duel-side .duel-art { width: 96px; height: 96px; }
}

#tooltip {
  position: fixed;
  z-index: 120;
  background: #000;
  border: 1px solid var(--accent);
  padding: 7px 9px;
  pointer-events: none;
  max-width: 280px;
  font-size: 10px;
  line-height: 1.6;
}
#tooltip .th { color: var(--accent); letter-spacing: 0.14em; }

#boot {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--bg);
  color: var(--accent);
  letter-spacing: 0.3em;
  z-index: 200;
}
#boot.gone { display: none; }
#boot.error { color: var(--alert); text-align: center; padding: 40px; line-height: 2; }

@media (max-width: 1100px) {
  #layout { grid-template-columns: 1fr; grid-template-rows: 1fr 320px; }
  #panel { border-left: 0; border-top: 1px solid var(--line); }
  /* The panel is only 320px tall here — the plate shrinks so it does not eat
     the pane it sits under. */
  #avatar-card { grid-template-columns: 84px minmax(0, 1fr); gap: 12px; padding: 10px 12px; }
  #avatar-art { width: 84px; height: 84px; }
  #avatar-org { font-size: 13px; }
  #avatar-concept { -webkit-line-clamp: 2; margin-top: 6px; }
}
