/* global React, ReactDOM, Hero, ROI, Pillars, Comparison, Pricing, Partners, Mission, DataShowcase, AskAI, ResetBand, Footer, BookingModal, PausaLogo */
const { useState, useEffect } = React;
function Nav({ onBook }) {
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const on = () => setScrolled(window.scrollY > 24);
on();
window.addEventListener("scroll", on, { passive: true });
return () => window.removeEventListener("scroll", on);
}, []);
return (
);
}
function useReveal() {
useEffect(() => {
const revealAll = () =>
document.querySelectorAll(".reveal:not(.in)").forEach((el) => {
el.style.transition = "none"; // bypass the fade so non-painting contexts (export/PDF) aren't blank
el.classList.add("in");
});
// No IO (or non-painting contexts like export/print) → show everything.
if (!("IntersectionObserver" in window)) { revealAll(); return; }
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); }
});
}, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
document.querySelectorAll(".reveal").forEach((el) => io.observe(el));
// Safety net: if frames never paint (screenshots, throttled tabs), reveal anyway.
const fallback = setTimeout(revealAll, 1400);
return () => { io.disconnect(); clearTimeout(fallback); };
}, []);
}
function useParallax() {
useEffect(() => {
if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
const nodes = Array.from(document.querySelectorAll("[data-parallax]"));
if (!nodes.length) return;
let raf = 0;
const update = () => {
raf = 0;
const vh = window.innerHeight;
for (const el of nodes) {
const r = el.getBoundingClientRect();
if (r.bottom < -200 || r.top > vh + 200) continue;
const factor = parseFloat(el.getAttribute("data-parallax")) || 0.05;
const mid = r.top + r.height / 2 - vh / 2;
el.style.transform = `translate3d(0, ${(-mid * factor).toFixed(1)}px, 0)`;
}
};
const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
update();
window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", onScroll, { passive: true });
return () => {
window.removeEventListener("scroll", onScroll);
window.removeEventListener("resize", onScroll);
if (raf) cancelAnimationFrame(raf);
};
}, []);
}
function App() {
const [booking, setBooking] = useState(false);
const onBook = () => setBooking(true);
useReveal();
useParallax();
useEffect(() => {
document.body.style.overflow = booking ? "hidden" : "";
}, [booking]);
// smooth scroll for in-page anchors
useEffect(() => {
const handler = (e) => {
const a = e.target.closest('a[href^="#"]');
if (!a) return;
const id = a.getAttribute("href");
if (id.length < 2) return;
const el = document.querySelector(id);
if (el) { e.preventDefault(); window.scrollTo({ top: id === "#top" ? 0 : el.getBoundingClientRect().top + window.scrollY - 70, behavior: "smooth" }); }
};
document.addEventListener("click", handler);
return () => document.removeEventListener("click", handler);
}, []);
return (
<>
setBooking(false)} />
>
);
}
ReactDOM.createRoot(document.getElementById("root")).render();