/* =============================================================
   REVEAL ON SCROLL / LOAD
   Reusable subtle-motion utility. Add data-reveal to any element:
     data-reveal          -> fade + rise
     data-reveal="fade"   -> fade only
     data-reveal="left"   -> fade + slide from left
     data-reveal="right"  -> fade + slide from right
     data-reveal="zoom"   -> fade + gentle scale up
   Stagger with data-reveal-delay="120" (milliseconds).
   Driven by js/reveal.js. Without JS, or with reduced motion,
   everything is shown immediately (see the :root fallback rule).
   ============================================================= */

[data-reveal] {
    opacity: 0;
    transform: translateY(26px);
    transition:
        opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
        transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform;
}

[data-reveal="fade"]  { transform: none; }
[data-reveal="left"]  { transform: translateX(-32px); }
[data-reveal="right"] { transform: translateX(32px); }
[data-reveal="zoom"]  { transform: scale(0.94); }

[data-reveal].is-revealed {
    opacity: 1;
    transform: none;
}

/* JS absent: reveal.js never runs, so nothing gets .is-revealed.
   This guard shows content anyway once the stylesheet loads, but
   reveal.js adds .reveal-ready to <html> first, which suppresses it,
   so with JS the hidden start-state holds until the observer fires. */
html:not(.reveal-ready) [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
}

@media (prefers-reduced-motion: reduce) {
    [data-reveal] {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}
