// Shared layout — Header + Footer + theme persistence across pages. // Each page imports this and renders its content inside . const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "whiteLabel": "ai-company", "hexIntensity": "subtle" }/*EDITMODE-END*/; const THEMES = { 'ai-company': { brandName: 'AI Company', primary: '#1B3A6B', secondary: '#1E6BB0', accent: '#E8620A' }, 'bakery': { brandName: 'Panadería Aurora', primary: '#7C2D12', secondary: '#C2410C', accent: '#FACC15' }, 'fashion': { brandName: 'Atelier Noir', primary: '#18181B', secondary: '#52525B', accent: '#E11D48' }, 'wellness': { brandName: 'Verde Salud', primary: '#14532D', secondary: '#16A34A', accent: '#F59E0B' }, }; // Read theme from localStorage so it persists across pages function readPersistedTheme(){ try { const v = localStorage.getItem('aic_theme'); if (v) return JSON.parse(v); } catch(e){} return { whiteLabel: 'ai-company', custom: THEMES['ai-company'], hexIntensity: 'subtle' }; } function persistTheme(state){ try{ localStorage.setItem('aic_theme', JSON.stringify(state)); }catch(e){} } function applyTheme(theme){ const r = document.documentElement; r.style.setProperty('--brand-primary', theme.primary); r.style.setProperty('--brand-secondary', theme.secondary); r.style.setProperty('--brand-accent', theme.accent); } // Re-export SiteHeader & SiteFooter that accept "active" prop function NavHeader({ theme, active = '' }) { const [menuOpen, setMenuOpen] = React.useState(false); const items = [ { id: 'como-funciona', label: 'Cómo funciona', href: 'como-funciona.html' }, { id: 'colaboradores', label: 'Colaboradores', href: 'colaboradores.html' }, { id: 'casos-de-uso', label: 'Casos de uso', href: 'casos-de-uso.html' }, { id: 'precios', label: 'Precios', href: 'precios.html' }, { id: 'blog', label: 'Blog', href: 'blog.html' }, ]; // Lock body scroll when menu open React.useEffect(() => { document.body.style.overflow = menuOpen ? 'hidden' : ''; return () => { document.body.style.overflow = ''; }; }, [menuOpen]); return (
{theme.brandName}
Contacto Empieza gratis
{/* Mobile drawer */}
setMenuOpen(false)}>
e.stopPropagation()}>
); } function NavFooter({ theme }) { const cols = [ { title: 'Producto', items: [ ['Cómo funciona', 'como-funciona.html'], ['Colaboradores', 'colaboradores.html'], ['Casos de uso', 'casos-de-uso.html'], ['Precios', 'precios.html'], ['Demo', 'demo.html'], ]}, { title: 'Empresa', items: [ ['Blog', 'blog.html'], ['Sobre nosotros','#'], ['Contacto', 'contacto.html'], ['Prensa', '#'], ['Carreras', '#'], ]}, { title: 'Legal', items: [ ['Privacidad', '#'], ['Términos','#'], ['Cookies','#'], ['Seguridad','#'], ['GDPR','#'], ]}, ]; return ( ); } function PageHero({ crumb, title, subtitle, eyebrow }) { return (
{crumb && (
{crumb.map((c, i) => ( {i > 0 && /} {c.href ? {c.label} : {c.label}} ))}
)} {eyebrow &&
{eyebrow}
}

{title}

{subtitle &&

{subtitle}

}
); } // Layout component — wraps page content, applies theme. function Layout({ active, children }) { const [state, setState] = React.useState(readPersistedTheme); const theme = state.whiteLabel === 'custom' ? state.custom : (THEMES[state.whiteLabel] || THEMES['ai-company']); React.useEffect(() => { applyTheme(theme); document.body.dataset.hex = state.hexIntensity; persistTheme(state); }, [state.whiteLabel, state.hexIntensity, theme.primary, theme.secondary, theme.accent]); // Reveal-on-scroll React.useEffect(() => { const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('in'); }); }, { threshold: 0.12 }); document.querySelectorAll('.section').forEach(s => { s.classList.add('reveal'); io.observe(s); }); return () => io.disconnect(); }, []); const childrenWithTheme = React.Children.map(children, child => React.isValidElement(child) ? React.cloneElement(child, { theme }) : child ); return ( <>
{childrenWithTheme}
); } Object.assign(window, { Layout, NavHeader, NavFooter, PageHero, THEMES, readPersistedTheme });