/*
 * Velora sections — motion (Templates v3). Loaded with velora-sections.css.
 *
 * Presets, chosen per template with body[data-vws-motion] (SiteTemplates::motion()):
 *   rise      fade + 24px up, staggered children
 *   glide     sections enter from the left / right alternately (data-vws-side set by the script)
 *   zoom      scale .96 → 1 with a fade
 *   parallax  soft rise; large section images drift slower than the page (script, transform only)
 *   curtain   soft rise; images are unmasked from one side (clip-path)
 *   marquee   added to any base preset: logo and headline strips scroll continuously
 * Without the attribute (Velora sections added by hand, no template) the classic rise applies.
 *
 * Rules that keep pages safe:
 *  - start states apply only under html.vws-js (set before the first paint by SiteTemplates::headMarkup
 *    or by velora-sections.js itself, and removed again if the script never runs);
 *  - only opacity, transform and clip-path move: no layout shift;
 *  - prefers-reduced-motion: reduce shows everything at once, nothing moves; print shows everything.
 */

.vws { --vws-from: translateY(26px); --vws-step: 90ms; }
[data-vws-motion~="rise"] .vws { --vws-from: translateY(24px); }
[data-vws-motion~="glide"] .vws { --vws-from: translateX(-56px); }
[data-vws-motion~="glide"] .vws[data-vws-side="r"] { --vws-from: translateX(56px); }
[data-vws-motion~="zoom"] .vws { --vws-from: scale(.96); }
[data-vws-motion~="parallax"] .vws { --vws-from: translateY(18px); }
[data-vws-motion~="curtain"] .vws { --vws-from: translateY(14px); --vws-step: 110ms; }

.vws-js [data-vws-reveal] {
    opacity: 0;
    transform: var(--vws-from, translateY(26px));
    transition: opacity .8s var(--_ease) calc(var(--vws-i, 0) * var(--vws-step, 90ms)), transform 1s var(--_ease) calc(var(--vws-i, 0) * var(--vws-step, 90ms));
}
.vws-js [data-vws-motion~="zoom"] [data-vws-reveal] { transform-origin: 50% 70%; }
.vws-js [data-vws-reveal].is-in { opacity: 1; transform: none; }

/* curtain: images and art panels inside a revealed block are unmasked from the left (right on "r" sections).
   Only images that have ALREADY loaded are masked (class vws-cl, set by the script): a fully clipped
   lazy image never intersects the viewport, so the browser would never load it. The masked state
   exists only before .is-in (:not(.is-in)), so the revealed state can never lose to a more specific
   side rule; .is-done (set ~1.4 s after the reveal) drops every effect for good. */
.vws-js [data-vws-motion~="curtain"] [data-vws-reveal] :is(img.vws-cl, .vws-art) {
    transition: clip-path 1.25s cubic-bezier(.7, 0, .2, 1) calc(var(--vws-i, 0) * var(--vws-step, 90ms) + 120ms);
}
.vws-js [data-vws-motion~="curtain"] .vws [data-vws-reveal]:not(.is-in) :is(img.vws-cl, .vws-art) { clip-path: inset(0 100% 0 0); }
.vws-js [data-vws-motion~="curtain"] .vws[data-vws-side="r"] [data-vws-reveal]:not(.is-in) :is(img.vws-cl, .vws-art) { clip-path: inset(0 0 0 100%); }
.vws-js [data-vws-motion~="curtain"] .vws [data-vws-reveal].is-in :is(img.vws-cl, .vws-art) { clip-path: inset(0 0 0 0); }

/* hard stop: once revealed and given time to animate, a block is shown plainly whatever happens */
.vws-js [data-vws-reveal].is-done, .vws-js [data-vws-reveal].is-done :is(img, .vws-art) { opacity: 1 !important; transform: none !important; clip-path: none !important; }

/* The first section of a page (the hero) is never hidden: a visitor must see it at once, motion or not. */
.vws-js section.vws:first-of-type [data-vws-reveal],
.vws-js section.vws:first-of-type [data-vws-reveal] :is(img, .vws-art) { opacity: 1 !important; transform: none !important; clip-path: none !important; }

/* parallax: the script moves the image inside its own frame (clipped, not resized) */
.vws-px { overflow: clip; }
.vws-px > img { will-change: transform; transition: none; }

/* marquee: the strip becomes one clipped row from the first paint; the script duplicates the
   items (aria-hidden) and sets --vws-mq-w (width of one copy) and --vws-mq-t (duration). */
@media (prefers-reduced-motion: no-preference) {
    .vws-js [data-vws-motion~="marquee"] :is(.vws-logostrip__list, .vwp-ticker__list) {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow: hidden;
        -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
        mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
    }
    .vws-js [data-vws-motion~="marquee"] :is(.vws-logostrip__list, .vwp-ticker__list) > li { flex: none; }
    .vws-js [data-vws-motion~="marquee"] .vwp-ticker__list li:nth-child(n+2) { display: block; }
    .vws-js [data-vws-motion~="marquee"] .vwp-ticker__list li { overflow: visible; text-overflow: clip; }
    .vws-mq > li { animation: vws-mq var(--vws-mq-t, 30s) linear infinite; }
    .vws-mq:hover > li, .vws-mq:focus-within > li { animation-play-state: paused; }
}
@keyframes vws-mq { to { transform: translateX(calc(-1 * var(--vws-mq-w, 0px))); } }

@media (prefers-reduced-motion: reduce) {
    .vws-js [data-vws-reveal], .vws-js [data-vws-reveal] :is(img, .vws-art) { opacity: 1 !important; transform: none !important; clip-path: none !important; transition: none !important; }
    .vws-mq > li { animation: none; }
}
@media print {
    .vws-js [data-vws-reveal], .vws-js [data-vws-reveal] :is(img, .vws-art) { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}
