// Shared primitives: Logo, icons, arrow, badges const { useState, useEffect, useRef, useMemo } = React; const Logo = ({ tone = 'light', size = 28 }) => { // White-label re-creation of the wordmark: "decisive" + "ZONE" boxed const fg = tone === 'light' ? 'var(--ink)' : 'var(--paper)'; const box = 'var(--accent)'; const boxText = 'var(--ink)'; return (
decisive ZONE
); }; // Simple monoline icons (24x24) const Icon = ({ name, size = 22, stroke = 1.6, color = 'currentColor' }) => { const p = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' }; switch (name) { case 'arrow': return ; case 'arrow-up': return ; case 'phone': return ; case 'mail': return ; case 'pin': return ; case 'whatsapp': return ; case 'check': return ; case 'sparkle': return ; case 'compass': return ; case 'building': return ; case 'globe': return ; case 'anchor': return ; case 'id': return ; case 'bank': return ; case 'calc': return ; case 'book': return ; case 'office': return ; case 'shield': return ; case 'play': return ; case 'star': return ; case 'minus': return ; case 'plus': return ; case 'chev-r': return ; case 'chev-d': return ; default: return null; } }; const Pill = ({ children, tone = 'paper' }) => ( {children} ); // Hook: in-view fade const useReveal = () => { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const obs = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('fade-up'); obs.unobserve(e.target); }}); }, { threshold: 0.12 }); obs.observe(el); return () => obs.disconnect(); }, []); return ref; }; Object.assign(window, { Logo, Icon, Pill, useReveal });