// chrome.jsx — Header, Footer, shared bits const NAV_ITEMS = [ { id: 'home', label: 'Home' }, { id: 'services', label: 'Services' }, { id: 'work', label: 'Work' }, { id: 'about', label: 'About' }, { id: 'contact', label: 'Contact' }, { id: 'book', label: 'Book a Call' }, ]; const PAGE_HREFS = { home: '/', services: '/services', work: '/work', about: '/about', contact: '/contact', book: '/book', privacy: '/privacy', disclaimer: '/disclaimer', }; function Arrow({ size = 12, style }) { return ( ); } function SunMoon({ dark }) { return dark ? ( ) : ( ); } function MenuIcon({ open }) { return open ? ( ) : ( ); } function Header({ route, setRoute, dark, setDark }) { const [scrolled, setScrolled] = React.useState(false); const [menuOpen, setMenuOpen] = React.useState(false); React.useEffect(() => { const on = () => setScrolled(window.scrollY > 12); on(); window.addEventListener('scroll', on, { passive: true }); return () => window.removeEventListener('scroll', on); }, []); const go = (id) => { setRoute(id); setMenuOpen(false); window.scrollTo({ top: 0, behavior: 'smooth' }); }; return ( <>
go('home')}> Harjog
{menuOpen && (
{NAV_ITEMS.filter(i => i.id !== 'book').map(item => ( { e.preventDefault(); go(item.id); }}> {item.label} ))} { e.preventDefault(); go('book'); setMenuOpen(false); }}> Book a Call →
)} ); } function Footer({ setRoute }) { const [email, setEmail] = React.useState(''); const [subscribed, setSubscribed] = React.useState(false); const go = (id) => { setRoute(id); window.scrollTo({ top: 0, behavior: 'smooth' }); }; const submit = (e) => { e.preventDefault(); if (!email.includes('@')) return; setSubscribed(true); setEmail(''); setTimeout(() => setSubscribed(false), 3500); }; return ( ); } // Reveal-on-scroll wrapper function Reveal({ children, delay = 0, as: As = 'div', className, ...rest }) { const ref = React.useRef(null); const [seen, setSeen] = React.useState(false); React.useEffect(() => { if (!ref.current) return; const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { setTimeout(() => setSeen(true), delay); io.disconnect(); } }); }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' }); io.observe(ref.current); return () => io.disconnect(); }, [delay]); return ( {children} ); } Object.assign(window, { Header, Footer, Arrow, Reveal, NAV_ITEMS });