/* scroll-reveal — shared visual layer for site fade/slide-in on scroll.
 *
 * Usage:
 *   <h2 class="reveal">...</h2>                  fade up
 *   <div class="reveal" data-reveal="left">...   slide in from left
 *   <ul class="reveal-stagger">                  staggered children
 *     <li class="reveal">...</li>
 *     <li class="reveal">...</li>
 *   </ul>
 *
 * The base .reveal hides + sets up the transition. The IntersectionObserver
 * in scroll-reveal.js adds .is-visible when the element enters the viewport,
 * which animates to the resting state. Reduced motion users see no animation
 * but get the same final state.
 *
 * The pre-paint script in <head> adds .reveal-ready to <html> only when
 * reduced-motion is OFF; without that class, .reveal stays at its visible
 * resting state so a JS failure or slow load doesn't leave content invisible.
 */

/* Fallback: when JS hasn't run, content is fully visible (no FOUC of empty
 * pages). The reveal-ready class is set by the pre-paint script in <head>;
 * only then does .reveal hide its content waiting for IntersectionObserver. */
html.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

/* Direction variants — set transform inline before paint so the in-state
 * animates from the right starting point. */
html.reveal-ready .reveal[data-reveal="up"]    { transform: translateY(28px); }
html.reveal-ready .reveal[data-reveal="down"]  { transform: translateY(-28px); }
html.reveal-ready .reveal[data-reveal="left"]  { transform: translateX(-28px); }
html.reveal-ready .reveal[data-reveal="right"] { transform: translateX(28px); }
html.reveal-ready .reveal[data-reveal="scale"] { transform: scale(0.96); }
html.reveal-ready .reveal[data-reveal="fade"]  { transform: none; }

html.reveal-ready .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Stagger: children of .reveal-stagger get auto-incremented delays via
 * the JS layer, set as --reveal-delay on the element. CSS just honors it. */
html.reveal-ready .reveal-stagger > .reveal { transition-delay: var(--reveal-delay, 0ms); }

/* Respect user motion preferences — no animation, just instant final state. */
@media (prefers-reduced-motion: reduce) {
  html.reveal-ready .reveal,
  html.reveal-ready .reveal-stagger > .reveal {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}
