const { useRef, useEffect } = React; // ── CUSTOM CURSOR ───────────────────────────────────────────────────────────── const CustomCursor = () => { const dotRef = useRef(null); const lblRef = useRef(null); useEffect(() => { let cx = -100, cy = -100, tx = -100, ty = -100; let raf; const onMove = (e) => { tx = e.clientX; ty = e.clientY; }; window.addEventListener('mousemove', onMove); const lerp = () => { raf = requestAnimationFrame(lerp); cx += (tx - cx) * 0.11; cy += (ty - cy) * 0.11; const dot = dotRef.current; const lbl = lblRef.current; if (dot) { dot.style.left = cx + 'px'; dot.style.top = cy + 'px'; } if (lbl) { lbl.style.left = cx + 'px'; lbl.style.top = cy + 'px'; } }; lerp(); const onOver = (e) => { const interactive = e.target.closest('a, button, [data-cursor]'); if (!interactive) return; dotRef.current?.classList.add('expanded'); const label = e.target.closest('[data-cursor-label]')?.getAttribute('data-cursor-label'); if (label && lblRef.current) { lblRef.current.textContent = label; lblRef.current.classList.add('visible'); } }; const onOut = (e) => { if (e.target.closest('a, button, [data-cursor]') && !e.relatedTarget?.closest('a, button, [data-cursor]')) { dotRef.current?.classList.remove('expanded'); if (lblRef.current) lblRef.current.classList.remove('visible'); } }; document.addEventListener('mouseover', onOver); document.addEventListener('mouseout', onOut); return () => { cancelAnimationFrame(raf); window.removeEventListener('mousemove', onMove); document.removeEventListener('mouseover', onOver); document.removeEventListener('mouseout', onOut); }; }, []); return ( <>
> ); }; // ── DIVIDER — jaali geometric ───────────────────────────────────────────────── const JaaliDivider = ({ flip = false }) => (