Files
dintel-design-system/tweaks-app.jsx
2026-10-24 18:10:13 +09:00

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 />);