// ============================================================
// Monarch — : simulateur d'extraction de trésorerie
// Composant React autonome. Exposé sur window.HoldingDiagnostic.
// Chargé AVANT monarch.jsx pour que Home puisse le rendre.
// ============================================================
(function () {
const { useState, useEffect, useRef } = React;
// ----- Design tokens (cohérents avec le site) -----
const C = {
blanc: "#FFFFFF", albatre: "#FAF9F6", encre: "#1B1D1C",
ardoise: "#5B7C99", ardoiseF: "#3D5468",
sauge: "#5C6F5C", saugeF: "#48584A",
gris: "#737373", grisC: "#9A9A95", trait: "#E4E1DA"
};
const SERIF = "'Fraunces', Georgia, serif";
const BODY = "'Archivo', system-ui, sans-serif";
const CAL_LINK = "hugo-groslambert/diagnostic1h";
const CAL_ORIGIN = "https://cal.eu";
// =====================================================
// MOTEUR FISCAL — fonctions pures, faciles à maintenir
// (taux à ajuster ici si la loi de finances change)
// =====================================================
const TAUX = {
IS_BAS: 0.15, IS_HAUT: 0.25, IS_SEUIL: 42500,
FLAT_TAX: 0.314, // PFU : 12,8 % IR + 18,6 % PS
TMI: 0.30, // tranche marginale estimée
CHARGES_SAS: 0.80, // cotisations ≈ 80 % du net (assimilé salarié)
CHARGES_SARL: 0.45, // cotisations ≈ 45 % du net (TNS)
QUOTE_PART: 0.05 // mère-fille : quote-part de frais et charges
};
// IS progressif : 15 % jusqu'à 42 500 €, 25 % au-delà
function calculateIS(base) {
const bas = Math.min(Math.max(base, 0), TAUX.IS_SEUIL);
const haut = Math.max(0, base - TAUX.IS_SEUIL);
return bas * TAUX.IS_BAS + haut * TAUX.IS_HAUT;
}
function calculateFlatTax(montant) {
return montant * TAUX.FLAT_TAX;
}
// Voie rémunération : enveloppe brute -> charges sociales -> IR.
// (La rémunération étant déductible de l'IS, elle n'est pas frappée d'IS.)
function calculateRemuneration(enveloppe, forme) {
const ratio = forme === "SAS" ? TAUX.CHARGES_SAS : TAUX.CHARGES_SARL;
const netImposable = enveloppe / (1 + ratio);
const social = enveloppe - netImposable;
const ir = netImposable * TAUX.TMI;
const net = netImposable - ir;
return { brut: enveloppe, social, netImposable, ir, net };
}
// Voie dividendes (sans holding) : IS puis flat tax.
function calculateDividende(brut) {
const is = calculateIS(brut);
const distribuable = brut - is;
const flat = calculateFlatTax(distribuable);
const net = distribuable - flat;
return { brut, is, distribuable, flat, net };
}
// Ingénierie de groupe : IS à l'exploitation puis remontée mère-fille.
// Friction = quote-part 5 % imposée à l'IS de la holding (15 % ici, quote-part faible).
function calculateHolding(brut) {
const is = calculateIS(brut);
const distribuable = brut - is;
const friction = distribuable * TAUX.QUOTE_PART * TAUX.IS_BAS; // ≈ 0,75 %
const conserve = distribuable - friction;
return { brut, is, distribuable, friction, conserve };
}
// ----- helpers format -----
const euro0 = new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR", maximumFractionDigits: 0 });
const fmt = (n) => euro0.format(Math.round(n));
const pct = (n, base) => base > 0 ? Math.round((n / base) * 100) : 0;
// ----- CountUp (rAF) -----
function useCountUp(target, run, duration) {
const [val, setVal] = useState(0);
const ref = useRef();
useEffect(() => {
if (!run) { setVal(0); return; }
const d = duration || 1100;
let raf, start;
const ease = (t) => 1 - Math.pow(1 - t, 3);
const tick = (ts) => {
if (!start) start = ts;
const p = Math.min(1, (ts - start) / d);
setVal(target * ease(p));
if (p < 1) raf = requestAnimationFrame(tick);
};
raf = requestAnimationFrame(tick);
ref.current = raf;
return () => cancelAnimationFrame(raf);
}, [target, run, duration]);
return val;
}
function CountEuro({ value, run, style }) {
const v = useCountUp(value, run);
return {fmt(v)} ;
}
// ----- styles injectés (hachures + responsive) -----
function injectStyles() {
if (document.getElementById("hd-styles")) return;
const s = document.createElement("style");
s.id = "hd-styles";
s.textContent = `
.hd-bar { position: relative; height: 14px; border-radius: 2px; overflow: hidden; background: ${C.albatre}; border: 1px solid ${C.trait}; display: flex; }
.hd-seg { height: 100%; width: 0; transition: width 1.1s cubic-bezier(.2,.7,.3,1); }
.hd-seg-keep { background: ${C.ardoiseF}; }
.hd-seg-keep-good { background: ${C.saugeF}; }
.hd-seg-loss { background-color: rgba(91,124,153,.10); background-image: repeating-linear-gradient(135deg, rgba(91,124,153,.42) 0, rgba(91,124,153,.42) 1.5px, transparent 1.5px, transparent 6px); }
.hd-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: stretch; }
.hd-panel { animation: hdRise .7s both; }
@keyframes hdRise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.hd-inputs { display: grid; grid-template-columns: 1fr 1fr; gap: 26px 36px; }
.hd-curve { stroke-dasharray: 2600; stroke-dashoffset: 2600; transition: stroke-dashoffset 1.8s cubic-bezier(.4,0,.2,1); }
.hd-curve.on { stroke-dashoffset: 0; }
.hd-line { stroke-dasharray: 680; stroke-dashoffset: 680; transition: stroke-dashoffset 1s ease; }
.hd-line.on { stroke-dashoffset: 0; }
.hd-soft { opacity: 0; transition: opacity .8s ease; }
.hd-soft.on { opacity: 1; }
@media (max-width: 820px) {
.hd-grid2 { grid-template-columns: 1fr !important; }
.hd-inputs { grid-template-columns: 1fr !important; gap: 22px !important; }
.hd-recap { gap: 10px !important; }
}
`;
document.head.appendChild(s);
}
// ----- petits composants UI -----
function Eyebrow({ children, color }) {
return {children} ;
}
function SegBar({ segments, run, base }) {
const [w, setW] = useState(false);
useEffect(() => { if (run) { const id = setTimeout(() => setW(true), 60); return () => clearTimeout(id); } else setW(false); }, [run]);
return (
{segments.map((s, i) =>
)}
);
}
function WaterLine({ label, value, kind }) {
const color = kind === "keep" ? C.encre : C.gris;
return (
{kind === "loss" && }
{label}
{kind === "loss" ? "– " : ""}{fmt(value)}
);
}
// =====================================================
// COMPOSANT PRINCIPAL
// =====================================================
function HoldingDiagnostic() {
useEffect(injectStyles, []);
const [step, setStep] = useState("input"); // input | loading | results
const [montant, setMontant] = useState(150000);
const [forme, setForme] = useState("SAS");
const [objectif, setObjectif] = useState("immobilier");
const [hasHolding, setHasHolding] = useState(false);
const [revealB, setRevealB] = useState(false);
const [horizon, setHorizon] = useState("now"); // now | 10y
const ANNUITY10 = (Math.pow(1.04, 10) - 1) / 0.04; // capitalisation d'une annuité 10 ans @ 4 %
const proj = (v) => horizon === "10y" ? v * ANNUITY10 : v;
const capacite = (v) => v / 0.20; // capacité d'acquisition, apport 20 %
const bookCal = (e) => {
if (window.Cal) { if (e) e.preventDefault(); window.Cal("modal", { calLink: CAL_LINK, config: { layout: "month_view" } }); }
};
const brut = Math.max(0, Number(montant) || 0);
const remu = calculateRemuneration(brut, forme);
const div = calculateDividende(brut);
const holding = calculateHolding(brut);
const bestPropre = Math.max(remu.net, div.net);
const gain = holding.conserve - bestPropre;
const lancer = () => {
setStep("loading"); setRevealB(false);
setTimeout(() => {
setStep("results");
setTimeout(() => setRevealB(true), 950);
}, 1000);
};
const reset = () => { setStep("input"); setRevealB(false); };
const objectifs = [
{ id: "immobilier", label: "Construire un parc immobilier hors de portée de l'imposition personnelle" },
{ id: "liquidites", label: "Sécuriser des liquidités pour mon train de vie sans détruire la société" },
{ id: "transmission", label: "Préparer la transmission à mes enfants sans céder mon pouvoir" },
{ id: "diversification", label: "Réinvestir dans une nouvelle activité (diversification)" }
];
return (
Simulateur · Extraction de trésorerie
Combien vous coûte la sortie de votre trésorerie.
Comparez en un instant l'impôt d'une distribution à votre nom face à un transfert vers votre holding.
{/* ---------- ÉTAPE 1 : INPUTS ---------- */}
{step !== "results" &&
Trésorerie à arbitrer
{ const n = e.target.value.replace(/[^\d]/g, ""); setMontant(n === "" ? "" : Number(n)); }}
style={{ fontFamily: SERIF, fontSize: "clamp(30px,4vw,46px)", fontWeight: 500, color: C.encre, border: "none", background: "transparent", outline: "none", width: "100%", padding: 0 }} />
€
setMontant(Number(e.target.value))}
style={{ width: "100%", marginTop: 16, accentColor: C.sauge }} />
Forme de la société d'exploitation
{forme === "SAS" ? "Assimilé salarié — cotisations élevées (~80 % du net)." : "Travailleur non salarié — cotisations modérées (~45 % du net)."}
{forme === "SARL" &&
!
Alerte SARL (gérance majoritaire). La quote-part des dividendes dépassant 10 % du capital et des comptes courants subit les charges sociales. Ce frottement est intégré à notre calcul.
}
{step === "loading" ? "Analyse en cours…" : "Voir le disponible à investir"}
{step !== "loading" && → }
{step === "loading" && Analyse des voies d'extraction… }
}
{/* ---------- ÉTAPE 2 : RÉSULTATS ---------- */}
{step === "results" &&
{horizon === "10y" ? "Même arbitrage répété chaque année, capitalisé à 4 %/an." : "Arbitrage d'une année."}
{/* BLOC A — nom propre */}
Extraction en nom propre
Le frottement fiscal
Deux voies de distribution classiques. Les deux subissent une destruction de valeur massive au profit de la fiscalité personnelle.
{/* Voie rémunération */}
{/* Voie dividendes */}
{/* BLOC B — groupe */}
Ingénierie de Groupe
La doctrine Monarch
La trésorerie remonte vers la holding via le régime mère-fille — préservant ainsi l'intégrité de votre matière première.
Remontée mère-fille
{horizon === "10y" ? "Patrimoine constitué sur 10 ans (réinvesti à 4 %/an)" : "Matière première sécurisée pour réinvestissement"}
{horizon === "10y" ? fmt(holding.conserve) + " / an" : pct(holding.conserve, brut) + " % conservés"}
{/* ---- Impact selon l'objectif ---- */}
{/* Bandeau de synthèse */}
{horizon === "10y" ? "Projetée sur 10 ans (réinvestissement à 4 %/an), la perte de l'inaction face à la meilleure voie en nom propre atteint\u00a0:" : "À objectif identique, l'architecture de Groupe conserve, par rapport à la meilleure voie en nom propre\u00a0:"}
0 ? proj(gain) : 0} run={revealB}
style={{ fontFamily: SERIF, fontSize: "clamp(30px,4vw,48px)", fontWeight: 500, color: C.saugeF, letterSpacing: "-0.01em" }} />
{horizon === "10y" ? "de patrimoine amputé par l'inaction" : "de capital supplémentaire préservé"}
{horizon === "10y" &&
}
En toute transparence
Avantages
{["La trésorerie passe d'une société à l'autre presque sans impôt (≈ 1,25 %).", "Le capital reste mobilisable pour investir (immobilier, autre société…).", "Vous évitez l'impôt de 31,4 % d'une distribution personnelle."].map((t, i) =>
— {t}
)}
Inconvénients & limites
{["L'argent reste dans la holding : le sortir pour vous coûtera l'impôt à ce moment-là.", "Il faut créer et gérer une holding (frais de compta, juridique).", "L'avantage ne joue que si vous réinvestissez, pas pour un usage perso immédiat."].map((t, i) =>
— {t}
)}
↺ Modifier les paramètres
{/* ---------- ÉTAPE 3 : RENDEZ-VOUS ---------- */}
Passer à l'action
Appliquons ces leviers à votre situation réelle.
Cette simulation est une moyenne. Votre schéma, lui, se construit sur-mesure — à partir de vos chiffres et de vos objectifs.
Sans engagement · Confidentiel
Simulation indicative à visée pédagogique — ne constitue pas une consultation juridique ou fiscale.
}
);
}
// ----- sous-composants -----
function Toggle({ options, value, onChange, C }) {
return (
{options.map((o) => {
const on = o.id === value;
return (
onChange(o.id)}
style={{ flex: 1, fontFamily: BODY, fontSize: 14, fontWeight: 600, padding: "13px 10px", cursor: "pointer", border: "none", background: on ? C.encre : "transparent", color: on ? "#fff" : C.encre, transition: "background .25s" }}>
{o.label}
);
})}
);
}
function Voie({ titre, netLabel, net, base, run, segments, lines, C, SERIF, BODY, pct }) {
return (
{titre}
{pct(net, base)} % net
{lines.map((l, i) => )}
{netLabel}
);
}
function DarkLine({ label, value, kind, C, BODY }) {
return (
{kind === "loss" && }
{label}
{kind === "loss" ? "– " : ""}{fmt(value)}
);
}
// Segment de bascule (horizon)
function HSegment({ options, value, onChange, C, BODY }) {
return (
{options.map((o) => {
const on = o.id === value;
return (
onChange(o.id)}
style={{ fontFamily: BODY, fontSize: 13, fontWeight: 600, padding: "9px 16px", cursor: "pointer", border: "none", background: on ? C.encre : "transparent", color: on ? "#fff" : C.gris, transition: "background .25s, color .25s" }}>
{o.label}
);
})}
);
}
// Bloc d'impact adapté à l'objectif visé
function ObjectiveImpact({ objectif, bestPropre, holding, reveal, capacite, C, SERIF, BODY, fmt }) {
const wrap = (children) => (
{children}
);
const eyebrow = (txt, color) => {txt} ;
// --- IMMOBILIER : capacité d'acquisition (apport 20 %) ---
if (objectif === "immobilier") {
const capPropre = capacite(bestPropre);
const capGroupe = capacite(holding.conserve);
const mult = bestPropre > 0 ? capGroupe / capPropre : 0;
return wrap(
{eyebrow("Effet de levier bancaire · apport 20 %")}
Votre capacité d'acquisition immobilière
Un dirigeant n'achète pas comptant : il transforme son net en apport. Avec un financement classique (20 % d'apport), chaque euro conservé en pilote cinq.
En nom propre (meilleure voie)
{fmt(capPropre)}
apport {fmt(bestPropre)}
Via l'architecture de Groupe
{fmt(capGroupe)}
apport {fmt(holding.conserve)}
Soit un actif ≈ {mult.toFixed(1).replace(".", ",")}× plus grand — à effort d'épargne identique. Ne pas structurer, c'est se priver de la moitié de son parc.
);
}
// --- TRANSMISSION : souveraineté / droits de vote ---
if (objectif === "transmission") {
return wrap(
{eyebrow("Le nerf de la guerre · pouvoir décisionnaire")}
Transmettre la valeur sans céder le contrôle
La transmission n'est pas qu'une affaire de fiscalité : c'est d'abord une affaire de droits de vote.
Démembrement classique
Pouvoir partagé
La méthode classique transmet la nue-propriété : vous perdez votre qualité pleine d'associé sur les titres cédés et partagez les décisions stratégiques avec les nu-propriétaires.
Parts de préférence · Monarch
Contrôle verrouillé
majorité de décision conservée
Vous transmettez l'essentiel de la valeur économique à vos héritiers tout en conservant, via des parts de préférence à droit de vote renforcé, la direction du groupe — dans le respect de la prohibition des clauses léonines. Le patrimoine se transmet, le pouvoir de décision reste.
);
}
// --- LIQUIDITÉS : levier société civile (prêt à l'associé) ---
if (objectif === "liquidites") {
return wrap(
{eyebrow("Le levier de la société civile", C.sauge)}
Du train de vie sans détruire la société
La trésorerie remonte en franchise d'impôt vers la holding, puis vous est prêtée via une société civile patrimoniale (SCP) . Vous disposez de liquidités nettes, et les intérêts remboursés capitalisent au sein de votre propre structure au lieu d'être définitivement détruits par l'impôt.
);
}
// --- DIVERSIFICATION : réinvestir via le groupe ---
return wrap(
{eyebrow("Réinvestir via le groupe")}
Une force de frappe intacte pour votre prochaine activité
Capitalisée dans la holding, votre trésorerie finance votre nouvelle activité sans réimposition à l'entrée : l'IS déjà acquitté n'est pas dupliqué. Vous réinvestissez {fmt(holding.conserve)} là où le nom propre ne laisserait que {fmt(bestPropre)} — la différence, c'est votre marge de manœuvre stratégique.
);
}
// Rappel des paramètres dans l'écran de résultats
function ParamRecap({ montant, forme, objectif, hasHolding, onEdit, C, BODY, fmt }) {
const items = [
{ k: "Trésorerie", v: fmt(montant) },
{ k: "Forme", v: forme }
];
return (
{items.map((it) =>
{it.k}
{it.v}
)}
↺ Modifier
);
}
// Courbe de capitalisation — SVG « plan d'architecte »
function GrowthCurveBlueprint({ pPropre, pGroupe, reveal, C, SERIF, BODY, fmt }) {
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 af = (k) => (Math.pow(1.04, k) - 1) / 0.04;
const yrs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const vP = yrs.map((k) => pPropre * af(k));
const vG = yrs.map((k) => pGroupe * af(k));
const maxV = vG[9] || 1;
const X = (k) => x0 + (x1 - x0) * ((k - 1) / 9);
const Y = (v) => yb - (yb - yt) * (v / maxV);
const toPath = (arr) => arr.map((v, i) => `${i === 0 ? "M" : "L"} ${X(i + 1).toFixed(1)} ${Y(v).toFixed(1)}`).join(" ");
const area = [
...vG.map((v, i) => `${X(i + 1).toFixed(1)},${Y(v).toFixed(1)}`),
...vP.map((v, i) => `${X(10 - i).toFixed(1)},${Y(vP[9 - i]).toFixed(1)}`)
].join(" ");
return (
Projection de capitalisation · 10 ans @ 4 %/an
L'effet composé de la déperdition
{/* axe X */}
{[1, 5, 10].map((k) =>
AN {k}
)}
{/* zone de différence */}
{/* tracé nom propre */}
{/* tracé groupe */}
{/* points & labels de fin */}
} label="Nom propre" value={fmt(vP[9])} C={C} BODY={BODY} />
} label="Architecture de Groupe" value={fmt(vG[9])} C={C} BODY={BODY} strong />
);
}
function Legend({ swatch, label, value, C, BODY, strong }) {
return (
{swatch}
{label}
{value}
);
}
// Schéma d'architecture — SVG relationnel statique, style plan d'architecte
function ArchitectureFlowchart({ reveal, C, SERIF, BODY }) {
const [on, setOn] = useState(false);
useEffect(() => { if (reveal) { const id = setTimeout(() => setOn(true), 200); return () => clearTimeout(id); } else setOn(false); }, [reveal]);
const onc = on ? " on" : "";
const box = (x, y, w, h, l2, l1) => (
{l1 ?
{l2}
{l1}
:
{l2}
}
);
const flow = (d, delay, opts) => (
);
const lbl = (x, y, txt, delay, color) => (
{txt} );
return (
Le schéma cible · plan d'architecte
Votre architecture de souveraineté
{/* flux : exploitation -> holding */}
{flow("M 150 452 C 150 380, 300 360, 338 318", 0.1)}
{lbl(205, 392, "Remontée mère-fille", 0.5, C.saugeF)}
{/* flux : holding -> SCP */}
{flow("M 432 318 C 520 360, 600 392, 612 452", 0.8)}
{lbl(575, 392, "Prêt à l'associé", 1.2, C.ardoise)}
{/* flux : holding -> héritiers (actions ordinaires) */}
{flow("M 348 246 C 300 180, 230 140, 178 100", 1.5, { dash: true, color: C.ardoise })}
{lbl(232, 168, "Actions ordinaires (valeur)", 1.9, C.ardoise)}
{/* flux : holding -> dirigeant (actions de préférence) */}
{flow("M 432 246 C 500 180, 560 140, 588 100", 2.1, { w: 2 })}
{lbl(548, 175, "Actions de préférence — contrôle absolu", 2.5, C.encre)}
{/* boîtes */}
{box(60, 40, 230, 60, "HÉRITIERS", "BÉNÉFICIAIRES")}
{box(470, 40, 230, 60, "LE DIRIGEANT")}
{box(270, 248, 220, 72, "HOLDING", "ANIMATRICE")}
{box(30, 452, 240, 60, "SOCIÉTÉ", "D'EXPLOITATION")}
{box(500, 452, 230, 60, "SOCIÉTÉ CIVILE", "PATRIMONIALE")}
{/* cadenas + mention de souveraineté sous le dirigeant */}
Contrôle décisionnel verrouillé
(parts de préférence · vote renforcé)
La valeur économique descend vers vos bénéficiaires, le pouvoir reste verrouillé entre vos mains. C'est précisément ce que l'ingénierie des parts de préférence permet — et qu'un simple arbitrage fiscal ne saura jamais offrir.
);
}
window.HoldingDiagnostic = HoldingDiagnostic;
})();