/* global React, ReactDOM, CustomCursor, Nav, TopStrip, Footer, ChatWidget, PageInicio, PageServicios, PageAcademia, PagePromocion, PageContacto */ /* ============================================================ MULTIPAGE ENTRY Renders ONE page per HTML file. Each page's
sets: window.VIBELAMI_PAGE = "inicio" | "servicios" | ... window.VIBELAMI_LINKS = { inicio:"/", servicios:"/servicios/", ... } Navigation = real URL change (so menu uses real links, and any onNavigate("id") button also performs a real navigation). ============================================================ */ const { useEffect: useEffectMP, useRef: useRefMP } = React; const PAGE = (typeof window !== "undefined" && window.VIBELAMI_PAGE) || "inicio"; const LINKS = (typeof window !== "undefined" && window.VIBELAMI_LINKS) || {}; function navigate(id) { const url = LINKS[id] || "/"; window.location.href = url; } function MultiPageApp() { const ioRef = useRefMP(null); /* Reveal-on-scroll */ useEffectMP(() => { if (!("IntersectionObserver" in window)) { document.querySelectorAll(".fade-up, .stagger").forEach((el) => el.classList.add("is-in")); return; } const io = new IntersectionObserver( (entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("is-in"); io.unobserve(e.target); } }); }, { rootMargin: "0px 0px -8% 0px", threshold: 0.08 } ); ioRef.current = io; const t = window.setTimeout(() => { document.querySelectorAll(".fade-up, .stagger").forEach((el) => { const r = el.getBoundingClientRect(); if (r.top < window.innerHeight * 0.9) el.classList.add("is-in"); else io.observe(el); }); }, 60); return () => { window.clearTimeout(t); io.disconnect(); }; }, []); let body = null; if (PAGE === "servicios") body =