/* ========== App root ========== */ const MAPA_1 = "assets/mapa-1.jpg"; const MAPA_2 = "assets/mapa-2.jpg"; const MAPA_3 = "assets/mapa-3.jpg"; function App() { const [introGone, setIntroGone] = React.useState(false); const [active, setActive] = React.useState("top"); const [silencioP, setSilencioP] = React.useState(0); const [silencioVisible, setSilencioVisible] = React.useState(false); const onNav = (id) => { // Multipágina: NOSOTROS y SERVICIOS tienen su propia página. if (id === "nosotros") { window.location.href = "nosotros.html"; return; } if (id === "servicios") { window.location.href = "servicios.html"; return; } if (id === "archivo" || id === "prensa") { window.location.href = "archivo.html"; return; } if (id === "contacto") { window.location.href = "contacto.html"; return; } const el = document.getElementById(id); if (el) el.scrollIntoView({ behavior: "smooth", block: "start" }); }; React.useEffect(() => { const sections = ["top","nosotros","servicios","proyectos","contacto"]; const onScroll = () => { const y = window.scrollY + 200; for (let i = sections.length - 1; i >= 0; i--) { const el = document.getElementById(sections[i]); if (el && el.offsetTop <= y) { setActive(sections[i]); break; } } const secondRow = document.getElementById("nosotros"); const startY = secondRow ? secondRow.offsetTop : 0; setSilencioVisible(window.scrollY >= startY); const threshold = window.innerHeight * 0.55; const p = Math.max(0, Math.min(1, (window.scrollY - startY) / threshold)); const eased = p < 0.5 ? 2 * p * p : 1 - Math.pow(-2 * p + 2, 2) / 2; setSilencioP(eased); }; window.addEventListener("scroll", onScroll); onScroll(); return () => window.removeEventListener("scroll", onScroll); }, []); React.useEffect(() => { const els = document.querySelectorAll(".reveal"); const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) e.target.classList.add("in"); }); }, { threshold: 0.15 }); els.forEach(el => io.observe(el)); return () => io.disconnect(); }, []); const tweaks = useTweaks({ accent: "#DE9DAC", background: "ivory", density: "relaxed", }); React.useEffect(() => { const root = document.documentElement; root.style.setProperty("--accent", tweaks.accent); root.style.setProperty("--accent-deep", tweaks.accent); const bgMap = { ivory: { bg: "#FBF9F8", warm: "#EBC3CC", deep: "#D5D1CA" }, bone: { bg: "#F2EFEC", warm: "#E0D6D9", deep: "#CAC4C2" }, champagne: { bg: "#F5F0EC", warm: "#E8D8DC", deep: "#D6CCCC" }, }; const m = bgMap[tweaks.background] || bgMap.ivory; root.style.setProperty("--ivory", m.bg); root.style.setProperty("--ivory-warm", m.warm); root.style.setProperty("--ivory-deep", m.deep); root.style.setProperty("--gutter", tweaks.density === "tight" ? "clamp(16px, 3vw, 44px)" : "clamp(20px, 4vw, 72px)"); }, [tweaks.accent, tweaks.background, tweaks.density]); return ( <> {!introGone && setIntroGone(true)} />}