/* =============================================================================
   D1 — animations.css
   Split-text, scroll reveals, marquee loops, CSS-only moments.
   ============================================================================= */

/* Word / char split (used by SplitType via app.js). */
.split-char, .split-word, .split-line {
    display: inline-block;
    overflow: hidden;
}
.split-line { display: block; }
.split-char { position: relative; }

/* Pre-reveal state applied to split chars / lines. JS sets translate 100% to 0. */
html.is-loading .d1-hero__title .char,
html.is-loading .d1-hero__title .word { transform: translateY(110%); opacity: 0; }

/* Marquee base loop (JS replaces transform via GSAP for scroll-velocity bias). */
@keyframes d1-marquee-loop {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}
.d1-marquee__track--auto {
    animation: d1-marquee-loop 28s linear infinite;
}
.d1-marquee--reverse .d1-marquee__track--auto {
    animation-direction: reverse;
}

@media (prefers-reduced-motion: reduce) {
    .d1-marquee__track--auto { animation: none; }
}

/* Reveal baseline (JS toggles the class). */
[data-reveal="section"],
[data-reveal="up"],
[data-reveal="fade"],
[data-reveal="zoom"] {
    opacity: 0;
    transform: translateY(36px);
    transition: opacity 700ms var(--d1-ease-out), transform 900ms var(--d1-ease-out);
}
[data-reveal="fade"] { transform: none; }
[data-reveal].is-revealed {
    opacity: 1;
    transform: translate3d(0,0,0);
}

/* chars / lines variants keep their parent visible — the inner chars are
   animated by GSAP, and the parent's opacity should stay 1 so the child
   transforms (yPercent) aren't hidden behind the element's own 0 opacity. */
[data-reveal="chars"],
[data-reveal="lines"] {
    opacity: 1;
    transform: none;
}

/* Char reveal lines wrapper (for hero + big headings). */
.d1-split-line {
    display: block;
    overflow: hidden;
}

/* Quick scale-in on big images. */
[data-reveal="zoom"] {
    transform: scale(0.96);
    transform-origin: center;
}
[data-reveal="zoom"].is-revealed {
    transform: scale(1);
}

/* Snap pulse used on residency row numbers. */
@keyframes d1-blink {
    0%, 70%, 100% { opacity: 1; }
    80%, 90% { opacity: 0.3; }
}
.d1-residencies .d1-res-row__num {
    animation: d1-blink 3.8s var(--d1-ease-out) infinite;
}
@media (prefers-reduced-motion: reduce) { .d1-residencies .d1-res-row__num { animation: none; } }

/* Hero video scale-out on scroll — GSAP scrubs this. */
.d1-hero__video-wrap { will-change: transform, border-radius; }

/* Custom cursor label pairing. */
[data-cursor="view"]:hover ~ .d1-cursor__label,
[data-cursor="play"]:hover ~ .d1-cursor__label { opacity: 1; }
