/* ═══════════════════════════════════════════════════════════════════
   site.css — FIRST LIGHT
   One design system for every page.

   The thesis: George's day starts at 5:30 on dark water. The site opens in
   that blue hour and is lit, everywhere after, by the first warm light.
     night  the blue hour before dawn   (default follows the OS)
     day    the haze after sunrise
   Each world carries its own accent so a reader always knows where they are:
     robotics  carbon pink   rowing  first light   debate  ember
     research  volt          tools   prism         record  medal gold
     community jade
   Tokens live in :root (night) and [data-theme="light"] (day). Every colour
   change is made in both blocks.
   ═════════════════════════════════════════════════════════════════ */

/* ── 0. faces (self-hosted variable fonts; no CDN reaches China) ────
   Archivo and Chivo Mono (Omnibus-Type, SIL Open Font License 1.1).
   Archivo carries a width axis: expanded for display lettering, semi-
   condensed for labels and numerals, normal for reading. */
@font-face { font-family: 'Archivo'; font-style: italic; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap;
  src: url(../../fonts/archivo-italic-latin-ext.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: 'Archivo'; font-style: italic; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap;
  src: url(../../fonts/archivo-italic-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: 'Archivo'; font-style: normal; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap;
  src: url(../../fonts/archivo-latin-ext.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: 'Archivo'; font-style: normal; font-weight: 100 900; font-stretch: 62% 125%; font-display: swap;
  src: url(../../fonts/archivo-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: 'Chivo Mono'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url(../../fonts/chivo-mono-latin-ext.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: 'Chivo Mono'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url(../../fonts/chivo-mono-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; }

/* ── 1. tokens ──────────────────────────────────────────────────── */
/* The night ground. By day it is also worn by whatever sits on a dark
   picture: blocks set on the home lake (.on-night), and the nav while it
   floats over one (site.js sets .over-picture; the home page starts so). */
:root,
[data-theme="light"] .on-night,
[data-theme="light"] body[data-world="home"] .nav:not(.is-scrolled),
[data-theme="light"] .nav.over-picture {
  color-scheme: dark;
  /* ground: the blue hour */
  --bg:        #080c17;
  --bg-deep:   #05070e;
  --bg-raise:  #0d1322;
  --bg-raise2: #131a2c;
  --text:      #e8ebf2;
  --text-2:    #b0b7c8;
  --text-3:    #7d869d;
  --line:      rgba(214, 222, 240, 0.11);
  --line-2:    rgba(214, 222, 240, 0.22);
  --glass:     rgba(8, 12, 23, 0.62);
  --scrim:     rgba(5, 7, 14, 0.82);
  --shadow:    0 30px 80px -30px rgba(0, 0, 0, 0.75);
  --grain-op:  0.035;

  /* the one light, and the worlds it falls on */
  --dawn:      #ffb46a;
  --ember:     #ff6a45;
  --w-robotics: #ff7ac8;
  --w-rowing:   #ffb46a;
  --w-debate:   #ff6a45;
  --w-research: #7fd8ff;
  --w-tools:    #b3a4ff;
  --w-record:   #f4c56c;
  --w-community:#7fdcb5;
  --accent:    var(--dawn);
  --accent-gl: 1.0 0.706 0.416;       /* same colour, 0..1, for the shaders */
  --on-accent: #0a0d18;
  --text-rgb: 232, 235, 242;
  --bg-rgb: 8, 12, 23;
  --accent-rgb: 255, 180, 106;

  /* type */
  --f-disp: 'Archivo', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
  --f-sans: 'Archivo', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans SC', system-ui, sans-serif;
  --f-serif: var(--f-disp);            /* retired: emphasis is the same family's italic */
  --f-mono: 'Chivo Mono', ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;
  --wd-disp: 116%;                     /* display lettering, like the drawing's title block */
  --wd-label: 88%;                     /* labels and numerals, like a results board */

  --step--1: clamp(13px, 0.78rem + 0.1vw, 14px);
  --step-0:  clamp(16.5px, 0.96rem + 0.2vw, 18px);
  --step-1:  clamp(19px, 1.04rem + 0.5vw, 23px);
  --step-2:  clamp(23px, 1.1rem + 1vw, 31px);
  --step-3:  clamp(30px, 1.2rem + 2vw, 46px);
  --step-4:  clamp(38px, 1.2rem + 3.6vw, 76px);
  --step-5:  clamp(46px, 1.2rem + 5.4vw, 96px);

  /* space + shape */
  --mx: clamp(20px, 5.2vw, 96px);
  --maxw: 1520px;
  --gap: clamp(16px, 2vw, 32px);
  --sec: clamp(96px, 12vw, 208px);
  --r-pill: 0;                         /* one shape system: everything is cut square */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);   /* presses and quick replies */
  --ease-img: cubic-bezier(0.22, 1, 0.36, 1);
}
/* on :root alone: the block above is also worn by the nav over a picture,
   and a height declared there would undo the touch-screen bar's (below) */
:root { --nav-h: 72px; }

[data-theme="light"] {
  color-scheme: light;
  /* ground: morning haze */
  --bg:        #edf0f4;
  --bg-deep:   #e2e7ee;
  --bg-raise:  #f7f8fa;
  --bg-raise2: #ffffff;
  --text:      #0b1020;
  --text-2:    #394256;
  --text-3:    #596276;
  --line:      rgba(11, 16, 32, 0.11);
  --line-2:    rgba(11, 16, 32, 0.22);
  --glass:     rgba(237, 240, 244, 0.72);
  --scrim:     rgba(8, 12, 23, 0.72);
  --shadow:    0 30px 70px -34px rgba(11, 16, 32, 0.35);
  --grain-op:  0.03;

  --dawn:      #b15913;
  --ember:     #c6391c;
  --w-robotics: #b8237a;
  --w-rowing:   #a8560f;
  --w-debate:   #c23a1c;
  --w-research: #0a75a1;
  --w-tools:    #5543c8;
  --w-record:   #8f5e08;
  --w-community:#177a55;
  --on-accent: #ffffff;
  --text-rgb: 11, 16, 32;
  --bg-rgb: 237, 240, 244;
  --accent-rgb: 177, 89, 19;
}

/* worlds: one attribute on <body> recolours the page and its scene */
[data-world="robotics"]  { --accent: var(--w-robotics);  --accent-gl: 1.0 0.478 0.784; }
[data-world="rowing"]    { --accent: var(--w-rowing);    --accent-gl: 1.0 0.706 0.416; }
[data-world="debate"]    { --accent: var(--w-debate);    --accent-gl: 1.0 0.416 0.271; }
[data-world="research"]  { --accent: var(--w-research);  --accent-gl: 0.498 0.847 1.0; }
[data-world="tools"]     { --accent: var(--w-tools);     --accent-gl: 0.702 0.643 1.0; }
[data-world="record"]    { --accent: var(--w-record);    --accent-gl: 0.957 0.773 0.424; }
[data-world="community"] { --accent: var(--w-community); --accent-gl: 0.498 0.863 0.710; }
[data-world="home"]      { --accent: var(--dawn); }
[data-world="robotics"]  { --accent-rgb: 255, 122, 200; }
[data-world="rowing"]    { --accent-rgb: 255, 180, 106; }
[data-world="debate"]    { --accent-rgb: 255, 106, 69; }
[data-world="research"]  { --accent-rgb: 127, 216, 255; }
[data-world="tools"]     { --accent-rgb: 179, 164, 255; }
[data-world="record"]    { --accent-rgb: 244, 197, 108; }
[data-world="community"] { --accent-rgb: 127, 220, 181; }
[data-theme="light"] [data-world="robotics"], [data-theme="light"][data-world="robotics"], [data-theme="light"] body[data-world="robotics"]   { --accent-rgb: 184, 35, 122; }
[data-theme="light"] body[data-world="rowing"]    { --accent-rgb: 168, 86, 15; }
[data-theme="light"] body[data-world="debate"]    { --accent-rgb: 194, 58, 28; }
[data-theme="light"] body[data-world="research"]  { --accent-rgb: 10, 117, 161; }
[data-theme="light"] body[data-world="tools"]     { --accent-rgb: 85, 67, 200; }
[data-theme="light"] body[data-world="record"]    { --accent-rgb: 143, 94, 8; }
[data-theme="light"] body[data-world="community"] { --accent-rgb: 23, 122, 85; }

/* Legacy token bridge. Demo CSS ported from the pre-redesign pages speaks the
   old names (paper/ink/seal, rgba(var(--seal-rgb), a)); inside .legacy they
   resolve to this system, so a ported demo re-themes itself in both modes. */
.legacy {
  --paper: var(--bg-raise); --paper-2: var(--bg-raise2); --paper-3: var(--bg-deep);
  --ink: var(--text); --ink-soft: var(--text-2); --ink-mute: var(--text-3);
  --rule: var(--line); --rule-2: var(--line-2);
  --seal: var(--accent); --seal-dp: var(--accent); --seal-rgb: var(--accent-rgb);
  --gold: var(--accent); --gold-lt: color-mix(in srgb, var(--accent) 55%, transparent);
  --cream: var(--text); --muted: var(--text-3); --border: var(--line);
  --bg-card: var(--bg-deep);
  --ink-rgb: var(--text-rgb); --paper-rgb: var(--bg-rgb);
  --font-disp: var(--f-disp); --font-body: var(--f-sans); --font-serif: var(--f-serif);
  --disp: var(--f-disp); --serif: var(--f-serif); --sans: var(--f-sans);
  --blue: var(--w-research);
}
/* per-element worlds for mixed lists (timeline tracks, menu, cards) */
.w-robotics  { --accent: var(--w-robotics); }
.w-rowing    { --accent: var(--w-rowing); }
.w-debate    { --accent: var(--w-debate); }
.w-research  { --accent: var(--w-research); }
.w-tools     { --accent: var(--w-tools); }
.w-record    { --accent: var(--w-record); }
.w-community { --accent: var(--w-community); }
.w-plain     { --accent: var(--text-2); }
.w-home      { --accent: var(--dawn); }

/* ── 2. base ────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--nav-h) + 24px); }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 var(--step-0)/1.64 var(--f-sans);
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  transition: background-color 0.6s var(--ease), color 0.6s var(--ease);
}
/* film grain over everything: static, so it costs one layer and no frames */
body::after {
  content: ''; position: fixed; inset: -50%; z-index: 90; pointer-events: none;
  opacity: var(--grain-op);
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 220 220' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 220px 220px;
  mix-blend-mode: overlay;
}
[data-theme="light"] body::after { mix-blend-mode: multiply; }
img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
p { margin: 0; }
h1, h2, h3, h4, h5 { margin: 0; font-weight: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
figure { margin: 0; }
blockquote { margin: 0; }
strong, b { font-weight: 600; color: var(--text); }
code { font-family: var(--f-mono); font-size: 0.84em; padding: 0.1em 0.4em; background: var(--bg-raise2); border: 1px solid var(--line); }
::selection { background: color-mix(in srgb, var(--accent) 36%, transparent); color: var(--text); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
[hidden] { display: none !important; }

.skip {
  position: fixed; left: 16px; top: 12px; z-index: 200;
  padding: 10px 16px;
  background: var(--accent); color: var(--on-accent); font-weight: 600; font-size: 14px;
  transform: translateY(-160%); opacity: 0; pointer-events: none;   /* parked above the page it would show under a phone's status bar */
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.skip:focus { transform: none; opacity: 1; pointer-events: auto; }
.sr-only { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ── 3. type ─────────────────────────────────────────────────────── */
.display, .h-disp {
  font-family: var(--f-disp);
  font-weight: 680;
  font-stretch: var(--wd-disp);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--text);
  text-wrap: balance;
}
.display { font-size: var(--step-4); }
.display-xl { font-size: var(--step-5); line-height: 0.96; }
.display-m { font-size: var(--step-3); line-height: 1.04; }
/* the accent word: the same letters leaning into first light, never a second family */
.display em, .h-disp em, .phero-title em, .quote em, .title-em em {
  font-family: inherit;
  font-style: italic;
  font-weight: inherit;
  letter-spacing: inherit;
  color: var(--accent);
}
.display strong { font-weight: inherit; color: inherit; }

/* labels: sentence case, semi-condensed; a caption, not a shouted kicker */
.eyebrow, .label {
  display: inline-flex; align-items: center; gap: 0.6em;
  font: 600 var(--step--1)/1.3 var(--f-sans);
  font-stretch: var(--wd-label);
  letter-spacing: 0.005em;
  color: var(--text-3);
}
.eyebrow.no-rule::before { display: none; }
.lead { font-size: var(--step-1); line-height: 1.55; color: var(--text); letter-spacing: -0.005em; text-wrap: pretty; }
.prose { max-width: 66ch; }
.prose > * + * { margin-top: 1.25em; }
.prose p, .body-text { color: var(--text-2); text-wrap: pretty; }
.prose p strong, .body-text strong { color: var(--text); font-weight: 600; }
.prose a:not([class]), .body-text a:not([class]), .link {
  color: var(--text);
  background: linear-gradient(var(--accent), var(--accent)) 0 100% / 100% 1px no-repeat;
  padding-bottom: 1px;
  transition: background-size 0.5s var(--ease), color 0.3s;
}
.prose a:not([class]):hover, .body-text a:not([class]):hover, .link:hover { color: var(--accent); background-size: 0 1px; background-position: 100% 100%; }

.quote, .body-quote {
  position: relative;
  font-family: var(--f-sans);
  font-style: italic;
  font-weight: 400;
  font-size: var(--step-2);
  line-height: 1.36;
  letter-spacing: -0.012em;
  color: var(--text);
  padding-left: 1.1em;
  border-left: 1px solid var(--accent);
  text-wrap: balance;
}
.quote-xl { font-size: var(--step-3); line-height: 1.18; border: 0; padding: 0; }
.mono { font-family: var(--f-mono); letter-spacing: 0; }
.num { font-family: var(--f-disp); font-weight: 650; font-stretch: 75%; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }

/* Chinese is not Latin: no tracking, no forced caps, taller leading */
html[lang="zh-CN"] body { line-height: 1.85; }
html[lang="zh-CN"] .eyebrow, html[lang="zh-CN"] .label { letter-spacing: 0.04em; }
html[lang="zh-CN"] .display, html[lang="zh-CN"] .h-disp, html[lang="zh-CN"] .phero-title { letter-spacing: 0; line-height: 1.2; }
html[lang="zh-CN"] .display em, html[lang="zh-CN"] .h-disp em, html[lang="zh-CN"] .phero-title em,
html[lang="zh-CN"] .quote, html[lang="zh-CN"] .body-quote { font-style: normal; letter-spacing: 0; }
html[lang="zh-CN"] .lead { letter-spacing: 0.01em; line-height: 1.75; }
html[lang="zh-CN"] :is(.label, .eyebrow, .chip, .tag, .mono) { font-size: max(12px, var(--step--1)); }

/* ── 4. layout ───────────────────────────────────────────────────── */
.wrap { width: min(100% - 2 * var(--mx), var(--maxw)); margin-inline: auto; }
.wrap-narrow { width: min(100% - 2 * var(--mx), 980px); margin-inline: auto; }
.section { position: relative; padding-block: var(--sec); }
.section + .section { padding-top: 0; }
.section.band { background: var(--bg-deep); padding-top: var(--sec); }
.section.band + .section { padding-top: var(--sec); }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }
.sec-head { display: grid; gap: clamp(18px, 2.4vw, 32px); margin-bottom: clamp(48px, 7vw, 104px); }
.sec-head .display { max-width: 16ch; }
.sec-head .lead { max-width: 52ch; color: var(--text-2); }
/* head then text, stacked: one message per section, never a floating side note */
.sec-head.split { grid-template-columns: minmax(0, 1fr); }
.sec-head.split .lead, .sec-head.split .body-text { max-width: 58ch; }

/* chapter: sticky head left, text right */
.chapter-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: clamp(32px, 6vw, 120px);
  align-items: start;
}
.chapter-head { position: sticky; top: calc(var(--nav-h) + 32px); display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; }
.chapter-head .display { font-size: var(--step-3); line-height: 1.02; }
.chapter-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.45em; }   /* a wide table scrolls in its wrap, never widens the page */
.chapter-body > .quote, .chapter-body > .body-quote { margin-block: 0.8em; }
@media (max-width: 900px) {
  .chapter-grid { grid-template-columns: minmax(0, 1fr); row-gap: 36px; }
  .chapter-head { position: static; }
}
/* a mirrored chapter, head on the right; phones stack it like any other */
@media (min-width: 901px) {
  .chapter-grid.flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .chapter-grid.flip > .chapter-head { order: 2; }
}

/* ── 5. chrome: progress, nav, menu ──────────────────────────────── */
.progress, #progress {
  position: fixed; top: 0; left: 0; z-index: 120; height: 2px; width: 100%;
  transform-origin: 0 50%; transform: scaleX(var(--p, 0));
  background: var(--accent);
  pointer-events: none;
}
/* Safari 26 paints the strips behind its status bar and toolbar from the
   first fixed or sticky box it meets at the middle of each screen edge
   (WebKit's fixedContainerEdges): that box's background colour, or the body's
   for a glass box. A box under 90% of the edge's width ends the search with
   nothing, and Safari lets the page itself run on under the bar. The two
   .bar-shield boxes (partials/bars.html, above the nav) are those: so the
   strip behind the status bar is the nav's own glass, which reaches up there
   on touch screens (below), and the toolbar runs on over the page. */
.bar-shield {
  position: fixed; bottom: 0; left: 15%; width: 70%; height: 10px; z-index: 111;
  pointer-events: none; background: rgba(0, 0, 0, 0.01);
}
.bar-shield.is-top { top: 0; bottom: auto; }

.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 110;
  height: var(--nav-h);
  display: flex; align-items: center; gap: 24px;
  padding-inline: var(--mx);
  transition: background-color 0.5s var(--ease), border-color 0.5s var(--ease), transform 0.5s var(--ease), opacity 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
/* On a touch screen the nav is one bar of glass from the very top of the
   screen. Safari 26 starts the page below its status bar and lets the page
   scroll on up under it, so the glass sits on the nav's ::before and reaches
   160px above it, behind the clock and the notch; only the buttons sit below
   them. Scrolled, the page shows through that strip blurred, like through the
   bar. On the home page the lake has the screen to itself: no bar and no
   glass, and the notch is left to Safari. Bar and glass come in together once
   the page's own ground reaches the top (.is-shown, site.js; hidden only
   under html.can-reveal, so without site.js the bar simply stays): the glass
   settles down into place, then the buttons, on the main spring. Every other
   page shows its bar from the start. There is no reading-progress line on a
   phone. */
@media (hover: none), (pointer: coarse) {
  :root { --nav-h: calc(60px + env(safe-area-inset-top, 0px)); }   /* every offset under the bar follows */
  .nav, html .nav.is-scrolled {
    padding-top: env(safe-area-inset-top, 0px);
    padding-inline: max(var(--mx), env(safe-area-inset-left, 0px)) max(var(--mx), env(safe-area-inset-right, 0px));
    background: none;
    -webkit-backdrop-filter: none; backdrop-filter: none;   /* the glass is the ::before's alone */
    border-bottom-color: var(--line);
  }
  .nav::before {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; top: -160px; z-index: -1; pointer-events: none;
    background: var(--glass);
    -webkit-backdrop-filter: blur(18px) saturate(140%); backdrop-filter: blur(18px) saturate(140%);
    transition: opacity 0.7s var(--ease), transform 0.9s var(--ease);
  }
  .nav > * { transition: opacity 0.6s var(--ease) 0.12s, transform 0.9s var(--ease) 0.12s; }
  html.can-reveal:not(.menu-open) body[data-world="home"] .nav:not(.is-shown):not(:focus-within) { border-bottom-color: transparent; pointer-events: none; }
  html.can-reveal:not(.menu-open) body[data-world="home"] .nav:not(.is-shown):not(:focus-within)::before {
    opacity: 0; transform: translateY(-28px);
    transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
  }
  html.can-reveal:not(.menu-open) body[data-world="home"] .nav:not(.is-shown):not(:focus-within) > * {
    opacity: 0; transform: translateY(-12px);
    transition: opacity 0.25s var(--ease), transform 0.35s var(--ease);
  }
  .progress, #progress { display: none; }
}
.nav.is-scrolled {
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: var(--line);
}
.nav-mark { display: inline-flex; align-items: center; gap: 12px; min-height: 44px; font: 600 15px/1 var(--f-sans); letter-spacing: -0.01em; color: var(--text); }
/* the GH mark (gh-brand/): the letters in the text colour, the crossbar in
   dawn over them, each a mask of the same 174x100 drawing on its own layer
   (a mask on the box itself would clip the other), so both follow the theme */
.gh-mark {
  position: relative; display: inline-block; width: 40px; height: 23px; flex: none;
  transition: transform 0.6s var(--ease);
}
.gh-mark::before, .gh-mark::after {
  content: ''; position: absolute; inset: 0;
  background: currentColor;
  -webkit-mask: url(../../images/gh-mark-ink.svg) center / contain no-repeat;
  mask: url(../../images/gh-mark-ink.svg) center / contain no-repeat;
}
.gh-mark::after {
  background: var(--dawn);
  -webkit-mask-image: url(../../images/gh-mark-bar.svg);
  mask-image: url(../../images/gh-mark-bar.svg);
}
.nav-mark:hover .gh-mark { transform: rotate(-8deg) scale(1.06); }
.nav-crumbs { display: flex; align-items: center; gap: 10px; font: 500 var(--step--1)/1 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); }
.nav-crumbs a { display: inline-flex; align-items: center; min-height: 44px; transition: color 0.3s; }
.nav-crumbs a:hover { color: var(--text); }
.nav-crumbs .sep { opacity: 0.5; }
.nav-crumbs .here { color: var(--accent); }
html[lang="zh-CN"] .nav-crumbs { letter-spacing: 0.04em; }
.nav-links { display: flex; gap: clamp(14px, 1.8vw, 30px); margin-left: auto; }
.nav-links a {
  position: relative; display: inline-flex; align-items: center; min-height: 44px;
  font-size: 14px; font-weight: 450; color: var(--text-2); transition: color 0.3s;
}
.nav-links a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 10px; height: 1px;
  background: var(--accent); transform: scaleX(0); transform-origin: right; transition: transform 0.5s var(--ease);
}
.nav-links a:hover, .nav-links a.is-on { color: var(--text); }
.nav-links a:hover::after, .nav-links a.is-on::after { transform: scaleX(1); transform-origin: left; }
.nav-tools { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.nav-links + .nav-tools { margin-left: 18px; }

.icon-btn, .pill-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-width: 44px; height: 44px; padding-inline: 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-2);
  color: var(--text-2);
  font: 500 13px/1 var(--f-sans);
  transition: color 0.2s, border-color 0.2s, background-color 0.2s, transform 160ms var(--ease-out);
}
.icon-btn:active, .pill-btn:active, .lang-btn:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) { .icon-btn:hover, .pill-btn:hover { color: var(--text); border-color: var(--text-3); } }
.icon-btn svg { width: 17px; height: 17px; }
.theme-toggle { padding: 0; width: 44px; }
.theme-toggle .sun { display: none; }
[data-theme="light"] .theme-toggle .sun { display: block; }
[data-theme="light"] .theme-toggle .moon { display: none; }

/* language: the engine in i18n.js owns #langSelector/#langBtn/#langDropdown */
.lang-selector { position: relative; }
.lang-btn { composes: icon-btn; }
.lang-selector .lang-btn {
  display: inline-flex; align-items: center; gap: 7px; height: 44px; padding: 0 14px;
  border-radius: var(--r-pill); border: 1px solid var(--line-2); color: var(--text-2);
  font: 500 13px/1 var(--f-sans); transition: color 0.3s, border-color 0.3s;
}
.lang-selector .lang-btn:hover { color: var(--text); border-color: var(--text-3); }
.lang-current { display: inline-flex; align-items: center; gap: 6px; }
.lang-dropdown {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 150px; padding: 6px;
  border: 1px solid var(--line-2);
  background: var(--bg-raise);
  box-shadow: var(--shadow);
  opacity: 0; transform: translateY(-6px) scale(0.98); transform-origin: top right;
  pointer-events: none; transition: opacity 0.25s var(--ease), transform 0.35s var(--ease);
}
.lang-selector.open .lang-dropdown { opacity: 1; transform: none; pointer-events: auto; }
.lang-option {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 0 12px;
  font-size: 14px; color: var(--text-2); text-align: left;
  transition: background-color 0.2s, color 0.2s;
}
.lang-option:hover { background: var(--bg-raise2); color: var(--text); }
.lang-option.active { color: var(--text); }
.lang-option.active::after { content: ''; margin-left: auto; width: 6px; height: 6px; background: var(--accent); }
.lang-flag { display: inline-flex; border-radius: 2px; overflow: hidden; box-shadow: 0 0 0 1px var(--line); }

.nav-resume { gap: 7px; }
.nav-cta { min-height: 44px; padding: 0 20px; font-size: 13px; letter-spacing: 0.02em; margin-left: 18px; box-shadow: none; }
.nav-links + .nav-cta + .nav-tools { margin-left: 10px; }
@media (max-width: 1280px) { .nav-links ~ .nav-tools .nav-resume { display: none; } }
@media (max-width: 1080px) { .nav .nav-cta { display: none; } }
.nav-resume svg { width: 13px; height: 13px; }
.menu-btn { gap: 10px; padding-inline: 16px 14px; color: var(--text); border-color: var(--line-2); }
.menu-btn .bars { position: relative; width: 16px; height: 8px; }
.menu-btn .bars::before, .menu-btn .bars::after {
  content: ''; position: absolute; left: 0; right: 0; top: 3.25px; height: 1.5px; background: currentColor; border-radius: 2px;
  transition: transform 0.5s var(--ease);
}
.menu-btn .bars::before { transform: translateY(-3.25px); }
.menu-btn .bars::after { transform: translateY(3.25px); }
.menu-open .menu-btn .bars::before { transform: rotate(45deg); }
.menu-open .menu-btn .bars::after { transform: rotate(-45deg); }
@media (max-width: 1080px) { .nav-links { display: none; } .nav-links + .nav-tools, .nav-links + .nav-cta + .nav-tools { margin-left: auto; } }
@media (max-width: 560px) {
  .nav-crumbs { min-width: 0; }
  .nav-crumbs .nav-back, .nav-crumbs .sep { display: none; }
  .nav-crumbs .here { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media (max-width: 720px) {
  .nav { gap: 12px; }
  .nav-resume, .nav-crumbs .crumb-mid { display: none; }
  .nav-word { display: none; }
  .menu-btn .menu-word { display: none; }
  .menu-btn { width: 44px; padding: 0; }
}
@media (max-width: 420px) { .lang-selector .lang-btn { padding: 0 10px; } }

/* the index: every page, one keystroke away */
.menu {
  position: fixed; inset: 0; z-index: 105;
  display: grid; grid-template-rows: 1fr auto;
  padding: calc(var(--nav-h) + 24px) var(--mx) 28px;
  background: color-mix(in srgb, var(--bg-deep) 94%, transparent);
  -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
  overflow-y: auto; overscroll-behavior: contain;
  opacity: 0; visibility: hidden;
  transition: opacity 0.5s var(--ease), visibility 0s linear 0.5s;
}
.menu-open .menu { opacity: 1; visibility: visible; transition: opacity 0.5s var(--ease); }
.menu-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 64px); align-content: start; padding-block: clamp(20px, 5vh, 56px);
}
.menu-col h2 { margin-bottom: 18px; }
.menu-col ul { display: grid; gap: 2px; }
.menu-col a {
  display: flex; align-items: baseline; gap: 12px; padding-block: 7px;
  font: 600 clamp(20px, 1.2rem + 0.9vw, 32px)/1.1 var(--f-disp); letter-spacing: -0.02em;
  color: var(--text);
  opacity: 0; transform: translateY(18px);
  transition: color 0.3s, opacity 0.6s var(--ease), transform 0.8s var(--ease);
}
.menu-col a small { font: 500 12px/1 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); }
.menu-col a:hover, .menu-col a[aria-current="page"] { color: var(--accent); }
.menu-open .menu-col a { opacity: 1; transform: none; }
.menu-open .menu-col:nth-child(1) a { transition-delay: calc(60ms + var(--i, 0) * 35ms); }
.menu-open .menu-col:nth-child(2) a { transition-delay: calc(120ms + var(--i, 0) * 35ms); }
.menu-open .menu-col:nth-child(3) a { transition-delay: calc(180ms + var(--i, 0) * 35ms); }
.menu-open .menu-col:nth-child(4) a { transition-delay: calc(240ms + var(--i, 0) * 35ms); }
.menu-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px; padding-top: 22px; border-top: 1px solid var(--line); color: var(--text-3); font-size: 14px; }
.menu-foot .chips, .foot-say .chips { align-items: center; }
.menu-foot .chip, .foot-say .chip { min-height: 36px; padding: 0 14px; }
.menu-foot a:hover { color: var(--text); }
html[lang="zh-CN"] .menu-col a { letter-spacing: 0; }
@media (max-width: 1000px) { .menu-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .menu-grid { grid-template-columns: minmax(0, 1fr); } }

/* ── 6. buttons, chips, links ────────────────────────────────────── */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 50px; padding: 0 24px;
  font: 600 15px/1 var(--f-sans); letter-spacing: 0;
  color: var(--on-accent); background: var(--accent);
  border: 1px solid var(--accent);
  white-space: nowrap;
  transition: transform 160ms var(--ease-out), background-color 0.2s, color 0.2s, border-color 0.2s;
}
.btn:active { transform: scale(0.97); }
.btn.ghost { background: transparent; color: var(--text); border-color: var(--line-2); }
.btn svg, .arrow-link svg { width: 16px; height: 16px; flex: none; transition: transform 0.35s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: color-mix(in srgb, var(--accent) 84%, var(--text)); border-color: color-mix(in srgb, var(--accent) 84%, var(--text)); }
  .btn.ghost:hover { background: transparent; border-color: var(--accent); color: var(--accent); }
  .btn:hover svg, .arrow-link:hover svg { transform: translateX(3px); }
}
.arrow-link {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
  font-weight: 600; color: var(--text); transition: color 0.3s;
}
@media (hover: hover) and (pointer: fine) { .arrow-link:hover { color: var(--accent); } }
.arrow-link:focus-visible { color: var(--accent); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip, .tag {
  display: inline-flex; align-items: center; min-height: 28px; padding: 0 11px;
  border: 1px solid var(--line-2);
  font: 500 12px/1 var(--f-mono); letter-spacing: 0; color: var(--text-2);
  white-space: nowrap;
}
.chip.hot { border-color: color-mix(in srgb, var(--accent) 60%, transparent); color: var(--accent); }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); flex: none; }

/* ── 7. readouts: numbers set like instrument values ─────────────── */
.readouts {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--line-2);
}
.readouts > div { padding: 22px clamp(12px, 1.6vw, 26px) 4px 0; position: relative; }
.readouts > div + div { padding-left: clamp(12px, 1.6vw, 26px); border-left: 1px solid var(--line); }
/* numbers set like a regatta results board: condensed, tabular, no ornament */
.hstat-num, .as-n, .ss-num, .sstat-n, .ro-n {
  font-family: var(--f-disp); font-weight: 620; font-stretch: 75%;
  font-size: clamp(38px, 1.3rem + 2.8vw, 68px);
  line-height: 0.95; letter-spacing: -0.01em; color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.hstat-lbl, .as-l, .ss-lbl, .sstat-l, .ro-l {
  margin-top: 12px;
  font: 500 var(--step--1)/1.4 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3);
}
html[lang="zh-CN"] :is(.hstat-lbl, .as-l, .ss-lbl, .sstat-l, .ro-l) { letter-spacing: 0.02em; }
@media (max-width: 760px) {
  .readouts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .readouts > div:nth-child(3) { padding-left: 0; border-left: 0; }
  .readouts > div:nth-child(n+3) { border-top: 1px solid var(--line); margin-top: 18px; }
}

/* ── 8. page hero (every page but the index) ─────────────────────── */
.phero {
  position: relative; isolation: isolate;
  min-height: max(640px, 100svh);
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: calc(var(--nav-h) + 48px) 0 clamp(40px, 6vh, 72px);
  overflow: hidden;
  background: var(--bg-deep);
}
.phero-canvas, .scene-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: -2;
}
.phero::before {
  /* a scrim on the reading side, so any scene stays behind the words */
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, color-mix(in srgb, var(--bg) 55%, transparent) 0%, color-mix(in srgb, var(--bg) 18%, transparent) 45%, transparent 70%);
}
.phero::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 55%; z-index: -1; pointer-events: none;
  background: linear-gradient(to top, var(--bg) 0%, color-mix(in srgb, var(--bg) 60%, transparent) 40%, transparent);
}
/* the zero-size mark whose top is a line's baseline: scenes stand their horizon on it */
.baseline-probe { display: inline-block; width: 0; height: 0; vertical-align: baseline; }
/* WebGL unavailable: a still gradient in the scene's own colours */
canvas.gl-off, .scene-fallback { background:
  radial-gradient(90% 70% at 72% 55%, color-mix(in srgb, var(--accent) 26%, transparent), transparent 70%),
  linear-gradient(180deg, var(--bg-deep), var(--bg)); }
.phero-inner { position: relative; display: grid; gap: clamp(22px, 3vh, 34px); }
.phero-top { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 26px; }
.hero-chapter, .phero-chapter {
  display: inline-flex; align-items: center; gap: 10px;
  font: 600 var(--step--1)/1.2 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent);
}
.phero-eye { font: 500 var(--step--1)/1.5 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); }
html[lang="zh-CN"] :is(.hero-chapter, .phero-eye) { letter-spacing: 0.04em; }
.phero-title {
  font-family: var(--f-disp); font-weight: 700; font-stretch: var(--wd-disp);
  font-size: var(--step-5); line-height: 0.98; letter-spacing: -0.035em;
  color: var(--text);
  max-width: 14ch;
}
.phero-title > span { display: block; }
.phero-sub { max-width: 60ch; font-size: var(--step-1); line-height: 1.55; color: var(--text-2); text-wrap: pretty; }
.phero .readouts { margin-top: clamp(20px, 4vh, 44px); }
.phero-glyph {
  position: absolute; right: -0.05em; top: 50%; z-index: -1; transform: translateY(-58%);
  font: 800 clamp(260px, 42vw, 720px)/1 var(--f-disp); color: var(--accent); opacity: 0.07;
  pointer-events: none; user-select: none;
}
/* hero plates (photos under a page hero) */
/* the plates rise into the hero's bottom padding, never into its readouts: the
   overlap is that padding (6vh-based) minus a gap, so it holds at any screen shape */
.plates { display: grid; grid-template-columns: 1.35fr 1fr; gap: var(--gap); margin-top: calc(clamp(18px, 2vw, 28px) - clamp(40px, 6vh, 72px)); position: relative; z-index: 2; }
.plates.single { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 760px) { .plates { grid-template-columns: minmax(0, 1fr); margin-top: 0; } }

/* ── 9. figures + captions ───────────────────────────────────────── */
.frame {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--bg-raise);
  border: 1px solid var(--line);
}
.frame img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s var(--ease-img), filter 0.8s var(--ease); }
@media (hover: hover) and (pointer: fine) { .frame:not(.shot):hover img { transform: scale(1.035); } }
.frame > figcaption, .frame .cap {
  position: absolute; inset: auto 0 0 0; z-index: 2;
  padding: 48px 20px 16px;
  font: 500 13px/1.45 var(--f-sans); font-stretch: var(--wd-label); color: #eef1f6;
  background: linear-gradient(to top, rgba(5, 7, 14, 0.86), rgba(5, 7, 14, 0.4) 55%, transparent);
}
.frame-4x3 { aspect-ratio: 4 / 3; }
.frame-16x9 { aspect-ratio: 16 / 9; }
.frame-3x2 { aspect-ratio: 3 / 2; }
.frame-4x5 { aspect-ratio: 4 / 5; }
.frame-1x1 { aspect-ratio: 1 / 1; }
.frame.contain img { object-fit: contain; padding: clamp(16px, 3vw, 40px); }
.frame.plain { background: transparent; border: 0; }
.figure > figcaption, .fig-cap {
  margin-top: 12px; display: flex; gap: 10px; align-items: baseline;
  font: 500 13px/1.5 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3);
}

/* ── 10. cards ────────────────────────────────────────────────────── */
.card {
  position: relative;
  display: flex; flex-direction: column; gap: 14px;
  padding: clamp(20px, 2vw, 28px) 0 4px;
  border-top: 1px solid var(--line-2);
}
/* a link card draws its rule in the world's colour, left to right */
.card::before {
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px; pointer-events: none;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform 0.6s var(--ease);
}
a.card:focus-visible::before { transform: scaleX(1); }
.card-k { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent); }
html[lang="zh-CN"] .card-k { letter-spacing: 0.03em; }
.card-t { font: 680 clamp(21px, 1rem + 0.9vw, 29px)/1.14 var(--f-disp); font-stretch: 108%; letter-spacing: -0.02em; color: var(--text); text-wrap: balance; transition: color 0.2s; }
.card-p { color: var(--text-2); font-size: 16px; line-height: 1.62; }
.card-go { margin-top: auto; padding-top: 10px; display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; color: var(--text); transition: color 0.2s; }
.card-go svg { width: 15px; height: 15px; transition: transform 0.35s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  a.card:hover::before { transform: scaleX(1); }
  a.card:hover .card-t, a.card:hover .card-go { color: var(--accent); }
  a.card:hover .card-go svg { transform: translateX(4px); }
}
.card-n { font: 600 14px/1 var(--f-mono); color: var(--text-3); }
.cards { display: grid; gap: var(--gap); }
.cards-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cards-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cards-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .cards-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) { .cards-3 { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 700px) { .cards-2, .cards-4 { grid-template-columns: minmax(0, 1fr); } }

/* "also explore" + return */
.explore-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); margin-top: clamp(22px, 2.6vw, 36px); }
@media (max-width: 900px) { .explore-grid { grid-template-columns: minmax(0, 1fr); } }
.disc-label { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent); }
.disc-title { font: 700 clamp(24px, 1.1rem + 1.1vw, 36px)/1.05 var(--f-disp); font-stretch: var(--wd-disp); letter-spacing: -0.03em; transition: color 0.2s; }
.disc-arrow { margin-top: auto; padding-top: 18px; font-weight: 600; font-size: 14px; color: var(--text); transition: color 0.2s; }
@media (hover: hover) and (pointer: fine) { a.card:hover .disc-arrow, a.card:hover .disc-title { color: var(--accent); } }
.explore-card p, .explore-card .disc-sub { color: var(--text-2); font-size: 15.5px; line-height: 1.6; }
html[lang="zh-CN"] .disc-label { letter-spacing: 0.03em; }

.return {
  display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 24px;
  padding-top: clamp(40px, 6vw, 80px); margin-top: clamp(40px, 6vw, 80px); border-top: 1px solid var(--line);
}
.back-label { font: 600 var(--step--1)/1 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); }
.back-link { display: inline-flex; align-items: center; gap: 18px; font: 700 var(--step-3)/1 var(--f-disp); font-stretch: var(--wd-disp); letter-spacing: -0.03em; color: var(--text); transition: color 0.3s; }
.back-link svg { width: 0.7em; height: 0.7em; transition: transform 0.6s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .back-link:hover { color: var(--accent); }
  .back-link:hover svg { transform: translateX(-10px); }
}
.back-link:focus-visible { color: var(--accent); }

/* ── 11. lists used across pages ─────────────────────────────────── */
/* award / record rows */
.rows { display: grid; border-top: 1px solid var(--line-2); }
.row {
  position: relative;
  display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: 8px clamp(16px, 2vw, 32px); align-items: baseline;
  padding: clamp(20px, 2.2vw, 30px) 0;
  border-bottom: 1px solid var(--line);
  transition: background-color 0.5s var(--ease);
}
.row::before { content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform 0.6s var(--ease); }
@media (hover: hover) and (pointer: fine) { .row:hover::before { transform: scaleX(1); } }
.row-n { font: 600 13px/1 var(--f-mono); color: var(--text-3); padding-top: 6px; }
.row-t { font: 640 clamp(18px, 0.95rem + 0.6vw, 24px)/1.25 var(--f-sans); font-stretch: 104%; letter-spacing: -0.012em; color: var(--text); }
.row-c { margin-top: 6px; color: var(--text-2); font-size: 15px; line-height: 1.55; }
.row-b { justify-self: end; }
@media (max-width: 700px) { .row { grid-template-columns: 40px minmax(0, 1fr); } .row-b { grid-column: 2; justify-self: start; margin-top: 8px; } }
.badge {
  display: inline-flex; align-items: center; gap: 8px; min-height: 30px; padding: 0 13px;
  font: 600 12px/1 var(--f-mono); letter-spacing: 0;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 36%, transparent);
  white-space: nowrap;
}
.badge.seal { color: var(--on-accent); background: var(--accent); border-color: transparent; }

/* spec grid: label / name / description tiles */
.spec { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.spec > * { padding: clamp(20px, 2vw, 28px); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); display: grid; gap: 10px; align-content: start; transition: background-color 0.4s; }
.spec > *:hover { background: var(--bg-raise); }
.spec-k, .tech-label, .tech-item-label, .method-label { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent); }
.spec-n, .tech-name, .tech-item-name, .method-name { font: 680 clamp(19px, 0.9rem + 0.7vw, 25px)/1.15 var(--f-disp); font-stretch: 108%; letter-spacing: -0.015em; color: var(--text); }
.spec-d, .tech-desc, .tech-item-desc, .method-detail { font-size: 15px; line-height: 1.6; color: var(--text-2); }
html[lang="zh-CN"] :is(.spec-k, .tech-label, .tech-item-label, .method-label) { letter-spacing: 0.03em; }

/* insight / finding blocks */
.insights { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); }
.insights.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 960px) { .insights, .insights.two { grid-template-columns: minmax(0, 1fr); } }
.insight-num { font: 600 var(--step--1)/1 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent); }
.insight-title { font: 680 clamp(20px, 1rem + 0.8vw, 28px)/1.15 var(--f-disp); font-stretch: 108%; letter-spacing: -0.02em; color: var(--text); }
.insight-body { color: var(--text-2); font-size: 15.5px; line-height: 1.65; }

/* a panel that holds an interactive demo: an instrument on the bench */
.bench {
  position: relative; isolation: isolate;
  border: 1px solid var(--line-2);
  background: var(--bg-raise);
  overflow: hidden;
}
.bench-bar {
  display: flex; align-items: center; gap: 12px; padding: 14px 20px;
  border-bottom: 1px solid var(--line);
  font: 500 12px/1 var(--f-mono); color: var(--text-3);
}
.bench-bar .lights { display: none; }   /* no fake window chrome: the demo is the real thing */
.bench-body { padding: clamp(18px, 2.6vw, 36px); }

/* tables */
.table-wrap { overflow-x: auto; border-top: 1px solid var(--line-2); }
table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
th, td { padding: 14px 18px; text-align: left; border-bottom: 1px solid var(--line); font-size: 15px; }
th { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); }
tr:last-child td { border-bottom: 0; }
td { color: var(--text-2); }

/* bullet list with a luminous tick */
.ticks { display: grid; gap: 12px; }
.ticks li { display: grid; grid-template-columns: 18px 1fr; gap: 12px; color: var(--text-2); line-height: 1.55; }
.ticks li > span:first-child, .ticks .tk { color: var(--accent); font-size: 12px; padding-top: 5px; }

/* ── 12. gallery + lightbox ──────────────────────────────────────── */
.gallery { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: clamp(160px, 18vw, 300px); gap: clamp(8px, 1vw, 14px); grid-auto-flow: dense; }
.gallery > figure { position: relative; overflow: hidden; background: var(--bg-raise); cursor: zoom-in; border: 1px solid var(--line); }
.gallery > figure.wide { grid-column: span 2; }
.gallery > figure.tall { grid-row: span 2; }
.gallery > figure.big { grid-column: span 2; grid-row: span 2; }
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s var(--ease-img), filter 0.6s; }
.gallery > figure:hover img { transform: scale(1.05); }
.gallery figcaption, .gallery .g-caption {
  position: absolute; inset: auto 0 0 0; padding: 40px 16px 14px;
  font: 500 13px/1.45 var(--f-sans); font-stretch: var(--wd-label); color: #eef1f6;
  background: linear-gradient(to top, rgba(5,7,14,0.86), transparent);
  opacity: 0; transform: translateY(8px); transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.gallery > figure:hover figcaption, .gallery > figure:hover .g-caption, .gallery > figure:focus-visible figcaption { opacity: 1; transform: none; }
@media (hover: none) { .gallery figcaption, .gallery .g-caption { opacity: 1; transform: none; } }
@media (max-width: 900px) { .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: clamp(150px, 38vw, 260px); } }
/* The grid above is the fallback. site.js deals galleries and plates into
   justified rows (.is-justified): every photo at its own shape, each row
   filling the width exactly, sizes written on the figures. */
.gallery.is-justified, .plates.is-justified { display: flex; flex-wrap: wrap; align-items: flex-start; }
.gallery.is-justified > figure, .plates.is-justified > figure { flex: none; aspect-ratio: auto; }

.lightbox {
  position: fixed; inset: 0; z-index: 150;
  display: grid; grid-template-rows: 1fr auto; place-items: center;
  padding: clamp(16px, 4vw, 56px);
  background: rgba(3, 5, 10, 0.94);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  opacity: 0; visibility: hidden; transition: opacity 0.4s var(--ease), visibility 0s linear 0.4s;
}
.lightbox.is-open { opacity: 1; visibility: visible; transition: opacity 0.4s var(--ease); }
.lightbox img { max-width: 100%; max-height: 78vh; width: auto; object-fit: contain; box-shadow: 0 40px 120px rgba(0,0,0,0.6); }
.lightbox-cap { margin-top: 18px; color: #c9cfdb; font: 500 13px/1.5 var(--f-mono); text-align: center; max-width: 70ch; }
.lightbox-btn { position: absolute; width: 48px; height: 48px; border: 1px solid rgba(255,255,255,0.2); color: #fff; display: grid; place-items: center; transition: background-color 0.2s, transform 160ms var(--ease-out); }
.lightbox-btn:active { transform: scale(0.97); }
.lightbox-btn:hover { background: rgba(255,255,255,0.1); }
.lightbox-close { top: 20px; right: 20px; }
.lightbox-prev { left: 20px; top: 50%; }
.lightbox-next { right: 20px; top: 50%; }

/* ── 13. chapter rail (built by site.js from [data-rail-step]) ───── */
.cine-rail {
  position: fixed; right: clamp(12px, 1.6vw, 28px); top: 50%; z-index: 60;
  transform: translate(12px, -50%); opacity: 0; pointer-events: none;
  display: grid; gap: 4px;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.cine-rail.is-visible { opacity: 1; transform: translate(0, -50%); pointer-events: auto; }
.cine-rail-step {
  display: flex; align-items: center; justify-content: flex-end; gap: 12px;
  min-height: 26px; color: var(--text-3); font: 500 12px/1 var(--f-sans); font-stretch: var(--wd-label);
}
.cine-rail-label { opacity: 0; transform: translateX(6px); transition: opacity 0.35s var(--ease), transform 0.45s var(--ease); white-space: nowrap; padding: 5px 9px; background: var(--glass); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.cine-rail-tick { width: 28px; height: 2px; background: var(--line-2); transform: scaleX(0.5); transform-origin: right; transition: transform 0.45s var(--ease), background-color 0.3s; }
.cine-rail:hover .cine-rail-label, .cine-rail-step:focus-visible .cine-rail-label { opacity: 1; transform: none; }
.cine-rail-step.is-on { color: var(--text); }
.cine-rail-step.is-on .cine-rail-tick { transform: scaleX(1); background: var(--accent); }
@media (max-width: 1180px) { .cine-rail { display: none; } }

/* ── 14. footer ──────────────────────────────────────────────────── */
.footer {
  position: relative; overflow: hidden; isolation: isolate;
  background: var(--bg-deep);
  border-top: 1px solid var(--line);
  padding: clamp(72px, 10vw, 140px) 0 28px;
}
.foot-top { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr); gap: clamp(40px, 6vw, 96px); }
.foot-say { display: grid; gap: 22px; align-content: start; }
.foot-say .display { font-size: var(--step-3); }
.foot-cols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px; }
.foot-cols h2 { margin-bottom: 14px; }
.foot-cols ul { display: grid; gap: 2px; }
.foot-cols a { display: inline-flex; min-height: 34px; align-items: center; color: var(--text-2); font-size: 15px; transition: color 0.3s; }
.foot-cols a:hover { color: var(--accent); }
.foot-bottom {
  margin-top: clamp(56px, 8vw, 110px); padding-top: 22px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 28px;
  color: var(--text-3); font-size: 13.5px;
}
.foot-bottom a { transition: color 0.3s; }
.foot-bottom a:hover { color: var(--text); }
.foot-mid { font-family: var(--f-mono); font-size: 12px; }
.foot-sign { display: flex; align-items: center; gap: 14px; }
.foot-sign .gh-mark { width: 35px; height: 20px; color: var(--text-2); }
@media (max-width: 1000px) { .foot-top { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 640px) { .foot-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* reveal delays as classes, so inline style stays free for data (--pct) */
.d1 { --d: 1; } .d2 { --d: 2; } .d3 { --d: 3; } .d4 { --d: 4; } .d5 { --d: 5; }

/* ── 15. motion ──────────────────────────────────────────────────── */
/* Reveals are opt-in and only hide content once site.js has proved it can
   bring it back (html.can-reveal). No JS, no observer: everything shows. */
.can-reveal [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 34px, 0);
  transition: opacity 0.9s var(--ease), transform 1.2s var(--ease);
  transition-delay: calc(var(--d, 0) * 90ms);
}
.can-reveal [data-reveal="fade"] { transform: none; }
.can-reveal [data-reveal="clip"] { opacity: 1; transform: none; clip-path: inset(0 0 100% 0); transition: clip-path 1.3s var(--ease-img); transition-delay: calc(var(--d, 0) * 90ms); }
.can-reveal [data-reveal].is-in { opacity: 1; transform: none; }
.can-reveal [data-reveal="clip"].is-in { clip-path: inset(0 0 0 0); }
/* line-by-line headline rise */
.can-reveal [data-split] .ln { display: block; overflow: hidden; padding-bottom: 0.16em; margin-bottom: -0.16em; }
.can-reveal [data-split] .ln > span { display: inline-block; transform: translateY(105%); transition: transform 1.25s var(--ease); transition-delay: calc(var(--d, 0) * 90ms + var(--l, 0) * 80ms); }
.can-reveal [data-split].is-in .ln > span { transform: none; }

@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out 0.45s var(--ease) both; }
::view-transition-new(root) { animation: vt-in 0.7s var(--ease) both; }
@keyframes vt-out { to { opacity: 0; transform: scale(0.985); filter: blur(4px); } }
@keyframes vt-in { from { opacity: 0; transform: scale(1.01); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
  .can-reveal [data-reveal], .can-reveal [data-split] .ln > span { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* ── 16. print: the record, on paper ─────────────────────────────── */
@media print {
  body::after, .nav, .menu, .cine-rail, canvas, .progress { display: none !important; }
  body { background: #fff; color: #000; }
  .can-reveal [data-reveal], .can-reveal [data-split] .ln > span { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}

/* ── projects (Home featured, All projects, facts block, previous / next) ─
   One record per project (data/projects.yml) drives every block below;
   tools/projects.py stamps them. Status is always plain text, never a badge:
   day accents on a tint fail contrast. */

/* featured entries: a vertical list on the 3fr / 9fr grid, never side-by-side cards */
.wk-groups { display: grid; gap: clamp(64px, 9vw, 128px); }
.wk-group { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); column-gap: clamp(24px, 4vw, 72px); align-items: start; }
.wk-group-head { grid-column: 1; grid-row: 1 / span 6; position: sticky; top: calc(var(--nav-h) + 32px); display: grid; gap: 12px; padding-top: 30px; }
.wk-group-title { font: 700 clamp(22px, 1rem + 0.9vw, 30px)/1.1 var(--f-disp); letter-spacing: -0.02em; color: var(--text); }
.wk-group-note { color: var(--text-3); font-size: 15px; line-height: 1.55; max-width: 28ch; }
.wk-item {
  grid-column: 2;
  position: relative;
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 14px clamp(24px, 3vw, 56px);
  padding: clamp(26px, 3vw, 40px) 0;
  border-top: 1px solid var(--line-2);
}
.wk-group .wk-item:last-child { border-bottom: 1px solid var(--line-2); }
.wk-item::before {
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, var(--accent), transparent 80%);
  transform: scaleX(0); transform-origin: left; transition: transform 0.9s var(--ease);
}
.wk-head { display: grid; gap: 14px; align-content: start; }
.wk-name {
  font: 700 clamp(28px, 1rem + 2.2vw, 52px)/1 var(--f-disp); letter-spacing: -0.045em;
  color: var(--text); transition: color 0.4s, transform 0.7s var(--ease);
}
/* the name is the link; its ::after makes the whole entry the target without
   turning an 80-word description into the link's name */
.wk-link { color: inherit; }
.wk-link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.wk-link:focus-visible { outline: none; }
.wk-item:has(.wk-link:focus-visible) { outline: 2px solid var(--accent); outline-offset: 6px; }
.wk-item:has(.wk-link:focus-visible)::before { transform: scaleX(1); }
.wk-meta { display: grid; gap: 4px; max-width: 18ch; }
.wk-area { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent); }
.wk-status { font: 500 var(--step--1)/1.4 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-2); }
.wk-body { display: grid; gap: 18px; align-content: start; }
.wk-desc { color: var(--text-2); font-size: 16px; line-height: 1.65; }
.wk-shot { margin: 2px 0 0; border-color: var(--line-2); }
.wk-shot img { height: auto; max-height: clamp(240px, 26vw, 380px); object-fit: contain; object-position: left top; background: var(--bg-raise); }
.wk-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; }
.wk-dest { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; color: var(--text); white-space: nowrap; }
.wk-dest svg { width: 16px; height: 16px; transition: transform 0.6s var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .wk-item:hover::before { transform: scaleX(1); }
  .wk-item:hover .wk-name { color: var(--accent); transform: translateX(6px); }
  .wk-item:hover .wk-dest { color: var(--accent); }
  .wk-item:hover .wk-dest svg { transform: translate(3px, -3px); }
}
html[lang="zh-CN"] .wk-name { letter-spacing: -0.01em; }
html[lang="zh-CN"] :is(.wk-area, .wk-status) { letter-spacing: 0; line-height: 1.6; }
@media (max-width: 1000px) {
  .wk-group { grid-template-columns: minmax(0, 1fr); }
  .wk-group-head { position: static; grid-row: auto; padding: 0 0 18px; }
  .wk-item { grid-column: 1; grid-template-columns: minmax(0, 1fr); }
  .wk-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; max-width: none; }
}

/* All projects: a list of links (a table of contents, not data to compare) */
.ix-head { display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; }
.ix-count { font: 600 14px/1 var(--f-mono); color: var(--text-3); }
.ix { display: grid; gap: 0; margin-top: clamp(20px, 3vw, 40px); }
.ix-group { padding-top: clamp(28px, 3vw, 44px); }
.ix-area { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--accent); margin-bottom: 10px; }
.ix-list { list-style: none; margin: 0; padding: 0; }
.ix-row {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 6fr) minmax(8.5em, auto) 18px;
  grid-template-areas: "name line status arrow";
  align-items: baseline; gap: 6px clamp(16px, 2.4vw, 36px);
  min-height: 44px; padding: 15px 0;
  border-bottom: 1px solid var(--line);
}
.ix-row:first-child { border-top: 1px solid var(--line-2); }
.ix-row::before {
  content: ''; position: absolute; left: 0; right: 0; top: -1px; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, var(--accent), transparent 85%);
  transform: scaleX(0); transform-origin: left; transition: transform 0.6s var(--ease);
}
.ix-link { grid-area: name; color: var(--text); }
.ix-link::after { content: ''; position: absolute; inset: 0; }
.ix-link:focus-visible { outline: none; }
.ix-row:has(.ix-link:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }
.ix-row:has(.ix-link:focus-visible)::before { transform: scaleX(1); }
.ix-name { font: 640 clamp(17px, 0.9rem + 0.4vw, 21px)/1.25 var(--f-sans); font-stretch: 104%; letter-spacing: -0.01em; transition: color 0.3s; }
.ix-line { grid-area: line; color: var(--text-2); font-size: 15px; line-height: 1.5; }
.ix-status { grid-area: status; font: 500 var(--step--1)/1.4 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); white-space: nowrap; }
.ix-gh { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; margin-block: -14px; color: var(--text-2); }
.ix-gh svg { width: 13px; height: 13px; }
.ix-gh:focus-visible { color: var(--accent); }
.ix-arrow { grid-area: arrow; align-self: center; color: var(--text-3); transition: color 0.3s, transform 0.5s var(--ease); }
.ix-arrow svg { width: 15px; height: 15px; display: block; }
.ix-row:active { background: var(--bg-raise); transition: background 0.16s; }
@media (hover: hover) and (pointer: fine) {
  .ix-row:hover::before { transform: scaleX(1); }
  .ix-row:hover .ix-name { color: var(--accent); }
  .ix-row:hover .ix-arrow { color: var(--accent); transform: translate(3px, -3px); }
  .ix-gh:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
}
html[lang="zh-CN"] :is(.ix-name, .ix-area) { letter-spacing: 0; }
html[lang="zh-CN"] :is(.ix-line, .ix-status) { line-height: 1.7; letter-spacing: 0; }
html[lang="zh-CN"] :is(.ix-status, .ix-area, .wk-area, .wk-status) { font-size: max(12px, var(--step--1)); }
@media (max-width: 760px) {
  .ix-row { grid-template-columns: minmax(0, 1fr) 18px; grid-template-areas: "name arrow" "line line" "status status"; gap: 4px 12px; }
  .ix-status { white-space: normal; }
  .ix-gh { margin-block: -10px 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ix-row::before, .wk-item::before { transition: none; }
  .ix-arrow, .wk-name, .wk-dest svg { transition: none; transform: none !important; }
}

/* the facts block under every project hero: drawn like a drawing's title block */
.notation-wrap { padding-top: clamp(28px, 4vw, 48px); display: grid; gap: clamp(24px, 3vw, 36px); }
.notation {
  margin: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-flow: dense;
  column-gap: clamp(20px, 3vw, 44px); border-bottom: 1px solid var(--line);
}
.nt-cell { padding: 16px 0 18px; border-top: 1px solid var(--line-2); display: grid; gap: 6px; align-content: start; min-width: 0; }
.nt-wide { grid-column: span 2; }
.notation dt { font: 600 var(--step--1)/1.3 var(--f-sans); font-stretch: var(--wd-label); color: var(--text-3); }
.notation dd { margin: 0; font-size: 16px; line-height: 1.45; color: var(--text); }
.nt-stack { font: 500 13px/1.6 var(--f-mono) !important; color: var(--text-2) !important; }
.nt-links { display: flex; flex-wrap: wrap; gap: 0 18px; }
.nt-links .arrow-link { min-height: 32px; font-size: 15px; gap: 6px; }
.nt-links .arrow-link svg { width: 13px; height: 13px; }
.nt-summary { max-width: 66ch; }
html[lang="zh-CN"] .notation dt { letter-spacing: 0; }
html[lang="zh-CN"] .notation dd { line-height: 1.7; }
@media (max-width: 860px) {
  .notation { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nt-wide { grid-column: 1 / -1; }
}

/* previous / next: the projects in the order of Home's All projects */
.pn-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap); }
.pn-card { min-height: 44px; }
.pn-next { grid-column: 2; text-align: right; align-items: flex-end; }
.pn .return { margin-top: clamp(32px, 4vw, 56px); padding-top: clamp(28px, 4vw, 48px); }
@media (max-width: 700px) {
  .pn-grid { grid-template-columns: minmax(0, 1fr); }
  .pn-next { grid-column: 1; text-align: left; align-items: flex-start; }
}

/* screenshots: a real capture, never cropped, never zoomed, caption below */
.shot-fig { margin: 0; display: grid; gap: 0; cursor: zoom-in; }
.frame.shot { padding: clamp(6px, 0.8vw, 10px); background: var(--bg-raise); border-color: var(--line-2); }
.frame.shot img { width: 100%; height: auto; object-fit: contain; }
.shot-fig:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* how it works: numbered parts, each with its own heading, a picture beside the part it shows */
.steps { display: grid; gap: clamp(28px, 3.4vw, 44px); counter-reset: step; }
.step { display: grid; gap: 10px; padding-top: 18px; border-top: 1px solid var(--line-2); counter-increment: step; }
.step h3 { display: flex; gap: 14px; align-items: baseline; font: 680 clamp(20px, 1rem + 0.6vw, 26px)/1.2 var(--f-disp); font-stretch: 106%; letter-spacing: -0.015em; color: var(--text); }
.step h3::before { content: counter(step, decimal-leading-zero); font: 600 13px/1 var(--f-mono); color: var(--accent); }
.step p { color: var(--text-2); }
.step .shot-fig { margin-top: 10px; }
.small-print { font: 500 13px/1.6 var(--f-mono); color: var(--text-3); }
html[lang="zh-CN"] .step h3 { letter-spacing: 0; }

/* discipline showcase (FTC: ScoutSelect; Rowing: RowingLab) */
.showcase .chapter-head { gap: 18px; }
.showcase-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; }
.showcase-credit { font: 500 12px/1.5 var(--f-mono); letter-spacing: 0.04em; color: var(--text-3); }
html[lang="zh-CN"] .showcase-credit { letter-spacing: 0; }
.showcase-sub { font: 500 12.5px/1.5 var(--f-mono); color: var(--text-3); }
.showcase .chips { margin-top: clamp(18px, 2vw, 26px); }
.showcase-all { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.proj-link { max-width: 760px; }
.limits-h { margin-top: 1.8em; font: 680 clamp(20px, 1rem + 0.6vw, 26px)/1.2 var(--f-disp); font-stretch: 106%; letter-spacing: -0.015em; color: var(--text); }
html[lang="zh-CN"] .limits-h { letter-spacing: 0; }

/* project pages: the way out to the site or the code, in the hero and at the end */
.phero-cta { display: flex; flex-wrap: wrap; gap: 12px; }
.phero-cta:empty { display: none; }
/* what I learned: a few lessons, read as sentences, not features */
.lessons { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: clamp(28px, 3.4vw, 48px) var(--gap); margin-top: clamp(28px, 3vw, 44px); counter-reset: lesson; }
.lesson { display: grid; gap: 12px; align-content: start; padding-top: 18px; border-top: 1px solid var(--line-2); counter-increment: lesson; }
.lesson h3 { font: 680 clamp(21px, 1rem + 0.8vw, 28px)/1.18 var(--f-disp); font-stretch: 106%; letter-spacing: -0.02em; color: var(--text); text-wrap: balance; }
.lesson h3::before { content: counter(lesson, decimal-leading-zero); display: block; margin-bottom: 10px; font: 600 13px/1 var(--f-mono); color: var(--accent); }
.lesson p { color: var(--text-2); }
html[lang="zh-CN"] .lesson h3 { letter-spacing: 0; line-height: 1.35; }
.cta-band .cta-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 24px clamp(24px, 4vw, 64px); padding-top: clamp(32px, 4vw, 56px); border-top: 1px solid var(--line-2); }
.cta-band .display { max-width: 16ch; }
