/* ══ DAY ONE — THE PLACEMENT SUITE ═══════════════════════════════════════════
   js/11l-placement.js (#screen-placement, #screen-placement-board).

   Numbered 31 after 30-lexicon.css and set on the same broadsheet stock. Same
   type ladder (agate mono eyebrow · Fraunces display · Archivo body), same
   reading measure, same hard edges, no shadows, no rounded cards. Every colour
   below is a token that already existed in 01-tokens.css; nothing new is
   introduced. --bs-camel is never set as a `color:` — it measures 2.13:1 and
   test_palette_contrast.py bans it.

   ── THE SPINE IS THE DESIGN ─────────────────────────────────────────────────
   An eleven-year-old sits this for an hour on the first day. The one thing
   that makes a long sitting bearable is seeing how much is left, so the
   progress treatment is the permanent furniture of the page and the working
   card is the part that changes underneath it.

   Fifteen drills read as an unbounded queue when they are printed "9 of 15"
   and as a finite sequence when all fifteen are DRAWN. So each section is a
   row of TALLY STROKES, one per unit — the whole afternoon is thirty-nine
   marks and a student can see the end of it without reading a number. Done
   strokes are inked full height; the one in hand is inked, wider, and dropped
   below the rule so the eye finds it; the rest are hairlines.

   NOTHING COUNTS DOWN. The strokes fill with what is BEHIND the student. There
   is no timer element in this file, deliberately — the same ruling the
   dailies, the lecture and the track already follow.

   ── NO MOTION NEAR A MEASURED RESPONSE ──────────────────────────────────────
   Several of the fifteen are reaction-timed to the millisecond. `.plc-stage`
   carries no transition of any kind, and `.plc-drill-host` — the element the
   drill mounts into — is a bare box: no border, no padding, no background, so
   nothing this sheet owns can paint over a stimulus or move under a click.
   The ONE transition on the student surface is the stroke's ink, which only
   ever paints between drills, and it is off under prefers-reduced-motion.

   ── THE BOARD ANSWERS ONE QUESTION ──────────────────────────────────────────
   Mark reads it to decide how long the afternoon stations get, and the answer
   is the SLOWEST student, not the average. So the page opens with one figure
   at --fs-num-hero — the longest remaining read in the room — the spread strip
   sits under it so one straggler is distinguishable from half a class behind,
   and the list is sorted slowest-first with the top row ruled heavier because
   that is the row that sets the clock.
   ═══════════════════════════════════════════════════════════════════════════ */

.bs .plc, .bs .plcb {
  --plc-measure: 820px;
  --plc-read: var(--read-measure);
  --plc-gap: clamp(16px, 1.2vw + 10px, 24px);
  --plc-pad-x: clamp(18px, 3vw, 44px);
  max-width: var(--plc-measure);
}

.bs .plcb { max-width: 1040px; }

.bs .plc-eyebrow {
  font-family: var(--bs-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}

.bs .plc-loading {
  font-family: var(--bs-mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  padding: 28px 0;
}

/* ── the spine ───────────────────────────────────────────────────────────── */

/* THE PREVIEW BAR. Staff only, and it has to read as furniture belonging to
   the room rather than to the suite — an ochre rule and a label, not a card
   that competes with the spine underneath it. */
.bs .plc-preview {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  border-left: 4px solid var(--bs-blue);
  padding: 10px 0 10px 14px;
  margin-bottom: clamp(16px, 2vh, 24px);
}

.bs .plc-preview-k {
  font-family: var(--bs-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bs-blue);
}

.bs .plc-preview-t {
  font-size: 14px;
  line-height: 1.5;
  color: var(--bs-ink-3);
  max-width: 62ch;
}

/* THE SKIP-AHEAD, inside the preview bar and nowhere else. It takes the whole
   width of the bar as a second line — a select and a button set on the baseline
   beside the standing note would push the note's sentence into a two-word
   column at 1280. Agate labels, no fill, no radius: it is a piece of the room's
   furniture, not a control panel bolted to a student surface. */
.bs .plc-jump {
  flex: 1 0 100%;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 4px;
}

.bs .plc-jump-l,
.bs .plc-jump-state {
  font-family: var(--bs-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}

.bs .plc-jump-sel {
  font-family: var(--bs-ui);
  font-size: 13px;
  color: var(--bs-ink);
  background: var(--card-hi);
  border: 1px solid var(--bs-rule);
  border-bottom: 2px solid var(--bs-ink);
  padding: 7px 10px;
  max-width: 100%;
}

.bs .plc-jump-sel:focus-visible {
  outline: 2px solid var(--bs-blue);
  outline-offset: 1px;
}

.bs .btn-ghost.plc-jump-go {
  width: auto;
  padding: 6px 12px;
  font-family: var(--bs-mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* Only inked while inspection is actually on, so the bar's default state is
   the standing preview note and nothing else. */
.bs .plc-jump-state.is-on {
  color: var(--bs-ink);
  border-left: 3px solid var(--bs-blue);
  padding-left: 10px;
}

.bs .plc-spine { margin-bottom: clamp(22px, 3vh, 34px); }

.bs .plc-spine-list {
  list-style: none;
  border-top: 2px solid var(--bs-ink);
  margin: 0;
  padding: 0;
}

.bs .plc-sec {
  border-bottom: 1px solid var(--bs-rule);
  padding: 12px 0 14px;
  /* Not a card. A ruled ledger row — the section in hand is distinguished by
     ink weight and a left rule, never by a box or a fill. */
  border-left: 3px solid transparent;
  padding-left: 12px;
  margin-left: -15px;
}

.bs .plc-sec.is-live {
  border-left-color: var(--bs-ink);
  background: var(--bs-sheet);
}

.bs .plc-sec-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 9px;
}

/* The roman numeral is the section's name before its name is — it is the one
   thing on the row that says "three of these, in order". */
.bs .plc-sec-num {
  font-family: var(--bs-ed);
  font-weight: 900;
  font-size: 15px;
  line-height: 1;
  color: var(--bs-ink-3);
  min-width: 2.1em;
  letter-spacing: .04em;
}

.bs .plc-sec.is-live .plc-sec-num,
.bs .plc-sec.is-done .plc-sec-num { color: var(--bs-ink); }

.bs .plc-sec-name {
  font-family: var(--bs-ed);
  font-weight: 700;
  font-size: clamp(17px, 0.6vw + 15px, 21px);
  color: var(--bs-ink-3);
  flex: 1;
}

.bs .plc-sec.is-live .plc-sec-name { color: var(--bs-ink); font-weight: 900; }
.bs .plc-sec.is-done .plc-sec-name { color: var(--bs-ink-2); }

.bs .plc-sec-count {
  font-family: var(--bs-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.bs .plc-sec.is-live .plc-sec-count { color: var(--bs-ink); }

/* ── the tally strokes ───────────────────────────────────────────────────── */

/* A FIXED stroke width, not a proportional one. Fifteen strokes must draw a
   visibly longer row than twelve — that is half of what the picture says — and
   a flexed stroke would make all three sections the same length and encode
   nothing. */
.bs .plc-strokes {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 24px;
  margin-left: calc(2.1em + 12px);
}

.bs .plc-stroke {
  flex: 0 0 auto;
  width: 4px;
  height: 8px;
  align-self: flex-end;
  background: var(--bs-rule);
  transition: background var(--dur) var(--ease-out), height var(--dur) var(--ease-out);
}

.bs .plc-stroke.is-inked { height: 19px; background: var(--bs-ink); }

/* Where you are. Taller than the inked marks and carrying the camel as a
   GROUND (never as type — see 01-tokens.css) so the eye lands on it without a
   second colour entering the page. */
.bs .plc-stroke.is-here {
  height: 24px;
  background: var(--bs-camel);
  border-bottom: 3px solid var(--bs-ink);
}

.bs .plc-sec.is-done .plc-stroke.is-inked { background: var(--bs-ink-2); }

@media (prefers-reduced-motion: reduce) {
  .bs .plc-stroke { transition: none; }
}

/* ── the working card ────────────────────────────────────────────────────── */

/* The one thing on the page under the spine, so it is the one thing lifted off
   the stock: a heavy top rule and the sheet, the same treatment 30-lexicon.css
   reserves for the item in hand. Rhythm is `gap`, set once. */
.bs .plc-card {
  display: flex;
  flex-direction: column;
  gap: var(--plc-gap);
  border-top: 3px solid var(--bs-ink);
  border-bottom: 1px solid var(--bs-rule);
  background: var(--bs-sheet);
  padding: clamp(22px, 3vh, 32px) var(--plc-pad-x) clamp(26px, 3.4vh, 36px);
}

.bs .plc-card-t {
  font-family: var(--bs-ed);
  font-weight: 900;
  font-size: var(--page-lead);
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--bs-ink);
  max-width: var(--plc-read);
}

.bs .plc-sub-t {
  font-family: var(--bs-ed);
  font-weight: 700;
  font-size: clamp(19px, 0.8vw + 16px, 24px);
  color: var(--bs-ink);
}

.bs .plc-lede {
  font-family: var(--bs-ed);
  font-size: clamp(16px, 0.95rem + 0.2vw, 18px);
  line-height: 1.58;
  color: var(--bs-ink);
  max-width: var(--plc-read);
}

.bs .plc-note {
  font-family: var(--bs-ui);
  font-size: 14px;
  line-height: 1.55;
  color: var(--bs-ink-3);
  max-width: var(--plc-read);
}

/* A thing the student is being TOLD, not a thing being explained — the resume
   warning and the "this replaced your first score" line. Marginalia register:
   a bronze rule down the left, the way the paper marks an aside. */
.bs .plc-notice {
  font-family: var(--bs-ui);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--bs-ink);
  border-left: 3px solid var(--bs-blue);
  padding: 2px 0 2px 14px;
  max-width: var(--plc-read);
}

.bs .plc-rule {
  height: 0;
  border-top: 1px solid var(--bs-rule);
  margin: 2px 0;
}

.bs .plc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 4px;
}

/* The continue is the primary and the repeat is not, but the repeat's label is
   a whole sentence and must not be squeezed into a chip. Both stay full-height
   and the repeat is allowed to wrap. */
.bs .plc-actions .btn-primary,
.bs .plc-actions .btn-secondary {
  width: auto;
  padding: 12px 22px;
  white-space: normal;
  text-align: left;
}

.bs .plc-actions .btn-ghost { padding: 10px 4px; }

.bs .plc-card :focus-visible,
.bs .plcb :focus-visible {
  outline: 2px solid var(--bs-blue);
  outline-offset: 2px;
}

/* ── the score reveal ────────────────────────────────────────────────────── */

.bs .plc-score {
  display: flex;
  align-items: baseline;
  gap: 12px;
  border-top: 1px solid var(--bs-rule);
  border-bottom: 1px solid var(--bs-rule);
  padding: 14px 0;
}

.bs .plc-score-n {
  font-family: var(--bs-ed);
  font-weight: 900;
  font-size: var(--fs-num-hero);
  line-height: 0.92;
  color: var(--bs-ink);
  font-variant-numeric: tabular-nums;
}

.bs .plc-score-u {
  font-family: var(--bs-mono);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}

/* ── the drill host ──────────────────────────────────────────────────────── */

/* DELIBERATELY BARE. The fifteen mechanics own everything inside this box, and
   several of them are timed to the millisecond: a border, a padding change or
   a background here would move a stimulus or paint over a click target. It
   exists only to give 09-drills.js the #cog-drill-host it mounts into, and to
   reserve enough height that a stage appearing does not jump the page.

   COLUMN, AND THAT WORD IS THE WHOLE BUG. This was `display: flex` with the
   default ROW direction, so every element a drill appends to the stage — the
   meta row, the instruction, the playfield, the keypad, the Start button —
   became a shrinking flex item on ONE LINE. MEASURED at 1440x900 before the
   fix: Symbol Match's 9-column key was 186px wide (about 18px a cell) sitting
   beside its own instruction set one word per line, N-Back's 3x3 pad 214px,
   Stroop's word panel 226px. Mark, previewing it: "massively cramped for zero
   reason."

   The SIZE of what sits in the column is not set here. `#cog-drill-host` is
   the Lab's element too, and the caps that bound a playfield against the short
   axis, the reading measure and the touch minimum are written once in
   05-drills.css — `.plc-stage` was added to that block's prefix rather than
   copied into this sheet, so the two surfaces cannot drift apart. Those rules
   carry an id and therefore win over what is declared here; the declarations
   below are kept whole anyway so this host still reads as a complete
   definition on its own.

   `safe center`, not `center`: a stage taller than 420px must fall back to
   flex-start, because a centred flex child that overflows both edges cannot be
   scrolled back up to. Same reasoning `.mg-body-inner` gives in 05-drills.css. */
.bs .plc-drill-host {
  min-height: 420px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
}

/* THE ROOM THIS STAGE ACTUALLY HAS, which is not the window. 05-drills.css
   writes every short-axis cap as a fraction of `--drill-room` and defaults it
   to 100vh, which is true of the Lab — a full-screen modal — and false here.
   MEASURED 2026-08-31 with the page scrolled to the top: the masthead, the
   "Placement" title and the three-row spine occupy 448px above `#plc-stage` at
   BOTH 1440x900 and 1280x800 on a student's page (the staff preview bar adds
   another 132, and staff are the ones who can scroll on purpose). Left at
   100vh, a 58%-of-window playfield put Symbol Match's Start button 282px below
   the fold of a Chromebook.
   The caps are floored at each drill's own base size, so this only ever gives
   the stage LESS than the Lab takes, never less than the drill already had.
   Specificity: an id plus a class, matching 05-drills.css's own prefix, and
   this sheet is the later one. */
#cog-drill-host.plc-drill-host { --drill-room: calc(100vh - 470px); }

/* ── the academic item ───────────────────────────────────────────────────── */

.bs .plc-passage {
  font-family: var(--bs-ed);
  font-size: clamp(16px, 0.95rem + 0.2vw, 18px);
  line-height: 1.62;
  color: var(--bs-ink);
  max-width: var(--plc-read);
  border-left: 2px solid var(--bs-rule);
  padding-left: 16px;
}

.bs .plc-passage p { margin-bottom: 0.7em; }
.bs .plc-passage p:last-child { margin-bottom: 0; }

/* 500, not 700. An SAT R&W item inlines its passage into the stem — the split
   only fires when there is a paragraph break, and most of this pool has none —
   so this rule sets a six-line paragraph as often as it sets one sentence, and
   a six-line paragraph of bold Fraunces is a wall. Weight goes to the ask,
   which appendStemText marks up as .bs-ask. */
.bs .plc-stem {
  font-family: var(--bs-ed);
  font-weight: 500;
  font-size: clamp(17px, 1rem + 0.3vw, 20px);
  line-height: 1.52;
  color: var(--bs-ink);
  max-width: var(--plc-read);
}

.bs .plc-stem .bs-ask { font-weight: 800; }

.bs .plc-figure {
  max-width: 100%;
  height: auto;
  border: 1px solid var(--bs-rule);
  background: var(--card-hi);
  padding: 8px;
}

.bs .plc-answer { display: flex; flex-direction: column; gap: 14px; }

.bs .plc-choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: var(--plc-read);
}

/* Never a four-across tile grid: the comp-math pool's AMC 8 items carry FIVE
   choices and its MathCounts items carry none at all, so the ballot is a
   single column that does not care how many there are. */
.bs .plc-choice {
  display: flex;
  align-items: baseline;
  gap: 12px;
  width: 100%;
  text-align: left;
  font-family: var(--bs-ed);
  font-size: clamp(15px, 0.9rem + 0.2vw, 17px);
  line-height: 1.45;
  color: var(--bs-ink);
  background: var(--card-hi);
  border: 1px solid var(--bs-rule);
  border-left: 3px solid var(--bs-rule);
  padding: 12px 16px;
  cursor: pointer;
}

.bs .plc-choice:hover:not(:disabled) { border-color: var(--border-hi); border-left-color: var(--bs-ink-3); }

.bs .plc-choice.is-picked {
  border-color: var(--bs-ink);
  border-left-color: var(--bs-ink);
  background: var(--bs-sheet);
}

.bs .plc-choice:disabled { cursor: default; opacity: 1; color: var(--bs-ink-3); }

.bs .plc-choice-l {
  font-family: var(--bs-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--bs-ink-3);
  min-width: 1.2em;
}

.bs .plc-choice.is-picked .plc-choice-l { color: var(--bs-ink); }
.bs .plc-choice-t { flex: 1; }
.bs .plc-choice-img { max-width: 100%; height: auto; }

.bs .plc-free {
  display: flex;
  gap: 12px;
  align-items: stretch;
  max-width: var(--plc-read);
  flex-wrap: wrap;
}

.bs .plc-free-input {
  flex: 1 1 220px;
  font-family: var(--bs-mono);
  font-size: 17px;
  color: var(--bs-ink);
  background: var(--card-hi);
  border: 1px solid var(--bs-rule);
  border-bottom: 2px solid var(--bs-ink);
  padding: 12px 14px;
}

.bs .plc-free-input:focus-visible {
  outline: 2px solid var(--bs-blue);
  outline-offset: 1px;
}

.bs .plc-free .btn-primary { width: auto; padding: 12px 24px; }

.bs .plc-status {
  font-family: var(--bs-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  min-height: 1.2em;
}

/* ══ MARK'S BOARD ═══════════════════════════════════════════════════════════ */

.bs .plcb-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(20px, 4vw, 56px);
  border-top: 3px solid var(--bs-ink);
  border-bottom: 1px solid var(--bs-rule);
  padding: clamp(18px, 2.6vh, 26px) 0 clamp(20px, 2.8vh, 28px);
}

/* THE FIGURE. One number, larger than anything else on any screen in this
   file, because it is the only thing he came to read. */
.bs .plcb-fig { flex: 0 0 auto; }

.bs .plcb-fig-n {
  font-family: var(--bs-ed);
  font-weight: 900;
  font-size: var(--fs-num-hero);
  line-height: 0.9;
  letter-spacing: -0.02em;
  color: var(--bs-ink);
  font-variant-numeric: tabular-nums;
}

.bs .plcb-fig-l {
  font-family: var(--bs-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  margin-top: 8px;
  max-width: 22ch;
}

.bs .plcb-facts {
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 4px 18px;
  align-content: end;
}

.bs .plcb-fact-k {
  font-family: var(--bs-mono);
  font-size: 10px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  align-self: baseline;
}

.bs .plcb-fact-v {
  font-family: var(--bs-ed);
  font-weight: 700;
  font-size: 17px;
  color: var(--bs-ink);
  font-variant-numeric: tabular-nums;
}

.bs .plcb-head .plc-note { flex: 1 1 260px; max-width: 42ch; }

/* ── the spread ──────────────────────────────────────────────────────────── */

.bs .plcb-strip { padding: clamp(18px, 2.6vh, 26px) 0; border-bottom: 1px solid var(--bs-rule); }

.bs .plcb-axis { position: relative; margin-top: 10px; padding-bottom: 16px; }

.bs .plcb-band { display: flex; height: 26px; }

.bs .plcb-seg {
  border: 1px solid var(--bs-rule);
  border-right: 0;
  display: flex;
  align-items: center;
  padding-left: 8px;
  overflow: hidden;
}

.bs .plcb-seg:last-child { border-right: 1px solid var(--bs-rule); }

.bs .plcb-seg-l {
  font-family: var(--bs-mono);
  font-size: 9.5px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
  white-space: nowrap;
}

.bs .plcb-pins { position: relative; height: 14px; margin-top: 2px; }

/* One pin per student at their fraction of the whole suite. Thin, inked, and
   overlapping freely — a clump IS the information. */
.bs .plcb-pin {
  position: absolute;
  top: 0;
  width: 2px;
  height: 12px;
  margin-left: -1px;
  background: var(--bs-ink);
}

.bs .plcb-pin.is-done { background: var(--bs-camel-deep); height: 8px; }

/* ── the list ────────────────────────────────────────────────────────────── */

.bs .plcb-list { padding-top: clamp(18px, 2.6vh, 26px); }

.bs .plcb-list-head { margin-bottom: 10px; }

.bs .plcb-row {
  display: grid;
  grid-template-columns: minmax(120px, 1.3fr) minmax(130px, 1fr) minmax(120px, 1.6fr) 92px 108px;
  align-items: center;
  gap: 14px;
  border-bottom: 1px solid var(--bs-rule);
  padding: 11px 0 11px 12px;
  border-left: 3px solid transparent;
  margin-left: -15px;
}

/* THE ROW THAT SETS THE CLOCK. Heavier rule, the sheet under it, and its
   remaining figure in the display face — everything else on the board is
   context for this line. */
.bs .plcb-row.is-last-out {
  border-left-color: var(--bs-ink);
  background: var(--bs-sheet);
  border-bottom-color: var(--bs-ink-3);
}

.bs .plcb-row.is-done { color: var(--bs-ink-3); }

.bs .plcb-name {
  font-family: var(--bs-ed);
  font-weight: 700;
  font-size: 17px;
  color: var(--bs-ink);
}

.bs .plcb-row.is-done .plcb-name { color: var(--bs-ink-3); font-weight: 400; }

.bs .plcb-where { display: flex; flex-direction: column; gap: 2px; }

.bs .plcb-sec {
  font-family: var(--bs-mono);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}

.bs .plcb-pos {
  font-family: var(--bs-ui);
  font-size: 13px;
  color: var(--bs-ink);
  font-variant-numeric: tabular-nums;
}

.bs .plcb-strokes { display: flex; align-items: flex-end; gap: 2px; height: 14px; }
.bs .plcb-strokes .plc-stroke { height: 6px; min-width: 2px; max-width: 8px; }
.bs .plcb-strokes .plc-stroke.is-inked { height: 13px; }

.bs .plcb-left {
  font-family: var(--bs-ed);
  font-weight: 700;
  font-size: 16px;
  color: var(--bs-ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.bs .plcb-row.is-last-out .plcb-left { font-size: 20px; font-weight: 900; }
.bs .plcb-row.is-done .plcb-left { color: var(--bs-ink-3); font-weight: 400; }

.bs .plcb-act { display: flex; justify-content: flex-end; }

/* GHOST ONLY, never .btn-secondary — sizing the secondary apart from the
   primary is what test_button_system.py forbids, and it is right to: the pair
   is one control and every local override of the quiet half has been a patch
   for a mismatch. These are agate chips in a table row, which is a different
   register from the paired primary/secondary altogether, so they take the
   ghost and the confirming one is distinguished by its rule, not by size. */
.bs .btn-ghost.plcb-override {
  width: auto;
  padding: 6px 12px;
  font-family: var(--bs-mono);
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.bs .btn-ghost.plcb-override.is-yes {
  border: 1px solid var(--bs-ink);
  color: var(--bs-ink);
}

.bs .plcb-confirm { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

.bs .plcb-confirm-q {
  font-family: var(--bs-ui);
  font-size: 12px;
  color: var(--bs-ink);
}

.bs .plcb-done-mark {
  font-family: var(--bs-mono);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bs-ink-3);
}

.bs .plcb-done-mark.is-bad { color: var(--bs-pen); }

/* ── narrow ──────────────────────────────────────────────────────────────── */

@media (max-width: 720px) {
  .bs .plc-sec-head { flex-wrap: wrap; gap: 6px 10px; }
  .bs .plc-sec-count { width: 100%; padding-left: calc(2.1em + 12px); }
  .bs .plc-strokes { margin-left: 0; gap: 3px; }
  .bs .plc-sec { margin-left: 0; padding-left: 10px; }

  .bs .plc-actions { flex-direction: column; align-items: stretch; }
  .bs .plc-actions .btn-primary,
  .bs .plc-actions .btn-secondary { width: 100%; text-align: center; }

  /* `flex: 1 1 220px` resolves against the MAIN axis, so turning the row into a
     column turned the 220px basis into a 220px-tall text box. MEASURED at 375.
     The basis has to be reset with the direction. */
  .bs .plc-free { flex-direction: column; }
  .bs .plc-free-input { flex: 0 0 auto; width: 100%; }
  .bs .plc-free .btn-primary { width: 100%; }

  .bs .plc-drill-host { min-height: 380px; }

  .bs .plcb-head { gap: 18px; }
  .bs .plcb-facts { grid-template-columns: auto auto; }

  /* The board is a table on a laptop and a stack on a phone. The remaining
     figure stays on the first line with the name, because that pairing is the
     entire point of the row. */
  .bs .plcb-row {
    grid-template-columns: 1fr auto;
    grid-template-areas: 'name left' 'where where' 'strokes strokes' 'act act';
    gap: 6px 12px;
    margin-left: 0;
    padding-left: 10px;
  }
  .bs .plcb-name { grid-area: name; }
  .bs .plcb-left { grid-area: left; }
  .bs .plcb-where { grid-area: where; flex-direction: row; gap: 10px; align-items: baseline; }
  .bs .plcb-strokes { grid-area: strokes; }
  .bs .plcb-act { grid-area: act; justify-content: flex-start; }
}

/* ── the two counted groups ──────────────────────────────────────────────────
   "Who has not opened it" and "who is done" are counts with names attached, not
   twenty ruled rows each. MEASURED: on a 190-name roster the full-row treatment
   printed 178 identical not-started rows and buried the four students actually
   working, which is the one thing this board exists to show. */

.bs .plcb-group { padding-top: clamp(18px, 2.6vh, 26px); }

.bs .plcb-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  margin-top: 10px;
}

.bs .plcb-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--bs-rule);
  background: var(--card-hi);
  padding: 4px 6px 4px 10px;
}

.bs .plcb-chip-n {
  font-family: var(--bs-ui);
  font-size: 13px;
  color: var(--bs-ink);
}

.bs .plcb-chip-act { display: inline-flex; }
.bs .plcb-chip .btn-ghost.plcb-override { padding: 3px 8px; }

/* A section not yet started is one line: its name and how many questions it
   holds. See plcRenderSpine's own note — drawing strokes for all three cost
   ~60px of the fold and said nothing the count does not. */
.bs .plc-sec.is-ahead { padding-bottom: 10px; }
.bs .plc-sec.is-ahead .plc-sec-head { margin-bottom: 0; }
