/* ═════════════════════════════════════════════════════════════════════════
   GOLDEN ARENA · COMPONENTS · v3 "the archive"
   Built exclusively on the SEMANTIC layer in tokens.css. No component reads
   a raw palette value and none of them branch on register — .register-room
   remaps the same names underneath them.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── base ─────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; background-color: var(--surface-page); }
body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--surface-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
/* the only textural indulgence: paper grain here, the light pool in the room */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;               /* above the propagated canvas, below all content */
  pointer-events: none;
  background-image: var(--page-texture);
  background-size: var(--page-texture-size);
  background-repeat: repeat;
}
html.turning body::before { animation: veilIn var(--t-register) var(--ease-out) both; }
@keyframes veilIn { from { opacity: 0; } to { opacity: 1; } }

/* THE LIGHTS GOING DOWN, AND THE RECORD PRINTING BACK ONTO PAPER.
   A full field of the OUTGOING register washes away and the new register
   resolves through it. Deliberately a dissolve on a real layer rather than a
   transition on the tokens: (a) a change driven by a custom property does
   not reliably start a CSS transition on the properties that read it, and
   (b) melting cream into near-black passes every piece of type through a
   muddy, low-contrast middle. The wash cuts cleanly instead. */
.lights-wash {
  position: fixed;
  inset: 0;
  z-index: 150;
  pointer-events: none;
  background-color: var(--wash-from, transparent);
  animation: washOut var(--t-register) cubic-bezier(.35, 0, .18, 1) forwards;
}
@keyframes washOut { from { opacity: 1; } to { opacity: 0; } }

::selection { background: var(--sig-bad-wash); color: var(--text-primary); }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.14; }
p { margin: 0; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
button:disabled { cursor: default; opacity: .5; }
img { max-width: 100%; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* every number that can change is tabular */
.receipt, .idx, .teaser, .payoff-num, .readout, .mc-pay, .mr-pay, .rr-pay,
.idx-earn, .idx-matches, .mb-val, .t-earn, .board-totals {
  font-variant-numeric: tabular-nums;
}

.wrap { max-width: var(--container); margin: 0 auto; padding: 0 var(--sp-4); }
#view { display: block; padding-block: var(--sp-5) var(--sp-7); }
/* page changes: 120ms opacity, no slide, no stagger */
#view.view-in { animation: pageIn var(--t-page) linear both; }
@keyframes pageIn { from { opacity: 0; } to { opacity: 1; } }

/* ── the editorial page: running head · sheet · marginalia · folio ────── */
.runhead {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--foil-rule);
  margin-bottom: var(--sp-6);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.runhead b { font-weight: 500; color: var(--text-secondary); }
.runhead .rh-no { margin-left: auto; font-family: var(--font-mono); }

.folio {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  margin-top: var(--sp-8);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.folio a { border-bottom: 1px solid var(--foil-rule); }
.folio a:hover { color: var(--text-primary); }

/* a sheet: main column plus a marginalia column on wide screens */
.sheet { display: block; }
.margin-note {
  font-size: .8rem;
  line-height: 1.6;
  color: var(--text-tertiary);
  border-top: 1px solid var(--foil-rule);
  padding-top: var(--sp-2);
  margin-top: var(--sp-4);
  max-width: 46ch;
}
.margin-note b { color: var(--text-secondary); font-weight: 500; }
.margin-note-h {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-secondary);
  margin-bottom: var(--sp-1);
}
@media (min-width: 1024px) {
  .sheet {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--margin-col);
    gap: var(--sp-7);
    align-items: start;
  }
  .margin-note { margin-top: var(--sp-1); }
}

/* ── type helpers ─────────────────────────────────────────────────────── */
.kicker {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.kicker-rule { display: flex; align-items: center; gap: var(--sp-4); }
.kicker-rule::after {
  content: ""; height: 1px; flex: 1;
  background: var(--foil-rule);
}
.micro { font-size: var(--fs-xs); color: var(--text-tertiary); }
.nowrap { white-space: nowrap; }
.sec-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--rule);
}
.view-head { margin-bottom: var(--sp-6); }
.view-head h2 {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  margin-top: var(--sp-2);
  max-width: 20ch;
}
.view-head .dek {
  max-width: var(--measure); margin-top: var(--sp-3);
  color: var(--text-secondary); font-size: var(--fs-sm);
}

/* ── masthead ─────────────────────────────────────────────────────────── */
.topnav {
  position: sticky; top: 0; z-index: var(--z-nav);
  background: var(--scrim);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}
.topnav-in {
  display: flex; align-items: center; gap: var(--sp-4);
  flex-wrap: wrap;
  padding-top: var(--sp-3); padding-bottom: var(--sp-3);
}
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-display);
  font-size: 1.34rem;
  font-weight: 700;
  letter-spacing: .05em;
  background: var(--foil-ramp);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  white-space: nowrap;
}
.wordmark .mark { flex: 0 0 auto; display: block; }
.nav-links { display: flex; gap: var(--sp-5); flex-wrap: wrap; margin-right: auto; }
.nav-link {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: var(--sp-1) 0;
  border-bottom: 1px solid transparent;
  transition: color var(--t-fast) var(--ease-out);
}
.nav-link:hover { color: var(--text-primary); }
.nav-link.active { color: var(--text-primary); border-bottom-color: var(--foil); }
/* At 375 the five items need 404px of a 343px strip, so THE INDEX hung 61px
   off the right edge with nothing to say it was there. Tighter gap and tracking
   fit them, and the links become a real 44px target on the way. */
@media (max-width: 480px) {
  .nav-links { gap: 10px; }
  /* 12px of padding landed the link on 43 — one pixel under the target, which
     is not a rounding opinion, it either clears 44 or it does not */
  .nav-link { letter-spacing: .02em; padding: 13px 0; }
  /* primary controls in the gallery, not decoration */
  .check, .seg-item { min-height: 44px; }
  .seg-item { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; }
}

/* status chips — the one place a pill survives.
   The mode pill is also the door to the key panel, so it is a real button:
   pointer, hover, and the global focus ring. */
.pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs); font-weight: 500;
  letter-spacing: var(--track-label);
  padding: 2px var(--sp-3);
  border-radius: var(--r-pill);
  border: 1px solid var(--rule-strong);
  color: var(--text-tertiary);
  cursor: default;
  white-space: nowrap;
}
button.pill { cursor: pointer; transition: border-color var(--t-fast) var(--ease-out); }
button.pill:hover { border-color: currentColor; }
.pill-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill-live { color: var(--sig-good); border-color: var(--sig-good-rule); }
.pill-live .pill-dot { animation: pillPulse 2.4s infinite; }
/* DEMO reads amber the archive's way: a foil hairline and a foil mark. Foil
   never becomes type here — the label stays ink (tokens.css, the foil rule). */
.pill-demo { color: var(--text-secondary); border-color: var(--foil-rule); }
.pill-demo .pill-dot { background: var(--foil); }
@keyframes pillPulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }

/* ── buttons: ink outline, 2px radius, foil hairline on the primary ───── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs); font-weight: 500;
  letter-spacing: var(--track-label); text-transform: uppercase;
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r);
  border: 1px solid var(--rule-strong);
  color: var(--text-primary);
  background: transparent;
  transition: background-color var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out),
              border-color var(--t-fast) var(--ease-out);
  white-space: nowrap;
}
.btn:hover:not(:disabled) { border-color: var(--text-primary); }
/* the gilt line: ink rule outside, a paper gap, a foil hairline inside */
.btn-primary {
  border-color: var(--text-primary);
  box-shadow: inset 0 0 0 2px var(--surface-page), inset 0 0 0 3px var(--foil-rule);
}
.btn-primary:hover:not(:disabled) {
  background: var(--surface-invert);
  color: var(--text-on-invert);
  box-shadow: inset 0 0 0 2px var(--surface-invert), inset 0 0 0 3px var(--foil-rule);
}
.btn-quiet { border-color: var(--rule); color: var(--text-secondary); }
.btn-quiet:hover:not(:disabled) { border-color: var(--text-secondary); color: var(--text-primary); }
.btn-sm { padding: var(--sp-2) var(--sp-4); }
.btn-lg { padding: var(--sp-3) var(--sp-6); font-size: var(--fs-sm); }
.btn-xl {
  padding: var(--sp-4) var(--sp-7);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-wide);
}

/* the two verdict buttons — the loudest thing in the room, deliberately */
.choice-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.btn-choice {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-1);
  min-height: 78px;
  padding: var(--sp-4);
  border-radius: var(--r);
  border: 1px solid;
  transition: background-color var(--t-fast) var(--ease-out);
}
.choice-big {
  font-family: var(--font-stamp);
  font-size: var(--fs-xl);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
}
.choice-sub { font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-secondary); }
/* The signal colours are set against the PAGE, and these two buttons carry a
   wash of that same colour behind them, so the word ends up dark-on-dark:
   measured 2.37 and 2.32 inside the room, against DESIGN.md's own floor of
   4.5 for body and 3 for large text. The word is 28px on a laptop but 21px on
   a phone, which is under the large-text threshold, so 4.5 is the bar it has
   to clear. Lifted until it does — measured in place at 4.78 and 4.74, with
   the border and the wash still carrying the colour. */
.btn-choice-good { background: var(--sig-good-wash); border-color: var(--sig-good-rule); color: rgb(158, 214, 181); }
.btn-choice-good:hover:not(:disabled) { background: var(--sig-good-rule); }
.btn-choice-bad { background: var(--sig-bad-wash); border-color: var(--sig-bad-rule); color: rgb(244, 180, 166); }
.btn-choice-bad:hover:not(:disabled) { background: var(--sig-bad-rule); }
/* the sub-line is small text on the same wash and needs the same treatment */
.btn-choice .choice-sub { color: inherit; opacity: .82; }

/* ── cards & chips ────────────────────────────────────────────────────── */
.card {
  background: var(--surface-inset);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-5);
}
.card-hover { transition: border-color var(--t-fast) var(--ease-out); }
.card-hover:hover { border-color: var(--rule-strong); }

.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  font-size: var(--fs-xs);
  letter-spacing: .04em;
  padding: 3px var(--sp-3);
  border-radius: var(--r);
  border: 1px solid var(--rule);
  color: var(--text-secondary);
  background: transparent;
  transition: border-color var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out),
              background-color var(--t-fast) var(--ease-out);
}
button.chip:hover:not(:disabled) { border-color: var(--text-secondary); color: var(--text-primary); }
.chip-power { border-color: var(--foil-rule); }
.chip-handicap { border-color: var(--sig-bad-rule); color: var(--sig-bad); }
.chip-on.chip-power { background: var(--surface-invert); color: var(--text-on-invert); border-color: var(--surface-invert); }
.chip-on.chip-handicap { background: var(--sig-bad); color: var(--surface-page); border-color: var(--sig-bad); }
.chip-model { padding: var(--sp-2) var(--sp-4); }
.chip-model.chip-on { background: var(--surface-invert); color: var(--text-on-invert); border-color: var(--surface-invert); }
.chip-xs { font-size: var(--fs-xs); padding: 1px var(--sp-2); }
.chip-none { border-style: dashed; color: var(--text-tertiary); }
.game-axis {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* ── forms ────────────────────────────────────────────────────────────── */
.input, .select {
  width: 100%;
  background: var(--surface-well);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  color: var(--text-primary);
  font-family: inherit;
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-md);
  transition: border-color var(--t-fast) var(--ease-out);
}
.input::placeholder { color: var(--text-tertiary); }
.input:focus-visible, .select:focus-visible { border-color: var(--text-primary); }
.select {
  width: auto;
  padding: var(--sp-2) var(--sp-6) var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  -webkit-appearance: none;
  appearance: none;
}
.selwrap { position: relative; display: inline-flex; }
.selwrap::after {
  content: "";
  position: absolute; right: var(--sp-3); top: 50%;
  margin-top: -2px;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--text-secondary);
  pointer-events: none;
}

.check {
  position: relative;
  display: inline-flex; align-items: center; gap: var(--sp-1);
  font-size: var(--fs-xs); letter-spacing: .04em;
  color: var(--text-secondary);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-2) var(--sp-4);
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out),
              background-color var(--t-fast) var(--ease-out);
}
.check:hover { border-color: var(--text-secondary); }
.check:has(input:checked) {
  border-color: var(--surface-invert);
  background: var(--surface-invert);
  color: var(--text-on-invert);
}
.check:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.check input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
.checks { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* range slider — a printed rule with a travelling mark */
.rangebox { padding: var(--sp-3) var(--sp-1) var(--sp-6); }
.range-wrap { position: relative; }
.range {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 3px;
  background: linear-gradient(90deg, var(--text-primary) var(--fill, 50%), var(--rule-strong) var(--fill, 50%));
  outline: none;
}
.range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 24px; border-radius: var(--r);
  background: var(--surface-invert);
  border: 1px solid var(--surface-invert);
  box-shadow: inset 0 0 0 1px var(--surface-page), inset 0 0 0 2px var(--foil-rule);
  cursor: grab;
}
.range::-moz-range-thumb {
  width: 14px; height: 24px; border-radius: var(--r);
  background: var(--surface-invert);
  border: 1px solid var(--surface-invert);
  box-shadow: inset 0 0 0 1px var(--surface-page), inset 0 0 0 2px var(--foil-rule);
  cursor: grab;
}
.rtick {
  position: absolute; left: var(--at, 50%); top: 50%;
  width: 1px; height: 14px;
  margin-top: -7px;
  background: var(--foil);
  pointer-events: none;
}
/* The thumb is 24px tall and centred on the track, so anything hung at the
   track's midline lands UNDER it. Measured at the 50/50 default where every
   reader starts: the "fair" label's top sat 8px inside the thumb and its
   centre 2px from the thumb's, which cut the tops off the glyphs. 16px clears
   the thumb's 12px reach with room to breathe. */
.rtick-label {
  position: absolute; left: var(--at, 50%); top: 50%;
  transform: translateX(-50%);
  margin-top: 16px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
  pointer-events: none;
}
/* same thumb, same reach: at either end of the travel it sits on these */
.rtick-end {
  position: absolute; top: 50%;
  margin-top: 16px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .06em;
  color: var(--text-tertiary);
  pointer-events: none;
}
.rtick-end-min { left: 0; }
.rtick-end-max { right: 0; }
.readout { font-size: var(--fs-sm); color: var(--text-secondary); margin: var(--sp-3) 0; }
.readout b { color: var(--text-primary); font-family: var(--font-mono); font-weight: 500; }
.readout .pos { color: var(--sig-good); }

/* ── setup (play wizard) ──────────────────────────────────────────────── */
.setup-card { display: flex; flex-direction: column; gap: var(--sp-4); }
.setup-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-top: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--rule);
}
.setup-label:first-child { margin-top: 0; }
.setup-hint { color: var(--text-tertiary); letter-spacing: .06em; margin-left: var(--sp-2); text-transform: none; opacity: .8; }

.seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-3); }
.seg-item {
  text-align: left;
  display: flex; flex-direction: column; gap: var(--sp-1);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-3) var(--sp-4);
  transition: border-color var(--t-fast) var(--ease-out),
              background-color var(--t-fast) var(--ease-out);
}
.seg-item:hover:not(:disabled) { border-color: var(--text-secondary); }
.seg-item.on { border-color: var(--text-primary); background: var(--surface-well); }
.seg-name { font-weight: 500; font-size: var(--fs-sm); color: var(--text-primary); }
.seg-tag { font-size: var(--fs-xs); color: var(--text-secondary); font-style: italic; }
.seg-meta { font-size: var(--fs-xs); color: var(--text-tertiary); letter-spacing: .04em; text-transform: uppercase; }
.seg-slim { grid-template-columns: repeat(4, auto); justify-content: start; }
.seg-slim .seg-item { padding: var(--sp-2) var(--sp-4); }

.rig-cols { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.rig-col {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-4);
}
.rig-col-title {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: var(--sp-3);
}
.rig-col.maxed .chip:not(.chip-on) { opacity: .4; }
.enter-row { margin-top: var(--sp-4); }

/* ── transcript ───────────────────────────────────────────────────────── */
.transcript {
  display: flex; flex-direction: column; gap: var(--sp-3);
  background: var(--surface-inset);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-4);
  max-height: min(48vh, 460px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-strong) transparent;
}
.transcript-mini { max-height: 320px; }
.bubble {
  position: relative;
  max-width: 82%;
  background: var(--surface-well);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-2) var(--sp-4) var(--sp-3);
  font-size: var(--fs-sm);
  line-height: 1.55;
  /* No base entrance animation. Every polling view rebuilds its DOM from
     innerHTML, so an unconditional fade here replayed on EVERY bubble on
     every 1.2s poll — a 20-minute Empire run pulsed once a second for its
     whole length. Lines that ARRIVE animate via .is-arriving, which the
     play transcript applies only to lines new since the last paint. */
}
.bubble-who {
  display: block;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 2px;
}
.bubble-you, .bubble-b { align-self: flex-end; }
.bubble-opp, .bubble-a { align-self: flex-start; border-left: 2px solid var(--foil-rule); }
.divider {
  align-self: center; text-align: center;
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%;
  color: var(--text-tertiary);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}
.divider::before, .divider::after { content: ""; height: 1px; flex: 1; background: var(--rule); }
.divider span { max-width: 70%; }
.bubble-thinking { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--text-secondary); }
.thinking-text { font-size: var(--fs-xs); }
.dots { display: inline-flex; gap: 4px; align-items: center; }
.dots i {
  width: 4px; height: 4px; border-radius: 50%;
  background: currentColor; display: inline-block;
  animation: dotPulse 1.2s infinite;
}
.dots i:nth-child(2) { animation-delay: .18s; }
.dots i:nth-child(3) { animation-delay: .36s; }
@keyframes dotPulse { 0%, 70%, 100% { opacity: .25; } 35% { opacity: 1; } }

/* ── match header ─────────────────────────────────────────────────────── */
.match { display: flex; flex-direction: column; gap: var(--sp-4); max-width: 780px; margin: 0 auto; }
.match-head { display: flex; flex-direction: column; gap: var(--sp-3); }
.vs { font-family: var(--font-display); font-size: var(--fs-xl); margin-top: var(--sp-1); }
.vs em { font-style: italic; color: var(--text-tertiary); font-size: .68em; padding: 0 var(--sp-1); }
.match-powers { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); }
.side-powers { display: inline-flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.side-who { font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary); }

/* ── the dock ─────────────────────────────────────────────────────────── */
.dock { display: flex; flex-direction: column; gap: var(--sp-3); }
.dock-note { font-size: var(--fs-sm); color: var(--text-secondary); }
.dock-idle { color: var(--text-tertiary); }
.msg-row { display: flex; gap: var(--sp-3); }
.msg-row .input { flex: 1; }
.leak {
  border: 1px solid var(--foil-rule);
  border-left-width: 3px;
  border-radius: var(--r);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-primary);
}
.leak b { font-family: var(--font-stamp); letter-spacing: .06em; font-weight: 400; }
.leak .leak-bad { color: var(--sig-bad); }
.leak .leak-good { color: var(--sig-good); }
.leak-tag {
  font-size: var(--fs-xs); font-weight: 500;
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: var(--foil);
  margin-right: var(--sp-3);
}
.offer-big { font-size: var(--fs-lg); font-family: var(--font-display); }
.offer-big b { font-family: var(--font-mono); font-weight: 500; }
.offer-big .pos { color: var(--sig-good); }
.offer-keep { display: block; font-family: var(--font-body); font-size: var(--fs-sm); color: var(--text-secondary); margin-top: var(--sp-1); }

.pips { display: flex; gap: var(--sp-2); }
.pip {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-1) var(--sp-2);
  min-width: 44px;
  opacity: .45;
}
.pip-done, .pip-now { opacity: 1; }
.pip-now { border-color: var(--foil); }
.pip-r { font-size: var(--fs-xs); letter-spacing: .06em; color: var(--text-tertiary); }
.pip-now .pip-r { color: var(--foil); }
.pip-pair { display: flex; gap: 4px; }
.pip-pair i { width: 8px; height: 8px; border-radius: 50%; border: 1px solid var(--rule-strong); display: inline-block; }
.pip-pair i.pc { background: var(--sig-good); border-color: var(--sig-good); }
.pip-pair i.pd { background: var(--sig-bad); border-color: var(--sig-bad); }
.pip-pair i.pq { border-color: var(--foil); animation: pillPulse 1.6s infinite; }

/* ── the reveal · the record prints onto paper ────────────────────────── */
.reveal { display: flex; flex-direction: column; gap: var(--sp-6); }
.payoff-row {
  display: flex; align-items: baseline; gap: var(--sp-6);
  border-bottom: 1px solid var(--rule);
  padding-bottom: var(--sp-4);
}
.payoff { display: flex; flex-direction: column; gap: 0; }
.payoff-who { font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary); }
/* the figure is the point */
.payoff-num {
  font-family: var(--font-mono);
  font-size: var(--fs-figure);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--text-primary);
}
.payoff-num.dim { color: var(--text-tertiary); }
.payoff-vs { color: var(--text-tertiary); font-size: var(--fs-lg); align-self: center; }

/* the receipt: a numbered impression on paper */
.receipt {
  position: relative;
  width: 100%; max-width: 580px;
  background: var(--surface-page);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r);
  padding: var(--sp-5);
  box-shadow: var(--shadow-paper);
}
.receipt::before {
  content: "";
  position: absolute; inset: 4px;
  border: 1px solid var(--foil-rule);
  border-radius: var(--r);
  pointer-events: none;
}
/* soft paper-settle when the record lands */
.receipt-anim { animation: paperSettle 460ms var(--ease-out) both; }
@keyframes paperSettle {
  from { opacity: 0; transform: translateY(-6px) scale(.994); }
  to   { opacity: 1; transform: none; }
}
.impression {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--sp-1) var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--foil-rule);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.imp-no {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--text-primary);
  margin-right: auto;
}
.imp-meta b { font-weight: 500; color: var(--text-secondary); }
.stamp-wrap { padding: var(--sp-6) 0 var(--sp-4); }
.stamp {
  display: inline-block;
  font-family: var(--font-stamp);
  font-size: var(--fs-2xl);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
  padding: var(--sp-2) var(--sp-4);
  border: 3px double currentColor;
  border-radius: var(--r);
  transform: rotate(-3.5deg);
  /* inked irregularity: a speckle mask eats a little pigment */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='2' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .3 .72'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23n)'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.75' numOctaves='2' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .3 .72'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* double-strike misregister: a same-hue copy a hair off register */
.stamp-bad { color: var(--sig-bad); text-shadow: 1px 2px 0 var(--sig-bad-rule); }
.stamp-good { color: var(--sig-good); text-shadow: 1px 2px 0 var(--sig-good-rule); }
.stamp-neutral { color: var(--text-secondary); text-shadow: 1px 2px 0 var(--rule-strong); }
.receipt-anim .stamp { animation: stampIn 340ms var(--ease-snap) .5s both; }
@keyframes stampIn {
  0%   { opacity: 0; transform: scale(1.55) rotate(2deg); }
  55%  { opacity: 1; transform: scale(.95) rotate(-5deg); }
  78%  { transform: scale(1.04) rotate(-3deg); }
  100% { transform: scale(1) rotate(-3.5deg); }
}
.receipt-headline { font-family: var(--font-display); font-size: var(--fs-xl); font-weight: 700; max-width: 26ch; }
.receipt-detail { font-size: var(--fs-sm); color: var(--text-secondary); margin-top: var(--sp-2); max-width: var(--measure); }
.receipt-rows { margin-top: var(--sp-5); border-top: 1px solid var(--rule); }
.receipt-pot {
  display: flex; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  color: var(--text-tertiary);
}
.receipt-row {
  display: grid; grid-template-columns: 1fr auto auto;
  gap: var(--sp-3); align-items: baseline;
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm);
}
.rr-label { font-weight: 500; }
.rr-you {
  font-style: normal; font-size: var(--fs-xs);
  color: var(--text-on-invert); background: var(--surface-invert);
  border-radius: var(--r); padding: 0 var(--sp-2);
  margin-left: var(--sp-2); letter-spacing: .06em; text-transform: uppercase;
}
.rr-powers { font-size: var(--fs-xs); color: var(--text-tertiary); }
.rr-pay { font-family: var(--font-mono); color: var(--text-primary); }
.damning {
  margin: var(--sp-5) 0 0;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-4);
  border-left: 2px solid var(--sig-bad);
}
.damning p { font-family: var(--font-display); font-style: italic; font-size: var(--fs-lg); line-height: 1.4; color: var(--text-primary); }
.damning cite { display: block; font-family: var(--font-body); font-style: normal; font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--sig-bad); margin-top: var(--sp-2); }
.receipt-foot {
  margin-top: var(--sp-5);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--foil-rule);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.reveal-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; }

/* ── watch ────────────────────────────────────────────────────────────── */
.watch-card { display: flex; flex-direction: column; gap: var(--sp-4); margin-bottom: var(--sp-5); }
.rig-selects { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.rig-sel {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  border: 1px solid var(--rule); border-radius: var(--r);
  padding: var(--sp-2) var(--sp-3);
}
.rig-sel-label { font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; }
.rig-sel-adv { color: var(--text-secondary); }
.rig-sel-hc { color: var(--sig-bad); }
.watch-actions { display: flex; gap: var(--sp-3); align-items: center; margin-top: var(--sp-2); }
.watch-error {
  color: var(--sig-bad); font-size: var(--fs-sm);
  border: 1px solid var(--sig-bad-rule); border-left-width: 3px; border-radius: var(--r);
  padding: var(--sp-2) var(--sp-4); margin-bottom: var(--sp-3);
}
.progress-line {
  display: flex; align-items: center; gap: var(--sp-3);
  color: var(--text-secondary); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase;
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--sp-4);
}
.progress-line.done { color: var(--text-tertiary); }
/* The floor holds its own space. Without it the page was 1062px tall at the
   moment Run was pressed, so scrolling to the results could travel 294px of the
   764 it needed and the table then rendered below where the scroll had stopped.
   Reserving the height makes that one scroll land, and stops the results
   shunting the page around underneath the reader as they arrive. */
#watch-live { min-height: 68vh; }
.match-list { display: flex; flex-direction: column; }
.matchcard {
  border-bottom: 1px solid var(--rule);
  transition: background-color var(--t-fast) var(--ease-out);
}
.matchcard[open] { background: var(--surface-inset); }
.matchcard summary {
  list-style: none;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  user-select: none;
}
.matchcard summary::-webkit-details-marker { display: none; }
.matchcard summary::before {
  content: "▸"; color: var(--text-tertiary);
  transition: transform var(--t-fast) var(--ease-out);
  font-size: var(--fs-xs);
}
.matchcard[open] summary::before { transform: rotate(90deg); }
.mc-vs { font-weight: 500; font-size: var(--fs-sm); margin-right: auto; }
.mc-vs em { font-style: italic; color: var(--text-tertiary); font-weight: 400; }
.mc-right { display: inline-flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; justify-content: flex-end; }
.mc-pay { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-secondary); }
.mc-live { display: inline-flex; align-items: center; gap: var(--sp-2); color: var(--text-tertiary); font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; }
.mc-body { padding: 0 var(--sp-4) var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.stamp-badge {
  display: inline-block;
  font-family: var(--font-stamp);
  font-size: var(--fs-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  border: 1px solid currentColor;
  border-radius: var(--r);
  padding: 1px var(--sp-2);
  transform: rotate(-1.5deg);
}
.stamp-badge.stamp-bad { color: var(--sig-bad); }
.stamp-badge.stamp-good { color: var(--sig-good); }
.stamp-badge.stamp-neutral { color: var(--text-secondary); }
.mini-receipt {
  background: var(--surface-page);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: var(--sp-4);
}
.mr-top { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.mr-game { font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary); }
.mr-head { font-family: var(--font-display); font-size: var(--fs-md); font-weight: 700; margin-top: var(--sp-2); }
.mr-detail { font-size: var(--fs-xs); color: var(--text-secondary); margin-top: var(--sp-1); }
.mr-vs { font-size: var(--fs-sm); font-weight: 500; margin-top: var(--sp-2); }
.mr-vs em { color: var(--text-tertiary); font-weight: 400; }
.mr-pay { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-secondary); margin-top: var(--sp-1); }
.mr-quote { font-family: var(--font-display); font-style: italic; font-size: var(--fs-sm); color: var(--text-secondary); margin-top: var(--sp-2); }

/* ── the Index · the catalogue ────────────────────────────────────────── */
.badge-seeded {
  display: inline-block;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  border: 1px dashed var(--rule-strong);
  border-radius: var(--r);
  padding: 2px var(--sp-3);
  margin-bottom: var(--sp-3);
}
.board-totals {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: var(--sp-4);
}
.idx { --idx-grid: 2.4rem minmax(7.5rem, 1.05fr) 3rem 6.4rem 3fr minmax(9.5rem, 1fr); display: flex; flex-direction: column; }
.idx-head, .idx-row {
  display: grid;
  grid-template-columns: var(--idx-grid);
  gap: var(--sp-4);
  align-items: center;
}
.idx-head {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: 0 var(--sp-2) var(--sp-2);
  border-bottom: 1px solid var(--text-primary);
}
.idx-row {
  padding: var(--sp-4) var(--sp-2);
  border-bottom: 1px solid var(--rule);
  transition: background-color var(--t-fast) var(--ease-out);
}
.idx-row:hover { background: var(--surface-inset); }
.idx-human { background: var(--surface-inset); box-shadow: inset 2px 0 0 var(--foil); }
.idx-rank { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.idx-player { font-weight: 500; font-size: var(--fs-sm); }
.idx-youlot {
  display: block;
  font-family: var(--font-display);
  font-weight: 400; font-size: var(--fs-xs); font-style: italic;
  color: var(--text-tertiary);
}
.idx-matches { font-size: var(--fs-sm); color: var(--text-tertiary); font-family: var(--font-mono); text-align: right; }
.idx-matches span { font-family: var(--font-body); font-size: var(--fs-xs); }
/* the figure carries the row */
.idx-earn { font-family: var(--font-mono); font-size: var(--fs-lg); font-weight: 500; color: var(--text-primary); text-align: right; letter-spacing: -.01em; }
.idx-h-num { text-align: right; }
.idx-axes { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--sp-2); }
.microbar { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.mb-label { font-size: var(--fs-xs); letter-spacing: .04em; color: var(--text-tertiary); overflow: hidden; text-overflow: ellipsis; }
.mb-track { display: block; height: 3px; background: var(--surface-well); overflow: hidden; }
.mb-fill { display: block; height: 100%; width: var(--w, 0%); background: var(--text-primary); }
.mb-val { font-size: var(--fs-xs); font-family: var(--font-mono); color: var(--text-secondary); }
.microbar-empty .mb-val { color: var(--text-tertiary); }
.idx-row:hover .mb-track { background: var(--rule-strong); }
/* corruption — a status chip, so a pill survives here */
.corr {
  display: inline-block;
  font-size: var(--fs-xs);
  border-radius: var(--r-pill);
  border: 1px solid var(--rule);
  padding: 2px var(--sp-3);
  line-height: 1.35;
  color: var(--text-secondary);
}
.corr-bad { color: var(--sig-bad); border-color: var(--sig-bad-rule); }
.corr-good { color: var(--sig-good); border-color: var(--sig-good-rule); }
.corr-mute { color: var(--text-tertiary); }
.receipts-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.method { margin-top: var(--sp-6); font-size: var(--fs-sm); color: var(--text-secondary); max-width: var(--measure); }
.method b { color: var(--text-primary); font-weight: 500; }
.method-budget { color: var(--sig-bad); margin-top: var(--sp-2); }

/* ── home ─────────────────────────────────────────────────────────────── */
.hero { padding: var(--sp-6) 0 var(--sp-7); border-bottom: 1px solid var(--rule); }
.hero-title {
  font-family: var(--font-display);
  font-size: var(--fs-hero);
  font-weight: 700; letter-spacing: -0.015em; line-height: 1.02;
  max-width: 15ch;
  margin: var(--sp-4) 0 0;
}
.hero-title em { font-style: italic; }
.hero-sub { max-width: var(--measure); margin: var(--sp-5) 0 0; color: var(--text-secondary); font-size: var(--fs-lg); line-height: 1.55; }
.hero-cta { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-6); }
.home-sec { margin-top: var(--sp-7); }
.game-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-4); }
.game-card { display: flex; flex-direction: column; gap: var(--sp-2); }
.game-name { font-family: var(--font-display); font-size: var(--fs-xl); }
.game-tag { color: var(--text-secondary); font-style: italic; font-size: var(--fs-sm); font-family: var(--font-display); }
.game-card-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: auto; padding-top: var(--sp-4); }
.game-min { font-size: var(--fs-xs); color: var(--text-tertiary); letter-spacing: .06em; text-transform: uppercase; }
.game-actions { display: inline-flex; gap: var(--sp-2); }
.rig-pitch { max-width: 40ch; margin: 0 0 var(--sp-4); color: var(--text-primary); font-family: var(--font-display); font-size: var(--fs-xl); font-style: italic; line-height: 1.3; }
.teaser { display: flex; flex-direction: column; gap: var(--sp-3); }
.teaser-loading, .teaser-empty { color: var(--text-tertiary); font-size: var(--fs-sm); padding: var(--sp-4) 0; }
.teaser-empty { display: flex; flex-direction: column; gap: var(--sp-3); align-items: flex-start; }
.teaser-rows { display: flex; flex-direction: column; }
.teaser-row {
  display: grid;
  grid-template-columns: 1.6rem minmax(7rem, 1fr) 2fr 5.2rem 5rem;
  gap: var(--sp-3); align-items: center;
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm);
}
.t-rank { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-tertiary); }
.t-label { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.t-bar { display: block; height: 3px; background: var(--surface-well); overflow: hidden; }
.t-fill { display: block; height: 100%; width: var(--w, 0%); background: var(--text-primary); }
.t-coop { font-size: var(--fs-xs); color: var(--text-tertiary); white-space: nowrap; }
.t-earn { font-family: var(--font-mono); font-weight: 500; color: var(--text-primary); text-align: right; }
.teaser-humans {
  border-left: 2px solid var(--foil);
  color: var(--text-secondary);
  padding: var(--sp-1) var(--sp-4);
  font-size: var(--fs-sm);
}
.t-youlot { font-family: var(--font-display); font-style: italic; color: var(--text-primary); margin-right: var(--sp-2); }
.foot-link { border-bottom: 1px solid var(--foil-rule); }
.foot-link:hover { color: var(--text-primary); }

/* ── empty & offline states ───────────────────────────────────────────── */
.empty, .empty-state { color: var(--text-secondary); }
.empty { padding: var(--sp-6); font-size: var(--fs-sm); }
.empty-state { padding: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-3); align-items: flex-start; }
/* --foil measured 2.72 here, under DESIGN.md's own 3:1 floor for large text.
   The ornament is the anchor of an empty state, not decoration you can ignore. */
.empty-art { font-size: var(--fs-lg); color: var(--text-tertiary); letter-spacing: var(--track-wide); }
.empty-state h3 { font-family: var(--font-display); font-size: var(--fs-xl); color: var(--text-primary); }
.empty-state p { max-width: 46ch; font-size: var(--fs-sm); }
.empty-cta { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-2); }

/* ── toasts ───────────────────────────────────────────────────────────── */
#toasts {
  position: fixed; left: 50%; bottom: var(--sp-5);
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex; flex-direction: column; gap: var(--sp-2); align-items: center;
  pointer-events: none;
  width: max-content; max-width: 92vw;
}
.toast {
  background: var(--surface-invert);
  border: 1px solid var(--surface-invert);
  color: var(--text-on-invert);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r);
  box-shadow: var(--shadow-paper);
  font-size: var(--fs-sm);
  max-width: min(92vw, 480px);
  animation: toastIn var(--t-med) var(--ease-out) both;
  transition: opacity var(--t-med) var(--ease-out);
}
.toast-btn {
  margin-left: var(--sp-3);
  padding: 2px var(--sp-3);
  border: 1px solid currentColor;
  border-radius: var(--r);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  opacity: .85;
}
.toast-btn:hover { opacity: 1; }
.toast-error { box-shadow: inset 3px 0 0 var(--oxblood-lift), var(--shadow-paper); }
.toast-ok { box-shadow: inset 3px 0 0 var(--verdigris-lift), var(--shadow-paper); }
.toast-out { opacity: 0; }
@keyframes toastIn { from { opacity: 0; } to { opacity: 1; } }

/* ── the key panel ─────────────────────────────────────────────────────
   A leaf slipped into whichever register you are standing in — it inherits
   the semantic tokens, so it prints on cream in the archive and sits under
   the lamp in the room, without branching on either. */
body.no-scroll { overflow: hidden; }

.keydlg-scrim {
  position: fixed; inset: 0;
  z-index: var(--z-toast);
  background: var(--scrim);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  animation: pageIn var(--t-med) linear both;
}
.keydlg {
  position: fixed;
  z-index: calc(var(--z-toast) + 1);
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(580px, calc(100vw - 2 * var(--sp-4)));
  max-height: calc(100dvh - 2 * var(--sp-5));
  overflow: auto;
  padding: var(--sp-6);
  background: var(--surface-inset);
  border: 1px solid var(--rule-strong);
  border-top: 2px solid var(--foil-rule);   /* the gilt edge of the leaf */
  border-radius: var(--r);
  box-shadow: var(--shadow-paper);
  animation: pageIn var(--t-med) linear both;
}
.keydlg-x {
  position: absolute; top: var(--sp-3); right: var(--sp-3);
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r);
  font-size: var(--fs-sm);
  color: var(--text-tertiary);
  transition: color var(--t-fast) var(--ease-out);
}
.keydlg-x:hover { color: var(--text-primary); }
.keydlg-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  margin: var(--sp-3) 0 var(--sp-3);
  padding-right: var(--sp-6);
}
.keydlg-lede { color: var(--text-secondary); font-size: var(--fs-sm); }
.keydlg-facts {
  margin: var(--sp-4) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.keydlg-facts li {
  position: relative;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-5);
  border-top: 1px solid var(--rule-faint);
}
.keydlg-facts li:first-child { border-top: 0; }
.keydlg-facts li::before {
  content: "·";
  position: absolute; left: var(--sp-2);
  color: var(--foil);
}
.keydlg-facts b { color: var(--text-primary); font-weight: 500; }

.keydlg-saved {
  margin-top: var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-well);
  border-left: 2px solid var(--foil-rule);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.keydlg-saved b { font-family: var(--font-mono); letter-spacing: 0; text-transform: none; color: var(--text-primary); }

.keydlg-form { margin-top: var(--sp-5); }
.keydlg-label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.keydlg-form .input { font-family: var(--font-mono); font-size: var(--fs-sm); }
.keydlg-actions { display: flex; gap: var(--sp-3); margin-top: var(--sp-4); flex-wrap: wrap; }

.keydlg-note {
  margin-top: var(--sp-4);
  padding: var(--sp-3);
  border-radius: var(--r);
  font-size: var(--fs-sm);
  border: 1px solid var(--rule);
  color: var(--text-secondary);
}
.keydlg-note-good { border-color: var(--sig-good-rule); background: var(--sig-good-wash); color: var(--sig-good); }
.keydlg-note-bad { border-color: var(--sig-bad-rule); background: var(--sig-bad-wash); color: var(--sig-bad); }

.keydlg-help {
  margin-top: var(--sp-5);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
  font-size: var(--fs-xs);
  color: var(--text-tertiary);
}
.keydlg-help a { border-bottom: 1px solid var(--foil-rule); color: var(--text-secondary); }
.keydlg-help a:hover { color: var(--text-primary); }

/* ── comprehension: the register of play, the payoff matrix, the glossary ─
   Nobody should have to hover, guess, or leave the room to find out what the
   room does. Three components, reused on every surface that needs them. ── */

/* the payoff matrix — the consequences, printed beside the decision */
.payoffs-box { margin-top: var(--sp-4); }
.payoffs-h {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.payoffs {
  margin: var(--sp-2) 0 0;
  border-top: 1px solid var(--rule);
  font-variant-numeric: tabular-nums;
}
.po-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: var(--sp-3);
  align-items: baseline;
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm);
  line-height: 1.45;
}
.po-row dt { font-weight: 500; color: var(--text-primary); }
.po-row dd { margin: 0; color: var(--text-secondary); }
.po-good dt { color: var(--sig-good); }
.po-bad dt { color: var(--sig-bad); }

/* the rule card: fifteen words, at the table, without leaving it */
.table-rule {
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--text-secondary);
  border-left: 2px solid var(--foil-rule);
  padding-left: var(--sp-3);
}
.table-rule a { color: var(--text-primary); border-bottom: 1px solid var(--foil-rule); white-space: nowrap; }
.table-brief { margin-top: var(--sp-2); }
/* a sentence, not a label: the caps treatment next door is for headings */
.blind-note { margin-top: var(--sp-2); }
.setup-hint-block { display: block; margin-left: 0; text-transform: uppercase; letter-spacing: var(--track-label); font-size: var(--fs-xs); color: var(--text-tertiary); }

/* the glossary — powers, handicaps and axes explaining themselves in words */
.gloss {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4) var(--sp-5);
  margin: var(--sp-3) 0 0;
}
.gloss-item { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-1); min-width: 0; }
.gloss-item dd { margin: 0; font-size: var(--fs-sm); line-height: 1.5; color: var(--text-secondary); }
.gloss-item dd b { color: var(--text-primary); font-weight: 500; }
.gloss-term {
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-primary);
}
/* at the table only the rig in play is listed, one line each */
.gloss-inplay { grid-template-columns: 1fr; gap: var(--sp-2); }
.gloss-inplay .gloss-item { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2); }
.gloss-inplay dd { font-size: var(--fs-xs); }

/* the register of play */
.rules-lede {
  max-width: var(--measure);
  font-size: var(--fs-lg);
  line-height: 1.55;
  color: var(--text-secondary);
}
.rules-toc { margin-top: var(--sp-5); }
a.chip:hover { border-color: var(--text-secondary); color: var(--text-primary); }
.rule-entry {
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--rule);
  scroll-margin-top: 92px;         /* the masthead is sticky */
}
.rule-entry h3 { font-family: var(--font-display); font-size: var(--fs-2xl); }
.rule-entry h4 {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-top: var(--sp-5);
}
.rule-sub {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-lg);
  color: var(--text-secondary);
  margin-top: var(--sp-1);
}
.rule-body {
  max-width: var(--measure);
  margin-top: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.rule-body b { color: var(--text-primary); font-weight: 500; }
.rule-list {
  max-width: var(--measure);
  margin: var(--sp-3) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.rule-list li { padding: var(--sp-1) 0 var(--sp-1) var(--sp-4); position: relative; border-top: 1px solid var(--rule-faint); }
.rule-list li:first-child { border-top: 0; }
.rule-list li::before { content: "·"; position: absolute; left: var(--sp-1); color: var(--foil); }
.rule-reveals {
  max-width: var(--measure);
  margin-top: var(--sp-4);
  padding-left: var(--sp-4);
  border-left: 2px solid var(--foil-rule);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
/* a run-in head: "WHAT IT REVEALS · whether a promise…" keeps RULES.md's
   own sentence, which starts lower case, reading as a sentence */
.rule-reveals-h {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.rule-reveals-h::after { content: " · "; letter-spacing: 0; }
.rule-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-5); }
.not-dealt {
  display: inline-block;
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-tertiary);
  border: 1px dashed var(--rule-strong);
  border-radius: var(--r);
  padding: 2px var(--sp-3);
  margin-bottom: var(--sp-3);
}
.empire-details { margin-top: var(--sp-5); }
.empire-details summary {
  list-style: none;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--foil-rule);
  padding-bottom: 2px;
  cursor: pointer;
}
.empire-details summary::-webkit-details-marker { display: none; }
.empire-details summary::before { content: "▸"; color: var(--text-tertiary); }
.empire-details[open] summary::before { content: "▾"; }
.empire-details summary:hover { color: var(--text-primary); }
.empire-body { margin-top: var(--sp-4); }

/* ── responsive ───────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .seg { grid-template-columns: repeat(2, 1fr); }
  .seg-slim { grid-template-columns: repeat(2, 1fr); }
  .game-grid { grid-template-columns: 1fr; }
  .idx { --idx-grid: none; }
  .idx-head { display: none; }
  .idx-row {
    grid-template-columns: 2rem 1fr auto;
    grid-template-areas:
      "rank player earn"
      "axes axes axes"
      "corr corr matches";
    row-gap: var(--sp-3);
    column-gap: var(--sp-3);
  }
  .idx-rank { grid-area: rank; }
  .idx-player { grid-area: player; }
  .idx-earn { grid-area: earn; text-align: right; }
  .idx-matches { grid-area: matches; text-align: right; }
  .idx-corr { grid-area: corr; }
  .idx-axes { grid-area: axes; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3) var(--sp-2); }
}
@media (max-width: 640px) {
  /* nav: wordmark + mode pill on row 1, links as one scrollable row 2 */
  .topnav-in { row-gap: var(--sp-2); }
  .wordmark { margin-right: auto; font-size: 1.16rem; }
  /* "LIVE · your key" is a long label; tighten it so the masthead stays two
     rows (wordmark + pill, then the links) instead of three */
  #mode-pill { order: 2; letter-spacing: .06em; padding: 2px var(--sp-2); gap: var(--sp-1); }
  .nav-links {
    order: 3;
    width: 100%;
    margin-right: 0;
    gap: var(--sp-4);
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .nav-links::-webkit-scrollbar { display: none; }
  .nav-link { flex: 0 0 auto; }
}
@media (max-width: 620px) {
  #view { padding-top: var(--sp-4); }
  .card { padding: var(--sp-4); }
  .receipt { padding: var(--sp-4); }
  .rig-cols { grid-template-columns: 1fr; }
  .teaser-row { grid-template-columns: 1.4rem 1fr 4.6rem; }
  .t-bar, .t-coop { display: none; }
  .msg-row { flex-direction: column; }
  .payoff-row { gap: var(--sp-4); }
  .btn-xl { width: 100%; }
  .choice-row { gap: var(--sp-2); }
  .btn-choice { min-height: 70px; }
  .pips { flex-wrap: wrap; }
  .mc-vs { white-space: normal; }
  .reveal-actions { flex-direction: column; align-items: stretch; }
  .reveal-actions .btn { width: 100%; }
  .watch-actions { flex-wrap: wrap; }
  .rig-selects { flex-direction: column; }
  .runhead .rh-no { margin-left: 0; width: 100%; }
  .keydlg { padding: var(--sp-5) var(--sp-4) var(--sp-4); }
  .keydlg-actions .btn { width: 100%; }
  /* two text columns are too narrow to read at this width — stack them */
  .po-row { grid-template-columns: 1fr; gap: 0; }
  .po-row dd { padding-left: var(--sp-3); }
  .gloss { grid-template-columns: 1fr; gap: var(--sp-3); }
}

/* ── reduced motion ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  html { scroll-behavior: auto; }
}

/* ══════════════════════════════════════════════════════════════════════
   THE SHOWDOWN
   Two hands face-down, a held beat, then they turn over together. This is
   the only sustained motion in the product; §6 of DESIGN.md cut everything
   else back to near-silence so that this one gesture lands.
   ══════════════════════════════════════════════════════════════════════ */
.showdown {
  position: relative;
  padding: var(--sp-7) var(--sp-4) var(--sp-6);
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-5);
  cursor: default;
}
/* the overhead pool, tightening while the room waits */
.showdown::before {
  content: ""; position: absolute; inset: -8% -4%;
  background: radial-gradient(58% 62% at 50% 42%, rgba(239,231,216,.09), transparent 70%);
  transform: scale(1.18); opacity: 0;
  transition: transform 1100ms var(--ease-out), opacity 700ms var(--ease-out);
  pointer-events: none;
}
.showdown[data-phase="lock"]::before { transform: scale(1); opacity: 1; }
.showdown[data-phase="flip"]::before,
.showdown[data-phase="pay"]::before { transform: scale(1.05); opacity: 1; }

.showdown-table {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; justify-items: center;
  gap: clamp(var(--sp-4), 4vw, var(--sp-7));
  width: 100%; max-width: 620px;
  perspective: 1100px;
}

/* ── the nameplate: presence without a face ── */
.hand { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); min-width: 0; }
.nameplate { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); min-width: 0; max-width: 100%; }
.monogram {
  display: grid; place-items: center;
  width: 30px; height: 30px;
  font-family: var(--font-stamp); font-size: var(--fs-sm); line-height: 1;
  color: var(--text-secondary);
  border: 1px solid var(--foil-rule);
  border-radius: var(--r);
}
.nameplate-who {
  font-size: var(--fs-xs); letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-secondary); text-align: center;
  max-width: 20ch; overflow-wrap: anywhere; text-wrap: balance;
}

/* ── the card ── */
.flipper {
  position: relative;
  width: clamp(88px, 24vw, 132px); aspect-ratio: 3 / 4;
  transform-style: preserve-3d;
  transition: transform var(--flip-ms, 560ms) var(--ease-expo);
}
.showdown[data-phase="flip"] .flipper,
.showdown[data-phase="pay"] .flipper { transform: rotateY(180deg); }

/* A hand that was never secret is dealt face-up and never turns: an ultimatum
   responder can read the offer before they answer it, so a card going over
   would be the theatre claiming a suspense that did not exist. Same angle in
   every phase means the transform never changes and nothing animates. */
.hand-open .flipper { transform: rotateY(180deg); }

.face {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--sp-1);
  border-radius: var(--r);
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  text-align: center; padding: var(--sp-2);
}
.face-back {
  background: var(--surface-inset);
  border: 1px solid var(--rule-strong);
  background-image: repeating-linear-gradient(135deg,
    var(--foil-rule) 0 1px, transparent 1px 7px);
  background-blend-mode: overlay;
  opacity: .92;
}
.face-front {
  transform: rotateY(180deg);
  background: var(--surface-inset);
  border: 1px solid currentColor;
  font-family: var(--font-stamp);
  font-size: clamp(.82rem, 3.1vw, 1.12rem);
  letter-spacing: .05em; text-transform: uppercase; line-height: 1.05;
}
.face-word { font: inherit; letter-spacing: inherit; }
/* the verb under the figure: $60 and $45 facing each other are two numbers
   with no story until one says "wired" and the other says "sent back" */
.face-note {
  font-family: var(--font-body); font-size: var(--fs-xs); font-weight: 400;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-tertiary);
}
.face-note:empty { display: none; }
.face-good { color: var(--sig-good); }
.face-bad  { color: var(--sig-bad); }
/* a sum that was staked rather than judged — an offer, a wire — carries the
   page's own ink, because colouring it would be scoring it */
.face-flat { color: var(--text-primary); }

/* ── the pot: an object on the table, not a caption ── */
.pot { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); min-width: 5.5ch; }
.pot-label {
  font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-tertiary);
  transition: opacity 400ms var(--ease-out);
}
.pot-figure {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-xl); color: var(--text-primary); line-height: 1;
  transition: opacity 420ms var(--ease-out), filter 520ms var(--ease-out);
}
.pot-slip {
  position: absolute; top: 50%; left: 50%;
  margin-top: -.5em;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-xl); line-height: 1; white-space: nowrap;
  opacity: 0; transform: translate(-50%, 0);
  transition: opacity 360ms var(--ease-out), transform 700ms var(--ease-expo);
  pointer-events: none;
}
/* The zero is not an absence, it is the result. Hiding it left a steal
   reading as one number floating beside two cards, with nothing to say the
   other player walked away with nothing. */
.pot-slip.is-nil { color: var(--text-tertiary); opacity: .75; }
.pot-strike {
  position: absolute; top: 50%; left: -6%; width: 112%; height: 2px;
  background: var(--sig-bad);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 460ms var(--ease-expo);
}

/* the money moves, and only then */
.showdown[data-phase="pay"] .pot-label { opacity: 0; }
.showdown[data-phase="pay"] .pot-slip { opacity: 1; }
.showdown[data-phase="pay"] .pot-slip-l { transform: translate(-50%, 0) translateX(clamp(-86px, -8vw, -30px)); }
.showdown[data-phase="pay"] .pot-slip-r { transform: translate(-50%, 0) translateX(clamp(30px, 8vw, 86px)); }
.showdown[data-phase="pay"] .pot-figure { opacity: .22; }

/* the colour follows the WORD, not the winner: money that was taken reads red
   even when taking it made the larger pile */
.pot-slip.slip-good { color: var(--sig-good); }
.pot-slip.slip-bad  { color: var(--sig-bad); }

/* both steal: the entry is struck out, the way a ledger cancels one */
.showdown[data-outcome="burned"][data-phase="pay"] .pot-slip { opacity: 0; }
.showdown[data-outcome="burned"][data-phase="pay"] .pot-figure { opacity: .45; filter: grayscale(1); }
.showdown[data-outcome="burned"][data-phase="pay"] .pot-strike { transform: scaleX(1); }

.showdown-line {
  min-height: 1.4em; margin: 0;
  font-size: var(--fs-sm); color: var(--text-secondary);
  letter-spacing: .01em;
}

@media (max-width: 460px) {
  .showdown { padding: var(--sp-6) var(--sp-2) var(--sp-5); }
  .showdown-table { gap: var(--sp-3); }
  .monogram { width: 26px; height: 26px; }
  /* 11ch broke the app's own default label mid-word — CONTEST | ANT B — because
     a ch is measured on "0" while this line is tracked uppercase, which runs far
     wider: "Contestant" measures 94px against 11ch = 71px. Measured in place,
     not from a probe on the body, which reported a pre-webfont 8.22px/ch and
     sent the first two attempts at this the wrong way. `anywhere` above is still
     the last resort for an unbreakable model id. */
  .nameplate-who { max-width: 15ch; }
  /* a narrower gap needs a narrower note, or the money lands on the card */
  .pot-slip { font-size: var(--fs-lg); }
}

@media (prefers-reduced-motion: reduce) {
  .showdown::before, .flipper, .pot-figure, .pot-slip, .pot-strike, .pot-label { transition: none; }
}

/* ── the ledger: five rounds as a relationship, not a list ─────────────── */
.ledger {
  width: 100%; border-collapse: collapse;
  margin-bottom: var(--sp-4);
  font-size: var(--fs-xs);
}
.lg-cap {
  text-align: left; padding-bottom: var(--sp-2);
  font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-tertiary);
}
.ledger th, .ledger td { padding: var(--sp-1) var(--sp-2); text-align: left; border-bottom: 1px solid var(--rule-faint); }
.ledger thead th { font-weight: 400; letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary); }
.ledger tbody th, .ledger tfoot th { font-weight: 400; color: var(--text-tertiary); font-family: var(--font-mono); }
.lg-cash { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.lg-move { text-transform: uppercase; letter-spacing: .04em; }
.lg-coop { color: var(--sig-good); }
.lg-defect { color: var(--sig-bad); }
.lg-todo td, .lg-todo th { color: var(--text-tertiary); opacity: .5; }
.lg-now td { color: var(--text-secondary); letter-spacing: var(--track-label); text-transform: uppercase; font-size: var(--fs-xs); }
.ledger tfoot th, .ledger tfoot .lg-cash { border-bottom: 0; border-top: 1px solid var(--foil-rule); color: var(--text-primary); }
/* a defection that answers a defection: a grudge, not a strategy */
.lg-grudge { margin-left: .35em; text-decoration: none; border: 0; color: var(--text-tertiary); cursor: help; }
.lg-head-group th { border-bottom: 0; padding-bottom: 0; color: var(--text-secondary); }
.lg-head-group + tr th { padding-top: 0; }

/* ── lines arrive, they do not appear ─────────────────────────────────── */
@keyframes line-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.is-arriving {
  animation: line-in 240ms var(--ease-out) backwards;
  animation-delay: calc(var(--in, 0) * 420ms);
}
@media (prefers-reduced-motion: reduce) { .is-arriving { animation: none; } }

/* ── the rules: a plate per game, readable in one pass ────────────────── */
.rule-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3);
  padding-bottom: var(--sp-2); margin-bottom: var(--sp-3);
  border-bottom: 1px solid var(--foil-rule);
}
.rule-num {
  font-family: var(--font-display); font-size: var(--fs-lg); line-height: 1;
  color: var(--text-tertiary); letter-spacing: .08em;
}
.rule-seats {
  font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-tertiary); text-align: right;
}
.rule-entry + .rule-entry { margin-top: var(--sp-7); }
.mb-n { font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-tertiary); font-variant-numeric: tabular-nums; }
.microbar-empty .mb-val { font-size: var(--fs-xs); letter-spacing: .04em; text-transform: none; }

/* ══════════════════════════════════════════════════════════════════════
   EMPIRE — the long game, watched
   The gallery already had the chrome for a feed of cards, so this adds only
   what Empire has that a two-seat match does not: a live net-worth board, a
   private channel a spectator is allowed to read, and an honesty line that
   states how many answers actually came from the models.
   ══════════════════════════════════════════════════════════════════════ */
.seg-long .seg-sub {
  display: block;
  font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-tertiary);
}
.emp-seats { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.emp-seat {
  display: inline-flex; align-items: baseline; gap: var(--sp-2);
  border: 1px solid var(--rule); border-radius: var(--r);
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm); color: var(--text-secondary);
}
.emp-seat b {
  font-family: var(--font-stamp); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-primary);
}

/* The one line that says whether you are watching models or a script. Never
   in a hover, never smaller than the thing it qualifies. */
.emp-honesty {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-tertiary);
}
.emp-honesty.is-bad { color: var(--sig-bad); }
.emp-n { color: var(--text-tertiary); text-transform: none; letter-spacing: 0; }

/* who is winning, answerable at a glance — SPEC's own test for this view */
.emp-board { display: flex; flex-direction: column; margin-bottom: var(--sp-4); }
.emp-row {
  display: grid; grid-template-columns: minmax(7rem, 1fr) 2fr auto;
  align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
}
.emp-row:last-child { border-bottom: 0; }
.emp-who { display: flex; flex-direction: column; min-width: 0; }
.emp-who b {
  font-family: var(--font-stamp); font-size: var(--fs-sm);
  letter-spacing: var(--track-label); text-transform: uppercase;
}
.emp-model { font-size: var(--fs-xs); color: var(--text-tertiary); overflow-wrap: anywhere; }
.emp-bar { display: block; height: 6px; background: var(--rule); border-radius: 999px; overflow: hidden; }
.emp-bar i { display: block; height: 100%; width: var(--w, 0%); background: var(--text-secondary); transition: width 600ms var(--ease-out); }
.emp-lead .emp-bar i { background: var(--text-primary); }
.emp-net {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-lg); text-align: right; line-height: 1.1;
}
.emp-sub { display: block; font-size: var(--fs-xs); color: var(--text-tertiary); font-family: var(--font-body); }

/* ── the relationship plate ────────────────────────────────────────────────
   SPEC §7's primary visual, in the archive register: an engraved plate, not a
   force-directed blob. Four seats always in the same four places. The one
   semantic that must never slip is dashed vs solid — dashed is what was SAID,
   solid is what actually MOVED — so nothing here may thicken a dashed line. */
.emp-graph { margin: 0 0 var(--sp-5); }
.eg-title {
  margin-bottom: var(--sp-2);
  font-family: var(--font-stamp); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary);
}
.eg-plate {
  display: block; width: 100%; height: auto;
  max-width: 600px; margin: 0 auto var(--sp-2);
}
.eg-arc { fill: none; stroke-linecap: round; }
.eg-talk { stroke: var(--text-tertiary); stroke-dasharray: 3 3.4; }
.eg-kept { stroke: var(--sig-good); }
.eg-harm { stroke: var(--sig-bad); }
.eg-tip { stroke: none; }
.eg-tip-talk { fill: var(--text-tertiary); }
.eg-tip-kept { fill: var(--sig-good); }
.eg-tip-harm { fill: var(--sig-bad); }
.eg-barb {
  fill: none; stroke: var(--sig-bad); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.eg-barb.is-landed { fill: var(--sig-bad); }
.eg-cut { stroke: var(--sig-bad); stroke-width: 1.8; stroke-linecap: butt; }
.eg-cut-halo { stroke: var(--surface-page); stroke-width: 4.4; stroke-linecap: butt; }
.eg-node rect { fill: var(--surface-page); stroke: var(--rule-strong); stroke-width: 1; }
.eg-name {
  text-anchor: middle; font-family: var(--font-stamp); font-size: 11px;
  letter-spacing: .08em; fill: var(--text-primary);
}
.eg-net {
  text-anchor: middle; font-family: var(--font-mono); font-size: 10px;
  font-variant-numeric: tabular-nums; fill: var(--text-secondary);
}

.eg-key {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  margin-bottom: var(--sp-3);
  font-size: var(--fs-xs); color: var(--text-secondary);
}
.eg-key span { display: inline-flex; align-items: center; gap: var(--sp-2); }
.eg-key svg { width: 30px; height: 12px; flex: none; }
.eg-none { font-size: var(--fs-sm); color: var(--text-tertiary); text-align: center; }

.eg-scroll { overflow-x: auto; }
.eg-ledger { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.eg-ledger caption {
  text-align: left; padding-bottom: var(--sp-1);
  font-size: var(--fs-xs); letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--text-tertiary);
}
.eg-ledger th, .eg-ledger td {
  padding: var(--sp-1) var(--sp-2); border-top: 1px solid var(--rule);
  text-align: right; white-space: nowrap;
}
.eg-ledger thead th {
  border-top: 0; border-bottom: 1px solid var(--rule-strong);
  font-family: var(--font-stamp); font-weight: 400; font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary);
}
.eg-ledger tbody th, .eg-ledger thead th:first-child {
  text-align: left; padding-left: 0;
}
.eg-ledger tbody th { font-weight: 500; color: var(--text-primary); }
.eg-ledger td { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--text-secondary); }
.eg-ledger small {
  display: block; font-family: var(--font-body);
  font-size: var(--fs-xs); color: var(--text-tertiary);
}
.eg-ledger td:last-child { padding-right: 0; }
.eg-ledger .is-broken th { color: var(--sig-bad); }

@media (max-width: 480px) {
  /* five nowrap columns of tabular numerals will not fit a 343px strip at body
     size; tracked-out uppercase headers are what costs the most, so they go */
  .eg-ledger { font-size: var(--fs-xs); }
  .eg-ledger th, .eg-ledger td { padding: var(--sp-1); }
  .eg-ledger thead th { letter-spacing: 0; }
}

/* a spectator reads the private channel; the players never do */
/* Empire's talk is short and it is the point, so it does not live in a
   scrolling well: at transcript-mini's 320px the entire private channel sat
   below the fold of its own box and never once appeared on screen. */
.emp-talk { max-height: none; overflow: visible; }
.bubble-private { border-style: dashed; }
.emp-priv {
  font-family: var(--font-stamp); font-size: 9px;
  letter-spacing: .1em; color: var(--sig-bad);
}
.emp-deals, .emp-raids, .emp-breaches {
  list-style: none; margin: var(--sp-3) 0 0; padding: 0;
  font-size: var(--fs-sm); color: var(--text-secondary);
}
.emp-deals li, .emp-raids li, .emp-breaches li { padding: var(--sp-1) 0; border-top: 1px solid var(--rule); }
.emp-tag {
  display: inline-block; margin-right: var(--sp-2);
  font-family: var(--font-stamp); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary);
}
.emp-tag-pledge { color: var(--sig-bad); }
.emp-turn { font-family: var(--font-mono); color: var(--text-tertiary); }
.emp-mark {
  margin-left: var(--sp-3);
  font-family: var(--font-stamp); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--sig-bad);
}

/* the reveal: all four actions at once, which is the rule the game runs on */
.emp-reveal { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.emp-act {
  display: inline-flex; align-items: baseline; gap: var(--sp-2);
  border: 1px solid var(--rule); border-radius: var(--r);
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--fs-sm); color: var(--text-secondary);
}
.emp-act b {
  font-family: var(--font-stamp); font-size: var(--fs-xs);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-primary);
}
.emp-act-raid { border-color: var(--sig-bad-rule); color: var(--sig-bad); }
.emp-act-fortify { border-color: var(--rule-strong); }
.emp-verdict { margin-bottom: var(--sp-4); }

@media (max-width: 560px) {
  .emp-row { grid-template-columns: 1fr auto; }
  .emp-bar { grid-column: 1 / -1; order: 3; }
}

/* ── the nav strip on a genuinely narrow phone ─────────────────────────────
   At ≤640 the masthead is designed as a single horizontally scrollable row
   with the scrollbar hidden — which is fine when everything fits, and at 375
   it now does (measured: 343px of content in a 343px strip). Below that it
   does not, and a hidden scrollbar means the last item is simply gone with
   nothing to say so: at 320 "THE INDEX" sat 55px past the edge. Let it wrap
   instead. Two short rows hide nothing, and this rule sits last on purpose —
   the ≤640 block that sets nowrap comes later in the file than the ≤480 one. */
@media (max-width: 380px) {
  .nav-links { flex-wrap: wrap; overflow-x: visible; row-gap: var(--sp-1); }
}

/* ═══ THE ARCHIVE PRINTS ITSELF — motion at the moment a turn lands ═════
   Empire is a game, and a landed turn should FEEL like one: the plate
   engraves its arcs, the standings measure themselves out, the fresh
   turn card prints and then reads aloud — talk, deals, the reveal, the
   raids, the damage — in the order a turn actually happens.
   The feed repaints exactly once per landed turn (the signature skip),
   so every entrance here fires once, at the right moment, never on a
   poll. Plate animations are scoped to .eg-plate because the key's
   little legend SVGs share the arc classes and must hold still; card
   animations are scoped to the fresh card so closed history stays put.
   Reduced motion gets the finished state instantly. */
@media (prefers-reduced-motion: no-preference) {
  /* solid arcs draw themselves; pathLength=1 in the SVG normalises the
     pace so a short arc and a long one finish together */
  .eg-plate .eg-kept, .eg-plate .eg-harm {
    stroke-dasharray: 1;
    animation: eg-engrave 620ms var(--ease-out) both;
    animation-delay: calc(var(--arc-i, 0) * 70ms);
  }
  /* dashed talk arcs keep their dash pattern and surface instead */
  .eg-plate .eg-talk {
    animation: eg-surface 460ms linear both;
    animation-delay: calc(var(--arc-i, 0) * 70ms);
  }
  /* heads, barbs and ticks land only after their line has arrived */
  .eg-plate .eg-tip, .eg-plate .eg-barb, .eg-plate .eg-cut, .eg-plate .eg-cut-halo {
    animation: eg-surface 220ms var(--ease-out) both;
    animation-delay: calc(var(--arc-i, 0) * 70ms + 460ms);
  }
  /* the standings re-measure themselves on every landed turn */
  .emp-board .emp-bar i { animation: emp-measure 640ms var(--ease-out) both; }

  /* the fresh turn card prints… */
  .mc-fresh { animation: paperSettle 460ms var(--ease-out) both; }
  /* …then reads aloud. Fixed phase offsets, nth-child stagger inside each
     family; anything past the eighth line shares the last beat. */
  .mc-fresh .emp-talk .bubble { animation: line-in 240ms var(--ease-out) both; animation-delay: 990ms; }
  .mc-fresh .emp-talk .bubble:nth-child(1) { animation-delay: 220ms; }
  .mc-fresh .emp-talk .bubble:nth-child(2) { animation-delay: 330ms; }
  .mc-fresh .emp-talk .bubble:nth-child(3) { animation-delay: 440ms; }
  .mc-fresh .emp-talk .bubble:nth-child(4) { animation-delay: 550ms; }
  .mc-fresh .emp-talk .bubble:nth-child(5) { animation-delay: 660ms; }
  .mc-fresh .emp-talk .bubble:nth-child(6) { animation-delay: 770ms; }
  .mc-fresh .emp-talk .bubble:nth-child(7) { animation-delay: 880ms; }
  .mc-fresh .emp-deals li { animation: line-in 240ms var(--ease-out) both; animation-delay: 1180ms; }
  .mc-fresh .emp-deals li:nth-child(1) { animation-delay: 900ms; }
  .mc-fresh .emp-deals li:nth-child(2) { animation-delay: 970ms; }
  .mc-fresh .emp-deals li:nth-child(3) { animation-delay: 1040ms; }
  .mc-fresh .emp-deals li:nth-child(4) { animation-delay: 1110ms; }
  /* the REVEAL — four hands turning over is the whole mechanic */
  .mc-fresh .emp-reveal { perspective: 520px; }
  .mc-fresh .emp-act {
    animation: chip-reveal 340ms var(--ease-out) both;
    transform-origin: 50% 100%;
    animation-delay: 1250ms;
  }
  .mc-fresh .emp-act:nth-child(2) { animation-delay: 1340ms; }
  .mc-fresh .emp-act:nth-child(3) { animation-delay: 1430ms; }
  .mc-fresh .emp-act:nth-child(4) { animation-delay: 1520ms; }
  .mc-fresh .emp-raids li { animation: line-in 240ms var(--ease-out) both; animation-delay: 1750ms; }
  .mc-fresh .emp-raids li:nth-child(2) { animation-delay: 1850ms; }
  .mc-fresh .emp-raids li:nth-child(3) { animation-delay: 1950ms; }
  .mc-fresh .emp-breaches li { animation: line-in 240ms var(--ease-out) both; animation-delay: 2050ms; }
  .mc-fresh .emp-breaches li:nth-child(2) { animation-delay: 2130ms; }
  .mc-fresh .emp-breaches li:nth-child(3) { animation-delay: 2210ms; }

  /* the verdict prints like the receipt it is */
  .emp-verdict { animation: paperSettle 460ms var(--ease-out) both; }
}
@keyframes eg-engrave { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes eg-surface { from { opacity: 0; } to { opacity: 1; } }
@keyframes emp-measure { from { width: 0; } }
@keyframes chip-reveal { from { opacity: 0; transform: rotateX(64deg); } to { opacity: 1; transform: none; } }
