/* ns-animations.css - UI/UX only: scroll-reveal animations for static pages.
 *
 * SAFETY GATE: the hidden state is scoped to html.ns-anim-ready, which is added by
 * ns-animations.js. If JS fails, is blocked, or the browser lacks IntersectionObserver,
 * nothing is ever hidden - the page renders exactly as before.
 *
 * Only `opacity` and `transform` are animated: both are GPU-composited and cause
 * ZERO layout shift, so scrolling stays at 60fps and nothing reflows.
 */

:root {
    --ns-anim-dur: 760ms;
    --ns-anim-ease: cubic-bezier(.22, .61, .36, 1);   /* easeOutQuint-ish */
    --ns-anim-shift: 26px;
}

/* ---- resting (pre-reveal) states ---- */
html.ns-anim-ready .ns-reveal {
    opacity: 0;
    transition:
        opacity var(--ns-anim-dur) var(--ns-anim-ease),
        transform var(--ns-anim-dur) var(--ns-anim-ease);
    transition-delay: var(--ns-delay, 0ms);
}

html.ns-anim-ready .ns-reveal.ns-up     { transform: translate3d(0, var(--ns-anim-shift), 0); }
html.ns-anim-ready .ns-reveal.ns-down   { transform: translate3d(0, calc(var(--ns-anim-shift) * -1), 0); }
html.ns-anim-ready .ns-reveal.ns-left   { transform: translate3d(calc(var(--ns-anim-shift) * -1.4), 0, 0); }
html.ns-anim-ready .ns-reveal.ns-right  { transform: translate3d(calc(var(--ns-anim-shift) * 1.4), 0, 0); }
html.ns-anim-ready .ns-reveal.ns-zoom   { transform: scale(.955); }
html.ns-anim-ready .ns-reveal.ns-fade   { transform: none; }

/* ---- revealed ---- */
html.ns-anim-ready .ns-reveal.ns-in {
    opacity: 1;
    transform: translate3d(0, 0, 0) scale(1);
}

/* Media gets a touch of polish: soften the scale-in with a slight origin shift */
html.ns-anim-ready .ns-reveal.ns-zoom {
    transform-origin: center center;
}

/* While animating only - dropped afterwards by JS so we don't pin layers forever */
html.ns-anim-ready .ns-reveal.ns-animating {
    will-change: opacity, transform;
}

/* Never let an animated wrapper clip a shadow or create a scroll bar */
html.ns-anim-ready .ns-reveal {
    backface-visibility: hidden;
}

/* ---------------------------------------------------------------
   Accessibility - users who ask for less motion get none.
   Content is shown immediately and fully.
   --------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html.ns-anim-ready .ns-reveal,
    html.ns-anim-ready .ns-reveal.ns-up,
    html.ns-anim-ready .ns-reveal.ns-down,
    html.ns-anim-ready .ns-reveal.ns-left,
    html.ns-anim-ready .ns-reveal.ns-right,
    html.ns-anim-ready .ns-reveal.ns-zoom {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}

/* Printing must never hide content */
@media print {
    .ns-reveal {
        opacity: 1 !important;
        transform: none !important;
    }
}
