/* theoelections (IDENTITY.md 4). One family, Commissioner (the owner's choice,
   2026-10-10, in place of Author), in two weights, 400 and 600, from one
   variable file. Paper under everything, the ink bar on top, colour only where
   a datum is. Radius 0, no shadow, no transition, no text-transform: the
   page's casing is decided in present/case.js.
   The face is set at 94% of its drawn size: at 100% it is 15 to 20% wider than
   the face the page's fixed columns were cut for (names 76px, shares and votes
   64px, chips 36px); at 94% every one of them fits and the lowercase still
   stands 6% taller than Author's did. Its weights are declared 400 to 600, so
   a bold the page never asked for (a b, a th) is the 600 and no heavier. Its
   figures are lining and proportional; the face has no tabular set. */
@font-face{font-family:"Commissioner";src:url(../fonts/commissioner.woff2) format("woff2");font-weight:400 600;font-style:normal;font-display:block;
           size-adjust:94%;unicode-range:U+0000-00FF,U+2013,U+2019,U+2039-203A,U+2212,U+00B7}

/* the tokens of 4.12 */
:root{
  color-scheme:light;
  --paper:#DCDEDB; --ink:#16171A; --ink2:#2F312F; --muted:#555855;
  --grn:#22B405; --hair:#B9BCB8; --tie:#A3A6A2; --pooled:#8A8D89; --leader:#8A8D89; --white:#FFFFFF; --dark-ground:#141118;
  --face:"Commissioner", sans-serif;
  --fs-title:40px; --fs-section:22px; --fs-fact:17px; --fs-name:18px; --fs-share:18px; --fs-votes:14px;
  --fs-chip:12px; --fs-edge:13px; --fs-index:15px; --fs-crumb:14px; --fs-label:13px; --fs-foot:13.5px; --fs-wordmark:22px;
  --lh-title:1.05; --lh-fact:1.35; --lh-index:1.6; --lh-foot:1.45;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px;
  --bar:112px; --tabs:36px; --panel-width:480px; --pad:24px;
  --stamp-h:24px; --stamp-pad:6px;
}
*{box-sizing:border-box}
html,body{height:100%;margin:0}
body{background:var(--paper);color:var(--ink);font:400 15px/1.45 var(--face);font-feature-settings:"lnum" 1;
     display:grid;grid-template-rows:var(--bar) var(--tabs) minmax(0,1fr);overflow:hidden}
button,input{font:inherit;font-feature-settings:"lnum" 1;color:inherit;border-radius:0;transition:none;margin:0}
button{cursor:pointer}
:where(button,input,a[href],[tabindex]):focus-visible{outline:2px solid var(--ink);outline-offset:2px}
h1,h2,p{margin:0}

/* ---- the bar: paper, the owner's logo at the centre, find at the right ---- */
.bar{display:flex;align-items:center;gap:var(--s5);background:var(--paper);color:var(--ink);padding:0 var(--pad);min-width:0;position:relative;z-index:8}
/* the owner's logo in the bar's centre, find at the right */
.brand{position:absolute;left:50%;transform:translateX(-50%);display:inline-flex;align-items:baseline;flex:none;color:var(--ink);text-decoration:none;font:600 var(--fs-wordmark)/1 var(--face);letter-spacing:-0.01em}
.brand .logo{display:block;height:96px;width:auto}
.mk{display:block;width:1.68em;height:.44em;fill:currentColor;flex:none}
.brand .mk{margin-right:.30em}
.finder{margin-left:auto;display:flex;align-items:center;gap:var(--s3);min-width:0}
#find-word{font:400 15px/1 var(--face);color:var(--ink);cursor:text}
.find{position:relative;width:280px}
#find{display:block;width:100%;height:30px;padding:0 8px;background:var(--paper);color:var(--ink);border:1px solid var(--ink);
      font:400 15px/28px var(--face);-webkit-appearance:none;appearance:none}
#find::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
#find::placeholder{color:var(--muted);opacity:1}
#find:focus::placeholder{color:transparent}
#find:focus-visible{outline-color:var(--ink)}
/* the tabs: one row of index words on the ink under the bar, the open one on a paper stamp;
   a phone slides the row sideways inside itself */
.tabs{display:flex;align-items:flex-start;gap:6px;height:var(--tabs);background:var(--paper);border-bottom:2px solid var(--ink);padding:0 var(--pad);
      margin:-1px 0 0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;min-width:0}
.tabs::-webkit-scrollbar{display:none}
.tabs a{flex:none;height:var(--stamp-h);padding:0 var(--stamp-pad);color:var(--ink);text-decoration:none;
        font:400 var(--fs-index)/var(--stamp-h) var(--face);white-space:nowrap}
/* centred while the row fits; a row wider than the screen starts at the left and slides */
.tabs a:first-child{margin-left:auto}
.tabs a:last-child{margin-right:auto}
.tabs a[aria-current="page"]{background:var(--ink);color:var(--paper)}
.tabs a:focus-visible{outline-color:var(--ink);outline-offset:-2px}
.tabs a[aria-current="page"]:focus-visible{outline-color:var(--paper);outline-offset:-4px}
/* a screen 900 wide and up: the tabs sit in the bar, left of the logo, as many lines as they need;
   the bar keeps the ink rule under it */
@media (min-width:900px){
  body{grid-template-rows:var(--bar) minmax(0,1fr)}
  .bar{height:var(--bar);border-bottom:2px solid var(--ink)}
  .tabs{position:absolute;top:0;left:0;z-index:9;width:calc(50% - 92px - var(--s5));height:var(--bar);padding:0 0 0 calc(var(--pad) - var(--stamp-pad));
        flex-wrap:wrap;align-content:center;gap:var(--s1) 6px;border-bottom:0;background:none;overflow:visible}
  .tabs a:first-child{margin-left:0}
  .tabs a:last-child{margin-right:0}
  /* Commissioner stands taller than Author did: 13.5px here reads as the 15px did */
  .tabs a{font-size:13.5px}
}
/* 1440 and up: every tab on one row beside the logo; a narrower bar keeps two
   rows, so the last tab never runs under the logo */
@media (min-width:1440px){
  .tabs{flex-wrap:nowrap;align-items:center;gap:2px}
  .tabs a{padding:0 4px}
}

/* a page that is not the archive: a print sheet on paper. A heavy lowercase title, the
   fact line, then the sections as the sheet's index: the name heavy, its state at the right */
body.page{display:block;overflow:auto;height:auto;min-height:100%}
.sheet{padding:var(--s7) var(--pad) var(--s7);max-width:1440px}
.sheet .big-logo{display:block;width:192px;height:auto;margin:0 0 var(--s5)}
.sheet-title{font:600 64px/1 var(--face);letter-spacing:-0.02em}
.sheet-facts{margin-top:var(--s3);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink2)}
.toc{list-style:none;margin:var(--s7) 0 0;padding:0}
.toc li{padding:var(--s2) 0}
.toc a{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:var(--s1) var(--s5);color:var(--ink);text-decoration:none}
.toc-name{font:600 var(--fs-title)/1.1 var(--face);letter-spacing:-0.01em}
.toc-st{font:400 var(--fs-fact)/var(--stamp-h) var(--face);color:var(--ink2);white-space:nowrap}
.toc-st.on{background:var(--ink);color:var(--paper);padding:0 var(--stamp-pad)}
.toc-pr{margin-top:var(--s1);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink2)}
.toc .open{padding-bottom:var(--s4)}
.sheet .big-logo + .sheet-title + .sheet-facts + .toc{margin-top:var(--s7)}
.sheet .big-logo ~ .toc .toc-name{font-size:var(--fs-section)}
.sheet .big-logo ~ .toc li{padding:var(--s1) 0}

/* national politics: the forecast. Each row a US map on the left, kept small, and the rich side
   on the right: both parties' numbers, the margin, the chances and the year's charts (src/national.js) */
.nat{padding:var(--s5) var(--pad) var(--s7)}
.nat-title{font:600 52px/1 var(--face);letter-spacing:-0.02em}
.nat-lede{margin-top:var(--s2);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink2)}
.nat-lede + :is(.nat-mode,.ftx-mode){margin-top:var(--s4)}
/* read by a screen reader, not shown */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
/* a page that draws by script says so when its scripts never arrive (tools/pages.mjs WATCH) */
.load-fail{margin:0 0 var(--s4);font:400 var(--fs-fact)/1.4 var(--face);color:var(--ink)}
.noscript{margin-top:var(--s3);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink2)}
.nat-row{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:var(--s5) var(--s7);align-items:center;padding:var(--s6) 0;border-top:2px solid var(--ink)}
.nat-row:first-of-type{border-top:0;padding-top:var(--s3)}
/* each map's box is kept before its map arrives, and a row and the footnotes are
   shown once the page's numbers are in them, so nothing a reader sees moves */
.nat-map{aspect-ratio:975 / 610}
#nat-house .nat-map{aspect-ratio:1900 / 1180}
.nat:not([data-ready]) .nat-row{visibility:hidden}
.nat:not([data-ready]) .nat-notes{display:none}
.nat-map svg{display:block;width:100%;height:auto}
.nat-map path[data-slip]{cursor:default}
.nat-mode{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) 6px;margin-left:calc(-1 * var(--stamp-pad));min-height:var(--stamp-h)}
.nat-mode .iw{position:relative;height:var(--stamp-h);padding:0 var(--stamp-pad);background:none;border:0;color:var(--ink2);font:400 var(--fs-index)/var(--stamp-h) var(--face);cursor:pointer}
.nat-mode .iw.on{background:var(--ink);color:var(--paper)}
.nat-key{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s3);margin-left:var(--s5)}
.nat-key .nk{display:inline-flex;align-items:center;gap:5px;font:400 var(--fs-label)/1.2 var(--face);color:var(--ink2);white-space:nowrap}
.nat-key .nk i{display:block;width:16px;height:12px}
.nat-frame{fill:none;stroke:var(--ink);stroke-width:1;vector-effect:non-scaling-stroke;pointer-events:none}
.nat-map svg[data-office="house"] path[data-slip]{stroke:var(--paper);stroke-width:.4;stroke-opacity:.7;vector-effect:non-scaling-stroke}
.nat-mesh{fill:none;stroke:var(--paper);stroke-opacity:.7;stroke-width:1;vector-effect:non-scaling-stroke;pointer-events:none}
.nat-pair{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--s4) var(--s7)}
.nat-sub{margin-top:var(--s4);font:600 var(--fs-name)/1.2 var(--face);color:var(--ink)}
.nat-sub span{font-weight:400;color:var(--ink2)}
.nat-gb .nat-t{margin-top:var(--s2)}
.nat-t.gb td.sv{font-size:26px}
.nat-h{font:600 var(--fs-title)/1.05 var(--face);letter-spacing:-0.01em}
.nat-f{margin-top:var(--s2);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink2)}
.nat-t{margin-top:var(--s4);border-collapse:collapse;font-variant-numeric:lining-nums tabular-nums}
.nat-t th{font:400 var(--fs-label)/1.2 var(--face);color:var(--muted);text-align:right;padding:0 0 var(--s2) var(--s5);white-space:nowrap}
.nat-t td{padding:var(--s1) 0 var(--s1) var(--s5);text-align:right;vertical-align:middle;color:var(--ink)}
.nat-t td.t{padding:0;width:4px}
.nat-t td.t i{display:block;width:4px;height:30px}
.nat-t td.nm{text-align:left;padding-left:var(--s2);font:600 var(--fs-name)/1.2 var(--face)}
.nat-t td.sv{font:600 34px/1 var(--face)}
.nat-t td.av{font:600 var(--fs-share)/1 var(--face);color:var(--ink2)}
.nat-t td.rg{font:400 var(--fs-votes)/1.2 var(--face);color:var(--muted);white-space:nowrap}
.nat-t td.pr{font:600 24px/1 var(--face)}
.nat-t tr.nf td.t i{background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cline x1='0' y1='2.5' x2='4' y2='2.5' stroke='%2316171A' stroke-opacity='.45'/%3E%3C/svg%3E")}
.nat-t tr.nf td.nm,.nat-t tr.nf td.sv{color:var(--ink2)}
/* the charts of a block in a row, each no narrower than its lines need: a row too
   narrow for them all puts the last on the next line (national.js draws each at
   the width it is given, so its words stay 13px) */
.nat-cs{display:flex;flex-wrap:wrap;gap:var(--s4) var(--s6);margin-top:var(--s5)}
.nat-cs.three{gap:var(--s4) var(--s5)}
.nat-c{margin:0;min-width:0;flex:1 1 240px;max-width:380px}
.nat-cs.three .nat-c{flex-basis:210px;max-width:250px}
/* the governors: the numbers beside their one chart where both fit whole (1400
   and up), the chart under the numbers on anything narrower */
.nat-two{display:grid;grid-template-columns:max-content minmax(0,380px);gap:var(--s6);align-items:end}
.nat-two .nat-cs{margin-top:0}
@media (max-width:1399.98px){
  .nat-two{grid-template-columns:minmax(0,1fr);gap:var(--s5)}
}
.nat-c figcaption{font:600 15px/1.2 var(--face);color:var(--ink);margin-bottom:var(--s1)}
.nat-c svg{display:block;width:100%;height:auto;overflow:visible}
.nat-c .g{stroke:var(--hair);stroke-width:1}
.nat-c .g.m{stroke:var(--ink2)}
.nat-c .tk{font:400 13px var(--face);fill:var(--muted)}
.nat-c .ln{fill:none;stroke-width:2;stroke-linejoin:round}
.nat-c .nw{stroke:var(--ink);stroke-width:1;stroke-dasharray:2 3}
.nat-c .el{font:600 13px var(--face);fill:var(--ink)}
/* a map's numbers as a table (the forecast pages): a word that opens it, the table in a box that scrolls by itself */
.twin{margin-top:var(--s4)}
.twin summary{display:inline-block;list-style:none;cursor:pointer;color:var(--ink);font:600 var(--fs-index)/var(--stamp-h) var(--face);
              text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.twin summary::-webkit-details-marker{display:none}
.twin-box{margin-top:var(--s2);max-height:420px;overflow:auto;border-top:2px solid var(--ink);border-bottom:2px solid var(--ink)}
.twin-t{border-collapse:collapse;width:100%;font:400 var(--fs-crumb)/1.3 var(--face);font-variant-numeric:lining-nums}
.twin-t th,.twin-t td{padding:3px var(--s3) 3px 0;text-align:right;white-space:nowrap;color:var(--ink2)}
.twin-t thead th{position:sticky;top:0;background:var(--paper);font:400 var(--fs-label)/1.2 var(--face);color:var(--muted);white-space:normal;vertical-align:bottom;padding-top:var(--s1)}
.twin-t th[scope="row"],.twin-t thead th:first-child{text-align:left;color:var(--ink);font-weight:600}
.twin-t thead th:first-child{font-weight:400;color:var(--muted)}
.nat-notes{margin-top:var(--s6);max-width:960px}
.nat-notes p{font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
.nat-notes p + p{margin-top:var(--s1)}
#nat-tip{position:absolute;z-index:20;pointer-events:none;background:var(--paper);border:1px solid var(--ink);padding:9px 11px 8px;
         width:max-content;max-width:300px;color:var(--ink2);font:400 14px/1.3 var(--face);font-variant-numeric:lining-nums tabular-nums}
#nat-tip[hidden]{display:none}
#nat-tip .tn{display:block;font:600 16px/1.2 var(--face);color:var(--ink)}
#nat-tip .tw{display:block;margin:1px 0 4px;color:var(--muted);font-size:var(--fs-label)}
#nat-tip{max-width:none}
#nat-tip .nt-t{margin-top:var(--s1);border-collapse:collapse;font-variant-numeric:lining-nums tabular-nums}
#nat-tip .nt-t th{font:400 var(--fs-label)/1.2 var(--face);color:var(--muted);text-align:right;padding:0 0 2px var(--s3)}
#nat-tip .nt-t td{padding:2px 0 2px var(--s3);text-align:right;color:var(--ink2)}
#nat-tip .nt-t td.t{padding:0;width:4px}
#nat-tip .nt-t td.t i{display:block;width:4px;height:14px}
#nat-tip .nt-t td.nm{text-align:left;padding-left:var(--s2);color:var(--ink)}
#nat-tip .nt-t td b{font-weight:600;color:var(--ink)}
#nat-tip .nt-ch{margin-top:var(--s2)}
#nat-tip .nt-sp{display:block;margin-top:2px;overflow:visible}
#nat-tip .nt-sp .g{stroke:var(--ink2);stroke-width:1}
#nat-tip .nt-sp .tk{font:400 13px var(--face);fill:var(--muted)}
#nat-tip .nt-sp .ln{fill:none;stroke-width:1.6}
#nat-tip .nt-sp .nw{stroke:var(--ink);stroke-width:1;stroke-dasharray:2 3}
#nat-tip .nt-sp .el{font:600 13px var(--face);fill:var(--ink)}
#nat-tip .nt-r{display:flex;align-items:center;gap:var(--s2);min-width:200px}
#nat-tip .nt-r i{flex:none;width:4px;height:14px}
#nat-tip .nt-r b{margin-left:auto;font-weight:600;color:var(--ink)}

/* the results slip (4.7): under the field, the field's width, over the map and the panel */
#find-list,#find-say{position:absolute;top:calc(100% + 4px);left:0;right:0;margin:0;padding:0;background:var(--paper);color:var(--ink);border:1px solid var(--ink)}
/* eight 32px rows show (4.7); the rest of the ten scroll */
#find-list{list-style:none;max-height:min(258px,70vh);overflow:auto}
#find-list[hidden],#find-say[hidden]{display:none}
/* a row is 32px; a name and kind too long for the slip wrap to a second line, never cut */
#find-list li{display:block;min-height:32px;padding:6px 8px;line-height:20px;cursor:pointer;font-size:15px}
#find-list .fn{font-weight:600;margin-right:var(--s1)}
#find-list .fq{color:var(--muted)}
#find-list li.on{background:var(--ink);color:var(--paper)}
#find-list li.on .fq{color:var(--paper)}
#find-say{padding:6px 8px;min-height:32px;line-height:20px;font-size:15px;pointer-events:none}

/* ---- the two columns (4.8) ---- */
.main{display:grid;grid-template-columns:minmax(0,1fr) var(--panel-width);position:relative;min-height:0}
.stage{position:relative;overflow:hidden;min-height:0}
/* a magnitude on the thermal ramp: the whole map is the dark ground (4.3) */
.stage.dark{background:var(--dark-ground)}
.stage.dark .clabel{color:var(--paper)}
#plate,#labels{position:absolute;inset:0;width:100%;height:100%}
/* one finger belongs to the page, so a phone scrolls past the map; two fingers move the map */
#plate{touch-action:pan-y}
#plate:focus-visible{outline:2px solid var(--ink);outline-offset:-2px}
#labels{z-index:1;pointer-events:none}
/* the picked unit's name and its leader (4.5) */
#pickname{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none;overflow:visible}
/* the last frame of the old geography, held while the next one loads; it goes in one frame */
#still{position:absolute;inset:0;width:100%;height:100%;z-index:3;pointer-events:none}
#still[hidden]{display:none}

/* loading (4.10): the doubling in ink2 and one line of muted text, 24px in from the map's corner */
#status,#face{position:absolute;top:var(--s5);left:var(--s5);z-index:5;margin:0;display:flex;align-items:baseline;gap:var(--s3);
              font:400 15px/1 var(--face);color:var(--muted);pointer-events:none}
#status .mk{font-size:22px;color:var(--ink2)}
/* the doubling as five bars (1:1:2:4:8) that keep rising in turn while anything
   loads; transform only, so they move even while the page is busy decoding */
#status .run{display:inline-flex;align-items:flex-end;gap:.06em;height:.44em;width:1.68em}
#status .run i{display:block;height:100%;background:currentColor;transform-origin:50% 100%;will-change:transform}
#status .run i:nth-child(1),#status .run i:nth-child(2){width:.09em}
#status .run i:nth-child(3){width:.18em}
#status .run i:nth-child(4){width:.36em}
#status .run i:nth-child(5){width:.72em}
#status.moving .run i{animation:rise 1.1s ease-in-out infinite}
#status.moving .run i:nth-child(2){animation-delay:.11s}
#status.moving .run i:nth-child(3){animation-delay:.22s}
#status.moving .run i:nth-child(4){animation-delay:.33s}
#status.moving .run i:nth-child(5){animation-delay:.44s}
@keyframes rise{0%,100%{transform:scaleY(.3)}50%{transform:scaleY(1)}}
@media (prefers-reduced-motion:reduce){
  #status.moving .run i{animation:none}
}
/* when the site is slow, down or offline the line is said in ink */
#status.trouble{color:var(--ink)}
#status.trouble .mk{color:var(--ink)}
#status[hidden],#face[hidden]{display:none}
/* a browser that cannot draw the map: one line in ink where the map would be, and no map furniture */
#nomap{position:absolute;top:var(--s5);left:var(--s5);right:var(--s5);z-index:5;margin:0;max-width:34em;font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink)}
.stage.nomap :is(canvas,.zoom,.tm,#gesture){display:none}
#face{top:calc(var(--s5) + 24px)}

/* zoom (4.5): typeset at the bottom left, 24px in, 16px apart, no box. The words
   sit where the type says; each hit area is a 32px square (44 on touch) centred
   on its word, laid over the paper around it, so the spacing is the type's */
/* the owner's trademark, small, at the bottom right of every map: the main map
   here, each small map below, and the map of every sheet (ui/sheet.js) */
.tm{position:absolute;right:var(--s5);bottom:var(--s5);z-index:1;width:88px;height:auto;pointer-events:none;user-select:none}
:is(.sg-map,.pf-map):has(img){position:relative;width:fit-content;max-width:100%}
/* a small map's mark sits under its bottom right, in the 16px of paper the map
   leaves round its precincts and a 10px band below: never on a precinct, a
   county or a district, at any size of grid (the sheet sets it the same way) */
:is(.sg-map,.pf-map):has(img,.sg-hold){padding-bottom:10px}
:is(.sg-map,.pf-map):has(img)::after{content:"";position:absolute;right:4px;bottom:0;width:min(40px,30%);aspect-ratio:1959.27 / 1028.38;
  background:url(../theo-elections-logo.svg) no-repeat center / contain;pointer-events:none}
.zoom{position:absolute;left:var(--s5);bottom:var(--s5);z-index:4;display:flex;align-items:baseline;gap:var(--s4)}
.zoom button{position:relative;display:block;padding:0;background:none;border:0;color:var(--ink);font:600 15px/1 var(--face);white-space:nowrap}
.zoom button::before{content:"";position:absolute;left:50%;top:50%;width:max(100%,32px);height:32px;transform:translate(-50%,-50%)}
/* a 3px halo of the ground, as the place names have, so the words read over fills */
.zoom button{-webkit-text-stroke:3px var(--paper);paint-order:stroke fill}
.stage.dark .zoom button{color:var(--paper);-webkit-text-stroke-color:var(--dark-ground)}

/* said once, the first time a finger tries to drag the map; laid over the stage, so nothing moves */
#gesture{position:absolute;top:var(--s5);left:var(--s5);z-index:5;margin:0;padding:10px 12px;max-width:calc(100% - 48px);
         background:var(--paper);border:1px solid var(--ink);color:var(--ink);font:400 15px/1.3 var(--face);pointer-events:none}
#gesture[hidden]{display:none}

/* the tooltip slip (4.5, the owner's concept D): paper, a 1px ink border, no
   shadow; the unit's name, its one figure on a chip in the unit's own fill,
   then a small table with lowercase heads and right-aligned lining figures */
#tip{position:absolute;z-index:6;pointer-events:none;background:var(--paper);border:1px solid var(--ink);padding:9px 11px 8px;
     max-width:460px;width:max-content;color:var(--ink2);font:400 14px/1.3 var(--face);font-variant-numeric:lining-nums tabular-nums}
#tip[hidden]{display:none}
/* a comparison's slip has two elections' columns and the words that go under them
   (a lead, a margin): room for them, and where a long name still does not fit,
   those words wrap between words in their cell rather than run out of the slip */
#tip.cmp{max-width:560px}
#tip.cmp tr.sum td:not(:first-child),#tip.cmp tr.q td:not(:first-child){white-space:normal}
#tip .tn{display:block;font:600 16px/1.2 var(--face);color:var(--ink)}
#tip .tw,#tip .tf{display:block;color:var(--muted);font-size:var(--fs-label)}
#tip .tw{margin-top:1px}
#tip .tf{margin-top:var(--s1)}
#tip .hd{display:flex;align-items:baseline;gap:var(--s2);margin:6px 0 5px}
#tip .chip{font:600 20px/1 var(--face);padding:3px 5px 2px;white-space:nowrap}
#tip .hw{color:var(--ink2);font-size:var(--fs-label)}
#tip .hw b{font-weight:600;color:var(--ink)}
#tip table{border-collapse:collapse;margin-top:2px}
#tip th{font:400 var(--fs-label)/1.2 var(--face);color:var(--muted);text-align:right;padding:0 0 2px 10px;vertical-align:bottom;white-space:nowrap}
#tip th:first-child{text-align:left;padding-left:0}
#tip thead tr:last-child th{border-bottom:1px solid var(--ink)}
#tip th.grp{text-align:center;border-bottom:1px solid var(--hair);padding-bottom:1px;white-space:normal}
#tip td{padding:1px 0 1px 10px;text-align:right;white-space:nowrap;color:var(--ink2)}
#tip td:first-child{text-align:left;padding-left:0}
#tip td.nm i{display:inline-block;width:3px;height:11px;margin-right:5px;vertical-align:-1px}
#tip td.nm i.no{background:transparent}
#tip tr.lead td{font-weight:600;color:var(--ink)}
#tip tr.sum td{border-top:1px solid var(--ink);padding-top:2px}
#tip tr.q td{color:var(--muted)}
#tip td.sep,#tip th.sep{padding-left:14px}
#tip td.ch,#tip th.ch{padding-left:14px}
#tip td.ch{font-weight:600;color:var(--ink)}
/* no return: the map's ruled paper, as a small swatch */
#tip .ruled{display:inline-block;width:26px;height:14px;border:1px solid var(--ink);vertical-align:-2px;margin-right:6px;
            background:repeating-linear-gradient(to bottom,var(--paper) 0 2px,var(--ink) 2px 3px)}

/* ---- the panel (4.8): crumb, title, fact line, results, the index, chart, actions, footnotes ---- */
.panel{overflow:auto;min-height:0;padding:var(--s6) var(--pad) var(--s7);display:flex;flex-direction:column}
.panel > *{flex:none;min-width:0}
.panel > * + *{margin-top:var(--s6)}
.panel > [hidden]{display:none}
.panel > #crumb + #headline{margin-top:var(--s2)}
.panel > #crumb[hidden] + #headline{margin-top:0}
.panel > #headline + #facts{margin-top:var(--s2)}
.panel > #facts + #block{margin-top:var(--s5)}
.panel > #index + #hint{margin-top:var(--s3)}

#crumb{font:400 var(--fs-crumb)/1.5 var(--face);color:var(--ink2);margin-top:-8px}
#crumb a{color:var(--ink2);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
#crumb a:hover{color:var(--ink)}
#headline{font:600 calc(var(--fs-title) * var(--hs, 1))/var(--lh-title) var(--face);letter-spacing:-0.015em;color:var(--ink);overflow-wrap:break-word}
#headline:focus{outline:none}
#headline .seg{white-space:nowrap}
#headline .seg.wrap{white-space:normal}
#facts{font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--muted)}
#facts span{white-space:nowrap}
#facts span.wrap{white-space:normal}
#facts:empty{display:none}

/* the results block (4.6): tick 4, name 76, chips 188, share 64, votes 64, gaps 8 8 10 10 */
:is(#block,#wb,.pf-block){color:var(--ink)}
:is(#block,#wb,.pf-block) .rb + .sd,:is(#block,#wb,.pf-block) .st + .sd{margin-top:var(--s6)}
.sd-none{margin:0 0 var(--s4);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--muted)}
:is(#block,#wb,.pf-block) .sd{font:600 var(--fs-section)/1.15 var(--face);color:var(--ink);margin-bottom:var(--s3)}
.rb .edges{display:grid;grid-template-columns:repeat(5,36px);column-gap:2px;height:18px;padding-left:96px;
              font:400 var(--fs-edge)/18px var(--face);color:var(--muted)}
.rb .edges i{font-style:normal;white-space:nowrap}
/* the edges and, at their end, the word that cuts the bands finer (more, fewer) */
.eg{display:flex;align-items:flex-start}
.eg > .edges,.eg > .se{flex:1 1 auto;min-width:0}
.eg .bx{flex:none;margin-left:auto;height:18px;padding:0 var(--stamp-pad);background:none;border:0;
        font:400 var(--fs-edge)/18px var(--face);color:var(--ink2);cursor:pointer}
.eg .bx:hover{color:var(--ink)}
/* a chip is pressed to show its band alone; the pressed one carries an ink frame */
:is(#block,#wb) .ch[data-band]{cursor:pointer}
:is(#block,#wb) .ch.pick{outline:2px solid var(--ink);outline-offset:-2px}
/* more than five margin bands: ten to a line, under each row's name */
.rb.wide .edges{grid-template-columns:repeat(10,36px);height:auto;row-gap:0}
.rb.wide .chips{grid-template-columns:repeat(10,36px);row-gap:2px}
.rb.two.wide .br{grid-template-rows:30px auto;padding-bottom:4px}
.rb .br{display:grid;grid-template-columns:4px 8px 76px 8px 188px 10px 64px 10px 64px;align-items:baseline;min-height:30px;padding:3px 0}
.rb .tk{grid-column:1;align-self:center;display:block;width:4px;height:20px}
.rb .nm{grid-column:3;font:600 var(--fs-name)/1.2 var(--face);color:var(--ink);overflow-wrap:break-word;min-width:0}
.rb .chips{grid-column:5;align-self:center;display:grid;grid-template-columns:repeat(5,36px);column-gap:2px}
.rb .ch{display:flex;align-items:center;justify-content:center;height:24px;font:600 var(--fs-chip)/1 var(--face);font-feature-settings:"lnum" 1}
.rb .chips.none{display:block;font:600 var(--fs-chip)/24px var(--face);color:var(--muted)}
.rb .sh{grid-column:7;text-align:right;font:600 var(--fs-share)/1.2 var(--face);color:var(--ink);white-space:nowrap}
.rb .vt{grid-column:9;text-align:right;font:400 var(--fs-votes)/1.2 var(--face);color:var(--muted);white-space:nowrap}
.rb .po .nm{font-weight:600}
/* a long name steps to 16px, then breaks at its hyphen (4.6; block.js nameFit
   measures it); in the two-line rows the name has the row's width and stays 18 */
.rb .nm.s16{font-size:16px;line-height:1.15}
.rb.two .nm.s16{font-size:var(--fs-name);line-height:1.2}
.rb.two br.hy{display:none}
/* candidates the precinct file never carried: no tick and no chips, under one muted line */
.rb .ab{margin:var(--s2) 0 var(--s1);font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
.rb .abr .tk{background:none}
/* a canvass row has no chips, so its name runs across the chip column */
.rb .abr .nm{grid-column:3 / 6}
/* a magnitude: stepped bars whose height follows the count (4.6) */
:is(#block,#wb,.pf-block) .st{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(36px,1fr);column-gap:2px;align-items:end}
:is(#block,#wb,.pf-block) .col{display:grid;grid-template-rows:auto 72px auto;align-items:end;justify-items:start;row-gap:var(--s1);min-width:0}
:is(#block,#wb,.pf-block) .col b{font:600 var(--fs-chip)/1 var(--face)}
:is(#block,#wb,.pf-block) .col i{display:block;width:100%;align-self:end}
:is(#block,#wb,.pf-block) .col span{font:400 var(--fs-edge)/1 var(--face);color:var(--muted);white-space:nowrap}
/* thermal bars on the dark ground (4.3), their figures in paper */
:is(#block,#wb,.pf-block) .st.dk{background:var(--dark-ground);padding:var(--s2) var(--s2) var(--s2)}
:is(#block,#wb,.pf-block) .st.dk .col b,:is(#block,#wb,.pf-block) .st.dk .col span{color:var(--paper)}

/* texas, kept under a picked place: a section title, its fact line and its block */
#whole h2{font:600 var(--fs-section)/1.15 var(--face);color:var(--ink)}
#whole #wf{margin-top:var(--s2);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--muted)}
#whole #wf span{white-space:nowrap}
#whole #wf span.wrap{white-space:normal}
#whole #wb{margin-top:var(--s4)}

/* the index (4.7, A): rows of words, the choice paper type on an ink stamp; nothing moves */
#index{display:flex;flex-direction:column;gap:var(--s2)}
#index .ir{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) 6px;margin-left:calc(-1 * var(--stamp-pad))}
/* the grid maker's panel speaks the index's words too: rows, columns, places, the picker */
:is(#index,#gm-panel,#charts,#scatter,#catalog) .iw{position:relative;height:var(--stamp-h);padding:0 var(--stamp-pad);background:none;border:0;color:var(--ink2);
           font:400 var(--fs-index)/var(--stamp-h) var(--face);white-space:nowrap;cursor:pointer}
:is(#index,#gm-panel,#charts,#scatter,#catalog) .iw:hover{color:var(--ink)}
:is(#index,#gm-panel,#charts,#scatter,#catalog) .iw.on{background:var(--ink);color:var(--paper)}
:is(#index,#gm-panel,#charts,#scatter) .iw.on:focus-visible{outline-color:var(--ink)}
/* in a comparison the partner is stamped green beside the base's ink; a word
   that is both keeps the ink stamp over a green foot */
#index .iw.vs{background:var(--grn);color:var(--ink)}
#index .iw.on.vs{background:linear-gradient(to top,var(--grn) 4px,var(--ink) 4px);color:var(--paper)}
/* the two small boxes that say which side the rows change: ink for the base,
   green for against, the chosen one ticked */
#index .iw.sb{display:inline-flex;align-items:center;gap:6px}
#index .sq{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font:600 var(--fs-label)/1 var(--face)}
#index .sq-ink{background:var(--ink);color:var(--paper)}
#index .sq-grn{background:var(--grn);color:var(--ink)}
#index .il{padding:0 var(--stamp-pad);font:400 var(--fs-index)/var(--stamp-h) var(--face);color:var(--muted)}
#index .ih{font:600 var(--fs-label)/1.2 var(--face);color:var(--muted);margin-top:var(--s2)}
#hint{font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
#hint span{display:block}

/* the charts (4.6): a plain section title, then the chart on paper */
#charts{display:flex;flex-direction:column;gap:var(--s6)}
#scatter{margin-top:var(--s6)}
#scatter figure{margin:0;min-width:0}
#scatter figcaption{font:600 var(--fs-section)/1.15 var(--face);color:var(--ink);margin-bottom:var(--s2)}
#scatter svg{display:block;max-width:100%;height:auto;cursor:crosshair}
#scatter .chs{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 var(--s2) calc(-1 * var(--stamp-pad))}
#scatter .chn,#scatter .sch{margin-top:var(--s2);font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
#scatter .sch{height:calc(2 * var(--lh-foot) * 1em);overflow:hidden}
#charts figure{margin:0;min-width:0}
#charts figcaption{font:600 var(--fs-section)/1.15 var(--face);color:var(--ink);margin-bottom:var(--s2)}
#charts svg{display:block;max-width:100%;height:auto}
#charts .chn{margin-top:var(--s2);font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
/* as voted or relative to nation, over the charts, in the index's own words */
#charts .chs{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 var(--s2) calc(-1 * var(--stamp-pad))}

/* the actions (4.7): slips, 32px tall, a lowercase verb phrase, 8px apart */
.actions{display:flex;flex-wrap:wrap;gap:var(--s2)}
/* the info line and the actions wait for the panel's first results, so the
   results never push them down the screen as the page arrives */
.panel:not([data-ready]) > :is(.pinfo,.actions){display:none}
.actions button{height:32px;padding:0 var(--s3);background:none;border:1px solid var(--ink);color:var(--ink);font:600 15px/30px var(--face);white-space:nowrap}

/* the footnotes: three to five muted lines, the source line last */
#notes p{font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
#notes p + p{margin-top:var(--s1)}

/* ---- one candidate (the owner's request 1): a row is a button to its share ---- */
/* the button keeps the row's own grid and type; only the native look goes */
button.br{-webkit-appearance:none;appearance:none;width:100%;margin:0;padding:0;background:none;border:0;font:inherit;color:inherit;text-align:left}
/* the chosen row takes the index stamp: ink ground, paper type. The ground is
   laid 6px past the row on each side behind it, so nothing in the row moves */
:is(#block,#wb) button.br{position:relative;isolation:isolate}
:is(#block,#wb) .br.on::before{content:"";position:absolute;top:0;bottom:0;left:-6px;right:-6px;background:var(--ink);z-index:-1}
:is(#block,#wb) .br.on .nm,:is(#block,#wb) .br.on .sh,:is(#block,#wb) .br.on .vt{color:var(--paper)}
:is(#block,#wb) .br.on:focus-visible{outline-offset:4px}
/* under the chosen row, the way to every race the candidate ran */
:is(#block,#wb) button.pr{display:block;margin:var(--s1) 0 var(--s2) 12px;padding:0;background:none;border:0;text-align:left;
                          font:600 15px/24px var(--face);color:var(--ink);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
:is(#block,#wb) button.pr[hidden]{display:none}
/* the chip strip of a share map: the lower edge of each 10-point band over its chip */
:is(#block,#wb) .ss{margin-bottom:var(--s3)}
:is(#block,#wb) .se,:is(#block,#wb) .sc{display:grid;grid-template-columns:repeat(10,minmax(0,36px));column-gap:2px}
:is(#block,#wb) .se{min-height:18px;font:400 var(--fs-edge)/18px var(--face);color:var(--muted)}
:is(#block,#wb) .sc{row-gap:2px}
:is(#block,#wb) .se i{font-style:normal;white-space:nowrap}
:is(#block,#wb) .sc .ch{min-width:0;overflow:visible}

/* ---- a candidate's profile (the owner's request 2), in the right column ---- */
.panel.pf-on > :not(#profile){display:none}
.panel.pf-on > #profile{margin-top:0}
#profile{color:var(--ink)}
.pf-crumb{margin-top:-8px;font:400 var(--fs-crumb)/1.5 var(--face);color:var(--ink2)}
.pf-crumb a{color:var(--ink2);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px}
.pf-name{margin:var(--s2) 0 0;font:600 var(--fs-title)/var(--lh-title) var(--face);letter-spacing:-0.015em;color:var(--ink);overflow-wrap:break-word}
.pf-party{margin-top:var(--s2);display:flex;align-items:center;gap:var(--s2);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink2)}
.pf-party .tk{display:block;width:4px;height:20px;flex:none}
.pf-facts{margin-top:var(--s2);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--muted)}
.pf-facts span,.pf-rf span,.pf-cv p span{white-space:nowrap}
.pf-list{list-style:none;margin:var(--s6) 0 0;padding:0}
.pf-race + .pf-race{margin-top:var(--s6)}
.pf-rt{margin:0;font:600 var(--fs-section)/1.15 var(--face);color:var(--ink)}
.pf-rf{margin-top:var(--s2);font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--muted)}
/* the small map: its box reserved before it draws, the image top left, no frame */
.pf-map{display:block;width:100%;margin:var(--s4) 0 0;padding:0;background:none;border:0;text-align:left;overflow:hidden}
.pf-map img{display:block}
.pf-wait{display:flex;align-items:baseline;gap:var(--s3);font:400 15px/1 var(--face);color:var(--muted)}
.pf-wait .mk{font-size:22px;color:var(--ink2)}
.pf-block{margin-top:var(--s4)}
/* the person's own row: an ink ring round the tick, no tint */
.pf-block .br.me .tk{outline:2px solid var(--ink);outline-offset:1px}
.pf-fn{margin-top:var(--s2);font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
.pf-fn[hidden]{display:none}
/* a canvass race: one line, the title at the fact line's size */
.pf-cv p{font:400 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--muted)}
.pf-cv .pf-rt{font:600 var(--fs-fact)/var(--lh-fact) var(--face);color:var(--ink)}
.pf-foot,.pf-data{font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
.pf-foot{margin-top:var(--s6)}
.pf-list + .pf-data{margin-top:var(--s6)}
.pf-foot + .pf-data,.pf-foot + .pf-foot{margin-top:var(--s1)}

/* ---- two elections on the map (4.11) ---- */
/* swipe: a 0.6px ink line, a 24 by 40 ink handle with a paper "‹›"; it moves only when dragged */
.divider{position:absolute;top:0;bottom:0;width:44px;z-index:3;cursor:ew-resize;touch-action:none}
.divider i{position:absolute;top:0;bottom:0;left:22px;width:.6px;background:var(--ink);pointer-events:none}
.divider b{position:absolute;top:50%;left:10px;width:24px;height:40px;margin-top:-20px;display:flex;align-items:center;justify-content:center;
           background:var(--ink);color:var(--paper);font:600 13px/1 var(--face);pointer-events:none}
.divider:focus-visible{outline:2px solid var(--ink);outline-offset:-2px}
/* side by side: 16px of paper between the two maps */
.gap{position:absolute;z-index:3;background:var(--paper);pointer-events:none}
.clabel{position:absolute;z-index:3;pointer-events:none;color:var(--ink);font:600 15px/1 var(--face)}
.clabel.big{font-size:22px}
.clabel.big.small{font-size:15px}
/* a label that has been given less room than its name needs wraps between words */
.clabel.fit{line-height:1.1}

/* ---- the full catalogue: every contest, over the whole page below the bar ---- */
#catalog{position:absolute;inset:0;background:var(--paper);display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);z-index:7}
#catalog[hidden]{display:none}
.cat-head{display:flex;flex-wrap:wrap;gap:var(--s3);align-items:center;padding:var(--s5) var(--pad) var(--s4)}
.cat-head input{height:32px;width:420px;max-width:100%;padding:0 8px;background:var(--paper);color:var(--ink);border:1px solid var(--ink);
                font:400 15px/30px var(--face);-webkit-appearance:none;appearance:none}
.cat-head input::placeholder{color:var(--muted);opacity:1}
.cat-head .n{color:var(--muted);margin-left:auto}
.cat-head button{height:32px;padding:0 var(--s3);background:none;border:1px solid var(--ink);color:var(--ink);font:600 15px/30px var(--face)}
.cat-list{overflow:auto;padding:0 var(--pad) var(--s6)}
.cat-list table{border-collapse:collapse;width:100%}
.cat-list th{position:sticky;top:0;background:var(--paper);text-align:left;font:600 13px/1.2 var(--face);color:var(--muted);padding:6px 10px 6px 0}
.cat-list th.r,.cat-list td.r{text-align:right;white-space:nowrap}
.cat-list td{padding:5px 10px 5px 0;vertical-align:top;color:var(--ink2)}
.cat-list td.c{color:var(--muted);max-width:36em}
.cat-list tr[data-id]{cursor:pointer}
/* a row's office and a column's head are words a keyboard can reach and press; they look as the cell's text does */
.cat-list :is(.cat-go,th button){display:inline;padding:0;margin:0;background:none;border:0;color:inherit;font:inherit;text-align:left;cursor:pointer}
.cat-list td.r .cu{display:none}
.cat-filters{flex:0 0 100%;display:flex;flex-direction:column;gap:var(--s1)}
.cat-filters .ir{display:flex;flex-wrap:wrap;gap:var(--s1) 6px;margin-left:calc(-1 * var(--stamp-pad))}
.cat-list th[data-by]{cursor:pointer;white-space:nowrap}
.cat-list th[data-by]:hover,.cat-list th.on{color:var(--ink)}
.cat-list tr[data-id]:hover td{color:var(--ink)}

/* a block whose row heads outrun the name column takes the two-line rows at every width */
.rb.two .edges{padding-left:24px}
.rb.two .br{grid-template-columns:4px 8px minmax(0,1fr) 10px 64px 10px 64px;grid-template-rows:30px 28px;padding:0}
.rb.two .tk{grid-column:1;grid-row:1}
.rb.two .nm{grid-column:3;grid-row:1;align-self:center}
.rb.two .sh{grid-column:5;grid-row:1;align-self:center}
.rb.two .vt{grid-column:7;grid-row:1;align-self:center}
.rb.two .chips{grid-column:3 / -1;grid-row:2;margin-left:12px;align-self:start}
.rb.two .po,.rb.two .abr{grid-template-rows:30px}
.rb.two .abr .nm{grid-column:3}

/* ---- 1024 to 1279: a 420px panel, the results in two lines ---- */
@media (max-width:1279.98px){
  :root{--panel-width:420px;--pad:20px}
  .rb .edges{padding-left:24px}
  .rb .br{grid-template-columns:4px 8px minmax(0,1fr) 10px 64px 10px 64px;grid-template-rows:30px 28px;padding:0}
  .rb .tk{grid-column:1;grid-row:1}
  .rb .nm{grid-column:3;grid-row:1;align-self:center}
  .rb .sh{grid-column:5;grid-row:1;align-self:center}
  .rb .vt{grid-column:7;grid-row:1;align-self:center}
  .rb .chips{grid-column:3 / -1;grid-row:2;margin-left:12px;align-self:start}
  .rb .po,.rb .abr{grid-template-rows:30px}
  .rb .abr .nm{grid-column:3}
  .rb.nochips .br{grid-template-rows:30px}
  .rb.nochips .chips{display:none}
  .rb .edges + .br{margin-top:0}
  .rb .nm.s16{font-size:var(--fs-name);line-height:1.2}
  .rb br.hy{display:none}
}
/* ---- 900 to 1023: a 380px panel ---- */
@media (max-width:1023.98px){
  :root{--panel-width:380px;--pad:16px}
}
/* ---- under 900: a 48px bar, the map first at 58% of the height, the panel below; the page scrolls ---- */
@media (max-width:899.98px){
  :root{--bar:84px;--fs-title:30px;--fs-section:19px;--fs-fact:15px;--fs-name:17px;--fs-share:17px;--fs-votes:13px;--fs-wordmark:20px;--pad:16px}
  /* the body grows with the page, so the sticky bar has the whole page to stay on */
  body{overflow:auto;display:block;height:auto;min-height:100%}
  .bar{position:sticky;top:0;height:var(--bar)}
  .tabs{--fs-index:14px}
  .brand .logo{height:72px}
  .nat-row{grid-template-columns:minmax(0,1fr)}
  .nat-title{font-size:34px}
  .nat-cs .nat-c,.nat-cs.three .nat-c{flex-basis:100%;max-width:none}
  .nat-t td.sv{font-size:28px}
  .nat-t th,.nat-t td{padding-left:var(--s3)}
  .sheet{padding:var(--s6) var(--pad) var(--s7)}
  .sheet-title{font-size:44px}
  .sheet .big-logo{width:144px}
  .toc-name{font-size:28px}
  .main{display:block}
  /* the box Texas needs at the phone's width before the map arrives (main.js
     fitStage sets the same to the pixel), so nothing under it moves on load:
     Texas is 0.956 as tall as it is wide, with 32px of paper all round */
  .stage{width:100%;height:min(58vh,calc((100vw - 64px) * .9562 + 64px));height:min(58svh,calc((100vw - 64px) * .9562 + 64px))}
  .stage.nomap{height:auto}
  .stage.nomap #nomap{position:static;padding:var(--s5) var(--pad) 0}
  .panel{overflow:visible;padding:var(--s5) var(--pad) var(--s7)}
  /* the profile opens under the sticky bar, not behind it; so does anything the keyboard reaches */
  #profile,.panel{scroll-margin-top:calc(var(--bar) + var(--s4))}
  html{scroll-padding-top:calc(var(--bar) + var(--s2))}
  /* the bar shows only the word find, which opens the field full width under the bar */
  #find-word{cursor:pointer;padding:12px 0}
  .find{display:none;position:absolute;top:var(--bar);left:0;right:0;width:auto;padding:0}
  .bar.finding .find{display:block}
  #find{height:44px;border:1px solid var(--ink)}
  #find-list,#find-say{top:100%}
  #find-list{max-height:min(354px,70vh)}
  #find-list li{min-height:44px;padding:12px 8px}
  #catalog{position:fixed;inset:var(--bar) 0 0 0}
  /* the column heads stay as a row of words to order by */
  .cat-list thead{display:block;position:sticky;top:0;background:var(--paper);z-index:1}
  .cat-list thead tr{display:flex;flex-wrap:wrap;column-gap:var(--s3)}
  .cat-list thead th{position:static;display:block;padding:var(--s2) 0;min-height:44px;line-height:28px}
  /* a row is its cells set as words that wrap whole, the candidates on a line of their own */
  .cat-list table,.cat-list tbody{display:block;width:auto}
  .cat-list tr[data-id]{display:flex;flex-wrap:wrap;column-gap:var(--s2);padding:var(--s2) 0;min-height:44px}
  .cat-list tr[data-id] td{display:block;padding:0;min-width:0;max-width:100%}
  .cat-list tr[data-id] td.c{flex:0 0 100%;max-width:100%;overflow-wrap:anywhere}
  /* the two numbers that end a row say what they count, the heads being out of sight by then */
  .cat-list td.r .cu{display:inline}
  .cat-list td.r + td.r::before{content:"· "}
}
/* a phone under 420 wide: the forecast tables closed up to fit 320, their column
   heads on two lines where a word is wider than its numbers */
@media (max-width:419.98px){
  .nat-t th,.nat-t td{padding-left:var(--s2)}
  .nat-t th{white-space:normal;line-height:1.1;vertical-align:bottom}
  .nat-t td.nm{font-size:16px}
  .nat-t td.sv{font-size:24px}
  .nat-t td.av{font-size:16px}
  .nat-t td.pr{font-size:19px}
}
@media (max-width:339.98px){
  .nat-t th,.nat-t td{padding-left:4px}
  .nat-t td.nm{font-size:15px;padding-left:6px}
  .nat-t td.sv{font-size:21px}
  .nat-t td.av{font-size:15px}
  .nat-t td.pr{font-size:17px}
}
/* a phone on its side: a 52px bar, and Texas as tall as the screen under it allows */
@media (max-width:899.98px) and (max-height:500px){
  :root{--bar:52px}
  .brand .logo{height:44px}
  .stage{height:min(calc(100vh - var(--bar) - var(--tabs)),calc((100vw - 64px) * .9562 + 64px));height:min(calc(100svh - var(--bar) - var(--tabs)),calc((100vw - 64px) * .9562 + 64px))}
}
/* ---- the sticky compare header (T3) ---- */
#compare-header{position:sticky;top:0;z-index:2;background:var(--paper);padding:0 0 var(--s2)}
#compare-header[hidden]{display:none}
.cmp-from,.cmp-to{font:400 var(--fs-index)/var(--stamp-h) var(--face);color:var(--muted)}
.cmp-from b,.cmp-to b{font-weight:600}

/* ---- the lines row: three radio sub-groups (T3) ---- */
.ir-radio-group{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) var(--s3)}
.ig{font:600 var(--fs-label)/1.2 var(--face);color:var(--muted)}
.ig-values{display:inline-flex;gap:2px}
.igp{display:inline-flex;align-items:center;gap:var(--s2);white-space:nowrap}
#index .iw.dis{opacity:0.4;cursor:default}

/* ---- the sheet grid in the map area (T4) ---- */
#sheet-grid{position:absolute;inset:0;z-index:2;background:var(--paper);overflow:auto;padding:var(--s5)}
#sheet-grid[hidden]{display:none}
.sg{min-width:0}
.sg-title{font:600 var(--fs-title)/1.1 var(--face);letter-spacing:-0.01em;color:var(--ink);margin:0 0 var(--s5)}
.sg-grid{display:grid;gap:var(--s5)}
.sg-cell{min-width:0}
.sg-nomap{padding:var(--s3) 0}
.sg-ct{margin:0;font:600 var(--fs-section)/1.15 var(--face);color:var(--ink)}
/* a projection's cell: the word on an ink stamp, the cell in an ink frame (outside its box, so the row keeps its line) */
.sg-stamp{display:inline-block;padding:0 .28em;background:var(--ink);color:var(--paper);line-height:1.15;white-space:nowrap}
.sg-proj{outline:3px solid var(--ink);outline-offset:9px}
.sg-cf{margin:var(--s1) 0 0;font:400 var(--fs-crumb)/var(--lh-fact) var(--face);color:var(--muted)}
.sg-cf span{white-space:nowrap}
.sg-cn{margin:var(--s1) 0 0;font:400 var(--fs-foot)/var(--lh-foot) var(--face);color:var(--muted)}
.sg-map{display:block;width:100%;margin:var(--s2) 0 0;padding:0;background:none;border:0;text-align:left;cursor:pointer}
.sg-map img{display:block;max-width:100%;height:auto}
.sg-block{margin-top:var(--s2)}
.sg-notes{margin-top:var(--s5);max-width:720px}
.sg-notes p{font:400 var(--fs-edge)/1.35 var(--face);color:var(--muted)}
/* inside a sheet cell the block uses the two-line form (F2: cell is always under 432px) */
.sg-block .rb .edges{padding-left:24px}
.sg-block .rb .br{grid-template-columns:4px 8px minmax(0,1fr) 10px 64px 10px 64px;grid-template-rows:30px 28px;padding:0}
.sg-block .rb .tk{grid-column:1;grid-row:1}
.sg-block .rb .nm{grid-column:3;grid-row:1;align-self:center}
.sg-block .rb .sh{grid-column:5;grid-row:1;align-self:center}
.sg-block .rb .vt{grid-column:7;grid-row:1;align-self:center}
.sg-block .rb .chips{grid-column:3 / -1;grid-row:2;margin-left:12px;align-self:start}
.sg-block .rb .po,.sg-block .rb .abr{grid-template-rows:30px}
.sg-block .rb .abr .nm{grid-column:3}
.sg-block .rb .nm.s16{font-size:var(--fs-name);line-height:1.2}
.sg-block .rb br.hy{display:none}
/* a swing cell: each toward row on one line, its party letter and its chips,
   then the two races' results under their names */
.sg-vs{width:100%;margin-top:var(--s3);border-collapse:collapse;table-layout:fixed;font:400 var(--fs-label)/1.25 var(--face);color:var(--ink)}
.sg-vs th{text-align:left;font-weight:600;padding:0 0 var(--s1)}
.sg-vs th:first-child,.sg-vs td.t{width:10px}
.sg-vs td{padding:var(--s1) var(--s2) var(--s1) 0;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-vs td.t i{display:block;width:4px;height:30px}
.sg-vs td b{font-weight:600}
.sg-vs td .v{display:block;color:var(--muted);font-size:var(--fs-edge)}
.sg-block .sg-sw .rb .br{grid-template-columns:4px 6px 14px 6px minmax(0,1fr);grid-template-rows:30px}
.sg-block .sg-sw .rb .nm{white-space:nowrap}
.sg-block .sg-sw .rb .chips{grid-column:5;grid-row:1;margin-left:0;align-self:center;grid-template-columns:repeat(5,minmax(0,36px))}
.sg-block .sg-sw .rb .edges{padding-left:30px;grid-template-columns:repeat(5,minmax(0,36px))}
/* a narrow cell (four columns on a laptop): the share and votes take only their
   own width, so a name keeps a whole line and is never broken inside a word */
.sg-cell{container-type:inline-size}
@container (max-width:320px){
  .sg-block .rb .br{grid-template-columns:4px 6px minmax(0,1fr) 6px auto 6px auto}
  .sg-block .rb .edges{padding-left:16px;grid-template-columns:repeat(5,minmax(0,36px))}
  .sg-block .rb .chips{margin-left:6px;grid-template-columns:repeat(5,minmax(0,36px))}
}
/* a small cell (five to ten columns): the results as a list, each candidate's
   name and share on one line and the votes under the share; no chips (the
   bands' counts need the width); the numbers are the block's */
@container (max-width:319.98px){
  .sg-ct{font-size:var(--fs-name)}
}
@container (max-width:199.98px){
  .sg-ct{font-size:var(--fs-crumb)}
  .sg-block .eg,.sg-block .rb .edges,.sg-block .rb .chips{display:none}
  .sg-block .rb .br,.sg-block .rb .po,.sg-block .rb .abr{grid-template-columns:3px 4px minmax(0,1fr) 4px auto;grid-template-rows:auto;min-height:0;padding:1px 0}
  .sg-block .rb .tk{height:12px}
  .sg-block .rb .nm,.sg-block .rb .nm.s16{font:600 var(--fs-label)/1.3 var(--face);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;overflow-wrap:normal}
  .sg-block .rb .sh{font:600 var(--fs-label)/1.3 var(--face);grid-row:1}
  .sg-block .rb .vt{grid-column:3 / -1;grid-row:2;align-self:start;text-align:right;font:400 var(--fs-edge)/1.2 var(--face)}
  .sg-block .rb .tk,.sg-block .rb .nm{grid-row:1}
  .sg-block .rb .nm.s16 br.hy{display:none}
  .sg-grid{gap:var(--s3)}
  .sg-cf{overflow-wrap:anywhere}
  /* a swing cell's chips need the width a small cell has not; its two results stay */
  .sg-sw{display:none}
  /* the two results stacked, each share after its year, the name left out */
  .sg-vs thead{display:none}
  .sg-vs td{display:block;padding:0 0 var(--s1)}
  .sg-vs td.t{display:table-cell;width:6px}
  .sg-vs tr{display:table-row}
  .sg-vs td b{display:none}
  .sg-vs td[data-h]::before{content:attr(data-h) " ";font-weight:600}
  .sg-cf span{white-space:normal}
}

/* ---- the grid maker panel (T5) ---- */
.panel.gm-on > :not(#gm-panel,#compare-header){display:none}
.panel.gm-on > #gm-panel{margin-top:0}
#gm-panel{color:var(--ink)}
#gm-panel[hidden]{display:none}
.gm{display:flex;flex-direction:column;gap:var(--s3)}
.gm-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) 6px}
.gm-label{font:600 var(--fs-label)/1.2 var(--face);color:var(--muted)}
.gm-place-name{font:400 var(--fs-index)/var(--stamp-h) var(--face);color:var(--ink)}
.gm-place-field{height:30px;width:200px;max-width:100%;padding:0 8px;background:var(--paper);color:var(--ink);border:1px solid var(--ink);
                font:400 var(--fs-index)/28px var(--face);-webkit-appearance:none;appearance:none}
.gm-place-list{position:relative;background:var(--paper);border:1px solid var(--ink);max-height:200px;overflow:auto}
.gm-place-list[hidden]{display:none}
.gm-place-hit{display:block;width:100%}
.gm-cell-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) 6px}
.gm-picker{margin-top:var(--s1)}
.gm-picker-years,.gm-picker-offices{display:flex;flex-wrap:wrap;gap:2px}

/* ---- F4: ink words for profile race list, grid maker cells, no blue links ---- */
/* an ink word with a 1px underline: used for "back to the map", cell election pickers, download */
.gm-acts{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s5)}
.ink-link{display:inline;padding:0;margin:0;background:none;border:0;color:var(--ink);
          font:600 var(--fs-index)/var(--stamp-h) var(--face);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;cursor:pointer}
.ink-link:hover{color:var(--ink)}
a.ink-link{color:var(--ink)}
/* the person's race list on the map: one ink word per line, the current one stamped */
.pf-races{display:flex;flex-direction:column;gap:var(--s1);margin-top:var(--s6)}
.pf-races .pf-go.iw{display:block;height:auto;padding:var(--s1) var(--stamp-pad);background:none;border:0;text-align:left;
                     font:400 var(--fs-index)/var(--lh-index) var(--face);color:var(--ink2);cursor:pointer;white-space:normal}
.pf-races .pf-go.iw:hover{color:var(--ink)}
.pf-races .pf-go.iw.on{background:var(--ink);color:var(--paper)}
.pf-arrange{display:flex;flex-direction:column;gap:var(--s2);margin-top:var(--s5)}
.pf-line{display:flex;align-items:baseline;gap:2px}
.pf-line .pf-go.iw{flex:1 1 auto;min-width:0}
.pf-line .pf-mv{flex:none;font-size:var(--fs-label)}
.pf-line .pf-mv:disabled{color:var(--hair);cursor:default}
.pf-dl{margin-top:var(--s5)}
.pf-back{margin-top:var(--s6)}
/* kill any remaining default blue on links; zero specificity, so a link's own
   class (the paper brand on the ink bar) always wins */
:where(a[href]){color:var(--ink2)}
:where(a[href]:hover){color:var(--ink)}

/* a finger needs a target: 44px by padding, and nothing a finger sees changes size */
@media (pointer:coarse){
  :is(#index,#gm-panel,#charts,#scatter,#catalog,.ftx,.nat-mode) .iw::before{content:"";position:absolute;left:0;right:0;top:-10px;bottom:-10px}
  .tabs a,.ftx-fs,.eg .bx{position:relative}
  .eg .bx::before{content:"";position:absolute;left:-6px;right:-6px;top:-13px;bottom:-13px}
  /* the line weights 1 to 5, each a finger wide */
  #index .iw[data-row="lines"],.ftx .iw[data-lw]{min-width:44px}
  .tabs a::before{content:"";position:absolute;left:0;right:0;top:-10px;bottom:-10px}
  .ftx-fs::before{content:"";position:absolute;left:-8px;right:-8px;top:-14px;bottom:-14px}
  .zoom button::before,.ftx-zoom button::before{width:max(100%,44px);height:44px}
  /* plus and minus each in a box a finger wide, side by side, so neither covers
     the other; the plus stays where it was */
  .stage .zoom,.ftx-stage .ftx-zoom{gap:0}
  :is(.zoom,.ftx-zoom) button:nth-child(-n+2){width:44px;text-align:center}
  .stage .zoom{left:calc(var(--s5) - 17px)}
  .ftx-stage .ftx-zoom{left:-17px}
  :is(.zoom,.ftx-zoom) button:nth-child(3){margin-left:var(--s1)}
  .actions button,.cat-head button{position:relative}
  .actions button::before,.cat-head button::before{content:"";position:absolute;left:0;right:0;top:-7px;bottom:-7px}
  .cat-head input{height:44px;line-height:42px}
}

/* F3 */
.stage.sheet-on .zoom,
.stage.sheet-on #pickname,
.stage.sheet-on #tip,
.stage.sheet-on .scale{display:none}
/* a chart cell: the scatter in place of the small map */
.sg-chart svg{display:block;max-width:100%;height:auto}
.gm-views{display:inline-flex;gap:2px}
/* a label kept on the line of what it names: from, by, voters */
.gm-with{display:inline-flex;align-items:center;gap:6px}
.gm-picker-rows{display:flex;flex-direction:column;gap:var(--s1);margin-top:var(--s1)}
.gm-picker-rows[hidden]{display:none}
.gm-picker-row{display:flex;flex-wrap:wrap;align-items:center;gap:2px}
.gm-pq{height:30px;width:100%;max-width:420px;padding:0 8px;background:var(--paper);color:var(--ink);border:1px solid var(--ink);
       font:400 var(--fs-index)/28px var(--face);-webkit-appearance:none;appearance:none;border-radius:0}
.gm-picker-offices{margin-top:var(--s1)}
.gm-pn{font:400 var(--fs-label)/1.3 var(--face);color:var(--muted)}
.gm-picker-row .gm-label{margin-right:4px}

/* ---- the 2026 texas forecast (forecast.html): four rows, two maps and a thin column each ---- */
.ftx{padding:var(--s4) var(--pad) var(--s7)}
.ftx :is(.ftx-mode,.ftx-row) .iw{position:relative;height:var(--stamp-h);padding:0 var(--stamp-pad);background:none;border:0;color:var(--ink2);
  font:400 var(--fs-index)/var(--stamp-h) var(--face);white-space:nowrap;cursor:pointer}
.ftx :is(.ftx-mode,.ftx-row) .iw:hover{color:var(--ink)}
.ftx :is(.ftx-mode,.ftx-row) .iw.on{background:var(--ink);color:var(--paper)}
.ftx-lede{min-height:calc(var(--lh-fact) * 1em)}
.ftx-mode{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s2) 2px;margin-left:calc(-1 * var(--stamp-pad))}
.ftx-cl{font:600 var(--fs-label)/var(--stamp-h) var(--face);color:var(--muted);padding:0 var(--s1) 0 var(--stamp-pad)}
.ftx-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(250px,276px) minmax(0,1fr) minmax(250px,276px);grid-template-areas:"a ra b rb" "ca ca cb cb";
  gap:var(--s3) var(--s5);padding:var(--s5) 0 var(--s4);border-top:2px solid var(--ink)}
#ftx-rows .ftx-row:first-child{border-top:0}
.ftx-map[data-side="a"]{grid-area:a}
.ftx-map[data-side="b"]{grid-area:b}
.ftx-map{min-width:0;display:flex;flex-direction:column}
.ftx-mh{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s3);min-height:32px}
.ftx-mt{margin:0;font:600 var(--fs-section)/1.15 var(--face);color:var(--ink)}
.ftx-fs{flex:none;padding:0;background:none;border:0;color:var(--ink);font:600 var(--fs-label)/1.2 var(--face);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;cursor:pointer;white-space:nowrap}
.ftx-stage{position:relative;width:100%;aspect-ratio:1 / .94;overflow:hidden;margin-top:var(--s2)}
.ftx-stage canvas{position:absolute;inset:0;width:100%;height:100%}
.ftx-plate{touch-action:pan-y}
.ftx-labels{z-index:1;pointer-events:none}
.ftx-still{z-index:0}
.ftx-wait{position:absolute;left:0;top:var(--s2);z-index:2;margin:0;font:400 var(--fs-label)/1.2 var(--face);color:var(--muted)}
.ftx-zoom{position:absolute;left:0;bottom:var(--s1);z-index:3;display:flex;align-items:baseline;gap:var(--s4)}
.ftx-zoom button{position:relative;display:block;padding:0;background:none;border:0;color:var(--ink);font:600 15px/1 var(--face);white-space:nowrap;cursor:pointer;
  -webkit-text-stroke:3px var(--paper);paint-order:stroke fill}
.ftx-zoom button::before{content:"";position:absolute;left:50%;top:50%;width:max(100%,32px);height:32px;transform:translate(-50%,-50%)}
.ftx-res{min-width:0;display:flex;flex-direction:column;gap:var(--s4);padding-top:var(--s1)}
.ftx-res[data-side="a"]{grid-area:ra}
.ftx-res[data-side="b"]{grid-area:rb}
.ftx-h{margin:0;font:600 var(--fs-name)/1.2 var(--face);color:var(--ink)}
.ftx-f{margin:var(--s1) 0 0;font:400 var(--fs-label)/1.35 var(--face);color:var(--ink2)}
.ftx-f span{white-space:nowrap}
.ftx-t{margin-top:var(--s2);border-collapse:collapse;font-variant-numeric:lining-nums tabular-nums}
.ftx-t th{font:400 var(--fs-label)/1.2 var(--face);color:var(--muted);text-align:right;padding:0 0 var(--s1) var(--s3);white-space:nowrap}
.ftx-t td{padding:2px 0 2px var(--s3);text-align:right;vertical-align:middle;color:var(--ink);white-space:nowrap}
.ftx-t td.t{padding:0;width:4px}
.ftx-t td.t i{display:block;width:4px;height:24px}
.ftx-t td.nm{text-align:left;padding-left:var(--s2);font:600 var(--fs-crumb)/1.2 var(--face)}
.ftx-t td.sh{font:600 var(--fs-share)/1 var(--face)}
.ftx-t td.pr{font:600 var(--fs-crumb)/1 var(--face)}
.ftx-t td.rg{font:400 var(--fs-label)/1.2 var(--face);color:var(--muted)}
.ftx-t td.vt,.ftx-g td.vt{font:400 var(--fs-label)/1.2 var(--face);color:var(--ink2)}
.ftx-t th:nth-child(2){text-align:left;padding-left:var(--s2)}
#ftx-tip .nt-t .v{color:var(--muted)}
.ftx-t tr.nf td{color:var(--ink2)}
.ftx-t tr.nf td.sh{font-weight:400}
.ftx-chips{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s3);margin:var(--s2) 0 0}
.ftx-chip{display:inline-flex;align-items:center;gap:5px;font:400 var(--fs-label)/1.2 var(--face);color:var(--ink2);white-space:nowrap}
.ftx-chip i{display:block;width:14px;height:12px}
.ftx-chip b{font-weight:600;color:var(--ink)}
.ftx-g{border-collapse:collapse;font-variant-numeric:lining-nums tabular-nums;margin-left:calc(-1 * var(--stamp-pad))}
.ftx-g th{font:400 var(--fs-label)/1.2 var(--face);color:var(--muted);text-align:right;padding:0 0 var(--s1) var(--s3);white-space:nowrap}
.ftx-g th:first-child{text-align:left;padding-left:var(--stamp-pad)}
.ftx-g td{padding:1px 0 1px var(--s3);text-align:right;font:600 var(--fs-crumb)/var(--stamp-h) var(--face);color:var(--ink);white-space:nowrap}
.ftx-g td.gw{text-align:left;padding-left:0;font-weight:400}
.ftx-g .gs{margin-left:var(--s1);font:400 var(--fs-label)/1 var(--face);color:var(--muted)}
/* each map's own controls, under its map and its results */
.ftx-ctl{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:center;gap:var(--s2) var(--s4);margin-left:calc(-1 * var(--stamp-pad))}
.ftx-ctl[data-side="a"]{grid-area:ca}
.ftx-ctl[data-side="b"]{grid-area:cb}
.ftx-cg{display:inline-flex;flex-wrap:wrap;align-items:center;gap:2px}
.ftx-cg .ftx-cl{padding-left:var(--stamp-pad)}
.ftx-fail{font:400 var(--fs-fact)/1.4 var(--face);color:var(--ink2)}
#ftx-notes{margin-top:var(--s6)}
#ftx-tip{position:fixed;z-index:30;pointer-events:none;background:var(--paper);border:1px solid var(--ink);padding:9px 11px 8px;max-width:min(420px,calc(100vw - 16px))}
#ftx-tip[hidden]{display:none}
#ftx-tip .tn{display:block;font:600 16px/1.2 var(--face);color:var(--ink)}
#ftx-tip .tw{display:block;margin:1px 0 2px;color:var(--muted);font:400 var(--fs-label)/1.2 var(--face)}
#ftx-tip .nt-t{margin-top:var(--s1);border-collapse:collapse;font:400 var(--fs-label)/1.3 var(--face);font-variant-numeric:lining-nums tabular-nums}
#ftx-tip .nt-t td{padding:2px 0 2px var(--s3);color:var(--ink2);white-space:nowrap}
#ftx-tip .nt-t td:first-child{padding-left:0}
#ftx-tip .nt-t td.nm{color:var(--ink);font-weight:600}
#ftx-tip .nt-t td.na{color:var(--muted)}
#ftx-tip .nt-t b{color:var(--ink);font-weight:600}
/* full screen: the one race over the whole window, its column beside it */
html.ftx-locked,html.ftx-locked body{overflow:hidden}
.ftx-row.full{position:fixed;inset:0;z-index:40;background:var(--paper);margin:0;padding:var(--s4) var(--pad);border:0;overflow:auto;
  grid-template-columns:minmax(0,1fr) minmax(230px,260px);grid-template-rows:minmax(0,1fr) auto;grid-template-areas:"m r" "ctl ctl"}
.ftx-row.full .ftx-map{grid-area:m;min-height:0}
.ftx-row.full .ftx-stage{aspect-ratio:auto;flex:1 1 auto;min-height:0}
.ftx-row.full[data-full="a"] .ftx-res[data-side="a"],.ftx-row.full[data-full="b"] .ftx-res[data-side="b"]{grid-area:r}
.ftx-row.full[data-full="a"] .ftx-map[data-side="b"],.ftx-row.full[data-full="b"] .ftx-map[data-side="a"]{position:absolute;left:-10000px;top:0;width:600px;visibility:hidden}
.ftx-row.full[data-full="a"] .ftx-res[data-side="b"],.ftx-row.full[data-full="b"] .ftx-res[data-side="a"]{display:none}
.ftx-row.full[data-full="a"] .ftx-ctl[data-side="a"],.ftx-row.full[data-full="b"] .ftx-ctl[data-side="b"]{grid-area:ctl}
.ftx-row.full[data-full="a"] .ftx-ctl[data-side="b"],.ftx-row.full[data-full="b"] .ftx-ctl[data-side="a"]{display:none}
/* 900 to 1279: a race a line, its map no wider than 600 and its numbers beside it;
   two across would leave each map smaller than a phone's */
@media (min-width:900px) and (max-width:1279.98px){
  .ftx-row{grid-template-columns:minmax(0,600px) minmax(250px,1fr);grid-template-areas:"a ra" "ca ca" "b rb" "cb cb"}
  .ftx-row .ftx-ctl[data-side="a"]{margin-bottom:var(--s5)}
}
@media (max-width:899.98px){
  .ftx-lede{min-height:calc(2 * var(--lh-fact) * 1em)}
  /* on a phone each map, its controls, then its numbers */
  .ftx-row{grid-template-columns:minmax(0,1fr);grid-template-areas:"a" "ca" "ra" "b" "cb" "rb"}
  .ftx-ctl{margin-bottom:var(--s3)}
  .ftx-stage{aspect-ratio:1 / .96}
  .ftx-zoom button::before{width:max(100%,44px);height:44px}
  /* full screen on a phone: the map, its controls, then its numbers, scrolled together */
  .ftx-row.full{display:flex;flex-direction:column;gap:var(--s3);overflow:auto;padding-top:0}
  .ftx-row.full .ftx-map{flex:none}
  /* its name and "close" stay at the top while the map, the words and the numbers scroll under */
  .ftx-row.full[data-full="a"] .ftx-map[data-side="a"],.ftx-row.full[data-full="b"] .ftx-map[data-side="b"]{display:contents}
  .ftx-row.full .ftx-mh{position:sticky;top:0;z-index:5;flex:none;align-items:center;min-height:52px;margin:0 calc(-1 * var(--pad));padding:0 var(--pad);background:var(--paper)}
  .ftx-row.full .ftx-fs{position:relative}
  .ftx-row.full .ftx-fs::before{content:"";position:absolute;left:-12px;right:-12px;top:-14px;bottom:-14px}
  .ftx-row.full .ftx-stage{margin-top:0}
  .ftx-row.full .ftx-stage{flex:none;height:66vh;height:66svh;aspect-ratio:auto}
  .ftx-row.full .ftx-ctl{order:2}
  .ftx-row.full .ftx-res{order:3}
}
