/**
 * Alpine Motion — CSS-first animation system (GSAP replacement).
 *
 * Pairs with assets/js/alpine-motion.js, which adds `.is-inview` to reveal
 * targets and assigns `--i` / `--wi` stagger indexes. All rules that pre-hide
 * content are gated behind `html.alp-cssmotion` (set server-side only on
 * pages flipped to the CSS system) so unflipped GSAP pages are unaffected
 * during the rollout, and no-JS visitors on flipped pages… still get the
 * same behaviour GSAP had (pre-hide + reduced-motion override).
 *
 * GSAP ease equivalents:
 *   power2.out   → cubic-bezier(0.25, 0.46, 0.45, 0.94)
 *   power3.out   → cubic-bezier(0.215, 0.61, 0.355, 1)
 *   power2.inOut → cubic-bezier(0.455, 0.03, 0.515, 0.955)
 *   back.out(2)  → cubic-bezier(0.34, 1.8, 0.64, 1)
 *   expo.out     → cubic-bezier(0.19, 1, 0.22, 1)
 */

:root {
  --alp-ease-out2: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --alp-ease-out3: cubic-bezier(0.215, 0.61, 0.355, 1);
  --alp-ease-inout2: cubic-bezier(0.455, 0.03, 0.515, 0.955);
  --alp-ease-back2: cubic-bezier(0.34, 1.8, 0.64, 1);
  --alp-ease-expo: cubic-bezier(0.19, 1, 0.22, 1);
}

/* ==========================================================================
   Shared keyframes
   ========================================================================== */

/* Load-time entrance: rise + fade. Per-page tuning via
   --alp-rise-y (offset) and the animation shorthand (duration/delay/ease). */
@keyframes alp-rise {
  from { opacity: 0; transform: translateY(var(--alp-rise-y, 30px)); }
  to { opacity: 1; transform: none; }
}

/* ==========================================================================
   Generic reveal classes (were driven by gsap-observer.js)
   ========================================================================== */

/* Section fade-in — gsap.from(opacity:0, y:24, .5s power2.out) */
html.alp-cssmotion .gsap-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.5s var(--alp-ease-out2), transform 0.5s var(--alp-ease-out2);
}
html.alp-cssmotion .gsap-reveal.is-inview {
  opacity: 1;
  transform: none;
}

/* Fade up — gsap.from(opacity:0, y:30, .6s power2.out) */
html.alp-cssmotion .gsap-fade-up {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.6s var(--alp-ease-out2), transform 0.6s var(--alp-ease-out2);
}
html.alp-cssmotion .gsap-fade-up.is-inview {
  opacity: 1;
  transform: none;
}

/* Stagger children — gsap.from(children, opacity:0, y:20, .5s, stagger .08) */
html.alp-cssmotion .gsap-stagger > * {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.5s var(--alp-ease-out2), transform 0.5s var(--alp-ease-out2);
  transition-delay: calc(var(--i, 0) * 0.08s);
}
html.alp-cssmotion .gsap-stagger.is-inview > * {
  opacity: 1;
  transform: none;
}

/* Split-text word reveal — words rise from an overflow mask
   (gsap.from(y:100%, .6s power3.out, stagger .05)) */
.gsap-split .word,
.alp-fn-split .word,
.alp-menu-split .word {
  overflow: hidden;
  display: inline-block;
}
.gsap-split .word-inner,
.alp-fn-split .word-inner,
.alp-menu-split .word-inner {
  display: inline-block;
}
html.alp-cssmotion .gsap-split .word-inner {
  transform: translateY(110%);
  transition: transform 0.6s var(--alp-ease-out3);
  transition-delay: calc(var(--wi, 0) * 0.05s);
}
html.alp-cssmotion .gsap-split.is-inview .word-inner {
  transform: none;
}

/* Editorial images — gsap.from(scale:1.06, opacity:0, .7s, stagger .12) */
html.alp-cssmotion .gsap-images .alp-editorial__img {
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 0.7s var(--alp-ease-out2), transform 0.7s var(--alp-ease-out2);
  transition-delay: calc(var(--i, 0) * 0.12s);
}
html.alp-cssmotion .gsap-images.is-inview .alp-editorial__img {
  opacity: 1;
  transform: none;
}

/* Card hover lift — was a JS mouseenter/mouseleave tween */
html.alp-cssmotion .gsap-card {
  transition: transform 0.25s var(--alp-ease-out2), box-shadow 0.25s var(--alp-ease-out2);
}
html.alp-cssmotion .gsap-card:hover {
  transform: translateY(-4px);
}

/* ==========================================================================
   Home / block section reveals (were block view.js + home-animations.js)
   ========================================================================== */

/* Stats ribbon — items rise (stagger .08), dividers grow (scaleY, stagger .06) */
html.alp-cssmotion .alp-home-stats .alp-home-stats__item {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.45s var(--alp-ease-out2), transform 0.45s var(--alp-ease-out2);
  transition-delay: calc(var(--i, 0) * 0.08s);
}
html.alp-cssmotion .alp-home-stats.is-inview .alp-home-stats__item {
  opacity: 1;
  transform: none;
}
html.alp-cssmotion .alp-home-stats .alp-home-stats__divider {
  opacity: 0;
  transform: scaleY(0);
  transition: opacity 0.3s var(--alp-ease-out2), transform 0.3s var(--alp-ease-out2);
  transition-delay: calc(var(--i, 0) * 0.06s);
}
html.alp-cssmotion .alp-home-stats.is-inview .alp-home-stats__divider {
  opacity: 1;
  transform: none;
}

/* CTA grid entrance — gsap.from(opacity:0, y:16, .4s, stagger .1) */
html.alp-cssmotion .alp-cta-grid .alp-cta-card {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.4s var(--alp-ease-out2), transform 0.4s var(--alp-ease-out2);
  transition-delay: calc(var(--i, 0) * 0.1s);
}
html.alp-cssmotion .alp-cta-grid.is-inview .alp-cta-card {
  opacity: 1;
  transform: none;
}
html.alp-cssmotion .alp-cta-grid.is-inview .alp-cta-card:hover {
  transform: translateY(-4px);
  transition-delay: 0s;
}

/* CTA card sheen sweep — was gsap animating --alp-cta-sheen-x/-opacity.
   The ::before consumes the vars, so transition the pseudo itself: sweep in
   on hover (transform .55s / opacity .18s); on leave, snap the sheen back
   (no transform transition) while opacity fades — matching gsap.set + fade. */
html.alp-cssmotion .alp-cta-card::before {
  transition: opacity 0.18s ease-out;
}
html.alp-cssmotion .alp-cta-card:hover::before {
  transition: transform 0.55s var(--alp-ease-out2), opacity 0.18s ease-out;
}
html.alp-cssmotion .alp-cta-card:hover {
  --alp-cta-sheen-x: 120%;
  --alp-cta-sheen-opacity: 1;
}

/* Interlude quote — gsap.from(opacity:0, y:20, .6s) at top 60% */
html.alp-cssmotion .alp-home-interlude blockquote p {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s var(--alp-ease-out2), transform 0.6s var(--alp-ease-out2);
}
html.alp-cssmotion .alp-home-interlude.is-inview blockquote p {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Mobile nav overlay item stagger (was a gsap.fromTo in the observer)
   ========================================================================== */
html.alp-cssmotion .alp-mobile-overlay .alp-mobile-overlay__menu li,
html.alp-cssmotion .alp-mobile-overlay .alp-mobile-overlay__book {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.35s var(--alp-ease-out2), transform 0.35s var(--alp-ease-out2);
  transition-delay: calc(0.1s + var(--i, 0) * 0.06s);
}
html.alp-cssmotion .alp-mobile-overlay.is-open .alp-mobile-overlay__menu li,
html.alp-cssmotion .alp-mobile-overlay.is-open .alp-mobile-overlay__book {
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Scroll-driven animations (were ScrollTrigger scrub tweens)
   Progressive enhancement: unsupported browsers get static images.
   ========================================================================== */
@supports (animation-timeline: view()) {
  /* Generic parallax while the element crosses the viewport
     (= ScrollTrigger "top bottom → bottom top", ease none).
     Tune per element with --alp-parallax-from / --alp-parallax-to, or for
     the common "yPercent ±base×speed" pattern set --alp-parallax-base and
     let alpine-motion.js map data-speed → --alp-speed. */
  @keyframes alp-parallax-y {
    from { transform: translateY(var(--alp-parallax-from, calc(-1 * var(--alp-parallax-base, 10%) * var(--alp-speed, 1)))); }
    to { transform: translateY(var(--alp-parallax-to, calc(var(--alp-parallax-base, 10%) * var(--alp-speed, 1)))); }
  }

  /* Ken Burns scale while scrolling away from a full-viewport hero
     (= ScrollTrigger "top top → bottom top"). */
  @keyframes alp-kenburns {
    from { transform: scale(var(--alp-kb-from, 1.05)); }
    to { transform: scale(var(--alp-kb-to, 1.2)); }
  }

  html.alp-cssmotion .gsap-parallax {
    animation: alp-parallax-y linear both;
    animation-timeline: view();
  }

  /* Interlude media parallax — was gsap.fromTo(yPercent -15 → 5, scrub:true).
     IMPORTANT pattern: parallax images sit inside overflow:hidden crop
     sections, and overflow:hidden ancestors hijack view() (they count as
     scroll containers). So the SECTION declares a named view-timeline
     (its own scroll container is the viewport) and the inner media
     animates against that name. Reuse `--alp-vt` for every parallax. */
  html.alp-cssmotion .alp-home-interlude {
    view-timeline-name: --alp-vt;
  }
  html.alp-cssmotion .alp-home-interlude__media {
    --alp-parallax-from: -15%;
    --alp-parallax-to: 5%;
    animation: alp-parallax-y linear both;
    animation-timeline: --alp-vt;
  }
}

/* ==========================================================================
   JS-driven components that swapped gsap tweens for CSS transitions
   ========================================================================== */

/* Hero video playlist crossfades (block view.js + alpine-motion.js rotators) */
html.alp-cssmotion .alp-hero video,
html.alp-cssmotion #alp-hero-video,
html.alp-cssmotion video[data-videos] {
  transition: opacity 0.6s var(--alp-ease-inout2);
}

/* CPT carousel slide (alpine-cpt-carousel/view.js) */
html.alp-cssmotion .alp-carousel__track {
  transition: transform 0.5s var(--alp-ease-inout2);
}

/* ==========================================================================
   Reduced motion — everything visible, nothing moves
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.alp-cssmotion .gsap-reveal,
  html.alp-cssmotion .gsap-fade-up,
  html.alp-cssmotion .gsap-stagger > *,
  html.alp-cssmotion .gsap-split .word-inner,
  html.alp-cssmotion .gsap-images .alp-editorial__img,
  html.alp-cssmotion .alp-home-stats .alp-home-stats__item,
  html.alp-cssmotion .alp-home-stats .alp-home-stats__divider,
  html.alp-cssmotion .alp-cta-grid .alp-cta-card,
  html.alp-cssmotion .alp-home-interlude blockquote p,
  html.alp-cssmotion .alp-mobile-overlay .alp-mobile-overlay__menu li,
  html.alp-cssmotion .alp-mobile-overlay .alp-mobile-overlay__book {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  html.alp-cssmotion .gsap-card,
  html.alp-cssmotion .gsap-card:hover,
  html.alp-cssmotion .alp-cta-card:hover {
    transform: none !important;
    transition: none !important;
  }
  html.alp-cssmotion .gsap-parallax,
  html.alp-cssmotion .alp-home-interlude__media {
    animation: none !important;
  }
  html.alp-cssmotion .alp-hero video,
  html.alp-cssmotion #alp-hero-video,
  html.alp-cssmotion video[data-videos],
  html.alp-cssmotion .alp-carousel__track {
    transition: none !important;
  }
}
