// Tweaks panel — shared across landing and admin const { useEffect: tEffect } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "moss": "#1a3a2a", "theme": "light", "lang": "en", "font": "sans" }/*EDITMODE-END*/; function JGTweaks({ page = "landing" }) { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // Apply moss color via CSS variable tEffect(() => { document.documentElement.style.setProperty("--moss", t.moss); document.documentElement.style.setProperty("--moss-deep", shade(t.moss, -0.4)); document.documentElement.style.setProperty("--moss-tint", shade(t.moss, 0.25)); }, [t.moss]); tEffect(() => { document.documentElement.setAttribute("data-theme", t.theme); }, [t.theme]); tEffect(() => { document.body.setAttribute("data-font", t.font); }, [t.font]); // Broadcast lang to App tEffect(() => { if (window.__jg_setLang) window.__jg_setLang(t.lang); try { localStorage.setItem("jg.lang", t.lang); } catch (e) {} }, [t.lang]); return ( setTweak("moss", v)} /> setTweak("theme", v)} /> setTweak("font", v)} /> setTweak("lang", v)} /> ); } // hex shade utility — amt -1..1 ; negative darkens, positive lightens function shade(hex, amt) { const h = String(hex).replace("#", ""); const x = h.length === 3 ? h.replace(/./g, (c) => c + c) : h.padEnd(6, "0"); const n = parseInt(x.slice(0, 6), 16); let r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255; const adj = (c) => amt < 0 ? Math.max(0, Math.round(c * (1 + amt))) : Math.min(255, Math.round(c + (255 - c) * amt)); r = adj(r); g = adj(g); b = adj(b); return "#" + ((r << 16) | (g << 8) | b).toString(16).padStart(6, "0"); } window.JGTweaks = JGTweaks;