// Shared primitives const { useEffect, useRef, useState, useMemo, useCallback } = React; // Reveal on scroll using IntersectionObserver function useReveal() { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add('is-visible'); io.unobserve(e.target); } }); }, { threshold: 0.12, rootMargin: '0px 0px -60px 0px' }); io.observe(el); return () => io.disconnect(); }, []); return ref; } function Reveal({ children, delay = 0, as: Tag = 'div', style = {}, ...rest }) { const ref = useReveal(); return ( {children} ); } // Arrow glyphs const ArrowRight = ({ size = 14 }) => ( ); const ArrowDown = ({ size = 14 }) => ( ); // Buttons const btnStyles = { base: { display: 'inline-flex', alignItems: 'center', gap: 10, padding: '14px 22px', fontFamily: 'var(--sans)', fontSize: 14, letterSpacing: '0.01em', fontWeight: 500, borderRadius: 2, transition: 'all 200ms ease', whiteSpace: 'nowrap', }, primary: { background: 'var(--ink)', color: 'var(--bg)', }, ghost: { background: 'transparent', color: 'var(--ink)', border: '1px solid var(--rule-2)', }, text: { padding: 0, color: 'var(--ink-2)', background: 'transparent', borderBottom: '1px solid var(--rule-2)', borderRadius: 0, paddingBottom: 4, }, }; function PrimaryBtn({ children, href, onClick, style, ...rest }) { const [hover, setHover] = useState(false); const s = { ...btnStyles.base, ...btnStyles.primary, ...(hover ? { background: 'var(--accent)', color: 'var(--bg)' } : {}), ...style, }; const El = href ? 'a' : 'button'; return ( setHover(true)} onMouseLeave={() => setHover(false)} {...rest}> {children} ); } function GhostBtn({ children, href, onClick, style }) { const [hover, setHover] = useState(false); const s = { ...btnStyles.base, ...btnStyles.ghost, ...(hover ? { borderColor: 'var(--accent)', color: 'var(--accent)' } : {}), ...style, }; const El = href ? 'a' : 'button'; return ( setHover(true)} onMouseLeave={() => setHover(false)}> {children} ); } function TextLink({ children, href, onClick, style }) { const [hover, setHover] = useState(false); const s = { ...btnStyles.base, ...btnStyles.text, ...(hover ? { color: 'var(--accent)', borderColor: 'var(--accent)' } : {}), ...style, }; const El = href ? 'a' : 'button'; return ( setHover(true)} onMouseLeave={() => setHover(false)}> {children} ); } // Section wrapper with numeric label + eyebrow function SectionHeader({ index, kicker, title, intro, id }) { return (
{kicker}

{title}

{intro && (

{intro}

)}
); } Object.assign(window, { Reveal, useReveal, ArrowRight, ArrowDown, PrimaryBtn, GhostBtn, TextLink, SectionHeader, });