/* ================================================================= Pages + history router Routes: / home /videos category (film) /videos/tides work detail /apps /webtools category /about /contact ================================================================= */ const { useState: pUS, useEffect: pUE, useRef: pUR } = React; /* ---------------- router ---------------- */ function useRoute() { const parse = () => { const raw = location.pathname.replace(/\/$/, ''); const segs = raw.split('/').filter(Boolean); if (!segs.length) return { view: 'home', key: 'home' }; if (segs[0] === 'about') return { view: 'about', key: 'about' }; if (segs[0] === 'contact') return { view: 'contact', key: 'contact' }; const cat = CAT_BY_ROUTE[segs[0]]; if (!cat) return { view: 'home', key: 'home' }; if (segs[1]) return { view: 'work', cat, slug: segs[1], key: `work:${segs[0]}/${segs[1]}` }; return { view: 'category', cat, key: `cat:${segs[0]}` }; }; const [r, setR] = pUS(parse); pUE(() => { const f = () => setR(parse()); window.addEventListener('popstate', f); return () => window.removeEventListener('popstate', f); }, []); return r; } /* label shown on the transition curtain */ function routeLabel(route, lang) { if (!route) return ''; if (route.view === 'home') return 'INDEX'; if (route.view === 'about') return L(window.PORTFOLIO.ui.about, lang).toUpperCase(); if (route.view === 'contact') return L(window.PORTFOLIO.ui.contact, lang).toUpperCase(); const cm = catMeta(route.cat); if (route.view === 'category') return `${cm.no} · ${L(cm.label, lang).toUpperCase()}`; if (route.view === 'work') { const w = workBySlug(route.cat, route.slug); return w ? w.title.toUpperCase() : ''; } return ''; } /* ---------------- footer (global) ---------------- */ function Footer({ data, lang }) { return ( ); } /* ================= HOME ================= */ function HomePage({ data, lang, topDirection }) { const scrollToIndex = () => { const el = document.querySelector('.home-index'); if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 60, behavior: 'smooth' }); }; return (
404 · NOT FOUND
← {L(cm.label, lang)}