/* App entry */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"palette": "forest",
"density": "regular",
"marqueeSpeed": 50,
"theme": "light",
"fontPair": "instrument-inter"
}/*EDITMODE-END*/;
const PALETTES = {
forest: { bg: "#F1EEE3", bg2: "#E6E2D2", ink: "#0E1A12", paper: "#FAF7EE", accent: "#2F6B45", accentDeep: "#14361F" },
moss: { bg: "#F4EFE6", bg2: "#ECE6D9", ink: "#14180F", paper: "#FBF8F2", accent: "#4A6346", accentDeep: "#2F3F2C" },
saffron: { bg: "#F5F1EA", bg2: "#EDE7DA", ink: "#161310", paper: "#FBF7EE", accent: "#A66A2C", accentDeep: "#7A4A18" },
clay: { bg: "#F2EDE5", bg2: "#E8E1D2", ink: "#1A140F", paper: "#FAF4E8", accent: "#9D5238", accentDeep: "#6E3520" }
};
const FONT_PAIRS = {
"instrument-inter": { serif: '"Instrument Serif", Georgia, serif', sans: '"Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif' },
"fraunces-dm": { serif: '"Fraunces", Georgia, serif', sans: '"DM Sans", "Helvetica Neue", Helvetica, Arial, sans-serif' },
"spectral-spaceg": { serif: '"Spectral", Georgia, serif', sans: '"Space Grotesk", "Helvetica Neue", Helvetica, Arial, sans-serif' }
};
function applyTweaks(t) {
const r = document.documentElement;
const p = PALETTES[t.palette] || PALETTES.moss;
if (t.theme !== "dark") {
r.style.setProperty("--bg", p.bg);
r.style.setProperty("--bg-2", p.bg2);
r.style.setProperty("--ink", p.ink);
r.style.setProperty("--paper", p.paper);
r.style.setProperty("--accent", p.accent);
r.style.setProperty("--accent-deep", p.accentDeep);
} else {
r.style.removeProperty("--bg");
r.style.removeProperty("--bg-2");
r.style.removeProperty("--ink");
r.style.removeProperty("--paper");
r.style.removeProperty("--accent");
r.style.removeProperty("--accent-deep");
}
document.body.dataset.theme = t.theme;
r.style.setProperty("--density", t.density === "compact" ? 0.78 : t.density === "spacious" ? 1.18 : 1);
r.style.setProperty("--marquee-speed", `${t.marqueeSpeed}s`);
const fp = FONT_PAIRS[t.fontPair] || FONT_PAIRS["instrument-inter"];
r.style.setProperty("--serif", fp.serif);
r.style.setProperty("--sans", fp.sans);
}
const App = () => {
const [tweaks, setTweaks] = window.useTweaks(TWEAK_DEFAULTS);
React.useEffect(() => { applyTweaks(tweaks); }, [tweaks]);
// 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"); io.unobserve(e.target); } });
}, { threshold: 0.12 });
els.forEach(el => io.observe(el));
return () => io.disconnect();
}, []);
// Handle clean URLs for anchor links
React.useEffect(() => {
window.__nav = (e, targetId) => {
e.preventDefault();
const targetEl = document.getElementById(targetId);
if (targetEl) {
targetEl.scrollIntoView({ behavior: 'smooth' });
const newPath = targetId === 'top' ? '/' : '/' + targetId;
window.history.pushState(null, '', newPath);
} else if (targetId === 'top') {
window.scrollTo({ top: 0, behavior: 'smooth' });
window.history.pushState(null, '', '/');
}
};
}, []);
return (
<>
setTweaks({theme:v})} />
setTweaks({palette:v})} />
setTweaks({fontPair:v})} />
setTweaks({density:v})} />
setTweaks({marqueeSpeed:v})} formatValue={(v)=>`${v}s/cycle`} />
>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render();