/* ============================================================
   Scroll reveal — Apple-style entrance motion (site-wide)
   ------------------------------------------------------------
   Tag any element with [data-reveal] (optionally a direction:
   up | down | left | right | scale | up-scale). It starts faded
   + offset and animates into place when scrolled into view, with
   a smooth opacity ramp and a subtly springy transform.

   Stagger: put [data-reveal-group] (optional value = ms step) on a
   parent; its direct [data-reveal] children cascade in sequence
   (great for card rows = left-to-right, or stacks = top-to-bottom).

   Reveal-once. Guarded by .reveal-ready (added by a tiny inline
   <head> script) so that if JS is off, nothing is ever hidden.
   ============================================================ */

:root {
    --reveal-distance: 34px;
    --reveal-distance-x: 44px;
    --reveal-duration: 0.72s;
    --reveal-blur: 6px;
    /* Smooth ease on opacity; gently springy (slight overshoot) on transform */
    --reveal-ease-opacity: cubic-bezier(0.33, 1, 0.68, 1);
    --reveal-ease-spring: cubic-bezier(0.34, 1.3, 0.5, 1);
}

.reveal-ready [data-reveal] {
    opacity: 0;
    /* Apple-style blur-to-sharp on the way in, so the fade reads clearly */
    filter: blur(var(--reveal-blur));
    transition:
        opacity var(--reveal-duration) var(--reveal-ease-opacity),
        transform var(--reveal-duration) var(--reveal-ease-spring),
        filter var(--reveal-duration) var(--reveal-ease-opacity);
    transition-delay: var(--reveal-delay, 0s);
    will-change: opacity, transform, filter;
}

.reveal-ready [data-reveal="up"],
.reveal-ready [data-reveal=""] {
    transform: translate3d(0, var(--reveal-distance), 0);
}

.reveal-ready [data-reveal="down"] {
    transform: translate3d(0, calc(-1 * var(--reveal-distance)), 0);
}

.reveal-ready [data-reveal="left"] {
    /* enters from the left */
    transform: translate3d(calc(-1 * var(--reveal-distance-x)), 0, 0);
}

.reveal-ready [data-reveal="right"] {
    /* enters from the right */
    transform: translate3d(var(--reveal-distance-x), 0, 0);
}

.reveal-ready [data-reveal="scale"] {
    transform: scale(0.955);
}

.reveal-ready [data-reveal="up-scale"] {
    transform: translate3d(0, var(--reveal-distance), 0) scale(0.975);
}

/* Opacity + blur only, no transform — for absolutely-positioned / clipped images
   (e.g. the toggle diagrams) where a translate/scale would clip or show edges. */
.reveal-ready [data-reveal="fade"] {
    transform: none;
}

.reveal-ready [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
    filter: blur(0);
}

/* Drop will-change once settled (avoids holding a compositor layer forever) */
.reveal-ready [data-reveal].is-revealed {
    will-change: auto;
}

/* The proof panel (iframe) handles its own cross-fade on tab switch and the
   reveal entrance — skip the blur there (blurring an iframe can be glitchy). */
.reveal-ready .nl-proof-stage[data-reveal] {
    filter: none;
}

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