/* Shared styles for every page. Edit here, then run: node build.mjs */
  :root {
    --paper: #f7f4ee;
    --ink: #191714;
    --body: #3f3a33;
    --muted: #6b6459;
    --rule: #ded6c9;
    --rule-strong: #191714;
    --accent: #2b4a3a;
    --film: #07080c;
    --bone: #ece7dd;

  }

  * { box-sizing: border-box; }
  html { scroll-behavior: smooth; }
  body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: 'Inter Tight', 'Helvetica Neue', Arial, sans-serif;
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
  }
  .serif { font-family: 'Instrument Serif', Georgia, serif; font-weight: 400; }
  .mono { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; }
  .wrap { width: min(1180px, 100% - 2 * clamp(20px, 5vw, 72px)); margin-inline: auto; }

  /* ---------- header ---------- */
  header {
    position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 50;
    display: flex; align-items: center; justify-content: space-between;
    padding: 18px clamp(20px, 5vw, 72px);
    color: var(--bone);
    transition: background 400ms ease, color 400ms ease, border-color 400ms ease, backdrop-filter 400ms ease;
    border-block-end: 1px solid transparent;
  }
  header.docked {
    background: color-mix(in srgb, var(--paper) 88%, transparent);
    backdrop-filter: blur(14px) saturate(1.1);
    color: var(--ink);
    border-block-end-color: var(--rule);
  }
  .brand { font-size: 22px; letter-spacing: -0.005em; }
  nav { display: flex; align-items: center; gap: clamp(16px, 2.4vw, 32px); font-size: 14px; }
  nav a { color: inherit; text-decoration: none; opacity: 0.85; }
  nav a:hover { opacity: 1; }
  .lang { display: flex; border: 1px solid currentColor; border-radius: 2px; overflow: hidden; opacity: 0.85; }
  .lang button {
    appearance: none; border: 0; margin: 0; background: none; color: inherit; cursor: pointer;
    padding: 4px 10px; font: 12px 'JetBrains Mono', 'Noto Sans SC', monospace;
  }
  .lang button[aria-pressed="true"] { background: var(--bone); color: var(--film); font-weight: 500; cursor: default; }
  header.docked .lang button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
  .lang button:focus-visible { outline: 2px solid currentColor; outline-offset: -4px; }
  @media (max-width: 720px) { nav .hide-sm { display: none; } }

  /* ---------- cinematic panels ---------- */
  .film {
    position: relative;
    min-height: 100svh;
    display: grid;
    align-content: center;
    overflow: clip;
    color: var(--bone);
    background: var(--film);
  }
  .film .plate {
    position: absolute; inset: -12% 0 -12% 0;
    background-size: cover;
    background-position: center;
    will-change: transform;
  }
  /* Two passes rather than one flat wash: a vertical gradient to seat the panel against
     the sections above and below, and a horizontal one that shades only the column the
     text actually occupies. Kept deliberately light — these are night-sky frames whose
     mean value is already near black, so the scrim only has to lift local contrast under
     the type. The heavier wash this replaced was tuned for a mid-tone landscape and
     erased the Milky Way it was sitting on. */
  .film .scrim {
    position: absolute; inset: 0;
    background:
      linear-gradient(to bottom, rgba(7,8,12,0.5) 0%, rgba(7,8,12,0) 38%, rgba(7,8,12,0.6) 100%),
      linear-gradient(to right, rgba(7,8,12,0.62) 0%, rgba(7,8,12,0.22) 46%, rgba(7,8,12,0) 76%);
  }
  .film > .wrap { position: relative; z-index: 2; padding-block: 14vh; }

  .hero h1 {
    margin: 0;
    font-size: clamp(44px, 7.4vw, 104px);
    line-height: 1.02;
    letter-spacing: -0.025em;
    font-weight: 400;
    max-width: 15ch;
    text-wrap: balance;
  }
  .hero .lede {
    margin-block-start: 28px;
    max-width: 46ch;
    font-size: clamp(15px, 1.25vw, 18px);
    line-height: 1.7;
    color: rgba(236,231,221,0.82);
    text-wrap: pretty;
  }
  .hero .cta {
    margin-block-start: 34px;
    display: inline-flex; align-items: center; gap: 10px;
    padding-block-end: 8px;
    border-block-end: 1px solid var(--bone);
    font-size: 16px; color: var(--bone); text-decoration: none;
  }
  .cue {
    position: absolute; inset-block-end: 34px; inset-inline-start: 50%;
    translate: -50% 0; z-index: 3;
    display: grid; justify-items: center; gap: 10px;
    color: rgba(236,231,221,0.6);
  }
  .cue i { display: block; inline-size: 1px; block-size: 44px; background: currentColor; transform-origin: top; }

  .chapter h2 {
    margin: 0;
    font-size: clamp(34px, 4.6vw, 62px);
    line-height: 1.08; letter-spacing: -0.02em; font-weight: 400;
    max-width: 18ch; text-wrap: balance;
  }
  .chapter p {
    margin-block-start: 20px; max-width: 44ch;
    font-size: clamp(15px, 1.15vw, 17px); line-height: 1.75;
    color: rgba(236,231,221,0.78); text-wrap: pretty;
  }

  /* ---------- paper sections ---------- */
  .paper { padding-block: clamp(64px, 9vw, 128px); }
  .rows { display: flex; flex-direction: column; }
  .row {
    display: grid; gap: clamp(16px, 2.4vw, 28px); align-items: baseline;
    padding-block: 24px; border-block-start: 1px solid var(--rule);
  }
  .row:first-child { border-block-start: 1px solid var(--rule-strong); }
  .rows > .row:last-child { border-block-end: 1px solid var(--rule-strong); }
  .plans .row { grid-template-columns: minmax(0, 380px) 1fr 110px; }
  .plans .t { font-size: clamp(20px, 1.9vw, 25px); letter-spacing: -0.01em; }
  .plans .d { font-size: 15px; line-height: 1.65; color: var(--body); }
  .plans .m { color: var(--muted); text-align: end; }
  .tracks .row { grid-template-columns: 170px 1fr; }
  .tracks .t { font-size: 22px; }
  .tracks .chain { font-size: 16px; line-height: 1.9; color: var(--body); }
  .tracks .chain i { color: #b3a897; font-style: normal; padding-inline: 7px; }
  .doms .topic { grid-template-columns: minmax(0, 320px) 1fr; align-items: start; }
  .doms .t { font-size: 22px; }
  .doms .d { margin-block-start: 6px; font-size: 14px; line-height: 1.6; color: var(--muted); }
  .plan-list { list-style: none; margin: 0; padding: 0; }
  .plan-list li { display: flex; justify-content: space-between; align-items: baseline; gap: 20px; padding-block: 7px; }
  .plan-list a.plan { font-size: 16px; }
  .plan-list .m, .plans .m { color: var(--muted); white-space: nowrap; }
  .row.deep .t { color: var(--accent); }
  /* Plan titles are the only links in the catalog, so they carry a quiet underline at rest
     rather than an icon on every one of them. */
  a.plan { color: inherit; text-decoration: underline; text-decoration-color: var(--rule);
           text-decoration-thickness: 1px; text-underline-offset: 5px; transition: color 160ms ease, text-decoration-color 160ms ease; }
  a.plan:hover, a.plan:focus-visible { color: var(--accent); text-decoration-color: currentColor; }
  a.plan:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
  .tag {
    display: inline-block; margin-inline-start: 10px; padding: 1px 7px; vertical-align: 3px;
    border: 1px solid #c9bfae; border-radius: 2px; font-size: 12px; color: var(--muted);
  }
  .only-zh { display: none; }
  :lang(zh-CN) .only-zh { display: inline-block; }
  @media (max-width: 860px) {
    .plans .row { grid-template-columns: 1fr; }
    .plans .m { text-align: start; }
    .tracks .row, .doms .row { grid-template-columns: 1fr; }
    .doms .topic { grid-template-columns: 1fr; }
    .plan-list li { flex-wrap: wrap; gap: 4px 16px; }
  }

  footer {
    padding-block: 30px 44px;
    border-block-start: 1px solid var(--rule);
    display: flex; align-items: flex-start; justify-content: space-between; gap: 40px; flex-wrap: wrap;
    font-size: 13px; line-height: 1.65; color: #5c554a;
  }
  footer strong { color: var(--ink); font-weight: 400; }

  /* ---------- 中文 ---------- */
  :lang(zh-CN) body { font-family: 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif; }
  :lang(zh-CN) .serif { font-family: 'Noto Serif SC', 'Songti SC', serif; font-weight: 600; letter-spacing: 0.01em; }
  :lang(zh-CN) .mono { font-family: 'JetBrains Mono', 'Noto Sans SC', monospace; letter-spacing: 0.04em; text-transform: none; }
  :lang(zh-CN) em { font-style: normal; }
  :lang(zh-CN) .hero h1 { font-size: clamp(34px, 5.2vw, 72px); line-height: 1.3; max-width: 12em; }
  :lang(zh-CN) .chapter h2 { font-size: clamp(28px, 3.4vw, 46px); line-height: 1.35; max-width: 14em; }
  :lang(zh-CN) .hero .lede { line-height: 1.95; max-width: 26em; }
  :lang(zh-CN) .chapter p { line-height: 1.95; max-width: 24em; }
  :lang(zh-CN) .plans .t, :lang(zh-CN) .doms .t, :lang(zh-CN) .tracks .t { font-weight: 500; letter-spacing: 0; }
  :lang(zh-CN) .plans .d, :lang(zh-CN) .doms .d, :lang(zh-CN) .tracks .chain { line-height: 1.9; }
  :lang(zh-CN) footer { line-height: 1.9; }

  /* ---------- motion ----------
     Every hidden state is gated on .js, so a visitor whose script never runs gets the
     whole page rather than a blank one. Nothing here is load-bearing for reading. */
  @media (prefers-reduced-motion: no-preference) {
    .js .reveal > * { opacity: 0; transform: translateY(22px); }
    .reveal.in > * {
      opacity: 1; transform: none;
      transition: opacity 900ms cubic-bezier(.22,.7,.3,1), transform 900ms cubic-bezier(.22,.7,.3,1);
    }
    .reveal.in > *:nth-child(2) { transition-delay: 90ms; }
    .reveal.in > *:nth-child(3) { transition-delay: 180ms; }
    .reveal.in > *:nth-child(4) { transition-delay: 270ms; }
    .js .row { opacity: 0; transform: translateY(18px); }
    .row.in { opacity: 1; transform: none; transition: opacity 700ms ease, transform 700ms cubic-bezier(.22,.7,.3,1); }
    .cue i { animation: cue 2.4s ease-in-out infinite; }
    @keyframes cue { 0%,100% { scale: 1 0.35; opacity: .35 } 50% { scale: 1 1; opacity: .9 } }
  }
  @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

  /* ---------- pages ---------- */
  a.brand { color: inherit; text-decoration: none; }
  nav a[aria-current="page"] { opacity: 1; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
  .page-hero { min-height: 78svh; }
  .page-hero h1 { font-size: clamp(40px, 5.6vw, 80px); }
  .topic-links {
    list-style: none; margin: 40px 0 0; padding: 0;
    display: grid; grid-template-columns: repeat(2, max-content); gap: 12px 56px;
  }
  .topic-links a {
    color: var(--bone); font-size: clamp(18px, 1.7vw, 23px);
    text-decoration: underline; text-decoration-color: rgba(236,231,221,0.28);
    text-decoration-thickness: 1px; text-underline-offset: 6px; transition: text-decoration-color 160ms ease;
  }
  .topic-links a:hover, .topic-links a:focus-visible { text-decoration-color: var(--bone); }
  .topic { scroll-margin-top: 96px; }
  @media (max-width: 640px) { .topic-links { grid-template-columns: 1fr; } }
  :lang(zh-CN) .page-hero h1 { font-size: clamp(32px, 4.4vw, 60px); }
  .how-to {
    margin: 0 0 28px; max-width: 64ch; padding-inline-start: 14px;
    border-inline-start: 2px solid var(--accent);
    font-size: 14px; line-height: 1.7; color: var(--body);
  }
  .how-to strong { font-weight: 500; color: var(--ink); }
  :lang(zh-CN) .how-to { line-height: 1.9; }
