// Artbot — Tweaks app: 3 expressive controls that reshape the feel. // Each tweak swaps a body class, so all CSS variables flip at once. const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "palette": "dawn", "ornament": "balanced", "voice": "refined" }/*EDITMODE-END*/; // Palette swatches shown in the chip picker (hero + a few accents) const PALETTES = { dawn: ['#FDFAF3', '#C9A961', '#704C3E', '#D4841C'], // Vedic Dawn — warm cream stone: ['#ECE9E0', '#A89263', '#5C5448', '#7B8A7D'], // Stone Temple — cool monastic twilight: ['#1B1924', '#DDB87B', '#B5856A', '#E8A340'], // Twilight — dark + brass glow }; const PALETTE_OPTS = [PALETTES.dawn, PALETTES.stone, PALETTES.twilight]; const PALETTE_KEY = (arr) => { const hero = arr[0].toLowerCase(); if (hero === '#fdfaf3') return 'dawn'; if (hero === '#ece9e0') return 'stone'; return 'twilight'; }; function ArtbotTweaks() { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // Drive body classes from current tweak state React.useEffect(() => { const b = document.body; // snapshot before mutation — forEach on a live classList skips entries when items removed [...b.classList].forEach((c) => { if (c.startsWith('palette-') || c.startsWith('ornament-') || c.startsWith('voice-')) { b.classList.remove(c); } }); b.classList.add(`palette-${t.palette}`); b.classList.add(`ornament-${t.ornament}`); b.classList.add(`voice-${t.voice}`); }, [t.palette, t.ornament, t.voice]); // Map palette string ↔ swatch array for the TweakColor chip UI const currentPalette = PALETTES[t.palette] || PALETTES.dawn; return ( setTweak('palette', PALETTE_KEY(v))} />
{t.palette === 'dawn' && 'Vedic Dawn — warm cream + antique gold'} {t.palette === 'stone' && 'Stone Temple — cooler, monastic'} {t.palette === 'twilight' && 'Twilight Temple — night with brass glow'}
setTweak('ornament', v)} />
{t.ornament === 'spare' && 'Almost no mandalas — geometric quiet.'} {t.ornament === 'balanced' && 'Sacred geometry breathes at low opacity.'} {t.ornament === 'ornate' && 'Heavier sacred geometry, fuller textures.'}
setTweak('voice', v)} />
{t.voice === 'refined' && 'EB Garamond — classical book serif.'} {t.voice === 'etched' && 'Cinzel — inscribed temple capitals.'} {t.voice === 'modern' && 'DM Sans — break the antique mood.'}
); } const root = ReactDOM.createRoot(document.getElementById('tweaks-root')); root.render();