// Shared marketing-site primitives — icons, mock fragments, reusable bits. const MIcon = ({ name, size = 16, stroke = 1.6 }) => { const paths = { arrR: , arrUR: , chevD: , bolt: , upload: <>, layers: <>, spark: , shield: <>, plug: <>, chip: <>, lock: <>, globe: <>, docs: <>, bot: <>, flow: <>, graph: <>, vendor: <>, check: , play: , twitter: , li: <>, gh: , }; return ( {paths[name]} ); }; // Top navigation const MNav = () => ( ); // ---- Mini product fragments used in hero & capability sections ---- // Score ring as a compact element const MRing = ({ value = 78, size = 92, stroke = 8 }) => { const r = (size - stroke) / 2; const c = 2 * Math.PI * r; const dash = c * (1 - value / 100); return (
{value}
); }; // Animated count-up const CountUp = ({ to = 100, suffix = '', duration = 1400, prefix = '' }) => { const [v, setV] = React.useState(0); const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) { const start = performance.now(); const tick = (now) => { const t = Math.min(1, (now - start) / duration); const eased = 1 - Math.pow(1 - t, 3); setV(to * eased); if (t < 1) requestAnimationFrame(tick); }; requestAnimationFrame(tick); io.disconnect(); } }, { threshold: 0.4 }); io.observe(el); return () => io.disconnect(); }, [to, duration]); const display = to >= 100 ? Math.round(v) : v.toFixed(1); return {prefix}{display}{suffix}; }; // Reveal-on-scroll wrapper const Reveal = ({ children, delay = 0, as: As = 'div', ...rest }) => { const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setTimeout(() => el.classList.add('in'), delay); io.disconnect(); } }, { threshold: 0.15 }); io.observe(el); return () => io.disconnect(); }, [delay]); return {children}; }; // Frame chrome wrapper around a mini product mock const Frame = ({ url = 'app.complychip.com', children, style }) => (
{url}
{children}
); Object.assign(window, { MIcon, MNav, MRing, CountUp, Reveal, Frame });