/* ═══════════════════════════════════════════ App principal — Manual completo ═══════════════════════════════════════════ */ const { useState: useStateApp, useEffect: useEffectApp } = React; const SECTIONS = [ { id: "portada", num: "00", label: "Portada" }, { id: "introduccion", num: "0.0", label: "Introducción" }, { id: "div-1", num: "01", label: "El emblema", divider: true, desc: "Construcción geométrica, área de respeto, versiones cromáticas y reglas de uso." }, { id: "construccion", num: "1.1", label: "Construcción geométrica" }, { id: "seguridad", num: "1.2", label: "Área de respeto" }, { id: "versiones", num: "1.3", label: "Versiones cromáticas" }, { id: "usos", num: "1.4", label: "Usos correctos / incorrectos" }, { id: "div-2", num: "02", label: "Color y tipografía", divider: true, desc: "Paleta cromática institucional con valores Pantone, CMYK, RGB y HEX. Familias tipográficas y jerarquías." }, { id: "color", num: "2.1", label: "Paleta cromática" }, { id: "tipografia", num: "2.2", label: "Tipografía" }, { id: "div-3", num: "03", label: "Papelería", divider: true, desc: "Aplicación del sistema en tarjetas de visita, papel de carta, sobres y firma de correo electrónico." }, { id: "papeleria", num: "3.1", label: "Tarjeta de visita" }, { id: "carta", num: "3.2", label: "Carta y sobre" }, { id: "div-4", num: "04", label: "Plantillas", divider: true, desc: "Plantillas operativas para informes, partes diarios y presentaciones." }, { id: "plantillas", num: "4.1", label: "Plantillas operativas" }, { id: "cierre", num: "—", label: "Cierre" }, ]; const NAV = SECTIONS.filter(s => !s.id.startsWith("div-")); function Sidebar({ active }) { return ( ); } function App() { const [active, setActive] = useStateApp("portada"); const total = NAV.length; useEffectApp(() => { const observer = new IntersectionObserver( entries => { const visible = entries.filter(e => e.isIntersecting); if (visible.length > 0) { // pick the topmost visible visible.sort((a,b) => a.boundingClientRect.top - b.boundingClientRect.top); setActive(visible[0].target.id); } }, { rootMargin: "-30% 0px -60% 0px", threshold: 0 } ); NAV.forEach(s => { const el = document.getElementById(s.id); if (el) observer.observe(el); }); return () => observer.disconnect(); }, []); // Get the page number for a given section id const idx = (id) => NAV.findIndex(s => s.id === id) + 1; return (
); } ReactDOM.createRoot(document.getElementById('root')).render();