@font-face{font-family:'Suisse Intl';src:url('../fonts/SuisseIntl-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Suisse Intl';src:url('../fonts/SuisseIntl-RegularItalic.woff2') format('woff2');font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'Suisse Intl';src:url('../fonts/SuisseIntl-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Ioskeley Mono';src:url('../fonts/IoskeleyMono-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Ioskeley Mono';src:url('../fonts/IoskeleyMono-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Ioskeley Mono';src:url('../fonts/IoskeleyMono-SemiBold.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
:root{
  --bg:#050505; --bg2:#101313; --bg3:#1e2020; --tab-on:#2b2f2e; --line:#252827; --line2:#323534;
  --ink:#e9ece9; --dim:#98a29e; --faint:#606864;
  /* the full list's row hover: a translucent wash, not an opaque grey, so it reads
     the same whatever the row sits on rather than matching it and vanishing */
  --row-hover:rgba(238,242,239,.06);
  --hot:#d9569d; --hot-ink:#eaa0c8; --hot-soft:rgba(217,86,157,.10); --hot-line:rgba(217,86,157,.45);
  --cool:#4a92e5; --cool-ink:#98c1f0; --cool-soft:rgba(74,146,229,.10); --cool-line:rgba(74,146,229,.45);
  --gain:#7de8a8; --loss:#ff8a80; --accent:#eef2ef; --accent-dim:#cbd2ce; --accent-soft:rgba(238,242,239,.07); --r:2px; --gold:var(--accent); --gold-soft:var(--accent-soft);
  --mono:'Ioskeley Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:'Suisse Intl',-apple-system,Segoe UI,sans-serif;
  --disp:'Suisse Intl',var(--sans);
  --s2:8px; --s3:16px; --s4:24px; --s5:40px; --s6:64px; --s7:96px; --ease:cubic-bezier(.16,1,.3,1);
  --gut:var(--s4);
}
@media (max-width:640px){:root{--gut:var(--s3)}}
*{box-sizing:border-box}
::selection{background:#fff;color:#050505;text-shadow:none}
::-moz-selection{background:#fff;color:#050505;text-shadow:none}
html{background:var(--bg)}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}
.wrap{max-width:1080px;margin:0 auto;padding:0 var(--gut)}
.mono{font-family:var(--mono)}
.ic{width:1em;height:1em;vertical-align:-.13em;flex-shrink:0}
svg text{font-family:var(--mono)}
.up{color:var(--gain)}.down{color:var(--loss)}

.nav{position:sticky;top:0;z-index:50;background:rgba(5,5,5,.90);backdrop-filter:blur(8px);border-bottom:1px solid var(--line)}
.nav-in{position:relative;max-width:1080px;margin:0 auto;padding:10px var(--gut);display:flex;align-items:center;gap:6px}
.brand{font-family:var(--disp);font-weight:400;font-size:17px;letter-spacing:.01em;color:var(--ink);text-decoration:none;display:flex;align-items:center;gap:10px}
.brand .dot{width:8px;height:8px;border-radius:50%;background:var(--gain);animation:pulse 2s ease-in-out infinite;flex-shrink:0}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.nav-dir,.nav-list,.nav-pro{font-family:var(--sans);font-size:13px;font-weight:500;color:var(--dim);text-decoration:none;letter-spacing:.01em;padding:7px 14px;flex-shrink:0;background:transparent;border-radius:var(--r);transition:background .12s,color .12s}
.nav-dir{margin-left:auto}
.nav-dir:hover,.nav-dir.active,.nav-list:hover,.nav-pro:hover{color:var(--ink);background:var(--accent-soft)}
/* Directories keeps its own link — the dropdown is a shortcut past it, not a
   replacement for it. Hover opens it, and so does focus-within: the trigger sits
   inside the wrapper, so tabbing to it is what reveals the menu and makes the two
   links below it focusable on the next tab. Touch has no hover, so a tap just
   follows the link to the page that lists both books anyway. */
.nav-dd{position:relative;margin-left:auto;flex-shrink:0}
.nav-dd .nav-dir{margin-left:0;display:block}
.nav-dd-menu{position:absolute;top:calc(100% + 12px);left:0;min-width:212px;z-index:60;display:flex;flex-direction:column;padding:6px;background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);box-shadow:0 14px 30px rgba(0,0,0,.5);opacity:0;visibility:hidden;transform:translateY(-5px);transition:opacity .14s ease,transform .2s var(--ease),visibility .14s}
/* the gap under the trigger would drop the hover on the way down to the menu */
.nav-dd-menu::before{content:'';position:absolute;left:0;right:0;top:-12px;height:12px}
.nav-dd-menu a{display:flex;flex-direction:column;gap:2px;padding:8px 10px;border-radius:var(--r);font-family:var(--sans);font-size:13px;font-weight:500;color:var(--ink);text-decoration:none;transition:background .12s}
.nav-dd-menu a span{font-size:11px;font-weight:400;color:var(--dim)}
.nav-dd-menu a:hover{background:var(--accent-soft)}
.nav-dd:focus-within .nav-dd-menu{opacity:1;visibility:visible;transform:none}
@media (hover:hover){.nav-dd:hover .nav-dd-menu{opacity:1;visibility:visible;transform:none}}
@media (prefers-reduced-motion:reduce){.nav-dd-menu{transition-duration:.01ms}}
@media (max-width:640px){.nav-dir,.nav-dd,.nav-pro{display:none}.nav-list{margin-left:auto}}

/* ---------- hero ----------
   No band of its own — no rule, no gradient backdrop: the page is one surface
   from the name to the footer, and the first panel's margin is the seam. */
.hero{padding:var(--s6) 0 0}
.kicker{font-family:var(--mono);font-size:13px;font-weight:600;letter-spacing:.14em;color:var(--dim);text-transform:uppercase;margin-bottom:var(--s3)}
.h1-row{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.hero h1{font-size:clamp(30px,7vw,50px);font-weight:400;letter-spacing:-.02em;line-height:1.05;margin:0}
.h1-row .sx{font-size:12px;padding:1px 6px}
.h1-btns{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap}
@media (max-width:640px){.h1-btns{margin-left:0;width:100%}}
.hero .sub{color:var(--dim);font-size:19px;max-width:58ch;margin:var(--s4) 0 0}
/* the board chips double as the toggle on dual listings */
button.sx{cursor:pointer;-webkit-appearance:none;appearance:none}
.bd-chip[aria-pressed="false"]{opacity:.4;transition:opacity .15s}
.bd-chip[aria-pressed="false"]:hover{opacity:.8}

/* ---------- quote bar ----------
   Sits in flow at the hero's end, then rides sticky under the nav for the rest
   of the page: the name, the Girls/Boys board toggle, and the terminal link.
   --nav-h is measured by the page script; 49px is the unscripted fallback. */
.qbar{position:sticky;top:var(--nav-h,49px);z-index:40;background:rgba(5,5,5,.92);backdrop-filter:blur(8px);border-bottom:1px solid var(--line)}
/* The page script promotes the bar to .fx — fixed under the nav and slid up out
   of sight — and .on drops it in once the hero has scrolled away (an observer
   watches the hero); scrolling back toward the top retracts it the same way. It
   slides from behind the nav, whose near-opaque blur is what sells the reveal.
   Without scripting the bar keeps the in-flow sticky behavior above. */
/* visibility rides the slide (delayed on the way out, immediate on the way in)
   so the retracted bar can't take keyboard focus or catch pointers behind the nav */
.qbar.fx{position:fixed;left:0;right:0;transform:translateY(-130%);visibility:hidden;transition:transform .34s var(--ease),visibility 0s .34s}
.qbar.fx.on{transform:translateY(0);visibility:visible;transition:transform .34s var(--ease)}
@media (prefers-reduced-motion:reduce){.qbar.fx{transition-duration:.01ms}}
.qbar-in{max-width:1080px;margin:0 auto;padding:8px var(--gut);display:flex;align-items:center;gap:14px}
.qbar .qname{font-weight:500;font-size:15px}
.qbar .btn{padding:6px 12px;font-size:12px}
.qbar .share{margin-left:auto}
/* the terminal's segmented tabs, sliding indicator and all — the page script
   carries a compact tabsInit/tabsSync port that measures the selected button
   and slides .tabs-ind under it. With scripting off the selected label still
   reads: the ink color states it even before the indicator exists. */
.tabs{position:relative;display:inline-flex;align-items:center;padding:3px;background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);font-family:var(--sans)}
.tabs>button{position:relative;z-index:1;background:none;border:0;border-radius:1px;color:var(--dim);cursor:pointer;font:inherit;font-size:12.5px;font-weight:500;letter-spacing:.01em;padding:5px 14px;transition:color .18s ease}
.tabs>button:hover{color:var(--ink)}
.tabs>button:focus-visible{outline:2px solid var(--gold);outline-offset:-1px}
.tabs>button[aria-selected="true"]{color:var(--ink)}
/* the board toggle carries the full list's sex-tab coding: the indicator fills
   solid hot/cool (via data-ind) and the selected label goes near-black on it —
   --ink on --hot is only ~3.5:1, while #050505 clears AA on both fills */
#bdTabs>button[aria-selected="true"]{color:#050505}
.tabs-ind{position:absolute;top:0;left:0;opacity:0;background:var(--tab-on);border-radius:1px;pointer-events:none;z-index:0;transition:transform .28s cubic-bezier(.4,0,.2,1),width .28s cubic-bezier(.4,0,.2,1),background-color .28s ease}
.tabs.no-anim .tabs-ind{transition:none}
@media (prefers-reduced-motion:reduce){.tabs-ind{transition:none}}
.hero .sub b,.lede b{color:var(--ink);font-weight:500}
.hero .sub a{color:var(--ink)}
/* the y-axis toggle rides above the chart, right-aligned over the plot. It is the
   report's compact tab variant — smaller type, gold on the selected label — and it
   sits in its own row because the h1 row above it is already carrying the name, the
   sex chips and two buttons. Board focus stays where it was, on the sex chips and
   the sticky bar's own toggle; this one only ever changes what the y axis counts. */
.chart-tools{display:flex;justify-content:flex-end;margin-top:var(--s4)}
.tabs.sm>button{font-size:11.5px;font-weight:400;letter-spacing:0;padding:5px 12px}
.tabs.sm>button[aria-selected="true"]{color:var(--gold);font-weight:600}
.tabs.sm .tabs-ind{background:var(--bg3)}
.hero .chart-tools+.chart-box{margin-top:var(--s2)}
.hero .chart-box{margin-top:var(--s4)}
.share.done{color:var(--gold);border-color:var(--gold)}
/* the market report's quote-desk stat strip. Stated columns rather than its
   auto-fit: at this hero's width auto-fit seats seven tiles and orphans the
   eighth on its own row. All eight in one band on a desk, as on the report. */
.qstats{display:grid;grid-template-columns:repeat(8,1fr);gap:1px;background:var(--line);border:1px solid var(--line);margin-top:var(--s3)}
@media (max-width:980px){.qstats{grid-template-columns:repeat(4,1fr)}}
@media (max-width:640px){.qstats{grid-template-columns:1fr 1fr}}
@media (min-width:981px){.qstat{padding:10px 12px}}
.qstat{background:var(--bg2);padding:10px var(--s3)}
.qstat .v{font-family:var(--mono);font-size:17px;font-weight:600}
.qstat .k{font-family:var(--mono);font-size:11px;color:var(--dim);letter-spacing:.08em;text-transform:uppercase}
.qstat .v.up{color:var(--gain)}.qstat .v.down{color:var(--loss)}
/* the terminal's one tooltip — a single fixed node that trails the cursor */
.dyn-tip{position:fixed;left:0;top:0;display:none;pointer-events:none;background:var(--bg3);border:1px solid var(--line2);font-family:var(--mono);font-size:12px;line-height:1.6;padding:6px 10px;white-space:nowrap;z-index:100;box-shadow:0 4px 16px rgba(0,0,0,.4)}
.dyn-tip b{color:var(--gold)}
.dyn-tip.scrub-tip{font-size:11.5px;line-height:1.7}
.dyn-tip.scrub-tip b{display:block;margin-bottom:3px}
.dyn-tip .tip-grid{display:grid;grid-template-columns:auto auto;column-gap:18px}
.dyn-tip .tip-v{text-align:right;color:var(--ink)}

/* ---------- boards ---------- */
.eyebrow{font-family:var(--mono);font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);margin:var(--s5) 0 0}
.lede{color:var(--dim);font-size:18px;max-width:72ch;margin:var(--s3) 0 0}
main{padding-bottom:var(--s5)}

/* ---------- ticker chips (the terminal's, as links) ---------- */
.tickers{display:inline-flex;gap:6px;flex-wrap:wrap}
.ticker{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:13px;font-weight:500;border:1px solid var(--line2);background:var(--bg2);padding:4px 8px;border-radius:var(--r);color:var(--ink);text-decoration:none;transition:border-color .15s,background-color .15s}
a.ticker:hover{border-color:var(--gold);background:var(--gold-soft)}
.sx{font-family:var(--mono);font-size:11px;border:1px solid var(--line2);padding:0 4px;border-radius:2px;font-weight:600}
.sx.f{color:var(--hot-ink);border-color:var(--hot-line);background:var(--hot-soft)}
.sx.m{color:var(--cool-ink);border-color:var(--cool-line);background:var(--cool-soft)}

/* ---------- panels (terminal chrome) ---------- */
/* s5 between blocks, not the terminal's s3 — on one continuous surface the
   panels are the only articulation the page has, so they get room to breathe */
.panel{border:1px solid var(--line);background:var(--bg2);padding:var(--s3);margin-top:var(--s5);border-radius:var(--r)}
.panel-hd{font-family:var(--mono);font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);margin-bottom:10px}
.panel .prose{font-size:15px;line-height:1.65;color:var(--dim);max-width:72ch;margin:0}
.panel .prose b{color:var(--ink);font-weight:500}
.panel .prose a{color:var(--ink)}
.chart-box{width:100%;overflow-x:auto;position:relative;direction:rtl}
.chart-box svg{display:block;width:100%;height:auto;min-width:640px;direction:ltr}

/* ---------- state tile map (terminal chrome) ---------- */
.st-inner{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(260px,1fr);gap:var(--s4);align-items:start}
@media (max-width:840px){.st-inner{grid-template-columns:1fr}}
.st-inner>*{min-width:0}
.usmap{display:grid;grid-template-columns:repeat(11,1fr);grid-template-rows:repeat(8,1fr);gap:4px;aspect-ratio:11/8;margin-top:6px;max-width:760px}
.st{border:0;border-radius:var(--r);font-family:var(--mono);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;padding:2px;min-width:0;background:var(--bg3);color:var(--dim)}
.st .ab{font-size:11px;font-weight:600;line-height:1.2}
/* full opacity, unlike the terminal's .9 — the blended loss is what pushes the
   crossover shades under AA; the weight difference against .ab keeps the hierarchy */
.st .lf{font-size:11px;line-height:1}
.strows{font-family:var(--mono);font-size:12.5px;margin-top:10px}
.strow{display:flex;justify-content:space-between;padding:5px 0;border-bottom:1px solid var(--line)}
.strow:last-child{border-bottom:0}
.strow .lift{color:var(--gold);font-weight:600}
.empty{font-family:var(--mono);font-size:13px;color:var(--dim);padding:var(--s4) 0}

/* ---------- buttons (terminal chrome) ---------- */
.btn{display:inline-block;background:var(--accent);border:1px solid var(--accent);color:#050505;font-family:var(--sans);font-size:13px;font-weight:500;padding:9px 16px;cursor:pointer;letter-spacing:.01em;border-radius:var(--r);text-decoration:none;transition:filter .12s,border-color .15s,color .15s}
.btn:hover{filter:brightness(.94)}
.btn.ghost{background:transparent;border:1px solid var(--line2);color:var(--dim)}
.btn.ghost:hover{color:var(--ink);border-color:var(--faint);filter:none}

/* ---------- hubs (the full list's chrome, rule for rule) ----------
   A letter book is the 2025 Full List sliced by first letter, so the two hub
   pages wear the full list's furniture rather than the quote page's: its
   masthead instead of the hero, its sticky controls bar, and its table instead
   of a panel of tiles. Everything below is lifted from rankings-raw.html, with
   two changes — the column classes carry the responsive rules that page hangs
   off :nth-child, because the two hub tables don't share a column order. */
header.hd{padding:var(--s5) 0 var(--s4);border-bottom:1px solid var(--line)}
/* The way back up the book, in the market report's kicker. A letter page has a
   parent the nav can't offer — the brand goes home and the directory is a level
   in between — so the masthead names it, above the title it belongs to. */
.crumb{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);text-decoration:none;margin-bottom:var(--s3);transition:color .14s ease}
.crumb:hover{color:var(--ink)}
.crumb .ic{opacity:.6;transition:transform .22s var(--ease),opacity .14s ease}
.crumb:hover .ic{opacity:1;transform:translateX(-3px)}
.hd h1{font-family:var(--disp);font-size:clamp(28px,4vw,42px);font-weight:400;letter-spacing:-.02em;margin:0;text-wrap:balance}
/* The directory's two books each get the masthead's own type, a size down: they are
   the page, and an eyebrow over a 4,000-row table reads as a caption for it. The
   scroll offset clears the sticky nav so a jump link doesn't land under it. */
.book-hd{font-family:var(--disp);font-size:clamp(24px,3vw,32px);font-weight:400;letter-spacing:-.02em;margin:0 0 var(--s3);scroll-margin-top:76px}
.tbl+.book-hd{margin-top:var(--s5)}
/* the way down to either book, for a reader who lands above both of them */
.dir-jump{display:flex;gap:8px;flex-wrap:wrap;margin-top:var(--s3)}

/* the filter and the sort are nothing without scripting, so the bar only appears
   once the head script says there is some; the table below it is plain HTML */
.controls{display:none;gap:var(--s3);align-items:center;flex-wrap:wrap;position:sticky;top:50px;background:var(--bg);z-index:30;padding:14px 0;border-bottom:1px solid var(--line)}
.js .controls{display:flex}
.tabs{position:relative;display:inline-flex;align-items:center;justify-content:center;padding:3px;background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);font-family:var(--sans)}
.tabs>button{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;gap:8px;white-space:nowrap;background:none;border:0;border-radius:1px;color:var(--dim);cursor:pointer;font:inherit;font-size:13px;font-weight:500;letter-spacing:.01em;padding:7px 17px;transition:color .18s ease}
.tabs>button:hover{color:var(--ink)}
.tabs>button:focus-visible{outline:2px solid var(--gold);outline-offset:-1px}
.tabs>button[aria-selected=true]{color:var(--ink)}
.tabs-ind{position:absolute;top:0;left:0;background:var(--tab-on);border-radius:1px;pointer-events:none;z-index:0;transition:transform .28s cubic-bezier(.4,0,.2,1),width .28s cubic-bezier(.4,0,.2,1)}
.tabs.no-anim .tabs-ind{transition:none}
@media (prefers-reduced-motion:reduce){.tabs-ind{transition:none}}
.searchbox{position:relative;flex:1;min-width:200px;max-width:320px;display:flex}
#q{width:100%;background:var(--bg3);border:1px solid var(--line2);color:var(--ink);font-family:var(--mono);font-size:15px;padding:9px 40px 9px 13px;border-radius:var(--r)}
#q:focus{outline:2px solid var(--gold);outline-offset:-1px}
#q::-webkit-search-cancel-button{-webkit-appearance:none;display:none}
.searchbox .clr{position:absolute;right:5px;top:50%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;width:30px;height:30px;flex-shrink:0;padding:0;border:0;background:none;color:var(--faint);cursor:pointer;border-radius:var(--r);transition:color .15s,background-color .15s}
.searchbox .clr .ic{width:16px;height:16px;vertical-align:0}
.searchbox .clr:hover{color:var(--ink);background:var(--bg2)}
.searchbox .clr:focus-visible{outline:2px solid var(--gold);outline-offset:-1px}
.searchbox .clr[hidden]{display:none}
.count{font-family:var(--mono);font-size:12px;color:var(--faint);margin-left:auto}

.tbl{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:14px;margin-bottom:80px}
/* parks under the controls bar. The fallback is the desktop height; the real one is
   measured, because the bar grows a line when the filter or the count wraps below it */
.tbl thead th{position:sticky;top:var(--thead-top,50px);background:var(--bg);text-align:right;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);font-weight:600;padding:10px 12px;border-bottom:1px solid var(--line2);z-index:5}
.tbl thead th.l{text-align:left}
.tbl td{padding:7px 12px;border-bottom:1px solid var(--line);text-align:right;white-space:nowrap}
.tbl td.rk{color:var(--faint);width:64px}
.tbl td.nm{text-align:left}
.tbl td.nm a{color:var(--ink);text-decoration:none;font-weight:500}
.tbl td.nm a:hover{color:var(--gold);text-decoration:underline}
.tbl .sx{margin-left:7px}
/* the directory's name column holds one letter, and the full list's width:100% on
   it would leave the row a hand-span of nothing. The first and last listing under
   the letter fill it, and say what is behind the initial. */
.tbl .rng{color:var(--faint);font-size:12.5px;margin-left:12px}
.tbl td.share{color:var(--dim)}
.tbl td.cum{color:var(--faint)}
.tbl td.del{color:var(--faint)}
/* 10-year shape, normalised to each name's own peak — the babies column already
   carries magnitude. The stroke tints with the sex, and stays neutral for the
   names that trade in both books, where the curve is the two added together. */
.tbl td.tr{width:96px;padding-top:0;padding-bottom:0;line-height:0}
.spark{display:block;width:100%;max-width:84px;height:24px;margin-left:auto}
.spark path{fill:none;stroke-width:1.5;stroke:var(--dim)}
.tbl td.tr.f .spark path{stroke:#d9569d}
.tbl td.tr.m .spark path{stroke:#4a92e5}
/* the whole row is the click target; the <a> stays so keyboard + open-in-new-tab still work */
.tbl tbody tr[data-h]{cursor:pointer;transition:background-color .12s}
.tbl tbody tr[data-h]:hover{background:var(--row-hover)}
.tbl tbody tr[data-h]:hover td.nm a{color:var(--gold);text-decoration:underline}
/* the same table living inside a quote-page panel: nothing above it to park
   under, nothing after it to clear — so no sticky header and no runout margin */
.tbl.mini{margin:6px 0 0}
/* not sticky, so it also sheds the opaque page-bg fill the hubs' header needs to
   cover rows scrolling under it — on a panel that fill printed as a dark band */
.tbl.mini thead th{position:static;background:transparent}
.tbl.mini tbody tr:last-child td{border-bottom:0}
/* the page's own listing, sitting in the middle of its own comps. It is the one
   row that goes nowhere, so it takes the tint instead of the hover and prints its
   name as text — the rank column already says where on the tape it falls. */
.tbl tbody tr.here{background:var(--accent-soft)}
.tbl tbody tr.here td{color:var(--ink)}
.tbl tbody tr.here td.nm{font-weight:600}
.tbl tbody tr.here td.rk{color:var(--dim)}
/* needs .tbl td.empty, not .empty — plain .empty loses to .tbl td{text-align:right} */
.tbl td.empty{font-family:var(--mono);color:var(--dim);text-align:center;white-space:normal;border-bottom:0;padding:112px var(--s4)}
.empty-acts{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-top:18px}
/* The Origin panel's shelf links. Same pills as an empty state's actions, but left
   and in flow — dropped straight into .prose the inline-block padding fights the
   1.65 line-height and the rows go ragged. */
.shelf-links{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
.ebtn{font-family:var(--sans);font-size:13px;font-weight:500;color:var(--dim);background:var(--bg2);border:1px solid var(--line2);border-radius:var(--r);padding:8px 14px;cursor:pointer;transition:color .15s,border-color .15s;text-decoration:none;display:inline-block}
.ebtn:hover{color:var(--ink);border-color:var(--gold)}
.ebtn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* Above the narrow breakpoint the row has slack in it, and left to itself the auto
   layout spreads the figures down the row. Giving the name column all of it packs
   every figure into one group against the right edge. */
@media (min-width:601px){
  .tbl td.nm{width:100%}
  .tbl td.tr{min-width:96px}
  .tbl thead th{white-space:nowrap}
}
@media (max-width:560px){
  .tbl{font-size:13px}
  .tbl td,.tbl thead th{padding:7px 8px}
  .tbl td.empty{padding:72px var(--s3)}
  .tbl td.cum,.tbl th.cum,.tbl td.share,.tbl th.share,.tbl .rng{display:none}
  .tbl td.rk{width:46px}
}

/* ---------- footer (identical markup + rules on all three pages) ---------- */
footer{padding:var(--s5,40px) 0 var(--s7,96px);color:var(--faint);font-family:var(--mono);font-size:12.5px}
footer a{color:var(--dim)}
.foot-src,.foot-joke{letter-spacing:.04em}
.foot-joke{margin-top:var(--s3,16px)}
.made-by{margin-top:var(--s4,24px);display:flex;align-items:center;gap:.6em;letter-spacing:.04em;font-size:14px}
.made-by .heart{font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif;font-size:1.05em;line-height:1}
.made-by svg{height:1.35em;width:auto;display:block}
.made-by .sb{display:flex;color:var(--dim);transition:color .18s ease}
.made-by .sb:hover,.made-by .sb:focus-visible{color:var(--ink)}

/* ---------- entrance motion (hubs only) ----------
   The full list's intro, verbatim. Scoped to .anim, which only the two hub
   templates set — a quote page never sets it, so none of these start states
   exist there and its markup is untouched. A hub is one long table with
   nothing worth revealing on scroll, so the intro is pure CSS on the masthead
   and controls; the rows stay put, since animating thousands would be noise. */
.anim .nav{animation:fadeIn .5s ease both}
.anim .hd .crumb{animation:riseIn .65s var(--ease) both}
.anim .hd h1{animation:riseIn .65s var(--ease) both;animation-delay:.04s}
.anim .controls{animation:riseIn .65s var(--ease) both;animation-delay:.09s}
.anim .tbl{animation:fadeIn .6s ease both;animation-delay:.16s}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes riseIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* Crossing to a listing. A name is a link to another document, so the arrival is
   handed to the browser's cross-document view transition rather than faked in JS.
   Deliberately not a cross-fade: the browser's built-in one dissolves the two pages
   through each other, and two pages of dense type are both legible at the midpoint —
   the masthead doubled and offset, one page's tables showing through the other's
   prose. That read as a flicker. So the halves are sequenced instead, and never
   overlap: the old page dissolves to the background, then the new one fades up off
   it, which is the same fade the homepage opens on. Browsers without the API just
   load the page. */
@view-transition{navigation:auto}
@keyframes vt-out{from{opacity:1}to{opacity:0}}
@keyframes vt-in{from{opacity:0}to{opacity:1}}
::view-transition-old(root){animation:vt-out .18s ease both}
::view-transition-new(root){animation:vt-in .32s ease .18s both}
/* @view-transition can't be scoped to .anim — it's a document-level at-rule — so
   reduced motion is honoured by collapsing the fade rather than skipping it */
@media (prefers-reduced-motion:reduce){::view-transition-old(root),::view-transition-new(root){animation-duration:.01ms;animation-delay:0s}}
