/* The Design Mate · motion layer (Milo owns this file).
   Everything that hides or moves content sits under .has-motion, which js/motion.js adds only when
   JS runs, IntersectionObserver exists and the visitor has not asked for reduced motion.
   No JS / reduced motion / ?render=1: none of these rules apply and the page is static and complete.
   Guard rails (DESIGN.md §9): transform/opacity only, no scroll-jacking, no pinning, no loops, no layout shift. */

:root {
  --m-ease: cubic-bezier(.22, 1, .36, 1);      /* house curve: confident arrival */
  --m-spring: cubic-bezier(.34, 1.45, .64, 1); /* small overshoot, Mates hover only */
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }

  /* Press feedback */
  .btn, .nav__cta { transition: background-color .35s var(--ease), transform .35s var(--ease); }
  .btn:active { transform: scale(.98); }
  .nav__cta:active { transform: scale(.97); }

  /* Base fade-and-rise once (approved v3 mock-up) */
  .has-motion [data-reveal] { opacity: 0; transform: translateY(28px); transition: opacity .9s var(--m-ease), transform 1.1s var(--m-ease); }
  .has-motion [data-reveal].is-in { opacity: 1; transform: none; }

  /* Sticky nav: transparent on the hero, glass fades in once content slides under it.
     The glass lives on a pseudo-element so only its opacity animates (no backdrop-filter transition). */
  .has-motion .nav { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; isolation: isolate; box-shadow: none; }
  .has-motion .nav::before {
    content: ""; position: absolute; inset: 0; z-index: -1; opacity: 0; pointer-events: none;
    background: rgba(255, 255, 255, .95); box-shadow: 0 1px 0 var(--line);
    transition: opacity .5s var(--m-ease);
  }
  @supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    .has-motion .nav::before { background: rgba(255, 255, 255, .78); -webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px); }
  }
  .has-motion .nav.is-scrolled::before { opacity: 1; }

  /* Hero: JS writes the scroll transforms; these only promote the layers while motion is on */
  .has-motion .hero__mates, .has-motion .hero__text { will-change: transform, opacity; transform-origin: 50% 0; }

  /* Five Mates: the list itself stays put; the cards rise in one after another */
  .has-motion .mates[data-reveal] { opacity: 1; transform: none; }
  .has-motion .mate { opacity: 0; transform: translateY(44px); transition: opacity .9s var(--m-ease), transform 1.2s var(--m-ease); }
  .has-motion .mates.is-in .mate { opacity: 1; transform: none; }
  .has-motion .mates .mate:nth-child(2) { transition-delay: 90ms; }
  .has-motion .mates .mate:nth-child(3) { transition-delay: 180ms; }
  .has-motion .mates .mate:nth-child(4) { transition-delay: 270ms; }
  .has-motion .mates .mate:nth-child(5) { transition-delay: 360ms; }

  /* Mate scene images: scaled 10% inside their clipping wrapper so JS can drift them ±4% */
  .has-motion [data-parallax="mate"] img { transform: scale(1.1); }

  /* Mate hover / tap: a small lift and tilt, each Mate leaning its own way */
  .mate { --tilt: -1.6deg; }
  .mate:nth-child(2n) { --tilt: 1.4deg; }
  .mate:nth-child(3) { --tilt: -1deg; }
  .mate__media { transition: transform .55s var(--m-spring); }
  @media (hover: hover) and (pointer: fine) {
    .mate:hover .mate__media { transform: translateY(-8px) rotate(var(--tilt)); }
  }
  .mate.is-pop .mate__media { animation: mate-pop .6s var(--m-ease); }
  @keyframes mate-pop {
    0% { transform: none; }
    35% { transform: translateY(-9px) rotate(var(--tilt)) scale(1.015); }
    70% { transform: translateY(2px) rotate(calc(var(--tilt) * -.3)); }
    100% { transform: none; }
  }

  /* How it works: the numerals rise in sequence, each line follows its numeral */
  .has-motion .steps[data-reveal] { opacity: 1; transform: none; }
  .has-motion .steps li { opacity: 0; transition: opacity .8s var(--m-ease); }
  .has-motion .steps__n { transform: translateY(.42em); transition: transform 1.1s var(--m-ease); }
  .has-motion .steps.is-in li { opacity: 1; }
  .has-motion .steps.is-in .steps__n { transform: none; }
  .has-motion .steps li:nth-child(2), .has-motion .steps li:nth-child(2) .steps__n { transition-delay: 180ms; }
  .has-motion .steps li:nth-child(3), .has-motion .steps li:nth-child(3) .steps__n { transition-delay: 360ms; }

  /* Every detail, checked: the four items rise in sequence, like the How it works numerals */
  .has-motion .checks[data-reveal] { opacity: 1; transform: none; }
  .has-motion .checks li { opacity: 0; transform: translateY(24px); transition: opacity .8s var(--m-ease), transform 1.1s var(--m-ease); }
  .has-motion .checks.is-in li { opacity: 1; transform: none; }
  .has-motion .checks li:nth-child(2) { transition-delay: 140ms; }
  .has-motion .checks li:nth-child(3) { transition-delay: 280ms; }
  .has-motion .checks li:nth-child(4) { transition-delay: 420ms; }

  /* Before / after: the finished post starts tucked behind the phone photo; JS slides them apart */
  .has-motion .ba__item:first-child { position: relative; z-index: 2; }
  .has-motion .ba__media { will-change: transform; }

  /* $200: grows into place once, from slightly small (no counting, so it never shows a wrong price) */
  .has-motion .price__n { display: inline-block; opacity: 0; transform: scale(.84); transform-origin: 50% 70%; transition: opacity 1s var(--m-ease), transform 1.6s var(--m-ease); transition-delay: .12s; }
  .has-motion .price.is-in .price__n { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  [data-reveal], .mate, .steps li, .checks li, .price__n { opacity: 1 !important; transform: none !important; }
}
