/* ============================================================
   GARDE GLOBALE — `hidden` DOIT TOUJOURS GAGNER.
   `[hidden]{display:none}` de l'agent utilisateur a une spécificité d'ATTRIBUT (0,1,0) : toute
   règle de CLASSE portant un `display` la bat, et l'élément reste visible alors que le code le
   croit masqué. Ce piège s'est produit DEUX FOIS le 2026-08-04 — le voile du panneau cookies,
   qui interceptait les clics sur « Tout accepter » et « Tout refuser », puis la mention « la
   plus avantageuse », qui s'affichait sur toutes les modalités à la fois. Aucun symptôme commun
   entre les deux, même cause. Cette règle en tête ferme le sujet.
   Vérifié avant pose : aucune règle du site n'affiche délibérément un élément [hidden].
   ============================================================ */
[hidden]{display:none !important}

:root{
  /* CHARTE DU SITE — valeurs identiques à site.css et accueil.css (2026-08-02).
     Les noms de variables sont CONSERVÉS (--brand, --violet, --cyan…) : les renommer aurait
     imposé de toucher aux 400 déclarations qui les utilisent, donc à la structure. Seules
     leurs VALEURS changent. --violet et --cyan ne portent plus de violet ni de cyan : ce sont
     désormais les deux nuances de bleu de la charte, ce qui suffit à éteindre tous les
     dégradés bicolores hérités sans réécrire une seule règle. */
  --ink:#0b2239; --muted:#63696f; --line:#e4e1db; --bg:#ffffff; --bg-soft:#f6f4f0;
  --brand:#1054c9; --brand-d:#0c3f9c; --violet:#0c3f9c; --cyan:#7fb0ff;
  --ok:#0f7a5a; --okbg:#eafaf3; --okline:#bfe6d6;
  --warn:#8a5a12; --warnbg:#fdf8ee; --warnline:#e8d9b8;
  --err:#b3261e; --errbg:#fdf1f0; --errline:#f0c9c5;
  --radius:16px; --shadow:0 10px 30px -12px rgba(11,34,57,.18); --shadow-sm:0 2px 8px rgba(11,34,57,.06);
}
*{box-sizing:border-box}
/* ⚠️ LA GARDE `prefers-reduced-motion` EST OBLIGATOIRE ICI, PAS SEULEMENT DANS site.css.
   site.css pose bien `@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}`, mais
   cette feuille est chargée APRÈS elle sur les pages du simulateur : à spécificité égale, la
   dernière déclaration gagne. La règle nue qui vivait ici ANNULAIT donc la garde de site.css, et
   un visiteur ayant demandé l'arrêt des animations subissait quand même le défilement animé
   (vérifié en émulant `reduce` : 17 images d'animation au lieu d'un saut). */
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{margin:0;font-family:'Inter',system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  color:var(--ink);background:var(--bg);line-height:1.6;-webkit-font-smoothing:antialiased}
h1,h2,h3{line-height:1.15;margin:0;letter-spacing:-.028em}
a{color:inherit;text-decoration:none}
.section-in{max-width:1080px;margin:0 auto;padding:0 20px}

/* ---- animations ---- */
@keyframes fadeUp{from{opacity:0;transform:translateY(22px)}to{opacity:1;transform:none}}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
@keyframes blob{0%,100%{border-radius:42% 58% 60% 40%/45% 45% 55% 55%}50%{border-radius:60% 40% 45% 55%/55% 60% 40% 45%}}
.reveal{animation:fadeUp .7s both}
.b-card:nth-child(2),.how-step:nth-child(2){animation-delay:.08s}
.b-card:nth-child(3),.how-step:nth-child(3){animation-delay:.16s}
@media(prefers-reduced-motion:reduce){.reveal{animation:none}}

/* ---- buttons ---- */
.btn{display:inline-flex;align-items:center;gap:.4em;justify-content:center;border:0;cursor:pointer;
  background:linear-gradient(135deg,var(--brand),var(--brand));color:#fff;font:inherit;font-weight:700;
  padding:13px 22px;border-radius:12px;box-shadow:0 8px 20px -8px rgba(16,84,201,.6);
  transition:transform .15s ease,box-shadow .15s ease,filter .15s}
.btn:hover{transform:translateY(-2px);filter:brightness(1.05);box-shadow:0 12px 26px -8px rgba(16,84,201,.7)}
.btn:active{transform:translateY(0)}
.btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none;filter:grayscale(.3)}
.btn-lg{padding:16px 28px;font-size:1.05rem;border-radius:14px}
.btn-sm{padding:9px 16px;font-size:.9rem;border-radius:10px}
.btn-ghost{background:#fff;color:var(--brand);border:1.5px solid var(--line);box-shadow:none}
.btn-ghost:hover{background:var(--bg-soft);filter:none}

/* ---- nav ---- */
.nav{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.85);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line)}
.nav-in{max-width:1080px;margin:0 auto;padding:12px 20px;display:flex;align-items:center;justify-content:space-between}
.brand{display:flex;align-items:center;gap:9px;font-weight:700;font-size:1.05rem}
.brand-mark{display:grid;place-items:center;width:34px;height:34px;border-radius:10px;
  background:linear-gradient(135deg,var(--brand),var(--brand));font-size:1rem}

/* ---- hero ---- */
.hero{position:relative;overflow:hidden;
  background:radial-gradient(1200px 500px at 80% -10%,rgba(16,84,201,.16),transparent 60%),
             radial-gradient(900px 500px at 0% 10%,rgba(11,34,57,.06),transparent 55%),
             linear-gradient(180deg,#f6f4f0,#ffffff)}
.hero-in{max-width:1080px;margin:0 auto;padding:64px 20px 72px;display:grid;
  grid-template-columns:1.1fr .9fr;gap:40px;align-items:center}
.eyebrow{display:inline-block;font-weight:700;font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--brand);background:#eaf1fe;padding:6px 12px;border-radius:999px;margin-bottom:18px}
.eyebrow.center{display:block;width:max-content;margin:0 auto 14px}
.hero-copy h1{font-size:clamp(2rem,4.6vw,3.2rem);font-weight:700;letter-spacing:-.02em}
.hero-copy h1 .hl{background:linear-gradient(120deg,var(--brand),var(--brand),var(--brand));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.lede{font-size:1.12rem;color:var(--muted);margin:18px 0 26px;max-width:38ch}
.lede strong{color:var(--ink)}
.hero-cta{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.hero-note{font-size:.85rem;color:var(--muted)}
.trust{list-style:none;display:flex;flex-wrap:wrap;gap:18px;padding:0;margin:28px 0 0;font-size:.9rem;color:var(--ink);font-weight:500}
.trust li{display:flex;align-items:center;gap:7px}

/* hero art */
.hero-art{position:relative;min-height:300px;display:grid;place-items:center}
.art-blob{position:absolute;inset:10% 8%;background:linear-gradient(135deg,var(--brand),var(--brand));
  filter:blur(2px);opacity:.16;animation:blob 9s ease-in-out infinite}
.art-card{position:relative;background:#fff;border:1px solid var(--line);border-radius:18px;
  box-shadow:var(--shadow);padding:18px 20px;display:flex;align-items:center;gap:14px;animation:floaty 6s ease-in-out infinite}
.art-1{z-index:2}
.art-2{margin-top:18px;margin-left:40px;animation-delay:1.2s;min-width:230px}
.art-ico{display:grid;place-items:center;width:46px;height:46px;border-radius:12px;font-size:1.4rem;
  background:linear-gradient(135deg,#eaf1fe,#eaf1fe)}
.art-k{font-size:.74rem;color:var(--muted);font-weight:600}
.art-v{font-size:1.55rem;font-weight:700;color:var(--ok);line-height:1.1}
.art-bar{height:9px;border-radius:99px;background:#eaf1fe;margin-top:8px;overflow:hidden}
.art-bar i{display:block;height:100%;background:linear-gradient(90deg,var(--brand),var(--cyan))}

/* ---- benefits ---- */
.benefits{padding:54px 0;background:var(--bg)}
.b-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.b-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:26px 22px;
  box-shadow:var(--shadow-sm);transition:transform .18s,box-shadow .18s}
.b-card:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
.b-ico{width:54px;height:54px;border-radius:14px;display:grid;place-items:center;font-size:1.6rem;margin-bottom:14px;color:#fff}
.grad-a{background:linear-gradient(135deg,#0f7a5a,#0f7a5a)}
.grad-b{background:linear-gradient(135deg,#16324a,#0b2239)}
.grad-c{background:linear-gradient(135deg,var(--brand),var(--brand))}
.b-card h3{font-size:1.12rem;margin-bottom:8px}
.b-card p{color:var(--muted);margin:0}

/* ---- simulateur ---- */
.sim{padding:56px 0;background:var(--bg-soft)}
.sim-head{text-align:center;margin-bottom:30px}
.sim-head h2{font-size:clamp(1.5rem,3vw,2.1rem);font-weight:700;letter-spacing:-.01em}
.sub{color:var(--muted);margin:.4rem 0 0;font-size:.875rem}
.sim-shell{max-width:1000px;margin:0 auto;background:#fff;border:1px solid var(--line);
  border-radius:22px;box-shadow:var(--shadow);padding:14px 14px 6px;overflow:hidden;
  /* CALAGE DU DÉFILEMENT ENTRE ÉTAPES — la correction du « la page saute » du 2026-08-05.
     `gotoStep()` amène ce bloc en haut de l'écran à chaque changement d'étape. Sans cette marge,
     `block:'start'` l'alignait sur le haut du VIEWPORT, c'est-à-dire SOUS l'en-tête, qui est
     `position:sticky` : le bandeau d'étapes (54 px au bureau, 95 px sur mobile) était
     intégralement recouvert à chaque transition, et le visiteur perdait le fil du parcours.
     `--nav-h` est la hauteur RÉELLE de l'en-tête, mesurée et republiée à chaque
     redimensionnement par assets/nav.js. Une valeur en dur mentirait au premier changement de
     l'en-tête — ce qui vient précisément d'arriver, la barre étant passée de 89/158 px à 69/76.
     Le repli `72px` couvre la fenêtre avant l'exécution du script et le cas où il ne charge pas.
     Les 14 px supplémentaires sont l'air entre l'en-tête et le bloc : collé, il donne
     l'impression d'être coupé. */
  scroll-margin-top:calc(var(--nav-h, 72px) + 14px)}
.steps{display:flex;gap:6px;list-style:none;padding:10px 8px 4px;margin:0;font-size:.8125rem;color:var(--muted);font-weight:500}
.steps li{flex:1;text-align:center;padding:8px 4px;border-bottom:3px solid var(--line);transition:.2s}
.steps li.on{color:var(--brand);border-color:var(--brand)}
.card{padding:18px 22px 10px}
/* écrans 1–4 = formulaires simples : contenu centré, pas étiré sur 1000px */
#step1,#step2,#step3,#step4{max-width:660px;margin:0 auto}
/* écran 5 (catalogue + panier) utilise toute la largeur du conteneur élargi */
.card-t{font-size:1.3rem;font-weight:600;color:#1e293b;letter-spacing:-.01em;margin-bottom:4px}
.card-s{color:var(--muted);font-size:.875rem;margin:.15rem 0 14px}

/* choice / options */
.choice{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:8px}
.opt{display:flex;align-items:center;gap:9px;justify-content:flex-start;background:#fff;border:1.5px solid var(--line);
  border-radius:14px;padding:16px;font:inherit;font-weight:600;color:var(--ink);cursor:pointer;text-align:left;transition:.15s}
.opt:hover{border-color:var(--brand);background:#faf9f7}
.opt.sel{border-color:var(--brand);background:#eaf1fe;box-shadow:0 0 0 3px rgba(16,84,201,.15)}
.opt-i{font-size:1.15rem}
@media(max-width:480px){.choice{grid-template-columns:1fr}}

/* fields */
.field{margin:10px 0}
label{display:block;font-size:.8125rem;font-weight:500;color:#475569;margin-bottom:5px}
input,select{width:100%;padding:10px 12px;border:1px solid #cfcbc3;border-radius:8px;font:inherit;font-size:.875rem;background:#fff;color:var(--ink);transition:.15s}
input:focus,select:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(16,84,201,.15)}
/* CONSIGNE SOUS UN CHAMP. Discrète, mais LISIBLE — ce n'est pas la même chose.
   🔴 Corrigé le 2026-08-06 : #8b9099 donnait 3,21:1 sur blanc et 2,92:1 sur `--bg-soft`, sous le
   seuil de 4,5:1 que ce projet s'impose (lisibilité au soleil sur un écran de téléphone).
   `--muted` #63696f donne 5,55:1 pour la même discrétion apparente — c'est le gris déjà employé
   par les libellés du panneau, donc aucune couleur nouvelle n'entre dans la charte.
   ⚠️ Ne pas « alléger » ce gris sans remesurer : 6 consignes du simulateur en dépendent. */
.hint{font-size:.72rem;line-height:1.45;color:var(--muted);margin:4px 0 0}

/* SAISIE D'UN NOMBRE + SON UNITÉ (effectif, 2026-08-06). La règle globale `input{width:100%}`
   étirait le champ sur toute sa colonne pour y accueillir deux chiffres. Ici la largeur est
   fixée et l'unité posée à côté, ce qui dit au premier coup d'œil ce qu'on attend.
   `width` ET `flex:none` : sans le second, le champ se ré-étirerait dans le conteneur flex. */
.eff-saisie{display:flex;align-items:center;gap:9px}
.eff-saisie input{width:100px;flex:none;text-align:right;font-variant-numeric:tabular-nums}
.eff-unite{font-size:.875rem;color:var(--muted)}

.grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:480px){.grid{grid-template-columns:1fr}}
.actions{display:flex;gap:10px;justify-content:flex-end;margin:16px 0 12px;flex-wrap:wrap}

/* messages / banner */
.msg{padding:11px 13px;border-radius:10px;font-size:.9rem;margin:12px 0 0}
.msg-err{background:var(--errbg);color:var(--err);border:1px solid var(--errline)}
.msg-ok{background:var(--okbg);color:var(--ok);border:1px solid var(--okline);font-weight:600}

/* harmonisation typo simulateur : boutons plus fins, non surdimensionnés */
.sim-shell .btn{font-weight:600}
.sim-shell .btn-lg{font-size:.95rem;padding:12px 22px}
.opco-banner{padding:14px 16px;border-radius:12px;margin-bottom:10px;font-size:1.05rem}
.opco-banner.ok{background:var(--okbg);color:var(--ok);border:1px solid var(--okline)}
.opco-banner.warn{background:var(--warnbg);color:var(--warn);border:1px solid var(--warnline)}
.tag{font-size:.8rem;opacity:.9;font-weight:700}

/* estimation result */
.lead{font-size:1.05rem;color:var(--muted);margin:6px 0 2px;text-align:center}
.amount{font-size:clamp(2.1rem,6vw,3rem);font-weight:700;text-align:center;margin:0 0 16px;letter-spacing:-.02em;
  background:linear-gradient(120deg,var(--ok),var(--ok));-webkit-background-clip:text;background-clip:text;color:transparent}
.detail{list-style:none;padding:0;margin:0 0 12px}
.detail li{padding:10px 13px;border:1px solid var(--line);border-radius:10px;margin-bottom:7px;font-size:.93rem;background:#faf9f7}
.detail li.cap{color:var(--warn);background:var(--warnbg);border-color:var(--warnline)}
.note{font-size:.8rem;color:var(--muted);text-align:center}

/* ---- how ---- */
.how{padding:56px 0;background:var(--bg)}
.how-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:8px}
.how-step{background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius);padding:26px 22px;position:relative}
.how-n{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;font-weight:700;color:#fff;
  background:linear-gradient(135deg,var(--brand),var(--brand));margin-bottom:12px}
.how-step h3{font-size:1.08rem;margin-bottom:6px}
.how-step p{color:var(--muted);margin:0}
.how-cta{text-align:center;margin-top:30px}

/* ---- footer ---- */
.foot{padding:28px 0;background:#0b2239;color:#8b9099;font-size:.82rem;text-align:center}

/* ---- responsive ---- */
@media(max-width:860px){
  .hero-in{grid-template-columns:1fr;padding:44px 20px 54px}
  .hero-art{order:-1;min-height:220px}
  .b-grid,.how-grid{grid-template-columns:1fr}
}

/* ===== Écran résultat : contrôles intra/inter + curseur stagiaires ===== */
.result-controls{display:flex;flex-direction:column;gap:14px;margin:0 0 18px;padding:14px 16px;
  background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius)}
.rc-row{display:flex;flex-direction:column;gap:8px}
.rc-label{font-size:.9rem;font-weight:600;color:var(--ink)}
.toggle-intra{display:inline-flex;background:#fff;border:1px solid var(--line);border-radius:12px;padding:3px;gap:3px;align-self:flex-start}
.toggle-intra .seg{border:0;background:transparent;font:inherit;font-weight:600;color:var(--muted);
  padding:8px 14px;border-radius:9px;cursor:pointer;transition:background .15s,color .15s}
.toggle-intra .seg.active{background:linear-gradient(135deg,var(--brand),var(--brand));color:#fff;box-shadow:var(--shadow-sm)}
.result-controls input[type=range]{width:100%;accent-color:var(--brand);cursor:pointer}

/* ===== Recherche entreprise (étape 1) + identification (étape 2) ===== */
.ent-list{list-style:none;margin:10px 0 0;padding:0;border:1px solid var(--line);border-radius:var(--radius);
  overflow:hidden;box-shadow:var(--shadow-sm);background:#fff}
.ent-list li{display:flex;flex-direction:column;gap:2px;padding:10px 14px;cursor:pointer;border-top:1px solid var(--line)}
.ent-list li:first-child{border-top:0}
.ent-list li:hover{background:var(--bg-soft)}
.ent-list li strong{color:var(--ink);font-size:.95rem}
.ent-list li span{color:var(--muted);font-size:.82rem}
.ident-recap{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:0 0 18px}
.ident-line{margin:2px 0 6px;font-size:.9rem;font-weight:600;color:var(--ink)}
.chk{display:flex;align-items:center;gap:8px;font-size:.85rem;font-weight:500;color:var(--muted);cursor:pointer}
.chk input{width:16px;height:16px;accent-color:var(--brand);cursor:pointer}
@media(max-width:640px){ .ident-recap{grid-template-columns:1fr} }

/* ===== Écran 5 : catalogue + panier + reste à charge ===== */
.spinner{display:flex;align-items:center;gap:10px;margin-top:16px;color:var(--muted);font-weight:600}
.spin{width:18px;height:18px;border:3px solid var(--line);border-top-color:var(--brand);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
/* ── BLOC « PAS DE MONTANT À AFFICHER » — UN SEUL BLOC, UN SEUL ALIGNEMENT ──────────────────
   CORRIGÉ LE 2026-08-08. Ce conteneur n'avait qu'un `padding`. Ses paragraphes héritaient donc
   de deux styles différents : le premier porte `.lead` (1,05 rem, `text-align:center`), les
   suivants sont des `<p>` nus, alignés à gauche à la taille du corps de texte. Résultat à
   l'écran : une phrase unique coupée en deux, première ligne centrée, seconde à gauche, dans
   deux tailles. Le défaut touchait TOUS les messages de cet écran — fonds, suspension, barème
   manquant — parce qu'ils partagent ce conteneur.
   On aligne à GAUCHE et non au centre : c'est le sens de lecture des autres messages du
   parcours (`.card-s`, `.hint`), et un paragraphe de trois lignes centré se lit mal. */
/* ── QUESTION « GÉRANT MAJORITAIRE ? » — sous la note bleue de l'écran 3 ────────────────────
   Détachée de la note par un filet, pas par un second encadré : c'est la SUITE de ce que la
   note vient de dire (« à condition que vous soyez gérant majoritaire »), pas un nouveau sujet.
   Deux boîtes empilées auraient donné l'impression de deux questions. */
.tns-q{margin-top:12px;padding-top:12px;border-top:1px solid var(--line)}
.tns-lbl{font-weight:600;margin:0 0 8px}
.tns-fonds{margin-bottom:12px}
.tns-fonds .tns-lbl{font-weight:500}
.tns-sel{width:100%;max-width:420px;padding:10px 12px;border:1px solid var(--line);
         border-radius:10px;background:#fff;font:inherit}
/* L'aide reste lisible : c'est elle qui permet au visiteur de répondre juste du premier coup. */
.tns-aide{font-size:.9rem;color:var(--muted);margin:10px 0 0;line-height:1.45}

/* ── DISPOSITIF COMPLÉMENTAIRE — une carte À CÔTÉ du barème, jamais une rangée dedans ────────
   Le contraste de couleur avec le bloc de montants est délibéré : ce n'est pas un chiffre de
   plus dans l'addition, c'est une piste conditionnelle. Le lecteur doit voir la différence
   avant même de lire. */
.pec-dispo{margin-top:12px;display:flex;flex-direction:column;gap:8px}
.pec-dispo .pd-carte{border:1px solid #bae6fd;background:#f0f9ff;border-radius:12px;padding:10px 12px}
.pec-dispo .pd-t{font-weight:600;color:#0c4a6e;margin:0 0 2px;font-size:.95rem}
.pec-dispo .pd-m{color:#075985;margin:0;font-size:.9rem}
.pec-dispo .pd-c{color:#0369a1;margin:6px 0 0;font-size:.82rem;line-height:1.45}
.pec-dispo a{color:inherit}

.estim-empty{padding:8px 0;text-align:left}
.estim-empty .lead{text-align:left;font-size:1.05rem;color:var(--fg);margin:0 0 8px}
.estim-empty p{margin:0 0 8px;line-height:1.5}
.estim-empty p:last-child{margin-bottom:0}
/* L'action ne colle pas au texte : elle se détache pour se voir. */
.estim-empty .estim-cta{margin-top:14px;display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.cat-wrap{margin-top:16px}
.cat-search{width:100%;padding:10px 14px;border:1px solid var(--line);border-radius:12px;outline:none;margin-bottom:12px}
/* Plus de boîte à défilement interne (elle était à 460 px). Avec de vraies cards illustrées,
   460 px ne montrent qu'une rangée et demie et la molette se fait piéger dans le cadre. Le
   catalogue est replié par défaut : quand on l'ouvre, on veut le parcourir dans la page. */
.cat-list{padding-right:0}
.cat-fam{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;margin-bottom:14px}
.cat-item{display:flex;justify-content:space-between;align-items:center;gap:14px;
          padding:14px 16px;border:1px solid var(--line);border-radius:14px;background:#fff}
.cat-item:hover{border-color:#c9d4e4}
.ci-txt{display:flex;flex-direction:column;gap:4px;min-width:0}
.ci-txt strong{font-size:.95rem;font-weight:600;color:var(--ink);line-height:1.35}
.ci-meta{display:flex;align-items:center;gap:5px;font-size:.8rem;color:var(--muted)}
.ci-add{flex:0 0 auto;padding:9px 16px;font-size:.85rem}
.ci-add.est-dedans{background:#fff;color:var(--brand);border:1.5px solid #c9d4e4;box-shadow:none}
.recap-bar{background:var(--bg-soft);border:1px solid var(--line);border-radius:var(--radius);padding:16px 18px;margin-bottom:18px}
/* ⚠️ MASQUÉ PAR DÉFAUT, RÉVÉLÉ À ≥900 px — et surtout pas l'inverse. « Votre projet » nomme la
   CARTE de la colonne de travail, qui n'existe qu'en deux colonnes ; sous 900 px la colonne est un
   simple empilement et ce titre n'aurait rien à nommer. Un `<h3>` est `display:block` par défaut :
   sans cette ligne il s'afficherait sur mobile, où l'écran 5 est déjà mesuré au plus juste. */
.ec5-work-t{display:none}
.recap-sel{margin-bottom:12px}
.recap-sel h3{margin:0 0 8px;font-size:.95rem;font-weight:600}
.panier-list{list-style:none;margin:0;padding:0}
/* L'astuce d'effet de groupe, sous les sélecteurs de stagiaires.
   ⚠️ ELLE N'UTILISE PAS `.hint` — mesuré le 2026-08-06, `.hint` est à #8b9099, soit 3,21:1 sur
   blanc : sous le seuil de 4,5 que ce projet s'impose. `--muted` donne 5,55:1 pour la même
   discrétion apparente. Ne pas « harmoniser » l'une sur l'autre sans remesurer. */
.pi-astuce{margin:9px 0 0;font-size:.78rem;line-height:1.45;color:var(--muted)}
.panier-empty{color:var(--muted);font-size:.85rem;padding:6px 0}
.panier-item{display:flex;flex-direction:column;gap:8px;padding:12px 0;border-bottom:1px solid var(--line)}
.pi-head{display:flex;align-items:center;gap:8px}
.pi-head strong{font-size:.9rem}
.pi-duree{font-size:.76rem;color:var(--muted)}
.pi-del{margin-left:auto;border:0;background:transparent;color:var(--err);cursor:pointer;font-size:1rem;line-height:1}
/* ⚠️ `auto` SUR LE STEPPER, PAS `1fr` — corrigé le 2026-08-08, mesuré avant et après.
   `1fr 1fr` donnait la MOITIÉ de la rangée au compteur de stagiaires, qui n'a jamais besoin que
   de sa largeur naturelle (~126 px, `.pi-nb-grp` est en `width:fit-content`). À 1280 px, les
   modalités tombaient donc à 245 px, dont 90 px pour le libellé une fois la puce, le prix, les
   gaps et le padding retirés — et « Présentiel individuel », qui demande ~133 px, cassait en deux
   lignes. Le défaut ne se voyait QU'EN DESKTOP : sous 480 px la règle une-colonne plus bas rendait
   déjà toute la largeur au libellé, ce qui l'a longtemps fait passer pour un problème de mobile.
   `minmax(0,1fr)` et non `1fr` : un `1fr` nu a pour minimum `auto`, donc refuse de descendre sous
   la taille de son contenu et pousserait la grille en débordement au lieu de laisser le libellé
   se réduire. */
/* Le filet du bloc modalité est porté ICI et non par `.pi-modalites` (2026-08-08) : le fieldset
   n'occupe que la première colonne de cette grille, son filet s'arrêtait donc avant le stepper —
   362 px sur une rangée de 500 px, mesuré à 1280 px. Sur `.pi-ctrls`, il traverse la rangée
   entière et sépare vraiment l'en-tête de formation de ses contrôles. */
.pi-ctrls{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start;
          border-top:2px solid #e6ebf2;padding-top:9px}
.pi-field{display:flex;flex-direction:column;gap:4px;font-size:.76rem;color:var(--muted)}
.pi-field select{padding:8px 10px;border:1px solid #cfcbc3;border-radius:8px;font:inherit;font-size:.85rem;background:#fff}
/* CHAMP STAGIAIRES — le curseur a été remplacé par un champ numérique encadré de deux boutons
   (2026-08-04). Le curseur ne montrait pas sa borne, se réglait mal au doigt, et interdisait la
   saisie directe : à 12 stagiaires il fallait douze gestes. */
.pi-nb-grp{display:inline-flex;align-items:stretch;border:1px solid #cfcbc3;border-radius:8px;overflow:hidden;background:#fff;width:fit-content}
.pi-nb-pas{width:34px;border:0;background:#f6f4f0;color:var(--encre,#0b2239);font:inherit;font-size:1.05rem;line-height:1;cursor:pointer}
.pi-nb-pas:hover{background:#ece8e1}
.pi-nb-pas:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.pi-nb{width:58px;border:0;border-left:1px solid #e6e2da;border-right:1px solid #e6e2da;
       padding:8px 6px;font:inherit;font-size:.9rem;text-align:center;
       -moz-appearance:textfield;appearance:textfield}
.pi-nb::-webkit-outer-spin-button,.pi-nb::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.pi-nb:focus{outline:2px solid var(--brand);outline-offset:-2px}
/* Barème inconnu : ni vert (éligible), ni rouge (refusé) — c'est une information en attente. */
.pi-pec-inconnu{color:var(--muted);font-weight:500;font-style:italic}
.pi-meta{display:flex;justify-content:space-between;align-items:baseline;gap:10px;flex-wrap:wrap;font-size:.78rem;color:var(--muted)}
/* `.pi-mode` (« Groupe » / « Individuel ») a été retiré du markup le 2026-08-01 — vocabulaire de
   tarification interne qui répétait le curseur de stagiaires. Sa règle est retirée avec lui.
   `.pi-meta` reste en flex : il n'accueille plus qu'un enfant, mais garde son alignement si une
   seconde information y revient un jour. */
.pi-pec{color:var(--ok);font-weight:600}
@media(max-width:480px){.pi-ctrls{grid-template-columns:1fr}}
/* Panneau de prise en charge : 4 tuiles + le CTA. Une ligne sans valeur est masquée en JS
   (attribut hidden), la grille se recompose donc toute seule — pas de trou. */
.totaux{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
.t-row{display:flex;flex-direction:column;gap:3px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:12px 14px;color:var(--ink)}
/* ⚠️ INDISPENSABLE. `[hidden]` est appliqué par la feuille du NAVIGATEUR (display:none) ; toute
   déclaration `display` d'AUTEUR l'écrase. Sans cette règle, `row.hidden = true` n'a aucun effet
   et les lignes du panneau restent affichées avec leur texte de gabarit « — ».
   C'est exactement le bug constaté le 2026-08-01 : panneau « tout à — » alors que les données
   arrivaient correctement. Toute classe de ce fichier qui déclare un `display` ET qu'on masque
   par attribut doit avoir sa propre règle [hidden] — cf. .pec-cta, .reco-badge, .cat-browse. */
.t-row[hidden]{display:none}
.t-k{font-size:.8rem;color:var(--muted);font-weight:500}
.t-row strong{font-size:1.2rem}
/* Note explicative sous une valeur du panneau. Réservée aux montants qui ne se comprennent pas
   seuls — aujourd'hui les salaires remboursés, qui ne sont ni une remise ni un financement de la
   formation. Elle traverse les deux colonnes de la grille pour rester lisible sur une ligne. */
.t-fs{grid-column:1/-1}
/* Prise en charge estimée : c'est LE chiffre que le prospect vient chercher avant de laisser
   ses coordonnées. Il traverse la grille et se lit plus gros que les autres tuiles. */
.t-pecmax{grid-column:1/-1;border-color:#bfe6d6;background:#eafaf3}
.t-pecmax strong{font-size:1.6rem;color:var(--ok)}
.t-note{font-size:.75rem;color:var(--muted);font-weight:400;line-height:1.45;margin-top:2px}
.t-fin strong{color:var(--ok)}
/* 🔴 `.t-reste` RETIRÉ LE 2026-08-06 — code mort. Aucune rangée du gabarit ne porte cette classe :
   le reste à charge n'est pas dans le panneau, il est dans l'estimation rendue par le serveur.
   C'étaient deux règles de couleur qui ne peignaient rien, mais qui décrivaient au lecteur suivant
   une intention fausse — « le reste à charge est bleu ici », alors qu'il est vert ou ambre ailleurs. */

/* ===== HIÉRARCHIE SÉMANTIQUE DU PANNEAU (LOT 4, 2026-08-06) =====
   UN GAIN N'EST PAS UNE LIMITE. Le plafond et le coût horaire étaient rendus en `--ink` (16:1),
   c'est-à-dire au même poids visuel que la prise en charge estimée — alors qu'ils disent l'inverse :
   ce sont des BORNES, pas de l'argent obtenu. Ils passent en `--muted`, mesuré à 5,55:1 sur blanc,
   au-dessus du seuil de 4,5. Le vert reste réservé à ce que le prospect OBTIENT.
   ⚠️ Le libellé de chaque rangée porte déjà l'information (« Plafond annuel », « Coût horaire ») :
   la couleur ne fait que la hiérarchiser, elle ne la remplace jamais. */
.t-row[data-pec="plafond"] > strong,
.t-row[data-pec="couth"] > strong{color:var(--muted)}

/* ===== JAUGE DU TAUX =====
   APLAT, PAS DE DÉGRADÉ. Et un CONTOUR, pas un rail plein : mesuré sur huit gris, aucun ne tient
   À LA FOIS 3:1 sur blanc et 3:1 contre `--ok` — à 3:1 sur blanc, un gris a pratiquement la
   luminance du vert (1,67:1 entre les deux), les deux deviennent indistinguables. Le vert porte
   donc sur le blanc (5,31:1) et le trait #767676 (4,54:1) délimite la course. Sans limite
   perceptible, une barre verte ne dit pas QUELLE PROPORTION — elle ne dit plus rien.
   ⚠️ RÈGLE [hidden] OBLIGATOIRE — cf. l'avertissement de `.t-row[hidden]`. Cette classe déclare un
   `display`, elle écraserait donc le masquage par attribut. Troisième instance du même piège. */
.t-jauge{display:block;height:8px;margin-top:5px;border:1px solid #767676;border-radius:999px;
  background:#fff;overflow:hidden}
.t-jauge[hidden]{display:none}
.t-jauge > i{display:block;height:100%;background:var(--ok)}

/* 🔴 LA JAUGE EST UNE FUITE SI ON L'OUBLIE. Avant le formulaire, `simu_pec_masquee()` renvoie un
   taux FACTICE (99) et le flou ne couvre que le `<strong>`. Une barre remplie à 99 % publierait en
   clair, juste à côté du chiffre flouté, une valeur que le contrat public interdit — et en plus une
   valeur fausse, qui se lirait « presque tout est couvert ».
   Elle disparaît AVEC le flou et PAR LA MÊME CLASSE que lui : une seule source de vérité, donc
   aucun moyen de lever l'un en oubliant l'autre. */
.pec-detail.pec-floute .t-jauge{display:none}

/* Accroche du CTA. Elle traverse la grille comme le bouton et se place juste au-dessus : c'est la
   phrase qui justifie le clic, elle ne doit pas se retrouver dans une colonne à côté d'un plafond.
   Règle [hidden] obligatoire — cf. l'avertissement de .t-row[hidden] ci-dessus. */
.pec-accroche{grid-column:1/-1;margin:6px 0 0;font-size:.9rem;color:var(--ink);text-align:center;line-height:1.5}
.pec-accroche[hidden]{display:none}

/* « Recevoir mon estimation détaillée » — c'est la conversion de toute la page : il traverse la
   grille, il est plus haut que les tuiles, et il reste visible sans scroll sur mobile.
   Toujours aucun montant à côté de lui : les chiffres arrivent APRÈS le clic, dans #estim-wrap. */
.pec-cta{grid-column:1/-1;width:100%;padding:16px 28px;font-size:1.05rem;border-radius:14px;margin-top:2px}
.pec-cta[hidden]{display:none}

/* Formulaire de contact — déplacé de l'écran 3 vers ici le 2026-08-01. Il traverse la grille et
   se substitue au bouton : à ce moment du parcours il n'y a plus qu'une seule action possible.
   Règle [hidden] obligatoire, comme pour toute classe de ce fichier qui déclare un `display`
   et qu'on masque par attribut — cf. l'avertissement de .t-row[hidden]. */
/* ⚠️ CES RÈGLES NE SERVENT PLUS QUE LE REPLI. Depuis le 2026-08-06 le formulaire vit dans un
   `<dialog>` (cf. §MODALE plus bas), qui les réécrit. Elles restent pour le seul cas où
   `showModal()` n'existe pas : le <dialog> est alors ouvert par son attribut `open` et se rend
   DANS LE FLUX, à l'emplacement d'origine — c'est-à-dire exactement l'écran d'avant ce lot. */
.pec-form{grid-column:1/-1;display:flex;flex-direction:column;gap:12px;background:#fff;
          border:1px solid var(--line);border-radius:14px;padding:16px 16px 14px;margin-top:4px}
.pec-form[hidden]{display:none}
.pec-form-t{margin:0;font-weight:700;font-size:1rem;color:var(--ink)}
.pec-form-go{width:100%;padding:14px 24px;border-radius:12px}
.pec-civ select{width:auto;min-width:8rem}
.opt-lbl{font-weight:400;color:var(--muted);font-size:.8rem}
.pec-form-note{margin:0;font-size:.75rem;color:var(--muted);line-height:1.45}
@media(max-width:640px){
  .totaux{grid-template-columns:1fr}
  /* 🔴 `.pec-cta{position:sticky;bottom:12px;z-index:5}` RETIRÉ LE 2026-08-06 — IL N'A JAMAIS COLLÉ.
     `#pec-bloc` porte la classe `.totaux`, qui déclare `overflow:hidden` (voir plus bas, « le
     panneau devient la carte ») pour rogner ses rangées sur le rayon. Or un ancêtre en
     `overflow:hidden` ANNULE tout `position:sticky` descendant. C'est la DEUXIÈME instance du même
     piège : la première (`.sim-shell` au-dessus de 900 px) avait été réparée en `overflow:clip`.
     ⚠️ ON NE RÉPARE PAS CELLE-CI, on la retire. Le bandeau flottant porte désormais le libellé et
     l'action de ce bouton (cf. `cibleBandeau` dans app.js) : deux boutons collants concurrents en
     bas d'un téléphone seraient pires que celui qui manquait.
     Mesuré avant retrait, sur un écran 5 haut de 6 655 px : le bouton n'était visible qu'entre
     scrollY 600 et ~1150 — invisible à l'arrivée (top=885 pour un pli à 844) et parti dès 1200. */
}

/* ===== Estimation chiffrée (écran 5, après le formulaire) =====
   VOLONTAIREMENT PRESQUE VIDE. Le contenu arrive du serveur avec ses styles EN LIGNE, parce que
   le même HTML doit pouvoir partir par email — un client de messagerie ignore cette feuille.
   Habiller ce bloc ici créerait un écart entre ce que voit le prospect à l'écran et ce qu'il
   recevrait dans sa boîte. On ne fournit donc que le cadre : la carte et son espacement. */
.estim-wrap{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:20px 18px;margin-bottom:18px}
.estim-wrap[hidden]{display:none}

/* FILET DE SÉCURITÉ SUR LA LARGEUR (correctif du 2026-08-05).
   Le HTML injecté porte deux <table> dont trois colonnes en `white-space:nowrap` — un plancher
   de largeur que rien ne peut comprimer. Sans cette règle, le débordement ne s'arrêtait à aucun
   ancêtre et mettait TOUTE LA PAGE en défilement horizontal sur téléphone. L'empilement ci-
   dessous règle le cas courant ; ceci garde le cas non prévu DANS la carte. */
.estim-wrap{overflow-x:auto}

/* R13 — CALAGE SOUS L'EN-TÊTE COLLANT (2026-08-06).
   MÊME CONVENTION QUE `.sim-shell` ET `.reco-wrap` : c'est `scroll-margin-top` qui répare, jamais
   un décalage codé dans l'appel de défilement — la valeur suit `--nav-h`, mesurée par nav.js, et
   l'en-tête est déjà passé de 158 à 76 px sur mobile une fois.
   Sans elle, un bloc amené par scrollIntoView cale à top=0 et ses 69 premiers pixels passent SOUS
   l'en-tête. Pour `#estim-wrap` c'était le titre « Votre estimation détaillée » et la ligne
   OPCO / effectif / convention, c'est-à-dire ce qui dit de quoi l'estimation parle ; pour
   `#pec-bloc`, la rangée du nom de l'OPCO ; pour `.rcard`, sa photo.
   Les trois sont désormais des cibles de défilement : révélation du barème (revelerBareme), clic
   sur le bandeau flottant, et « Voir les formations recommandées ». */
.estim-wrap,#pec-bloc,.rcard{scroll-margin-top:calc(var(--nav-h, 72px) + 14px)}

/* ===== État « Mise à jour… » (correctif du saut de mise en page, 2026-08-05) =====
   Le bloc reste DANS LE FLUX pendant le recalcul, avec sa hauteur : il porte encore l'ancien
   rendu, donc il occupe exactement la même place et rien ne remonte derrière lui (le bloc
   « Recommandé pour votre activité » sautait de 461 px, aller et retour, à chaque changement
   de modalité). Voir estimAttente() dans app.js.
   Le contenu est grisé et rendu inerte : il ne doit plus être lu comme un résultat courant —
   c'est la raison pour laquelle il était vidé auparavant, et elle est ici satisfaite sans
   toucher à la mise en page.
   ⚠️ L'opacité porte sur l'ENFANT, jamais sur le bloc : posée sur le bloc, elle s'appliquerait
   aussi au badge ::after, qui doit rester parfaitement lisible. */
.estim-wrap.estim-maj{position:relative}
.estim-wrap.estim-maj>*{opacity:.42;pointer-events:none;transition:opacity .12s linear}
.estim-wrap.estim-maj::after{content:"Mise à jour…";position:absolute;top:10px;right:12px;
  background:var(--brand);color:#fff;border-radius:999px;padding:3px 11px;
  font-size:.78rem;font-weight:600;line-height:1.5;box-shadow:var(--shadow-sm);pointer-events:none}
/* Sur téléphone, le badge passe forcément AU-DESSUS du titre du bloc : réserver sa place
   changerait la hauteur, donc rendrait le saut qu'on vient de supprimer. Il est simplement
   réduit pour n'en masquer que la fin — ce qu'il recouvre est de toute façon grisé et
   explicitement hors lecture le temps du recalcul. */
@media (max-width:640px){
  .estim-wrap.estim-maj::after{top:8px;right:8px;font-size:.7rem;padding:2px 9px}
}

/* ===== Aperçu flouté (écran 5, AVANT le formulaire) =====
   Ce que le prospect voit à la place de son estimation tant qu'il n'a pas laissé ses
   coordonnées : la structure complète et vraie — ses formations, ses libellés — avec des
   montants CONSTANTS sous un flou (cf. includes/estimation_html.php, §APERÇU FLOUTÉ).
   Le flou n'est PAS un dispositif de protection : il se retire à l'inspecteur, et c'est sans
   conséquence puisque ce qu'il cache est faux. Il ne fait que mettre en scène le manque. */
.estim-apercu{position:relative}
/* Le document reste dans le flux : c'est LUI qui donne sa hauteur au bloc, donc l'aperçu fait
   exactement la taille du résultat qu'il annonce et rien ne saute à la révélation. */
.estim-apercu-doc{user-select:none;pointer-events:none}

/* LE FLOU PORTE SUR LES SEULS MONTANTS, JAMAIS SUR LE BLOC.
   Un blur() s'exprime en pixels : réglé pour rester suggestif sur les tuiles à 19 px, il efface
   entièrement un libellé de 12 px sur un écran de téléphone — et le prospect ne voit plus ce
   qu'il rate, qui est toute la raison d'être de cet écran. En ne floutant que les chiffres,
   « Coût total », « Financé par l'OPCO », « Reste à charge » et les noms de formations restent
   NETS À TOUTE TAILLE : la lisibilité est garantie par construction, pas par réglage.
   inline-block : un filter sur un inline pur bave hors de sa ligne. */
.estim-mtn{display:inline-block;filter:blur(5px);opacity:.75}
@media(max-width:560px){ .estim-mtn{filter:blur(4px)} }
@media(prefers-reduced-motion:reduce){ .estim-mtn{filter:blur(4px)} }

/* ===== Panneau : le barème SOUS le bouton, ses montants floutés (2026-08-05) =====
   Même principe que l'aperçu, et même garantie : ce qui est flouté ici est FAUX côté serveur
   (cf. simu_pec_masquee dans includes/profil.php). Le flou ne protège rien, il annonce.
   Le masque tombe à la révélation : `pec-floute` est retirée dès que le jeton de lead est en
   main, et le panneau reçoit alors les vraies valeurs par api/estimation.php. */
/* ===== Demande hors catalogue =====
   Le déclencheur est un LIEN, pas un bouton plein : c'est une porte de secours pour qui ne
   trouve pas sa formation, elle ne doit pas concurrencer le catalogue ni le bouton
   d'estimation. Une fois ouvert, en revanche, son bouton d'envoi est un vrai bouton — à ce
   moment-là c'est l'action que le prospect a choisie. */
.hc-toggle{display:inline-block;margin-top:14px;padding:0;border:0;background:none;
  font:inherit;font-size:.85rem;color:var(--brand);text-decoration:underline;cursor:pointer}
.hc-toggle:hover{color:var(--brand-d)}
.hc-form{margin-top:12px;padding:14px 16px;background:var(--bg);border:1px solid var(--line);
  border-radius:12px}
.hc-form[hidden]{display:none}
.hc-form textarea{width:100%;box-sizing:border-box;font:inherit;padding:10px 12px;
  border:1px solid var(--line);border-radius:10px;resize:vertical}
.hc-go{width:100%;margin-top:4px}

/* Porte de sortie du panier vide : c'est le SEUL appel à l'action de l'écran dans cet état,
   donc il a le poids d'un bouton principal, pas d'un lien discret. */
.recap-go{width:100%;margin-top:12px}
.recap-go[hidden]{display:none}
/* Cible du bouton ci-dessus. MÊME CONVENTION QUE `.sim-shell` : c'est `scroll-margin-top` qui
   cale le défilement sous l'en-tête sticky, jamais un offset calculé en JS. Sans cette ligne,
   `block:'start'` amène le bloc à 0 px du haut du viewport — donc entièrement derrière
   l'en-tête, mesuré à 0 px en recette. */
.reco-wrap{scroll-margin-top:calc(var(--nav-h, 72px) + 14px)}

.pec-detail{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.pec-detail.pec-floute [data-pec="taux"] strong,
.pec-detail.pec-floute [data-pec="plafond"] strong,
.pec-detail.pec-floute [data-pec="couth"] strong,
.pec-detail.pec-floute [data-pec="pecmax"] strong,
.pec-detail.pec-floute [data-pec="fs"] strong{display:inline-block;filter:blur(5px);opacity:.75}
/* ⚠️ `tranche` et `branche` ne sont PAS dans la liste : « 0–49 salariés » et le nom de la
   convention ne sont pas des montants. Ce sont eux qui prouvent au prospect qu'on a identifié
   SA situation — les flouter retirerait l'argument sans rien protéger. */

/* Voile : LÉGER, et la carte EN BAS. Deux réglages corrigés le 2026-08-05 après capture.
   1. L'opacité initiale (.55 → .94) blanchissait tout : le tableau devenait fantomatique et la
      mention de bas de bloc illisible. Or ce voile ne cache RIEN — les chiffres qu'il recouvre
      sont faux. Il n'a qu'un rôle : détacher la carte du document. Il doit donc être le plus
      léger possible, sans quoi il efface la structure que cet écran existe pour montrer.
   2. `align-items:flex-end` — centrée, la carte se posait en plein milieu du tableau et masquait
      l'en-tête « Formation par formation » et la colonne « Financé », c'est-à-dire précisément
      ce qu'on veut donner à voir. En bas, elle ne recouvre que la mention légale, et le dégradé
      s'intensifie là où elle se trouve. */
.estim-voile{position:absolute;inset:0;display:flex;align-items:flex-end;justify-content:center;
  padding:16px;background:linear-gradient(180deg,rgba(255,255,255,0) 0%,rgba(255,255,255,.10) 45%,rgba(255,255,255,.62) 100%)}
.ea-carte{max-width:100%;width:min(420px,100%);box-sizing:border-box;text-align:center;
  background:#fff;border:1px solid var(--line);border-radius:14px;padding:18px 16px;
  box-shadow:var(--shadow-sm)}
.ea-lock{color:var(--brand);margin-bottom:6px}
.ea-t{margin:0 0 6px;font-size:1rem;font-weight:700;color:var(--ink);line-height:1.35}
.ea-p{margin:0;font-size:.85rem;color:var(--muted);line-height:1.5}

/* ===== Estimation sur petit écran : le tableau s'EMPILE =====
   Correctif du 2026-08-05, il porte sur le VRAI rendu autant que sur l'aperçu.
   Sur 375 px, la carte laisse ~255 px utiles ; les trois colonnes de montants en `nowrap`
   (« 4 444 € HT ») en réclament ~216 à elles seules, et il restait ~39 px pour le nom de la
   formation. Le tableau ne POUVAIT pas rentrer.
   Tout se fait ici, en CSS externe, sans toucher au HTML à styles en ligne : celui-ci doit
   continuer à partir par email, où cette feuille n'est pas chargée. Les clients de messagerie
   liront donc le tableau classique, ce qui est le comportement voulu là-bas.
   Les deux tables se distinguent par leur `cellspacing` — 8 pour les tuiles, 0 pour le détail.
   C'est l'attribut présent dans le HTML généré ; le sélecteur est explicite plutôt que
   positionnel, parce que la 1re table disparaît dans le cas hors-PDC et qu'un :first-of-type
   désignerait alors le détail. */
@media(max-width:560px){
  /* Les trois tuiles passent l'une sous l'autre : chacune prend toute la largeur. */
  .estim-wrap table[cellspacing="8"] td{display:block;width:auto}

  /* Détail par formation : une formation = un bloc, ses montants en dessous, chacun ÉTIQUETÉ.
     Sans les étiquettes, trois montants empilés ne disent plus lequel est le coût, lequel le
     financement et lequel le reste — l'empilement aurait juste remplacé un débordement par une
     ambiguïté. L'en-tête de colonnes est masqué : il ne surmonte plus rien. */
  .estim-wrap table[cellspacing="0"] th{display:none}
  /* La ligne d'en-tête entière disparaît : ses `th` masqués laisseraient sinon une bande vide
     de 20 px surmontée d'un filet. `:has()` est la règle ; le `th{display:none}` ci-dessus est
     le repli si un navigateur ne le connaît pas — on retombe alors sur cette bande vide, pas
     sur un en-tête qui déborde. */
  .estim-wrap table[cellspacing="0"] tr:has(th){display:none}
  .estim-wrap table[cellspacing="0"] tr{display:block;padding:10px 0;border-bottom:1px solid #e2e8f0}
  .estim-wrap table[cellspacing="0"] tr:last-child{border-bottom:0}
  .estim-wrap table[cellspacing="0"] td{display:block;border-bottom:0!important;
    padding:2px 0!important;text-align:left!important}
  .estim-wrap table[cellspacing="0"] td:nth-child(n+2){display:flex;justify-content:space-between;
    gap:12px;margin-top:2px}
  .estim-wrap table[cellspacing="0"] td:nth-child(n+2)::before{
    font-size:12px;color:#64748b;font-weight:600}
  .estim-wrap table[cellspacing="0"] td:nth-child(2)::before{content:"Coût"}
  .estim-wrap table[cellspacing="0"] td:nth-child(3)::before{content:"Financé"}
  .estim-wrap table[cellspacing="0"] td:nth-child(4)::before{content:"Reste"}
  /* Ligne « format indisponible » : sa cellule vide en colspan=3 n'a rien à étiqueter. */
  .estim-wrap table[cellspacing="0"] td[colspan]{display:none}
}

/* ===== Recommandations sectorielles (écran 5) — GRANDES CARTES =====
   Refonte du 2026-08-02. Les formations sont le CŒUR DE L'OFFRE : elles avaient une vignette de
   48 px dans une liste compacte à deux colonnes, c'est-à-dire le traitement d'une ligne de
   tableau. Elles ont désormais le traitement d'un produit — photo pleine largeur en haut de
   carte, titre lisible, durée, motif, bouton d'action à la base.

   CHARTE MARINE, registre éditorial repris de l'accueil (variables --ac-) :
   le FILET 1 px porte la carte, pas l'ombre ; le bleu est réservé au cliquable (donc au seul
   bouton) ; pas de dégradé, pas de grand rayon. Le liseré vert de la fiche agent est retiré :
   c'était le vocabulaire du CRM, pas celui du site public.

   ⚠️ AUCUN MONTANT SUR CES CARTES, JAMAIS. La durée y est publiée ; durée + montant sur le même
   bloc redonnerait le tarif horaire par une simple division. */
.reco-wrap{background:#fff;border:1px solid var(--line);border-radius:var(--radius);
           padding:24px 24px 26px;margin-bottom:22px}
.reco-head{display:flex;align-items:baseline;gap:10px;margin-bottom:20px;flex-wrap:wrap}
.reco-head h3{margin:0;font-size:1.35rem;font-weight:600;letter-spacing:-.028em;color:var(--ink)}
.reco-badge{font-size:.72rem;font-weight:600;letter-spacing:.02em;padding:4px 11px;border-radius:999px;
            background:#eaf1fe;color:var(--brand-d)}
.reco-badge[hidden]{display:none}

/* 3 cartes / ligne dans la coque de 1000 px, 2 en tablette, 1 en mobile — sans media query :
   auto-fill + minmax fait la bascule sur la largeur RÉELLE du conteneur. */
.reco-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:22px}

/* REPLI DES RECOMMANDATIONS — SOUS 900 px SEULEMENT (2026-08-06).
   Au-dessus, la grille fait trois à quatre colonnes : les 12 cartes tiennent en trois rangées et
   il n'y a rien à replier. C'est la colonne unique du téléphone qui les empile sur 5 255 px, soit
   79 % des 6 655 px de l'écran 5 — le catalogue qui les suit était à +5 840 px du pli.
   `display:none` et non `visibility` : il faut que les cartes cessent d'occuper la hauteur, et
   c'est aussi ce qui empêche `loading="lazy"` de télécharger leurs photos.
   Le bouton est masqué par défaut (donc au bureau) et révélé ici ; c'est le JS qui décide s'il y a
   quelque chose à déplier, via l'attribut `hidden`. */
.reco-plus{display:none}
@media(max-width:899px){
  .reco-list.reco-plie > .rcard:nth-child(n+5){display:none}
  .reco-plus{display:block;width:100%;margin-top:18px;padding:13px 18px;
    background:#fff;border:1.5px solid #c9d4e4;border-radius:12px;color:var(--brand);
    font:inherit;font-weight:600;font-size:.9rem;cursor:pointer}
  .reco-plus:hover{border-color:var(--brand)}
  .reco-plus[hidden]{display:none}
}

.rcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
       border-radius:14px;overflow:hidden;transition:border-color .18s,transform .18s}
.rcard:hover{border-color:#c9d4e4;transform:translateY(-2px)}
/* Le socle transversal (formations « TOUS », sans motif sectoriel) reste plus sourd : l'œil doit
   accrocher d'abord le sectoriel, qui est ce qui déclenche la conversation. */
.rcard--socle{background:var(--bg-soft)}
.rcard--socle .rcard-media{opacity:.92}

/* GRANDE IMAGE, ratio 3/2 comme les fichiers sources (800x534) : aucun recadrage parasite. */
.rcard-media{display:block;position:relative;aspect-ratio:3/2;background:var(--bg-soft);overflow:hidden}
.rcard-img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .4s ease}
.rcard:hover .rcard-img{transform:scale(1.03)}
/* Recadrages des doublons — cf. compteurCadres() dans app.js. Le zoom rend le décentrage
   possible sans laisser apparaître de bord vide. `!important` : ces classes doivent l'emporter
   sur le scale(1.03) du survol, qui vit sur un sélecteur plus spécifique. */
.rcard-img--v1{transform:scale(1.22) translate(-7%,2%) !important}
.rcard-img--v2{transform:scale(1.22) translate(7%,-3%) !important}
.rcard-img--v3{transform:scale(1.3)  translate(1%,7%)  !important}
.rcard-img--v4{transform:scale(1.16) translate(-5%,-6%) !important}
.rcard-img--v5{transform:scale(1.34) translate(6%,5%)  !important}
/* Repli quand ni la formation ni sa famille n'a de photo : deux initiales, pas d'image cassée.
   BANDEAU COURT, PAS UN BLOC 3/2 : sans photo, la carte n'a rien à montrer — lui réserver la
   même hauteur qu'une vraie photo creusait un trou gris de 260 px de haut en mobile. Une carte
   qui a moins à dire prend moins de place. `aspect-ratio:auto` annule le 3/2 de .rcard-media. */
.rcard-media--txt{display:flex;align-items:center;justify-content:center;aspect-ratio:auto;
                  min-height:66px;background:#eef2f7;border-bottom:1px solid var(--line);
                  font-size:1.25rem;font-weight:400;color:#8e99a6;letter-spacing:.12em}

.rcard-corps{padding:16px 18px 4px;flex:1}
.rcard-nom{margin:0;font-size:1rem;font-weight:600;line-height:1.35;color:var(--ink);letter-spacing:-.012em}
.rcard-duree{display:flex;align-items:center;gap:6px;margin:9px 0 0;font-size:.82rem;color:var(--muted)}
.rc-ico{width:14px;height:14px;flex:0 0 14px;display:block}
.rcard-motif{margin:11px 0 0;font-size:.85rem;line-height:1.5;color:#4d5765}

/* Pied collé en bas de carte : `margin-top:auto` aligne TOUS les boutons d'une même rangée,
   quelle que soit la longueur du motif. C'est le point de conversion du bloc. */
.rcard-pied{padding:16px 18px 18px;margin-top:auto}
.rcard-add{width:100%;justify-content:center;padding:12px 18px;font-size:.9rem;
           box-shadow:0 4px 12px -6px rgba(16,84,201,.55)}
/* La carte se soulève déjà au survol : le bouton ne doit pas se soulever DANS la carte qui se
   soulève, les deux mouvements se composent et la carte tressaute. */
.rcard-add:hover,.ci-add:hover{transform:none;box-shadow:0 4px 12px -6px rgba(16,84,201,.55)}
.rcard-add.est-dedans{background:#fff;color:var(--brand);border:1.5px solid #c9d4e4;box-shadow:none}
/* Formation recommandée mais non tarifée : pas de bouton mort, une mention neutre. Le rappel
   reste le chemin pour ces cas — c'est exactement ce que le site vend. */
.rcard-surdevis{display:block;text-align:center;font-size:.8rem;color:var(--muted);
                background:var(--bg-soft);border:1px solid var(--line);border-radius:10px;padding:11px 12px}

/* Bouton de repli du catalogue. Discret : le parcours principal est le bloc « Recommandé »,
   celui-ci n'est qu'une porte de sortie vers l'exhaustif. */
.cat-toggle{width:100%;background:#fff;border:1px solid var(--line);color:var(--brand);
            border-radius:12px;padding:13px 16px;font:inherit;font-size:.9rem;font-weight:600;
            cursor:pointer;margin-bottom:20px}
.cat-toggle:hover{background:var(--bg-soft)}

/* ===== Cards de famille — même grammaire que les cartes « Recommandé » =====
   Même filet, même rayon, même grille respirante : les deux blocs doivent se lire comme un
   seul système. La photo de famille est ici à sa place — elle désigne un domaine, pas une
   formation — donc elle prend toute la largeur de la carte. */
.fam-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:22px}
.fam-card{display:flex;flex-direction:column;text-align:left;background:#fff;border:1px solid var(--line);
          border-radius:14px;overflow:hidden;padding:0;cursor:pointer;font:inherit;
          transition:border-color .18s,transform .18s}
.fam-card:hover{border-color:#c9d4e4;transform:translateY(-2px)}
.fam-img{display:block;position:relative;aspect-ratio:3/2;background:var(--bg-soft);overflow:hidden}
.fam-photo{width:100%;height:100%;object-fit:cover;display:block;transition:transform .4s ease}
.fam-card:hover .fam-photo{transform:scale(1.03)}
.fam-init{display:flex;align-items:center;justify-content:center;width:100%;height:100%;
          font-size:2rem;font-weight:300;color:#9aa3ad;letter-spacing:.06em}
.fam-txt{display:block;padding:16px 18px 18px}
.fam-nom{display:block;font-size:1rem;font-weight:600;color:var(--ink);line-height:1.35;letter-spacing:-.012em}
.fam-pastille{display:inline-block;margin-top:9px;font-size:.75rem;font-weight:500;
              background:var(--bg-soft);color:var(--muted);border-radius:999px;padding:3px 11px}
.cat-back{background:none;border:0;color:var(--brand);font:inherit;font-size:.85rem;font-weight:600;
          cursor:pointer;padding:0 0 14px}
.cat-fam-titre{margin:0 0 16px;font-size:1.35rem;font-weight:600;letter-spacing:-.028em}
.cat-intro{font-size:.85rem;color:var(--muted);margin:0 0 12px}
.cat-browse[hidden]{display:none}

/* ===== Écran 4 : animation « recherche du budget » ===== */
.calc-anim{display:flex;flex-direction:column;align-items:center;gap:16px;padding:34px 10px 30px;text-align:center}
.calc-title{margin:0;font-size:1.2rem;font-weight:700;color:var(--ink);letter-spacing:-.01em}
.calc-spin .spin{width:40px;height:40px;border-width:4px}
.calc-stage{position:relative;width:100%;max-width:360px;aspect-ratio:3/2;min-height:200px;
  border-radius:16px;overflow:hidden;background:linear-gradient(135deg,#eaf1fe,#eaf1fe);box-shadow:var(--shadow-sm)}
.calc-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .3s ease}
.calc-img.show{opacity:1}
.calc-msg{font-weight:600;color:var(--ink);min-height:2.8em;font-size:1.1rem;line-height:1.4;
  max-width:40ch;margin:0 auto;text-align:center;opacity:0;transition:opacity .3s ease}
.calc-msg.show{opacity:1}
.calc-bar{width:100%;max-width:340px;height:8px;background:var(--line);border-radius:99px;overflow:hidden}
.calc-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--brand),var(--violet));transition:width .5s ease}

/* ============================================================
   ÉCRAN 4 — RECHERCHE EN COURS (refonte 2026-08-04)
   Registre du site : le filet porte la structure, pas l'ombre ; le bleu est réservé au signal.
   L'attente est une LISTE D'ÉTAPES qui se cochent, pas une barre qui avance seule — le prospect
   voit ce qui se passe, et l'attente cesse d'être une durée pour devenir un déroulé.
   ============================================================ */
.calc{max-width:620px;margin:0 auto;padding:8px 0 4px}
.calc-title{font-size:1.12rem;font-weight:600;letter-spacing:-.02em;margin:0 0 22px;color:var(--encre,#0b2239)}

/* --- étapes : puce vide -> anneau qui tourne -> coche --- */
.calc-etapes{list-style:none;margin:0 0 22px;padding:0;display:flex;flex-direction:column;gap:11px}
.calc-etapes li{position:relative;padding-left:30px;font-size:.93rem;line-height:1.45;
                color:#9aa6b4;transition:color .35s ease}
.calc-etapes li::before{content:'';position:absolute;left:0;top:.28em;width:15px;height:15px;
                        border-radius:50%;border:1.5px solid #d8dee6;box-sizing:border-box;
                        transition:border-color .35s ease,background .35s ease}
.calc-etapes li[data-etat="encours"]{color:var(--encre,#0b2239);font-weight:500}
.calc-etapes li[data-etat="encours"]::before{border-color:var(--brand,#1054c9);
    border-top-color:transparent;animation:calcSpin .7s linear infinite}
.calc-etapes li[data-etat="fait"]{color:#5b6b7f}
.calc-etapes li[data-etat="fait"]::before{border-color:var(--brand,#1054c9);background:var(--brand,#1054c9)}
/* la coche est dessinée, pas écrite : pas de glyphe qui change d'une police à l'autre */
.calc-etapes li[data-etat="fait"]::after{content:'';position:absolute;left:4.6px;top:.62em;
    width:4px;height:7.5px;border:solid #fff;border-width:0 1.6px 1.6px 0;transform:rotate(45deg)}
@keyframes calcSpin{to{transform:rotate(360deg)}}

.calc-secteur{margin:0 0 14px;font-size:.82rem;letter-spacing:.04em;text-transform:uppercase;
              color:var(--brand,#1054c9);font-weight:600}

/* --- cartes de formations du secteur (squelette puis contenu réel) --- */
.calc-cartes{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:12px}
.calc-c{border:1px solid var(--ligne,#e3e8ef);border-radius:10px;overflow:hidden;background:#fff;
        display:flex;flex-direction:column;min-height:150px}
.calc-c-img{width:100%;aspect-ratio:3/2;object-fit:cover;display:block;background:#f2f4f7}
.calc-c-txt{padding:9px 11px 11px}
.calc-c-nom{display:block;font-size:.84rem;font-weight:600;line-height:1.3;color:var(--encre,#0b2239)}
.calc-c-motif{display:block;margin-top:4px;font-size:.76rem;line-height:1.35;color:#7c8896}
/* apparition : les cartes ne surgissent pas, elles remplacent leur squelette en fondu montant */
.calc-c--vraie{animation:calcIn .42s cubic-bezier(.22,.61,.36,1) both}
@keyframes calcIn{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}

/* --- squelettes : la place est tenue AVANT l'arrivée des données, la page ne saute pas --- */
.sk{display:block;background:linear-gradient(90deg,#eef1f5 25%,#e2e7ee 37%,#eef1f5 63%);
    background-size:400% 100%;animation:skShine 1.35s ease-in-out infinite}
.sk-img{width:100%;aspect-ratio:3/2}
.sk-l1{height:9px;border-radius:3px;margin:11px 11px 0}
.sk-l2{height:9px;border-radius:3px;margin:7px 34% 13px 11px}
@keyframes skShine{from{background-position:100% 0}to{background-position:0 0}}

@media (prefers-reduced-motion:reduce){
  .sk,.calc-etapes li::before{animation:none}
  .calc-c--vraie{animation:none}
}

/* Suggestions d'entreprise : 2 lignes. La 2e porte ce qui départage — activité, effectif, ville. */
.ent-siret{font-style:normal;color:#9aa6b4;font-variant-numeric:tabular-nums}
/* Suggestions sur trois lignes (2026-08-05) : adresse postale puis dirigeant/activité/SIRET.
   L'icône est posée en `flex:none` et le texte tronque tout seul — une adresse longue ne doit
   ni pousser la ligne hors de la liste ni renvoyer le pictogramme à la ligne. */
.ent-l{display:flex;align-items:center;gap:6px;min-width:0}
.ent-l>:not(.ent-ico){overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Le SIRET sort du flux d'ellipse (2026-08-06) : c'est l'IDENTIFIANT de la ligne, et il se
   tronquait (« 8314211770… ») dès qu'une adresse était longue. Tronquer le nom du dirigeant ou
   l'activité coûte une nuance ; tronquer le SIRET coûte la seule donnée qui départage vraiment.
   `flex:none` le sert en entier, l'ellipse mange le texte à sa gauche. */
.ent-l .ent-siret{flex:none;overflow:visible;margin-left:auto;padding-left:8px}
.ent-ico{flex:none;width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;opacity:.62}
.ent-cessee{display:inline-block;margin-left:4px;padding:0 5px;border-radius:3px;
            background:#fdeceb;color:#a02b22;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.ent-li--cessee strong{color:#7c8896}

/* Rappel d'entreprise en tête de l'écran 5 : le prospect doit reconnaître SA société d'un coup
   d'œil, sans relire les quatre écrans précédents. Filet, pas encadré : c'est un repère, pas un
   bloc d'information concurrent du panneau de prise en charge. */
.ent-rappel{margin:0 0 18px;padding:0 0 13px;border-bottom:1px solid var(--ligne,#e3e8ef);
            display:flex;flex-direction:column;gap:3px}
.er-nom{font-size:1rem;font-weight:600;letter-spacing:-.01em;color:var(--encre,#0b2239)}
.er-det{font-size:.82rem;color:#7c8896;font-variant-numeric:tabular-nums}

/* ============================================================
   BANDEAU FLOTTANT DU PANIER
   Le panier est en haut, les cartes en bas : sans ce rappel, l'ajout d'une formation ne produit
   aucun signal visible. Ancré en bas AU CENTRE et non pleine largeur — il doit se lire comme un
   rappel, pas comme une barre d'outils qui ampute la page.
   ============================================================ */
.panier-flot{
  position:fixed;left:50%;bottom:calc(var(--ck-h, 0px) + 22px);transform:translateX(-50%);z-index:70;
  display:flex;align-items:center;gap:12px;
  padding:11px 13px 11px 11px;border:0;border-radius:999px;cursor:pointer;
  font:inherit;font-size:.93rem;color:#fff;background:#0b2239;
  box-shadow:0 4px 10px -4px rgba(11,34,57,.4), 0 18px 40px -18px rgba(11,34,57,.85);
  animation:pf-entree .22s ease-out;
  max-width:calc(100vw - 32px);
}
.panier-flot:hover{background:#16324a}
.panier-flot:focus-visible{outline:2px solid #fff;outline-offset:3px}
@keyframes pf-entree{from{opacity:0;transform:translate(-50%,14px)}to{opacity:1;transform:translate(-50%,0)}}

.pf-n{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
      min-width:28px;height:28px;padding:0 8px;border-radius:999px;
      background:#1054c9;font-weight:700;font-variant-numeric:tabular-nums}
/* Pulsation rejouée UNIQUEMENT quand le compte change (piloté en JS) : une animation qui se
   relance à chaque rendu deviendrait du bruit et cesserait d'être un signal. */
.pf-pulse{animation:pf-pulse .42s ease-out}
@keyframes pf-pulse{0%{transform:scale(1)}38%{transform:scale(1.28)}100%{transform:scale(1)}}

/* Règle [hidden] obligatoire — cf. l'avertissement de `.t-row[hidden]` : la pastille déclare un
   `display`, la feuille du navigateur ne peut donc plus la masquer par attribut. */
.pf-n[hidden]{display:none}

/* LE MONTANT, À CÔTÉ DU COMPTE. Il n'apparaît QU'APRÈS le formulaire (cf. `montantBandeau` dans
   app.js) : avant, aucun chiffre n'est publiable et le panneau lui-même est flouté.
   Fond translucide et non un second aplat plein : deux pastilles bleues côte à côte se liraient
   comme deux compteurs. */
.pf-mt{flex:0 0 auto;display:inline-flex;align-items:center;height:28px;padding:0 9px;
       border-radius:999px;background:rgba(255,255,255,.14);font-weight:700;
       font-variant-numeric:tabular-nums;white-space:nowrap}
.pf-mt[hidden]{display:none}

/* `.pf-go` N'EST PLUS `flex:0 0 auto`. Il porte maintenant le libellé du bouton principal, qui est
   long (« Recevoir mon estimation détaillée »). Il prend donc la place restante et se coupe
   proprement PLUTÔT QUE DE DÉBORDER : un bandeau plus large que la fenêtre fait ÉLARGIR LE
   VIEWPORT par Chrome, et le bandeau se retrouve à moitié injoignable — exactement ce qui était
   arrivé à l'en-tête, 405 px de large dans une fenêtre de 360.
   ⚠️ `min-width:0` est indispensable : un élément flex ne descend pas sous la largeur de son
   contenu sans lui, et l'ellipsis ne se déclenche jamais. */
.pf-go{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:6px;
       padding-left:12px;margin-left:2px;border-left:1px solid rgba(255,255,255,.22);
       font-weight:600}
.pf-lib{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

@media(max-width:560px){
  .panier-flot{left:12px;right:12px;bottom:calc(var(--ck-h, 0px) + 14px);transform:none;
               justify-content:center;border-radius:12px;font-size:.89rem}
  @keyframes pf-entree{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
  /* `.pf-txt` (« formations sélectionnées ») a été RETIRÉ DU MARKUP le 2026-08-06 : le libellé du
     bouton principal occupe cette place, et les deux ensemble ne tenaient sur aucun téléphone. */
  .pf-go{border-left:0;padding-left:0}
}
/* 🔴 RÈGLE SUPPRIMÉE LE 2026-08-05, même défaut que pour `.ap-flot` :
     .ck-bandeau:not([hidden]) ~ .panier-flot{bottom:120px}
   `~` exige un frère SUIVANT, et le bandeau de consentement est en FIN de body : il suit tout le
   monde, donc il n'est le prédécesseur de personne. La règle était inerte, et sa valeur (120 px)
   fausse de toute façon — le bandeau mesure 303 px sur un écran de 390 px.
   Le décalage est maintenant porté par `.panier-flot` et par la règle mobile ci-dessous, via la
   hauteur mesurée `--ck-h` (0 px quand le bandeau est masqué : un seul jeu de règles). */

/* DÉGAGEMENT DU BAS DE PAGE. Le bandeau est `position:fixed` : il ne pousse rien, mais il
   RECOUVRE en permanence les 64 derniers pixels de l'écran. La dernière carte du catalogue
   passait donc dessous sans qu'on puisse jamais la dégager — un élément fixe ne se contourne
   pas en faisant défiler, il faut lui réserver la place en fin de contenu.
   Conditionné par `:has()` : la marge n'existe QUE quand le bandeau est réellement affiché,
   sinon on laisserait un blanc de 88 px au bas d'un simulateur sans panier. Là où `:has()`
   n'est pas connu, on retombe simplement sur le comportement d'avant. */
body:has(.panier-flot:not([hidden])) .sim{padding-bottom:88px}
@media(prefers-reduced-motion:reduce){
  .panier-flot,.pf-pulse{animation:none}
}

/* Étiquette « modalité la plus avantageuse ». Volontairement SANS montant : avant le
   formulaire, le contrat public interdit d'exposer un coût, et reste = coût − financé le
   livrerait. L'orientation se fait par le mot, le chiffre vient après le formulaire. */
.pi-conseil{display:inline-block;margin-left:10px;padding:2px 9px;border-radius:999px;
            font-size:.76rem;font-weight:600;color:#0f7a5a;background:#eafaf3}
.pi-conseil[hidden]{display:none}

/* ============================================================
   MODALITÉS EN RADIOS — remplace la liste déroulante le 2026-08-04.
   Une liste déroulante cachait les options : le prospect ne comparait rien, puisqu'il ne voyait
   qu'une ligne. Tout est affiché, le plafond aligné À DROITE pour que les montants se lisent en
   colonne — c'est ce qui rend la comparaison instantanée.
   ============================================================ */
/* VISIBILITÉ DU BLOC (2026-08-08, option « filet + légende »). Le bloc était intégralement
   transparent — pas de fond, pas de cadre — et sa légende en gris clair : il fallait le chercher.
   Le renfort passe par la HIÉRARCHIE et non par une boîte : un filet qui le détache de l'en-tête
   de formation, et une légende qui passe du gris au marine.
   POURQUOI PAS UN ENCADRÉ : un cadre aurait coûté ~24 px de padding latéral, pris directement sur
   la largeur du libellé (203 px à 1280 px) que le lot précédent venait de dégager. Ici le coût en
   largeur est nul.
   La graisse reste à 600 : le contraste vient du marine et du filet, l'alourdir en plus rendrait
   la légende plus présente que les modalités qu'elle annonce.
   LE FILET EST SUR `.pi-ctrls`, PAS ICI — il doit traverser la rangée entière, stepper compris ;
   posé sur ce fieldset il s'arrêtait à la première colonne. Ne pas le rapatrier.
   Aucun trait n'existait ici : la seule bordure du bloc formation est `.panier-item{border-bottom}`
   (l. 285), qui sépare les formations entre elles, tout en bas. Rien n'est donc doublé. */
.pi-modalites{border:0;margin:0;padding:0;min-width:0}
.pi-modalites legend{padding:0;margin-bottom:7px;font-size:.8rem;font-weight:600;
                     text-transform:uppercase;letter-spacing:.05em;color:#0b2239}
.pi-modalites-vide{margin:0;font-size:.85rem;color:#8695a6}

.pi-mod{display:flex;align-items:center;gap:12px;padding:8px 11px;border-radius:8px;
        cursor:pointer;border:1px solid transparent;transition:background .13s ease}
.pi-mod:hover{background:#f7f9fc}
.pi-mod input{position:absolute;opacity:0;width:0;height:0}

/* Puce dessinée : la radio native ne se colore pas de façon homogène d'un navigateur à l'autre. */
.pm-puce{flex:0 0 auto;width:16px;height:16px;border-radius:50%;border:2px solid #d3dae4;
         background:#fff;position:relative;transition:border-color .13s ease}
.pi-mod input:checked ~ .pm-puce{border-color:#1054c9}
.pi-mod input:checked ~ .pm-puce::after{content:"";position:absolute;inset:2px;border-radius:50%;
                                        background:#1054c9}
.pi-mod input:focus-visible ~ .pm-puce{outline:2px solid #1054c9;outline-offset:2px}

.pm-lib{flex:1 1 auto;min-width:0;font-size:.9rem;line-height:1.35}
.pi-mod input:checked ~ .pm-lib{font-weight:600}

/* ===== LE FOND COLORÉ APPARTIENT À LA SÉLECTION, ET À ELLE SEULE (2026-08-08) =====
   LE DÉFAUT CORRIGÉ. Deux états différents se disputaient le même signal. « La plus avantageuse »
   peignait la ligne en vert (`.pi-mod-best`, posé une fois d'après la réponse serveur), tandis que
   « sélectionné » n'avait AUCUN fond — seulement la puce bleue et le libellé en gras. Choisir
   « Visio individuel » laissait donc le seul aplat de la liste sur « E-learning » : l'œil suit la
   surface colorée avant la graisse du texte, et désignait la mauvaise ligne.
   Un conseil et un choix ne sont pas de même nature — le premier informe, le second est l'état du
   formulaire. C'est le second qui doit être lisible d'un coup d'œil, parce que c'est lui qui part
   au serveur. Le conseil garde sa pastille, qui se lit sans repeindre toute la ligne.
   `:has()` est le seul moyen de teinter le LABEL depuis la radio qu'il contient — un combinateur
   `~` ne remonte pas au parent. Le fichier s'en sert déjà (cf. `body:has(.panier-flot…)`).
   ⚠️ APRÈS `.pi-mod:hover`, JAMAIS AVANT : les deux règles pèsent le même poids de spécificité
   (0,2,1), donc seul l'ordre départage. Placée avant, la sélection disparaissait au survol. */
.pi-mod:has(input:checked){background:#eef3fd;border-color:#c7d8f7}
.pi-mod:has(input:checked):hover{background:#e6eefb}

/* PASTILLE INLINE, À LA SUITE DU LIBELLÉ (2026-08-08 — remplace la mise à la ligne).
   L'ancien commentaire disait que la mention en ligne « repoussait le plafond et cassait
   l'alignement des montants ». C'était vrai TANT QUE la rangée faisait 245 px : à cette largeur,
   n'importe quoi ajouté au libellé poussait le prix. La cause était la grille `1fr 1fr` de
   `.pi-ctrls`, corrigée plus haut — pas la mention. Le prix ne peut d'ailleurs pas être poussé :
   il est `flex:0 0 auto` avec `white-space:nowrap`, c'est le LIBELLÉ qui se réduit (`min-width:0`).
   `nowrap` sur la pastille : une étiquette de 5 mots coupée en deux ne se lit plus comme une
   étiquette. Elle se place donc entière, ou elle passe entière à la ligne suivante.
   ⚠️ LA RÈGLE `[hidden]` D'ABORD. `[hidden]{display:none}` de l'agent utilisateur a une
   spécificité d'attribut (0,1,0), battue par n'importe quelle règle de classe portant un
   `display` : sans cette ligne, la mention s'affichait sur TOUTES les modalités et l'étiquette
   ne distinguait plus rien. Le piège revient à chaque `display` posé sur un élément piloté par
   `hidden` — il a resservi ici, puisqu'on passe de `block` à `inline-block`. */
.pm-conseil[hidden]{display:none !important}
.pm-conseil{display:inline-block;margin-left:8px;padding:2px 8px;border-radius:10px;
            font-size:11px;font-weight:600;line-height:1.45;white-space:nowrap;
            color:#0f7a5a;background:#eafaf3}
/* REPLI SOUS 560 px — décidé sur mesure, pas par précaution. La pastille fait 180 px à elle
   seule ; sous 560 px le libellé entier ne dispose que de 121 à 226 px. Elle ne peut donc pas
   tenir à la suite du texte, et une pastille rejetée seule sur la ligne suivante est un objet
   qui flotte sans rattachement visible. On revient au libellé simple, sans fond ni arrondi :
   c'est le comportement d'origine, et il reste le bon à cette largeur. */
@media(max-width:560px){
  .pm-conseil{display:block;margin-left:0;padding:0;border-radius:0;font-size:.75rem;
              line-height:1.35;white-space:normal;background:none}
}

.pm-plafond{flex:0 0 auto;font-size:.9rem;font-weight:600;color:#0b2239;
            font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.pm-plafond-vide{color:#8695a6;font-weight:400}

/* Mention de règle de vente. Registre d'AVERTISSEMENT, pas d'erreur : la modalité reste
   sélectionnable — c'est une information, pas un refus. D'où l'ocre plutôt que le rouge.
   ⚠️ Règle [hidden] : cf. la garde globale en tête de fichier. */
.pm-alerte{display:block;font-size:.75rem;color:#8a5a12;line-height:1.35}
.pi-mod-alerte .pm-lib{color:#5b6b7f}

/* `.pi-mod-best` NE PEINT PLUS LA LIGNE (2026-08-08) — cf. le bloc sélection plus haut. La classe
   reste posée par app.js (`peindreModalites`) et reste utile comme prise : elle dit quelle ligne
   porte le conseil, sans se disputer le fond avec la sélection. Son seul rendu est désormais la
   pastille `.pm-conseil`. Ne pas lui redonner de `background` : ce serait rouvrir le défaut. */
.pi-mod-indispo{opacity:.5}
.pi-mod-indispo .pm-plafond{color:#8695a6}

@media(max-width:620px){
  .pi-mod{gap:8px;padding:7px 8px}
  .pm-lib,.pm-plafond{font-size:.85rem}
}

/* ===== Fiabilité de la donnée (2026-08-05) =====
   TROIS ÉTATS, TROIS FORMES — et c'est la forme qui porte l'information, pas la couleur :
   carré plein = certain, rond plein = estimé, rond pointillé = absent. Un daltonien lit les
   trois, et elles restent distinctes en niveaux de gris ou à l'impression.
   La pastille ne dit qu'un mot ; la phrase qui explique ce que le pourcentage MESURE est portée
   par `title` — elle ne tient pas dans une pastille et elle ne doit pas être perdue. */
.fia{display:inline-flex;align-items:center;gap:6px;font-size:.72rem;font-weight:700;
  padding:2px 9px;border-radius:999px;border:1px solid;letter-spacing:.01em;white-space:nowrap;
  vertical-align:middle}
.fia::before{content:"";width:7px;height:7px;border-radius:2px;background:currentColor;flex:none}
.fia-ok{color:var(--ok);background:var(--okbg);border-color:var(--okline)}
.fia-est{color:var(--warn);background:var(--warnbg);border-color:var(--warnline)}
.fia-est::before{border-radius:50%}
.fia-abs{color:var(--muted);background:#f4f4f5;border-color:#dcdcdf}
.fia-abs::before{background:transparent;border:1.5px dashed currentColor;border-radius:50%}

/* La ligne « convention » du panneau accueille désormais trois choses : la valeur, la pastille
   et le bouton de correction. Elle passe donc en colonne, sans toucher aux autres `.t-row`. */
.t-conv{display:block}
.conv-meta{display:inline-flex;align-items:center;gap:10px;margin-top:4px;flex-wrap:wrap}
.conv-corriger{background:none;border:0;padding:0;color:var(--brand);font:inherit;font-size:.8rem;
  font-weight:600;text-decoration:underline;text-underline-offset:2px;cursor:pointer}
.conv-corriger:focus-visible{outline:2px solid var(--brand);outline-offset:3px;border-radius:3px}
.conv-choix{margin-top:10px;padding:12px;background:var(--bg-soft);border:1px solid var(--line);
  border-radius:12px}
.conv-choix label{display:block;font-size:.8rem;font-weight:600;margin-bottom:6px;color:var(--ink)}
.conv-choix select{width:100%;padding:9px 10px;border:1px solid var(--line);border-radius:9px;
  font:inherit;font-size:.9rem;background:#fff;color:var(--ink)}
.conv-choix .hint{margin:6px 0 0;font-size:.75rem;color:var(--muted)}

/* ===== Établissement rattaché =====
   Information, pas alerte : le comportement décrit est le bon, on ne signale pas un problème. */
.etab-lien{margin:0 0 14px;padding:11px 14px;background:var(--bg-soft);border:1px solid var(--line);
  border-left:3px solid var(--brand);border-radius:10px;font-size:.85rem;line-height:1.5;color:var(--ink)}
.etab-lien[hidden]{display:none}
.etab-lien strong{color:var(--brand-d)}

/* ===== ÉCRAN 5 EN DEUX COLONNES (2026-08-05) =====
   La grille ne s'active qu'au-dessus de 900 px. En dessous, `.ec5` reste un simple bloc et les
   deux colonnes s'empilent DANS L'ORDRE DU DOM — contexte puis travail — c'est-à-dire l'ordre
   d'avant ce lot. Aucune règle mobile à écrire : ne rien faire est le comportement correct.

   ⚠️ AUCUN `order` ICI, ET JAMAIS. L'ordre visuel vient du DOM (cf. le commentaire du gabarit).
   Une inversion en CSS donnerait le même écran avec un parcours clavier incompréhensible. */
@media (min-width:900px){
  /* ⚠️ SANS CETTE LIGNE, LE COLLANT NE PREND PAS. `.sim-shell` porte `overflow:hidden` pour
     rogner ses coins arrondis ; or `hidden` fait de lui un conteneur de défilement, et un
     `position:sticky` descendant se cale alors sur CE conteneur — qui ne défile jamais. La
     colonne restait donc parfaitement immobile en haut du bloc, hors de l'écran.
     `overflow:clip` rogne exactement pareil SANS créer de conteneur de défilement : le collant
     retrouve la fenêtre comme référence. Posé UNIQUEMENT ici, dans la requête ≥900 px : sous
     900 px il n'y a pas de collant à sauver, et le comportement mobile reste au millimètre
     celui d'avant. Un navigateur qui ignore `clip` garde `hidden` — il perd le collant, il ne
     casse rien. */
  .sim-shell{overflow:clip}
  .ec5{display:grid;grid-template-columns:minmax(290px,340px) minmax(0,1fr);gap:22px;
       align-items:start}
  /* `align-items:start` est OBLIGATOIRE pour que le collant fonctionne : en `stretch` (défaut),
     la colonne fait toute la hauteur de la grille et n'a plus de course pour coller. */
  .ec5-ctx{position:sticky;top:calc(var(--nav-h, 72px) + 14px)}
  /* `minmax(0,1fr)` et non `1fr` : sans le minimum à 0, une table large dans l'estimation
     imposerait sa largeur à la colonne et débordrait la grille au lieu de défiler chez elle. */
  .ec5-work{min-width:0}
  /* Le récapitulatif n'est plus une barre horizontale : dans une colonne étroite, ses lignes
     s'empilent naturellement. On neutralise la grille héritée plutôt que d'y superposer une
     seconde règle de colonnes. */
  .ec5-ctx .totaux{grid-template-columns:1fr}

  /* ============================================================
     LES RÔLES ÉTAIENT INVERSÉS — corrigé le 2026-08-06 (LOT 3).

     MESURÉ AVANT CORRECTIF, à 1440x900 : `.ec5-ctx` portait DEUX cadres imbriqués — `.recap-bar`
     en fond doux avec bordure et rayon, contenant `#pec-bloc` en carte blanche avec bordure et
     ombre — pendant que `.ec5-work` n'avait RIEN : background rgba(0,0,0,0), border 0px,
     box-shadow none, padding 0.
     Autrement dit, le CONTEXTE — ce que le prospect ne touche pas — était l'objet le plus appuyé
     de l'écran, et la ZONE DE TRAVAIL, où il compose son projet et lit son chiffrage, flottait
     sur le fond de page comme un reste de mise en page.

     ON ÉCHANGE, ON N'EMPILE PAS. Ajouter un cadre à droite sans retirer celui de gauche aurait
     donné deux cartes concurrentes, donc aucune hiérarchie — le défaut doublé au lieu d'être
     corrigé.

     ⚠️ AUCUN CHANGEMENT D'ORDRE DOM. Le contexte reste écrit AVANT la zone de travail, parce
     qu'il est à sa gauche : au clavier et au lecteur d'écran, on rencontre les blocs dans l'ordre
     où l'oeil les voit. C'est la règle de tout cet écran, et elle vaut aussi quand on redistribue
     les cadres.
     ============================================================ */

  /* LA DROITE DEVIENT LA CARTE. Le liseré gauche de 3 px est le seul aplat de couleur du bloc :
     il DÉSIGNE la colonne active sans la colorer — le marine reste réservé à la structure. */
  .ec5-work{background:#fff;border:1px solid var(--line);border-left:3px solid var(--brand);
    border-radius:var(--radius);box-shadow:var(--shadow-sm);padding:18px 20px 20px}
  .ec5-work-t{display:block;margin:0 0 14px;font-size:1.05rem;font-weight:700;
    letter-spacing:-.02em;color:var(--ink)}

  /* ⚠️ ET `#estim-wrap` PERD LE SIEN. Il est DANS la carte : lui laisser bordure, rayon et ombre
     recréerait à droite exactement le double cadre qu'on vient de retirer à gauche — le défaut
     déplacé, pas corrigé. Un filet horizontal suffit à séparer le chiffrage de la sélection.
     Sous 900 px la règle ne s'applique pas et le bloc garde sa carte : il n'est plus dans une. */
  .ec5-work .estim-wrap{background:none;border:0;border-radius:0;box-shadow:none;
    padding:16px 0 0;margin-bottom:0;border-top:1px solid var(--line)}

  /* `#recap-titre` PASSE EN ÉTIQUETTE. Deux titres de même poids empilés — « Votre projet » puis
     « Votre sélection » — ne font pas une hiérarchie, ils se concurrencent. Même traitement que
     `.pi-modalites legend`, déjà en place dans le panier juste en dessous.
     Son TEXTE ne change pas : il porte la consigne (« Ajouter des formations (facultatif) »)
     quand le panier est vide, et c'est la seule chose de l'écran qui l'indique. */
  .ec5-work .recap-sel > h3{font-size:.78rem;font-weight:600;text-transform:uppercase;
    letter-spacing:.04em;color:#5b6b7f;margin:0 0 8px}

  /* LA GAUCHE PERD SA CARTE et devient une marge à filet vertical. `.recap-bar` d'abord... */
  .ec5-ctx .recap-bar{background:none;border:0;border-radius:0;box-shadow:none;
    padding:2px 0 2px 16px;border-left:2px solid var(--line);margin-bottom:0}
  /* ...puis le panneau lui-même, sans quoi la colonne resterait une carte : simplement une autre.
     Les rangées gardent leurs filets de séparation, ce sont eux qui portent la lisibilité.
     ⚠️ `overflow:visible` : le `hidden` d'origine ne servait qu'à rogner les rangées sur le rayon
     de la carte, qui n'existe plus ici. C'est aussi lui qui avait tué `.pec-cta{position:sticky}`
     sous 640 px — le lever ne peut donc rien casser, et le collant de `.ec5-ctx` ne dépend pas de
     ce conteneur-ci mais de `.sim-shell{overflow:clip}` posé plus haut. Vérifié dans les deux sens. */
  .ec5-ctx .totaux{background:none;border:0;border-radius:0;box-shadow:none;overflow:visible}
  /* SEULE EXCEPTION : la rangée du nom de l'OPCO garde son aplat. Ce n'est pas de la décoration —
     c'est la preuve qu'on a identifié le cas du prospect. Elle donne une tête à la colonne, et
     c'est ce qu'il doit retrouver d'un coup d'oeil en remontant. */
  .ec5-ctx .totaux > .t-row[data-pec="opco"]{border-radius:10px;border-bottom:0;margin-bottom:2px}
}

/* ===== RESPIRATION DES CARTES (2026-08-05) =====
   AUCUNE COULEUR NE CHANGE. La charte marine est intacte : ni la palette, ni les filets, ni les
   contrastes. On ne touche qu'à trois choses — l'écart entre les cartes, leur rayon, et une
   ombre très basse qui les décolle du fond sans les faire flotter.
   Le rayon converge vers --radius (16px), déjà la valeur de la charte : plusieurs blocs le
   redéclaraient en dur à 12 ou 14px, ce qui donnait quatre arrondis différents sur le même
   écran. C'est donc un ALIGNEMENT sur la charte, pas une nouvelle charte.
   L'ombre est volontairement plus faible que --shadow (réservée aux grands conteneurs) :
   --shadow-sm existait déjà et n'était appliquée nulle part. */
.t-row{border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-sm)}
.totaux{gap:14px}
.rcard{border-radius:var(--radius);box-shadow:var(--shadow-sm)}
.fam-card{border-radius:var(--radius);box-shadow:var(--shadow-sm)}
.estim-wrap{border-radius:var(--radius);box-shadow:var(--shadow-sm)}
.conv-choix{border-radius:var(--radius)}
/* Les lignes du panier ne sont pas des cartes : elles restent séparées par un filet, on ne leur
   met ni rayon ni ombre — les encadrer une par une hacherait la liste. Seul l'air augmente. */
.panier-item{padding:15px 0}
.recap-sel{margin-bottom:16px}

/* ============================================================
   COLONNE DE CONTEXTE — UN PANNEAU, PAS UNE PILE DE CARTES (2026-08-05)

   CE QUI CLOCHAIT. Chaque ligne du barème était une carte : bordure, rayon, ombre, 16 px de
   padding de chaque côté. Six cartes empilées dans 340 px, dont 32 px perdus par carte — il ne
   restait que 270 px de texte utile, et « jusqu'à 2 000 € par an et par entreprise » passait à
   la ligne deux fois. Ce n'était pas la colonne qui était étroite, c'étaient les cadres.

   CE QU'ON FAIT. Un seul cadre, des rangées séparées par un filet, libellé à gauche et valeur à
   droite. La place récupérée vient des paddings supprimés, pas de la largeur : les 20 px de plus
   (340 -> 360) ne sont que du confort.

   HIÉRARCHIE. Le taux et le plafond dominent (1.32rem/800), le reste suit (1rem), les libellés
   s'effacent (0.78rem, gris). AUCUNE COULEUR NE CHANGE — la charte marine est intacte.
   ============================================================ */
@media (min-width:900px){
  .ec5{grid-template-columns:minmax(320px,360px) minmax(0,1fr)}
}

/* Le panneau devient la carte ; ses enfants n'en sont plus. `overflow:hidden` rogne les rangées
   sur le rayon — sans lui, la première rangée déborde du coin arrondi. */
.totaux{display:block;background:#fff;border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow-sm);overflow:hidden;gap:0;padding:0}
.totaux > .t-row,
.pec-detail > .t-row{background:none;border:0;border-radius:0;box-shadow:none;
  border-bottom:1px solid #f2f0ec;
  display:flex;flex-direction:row;align-items:baseline;justify-content:space-between;
  gap:12px;padding:11px 16px}
/* `.pec-detail` était un bloc SÉPARÉ du panneau : il portait sa propre marge et son propre filet
   de séparation (l. 434). Depuis qu'il est à l'intérieur de la carte unique, ces trois réglages
   se cumulent avec le filet de l'en-tête OPCO — d'où la bande vide de ~26 px et le double trait
   entre « AKTO » et la première rangée. Les rangées se séparent déjà entre elles. */
.pec-detail{display:block;margin-top:0;padding-top:0;border-top:0}
.t-row:last-child{border-bottom:0}
.t-k{font-size:.78rem;color:var(--muted);flex:none}
.t-row > strong{font-weight:700;font-size:1.02rem;text-align:right;font-variant-numeric:tabular-nums}

/* EN-TÊTE : le nom de l'OPCO. C'est l'information centrale de l'écran — la preuve qu'on a
   identifié le cas du prospect — donc elle est traitée comme un titre, pas comme une rangée. */
.totaux > .t-row[data-pec="opco"]{display:block;background:var(--bg-soft);
  border-bottom:1px solid var(--line);padding:13px 16px}
.t-row[data-pec="opco"] .t-k{display:block;font-size:.72rem;letter-spacing:.08em;
  text-transform:uppercase;margin-bottom:1px}
.t-row[data-pec="opco"] > strong{display:block;text-align:left;font-size:1.15rem;font-weight:800;
  letter-spacing:-.01em;line-height:1.2}

/* LES DEUX CHIFFRES QUI COMPTENT. Le prospect vient chercher ça. */
.t-row[data-pec="taux"] > strong,
.t-row[data-pec="plafond"] > strong,
.t-row[data-pec="pecmax"] > strong{font-size:1.32rem;font-weight:800;letter-spacing:-.01em}
.t-row[data-pec="taux"], .t-row[data-pec="plafond"], .t-row[data-pec="pecmax"]{padding:13px 16px}

/* LE DROIT DE TIRAGE PASSE EN BLOC. « Prise en charge estimée » + « jusqu'à 2 000 € » ne tiennent
   pas sur une ligne à 360 px, et la valeur se coupait entre « jusqu'à » et le montant — la
   coupure la plus laide possible. Libellé au-dessus, montant en dessous : la ligne est courte,
   le montant reste entier. Même traitement que l'OPCO et la convention, qui sont eux aussi des
   rangées « à lire » plutôt que des couples clé/valeur. */
.t-row[data-pec="pecmax"]{display:block}
.t-row[data-pec="pecmax"] .t-k{display:block;margin-bottom:1px}
.t-row[data-pec="pecmax"] > strong{display:block;text-align:left}

/* MÊME TRAITEMENT POUR LES SALAIRES REMBOURSÉS (2026-08-06). La valeur n'est pas un montant sec
   mais une phrase — « jusqu'à 19 € de l'heure » — et `.t-k{flex:none}` ne laissait au montant
   que la place restante : il se cassait sur quatre lignes et sortait de la carte. Le libellé est
   raccourci dans le gabarit ET la rangée passe en bloc : les deux étaient nécessaires, le seul
   raccourcissement ne suffisait pas à faire tenir la phrase sur une ligne à 360 px. */
.t-row[data-pec="fs"]{display:block}
.t-row[data-pec="fs"] .t-k{display:block;margin-bottom:1px}
.t-row[data-pec="fs"] > strong{display:block;text-align:left;font-size:1.02rem}

/* La note d'une rangée (« Plafond de votre OPCO… ») n'a plus la place d'être une troisième
   ligne : elle devient une infobulle portée par la rangée. */
.t-row .t-note{display:none}

/* CONVENTION : plus de carte, plus de pastille, plus de pourcentage en gros. Un nom, puis un mot
   gris et un lien. Le pourcentage est dans l'infobulle de `.fia` (attribut title). */
.t-conv{display:block !important;padding:12px 16px}
/* ⚠️ LE `!important` CI-DESSUS BAT LA GARDE GLOBALE `[hidden]` (ligne 11) : même spécificité
   (0,1,0), même poids, et celle-ci vient plus loin. Mesuré : une rangée convention masquée
   restait affichée sur 89 px, avec son tiret — soit « Votre convention — » chez tout prospect
   dont on n'a pas identifié la branche. La garde est donc RÉTABLIE ici, au même poids.
   Le commentaire de la ligne 9 (« aucune règle du site n'affiche délibérément un élément
   [hidden] ») redevient vrai avec cette ligne, et pas sans elle. */
.t-conv[hidden]{display:none !important}
.t-conv .t-k{display:block;margin-bottom:2px}
.t-conv > strong{display:block;text-align:left;font-size:.95rem;font-weight:600;line-height:1.35}
.conv-meta{display:flex;align-items:baseline;gap:8px;margin-top:3px;flex-wrap:wrap}
.conv-meta .fia{background:none;border:0;padding:0;color:var(--muted);font-size:.78rem;
  font-weight:400;border-bottom:1px dotted var(--muted);cursor:help;border-radius:0}
.conv-meta .fia::before{display:none}
.conv-meta .fia::after{content:"·";margin-left:8px;color:var(--line);border:0}
.conv-corriger{font-size:.78rem}

/* L'action passe sous le panneau : elle n'est plus dedans, elle ne colle donc plus au cadre. */
.pec-accroche{margin-top:14px}
.pec-cta{margin-top:10px;width:100%}
.pec-form{margin-top:12px}

/* SUR PETIT ÉCRAN, LE POURCENTAGE S'ÉCRIT EN CLAIR. Une infobulle `title` ne s'ouvre pas au
   toucher : la garder seule rendrait l'information inaccessible là où, justement, la colonne est
   pleine largeur et où la place ne manque pas. Le texte long est posé par le JS dans
   `data-detail`, et c'est LUI qui s'affiche ici — le mot court disparaît. */
@media (max-width:899px){
  /* 🔴 CHEVAUCHEMENT — CORRIGÉ LE 2026-08-06.
     `.fia` est déclarée `display:inline-flex` plus haut. Son `::before` devient donc un ÉLÉMENT
     FLEX, et un élément flex est BLOCKIFIÉ quoi qu'en dise sa propre déclaration `display:inline`
     ci-dessous : la boîte restait dimensionnée sur le contenu à `font-size:0` (31 px de large)
     pendant que le texte peint en réclamait ~105. « estimée à 72,4 % » se peignait donc PAR-DESSUS
     le bouton « Corriger », à x=132.
     On repasse `.fia` en bloc : elle n'a plus d'enfant flex, sa largeur suit son contenu réel, et
     le `flex-wrap` de `.conv-meta` renvoie « Corriger » à la ligne quand la place manque. */
  .conv-meta .fia{display:block;border-bottom:0;cursor:default;font-size:0}
  .conv-meta .fia::after{font-size:.78rem}
  /* 🔴 ET LA PASTILLE DOIT ÊTRE DÉSHABILLÉE, PAS SEULEMENT REMPLIE.
     Ce `::before` est à l'origine la PUCE de la pastille de fiabilité : `.fia::before` lui pose
     `width:7px;height:7px;background:currentColor`, et `.fia-est::before` un `border-radius:50%`.
     Lui donner un `content` textuel ne retire rien de tout ça — l'aplat `currentColor` s'étalait
     donc SUR SON PROPRE TEXTE, dans la même couleur : « estimée à 72,4 % » se rendait en ellipse
     grise pleine, illisible. Vérifié en capture 4x avant/après.
     ⚠️ `width`/`height` n'ont aucun effet sur un `display:inline`, mais ils sont remis à `auto`
     quand même : la déclaration `display` ci-dessus est fragile — `.fia` est un conteneur flex
     partout ailleurs, et un élément flex serait blockifié, ce qui les rendrait actifs. */
  .conv-meta .fia[data-detail]::before{display:inline;content:attr(data-detail);font-size:.78rem;
    width:auto;height:auto;background:none;border:0;border-radius:0;color:var(--muted)}
}

/* ============================================================
   PRÉAMBULE DE L'ÉCRAN 5 — RESSERRÉ SOUS 640 px (2026-08-06)

   Mesuré : 940 px avant le premier chiffre sur un téléphone. AUCUN CONTENU N'EST RETIRÉ — ni le
   rappel d'entreprise, qui est la preuve qu'on parle bien de SA société et pas d'une homonyme,
   ni le sous-titre, qui annonce l'ordre réel de l'écran. On ne reprend que des marges.

   ⚠️ `.steps` N'EST PAS TOUCHÉ, et c'est délibéré : la barre d'étapes est partagée avec les
   écrans 1 à 4, qui sont mesurés sains (scrollY constant à 303, étapes toujours à 98 px) et hors
   du périmètre de ce lot. Le gain ici est modeste (~35 px) et assumé comme tel : sur mobile, la
   hauteur se récupère par le repli des recommandations (−3 400 px), pas par cet en-tête.
   ============================================================ */
@media(max-width:640px){
  .card{padding:14px 16px 10px}
  .card-t{font-size:1.18rem;margin-bottom:2px}
  .card-s{margin:.1rem 0 10px}
  .ent-rappel{margin-bottom:12px;padding-bottom:10px}
  .recap-bar{padding:14px 14px}
}

/* ============================================================
   MODALE DE COORDONNÉES — LOT 2, 2026-08-06

   CE QUI CLOCHAIT. Le formulaire était injecté dans le flux, à l'intérieur du panneau.
   Mesuré à 390x844 : 969 px de haut, bouton d'envoi à top=817 pour un pli à 844 — coupé de 46 px,
   la note d'en dessous entièrement hors écran. Au bureau, il était injecté dans la colonne GAUCHE
   et l'étirait à 1 505 px pendant que la colonne de droite se vidait.

   ⚠️ AUCUN `position:sticky` DANS CE BLOC, ET C'EST VOLONTAIRE. Le pied serait le candidat
   évident ; c'est précisément le piège qu'on vient de payer deux fois (`.sim-shell`, puis
   `.pec-cta` annulé par `#pec-bloc{overflow:hidden}`). Le dialogue est une COLONNE FLEX : tête et
   pied en `flex:none`, corps en `overflow-y:auto`. Le bouton d'envoi ne peut alors pas tomber
   sous le pli, quelle que soit la hauteur des champs, et il n'y a aucun ancêtre à surveiller.
   ============================================================ */
.pec-modal{padding:0;border:0;background:#fff;color:var(--ink);
  max-width:560px;width:calc(100% - 32px);max-height:min(88dvh,760px);
  border-radius:var(--radius);box-shadow:0 24px 60px -20px rgba(11,34,57,.5)}
.pec-modal::backdrop{background:rgba(11,34,57,.55)}
/* 🔴 `display:flex` DOIT ÊTRE CONDITIONNÉ PAR `[open]`, JAMAIS POSÉ SUR `.pec-modal`.
   Le masquage d'un <dialog> fermé vient de `dialog:not([open]){display:none}` de la feuille du
   NAVIGATEUR — et une déclaration d'AUTEUR la bat toujours, quelle que soit la spécificité.
   `.pec-modal{display:flex}` afficherait donc la modale en permanence, sur toutes les pages du
   simulateur. C'est le même piège que `[hidden]`, documenté deux fois dans cette feuille.
   `padding:0` n'est pas cosmétique non plus : c'est ce qui garantit que le formulaire remplit
   toute la surface du dialogue, donc qu'un clic dont la cible EST le dialogue vient forcément du
   fond — le seul moyen de distinguer le clic sur le fond, que <dialog> ne signale pas. */
.pec-modal[open]{display:flex;flex-direction:column}
/* ⚠️ `min-height:0` SUR LES DEUX NIVEAUX. Un élément flex ne descend pas sous la hauteur de son
   contenu sans lui : sans ces deux déclarations, `.pm-corps{overflow-y:auto}` ne défile pas, le
   formulaire garde sa hauteur naturelle et POUSSE LE PIED HORS DU DIALOGUE.
   Mesuré avant correctif, à 390x844 : pied à top=831 pour 121 px de haut, bouton d'envoi à
   top=844 — c'est-à-dire entièrement hors écran, PIRE qu'avant ce lot. */
.pec-modal .pec-form{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;gap:0;
  background:none;border:0;border-radius:0;padding:0;margin:0}

.pm-tete{flex:none;display:flex;align-items:flex-start;gap:12px;
  padding:18px 20px 13px;border-bottom:1px solid var(--line)}
.pm-tete-txt{flex:1 1 auto;min-width:0}
.pec-modal .pec-form-t{margin:0}
.pec-form-sous{margin:5px 0 0;font-size:.85rem;line-height:1.45;color:var(--muted)}
.pec-form-sous[hidden]{display:none}
.pm-fermer{flex:none;border:0;background:none;font-size:1.6rem;line-height:1;padding:0 4px;
  color:var(--muted);cursor:pointer;border-radius:8px}
.pm-fermer:hover{color:var(--ink);background:var(--bg-soft)}
.pm-fermer:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

.pm-corps{flex:1 1 auto;min-height:0;overflow-y:auto;padding:16px 20px;
  display:grid;gap:14px;align-content:start}
.pm-pied{flex:none;padding:13px 20px 16px;border-top:1px solid var(--line);background:#fff}
.pec-modal .pec-form-go{margin:0}
.pec-modal .pec-form-note{margin:9px 0 0}

/* CHAMPS APPARIÉS à partir de 560 px : civilité+prénom, puis téléphone+email. Nom et fonction
   traversent (`pm-large`) — le nom porte une consigne sous son champ, et appairé il désalignerait
   sa voisine d'une ligne entière.
   En dessous de 560 px, une seule colonne : deux champs de 150 px ne se remplissent pas au pouce. */
@media(min-width:560px){
  .pm-corps{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .pm-corps .pm-large{grid-column:1/-1}
}
.pec-civ select{width:100%;min-width:0}

/* MOBILE : FEUILLE PLEIN ÉCRAN.
   `100dvh` et NON `100vh` — `vh` ignore la barre d'adresse rétractable, et c'est exactement ce
   qui faisait tomber le bouton d'envoi à top=843 pour un pli à 844. */
@media(max-width:640px){
  .pec-modal{width:100%;max-width:none;height:100dvh;max-height:none;margin:0;border-radius:0}
  .pm-corps{padding:16px}
  .pm-tete{padding:16px 16px 12px}
  .pm-pied{padding:12px 16px 16px}
}

/* CONFIRMATION D'ABANDON — posée SUR la modale, en bas, pas à côté : elle doit interrompre le
   geste de fermeture, pas s'ajouter au formulaire. Le bouton plein est « Continuer à remplir » ;
   l'abandon est un lien discret. La hiérarchie visuelle dit la même chose que le focus. */
.pm-abandon{position:absolute;inset:auto 0 0;z-index:2;padding:18px 20px 20px;background:#fff;
  border-top:1px solid var(--line);box-shadow:0 -14px 34px -18px rgba(11,34,57,.55);
  display:grid;gap:10px;justify-items:stretch;text-align:center}
.pm-abandon[hidden]{display:none}
.pm-abandon-t{margin:0;font-weight:700;font-size:1rem;color:var(--ink)}
.pm-abandon-d{margin:0;font-size:.85rem;color:var(--muted);line-height:1.45}
.pm-rester{width:100%}
.pm-partir{background:none;border:0;color:var(--muted);font:inherit;font-size:.88rem;
  text-decoration:underline;cursor:pointer;padding:4px}
.pm-partir:hover{color:var(--ink)}
.pm-partir:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}

/* LE FOND NE DÉFILE PAS PENDANT LA MODALE. `showModal()` rend le fond inerte au clavier et à la
   souris, mais il ne bloque PAS le défilement : sans cette règle, le prospect fait glisser la page
   derrière la feuille et retrouve son écran 5 à une autre position en refermant. */
.modale-ouverte{overflow:hidden}

/* ============================================================
   BLOC RÉGLEMENTAIRE — l'incitation d'après le barème (2026-08-06)

   CE QU'IL RÉSOUT. Le prospect obtenait son financement et rien ne se passait : il pouvait fermer
   l'onglet avec son barème et sans avoir rien demandé.

   LISTE, PAS CARTES. La colonne de contexte fait 340 px, et l'écran 5 mobile est à 3 387 px après
   le LOT 1 : douze cartes illustrées coûteraient 5 255 px. Une ligne « intitulé + durée + Ajouter »
   se parcourt aussi plus vite quand on cherche ce qui vous concerne.
   ============================================================ */
/* ⚠️ IL OUVRE LA COLONNE DE TRAVAIL, il ne la termine pas — déplacé le 2026-08-06.
   Le filet est donc EN BAS (il sépare le bloc de « Votre projet »), plus en haut où il séparait
   du barème quand le bloc vivait à gauche. Sans cette inversion, la carte de droite s'ouvrait
   sur un trait horizontal orphelin. */
.reg-wrap{margin:0 0 16px;padding:0 0 16px;border-bottom:1px solid var(--line)}
.reg-wrap[hidden]{display:none}
.reg-transition{margin:0 0 3px;font-size:.95rem;line-height:1.45;color:var(--ink)}
.reg-transition strong{font-weight:700}
/* Le compteur en `--ok` quand il annonce de vraies obligations, en gris quand il bascule sur le
   libellé de repli : la couleur ne doit pas donner du poids à une phrase qui n'en revendique pas. */
.reg-compteur{margin:0 0 12px;font-size:.83rem;font-weight:600;color:var(--muted)}
.reg-compteur-fort{color:var(--ok)}
/* SECOND COMPTEUR — plus discret que le strict, et volontairement pas aligné sur lui : deux
   lignes de même poids se liraient comme un total en deux morceaux, donc comme une addition.
   `hidden` quand il n'y a aucune conditionnelle : une ligne vide vaut mieux absente que réservée. */
.reg-compteur-cond{margin:-8px 0 12px;font-size:.8rem;line-height:1.4;color:var(--muted)}
.reg-compteur-cond[hidden]{display:none}

/* SÉPARATEUR DE GROUPE — 2026-08-07. Il nomme les lignes SANS badge, une seule fois, au lieu
   d'ajouter une troisième pastille à côté de deux affirmations juridiques. L'absence de badge
   EST déjà l'information : écrire « Non obligatoire » sur chaque ligne serait du bruit.
   ⚠️ C'est du TEXTE, pas une nuance de fond : la règle « la couleur ne porte pas l'information »
   vaut ici comme pour l'ambre. Lisible en dichromate, en noir et blanc, au lecteur d'écran.
   `role="presentation"` côté JS : c'est un intertitre dans un <ul> d'éléments interactifs, il ne
   doit pas être annoncé comme un item de la liste. */
.reg-sep{display:flex;align-items:center;gap:10px;margin:14px 0 6px;padding:0;
  font-size:.72rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--muted);border:0}
.reg-sep::after{content:"";flex:1;height:1px;background:var(--line)}

.reg-list{list-style:none;margin:0;padding:0}
.reg-item{display:flex;align-items:center;gap:12px;padding:10px 0;
  border-bottom:1px solid #f2f0ec}
.reg-item:last-child{border-bottom:0}
.reg-txt{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.reg-txt strong{font-size:.88rem;font-weight:600;line-height:1.35;color:var(--ink)}
.reg-duree{font-size:.76rem;color:var(--muted)}
.reg-add{flex:0 0 auto;padding:8px 14px;font-size:.82rem}
.reg-add.est-dedans{background:#fff;color:var(--brand);border:1.5px solid #c9d4e4;box-shadow:none}

.reg-plus{width:100%;margin-top:12px;padding:10px 14px;background:#fff;
  border:1.5px solid #c9d4e4;border-radius:10px;color:var(--brand);
  font:inherit;font-weight:600;font-size:.83rem;cursor:pointer}
.reg-plus:hover{border-color:var(--brand)}
.reg-plus[hidden]{display:none}

/* Cible de défilement du bandeau mobile (« Voir les formations de mon secteur → », lot suivant).
   Même convention que partout : c'est `scroll-margin-top` qui cale sous l'en-tête collant. */
.reg-wrap{scroll-margin-top:calc(var(--nav-h, 72px) + 14px)}

/* ===== FORMATION MISE EN AVANT (vedette du bloc réglementaire) — 2026-08-06 =====
   ELLE EST HORS DE LA LISTE, visuellement et dans le DOM. Une « plus demandée » qui ressemblerait
   à une ligne de plus ne serait pas mise en avant, elle serait rangée.
   ⚠️ AUCUN BADGE ne s'y accroche : elle n'a pas d'`obligation` en base. Son étiquette est une
   affirmation COMMERCIALE — l'étoile et le fond bleu pâle la séparent délibérément du vocabulaire
   du badge « Obligatoire », qui est une affirmation JURIDIQUE. Les deux ne doivent jamais se
   ressembler à l'écran. */
.reg-vedette{margin:0 0 14px;padding:13px 14px;background:var(--brand-pale,#eaf1fe);
  border:1px solid #c9dbfb;border-left:3px solid var(--brand);border-radius:12px}
.reg-vedette[hidden]{display:none}
/* FLEX, PAS UN GLYPHE DANS LE FLUX : l'étoile est un SVG (voir ICO_ETOILE dans app.js). Posée en
   ligne, une boîte de 14 px cale sur la ligne de base d'un texte de 11,5 px et pend sous elle.
   `align-items:center` la centre sur la hauteur du mot ; le `gap` remplace l'espace qui suivait
   l'émoji. Taille réduite à 12 px : l'échelle de 14 px des cartes est trop lourde à côté d'un
   texte en petites capitales. */
.rv-etiquette{display:flex;align-items:center;gap:5px;
  margin:0 0 5px;font-size:.72rem;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--brand)}
.rv-etiquette .rc-ico{width:12px;height:12px;flex:0 0 12px}
.rv-nom{margin:0;font-size:.92rem;font-weight:700;line-height:1.35;color:var(--ink)}
.rv-accroche{margin:4px 0 0;font-size:.82rem;line-height:1.45;color:#4d5765}
.rv-pied{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:11px}
.rv-duree{font-size:.76rem;color:var(--muted)}
.rv-add{margin-left:auto;padding:8px 16px;font-size:.82rem}
.rv-add.est-dedans{background:#fff;color:var(--brand);border:1.5px solid #c9d4e4;box-shadow:none}

/* ===== VERROU DU BLOC SECTORIEL — 2026-08-07 =====
   Avant le barème, le bloc sectoriel (vedette + lignes + cartes « Recommandé ») est en LECTURE
   SEULE. Ce n'est pas un garde-fou, c'est le levier de conversion : le prospect voit la formation
   qui le concerne, et c'est elle qui lui donne une raison de demander son barème.

   PAS DE BOUTON GRISÉ. Le bouton est RETIRÉ du rendu (cf. peindreReg/peindreVedette/peindreReco) :
   un bouton désactivé se lit comme une panne, son absence se lit comme un état. Le survol et le
   curseur disent que la ligne répond ; l'encart dit ce qu'elle répond.

   ⚠️ AUCUN OPACITY, AUCUN GRIS SUR LE CONTENU. Estomper la liste reviendrait à dévaloriser
   exactement ce qu'on veut faire désirer. Ce qui est retenu, c'est l'action — pas l'information.
   Le badge « Obligatoire » reste pleinement lisible ET cliquable : c'est la preuve juridique,
   elle n'est pas la monnaie d'échange du barème. */
[data-verrou]{cursor:pointer}
.reg-item[data-verrou]:hover,.reg-vedette[data-verrou]:hover{background:#f5f8ff}
.reg-item[data-verrou]{border-radius:8px;padding-left:6px;padding-right:6px;margin-left:-6px;margin-right:-6px}
.rcard[data-verrou]:hover{border-color:var(--brand)}
[data-verrou]:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
/* Le pied de la vedette garde sa place sans bouton : sans ce plancher, la carte se rétracte de
   32 px à la bascule et toute la colonne saute sous les yeux du prospect. */
.bloc-verrou .rv-pied{min-height:34px}

/* L'ENCART. Il REPREND LE NOM de la formation cliquée — c'est ce qui distingue une invitation
   d'une consigne — et il PORTE LE BOUTON lui-même : `#pec-cta` est dans l'autre colonne, et au
   bout d'un renvoi il ne reste qu'un bouton, plus une formation.
   Bordure gauche marine, comme la vedette : c'est la même famille de messages, celle du site qui
   s'adresse au prospect, pas celle de la loi (ambre). */
.reg-invite{margin:8px 0 12px;padding:12px 14px;background:var(--brand-pale,#eaf1fe);
  border:1px solid #c9dbfb;border-left:3px solid var(--brand);border-radius:10px}
.reg-invite-t{margin:0 0 10px;font-size:.86rem;line-height:1.45;color:var(--ink)}
.reg-invite-t strong{color:var(--brand)}
.reg-invite-go{width:100%;justify-content:center;padding:11px 18px;font-size:.88rem}
/* Dans la grille des cartes, l'encart doit couvrir toute la largeur : posé dans une colonne, il
   déformerait la rangée et se retrouverait à côté de sa carte, pas dessous. */
.reco-list .reg-invite{grid-column:1/-1}

/* MISE EN ÉVIDENCE APRÈS DÉVERROUILLAGE — la formation qu'il avait cliquée, retrouvée.
   3 s puis retour au calme : un surlignage permanent deviendrait un état de plus à interpréter.
   ⚠️ La transition est neutralisée sous `prefers-reduced-motion` — la classe est posée puis
   retirée par un `setTimeout`, donc sans transition l'effet reste visible, il ne clignote pas. */
.reg-item--cible{background:#fff6e0;box-shadow:0 0 0 2px var(--warnline);
  transition:background .4s ease,box-shadow .4s ease}
@media (prefers-reduced-motion:reduce){ .reg-item--cible{transition:none} }
/* La cible est désormais D'ABORD une ligne de PANIER : depuis le 2026-08-07, la formation cliquée
   avant le formulaire n'est plus seulement désignée, elle est OUVERTE sur son tableau de
   financement. Le surlignage suit donc jusque dans `#panier-list`.
   Pas de `box-shadow` en anneau ici : la ligne de panier contient déjà un fieldset encadré, et
   deux cadres imbriqués se lisent comme une erreur de rendu. Un liseré à gauche suffit à dire
   « c'est celle-ci », sans redessiner la boîte.
   ⚠️ LISERÉ EN `inset`, PAS EN `border-left`. `.panier-item` a `padding:15px 0`, donc zéro à
   gauche : une bordure de 3 px + son padding décaleraient tout le contenu de 14 px à la pose de
   la classe, puis le feraient revenir 3 s plus tard. Un surlignage qui fait sauter la ligne qu'il
   désigne se remarque plus que la ligne. L'ombre interne ne prend aucune place. */
.panier-item.reg-item--cible{background:#fff6e0;box-shadow:inset 3px 0 0 var(--warn)}

/* HORS CATALOGUE SORTI DE `.recap-sel` — il lui rend le retrait et le filet du cadre qu'il a
   quitté, pour que sa position à l'oeil ne bouge pas à l'état déverrouillé. */
.hc-bloc{margin:0 0 14px;padding:14px 16px;background:#fff;border:1px solid var(--line);
  border-radius:var(--radius)}
.hc-bloc .hc-form{margin-top:10px}

/* ===== BADGE « OBLIGATOIRE » ET SON POPUP — 2026-08-06 =====
   AMBRE, ET PAS VERT. Une obligation n'est pas un gain : le vert reste réservé à ce que le
   prospect OBTIENT (prise en charge, taux). `--warn` = 5,91:1 sur blanc et 5,59:1 sur `--warnbg`,
   tous deux au-dessus du seuil de 4,5 mesuré au LOT 4.
   ⚠️ LA COULEUR NE PORTE PAS L'INFORMATION : vert et ambre ont la MÊME CLARTÉ (1,09:1 en vision
   normale, 1,28:1 en deutéranopie) — ils sont indistinguables pour un dichromate. C'est le MOT
   « Obligatoire » qui informe ; l'ambre ne fait que le souligner.
   C'est un BOUTON : il ouvre le texte. Un badge qui affirme sans pouvoir être vérifié demande
   qu'on le croie sur parole. */
.ob-badge{display:inline-flex;align-items:center;flex:0 0 auto;
  padding:3px 9px;border-radius:999px;cursor:pointer;
  background:var(--warnbg);color:var(--warn);border:1px solid var(--warnline);
  font:inherit;font-size:.7rem;font-weight:700;letter-spacing:.02em;line-height:1.3}
.ob-badge:hover{background:#f8efdd}
.ob-badge:focus-visible{outline:2px solid var(--warn);outline-offset:2px}
/* BADGE CONDITIONNEL — MÊME AMBRE, EN CONTOUR. Le plein affirme, le contour nuance : l'agent
   distingue les deux d'un coup d'oeil sans avoir à lire chaque ligne.
   ⚠️ LE CONTRASTE DU TEXTE NE BOUGE PAS. `--warn` passe de `--warnbg` à blanc, soit 5,59:1 puis
   5,91:1 — les deux au-dessus du seuil de 4,5 mesuré au LOT 4. Le tireté est plus clair que le
   texte, il ne porte aucune information à lui seul.
   ⚠️ ET LA COULEUR NE DISTINGUE RIEN NON PLUS : les deux badges sont du même ambre. Ce qui les
   sépare est le LIBELLÉ — « Obligatoire » contre « Obligatoire si… » — lisible en vision
   dichromate, en noir et blanc, et par un lecteur d'écran. Le contour ne fait que le souligner.
   Ne jamais remplacer le « si… » par une simple nuance de couleur. */
.ob-badge--cond{background:transparent;border:1px dashed var(--warnline);font-weight:600}
.ob-badge--cond:hover{background:var(--warnbg)}
/* Dans la liste du bloc : sur sa propre ligne, sous l'intitulé — en ligne il repousserait la
   durée et casserait l'alignement des boutons d'ajout. */
.reg-txt .ob-badge{align-self:flex-start;margin-top:3px}
/* Sur une carte de reco et dans le catalogue : juste sous le titre. */
.rcard-nom + .ob-badge{margin-top:8px}
.ci-txt .ob-badge{align-self:flex-start;margin-top:2px}

.ob-modal{padding:0;border:0;background:#fff;color:var(--ink);
  max-width:480px;width:calc(100% - 32px);max-height:min(82dvh,620px);
  border-radius:var(--radius);box-shadow:0 24px 60px -20px rgba(11,34,57,.5)}
.ob-modal::backdrop{background:rgba(11,34,57,.55)}
/* Conditionné par [open] — une déclaration `display` d'auteur bat la feuille du navigateur et
   afficherait le dialogue fermé. Troisième fois qu'on note ce piège dans ce fichier. */
.ob-modal[open]{display:flex;flex-direction:column}
.ob-corps{flex:1 1 auto;min-height:0;overflow-y:auto;padding:16px 20px 20px}
.ob-nom{margin:0 0 14px;font-size:1rem;font-weight:700;line-height:1.35;color:var(--ink)}
.ob-k{margin:0 0 3px;font-size:.72rem;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted)}
.ob-base{margin:0 0 15px;font-size:.9rem;line-height:1.5;color:var(--ink);
  padding:10px 12px;background:var(--warnbg);border-left:3px solid var(--warn);border-radius:8px}
.ob-cond{margin:0 0 15px;font-size:.88rem;line-height:1.5;color:#4d5765}
.ob-verif{margin:0;font-size:.75rem;color:var(--muted);font-variant-numeric:tabular-nums}
@media(max-width:640px){
  .ob-modal{width:100%;max-width:none;max-height:88dvh;margin:auto 0 0;
    border-radius:var(--radius) var(--radius) 0 0}
}

/* ===== VISUELS DU BLOC RÉGLEMENTAIRE ET DE LA VEDETTE — 2026-08-06 =====
   LE CADRE EXISTE TOUJOURS, avec ou sans fichier. Un cadre qui apparaît et disparaît d'une ligne
   à l'autre décale tous les intitulés et fait « sauter » la liste au défilement. Sans visuel, on
   peint les initiales sur le fond doux de la charte — jamais un vide, jamais une image cassée.
   Le repli est celui des cartes de recommandation (`.rcard-media--txt`), pas un second mécanisme. */
.reg-vig{flex:0 0 auto;width:48px;height:48px;border-radius:8px;object-fit:cover;display:block;
  background:var(--bg-soft)}
.reg-vig--txt{display:flex;align-items:center;justify-content:center;
  font-size:.82rem;font-weight:700;color:var(--muted);letter-spacing:.02em}

/* La vedette garde le rapport 3/2 des cartes de reco : elle ne doit pas se lire comme un objet
   d'une autre famille. `aspect-ratio` réserve la place AVANT le chargement — c'est ce qui évite
   le décalage à l'arrivée de l'image, comme sur les 32 visuels du site. */
.rv-media{display:block;aspect-ratio:3/2;margin:0 0 11px;border-radius:9px;overflow:hidden;
  background:var(--bg-soft)}
.rv-media img{width:100%;height:100%;object-fit:cover;display:block}
.rv-media--txt{display:flex;align-items:center;justify-content:center;
  font-size:1.5rem;font-weight:700;color:var(--muted);letter-spacing:.02em}

/* « Sur devis » dans la LISTE du bloc — même règle que .rcard-surdevis sur les cartes, alignée le
   2026-08-07 : une formation sans modalité tarifée n'a pas de bouton d'ajout, elle a un renvoi.
   Compact, à la place qu'occupait le bouton : la liste ne doit pas changer de gabarit d'une ligne
   à l'autre, sinon les intitulés se décalent. */
.reg-surdevis{flex:0 0 auto;align-self:center;font-size:.72rem;color:var(--muted);
  background:var(--bg-soft);border:1px solid var(--line);border-radius:999px;padding:4px 10px;
  white-space:nowrap}

/* ===== CONVENTION MANQUANTE — LE CHAMP DE L'ÉCRAN 5 (2026-08-08) =====
   Même habillage que `.conv-choix` de l'écran 2, délibérément : c'est la même question posée
   au même visiteur, à un autre moment du parcours. Lui donner une apparence neuve laisserait
   croire à une démarche différente.
   Le bouton reste sur sa ligne sous 480 px : côte à côte, le champ tombait sous 150 px de large
   et le placeholder devenait illisible — or c'est lui qui dit ce qu'on attend. */
.conv-demande{margin-top:14px;padding:14px;background:var(--bg-soft);border:1px solid var(--line);
  border-radius:12px}
.conv-demande label{display:block;font-size:.8rem;font-weight:600;margin-bottom:6px;color:var(--ink)}
.conv-demande input{margin-bottom:10px}
.conv-demande .btn{width:100%}
.conv-demande .hint{margin:8px 0 0;font-size:.8rem;color:#b45309}
.conv-demande .hint[hidden]{display:none}
@media (min-width:480px){
  .conv-demande{display:grid;grid-template-columns:1fr auto;gap:10px;align-items:end}
  .conv-demande label{grid-column:1 / -1;margin-bottom:0}
  .conv-demande input{margin-bottom:0}
  .conv-demande .btn{width:auto;white-space:nowrap}
  .conv-demande .hint{grid-column:1 / -1}
}

/* ============================================================
   CONSENTEMENT AU RAPPEL — popup de confirmation + bouton persistant (2026-08-09).

   POSÉ EN FIN DE FEUILLE, à dessein : toutes les classes sont NEUVES (`cs-`), aucune ne
   redéfinit d'existante, donc aucune surprise de cascade quel que soit l'endroit — et la fin
   de fichier est le seul endroit qui ne décale la ligne d'aucune règle déjà mesurée.

   AUCUN EMOJI DANS CE BLOC ni dans le gabarit : les pictogrammes sont des <svg> en
   `currentColor`, ils héritent de la couleur du texte qui les porte et suivent tout changement
   d'état sans qu'une règle de couleur supplémentaire soit nécessaire.
   ============================================================ */
.cs-modal{border:0;padding:0;max-width:520px;width:calc(100vw - 32px);
  border-radius:var(--radius);box-shadow:var(--shadow);background:#fff;color:var(--ink)}
.cs-modal::backdrop{background:rgba(11,34,57,.45)}
.cs-corps{padding:16px 20px;display:grid;gap:8px}
.cs-k{margin:6px 0 0;font-size:.72rem;font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted)}

/* NUMÉRO DE DOSSIER. `input` et non `<p>` : sélectionnable et copiable au doigt même si le
   bouton de copie échoue (Clipboard indisponible hors contexte sécurisé, ou permission refusée).
   `tabular-nums` : un numéro qu'on relit chiffre à chiffre au téléphone ne doit pas danser. */
.cs-copie{display:flex;gap:8px;align-items:stretch}
.cs-copie input{flex:1 1 auto;min-width:0;font-weight:700;font-size:1.05rem;letter-spacing:.02em;
  font-variant-numeric:tabular-nums;background:var(--bg-soft);border-color:var(--line)}
.cs-btn-copie{flex:none;display:inline-flex;align-items:center;gap:6px;padding:10px 13px;
  border:1px solid var(--brand);border-radius:8px;background:#fff;color:var(--brand);
  font:inherit;font-size:.8rem;font-weight:600;cursor:pointer;white-space:nowrap}
.cs-btn-copie:hover{background:#eef4ff}
.cs-btn-copie:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.cs-btn-copie svg{width:16px;height:16px;flex:none}

.cs-tel{display:inline-flex;align-items:center;gap:8px;font-size:1.15rem;font-weight:700;
  color:var(--brand);text-decoration:none}
.cs-tel svg{width:19px;height:19px;flex:none}
.cs-horaires{margin:2px 0 0;font-size:.78rem;color:var(--muted)}

/* LA CASE — MISE EN AVANT, PAS UNE MENTION DE BAS DE PAGE.
   🔴 `input,select{width:100%}` (plus haut dans cette feuille) S'APPLIQUE AUSSI AUX CASES À
   COCHER : sans la largeur fixe ci-dessous, la case s'étire sur toute la modale et devient une
   barre grise. Piège déjà vu sur ce projet.
   Contraste `--ink` #0b2239 sur #eef4ff = 13,9:1.
   La couleur n'est JAMAIS le seul signal de l'état : la coche native reste, et `:has(:checked)`
   ne fait que la doubler. Sur un navigateur sans `:has()`, la case reste bleue et cochée —
   aucun repli à écrire. */
.cs-box{display:flex;align-items:flex-start;gap:11px;margin:10px 0 0;padding:14px;
  border:1.5px solid var(--brand);border-radius:12px;background:#eef4ff;cursor:pointer;
  font-size:.9rem;font-weight:500;color:var(--ink);line-height:1.45}
.cs-box:hover{background:#e4edff}
.cs-box:has(:checked){background:var(--okbg);border-color:var(--ok)}
.cs-box input[type=checkbox]{width:20px;height:20px;flex:none;margin:1px 0 0;
  accent-color:var(--brand);cursor:pointer}
.cs-box:has(:checked) input[type=checkbox]{accent-color:var(--ok)}
.cs-box:focus-within{outline:2px solid var(--brand);outline-offset:2px}
.cs-txt{min-width:0}

.cs-etat{margin:0 0 10px;font-size:.85rem;line-height:1.45}
.cs-etat[data-ok="1"]{color:var(--ok);font-weight:600}
.cs-etat[data-ok="0"]{color:var(--ink)}

/* BOUTON PERSISTANT, sous l'estimation. Volontairement en SECOND rôle — bordé, pas plein : le
   bouton plein de cette colonne est celui de l'estimation, et deux boutons pleins l'un sous
   l'autre se disputent le même geste. Il ne s'affiche que si le visiteur a vu le popup sans
   cocher, donc il ne concurrence jamais l'ouverture automatique. */
.cs-relance{display:inline-flex;align-items:center;gap:9px;margin:14px 0 0;padding:12px 18px;
  border:1.5px solid var(--brand);border-radius:12px;background:#fff;color:var(--brand);
  font:inherit;font-size:.9rem;font-weight:600;cursor:pointer}
.cs-relance:hover{background:#eef4ff}
.cs-relance:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
.cs-relance svg{width:18px;height:18px;flex:none}
.cs-relance[hidden]{display:none}
