/* ===== Подари вторую жизнь — App / router ===== */ const FONT_MAP = { 'Nunito': ["'Nunito'","'Manrope'"], 'Onest': ["'Onest'","'Onest'"], 'Golos': ["'Golos Text'","'Golos Text'"], }; const ACCENTS = { 'Коралловый':'#f5784f', 'Оранжевый':'#fb8c00', 'Янтарный':'#e0a52a' }; const BGS = { 'Кремовый':['#f9f4ea','#f1e7d6'], 'Тёплый':['#f5ecdb','#ebdcc4'], 'Белый':['#ffffff','#f1eee8'] }; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "warmth": 0, "bg": "Кремовый", "accent": "Коралловый", "radius": 22, "cols": "3", "font": "Nunito", "hero": "Коллаж" }/*EDITMODE-END*/; const SCREENS = { home: HomeScreen, photo: PhotoSearchScreen, filter: FilterScreen, catalog: CatalogScreen, detail: DetailScreen, admin: AdminScreen, about: AboutScreen, second: SecondChanceScreen, }; function App(){ const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // showcase overrides via URL (?hero=A|B, ?screen=home|second|…) const sp = new URLSearchParams(location.search); const forcedHero = sp.get('hero'); const startScreen = sp.get('screen'); const [route, setRoute] = useState({ name: (startScreen && SCREENS[startScreen]) ? startScreen : 'home', params:{} }); const [favs, setFavs] = useState(()=>{ try{ return JSON.parse(localStorage.getItem('pf_favs')||'[]'); }catch(e){ return []; } }); const go = useCallback((name, params={})=>{ setRoute({ name, params }); requestAnimationFrame(()=> window.scrollTo({top:0,behavior:'instant'in document.body.style?'instant':'auto'})); },[]); const toggleFav = useCallback((id)=>{ setFavs(prev=>{ const next = prev.includes(id)?prev.filter(x=>x!==id):[...prev,id]; localStorage.setItem('pf_favs', JSON.stringify(next)); return next; }); },[]); // apply tweaks → CSS vars useEffect(()=>{ const r = document.documentElement.style; const H = 192 - (t.warmth||0)*0.27; // тёплый ↔ холодный teal r.setProperty('--primary', `oklch(0.60 0.087 ${H})`); r.setProperty('--accent', ACCENTS[t.accent] || ACCENTS['Коралловый']); const bg = BGS[t.bg] || BGS['Кремовый']; r.setProperty('--bg', bg[0]); r.setProperty('--bg-warm', bg[1]); r.setProperty('--radius', (t.radius||22)+'px'); r.setProperty('--cols', String(t.cols||3)); const f = FONT_MAP[t.font] || FONT_MAP['Nunito']; r.setProperty('--font-display', f[0]+", system-ui, sans-serif"); r.setProperty('--font-body', f[1]+", system-ui, sans-serif"); },[t.warmth,t.accent,t.bg,t.radius,t.cols,t.font]); const Screen = SCREENS[route.name] || HomeScreen; const tEff = forcedHero ? { ...t, hero: forcedHero==='B' ? 'Крупный' : 'Коллаж' } : t; return (
{route.name!=='admin' &&
}
setTweak('warmth', v)}/> setTweak('bg', v)}/> setTweak('accent', v)}/> setTweak('radius', v)}/> setTweak('cols', v)}/> setTweak('font', v)}/> setTweak('hero', v)}/>
); } ReactDOM.createRoot(document.getElementById('root')).render();