/* ═══════════════════════════════════════════════════════════════════════════
   patriot.plus LIVE — CIVIC: the wager, hot takes and the straw poll.

   Loaded after live.css (and after show.css on the projector). Everything here
   is prefixed `cv-` and nothing here restyles a shared class, so this file can
   be added to or taken off a page without moving anything else on it.

   Two registers, the same as the rest of the show:
     · `.paper` — the phone and the officer's panels. White, hard 2px rules,
       Courier, offset black shadows.
     · `.sky` — the projector. Navy, gold, big clamp()ed type sized to be read
       from the back of a hall rather than from a laptop.

   THE ONE RULE THAT IS NOT DECORATION: every control a member touches is at
   least 48px on its short side. These are used standing up, one-handed, in a
   room with the lights down. A 32px target is a control that half the room
   gives up on, and a round where half the room gives up is a broken round.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────── shared small print ─────────────────────────── */
.cv-note { margin: 8px 0 0; font-size: .78rem; line-height: 1.45; }
.cv-dim { color: var(--ink-2); }
.sky .cv-dim { color: var(--sky-muted); }
.cv-hint {
  margin-top: 12px; padding: 10px 12px; border: 2px dashed var(--ink);
  font: 700 .74rem var(--mono); letter-spacing: .06em; text-transform: uppercase; line-height: 1.4;
}
.cv-hint.cv-warn { border-color: var(--orange-ink); color: var(--orange-ink); background: #fff6f2; }

/* ═══════════════════════════ 1. THE WAGER ═══════════════════════════ */

/* The stack, big, because it is the number every decision on this screen is
   measured against. A stake row means nothing beside a chip count you have to
   hunt for. */
.cv-chipcount {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 14px 0 10px; padding: 10px 14px;
  border: 3px solid var(--ink); background: var(--yellow); box-shadow: 4px 4px 0 #000;
}
.cv-chipcount .num { font-size: 2.1rem; line-height: 1; font-variant-numeric: tabular-nums; }
.cv-stakes-label { display: block; margin: 16px 0 8px; }

/* Four chips across on any phone that exists.
   `minmax(0, 1fr)` rather than `1fr`: a bare 1fr track refuses to shrink below
   its content, so one long "lose 1,000" pushed the whole ballot wider than the
   handset and every card on the screen slid sideways. This is the fix for that
   and it is the reason the harness measures scrollWidth. */
.cv-stakes { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }

.cv-stake {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: 88px; padding: 10px 4px;
  border: 2px solid var(--ink); background: #fff; box-shadow: 4px 4px 0 #000;
  font-family: var(--mono); cursor: pointer; border-radius: 0; text-align: center;
  transition: transform .08s;
}
.cv-stake:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #000; }
.cv-stake.on { background: var(--ink); color: #fff; }
.cv-stake.on .cv-win { color: #7dffb0; }
.cv-stake.on .cv-lose { color: #ff9d8a; }
.cv-stake-pct { font: 700 1rem var(--head); letter-spacing: .08em; text-transform: uppercase; }
.cv-stake-line { font-size: .66rem; letter-spacing: 0; line-height: 1.25; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* "nothing either way" is a sentence, not a figure: it wraps rather than being
   cut to "nothing e…", which reads as a bug. Only the win/lose numbers hold
   their line. */
.cv-stake-none { white-space: normal; overflow: visible; }
.cv-stake-line b { font-variant-numeric: tabular-nums; }
.cv-win { color: var(--good); }
.cv-lose { color: var(--bad); }

/* How the room bet. Three rows, widest first, so "how many went big" is the
   line the eye lands on. */
.cv-spread { display: grid; gap: 7px; margin-top: 12px; }
.cv-spread-row { display: grid; grid-template-columns: 11ch minmax(0, 1fr) auto; gap: 10px; align-items: center; }
.cv-spread-k { font: 700 .68rem var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.cv-spread-track { height: 14px; border: 2px solid var(--ink); background: #fff; overflow: hidden; }
.cv-spread-track > i { display: block; height: 100%; width: 0; background: #bdbdbd; transition: width .9s cubic-bezier(.2, .8, .2, 1); }
.cv-spread-row.big .cv-spread-track > i { background: var(--orange); }
.cv-spread-row.mid .cv-spread-track > i { background: var(--gold); }
.cv-spread-n { font: 700 1rem var(--head); font-variant-numeric: tabular-nums; min-width: 2.5ch; text-align: right; }

.sky .cv-spread-k { color: var(--gold); font-size: clamp(.8rem, 1.3vw, 1.1rem); }
.sky .cv-spread-track { height: clamp(14px, 2vw, 26px); border-color: rgba(255, 255, 255, .5); background: rgba(0, 0, 0, .35); }
.sky .cv-spread-row.big .cv-spread-track > i { background: linear-gradient(90deg, var(--orange), #ff8a3d); }
.sky .cv-spread-row.mid .cv-spread-track > i { background: linear-gradient(90deg, var(--gold), #ffd77a); }
.sky .cv-spread-n { font-size: clamp(1.1rem, 2.2vw, 1.9rem); color: #fff; }

/* The swings. A name, a number and whether the nerve paid — never which option
   the person picked. */
.cv-swings { display: grid; gap: 8px; margin-top: 12px; }
.cv-swing {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 2px 10px; align-items: baseline;
  padding: 9px 11px; border: 2px solid var(--ink); background: #fff;
}
.cv-swing.up { border-left: 7px solid var(--good); }
.cv-swing.down { border-left: 7px solid var(--bad); }
.cv-swing-no { font: 700 1rem var(--head); color: var(--ink-2); grid-row: span 2; align-self: center; }
.cv-swing-name { font: 700 .95rem var(--head); letter-spacing: .02em; overflow-wrap: anywhere; }
.cv-swing-delta { font: 700 1.25rem var(--head); font-variant-numeric: tabular-nums; }
.cv-swing.up .cv-swing-delta { color: var(--good); }
.cv-swing.down .cv-swing-delta { color: var(--bad); }
.cv-swing-meta { grid-column: 2 / -1; font: .7rem var(--mono); color: var(--ink-2); letter-spacing: .04em; text-transform: uppercase; }

.sky .cv-swing { border-color: rgba(255, 255, 255, .5); background: rgba(0, 12, 36, .6); padding: 1.1vh 1.4vw; }
.sky .cv-swing-no { color: var(--gold); font-size: clamp(1.1rem, 2.2vw, 2rem); }
.sky .cv-swing-name { font-size: clamp(1.1rem, 2.3vw, 2.1rem); color: #fff; }
.sky .cv-swing-delta { font-size: clamp(1.3rem, 2.8vw, 2.6rem); }
.sky .cv-swing.up .cv-swing-delta { color: #7dffb0; }
.sky .cv-swing.down .cv-swing-delta { color: #ff9d8a; }
.sky .cv-swing-meta { color: var(--sky-muted); font-size: clamp(.72rem, 1.2vw, 1.05rem); }

/* Two columns on the wall: how the room bet, and who it cost. */
.cv-pj-cols { display: grid; grid-template-columns: 1fr 1.25fr; gap: 2vw; margin-top: 2vh; text-align: left; }
@media (max-width: 900px) { .cv-pj-cols { grid-template-columns: 1fr; } }
.cv-pj-label {
  font-family: var(--head); letter-spacing: .24em; text-transform: uppercase;
  color: var(--gold); font-size: clamp(.78rem, 1.3vw, 1.15rem); margin-bottom: .8vh;
}
.cv-pj-stakes { display: flex; gap: 1vw; justify-content: center; flex-wrap: wrap; margin-top: 1.4vh; }
.cv-pj-stake {
  font-family: var(--head); font-weight: 600; letter-spacing: .12em;
  font-size: clamp(.85rem, 1.6vw, 1.4rem); padding: .5vh 1.2vw;
  border: 2px solid rgba(255, 255, 255, .4); color: var(--sky-muted);
}

/* ═══════════════════════════ 2. HOT TAKES ═══════════════════════════ */

/* The rule, said out loud rather than buried in a rules card nobody reads. */
.cv-rule {
  display: block; margin: 12px 0; padding: 11px 13px;
  border: 3px solid var(--ink); background: #fff6bf;
  font: 700 .86rem var(--head); letter-spacing: .04em; text-transform: uppercase; line-height: 1.3;
}
.cv-rule span { display: block; margin-top: 6px; font: 400 .76rem/1.45 var(--mono); text-transform: none; letter-spacing: 0; }
.cv-rule-small { margin-top: 14px; font: 700 .72rem var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); text-align: center; }

.cv-takes { display: block; }
.cv-ratelist { display: grid; gap: 12px; margin-top: 12px; }
.cv-takecard { padding: 12px; border: 2px solid var(--ink); background: #fff; box-shadow: 4px 4px 0 #000; }
.cv-takecard + .cv-takecard { margin-top: 12px; }
.cv-ratelist .cv-takecard + .cv-takecard { margin-top: 0; }
.cv-take-no { font: 700 .72rem var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--ink-2); }
.cv-take-text { margin: 6px 0 12px; font-size: 1.02rem; line-height: 1.4; overflow-wrap: anywhere; }
.cv-take-meta { margin-top: 8px; font: 700 .7rem var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); }

/* 1–5, and every one of them a thumb target. */
.cv-rate { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 7px; }
.cv-rate-btn {
  min-height: 56px; border: 2px solid var(--ink); background: #fff; box-shadow: 3px 3px 0 #000;
  font: 700 1.3rem var(--head); cursor: pointer; border-radius: 0; color: var(--ink);
  transition: transform .08s;
}
.cv-rate-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 #000; }
.cv-rate-btn.on { background: var(--ink); color: #fff; }
.cv-rate-ends { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px; font: .64rem var(--mono); color: var(--ink-2); letter-spacing: .04em; }

/* ── the five-bar histogram ──────────────────────────────────────────────
   The shape IS the result, so this draws the shape and never an average.
   Colour runs along the 1→5 axis, which means a take that split the room
   shows two lit ends with a grey hole between them, and a take everybody
   shrugged at shows an even wash. You can tell them apart from the back. */
.cv-hist5 {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; align-items: end;
}
.cv-hist5-col { display: flex; flex-direction: column; gap: 4px; }
.cv-hist5-n { text-align: center; font: 700 .78rem var(--head); font-variant-numeric: tabular-nums; }
.cv-hist5-bar { display: flex; align-items: flex-end; height: 74px; border-bottom: 2px solid var(--ink); }
.cv-hist5-bar > i { display: block; width: 100%; min-height: 3px; border: 2px solid var(--ink); border-bottom: 0; background: #bdbdbd; transition: height .9s cubic-bezier(.2, .8, .2, 1); }
.cv-hist5-k { text-align: center; font: 700 .72rem var(--mono); color: var(--ink-2); }
/* Short on purpose. The full sentence lives under the rate buttons on the
   phone, where there is room for it; on a projector column 340px wide it wraps
   into porridge, and a wrapped axis label is worse than a terse one. */
.cv-hist5-axis {
  grid-column: 1 / -1; display: flex; align-items: baseline; margin-top: 4px;
  font: .62rem var(--mono); color: var(--ink-2); letter-spacing: .02em;
  flex-wrap: nowrap; white-space: nowrap; text-transform: uppercase;
}
.cv-hist5-axis .grow { flex: 1 1 auto; }
.cv-hist5-axis b { font-family: var(--head); margin: 0 .4em; }

.cv-hist5-col[data-v="1"] > .cv-hist5-bar > i { background: #2a4bbd; }
.cv-hist5-col[data-v="2"] > .cv-hist5-bar > i { background: #7d93dd; }
.cv-hist5-col[data-v="3"] > .cv-hist5-bar > i { background: #c4c4c4; }
.cv-hist5-col[data-v="4"] > .cv-hist5-bar > i { background: var(--gold); }
.cv-hist5-col[data-v="5"] > .cv-hist5-bar > i { background: var(--orange); }

.sky .cv-hist5 { gap: .7vw; max-width: 1000px; }
.sky .cv-hist5.cv-big .cv-hist5-bar { height: clamp(70px, 14vh, 160px); border-color: rgba(255, 255, 255, .5); }
.sky .cv-hist5-bar { height: clamp(70px, 12vh, 150px); border-color: rgba(255, 255, 255, .5); }
.sky .cv-hist5-bar > i { border-color: rgba(255, 255, 255, .5); }
.sky .cv-hist5-n { color: #fff; font-size: clamp(.9rem, 1.7vw, 1.5rem); }
.sky .cv-hist5-k { color: var(--sky-muted); font-size: clamp(.8rem, 1.4vw, 1.2rem); }
.sky .cv-hist5-axis { color: var(--sky-muted); font-size: clamp(.68rem, 1.1vw, 1rem); }
.sky .cv-hist5-col[data-v="1"] > .cv-hist5-bar > i { background: linear-gradient(180deg, #7d9bff, #2a4bbd); }
.sky .cv-hist5-col[data-v="2"] > .cv-hist5-bar > i { background: linear-gradient(180deg, #a9bcf0, #5f7ad0); }
.sky .cv-hist5-col[data-v="3"] > .cv-hist5-bar > i { background: linear-gradient(180deg, #d6d6d6, #8e8e8e); }
.sky .cv-hist5-col[data-v="4"] > .cv-hist5-bar > i { background: linear-gradient(180deg, #ffd77a, var(--gold)); }
.sky .cv-hist5-col[data-v="5"] > .cv-hist5-bar > i { background: linear-gradient(180deg, #ff8a3d, var(--orange)); }

/* the wall */
.cv-pj-rule {
  font-family: var(--head); font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  font-size: clamp(1.1rem, 2.6vw, 2.3rem); color: var(--gold); line-height: 1.15;
  text-shadow: 3px 3px 0 var(--blue); margin-bottom: 1vh;
}
.cv-pj-sub { font-size: clamp(.9rem, 1.7vw, 1.4rem); color: var(--sky-muted); max-width: 64ch; margin: 0 auto 2vh; line-height: 1.4; }
/* One take, two takes or three: `auto-fit` puts them side by side the moment
   there is room, which is the layout the activity actually wants — three
   histograms in a row is a comparison, three stacked is a scroll nobody on a
   projector can do. */
.cv-pj-takes { display: grid; gap: 1.6vh 1.4vw; margin: 0 auto;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.cv-pj-take { padding: 1.4vh 1.4vw; border: 2px solid rgba(255, 255, 255, .5); background: rgba(0, 12, 36, .6); text-align: left; }
.cv-pj-take[data-rank="1"] { border-color: var(--gold); box-shadow: 0 0 40px rgba(240, 168, 48, .3); }
.cv-pj-take-head { display: flex; align-items: baseline; gap: .9vw; margin-bottom: 1vh; min-height: 3.2em; }
.cv-pj-take-no { font-family: var(--head); font-weight: 700; font-size: clamp(1.4rem, 3.4vw, 3rem); color: var(--gold); text-shadow: 3px 3px 0 var(--blue); }
.cv-pj-take-text { font-family: var(--head); font-weight: 600; font-size: clamp(1.1rem, 2.5vw, 2.3rem); line-height: 1.15; overflow-wrap: anywhere; }
.cv-pj-take-meta { margin-top: .8vh; font-family: var(--head); letter-spacing: .12em; text-transform: uppercase; color: var(--sky-muted); font-size: clamp(.75rem, 1.3vw, 1.15rem); }
.cv-pj-quotes .pj-opt { font-size: clamp(1rem, 2.1vw, 1.9rem); }

/* ═══════════════════════════ 3. STRAW POLL ═══════════════════════════ */

.cv-ballot { display: grid; gap: 18px; margin-top: 12px; }
.cv-race { padding-top: 14px; border-top: 2px solid var(--ink); }
.cv-race:first-child { border-top: 0; padding-top: 0; }
.cv-race-title {
  display: flex; align-items: center; gap: 10px; margin: 0 0 10px; overflow-wrap: anywhere;
  font: 700 1.05rem var(--head); letter-spacing: .02em; text-transform: uppercase; line-height: 1.15;
}
.cv-race-no {
  flex: 0 0 auto; display: grid; place-items: center; min-width: 26px; height: 26px;
  border: 2px solid var(--ink); background: var(--yellow); font: 700 .8rem var(--mono);
}
/* The ballot is long and it is scrolled with a thumb, so every target on it is
   a full row and nothing on it is a radio button. */
.cv-opt { min-height: 54px; }
.cv-race-result + .cv-race-result { margin-top: 20px; padding-top: 16px; border-top: 2px solid var(--ink); }

/* ── the line that is not optional ──────────────────────────────────────
   CIVIC.md §3: this rides the projector for the whole activity, not just the
   intro card, because a number and the frame it is read in have to be on the
   screen at the same time. It is written to be read rather than to be
   defended — short sentences, no hedging, no small print. */
.cv-disclaimer {
  display: grid; gap: 6px; margin-top: 16px; padding: 12px 14px;
  border: 3px solid var(--ink); background: #fff; line-height: 1.4;
  font: .82rem/1.45 var(--mono); text-align: left;
}
.cv-disclaimer b { font-family: var(--head); letter-spacing: .02em; text-transform: uppercase; font-size: .92rem; }
.cv-disclaimer.cv-compact { font-size: .74rem; padding: 10px 12px; margin-top: 12px; }
.cv-disclaimer.cv-compact b { font-size: .8rem; }

.sky .cv-disclaimer {
  margin: 3vh auto 0; max-width: 78ch; text-align: center; justify-items: center;
  border: 0; border-top: 3px solid var(--gold); background: rgba(0, 12, 36, .72);
  padding: 1.8vh 2vw; color: #fff;
  font-size: clamp(.92rem, 1.55vw, 1.3rem);
}
.sky .cv-disclaimer b {
  font-size: clamp(1.05rem, 2.1vw, 1.8rem); color: var(--gold);
  letter-spacing: .05em; text-shadow: 2px 2px 0 var(--blue);
}
.sky .cv-disclaimer span { max-width: 70ch; }

.cv-pj-races .pj-opt .key { border-color: rgba(255, 255, 255, .5); color: #fff; }

/* ═══════════════════════════ the editors ═══════════════════════════ */

.cv-qbox { display: grid; gap: 10px; }
.cv-q { display: grid; gap: 8px; padding: 11px; border: 2px solid var(--ink); background: #fbfbfb; }
.cv-q-head { display: flex; align-items: center; gap: 6px; }
.cv-q-no { font: 700 .72rem var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--ink-2); }
.cv-q-text { font-weight: 700; }
.cv-q-answers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 640px) { .cv-q-answers { grid-template-columns: 1fr; } }
.cv-q-ans { display: flex; align-items: center; gap: 8px; }
.cv-q-key {
  flex: 0 0 auto; display: grid; place-items: center; width: 28px; height: 28px;
  border: 2px solid var(--ink); background: #fff; font: 700 .82rem var(--head);
}
.cv-q-foot { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.cv-q-pick { display: grid; gap: 4px; min-width: 110px; }
.cv-race-edit .cv-q-text { font-size: 1rem; }

/* ═══════════════════════════ motion ═══════════════════════════
   live.css already flattens every animation under a reduced-motion setting.
   The transitions declared in this file are named again here so that a bar
   which GROWS is the one thing a person who asked for stillness never gets. */
@media (prefers-reduced-motion: reduce) {
  .cv-hist5-bar > i,
  .cv-spread-track > i,
  .cv-stake,
  .cv-rate-btn { transition: none !important; }
}

/* ── the straw-poll reveal has to FIT ───────────────────────────────────
   The disclaimer is only doing its job if it is on the screen at the same
   time as the number. At 1280x720 with five options and the shared bar sizes
   it fell below the fold, so the bars inside a race result are scoped down
   here — my own wrapper class, so no other activity's bars move. The harness
   measures this: `?scene=fit` renders every projector view in a real 1280x720
   viewport and reports anything taller than the screen. */
.sky .cv-pj-racehead { font-size: clamp(1.7rem, 4.4vw, 4rem); margin-bottom: 1.4vh; }
.sky .cv-pj-racebars .bars { gap: 1vh; }
.sky .cv-pj-racebars .bar { gap: 2px 1.2vw; }
.sky .cv-pj-racebars .bar .opt { font-size: clamp(.95rem, 2vw, 1.6rem); }
.sky .cv-pj-racebars .bar .pct { font-size: clamp(1.05rem, 2.4vw, 1.9rem); }
.sky .cv-pj-racebars .bar .n { font-size: .85rem; }
.sky .cv-pj-racebars .bar .track { height: clamp(12px, 1.9vw, 22px); }
.sky .cv-pj-result .pj-foot { margin-top: 1.6vh; font-size: clamp(.9rem, 1.7vw, 1.4rem); }
.sky .cv-pj-result .cv-disclaimer { margin-top: 1.8vh; padding: 1.2vh 2vw; }

/* The ballot list and the wager's option list, sized so the whole card lands
   inside 1280x720 rather than relying on the projector scaling it down. */
.sky .cv-pj-races, .sky .cv-pj-qopts { gap: .9vh; }
.sky .cv-pj-races .pj-opt, .sky .cv-pj-qopts .pj-opt {
  font-size: clamp(1rem, 2.2vw, 2rem); padding: .85vh 1.3vw; gap: 1.2vw;
}
.sky .cv-pj-q .pj-foot { margin-top: 1.8vh; }
.sky .cv-pj-result .cv-pj-cols { margin-top: 1.4vh; gap: 1.6vw; }
.sky .cv-pj-result .cv-swings { gap: .7vh; margin-top: .6vh; }
.sky .cv-pj-result .cv-swing { padding: .7vh 1.1vw; }
.sky .cv-pj-result .cv-swing-name { font-size: clamp(1rem, 1.9vw, 1.6rem); }
.sky .cv-pj-result .cv-swing-delta { font-size: clamp(1.1rem, 2.2vw, 1.9rem); }
.sky .cv-pj-result .cv-swing-meta { font-size: clamp(.66rem, 1vw, .9rem); }
.sky .cv-pj-result .cv-spread { gap: .6vh; margin-top: .4vh; }
.sky .cv-pj-result .pj-sub { font-size: clamp(1rem, 2.1vw, 1.7rem); }
.sky .cv-pj-result .pj-body { font-size: clamp(.92rem, 1.6vw, 1.35rem); margin-top: 1.2vh; }

/* The last 30px. `.pj-stage` adds 5vh of its own padding on top of the card,
   so a card that measures 719 of 720 still puts the disclaimer 24px off the
   bottom of the screen — which is the same as not having one. Measured, not
   guessed: see `?scene=fit`. */
.sky .cv-pj-result .cv-pj-races { gap: .8vh; }
.sky .cv-pj-result .cv-pj-races .pj-opt { font-size: clamp(.95rem, 1.9vw, 1.7rem); padding: .75vh 1.2vw; }
.sky .cv-pj-result .cv-pj-racehead { margin-bottom: 1.5vh; }
.sky .cv-pj-result .cv-disclaimer { margin-top: 1.4vh; padding: 1vh 2vw; }

/* On the wall the spread labels set their own column — "Went all in" wrapping
   onto two lines inside a fixed 11ch track looked like a layout accident. */
.sky .cv-spread-row { grid-template-columns: auto minmax(0, 1fr) auto; }
.sky .cv-spread-k { white-space: nowrap; }

/* On the answer card the question is context, not the headline — the answer,
   the split and the swings are. Sized down so the whole reveal lands closer to
   one screen before the projector's own fit-to-screen touches it. */
.sky .cv-pj-answer .cv-pj-racehead { font-size: clamp(1.3rem, 3.2vw, 2.9rem); margin-bottom: .8vh; }
.sky .cv-pj-answer .cv-pj-racebars .bars { gap: .7vh; }
.sky .cv-pj-answer .pj-sub { margin-bottom: .6vh; }
