/* global React */ const { useState, useEffect, useRef, useMemo, useCallback } = React; // ── App state: route + language ────────────────────────────────── const LANGS = ['pt-BR', 'en']; function detectLang() { try { const saved = localStorage.getItem('axiom0.lang'); if (saved && LANGS.includes(saved)) return saved; const nav = (navigator.language || 'pt-BR').toLowerCase(); if (nav.startsWith('en')) return 'en'; } catch (e) {} return 'pt-BR'; } function parseHash() { const h = (window.location.hash || '#/').replace(/^#/, ''); const parts = h.split('/').filter(Boolean); return { page: parts[0] || 'home', slug: parts[1] || null }; } function useRouter() { const [route, setRoute] = useState(parseHash()); useEffect(() => { const onHash = () => setRoute(parseHash()); window.addEventListener('hashchange', onHash); return () => window.removeEventListener('hashchange', onHash); }, []); const navigate = useCallback((page, slug) => { const h = slug ? `#/${page}/${slug}` : `#/${page}`; window.location.hash = h; window.scrollTo({ top: 0, behavior: 'instant' }); }, []); return { route, navigate }; } function useLang() { const [lang, setLang] = useState(detectLang()); useEffect(() => { try { localStorage.setItem('axiom0.lang', lang); } catch (e) {} document.documentElement.lang = lang === 'pt-BR' ? 'pt-BR' : 'en'; }, [lang]); return [lang, setLang]; } // ── IntersectionObserver-based reveal helper ───────────────────── function useReveal() { useEffect(() => { document.documentElement.classList.add('js-reveal'); const markAll = () => { document.querySelectorAll('.reveal:not(.in)').forEach((el) => { const r = el.getBoundingClientRect(); if (r.top < window.innerHeight + 40) el.classList.add('in'); }); }; // Initial reveal const t1 = setTimeout(markAll, 60); const t2 = setTimeout(markAll, 400); const onScroll = () => markAll(); window.addEventListener('scroll', onScroll, { passive: true }); const mo = new MutationObserver(() => setTimeout(markAll, 30)); mo.observe(document.body, { childList: true, subtree: true }); return () => { clearTimeout(t1); clearTimeout(t2); window.removeEventListener('scroll', onScroll); mo.disconnect(); }; }, []); } // Expose to all babel script scopes Object.assign(window, { useRouter, useLang, useReveal, LANGS });