// app.jsx — main App, tweaks panel, mount
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"palette": "cream",
"hero": "editorial",
"displayFont": "Instrument Serif",
"eyebrowStyle": "mono",
"showComparison": true,
"showNutrition": true
}/*EDITMODE-END*/;
function App() {
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
const [presetTier, setPresetTier] = React.useState(null);
// Apply palette via data attribute on root
React.useEffect(() => {
document.documentElement.setAttribute('data-palette', t.palette);
}, [t.palette]);
// Display font swap via CSS variable
React.useEffect(() => {
document.documentElement.style.setProperty('--display',
`"${t.displayFont}", "Times New Roman", serif`);
}, [t.displayFont]);
const handleOrder = () => {
const el = document.querySelector('#order');
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
const handlePick = (tier) => {
setPresetTier(tier);
setTimeout(handleOrder, 60);
};
// Reveal-on-scroll
React.useEffect(() => {
const els = document.querySelectorAll('.reveal');
const io = new IntersectionObserver(entries => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('in'); });
}, { threshold: 0.15 });
els.forEach(el => io.observe(el));
return () => io.disconnect();
}, []);
return (
<>
{t.showComparison && }
{t.showNutrition && }
setTweak('hero', v)} />
setTweak('eyebrowStyle', v)} />
setTweak('palette', v)} />
setTweak('displayFont', v)} />
setTweak('showComparison', v)} />
setTweak('showNutrition', v)} />
>
);
}
ReactDOM.createRoot(document.getElementById('root')).render();