// Shared UI: Nav, Footer, Logo, Reveal, Icons const { useState, useEffect, useRef, useMemo } = React; // ============ LOGO ============ function LogoMark({ color = '#1A2B3C', dot = '#00C9A7', size = 32 }) { return ( ); } function LogoWord({ variant = 'dark' }) { const stroke = variant === 'light' ? '#FFFFFF' : '#1A2B3C'; const fill = variant === 'light' ? '#FFFFFF' : '#1A2B3C'; return (
keynara
); } // ============ ICONS ============ const Icon = { arrow: (p) => , chevron: (p) => , send: (p) => , check: (p) => , x: (p) => , plus: (p) => , minus: (p) => , sparkle: (p) => , map: (p) => , euro: (p) => , bed: (p) => , area: (p) => , globe: (p) => , }; // ============ Reveal (scroll-in) ============ function Reveal({ children, delay = 0, as: As = 'div', className = '', style = {} }) { const ref = useRef(null); const [visible, setVisible] = useState(false); useEffect(() => { if (!ref.current) return; const obs = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { setVisible(true); obs.disconnect(); } }); }, { threshold: 0.12 }); obs.observe(ref.current); return () => obs.disconnect(); }, []); return ( {children} ); } // ============ NAV ============ function Nav({ t, lang, setLang, page, setPage, onStartChat }) { const [scrolled, setScrolled] = useState(false); const [mobileOpen, setMobileOpen] = useState(false); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 8); window.addEventListener('scroll', onScroll); return () => window.removeEventListener('scroll', onScroll); }, []); const links = [ { id: 'how', label: t.nav.how }, { id: 'pricing', label: t.nav.pricing }, { id: 'investors', label: t.nav.investors }, { id: 'about', label: t.nav.about }, { id: 'blog', label: t.nav.blog }, { id: 'contact', label: t.nav.contact }, { id: 'agent', label: t.nav.agentTool, highlight: true }, ]; return (
{ e.preventDefault(); setPage('home'); }} href="#" aria-label="Keynara" style={{ display: 'flex', alignItems: 'center' }}>
{mobileOpen && (
{links.map(l => ( { e.preventDefault(); setPage(l.id); setMobileOpen(false); }} style={{ display: 'block', padding: '12px 0', borderBottom: '1px solid var(--line)', fontWeight: l.highlight ? 600 : 500, color: l.highlight ? 'var(--mint-dark)' : 'inherit', }}>{l.label} ))}
)}
); } function LangToggle({ lang, setLang }) { return (
{['de', 'en'].map(l => ( ))}
); } // ============ FOOTER ============ function Footer({ t, setPage }) { const cols = [ { title: t.footer.cols.product, links: [ { k: 'how', label: t.footer.links.how }, { k: 'pricing', label: t.footer.links.pricing }, { k: 'investors', label: t.footer.links.investors }, { k: 'contact', label: t.footer.links.api }, ]}, { title: t.footer.cols.company, links: [ { k: 'about', label: t.footer.links.about }, { k: 'about', label: t.footer.links.careers }, { k: 'blog', label: t.footer.links.press }, { k: 'contact', label: t.footer.links.contact }, ]}, { title: t.footer.cols.resources, links: [ { k: 'blog', label: t.footer.links.blog }, { k: 'contact', label: t.footer.links.help }, { k: 'contact', label: t.footer.links.status }, { k: 'about', label: t.footer.links.security }, ]}, { title: t.footer.cols.legal, links: [ { k: 'contact', label: t.footer.links.imprint }, { k: 'contact', label: t.footer.links.privacy }, { k: 'contact', label: t.footer.links.terms }, { k: 'contact', label: t.footer.links.cookies }, ]}, ]; return ( ); } function NewsletterBlock({ t }) { const [email, setEmail] = useState(''); const [sent, setSent] = useState(false); return (
{t.newsletter.title}

{t.newsletter.sub}

{ e.preventDefault(); if (email) setSent(true); }}>
setEmail(e.target.value)} placeholder={t.newsletter.placeholder} disabled={sent} style={{ flex: 1, padding: '14px 20px', background: 'transparent', border: 'none', color: 'white', fontSize: 15, fontFamily: 'inherit', outline: 'none', }} />

{t.newsletter.consent}

); } Object.assign(window, { LogoMark, LogoWord, Icon, Reveal, Nav, Footer });