// ============================================================ // Tribeca Lisboa — shared site chrome (bilingual header + drawer) // One header/nav/lang-switch reused by every page. Reads the // active language from LangContext; switch persists globally. // ============================================================ // Primary navigation — only the allowed destinations are active. // The current page's item is marked; scroll targets never are. window.navItems = function navItems(lang) { return [ { label: tt(lang, 'Program', 'Programa'), href: urlFor('program', 'all'), kind: 'program' }, { label: tt(lang, 'Talent', 'Talentos'), href: urlFor('talents'), kind: 'talents' }, { label: FIX('What’s new'), href: urlFor('home') + '#whats-new', scroll: 'whats-new', kind: 'home' }, { label: tt(lang, 'About', 'Sobre'), href: urlFor('about'), kind: 'about' }, { label: tt(lang, 'Pillars', 'Pilares'), href: urlFor('soon', 'pillars'), kind: 'soon' }, { label: 'Info', href: urlFor('salas'), kind: 'salas' }, { label: tt(lang, 'News', 'Notícias'), href: urlFor('news_list'), kind: 'news_list' }, ]; }; // Nav kind of the current page (event → program, talent → talents, news → news_list), // as a plain function above the JSX so the active rule is testable without a browser. window.navActiveKind = function (pathname, search) { return TFL_ROUTES.navKind(TFL_ROUTES.parse(pathname, search).kind); }; const hereKind = window.navActiveKind(location.pathname, location.search); const isActiveItem = function (n) { return !n.scroll && n.kind === hereKind; }; // smooth scroll (easeInOutQuad) over a fixed duration function smoothScrollTo(targetY, duration) { const startY = window.scrollY || window.pageYOffset; const diff = targetY - startY; let start = null; const ease = (t) => (t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2); function step(ts) { if (start === null) start = ts; const p = Math.min((ts - start) / duration, 1); window.scrollTo(0, startY + diff * ease(p)); if (p < 1) requestAnimationFrame(step); } requestAnimationFrame(step); } // What's new nav: same-page → 1s smooth scroll; other pages → let the link navigate function handleScrollNav(e, id, after) { const el = document.getElementById(id); if (el) { e.preventDefault(); const hdr = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--hdr-h')) || 82; const y = el.getBoundingClientRect().top + (window.scrollY || window.pageYOffset) - hdr; smoothScrollTo(y, 1000); } if (after) after(); } window.smoothScrollTo = smoothScrollTo; // EN / PT toggle — self-contained (drives the global language) function SiteLangSwitch() { const [lang, setLang] = useLang(); return (
/
); } function SiteFbIcon({ size = 20 }) { return ( ); } function SiteHeader({ onMenu }) { const lang = React.useContext(LangContext); return (
Powered by SIC
); } function SiteMenuDrawer({ open, onClose }) { const lang = React.useContext(LangContext); return (
{navItems(lang).map((n, i) => n.scroll ? handleScrollNav(e, n.scroll, onClose)}>{n.label} : n.href ? {n.label} : { e.preventDefault(); onClose(); }}>{n.label})}
Instagram Facebook
); } Object.assign(window, { SiteLangSwitch, SiteHeader, SiteMenuDrawer });