/* Midterms app. Layout variables (--bg, --line, ...) come from includes/sheet.php. */
.app {
  --d: #2563eb;
  --r: #dc2626;
  --i: #7c3aed;
  --cardw: min(560px, calc(100vw - 24px));
  max-width: 560px;   /* same as the swipe card, so the controls bar and scroll list line up with it */
  margin: 0 auto;
}
.panel {
  background: var(--bg);
  border: 2px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 8px 24px rgba(15, 23, 42, .06);
  padding: 12px;
}

.lrow:focus-visible, .chev:focus-visible {
  outline: 2px solid var(--d);
  outline-offset: 1px;
}

.races { margin-top: 10px; }   /* same as the gap between scroll-view rows */
.page { padding-top: 10px; }
.empty {
  margin: 0;
  padding: 18px;
  text-align: center;
  color: var(--muted);
  font-size: 15px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 12px;
}

/* ---------- shared bits ---------- */
.avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--pc, #64748b);
  color: #fff;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: .02em;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; object-position: center 22%; display: block; }
.p-D { --pc: var(--d); }
.p-R { --pc: var(--r); }
.p-I, .p-L, .p-G, .p-O { --pc: var(--i); }
.inc {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--chrome-2);
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  vertical-align: 2px;
}
/* Rating label tinted by which party it leans toward (the label itself is the source's own words) */
.chip {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  background: var(--chrome-2);
  color: #334155;
}
.chip.lean-D { background: #dbe7fe; color: #1d4ed8; }
.chip.lean-D.strong { background: var(--d); color: #fff; }
.chip.lean-R { background: #fde2e2; color: #b91c1c; }
.chip.lean-R.strong { background: var(--r); color: #fff; }

/* ---------- swipe card ---------- */
.swipe { position: relative; }
.swipe > .rcard { position: relative; z-index: 1; }
/* Neighbouring cards parked behind the front card; shown the moment a swipe starts (see showPeek) */
.swipe > .peek { position: absolute; top: 0; left: 0; right: 0; z-index: 0; display: none; pointer-events: none; }
.swipe > .peek.show { display: block; }
.swipe > .peek > .rcard { overflow: hidden; }
.rcard {
  width: var(--cardw);
  max-width: 100%;
  margin: 0 auto;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  box-shadow: 0 2px 4px rgba(15, 23, 42, .05), 0 12px 32px rgba(15, 23, 42, .10);
  --pad: 20px;
  padding: 20px var(--pad) 16px;
  touch-action: pan-y;          /* we handle horizontal drags; vertical still scrolls */
  user-select: none;
  -webkit-user-select: none;
  will-change: transform;
}
.rcard.enter-next { animation: enter-next .28s cubic-bezier(.2, .8, .3, 1); }
.rcard.enter-prev { animation: enter-prev .28s cubic-bezier(.2, .8, .3, 1); }
@keyframes enter-next { from { transform: translateX(48px); opacity: 0; } }
@keyframes enter-prev { from { transform: translateX(-48px); opacity: 0; } }

.rc-top { display: flex; align-items: center; gap: 8px; }
.donate {
  margin-left: auto;
  padding: 8px 13px;
  border-radius: 999px;
  background: var(--d);
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  white-space: nowrap;
  text-decoration: none;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .12), 0 3px 10px rgba(37, 99, 235, .25);
  transition: background .15s, transform .1s;
}
.donate span { font-weight: 600; opacity: .85; }
.donate:hover { background: #1d4ed8; }
.donate:active { transform: scale(.98); }
.donate:focus-visible { outline: 3px solid #93c5fd; outline-offset: 2px; }
.rc-code { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; color: #000; line-height: 1; }
.hero { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 18px 0 4px; }
.rcard .hero .avatar { width: 168px; height: 168px; font-size: 52px; }
.hero-name { margin-top: 14px; font-size: 24px; font-weight: 800; letter-spacing: -0.015em; color: #000; line-height: 1.15; }
.hero .inc { margin-left: 8px; vertical-align: 5px; }
.hero-bio { margin-top: 4px; font-size: 15px; color: #334155; line-height: 1.35; }
.hero-links {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 5px;
  font-size: 15.5px;
  font-weight: 600;
}
.hero-links span { color: var(--line-strong); }
.hero-links a { color: var(--d); text-decoration: none; padding: 4px 0; }   /* taller tap target */
.hero-links a:hover { text-decoration: underline; }
.hero-links { align-items: center; }
.hero-links a.ico { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; }   /* 32px tap target */
.hero-links a.ico svg { width: 20px; height: 20px; }

/* Card sections (Running against, Forecast, ...) */
.sec {
  margin: 18px calc(-1 * var(--pad)) 0;
  padding: 16px var(--pad) 0;
  border-top: 2px solid var(--line-strong);
}
.sec-h {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: #000;
}
.sec-h::before { content: ""; width: 4px; height: 16px; border-radius: 2px; background: #000; }
.opps { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px 28px; }
.opp { display: flex; align-items: center; gap: 12px; text-align: left; }
.rcard .opp .avatar { width: 60px; height: 60px; font-size: 20px; }
.opp-name { font-size: 18px; font-weight: 700; color: #000; line-height: 1.2; }
.opp .inc { margin: 0 0 4px; }
.opp .hero-links { justify-content: flex-start; margin-top: 4px; }
.opp .hero-links a { color: var(--pc, var(--r)); }   /* opponent's links in their party colour (red for R) */
.opp .hero-links a:first-child.ico { margin-left: -6px; }
.drace { margin: 0 0 10px; font-size: 14px; color: #000; }   /* wraps between items on narrow phones */
.drace span { white-space: nowrap; }
.ddesc { margin: 2px 0 10px; font-size: 14px; font-weight: 400; color: #000; }
.dtable { display: grid; }
.drow { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 7px 0; border-top: 1px solid var(--line); }
.drow:first-child { border-top: 0; }
.dlabel { flex: none; font-size: 14px; font-weight: 400; color: #000; }
.dval { text-align: right; font-size: 14px; color: #1e293b; font-variant-numeric: tabular-nums; }
.dsub { display: block; margin-top: 2px; font-size: 12px; color: var(--muted); }
.dpair { padding: 0 0 10px; font-size: 14px; line-height: 1.5; }
.dsep { margin-right: 10px; }
.dstat { display: inline; white-space: nowrap; }   /* each label + number stays together */
.dnum { font-size: 14px; font-weight: 600; color: #334155; font-variant-numeric: tabular-nums; }   /* plain number, no pill */
.dnum.lean-D { color: var(--d); }
.dnum.lean-R { color: var(--r); }
.dsrc { font-size: 11.5px; font-weight: 400; color: var(--muted); }
.dstat .dlabel, .dstat .dchip { display: inline; }
.dchip { margin-left: 5px; }
.dstat .dsub { margin-top: 0; line-height: 1.2; white-space: nowrap; font-size: 11.5px; }
.dstat .dlabel { font-size: 14px; }
.dpair + .drow { border-top: 1px solid var(--line); }
.dtable > .dpair:last-child { padding-bottom: 0; }   /* no extra gap before the redrawn note */
.dnote { margin: 8px 0 0; font-size: 12px; color: var(--muted); }
/* Fundraising */
.fmetric { margin-bottom: 12px; }
.flabel { margin-bottom: 4px; font-size: 14px; color: #000; }
.fsub { font-size: 12px; color: var(--muted); }
.fbar { display: flex; align-items: center; gap: 8px; margin: 3px 0; font-size: 13px; }
.fname { flex: none; width: 92px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #334155; }
.ftrack { flex: 1; height: 10px; border-radius: 5px; background: var(--chrome-2); overflow: hidden; }
.ffill { display: block; height: 100%; border-radius: 5px; background: var(--pc); }
.fnone { flex: 1; font-size: 13px; color: var(--muted); }
.famt { flex: none; width: 56px; text-align: right; font-variant-numeric: tabular-nums; color: #000; }
.rtable { display: grid; }
.rrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.rrow:first-child { border-top: 0; }
.rname { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: #000; }
.rlink { font-weight: 400; color: var(--d); text-decoration: none; }
.rlink:hover { text-decoration: underline; }
.rdate { display: block; font-size: 12px; font-weight: 400; color: var(--muted); margin-top: 1px; }
.rprob { flex: none; width: 58px; text-align: right; font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rc-pos {
  margin-top: 16px;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Chevrons (same pattern as Telephone Archive / Walkable City Rules): 44px discs hugging the
   card's edges, clamped to the viewport, fixed at mid-screen below the header. */
.chev {
  position: fixed;
  top: 55%;
  z-index: 15;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 56px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  color: #475569;
  cursor: pointer;
  transform: translateY(-50%);
  transition: color .16s, background .16s;
}
.chev svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.chev.left { left: max(4px, calc(50% - var(--cardw) / 2 - 34px)); }
.chev.right { left: min(calc(100vw - 32px), calc(50% + var(--cardw) / 2 + 6px)); }
.chev:hover { color: #000; background: rgba(15, 23, 42, .05); }
.chev:active { transform: translateY(-50%) scale(.94); }
.chev[hidden] { display: none; }
/* Phones swipe instead. Tablets keep the chevrons, so people who don't know to swipe can still move on (Dave, 2026-10-03). */
html.phone .chev { display: none; }

/* ---------- list view ---------- */
.list { display: grid; gap: 10px; }
.lrow {
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 4px 12px rgba(15, 23, 42, .05);
  padding: 12px 14px;
  cursor: pointer;
}
/* Tappable-card cues: a chevron on every row, a lift on hover, a press on tap */
.lrow {
  position: relative;
  padding-right: 40px;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.l-go {
  position: absolute;
  right: 12px;
  top: 50%;
  width: 20px;
  height: 20px;
  margin-top: -10px;
  fill: none;
  stroke: #000;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .15s ease;
}
@media (hover: hover) {
  .lrow:hover {
    border-color: #b8c2cf;
    transform: translateY(-2px);
    box-shadow: 0 2px 4px rgba(15, 23, 42, .06), 0 10px 24px rgba(15, 23, 42, .12);
  }
  .lrow:hover .l-go { transform: translateX(3px); }
}
.lrow:active { transform: scale(.985); }
.l-dem { display: flex; align-items: center; gap: 12px; min-width: 0; }
.l-dem .avatar { width: 64px; height: 64px; font-size: 21px; }
.l-dem .cd { margin-right: .45em; }
/* Ring around the photo: blue for every Democrat (incumbents were black until 2026-10-03) */
.l-dem .avatar { margin: 3px; box-shadow: 0 0 0 1px #fff, 0 0 0 3.5px var(--ring); }
.ring-dem { --ring: var(--d); }
.ring-inc { --ring: var(--d); }   /* incumbents blue too (Dave, 2026-10-03) */
.l-dem-text { min-width: 0; }
.l-dem .nm { font-size: 18px; font-weight: 700; color: #000; line-height: 1.2; }   /* wraps rather than cutting off the district */

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* phones only (html.phone, decided at load), so a narrowed desktop window keeps desktop sizes */
html.phone .page { padding: 10px 12px 32px; }
html.phone .swipe { margin: 0 -2px; }   /* race cards only: 10px at the sides, matching the 10px above (Dave, 2026-10-04) */
html.phone .panel { padding: 10px; }
html.phone .rcard { --pad: 16px; padding: 18px var(--pad) 14px; }
html.phone .rc-code { font-size: 26px; }


/* ---------- text pages (About, Credits) ---------- */
/* Single pages (About, Credits, Feedback, and any new one): use <article class="panel prose">. The margin gives
   them breathing room below the header; the races page (/midterms) has no .prose panel, so its spacing is unchanged. */
.panel.prose { margin-top: 12px; }
.prose { font-size: 16px; line-height: 1.55; color: #1e293b; }
.prose h1 { margin: 0 0 10px; font-size: 22px; font-weight: 800; letter-spacing: -0.015em; color: #000; }
.prose h2 { margin: 26px 0 8px; font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.prose p { margin: 0 0 10px; }
.prose ul { margin: 0; padding-left: 20px; }
.prose li { margin: 6px 0; }
.prose a { color: var(--d); text-decoration: underline; text-underline-offset: 2px; }
.prose .muted { color: var(--muted); }
html.phone .prose h1 { font-size: 20px; }

/* ---------- feedback form ---------- */
.fform { display: grid; gap: 14px; margin-top: 20px; }
.fform label { display: grid; gap: 6px; font-size: 14px; color: #000; }
.fform input, .fform textarea {
  font: inherit; font-size: 16px;   /* 16px keeps iPhones from zooming in on focus */
  padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: 8px; background: #fff; color: #000;
  width: 100%; box-sizing: border-box;
}
.fform textarea { resize: vertical; min-height: 120px; }
.fform input:focus, .fform textarea:focus { outline: 2px solid var(--d); outline-offset: 1px; }
.fform .hp { position: absolute; left: -9999px; }
.fform button {
  justify-self: start; font: inherit; font-size: 15px; padding: 10px 22px; border: 0; border-radius: 8px;
  background: var(--d); color: #fff; cursor: pointer;
}
.ferr { color: #b91c1c; }

/* ---------- volunteer opportunities ---------- */
.vgroup + .vgroup { margin-top: 14px; }
.vlabel { font-size: 14px; color: var(--muted); margin-bottom: 12px; }
/* host links above a card's Volunteering list (All | the campaign | the others): chosen = bold + underlined, as the raters */
.vgroup .vev[hidden] { display: none; }
.vhosts { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 12px; font-size: 14px; }
.vhosts button { padding: 2px 0; border: 0; background: none; font: inherit; color: #475569; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.vhosts button[aria-pressed="true"] { color: #0f172a; font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
@media (hover: hover) { .vhosts button:hover { color: #0f172a; } }
.vev { display: block; padding: 8px 0; border-top: 1px solid var(--line); color: inherit; }
.vev:first-of-type { border-top: 0; padding-top: 0; }
.vwhen { display: block; font-size: 14px; color: #000; }
.vmore { color: var(--muted); }
.vtitle { display: block; font-size: 14px; color: #0f172a; text-decoration: none; }   /* black, as on the Volunteer page; blue + underline on hover */
.vmeta { display: block; font-size: 13px; color: var(--muted); }
.vmeta a { color: var(--d); text-decoration: none; }   /* the host's Mobilize page */
@media (hover: hover) { .vtitle:hover { color: #1d4ed8; text-decoration: underline; } .vmeta a:hover { text-decoration: underline; } }

/* ---------- phone welcome card (in front of the first race on /midterms) ---------- */
.rcard.intro {   /* fills most of the phone screen now the Swipe/Scroll bar is gone: room below the faces */
  min-height: min(680px, calc(100svh - 120px));
  display: flex; flex-direction: column; justify-content: flex-start; align-items: center;   /* sits a little above centre */
  text-align: center; padding: 72px 22px 40px;
}
.intro-h { text-wrap: balance; margin: 0 0 16px; font-size: 26px; line-height: 1.25; font-weight: 700; color: #000; letter-spacing: -0.01em; }
.intro-sub { text-wrap: balance; margin: 0 0 26px; font-size: 20px; line-height: 1.45; color: #334155; }
/* swipe hint: a fingertip dot sliding left along a track, toward a left arrow (swiping left moves on) */
.swipe-hint { position: relative; width: 150px; height: 40px; }
.sh-track { position: absolute; left: 30px; right: 10px; top: 19px; height: 2px; border-radius: 1px;
  background: linear-gradient(270deg, rgba(37, 99, 235, 0), rgba(37, 99, 235, .45)); }
.sh-dot { position: absolute; right: 0; top: 8px; width: 24px; height: 24px; border-radius: 50%;
  background: rgba(37, 99, 235, .18); border: 2px solid var(--d); animation: sh-slide 1.8s ease-in-out infinite; }
.sh-arrow { position: absolute; left: 0; top: 8px; width: 24px; height: 24px; fill: none; stroke: var(--d);
  stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
@keyframes sh-slide {
  0% { transform: translateX(0); opacity: 0; }
  15% { opacity: 1; }
  70% { transform: translateX(-96px); opacity: 1; }
  100% { transform: translateX(-96px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .sh-dot { animation: none; transform: translateX(-48px); } }
/* the first few candidates, overlapping, so it's clear the swipe leads to people */
.intro-faces { margin-top: 30px; }
.face-row { display: flex; justify-content: center; gap: 12px; }
.face-row + .face-row { margin-top: 12px; }
.intro-faces .avatar { width: 86px; height: 86px; font-size: 26px; margin: 3px; box-shadow: 0 0 0 1px #fff, 0 0 0 3.5px var(--d); }   /* same thin ring as the Scroll list photos */

/* ---------- wider screens (tablet/desktop): grid home, dropdown in the header ---------- */
body.wide .app { max-width: 1100px; }
body.wide .app .panel { display: none; }            /* no Swipe/Scroll; the dropdown moved to the header */
body.wide .races { margin-top: 18px; }
.cardgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px; }   /* not .grid: that is the sheet background */
.gcard {
  font: inherit; text-align: center; cursor: pointer; color: inherit;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: var(--bg); border: 1px solid var(--line-strong); border-radius: 14px;
  padding: 20px 16px 22px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 18px rgba(15, 23, 42, .06);
  transition: transform .15s, box-shadow .15s;
}
@media (hover: hover) { .gcard:hover { transform: translateY(-2px); box-shadow: 0 2px 4px rgba(15, 23, 42, .06), 0 12px 28px rgba(15, 23, 42, .12); } }
.gcard:focus-visible { outline: 2px solid var(--d); outline-offset: 2px; }
.g-top { align-self: stretch; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.g-code { font-size: 20px; font-weight: 800; color: #000; letter-spacing: .01em; }
.gcard .avatar { width: 144px; height: 144px; font-size: 42px; margin: 4px 0 4px; box-shadow: 0 0 0 1px #fff, 0 0 0 3.5px var(--ring); }
.g-name { font-size: 16px; font-weight: 600; color: #000; line-height: 1.3; }
.g-dist { white-space: nowrap; }   /* keep "(AZ-06)" together */
/* Rating bar: a slim line in three coloured segments (Toss Up grey, Lean R light pink, Likely R darker
   pink, as in the Forecast chips), the same width as the forecast slider; labels sit under each segment,
   and the chosen segment is raised with a dark ring, like the slider's band. */
.rline { display: flex; width: 390px; max-width: 100%; margin: 8px auto 0; }   /* bar lines up with the forecast track opposite */
.rline button {
  flex: 1; font: inherit; font-size: 13px; font-weight: 600; color: #334155; background: none; border: 0;
  padding: 0; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.rline button::before { content: ""; align-self: stretch; height: 10px; border: 2px solid transparent; border-radius: 0; transition: transform .15s; }
.rline button:first-child::before { border-radius: 6px 0 0 6px; }
.rline button:last-child::before { border-radius: 0 6px 6px 0; }
.rs-toss::before { background: var(--chrome-2); }
.rs-lean::before { background: #fde2e2; }
.rs-likely::before { background: #f8b4b4; }
.rs-lean, .rs-likely { color: #b91c1c; }
.rs-leand::before { background: #dbe6fd; }
.rs-leand { color: #1d4ed8; }
.rline button[aria-pressed="true"]::before { border-color: #0f172a; border-radius: 6px; box-shadow: 0 1px 4px rgba(15, 23, 42, .25); }   /* ring only, no growth: stays no thicker than the forecast track */
@media (hover: hover) { .rline button:not([aria-pressed="true"]):hover::before { border-color: rgba(15, 23, 42, .25); } }

/* forecaster choice: neutral pills, the selected one ringed with a check (same idea as the rating pills) */
.osel { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 14px 0 4px; }   /* pills under the bars */
.osel button {
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; border-radius: 999px;
  padding: 6px 14px; border: 2px solid transparent; background: #eef2f7; color: #1e293b;
  transition: border-color .15s, box-shadow .15s;
}
.osel button[aria-pressed="true"] { border-color: #0f172a; box-shadow: 0 2px 6px rgba(15, 23, 42, .18); }
.osel button[aria-pressed="true"]::before { content: "✓ "; }
@media (hover: hover) { .osel button:not([aria-pressed="true"]):hover { border-color: rgba(15, 23, 42, .25); } }
.oslider { position: relative; width: 390px; max-width: 100%; margin: 0 auto 4px; }
/* The track (390px) stands for 25-85%; the handle is a band exactly 10 points wide (1/6 = 65px), so its
   centre runs 30-80 and it covers the window being shown (e.g. 45-55). Ticks sit at their true values. */
.oslider input { -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 34px; margin: 0; background: transparent; cursor: pointer; }
.oslider input::-webkit-slider-runnable-track { height: 12px; border-radius: 6px; background: #e2e8f0; }
.oslider input::-webkit-slider-thumb {
  -webkit-appearance: none; width: 65px; height: 30px; margin-top: -9px; border-radius: 15px;
  background: rgba(37, 99, 235, .85); border: 2px solid #fff; box-shadow: 0 1px 4px rgba(15, 23, 42, .3); cursor: grab;
}
.oslider input::-moz-range-track { height: 12px; border-radius: 6px; background: #e2e8f0; }
.oslider input::-moz-range-thumb {
  width: 61px; height: 26px; border-radius: 15px; background: rgba(37, 99, 235, .85);
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(15, 23, 42, .3); cursor: grab;
}
.oslider input:focus-visible { outline: 2px solid var(--d); outline-offset: 4px; border-radius: 6px; }
.oband-label {   /* white "D win" on the blue band; follows it as it moves (set in syncRatingBar) */
  position: absolute; top: 17px; transform: translate(-50%, -50%); pointer-events: none;
  font-size: 14px; font-weight: 700; color: #fff; white-space: nowrap; letter-spacing: .01em;
}
.oticks { position: relative; height: 16px; font-size: 12px; color: var(--muted); }
.oticks span { position: absolute; top: 0; transform: translateX(-50%); }


/* ---------- header browse control + drawer (wide screens) ---------- */
.titlebar { flex-wrap: wrap; }   /* the Sort-by drawer is its full-width second row (phones and desktop) */
.tcol { display: flex; flex-direction: column; }
html.desk .titles { align-items: center; }   /* the tagline centres on the two-line title block (every midterms page) */
/* "Sort by ratings or forecasts" under the title; each word opens its selector in the drawer below */
.sortline { margin: 2px 0 0; font-size: 17px; color: #475569; }
html.phone .sortline { font-size: 17.6px; }   /* phones: 10% bigger for readability (Dave, 2026-10-03) */
.sortline a { color: var(--d); text-decoration: underline; text-underline-offset: 2px; }
.sortline a.on { color: #000; font-weight: 600; text-decoration: none; }
/* Phones browse with the same Sort-by drawer (Dave, 2026-09-30): no Swipe/Scroll/filter bar. The selectors
   shrink to fit (the forecast band stays exactly 10 points: 330px track / 6 = 55px). */
html.phone .races { margin-top: 0; }
html.phone .rline, html.phone .oslider { width: 330px; }
html.phone .oslider input::-webkit-slider-thumb { width: 55px; }
html.phone .oslider input::-moz-range-thumb { width: 51px; }
html.phone .oband-label { font-size: 13px; }
html.phone .hdrawer .mode-panel { height: auto; min-height: 110px; }
html.phone .hdrawer { margin-top: 8px; padding-top: 10px; }
/* the drawer: a full-width second row of the header with the chosen selector */
.hdrawer { flex: 0 0 100%; order: 99; margin-top: 10px; padding: 12px 0 4px; border-top: 1px solid var(--line); text-align: center; }
.hdrawer .mode-panel { max-width: 520px; margin: 0 auto; }
/* all three selectors take exactly the same height (content centred), so switching doesn't make the header jump */
.hdrawer .mode-panel { height: 140px; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; }
.hdrawer .mode-panel[hidden] { display: none; }
.hdrawer .mode-panel .rline { margin-top: 0; }
.hdrawer .mode-panel[data-mode="list"] .osel { margin: 0; }
.hdrawer .mode-panel[data-mode="list"], .hdrawer .mode-panel[data-mode="money"] { max-width: 1000px; }   /* pills run across, wrapping only when they must */
.hdrawer .mode-panel[data-mode="list"] .osel { row-gap: 10px; }   /* one row of pills that wraps naturally */

/* ---------- single pages: wider on desktop; the Donate page wider still ---------- */
html.desk .app-page { max-width: 760px; }
html.desk .app-wide { max-width: 860px; }
/* Donate page: every Democrat with their Donate (ActBlue) button; 1 column on phones, 2-3 on desktop */
.donate-list, .prose .donate-list { list-style: none; margin: 14px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(380px, 100%), 1fr)); gap: 0 32px; }
.prose .donate-list li { margin: 0; }
.dn-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.dn-who { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 0 1 210px; color: inherit; text-decoration: none; }   /* fixed width: buttons sit close to the names and line up in a column */
/* desktop and iPad: a plain width, not flex-basis, since Safari sizes max-content grid columns from width */
html.desk .dn-who { flex: none; width: 210px; }
.prose .dn-who { text-decoration: none; color: inherit; }
.dn-photo { width: 48px; height: 48px; margin: 3px; box-shadow: 0 0 0 1px #fff, 0 0 0 3px var(--d); }
.dn-photo.dn-inc { box-shadow: 0 0 0 1px #fff, 0 0 0 3px #000; }
.dn-text { min-width: 0; line-height: 1.3; }
.dn-name { font-weight: 600; color: #000; }
.dn-dist { color: var(--muted); white-space: nowrap; }
@media (hover: hover) { .dn-who:hover .dn-name { text-decoration: underline; } }
.dn-row .donate, .prose .dn-row .donate { margin-left: 4px; flex: none; font-size: 13px; padding: 7px 12px; color: #fff; text-decoration: none; }   /* beat .prose a's link colour */
/* Desktop single pages: roomier padding inside the white panel */
html.desk .panel.prose { padding: 26px 36px 30px; }
/* Donate page on desktop: two columns sized to their content and centred, so the space either side is equal */
html.desk .prose .donate-list { grid-template-columns: repeat(2, max-content); justify-content: center; column-gap: 60px; }
@media (max-width: 860px) { html.desk .prose .donate-list { grid-template-columns: max-content; justify-content: start; } }   /* one column lines up under the heading */

.gcard { position: relative; }
/* the phone card padding (html.phone .rcard) would otherwise override the welcome card's own */
html.phone .rcard.intro { padding: 44px 22px 40px; }

/* ---------- previous / next previews beside the race card (wide screens with room) ---------- */
.nbthumb {
  position: fixed; top: 55%; transform: translateY(-50%); z-index: 14; width: 116px;
  display: none; flex-direction: column; align-items: center; gap: 8px; padding: 12px 10px 14px;
  font: inherit; text-align: center; color: inherit; cursor: pointer;
  background: var(--bg); border: 1px solid var(--line-strong); border-radius: 14px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 18px rgba(15, 23, 42, .08);
  transition: transform .15s, box-shadow .15s;
}
/* horizontal position set by placeSideNav() in app.js, 18px from the card */
/* where the previews fit they are the navigation (arrow in the label), so the round arrows step aside */
/* the photo previews are retired (Dave, 2026-10-02): plain arrows at every desktop width */
@media (hover: hover) {
  .nbthumb.prev:hover { transform: translateY(-50%) translateX(-3px); box-shadow: 0 2px 4px rgba(15, 23, 42, .06), 0 12px 28px rgba(15, 23, 42, .12); }
  .nbthumb.next:hover { transform: translateY(-50%) translateX(3px); box-shadow: 0 2px 4px rgba(15, 23, 42, .06), 0 12px 28px rgba(15, 23, 42, .12); }
}
.nb-label { display: inline-flex; align-items: center; gap: 2px; margin-bottom: 6px; font-size: 13px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: #000; }
.nb-label svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.nbthumb .avatar { width: 80px; height: 80px; font-size: 24px; margin: 0 0 2px; box-shadow: 0 0 0 1px #fff, 0 0 0 3px var(--d); }
.nb-name { font-size: 14px; font-weight: 600; color: #000; line-height: 1.25; }
.nb-dist { font-size: 14px; font-weight: 600; color: #000; }

/* ---------- welcome banner in the header on the wide-screen landing grid (until a sort is opened) ---------- */

.hdrawer .mode-panel[data-mode="list"] { height: auto; min-height: 140px; }

/* ---------- In the news (race card) ---------- */
.nw-list { list-style: none; margin: 0; padding: 0; }
.nw-list li { padding: 8px 0; border-top: 1px solid var(--line); }
.nw-list li:first-child { border-top: 0; padding-top: 0; }
.nw-title { display: block; font-size: 14px; color: var(--d); text-decoration: none; line-height: 1.35; }
@media (hover: hover) { .nw-title:hover { text-decoration: underline; } }
.nw-meta { display: block; font-size: 13px; color: var(--muted); margin-top: 2px; }

/* ---------- Videos (race card): tabs for each candidate, a scrolling row of thumbnails, pop-up player ---------- */
.vs-tabs { display: flex; gap: 18px; margin-bottom: 10px; flex-wrap: wrap; border-bottom: 1px solid #e2e8f0; }
.vs-tab { font: inherit; font-size: 14px; padding: 4px 0 6px; margin-bottom: -1px; background: none; border: 0; border-bottom: 3px solid transparent; color: var(--muted); cursor: pointer; }
.vs-tab span { color: var(--muted); }
.vs-tab[aria-selected="true"] { color: #000; }
.vs-tab.p-D[aria-selected="true"] { border-bottom-color: var(--d); }
.vs-tab.p-R[aria-selected="true"] { border-bottom-color: var(--r); }
.vs-tab[aria-selected="true"]:not(.p-D):not(.p-R) { border-bottom-color: #0f172a; }
.vids-row { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 6px; }
.vids-row[hidden] { display: none; }
.vids-item { flex: 0 0 170px; scroll-snap-align: start; font: inherit; text-align: left; background: none; border: 0; padding: 0; cursor: pointer; color: inherit; }
.vids-thumb { position: relative; display: block; aspect-ratio: 16 / 9; border-radius: 8px; overflow: hidden; background: #0f172a; }
.vids-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vids-dur { position: absolute; right: 5px; bottom: 5px; font-size: 11px; font-weight: 600; color: #fff; background: rgba(0, 0, 0, .75); padding: 1px 5px; border-radius: 4px; }
.vids-kind { display: block; margin-top: 5px; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.vids-title { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 13px; line-height: 1.3; color: #000; }
@media (hover: hover) { .vids-item:hover .vids-title { text-decoration: underline; } }
.vmodal { position: fixed; inset: 0; z-index: 100; background: rgba(15, 23, 42, .78); display: flex; align-items: center; justify-content: center; padding: 16px; }
.vmodal[hidden] { display: none; }
.vm-box { position: relative; width: min(960px, 100%); }
.vm-frame { position: relative; aspect-ratio: 16 / 9; background: #000; border-radius: 10px; overflow: hidden; }
.vm-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vm-title { margin-top: 10px; font-size: 16px; font-weight: 600; color: #fff; }
.vm-meta { font-size: 13px; color: #cbd5e1; }
.vm-close { position: absolute; top: -44px; right: 0; width: 38px; height: 38px; border-radius: 50%; border: 0; background: #fff; color: #000; font-size: 24px; line-height: 1; cursor: pointer; }

/* desktop: the photo rises into the empty middle of the top row (code/star left, Donate right); the row stays clickable */
html.desk .rc-top { position: relative; z-index: 1; }
/* (the photo no longer rises into the top row: the labels beside Donate are too wide; Dave, 2026-10-03) */

/* ---------- pinned bar on a race card: district + the Democrat's name, shown once the photo scrolls away ---------- */
.pinbar { position: fixed; z-index: 16; display: flex; align-items: center; gap: 14px; padding: 15px 20px; background: #fff;
  border: 1.5px solid #94a3b8; border-radius: 12px; box-shadow: 0 4px 14px rgba(15, 23, 42, .14);
  opacity: 0; transform: translateY(-8px); pointer-events: none; transition: opacity .15s, transform .15s; }
.pinbar.on { opacity: 1; transform: none; pointer-events: auto; }   /* the star in it is clickable */
/* blank out the strip between the header and the bar, so the card doesn't scroll by in that gap */
.pinbar::before { content: ""; position: absolute; z-index: -1; left: -2px; right: -2px; top: -10px; bottom: calc(100% + 1.5px); background: var(--bg, #fff); }
.pb-code { white-space: nowrap; font-size: 25px; font-weight: 800; letter-spacing: -0.02em; color: #000; margin-right: 4px; }
.pb-name { font-size: 22px; line-height: 1.2; color: #000; min-width: 0; }
.pinbar.tight .pb-name { font-size: 18px; }
html.phone .pinbar { gap: 12px; padding: 13px 16px; }
html.phone .pb-code { font-size: 23px; margin-right: 0; }
html.phone .pb-name { font-size: 21px; }
html.phone .pinbar.tight .pb-name { font-size: 18px; }

/* ---------- More: the last pill in the list bar opens a small menu of extra lists ---------- */
.pl-wrap { position: relative; display: inline-flex; }
.osel .pl-btn::after { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 2px 3px 8px; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.osel .pl-btn[aria-expanded="true"]::after { transform: rotate(-135deg); margin-bottom: -1px; }
.pl-menu { position: absolute; z-index: 40; top: calc(100% + 6px); left: 50%; transform: translateX(-50%); min-width: 200px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px; background: #fff; border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 8px 24px rgba(15, 23, 42, .16); text-align: left; }
.pl-menu[hidden], .pl-menu button[hidden] { display: none; }
.osel .pl-menu button { border: 0; border-radius: 8px; background: none; box-shadow: none; text-align: left; padding: 9px 12px; font-weight: 400; white-space: nowrap; }
.osel .pl-menu button[aria-pressed="true"] { background: #eef2f7; box-shadow: none; font-weight: 600; }
@media (hover: hover) { .osel .pl-menu button:hover { background: #f1f5f9; } }

/* a line of context at the top of each selector in the header drawer */
.mp-note { margin: 0 0 12px; font-size: 14px; color: var(--muted); text-align: center; }
/* desktop: each selector's line of context starts at the same height, and the panel is only as tall as it needs */
html.desk .hdrawer .mode-panel, html.desk .hdrawer .mode-panel[data-mode="list"] { height: auto; min-height: 0; justify-content: flex-start; padding: 3px 0; }
/* desktop ratings: a little more breathing room between the line of context, the bar and the pills */
html.desk .hdrawer .mode-panel[data-mode="rating"] .mp-note { margin-bottom: 18px; }
html.desk .hdrawer .mode-panel[data-mode="rating"] .osel { margin-top: 20px; }
/* desktop lists: the same breathing room above and below the pills */
html.desk .hdrawer .mode-panel[data-mode="list"] .mp-note { margin-bottom: 18px; }
html.desk .hdrawer .mode-panel[data-mode="list"] { padding-bottom: 12px; }
.oticks span.on { color: #1d4ed8; font-weight: 800; }   /* percentages under the slider's band (explicit blue: --d is not defined up in the header) */
.rline { touch-action: pan-y; user-select: none; -webkit-user-select: none; }   /* a sideways drag along the ratings bar picks sections instead of scrolling */

/* ---------- Donate page: list filter pills (same look as the race browser's lists) ---------- */
.prose .dn-filter { margin: 4px 0 18px; justify-content: flex-start; flex-wrap: nowrap; }   /* one line, flush left; overflow goes in More */
.dn-filter .dn-pill, .dn-filter .pl-btn { flex: none; white-space: nowrap; }
.dn-filter .pl-wrap[hidden], .dn-filter .dn-pill[hidden] { display: none; }
.dn-filter .pl-menu { left: auto; right: 0; transform: none; }   /* More sits at the end of the line: open leftwards so it stays on screen */
.prose .donate-list li[hidden] { display: none; }
.prose .dn-empty { color: var(--muted); text-align: center; margin: 24px 0; }

/* ---------- Getting back from a race page (browser Back): a glow on the race you came from ---------- */
.backflash { animation: backflash 1.6s ease-out; }
@keyframes backflash { 0%, 35% { box-shadow: 0 0 0 4px #93c5fd; } 100% { box-shadow: 0 0 0 4px rgba(147, 197, 253, 0); } }

/* ---------- Outside spending (race card): same bars as Fundraising, top groups under each bar ---------- */
.osp-none { margin: 0; font-size: 14px; color: var(--muted); }

/* ---------- Map (Sort by … map): US -> state districts -> race page; and the race card's district map ---------- */
.map-view { max-width: 820px; margin: -10px auto 18px; padding: 16px 18px 12px; background: #fff; border: 1px solid var(--line); border-radius: 16px; }
.map-crumb { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; font-size: 15px; }
.map-crumb b { font-weight: 700; color: #000; }
.map-crumb button { font: inherit; font-weight: 600; color: #2563eb; background: none; border: 0; padding: 0; cursor: pointer; }
@media (hover: hover) { .map-crumb button:hover { text-decoration: underline; } }
.map-back { margin: 0 0 6px; }
.map-box { aspect-ratio: 975 / 610; }
.map-box.map-state { aspect-ratio: auto; min-height: 200px; }
.map-box svg { display: block; width: 100%; height: auto; max-height: 64vh; margin: 0 auto; }
.usmap .ms { fill: #eef2f7; stroke: #fff; stroke-width: .8; }
.usmap .ms.has { fill: #9969a0;   /* the midpoint of the site's Democratic blue and Republican red, 20% lighter */ cursor: pointer; transition: fill .12s; }
@media (hover: hover) { .usmap .ms.has:hover { fill: #804488; } }
.stmap .md { fill: #f1f5f9; stroke: #fff; stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.stmap .md-hit { cursor: pointer; transition: filter .12s; }
@media (hover: hover) { .stmap .md-hit:hover { filter: brightness(.85); } }
.stmap .md.mb-toss, .mb-toss { fill: #a8b3c4; background: #a8b3c4; }
.stmap .md.mb-leanr, .mb-leanr { fill: #f4a5a5; background: #f4a5a5; }
.stmap .md.mb-stretch, .mb-stretch { fill: #e06b6b; background: #e06b6b; }
.stmap .md.mb-none, .mb-none { fill: #f1f5f9; background: #f1f5f9; }
.stmap .md-labels text { font-family: Inter, system-ui, sans-serif; font-weight: 700; fill: #0f172a; text-anchor: middle; dominant-baseline: central;
  pointer-events: none; paint-order: stroke; stroke: rgba(255, 255, 255, .85); }
.map-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; margin: 10px 0 0; font-size: 13px; color: #334155; }
.map-legend i { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; border: 1px solid rgba(15, 23, 42, .12); }
html.phone .map-view { padding: 12px 10px 10px; border-radius: 14px; margin-bottom: 12px; }
.dmini { margin: 2px auto 10px; max-width: 260px; }
.dmini svg { display: block; width: 100%; height: auto; max-height: 190px; }
.dmini .dm { fill: #eef2f7; stroke: #fff; stroke-width: 1; vector-effect: non-scaling-stroke; }
.dmini .dm-on { fill: #475569; stroke: #fff; stroke-width: 1; vector-effect: non-scaling-stroke; }
/* desktop: state maps no taller than ~45% of the window, so the race cards below show without scrolling (tall states shrink; wide ones are already short) */
html.desk .map-box.map-state svg { max-height: 45vh; }
/* state map <-> race cards: hovering one highlights the other */
.stmap .md-hit.is-linked { filter: brightness(.78); }
.gcard.is-linked { transform: translateY(-2px); box-shadow: 0 0 0 2px #0f172a, 0 12px 28px rgba(15, 23, 42, .12); }
.lrow.is-linked { box-shadow: 0 0 0 2px #0f172a; }
.prose h2.ab-h { margin: 38px 0 10px; font-size: 22px; font-weight: 800; letter-spacing: -0.015em; color: #000; text-transform: none; }   /* About page: "Feedback", same as the "About" heading */
html.phone .prose h2.ab-h { font-size: 20px; }
html.desk .prose .fform { max-width: 540px; }   /* About page form: fields don't run to the panel's edge on desktop */
body.plain .map-view { border-color: var(--line-strong); }   /* white page: the map panel needs the darker border too */
/* White pages: the line under the title row is the same everywhere (1.5px, edge to edge). When the welcome banner
   or the Sort-by drawer sits in the header, that line goes above it and the header's own bottom is a thin hairline. */
body.plain .hdrawer { border-top: 1.5px solid #aeb8c5; margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; }
html.phone body.plain .hdrawer { margin-left: -8px; padding-left: 8px; }
body.plain .titlebar:has(> .hdrawer:not([hidden])) { border-bottom: 1px solid var(--line-strong); }
/* the welcome banner sits at the top of the page (not in the header) and scrolls away; no lines */
/* race page card: a slightly heavier border on the white page */
body.plain .rcard, body.plain .gcard, body.plain .lrow { border-width: 1.5px; }   /* race page card, grid tiles, phone list rows */
html.phone body.plain .rcard, html.phone body.plain .gcard, html.phone body.plain .lrow { border-width: 2px; }   /* phone screens are denser: 2px reads like 1.5px on desktop */

/* ---------- Forecast section: two columns (analysts' ratings | models' forecasts), on phones too ---------- */
.fc-grid { display: grid; grid-template-columns: 1fr 1fr; column-gap: 20px; align-items: start; padding-top: 6px; }
.fc-h { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); margin: 0 0 2px; }
.fc-item { padding: 7px 0; border-top: 1px solid var(--line); }
.fc-col > .fc-item:first-child { border-top: 0; padding-top: 0; }
.fc-src { color: inherit; text-decoration: none; }   /* the source name links to it, looking like plain text */
.fc-name { font-size: 14px; font-weight: 600; color: #000; line-height: 1.25; }
.fc-val { display: flex; align-items: center; flex-wrap: wrap; gap: 3px 8px; margin-top: 4px; font-size: 12px; color: var(--muted); }
.fc-prob { font-size: 13px; color: #334155; font-variant-numeric: tabular-nums; }
html.phone .fc-grid { column-gap: 12px; }
html.phone .fc-name { font-size: 13px; }

/* ---------- Outside spending by side: one bar per candidate's side, the groups behind it listed below ---------- */
.osp-side + .osp-side { margin-top: 14px; }
.fname.osp-lab { width: auto; flex: none; min-width: 92px; font-weight: 600; color: #000; }
.osp-list { list-style: none; margin: 6px 0 0; padding: 0; font-size: 13px; }
.osp-list li { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; border-top: 1px solid var(--line); }
.osp-list li:first-child { border-top: 0; }
.osp-g { min-width: 0; color: #334155; }
.osp-when { color: var(--muted); font-size: 12px; white-space: nowrap; }
.osp-a { flex: none; font-variant-numeric: tabular-nums; color: #000; }
.osp-list .osp-more { display: block; color: var(--muted); font-size: 12px; }

/* ---------- Wider desktop windows (900px+): the race card goes double-wide in two columns ----------
   Left: candidate, Opponent, District, Ratings and forecasts. Right (from the top, beside the photo): Fundraising,
   Outside spending, Videos, News, Volunteering. Same order as the single column, which phones and narrower
   windows keep. The card is liquid: up to 1080px, and always 80px narrower than the window (room for the plain
   arrows, never a sideways scrollbar). At 900px that leaves two columns of ~370px; at 1180px+ they're ~500px. */
@media (min-width: 900px) {
  html.desk .app:has(> .races > .swipe) { --cardw: min(1080px, calc(100vw - 80px)); max-width: var(--cardw); }
  html.desk .rc-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 36px; align-items: start; }
  html.desk .rc-cols .sec { margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }   /* dividers span their own column */
  html.desk .rc-right > .sec:first-child { margin-top: 0; padding-top: 0; border-top: 0; }           /* the right column starts at the top */
  html.desk .rc-cols ~ .rc-top, html.desk .rcard:has(> .rc-cols) > .rc-top { width: calc(50% - 18px); }   /* top row spans the left column, so Donate sits above-right of the photo */
  html.desk .news-narrow { display: none; }   /* News moves to the left column */
  html.desk .news-wide { display: block; }
}
.news-wide { display: none; }   /* News: shown in the left column only on the two-column layout (900px+ desktop) */

/* Oath as the main donate button, ActBlue as a small link under it */
.don-stack { margin-left: auto; display: inline-flex; flex-direction: column; align-items: center; gap: 4px; }
.don-stack .donate { margin-left: 0; }
.rc-top .donate { font-size: 15.4px; padding: 9px 14px; }   /* race cards: 10% bigger (Dave, 2026-10-03) */
.dn-row .don-stack { margin-left: 4px; flex: none; }
/* Top row: Donate first, then the district or race name beside it (Dave, 2026-10-03) */
.rc-top { align-items: center; gap: 16px; }
.rc-top .don-stack, .rc-top > .donate { order: -1; margin-left: 0; }

/* ---------- Money dashboard (Sort by … money) ---------- */
/* every row: [number] [district + both photos] [detail: date / name / amounts in their own columns] */
.mn-view { max-width: 860px; margin: 0 auto; }
.mn-deck { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin: 0 0 12px; padding: 10px 14px; background: #fff; border: 1.5px solid var(--line-strong); border-radius: 14px; }
.mn-deck .mn-note { flex: 1; min-width: 220px; margin: 0; font-size: 13px; color: var(--muted); }
.mn-list { display: grid; gap: 8px; }
.mn-r { color: #b91c1c; }
.mn-d { color: #1d4ed8; }
.mn-empty { margin: 8px 0; padding: 18px; text-align: center; color: var(--muted); background: #fff; border: 1.5px dashed var(--line-strong); border-radius: 12px; }
.mrow, .mpac-head { display: flex; align-items: center; gap: 12px; width: 100%; padding: 10px 14px; font: inherit; text-align: left; color: inherit;
  background: #fff; border: 1.5px solid var(--line-strong); border-radius: 12px; cursor: pointer; }
@media (hover: hover) { .mrow:hover, .mpac-head:hover { border-color: #94a3b8; box-shadow: 0 4px 14px rgba(15, 23, 42, .08); } }
.mb-amt { flex: none; min-width: 72px; font-size: 19px; font-weight: 800; font-variant-numeric: tabular-nums; }
.mb-race { flex: none; display: flex; align-items: center; gap: 10px; min-width: 150px; font-size: 17px; }
.mb-race b { min-width: 58px; font-weight: 800; color: #000; }
.mb-pair { display: flex; }
.mb-pair .avatar { width: 40px; height: 40px; margin: 0; box-shadow: 0 0 0 2px #fff; }
.mb-pair .avatar + .avatar { margin-left: -8px; }
.mb-pair .avatar.p-D { box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px var(--d); }
.mb-pair .avatar.p-R { box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px var(--r); }
.mr-main { flex: 1; min-width: 0; margin-left: 12px; }
.mb-what { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 24px; font-size: 17px; font-weight: 400; color: #000; line-height: 1.3; }
.mb-date { flex: none; min-width: 3.6em; white-space: nowrap; font-weight: 700; color: #475569; }
.mb-name { flex: 1; min-width: 0; }
.mpac-head .mr-main { margin-left: 0; }
.mpac-count { flex: none; display: flex; align-items: center; gap: 8px; font-size: 15px; color: #475569; white-space: nowrap; }
.mpac-count i { font-style: normal; font-size: 22px; line-height: 1; transition: transform .15s; }
.mpac-head[aria-expanded="true"] .mpac-count i { transform: rotate(90deg); }
.mpac-races { display: grid; gap: 6px; padding: 6px 0 4px 28px; }
.mpac-races[hidden] { display: none; }
.mpac-races .mrow { padding: 6px 12px; }
.mpac-races .mb-amt { font-size: 16px; }
.mpac-races .mb-what { font-size: 15px; }
html.phone .mrow, html.phone .mpac-head { padding: 9px 10px; gap: 10px; }
html.phone .mb-amt { min-width: 58px; font-size: 16px; }
html.phone .mb-race { flex-direction: column; gap: 3px; min-width: 0; font-size: 14px; }
html.phone .mb-race b { min-width: 0; }
html.phone .mb-pair .avatar { width: 32px; height: 32px; }
html.phone .mr-main { margin-left: 4px; }
html.phone .mpac-head .mr-main { margin-left: 0; }
html.phone .mb-what { font-size: 15.5px; gap: 2px 14px; }
html.phone .mn-v-latest .mb-what { flex-wrap: nowrap; }
html.phone .mpac-count { font-size: 13px; }
html.phone .mpac-races { padding-left: 12px; }
html.phone .mpac-races .mb-race { flex-direction: row; }
html.phone .mpac-races .mb-pair .avatar { width: 28px; height: 28px; }
/* two-figure details (outspent, biggest, heating, underdogs): first figure in a fixed column so the second lines up */
.mb-what > span:first-child:not(.mb-date):not(.mb-name) { min-width: 12.5em; }
html.phone .mb-what > span:first-child:not(.mb-date):not(.mb-name) { min-width: 0; }
html.phone .mpac-races .mb-race { gap: 8px; min-width: 104px; }
.mpac-races .mb-date { font-weight: 400; }
/* more room between the amount and the district */
.mb-amt { margin-right: 10px; }
html.phone .mb-amt { margin-right: 6px; }
/* outspent: names are short now, so a tighter first column keeps the gaps even */
.mn-v-outspent .mb-what > span:first-child:not(.mb-date):not(.mb-name) { min-width: 142px; }   /* longest entry + the 24px column gap */
.mn-v-biggest .mb-what > span:first-child:not(.mb-date):not(.mb-name) { min-width: 108px; }   /* longest "$NNM raised" + the 24px gap */
.mn-v-heating .mb-what > span:first-child:not(.mb-date):not(.mb-name) { min-width: 150px; }   /* longest "$NNNK Republican" + the 24px gap */
/* latest: smaller PAC names, and the room goes to even gaps between columns */
.mn-v-latest .mb-name { font-size: 15px; }
html.phone .mn-v-latest .mb-name { font-size: 13.5px; }
html.phone .mn-v-latest .mr-main { margin-left: 8px; }
html.phone .mn-v-latest .mb-what { gap: 2px 16px; }
/* more room on both sides of the district + photos column (not on Top PAC spenders) */
.mn-view:not(.mn-v-pacs) .mb-race { margin: 0 10px; }
html.phone .mn-view:not(.mn-v-pacs) .mb-race { margin: 0 5px; }
.mn-v-latest .mb-what { align-items: center; }   /* date centred against a wrapped PAC name */
/* every view's rows the same height as the race rows (district + photos), so switching views doesn't jump */
.mrow, .mpac-head { min-height: 63px; box-sizing: border-box; }
html.phone .mrow, html.phone .mpac-head { min-height: 73px; }
.mpac-races .mrow { min-height: 0; }
/* explainer text in the deck: bigger, darker */
.mn-deck .mn-note { font-size: 16.5px; color: #334155; line-height: 1.4; }
html.phone .mn-deck .mn-note { font-size: 16px; }
html.phone .mp-note-money { display: none; }   /* phones: no "Follow the money." (saves space) */
/* money: note-to-pills gap matches the Lists and Ratings selectors (18px) */
.hdrawer .mode-panel[data-mode="money"] .osel { margin-top: 0; }
.hdrawer .mode-panel[data-mode="money"] .mp-note { margin-bottom: 18px; }

/* Senate races: the state on the US map (State section) */
.dmini-us { max-width: 300px; }
/* Other <state> races, at the bottom of the District / State section: each race as its Democrat's photo and the district */
.xb-line { margin: 14px 0 0; }
.xb-lab { font-size: 14px; color: #475569; margin-bottom: 14px; }
.xb-items { display: flex; flex-wrap: wrap; gap: 12px 18px; }
.xb-link { display: inline-flex; flex-direction: column; align-items: center; gap: 5px; color: #2563eb; text-decoration: none; font-size: 13px; }   /* photo, district underneath */
.xb-link b { font-weight: 700; }
.xb-link .avatar { width: 60px; height: 60px; margin: 0; font-size: 20px;   /* same size as the opponent's photo */
  box-shadow: 0 0 0 1.5px #fff, 0 0 0 3px var(--d); }
@media (hover: hover) { .xb-link:hover b { text-decoration: underline; } }
/* Lists and Ratings have no note line any more: give their selectors room below the header line */
.hdrawer .mode-panel[data-mode="list"], .hdrawer .mode-panel[data-mode="rating"], .hdrawer .mode-panel[data-mode="money"] { padding-top: 14px; }
html.desk .hdrawer .mode-panel[data-mode="list"], html.desk .hdrawer .mode-panel[data-mode="rating"], html.desk .hdrawer .mode-panel[data-mode="money"] { padding-top: 14px; }
/* phones: even space above and below the selectors (the drawer already has 10px on top), and room above the map */
html.phone .map-view { margin-top: 12px; }
/* phones: the selectors no longer need fixed-height panels (the notes are gone), so each takes its natural height:
   14px above (as before) and 10px below */
html.phone .hdrawer .mode-panel, html.phone .hdrawer .mode-panel[data-mode="list"] { height: auto; min-height: 0; justify-content: flex-start; padding: 2px 0 6px; }
html.phone .hdrawer .mode-panel .osel { margin-bottom: 0; }
/* phones: the drawer spans the full screen width (it ran 21px short on the right, so its contents sat left of centre)
   with equal padding each side, so the selectors are centred on the screen */
html.phone body.plain .hdrawer { flex-basis: calc(100% + 24px); box-sizing: border-box; padding-left: 12px; padding-right: 12px; }
/* the ratings bar is thin, so it gets a little more room above it than the pills do */
html.phone .hdrawer .mode-panel[data-mode="rating"] { padding-top: 8px; }
html.phone .hdrawer .mode-panel[data-mode="list"], html.phone .hdrawer .mode-panel[data-mode="money"] { padding-top: 6px; }   /* 18px above the pills */
.dmini .dm-ring { fill: none; stroke: #0f172a; stroke-width: 2.5; vector-effect: non-scaling-stroke; }   /* marks a district too small to spot */
html.desk .rcard.rc-statewide .hero { margin-top: 0; }   /* statewide labels ("MI Governor") are wider than a district code, so the photo isn't raised beside them */
.prose h2.ab-h#feedback { margin-top: 44px; padding-top: 30px; border-top: 1px solid var(--line-strong); }   /* About: a hairline and more room between Credits and Feedback */
.avatar:has(img) { background: #eef2f7; }   /* light grey while a photo loads (not the party colour, which flashed blue); initials keep the colour */
/* Easy Donate (midterms/donate/): one Oath button per group of key races, the races' Democrats underneath */
.prose .ed-intro { margin: 4px 0 8px; font-size: 16px; color: #334155; }
.ed-group { padding: 22px 0 6px; border-top: 1px solid var(--line); margin-top: 18px; }
.ed-head { display: flex; align-items: center; justify-content: flex-start; gap: 10px 16px; flex-wrap: wrap; margin-bottom: 16px; }   /* the Oath button first, then the group's title */
.prose .ed-title { margin: 0; font-size: 20px; font-weight: 800; letter-spacing: -0.01em; color: #000; text-transform: none; }
.prose .ed-btn { color: #fff; text-decoration: none; font-size: 15px; padding: 9px 16px; flex: none; margin: 0; }   /* first in the row (the shared .donate style pushes it right) */
.ed-races { display: flex; flex-wrap: wrap; gap: 14px 18px; }
.prose .ed-races .xb-link { text-decoration: none; }
html.phone .prose .ed-title { font-size: 18px; }
.ed-races { padding: 4px 4px 0; }   /* room for the photo rings when the row is clipped */
.ed-more { display: block; margin: 8px 0 0; padding: 4px 0; font: inherit; font-size: 14px; font-weight: 600; color: #2563eb; background: none; border: 0; cursor: pointer; }
@media (hover: hover) { .ed-more:hover { text-decoration: underline; } }
/* the group's title always sits to the right of its button, wrapping beside it when long */
.ed-head { flex-wrap: nowrap; }
.prose .ed-title { flex: 1; min-width: 0; line-height: 1.25; }
.ed-races .xb-link[hidden] { display: none; }
.prose h1.ed-h1 { font-weight: 400; }   /* Donate page heading in regular weight (Dave, 2026-10-03) */
/* Donate page opened from a race card: that candidate in a card of their own (photo, then name, race and Donate
   beside it), then "or", then the groups card */
.prose.ed-focus { display: flex; align-items: center; gap: 20px; }
.prose .ed-photo { width: 110px; height: 110px; margin: 0; flex: none; }
.ed-who { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; min-width: 0; }
.prose .ed-who a:not(.donate) { display: flex; flex-direction: column; gap: 3px; color: #000; text-decoration: none; }
.ed-who b { font-size: 24px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.2; }
.ed-who a:not(.donate) span { font-size: 17px; color: #475569; }
html.phone .ed-who b { font-size: 21px; }
.ed-dstack { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.prose .via-ab { font-size: 13px; color: #475569; text-decoration: none; white-space: nowrap; }
@media (hover: hover) { .prose .via-ab:hover { color: #2563eb; text-decoration: underline; } }
.ed-or { margin: 16px 0; text-align: center; font-size: 20px; color: #475569; }
/* wider screens: name and race, then the Donate block to their right, all in one row beside the photo (phones keep it stacked) */
html.desk .ed-who { flex-direction: row; align-items: center; gap: 40px; }
html.desk .prose.ed-focus { gap: 28px; padding-top: 32px; padding-bottom: 32px; }
/* phones: no race name under the candidate's name, which leaves room for "or ActBlue" under the button (Dave, 2026-10-03) */
html.phone .prose .ed-photo { width: 96px; height: 96px; }
html.phone .ed-who a:not(.donate) span { display: none; }
.donate .ed-via { font-weight: inherit; opacity: 1; }   /* "Donate via Oath" in one weight */
/* desktop race cards: the race name centred over the photo; Donate stays at the left (phones unchanged; Dave, 2026-10-03) */
html.desk .rc-top .rc-code { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); white-space: nowrap; }
.prose.ab-page { font-size: 17.5px; }   /* About page text a smidge bigger (Dave, 2026-10-03) */
.ed-or { color: #e2e8f0; }   /* on the navy page */
/* chevrons on the royal-navy page: white and a little heavier so they show (a soft shadow keeps them visible if they ever sit over a card) */
body.plain .chev { color: #fff; filter: drop-shadow(0 1px 2px rgba(15, 23, 42, .45)); }
body.plain .chev svg { width: 30px; height: 30px; stroke-width: 2.8; }
body.plain .chev:hover { color: #fff; background: rgba(255, 255, 255, .14); }
html.desk body.plain .app:not(.app-page) { margin-top: -6px; }   /* desktop: grid and race cards start the same distance below the header as the About panel (22px) */
.pinbar { display: none !important; }   /* no pinned name bar on race cards, phone or desktop (Dave, 2026-10-03) */
/* state card (map tab): the state's races as rows inside the card, then its map; news and volunteering on the right */
.stcard .list { gap: 8px; }
.stcard .lrow { box-shadow: none; }
.stcard .map-box.map-state { margin-top: 2px; }
html.desk .stcard .rc-top .rc-code { position: static; transform: none; }   /* the state name sits at the left, not over a photo */
/* state card races: photo tiles (race label, then the Democrat's last name), four per row on desktop, three on phones */
.st-races { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 10px; padding-top: 4px; }
html.phone .st-races { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 8px; }
.st-race { display: flex; flex-direction: column; align-items: center; gap: 5px; padding: 0; border: 0; background: none; font: inherit; cursor: pointer; text-align: center; min-width: 0; }
.st-race .avatar { width: 88px; height: 88px; margin: 3px 3px 5px; font-size: 28px; box-shadow: 0 0 0 1.5px #fff, 0 0 0 4px var(--d); }
.st-race b { font-size: 17px; font-weight: 700; color: #2563eb; line-height: 1.2; white-space: nowrap; }
.st-race .st-name { font-size: 15px; color: #475569; line-height: 1.2; }
@media (hover: hover) { .st-race:hover b { text-decoration: underline; } }
.ed-plain .ed-group:first-of-type { border-top: 0; margin-top: 0; padding-top: 4px; }   /* plain Donate page: no heading or hairline above the first row */
/* map tab: desktop hover card (a state's name and its Democrats) */
.map-tip { position: fixed; left: 0; top: 0; z-index: 40; pointer-events: none; max-width: 480px; padding: 12px 14px; will-change: transform; background: #fff; border: 1px solid var(--line-strong, #bcc5d1);
  border-radius: 12px; box-shadow: 0 8px 24px rgba(15, 23, 42, .22); }
.map-tip[hidden] { display: none; }
.mt-races { display: grid; gap: 12px 12px; justify-content: center; }
.mt-race { display: flex; flex-direction: column; align-items: center; gap: 5px; width: 78px; text-align: center; }
.mt-race .avatar { width: 66px; height: 66px; margin: 3px; box-shadow: 0 0 0 1.5px #fff, 0 0 0 3.5px var(--d); }
.mt-race b { font-size: 14px; font-weight: 700; color: #2563eb; line-height: 1.15; }
/* map tab, phones: pinch-zoom inside the map box, and the states as a list underneath */
.map-box.zoomable { position: relative; overflow: hidden; touch-action: pan-y; border-radius: 8px; }
.map-box.zoomable svg { transform-origin: 0 0; will-change: transform; }
.map-reset { position: absolute; right: 6px; top: 6px; padding: 5px 12px; border: 1px solid var(--line-strong, #bcc5d1); border-radius: 999px; background: #fff;
  font: inherit; font-size: 14px; font-weight: 700; color: #0f172a; box-shadow: 0 2px 6px rgba(15, 23, 42, .15); }
.map-reset[hidden] { display: none; }
.st-list { display: grid; gap: 8px; margin-top: 2px; }
.st-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 15px 14px; background: #fff; border: 2px solid var(--line-strong, #bcc5d1); border-radius: 14px;
  font: inherit; text-align: left; cursor: pointer; }
.st-row-name { font-size: 20px; font-weight: 700; color: #000; flex: 1 1 auto; min-width: 0; }
.st-row-pics { display: flex; flex: none; }
.st-row-pics .avatar { width: 44px; height: 44px; margin: 0 0 0 -10px; box-shadow: 0 0 0 2px #fff; }
.st-row-pics .avatar:first-child { margin-left: 0; }
.st-row-n { flex: none; font-size: 15px; color: #475569; min-width: 62px; text-align: right; }
.st-row .l-go { width: 18px; height: 18px; flex: none; fill: none; stroke: #0f172a; stroke-width: 2.4; }
.st-row { position: relative; }
.st-row .l-go { position: static; transform: none; margin: 0; }
/* desktop: the state list in two columns under the map, the map's width */
html.desk .st-list { max-width: 820px; margin: 0 auto; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (hover: hover) { .st-row:hover { border-color: #94a3b8; } .st-row:hover .st-row-name { text-decoration: underline; } }
html.desk .st-row { gap: 10px; }
html.desk .st-row-pics .avatar { width: 40px; height: 40px; margin-left: -12px; }
html.desk .st-row-pics .avatar:first-child { margin-left: 0; }
html.desk .st-row-n { min-width: 54px; }
.st-row { box-sizing: border-box; max-width: 100%; }   /* padding inside the width, so rows never run off a phone screen */
html.phone .st-row-pics .avatar { width: 40px; height: 40px; margin-left: -12px; }
html.phone .st-row-pics .avatar:first-child { margin-left: 0; }
html.phone .st-row { gap: 8px; padding: 14px 12px; }
html.phone .st-row-n { min-width: 0; }
html.phone .st-row-name { font-size: 19px; }
html.phone .st-row-pics .avatar:nth-child(n+4) { display: none; }   /* phones: up to three photos, so long names fit whole */
/* SoS page: the ratings card above the races (white, on the page background), "All" first and white */
.rmod { max-width: 560px; margin: 0 auto 14px; padding: 16px 18px 10px; background: #fff; border: 1.5px solid var(--line-strong, #bcc5d1); border-radius: 14px; }
.rmod[hidden] { display: none; }
.rmod .rline { width: 100%; max-width: 480px; margin: 0 auto; }
.rs-all::before { background: #fff; box-shadow: inset 0 0 0 1px #cbd5e1; }
.rs-all { color: #0f172a; }
.rmod-src { margin: 10px 0 0; text-align: center; font-size: 13px; color: #64748b; }
html.phone .rmod { margin-bottom: 10px; padding: 14px 12px 8px; }
html.desk .rmod { margin-top: 14px; }   /* the same blue gap under the header as the map page (18px) */
html.phone .rmod { padding: 16px 6px 12px; }   /* phones: the bar runs nearly edge to edge so the labels fit */   /* phones: a bit more breathing room */
html.phone .rmod .rline { margin-bottom: 4px; }
html.phone .rmod-src { margin-top: 14px; }
/* SoS ratings card: a segmented control - one bar with an outline round the whole set; each segment is a tall
   tap target with its label inside, coloured by rating; the chosen one gets a dark inset outline and a bold label */
.rmod .rline { gap: 0; border: 1.5px solid #64748b; border-radius: 12px; overflow: hidden; max-width: 520px; }
.rmod .rline button { min-height: 50px; padding: 0 2px; justify-content: center; align-items: center; font-size: 15px; font-weight: 600; color: #1e293b;
  border-left: 1px solid rgba(15, 23, 42, .18); transition: box-shadow .12s; }
.rmod .rline button:first-child { border-left: 0; }
.rmod .rline button::before { display: none; }
.rmod .rline .rs-all { background: #fff; }
.rmod .rline .rs-leand { background: #dbe6fd; color: #1d4ed8; }
.rmod .rline .rs-toss { background: var(--chrome-2, #e2e8f0); }
.rmod .rline .rs-lean { background: #fde2e2; color: #b91c1c; }
.rmod .rline .rs-likely { background: #f8b4b4; color: #991b1b; }
/* the chosen segment fills solid in its rating colour with white text; the others stay light tints - no outlines */
.rmod .rline button[aria-pressed="true"] { box-shadow: none; font-weight: 700; color: #fff; }
.rmod .rline .rs-all[aria-pressed="true"] { background: #fff; color: #0f172a; text-decoration: underline; text-decoration-thickness: 2.5px; text-underline-offset: 5px; }   /* All: just underlined */
.rmod .rline .rs-leand[aria-pressed="true"] { background: #2563eb; }
.rmod .rline .rs-toss[aria-pressed="true"] { background: #64748b; }
.rmod .rline .rs-lean[aria-pressed="true"] { background: #e05252; }
.rmod .rline .rs-likely[aria-pressed="true"] { background: #b91c1c; }
@media (hover: hover) { .rmod .rline button:not([aria-pressed="true"]):hover { filter: brightness(.94); } }
html.phone .rmod .rline button { font-size: 13.5px; letter-spacing: -0.01em; min-height: 52px; padding: 0 1px; }
html.phone .rmod .rline { margin-bottom: 0; }
html.phone .rmod .rline { max-width: none; width: auto; margin-left: 0; margin-right: 0; }   /* fills the card, same gap each side (the header bar's fixed 330px doesn't apply here) */
/* The outline is drawn by each segment (top and bottom, plus the outer ends), not by the bar, so the chosen segment's
   colour fills its full height, edge to edge, instead of sitting inside the outline and looking shorter */
.rmod .rline { border: 0; }
.rmod .rline button { box-shadow: inset 0 1.5px 0 #64748b, inset 0 -1.5px 0 #64748b; }
.rmod .rline button:first-child { box-shadow: inset 0 1.5px 0 #64748b, inset 0 -1.5px 0 #64748b, inset 1.5px 0 0 #64748b; }
.rmod .rline button:last-child { box-shadow: inset 0 1.5px 0 #64748b, inset 0 -1.5px 0 #64748b, inset -1.5px 0 0 #64748b; }
.rmod .rline button[aria-pressed="true"]:not(.rs-all) { box-shadow: none; border-left-color: transparent; }
.rmod .rline button[aria-pressed="true"]:not(.rs-all) + button { border-left-color: transparent; }
/* the end segments carry the bar's rounded corners themselves, so their outline follows the curve */
.rmod .rline { border-radius: 12px; }
.rmod .rline button:first-child { border-radius: 12px 0 0 12px; }
.rmod .rline button:last-child { border-radius: 0 12px 12px 0; }
/* Governor / SoS ratings: no card - the bar sits on the blue page, the width of the race cards; raters under it */
.rmod { background: none; border: 0; padding: 0; max-width: 620px; }
html.desk .rmod { margin-top: 18px; margin-bottom: 18px; }
html.phone .rmod { padding: 0; margin-bottom: 12px; }
.rmod .rline { max-width: none; width: 100%; }
html.phone .rmod .rline { margin: 0; }
.rmod .rline button { box-shadow: inset 0 1.5px 0 #fff, inset 0 -1.5px 0 #fff; border-left-color: rgba(15, 23, 42, .15); }
.rmod .rline button:first-child { box-shadow: inset 0 1.5px 0 #fff, inset 0 -1.5px 0 #fff, inset 1.5px 0 0 #fff; }
.rmod .rline button:last-child { box-shadow: inset 0 1.5px 0 #fff, inset 0 -1.5px 0 #fff, inset -1.5px 0 0 #fff; }
.rmod .rmod-src { color: #e2e8f0; margin: 10px 0 0; }
.rmod-raters { display: flex; justify-content: center; flex-wrap: wrap; gap: 4px 22px; margin: 10px 0 0; }
.rmod-raters button { padding: 4px 0; border: 0; background: none; font: inherit; font-size: 15px; font-weight: 600; color: #dbe6fd; cursor: pointer; }
.rmod-raters button[aria-pressed="true"] { color: #fff; font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }
@media (hover: hover) { .rmod-raters button:hover { color: #fff; } }
/* on the blue page the chosen segment keeps the white outline (so a blue Lean D doesn't melt into the background) */
.rmod .rline button[aria-pressed="true"]:not(.rs-all) { box-shadow: inset 0 1.5px 0 #fff, inset 0 -1.5px 0 #fff; }
.rmod .rline button[aria-pressed="true"]:not(.rs-all):first-child { box-shadow: inset 0 1.5px 0 #fff, inset 0 -1.5px 0 #fff, inset 1.5px 0 0 #fff; }
.rmod .rline button[aria-pressed="true"]:not(.rs-all):last-child { box-shadow: inset 0 1.5px 0 #fff, inset 0 -1.5px 0 #fff, inset -1.5px 0 0 #fff; }
.rmod .rline .rs-leand[aria-pressed="true"] { background: #1e3a8a; }
/* the chosen segment is just underlined, in its own colour (no fill change) - simpler (Dave, 2026-10-04) */
.rmod .rline .rs-all[aria-pressed="true"] { background: #fff; color: #0f172a; }
.rmod .rline .rs-leand[aria-pressed="true"] { background: #dbe6fd; color: #1d4ed8; }
.rmod .rline .rs-toss[aria-pressed="true"] { background: var(--chrome-2, #e2e8f0); color: #0f172a; }
.rmod .rline .rs-lean[aria-pressed="true"] { background: #fde2e2; color: #b91c1c; }
.rmod .rline .rs-likely[aria-pressed="true"] { background: #f8b4b4; color: #991b1b; }
.rmod .rline button[aria-pressed="true"] { font-weight: 800; text-decoration: underline; text-decoration-thickness: 2.5px; text-underline-offset: 5px; }
/* no white outline round the segments (it haloed, worst on Likely R): the colours stand on the blue by themselves */
.rmod .rline button, .rmod .rline button:first-child, .rmod .rline button:last-child,
.rmod .rline button[aria-pressed="true"]:not(.rs-all), .rmod .rline button[aria-pressed="true"]:not(.rs-all):first-child,
.rmod .rline button[aria-pressed="true"]:not(.rs-all):last-child { box-shadow: none; }
.rmod .rline button[aria-pressed="true"]:not(.rs-all) + button, .rmod .rline button[aria-pressed="true"]:not(.rs-all) { border-left-color: rgba(15, 23, 42, .15); }
.rmod .rline button:first-child { border-left: 0; }
html.phone .rmod { margin-top: 8px; }   /* phones: room between the header and the bar (18px, like the gap under the bar) */
/* Money tab: its views as options on the blue page, above the dashboard */
.rmod.pnav .rmod-list { margin: 0; }   /* the views pulldown */
html.desk .rmod.pnav { margin-top: 18px; margin-bottom: 14px; }
html.phone .rmod.pnav { margin-top: 10px; margin-bottom: 10px; }
/* House: the list menu under the raters, a white rounded select on the blue page */
.rmod-list { display: flex; justify-content: center; margin: 12px 0 0; }
.rmod-list .dd-btn { appearance: none; -webkit-appearance: none; font: inherit; font-size: 16px; font-weight: 600; color: #0f172a; background: #fff
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%230f172a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 14px center / 12px 8px;
  border: 0; border-radius: 10px; padding: 10px 40px 10px 16px; min-width: 240px; cursor: pointer; }
.rmod-list .dd-btn.on { box-shadow: inset 0 0 0 2px #1e293b; }
/* dropdown.js: every site dropdown is a button plus a list that always drops down from it */
.dd { position: relative; display: inline-block; }
.dd > select { display: none; }
.dd-btn { text-align: left; white-space: nowrap; line-height: 1.35; }
.dd-menu { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; min-width: 100%; max-height: min(60vh, 420px); overflow-y: auto;
  padding: 6px; background: #fff; border: 1px solid #d7dde5; border-radius: 10px; box-shadow: 0 8px 24px rgba(15, 23, 42, .18); }
.dd-menu[hidden] { display: none; }
.dd-menu button { display: block; width: 100%; padding: 7px 12px; border: 0; border-radius: 6px; background: none; font: inherit; font-size: 16px; color: #0f172a; text-align: left; white-space: nowrap; cursor: pointer; }
.dd-menu button[aria-selected="true"] { font-weight: 700; }
.dd-menu button:has(.dd-note) { display: flex; justify-content: space-between; gap: 18px; }
.dd-note { font-weight: 400; color: #94a3b8; }
/* events.js: volunteer-event labels (race and state cards, the Volunteer page): small square-cornered tags, not pills */
.ev-tag { display: inline-block; margin-right: 6px; padding: 0 6px; border-radius: 4px; font-size: 12.5px; font-weight: 600; line-height: 1.5; }
.ev-virtual { background: #dbeafe; color: #1d4ed8; }
.ev-inperson { background: #ede9fe; color: #6d28d9; }
.ev-type { background: #f1f5f9; color: #334155; }
.ev-full { background: #fee2e2; color: #b91c1c; }
.ev-hp { background: #fef3c7; color: #92400e; }
.dd-menu button:hover, .dd-menu button:focus { background: #f1f5f9; outline: none; }
/* The ratings bar and its raters as one block: the coloured segments on top, the raters in a light strip attached
   underneath (selected rater dark and underlined), rounded as a whole (Dave, 2026-10-04) */
.rmod .rblock { border-radius: 12px; overflow: hidden; background: #fff; box-shadow: 0 2px 8px rgba(15, 23, 42, .18); }
.rmod .rblock .rline { border-radius: 0; }
.rmod .rblock .rline button:first-child, .rmod .rblock .rline button:last-child { border-radius: 0; }
.rmod .rblock .rmod-raters { margin: 0; padding: 7px 10px 8px; gap: 2px 20px; background: #f1f5f9; border-top: 1px solid rgba(15, 23, 42, .12); }
.rmod .rblock .rmod-raters button { color: #475569; font-size: 14px; font-weight: 600; padding: 3px 0; }
.rmod .rblock .rmod-raters button[aria-pressed="true"] { color: #0f172a; font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
@media (hover: hover) { .rmod .rblock .rmod-raters button:hover { color: #0f172a; } }
html.phone .rmod .rblock .rmod-raters { gap: 2px 14px; }
html.phone .rmod .rblock .rmod-raters button { font-size: 13.5px; }
/* the raters strip: thinner - a slim band along the bottom of the bar, just the names */
.rmod .rblock .rmod-raters { padding: 3px 10px 4px; gap: 0 18px; line-height: 1.2; }
.rmod .rblock .rmod-raters button { font-size: 12.5px; padding: 2px 0; }
.rmod .rblock .rmod-raters button[aria-pressed="true"] { text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
html.phone .rmod .rblock .rmod-raters button { font-size: 12.5px; }
/* raters band: back up to a comfortable height and size */
.rmod .rblock .rmod-raters { padding: 8px 10px 9px; gap: 2px 22px; }
.rmod .rblock .rmod-raters button { font-size: 15px; padding: 3px 0; }
.rmod .rblock .rmod-raters button[aria-pressed="true"] { text-decoration-thickness: 2px; text-underline-offset: 4px; }
html.phone .rmod .rblock .rmod-raters { gap: 2px 16px; }
html.phone .rmod .rblock .rmod-raters button { font-size: 14.5px; }
.rmod .rblock .rmod-raters { background: #fff; }   /* raters band white (Dave, 2026-10-04) */
.rmod .rblock .rmod-raters { gap: 2px 32px; }   /* a bit more space between the raters */
html.phone .rmod .rblock .rmod-raters { gap: 2px 22px; }
.rmod .rblock .rmod-raters { justify-content: space-evenly; gap: 2px 12px; padding-left: 6px; padding-right: 6px; }   /* raters spread evenly across the whole band */
html.phone .rmod .rblock .rmod-raters { gap: 2px 8px; }
/* House: equal space above and below the "Or sort by…" menu */
.rmod .rmod-list { margin-top: 16px; }
.rmod:has(.rmod-list) { margin-bottom: 16px; }
html.desk .rmod:has(.rmod-list) { margin-bottom: 16px; }
html.phone .rmod:has(.rmod-list) { margin-bottom: 16px; }
html.desk .rmod:has(.rmod-list) { margin-bottom: 12px; }   /* + the races block's own 4px = 16 */
/* Under the on-page controls the race list adds no space of its own; the controls set the gap:
   Governor / SoS: the same below the bar as above it (18px); House: 16px above and below the "Or sort by…" menu */
.rmod:not([hidden]) ~ .races, .rmod:not([hidden]) ~ #races { margin-top: 0; }
.rmod { margin-bottom: 18px; }
html.desk .rmod, html.phone .rmod { margin-bottom: 18px; }
html.desk .rmod:has(.rmod-list), html.phone .rmod:has(.rmod-list) { margin-bottom: 16px; }
html.desk .rmod.pnav { margin-bottom: 22px; }   /* the same space below the views pulldown as above it */
html.phone .rmod.pnav { margin-bottom: 20px; }
html.desk .rmod:not(.pnav):not(:has(.rmod-list)) { margin-bottom: 22px; }   /* desktop: the bar sits 22px under the header, so 22px under it too */
