/* ui_kit motion layer. Pairs with motion.js. Everything animated is gated on
   prefers-reduced-motion: no-preference; without JS (no .js-motion) content stays visible. */
:root {
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --reveal-dur: 700ms;
  --reveal-delay: 0ms;
}

@media (prefers-reduced-motion: no-preference) {
  /* Reveal: IntersectionObserver adds .is-in */
  html.js-motion [data-reveal] {
    opacity: 0;
    transition:
      opacity var(--reveal-dur) var(--ease) var(--reveal-delay),
      transform var(--reveal-dur) var(--ease) var(--reveal-delay);
  }
  html.js-motion [data-reveal="fade"] { transform: translate3d(0, 16px, 0); }
  /* mask-up: the wrapper (what the observer watches) clips its children as they slide up.
     Do not clip-path the wrapper itself: Chrome then reports it as never intersecting.
     It clips shadows, so use fade for shadowed cards. */
  html.js-motion [data-reveal="mask-up"] { opacity: 1; overflow: hidden; }
  html.js-motion [data-reveal="mask-up"] > * {
    transform: translate3d(0, 105%, 0);
    transition: transform var(--reveal-dur) var(--ease) var(--reveal-delay);
  }
  html.js-motion [data-reveal="mask-up"].is-in > * { transform: none; }
  html.js-motion [data-reveal].is-in { opacity: 1; transform: none; }

  /* Parallax: native scroll-driven animation; motion.js sets .plx-js (everywhere) or [data-plx-js] (per layer) when it must take over. */
  @supports (animation-timeline: view()) {
    html:not(.plx-js) [data-parallax]:not([data-plx-js]) {
      --plx-dist: calc(var(--plx-speed, 0.2) * 100px);
      animation: ui-plx linear both;
      animation-timeline: view();
      animation-range: cover;
    }
    html:not(.plx-js) [data-parallax]:not([data-plx-js])[data-parallax-range="exit"] { animation-range: exit; }
  }
}

@keyframes ui-plx {
  from { transform: translate3d(0, calc(var(--plx-dist) * -1), 0); }
  to   { transform: translate3d(0, var(--plx-dist), 0); }
}

/* Tilt: pointer vars are set by motion.js. Put TiltCard inside a Reveal, never on the same element. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  [data-tilt] {
    transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg));
    transition: transform 450ms var(--ease);
    will-change: transform;
  }
  [data-tilt].is-tilting { transition-duration: 90ms; }
}

/* First-paint handoff from a static HTML shell to the mounted app: html.ui-no-intro skips entrance
   animations so content that is already on screen does not blink out and fade back in. */
html.ui-no-intro [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
html.ui-no-intro [data-reveal] > * { transform: none !important; transition: none !important; }
