/* ============================================================
   ELEVEN — Animations
   
   MOTION HIERARCHY:
   1. Scroll reveals  — one-shot entrance, IntersectionObserver driven
   2. Perpetual float  — ambient idle motion on hero phone
   3. Hover reactions  — card tilt, image zoom, button lift
   4. Theme transition — 600ms color/shadow swap (handled in tokens)
   
   RULES:
   - Only transform + opacity + filter are animated (no layout thrash)
   - will-change is set surgically and only on active elements
   - All durations/easings use CSS custom properties from tokens.css
   - prefers-reduced-motion: everything collapses to instant
   ============================================================ */


/* ═══════════════════════════════════════════════════════════
   1. SCROLL REVEALS
   
   Pattern: .reveal        → fade up 30px
            .reveal--left   → fade from left 50px
            .reveal--right  → fade from right 50px
            .reveal--scale  → fade + scale from 0.94
            
   Activation: JS adds .reveal--visible via IntersectionObserver
   Stagger: parent has .reveal-stagger, children get --stagger-i
            set by JS (scoped per parent, not global)
   ═══════════════════════════════════════════════════════════ */

/* Base: fade up */
.reveal {
    opacity: 0;
    transform: translateY(30px);
    filter: blur(4px);
    will-change: opacity, transform, filter;
    transition:
        opacity    var(--duration-slow) var(--ease-out-expo),
        transform  var(--duration-slow) var(--ease-out-expo),
        filter     var(--duration-slow) var(--ease-out-expo);
}
.reveal--visible {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
    will-change: auto;
}

/* Directional: left */
.reveal--left {
    opacity: 0;
    transform: translateX(-50px);
    filter: blur(4px);
    will-change: opacity, transform, filter;
    transition:
        opacity    var(--duration-slow) var(--ease-out-expo),
        transform  var(--duration-slow) var(--ease-out-expo),
        filter     var(--duration-slow) var(--ease-out-expo);
}
.reveal--left.reveal--visible {
    opacity: 1;
    transform: translateX(0);
    filter: blur(0);
    will-change: auto;
}

/* Directional: right */
.reveal--right {
    opacity: 0;
    transform: translateX(50px);
    filter: blur(4px);
    will-change: opacity, transform, filter;
    transition:
        opacity    var(--duration-slow) var(--ease-out-expo),
        transform  var(--duration-slow) var(--ease-out-expo),
        filter     var(--duration-slow) var(--ease-out-expo);
}
.reveal--right.reveal--visible {
    opacity: 1;
    transform: translateX(0);
    filter: blur(0);
    will-change: auto;
}

/* Scale in (testimonial, CTA) */
.reveal--scale {
    opacity: 0;
    transform: scale(0.94);
    filter: blur(4px);
    will-change: opacity, transform, filter;
    transition:
        opacity    var(--duration-slow) var(--ease-out-expo),
        transform  var(--duration-slow) var(--ease-out-expo),
        filter     var(--duration-slow) var(--ease-out-expo);
}
.reveal--scale.reveal--visible {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
    will-change: auto;
}

/* ── Stagger ──
   Parent: .reveal-stagger
   Children: .reveal with --stagger-i set by JS (0, 1, 2…)
   Delay = index × 120ms (enough to read the sequence, not so slow it drags) */
.reveal-stagger > .reveal,
.reveal-stagger > .reveal--left,
.reveal-stagger > .reveal--right {
    transition-delay: calc(var(--stagger-i, 0) * 120ms);
}
/* Once visible, clear the delay so hover transitions aren't laggy */
.reveal-stagger > .reveal--visible {
    transition-delay: 0ms;
}


/* ═══════════════════════════════════════════════════════════
   2. PERPETUAL FLOAT — Hero phone idle animation
   
   The phone uses a CSS @keyframes loop for ambient movement.
   Problem: float sets transform, which fights with reveal.
   Solution: float lives on .floating-phone, reveal lives on
   .phone-container (the parent). They never collide.
   ═══════════════════════════════════════════════════════════ */

@keyframes float-gentle {
    0%   { transform: translateY(0px)   rotateX(0deg)    rotateY(0deg);   }
    25%  { transform: translateY(-10px) rotateX(0.8deg)  rotateY(-0.4deg);}
    50%  { transform: translateY(-4px)  rotateX(-0.4deg) rotateY(0.6deg); }
    75%  { transform: translateY(-14px) rotateX(0.4deg)  rotateY(-0.3deg);}
    100% { transform: translateY(0px)   rotateX(0deg)    rotateY(0deg);   }
}

.float-3d {
    animation: float-gentle 7s ease-in-out infinite;
    will-change: transform;
}

/* When phone-tilt JS takes over on hover, pause the CSS animation */
.float-3d.tilt-active {
    animation-play-state: paused;
}

/* Subtle float for decorative elements */
@keyframes float-subtle {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-5px); }
}
.float-subtle {
    animation: float-subtle 4s ease-in-out infinite;
}


/* ═══════════════════════════════════════════════════════════
   3. HERO BACKGROUND TEXT — slow drift
   ═══════════════════════════════════════════════════════════ */

@keyframes drift-slow {
    0%, 100% { transform: translate(-50%, -50%) scale(1);     }
    50%      { transform: translate(-50%, -52%) scale(1.008);  }
}
.hero-bg-text {
    animation: drift-slow 14s ease-in-out infinite;
}


/* ═══════════════════════════════════════════════════════════
   4. HOVER REACTIONS
   ═══════════════════════════════════════════════════════════ */

/* Card tilt on hover — CSS fallback when JS tilt is unavailable.
   JS phone-tilt overrides this for .phone-container. */
.card-tilt {
    transition:
        transform  var(--duration-normal) var(--ease-smooth),
        box-shadow var(--duration-normal) var(--ease-smooth);
}
.card-tilt:hover {
    transform: perspective(800px) rotateX(1.5deg) rotateY(-1.5deg) translateY(-6px);
    box-shadow: var(--shadow-elevated);
}

/* Image zoom inside cards */
.savoir-card:hover .savoir-img-wrap img,
.split-media:hover img {
    transform: scale(1.03);
}

/* Glow pulse for active/featured elements */
@keyframes glow-pulse {
    0%, 100% { box-shadow: var(--shadow-card); }
    50%      { box-shadow: var(--shadow-glow), var(--shadow-card); }
}
.glow-active {
    animation: glow-pulse 3s ease-in-out infinite;
}


/* ═══════════════════════════════════════════════════════════
   5. PHONE HOVER PARALLAX (JS-driven)
   
   The phone-tilt.js module sets inline transform on .floating-phone
   based on mouse position. These CSS rules provide the transition
   smoothing so JS only needs to set the target values.
   ═══════════════════════════════════════════════════════════ */

.phone-container {
    perspective: 1200px;
}

/* Smooth return when mouse leaves */
.floating-phone {
    transition:
        transform  0.6s var(--ease-out-expo),
        box-shadow var(--duration-normal) var(--ease-smooth),
        background-color var(--transition-theme),
        border-color var(--transition-theme);
}

/* While hovering, use faster tracking (set by JS via .tilt-active) */
.floating-phone.tilt-active {
    transition:
        transform  0.12s linear,
        box-shadow var(--duration-normal) var(--ease-smooth),
        background-color var(--transition-theme),
        border-color var(--transition-theme);
}

/* Shadow reacts to tilt — JS applies data attribute for shadow direction */
.floating-phone.tilt-active {
    box-shadow: var(--shadow-elevated);
}


/* ═══════════════════════════════════════════════════════════
   6. REDUCED MOTION — everything collapses to instant
   ═══════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
    /* All reveals: visible immediately */
    .reveal,
    .reveal--left,
    .reveal--right,
    .reveal--scale {
        opacity: 1;
        transform: none;
        filter: none;
        transition: none;
        will-change: auto;
    }

    /* All perpetual animations: off */
    .float-3d,
    .float-subtle,
    .hero-bg-text,
    .glow-active {
        animation: none;
    }

    /* Hover tilt: off */
    .card-tilt:hover {
        transform: none;
    }

    /* Image zoom: off */
    .savoir-card:hover .savoir-img-wrap img,
    .split-media:hover img {
        transform: none;
    }

    /* Phone tilt: off (JS also checks, but belt + suspenders) */
    .floating-phone,
    .floating-phone.tilt-active {
        transition: none;
        transform: none !important;
    }

    /* Nuclear: no transitions or animations on anything */
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
