/* ══ THE TWO NEW INSTRUMENTS ════════════════════════════════════════════════
   The reading-speed ceiling (rsvp_ceiling) and the chess column. Numbered 18 so
   it lands after 17-gate.css; the NN- prefix IS the cascade, and both surfaces
   have to out-specify the pre-broadsheet drill sheet at 05.

   Both belong to the same paper as everything else, so neither invents a
   device: the chess column takes the back page's ruled head and dotted-leader
   list, and the reading window takes the practice masthead's habit of setting
   instrumentation in mono agate under a rule. Nothing here is a card.

   TWO STANDING TRAPS, honoured throughout:
     * Type is never muted with opacity — alpha erases on this stock instead of
       muting, and it has broken AA here repeatedly. Recede with --bs-ink-3 at
       full opacity.
     * --bs-camel is 2.13:1 and NEVER carries type. Camel where it is seen,
       bronze (--bs-blue) where it is read.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══ RSVP — the reading-speed ceiling ══════════════════════════════════════
   The drill stage is the one screen that is NOT .bs, so these selectors are
   unscoped like the rest of 05-drills.css. The tokens are global, so the page
   is newsprint regardless. */

/* The word window. A ruled band with one fixation mark above it, and nothing
   else inside — every other element on this screen is outside the band, so the
   eye has no reason to leave the fixation point mid-stream. */
.rsvp-window {
  width: 100%;
  max-width: 620px;
  margin: 18px 0 6px;
  padding: 0 0 4px;
  border-top: 3px solid var(--bs-ink);
  border-bottom: 1px solid var(--bs-ink);
}
/* The fixation mark: a short camel rule directly over the pivot column. Camel
   is legitimate here because it is SEEN, not read. */
.rsvp-mark {
  width: 2px;
  height: 9px;
  margin: 0 auto;
  background: var(--bs-camel-deep);
  transform: translateX(0);
}
/* Three cells — [pre][pivot][post] — with pre right-aligned and post
   left-aligned. That is what pins the pivot GLYPH to the same x for every word.
   A single centred word instead is the classic mistake: long words shove their
   own recognition point off the fixation and the eye starts hunting again. */
.rsvp-line {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
  min-height: 92px;
  padding: 16px 0 10px;
  font-family: var(--bs-ed);
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
  font-weight: 700;
  font-size: clamp(30px, 6.2vw, 52px);
  line-height: 1;
  letter-spacing: -.015em;
  color: var(--bs-ink);
  /* The stream must never reflow mid-word or the fixation moves. */
  white-space: pre;
}
.rsvp-pre { text-align: right; }
.rsvp-post { text-align: left; }
/* The recognition point, in the reader's own pen. This is the marginalia red
   already used for marks on the page, and it reads at full opacity. */
.rsvp-orp { color: var(--bs-pen); }

.rsvp-question {
  width: 100%;
  max-width: 620px;
  margin: 4px 0 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--bs-ink);
  font-family: var(--bs-ed);
  font-variation-settings: 'WONK' 1;
  font-weight: 900;
  font-size: clamp(19px, 2.6vw, 24px);
  line-height: 1.22;
  letter-spacing: -.02em;
  color: var(--bs-ink);
}

.rsvp-choices {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 620px;
}
/* Ballot rows, not cards: a rule between entries and a lettered stub, matching
   how the question page sets its choices. */
.rsvp-choice {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  align-items: baseline;
  gap: 12px;
  width: 100%;
  padding: 13px 6px;
  background: transparent;
  border: none;
  border-bottom: 1px dotted var(--bs-rule);
  border-radius: 0;
  text-align: left;
  font: inherit;
  color: var(--bs-ink);
  cursor: pointer;
  transition: background .12s ease, transform .12s ease;
}
.rsvp-choice:hover { background: var(--bs-sheet); transform: translateX(6px); }
.rsvp-choice:active { transform: translateX(3px); }
.rsvp-choice:focus-visible { outline: 3px solid var(--bs-blue); outline-offset: 2px; background: var(--bs-sheet); }
.rsvp-choice-letter {
  font-family: var(--bs-mono);
  font-size: 11px;
  letter-spacing: .14em;
  color: var(--bs-blue);
}
.rsvp-choice-text {
  font-family: var(--bs-ui);
  font-size: 15px;
  line-height: 1.45;
}
/* State is a stamped ground plus a rule, never colour alone — --bs-ok sits only
   1.89:1 from the ink, so hue cannot carry the signal on this stock. */
.rsvp-choice.right { background: var(--green-bg); border-bottom-color: var(--green); }
.rsvp-choice.right .rsvp-choice-letter { color: var(--bs-ok); }
.rsvp-choice.wrong { background: var(--red-bg); border-bottom-color: var(--red); }
.rsvp-choice.wrong .rsvp-choice-letter { color: var(--bs-miss); }
/* The key, shown only after a miss. */
.rsvp-choice.key { border-bottom-color: var(--bs-ok); box-shadow: inset 3px 0 0 var(--bs-ok); }

/* The sentence the result panel is not allowed to lose. */
.rsvp-caveat {
  max-width: 380px;
  margin: 0 auto 14px;
  padding: 10px 0 0;
  border-top: 1px solid var(--bs-rule);
  font-family: var(--bs-ui);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--bs-ink-3);
}

@media (prefers-reduced-motion: reduce) {
  .rsvp-choice { transition-duration: .001s; }
}

/* ══ THE CHESS COLUMN ══════════════════════════════════════════════════════ */

/* .mg-body-inner is already this screen's scroller and .screen carries
   scrollbar-gutter: stable — making the screen a second scroller would reserve
   the gutter TWICE and shift the column sideways, the defect #global-bar's
   --sbw exists to prevent. */
#screen-chess .mg-body-inner { justify-content: flex-start; padding: 0; }

.chess-wrap {
  width: 100%;
  max-width: 1080px;
  padding: 0 28px 56px;
}

/* ── the column head, same as every ruled page ── */
/* .chess-rule stood here — a second hairline above the title, directly under
   .mg-topbar's own 1px border-bottom (05-drills.css). Board awkwardly placed
   "relative to the header" (Mark, §9) traced to this: the masthead's own rule
   is the separator, exactly the rule 02-chrome.css's page-head system already
   enforces everywhere it applies; chess carries its own masthead instead
   (DECISIONS-2026-08-09-AM §6 puts it out of that system's scope) and had
   independently grown the identical defect — the brand's own name printed
   once in the masthead label and once more twelve lines later, with a spare
   rule between them where the masthead's already closed the band. Deleted,
   not restyled, matching how .cog-rule was deleted rather than retuned. */
.chess-head { padding: 22px 0 0; margin-bottom: 22px; }
.chess-title {
  font-family: var(--bs-ed);
  font-variation-settings: 'SOFT' 0, 'WONK' 1;
  font-weight: 900;
  font-size: clamp(32px, 5vw, 52px);
  line-height: .9;
  letter-spacing: -.04em;
  color: var(--bs-ink);
  margin: 0;
}
.chess-folio {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin-top: 11px;
  padding: 7px 0 6px;
  border-top: 3px solid var(--bs-ink);
  border-bottom: 1px solid var(--bs-ink);
  font-family: var(--bs-mono);
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink-2);
}
.chess-folio-dot { color: var(--bs-rule); }
#chess-your-rating { color: var(--bs-blue); font-variant-numeric: tabular-nums; }

/* Diagram left, standings in the right-hand rail — the feedback page's split,
   because this is the same shape of page: one thing to work on, one column of
   notes beside it. */
.chess-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 292px;
  gap: 34px;
  align-items: start;
}

.chess-to-move {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bs-blue);
  margin: 0 0 10px;
}

/* ── the board ──
   Our own grid, not a library's. Squares are the paper's two grounds rather
   than a green-and-buff chess palette: the diagram is printed in the same ink
   as the rest of the page, which is exactly what a newspaper diagram is. */
/* THE BOARD IS IN THE FIRST TRACK, and that is the whole of the alignment.
   It used to be `auto minmax(0, max-content)` with the rank agate in track 1.
   An `auto` track is STRETCHED by leftover space and this frame is a block-level
   grid, so it is as wide as the diagram column; the board is max-content and
   capped at a 56px square, so it never grows. Every spare pixel in the column
   went to the rank track and the board was shoved to the far RIGHT of it.
   MEASURED before the change: the board's left ink edge sat 262px right of the
   page's left rule at 768, 192px at 1024, 248px at 1440 — not the ~16px the
   coordinates actually occupy, which is all it looks like at 320 where the
   column has no spare width to give away.

   With the board first, its 1.5px ink border starts at the frame's own left
   edge, the frame starts at the diagram column, and the diagram column starts
   at the page rule — so board.x IS rule.x, exactly, at every width, with no
   negative margin and no guess about how wide a 9px mono digit is.

   The rank agate moves to the right of the board rather than hanging into the
   page gutter. Hanging is the other exact answer and it was measured too: the
   digits are 6.31px of ink sitting 8px off the board, so a hang costs 14.31px
   against an 18px gutter at 320 — 3.7px of clearance, and off the page entirely
   if the mono fallback is any wider. Coordinates on the right is what lichess
   and chess.com both print, and it costs nothing. `auto` still stretches, but
   it now stretches into the gutter between the diagram and the standings rail,
   which is where slack belongs. */
.chess-board-frame {
  display: grid;
  grid-template-columns: minmax(0, max-content) auto;
  grid-template-rows: max-content max-content;
  gap: 5px;
  /* 72px -> 84px, Mark's call 2026-08-09: still "too small" after the first
     enlargement. MEASURED live before this change: the diagram column is
     698px at 1440 and 642px at 1024, but the board sat at a flat 578px at
     BOTH (the ceiling bound at both, since the vw term only overtakes it
     above 973px) — 83% of the 1440 column, 90% of the 1024 one, with the
     ranks agate absorbing 115px of pure stretch at 1440 that nothing was
     printed into. At 84 the board is 675px (8 squares + border): 97% of the
     1440 column, ranks left 23px, still clear of the 292px standings rail by
     the grid's own 34px gap. Same slope (7.4vw) as the last change, same
     reasoning: 768 and 320 already sit below the old crossover and stay
     exactly as they were; only 1024 also picks up a smaller vw-driven gain
     (578 -> ~606) since the new crossover (1135px) now sits above it. */
  --chess-sq: clamp(30px, 7.4vw, 84px);
}
.chess-board {
  grid-column: 1; grid-row: 1;
  display: grid;
  grid-template-rows: repeat(8, var(--chess-sq));
  border: 1.5px solid var(--bs-ink);
}
.chess-rank-row { display: grid; grid-template-columns: repeat(8, var(--chess-sq)); }

.chess-sq {
  position: relative;
  width: var(--chess-sq);
  height: var(--chess-sq);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 0;
  font: inherit;
  cursor: pointer;
  /* The board must not move under the cursor — a square that lifts or shifts
     makes the piece you are aiming at a moving target. Ground only. */
  transition: background .1s ease;
}
.chess-sq.light { background: var(--bs-sheet); }
.chess-sq.dark  { background: var(--bs-stock-2); }
/* All 64 squares had no hover affordance while every other control on the screen
   did (audit 2026-08-01; the board's three buttons all carry one). Ground only,
   per the note above — a lift or an inset ring would move the square you are
   aiming at. `hover: hover` so a touch device does not strand the last-tapped
   square in a hover state, which is the usual way this goes wrong.
   `.selected` and `.target` are declared after this and keep winning. */
@media (hover: hover) {
  .chess-sq:hover { background: color-mix(in srgb, var(--bs-blue) 14%, var(--bs-sheet)); }
  .chess-sq.dark:hover { background: color-mix(in srgb, var(--bs-blue) 20%, var(--bs-stock-2)); }
}
/* Inset so the ring never overlaps the neighbouring square and stays readable
   against both grounds. */
.chess-sq:focus-visible {
  outline: 3px solid var(--bs-blue);
  outline-offset: -3px;
  z-index: 2;
}
/* Figurine notation: outline glyphs for White, solid for Black, both in ink —
   the printed convention, and the reason no second colour is needed. */
.chess-piece {
  font-family: 'Segoe UI Symbol', 'Apple Symbols', 'Noto Sans Symbols 2', serif;
  font-size: calc(var(--chess-sq) * 0.78);
  line-height: 1;
  color: var(--bs-ink);
  pointer-events: none;
  user-select: none;
}
/* The picked-up piece: an ink stamp, the same device as the masthead toggle. */
.chess-sq.selected { background: var(--bs-ink); }
.chess-sq.selected .chess-piece { color: var(--bs-stock); }
/* A legal empty destination is a printed dot; a legal capture is a ring around
   the square. Both are marks on the board, not tinted grounds — a tint would
   read as another kind of square. */
.chess-sq.target::after {
  content: '';
  position: absolute;
  width: 26%;
  height: 26%;
  border-radius: 50%;
  background: var(--bs-camel-deep);
}
.chess-sq.target-capture::after {
  content: '';
  position: absolute;
  inset: 8%;
  border: 3px solid var(--bs-camel-deep);
  border-radius: 50%;
}

.chess-ranks, .chess-files {
  font-family: var(--bs-mono);
  font-size: 9px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}
/* Agate to the RIGHT of the board, set against it — `start`, not `end`, or the
   digits ride the stretched track out to the standings rail. */
.chess-ranks {
  grid-column: 2; grid-row: 1;
  display: grid;
  grid-template-rows: repeat(8, var(--chess-sq));
  align-items: center;
  justify-items: start;
  padding-left: 3px;
}
.chess-files {
  grid-column: 1; grid-row: 2;
  display: grid;
  grid-template-columns: repeat(8, var(--chess-sq));
  justify-items: center;
}

.chess-status {
  margin: 14px 0 0;
  max-width: 560px;
  font-family: var(--bs-ui);
  font-size: 14.5px;
  line-height: 1.45;
  color: var(--bs-ink-2);
  min-height: 21px;
}
.chess-status.good { color: var(--bs-ok); font-weight: 600; }
.chess-status.fail { color: var(--bs-miss); font-weight: 600; }

/* The key, printed only once the puzzle is over. */
.chess-themes {
  margin-top: 8px;
  font-family: var(--bs-mono);
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  min-height: 12px;
}

.chess-result { margin-top: 14px; }
.chess-result-line {
  padding-top: 12px;
  border-top: 2px solid var(--bs-ink);
  font-family: var(--bs-ed);
  font-variation-settings: 'WONK' 1;
  font-weight: 900;
  font-size: 19px;
  letter-spacing: -.02em;
  color: var(--bs-ink);
}

/* ── standings ──
   Its own board, and the ± is the point of it. */
.chess-standings {
  border-top: 3px solid var(--bs-ink);
  padding-top: 12px;
}
.chess-lb-head {
  font-family: var(--bs-mono);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bs-blue);
  margin: 0 0 10px;
}
.chess-lb-list { display: block; }
.chess-lb-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: 10px;
  row-gap: 1px;
  padding: 9px 2px;
  border-bottom: 1px dotted var(--bs-rule);
}
.chess-lb-row.you { background: var(--bs-sheet); box-shadow: inset 3px 0 0 var(--bs-blue); }
.chess-lb-rank {
  font-family: var(--bs-mono); font-size: 9.5px; letter-spacing: .08em;
  color: var(--bs-ink-3);
}
.chess-lb-handle {
  font-family: var(--bs-ui); font-size: 13.5px; color: var(--bs-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chess-lb-rating {
  font-family: var(--bs-mono); font-size: 11px; color: var(--bs-ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.chess-lb-rating b { font-weight: 600; }
/* The uncertainty, set as agate beside the figure. It recedes with ink, never
   with alpha, and it is never dropped to tidy the column — a rating printed
   without its RD invites a comparison the number cannot support, which is the
   entire reason this board is separate from the Cognition Index. */
.chess-lb-rd { color: var(--bs-ink-3); }
.chess-lb-note {
  grid-column: 2 / -1;
  font-family: var(--bs-mono); font-size: 8.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--bs-ink-3);
}
.chess-lb-empty {
  padding: 10px 2px;
  font-family: var(--bs-ui); font-size: 12.5px; color: var(--bs-ink-3);
}
.chess-lb-caption {
  margin-top: 10px; padding-top: 9px;
  border-top: 1px solid var(--bs-rule);
  font-family: var(--bs-ui); font-size: 11.5px; line-height: 1.5;
  color: var(--bs-ink-3);
}
.chess-lb-join {
  padding: 10px 0 12px;
  border-bottom: 1px solid var(--bs-ink);
  margin-bottom: 8px;
}
.chess-lb-join-copy {
  font-family: var(--bs-ui); font-size: 12.5px; line-height: 1.45;
  color: var(--bs-ink-2); margin-bottom: 8px;
}
.chess-lb-join-btn {
  background: transparent;
  border: 1px solid var(--bs-ink);
  border-radius: 0;
  padding: 8px 14px;
  font-family: var(--bs-mono);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bs-ink);
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.chess-lb-join-btn:hover { background: var(--bs-ink); color: var(--bs-stock); }
.chess-lb-join-btn:focus-visible { outline: 3px solid var(--bs-blue); outline-offset: 2px; }

/* ── the way out, and the time extension ──
   These are not peers. MEASURED before this rule: "+5 min" 520px against "Back
   to Problems" 494px at 1440, 492/466 at 1024, 364/338 at 768, 150/124 at 320 —
   the SECONDARY was the wider of the two at every width, because the markup
   carries `style="flex:1"` on both and .btn-secondary's 14px side padding beats
   .btn-primary's zero.

   GRID, not a flex override. `flex: 1` is an inline style and only !important
   could out-specify it — but flex-grow does not apply to a GRID item at all, so
   changing the formatting context retires both inline declarations without one.
   The tracks then say the hierarchy outright: the extension takes its own text's
   width, the way out takes the measure. 320 + 10 + ~76 lands the row on the
   420px every other .bs action row uses (14-bs-measures.css), which this one
   opted out of with `style="max-width:none"`.

   Scoped to #screen-chess: .mg-actions is also the drills hub, the drill stage,
   RSVP, sudoku, wordle and memory, and none of those were asked to move.

   `#screen-chess .mg-actions .btn-primary { margin-top: 0 }` STOOD HERE, and
   it was the first sighting of the leak that has since been fixed at its
   source: `.btn-primary` no longer carries `margin-top: 8px` at all
   (02-chrome.css gave that spacing to `.login-box`, which is the form that
   actually wanted it). A per-screen override of a global control class is the
   symptom, not the repair — it fixes the one screen somebody looked at, and
   this file's own note above records the same class of defect being measured
   again three screens later. There is also no `.btn-primary` left in this row
   to override: the `+5 min` button the note above deletes was the only one. */
#screen-chess .mg-actions {
  display: grid;
  grid-template-columns: max-content minmax(0, 320px);
  justify-content: start;
}

@media (max-width: 940px) {
  /* The rail goes under the board rather than squeezing the diagram — the
     board has a minimum size below which the pieces stop being readable. */
  .chess-main { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .chess-standings { max-width: 520px; }
}
@media (max-width: 700px) {
  .chess-wrap { padding: 0 18px 48px; }
  .chess-board-frame { --chess-sq: clamp(30px, 10.4vw, 44px); }
}
@media (prefers-reduced-motion: reduce) {
  .chess-sq, .chess-lb-join-btn { transition-duration: .001s; }
}
