// Root Site component — composes sections, wires up Tweaks. const { useState: useStateS, useEffect: useEffectS } = React; function TweaksPanel({ state, setState, visible, onClose }) { if (!visible) return null; const upd = (k, v) => setState(s => ({ ...s, [k]: v })); const swatchRow = (k, opts) => (
{opts.map(o => ( ))}
); return (
Tweaks
Firm size
Swaps proof points & highlights the pricing tier.
{swatchRow('firmTier', [ { v: 'solo', label: 'Solo' }, { v: 'boutique', label: 'Boutique' }, { v: 'midsize', label: 'Mid-size' }, ])}
Accent tint
{swatchRow('accent', [ { v: 'blue', label: 'Blue', dot: T.blue }, { v: 'green', label: 'Green', dot: T.green }, { v: 'violet', label: 'Violet', dot: T.violet }, ])}
Density
{swatchRow('density', [ { v: 'comfortable', label: 'Comfortable' }, { v: 'compact', label: 'Compact' }, ])}
Hero product shot
{swatchRow('heroShot', [ { v: 'dashboard', label: 'Dashboard' }, { v: 'rfe', label: 'RFE' }, { v: 'cases', label: 'Cases' }, ])}
Changes persist across reloads. The firm-size tweak highlights the matching pricing tier and swaps the tone of the hero.
); } function Site() { const defaults = window.__TWEAKS__ || { firmTier: 'boutique', accent: 'blue', density: 'comfortable', heroShot: 'dashboard' }; const [tweaks, setTweaks] = useStateS(() => { try { const saved = localStorage.getItem('immihub-atty-tweaks'); return saved ? { ...defaults, ...JSON.parse(saved) } : defaults; } catch (e) { return defaults; } }); const [tweakOpen, setTweakOpen] = useStateS(false); // Persist useEffectS(() => { try { localStorage.setItem('immihub-atty-tweaks', JSON.stringify(tweaks)); } catch (e) {} window.parent && window.parent.postMessage({ type: '__edit_mode_set_keys', edits: tweaks }, '*'); }, [tweaks]); // Tweaks protocol — listener FIRST, then announce useEffectS(() => { const onMsg = (e) => { if (!e.data || !e.data.type) return; if (e.data.type === '__activate_edit_mode') setTweakOpen(true); if (e.data.type === '__deactivate_edit_mode') setTweakOpen(false); }; window.addEventListener('message', onMsg); // announce window.parent && window.parent.postMessage({ type: '__edit_mode_available' }, '*'); return () => window.removeEventListener('message', onMsg); }, []); const { accent, firmTier, heroShot } = tweaks; return (
); } Object.assign(window, { Site, TweaksPanel });