/* =====================================================================
   YT Life — shared design system for web/ (index, invest, whitepaper)
   Light is the default; <html data-theme="dark"> switches every token.
   Pages use tokens + the classes below; page-specific CSS stays inline.
   No external hosts: the font is self-hosted under web/fonts/.
   ===================================================================== */

/* ---------- font (OFL, variable weight 200–800, Latin subset) ---------- */
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Plus Jakarta Sans";
  src: url("../fonts/plus-jakarta-sans-italic-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: italic;
  font-display: swap;
}

/* ---------- tokens: light (default) ---------- */
:root {
  color-scheme: light;

  --font-sans: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
    "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC", sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji";
  --font-cjk: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC",
    "Noto Sans SC", "Source Han Sans SC", "Plus Jakarta Sans", system-ui, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;

  /* ground + surfaces (the mockups' ground samples #fbfbf8-#fdfdfb) */
  --bg: #fafaf7;
  --bg-soft: #eef3ee;                 /* alternate section band */
  --bg-wash:
    radial-gradient(1100px 640px at 88% -80px, rgba(126, 196, 170, .10), transparent 64%),
    radial-gradient(900px 560px at -6% 60px, rgba(225, 241, 233, .5), transparent 62%);
  --surface: #ffffff;
  --surface-2: #fafbf8;               /* table heads, subtle fills */
  --surface-sunk: #f0f3ef;
  --surface-solid: #ffffff;           /* opaque panels (mobile menu) */

  /* ink */
  --ink: #0d2330;                     /* headlines */
  --body: #33433f;                    /* running text */
  --muted: #5c6b65;                   /* secondary text: >= 4.8:1 on bg, band, wash, mint */
  --faint: #7d8d87;                   /* decorative marks only (bullets, rules), never text */
  --caption: #466e62;                 /* divider caption text: >= 4.9:1 */

  /* brand */
  --brand: #0f5245;                   /* deep green: primary actions */
  --brand-hi: #1b6e5d;
  --accent: #2a8f7b;                  /* teal: rules, icons, focus */
  --accent-ink: #1e6f60;              /* teal text: links (AA on --bg) */
  --kicker: #236b5d;
  --mint: #e1f1e9;
  --mint-2: #cfe7db;
  --on-brand: #ffffff;
  --focus: #2a8f7b;

  /* lines */
  --line: rgba(13, 35, 48, .09);
  --line-strong: rgba(13, 35, 48, .16);
  --rule: rgba(13, 35, 48, .13);

  /* shadows */
  --shadow-sm: 0 1px 2px rgba(15, 45, 40, .05), 0 3px 10px -4px rgba(15, 45, 40, .08);
  --shadow-card: 0 1px 2px rgba(15, 45, 40, .04), 0 16px 36px -16px rgba(15, 45, 40, .17);
  --shadow-lift: 0 2px 4px rgba(15, 45, 40, .05), 0 26px 52px -20px rgba(15, 45, 40, .26);

  /* components */
  --card-bg: #ffffff;
  --card-border: rgba(13, 35, 48, .055);
  --card-blur: none;
  --glass-bg: rgba(255, 255, 255, .6);
  --glass-border: rgba(255, 255, 255, .8);
  --glass-shadow: 0 1px 1px rgba(255, 255, 255, .6) inset, 0 18px 40px -20px rgba(15, 45, 40, .22);
  --nav-bg: rgba(250, 250, 247, .86);
  --nav-border: rgba(13, 35, 48, .07);

  --btn-primary-bg: linear-gradient(180deg, #1b6e5d 0%, #0f5245 100%);
  --btn-primary-bg-hover: linear-gradient(180deg, #1f7867 0%, #125a4c 100%);
  --btn-primary-ink: #ffffff;
  --btn-primary-shadow: 0 1px 0 rgba(255, 255, 255, .14) inset, 0 12px 26px -12px rgba(15, 82, 69, .75);
  --btn-outline-border: rgba(13, 35, 48, .42);
  --btn-outline-ink: var(--ink);
  --btn-outline-hover-bg: rgba(15, 82, 69, .06);

  --medal-bg: var(--mint);
  --medal-glyph: #0f5245;
  --medal-ring: 0 0 0 0 transparent;
  --illu-halo: rgba(225, 241, 233, .9);
  --illu-filter: none;

  --tag-built-bg: #e1f1e9;  --tag-built-ink: #0f5245;  --tag-built-dot: #1f8a6f;
  --tag-dev-bg: #f6eedb;    --tag-dev-ink: #6e5314;    --tag-dev-dot: #c1912a;
  --tag-later-bg: #eaeef2;  --tag-later-ink: #475566;  --tag-later-dot: #7d8da0;

  --stat-num: #0f5245;
  --stat-num-fill: none;
  --notice-bg: #eef6f1;
  --notice-border: rgba(42, 143, 123, .28);
  --selection: rgba(42, 143, 123, .22);
  /* theme-toggle placeholder icon (before site.js paints its SVG): moon in light, sun in dark */
  --icon-theme: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20.2 14.6A8.5 8.5 0 0 1 9.4 3.8a8.5 8.5 0 1 0 10.8 10.8z'/%3E%3C/svg%3E");
  /* padlock for [data-invite-only] links (a mask: it takes the link colour) */
  --icon-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4.5' y='10.5' width='15' height='10.5' rx='2.2'/%3E%3Cpath d='M8 10.5V7.4a4 4 0 0 1 8 0v3.1'/%3E%3C/svg%3E");
  /* hero figure (media/invest/hero_figure): the side fades are baked into the
     asset; this mask only softens the top and bottom mist. Dark theme: see
     the .figure-glow disc in the dark overrides at the end of this file. */
  --figure-feather: radial-gradient(ellipse 64% 62% at 50% 52%, #000 72%, transparent 100%);
  --figure-filter: none;
  --figure-halo: radial-gradient(closest-side, rgba(225, 241, 233, .85), rgba(225, 241, 233, 0));

  /* shape + rhythm */
  --r-sm: 10px;
  --r-md: 14px;
  --r-card: 14px;                     /* cards (both mockups ~14 px) */
  --r-lg: 18px;                       /* media frames, glass, tiles */
  --r-xl: 26px;
  --r-pill: 999px;
  --wrap: 1200px;
  --wrap-narrow: 760px;
  --gutter: clamp(16px, 4vw, 40px);
  --gap: clamp(16px, 2vw, 24px);
  --section-y: clamp(64px, 9vw, 128px);
  --nav-h: 92px;                      /* 84 at <= 1180, 64 at <= 1024 */
  --ease: cubic-bezier(.2, .7, .2, 1);
}

/* ---------- tokens: dark ----------
   Screen only: printing (the white-paper PDF) always uses the light palette.
   Every dark component override lives in the @media screen block at the end
   of this file for the same reason; page CSS should do the same. */
@media screen {
:root[data-theme="dark"] {
  color-scheme: dark;

  /* the dark mockup samples #010b11-#01111a between elements */
  --bg: #020c11;
  --bg-soft: rgba(255, 255, 255, .018);
  --bg-wash:
    radial-gradient(1000px 680px at 82% -60px, rgba(63, 207, 170, .13), transparent 62%),
    radial-gradient(820px 600px at -8% 420px, rgba(29, 143, 178, .09), transparent 60%),
    linear-gradient(180deg, #010a10 0%, #03121a 50%, #041820 100%);
  --surface: rgba(255, 255, 255, .035);
  --surface-2: rgba(255, 255, 255, .05);
  --surface-sunk: rgba(0, 0, 0, .22);
  --surface-solid: #061820;

  --ink: #eef5f3;
  --body: #c3d1cd;
  --muted: #93a8a3;
  --faint: #6f8883;
  --caption: #6f98a0;

  --brand: #5fdcbf;
  --brand-hi: #7fe9cf;
  --accent: #5fdcbf;
  --accent-ink: #72e2c7;
  --kicker: #a3d6cb;
  --mint: rgba(95, 220, 191, .1);
  --mint-2: rgba(95, 220, 191, .18);
  --on-brand: #ffffff;
  --focus: #6fe3c6;

  --line: rgba(110, 220, 195, .12);
  --line-strong: rgba(110, 220, 195, .24);
  --rule: rgba(120, 190, 200, .26);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
  --shadow-card: 0 1px 0 rgba(255, 255, 255, .035) inset, 0 26px 50px -30px rgba(0, 0, 0, .85);
  --shadow-lift: 0 1px 0 rgba(255, 255, 255, .05) inset, 0 30px 60px -28px rgba(0, 0, 0, .9),
    0 0 0 1px rgba(95, 220, 191, .08), 0 0 40px -12px rgba(95, 220, 191, .22);

  /* near-black glass with a teal hairline, as in the dark mockup */
  --card-bg: linear-gradient(180deg, rgba(255, 255, 255, .032) 0%, rgba(255, 255, 255, .008) 100%);
  --card-border: rgba(110, 220, 195, .17);
  --card-blur: blur(10px);
  --glass-bg: linear-gradient(180deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, .015)), rgba(7, 26, 32, .62);
  --glass-border: rgba(110, 220, 195, .22);
  --glass-shadow: 0 1px 0 rgba(255, 255, 255, .05) inset, 0 24px 50px -26px rgba(0, 0, 0, .8);
  --nav-bg: rgba(2, 12, 17, .8);
  --nav-border: rgba(110, 220, 195, .1);

  /* the bright green edge stays under the left padding (stop at 1.2em; the
     smallest padding is .btn-sm's 1.3em): white label >= 4.75:1 everywhere it
     sits, >= 4.6:1 on hover */
  --btn-primary-bg: linear-gradient(95deg, #25a572 0, #178257 1.2em, #137f88 52%, #0f6a93 100%);
  --btn-primary-bg-hover: linear-gradient(95deg, #2cb37d 0, #178559 1.2em, #13818a 52%, #0e6c96 100%);
  --btn-primary-ink: #ffffff;
  --btn-primary-shadow: 0 1px 0 rgba(255, 255, 255, .2) inset, 0 12px 30px -12px rgba(63, 207, 142, .55);
  --btn-outline-border: rgba(214, 238, 232, .5);
  --btn-outline-ink: var(--ink);
  --btn-outline-hover-bg: rgba(95, 220, 191, .08);

  --medal-bg: radial-gradient(circle at 50% 30%, rgba(95, 220, 191, .17) 0%, rgba(3, 32, 36, .92) 72%);
  --medal-glyph: #5fdcbf;
  --medal-ring: inset 0 0 0 1.5px rgba(95, 220, 191, .55), 0 0 24px -4px rgba(95, 220, 191, .4);
  --illu-halo: rgba(95, 220, 191, .1);
  --illu-filter: saturate(1.08) brightness(1.04);

  --tag-built-bg: rgba(95, 220, 191, .12);   --tag-built-ink: #8ff0d4;  --tag-built-dot: #5fdcbf;
  --tag-dev-bg: rgba(233, 190, 110, .12);    --tag-dev-ink: #f1d08f;    --tag-dev-dot: #e3b45c;
  --tag-later-bg: rgba(170, 190, 215, .1);   --tag-later-ink: #bccadb;  --tag-later-dot: #8fa3bb;

  --stat-num: #9ff3da;
  --stat-num-fill: linear-gradient(180deg, #dcfff3 0%, #7fe9cf 100%);
  --notice-bg: rgba(95, 220, 191, .07);
  --notice-border: rgba(95, 220, 191, .26);
  --selection: rgba(95, 220, 191, .3);
  /* dark: the figure sits whole inside a ringed disc (.figure-glow), no mask */
  --figure-feather: none;
  --figure-filter: brightness(.72) saturate(1.25);
  --figure-halo: none;
}
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
[hidden] { display: none !important; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--bg);
}
/* smooth in-page jumps, but only once the page has landed: site.js adds
   html.is-ready after load (or after YTL.holdScroll() is released, for pages
   that mount their deep-link targets late), so arriving on invest.html#team
   or whitepaper.html#s10 jumps straight there instead of animating the scroll */
@media (prefers-reduced-motion: no-preference) {
  html.is-ready { scroll-behavior: smooth; }
}
body {
  min-height: 100vh;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--body);
  background: var(--bg);
  background-image: var(--bg-wash);
  background-repeat: no-repeat;
  word-spacing: .06em;               /* the face's space is narrow (0.17em) */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
img, video, svg, canvas, picture { display: block; max-width: 100%; }
img, video { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--accent-ink); text-underline-offset: .18em; text-decoration-thickness: 1px; }
a:hover { color: var(--ink); }
strong, b { font-weight: 650; color: var(--ink); }
::selection { background: var(--selection); }
[id] { scroll-margin-top: calc(var(--nav-h) + 20px); }
:lang(zh), .zh { font-family: var(--font-cjk); letter-spacing: .02em; }
/* bilingual pages (<html data-i18n>: index.html; the toggle is site.js). Text the
   page has in both languages is a pair of halves in the markup,
   <span data-l="en">...</span><span data-l="zh" lang="zh-Hans">...</span>, and
   <html lang> shows one of them. The page's head snippet sets <html lang> before
   first paint, so nothing is swapped and the other language never flashes; with
   no script at all the page stays English. */
html:not([lang|="zh"]) [data-l="zh"], html[lang|="zh"] [data-l="en"] { display: none !important; }
/* Chinese: the Latin brand face first (a Latin subset, so Latin words keep it and
   every Han character falls through to the system CJK faces; no CJK webfont is
   shipped), no negative tracking on CJK, and a little more leading */
html[lang|="zh"] {
  --font-sans: "Plus Jakarta Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
    "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC", sans-serif;
  --font-cjk: var(--font-sans);
}
html[lang|="zh"] body { line-height: 1.75; }
/* a Chinese phrase that wraps as a unit (headings: a line breaks between phrases, never
   inside a word such as 自己); an inline-block, so a phrase wider than its line still wraps */
.phrase { display: inline-block; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; }
}

/* focus + skip link */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 6px; }
.btn:focus-visible, .nav-toggle:focus-visible, .theme-toggle:focus-visible { border-radius: var(--r-pill); }
.skip-link {
  position: fixed; left: 16px; top: 12px; z-index: 200;
  padding: 10px 18px; border-radius: var(--r-pill);
  background: var(--brand); color: var(--on-brand); font-weight: 600; text-decoration: none;
  transform: translateY(-160%); transition: transform .2s var(--ease);
}
.skip-link:focus, .skip-link:focus-visible { transform: none; color: var(--on-brand); }
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: calc(var(--wrap) + 2 * var(--gutter)); margin-inline: auto; padding-inline: var(--gutter); }
.wrap-narrow { max-width: calc(var(--wrap-narrow) + 2 * var(--gutter)); }
.section { padding-block: var(--section-y); position: relative; }
.section-tight { padding-block: calc(var(--section-y) * .6); }
.section-alt { background: var(--bg-soft); }
.grid { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.grid-2 { display: grid; gap: var(--gap); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { display: grid; gap: var(--gap); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { display: grid; gap: var(--gap); grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1024px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 860px) { .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }
@media (max-width: 420px) { .grid-4 { grid-template-columns: 1fr; } }
.split { display: grid; gap: clamp(28px, 5vw, 72px); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }
.stack > * + * { margin-top: var(--stack, 1rem); }
.center { text-align: center; }
.center .lede, .lede.center { margin-inline: auto; }
.row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* ---------- type ---------- */
h1, h2, h3, h4, .display, .h1, .h2, .h3 {
  color: var(--ink); font-weight: 600; text-wrap: balance;
}
.display, h1 {
  font-size: clamp(2.6rem, 1rem + 4.4vw, 5rem);
  line-height: 1.02; letter-spacing: -.042em; word-spacing: .08em; font-weight: 620;
}
.display-sub {
  display: block; font-size: .6em; line-height: 1.12; letter-spacing: -.022em;
  font-weight: 300; color: var(--ink); margin-top: .12em;
}
h2, .h2 { font-size: clamp(2rem, 1.2rem + 2.5vw, 3.25rem); line-height: 1.08; letter-spacing: -.034em; word-spacing: .07em; }
h3, .h3 { font-size: clamp(1.14rem, 1.02rem + .45vw, 1.38rem); line-height: 1.28; letter-spacing: -.016em; }
h4 { font-size: 1.02rem; line-height: 1.35; letter-spacing: -.01em; }
p { text-wrap: pretty; }
.kicker {
  display: inline-block; font-size: .74rem; line-height: 1.4; font-weight: 600;
  letter-spacing: .32em; text-transform: uppercase; color: var(--kicker);
  margin-bottom: 1.1rem;
}
.subhead {
  font-size: clamp(1.2rem, 1rem + .75vw, 1.65rem); line-height: 1.35; font-weight: 420;
  letter-spacing: -.012em; color: var(--ink);
}
.lede {
  font-size: clamp(1.05rem, .98rem + .32vw, 1.25rem); line-height: 1.6; color: var(--body);
  max-width: 58ch;
}
.small { font-size: .875rem; }
.nowrap { white-space: nowrap; }
.muted { color: var(--muted); }
.ink { color: var(--ink); }
.accent { color: var(--accent-ink); }
.tabular { font-variant-numeric: tabular-nums; }
.accent-rule { display: block; width: 64px; height: 2px; border: 0; border-radius: 2px; background: var(--accent); margin-block: 1.4rem; }
/* bullet-separated items. Every item carries its bullet in the gap before it;
   the bullet of the first item on each row falls outside the list's box and
   is clipped, so a wrapped row never starts with an orphan bullet. */
.status-line {
  display: flex; flex-wrap: wrap; gap: .25rem 1.8rem; padding: 0; list-style: none;
  color: var(--muted); font-size: 1rem;
  overflow: hidden; overflow: clip;
}
.status-line li::before {
  content: "\2022"; display: inline-block; width: 1.8rem; margin-left: -1.8rem; text-align: center;
  color: var(--faint);
}
.link-arrow { font-weight: 600; text-decoration: none; display: inline-flex; gap: .45em; align-items: center; }
.link-arrow::after { content: "\2192"; content: "\2192" / ""; transition: transform .25s var(--ease); }
.link-arrow:hover::after { transform: translateX(3px); }
/* gated links (studio, atlas, white paper, citations into the paper): for keyless
   visitors (html.no-key, set by site.js) a small lock precedes the link, site.js
   titles it "Invite-only", and a click opens the invite-code dialog (then
   continues to the link); keyed visitors and printouts see the plain link */
@media screen {
  html.no-key [data-invite-only]::before {
    content: ""; display: inline-block; flex: none; width: .78em; height: .78em;
    margin-right: .28em; vertical-align: -.04em;
    background-color: currentColor; opacity: .85;
    -webkit-mask: var(--icon-lock) center / contain no-repeat; mask: var(--icon-lock) center / contain no-repeat;
  }
  html.no-key .link-arrow[data-invite-only]::before { margin-right: 0; }
  html.no-key .btn[data-invite-only]::before { margin-right: -.18em; }   /* .btn's gap does the spacing */
}

/* section header block */
.section-head { max-width: 760px; margin-bottom: clamp(28px, 4vw, 52px); }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head .lede { margin-top: 1rem; }
.section-head.center .lede { margin-inline: auto; }

/* divider caption: centred, letter-spaced, rules either side */
.divider-caption {
  display: flex; align-items: center; justify-content: center; gap: clamp(14px, 2.4vw, 28px);
  font-size: .72rem; line-height: 1.5; font-weight: 500; letter-spacing: .38em;
  text-transform: uppercase; color: var(--caption); text-align: center;
  padding-block: clamp(20px, 3vw, 36px);
}
.divider-caption::before, .divider-caption::after {
  content: ""; flex: 0 1 120px; min-width: 24px; height: 1px; background: var(--rule);
}
@media (max-width: 560px) { .divider-caption { letter-spacing: .24em; font-size: .68rem; } }
@media (max-width: 480px) {
  .divider-caption::before, .divider-caption::after { flex: 0 0 24px; }
  .kicker { letter-spacing: .22em; }
}

/* vertical letter-spaced aside caption (e.g. "HUMAN POTENTIAL / IN MOTION") */
.aside-caption {
  font-size: .68rem; line-height: 2.1; letter-spacing: .34em; text-transform: uppercase;
  color: var(--kicker); font-weight: 500;
}
.aside-caption::after { content: ""; display: block; width: 22px; height: 1px; margin-top: .6rem; background: currentColor; opacity: .7; }

/* Simplified Chinese (html[lang="zh-Hans"]): Han characters fill the em box, so
   display type is set a little smaller and looser than the Latin, and the wide
   tracking of the small caps labels is halved */
html[lang|="zh"] :is(h1, .display) { font-size: clamp(2.15rem, .82rem + 3.6vw, 4.1rem); line-height: 1.18; letter-spacing: .01em; }
html[lang|="zh"] .display-sub { line-height: 1.32; letter-spacing: .02em; }
html[lang|="zh"] :is(h2, .h2) { font-size: clamp(1.7rem, 1.05rem + 2.1vw, 2.75rem); line-height: 1.26; letter-spacing: .01em; }
html[lang|="zh"] :is(h3, .h3) { line-height: 1.42; letter-spacing: .01em; }
html[lang|="zh"] .card p { line-height: 1.7; }
html[lang|="zh"] .kicker { letter-spacing: .16em; }
html[lang|="zh"] .divider-caption { letter-spacing: .24em; }
html[lang|="zh"] .footer-title { letter-spacing: .12em; }

/* ---------- nav ---------- */
.site-nav {
  position: sticky; top: 0; z-index: 60;
  background: transparent;
  transition: background-color .3s var(--ease), box-shadow .3s var(--ease), border-color .3s;
  border-bottom: 1px solid transparent;
}
.site-nav.is-scrolled, .site-nav.is-open {
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(16px) saturate(1.3); backdrop-filter: blur(16px) saturate(1.3);
  border-bottom-color: var(--nav-border);
}
.nav-bar { display: flex; align-items: center; gap: 20px; min-height: var(--nav-h); }
.brand {
  display: inline-flex; align-items: center; gap: 12px; text-decoration: none; color: var(--ink);
  flex: none;
}
.brand:hover { color: var(--ink); }
/* desktop sizes follow the light mockups at 1440 (mark ~64-70 px, wordmark ~40 px) */
.brand-mark { width: 64px; height: 64px; object-fit: contain; flex: none; }
.brand-text { display: flex; flex-direction: column; line-height: 1; }
.brand-name { font-size: 2.35rem; font-weight: 600; letter-spacing: -.035em; word-spacing: .04em; line-height: 1; }
.brand-tag { font-size: .7rem; font-weight: 500; letter-spacing: .03em; color: var(--muted); margin-top: .36rem; white-space: nowrap; }
.nav-links { display: flex; align-items: center; justify-content: center; gap: clamp(18px, 2.6vw, 40px); flex: 1; }
.nav-links a {
  position: relative; color: var(--body); text-decoration: none; font-size: .95rem; font-weight: 500;
  padding: 8px 0; white-space: nowrap; transition: color .2s;
}
.nav-links a:hover { color: var(--ink); }
.nav-links a[aria-current="page"], .nav-links a[aria-current="true"], .nav-links a.is-active { color: var(--brand); font-weight: 600; }
.nav-links a[aria-current="page"]::after, .nav-links a[aria-current="true"]::after, .nav-links a.is-active::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px; border-radius: 2px;
  background: var(--accent);
}
.nav-links .nav-menu-cta { display: none; }
/* a quieter link to the sibling page (index: Investors; invest: The product) */
.nav-links a.nav-muted { color: var(--muted); }
.nav-links a.nav-muted:hover { color: var(--ink); }
/* a link that only belongs in the mobile menu panel */
.nav-links .nav-menu-only { display: none; }
.nav-actions { display: flex; align-items: center; gap: 12px; flex: none; margin-left: auto; }
/* bar CTA: full-size pill on desktop (mockup ~220 x 52), small below 1180.
   Sized here so it wins over .btn-sm if a page adds it. */
.nav-actions .nav-cta { font-size: 1.02rem; --btn-pad-y: .92em; --btn-pad-x: 2em; }
.theme-toggle, .nav-toggle {
  display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); background: transparent; color: var(--ink);
  transition: background-color .2s, border-color .2s, color .2s;
}
.theme-toggle:hover, .nav-toggle:hover { background: var(--btn-outline-hover-bg); border-color: var(--accent); }
.theme-toggle svg { width: 18px; height: 18px; }
/* invite code (keyless visitors only; site.js opens the dialog). A round key
   button beside the theme toggle: the bar has no room for a text pill at desktop
   widths (the six- and seven-link bars leave ~45-120px), so its name
   "Have an invite code?" shows as a tooltip on hover / keyboard focus, and the
   mobile menu lists it as text. It keeps its space, invisible, until site.js has
   checked for a key; it is gone for keyed visitors and without JS. */
.nav-invite {
  position: relative;
  display: inline-grid; place-items: center; width: 40px; height: 40px; padding: 0; border-radius: var(--r-pill);
  border: 1px solid var(--mint-2); background: var(--mint); color: var(--brand);
  transition: background-color .2s, border-color .2s, color .2s;
}
.nav-invite:hover { background: var(--mint-2); border-color: var(--accent); }
.nav-invite:focus-visible { border-radius: var(--r-pill); }
.nav-invite svg { width: 20px; height: 20px; }
.nav-invite::after {
  content: "Have an invite code?"; content: "Have an invite code?" / "";
  position: absolute; top: calc(100% + 10px); left: 50%; z-index: 5;
  padding: .42em .8em; border-radius: var(--r-sm);
  background: var(--ink); color: var(--bg); box-shadow: var(--shadow-sm);
  font-size: .8rem; font-weight: 600; line-height: 1.3; letter-spacing: 0; white-space: nowrap;
  pointer-events: none; opacity: 0; transform: translate(-50%, -3px);
  transition: opacity .18s var(--ease), transform .18s var(--ease);
}
html[data-i18n][lang|="zh"] .nav-invite::after { content: "有邀请码？"; content: "有邀请码？" / ""; }
.nav-invite:focus-visible::after { opacity: 1; transform: translate(-50%, 0); }
@media (hover: hover) { .nav-invite:hover::after { opacity: 1; transform: translate(-50%, 0); } }
/* near the right edge (the key sits left of the menu toggle) the tip opens leftward */
@media (max-width: 1024px) { .nav-invite::after { left: auto; right: -8px; transform: translateY(-3px); } .nav-invite:focus-visible::after { transform: none; } }
@media (max-width: 1024px) and (hover: hover) { .nav-invite:hover::after { transform: none; } }
/* language toggle (bilingual pages): "EN | 中文" among the bar's actions at every
   width (after the invite key, so it stays put when that goes). The current
   language is drawn from <html lang>, which the head snippet sets before first
   paint, so it never shows the other one first; site.js keeps aria-pressed in
   step and switches in place. Without script it could not switch, so it is not
   shown. */
.lang-toggle {
  display: inline-flex; align-items: center; flex: none; height: 40px; padding: 0 1px;
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
}
.lang-toggle button {
  position: relative;
  display: inline-grid; place-items: center; height: 34px; min-width: 26px; padding: 0 .44em;
  border: 0; border-radius: var(--r-pill); background: transparent; color: var(--muted);
  font-size: .74rem; font-weight: 600; line-height: 1; letter-spacing: .02em; white-space: nowrap;
  transition: color .2s, background-color .2s;
}
.lang-toggle button:hover { color: var(--ink); background: var(--btn-outline-hover-bg); }
.lang-toggle button:focus-visible { border-radius: var(--r-pill); outline-offset: 0; }
/* the current one: the nav's own "you are here" mark, a short accent bar under it */
html:not([lang|="zh"]) .lang-toggle [data-lang-set="en"],
html[lang|="zh"] .lang-toggle [data-lang-set="zh"] { color: var(--brand); font-weight: 750; }
html:not([lang|="zh"]) .lang-toggle [data-lang-set="en"]::after,
html[lang|="zh"] .lang-toggle [data-lang-set="zh"]::after {
  content: ""; position: absolute; left: .5em; right: .5em; bottom: 5px; height: 2px; border-radius: 2px;
  background: var(--accent);
}
.lang-sep { flex: none; width: 1px; height: 14px; background: var(--line-strong); }
html:not(.js) .lang-toggle { display: none !important; }
html:not(.js) .nav-invite, html:not(.js) [data-invite-open], html:not(.js) form[data-invite-form] { display: none !important; }
html.js:not(.no-key) .nav-invite { visibility: hidden; }
.nav-links .nav-invite-menu { display: none; }
/* before site.js injects its SVG (or if it never loads) the empty button
   draws the icon for the current theme: moon while light, sun while dark */
.theme-toggle:empty::before {
  content: ""; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: var(--icon-theme) center / contain no-repeat; mask: var(--icon-theme) center / contain no-repeat;
}
.nav-toggle { display: none; }
.nav-toggle-bars, .nav-toggle-bars::before, .nav-toggle-bars::after {
  display: block; width: 18px; height: 1.6px; border-radius: 2px; background: currentColor;
  transition: transform .25s var(--ease), opacity .2s;
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before, .nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after { top: 6px; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 1180px) {
  :root { --nav-h: 84px; }
  .brand-mark { width: 54px; height: 54px; }
  .brand-name { font-size: 1.9rem; }
  .brand-tag { display: none; }
  .nav-links { gap: clamp(16px, 2vw, 28px); }
  .nav-actions { gap: 10px; }
  .nav-actions .nav-cta { font-size: .92rem; --btn-pad-y: .68em; --btn-pad-x: 1.3em; }
}
/* LINK BUDGET: the default bar is tuned for up to five links. A bar with six
   or seven (index, invest, whitepaper) adds .nav-dense to .site-nav: a tighter
   link rhythm and slightly smaller link text on desktop, so the row keeps clear
   space either side of the links at every width from 1025 up (the mobile menu
   takes over at 1024). Eight or more links do not fit: use the menu. */
@media (min-width: 1025px) {
  .site-nav.nav-dense .nav-links { gap: clamp(12px, 1.5vw, 24px); }
  .site-nav.nav-dense .nav-links a { font-size: .92rem; }
}
@media (min-width: 1025px) and (max-width: 1280px) {
  .site-nav.nav-dense .nav-bar { gap: 14px; }
  .site-nav.nav-dense .nav-links a { font-size: .86rem; }
  .site-nav.nav-dense .brand-tag { display: none; }
}
/* keyless, the bar also carries the invite-code key (40px): just above the
   menu breakpoint a seven-link bar is ~10px short, so tighten the rhythm there */
@media (min-width: 1025px) and (max-width: 1120px) {
  html.no-key .site-nav.nav-dense .nav-bar { gap: 10px; }
  html.no-key .site-nav.nav-dense .nav-links { gap: clamp(12px, 1.2vw, 24px); }
  html.no-key .site-nav.nav-dense .nav-actions { gap: 8px; }
}
/* mobile menu: at <= 1024px five links + CTA + toggle no longer fit on one row */
@media (max-width: 1024px) {
  :root { --nav-h: 64px; }
  .brand-mark { width: 40px; height: 40px; }
  .brand-name { font-size: 1.4rem; }
  .brand-tag { display: none; }
  .nav-toggle { display: inline-grid; }
  .nav-links {
    position: absolute; left: 0; right: 0; top: 100%;
    display: none; flex-direction: column; align-items: stretch; gap: 0;
    padding: 8px var(--gutter) 20px;
    background: var(--surface-solid); border-bottom: 1px solid var(--nav-border);
    box-shadow: 0 24px 40px -24px rgba(0, 0, 0, .28);
  }
  .site-nav.is-open .nav-links { display: flex; }
  .nav-links a { padding: 14px 2px; font-size: 1.02rem; border-bottom: 1px solid var(--line); }
  .nav-links a[aria-current="page"]::after, .nav-links a[aria-current="true"]::after, .nav-links a.is-active::after { display: none; }
  .nav-links .nav-menu-cta { display: inline-flex; margin-top: 16px; justify-content: center; border-bottom: 0; padding: .85em 1.5em; color: var(--btn-primary-ink); }
  .nav-links .nav-menu-only { display: block; }
  /* the invite code, as text, just above the menu's CTA */
  .nav-links .nav-invite-menu {
    display: flex; align-items: center; gap: .55em; width: 100%;
    padding: 14px 2px; border: 0; border-bottom: 1px solid var(--line); background: none;
    font-size: 1.02rem; font-weight: 600; line-height: inherit; text-align: left; color: var(--accent-ink);
  }
  .nav-links .nav-invite-menu svg { width: 18px; height: 18px; flex: none; }
  .nav-links .nav-invite-menu:hover { color: var(--ink); }
}
@media (max-width: 560px) {
  .nav-actions .nav-cta { display: none; }
}
/* a bilingual page's bar also carries the language toggle (~64px), and gives that
   room back so the six-link bar keeps clear space beside its links at every width
   (measured before the toggle, English, keyless: 23px either side at 1025, 48 at
   1440; the phone bar had ~80px to spare at 390 and ~10 at 320). Both languages
   get the same spacing, so nothing in the bar moves when the language changes. */
@media (min-width: 1181px) {
  html[data-i18n] .nav-actions { gap: 10px; }
  html[data-i18n] .site-nav.nav-dense .nav-links { gap: clamp(12px, 1.25vw, 20px); }
  html[data-i18n] .nav-actions .nav-cta { font-size: .95rem; --btn-pad-x: 1.5em; }
}
@media (min-width: 1025px) and (max-width: 1180px) {
  html[data-i18n] .site-nav.nav-dense .nav-bar { gap: 10px; }
  html[data-i18n] .site-nav.nav-dense .nav-links { gap: clamp(10px, 1.1vw, 16px); }
  html[data-i18n] .nav-actions { gap: 7px; }
  html[data-i18n] .nav-actions .nav-cta { font-size: .88rem; --btn-pad-x: 1.05em; }
  html[data-i18n] .site-nav .brand-mark { width: 48px; height: 48px; }
  html[data-i18n] .site-nav .brand-name { font-size: 1.7rem; }
}
/* just above the menu breakpoint the keyless English bar (key button too) is
   still ~25px short: a slightly smaller link face and rhythm there */
@media (min-width: 1025px) and (max-width: 1070px) {
  html[data-i18n] .site-nav.nav-dense .nav-links { gap: 9px; }
  html[data-i18n] .site-nav.nav-dense .nav-links a { font-size: .82rem; }
}
@media (max-width: 480px) {
  html[data-i18n] .nav-bar { gap: 12px; }
  html[data-i18n] .nav-actions { gap: 6px; }
  html[data-i18n] :is(.theme-toggle, .nav-toggle, .nav-invite) { width: 38px; height: 38px; }
  html[data-i18n] .lang-toggle { height: 38px; }
}
@media (max-width: 360px) {
  html[data-i18n] .site-nav .brand { gap: 8px; }
  html[data-i18n] .site-nav .brand-name { font-size: 1.2rem; }
}
/* the narrowest phones: the emblem alone, the wordmark kept for screen readers */
@media (max-width: 340px) {
  html[data-i18n] .site-nav .brand-text {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}

/* ---------- buttons ---------- */
.btn {
  --btn-pad-y: .82em; --btn-pad-x: 1.55em;
  display: inline-flex; align-items: center; justify-content: center; gap: .6em;
  padding: var(--btn-pad-y) var(--btn-pad-x); border-radius: var(--r-pill);
  font-size: 1rem; font-weight: 600; line-height: 1.2; letter-spacing: -.005em;
  text-decoration: none; white-space: nowrap; border: 1px solid transparent; background: transparent;
  color: var(--ink);
  transition: transform .2s var(--ease), box-shadow .25s var(--ease), background-color .2s, border-color .2s, color .2s;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 1.15em; height: 1.15em; flex: none; }
.btn-primary {
  background: var(--btn-primary-bg); color: var(--btn-primary-ink); box-shadow: var(--btn-primary-shadow);
}
.btn-primary:hover { background: var(--btn-primary-bg-hover); color: var(--btn-primary-ink); }
.btn-outline { border-color: var(--btn-outline-border); color: var(--btn-outline-ink); background: transparent; }
.btn-outline:hover { background: var(--btn-outline-hover-bg); border-color: var(--accent); color: var(--btn-outline-ink); }
.btn-ghost { color: var(--accent-ink); padding-inline: .9em; }
.btn-ghost:hover { background: var(--btn-outline-hover-bg); color: var(--ink); }
.btn-sm { font-size: .92rem; --btn-pad-y: .68em; --btn-pad-x: 1.3em; }
.btn-lg { font-size: 1.12rem; --btn-pad-y: .95em; --btn-pad-x: 1.9em; }
.btn-arrow::after {
  content: "\2192"; content: "\2192" / ""; font-weight: 500; font-size: 1.12em; line-height: 1;
  transition: transform .25s var(--ease);
}
.btn-arrow:hover::after { transform: translateX(4px); }

/* ---------- cards ---------- */
.card {
  position: relative; display: block;
  background: var(--card-bg); border: 1px solid var(--card-border); border-radius: var(--r-card);
  box-shadow: var(--shadow-card); padding: clamp(20px, 2.2vw, 30px);
  color: var(--body); text-decoration: none;
  -webkit-backdrop-filter: var(--card-blur); backdrop-filter: var(--card-blur);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s;
}
.card > * + * { margin-top: .6rem; }
.card h3 { margin-top: 1rem; }
.card > h3:first-child { margin-top: 0; }
.card p { color: var(--muted); font-size: .95rem; line-height: 1.55; }
a.card:hover, .card.is-interactive:hover, .card:focus-within.is-interactive {
  transform: translateY(-4px); box-shadow: var(--shadow-lift); border-color: var(--line-strong); color: var(--body);
}
/* centred card = flex column, so a .card-arrow (or a last .tag) sits on the
   card's bottom edge and lines up across a grid row of equal-height cards */
.card-center {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; padding-inline: clamp(16px, 1.6vw, 24px);
}
.card h3 { font-size: clamp(1.08rem, .98rem + .3vw, 1.22rem); }
.card-center > .medal, .card-center > .illu { margin-inline: auto; }
.card-arrow {
  display: inline-block; color: var(--ink); font-size: 1.1rem; line-height: 1;
  transition: transform .25s var(--ease), color .2s;
}
.card > .card-arrow { margin-top: auto; padding-top: 1rem; }
.card-center > .tag:last-child { margin-top: auto; }
.card-center > :has(+ .tag:last-child) { margin-bottom: .9rem; }
.card-arrow::before { content: "\2192"; content: "\2192" / ""; }
a.card:hover .card-arrow { transform: translateX(4px); color: var(--accent-ink); }
.card .tag { margin-top: .9rem; }
.card-flat { box-shadow: none; }

/* icon medallion: mint circle + glyph via mask so the glyph follows the theme.
   Glyph masks (web/media/invest/icon_*.png) are square crops of the full circle,
   so mask-size 100% reproduces the mockup's glyph-to-circle proportion. */
.medal {
  --medal-size: 66px;
  position: relative; display: block; flex: none;
  width: var(--medal-size); height: var(--medal-size); border-radius: 50%;
  background: var(--medal-bg); box-shadow: var(--medal-ring);
}
.medal::before {
  /* border-radius: PDF output can bleed a hairline of the masked fill along its
     box edge; rounding the box clips any such seam to the circle */
  content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--medal-glyph);
  -webkit-mask: var(--glyph) center / 100% 100% no-repeat; mask: var(--glyph) center / 100% 100% no-repeat;
}
.medal-sm { --medal-size: 48px; }
.medal-lg { --medal-size: 84px; }
.medal-person { --glyph: url("../media/invest/icon_person.png"); }
.medal-brain { --glyph: url("../media/invest/icon_brain.png"); }
.medal-bars { --glyph: url("../media/invest/icon_bars.png"); }
.medal-group { --glyph: url("../media/invest/icon_group.png"); }

/* illustration slot (transparent pack illustrations, web/media/ui/illu_*.png) */
.illu {
  position: relative; display: grid; place-items: center;
  height: var(--illu-h, clamp(120px, 12vw, 156px)); aspect-ratio: 4 / 3; max-width: 100%;
}
.illu::before {
  content: ""; position: absolute; inset: 4% 14%; border-radius: 50%;
  background: radial-gradient(closest-side, var(--illu-halo), transparent);
}
.illu img { position: relative; max-height: 100%; width: auto; object-fit: contain; filter: var(--illu-filter); }

/* glass panel */
.glass {
  background: var(--glass-bg); border: 1px solid var(--glass-border); border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow); padding: clamp(18px, 2vw, 26px);
  -webkit-backdrop-filter: blur(16px) saturate(1.25); backdrop-filter: blur(16px) saturate(1.25);
}

/* media frame for renders / clips / screenshots */
.media-frame {
  position: relative; overflow: hidden; border-radius: var(--r-lg);
  background: var(--surface-sunk); border: 1px solid var(--card-border); box-shadow: var(--shadow-card);
}
.media-frame > img, .media-frame > video { width: 100%; height: 100%; object-fit: cover; }
.media-caption { font-size: .85rem; color: var(--muted); margin-top: .7rem; }

/* hero figure (media/invest/hero_figure). .figure-glow wraps ONLY the
   <picture>; put captions and other overlays on a parent, because in the dark
   theme .figure-glow becomes a clipped, ringed disc (a square of its own
   width: set max-width on it). .figure-feather goes on the <img>.
   Light: halo + soft top/bottom mask. Dark: whole figure inside the disc. */
.figure-glow { position: relative; isolation: isolate; }
.figure-glow::before {
  content: ""; position: absolute; inset: 6% 8%; z-index: -1; border-radius: 50%;
  background: var(--figure-halo); pointer-events: none;
}
.figure-feather {
  -webkit-mask-image: var(--figure-feather); mask-image: var(--figure-feather);
  filter: var(--figure-filter);
}

/* ---------- status tags ---------- */
.tag {
  display: inline-flex; align-items: center; gap: .5em; vertical-align: middle;
  padding: .3em .78em .3em .66em; border-radius: var(--r-pill);
  font-size: .74rem; line-height: 1.3; font-weight: 600; letter-spacing: .015em; white-space: nowrap;
  background: var(--tag-later-bg); color: var(--tag-later-ink);
}
.tag::before {
  content: ""; width: .52em; height: .52em; border-radius: 50%; flex: none; background: var(--tag-later-dot);
}
.tag-built { background: var(--tag-built-bg); color: var(--tag-built-ink); }
.tag-built::before { background: var(--tag-built-dot); }
.tag-dev { background: var(--tag-dev-bg); color: var(--tag-dev-ink); }
.tag-dev::before { background: linear-gradient(90deg, var(--tag-dev-dot) 50%, transparent 50%); box-shadow: inset 0 0 0 1.4px var(--tag-dev-dot); }
.tag-later { background: var(--tag-later-bg); color: var(--tag-later-ink); }
.tag-later::before { background: transparent; box-shadow: inset 0 0 0 1.4px var(--tag-later-dot); }

/* ---------- stats strip ---------- */
.stats {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
  border-block: 1px solid var(--line); padding-block: clamp(22px, 3vw, 34px);
}
.stat { text-align: center; padding: 6px clamp(12px, 2vw, 28px); }
.stat + .stat { border-left: 1px solid var(--rule); }
.stat-num {
  font-size: clamp(1.75rem, 1.2rem + 1.6vw, 2.45rem); line-height: 1.1; font-weight: 600;
  letter-spacing: -.03em; color: var(--stat-num); font-variant-numeric: tabular-nums;
}
.stat-label { margin-top: .35rem; color: var(--ink); font-weight: 500; font-size: 1rem; }
.stat-sub { margin-top: .2rem; color: var(--muted); font-size: .86rem; }
@media (max-width: 900px) {
  .stats { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 22px; }
  .stat + .stat { border-left: 0; }
  .stat:nth-child(2n) { border-left: 1px solid var(--rule); }
}
@media (max-width: 380px) {
  .stats { grid-template-columns: 1fr; }
  .stat:nth-child(2n) { border-left: 0; }
}

/* ---------- notice / callout ---------- */
.notice {
  display: flex; gap: .8rem; align-items: flex-start;
  background: var(--notice-bg); border: 1px solid var(--notice-border); border-radius: var(--r-md);
  padding: .9rem 1.15rem; color: var(--body); font-size: .94rem; line-height: 1.55;
}
.notice strong { color: var(--ink); flex: none; white-space: nowrap; }

/* ---------- tables (white paper) ---------- */
.table-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--card-border); border-radius: var(--r-md);
  background: var(--surface); box-shadow: var(--shadow-sm);
}
/* min-width: on phones the wrapper scrolls instead of squeezing columns to one word */
.table { width: 100%; min-width: 560px; border-collapse: collapse; font-size: .93rem; line-height: 1.5; }
.table caption { caption-side: top; text-align: left; padding: .9rem 1rem .4rem; color: var(--muted); font-size: .85rem; }
.table th, .table td { padding: .78rem 1rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); }
.table thead th {
  background: var(--surface-2); color: var(--ink); font-weight: 600; font-size: .78rem;
  letter-spacing: .08em; text-transform: uppercase; white-space: nowrap;
}
.table tbody tr:last-child > * { border-bottom: 0; }
.table tbody th { color: var(--ink); font-weight: 600; }
.table tbody tr:hover > * { background: var(--surface-2); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- long-form reading (white paper) ---------- */
.prose { max-width: 70ch; color: var(--body); font-size: 1.04rem; line-height: 1.75; }
.prose > * + * { margin-top: 1.05em; }
.prose h2 { margin-top: 2.4em; font-size: clamp(1.6rem, 1.2rem + 1.3vw, 2.2rem); }
.prose h3 { margin-top: 1.9em; }
.prose h4 { margin-top: 1.6em; }
.prose h2 + *, .prose h3 + *, .prose h4 + * { margin-top: .7em; }
.prose ul, .prose ol { padding-left: 1.35em; }
.prose li + li { margin-top: .4em; }
.prose li::marker { color: var(--accent); }
.prose blockquote {
  border-left: 2px solid var(--accent); padding: .2em 0 .2em 1.2em; color: var(--ink); font-style: italic;
}
.prose hr { border: 0; height: 1px; background: var(--rule); margin-block: 2.4em; }
.prose .table-wrap { margin-block: 1.6em; }
.standfirst {
  font-style: italic; font-weight: 400; font-size: clamp(1.1rem, 1rem + .4vw, 1.3rem); line-height: 1.6;
  color: var(--ink); letter-spacing: -.005em;
}
.toc { font-size: .92rem; line-height: 1.45; }
.toc ol, .toc ul { list-style: none; padding: 0; counter-reset: toc; }
.toc li { counter-increment: toc; }
.toc a {
  display: flex; gap: .7em; padding: .42em .6em; border-radius: var(--r-sm);
  color: var(--body); text-decoration: none; transition: background-color .2s, color .2s;
}
.toc a::before { content: counter(toc, decimal-leading-zero); color: var(--muted); font-variant-numeric: tabular-nums; font-size: .82em; padding-top: .12em; }
.toc a:hover { background: var(--btn-outline-hover-bg); color: var(--ink); }
.toc a[aria-current="true"], .toc a.is-active { color: var(--brand); font-weight: 600; background: var(--mint); }

/* ---------- hero scaffolding ---------- */
.hero { position: relative; padding-block: clamp(28px, 5vw, 72px) clamp(40px, 6vw, 88px); }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr); gap: clamp(24px, 4vw, 56px); align-items: center; }
.hero-copy .lede { margin-top: 1.4rem; }
.hero-copy .subhead { margin-top: 1.3rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 2rem; }
.hero-media { position: relative; }
@media (max-width: 900px) { .hero-grid { grid-template-columns: 1fr; } }
@media (max-width: 480px) { .hero-actions .btn { flex: 1 1 100%; } }

/* ---------- movement tiles (behaviour in site.js) ---------- */
.moves { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); gap: var(--gap); }
.move {
  position: relative; overflow: hidden; aspect-ratio: 4 / 5; border-radius: var(--r-lg);
  background: var(--surface-sunk); border: 1px solid var(--card-border); box-shadow: var(--shadow-card);
  cursor: pointer; isolation: isolate;
}
.move > img, .move > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.move > video { z-index: 1; }
.move:hover > img, .move:hover > video { transform: scale(1.04); }
.move figcaption {
  position: absolute; inset: auto 0 0 0; z-index: 2; padding: 44px 16px 14px;
  background: linear-gradient(180deg, transparent, rgba(4, 18, 22, .78));
  color: #f2f7f5;
}
.move .idx { font-size: .74rem; letter-spacing: .2em; color: #9fe6d2; font-family: var(--font-cjk); }
.move .nm { font-weight: 600; font-size: 1.02rem; line-height: 1.25; margin-top: 2px; }
.move .badge {
  position: absolute; top: 12px; right: 12px; z-index: 2; padding: .25em .7em; border-radius: var(--r-pill);
  font-size: .7rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  background: rgba(4, 18, 22, .55); color: #eaf5f1; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: .9; transition: opacity .25s;
}
.move.is-playing .badge { opacity: 0; }
/* toggle button injected by site.js over the whole tile (keyboard + screen readers) */
.move-hit {
  position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%;
  padding: 0; border: 0; border-radius: inherit; background: transparent; cursor: pointer;
}
.move-hit:focus-visible { outline-offset: -4px; border-radius: inherit; }
@media (max-width: 600px) {
  .moves { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .move figcaption { padding: 36px 10px 10px; }
  .move .nm { font-size: .86rem; }
  .move .badge { top: 8px; right: 8px; }
}

/* ---------- footer ---------- */
.site-footer { margin-top: var(--section-y); border-top: 1px solid var(--line); background: var(--bg-soft); }
.footer-grid {
  display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 4vw, 48px); padding-block: clamp(40px, 5vw, 64px) clamp(24px, 3vw, 36px);
}
.footer-brand p { margin-top: 1rem; max-width: 36ch; color: var(--muted); font-size: .92rem; }
.footer-title { font-size: .72rem; letter-spacing: .24em; text-transform: uppercase; color: var(--kicker); font-weight: 600; margin-bottom: .9rem; }
.footer-links { display: flex; flex-direction: column; gap: .55rem; font-size: .93rem; }
.footer-links a { color: var(--body); text-decoration: none; }
.footer-links a:hover { color: var(--ink); text-decoration: underline; }
/* plain (non-link) lines in a footer column: credits, access notes */
.footer-note { color: var(--muted); font-size: .88rem; line-height: 1.5; }
.footer-bottom {
  position: relative; display: flex; flex-wrap: wrap; gap: 8px 24px; align-items: center; justify-content: space-between;
  padding-block: 18px 28px; font-size: .82rem; color: var(--muted);
}
.footer-bottom::before { content: ""; position: absolute; top: 0; left: var(--gutter); right: var(--gutter); height: 1px; background: var(--line); }
.footer-bottom a { color: var(--muted); }
@media (max-width: 860px) { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .footer-brand { grid-column: 1 / -1; } }
@media (max-width: 420px) { .footer-grid { grid-template-columns: 1fr; } }

/* ---------- invite code (behaviour in site.js) ----------
   The dialog site.js builds on first use, the pieces an on-page form reuses
   (whitepaper.html's access panel: .invite-label / -field / -input / -reveal /
   -err), the confirmation after an in-place unlock, and a text-style button. */
.linkbtn {
  display: inline; padding: 0; border: 0; background: none; font: inherit; font-weight: 600;
  color: var(--accent-ink); text-align: left; cursor: pointer;
  text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px;
}
.linkbtn:hover { color: var(--ink); }

.invite-dlg {
  width: min(440px, calc(100% - 2 * var(--gutter))); max-width: none; max-height: calc(100% - 32px);
  margin: auto; padding: 0; border: 0; border-radius: var(--r-xl);
  background: var(--surface-solid); color: var(--body); box-shadow: var(--shadow-lift);
  overflow: auto; overscroll-behavior: contain;
}
.invite-dlg::backdrop { background: rgba(6, 22, 26, .42); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.invite-card { position: relative; display: flex; flex-direction: column; align-items: stretch; padding: clamp(26px, 5vw, 38px) clamp(22px, 5vw, 36px) clamp(22px, 4vw, 30px); }
.invite-x {
  position: absolute; top: 12px; right: 12px; display: grid; place-items: center; width: 40px; height: 40px;
  padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--muted);
}
.invite-x:hover { background: var(--btn-outline-hover-bg); color: var(--ink); }
.invite-x:focus-visible { border-radius: 50%; }
.invite-x svg { width: 18px; height: 18px; }
.invite-mark { display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%; background: var(--mint); color: var(--brand); }
.invite-mark svg { width: 24px; height: 24px; }
.invite-title { margin-top: 1.1rem; padding-right: 28px; font-size: clamp(1.4rem, 1.25rem + .6vw, 1.7rem); line-height: 1.2; letter-spacing: -.022em; }
.invite-desc { margin-top: .55rem; font-size: .96rem; line-height: 1.55; color: var(--body); }
.invite-label { display: block; margin-top: 1.4rem; font-size: .88rem; font-weight: 650; color: var(--ink); }
.invite-field { position: relative; margin-top: .45rem; }
.invite-input {
  display: block; width: 100%; height: 50px; padding: 0 52px 0 18px;
  border: 1px solid var(--btn-outline-border); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink); font-size: 1.05rem; letter-spacing: .03em;
  transition: border-color .2s, box-shadow .2s;
}
.invite-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--selection); }
.invite-input[aria-invalid="true"] { border-color: var(--tag-dev-dot); }
.invite-reveal {
  position: absolute; top: 5px; right: 5px; display: grid; place-items: center; width: 40px; height: 40px;
  padding: 0; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--muted);
}
.invite-reveal:hover { color: var(--ink); background: var(--btn-outline-hover-bg); }
.invite-reveal svg { width: 20px; height: 20px; }
/* the icon shows the action: an eye while the code is hidden, struck through while shown */
.invite-reveal .eye-slash { display: none; }
.invite-reveal[aria-pressed="true"] .eye-slash { display: inline; }
/* calm, not alarming: the "in development" ink; rendered even when empty so the
   role=alert line is in place before it speaks */
.invite-err { font-size: .9rem; line-height: 1.5; font-weight: 500; color: var(--tag-dev-ink); }
.invite-err:not(:empty) { margin-top: .6rem; }
.invite-submit { margin-top: 1.25rem; width: 100%; }
[data-invite-form] [aria-disabled="true"] { opacity: .78; cursor: progress; }
.invite-foot { margin-top: 1.1rem; font-size: .88rem; line-height: 1.5; color: var(--muted); text-align: center; }
.invite-foot a { font-weight: 600; }
@media (prefers-reduced-motion: no-preference) {
  .invite-dlg[open] { animation: invite-in .22s var(--ease); }
  .invite-dlg[open]::backdrop { animation: invite-fade .22s var(--ease); }
}
@keyframes invite-in { from { opacity: 0; transform: translateY(10px) scale(.985); } }
@keyframes invite-fade { from { opacity: 0; } }

.invite-toast {
  position: fixed; left: 50%; bottom: max(20px, env(safe-area-inset-bottom, 0px)); z-index: 120;
  max-width: calc(100% - 32px); padding: .75em 1.25em; border-radius: var(--r-md);
  background: var(--ink); color: var(--bg); box-shadow: var(--shadow-lift);
  font-size: .92rem; font-weight: 600; line-height: 1.4; text-align: center;
  opacity: 0; transform: translate(-50%, 8px); pointer-events: none;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}
.invite-toast.is-on { opacity: 1; transform: translate(-50%, 0); }

/* ---------- reveal on scroll (.rv -> .rv.in via site.js) ---------- */
.js .rv {
  opacity: 0; transform: translateY(18px);
  transition: opacity .75s var(--ease), transform .75s var(--ease);
}
.js .rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .rv { opacity: 1; transform: none; transition: none; }
}

/* ---------- print (white paper PDF) ----------
   The dark tokens and dark overrides are screen-only, so print is always the
   light palette whatever theme the reader had on. */
@media print {
  :root { --bg-wash: none; --bg: #fff; }
  html, body { background: #fff; }
  body { color: #1d2b28; }
  .site-nav, .skip-link, .theme-toggle, .nav-toggle, .no-print,
  .invite-dlg, .invite-toast, [data-invite-open], form[data-invite-form] { display: none !important; }
  .js .rv { opacity: 1 !important; transform: none !important; }
  .card, .glass, .table-wrap { box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
  .table { min-width: 0; }
  a { color: inherit; }
  /* some PDF renderers ignore CSS masks: paint the glyph PNG (black + alpha) itself */
  .medal::before { -webkit-mask: none; mask: none; background: var(--glyph) center / 100% 100% no-repeat; opacity: .85; }
}

/* =====================================================================
   Dark theme: component overrides. Screen only (see the dark tokens).
   ===================================================================== */
@media screen {
  :root[data-theme="dark"] {
    --icon-theme: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4.2'/%3E%3Cpath d='M12 2.5v2.2M12 19.3v2.2M4.6 4.6l1.6 1.6M17.8 17.8l1.6 1.6M2.5 12h2.2M19.3 12h2.2M4.6 19.4l1.6-1.6M17.8 6.2l1.6-1.6'/%3E%3C/svg%3E");
  }
  :root[data-theme="dark"] .skip-link { background: #0f6a5a; }
  :root[data-theme="dark"] .section-alt { border-block: 1px solid var(--line); }

  /* light type on near-black reads heavier: optical compensation */
  :root[data-theme="dark"] :is(h1, .display) { font-weight: 540; }
  :root[data-theme="dark"] :is(h2, .h2) { font-weight: 560; }

  :root[data-theme="dark"] .accent-rule { box-shadow: 0 0 12px rgba(95, 220, 191, .5); }
  :root[data-theme="dark"] .site-nav { border-bottom-color: var(--nav-border); }
  :root[data-theme="dark"] .nav-links a[aria-current="page"],
  :root[data-theme="dark"] .nav-links a[aria-current="true"],
  :root[data-theme="dark"] .nav-links a.is-active { color: var(--ink); }
  :root[data-theme="dark"]:not([lang|="zh"]) .lang-toggle [data-lang-set="en"],
  :root[data-theme="dark"][lang|="zh"] .lang-toggle [data-lang-set="zh"] { color: var(--ink); }
  :root[data-theme="dark"] .btn-primary { text-shadow: 0 1px 1px rgba(0, 40, 45, .35); border-color: rgba(160, 255, 225, .18); }

  /* hero figure: a ringed "moon window" disc that keeps the whole figure */
  :root[data-theme="dark"] .figure-glow {
    aspect-ratio: 1; border-radius: 50%; overflow: hidden;
    background: radial-gradient(circle at 50% 42%, rgba(63, 207, 170, .14), rgba(2, 14, 20, .9) 70%);
    box-shadow: 0 0 64px -12px rgba(95, 220, 191, .42), 0 40px 80px -40px rgba(0, 0, 0, .9);
  }
  :root[data-theme="dark"] .figure-glow::before { display: none; }
  :root[data-theme="dark"] .figure-glow > picture,
  :root[data-theme="dark"] .figure-glow > picture > img,
  :root[data-theme="dark"] .figure-glow > img { width: 100%; height: 100%; }
  :root[data-theme="dark"] .figure-glow img { object-fit: cover; object-position: 50% 40%; }
  :root[data-theme="dark"] .figure-glow::after {
    content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
    background: radial-gradient(closest-side, transparent 74%, rgba(2, 12, 17, .5) 90%, rgba(2, 12, 17, .88) 100%);
    box-shadow: inset 0 0 0 1.5px rgba(95, 220, 191, .5);
  }

  :root[data-theme="dark"] .tag-built { box-shadow: inset 0 0 0 1px rgba(95, 220, 191, .28); }
  :root[data-theme="dark"] .tag-dev { box-shadow: inset 0 0 0 1px rgba(233, 190, 110, .26); }
  :root[data-theme="dark"] .tag-later { box-shadow: inset 0 0 0 1px rgba(170, 190, 215, .22); }
  :root[data-theme="dark"] .stat-num {
    background: var(--stat-num-fill); -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
  }
  :root[data-theme="dark"] .toc a[aria-current="true"], :root[data-theme="dark"] .toc a.is-active { color: var(--ink); }

  /* invite code */
  :root[data-theme="dark"] .invite-dlg { box-shadow: 0 0 0 1px var(--card-border), var(--shadow-lift); }
  :root[data-theme="dark"] .invite-dlg::backdrop { background: rgba(0, 6, 9, .62); }
  :root[data-theme="dark"] .invite-mark { color: var(--accent); box-shadow: inset 0 0 0 1px rgba(95, 220, 191, .28); }
  :root[data-theme="dark"] .invite-input { background: rgba(255, 255, 255, .04); }
  :root[data-theme="dark"] .invite-toast { background: #dff3ec; color: #041419; }
  :root[data-theme="dark"] .site-footer { background: rgba(0, 0, 0, .18); }
}

/* forced colours (Windows contrast themes): plain text for gradient numbers */
@media (forced-colors: active) {
  .stat-num { background: none !important; -webkit-text-fill-color: currentColor !important; }
}
