/* global React */
const { useState, useContext, createContext, useEffect } = React;

// ============================================================
// Promotion
// ============================================================
//
// THE knob. `enabled` turns the Early Bird phase on and off. There is no end
// date and no per-user window, deliberately: while it is on, every account gets
// `promoCloudScansPerMonth` cloud scans each month plus the premium features,
// and it stays that way until somebody sets this to false. Flip it and the whole
// page reverts by itself to the regular 4,99 EUR / Early Bird presentation — no
// code has to be removed to end the phase.
//
// This replaced a `freeUntil: 'YYYY-MM-DD'` date. The date implied a calendar
// guarantee ("free until 31.12.2026") that nothing in the product enforced, and
// it expired on its own on a day nobody had chosen.
//
// ── The numbers are MIRRORS, not sources of truth ─────────────────────────
// The page is compiled in the visitor's browser and has no build step, so it
// cannot import from packages/shared. The real homes are:
//
//   freeCloudScansPerMonth   ->  TIER_LIMITS.free.monthlyScans
//                                (packages/shared/src/config/tiers.ts)
//   freeActiveDeadlines      ->  TIER_LIMITS.free.activeDeadlines
//                                (same file)
//   promoCloudScansPerMonth  ->  EARLY_BIRD_MODE
//                                (apps/api/wrangler.jsonc — the API's own switch)
//
// Change a number there and change it here too, or the page advertises a limit
// the product does not enforce. NOTE the two switches are independent:
// `enabled` here only changes what the SITE SAYS; EARLY_BIRD_MODE is what
// actually grants the scans. Flipping one without the other makes the page lie.

const PROMO = {
  enabled: true,
  promoCloudScansPerMonth: 30,
  freeCloudScansPerMonth: 5,
  freeActiveDeadlines: 3,
};

// Every number the page quotes, in one object, so a string can never be written
// against a literal. Pass it to fill() wherever copy mentions a limit.
const PROMO_VARS = {
  promoScans: PROMO.promoCloudScansPerMonth,
  freeScans: PROMO.freeCloudScansPerMonth,
  freeDeadlines: PROMO.freeActiveDeadlines,
};

function promoIsActive() {
  return Boolean(PROMO.enabled);
}

// Minimal {placeholder} interpolation - the page carries no i18n library.
function fill(template, vars) {
  return template.replace(/\{(\w+)\}/g, (whole, key) => (key in vars ? vars[key] : whole));
}

// ============================================================
// i18n
// ============================================================

const STRINGS = {
  de: {
    htmlLang: 'de',
    nav: { features: 'Funktionen', security: 'Sicherheit', pricing: 'Preise', faq: 'FAQ', cta: 'Auf die Warteliste' },
    hero: {
      badge: 'Bald verfügbar — iOS & Android',
      titleA: 'Behördenpost', titleB: 'im Griff.',
      body: 'Fotografieren Sie einen Brief vom Finanzamt, Jobcenter oder der Bußgeldstelle — FristRadar erkennt die Frist, plant die Schritte und erstellt die DIN 5008 Antwort.',
      cta: 'Auf die Warteliste',
      ghost: 'So funktioniert’s',
      soon: 'Bald verfügbar',
      tooltip: 'Bald im App Store & Play Store — jetzt vormerken lassen.',
    },
    mini: {
      brand: 'FristRadar', scan: 'Brief scannen', latest: 'Letzte Briefe',
      letters: [
        { from: 'Finanzamt Berlin‑Mitte', subj: 'Einkommensteuererklärung 2024', risk: 'high', days: '15', deadline: '19.03.2026' },
        { from: 'Bußgeldstelle Köln', subj: 'Anhörung – Geschwindigkeit', risk: 'mid', days: '22', deadline: '26.03.2026' },
        { from: 'Jobcenter München', subj: 'Weiterbewilligungsantrag', risk: 'low', days: '37', deadline: '10.04.2026' },
      ],
      heroLetterFrom: 'FINANZAMT BERLIN‑MITTE',
      heroLetterDeadline: 'Frist: 19.03.2026',
      daysWord: 'Tage',
      risks: { high: 'Hohes Risiko', mid: 'Mittleres', low: 'Geringes' },
    },
    waitlist: {
      badge: 'Early Bird', title: 'Werde Early Bird.',
      bodyA: 'Trag dich in die Warteliste ein und erhalte ',
      bodyB: '3–6 Monate FristRadar Premium kostenlos',
      bodyC: ', sobald die App live ist.',
      // Used instead of bodyB/bodyC while PROMO.enabled. Must describe the SAME
      // grant the API actually makes (LAUNCH_TRIAL_DAYS / LAUNCH_TRIAL_CLOUD_SCANS).
      promoBodyB: 'FristRadar Premium gratis',
      promoBodyC: ' – mit {promoScans} Cloud‑Scans pro Monat, sobald die App live ist.',
      placeholder: 'ihre@email.de', cta: 'Vormerken',
      ctaSending: 'Wird gesendet…',
      reassure: 'Kein Spam. Wir melden uns nur einmal — wenn die App startet.',
      successTitle: 'Sie sind dabei.',
      successBody: 'Wir haben Ihnen eine Bestätigung an Ihre E-Mail-Adresse geschickt.',
      errorInvalid: 'Bitte geben Sie eine gültige E-Mail-Adresse ein.',
      errorGeneric: 'Etwas ist schiefgelaufen. Bitte später noch einmal versuchen.',
    },
    problem: {
      eyebrow: 'Das Problem',
      title: 'Eine verpasste Frist kann teuer werden.',
      body: 'Behördenbriefe kommen in Papier. Sie liegen Tage auf dem Küchentisch. Niemand erinnert. Niemand trackt. Eine versäumte Frist kostet Geld, manchmal eine Genehmigung, manchmal mehr — und es gibt schlicht kein System dafür.',
    },
    how: {
      eyebrow: 'So funktioniert’s',
      title: 'Vier Schritte vom Brief zum Nachweis.',
      steps: [
        { n: '01', t: 'Foto machen', d: 'Fotografieren Sie den Brief — vorne und hinten. Die Texterkennung läuft auf Ihrem Gerät.' },
        { n: '02', t: 'Frist & Risiko sehen', d: 'FristRadar erkennt die Frist und stuft das Risiko ein: Was passiert, wenn Sie sie versäumen?' },
        { n: '03', t: 'Aktionsplan + Antwort', d: 'Schritt‑für‑Schritt‑Plan plus eine fertige Antwortvorlage im DIN 5008 Format.' },
        { n: '04', t: 'Nachweis ablegen', d: 'Versandbeleg fotografieren. Tracking‑Nummer eintragen. Frist sauber abgeschlossen.' },
      ],
    },
    features: {
      eyebrow: 'Funktionen',
      title: 'Alles, was zwischen Briefkasten und Frist passiert.',
      items: [
        { t: 'Frist‑Erkennung mit Risikostufe', d: 'Drei Stufen: hoch, mittel, gering — mit konkreter Konsequenz in Euro.' },
        { t: 'Aktionsplan pro Behörde', d: 'Vorgefertigte Schritte für Finanzamt, Jobcenter, Bußgeldstelle, Ausländerbehörde und mehr.' },
        { t: 'DIN 5008 Antwort‑Generator', d: 'Formaler Antwortbrief, fertig zum Drucken oder als PDF — Adressblock, Aktenzeichen, Betreff.' },
        { t: 'Nachweis‑Ordner', d: 'Posteingang, Sendebeleg, Tracking. Pro Brief ein vollständiger Vorgang.' },
        { t: 'Kalender‑Sync + Reminder', d: 'T‑7, T‑3, T‑1 als Push. „Erledigt"‑Knopf schließt die Frist sauber ab.' },
        { t: 'On‑Device OCR', d: 'Daten bleiben auf Ihrem Gerät. Cloud‑OCR nur, wenn Sie es ausdrücklich wählen.' },
      ],
    },
    authorities: {
      eyebrow: 'Unterstützte Behörden',
      title: 'Von Finanzamt bis Gericht.',
      list: ['Finanzamt', 'Bußgeldstelle', 'Jobcenter / Agentur für Arbeit', 'Ausländerbehörde', 'Krankenkasse', 'Rentenversicherung', 'Bauamt', 'Kfz‑Zulassung', 'Kita / Schule', 'Gericht'],
    },
    privacy: {
      eyebrow: 'Datenschutz',
      title: 'Ihre Briefe bleiben Ihre Briefe.',
      body: 'FristRadar ist für deutsche Nutzer gebaut — und das schließt deutschen Datenschutz‑Anspruch ein.',
      items: [
        ['On‑Device OCR', 'Standard. Texterkennung passiert auf Ihrem Gerät — der Brief verlässt es nicht.'],
        ['EU‑only Hosting', 'Cloudflare EU. Keine Drittland‑Übermittlung, keine US‑Hyperscaler.'],
        ['Datenminimierung', 'Wir speichern nur, was die App braucht. Keine Werbe‑IDs, kein Tracking.'],
        ['Verschlüsselung', 'At rest und in transit. AES‑256 / TLS 1.3.'],
        ['Auto‑Löschung', 'Konfigurierbar pro Brief: nach 90, 180 oder 365 Tagen.'],
        ['Open Audit', 'Datenschutzkonzept und Sicherheitsbericht öffentlich einsehbar.'],
      ],
    },
    pricing: {
      eyebrow: 'Preise', title: 'Klar, fair, deutsch.',
      free: { name: 'Free', desc: 'Für gelegentliche Briefe.', price: '0 €', items: ['{freeScans} Scans pro Monat', '{freeDeadlines} aktive Fristen', 'Manueller .ics‑Export', 'Vorlagen nur lesen'] },
      premium: {
        name: 'Premium', desc: 'Für alle, die alles im Griff brauchen.',
        price: '4,99 €', perMonth: '/ Monat', promoPrice: '0 €',
        earlyBird: 'Early Bird · 3–6 Monate gratis',
        earlyBirdNote: 'Auf der Warteliste: 3–6 Monate gratis',
        promoBadge: 'Gratis für Early Birds',
        promoNote: 'Als Early Bird gratis · danach {price} / Monat',
        items: ['Unbegrenzte Scans & Fristen', 'Auto‑Kalender‑Sync', 'Antwortvorlagen generieren & bearbeiten', 'DIN 5008 PDF‑Export', 'Cloud‑OCR (auch Handschrift)'],
        // Replaces items[0] while the promo runs. The free phase is METERED:
        // {promoScans} Cloud‑Scans pro Monat, nicht unbegrenzt. Die Fristen sind
        // nicht gedeckelt, deshalb trägt nur die Scan‑Zahl eine Zahl.
        promoFirstItem: '{promoScans} Cloud‑Scans pro Monat · unbegrenzte Fristen',
      },
    },
    faq: {
      eyebrow: 'Fragen & Antworten', title: 'Was Sie wissen sollten.',
      qa: [
        ['Wann startet die App?', 'Wir planen den Launch im Lauf des Jahres 2026 — iOS und Android gemeinsam. Early Birds bekommen die App eine Woche vor allen anderen.'],
        ['Was bekomme ich als Early Bird genau?', '3 bis 6 Monate FristRadar Premium kostenlos, sobald die App live ist. Die Länge richtet sich nach Ihrer Position auf der Warteliste.', 'Solange die Early‑Bird‑Phase läuft: FristRadar Premium kostenlos, mit {promoScans} Cloud‑Scans pro Monat. Alle übrigen Premium‑Funktionen sind unbegrenzt – Auto‑Kalender‑Sync, Antwortvorlagen, DIN 5008 PDF‑Export und Cloud‑OCR, dazu unbegrenzte Fristen. Endet die Phase, läuft Ihr Konto normal weiter mit {freeScans} Cloud‑Scans pro Monat.'],
        ['Wo werden meine Daten gespeichert?', 'Ausschließlich in der EU, gehostet bei Cloudflare EU. Texterkennung läuft standardmäßig auf Ihrem Gerät — nichts verlässt das Telefon ohne Ihre Zustimmung.'],
        ['Funktioniert das auch mit handschriftlichen Briefen?', 'Mit Premium: ja. Cloud‑OCR erkennt auch deutsche Handschrift in Druckbuchstaben — Sie können das Ergebnis vor dem Speichern korrigieren.'],
        ['Welche Behörden werden unterstützt?', 'Finanzamt, Jobcenter, Bußgeldstelle, Ausländerbehörde, Krankenkasse, Rentenversicherung, Bauamt, Kfz‑Zulassung, Kita/Schule, Gericht. Andere Behörden lassen sich manuell anlegen.'],
        ['iOS und Android?', 'Beides. Beide Plattformen starten gleichzeitig.'],
      ],
    },
    footer: {
      tagline: 'Behördenpost im Griff. Frist erkennen, handeln, Nachweis sichern.',
      colProduct: 'Produkt', colLegal: 'Rechtliches', colContact: 'Kontakt',
      productLinks: [['Funktionen', '#funktionen'], ['Sicherheit', '#sicherheit'], ['Preise', '#preise'], ['FAQ', '#faq']],
      legalLinks: [['Impressum', 'https://teknora.de/de/contact#legal'], ['Datenschutz', 'https://teknora.de/de/privacy-policy']],
      contactLinks: [['info@teknora.de', 'mailto:info@teknora.de'], ['Kontaktformular', 'https://teknora.de/de/contact']],
      copyright: '© 2026 Teknora e.K. · Made in Germany',
    },
  },

  en: {
    htmlLang: 'en',
    nav: { features: 'Features', security: 'Privacy', pricing: 'Pricing', faq: 'FAQ', cta: 'Join the waitlist' },
    hero: {
      badge: 'Coming soon — iOS & Android',
      titleA: 'Government mail,', titleB: 'under control.',
      body: 'Photograph a letter from the Finanzamt, Jobcenter or Bußgeldstelle — FristRadar detects the deadline, plans the steps, and drafts a DIN 5008 reply for you.',
      cta: 'Join the waitlist',
      ghost: 'How it works',
      soon: 'Coming soon',
      tooltip: 'Coming to App Store & Play Store — sign up to be notified.',
    },
    mini: {
      brand: 'FristRadar', scan: 'Scan letter', latest: 'Recent letters',
      letters: [
        { from: 'Finanzamt Berlin‑Mitte', subj: 'Income tax return 2024', risk: 'high', days: '15', deadline: '19.03.2026' },
        { from: 'Bußgeldstelle Köln', subj: 'Hearing — speeding', risk: 'mid', days: '22', deadline: '26.03.2026' },
        { from: 'Jobcenter München', subj: 'Benefits renewal', risk: 'low', days: '37', deadline: '10.04.2026' },
      ],
      heroLetterFrom: 'FINANZAMT BERLIN‑MITTE',
      heroLetterDeadline: 'Deadline: 19.03.2026',
      daysWord: 'days',
      risks: { high: 'High risk', mid: 'Medium', low: 'Low' },
    },
    waitlist: {
      badge: 'Early Bird', title: 'Become an early bird.',
      bodyA: 'Join the waitlist and receive ',
      bodyB: '3–6 months of FristRadar Premium for free',
      bodyC: ' as soon as the app launches.',
      // See the German note above.
      promoBodyB: 'FristRadar Premium for free',
      promoBodyC: ' — with {promoScans} cloud scans a month, as soon as the app launches.',
      placeholder: 'your@email.com', cta: 'Notify me',
      ctaSending: 'Sending…',
      reassure: 'No spam. We’ll write you exactly once — when the app goes live.',
      successTitle: 'You’re on the list.',
      successBody: 'We’ve sent a confirmation to your inbox.',
      errorInvalid: 'Please enter a valid email address.',
      errorGeneric: 'Something went wrong. Please try again later.',
    },
    problem: {
      eyebrow: 'The problem',
      title: 'A missed deadline can get expensive — fast.',
      body: 'Government letters arrive on paper. They sit on the kitchen table for days. Nobody reminds you. Nobody tracks them. A missed deadline costs money, sometimes a permit, sometimes more — and there is simply no system for it.',
    },
    how: {
      eyebrow: 'How it works',
      title: 'Four steps from letter to proof of delivery.',
      steps: [
        { n: '01', t: 'Take a photo', d: 'Photograph the letter — front and back. Text recognition runs on your device.' },
        { n: '02', t: 'See deadline & risk', d: 'FristRadar detects the deadline and rates the risk: what happens if you miss it?' },
        { n: '03', t: 'Action plan + reply', d: 'Step‑by‑step plan plus a ready‑to‑send DIN 5008 response template.' },
        { n: '04', t: 'File the proof', d: 'Photograph the postal receipt. Add the tracking number. Deadline cleanly closed.' },
      ],
    },
    features: {
      eyebrow: 'Features',
      title: 'Everything that happens between the mailbox and the deadline.',
      items: [
        { t: 'Deadline detection with risk level', d: 'Three tiers: high, medium, low — with concrete consequences in euros.' },
        { t: 'Action plan per authority', d: 'Pre‑built steps for Finanzamt, Jobcenter, Bußgeldstelle, Ausländerbehörde and more.' },
        { t: 'DIN 5008 response generator', d: 'A formal reply letter, ready to print or as PDF — address block, file number, subject.' },
        { t: 'Proof folder', d: 'Inbox, postal receipt, tracking. One complete record per letter.' },
        { t: 'Calendar sync + reminders', d: 'T‑7, T‑3, T‑1 as push. “Done” button closes the deadline cleanly.' },
        { t: 'On‑device OCR', d: 'Your data stays on your device. Cloud OCR only when you explicitly choose it.' },
      ],
    },
    authorities: {
      eyebrow: 'Supported authorities',
      title: 'From Finanzamt to Gericht.',
      list: ['Finanzamt', 'Bußgeldstelle', 'Jobcenter / Agentur für Arbeit', 'Ausländerbehörde', 'Krankenkasse', 'Rentenversicherung', 'Bauamt', 'Kfz‑Zulassung', 'Kita / Schule', 'Gericht'],
    },
    privacy: {
      eyebrow: 'Privacy',
      title: 'Your letters stay your letters.',
      body: 'FristRadar is built for German users — and that includes a German‑level expectation of privacy.',
      items: [
        ['On‑device OCR', 'Default. Text recognition runs on your device — the letter never leaves it.'],
        ['EU‑only hosting', 'Cloudflare EU. No third‑country transfers, no US hyperscalers.'],
        ['Data minimisation', 'We only store what the app needs. No advertising IDs, no tracking.'],
        ['Encryption', 'At rest and in transit. AES‑256 / TLS 1.3.'],
        ['Auto‑deletion', 'Configurable per letter: after 90, 180 or 365 days.'],
        ['Open audit', 'Privacy concept and security report publicly available.'],
      ],
    },
    pricing: {
      eyebrow: 'Pricing', title: 'Clear, fair, no surprises.',
      free: { name: 'Free', desc: 'For occasional letters.', price: '€ 0', items: ['{freeScans} scans per month', '{freeDeadlines} active deadlines', 'Manual .ics export', 'Templates read‑only'] },
      premium: {
        name: 'Premium', desc: 'For everyone who needs all of it under control.',
        price: '€ 4.99', perMonth: '/ month', promoPrice: '€ 0',
        earlyBird: 'Early Bird · 3–6 months free',
        earlyBirdNote: 'On the waitlist: 3–6 months free',
        promoBadge: 'Free for Early Birds',
        promoNote: 'Free as an early bird · then {price} / month',
        items: ['Unlimited scans & deadlines', 'Auto calendar sync', 'Generate & edit response templates', 'DIN 5008 PDF export', 'Cloud OCR (handwriting too)'],
        // See the German note above.
        promoFirstItem: '{promoScans} cloud scans per month · unlimited deadlines',
      },
    },
    faq: {
      eyebrow: 'Questions & answers', title: 'What you should know.',
      qa: [
        ['When is the app launching?', 'We are planning the launch during 2026 — iOS and Android together. Early birds get the app a week before everyone else.'],
        ['What exactly do I get as an early bird?', '3 to 6 months of FristRadar Premium for free, as soon as the app launches. The length depends on your position on the waitlist.', 'For as long as the Early Bird phase runs: FristRadar Premium for free, with {promoScans} cloud scans per month. Every other premium feature is unlimited — auto calendar sync, response templates, DIN 5008 PDF export and cloud OCR, plus unlimited deadlines. When the phase ends your account continues normally with {freeScans} cloud scans per month.'],
        ['Where is my data stored?', 'Exclusively in the EU, hosted on Cloudflare EU. Text recognition runs on your device by default — nothing leaves your phone without your consent.'],
        ['Does it work with handwritten letters?', 'With Premium: yes. Cloud OCR also recognises German block‑letter handwriting — and you can correct the result before saving.'],
        ['Which authorities are supported?', 'Finanzamt, Jobcenter, Bußgeldstelle, Ausländerbehörde, Krankenkasse, Rentenversicherung, Bauamt, Kfz‑Zulassung, Kita/Schule, Gericht. Other authorities can be added manually.'],
        ['iOS and Android?', 'Both. Both platforms launch at the same time.'],
      ],
    },
    footer: {
      tagline: 'Government mail under control. Detect, act, prove.',
      colProduct: 'Product', colLegal: 'Legal', colContact: 'Contact',
      productLinks: [['Features', '#funktionen'], ['Privacy', '#sicherheit'], ['Pricing', '#preise'], ['FAQ', '#faq']],
      legalLinks: [['Legal notice', 'https://teknora.de/en/contact#legal'], ['Privacy policy', 'https://teknora.de/en/privacy-policy']],
      contactLinks: [['info@teknora.de', 'mailto:info@teknora.de'], ['Contact form', 'https://teknora.de/en/contact']],
      copyright: '© 2026 Teknora e.K. · Made in Germany',
    },
  },
};

const I18nContext = createContext({ t: STRINGS.de, lang: 'de', setLang: () => {} });
const useT = () => useContext(I18nContext);

function I18nProvider({ children }) {
  const initial = (() => {
    if (typeof window === 'undefined') return 'de';
    const saved = window.localStorage?.getItem('fristradar-lang');
    if (saved === 'de' || saved === 'en') return saved;
    const nav = (window.navigator?.language || 'de').toLowerCase();
    return nav.startsWith('en') ? 'en' : 'de';
  })();
  const [lang, _setLang] = useState(initial);
  const setLang = (l) => {
    _setLang(l);
    try { window.localStorage.setItem('fristradar-lang', l); } catch {}
    document.documentElement.lang = STRINGS[l].htmlLang;
  };
  useEffect(() => { document.documentElement.lang = STRINGS[lang].htmlLang; }, [lang]);
  return (
    <I18nContext.Provider value={{ t: STRINGS[lang], lang, setLang }}>
      {children}
    </I18nContext.Provider>
  );
}

// ============================================================
// Components
// ============================================================

function Nav() {
  const { t, lang, setLang } = useT();
  return (
    <header className="lp-nav" style={lpStyles.nav}>
      <a href="#top" style={{ display: 'flex', alignItems: 'center', gap: 10, textDecoration: 'none' }}>
        <div style={{ width: 32, height: 32, borderRadius: '22%', background: '#0F1115', color: '#fff', fontWeight: 800, fontSize: 16, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>F</div>
        <span style={{ fontWeight: 700, fontSize: 18, color: '#1C2833', letterSpacing: '-0.01em' }}>FristRadar</span>
      </a>
      <nav className="lp-nav-links" style={{ display: 'flex', gap: 28, alignItems: 'center' }}>
        <a className="lp-nav-text" href="#funktionen" style={lpStyles.navLink}>{t.nav.features}</a>
        <a className="lp-nav-text" href="#sicherheit" style={lpStyles.navLink}>{t.nav.security}</a>
        <a className="lp-nav-text" href="#preise" style={lpStyles.navLink}>{t.nav.pricing}</a>
        <a className="lp-nav-text" href="#faq" style={lpStyles.navLink}>{t.nav.faq}</a>
        <LangToggle lang={lang} setLang={setLang}/>
        <a href="#waitlist" className="lp-cta-link" style={{ ...lpStyles.navLink, background: '#1B4F72', color: '#fff', padding: '9px 16px', borderRadius: 12, fontWeight: 700 }}>{t.nav.cta}</a>
      </nav>
    </header>
  );
}

function LangToggle({ lang, setLang }) {
  const btn = (active) => ({
    background: active ? '#1B4F72' : 'transparent',
    color: active ? '#fff' : '#1C2833',
    border: '1px solid ' + (active ? '#1B4F72' : '#C5D0DB'),
    padding: '5px 10px',
    borderRadius: 8,
    fontSize: 12,
    fontWeight: 700,
    fontFamily: 'inherit',
    cursor: 'pointer',
    letterSpacing: '.02em',
  });
  return (
    <div role="group" aria-label="Language" style={{ display: 'inline-flex', gap: 4 }}>
      <button type="button" onClick={() => setLang('de')} style={btn(lang === 'de')} aria-pressed={lang === 'de'}>DE</button>
      <button type="button" onClick={() => setLang('en')} style={btn(lang === 'en')} aria-pressed={lang === 'en'}>EN</button>
    </div>
  );
}

function Hero() {
  const { t } = useT();
  return (
    <section id="top" className="lp-section lp-hero-section" style={{ ...lpStyles.section, paddingTop: 64, paddingBottom: 48, background: '#EBF0F5' }}>
      <div style={lpStyles.container}>
        <div className="lp-grid-hero" style={{ display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 64, alignItems: 'center' }}>
          <div>
            <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '6px 12px', borderRadius: 999, background: '#D6EAF8', color: '#1B4F72', fontSize: 13, fontWeight: 600, marginBottom: 24 }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#E67E22' }}/>{t.hero.badge}
            </div>
            <h1 style={{ fontSize: 'clamp(36px,5vw,60px)', fontWeight: 700, lineHeight: 1.05, letterSpacing: '-0.02em', color: '#1C2833', margin: '0 0 20px' }}>
              {t.hero.titleA}<br/>{t.hero.titleB}
            </h1>
            <p style={{ fontSize: 19, lineHeight: 1.5, color: '#5D6D7E', margin: '0 0 32px', maxWidth: 520 }}>{t.hero.body}</p>
            <div className="lp-hero-cta" style={{ display: 'flex', gap: 12, marginBottom: 24, flexWrap: 'wrap' }}>
              <a href="#waitlist" style={{ ...lpStyles.btnPrimary }}>{t.hero.cta}</a>
              <a href="#how" style={{ ...lpStyles.btnGhost }}>{t.hero.ghost}</a>
            </div>
            <div className="lp-hero-stores" style={{ display: 'flex', gap: 14, alignItems: 'center', flexWrap: 'wrap' }} title={t.hero.tooltip}>
              <a href="#waitlist" style={{ filter: 'grayscale(1)', opacity: .55, position: 'relative', display: 'inline-block' }}>
                <StoreBadge variant="apple"/>
              </a>
              <a href="#waitlist" style={{ filter: 'grayscale(1)', opacity: .55 }}>
                <StoreBadge variant="google"/>
              </a>
              <span style={{ fontSize: 12, color: '#5D6D7E', padding: '4px 10px', background: '#fff', border: '1px solid #E5E7EB', borderRadius: 999, fontWeight: 600 }}>{t.hero.soon}</span>
            </div>
          </div>
          <HeroVisual/>
        </div>
      </div>
    </section>
  );
}

function StoreBadge({ variant }) {
  if (variant === 'apple') {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: '#000', color: '#fff', padding: '8px 18px', borderRadius: 10, minWidth: 160 }}>
        <svg width="22" height="26" viewBox="0 0 24 28" fill="currentColor"><path d="M19.6 21.6c-1 1.5-2.1 3-3.7 3-1.6 0-2.1-1-4-1s-2.4 1-3.9 1c-1.6 0-2.8-1.4-3.8-2.9-2-3-3.5-8.5-1.5-12.2.9-1.8 2.7-3 4.6-3 1.6 0 3 1.1 4 1.1.9 0 2.7-1.3 4.6-1.1 1.5 0 2.9.7 3.8 1.7-3.4 1.9-2.9 6.8.6 8.1-1 1.5-1.7 2.8-2.7 4.4ZM12.5 5.4C13.4 4.3 14 2.8 13.8 1.3c-1.4.1-3 1-3.9 2-.8.9-1.5 2.4-1.3 3.9 1.5.1 3-.7 3.9-1.8Z"/></svg>
        <div style={{ lineHeight: 1.1 }}>
          <div style={{ fontSize: 9 }}>Download on the</div>
          <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.02em' }}>App Store</div>
        </div>
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: '#000', color: '#fff', padding: '8px 18px', borderRadius: 10, minWidth: 170 }}>
      <svg width="22" height="24" viewBox="0 0 24 26" fill="none"><path d="M3 1l11 12L3 25z" fill="#34A853"/><path d="M3 1l13 12L3 25l13-7z" fill="#FBBC04" opacity=".6"/><path d="M14 9l8 4-8 4z" fill="#EA4335"/><path d="M3 1l11 8-3 4z" fill="#4285F4"/></svg>
      <div style={{ lineHeight: 1.1 }}>
        <div style={{ fontSize: 9 }}>GET IT ON</div>
        <div style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.02em' }}>Google Play</div>
      </div>
    </div>
  );
}

function HeroVisual() {
  const { t } = useT();
  return (
    <div className="lp-hero-visual" style={{ position: 'relative', height: 520, display: 'flex', justifyContent: 'center' }}>
      <div className="lp-hero-letter" style={{ position: 'absolute', top: 30, left: 30, width: 240, height: 300, background: '#fff', borderRadius: 8, boxShadow: '0 12px 32px rgba(15,17,21,.08)', padding: '24px 22px', transform: 'rotate(-6deg)', border: '1px solid #E5E7EB' }}>
        <div style={{ fontFamily: 'ui-monospace,Menlo,monospace', fontSize: 9, color: '#5D6D7E', marginBottom: 12 }}>{t.mini.heroLetterFrom}</div>
        <div style={{ height: 6, background: '#1C2833', width: '70%', borderRadius: 2, marginBottom: 8 }}/>
        <div style={{ height: 6, background: '#E5E7EB', width: '90%', borderRadius: 2, marginBottom: 6 }}/>
        <div style={{ height: 6, background: '#E5E7EB', width: '85%', borderRadius: 2, marginBottom: 6 }}/>
        <div style={{ height: 6, background: '#E5E7EB', width: '92%', borderRadius: 2, marginBottom: 6 }}/>
        <div style={{ height: 6, background: '#E5E7EB', width: '60%', borderRadius: 2, marginBottom: 24 }}/>
        <div style={{ fontSize: 11, fontWeight: 700, color: '#E74C3C' }}>{t.mini.heroLetterDeadline}</div>
        <div style={{ height: 6, background: '#FDECEA', width: '70%', borderRadius: 2, marginTop: 8 }}/>
        <div style={{ height: 6, background: '#FDECEA', width: '55%', borderRadius: 2, marginTop: 6 }}/>
      </div>
      <div className="lp-hero-phone" style={{ position: 'relative', width: 280, height: 560, background: '#0F1115', borderRadius: 40, padding: 8, boxShadow: '0 24px 60px rgba(15,17,21,.20)', marginLeft: 80, marginTop: -10 }}>
        <div style={{ width: '100%', height: '100%', background: '#F4F5F7', borderRadius: 32, overflow: 'hidden', position: 'relative' }}>
          <div style={{ padding: '46px 18px 18px' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
              <div style={{ width: 24, height: 24, borderRadius: '22%', background: '#0F1115', color: '#fff', fontWeight: 800, fontSize: 13, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>F</div>
              <div style={{ fontWeight: 700, fontSize: 16, color: '#1C2833' }}>{t.mini.brand}</div>
            </div>
            <div style={{ background: '#0F1115', color: '#fff', padding: '10px 12px', borderRadius: 12, fontSize: 12, fontWeight: 700, textAlign: 'center', marginBottom: 14 }}>{t.mini.scan}</div>
            <div style={{ fontSize: 9, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: '#5D6D7E', marginBottom: 8 }}>{t.mini.latest}</div>
            {t.mini.letters.map((l, i) => (
              <div key={i}>
                <MiniLetterCard from={l.from} subj={l.subj} risk={l.risk} days={l.days} deadline={l.deadline}/>
                {i < t.mini.letters.length - 1 ? <div style={{ height: 8 }}/> : null}
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

function MiniLetterCard({ from, subj, risk, days, deadline }) {
  const { t } = useT();
  const c = { high: { bg: '#FDECEA', fg: '#B33120', dot: '#E74C3C' }, mid: { bg: '#FEF3E2', fg: '#B57100', dot: '#F39C12' }, low: { bg: '#E8F6EE', fg: '#1D7A43', dot: '#27AE60' } }[risk];
  const label = t.mini.risks[risk];
  return (
    <div style={{ background: '#fff', border: '1px solid #E5E7EB', borderRadius: 8, padding: 10 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 2 }}>
        <div style={{ fontWeight: 700, fontSize: 11, color: '#1C2833' }}>{from}</div>
        <div style={{ fontWeight: 700, fontSize: 10, color: '#1C2833' }}>{days} {t.mini.daysWord}</div>
      </div>
      <div style={{ fontSize: 10, color: '#5D6D7E', marginBottom: 6 }}>{subj}</div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, background: c.bg, color: c.fg, padding: '2px 7px', borderRadius: 999, fontWeight: 700, fontSize: 9 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: c.dot }}/>{label}
        </span>
        <span style={{ fontSize: 9, color: '#5D6D7E', fontFamily: 'ui-monospace,Menlo,monospace' }}>{deadline}</span>
      </div>
    </div>
  );
}

function Waitlist() {
  const { t, lang } = useT();
  // The waitlist promise must describe the grant the API actually makes. While
  // the Early Bird phase runs that is PROMO.promoCloudScansPerMonth a month,
  // not the original "3-6 months"; flip PROMO.enabled and the old wording returns.
  const promo = promoIsActive();
  const w = t.waitlist;
  const bodyB = promo && w.promoBodyB ? fill(w.promoBodyB, PROMO_VARS) : w.bodyB;
  const bodyC = promo && w.promoBodyC ? fill(w.promoBodyC, PROMO_VARS) : w.bodyC;
  const [email, setEmail] = useState('');
  const [status, setStatus] = useState('idle'); // 'idle' | 'sending' | 'ok' | 'error'
  const [errorMsg, setErrorMsg] = useState('');

  const submit = async (e) => {
    e.preventDefault();
    if (status === 'sending') return;
    setErrorMsg('');
    setStatus('sending');
    try {
      const r = await fetch('/api/waitlist', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, lang }),
      });
      const data = await r.json().catch(() => ({}));
      if (r.ok && data.ok) {
        setStatus('ok');
      } else {
        setStatus('error');
        setErrorMsg(r.status === 400 ? t.waitlist.errorInvalid : t.waitlist.errorGeneric);
      }
    } catch {
      setStatus('error');
      setErrorMsg(t.waitlist.errorGeneric);
    }
  };

  return (
    <section id="waitlist" className="lp-section" style={{ ...lpStyles.section, background: '#0E2C42', color: '#fff' }}>
      <div style={{ ...lpStyles.container, maxWidth: 880, textAlign: 'center' }}>
        <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '6px 14px', borderRadius: 999, background: 'rgba(230,126,34,.18)', color: '#F4B27A', fontSize: 13, fontWeight: 700, marginBottom: 24 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#E67E22' }}/>{t.waitlist.badge}
        </div>
        <h2 style={{ fontSize: 'clamp(28px,4vw,44px)', fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 1.1, margin: '0 0 16px' }}>
          {status === 'ok' ? t.waitlist.successTitle : t.waitlist.title}
        </h2>
        <p style={{ fontSize: 18, lineHeight: 1.5, color: 'rgba(255,255,255,.8)', margin: '0 auto 32px', maxWidth: 560 }}>
          {status === 'ok'
            ? t.waitlist.successBody
            : (<>{t.waitlist.bodyA}<strong style={{ color: '#fff' }}>{bodyB}</strong>{bodyC}</>)}
        </p>

        {status !== 'ok' && (
          <>
            <form className="lp-waitlist-form" onSubmit={submit} style={{ display: 'flex', gap: 8, maxWidth: 480, margin: '0 auto' }}>
              <input
                type="email"
                required
                value={email}
                onChange={e => setEmail(e.target.value)}
                placeholder={t.waitlist.placeholder}
                disabled={status === 'sending'}
                style={{ flex: 1, padding: '14px 18px', borderRadius: 12, border: '1px solid rgba(255,255,255,.2)', background: 'rgba(255,255,255,.08)', color: '#fff', fontSize: 15, fontFamily: 'inherit', minWidth: 0 }}
              />
              <button
                type="submit"
                disabled={status === 'sending'}
                style={{ padding: '14px 22px', borderRadius: 12, background: '#E67E22', color: '#fff', border: 0, fontWeight: 700, fontSize: 15, fontFamily: 'inherit', cursor: status === 'sending' ? 'wait' : 'pointer', whiteSpace: 'nowrap', opacity: status === 'sending' ? .7 : 1 }}
              >{status === 'sending' ? t.waitlist.ctaSending : t.waitlist.cta}</button>
            </form>
            {status === 'error' && (
              <p style={{ fontSize: 14, color: '#F4B27A', marginTop: 14 }}>{errorMsg}</p>
            )}
            <p style={{ fontSize: 13, color: 'rgba(255,255,255,.55)', marginTop: 16 }}>{t.waitlist.reassure}</p>
          </>
        )}

        {status === 'ok' && (
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10, padding: '12px 20px', borderRadius: 999, background: 'rgba(39,174,96,.15)', color: '#86E1AB', fontSize: 14, fontWeight: 700 }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
            {t.waitlist.successBody}
          </div>
        )}
      </div>
    </section>
  );
}

function Problem() {
  const { t } = useT();
  return (
    <section className="lp-section" style={{ ...lpStyles.section, background: '#fff' }}>
      <div style={{ ...lpStyles.container, maxWidth: 780 }}>
        <div style={lpStyles.eyebrow}>{t.problem.eyebrow}</div>
        <h2 style={lpStyles.h2}>{t.problem.title}</h2>
        <p style={{ fontSize: 19, lineHeight: 1.6, color: '#5D6D7E', margin: '16px 0 0' }}>{t.problem.body}</p>
      </div>
    </section>
  );
}

function HowItWorks() {
  const { t } = useT();
  return (
    <section id="how" className="lp-section" style={{ ...lpStyles.section, background: '#F2F6FA' }}>
      <div style={lpStyles.container}>
        <div style={{ maxWidth: 680, marginBottom: 48 }}>
          <div style={lpStyles.eyebrow}>{t.how.eyebrow}</div>
          <h2 style={lpStyles.h2}>{t.how.title}</h2>
        </div>
        <div className="lp-grid-4" style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 20 }}>
          {t.how.steps.map(s => (
            <div key={s.n} style={{ background: '#fff', padding: 24, borderRadius: 16, border: '1px solid #E5E7EB' }}>
              <div style={{ fontFamily: 'ui-monospace,Menlo,monospace', fontSize: 12, color: '#1B4F72', fontWeight: 700, marginBottom: 12 }}>{s.n}</div>
              <div style={{ fontWeight: 700, fontSize: 18, color: '#1C2833', marginBottom: 8, letterSpacing: '-0.01em' }}>{s.t}</div>
              <div style={{ fontSize: 14, color: '#5D6D7E', lineHeight: 1.5 }}>{s.d}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Features() {
  const { t } = useT();
  return (
    <section id="funktionen" className="lp-section" style={{ ...lpStyles.section, background: '#fff' }}>
      <div style={lpStyles.container}>
        <div style={{ maxWidth: 680, marginBottom: 48 }}>
          <div style={lpStyles.eyebrow}>{t.features.eyebrow}</div>
          <h2 style={lpStyles.h2}>{t.features.title}</h2>
        </div>
        <div className="lp-grid-3" style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 20 }}>
          {t.features.items.map((it, i) => (
            <div key={i} style={{ padding: 24, borderRadius: 16, border: '1px solid #E5E7EB', background: '#fff' }}>
              <div style={{ fontWeight: 700, fontSize: 17, color: '#1C2833', marginBottom: 8, letterSpacing: '-0.01em' }}>{it.t}</div>
              <div style={{ fontSize: 14, color: '#5D6D7E', lineHeight: 1.55 }}>{it.d}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Authorities() {
  const { t } = useT();
  return (
    <section className="lp-section" style={{ ...lpStyles.section, background: '#F2F6FA' }}>
      <div style={lpStyles.container}>
        <div style={{ maxWidth: 680, marginBottom: 32 }}>
          <div style={lpStyles.eyebrow}>{t.authorities.eyebrow}</div>
          <h2 style={lpStyles.h2}>{t.authorities.title}</h2>
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
          {t.authorities.list.map(n => (
            <span key={n} style={{ padding: '12px 18px', background: '#fff', border: '1px solid #E5E7EB', borderRadius: 999, fontSize: 14, fontWeight: 600, color: '#1C2833' }}>{n}</span>
          ))}
        </div>
      </div>
    </section>
  );
}

function Privacy() {
  const { t } = useT();
  return (
    <section id="sicherheit" className="lp-section" style={{ ...lpStyles.section, background: '#1B4F72', color: '#fff' }}>
      <div style={lpStyles.container}>
        <div className="lp-grid-privacy" style={{ display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 64, alignItems: 'center' }}>
          <div>
            <div style={{ ...lpStyles.eyebrow, color: '#A9C8DF' }}>{t.privacy.eyebrow}</div>
            <h2 style={{ ...lpStyles.h2, color: '#fff' }}>{t.privacy.title}</h2>
            <p style={{ fontSize: 18, lineHeight: 1.6, color: 'rgba(255,255,255,.78)', margin: '16px 0 0' }}>{t.privacy.body}</p>
          </div>
          <div className="lp-grid-privacy-cards" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
            {t.privacy.items.map(([title, desc]) => (
              <div key={title} style={{ background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.12)', borderRadius: 12, padding: 18 }}>
                <div style={{ fontWeight: 700, fontSize: 15, color: '#fff', marginBottom: 6 }}>{title}</div>
                <div style={{ fontSize: 13, color: 'rgba(255,255,255,.7)', lineHeight: 1.5 }}>{desc}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

function Pricing() {
  const { t } = useT();
  const f = t.pricing.free;
  const p = t.pricing.premium;

  // While the free phase runs it REPLACES the Early Bird badge and note rather
  // than sitting alongside them. "Free for everyone until X" already contains
  // "3-6 months free for people on the waitlist", so showing both on one card
  // reads as two competing offers. Both strings stay in STRINGS untouched and
  // come back on their own the day the promo lapses.
  const promo = promoIsActive();
  const badge = promo ? p.promoBadge : p.earlyBird;
  const note = promo ? fill(p.promoNote, { price: p.price }) : p.earlyBirdNote;

  // Every quoted limit comes from PROMO, so the card can never drift from the
  // numbers at the top of this file.
  const freeItems = f.items.map((it) => fill(it, PROMO_VARS));
  // items[0] is "unlimited scans & deadlines", which is true of PAID premium
  // and NOT of the free phase — that one is metered. Swap just that line while
  // the promo runs; the rest of the feature list is identical either way.
  const premiumItems = promo
    ? [fill(p.promoFirstItem, PROMO_VARS), ...p.items.slice(1)]
    : p.items;
  return (
    <section id="preise" className="lp-section" style={{ ...lpStyles.section, background: '#fff' }}>
      <div style={lpStyles.container}>
        <div style={{ maxWidth: 680, marginBottom: 48 }}>
          <div style={lpStyles.eyebrow}>{t.pricing.eyebrow}</div>
          <h2 style={lpStyles.h2}>{t.pricing.title}</h2>
        </div>
        <div className="lp-grid-2 lp-pricing-grid" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24, maxWidth: 920 }}>
          <div className="lp-pricing-card" style={{ padding: 32, borderRadius: 20, border: '1px solid #E5E7EB', background: '#fff' }}>
            <div style={{ fontWeight: 700, fontSize: 22, color: '#1C2833', marginBottom: 4, letterSpacing: '-0.01em' }}>{f.name}</div>
            <div style={{ fontSize: 14, color: '#5D6D7E', marginBottom: 24 }}>{f.desc}</div>
            <div style={{ fontSize: 40, fontWeight: 700, color: '#1C2833', letterSpacing: '-0.02em', marginBottom: 24 }}>{f.price}</div>
            <ul style={lpStyles.ul}>
              {freeItems.map((it, i) => <li key={i}>{it}</li>)}
            </ul>
          </div>
          <div className="lp-pricing-card lp-pricing-premium" style={{ padding: 32, borderRadius: 20, border: '2px solid #1B4F72', background: '#F7FAFD', position: 'relative' }}>
            <div style={{ position: 'absolute', top: -12, right: 24, padding: '5px 12px', background: '#E67E22', color: '#fff', fontWeight: 700, fontSize: 12, borderRadius: 999, letterSpacing: '.02em' }}>{badge}</div>
            <div style={{ fontWeight: 700, fontSize: 22, color: '#1B4F72', marginBottom: 4, letterSpacing: '-0.01em' }}>{p.name}</div>
            <div style={{ fontSize: 14, color: '#5D6D7E', marginBottom: 24 }}>{p.desc}</div>
            <div style={{ fontSize: 40, fontWeight: 700, color: '#1C2833', letterSpacing: '-0.02em', marginBottom: 4 }}>
              {promo && <s style={{ fontSize: 26, fontWeight: 600, color: '#8A97A4', textDecorationThickness: 2, marginRight: 10 }}>{p.price}</s>}
              {promo ? p.promoPrice : p.price} <span style={{ fontSize: 16, fontWeight: 500, color: '#5D6D7E' }}>{p.perMonth}</span>
            </div>
            <div style={{ fontSize: 13, color: '#E67E22', fontWeight: 600, marginBottom: 24 }}>{note}</div>
            <ul style={lpStyles.ul}>
              {premiumItems.map((it, i) => <li key={i}>{it}</li>)}
            </ul>
          </div>
        </div>
      </div>
    </section>
  );
}

function FAQ() {
  const { t } = useT();
  const promo = promoIsActive();
  return (
    <section id="faq" className="lp-section" style={{ ...lpStyles.section, background: '#F2F6FA' }}>
      <div style={{ ...lpStyles.container, maxWidth: 780 }}>
        <div style={{ marginBottom: 32 }}>
          <div style={lpStyles.eyebrow}>{t.faq.eyebrow}</div>
          <h2 style={lpStyles.h2}>{t.faq.title}</h2>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          {t.faq.qa.map(([q, a, promoA], i) => (
            <details key={i} style={{ borderTop: '1px solid #D6DEE7', padding: '20px 0' }}>
              <summary style={{ fontWeight: 700, fontSize: 17, color: '#1C2833', cursor: 'pointer', listStyle: 'none', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16 }}>
                {q}<span style={{ fontSize: 20, color: '#1B4F72', fontWeight: 400, flexShrink: 0 }}>+</span>
              </summary>
              <p style={{ fontSize: 15, color: '#5D6D7E', lineHeight: 1.6, margin: '12px 0 0' }}>{promo && promoA ? fill(promoA, PROMO_VARS) : a}</p>
            </details>
          ))}
        </div>
      </div>
    </section>
  );
}

function Footer() {
  const { t } = useT();
  return (
    <footer style={{ background: '#0E2C42', color: 'rgba(255,255,255,.7)', padding: '48px 24px 32px' }}>
      <div className="lp-grid-footer" style={{ ...lpStyles.container, display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 1fr', gap: 32, marginBottom: 32 }}>
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
            <div style={{ width: 28, height: 28, borderRadius: '22%', background: '#fff', color: '#0F1115', fontWeight: 800, fontSize: 14, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>F</div>
            <span style={{ fontWeight: 700, fontSize: 16, color: '#fff' }}>FristRadar</span>
          </div>
          <p style={{ fontSize: 13, lineHeight: 1.55, maxWidth: 320 }}>{t.footer.tagline}</p>
        </div>
        <FCol h={t.footer.colProduct} links={t.footer.productLinks}/>
        <FCol h={t.footer.colLegal} links={t.footer.legalLinks}/>
        <FCol h={t.footer.colContact} links={t.footer.contactLinks}/>
      </div>
      <div className="lp-footer-bottom" style={{ ...lpStyles.container, display: 'flex', justifyContent: 'center', alignItems: 'center', paddingTop: 24, borderTop: '1px solid rgba(255,255,255,.1)', fontSize: 12 }}>
        <span>{t.footer.copyright}</span>
      </div>
    </footer>
  );
}

function FCol({ h, links }) {
  return (
    <div>
      <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: '#fff', marginBottom: 14 }}>{h}</div>
      <ul className="lp-footer-list" style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8, fontSize: 13 }}>
        {links.map(([label, href]) => {
          const external = /^https?:/.test(href);
          return (
            <li key={label}>
              <a
                href={href}
                {...(external ? { target: '_blank', rel: 'noopener noreferrer' } : {})}
                style={{ color: 'rgba(255,255,255,.7)', textDecoration: 'none' }}
              >{label}</a>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

const lpStyles = {
  nav: { position: 'sticky', top: 0, zIndex: 10, display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '16px 32px', background: 'rgba(235,240,245,.85)', backdropFilter: 'saturate(180%) blur(12px)', borderBottom: '1px solid rgba(28,40,51,.06)' },
  navLink: { fontSize: 14, color: '#1C2833', textDecoration: 'none', fontWeight: 500 },
  section: { padding: '80px 32px' },
  container: { maxWidth: 1200, margin: '0 auto' },
  eyebrow: { fontSize: 12, fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: '#1B4F72', marginBottom: 14 },
  h2: { fontSize: 'clamp(26px,3.5vw,42px)', fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 1.1, color: '#1C2833', margin: 0 },
  btnPrimary: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', padding: '14px 22px', borderRadius: 14, background: '#1B4F72', color: '#fff', textDecoration: 'none', fontWeight: 700, fontSize: 15 },
  btnGhost: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', padding: '14px 22px', borderRadius: 14, background: 'transparent', color: '#1C2833', textDecoration: 'none', fontWeight: 700, fontSize: 15, border: '1px solid #C5D0DB' },
  ul: { listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 10, fontSize: 14, color: '#1C2833' },
};

// ============================================================
// Global styles: pricing checkmarks + responsive media queries
// ============================================================

const _globalStyle = document.createElement('style');
_globalStyle.textContent = `
  .lp-pricing-card ul li::before {
    content: "✓";
    color: #27AE60;
    font-weight: 700;
    margin-right: 10px;
  }
  .lp-footer-list li::before { content: none; }

  /* Tablet */
  @media (max-width: 960px) {
    .lp-nav { padding: 12px 20px !important; }
    .lp-nav-links { gap: 16px !important; }
    .lp-nav-text { display: none !important; }
    .lp-section { padding: 56px 20px !important; }
    .lp-grid-hero { grid-template-columns: 1fr !important; gap: 40px !important; }
    .lp-grid-4 { grid-template-columns: repeat(2,1fr) !important; }
    .lp-grid-3 { grid-template-columns: repeat(2,1fr) !important; }
    .lp-grid-2, .lp-pricing-grid { grid-template-columns: 1fr !important; }
    .lp-grid-privacy { grid-template-columns: 1fr !important; gap: 32px !important; }
    .lp-hero-visual { height: auto !important; padding: 0 !important; min-height: 480px; }
    .lp-hero-letter { display: none !important; }
    .lp-hero-phone { margin-left: 0 !important; margin-top: 0 !important; }
    .lp-grid-footer { grid-template-columns: 1fr 1fr !important; gap: 28px !important; }
    .lp-footer-bottom { flex-direction: column !important; gap: 12px !important; text-align: center; }
  }

  /* Phone */
  @media (max-width: 600px) {
    .lp-nav { padding: 10px 16px !important; }
    .lp-nav-links { gap: 8px !important; }
    .lp-section { padding: 40px 16px !important; }
    .lp-grid-4, .lp-grid-3 { grid-template-columns: 1fr !important; }
    .lp-grid-privacy-cards { grid-template-columns: 1fr !important; }
    .lp-hero-cta { flex-direction: column !important; align-items: stretch !important; }
    .lp-hero-cta a { justify-content: center !important; }
    .lp-hero-stores { gap: 10px !important; }
    .lp-waitlist-form { flex-direction: column !important; }
    .lp-grid-footer { grid-template-columns: 1fr !important; gap: 24px !important; }
    .lp-pricing-premium > div:first-child {
      right: 16px !important; font-size: 11px !important; padding: 4px 10px !important;
    }
  }
`;
document.head.appendChild(_globalStyle);

Object.assign(window, { I18nProvider, Nav, Hero, Waitlist, Problem, HowItWorks, Features, Authorities, Privacy, Pricing, FAQ, Footer });
