/* =============================================================================
 * SPA — ANIMATIONS  (spa-animations.css)
 *
 * All @keyframes definitions and animation utility classes.
 * Sections reference these classes; no animation logic lives in other files.
 *
 * Respects prefers-reduced-motion: all animated elements fall back to
 * their final visible state when the user has requested reduced motion.
 * ============================================================================= */


/* ── @keyframes ─────────────────────────────────────────────────────────── */

/**
 * heroFadeIn — hero content slides up and fades in on page load.
 * Triggered via a direct animation declaration on .spa-hero__content.
 */
@keyframes heroFadeIn {
    0%   { opacity: 0; transform: translateY(30px); }
    100% { opacity: 1; transform: translateY(0); }
}

/**
 * fadeUp — entrance animation for staggered elements (testimonials).
 * Applied with a delay via .spa-anim-delay-* classes below.
 */
@keyframes fadeUp {
    from { opacity: 0; transform: translateY(30px); }
    to   { opacity: 1; transform: translateY(0); }
}

/**
 * scrollLine — the animated vertical line inside the hero scroll indicator.
 */
@keyframes scrollLine {
    0%,  100% { opacity: 1; transform: scaleY(1); }
    50%        { opacity: 0.3; transform: scaleY(0.6); }
}

/**
 * galleryScroll — drives the infinite horizontal gallery strip.
 * Duration is set in the rule (40s) to allow easy override.
 */
@keyframes galleryScroll {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

@keyframes spaCatalogueFloat {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50% { transform: translate3d(0, -12px, 0) scale(1.04); }
}

@keyframes spaCataloguePulse {
    0%, 100% { opacity: 0.3; transform: scale(0.96); }
    50% { opacity: 0.55; transform: scale(1.08); }
}


/* ── Utility: hero content entrance ────────────────────────────────────── */

.spa-hero__content {
    opacity: 0;
    animation: heroFadeIn 2s ease 0.5s forwards;
}


/* ── Utility: staggered fade-up (testimonials, feature cards) ───────────── */

/**
 * Base state: hidden. Animation applied per element via delay classes.
 * JS can also add .spa-anim-visible to trigger the animation on scroll.
 */
.spa-anim-fade-up {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s cubic-bezier(0.4, 0, 0.2, 1),
                transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.spa-anim-fade-up.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Delay modifiers — add these alongside .spa-anim-fade-up */
.spa-anim-delay-1 { transition-delay: 0.15s; }
.spa-anim-delay-2 { transition-delay: 0.30s; }
.spa-anim-delay-3 { transition-delay: 0.45s; }

/**
 * Testimonials use CSS animation (always plays; no JS IntersectionObserver).
 * The stagger is achieved via nth-child animation-delay.
 */
.spa-testimonials .spa-testi {
    opacity: 0;
    animation: fadeUp 0.8s ease forwards;
}
.spa-testimonials .spa-testi:nth-child(1) { animation-delay: 0.2s; }
.spa-testimonials .spa-testi:nth-child(2) { animation-delay: 0.4s; }
.spa-testimonials .spa-testi:nth-child(3) { animation-delay: 0.6s; }


/* ── Accessibility: honour reduced-motion preference ───────────────────── */

@media (prefers-reduced-motion: reduce) {
    /* Show all animated elements immediately in their final state */
    .spa-hero__content,
    .spa-testimonials .spa-testi,
    .spa-anim-fade-up {
        opacity: 1 !important;
        transform: none !important;
        animation: none !important;
        transition: none !important;
    }

    /* Stop gallery auto-scroll */
    .spa-gallery-track {
        animation: none !important;
    }

    .spa-catalogue-orb {
        animation: none !important;
    }
}
