'use client' import { motion, AnimatePresence } from 'motion/react' import { ArrowRight, Menu, X, Check, BrainCircuit, Network, GraduationCap, Bot, KeyRound, Globe, ChevronDown } from 'lucide-react' import Link from 'next/link' import Image from 'next/image' import { useLanguage } from '@/lib/i18n' import type { SupportedLanguage } from '@/lib/i18n/load-translations' import { useEffect, useRef, useState, type ReactNode } from 'react' const ECHO_LINES = ['echo0', 'echo1', 'echo2'] as const const LANDING_LANGS: { code: SupportedLanguage; labelKey: string }[] = [ { code: 'fr', labelKey: 'languages.fr' }, { code: 'en', labelKey: 'languages.en' }, { code: 'es', labelKey: 'languages.es' }, { code: 'de', labelKey: 'languages.de' }, { code: 'it', labelKey: 'languages.it' }, { code: 'pt', labelKey: 'languages.pt' }, { code: 'nl', labelKey: 'languages.nl' }, { code: 'pl', labelKey: 'languages.pl' }, { code: 'ru', labelKey: 'languages.ru' }, { code: 'zh', labelKey: 'languages.zh' }, { code: 'ja', labelKey: 'languages.ja' }, { code: 'ko', labelKey: 'languages.ko' }, { code: 'ar', labelKey: 'languages.ar' }, { code: 'fa', labelKey: 'languages.fa' }, { code: 'hi', labelKey: 'languages.hi' }, ] export function LandingPage() { const { t, language, setLanguage } = useLanguage() const [billingInterval, setBillingInterval] = useState<'monthly' | 'annual'>('monthly') const [menuOpen, setMenuOpen] = useState(false) const [langOpen, setLangOpen] = useState(false) const [echoIndex, setEchoIndex] = useState(0) const langRef = useRef(null) useEffect(() => { if (!langOpen) return const onPointer = (e: MouseEvent) => { if (langRef.current && !langRef.current.contains(e.target as Node)) setLangOpen(false) } const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setLangOpen(false) } document.addEventListener('mousedown', onPointer) document.addEventListener('keydown', onKey) return () => { document.removeEventListener('mousedown', onPointer) document.removeEventListener('keydown', onKey) } }, [langOpen]) useEffect(() => { const id = setInterval(() => setEchoIndex((i) => (i + 1) % ECHO_LINES.length), 3200) return () => clearInterval(id) }, []) useEffect(() => { const root = document.querySelector('[data-public-scroll-root]') if (!root) return const prev = root.style.overflow if (menuOpen) root.style.overflow = 'hidden' else root.style.overflow = prev || '' return () => { root.style.overflow = prev } }, [menuOpen]) const PLANS = [ { key: 'basic', popular: false, price: t('landing.pricing.basicPrice'), period: '' }, { key: 'pro', popular: true, price: billingInterval === 'monthly' ? '9,90€' : '7,90€', period: billingInterval === 'monthly' ? t('landing.pricing.perMonth') : t('landing.pricing.perMonthAnnual') }, { key: 'business', popular: false, price: billingInterval === 'monthly' ? '29,90€' : '23,90€', period: billingInterval === 'monthly' ? t('landing.pricing.perMonth') : t('landing.pricing.perMonthAnnual') }, { key: 'enterprise', popular: false, price: billingInterval === 'monthly' ? '49,90€' : '39,90€', period: billingInterval === 'monthly' ? t('landing.pricing.perUser') : t('landing.pricing.perUserAnnual') }, ] const NAV = [ { href: '#product', label: t('landing.nav.secondBrain') }, { href: '#echo', label: t('landing.nav.echo') }, { href: '#agents', label: t('landing.nav.agents') }, { href: '#pricing', label: t('landing.nav.pricing') }, ] return (
{/* Nav */} {menuOpen && (
{NAV.map((l) => ( setMenuOpen(false)} className="py-4 text-3xl font-serif border-b border-white/10" > {l.label} ))} setMenuOpen(false)} className="mt-10 py-4 rounded-2xl bg-[#F4F1EA] text-[#0B0A09] text-center font-semibold"> {t('landing.nav.cta')}
)}
{/* ── HERO ── */}
{/* Atmosphere — warm, not purple neon */}
{t('landing.hero.badge')}

{t('landing.hero.eyebrow')}

{t('landing.hero.headline')}
{t('landing.hero.headlineAccent')}

{t('landing.hero.subtitle')}

{t('landing.hero.cta')}

{t('landing.hero.ctaHint')}

{/* Product stage */}
{t('landing.hero.imageAlt')} {/* Live Memory Echo chip */}
{t('landing.hero.echoLive')}
{t(`landing.hero.${ECHO_LINES[echoIndex]}`)}
{/* Trust strip */}
{['trust0', 'trust1', 'trust2', 'trust3'].map((k) => ( {t(`landing.trust.${k}`)} ))}
{/* Pain → Promise */}

{t('landing.pain.label')}

{t('landing.pain.title')}

{t('landing.pain.desc')}

{t('landing.pain.secondBrain')}

{/* Product moments — large narrative blocks, not wireframe cards */}
{[0, 1, 2].map((i) => (

{t(`landing.moments.echo.card${i}Label`)}

{t(`landing.moments.echo.card${i}`)}

))}
{['w0', 'w1', 'w2', 'w3'].map((w) => (

{t(`landing.moments.dashboard.${w}Label`)}

{t(`landing.moments.dashboard.${w}`)}

))}

{t('landing.moments.insights.chip')}

{t('landing.moments.revision.card')}

? SM-2
{/* How it works */}

{t('landing.how.title')}

{['s0', 's1', 's2'].map((s, i) => (
0{i + 1}

{t(`landing.how.${s}.title`)}

{t(`landing.how.${s}.desc`)}

))}
{/* Agents */}

{t('landing.agents.label')}

{t('landing.agents.title')}

{t('landing.agents.desc')}

{(['scraper', 'researcher', 'slideGen', 'monitor', 'diagramGen', 'custom'] as const).map((key) => (

{t(`landing.agents.${key}.title`)}

{t(`landing.agents.${key}.desc`)}

))}
{/* BYOK */}
{t('landing.byok.label')}

{t('landing.byok.title')}

{t('landing.byok.desc')}

{'{'}

"provider": "anthropic",

"model": "claude-sonnet",

"apiKey": "sk-ant-…",

"yours": true

{'}'}

{/* Pricing */}

{t('landing.pricing.title')}

{t('landing.pricing.desc')}

{PLANS.map((plan) => (
{plan.popular && ( {t('landing.pricing.popular')} )}

{t(`landing.pricing.${plan.key}.name`)}

{plan.price} {plan.period && {plan.period}}

{t(`landing.pricing.${plan.key}.desc`)}

    {[0, 1, 2, 3, 4, 5].map((j) => { const feat = t(`landing.pricing.${plan.key}.feature${j}`) if (!feat || feat.startsWith('landing.')) return null return (
  • {feat}
  • ) })}
{t(`landing.pricing.${plan.key}.cta`)}
))}
{/* Final CTA */}

{t('landing.cta.title')}

{t('landing.cta.desc')}

{t('landing.cta.button')}

{t('landing.hero.ctaHint')}

M
Memento

{t('landing.footer.desc')}

{(['product', 'community', 'legal'] as const).map((section) => (

{t(`landing.footer.${section}.title`)}

    {[0, 1, 2].map((j) => { const label = t(`landing.footer.${section}.link${j}`) const href = t(`landing.footer.${section}.link${j}Href`) if (!label || label.startsWith('landing.')) return null return (
  • {label}
  • ) })}
))}

© 2026 Memento. {t('landing.footer.rights')}

) } function ProductMoment({ id, eyebrow, title, desc, children, dark, compact, }: { id?: string eyebrow: string title: string desc: string children: ReactNode dark?: boolean compact?: boolean }) { return (

{eyebrow}

{title}

{desc}

{children}
) }