/* global React, Reveal */
const { useState: useStateS, useEffect: useEffectS, useRef: useRefS, useMemo: useMemoS } = React;

// ============================================================
// Problem — "Tu connais ces moments ?"
// ============================================================
function Problem({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Le constat",
    title: "Tu connais ces moments ?",
    sub: "Ces situations répétitives que toutes les apps de finance promettent de résoudre — sans jamais vraiment y arriver.",
    items: [
      { n: "01", t: "Tu finis le mois sans savoir où est passé ton argent.", d: "Tu regardes ton relevé, tu ne reconnais pas la moitié. Où sont passés ces 300€ ?" },
      { n: "02", t: "Ton objectif d'épargne te paraît loin, abstrait.", d: "Tu sais ce que tu veux, mais tu ne sais jamais où tu en es exactement. Dans 3 ans ? Jamais ?" },
      { n: "03", t: "Tu doutes de pouvoir vraiment y arriver.", d: "Tu fais des efforts, mais rien ne te montre si ça paye. Alors tu lâches. Tu recommences. Tu lâches." },
      { n: "04", t: "Les apps que tu as testées te culpabilisent.", d: "Elles listent tes dépenses avec des emojis tristes. Elles ne t'aident pas à construire — elles te jugent." },
    ],
  } : {
    eyebrow: "The reality",
    title: "Sound familiar?",
    sub: "Recurring situations every finance app promises to fix — without ever really delivering.",
    items: [
      { n: "01", t: "You end the month with no idea where your money went.", d: "You stare at your statement, half of it doesn't ring a bell. Where did that €300 go?" },
      { n: "02", t: "Your savings goal feels distant, abstract.", d: "You know what you want, but you never know exactly where you stand. 3 years? Never?" },
      { n: "03", t: "You doubt you can actually make it.", d: "You try. Nothing shows it's working. So you quit. You restart. You quit again." },
      { n: "04", t: "The apps you tried just make you feel guilty.", d: "They list expenses with sad emojis. They don't help you build — they judge you." },
    ],
  };

  return (
    <section className="problem" id="problem">
      <div className="problem-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--warn">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>
        <div className="problem-grid">
          {t.items.map((item, i) => (
            <Reveal key={i} delay={i * 80} className="problem-card">
              <div className="problem-n">{item.n}</div>
              <div className="problem-t">{item.t}</div>
              <div className="problem-d">{item.d}</div>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Promise — "TargetSaver, c'est l'inverse"
// ============================================================
function PromiseSection({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Notre promesse",
    title: "TargetSaver, c'est l'inverse.",
    sub: "Une app qui te regarde construire, pas une app qui te regarde dépenser.",
    items: [
      { t: "Tu vois exactement où tu vas.", d: "Projection jour par jour, mois par mois, basée sur ta vraie vie." },
      { t: "Tu sais quand tu y arrives.", d: "Date estimée pour chaque objectif — réactualisée automatiquement." },
      { t: "Tu es récompensé pour chaque victoire.", d: "Les jours sans dépense, les étapes franchies, les libérations débloquées." },
      { t: "Tes données restent à toi.", d: "Chiffrement local AES-256. Sync optionnelle via serveur RGPD UE. Pas de revente. Jamais." },
    ],
  } : {
    eyebrow: "Our promise",
    title: "TargetSaver is the opposite.",
    sub: "An app that watches you build, not one that watches you spend.",
    items: [
      { t: "You see exactly where you're headed.", d: "Day-by-day, month-by-month projection based on your real life." },
      { t: "You know when you'll get there.", d: "Estimated date for every goal — auto-updated with every entry." },
      { t: "You get rewarded for every win.", d: "Spendless days, milestones hit, credit releases unlocked." },
      { t: "Your data stays yours.", d: "AES-256 local encryption. Optional sync via GDPR EU server. No reselling. Ever." },
    ],
  };

  return (
    <section className="promise section--alt" id="promise">
      <div className="promise-inner">
        <div className="section-head">
          <Reveal className="eyebrow">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>
        <div className="promise-grid">
          {t.items.map((item, i) => (
            <Reveal key={i} delay={i * 80} className="promise-card">
              <div className="promise-check">
                <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                  <polyline points="20 6 9 17 4 12" />
                </svg>
              </div>
              <div className="promise-t">{item.t}</div>
              <div className="promise-d">{item.d}</div>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Pillars — 4 piliers qui nous rendent différents
// ============================================================
function Pillars({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Ce qui nous rend différents",
    title: "Quatre piliers. Zéro compromis.",
    sub: "Les choses que nous faisons que personne d'autre ne fait vraiment.",
    items: [
      {
        k: "①",
        t: "Tes données. Sous ton contrôle.",
        d: "Saisie manuelle, pas de connexion bancaire. Stockage chiffré AES-256 sur ton iPhone. Sync optionnelle via serveur RGPD en Union Européenne. Export et suppression complète en 1 tap.",
        tag: "Local-first · RGPD",
      },
      {
        k: "②",
        t: "La vraie projection. Pas une moyenne.",
        d: "Les autres apps calculent ton épargne sur une moyenne des 3 derniers mois. Nous intégrons tes crédits qui se terminent, tes revenus variables, tes objectifs réels.",
        tag: "Algorithme propriétaire",
      },
      {
        k: "③",
        t: "Les jours en or.",
        d: "Chaque jour où tu ne dépenses rien est valorisé. Compté. Célébré. C'est ce qui transforme une discipline en habitude — et une habitude en liberté.",
        tag: "Psychologie positive",
      },
      {
        k: "④",
        t: "Voice & Widgets, natifs iOS.",
        d: "14 commandes Siri. 6 widgets. Apple Watch. Shortcuts. Nous respectons la plateforme — pas de web view bricolée.",
        tag: "iOS 18+",
      },
    ],
  } : {
    eyebrow: "What makes us different",
    title: "Four pillars. Zero compromise.",
    sub: "Things we do that nobody else actually does.",
    items: [
      { k: "①", t: "Your data. Under your control.", d: "Manual entry, no bank connection. AES-256 encrypted storage on your iPhone. Optional sync via GDPR-compliant EU server. Export and full deletion in one tap.", tag: "Local-first · GDPR" },
      { k: "②", t: "Real projection. Not an average.", d: "Other apps compute savings from a 3-month average. We factor in credits ending, variable income, and your actual goals.", tag: "Proprietary algorithm" },
      { k: "③", t: "Golden days.", d: "Every day you don't spend is counted. Celebrated. That's what turns discipline into habit — and habit into freedom.", tag: "Positive psychology" },
      { k: "④", t: "Voice & Widgets, native iOS.", d: "14 Siri commands. 6 widgets. Apple Watch. Shortcuts. We respect the platform — no hacky web view.", tag: "iOS 18+" },
    ],
  };

  return (
    <section className="pillars" id="pillars">
      <div className="pillars-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--primary">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>
        <div className="pillars-grid">
          {t.items.map((item, i) => (
            <Reveal key={i} delay={i * 60} className="pillar-card">
              <div className="pillar-k">{item.k}</div>
              <div className="pillar-tag">{item.tag}</div>
              <div className="pillar-t">{item.t}</div>
              <div className="pillar-d">{item.d}</div>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Story — Notre histoire personnelle
// ============================================================
function Story({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Notre histoire",
    title: "Au début, il y avait un budget serré et un objectif énorme.",
    paragraphs: [
      "Étudiant, j'avais peu. Mais j'avais une idée précise de ce que je voulais : devenir indépendant. Monter ma propre boîte. Ne plus avoir à demander.",
      "Pour y arriver, je devais faire une seule chose : transformer chaque euro en pas vers ce rêve.",
      "J'ai testé toutes les apps de finance qui existent. Excel, carnets, Bankin', Linxo, Plum, vingt autres. Toutes m'apprenaient une chose que je savais déjà : où passait mon argent.",
      "Aucune ne répondait à la vraie question : est-ce que je me rapproche, oui ou non, de ce que je veux vraiment ?",
      "Alors je me suis construit ma propre méthode.",
    ],
    pull: "Aucune app ne répondait à la vraie question : est-ce que je me rapproche, oui ou non, de ce que je veux vraiment ?",
    concepts: {
      label: "Des concepts qui n'existaient nulle part",
      items: [
        { t: "Les jours sans dépense", d: "Ces jours où tu ne touches pas à ton budget — et qui valent de l'or quand tu les mets bout à bout." },
        { t: "La projection optimisée", d: "Mois par mois, en intégrant tes engagements qui se terminent — ce que tu auras vraiment." },
        { t: "La séparation 4-catégories", d: "Engagements / objectifs / vie courante / disponible — pour savoir ce que tu peux dépenser sans te mentir." },
      ],
    },
    end: [
      "J'ai vécu deux ans sur ces principes. Pendant que les autres dépensaient leur premier salaire, j'épargnais. Pendant qu'ils consommaient, je construisais.",
      "Quelques années plus tard, j'avais de quoi lancer ma boîte. Pas grâce à un héritage. Pas grâce à un investisseur. Grâce à une discipline financière que je m'étais forgée à 22 ans avec très peu.",
      "Mes proches ont commencé à me demander ma méthode. À chaque fois, le même retour :",
    ],
    quote: "Je n'avais jamais vu mon argent comme ça. C'est la première fois que je sens que je le contrôle, pas l'inverse.",
    final: "TargetSaver, c'est tout ça, codé dans une app.",
    signoff: "Si je l'ai fait avec rien, tu peux le faire avec ce que tu as.",
    signature: "Le fondateur",
    date: "Projet démarré en août 2024",
  } : {
    eyebrow: "Our story",
    title: "At the start, there was a tight budget and a huge goal.",
    paragraphs: [
      "As a student, I had little. But I knew exactly what I wanted: to be independent. To build my own company. Never to have to ask.",
      "To get there, I had to do one thing: turn every euro into a step toward that dream.",
      "I tried every finance app out there. Excel, notebooks, Bankin', Linxo, Plum, twenty others. They all taught me something I already knew: where my money went.",
      "None answered the real question: am I getting closer, yes or no, to what I actually want?",
      "So I built my own method.",
    ],
    pull: "No app answered the real question: am I getting closer to what I actually want?",
    concepts: {
      label: "Concepts that existed nowhere",
      items: [
        { t: "Spendless days", d: "Days where you don't touch your budget — they're gold when you line them up." },
        { t: "Optimized projection", d: "Month by month, factoring in commitments ending — what you'll actually have." },
        { t: "4-category split", d: "Commitments / goals / daily life / available — to know what you can spend without lying to yourself." },
      ],
    },
    end: [
      "I lived two years on these principles. While others spent their first salary, I saved. While they consumed, I built.",
      "A few years later, I had what I needed to launch my company. Not thanks to an inheritance. Not thanks to an investor. Thanks to the financial discipline I forged at 22 with very little.",
      "People close to me started asking for my method. Every single time, the same feedback:",
    ],
    quote: "I had never seen my money like that. It's the first time I feel I'm in control, not the other way around.",
    final: "TargetSaver is all of that, coded into an app.",
    signoff: "If I did it with nothing, you can do it with what you have.",
    signature: "The founder",
    date: "Started August 2024",
  };

  return (
    <section className="story" id="story">
      <div className="story-inner">
        <div className="section-head">
          <Reveal className="eyebrow">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="story-title">{t.title}</Reveal>
        </div>

        <div className="story-body">
          {t.paragraphs.map((p, i) => (
            <WordReveal key={i} delay={i * 40} as="p" className="story-p">{p}</WordReveal>
          ))}

          <Reveal delay={120} className="story-pull">
            <div className="pull-quote-mark">"</div>
            <div className="pull-text">{t.pull}</div>
          </Reveal>

          <Reveal className="story-concepts">
            <div className="concepts-label">{t.concepts.label}</div>
            <div className="concepts-list">
              {t.concepts.items.map((c, i) => (
                <Reveal key={i} delay={i * 80} className="concept-row">
                  <div className="concept-idx">{String(i + 1).padStart(2, "0")}</div>
                  <div>
                    <div className="concept-t">{c.t}</div>
                    <div className="concept-d">{c.d}</div>
                  </div>
                </Reveal>
              ))}
            </div>
          </Reveal>

          {t.end.map((p, i) => (
            <WordReveal key={`e${i}`} delay={i * 40} as="p" className="story-p">{p}</WordReveal>
          ))}

          <Reveal className="story-testimonial">
            <div className="test-mark">"</div>
            <div className="test-text">{t.quote}</div>
          </Reveal>

          <WordReveal as="p" className="story-final">{t.final}</WordReveal>

          <Reveal className="story-signoff">
            <div className="signoff-text">« {t.signoff} »</div>
            <div className="signoff-block">
              <div className="signoff-avatar">
                <svg viewBox="0 0 40 40" width="40" height="40">
                  <circle cx="20" cy="20" r="20" fill="currentColor" opacity="0.12" />
                  <circle cx="20" cy="16" r="6" fill="currentColor" opacity="0.55" />
                  <path d="M8 36c0-6 5.5-10 12-10s12 4 12 10" fill="currentColor" opacity="0.55" />
                </svg>
              </div>
              <div>
                <div className="signoff-name">{t.signature}</div>
                <div className="signoff-date">{t.date}</div>
              </div>
            </div>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Quiz — Quel est ton rêve ?
// ============================================================
function Quiz({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Ton projet",
    title: "Quel est ton rêve ?",
    sub: "Choisis celui qui te ressemble. On te montre comment TargetSaver peut t'y mener.",
    options: [
      { k: "business", emoji: "◆", label: "Lancer ma boîte", feature: "Projection long-terme + mode fondateur", amount: "30 000 €", months: 36 },
      { k: "freedom", emoji: "◇", label: "Acheter ma liberté financière", feature: "Objectifs multi-étapes + trajectoire", amount: "100 000 €", months: 60 },
      { k: "travel", emoji: "✦", label: "Voyager longtemps", feature: "Budget voyage + jours sans dépense", amount: "15 000 €", months: 18 },
      { k: "quit", emoji: "◈", label: "Sortir du salariat", feature: "Coussin de sécurité + revenus passifs", amount: "25 000 €", months: 24 },
      { k: "real", emoji: "◉", label: "Acheter un bien immobilier", feature: "Apport + simulation crédit", amount: "50 000 €", months: 48 },
      { k: "change", emoji: "◎", label: "Quitter une situation qui m'use", feature: "Épargne d'urgence + plan de sortie", amount: "10 000 €", months: 12 },
      { k: "other", emoji: "✧", label: "Autre projet", feature: "Objectifs personnalisés illimités", amount: "20 000 €", months: 24 },
    ],
    result: "Pour atteindre ce rêve",
    resultSub: "TargetSaver te montrerait exactement :",
    tips: [
      { t: "Ton montant cible", get: o => o.amount },
      { t: "Ta durée estimée", get: o => `${o.months} mois` },
      { t: "L'outil clé pour toi", get: o => o.feature },
    ],
    cta: "Commencer avec ce rêve",
    pickPrompt: "👆 Choisis ton rêve",
  } : {
    eyebrow: "Your project",
    title: "What's your dream?",
    sub: "Pick the one that fits. We'll show you how TargetSaver gets you there.",
    options: [
      { k: "business", emoji: "◆", label: "Start my company", feature: "Long-term projection + founder mode", amount: "€30,000", months: 36 },
      { k: "freedom", emoji: "◇", label: "Buy my financial freedom", feature: "Multi-step goals + trajectory", amount: "€100,000", months: 60 },
      { k: "travel", emoji: "✦", label: "Travel long-term", feature: "Travel budget + spendless days", amount: "€15,000", months: 18 },
      { k: "quit", emoji: "◈", label: "Leave salary work", feature: "Safety cushion + passive income", amount: "€25,000", months: 24 },
      { k: "real", emoji: "◉", label: "Buy property", feature: "Down payment + credit sim", amount: "€50,000", months: 48 },
      { k: "change", emoji: "◎", label: "Exit a draining situation", feature: "Emergency fund + exit plan", amount: "€10,000", months: 12 },
      { k: "other", emoji: "✧", label: "Another project", feature: "Unlimited custom goals", amount: "€20,000", months: 24 },
    ],
    result: "To reach this dream",
    resultSub: "TargetSaver would show you exactly:",
    tips: [
      { t: "Your target amount", get: o => o.amount },
      { t: "Your estimated duration", get: o => `${o.months} months` },
      { t: "The key tool for you", get: o => o.feature },
    ],
    cta: "Start with this dream",
    pickPrompt: "👆 Pick your dream",
  };

  const [selected, setSelected] = useStateS(null);
  const chosen = t.options.find(o => o.k === selected);

  return (
    <section className="quiz section--alt" id="quiz">
      <div className="quiz-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--primary">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>

        <div className="quiz-layout">
          <div className="quiz-options">
            {t.options.map((o, i) => (
              <Reveal key={o.k} delay={i * 40}>
                <button
                  className={`quiz-opt ${selected === o.k ? "active" : ""}`}
                  onClick={() => setSelected(o.k)}
                >
                  <span className="quiz-opt-em">{o.emoji}</span>
                  <span className="quiz-opt-l">{o.label}</span>
                  <span className="quiz-opt-arrow">→</span>
                </button>
              </Reveal>
            ))}
          </div>

          <Reveal delay={120} className={`quiz-result ${chosen ? "has" : ""}`}>
            {!chosen && (
              <div className="quiz-empty">
                <div className="quiz-empty-mark">?</div>
                <div className="quiz-empty-t">{t.pickPrompt}</div>
              </div>
            )}
            {chosen && (
              <div className="quiz-card">
                <div className="qc-head">
                  <div className="qc-em">{chosen.emoji}</div>
                  <div>
                    <div className="qc-eye">{t.result}</div>
                    <div className="qc-lbl">{chosen.label}</div>
                  </div>
                </div>
                <div className="qc-sub">{t.resultSub}</div>
                <div className="qc-tips">
                  {t.tips.map((tip, i) => (
                    <div key={i} className="qc-tip">
                      <div className="qct-l">{tip.t}</div>
                      <div className="qct-v">{tip.get(chosen)}</div>
                    </div>
                  ))}
                </div>
                <button
                  type="button"
                  className="btn btn-primary qc-cta"
                  data-magnetic
                  onClick={() => {
                    // Send the chosen dream's amount + months to the Calculator
                    const numericAmount = typeof chosen.amount === "string"
                      ? parseInt(chosen.amount.replace(/[^\d]/g, ""), 10)
                      : chosen.amount;
                    window.dispatchEvent(new CustomEvent("ts:applyDream", {
                      detail: { amount: numericAmount, months: chosen.months, label: chosen.label }
                    }));
                    // Smooth-scroll to the calculator
                    const calc = document.getElementById("calc");
                    if (calc) {
                      const top = calc.getBoundingClientRect().top + window.scrollY - 60;
                      window.scrollTo({ top, behavior: "smooth" });
                    }
                  }}
                >
                  {t.cta}
                  <span className="arrow">→</span>
                </button>
              </div>
            )}
          </Reveal>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Calculator — Ton rêve en chiffres
// ============================================================
function Calculator({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Ton rêve en chiffres",
    title: "Combien. Pendant combien de temps.",
    sub: "Règle le montant et la durée. On te montre ce que ton épargne devient avec TargetSaver — vs une app classique.",
    amountLabel: "Montant cible",
    monthsLabel: "Durée",
    monthsUnit: "mois",
    current: "Épargne actuelle",
    classical: "Avec une app classique",
    withUs: "Avec TargetSaver",
    gain: "Gain",
    gainExpl: "grâce aux libérations de crédits détectées et aux jours sans dépense valorisés",
    monthly: "Épargne mensuelle requise",
    reach: "Objectif atteint en",
    cta: "Télécharger l'app",
  } : {
    eyebrow: "Your dream in numbers",
    title: "How much. How long.",
    sub: "Set the amount and the duration. See what your savings become with TargetSaver — vs a classic app.",
    amountLabel: "Target amount",
    monthsLabel: "Duration",
    monthsUnit: "months",
    current: "Current savings",
    classical: "With a classic app",
    withUs: "With TargetSaver",
    gain: "Gain",
    gainExpl: "thanks to detected credit releases and valued spendless days",
    monthly: "Required monthly saving",
    reach: "Goal reached in",
    cta: "Download app",
  };

  const [amount, setAmount] = useStateS(20000);
  const [months, setMonths] = useStateS(24);
  const [appliedLabel, setAppliedLabel] = useStateS(null);
  const [pulsing, setPulsing] = useStateS(false);
  const current = 1500;

  // Listen for "apply dream" events from the Quiz
  React.useEffect(() => {
    const onApply = (e) => {
      const { amount: a, months: m, label } = e.detail || {};
      if (typeof a === "number" && a > 0) {
        // Clamp to slider bounds
        setAmount(Math.max(5000, Math.min(200000, a)));
      }
      if (typeof m === "number" && m > 0) {
        setMonths(Math.max(6, Math.min(120, m)));
      }
      if (label) setAppliedLabel(label);
      // Trigger pulse animation
      setPulsing(true);
      setTimeout(() => setPulsing(false), 900);
    };
    window.addEventListener("ts:applyDream", onApply);
    return () => window.removeEventListener("ts:applyDream", onApply);
  }, []);

  // Simulation: TargetSaver adds +15% efficiency via releases + spendless days
  const classicalMonthly = Math.round((amount - current) / months);
  const tsEfficiency = 1.15;
  const tsMonthly = Math.round(classicalMonthly / tsEfficiency);
  const tsReach = Math.round((amount - current) / (classicalMonthly * tsEfficiency) * months / months * (months / tsEfficiency));
  const gainAmount = Math.round(classicalMonthly * months * (tsEfficiency - 1));

  // Build projection data points
  const points = useMemoS(() => {
    const pts = [];
    for (let m = 0; m <= months; m++) {
      const classical = current + classicalMonthly * m;
      const ts = current + classicalMonthly * tsEfficiency * m;
      pts.push({ m, classical, ts });
    }
    return pts;
  }, [amount, months]);

  const maxVal = amount * 1.15;
  const W = 600, H = 260, pad = 32;
  const xScale = (m) => pad + (m / months) * (W - pad * 2);
  const yScale = (v) => H - pad - (v / maxVal) * (H - pad * 2);

  const classicalPath = points.map((p, i) => `${i === 0 ? "M" : "L"} ${xScale(p.m)} ${yScale(p.classical)}`).join(" ");
  const tsPath = points.map((p, i) => `${i === 0 ? "M" : "L"} ${xScale(p.m)} ${yScale(p.ts)}`).join(" ");
  const tsAreaPath = `${tsPath} L ${xScale(months)} ${yScale(0)} L ${xScale(0)} ${yScale(0)} Z`;

  const fmt = (n) => new Intl.NumberFormat(lang === "fr" ? "fr-FR" : "en-US").format(Math.round(n));

  return (
    <section className="calc" id="calc">
      <div className="calc-inner">
        <div className="section-head">
          <Reveal className="eyebrow">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>

        <Reveal className={`calc-card ${pulsing ? "pulsing" : ""}`}>
          {appliedLabel && (
            <div className="calc-applied" key={appliedLabel}>
              <span className="calc-applied-mark">✦</span>
              <span className="calc-applied-l">{lang === "fr" ? "Calculé pour" : "Calculated for"}</span>
              <strong className="calc-applied-v">{appliedLabel}</strong>
              <button
                type="button"
                className="calc-applied-x"
                onClick={() => { setAppliedLabel(null); setAmount(20000); setMonths(24); }}
                aria-label={lang === "fr" ? "Réinitialiser" : "Reset"}
              >×</button>
            </div>
          )}
          <div className="calc-controls">
            <div className="calc-control">
              <div className="calc-ctrl-head">
                <div className="calc-ctrl-label">{t.amountLabel}</div>
                <div className="calc-ctrl-value">{fmt(amount)} €</div>
              </div>
              <input
                type="range" min="5000" max="200000" step="1000"
                value={amount}
                onChange={e => setAmount(+e.target.value)}
                className="calc-slider"
              />
              <div className="calc-ctrl-foot">
                <span>5 000 €</span>
                <span>200 000 €</span>
              </div>
            </div>

            <div className="calc-control">
              <div className="calc-ctrl-head">
                <div className="calc-ctrl-label">{t.monthsLabel}</div>
                <div className="calc-ctrl-value">{months} {t.monthsUnit}</div>
              </div>
              <input
                type="range" min="6" max="120" step="1"
                value={months}
                onChange={e => setMonths(+e.target.value)}
                className="calc-slider"
              />
              <div className="calc-ctrl-foot">
                <span>6 {t.monthsUnit}</span>
                <span>120 {t.monthsUnit}</span>
              </div>
            </div>
          </div>

          <div className="calc-viz">
            <svg viewBox={`0 0 ${W} ${H}`} className="calc-chart" preserveAspectRatio="xMidYMid meet">
              <defs>
                <linearGradient id="tsFill" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor="var(--primary)" stopOpacity="0.5" />
                  <stop offset="100%" stopColor="var(--primary)" stopOpacity="0" />
                </linearGradient>
              </defs>
              {/* grid */}
              {[0, 0.25, 0.5, 0.75, 1].map(p => (
                <line key={p} x1={pad} x2={W - pad} y1={pad + p * (H - pad * 2)} y2={pad + p * (H - pad * 2)} stroke="var(--border)" strokeDasharray="2 4" />
              ))}
              <path d={tsAreaPath} fill="url(#tsFill)" />
              <path d={classicalPath} fill="none" stroke="var(--fg-muted)" strokeWidth="2" strokeDasharray="4 5" />
              <path d={tsPath} fill="none" stroke="var(--primary)" strokeWidth="2.5" />
              {/* dots at end */}
              <circle cx={xScale(months)} cy={yScale(points[points.length - 1].classical)} r="4" fill="var(--fg-muted)" />
              <circle cx={xScale(months)} cy={yScale(points[points.length - 1].ts)} r="5" fill="var(--primary)" />
            </svg>
            <div className="calc-legend">
              <div className="legend-row"><span className="dot" style={{ background: "var(--fg-muted)" }} />{t.classical}</div>
              <div className="legend-row"><span className="dot" style={{ background: "var(--primary)" }} />{t.withUs}</div>
            </div>
          </div>

          <div className="calc-outputs">
            <div className="calc-out">
              <div className="calc-out-l">{t.monthly}</div>
              <div className="calc-out-v">{fmt(tsMonthly)} €<span className="unit">/{lang === "fr" ? "mois" : "mo"}</span></div>
              <div className="calc-out-s">vs {fmt(classicalMonthly)} € {lang === "fr" ? "classique" : "classic"}</div>
            </div>
            <div className="calc-out highlight">
              <div className="calc-out-l">{t.gain}</div>
              <div className="calc-out-v accent">+{fmt(gainAmount)} €</div>
              <div className="calc-out-s">{t.gainExpl}</div>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ============================================================
// Privacy First
// ============================================================
function Privacy({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Privacy first",
    title: "Privacy-first. RGPD-compliant. Sans bullshit.",
    sub: "Pas de connexion bancaire. Pas de revente. Pas de tracker. Stockage chiffré, sync optionnelle, export et suppression à la demande.",
    left: { t: "Chez nous", items: [
      "Saisie manuelle — pas de connexion bancaire",
      "Données chiffrées AES-256 sur ton iPhone",
      "Sync optionnelle, serveur RGPD en UE",
      "Aucun tracker tiers, aucune pub",
      "Export JSON et suppression totale en 1 tap",
      "Privacy Manifest Apple complet",
    ]},
    right: { t: "Chez les autres", items: [
      "Connexion bancaire obligatoire",
      "Données stockées en clair sur leurs serveurs",
      "Compte, email, mot de passe",
      "Trackers publicitaires (revente)",
      "Suppression compte = parcours du combattant",
      "TOS opaques, juridiction floue",
    ]},
    foot: "Nous sommes payés par tes abonnements. Pas par tes données. Pas par la pub. Jamais.",
  } : {
    eyebrow: "Privacy first",
    title: "Privacy-first. GDPR-compliant. No bullshit.",
    sub: "No bank connection. No reselling. No tracker. Encrypted storage, optional sync, on-demand export and deletion.",
    left: { t: "Here", items: [
      "Manual entry — no bank connection",
      "AES-256 encrypted on your iPhone",
      "Optional sync, GDPR EU server",
      "No third-party trackers, no ads",
      "JSON export + full deletion in one tap",
      "Full Apple Privacy Manifest",
    ]},
    right: { t: "Elsewhere", items: [
      "Mandatory bank connection",
      "Data stored in clear on their servers",
      "Account, email, password",
      "Ad trackers (data reselling)",
      "Account deletion = obstacle course",
      "Opaque TOS, fuzzy jurisdiction",
    ]},
    foot: "We're paid by your subscription. Not your data. Not by ads. Ever.",
  };

  return (
    <section className="privacy section--alt" id="privacy">
      <div className="privacy-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--muted">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>

        <div className="privacy-compare">
          <Reveal className="priv-col us">
            <div className="priv-col-badge">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
            </div>
            <div className="priv-col-t">{t.left.t}</div>
            <ul className="priv-list">
              {t.left.items.map((it, i) => (
                <li key={i}><span className="priv-tick">✓</span>{it}</li>
              ))}
            </ul>
          </Reveal>

          <Reveal delay={120} className="priv-col them">
            <div className="priv-col-badge x">×</div>
            <div className="priv-col-t">{t.right.t}</div>
            <ul className="priv-list">
              {t.right.items.map((it, i) => (
                <li key={i}><span className="priv-x">×</span>{it}</li>
              ))}
            </ul>
          </Reveal>
        </div>

        <Reveal delay={200} className="privacy-foot">{t.foot}</Reveal>
      </div>
    </section>
  );
}

// ============================================================
// FAQ
// ============================================================
function FAQ({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "FAQ",
    title: "Les questions qu'on nous pose.",
    items: [
      { q: "L'app se connecte à ma banque ?", a: "Non. Jamais. Tu saisis toi-même tes transactions (ça prend 5 secondes), ou tu les importes manuellement si tu préfères. Nous pensons qu'une app qui a accès à ton compte a trop de pouvoir sur toi." },
      { q: "Qu'est-ce qui se passe si je perds mon iPhone ?", a: "Active la sync optionnelle (serveur RGPD en Union Européenne) : ton compte et tes données chiffrées sont restaurés sur ton nouvel appareil après authentification. Sans sync, un export JSON manuel reste disponible à tout moment depuis les Réglages." },
      { q: "Ça coûte combien ?", a: "7 jours gratuits, puis 4,99 €/mois ou 49,99 €/an (~16 % d'économie). Annulation en 1 tap depuis les réglages iOS. Aucune pub, aucun freemium déguisé." },
      { q: "Pourquoi pas Android ?", a: "Nous sommes une très petite équipe. Faire une app vraiment bien sur iOS nous prend tout notre temps. Android viendra — mais seulement quand nous pourrons offrir la même qualité." },
      { q: "Vous êtes qui, concrètement ?", a: "Un fondateur + deux indépendants. Basés entre Paris et Lisbonne. Nous mangeons notre propre cuisine : nous utilisons TargetSaver tous les jours pour financer nos propres projets." },
      { q: "Mes données peuvent-elles partir un jour ?", a: "Notre modèle économique est l'abonnement, pas la donnée. Nous ne vendons rien, jamais. Si tu actives la sync, tes données chiffrées transitent vers un serveur RGPD basé en Union Européenne (Supabase, hébergement Frankfurt) — uniquement pour permettre la restauration sur tes propres appareils. Tu peux supprimer ton compte et toutes les données associées en 1 tap depuis les Réglages : suppression effective sous 30 jours conformément au RGPD." },
    ],
  } : {
    eyebrow: "FAQ",
    title: "Questions we get asked.",
    items: [
      { q: "Does the app connect to my bank?", a: "No. Never. You enter transactions yourself (5 seconds), or import manually. We believe an app with access to your account has too much power over you." },
      { q: "What if I lose my iPhone?", a: "Turn on optional sync (GDPR-compliant EU server): your account and encrypted data are restored on your new device after authentication. Without sync, a manual JSON export is always available from Settings." },
      { q: "How much does it cost?", a: "7 days free, then €4.99/month or €49.99/year (~16% savings). One-tap cancel from iOS settings. No ads, no freemium trick." },
      { q: "Why not Android?", a: "We're a tiny team. Making a really good iOS app takes all our time. Android will come — only when we can deliver the same quality." },
      { q: "Who are you, actually?", a: "One founder + two indies. Between Paris and Lisbon. We eat our own cooking: we use TargetSaver daily to fund our own projects." },
      { q: "Can my data leak one day?", a: "Our business model is subscription, not data. We never sell, ever. If you enable sync, your encrypted data transits to a GDPR-compliant EU server (Supabase, Frankfurt hosting) — only to enable restore across your own devices. You can delete your account and all associated data in one tap from Settings: deletion completes within 30 days per GDPR." },
    ],
  };

  const [open, setOpen] = useStateS(0);

  return (
    <section className="faq section--alt" id="faq">
      <div className="faq-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--muted">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
        </div>
        <div className="faq-list">
          {t.items.map((item, i) => (
            <Reveal key={i} delay={i * 40} className={`faq-item ${open === i ? "open" : ""}`}>
              <button className="faq-q" onClick={() => setOpen(open === i ? -1 : i)}>
                <span className="faq-q-t">{item.q}</span>
                <span className="faq-q-icn">
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                    <line x1="7" y1="1" x2="7" y2="13" className="vert" />
                    <line x1="1" y1="7" x2="13" y2="7" />
                  </svg>
                </span>
              </button>
              <div className="faq-a-wrap">
                <div className="faq-a">{item.a}</div>
              </div>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Performance — Built like Apple expects
// ============================================================
function Performance({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Architecture",
    title: "Construit comme une app Apple. Pas comme un site web déguisé.",
    sub: "iOS 18+. Swift 6. SwiftUI natif. Concurrence stricte. Aucun framework hybride. Performance contrôlée à chaque commit.",
    metrics: [
      { v: "< 2s", l: "Lancement à froid", s: "iPhone 13 et plus" },
      { v: "99.9 %", l: "Crash-free rate", s: "MetricKit en continu" },
      { v: "< 150 MB", l: "Empreinte mémoire", s: "Mesurée en production" },
      { v: "0", l: "Force unwrap", s: "Audit code-reviewer" },
    ],
    stack: [
      { k: "Swift 6", d: "Concurrence stricte, Sendable, actors. Zéro race condition possible." },
      { k: "SwiftUI", d: "Interface native, déclarative. Pas de WebView, pas de React Native, pas d'Electron." },
      { k: "Realm + Sync", d: "Persistance locale chiffrée AES-256. Sync optionnelle vers serveur RGPD UE." },
      { k: "Apple Intelligence", d: "Foundation Models pour les insights — 100 % on-device. Ton iPhone, jamais un serveur." },
      { k: "App Intents · Siri", d: "14 commandes natives. Widgets interactifs iOS 18. Shortcuts." },
      { k: "Apple Watch", d: "Companion app. Score, budget restant, jours en or au poignet." },
    ],
  } : {
    eyebrow: "Architecture",
    title: "Built like an Apple app. Not a disguised website.",
    sub: "iOS 18+. Swift 6. Native SwiftUI. Strict concurrency. No hybrid framework. Performance controlled on every commit.",
    metrics: [
      { v: "< 2s", l: "Cold launch", s: "iPhone 13 and newer" },
      { v: "99.9 %", l: "Crash-free rate", s: "Continuous MetricKit" },
      { v: "< 150 MB", l: "Memory footprint", s: "Measured in production" },
      { v: "0", l: "Force unwraps", s: "Code-reviewer audit" },
    ],
    stack: [
      { k: "Swift 6", d: "Strict concurrency, Sendable, actors. Zero race conditions possible." },
      { k: "SwiftUI", d: "Native, declarative UI. No WebView, no React Native, no Electron." },
      { k: "Realm + Sync", d: "Encrypted AES-256 local persistence. Optional sync to GDPR EU server." },
      { k: "Apple Intelligence", d: "Foundation Models for insights — 100% on-device. Your iPhone, never a server." },
      { k: "App Intents · Siri", d: "14 native voice commands. Interactive iOS 18 widgets. Shortcuts." },
      { k: "Apple Watch", d: "Companion app. Score, daily budget, golden days on your wrist." },
    ],
  };

  return (
    <section className="perf section--alt" id="perf">
      <div className="perf-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--primary">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>

        <div className="perf-metrics">
          {t.metrics.map((m, i) => (
            <Reveal key={i} delay={i * 60} className="perf-metric">
              <div className="perf-metric-v">{m.v}</div>
              <div className="perf-metric-l">{m.l}</div>
              <div className="perf-metric-s">{m.s}</div>
            </Reveal>
          ))}
        </div>

        <div className="perf-stack">
          {t.stack.map((s, i) => (
            <Reveal key={i} delay={i * 50} className="perf-stack-card">
              <div className="perf-stack-k">{s.k}</div>
              <div className="perf-stack-d">{s.d}</div>
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// Trust — Security, RGPD, App Store compliance
// ============================================================
function Trust({ lang }) {
  const t = lang === "fr" ? {
    eyebrow: "Sécurité & Confiance",
    title: "Trois standards Apple. Trois normes européennes. Zéro raccourci.",
    sub: "On a fait l'effort de construire ce que les apps de finance sérieuses doivent avoir — et on le documente.",
    pillars: [
      {
        icon: "shield",
        t: "Chiffrement AES-256",
        d: "Toutes les données sensibles (montants, libellés, objectifs) sont chiffrées en local avec une clé stockée dans le Keychain iOS, déverrouillée par Face ID ou Touch ID.",
        tags: ["Keychain", "Biométrie", "AES-256"],
      },
      {
        icon: "doc",
        t: "Privacy Manifest complet",
        d: "Manifeste de confidentialité Apple déclaré : zéro tracker tiers, zéro IDFA, zéro pixel publicitaire. Tu peux vérifier toi-même dans la fiche App Store.",
        tags: ["NSPrivacyTracking: false", "Privacy Manifest", "ATT-ready"],
      },
      {
        icon: "scale",
        t: "RGPD natif & DPA signé",
        d: "Hébergement Union Européenne (Frankfurt). Data Processing Agreement signé avec notre sous-traitant Supabase. Clauses Contractuelles Types pour tout transfert. Suppression sous 30 jours sur simple demande.",
        tags: ["Article 32", "DPA", "SCCs"],
      },
    ],
    pledge: {
      title: "Nos 4 engagements",
      items: [
        "Nous ne vendrons jamais tes données. Jamais.",
        "Nous ne ferons jamais de publicité dans l'app.",
        "Nous n'introduirons jamais de tracker tiers.",
        "Tu peux exporter tout, supprimer tout, à tout moment.",
      ],
    },
    cta: { label: "Lire la politique de confidentialité complète", href: "privacy.html" },
  } : {
    eyebrow: "Security & Trust",
    title: "Three Apple standards. Three EU norms. Zero shortcuts.",
    sub: "We did the work to build what serious finance apps must have — and we document it.",
    pillars: [
      {
        icon: "shield",
        t: "AES-256 encryption",
        d: "All sensitive data (amounts, labels, goals) is encrypted locally with a key stored in the iOS Keychain, unlocked by Face ID or Touch ID.",
        tags: ["Keychain", "Biometrics", "AES-256"],
      },
      {
        icon: "doc",
        t: "Full Privacy Manifest",
        d: "Apple Privacy Manifest declared: zero third-party trackers, zero IDFA, zero ad pixel. Verify it yourself in the App Store listing.",
        tags: ["NSPrivacyTracking: false", "Privacy Manifest", "ATT-ready"],
      },
      {
        icon: "scale",
        t: "GDPR-native & signed DPA",
        d: "European Union hosting (Frankfurt). Data Processing Agreement signed with our processor Supabase. Standard Contractual Clauses for any transfer. Deletion within 30 days upon request.",
        tags: ["Article 32", "DPA", "SCCs"],
      },
    ],
    pledge: {
      title: "Our 4 commitments",
      items: [
        "We will never sell your data. Ever.",
        "We will never run ads in the app.",
        "We will never add a third-party tracker.",
        "You can export everything, delete everything, anytime.",
      ],
    },
    cta: { label: "Read the full privacy policy", href: "privacy.html" },
  };

  const icons = {
    shield: <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2 4 5v7c0 5 3.5 9 8 10 4.5-1 8-5 8-10V5l-8-3Z"/><path d="m9 12 2 2 4-4"/></svg>,
    doc: <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><path d="M9 13h6M9 17h4"/></svg>,
    scale: <svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v18M5 7h14M5 7l-3 7c.5 1.5 2 2.5 3.5 2.5S8.5 15.5 9 14L6 7m12 0-3 7c.5 1.5 2 2.5 3.5 2.5S21.5 15.5 22 14l-3-7"/></svg>,
  };

  return (
    <section className="trust" id="trust">
      <div className="trust-inner">
        <div className="section-head">
          <Reveal className="eyebrow eyebrow--warn">{t.eyebrow}</Reveal>
          <Reveal as="h2" delay={80} className="section-title">{t.title}</Reveal>
          <Reveal as="p" delay={160} className="section-sub">{t.sub}</Reveal>
        </div>

        <div className="trust-pillars">
          {t.pillars.map((p, i) => (
            <Reveal key={i} delay={i * 80} className="trust-pillar">
              <div className="trust-pillar-icn">{icons[p.icon]}</div>
              <div className="trust-pillar-t">{p.t}</div>
              <div className="trust-pillar-d">{p.d}</div>
              <div className="trust-pillar-tags">
                {p.tags.map((tag, j) => (
                  <span key={j} className="trust-tag">{tag}</span>
                ))}
              </div>
            </Reveal>
          ))}
        </div>

        <Reveal delay={120} className="trust-pledge">
          <div className="trust-pledge-t">{t.pledge.title}</div>
          <ul className="trust-pledge-list">
            {t.pledge.items.map((it, i) => (
              <li key={i}>
                <span className="trust-pledge-tick">
                  <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
                </span>
                {it}
              </li>
            ))}
          </ul>
          <a href={t.cta.href} className="trust-pledge-cta">
            {t.cta.label}
            <span className="arrow">→</span>
          </a>
        </Reveal>
      </div>
    </section>
  );
}

// Expose components globally
Object.assign(window, { Problem, PromiseSection, Pillars, Performance, Trust, Story, Quiz, Calculator, Privacy, FAQ });
