/* ---------------------------------------------------------------------------
   hankuiwang.com — hand-written styles. No framework.
   Tokens → base → layout → components → utilities.
   --------------------------------------------------------------------------- */

:root {
  --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-serif: "Newsreader", ui-serif, Georgia, "Times New Roman", serif;

  --bg: #fbfaf7;
  --bg-elev: #ffffff;
  --fg: #1b1b1a;
  --fg-muted: #5f5e5a;
  --fg-faint: #6f6e69;
  --line: #e6e3dc;
  --accent: #1f6f6b;
  --accent-ink: #145350;
  --accent-soft: #e6f0ee;
  --sage: #cfdbd3;
  --pill-bg: #f1efe9;

  --radius: 14px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(20, 20, 20, .04), 0 8px 24px -12px rgba(20, 20, 20, .12);

  --w-text: 68ch;
  --w-wide: 1120px;
  --gutter: clamp(1rem, 4vw, 2rem);
  /* Header and footer run edge to edge with this gutter, so they follow the window width on large screens. */
  --gutter-bar: clamp(1rem, 3vw, 3rem);

  --step--1: clamp(.85rem, .82rem + .15vw, .95rem);
  --step-0: clamp(1rem, .96rem + .2vw, 1.125rem);
  --step-1: clamp(1.2rem, 1.1rem + .5vw, 1.5rem);
  --step-2: clamp(1.5rem, 1.3rem + 1vw, 2.1rem);
  --step-3: clamp(2rem, 1.6rem + 2vw, 3.2rem);
  --step-4: clamp(2.6rem, 2rem + 3.2vw, 4.4rem);

  --ease: cubic-bezier(.2, .7, .2, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f1413;
    --bg-elev: #151c1b;
    --fg: #e9e7e1;
    --fg-muted: #b0aea7;
    --fg-faint: #8a8982;
    --line: #26302e;
    --accent: #6cc7bf;
    --accent-ink: #9edcd6;
    --accent-soft: #16302e;
    --sage: #1d2a27;
    --pill-bg: #1b2321;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px -12px rgba(0, 0, 0, .5);
  }
}
:root[data-theme="dark"] {
  --bg: #0f1413;
  --bg-elev: #151c1b;
  --fg: #e9e7e1;
  --fg-muted: #b0aea7;
  --fg-faint: #8a8982;
  --line: #26302e;
  --accent: #6cc7bf;
  --accent-ink: #9edcd6;
  --accent-soft: #16302e;
  --sage: #1d2a27;
  --pill-bg: #1b2321;
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px -12px rgba(0, 0, 0, .5);
}

/* Increased contrast (an OS setting): the faint text tone becomes the muted one, per theme. The selector list
   matches the specificity of the dark rules above, as the print block does. */
@media (prefers-contrast: more) {
  :root, :root[data-theme="dark"], :root:not([data-theme="light"]) { --fg-faint: var(--fg-muted); }
}

/* ------------------------------------------------------------------ base */
*, *::before, *::after { box-sizing: border-box; }
/* scroll-padding keeps fragment jumps (the skip link's #main) clear of the sticky header, about 65 px. */
html { scroll-behavior: smooth; scroll-padding-top: 5rem; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* A column whose main takes the free height, so on a short page the footer sits at the bottom of the window. */
  display: flex; flex-direction: column; min-height: 100vh;
}
/* width: 100% because a flex item with auto side margins would shrink to its content; .page keeps centring it. */
main { flex: 1 0 auto; width: 100%; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--accent-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .15em; }
a:hover { color: var(--accent); }
h1, h2, h3, h4 { font-family: var(--font-serif); font-weight: 500; line-height: 1.12; letter-spacing: -.01em; margin: 0 0 .5em; color: var(--fg); }
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
p, ul, ol { margin: 0 0 1em; }
small, .small { font-size: var(--step--1); }
hr { border: 0; border-top: 1px solid var(--line); margin: 3rem 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
/* The skip link focuses <main> (tabindex=-1) by script; a ring around the whole column helps nobody. */
main:focus { outline: none; }

.skip-link { position: absolute; left: -999px; top: 0; background: var(--accent); color: var(--bg); padding: .5rem 1rem; z-index: 100; }
.skip-link:focus { left: 1rem; top: 1rem; }

/* ---------------------------------------------------------------- header */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  padding: .8rem var(--gutter-bar);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.brand { text-decoration: none; color: var(--fg); transition: opacity .35s var(--ease); }
/* Home: the hero already carries the name; show the brand only once it scrolls out of view.
   visibility (flipped after the fade-out, before the fade-in) keeps the hidden link out of the tab order. */
/* Home: over the dark hero the header is transparent with light text; past the hero it is the usual bar. Fixed, so the
   hero runs up under it to the top of the window. An open phone menu brings the usual bar back. */
body.has-hero .site-header { position: fixed; left: 0; right: 0; transition: background-color .3s var(--ease), border-color .3s var(--ease); }
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) {
  background: transparent; border-bottom-color: transparent; backdrop-filter: none; -webkit-backdrop-filter: none;
}
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) .site-nav__link { color: rgba(255, 255, 255, .86); }
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) .site-nav__link:hover,
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) .site-nav__link.is-active { color: #fff; background: rgba(255, 255, 255, .14); }
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) .theme-toggle,
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) .nav-toggle { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .35); color: #fff; }
body.has-hero:not(.past-hero) .site-header:not(:has(.site-nav.is-open)) .nav-toggle__bar { background: #fff; }
body.has-hero:not(.past-hero) .site-header :focus-visible { outline-color: #f4f2ec; }
body.has-hero .brand { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .35s var(--ease), visibility 0s .35s; }
body.has-hero.past-hero .brand { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .35s var(--ease), visibility 0s; }
.brand__name { font-family: var(--font-serif); font-size: clamp(1.35rem, 1rem + .35vw, 1.6rem); font-weight: 500; letter-spacing: -.01em; }
.site-nav { display: flex; align-items: center; gap: .25rem; margin-left: auto; }
.site-nav__link {
  text-decoration: none; color: var(--fg-muted); font-weight: 500; font-size: clamp(.95rem, .7rem + .25vw, 1.1rem);
  padding: .45rem .7rem; border-radius: 999px; transition: color .2s var(--ease), background .2s var(--ease);
}
.site-nav__link:hover { color: var(--fg); background: var(--pill-bg); }
.site-nav__link.is-active { color: var(--fg); background: var(--accent-soft); }
.theme-toggle {
  margin-left: .35rem; display: inline-grid; place-items: center; width: 36px; height: 36px;
  border: 1px solid var(--line); background: var(--bg-elev); color: var(--fg-muted); border-radius: 999px; cursor: pointer;
}
.theme-toggle:hover { color: var(--fg); }
.theme-toggle .icon--moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon--sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon--moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon--sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon--moon { display: block; }
}
.nav-toggle { display: none; }

@media (max-width: 720px) {
  .nav-toggle {
    display: inline-flex; flex-direction: column; gap: 5px; justify-content: center;
    width: 40px; height: 36px; border: 1px solid var(--line); background: var(--bg-elev); border-radius: 10px; cursor: pointer; padding: 0 10px;
  }
  .nav-toggle__bar { display: block; height: 2px; background: var(--fg); border-radius: 2px; transition: transform .25s var(--ease), opacity .2s; }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:first-child { transform: translateY(3.5px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:last-child { transform: translateY(-3.5px) rotate(-45deg); }
  .site-nav {
    position: absolute; left: 0; right: 0; top: 100%; flex-direction: column; align-items: stretch; gap: .15rem;
    padding: .6rem var(--gutter) 1rem; background: var(--bg); border-bottom: 1px solid var(--line);
    display: none;
  }
  .site-nav.is-open { display: flex; }
  .site-nav__link { padding: .7rem .8rem; font-size: 1.05rem; }
  /* The nav is out of flow here, so the hamburger and the theme toggle sit together at the right. */
  .nav-toggle { margin-left: auto; }
}
/* Without JavaScript (no `js` class from the head script) the menu button and the theme toggle cannot work:
   hide them, and on phones show the links as a second header row instead of the closed menu. */
html:not(.js) .nav-toggle, html:not(.js) .theme-toggle { display: none; }
@media (max-width: 720px) {
  html:not(.js) .site-header__inner { flex-wrap: wrap; }
  html:not(.js) .site-nav { display: flex; position: static; flex-direction: row; flex-wrap: wrap; width: 100%; padding: 0; border: 0; background: none; gap: .15rem; margin-left: -.6rem; }
  html:not(.js) .site-nav__link { padding: .45rem .6rem; font-size: .95rem; }
}

/* ---------------------------------------------------------------- layout */
.page { max-width: var(--w-text); margin: 0 auto; padding: clamp(2rem, 5vw, 4rem) var(--gutter) 4rem; }
.page--wide { max-width: var(--w-wide); }
.page--compact-top { padding-top: clamp(1.25rem, 2.5vw, 2rem); }
.section { margin: clamp(3rem, 7vw, 5.5rem) 0; }
.section__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; }
.section__head h2 { margin: 0; }
.section__more { font-size: .95rem; white-space: nowrap; }
.eyebrow { font-family: var(--font-sans); font-size: .8rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin-bottom: .6rem; }
.lede { font-size: var(--step-1); line-height: 1.45; color: var(--fg-muted); max-width: 40ch; }
.prose { max-width: var(--w-text); }
.prose h2 { margin-top: 2.2rem; }
.prose h3 { margin-top: 1.6rem; }

/* A compact introduction shared by the content pages. */
.page-intro h1 { font-size: clamp(2rem, 1.7rem + 1.2vw, 2.8rem); margin-bottom: 1rem; }
.page-intro .lede {
  font-family: var(--font-serif); font-style: italic;
  font-size: var(--step-0); line-height: 1.6; max-width: none;
  margin-bottom: 1rem;
}
.page-intro > :last-child { margin-bottom: 0; }
.page-intro + .section { margin-top: clamp(2rem, 4vw, 3rem); }

/* ------------------------------------------------------------- components */
.btn {
  display: inline-flex; align-items: center; gap: .45rem; padding: .62rem 1rem; border-radius: 999px;
  font-weight: 500; font-size: .95rem; text-decoration: none; border: 1px solid var(--line); color: var(--fg); background: var(--bg-elev);
  transition: transform .2s var(--ease), background .2s, border-color .2s;
}
.btn:hover { transform: translateY(-1px); border-color: var(--fg-faint); color: var(--fg); }
.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.btn--primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); color: var(--bg); }

.pill {
  display: inline-block; font-size: .72rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  padding: .22rem .55rem; border-radius: 999px; background: var(--pill-bg); color: var(--fg-muted); white-space: nowrap;
}
.pill--preprint { background: var(--accent-soft); color: var(--accent-ink); }
.pill--review { background: #f3ead9; color: #7a5a17; }
:root[data-theme="dark"] .pill--review { background: #33281a; color: #e3c27a; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .pill--review { background: #33281a; color: #e3c27a; } }

.grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.card {
  background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.35rem 1.35rem 1.2rem;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: color-mix(in srgb, var(--line) 40%, var(--accent)); }
.card h3 { font-size: var(--step-1); margin-bottom: .45rem; }
.card p { color: var(--fg-muted); margin: 0; font-size: .97rem; }
.card__kicker { display: block; font-size: .78rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); margin-bottom: .5rem; }
/* Reduced motion: hover keeps its colour, border and shadow changes but no longer lifts buttons and cards. */
@media (prefers-reduced-motion: reduce) { .btn:hover, .card:hover { transform: none; } }

/* publications */
.pubs { list-style: none; padding: 0; margin: 0; }
.pub { padding: 1.15rem 0; border-top: 1px solid var(--line); display: grid; grid-template-columns: 1fr auto; gap: .5rem 1.25rem; align-items: start; }
.pub:last-child { border-bottom: 1px solid var(--line); }
.pub__title { font-family: var(--font-serif); font-size: var(--step-1); font-weight: 500; line-height: 1.25; margin: 0 0 .25rem; }
/* A linked title is underlined faintly so it can be told from an unlinked one (two entries have no link). */
.pub__title a { text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: var(--fg-faint); text-underline-offset: .14em; color: var(--fg); }
.pub__title a:hover { color: var(--accent); text-decoration-color: var(--accent); }
/* Prose under a title is capped at 80ch: on the 1120 px research page a full-width
   line would run to about 140 characters. Below 80ch (phones) width: 100% still wins. */
.pub__meta { max-width: 80ch; color: var(--fg-muted); font-size: .95rem; margin: 0; }
.pub__links { margin: .45rem 0 0; font-size: .9rem; }
.pub__note { color: var(--fg-faint); }
.pub__summary {
  width: 100%; max-width: 80ch; color: var(--fg-muted); font-size: .95rem; margin: .5rem 0 0;
  text-align: justify; text-justify: inter-word;
  -webkit-hyphens: auto; hyphens: auto;
}
.pub__abstract { color: var(--fg-muted); font-size: .9rem; margin-top: .65rem; }
.pub__abstract summary { width: max-content; padding-block: .15rem; color: var(--accent-ink); cursor: pointer; text-decoration: underline; text-underline-offset: .15em; }
.pub__abstract p {
  width: 100%; max-width: 80ch; margin: .6rem 0 0;
  text-align: justify; text-justify: inter-word;
  -webkit-hyphens: auto; hyphens: auto;
}
@media (max-width: 560px) { .pub { grid-template-columns: 1fr; } }
.research-list { margin-top: 0; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.research-list .pub:first-child { padding-top: 0; border-top: 0; }
/* The closing note below has its own top rule, so the list ends without one, as on the other pages. */
.research-list .pub:last-child { border-bottom: 0; }
.research-list .section__head { margin-bottom: .65rem; }
.research-list .section__head h2 { font-size: var(--step-2); }
.page-note {
  width: 100%; margin: 2rem 0 0; padding: 1rem 0 0;
  border-top: 1px solid var(--line); text-align: left;
}
.page-note p {
  max-width: 80ch; margin: 0; font-family: var(--font-serif); font-size: .9rem;
  font-style: italic; line-height: 1.55; color: var(--fg-faint);
}

/* timeline / CV */
.cv-section { margin: clamp(2.4rem, 5vw, 3.6rem) 0; }
.cv-section:first-of-type { margin-top: 0; }
.cv-section .section__head { margin-bottom: .65rem; }
.cv-section .section__head h2 { font-size: var(--step-2); }
.timeline { list-style: none; padding: 0; margin: 0; }
.timeline li { display: grid; grid-template-columns: 8.5rem 1fr; gap: 1rem; padding: .75rem 0; border-top: 1px solid var(--line); }
.timeline li:last-child { border-bottom: 1px solid var(--line); }
.timeline__when { color: var(--fg-faint); font-variant-numeric: tabular-nums; font-size: .95rem; padding-top: .1rem; }
.timeline__what strong { display: block; font-weight: 600; }
.timeline__what span { color: var(--fg-muted); font-size: .95rem; }
.timeline__what .note { display: block; color: var(--fg-faint); font-size: .9rem; margin-top: .15rem; }
@media (max-width: 560px) { .timeline li { grid-template-columns: 1fr; gap: .15rem; } }

/* news */
.news { list-style: none; padding: 0; margin: 0; }
.news li { display: grid; grid-template-columns: 7rem 1fr; gap: 1rem; padding: .55rem 0; border-top: 1px dashed var(--line); }
.news time { color: var(--fg-faint); font-variant-numeric: tabular-nums; font-size: .92rem; }
/* Like the paper summaries, news text wraps at the site's text measure on the wide home page; the row separators keep the full width. */
.news li > span { max-width: var(--w-text); }
@media (max-width: 560px) { .news li { grid-template-columns: 1fr; gap: .1rem; } }

/* stories */
/* The first story starts right under the header, like the first block of the other compact pages. */
.stories-list { margin-top: 0; }
.story { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.5rem; align-items: center; padding: 1.5rem 0; border-top: 1px solid var(--line); }
.story:first-child { padding-top: 0; border-top: 0; }
/* Even stories put the media on the right (order 2 moves the figure behind the text div), as the teaching features do. */
.story:nth-child(even) .story__media { order: 2; }
.story__media { margin: 0; border-radius: var(--radius); overflow: hidden; background: var(--sage); aspect-ratio: 4 / 3; display: grid; place-items: center; color: var(--fg-muted); font-size: .9rem; }
.story__media img { width: 100%; height: 100%; object-fit: cover; }
.story__media--video { aspect-ratio: 16 / 9; background: #000; position: relative; }
/* The thumbnail link (and the player that replaces it) cover the whole frame, so the image is cropped around its
   centre: YouTube's 4:3 hqdefault loses exactly its black bars in the 16:9 frame. */
.story__media--video > .video, .story__media--video > iframe { position: absolute; inset: 0; width: 100%; height: 100%; }
.video { position: relative; display: block; width: 100%; height: 100%; }
/* Phone video: an upright frame, centred in its column, so its cover fills it with no side bars. */
.story__media--portrait { aspect-ratio: 9 / 16; width: min(100%, 300px); justify-self: center; }
.video__play { position: absolute; left: 50%; top: 50%; width: 3.5rem; height: 3.5rem; margin: -1.75rem 0 0 -1.75rem; border-radius: 50%; background: rgba(0, 0, 0, .55); transition: background .2s; }
.video__play::after { content: ""; position: absolute; left: 1.4rem; top: 1.05rem; border-style: solid; border-width: .7rem 0 .7rem 1.1rem; border-color: transparent transparent transparent #fff; }
.video:hover .video__play, .video:focus-visible .video__play { background: var(--accent); }
.story__media iframe { width: 100%; height: 100%; border: 0; display: block; }
@media (max-width: 640px) { .story { grid-template-columns: 1fr; } .story:nth-child(even) .story__media { order: 0; } }

/* virtual classroom (/teaching/ and the course and chapter pages under it) */
/* Covers: the two drawings in _includes/classroom/, on the accent tint (macroeconomics) or sage (econometrics). */
.course-feature__cover {
  position: relative; overflow: hidden; aspect-ratio: 16 / 10;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--accent-soft); color: var(--accent-ink);
}
.course-feature__cover--metrics { background: var(--sage); }
.course-feature__cover svg { display: block; width: 100%; height: 100%; }
.course-feature__grid { fill: none; stroke: currentColor; stroke-width: 1; opacity: .13; }
.course-feature__axis { fill: none; stroke: currentColor; stroke-width: 2; opacity: .28; }
.course-feature__line { fill: none; stroke: currentColor; stroke-width: 4; stroke-linecap: round; }
.course-feature__cover circle { fill: var(--bg-elev); stroke: currentColor; stroke-width: 3; }
.course-feature__thin { fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; opacity: .6; }
.course-feature__arrow { fill: currentColor; }
.course-feature__label { fill: currentColor; font: 600 24px var(--font-sans); text-anchor: middle; }
.course-feature__points { opacity: .9; }

.classroom-intro { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.classroom-intro .lede { font-family: var(--font-serif); font-style: italic; font-size: var(--step-0); line-height: 1.6; max-width: 62ch; margin: 0; }
/* Invitation-code form; classroom.js shows it (without JavaScript it stays hidden and the noscript note shows). */
.classroom-gate { margin: 0 0 clamp(2rem, 4vw, 3rem); }
.classroom-gate__form { padding: 1.1rem 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg-elev); max-width: 34rem; }
.classroom-gate__form label { display: block; font-weight: 500; margin-bottom: .5rem; }
.classroom-gate__row { display: flex; flex-wrap: wrap; gap: .6rem; }
.classroom-gate__row input {
  flex: 1 1 12rem; min-width: 0; font: inherit; color: var(--fg); background: var(--bg);
  border: 1px solid var(--line); border-radius: 999px; padding: .55rem 1rem;
}
.classroom-gate__row input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.classroom-gate .btn, .cr-block .btn { cursor: pointer; font-family: inherit; }
.classroom-gate__msg { margin: .6rem 0 0; font-size: .9rem; color: var(--fg-muted); min-height: 1.4em; }
.classroom__back { margin: 0 0 1.5rem; font-size: .9rem; }

/* Home: one row of three level cards per subject. */
.classroom-subject { margin: 0 0 clamp(2rem, 4vw, 3rem); }
.classroom-subject .section__head h2, .classroom__content .section__head h2 { font-size: var(--step-2); margin: 0; }
.classroom__content .section { margin: clamp(2rem, 4vw, 3rem) 0 0; }
.classroom-grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.classroom-card { display: flex; flex-direction: column; text-decoration: none; color: inherit; padding: .75rem .75rem 1.1rem; }
.classroom-card:hover { color: inherit; }
.classroom-card .course-feature__cover { border-radius: var(--radius-sm); }
.classroom-card__body { padding: .9rem .5rem 0; }
.classroom-card__body h3 { margin: 0 0 .35rem; }
.classroom-card__state { display: inline-flex; align-items: center; gap: .35rem; margin-top: .8rem; font-size: .85rem; color: var(--fg-faint); }
.classroom-card__state svg { flex: none; }
@media (max-width: 860px) { .classroom-grid { grid-template-columns: 1fr; } }

/* Course page: the premise, the cast and the chapter list. */
.course-cast { list-style: none; margin: 0; padding: 0; border-bottom: 1px solid var(--line); }
.course-cast li { display: grid; grid-template-columns: 12rem minmax(0, 1fr); gap: 1rem; padding: .75rem 0; border-top: 1px solid var(--line); }
.course-cast strong { font-weight: 500; }
.course-cast span { color: var(--fg-muted); }
.chapter-list { list-style: none; margin: 0; padding: 0; border-bottom: 1px solid var(--line); }
.chapter-list li { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto; gap: 1rem; align-items: baseline; padding: .95rem 0; border-top: 1px solid var(--line); }
.chapter-list__n { color: var(--fg-faint); font-size: .85rem; font-variant-numeric: tabular-nums; }
.chapter-list__title { font-family: var(--font-serif); font-size: var(--step-1); line-height: 1.25; }
.chapter-list__title > span, .chapter-list__title a > span { display: block; }
.chapter-list__title a { color: var(--fg); text-decoration: none; }
.chapter-list__title a:hover { color: var(--accent); }
.chapter-list__topic { display: block; margin-top: .25rem; font-family: var(--font-sans); font-size: .85rem; color: var(--fg-faint); }
.chapter-list__pills { display: flex; gap: .35rem; }
.chapter-list li.is-planned .chapter-list__title { color: var(--fg-faint); }
@media (max-width: 680px) {
  .course-cast li, .chapter-list li { grid-template-columns: 1fr; gap: .2rem; }
}

/* Chapter page. Story passages are set in the serif face; the working parts (model, exercises) in the sans. */
.chapter__head { margin-bottom: 2rem; }
.chapter__kicker { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0 0 .9rem; font-size: .8rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.chapter__title { font-size: var(--step-3); margin: 0; }
.chapter__title span { display: block; }
.chapter__title span + span { font-style: italic; color: var(--fg-muted); font-size: .72em; margin-top: .35rem; }
.chapter__previously { margin: 0 0 2rem; padding-left: 1rem; border-left: 2px solid var(--sage); color: var(--fg-muted); font-size: .95rem; }
.chapter__body > p, .chapter__body > ul, .chapter__body > ol, .chapter__body > blockquote { font-family: var(--font-serif); font-size: 1.12em; line-height: 1.65; }
.chapter__body h2 { font-size: var(--step-2); margin-top: 2.2em; }
.chapter__body blockquote { margin: 1.2em 0; padding-left: 1rem; border-left: 2px solid var(--accent); color: var(--fg-muted); font-style: italic; }
.chapter__body table { border-collapse: collapse; margin: 1.5em 0; font-size: .95rem; font-variant-numeric: tabular-nums; display: block; overflow-x: auto; }
.chapter__body th, .chapter__body td { padding: .45rem .9rem .45rem 0; border-bottom: 1px solid var(--line); text-align: left; }
.chapter__body thead th { font-weight: 600; color: var(--fg-muted); border-bottom-color: var(--fg-faint); }
.math-display { display: block; overflow-x: auto; margin: 1em 0; text-align: center; }
.math-display:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chapter__points { margin: 3rem 0 0; }
.chapter__points h2 { font-size: var(--step-1); }
.chapter__points ul { margin: 0; padding: 0; list-style: none; border-bottom: 1px solid var(--line); }
.chapter__points li { padding: .65rem 0; border-top: 1px solid var(--line); }
.chapter__nav { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .6rem; margin-top: 2rem; }

/* Interactive blocks: a card each. */
.cr-block { margin: 2rem 0; padding: 1.25rem 1.35rem; background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius); }
.cr-block__label { display: block; font-size: .78rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); margin-bottom: .6rem; }
.cr-block > :last-child { margin-bottom: 0; }
.cr-choice__prompt { font-family: var(--font-serif); font-size: 1.1em; }
.cr-choice__options { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1rem 0 0; }
.cr-choice__options .btn { text-align: left; }
.cr-choice__options .btn[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.cr-choice__result { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); font-family: var(--font-serif); }
.cr-choice__result > :last-child { margin-bottom: 0; }
/* Story media: listen bar, progress bar, completion card, conversation, illustration, scroll-driven drawing, video. */
.cr-listen { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1.1rem 0 0; }
.cr-listen[hidden], .cr-dialogue__actions[hidden] { display: none; }
.cr-listen .btn, .cr-model__play .btn, .cr-complete .btn { cursor: pointer; font-family: inherit; }
.is-speaking { background: var(--accent-soft); box-shadow: 0 0 0 .4rem var(--accent-soft); border-radius: 4px; }
.cr-mission {
  position: sticky; top: 64px; z-index: 5; margin: 0 0 2rem; padding: .55rem .8rem;
  background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--line); border-radius: 999px;
}
.cr-mission ol { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .3rem 1rem; margin: 0; padding: 0; list-style: none; font-size: .85rem; color: var(--fg-muted); }
.cr-mission li { display: inline-flex; align-items: center; gap: .4rem; }
.cr-mission__dot { width: .8rem; height: .8rem; border-radius: 50%; border: 2px solid var(--fg-faint); }
.cr-mission li.is-done { color: var(--fg); }
.cr-mission li.is-done .cr-mission__dot { background: var(--accent); border-color: var(--accent); }
.cr-complete { margin: 2rem 0; padding: 1.4rem 1.5rem; border-radius: var(--radius); background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--line) 40%, var(--accent)); }
.cr-complete__title { font-family: var(--font-serif); font-size: var(--step-1); margin: 0 0 .8rem; }
.cr-complete dl { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1.2rem; margin: 0 0 1rem; }
.cr-complete dt { color: var(--fg-muted); }
.cr-complete dd { margin: 0; font-weight: 500; }
.cr-complete__actions { margin: 0; }
.cr-dialogue { margin: 2rem 0; }
.cr-dialogue__lines { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.cr-dialogue__line { display: flex; align-items: flex-end; gap: .6rem; animation: cr-rise .35s var(--ease); }
.cr-dialogue__line--you { flex-direction: row-reverse; }
.cr-dialogue__avatar {
  flex: none; width: 2.4rem; height: 2.4rem; border-radius: 50%; display: grid; place-items: center;
  font-size: .8rem; font-weight: 600; color: var(--accent-ink); background: var(--accent-soft); border: 2px solid var(--accent);
}
.cr-dialogue__line--you .cr-dialogue__avatar { background: var(--sage); }
.cr-dialogue__bubble {
  max-width: 34rem; padding: .6rem .9rem; border-radius: 1rem 1rem 1rem .25rem; background: var(--bg-elev);
  border: 1px solid var(--line); font-family: var(--font-serif); font-size: 1.05em; line-height: 1.5;
}
.cr-dialogue__line--you .cr-dialogue__bubble { border-radius: 1rem 1rem .25rem 1rem; background: var(--accent-soft); border-color: transparent; }
.cr-dialogue__who { display: block; font-family: var(--font-sans); font-size: .75rem; font-weight: 600; color: var(--fg-muted); margin-bottom: .1rem; }
.cr-dialogue__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem; margin: 1rem 0 0; }
.cr-dialogue__actions .btn { cursor: pointer; font-family: inherit; }
.cr-dialogue__all { font: inherit; font-size: .9rem; color: var(--accent); background: none; border: 0; padding: 0; text-decoration: underline; cursor: pointer; }
@keyframes cr-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.cr-illustration { margin: 1.5rem 0 2rem; }
.cr-illustration__art { border-radius: var(--radius); overflow: hidden; background: var(--accent-soft); color: var(--accent-ink); border: 1px solid var(--line); }
.cr-illustration__art svg, .cr-scene__figure svg { display: block; width: 100%; height: auto; }
.cr-illustration figcaption { margin-top: .5rem; font-size: .85rem; color: var(--fg-muted); }
.cr-fig__line { fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.cr-fig__thin { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .6; }
.cr-fig__fill { fill: var(--bg-elev); stroke: currentColor; stroke-width: 3; stroke-linejoin: round; }
.cr-fig__solid { fill: currentColor; }
.cr-fig__text { fill: currentColor; font-family: var(--font-sans); font-weight: 600; }
.cr-fig__serif { fill: currentColor; font-family: var(--font-serif); font-weight: 500; }
.cr-scene { margin: 2rem 0; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--bg-elev); }
.cr-scene__figure { background: var(--accent-soft); color: var(--accent-ink); }
.cr-scene.is-stepping .cr-scene__figure [data-step] { opacity: 0; transition: opacity .45s var(--ease); }
.cr-scene.is-stepping .cr-scene__figure [data-step].is-on { opacity: 1; }
.cr-scene__panel { padding: .9rem 1.1rem 1rem; }
.cr-scene__steps { margin: 0; padding: 0; list-style: none; font-family: var(--font-serif); font-size: 1.15em; line-height: 1.45; }
.cr-scene:not(.is-stepping) .cr-scene__step + .cr-scene__step { margin-top: .4rem; }
.cr-scene.is-stepping .cr-scene__steps { min-height: 3em; }
.cr-scene__nav { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin: .8rem 0 0; }
.cr-scene__nav[hidden] { display: none; }
.cr-scene__nav .btn { cursor: pointer; font-family: inherit; }
.cr-scene__nav .btn:disabled { opacity: .45; cursor: default; transform: none; }
.cr-scene__count { font-size: .85rem; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.cr-download { background: var(--accent-soft); border-color: color-mix(in srgb, var(--line) 40%, var(--accent)); }
.cr-download__title { font-family: var(--font-serif); font-size: var(--step-1); margin: 0 0 .4rem; }
.cr-download__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem; margin: .8rem 0 0; }
.cr-download__meta { font-size: .85rem; color: var(--fg-muted); }
.cr-video { margin: 0 0 2rem; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden; background: #000; position: relative; }
.cr-video iframe, .cr-video img { width: 100%; height: 100%; border: 0; object-fit: cover; display: block; }
.cr-model__play { margin: 0 0 .5rem; }
@media (prefers-reduced-motion: reduce) {
  .cr-dialogue__line { animation: none; }
  .cr-scene.is-stepping .cr-scene__figure [data-step] { transition: none; }
}
.chapter__time { color: var(--fg-faint); font-weight: 500; letter-spacing: .04em; }
.chapter__time::before { content: "·"; margin-right: .5rem; }
.cr-predict { border-color: color-mix(in srgb, var(--line) 40%, var(--accent)); }
.cr-predict__noted { margin: .9rem 0 0; font-size: .9rem; color: var(--fg-muted); }
.cr-recall__you { margin: 0 0 .5rem; }
.cr-recall__note > :last-child { margin-bottom: 0; }
.cr-recall__note { font-family: var(--font-serif); }
.cr-critique__ask { margin: 0 0 .75rem; font-weight: 500; }
.cr-critique__ask span, .cr-critique__who {
  display: block; font-size: .78rem; font-weight: 500; color: var(--fg-muted); margin-bottom: .2rem;
}
.cr-critique__answer { margin: 0 0 1rem; padding: .85rem 1rem; background: var(--pill-bg); border-radius: var(--radius-sm); }
.cr-critique__answer p { margin: 0; line-height: 1.6; }
.cr-critique__s sup { color: var(--accent); font-weight: 600; margin-right: .1rem; }
.cr-askai__prompt {
  margin: .75rem 0; padding: .85rem 1rem; max-height: 14rem; overflow: auto; white-space: pre-wrap;
  font: .85rem/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--fg);
  background: var(--pill-bg); border-radius: var(--radius-sm);
}
.cr-askai__prompt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cr-askai__actions { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.cr-askai__msg { font-size: .9rem; color: var(--fg-muted); }
.cr-model__challenge { margin: 0 0 1rem; padding: .7rem .9rem; border-left: 2px solid var(--accent); background: var(--accent-soft); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; font-size: .95rem; }
.cr-model__challenge p { margin: 0; }
.cr-model__solved { margin-top: .4rem !important; color: var(--accent-ink); }
.cr-model__controls { display: grid; gap: .8rem 1.5rem; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); margin: .5rem 0 1rem; }
.cr-model__control label { display: flex; justify-content: space-between; gap: .5rem; font-size: .9rem; }
.cr-model__control output { font-variant-numeric: tabular-nums; color: var(--fg-muted); }
.cr-model__control input[type="range"] { width: 100%; accent-color: var(--accent); min-height: 24px; }
.cr-model__note { font-size: .85rem; color: var(--fg-faint); margin: .75rem 0 0; }
.cr-quiz__q { margin: 0; padding: 1rem 0; border: 0; border-top: 1px solid var(--line); min-width: 0; }
.cr-quiz__q:first-of-type { border-top: 0; padding-top: 0; }
.cr-quiz__q legend { padding: 0; margin-bottom: .6rem; font-weight: 500; }
.cr-quiz__q label { display: flex; gap: .5rem; align-items: baseline; margin: .35rem 0; }
.cr-quiz__q input[type="text"] { font: inherit; color: var(--fg); background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .4rem .6rem; width: 9rem; }
.cr-quiz__q .btn { margin-top: .6rem; }
.cr-quiz__feedback { margin: .6rem 0 0; font-size: .95rem; }
.cr-quiz__feedback:empty { display: none; }

/* Line chart of the model blocks. Series colours: slots 1-3 of the validated categorical palette, stepped per theme
   (light #1baf7a is under 3:1 on white, so every line also has a direct label, and a table view sits under the chart). */
.cr-chart { --series-1: #2a78d6; --series-2: #eb6834; --series-3: #1baf7a; position: relative; }
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .cr-chart { --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; }
}
:root[data-theme="dark"] .cr-chart { --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; }
.cr-chart__legend { display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; margin: 0 0 .5rem; padding: 0; list-style: none; font-size: .85rem; color: var(--fg-muted); }
.cr-chart__legend li { display: inline-flex; align-items: center; gap: .4rem; }
.cr-chart__key { display: inline-block; width: 1rem; height: 2px; border-radius: 1px; }
.cr-chart svg { display: block; width: 100%; height: auto; overflow: visible; touch-action: pan-y; }
.cr-chart__grid { stroke: var(--line); stroke-width: 1; }
.cr-chart__zero { stroke: var(--fg-faint); stroke-width: 1; }
.cr-chart__tick { fill: var(--fg-faint); font-size: 11px; font-family: var(--font-sans); }
.cr-chart__line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.cr-chart__label { fill: var(--fg-muted); font-size: 12px; font-family: var(--font-sans); }
.cr-chart__leader { stroke: var(--fg-faint); stroke-width: 1; }
.cr-chart__cross { stroke: var(--fg-faint); stroke-width: 1; }
.cr-chart__ref { stroke: var(--fg-muted); stroke-width: 1; stroke-dasharray: 4 3; }
.cr-chart__mark { stroke: var(--accent); stroke-width: 1.5; }
.cr-chart__point { fill: var(--bg-elev); stroke: var(--fg-muted); stroke-width: 1.5; }
.cr-model__readout { margin: .75rem 0 0; font-size: .9rem; font-variant-numeric: tabular-nums; }
.cr-model__readout:empty { display: none; }
.cr-chart__dot { stroke: var(--bg-elev); stroke-width: 2; }
.cr-chart__tip {
  position: absolute; top: 0; pointer-events: none; padding: .45rem .6rem; font-size: .8rem; line-height: 1.45;
  background: var(--bg-elev); color: var(--fg); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.cr-chart__tip i { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%; margin-right: .35rem; }
.cr-chart__table { margin-top: .75rem; font-size: .85rem; }
.cr-chart__table summary { cursor: pointer; color: var(--fg-muted); }
.cr-chart__scroll { max-height: 16rem; overflow: auto; margin-top: .5rem; }
.cr-chart__table table { border-collapse: collapse; font-variant-numeric: tabular-nums; }
.cr-chart__table th, .cr-chart__table td { padding: .2rem .8rem .2rem 0; text-align: right; border-bottom: 1px solid var(--line); }
@media (forced-colors: active) { .cr-chart__line { stroke: CanvasText; } .cr-chart__key { background: CanvasText !important; } }

/* footer */
.site-footer { border-top: 1px solid var(--line); margin-top: 1.5rem; background: var(--bg); }
.site-footer__inner { padding: 1.5rem var(--gutter-bar); display: flex; flex-wrap: wrap; justify-content: space-between; gap: .75rem 2rem; align-items: center; color: var(--fg-muted); font-size: .82rem; }
.site-footer__name { font-family: var(--font-sans); font-size: inherit; margin: 0; }
.site-footer__links { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem 1rem; font-size: inherit; }
.site-footer__links a { display: inline-flex; align-items: center; gap: .35rem; padding-block: .25rem; text-decoration: none; color: inherit; }
.site-footer__links a:hover { color: var(--fg); text-decoration: underline; }
.site-footer__links .icon { width: 14px; height: 14px; flex: none; opacity: .8; }
@media (max-width: 720px) {
  .site-footer__inner { flex-direction: column; align-items: flex-start; gap: .5rem; }
}
/* Forced colors (Windows high contrast) replace backgrounds and paint every border: keep the hamburger bars,
   the play triangle and the current-page mark visible, in system colours only. */
@media (forced-colors: active) {
  .nav-toggle__bar { background: CanvasText; }
  .video__play { forced-color-adjust: none; background: Canvas; border: 1px solid CanvasText; }
  .video__play::after { border-color: transparent transparent transparent CanvasText; }
  .site-nav__link.is-active { text-decoration: underline; text-underline-offset: .3em; }
}
/* ------------------------------------------------------------------ hero */
/* The home page itself has no width limit and no gutter, so the hero spans the full body width without
   viewport-width units (they count the vertical scrollbar and add a horizontal one); .home-body restores
   the 1120 px column and the gutter for the sections below. */
.page--home { max-width: none; padding-top: 0; padding-left: 0; padding-right: 0; }
.hero {
  position: relative; overflow: hidden;
  width: 100%; margin-left: 0;
  height: 100vh;
  height: 100svh; min-height: 480px;
  display: grid; align-items: center;
  color: #f4f2ec; background: #0b0f14;
}
.hero__media { position: absolute; inset: 0; }
.hero__img { position: absolute; inset: 0; opacity: 0; transition: opacity 1.6s var(--ease); will-change: opacity; }
.hero[data-slide="0"] [data-slide="0"], .hero[data-slide="1"] [data-slide="1"], .hero[data-slide="2"] [data-slide="2"] { opacity: 1; }
.hero__img img { width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* Focal points: on very wide windows only part of each photo's height shows, so keep the bicycle and the sign
   (bottom of the Leutasch photo) and the head (top of the portrait) in view. */
.hero__img--earth img { object-position: center 85%; }
.hero__img--human img { object-position: right 12%; }
.hero__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(6, 9, 14, .78) 0%, rgba(6, 9, 14, .5) 45%, rgba(6, 9, 14, .08) 80%),
              linear-gradient(0deg, rgba(6, 9, 14, .5) 0%, rgba(6, 9, 14, 0) 45%);
}
.hero__text {
  position: relative; width: 100%; max-width: var(--w-wide); margin: 0 auto;
  padding: 3rem var(--gutter) 3.5rem;
}
/* Full opacity: at .82 the small eyebrow text fell under 4.5:1 over the brighter parts of the photos. */
.hero__eyebrow { font-size: .8rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; margin: 0 0 1rem; }
.hero__name { font-size: var(--step-4); color: inherit; margin: 0; }
.hero__actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.4rem; }
.hero .btn { min-width: 112px; justify-content: center; background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .35); color: #fff; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.hero .btn:hover { background: rgba(255, 255, 255, .2); border-color: rgba(255, 255, 255, .6); color: #fff; }
.hero .btn--primary { background: #f4f2ec; border-color: #f4f2ec; color: #272a29; }
.hero .btn--primary:hover { background: #fff; border-color: #fff; color: #202322; }
.hero :focus-visible { outline-color: #f4f2ec; }
/* Photo controls: small arrows at the sides, dots above the scroll cue; same translucent style as the hero buttons. */
/* The controls layer covers the hero without taking a grid row (the text keeps its place); only the buttons take clicks. */
.hero__controls { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero__controls button { pointer-events: auto; }
.hero__controls[hidden] { display: none; }
.hero__arrow {
  position: absolute; top: 50%; z-index: 1; transform: translateY(-50%);
  display: inline-grid; place-items: center; width: 40px; height: 40px; padding: 0; border-radius: 999px; cursor: pointer;
  color: #fff; background: rgba(255, 255, 255, .08); border: 1px solid rgba(255, 255, 255, .28); opacity: .75;
  transition: opacity .2s var(--ease), background .2s var(--ease);
}
.hero__arrow:hover, .hero__arrow:focus-visible { opacity: 1; background: rgba(255, 255, 255, .2); }
.hero__arrow--prev { left: var(--gutter-bar); }
.hero__arrow--next { right: var(--gutter-bar); }
.hero__dots { position: absolute; left: 50%; bottom: 5rem; z-index: 1; transform: translateX(-50%); display: flex; gap: .2rem; }
.hero__dot { width: 24px; height: 24px; padding: 0; border: 0; background: none; cursor: pointer; display: grid; place-items: center; }
.hero__dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 999px; background: rgba(255, 255, 255, .45);
  transition: width .3s var(--ease), background .3s var(--ease);
}
.hero__dot[aria-current="true"]::before { width: 20px; background: #fff; }
/* Tablets and small laptops: the text column reaches the left edge, so the arrows move down beside the dots. */
@media (min-width: 721px) and (max-width: 1240px) {
  .hero__arrow { top: auto; bottom: calc(5rem - 8px); transform: none; }
  .hero__arrow--prev { left: calc(50% - 100px); }
  .hero__arrow--next { right: calc(50% - 100px); }
}
.hero__dot:hover::before { background: rgba(255, 255, 255, .8); }
/* Scroll cue: a bouncing chevron at the bottom centre that links to the content below (still for reduced motion). */
.hero__scroll {
  position: absolute; left: 50%; bottom: 1.4rem; z-index: 1; transform: translateX(-50%);
  display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 999px;
  color: #fff; background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .3);
  animation: hero-bounce 2s var(--ease) infinite;
}
.hero__scroll:hover { color: #fff; background: rgba(255, 255, 255, .2); }
@keyframes hero-bounce { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, 8px); } }

/* 天 · 地 · 人 — one glyph per photo (left / centre / right), 志莽行书, fading with its image */
.hero__glyph {
  position: absolute; bottom: 1.1rem; opacity: 0; transition: opacity 1.6s var(--ease);
  font-family: "Zhi Mang Xing", "Kaiti SC", "STKaiti", "KaiTi", "Noto Serif SC", serif;
  font-size: clamp(1.6rem, 2.6vw, 2.2rem); line-height: 1; color: #f4f2ec;
  -webkit-text-stroke: .015em currentColor; paint-order: stroke fill;
  text-shadow: 0 .04em .12em rgba(0, 0, 0, .3);
}
.hero__glyph--l { left: var(--gutter); }
.hero__glyph--c { left: 50%; transform: translateX(-50%); }
.hero__glyph--r { right: var(--gutter); }
.hero[data-slide="0"] .hero__glyph[data-slide="0"], .hero[data-slide="1"] .hero__glyph[data-slide="1"], .hero[data-slide="2"] .hero__glyph[data-slide="2"] { opacity: .55; }
.hero[data-slide="0"] .hero__glyph[data-slide="0"] { opacity: .4; }

@media (max-width: 720px) {
  .hero { align-items: end; min-height: 440px; }
  .hero__text { padding: 2.5rem var(--gutter) 7.6rem; }
  .hero__arrow { width: 34px; height: 34px; top: 42%; }
  .hero__arrow svg { width: 17px; height: 17px; }
  .hero__dots { bottom: 4.5rem; }
  /* Phones show a narrow upright slice: the galaxy's core, the big summit (the sign lies behind the text) and the whole face. */
  .hero__img img { object-position: 62% center; }
  .hero__img--earth img { object-position: 20% center; }
  .hero__img--human img { object-position: 85% center; }
  .hero__scrim {
    background: linear-gradient(0deg, rgba(6, 9, 14, .82) 0%, rgba(6, 9, 14, .5) 50%, rgba(6, 9, 14, .1) 85%);
  }
  .hero__glyph { bottom: .8rem; font-size: 1.5rem; }
}
@media (prefers-reduced-motion: reduce) { .hero__img, .hero__glyph { transition: none; } .hero__scroll { animation: none; } .hero__dot::before { transition: none; } }
/* Short viewports (a phone held sideways): let the window height decide, so the buttons stay on the first screen. */
@media (max-height: 560px) { .hero { min-height: 0; } }

.home-body { max-width: var(--w-wide); margin: 0 auto; padding: clamp(1rem, 3vw, 2rem) var(--gutter) 0; }

/* reveal on scroll (progressive enhancement): the head script adds `js` to <html>, so without
   JavaScript nothing is hidden and the sections render as plain blocks. */
.js .reveal { opacity: 0; transform: translateY(10px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.js .reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; transition: none; } }

/* ------------------------------------------------------------- utilities */
/* Hidden visually, still read by assistive technology (e.g. the page-title h1 the layout adds on compact_top pages). */
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Print (CV and Research above all): a plain light page without chrome, hero or hidden reveal sections. */
@media print {
  .site-nav, .nav-toggle, .site-footer, .skip-link, .hero__media, .hero__actions, .hero__scroll, .hero__controls, .section__more, .theme-toggle,
  .story__media--video, .course-feature__cover, .classroom-gate, .cr-chart__tip, .cr-mission, .cr-listen,
  .cr-model__play, .cr-dialogue__actions, .cr-video { display: none; }
  .cr-dialogue__line[hidden] { display: flex; }
  .cr-scene__figure [data-step] { opacity: 1 !important; }
  .cr-scene__step[hidden] { display: list-item; }
  .cr-scene__nav { display: none !important; }
  /* The header prints with the brand name only (the nav and toggles are hidden above); the page title h1 the
     layout keeps for screen readers prints as a heading under it, so a printed page says whose and which it is. */
  .site-header, body.has-hero .site-header { position: static; backdrop-filter: none; -webkit-backdrop-filter: none; }
  body.has-hero .brand { opacity: 1; visibility: visible; transition: none; }
  main > h1.visually-hidden { position: static; width: auto; height: auto; margin: 0 0 .5em; overflow: visible; clip: auto; clip-path: none; white-space: normal; font-size: var(--step-3); }
  /* The light tokens, at the specificity of the two dark-theme rules above so they win whatever the theme. */
  :root, :root[data-theme="dark"], :root:not([data-theme="light"]) {
    --bg: #fbfaf7;
    --bg-elev: #ffffff;
    --fg: #1b1b1a;
    --fg-muted: #5f5e5a;
    --fg-faint: #6f6e69;
    --line: #e6e3dc;
    --accent: #1f6f6b;
    --accent-ink: #145350;
    --accent-soft: #e6f0ee;
    --sage: #cfdbd3;
    --pill-bg: #f1efe9;
    --shadow: none;
    color-scheme: light;
  }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .hero { height: auto; min-height: 0; color: var(--fg); background: none; }
  a { color: inherit; }
  /* Links print in the text colour, so a linked paper title prints its URL after the title. */
  .pub__title a[href^="http"]::after { content: " (" attr(href) ")"; font-family: var(--font-sans); font-size: .75rem; font-weight: 400; color: var(--fg-muted); }
  .card, .pub, .timeline li, .story, .cr-block { break-inside: avoid; }
}
