// app.jsx — main app + reveal-on-scroll
const { useState, useEffect } = React;
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"years": 26,
"projects": 84,
"sqm": 12500,
"palette": ["#0A1F44", "#C5A059", "#F4F1EC"]
}/*EDITMODE-END*/;
function useReveal() {
useEffect(() => {
const items = document.querySelectorAll(
".intro h2, .intro p, .numbers, .portfolio-head, .filters, .proj, .about-photo, .about h2, .about p, .about-skills, .about-quote, .testi-head, .testi-card, .blog-head, .blog-row, .cta h2, .cta p, .cta-buttons, .ai-left, .ai-chat-wrap"
);
items.forEach((el) => el.classList.add("reveal"));
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) {
e.target.classList.add("in");
io.unobserve(e.target);
}
});
}, { threshold: 0.12, rootMargin: "0px 0px -60px 0px" });
items.forEach((el) => io.observe(el));
return () => io.disconnect();
}, []);
}
function App() {
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
const [modal, setModal] = useState(null);
// apply palette tweaks
useEffect(() => {
const r = document.documentElement;
r.style.setProperty("--navy", t.palette[0]);
r.style.setProperty("--gold", t.palette[1]);
r.style.setProperty("--paper", t.palette[2]);
}, [t.palette]);
useReveal();
return (
<>
setModal(p)} />
setModal(null)} />
setTweak("years", v)} />
setTweak("projects", v)} />
setTweak("sqm", v)} />
setTweak("palette", v)} />
>
);
}
ReactDOM.createRoot(document.getElementById("root")).render();