// APP ROOT — router interno + tweaks panel const { useState, useEffect } = React; const App = () => { const [route, setRoute] = useState('home'); // 'home' | 'catalogo' | 'detalle' const [vehicleId, setVehicleId] = useState(null); const [searchPreset, setSearchPreset] = useState(null); // Tweaks const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "accent": "#ea5a0c", "displayFont": "Cairo", "density": 3, "dark": true }/*EDITMODE-END*/; const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); // Apply tweaks → CSS vars useEffect(() => { document.documentElement.style.setProperty('--accent', t.accent); // brighten document.documentElement.style.setProperty('--accent-bright', shiftLight(t.accent, 0.08)); document.body.dataset.density = t.density; document.documentElement.style.setProperty('--serif', `"${t.displayFont}", "Helvetica Neue", Helvetica, Arial, sans-serif`); if (!t.dark) { document.documentElement.style.setProperty('--bg', '#f6f2ea'); document.documentElement.style.setProperty('--bg-elev', '#efe9dd'); document.documentElement.style.setProperty('--bg-elev-2', '#e6decb'); document.documentElement.style.setProperty('--ink', '#15110a'); document.documentElement.style.setProperty('--ink-dim', '#5d564a'); document.documentElement.style.setProperty('--ink-mute', '#857b6a'); document.documentElement.style.setProperty('--line', '#d4ccba'); document.documentElement.style.setProperty('--line-soft', '#e2dac6'); } else { document.documentElement.style.setProperty('--bg', '#0a0a0a'); document.documentElement.style.setProperty('--bg-elev', '#131311'); document.documentElement.style.setProperty('--bg-elev-2', '#1c1b18'); document.documentElement.style.setProperty('--ink', '#f3ede2'); document.documentElement.style.setProperty('--ink-dim', '#a8a094'); document.documentElement.style.setProperty('--ink-mute', '#6b6358'); document.documentElement.style.setProperty('--line', '#2a2823'); document.documentElement.style.setProperty('--line-soft', '#1f1d1a'); } }, [t]); const nav = (newRoute, anchor, preset) => { setRoute(newRoute); if (preset) setSearchPreset(preset); try { window.history.pushState({ route:newRoute, anchor:anchor||null, preset:preset||null }, '', '#'+newRoute); } catch(e) {} setTimeout(() => { if (anchor) { const el = document.getElementById(anchor); if (el) { const rect = el.getBoundingClientRect(); window.scrollTo({top: window.scrollY + rect.top - 80, behavior:'smooth'}); } } else { window.scrollTo({top:0, behavior:'instant'}); } }, 50); }; const selectVehicle = (id) => { setVehicleId(id); setRoute('detalle'); try { window.history.pushState({ route:'detalle', vehicleId:id }, '', '#detalle'); } catch(e) {} setTimeout(() => window.scrollTo({top:0, behavior:'instant'}), 30); }; // Botón ATRÁS/ADELANTE del navegador -> navegación interna (no sale del sitio) useEffect(() => { if (!window.history.state) { try { window.history.replaceState({ route:'home' }, '', window.location.pathname); } catch(e) {} } const onPop = (e) => { const st = e.state || { route:'home' }; setRoute(st.route || 'home'); setVehicleId(st.vehicleId || null); if (st.preset) setSearchPreset(st.preset); setTimeout(() => window.scrollTo({ top:0, behavior:'instant' }), 20); }; window.addEventListener('popstate', onPop); return () => window.removeEventListener('popstate', onPop); }, []); return (
{route === 'home' && } {route === 'catalogo' && } {route === 'detalle' && nav('catalogo')} onNav={nav} onSelectVehicle={selectVehicle}/>} setTweak('accent', v)}/> setTweak('dark', v)}/> setTweak('displayFont', v)}/> setTweak('density', v)}/> ); }; // Util: lighten a hex by amount (0..1) function shiftLight(hex, amt) { const m = hex.replace('#','').match(/.{2}/g); if (!m) return hex; const [r,g,b] = m.map(x => parseInt(x,16)); const nr = Math.min(255, Math.round(r + (255-r)*amt)); const ng = Math.min(255, Math.round(g + (255-g)*amt)); const nb = Math.min(255, Math.round(b + (255-b)*amt)); return '#' + [nr,ng,nb].map(x=>x.toString(16).padStart(2,'0')).join(''); } const root = ReactDOM.createRoot(document.getElementById('root')); // Esperar a que el storage layer hidrate los vehículos antes de montar la app (window.__OMEGA_READY || Promise.resolve()).then(() => { root.render(); });