// app.jsx — composes everything const { useState, useEffect } = React; const PALETTES = { skyideaDefault: { name: 'Sky / 提案準拠', sky: '#87CEEB', deep: '#4A9BC4', mid: '#5B7FE0', sec: '#1F4E96', bcp: '#5DADE2', night: '#191970' }, cooler: { name: 'Cool Navy', sky: '#A8DADC', deep: '#457B9D', mid: '#5B7FE0', sec: '#1D3557', bcp: '#6FB1FC', night: '#0F1B3D' }, monoNavy: { name: 'Mono Navy', sky: '#B8C5DB', deep: '#3D5A8A', mid: '#4F6FA8', sec: '#1E2F5A', bcp: '#7B96C2', night: '#0E1849' } }; function App() { const [modalOpen, setModalOpen] = useState(false); const [initialTheme, setInitialTheme] = useState(''); const openModal = (theme) => { setInitialTheme(typeof theme === 'string' ? theme : ''); setModalOpen(true); }; // Tweaks const tweakDefaults = /*EDITMODE-BEGIN*/{ "palette": "skyideaDefault", "showPhilosophy": true }/*EDITMODE-END*/; const [t, setTweak] = window.useTweaks(tweakDefaults); // Apply palette useEffect(() => { const p = PALETTES[t.palette] || PALETTES.skyideaDefault; const root = document.documentElement; root.style.setProperty('--sky-blue', p.sky); root.style.setProperty('--sky-deep', p.deep); root.style.setProperty('--mid-blue', p.mid); root.style.setProperty('--deep-blue', p.sec); root.style.setProperty('--light-sky', p.bcp); root.style.setProperty('--midnight', p.night); }, [t.palette]); // Reveal on scroll useEffect(() => { const els = document.querySelectorAll('.reveal'); const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('is-shown'); io.unobserve(e.target); } }); }, { threshold: 0.08 }); els.forEach(el => io.observe(el)); return () => io.disconnect(); }, []); // Palette options for TweakColor — array of palette arrays const paletteOptions = Object.values(PALETTES).map(p => [p.sky, p.deep, p.night]); const paletteKeys = Object.keys(PALETTES); const currentPaletteArr = (() => { const p = PALETTES[t.palette] || PALETTES.skyideaDefault; return [p.sky, p.deep, p.night]; })(); return ( openModal()} />
openModal()} /> {t.showPhilosophy && (
)}
{window.CONTACT_ENABLED && (
openModal()} />
)}
{window.CONTACT_ENABLED && ( setModalOpen(false)} initialTheme={initialTheme} /> )} { const idx = paletteOptions.findIndex(p => JSON.stringify(p) === JSON.stringify(arr)); if (idx >= 0) setTweak('palette', paletteKeys[idx]); }} /> setTweak('showPhilosophy', v)} />
); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render();