/* =========================================================================
   EDUVAL — ANIMATIONS
   Scroll reveals, floats, skeleton shimmer, page fade-in.
   All animations are disabled under prefers-reduced-motion.
   ========================================================================= */

/* ---- Page fade-in on load ---- */
@keyframes eduval-page-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* Applied to body directly, NOT via a class that JavaScript adds later.
   The class version fired on DOMContentLoaded — by which time the page was
   already painted — so the animation restarted it from opacity 0 and the whole
   page blinked out and faded back in. That was invisible on fast cached pages
   and very visible on the uncached dashboard. Applying it in CSS means the fade
   runs as the page first paints, which is what it was always meant to do. */
body { animation: eduval-page-in 300ms ease both; }

/* ---- Scroll-triggered reveal ---- */
.eduval-reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity .4s ease, transform .4s ease;
    will-change: opacity, transform;
}
.eduval-reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
}
/* staggered children */
.eduval-stagger > * {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity .4s ease, transform .4s ease;
}
.eduval-stagger.is-visible > * {
    opacity: 1;
    transform: translateY(0);
}
.eduval-stagger.is-visible > *:nth-child(1) { transition-delay: .00s; }
.eduval-stagger.is-visible > *:nth-child(2) { transition-delay: .06s; }
.eduval-stagger.is-visible > *:nth-child(3) { transition-delay: .12s; }
.eduval-stagger.is-visible > *:nth-child(4) { transition-delay: .18s; }
.eduval-stagger.is-visible > *:nth-child(5) { transition-delay: .24s; }
.eduval-stagger.is-visible > *:nth-child(6) { transition-delay: .30s; }
.eduval-stagger.is-visible > *:nth-child(7) { transition-delay: .36s; }
.eduval-stagger.is-visible > *:nth-child(8) { transition-delay: .42s; }

/* ---- Floating hero element ---- */
@keyframes eduval-float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50%      { transform: translateY(-22px) rotate(8deg); }
}

/* ---- Skeleton shimmer (loading state) ---- */
.eduval-skeleton {
    position: relative;
    overflow: hidden;
    background: var(--eduval-surface-2);
    border-radius: var(--eduval-radius);
}
.eduval-skeleton::after {
    content: "";
    position: absolute; inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(
        90deg,
        transparent,
        rgba(var(--eduval-secondary-rgb), .15),
        transparent
    );
    animation: eduval-shimmer 1.3s infinite;
}
@keyframes eduval-shimmer {
    100% { transform: translateX(100%); }
}
.eduval-skeleton-card { height: 280px; }
.eduval-skeleton-line { height: 14px; margin: 8px 0; border-radius: 6px; }

/* ---- Drawer slide handled via transform in main.css ---- */

/* ---- Reduced motion: turn everything off ---- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    .eduval-reveal,
    .eduval-stagger > * {
        opacity: 1 !important;
        transform: none !important;
    }
    .eduval-hero__float { animation: none !important; }
}

/* Fade-up entrance used by cart, checkout, and empty-cart blocks. */
@keyframes eduval-fade-up {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .eduval-cart, .eduval-checkout, .eduval-cart-empty,
    .eduval-cart__table tbody tr,
    .eduval-checkout__details, .eduval-checkout__order,
    .eduval-cart__collaterals {
        animation: none !important;
    }
}

/* ---- Failsafe for scroll reveals ----
   .eduval-reveal and .eduval-stagger start at opacity 0 and are revealed by
   main.js, which is deferred. On a slow, uncached page the browser can paint
   before that script runs, leaving the visitor looking at an empty page — this
   was visible on the dashboard as a white flash on every reload.
   These rules reveal the content on their own after a short delay, so a slow,
   blocked or broken script can never leave the page blank. The IntersectionObserver
   normally wins long before this fires, so the animations still look the same. */
@keyframes eduval-reveal-failsafe { to { opacity: 1; transform: none; } }

.eduval-reveal,
.eduval-stagger > * {
    animation: eduval-reveal-failsafe .3s ease 1s both;
}
.eduval-reveal.is-visible,
.eduval-stagger.is-visible > * {
    animation: none;
}

@media (prefers-reduced-motion: reduce) {
    .eduval-reveal,
    .eduval-stagger > * { animation: none; opacity: 1; transform: none; }
}
