/* ═══════════════════════════════════════════════════════════════════════════
   race-sheet.css — one office, the whole field, side by side
   ────────────────────────────────────────────────────────────────────────────
   Two layouts, one markup. The pane list is a flex column on a phone (stacked
   cards, each with a sticky header so the name and the score stay on screen
   while the issue rows scroll past) and a horizontal track on a wide screen
   (true side-by-side panes, each column a candidate).

   Issue labels repeat inside every pane rather than living in a shared left
   gutter. A gutter reads beautifully at 1400px and collapses into nonsense the
   moment one pane wraps; repeating the label costs a line of type and means the
   cell is never orphaned from the issue it answers, at any width, in any
   reading order, including a screen reader going pane by pane.

   Colour discipline: the only good/bad ramp on this surface is the match score
   (from _alignScoreColor, the app's own) and the per-issue verdict tint on a
   cell. Issue hues come from PDXIssueColors via inline --pdx-ic* custom
   properties, so this file contains no per-issue rules. Nothing is coloured by
   party, because nothing here reads party.

   Targets are 44px minimum on every control, per the mobile brief.
   ═══════════════════════════════════════════════════════════════════════════ */

.rs-overlay {
  position: fixed; inset: 0; z-index: 9600;
  display: none; align-items: flex-start; justify-content: center;
  background: rgba(3, 7, 18, 0.86);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; transition: opacity 0.18s ease;
  overflow-y: auto; overscroll-behavior: contain;
  padding: 0;
}
.rs-overlay.is-open { opacity: 1; }

.rs-sheet {
  width: 100%; max-width: 1240px;
  background: linear-gradient(180deg, #0b1220 0%, #070c16 100%);
  border: 1px solid rgba(96, 165, 250, 0.18);
  border-radius: 0;
  /* THE BOTTOM GAP IS RESERVED ONCE, HERE. On a phone this sheet runs edge to
     edge, so the last thing in it — the final candidate card, or the footer that
     promises party is never read — ends where the device does: under the home
     indicator on an iPhone, under whatever bar the browser is currently showing
     everywhere else. env() resolves to 0 on a desktop, so the same declaration
     serves both and there is no second number to keep in sync. */
  padding: 0 0 calc(2rem + env(safe-area-inset-bottom, 0px));
  min-height: 100%;
  /* The height of .rs-hd, written down once, because two sticky things stack on
     this sheet and the lower one has to know how tall the upper one is. It is
     0.9rem of padding twice over a row whose tallest child is the 44px close
     button (2.75rem) — 4.55rem, rounded up so the pane header clears the border
     rather than kissing it. Guessing this number is how a sticky header ends up
     tucked under the one above it, which is exactly what it used to do. */
  --rs-hd-h: 4.6rem;
}
@media (min-width: 900px) {
  .rs-overlay { align-items: center; padding: 1.5rem; }
  .rs-sheet { border-radius: 1rem; min-height: 0; max-height: calc(100vh - 3rem); overflow-y: auto; }
}

/* ── Header ───────────────────────────────────────────────────────────────── */
.rs-hd {
  position: sticky; top: 0; z-index: 6;
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.9rem 1rem;
  background: linear-gradient(180deg, rgba(11, 18, 32, 0.98), rgba(11, 18, 32, 0.92));
  border-bottom: 1px solid rgba(96, 165, 250, 0.2);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.rs-hd-title { display: flex; align-items: center; gap: 0.65rem; flex: 1; min-width: 0; }
.rs-hd-ico {
  width: 2.5rem; height: 2.5rem; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.15rem; border-radius: 0.7rem;
  /* The seat's own hue as a flat tint. Deliberately not color-mix(): this file
     has to render identically in every browser the rest of the app supports, and
     an opacity wrapper gets the same result with none of the support question. */
  background: rgba(148, 163, 184, 0.1);
  border: 1px solid currentColor; color: var(--rs-seat, #60a5fa);
}
.rs-hd-kicker {
  display: block; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--rs-seat, #60a5fa);
}
.rs-hd-seat {
  margin: 0; font-family: 'Oswald', 'Barlow Condensed', sans-serif;
  font-size: 1.2rem; letter-spacing: 0.03em; color: #fff; line-height: 1.1;
}
.rs-close {
  flex: 0 0 auto; min-width: 44px; min-height: 44px;
  font-size: 1.5rem; line-height: 1; color: #9fb4d4;
  background: rgba(148, 163, 184, 0.1); border: 1px solid rgba(148, 163, 184, 0.22);
  border-radius: 0.6rem; cursor: pointer;
}
.rs-close:hover { color: #fff; background: rgba(148, 163, 184, 0.2); }

/* ── Controls: the toggle, the rank line, the explainer ───────────────────── */
.rs-controls { padding: 0.9rem 1rem 0.2rem; }
.rs-modes {
  display: inline-flex; gap: 0.25rem; padding: 0.25rem;
  background: rgba(15, 23, 42, 0.9); border: 1px solid rgba(96, 165, 250, 0.2);
  border-radius: 0.7rem; flex-wrap: wrap;
}
.rs-mode {
  min-height: 44px; padding: 0.4rem 0.85rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.82rem;
  letter-spacing: 0.04em; color: #9fb4d4;
  background: transparent; border: 1px solid transparent; border-radius: 0.5rem;
  cursor: pointer; white-space: nowrap;
}
.rs-mode:hover { color: #e2e8f0; }
/* A ruler that cannot rank yet is dimmed, never hidden: pressing it is how a
   reader with no positions learns what would change. */
.rs-mode.is-gated { opacity: 0.62; font-style: italic; }
/* The Overview tab. Same tablist, deliberately not .rs-mode — that class means
   "can order this field", and this one cannot. */
.rs-vtab {
  min-height: 44px; padding: 0.4rem 0.85rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.82rem;
  letter-spacing: 0.04em; color: #9fb4d4;
  background: transparent; border: 1px solid transparent; border-radius: 0.5rem;
  cursor: pointer; white-space: nowrap;
}
.rs-vtab:hover { color: #e2e8f0; }
.rs-vtab.is-on {
  color: #0b1220; font-weight: 700;
  background: linear-gradient(135deg, #a7f3d0, #34d399);
  border-color: #34d399;
}
.rs-mode.is-on {
  color: #0b1220; font-weight: 700;
  background: linear-gradient(135deg, #93c5fd, #60a5fa);
  border-color: #60a5fa;
}
.rs-rankline, .rs-explain, .rs-thinaxis, .rs-onlyone, .rs-foot {
  font-family: 'Barlow Condensed', sans-serif; line-height: 1.45; margin: 0.55rem 0 0;
}
.rs-rankline { font-size: 0.82rem; color: #cbd5e1; }
.rs-rankline b { color: #93c5fd; }
.rs-explain {
  font-size: 0.74rem; color: #7596c0;
  padding: 0.45rem 0.6rem; border-left: 2px solid rgba(96, 165, 250, 0.35);
  background: rgba(96, 165, 250, 0.06); border-radius: 0 0.4rem 0.4rem 0;
}
.rs-explain b { color: #bfdbfe; }
.rs-thinaxis { font-size: 0.74rem; color: #fbbf24; }
.rs-onlyone {
  font-size: 0.8rem; color: #cbd5e1; margin: 0.6rem 1rem 0;
  padding: 0.6rem 0.7rem; border-radius: 0.5rem;
  background: rgba(251, 191, 36, 0.08); border: 1px solid rgba(251, 191, 36, 0.25);
}
/* A field of one is an admission, so it is written as one: what is true, what
   it does NOT mean, and what the reader can do instead of waiting. */
.rs-onlyone-l { margin: 0 0 0.45rem; line-height: 1.5; }
.rs-onlyone-l:first-child { color: #fde68a; }
.rs-onlyone-l b { color: #fbbf24; }
.rs-onlyone-l + .rs-onlyone-l { font-size: 0.76rem; color: #9fb4d4; }
.rs-onlyone-a { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.6rem 0 0; }
.rs-onlyone-b {
  min-height: 44px; padding: 0.4rem 0.8rem; border-radius: 0.5rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem;
  color: #0b1220; font-weight: 700; cursor: pointer;
  background: linear-gradient(135deg, #fde68a, #fbbf24); border: 1px solid #fbbf24;
}
.rs-onlyone-b.is-alt {
  color: #bfdbfe; font-weight: 400;
  background: rgba(96, 165, 250, 0.1); border: 1px solid rgba(96, 165, 250, 0.3);
}
.rs-foot {
  font-size: 0.72rem; color: #64748b; margin: 1rem 1rem 0;
  padding-top: 0.7rem; border-top: 1px solid rgba(148, 163, 184, 0.14);
}
.rs-foot b { color: #94a3b8; }

/* ── No-stance CTA ────────────────────────────────────────────────────────── */
.rs-cta {
  margin: 0.9rem 1rem 0; padding: 0.9rem;
  background: linear-gradient(135deg, rgba(94, 234, 212, 0.1), rgba(94, 234, 212, 0.03));
  border: 1px solid rgba(94, 234, 212, 0.3); border-radius: 0.75rem;
}
.rs-cta-hd {
  margin: 0; font-family: 'Oswald', sans-serif; font-size: 0.95rem;
  letter-spacing: 0.02em; color: #5eead4;
}
.rs-cta-sub {
  margin: 0.35rem 0 0.7rem; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.8rem; line-height: 1.45; color: #cbd5e1;
}
.rs-cta-btn {
  min-height: 44px; padding: 0.5rem 1rem;
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; font-size: 0.78rem;
  color: #042f2e; background: linear-gradient(135deg, #5eead4, #2dd4bf);
  border: none; border-radius: 0.55rem; cursor: pointer;
}

/* ── The field ────────────────────────────────────────────────────────────── */
.rs-grid { display: flex; flex-direction: column; gap: 0.7rem; padding: 0.9rem 1rem 0; }

.rs-band {
  display: flex; flex-direction: column; gap: 0.2rem;
  margin-top: 0.6rem; padding: 0.6rem 0.7rem;
  background: rgba(148, 163, 184, 0.07);
  border: 1px dashed rgba(148, 163, 184, 0.3); border-radius: 0.6rem;
}
.rs-band-hd {
  font-family: 'Oswald', sans-serif; font-size: 0.8rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: #cbd5e1;
}
.rs-band-sub {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.75rem;
  line-height: 1.45; color: #94a3b8;
}
/* The pointer out of the band and onto the other ruler. Deliberately NOT styled
   like the two tab buttons above it: it is a link out of an admission, not a
   third control, and a reader must not read it as a ruler this band is ranked
   by. Full tap target because it is an action on a phone. */
.rs-band-go {
  align-self: flex-start; margin-top: 0.35rem; min-height: 44px;
  padding: 0.3rem 0; background: none; border: none; cursor: pointer;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.76rem;
  letter-spacing: 0.03em; color: #93c5fd; text-align: left;
}
.rs-band-go:hover { color: #bfdbfe; text-decoration: underline; }

.rs-pane {
  display: flex; flex-direction: column;
  background: rgba(15, 23, 42, 0.72);
  border: 1px solid rgba(96, 165, 250, 0.18);
  border-radius: 0.8rem; overflow: hidden;
}
.rs-pane.is-gap { border-style: dashed; border-color: rgba(148, 163, 184, 0.28); background: rgba(15, 23, 42, 0.5); }

/* STICKY CANDIDATE HEADER. On a phone the pane is tall and the reader scrolls
   through six issue rows; without this they lose track of whose row they are
   reading two swipes in. */
.rs-panehd {
  position: sticky; top: var(--rs-hd-h, 4.6rem); z-index: 4;
  display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  padding: 0.7rem 0.8rem;
  background: linear-gradient(180deg, rgba(17, 26, 44, 0.99), rgba(15, 23, 42, 0.96));
  border-bottom: 1px solid rgba(96, 165, 250, 0.16);
}
.rs-rank {
  flex: 0 0 auto; width: 1.9rem; height: 1.9rem;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Oswald', sans-serif; font-size: 0.9rem; font-weight: 700;
  color: #0b1220; background: linear-gradient(135deg, #bfdbfe, #60a5fa);
  border-radius: 0.5rem;
}
.rs-rank--gap { color: #64748b; background: rgba(148, 163, 184, 0.14); }
.rs-scorewrap { display: flex; flex-direction: column; gap: 0.1rem; min-width: 7.5rem; }
.rs-score { font-family: 'Oswald', sans-serif; font-size: 1.45rem; line-height: 1; }
.rs-pct { font-size: 0.85rem; }
.rs-scorelbl {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.62rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: #7596c0;
}
.rs-bar { display: block; height: 3px; border-radius: 2px; background: rgba(148, 163, 184, 0.2); overflow: hidden; }
.rs-bar i { display: block; height: 100%; border-radius: 2px; }
.rs-gapword {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem;
  font-weight: 700; color: #94a3b8; line-height: 1.2;
}
.rs-alt {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.68rem;
  color: #7596c0; letter-spacing: 0.03em;
}

.rs-who { display: flex; align-items: center; gap: 0.5rem; flex: 1 1 9rem; min-width: 0; }
.rs-face {
  width: 2.1rem; height: 2.1rem; flex: 0 0 auto; border-radius: 50%;
  overflow: hidden; border: 1px solid rgba(148, 163, 184, 0.4);
  display: flex; align-items: center; justify-content: center;
}
.rs-face img { width: 100%; height: 100%; object-fit: cover; }
.rs-face--empty { color: #9fb4d4; font-size: 0.9rem; }
.rs-whotext { display: flex; flex-direction: column; min-width: 0; }
.rs-name {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.92rem; font-weight: 700;
  letter-spacing: 0.02em; color: #fff; text-align: left;
  background: none; border: none; padding: 0.15rem 0; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rs-name:hover { color: #93c5fd; text-decoration: underline; }
/* The name is a real <a href="/p/<pid>"> (race-sheet.js personOpen), so it needs
   the link colour and underline off — it already reads as the card's heading and
   takes an underline on hover like it always did. display:block keeps the
   ellipsis truncation that the old <button> got for free. */
a.rs-name { display: block; text-decoration: none; }
a.rs-name:hover, a.rs-name:focus-visible { color: #93c5fd; text-decoration: underline; }
.rs-inc {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.62rem;
  letter-spacing: 0.06em; text-transform: uppercase; color: #fbbf24;
}

/* ── Direction Match chip ─────────────────────────────────────────────────── */
.rs-dm {
  display: flex; align-items: flex-start; gap: 0.35rem;
  flex: 1 1 11rem; min-width: 0;
  padding: 0.3rem 0.5rem; border-radius: 0.5rem;
  background: rgba(148, 163, 184, 0.08); border: 1px solid rgba(148, 163, 184, 0.22);
}
.rs-dm-k { font-size: 0.75rem; line-height: 1.3; }
.rs-dm-body { display: flex; flex-direction: column; min-width: 0; }
.rs-dm-label {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.6rem;
  letter-spacing: 0.07em; text-transform: uppercase; color: #94a3b8;
}
.rs-dm-hint { text-transform: none; letter-spacing: 0.02em; color: #64748b; }
.rs-dm-val {
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.76rem;
  color: #cbd5e1; line-height: 1.25;
}
.rs-dm-pct { color: #e2e8f0; }
.rs-dm-n { color: #64748b; font-size: 0.68rem; }

/* ── Team control ─────────────────────────────────────────────────────────── */
.rs-team {
  flex: 0 0 auto; min-height: 44px; padding: 0.4rem 0.8rem;
  font-family: 'Barlow Condensed', sans-serif; font-weight: 700;
  font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
  color: #fbbf24; background: linear-gradient(135deg, rgba(245, 158, 11, 0.2), rgba(245, 158, 11, 0.07));
  border: 1px solid rgba(245, 158, 11, 0.5); border-radius: 0.55rem; cursor: pointer;
  white-space: nowrap;
}
.rs-team.is-on {
  color: #4ade80; background: linear-gradient(135deg, rgba(74, 222, 128, 0.22), rgba(74, 222, 128, 0.08));
  border-color: rgba(74, 222, 128, 0.55);
}

/* ── Issue cells ──────────────────────────────────────────────────────────── */
.rs-cells { display: flex; flex-direction: column; }
.rs-issuecell {
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 0.5rem 0.8rem;
  border-top: 1px solid rgba(148, 163, 184, 0.1);
  border-left: 3px solid var(--pdx-ic, #64748b);
}
.rs-issuecell-lbl {
  display: flex; align-items: center; gap: 0.3rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.68rem;
  letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--pdx-ic-ink, #9fb4d4);
}
.rs-star { font-size: 0.7rem; }
.rs-cell { display: flex; flex-direction: column; gap: 0.15rem; }
.rs-cell-lead { font-family: 'Barlow Condensed', sans-serif; font-size: 0.8rem; color: #e2e8f0; }
.rs-cell-other { opacity: 0.52; font-size: 0.72rem; }
.rs-cell-none { color: #64748b; font-style: italic; font-size: 0.76rem; }
.rs-cell[data-rs-v="match"] .rs-cell-lead { color: #86efac; }
.rs-cell[data-rs-v="partial"] .rs-cell-lead { color: #fcd34d; }
.rs-cell[data-rs-v="mismatch"] .rs-cell-lead { color: #fca5a5; }
/* A cell whose ACTIVE lane is silent and whose other lane is not. The chip that
   spoke sits in the lead slot at full opacity — it is the only signal here, and
   dimming the only signal is what made these columns read as empty — while the
   left edge marks that it came from the other lane, and the silence rides
   underneath in the quiet slot. No verdict tint: data-rs-v is "none" here by
   construction, so none of the three colour rules above can reach it. */
.rs-cell[data-rs-alt] { box-shadow: inset 2px 0 0 rgba(148,163,184,0.34); padding-left: 0.4rem; }
.rs-cell[data-rs-alt] .rs-cell-lead { opacity: 0.92; }
.rs-cell[data-rs-alt] .rs-cell-other { opacity: 0.6; font-style: italic; }

.rs-morewrap { padding: 0.8rem 1rem 0; }
.rs-more {
  min-height: 44px; width: 100%; padding: 0.5rem 0.9rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem;
  letter-spacing: 0.06em; text-transform: uppercase; color: #93c5fd;
  background: rgba(96, 165, 250, 0.1); border: 1px solid rgba(96, 165, 250, 0.32);
  border-radius: 0.55rem; cursor: pointer;
}

.rs-empty {
  margin: 1rem; padding: 1rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.85rem;
  line-height: 1.5; color: #cbd5e1;
  background: rgba(148, 163, 184, 0.07);
  border: 1px dashed rgba(148, 163, 184, 0.3); border-radius: 0.7rem;
}
.rs-empty p { margin: 0 0 0.4rem; }
.rs-empty p:last-child { margin-bottom: 0; color: #94a3b8; font-size: 0.8rem; }
/* An empty field still owes the reader two things: what would fill it, and
   somewhere to go that is not the back button. */
.rs-empty-next {
  padding: 0.5rem 0.6rem; border-radius: 0.5rem; font-size: 0.78rem; color: #9fb4d4;
  background: rgba(15, 23, 42, 0.5); border: 1px solid rgba(148, 163, 184, 0.16);
}
.rs-empty-next b { color: #cbd5e1; }
.rs-empty-acts {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  margin: 0.7rem 0 0 !important;
}
.rs-empty-note { font-size: 0.74rem; color: #64748b; }

/* ── Desktop: true side by side ───────────────────────────────────────────── */
@media (min-width: 900px) {
  /* TRUE SIDE BY SIDE. Each track is one row of equal-width candidate columns;
     four or fewer fit the sheet, more scroll horizontally rather than shrinking
     into unreadable slivers. align-items:stretch keeps every pane the height of
     the tallest so the Nth issue row lines up across the field, which is the
     whole reason a voter opened a comparison. */
  .rs-grid {
    display: grid; align-items: stretch;
    grid-auto-flow: column; grid-auto-columns: minmax(17rem, 1fr);
    overflow-x: auto; overscroll-behavior-x: contain;
    padding-bottom: 0.6rem;
  }
  .rs-band { margin: 0.2rem 1rem 0; }
  .rs-pane { height: 100%; }
  /* The sticky pane header is a phone affordance. Side by side, the header is
     already the top of a short column and sticking it only fights the sheet's
     own sticky title bar. */
  .rs-panehd { position: static; }
  /* One issue row per candidate, all the same height, so the rows read across
     the field as rows. */
  .rs-issuecell { min-height: 4.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .rs-overlay { transition: none; }
}

/* ── The entry control ───────────────────────────────────────────────────────
   pdxRaceSheetEntry() returns one button and every host drops it in as-is, so
   the button owns its own look here rather than each host restyling it. It sits
   inside rows that are themselves clickable (a Who Represents Me seat row is
   role="button"), hence the onclick's stopPropagation and the visually distinct
   outlined treatment — it has to read as a second, separate action. */
.rs-entry {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  min-height: 44px; padding: 0.55rem 0.85rem;
  border: 1px solid rgba(96, 165, 250, 0.3);
  border-radius: 0.7rem;
  background: rgba(30, 58, 96, 0.28);
  color: #bfdbfe; cursor: pointer; text-align: left;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.82rem; font-weight: 600; letter-spacing: 0.04em;
  transition: background 0.16s ease, border-color 0.16s ease;
}
.rs-entry:hover, .rs-entry:focus-visible {
  background: rgba(37, 78, 130, 0.42);
  border-color: rgba(96, 165, 250, 0.55);
  color: #e0edff;
}
.rs-entry-ico { font-size: 0.95rem; line-height: 1; flex: 0 0 auto; }
.rs-entry-txt { flex: 1 1 auto; }
.rs-entry-go { flex: 0 0 auto; opacity: 0.75; font-size: 1.05rem; line-height: 1; }
/* Compact = inside a list of seats, where the button repeats once per row and
   should not out-shout the seat it belongs to. */
.rs-entry--compact {
  min-height: 44px; padding: 0.45rem 0.7rem;
  font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase;
  border-radius: 0.55rem;
}

/* Host hook: Who Represents Me. .wrm-rows is a flex column, so the entry is
   simply the next flex item after its seat row — never nested inside it, since
   that row is itself role="button". The negative top margin closes the column
   gap so the button reads as attached to the seat above it. */
.wrm-seatcompare { margin: -0.35rem 0 0.15rem; }

/* Host hook: My Voting Team seat card. Sits between the seat's explainer and its
   candidate grid, so the offer to compare arrives before the unranked list the
   voter would otherwise have to judge by name alone. */
.bb-seatcompare { margin: 0.15rem 0 0.6rem; }

/* Only rendered when the visitor actually has a High-priority issue, so it can
   afford to be emphatic — it is explaining why this order is not the same order
   another voter would see. */
.rs-rankstar { color: #fde68a; font-weight: 600; }

/* ── Seat strip ──────────────────────────────────────────────────────────────
   The three-part contract every seat row carries: where the team slot stands,
   the way into the field, the stance footnote. Column on purpose — on a phone
   these must never compete for one line, and the compare control has to keep
   its full 44px whatever sits above it. */
.rs-seat-strip {
  display: flex; flex-direction: column; align-items: stretch; gap: 0.3rem;
  margin: -0.35rem 0 0.15rem;
}
.rs-seat-team {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: #7f93b4;
}
.rs-seat-team-ic { font-size: 0.85rem; line-height: 1; }
/* Filled reads gold because it is the one fact on this row the voter put there
   themselves — it should be findable at a glance down a list of six seats. */
.rs-seat-team.is-on { color: #fde68a; }
.rs-seat-team.is-on b { color: #fff7dd; font-weight: 700; }
/* ── "Work this seat" ────────────────────────────────────────────────────────
   The loop's own control, so it reads as the primary action on the row while the
   compare button beside it reads as the reference lookup it is. Gold, because
   gold is this app's colour for a ballot decision — the same colour the filled
   team slot above it uses. 44px on every width. */
.rs-seat-work {
  display: inline-flex; align-self: flex-start; align-items: center; gap: 0.4rem;
  min-height: 44px; padding: 0 0.75rem; border-radius: 0.6rem; cursor: pointer;
  background: rgba(251, 191, 36, 0.12); border: 1px solid rgba(251, 191, 36, 0.36);
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; color: #fde68a;
  white-space: nowrap; text-align: left;
}
.rs-seat-work:hover, .rs-seat-work:focus-visible {
  background: rgba(251, 191, 36, 0.2); border-color: rgba(251, 191, 36, 0.6); color: #fff7dd;
}
.rs-seat-work-ic { font-size: 0.9rem; line-height: 1; }
.rs-seat-work-go { opacity: 0.7; }

/* Footnote weight, deliberately: it explains an absence, it is not the CTA. */
.rs-seat-stance {
  align-self: flex-start; min-height: 32px; padding: 0.25rem 0;
  background: none; border: 0; cursor: pointer;
  font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.74rem; font-weight: 600; letter-spacing: 0.04em;
  color: #8fb3e6; text-align: left;
}
.rs-seat-stance:hover, .rs-seat-stance:focus-visible { color: #cfe3ff; text-decoration: underline; }
@media (max-width: 640px) {
  .rs-seat-stance { min-height: 44px; }
}

/* ── Header actions: share, then close ───────────────────────────────────────
   A row of its own so the share control cannot squeeze the close target below
   44px on a narrow phone. Share sits left of close because close is the last
   thing on the row everywhere else in the app and moving it would cost more
   than it buys. */
.rs-hd-acts { flex: 0 0 auto; display: flex; align-items: center; gap: 0.4rem; }
.rs-share {
  display: inline-flex; align-items: center; gap: 0.35rem;
  min-height: 44px; padding: 0 0.7rem;
  background: rgba(96, 165, 250, 0.12); border: 1px solid rgba(96, 165, 250, 0.34);
  border-radius: 0.6rem; cursor: pointer;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; color: #cfe3ff; white-space: nowrap;
}
.rs-share:hover, .rs-share:focus-visible { background: rgba(96, 165, 250, 0.22); color: #fff; }
.rs-share-ico { font-size: 0.95rem; line-height: 1; }
/* Under ~420px the seat name needs the room more than the word does; the icon
   keeps a full 44px target and the aria-label still says what it is. */
@media (max-width: 420px) { .rs-share-txt { display: none; } .rs-share { padding: 0 0.55rem; min-width: 44px; justify-content: center; } }

/* ── Arrived from a shared link ──────────────────────────────────────────────
   Sits above the controls, not inside them: it is a statement about where this
   sheet came from, and the last clause — that none of the sender's positions
   travelled — is the one thing a recipient must not have to infer. */
.rs-shared {
  margin: 0; padding: 0.7rem 1rem;
  background: rgba(96, 165, 250, 0.08);
  border-bottom: 1px solid rgba(96, 165, 250, 0.16);
  font-family: 'Barlow', sans-serif; font-size: 0.82rem; line-height: 1.5; color: #bcd0ee;
}
.rs-shared b { color: #dbeafe; }


/* ═══════════════════════════════════════════════════════════════════════════
   OVERVIEW — the tab that needs nothing from the reader
   ═══════════════════════════════════════════════════════════════════════════ */

/* The reader-scoped gate note. Amber, because it is an ask, not a failure. */
.rs-gate {
  margin: 0.8rem 1rem 0; padding: 0.7rem 0.85rem;
  border-radius: 0.6rem;
  background: rgba(251, 191, 36, 0.08); border: 1px solid rgba(251, 191, 36, 0.28);
}
.rs-gate-hd {
  margin: 0; font-family: 'Barlow Condensed', sans-serif; font-size: 0.92rem;
  color: #fcd34d; letter-spacing: 0.01em;
}
.rs-gate-sub {
  margin: 0.25rem 0 0; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.78rem; color: #cbd5e1; line-height: 1.45;
}

/* Race context strip — on every tab. */
.rs-ctx {
  margin: 0.8rem 1rem 0; padding: 0.7rem 0.85rem;
  border-radius: 0.6rem;
  background: rgba(15, 23, 42, 0.62); border: 1px solid rgba(96, 165, 250, 0.18);
}
.rs-ctx-top {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.75rem;
  font-family: 'Barlow Condensed', sans-serif;
}
.rs-ctx-seat { font-size: 0.95rem; color: #e2e8f0; letter-spacing: 0.01em; }
.rs-ctx-count, .rs-ctx-inc { font-size: 0.74rem; color: #8ea4c6; }
.rs-ctx-i { color: #fbbf24; }
/* What kind of field this is, and what its records did — the seat-level story,
   above the people and above Direction Match. */
.rs-ctx-shape {
  margin: 0.45rem 0 0; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.78rem; color: #9fb4d4; line-height: 1.5;
}
.rs-ctx-shape b { color: #e2e8f0; }
.rs-ctx-div {
  margin: 0.5rem 0 0; padding: 0.45rem 0.6rem; border-radius: 0.5rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.86rem;
  color: #cbd5e1; line-height: 1.5;
  background: rgba(30, 41, 59, 0.6); border: 1px solid rgba(148, 163, 184, 0.2);
}
.rs-ctx-div b { color: #e2e8f0; }
.rs-ctx-div[data-rs-d="diverge"] {
  border-color: rgba(251, 191, 36, 0.34); background: rgba(251, 191, 36, 0.07);
}
.rs-ctx-div[data-rs-d="diverge"] b { color: #fbbf24; }
.rs-ctx-divn { display: block; font-size: 0.68rem; color: #7596c0; }
/* THE DEMOTION IS TYPOGRAPHIC. Direction Match keeps its slot, its classes and
   its figure; what it loses is the visual claim to being the point of the strip.
   The label above the chips says which reading they are. */
.rs-ctx-2nd {
  margin: 0.7rem 0 0; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.66rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: #64748b;
}
.rs-ctx-chips {
  display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.3rem;
}
.rs-ctx-chip {
  display: flex; flex-direction: column; gap: 0.1rem;
  padding: 0.3rem 0.55rem; border-radius: 0.5rem;
  background: rgba(30, 41, 59, 0.5); border: 1px solid rgba(148, 163, 184, 0.14);
  font-family: 'Barlow Condensed', sans-serif;
}
.rs-ctx-who { font-size: 0.76rem; color: #cbd5e1; }
.rs-ctx-dm { font-size: 0.7rem; color: #8ea4c6; }
.rs-ctx-pct { color: #7596c0; font-size: 0.78rem; }
.rs-ctx-n { font-size: 0.68rem; color: #64748b; }
.rs-ctx-caveat {
  margin: 0.55rem 0 0; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.7rem; color: #7596c0; line-height: 1.45;
}
.rs-ctx-caveat b { color: #bfdbfe; }

/* Shared topic snapshot. */
.rs-snap { margin: 0.9rem 1rem 0; }
.rs-snap-hd {
  margin: 0; font-family: 'Barlow Condensed', sans-serif; font-size: 0.95rem;
  color: #e2e8f0; letter-spacing: 0.02em;
}
.rs-snap-rule, .rs-snap-none {
  margin: 0.3rem 0 0.6rem; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.72rem; color: #7596c0; line-height: 1.5;
}
/* THE TALLY IS THE HEADLINE. It is the one line that says what the whole table
   found, so it gets the weight the depth badges used to hold. */
.rs-snap-tally {
  margin: 0.35rem 0 0.5rem; padding: 0.45rem 0.6rem; border-radius: 0.5rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.8rem;
  color: #cbd5e1; line-height: 1.55;
  background: rgba(30, 41, 59, 0.55); border: 1px solid rgba(148, 163, 184, 0.18);
}
.rs-snap-tally b { color: #e2e8f0; }
.rs-snap-t-d { color: #fbbf24 !important; }
.rs-snap-t-a { color: #93c5fd !important; }
.rs-snap-t-k { color: #8ea4c6; font-size: 0.74rem; }

/* THE ISSUE PALETTE, ACTUALLY CONNECTED. These rows always meant to carry the
   site's topic colour; they were reading `--issue-color`, which nothing in the
   repo sets. PDXIssueColors.styleFor() emits --pdx-ic / -soft / -wash / -ink, the
   same four the rest of the site consumes, so that is what these read now. The
   grey fallback keeps a row that somehow arrives unthemed looking deliberate. */
.rs-snap-row {
  display: flex; flex-direction: column; gap: 0.35rem;
  padding: 0.55rem 0.6rem; margin-bottom: 0.45rem;
  border-radius: 0.55rem;
  background:
    linear-gradient(90deg, var(--pdx-ic-wash, var(--pdx-ic-soft, transparent)), transparent 58%),
    rgba(15, 23, 42, 0.55);
  border: 1px solid rgba(148, 163, 184, 0.16);
  border-left: 3px solid var(--pdx-ic, rgba(148, 163, 184, 0.5));
}
/* A row where the records point different ways is the reason this table exists,
   so it is the only row that gets a lift. Divergence is a fact about the file,
   not a score, and nothing about this rule reorders anything. */
.rs-snap-row[data-rs-d="diverge"], .rs-snap-row[data-rs-d="diverge_thin"] {
  border-color: rgba(251, 191, 36, 0.34);
  border-left-width: 4px;
}
.rs-snap-issue {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem;
  font-family: 'Barlow Condensed', sans-serif;
}
.rs-snap-name { font-size: 0.9rem; color: var(--pdx-ic-ink, #e2e8f0); letter-spacing: 0.01em; }
/* The direction read leads the row. */
.rs-snap-dir {
  font-size: 0.76rem; padding: 0.08rem 0.5rem; border-radius: 999px;
  white-space: nowrap; color: #cbd5e1;
  border: 1px solid rgba(148, 163, 184, 0.34); background: rgba(15, 23, 42, 0.5);
}
.rs-snap-dir[data-rs-d="diverge"] {
  color: #0b1220; font-weight: 700;
  background: #fbbf24; border-color: #fbbf24;
}
.rs-snap-dir[data-rs-d="diverge_thin"] {
  color: #fbbf24; border-color: rgba(251, 191, 36, 0.5); background: rgba(251, 191, 36, 0.12);
}
.rs-snap-dir[data-rs-d="align"] { color: #93c5fd; border-color: rgba(96, 165, 250, 0.42); }
.rs-snap-dir[data-rs-d="align_thin"] { color: #9fb4d4; border-color: rgba(96, 165, 250, 0.26); }
.rs-snap-dir[data-rs-d="one"], .rs-snap-dir[data-rs-d="mixed"],
.rs-snap-dir[data-rs-d="none"] { color: #8ea4c6; border-color: rgba(148, 163, 184, 0.26); }
/* SUBORDINATE ON PURPOSE. Same words, same tooltip, same rule as before — the
   depth read is a footnote to the direction read, not a competitor to it. */
.rs-snap-glance {
  font-size: 0.64rem; padding: 0.02rem 0.36rem; border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.2); color: #64748b; white-space: nowrap;
  opacity: 0.85;
}
.rs-snap-glance[data-rs-g="similar"] { color: #7596c0; border-color: rgba(96, 165, 250, 0.24); }
.rs-snap-glance[data-rs-g="different"] { color: #8ea4c6; border-color: rgba(148, 163, 184, 0.26); }
.rs-snap-glance[data-rs-g="thin"] { color: #a1832a; border-color: rgba(251, 191, 36, 0.24); }
/* The named sides, in field order. */
.rs-snap-sides {
  margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem 0.45rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.76rem; line-height: 1.4;
}
.rs-snap-sideof { color: #9fb4d4; }
.rs-snap-sideof b { color: #e2e8f0; font-weight: 600; }
.rs-snap-sideof[data-rs-t="support"] { color: #86efac; }
.rs-snap-sideof[data-rs-t="oppose"] { color: #fca5a5; }
.rs-snap-vs { color: #475569; }
.rs-snap-cells { display: grid; grid-template-columns: 1fr; gap: 0.35rem; }
.rs-snap-cell {
  display: flex; flex-direction: column; gap: 0.08rem; text-align: left;
  min-height: 44px; padding: 0.4rem 0.55rem; border-radius: 0.45rem;
  background: rgba(30, 41, 59, 0.6); border: 1px solid rgba(148, 163, 184, 0.16);
  font-family: 'Barlow Condensed', sans-serif; color: #cbd5e1; cursor: pointer;
  position: relative;
}
/* The go arrow is absolutely positioned, so the cell has to reserve its column
   or a long candidate name runs underneath it. Only the cells that HAVE an arrow
   pay for it. */
.rs-snap-cell:not(.is-empty) { padding-right: 1.75rem; }
.rs-snap-cell.is-empty { cursor: default; opacity: 0.72; }
.rs-snap-cell:not(.is-empty):hover { border-color: rgba(96, 165, 250, 0.45); }
/* A tone on the cell edge, so the two files can be told apart without reading.
   `muted` and `none` deliberately get nothing — a record with no readable
   direction must not look like a quiet version of one that has a side. */
.rs-snap-cell[data-rs-t="support"] { border-left: 3px solid rgba(134, 239, 172, 0.6); }
.rs-snap-cell[data-rs-t="oppose"] { border-left: 3px solid rgba(252, 165, 165, 0.6); }
.rs-snap-cell[data-rs-t="mixed"] { border-left: 3px solid rgba(148, 163, 184, 0.55); }
/* Thin is a dashed edge, never a faded one: the read is real, the file under it
   is shallow, and the engine has not called it a pattern. */
.rs-snap-cell[data-rs-thin="1"] { border-left-style: dashed; }
.rs-snap-who { font-size: 0.72rem; color: #8ea4c6; }
.rs-snap-side { font-size: 0.86rem; color: #e2e8f0; letter-spacing: 0.01em; }
.rs-snap-side[data-rs-t="support"] { color: #86efac; }
.rs-snap-side[data-rs-t="oppose"] { color: #fca5a5; }
.rs-snap-side[data-rs-t="mixed"] { color: #cbd5e1; }
.rs-snap-lbl { font-size: 0.8rem; color: #e2e8f0; }
.rs-snap-lbl.is-sub { font-size: 0.7rem; color: #9fb4d4; }
.rs-snap-dep { font-size: 0.68rem; color: #64748b; }
.rs-snap-1 {
  align-self: flex-start; margin-top: 0.12rem;
  font-size: 0.66rem; color: #fbbf24;
  border: 1px solid rgba(251, 191, 36, 0.34); background: rgba(251, 191, 36, 0.1);
  border-radius: 999px; padding: 0.02rem 0.4rem; white-space: nowrap;
}
.rs-snap-go { position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%); color: #60a5fa; }

/* Head-to-head blurb. */
.rs-h2h {
  margin: 0.9rem 1rem 0; padding: 0.7rem 0.85rem; border-radius: 0.6rem;
  background: rgba(96, 165, 250, 0.06); border: 1px solid rgba(96, 165, 250, 0.2);
}
.rs-h2h-hd {
  margin: 0 0 0.35rem; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.92rem; color: #e2e8f0; letter-spacing: 0.02em;
}
.rs-h2h-l {
  margin: 0.25rem 0 0; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.76rem; color: #cbd5e1; line-height: 1.5;
}
.rs-h2h-l b { color: #bfdbfe; }
.rs-h2h-l.is-secondary { color: #8ea4c6; font-size: 0.72rem; }
.rs-h2h-l.is-secondary b { color: #9fb4d4; }
.rs-h2h-2nd {
  display: inline-block; margin-right: 0.25rem; padding: 0.02rem 0.36rem;
  border-radius: 999px; border: 1px solid rgba(148, 163, 184, 0.24);
  font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase; color: #64748b;
}
.rs-h2h-n { white-space: nowrap; color: #e2e8f0; }
.rs-h2h-cta {
  margin: 0.55rem 0 0; font-family: 'Barlow Condensed', sans-serif;
  font-size: 0.74rem; color: #7596c0;
}
.rs-h2h-btn {
  min-height: 44px; margin-left: 0.3rem; padding: 0.4rem 0.8rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem;
  color: #0b1220; font-weight: 700; cursor: pointer;
  background: linear-gradient(135deg, #93c5fd, #60a5fa);
  border: 1px solid #60a5fa; border-radius: 0.5rem;
}

/* Overview candidate cards. */
.rs-ovgrid {
  display: grid; grid-template-columns: 1fr; gap: 0.6rem;
  padding: 0.9rem 1rem 0;
}
.rs-ovcard {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: 0.7rem 0.8rem; border-radius: 0.65rem;
  background: rgba(15, 23, 42, 0.62); border: 1px solid rgba(148, 163, 184, 0.2);
}
.rs-ovhd { display: flex; align-items: center; gap: 0.6rem; }
.rs-ovseat { display: block; font-size: 0.7rem; color: #8ea4c6; }
.rs-ovdm {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.5rem;
  padding: 0.35rem 0.5rem; border-radius: 0.5rem;
  background: rgba(30, 41, 59, 0.45); border: 1px solid rgba(148, 163, 184, 0.12);
  font-family: 'Barlow Condensed', sans-serif;
}
/* Direction Match keeps the card slot and the figure; it stops holding the
   card's largest number. The label says which reading it is before the number
   gets a chance to be mistaken for a score against the reader. */
.rs-ovdm-2nd {
  flex: 0 0 100%; font-size: 0.62rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: #64748b;
}
.rs-ovdm-p { font-size: 0.86rem; color: #7596c0; }
.rs-ovdm-s { font-size: 0.72rem; color: #8ea4c6; }
.rs-ovdm-n { font-size: 0.66rem; color: #64748b; }
.rs-ovpeek { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.rs-peek[data-rs-t="support"] .rs-peek-o { color: #86efac; }
.rs-peek[data-rs-t="oppose"] .rs-peek-o { color: #fca5a5; }
.rs-peek {
  display: flex; flex-direction: column; gap: 0.05rem; text-align: left;
  min-height: 44px; padding: 0.32rem 0.55rem; border-radius: 0.45rem;
  background:
    linear-gradient(90deg, var(--pdx-ic-wash, var(--pdx-ic-soft, transparent)), transparent 62%),
    rgba(30, 41, 59, 0.6);
  border: 1px solid rgba(148, 163, 184, 0.18);
  border-left: 3px solid var(--pdx-ic, rgba(148, 163, 184, 0.5));
  font-family: 'Barlow Condensed', sans-serif; cursor: pointer;
}
.rs-peek:hover { border-color: rgba(96, 165, 250, 0.45); }
.rs-peek-i { font-size: 0.74rem; color: var(--pdx-ic-ink, #e2e8f0); }
.rs-peek-o { font-size: 0.66rem; color: #8ea4c6; }
.rs-peek-none { font-family: 'Barlow Condensed', sans-serif; font-size: 0.72rem; color: #64748b; }
.rs-ovacts { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.rs-ovprof {
  min-height: 44px; padding: 0.4rem 0.8rem; border-radius: 0.5rem;
  font-family: 'Barlow Condensed', sans-serif; font-size: 0.78rem;
  color: #bfdbfe; background: rgba(96, 165, 250, 0.1);
  border: 1px solid rgba(96, 165, 250, 0.3); cursor: pointer;
}
/* Both of these are links now, not buttons (race-sheet.js personOpen). An
   anchor is inline, so it ignores min-height and centres nothing: inline-flex
   restores the 44px target and the vertical centring the <button> had, and
   text-decoration:none keeps a pill from also being underlined. */
a.rs-ovprof, a.rs-onlyone-b {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; text-decoration: none;
}

@media (min-width: 700px) {
  .rs-snap-cells { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
  .rs-ovgrid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE PHONE — ≤640px
   ────────────────────────────────────────────────────────────────────────────
   Everything above already stacks: the field is a flex column below 900px, the
   snapshot cells and the Overview cards are single-column below 700px, and no
   rule on this sheet turns on a horizontal scroller until 900px. So this block
   is not a second layout. It is the four places where a design that is correct
   at 1240px stops being usable at 360.

   Last in the file on purpose. These are all equal-specificity overrides of
   rules declared above, and "last one wins" is the only thing making them win.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* ── The tab row: three tabs, one width ───────────────────────────────────
     inline-flex + wrap does not clip the third tab, but it does something
     almost as bad: "Overview" is short, "Your Record Match" is not, so the
     row breaks into a 2 + 1 stack of unequal buttons and the third one reads
     as an afterthought rather than a peer. These three are peers — one shows
     the race, two rank it — so on a phone they are three equal columns of a
     grid, each free to wrap its own label onto a second line. Equal width,
     equal height, nothing clipped, nothing sideways. */
  .rs-modes {
    display: grid; grid-template-columns: repeat(3, 1fr);
    width: 100%; gap: 0.25rem;
  }
  .rs-vtab, .rs-mode {
    display: flex; align-items: center; justify-content: center;
    gap: 0.25rem; flex-wrap: wrap;
    padding: 0.4rem 0.3rem;
    white-space: normal; text-align: center; line-height: 1.15;
    font-size: 0.78rem; letter-spacing: 0.02em;
  }
  /* A GATED RULER HAS TO READ AS GATED AT ARM'S LENGTH. Dimmed italic is a
     desktop cue: at 0.78rem on a phone held at reading distance, 62% opacity
     is just "slightly grey text" and the reader learns nothing until they tap.
     The dashed amber edge is the same vocabulary the gate note below it uses,
     so the tab and the sentence explaining it are visibly the same subject. */
  .rs-mode.is-gated {
    opacity: 0.78;
    border-style: dashed; border-color: rgba(251, 191, 36, 0.42);
  }

  /* ── Touch targets that were sized for a cursor ───────────────────────────
     Both of these are real doors — the name opens a full profile, the compare
     entry opens this sheet — and both were under the 44px this file's own
     header promises. */
  .rs-name { min-height: 44px; }
  .rs-seat-stance { min-height: 44px; }

  /* ── Density, not deletion ────────────────────────────────────────────────
     The blocks between the header and the first candidate are context. They
     keep every fact they have on a desktop; they just stop spending a full
     1rem gutter each to say it, so the tab row and the first card both land
     within reach of the top of the screen. */
  .rs-controls { padding: 0.7rem 0.8rem 0.2rem; }
  .rs-ctx, .rs-gate, .rs-snap, .rs-h2h { margin-left: 0.8rem; margin-right: 0.8rem; }
  .rs-grid, .rs-ovgrid { padding-left: 0.8rem; padding-right: 0.8rem; }
  .rs-cta { margin-left: 0.8rem; margin-right: 0.8rem; }
  .rs-foot { margin-left: 0.8rem; margin-right: 0.8rem; }

  /* The last card must not end under the home indicator. .rs-sheet already
     reserves the inset; this adds the breathing room the desktop gets from the
     overlay's own 1.5rem of padding, which a full-bleed phone sheet has none
     of. */
  .rs-sheet { padding-bottom: calc(2.6rem + env(safe-area-inset-bottom, 0px)); }
}
