/* =====================================================
   PrivateSource — Pages /outils/
   Chargé après tokens.css, base.css et landing.css, dont cette feuille réutilise
   les conteneurs, les boutons et le formulaire e-mail (.form-c). N'y sont écrits
   que les motifs propres aux outils interactifs : formulaire de calcul dense,
   panneau de résultats, encadré d'hypothèses.

   ── DEUX RÈGLES D'ACCESSIBILITÉ À NE PAS DÉFAIRE ───────────────────────────
   1. Le texte secondaire utilise --ps-text-muted (#495057), jamais
      --ps-text-secondary (#6c757d). Le second passe le seuil de 4,5:1 sur blanc
      pur (4,68) mais tombe en dessous dès que le fond est teinté : 4,3 sur
      --ps-bg-app (#f5f5f7), 4,34 sur --ps-primary-light (#f0f7ff). Or cette page
      pose l'essentiel de ses aides et de ses libellés sur ces deux fonds.
      --ps-text-muted tient au-dessus de 7:1 sur les trois.
   2. Les liens en corps de texte sont SOULIGNÉS. Le bleu de marque n'a que
      1,96:1 de contraste avec le texte courant, très en dessous des 3:1 exigés
      pour distinguer un lien par la couleur seule (WCAG 1.4.1).
   ───────────────────────────────────────────────────────────────────────────
   ===================================================== */

/* ----- Fil d'Ariane ----- */
.outil-breadcrumb {
  padding: 24px 0 0;
  background: var(--ps-bg-card);
}
.outil-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--fs-small);
  color: var(--ps-text-muted);
}
.outil-breadcrumb li + li::before {
  content: "/";
  margin-right: 8px;
  color: var(--ps-border-light);
}
.outil-breadcrumb a { color: var(--ps-text-muted); }
.outil-breadcrumb a:hover { color: var(--ps-primary); }
.outil-breadcrumb [aria-current="page"] { color: var(--ps-text-body); }

/* ----- En-tête ----- */
.outil-header {
  padding: 40px 0 24px;
  background: var(--ps-bg-card);
}
.outil-h1 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-h1);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 12px 0 20px;
  color: var(--ps-text);
}
.outil-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  color: var(--ps-text-muted);
  margin-top: 20px;
}

/* ----- Sections ----- */
.outil-section {
  padding: 48px 0;
  background: var(--ps-bg-card);
}
.outil-section--soft { background: var(--ps-bg-app); }
.outil-section--cta {
  background: var(--ps-primary-light);
  border-top: 1px solid var(--ps-primary-border);
  border-bottom: 1px solid var(--ps-primary-border);
}
/* .form-reassure vient de la landing, où elle se pose sur du blanc : son
   --ps-text-secondary y tient 4,69:1. Sur le bleu clair de cette section elle
   tombe à 4,34:1 et manque le seuil AA. Le défaut existait déjà, masqué par la
   règle `.outil-section p` qui la repeignait en #333333 ; le rendre visible en
   corrigeant la spécificité oblige à le traiter ici, pour de bon. */
.outil-section--cta .form-reassure { color: var(--ps-text-muted); }
.outil-section h2 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin-bottom: 20px;
  color: var(--ps-text);
}
/* `:not([class])` est la clé de voûte de la hiérarchie de cette page, et son
   absence était le défaut de fond du calculateur.
   `.outil-section p` pèse (0,1,1) : plus qu'une classe seule. Il écrasait donc
   .mfba-aide, .mfba-verdict, .mfba-rappel, .mfba-disclaimer, .outil-intro-form,
   .outil-note-taux, .form-reassure et .form-rgpd-notice — huit niveaux
   d'information distincts rendus en 17 px / #333 / 1.7, exactement comme le
   texte courant. Les tailles et les teintes écrites pour les différencier
   n'étaient jamais appliquées, et l'œil n'avait aucun repère pour hiérarchiser
   ce qu'il voyait.
   La règle ne vise plus que les paragraphes de contenu, ceux sans classe ;
   chaque composant reprend le sien. Ne PAS retirer `:not([class])` sans
   revérifier ces huit classes. */
.outil-section p:not([class]) {
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--ps-text-body);
  margin-bottom: 16px;
}
.outil-section p a,
.outil-section li a {
  color: var(--ps-primary);
  text-decoration: underline;
}

.outil-hypotheses,
.outil-liste-ecarts {
  margin: 0 0 20px;
  padding-left: 22px;
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--ps-text-body);
}
.outil-hypotheses li,
.outil-liste-ecarts li { margin-bottom: 14px; }
.outil-hypotheses strong { color: var(--ps-text); font-weight: 600; }

/* Depuis que `.outil-section p` ne s'applique plus aux paragraphes à classe,
   chaque composant porte sa propre interlettre et ses propres marges. */
.outil-note-taux {
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--ps-text-muted);
  border-left: 3px solid var(--ps-border);
  padding-left: 14px;
  margin: 0 0 16px;
}

/* Bloc de sources : la citation de la source primaire est le signal de confiance
   le plus fort de la page, mais elle ne doit pas concurrencer visuellement le
   calcul. D'où le corps réduit et la teinte atténuée — lisible pour qui vérifie,
   discret pour qui vient calculer. */
.outil-sources-titre {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 32px 0 12px;
  color: var(--ps-text);
}
.outil-sources {
  margin: 0;
  padding-left: 22px;
  font-size: var(--fs-small);
  line-height: 1.65;
  color: var(--ps-text-muted);
}
.outil-sources li { margin-bottom: 10px; }
.outil-sources li:last-child { margin-bottom: 0; }

/* Renvois de fin de page vers le blog. Même densité que les listes de contenu :
   ce sont des propositions de lecture, pas une note de bas de page. */
.outil-renvois {
  margin: 0;
  padding-left: 22px;
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--ps-text-body);
}
.outil-renvois li { margin-bottom: 14px; }
.outil-renvois li:last-child { margin-bottom: 0; }
.outil-intro-form {
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--ps-text-muted);
  margin: 0 0 28px;
}

/* =====================================================
   Illustrations
   Reprise du composant figure du blog (.post-figure--wide de blog.css), à deux
   différences près, toutes deux assumées :
    · les classes sont préfixées .outil- : celles du blog dépendent du conteneur
      `.post`, absent ici (`.post a.post-figure-zoom` ne s'appliquerait pas) ;
    · PAS de modale d'agrandissement. Le blog en a une (post-lightbox.js), mais elle
      demande ~70 lignes de CSS supplémentaires qu'il faudrait dupliquer et maintenir
      en double. Le lien vers le fichier pleine résolution suffit : le visualiseur
      natif du navigateur assure le zoom, au pinch comme au clavier — c'est d'ailleurs
      le repli que blog.css documente pour les visiteurs sans JavaScript.
   ===================================================== */
.outil-figure {
  margin: 36px 0;
}
.outil-figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--ps-border-light);
  border-radius: var(--ps-radius-lg);
  box-shadow: var(--ps-shadow-ring);
}
.outil-figure figcaption {
  margin-top: 12px;
  max-width: 68ch;
  margin-inline: auto;
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--ps-text-muted);
  text-align: center;
}
/* Ces schémas portent des montants au centime : ils ont besoin de plus que la
   colonne de lecture, mais surtout pas de toute la fenêtre. 75 % de la largeur,
   centrés, plafonnés à 1500 px — les sources font 1672 px, au-delà on afficherait
   un pixel au-delà de sa définition.

   ⚠ NE PAS recopier ici la règle du blog (`clamp(100%, 75vw, 1500px)` avec
   `margin-left: 50%` et `transform: translateX(-50%)`). Elle produit un débord
   MAÎTRISÉ uniquement parce que, dans un article, la figure est enfant d'une
   colonne de ~720 px : le `100%` du clamp vaut alors 720 px et c'est le `75vw`
   qui l'emporte. Ici les figures sont enfants directes de <main>, donc ce `100%`
   vaut 100vw et gagne toujours : l'image partait bord à bord. */
.outil-figure--wide {
  width: min(75vw, 1500px);
  margin-inline: auto;
}
.outil-figure--wide img {
  box-shadow: var(--ps-shadow-lift);
}
.outil-figure-zoom {
  display: block;
  position: relative;
  cursor: zoom-in;
  text-decoration: none;
}
.outil-figure-zoom img {
  transition: box-shadow 160ms ease;
}
.outil-figure-zoom:hover img {
  box-shadow: var(--ps-shadow-lift-hover);
}
/* Pastille loupe : rend l'agrandissement découvrable au tactile, où aucun curseur
   ne vient le signaler. */
.outil-figure-zoom::after {
  content: "";
  position: absolute;
  right: 14px;
  bottom: 14px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.94) center / 20px 20px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23212529' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.8-3.8M11 8.5v5M8.5 11h5'/%3E%3C/svg%3E");
  box-shadow: var(--ps-shadow-lift);
  opacity: 0.55;
  transition: opacity 160ms ease;
}
.outil-figure-zoom:hover::after,
.outil-figure-zoom:focus-visible::after {
  opacity: 1;
}
/* Sur mobile, 75 % de la fenêtre rendrait les montants illisibles : on prend toute
   la largeur disponible, moins la gouttière des sections. */
@media (max-width: 860px) {
  .outil-figure--wide {
    width: calc(100% - 40px);
  }
}

/* =====================================================
   Formulaire de calcul
   ===================================================== */
.mfba {
  border: 0;
  margin: 0 0 32px;
  padding: 0;
}
.mfba-group {
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-md);
  background: var(--ps-bg-card);
  padding: 20px;
  margin-bottom: 20px;
}
.mfba-group > legend {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ps-primary);
  padding: 0 8px;
  margin-left: -8px;
}
.mfba-field { margin-bottom: 20px; }
.mfba-field:last-child { margin-bottom: 0; }

/* Champs appariés. Cinq paires du formulaire sont logiquement liées (un montant
   et son taux, un port et une préparation) : les empiler doublait la hauteur du
   formulaire sans rien clarifier. Le seuil est bas — dès 620 px une colonne de
   ~290 px accueille un champ de 180 px et son aide. */
/* Empilés tant que la place manque : l'espacement reste porté par les champs. */
.mfba-duo > .mfba-field { margin-bottom: 20px; }
.mfba-duo:last-child > .mfba-field:last-child { margin-bottom: 0; }

@media (min-width: 620px) {
  /* Grille de TROIS rangées — labels, champs, aides — et non deux colonnes de
     blocs empilés. La différence se voit dès qu'un label passe sur deux lignes :
     en colonnes de blocs, le champ voisin descend d'une ligne et les deux
     champs cessent d'être alignés. Ici chaque rangée impose son propre
     alignement, quelle que soit la longueur des libellés. */
  .mfba-duo {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 20px;
    align-items: start;
    margin-bottom: 20px;
  }
  .mfba-duo:last-child { margin-bottom: 0; }

  /* Le conteneur de champ s'efface pour que ses trois éléments deviennent
     enfants directs de la grille. .mfba-field n'a ni rôle ARIA ni sémantique à
     préserver : c'est un div de regroupement, et le lien label/champ passe par
     l'attribut `for`, que la mise en page ne touche pas. */
  .mfba-duo > .mfba-field { display: contents; }
  .mfba-duo > .mfba-field > label { grid-row: 1; }
  .mfba-duo > .mfba-field > .mfba-input-unit { grid-row: 2; }
  .mfba-duo > .mfba-field > .mfba-aide { grid-row: 3; }
  .mfba-duo > .mfba-field:first-child > * { grid-column: 1; }
  .mfba-duo > .mfba-field:last-child > * { grid-column: 2; }
}

.mfba-field > label,
.mfba-radios > legend {
  display: block;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ps-text);
  margin-bottom: 7px;
}

/* L'aide est un commentaire, pas une consigne : elle doit se lire quand on la
   cherche et disparaître quand on remplit. Deux corrections à l'origine du
   « tout au même niveau » — la couleur (--ps-text-muted vaut #495057, presque
   aussi sombre que le label) et la largeur (une aide qui s'étire sur toute la
   colonne devient le bloc le plus large du formulaire, donc le plus vu). */
.mfba-aide {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ps-text-secondary);
  max-width: 54ch;
  margin: 7px 0 0;
}
.mfba-aide a {
  color: var(--ps-primary);
  text-decoration: underline;
}

/* Champ numérique suffixé par son unité (€, %) */
/* 180 px : la place d'un montant à cinq chiffres et deux décimales, pas plus. À
   260 px le champ était vide aux trois quarts et paraissait moins important que
   le paragraphe d'aide posé dessous. */
.mfba-input-unit {
  display: flex;
  align-items: stretch;
  max-width: 180px;
}
.mfba-input-unit input {
  flex: 1;
  min-width: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  color: var(--ps-text);
  background: var(--ps-bg-card);
  border: 1px solid var(--ps-border-light);
  border-right: 0;
  border-radius: var(--ps-radius-sm) 0 0 var(--ps-radius-sm);
  padding: 11px 13px;
  transition: border-color var(--ps-transition), box-shadow var(--ps-transition);
}
.mfba-input-unit input:focus {
  outline: none;
  border-color: var(--ps-primary);
  box-shadow: 0 0 0 3px rgba(var(--ps-primary-rgb), 0.15);
}
.mfba-input-unit input:focus-visible { outline: 2px solid transparent; }
.mfba-unit {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  padding: 0 12px;
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  /* --ps-text-secondary ne tiendrait que 4,45:1 sur le gris de --ps-bg-hover,
     juste sous le seuil AA. Le suffixe garde donc la teinte plus dense. */
  color: var(--ps-text-muted);
  background: var(--ps-bg-hover);
  border: 1px solid var(--ps-border-light);
  border-radius: 0 var(--ps-radius-sm) var(--ps-radius-sm) 0;
}

.mfba select {
  width: 100%;
  max-width: 340px;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  color: var(--ps-text);
  background: var(--ps-bg-card);
  border: 1px solid var(--ps-border-light);
  border-radius: var(--ps-radius-sm);
  /* Le chevron natif est dessiné à droite de la boîte de contenu : c'est le
     padding droit qui l'écarte du bord, et 14 px le laissaient collé au filet. */
  padding: 12px 22px 12px 14px;
}
.mfba select:focus {
  outline: none;
  border-color: var(--ps-primary);
  box-shadow: 0 0 0 3px rgba(var(--ps-primary-rgb), 0.15);
}

/* Radios et case à cocher */
.mfba-radios {
  border: 0;
  margin: 0;
  padding: 0;
}
.mfba-radio,
.mfba-checkbox {
  display: block;
  position: relative;
  padding: 11px 14px 11px 38px;
  margin-bottom: 6px;
  font-size: 15px;
  line-height: 1.4;
  color: var(--ps-text-body);
  background: var(--ps-bg-card);
  border: 1px solid var(--ps-border-light);
  border-radius: var(--ps-radius-sm);
  cursor: pointer;
  transition: border-color var(--ps-transition), background var(--ps-transition);
}
.mfba-radio:hover,
.mfba-checkbox:hover { border-color: var(--ps-primary-border); }
.mfba-radio:has(input:checked),
.mfba-checkbox:has(input:checked) {
  border-color: var(--ps-primary);
  background: var(--ps-primary-light);
}
.mfba-radio input,
.mfba-checkbox input {
  position: absolute;
  left: 13px;
  top: 13px;
  width: 16px;
  height: 16px;
  accent-color: var(--ps-primary);
  cursor: pointer;
}
.mfba-radio input:focus-visible,
.mfba-checkbox input:focus-visible {
  outline: 2px solid var(--ps-primary);
  outline-offset: 3px;
}
/* Même corps que .mfba-aide, mais la teinte reste --ps-text-muted : la note passe
   sur le bleu clair de l'option cochée, où --ps-text-secondary serait trop pâle. */
.mfba-radio-note {
  display: block;
  font-size: 13px;
  color: var(--ps-text-muted);
  margin-top: 2px;
}

/* =====================================================
   Panneau de résultats
   ===================================================== */
.mfba-resultat {
  background: var(--ps-bg-app);
  border: 1px solid var(--ps-border);
  border-radius: var(--ps-radius-lg);
  padding: 24px;
}
.mfba-resultat-titre {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ps-text-muted);
  margin-bottom: 20px;
}
/* La vedette et les trois lignes de détail forment UN bloc blanc continu : rayons
   complémentaires, bordure partagée, aucun conteneur supplémentaire. Le filet qui
   les sépare porte toute la hiérarchie — au-dessus le chiffre qu'on vient
   chercher, en dessous ceux qu'on lit ensuite. */
.mfba-kpi--principal {
  background: var(--ps-bg-card);
  border: 1px solid var(--ps-border);
  border-bottom: 0;
  border-radius: var(--ps-radius-md) var(--ps-radius-md) 0 0;
  padding: 16px 18px 18px;
}
.mfba-kpi-label {
  display: block;
  font-size: var(--fs-small);
  color: var(--ps-text-secondary);
  margin-bottom: 2px;
}
.mfba-kpi-valeur {
  display: block;
  /* Chiffres en Inter plutôt qu'en mono. En chasse fixe, la virgule occupe une
     chasse pleine et « −0,39 » se lit délavé, espacé — un ticket de caisse. Les
     tabular-nums d'Inter conservent la largeur constante qui empêche la valeur
     de sauter à chaque frappe, sans le relâchement. */
  font-family: var(--font-sans);
  font-size: 46px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--ps-text);
  /* Le nombre et son unité sont deux nœuds distincts — le script ne réécrit que le
     premier. Ils ne doivent jamais être séparés par un retour à la ligne. */
  white-space: nowrap;
}
.mfba-kpi-valeur .mfba-devise,
.mfba-kpi-valeur .mfba-unit-kpi {
  font-size: 24px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ps-text-secondary);
  margin-left: 5px;
}
.mfba-kpi--negatif .mfba-kpi-valeur { color: var(--ps-error); }
.mfba-kpi--positif .mfba-kpi-valeur { color: var(--ps-success-dark); }

.mfba-details {
  margin: 0 0 20px;
  padding: 0 18px;
  background: var(--ps-bg-card);
  border: 1px solid var(--ps-border);
  /* Pas de bordure haute : le filet sous la vedette est déjà posé par le
     border-top du premier .mfba-detail. Les deux cumulés donnaient un trait de
     2 px, seul endroit du panneau où l'épaisseur doublait. */
  border-top: 0;
  border-radius: 0 0 var(--ps-radius-md) var(--ps-radius-md);
}
.mfba-detail {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-top: 1px solid var(--ps-border);
}
.mfba-details dt {
  font-size: var(--fs-small);
  line-height: 1.35;
  color: var(--ps-text-secondary);
}
.mfba-details dd {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ps-text);
  white-space: nowrap;
}
/* Largeur d'unité constante. Les trois valeurs sont alignées à droite, mais « % »
   est plus large que « € » : sans cette réserve, les chiffres eux-mêmes se
   décalent de deux ou trois pixels d'une ligne à l'autre — ce qui se voit
   précisément parce que tout le reste est aligné. */
.mfba-details dd .mfba-devise,
.mfba-details dd .mfba-unit-kpi {
  display: inline-block;
  min-width: 11px;
  text-align: right;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ps-text-secondary);
  margin-left: 3px;
}

.mfba-verdict {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ps-text);
  font-weight: 600;
  margin: 0 0 12px;
}
.mfba-rappel {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--ps-text-muted);
  background: var(--ps-bg-card);
  border-left: 3px solid var(--ps-primary-border);
  padding: 10px 14px;
  margin: 0 0 12px;
}
.mfba-rappel[hidden] { display: none; }
/* Le disclaimer doit rester lisible sans peser autant que le résultat : 13 px sur
   le fond gris du panneau, où --ps-text-secondary tomberait à 4,3:1 et manquerait
   le seuil AA. La teinte reste donc --ps-text-muted, seul le corps recule. */
.mfba-disclaimer {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ps-text-muted);
  margin: 0;
}

/* ----- Desktop : formulaire et résultats côte à côte ----- */
@media (min-width: 900px) {
  #calculateur .container {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
    grid-template-areas:
      "titre  titre"
      "intro  intro"
      "form   resultat";
    gap: 0 32px;
    max-width: 1100px;
  }
  #calculateur h2 { grid-area: titre; }
  #calculateur .outil-intro-form { grid-area: intro; }
  #calculateur .mfba { grid-area: form; }
  #calculateur .mfba-resultat {
    grid-area: resultat;
    align-self: start;
    position: sticky;
    top: 24px;
  }
}
