/* ============================================================
Plasteec — Tweaks panel
============================================================ */
const { useState, useEffect, useRef } = React;
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"headline": "reborn",
"bg": "#D5D8C7",
"particles": "regular",
"showMaterials": true,
"showProcess": true,
"showAbout": true,
"showProducts": true,
"showFacility": true,
"showJournal": false,
"showContact": true,
"showTicker": true
}/*EDITMODE-END*/;
const HEADLINE_VARIANTS = {
"reborn": { first: "Plastic,", italic: "reborn" },
"loop": { first: "Closing", italic: "the loop" },
"returned": { first: "Material,", italic: "returned" },
"again": { first: "Once more,", italic: "again" },
};
const BG_OPTIONS = [
"#D5D8C7", // user's current sage-cream
"#E2EAB9", // lime
"#FBFAF5", // cream
"#E8F3EE", // mint
"#0D3B2E", // forest (dark mode hint)
];
const PARTICLE_PRESETS = { low: 180, regular: 380, dense: 720 };
function App(){
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
// -- apply headline
useEffect(()=>{
const h = document.querySelector('h1.headline');
if(!h) return;
const v = HEADLINE_VARIANTS[t.headline] || HEADLINE_VARIANTS.reborn;
h.innerHTML = `${v.first}
${v.italic}`;
}, [t.headline]);
// -- apply bg
useEffect(()=>{
document.body.style.backgroundColor = t.bg;
// when bg is forest, flip text colors automatically
const dark = t.bg === "#0D3B2E";
document.body.style.color = dark ? "#E8F3EE" : "#0F1A14";
document.documentElement.classList.toggle('twk-dark', dark);
}, [t.bg]);
// -- apply particle density
useEffect(()=>{
const n = PARTICLE_PRESETS[t.particles] ?? 380;
if(window.Plasteec && window.Plasteec.setParticleCount){
window.Plasteec.setParticleCount(n);
}
}, [t.particles]);
// -- section visibility
const sectionMap = [
['showMaterials', '#materials'],
['showProcess', '#process'],
['showAbout', '#about'],
['showProducts', '#products'],
['showFacility', '#facility'],
['showJournal', '#journal'],
['showContact', '#contact'],
];
sectionMap.forEach(([key, sel])=>{
/* eslint-disable react-hooks/rules-of-hooks */
useEffect(()=>{
const el = document.querySelector(sel);
if(!el) return;
el.style.display = t[key] ? '' : 'none';
}, [t[key]]);
});
// -- ticker
useEffect(()=>{
const el = document.querySelector('.ticker');
if(!el) return;
el.style.display = t.showTicker ? '' : 'none';
}, [t.showTicker]);
// -- nav link visibility tracks section visibility
useEffect(()=>{
const matches = {
'#materials': t.showMaterials,
'#process': t.showProcess,
'#about': t.showAbout,
'#products': t.showProducts,
'#journal': t.showJournal,
'#contact': t.showContact,
};
document.querySelectorAll('.nav-links a').forEach(a=>{
const href = a.getAttribute('href');
if(href in matches){
a.style.display = matches[href] ? '' : 'none';
}
});
}, [t.showMaterials, t.showProcess, t.showAbout, t.showProducts, t.showJournal, t.showContact]);
return (
setTweak('headline', v)}
/>
setTweak('particles', v)}
/>
setTweak('bg', v)}
/>
setTweak('showMaterials', v)} />
setTweak('showProcess', v)} />
setTweak('showAbout', v)} />
setTweak('showProducts', v)} />
setTweak('showFacility', v)} />
setTweak('showJournal', v)} />
setTweak('showContact', v)} />
setTweak('showTicker', v)} />
);
}
const root = document.createElement('div');
root.id = 'tweaks-root';
document.body.appendChild(root);
ReactDOM.createRoot(root).render();