const MOTION_OK=!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches);
function Reveal({as="div",delay=0,className="",style,children,...rest}){
  const Tag=as;
  const ref=React.useRef(null);
  const [inView,setInView]=React.useState(!MOTION_OK);
  React.useEffect(()=>{
    if(!MOTION_OK)return;
    const el=ref.current;if(!el)return;
    const io=new IntersectionObserver(es=>{if(es[0].isIntersecting){setInView(true);io.disconnect();}},{threshold:.12,rootMargin:"0px 0px -7% 0px"});
    io.observe(el);return()=>io.disconnect();
  },[]);
  return <Tag ref={ref} className={"rv "+(inView?"in ":"")+className} style={{...style,"--rd":delay+"ms"}} {...rest}>{children}</Tag>;
}
function Words({text,start=0,step=80}){
  const [go,setGo]=React.useState(!MOTION_OK);
  React.useEffect(()=>{
    if(!MOTION_OK)return;
    let r2;const r1=requestAnimationFrame(()=>{r2=requestAnimationFrame(()=>setGo(true));});
    return()=>{cancelAnimationFrame(r1);if(r2)cancelAnimationFrame(r2);};
  },[]);
  return <span className={go?"in":""}>{text.split(" ").map((w,i)=><React.Fragment key={i}><span className="wmask"><span style={{"--wd":(start+i*step)+"ms"}}>{w}</span></span>{i<text.split(" ").length-1?" ":""}</React.Fragment>)}</span>;
}
function ScrollProgress(){
  const ref=React.useRef(null);
  React.useEffect(()=>{
    const el=ref.current;let raf=0;
    const on=()=>{raf=0;const h=document.documentElement;const max=h.scrollHeight-h.clientHeight;if(el)el.style.transform="scaleX("+(max>0?h.scrollTop/max:0)+")";};
    const req=()=>{if(!raf)raf=requestAnimationFrame(on);};
    on();window.addEventListener("scroll",req,{passive:true});window.addEventListener("resize",req);
    return()=>{window.removeEventListener("scroll",req);window.removeEventListener("resize",req);};
  },[]);
  return <div ref={ref} aria-hidden="true" style={{position:"fixed",top:0,left:0,right:0,height:"2px",background:"var(--ember)",transform:"scaleX(0)",transformOrigin:"0 0",zIndex:120,pointerEvents:"none"}}></div>;
}
function Magnet({strength=.28,children,style}){
  const ref=React.useRef(null);
  const mm=e=>{if(!MOTION_OK)return;const el=ref.current;if(!el)return;const r=el.getBoundingClientRect();el.style.transform="translate("+((e.clientX-r.left-r.width/2)*strength)+"px,"+((e.clientY-r.top-r.height/2)*strength)+"px)";};
  const ml=()=>{const el=ref.current;if(el)el.style.transform="";};
  return <div ref={ref} onMouseMove={mm} onMouseLeave={ml} style={{display:"inline-block",transition:"transform .5s var(--e-rev)",willChange:"transform",...style}}>{children}</div>;
}
function Grain(){
  return <div aria-hidden="true" style={{position:"fixed",inset:0,zIndex:90,pointerEvents:"none",opacity:.05,mixBlendMode:"multiply",backgroundSize:"260px 260px",backgroundImage:"url(\"data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='260'%20height='260'%3E%3Cfilter%20id='n'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.75'%20numOctaves='2'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='saturate'%20values='0'/%3E%3C/filter%3E%3Crect%20width='260'%20height='260'%20filter='url(%23n)'/%3E%3C/svg%3E\")"}}></div>;
}
function Scrub({text,style}){
  const ref=React.useRef(null);
  React.useEffect(()=>{
    const el=ref.current;if(!el)return;
    const words=[].slice.call(el.querySelectorAll(".sw"));
    if(!MOTION_OK){words.forEach(w=>w.classList.add("lit"));return;}
    let raf=0;
    const on=()=>{raf=0;const r=el.getBoundingClientRect();const vh=window.innerHeight;const p=Math.min(1,Math.max(0,(vh*.82-r.top)/(vh*.62)));const n=Math.round(p*words.length);for(let i=0;i<words.length;i++)words[i].classList.toggle("lit",i<n);};
    const req=()=>{if(!raf)raf=requestAnimationFrame(on);};
    on();window.addEventListener("scroll",req,{passive:true});window.addEventListener("resize",req);
    return()=>{window.removeEventListener("scroll",req);window.removeEventListener("resize",req);};
  },[]);
  return <p ref={ref} style={style}>{text.split(" ").map((w,i)=><span key={i} className="sw">{w}{" "}</span>)}</p>;
}
Object.assign(window,{MOTION_OK,Reveal,Words,ScrollProgress,Magnet,Grain,Scrub});
