:root {
    --spa-transition-duration: 180ms;
    --spa-transition-easing: cubic-bezier(0.22, 1, 0.36, 1);
}

html {
    scroll-behavior: smooth;
}

/* Apply the swap transition to direct body children that are NOT persisted nav
   shells. CSS opacity on a parent multiplies onto children, so dimming body
   would dim the bottom-nav too — moving the rule to non-persisted siblings
   keeps the navs rock-solid through every SPA swap. */
body > :not([data-spa-persist]) {
    will-change: opacity, filter;
    transition:
        opacity var(--spa-transition-duration) var(--spa-transition-easing),
        filter var(--spa-transition-duration) var(--spa-transition-easing);
}

html.spa-loading body {
    pointer-events: none;
}

html.spa-loading body,
html.spa-swapping body {
    animation: none !important;
}

html.spa-swapping body > :not([data-spa-persist]) {
    opacity: 0.985;
    filter: saturate(0.98);
}

html.app-ready body > :not([data-spa-persist]) {
    opacity: 1;
}

@supports (view-transition-name: root) {
    :root {
        view-transition-name: root;
    }

    [data-spa-persist="top-nav"] .navbar {
        view-transition-name: navbar;
    }

    /* Give the bottom nav and mobile menu their own transition tracks too,
       so they don't get bundled into the `root` fade and stay rock-still
       through every SPA swap. The before/after snapshots are identical
       because the DOM elements are persisted, so no animation runs. */
    .bottom-nav {
        view-transition-name: bottom-nav;
    }

    .mobile-menu {
        view-transition-name: mobile-menu;
    }

    ::view-transition-old(root) {
        animation: spa-fade-out var(--spa-transition-duration) var(--spa-transition-easing);
    }

    ::view-transition-new(root) {
        animation: spa-fade-in var(--spa-transition-duration) var(--spa-transition-easing);
    }

    ::view-transition-old(navbar),
    ::view-transition-new(navbar),
    ::view-transition-old(bottom-nav),
    ::view-transition-new(bottom-nav),
    ::view-transition-old(mobile-menu),
    ::view-transition-new(mobile-menu) {
        animation: none !important;
    }
}

@keyframes spa-fade-out {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

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

    to {
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    body,
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none !important;
        transition: none !important;
    }
}

/* Bottom nav is always static — no animations, transitions, or visibility changes */
.bottom-nav {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
    pointer-events: auto !important;
}
