// Tweaks panel for DEMON.html — applies live to existing DOM/CSS.
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"releaseDate": "07 / 25 / 26",
"marquee": "In Theaters • July 25, 2026",
"verse": "Transformation comes from the gradual increase of pressure. The more the weight, the greater the diamond. The mirror of truth doesn't change.",
"pathHeadline": "You felt it too, didn’t you?",
"pathSub": "That quiet pressure behind your eyes. That little voice asking whether this life is really the one you chose.",
"crimson": "#8A0303",
"amethyst": "#6B21A8",
"grain": true,
"snap": true
}/*EDITMODE-END*/;
function applyTweaks(t) {
const set = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val; };
set('tw-date', t.releaseDate);
set('tw-meta', t.marquee);
set('tw-verse', t.verse);
set('tw-path-sub', t.pathSub);
// Headline: preserve wrapper around the emphasized word.
// Simple convention: wrap the word "looking" (or first **word**) in strong.
const head = document.getElementById('tw-path-head');
if (head) {
const raw = (t.pathHeadline || '').trim();
// Allow **word** to mark the emphasized run; otherwise emphasize the
// word "looking" if it appears.
let html;
if (/\*\*[^*]+\*\*/.test(raw)) {
html = raw.replace(/\*\*([^*]+)\*\*/, '$1');
} else {
html = raw.replace(/\b(looking|direction|truth|descent|path)\b/i, '$1');
}
// Insert a soft break before the strong if it's near the middle
head.innerHTML = html;
}
// CSS color vars
document.documentElement.style.setProperty('--crimson', t.crimson);
document.documentElement.style.setProperty('--amethyst', t.amethyst);
// Amethyst variant for the gradient
const dark = mixHex(t.amethyst, '#000000', 0.55);
document.documentElement.style.setProperty('--amethyst-2', dark);
// Grain on/off
document.body.style.setProperty('--grain-opacity', t.grain ? '.08' : '0');
if (!document.getElementById('tw-grain-style')) {
const s = document.createElement('style');
s.id = 'tw-grain-style';
s.textContent = 'body::after{opacity:var(--grain-opacity,.08) !important}';
document.head.appendChild(s);
}
// Scroll-snap on/off
const shell = document.getElementById('shell');
if (shell) shell.style.scrollSnapType = t.snap ? 'y mandatory' : 'none';
}
// Hex mixer for amethyst-2 derivation
function mixHex(a, b, amt) {
const p = (h) => {
const x = h.replace('#','');
const v = x.length === 3 ? x.split('').map(c=>c+c).join('') : x;
return [parseInt(v.slice(0,2),16), parseInt(v.slice(2,4),16), parseInt(v.slice(4,6),16)];
};
const [r1,g1,b1] = p(a), [r2,g2,b2] = p(b);
const r = Math.round(r1*(1-amt)+r2*amt);
const g = Math.round(g1*(1-amt)+g2*amt);
const bl = Math.round(b1*(1-amt)+b2*amt);
return '#' + [r,g,bl].map(n => n.toString(16).padStart(2,'0')).join('');
}
function App() {
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
React.useEffect(() => { applyTweaks(t); }, [t]);
return (
setTweak('releaseDate', v)} />
setTweak('marquee', v)} />
setTweak('pathHeadline', v)} />
setTweak('pathSub', v)} />
setTweak('crimson', v)} />
setTweak('amethyst', v)} />
setTweak('grain', v)} />
setTweak('snap', v)} />
);
}
const root = ReactDOM.createRoot(document.getElementById('tweaks-root'));
root.render();