'use client'; import { useEffect, useRef, type CSSProperties, type ReactNode } from 'react'; // The page's only motion, and it is built the opposite way round from the // system it replaces. // // The hidden state lives in CSS and applies only under `html.js`, a class an // inline script in
adds before first paint. Nothing here writes // `opacity: 0` into the markup, so the static export ships a page that reads in // full — the previous architecture shipped 112 elements at opacity zero and // went blank whenever the JavaScript failed to arrive. // // One module-level observer for the whole page rather than one per block. let observador: IntersectionObserver | null = null; function observadorCompartido() { if (observador) return observador; observador = new IntersectionObserver( (entradas) => { for (const entrada of entradas) { if (!entrada.isIntersecting) continue; entrada.target.setAttribute('data-visible', ''); observador?.unobserve(entrada.target); } }, // Fires a touch before the block is fully in, so the gesture has finished // by the time the reader's eye lands on it. { rootMargin: '0px 0px -10% 0px' }, ); return observador; } export function Revelar({ children, indice = 0, className = '', }: { children: ReactNode; indice?: number; className?: string; }) { const ref = useRef