/* ============================================================
   Fonts (vendored woff2 — Latin subsets, self-contained)
   Matches the N283T.github.io personal site type system.
   ============================================================ */
@font-face {
  font-family: "Outfit"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../vendor/fonts/outfit-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Outfit"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../vendor/fonts/outfit-latinext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Zen Maru Gothic"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../vendor/fonts/zenmaru-400-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Zen Maru Gothic"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../vendor/fonts/zenmaru-500-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Zen Maru Gothic"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../vendor/fonts/zenmaru-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Japanese body face for the translated page (scripts/build_font_subsets.py).
   It carries its own family name rather than extending "Zen Maru Gothic" with a
   CJK unicode-range: browsers fetch every face of a family that a page
   references, unicode-range or not, which would cost the English page ~1.3 MB it
   never renders. Only html[lang="ja"] puts it in the stack.
   No Japanese counterpart for --font-display: headings, tables and cards are
   English on both pages, so nothing Japanese ever reaches Outfit's fallbacks. */
@font-face {
  font-family: "Zen Maru Gothic JP"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../vendor/fonts/zenmaru-400-jp.woff2") format("woff2");
}
@font-face {
  font-family: "Zen Maru Gothic JP"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("../vendor/fonts/zenmaru-500-jp.woff2") format("woff2");
}
@font-face {
  font-family: "Zen Maru Gothic JP"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("../vendor/fonts/zenmaru-700-jp.woff2") format("woff2");
}
@font-face {
  font-family: "PlemolJP"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("../vendor/fonts/PlemolJP-Regular.woff2") format("woff2");
}

/* ============================================================
   Theme tokens (mirrors N283T.github.io global.css)
   ============================================================ */
:root {
  --color-ink: #3a4257;
  --color-blue: #5b7bb0;
  --color-teal: #7ac4b8;
  --color-coral: #ef9f8c;
  --color-peach: #f7d9cf;
  --color-bg: #fbf7f2;
  --color-surface: #ffffff;
  --color-line: #e7e0d6;

  --bg: var(--color-bg);
  --surface: var(--color-surface);
  --ink: var(--color-ink);
  --muted: #6b7488;
  --line: var(--color-line);

  --font-display: "Outfit", "Klee One", system-ui, sans-serif;
  --font-body: "Zen Maru Gothic", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "PlemolJP", ui-monospace, SFMono-Regular, Menlo, monospace;

  --maxw: 960px;
  /* The header is sticky, so its height decides where the rail hangs, how tall
     the menu panel may be, where a jump has to stop to clear the bar, and
     where the scroll-spy draws its fold line. All five read from here rather
     than repeating a number that has already gone stale once. */
  --header-h: 68px;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --bg: #2b3047;
  --surface: #343a54;
  --ink: #f3eee8;
  --muted: #b8c0d4;
  --line: #3f4663;
  --color-blue: #8fb3df;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html {
  background: var(--bg); color: var(--ink);
  font-size: 17px; scrollbar-gutter: stable;
}
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
body { margin: 0; font-family: var(--font-body); line-height: 1.7; -webkit-font-smoothing: antialiased; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; }
::selection { background: var(--color-peach); color: var(--color-ink); }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }

/* Nothing declared a focus ring, so every control relied on the user agent's.
   That passes today only because color-scheme is set for both themes and the
   browsers invert their default accordingly -- a pass we do not control, and
   one WCAG 2.2's 2.4.11 does not promise.
   --ink and not --color-blue: measured against every surface a ring can land
   on, blue falls to 1.91:1 on a dark .note and coral to 1.88:1 on a light one,
   while ink holds 3.59:1 at its worst and 11.26:1 at its best.
   :focus-visible rather than :focus, so it answers the keyboard and leaves
   mouse clicks alone. */
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ============================================================
   Header
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
}
/* Full bleed: the controls sit against the window, not against the content
   column, so .header-inner brings its own padding instead of using .wrap. */
.header-inner {
  display: flex; align-items: center; gap: 16px;
  height: var(--header-h); padding: 0 20px;
}
.header-links { margin-left: auto; display: flex; align-items: center; gap: 16px; }
.header-links a { display: inline-flex; align-items: center; color: var(--muted); text-decoration: none; transition: color 0.15s ease, transform 0.15s ease; }
.header-links a:hover { color: var(--color-coral); transform: translateY(-1px); }
.header-links svg { display: block; }
.theme-toggle {
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  border-radius: 12px; width: 44px; height: 44px; cursor: pointer; font-size: 17px; flex: none;
}
.theme-toggle:hover { border-color: var(--color-coral); }

/* Header menu (hamburger that drops the table of contents down). Unlike the
   .section-nav rail further down this file, it is offered at every width.
   Everything here stays on the themed --ink / --surface pair rather than the
   raw palette tokens: --color-ink and --color-peach do not flip with the dark
   theme, so text painted in them goes unreadable once the surface darkens. */
/* Stretched to the full bar so the panel's top: 100% means "below the header"
   rather than "below the button", which left it tucked under the bar. */
.nav-menu-wrap { position: relative; align-self: stretch; display: flex; align-items: center; }
.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; flex: none;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 12px; cursor: pointer;
  transition: border-color 0.15s ease;
}
.nav-toggle:hover { border-color: var(--color-coral); }
/* Only the border picks up the accent; the bars keep --ink, since the × they
   form is the state indicator and coral on white is far under 3:1. */
.nav-toggle[aria-expanded="true"] { border-color: var(--color-coral); }
.nav-bars { position: relative; width: 20px; height: 14px; }
.nav-bars span {
  position: absolute; left: 0; width: 100%; height: 2px; border-radius: 2px;
  background: currentColor; transition: transform 0.22s ease, opacity 0.15s ease;
}
.nav-bars span:nth-child(1) { top: 0; }
.nav-bars span:nth-child(2) { top: 6px; }
.nav-bars span:nth-child(3) { top: 12px; }
.nav-toggle[aria-expanded="true"] .nav-bars span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-bars span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* The panel hangs off a sticky header, so it never scrolls out of the way:
   without a max-height its lower entries are unreachable on short viewports. */
.nav-menu {
  position: absolute; top: calc(100% + 10px); left: 0; z-index: 30;
  width: max-content; min-width: 220px; max-width: calc(100vw - 40px);
  max-height: calc(100vh - var(--header-h) - 20px);
  max-height: calc(100dvh - var(--header-h) - 20px);
  overflow-y: auto; overscroll-behavior: contain;
  padding: 10px; border: 1px solid var(--line); border-radius: 16px;
  background: var(--surface);
  box-shadow: 0 14px 34px color-mix(in srgb, var(--color-ink) 18%, transparent);
}
.nav-menu[hidden] { display: none; }
.nm-title {
  margin: 2px 10px 8px; font-family: var(--font-display); font-weight: 800;
  font-size: 0.8rem; letter-spacing: .04em; color: var(--muted);
}
.nm-sep { height: 1px; margin: 8px 6px; border: 0; background: var(--line); }
.nm-link {
  display: flex; align-items: baseline; gap: 10px;
  padding: 6px 10px; border-radius: 10px;
  font-size: 0.95rem; line-height: 1.4; color: var(--ink); text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease;
}
/* Both states tint the surface and leave the label on --ink, so the text keeps
   its contrast in either theme. Current is bold as well as tinted — never
   colour alone. */
.nm-link:hover { background: color-mix(in srgb, var(--ink) 9%, transparent); }
.nm-num {
  flex: none; width: 1.1em;
  font-family: var(--font-display); font-weight: 700; font-size: 0.86rem;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.nm-link.is-active { background: color-mix(in srgb, var(--color-blue) 16%, transparent); font-weight: 700; }
.nm-link:hover .nm-num, .nm-link.is-active .nm-num { color: var(--ink); }
/* Sub-sections carry no number, and indent to where the parent's label starts
   (10px padding + 1.1em number + 10px gap). The panel scrolls, so unlike the
   rail it can afford to list every one of them at once. */
.nm-sub { padding-left: 36px; font-size: 0.88rem; color: var(--muted); }
.nm-sub.is-active { color: var(--ink); }

/* Section nav (fixed on-page map with scroll-spy, wide screens only) */
.section-nav { display: none; }
@media (min-width: 1300px) {
  .section-nav {
    display: flex; flex-direction: column; gap: 10px;
    position: fixed; top: calc(var(--header-h) + 60px); left: calc(50% + 31rem); z-index: 20;
    /* Only one section's children are ever open, so the rail tops out at 16
       rows. This is the backstop for a short window: the rail is fixed, so
       anything past the fold would otherwise be unreachable. */
    max-height: calc(100vh - 140px); overflow-y: auto;
  }
}
/* Sat at 14px in --muted, which reads as faint at the far edge of a wide
   screen. Nudged up and darkened part of the way to --ink, still short of the
   body text so the rail stays secondary. */
.sn-link {
  display: flex; align-items: center; gap: 11px;
  font-size: 15px; color: color-mix(in srgb, var(--muted) 55%, var(--ink));
  text-decoration: none;
  transition: color 0.15s ease;
}
.sn-link span:last-child { white-space: nowrap; }
.sn-link:hover { color: var(--color-coral); }
.sn-dot { flex: none; height: 1px; width: 16px; background: var(--line); transition: all 0.2s ease; }
.sn-link:hover .sn-dot { background: var(--color-coral); }
/* Current is weighted as well as darkened; the rest of the rail is close
   enough in colour now that the shift alone would be easy to miss. */
.sn-link.is-active { color: var(--ink); font-weight: 700; }
.sn-link.is-active .sn-dot { width: 24px; height: 2px; background: var(--color-coral); }
/* Sub-sections. The dash shortens but keeps its 16px slot, so the labels stay
   on the parent's left edge and the rail does not grow wider — it has only
   ~25px of room before it reaches the window edge at 1300px. */
.sn-link[hidden] { display: none; }
.sn-sub { font-size: 13px; }
.sn-sub .sn-dot { width: 9px; margin-left: 7px; }
.sn-sub.is-active .sn-dot { width: 14px; margin-left: 2px; }

/* ============================================================
   Hero
   ============================================================ */
.hero { padding: 60px 0 30px; }
.eyebrow { font-family: var(--font-display); color: var(--color-blue); font-weight: 600; letter-spacing: .03em; text-transform: uppercase; font-size: 13px; margin: 0 0 12px; }
h1 { font-size: clamp(1.9rem, 4.6vw, 3rem); line-height: 1.12; margin: 0 0 18px; letter-spacing: -0.01em; position: relative; }
h1::after {
  content: ""; display: block; height: 4px; width: 3rem; margin-top: 0.6rem;
  border-radius: 99px; background: linear-gradient(90deg, var(--color-coral), var(--color-peach));
}
.lede { font-size: 1.1rem; color: var(--muted); max-width: 64ch; margin: 18px 0 28px; }
.result-cards { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 28px; }
.result-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  padding: 16px 22px; display: flex; flex-direction: column; gap: 3px; min-width: 150px;
}
.rc-label { font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.rc-rank { font-family: var(--font-display); font-size: 1.8rem; font-weight: 800; color: var(--color-blue); }
.rc-metric { font-size: .92rem; color: var(--muted); font-variant-numeric: tabular-nums; }
/* The three ranks are a comparison, so they stay a row on a phone rather than
   stacking into three unrelated cards. min-width: 0 lets them share the width
   the 150px floor would otherwise refuse to give up, and the type comes down
   to fit what is left. */
@media (max-width: 560px) {
  .result-cards { gap: 8px; }
  .result-card { flex: 1; min-width: 0; padding: 12px 9px; gap: 2px; }
  .rc-label { font-size: 9.5px; letter-spacing: .03em; }
  .rc-rank { font-size: 1.3rem; }
  .rc-metric { font-size: .72rem; }
}
.btn {
  display: inline-block; font-family: var(--font-display); font-weight: 600;
  background: var(--color-blue); color: #fff; text-decoration: none;
  padding: 10px 18px; border-radius: 12px; font-size: .95rem; border: 1px solid transparent;
  transition: transform .18s ease, box-shadow .18s ease;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--color-blue) 22%, transparent);
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 12px 26px color-mix(in srgb, var(--color-blue) 30%, transparent); }
.btn.ghost { background: transparent; color: var(--color-blue); border-color: var(--line); box-shadow: none; }
.btn.ghost:hover { border-color: var(--color-coral); }

/* ============================================================
   Sections
   ============================================================ */
/* The header is sticky, so anything scrolled to by id has to stop clear of it
   or it lands underneath. This covered sections only, which was enough while
   they were the only jump targets; the sub-headings in the nav and the table
   anchors linked from the prose need it too. They need more of it: a section
   has 40px of padding to push its h2 down, and a bare h3 has none, so the
   header height alone would leave it hard against the bar. Both stay under
   the scroll-spy's fold line (--header-h + 52px), or arriving somewhere would
   fail to mark it. main#top carries it too: main starts below the header, so
   without it the Top link stops one header down the page with the hero flush
   against the bar, rather than at the top of the document. */
main [id], main#top { scroll-margin-top: calc(var(--header-h) + 38px); }
main section { padding: 40px 0; }
/* Qualified so it outweighs the attribute selector above, which would
   otherwise move every section jump 24px further down the page. */
main section[id] { scroll-margin-top: calc(var(--header-h) + 14px); }
main section + section { border-top: 1px solid var(--line); }
h2 { font-size: 1.55rem; margin: 0 0 16px; letter-spacing: -0.01em; display: flex; align-items: center; gap: 0.5rem; }
h2::before { content: "\2726"; color: var(--color-coral); font-size: 0.68em; }
h3 { font-size: 1.02rem; margin: 0 0 6px; font-family: var(--font-display); }
p { margin: 0 0 14px; }
ul, ol { margin: 0 0 14px; padding-left: 22px; }
li { margin-bottom: 6px; }
a { color: var(--color-blue); text-underline-offset: 2px; }
strong { font-weight: 700; }
code {
  font-family: var(--font-mono); background: var(--surface); border: 1px solid var(--line);
  border-radius: 5px; padding: 0.1em 0.4em; font-size: .86em;
}
pre {
  margin: 0 0 14px; padding: 12px 14px; overflow-x: auto;
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px;
}
pre code { background: none; border: 0; padding: 0; font-size: .84em; line-height: 1.55; }
/* Back for the Japanese page only, which is the only one with a deck to point
   at. #32 removed the original .hero-links because both of its buttons went
   somewhere the navigation already reached; the deck is not in the navigation
   at all, and is a different way to read the whole report rather than a jump
   within it. */
/* 24 + the hero's 30px of padding + #tldr's 40px puts the TL;DR heading 94px
   below the button, matching the 95px #32 settled on between any two sections. */
.hero-links { display: flex; gap: 12px; flex-wrap: wrap; margin: 0 0 24px; }

/* The one .btn on either page with Japanese in its label, so it steps off
   --font-display: that stack is Outfit over system-ui with no Japanese face
   behind it, by the design set out above the @font-face block. */
.hero-links .btn { font-family: var(--font-body); font-weight: 700; }

.official-links { display: flex; gap: 12px; flex-wrap: wrap; margin: 4px 0 18px; }

/* ============================================================
   Buterez et al.: the paper card and its six strategies
   ============================================================ */
.paper-card {
  border: 1px solid var(--line); border-left: 4px solid var(--color-coral);
  border-radius: 12px; padding: 14px 18px; margin: 4px 0 18px; background: var(--surface);
}
:root[data-theme="dark"] .paper-card { background: #3b4263; }
.paper-card__title { font-family: var(--font-display); font-weight: 700; margin: 0 0 4px; line-height: 1.45; }
.paper-card__meta { margin: 0; font-size: .84rem; color: var(--muted); }

/* The paper's setting: a cheap screen feeding a small confirmatory assay. */
.cascade { display: flex; align-items: stretch; gap: 12px; margin: 6px 0 10px; }
.cascade__tier {
  flex: 1; display: flex; flex-direction: column; gap: 3px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 12px 15px;
}
:root[data-theme="dark"] .cascade__tier { background: #3b4263; }
.cascade__tier.is-hf { border-color: var(--color-coral); }
.cascade__tag {
  font-family: var(--font-display); font-size: .62rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--color-blue);
}
.cascade__tier.is-hf .cascade__tag { color: var(--color-coral); }
.cascade__what { font-weight: 700; font-size: .95rem; }
.cascade__note { font-size: .8rem; color: var(--muted); line-height: 1.5; }
.cascade__arrow {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 2px; text-align: center; max-width: 150px;
}
.cascade__mark { font-size: 1.5rem; color: var(--muted); line-height: 1; }
.cascade__ask { margin: 0 0 16px; }
@media (max-width: 640px) {
  .cascade { flex-direction: column; }
  .cascade__mark { transform: rotate(90deg); }
}

/* The six strategies read as a set, so they sit in a grid rather than a list.
   The circled numbers are drawn rather than typed: the report vendors a subset
   font, and the enclosed-numeral glyphs are not in it. */
.strat-grid {
  list-style: none; display: grid; grid-template-columns: 1fr 1fr;
  gap: 10px; margin: 0 0 8px; padding: 0;
}
.strat {
  display: flex; align-items: center; gap: 10px; margin: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px;
}
:root[data-theme="dark"] .strat { background: #3b4263; }
.strat__n, .strat-ref {
  flex: 0 0 auto; display: inline-grid; place-items: center;
  width: 23px; height: 23px; border-radius: 999px;
  background: var(--color-blue); color: #fff;
  font-family: var(--font-display); font-weight: 800; font-size: .78rem; line-height: 1;
}
.strat__body { flex: 1; font-size: .9rem; line-height: 1.5; }
.strat__count {
  flex: 0 0 auto; font-family: var(--font-display); font-weight: 700; font-size: .95rem;
  color: var(--muted); font-variant-numeric: tabular-nums;
}
/* The two the report went on to use. */
.strat.is-picked { border-color: var(--color-coral); }
.strat.is-picked .strat__n { background: var(--color-coral); }
.strat.is-picked .strat__count { color: var(--color-coral); }
.strat-ref { vertical-align: -.2em; margin-right: 7px; }
.strat-ref.coral { background: var(--color-coral); }
@media (max-width: 640px) { .strat-grid { grid-template-columns: 1fr; } }

/* Language switch (English page <-> Japanese page) */
.lang-switch {
  font-family: var(--font-display); font-weight: 600; font-size: 12px; letter-spacing: .02em;
  color: var(--muted); text-decoration: none; border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 10px; white-space: nowrap;
}
.lang-switch:hover { color: var(--ink); border-color: var(--color-blue); }

/* Japanese page: append the CJK face to the body stack (Latin still resolves to
   Zen Maru Gothic first), then tighten punctuation and open up the leading a
   little. Running text only — the headings and the lede are English on both
   pages, so they keep the shared leading and the two pages stay identical. */
html[lang="ja"] {
  --font-body: "Zen Maru Gothic", "Zen Maru Gothic JP", system-ui, -apple-system, "Segoe UI", sans-serif;
}
html[lang="ja"] body { font-feature-settings: "palt" 1; }
html[lang="ja"] p:not(.lede), html[lang="ja"] li { line-height: 1.9; }
/* Zen Maru Gothic is a rounded gothic and sets a visibly smaller face than
   Outfit or the system stack at the same size; palt then pulls it in further.
   A step up on the running text only, so .lede, .note and every heading, card
   and table keep their own rem sizes and the two pages stay comparable. */
html[lang="ja"] p:not(.lede):not(.note), html[lang="ja"] li { font-size: 1.06rem; }

/* Member roster table (aliases) */
/* 560px was under what these tables need: the widest of them wants 947px, so
   at 560 the descriptive columns collapsed to roughly a word per line and the
   tallest row reached 181px on a phone, while still scrolling sideways. 680
   halves that with no extra scrolling, since the widest table already forces
   688px on its own. Inert above 680px of container, where width: 100% wins. */
.roster-table {
  width: 100%; min-width: 680px; border-collapse: collapse;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--color-blue) 10%, transparent);
}
:root[data-theme="dark"] .roster-table { background: #3b4263; }
.roster-table th, .roster-table td { padding: 9px 16px; text-align: left; font-size: .93rem; }
.roster-table thead th {
  font-family: var(--font-display); font-size: .72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .03em; color: var(--muted);
  background: color-mix(in srgb, var(--color-blue) 12%, var(--surface)); border-bottom: 2px solid var(--line);
}
:root[data-theme="dark"] .roster-table thead th { background: color-mix(in srgb, var(--color-blue) 26%, #3b4263); }
.roster-table tbody th {
  font-family: var(--font-mono); font-weight: 700; color: var(--color-blue); white-space: nowrap;
  border-right: 1px solid var(--line);
}
.roster-table tbody td { color: var(--muted); }
.roster-table tbody tr + tr th, .roster-table tbody tr + tr td { border-top: 1px solid var(--line); }
.roster-table td.c { text-align: center; }
.roster-table .fam-tabular { color: var(--color-blue); font-weight: 600; }
.roster-table .fam-embed { color: #3f9e8b; font-weight: 600; }
.roster-table .fam-structural { color: var(--color-coral); font-weight: 600; }
.roster-table .yes { color: #3f9e8b; font-weight: 700; }
.roster-table .no { color: var(--color-coral); font-weight: 800; }
/* Partial coverage: the count of rows that carry the column, not all of them. */
.roster-table .part { color: var(--muted); font-variant-numeric: tabular-nums; }
.roster-table td.num, .roster-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.roster-table .no-strat { color: var(--muted); }
.roster-table td .strat-ref { margin-right: 0; }
/* The log2fc columns are the signal the whole approach leans on, so they read as
   one coral-tinted group rather than as two more columns that happen to exist. */
.roster-table td.aux { background: color-mix(in srgb, var(--color-coral) 15%, transparent); }
.roster-table thead th.aux {
  background: color-mix(in srgb, var(--color-coral) 24%, transparent);
  color: #b35f47;
}
.roster-table td.aux .part { color: var(--ink); font-weight: 700; }
:root[data-theme="dark"] .roster-table thead th.aux {
  background: color-mix(in srgb, var(--color-coral) 30%, #3b4263); color: #f4b7a3;
}

/* Boltz pooled-vector composition strip (mimics the 1024-d block diagram) */
.vblocks { display: flex; flex-direction: column; gap: 8px; margin: 16px 0 6px; }
.vblock-row { display: flex; align-items: center; gap: 12px; }
.vblock-name { width: 84px; flex-shrink: 0; text-align: right; font-family: var(--font-mono); font-weight: 700; font-size: .84rem; color: var(--ink); }
.vblock-bar { display: flex; flex: 1; height: 40px; border-radius: 8px; overflow: hidden; border: 1px solid var(--line); }
.vblock-seg { display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; font-size: .72rem; font-weight: 600; line-height: 1.15; text-align: center; padding: 0 4px; }
.vblock-seg small { font-weight: 500; opacity: .82; font-size: .64rem; }
.vb-sprot { background: var(--color-blue); }
.vb-slig { background: var(--color-coral); }
.vb-zmean { background: var(--color-teal); }
.vb-zmax { background: color-mix(in srgb, var(--color-teal) 55%, #fff); color: var(--ink); }
.vblocks-note { font-size: .82rem; color: var(--muted); margin: 4px 0 0 96px; }

/* Numeric comparison table (ablation baselines, metrics) */
.table-scroll { overflow-x: auto; margin: 10px 0 6px; -webkit-overflow-scrolling: touch; }
.metric-table {
  width: 100%; min-width: 540px; border-collapse: collapse;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--color-blue) 10%, transparent);
}
:root[data-theme="dark"] .metric-table { background: #3b4263; }
.metric-table th, .metric-table td { padding: 10px 18px; font-variant-numeric: tabular-nums; }
.metric-table thead th {
  font-family: var(--font-display); font-size: .74rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .03em; color: var(--muted); text-align: right;
  background: color-mix(in srgb, var(--color-blue) 12%, var(--surface));
  border-bottom: 2px solid var(--line);
}
:root[data-theme="dark"] .metric-table thead th { background: color-mix(in srgb, var(--color-blue) 26%, #3b4263); }
.metric-table thead th:first-child { text-align: left; }
.metric-table tbody th {
  text-align: left; font-family: var(--font-display); font-weight: 600; color: var(--ink);
  white-space: nowrap; border-right: 1px solid var(--line);
}
.metric-table tbody td { text-align: right; font-weight: 700; color: var(--color-blue); }
.metric-table tbody tr + tr th, .metric-table tbody tr + tr td { border-top: 1px solid var(--line); }

/* Highlighted rows: the pred baselines are the hero of the table.
   Emphasis comes from a coral feature name + accent bar and a light lift,
   not a heavy fill (which muddies on the dark theme). */
.metric-table tbody tr.hi th,
.metric-table tbody tr.hi td { background: color-mix(in srgb, var(--color-peach) 38%, var(--surface)); }
:root[data-theme="dark"] .metric-table tbody tr.hi th,
:root[data-theme="dark"] .metric-table tbody tr.hi td { background: color-mix(in srgb, var(--color-coral) 13%, #3b4263); }
.metric-table tbody tr.hi th {
  color: var(--color-coral); font-weight: 700; border-left: 3px solid var(--color-coral);
}
.metric-table tbody tr.hi td { color: var(--ink); font-weight: 700; }

/* Reference row: de-emphasized. */
.metric-table tbody tr.ref th,
.metric-table tbody tr.ref td {
  color: var(--muted); font-weight: 500; background: transparent;
  border-top: 2px solid var(--line);
}
.metric-table tbody tr.ref th { font-style: italic; }

.pipeline {
  font-family: var(--font-display); font-size: 1.02rem; line-height: 1.9; color: var(--ink);
  background: color-mix(in srgb, var(--color-teal) 12%, var(--surface));
  border-left: 3px solid var(--color-teal);
  padding: 12px 16px; border-radius: 10px; margin: 10px 0 18px;
}

.spec-table {
  width: 100%; border-collapse: collapse; margin: 8px 0 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden; box-shadow: 0 6px 18px color-mix(in srgb, var(--color-blue) 12%, transparent);
}
:root[data-theme="dark"] .spec-table { background-color: #3b4263; box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.spec-table th, .spec-table td { text-align: left; padding: 10px 16px; vertical-align: baseline; }
.spec-table thead th {
  font-family: var(--font-display); font-size: .74rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); background: color-mix(in srgb, var(--color-blue) 8%, var(--surface));
}
:root[data-theme="dark"] .spec-table thead th { background: color-mix(in srgb, var(--color-blue) 16%, #3b4263); }
.spec-table tbody th {
  font-family: var(--font-display); font-weight: 600; color: var(--ink); white-space: nowrap;
}
.spec-table td.val {
  font-weight: 700; font-size: 1.05rem; color: var(--color-blue);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.spec-table td:last-child { color: var(--muted); font-size: .92rem; }
.spec-table tbody tr + tr th, .spec-table tbody tr + tr td { border-top: 1px solid var(--line); }
@media (max-width: 560px) {
  .spec-table thead { display: none; }
  .spec-table tbody th, .spec-table td { display: block; width: auto; white-space: normal; padding: 2px 16px; }
  .spec-table tbody th { padding-top: 12px; }
  .spec-table td.val { font-size: 1.15rem; }
  .spec-table td:last-child { padding-bottom: 12px; }
  .spec-table tbody tr + tr th { border-top: 1px solid var(--line); }
  .spec-table tbody tr + tr td { border-top: none; }
}
.note {
  background: color-mix(in srgb, var(--color-peach) 40%, var(--surface));
  border-left: 3px solid var(--color-coral);
  padding: 12px 16px; border-radius: 10px; color: var(--ink); font-size: .96rem;
}

/* ============================================================
   Soft cards (feature grid, result cards share the treatment)
   ============================================================ */
.soft-card, .result-card, .feature-cell {
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--color-blue) 14%, transparent);
}
:root[data-theme="dark"] .result-card,
:root[data-theme="dark"] .feature-cell { background-color: #3b4263; box-shadow: 0 6px 18px rgba(0,0,0,.35); }

.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px; margin: 18px 0; }
.feature-cell { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 18px; }
.feature-cell:hover { transform: translateY(-4px); box-shadow: 0 14px 30px color-mix(in srgb, var(--color-blue) 24%, transparent); }
.feature-cell.hi { border-color: var(--color-coral); background: color-mix(in srgb, var(--color-peach) 34%, var(--surface)); }
.feature-cell h3 { color: var(--color-blue); }
.feature-cell p { margin: 0; color: var(--muted); font-size: .92rem; }

/* ============================================================
   Charts
   ============================================================ */
/* Results: concise summary with per-phase stat cards */
.phase-block {
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
  padding: 18px 20px; margin: 16px 0;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--color-blue) 12%, transparent);
}
:root[data-theme="dark"] .phase-block { background-color: #3b4263; box-shadow: 0 6px 18px rgba(0,0,0,.35); }
/* Wraps between its items now that the badges inside it will not break: with
   the row still nowrap, keeping the pills whole would push them off the card
   on a phone. */
.phase-block h3 { font-size: 1.12rem; margin: 0 0 4px; color: var(--ink); display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
/* A pill has to stay on one line or it stops reading as a pill: "post-challenge"
   was breaking at its hyphen into a two-line lozenge, and the phase headings
   were splitting "AS1 + AS2 (513)" across three. The label moves to the next
   line whole instead. inline-block so the padding belongs to one box. */
.badge {
  display: inline-block; white-space: nowrap;
  font-family: var(--font-display); font-size: .64rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em;
  color: #fff; background: var(--color-coral); padding: 3px 9px; border-radius: 999px;
}
/* Secondary badge: sits next to a coral one without competing with it. */
.badge.soft { color: var(--muted); background: transparent; border: 1px solid var(--line); }
/* Marks an analysis run after the challenge closed, on labels nobody had at the
   time. It is not evidence of how the model was built. */
.badge.post { background: var(--color-blue); }
/* Overall standing for a scoring round, pushed to the end of its h3. */
.phase-rank {
  margin-left: auto; font-family: var(--font-display); font-size: .72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em; color: var(--muted); white-space: nowrap;
}
.phase-rank b { font-size: 1.15rem; font-weight: 800; color: var(--color-blue); letter-spacing: 0; }
.phase-eval { color: var(--muted); font-size: .9rem; margin: 0 0 14px; }
.stat-strip { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.stat {
  background: color-mix(in srgb, var(--color-blue) 6%, var(--surface));
  border: 1px solid var(--line); border-radius: 12px; padding: 11px 8px;
  display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center;
}
:root[data-theme="dark"] .stat { background: color-mix(in srgb, var(--color-blue) 14%, #3b4263); }
.stat-l { font-size: .72rem; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.stat-v { font-family: var(--font-display); font-weight: 800; font-size: 1.2rem; color: var(--color-blue); font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat-r { font-size: .72rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.stat-r b { color: var(--color-coral); font-weight: 700; }
.metrics-key { color: var(--muted); font-size: .84rem; margin: 6px 0 8px; }
@media (max-width: 620px) {
  .stat-strip { grid-template-columns: repeat(3, 1fr); }
  /* Three across leaves 75px inside a cell and "Spearman ρ" wanted 79px, so
     the ρ dropped to a line of its own. Tighter padding and type buy it back;
     nowrap then keeps the symbol with the name it belongs to. */
  .stat { padding: 11px 6px; }
  .stat-l { font-size: .64rem; letter-spacing: .02em; white-space: nowrap; }
}

#strategy h3 { font-size: 1.16rem; margin: 26px 0 8px; color: var(--ink); }
#members h3 { font-size: 1.16rem; margin: 28px 0 8px; color: var(--ink); }
h4 { font-family: var(--font-display); font-size: 1rem; font-weight: 700; color: var(--color-blue); margin: 20px 0 4px; }
.metric-table td.bk { text-align: left; font-weight: 500; color: var(--muted); white-space: nowrap; }
.metric-table thead th.bk { text-align: left; }

/* Understated aside (optional side-notes) */
.aside { border-left: 3px solid var(--line); padding: 2px 0 2px 16px; margin: 18px 0; }
.aside p { font-size: .9rem; color: var(--muted); }
.aside .metric-table { min-width: 380px; box-shadow: none; background: transparent; }
:root[data-theme="dark"] .aside .metric-table { background: transparent; }
.aside .metric-table thead th { background: transparent; color: var(--muted); }
.aside .metric-table tbody th { color: var(--muted); font-weight: 500; }
.aside .metric-table tbody td { color: var(--muted); font-weight: 600; }
.viz-label { font-family: var(--font-display); font-weight: 700; font-size: .95rem; color: var(--color-blue); margin: 18px 0 6px; }
.cov-table td.cov0 { color: var(--muted); font-weight: 500; }

.scatter-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
/* The predicted panels are the point of the figure; the observed ones are what
   they are being compared against. Boxing the pair says which is which before
   the caption does. Every panel carries the same border and padding so that all
   four canvases come out the same size — ECharts measures the content box — and
   only the highlighted pair has them coloured in. */
.scatter-grid .chart {
  border: 1px solid transparent; border-radius: 12px; padding: 8px 8px 4px;
}
.scatter-grid .is-pick {
  border-color: var(--color-coral);
  background: color-mix(in srgb, var(--color-coral) 5%, transparent);
}
@media (max-width: 640px) { .scatter-grid { grid-template-columns: 1fr; } }

.chart-figure { margin: 22px 0 4px; }
/* A drawn figure rather than a chart. The artwork is transparent and carries
   its own panels, so it needs no frame and sits on either theme. */
.figure-img { display: block; width: 100%; height: auto; }
/* Charts sit directly on the page, no card chrome. */
/* min-width: 0 because the scatter charts are grid items, where the default
   min-width: auto refuses to shrink below the content. echarts leaves a sized
   wrapper inside, so on a narrowing window the container was held open at its
   old width, and resize() then measured that stale width and kept it. */
.chart { width: 100%; min-width: 0; }
.chart + .chart { margin-top: 6px; }
figcaption { color: var(--muted); font-size: .88rem; margin-top: 10px; padding: 0 4px; }

/* ============================================================
   Footer
   ============================================================ */
.site-footer { padding: 34px 0; color: var(--muted); font-size: .9rem; border-top: 1px solid var(--line); }

@media (max-width: 640px) {
  .hero { padding-top: 40px; }
}
@media (prefers-reduced-motion: reduce) {
  .btn, .feature-cell, .result-card, .chart, .nav-bars span { transition: none; }
  .btn:hover, .feature-cell:hover { transform: none; }
}
