/* ==========================================================================
   Weekend English — Motion
   --------------------------------------------------------------------------
   Three layers, each optional:

   1. Reveal-on-enter, driven by one IntersectionObserver in main.js. It
      adds .is-visible, and everything keyed off that class is a transition,
      so it works in every browser.
   2. Scroll-driven animations (animation-timeline: scroll() / view()) for
      effects that should track the scroll position itself. All of them sit
      inside @supports, so a browser without them just gets the end state.
   3. A view transition when the theme changes.

   prefers-reduced-motion switches all three off at the bottom of the file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Reveal on enter
   --------------------------------------------------------------------------
   Gated behind the .js class stamped on <html> before first paint. Hiding
   content in the base stylesheet would leave a blank page for anyone
   without JavaScript, so the hidden state only exists when the script that
   reveals it is guaranteed to run.
   -------------------------------------------------------------------------- */

.js .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 700ms var(--ease), transform 900ms var(--ease-out);
}

.js .reveal.is-visible {
    opacity: 1;
    transform: none;
}

/* How it works: the three steps arrive one after another, then the mini
   illustrations start moving. */
.js .loop__step {
    transition: opacity 600ms var(--ease), translate 800ms var(--spring);
}

.js .loop:not(.is-visible) .loop__step {
    opacity: 0;
    translate: 0 1.25rem;
}

.loop__step:nth-child(2) { transition-delay: 150ms; }
.loop__step:nth-child(3) { transition-delay: 300ms; }

.loop.is-visible .mini__wave i {
    animation: wave 1s ease-in-out infinite;
}

.mini__wave i:nth-child(2) { animation-delay: -0.2s; }
.mini__wave i:nth-child(3) { animation-delay: -0.5s; }
.mini__wave i:nth-child(4) { animation-delay: -0.1s; }
.mini__wave i:nth-child(5) { animation-delay: -0.7s; }
.mini__wave i:nth-child(6) { animation-delay: -0.35s; }
.mini__wave i:nth-child(7) { animation-delay: -0.6s; }

@keyframes wave {
    50% { transform: scaleY(1); }
}

.loop.is-visible .mini__opts .is-ok {
    animation: ok-pop 700ms var(--spring) 900ms both;
}

@keyframes ok-pop {
    from {
        border-color: var(--rule-strong);
        background: transparent;
        color: var(--ink);
        transform: scale(0.9);
    }
}

/* For you: benefits rise in sequence, the phone floats up. */
.js .benefits li {
    transition: opacity 600ms var(--ease), translate 800ms var(--spring);
}

.js .benefits:not(.is-visible) li {
    opacity: 0;
    translate: 0 1rem;
}

.benefits li:nth-child(2) { transition-delay: 100ms; }
.benefits li:nth-child(3) { transition-delay: 200ms; }
.benefits li:nth-child(4) { transition-delay: 300ms; }

/* --------------------------------------------------------------------------
   Kinetic headline: each word rises out of a blur on load.
   -------------------------------------------------------------------------- */

.kinetic .w {
    display: inline-block;
    animation: word-rise 1000ms var(--spring) both;
    animation-delay: calc(var(--i) * 70ms + 120ms);
}

@keyframes word-rise {
    from {
        opacity: 0;
        transform: translateY(0.5em) rotate(2deg);
        filter: blur(8px);
    }
    60% {
        filter: blur(0);
    }
}

.hero__kicker::before {
    animation: draw-x 900ms var(--ease-out) both 100ms;
    transform-origin: left;
}

@keyframes draw-x {
    from { transform: scaleX(0); }
}

.hero__aside,
.spec-strip {
    animation: fade-up 900ms var(--ease-out) both;
    animation-delay: 650ms;
}

.spec-strip {
    animation-delay: 800ms;
}

@keyframes fade-up {
    from { opacity: 0; transform: translateY(14px); }
}

/* --------------------------------------------------------------------------
   Scroll-driven
   -------------------------------------------------------------------------- */

@supports (animation-timeline: scroll()) {
    /* Reading progress under the masthead. */
    .read-progress {
        animation: grow-x linear both;
        animation-timeline: scroll(root block);
    }

    @keyframes grow-x {
        from { transform: scaleX(0); }
        to   { transform: scaleX(1); }
    }
}

@supports (animation-timeline: view()) {
    /* The film eases up and to full size as it scrolls into view. Uses the
       individual scale/translate properties so it composes with .reveal's
       transform instead of fighting it. */
    .film__frame {
        animation: film-rise linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 70%;
    }

    @keyframes film-rise {
        from { scale: 0.94; translate: 0 2.5rem; }
        to   { scale: 1;    translate: 0 0; }
    }

    /* The phone in "Per te" drifts against the scroll, a light parallax. */
    .benefits__device .phone {
        animation: drift linear both;
        animation-timeline: view();
        animation-range: cover 0% cover 100%;
    }

    @keyframes drift {
        from { translate: 0 2.5rem; rotate: -1.5deg; }
        to   { translate: 0 -2.5rem; rotate: 1.5deg; }
    }

    /* Section numbers slide along their rule as each section enters. */
    .eyebrow-num {
        animation: num-in linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 80%;
    }

    @keyframes num-in {
        from { opacity: 0; translate: -0.75rem 0; }
    }
}

/* --------------------------------------------------------------------------
   Reduced motion: end states only. (base.css already collapses durations;
   this removes the things that would otherwise still run or track scroll.)
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .kinetic .w,
    .hero__kicker::before,
    .hero__aside,
    .spec-strip,
    .read-progress,
    .film__frame,
    .benefits__device .phone,
    .eyebrow-num,
    .loop__return path,
    .mini__wave i,
    .mini__opts .is-ok,
    .fex__caret {
        animation: none !important;
    }

    .read-progress {
        display: none;
    }

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