'use client' import { motion, AnimatePresence } from 'motion/react' import { ArrowRight, Check, BrainCircuit, Network, GraduationCap, Bot, KeyRound } from 'lucide-react' import Link from 'next/link' import Image from 'next/image' import { useLanguage } from '@/lib/i18n' import { SUBSCRIPTION_TRIAL_DAYS } from '@/lib/billing/trial-constants' import { useEffect, useState, type ReactNode } from 'react' import { useQuery } from '@tanstack/react-query' import { PublicSiteChrome } from '@/components/public-site-chrome' import { DEFAULT_PRICES, annualDiscountPercent, } from '@/lib/billing/price-catalog' const ECHO_LINES = ['echo0', 'echo1', 'echo2'] as const export function LandingPage() { const { t } = useLanguage() const [billingInterval, setBillingInterval] = useState<'monthly' | 'annual'>('monthly') const [echoIndex, setEchoIndex] = useState(0) const { data: byokCatalog } = useQuery({ queryKey: ['public', 'byok-catalog'], queryFn: async () => { const res = await fetch('/api/public/byok-catalog') if (!res.ok) throw new Error('catalog') return res.json() as Promise<{ providers: { id: string; name: string }[] }> }, staleTime: 60_000, }) const byokProviders = byokCatalog?.providers ?? [] useEffect(() => { const id = setInterval(() => setEchoIndex((i) => (i + 1) % ECHO_LINES.length), 3200) return () => clearInterval(id) }, []) const trialDays = SUBSCRIPTION_TRIAL_DAYS const annualSavePercent = annualDiscountPercent( DEFAULT_PRICES.PRO.month.amount, DEFAULT_PRICES.PRO.year.amount, ) const PLANS = [ { key: 'basic', popular: false, hasTrial: false, price: t('landing.pricing.basicPrice'), period: '' }, { key: 'pro', popular: true, hasTrial: true, price: billingInterval === 'monthly' ? t('landing.pricing.proMonthly') : t('landing.pricing.proAnnualMonthly'), period: billingInterval === 'monthly' ? t('landing.pricing.perMonth') : t('landing.pricing.perMonthAnnual'), }, { key: 'business', popular: false, hasTrial: true, price: billingInterval === 'monthly' ? t('landing.pricing.businessMonthly') : t('landing.pricing.businessAnnualMonthly'), period: billingInterval === 'monthly' ? t('landing.pricing.perMonth') : t('landing.pricing.perMonthAnnual'), }, { key: 'enterprise', popular: false, hasTrial: false, price: t('landing.pricing.enterprisePrice'), period: '', }, ] const scrollPublicHash = (hash: string) => { const id = hash.replace(/^#/, '') const target = document.getElementById(id) const root = document.querySelector('[data-public-scroll-root]') if (!target || !root) return const top = target.getBoundingClientRect().top - root.getBoundingClientRect().top + root.scrollTop - 88 root.scrollTo({ top, behavior: 'smooth' }) } useEffect(() => { const hash = window.location.hash if (!hash) return const id = window.requestAnimationFrame(() => scrollPublicHash(hash)) return () => window.cancelAnimationFrame(id) }, []) return ( {/* ── 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')}

? {t('landing.moments.revision.badge')}
{/* 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')}

{byokProviders.length > 0 ? (
    {byokProviders.map((p) => (
  • {p.name}
  • ))}
) : (

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

)}

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

{/* 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}}
{plan.hasTrial && (

{t('landing.pricing.trialBadge', { days: trialDays })}

)}

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

    {plan.hasTrial && (
  • {t('landing.pricing.trialFeature', { days: trialDays })}
  • )} {[0, 1, 2, 3, 4, 5].map((j) => { const feat = t(`landing.pricing.${plan.key}.feature${j}`, { count: byokProviders.length || '…', }) if (!feat || feat.startsWith('landing.')) return null return (
  • {feat}
  • ) })}
{plan.hasTrial ? t('landing.pricing.trialCta', { days: trialDays }) : t(`landing.pricing.${plan.key}.cta`)}
))}
{/* Final CTA */}

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

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

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

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

) } 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}
) }