/* global React, TimelineContext, clamp, Easing */
// ScrollStage — sticky scroll-driven video. The page scroll within the section
// drives the timeline 0 → duration, instead of a RAF playhead.
// Reuses TimelineContext from animations.jsx so Sprite/useTime still work.
const _sc = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
function useIsMobile() {
const [isMobile, setIsMobile] = React.useState(typeof window !== 'undefined' ? window.innerWidth < 1024 : false);
React.useEffect(() => {
const check = () => setIsMobile(window.innerWidth < 1024);
window.addEventListener('resize', check);
return () => window.removeEventListener('resize', check);
}, []);
return isMobile;
}
function ScrollStage({
width = 1920,
height = 1080,
duration = 60,
background,
scrollVH = 700,
children,
label,
fit = 0.94, // fraction of viewport to occupy
}) {
const isMobile = useIsMobile();
const cWidth = isMobile ? 1080 : width;
const cHeight = isMobile ? 1920 : height;
const outerRef = React.useRef(null);
const [time, setTime] = React.useState(0);
const [scale, setScale] = React.useState(1);
const [progress, setProgress] = React.useState(0);
React.useEffect(() => {
const onScroll = () => {
const el = outerRef.current;
if (!el) return;
const rect = el.getBoundingClientRect();
const vh = window.innerHeight;
const total = el.offsetHeight - vh;
if (total <= 0) return;
const scrolled = _sc(-rect.top, 0, total);
const p = scrolled / total;
setProgress(p);
setTime(p * duration);
};
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
return () => window.removeEventListener('scroll', onScroll);
}, [duration]);
React.useEffect(() => {
const fit_ = () => {
const vw = window.innerWidth;
const vh = window.innerHeight;
const s = Math.min(vw / cWidth, vh / cHeight) * fit;
setScale(s);
};
fit_();
window.addEventListener('resize', fit_);
return () => window.removeEventListener('resize', fit_);
}, [cWidth, cHeight, fit]);
const ctxValue = React.useMemo(() => ({ time, duration, playing: false }), [time, duration]);
return (
{blurb}
{stats && (