/* =========================================================
   motion.css – scroll-driven + time-based effects
   ========================================================= */

/* ---------- Tokens ---------- */

:root {
    --fx-distance: clamp(1rem, 3vw, 3rem);
    --fx-blur: 6px;
    --fx-duration: 650ms;
    --fx-delay: 0ms;
    --fx-ease: cubic-bezier(.16, 1, .3, 1);
    --fx-stagger-step: 8%;
    --fx-stagger-delay: 70ms;
    --fx-parallax-distance: 4vh;
    --fx-scale-from: .94;
    --fx-scale-to: 1.06;
    --fx-corner-from: scoop;
    --fx-corner-to: squircle;
    --fx-rotate: 25deg;
    --fx-highlight: #f7df6e;
    --fx-gradient-a: #6d4aff;
    --fx-gradient-b: #ff8a3d;
}

@media (max-width: 48rem) {
    :root {
        --fx-parallax-distance: 2vh;
        --fx-blur: 3px;
    }
}

@property --fx-index {
    syntax: "<integer>";
    inherits: true;
    initial-value: 0;
}

@property --fx-step-count {
    syntax: "<integer>";
    inherits: true;
    initial-value: 3;
}

/* ---------- Child index (stagger, text, slices, stack, pin) ---------- */

:where(.fx-stagger, .fx-text-lines, .fx-text-words, .fx-text-letters, .fx-image-slices, .fx-stack, .fx-pin > .wp-block-group) > * { --fx-index: 0; }

@supports (order: sibling-count()) {
    .fx-stagger > * { --fx-stagger: calc(var(--fx-index) / sibling-count() * 35%); }
}

@supports (order: sibling-index()) {
    :where(.fx-stagger, .fx-text-lines, .fx-text-words, .fx-text-letters, .fx-image-slices, .fx-stack, .fx-pin > .wp-block-group) > * { --fx-index: calc(sibling-index() - 1); }
}

.fx-stagger > * {
    --fx-stagger: calc(var(--fx-index) * var(--fx-stagger-step));
}

/* ---------- In / out / scroll ---------- */

.fx-in-corner {
    corner-shape: var(--fx-corner-to);
}

@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) and (animation-range: entry 0% cover 35%) {
        :is(.fx-in-fade, .fx-in-up, .fx-in-left, .fx-in-right, .fx-in-scale, .fx-in-focus, .fx-in-rise, .fx-in-reveal, .fx-in-corner, .fx-in-iris,
            .fx-out-fade, .fx-out-up, .fx-out-exit, .fx-out-left, .fx-out-right, .fx-out-blur,
            .fx-scroll-drift, .fx-scroll-scale, .fx-scroll-pan, .fx-scroll-rotate) {
            --fx-in-name: none;
            --fx-out-name: none;
            --fx-scroll-name: none;
            animation-name: var(--fx-in-name), var(--fx-out-name), var(--fx-scroll-name);
            animation-duration: auto;
            animation-timing-function: linear;
            animation-fill-mode: both;
            animation-timeline: view(), view(), view();
            animation-range: entry calc(var(--fx-in-start, 5%) + var(--fx-stagger, 0%)) cover calc(var(--fx-in-end, 35%) + var(--fx-stagger, 0%)),
                exit var(--fx-out-start, 0%) exit var(--fx-out-end, 80%),
                entry 0% exit 100%;
        }

        @supports (animation-composition: add) {
            :is(.fx-scroll-drift, .fx-scroll-pan, .fx-scroll-rotate) {
                animation-composition: replace, replace, add;
            }
        }

        .fx-in-fade { --fx-in-name: fx-fade-in; }
        .fx-in-up { --fx-in-name: fx-up-in; }
        .fx-in-left { --fx-in-name: fx-left-in; }
        .fx-in-right { --fx-in-name: fx-right-in; }
        .fx-in-scale { --fx-in-name: fx-scale-in; }
        .fx-in-focus { --fx-in-name: fx-focus-in; }
        .fx-in-rise { --fx-in-name: fx-rise-in; }
        .fx-in-reveal { --fx-in-name: fx-reveal-in; }
        .fx-in-corner { --fx-in-name: fx-corner-in; }
        .fx-in-iris { --fx-in-name: fx-iris-in; }

        .fx-out-fade { --fx-out-name: fx-fade-out; }
        .fx-out-up { --fx-out-name: fx-up-out; }
        .fx-out-exit { --fx-out-name: fx-exit-out; }
        .fx-out-left { --fx-out-name: fx-left-out; }
        .fx-out-right { --fx-out-name: fx-right-out; }
        .fx-out-blur { --fx-out-name: fx-blur-out; }

        .fx-scroll-drift { --fx-scroll-name: fx-scroll-drift; }
        .fx-scroll-scale { --fx-scroll-name: fx-scroll-scale; }
        .fx-scroll-pan { --fx-scroll-name: fx-scroll-pan; }
        .fx-scroll-rotate { --fx-scroll-name: fx-scroll-rotate; }
    }

    /* .fx-enter: time-based entrance on load instead of scroll */
    .fx-enter:is(.fx-in-fade, .fx-in-up, .fx-in-left, .fx-in-right, .fx-in-scale, .fx-in-focus, .fx-in-rise, .fx-in-reveal, .fx-in-corner, .fx-in-iris) {
        animation-duration: var(--fx-duration);
        animation-delay: calc(var(--fx-delay) + var(--fx-index, 0) * var(--fx-stagger-delay));
        animation-timing-function: var(--fx-ease);
        animation-fill-mode: backwards;
        animation-timeline: auto;
        animation-range: normal;
    }

    .fx-enter.fx-in-fade { animation-name: fx-fade-in; }
    .fx-enter.fx-in-up { animation-name: fx-up-in; }
    .fx-enter.fx-in-left { animation-name: fx-left-in; }
    .fx-enter.fx-in-right { animation-name: fx-right-in; }
    .fx-enter.fx-in-scale { animation-name: fx-scale-in; }
    .fx-enter.fx-in-focus { animation-name: fx-focus-in; }
    .fx-enter.fx-in-rise { animation-name: fx-rise-in; }
    .fx-enter.fx-in-reveal { animation-name: fx-reveal-in; }
    .fx-enter.fx-in-corner { animation-name: fx-corner-in; }
    .fx-enter.fx-in-iris { animation-name: fx-iris-in; }
}

@keyframes fx-fade-in {
    from { opacity: 0; }
}

@keyframes fx-up-in {
    from {
        opacity: 0;
        translate: 0 var(--fx-distance);
        rotate: var(--fx-in-rotate, 0deg);
    }
}

@keyframes fx-left-in {
    from {
        opacity: 0;
        translate: calc(-1 * var(--fx-distance)) 0;
        rotate: var(--fx-in-rotate, 0deg);
    }
}

@keyframes fx-right-in {
    from {
        opacity: 0;
        translate: var(--fx-distance) 0;
        rotate: var(--fx-in-rotate, 0deg);
    }
}

@keyframes fx-scale-in {
    from {
        opacity: 0;
        scale: var(--fx-scale-from);
    }
}

@keyframes fx-focus-in {
    from {
        opacity: 0;
        filter: blur(var(--fx-blur));
    }
}

@keyframes fx-rise-in {
    from {
        opacity: 0;
        translate: 0 1em;
        rotate: 2deg;
        clip-path: inset(100% 0 0);
    }

    to {
        clip-path: inset(0);
    }
}

@keyframes fx-reveal-in {
    from { clip-path: inset(0 100% 0 0); }
    to { clip-path: inset(0); }
}

@keyframes fx-corner-in {
    from {
        opacity: 0;
        scale: .92;
        corner-shape: var(--fx-corner-from);
    }
}

@keyframes fx-iris-in {
    from { clip-path: circle(0% at 50% 50%); }
    to { clip-path: circle(75% at 50% 50%); }
}

/* Out keyframes only define "to", so they never override the in-animation. */

@keyframes fx-fade-out {
    to { opacity: 0; }
}

@keyframes fx-up-out {
    to {
        opacity: 0;
        translate: 0 calc(-1 * var(--fx-distance));
    }
}

@keyframes fx-exit-out {
    to {
        opacity: 0;
        translate: 0 calc(-1 * var(--fx-distance));
        scale: var(--fx-scale-from);
        filter: blur(var(--fx-blur));
    }
}

@keyframes fx-left-out {
    to {
        opacity: 0;
        translate: calc(-1 * var(--fx-distance)) 0;
    }
}

@keyframes fx-right-out {
    to {
        opacity: 0;
        translate: var(--fx-distance) 0;
    }
}

@keyframes fx-blur-out {
    to {
        opacity: 0;
        filter: blur(var(--fx-blur));
    }
}

@keyframes fx-scroll-drift {
    from { translate: 0 var(--fx-parallax-distance); }
    to { translate: 0 calc(-1 * var(--fx-parallax-distance)); }
}

@keyframes fx-scroll-scale {
    from { scale: var(--fx-scale-from); }
    to { scale: var(--fx-scale-to); }
}

@keyframes fx-scroll-pan {
    from {
        translate: 0 var(--fx-parallax-distance);
        scale: 1.12;
    }

    to {
        translate: 0 calc(-1 * var(--fx-parallax-distance));
        scale: 1.03;
    }
}

@keyframes fx-scroll-rotate {
    from { rotate: calc(-1 * var(--fx-rotate)); }
    to { rotate: var(--fx-rotate); }
}

/* ---------- Stagger parent: animates unconfigured direct children ---------- */

@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
        .fx-stagger {
            view-timeline-name: --fx-stagger;
            view-timeline-axis: block;
        }

        .fx-stagger > :not([class*="fx-in-"], [class*="fx-out-"], [class*="fx-scroll-"], .fx-stagger) {
            animation: var(--fx-stagger-effect, fx-up-in) linear both;
            animation-timeline: --fx-stagger;
            animation-range: entry calc(var(--fx-in-start, 5%) + min(var(--fx-stagger), 35%)) cover calc(var(--fx-in-end, 35%) + min(var(--fx-stagger), 35%));
        }
    }
}

/* ---------- Text ---------- */

:where(.fx-text-lines, .fx-text-words, .fx-text-letters) > strong {
    display: inline-block;
    font-weight: inherit;
    font-style: inherit;
}

.fx-text-lines > strong {
    display: block;
    overflow: clip;
}

.fx-text-wipe {
    position: relative;
    overflow: clip;
}

.fx-text-highlight mark {
    position: relative;
    display: inline-block;
    isolation: isolate;
    -webkit-background-clip: text;
    background-clip: text;
}

.fx-text-highlight :where(mark) {
    background-color: var(--fx-highlight);
    color: inherit;
}

/* Marker bar inherits the mark's background (theme highlight colour works too). */
.fx-text-highlight mark::before {
    content: '';
    position: absolute;
    inset: auto 0 .08em;
    height: .42em;
    z-index: -1;
    background: inherit;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    transform-origin: left center;
    pointer-events: none;
}

.fx-text-gradient {
    background: linear-gradient(90deg, var(--fx-gradient-a), var(--fx-gradient-b), var(--fx-gradient-a)) 0 0 / 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

@property --fx-count {
    syntax: "<integer>";
    inherits: false;
    initial-value: 0;
}

.fx-count {
    --fx-count: var(--fx-count-to, 0);
    counter-reset: fx-count var(--fx-count);
}

.fx-count::after {
    content: counter(fx-count);
}

.fx-text-image {
    background-color: currentColor;
    background-image: var(--fx-text-image, none);
    background-size: var(--fx-text-image-size, cover);
    background-position: 50% 30%;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

@property --fx-text-fill-progress {
    syntax: "<percentage>";
    inherits: false;
    initial-value: 0%;
}

@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) and (animation-range: entry 0% cover 35%) {
        :is(.fx-text-reveal, .fx-text-focus, .fx-text-spread, .fx-text-gradient, .fx-count) {
            animation-duration: auto;
            animation-timing-function: linear;
            animation-fill-mode: both;
            animation-timeline: view();
            animation-range: entry var(--fx-in-start, 5%) cover var(--fx-in-end, 35%);
        }

        :is(.fx-text-gradient, .fx-count) {
            animation-range: entry var(--fx-in-start, 5%) cover var(--fx-in-end, 45%);
        }

        .fx-text-reveal { animation-name: fx-reveal-in; }
        .fx-text-focus { animation-name: fx-focus-in; }
        .fx-text-spread { animation-name: fx-text-spread; }
        .fx-text-gradient { animation-name: fx-gradient; }
        .fx-count { animation-name: fx-count; }

        /* Split text: wrap each line / word / letter in <strong> */
        :is(.fx-text-lines, .fx-text-words, .fx-text-letters, .fx-text-wipe) {
            view-timeline-name: --fx-text;
            view-timeline-axis: block;
        }

        :where(.fx-text-lines, .fx-text-words, .fx-text-letters) > strong {
            animation: fx-rise-in linear both;
            animation-timeline: --fx-text;
            animation-range: entry calc(5% + var(--fx-index, 0) * 2%) cover calc(35% + var(--fx-index, 0) * 2%);
        }

        .fx-text-letters > strong {
            --fx-distance: .5em;
            animation-name: fx-up-in;
        }

        .fx-text-wipe::after {
            content: '';
            position: absolute;
            inset: 0;
            background: currentColor;
            pointer-events: none;
            animation: fx-text-wipe linear both;
            animation-timeline: --fx-text;
            animation-range: entry 0% cover 40%;
        }

        .fx-text-highlight {
            view-timeline-name: --fx-highlight;
            view-timeline-axis: block;
        }

        .fx-text-highlight mark::before {
            animation: fx-highlight linear both;
            animation-timeline: --fx-highlight;
            animation-range: entry var(--fx-in-start, 5%) cover var(--fx-in-end, 45%);
        }

        .fx-text-weight {
            animation: fx-text-weight linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 65%;
        }

        .fx-text-image {
            animation: fx-text-image-pan linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 80%;
        }
    }

    /* Fill / outline paint directly on the existing text */
    @supports (background-clip: text) and (animation-timeline: view()) {
        :is(.fx-text-fill, .fx-text-outline) {
            background-image: linear-gradient(currentColor, currentColor);
            background-size: var(--fx-text-fill-progress) 100%;
            background-position: left top;
            background-repeat: no-repeat;
            -webkit-background-clip: text;
            background-clip: text;
            -webkit-text-fill-color: transparent;
            animation: fx-text-paint linear both;
            animation-timeline: view();
            animation-range: entry 0% cover 60%;
        }

        .fx-text-fill {
            background-image: linear-gradient(currentColor, currentColor), linear-gradient(color-mix(in srgb, currentColor 25%, transparent), color-mix(in srgb, currentColor 25%, transparent));
            background-size: var(--fx-text-fill-progress) 100%, 100% 100%;
        }

        .fx-text-outline {
            -webkit-text-stroke: var(--fx-stroke-width, 1px) var(--fx-outline-color, currentColor);
        }

        :is(.fx-text-fill, .fx-text-outline):is(:focus-visible, :focus-within) {
            animation: none;
            background: none;
            -webkit-text-fill-color: currentColor;
            -webkit-text-stroke: 0;
        }
    }
}

@keyframes fx-text-spread {
    from {
        opacity: 0;
        scale: 1.08 1;
        filter: blur(var(--fx-blur));
    }
}

@keyframes fx-text-wipe {
    0% { translate: -101% 0; }
    45%, 55% { translate: 0 0; }
    100% { translate: 101% 0; }
}

@keyframes fx-highlight {
    from { scale: 0 1; }
}

@keyframes fx-gradient {
    from { background-position: 100% 0; }
}

@keyframes fx-count {
    from { --fx-count: 0; }
}

@keyframes fx-text-weight {
    from { font-weight: 100; }
    to { font-weight: 900; }
}

@keyframes fx-text-image-pan {
    from { background-position: 50% 0%; }
    to { background-position: 50% 100%; }
}

@keyframes fx-text-paint {
    to { --fx-text-fill-progress: 100%; }
}

@media (forced-colors: active) {
    :is(.fx-text-fill, .fx-text-outline, .fx-text-image) {
        animation: none !important;
        background: none;
        -webkit-text-fill-color: currentColor;
        -webkit-text-stroke: 0;
    }
}

/* ---------- Stack (sticky cards) ---------- */

.fx-stack {
    display: grid;
    &::after {
        content: "";
        height: var(--fx-stack-space, 50vh);
    }
    & > * {
        width: 100%;
        max-width: none;
        box-sizing: border-box;
        justify-self: stretch;
        position: sticky;
        top: calc(var(--fx-stack-top, 12vh) + var(--fx-index, 0) * var(--fx-stack-offset, .75rem));
        transform-origin: 50% 0;
    }
    @media (prefers-reduced-motion: no-preference) {
        @supports (timeline-scope: --a) and (animation-timeline: view()) {
            timeline-scope: --fx-s2, --fx-s3, --fx-s4, --fx-s5, --fx-s6, --fx-s7, --fx-s8, --fx-s9;
            & > :nth-child(2) { view-timeline-name: --fx-s2; }
            & > :nth-child(3) { view-timeline-name: --fx-s3; }
            & > :nth-child(4) { view-timeline-name: --fx-s4; }
            & > :nth-child(5) { view-timeline-name: --fx-s5; }
            & > :nth-child(6) { view-timeline-name: --fx-s6; }
            & > :nth-child(7) { view-timeline-name: --fx-s7; }
            & > :nth-child(8) { view-timeline-name: --fx-s8; }
            & > :nth-child(9) { view-timeline-name: --fx-s9; }
            & > :not(:last-child) {
                animation: fx-stack-back linear both;
                animation-range: entry 0% cover var(--fx-stack-end, 45%);
            }
            & > :nth-child(1) { animation-timeline: --fx-s2; }
            & > :nth-child(2) { animation-timeline: --fx-s3; }
            & > :nth-child(3) { animation-timeline: --fx-s4; }
            & > :nth-child(4) { animation-timeline: --fx-s5; }
            & > :nth-child(5) { animation-timeline: --fx-s6; }
            & > :nth-child(6) { animation-timeline: --fx-s7; }
            & > :nth-child(7) { animation-timeline: --fx-s8; }
            & > :nth-child(8) { animation-timeline: --fx-s9; }
        }
    }
}

@keyframes fx-stack-back {
    to { scale: var(--fx-stack-scale, .9); }
}

/* ---------- Pin (sticky step-by-step slides) ---------- */

.fx-pin {
    --fx-pin-steps: 3;
    & > .wp-block-group {
        display: grid;
        gap: 4rem;
    }
    & > .wp-block-group > .wp-block-cover {
        width: 100%;
        min-height: 0;
        aspect-ratio: 16 / 9;
        box-sizing: border-box;
    }
    @media (prefers-reduced-motion: no-preference) {
        @supports (view-timeline-name: --a) {
            height: calc(var(--fx-pin-steps) * 100svh);
            view-timeline: --fx-pin block;
            & > .wp-block-group {
                position: sticky;
                top: 0;
                height: 100svh;
                align-items: center;
                overflow: clip;
            }
            & > .wp-block-group > .wp-block-cover {
                width: min(100%, calc(100svh * 16 / 9));
                justify-self: center;
            }
            & > .wp-block-group > * {
                grid-area: 1 / 1;
                animation: fx-pin-step linear both;
                animation-timeline: --fx-pin;
                animation-range: contain calc(var(--fx-index) / var(--fx-step-count) * 100%)
                contain calc((var(--fx-index) + 1) / var(--fx-step-count, var(--fx-pin-steps)) * 100%);
                @supports (order: sibling-count()) { --fx-step-count: sibling-count(); }
            }
            & > .wp-block-group > :first-child { animation-name: fx-pin-first; }
            & > .wp-block-group > :last-child { animation-name: fx-pin-last; }
            :is(& > .wp-block-group > * > :is(h1, h2, h3, h4, h5, h6, p), & > .wp-block-group > * > .wp-block-cover__inner-container > *) {
                animation: fx-pin-text linear both;
                animation-timeline: --fx-pin;
                animation-range: contain calc((var(--fx-index) + var(--fx-text-delay, 0)) / var(--fx-step-count, var(--fx-pin-steps)) * 100%)
                contain calc((var(--fx-index) + 1) / var(--fx-step-count, var(--fx-pin-steps)) * 100%);
            }
            & > .wp-block-group > * p { --fx-text-delay: .1; }
            :is(& > .wp-block-group > :first-child > :is(h1, h2, h3, h4, h5, h6, p), & > .wp-block-group > :first-child > .wp-block-cover__inner-container > *) { animation-name: fx-pin-text-first; }
            :is(& > .wp-block-group > :last-child > :is(h1, h2, h3, h4, h5, h6, p), & > .wp-block-group > :last-child > .wp-block-cover__inner-container > *) { animation-name: fx-pin-text-last; }
        }
    }
}

@keyframes fx-pin-step {
    from { opacity: 0; }
    20%, 100% { opacity: 1; }
}

@keyframes fx-pin-first {
    from, to { opacity: 1; }
}

@keyframes fx-pin-last {
    from { opacity: 0; }
    20%, 100% { opacity: 1; }
}

@keyframes fx-pin-text {
    0%, 20%, 95%, 100% { opacity: 0; }
    35%, 80% { opacity: 1; }
}

@keyframes fx-pin-text-first {
    0%, 80% { opacity: 1; }
    95%, 100% { opacity: 0; }
}

@keyframes fx-pin-text-last {
    0%, 20% { opacity: 0; }
    35%, 100% { opacity: 1; }
}

/* ---------- Horizontal scroll section ---------- */

.fx-horizontal > .wp-block-group {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
}

.fx-horizontal > .wp-block-group > .wp-block-group {
    width: max-content;
    max-width: none;
    flex-shrink: 0;
    display: grid;
    grid-auto-flow: column;
    grid-template-columns: none;
    grid-template-rows: auto;
}

.fx-horizontal > .wp-block-group > .wp-block-group > * {
    scroll-snap-align: start;
}

@media (prefers-reduced-motion: no-preference) {
    @supports (view-timeline-name: --a) {
        .fx-horizontal {
            height: var(--fx-horizontal-height, 300svh);
            view-timeline: --fx-horizontal block;
        }

        .fx-horizontal > .wp-block-group {
            position: sticky;
            top: 0;
            height: 100svh;
            display: flex;
            align-items: center;
            overflow: clip;
            container-type: inline-size;
        }

        .fx-horizontal > .wp-block-group > .wp-block-group {
            animation: fx-horizontal linear both;
            animation-timeline: --fx-horizontal;
            animation-range: contain 0% contain 100%;
        }
    }
}

@keyframes fx-horizontal {
    to { translate: calc(-100% + 100cqw) 0; }
}

/* ---------- Backgrounds (one effect per element) ---------- */

@property --fx-glow-x { syntax: "<percentage>"; inherits: false; initial-value: 50%; }
@property --fx-glow-y { syntax: "<percentage>"; inherits: false; initial-value: 40%; }
@property --fx-spot { syntax: "<percentage>"; inherits: false; initial-value: 70%; }
@property --fx-ring-gap { syntax: "<length>"; inherits: false; initial-value: 24px; }

:is(.fx-bg-tint, .fx-bg-angle, .fx-bg-glow, .fx-bg-mesh, .fx-bg-expand, .fx-bg-aurora, .fx-bg-dots, .fx-bg-spotlight, .fx-bg-rings, .fx-bg-sunset, .fx-bg-dark) {
    position: relative;
    isolation: isolate;
    -webkit-background-clip: text;
    background-clip: text;
}

:is(.fx-bg-angle, .fx-bg-glow, .fx-bg-mesh, .fx-bg-aurora, .fx-bg-dots, .fx-bg-spotlight, .fx-bg-rings, .fx-bg-sunset) {
    overflow: clip;
}

:is(.fx-bg-tint, .fx-bg-angle, .fx-bg-glow, .fx-bg-mesh, .fx-bg-expand, .fx-bg-aurora, .fx-bg-dots, .fx-bg-spotlight, .fx-bg-rings, .fx-bg-sunset, .fx-bg-dark)::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: inherit;
    -webkit-background-clip: border-box;
    background-clip: border-box;
}

.fx-bg-shift,
.fx-bg-sunset::before {
    background-size: var(--fx-bg-size, 220% 220%);
    background-position: 50% 50%;
}

.fx-bg-angle::before,
.fx-bg-aurora::before { inset: -50%; }

.fx-bg-glow::before {
    mask-image: radial-gradient(circle at var(--fx-glow-x) var(--fx-glow-y), #000 0, transparent var(--fx-glow-size, 45%));
}

.fx-bg-mesh::before {
    background-size: 140% 140%;
    filter: blur(var(--fx-mesh-blur, 24px));
}

.fx-bg-aurora::before {
    filter: blur(var(--fx-aurora-blur, 70px));
    opacity: var(--fx-aurora-opacity, .55);
}

.fx-bg-dots::before {
    mask-image: radial-gradient(#000 1px, transparent 1.5px);
    mask-size: var(--fx-dot-gap, 12px) var(--fx-dot-gap, 12px);
    mask-position: 50% 50%;
}

.fx-bg-spotlight::before {
    mask-image: radial-gradient(circle at 50% 50%, transparent var(--fx-spot), #000 calc(var(--fx-spot) + 18%));
}

.fx-bg-rings::before {
    mask-image: repeating-radial-gradient(circle at 50% 110%, #000 0 2px, transparent 2px var(--fx-ring-gap));
}

.fx-bg-dark::before { position: fixed; }

@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) and (animation-range: entry 0% cover 35%) {
        :is(.fx-bg-tint, .fx-bg-angle, .fx-bg-shift, .fx-bg-glow, .fx-bg-mesh, .fx-bg-expand, .fx-bg-aurora, .fx-bg-dots, .fx-bg-spotlight, .fx-bg-rings, .fx-bg-sunset, .fx-bg-dark) {
            view-timeline-name: --fx-bg;
            view-timeline-axis: block;
        }

        .fx-bg-shift,
        :is(.fx-bg-tint, .fx-bg-angle, .fx-bg-glow, .fx-bg-mesh, .fx-bg-expand, .fx-bg-aurora, .fx-bg-dots, .fx-bg-spotlight, .fx-bg-rings, .fx-bg-sunset, .fx-bg-dark)::before {
            animation-duration: auto;
            animation-timing-function: linear;
            animation-fill-mode: both;
            animation-timeline: --fx-bg;
            animation-range: entry 0% exit 100%;
        }

        .fx-bg-tint::before { animation-name: fx-bg-tint; animation-range: entry 0% cover 45%; }
        .fx-bg-angle::before { animation-name: fx-bg-angle; }
        .fx-bg-shift, .fx-bg-sunset::before { animation-name: fx-bg-shift; }
        .fx-bg-glow::before { animation-name: fx-bg-glow; }
        .fx-bg-mesh::before { animation-name: fx-bg-mesh; }
        .fx-bg-expand::before { animation-name: fx-bg-expand; animation-range: entry 0% cover 40%; }
        .fx-bg-aurora::before { animation-name: fx-bg-aurora; }
        .fx-bg-dots::before { animation-name: fx-bg-dots; }
        .fx-bg-spotlight::before { animation-name: fx-bg-spotlight; animation-range: entry 20% cover 60%; }
        .fx-bg-rings::before { animation-name: fx-bg-rings; }
        .fx-bg-dark::before { animation-name: fx-bg-dark; animation-range: entry 30% exit 70%; }
    }
}

@keyframes fx-bg-tint { from { opacity: 0; } }
@keyframes fx-bg-angle { from { rotate: 0deg; } to { rotate: 270deg; } }
@keyframes fx-bg-shift { from { background-position: 0% 0%; } to { background-position: 100% 100%; } }
@keyframes fx-bg-glow { from { --fx-glow-x: 25%; --fx-glow-y: 0%; } to { --fx-glow-x: 75%; --fx-glow-y: 100%; } }
@keyframes fx-bg-mesh { from { background-position: 0% 0%, 100% 100%, 50% 0%; } to { background-position: 100% 100%, 0% 0%, 50% 100%; } }
@keyframes fx-bg-expand { from { clip-path: inset(0 var(--fx-expand-inset, 8vw) round var(--fx-expand-radius, 48px)); } to { clip-path: inset(0 round 0); } }
@keyframes fx-bg-aurora { to { rotate: 360deg; } }
@keyframes fx-bg-dots { from { mask-size: calc(var(--fx-dot-gap, 12px) * .5) calc(var(--fx-dot-gap, 12px) * .5); } to { mask-size: calc(var(--fx-dot-gap, 12px) * 2) calc(var(--fx-dot-gap, 12px) * 2); } }
@keyframes fx-bg-spotlight { from { --fx-spot: 0%; } }
@keyframes fx-bg-rings { from { --fx-ring-gap: 8px; } to { --fx-ring-gap: 40px; } }
@keyframes fx-bg-dark { 0%, 100% { opacity: 0; } 25%, 75% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
    .fx-bg-dark::before { position: absolute; }
}


/* ---------- Marquee (scroll) & ticker (loop) ---------- */

:is(.fx-marquee, .fx-marquee-rotate) > .wp-block-group {
    width: 100%;
    max-width: 100%;
    overflow: clip;
}

:is(.fx-marquee, .fx-marquee-rotate) > .wp-block-group > .wp-block-group,
.fx-ticker {
    display: flex;
    flex-shrink: 0;
    width: max-content;
    max-width: none;
    white-space: nowrap;
}

.fx-marquee-rotate {
    display: grid;
    align-items: center;
    min-height: clamp(10rem, 20vw, 18rem);
    overflow: clip;
}

.fx-marquee-rotate > .wp-block-group {
    grid-area: 1 / 1;
    justify-self: center;
    width: 110%;
    max-width: none;
    margin-block: 0 !important;
    rotate: calc(-1 * var(--fx-marquee-angle, 4deg));
}

.fx-marquee-rotate > .wp-block-group:nth-child(even) {
    z-index: 1;
    rotate: var(--fx-marquee-angle, 4deg);
}

.wp-block-group:has(> .fx-ticker, > .fx-scroll-pan) {
    overflow-x: clip;
}

.fx-ticker {
    padding-right: var(--fx-marquee-gap, 2rem);
}

.fx-ticker:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 4px;
}

@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
        :is(.fx-marquee, .fx-marquee-rotate) > .wp-block-group > .wp-block-group {
            animation: fx-marquee linear both;
            animation-timeline: view();
            animation-range: cover 0% cover 100%;
        }

        :is(.fx-marquee, .fx-marquee-rotate) > .wp-block-group:nth-child(even) > .wp-block-group {
            animation-direction: reverse;
        }
    }

    .fx-ticker {
        animation: fx-ticker var(--fx-ticker-duration, 30s) linear infinite;
    }

    .fx-ticker:nth-child(even) {
        animation-direction: reverse;
    }

    .fx-ticker:is(:hover, :focus-within) {
        animation-play-state: paused;
    }
}

@keyframes fx-marquee {
    from { translate: var(--fx-marquee-from, 0) 0; }
    to { translate: var(--fx-marquee-distance, -35%) 0; }
}

@keyframes fx-ticker {
    to { translate: -50% 0; }
}

/* ---------- Images ---------- */

.fx-image-expand {
    display: block;
    overflow: clip;
    border-radius: 0;
}

:is(.fx-image-expand, .fx-image-curtain) > img {
    display: block;
    width: 100%;
    height: auto;
}

.fx-image-slices {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    overflow: clip;
}

.fx-image-slices > span {
    aspect-ratio: 1 / 3;
    background-image: var(--fx-image);
    background-size: 500% 100%;
    background-position: calc(var(--fx-index, 0) * 25%) 50%;
}

.fx-image-curtain {
    position: relative;
    overflow: clip;
}

.fx-image-curtain::before,
.fx-image-curtain::after {
    content: "";
    position: absolute;
    inset-block: 0;
    width: 50%;
    background: var(--fx-curtain-color, #244b3b);
    pointer-events: none;
    scale: 0 1;
}

.fx-image-curtain::before {
    left: 0;
    transform-origin: left;
}

.fx-image-curtain::after {
    right: 0;
    transform-origin: right;
}

.fx-gallery-settle {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--fx-gallery-gap, 1rem);
}

.fx-gallery-settle > * {
    min-width: 0;
}

.fx-gallery-settle > :nth-child(3n+1) { --fx-gallery-offset: 18%; }
.fx-gallery-settle > :nth-child(3n+2) { --fx-gallery-offset: -12%; }
.fx-gallery-settle > :nth-child(3n) { --fx-gallery-offset: 30%; }

.fx-in-perspective {
    transform-origin: 50% 100%;
}

@media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
        .fx-image-expand {
            animation: fx-image-expand linear both;
            animation-timeline: view();
            animation-range: entry 5% cover 55%;
        }

        .fx-image-slices {
            view-timeline-name: --fx-slices;
        }

        .fx-image-slices > span {
            animation: fx-image-slice linear both;
            animation-timeline: --fx-slices;
            animation-range: entry calc(5% + var(--fx-index) * 3%) cover calc(40% + var(--fx-index) * 3%);
        }

        .fx-image-curtain {
            view-timeline-name: --fx-curtain;
        }

        .fx-image-curtain::before,
        .fx-image-curtain::after {
            animation: fx-curtain-open linear both;
            animation-timeline: --fx-curtain;
            animation-range: entry 5% cover 55%;
        }

        .fx-gallery-settle {
            view-timeline-name: --fx-gallery;
        }

        .fx-gallery-settle > * {
            animation: fx-gallery-settle linear both;
            animation-timeline: --fx-gallery;
            animation-range: entry 0% cover 60%;
        }

        .fx-in-perspective {
            animation: fx-in-perspective linear both;
            animation-timeline: view();
            animation-range: entry 5% cover 45%;
        }
    }
}

@keyframes fx-image-expand {
    from { clip-path: inset(0 15% round 64px); }
    to { clip-path: inset(0 0 round 0px); }
}

@keyframes fx-image-slice {
    from {
        opacity: 0;
        translate: 0 35%;
    }
}

@keyframes fx-curtain-open {
    from { scale: 1 1; }
    to { scale: 0 1; }
}

@keyframes fx-gallery-settle {
    from { translate: 0 var(--fx-gallery-offset, 20%); }
}

@keyframes fx-in-perspective {
    from {
        transform: perspective(1000px) rotateX(35deg);
        opacity: .2;
    }

    to {
        transform: perspective(1000px) rotateX(0deg);
    }
}

/* ---------- Hover ---------- */

.fx-hover-tilt {
    position: relative;
    overflow: clip;
}

.fx-hover-tilt::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(110deg, transparent 25%, #ffffff55 45%, transparent 65%);
    translate: -120% 0;
}

.fx-underline {
    display: inline-block;
    position: relative;
    text-decoration: none;
}

.fx-underline::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: var(--fx-underline-offset, -.12em);
    height: var(--fx-underline-width, 2px);
    background: currentColor;
    transform-origin: left;
}

@media (prefers-reduced-motion: no-preference) {
    .fx-hover-tilt {
        transition: transform 650ms var(--fx-ease);
    }

    .fx-hover-tilt::after {
        transition: translate 900ms var(--fx-ease);
    }

    .fx-underline::after {
        scale: 0 1;
        transition: scale 450ms var(--fx-ease);
    }

    .fx-hover-tilt:focus-visible {
        transform: perspective(1000px) rotateY(-7deg) rotateX(3deg);
    }

    .fx-hover-tilt:focus-visible::after {
        translate: 120% 0;
    }

    .fx-underline:focus-visible::after {
        scale: 1 1;
    }

    @media (hover: hover) and (pointer: fine) {
        .fx-hover-tilt:hover {
            transform: perspective(1000px) rotateY(-7deg) rotateX(3deg);
        }

        .fx-hover-tilt:hover::after {
            translate: 120% 0;
        }

        .fx-underline:hover::after {
            scale: 1 1;
        }
    }
}

/* ---------- Keyboard focus: show content immediately ---------- */

:is(.fx-in-fade, .fx-in-up, .fx-in-left, .fx-in-right, .fx-in-scale, .fx-in-focus, .fx-in-rise, .fx-in-reveal, .fx-in-corner, .fx-in-iris,
    .fx-out-fade, .fx-out-up, .fx-out-exit, .fx-out-left, .fx-out-right, .fx-out-blur,
    .fx-scroll-drift, .fx-scroll-scale, .fx-scroll-pan, .fx-scroll-rotate,
    .fx-text-reveal, .fx-text-focus, .fx-text-spread, .fx-text-wipe):is(:focus-visible, :focus-within),
:is(.fx-text-lines, .fx-text-words, .fx-text-letters):focus-within > strong,
.fx-stagger > :is(:focus-visible, :focus-within) {
    animation: none;
    opacity: 1;
    translate: none;
    scale: none;
    rotate: none;
    filter: none;
    clip-path: none;
}

.fx-text-wipe:focus-within::after {
    display: none;
}
