// app.jsx — root: wires sections together + reveal-on-scroll + tweaks const { useEffect: useEffectApp, useState: useStateApp } = React; const PALETTES = { purple: { primary: "#A78BFA", primarySoft: "rgba(167,139,250,0.18)" }, cyan: { primary: "#22D3EE", primarySoft: "rgba(34,211,238,0.18)" }, orange: { primary: "#FF6B35", primarySoft: "rgba(255,107,53,0.20)" }, lime: { primary: "#BEF264", primarySoft: "rgba(190,242,100,0.22)" }, pink: { primary: "#F472B6", primarySoft: "rgba(244,114,182,0.20)" } }; function useReveal() { useEffectApp(() => { const els = document.querySelectorAll(".reveal:not(.in)"); const io = new IntersectionObserver((ents) => { ents.forEach(e => { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } }); }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" }); els.forEach(el => io.observe(el)); return () => io.disconnect(); }); } function App() { const [t, setTweak] = useTweaks(window.TWEAK_DEFAULTS); useReveal(); useEffectApp(() => { const root = document.documentElement; const p = PALETTES[t.palette] || PALETTES.purple; root.style.setProperty("--primary", p.primary); root.style.setProperty("--primary-soft", p.primarySoft); }, [t.palette]); useEffectApp(() => { const noise = document.querySelector(".bg-noise"); if (noise) noise.style.display = t.showNoise ? "" : "none"; }, [t.showNoise]); return ( <>