/* kinetic.css — split text, reveal states, scroll-linked type, drift rows, marquees, stars.
   SPEC §3.7 (+ §2.5 variants, §2.6 sides/lag, §2.7 velocity skew, §2.10 reduced/mobile).
   kinetic.js writes the state and the per-unit variables; this file turns them into motion.

   Host attributes (written by kinetic.js)
     data-k   pre | pre-up | in | done | out | scrub | idle      state (idle = manual host not yet driven)
     data-kv  the effective variant (sides, sides-soft, rise, flip, wave, stretch, blur, scramble, scrub)
     data-ku  the animated unit: l (lines) | w (words) | c (chars)
     data-kl  lines were measured (the host had a box when it was split; otherwise only <br> breaks lines)
     data-kwc off = this host is over the will-change budget (§5.2)
     --d0 (start delay) --st (per-unit stagger) --lst (per-line stagger) --n --nl --nw (counts)
     --tempo / --stk (fast-scroll compression, P2) --x (exit 0..1)
   Structure
     host > .k-wrap[aria-hidden] > .k-l(--li, --side) > .k-li > [inline clones] > .k-w(--wi --k --cd) > .k-c(--ci --k --cd)
     + .sr-only (plain text for screen readers). The animated unit carries .k-u and --i (its delay index). */

:root{
  --k-rtl:1; --k-start:0%;
  --k-star:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C12.9 7.6 16.4 11.1 24 12C16.4 12.9 12.9 16.4 12 24C11.1 16.4 7.6 12.9 0 12C7.6 11.1 11.1 7.6 12 0Z'/%3E%3C/svg%3E");
}
html[dir=rtl]{--k-rtl:-1; --k-start:100%}

/* ---------------------------------------------------------------- 0. no flash before the split
   Until kinetic has split (html.k-ready) the hosts are laid out but invisible, so the static text never flashes
   before its start pose. If kinetic never loads, html.is-entered (main.js, after the preloader) shows them. */
html.js:not(.k-ready):not(.is-entered) :is([data-split]:not([data-reveal=manual]),[data-scroll-x]){visibility:hidden}

/* ---------------------------------------------------------------- 1. structure */
span[data-split],.k-inline{display:inline-block;max-width:100%}
.k-wrap{display:block}
.k-l{display:block}
.k-li{display:block}
.k-w{display:inline-block;white-space:nowrap}
.k-c,.k-s{display:inline-block}
[data-kl] .k-li{white-space:nowrap}                    /* a measured line never re-wraps (re-split on resize) */
/* Measuring pass only (inside one synchronous split): no transforms from any owner, chars inline so the font's
   kerning shows; kinetic.js then gives each inline-block char the margin that restores its kerned advance. */
.k-measure :is(.k-l,.k-li,.k-w,.k-c,.k-s,.m-base,.m-fill){transform:none!important;transition:none!important;animation:none!important;filter:none!important}
.k-kern :is(.k-c,.k-s){display:inline!important}
.k-atom{vertical-align:baseline}
[data-layers=fill] .k-li{position:relative}
[data-layers=fill] .m-base{display:block}
[data-layers=fill] .m-fill{position:absolute;inset:0;display:block;pointer-events:none}

/* Masks (crisp edges; generous outsets so ascenders, descenders and niqqud never clip). Only while moving. */
:is([data-kv=rise],[data-kv=wave]):is([data-k^=pre],[data-k=in]) .k-l,
[data-reveal=manual][data-mask] .k-l{clip-path:inset(-.2em -.08em -.28em -.08em)}

/* ---------------------------------------------------------------- 2. state plumbing */
[data-k^=pre]{--vy:1}
[data-k=pre-up]{--vy:-1}
[data-k^=pre] *{transition:none!important}
[data-k] .k-l{--ld:calc(var(--d0,0ms) + var(--li,0)*var(--lst,0ms)*var(--stk,1)*var(--tempo,1))}
[data-k] .k-u{--ud:calc(var(--ld,0ms) + var(--i,0)*var(--st,0ms)*var(--stk,1)*var(--tempo,1))}
[data-k=in]:not([data-kwc]):is([data-kv=sides],[data-kv=sides-soft],[data-ku=l]) .k-li,
[data-k=in]:not([data-kwc]):not([data-ku=l]):not([data-kv=scramble]):not([data-kv=sides-soft]) .k-u{will-change:transform,opacity}
/* Gate closed while on screen: a quick fade, then kinetic resets to pre. */
[data-k=out]>.k-wrap{opacity:0;transition:opacity 240ms linear}

/* ---------------------------------------------------------------- 3. variants (§2.5) */
/* sides: lines fly in from alternating sides, leaning into the motion; trailing letters lag and snap together */
[data-kv=sides][data-k^=pre] .k-li{transform:translate3d(calc(var(--side)*var(--dx-far)),0,0) skewX(calc(var(--side)*var(--skew)));opacity:0}
[data-kv=sides][data-k^=pre] .k-u{transform:translate3d(calc(var(--side)*var(--k)*var(--lag)),0,0)}
[data-kv=sides][data-k=in] .k-li{transition:transform calc(var(--d-xl)*var(--tempo)) var(--ease-out) var(--ld),opacity var(--d-fade) linear var(--ld)}
[data-kv=sides][data-k=in] .k-u{transition:transform calc(1350ms*var(--tempo)) var(--ease-out) var(--ud)}

/* sides-soft: a short slide from the side */
[data-kv=sides-soft][data-k^=pre] .k-li{transform:translate3d(calc(var(--side)*var(--dx-near)),0,0);opacity:0}
[data-kv=sides-soft][data-k=in] .k-li{transition:transform calc(var(--d-l)*var(--tempo)) var(--ease-out) var(--ld),opacity var(--d-fade) linear var(--ld)}

/* rise (masked): lines, words or chars rise out of their line's mask; from above when the host is above (pre-up) */
[data-kv=rise] :is(.k-li,.k-u){transform-origin:var(--k-start) 100%}
[data-kv=rise][data-ku=l][data-k^=pre] .k-li,
[data-kv=rise]:not([data-ku=l])[data-k^=pre] .k-u{transform:translate3d(0,calc(var(--vy)*var(--dy-mask)),0) rotate(calc(var(--vy)*var(--k-rtl)*3deg));opacity:0}
[data-kv=rise][data-ku=l][data-k=in] .k-li{transition:transform calc(var(--d-l)*var(--tempo)) var(--ease-out) var(--ld),opacity var(--d-fade) linear var(--ld)}
[data-kv=rise]:not([data-ku=l])[data-k=in] .k-u{transition:transform calc(var(--d-l)*var(--tempo)) var(--ease-out) var(--ud),opacity var(--d-fade) linear var(--ud)}

/* flip: chars hinge up from their baseline */
[data-kv=flip] .k-u{transform-origin:50% 100%;backface-visibility:hidden;-webkit-backface-visibility:hidden}
[data-kv=flip][data-k^=pre] .k-u{transform:perspective(700px) translate3d(0,.3em,-.4em) rotateX(calc(var(--vy)*-100deg));opacity:0}
[data-kv=flip][data-k=in] .k-u{transition:transform calc(var(--d-l)*var(--tempo)) var(--ease-out) var(--ud),opacity calc(300ms*var(--tempo)) linear var(--ud)}

/* wave (masked): chars bounce up out of the mask */
[data-kv=wave][data-k^=pre] .k-u{transform:translate3d(0,calc(var(--vy)*110%),0)}
[data-kv=wave][data-k=in] .k-u{transition:transform calc(var(--d-land)*var(--tempo)) var(--ease-back) var(--ud)}

/* stretch: chars squash-and-stretch up from the baseline, centre outward */
[data-kv=stretch] .k-u{transform-origin:50% 100%}
[data-kv=stretch][data-k^=pre] .k-u{transform:translate3d(0,35%,0) scale(.35,2.1);opacity:0}
[data-kv=stretch][data-k=in] .k-u{transition:transform calc(var(--d-land)*var(--tempo)) var(--ease-back) var(--ud),opacity calc(350ms*var(--tempo)) linear var(--ud)}

/* blur: words drift up out of focus (the filter is desktop-only, §0.2 law 5) */
[data-kv=blur][data-k^=pre] .k-u{transform:translate3d(0,.35em,0);opacity:0}
html:not(.mobile) [data-kv=blur][data-k^=pre] .k-u{filter:blur(10px)}
[data-kv=blur][data-k=in] .k-u{transition:transform calc(800ms*var(--tempo)) var(--ease-out) var(--ud),filter calc(700ms*var(--tempo)) var(--ease-out) var(--ud),opacity var(--d-fade) linear var(--ud)}

/* scramble: JS cycles the glyphs; each char is pinned to its final width so nothing jitters */
[data-kv=scramble] .k-c{width:var(--cw,auto);text-align:center}
[data-kv=scramble][data-k^=pre] .k-c,
[data-kv=scramble][data-k=in] .k-c:not(.on){opacity:0}

/* ---------------------------------------------------------------- 4. scroll-linked forms */
/* exit (outer wrapper; §2.5): back toward the side the line came from ("tide") */
.h-hero,[data-intro] [data-exit],.cap [data-exit]{--exit:var(--exit-far)}
[data-exit] .k-l{transform:translate3d(calc(var(--side)*var(--x,0)*var(--x,0)*var(--exit,var(--exit-near))),0,0);opacity:calc(1 - var(--x,0)*var(--x,0)*.6)}
/* scrub-in (inner; --q per line written by kinetic.scrub) */
[data-scrub] .k-li{--e:calc(1 - (1 - var(--q,0))*(1 - var(--q,0))*(1 - var(--q,0)));
  transform:translate3d(calc(var(--side)*(1 - var(--e))*var(--scrub-dist,70vw)),0,0) skewX(calc(var(--side)*(1 - var(--e))*var(--skew)));
  opacity:min(1,calc(var(--q,0)*3.3))}
[data-scrub] .k-u{transform:translate3d(calc(var(--side)*(1 - var(--e))*var(--k)*var(--lag)),0,0)}

/* ---------------------------------------------------------------- 5. drift rows (§3.7.7) */
.drift-row{position:relative;margin:0;font-size:var(--fs-mega);line-height:.86;letter-spacing:-.06em;white-space:nowrap;font-weight:500;
  overflow:visible;user-select:none;-webkit-user-select:none}
:lang(he) .drift-row{font-family:var(--font-he);font-weight:600;letter-spacing:-.02em;line-height:.95}
.drift-row--outline{color:transparent;-webkit-text-stroke:1.2px var(--fg)}
.k-drift{display:inline-block;white-space:nowrap;will-change:transform;backface-visibility:hidden}
.k-dc{display:inline-block;padding-inline-end:.26em}

/* ---------------------------------------------------------------- 6. marquees (§3.7.8) */
[data-marquee]{overflow:hidden}
.marquee-track{display:flex;width:max-content;direction:ltr;will-change:transform;backface-visibility:hidden}
.marquee-item{flex:none;white-space:nowrap;padding-inline-end:.5em}

/* ---------------------------------------------------------------- 7. the star (drift rows, marquees, tapes) */
.star{display:inline-block;width:.62em;height:.62em;vertical-align:-.02em;margin-inline:.04em;background:currentColor;
  -webkit-mask:var(--k-star) center/contain no-repeat;mask:var(--k-star) center/contain no-repeat;
  transform:rotate(var(--rot,0deg));font-style:normal}
.drift-row--outline .star{background:var(--accent)}

/* ---------------------------------------------------------------- 8. reduced motion (§2.10) */
html.reduced [data-k] *{transform:none!important;filter:none!important}
html.reduced [data-k] :is(.k-w,.k-c,.k-u){opacity:1!important}
html.reduced [data-k^=pre] .k-li{opacity:0!important}
html.reduced [data-k=in] .k-li{opacity:1;transition:opacity 400ms linear!important}
html.reduced [data-k=done] .k-li,html.reduced [data-scrub] .k-li{opacity:1!important}
html.reduced [data-exit] .k-l{opacity:1!important}
html.reduced [data-k] .k-l{clip-path:none!important}
html.reduced :is(.k-drift,.marquee-track){will-change:auto}
