/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* Information au POINT DE COLLECTE des deux démonstrations d'IA (31/07).
   L'article 13 du RGPD demande l'information LÀ OÙ la donnée est recueillie, pas seulement au fond
   d'une page légale : ni /mangaka ni /atelier n'en portaient la moindre trace. Le lien est discret
   par construction (il ne doit pas voler la vedette au dessin) mais il reste visible, y compris sur
   téléphone — c'est pour ça qu'il ne réutilise pas `.kr-mangaka-lien`, masquée sous 900 px.
   Styles d'INSTANCE : les deux pages n'existent que sur esms-tech (features demo_pixels/mangaka). */
.vit-demo-vieprivee { margin: 0; padding: 0 16px 12px; font-size: 11.5px; opacity: 0.75; }
.vit-demo-vieprivee a { color: inherit; }

/* ── LE PITCH DES DEUX DÉMONSTRATIONS D'IA (31/07) ────────────────────────────────────────────────
   Demande de Max : « une petite explication du projet en haut de la fenêtre, en mode à la cool ».
   Ces deux pages sont des VITRINES D'INGÉNIERIE : le texte est là pour montrer ce qu'on sait faire.

   ⛔ REPLIÉ PAR DÉFAUT, ET CE N'EST PAS UN CONFORT DE LECTURE. Le visiteur vient ESSAYER : si le
   texte pousse le bouton sous la ligne de flottaison, il a raté son but quelle que soit sa qualité.
   Sur /atelier c'est même une condition de fonctionnement — la page tient en hauteur d'écran fixe et
   ne scrolle pas (kraken_scene.css:12, height: calc(100vh - 88px)) : un bloc déplié y écraserait le
   fil de messages, d'où le max-height + overflow posés sur le corps dans ce contexte-là seulement.

   ⭐ <details> NATIF, ZÉRO JAVASCRIPT, et les trois raisons sont dans cet ordre : la CSP de cette app
   pose `script_src :self` (aucun script inline, content_security_policy.rb) ; le repli natif est
   accessible au clavier et aux lecteurs d'écran sans une ligne de notre part ; refermé à chaque
   visite, il ne peut JAMAIS voler la place de l'outil. Un localStorage a été envisagé puis ÉCARTÉ :
   il ne servirait qu'à laisser le pavé OUVERT au retour, c'est-à-dire exactement le comportement
   qu'on cherche à éviter. Le lecteur qui revient ne relit rien, il a déjà une seule ligne.

   ⚠️ LE PLACEMENT DÉCIDE DE TOUT, ET IL DIFFÈRE SUR LES DEUX PAGES :
   - /mangaka : dans la colonne du ROULEAU, sous le titre, au-dessus du ruban. Le champ d'écriture et
     le bouton « Dessine ! » vivent dans l'AUTRE colonne : le pitch ne s'interpose donc jamais entre
     le visiteur et l'action, et il sort de l'écran tout seul dès que les cases descendent, sans une
     ligne de code. Largeur calée sur celle du ruban, pour que la colonne se lise d'un bloc.
   - /atelier : en tête du PANNEAU DE CHAT, et surtout JAMAIS au-dessus du <main>. Un bandeau posé
     au-dessus volerait des pixels au canvas, or sampleOctopus() ré-échantillonne la créature sur la
     hauteur RÉELLE du canvas et se relance au resize (kraken_scene.js) : le déplier recalculerait
     toute la créature et casserait l'animation en cours.

   L'accent se branche sur les tokens de chaque page (le sceau rouge du Mangaka, le teal de la
   scène) : le pitch appartient visuellement à la page où il est posé, il n'y est pas collé.
   Styles d'INSTANCE (#0031) : un 3e client qui monte site_vitrine n'a ni Mangaka ni atelier. */
.vit-pitch {
  --vp-accent: #b3271e;
  --vp-bord: rgba(22, 24, 29, 0.13);
  --vp-fond: #ffffff;
  margin: 0 0 20px;
  background: var(--vp-fond);
  border: 1px solid var(--vp-bord);
  border-left: 3px solid var(--vp-accent);
  font-size: 13.5px;
  line-height: 1.55;
}
.vit-pitch > summary { list-style: none; cursor: pointer; position: relative;
  padding: 10px 34px 10px 14px; font-weight: 600; }
.vit-pitch > summary::-webkit-details-marker { display: none; }
.vit-pitch > summary::after { content: "▾"; position: absolute; right: 13px; top: 50%;
  transform: translateY(-50%); color: var(--vp-accent); transition: transform 0.18s ease; }
.vit-pitch[open] > summary::after { transform: translateY(-50%) rotate(180deg); }
.vit-pitch > summary:hover { background: rgba(0, 0, 0, 0.025); }
.vit-pitch > summary:focus-visible { outline: 2px solid var(--vp-accent); outline-offset: -2px; }

.vit-pitch-corps { padding: 2px 14px 12px; }
.vit-pitch-corps p { margin: 0 0 9px; }
.vit-pitch-corps ul { margin: 0 0 9px; padding-left: 18px; }
.vit-pitch-corps li { margin-bottom: 6px; }
.vit-pitch-corps .vit-pitch-quoi { font-size: 15px; font-weight: 600; }
/* Le « parce qu'on pouvait » est la blague qui porte tout le message : elle a droit à sa couleur. */
.vit-pitch-corps .vit-pitch-coup span { color: var(--vp-accent); font-weight: 700; }
.vit-pitch-corps .vit-pitch-h { margin: 15px 0 5px; font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase; opacity: 0.55; }
.vit-pitch-corps .vit-pitch-rythme { opacity: 0.72; }
.vit-pitch-corps .vit-pitch-chute { margin: 13px 0 0; padding-top: 10px;
  border-top: 1px solid var(--vp-bord); font-weight: 600; }
.vit-pitch-chute a { color: var(--vp-accent); white-space: nowrap; }

.kr-mangaka .vit-pitch { --vp-accent: var(--kr-mangaka-accent); --vp-fond: var(--kr-mangaka-papier);
  max-width: 620px; margin: 0 auto 20px; }

/* Dans le panneau de chat, le pitch est un ITEM FLEX qui ne doit ni s'étirer ni se comprimer :
   flex 0 0 auto, et c'est son corps qui scrolle quand il est ouvert. Sans ça, le fil de messages
   (flex: 1) se ferait écraser à zéro sur un écran court. */
.kr-scene-chat > .vit-pitch { --vp-accent: var(--kr-scene-accent); --vp-bord: var(--kr-scene-line);
  margin: 0; border: 0; border-bottom: 1px solid var(--vp-bord);
  border-left: 3px solid var(--vp-accent); }

/* ⛔⛔ LA PLACE DE LA SAISIE EST INTOUCHABLE, ET C'EST DU FLEX QUI DOIT LE GARANTIR, PAS UN CHIFFRE.
   Mesuré au navigateur le 31/07 : sur un téléphone de 844 px, déplier le pitch envoyait le bouton
   « Envoyer » à 851 px, donc HORS DE L'ÉCRAN — sur une page qui, par construction, ne scrolle pas
   (kraken_scene.css:12). L'outil devenait inutilisable pour lire du texte qui vante l'outil.

   ⚠️ La première correction était un plafond en pixels sur le corps du pitch. Elle marchait sur le
   téléphone que je mesurais et se serait cassée sur le suivant : la colonne de chat, elle, est en
   vh (le stage garde 55vh), donc un plafond fixe redevient trop grand dès que l'écran raccourcit.
   Un réglage juste sur un seul appareil n'est pas un réglage.

   La règle qui tient sur tous les écrans, sans arithmétique : le pitch est le SEUL bloc autorisé à
   se comprimer, et son corps scrolle. Les trois commandes sont clouées à `flex: 0 0 auto`, le fil
   de messages garde sa part (base 0, il ne participe pas au retrait), et le trop-plein n'a donc
   qu'un seul endroit où aller : l'intérieur du pitch. `<details>` passe en colonne flex quand il
   est ouvert, sans quoi son corps ne saurait pas se comprimer.
   ⛔ On ne récupère JAMAIS la place sur le canvas : sampleOctopus() ré-échantillonne la créature sur
   la hauteur réelle du canvas et se relance au resize (kraken_scene.js). Le déplier la recalculerait
   et casserait l'animation en cours. Le pitch se serre, le canvas ne bouge pas. */
/* ⚠️ LE MAILLON SANS LEQUEL TOUT LE RESTE EST DÉCORATIF, et il m'a coûté une mesure fausse : le
   panneau de chat est lui-même un item flex de `.kr-scene`, dont la hauteur est FIXE. Laissé à
   `min-height: auto`, il grandit à la hauteur de son contenu et déborde son parent en silence — donc
   aucune pression de retrait n'atteint jamais ses enfants, et tout le réglage ci-dessous ne sert à
   rien. Mesuré : sans cette ligne, le bouton descendait à 953 px pour un écran de 844. */
.kr-scene > .kr-scene-chat { min-height: 0; }
.kr-scene-chat > .vit-pitch { flex: 0 1 auto; min-height: 0; }
/* ⚠️ `overflow: hidden` N'EST PAS UNE PRÉCAUTION, c'est la moitié du mécanisme : comprimer une boîte
   ne découpe pas son contenu. Sans lui, le pitch se serrait bien mais son texte continuait à se
   peindre PAR-DESSUS le fil de messages, les boutons de style et la ligne de saisie (constaté en
   capture, 390x844). Le corps est le seul enfant qui absorbe le retrait, et il scrolle. */
.kr-scene-chat > .vit-pitch[open] { display: flex; flex-direction: column; overflow: hidden; }
.kr-scene-chat > .vit-pitch[open] > summary { flex: 0 0 auto; }
.kr-scene-chat > .vit-pitch[open] > .vit-pitch-corps { flex: 1 1 auto; }
.kr-scene-chat > .vit-pitch .vit-pitch-corps { min-height: 0; max-height: 44vh; overflow-y: auto; }
.kr-scene-chat > .kr-scene-mode,
.kr-scene-chat > .kr-scene-input-row,
.kr-scene-chat > .vit-demo-vieprivee { flex: 0 0 auto; }

/* ⛔ LE DÉFAUT QUE CE PITCH A CRÉÉ, ET QUI NE SE VOIT QU'EN TÉLÉPHONE (trouvé à la capture, 31/07 :
   le bouton « Envoyer » sortait de l'écran, bas à 986 px pour une fenêtre de 844).
   La cause n'est pas la hauteur du texte, c'est que `.kr-scene-msgs` est un item flex laissé à
   `min-height: auto` : un item flex refuse par défaut de descendre sous la hauteur de son contenu,
   donc dès que le fil portait le message d'accueil, la colonne débordait par le BAS et emportait la
   ligne de saisie avec elle. Le pitch n'a fait que révéler la fragilité en ajoutant un frère.
   `min-height: 0` rend au fil le droit de se comprimer — il a déjà `overflow-y: auto`, il scrolle.
   ⭐ On corrige ICI et pas dans la brique parce que c'est NOTRE ajout qui charge la colonne : un
   3e client qui monte kraken_scene sans pitch n'a pas ce voisin (#0031). */
.kr-scene-chat > .kr-scene-msgs { min-height: 0; }

@media (max-width: 900px) {
  .vit-pitch { font-size: 13px; }
  .vit-pitch-corps .vit-pitch-quoi { font-size: 14px; }
}
/* Sous 720 px l'atelier passe en colonne et le stage garde 55vh : il ne reste qu'environ 290 px au
   panneau de chat. Le plafond en vh n'y sert plus à rien (c'est le flex ci-dessus qui garantit la
   saisie) mais il évite au pitch de manger tout le fil de messages avant même de se comprimer. */
@media (max-width: 720px) {
  .kr-scene-chat > .vit-pitch .vit-pitch-corps { max-height: 34vh; }
  /* ⚠️ LE BUDGET RÉEL, MESURÉ ET PAS SUPPOSÉ : sur un 390x844, le panneau de chat reçoit 292 px, dont
     176 sont pris par l'en-tête du pitch, les deux boutons de style, la ligne de saisie et la note
     vie privée. Il reste donc 116 px À PARTAGER entre le fil de messages et le corps du pitch, et
     aucune règle CSS ne créera un pixel de plus — les seules façons d'en gagner seraient de
     rétrécir le canvas (interdit, ça recalcule la créature) ou de laisser la page scroller (elle
     perdrait la saisie de vue, ce qu'on refuse).
     Alors on tranche au lieu de partager : tant que le pitch est OUVERT, le fil rend sa place et le
     texte prend les 116 px ; à la fermeture, le fil la reprend entière. Celui qui déplie veut lire,
     celui qui a refermé veut discuter, et personne ne perd le bouton Envoyer.
     Si `:has()` manque au navigateur, on retombe sur la règle du dessus : plus serré, jamais cassé. */
  .kr-scene-chat:has(> .vit-pitch[open]) > .kr-scene-msgs { flex: 0 1 0; padding-block: 0; }
}

/* ⛔⛔ DEUX BARRES FIXES AU MÊME ENDROIT : LE BOUTON « Dessine ! » ÉTAIT MORT AU TÉLÉPHONE (31/07).
   Mesuré au navigateur, 390x780, PREMIER chargement de /mangaka (visiteur qui n'a pas encore tranché
   sur les cookies) : le bandeau de consentement se pose EXACTEMENT sur la rangée d'actions du
   pupitre. Verdicts elementFromPoint, ce ne sont pas des estimations :
     .kr-mangaka-send   [738,772] -> RECOUVERT par BUTTON.kt-btn-no
     .kr-mangaka-auto   [739,771] -> RECOUVERT par P.kt-consent-txt
     .kr-mangaka-copier [739,771] -> RECOUVERT par P.kt-consent-txt
   ⚠️ Ce n'est pas « gênant », c'est PIRE que recouvert : le clic réel sur « Dessine ! » a déclenché
   « Non merci ». Le visiteur qui veut lancer son dessin refuse en fait les cookies, et rien ne se
   dessine. Le textarea, lui, reste cliquable : on peut écrire son histoire et on n'a AUCUN moyen de
   la lancer. kraken_mangaka.js n'écoute ni Enter ni keydown, le seul déclencheur est le click : il
   n'existe aucun chemin de secours.
   ⚠️ ET LE SCROLL NE SAUVE RIEN : les DEUX blocs sont `position:fixed`. Vérifié à scrollY = maxScroll
   (247 px), les deux rectangles n'avaient pas bougé d'un pixel. Idem pour `.kt-consent-spacer` : il
   vit dans le flux, il ne déplacera JAMAIS un élément fixe. Sur cette page il est structurellement
   impuissant, alors qu'il fait correctement son travail sur les 8 autres (vérifié une par une).
   ⭐ CIBLE DU DÉFAUT : 100 % des PREMIÈRES visites téléphone, c'est-à-dire exactement la population
   que le pitch va chercher. Le bandeau disparaît dès que le visiteur tranche, donc le défaut est
   invisible pour quiconque a déjà visité le site une fois — Max le premier. Vert-et-vide de manuel :
   la page répond 200 et l'outil est mort.

   ⛔ POURQUOI ICI ET PAS DANS UNE BRIQUE. Ni kraken_tracker (montée sur 5 apps) ni kraken_mangaka ne
   sont fautives : chacune fait correctement son travail. Le défaut n'apparaît que parce que CETTE
   instance monte les deux ensemble, et qu'elles posent une barre fixe au même endroit. C'est un
   problème de COMPOSITION, il appartient à l'app qui compose (#0031). application.css est chargé en
   dernier par le layout, il gagne donc la cascade sans un seul !important.

   Les deux chiffres viennent d'ailleurs, ils ne sont pas inventés :
   - 5rem = la place que la brique DÉCLARE elle-même réclamer sous 640 px (.kt-consent-spacer). On
     consomme le chiffre du tracker au lieu d'en inventer un. Mesure : le bandeau occupe 58 px depuis
     le bas, 80 px laissent la marge pour sa version deux lignes.
   - 296px = les 216px que le rouleau réserve déjà pour ne jamais finir sous la barre, PLUS les 80 px
     dont la barre vient de monter.
   ⭐ `:has()` EST CE QUI REND LA CORRECTION AUTO-RÉVERSIBLE, et c'est la seule raison de l'employer :
   vérifié au navigateur, le bandeau QUITTE le DOM dès que le visiteur tranche, donc la règle se
   désarme toute seule et on ne laisse pas 80 px de trou permanent à ceux qui ont déjà choisi. Si un
   vieux moteur ignore `:has()`, la règle est simplement inerte : on retombe sur le comportement
   d'aujourd'hui, jamais sur pire.
   ⛔ LE BANDEAU NE BOUGE PAS D'UN PIXEL : même place, même taille, « D'accord » et « Non merci »
   restent cliquables. L'obligation CNIL est intacte, c'est le contenu de la page qui s'écarte. */
@media (max-width: 900px) {
  body:has(.kt-consent) .kr-mangaka-pupitre { bottom: 5rem; }
  body:has(.kt-consent) .kr-mangaka-rouleau { padding-bottom: 296px; }
}

/* ⛔ LE PIED DE PAGE LÉGAL DE /mangaka, MASQUÉ PAR LA BARRE D'ÉCRITURE, BANDEAU OU PAS (31/07).
   C'est un défaut SÉPARÉ du précédent et il survivait à l'acceptation des cookies. Mesuré au scroll
   maximum, APRÈS acceptation : .vit-foot [554,700] RECOUVERT par la zone de saisie, .vit-legal
   [626,668] RECOUVERT par le miroir du texte. Les mentions légales, la politique de confidentialité
   et la page cookies étaient donc inatteignables sur cette page au téléphone. Exactement le défaut
   fermé sur support_public le 31/07, resté ouvert ici.
   ⚠️ 320px ET PAS 216px, parce que la mesure a contredit le calcul : le pupitre fait 242 px de haut
   avec ses amorces (rect [538,780]), et la zone de saisie grandit encore de 70 px quand le texte
   s'allonge (max-height 128 contre 58 au repos). 320 couvre le pupitre à sa hauteur MAXIMALE. Ces
   pixels ne coûtent aucun blanc visible : ils vivent sous le pied de page, derrière la barre fixe.
   Le sélecteur de frère vise la seule page concernée, le footer est partagé par tout le site. */
@media (max-width: 900px) {
  main.kr-mangaka ~ .vit-foot { margin-bottom: 320px; }
}

/* ⛔ NE DÉPLACEZ PAS `render "kraken_tracker/tracker"` AVANT LE PIED DE PAGE DANS LE LAYOUT. C'est la
   correction évidente, elle a été essayée le 31/07, MESURÉE, et elle EMPIRE les choses. Gardée ici
   parce qu'elle se re-proposera toute seule à la prochaine lecture du layout.
   Le raisonnement qui séduit : l'espaceur vit dans le flux, donc il devrait pousser le pied de page
   au-dessus du bandeau, et aujourd'hui il tombe SOUS lui. Ce que la mesure a répondu, 390x780, au
   scroll maximum, tracker déplacé avant le footer :
     /mentions-legales  .vit-legal [706,748] -> RECOUVERT par DIV.kt-consent
     /cookies           .vit-legal [706,748] -> RECOUVERT par DIV.kt-consent
     /vos-droits        .vit-legal [707,749] -> RECOUVERT par DIV.kt-consent
     /atelier           .vit-legal [706,748] -> RECOUVERT par DIV.kt-consent
   Quatre pages légales dont les liens ne sont alors atteignables À AUCUNE position de scroll, alors
   qu'ils l'étaient. La cause : rendu APRÈS le pied de page, l'espaceur est le dernier bloc du
   document et fait donc office de MARGE DE FIN. Au scroll maximum, le bas du document s'aligne sur
   le bas de l'écran, et ces 80 px sont exactement ce qui décolle le pied du bandeau. Remonté avant
   le pied, il pousse bien le contenu, mais il rend le pied dernier : le pied se colle au bas de
   l'écran, là où le bandeau est ancré. On perd plus qu'on ne gagne.
   ⭐ Vérifié une par une, les 9 pages ont leurs liens légaux cliquables au scroll maximum avec
   l'ordre ACTUEL. Seul reste /atelier AVANT tout scroll (page courte, pied déjà à l'écran) : les
   138 px de défilement disponibles suffisent à le dégager, aucun contenu n'est inatteignable. */

/* ═══════════════════════════════════════════════════════════════════════════════════════════════
   FICHES MEMBRES (/equipe/<slug>, 31/07) — une page de VENTE d'une personne.

   ⭐ CE BLOC EST VOLONTAIREMENT COURT, ET C'EST LE POINT. La vitrine sait déjà tout faire : le hero
   papier millimétré et son surlignage pétrole, les piliers, la bande sombre en dégradé, la grille
   numérotée, l'apparition au scroll par IntersectionObserver avec son repli prefers-reduced-motion.
   La fiche ASSEMBLE ces composants au lieu d'inventer un second système de design — c'est ce qui la
   fait ressembler à la maison plutôt qu'à une page collée. Rythme retenu : clair, chiffres, piliers,
   SOMBRE, clair, clair, citation, appel à l'action. C'est le contraste qui produit l'effet, pas
   l'animation. Ne restent ici que les quelques pièces qui n'existaient pas : le médaillon, la bande
   de chiffres, les pastilles de compétence et la citation.

   ⚠️ TOUTE GRILLE AJOUTÉE DOIT REPASSER EN COLONNE DANS LE BLOC @media (max-width:900px) EN BAS DE
   CE FICHIER. esms_ui pose ses grilles en repeat(3,1fr) EN DUR et ne les déplie que là ; une grille
   neuve oubliée resterait sur trois colonnes de 130 px au téléphone.
   Styles d'INSTANCE (#0031) : un 3e client qui monte site_vitrine n'a pas de fiches membres.
   ═══════════════════════════════════════════════════════════════════════════════════════════════ */

/* En-tête minimal : la marque, et RIEN d'autre. Ce n'est pas une économie de moyens, c'est la
   demande — la fiche ne doit être atteignable que par son adresse, donc elle ne porte aucune
   navigation qui pourrait un jour se mettre à énumérer les pages. Le lien sortant vers l'accueil
   évite le cul-de-sac pour le lecteur qui veut savoir qui est derrière. */
.mb-top { display: flex; align-items: center; padding: 1.1rem clamp(1rem, 5vw, 3rem); }
.mb-top .es-brand { text-decoration: none; }

.mb-hero { display: grid; grid-template-columns: 1fr auto; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.mb-hero h1 { max-width: 18ch; }
.mb-identite { margin: 0 0 1.3rem; font-size: 1.02rem; color: var(--es-ink); font-weight: 600; }
.mb-identite b { font-size: 1.12rem; }
.mb-sep { color: var(--es-brand); margin: 0 .5rem; font-weight: 700; }

/* Le médaillon. `object-fit: cover` sur un carré fixe : une photo de n'importe quel format y entre
   sans se déformer, ce qui évite d'exiger de Max une image parfaitement calibrée. */
.mb-portrait { margin: 0; width: 260px; height: 260px; border-radius: 28px; overflow: hidden;
  background: linear-gradient(160deg, var(--es-deep), var(--es-deep2));
  display: flex; align-items: center; justify-content: center; flex: none;
  border: 6px solid #fff; box-shadow: 0 18px 50px rgba(4, 47, 46, .22); }
.mb-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mb-initiales { font-family: var(--es-mono); font-size: 4.6rem; font-weight: 700; color: #fff;
  letter-spacing: .04em; }

/* La bande de chiffres, juste sous le hero : la preuve arrive AVANT les qualités, c'est le seul
   endroit où un CV cesse d'être une déclaration. Filet pétrole à gauche pour la rattacher aux
   piliers de la maison. */
.mb-chiffres-wrap { background: #fff; border-bottom: 1px solid var(--es-line); }
.mb-chiffres { max-width: 1240px; margin: 0 auto; padding: clamp(1.6rem, 3vw, 2.4rem) clamp(1rem, 5vw, 3rem);
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.4rem; }
.mb-chiffre { border-left: 3px solid var(--es-brand); padding-left: 1rem; }
.mb-chiffre b { display: block; font-size: clamp(1.9rem, 3.4vw, 2.6rem); line-height: 1;
  letter-spacing: -.03em; color: var(--es-ink); }
.mb-chiffre span { display: block; margin-top: .4rem; color: var(--es-muted); font-size: .88rem; line-height: 1.45; }

/* Réalisations sur la bande sombre : problème, ce que j'ai construit, résultat. Le résultat est la
   seule ligne mise en avant, parce que c'est la seule que le lecteur retient. */
.mb-real { display: flex; flex-direction: column; }
.mb-real-l { margin: 0 0 .6rem !important; }
.mb-real-l b { color: var(--es-accent); font-weight: 700; }
.mb-real-out { margin-top: auto !important; padding-top: .7rem;
  border-top: 1px solid rgba(255, 255, 255, .14); color: #dff2ef !important; }
.mb-real-lien { display: inline-block; margin-top: .9rem; color: var(--es-accent);
  text-decoration: none; font-weight: 700; font-size: .88rem; }
.mb-real-lien:hover { color: #fff; text-decoration: underline; }

/* La stack en pastilles. ⛔ JAMAIS EN BARRES DE POURCENTAGE : personne n'y croit, et une compétence
   ne se mesure pas en pour cent. Groupées par famille, elles se lisent d'un coup d'œil. */
.mb-stack-wrap { background: var(--es-paper); border-top: 1px solid #e8efee; border-bottom: 1px solid #e8efee; }
.mb-stack { max-width: 1240px; margin: 0 auto; padding: clamp(2.5rem, 5vw, 4rem) clamp(1rem, 5vw, 3rem); }
.mb-familles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.6rem 2.4rem; }
.mb-famille h3 { margin: 0 0 .8rem; font-size: .78rem; font-family: var(--es-mono);
  text-transform: uppercase; letter-spacing: .12em; color: var(--es-brand); }
.mb-famille ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.mb-pastille { background: #fff; border: 1px solid var(--es-line); border-radius: 999px;
  padding: .42rem .95rem; font-size: .87rem; font-weight: 600; color: var(--es-ink); }

.mb-parcours-wrap { background: #fff; }
.mb-parcours { max-width: 1240px; margin: 0 auto; padding: clamp(2.5rem, 5vw, 4rem) clamp(1rem, 5vw, 3rem); }
.mb-periode { margin: 0 0 .3rem !important; font-family: var(--es-mono); font-size: .74rem;
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--es-brand); }

/* La phrase de personnalité : la seule qui donne un timbre de voix. Sans elle la page est un
   document, avec elle c'est quelqu'un. Grande, centrée, seule sur sa ligne. */
.mb-timbre-wrap { background: #fff; padding: 0 clamp(1rem, 5vw, 3rem) clamp(2.5rem, 5vw, 4rem); }
.mb-timbre { max-width: 900px; margin: 0 auto; padding: 2rem 0 0; border-top: 1px solid var(--es-line);
  text-align: center; }
.mb-timbre p { margin: 0 0 .9rem; font-size: clamp(1.15rem, 2.4vw, 1.55rem); line-height: 1.55;
  letter-spacing: -.015em; color: var(--es-ink); font-weight: 600; }
.mb-timbre p::before { content: "« "; color: var(--es-brand); }
.mb-timbre p::after { content: " »"; color: var(--es-brand); }
.mb-timbre footer { font-family: var(--es-mono); font-size: .8rem; color: var(--es-muted); }

.mb-cta-boutons { display: flex; gap: .9rem; flex-wrap: wrap; justify-content: center; }

@media (max-width: 900px) {
  .mb-hero { grid-template-columns: 1fr; }
  /* Le portrait passe AVANT le texte au téléphone : sur une page qui vend une personne, le visage
     est ce qui accroche, et il tient dans le premier écran là où le hero complet ne tient pas. */
  .mb-portrait { order: -1; width: 148px; height: 148px; border-radius: 20px; border-width: 4px; }
  .mb-initiales { font-size: 2.6rem; }
  .mb-chiffres { grid-template-columns: repeat(2, 1fr); }
  .mb-familles { grid-template-columns: 1fr; }
  /* L'accroche du hero est réglée pour une page d'entreprise, où elle fait 3 lignes. Sur une fiche
     elle est plus longue (c'est une phrase, pas un slogan) et passait à 6 lignes au téléphone, ce
     qui repoussait les boutons de contact loin sous la ligne de flottaison. On la resserre ICI
     seulement : la home garde son échelle. */
  .mb-hero h1 { max-width: none; font-size: clamp(1.8rem, 6.6vw, 2.4rem); }
  .es-hero.mb-hero { padding-top: clamp(1.6rem, 5vw, 3rem); }
}
