// Mounts the Tweaks panel for ACLEAP site
// Reads window.TWEAK_DEFAULTS and persists changes via host protocol.
function ACLEAPTweaks() {
const [t, setTweak] = useTweaks(window.TWEAK_DEFAULTS);
// Apply tweaks to
data attributes & CSS vars
React.useEffect(() => {
document.body.dataset.dark = String(!!t.dark);
document.body.dataset.density = t.density || 'regular';
document.body.dataset.header = t.header || 'default';
// Apply primary color override
const root = document.documentElement;
if (t.primaryColor) {
root.style.setProperty('--primary', t.primaryColor);
// derive deeper shade by reducing lightness ~10%
root.style.setProperty('--primary-deep', shade(t.primaryColor, -14));
root.style.setProperty('--primary-tint', tint(t.primaryColor, 0.85));
}
}, [t]);
return (
setTweak('primaryColor', v)}
/>
setTweak('dark', v)}
/>
setTweak('density', v)}
/>
setTweak('header', v)}
/>
);
}
// Helpers: shade/tint a hex color
function shade(hex, percent) {
const c = hexToRgb(hex);
if (!c) return hex;
const f = 1 + percent / 100;
const r = clamp(Math.round(c.r * f), 0, 255);
const g = clamp(Math.round(c.g * f), 0, 255);
const b = clamp(Math.round(c.b * f), 0, 255);
return rgbToHex(r, g, b);
}
function tint(hex, amount) {
const c = hexToRgb(hex);
if (!c) return hex;
const r = clamp(Math.round(c.r + (255 - c.r) * amount), 0, 255);
const g = clamp(Math.round(c.g + (255 - c.g) * amount), 0, 255);
const b = clamp(Math.round(c.b + (255 - c.b) * amount), 0, 255);
return rgbToHex(r, g, b);
}
function hexToRgb(h) {
if (!h) return null;
const m = h.replace('#','');
if (m.length !== 6) return null;
return { r: parseInt(m.slice(0,2),16), g: parseInt(m.slice(2,4),16), b: parseInt(m.slice(4,6),16) };
}
function rgbToHex(r,g,b){return '#'+[r,g,b].map(x=>x.toString(16).padStart(2,'0')).join('')}
function clamp(v,a,b){return Math.max(a,Math.min(b,v))}
// Mount
const __tweakMount = document.createElement('div');
document.body.appendChild(__tweakMount);
ReactDOM.createRoot(__tweakMount).render();