/* Vwake "Halo Hour" — shared styles for /, /en/, /ja/. See DESIGN.md. */

:root {
  --ink: #15101F;
  --ink-deep: #0D0A14;
  --plum: #221A33;
  --plum-soft: #1B1528;
  --line: rgba(180, 156, 230, 0.16);
  --line-strong: rgba(180, 156, 230, 0.32);
  --lavender: #B49CE6;
  --cream: #F5F2EE;
  --muted: #A79DBA;
  --faint: #6F6582;
  --coral: #EE6B55;
  --orange: #FF9F5A;
  --magenta: #B05CC8;
  --signal: linear-gradient(100deg, #EE6B55 0%, #FF9F5A 45%, #B05CC8 100%);

  /* Aliases used by assets/creator-marquee.css */
  --accent-light: var(--lavender);
  --gradient-soft: linear-gradient(135deg, #B49CE6, #B05CC8);

  /* One family everywhere: Inter for Latin, the system / Noto sans for CJK. */
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'PingFang TC', 'Noto Sans TC', sans-serif;
  --font-body: var(--font-display);
  --font-mono: var(--font-display);

  --gutter: clamp(20px, 4vw, 48px);
  --section-space: clamp(72px, 9vw, 128px);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

html:lang(ja) {
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Hiragino Sans', 'Noto Sans JP', sans-serif;
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
  /* No rubber-band bounce at the top or bottom: it fought the pinned slides on phones. */
  overscroll-behavior-y: none;
  background: var(--ink);
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--ink);
  color: var(--cream);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
main { overflow-x: clip; }

/* CJK text should not inherit Latin letter-spacing tweaks. */
html:lang(zh-TW) body, html:lang(ja) body { line-height: 1.8; }

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
img { display: block; max-width: 100%; }
::selection { background: rgba(238, 107, 85, 0.35); color: var(--cream); }

:focus-visible {
  outline: 2px solid var(--lavender);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--cream);
  color: var(--ink);
  font-weight: 600;
}
.skip-link:focus { top: 16px; }

.container {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Shared type ---------- */

.label {
  display: block;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.label time,
.label .label-time {
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  font-variant-numeric: tabular-nums;
}

.display {
  font-family: var(--font-display);
  font-weight: 600;
  font-optical-sizing: auto;
  letter-spacing: -0.03em;
  line-height: 1.04;
  text-wrap: balance;
}
html:lang(zh-TW) .display,
html:lang(ja) .display {
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1.22;
}
/* Titles are split into phrases (.p). A line can only break between phrases,
   unless a single phrase is wider than the screen. */
.display .p,
.step-title .p {
  display: inline-block;
  max-width: 100%;
}
/* Japanese has no spaces, so a phrase wider than the screen would break between
   any two characters. Keep each phrase whole; a long phrase may break only at a
   <wbr> placed at a natural pause in the HTML. */
html:lang(ja) .display .p,
html:lang(ja) .step-title .p { word-break: keep-all; }
/* The emphasised part of a headline carries the signal gradient in every language.
   Latin text is also italic; the padding keeps the slanted last letter inside the
   painted gradient. */
.display em {
  font-style: italic;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  padding-right: 0.08em;
}
html:lang(zh-TW) .display em,
html:lang(ja) .display em {
  font-style: normal;
  padding-right: 0;
}

.section {
  position: relative;
  padding: var(--section-space) 0;
  scroll-margin-top: 84px;
}

.section-header {
  display: grid;
  /* Stay at the top even when a two-column layout (FAQ) stretches the header
     to the height of its neighbour; otherwise the headline drifts down. */
  align-content: start;
  gap: 22px;
  max-width: 880px;
  margin-bottom: clamp(48px, 6vw, 80px);
}

.section-title {
  font-size: clamp(34px, 4.6vw, 64px);
}

.section-desc, .hero-desc, .final-cta-desc { text-wrap: balance; }
/* Keeps a sentence together; lines break between sentences. */
.phrase { display: inline-block; max-width: 100%; }
.section-desc {
  max-width: 600px;
  color: var(--muted);
  font-size: clamp(16px, 1.3vw, 18px);
  line-height: 1.75;
}

.hairline {
  height: 1px;
  border: 0;
  background: var(--line);
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 56px;
  padding: 0 32px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  transition: transform 0.2s var(--ease-out), box-shadow 0.2s var(--ease-out), background-color 0.2s;
}
.btn svg { flex: none; transition: transform 0.2s var(--ease-out); }
.btn:hover svg { transform: translateX(3px); }

.btn-primary {
  background: linear-gradient(100deg, #FF8A5C 0%, #EE6B55 40%, #D9506E 75%, #B05CC8 130%);
  color: #FFF8F3;
  text-shadow: 0 1px 0 rgba(120, 30, 40, 0.25);
  box-shadow: 0 10px 40px -12px rgba(238, 107, 85, 0.7);
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 48px -12px rgba(238, 107, 85, 0.85);
}
.btn-primary:active { transform: translateY(0); }

.btn-ghost {
  padding: 0 6px;
  color: var(--cream);
}
.btn-ghost:hover { color: var(--orange); }

.btn-outline {
  border: 1px solid var(--line-strong);
  color: var(--cream);
}
.btn-outline:hover { border-color: var(--lavender); background: rgba(180, 156, 230, 0.06); }

/* ---------- Nav ---------- */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  transition: background-color 0.3s, border-color 0.3s, backdrop-filter 0.3s;
  border-bottom: 1px solid transparent;
}
.nav.is-scrolled {
  background: rgba(21, 16, 31, 0.78);
  border-bottom-color: var(--line);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
}

.nav-inner {
  display: flex;
  align-items: center;
  gap: 40px;
  height: 84px;
}

.wordmark {
  /* The Vwake wordmark: heavy Inter, tight tracking, V in the app icon's gradient. */
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 26px;
  font-weight: 900;
  line-height: 1;
  letter-spacing: -1px;
  color: var(--cream);
}
.wordmark .v {
  color: transparent;
  /* The app icon's clock hands: coral → orange → magenta. */
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
}
.nav-links a {
  position: relative;
  display: inline-flex;
  white-space: nowrap;
  align-items: center;
  min-height: 40px;
  padding: 0 14px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--muted);
  transition: color 0.2s, background-color 0.2s;
}
.nav-links a:hover { color: var(--cream); background: rgba(180, 156, 230, 0.08); }
/* The section on screen (site.js sets .is-current). */
.nav-links a.is-current { color: var(--cream); }
.nav-links a.is-current::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 4px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--coral);
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: 20px;
}

/* Language switch: one compact pill. */
.lang-switch {
  display: flex;
  align-items: center;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
}
.lang-switch a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 30px;
  padding: 0 8px;
  border-radius: 999px;
  color: var(--faint);
  transition: color 0.2s, background-color 0.2s;
}
.lang-switch a:hover { color: var(--cream); }
.lang-switch a.active { color: var(--cream); background: rgba(180, 156, 230, 0.14); }
/* Language menu (lang-menu.js adds .is-menu): one 「中 ▾」 button at every width.
   The other languages drop down under it, one per row, so adding languages later
   only adds rows to the menu, never width to the nav. Without the script all
   buttons stay in a row. */
.lang-switch { position: relative; }
.lang-switch.is-menu a:not(.active) { display: none; }
.lang-switch.is-menu a.active { padding: 0 10px; }
.lang-switch.is-menu a.active::after {
  content: "";
  width: 0;
  height: 0;
  margin-left: 5px;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  border-top: 4px solid currentColor;
  transition: transform 0.2s;
}
.lang-switch.is-menu.is-open a.active::after { transform: rotate(180deg); }
/* lang-menu.js sets --i (0, 1, 2 …) on each of the other languages. */
.lang-switch.is-menu.is-open a:not(.active) {
  display: inline-flex;
  position: absolute;
  right: -1px;
  top: calc(100% + 6px + var(--i, 0) * 40px);
  min-width: 52px;
  height: 34px;
  border: 1px solid var(--line-strong);
  background: rgba(21, 16, 31, 0.96);
  color: var(--cream);
}
.lang-switch.is-menu.is-open a:not(.active):hover { border-color: var(--lavender); }

/* Fans / creators switch: the same pill, a size up, shown on every width. */
.audience-switch {
  display: flex;
  align-items: center;
  padding: 3px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
.audience-switch a {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 14px;
  border-radius: 999px;
  color: var(--muted);
  transition: color 0.2s, background-color 0.2s;
}
.audience-switch a:hover { color: var(--cream); }
.audience-switch a.active { color: var(--cream); background: rgba(238, 107, 85, 0.16); }

.nav-login {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding: 0 16px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  color: var(--cream);
  white-space: nowrap;
  transition: border-color 0.2s, background-color 0.2s;
}
.nav-login:hover { border-color: var(--coral); background: rgba(238, 107, 85, 0.08); }
/* The person icon replaces the words on phones (see the 620 px block). */
.nav-login-icon { display: none; flex: none; }
/* en / ja creators tab: a shorter label on phones (Creators / クリエイター). */
.audience-switch .tab-short { display: none; }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  padding-top: 84px;
  overflow: hidden;
  isolation: isolate;
}

.hero .container {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.hero-grid {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  align-items: center;
  gap: 24px;
  padding: clamp(20px, 3.5vh, 44px) 0 clamp(20px, 3vh, 36px);
  border-top: 1px solid var(--line);
}

.hero-copy {
  position: relative;
  z-index: 2;
  display: grid;
  justify-items: start;
}

.hero-clock {
  font-family: var(--font-display);
  font-size: clamp(64px, 9.4vw, 150px);
  font-weight: 500;
  line-height: 0.9;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
}
.hero-clock .clock-sec { display: inline-block; min-width: 1.02em; }

.hero-clock-label { margin: 12px 0 clamp(18px, 3vh, 32px); }

.hero-tagline {
  font-size: clamp(46px, 6.6vw, 100px);
  max-width: 13ch;
}
html:lang(zh-TW) .hero-tagline,
html:lang(ja) .hero-tagline {
  font-size: clamp(42px, 6.2vw, 92px);
  line-height: 1.12;
  max-width: none;
}
.hero-tagline .line { display: block; }
/* English and Japanese headlines are longer than the Chinese one. */
html:lang(en) .hero-tagline { font-size: clamp(40px, 4.6vw, 72px); max-width: 15ch; }
html:lang(ja) .hero-tagline { font-size: clamp(32px, 4.1vw, 62px); }
html:lang(ja) .hero-tagline .line { white-space: nowrap; }
@media (max-width: 620px) {
  /* "VTuberボイスパックを" must fit one line: size the headline to the screen width. */
  html:lang(ja) .hero-tagline { font-size: min(8.4vw, 40px); }
}

.hero-desc {
  max-width: 560px;
  margin-top: 18px;
  color: var(--muted);
  font-size: clamp(16px, 1.25vw, 18px);
  line-height: 1.75;
}

.hero-ctas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 28px;
  margin-top: clamp(22px, 3vh, 32px);
}

.hero-stats {
  margin-top: 22px;
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.hero-stats strong { color: var(--cream); font-weight: 500; }
.hero-stats .dot { margin: 0 10px; color: var(--faint); }

/* The eclipse: a CSS disc with a corona. Vanta HALO adds motion behind it on capable desktops. */
.hero-eclipse {
  position: relative;
  z-index: 1;
  justify-self: end;
  width: min(37vw, 560px);
  aspect-ratio: 1;
  margin-right: clamp(-40px, -2vw, 0px);
  pointer-events: none;
}

/* A lit planet, like the user's reference: light comes from the upper right.
   The top rim glows purple → magenta, the right side warms to pink → coral, and the
   inside of the sphere picks up a soft haze near the lit edge. The left side stays dark.
   Layers: bloom → hover-only left rim → thin corona → sphere. */
.hero-eclipse-inner { position: absolute; inset: 0; }

.eclipse-bloom {
  position: absolute;
  inset: -30%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 88% 62%, rgba(238, 107, 85, 0.42), transparent 40%),
    radial-gradient(circle at 74% 18%, rgba(196, 92, 190, 0.30), transparent 40%);
  filter: blur(50px);
  animation: eclipse-breathe 7s ease-in-out infinite alternate;
}

.eclipse-left {
  position: absolute;
  inset: -2%;
  border-radius: 50%;
  background: conic-gradient(from 200deg,
    transparent 0deg,
    rgba(150, 120, 230, 0.7) 50deg,
    rgba(176, 92, 200, 0.55) 105deg,
    transparent 150deg,
    transparent 360deg);
  filter: blur(16px);
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
}
@media (hover: hover) {
  .hero-eclipse { pointer-events: auto; }
  .hero-eclipse:hover .eclipse-left { opacity: 0.5; }
}

.eclipse-corona {
  position: absolute;
  inset: -1.6%;
  border-radius: 50%;
  background: conic-gradient(from 200deg,
    transparent 0deg,
    transparent 115deg,
    rgba(140, 90, 210, 0.55) 150deg,
    #B65BC0 185deg,
    #DE5F9C 215deg,
    #EF6A72 245deg,
    #FF7A5C 275deg,
    rgba(238, 107, 85, 0.35) 305deg,
    transparent 335deg);
  filter: blur(12px);
  transform: translate(0.8%, -0.4%);
  animation: eclipse-flow 12s ease-in-out infinite alternate;
}

.eclipse-disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 80% 16%, rgba(200, 96, 190, 0.55) 0%, rgba(120, 62, 152, 0.30) 24%, transparent 55%),
    radial-gradient(circle at 98% 62%, rgba(238, 107, 85, 0.40) 0%, transparent 38%),
    radial-gradient(circle at 28% 72%, #100B19 0%, #150F23 50%, #1D1430 100%);
  /* A thin bright rim on the lit (upper-right) edge. */
  box-shadow:
    inset -12px 10px 26px -8px rgba(232, 110, 170, 0.65),
    inset -2px 2px 3px rgba(255, 175, 195, 0.55);
  animation: eclipse-drift 14s ease-in-out infinite alternate;
}

@keyframes eclipse-breathe {
  from { opacity: 0.75; transform: scale(0.98); }
  to { opacity: 1; transform: scale(1.03); }
}
@keyframes eclipse-flow {
  from { transform: translate(0.8%, -0.4%) rotate(-10deg); }
  to { transform: translate(1%, -0.2%) rotate(8deg); }
}
@keyframes eclipse-drift {
  from { transform: translate(-0.4%, 0.4%); }
  to { transform: translate(0.3%, -0.2%); }
}

.hero-avatars {
  position: relative;
  z-index: 2;
  display: block;
  height: clamp(96px, 11vw, 150px);
  border-top: 1px solid var(--line);
}
.hero-avatars-row {
  display: flex;
  justify-content: space-between;
  gap: clamp(12px, 2vw, 32px);
  padding-top: clamp(20px, 2.4vw, 32px);
}
.hero-avatar {
  position: relative;
  flex: 0 1 auto;
  min-width: 0;
  border-radius: 50%;
  transform-origin: 50% 100%;
  transition: transform 0.35s var(--ease-out);
}
.hero-avatars-row img {
  display: block;
  width: clamp(96px, 11.5vw, 180px);
  max-width: 100%;
  aspect-ratio: 1;
  height: auto;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  object-fit: cover;
  background: var(--plum);
  box-shadow: 0 -10px 40px -20px rgba(180, 156, 230, 0.4);
  transition: border-color 0.3s, box-shadow 0.3s;
}
.hero-avatar-name {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(21, 16, 31, 0.85);
  font-size: 12px;
  white-space: nowrap;
  color: var(--cream);
  opacity: 0;
  transform: translate(-50%, 4px);
  transition: opacity 0.25s, transform 0.25s var(--ease-out);
  pointer-events: none;
}
/* Hover or keyboard focus: the avatar grows out of the row and shows its name. */
.hero-avatar:hover,
.hero-avatar:focus-visible { transform: translateY(-14px) scale(1.18); z-index: 1; }
.hero-avatar:hover img,
.hero-avatar:focus-visible img {
  border-color: var(--coral);
  box-shadow: 0 0 0 3px rgba(238, 107, 85, 0.35), 0 16px 40px -12px rgba(238, 107, 85, 0.6);
}
.hero-avatar:hover .hero-avatar-name,
.hero-avatar:focus-visible .hero-avatar-name { opacity: 1; transform: translate(-50%, 0); }

/* ---------- App preview (carousel) ---------- */

/* The section right after the eclipse zoom starts close, so the dark frame is brief. */
#preview { padding-top: clamp(72px, 8vw, 110px); }

.preview-frame { position: relative; }

.preview-strip {
  display: flex;
  gap: clamp(14px, 1.8vw, 24px);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  border-radius: 28px;
  -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent);
  mask-image: linear-gradient(90deg, #000 88%, transparent);
}
.preview-strip::-webkit-scrollbar { display: none; }

.preview-tile {
  flex: 0 0 calc((100% - 2 * clamp(14px, 1.8vw, 24px)) / 3.3);
  scroll-snap-align: start;
  border-radius: 28px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--plum-soft);
}
.preview-tile img { width: 100%; height: auto; }

.preview-nav {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(21, 16, 31, 0.82);
  color: var(--cream);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  transform: translateY(-50%);
  transition: opacity 0.2s, border-color 0.2s, background-color 0.2s;
}
.preview-nav:hover:not(:disabled) { border-color: var(--orange); background: rgba(34, 26, 51, 0.95); }
.preview-nav:disabled { opacity: 0; pointer-events: none; }
.preview-nav-prev { left: -20px; }
.preview-nav-next { right: -20px; }

@media (max-width: 820px) {
  .preview-tile { flex-basis: 72%; }
  .preview-nav { display: none; }
}

/* ---------- Why / retention ---------- */

/* Three numbers on one slide (stat picker). Tabs pick a number; its panel
 * lands the number big and counts it up (site.js), then the words follow.
 * Without site.js every panel shows, one under another. */
.stat-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: clamp(16px, 2.5vw, 32px);
}
.stat-tab {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 132px;
  padding: 12px 18px;
  border: 1px solid var(--line);
  border-radius: 6px;
  text-align: left;
  color: var(--muted);
  transition: border-color 0.2s, background-color 0.2s, color 0.2s;
}
.stat-tab:hover { border-color: var(--line-strong); color: var(--cream); }
.stat-tab:focus-visible { outline: 2px solid var(--lavender); outline-offset: 2px; }
.stat-tab-number {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
}
.stat-tab-name { font-size: 12px; letter-spacing: 0.06em; }
.stat-tab[aria-selected="true"] {
  border-color: rgba(238, 107, 85, 0.55);
  background: rgba(238, 107, 85, 0.10);
  color: var(--cream);
}
.stat-tab[aria-selected="true"] .stat-tab-number {
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
}

.stat-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(24px, 4vw, 64px);
  margin-top: clamp(20px, 3vw, 40px);
}
.stat-panel[hidden] { display: none; }
/* With site.js, all panels share one grid cell, so the slide keeps the height of
 * the tallest and nothing above moves when you switch. Hidden ones stay laid out
 * but invisible (visibility also hides them from screen readers). */
.stat-picker.is-ready { display: grid; }
.stat-picker.is-ready .stat-tabs { grid-row: 1; }
.stat-picker.is-ready .stat-panel { grid-row: 2; grid-column: 1; align-self: start; }
.stat-picker.is-ready .stat-panel[hidden] { display: grid; visibility: hidden; }
/* container-type lets the number size itself to this column (cqi units below). */
.stat-panel-figure { position: relative; isolation: isolate; container-type: inline-size; }
/* A warm flash behind the number as it lands. */
.stat-panel-figure::before {
  content: "";
  position: absolute;
  left: -10%;
  top: 50%;
  width: 90%;
  aspect-ratio: 2 / 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(238, 107, 85, 0.45), rgba(176, 92, 200, 0.18) 55%, transparent);
  transform: translateY(-50%);
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}
.stat-panel-number {
  /* The gradient only paints inside this box. Two things kept it from covering
     the whole "70.4%":
     - the number was wider than its column (13vw grows faster than the column),
       so the font is also capped at a third of the column (33cqi, measured:
       "70.4%" is about 2.95 em wide);
     - the negative letter-spacing pulls the box in past the last glyph, so the
       box hugs the text (inline-block) and gets a little padding on the right. */
  display: inline-block;
  font-family: var(--font-display);
  font-size: min(clamp(88px, 13vw, 200px), 33cqi);
  font-weight: 600;
  line-height: 0.95;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-right: 0.08em;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
}
.stat-panel-label { margin-top: 10px; color: var(--cream); font-size: 17px; }
.stat-panel-title {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.4vw, 34px);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--cream);
}
.stat-panel-title em {
  font-style: normal;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
}
.stat-panel-desc { margin-top: 12px; color: var(--muted); font-size: 15px; line-height: 1.7; }
.stat-panel .compare { margin-top: 20px; }

/* The impact: the number drops in big and sharpens, the glow flashes, the words rise after. */
.stat-panel.is-entering .stat-panel-number { animation: stat-land 0.8s var(--ease-out) both; }
.stat-panel.is-entering .stat-panel-figure::before { animation: stat-glow 1.4s ease-out both; }
.stat-panel.is-entering .stat-panel-label { animation: stat-rise 0.6s var(--ease-out) 0.25s both; }
.stat-panel.is-entering .stat-panel-text > * { animation: stat-rise 0.7s var(--ease-out) both; }
.stat-panel.is-entering .stat-panel-text > :nth-child(1) { animation-delay: 0.3s; }
.stat-panel.is-entering .stat-panel-text > :nth-child(2) { animation-delay: 0.42s; }
.stat-panel.is-entering .compare-bar i { animation: stat-bar 1s var(--ease-out) 0.55s both; }
@keyframes stat-land {
  0% { opacity: 0; transform: scale(1.35) translateY(-8px); filter: blur(14px); }
  55% { opacity: 1; filter: blur(0); }
  100% { opacity: 1; transform: none; filter: none; }
}
@keyframes stat-glow {
  0% { opacity: 0; transform: translateY(-50%) scale(0.6); }
  30% { opacity: 1; transform: translateY(-50%) scale(1.05); }
  100% { opacity: 0.35; transform: translateY(-50%) scale(1); }
}
@keyframes stat-rise {
  0% { opacity: 0; transform: translateY(16px); filter: blur(6px); }
  100% { opacity: 1; transform: none; filter: none; }
}
@keyframes stat-bar { 0% { transform: scaleX(0); } 100% { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) {
  .stat-panel.is-entering *,
  .stat-panel.is-entering .stat-panel-figure::before { animation: none !important; }
}
@media (max-width: 820px) {
  .stat-panel { grid-template-columns: minmax(0, 1fr); gap: 16px; }
}
@media (max-width: 620px) {
  /* Phones: light, compact tabs so the one big number below leads. */
  .stat-tabs { flex-wrap: nowrap; gap: 6px; margin-top: 14px; }
  .stat-tab { flex: 1 1 0; min-width: 0; align-items: center; padding: 8px 6px; border-radius: 10px; text-align: center; }
  .stat-tab-number { font-size: 17px; }
  .stat-tab-name { font-size: 11px; letter-spacing: 0.02em; }
  /* The three-number slide is the tallest on phones: a little less top space (the nav is 84px). */
  .has-motion .slide:has(.stat-picker) { padding-top: 88px; }
  .stat-panel { margin-top: 14px; gap: 10px; }
  .stat-panel-number { font-size: clamp(64px, 21vw, 92px); }
  .stat-panel-label { margin-top: 6px; font-size: 15px; }
  .stat-panel-title { font-size: 19px; line-height: 1.35; }
  .stat-panel-desc { margin-top: 6px; font-size: 14px; line-height: 1.6; }
  /* No bar chart on phones: just the 4.9x line, as plain text under the title. */
  .stat-panel .compare { margin-top: 8px; padding: 0; border: 0; background: none; }
  .stat-panel .compare-row { display: none; }
  .stat-panel .compare-multiple { margin-top: 0; font-size: 14px; line-height: 1.7; }
  .stat-panel .compare-multiple strong { display: block; margin: 0 0 2px; font-size: 22px; }
}

.why-metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}

.why-metric {
  padding: clamp(28px, 3.5vw, 48px) clamp(16px, 2vw, 32px) clamp(28px, 3.5vw, 40px) 0;
  border-right: 1px solid var(--line);
}
.why-metric + .why-metric { padding-left: clamp(16px, 2.5vw, 40px); }
.why-metric:last-child { border-right: 0; }

.why-metric-number {
  font-family: var(--font-display);
  font-size: clamp(56px, 6.6vw, 104px);
  line-height: 0.95;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.why-metric-featured .why-metric-number {
  /* Room for the last glyph past the negative letter-spacing (see .stat-panel-number). */
  padding-right: 0.06em;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
}
.why-metric-label {
  margin-top: 14px;
  max-width: 24ch;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.6;
}

/* Vwake vs. a typical utility app, day 30. Bar width = value / 34.2%. */
.compare {
  display: grid;
  gap: 18px;
  margin-top: clamp(40px, 5vw, 64px);
  padding: clamp(24px, 3vw, 36px);
  border: 1px solid var(--line);
  border-radius: 6px;
  background: rgba(34, 26, 51, 0.45);
}
.compare-row {
  display: grid;
  grid-template-columns: minmax(120px, 180px) minmax(0, 1fr) 72px;
  align-items: center;
  gap: 20px;
}
.compare-name { font-size: 15px; color: var(--muted); }
.is-vwake .compare-name { color: var(--cream); font-weight: 600; }
.compare-bar {
  display: block;
  height: 14px;
  border-radius: 999px;
  background: rgba(180, 156, 230, 0.10);
  overflow: hidden;
}
.compare-bar i {
  display: block;
  height: 100%;
  width: calc(var(--value) * 100%);
  border-radius: inherit;
  transform-origin: left;
}
.is-vwake .compare-bar i { background: var(--signal); }
.is-baseline .compare-bar i { background: var(--faint); }
.compare-value { font-size: 17px; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.is-baseline .compare-value { color: var(--muted); font-weight: 500; }
.compare-multiple { margin-top: 6px; color: var(--muted); font-size: 15px; }
.compare-multiple strong {
  margin-right: 12px;
  font-size: clamp(22px, 2.2vw, 28px);
  font-weight: 700;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
}

.why-note {
  margin-top: 28px;
  max-width: 720px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.7;
  letter-spacing: 0.02em;
  color: var(--faint);
}

/* ---------- Morning Letters ---------- */

/* Headline across the full width on top, like every other slide; below it the
   description (left) and the banner (right). The header is dissolved
   (display: contents) so its label, headline and description join this grid. */
.letters-layout {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  grid-template-areas:
    "label label"
    "title title"
    "desc  banner";
  column-gap: clamp(32px, 5vw, 80px);
  row-gap: 22px;
  align-items: start;
}
.letters-layout > .section-header { display: contents; }
.letters-layout .label { grid-area: label; }
/* Same 880 px measure as every other slide's header (.section-header max-width). */
.letters-layout .section-title { grid-area: title; max-width: 880px; }
.letters-layout .section-desc { grid-area: desc; margin-top: clamp(16px, 2.5vw, 36px); }
.letters-layout .letters-banner { grid-area: banner; margin-top: clamp(16px, 2.5vw, 36px); }
.letters-banner {
  position: relative;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--line);
  box-shadow: 0 40px 100px -40px rgba(238, 107, 85, 0.45);
}
.letters-banner img { width: 100%; height: auto; }

/* ---------- Roster ---------- */

/* Between the stats and the marquee: fans ask for a VTuber who is not on Vwake
   yet. Not under the marquee: there it sat under the fixed corner buttons on
   shorter screens. */
.roster-request { margin-top: clamp(16px, 2.5vw, 28px); }
.roster-request a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 15px;
  font-weight: 500;
  color: var(--cream);
  transition: border-color 0.2s, background-color 0.2s;
}
.roster-request a:hover { border-color: var(--coral); background: rgba(238, 107, 85, 0.08); }
.roster-request svg { flex: none; transition: transform 0.2s var(--ease-out); }
.roster-request a:hover svg { transform: translateX(3px); }

.roster-head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 32px;
}

.roster-stats {
  display: flex;
  align-items: center;
  gap: 48px;
  margin: 4px 0 22px;
}
.rstat { display: grid; gap: 4px; }
.rstat-num {
  font-family: var(--font-display);
  font-size: clamp(44px, 5vw, 72px);
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.rstat-label {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.rstat-sep { width: 1px; height: 56px; background: var(--line-strong); }

/* Restyle the shared marquee cards for this theme without changing their size. */
.creator-marquee-card {
  border-color: var(--line) !important;
  border-radius: 999px !important;
  background: rgba(34, 26, 51, 0.72) !important;
  box-shadow: none !important;
  transition: border-color 0.2s, background-color 0.2s;
}
.creator-marquee-card:hover {
  border-color: var(--line-strong) !important;
  background: rgba(34, 26, 51, 1) !important;
}
.creator-marquee-card-name { color: var(--cream) !important; font-weight: 600 !important; }
.creator-marquee-card-label { font-family: var(--font-mono); color: var(--faint) !important; font-weight: 400 !important; }

/* ---------- Indie / Agency ---------- */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}

.split-col {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: clamp(28px, 4vw, 56px);
}

.split-indie {
  background:
    radial-gradient(120% 80% at 0% 0%, rgba(238, 107, 85, 0.16), transparent 60%),
    var(--plum-soft);
}
.split-agency {
  background: var(--ink-deep);
  border-left: 1px solid var(--line);
}

.split-title { font-size: clamp(30px, 3.4vw, 48px); }

.split-desc { color: var(--muted); max-width: 46ch; }

.indie-points {
  display: grid;
  gap: 14px;
  list-style: none;
}
.indie-points li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 10px;
  color: var(--cream);
}
.indie-points li::before {
  content: "";
  width: 8px;
  height: 8px;
  margin-top: 0.7em;
  border-radius: 50%;
  background: var(--signal);
}

.split-cta { margin-top: auto; padding-top: 8px; }

/* ---------- Partner plans table (zh /creators/) ----------
   Rows that differ have one cell per plan; rows that are the same for both
   span the two plan columns, so the differences stand out. */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.plans-wrap {
  border: 1px solid var(--line);
  border-radius: 6px;
  background: rgba(13, 10, 20, 0.55);
  overflow: hidden;
}
.plans {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: 15px;
  line-height: 1.6;
}
.plans th,
.plans td {
  padding: 10px clamp(16px, 2vw, 28px);
  text-align: left;
  vertical-align: top;
  border-top: 1px solid var(--line);
}
.plans thead th,
.plans thead td { border-top: 0; padding-top: 18px; padding-bottom: 12px; }
.plans thead td,
.plans tbody th { width: 22%; }
.plans tbody th { color: var(--muted); font-weight: 500; }
.plans td { color: var(--cream); }
/* The indie column carries the halo tint, as the old indie card did. */
.plans thead th:nth-of-type(1) {
  background: radial-gradient(140% 120% at 0% 0%, rgba(238, 107, 85, 0.18), transparent 70%);
}
.plans-kind { display: block; font-size: clamp(20px, 2vw, 26px); font-weight: 600; letter-spacing: -0.01em; }
.plans-sub { display: block; margin-top: 2px; font-size: 12px; letter-spacing: 0.14em; color: var(--muted); }
.plans tfoot td { padding-top: 16px; padding-bottom: 20px; }
/* The revenue share never splits across lines; its condition sits under it. */
.plans-rate { white-space: nowrap; }
.plans-note { display: block; margin-top: 2px; font-size: 13px; color: var(--muted); word-break: keep-all; overflow-wrap: anywhere; }
/* A list of short items (App 維護、金流…): Chinese and Japanese wrap only between
   items, never inside a word like サポート. */
.plans-items { word-break: keep-all; overflow-wrap: anywhere; }
/* A feature that has not launched yet (Vwake Studio). */
.soon-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border: 1px solid rgba(238, 107, 85, 0.5);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1.6;
  color: var(--coral);
  white-space: nowrap;
  vertical-align: 1px;
}
/* The table slide fits one 900 px desktop screen: tighter top and title. */
@media (min-width: 621px) {
  #agencies:has(.plans) { padding-top: 100px; }
  #agencies:has(.plans) .section-header { margin-bottom: 36px; }
  #agencies:has(.plans) .section-title { font-size: clamp(30px, 3.6vw, 52px); }
}

@media (max-width: 620px) {
  /* Phones: each row becomes a label line with the plan values under it. */
  .plans, .plans thead, .plans tbody, .plans tfoot { display: block; }
  .plans { font-size: 13px; line-height: 1.5; }
  .plans tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 12px;
    padding: 9px 14px;
    border-top: 1px solid var(--line);
  }
  .plans thead tr { border-top: 0; padding-top: 12px; padding-bottom: 8px; }
  .plans th, .plans td { display: block; width: auto; padding: 0; border: 0; }
  .plans thead td, .plans tbody th { width: auto; }
  .plans thead td:empty, .plans tfoot td:empty { display: none; }
  .plans thead th:nth-of-type(1) { background: none; }
  .plans tbody th { grid-column: 1 / -1; margin-bottom: 2px; font-size: 12px; }
  .plans-note { font-size: 12px; }
  .plans td[colspan] { grid-column: 1 / -1; }
  .plans-kind { font-size: 17px; }
  .plans-sub { font-size: 10px; }
  .plans tfoot tr { padding-top: 14px; padding-bottom: 14px; }
  /* Half-width buttons: long labels ("Partner with us as an agency") wrap to two lines. */
  .plans tfoot .btn { width: 100%; justify-content: center; padding: 8px 10px; font-size: 14px; white-space: normal; text-align: center; line-height: 1.25; }
  /* Room under the table so its buttons end above the fixed next-page button. */
  #agencies:has(.plans) { padding-bottom: 84px; }
}

/* ---------- How it works ---------- */

.steps-wrap { position: relative; }
.steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  list-style: none;
}
.steps::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 7px;
  height: 1px;
  background: var(--line);
}
.steps-progress {
  position: absolute;
  left: 0; top: 7px;
  height: 1px;
  width: 100%;
  background: var(--signal);
  transform-origin: left;
}
.step {
  position: relative;
  padding: 40px clamp(12px, 2vw, 32px) 0 0;
}
.step::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--ink);
  border: 1px solid var(--lavender);
}
.step-time {
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.1em;
  color: var(--orange);
  font-variant-numeric: tabular-nums;
}
.step-title {
  margin: 10px 0 12px;
  font-family: var(--font-display);
  font-size: clamp(24px, 2.2vw, 32px);
  line-height: 1.2;
}
html:lang(zh-TW) .step-title,
html:lang(ja) .step-title { font-weight: 700; font-size: clamp(20px, 1.8vw, 24px); }
.step-desc { color: var(--muted); font-size: 15px; line-height: 1.75; }

/* ---------- FAQ ---------- */

/* Headline across the full width on top, like every other slide; the questions below. */
.faq-layout { display: block; }
.faq-layout .section-header { margin-bottom: clamp(28px, 3.5vw, 48px); }
.faq-list { max-width: 880px; border-top: 1px solid var(--line); }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 72px;
  padding: 18px 0;
  font-size: 17px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after {
  content: "+";
  flex: none;
  font-family: var(--font-mono);
  font-size: 20px;
  color: var(--lavender);
  transition: transform 0.25s var(--ease-out);
}
.faq-item[open] .faq-q::after { transform: rotate(45deg); }
.faq-q:hover { color: var(--orange); }
.faq-a {
  padding: 0 48px 26px 0;
  color: var(--muted);
  line-height: 1.8;
}
.faq-a strong { color: var(--cream); font-weight: 600; }
.faq-a a { color: var(--lavender); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Final CTA ---------- */

.final {
  position: relative;
  overflow: hidden;
  padding: clamp(120px, 16vw, 220px) 0 clamp(96px, 12vw, 160px);
  isolation: isolate;
}
.final-inner { display: grid; justify-items: start; gap: 28px; }

/* ---------- Slides (motion only) ----------
   After the hero, every section fills the screen like a presentation slide.
   site.js pins each one while the next slides over it. */
.has-motion .slide {
  display: flex;
  align-items: center;
  min-height: 100vh;
  min-height: 100svh;
  /* Transparent: the night scene behind the page is every slide's background. */
  background: transparent;
}
.has-motion .slide > .container { width: 100%; }
/* While a slide waits to enter, its container is moved up over the previous one.
   Only its visible blocks take the mouse, so it never blocks what is underneath. */
.has-motion .slide > .container { pointer-events: none; }
.has-motion .slide > .container > * { pointer-events: auto; }
.final-clock {
  font-family: var(--font-display);
  font-size: clamp(56px, 8vw, 120px);
  line-height: 0.9;
  font-variant-numeric: tabular-nums;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  font-weight: 600;
}
.final-cta-title { font-size: clamp(36px, 5vw, 76px); max-width: 18ch; }
html:lang(zh-TW) .final-cta-title,
html:lang(ja) .final-cta-title { max-width: none; }
.final-cta-desc { max-width: 560px; color: var(--muted); font-size: 17px; }
.final-cta-buttons { display: flex; flex-wrap: wrap; gap: 16px 24px; align-items: center; }

/* ---------- Footer ---------- */

.footer {
  padding: 40px 0 48px;
  /* The same black as the land silhouettes: the footer is the ground under the horizon. */
  background: #050308;
  font-size: 13px;
  color: var(--faint);
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 32px;
}
.footer-brand { display: flex; align-items: center; gap: 14px; }
.footer-brand .wordmark { font-size: 24px; }
.footer-legal { display: flex; flex-wrap: wrap; gap: 4px 20px; }
.footer-legal a { display: inline-flex; align-items: center; min-height: 32px; color: var(--muted); }
.footer-legal a:hover { color: var(--cream); }

/* ---------- Responsive ---------- */

/* Laptops: tighter nav spacing so five links, the switch, language and login fit. */
@media (max-width: 1280px) {
  .nav-inner { gap: 20px; }
  .nav-links { gap: 0; }
  .nav-links a { padding: 0 10px; font-size: 13px; }
  .nav-right { gap: 10px; margin-left: 12px; }
}
@media (max-width: 1080px) {
  .nav-links { display: none; }
  .nav-right { margin-left: auto; }
  /* Morning Letters: one column (label, headline, description, banner). */
  .letters-layout {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "label" "title" "desc" "banner";
  }
  .letters-layout .section-desc { margin-top: 0; }
  .split { grid-template-columns: 1fr; }
  .split-agency { border-left: 0; border-top: 1px solid var(--line); }
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 48px; }
  .steps::before, .steps-progress { display: none; }
}

@media (max-width: 820px) {
  /* Phones: the copy and the eclipse sit together in the middle of the space
     above the avatar row, instead of the copy at the top and the eclipse at the
     bottom with an empty band between them. */
  .hero-grid {
    grid-template-columns: 1fr;
    align-content: center;
    gap: 0;
    padding-top: 16px;
  }
  /* Phones: a small eclipse under the copy. It used to take about half the
     screen and push the avatar row below the fold; now the copy, the eclipse
     and the avatars all fit on the first screen. */
  .hero-eclipse {
    justify-self: center;
    align-self: center;
    width: min(34vw, 15svh, 150px);
    margin: clamp(10px, 2svh, 20px) 0 clamp(8px, 1.5svh, 14px);
  }
  .hero-ctas { gap: 12px 20px; }
  .hero-ctas .btn-ghost { padding-left: 0; padding-right: 0; }
  /* Keep the avatar row clear of the phone's bottom toolbar. */
  .hero-avatars { margin-bottom: env(safe-area-inset-bottom, 0px); }
  .why-metrics { grid-template-columns: 1fr; }
  .why-metric, .why-metric + .why-metric {
    padding: 28px 0;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
}

@media (max-width: 620px) {
  /* Phones: one row. The language switch folds into one 「中 ▾」 button (lang-menu.js
     opens the other languages under it; without it all three stay) and 創作者登入 becomes a person icon,
     so wordmark, fans / creators switch, language and login all fit. */
  .nav-inner { gap: 10px; }
  .nav-right { gap: 8px; }
  .audience-switch { font-size: 12px; }
  .audience-switch a { padding: 0 9px; }
  .nav-login { width: 34px; height: 34px; padding: 0; justify-content: center; }
  .nav-login-long { display: none; }
  .nav-login-icon { display: block; }
  .audience-switch .tab-long { display: none; }
  .audience-switch .tab-short { display: inline; }

  .lang-switch a { min-width: 30px; padding: 0 6px; }
  .hero-avatars { height: 104px; }
  /* FAQ: every question fits one phone screen, clear of the fixed buttons at the bottom. */
  .faq-q { min-height: 52px; padding: 12px 0; font-size: 15px; gap: 16px; }
  #faq { padding-bottom: 84px; }
  /* The two stats stay on one line each instead of breaking mid-phrase. */
  .hero-stats { font-size: 13px; letter-spacing: 0.02em; }
  .hero-stats .dot { margin: 0 6px; }
  .hero-avatars-row { justify-content: flex-start; }
  .hero-avatars-row img { width: 84px; }
  .hero-avatar { flex: none; }
  .steps { grid-template-columns: 1fr; }
  .faq-a { padding-right: 0; }
  .btn { min-height: 50px; padding: 0 22px; }
}

/* The smallest phones (320–380px): a smaller wordmark and tighter gaps keep the nav on one line. */
@media (max-width: 380px) {
  .nav-inner { gap: 6px; }
  .nav-right { gap: 6px; }
  .nav .wordmark { font-size: 22px; }
  .audience-switch a { padding: 0 7px; }
}
@media (max-width: 340px) {
  .nav-inner, .nav-right { gap: 4px; }
  .audience-switch { font-size: 11px; }
  .audience-switch a { padding: 0 6px; }
  .lang-switch a { padding: 0 4px; }
}

@media (max-width: 540px) {
  /* Phones: the two numbers share the width; long labels wrap instead of overflowing. */
  .roster-stats {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1fr);
    gap: 18px;
    max-width: 100%;
  }
  .rstat { min-width: 0; }
  .rstat-num { font-size: min(10.5vw, 44px); }
  .rstat-label { white-space: normal; overflow-wrap: anywhere; letter-spacing: 0.06em; }
}
@media (max-width: 540px) {
  .compare-row { grid-template-columns: 1fr auto; gap: 8px 12px; }
  .compare-bar { grid-column: 1 / -1; grid-row: 2; }
}

@media (max-width: 380px) {
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Cursor dot (assets/glow.js): replaces the system cursor on mouse devices with
   a small glowing point exactly at the pointer. No halo around it. */
html.has-halo-cursor,
html.has-halo-cursor * { cursor: none !important; }

.cursor-halo {
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.cursor-halo.is-active { opacity: 1; }
/* The dot: a small glowing moon, exactly under the mouse. */
.halo-dot {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 50%;
  will-change: transform;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  background: radial-gradient(circle, #FFF4EC 0%, #FFC6A8 45%, rgba(238, 107, 85, 0.9) 100%);
  box-shadow: 0 0 10px 2px rgba(255, 150, 120, 0.7), 0 0 24px 6px rgba(196, 120, 220, 0.35);
  transition: width 0.25s var(--ease-out), height 0.25s var(--ease-out), margin 0.25s var(--ease-out), opacity 0.2s, box-shadow 0.3s ease;
}
/* Over something clickable the dot grows; over the elephant calf (the story
   easter egg) a little more. */
.cursor-halo.is-hovering .halo-dot { width: 16px; height: 16px; margin: -8px 0 0 -8px; }
/* Over the calf: the same size as any hover, plus a small soft glow around it. */
.cursor-halo.is-on-calf .halo-dot {
  width: 16px;
  height: 16px;
  margin: -8px 0 0 -8px;
  box-shadow:
    0 0 10px 2px rgba(255, 150, 120, 0.7),
    0 0 18px 8px rgba(255, 176, 140, 0.35),
    0 0 30px 14px rgba(196, 120, 220, 0.22);
}
.cursor-halo.is-pressed .halo-dot { width: 6px; height: 6px; margin: -3px 0 0 -3px; }

/* ---------- Scene: one night over the savanna ----------
   Fixed behind every slide. site.js drives it with scroll:
   --dawn goes 0 → 1 (warmer sky, brighter horizon, lit silhouettes),
   the moon crosses the sky from left to right, and the land pans.
   Without motion it is a still night with no moon (the hero has the eclipse). */
main, .footer { position: relative; z-index: 1; }

.scene {
  --dawn: 0.15;
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.scene-sky {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, #0D0915 0%, #15101F 42%, #23183A 74%, #3A2348 100%);
}

.scene-stars {
  position: absolute;
  inset: 0 0 30% 0;
  opacity: calc(0.75 - var(--dawn) * 0.75);
  background-image:
    radial-gradient(1px 1px at 22px 34px, rgba(245, 242, 238, 0.9), transparent),
    radial-gradient(1px 1px at 140px 90px, rgba(245, 242, 238, 0.7), transparent),
    radial-gradient(1.5px 1.5px at 260px 40px, rgba(245, 242, 238, 0.8), transparent),
    radial-gradient(1px 1px at 330px 150px, rgba(180, 156, 230, 0.8), transparent),
    radial-gradient(1px 1px at 90px 210px, rgba(245, 242, 238, 0.6), transparent),
    radial-gradient(1.2px 1.2px at 210px 260px, rgba(245, 242, 238, 0.7), transparent),
    radial-gradient(1px 1px at 380px 300px, rgba(245, 242, 238, 0.5), transparent);
  background-size: 420px 340px;
}

.scene-dawn {
  position: absolute;
  inset: 0;
  opacity: var(--dawn);
  background:
    radial-gradient(70% 55% at 78% 100%, rgba(255, 159, 90, 0.55), transparent 70%),
    linear-gradient(to bottom, transparent 30%, rgba(238, 107, 85, 0.22) 75%, rgba(255, 159, 90, 0.35) 100%);
}

.scene-horizon {
  position: absolute;
  left: -10%;
  right: -10%;
  bottom: 12vh;
  height: 40vh;
  opacity: calc(0.45 + var(--dawn) * 0.55);
  background:
    radial-gradient(50% 55% at 50% 100%, rgba(255, 159, 90, 0.40), transparent 70%),
    radial-gradient(70% 70% at 50% 100%, rgba(238, 107, 85, 0.36), transparent 72%),
    radial-gradient(95% 85% at 50% 100%, rgba(176, 92, 200, 0.28), transparent 78%);
  filter: blur(10px);
}

/* The moon is the hero eclipse, small. Its children reuse the eclipse layers. */
.scene-moon {
  position: absolute;
  left: 6vw;
  top: 46vh;
  width: clamp(54px, 7.5vmin, 90px);
  aspect-ratio: 1;
  display: none;
}
.has-motion .scene-moon { display: block; }
.scene-moon .eclipse-bloom { inset: -45%; }

.scene-land {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* Scales with the screen width only, so the silhouettes keep the same proportions
     at every resolution: the strip is 480vw wide and its viewBox is 4800 x 240. */
  height: 24vw;
}
.land-far, .land-near {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 480vw;
  height: 100%;
}
.land-far svg, .land-near svg { display: block; width: 100%; height: 100%; }
.land-far path { fill: #1B1328; }
.land-shape { fill: #050308; }
/* The ground continues past the right end of the panned strip at the same height
   (the strip's ground ends 38 of 240 units above its bottom), so no notch shows. */
.land-near::after {
  content: "";
  position: absolute;
  left: calc(100% - 6px);
  bottom: 0;
  width: 40vw;
  height: calc(39.6 / 240 * 100%);
  background: #050308;
}

/* "Next slide" button (site.js shows it only when the slide motion is on). */
.next-slide {
  position: fixed;
  right: clamp(16px, 3vw, 32px);
  bottom: clamp(16px, 3vw, 32px);
  z-index: 60;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: rgba(21, 16, 31, 0.7);
  color: var(--cream);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  transition: border-color 0.2s, background-color 0.2s, opacity 0.3s, transform 0.3s var(--ease-out);
}
.next-slide[hidden] { display: none; }
.next-slide:hover { border-color: var(--coral); background: rgba(34, 26, 51, 0.9); }
.next-slide svg { animation: next-nudge 2.4s ease-in-out infinite; }
.next-slide.is-done { opacity: 0; transform: translateY(12px); pointer-events: none; }
/* Fan page: the always-on 創作者合作 button, bottom-left, level with the next-page button. */
.creator-cta {
  position: fixed;
  left: clamp(16px, 3vw, 32px);
  bottom: clamp(16px, 3vw, 32px);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 52px;
  padding: 0 22px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: rgba(21, 16, 31, 0.7);
  color: var(--cream);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  transition: border-color 0.2s, background-color 0.2s, bottom 0.5s var(--ease-out);
}
.creator-cta:hover { border-color: var(--coral); background: rgba(34, 26, 51, 0.9); }
/* Creator page, on the hero: hidden (site.js), since the hero has its own 立即註冊.
   visibility keeps it out of the tab order and away from screen readers too. */
.creator-cta.is-tucked {
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  pointer-events: none;
}
.creator-cta { transition: border-color 0.2s, background-color 0.2s, bottom 0.5s var(--ease-out), opacity 0.3s, transform 0.3s var(--ease-out), visibility 0.3s; }
/* Creator page: the same always-on button is the sign-up, in the primary gradient. */
.creator-cta.is-signup,
.creator-cta.is-signup:hover {
  border-color: transparent;
  background: linear-gradient(100deg, #FF8A5C 0%, #EE6B55 40%, #D9506E 75%, #B05CC8 130%);
  color: #FFF8F3;
  font-weight: 600;
  box-shadow: 0 10px 40px -12px rgba(238, 107, 85, 0.7);
}
.creator-cta.is-signup:hover { box-shadow: 0 16px 48px -12px rgba(238, 107, 85, 0.85); }
/* At the top of the page: above the hero avatar row (same height as .hero-avatars). */
.creator-cta.is-above-avatars { bottom: calc(clamp(96px, 11vw, 150px) + 16px); }
@media (max-width: 620px) {
  .creator-cta { height: 44px; padding: 0 16px; font-size: 13px; }
  .creator-cta.is-above-avatars { bottom: calc(104px + 12px + env(safe-area-inset-bottom, 0px)); }
}

/* Official App Store / Google Play badges. The Google PNG carries transparent
   padding (artwork is 184 of its 250 px height), so it is drawn taller and pulled
   in with negative margins until both badges look the same height. */
.store-badges { --badge-h: 48px; display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.store-badge { display: inline-block; border-radius: 8px; line-height: 0; }
.store-badge img { display: block; width: auto; height: var(--badge-h); }
.store-badge--google img {
  height: calc(var(--badge-h) * 250 / 184);
  margin: calc(var(--badge-h) * -33 / 184) calc(var(--badge-h) * -4 / 184);
}
@media (max-width: 620px) {
  .store-badges { --badge-h: 44px; gap: 12px; }
}

@keyframes next-nudge {
  0%, 60%, 100% { transform: translateY(0); }
  30% { transform: translateY(3px); }
}

/* ---------- The walker: a lost elephant calf and the bird that sings to it ----------
   --u is one strip unit in px (set by site.js from the land's real scale), so the
   calf and bird match the silhouettes. Hidden without motion (the land is still). */
.scene-land { --u: 0.1vw; }  /* fallback; site.js sets the measured value */
/* Calf and bird size in strip units. On phones the strip is tiny, so they are drawn
   a little larger than the silhouettes to stay visible. */
.scene-walker { --calf: 0.32; --bird: 0.7; }
@media (max-width: 620px) {
  .scene-walker { --calf: 0.56; --bird: 1.1; }
  /* No easter egg on phones: the caption does not fit under the hills there.
     The calf and bird still walk. */
  .story-toggle,
  .story-line { display: none !important; }
}
.scene-walker {
  position: absolute;
  left: 28vw;
  bottom: calc(39 * var(--u));
  display: none;
}
.has-motion .scene-walker { display: block; }

.walker-calf {
  position: absolute;
  left: calc(-36 * var(--calf) * var(--u));
  bottom: 0;
  width: calc(90 * var(--calf) * var(--u));
  height: calc(57 * var(--calf) * var(--u));
  overflow: visible;
  fill: #050308;
}
.scene-walker.is-back .walker-calf { transform: scaleX(-1); }
.walker-calf .leg {
  transform-box: fill-box;
  transform-origin: 50% 0;
}
.scene-walker.is-walking .leg-a { animation: calf-step 0.46s ease-in-out infinite alternate; }
.scene-walker.is-walking .leg-b { animation: calf-step 0.46s ease-in-out infinite alternate-reverse; }
.scene-walker.is-walking .calf-body { animation: calf-bob 0.23s ease-in-out infinite alternate; }
@keyframes calf-step {
  from { transform: rotate(-15deg); }
  to { transform: rotate(15deg); }
}
@keyframes calf-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-1.2px); }
}

/* The bird flutters above and a little ahead of the calf. */
.walker-bird {
  position: absolute;

  left: calc(6 * var(--u));
  bottom: calc(24 * var(--u));
  width: calc(20 * var(--bird) * var(--u));
  height: calc(12 * var(--bird) * var(--u));
  overflow: visible;
  fill: #050308;
  opacity: 0;
  animation: bird-hover 2.6s ease-in-out infinite;
}
.walker-bird .wing-up { animation: bird-flap 0.32s steps(1) infinite; }
.walker-bird .wing-down { animation: bird-flap 0.32s steps(1) infinite reverse; }
@keyframes bird-flap {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@keyframes bird-hover {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -5px; }
}

/* ---------- Easter egg: the story under the hills ----------
   .story-toggle is an invisible button that site.js keeps on top of the calf,
   above the slides, so the calf can be clicked. The caption sits on the dark
   ground below the hills and fades between chapters. */
.story-toggle {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 46;
  width: 0;
  height: 0;
  padding: 0;
  border-radius: 40%;
  background: transparent;
  cursor: pointer;
}
.story-toggle[hidden] { display: none; }
.story-toggle:focus-visible { outline: 1px solid rgba(245, 242, 238, 0.5); outline-offset: 4px; }

.story-line {
  position: absolute;
  left: 50%;
  bottom: max(calc(14 * var(--u)), 18px);
  z-index: 1;
  width: max-content;
  max-width: min(90vw, 760px);
  margin: 0;
  transform: translate(-50%, 50%);
  text-align: center;
  font-size: clamp(11px, 0.95vw, 14px);
  line-height: 1.5;
  letter-spacing: 0.08em;
  color: rgba(245, 242, 238, 0.72);
  opacity: 0;
  transition: opacity 0.6s ease;
  pointer-events: none;
}
.story-line.is-shown { opacity: 1; }
.story-line.is-changing { opacity: 0; transition-duration: 0.25s; }
.story-chapter {
  margin-right: 0.9em;
  color: transparent;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  font-weight: 600;
}

/* Touch paging (site.js): the page moves one page per swipe instead of scrolling.
   Pinch-zoom stays; the carousel keeps its sideways swipe. */
/* Safari does not know "pinch-zoom" and drops the whole value, which let it start a
   native scroll at the beginning of every swipe. The plain value comes first as its
   fallback; browsers that know pinch-zoom use the second line. */
html.is-paged { touch-action: none; touch-action: pinch-zoom; }
.is-paged .preview-strip { touch-action: pan-x; touch-action: pan-x pinch-zoom; }

/* ---------- Phones: partner plans and the 4 steps swipe sideways ----------
   One card per view with the next one peeking in, snapped with native
   horizontal scrolling. site.js adds the dots under each row. */
@media (max-width: 620px) {
  .split,
  .steps {
    display: flex;
    gap: 12px;
    margin: 0 calc(-1 * var(--gutter));
    padding: 0 var(--gutter) 4px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding: 0 var(--gutter);
    scrollbar-width: none;
    border: 0;
    border-radius: 0;
  }
  .split::-webkit-scrollbar,
  .steps::-webkit-scrollbar { display: none; }

  .split-col {
    flex: 0 0 86%;
    scroll-snap-align: start;
    gap: 16px;
    padding: 24px 22px;
    border: 1px solid var(--line);
    border-radius: 6px;
  }
  .split-agency { border-top: 1px solid var(--line); }
  .split-title { font-size: 26px; }
  .indie-points { gap: 10px; }
  .indie-points li { font-size: 15px; line-height: 1.6; }

  .steps { row-gap: 0; }
  .step {
    flex: 0 0 80%;
    scroll-snap-align: start;
    padding: 24px 22px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: rgba(34, 26, 51, 0.55);
  }
  .step::before { display: none; }

  .swipe-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 14px;
  }
  .swipe-dots span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--line-strong);
    transition: background-color 0.2s, width 0.2s;
  }
  .swipe-dots span.is-on { width: 18px; border-radius: 3px; background: var(--coral); }
  .is-paged .split,
  .is-paged .steps { touch-action: pan-x; touch-action: pan-x pinch-zoom; }
}
@media (max-width: 620px) {
  /* The partner page fits one phone screen: tighter title, spacing and bullets. */
  #agencies { padding-top: 100px; padding-bottom: 16px; }
  #agencies .section-header { gap: 12px; margin-bottom: 20px; }
  #agencies .section-title { font-size: 28px; }
  #agencies .split-col { gap: 12px; padding: 20px 20px 22px; }
  #agencies .split-title { font-size: 22px; }
  #agencies .indie-points { gap: 6px; }
  #agencies .indie-points li { font-size: 14px; line-height: 1.55; }
  #agencies .split-cta { padding-top: 4px; }
  #agencies .btn { min-height: 44px; }

  #how { padding-top: 100px; padding-bottom: 16px; }
  #how .section-header { gap: 12px; margin-bottom: 20px; }
  #how .section-title { font-size: 28px; }
  #how .section-desc { font-size: 15px; }
  #how .step { padding: 20px 20px 22px; }
  #how .step-title { margin: 8px 0 8px; }
  #how .step-desc { font-size: 14px; line-height: 1.6; }
}
@media (max-width: 620px) and (max-height: 700px) {
  /* Small phones (iPhone SE): a little tighter still. */
  #agencies .section-title,
  #how .section-title { font-size: 24px; }
  #agencies .section-desc,
  #how .section-desc { display: none; }
  #agencies .indie-points li { font-size: 13px; }
  /* The hero fits the first screen: smaller headline and copy, tighter gaps. */
  .hero-grid { padding-top: 16px; }
  .hero-tagline { font-size: 34px; }
  html:lang(en) .hero-tagline { font-size: 30px; }
  .hero-desc { margin-top: 12px; font-size: 14px; line-height: 1.6; }
  .hero-ctas { margin-top: 16px; }
  .hero-stats { margin-top: 14px; }
  .hero-eclipse { width: min(26vw, 12svh, 96px); margin: 8px 0 6px; }
}
@media (min-width: 621px) {
  .swipe-dots { display: none; }
}

/* Phones: the fixed nav is 84 px tall. Every slide keeps its content below it,
   even when Safari's toolbars leave a short screen and content would centre upward. */
/* The fixed nav is 84 px tall at every width: keep slide content below it on
   tablets too (at ~830-950 px the section spacing alone was smaller than the nav). */
.has-motion .slide,
.has-motion #preview { padding-top: max(var(--section-space), 100px); }
@media (max-width: 820px) {
  /* "safe": when the content is taller than the space, it starts below the padding
     instead of centring upward under the nav. */
  .has-motion .slide { align-items: flex-start; align-items: safe center; }
}

/* One headline line for every slide. Each slide's content starts at the same
   height (--slide-top), so the label and headline stay in place from slide to
   slide on phones and desktops alike, instead of moving with how much content
   the slide has. The hero (not a .slide) and the final dawn slide (.final) keep
   their own centred layout. !important: this one value replaces the per-slide
   top paddings set above (#preview, #agencies, #how, the stat picker). */
:root { --slide-top: clamp(128px, 17vh, 168px); }
@media (max-width: 620px) {
  :root { --slide-top: 108px; }
  /* Same label-to-headline gap on every phone slide (the partner and steps
     slides already used 12px to fit the screen). */
  .section-header { gap: 12px; }
  .letters-layout { row-gap: 12px; }
}
@media (max-width: 620px) {
  .has-motion .slide:not(.final) {
    align-items: flex-start;
    padding-top: var(--slide-top) !important;
  }
}
/* Desktops and tablets: each slide's content sits in the middle of the space
   under the nav. Spacing follows the screen's height, not its width, so a wide
   but short laptop screen (a MacBook) still fits the slide in one screen; a
   slide taller than the screen pins at its bottom and its title would go under
   the nav. "safe": content that is still too tall starts below the nav instead
   of centring upward under it. !important: replaces the per-slide paddings. */
@media (min-width: 621px) {
  .has-motion .slide {
    align-items: center;
    align-items: safe center;
    padding-top: 100px !important;
    padding-bottom: clamp(24px, 5vh, 64px) !important;
  }
}
/* Short laptop screens (MacBooks, a browser with toolbars): the gaps and the big
   numbers also follow the screen's height, so each slide still fits one screen.
   Taller screens keep the sizes above. */
@media (min-width: 621px) and (max-height: 900px) {
  .section-header { gap: clamp(10px, 2vh, 22px); margin-bottom: clamp(20px, 4vh, 80px); }
  .section-title { font-size: min(clamp(34px, 4.6vw, 64px), 7vh); }
  .stat-tabs { margin-top: clamp(8px, 2vh, 32px); }
  .stat-panel { margin-top: clamp(12px, 2.5vh, 40px); }
  .stat-panel-number { font-size: min(clamp(88px, 13vw, 200px), 33cqi, 15vh); }
  .compare { gap: clamp(8px, 1.6vh, 18px); margin-top: clamp(14px, 3vh, 64px); padding: clamp(14px, 2.4vh, 36px); }
  .roster-head { row-gap: clamp(8px, 2vh, 32px); }
  .roster-stats { margin: 0 0 clamp(8px, 2vh, 22px); }
  .rstat-num { font-size: min(clamp(44px, 5vw, 72px), 8vh); }
}
/* Very short screens (a 13" laptop with the dock and toolbars): tighter rows. */
@media (min-width: 621px) and (max-height: 720px) {
  .plans th, .plans td { padding-top: 6px; padding-bottom: 6px; }
  .plans thead th, .plans thead td { padding-top: 12px; padding-bottom: 8px; }
  .plans tfoot td { padding-top: 10px; padding-bottom: 12px; }
  .faq-q { min-height: 56px; padding: 12px 0; }
  .stat-panel-label { margin-top: 6px; }
  .stat-panel-number { font-size: min(clamp(88px, 13vw, 200px), 33cqi, 13vh); }
  .section-title { font-size: min(clamp(34px, 4.6vw, 64px), 6.5vh); }
  .has-motion .slide { padding-top: 92px !important; padding-bottom: 12px !important; }
}

/* The story caption shows only the line, without its chapter number. */
.story-chapter { display: none; }

/* Portrait tablets (iPad and similar): stack the hero like a phone, with a larger
   eclipse under the copy, instead of a side-by-side row lost in a tall screen. */
@media (min-width: 821px) and (orientation: portrait) {
  .hero-grid {
    grid-template-columns: 1fr;
    align-content: space-evenly;
    gap: clamp(32px, 4vh, 64px);
  }
  .hero-copy { max-width: 760px; }
  .hero-eclipse {
    justify-self: center;
    width: min(58vw, 34vh, 600px);
    margin: 0;
  }
}

/* ---------- Chapter rail (built by site.js) ---------- */
.chapter-rail {
  position: fixed;
  top: 50%;
  right: clamp(6px, 1.4vw, 24px);
  z-index: 55;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  transform: translateY(-50%);
}
.chapter-rail-item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  /* Lines 12 px apart: one tight column instead of scattered dashes. */
  height: 12px;
  padding: 0 4px;
}
.chapter-rail-line {
  display: block;
  width: 14px;
  height: 2px;
  border-radius: 2px;
  background: var(--line-strong);
  transition: width 0.3s var(--ease-out), background-color 0.3s;
}
.chapter-rail-item:hover .chapter-rail-line { width: 22px; background: var(--muted); }
.chapter-rail-item.is-current .chapter-rail-line { width: 28px; background: var(--signal); }
/* Out of the flow: the button is only as wide as its line, so the hidden name never covers the page. */
.chapter-rail-name {
  position: absolute;
  right: calc(100% + 8px);
  font-size: 12px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: var(--cream);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.7);
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition: opacity 0.2s, transform 0.2s;
}
.chapter-rail-item:hover .chapter-rail-name,
.chapter-rail-item:focus-visible .chapter-rail-name { opacity: 1; transform: none; }
.chapter-rail-item:focus-visible { outline: 2px solid var(--lavender); outline-offset: 2px; border-radius: 4px; }
/* Until the side margins are wide enough to hold it, keep slide content clear of the rail. */
@media (max-width: 1440px) {
  .has-chapter-rail main .container { padding-right: calc(var(--gutter) + 36px); }
}
/* Touch screens and phones: no rail. Pages turn by swipe, the nav is at the top,
   and 44 px tap targets would spread the lines far apart and over the content.
   The content gets its full width back. */
@media (pointer: coarse), (max-width: 620px) {
  .chapter-rail { display: none; }
  .has-chapter-rail main .container { padding-right: var(--gutter); }
}
