/* ============================================================ 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();