/* Hidden Roots – Motion
   Entrances are AOS (data-aos, css/vendors/aos.css); the scroll-linked set
   pieces are GSAP (js/motion.js). This file holds the states they share and
   the CSS-only details. html.has-motion is set by js/motion.js once GSAP is
   running – without it (no JS, reduced motion) everything is simply shown.

   AOS hides [data-aos] until it runs, which would leave content invisible
   without JS; html.js (set inline in <head>) scopes that. */

html:not(.js) [data-aos] {
    opacity:   1 !important;
    transform: none !important;
}

/* ── Image reveal ────────────────────────────────────────── */
/* [data-reveal-image]: the frame opens from the bottom as it scrolls in and
   the image settles from a slight zoom. GSAP drives it; these are the start
   values, applied only once GSAP has taken over. */
.has-motion [data-reveal-image] {
    clip-path: inset(100% 0 0 0);

    img {
        transform: scale(1.18);
    }
}

/* ── Parallax ────────────────────────────────────────────── */
/* [data-parallax="0.12"] drifts the element a little with the scroll (js/motion.js). */
[data-parallax] {
    will-change: transform;
}

/* ── Marquee ─────────────────────────────────────────────── */
.marquee {
    overflow:  hidden;
    display:   flex;
    user-select: none;
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
    display:     flex;
    flex:        none;
    gap:         var(--space-xl);
    padding-right: var(--space-xl);
    animation:   marquee 38s linear infinite;
}

.marquee:hover .marquee__track {
    animation-play-state: paused;
}

@keyframes marquee {
    to { transform: translateX(-100%); }
}

/* ── Branch lines ────────────────────────────────────────── */
/* Inline SVG branches (template-parts/branches) that draw themselves – GSAP
   sets the dash offset from the scroll position. */
.branches {
    position:       absolute;
    max-width:      none;   /* the base svg { max-width: 100% } would cap them at the screen width */
    pointer-events: none;
    overflow:       visible;

    path {
        fill:            none;
        stroke:          currentColor;
        stroke-width:    1.5;
        stroke-linecap:  round;
        /* No vector-effect: non-scaling-stroke here – with it, Chrome measures
           the dash pattern in screen pixels and ignores pathLength="1", so the
           draw-in left every branch broken into dashes. */
    }
}

/* Mirrored trees grow from the bottom-left */
.branches.is-flipped {
    transform: scaleX(-1);
}

/* Branches stay hidden until js/motion.js grows them – no limb, and no
   round-cap dot, shows before its turn. Without motion they show whole. */
.js [data-branches] path {
    visibility: hidden;
}

.no-motion [data-branches] path {
    visibility: visible;
}

/* ── Reduced motion ──────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .marquee__track {
        animation: none;
    }

    [data-aos] {
        opacity:    1 !important;
        transform:  none !important;
        transition: none !important;
    }
}

/* Word-by-word headlines ([data-split], js/motion.js) */
.split-word {
    display:        inline-block;
    overflow:       hidden;
    vertical-align: top;
    padding-bottom: 0.08em;   /* room for descenders inside the mask */

    > span {
        display: inline-block;
    }
}
