/* Runtime mechanics for the DOM layer. Templates style the look; this file only makes the effects work.
   Timing tokens can be overridden per template: --ease-out, --reveal-dur, --stagger. */
:root { --ease-out: cubic-bezier(.16, .84, .24, 1); --ease-io: cubic-bezier(.65, 0, .35, 1); --reveal-dur: .95s; --stagger: 18ms; }

/* the hidden attribute always hides (a component's own display must not override it) */
[hidden] { display: none !important; }

/* the WebGL canvas sits behind the page */
canvas.gl { position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; pointer-events: none; }
canvas.gl.is-interactive { pointer-events: auto; }
.no-webgl canvas.gl { display: none; }
.poster { display: none; }
.no-webgl .poster { display: block; position: fixed; inset: 0; z-index: 0; background-size: cover; background-position: center; }

/* split text */
.is-split .w { display: inline-block; white-space: nowrap; }
.is-split .u { display: inline-block; will-change: transform, opacity; }

/* reveal presets: [data-reveal] + .is-in (added when the element enters) */
[data-reveal] { --d: 0ms; }
[data-reveal="rise"].is-split .w { overflow: hidden; vertical-align: top; padding: 0.06em 0.02em 0.1em; margin: -0.06em -0.02em -0.1em; }
[data-reveal="rise"].is-split .u { transform: translate3d(0, 110%, 0) rotate(3deg); transition: transform var(--reveal-dur) var(--ease-out) calc(var(--i) * var(--stagger)); }
[data-reveal="rise"].is-split.is-in .u { transform: none; }
[data-reveal="fade"].is-split .u, [data-reveal="blur"].is-split .u, [data-reveal="scale"].is-split .u, [data-reveal="slide"].is-split .u {
  opacity: 0; transition: opacity var(--reveal-dur) var(--ease-out) calc(var(--i) * var(--stagger)), transform var(--reveal-dur) var(--ease-out) calc(var(--i) * var(--stagger)), filter var(--reveal-dur) var(--ease-out) calc(var(--i) * var(--stagger)); }
[data-reveal="fade"].is-split .u { transform: translate3d(0, .35em, 0); }
[data-reveal="blur"].is-split .u { filter: blur(10px); transform: scale(1.08); }
[data-reveal="scale"].is-split .u { transform: scale(0.2); }
[data-reveal="slide"].is-split .u { transform: translate3d(-.6em, 0, 0); }
[data-reveal].is-split.is-in .u { opacity: 1; transform: none; filter: none; }
/* whole-block reveals */
[data-reveal="fade"]:not(.is-split), [data-reveal="rise"]:not(.is-split) { opacity: 0; transform: translate3d(0, 28px, 0); transition: opacity 1s var(--ease-out) var(--d), transform 1.1s var(--ease-out) var(--d); }
[data-reveal="blur"]:not(.is-split) { opacity: 0; filter: blur(14px); transition: opacity 1.1s var(--ease-out), filter 1.2s var(--ease-out); }
[data-reveal="scale"]:not(.is-split) { opacity: 0; transform: scale(.94); transition: opacity 1s var(--ease-out), transform 1.2s var(--ease-out); }
[data-reveal="clip"] { clip-path: inset(0 0 100% 0); transition: clip-path 1.2s var(--ease-io); }
[data-reveal].is-in:not(.is-split) { opacity: 1; transform: none; filter: none; clip-path: inset(0 0 0 0); }
[data-reveal="scramble"], [data-reveal="type"] { opacity: 1; }
/* a capture (window.__studio.settle) shows reveals at rest: their transitions are off for that frame */
html.settling [data-reveal], html.settling [data-reveal] .u { transition: none !important; }
.reduced [data-reveal], .reduced [data-reveal] .u { opacity: 1 !important; transform: none !important; filter: none !important; clip-path: none !important; transition: none !important; }

/* letter roll on hover ([data-roll]) */
.roll { position: relative; display: inline-block; overflow: hidden; vertical-align: top; line-height: 1.15; }
.roll-a, .roll-b { display: inline-block; white-space: nowrap; }
.roll-b { position: absolute; left: 0; top: 100%; }
.roll .ru { display: inline-block; transition: transform .42s var(--ease-out) calc(var(--i) * 16ms); }
[data-roll]:hover .roll .ru, [data-roll]:focus-visible .roll .ru { transform: translateY(-100%); }
.reduced [data-roll] .roll .ru { transition: none; }

/* tickers */
.marquee { display: flex; overflow: hidden; white-space: nowrap; }
.marquee-track { display: flex; flex-shrink: 0; align-items: center; will-change: transform; }

/* custom cursor (pointer devices only) */
.has-cursor, .has-cursor a, .has-cursor button { cursor: none; }
.cursor { position: fixed; left: 0; top: 0; z-index: 1000; pointer-events: none; --s: 1; }
.cursor i { position: absolute; left: -5px; top: -5px; width: 10px; height: 10px; border-radius: 50%; background: currentColor; transform: scale(var(--s)); transition: width .35s var(--ease-out), height .35s var(--ease-out), left .35s var(--ease-out), top .35s var(--ease-out), opacity .3s; }
.cursor.is-link i { width: 44px; height: 44px; left: -22px; top: -22px; opacity: .25; }
.cursor.is-down i { transform: scale(calc(var(--s) * .7)); }
.cursor span { position: absolute; left: 16px; top: 12px; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; opacity: 0; transition: opacity .3s; }
.cursor.has-label span { opacity: 1; }
.cursor.is-out { opacity: 0; }
@media (hover: none) { .cursor { display: none; } }

/* loader: templates style it; --p carries real progress 0..1 */
.loader { position: fixed; inset: 0; z-index: 900; transition: opacity .9s var(--ease-io), visibility .9s; }
.is-loaded .loader { opacity: 0; visibility: hidden; pointer-events: none; }

/* header that hides on the way down */
.autohide { transition: transform .6s var(--ease-out), background-color .4s; }
.autohide.is-hidden { transform: translate3d(0, -120%, 0); }

/* sound toggle: four bars that dance when on */
.sound-bars { display: inline-flex; gap: 2px; align-items: flex-end; height: 10px; }
.sound-bars i { width: 2px; height: 3px; background: currentColor; transition: height .3s; }
.is-on .sound-bars i { animation: sb 1s ease-in-out infinite; }
.is-on .sound-bars i:nth-child(2) { animation-delay: -.3s; } .is-on .sound-bars i:nth-child(3) { animation-delay: -.6s; } .is-on .sound-bars i:nth-child(4) { animation-delay: -.15s; }
@keyframes sb { 0%, 100% { height: 3px; } 50% { height: 10px; } }
.reduced .is-on .sound-bars i { animation: none; height: 6px; }

.visually-hidden { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
