/* ==========================================================================
   I'm Here — shared motion layer
   Pairs with /assets/motion.js. The <html> element only gets the `motion`
   class from an inline snippet in each page's <head>, so with JavaScript off
   nothing is ever hidden. If motion.js fails to load, the same snippet adds
   `motion-off` after two seconds and every resting state is dropped.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  /* Resting (pre-reveal) state. Keep this list in sync with SELECTOR in
     motion.js — CSS owns the hidden state so nothing flashes before the
     observer runs. */
  .motion:not(.motion-off) .hero > *:not(.hero-rings):not(.wrap):not(.hero-grid),
  .motion:not(.motion-off) .hero .wrap > *,
  .motion:not(.motion-off) .hero-grid > *,
  .motion:not(.motion-off) .why-inner > *,
  .motion:not(.motion-off) .snippet,
  .motion:not(.motion-off) .solution-inner > *,
  .motion:not(.motion-off) .bottom-cta > *,
  .motion:not(.motion-off) .contact-inner > *,
  .motion:not(.motion-off) .why-text > *,
  .motion:not(.motion-off) .sc,
  .motion:not(.motion-off) .sec-eyebrow,
  .motion:not(.motion-off) .sec-title,
  .motion:not(.motion-off) .sec-body,
  .motion:not(.motion-off) .step,
  .motion:not(.motion-off) .intent-card,
  .motion:not(.motion-off) .intent-note,
  .motion:not(.motion-off) .safe-card,
  .motion:not(.motion-off) .app-text > *,
  .motion:not(.motion-off) .phone-stage,
  .motion:not(.motion-off) .photo-stage,
  .motion:not(.motion-off) .pf,
  .motion:not(.motion-off) .pass-cta-box,
  .motion:not(.motion-off) .ben,
  .motion:not(.motion-off) .venue-header > *,
  .motion:not(.motion-off) .portal-box,
  .motion:not(.motion-off) .pr,
  .motion:not(.motion-off) .cta-section > *,
  .motion:not(.motion-off) .section-head,
  .motion:not(.motion-off) .problem-grid > div,
  .motion:not(.motion-off) .flow-step,
  .motion:not(.motion-off) .vibe-chip,
  .motion:not(.motion-off) .vibes-foot,
  .motion:not(.motion-off) .guest-card,
  .motion:not(.motion-off) .toss-rise,
  .motion:not(.motion-off) .toss-line,
  .motion:not(.motion-off) .couple-grid > div,
  .motion:not(.motion-off) .benefit-item,
  .motion:not(.motion-off) .offer,
  .motion:not(.motion-off) .lead > *,
  .motion:not(.motion-off) .faq-item,
  .motion:not(.motion-off) .cta-band-inner > *,
  .motion:not(.motion-off) .footer-inner > * {
    opacity: 0;
    /* Uses the independent `translate` / `scale` properties rather than
       `transform`, so hover lifts and the float animation keep their own
       transform untouched — and so the reveal below can win outright. */
    translate: 0 22px;
    transition:
      opacity 0.75s cubic-bezier(0.22, 0.61, 0.36, 1),
      translate 0.75s cubic-bezier(0.22, 0.61, 0.36, 1),
      scale 0.75s cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  /* Sideways entrances for two-column blocks */
  .motion:not(.motion-off) .why-text > *,
  .motion:not(.motion-off) .app-text > *,
  .motion:not(.motion-off) .problem-grid > div:first-child,
  .motion:not(.motion-off) .couple-grid > div:first-child {
    translate: -18px 14px;
  }
  .motion:not(.motion-off) .phone-stage,
  .motion:not(.motion-off) .photo-stage,
  .motion:not(.motion-off) .problem-grid > div:last-child,
  .motion:not(.motion-off) .couple-grid > div:last-child {
    translate: 18px 14px;
  }

  /* Cards and chips pop rather than slide */
  .motion:not(.motion-off) .sc,
  .motion:not(.motion-off) .intent-card,
  .motion:not(.motion-off) .safe-card,
  .motion:not(.motion-off) .guest-card,
  .motion:not(.motion-off) .vibe-chip,
  .motion:not(.motion-off) .ben,
  .motion:not(.motion-off) .pf,
  .motion:not(.motion-off) .flow-step {
    translate: 0 16px;
    scale: 0.97;
  }

  /* Revealed. Marked !important so it always beats the resting rules above,
     whatever their specificity — this is what keeps content on screen. */
  .motion .is-visible {
    opacity: 1 !important;
    translate: none !important;
    scale: none !important;
  }

  /* ------------------------------------------------------------------
     Ambient motion
     ------------------------------------------------------------------ */

  /* Phone mockups drift gently once they have arrived. This runs on the inner
     element, never the stage, so the float's `transform` and the reveal's
     `translate` stay on separate elements and never overwrite each other. */
  @keyframes ih-float {
    0%,
    100% {
      transform: translateY(0);
    }
    50% {
      transform: translateY(-11px);
    }
  }
  .phone-shell,
  .photo-stage img {
    animation: ih-float 7s ease-in-out infinite;
  }
  /* Offset so the two phones on a page aren't bobbing in lockstep */
  .match-photo img {
    animation-duration: 8.4s;
    animation-delay: -2.6s;
  }

  /* The wave button breathes, so the core gesture reads as live */
  @keyframes ih-wave-pulse {
    0%,
    100% {
      box-shadow: 0 0 0 0 rgba(198, 126, 61, 0.45);
    }
    60% {
      box-shadow: 0 0 0 10px rgba(198, 126, 61, 0);
    }
  }
  .ph-wave,
  .wp-wave {
    animation: ih-wave-pulse 3.4s ease-out infinite;
  }

  /* Live indicators blink */
  @keyframes ih-blink {
    0%,
    100% {
      opacity: 1;
    }
    50% {
      opacity: 0.3;
    }
  }
  .wp-live-dot,
  .hero-tag-dot {
    animation: ih-blink 2.2s ease-in-out infinite;
  }
}

/* Navigation gains depth once the page scrolls (safe under reduced motion) */
nav,
header.site {
  transition:
    padding 0.3s ease,
    box-shadow 0.3s ease;
}
.is-scrolled nav,
.is-scrolled header.site {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
}

/* A stage wraps a mockup so the reveal transform and the float animation
   never fight over the same element */
.phone-stage {
  flex-shrink: 0;
}

/* Flow icons lift on hover */
.flow-step .flow-icon {
  transition:
    transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1),
    box-shadow 0.3s ease;
}
.flow-step:hover .flow-icon {
  transform: translateY(-6px) scale(1.05);
  box-shadow: 0 14px 34px rgba(198, 126, 61, 0.32);
}
