/* global React */ const { useState, useEffect, useRef } = React; /* ============ Icons ============ */ const Icon = ({ name, size = 20, stroke = 1.6 }) => { const paths = { arrow: , arrowUp: , check: , plus: <>, star: , shield: , bolt: , cloud: , server: <>, lock: <>, chart: <>, layers: <>, settings: <>, cube: <>, code: <>, grid: <>, factory: <>, shop: <>, health: <>, truck: <>, bank: <>, book: <>, home: <>, cart: <>, phone: , mail: <>, pin: <>, linkedin: <>, twitter: , whatsapp: , sparkle: <>, target: <>, rocket: , refresh: <>, clock: <>, users: <>, x: <>, }; return ( {paths[name]} ); }; /* ============ Reveal Observer ============ */ function useReveal() { useEffect(() => { const els = document.querySelectorAll(".reveal, .reveal-stagger"); els.forEach(el => el.classList.add("is-pending")); const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); } }); }, { threshold: 0.05, rootMargin: "0px 0px -3% 0px" }); els.forEach(el => io.observe(el)); // Safety net for initial viewport: mark anything visible now requestAnimationFrame(() => { els.forEach(el => { const r = el.getBoundingClientRect(); if (r.top < window.innerHeight * 0.95 && r.bottom > 0) { el.classList.add("in"); } }); }); return () => io.disconnect(); }, []); } /* ============ Counter ============ */ function Counter({ to, suffix = "", duration = 1800 }) { const ref = useRef(null); const [val, setVal] = useState(0); const started = useRef(false); useEffect(() => { const io = new IntersectionObserver((entries) => { if (entries[0].isIntersecting && !started.current) { started.current = true; const start = performance.now(); const tick = (now) => { const t = Math.min(1, (now - start) / duration); const eased = 1 - Math.pow(1 - t, 3); setVal(Math.round(to * eased)); if (t < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); } }, { threshold: 0.5 }); if (ref.current) io.observe(ref.current); return () => io.disconnect(); }, [to, duration]); return {val}{suffix}; } window.Icon = Icon; window.useReveal = useReveal; window.Counter = Counter;