/* motion.css — parallax, reveals, the flow scrollytelling and the stamps.
 * Only transform and opacity animate. Reduced motion switches everything off at the end. */

/* ---------- Hero parallax ----------
 * Depth is the fraction of the scrolled distance a layer lags behind the page: the grid
 * (depth-4) barely moves, the stage (depth-2) almost keeps up with the copy.
 * The stage is one layer, card and stamp and chips together: they are positioned against each
 * other, so a depth between them would slide the chips and the stamp across the card's text. */
.hero__layer { will-change: transform; }
.depth-2 { --depth: .3; }
.depth-3 { --depth: .5; }
.depth-4 { --depth: .7; }

/* On phones the hero has no room for the lag: the stage sits at the bottom of a 100svh section
 * with a few rem under it, so any depth slides it straight into the clipped edge and the band
 * below cuts a chip in half. There the stage travels with the page and the grid and the
 * watermark carry the depth alone. --depth is what both paths read, so this switches the
 * native animation and the motion.js fallback together. */
@media (max-width: 59.99em) {
  .hero__stage { --depth: 0; will-change: auto; }
}

@supports (animation-timeline: scroll()) {
  .hero__layer {
    animation: parallax linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 100vh;
  }
  @keyframes parallax {
    to { transform: translate3d(0, calc(var(--depth) * 100vh), 0); }
  }
  /* ?motion=js: motion.js drives the layers instead, for testing the fallback. */
  :root.motion-js .hero__layer { animation: none; }
}

/* ---------- Reveals ---------- */
.js .reveal { opacity: 0; translate: 0 18px; transition: opacity .7s cubic-bezier(.2, .7, .2, 1), translate .7s cubic-bezier(.2, .7, .2, 1); }
.js .reveal.is-in { opacity: 1; translate: 0 0; }
.d1 { transition-delay: .08s; }
.d2 { transition-delay: .16s; }
.d3 { transition-delay: .24s; }
.d4 { transition-delay: .32s; }

/* ---------- Stamps ---------- */
@keyframes stamp {
  0%   { opacity: 0; transform: scale(1.6) rotate(-14deg); }
  60%  { opacity: 1; transform: scale(.94) rotate(-6deg); }
  100% { opacity: 1; transform: scale(1) rotate(-7deg); }
}
.hero__stamp { rotate: none; animation: stamp .55s cubic-bezier(.2, .9, .3, 1.2) 1.1s both; }

/* ---------- Matrix demo: card slides in → matching row → levels, one by one → stamp ----------
 * site.css holds the final states. Under .js they are wound back and replayed by transitions
 * when the block reveals (.is-in comes from the same observer as every other reveal). */
.js .mx__card { opacity: 0; transform: translateX(-24px); transition: opacity .5s ease-out, transform .5s ease-out; }
.js .mx__hit td { background: transparent; transition: background-color .4s .7s; }
.js .mx__cell span { background: transparent; color: inherit; transition: background-color .3s, color .3s; }
.js .mx__cell span::before { opacity: 0; transition: opacity .3s; }
.js .mx__stamp { opacity: 0; }
.js .mx.is-in .mx__card { opacity: 1; transform: none; }
.js .mx.is-in .mx__hit td { background: var(--primary-soft); }
.js .mx.is-in .mx__cell span { background: var(--ok-soft); color: var(--ok); }
.js .mx.is-in .mx__cell span::before { opacity: 1; }
.js .mx.is-in .mx__cell--1 span, .js .mx.is-in .mx__cell--1 span::before { transition-delay: 1.2s; }
.js .mx.is-in .mx__cell--2 span, .js .mx.is-in .mx__cell--2 span::before { transition-delay: 1.8s; }
.js .mx.is-in .mx__cell--3 span, .js .mx.is-in .mx__cell--3 span::before { transition-delay: 2.4s; }
.js .mx.is-in .mx__stamp { rotate: none; animation: stamp .55s cubic-bezier(.2, .9, .3, 1.2) 3s both; }

/* ---------- Flow: the stamp lands on the diagram once the approval step is reached ---------- */
.flow:not([data-step="1"]) .flow__stamp { rotate: none; animation: stamp .55s cubic-bezier(.2, .9, .3, 1.2) .2s both; }

/* ---------- Reduced motion: nothing moves, everything is in its final state ---------- */
@media (prefers-reduced-motion: reduce) {
  .hero__layer { animation: none !important; transform: none !important; will-change: auto; }
  .reveal { opacity: 1 !important; translate: none !important; transition: none !important; }
  .hero__stamp, .mx__stamp, .flow:not([data-step="1"]) .flow__stamp, .mx__card { animation: none !important; transition: none !important; opacity: 1 !important; transform: none !important; }
  .hero__stamp, .mx__stamp, .flow__stamp { rotate: -7deg; }
  .mx__hit td { background: var(--primary-soft) !important; transition: none !important; }
  .mx__cell span { background: var(--ok-soft) !important; color: var(--ok) !important; transition: none !important; }
  .mx__cell span::before { opacity: 1 !important; transition: none !important; }
  .flow__node, .flow__num, .flow__detail, .flow__step { transition: none !important; }
}
