171 lines
5.3 KiB
JavaScript
171 lines
5.3 KiB
JavaScript
// D.intelligence Design System — Tweaks app
|
|
// Lets viewers explore alternative visual treatments for the brand system.
|
|
|
|
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
|
|
"coverBg": "beige",
|
|
"accent": "olive",
|
|
"density": "regular",
|
|
"motif": "all",
|
|
"showGrid": false,
|
|
"monoTone": false
|
|
}/*EDITMODE-END*/;
|
|
|
|
function applyTweaks(t) {
|
|
const root = document.documentElement.style;
|
|
|
|
// Cover background tone
|
|
const coverBgMap = {
|
|
beige: { bg: '#E5E1D2', text: '#231815' },
|
|
brown: { bg: '#231815', text: '#E5E1D2' },
|
|
white: { bg: '#FFFFFF', text: '#231815' },
|
|
olive: { bg: '#CEDC00', text: '#231815' },
|
|
};
|
|
const cov = coverBgMap[t.coverBg] || coverBgMap.beige;
|
|
document.querySelectorAll('section.s-cover, section.s-section').forEach(s => {
|
|
// only flip sections that don't already have inline background:var(--white) (content slides)
|
|
const inline = s.getAttribute('style') || '';
|
|
if (!inline.includes('background:var(--white)')) {
|
|
s.style.background = cov.bg;
|
|
}
|
|
});
|
|
|
|
// Accent color
|
|
const accentMap = {
|
|
olive: '#CEDC00',
|
|
blue: '#0075C0',
|
|
none: '#727171',
|
|
};
|
|
root.setProperty('--olive', accentMap[t.accent] || accentMap.olive);
|
|
|
|
// Density — adjusts global font-size on stage via deck-stage element
|
|
const densityMap = {
|
|
compact: 0.92,
|
|
regular: 1.0,
|
|
spacious: 1.08,
|
|
};
|
|
const stage = document.querySelector('deck-stage');
|
|
if (stage) {
|
|
stage.style.setProperty('--dc-density', densityMap[t.density] || 1);
|
|
}
|
|
// apply as CSS variable on body
|
|
document.body.style.setProperty('--type-scale', densityMap[t.density] || 1);
|
|
document.querySelectorAll('section[data-screen-label]').forEach(s => {
|
|
s.style.zoom = densityMap[t.density] || 1;
|
|
});
|
|
|
|
// Motif visibility
|
|
document.querySelectorAll('.s-three-dots').forEach(el => {
|
|
el.style.display = (t.motif === 'all' || t.motif === 'dots') ? 'flex' : 'none';
|
|
});
|
|
// vertical lines on section dividers — find via the inline style pattern
|
|
document.querySelectorAll('section.s-section div[style*="width:1px"]').forEach(el => {
|
|
el.style.visibility = (t.motif === 'all' || t.motif === 'line') ? 'visible' : 'hidden';
|
|
});
|
|
|
|
// Grid overlay
|
|
let grid = document.getElementById('__grid_overlay');
|
|
if (t.showGrid) {
|
|
if (!grid) {
|
|
grid = document.createElement('div');
|
|
grid.id = '__grid_overlay';
|
|
grid.style.cssText = `
|
|
position:absolute; inset:0; pointer-events:none; z-index:99;
|
|
background-image:
|
|
linear-gradient(to right, rgba(0,117,192,0.18) 0.5px, transparent 0.5px),
|
|
linear-gradient(to bottom, rgba(0,117,192,0.18) 0.5px, transparent 0.5px);
|
|
background-size:140px 60px;
|
|
`;
|
|
document.querySelectorAll('section[data-screen-label]').forEach(s => {
|
|
const g = grid.cloneNode();
|
|
// margin guides
|
|
const margin = document.createElement('div');
|
|
margin.style.cssText = `position:absolute; inset:56px 96px; border:0.5px dashed rgba(0,117,192,0.5); pointer-events:none;`;
|
|
g.appendChild(margin);
|
|
s.appendChild(g);
|
|
});
|
|
}
|
|
} else {
|
|
document.querySelectorAll('#__grid_overlay').forEach(g => g.remove());
|
|
}
|
|
|
|
// Mono tone (preview without olive accent)
|
|
if (t.monoTone) {
|
|
root.setProperty('--olive', '#727171');
|
|
}
|
|
}
|
|
|
|
function App() {
|
|
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
|
|
|
|
React.useEffect(() => {
|
|
// small delay so deck-stage has rendered its shadow children
|
|
const id = setTimeout(() => applyTweaks(t), 60);
|
|
return () => clearTimeout(id);
|
|
}, [t]);
|
|
|
|
return (
|
|
<TweaksPanel>
|
|
<TweakSection label="Background" />
|
|
<TweakRadio
|
|
label="Cover / Section BG"
|
|
value={t.coverBg}
|
|
options={[
|
|
{ value: 'beige', label: 'Beige' },
|
|
{ value: 'brown', label: 'Brown' },
|
|
{ value: 'white', label: 'White' },
|
|
{ value: 'olive', label: 'Olive' },
|
|
]}
|
|
onChange={(v) => setTweak('coverBg', v)}
|
|
/>
|
|
|
|
<TweakSection label="Accent" />
|
|
<TweakRadio
|
|
label="Accent color"
|
|
value={t.accent}
|
|
options={[
|
|
{ value: 'olive', label: 'Olive' },
|
|
{ value: 'blue', label: 'Blue' },
|
|
{ value: 'none', label: 'None' },
|
|
]}
|
|
onChange={(v) => setTweak('accent', v)}
|
|
/>
|
|
<TweakToggle
|
|
label="Mono tone preview"
|
|
value={t.monoTone}
|
|
onChange={(v) => setTweak('monoTone', v)}
|
|
/>
|
|
|
|
<TweakSection label="Layout" />
|
|
<TweakRadio
|
|
label="Type density"
|
|
value={t.density}
|
|
options={[
|
|
{ value: 'compact', label: 'Compact' },
|
|
{ value: 'regular', label: 'Regular' },
|
|
{ value: 'spacious', label: 'Spacious' },
|
|
]}
|
|
onChange={(v) => setTweak('density', v)}
|
|
/>
|
|
<TweakSelect
|
|
label="Motif visibility"
|
|
value={t.motif}
|
|
options={[
|
|
{ value: 'all', label: 'All motifs' },
|
|
{ value: 'dots', label: 'Three-dot only' },
|
|
{ value: 'line', label: 'Vertical line only' },
|
|
{ value: 'none', label: 'Minimal' },
|
|
]}
|
|
onChange={(v) => setTweak('motif', v)}
|
|
/>
|
|
<TweakToggle
|
|
label="Grid overlay"
|
|
value={t.showGrid}
|
|
onChange={(v) => setTweak('showGrid', v)}
|
|
/>
|
|
</TweaksPanel>
|
|
);
|
|
}
|
|
|
|
const root = ReactDOM.createRoot(document.getElementById('tweaks-root'));
|
|
root.render(<App />);
|