// Animated horizontal beam — scroll-linked, red glow → green glow. // Bridges the Problema (dark/red) and Solutia (lifted/green) sections. const { useState: useStateBM, useEffect: useEffectBM, useRef: useRefBM } = React; const clampBM = (v, lo, hi) => Math.max(lo, Math.min(hi, v)); const Beam = () => { const ref = useRefBM(null); const [p, setP] = useStateBM(0); useEffectBM(() => { const el = ref.current; if (!el) return; let raf = 0; const update = () => { raf = 0; const r = el.getBoundingClientRect(); const vh = window.innerHeight || 1; const start = vh * 1.1; const end = vh * 0.2; setP(clampBM((start - r.top) / (start - end), 0, 1)); }; const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); }; update(); window.addEventListener("scroll", onScroll, { passive: true }); window.addEventListener("resize", onScroll); return () => { window.removeEventListener("scroll", onScroll); window.removeEventListener("resize", onScroll); if (raf) cancelAnimationFrame(raf); }; }, []); // Trace progresses across the screen as user scrolls const traceWidth = `${(p * 100).toFixed(2)}%`; // Colour shifts red → green as it crosses const headHue = 0 + p * 146; // 0=red, 146=green const headColor = `hsl(${headHue}, 92%, 60%)`; const headGlow = `0 0 24px ${headColor}, 0 0 60px ${headColor}, 0 0 120px ${headColor}`; return (