  /* Type scale: six sizes, one job each (label, UI, body, lead, statement, and the h1 lockup). Every font-size uses one
     of these; don't add a seventh. Phones step down one notch. */
  :root { --t-label: 11px; --t-ui: 13px; --t-body: 16px; --t-lead: clamp(17px, 1.1vw + 9px, 24px); --t-statement: 36px; }
  @media (max-width: 520px) {
    :root { --t-label: 10px; --t-ui: 12px; --t-body: 15px; --t-statement: 28px; }
    #q, .cg input { font-size: 16px; }   /* inputs stay 16px on phones, or iOS zooms the page when you tap them */
  }

  :root {
    --ground: #F3F4F8;
    --ink: #10172E;
    --ink-soft: #4A5270;
    --rule: #D5D9E4;
    --red: #B0101C;
    --red-deep: #8A0A14;
    --on-red: #FFFFFF;
    --on-red-soft: rgba(255,255,255,.78);
    --good: #1F7A52;
    --chip: #E6E8F0;
    --panel: #FFFFFF;
    --focus: #1D4ED8;
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      color-scheme: dark;
      --ground: #0B0F1C;
      --ink: #E9ECF5;
      --ink-soft: #9AA2BD;
      --rule: #252C44;
      --red: #C4141F;
      --red-deep: #8E0C15;
      --good: #3FD6A5;
      --chip: #1A2034;
      --panel: #141A2C;
      --focus: #7AA2FF;
    }
  }
  :root[data-theme="dark"] {
    color-scheme: dark;
    --ground: #0B0F1C;
    --ink: #E9ECF5;
    --ink-soft: #9AA2BD;
    --rule: #252C44;
    --red: #C4141F;
    --red-deep: #8E0C15;
    --good: #3FD6A5;
    --chip: #1A2034;
    --panel: #141A2C;
    --focus: #7AA2FF;
  }

  html { -webkit-tap-highlight-color: transparent; }
  body {
    background: var(--ground);
    color: var(--ink);
    font-family: "Public Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: var(--t-body);
    line-height: 1.5;
    -webkit-tap-highlight-color: transparent;
  }
  .wrap { max-width: 1320px; margin: 0 auto; padding-inline: 20px; padding-block: 14px 64px; }
  /* iPhone in landscape: keep everything clear of the Dynamic Island / notch and the rounded corners */
  .wrap { padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right)); padding-bottom: max(64px, env(safe-area-inset-bottom)); }
  .votebar { padding-left: max(20px, env(safe-area-inset-left)); padding-right: max(20px, env(safe-area-inset-right)); }
  .mono { font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace; }

  /* .topline sits outside <header> on every page now (the mobile sticky nav needs its own
     containing block spanning .wrap -- nested in header, position:sticky only held until
     header's own bottom edge scrolled by). A negative margin-top pulls the wordmark's own ink
     above the nav row's text -- safe to do (not an actual collision) because the lockup's text
     box and the nav row's links sit in different horizontal zones (lockup starts at the far
     left, nav is flush right) and h1 has pointer-events:none regardless, so nothing pulls focus
     from the real nav links underneath even where their rows visually overlap. */
  header { display: grid; gap: 14px; margin-top: -12px; margin-bottom: 20px; }
  h1 {
    font-family: "Anton", Impact, "Arial Narrow", sans-serif;
    font-weight: 400;
    font-size: min(90px, calc((100vw - 72px) / 9.25));   /* room for side padding and a desktop scrollbar */
    display: flex; align-items: center; gap: .14em;
    white-space: nowrap;
    line-height: .88;
    letter-spacing: .005em;
    margin: 0;
    color: var(--ink);
    text-transform: uppercase;
    /* Anton's glyphs carry more ink-overflow above/below the line box than the line-height
       admits at this size, so the rendered text box actually reaches up into the nav row 14px
       above -- real clicks on House/Senate/About there were landing on this invisible overflow
       instead of the link underneath. The h1 has nothing of its own to click, so drop it from
       hit-testing entirely and let pointer events fall through to whatever's really there. */
    pointer-events: none;
  }
  h1 span { color: var(--red); }
  h1 .words { color: var(--ink); }
  h1 .mark { height: .88em; width: .88em; flex: none; }
  .lede { max-width: 62ch; font-size: var(--t-body); color: var(--ink-soft); margin: 10px 0 16px; display: grid; gap: 8px; }
  .lede p { margin: 0; }
  .lede strong { color: var(--ink); }

  .votebar {
    background: var(--ink); color: var(--ground);
    padding-inline: 20px; padding-block: 9px;
    display: flex; flex-wrap: wrap; gap: 6px 18px; justify-content: center; align-items: center;
    font-size: var(--t-ui);
  }
  .votebar strong { font-weight: 700; }
  .votebar a { color: var(--ground); font-weight: 700; text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 4px; }
  .votebar a:hover { text-decoration-color: currentColor; }
  @media (max-width: 520px) { .votebar > span { flex-basis: 100%; text-align: center; } }   /* phones: the date, then both links on the next line */
  .frow { display: grid; gap: 6px; }
  .frow-lbl { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
  .paths, .statuses { display: flex; flex-wrap: wrap; gap: 8px; }
  .sw { width: 14px; height: 14px; flex: none; align-self: center; background: var(--red); }
  .sw.partial { background-color: var(--red); background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.45) 0 3px, transparent 3px 6px); }
  .sw.courts { background: transparent; border: 2px solid var(--red); }
  .sw.proposed { background: transparent; border: 2px dashed var(--red); }
  .sw.reversed { background: var(--chip); border: 1px solid var(--rule); }
  .path-btn {
    display: flex; align-items: baseline; gap: 10px;
    border: 1.5px solid var(--rule); background: var(--panel); color: var(--ink);
    border-radius: 3px; padding: 8px 12px; cursor: pointer; font: inherit; font-size: var(--t-ui); font-weight: 600;
  }
  .path-btn b { font-family: "Anton", Impact, sans-serif; font-weight: 400; font-size: var(--t-lead); line-height: 1; color: var(--red); font-variant-numeric: tabular-nums; }
  .path-btn[aria-pressed="true"] { border-color: var(--ink); background: var(--ink); color: var(--ground); }
  .path-btn[aria-pressed="true"] b { color: var(--ground); }
  .path-btn.zero:not([aria-pressed="true"]) { opacity: .4; }

  /* "The cost to you": shown after "What affects you?", above the squares; its ✕ clears that view */
  .cost { position: relative; border-bottom: 1px solid var(--rule); padding: 26px 48px 24px 0; margin-bottom: 20px; }
  .cost[hidden] { display: none; }
  .cost .k { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--red); margin: 0 0 12px; }
  .cost .big { font-size: var(--t-statement); line-height: 1.18; font-weight: 500; margin: 0 0 12px; max-width: 34ch; }
  .cost .big strong { color: var(--red); font-weight: 700; }
  .cost .sub { font-size: var(--t-body); line-height: 1.55; margin: 0; }
  .cost .sub.bill { margin-top: 8px; color: var(--ink-soft); }
  .cost .sub.bill a { color: inherit; text-underline-offset: 3px; }
  .cost .sub b { font-family: "Anton", Impact, sans-serif; font-weight: 400; font-size: var(--t-lead); color: var(--red); line-height: 1; }
  .cost .kind { font: inherit; font-weight: 700; color: var(--red); background: none; border: 0; padding: 0 2px; cursor: pointer;
    text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }
  .cost .kind[aria-pressed="true"] { background: var(--red); color: #fff; text-decoration: none; border-radius: 2px; }
  .cost .x { position: absolute; top: 18px; right: 0; width: 40px; height: 40px; border: 1px solid var(--rule); background: none; color: var(--ink);
    font-size: 18px; line-height: 1; cursor: pointer; border-radius: 3px; }
  .cost .x:hover, .cost .x:focus-visible { border-color: var(--ink); }
  @media (max-width: 520px) { .cost { padding-right: 44px; } .cost .big { max-width: none; } }
  @supports (text-box: trim-both cap alphabetic) {   /* center the swatch, number and label on their capital letters, not their line boxes */
    .path-btn { align-items: center; }
    .path-btn b, .path-btn .lb { text-box: trim-both cap alphabetic; }
  }   /* nothing in this choice under the current filters */

  .controls {
    position: sticky; top: env(safe-area-inset-top, 0px); z-index: 5;
    background: var(--ground);
    display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
    padding-block: 12px; border-block: 1px solid var(--rule); margin-bottom: 18px;
  }
  /* The bar's ground reaches 20 px past the content on both sides, so a hovered square (which grows 3%) can't be seen peeking out beside the bar as it scrolls beneath it. The two rules stay at the content width. */
  .controls::before { content: ""; position: absolute; inset: 0 -20px; z-index: -1; background: var(--ground); pointer-events: none; }
  .areas { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 520px; }
  .area {
    border: 0; background: var(--chip); color: var(--ink); cursor: pointer;
    font: inherit; font-size: var(--t-label); font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
    padding: 7px 11px; border-radius: 2px;
  }
  .area[aria-pressed="true"] { background: var(--red); color: var(--on-red); }
  #q {
    flex: 0 1 380px; min-width: 0; width: 100%;
    font: inherit; font-size: var(--t-body); color: var(--ink); background: var(--panel);
    border: 1.5px solid var(--rule); border-radius: 3px; padding: 8px 12px;
  }
  .fbtn { display: inline-flex; gap: 6px; align-items: center; flex: none; font: inherit; font-size: var(--t-ui); font-weight: 600; color: var(--ink); background: var(--panel); border: 1.5px solid var(--rule); border-radius: 3px; padding: 8px 12px; cursor: pointer; }
  .fbtn[aria-expanded="true"], .fbtn.on { border-color: var(--ink); }
  #mebtn { background: var(--red); border-color: var(--red); color: var(--on-red); }
  #mebtn:hover { background: var(--red-deep); border-color: var(--red-deep); }
  #mebtn.on { border-color: var(--ink); }
  .fchips, .fpanel { display: none; }
  .fchips:not([hidden]) { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
  .fchip { font: inherit; font-size: var(--t-label); font-weight: 600; color: var(--on-red); background: var(--red); border: 0; border-radius: 2px; padding: 6px 10px; cursor: pointer; }
  .fpanel:not([hidden]) { display: grid; gap: 14px; width: 100%; padding-block: 4px 2px; max-height: var(--room, 60vh); overflow-y: auto; overscroll-behavior: contain; }
  .tally { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); color: var(--ink-soft); width: 100%; display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
  .tally strong { color: var(--red); font-weight: 500; }
  .sort { font: inherit; color: var(--ink); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

  .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; }
  .sq {
    /* Squares always use the dark palette, in light mode too, so they match their images on social media. */
    --ink: #E9ECF5; --ink-soft: #9AA2BD; --rule: #252C44; --red: #C4141F; --red-deep: #8E0C15; --chip: #1A2034; --panel: #141A2C;
    position: relative; aspect-ratio: 1; max-width: 100%; text-decoration: none;
    background: var(--red); color: var(--on-red);
    border: 0; border-radius: 0; cursor: pointer; text-align: left;
    padding: 14px; display: flex; flex-direction: column; justify-content: space-between; gap: 8px;
    font: inherit; overflow: hidden;
    transition: background .15s ease, transform .15s ease;
    user-select: none; -webkit-user-select: none;
  }
  .sq:hover { background: var(--red-deep); }
  @media (hover: hover) {
    .sq:hover { transform: scale(1.03); box-shadow: 0 12px 28px rgba(0,0,0,.35); z-index: 2; }
    .sq.courts:hover { box-shadow: inset 0 0 0 3px var(--red), 0 12px 28px rgba(0,0,0,.35); }
  }
  .sq:active { transform: scale(.97); box-shadow: none; }
  .sq.courts:active { box-shadow: inset 0 0 0 3px var(--red); }
  .morph { position: fixed; z-index: 2147483647; pointer-events: none; overflow: hidden; }
  .morph.m-panel { background: var(--panel); }
  .morph.m-head { background: var(--red); }
  .morph .skin { position: absolute; inset: 0; }
  .morph .skin.partial { background: var(--red) repeating-linear-gradient(135deg, rgba(255,255,255,.13) 0 10px, transparent 10px 20px); }
  .morph .skin.courts { background: var(--panel); box-shadow: inset 0 0 0 3px var(--red); }
  .morph .skin.reversed { background: var(--chip); }
  .morph .skin.proposed { background: var(--panel); border: 3px dashed var(--red); }
  dialog.hiding { background: transparent; box-shadow: none; }
  dialog.hiding .dlg-top { background: transparent; }
  .dlg-top > *, .dlg-body > * { transition: opacity .14s ease, transform .14s ease; }
  dialog.hiding .dlg-top > *, dialog.hiding .dlg-body > *, dialog.fading .dlg-top > *, dialog.fading .dlg-body > * { opacity: 0; transform: translateY(6px); }
  .sq:focus-visible, button:focus-visible, #q:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
  .sq .meta { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .04em; color: var(--on-red-soft); text-transform: uppercase; line-height: 1.35; }
  .sq .ttl { font-family: "Anton", Impact, "Arial Narrow", sans-serif; font-weight: 400; font-size: var(--t-lead); line-height: 1.05; text-transform: uppercase; text-wrap: balance; }
  .sq .path { font-size: var(--t-label); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; border-top: 1px solid rgba(255,255,255,.35); padding-top: 7px; }
  .sq .st { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); font-weight: 500; letter-spacing: .06em; text-transform: uppercase; }
  .sq .foot { display: grid; gap: 4px; border-top: 1px solid rgba(255,255,255,.35); padding-top: 7px; }
  .sq .foot .path { border: 0; padding: 0; }

  /* One badge per square for the single most notable fact about that member (fixed priority:
     flagged trade > donor/committee overlap > top fundraiser > party-line extreme), plus the
     plain yes/no election badge -- both stack in one corner so neither ever sits over the
     card's own text (state/district, name). */
  .sq .badges {
    position: absolute; top: 10px; right: 10px; z-index: 1;
    display: flex; flex-direction: column; align-items: flex-end; gap: 6px; max-width: 60%;
  }
  .sq .badge {
    display: flex; align-items: center; gap: 4px;
    font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: 9.5px; font-weight: 700;
    letter-spacing: .05em; text-transform: uppercase;
    padding: 4px 7px 4px 6px; border-radius: 3px;
    background: rgba(11,15,28,.82);
    line-height: 1.25; max-width: 100%;
    box-shadow: 0 0 0 1px rgba(255,255,255,.14);
  }
  .sq .badge .dot { width: 6px; height: 6px; border-radius: 50%; flex: none; margin-top: 1px; }
  .sq .badge.trade { color: #FF6B6B; }
  .sq .badge.trade .dot { background: #FF6B6B; }
  .sq .badge.overlap { color: #D98C12; }
  .sq .badge.overlap .dot { background: #D98C12; }
  .sq .badge.fundraiser { color: #E9ECF5; }
  .sq .badge.fundraiser .dot { background: #E9ECF5; }
  .sq .badge.breaks { color: #7FD4C8; }
  .sq .badge.breaks .dot { background: #7FD4C8; }
  .sq .badge.loyal { color: #B7A8F0; }
  .sq .badge.loyal .dot { background: #B7A8F0; }
  .sq .badge.election { color: #FFD166; }
  .sq .badge.election .dot { background: #FFD166; }
  .sq .badge.not-running { color: #9AA2BD; }
  .sq .badge.not-running .dot { background: #9AA2BD; }
  .sq .badge.reelected { color: #6FCF7F; }
  .sq .badge.reelected .dot { background: #6FCF7F; }
  .sq .badge.lost { color: #FF8C5A; }
  .sq .badge.lost .dot { background: #FF8C5A; }
  .sq.partial { background-image: repeating-linear-gradient(135deg, rgba(255,255,255,.13) 0 10px, transparent 10px 20px); }
  .sq.courts { background: var(--panel); color: var(--ink); box-shadow: inset 0 0 0 3px var(--red); }
  .sq.courts:hover { background: var(--chip); }
  .sq.courts .meta { color: var(--ink-soft); }
  .sq.courts .st { color: var(--red); }
  .sq.courts .foot { border-top-color: var(--rule); }
  .sq.proposed { box-sizing: border-box; background: var(--panel); color: var(--ink); border: 3px dashed var(--red); }
  .sq.proposed .meta { color: var(--ink-soft); }
  .sq.proposed .st { color: var(--red); }
  .sq.proposed .foot { border-top-color: var(--rule); }
  .sq.proposed:hover { background: var(--chip); }
  .sq.reversed { background: var(--chip); color: var(--ink-soft); }
  .sq.reversed:hover { background: var(--rule); }
  .sq.reversed .meta { color: var(--ink-soft); }
  .sq.reversed .ttl { text-decoration: line-through; text-decoration-thickness: 2px; }
  .sq.reversed .foot { border-top-color: var(--rule); }
  .sq.party-d { --red: #2552D9; --red-deep: #1B3FAE; }
  .sq.party-i { --red: #5B6472; --red-deep: #454C57; }
  .morph.m-head.party-d { background: #2552D9; }
  .morph.m-head.party-i { background: #5B6472; }
  /* Unlike the item dialog (#dlg), which always shows the same red header once fully open
     regardless of status -- the skin color is only a transient morph-animation effect there --
     the senator panel's whole point is party identification, so its header stays party-colored
     for as long as it's open, not just during the open/close animation. */
  #senate-member.party-d .dlg-top { background: #2552D9; }
  #senate-member.party-i .dlg-top { background: #5B6472; }
  .navgroup { display: flex; gap: 20px; align-items: baseline; }
  .sen-meta { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; flex-wrap: wrap; }
  .sen-meta .party-tag { font-weight: 700; }
  /* Tenure moves into the red header itself (set by JS on #sen-tenure) instead of being its own
     section below -- it's a single fact, not something anyone needs to expand. */
  .sen-tenure-line { font-size: var(--t-ui); color: var(--on-red-soft); }

  /* Every section below is a <details>: closed by default, showing only its label and one
     headline stat (right-justified, next to the +/- marker) until clicked. A lightbox with six
     sections of donor tables, vote lists, and trade histories all expanded at once was a wall of
     text before you'd read a word of it -- this makes the modal land as a short list of facts,
     and reading further is something the visitor chooses per section, not something imposed on
     them. "Key votes" gets no special default: it opens closed like everything else, for the
     same reason. */
  .sen-section { border-top: 1px solid var(--rule); margin-top: 14px; padding-top: 0; }
  .sen-section[hidden] { display: none; }
  .sen-section:first-of-type { border-top: 0; margin-top: 0; }
  .sen-section > summary { list-style: none; cursor: pointer; padding: 14px 0; display: flex; align-items: center; gap: 12px; }
  .sen-section > summary::-webkit-details-marker { display: none; }
  /* The label takes all the leftover space so the stat and the marker after it sit flush right,
     next to each other, instead of floating at an arbitrary point in the row. */
  .sen-section > summary > h3 { flex: 1 1 auto; }
  .sen-section > summary::after { content: "+"; font-family: "Anton", Impact, sans-serif; font-size: 18px;
    color: var(--ink-soft); flex: none; width: 16px; text-align: center; }
  .sen-section[open] > summary::after { content: "\2212"; }
  .sen-section-body { display: grid; gap: 6px; padding-bottom: 14px; }
  .sen-section h3 { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--red); margin: 0; }
  .sen-stat { font-family: "Anton", Impact, sans-serif; font-weight: 400; font-size: var(--t-lead); color: var(--red); line-height: 1; }
  /* The collapsed-row stat, sized down from .sen-stat so it reads as a summary number, not a
     second headline competing with the section label next to it. */
  .sen-stat-sm { font-family: "Anton", Impact, sans-serif; font-weight: 400; font-size: 18px; color: var(--red); line-height: 1; flex: none; }
  .sen-stat-sm.quiet { font-family: inherit; font-size: var(--t-ui); font-weight: 600; color: var(--ink-soft); }

  /* Key votes: one card per roll call, the vote tied directly to the item(s) it's tracked as on
     the main site. */
  .kv-list { display: grid; gap: 12px; }
  .kv-card { border-left: 4px solid var(--red); background: var(--chip); padding: 12px 14px; display: grid; gap: 7px; }
  .kv-card.nay { border-left-color: var(--good); }
  .kv-card.other { border-left-color: var(--ink-soft); }
  .kv-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; flex-wrap: wrap; }
  .kv-bill { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); font-weight: 700; letter-spacing: .04em; color: var(--ink-soft); text-transform: uppercase; }
  .kv-verdict { font-family: "Anton", Impact, sans-serif; font-size: 20px; line-height: 1; color: var(--red); flex: none; }
  .kv-verdict.nay { color: var(--good); }
  .kv-verdict.other { color: var(--ink-soft); }
  .kv-tally { font-size: var(--t-label); color: var(--ink-soft); }
  .kv-desc { font-size: var(--t-ui); line-height: 1.5; margin: 0; }
  .kv-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
  .kv-chip { font-size: var(--t-label); font-weight: 600; background: var(--panel); color: var(--ink);
    border: 1px solid var(--rule); border-radius: 2px; padding: 5px 9px; text-decoration: none; }
  .kv-chip:hover { border-color: var(--red); color: var(--red); }

  /* Earmarks: a footnote, not a feature -- a normal part of the job, not a conflict, so it
     doesn't get a section header, a collapsible body, or equal visual weight with the sections
     above. One line, with the existing itemized list still reachable via "Full list" inline. */
  .sen-earmark-line { font-size: var(--t-ui); color: var(--ink-soft); line-height: 1.5; border-top: 1px solid var(--rule); padding-top: 14px; margin-top: 14px; }
  .sen-earmark-line strong { color: var(--ink); }
  .sen-earmark-line details { display: inline; }
  .sen-earmark-line summary { display: inline; cursor: pointer; color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
  .sen-earmark-line .sen-earmarks { display: grid; gap: 6px; font-size: var(--t-label); margin-top: 10px; }
  .sen-note { font-size: var(--t-label); color: var(--ink-soft); }
  .sen-donors { display: grid; gap: 4px; font-size: var(--t-label); }
  .sen-donors div { display: flex; justify-content: space-between; gap: 10px; }
  .sen-donors .amt { font-weight: 700; white-space: nowrap; }
  .sen-trades { display: grid; gap: 12px; font-size: var(--t-label); }
  .sen-trades > div { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
  .sen-trades .amt { font-weight: 700; white-space: nowrap; flex: none; }
  .sen-trades .flag { display: block; color: var(--red); font-weight: 700; margin-top: 3px; }
  .sen-trades .subject { display: block; color: var(--ink-soft); margin-top: 3px; font-style: italic; }
  .sen-sectors { display: grid; gap: 6px; font-size: var(--t-label); }
  .sen-sectors .bar-row { display: flex; justify-content: space-between; gap: 10px; }
  .sen-sectors .amt { font-weight: 700; white-space: nowrap; }
  .sen-earmarks { display: grid; gap: 6px; font-size: var(--t-label); }
  .sen-earmarks > div { display: flex; justify-content: space-between; gap: 10px; }
  .sen-earmarks .amt { font-weight: 700; white-space: nowrap; flex: none; }
  .sen-portrait { width: 96px; aspect-ratio: 3/4; object-fit: cover; float: right; margin: 0 0 10px 14px; }
  .new { position: absolute; top: 10px; right: 10px; background: var(--on-red); color: var(--red); font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); font-weight: 500; letter-spacing: .1em; padding: 2px 6px; }
  .sq.courts .new, .sq.reversed .new { background: var(--red); color: var(--on-red); }
  .sq:has(.new) .meta { padding-right: 76px; }   /* the date never runs under the NEW or UPDATE badge */
  .empty { padding: 40px 0; color: var(--ink-soft); }
  .grid-div { grid-column: 1 / -1; margin: 18px 0 2px; font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--red); border-top: 1px solid var(--rule); padding-top: 14px; }

  dialog {
    width: min(620px, calc(100% - 32px)); max-height: calc(100% - 48px);
    border: 0; border-radius: 0; padding: 0; background: var(--panel); color: var(--ink);
    box-shadow: 0 30px 80px rgba(0,0,0,.35);
  }
  dialog::backdrop { background: rgba(8,10,20,.6); }
  .dlg-top { background: var(--red); color: var(--on-red); padding: 22px 24px 20px; display: grid; gap: 8px; user-select: none; -webkit-user-select: none; }
  .dlg-top .meta { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); color: var(--on-red-soft); text-transform: uppercase; letter-spacing: .05em; }
  .dlg-top h2 { font-family: "Anton", Impact, sans-serif; font-weight: 400; font-size: var(--t-statement); line-height: 1; margin: 0; text-transform: uppercase; text-wrap: balance; }
  .dlg-body { padding: 20px 24px 24px; display: grid; gap: 16px; }
  .dlg-body p { margin: 0; max-width: 62ch; }
  .status { background: var(--chip); padding: 10px 14px; display: grid; gap: 2px; }
  .status .lbl { font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
  .status strong { font-size: var(--t-body); }
  .status a { font-size: var(--t-ui); font-weight: 700; color: var(--ink); text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 3px; margin-top: 4px; justify-self: start; }
  /* A square that has changed tells its story as dated steps, newest last and in red */
  .tl { list-style: none; margin: 0; padding: 0 0 0 18px; border-left: 2px solid var(--rule); }
  .tl li { position: relative; }
  .tl li + li { margin-top: 14px; }      /* block layout, not a grid with a gap: a row's height and margin can then animate to zero in every browser (Safari kept a 14 px grid gap and jumped when the list finished unfurling) */
  .tl li::before { content: ""; position: absolute; left: -25px; top: 5px; width: 12px; height: 12px; border-radius: 50%; background: var(--ink-soft); }
  .tl li.now::before { background: var(--red); }
  .tl .d { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); display: block; }
  .tl li.now .d { color: var(--red); }
  .tl li:focus { outline: none; }          /* focus is only parked on the first revealed step so a keyboard user keeps their place */
  .tl li.tl-more::before { background: var(--bg); box-shadow: inset 0 0 0 2px var(--ink-soft); }
  .tl .tl-toggle { font: inherit; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .06em; text-transform: uppercase; color: var(--ink); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 3px; }
  .tl a { font-size: var(--t-ui); font-weight: 700; color: var(--ink); text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 3px; white-space: nowrap; }
  .fix { border-left: 4px solid var(--red); padding: 4px 0 4px 14px; }
  .fix .lbl { font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--red); display: block; margin-bottom: 2px; }
  .dlg-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
  .btn { font: inherit; font-size: var(--t-ui); font-weight: 700; padding: 10px 14px; border-radius: 2px; cursor: pointer; border: 1.5px solid var(--ink); background: transparent; color: var(--ink); text-decoration: none; }
  .btn.primary { background: var(--red); border-color: var(--red); color: var(--on-red); }
  .btn.close { margin-left: auto; }

  footer strong { color: var(--ink); }
  /* Locked on scroll: once the page scrolls enough that .controls (also sticky, see below)
     reaches the top, this nav row is already pinned there too (it starts sticking much
     earlier, since .topline's own natural position is near the very top of the page) -- so
     the two end up sharing the same top edge, nav lined up with the Filter button's own row.
     Nothing below .topline moves or reserves space for it; it isn't removed from flow, it's
     just pinned once its own scroll point is reached. z-index keeps it above .controls'
     opaque background at that shared position. */
  .topline { display: flex; justify-content: flex-end; align-items: baseline; gap: 28px; position: sticky; top: 15px; z-index: 7; }
  .navlink { font: inherit; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; color: var(--ink); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 4px; white-space: nowrap; }
  #about-title:focus, #privacy-title:focus, #dlg-title:focus, #me-title:focus, #sen-title:focus, #kv-item-title:focus, #cand-title:focus { outline: none; }
  .about-body h3 { font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--red); margin: 0 0 4px; }
  .about-body section { display: grid; gap: 2px; }
  .about-body ul { margin: 4px 0 0; padding-left: 18px; display: grid; gap: 2px; }
  .toast { font-size: var(--t-ui); color: var(--ink-soft); }
  #me-title:focus { outline: none; }
  #me-groups.picks { margin: 0; gap: 8px; }
  #me-groups.picks button { font-size: var(--t-ui); padding: 8px 12px; text-align: left; }
  /* the Show button stays in view at the bottom of the lightbox, however long the list */
  #me .dlg-actions { position: sticky; bottom: 0; background: var(--panel); padding-block: 12px; margin-bottom: -12px; border-top: 1px solid var(--rule); }
  @media (max-width: 520px) { #me-groups.picks { gap: 6px; } #me-groups.picks button { padding: 7px 10px; } }
  .me-all { display: flex; gap: 8px; align-items: flex-start; font-size: var(--t-ui); }
  .me-all input { margin-top: 3px; accent-color: var(--red); }
  #me .note { font-size: var(--t-ui); color: var(--ink-soft); }
  .cg { border-top: 1px solid var(--rule); padding-top: 16px; display: grid; gap: 12px; }
  .cg h3 { font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--red); margin: 0; }
  .cg form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
  .cg label { font-size: var(--t-ui); font-weight: 600; }
  .cg input { font: inherit; font-size: var(--t-body); width: 7.5em; padding: 8px 10px; color: var(--ink); background: var(--ground); border: 1.5px solid var(--rule); border-radius: 3px; font-variant-numeric: tabular-nums; }
  .cg input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
  .mems { display: grid; gap: 8px; }
  .mem { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 6px 12px; padding: 10px 12px; background: var(--chip); border-radius: 3px; }
  .mem b { font-size: var(--t-ui); }
  .mem .who span { display: block; font-size: var(--t-label); color: var(--ink-soft); }
  .mem .acts { display: flex; gap: 8px; flex-wrap: wrap; }
  .mem a { font-size: var(--t-ui); font-weight: 700; color: var(--ink); text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 3px; }
  .script { background: var(--ground); border-left: 4px solid var(--red); padding: 10px 14px; font-size: var(--t-ui); }
  .script .lbl { font-size: var(--t-label); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); display: block; margin-bottom: 4px; }
  .cg .note { font-size: var(--t-ui); color: var(--ink-soft); margin: 0; }
  .picks { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
  .picks button { font: inherit; font-size: var(--t-ui); font-weight: 700; padding: 5px 9px; border-radius: 2px; border: 1.5px solid var(--rule); background: transparent; color: var(--ink); cursor: pointer; }
  .picks button[aria-pressed="true"] { background: var(--red); border-color: var(--red); color: var(--on-red); }
  .cg .note a { color: var(--ink); }
  /* The nav row's own current-page marker: every item keeps the same weight and case, so the
     red underline (the site's one "this is active/clickable" signal) is what tells you which
     of Home/House/Senate you're on, rather than that item silently vanishing from the row. */
  .navgroup .navlink { text-decoration: none; }
  .navgroup .navlink:hover, .navgroup .navlink:focus-visible { text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 4px; }
  .navgroup .navlink[aria-current="page"] { text-decoration: underline; text-decoration-color: var(--red); text-decoration-thickness: 2px; text-underline-offset: 4px; cursor: default; }
  /* Mobile-only hamburger, shared by every page (homepage, every square's /s/ page, /house/,
     /senate/): collapses the nav row behind a toggle once the full Home/House/Senate/About row
     stops fitting. Desktop is untouched -- .mnav-toggle stays display:none and .navgroup stays
     the plain inline row it always was. */
  .mnav-toggle { display: none; align-items: center; gap: 8px; font: inherit; font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; color: var(--ink); background: none; border: 0; padding: 8px 4px; cursor: pointer; }
  .mnav-bars, .mnav-bars::before, .mnav-bars::after { content: ""; display: block; width: 18px; height: 2px; background: var(--ink); border-radius: 1px; }
  .mnav-bars { position: relative; }
  .mnav-bars::before { position: absolute; left: 0; top: -6px; }
  .mnav-bars::after { position: absolute; left: 0; top: 6px; }

  footer { margin-top: 40px; padding-top: 18px; border-top: 1px solid var(--rule); color: var(--ink-soft); font-size: var(--t-ui); display: grid; gap: 6px; max-width: 80ch; }
  footer a { color: inherit; text-decoration: underline; text-decoration-color: var(--red); text-underline-offset: 3px; white-space: nowrap; }
  footer .footrow { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 10px; }
  footer .social { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; }
  footer .social span { font-family: "IBM Plex Mono", ui-monospace, monospace; font-size: var(--t-label); letter-spacing: .12em; text-transform: uppercase; margin-right: 4px; }
  footer .social a { display: inline-flex; color: var(--ink); padding: 4px; margin: -4px; }
  footer .social svg { width: 20px; height: 20px; fill: currentColor; }
  footer .social a:hover, footer .social a:focus-visible { color: var(--red); }

  /* The hamburger breakpoint is about the nav row, not screen size: below this width the right-
     aligned Home/House/Senate/Candidates/Election Night/About row runs into the lockup's own
     text (measured directly with real glyph extents, not box edges -- clearance is still
     negative at 1300px and only crosses zero around 1310-1320, in the messy zone where .wrap
     is still growing toward its own 1320px cap; past that cap clearance plateaus at a stable
     +60px). So this is set to .wrap's own max-width + its 40px of side padding (1360px) rather
     than to a point inside that transition -- once .wrap has fully capped out, the layout is in
     its stable zone, not the kink. Raised from 1150 when Election Night was added to the row,
     which cost it real width, so everything from here down gets the same hamburger-shares-the-
     lockup's-row treatment, all the way to phone widths. The narrower @media (max-width: 520px)
     block below layers phone-only tweaks (tighter grid, side padding) on top of this; it
     doesn't need its own copy of the nav rules. */
  @media (max-width: 1360px) {
    /* The hamburger shares the lockup's own row instead of sitting in a row of its own above
       it, and the logo's own font-size formula below gives up a little width on the right so
       the two never collide. .topline stays in normal flow (not position:absolute) rather than
       overlaying the lockup, so it can lock on scroll the same way the desktop nav row does --
       its own row is short, so header's negative margin pulls the lockup up to share it
       visually instead of sitting in a stacked row below it. Once scrolled, .topline (sticky,
       and starting life near the very top of the page so it engages almost immediately) ends
       up level with .controls' own Filter row once that also reaches the top. */
    .wrap { position: relative; padding-top: 18px; }
    h1 { font-size: calc((100vw - 40px - 64px) / 9.25); }
    header { margin-top: -24px; }
    .topline { position: sticky; top: 13px; z-index: 6; }
    .mnav-toggle { display: flex; padding: 10px 6px; }
    .mnav-toggle .mnav-label { display: none; }
    .navgroup { display: none; position: absolute; top: 100%; right: 0; left: auto; flex-direction: column; align-items: stretch; gap: 0; min-width: 220px; background: var(--panel); border: 1px solid var(--rule); border-radius: 4px; padding: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.25); }
    .navgroup.open { display: flex; }
    .navgroup .navlink { display: block; width: 100%; text-align: left; padding: 12px 10px; margin: 0; }
  }
  @media (max-width: 520px) {
    #q { flex: 1 1 100%; }
    #mebtn { flex: 1 1 auto; justify-content: center; }
    .wrap { padding-inline: 16px; padding-block-end: 48px; }
    .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .sq { padding: 10px; }
    .sq .ttl { }
    .sq .meta, .sq .path { }
    .lede { margin: 14px 0 20px; }
    header { gap: 10px; margin-bottom: 14px; }
    .statuses { gap: 6px; }
    .statuses .path-btn, .paths .path-btn { padding: 6px 10px; }
    .paths { gap: 6px; }
    .controls { gap: 8px; padding-block: 10px; }
  }
  @media (prefers-reduced-motion: reduce) { .sq { transition: none; } .sq:hover, .sq:active { transform: none; } .dlg-top > *, .dlg-body > * { transition: none; } }
