/**
 * About-reveal section — scroll-scrubbed about block.
 *
 * Reveal recipe:
 *   1. Text blocks (statement / closer / headline / tagline) get split
 *      into per-word <span class="about-reveal__word"> via JS. Each word
 *      animates `opacity 0→1, blur 8→0` with its own scrub trigger
 *      `top 75% → top 60%`. Words reveal one-by-one as they cross that
 *      band — "soft typing" feel.
 *   2. The bio is the EXCEPTION — whole-block reveal (opacity 0→1,
 *      blur 12→0) with trigger `top 80% → top 60%`.
 *   3. The btn (Reels) just sits there at opacity 1 — no reveal.
 *   4. Each photo gets ONE GSAP timeline anchored to its OWN photo-wrap
 *      with `start: top bottom, end: bottom top`. Two simultaneous
 *      tweens scrub across the trigger range:
 *        - `y: -50% → 50%` over the FULL range  → slow parallax (the
 *          photo translates DOWN by 100% of its own height as the
 *          wrap travels up the viewport, creating a slow-rise look).
 *        - `opacity 0→1, blur 20→0` over the FIRST 30% only → snappy
 *          reveal during the entry phase.
 *      Spatchcock and red use the SAME timeline; they only differ in
 *      where they're anchored (right-top vs left-bottom).
 *
 * Local tweaks:
 *   - Background `var(--bg)` so the seam between the hero's bottom
 *     fade and this section disappears.
 *   - "have we met?" headline + "you may not know me…" tagline get the
 *     per-word treatment too.
 *   - Closer is LEFT-aligned.
 *   - lumin_red photo on the LEFT — second photo so the section has
 *     visual hand-off instead of fading to empty.
 */

/* —— 1. Container ——
 * Bottom padding 80vh — long, so the photo timeline's y(-50% → 50%)
 * parallax maps across plenty of scroll for a slow per-pixel motion.
 *
 * Top padding (8vh) + section margin-top (-15vh) work together to
 * land "have we met?" in the upper-middle of the viewport at the
 * exact scroll position where the hero's role line ("Pole dancer ·
 * Science communicator · Performer") reaches the top:
 *
 *   - Hero is 100vh tall; the role line sits at ~viewport 60% inside
 *     the hero (content block is centered vertically, role is its
 *     last child).
 *   - Role hits the viewport top after ~60vh of page scroll.
 *
 *   - .about-reveal's natural top in the page is 100vh (right after
 *     the hero). With margin-top: -15vh, it starts at page Y 85vh —
 *     exactly where the hero's mask makes the photo fully transparent
 *     (--hero-fade-end: 85% in css/hero-story.css). The hero's own
 *     background fills that 85vh–100vh band with var(--bg) already,
 *     so overlapping it with our var(--bg) section is invisible: no
 *     hero content gets covered up.
 *
 *   - With padding-top 8vh, the headline sits at page Y 93vh. At
 *     scroll = 60vh (role at top), the headline is at viewport
 *     93 - 60 = 33vh — upper-middle. ✓
 *
 * Background: var(--bg), matching the site's page background and
 * (importantly) the hero-splash bottom — kills the dark seam between
 * the hero's bottom fade and this section. */
.about-reveal {
  position: relative;
  /* Sit ABOVE the hero in document stacking. The hero's
     .hero-splash__content child has z-index: 2 which (without isolation)
     would compete with our headline at z-index: 20. We give .hero-splash
     an explicit z-index of 1 + isolation: isolate (see hero-story.css)
     so its inner z-indexes are isolated, and put about-reveal at z-index: 5
     here so the parallax-rising headline never gets visually undercut by
     any hero leftover. */
  z-index: 5;
  /* margin-top: 0 — no negative overlap with the hero any more. The hero
     now fills the first 100vh edge-to-edge and this section starts cleanly
     at page y = 100vh. */
  min-height: 100vh;
  padding: 8vh 4rem 0;
  background: var(--bg);
  color: #f0f0f0;
  /* `isolation: isolate` keeps this section's inner z-indexes (photos z:5,
     headline z:20) contained without using clip-path. We removed clip-path
     because the finale block uses GSAP `pin` to lock lumin_red in viewport,
     and an ancestor clip-path was clipping the fixed-positioned pinned
     element. Overflow defaults to visible — the headline's `y: -30vh`
     parallax still escapes the section top naturally and reads above the
     hero (about-reveal z:5 > hero z:1). */
  isolation: isolate;
}


/* —— 2. "have we met?" — headline ——
 * Bigger + bolder than .about-reveal__statement below. Lowercase
 * preserved intentionally. Per-word reveal via the .about-reveal__word
 * spans wrap-injected by JS — initial state is set on those spans
 * (§ 7), not on this container, so the container itself stays at
 * opacity 1. */
.about-reveal__headline {
  position: relative;
  z-index: 20;
  width: 66.6%;
  max-width: 1180px;
  margin: 0;
  font-family: "DM Sans", "Inter", sans-serif;
  font-weight: 700;
  font-size: clamp(3.5rem, 9vw, 8rem);
  line-height: 1.0;
  letter-spacing: -0.04em;
  color: #f0f0f0;
}

/* —— 2b. Tagline — the spatchcock pun ——
 * Same per-word reveal model as the headline, just smaller and more
 * subtle. */
.about-reveal__tagline {
  position: relative;
  z-index: 20;
  width: 66.6%;
  max-width: 920px;
  margin: 1.2rem 0 6vh 0;
  font-family: "DM Sans", "Inter", sans-serif;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(0.95rem, 1.3vw, 1.25rem);
  line-height: 1.4;
  color: rgba(240, 240, 240, 0.62);
}

/* —— 3. Big statement ——
 * Wide editorial block; per-word reveal via spans. */
.about-reveal__statement {
  position: relative;
  z-index: 20;
  width: 66.6%;
  max-width: 1180px;
  /* Replaces the gap the (now removed) tagline used to provide between the
     headline and the statement. */
  margin-top: 5vh;
  font-family: "DM Sans", "Inter", sans-serif;
  font-weight: 400;
  font-size: clamp(1.8rem, 3.6vw, 3.4rem);
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: #f0f0f0;
}

/* Blocks 1–2 stack as paragraphs inside the big statement. */
.about-reveal__statement p {
  margin: 0 0 0.6em;
}
.about-reveal__statement p:last-child {
  margin-bottom: 0;
}

/* —— 4. Indented bio ——
 * Narrow column, hung 20% from the left, 12vh below the statement.
 * Reveals as a WHOLE BLOCK (not per-word) — the one place in the
 * section that diverges from the per-word recipe. */
.about-reveal__bio {
  position: relative;
  z-index: 20;
  width: 32%;
  margin-top: 12vh;
  margin-left: 20%;
  font-family: "DM Sans", "Inter", sans-serif;
  font-weight: 400;
  font-size: clamp(0.9rem, 1.6vw, 1.5rem);
  line-height: 1.6;
  letter-spacing: -0.005em;
  color: #f0f0f0;
}

/* Blocks 2–4 stack as paragraphs inside the bio column. */
.about-reveal__bio p {
  margin: 0 0 1.1em;
}
.about-reveal__bio p:last-child {
  margin-bottom: 0;
}

/* —— 5. Reels CTA ——
 * Aligned with the bio column (margin-left 20%). No reveal animation
 * — always visible. The magnet-cursor JS auto-attaches to the <a>. */
.about-reveal__btn {
  position: relative;
  z-index: 20;
  margin-top: 3.5rem;
  margin-left: 20%;
}

.about-reveal__link {
  display: inline-block;
  padding: 0.7em 1.6em;
  font-family: "DM Sans", "Inter", sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #f0f0f0;
  text-decoration: none;
  border: 1px solid rgba(240, 240, 240, 0.4);
  border-radius: 999px;
  transition: border-color 0.3s ease, color 0.3s ease, background 0.3s ease;
}

.about-reveal__link:hover,
.about-reveal__link:focus-visible {
  color: #0a0a0a;
  background: #f0f0f0;
  border-color: #f0f0f0;
}

/* —— 7. Per-word reveal initial state ——
 * Every <span class="about-reveal__word"> wrap-injected by JS starts
 * invisible + softly blurred. JS scrubs them to opacity 1, blur 0
 * one-by-one as each crosses the trigger band.
 *
 * `display: inline-block` is required for the per-element filter to
 * paint without breaking the inline text flow. */
.about-reveal__word {
  display: inline-block;
  opacity: 0;
  filter: blur(8px);
  will-change: filter, opacity;
}

/* Coarse-pointer devices drop the blur (heavy per-span blur kills
 * mobile GPU perf). */
@media (hover: none) and (pointer: coarse) {
  .about-reveal__word {
    filter: none;
  }
}

/* —— 7b. Whole-block reveal initial state ——
 * Only the bio uses this. Slightly heavier blur (12px) than the
 * per-word value because a block-sized blur reads weaker at the same
 * radius than a word-sized one. */
.about-reveal__bio[data-about-reveal-block] {
  opacity: 0;
  filter: blur(12px);
  will-change: filter, opacity;
}

@media (hover: none) and (pointer: coarse) {
  .about-reveal__bio[data-about-reveal-block] {
    filter: none;
  }
}

/* —— 8. Spatchcock photo (right, pill-arc on the left) ——
 * Absolute positioning + top:35vh + right:0. Width capped at
 * min(55vw, 780px). Border-radius 280px 0 0 280px gives the giant
 * arc on the side facing the copy.
 *
 * Initial state opacity 0 / blur(20px): the photo is invisible-blurred
 * until the GSAP timeline's first-30% reveal lerps it to clear. */
.about-reveal__photo-wrap {
  position: absolute;
  right: 0;
  /* The reveal opacity 0 → 1 inside the photo timeline handles
     "don't appear prematurely" — the photo is invisible until its
     wrap enters the viewport, so no need to push it further down. */
  top: 35vh;
  z-index: 5;
}

.about-reveal__photo {
  position: relative;
  display: block;
  width: min(55vw, 780px);
  overflow: hidden;
  will-change: transform, filter, opacity;
  opacity: 0;
  filter: blur(20px);
  border-radius: 280px 0 0 280px;
  /* 0 → 100: how far the x-ray scan has swept down. Animated by GSAP in
     js/about-reveal.js (§5b). Both the x-ray clip and the scan line read it. */
  --xray-reveal: 0;
}

/* Base photo sets the box size; the x-ray layer overlays it. */
.about-reveal__photo-img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* X-ray (anatomy) layer — sits on top of the base photo, clipped from the
   bottom so only the portion ABOVE the scan line shows. As --xray-reveal
   goes 0 → 100 the bottom inset shrinks 100% → 0, revealing top→bottom. */
.about-reveal__photo-img--xray {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  clip-path: inset(0 0 calc((100 - var(--xray-reveal)) * 1%) 0);
  /* cool clinical tint so it reads as an x-ray, not a second photo */
  filter: brightness(1.06) contrast(1.05);
  pointer-events: none;
}

/* Scan line — thin glowing bar riding the reveal boundary. */
.about-reveal__scanline {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--xray-reveal) * 1%);
  height: 2px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, transparent, rgba(120, 220, 255, 0.95), transparent);
  box-shadow: 0 0 18px 4px rgba(120, 220, 255, 0.55);
  opacity: 0;
  pointer-events: none;
}

/* —— 9. Mobile collapse ——
 * Below 768px: single column, photo flows in line below the copy
 * with top-only rounded corners. */
@media (max-width: 768px) {
  .about-reveal {
    margin-top: 0;
    padding: 12vh 1.5rem 0;
  }

  .about-reveal__headline {
    width: 100%;
    font-size: clamp(2.6rem, 13vw, 5rem);
  }

  .about-reveal__tagline {
    width: 100%;
    margin: 1rem 0 4vh 0;
    font-size: clamp(0.9rem, 3.2vw, 1.1rem);
  }

  .about-reveal__statement { width: 100%; }

  .about-reveal__bio {
    width: 100%;
    margin-left: 0;
    margin-top: 5vh;
  }

  .about-reveal__btn { margin-left: 0; }

  .about-reveal__photo-wrap {
    position: relative;
    left: auto;
    right: auto;
    top: auto;
    bottom: auto;
    margin-top: 6vh;
    width: 100%;
  }

  .about-reveal__photo {
    width: 100%;
    border-radius: 140px 140px 0 0;
  }
}

/* —— 10. Reduced-motion safety net ——
 * Even if JS fails or the user prefers reduced motion, keep the
 * section legible — no permanently-blurred copy, no permanently-
 * invisible photo. */
@media (prefers-reduced-motion: reduce) {
  .about-reveal__word,
  .about-reveal__bio[data-about-reveal-block] {
    opacity: 1;
    filter: none;
  }

  .about-reveal__photo { opacity: 1; filter: none; }
}
