/* ===========================================================
Mira — Tweaks
Mounts only the Tweaks panel; applies values to CSS vars
and data-attributes that the static page reads.
=========================================================== */
const { useTweaks, TweaksPanel, TweakSection, TweakSlider, TweakToggle, TweakRadio, TweakSelect } = window;
const MIRA_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"heroBackdrop": "Watercolour",
"goldIntensity": 50,
"motion": true,
"fontScale": 100,
"warmth": 0
}/*EDITMODE-END*/;
const BACKDROPS = {
"Watercolour": 'url("assets/tex-watercolour-full.png")',
"Sea": 'url("assets/tex-sea.png")',
"Sunburst": 'url("assets/tex-sunburst.png")',
"Starfield": 'url("assets/tex-starfield.png")'
};
function MiraTweaks() {
const [t, setTweak] = useTweaks(MIRA_TWEAK_DEFAULTS);
React.useEffect(() => {
const root = document.documentElement;
// Hero backdrop
root.style.setProperty("--hero-bg", BACKDROPS[t.heroBackdrop] || BACKDROPS.Watercolour);
// Gold intensity → chroma + lightness (richer = deeper, more saturated)
const g = t.goldIntensity / 100;
root.style.setProperty("--gold-c", (0.07 + g * 0.085).toFixed(3));
root.style.setProperty("--gold-l", (0.86 - g * 0.10).toFixed(3));
// Motion
document.body.classList.toggle("no-motion", !t.motion);
// Font scale
root.style.setProperty("--scale", (t.fontScale / 100).toFixed(3));
// Palette warmth ↔ blue: tint the ivory family cooler/bluer
const w = t.warmth; // 0 = warm ivory, 100 = cool blue mist
root.style.setProperty("--ivory", `color-mix(in oklab, #f5f1e8, #dde6f6 ${w}%)`);
root.style.setProperty("--ivory-2", `color-mix(in oklab, #efe9db, #d2def0 ${w}%)`);
root.style.setProperty("--ivory-3", `color-mix(in oklab, #e7dfcd, #c4d3ea ${w}%)`);
}, [t.heroBackdrop, t.goldIntensity, t.motion, t.fontScale, t.warmth]);
return (
setTweak("heroBackdrop", v)} />
setTweak("goldIntensity", v)} />
setTweak("warmth", v)} />
setTweak("fontScale", v)} />
setTweak("motion", v)} />
);
}
ReactDOM.createRoot(document.getElementById("tweaks-root")).render();