/* ================================================================
   Casa Lujuria — GSAP motion layer (homepage)
   Loaded alongside enhance.css. Only active when <html class="gm">.
   .gm is set by an inline head script ONLY when motion is safe
   (not reduced-motion). If GSAP fails to load, motion.js strips .gm
   and falls back to the legacy one-shot reveals.
   ================================================================ */

/* ---- Lenis required styles (self-hosted smooth scroll) ---- */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ================================================================
   When GSAP owns the page (.gm), hand it a clean slate:
   neutralize the legacy CSS out-state transforms so GSAP sets the
   initial pose itself. Elements still start hidden (opacity:0) so
   there is no flash of unstyled, un-animated content.
   ================================================================ */
html.gm .feat-grid .reveal,
html.gm .grid .reveal,
html.gm .steps-grid .reveal,
html.gm .marquee-sec.reveal,
html.gm .stats.reveal,
html.gm .cta-band.reveal,
html.gm .trust-sec .reveal,
html.gm .faq .reveal,
html.gm .show-copy .reveal,
html.gm .feat-head.reveal {
  transform: none;
}

/* GSAP-owned elements: start invisible, GSAP reveals them.
   (Headings use clip-path reveal and stay in-flow.) */
html.gm .gm-hide { opacity: 0; will-change: opacity, transform; }
html.gm .gm-head { opacity: 0; clip-path: inset(0 0 105% 0); will-change: clip-path, opacity; }

/* Deck-spread signature: the shortlist cards get a warm ring while
   they settle, distinct from the sibling site's plain fan. */
html.gm .feat-card { transform-origin: 50% 80%; }
html.gm .feat-card.gm-landing { box-shadow: 0 30px 80px rgba(0,0,0,.45), 0 0 0 1px rgba(242,178,51,.35); }

/* Pinned "how we test" band: dim until its moment, then light up.
   motion.js scrubs --lit 0 -> 1 across the pin. */
html.gm .steps-grid.gm-seq .step-card {
  opacity: calc(.34 + .66 * var(--lit, 0));
  transform: translateY(calc((1 - var(--lit, 0)) * 22px)) scale(calc(.975 + .025 * var(--lit, 0)));
  transition: none;
}
html.gm .steps-grid.gm-seq .step-card .step-n { opacity: var(--lit, 0); transform: none; }

/* Small parallax drift room for the marquee so it feels alive under Lenis */
html.gm .marquee-row { will-change: transform; }

/* Brand card-fan: under .gm, GSAP owns the transforms (the CSS arc is the
   reduced-motion / no-JS fallback). Neutralize the CSS arc so they don't fight. */
html.gm .ls-fan-stage .ls-fcard { transform: none; }

/* Section-two headline: kill the dead on-load word animation and hide the
   heading at parse so motion.js can clip-wipe it in when scrolled to. */
html.gm .show-h2 { opacity: 0; }
html.gm .show-h2 .word { animation: none !important; opacity: 1 !important; transform: none !important; }

/* Progress bar already defined in enhance.css (#ls-progress) — leave as-is. */

/* If motion.js runs it removes gm-hide/gm-head per element as it wires
   them, so nothing stays hidden. The JS also has a hard safety net that
   strips .gm and shows everything if GSAP fails to load. */
