/* VocabStash landing page
   Look borrowed from the promo video: white ground, big green/yellow blocks,
   sticker labels with a hard ink shadow, bouncy motion. */

:root {
  /* Raw palette */
  --green: #3fb27f;
  --yellow: #ffd84d;
  --ink-light: #111111;
  --ink-dark: #f3f3ee;
  --ground-light: #ffffff;
  --ground-dark: #121512;
  --surface-light: #f6f7f2;
  --surface-dark: #1c201c;
  --muted-light: #4a4d47;
  --muted-dark: #b9bcb4;

  /* Themed tokens (fallback for browsers without light-dark()) */
  --ground: var(--ground-light);
  --surface: var(--surface-light);
  --ink: var(--ink-light);
  --muted: var(--muted-light);
  --line: var(--ink-light);

  @media (prefers-color-scheme: dark) {
    --ground: var(--ground-dark);
    --surface: var(--surface-dark);
    --ink: var(--ink-dark);
    --muted: var(--muted-dark);
    --line: var(--ink-dark);
  }

  @supports (color: light-dark(white, black)) {
    --ground: light-dark(var(--ground-light), var(--ground-dark));
    --surface: light-dark(var(--surface-light), var(--surface-dark));
    --ink: light-dark(var(--ink-light), var(--ink-dark));
    --muted: light-dark(var(--muted-light), var(--muted-dark));
    --line: light-dark(var(--ink-light), var(--ink-dark));
  }

  --font: "Poppins", "PingFang TC", "Noto Sans TC", "Microsoft JhengHei", system-ui, sans-serif;
  --radius-phone: 46px;
  --bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
  --wrap: 1180px;

  color-scheme: light dark;
  accent-color: var(--green);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 88px;

  @media (prefers-reduced-motion: reduce) {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

h1,
h2,
h3 {
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: inherit;
}

.wrap {
  width: min(100% - 32px, var(--wrap));
  margin-inline: auto;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 100;
  padding: 10px 18px;
  border: 3px solid var(--line);
  border-radius: 999px;
  background: var(--yellow);
  color: var(--ink-light);
  font-weight: 700;
  text-decoration: none;

  &:focus {
    top: 12px;
  }
}

:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: 3px;
}

/* ---------- Stickers & buttons ---------- */

.sticker {
  display: inline-block;
  padding: 6px 20px;
  border: 3px solid var(--line);
  border-radius: 999px;
  box-shadow: 4px 4px 0 var(--line);
  font-size: 18px;
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
}

.sticker-yellow {
  background: var(--yellow);
  color: var(--ink-light);
}

.sticker-green {
  background: var(--green);
  color: var(--ink-light);
}

.sticker-white {
  background: var(--ground);
  color: var(--ink);
}

.tilt-l {
  rotate: -3deg;
}

.tilt-r {
  rotate: 3deg;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 12px 30px;
  border: 3px solid var(--line);
  border-radius: 999px;
  background: var(--green);
  box-shadow: 5px 5px 0 var(--line);
  color: var(--ink-light);
  font-size: 18px;
  font-weight: 700;
  text-decoration: none;
  transition:
    translate 0.15s ease,
    box-shadow 0.15s ease,
    background-color 0.15s ease;

  &:hover {
    translate: -2px -2px;
    box-shadow: 7px 7px 0 var(--line);
  }

  &:active {
    translate: 3px 3px;
    box-shadow: 2px 2px 0 var(--line);
  }

  @media (prefers-reduced-motion: reduce) {
    &:hover,
    &:active {
      translate: none;
    }
  }
}

.btn-small {
  min-height: 44px;
  padding: 6px 22px;
  font-size: 16px;
  box-shadow: 3px 3px 0 var(--line);
}

.btn-ghost {
  background: var(--ground);
  color: var(--ink);
}

.btn-dark {
  background: var(--ink-light);
  border-color: var(--ink-light);
  box-shadow: 5px 5px 0 var(--yellow);
  color: #fff;

  &:hover {
    box-shadow: 7px 7px 0 var(--yellow);
  }
}

.btn-static {
  cursor: default;

  &:hover,
  &:active {
    translate: none;
    box-shadow: 5px 5px 0 var(--yellow);
  }
}

/* ---------- Phone, blobs, decorations ---------- */

/* iPhone-style frame: titanium edge, thin black bezel, iPhone corner radius and
   side buttons. The phone is an inline-size container so the bezel scales with it. */
.phone {
  position: relative;
  z-index: 1;
  width: min(100%, 320px);
  container-type: inline-size;
  border-radius: 17% / 7.9%;
  background: #0b0b0c;
  box-shadow:
    0 0 0 1.5px #3a3a3c,
    0 0 0 3.5px #a7a7ac,
    0 0 0 4.5px #5b5b60,
    0 30px 60px rgb(0 0 0 / 0.2);

  img,
  video,
  .mock {
    display: block;
    width: calc(100% - 6.8cqw);
    height: auto;
    margin: 3.4cqw;
    aspect-ratio: 600 / 1317;
    border-radius: 13.6% / 6.2%;
    object-fit: cover;
    background: #eef0e8;
  }

  /* Action button and volume buttons on the left, side button on the right */
  &::before,
  &::after {
    content: "";
    position: absolute;
    width: 4px;
    background: #a7a7ac;
  }

  &::before {
    left: -8px;
    top: 17%;
    height: 27%;
    border-radius: 3px 0 0 3px;
    background: linear-gradient(
      to bottom,
      #a7a7ac 0 11%,
      transparent 11% 25%,
      #a7a7ac 25% 55%,
      transparent 55% 63%,
      #a7a7ac 63% 93%,
      transparent 93%
    );
  }

  &::after {
    right: -8px;
    top: 25%;
    height: 12%;
    border-radius: 0 3px 3px 0;
  }
}

.blob {
  position: absolute;
  z-index: 0;
  inset: 12% -2%;
  border-radius: 28%;
  rotate: var(--tilt, 8deg);
}

.blob-green {
  background: var(--green);
}

.blob-yellow {
  background: var(--yellow);
}

.tilt-blob-l {
  --tilt: -8deg;
}

.tilt-blob-r {
  --tilt: 8deg;
}

.deco {
  position: absolute;
  z-index: 0;
  border-radius: 50%;
  pointer-events: none;
}

.deco-circle-green {
  left: -180px;
  bottom: -220px;
  width: 360px;
  aspect-ratio: 1;
  background: var(--green);
}

.deco-circle-yellow {
  right: -120px;
  top: -120px;
  width: 300px;
  aspect-ratio: 1;
  background: var(--yellow);
}

.nobr {
  white-space: nowrap;
}

.marker {
  padding: 0 0.12em;
  border-radius: 0.18em;
  background: linear-gradient(transparent 45%, var(--yellow) 45% 92%, transparent 92%);
  color: inherit;
}

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 3px solid var(--line);
  background: color-mix(in srgb, var(--ground) 88%, transparent);
  backdrop-filter: blur(12px);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  min-height: 72px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
  text-decoration: none;

  img {
    border: 2px solid var(--line);
    border-radius: 11px;
  }
}

.site-header nav {
  margin-left: auto;
}

.nav-links {
  display: flex;
  gap: 28px;
  margin: 0;
  padding: 0;
  list-style: none;

  a {
    font-weight: 600;
    text-decoration: none;
    text-underline-offset: 6px;
    text-decoration-thickness: 3px;

    &:hover {
      text-decoration-line: underline;
      text-decoration-color: var(--green);
    }
  }

  @media (width < 720px) {
    display: none;
  }
}

.header-inner > .btn {
  @media (width < 720px) {
    margin-left: auto;
  }
}

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

.hero {
  position: relative;
  overflow: clip;
  padding-block: clamp(48px, 8vw, 96px) clamp(64px, 9vw, 120px);
}

.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  align-items: center;
  gap: 56px;

  @media (width >= 900px) {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

.hero-copy {
  display: grid;
  justify-items: start;
  gap: 24px;
}

.hero h1 {
  font-size: clamp(38px, 5.4vw, 76px);
  font-weight: 800;
}

.lead {
  max-width: 34em;
  color: var(--muted);
  font-size: clamp(18px, 2vw, 21px);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 8px;
}

.fineprint {
  color: var(--muted);
  font-size: 15px;
  font-weight: 600;
}

.hero-visual {
  position: relative;
  display: grid;
  place-items: center;
  padding-block: 24px;
}

.word-card {
  position: absolute;
  z-index: 2;
  left: 0;
  bottom: 18%;
  display: grid;
  justify-items: start;
  gap: 8px;
  padding: 16px 20px;
  border: 3px solid var(--line);
  border-radius: 22px;
  background: var(--ground);
  box-shadow: 6px 6px 0 var(--line);
  rotate: -4deg;

  @media (width < 900px) {
    left: 4%;
  }
}

.word-card-term {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.01em;
  background: linear-gradient(transparent 50%, var(--yellow) 50% 92%, transparent 92%);
}

/* ---------- Sections ---------- */

.section {
  padding-block: clamp(72px, 10vw, 128px);
}

.section-title {
  margin-bottom: clamp(40px, 6vw, 72px);
  font-size: clamp(34px, 5vw, 56px);
  font-weight: 800;
  text-align: center;
}

.how {
  border-block: 3px solid var(--line);
  background: var(--surface);
}

.how-grid {
  display: grid;
  align-items: center;
  gap: 56px;

  @media (width >= 900px) {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

.how-copy {
  display: grid;
  justify-items: start;
  gap: 24px;

  h2 {
    font-size: clamp(36px, 5vw, 60px);
    font-weight: 800;
  }
}

.steps {
  display: grid;
  gap: 24px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;

  li {
    display: flex;
    align-items: flex-start;
    gap: 18px;
  }

  h3 {
    font-size: 22px;
    font-weight: 700;
  }

  p {
    color: var(--muted);
  }
}

.step-num {
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 3px solid var(--line);
  border-radius: 50%;
  box-shadow: 3px 3px 0 var(--line);
  color: var(--ink-light);
  font-size: 22px;
  font-weight: 800;
}

.step-yellow {
  background: var(--yellow);
}

.step-green {
  background: var(--green);
}

.how-visual {
  position: relative;
  display: grid;
  place-items: center;
  margin: 0;
  padding-block: 24px;
}

.video-toggle {
  position: absolute;
  z-index: 2;
  right: 6%;
  bottom: 4%;
  cursor: pointer;
  font-family: inherit;
}

/* ---------- Features ---------- */

.feature {
  display: grid;
  align-items: center;
  gap: 40px;

  & + & {
    margin-top: clamp(72px, 10vw, 128px);
  }

  @media (width >= 900px) {
    grid-template-columns: 1fr 1fr;
    gap: 80px;
  }
}

.feature-flip .feature-visual {
  @media (width >= 900px) {
    order: 2;
  }
}

.feature-visual {
  position: relative;
  display: grid;
  place-items: center;
  padding-block: 24px;

  .phone {
    width: min(100%, 290px);
  }
}

.feature-copy {
  display: grid;
  justify-items: start;
  gap: 20px;

  h3 {
    font-size: clamp(30px, 4vw, 46px);
    font-weight: 800;
  }

  > p:not(:first-child) {
    max-width: 30em;
    color: var(--muted);
  }
}

.chips,
.interval {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.interval li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 100%;
  top: 50%;
  width: 18px;
  height: 3px;
  margin-left: 6px;
  background: var(--line);
}

.interval {
  gap: 30px;

  li {
    position: relative;
  }
}

/* ---------- Privacy band ---------- */

.band {
  border-block: 3px solid var(--line);
  background: var(--green);
  color: var(--ink-light);
  padding-block: clamp(64px, 9vw, 112px);

  h2 {
    max-width: 18em;
    font-size: clamp(32px, 4.6vw, 54px);
    font-weight: 800;
  }
}

.band-inner {
  display: grid;
  gap: 48px;
}

.band-points {
  display: grid;
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;

  @media (width >= 820px) {
    grid-template-columns: repeat(3, 1fr);
  }

  li {
    display: grid;
    gap: 8px;
    padding: 24px;
    border: 3px solid var(--ink-light);
    border-radius: 24px;
    background: #fff;
    box-shadow: 6px 6px 0 var(--ink-light);
  }

  h3 {
    font-size: 22px;
    font-weight: 700;
  }

  p {
    color: #3d3f3a;
  }
}

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

.faq-inner {
  max-width: 820px;
}

.faq-list {
  display: grid;
  gap: 18px;

  details {
    border: 3px solid var(--line);
    border-radius: 22px;
    background: var(--ground);
    box-shadow: 5px 5px 0 var(--line);

    &[open] {
      background: var(--surface);
    }
  }

  summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 24px;
    cursor: pointer;
    font-size: 20px;
    font-weight: 700;
    list-style: none;

    &::-webkit-details-marker {
      display: none;
    }

    &::after {
      content: "+";
      flex: none;
      display: grid;
      place-items: center;
      width: 36px;
      height: 36px;
      border: 3px solid var(--line);
      border-radius: 50%;
      background: var(--yellow);
      color: var(--ink-light);
      font-size: 22px;
      line-height: 1;
    }
  }

  details[open] summary::after {
    content: "–";
    background: var(--green);
  }

  details p {
    padding: 0 24px 22px;
    color: var(--muted);
  }
}

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

.final {
  border-top: 3px solid var(--line);
  background: var(--yellow);
  color: var(--ink-light);
  padding-block: clamp(72px, 10vw, 128px);
  text-align: center;
}

.final-inner {
  display: grid;
  justify-items: center;
  gap: 28px;

  h2 {
    font-size: clamp(48px, 8vw, 96px);
    font-weight: 800;
    letter-spacing: -0.03em;
  }

  .sticker-yellow {
    background: #fff;
    border-color: var(--ink-light);
    box-shadow: 4px 4px 0 var(--ink-light);
  }
}

.final-icon {
  width: clamp(120px, 16vw, 180px);
  border: 4px solid var(--ink-light);
  border-radius: 22%;
  box-shadow: 8px 8px 0 var(--ink-light);
  rotate: -4deg;
}

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

.site-footer {
  border-top: 3px solid var(--line);
  padding-block: 32px;
  color: var(--muted);
  font-size: 15px;
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.footer-links {
  display: flex;
  gap: 24px;
  margin: 0;
  padding: 0;
  list-style: none;

  a {
    text-decoration: none;

    &:hover {
      color: var(--ink);
    }
  }
}

/* ---------- Motion (opt-in) ---------- */

@keyframes pop-in {
  from {
    opacity: 0;
    scale: 0.6;
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    translate: 0 60px;
  }
}

@keyframes blob-in {
  from {
    scale: 0;
    rotate: -30deg;
  }
}

@keyframes reveal-up {
  from {
    opacity: 0;
    translate: 0 48px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .hero-copy .sticker {
    animation: pop-in 0.6s var(--bounce) both;
  }

  .hero h1 {
    animation: rise-in 0.7s var(--bounce) 0.08s both;
  }

  .hero .lead,
  .hero .cta-row,
  .hero .fineprint {
    animation: rise-in 0.7s var(--bounce) 0.16s both;
  }

  .hero-visual .blob {
    animation: blob-in 0.8s var(--bounce) 0.1s both;
  }

  .hero-visual .phone {
    animation: rise-in 0.9s var(--bounce) 0.2s both;
  }

  .word-card {
    animation: pop-in 0.6s var(--bounce) 0.7s both;
  }

  .deco {
    animation: pop-in 0.8s var(--bounce) both;
  }

  .chips .sticker,
  .interval .sticker {
    transition: rotate 0.25s var(--bounce), scale 0.25s var(--bounce);

    &:hover {
      rotate: 0deg;
      scale: 1.08;
    }
  }

  /* Scroll-driven reveal; browsers without it show content in place */
  @supports (animation-timeline: view()) {
    .reveal {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 40%;
    }
  }
}

/* On the yellow CTA band the dark button gets a white offset shadow */
.final .btn-dark,
.final .btn-dark:hover,
.final .btn-static:active {
  box-shadow: 5px 5px 0 #fff;
}

/* Highlighted words always sit on yellow, so keep their text dark */
.marker {
  color: var(--ink-light);
}

.word-card {
  border-color: var(--ink-light);
  background: #fff;
  box-shadow: 6px 6px 0 var(--ink-light);
  color: var(--ink-light);
}

/* Keep the corner circles clear of the headline on narrow screens */
@media (width < 720px) {
  .deco-circle-yellow {
    right: -110px;
    top: -110px;
    width: 180px;
  }

  .deco-circle-green {
    width: 240px;
    left: -150px;
    bottom: -170px;
  }
}

/* Full yellow block so the dark text stays readable on any ground */
.marker {
  padding: 0 0.14em;
  border-radius: 0.16em;
  background: var(--yellow);
  box-decoration-break: clone;
}

/* =====================================================================
   Scroll story (inspired by a sticky-stage "push" story)
   Base: scenes are ordinary stacked sections.
   .story.is-on (added by main.js on wide screens with motion allowed):
   a sticky stage where each scene is pushed up by the next one.
   ===================================================================== */

:root {
  --header-h: 75px;
}

.story-scene:not(.hero) {
  padding-block: clamp(72px, 10vw, 128px);
}

.story-scene.how {
  border-block: 3px solid var(--line);
  background: var(--surface);
}

.skip-story {
  display: none;
}

/* ---------- Film scene ---------- */

.film-scene {
  background: var(--ground);
}

.film-inner {
  display: grid;
  justify-items: center;
  gap: 22px;
  text-align: center;

  h2 {
    font-size: clamp(32px, 4.6vw, 56px);
    font-weight: 800;
  }
}

.film-frame {
  position: relative;
  width: min(100%, 960px);
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 4px solid var(--line);
  border-radius: 28px;
  background: #111;
  box-shadow: 10px 10px 0 var(--green);

  iframe,
  .film-poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
  }
}

.film-poster {
  padding: 0;
  cursor: pointer;
  background: #111;

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  &:focus-visible {
    outline-offset: -8px;
  }
}

.film-play {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 92px;
  height: 92px;
  margin: -46px 0 0 -46px;
  border: 4px solid var(--ink-light);
  border-radius: 50%;
  background: var(--yellow);
  box-shadow: 5px 5px 0 var(--ink-light);
  transition: scale 0.2s var(--bounce);

  &::after {
    content: "";
    position: absolute;
    left: 36px;
    top: 26px;
    border-left: 28px solid var(--ink-light);
    border-block: 18px solid transparent;
  }

  .film-poster:hover & {
    scale: 1.08;
  }
}

.film-sound {
  cursor: pointer;
  font-family: inherit;
}

/* ---------- Story mode ---------- */

.story.is-on {
  /* main.js sets the height from each scene's data-length */

  .story-stage {
    position: sticky;
    top: var(--header-h);
    height: calc(100svh - var(--header-h));
    overflow: clip;
  }

  .story-scene {
    --pos: 1;
    --in: 0;
    position: absolute;
    inset: 0;
    display: grid;
    align-items: center;
    padding-block: 0;
    visibility: hidden;
    border-top: 3px solid var(--line);
    background: var(--ground);
    translate: 0 calc(var(--pos) * 100%);
    will-change: translate;

    &.is-visible {
      visibility: visible;
    }

    &.hero {
      border-top: 0;
    }
  }

  .story-scene.how {
    border-bottom: 0;
    background: var(--surface);
  }

  /* Size phones and the film by the stage height so every scene fits */
  .story-scene .phone {
    width: clamp(200px, calc((100svh - var(--header-h) - 110px) * 0.473), 300px);
  }

  .story-scene .feature-visual,
  .story-scene .how-visual,
  .story-scene .hero-visual {
    padding-block: 0;
  }

  .film-frame {
    width: min(100%, 960px, calc((100svh - var(--header-h) - 290px) * 16 / 9));
  }

  .hero {
    padding-block: 0;
  }

  .skip-story {
    position: absolute;
    z-index: 5;
    left: 24px;
    bottom: 20px;
    display: inline-block;
    font-size: 15px;
    text-decoration: none;
  }
}

/* The YouTube player sits over its poster; the poster shows until the player paints */
.film-frame iframe {
  z-index: 1;
}

.film-frame.has-player .film-poster {
  pointer-events: none;

  .film-play {
    display: none;
  }
}

/* Component display rules must never un-hide [hidden] elements */
[hidden] {
  display: none !important;
}

/* =====================================================================
   Scroll-scrubbed animation (story mode only)
   main.js turns each element's data-anim="name@start+length" into a
   0→1 custom property (--rise, --pop, ...) from the page's own scroll
   progress, so scrolling back plays the animation in reverse.
   Outside story mode none of these properties are set and every
   element rests in its final state.
   ===================================================================== */

.hook,
.scroll-hint {
  display: none;
}

.story.is-on {
  /* Load-time entrances would fight the scroll timeline */
  .story-scene,
  .story-scene * {
    animation: none !important;
  }

  .hero-kicker {
    display: none;
  }

  [data-anim~="rise"],
  [data-anim*="rise@"] {
    opacity: clamp(0, var(--rise, 1), 1);
    translate: 0 calc((1 - var(--rise, 1)) * 140px);
  }

  [data-anim*="pop@"] {
    opacity: clamp(0, var(--pop, 1) * 3, 1);
    scale: calc(0.25 + 0.75 * var(--pop, 1));
  }

  [data-anim*="spin@"] {
    scale: var(--spin, 1);
    rotate: calc(var(--tilt, 8deg) - (1 - var(--spin, 1)) * 45deg);
  }

  [data-anim*="grow@"] {
    opacity: clamp(0, var(--grow, 1) * 2, 1);
    scale: calc(0.5 + 0.5 * var(--grow, 1));
  }

  [data-anim*="out@"] {
    opacity: calc(1 - var(--out, 0));
    translate: 0 calc(var(--out, 0) * -90px);
  }

  [data-anim*="draw@"] {
    scale: var(--draw, 1) 1;
    transform-origin: 0 50%;
  }

  /* An element can rise and then zoom: rise moves it, zoom scales it */
  .phone[data-anim*="zoom@"] {
    scale: calc(1 + (var(--zoom-to, 1.35) - 1) * var(--zoom, 0));
  }

  #review .phone {
    --zoom-to: 1.45;
    transform-origin: 50% 64%;
  }

  #progress .phone {
    --zoom-to: 1.35;
    transform-origin: 50% 36%;
  }

  .interval li::after {
    scale: var(--link, 1) 1;
    transform-origin: 0 50%;
  }

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

  .hook {
    position: absolute;
    z-index: 3;
    inset: 0;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 40px;
    padding-inline: 24px;
    text-align: center;
    pointer-events: none;
  }

  .hook-sentence {
    font-size: clamp(48px, 7vw, 104px);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.02em;
  }

  .hook-word {
    position: relative;
    isolation: isolate;
    display: inline-block;
    font-weight: 800;
  }

  .hook-marker {
    position: absolute;
    z-index: -1;
    left: -0.12em;
    right: -0.12em;
    top: 0.06em;
    bottom: -0.02em;
    border-radius: 0.14em;
    background: var(--yellow);
  }

  /* The word turns dark as the yellow marker sweeps under it (matters in dark mode) */
  .hook-word {
    color: color-mix(in srgb, var(--ink-light) calc(var(--tone, 1) * 100%), var(--ink));
  }

  .hook-tip {
    position: absolute;
    left: 50%;
    top: 112%;
    margin-left: -3.2em;
    width: 6.4em;
    font-size: clamp(22px, 2.6vw, 34px);
    letter-spacing: 0;
    text-align: center;
    rotate: 4deg;
  }

  .scroll-hint {
    position: absolute;
    z-index: 3;
    left: 50%;
    bottom: 64px;
    display: block;
    margin: 0;
    translate: -50% 0;
    color: var(--muted);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.08em;

    &::after {
      content: "";
      display: block;
      width: 12px;
      height: 12px;
      margin: 8px auto 0;
      border-right: 3px solid currentColor;
      border-bottom: 3px solid currentColor;
      rotate: 45deg;
    }
  }

  .scroll-hint[data-anim*="out@"] {
    translate: -50% calc(var(--out, 0) * -40px);
  }
}

/* =====================================================================
   Simulated Safari + VocabStash extension (story mode only)
   1 --u = 1pt on a 393pt-wide iPhone screen, so the layout scales with
   the phone frame. Values mirror WordCollector Extension/Resources/content.js.
   ===================================================================== */

.mock-phone {
  display: none;
}

.story.is-on {
  .how-visual .video-phone,
  .how-visual .video-toggle {
    display: none;
  }

  .how-visual .mock-phone {
    display: block;
  }
}

.mock {
  --u: calc(100cqw / 393);
  --sys: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang TC", system-ui, sans-serif;
  position: relative;
  aspect-ratio: 600 / 1317;
  overflow: hidden;
  container-type: inline-size;
  background: #fff;
  color: #1d1d1f;
  font-family: var(--sys);
  /* The simulated page keeps light colours, like the recording's page */
  color-scheme: light;
}

.mock-status {
  position: absolute;
  inset: 0 0 auto;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: calc(54 * var(--u));
  padding: 0 calc(34 * var(--u)) 0 calc(44 * var(--u));
  background: #fff;
}

.mock-time {
  font-size: calc(16 * var(--u));
  font-weight: 650;
}

.mock-icons {
  display: flex;
  align-items: center;
  gap: calc(5 * var(--u));

  i {
    display: block;
    width: calc(17 * var(--u));
    height: calc(10 * var(--u));
    border-radius: calc(3 * var(--u));
    background: #1d1d1f;
  }

  i:last-child {
    width: calc(24 * var(--u));
    height: calc(11 * var(--u));
  }
}

.mock-article {
  position: absolute;
  inset: calc(64 * var(--u)) calc(22 * var(--u)) auto;
  font-size: calc(17 * var(--u));
  line-height: 1.55;

  p {
    margin: 0 0 calc(16 * var(--u));
  }

  h4 {
    margin: 0 0 calc(14 * var(--u));
    font-family: Georgia, "Times New Roman", serif;
    font-size: calc(27 * var(--u));
    line-height: 1.18;
    font-weight: 700;
  }
}

.mock-kicker {
  color: #b00020;
  font-size: calc(13 * var(--u));
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.mock-sel {
  position: relative;
  isolation: isolate;
}

.mock-sel-bg {
  position: absolute;
  z-index: -1;
  inset: -0.05em -0.08em;
  border-radius: calc(3 * var(--u));
  background: rgb(0 122 255 / 0.28);
  opacity: calc(var(--sel, 0) - var(--selx, 0));

  &::before,
  &::after {
    content: "";
    position: absolute;
    width: calc(2 * var(--u));
    background: #007aff;
  }

  &::before {
    left: 0;
    top: calc(-6 * var(--u));
    bottom: 0;
  }

  &::after {
    right: 0;
    top: 0;
    bottom: calc(-6 * var(--u));
  }
}

.mock-menu {
  position: absolute;
  z-index: 5;
  left: calc(-6 * var(--u));
  bottom: calc(100% + 10 * var(--u));
  display: flex;
  transform-origin: 30% 100%;
  overflow: hidden;
  border-radius: calc(9 * var(--u));
  background: #2c2c2e;
  box-shadow: 0 calc(6 * var(--u)) calc(20 * var(--u)) rgb(0 0 0 / 0.25);
  opacity: calc(var(--menu, 0) - var(--menux, 0));
  scale: calc(0.85 + 0.15 * var(--menu, 0));
  white-space: nowrap;

  b {
    padding: calc(8 * var(--u)) calc(12 * var(--u));
    color: #fff;
    font-size: calc(14 * var(--u));
    font-weight: 500;
    line-height: 1.2;
  }

  b + b {
    border-left: 1px solid rgb(255 255 255 / 0.18);
  }
}

.mock-dim {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgb(5 18 12 / 0.18);
  opacity: calc(var(--dim, 0) - var(--dimx, 0));
}

/* Extension selection button: content.js insertSelectionButton() */
.mock-bar {
  position: absolute;
  z-index: 6;
  left: calc(14 * var(--u));
  right: calc(14 * var(--u));
  bottom: calc(108 * var(--u));
  display: flex;
  align-items: center;
  height: calc(72 * var(--u));
  padding: calc(10 * var(--u)) calc(16 * var(--u)) calc(10 * var(--u)) calc(18 * var(--u));
  border: 1px solid rgb(255 255 255 / 0.62);
  border-radius: calc(22 * var(--u));
  color: #f7fffa;
  background: linear-gradient(135deg, rgb(63 139 102 / 0.95), rgb(29 102 72 / 0.94));
  box-shadow: 0 calc(14 * var(--u)) calc(38 * var(--u)) rgb(11 52 35 / 0.3), inset 0 1px rgb(255 255 255 / 0.28);
  opacity: calc(var(--bar, 0) - var(--barx, 0));
  translate: 0 calc((1 - var(--bar, 0)) * 18 * var(--u));

  svg {
    width: calc(22 * var(--u));
    height: calc(22 * var(--u));
    margin-left: calc(12 * var(--u));
    fill: none;
    stroke: currentColor;
    stroke-width: 2.25;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
}

.mock-bar-copy {
  flex: 1;
  min-width: 0;
}

.mock-bar-sel {
  display: block;
  margin-bottom: calc(5 * var(--u));
  color: rgb(255 255 255 / 0.72);
  font-size: calc(12 * var(--u));
  font-weight: 550;
  line-height: 1.1;
}

.mock-bar-action {
  display: block;
  font-size: calc(17 * var(--u));
  font-weight: 750;
  line-height: 1.15;
  letter-spacing: -0.2px;
}

/* Lookup sheet: content.js openLookupPanel() */
.mock-sheet {
  position: absolute;
  z-index: 7;
  left: calc(14 * var(--u));
  right: calc(14 * var(--u));
  bottom: calc(108 * var(--u));
  padding: calc(6 * var(--u)) calc(18 * var(--u)) calc(18 * var(--u));
  border: 1px solid rgb(255 255 255 / 0.6);
  border-radius: calc(28 * var(--u));
  color: #14251d;
  background: rgb(244 250 246 / 0.97);
  box-shadow: 0 calc(24 * var(--u)) calc(70 * var(--u)) rgb(6 35 23 / 0.28);
  translate: 0 calc((1 - var(--sheet, 0) + var(--sheetx, 0)) * 130%);
}

.mock-grabber {
  width: calc(40 * var(--u));
  height: calc(5 * var(--u));
  margin: calc(11 * var(--u)) auto calc(19 * var(--u));
  border-radius: calc(9 * var(--u));
  background: rgb(35 62 49 / 0.25);
}

.mock-sheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: calc(12 * var(--u));
}

.mock-eyebrow {
  margin: 0 0 calc(4 * var(--u));
  color: #4b6b5b;
  font-size: calc(12 * var(--u));
  font-weight: 650;
}

.mock-term {
  margin: 0;
  font-size: calc(25 * var(--u));
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.5px;
}

.mock-close {
  display: grid;
  place-items: center;
  width: calc(36 * var(--u));
  height: calc(36 * var(--u));
  border-radius: 50%;
  color: #355144;
  background: rgb(56 98 77 / 0.11);
  font-size: calc(21 * var(--u));
}

.mock-meaning {
  position: relative;
  display: grid;
  align-items: center;
  min-height: calc(72 * var(--u));
  margin-top: calc(17 * var(--u));
  padding: calc(16 * var(--u));
  border: 1px solid rgb(53 112 82 / 0.1);
  border-radius: calc(18 * var(--u));
  background: rgb(129 203 164 / 0.18);

  > * {
    grid-area: 1 / 1;
  }
}

.mock-loading {
  display: flex;
  align-items: center;
  gap: calc(10 * var(--u));
  color: #557064;
  font-size: calc(15 * var(--u));
  font-weight: 550;
  opacity: calc(1 - var(--meaning, 0));
}

.mock-spinner {
  flex: none;
  width: calc(18 * var(--u));
  height: calc(18 * var(--u));
  border: 2px solid rgb(42 121 89 / 0.2);
  border-top-color: #2a7959;
  border-radius: 50%;
  rotate: calc(var(--turn, 0) * 1440deg);
}

.mock-result {
  color: #1c4c35;
  font-size: calc(20 * var(--u));
  font-weight: 650;
  opacity: var(--meaning, 0);
  translate: 0 calc((1 - var(--meaning, 0)) * 8 * var(--u));
}

.mock-label {
  margin: calc(17 * var(--u)) calc(2 * var(--u)) calc(7 * var(--u));
  color: #52675d;
  font-size: calc(13 * var(--u));
  font-weight: 650;
}

.mock-select {
  position: relative;
  display: flex;
  align-items: center;
  height: calc(52 * var(--u));
  padding: 0 calc(15 * var(--u));
  border: 1px solid rgb(37 79 59 / 0.14);
  border-radius: calc(15 * var(--u));
  color: #183528;
  background: rgb(255 255 255 / 0.55);
  font-size: calc(16 * var(--u));
  font-weight: 650;

  i {
    position: absolute;
    right: calc(16 * var(--u));
    top: 50%;
    width: calc(9 * var(--u));
    height: calc(9 * var(--u));
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    translate: 0 -70%;
    rotate: 45deg;
  }
}

.mock-primary {
  display: grid;
  place-items: center;
  min-height: calc(54 * var(--u));
  margin-top: calc(16 * var(--u));
  border-radius: calc(17 * var(--u));
  color: #fff;
  background: linear-gradient(135deg, #3f8b66, #1d6648);
  box-shadow: 0 calc(10 * var(--u)) calc(24 * var(--u)) rgb(24 90 61 / 0.22);
  font-size: calc(17 * var(--u));
  font-weight: 750;
  opacity: calc(0.52 + 0.48 * var(--enable, 0));
}

/* Save status: content.js showLoadingDialog() */
.mock-toast {
  position: absolute;
  z-index: 8;
  left: calc(14 * var(--u));
  right: calc(14 * var(--u));
  bottom: calc(108 * var(--u));
  display: flex;
  align-items: center;
  gap: calc(14 * var(--u));
  height: calc(76 * var(--u));
  padding: calc(10 * var(--u)) calc(18 * var(--u));
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / 0.62);
  border-radius: calc(22 * var(--u));
  color: color-mix(in srgb, #fff calc(var(--done, 0) * 100%), #183528);
  background: rgb(244 250 246 / 0.97);
  box-shadow: 0 calc(14 * var(--u)) calc(38 * var(--u)) rgb(11 52 35 / 0.24);
  opacity: var(--toast, 0);
  translate: 0 calc((1 - var(--toast, 0)) * 24 * var(--u));

  /* Completed state fades in over the light card */
  &::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg, rgb(63 139 102 / 0.98), rgb(29 102 72 / 0.98));
    opacity: var(--done, 0);
  }

  > * {
    position: relative;
  }
}

.mock-toast-icon {
  display: grid;
  place-items: center;
  width: calc(44 * var(--u));
  height: calc(44 * var(--u));
  flex: none;
  border-radius: calc(15 * var(--u));
  color: color-mix(in srgb, #fff calc(var(--done, 0) * 100%), #2a7959);
  background: color-mix(in srgb, rgb(255 255 255 / 0.16) calc(var(--done, 0) * 100%), rgb(74 147 108 / 0.12));

  > * {
    grid-area: 1 / 1;
  }

  .mock-spinner {
    width: calc(24 * var(--u));
    height: calc(24 * var(--u));
    opacity: calc(1 - var(--done, 0));
    rotate: calc(var(--toast, 0) * 360deg + var(--done, 0) * 360deg);
  }

  svg {
    width: calc(27 * var(--u));
    height: calc(27 * var(--u));
    fill: none;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: var(--done, 0);
  }

  circle {
    stroke-width: 1.8;
    opacity: 0.38;
  }

  path {
    stroke-width: 2.5;
    stroke-dasharray: 22;
    stroke-dashoffset: calc((1 - var(--done, 0)) * 22);
  }
}

.mock-toast-text {
  display: grid;
  font-size: calc(18 * var(--u));
  font-weight: 760;

  b {
    grid-area: 1 / 1;
    font-weight: inherit;
  }
}

.mock-adding {
  opacity: calc(1 - var(--done, 0));
}

.mock-done {
  opacity: var(--done, 0);
}

/* A fingertip shows where the visitor would tap */
.mock-touch {
  position: absolute;
  z-index: 9;
  width: calc(46 * var(--u));
  height: calc(46 * var(--u));
  margin: calc(-23 * var(--u)) 0 0 calc(-23 * var(--u));
  border: calc(2 * var(--u)) solid rgb(255 255 255 / 0.9);
  border-radius: 50%;
  background: rgb(17 17 17 / 0.35);
  box-shadow: 0 calc(4 * var(--u)) calc(14 * var(--u)) rgb(0 0 0 / 0.25);
}

.mock-touch-a {
  left: 50%;
  bottom: calc(144 * var(--u));
  opacity: calc(var(--tina, 0) - var(--touta, 0));
  scale: calc(1.4 - 0.4 * var(--tina, 0));
}

.mock-touch-b {
  left: 50%;
  bottom: calc(153 * var(--u));
  opacity: calc(var(--tinb, 0) - var(--toutb, 0));
  scale: calc(1.4 - 0.4 * var(--tinb, 0));
}

.mock-toolbar {
  position: absolute;
  z-index: 4;
  inset: auto 0 0;
  display: grid;
  place-items: start center;
  height: calc(96 * var(--u));
  padding-top: calc(12 * var(--u));
  border-top: 1px solid rgb(0 0 0 / 0.06);
  background: rgb(249 249 249 / 0.96);

  span {
    padding: calc(9 * var(--u)) calc(26 * var(--u));
    border-radius: calc(14 * var(--u));
    background: #fff;
    box-shadow: 0 1px calc(6 * var(--u)) rgb(0 0 0 / 0.1);
    font-size: calc(15 * var(--u));
    font-weight: 500;
  }
}

/* =====================================================================
   Story layout on phones and narrow windows (< 900px):
   every page stacks its text above its visual, and the visual takes
   whatever height is left, so each page fits the screen.
   ===================================================================== */

@media (width < 900px) {
  .story.is-on {
    .story-scene {
      align-items: stretch;
    }

    .feature-scene > .wrap,
    .story-scene > .wrap {
      height: 100%;
    }

    :is(.hero-grid, .how-grid, .feature) {
      grid-template-columns: 1fr;
      grid-template-rows: auto minmax(0, 1fr);
      gap: 14px;
      height: 100%;
      padding-block: 18px 56px;
      align-items: stretch;
    }

    /* Text first, picture below */
    .feature .feature-visual {
      order: 2;
    }

    .feature + .feature {
      margin-top: 0;
    }

    /* The visual area is a size container; the phone is sized by its height */
    :is(.hero-visual, .how-visual, .feature-visual) {
      min-height: 0;
      container-type: size;
      display: grid;
      place-items: center;
    }

    /* Punch-ins stay inside the picture area instead of covering the text */
    .feature-visual {
      overflow: clip;
      border-radius: 24px;
    }

    .story-scene .phone {
      width: min(100cqw - 24px, calc((100cqh - 12px) * 0.473));
    }

    .blob {
      inset: 8% 6%;
    }

    /* Hero */
    .hero-copy {
      gap: 12px;
    }

    .hero h1 {
      font-size: clamp(30px, 8.4vw, 40px);
    }

    .lead {
      font-size: 15px;
      line-height: 1.6;
    }

    .cta-row {
      gap: 12px;
      margin-top: 0;

      .btn {
        min-height: 44px;
        padding: 6px 20px;
        font-size: 15px;
        box-shadow: 3px 3px 0 var(--line);
      }
    }

    .fineprint {
      font-size: 12px;
    }

    .word-card {
      left: 2%;
      bottom: 10%;
      padding: 10px 14px;
      gap: 6px;

      .word-card-term {
        font-size: 18px;
      }

      .sticker {
        font-size: 14px;
        padding: 3px 12px;
      }
    }

    .hook {
      gap: 28px;
    }

    .hook-sentence {
      font-size: clamp(38px, 10vw, 56px);
    }

    .scroll-hint {
      bottom: 28px;
    }

    /* Film */
    .film-scene {
      align-items: center;
    }

    .film-scene > .wrap {
      height: auto;
    }

    .film-inner h2 {
      font-size: clamp(26px, 7vw, 36px);
    }

    .film-frame {
      width: 100%;
      border-radius: 18px;
      box-shadow: 6px 6px 0 var(--green);
    }

    .film-play {
      width: 64px;
      height: 64px;
      margin: -32px 0 0 -32px;

      &::after {
        left: 24px;
        top: 17px;
        border-left-width: 20px;
        border-block-width: 13px;
      }
    }

    /* How */
    .how-copy {
      gap: 10px;

      h2 {
        font-size: clamp(26px, 7.4vw, 36px);
      }
    }

    .steps {
      gap: 8px;
      margin: 0;

      li {
        align-items: center;
        gap: 12px;
      }

      h3 {
        font-size: 16px;
      }

      p {
        display: none;
      }
    }

    .step-num {
      width: 34px;
      height: 34px;
      font-size: 16px;
    }

    /* Feature pages */
    .feature-copy {
      gap: 10px;

      h3 {
        font-size: clamp(24px, 6.8vw, 32px);
      }

      > p:not(:first-child) {
        font-size: 15px;
        line-height: 1.6;
      }
    }

    .sticker {
      font-size: 15px;
      padding: 4px 14px;
      border-width: 2.5px;
      box-shadow: 3px 3px 0 var(--line);
    }

    .chips,
    .interval {
      gap: 10px;
    }

    .interval {
      gap: 26px;
    }

    .skip-story {
      left: 16px;
      bottom: 12px;
      font-size: 13px;
    }
  }
}

/* The page inside the simulated Safari scrolls (by page scroll) until the
   sentence with the word sits mid-screen. main.js measures --read-dist. */
.mock-page {
  position: absolute;
  inset: calc(54 * var(--u)) 0 calc(96 * var(--u));
  overflow: hidden;
}

.mock .mock-article {
  position: relative;
  inset: auto;
  padding: calc(10 * var(--u)) calc(22 * var(--u)) 0;
  translate: 0 calc(var(--read, 0) * var(--read-dist, 0px) * -1);
}

.mock-byline {
  color: #6e6e73;
  font-size: calc(13 * var(--u));
}

.mock-photo {
  height: calc(190 * var(--u));
  margin: 0 0 calc(18 * var(--u));
  border-radius: calc(10 * var(--u));
  background:
    radial-gradient(circle at 50% 120%, rgb(255 255 255 / 0.35) 0 22%, transparent 23%),
    repeating-linear-gradient(90deg, #3c9a5f 0 calc(28 * var(--u)), #44a868 calc(28 * var(--u)) calc(56 * var(--u)));
}

/* The simulated Safari page is white, with the Dynamic Island on top */
.phone .mock {
  background: #fff;
}

.mock-island {
  position: absolute;
  left: 50%;
  top: calc(11 * var(--u));
  width: calc(124 * var(--u));
  height: calc(36 * var(--u));
  translate: -50% 0;
  border-radius: calc(20 * var(--u));
  background: #000;
}
