/*
  Color tokens extracted from the app's own source (styles.ts) — not
  invented for the web: lightTheme / darkTheme -> background, surface,
  border, textSecondary, primary, textPrimary, success, stepIconBackground.
  --die (the app's colorFeminine red) is kept as the site's link/focus
  accent color.

  Typography, corner-radius scale, shadow softness, and the fixed frosted
  nav are instead modeled on the sibling marketing site,
  doudou-chinese.com/main.css, for visual consistency across the two apps'
  sites: Outfit for headings / Work Sans for body text, 8-20px radius
  scale, soft large-blur card shadows, hover-lift buttons, underline-on-
  hover nav links, a fixed translucent/blurred nav bar. (Its CSS
  references "Outfit" and "Sans" that were never actually linked, so the
  live site silently falls back to the browser's default sans-serif for
  those — a bug on their end. Implemented here as it was clearly
  intended, with both fonts correctly loaded.)
*/

:root {
  --bg: #FFFFFF;
  --bg-alt: #F0F1EC;
  --surface: #FFFFFF;
  --border: #E8ECEF;
  --ink: #1A2A44;
  --ink-soft: #4B5563;
  --on-ink: #F7FAFC;
  --chip-bg: #EEF1F5;
  --success: #22C55E;

  /* Gender colors from the app's genderBtn fills (App.tsx) — colorMasculine
     #000000, colorFeminine #DC0000, colorNeutral #FECE00. There they're
     always a solid fill behind white text, so they never have to work as
     foreground text color; used that way for the DER/DIE/DAS headline,
     --der (pure black) is invisible on the dark theme's background, so it
     gets a per-theme adjustment below — --die (red) and --das (yellow)
     are used unadjusted in both themes. */
  --der: #000000;
  --die: #DC0000;
  --das: #FECE00;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  --shadow-card: 0 4px 12px rgba(0, 0, 0, 0.08);
  --shadow-card-hover: 0 20px 40px rgba(0, 0, 0, 0.1);

  --font-heading: "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Work Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --nav-height: 60px;
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* One section per screen: each snap target below is sized to the
     device's viewport (100dvh, so mobile browser chrome showing/hiding
     doesn't leave a gap) and snaps to rest there. `proximity` (rather than
     `mandatory`) so a fast fling can sail past a section instead of being
     yanked to a hard stop at every one — softer, less sticky feel. The two
     hero-wrapper sections are also given their own scroll-snap-align (see
     hero-animation.css) so a flick released inside one lands at its own
     start instead of being yanked past it to an unrelated section.
     scroll-padding-top offsets every snap point by the fixed nav's height
     so sections don't settle partially hidden under it. */
  scroll-snap-type: y proximity;
  scroll-padding-top: var(--nav-height);
}

@media (max-width: 899.98px) {
  /* Mobile gets plain free scrolling instead — no snap, and scroll-
     lock.js (which pauses scrolling right after landing on a snap point)
     disables itself to match, matching the same width threshold used for
     the hero-animation desktop/mobile split. */
  html { scroll-snap-type: none; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--ink); }
a:focus-visible, summary:focus-visible, button:focus-visible {
  outline: 2px solid var(--die);
  outline-offset: 3px;
}

h1, h2, h3 {
  font-family: var(--font-heading);
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0;
}

p { margin: 0 0 12px; }

/* ---------- layout shell ---------- */
footer {
  max-width: 760px;
  margin: 0 auto;
  padding-left: 20px;
  padding-right: 20px;
}

/* header and every section are full-width now (each carries its own
   real background-color — see the alternating-backgrounds block below),
   with the actual content capped/centered by this inner wrapper instead
   of the section/header element itself. */
.container {
  max-width: 760px;
  margin: 0 auto;
  padding-left: 20px;
  padding-right: 20px;
}

/* Scroll-reveal for the plain text slides (see reveal.js): each direct
   child of .container (except the mascot icon, which gets its own
   punchier keyframe entrance below) fades/rises/grows in with a slight
   stagger the first time the slide crosses ~25% into view, then stays
   put — reveal.js unobserves after the first trigger, so scrolling back
   past a slide doesn't re-hide or re-animate it. Hero-wrapper scenes are
   excluded — they already have their own scroll-driven animation. */
main section:not(.hero-wrapper) > .container > :not(.mascot-circle) {
  opacity: 0;
  transform: translateY(36px) scale(0.97);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
main section:not(.hero-wrapper) > .container.is-visible > :not(.mascot-circle) {
  opacity: 1;
  transform: translateY(0) scale(1);
}
main section:not(.hero-wrapper) > .container > :nth-child(1) { transition-delay: 0s; }
main section:not(.hero-wrapper) > .container > :nth-child(2) { transition-delay: 0.08s; }
main section:not(.hero-wrapper) > .container > :nth-child(3) { transition-delay: 0.16s; }
main section:not(.hero-wrapper) > .container > :nth-child(4) { transition-delay: 0.24s; }
main section:not(.hero-wrapper) > .container > :nth-child(5) { transition-delay: 0.32s; }

/* ---------- mascot icon entrance effects ----------
   Each text-slide mascot gets one of these instead of the plain fade
   above, assigned per section in the markup (fx-roll-left, fx-bounce,
   fx-pulse, fx-spin) purely for visual variety. Scoped to slide mascots
   only — the header's own mascot is unaffected since it's outside
   main/isn't targeted by reveal.js. */
main section:not(.hero-wrapper) > .container .mascot-circle {
  opacity: 0;
}
.container.is-visible .mascot-circle.fx-roll-left {
  animation: fx-roll-left 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.3s forwards;
  animation-fill-mode: both;
}
.container.is-visible .mascot-circle.fx-roll-right {
  animation: fx-roll-right 0.7s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.container.is-visible .mascot-circle.fx-bounce {
  animation: fx-bounce 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.container.is-visible .mascot-circle.fx-pulse {
  animation: fx-pulse 0.7s ease-out forwards;
}
.container.is-visible .mascot-circle.fx-spin {
  animation: fx-spin 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
@keyframes fx-roll-left {
  from { opacity: 0; transform: translateX(-200px) rotate(-260deg); }
  to   { opacity: 1; transform: translateX(0) rotate(0deg); }
}
@keyframes fx-roll-right {
  from { opacity: 0; transform: translateX(200px) rotate(260deg); }
  to   { opacity: 1; transform: translateX(0) rotate(0deg); }
}
@keyframes fx-bounce {
  0%   { opacity: 0; transform: translateY(-120px) scale(0.7); }
  55%  { opacity: 1; transform: translateY(18px) scale(1.05); }
  75%  { opacity: 1; transform: translateY(-8px) scale(0.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes fx-pulse {
  0%   { opacity: 0; transform: scale(0.4); }
  60%  { opacity: 1; transform: scale(1.25); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes fx-spin {
  0%   { opacity: 0; transform: rotate(0deg) scale(0.5); }
  60%  { opacity: 1; transform: rotate(370deg) scale(1.05); }
  100% { opacity: 1; transform: rotate(360deg) scale(1); }
}

/* ---------- header / hero ---------- */
header {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
  scroll-snap-stop: always;
  padding-top: calc(var(--nav-height) + 32px);
  padding-bottom: 28px;
  border-bottom: 1px solid var(--border);
  text-align: center;
}
header .container { width: 100%; }

/* Circular tinted badge holding the mascot, matching the app's CircleIcon
   component (size 76 / stepIconBackground fill / image at ~86% of the
   circle) — scaled up for a hero placement. Background alternates
   opposite of whatever the containing slide's own background is, so the
   circle always pops against it: white by default (header, What is,
   Let's Stay Connected all sit on F0F1EC slides), overridden to F0F1EC
   on the two white slides that have a mascot (How it works, Download). */
.mascot-circle {
  width: 140px;
  height: 140px;
  margin: 0 auto 20px;
  border-radius: 50%;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mascot-circle img {
  width: 86%;
  height: 86%;
  object-fit: contain;
}
.mascot-circle--sm {
  width: 118px;
  height: 118px;
  margin-bottom: 16px;
}
#how-it-works .mascot-circle, #download .mascot-circle { background: var(--bg-alt); }

header h1 {
  font-size: clamp(1.8rem, 6vw, 2.6rem);
  margin-bottom: 14px;
}
header .gender-der, header .gender-die, header .gender-das { color: var(--ink); }

.gender-der { color: var(--der); }
.gender-die { color: var(--die); }
.gender-das { color: var(--das); }

.tagline {
  max-width: 56ch;
  font-size: 1.1rem;
  color: var(--ink-soft);
  margin: 0 auto 24px;
}

.stat-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
}
.stat-list li {
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid rgba(75, 85, 99, 0.3);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
header .cta-row { justify-content: center; }

/* ---------- store links (QR stacked centered above its own badge) ---------- */
.store-links {
  margin-top: 72px;
  gap: 44px;
}
.store-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  width: 110px;
  line-height: 0;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.store-link:hover { transform: translateY(-2px); }
.store-link .qr {
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: #fff;
  padding: 8px;
}
.store-link .badge {
  display: block;
  width: 100%;
  height: auto;
}

/* ---------- store badges (Download section, no QR pairing) ---------- */
.store-badges a {
  display: inline-block;
  line-height: 0;
  border-radius: var(--radius-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.store-badges img {
  display: block;
  height: 48px;
  width: auto;
}
.store-badges a:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-hover);
}

/* ---------- nav ---------- */
nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.nav-inner {
  max-width: 860px;
  margin: 0 auto;
  padding: 0 20px;
  min-height: var(--nav-height);
  display: flex;
  align-items: center;
  gap: 20px;
}
.nav-logo {
  flex: none;
  display: flex;
  align-items: center;
}
.nav-logo img {
  height: 36px;
  width: auto;
  display: block;
}
nav ul {
  display: flex;
  gap: 4px;
  list-style: none;
  margin: 0;
  padding: 0;
  align-items: center;
  overflow-x: auto;
  scrollbar-width: none;
  /* Hints that the list scrolls horizontally on narrow screens, where it
     doesn't fully fit — without this the last item just gets cut off with
     no visual cue there's more to scroll to. */
  mask-image: linear-gradient(to right, black calc(100% - 28px), transparent 100%);
  -webkit-mask-image: linear-gradient(to right, black calc(100% - 28px), transparent 100%);
}
nav ul::-webkit-scrollbar { display: none; }
nav a {
  flex: none;
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
  padding: 12px 10px;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color 0.2s ease, border-color 0.2s ease;
}
nav a:hover { color: var(--ink); border-bottom-color: var(--die); }

/* ---------- burger menu (mobile) ---------- */
#nav-toggle {
  display: none;
  flex: none;
  width: 32px;
  height: 32px;
  margin-left: auto;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
#nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: var(--ink);
  transition: transform 0.2s ease, opacity 0.2s ease;
}
nav.nav-open #nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
nav.nav-open #nav-toggle span:nth-child(2) { opacity: 0; }
nav.nav-open #nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 720px) {
  #nav-toggle { display: flex; }

  nav ul {
    position: fixed;
    top: var(--nav-height);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--bg);
    /* Collapsed by default; nav-toggle.js toggles nav.nav-open. Height-
       based rather than display:none so the slide has something to
       transition. border-bottom/box-shadow are NOT here — a border
       still renders along a 0-height box's edge even with
       overflow:hidden, so they'd show as a faint second line under the
       header at all times otherwise; only the open state below gets
       them. */
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.25s ease;
    mask-image: none;
    -webkit-mask-image: none;
  }
  nav.nav-open ul {
    max-height: calc(100dvh - var(--nav-height));
    overflow-y: auto;
    border-bottom: 1px solid var(--border);
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
  }
  nav ul li { width: 100%; }
  nav a {
    padding: 14px 20px;
    border-bottom: 1px solid var(--border);
    border-left: 2px solid transparent;
  }
  nav a:hover { border-bottom-color: var(--border); border-left-color: var(--die); }
}

/* ---------- sections ---------- */
main { padding-top: 8px; padding-bottom: 40px; }

section {
  padding: 40px 0;
  border-bottom: 1px solid var(--border);
  scroll-margin-top: calc(var(--nav-height) + 12px);
}
section:last-of-type { border-bottom: none; }

/* One-section-per-screen: every text section snaps to and fills the
   viewport, EXCEPT the two .hero-wrapper scenes — those are tall
   scroll-linked parallax zones (see html's scroll-snap-type comment
   above) and must keep scrolling freely instead of snapping. min-height
   (not height) so a section with more content than fits one screen
   (e.g. FAQ, Learning core on a short viewport) grows instead of
   clipping — it just won't perfectly fill exactly one screen there. */
section:not(.hero-wrapper) {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}
section:not(.hero-wrapper) > .container { width: 100%; }
#learning-core { padding-top: 8px; }

#what-is { text-align: center; }
#what-is > .container > p { margin-left: auto; margin-right: auto; }

/* Strict alternation, in document order, across every "slide" — header,
   both hero-wrapper scenes, and all six text sections: F0F1EC, white,
   F0F1EC, white, ... starting with the header. header/sections/hero
   scenes are left transparent here on purpose — bg-fade.js paints a
   single continuous color onto <body> instead, interpolated live between
   each slide's shade as you scroll through it, so the swap fades in/out
   with scroll position rather than cutting instantly at each boundary.
   body's own `background: var(--bg)` above is the no-JS fallback. */

#download { text-align: center; }
#download .cta-row { justify-content: center; }

/* ---------- contact ---------- */
#stay-in-touch { text-align: center; }
#stay-in-touch > .container > p { margin-left: auto; margin-right: auto; }

.contact-row {
  justify-content: center;
  margin-top: 24px;
}
.contact-row .button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 28px;
  border: none;
  border-radius: var(--radius-pill);
  background: #000;
  color: #fff;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  box-sizing: border-box;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.contact-row .button:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-hover);
}

section h2 {
  font-size: clamp(2rem, 5vw, 2.75rem);
  line-height: 1;
  margin: 0 0 2.5rem;
  text-align: center;
}

section > .container > p:not(.cta-row) { max-width: 66ch; color: var(--ink-soft); }

section ol, section > .container > ul {
  padding-left: 22px;
  display: grid;
  gap: 10px;
  max-width: 66ch;
}
section ol li, section > .container > ul li { padding-left: 2px; }

/* ---------- definition list (Learning core) ---------- */
dl { margin: 0; }
dt {
  font-weight: 800;
  color: var(--ink);
  margin-top: 18px;
  text-align: center;
}
dt:first-child { margin-top: 0; }
dd {
  margin: 4px auto 0;
  color: var(--ink-soft);
  max-width: 62ch;
  text-align: center;
}

/* ---------- tables ---------- */
.table-scroll { overflow-x: auto; }
table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-size: 0.92rem;
}
caption { text-align: left; margin-bottom: 8px; color: var(--ink-soft); }
th, td {
  text-align: left;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
thead th {
  background: var(--chip-bg);
  color: var(--ink);
  font-weight: 800;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
tbody th[scope="row"] {
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
tbody tr:last-child td, tbody tr:last-child th { border-bottom: none; }

/* ---------- FAQ ---------- */
#faq details {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 18px;
  margin-bottom: 10px;
}
#faq summary {
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
#faq summary::-webkit-details-marker { display: none; }
#faq summary::before {
  content: "+";
  display: inline-block;
  width: 1em;
  color: var(--die);
  font-weight: 900;
}
#faq details[open] summary::before { content: "\2212"; }
#faq details p {
  margin: 10px 0 0;
  color: var(--ink-soft);
}

/* ---------- footer ---------- */
footer {
  /* Without its own snap point, the footer sits in a no-man's-land past
     the last real section (#stay-in-touch) — proximity scroll-snap has
     nothing to rest on there, so it can spring back to stay-in-touch's
     snap point moments after you stop scrolling (a delayed settle that
     looks like clicking a footer link caused the page to jump up).
     Giving the footer its own snap-align stops that. */
  scroll-snap-align: end;
  scroll-snap-stop: always;
  padding-top: 24px;
  padding-bottom: 48px;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-align: center;
}
footer a { color: var(--ink-soft); }
footer a:hover { color: var(--ink); }
.footer-logo {
  display: block;
  height: 32px;
  width: auto;
  margin: 0 auto 14px;
}
#back-to-top {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 20px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}
#back-to-top:hover {
  color: var(--ink);
  border-color: var(--ink-soft);
  transform: translateY(-2px);
}

@media (max-width: 520px) {
  /* Not 0 — header's content (mascot, headline, tagline, pills, QR
     codes, store badges) got tall enough on small screens that
     justify-content: center alone no longer reliably keeps the mascot
     clear of the fixed nav above it; this guarantees the clearance the
     base header rule's calc(var(--nav-height) + 32px) gives everywhere
     else, just trimmed down to fit more on a short viewport. */
  header { padding-top: calc(var(--nav-height) + 12px); }
  section { padding: 32px 0; }

  .nav-inner { padding: 0 14px; gap: 12px; }
  .nav-logo img { height: 28px; }
  nav a { padding: 12px 8px; font-size: 0.78rem; }

  .mascot-circle { width: 110px; height: 110px; }
  .mascot-circle--sm { width: 88px; height: 88px; }

  .store-links { margin-top: 36px; gap: 28px; }
  .store-link { width: 96px; gap: 16px; }
}
