/* bluewavesc.org. Blue Wave SC's brand as on the sign-up form's header: navy and the wave's sky, on white, in one
   typeface (Figtree, the closest Google Fonts face to the form header's Avenir Next, served from here). */
@font-face {
  font-family: "Figtree";
  src: url("assets/fonts/figtree-latin.woff2") format("woff2");
  font-weight: 400 900;
  font-display: swap;
}

:root {
  --navy: #012957;
  --sky: #29B7FF;
  --white: #ffffff;
  --mist: #c9dcef;      /* the navy's own hue, lightened: secondary words on the navy field */
  --line: #d9e3ee;      /* rules on white, and 2024's gray on the map */
  --ink-2: rgba(1, 41, 87, 0.74);  /* secondary words on white: the navy, lightened by the paper */
  --pad: max(24px, calc((100vw - 1200px) / 2));
  color-scheme: light;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--white);
  color: var(--navy);
  font: 400 18px/1.5 "Figtree", "Avenir Next", system-ui, sans-serif;
  font-feature-settings: "kern", "liga";
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--sky); color: var(--navy); }
a { color: inherit; text-underline-offset: 0.18em; text-decoration-thickness: 0.06em; }
:focus-visible { outline: 3px solid var(--sky); outline-offset: 3px; border-radius: 4px; }
img { display: block; max-width: 100%; height: auto; }
p, h1, h2, h3, figure { margin: 0; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.wrap { padding-inline: var(--pad); }

/* The first screen, built from Apple's event page (apple.com/apple-events): one field, the event's mark at size,
   its name, the date once, one line and the one button, on one centre line. */
.first { background: var(--navy); color: var(--white); padding-block: 40px 72px; text-align: center; }
.lockup { display: flex; align-items: center; justify-content: center; gap: 16px; font-weight: 800; font-size: 34px; line-height: 1; letter-spacing: -0.015em; }
.lockup img { height: 92px; width: auto; }
.lockup span { padding-top: 0.06em; }  /* the name's capitals sit on the mark's middle, measured on the export */
.first h1 {
  margin-top: 56px;
  font-size: clamp(32px, 10.2vw, 96px);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.025em;
}
.keep { white-space: nowrap; }
.when { margin-top: 28px; font-size: clamp(20px, 1.2vw + 15px, 30px); font-weight: 700; line-height: 1.2; }
.what { margin: 12px auto 0; max-width: 38em; color: var(--mist); font-size: clamp(17px, 0.5vw + 15px, 22px); line-height: 1.45; text-wrap: balance; }
.go { margin-top: 36px; }
.act {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 60px; padding: 14px 36px;
  background: var(--sky); color: var(--navy);
  font-size: 19px; font-weight: 800; line-height: 1.2; text-align: center; text-decoration: none;
  border-radius: 999px;
  transition: background-color 160ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.act:hover { background: #5ccaff; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28); }
.act:focus-visible { outline-color: var(--white); }

@media (max-width: 599px) {
  .first { padding-block: 32px 48px; }
  .lockup { gap: 12px; font-size: 24px; }
  .lockup img { height: 62px; }
  .first h1 { margin-top: 40px; }
  .when { margin-top: 20px; }
  .go { margin-top: 28px; }
  .act { display: flex; width: 100%; min-height: 58px; padding-inline: 16px; font-size: clamp(15px, 4.36vw, 17px); }
}

/* find */
/* Find your district, on the sky: one question, one field, one button, the source in small type under it (built from
   Common Cause's "Who are my representatives?", research/sections notes.txt). The field and the button are the first
   screen's pill at its height; everything stands on the grid's left line. */
.lookup { padding-block: 72px; background: var(--sky); color: var(--navy); }
.lookup-title { font-size: clamp(30px, 2.4vw + 13px, 48px); font-weight: 800; line-height: 1.08; letter-spacing: -0.022em; text-wrap: balance; }
.lookup-body { max-width: 760px; margin-top: 28px; }
@media (min-width: 1024px) { .lookup-body { max-width: calc(100% - 360px); } }  /* the map's column: the card is 320 and its gap 40 */
@media (min-width: 1280px) { .lookup-body { max-width: calc(100% - 436px); } }  /* the card 380, its gap 56 */
.lookup-form { display: flex; gap: 12px; }
.lookup-field {
  flex: 1 1 auto; min-width: 0; height: 60px; padding: 0 24px;
  border: 2px solid var(--navy); border-radius: 999px; background: var(--white); color: var(--navy);
  font: inherit; font-size: 19px; font-weight: 600; -webkit-appearance: none; appearance: none;
}
.lookup-field::placeholder { color: var(--ink-2); font-weight: 500; opacity: 1; }
.lookup-field:focus-visible { outline: 3px solid var(--white); outline-offset: 2px; }
.lookup-go {
  flex: none; min-height: 60px; padding: 14px 32px; border: 0; border-radius: 999px;
  background: var(--navy); color: var(--white); font: inherit; font-size: 19px; font-weight: 800; line-height: 1.2; cursor: pointer;
  transition: background-color 160ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.lookup-go:hover { background: #02386f; box-shadow: 0 6px 18px rgba(1, 41, 87, 0.28); }
.lookup-go:focus-visible { outline: 3px solid var(--white); outline-offset: 3px; }
.lookup-go[aria-busy="true"] { cursor: progress; }
.lookup-note { margin-top: 14px; font-size: 15px; font-weight: 500; line-height: 1.4; }
.lookup-note a { font-weight: 800; }
@media (max-width: 599px) {
  .lookup { padding-block: 48px; }
  .lookup-body { margin-top: 20px; }
  .lookup-form { flex-direction: column; }
  .lookup-field, .lookup-go { width: 100%; height: 58px; min-height: 58px; font-size: 17px; }
}
/* /find */

/* figures */
/* The three figures on the navy, each a sentence that leads with its number (Figma's "at a glance"; the States
   Project sets the number inside the sentence; Politico sets the numeral in the side's color), the source in small
   type under it. One line of three on a laptop, divided by hairlines; stacked on a phone. No tiles, no icons. */
.figures { padding-block: 88px; background: var(--navy); color: var(--white); }
.figs { display: grid; margin: 0; padding: 0; list-style: none; }
.fig { display: flex; flex-direction: column; }
.fig-line { font-size: 26px; font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; text-wrap: balance; }
.fig-n { display: block; margin-bottom: 10px; color: var(--sky); font-size: clamp(64px, 6.2vw, 92px); font-weight: 800; line-height: 0.92; letter-spacing: -0.035em; font-variant-numeric: lining-nums proportional-nums; }
.fig-src { margin-top: auto; padding-top: 18px; color: var(--mist); font-size: 15px; font-weight: 600; line-height: 1.4; text-wrap: balance; }
.fig-src a { color: inherit; }
.fig-src a:hover { color: var(--white); }
@media (min-width: 1024px) {
  .figs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .fig { padding-inline: 40px; border-left: 1px solid rgba(201, 220, 239, 0.28); }
  .fig:first-child { padding-left: 0; border-left: 0; }
  .fig:last-child { padding-right: 0; }
  /* The three sources start on one line, whichever sentence above them runs to two lines. */
  @supports (grid-template-rows: subgrid) {
    .figs { grid-template-rows: auto auto; }
    .fig { display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0; }
    .fig-src { margin-top: 0; }
  }
}
@media (max-width: 1023px) {
  .figures { padding-block: 24px; }
  .fig { padding-block: 32px; border-top: 1px solid rgba(201, 220, 239, 0.28); }
  .fig:first-child { border-top: 0; }
  .fig-line { font-size: 24px; }
}
/* /figures */

/* video */
/* The video with the words beside it (Jon Ossoff's "In the Senate": the video the larger of the two, the words
   beside it, their tops on one line). The play control sits in the caption under the picture, never drawn on it;
   the whole picture plays too. Stacked on a phone: the video, its caption, the words. */
.film { padding-block: 96px; }
.film-grid { display: grid; gap: 28px; align-items: start; }
.film-media { margin: 0; }
.film-frame { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; border-radius: 16px; background: var(--navy); }
.film-frame:focus-visible { outline: 3px solid var(--sky); outline-offset: 3px; }
.film-poster, .film-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: cover; }
.film-poster { transition: transform 600ms cubic-bezier(0.16, 1, 0.3, 1); }
.film-frame:hover .film-poster { transform: scale(1.015); }
.film-caption { display: flex; align-items: center; gap: 14px; min-height: 48px; margin-top: 14px; color: var(--ink-2); font-size: 15px; font-weight: 500; line-height: 1.35; }
.film-play {
  flex: none; display: grid; place-items: center; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%;
  background: var(--navy); color: var(--white); cursor: pointer;
  transition: background-color 160ms cubic-bezier(0.16, 1, 0.3, 1), color 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.film-play svg { width: 22px; height: 22px; margin-left: 3px; fill: currentColor; }
.film-play:hover, .film-frame:hover + .film-caption .film-play { background: var(--sky); color: var(--navy); }
.film-play[hidden] { display: none; }
.film-words p + p { margin-top: 0.9em; }
.film-words p { max-width: 34em; font-size: clamp(19px, 0.4vw + 16px, 22px); font-weight: 500; line-height: 1.5; text-wrap: pretty; }
@media (min-width: 1024px) {
  .film-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: 56px; }
  .film-words p { margin-top: -0.3em; }  /* the paragraph's first cap height on the video's top edge */
}
@media (max-width: 599px) {
  .film { padding-block: 56px; }
  .film-frame { border-radius: 12px; }
}
/* /video */

/* class */
/* The class: one wide band on the navy, the first screen's field. Until the picture, the count alone, set as large
   as the first screen's headline steps down to (its numeral in the sky, as the figures set theirs); with the
   picture, the picture alone, edge to edge up to the first screen's width, never cropped. The roster line under it. */
.class[hidden] { display: none; }
.class-band { background: var(--navy); color: var(--white); }
.class-count { padding-block: 104px; font-size: clamp(40px, 6vw, 88px); font-weight: 800; line-height: 1.02; letter-spacing: -0.03em; text-wrap: balance; }
.class-count[hidden] { display: none; }
.class-count .n { color: var(--sky); }
.class-photo { display: block; width: 100%; max-width: 1440px; height: auto; margin-inline: auto; }
.class { padding-bottom: 72px; }
.class-roster { padding-block: 24px 0; font-size: 18px; font-weight: 600; line-height: 1.4; }
.class-roster a { font-weight: 800; }
@media (max-width: 599px) {
  .class-count { padding-block: 64px; }
  .class { padding-bottom: 48px; }
  .class-roster { font-size: 17px; }
}
/* /class */

/* how */
/* How to ask, for a voter: three numbered steps, each a verb phrase in the order a person does them (When We All
   Vote's "01. Register to vote, 02. Get ready to vote"), divided by hairlines. Early voting beside them is its own
   object on the sky: the dates as the headline, the hours, the one link and Election Day, each once. */
.steps-grid { display: grid; gap: 48px; margin-bottom: 96px; padding-top: 56px; border-top: 1px solid var(--line); align-items: start; }
.how-title { font-size: clamp(30px, 2.4vw + 13px, 48px); font-weight: 800; line-height: 1.08; letter-spacing: -0.022em; }
.steps { margin: 28px 0 0; padding: 0; list-style: none; counter-reset: step; }
.step { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: baseline; padding-block: 22px; border-top: 1px solid var(--line); counter-increment: step; }
.step:last-child { border-bottom: 1px solid var(--line); }
.step::before { content: counter(step); grid-column: 1; grid-row: 1; font-size: 40px; font-weight: 800; line-height: 1; letter-spacing: -0.02em; font-variant-numeric: lining-nums; }
.step > * { grid-column: 2; }
.step-do { font-size: 22px; font-weight: 700; line-height: 1.3; text-wrap: balance; }
.step-more { margin-top: 6px; color: var(--ink-2); font-size: 16px; font-weight: 500; line-height: 1.4; }
.step-more a { color: var(--navy); font-weight: 700; }
.to-reddit { white-space: nowrap; }
.to-reddit img { display: inline-block; width: 1.05em; height: 1.05em; margin: 0 0.22em 0 0.06em; vertical-align: -0.16em; }

.vote { padding: 36px 32px 32px; border-radius: 20px; background: var(--sky); color: var(--navy); }
.vote-title { font-size: clamp(28px, 1.4vw + 16px, 36px); font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; text-wrap: balance; }
.vote-hours { margin-top: 12px; font-size: 18px; font-weight: 600; line-height: 1.4; }
.vote-go { margin-top: 24px; }
.vote-link {
  display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 12px 26px;
  border-radius: 999px; background: var(--navy); color: var(--white); font-size: 17px; font-weight: 800; line-height: 1.2; text-decoration: none;
  transition: background-color 160ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.vote-link:hover { background: #02386f; box-shadow: 0 6px 18px rgba(1, 41, 87, 0.28); }
.vote-link:focus-visible { outline-color: var(--white); }
.vote-day { margin-top: 24px; padding-top: 18px; border-top: 1px solid rgba(1, 41, 87, 0.28); font-size: 18px; font-weight: 800; line-height: 1.3; }
@media (min-width: 1024px) {
  .steps-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: 56px; }
  .vote { margin-top: calc(clamp(30px, 2.4vw + 13px, 48px) * 1.08 + 28px); }  /* its top on the first step's rule */
}
@media (max-width: 599px) {
  .steps-grid { margin-bottom: 56px; padding-top: 40px; gap: 40px; }
  .step { grid-template-columns: 52px minmax(0, 1fr); }
  .step::before { font-size: 34px; }
  .step-do { font-size: 20px; }
  .vote { padding: 28px 24px 24px; border-radius: 16px; }
  .vote-link { display: flex; width: 100%; }
}
/* /how */

/* press */
/* For the press, on the white under a hairline on the grid: the heading, then the contact as one line (Stripe's
   newsroom: "Press and media inquiries" and the address, nothing else), and from Wednesday the release and the
   class picture as downloads (Figma's media center: what it is, and the file). */
.press { padding-block: 0 96px; }
.press-grid { display: grid; gap: 20px; padding-top: 56px; border-top: 1px solid var(--line); }
.press-title { font-size: clamp(30px, 2.4vw + 13px, 48px); font-weight: 800; line-height: 1.08; letter-spacing: -0.022em; }
.press-contact { font-size: clamp(20px, 0.6vw + 16px, 26px); font-weight: 700; line-height: 1.35; }
.press-contact a { white-space: nowrap; }
.press-files { display: flex; flex-wrap: wrap; gap: 16px; margin: 28px 0 0; padding: 0; list-style: none; }
.press-files[hidden], .press-files li[hidden] { display: none; }
.press-file {
  display: grid; grid-template-columns: auto; align-content: center; gap: 2px; min-height: 72px; padding: 14px 22px;
  border: 2px solid var(--navy); border-radius: 16px; text-decoration: none;
  transition: background-color 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
.press-file:hover { background: var(--line); }
.press-file:has(.press-thumb) { grid-template-columns: 96px auto; column-gap: 16px; padding-left: 12px; }
.press-thumb { grid-row: 1 / span 2; width: 96px; height: 54px; border-radius: 8px; object-fit: cover; background: var(--line); }
.press-file-name { font-size: 18px; font-weight: 800; line-height: 1.2; }
.press-file-kind { color: var(--ink-2); font-size: 14px; font-weight: 600; line-height: 1.3; }
@media (min-width: 1024px) {
  .press-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: 56px; align-items: baseline; }  /* the video's and early voting's columns */
}
@media (max-width: 599px) {
  .press { padding-bottom: 56px; }
  .press-grid { padding-top: 40px; }
}
/* /press */

/* foot */
/* The foot closes the page on the first screen's navy: who hosts it, with Reddit's mark where it points to Reddit,
   and "Organized by" with the firm's horizontal lockup in one-color white (the logo system's one-color form; the
   name never typed beside it). Nothing else. */
.foot { padding-block: 44px; border-top: 0; background: var(--navy); color: var(--white); font-size: 17px; }
.foot-grid { display: grid; gap: 18px; align-items: center; }
.foot-host { max-width: 46em; font-weight: 600; line-height: 1.45; }
.foot-host a { font-weight: 800; }
.foot-org { display: flex; align-items: center; gap: 12px; font-weight: 600; }
.foot-org a { display: block; margin-right: calc(-347.5 / 1928 * 30px); border-radius: 4px; }  /* the file's own clear space past the grid's edge, so the ink ends on it */
.foot-org img { display: block; height: 30px; width: auto; }
@media (min-width: 1024px) {
  .foot-grid { grid-template-columns: minmax(0, 1fr) auto; column-gap: 56px; }
}
/* /foot */


/* map */
/* 2. The map. Phase 2a built it from SDPB's candidate map (one blue, white hairlines, the number first), the Post's SC
   map (a few cities for bearings) and GGWash's guide (one search over the list; the card beside the map, never over
   it). Phase 2b refined it from the newsrooms' maps (research/map refined notes.txt): the Post's hover and its faint
   county lines, insets for the three dense cities, Bloomberg's one-pill switch, a one-line legend at 2024, and DRA's
   dense list collapsed behind one search. */
.map {
  --gray24: #d9e3ee;     /* 2024's districts with no Democrat: the page's rule color, a neutral */
  --gray24-hi: #c2d2e3;
  --navy-hi: #0b4c81;    /* a district under the pointer: the navy, a quarter of the way to the sky */
  padding-block: 72px 88px;
}
.map-head { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; }
.map-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; }

/* The year: one pill, two words of equal weight, the navy sliding under the chosen one. Radio buttons, so it works
   with scripts off. */
.year { position: relative; isolation: isolate; display: inline-grid; grid-template-columns: 1fr 1fr; margin: 0; padding: 4px; border: 2px solid var(--navy); border-radius: 999px; min-inline-size: 0; }
.year::before { content: ""; position: absolute; z-index: -1; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px); border-radius: 999px; background: var(--navy); transform: translateX(100%); transition: transform 360ms cubic-bezier(0.16, 1, 0.3, 1); }
.map[data-year="2024"] .year::before { transform: none; }
.year input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.year label { min-width: 104px; padding: 9px 24px; border-radius: 999px; color: var(--navy); font-size: 18px; font-weight: 700; line-height: 1.2; text-align: center; font-variant-numeric: tabular-nums; cursor: pointer; transition: color 200ms cubic-bezier(0.16, 1, 0.3, 1); }
.map[data-year="2024"] label[for="year-2024"], .map[data-year="2026"] label[for="year-2026"] { color: var(--white); }
.year input:focus-visible + label { outline: 3px solid var(--sky); outline-offset: 2px; }
html:not(.js) .map:has(#year-2024:checked) .year::before { transform: none; }
html:not(.js) .year input:checked + label { color: var(--white); }
html:not(.js) .year input:not(:checked) + label { color: var(--navy); }

/* The key, in the map's empty corner where Georgia would be (the Post's and Politico's one plain line, stacked); on a
   phone, the line under the state. Its second entry shows while any district is gray (at 2024, and until the last one
   turns on the way to 2026) and keeps its room at 2026, so nothing moves when it comes and goes. */
.legend { position: absolute; left: 0; bottom: 0; display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; color: var(--navy); font-size: 15px; font-weight: 600; line-height: 1.2; }
.legend li + li { visibility: hidden; opacity: 0; transition: opacity 240ms cubic-bezier(0.16, 1, 0.3, 1), visibility 0s 240ms; }
.map[data-say="24"] .legend li + li { visibility: visible; opacity: 1; transition: opacity 240ms cubic-bezier(0.16, 1, 0.3, 1); }
html:not(.js) .map:has(#year-2024:checked) .legend li + li { visibility: visible; opacity: 1; }
.legend li { display: flex; align-items: center; gap: 8px; }
.swatch { flex: none; width: 14px; height: 14px; border-radius: 4px; background: var(--navy); }
.swatch-none { background: var(--gray24); box-shadow: inset 0 0 0 1px var(--gray24-hi); }

/* The line over the map: both sentences share one place, so the switch never moves the map. In 2024 its number
   counts with the districts as they turn. */
.statement { display: grid; max-width: 21ch; font-size: clamp(30px, 2.4vw + 13px, 48px); font-weight: 800; line-height: 1.08; letter-spacing: -0.022em; }
.statement > span { grid-area: 1 / 1; text-wrap: balance; transition: opacity 200ms cubic-bezier(0.16, 1, 0.3, 1); }
.statement .n { font-variant-numeric: tabular-nums; }
.y24 { visibility: hidden; opacity: 0; }
.map[data-say="24"] .y24 { visibility: visible; opacity: 1; }
.map[data-say="24"] .y26 { visibility: hidden; opacity: 0; }
html:not(.js) .map:has(#year-2024:checked) .y24 { visibility: visible; opacity: 1; }
html:not(.js) .map:has(#year-2024:checked) .y26 { visibility: hidden; opacity: 0; }

/* For a keyboard: past the 124 districts to the search, shown only when it has the focus. */
.skip { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip:focus-visible { position: static; display: inline-block; width: auto; height: auto; margin-top: 16px; padding: 8px 14px; clip-path: none; border-radius: 8px; background: var(--navy); color: var(--white); font-size: 16px; font-weight: 700; text-decoration: none; }
.map-body { display: grid; gap: 24px; margin-top: 36px; }
.map-stage { position: relative; min-width: 0; }
.map-state { position: relative; margin: 0; }
.map-canvas { position: relative; }
.sc { display: block; width: 100%; height: auto; overflow: visible; outline: none; }

/* The districts. Every outline is drawn once and used again in the insets; the strokes do not scale with the drawing,
   so a hairline is the same hairline in the state map and in an inset at any width. */
.sc a { outline: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; cursor: pointer; }
.sc .d { fill: var(--navy); stroke: none; transition: fill 160ms cubic-bezier(0.16, 1, 0.3, 1); }
.sc .edges { fill: none; stroke: var(--white); stroke-width: 1px; stroke-linejoin: round; pointer-events: none; }
.map[data-year="2024"] .sc .d.no24 { fill: var(--gray24); }
html:not(.js) .map:has(#year-2024:checked) .sc .d.no24 { fill: var(--gray24); }
.map.is-turning .sc .d.no24 { transition: fill 240ms cubic-bezier(0.33, 0, 0.2, 1) var(--t, 0ms); }
.sc .d.is-hot, .sc .d:focus-visible { fill: var(--navy-hi); }
.map[data-year="2024"] .sc .d.no24.is-hot, .map[data-year="2024"] .sc .d.no24:focus-visible { fill: var(--gray24-hi); }
@media (hover: hover) {
  .sc .d:hover { fill: var(--navy-hi); }
  .map[data-year="2024"] .sc .d.no24:hover { fill: var(--gray24-hi); }
}
.sc .d.is-open, .map[data-year="2024"] .sc .d.no24.is-open { fill: var(--sky); }
.sc .counties { fill: none; stroke: var(--sky); stroke-opacity: 0.5; stroke-width: 1px; stroke-linejoin: round; pointer-events: none; }
.map[data-year="2024"] .sc .counties { stroke-opacity: 0.4; }
.mark { pointer-events: none; }
.mark .halo { fill: none; stroke: var(--white); stroke-width: 6px; stroke-linejoin: round; }
.mark .ring { fill: var(--sky); stroke: var(--sky); stroke-width: 2px; stroke-linejoin: round; }
.frames { pointer-events: none; }
.frames rect { fill: none; }
.frames .casing { stroke: var(--white); stroke-width: 4.5px; }
.frames .line { stroke: var(--navy); stroke-width: 1.5px; }

/* Cities for bearings: a dot at the city and its name in a small navy plate beside it, which reads on the navy, on
   2024's gray and on the paper alike; they never take a tap. */
.cities { position: absolute; inset: 0; pointer-events: none; }
.city { position: absolute; width: 0; height: 0; }
.city::before { content: ""; position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 50%; background: var(--white); box-shadow: 0 0 0 2px var(--navy); }
.city span { position: absolute; padding: 3px 6px 4px; border-radius: 4px; background: var(--navy); color: var(--white); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6); font-size: 13px; font-weight: 700; line-height: 1; letter-spacing: 0.01em; white-space: nowrap; }
.city-e span { left: 9px; top: 0; transform: translateY(-50%); }
.city-w span { right: 9px; top: 0; transform: translateY(-50%); }
.city-se span { left: 6px; top: 6px; }
.city-sw span { right: 6px; top: 6px; }
.city-nw span { right: 6px; bottom: 6px; }
.city-s span { left: 0; top: 8px; transform: translateX(-50%); }
.frame-name { position: absolute; width: 0; height: 0; }
.frame-name span { position: absolute; left: 0; top: 4px; padding: 3px 6px 4px; border-radius: 4px; background: var(--navy); color: var(--white); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6); font-size: 13px; font-weight: 700; line-height: 1; letter-spacing: 0.01em; white-space: nowrap; }

/* The insets: Greenville and Spartanburg, Columbia, Charleston, each outlined on the state map by the same frame. */
.insets { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 28px; }
.inset { margin: 0; min-width: 0; }
.inset-map { position: relative; overflow: hidden; border-radius: 10px; background: var(--white); }
/* A small inset sets its city names small, as the phone does. */
.inset-map { container-type: inline-size; }
@container (max-width: 220px) { .inset-map .city span { font-size: 11px; padding: 2px 5px 3px; } }
.inset-map::after { content: ""; position: absolute; inset: 0; border: 1.5px solid var(--navy); border-radius: 10px; pointer-events: none; }
/* A tap on the state map inside a frame brings that inset up: its edge turns sky for a moment. */
.inset-map::after { transition: border-color 400ms cubic-bezier(0.16, 1, 0.3, 1), border-width 400ms cubic-bezier(0.16, 1, 0.3, 1); }
.inset.is-called .inset-map::after { border-color: var(--sky); border-width: 3px; }
.inset figcaption { margin-top: 8px; font-size: 15px; font-weight: 700; line-height: 1.25; }

/* Before a district is opened: its number and its candidate, over the district under the pointer. */
.tip, .pin { position: absolute; z-index: 3; left: 0; top: 0; pointer-events: none; }
.tip[hidden], .pin[hidden] { display: none; }
.tip { display: flex; align-items: baseline; gap: 7px; padding: 6px 10px 7px; border-radius: 7px; background: var(--navy); color: var(--white); box-shadow: 0 0 0 2px var(--white), 0 8px 20px rgba(1, 41, 87, 0.28); font-size: 15px; font-weight: 600; line-height: 1; white-space: nowrap; transform: translate(-50%, calc(-100% - 12px)); }
.tip b { font-weight: 800; font-variant-numeric: tabular-nums; }
.tip::after, .pin span::after { content: ""; position: absolute; left: var(--ax, 50%); bottom: -7px; width: 0; height: 0; border: 7px solid transparent; border-bottom: 0; border-top-color: var(--navy); transform: translateX(-50%); }
.pin span { position: absolute; left: 0; top: 0; transform: translate(-50%, calc(-100% - 10px)); padding: 4px 7px 5px; border-radius: 5px; background: var(--navy); color: var(--white); box-shadow: 0 0 0 2px var(--white); font-size: 14px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; }

/* The card: one object on its own field. The name is the headline; the district and the counties under it; the
   website first, then the socials in one row, each icon with its name. */
.card-slot { min-width: 0; }
.card-slot:empty { display: none; }
.card { position: relative; display: block; padding: 20px; border: 1px solid var(--line); border-radius: 20px; background: var(--white); }
.card-head { display: grid; grid-template-columns: 88px minmax(0, 1fr); align-items: center; gap: 16px; }
.face { flex: none; width: 88px; height: 88px; border-radius: 12px; object-fit: cover; background: var(--navy); }
.face-initials { display: grid; place-items: center; color: var(--white); font-size: 30px; font-weight: 800; letter-spacing: 0.02em; line-height: 1; }
.who { display: flex; flex-direction: column; min-width: 0; }
.card .name { font-size: 24px; font-weight: 800; line-height: 1.1; letter-spacing: -0.015em; overflow-wrap: anywhere; }
.card .district { margin-top: 8px; font-size: 17px; font-weight: 700; line-height: 1.25; }
.card .counties { margin-top: 2px; font-size: 15px; line-height: 1.35; color: var(--ink-2); }
.card-body { display: grid; justify-items: start; gap: 12px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }
.site { display: inline-block; max-width: 100%; padding-block: 8px; font-size: 18px; font-weight: 800; line-height: 1.3; overflow-wrap: anywhere; text-decoration: underline; text-decoration-color: var(--sky); text-decoration-thickness: 2px; text-underline-offset: 0.22em; }
.site:hover { text-decoration-color: currentColor; }
.site-end { white-space: nowrap; }
.out { display: inline-block; width: 15px; height: 15px; margin-left: 5px; vertical-align: -1px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.socials { display: flex; flex-wrap: wrap; gap: 2px 18px; margin: 0; padding: 0; list-style: none; }
.socials a { display: inline-flex; align-items: center; gap: 7px; min-height: 40px; font-size: 15px; font-weight: 700; text-decoration: none; }
.socials a:hover { text-decoration: underline; }
.icon { flex: none; width: 18px; height: 18px; fill: currentColor; }
.ama { font-size: 16px; font-weight: 700; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.sources { margin-top: 24px; font-size: 14px; color: var(--ink-2); }
.sources summary { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; font-weight: 700; cursor: pointer; list-style: none; }
.sources summary::-webkit-details-marker { display: none; }
.sources summary::after { content: ""; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform 160ms; }
.sources[open] summary::after { transform: translateY(1px) rotate(-135deg); }
.sources ul { margin: 6px 0 0; padding: 0 0 0 18px; max-width: 70ch; }
.sources li + li { margin-top: 4px; }

/* The directory: one search, and under it nothing until a person types or asks for all 124. Each row is one dense
   line, 56 px at most; opened, it is the card the map opens. With scripts off there is no search and every row shows. */
.directory { margin-top: 48px; }
.find { position: sticky; top: 0; z-index: 4; display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; padding-block: 12px; background: var(--white); }
html:not(.js) .find { display: none; }
.search-box { position: relative; flex: 1 1 320px; max-width: 560px; }
.glass { position: absolute; left: 18px; top: 50%; width: 20px; height: 20px; transform: translateY(-50%); fill: none; stroke: var(--navy); stroke-width: 2.2; stroke-linecap: round; pointer-events: none; }
.search { display: block; width: 100%; height: 54px; padding: 0 18px 0 48px; border: 2px solid var(--navy); border-radius: 999px; background: var(--white); color: var(--navy); font: inherit; font-size: 18px; font-weight: 500; -webkit-appearance: none; appearance: none; }
.search::placeholder { color: var(--ink-2); opacity: 1; }
.search:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.search::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; cursor: pointer; background: center / 18px no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 5l10 10M15 5L5 15' stroke='%23012957' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E"); }
.show-all { flex: none; display: inline-flex; align-items: center; gap: 8px; height: 54px; padding: 0 22px; border: 2px solid var(--navy); border-radius: 999px; background: var(--white); color: var(--navy); font: inherit; font-size: 17px; font-weight: 700; cursor: pointer; transition: background-color 160ms cubic-bezier(0.16, 1, 0.3, 1), color 160ms cubic-bezier(0.16, 1, 0.3, 1); }
.show-all[hidden] { display: none; }
.show-all:hover { background: var(--navy); color: var(--white); }
.show-all:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; }
.search-status { flex-basis: 100%; margin-top: -4px; font-size: 15px; color: var(--ink-2); }
.search-status:empty { display: none; }

.rows { display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; column-gap: 32px; margin: 0; padding: 0; list-style: none; }
.row { border-bottom: 1px solid var(--line); scroll-margin-top: 96px; }
html.js .row:not(.is-shown) { display: none; }
.row:has(> details[open]) { border-bottom-color: transparent; }
.is-row:not([open]) { padding: 0; border: 0; border-radius: 0; background: none; }
.is-row:not([open]) > .card-head { display: flex; align-items: center; gap: 12px; min-height: 56px; padding-block: 3px; }
.is-row > summary { list-style: none; cursor: pointer; }
.is-row > summary::-webkit-details-marker { display: none; }
.is-row > summary:focus-visible { outline: 3px solid var(--sky); outline-offset: 2px; border-radius: 8px; }
.is-row .num { flex: none; width: 34px; font-size: 17px; font-weight: 800; line-height: 1; text-align: right; font-variant-numeric: tabular-nums; }
.is-row:not([open]) .face { width: 40px; height: 40px; border-radius: 50%; font-size: 14px; }
.is-row:not([open]) .name { font-size: 16px; font-weight: 700; line-height: 1.15; letter-spacing: 0; }
.is-row:not([open]) .district { display: none; }
.is-row:not([open]) .counties { margin-top: 1px; font-size: 13px; line-height: 15px; }
.is-row[open] { margin-block: 8px; }
.is-row[open] .num { display: none; }
.is-row[open] .who { padding-right: 24px; }
.chev { flex: none; width: 16px; height: 16px; margin-left: auto; fill: none; stroke: var(--navy); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform 200ms cubic-bezier(0.16, 1, 0.3, 1); }
.is-row[open] .chev { position: absolute; top: 16px; right: 16px; transform: rotate(180deg); }
.row:has(> .is-plain) .card-head { padding-right: 28px; }

@media (min-width: 640px) { .rows { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* The search and its button end on the edge the map and the insets end on. */
@media (min-width: 600px) { .search-box { max-width: none; } }
@media (min-width: 1024px) { .find { padding-right: 360px; } }
@media (min-width: 1280px) { .find { padding-right: 436px; } }
@media (min-width: 1024px) {
  .map-body { grid-template-columns: minmax(0, 1fr) 380px; gap: 56px; align-items: start; }
}
@media (min-width: 1024px) and (max-width: 1279px) {
  .map-body { grid-template-columns: minmax(0, 1fr) 320px; gap: 40px; }
}
@media (min-width: 1024px) {
  .card-slot { position: sticky; top: 24px; }
  .rows { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* On a laptop the card's photo runs the card's width. */
  .card { padding: 24px; }
  .card:not(.is-row) .card-head, .is-row[open] .card-head { grid-template-columns: minmax(0, 1fr); align-items: start; gap: 20px; }
  .card:not(.is-row) .face, .is-row[open] .face { width: 100%; height: auto; aspect-ratio: 1; border-radius: 14px; font-size: 104px; }
  .card .name { font-size: 32px; line-height: 1.05; }
  .card .district { margin-top: 12px; font-size: 18px; }
  .card .counties { font-size: 16px; }
  .card-body { margin-top: 20px; padding-top: 18px; }
}
@media (max-width: 599px) {
  .map { padding-block: 48px 56px; }
  .map-head { gap: 18px; }
  .map-controls { width: 100%; }
  .year { width: 100%; }
  .year label { min-width: 0; }
  .map-body { margin-top: 24px; gap: 20px; }
  .city span, .frame-name span { font-size: 11px; padding: 2px 5px 3px; }
  .legend { position: static; display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 12px; font-size: 14px; }
  .swatch { width: 12px; height: 12px; border-radius: 3px; }
  .insets { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 12px; margin-top: 20px; }
  .inset-charleston { grid-column: 1 / -1; }
  .inset figcaption { font-size: 14px; }
  .card { padding: 18px; }
  .directory { margin-top: 36px; }
  .search-box { flex-basis: 100%; max-width: none; }
  .show-all { height: 48px; }
}
/* /map */
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
