const { useEffect, useRef, useState } = React; function Container({ children, style, ...rest }) { return (
{children}
); } function Rule({ style }) { return
; } function Kicker({ children, dot = true, style }) { return (
{dot && } {children}
); } function Btn({ children, variant = "accent", onClick, as = "button", href, style, size = "lg", ...rest }) { const sizes = { lg: { height: 56, padding: "0 28px", fontSize: 16 }, md: { height: 44, padding: "0 20px", fontSize: 14 }, }; const variants = { accent: { background: "var(--accent)", color: "var(--accent-ink)", border: "1px solid var(--accent)" }, solid: { background: "var(--fg)", color: "var(--bg)", border: "1px solid var(--fg)" }, ghost: { background: "transparent", color: "var(--fg)", border: "1px solid var(--rule-2)" }, }; const Tag = as; return ( (e.currentTarget.style.transform = "scale(0.98)")} onMouseUp={(e) => (e.currentTarget.style.transform = "")} onMouseLeave={(e) => (e.currentTarget.style.transform = "")} {...rest} > {children} ); } function Arrow({ size = 14, angle = 0 }) { return ( ); } function Plus({ size = 14 }) { return ( ); } function Check({ size = 14 }) { return ( ); } // Striped placeholder function ImgPH({ label = "image", aspect = "4/5", style }) { return (
[ {label} ]
); } function Reveal({ children, delay = 0, y = 16 }) { const ref = useRef(null); const [shown, setShown] = useState(false); useEffect(() => { const el = ref.current; if (!el) return; const r = el.getBoundingClientRect(); if (r.top < window.innerHeight && r.bottom > 0) { setShown(true); return; } const io = new IntersectionObserver( (entries) => entries.forEach((e) => e.isIntersecting && setShown(true)), { threshold: 0 } ); io.observe(el); const t = setTimeout(() => setShown(true), 900); return () => { io.disconnect(); clearTimeout(t); }; }, []); return (
{children}
); } // Counter function Counter({ to, decimals = 0, duration = 1600, prefix = "", suffix = "" }) { const ref = useRef(null); const [v, setV] = useState(0); useEffect(() => { const el = ref.current; if (!el) return; const fire = () => { const start = performance.now(); const tick = (now) => { const t = Math.min(1, (now - start) / duration); setV((1 - Math.pow(1 - t, 3)) * to); if (t < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); }; const r = el.getBoundingClientRect(); if (r.top < window.innerHeight && r.bottom > 0) { fire(); return; } const io = new IntersectionObserver((es) => es.forEach((e) => e.isIntersecting && (fire(), io.disconnect())), { threshold: 0.2 }); io.observe(el); return () => io.disconnect(); }, [to]); return {prefix}{v.toFixed(decimals)}{suffix}; } Object.assign(window, { Container, Rule, Kicker, Btn, Arrow, Plus, Check, ImgPH, Reveal, Counter });