/* VideoHook landing kit — shared primitives & icons */ const { useState, useEffect, useRef } = React; /* ---- ICONS (1.5px stroke geometric, brand register) ---- */ function WAIcon({ size = 14 }) { return ( ); } function Arrow({ size = 13 }) { return ( ); } function FlowArrow() { return ( ); } const PAIN_ICONS = { doc: , clock: , phone: , warn: , }; function PainIcon({ kind }) { return ( {PAIN_ICONS[kind]} ); } /* ---- BUTTONS ---- */ const WA = "https://wa.me/34671325102?text=Hola%2C%20me%20interesa%20VideoHook."; function BtnPrimary({ children, href = WA, style }) { return {children}; } function BtnGhost({ children, href = "#demo", style }) { return {children}; } /* ---- reveal-on-scroll hook ---- */ function useReveal() { const ref = useRef(null); useEffect(() => { const els = ref.current ? ref.current.querySelectorAll(".reveal") : []; const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) e.target.classList.add("in"); }); }, { threshold: 0.12 }); els.forEach((el) => io.observe(el)); return () => io.disconnect(); }, []); return ref; } /* ---- LazyVideo: poster shows instantly, source loads only when near viewport ---- */ function LazyVideo({ src, poster, className }) { const ref = useRef(null); useEffect(() => { const v = ref.current; if (!v) return; const io = new IntersectionObserver((entries, obs) => { entries.forEach((e) => { if (e.isIntersecting) { if (!v.querySelector("source")) { const s = document.createElement("source"); s.src = src; s.type = "video/mp4"; v.appendChild(s); v.load(); v.play().catch(() => {}); } obs.disconnect(); } }); }, { rootMargin: "400px 0px" }); io.observe(v); return () => io.disconnect(); }, [src]); return ; } Object.assign(window, { WAIcon, Arrow, FlowArrow, PainIcon, BtnPrimary, BtnGhost, WA, useReveal, LazyVideo });