/* The player page's own rules (templates/player.html, head_to_head.html and the player
   not-found page). It also keeps the old briefing rules that no template uses any more.
   Linked after site.css. On a page where a deck list can open, deck-view.css follows it. */

.deck-stack, .intel-stack { display: grid; gap: 1.25rem; align-content: start; min-width: 0; }
.deck-stack .empty-panel, .intel-stack .empty-panel { margin-top: 0; }
.intel-card .empty-panel { margin-top: .6rem; padding: 1rem; box-shadow: none; }
.deck-stack .promo-728 { width: min(728px, 100%); margin: 0 auto; }
.deck-card, .intel-card { padding: 1rem 1.1rem; background: var(--panel); border: 1px solid var(--line); border-radius: .8rem; box-shadow: var(--shadow); }
.latest-deck .deck-heading h2 { margin: 0; color: var(--text); font-size: 1.25rem; font-weight: 700; letter-spacing: normal; text-transform: none; }
.likely-playing { border-left: 3px solid var(--gold); }
.tendency-top { margin: 0; font-size: 1.2rem; font-weight: 800; line-height: 1.3; }
.tendency-top .tendency-evidence { display: block; font-weight: 400; }
.tendency-basis { margin: .35rem 0 0; color: var(--muted); font-size: .85rem; }
.tendency-list { margin: .6rem 0 0; padding-left: 1.2rem; color: var(--muted); font-size: .9rem; }
.tendency-evidence { color: var(--muted); font-size: .82rem; }
.deck-list, .achievement-list { margin: 0; padding: 0; list-style: none; }
.briefing-deck { padding: .6rem .1rem; border-bottom: 1px solid var(--line); }
.briefing-deck:last-child { padding-bottom: 0; border-bottom: 0; }
.briefing-deck:target { border-radius: .4rem; outline: 2px solid var(--gold); outline-offset: 2px; }
.deck-heading { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem; }
.deck-heading h3 { margin: 0; font-size: 1.05rem; }
.method-note, .deck-context, .achievement-date, .prelim-note { color: var(--muted); font-size: .82rem; }
.reported-note { border: 1px solid currentColor; border-radius: .25rem; padding: .08rem .3rem; font-size: .72rem; line-height: 1.2; }
.deck-context { margin: .25rem 0 0; }
.achievement { display: flex; align-items: baseline; gap: .6rem; padding: .45rem 0; font-size: .88rem; }
.finish-pill { padding: .15rem .55rem; font-size: .82rem; font-weight: 750; white-space: nowrap; background: var(--panel-strong); border: 1px solid var(--line); border-radius: 99rem; }
.finish-pill.win { color: #18150d; background: var(--gold); border-color: var(--gold); }
.achievement-date { display: block; }
.prelim-note { margin: .8rem 0 0; }
.h2h-intro { margin: 0; color: var(--muted); }
.h2h-form { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }
.h2h-form input { flex: 1; max-width: 18rem; min-width: 10rem; }
.h2h-forget { color: var(--text); background: var(--panel-strong); border: 1px solid var(--line); }
.h2h-note { margin: .6rem 0 0; color: var(--muted); font-size: .82rem; }
.h2h-record { margin: 0; }
.h2h-format-record.ahead { color: var(--gold); }
.h2h-none, .h2h-overall { color: var(--muted); }
.h2h-list { margin: .4rem 0 0; padding: 0; list-style: none; }
.h2h-match { display: flex; align-items: baseline; gap: .6rem; padding: .45rem 0; font-size: .88rem; }

/* ==========================================================================
   REDESIGN TICKET 12 — the player page, A2 (efforts/redesign/issues/12-build-player.md)
   The first screen answers one question: what will this player bring, and how sure can I be.
   The call is the hero, the run strip is the page's second object, and four numbers close the
   window section. Everything else is a second read.

   Confidence borrows the site's certainty pair (`--sure` / `--unsure`, declared at `:root`)
   rather than inventing a third colour. Pale means the field has settled this slot and violet
   means the pilot is still choosing; here it is the same claim about a person — pale means this
   player has settled on a deck, violet means they are still choosing one.
   ========================================================================== */


.player-page { padding-block: 1.2rem 5rem; }
.player-page h1 { max-width: 24ch; margin: 0; font-size: clamp(1.9rem, 5vw, 3.2rem); font-weight: 850; line-height: 1; letter-spacing: -.04em; }
.player-facts { margin: .7rem 0 0; color: var(--muted); font-size: .92rem; }

/* The format rail as a row of chips under the name, ordered by how much of the window each
   format holds. A format with nothing in it stays, dimmed, because its absence is also an
   answer. */
.player-rail { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: 1rem; }
.player-rail a { padding: .3rem .6rem; color: var(--muted); font-size: .8rem; font-weight: 650; text-decoration: none; background: var(--panel); border: 1px solid var(--line); border-radius: 99rem; }
.player-rail a:hover { color: var(--text); border-color: var(--quiet); }
.player-rail a.on { color: #17140c; background: var(--gold); border-color: var(--gold); }
.player-rail a.zero { color: #5a6070; background: none; }
.player-rail a b { font-weight: 800; font-variant-numeric: tabular-nums; }
.player-rail a small { margin-left: .3rem; font-size: .82em; opacity: .8; }

/* ---------- the hero: the call ----------
   The answer is at the size of an answer: the deck's art, the deck name over it, and the band
   chip. `Not enough` changes the picture, not just the chip: the art shortens and drains and
   the name comes down a size, because a player with one list was getting the same 17rem of art
   as a player with thirty-three. */
.player-hero { position: relative; width: min(100% - 2rem, 70rem); margin: 1.4rem auto 0; }
.player-hero-frame { position: relative; overflow: hidden; border-radius: .5rem;
  -webkit-mask-image: linear-gradient(90deg, #0000 0, #000 min(3rem, 8%), #000 calc(100% - min(3rem, 8%)), #0000 100%);
  mask-image: linear-gradient(90deg, #0000 0, #000 min(3rem, 8%), #000 calc(100% - min(3rem, 8%)), #0000 100%); }
.player-hero-art { display: block; width: 100%; height: clamp(11rem, 21vw, 17rem); object-fit: cover; object-position: center 30%; }
.player-hero-art-blank { display: block; width: 100%; height: clamp(11rem, 21vw, 17rem); background: repeating-linear-gradient(135deg, #171b23 0 8px, #1e232e 8px 16px); }
.player-hero-scrim { position: absolute; inset: 0; background: linear-gradient(180deg, #111319cc 0, #11131959 26%, #111319d6 70%, var(--bg) 100%), linear-gradient(90deg, #111319d1 0, #11131933 55%, #11131900 100%); }
.player-hero-body { position: absolute; inset: auto 0 0; padding: 0 1.2rem 1.1rem; }
.player-hero-credit { position: absolute; top: .7rem; right: 1rem; margin: 0; color: #ffffff85; font-size: .66rem; }
.player-hero[data-band="none"] .player-hero-art,
.player-hero[data-band="none"] .player-hero-art-blank { height: clamp(7rem, 13vw, 10.5rem); filter: grayscale(.55); }
.player-hero[data-band="none"] .player-call-name { font-size: clamp(1.6rem, 4vw, 2.6rem); }
.player-hero[data-band="none"] .player-call-name .color-pip { width: clamp(1.1rem, 2.2vw, 1.5rem); height: clamp(1.1rem, 2.2vw, 1.5rem); }

/* The mixed treatment: four crops in one frame instead of one, because a single card face
   under the words "something different" names a deck the headline has refused to name. */
span.player-mosaic { display: flex; gap: 2px; overflow: hidden; }
span.player-mosaic img { flex: 1 1 0; min-width: 0; height: 100%; object-fit: cover; }

.player-call-eyebrow { margin: 0 0 .35rem; color: var(--muted); font-size: .68rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.player-call-name { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .7rem; margin: 0; font-weight: 850; line-height: .98; letter-spacing: -.04em; }
.player-call-name .color-identity { min-height: 0; gap: .2rem; }
.player-call-name .color-pip { width: clamp(1.3rem, 3vw, 2.1rem); height: clamp(1.3rem, 3vw, 2.1rem); }
.player-call-name .color-identity img { filter: drop-shadow(0 2px 6px #0009); }
.player-call-name.is-small { font-size: 1.4rem; }
.player-call-why { max-width: 46ch; margin: .6rem 0 0; color: var(--muted); font-size: .95rem; }
.player-call-why b { color: var(--text); font-weight: 700; }
.player-call-alt { margin: .45rem 0 0; color: var(--quiet); font-size: .84rem; }
.player-call-alt b { color: var(--muted); font-weight: 650; }
.player-hero-body .player-call-why { max-width: 52ch; text-shadow: 0 1px 6px #000a; }

/* The band chip: one word for how far the call can be trusted, in the ink the run itself uses. */
.player-band { display: inline-block; padding: .18rem .48rem; color: #10131b; font-size: .62rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; background: var(--sure); border-radius: .25rem; }
.player-band.unsure { background: var(--unsure); }
.player-band.none { color: var(--quiet); background: none; box-shadow: inset 0 0 0 1px var(--line); }

/* The last list, on the first screen. The hero names the deck; this names the event it came
   from and opens it. It is a bar rather than a link in body copy because "see the list" is the
   second thing every visitor wants. */
.player-last { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem 1.2rem; width: min(100% - 2rem, 70rem); margin: .9rem auto 0; padding: .7rem .8rem .7rem 1rem; background: var(--panel); border: 1px solid var(--line); border-radius: .5rem; }
.player-last-what { display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .7rem; min-width: 0; }
.player-last-what > b { display: flex; align-items: center; gap: .35rem; font-size: 1rem; font-weight: 780; }
.player-last-eyebrow { color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; }
.player-last-where { color: var(--quiet); font-size: .84rem; }
.player-last-open { padding: .45rem .85rem; color: #17140c; font-size: .82rem; font-weight: 800; text-decoration: none; background: var(--gold); border-radius: .35rem; }
.player-last-open:hover { filter: brightness(1.1); }
.player-last-open:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* ---------- the window: three months, drawn as frames ----------
   The heading names the axis, and the strip under it is the page's second object: one frame
   per run, so the width of a frame is how long they stayed on that deck and every edge in the
   row is a day they changed. Newest first, so the left edge is always now. */
.player-run-h { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: .3rem .8rem; margin: 0 0 .5rem; color: var(--muted); font-size: .72rem; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; }
.player-run-h em { color: var(--quiet); font-weight: 600; font-style: normal; letter-spacing: 0; text-transform: none; }
.player-window { margin-top: 1.6rem; }

.player-frames { display: flex; gap: 2px; height: clamp(8.5rem, 16vw, 12rem); margin: 0; padding: 0; overflow: hidden; list-style: none; border-radius: .35rem; }
.player-frame { position: relative; display: flex; flex: var(--frame-flex, 1) 1 0; gap: 1px; min-width: 0; background: var(--panel-strong); }
.player-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .82; transition: opacity .15s; }
.player-frame:hover .player-art { opacity: 1; }
/* Dark at both ends: the top holds the result marks, the bottom holds the deck name. */
.player-scrim { position: absolute; inset: 0; background: linear-gradient(180deg, #111319c4 0, #11131926 30%, #11131933 52%, #111319e0 100%); }
.player-frame.noart { background: var(--panel-strong); box-shadow: inset 0 0 0 1px #ffffff12; }
.player-frame.gap { background: repeating-linear-gradient(135deg, #22283400 0 5px, #1b202b 5px 10px), var(--panel-strong); }
/* The current run, in the gold the tournament page gives the champion. A pseudo-element rather
   than a shadow on the frame, because the art is absolutely positioned and paints over both. */
.player-frame.now { z-index: 2; }
.player-frame.now::after { position: absolute; z-index: 3; inset: 0; box-shadow: inset 0 0 0 1px var(--gold), inset 0 -3px var(--gold); content: ""; pointer-events: none; }

/* One slice per event, and every slice is a link into its list. */
.player-seg { position: relative; z-index: 1; flex: 1 1 0; min-width: 0; display: block; border-right: 1px solid #11131959; text-decoration: none; }
.player-seg:last-child { border-right: 0; }
.player-seg.blank { flex: .3 1 0; background: #0d1017cc; }
/* A slice in a gap is not a link, because there is no list under it. It keeps the hatch of the
   frame instead of the dark notch, and still answers the pointer. */
.player-seg.dead { background: transparent; }
.player-seg:hover { background: #ffffff2b; }
.player-seg.dead:hover { background: #ffffff14; }
.player-seg:focus-visible { z-index: 4; outline: 2px solid var(--blue); outline-offset: -2px; }
.player-frames:focus-visible { outline: 3px solid var(--blue); outline-offset: 3px; }
/* The strip is one tab stop, so arrow keys move a virtual focus the browser cannot draw. The
   active slice carries the same ring a real focus would, but only while the strip holds the
   keyboard, so a pointer reader never sees a stale mark. */
.player-frames:focus-visible [data-deck-rover-active] { z-index: 4; outline: 2px solid var(--blue); outline-offset: -2px; }
/* The slice whose list is open in the pane, marked pale rather than gold: gold is already
   saying "this is the deck they are on now", and two claims in one colour is one claim nobody
   can read. */
.player-seg.is-picked { background: #ffffff1c; box-shadow: inset 0 0 0 1px #ffffff8a; }

/* The result marks, on the rail along the top. Only three finishes get one, because a mark on
   every event is a mark on nothing. */
.player-mark-rail { position: absolute; top: .4rem; left: 50%; width: 7px; height: 7px; margin-left: -3.5px; }
.player-mark-rail.won { background: var(--gold); box-shadow: 0 0 4px #e0b45899; transform: rotate(45deg); }
.player-mark-rail.t8 { background: #11131959; border: 1.5px solid var(--gold); border-radius: 50%; }
.player-mark-rail.t16 { top: .55rem; width: 4px; height: 4px; margin-left: -2px; background: #ccd4e8b8; border-radius: 50%; }
.player-mark-rail.clean { top: .58rem; width: 10px; height: 3px; margin-left: -5px; background: var(--gold); border-radius: 1px; }

.player-label { position: absolute; z-index: 2; inset: auto .35rem .35rem .45rem; overflow: hidden; color: var(--text); text-shadow: 0 1px 4px #000d; pointer-events: none; }
.player-label b { display: block; overflow: hidden; font-size: .86rem; font-weight: 780; line-height: 1.2; text-overflow: ellipsis; white-space: nowrap; }
.player-label span { display: block; overflow: hidden; color: #c8cfdf; font-size: .7rem; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; }
.player-frame.narrow .player-label { display: none; }
.player-frame.now .player-label { display: block; }
.player-frame.now.narrow .player-label span { display: none; }

/* A strip of one event is not a strip: below eight events the frames stop stretching and keep
   a fixed width, so one event reads as one event instead of as a banner. */
.player-frames.sparse { justify-content: flex-start; }
.player-frames.sparse .player-frame { flex: 0 0 auto; }
/* A width, not a flex-basis: Firefox leaves flex-basis out of the frame's auto width, so the
   frame collapses and the slices spill out past its art. */
.player-frames.sparse .player-seg { flex: none; width: 9rem; }
.player-frames.sparse .player-seg.blank { width: 2.6rem; }

.run-scale { display: flex; margin-top: .3rem; color: var(--quiet); font-size: .7rem; }
.run-scale span { flex: 1 1 0; padding-top: .25rem; border-top: 1px solid var(--line); }
.run-scale span + span { margin-left: 2px; }
.run-scale .run-scale-end { text-align: right; }

/* The readout line, kept on its hint: ticket 20 fills it on hover or focus. It has a fixed
   height so nothing moves when it fills. */
.player-read { height: 2.5rem; margin: .5rem 0 0; overflow: hidden; color: var(--muted); font-size: .82rem; line-height: 1.25rem; }

.run-key { display: flex; flex-wrap: wrap; gap: .2rem 1.4rem; margin: .5rem 0 0; color: var(--quiet); font-size: .76rem; }
.run-key i { display: inline-block; width: .7rem; height: .7rem; margin-right: .3rem; vertical-align: -1px; border-radius: 2px; }
.run-key i.gold { background: var(--gold); }
.run-key i.notch { background: #0d1017; box-shadow: inset 0 0 0 1px var(--line); }
.run-key i.hatch { background: repeating-linear-gradient(135deg, #22283400 0 5px, #1b202b 5px 10px), var(--panel-strong); }
.run-key i.won { background: var(--gold); border-radius: 1px; transform: rotate(45deg) scale(.8); }
.run-key i.t8 { background: none; border: 1.5px solid var(--gold); border-radius: 50%; }
.run-key i.t16 { width: .4rem; height: .4rem; margin-right: .45rem; margin-left: .15rem; background: #ccd4e8b8; border-radius: 50%; }
.run-key i.clean { height: .25rem; margin-bottom: .2rem; background: var(--gold); border-radius: 1px; }

/* The four numbers close the same block the strip opens: the strip says what they play, these
   say how it goes. The dormant rating vital carries a dashed tag and a muted value. */
.player-window .page-vitals { margin-top: 1.2rem; }

/* ---------- head to head ----------
   Four states, all drawn. The change/forget control is one line of small text, not two gold
   buttons: changing a remembered handle is a rare, quiet action. */
.h2h-record { display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem .9rem; }
.h2h-score { font-size: clamp(2rem, 5vw, 3.4rem); font-weight: 850; font-variant-numeric: tabular-nums; letter-spacing: -.045em; line-height: 1; }
.h2h-score .ahead { color: var(--gold); }
.h2h-score .behind { color: var(--blue); }
.h2h-verdict { color: var(--muted); font-size: .95rem; }
.h2h-strip { display: flex; flex-wrap: wrap; gap: 3px; margin-top: .8rem; }
.h2h-pip { display: grid; place-items: center; width: 1.5rem; height: 1.5rem; color: #10131b; font-size: .7rem; font-weight: 800; background: var(--blue); border-radius: .25rem; }
.h2h-pip.w { background: var(--gold); }
.h2h-pip.d { color: var(--muted); background: var(--panel-strong); }
.h2h-list { margin: .8rem 0 0; padding: 0; list-style: none; }
.h2h-list li { display: grid; grid-template-columns: 2.6rem minmax(0, 1fr) auto; gap: .2rem .7rem; align-items: baseline; padding: .3rem .1rem; border-bottom: 1px solid var(--line); font-size: .86rem; }
.h2h-list b { color: var(--gold); font-variant-numeric: tabular-nums; }
.h2h-list b.l { color: var(--blue); }
.h2h-list span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.h2h-list em { color: var(--quiet); font-size: .82rem; font-style: normal; }
.h2h-form { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: .8rem; }
.h2h-form input { flex: 1 1 12rem; padding: .55rem .7rem; font-size: .9rem; }
.h2h-form button { padding: .55rem .9rem; font-size: .9rem; }
.h2h-note { max-width: 52ch; margin: .6rem 0 0; color: var(--quiet); font-size: .8rem; }
.h2h-empty { padding: 1rem; color: var(--muted); font-size: .9rem; background: var(--panel); border: 1px dashed var(--line); border-radius: .6rem; }
.h2h-empty p { margin: 0; }
.h2h-swap { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin: .7rem 0 0; color: var(--quiet); font-size: .8rem; }
.h2h-swap input { flex: 0 1 11rem; padding: .3rem .5rem; font-size: .82rem; }
.h2h-swap b { color: var(--muted); font-weight: 650; }
.linkish { padding: 0; color: var(--blue); font-size: inherit; font-weight: 600; background: none; border: 0; text-decoration: underline; cursor: pointer; }
.linkish:hover { color: var(--text); }

/* ---------- their lists: the picker and the pane ----------
   Every published list as a row beside one open list in a floating pane. The pane floats with
   the picker for the same reason the tournament page's does. */
/* The second track only exists once the pane does. Without scripting the pane is hidden and
   the picker takes the whole row, the way the tournament page's layout does. */
.player-split { margin-top: .4rem; }
.js-deck-pane .player-split { display: grid; grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr); gap: 1.2rem 2rem; align-items: start; }
.player-picker { border-top: 1px solid var(--line); }
/* The one row that does not baseline its own tracks: its date and chevron are single-line and its
   middle track baselines its own contents, so it keeps the stretch ticket 36 approved. */
.player-picker > .deck-list-row { grid-template-columns: 4.6rem minmax(0, 1fr) 1.1rem; gap: .1rem .7rem; align-items: normal; width: 100%; padding: .42rem .45rem; border-bottom: 1px solid var(--line); }
.player-picker > .deck-list-row.is-picked { box-shadow: inset 3px 0 #ccd4e8; }
.player-picker > .deck-list-row.is-picked .player-pick-date, .player-picker > .deck-list-row.is-picked .player-pick-place { color: var(--muted); }
.player-pick-date { color: var(--quiet); font-size: .82rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.player-pick-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: .1rem .55rem; min-width: 0; }
.player-pick-arch { overflow: hidden; font-weight: 650; text-overflow: ellipsis; white-space: nowrap; }
.player-pick-place { color: var(--muted); font-size: .84rem; font-variant-numeric: tabular-nums; }
.player-pick-chev { color: var(--quiet); font-size: .7rem; text-align: right; }
.player-picker > .deck-list-row.is-picked .player-pick-chev { color: #ccd4e8; }
.player-key { display: flex; flex-wrap: wrap; gap: .2rem 1.4rem; margin: .5rem 0 0; color: var(--quiet); font-size: .76rem; }
.player-key b { color: var(--gold); font-weight: 800; }
.player-split > div > .deck-list-source { margin-top: .5rem; color: var(--muted); }
.player-split > div > .deck-list-source > summary { cursor: pointer; }
.player-split .deck-list-pane { min-width: 0; }
.js-deck-pane .player-split .deck-list-pane { position: sticky; top: 1rem; max-height: calc(100dvh - 2rem); overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; scrollbar-width: thin; }
.player-split .deck-pane-head b { font-weight: 800; }

/* ---------- best finishes ----------
   The prototype's plain pills: `2nd`, `5–0`, `4–0`, gold only for a win. */
.player-finishes { display: grid; grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); gap: .1rem 1.4rem; margin: 0; padding: 0; list-style: none; }
.player-finishes li { display: grid; grid-template-columns: 3.2rem minmax(0, 1fr); gap: .2rem .7rem; align-items: baseline; padding: .34rem .1rem; border-bottom: 1px solid var(--line); }
.player-finish-pill { color: var(--muted); font-size: .82rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.player-finish-pill.win { color: var(--gold); }
.player-finish-event { min-width: 0; overflow: hidden; font-size: .88rem; text-overflow: ellipsis; white-space: nowrap; }
.player-finish-event em { color: var(--quiet); font-size: .8rem; font-style: normal; }

@media screen and (max-width: 62rem) {
  .js-deck-pane .player-split { grid-template-columns: minmax(0, 1fr); }
  .js-deck-pane .player-split .deck-list-pane { position: static; max-height: none; overflow: visible; }
}

@media screen and (max-width: 46rem) {
  /* The strip keeps its shape and scrolls sideways rather than stacking: stacked, the one
     thing it is for becomes a list of 72 rows. */
  .run-scroll { overflow-x: auto; padding-bottom: .4rem; }
  .run-scroll .player-frames, .run-scroll .run-scale { min-width: 30rem; }
  /* The place line holds two lines of the wide layout's readout, which is three of this one.
     The height stays fixed so nothing moves; a third line is what stops the place and the
     record, the end of every readout, being cut off. */
  .player-read { height: 3.75rem; }
  .player-picker > .deck-list-row { grid-template-columns: 4.2rem minmax(0, 1fr) 1rem; }
  .player-finishes { grid-template-columns: minmax(0, 1fr); }
  /* The hero body is anchored to the bottom of the frame, so at 375px its copy climbs out of
     the top of the art and lands on the credit. The art grows to hold it and the credit goes:
     a caption naming the card a crop came from is the first thing a 375px screen can spare. */
  .player-hero-art, .player-hero-art-blank { height: 16rem; }
  .player-hero[data-band="none"] .player-hero-art,
  .player-hero[data-band="none"] .player-hero-art-blank { height: 11rem; }
  .player-hero-credit { display: none; }
}
