/* ── Standalone animation page background ─────────────────────────────────── */
body.page-animation {
  background: #000;
}

/* ── Scroll container ─────────────────────────────────────────────────────── */
.page-animation .hero.section {
  max-width: 100%;
  overflow-x: clip;
}

.page-animation .hero__scroll {
  position: relative;
  width: 100%;
  max-width: 100%;
  overflow-x: clip;
}

/* ── Sticky image background ──────────────────────────────────────────────── */
/* Native `position: sticky` is intentionally NOT used here. On mobile
   browsers, while the address bar animates away during scroll, sticky's
   recalculation can visibly desync for a frame (element pops up, then
   snaps back). Instead, hero-scroll.js drives this element's position
   itself (fixed while "pinned", translateY while scrolled past) purely
   from scrollY, which is immune to that browser-level glitch. */
.page-animation .hero__scroll-sticky {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100svh;
  z-index: 0;
  overflow: hidden;
  background: #fff;
  transform: translate3d(0, 0, 0);
  will-change: transform;
}

.page-animation .hero__scroll-sticky.is-pinned {
  position: fixed;
}

.page-animation .hero__scroll-frame {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100%;
  max-width: 1600px;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transform: translate3d(-50%, 0, 0);
  /* Opacity is scroll-driven in hero-scroll.js so the ring can dissolve
     before the next section covers it — a CSS transition would lag. */
  transition: none;
  user-select: none;
  pointer-events: none;
}

.page-animation .hero__scroll-frame.is-visible {
  opacity: 1;
}

/* ── Text content wrapper ─────────────────────────────────────────────────── */
.page-animation .hero__scroll-text {
  position: relative;
  z-index: 1;
  max-width: 1300px;
  margin: 0 auto;
}

/* ── Sections ─────────────────────────────────────────────────────────────── */
.page-animation .hero__scroll-section {
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  padding-inline: var(--scroll-copy-section-gutter);
}

/* Opening hero line – vertically centred; section height between the
   halved 50vh and original 100vh.
   Uses static vh/svh (not dvh) on purpose: dvh is recalculated live as the
   mobile browser's address bar hides/shows during scroll, which changes the
   document's total height mid-scroll and produces a visible up/down
   jitter/rubber-band effect. Keeping this static avoids that feedback loop. */
.page-animation .hero__scroll-section--lead {
  justify-content: center;
  align-items: center;
  min-height: 65vh;
  min-height: 65svh;
}

/* First text block: shorter section so the box arrives quickly and
   holds briefly – right side of the viewport */
.page-animation .hero__scroll-section--first {
  min-height: 130vh;
}

/* Last text block: brief hold while the final frame stays visible */
.page-animation .hero__scroll-section--last {
  min-height: 150vh;
  padding-top: 50vh;
  justify-content: flex-end;
}

/* ── Cards ────────────────────────────────────────────────────────────────── */
.page-animation .hero__scroll-card {
  flex-shrink: 0;
}

/* Opening headline: full-width, centred */
.page-animation .hero__scroll-card--lead {
  width: 100%;
  max-width: var(--layout-wide-max, 1100px);
  text-align: center;
}

.page-animation .hero__scroll-lead {
  color: var(--color-almost-black);
  font-size: 3.8rem;
  font-weight: var(--font-weight-light);
  letter-spacing: -0.025em;
  line-height: 1.15;
}

/* Side text blocks */
.page-animation .hero__scroll-card--side {
  width: 40vw;
  max-width: 650px;
  padding: clamp(20px, 3vw, 40px) var(--scroll-copy-card-padding-inline);
  border-radius: 16px 16px 90px 16px;
  /* No background on desktop – text sits directly over the animation */
  background: none;
  color: var(--color-almost-black);
  /* Hidden until scrolled into view */
  opacity: 0;
  transition: opacity 900ms ease;
}

.page-animation .hero__scroll-card--side.is-visible {
  opacity: 1;
}

/* Right block: left edge pinned to the horizontal centre */
.page-animation .hero__scroll-card--side-right {
  position: sticky;
  top: 40vh;
  margin-left: 50%;
}

/* Left block: right edge pinned to the horizontal centre */
.page-animation .hero__scroll-card--side-left {
  position: sticky;
  top: 50vh;
  transform: translateY(-50%);
  margin-right: 50%;
}

/* ── Typography ───────────────────────────────────────────────────────────── */
.page-animation .hero__scroll-card-text {
  text-align: left;
}

.page-animation .hero__scroll-card--side strong {
  font-weight: var(--font-weight-bold);
}

/* ── Mobile (≤ 768 px) ────────────────────────────────────────────────────── */
@media (max-width: 768px) {

  /* Cover-crop the frame so it fills the screen edge-to-edge.
     (Canvas path draws cover in JS; object-fit still helps img fallback.) */
  .page-animation .hero__scroll-frame {
    object-fit: cover;
    transform: translate3d(-50%, 0, 0) scale(1);
  }

  /* Cards fill the full width inside the section gutters */
  .page-animation .hero__scroll-card--side {
    width: 100%;
    /* Semi-transparent white box reappears to keep text readable */
    background: rgba(255, 255, 255, 0.85);
  }

  /* Right block: full width, no 50% margin offset */
  .page-animation .hero__scroll-card--side-right {
    margin-left: 0;
    /* Centre vertically (same trick as desktop last box) */
    top: 50vh;
    transform: translateY(-50%);
  }

  /* Last section: align left (same as the other sections) */
  .page-animation .hero__scroll-section--last {
    justify-content: flex-start;
  }

  /* Left block: full width, fixed offset (no translateY jitter) */
  .page-animation .hero__scroll-card--side-left {
    margin-right: 0;
    top: 38vh;
    transform: translate3d(0, 0, 0);
  }

  /* Section heights are reduced on small screens */
  .page-animation .hero__scroll-section--first {
    min-height: 120vh;
  }

  .page-animation .hero__scroll-section--last {
    min-height: 110vh;
    padding-top: 30vh;
  }

  /* Subtle glow so the lead text reads against the animation on mobile */
  .page-animation .hero__scroll-lead {
    font-size: clamp(1.75rem, 6.5vw, 2.6rem);
    text-shadow:
      0 0 24px rgb(255 255 255 / 0.95),
      0 0 8px rgb(255 255 255 / 0.9);
  }

}

/* Hide the ‘o’ when the final text block scrolls to the top.
   On every viewport the sticky final frame can leave a thin arc
   peeking between the showcase and memories sections. */
.page-animation .hero__scroll-sticky.is-o-hidden .hero__scroll-frame,
.page-animation .hero__scroll-sticky.is-o-hidden .hero__scroll-frame.is-visible {
  opacity: 0;
}
