/* The Scoring Console — the page a scorer works from during a live game.
 *
 * Ported from the approved Scoring Console prototype. The rules below are the
 * prototype's; the COLOURS AND FONTS are the site's own tokens from
 * `stadium.css`, which already define exactly the three typefaces the
 * prototype uses (Bebas Neue, DM Sans, JetBrains Mono).
 *
 * 🔴 That last point is most of why earlier attempts looked wrong. The tokens
 * were there all along and this stylesheet ignored them, so the console was
 * set in system fonts while every other page was not.
 */

/* The three colours the site does not already have: the grass, the dirt and
 * the chalk. Taken from the prototype.
 *
 * 🔴 The field follows the SITE's theme, not the phone's.
 *
 * This block used to key off `data-theme` on the root — a convention this
 * application does not use. `base.html` signals light mode with the class
 * `light-mode-html` on <html> and nothing else, so the light rules here never
 * matched anything, and the only thing that ever decided the field's colour
 * was `prefers-color-scheme` — the phone's own setting.
 *
 * The result: on a phone set to dark, with the site in light mode, the page
 * was cream and the field was black. Which is exactly what Tony photographed.
 * A dark theme is the default and the site's own light class overrides it, so
 * the field can never again disagree with the page around it. */
:root {
  --grass: #0F151C;
  --field: #12181F;
  --field-line: #2C3846;
}
html.light-mode-html,
:root[data-theme="light"] {
  --grass: #EDEDE2;
  --field: #E8E2D4;
  --field-line: #C9BFA8;
}

/* 🔴 `hidden` must win. Every rule below sets `display`, and a `display` on a
 * class beats the browser's own `[hidden]` — which is how a save bar for a
 * play nobody had chosen, and a SCORE target with no runner to send home,
 * both ended up on screen. */
.sv2 [hidden] { display: none !important; }

.sv2 {
  --sv2-gap: 16px;
  --sv2-radius: 14px;
  display: flex;
  flex-direction: column;
  gap: var(--sv2-gap);
}

/* ── correcting a play in the middle ────────────────────────────────────── */
/* Quiet until it is wanted. It sits on every row of the play log, and a row
 * of loud buttons would fight the thing the log is FOR — reading back what
 * was just scored. */

.sv2-log__fix {
  border: 1px solid var(--border-subtle, var(--border-default));
  background: transparent;
  color: var(--text-muted, var(--text-secondary));
  border-radius: var(--sv2-radius);
  padding: 2px 8px;
  font-family: var(--font-mono);
  font-size: .65rem;
  letter-spacing: .06em;
  cursor: pointer;
  white-space: nowrap;
}

.sv2-log__fix:hover,
.sv2-log__fix:focus-visible {
  color: var(--accent-danger);
  border-color: var(--accent-danger);
}

/* ── what the console just did ──────────────────────────────────────────── */
/* One quiet line under the strip, for the things a scorer has to be told and
 * must not be stopped by: what an undo took back, and that the pitches of that
 * at bat are already back on the count. Not a modal — this happens in the
 * middle of a live game and nothing may need dismissing. */

.sv2-said {
  margin: 8px 2px 0;
  padding: 8px 12px;
  border-left: 3px solid var(--accent-primary, var(--border-default));
  background: var(--bg-elevated, var(--bg-card));
  border-radius: var(--sv2-radius);
  font-size: .85rem;
  color: var(--text-secondary, var(--text-primary));
}

.sv2-said[hidden] { display: none; }

/* ── what the competition's own rules just did ──────────────────────────── */
/* Above everything the scorer taps, and wide enough that it cannot be taken
 * for a tooltip. It uses the house `dc-alert`, so it looks like every other
 * warning on the platform; only the spacing is local. */
.sv2-notices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 10px 2px 0;
}

.sv2-notice .dc-alert__title {
  margin: 0 0 2px;
  font-weight: 700;
}

.sv2-notice .dc-alert__message {
  margin: 0;
  font-size: .9rem;
  line-height: 1.45;
}

/* ── the runners an extra inning starts with ────────────────────────────── */
/* Directly under the sentence that announces them, and big enough to hit
 * without looking: a scorer presses this in the tenth inning of a final, on a
 * tablet, in the sun. Nothing here decides anything — the server says which
 * of these buttons exists at all. */

.sv2-tiebreak {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--dc-border, #d5d9e0);
  border-radius: 8px;
  background: var(--dc-surface-2, #f7f8fa);
}

.sv2-tiebreak__ask {
  margin: 0;
  font-weight: 700;
}

.sv2-tiebreak__bases {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.sv2-tiebreak__base {
  min-width: 88px;
  min-height: 44px;
}

/* The armed base. It must be obvious at a glance which one was tapped —
 * putting a man on the wrong base is a run nobody can account for later. */
.sv2-tiebreak__base.is-on {
  background: var(--dc-primary, #1d4ed8);
  border-color: var(--dc-primary, #1d4ed8);
  color: #fff;
  font-weight: 700;
}

.sv2-tiebreak__who {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: .9rem;
}

.sv2-tiebreak__who select {
  min-height: 44px;
  padding: 0 8px;
}

.sv2-tiebreak__hint {
  color: var(--dc-muted, #5b6472);
}

.sv2-tiebreak__go {
  min-height: 48px;
  font-weight: 700;
}

/* ── which competition this is ──────────────────────────────────────────── */
/* Quiet, and BELOW the strip. A scorer needs to be able to find it when he
 * wonders which sheet he is on, and never to have it competing for the glance
 * he gives the inning and the count. */

.sv2-competition {
  margin: 8px 2px 0;
  font-family: var(--font-mono);
  font-size: .7rem;
  letter-spacing: .08em;
  color: var(--text-muted, var(--text-secondary));
}

/* In the page head, directly under the two teams. Slightly larger and tucked
 * under the names rather than floating: it is read WITH them, in one glance,
 * as the answer to "which sheet is this?". */

.sv2-competition--head {
  margin: 4px 0 0;
  font-size: .78rem;
}

/* The host flags sit on the club names' line, at the height of the text.
 * twemoji replaces the character with an <img class="emoji">, which is
 * otherwise laid out as a full-size image and pushes the line apart. */

.dc-pagehead__subtitle img.emoji,
.sv2-competition img.emoji {
  height: 1em;
  width: 1em;
  margin: 0 .12em;
  vertical-align: -.12em;
}

/* ── the status strip ───────────────────────────────────────────────────── */
/* Glanced at between pitches, never read. */

.sv2-status {
  /* Flexible, not a fixed set of columns. The strip grew two blocks when the
   * count arrived and the extra ones fell onto a second row, pushing the
   * score under the batter. It has to take whatever the game is showing. */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
  padding: 12px 16px;
  background: var(--bg-elevated, var(--bg-card));
  border: 1px solid var(--border-subtle, var(--border-default));
  border-radius: var(--sv2-radius);
}

.sv2-status__block { display: flex; flex-direction: column; gap: 2px; }

.sv2-status__label {
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
}

.sv2-status__value {
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: .04em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--text-primary);
}

/* Three rings, filled as the outs come. Counted at a glance, which the words
 * "Outs: 2" are not. */
.sv2-outs { display: flex; gap: 5px; align-items: center; }
.sv2-outs__dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--border-strong, var(--border-default));
}
.sv2-outs__dot--on {
  background: var(--accent-danger);
  border-color: var(--accent-danger);
}

/* ── the game clock, in the strip ───────────────────────────────────────── */
/* The SAME four colours the game page uses — grey idle, green running, gold
 * under five minutes, red under one — because they come from the same
 * `getColorClass` in game_timer.js. Only the size is local: this one is read
 * out of the corner of an eye between pitches, so it is a third of the size
 * and carries no seconds box. */

.sv2-status__timer {
  display: flex;
  align-items: center;
  /* 🔴 It goes right, WITH the score. Tony, 2026-09-12: on the replay the
     clock sat where the batter's name ended and the score was hard right, so
     the strip read with a hole in the middle. `margin-left: auto` here takes
     the free space, and the score's own `auto` then only has to sit beside
     it. */
  margin-left: auto;
}

.sv2-timer {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sv2-timer.timer-hidden .sv2-timer__minutes,
.sv2-timer.timer-hidden .sv2-timer__display,
.sv2-timer.timer-hidden .sv2-timer__buttons { display: none; }

.sv2-timer__enable {
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
}

.sv2-timer__enable input { accent-color: var(--accent-gold); cursor: pointer; }

.sv2-timer__minutes {
  /* 🔴 Three digits AND the spinner. At 3.4em a 150-minute limit — what the
     Copa Cabildo plays to — was cut to "15(", so the box said one number and
     the competition played another. The spinner is taken off because a game
     limit is typed, never nudged one minute at a time. */
  width: 4.2em;
  appearance: textfield;
  -moz-appearance: textfield;
  padding: 3px 5px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: .85rem;
  color: var(--text-primary);
  background: var(--bg-card);
  border: 1px solid var(--border-default);
  border-radius: 4px;
}

.sv2-timer__minutes::-webkit-outer-spin-button,
.sv2-timer__minutes::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.sv2-timer__minutes:disabled { opacity: .5; cursor: not-allowed; }

.sv2-timer__display {
  padding: 2px 10px;
  border: 2px solid #475569;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}

.sv2-timer__display.timer-neutral { border-color: #475569; color: #94a3b8; }
.sv2-timer__display.timer-green { border-color: #22c55e; color: #22c55e; }
.sv2-timer__display.timer-yellow { border-color: #eab308; color: #eab308; }
.sv2-timer__display.timer-red {
  border-color: #ef4444;
  color: #ef4444;
  animation: timer-pulse 1s ease-in-out infinite;
}

.sv2-timer__buttons { display: flex; gap: 5px; }

.sv2-timer__btn {
  padding: 3px 10px;
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #0b0b0b;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.sv2-timer__btn--start,
.sv2-timer__btn--resume { background: var(--accent-live, #22c55e); }
.sv2-timer__btn--break { background: #ef4444; color: #fff; }
.sv2-timer__btn--reset { background: #f97316; }

/* On a narrow screen the clock drops onto its own line rather than squeezing
 * the score off the strip. */
@media (max-width: 720px) {
  .sv2-status__timer { order: 9; width: 100%; }
  .sv2-timer__enable-text { display: none; }
}

.sv2-status__score {
  display: flex;
  gap: 16px;
  justify-content: flex-end;
  font-variant-numeric: tabular-nums;
  /* Hard right, whatever else the strip is carrying — and beside the clock,
     which has taken the free space before it. */
  margin-left: 24px;
}
.sv2-score { display: flex; align-items: baseline; gap: 7px; }
.sv2-score__name {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
/* The side at bat is the one a scorer is watching. */
.sv2-score--batting .sv2-score__name { color: var(--accent-gold); }
.sv2-score__runs {
  font-family: var(--font-display);
  font-size: 1.8rem;
  line-height: 1;
  color: var(--text-primary);
}

@media (max-width: 760px) {
  .sv2-status { gap: 12px 16px; }
  .sv2-status__score { margin-left: 0; width: 100%; justify-content: flex-start; }
}

/* ── tabs ───────────────────────────────────────────────────────────────── */

/* 🔴 Every tab visible, on every screen, at its full size. Tony, 2026-10-04,
   on his iPad Mini: "I cannot access all the tabpages". The tabs shared one
   line with the pitch buttons and gave way to them, so on a tablet they were
   squeezed to a sliver or to nothing. They now have a line of their own and
   wrap onto a second one on a phone rather than scrolling out of sight —
   a scorer on a tablet must never have to hunt for a tab. */
.sv2-tabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

.sv2-tab { flex: 0 0 auto; }

.sv2-tab {
  font-family: var(--font-display);
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: 1rem;
  padding: 9px 18px;
  min-height: 44px;
  cursor: pointer;
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle, var(--border-default));
  border-radius: 9px;
}

.sv2-tab[aria-selected="true"] {
  background: var(--accent-gold);
  color: #0D1117;
  border-color: var(--accent-gold);
}

.sv2-tab:focus-visible { outline: 3px solid var(--accent-gold); outline-offset: 2px; }

.sv2-panel[hidden] { display: none !important; }

/* ── the console: field on the left, results on the right ───────────────── */
/* Side by side on purpose. Choosing a result and then tapping the field is
 * ONE action, and a scorer must never leave the buttons to reach the diamond. */

.sv2-console {
  display: grid;
  /* The field takes the wider share. A drawing can only grow sideways — its
   * height follows its width — so this is the only thing that makes the
   * diamond bigger, and it has to pay for the strip of foul ground now drawn
   * behind the plate. */
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  /* Both cards the same height. `start` let each shrink to its own content,
   * so the field card ended a third of the way up the buttons beside it. */
  align-items: stretch;
  gap: var(--sv2-gap);
}

/* The drawing keeps its natural size at the top of the card and the card
 * stretches under it, so the two cards end level.
 *
 * 🔴 NOT `flex: 1` on the drawing. Stretching the box does not enlarge the
 * drawing — it keeps its shape and centres itself — so the field ended up a
 * small diamond marooned in the middle of a 1,100px hall, with 290px of
 * nothing above and below it. */
.sv2-fieldcard {
  display: flex;
  flex-direction: column;
}

.sv2-fieldcard > svg.sv2-field { flex: 0 0 auto; }

@media (max-width: 980px) { .sv2-console { grid-template-columns: 1fr; } }

.sv2-card,
.sv2 #sv2Entry {
  /* 🔴 #sv2Sub is NOT a card any more. It is the dark surround of a pop-up,
   * and while it was still listed here it painted itself the colour of a card
   * — so the dialog had no backdrop at all and looked like part of the page
   * behind it. */
  background: var(--bg-elevated, var(--bg-card));
  border: 1px solid var(--border-subtle, var(--border-default));
  border-radius: var(--sv2-radius);
  padding: 14px;
}

.sv2-card__title,
.sv2 #sv2Entry > .dc-card__title {
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 400;
  margin: 0 0 3px;
  color: var(--text-primary);
}

.sv2-card__hint,
.sv2 .sv2-entry__due,
.sv2 .sv2-actions__hint,
.sv2 .sv2-entry__hint {
  margin: 0 0 10px;
  font-size: .79rem;
  color: var(--text-secondary);
}

/* ── the field ──────────────────────────────────────────────────────────── */

svg.sv2-field {
  width: 100%;
  height: auto;
  display: block;
  touch-action: manipulation;
  cursor: crosshair;
}

.sv2-grass { fill: var(--grass, #EDEDE2); stroke: var(--field-line, #C9BFA8); stroke-width: 1.5; }
.sv2-dirt { fill: var(--field, #E8E2D4); stroke: var(--field-line, #C9BFA8); stroke-width: 1.5; }
.sv2-foul { stroke: var(--field-line, #C9BFA8); stroke-width: 2; fill: none; }

/* Foul ground behind the plate. Drawn dimmer than the playing field: it is
 * territory, not a place a ball is meant to end up, and it must not read as a
 * second outfield. */
.sv2-backstop {
  fill: var(--field, #E8E2D4);
  fill-opacity: .5;
  stroke: var(--field-line, #C9BFA8);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}

.sv2-base {
  fill: var(--bg-input, var(--bg-card));
  stroke: var(--field-line, #C9BFA8);
  stroke-width: 2.5;
  cursor: pointer;
}
/* A bag with somebody standing on it. */
.sv2-base.is-occupied { fill: var(--accent-live); stroke: var(--accent-live); }
/* A bag a picked-up runner can be sent to. */
.sv2-base.is-target { stroke: var(--accent-gold); stroke-width: 4; }

.sv2-plate {
  fill: var(--bg-input, var(--bg-card));
  stroke: var(--field-line, #C9BFA8);
  stroke-width: 2.5;
}
.sv2-plate.is-target {
  stroke: var(--accent-gold);
  stroke-width: 4;
  fill: var(--accent-gold);
  cursor: pointer;
}

/* The word SCORE is the visible part of a 34px target, not a label that does
 * nothing when tapped. */
#sv2ScoreTarget { cursor: pointer; }
.sv2-score-target {
  fill: var(--accent-gold);
  opacity: .13;
  stroke: var(--accent-gold);
  stroke-width: 2;
  stroke-dasharray: 5 4;
}
#sv2ScoreTarget:hover .sv2-score-target { opacity: .28; }

/* The other thing that can happen to a runner. Red, because it is the opposite
   of scoring, and a scorer reaching for it at speed must not hit SCORE. */
.sv2-out-target {
  fill: var(--accent-danger);
  opacity: .13;
  stroke: var(--accent-danger);
  stroke-width: 2;
  stroke-dasharray: 5 4;
}
#sv2OutTarget:hover .sv2-out-target { opacity: .28; }
#sv2OutTarget .sv2-plate-hint { fill: var(--accent-danger); }
#sv2OutTarget, #sv2ScoreTarget { cursor: pointer; }

/* ── Charging the error ──────────────────────────────────────────────────── */
/* 🔴 The two targets that say WHO dropped it. Same danger colour as the OUT
 * circle, because both are the defence's bad news, and deliberately wide
 * rather than round: they carry two words, and a scorer on a tablet reaches
 * for them with a thumb while the game carries on. 120x34 in the drawing's
 * own units is comfortably past the 44-pixel touch target at every size the
 * console is used at. */
.sv2-error-target {
  fill: var(--accent-danger);
  opacity: .13;
  stroke: var(--accent-danger);
  stroke-width: 2;
  stroke-dasharray: 5 4;
}
#sv2DroppedTarget:hover .sv2-error-target,
#sv2ThrewItAwayTarget:hover .sv2-error-target { opacity: .3; }
#sv2DroppedTarget .sv2-plate-hint,
#sv2ThrewItAwayTarget .sv2-plate-hint { fill: var(--accent-danger); }
#sv2DroppedTarget, #sv2ThrewItAwayTarget { cursor: pointer; }
.sv2-plate-hint {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .14em;
  fill: var(--accent-gold);
  text-anchor: middle;
  font-weight: 700;
  pointer-events: none;
}
.sv2-plate-hint--sub {
  font-size: 6.5px;
  letter-spacing: .06em;
  font-weight: 400;
  fill: var(--text-secondary);
}

.sv2-fielder { cursor: pointer; }
.sv2-fielder circle {
  fill: var(--bg-surface, var(--bg-card));
  stroke: var(--border-strong, var(--border-default));
  stroke-width: 2;
  transition: fill .12s, stroke .12s;
}
.sv2-fielder text {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 700;
  fill: var(--text-primary);
  text-anchor: middle;
  pointer-events: none;
}
.sv2-fielder__ini {
  font-size: 7.5px !important;
  font-weight: 400 !important;
  fill: var(--text-muted, var(--text-secondary)) !important;
}
.sv2-fielder.is-picked circle { fill: var(--accent-gold); stroke: var(--accent-gold); }
.sv2-fielder.is-picked text { fill: #0D1117; }
.sv2-fielder:focus-visible circle { stroke: var(--accent-gold); stroke-width: 3; }
/* Nobody in the line-up at that position. The gap is information. */
.sv2-fielder--empty circle { stroke-dasharray: 3 3; opacity: .6; }

/* The runner's name, off the bag: a tag over the base hides the base, and a
 * tag over a fielder hides the man who might put him out. */
.sv2-runner { cursor: pointer; }
.sv2-runner rect {
  fill: var(--bg-surface, var(--bg-card));
  stroke: var(--accent-live);
  stroke-width: 2;
}
.sv2-runner text {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 700;
  fill: var(--text-primary);
  text-anchor: middle;
  pointer-events: none;
}
/* The batter's own tag. It behaves as a runner tag in every way — same tap,
 * same targets — so it is styled as one, with a dashed outline as the single
 * difference: he is not on a base yet. Selecting or moving him paints it
 * solid like any other, because at that point he has been spoken for. */
.sv2-runner--batter rect { stroke-dasharray: 4 3; }
.sv2-runner--batter.is-selected rect,
.sv2-runner--batter.has-move rect { stroke-dasharray: none; }

.sv2-runner__tie { stroke: var(--accent-live); stroke-width: 2; }
.sv2-runner.is-selected rect { stroke: var(--accent-gold); stroke-width: 3; fill: var(--accent-gold); }
.sv2-runner.is-selected text { fill: #0D1117; }
.sv2-runner.has-move rect { fill: var(--accent-gold); stroke: var(--accent-gold); }
.sv2-runner.has-move text { fill: #0D1117; }

.sv2-ball {
  fill: var(--accent-gold);
  stroke: var(--bg-surface, var(--bg-card));
  stroke-width: 2;
  pointer-events: none;
}

/* Decoration, never a target: the arc is painted across the middle of the
 * field and would otherwise swallow taps meant for runners and bases. */
.sv2-move-arc {
  stroke: var(--accent-gold);
  stroke-width: 3.5;
  fill: none;
  stroke-dasharray: 7 5;
  stroke-linecap: round;
  pointer-events: none;
}

/* A man being sent to the OUT target is not advancing, so he is not drawn in
 * the advancing colour. Told apart by colour AND by a shorter dash, because a
 * scorer checking his entry at speed should not have to compare two golds. */
.sv2-move-arc--out {
  stroke: var(--danger, #dc2626);
  stroke-dasharray: 3 4;
}

/* The chain bar sits directly under the drawing, and the card's spare height
 * falls below it. */
.sv2-fieldcard > .sv2-chainbar { margin-bottom: auto; }

/* ── the pitch count ────────────────────────────────────────────────────── */

/* 🔴 Beside the tabs, not at the foot of the field card. A scorer taps these
 * several times a plate appearance and had to scroll past the whole diamond
 * to reach them — so they were missed. Up here they sit in the same place on
 * every tab, level with the tab buttons. */
/* 🔴 Two lines, the same on every screen: the tabs on the first, Play and
 * the pitch buttons on the second.
 *
 * It was one line that could not wrap, with the TABS giving way to the
 * buttons — so on the tablets scorers actually use, the tabs vanished (iPad
 * Mini, portrait) or shrank to a sliver (landscape) and the last buttons ran
 * off the screen (Tony, 2026-10-04). Tony's earlier rule still holds, and is
 * now kept on EVERY width rather than only on a wide one: the pitch buttons
 * are always in the same place — the line under the tabs — and never jump
 * about with the size of the screen. */
.sv2-tabrow {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}

.sv2-tabrow > .sv2-tabs { min-width: 0; }

/* Play and the pitch count are one group, so Play is always the first button
   of it. It wraps when the screen is too narrow for all of them — a button on
   a second line can be pressed; a button off the edge of the screen cannot. */
.sv2-tabrow__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}
/* Play and the pitch buttons wrap as ONE run of buttons, so Play never sits
   alone on a line of its own above the pitch buttons. */
.sv2-tabrow__actions > .sv2-pitchbar { display: contents; }

.sv2-pitchbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.sv2-pitch {
  min-width: 84px;
  min-height: 44px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
/* The same three families as the results, in the same tints: a ball is a free
 * base coming, a strike is an out coming, a foul is neither.
 *
 * Written with BOTH classes on purpose. `.sv2-btn` is defined further down
 * this stylesheet and carries its own background; at equal specificity the
 * later rule wins, so a single class here painted nothing at all. */
.sv2-btn.sv2-pitch--ball {
  background: color-mix(in srgb, var(--accent-live) 18%, var(--bg-input, var(--bg-card)));
  border-color: var(--accent-live);
}
.sv2-btn.sv2-pitch--strike {
  background: color-mix(in srgb, var(--accent-danger) 18%, var(--bg-input, var(--bg-card)));
  border-color: var(--accent-danger);
}
.sv2-btn.sv2-pitch--foul {
  background: color-mix(in srgb, var(--accent-gold) 20%, var(--bg-input, var(--bg-card)));
  border-color: var(--accent-gold);
}
/* 🔴 A tap has to be FELT. The count changes in the strip above, which a
 * scorer looking at his hand does not see, so the button he pressed pulses
 * once — the answer to "did that go in?" arriving where he is looking. */
@keyframes sv2PitchPulse {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 currentColor; }
  35%  { transform: scale(1.06); box-shadow: 0 0 0 5px color-mix(in srgb, currentColor 22%, transparent); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 transparent; }
}
.sv2-pitch.is-just-tapped { animation: sv2PitchPulse .42s ease-out; }

/* The same answer for a RESULT card. Every button on this console says "yes,
 * I got that" where the hand is, not only in the strip at the top of the
 * page. Short and once — a card that went on pulsing would compete with the
 * count's call, which is the one thing here that must keep asking. */
@keyframes sv2CardTap {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-gold) 55%, transparent); }
  35%  { transform: scale(1.04); box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent-gold) 30%, transparent); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 transparent; }
}
.sv2-result.is-just-tapped { animation: sv2CardTap .4s ease-out; }
.sv2-pitch--ball.is-just-tapped { color: var(--accent-live); }
.sv2-pitch--strike.is-just-tapped { color: var(--accent-danger); }
.sv2-pitch--foul.is-just-tapped { color: var(--accent-gold); }

.sv2-pitch__key {
  font-family: var(--font-mono);
  font-size: .64rem;
  font-weight: 700;
  padding: 2px 5px;
  border-radius: 4px;
  background: var(--bg-surface, var(--bg-card));
  border: 1px solid var(--border-strong, var(--border-default));
  color: var(--text-secondary);
  text-transform: uppercase;
}
.sv2-pitchbar__calls {
  font-size: .78rem;
  font-weight: 600;
  color: var(--accent-gold);
}
/* A competition whose count rules are not settled says so here, in words. */
.sv2-pitchbar__refusal {
  font-size: .78rem;
  color: var(--text-secondary);
}

/* The count in the status strip: balls green, strikes RED, empty rings for the
 * rest. Red because a strike is an out coming — the same colour the Strike
 * button and the whole OUT family of results carry, so one colour means one
 * thing across the console. */
.sv2-count { display: flex; align-items: center; gap: 8px; }
.sv2-count__dots { display: flex; gap: 4px; }
.sv2-count__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid var(--border-strong, var(--border-default));
}
.sv2-count__dot--ball.is-on {
  background: var(--accent-live);
  border-color: var(--accent-live);
}
.sv2-count__dot--strike.is-on {
  background: var(--accent-danger);
  border-color: var(--accent-danger);
}
.sv2-count__value {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-variant-numeric: tabular-nums;
}



.sv2-chainbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding: 8px 10px;
  background: var(--bg-input, var(--bg-card));
  border-radius: 9px;
}
.sv2-chainbar__label {
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
}
.sv2-chainbar__value {
  font-family: var(--font-mono);
  font-size: 1rem;
  font-weight: 700;
  color: var(--accent-gold);
  min-width: 4rem;
}
.sv2-chainbar__hint { font-size: .74rem; color: var(--text-muted, var(--text-secondary)); }

/* ── the result keypad ──────────────────────────────────────────────────── */

.sv2 .sv2-entry__buttons { display: block; }

.sv2-group { margin-bottom: 12px; }
.sv2-group__label {
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
  margin: 0 0 5px;
}

.sv2-results {
  display: grid;
  /* Every card the same width, and wide enough for a whole word. At 108px the
   * label column was 68px of usable space and Italian broke "Fuoricampo"
   * across two lines; a card is easier to find by its name than by its
   * shape. */
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 6px;
}

/* The card and its question mark are one grid cell. The mark is positioned
 * over the card's top-right corner rather than inside it: a button inside a
 * button is not HTML, and the card must stay reserved for the play. */
.sv2-result-wrap {
  position: relative;
  display: flex;
}
.sv2-result-wrap > .sv2-result { flex: 1 1 auto; }

.sv2-result__help {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 20px;
  height: 20px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border-strong, var(--border-default));
  background: var(--bg-surface, var(--bg-card));
  color: var(--text-muted, var(--text-secondary));
  font-family: var(--font-mono);
  font-size: .72rem;
  line-height: 1;
  cursor: help;
  /* Quiet until it is wanted. A scorer reads this panel forty times an
   * inning and must see the play names, not a wall of question marks. */
  opacity: .45;
  transition: opacity .12s, border-color .12s, color .12s;
}
.sv2-result-wrap:hover > .sv2-result__help,
.sv2-result__help:hover,
.sv2-result__help:focus-visible {
  opacity: 1;
  color: var(--accent-gold);
  border-color: var(--accent-gold);
}
.sv2-result__help:focus-visible { outline: 3px solid var(--accent-gold); outline-offset: 2px; }
/* The window's own footnote under the rule. Everything else it uses is the
 * Stat Explainer's stylesheet, unchanged. */
.sv2-help__rulenote {
  margin: 8px 0 0;
  font-size: .74rem;
  color: var(--text-muted, var(--text-secondary));
}

.sv2-result {
  /* 🔴 A fixed gutter on the right, for the shortcut and the question mark,
     and the name confined to the column beside it. They used to share the
     space: in Spanish and Italian the name wrapped underneath them and the
     shortcut disappeared behind the text — Tony photographed it in three
     languages. Now nothing can grow into anything else, whatever the words. */
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22px;
  grid-template-rows: 1fr auto;
  align-items: start;
  gap: 4px 6px;
  min-height: 62px;
  padding: 7px 9px;
  background: var(--bg-input, var(--bg-card));
  color: var(--text-primary);
  border: 1px solid var(--border-subtle, var(--border-default));
  border-radius: 9px;
  font-family: var(--font-body);
  font-size: .82rem;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  transition: border-color .12s, transform .06s;
}
.sv2-result > span:first-child {
  grid-column: 1;
  grid-row: 1;
  /* Wrap rather than overflow — a long name in any language stays inside.
     `break-word`, not `anywhere`: it breaks at the spaces first and splits a
     word only when one genuinely will not fit, so Spanish and Italian read as
     words rather than as "abanican-do". */
  overflow-wrap: break-word;
}
.sv2-result:hover:not(:disabled) { border-color: var(--accent-gold); }
.sv2-result:active { transform: translateY(1px); }
.sv2-result:disabled { opacity: .45; cursor: not-allowed; }
.sv2-result:focus-visible { outline: 3px solid var(--accent-gold); outline-offset: 2px; }

.sv2-result__key {
  /* Under the question mark, in the gutter that is kept for the two of them. */
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  margin-top: 20px;
  justify-self: center;
  font-family: var(--font-mono);
  font-size: .64rem;
  font-weight: 700;
  padding: 2px 5px;
  border-radius: 4px;
  background: var(--bg-surface, var(--bg-card));
  border: 1px solid var(--border-strong, var(--border-default));
  color: var(--text-secondary);
}

/* The rule that governs this result — small, quiet, and always there.
   A scorer unsure between two buttons used to guess, and a guess between a
   fielder's choice and an occupied ball changes an earned-run calculation
   weeks later. Not translated: OBR 9.05(a)(1) is the same in every rulebook,
   and a translated citation cannot be looked up. */
.sv2-result__rule {
  grid-column: 1 / -1;
  grid-row: 2;
  align-self: end;
  font-family: var(--font-mono);
  font-size: .58rem;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: .01em;
  color: var(--text-secondary);
  opacity: .72;
}

/* 🔴 The whole card carries its family's colour, not just a stripe down its
   edge. A scorer reaching for a result at the speed of a live game finds the
   green block, then the button — which is the point of grouping them at all.
   The site's own accent tokens, mixed down to a tint so black text stays
   readable on them in both themes. */
.sv2-result[data-tone="safe"] {
  border-left: 3px solid var(--accent-live);
  background: color-mix(in srgb, var(--accent-live) 9%, var(--bg-input, var(--bg-card)));
}
.sv2-result[data-tone="out"] {
  border-left: 3px solid var(--accent-danger);
  background: color-mix(in srgb, var(--accent-danger) 9%, var(--bg-input, var(--bg-card)));
}
.sv2-result[data-tone="free"] {
  border-left: 3px solid var(--accent-gold);
  background: color-mix(in srgb, var(--accent-gold) 11%, var(--bg-input, var(--bg-card)));
}
.sv2-result[data-tone="runner"] {
  border-left: 3px solid var(--accent-fc);
  background: color-mix(in srgb, var(--accent-fc) 10%, var(--bg-input, var(--bg-card)));
}
.sv2-result[data-tone="other"] {
  border-left: 3px solid var(--text-muted, var(--text-secondary));
  background: color-mix(in srgb, var(--text-muted, var(--text-secondary)) 7%, var(--bg-input, var(--bg-card)));
}

/* The armed result: the one a tap on the field now belongs to. */
.sv2-result.is-armed {
  border-color: var(--accent-gold);
  border-width: 2px;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-gold) 30%, transparent);
}

/* ── the save bar ───────────────────────────────────────────────────────── */
/* Says in words what pressing Save will record. The scorer confirms a
 * sentence, not a colour on a button. */

.sv2-savebar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding: 9px 11px;
  border-radius: 9px;
  background: var(--accent-gold);
  color: #0D1117;
}
.sv2-savebar__what {
  font-family: var(--font-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: 1rem;
  flex: 1 1 auto;
}

/* ── buttons ────────────────────────────────────────────────────────────── */

.sv2-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

.sv2-btn {
  min-height: 44px;
  padding: 8px 15px;
  border-radius: 9px;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: .83rem;
  font-weight: 600;
  border: 1px solid var(--border-strong, var(--border-default));
  background: var(--bg-input, var(--bg-card));
  color: var(--text-primary);
}
.sv2-btn:hover:not(:disabled) { border-color: var(--accent-gold); }
.sv2-btn:focus-visible { outline: 3px solid var(--accent-gold); outline-offset: 2px; }
.sv2-btn:disabled { opacity: .45; cursor: not-allowed; }
.sv2-btn--danger { border-color: var(--accent-danger); color: var(--accent-danger); }
.sv2-btn--go { background: #0D1117; color: #fff; border-color: #0D1117; }
.sv2-savebar .sv2-btn { min-height: 38px; }

.sv2-btn kbd {
  font-family: var(--font-mono);
  font-size: .64rem;
  font-weight: 700;
  padding: 2px 5px;
  border-radius: 4px;
  background: var(--bg-surface, var(--bg-card));
  border: 1px solid var(--border-strong, var(--border-default));
  color: var(--text-secondary);
  margin-left: 6px;
}
.sv2-btn--go kbd { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .3); color: #fff; }

/* ── the play log ───────────────────────────────────────────────────────── */

.sv2-log { width: 100%; border-collapse: collapse; font-size: .83rem; }
.sv2-log th {
  font-family: var(--font-mono);
  font-size: .58rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
  text-align: left;
  padding: 6px 7px;
  border-bottom: 1px solid var(--border-subtle, var(--border-default));
  font-weight: 400;
}
.sv2-log td {
  padding: 6px 7px;
  border-bottom: 1px solid var(--border-subtle, var(--border-default));
  vertical-align: top;
  color: var(--text-primary);
}
.sv2-log tr:last-child td { border-bottom: none; }

/* On a phone the seven columns do not fit, and the last one is the button
   that corrects a play — the one a scorer must be able to reach. Each play
   becomes one wrapped line instead: everything still shown, the button on
   screen. */
@media (max-width: 600px) {
  .sv2-log thead { display: none; }
  .sv2-log, .sv2-log tbody { display: block; }
  .sv2-log tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border-subtle, var(--border-default));
  }
  .sv2-log td { border-bottom: none; padding: 0; }
}

.sv2-notation { font-family: var(--font-mono); font-weight: 700; font-size: .88rem; }
.sv2-notation--out { color: var(--accent-danger); }
.sv2-notation--hit { color: var(--accent-live); }
.sv2-notation--runner { color: var(--accent-fc); }
.sv2-notation--other { color: var(--text-secondary); }

.sv2-log__empty { color: var(--text-muted, var(--text-secondary)); font-size: .84rem; padding: 9px 7px; }
.sv2-log__start-again { margin: 12px 0 0; text-align: right; }

/* ── changing players: the two columns ──────────────────────────────────── */
/* 🔴 Tony, 12 September 2026: "intentar hacer la substitución tan fácil y
 * rápida que un niño pudiese hacerla." The pop-up that used to be styled here
 * asked three questions; this is a tab with two lists and a basket.
 *
 * Everything a finger lands on is at least 44px tall. A scorer taps these in
 * the middle of an inning, standing up, on a tablet. */

.sv2-swap { display: flex; flex-direction: column; gap: 14px; }

.sv2-swap__top {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.sv2-swap__team { display: flex; align-items: center; gap: 8px; }
.sv2-swap__label { font-size: .8rem; color: var(--text-secondary); }
.sv2-swap__team select { min-width: 190px; min-height: 44px; }

/* The change made more often than all the others put together. */
.sv2-swap__quick { min-height: 44px; font-weight: 700; }

/* What to do next, in one line, changing as he goes. A screen that says
 * nothing after the first tap is a screen nobody trusts. */
.sv2-swap__how {
  margin: 0;
  margin-left: auto;
  font-size: .86rem;
  color: var(--text-secondary);
}

.sv2-swap__cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

/* Mobile first: this community is mostly on a phone, and two columns of names
 * on a 390px screen are two columns of nothing. */
@media (max-width: 720px) {
  .sv2-swap__cols { grid-template-columns: 1fr; }
  .sv2-swap__how { margin-left: 0; width: 100%; }
}

.sv2-swap__col {
  border: 1px solid var(--border-subtle, var(--border-default));
  border-radius: 10px;
  background: var(--bg-elevated, var(--bg-card));
  overflow: hidden;
}

.sv2-swap__title {
  margin: 0;
  padding: 8px 12px;
  font-size: .82rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-subtle, var(--border-default));
}

.sv2-swap__list {
  list-style: none;
  margin: 0;
  padding: 6px;
  max-height: 52vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sv2-swap__man {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--text-primary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.sv2-swap__man:hover { border-color: var(--border-default); }

/* 🔴 The man armed for going out. It has to be unmistakable from a metre
 * away: taking the wrong man out of a game is not something a scorer can
 * quietly put right afterwards. */
.sv2-swap__man.is-armed {
  border-color: var(--accent-primary, #b8860b);
  background: color-mix(in srgb, var(--accent-primary, #b8860b) 18%, var(--bg-card));
  font-weight: 700;
}

/* Already spoken for by something in the basket. */
.sv2-swap__man.is-waiting {
  opacity: .55;
  text-decoration: line-through;
}

.sv2-swap__man[disabled] { opacity: .4; cursor: not-allowed; }

.sv2-swap__who { flex: 1 1 auto; }

.sv2-swap__note {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--text-muted, var(--text-secondary));
  white-space: pre;
}

.sv2-swap__empty {
  padding: 10px;
  font-size: .85rem;
  color: var(--text-secondary);
}

/* ── the basket ─────────────────────────────────────────────────────────── */

.sv2-swap__basket {
  border: 1px solid var(--border-default);
  border-radius: 10px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.sv2-swap__basket[hidden] { display: none; }

.sv2-swap__count {
  display: inline-block;
  min-width: 22px;
  padding: 0 6px;
  border-radius: 11px;
  background: var(--accent-primary, #b8860b);
  color: #fff;
  text-align: center;
}

/* The two doors two taps cannot open. Quiet, and out of the way of the
 * ordinary change — but there, because dropping them would drop the
 * capability with them. */
.sv2-swap__unusual {
  display: flex;
  align-items: flex-end;
  gap: 18px;
  flex-wrap: wrap;
}

.sv2-swap__move, .sv2-swap__kind {
  display: flex;
  align-items: center;
  gap: 8px;
}

.sv2-swap__move[hidden] { display: none; }
.sv2-swap__move select, .sv2-swap__kind select { min-height: 44px; }
.sv2-swap__move .sv2-btn { min-height: 44px; }

.sv2-swap__waiting { list-style: none; margin: 0; padding: 0; }

.sv2-swap__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border-subtle, var(--border-default));
}

.sv2-swap__row:last-child { border-bottom: none; }

.sv2-swap__says { flex: 1 1 auto; }

/* Where the man coming in lands. It is already filled in with the position of
 * the man he replaced; this is for the times that is not what happened. */
.sv2-swap__where {
  min-height: 38px;
  max-width: 12rem;
  font-size: .82rem;
}

.sv2-swap__drop {
  min-width: 34px;
  min-height: 34px;
  border: 1px solid var(--border-default);
  border-radius: 8px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

/* ── what the whole set will do ─────────────────────────────────────────── */
/* Worked out by the SERVER running every change and rolling them back. */

.sv2-swap__verdict {
  padding: 10px 12px;
  border-radius: 9px;
  border-left: 3px solid var(--border-default);
  background: var(--bg-elevated, var(--bg-card));
}

.sv2-swap__verdict--ready {
  border-left-color: var(--accent-live, var(--accent-gold));
  background: color-mix(in srgb, var(--accent-live, var(--accent-gold)) 8%, transparent);
}

.sv2-swap__verdict--no {
  border-left-color: var(--accent-danger, #d33);
  background: color-mix(in srgb, var(--accent-danger, #d33) 8%, transparent);
}

.sv2-swap__say { margin: 0; font-size: .95rem; line-height: 1.45; }
.sv2-swap__then {
  margin: 6px 0 0;
  padding-left: 1.1rem;
  font-size: .84rem;
  color: var(--text-secondary);
}
.sv2-swap__then:empty { display: none; }

/* 🔴 "When you confirm:" — the line that turns a list of facts into a promise
 * about what is going to be true. Without it a scorer reads the lines as a
 * description of what he just tapped and presses on. Deliberately heavier
 * than the list under it: this is the sentence he has to read. */
.sv2-swap__thenlabel {
  margin: 8px 0 0;
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-primary);
}

.sv2-swap__actions { display: flex; gap: 10px; justify-content: flex-end; }
.sv2-swap__actions .sv2-btn { min-height: 48px; }

/* Tom Select renders its popup on <body>, which sits under the overlay unless
 * it is told otherwise. Its own stylesheet already lifts it above everything;
 * this only makes sure the console's later stylesheet does not undo that. */
.sv2 ~ .ts-dropdown, .ts-dropdown { z-index: 9999; }

/* The positions a man has played, printed beside his name on the box score
 * the way MLB prints them: 1B-RF-CF, PR-RF. */
.sv2-box__pos {
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .06em;
  color: var(--text-muted, var(--text-secondary));
  white-space: nowrap;
}

/* A line-up change in the play log is not a play. Marked so it can be found
 * at a glance in a column of forty results. */
.sv2-notation--sub { color: var(--accent-gold); }
.sv2-log__change td {
  background: color-mix(in srgb, var(--accent-gold) 7%, transparent);
}

/* ── refusals ───────────────────────────────────────────────────────────── */
/* A play that was not scored and says nothing is the failure this whole panel
 * exists to prevent. */

.sv2 .sv2-entry__error {
  margin-top: 12px;
  padding: 10px 12px;
  border-radius: 9px;
  border: 1px solid var(--accent-danger);
  border-left: 3px solid var(--accent-danger);
  background: color-mix(in srgb, var(--accent-danger) 10%, transparent);
  color: var(--text-primary);
  font-size: .85rem;
}

/* ── the other tabs ─────────────────────────────────────────────────────── */

/* 🔴 Never wider than the screen. A box score table is wider than an iPad in
   portrait; it scrolls INSIDE its own card instead of sliding the whole page
   sideways (Tony, 2026-10-04, testing on an iPad Mini). `min()` lets a card
   be narrower than 340px on a phone rather than overflowing it. */
.sv2-boxes { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); gap: var(--sv2-gap); }
.sv2-boxes > .sv2-card { min-width: 0; overflow-x: auto; }
.sv2-box { width: 100%; border-collapse: collapse; font-size: .83rem; font-variant-numeric: tabular-nums; }
.sv2-box th, .sv2-box td { padding: 6px 8px; text-align: right; }
.sv2-box th:first-child, .sv2-box td:first-child { text-align: left; white-space: nowrap; }
/* The batting table leads with the slot number, so the NAME is the second
 * column — a right-aligned column of names reads as a column of figures. */
.sv2-box--card th:nth-child(2), .sv2-box--card td:nth-child(2) {
  text-align: left;
  white-space: nowrap;
  width: 99%;
}
.sv2-box thead th {
  font-family: var(--font-mono);
  font-size: .58rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
  font-weight: 400;
  border-bottom: 1px solid var(--border-subtle, var(--border-default));
}
.sv2-box tbody td { border-bottom: 1px solid var(--border-subtle, var(--border-default)); }

/* The box score carries the whole line-up card from the first pitch, so it
 * needs to say which part of the card you are reading. */
.sv2-box__head td {
  font-family: var(--font-mono);
  font-size: .58rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
  padding-top: 12px;
  border-bottom: 1px solid var(--border-strong, var(--border-default));
}
/* A man who has not batted yet is on the card, not in the game. Dimmed so the
 * eye finds the players with figures against their name first. */
.sv2-box__idle td { color: var(--text-muted, var(--text-secondary)); }
.sv2-box__slot { width: 2.4rem; font-family: var(--font-mono); }
.sv2-box__sub { color: var(--accent-gold); }

/* 🔴 The NAME gives way, never the numbers. Tony, 10 October 2026, on an iPad
 * Mini and an iPhone: the box score must show ALL its figures on every
 * device; a name too long for the room is cut with "…", and the whole name is
 * one hover (or one press-and-hold) away — `js/dc_cut_names.js`.
 *
 * The flag, the substitute mark, the positions and the (W)/(L) marks never
 * shrink; only the name inside `.dc-name` does. Every figure stays on one line. */
.sv2-box td:not(.sv2-box__name), .sv2-box th:not(.sv2-box__name) { white-space: nowrap; }
.sv2-box__who { display: flex; align-items: baseline; gap: .3em; min-width: 0; }
.sv2-box__who > * { flex: none; }
.sv2-box__who > .player-link {
  display: flex;
  align-items: baseline;
  gap: .3em;
  min-width: 0;
  flex: 0 1 auto;
  /* On a phone a long press opens the full name, not the system's own link
   * menu, which would cover it. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
.sv2-box__who > .player-link > * { flex: none; }
.sv2-box__who .dc-name {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Squeezed: the card is too narrow for its table, so the name column takes
 * exactly the room the figures leave it, and no more. `dc_cut_names.js` puts
 * this on a card only when its table would overflow: a box that fits keeps
 * the natural width — no gap between a short name and AB (Tony marked that
 * gap in red on the replay). `.sv2-boxes` in front, so the replay's compact
 * rules, loaded after this file, do not win it back. */
.sv2-boxes .sv2-card--squeezed .sv2-box { width: 100%; }
.sv2-boxes .sv2-card--squeezed .sv2-box th.sv2-box__name,
.sv2-boxes .sv2-card--squeezed .sv2-box td.sv2-box__name {
  width: 100%;
  max-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* The two numbers under the place in the play log: the record itself. */
.sv2-log__at {
  display: block;
  font-family: var(--font-mono);
  font-size: .62rem;
  color: var(--text-muted, var(--text-secondary));
  white-space: nowrap;
}

/* The sheet is a fixed-size document, so the window scrolls over it in BOTH
   directions rather than the form being squeezed to fit. The height cap is
   what makes the vertical bar appear: without it the page itself scrolls and
   the zoom buttons disappear off the top just when they are wanted. */
.sv2-sheetwrap {
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  max-height: min(78vh, 900px);
  overscroll-behavior: contain;
}

/* The team switch on the left, the magnifiers on the right. */
.sv2-sheettools {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.sv2-sheettools .sv2-sideswitch { flex: 1 1 240px; margin-bottom: 0; }

/* Three magnifiers, in the shape macOS Preview uses: smaller, actual size,
   bigger. */
.sv2-zoom {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: none;
  padding: 2px;
  border-radius: 999px;
  border: 1px solid var(--border-subtle, var(--border-default));
}
.sv2-zoom__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  cursor: pointer;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-secondary);
}
.sv2-zoom__btn:hover { background: var(--surface-raised, rgba(255, 255, 255, .08)); }
.sv2-zoom__btn:disabled { opacity: .35; cursor: default; background: none; }
.sv2-zoom__btn i { width: 18px; height: 18px; }
/* The "1" sits inside the glass of the middle magnifier, as Preview draws it. */
.sv2-zoom__one {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-53%, -60%);
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
  pointer-events: none;
}
.sv2-zoom__level {
  min-width: 4ch;
  padding: 0 6px;
  font-size: .8rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted, var(--text-secondary));
}

/* Save as PDF, beside the magnifiers: the same drawing, on paper. */
.sv2-pdf {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}
.sv2-pdf__size { display: flex; align-items: center; gap: 6px; }
.sv2-pdf__label {
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
}
.sv2-pdf__size select {
  min-height: 36px;
  padding: 0 8px;
  border-radius: 8px;
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border-subtle, var(--border-default));
}
.sv2-pdf__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 14px;
  text-decoration: none;
  white-space: nowrap;
}
.sv2-pdf__btn i { width: 16px; height: 16px; }

/* NOTHING FAILS SILENTLY — the balance verdict, outside the official form. */
.sv2-balancewarn {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 8px;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--accent-danger, #b3261e);
  background: color-mix(in srgb, var(--accent-danger, #b3261e) 12%, transparent);
  color: var(--accent-danger, #b3261e);
  font-weight: 600;
}
.sv2-balancewarn i { width: 16px; height: 16px; flex: none; }
/* A sheet that does not balance is a scoring mistake. The form's own
   arithmetic disagreeing with the engine's is the product having drifted, and
   it is worse — so it is filled, not outlined. */
.sv2-balancewarn--drift {
  background: var(--accent-danger, #b3261e);
  color: #fff;
  border-color: var(--accent-danger, #b3261e);
}
.sv2-balancewarn__rule {
  margin-left: auto;
  opacity: .6;
  font-weight: 400;
  font-size: .85em;
  white-space: nowrap;
}
.sv2-balancenote {
  margin: 0 0 8px;
  font-size: .85rem;
  color: var(--text-muted, var(--text-secondary));
}

.sv2-sideswitch { display: flex; gap: 4px; margin-bottom: 12px; }
.sv2-sideswitch__btn {
  flex: 1;
  min-height: 44px;
  cursor: pointer;
  border-radius: 9px;
  font-family: var(--font-display);
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: .95rem;
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle, var(--border-default));
}
.sv2-sideswitch__btn[aria-selected="true"] {
  background: var(--accent-gold);
  border-color: var(--accent-gold);
  color: #0D1117;
}

.sv2-spray__dot--hit { fill: var(--accent-live); }
.sv2-spray__dot--out { fill: var(--accent-danger); }
.sv2-spray__counts {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 16px;
  margin: 12px 0 0;
  font-family: var(--font-mono);
  font-size: .8rem;
}
.sv2-spray__counts dt { color: var(--text-secondary); }
.sv2-spray__counts dd { margin: 0; text-align: right; font-weight: 700; color: var(--text-primary); }
.sv2-spray__note {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 9px;
  border-left: 3px solid var(--accent-gold);
  background: var(--bg-elevated, var(--bg-card));
  color: var(--text-secondary);
  font-size: .8rem;
}

@media (prefers-reduced-motion: reduce) {
  .sv2-pitch.is-just-tapped { animation: none; }
  .sv2-result.is-just-tapped { animation: none; }
  .sv2 * { transition: none !important; animation: none !important; }
}

/* A refusal the scorer must not be able to miss. Red, in the panel they are
   looking at, above the buttons they just pressed. */
.sv2-error {
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--accent-danger);
  background: color-mix(in srgb, var(--accent-danger) 12%, transparent);
  color: var(--accent-danger);
  font-weight: 600;
  font-size: .9rem;
  line-height: 1.35;
}
.sv2-error[hidden] { display: none; }

/* ── the cards the count calls for ──────────────────────────────────────── */

/* 🔴 Lit, not pressed. On ball four or the last strike the console shows which
 * cards the count calls for and writes NOTHING — a third strike can be
 * looking, swinging, or dropped with the batter safe, and only the scorer
 * knows which.
 *
 * A gold ring alone was too quiet: Tony looked at a third strike and did not
 * see it. The whole card changes colour and breathes, because this is the one
 * moment on the console where the scorer MUST act and nothing else will move
 * until he does.
 *
 * Written with the attribute as well as the class so it beats the family
 * tints, which are set further up at the same specificity. */
.sv2-entry__buttons:not(.is-choosing) .sv2-result[data-tone].is-called-for {
  background: color-mix(in srgb, var(--accent-gold) 38%, var(--bg-input, var(--bg-card)));
  border-color: var(--accent-gold);
  border-left-color: var(--accent-gold);
  font-weight: 700;
  animation: sv2CalledFor 1.6s ease-in-out infinite;
}

@keyframes sv2CalledFor {
  0%, 100% {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-gold) 50%, transparent);
    background: color-mix(in srgb, var(--accent-gold) 30%, var(--bg-input, var(--bg-card)));
  }
  50% {
    box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent-gold) 16%, transparent);
    background: color-mix(in srgb, var(--accent-gold) 52%, var(--bg-input, var(--bg-card)));
  }
}

/* Still unmistakable without the movement. */
@media (prefers-reduced-motion: reduce) {
  .sv2-entry__buttons:not(.is-choosing) .sv2-result[data-tone].is-called-for {
    animation: none;
    box-shadow: 0 0 0 3px var(--accent-gold);
  }
}

/* 🔴 The moment the scorer picks one, the whole call goes quiet — the colour
 * back to its family's and the breathing off. It has said what it had to say;
 * leaving three cards flashing while he is placing fielders is noise. The
 * card he chose keeps the armed outline, which is a different thing and
 * belongs to the play being built. */

/* The Play button — the replay, in a new tab. A link styled as a button, so
 * it keeps middle-click and the keyboard, and works with no JavaScript. */

.sv2-btn--play {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* ── The pitcher's decision ─────────────────────────────────────────────── */
/* 🔴 Tony named the colours: W green, L red, S gold, HLD green, BS red,
 * QS green. Written as a MARK as well as a colour — "(W)" reads the same to
 * somebody who cannot tell green from red, and on a kiosk screen across a
 * room the bracket is what carries. */

.sv2-decision {
  font-weight: 700;
  font-size: .85em;
  letter-spacing: .02em;
  white-space: nowrap;
}

.sv2-decision--win,
.sv2-decision--hold,
.sv2-decision--quality {
  color: var(--accent-success, #2E7D52);
}

.sv2-decision--loss,
.sv2-decision--blown {
  color: var(--accent-danger, #C0392B);
}

.sv2-decision--save {
  color: var(--accent-gold, #C8A24A);
}

/* ── The head scorer's pitcher decisions ──────────────────────────────────
 *
 * 🔴 Miguel: "I need, sometimes, to override the pitchers decisions."
 *
 * Same shell as the substitution pop-up on purpose — .sv2-subpanel for the
 * overlay, the same head/body/foot grid, the same "may never grow taller than
 * the window" rule. Two dialogs a scorer opens over the same console must not
 * behave differently; the substitution panel learned the hard way that a foot
 * below the fold means a button he can read and cannot reach.
 *
 * Wider than the substitution panel (two team tables side by side, eleven
 * columns each), and it stacks under 900px rather than scrolling sideways —
 * a head scorer works on a laptop, not always a desk.
 */
.sv2 .sv2-dec {
  max-width: 1100px;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "head" "body" "foot";
  max-height: calc(100vh - 3rem);
  grid-template-rows: auto minmax(0, 1fr) auto;
}
.sv2 .sv2-dec .modal-header { grid-area: head; }
.sv2 .sv2-dec .modal-body { grid-area: body; overflow-y: auto; min-height: 0; }
.sv2 .sv2-dec .sv2-dec__foot { grid-area: foot; }

.sv2 .sv2-dec__stamp { margin-left: auto; }

.sv2 .sv2-dec__intro {
  margin: 0 0 14px;
  color: var(--text-secondary);
  font-size: .875rem;
  line-height: 1.5;
}

/* Every reason at once, not the first. A head scorer correcting a sheet
 * should not discover his mistakes one press at a time. */
.sv2 .sv2-dec__refusals {
  margin: 0 0 14px;
  padding: 10px 14px;
  border-left: 4px solid var(--accent-danger, #C0392B);
  background: var(--bg-sunk, var(--bg-card));
  border-radius: var(--radius-sm, 4px);
  color: var(--text-primary);
  font-size: .875rem;
}
.sv2 .sv2-dec__refusals[hidden] { display: none; }
.sv2 .sv2-dec__refusals p { margin: 0 0 4px; }
.sv2 .sv2-dec__refusals p:last-child { margin-bottom: 0; }

.sv2 .sv2-dec__side { margin-bottom: 18px; }
.sv2 .sv2-dec__side:last-child { margin-bottom: 0; }
.sv2 .sv2-dec__sidelabel {
  margin-left: 8px;
  font-weight: 400;
  font-size: .75rem;
  color: var(--text-muted);
}

/* The table scrolls inside its own box; the DIALOG never scrolls sideways. */
.sv2 .sv2-dec__scroll { overflow-x: auto; }
.sv2 .sv2-dec__table { width: 100%; font-size: .8125rem; }
.sv2 .sv2-dec__name { white-space: nowrap; }  /* weight: the one name look (.dc-person) */
.sv2 .sv2-dec__calc { text-align: center; white-space: nowrap; }
.sv2 .sv2-dec__tick { text-align: center; }
.sv2 .sv2-dec__none { color: var(--text-muted); }

/* A dropdown wide enough to read the whole answer. "W" alone is a letter a
 * scorer has to translate; "W — Win" is the answer itself. */
.sv2 .sv2-dec__pick {
  min-width: 108px;
  padding: 4px 6px;
  font-size: .8125rem;
}

.sv2 .sv2-dec__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}
.sv2 .sv2-dec__say {
  margin: 0;
  flex: 1 1 260px;
  min-width: 0;
  font-size: .8125rem;
  color: var(--text-secondary);
}
.sv2 .sv2-dec__actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

@media (max-width: 900px) {
  .sv2 .sv2-dec { max-width: 100%; }
  .sv2 .sv2-dec__actions { margin-left: 0; width: 100%; }
  .sv2 .sv2-dec__actions .sv2-btn { flex: 1 1 auto; }
}

/* ── The paperwork ───────────────────────────────────────────────────────── */
/*
 * Umpires, scorers, notes and expulsions, at the foot of the Field tab and of
 * the box score.
 *
 * 🔴 Every class here has a rule. A panel written against invented class names
 * renders as black text on white in the middle of a dark console — it looks
 * broken, and it looks broken only in the browser, where no test is watching.
 *
 * The colours are the console's own custom properties, never fixed values, so
 * the panel follows the light and dark themes the rest of the page follows.
 */
.sv2 .sv2-paperwork { margin-top: 16px; }

.sv2 .sv2-paperwork__locked {
  /* The sentence saying why nothing can be typed. It has to be read, so it is
   * not the same grey as a hint nobody looks at. */
  color: var(--text-primary);
  font-weight: 500;
}

.sv2 .sv2-paperwork__group {
  padding-top: 10px;
  margin-top: 10px;
  border-top: 1px solid var(--border-subtle, var(--border-default));
}
.sv2 .sv2-paperwork__group:first-of-type { border-top: 0; margin-top: 0; }

.sv2 .sv2-paperwork__label {
  font-family: var(--font-display);
  font-size: .75rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted, var(--text-secondary));
  margin-bottom: 4px;
}

.sv2 .sv2-paperwork__list,
.sv2 .sv2-paperwork__notes {
  /* No bullets: this is a form being read back, not prose. */
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: .85rem;
  color: var(--text-primary);
}
.sv2 .sv2-paperwork__list li,
.sv2 .sv2-paperwork__notes li { padding: 2px 0; }

.sv2 .sv2-paperwork__pos {
  display: inline-block;
  min-width: 2.4em;
  font-weight: 600;
  color: var(--text-secondary);
}

.sv2 .sv2-paperwork__empty {
  margin: 0;
  font-size: .8125rem;
  color: var(--text-secondary);
}

.sv2 .sv2-paperwork__notetext { display: block; }
.sv2 .sv2-paperwork__who {
  display: block;
  font-size: .75rem;
  color: var(--text-secondary);
}

.sv2 .sv2-paperwork__form { margin-top: 10px; }

.sv2 .sv2-paperwork__row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.sv2 .sv2-paperwork__rowlabel {
  flex: 0 0 11em;
  font-size: .8125rem;
  color: var(--text-secondary);
}
/* 🔴 The wrapper, not the select. Tom Select hides the <select> and shows its
 * own control in its place, so a flex rule aimed at `.sv2-input` sizes an
 * element nobody can see and the dropdown collapses to its content width. */
.sv2 .sv2-paperwork__row .sv2-input,
.sv2 .sv2-paperwork__row .ts-wrapper { flex: 1 1 auto; min-width: 0; }

.sv2 .sv2-paperwork__timebox {
  flex: 1 1 auto;
  display: flex;
  gap: 8px;
  min-width: 0;
}
.sv2 .sv2-paperwork__newcoach {
  margin: 0 0 10px 11em;
  font-size: .8125rem;
}
.sv2 .sv2-paperwork__newcoach summary { cursor: pointer; color: var(--text-secondary); }
@media (max-width: 640px) {
  .sv2 .sv2-paperwork__newcoach { margin-left: 0; }
}

.sv2 .sv2-paperwork__noteform {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
}
.sv2 .sv2-paperwork__noteform .sv2-input { flex: 1 1 auto; }

.sv2 .sv2-paperwork__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.sv2 .sv2-paperwork__said {
  font-size: .8125rem;
  color: var(--text-secondary);
}
/* 🔴 A refusal must not look like a confirmation. Same box, different colour,
 * set by the script when the server says no. */
.sv2 .sv2-paperwork__said[data-state="bad"] {
  color: var(--accent-danger);
  font-weight: 600;
}

.sv2 .sv2-paperwork__expulsions .expulsion-section { margin-bottom: 10px; }

@media (max-width: 700px) {
  /* The label above the box rather than beside it: at 11em each, six umpire
   * lines left no room to read the name being typed. */
  .sv2 .sv2-paperwork__row { flex-direction: column; align-items: stretch; gap: 3px; }
  .sv2 .sv2-paperwork__rowlabel { flex: 0 0 auto; }
  .sv2 .sv2-paperwork__noteform { flex-direction: column; align-items: stretch; }
}

/* ── "Out by rule — which case?" ────────────────────────────────────────── */
/* 🔴 A list of sentences, not a grid of two-word cards. `out_by_rule` is
   fourteen numbered cases and each one has to say what happened AND who takes
   the putout, so a `.sv2-result` card — built for a label like "Ground out"
   in a 128px column — is the wrong shape. Everything around this list is the
   Stat Explainer's own panel, unchanged. */
.sv2-obr__heading {
  margin: 14px 0 6px;
  font-family: var(--font-display, var(--font-body));
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.sv2-obr__heading:first-child { margin-top: 0; }

.sv2-obr__list {
  display: grid;
  gap: 6px;
}

.sv2-obr__case {
  display: grid;
  /* Wide enough for the three-letter mark the 2021 document writes. */
  grid-template-columns: 52px minmax(0, 1fr);
  align-items: start;
  gap: 2px 10px;
  width: 100%;
  padding: 9px 11px;
  background: var(--bg-input, var(--bg-card));
  color: var(--text-primary);
  border: 1px solid var(--border-subtle, var(--border-default));
  border-left: 3px solid var(--accent-danger);
  border-radius: 9px;
  font-family: var(--font-body);
  text-align: left;
  cursor: pointer;
  transition: border-color .12s, transform .06s;
}
.sv2-obr__case:hover { border-color: var(--accent-gold); }
.sv2-obr__case:active { transform: translateY(1px); }
.sv2-obr__case:focus-visible { outline: 3px solid var(--accent-gold); outline-offset: 2px; }

/* The number the manual writes beside the OBR — the whole point of asking. */
.sv2-obr__number {
  grid-column: 1;
  grid-row: 1 / span 5;
  align-self: center;
  justify-self: center;
  /* It holds the three-letter mark now — DIF, PPR, RIN — not a number. */
  min-width: 46px;
  padding: 3px 0;
  border-radius: 6px;
  background: var(--bg-surface, var(--bg-card));
  border: 1px solid var(--border-strong, var(--border-default));
  font-family: var(--font-mono);
  font-size: .82rem;
  font-weight: 700;
  text-align: center;
  color: var(--text-primary);
}

.sv2-obr__what {
  grid-column: 2;
  font-size: .84rem;
  font-weight: 500;
  line-height: 1.3;
  overflow-wrap: break-word;
}

/* What to do about the fielder — the question the scorer was left with. */
.sv2-obr__fielder {
  grid-column: 2;
  font-size: .76rem;
  line-height: 1.25;
  color: var(--accent-gold);
  overflow-wrap: break-word;
}

/* Said on the six cases that retire a runner: what the scorer has to DO
   about it, which is the part he is otherwise left holding. */
.sv2-obr__runner {
  grid-column: 2;
  font-size: .76rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--accent-danger);
  overflow-wrap: break-word;
}

.sv2-obr__note {
  grid-column: 2;
  font-size: .72rem;
  line-height: 1.25;
  color: var(--text-secondary);
  overflow-wrap: break-word;
}

/* The five marks of rule 2. The number beside them is a strikeout count and
   not a fielder, which is the opposite of every other number in that box —
   so it is said where the scorer chooses, and said so it cannot be skimmed. */
.sv2-obr__strikeout {
  grid-column: 2;
  margin: 2px 0;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--bg-surface, var(--bg-card));
  border-left: 3px solid var(--accent-gold);
  font-size: .72rem;
  line-height: 1.35;
  color: var(--text-primary);
  overflow-wrap: break-word;
}

/* Never translated, for the same reason every other citation on this console
   is not: a rule you cannot look up in your own rulebook is no use. */
.sv2-obr__rule {
  grid-column: 2;
  font-family: var(--font-mono);
  font-size: .58rem;
  color: var(--text-muted, var(--text-secondary));
  opacity: .72;
}

/* The Official Game Report tab: the paper-size bar, then the document on a
 * white sheet that stays white in the dark theme — it is what gets printed. */
.sv2 .sv2-acta__bar { margin-bottom: 12px; }
.sv2 .sv2-acta {
  overflow-x: auto;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .15);
}

/* The two questions of a play (core/_sv2_live.html): where a runner was put
 * out, and — on a double play with two runners out — where the batter
 * finished. Plain, bordered, in the scorer's line of sight above Save. */
.sv2 .sv2-ask {
  margin: 10px 0;
  padding: 12px 14px;
  border: 2px solid var(--accent-gold, #c9a227);
  border-radius: 10px;
  background: var(--bg-elevated, #fff);
}
.sv2 .sv2-ask--decide { border-color: var(--accent-warn, #d97706); }
.sv2 .sv2-ask__title { font-weight: 700; margin: 0 0 4px; }
.sv2 .sv2-ask__hint { font-size: .85rem; color: var(--text-secondary); margin: 0 0 10px; }
.sv2 .sv2-ask__choices { display: flex; flex-direction: column; gap: 8px; }
.sv2 .sv2-ask__choice { text-align: left; white-space: normal; }
.sv2 .sv2-ask__back { margin-top: 10px; }

/* The pitcher and the batter, each with his team's emblem in front. */
.sv2-status__who { display: inline-flex; align-items: center; }

/* ── The box score's totals, short lines, defence and phone view ──────────
 * Tony, 2026-11-05, with MLB's box score on his phone. One partial for the
 * console, the replay and a game's own page. */
.sv2-box tfoot td {
  font-weight: 700;
  border-top: 1px solid var(--border-strong, var(--border-default));
}
.sv2-box-notes { margin: 10px 0 0; font-size: .8rem; color: var(--text-secondary); }
.sv2-box-notes p { margin: 0 0 4px; }
.sv2-box-notes strong { color: var(--text-primary); }
.sv2-box-fault { margin: 8px 0 0; padding: 6px 8px; font-size: .8rem; color: var(--text-primary); border-left: 3px solid var(--accent-warning, #f59e0b); }
.sv2-box-notes__foot { font-size: .72rem; margin-top: 6px !important; color: var(--text-muted, var(--text-secondary)); }
.box-score-page { margin-top: var(--sv2-gap); }
/* A game's own page: the whole name, on two lines if it must, never cut. */
.box-score-page .sv2-box td.sv2-box__name { white-space: normal; }
.box-score-page .sv2-box__who { display: block; }
.box-score-page .sv2-box__who > .player-link { display: inline; }
.box-score-page .sv2-box__who .dc-name { white-space: normal; overflow: visible; }
.box-score-page .sv2-box--card td:nth-child(2) { white-space: normal; }
.sv2-box-teams { display: none; }
.dc-name--short { display: none; }

/* Two teams side by side where they fit: a season column more than the console. */
.box-score-page .sv2-boxes { grid-template-columns: repeat(auto-fit, minmax(min(460px, 100%), 1fr)); }

@media (max-width: 759px) {
  .sv2-box-teams {
    display: flex;
    gap: 18px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--border-subtle, var(--border-default));
  }
  .sv2-box-teams__btn {
    appearance: none;
    background: none;
    border: 0;
    border-bottom: 3px solid transparent;
    padding: 8px 2px;
    min-height: 44px;
    font-family: var(--font-display);
    font-size: 1rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-align: left;
    color: var(--text-muted, var(--text-secondary));
    cursor: pointer;
  }
  /* Away first until somebody chooses. */
  html:not([data-box-shown="home"]) .sv2-box-teams__btn[data-box-team="away"],
  html[data-box-shown="home"] .sv2-box-teams__btn[data-box-team="home"] {
    color: var(--text-primary);
    border-bottom-color: var(--accent-gold);
  }
  html:not([data-box-shown="home"]) .sv2-boxes--teams > .sv2-card[data-box-side="home"],
  html[data-box-shown="home"] .sv2-boxes--teams > .sv2-card[data-box-side="away"] {
    display: none;
  }
  .sv2-boxes--teams .dc-name--full { display: none; }
  .sv2-boxes--teams .dc-name--short { display: inline; }
  /* All the figures, always: the name folds onto a second line before it is cut. */
  .sv2-boxes--teams > .sv2-card { padding: 10px 8px; }
  .sv2-boxes--teams .sv2-box { font-size: .76rem; }
  .sv2-boxes--teams .sv2-box th, .sv2-boxes--teams .sv2-box td { padding: 6px 3px; }
  .sv2-boxes--teams .sv2-box thead th { letter-spacing: .02em; }
  .sv2-boxes--teams .sv2-box__slot { width: 1.3rem; }
  .sv2-boxes--teams .sv2-box td.sv2-box__name,
  .sv2-boxes--teams .sv2-box th.sv2-box__name { white-space: normal; }
  .sv2-boxes--teams .sv2-box__who { display: block; }
  .sv2-boxes--teams .sv2-box__who > .player-link { display: inline; }
  .sv2-boxes--teams .sv2-box__who .dc-name { display: inline; white-space: normal; overflow: visible; }
  .sv2-boxes--teams .sv2-box__who .dc-name--full { display: none; }
  .sv2-boxes--teams .sv2-box__who .dc-name--short { display: inline; }
}
