/*
 * LCMS scroll animations.
 *
 * Subtle fade-in for blocks as they scroll into view. Universal v1 — every
 * block wrapped by render-layout.php gets .lcms-anim-on-scroll. JS adds
 * .is-visible via IntersectionObserver. Honours prefers-reduced-motion.
 */

.lcms-anim-on-scroll {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity var(--lcms-anim-duration, 400ms) var(--lcms-anim-ease, cubic-bezier(0.215, 0.61, 0.355, 1)),
                transform var(--lcms-anim-duration, 400ms) var(--lcms-anim-ease, cubic-bezier(0.215, 0.61, 0.355, 1));
    /* will-change is intentionally NOT on the base class — that
       creates a compositor layer for every block on the page,
       blowing the browser's will-change memory budget on
       long pages (~40+ blocks). Added transiently by JS as
       `.lcms-anim-priming` just before reveal, removed after
       `transitionend`. See `lcms-scroll-animations.js`. */
}

.lcms-anim-on-scroll.lcms-anim-priming {
    will-change: opacity, transform;
}

/* Entrance styles (base-schema `entrance` field). Each overrides the
   hidden-state transform; the shared `.is-visible` reset below returns
   the block to neutral, so the existing opacity+transform transition
   tweens whatever offset the style sets. Declared BEFORE `.is-visible`
   (and the no-js / reduced-motion resets) so those equal-specificity
   rules win by source order once the block reveals. The default fade is
   the base `.lcms-anim-on-scroll` rule above — no modifier needed. */
.lcms-anim-on-scroll.lcms-entrance-fade-up { transform: translateY(20px); }
.lcms-anim-on-scroll.lcms-entrance-fade-in { transform: none; }
.lcms-anim-on-scroll.lcms-entrance-slide        { transform: translateX(-28px); }
.lcms-anim-on-scroll.lcms-entrance-slide-right  { transform: translateX(28px); }
.lcms-anim-on-scroll.lcms-entrance-scale        { transform: scale(0.96); }

/* `none` opts the block out of motion entirely. The class is hardcoded on
   every template's <section>, so we neutralise via CSS (higher specificity
   than the base rule) rather than trying to remove it. */
.lcms-anim-on-scroll.lcms-entrance-none {
    opacity: 1;
    transform: none;
    transition: none;
}

.lcms-anim-on-scroll.is-visible {
    opacity: 1;
    transform: none;
}

/* ── Child stagger (B38) ──────────────────────────────────────────
   A grid block opts in by adding `.lcms-stagger` to its item wrapper
   (e.g. card-grid's `.block-card-grid__cards`). The wrapper's direct
   children start hidden and fade up in sequence once the block's
   section reveals (`.is-visible`), driven by per-`nth-child`
   transition-delay. Reusable across grid blocks. Pairs cleanly with the
   block's own entrance set to `none` so only the children move. */
.lcms-anim-on-scroll .lcms-stagger > * {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity var(--lcms-stagger-duration, 500ms) var(--lcms-anim-ease, cubic-bezier(0.215, 0.61, 0.355, 1)),
                transform var(--lcms-stagger-duration, 500ms) var(--lcms-anim-ease, cubic-bezier(0.215, 0.61, 0.355, 1));
}
.lcms-anim-on-scroll.is-visible .lcms-stagger > * {
    opacity: 1;
    transform: none;
}
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(1)   { transition-delay: 0ms; }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(2)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 1); }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(3)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 2); }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(4)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 3); }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(5)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 4); }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(6)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 5); }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(7)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 6); }
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(8)   { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 7); }
/* Cap the delay so very long grids don't trail off the page. */
.lcms-anim-on-scroll.is-visible .lcms-stagger > *:nth-child(n+9) { transition-delay: calc(var(--lcms-stagger-step, 70ms) * 8); }

/* JS-disabled fallback — without JS, blocks stay visible. */
.no-js .lcms-anim-on-scroll {
    opacity: 1;
    transform: none;
    transition: none;
}
/* …and so do staggered children (the higher-specificity selector beats
   the hidden-state rule above so cards never get stranded invisible). */
.no-js .lcms-anim-on-scroll .lcms-stagger > * {
    opacity: 1;
    transform: none;
    transition: none;
}

/* Respect user motion preference — animations off, content visible. */
@media (prefers-reduced-motion: reduce) {
    .lcms-anim-on-scroll {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .lcms-anim-on-scroll .lcms-stagger > * {
        opacity: 1;
        transform: none;
        transition: none;
    }
}
