/* ==========================================================================
   MOTION — reveal primitives

   Elements declare their animation with data-anim; js/motion.js drives them
   with GSAP + ScrollTrigger. The starting states live here so content is
   hidden before JS runs, and the .no-motion escape hatch below guarantees
   everything is visible if JS never runs at all or motion is unwanted.
   ========================================================================== */

[data-anim] { will-change: transform, opacity; }

[data-anim="fade"]      { opacity: 0; }
[data-anim="up"]        { opacity: 0; transform: translateY(45px); }
[data-anim="up-scale"]  { opacity: 0; transform: translateY(40px) scale(.96); }
[data-anim="split"]     { opacity: 0; }
[data-anim="stagger"] > * { opacity: 0; transform: translateY(40px); }

/* Once GSAP has taken control it manages opacity/transform itself; once the
   reveal has run we drop will-change so the compositor can let go. */
[data-anim].is-revealed { will-change: auto; }

/* --------------------------------------------------------------------------
   THE ESCAPE HATCH
   .no-motion is set on <html> by the inline head script when the user prefers
   reduced motion, and by motion.js if GSAP fails to load. Everything must be
   visible and static in that state — the booking funnel cannot depend on
   animation to be usable.
   -------------------------------------------------------------------------- */
.no-motion [data-anim],
.no-motion [data-anim] > *,
.no-motion [data-anim="stagger"] > * {
  opacity: 1 !important;
  transform: none !important;
}
.no-motion .hero__bg img,
.no-motion .page-hero__bg img,
.no-motion .feature__bg img { height: 100%; }
.no-motion .scroll-bar { display: none; }

@media (prefers-reduced-motion: reduce) {
  [data-anim],
  [data-anim] > *,
  [data-anim="stagger"] > * {
    opacity: 1 !important;
    transform: none !important;
  }
  .hero__bg img, .page-hero__bg img, .feature__bg img { height: 100%; }
  .scroll-bar { display: none; }
}

/* Line-mask wrapper injected by SplitType handling in motion.js */
.line-mask { display: block; overflow: hidden; }
