// ============================================================
// Monarch — Simulateurs de dette : rachat de société (LBO) · immobilier locatif
//   CorporateBuyoutDebtSimulator — nom propre vs holding (vampirisme de la cible)
//   RealEstateDebtSimulator       — nom propre/SCI IR vs SCI à l'IS (autofinancement)
// Sans schéma : barres de flux + chiffres. Requiert window.MSC + window.__mscShared.
// ============================================================

(function () {
  const { useState, useEffect } = React;
  const M = window.MSC;
  const { C, SERIF, BODY, IS, fmt, pct, CountEuro, injectCore, useReveal,
    Eyebrow, Label, MoneyInput, Toggle, Shell, InputsCard, Doctrine, Alert, CTAEmail, ProsCons, Explainer } = M;
  function shared() { return window.__mscShared; }

  // annuité constante (capital + intérêts)
  function annuite(P, taux, annees) {
    const r = taux, n = annees;
    if (r <= 0) return P / n;
    return P * r / (1 - Math.pow(1 + r, -n));
  }

  function FlowBar({ label, sub, value, max, run, color, danger, good }) {
    const [on, setOn] = useState(false);
    useEffect(() => { if (run) { const id = setTimeout(() => setOn(true), 80); return () => clearTimeout(id); } else setOn(false); }, [run]);
    return (
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 8, flexWrap: "wrap", gap: 8 }}>
          <span style={{ fontFamily: BODY, fontSize: 13, color: good ? C.sauge : C.ardoise, letterSpacing: "0.08em", textTransform: "uppercase", fontWeight: 600 }}>{label}</span>
          <CountEuro value={value} run={run} style={{ fontFamily: SERIF, fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 500, color: color || C.encre, letterSpacing: "-0.01em" }} />
        </div>
        <div style={{ height: 18, background: C.albatre, border: `1px solid ${C.trait}`, overflow: "hidden" }}>
          <div style={{ height: "100%", width: on ? Math.min(100, pct(value, max)) + "%" : 0, transition: "width 1.1s cubic-bezier(.2,.7,.3,1)", background: good ? C.saugeF : "transparent", backgroundColor: good ? C.saugeF : (danger ? "rgba(162,59,59,.10)" : "rgba(91,124,153,.10)"), backgroundImage: good ? "none" : `repeating-linear-gradient(135deg, ${danger ? "rgba(162,59,59,.5)" : "rgba(91,124,153,.45)"} 0, ${danger ? "rgba(162,59,59,.5)" : "rgba(91,124,153,.45)"} 1.5px, transparent 1.5px, transparent 6px)` }} />
        </div>
        {sub && <div style={{ fontFamily: BODY, fontSize: 13, color: C.gris, marginTop: 8 }}>{sub}</div>}
      </div>);
  }

  // =====================================================
  // 1. RACHAT DE SOCIÉTÉ — la dette d'acquisition
  // =====================================================
  function CorporateBuyoutDebtSimulator() {
    useEffect(injectCore, []);
    const { ParamRecap, Panel } = shared();
    const [acq, setAcq] = useState(1500000);
    const [taux, setTaux] = useState(4);
    const [duree, setDuree] = useState(7);
    const [done, setDone] = useState(false);
    const [busy, setBusy] = useState(false);
    const reveal = useReveal(done, 250);

    const P = Math.max(0, Number(acq) || 0);
    const r = Math.max(0, Number(taux) || 0) / 100;
    const n = Math.max(1, Number(duree) || 1);
    const charge = annuite(P, r, n);             // annuité à payer à la banque
    const coutTotal = charge * n;                // total remboursé
    const interetsTotal = coutTotal - P;         // coût des intérêts
    const mensualite = charge / 12;
    const superBrutPropre = charge / (1 - 0.314); // à siphonner de la cible (Flat Tax)
    const superBrutHolding = charge / (1 - 0.0125); // via mère-fille
    const economie = superBrutPropre - superBrutHolding;
    const max = superBrutPropre || 1;

    const go = () => { setBusy(true); setDone(false); setTimeout(() => { setBusy(false); setDone(true); }, 700); };

    return (
      <Shell eyebrow="Reprise · Dette d'acquisition"
        title="Racheter une entreprise : le coût selon votre montage."
        intro="Pour rembourser un emprunt souscrit à titre personnel, vous devez vous verser des dividendes — fortement taxés. Loger l'emprunt dans une holding coûte bien moins cher. Comparez les deux.">
        {!done &&
          <InputsCard onCompute={go} computing={busy} label="Calculer le coût de financement">
            <div><Label>Montant de l'acquisition (dette bancaire)</Label><MoneyInput value={acq} onChange={setAcq} min={100000} max={20000000} step={100000} /></div>
            <div>
              <Label>Taux d'intérêt bancaire</Label>
              <div style={{ fontFamily: SERIF, fontSize: 30, fontWeight: 500, color: C.encre }}>{Number(taux).toFixed(1).replace(".", ",")} %</div>
              <input type="range" min="1" max="8" step="0.1" value={taux} onChange={(e) => setTaux(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
            <div style={{ gridColumn: "1 / -1" }}>
              <Label>Durée de l'emprunt</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{n} ans</div>
              <input type="range" min="5" max="10" step="1" value={n} onChange={(e) => setDuree(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
          </InputsCard>}

        {done &&
          <div style={{ marginTop: 36 }}>
            <ParamRecap items={[["Acquisition", fmt(P)], ["Taux", Number(taux).toFixed(1).replace(".", ",") + " %"], ["Durée", n + " ans"]]} onEdit={() => setDone(false)} />

            {/* Annuité de remboursement */}
            <div style={{ marginTop: 16, border: `1px solid ${C.trait}`, background: C.blanc, padding: "clamp(22px,3vw,32px)" }}>
              <Eyebrow>L'annuité de remboursement</Eyebrow>
              <h3 style={{ fontFamily: SERIF, fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 500, letterSpacing: "-0.01em", margin: "10px 0 4px" }}>Ce que vous remboursez à la banque</h3>
              <CountEuro value={charge} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(30px,4.4vw,52px)", fontWeight: 500, color: C.encre, letterSpacing: "-0.01em", lineHeight: 1 }} />
              <div style={{ fontFamily: BODY, fontSize: 14, color: C.gris, marginTop: 8 }}>par an, soit {fmt(mensualite)} par mois</div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px,1fr))", gap: 18, marginTop: 22, paddingTop: 20, borderTop: `1px solid ${C.trait}` }}>
                <div><div style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris, marginBottom: 4 }}>Capital emprunté</div><div style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: C.encre }}>{fmt(P)}</div></div>
                <div><div style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris, marginBottom: 4 }}>Intérêts sur {n} ans</div><div style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: C.ardoiseF }}>{fmt(interetsTotal)}</div></div>
                <div><div style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris, marginBottom: 4 }}>Coût total du crédit</div><div style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: C.encre }}>{fmt(coutTotal)}</div></div>
              </div>
            </div>

            <div className="msc-grid2" style={{ marginTop: 16 }}>
              <Panel tone="light" eyebrow="Emprunt à titre personnel" title="Ce que la société doit sortir">
                <FlowBar label="À sortir de la société / an" value={superBrutPropre} max={max} run={reveal} color={C.encre} danger
                  sub={`Pour rembourser ${fmt(charge)} à la banque, après impôt de 31,4 % sur les dividendes.`} />
                <p style={{ fontFamily: BODY, fontSize: 13.5, color: "#2c2e2d", lineHeight: 1.6, margin: "16px 0 0" }}>
                  Chaque année, <b style={{ color: "#a23b3b" }}>{fmt(superBrutPropre)}</b> doivent sortir de la société pour qu'il vous reste {fmt(charge)} net une fois l'impôt payé. Autant d'argent en moins pour la développer.
                </p>
              </Panel>
              <Panel tone="dark" eyebrow="Emprunt logé dans une holding" title="Le montage qui préserve la trésorerie">
                <div style={{ height: 18, background: "rgba(255,255,255,.08)", overflow: "hidden" }}>
                  <div style={{ height: "100%", width: reveal ? pct(superBrutHolding, max) + "%" : 0, transition: "width 1.1s cubic-bezier(.2,.7,.3,1)", background: C.sauge }} />
                </div>
                <div style={{ marginTop: 14, fontFamily: BODY, fontSize: 12.5, color: "#9ea7a0" }}>À remonter de la société / an (presque sans impôt)</div>
                <CountEuro value={superBrutHolding} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(28px,4vw,46px)", fontWeight: 500, color: "#fff", letterSpacing: "-0.01em", lineHeight: 1 }} />
                <div style={{ fontFamily: BODY, fontSize: 13, color: C.sauge, fontWeight: 600, marginTop: 8 }}>Frottement limité à 1,25 %</div>
              </Panel>
            </div>

            <div className={"msc-soft" + (reveal ? " on" : "")} style={{ transitionDelay: ".2s", marginTop: 22, border: `1px solid ${C.trait}`, background: C.albatre, padding: "clamp(22px,3vw,32px)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 30, flexWrap: "wrap" }}>
              <div style={{ fontFamily: BODY, fontSize: 14, color: C.gris, lineHeight: 1.5, maxWidth: "32em" }}>Trésorerie de la cible préservée chaque année grâce au logement de la dette dans la holding :</div>
              <div style={{ textAlign: "right" }}>
                <CountEuro value={economie} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(30px,4vw,48px)", fontWeight: 500, color: C.saugeF, letterSpacing: "-0.01em" }} />
                <div style={{ fontFamily: BODY, fontSize: 13, color: C.gris, marginTop: 2 }}>économisés par an · {fmt(economie * n)} sur la durée</div>
              </div>
            </div>

            <Doctrine open={reveal} eyebrow="À retenir" title="Évitez de rembourser un rachat avec de l'argent déjà taxé" accent={C.sauge}>
              <p style={{ margin: 0 }}>Racheter une entreprise en empruntant à titre personnel coûte cher : pour rembourser 100 € à la banque, il faut sortir environ <b style={{ color: "#fff" }}>145 € de la société</b> (le reste part en impôt sur les dividendes). En logeant l'emprunt dans une holding, les bénéfices remontent presque sans impôt pour rembourser la banque, et les intérêts deviennent déductibles. Le cabinet met en place ce montage.</p>
            </Doctrine>

            <ProsCons open={reveal}
              pour={["Les bénéfices remontent presque sans impôt pour rembourser la banque.", "Les intérêts d'emprunt sont déductibles à l'impôt sur les sociétés.", "La trésorerie de l'entreprise rachetée reste disponible pour la développer."]}
              contre={["Créer et gérer une holding a un coût et demande de la rigueur.", "La banque exige souvent des garanties personnelles malgré le montage.", "Un rachat reste un endettement : si l'activité ralentit, le remboursement pèse."]} />

            <CTAEmail />
          </div>}
      </Shell>);
  }

  // =====================================================
  // 2. IMMOBILIER LOCATIF — l'effort d'épargne
  // =====================================================
  function RealEstateDebtSimulator() {
    useEffect(injectCore, []);
    const { ParamRecap, Panel } = shared();
    const TMIs = [{ id: "11", v: 0.11 }, { id: "30", v: 0.30 }, { id: "41", v: 0.41 }, { id: "45", v: 0.45 }];
    const [projet, setProjet] = useState(500000);
    const [loyer, setLoyer] = useState(35000);
    const [taux, setTaux] = useState(3.5);
    const [duree, setDuree] = useState(20);
    const [tmiId, setTmiId] = useState("41");
    const [done, setDone] = useState(false);
    const [busy, setBusy] = useState(false);
    const reveal = useReveal(done, 250);

    const P = Math.max(0, Number(projet) || 0);
    const Lo = Math.max(0, Number(loyer) || 0);
    const r = Math.max(0, Number(taux) || 0) / 100;
    const n = Math.max(1, Number(duree) || 1);
    const tmi = (TMIs.find((t) => t.id === tmiId) || TMIs[1]).v;
    const PS = 0.172;
    const mens = annuite(P, r, n);              // annuité annuelle
    const coutTotalImmo = mens * n;
    const interetsTotalImmo = coutTotalImmo - P;
    const interets = P * r;                     // intérêts ~année 1
    const amort = P * 0.85 * 0.03;              // amortissement bâti (~85 % de la valeur, 3 %/an)

    // A : nom propre / SCI IR
    const baseIR = Math.max(0, Lo - interets);
    const impotIR = baseIR * (tmi + PS);
    const cashIR = Lo - mens - impotIR;
    const effortIR = cashIR < 0 ? -cashIR / 12 : 0;
    // B : SCI à l'IS
    const baseIS = Math.max(0, Lo - interets - amort);
    const impotIS = IS(baseIS);
    const cashIS = Lo - mens - impotIS;
    const effortIS = cashIS < 0 ? -cashIS / 12 : 0;
    const tauxFoncier = Math.round((tmi + PS) * 1000) / 10;

    const go = () => { setBusy(true); setDone(false); setTimeout(() => { setBusy(false); setDone(true); }, 700); };

    return (
      <Shell eyebrow="Patrimoine du dirigeant · Immobilier locatif"
        title="Immobilier locatif : combien ça vous coûte chaque mois."
        intro="En détenant le bien à votre nom, l'impôt sur les loyers crée souvent un effort d'épargne mensuel. En société (SCI à l'IS), les loyers remboursent l'emprunt presque seuls.">
        {!done &&
          <InputsCard onCompute={go} computing={busy} label="Calculer mon effort d'épargne">
            <div><Label>Montant du projet (emprunt 100 %)</Label><MoneyInput value={projet} onChange={setProjet} min={50000} max={10000000} step={10000} /></div>
            <div><Label>Loyer annuel brut estimé</Label><MoneyInput value={loyer} onChange={setLoyer} min={0} max={1000000} step={1000} /></div>
            <div>
              <Label>Taux d'intérêt bancaire</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{Number(taux).toFixed(1).replace(".", ",")} %</div>
              <input type="range" min="1" max="6" step="0.1" value={taux} onChange={(e) => setTaux(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
            <div>
              <Label>Durée du crédit</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{n} ans</div>
              <input type="range" min="10" max="25" step="1" value={n} onChange={(e) => setDuree(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
            <div style={{ gridColumn: "1 / -1" }}>
              <Label>Votre tranche marginale d'imposition (TMI)</Label>
              <Toggle full options={[{ id: "11", label: "11 %" }, { id: "30", label: "30 %" }, { id: "41", label: "41 %" }, { id: "45", label: "45 %" }]} value={tmiId} onChange={setTmiId} />
            </div>
          </InputsCard>}

        {done &&
          <div style={{ marginTop: 36 }}>
            <ParamRecap items={[["Projet", fmt(P)], ["Loyer/an", fmt(Lo)], ["Crédit", n + " ans à " + Number(taux).toFixed(1).replace(".", ",") + " %"], ["TMI", Math.round(tmi * 100) + " %"]]} onEdit={() => setDone(false)} />

            <div style={{ marginTop: 16, border: `1px solid ${C.trait}`, background: C.blanc, padding: "clamp(22px,3vw,32px)" }}>
              <Eyebrow>Votre crédit immobilier</Eyebrow>
              <h3 style={{ fontFamily: SERIF, fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 500, letterSpacing: "-0.01em", margin: "10px 0 4px" }}>Mensualité de {fmt(mens / 12)}</h3>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px,1fr))", gap: 18, marginTop: 18, paddingTop: 18, borderTop: `1px solid ${C.trait}` }}>
                <div><div style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris, marginBottom: 4 }}>Capital emprunté</div><div style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: C.encre }}>{fmt(P)}</div></div>
                <div><div style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris, marginBottom: 4 }}>Intérêts sur {n} ans</div><div style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: C.ardoiseF }}>{fmt(interetsTotalImmo)}</div></div>
                <div><div style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris, marginBottom: 4 }}>Coût total du crédit</div><div style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: C.encre }}>{fmt(coutTotalImmo)}</div></div>
              </div>
            </div>

            <div className="msc-grid2" style={{ marginTop: 16 }}>
              <Panel tone="light" eyebrow="Bien détenu à votre nom" title="L'actif qui vous coûte chaque mois">
                <FlowBar label="Impôt foncier annuel" value={impotIR} max={Lo || 1} run={reveal} color={C.encre} danger
                  sub={`Base ${fmt(baseIR)} × (TMI ${Math.round(tmi * 100)} % + PS 17,2 %) = ${tauxFoncier} %`} />
                <div style={{ marginTop: 18, padding: "16px 18px", background: C.albatre, border: `1px solid ${C.trait}` }}>
                  <div style={{ fontFamily: BODY, fontSize: 12.5, color: "#a23b3b", letterSpacing: "0.08em", textTransform: "uppercase", fontWeight: 600, marginBottom: 6 }}>Effort d'épargne mensuel</div>
                  <CountEuro value={effortIR} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(28px,3.8vw,44px)", fontWeight: 500, color: "#a23b3b", letterSpacing: "-0.01em", lineHeight: 1 }} />
                  <div style={{ fontFamily: BODY, fontSize: 13, color: C.gris, marginTop: 8 }}>à injecter chaque mois pour rembourser la banque ({fmt(Math.abs(cashIR))}/an de cash-flow négatif)</div>
                </div>
              </Panel>
              <Panel tone="dark" eyebrow="Bien détenu en société (SCI à l'IS)" title="Le locataire finance l'actif">
                <div style={{ fontFamily: BODY, fontSize: 12.5, color: "#9ea7a0", marginBottom: 6 }}>Impôt IS annuel</div>
                <CountEuro value={impotIS} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(26px,3.4vw,40px)", fontWeight: 500, color: "#fff", letterSpacing: "-0.01em", lineHeight: 1 }} />
                <div style={{ fontFamily: BODY, fontSize: 13, color: C.sauge, fontWeight: 600, marginTop: 8 }}>
                  {baseIS <= 0 ? "Base taxable nulle — amortissement + intérêts neutralisent l'impôt" : `Base ${fmt(baseIS)} après amortissement`}
                </div>
                <div style={{ marginTop: 18, padding: "16px 18px", background: "rgba(92,111,92,.18)", border: "1px solid rgba(92,111,92,.4)" }}>
                  <div style={{ fontFamily: BODY, fontSize: 12.5, color: C.sauge, letterSpacing: "0.08em", textTransform: "uppercase", fontWeight: 600, marginBottom: 6 }}>Effort d'épargne mensuel</div>
                  <CountEuro value={effortIS} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(28px,3.8vw,44px)", fontWeight: 500, color: "#fff", letterSpacing: "-0.01em", lineHeight: 1 }} />
                  <div style={{ fontFamily: BODY, fontSize: 13, color: "#9ea7a0", marginTop: 8 }}>{effortIS <= 1 ? "Les loyers couvrent l'emprunt : l'actif s'autofinance." : "quasi-équilibre de trésorerie"}</div>
                </div>
              </Panel>
            </div>

            <Doctrine open={reveal} eyebrow="L'encart doctrinal" title="L'autofinancement immobilier est une équation sociétaire" accent={C.sauge}>
              <p style={{ margin: 0 }}>Acquérir de l'immobilier de rendement en nom propre ou en SCI à l'IR est une anomalie pour un contribuable fortement fiscalisé : le frottement de votre imposition personnelle détruit la rentabilité locative et exige des injections de trésorerie constantes. Le cabinet structure vos acquisitions (<b style={{ color: "#fff" }}>SCI à l'IS, holding</b>) pour créer un effet de levier total — la société amortit l'actif, neutralise l'impôt immédiat, et permet à l'immobilier de se financer seul, en circuit fermé.</p>
            </Doctrine>
            <p style={{ fontFamily: BODY, fontSize: 12, color: C.grisC, lineHeight: 1.6, margin: "14px 0 0" }}>Estimation indicative (intérêts et amortissement de 1re année ; la base IS remonte progressivement avec l'amortissement du capital). La revente d'un bien à l'IS génère une plus-value majorée — à anticiper.</p>

            <ProsCons open={reveal}
              pour={["Les loyers couvrent l'emprunt : peu ou pas d'effort d'épargne mensuel.", "L'amortissement du bâti neutralise l'impôt pendant de longues années.", "Le bien se constitue dans la société, prêt à servir d'autres projets."]}
              contre={["À la revente, l'impôt est plus lourd qu'en nom propre (amortissements repris).", "Sortir les loyers vers votre compte personnel reste taxé.", "Comptabilité et gestion d'une SCI à l'IS : plus de formalisme et de frais."]} />

            <CTAEmail />
          </div>}
      </Shell>);
  }

  window.CorporateBuyoutDebtSimulator = CorporateBuyoutDebtSimulator;
  window.RealEstateDebtSimulator = RealEstateDebtSimulator;

  // =====================================================
  // 3. CAPITALISATION FINANCIÈRE — l'effet boule de neige
  // =====================================================
  function FinancialCapitalizationSimulator() {
    useEffect(injectCore, []);
    const { ParamRecap } = shared();
    const [capital, setCapital] = useState(100000);
    const [perf, setPerf] = useState(6);
    const [duree, setDuree] = useState(15);
    const [done, setDone] = useState(false);
    const [busy, setBusy] = useState(false);
    const reveal = useReveal(done, 250);

    const K = Math.max(0, Number(capital) || 0);
    const g = Math.max(0, Number(perf) || 0) / 100;
    const n = Math.max(1, Math.min(30, Number(duree) || 1));
    const gNet = g * (1 - 0.314);                 // gain net annuel en nom propre
    const nomPropre = K * Math.pow(1 + gNet, n);
    const holding = K * Math.pow(1 + g, n);
    const ecart = holding - nomPropre;

    const go = () => { setBusy(true); setDone(false); setTimeout(() => { setBusy(false); setDone(true); }, 700); };

    return (
      <Shell eyebrow="Placements · Capitalisation"
        title="L'effet boule de neige : faire fructifier sans freiner."
        intro="Quand vos placements rapportent, l'impôt prélevé chaque année freine leur croissance. En holding, les gains se réinvestissent en entier. Comparez sur la durée.">
        {!done &&
          <InputsCard onCompute={go} computing={busy} label="Voir l'écart sur la durée">
            <div><Label>Capital de départ à placer</Label><MoneyInput value={capital} onChange={setCapital} min={10000} max={5000000} step={10000} /></div>
            <div>
              <Label>Performance annuelle estimée</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{Number(perf).toFixed(1).replace(".", ",")} %</div>
              <input type="range" min="1" max="12" step="0.5" value={perf} onChange={(e) => setPerf(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
            <div style={{ gridColumn: "1 / -1" }}>
              <Label>Durée du placement</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{n} ans</div>
              <input type="range" min="5" max="25" step="1" value={n} onChange={(e) => setDuree(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
          </InputsCard>}

        {done &&
          <div style={{ marginTop: 36 }}>
            <ParamRecap items={[["Capital", fmt(K)], ["Performance", Number(perf).toFixed(1).replace(".", ",") + " %/an"], ["Durée", n + " ans"]]} onEdit={() => setDone(false)} />
            <GrowthCurve reveal={reveal} K={K} g={g} gNet={gNet} n={n} />
            <div className={"msc-soft" + (reveal ? " on" : "")} style={{ transitionDelay: ".2s", marginTop: 22, border: `1px solid ${C.trait}`, background: C.albatre, padding: "clamp(22px,3vw,32px)", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 30, flexWrap: "wrap" }}>
              <div style={{ fontFamily: BODY, fontSize: 14, color: C.gris, lineHeight: 1.5, maxWidth: "32em" }}>En {n} ans, à effort de départ identique, la holding vous fait gagner&nbsp;:</div>
              <div style={{ textAlign: "right" }}>
                <CountEuro value={ecart} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(30px,4vw,48px)", fontWeight: 500, color: C.saugeF, letterSpacing: "-0.01em" }} />
                <div style={{ fontFamily: BODY, fontSize: 13, color: C.gris, marginTop: 2 }}>de patrimoine supplémentaire</div>
              </div>
            </div>
            <Doctrine open={reveal} eyebrow="À retenir" title="Ne laissez pas l'impôt annuel freiner vos placements" accent={C.sauge}>
              <p style={{ margin: 0 }}>Le pire ennemi d'un capital qui grandit, ce n'est pas le rendement, c'est l'impôt prélevé chaque année. Placer vos excédents à votre nom revient à retirer près d'un tiers des gains à chaque étape. En holding, <b style={{ color: "#fff" }}>100 % de la performance est réinvestie</b> et l'impôt personnel n'intervient qu'à la sortie, jamais pendant la phase de croissance. Le cabinet met en place cette structure de capitalisation.</p>
            </Doctrine>
            <p style={{ fontFamily: BODY, fontSize: 12, color: C.grisC, lineHeight: 1.6, margin: "14px 0 0" }}>Estimation simplifiée : en holding, l'impôt sur les sociétés sur les gains réalisés reste dû ; l'avantage tient au report de l'impôt personnel (31,4 %) et au réinvestissement intégral.</p>
            <ProsCons open={reveal}
              pour={["Les gains se réinvestissent en entier : le capital grossit plus vite.", "L'impôt personnel est reporté tant que l'argent reste dans la société.", "Idéal pour un capital qu'on ne compte pas consommer à court terme."]}
              contre={["La société paie l'impôt sur les sociétés sur les gains réalisés.", "Sortir l'argent vers votre compte personnel sera taxé à ce moment-là.", "Argent immobilisé dans la société : moins de souplesse au quotidien."]} />
            <CTAEmail />
          </div>}
      </Shell>);
  }

  function GrowthCurve({ reveal, K, g, gNet, n }) {
    const [on, setOn] = useState(false);
    useEffect(() => { if (reveal) { const id = setTimeout(() => setOn(true), 250); return () => clearTimeout(id); } else setOn(false); }, [reveal]);
    const x0 = 46, x1 = 694, yb = 250, yt = 26;
    const hi = [], lo = [];
    for (let k = 0; k <= n; k++) { hi.push(K * Math.pow(1 + g, k)); lo.push(K * Math.pow(1 + gNet, k)); }
    const maxV = hi[n] || 1;
    const X = (k) => x0 + (x1 - x0) * (k / n);
    const Y = (v) => yb - (yb - yt) * (v / maxV);
    const path = (arr) => arr.map((v, i) => `${i === 0 ? "M" : "L"} ${X(i).toFixed(1)} ${Y(v).toFixed(1)}`).join(" ");
    const area = [...hi.map((v, i) => `${X(i).toFixed(1)},${Y(v).toFixed(1)}`), ...lo.map((v, i) => `${X(n - i).toFixed(1)},${Y(lo[n - i]).toFixed(1)}`)].join(" ");
    return (
      <div style={{ marginTop: 16, border: `1px solid ${C.trait}`, background: C.blanc, padding: "clamp(22px,3vw,32px)" }}>
        <Eyebrow>La croissance, année après année</Eyebrow>
        <h3 style={{ fontFamily: SERIF, fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 500, letterSpacing: "-0.01em", margin: "10px 0 18px" }}>L'écart se creuse avec le temps</h3>
        <svg viewBox="0 0 740 290" style={{ width: "100%", height: "auto", display: "block", overflow: "visible" }} role="img" aria-label="Courbes de capitalisation">
          <defs><pattern id="capHatch" width="7" height="7" patternTransform="rotate(45)" patternUnits="userSpaceOnUse"><line x1="0" y1="0" x2="0" y2="7" stroke={C.ardoise} strokeWidth="0.8" opacity="0.5" /></pattern></defs>
          <line x1={x0} y1={yb} x2={x1} y2={yb} stroke={C.trait} strokeWidth="1" />
          {[0, Math.round(n / 2), n].map((k) => <text key={k} x={X(k)} y={yb + 20} fontFamily="'Archivo',sans-serif" fontSize="11" fill={C.grisC} textAnchor="middle">AN {k}</text>)}
          <polygon className={"msc-soft" + (on ? " on" : "")} style={{ transitionDelay: "1.6s" }} points={area} fill="url(#capHatch)" />
          <path className={"msc-line" + (on ? " on" : "")} style={{ strokeDasharray: 2600, strokeDashoffset: on ? 0 : 2600 }} d={path(lo)} fill="none" stroke={C.ardoise} strokeWidth="1.6" strokeDasharray={on ? "5 4" : 2600} opacity="0.55" />
          <path className={"msc-line" + (on ? " on" : "")} style={{ strokeDasharray: 2600, strokeDashoffset: on ? 0 : 2600, transitionDelay: ".15s" }} d={path(hi)} fill="none" stroke={C.encre} strokeWidth="2.2" />
        </svg>
        <div style={{ display: "flex", gap: 26, flexWrap: "wrap", marginTop: 16 }}>
          <span style={{ display: "flex", alignItems: "center", gap: 10 }}><span style={{ width: 16, borderTop: `2px dashed ${C.ardoise}`, opacity: 0.6, display: "inline-block" }} /><span style={{ fontFamily: BODY, fontSize: 13, color: C.gris }}>À votre nom</span><span style={{ fontFamily: BODY, fontSize: 14, color: C.encre, fontWeight: 700 }}>{fmt(lo[n])}</span></span>
          <span style={{ display: "flex", alignItems: "center", gap: 10 }}><span style={{ width: 16, borderTop: `2px solid ${C.encre}`, display: "inline-block" }} /><span style={{ fontFamily: BODY, fontSize: 13, color: C.gris }}>En holding</span><span style={{ fontFamily: BODY, fontSize: 14, color: C.saugeF, fontWeight: 700 }}>{fmt(hi[n])}</span></span>
        </div>
      </div>);
  }

  window.FinancialCapitalizationSimulator = FinancialCapitalizationSimulator;

  // =====================================================
  // 4. INTÉRÊTS COMPOSÉS — le levier du temps
  // =====================================================
  function CompoundInterestSimulator() {
    useEffect(injectCore, []);
    const { ParamRecap } = shared();
    const [capital, setCapital] = useState(100000);
    const [mensuel, setMensuel] = useState(1000);
    const [perf, setPerf] = useState(7);
    const [duree, setDuree] = useState(20);
    const [done, setDone] = useState(false);
    const [busy, setBusy] = useState(false);
    const reveal = useReveal(done, 250);

    const K = Math.max(0, Number(capital) || 0);
    const mAnnuel = Math.max(0, Number(mensuel) || 0) * 12;
    const g = Math.max(0, Number(perf) || 0) / 100;
    const n = Math.max(1, Math.min(30, Number(duree) || 1));

    // série annuelle : versé cumulé vs total
    const verseArr = [], totalArr = [];
    let total = K;
    verseArr.push(K); totalArr.push(K);
    for (let k = 1; k <= n; k++) {
      total = total * (1 + g) + mAnnuel;
      verseArr.push(K + mAnnuel * k);
      totalArr.push(total);
    }
    const totalVerse = K + mAnnuel * n;
    const totalFinal = totalArr[n];
    const gains = totalFinal - totalVerse;
    const bascule = gains > (totalVerse);

    const go = () => { setBusy(true); setDone(false); setTimeout(() => { setBusy(false); setDone(true); }, 700); };

    return (
      <Shell eyebrow="Placements · Le temps"
        title="Le levier du temps : quand vos intérêts dépassent vos versements."
        intro="Sur le temps long, l'essentiel de votre patrimoine ne vient plus de ce que vous versez, mais des intérêts qui s'auto-alimentent. Voyez le point de bascule.">
        {!done &&
          <InputsCard onCompute={go} computing={busy} label="Voir la valeur créée par le temps">
            <div><Label>Capital de départ</Label><MoneyInput value={capital} onChange={setCapital} min={0} max={5000000} step={10000} /></div>
            <div><Label>Versement mensuel</Label><MoneyInput value={mensuel} onChange={setMensuel} min={0} max={50000} step={250} /></div>
            <div>
              <Label>Rendement annuel estimé</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{Number(perf).toFixed(1).replace(".", ",")} %</div>
              <input type="range" min="1" max="15" step="0.5" value={perf} onChange={(e) => setPerf(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
            <div>
              <Label>Horizon de placement</Label>
              <div style={{ fontFamily: SERIF, fontSize: 28, fontWeight: 500, color: C.encre }}>{n} ans</div>
              <input type="range" min="5" max="30" step="1" value={n} onChange={(e) => setDuree(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
          </InputsCard>}

        {done &&
          <div style={{ marginTop: 36 }}>
            <ParamRecap items={[["Départ", fmt(K)], ["Versement", fmt(Number(mensuel)) + "/mois"], ["Rendement", Number(perf).toFixed(1).replace(".", ",") + " %/an"], ["Horizon", n + " ans"]]} onEdit={() => setDone(false)} />

            <StackedArea reveal={reveal} verse={verseArr} total={totalArr} n={n} />

            <div className={"msc-soft" + (reveal ? " on" : "")} style={{ transitionDelay: ".2s", marginTop: 22, background: C.encre, color: "#fff", padding: "clamp(26px,4vw,42px)" }}>
              <Eyebrow color={C.sauge}>La richesse créée par le temps</Eyebrow>
              <div style={{ marginTop: 12 }}>
                <span style={{ fontFamily: BODY, fontSize: 15, color: "#cfd2cf" }}>La capitalisation a généré </span>
                <CountEuro value={gains} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(34px,5vw,60px)", fontWeight: 500, color: "#fff", letterSpacing: "-0.01em", display: "block", marginTop: 8 }} />
                <span style={{ fontFamily: BODY, fontSize: 15, color: C.sauge, fontWeight: 600 }}>de gains, en plus de vos versements</span>
              </div>
              <p style={{ fontFamily: BODY, fontSize: 14.5, color: "#cfd2cf", lineHeight: 1.7, margin: "16px 0 0", maxWidth: "46em" }}>
                À {n} ans, votre patrimoine atteint <b style={{ color: "#fff" }}>{fmt(totalFinal)}</b>. Vous avez versé <b style={{ color: "#fff" }}>{fmt(totalVerse)}</b> ; les intérêts ont ajouté <b style={{ color: "#fff" }}>{fmt(gains)}</b>.{bascule ? " La bascule est franchie : l'argent généré a dépassé votre propre effort." : ""}
              </p>
            </div>

            <Doctrine open={reveal} eyebrow="À retenir" title="La trésorerie qui dort perd de la valeur" accent={C.sauge}>
              <p style={{ margin: 0 }}>Laisser les excédents de votre entreprise sur un compte non rémunéré, c'est renoncer au levier le plus puissant : le temps. L'inflation grignote ce capital chaque année. Le cabinet structure vos excédents professionnels (contrat de capitalisation en holding, usufruit de SCPI…) pour que chaque euro de votre groupe travaille et se transforme en revenu durable.</p>
            </Doctrine>
            <ProsCons open={reveal}
              pour={["Plus l'horizon est long, plus les intérêts prennent le relais de vos versements.", "Mettre la trésorerie excédentaire au travail plutôt que de la laisser dormir.", "Protège votre capital contre l'érosion de l'inflation."]}
              contre={["Le rendement n'est jamais garanti : tout placement comporte un risque de perte.", "L'argent placé est moins disponible immédiatement.", "Une fiscalité s'applique aux gains, selon l'enveloppe choisie."]} />
            <CTAEmail />
          </div>}
      </Shell>);
  }

  function StackedArea({ reveal, verse, total, n }) {
    const [on, setOn] = useState(false);
    useEffect(() => { if (reveal) { const id = setTimeout(() => setOn(true), 250); return () => clearTimeout(id); } else setOn(false); }, [reveal]);
    const x0 = 46, x1 = 694, yb = 250, yt = 26;
    const maxV = total[n] || 1;
    const X = (k) => x0 + (x1 - x0) * (k / n);
    const Y = (v) => yb - (yb - yt) * (v / maxV);
    const baseline = `${X(0).toFixed(1)},${yb} ` + verse.map((v, i) => `${X(i).toFixed(1)},${Y(v).toFixed(1)}`).join(" ") + ` ${X(n).toFixed(1)},${yb}`;
    const interestPoly = verse.map((v, i) => `${X(i).toFixed(1)},${Y(v).toFixed(1)}`).join(" ") + " " + [...total].reverse().map((v, i) => `${X(n - i).toFixed(1)},${Y(v).toFixed(1)}`).join(" ");
    return (
      <div style={{ marginTop: 16, border: `1px solid ${C.trait}`, background: C.blanc, padding: "clamp(22px,3vw,32px)" }}>
        <Eyebrow>Vos versements vs les intérêts générés</Eyebrow>
        <h3 style={{ fontFamily: SERIF, fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 500, letterSpacing: "-0.01em", margin: "10px 0 18px" }}>La part des intérêts grandit avec le temps</h3>
        <svg viewBox="0 0 740 290" style={{ width: "100%", height: "auto", display: "block", overflow: "visible" }} role="img" aria-label="Aires empilées versements et intérêts">
          <defs>
            <pattern id="ciHatch" width="7" height="7" patternTransform="rotate(45)" patternUnits="userSpaceOnUse"><line x1="0" y1="0" x2="0" y2="7" stroke={C.ardoise} strokeWidth="0.9" opacity="0.5" /></pattern>
            <clipPath id="ciClip"><rect x={x0} y={yt - 6} width={on ? (x1 - x0) : 0} height={yb - yt + 12} style={{ transition: "width 1.4s cubic-bezier(.3,0,.2,1)" }} /></clipPath>
          </defs>
          <line x1={x0} y1={yb} x2={x1} y2={yb} stroke={C.trait} strokeWidth="1" />
          {[0, Math.round(n / 2), n].map((k) => <text key={k} x={X(k)} y={yb + 20} fontFamily="'Archivo',sans-serif" fontSize="11" fill={C.grisC} textAnchor="middle">AN {k}</text>)}
          <g clipPath="url(#ciClip)">
            <polygon points={interestPoly} fill={C.saugeF} opacity="0.9" />
            <polygon points={baseline} fill="url(#ciHatch)" stroke={C.ardoise} strokeWidth="1" />
          </g>
        </svg>
        <div style={{ display: "flex", gap: 26, flexWrap: "wrap", marginTop: 16 }}>
          <span style={{ display: "flex", alignItems: "center", gap: 10 }}><span style={{ width: 14, height: 14, background: "url(#ciHatch)", border: `1px solid ${C.ardoise}`, display: "inline-block", backgroundColor: "rgba(91,124,153,.12)" }} /><span style={{ fontFamily: BODY, fontSize: 13, color: C.gris }}>Vos versements</span><span style={{ fontFamily: BODY, fontSize: 14, color: C.encre, fontWeight: 700 }}>{fmt(verse[n])}</span></span>
          <span style={{ display: "flex", alignItems: "center", gap: 10 }}><span style={{ width: 14, height: 14, background: C.saugeF, display: "inline-block" }} /><span style={{ fontFamily: BODY, fontSize: 13, color: C.gris }}>Intérêts générés</span><span style={{ fontFamily: BODY, fontSize: 14, color: C.saugeF, fontWeight: 700 }}>{fmt(total[n] - verse[n])}</span></span>
        </div>
      </div>);
  }

  window.CompoundInterestSimulator = CompoundInterestSimulator;
})();
