/* Charte graphique Ediware — feuille partagee par les quatre pages de reference.
   Voir CHARTE.md a la racine du depot, et la note Obsidian systeme-de-design-ediware.
   Les valeurs de cette feuille sont mesurees, pas choisies : chaque seuil porte en
   commentaire la serie qui l'a fixe. */

/* R8 : fontes auto-hebergees, aucune requete tierce. Une page qui
   argumente "hebergement en France" ne va pas chercher sa typographie chez Google. */
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:500;font-display:swap;src:url(fontes/jetbrains-mono-500.woff2) format("woff2")}
/* ⚠️ ONEST REMPLACE RUBIK, ET LE MOTIF N'EST PAS TYPOGRAPHIQUE. Sur le dessin, les
   deux sont indiscernables : le directeur artistique les a notees 13,0 toutes les deux
   a l'aveugle, et ma mesure d'ecart au flou -- 14,6 -- ne mesurait pas la lettre mais
   la derive de chasse, un temoin decale de 3 px rendant 13,68.
   Le motif est une CHASSE plus etroite de 4 %, et son effet est mesure : le H1 de
   l'accueil tient sur TROIS lignes au lieu de quatre a 390, 375, 360 et 320 px, tout
   ce qui suit remonte de 35 px, et l'adresse `203.0.113.42` passe entierement
   au-dessus du pli mobile la ou Rubik la coupait (y 842-860 pour un pli a 844).
   C'est l'objet dont le DA dit qu'il est le seul du site qu'un concurrent ne peut pas
   copier ; il est desormais visible sans defiler.
   ⚠️ CE GAIN EST CONTINGENT AU TEXTE, PAS UNE PROPRIETE DE LA FONTE. La ligne la plus
   longue mesure 349 px dans 350 a 390 px de large. Un mot ajoute au H1 et on repasse a
   quatre lignes. A remesurer si le titre change.
   L'alternative gratuite proposee -- `letter-spacing:-0.01em` sur le H1 mobile -- ne
   reproduit RIEN : Rubik reste a quatre lignes a -0,01 comme a -0,015em, verifie aux
   quatre largeurs.
   UN SEUL FICHIER : Onest est variable, Google sert le meme woff2 pour 600 et 700.
   Deux declarations pointant deux fichiers auraient telecharge deux fois le meme. */
@font-face{font-family:"Onest";font-style:normal;font-weight:600 700;font-display:swap;src:url(fontes/onest.woff2) format("woff2-variations"),url(fontes/onest.woff2) format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;src:url(fontes/inter-400.woff2) format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:500;font-display:swap;src:url(fontes/inter-500.woff2) format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:600;font-display:swap;src:url(fontes/inter-600.woff2) format("woff2")}

:root{
  --bleu:#0072C9; --bleu-encre:#005597; --bleu-profond:#004376; --bleu-clair:#0094FF;
  --bleu-voile:#F3F5FA; --accent:#FF4300;
  /* --- Action : l'orange de marque assombri, libelle BLANC --------------------
     Le libelle reste blanc : le bouton secondaire et le bouton inverse portent
     une encre, un CTA a encre sombre serait le seul a ne ressembler a rien
     d'autre sur la page. Decision du commanditaire.
     Du blanc impose donc un orange plus foncé, et #D43600 est LE PLUS CLAIR qui
     tienne la reserve de 4,8:1. Il est a L* 47,8, soit PLUS CLAIR que --bleu
     (47,3) : l'action redevient plus lumineuse que la marque.
     Ce n'est pas une invention : c'est #FF4300 assombri d'un facteur 0,66 en
     lumiere lineaire, comme le survol en est l'assombrissement suivant. */
  --action:#D43600;          /* fond de CTA, libelle blanc. 4,853:1, reserve +0,353 */
  --action-survol:#CA3300;   /* le survol ASSOMBRIT : l'encre est claire. 5,270:1 */
  --action-actif:#B73000;    /* palette, 1,9 %. 6,111:1 */
  --ambre:#FFBF00; --encre-titre:#1A1A2E; --encre:#242525; --encre-douce:#5A6472;
  --fond:#FFFFFF; --fond-alt:#F4F6F8; --filet:#DDE3EA; --bordure-composant:#858FA0;
  --neutre-1:#B8C4D4; --neutre-2:#8A9CB1; --gris-logo:#505050;
  --focus:#0072C9; --focus-inverse:#FFFFFF;
  --succes:#0B6B43;         /* 6,57:1 sur blanc, 6,06:1 sur --fond-alt */
  --erreur:#B3261E;         /* 6,54:1 sur blanc */
  --alerte:#7A5200;         /* 6,92:1 sur blanc */
  /* 58ch, et le commentaire est de nouveau vrai. A 68ch la mesure rendait une
     mediane de 86 signes, un maximum de 98, et 41 lignes sur 51 au-dessus de 75 --
     que la charte interdit nommement. La cause etait une confusion d'unite : le ch
     est la largeur du zero, et il vaut 1,388 fois le signe moyen d'une phrase
     francaise en Inter. 68ch offraient donc une capacite de ~94 signes.
     Mesure a 58ch : mediane 73, p90 78. */
  --mesure:58ch;            /* longueur de ligne, 65 a 75 signes */
  --succes-clair:#86E8B6;   /* indicateur d'etat sur aplat bleu. 3,35:1 sur --bleu */
  --rayon-s:4px; --rayon-m:8px;
  --ombre-s:0 1px 2px rgba(16,24,40,.06);
  --ombre-m:0 4px 12px rgba(16,24,40,.10);
  --police-titre:Onest,Arial,sans-serif; --police-corps:Inter,Arial,sans-serif;
  --police-donnee:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --conteneur:1200px; --h1:64px; --visuel:400px;
}
*{box-sizing:border-box;margin:0}
body{font-family:var(--police-corps);color:var(--encre);background:var(--fond);font-size:16px;line-height:1.6}
.conteneur{max-width:var(--conteneur);margin:0 auto;padding:0 20px}
a{color:var(--bleu-encre);text-underline-offset:2px}
a:focus-visible,button:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* --focus rend 1,00:1 sur --bleu : le meme bleu de part et d'autre. --focus-inverse
   etait declare et employe zero fois. Il sert sur les deux aplats de marque et sur
   le bouton inverse, qui y vit. */
.chiffres a:focus-visible,.cloture a:focus-visible,.btn-inv:focus-visible{
  outline-color:var(--focus-inverse)}
/* ⚠️ h4 EST DANS CETTE LISTE, ET SON ABSENCE A COUTE. La feuille ne declarait aucune
   regle h4 : le corpus en emploie pourtant 106 dans 21 fichiers. Ils rendaient donc en
   Inter 18/700 sur --encre, c'est-a-dire EXACTEMENT le paragraphe en gras -- meme fonte,
   meme corps, meme encre, marges nulles. Une page annoncant quatre niveaux en rendait
   trois, et rien ne le signalait.
   Le defaut etait ancien ; je l'ai aggrave en descendant deux titres en h4 pour corriger
   une capitale qui tenait lieu de niveau. Deplacer une faute n'est pas la reparer. */
h1,h2,h3,h4{font-family:var(--police-titre);color:var(--encre-titre);letter-spacing:-.014em}
h2{font-size:28px;font-weight:700;line-height:1.3;color:var(--bleu-encre);margin-bottom:12px}
h3{font-size:22px;font-weight:600;line-height:1.35;margin-bottom:8px}
h4{font-size:18px;font-weight:600;line-height:1.4;margin-bottom:8px}
section{padding:96px 0}
/* var(--mesure) et non un litteral : .intro et .chapo figeaient 68ch et ont donc
   echappe au passage a 58ch. Les deux paragraphes les plus lus du site gardaient
   l'ancienne mesure -- 772 px et 81 signes sur .chapo -- pendant que le reste
   descendait a 659. La garde des jetons ne voit pas un litteral. */
.intro{max-width:var(--mesure);color:var(--encre-douce);margin-bottom:48px}

.bandeau{background:var(--bleu-voile);color:var(--encre);font-size:14px;padding:10px 0;
  border-bottom:1px solid var(--filet)}
.bandeau .conteneur{display:flex;gap:32px;align-items:center}
/* SELECTEUR DE LANGUE. Quatrieme item du bandeau, pousse au fil droit.
   ⚠️ AUCUNE ENCRE, AUCUN CORPS, AUCUNE GRAISSE NEUVE : `a{}` donne deja
   `--bleu-encre`, `.bandeau a` donne Inter 500 sans soulignement, `.bandeau a:hover`
   donne le soulignement au survol. La seule declaration neuve est la position.
   Le bleu plutot que `--encre-douce` : au flou de 3,2 px le gris s'evanouit -- 112,73
   de distance au fond contre 134,11 pour le bleu, soit 19 % de moins. La feuille a
   deja ecrit l'argument : la teinte est le seul signal qui survive au flou. */
.bandeau-langue{margin-left:auto;flex:0 0 auto;white-space:nowrap}
.bandeau-langue .lg-court{display:none}
/* 340 et non 480, c'est une mesure : « English » fait 48,6 px et tient des 340,
   « Français » 56,9 px et tient des 336. Sous ce seuil le bandeau passe a deux lignes
   (37,4 -> 59,8) ET le numero de telephone se coupe en deux -- un defaut plus grave
   que l'abreviation. Un seul seuil couvre les deux sens. */
@media(max-width:339px){
  .bandeau-langue .lg-long{display:none}
  .bandeau-langue .lg-court{display:inline}
}
/* ⚠️ LE BANDEAU ETAIT LE SEUL CHROME DU SITE A NE PAS ANNULER LE SOULIGNEMENT.
   Neuf composants de chrome -- `nav a`, `.sous-menu a`, `footer a`, `.fil a`,
   `.sommaire a`, `.som-aside a`, `.cocon-aside a`, `.module a`, `.btn` -- posent tous
   `text-decoration:none` au repos, et CINQ ajoutent le soulignement AU SURVOL. Le
   bandeau affichait donc en permanence l'etat que la maison reserve au survol, et
   n'avait plus rien a donner au survol : 0 pixel modifie, mesure sur quatre pages.
   Ce n'est pas un ecart de gout, c'est une inversion de systeme, en tete de 17 pages.

   ⚠️ ET LE BLEU RESTE, PARCE QUE LA MESURE DIT DE LE GARDER. Au flou de 3,2 px,
   l'encre neutre est PLUS saillante que le bleu -- 66,77 de distance au fond contre
   56,55. Retirer la couleur alourdirait le bandeau au lieu de l'alleger, et priverait
   le lien du seul signal qui lui survive au flou : la teinte, +28,92 de B-R sans le
   soulignement. Un chemin d'acces qui ne se signale plus n'en est pas un.

   ⚠️ LA DECLARATION DE COULEUR QUI VIVAIT ICI ETAIT MORTE. `.bandeau a{color:
   var(--bleu-encre)}` recalculait exactement ce que `a{}` ligne 55 donne deja : zero
   pixel produit. Le bleu de ce lien n'a jamais ete une decision, et son soulignement
   venait de la feuille du navigateur, pas d'une regle du projet.

   Le regime pose ici est celui de `.module a` (lignes 2308-2309), au mot pres. */
/* ⚠️ 500, ET C'EST LA DECLARATION QUE J'AVAIS OUBLIEE. En reprenant le regime de
   `.module a` j'en ai pris UNE SUR QUATRE : la source s'ecrit `font-size:16px;
   font-weight:500;color:var(--bleu-encre);text-decoration:none`, et ce sont les trois
   autres qui font qu'un bleu sans trait tient debout. Mesure sur l'accueil : 13 liens
   bleus au repos, DOUZE portent un renfort -- graisse 500 pour neuf, soulignement pour
   trois, filet pour deux -- et UN SEUL n'en portait aucun, celui-ci, en 400.
   Consequence : dans sa propre barre, ce qui est cliquable rendait 55,88 de densite
   d'encre contre 67,05 pour les mentions passives voisines, SOIT 16,7 % DE MOINS. Le
   soulignement permanent compensait ; il est parti, la compensation n'avait pas suivi.
   500 est aussi la graisse des deux autres mentions du bandeau : le lien rejoint le
   registre de sa barre au lieu d'y etre le seul objet leger. */
.bandeau a{text-decoration:none;font-weight:500}
/* Le telephone et l'email deviennent cliquables SANS devenir bleus : `color:inherit`
   annule la regle globale `a{}` de la ligne 55. Ils gardent leur chasse fixe et leur
   encre de mention ; seul le curseur et le survol les signalent. C'est ce qui permet de
   poser `format-detection:telephone=no` sans perdre l'appel au doigt. */
.bandeau .conteneur>span:nth-child(-n+2) a{color:inherit;font-weight:inherit}
.bandeau a:hover{text-decoration:underline}
header{border-bottom:1px solid var(--filet);padding:18px 0;position:sticky;top:0;background:#fff;z-index:10}
@media(max-width:1023px){
  /* S4 : en-tete collant de 160 px a 480-1023 px et 218 px a 320 px, soit
     24,1 % puis 30,9 % du premier ecran consommes en permanence.
     Sous 1024 px l'en-tete defile avec la page. */
  header{position:static}
}
header .conteneur{display:flex;align-items:center;justify-content:space-between;gap:24px}
.logo{flex:none}
.logo{display:block;height:34px;width:auto}
footer .logo{height:30px;margin-bottom:14px}
nav{display:flex;gap:26px;font-size:16px;font-weight:500}
nav a{color:var(--encre);text-decoration:none}
/* Les cinq liens de la navigation principale n'avaient AUCUNE regle de survol :
   0 pixel modifie sur 7 488 au passage de la souris. La charte l'interdit
   nommement. */
nav a:hover{color:var(--bleu-encre)}

/* LE MENU DEROULANT, ET POURQUOI IL ARRIVE SI TARD.
   Les quatre maquettes portaient `<nav><a href="#">Solutions</a>...` : cinq entrees
   MORTES des l'origine. Le portage sous Hugo en a cable deux. Resultat mesure le
   28 aout : l'en-tete et le pied ne contenaient que TROIS cibles internes, et 17 des
   20 pages portees n'etaient atteignables par aucun clic. Le menu n'avait jamais ete
   dessine, il avait ete dessine comme un placeholder et laisse tel quel.
   Le vrai menu, sorti du dump WordPress puis confronte au site en ligne, a trois
   entrees a sous-menu -- Solutions 3, Plateforme 10, Services 4 -- et deux entrees
   simples. Les 17 destinations existent toutes en local.

   ⚠️ LES TROIS TETES SONT DES `<button>`, PAS DES LIENS. Sur le site d'origine elles
   portent `href="#"` : un lien qui ne mene nulle part, focalisable, annonce comme
   lien par un lecteur d'ecran. C'est la meme fausse affordance que les neuf `<a
   tabindex="0">` de la FAQ, corrigee le 28 aout a la source. On ne la reintroduit pas
   dans le menu. Un bouton qui ouvre un panneau est un bouton. */
.nav-groupe{position:relative;display:flex}
/* La tete doit etre INDISCERNABLE des deux liens voisins : meme fonte, meme corps,
   meme graisse, meme encre. Un bouton natif apporte sa fonte systeme et son fond. */
.nav-tete{appearance:none;-webkit-appearance:none;background:none;border:0;padding:0;
  margin:0;font:inherit;color:var(--encre);cursor:pointer;
  display:inline-flex;align-items:center;gap:6px}
.nav-tete:hover,.nav-tete[aria-expanded="true"]{color:var(--bleu-encre)}
/* Le chevron est en CSS et non en glyphe : un caractere aurait sa propre chasse et
   sa propre ligne de base, et il aurait fallu le recaler a chaque corps. */
.nav-tete::after{content:"";width:7px;height:7px;border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;transform:rotate(45deg) translate(-2px,-2px);
  transition:transform 150ms}
.nav-tete[aria-expanded="true"]::after{transform:rotate(-135deg) translate(-2px,-2px)}

/* L'OUVERTURE ET LA FERMETURE SONT ASYMETRIQUES, ET C'EST LE SITE D'ORIGINE QUI LE
   DIT. Elementor pilote son menu avec SmartMenus, dont les reglages ont ete lus dans
   la bibliotheque servie en production :
       showTimeout 250   hideTimeout 500
       showFunction null, showDuration 0        -> l'ouverture est INSTANTANEE
       hideFunction   $ul.fadeOut(200)          -> la fermeture est un fondu
       collapsibleShowFunction $ul.slideDown(200)
       collapsibleHideFunction $ul.slideUp(200) -> le mobile glisse DANS LES DEUX SENS
   Les 200 ms tombent sur l'echelle de la charte, section 7 : « 150 ms sur les
   couleurs, 200 ms sur les transformations ».

   ⚠️ `display:none` NE S'ANIME PAS, et c'est ce qui commande toute la construction.
   L'etat ferme se dit donc autrement : `visibility` au bureau, ou une grille a une
   rangee de 0fr au mobile. `visibility:hidden` retire correctement le panneau de
   l'arbre d'accessibilite, ce qu'`opacity:0` seul ne ferait pas. */
.sous-menu{list-style:none;margin:0;padding:0;min-height:0}
.sous-panneau{display:none;grid-template-rows:0fr;overflow:hidden;
  transition:grid-template-rows 200ms,display 200ms allow-discrete}
.nav-tete[aria-expanded="true"]+.sous-panneau{display:grid;grid-template-rows:1fr}
/* ⚠️ `display:none` ET NON `visibility:hidden`, ET C'EST UNE REGRESSION MESUREE QUI
   L'IMPOSE. Avec `visibility`, le panneau ferme reste un element de la grille flex de
   son groupe : il y prend une largeur, force le groupe sur toute la ligne, et
   l'en-tete mobile passe de 157 a 262 px avec une nav a quatre rangs au lieu de deux.
   Les 157 px sont un acquis paye de la charte, on ne les rend pas pour une animation.
   `display` ne s'anime qu'en discret, d'ou `allow-discrete` et le `@starting-style`
   ci-dessous, qui donne au panneau une hauteur de depart a animer. Sur un navigateur
   qui ne les connait pas, l'ouverture est instantanee : c'est exactement le
   comportement d'avant cette passe, donc une degradation sans perte. */
@starting-style{
  .nav-tete[aria-expanded="true"]+.sous-panneau{grid-template-rows:0fr}
}
.sous-menu a{display:block;color:var(--encre);text-decoration:none;font-size:15px;
  font-weight:400;line-height:1.4}
.sous-menu a:hover{color:var(--bleu-encre)}

@media(min-width:1024px){
  /* Au-dessus de 1024 l'en-tete est collant : le panneau se pose sous lui, en
     absolu, et ne pousse rien. `z-index` superieur a l'en-tete lui-meme, sinon la
     bordure basse de l'en-tete passe devant le panneau. */
  /* 314 ET NON 264, ET C'EST LA LARGEUR QUI SUPPRIME LES CESURES. A 264, trois
     libelles sur dix-sept se repliaient sur deux lignes, dont « Gestion de campagnes
     « Full-Service » » qui coupait le mot compose sur son propre trait d'union --
     avec des insecables poses autour des guillemets et le trait laisse secable.
     ⚠️ `max-width` NE S'APPLIQUE PAS AUJOURD'HUI, et il faut le savoir plutot que
     de croire qu'il borne quelque chose : la largeur naturelle du panneau est de
     119,5 px, donc `min-width` decide seul. Il reste comme garde du jour ou un
     libelle depasserait 380 px, pas comme contrainte courante.
     ⚠️ L'OMBRE ET L'EMPILEMENT VIENNENT DE LA CHARTE, QUI LES AVAIT DEJA TRANCHES.
     J'avais ecrit `0 12px 28px rgba(16,24,40,.10)`, une troisieme valeur a 2,3 fois
     le flou du plus grand jeton autorise, et `z-index:11`. La charte nomme
     `--ombre-s` pour « menu deroulant, element flottant » (tableau des ombres) et
     fixe `100` pour le menu deroulant dans son ordre d'empilement. Je ne l'avais pas
     lue. */
  /* `overflow:visible` : la hauteur ne s'anime pas au bureau, donc le masquage ne
     sert plus a rien -- et il CLIPPAIT le tampon de survol, qui deborde le panneau
     par le haut pour couvrir les 18 px de vide sous la tete. */
  /* ⚠️ `display:none` AU REPOS, ET PAS `opacity:0` + `visibility:hidden`.
     C'est la version que j'avais ecrite d'abord, et elle a rendu LA RECETTE AU PIXEL
     NON DETERMINISTE : les quatre empreintes du bureau changeaient a chaque
     execution. Mesure du desaccord : 9,77 % des pixels d'une zone de 550x413,
     ECART MAXIMAL 2 SUR 255, et sur `.entete-page` -- pas sur les panneaux, qui
     etaient bien invisibles. Un `opacity:0` permanent sur un element absolu promeut
     une couche de composition, et la rasterisation du texte voisin bascule d'une
     execution a l'autre. Invisible a l'oeil, fatal pour une empreinte SHA-256.
     Il ne fallait PAS assouplir la recette avec un seuil de tolerance : un test qui
     accepte du bruit accepte aussi le debut d'une derive. On retire la couche.
     Au repos le panneau n'existe donc plus du tout, et le fondu tient quand meme :
     `allow-discrete` garde `display:grid` pendant les 200 ms de la fermeture. */
  .sous-panneau{display:none;overflow:visible;
    position:absolute;top:calc(100% + 18px);left:-16px;z-index:100;
    min-width:314px;max-width:380px;background:#fff;
    border:1px solid var(--filet);border-radius:var(--rayon-s);
    box-shadow:var(--ombre-s);
    grid-template-rows:1fr;opacity:0;
    transition:opacity 200ms,display 200ms allow-discrete}
  .sous-menu{padding:10px 0}
  /* L'ouverture ne transitionne PAS : `transition:none` sur l'etat ouvert rend le
     panneau instantane a l'aller et laisse la regle du dessus jouer au retour.
     C'est exactement showDuration:0 / hideFunction:fadeOut(200). */
  /* `transition:none` sur l'etat ouvert : l'aller est instantane, et c'est la regle
     du dessus qui joue au retour. Exactement showDuration:0 / hideFunction:fadeOut(200). */
  .nav-tete[aria-expanded="true"]+.sous-panneau{display:grid;opacity:1;transition:none}
  .sous-menu a{padding:9px 16px}
  .sous-menu a:hover{background:var(--fond-alt)}
  /* Le survol ouvre aussi, mais SEULEMENT la ou un survol existe. `@media(hover)`
     ecarte les appareils tactiles, ou `:hover` reste colle apres un appui et
     laisserait le panneau ouvert sans qu'on sache le fermer.
     La zone tampon de 18 px entre la tete et le panneau serait un trou ou le
     survol se perd : `::before` la couvre. */
  @media(hover:hover){
    /* ⚠️ LE SURVOL N'OUVRE PLUS PAR LE CSS, ET IL LE FAISAIT ENCORE HIER.
       Une regle `:hover` ferme des que le pointeur sort : elle ne sait pas attendre.
       Le delai de grace de 500 ms de l'original ne s'exprime dans aucune feuille, il
       demande un minuteur. Le script tient donc l'ouverture ET la fermeture, et le
       CSS ne reagit plus qu'a `aria-expanded`.
       Ce qui reste ici de l'ancienne regle : rien. `:focus-within` avait deja ete
       retire parce qu'il rouvrait ce qu'Echap venait de fermer. */
    /* LE TAMPON EST SUR LE PANNEAU, PAS SUR LE GROUPE, ET C'EST UNE REPARATION.
       Il etait pose sur `.nav-groupe` en `left:0;right:0` : 98,4 px de large, quand
       le panneau en fait 314 et deborde de plus de 160 px a droite de sa tete. Deux
       tiers de la bande de raccord n'etaient pas couverts, et approcher le panneau
       PAR LA DROITE -- le geste que la geometrie appelle -- le fermait sans retour
       possible, un `display:none` ne se survolant pas.
       Sur le panneau, le tampon epouse sa largeur par construction. Il n'existe que
       panneau ouvert, ce qui suffit : il ne sert qu'a la traversee. */
    .sous-panneau::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:20px}
  }
}

@media(max-width:1023px){
  /* LE DEPLIANT. Sous 1024 le panneau ne flotte pas : il pousse, comme sur le site
     d'origine. Il reste en flux, pleine largeur du rang de nav.
     ⚠️ « ON NE POSE PAS DE BURGER » A ETE LA REGLE JUSQU'AU 2 SEPTEMBRE 2026, au nom
     de la parite des destinations desktop/mobile. Le commanditaire a tranche l'inverse
     sur mesure : la nav depliee coutait 66 px sur deux rangs de 360 a 599 px et 98 px
     sur trois rangs a 320, le quart du premier ecran. SOUS 600 PX le menu se replie
     dans un <details> (bloc « LE MENU SE REPLIE » plus bas) ; de 600 a 1023 les trois
     parents se deplient toujours SUR PLACE, comme ici. */
  .nav-groupe{flex-wrap:wrap}
  /* ⚠️ LE VOISIN DE LA TETE N'EST PLUS LA `<ul>` MAIS L'ENVELOPPE. Ces trois regles
     visaient encore `.sous-menu` apres l'introduction de `.sous-panneau` : elles ne
     s'appliquaient plus du tout, et les quatre empreintes MOBILES de la recette ont
     bouge alors que les quatre desktop n'avaient pas bronche. C'est cet ecart qui a
     mis le defaut au jour -- une recette qui rend « 8/8 identiques » compare deux
     cotes entre eux, elle ne dit pas qu'ils sont justes.
     `flex-basis:100%` est pose sur l'enveloppe OUVERTE OU FERMEE : sinon le panneau
     ferme reste un element de la grille flex du groupe, y prend une largeur et
     deplace le repli de la barre. */
  .nav-tete[aria-expanded="true"]+.sous-panneau{flex-basis:100%;width:100%;margin-top:8px}
  .sous-menu{padding:10px 0 4px 14px;border-left:2px solid var(--filet)}
  .sous-menu a{padding:7px 0}
}

.btn{display:inline-flex;align-items:center;height:44px;padding:0 28px;background:var(--action);
  color:#fff;border-radius:var(--rayon-s);font-weight:500;font-size:16px;
  text-decoration:none;border:0;transition:background-color 150ms;font-family:var(--police-corps)}
/* La regle est le SENS de derive, pas le sens absolu : un etat ELOIGNE le fond
   de son encre en clarte. L'encre etant ici blanche, l'etat assombrit. Elle
   eclaircirait si l'encre etait sombre. */
.btn:hover{background:var(--action-survol)}
.btn:active{background:var(--action-actif)}
.btn-2{background:transparent;color:var(--bleu-encre);border:1px solid var(--bleu-encre)}
.btn-2:hover{background:var(--bleu-voile)}
/* Un aplat d'action pose sur un aplat de marque rend 1,018:1 : la luminance
   ne le delimite pas, il n'y survit que par sa teinte. Lisere blanc obligatoire.
   #FF4300 ne reglait pas ce cas non plus, a 1,425:1. */
/* .fiche et .delivrabilite n'existent plus sur aucune page : la regle ne
   nommait plus que des contextes morts. */
.chiffres .btn{box-shadow:0 0 0 2px #fff}
/* LE BOUTON DU PREMIER ECRAN EST LE PLUS PETIT DU MARCHE, ET DE LOIN. Mesure sur les
   six accueils du panel, bandeaux de consentement neutralises, 1440x1000 :
   Ediware 200x44 = 8 786 px², Mailchimp 16 464, Brevo 18 564, Mailjet 24 576,
   HubSpot 37 604. Moitie a quart du plus petit des autres, et seul -- les quatre
   concurrents en posent deux ou l'accompagnent d'une preuve.
   A 64 x 18 x 48 il rend 258x64 = 16 490 px², soit la surface de Mailchimp a 26 px
   pres. Les trois valeurs sont sur les echelles de CHARTE.md : 64 et 48 sur celle
   des espacements, 18 sur celle des corps.
   ⚠️ CE GESTE COUTE 20 PX A LA BANDE DE CHIFFRES, et c'est un echange assume. Elle
   passe de 72 a 52 px visibles sur 254 au pli de 1000. La bande etait deja cachee a
   72 % ; le bouton, lui, etait le seul poste ou l'ecart au marche se mesurait en
   facteurs. Et 7 700 px² d'orange de plus entrent dans un premier ecran dont 84,3 %
   des pixels sont quasi blancs, ce qui sert le plafond n°1 au lieu de le creuser.
   ⚠️ NE VAUT QUE POUR LE HERO. Le `.btn` de 44 px est un standard de cible tactile
   employe 75 fois ailleurs : l'agrandir partout ferait un site de gros boutons, pas
   un premier ecran qui porte. */
.hero .btn{height:64px;font-size:18px;padding:0 48px}
/* ⚠️ .btn-inv N'AVAIT PAS D'ETAT PROPRE et heritait de .btn:hover, qui pose le
   fond d'action : #CA3300 sous une encre #005597, soit 1,451:1. Le libelle
   disparaissait au survol, sur 4 occurrences et 3 pages -- dont le dernier appel a
   l'action de chaque page. Une regle attribuee par classe de base plutot que par
   ce qu'elle habille, exactement la faute retiree du masque du comparatif.
   L'etat ELOIGNE le fond de son encre en clarte : l'encre etant sombre ici, le
   fond ne peut pas s'eclaircir au-dela du blanc, c'est donc l'encre qui
   s'assombrit, sur un voile qui rend le survol perceptible. */
.btn-inv{background:#fff;color:var(--bleu-encre)}
.btn-inv:hover{background:var(--bleu-voile);color:var(--bleu-profond)}

/* RESPIRATION CONTINUE, ET NON PAR MARCHES. Deux paliers de hauteur creaient
   une falaise : 135 px de compaction d'un coup quand le pli ne gagnait que 20,
   d'ou une bande morte ou la signature retombait sous le pli. clamp() fait
   varier la respiration avec la fenetre sans aucun seuil a franchir. */
.hero{padding:clamp(8px, calc(24vh - 144px), 96px) 0 clamp(28px, calc(16vh - 80px), 80px)}
.hero .conteneur{display:grid;grid-template-columns:1fr var(--visuel);gap:64px;align-items:center;overflow:visible}
.hero .conteneur>*{container-type:inline-size}
.hero{overflow:hidden}
.surtitre{color:var(--bleu-encre);font-weight:600;font-size:16px;margin-bottom:12px}
/* LE CORPS DU H1 EST CONTINU, PAS PAR PALIERS. Sa contrainte l'est : mesure sur
   treize largeurs de colonne, le corps maximal tenant sans deborder vaut 9,3 a
   9,5 % de la colonne, sans une exception. Trois paliers n'etaient que trois
   echantillons d'une droite -- et entre les echantillons, deux bandes entieres
   sortaient de la regle des 25 % du premier ecran : 480-624 px jusqu'a 31,5 %,
   et 1120-1184 px a 27,6 % des que la fenetre depasse 827 px de haut.
   TROIS PLAFONDS, UN PAR CONTRAINTE, ET AUCUN N'EST DE TROP.
     --h1     le haut de l'echelle. Au-dela de 1280 px la colonne vaut 696 px
              fixes, donc 9,2 cqi rend 64 px : le palier de reference ne bouge pas.
     9,2cqi   la largeur. A 9,2 % de la colonne le titre se brise TOUJOURS au meme
              nombre de lignes : c'est ce qui rend la loi utilisable.
     7,7vh    la hauteur, et elle manquait. Les 25 % du premier ecran sont une
              contrainte de hauteur : un corps proportionnel a la largeur n'en
              sait rien, et rendait encore 31,9 % a 656x568. Trois lignes a 1,08
              d'interligne tiennent sous 25 % tant que le corps reste sous
              0,25 / 3,24 = 7,7 % de la hauteur de fenetre. */
h1{font-size:min(var(--h1), 9.2cqi, 7.7vh);font-weight:700;line-height:1.08;letter-spacing:-.02em;margin-bottom:24px}
/* ⚠️ LA FORMULE CI-DESSUS EST DERIVEE POUR TROIS LIGNES : « trois lignes a 1,08
   d'interligne tiennent sous 25 % tant que le corps reste sous 0,25/3,24 = 7,7 % ».
   Un titre plus long en rend quatre, et la derivation ne tient plus : mesure a
   1280, 1440 et 1920, l'accueil rendait 4 lignes et 28 % du pli, contre deux
   interdits nommes -- « plus de 3 lignes au-dela de 1024 px » et le plafond de 25 %.

   Ce n'est pas la PAGE qui demande un corps plus bas, c'est la LONGUEUR du titre :
   la regle se scope donc sur ce qu'elle habille, pas sur ou elle se trouve. Baisser
   --h1 aurait fait tomber a 52 px le titre de la page plateforme, qui tient en
   trois lignes a 64 et qui est le plus grand du panel concurrent.

   52 px et non 56 : la bascule est binaire, comme pour le titre precedent. Mesure
   aux trois largeurs -- 64, 60 et 56 px rendent quatre lignes, 52 en rend trois et
   17 % du pli. */
/* UN TITRE DE HERO SE COMPOSE SUR SES PROPOSITIONS, UNE PAR LIGNE. Le titre porte
   trois exclusions qu'aucun des quatre concurrents mesures ne peut revendiquer. En
   flux libre elles se dispersent : un « sans » orphelin en fin de premiere ligne a
   1920, 1440, 1280, 1100 et 768. Une clause par ligne les aligne en marge gauche, et
   au flou de 3,2 px la FORME se lit encore, ce que le meme texte en flux libre ne
   produit pas.
   58 px et non 52 : le titre a perdu « L'emailing B2B », que le surtitre dit 12 px
   plus haut et qui redisait 54 % de la premiere ligne. Le corps remonte sans qu'un
   mot ne se casse. */
h1.h1--clauses{font-size:min(58px, 9.2cqi, 7.7vh)}
/* Une clause par ligne seulement la ou la colonne les porte entieres. Sous 1080 px
   le titre revient au flux : forcer trois blocs qui se replient chacun rendrait six
   lignes la ou trois suffisent. */
@media(min-width:1080px){
  h1.h1--clauses span{display:block}
}
/* Ecran court. Le plafond des 25 % du premier ecran est une regle de HAUTEUR :
   le corps du H1 doit donc suivre la hauteur de la fenetre, pas sa largeur.
   Seuil : 207 px (3 lignes a 64 px) depassent 25 % des qu'on est sous 828 px.
   Corps : 58 px est la plus grande valeur conforme. La serie 62/60/58/56 montre
   que le retour a la ligne bascule de 3 a 2 lignes entre 60 et 58, et qu'aucune
   taille a 3 lignes ne passe (60 px -> 25,3 %). Le choix est donc binaire. */
.chapo{font-size:18px;max-width:var(--mesure);margin-bottom:16px}
.appui{color:var(--encre-douce);margin-bottom:32px}
/* ⚠️ CETTE REGLE VIVAIT DANS LE BLOC max-width:1023px, ou je l'avais ancree par
   erreur sur le mauvais .preuve. Consequence mesuree : en bureau la meilleure
   phrase du site n'avait AUCUNE composition -- 16 px d'heritage, marge nulle, et
   696 px de large, soit plus que le chapo a 659 ; en mobile elle en avait une, mais
   celle de la LEGENDE posee juste dessous, meme fonte, meme corps, meme encre.
   La phrase avait change de position, pas de rang.

   Elle porte la promesse du seul geste de la page. Elle prend donc l'encre du corps
   et non celle des legendes, une mesure plus etroite que le chapo pour se lire comme
   attachee au bouton, et une marge qui la detache de lui. */
.sous-bouton{margin:14px 0 0;font-size:16px;line-height:1.5;color:var(--encre);
  max-width:46ch}
.preuve{margin-top:28px;display:flex;gap:10px;align-items:center;font-size:14px;color:var(--encre-douce)}
/* Signale sans etre cliquable, et ne porte aucun mot : l'orange de marque
   exact, ou le seuil de 4,5:1 ne s'applique pas. */
.puce{width:8px;height:8px;border-radius:50%;background:var(--accent);flex:none}
svg{width:100%;height:auto;display:block}
/* --- Le hero montre le PRODUIT -----------------------------------------------
   Capture reelle de l'interface, recadree sur le bord du conteneur et affichee
   a taille lisible en debordant du bord droit. Un ecran entier retreci a 320 px
   serait illisible ; un fragment de 1794 px affiche a 760 px reste net.
   La colonne de droite est plus etroite que l'image : c'est le debordement qui
   donne l'echelle, pas la grille.                                              */
.produit{position:relative}
/* LA FENETRE DE CADRAGE VAUT A TOUTES LES LARGEURS. Elle n'etait appliquee que
   sous 1120 px, c'est-a-dire au cas minoritaire : au-dessus, le cadre laissait
   voir « Detail de la campagne » -- le titre de page de l'application -- et le
   titre de l'email, rendu a un corps equivalent de 24 px, donc plus gros que
   tous les h3 de la page, en gras noir isole sur blanc et tronque en milieu de
   mot. Le premier ecran portait trois masses de titrage au lieu d'une.

   C'EST LE CADRE QUI PORTE LA LARGEUR, ET NON L'IMAGE. Il le faut : le debord
   horizontal demande un depassement, la fenetre verticale demande un rognage, et
   `overflow` ne peut pas etre visible sur un axe et cache sur l'autre. Le cadre
   deborde donc sa colonne et rogne en hauteur ; c'est .hero{overflow:hidden} qui
   coupe au bord de la fenetre.

   Le debord doit EXISTER a toutes les largeurs. A 760 px fixes il disparaissait
   sur les moniteurs courants : la colonne droite commence a 50vw+180, donc
   l'image s'arretait 20 px avant le bord a 1920 -- ce qui se lit comme une
   erreur -- et flottait a 340 px du bord a 2560, en exposant son cote droit
   volontairement laisse sans bordure. La formule garantit 80 px de debord
   au-dela de 1720 px de large.

   Fenetre source y 70 -> 480 : sous-titre, bandeau d'etapes, barre d'outils.
   Le decalage vaut 70/1120 = 6,25 % de la hauteur de l'image, en pourcentage
   parce qu'une translation en % se resout sur la taille propre de l'element et
   suit donc l'echelle sans qu'aucune valeur en pixels soit a recalculer.
   Ne pas descendre la fenetre pour conserver de la masse : au-dela de y 480 on
   reintroduit le second logotype Ediware de l'apercu d'email. */
.produit-cadre{display:block;overflow:hidden;
  width:max(760px, calc(50vw - 100px));aspect-ratio:1794/410;
  /* ⚠️ `--bordure-composant` ET NON `--filet`, ET LA CHARTE AVAIT DEJA TRANCHE.
     A 1 px de `--filet` #DDE3EA, ce cadre rendait 1,29:1 sur le fond blanc, sous le
     seuil de 3:1 d'un element d'interface : la finition EXISTAIT et ne se voyait pas.
     Le rayon, le filet et l'ombre etaient tous les trois en place, et un observateur
     concluait « image collee, pas element de design » -- il avait raison sur ce qu'il
     voyait et tort sur la cause.
     A 40 px de la, dans la meme colonne, `.produit-encart` employait deja
     `--bordure-composant` #858FA0, soit 3,26:1 : LA PETITE CARTE ETAIT MIEUX CADREE QUE
     LA GRANDE CAPTURE. `CHARTE.md:1472` a rendu cet arbitrage pour la boite des
     certifications -- « le jeton existe pour les bords qui doivent se voir » -- et la
     capture y etait simplement restee en arriere. Un jeton echange, aucune valeur
     inventee.
     ⚠️ LE BORD DROIT RESTE ABSENT, et ce n'est pas un oubli : la capture deborde, et
     c'est le debordement qui donne l'echelle. Elle restera cadree a gauche et coupee a
     droite. */
  border:1px solid var(--bordure-composant);border-right:0;
  border-radius:var(--rayon-m) 0 0 var(--rayon-m);box-shadow:var(--ombre-m)}
.produit-vue{display:block;width:100%;height:auto;transform:translateY(-6.25%)}
/* ⚠️ L'IMAGE DE L'ACCUEIL EST DEJA AU RAPPORT DE LA FENETRE, DONC ELLE NE SE RECADRE PAS.
   `translateY(-6.25%)` existe pour faire glisser une capture de 1794x1120 sous une
   fenetre de 1794x410 : il faut une image plus haute que la fenetre pour avoir de quoi
   glisser. `produit-statistiques.png` fait 1286x294, soit 4,374 contre 4,376 -- elle
   remplit la fenetre exactement. La decaler la ferait remonter de 18 px et laisserait
   autant de vide en bas. */
.produit-vue--pleine{transform:none}
/* Encart de donnee reelle, detache sur le coin bas gauche. */
/* L'encart etait une capture de la capture : la donnee possedee y etait un
   raster, composee dans la typographie de l'application. Elle est donc restee
   muette la ou la page est la plus forte. En HTML, elle porte la chasse fixe et
   redevient le second objet de signature que la charte exige. Echelon « donnee
   majeure, 26 px » : la charte le definit comme l'objet de signature du premier
   ecran, et il n'etait employe nulle part depuis que la fiche a quitte le hero. */
/* L'encart PEND SOUS LE CADRE, il ne s'y pose plus. Il etait un accent de coin
   sur une image haute de 476 px ; la fenetre de cadrage l'ayant ramenee a 174,
   il recouvrait jusqu'a 47,8 % du cadre a 320 px et masquait le libelle
   « Message : » a 1440. `top:calc(100% - 18px)` le fait chevaucher de 18 px
   exactement, quelle que soit sa propre hauteur : un `bottom` negatif, lui,
   aurait demande une valeur par palier. */
.produit-encart{position:absolute;left:-40px;top:calc(100% - 18px);background:var(--fond);
  border:1px solid var(--bordure-composant);border-radius:var(--rayon-m);
  box-shadow:var(--ombre-m);padding:14px 18px 16px;display:block}
.encart-etiquette{display:block;font-family:var(--police-corps);font-size:14px;
  font-weight:400;line-height:1.3;color:var(--encre-douce);margin-bottom:6px}
.encart-donnee{display:block;font-family:var(--police-donnee);font-size:26px;
  font-weight:500;line-height:1.15;color:var(--encre-titre);white-space:nowrap}
/* Entre 1024 et 1119 px, le hero s'empile alors que le reste de la page reste
   en deux colonnes. C'est la seule facon de rendre la capture a plus de 728 px,
   le plancher sous lequel son plus petit objet passe sous 12 px de corps. La
   colonne de 280 px qui existait ici coupait 60,5 % de l'image et ne laissait
   qu'une etape sur cinq. Le corps du H1 n'est pas concerne : il reste sur
   l'echelle de la charte. */
@media(min-width:1024px) and (max-width:1119px){
  /* Le hero s'empile des 1119 px alors que le reste tient deux colonnes.
     L'intervalle mobile, lui, est repris plus bas, dans le bloc 1023. */
  .hero .conteneur{grid-template-columns:1fr;gap:20px}
  .hero .conteneur>*{min-width:0}
}
/* LE CADRAGE NE CONTIENT JAMAIS LE TITRE DE PAGE DE L'APPLICATION. « Detail de la
   campagne » est le seul objet de cette interface compose comme un objet
   d'affichage ; tout le reste est du texte d'interface. Cadrer dans le coin
   superieur gauche, c'est cadrer exactement la ou toute application pose son
   titre en grand -- et lui faire disputer le H1. On cadre donc dans le bandeau
   d'etapes, la ou le produit porte son argument.

   Fenetre source : y 70 -> 480, soit le sous-titre, le bandeau d'etapes et la
   barre d'outils. L'apercu de l'email en sort, et avec lui le second logotype
   Ediware, le titre concurrent et la date.

   Le decalage vaut 70/1120 = 6,25 % de la hauteur de l'image : un pourcentage de
   translation se resout sur la taille propre de l'element, donc il suit l'echelle
   sans qu'aucune valeur en pixels n'ait a etre recalculee. */
/* LA COUPE DROITE TOMBE DANS UNE GOUTTIERE, PAR PALIERS -- 2 septembre 2026.
   Le cadre reste a 760 px de 1120 a 1720 pendant que la colonne qui l'accueille
   retrecit : la part hors champ dependait donc de l'ecran, et la coupe tombait ou
   elle pouvait. Mesure : 300 px caches a 1280 (39 %, la troisieme tuile entiere),
   220 a 1440 (« Cliqu... »), et a 1600 « 483 » rendait « 48 », un nombre lisible et
   faux. La bande visible vaut 50vw - 180 (la colonne droite commence a 50vw + 180,
   verifie a 1280, 1440 et 1920).

   LE PRINCIPE : l'image ne bouge pas, la LARGEUR DU CADRE suit la fenetre pour que le
   bord de l'ecran tombe toujours sur une meme colonne source, choisie dans un blanc
   commun a toutes les lignes de texte du cadrage. Largeur = (source / colonne) x
   (50vw - 180). Le plancher de 760 px (lisibilite, voir plus bas) borne chaque
   palier par en bas : quand la colonne visee exigerait moins, on passe a la colonne
   sure suivante.

   Colonnes sures relevees au pixel sur les fichiers (blancs >= 8 px communs aux
   deux lignes de texte) :
     produit-statistiques.png (2000 px) : tuiles 41-658 | 698-1314 | 1354-1970,
       gouttieres 659-697 et 1315-1353, chiffres finissant a ~452 / ~1105 / ~1705,
       onglets d'en-tete 1600-1955.
     produit-campagne.png (1794 px) : 673-719 (apres « 1. Conception » et
       « Import URL »), 1071-1087 (apres « 2. Importer... » et « Import modele »),
       1511-1557 (apres le chevron de l'etape 3 et « Assistant IA »), 1708-1778
       (apres « 4. Tests » et « Previsualiser »).

   ⚠️ LES BORNES DES PALIERS DERIVENT DE 50vw - 180. Toucher a la grille du hero,
   au conteneur ou a la colonne de gauche les decale toutes ; il faut alors les
   remesurer, pas les recopier. ⚠️ Un palier qui passe SOUS 760 est un palier faux :
   le max() le rattrape, mais la coupe n'est alors plus garantie.
   ⚠️ `.hero{overflow:hidden}` coupe au bord de la fenetre, donc un cadre de 1 200 px
   ne fait pas defiler le document : scrollWidth = clientWidth, mesure a chaque palier.
   Au-dela du dernier palier, le debord garanti n'est plus 80 px mais 13 a 35 px :
   il suffit, puisque son seul objet est de ne jamais exposer le cote droit de
   l'image, laisse sans bordure. */
/* -- accueil : produit-statistiques.png, reperee par sa classe --pleine -- */
@media(min-width:1120px) and (max-width:1219px){
  /* colonne 680, gouttiere 1-2 : la premiere tuile entiere. 1235 -> 1263 px.
     ⚠️ SOUS 1200 LA BANDE VISIBLE NE SUIT PLUS 50vw - 180 : le conteneur est plein,
     la colonne droite garde ses 400 px et la bande vaut 420 px constants (mesure de
     1120 a 1200). Le plancher de 1235 px porte ce plateau ; le calc() prend le
     relais a 1200, ou les deux valent pareil. */
  .produit-cadre:has(.produit-vue--pleine){width:max(1235px, calc(147.06vw - 529.4px))}
}
/* 1220 -> 1377 : 760 px, la coupe court de 1131 a 1340, dans le blanc de la
   deuxieme tuile, apres « 2 274 ». */
@media(min-width:1378px) and (max-width:1679px){
  /* colonne 1340, gouttiere 2-3 : deux tuiles entieres. 760 -> 984 px. */
  .produit-cadre:has(.produit-vue--pleine){width:max(760px, calc(74.63vw - 268.7px))}
}
/* 1680 -> 1869 : 760 px, la coupe court de 1737 a 1802, dans le blanc de la
   troisieme tuile apres « 483 ». Les onglets d'en-tete y sont coupes, comme avant. */
@media(min-width:1870px){
  /* colonne 1965, apres « Statistiques uniques » : tout, jusqu'au bord du panneau. */
  .produit-cadre:has(.produit-vue--pleine){width:max(760px, calc(50.89vw - 183.2px))}
}
/* -- plateforme et pages anglaises : produit-campagne.png -- */
@media(min-width:1120px) and (max-width:1273px){
  /* colonne 696 : « 1. Conception » et « Import URL ». 1083 -> 1177 px. Meme
     plateau de 420 px sous 1200, meme plancher constant : 1794 x 420 / 696 = 1083. */
  .produit-cadre:not(:has(.produit-vue--pleine)){width:max(1083px, calc(128.88vw - 464px))}
}
@media(min-width:1274px) and (max-width:1659px){
  /* colonne 1079 : etapes 1-2, boutons Import URL / ZIP / modele. 760 -> 1080 px. */
  .produit-cadre:not(:has(.produit-vue--pleine)){width:max(760px, calc(83.14vw - 299.3px))}
}
@media(min-width:1660px) and (max-width:1835px){
  /* colonne 1534 : etapes 1-3, boutons jusqu'a Assistant IA. 760 -> 863 px. */
  .produit-cadre:not(:has(.produit-vue--pleine)){width:max(760px, calc(58.48vw - 210.5px))}
}
@media(min-width:1836px){
  /* colonne 1743 : etapes 1-4, boutons jusqu'a Previsualiser. 760 -> 1132 px a 2560. */
  .produit-cadre:not(:has(.produit-vue--pleine)){width:max(760px, calc(51.46vw - 185.3px))}
}
@media(max-width:1119px){
  .hero .conteneur>*{min-width:0}
  /* Empile : le cadre revient dans la colonne, il ne deborde plus, il retrouve
     donc sa bordure droite et ses quatre coins. */
  .produit-cadre{width:100%;border-right:1px solid var(--filet);border-radius:var(--rayon-m)}
  /* La place que l'encart occupe SOUS le cadre se reserve en marge et non en
     padding : un padding entrerait dans la hauteur de .produit, donc dans le
     calc(100% - 18px) qui ancre l'encart, et le repousserait a l'infini. */
  .produit{margin-bottom:64px}
  /* GESTE 4 — LA SIGNATURE REMONTE AU-DESSUS DU PLI MOBILE. A 390x844 l'encart
     tombait a y 924-1001, entierement sous le pli, et le cadre n'en montrait que
     76 px : le premier ecran mobile ne portait AUCUNE signature typographique.
     column-reverse le fait passer devant la capture, dans le seul ecran que la
     majorite des visiteurs verra. Il redevient statique, donc il ne recouvre
     plus rien. */
  .produit{display:flex;flex-direction:column-reverse;gap:8px}
  .produit-encart{position:static;padding:12px 14px 14px}
  /* 16 px et non 22. Deux raisons qui vont dans le meme sens : 22 n'est pas un
     echelon de l'echelle declaree pour la chasse fixe -- 26 / 16 / 14, « Aucun autre
     corps » -- et « news@votre-domaine.fr », 21 signes, demandait 277 px pour 252
     disponibles a 320 px, donc la valeur y etait coupee. A 16 px elle rend 202 px. */
  .encart-donnee{font-size:16px}
}
/* UN SEUL CHIFFRE DE LISIBILITE, ET IL EST DERIVE. Il y en avait deux -- 790 et
   728 -- pour le meme raisonnement sur la meme image, ce qui est impossible : un
   sous-ensemble ne peut pas avoir un plancher plus haut que l'ensemble. 728 valait
   768-40 et 790 valait 830-40 : c'etaient DEUX LARGEURS DE COLONNE habillees en
   mesure typographique.
   La seule mesure est celle-ci : le plus petit objet du cadrage a une capitale de
   8,9 px quand l'image est rendue a 760 px, et 12 px de corps en exigent 8,52,
   soit 728 px de rendu. L'image est donc posee a 760 px -- la largeur ou la mesure
   a ete prise -- des que la colonne ne peut plus les fournir.
   Les deux rognages se cumulent alors : la fenetre verticale y 70 -> 480 reste, et
   l'image deborde en plus horizontalement du cadre.
   Hauteur du cadre : 410 x 760 / 1794 = 174 px.

   ⚠️ CE PLANCHER NE VAUT PLUS POUR L'ACCUEIL, ET LE RAISONNEMENT CI-DESSUS RESTE
   JUSTE : c'est son OBJET qui a change. Les 8,9 px de capitale ont ete mesures sur
   `produit-campagne.png`, qui sert toujours la page plateforme et les deux pages
   anglaises -- pour elles, tout ce qui precede tient. L'accueil francais est passe le
   1er septembre a `produit-statistiques.png`, 2000 px de large au lieu de 1286, donc
   rendu a 0,38x au lieu de 0,59x : le plus petit objet du cadrage y a une capitale de
   6,1 px, soit 28 % SOUS le plancher, et cinq des dix objets de texte passent dessous.
   Verifie au rendu 1x : ils restent lisibles, donc ce n'est pas une faute de rendu.
   C'est une regle ecrite qui a survecu a l'image qui la fondait, et une session neuve
   la relira comme vraie. Le cadrage large n'est pas negociable pour autant -- il est
   demontre par le debord, voir le commit de la capture -- donc c'est LE PLANCHER qui
   est a remesurer sur son nouvel objet, pas la capture a retrecir. */
@media(max-width:799px){
  .produit-cadre{aspect-ratio:auto;height:174px}
  .produit-vue{width:760px;max-width:none}
}


.grille-3{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
/* Variante a deux colonnes. Une section qui n'a que DEUX sous-titres laissait un trou
   d'un tiers de largeur dans la grille a trois : le lecteur y lit un element manquant,
   pas une respiration. Le nombre de colonnes suit donc le nombre de cartes. */
.grille-2{display:grid;grid-template-columns:repeat(2,1fr);gap:24px}

/* TEMOIGNAGES. Employes sur /qui-sommes-nous/, et sur elle seule.
   ⚠️ PAS DE CARTES, ET C'EST UNE DECISION MESUREE AILLEURS. Le directeur artistique
   l'a etablie sur le pilote : « la carte est un objet de COMPARAISON, elle promet que
   ses voisines de rangee sont commensurables ». Les treize temoignages de cette page
   vont de 90 a 480 signes : en cartes, ils promettraient une comparaison que leur
   longueur dement, et laisseraient le vide au bas des plus courts -- le defaut exact
   qui avait fait retirer les quinze cartes du pilote.
   Un flux en colonnes ne promet rien : chaque temoignage prend la hauteur qu'il a. */
/* CHRONOLOGIE. Employee sur /qui-sommes-nous/, et sur elle seule.
   ⚠️ ELLE REPARE UN CONTENU QUI N'AVAIT PAS ETE PORTE. Dix-neuf annees de faits
   dates sortaient du dump d'un widget « Timeline » d'Elementor -- commentaires HTML,
   dix-huit `<ul>`, et une balise `<style>` -- et mon portage les avait logees A
   L'INTERIEUR du troisieme `.arg`, sous un h3 sur l'autonomie des salaries. Vingt-deux
   ans d'histoire de la societe en sous-element d'un paragraphe, soit 15 065 signes
   et 21,2 % de la page.
   L'ANNEE EST UN OBJET, PAS UN LABEL GRIS. Dans le dump elle rendait en 16 px
   `--encre-douce`, exactement le style des paragraphes qui l'entouraient : 2024 ne se
   lisait pas comme une date. Elle prend donc la fonte de titrage, sa propre colonne,
   et une seule mesure regne dans le bloc. C'est la seule matiere que cette page
   possede en propre. */
/* ⚠️ L'ANNEE A D'ABORD ETE UN H3 BLEU, ET C'ETAIT LE DEFAUT. Rubik 600 / 22 px /
   1,35 : c'est la ligne H3 de la charte caractere pour caractere, recoloree -- et
   aussi la spec de `.entete-clauses` sur la meme page. Au mobile le h2 fait 24 px
   pour une annee a 22 : la date etait PLUS PETITE que le titre de sa propre section.
   Elle prend le registre de chiffre d'affichage que la feuille possede deja a 48 px,
   employe par `.chiffres strong`, `.rang-chiffre` et `.prose>h2::before`.
   LES TROIS NOMBRES SONT MESURES, PAS CHOISIS.
   128 px : « 2024 » en Rubik 600 / 48 px / -0,02em rend 120,8 px. Meme methode que
            `.rang-chiffre`, qui reserve 60 px pour un « 10 » de 55,1.
   --encre-douce : l'encre des deux autres composants a 48 px. Elle rend le bleu au
            seul h2, qui redevient plus fort que ses entrees.
   +152 px : la mesure du texte reste exactement a 585 px, soit 58ch. Le bloc finit a
            877 au lieu de 725, et le vide a sa droite tombe de 595 a 443 px.
   La page ne s'allonge pas, elle RACCOURCIT de 61 px. */
.chrono{display:grid;gap:0;margin:0;max-width:calc(var(--mesure) + 152px)}
.chrono>div{display:grid;grid-template-columns:128px 1fr;gap:24px;
  padding:16px 0;border-top:1px solid var(--filet)}
.chrono dt{font-family:var(--police-titre);font-weight:600;font-size:48px;
  line-height:1;letter-spacing:-.02em;color:var(--encre-douce)}
.chrono dd{margin:0;font-size:16px;line-height:1.6;color:var(--encre)}
.chrono dd ul{margin:0;padding-left:18px}
.chrono dd li{margin-bottom:4px}
@media(max-width:520px){
  /* Sous 520 la colonne de 128 px ne laisserait que 152 px au texte : la date passe
     au-dessus, et son corps descend d'un cran -- 48 px sur une ligne seule y
     ecraserait le fait qu'elle date. */
  .chrono>div{grid-template-columns:1fr;gap:4px}
  .chrono dt{font-size:36px}
}

.temoignages{columns:3;column-gap:32px}
/* ⚠️ FILET BLEU, ET NON `--filet`. En gris il rendait 1,19:1 sur le fond `--fond-alt` :
   optiquement absent a 1x, entierement disparu au flou de 3,2 px, ou le bloc rendait
   trois colonnes de texte courant. `.normes` fait 4,56:1 avec le meme fond. Les
   temoignages avaient pris la FORME de ce composant et laisse sa COULEUR. */
.temoignage{break-inside:avoid;margin:0 0 28px;padding-left:16px;
  border-left:2px solid var(--bleu)}
.temoignage p{margin:0 0 8px;font-size:16px;line-height:1.6;color:var(--encre)}
.temoignage cite{display:block;font-style:normal;font-size:14px;color:var(--encre-douce)}
/* LA BANDE DE PAROLES DE L'ACCUEIL. Les trois citations ont d'abord ete glissees DANS
   `.clients`, la bande de logos : 258 px de texte courant dans une bande dont le
   padding vaut 24/28, colles a zero pixel des logos, et 27 px au-dessus de `.chiffres`
   qui gagne tout au flou. Elles etaient aussi posees a 900 px, soit 536 px AVANT le
   premier argument : un logo se reconnait sans contexte, une citation non.
   Bande propre, blanche -- le gris est deja pris par `pourquoi` et `ressources`, le
   bleu par `chiffres` et `cloture` -- separee par le seul precede du site pour joindre
   deux blancs, le filet du pied. Le padding est celui des sections d'argument, aucun
   cran nouveau.
   ⚠️ GRILLE ET NON `columns`. En multicol, trois extraits de longueurs libres rendaient
   des filets de 258, 210 et 107 px et un vide de 365 x 151 px en bas a droite. La
   grille etire les trois a la meme hauteur sans propriete supplementaire, et
   `/qui-sommes-nous/`, qui porte les treize et ou le denivele ne se voit pas, garde son
   multicol intact. */
/* POURQUOI CET OBJET EXISTE : trois citations de « intuitive », « a l'ecoute » et
   « reactive » ne portent aucun fait, et Mailchimp en met une de 101 signes soudee a
   deux chiffres. La duree de relation est la seule matiere que la maison possede et
   qu'un concurrent fonde en 2001 ne peut pas revendiquer contre 2002.
   ⚠️ ET ELLE NE SE DEDUIT PAS D'UNE CITATION. Prodiliste ecrivait « depuis maintenant
   7 ans » : l'avis datait de 2020, l'annee reelle est 2013. La mention est sortie de la
   citation quand l'objet a pris la duree en charge, sinon la carte se contredisait de
   six ans. Les trois annees viennent du commanditaire, aucune n'est calculee. */
/* ⚠️ DEUX ETAGES, ET C'EST LE FOND DU SUJET. En un seul, « Client depuis 2017 » posait
   l'annee et son libelle au MEME corps et a la MEME graisse : l'annee ne mesurait alors
   que 59,2 px sur 239,3, soit 24,7 % de l'objet, et les trois quarts restants etaient un
   mot invariant repete trois fois. L'objet portait donc surtout ce qui ne prouve rien.
   `.chiffres`, 2 343 px plus haut dans la meme page, fait l'inverse et le fait juste :
   `2002` en 48/700 sur « Editeur français depuis » en 14/400, rapport de 3,43:1. Deux
   traitements opposes du meme objet -- un millesime qui prouve une duree -- sur une
   seule page : le second annulait le premier.
   ⚠️ 40 px ET NON 48 : le 48 reste a `.chiffres`, qui est la preuve agregee du premier
   ecran. L'anciennete rime avec elle sans la doubler.
   ⚠️ CE QUE LE DEUXIEME ETAGE REPARE AUSSI : a 28/600 sur `--bleu-encre`, l'objet avait
   la fonte, le corps et l'encre du H2 de sa propre bande, a 12 px de lui, une graisse
   d'ecart pour seule difference. Au flou, la bande rendait quatre traits bleus de meme
   rang et le titre gagnait. Le H2 n'a pas bouge, c'est l'objet qui a change de rang. */
.paroles .anciennete{display:block;font-family:var(--police-titre);font-weight:700;
  font-size:40px;line-height:1.1;color:var(--bleu);margin-bottom:10px}
.paroles .anciennete span{display:block;font-family:var(--police-corps);font-weight:400;
  font-size:13px;line-height:1.4;color:var(--encre-douce);letter-spacing:.02em;margin-bottom:2px}
/* ⚠️ LES CORPS NE DECROISSENT PAS TOUS AU MEME RYTHME, ET L'ORDRE S'INVERSE EN BAS.
   `.chiffres strong` et le H1 sont fluides et tombent a 38 et 25,8 px sous 360 ;
   40 px pose en dur ne bouge pas. Les trois millesimes devenaient donc le plus gros
   corps de TOUTE la page, devant la preuve agregee du premier ecran et devant le titre
   du site. Une hierarchie juste a 1 440 peut se retourner a 320 : elle se verifie aux
   deux bouts. */
@media(max-width:359px){.paroles .anciennete{font-size:34px}}
.paroles{border-top:1px solid var(--filet)}
.paroles .temoignages{display:grid;grid-template-columns:repeat(3,1fr);gap:32px}
.paroles .temoignage{margin:0}
/* ⚠️ DE TROIS COLONNES A UNE, SANS PASSER PAR DEUX : trois cartes sur deux colonnes
   laissent une orpheline sur la seconde ligne. */
@media(max-width:1023px){.paroles .temoignages{grid-template-columns:1fr}}

/* ⚠️ NE PAS POSER UN `.temoignage` SEUL. Sa mesure ne vient pas de lui-meme mais de
   `.temoignages{columns:3}` : isole dans un conteneur de 1 200 px, le meme bloc rend
   des lignes de 150 signes, plus du double de la mesure de lecture du site. Un
   modificateur `--seul` a existe ici quelques heures pour le borner, sur l'accueil,
   sous la bande de logos. Il reglait la mesure et rien d'autre : au flou, un bloc
   unique compose comme le corps courant reste indiscernable d'un paragraphe, et un
   temoignage qui ne se distingue pas d'un paragraphe ne prouve rien. Le composant
   veut donc ses voisines -- l'accueil en porte trois. */
@media(max-width:1023px){.temoignages{columns:2}}
@media(max-width:640px){.temoignages{columns:1}}
/* P1 + T1 : "Pourquoi choisir Ediware" cesse d'etre une rangee de trois cartes.
   Colonne d'arguments a gauche, objet de preuve a droite, sur le modele du hero.
   La page gagne une seconde COMPOSITION au lieu d'une seconde rangee.
   L'objet de preuve se pose sur --fond-alt avec un filet, JAMAIS en troisieme
   aplat de marque : le volet portee en autorise deux par page. */
.pourquoi .conteneur{display:grid;grid-template-columns:1fr 400px;gap:64px;align-items:start}
/* ⚠️ `*{margin:0}` EST UN RESET GLOBAL, ET RIEN NE SEPARAIT LES PARAGRAPHES ICI.
   Seuls `.entete-page p+p` (14 px) et `.encadre p+p` (12 px) portaient une separation.
   Le jour ou deux paragraphes sont descendus d'un en-tete vers cette colonne, ils ont
   quitte un conteneur qui les espaçait pour un conteneur qui ne les espaçait pas :
   QUATRE PARAGRAPHES CONSECUTIFS, 307 px, ECART DE 0 PX, douze lignes d'un seul tenant.
   La page avait echange une anomalie d'en-tete contre le plus long pave non articule
   du site.
   12 px, la valeur de `.encadre p+p`, seul precedent du site a l'echelle du corps.
   Les deux rails sont exclus : ils ont leur propre rythme et ne portent pas de
   paragraphes suivis. */
/* ⚠️ `p+p` NE VOYAIT QUE LA MOITIE DU PROBLEME. Une liste suivie d'un paragraphe
   restait a 0 px pendant que deux paragraphes passaient a 12 : le paragraphe conclusif
   se lisait comme un item de plus, et le contraste avec les 12 px du dessus rendait ce
   collage PLUS voyant qu'avant. Defaut ne de la regle elle-meme, sur compte-gratuit et
   qui-sommes-nous.
   Portee mesuree avant d'ecrire, avec le selecteur lui-meme et non un parcours
   d'enfants : 47 occurrences sur 14 pages -> 64 sur 17, soit +17. */
/* ⚠️ LA REGLE NE VISAIT QUE `.pourquoi`, ET LE DEFAUT N'Y ETAIT PAS LIMITE. Toute
   section a une piste souffrait du meme `*{margin:0}` : sur `compte-gratuit` cinq
   paires de paragraphes se touchaient encore, une sur `qui-sommes-nous`, quatre sur
   `livre-blanc-emailing-1` des sa creation.
   PORTEE MESUREE AVANT D'ECRIRE, avec le selecteur lui-meme : 64 correspondances -> 95,
   sur 20 pages. Mais DIX PAIRES SEULEMENT se touchent vraiment ; les 21 autres ont deja
   un ecart superieur, et les marges adjacentes fusionnent, donc rien n'y bouge. Deux
   paires de `plateforme-sms` ont un ecart de 10 px pose EN LIGNE par WordPress : la
   specificite d'un style en ligne bat la feuille, elles restent a 10.
   `.prose` est exclue : les articles ont leur propre rythme de bloc. */
main section .conteneur>div:not(.normes):not(.etapes):not(.prose) :is(p,ul,ol)+:is(p,ul,ol){margin-top:12px}
/* LA COLONNE DE DROITE N'EST PLUS RESERVEE A L'OBJET DE PREUVE. Retirer les cartes du
   pilote avait laisse onze blocs d'arguments dans un conteneur de 1 160 px avec un
   paragraphe plafonne a 52ch : 635 px de vide a droite, 13,1 % de la surface, et cinq
   ecrans sur huit qui se lisent au flou comme une bande etroite a gauche.
   La regle qui remplit cette colonne est SEMANTIQUE et non quantitative, donc elle se
   transporte aux dix-sept pages restantes : ce que la page nomme comme NORME, LABEL ou
   SEUIL OPPOSABLE va a droite ; ce que l'editeur affirme reste a gauche.
   Pas de chasse fixe ici : une norme n'est pas une donnee possedee par le client. */
/* LA COLONNE DE NORMES SUIT LE LECTEUR.
   Le rail droit etait mort sur 123 732 px cumules a 1440x900, mesure par
   `rail-mort.mjs` sur les 18 pages qui portent une grille a deux pistes : une
   colonne de 220 px de haut en moyenne dans une rangee qui en fait plusieurs
   centaines, donc un rail que le lecteur voit vide la plupart du temps.

   ⚠️ AUCUNE MEDIA QUERY, ET C'EST MESURE, PAS SUPPOSE. Sous 1024 la grille passe a
   une piste et la colonne devient dernier enfant de son bloc conteneur : il ne lui
   reste rien en dessous, le collage n'accroche jamais et elle defile normalement.
   Verifie sur le precedent `.preuve-obj`, deja collant sans garde depuis le
   pilote : son haut tombe a -300 px a 390 comme a 768.

   ⚠️ PAS DE SCRIPT NON PLUS, CONTRAIREMENT A LA COLONNE DE L'ARTICLE. Celle-la
   depassait la fenetre et son bas devenait inatteignable, d'ou `colonne.js`. Ici la
   plus haute des 56 colonnes fait 534 px (statistiques-et-reporting) contre 639 px
   de hauteur utile au format le plus court supporte, 1366x768 moins l'en-tete
   collant et la respiration. Toutes tiennent. `recette-pilote.mjs` refuse desormais
   toute colonne qui depasserait, parce que le contenu peut grossir.

   `align-self` n'est pas repris de `.preuve-obj` : la grille declare deja
   `align-items:start`, le redeclarer serait du bruit. */
/* ⚠️ LE FILET EST BLEU SUR TOUTES LES COLONNES, ET C'EST UN RETOUR EN ARRIERE ASSUME.
   J'avais reserve le bleu a la seule classe « Les normes » -- 13 colonnes sur 60 --
   pour donner au rail la distinction de VUE que ses cinq libelles n'ont pas : au flou
   de 3,2 px, ils ne se separent qu'a 0,4 %, et le filet opposable rendait 5,7 fois la
   saturation du neutre. La mesure etait juste et le raisonnement faux.

   TROIS MESURES L'ONT DEFAIT, ET AUCUNE N'ETAIT DE MOI.

   1. J'AI COMPARE LE FILET A SON VOISIN, PAS A LA PAGE. Un accent ne signe que s'il
      est RARE sur la page. Or les H2 de section sont en `--bleu-encre` : meme teinte
      206°, meme saturation, 1,55:1 d'ecart de clarte seulement, et cinq a sept par
      page. Le filet de 600 px2 vit dans une fenetre qui compte 25 000 px2 de bleu, et
      au flou le H2 qui le surplombe monte a 67-74 % de saturation contre ses 31,5.
      Il n'etait pas un accent, il etait un tiers d'un bleu qui court deja partout.

   2. LA REGLE ETAIT CONTREDITE 21 FOIS SUR 27, ET 13 FOIS PAR MOI. Le site porte 27
      filets gauches bleus : 13 `.normes.opposable`, 13 `.temoignage` -- que j'avais
      passes au bleu trois passes plus tot parce que le gris rendait 1,19:1 -- et
      `.coordonnees`. Six a huit seulement portent de la matiere attestee par un tiers.
      La seule regle deductible restait « filet bleu = colonne de droite ».

   3. ELLE N'ETAIT OBSERVABLE NULLE PART. Deux encres ne coexistent dans une meme
      fenetre que sur 1 400 px de defilement sur le moule et 350 sur qui-sommes-nous.
      Zero ailleurs, et ZERO SUR TOUT LE MOBILE : sous 1024 la grille passe a une
      colonne. Un contraste qu'on ne peut pas constater n'est pas une regle.

   CE QU'ELLE A COUTE, MESURE : -1,5 sur gestion-de-base-de-contacts, -0,5 sur
   formulaires-en-ligne, -0,5 sur developpement-sur-mesure. Ces trois pages n'ont
   aucune colonne attestee, donc leur corps n'avait plus un seul objet bleu.

   ⚠️ ET LE CHIFFRE QUI FONDAIT LE -0,5 SUR FORMULAIRES ETAIT FAUX. J'avais annonce
   que le premier contact avec le bleu y passait de 775 px a 5 147 sur 8 184 : cette
   mesure NE COMPTAIT QUE LES OBJETS BLEUS NON TEXTUELS. Les H2 de section sont en
   #005597, et le premier tombe a 775 px DANS LES DEUX ETATS. Le premier contact n'a
   jamais recule. La conclusion tenait pour une autre raison -- le rail cessait
   d'appartenir a la couleur de la page -- mais elle a ete tiree d'une mesure partielle.
   Quatrieme fois dans ce projet que la meme faute produit un chiffre faux : mesurer un
   contenant au lieu de son contenu, ou un sous-ensemble au lieu de l'ensemble.
   Le partage semantique etait juste ; son porteur ne l'etait pas. Un filet de 3 px
   est trop mince pour porter la seule distinction de vue d'un systeme de 60 colonnes. */
.normes{border-left:3px solid var(--bleu);padding-left:20px;
  position:sticky;top:105px}
.normes p{margin:0 0 12px;font-size:14px;color:var(--encre-douce);letter-spacing:.02em;
  text-transform:uppercase;font-weight:600}
.normes ul{list-style:none;margin:0;padding:0}
.normes li{font-size:18px;font-weight:500;color:var(--encre-titre);margin-bottom:12px;
  line-height:1.35}
.normes li span{display:block;font-size:14px;font-weight:400;color:var(--encre-douce)}
@media(max-width:1023px){.normes{margin-top:8px}}

/* Coordonnees. Colonne de droite de /contact/, et de la seule.
   Elle reprend le filet bleu de `.normes` -- meme place, meme role de contrepoids --
   sans en reprendre le libelle : les cinq termes du rail nomment la nature de la
   preuve -- chiffres, normes, engagements, fonctions, indicateurs -- et une
   adresse postale n'en est pas une.
   ⚠️ LES DEUX NUMEROS SE COMPOSENT EN CHASSE FIXE 14 PX, l'echelon « donnee en
   ligne », celui du bandeau superieur. Le bandeau affiche deja `01 75 43 77 01` sur
   les vingt pages : composer le meme numero en Inter 18 px ici l'aurait montre dans
   deux fontes sur un seul ecran. Ce n'est PAS l'echelon 26 px de la donnee possedee :
   un numero de standard est le meme pour tous les clients, il ne signe rien. */
.coordonnees{border-left:3px solid var(--bleu);padding-left:20px;
  align-self:start;position:sticky;top:105px}
.coordonnees>p{margin:0 0 12px;font-size:14px;color:var(--encre-douce);
  letter-spacing:.02em;text-transform:uppercase;font-weight:600}
.coordonnees ul{list-style:none;margin:0;padding:0}
/* ⚠️ TOUTE LA COLONNE TIENT AU ROLE « LEGENDE », 14 PX, ET LA HIERARCHIE VIENT DE LA
   FAMILLE ET DE L'ENCRE, JAMAIS DU CORPS.
   Le defaut reel n'etait pas la graisse -- 18/500 est un emploi legitime, la charte
   le dit maintenant -- mais le fait que DEUX VALEURS DE LA MEME LISTE vivaient a deux
   corps : le telephone a 14 px en chasse fixe, contraint par l'emploi de convention,
   et l'adresse a 18 px. Meme role, deux crans, dans quatre `<li>` voisins.
   La cause est un composant emprunte a semantique retournee : dans `.normes`, le
   texte du `<li>` est le NOM de la norme, en 18/500, et le `<span>` est sa glose a
   14 px. Ici les roles sont inverses -- le `<li>` porte l'etiquette, le `<span>`
   porte la valeur. Meme forme de balisage, sens contraire.
   On ne pouvait pas remonter le telephone : un numero de standard est le meme pour
   tous les clients, il n'a droit qu'a l'emploi de convention du bandeau, 14 px. C'est
   donc l'adresse qui redescend, et la distinction se fait autrement : l'etiquette en
   Inter 400 sur encre douce, la valeur en Inter 500 sur encre de titre, la ligne
   directe en chasse fixe 500. Trois signaux, un seul corps. */
.coordonnees li{font-size:14px;font-weight:400;color:var(--encre-douce);
  margin-bottom:16px;line-height:1.45}
.coordonnees li span{display:block;margin-top:2px;font-size:14px;font-weight:500;
  color:var(--encre-titre);line-height:1.45}
/* 14 PX, ET J'Y REVIENS APRES M'ETRE TROMPE DEUX FOIS. Le directeur artistique
   avait prescrit 14, puis 26 ; j'ai refuse 26 -- a raison, la charte dit « ils vivent
   a 14 px, la signature vit a 26 » -- et pose 16 a la place. C'ETAIT LIRE LE MAUVAIS
   TABLEAU. La liste fermee dit QUELS EMPLOIS de la chasse fixe sont autorises hors
   donnee possedee ; l'echelle des echelons dit A QUEL CORPS on compose un emploi
   DEJA autorise. Se servir de la seconde pour ouvrir un emploi, c'est la lire comme
   la premiere. Un numero de standard n'a droit qu'a l'emploi de convention du
   bandeau, et cet emploi vit a 14.

   ⚠️ ET MA VALIDATION DU 16 ETAIT FAUSSE, POUR LA TROISIEME FOIS SUR CETTE QUESTION.
   J'avais conclu a la parite sur des boites de 21 px identiques. `getClientRects()`
   rend la boite d'em : 21/16 = 1,31 en chasse fixe, 21/18 = 1,17 en Inter. Deux
   rapports differents qui atterrissent sur 21 est une coincidence arithmetique, pas
   une egalite de corps. Mesuree sur un meme signe, l'adresse menait encore de 12,1 %.
   Le geste n'avait donc meme pas repare ce qu'il visait.

   LA CAUSE N'EST PAS LE TELEPHONE, C'EST L'ADRESSE, et elle est ailleurs : le 18/500
   de `.coordonnees li span` est repris de `.normes li`, ou 18/500 porte le NOM de la
   norme avec sa glose a 14 px dessous. Ici les roles sont retournes. Et le couple
   Inter 18/500 ne figure dans aucune ligne de l'echelle, qui donne « Corps large,
   Inter, 18 px, 400 ». Ce n'est donc pas un defaut de cette page : il vient de
   `.normes`, employe sur seize pages, et se traite comme tel. */
.coordonnees .coord-donnee{font-family:var(--police-donnee);font-size:14px;font-weight:500;
  letter-spacing:0;color:var(--encre-titre)}
@media(max-width:1023px){.coordonnees{margin-top:8px;position:static}}

/* --- /contact/ : le calendrier ne s'affiche qu'au-dessus de 1080 px ----------
   MESURE, PAS INTUITION, ET LE SEUIL N'EST PAS « MOBILE ». Le widget TidyCal
   bascule dans sa disposition a deux colonnes quand SON IFRAME atteint 996 px,
   pas quand la fenetre franchit un palier rond. En dessous il rend une colonne
   unique de 965 a 1176 px de haut qui n'affiche AUCUN creneau au chargement.
   Releve a 390, 600, 700, 768, 800, 900, 1000, 1010, 1020, 1024, 1028 et 1032 px
   de fenetre : zero creneau partout. A 1036 px (996 px d'iframe) : 27 creneaux
   et 600 px de haut.
   Il coutait donc jusqu'a 1176 px de page pour ne rien proposer, et repoussait
   le formulaire a 1 041 px sous le pli a 390 px. Tout portable sous 1036 px etait
   concerne, pas seulement les telephones.
   Le repli maison prend sa place ET SON RANG : la section reste la premiere, car
   tous les appels a l'action du site menent ici pour reserver.
   Seuil pose a 1080 px, deja present dans la feuille, ce qui laisse 44 px de
   marge au-dessus du basculement mesure -- une largeur d'iframe se calcule sur
   le conteneur, et le conteneur peut changer. */
@media(max-width:1079px){.tidycal-embed{display:none}}
@media(min-width:1080px){.visio-repli{display:none}}
/* PREMIERE VERSION : une carte --bleu-voile bordee --filet. Elle ne dessinait
   RIEN. Fond sur blanc 1,091:1, filet sur son propre fond 1,185:1 : au flou a
   3,2 px la boite avait disparu, il ne restait que la barre orange. L'objet qui
   remplace un calendrier de 599 px etait, visuellement, un bouton seul -- pour
   24 px de rembourrage et 48 px de hauteur.
   La matiere vient donc de la TYPOGRAPHIE, pas d'un cadre : « 20 minutes en
   visio » passe au cran d'affichage des engagements, celui que `.entete-clauses`
   pose douze centimetres plus haut sur « Reponse sous 4 h ouvrees ». */
/* `align-items:stretch` : sous 600 px le bouton prend la pleine chasse, il est
   le seul geste de la section une fois le calendrier retire. */
.visio-repli{margin:20px 0 0;display:flex;flex-direction:column;
  align-items:stretch;gap:16px}
.visio-duree{margin:0;font-family:var(--police-titre);font-weight:600;
  font-size:26px;line-height:1.32;letter-spacing:-.011em;color:var(--encre-titre)}
.visio-repli .btn{justify-content:center}
/* ⚠️ LE RANG PARTAGE EST LA CONDITION DU GESTE, PAS SA FINITION. Empiles, l'objet
   et le bouton restent deux choses posees l'une sous l'autre et la section ne se
   lit pas comme un objet. Cote a cote, elle en devient un. Le seuil est pris ou
   les deux tiennent sur une ligne sans que le libelle du bouton se casse. */
@media(min-width:600px){
  .visio-repli{flex-direction:row;align-items:center;gap:28px}
  .visio-repli .btn{flex:0 0 auto}
}
.args{display:grid;gap:0}
.arg{padding:24px 0;border-top:1px solid var(--filet)}
.arg:first-child{border-top:0;padding-top:0}
.arg h3{margin-bottom:6px}
.arg p{color:var(--encre-douce);font-size:16px;max-width:52ch}
/* L'objet de preuve etait --fond-alt DANS une section --fond-alt : fond sur fond,
   separe par un bord a 1,193:1 qui disparait au plissement. Il se pose en clair
   sur le gris de section, avec le meme bord que les cartes, a 3,264:1. */
/* LA DONNEE POSSEDEE DEVIENT UN OBJET D'AFFICHAGE, ET NON UNE LIGNE DE PANNEAU.
   Elle etait a 16 px dans une carte bordee : la page comptait alors DIX
   OCCURRENCES de chasse fixe dont UNE SEULE survivait au flou de 3,2 px. Une
   signature qui ne se voit qu'une fois n'est pas une signature, c'est un
   ornement -- le lecteur ne peut en deduire aucune regle par l'oeil.

   Les trois donnees passent a l'echelon « donnee majeure, 26 px », celui de
   l'encart du hero. La signature passe d'un objet perceptible a quatre, et la
   regle devient VISIBLE et non plus seulement logique.

   La carte disparait : ses 446 px dans une colonne de 1 036 laissaient 590 px de
   vide dessous, et la page comptait dix-sept panneaux bordes arrondis identiques.
   Un filet horizontal entre les donnees suffit a les separer.

   ⚠️ Les deux IP sont sur DEUX LIGNES et non appariees : « 203.0.113.42 ·
   203.0.113.43 » mesure 421 px a 26 px, pour 352 px utiles dans la colonne. C'est
   aussi ainsi qu'une interface les affiche. */
/* ⚠️ top MESURE CONTRE L'EN-TETE COLLANT, ET NON CHOISI. A 32 px l'objet passait
   SOUS l'en-tete, dont le bas colle a 81 px a toutes les largeurs : 49 px masques
   en permanence sur 508 px de defilement, le chapeau « Ce que vous possedez en
   propre » entierement cache et la premiere IP rognee de 9 px sur 33. J'avais
   decapite la signature que le geste venait de promouvoir.
   81 px de barre + 24 px d'air. Une regle en double disait aussi top:32px plus
   bas dans la feuille et gagnait par ordre de source : elle est retiree. */
.preuve-obj{align-self:start;position:sticky;top:105px}
.preuve-tete{font-size:14px;font-weight:600;color:var(--bleu-encre);
  margin:0 0 18px;letter-spacing:.01em}
.preuve-bloc{padding:26px 0;border-top:1px solid var(--filet)}
.preuve-bloc:first-of-type{border-top:0;padding-top:0}
/* ⚠️ LA DONNEE NE DOIT JAMAIS SE CASSER : coupee sur deux lignes, elle n'est plus une
   donnee, c'est du texte. Mesure : `c.durand@votre-domaine.fr`, 25 signes, se casse en
   deux a 390 px, et les trois donnees du pilote se cassent a 320. Temoins : tarifs
   (12 signes) ne casse a aucune largeur, l'accueil et plateforme (21-22 signes) cassent
   a 320 seulement.
   ⚠️ J'AI D'ABORD FAIT SUIVRE LE CORPS A LA LARGEUR -- `min(26px, 6.4vw)` plus `nowrap`.
   Deux defauts : la donnee debordait quand meme le document de 4 px a 390 et 7 a 320,
   ET la regle touchait tarifs et l'accueil, dont les donnees tiennent deja. Une regle
   qui repare une page en deplaçant trois autres n'est pas une regle.
   LE PLAFOND EST DONC SUR LA DONNEE, PAS SUR LE CORPS : 17 signes au maximum. C'est une
   contrainte de redaction, verifiee par script, et le corps reste a 26 px partout. */
.preuve-donnee{display:block;font-family:var(--police-donnee);font-size:26px;
  font-weight:500;line-height:1.25;color:var(--encre-titre)}
.preuve-bloc span{display:block;margin-top:10px;font-size:14px;color:var(--encre-douce)}
.preuve-note{margin:26px 0 0;padding-top:22px;border-top:1px solid var(--filet);
  font-size:14px;color:var(--encre-douce)}
/* La seconde note enchaine la premiere : pas de second filet. */
.preuve-note--suite{margin-top:12px;padding-top:0;border-top:0}
.preuve-tete{font-size:14px;font-weight:600;color:var(--bleu-encre)}
/* CHIFFRE PERIME, ET L'INTERDICTION QUI S'Y ADOSSAIT EST LEVEE.
   Ce commentaire annoncait un vide de 84,3 px « constants sur onze largeurs » et
   concluait : ne pas reparer. Les deux etaient vrais quand la colonne d'arguments
   faisait trois lignes. La passe d'enrichissement l'a portee a 1 026 px sans que
   ce chiffre soit remesure : LE VIDE FAIT 580 px de 1280 a 2560, et 605 a 1120.
   Soit 232 000 px carres en haut a droite du deuxieme ecran, visibles au flou.

   C'est la troisieme fois dans ce projet qu'un nombre inscrit en commentaire
   survit a la page qu'il decrivait. Un chiffre commente doit porter la condition
   de sa mesure, faute de quoi il devient une instruction fausse -- ici une
   interdiction de reparer.

   align-self:start reste : etirer l'objet lui donnerait 580 px de pied blanc
   DANS un cadre borde, ce qui est pire qu'un vide de section. Mais le trou est
   desormais un defaut ouvert, a traiter par le contenu ou par un objet collant,
   et non un comportement a preserver. */
@media(max-width:1023px){.pourquoi .conteneur{grid-template-columns:1fr;gap:32px}}

.carte{background:#fff;border:1px solid var(--bordure-composant);border-radius:var(--rayon-m);padding:0;
  overflow:hidden;transition:border-color 150ms,transform 200ms}
.carte:hover{border-color:var(--bleu);transform:translateY(-2px)}
.carte-corps{padding:24px}
.carte p{color:var(--encre-douce);font-size:16px}
/* T1 : le filet de marque en tete de carte remplace l'icone dans un carre
   arrondi, qui est le motif SaaS generique. Rayon compose 8px 8px 0 0 : ce
   n'est pas une derive, c'est la construction correcte d'une carte a en-tete. */
/* GESTE 8 — UNE COULEUR NE S'ATTRIBUE PAS PAR POSITION. Les trois filets
   venaient de nth-child(2) et nth-child(3) : la couleur dependait du rang de la
   carte dans le DOM, pas du metier qu'elle nomme. Trois couleurs pour trois
   metiers sans cle de lecture ne se deduisent nulle part -- c'est du decor.
   Unifiees en --bleu : le filet redevient un signe de famille et non un code
   qu'aucune legende n'explique. --ambre perd du meme coup son unique emploi de
   la page ; il reste declare pour l'alerte, ou il porte un sens. */
.carte-filet{height:4px;background:var(--bleu);border-radius:8px 8px 0 0}
.alt{background:var(--fond-alt)}

/* Second et dernier aplat de marque de la page. Volet categorie : ces chiffres
   portent des arguments, pas du chrome. Volet portee : deux aplats au plus. */
/* L'AIR SE RETIRE, IL NE SE DEPLACE PAS. La bande mesurait 315 px de haut a
   1440 pour 107 px de matiere -- 128 px de padding et 72 px entre la grille et
   la ligne d'action -- soit 5,2 % d'encre et 70 % de sa hauteur en bandes
   horizontales entierement vides. Une passe precedente avait tente de reprendre
   ce vide par `justify-content`, ce qui l'avait deplace de la droite vers le
   centre sans en retirer un pixel. Ici la surface diminue. */
.chiffres{padding:40px 0;background:var(--bleu);color:#fff}
.chiffres .conteneur{display:block}
.chiffres-grille{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
/* Le bandeau de chiffres portait une regle de bouton -- .chiffres .btn -- ecrite
   pour un bouton qui n'existait nulle part. Le point d'action y avait ete prevu
   puis oublie, et la page se retrouvait avec un seul bouton plein sur 4 296 px.
   Il porte l'AUTRE parcours du site, le compte gratuit, et non la demo : deux
   entonnoirs distincts valent mieux que le meme libelle repete trois fois. */
/* ⚠️ space-between RETIRE. Il ne supprimait pas le vide, il le deplacait :
   596 px de vide a droite devenaient 640 px de vide AU CENTRE, entre le bouton
   et la mention qui le qualifie -- 44 px de plus, et separant deux elements qui
   se lisent ensemble. Mesurer l'enveloppe d'un bloc ne dit rien de son
   occupation reelle : la bande rend 10,6 % d'encre sur sa surface. */
.chiffres-action{display:flex;flex-wrap:wrap;align-items:center;gap:14px 24px;
  margin:26px 0 0;padding-top:22px;border-top:1px solid rgba(255,255,255,.3)}
.chiffres-action span{font-size:14px;color:#fff}
/* Ces quatre nombres sont la matiere de la bande, pas sa legende : a 1440 chaque
   colonne leur offre 276 px et ils en occupaient 40 de haut. Le corps monte a 48,
   sous le H1 (64) qui doit rester la plus grande masse de la page. */
.chiffres strong{display:block;font-family:var(--police-titre);font-size:48px;font-weight:700;
  line-height:1.08;color:#fff}
.chiffres span{font-size:14px;color:#fff}
/* UNE DATE D'ORIGINE NE SE LIT PAS COMME UNE QUANTITE, ET LE TEXTE LE DISAIT DEJA.
   « Editeur français depuis » se termine par une preposition : la legende est une
   phrase ECRITE POUR APPELER le nombre. Posee sous lui, elle rendait « 2002. Editeur
   français depuis. », une preposition en l'air, et la cellule se lisait a l'envers de
   ce que sa propre copie demandait.
   La regle, et c'est une regle et non un compte : LEGENDE AU-DESSUS QUAND LE NOMBRE EST
   UNE DATE D'ORIGINE, legende en dessous quand c'est une quantite. Sur les 64 cellules
   du site, DEUX repondent au premier cas -- l'accueil et le developpement sur mesure,
   plus leurs jumelles anglaises. Les 62 autres sont des quantites et ne bougent pas :
   « 4 000+ » se lit bien avant « Entreprises clientes ».
   ⚠️ CE QU'ELLE REPARE AILLEURS : `.anciennete` de la bande de paroles est construite
   ainsi depuis le depart (« Client depuis » sur « 2017 »). Les deux objets etaient donc
   EN MIROIR sur la meme page, a 2 343 px l'un de l'autre, et aucune regle n'etait
   deductible de deux constructions opposees. Le « 2002 » du premier ecran rime
   desormais avec les millesimes des temoignages. */
/* ⚠️ 6,4 px ET NON 2, ET LA VALEUR EST MESUREE. A 2 px, la base du millesime tombait
   4,4 px AU-DESSUS de celle des legendes de quantite et 22 px sous celle des nombres :
   ni alignee sur les unes, ni sur les autres. La rangee passait de deux lignes
   d'alignement a quatre, dont deux se frolaient, et le decalage se lisait comme un
   ratage plutot que comme un pas. Le millesime partage desormais sa base avec les
   legendes : trois lignes, dont une commune.
   ⚠️ ET LA LEGENDE D'UNE DATE TIENT SUR UNE LIGNE. Sur deux lignes, l'ecart change de
   SIGNE -- +18 px au lieu de -4,4 -- et aucune marge unique ne rattrape les deux cas.
   C'est pourquoi celle du developpement sur mesure a ete raccourcie plutot que calee. */
.chiffres .origine span{display:block;margin-bottom:6.4px}
@media(max-width:1023px){}

/* Bandeau d'engagements. Les cinq logos ont des rapports allant de 1,00 a 3,19 :
   une hauteur imposee par logo, comme il en existait une, rogne les uns et ecrase
   les autres, et cesse de tenir des qu'un sixieme arrive. La boite est donc de
   taille fixe et l'image y est CONTENUE, jamais recadree. */
.certifs{padding:56px 0;border-top:1px solid var(--filet)}
.certifs h2{font-size:22px;line-height:1.3;margin-bottom:8px}
.certifs>.conteneur>p{color:var(--encre-douce);max-width:var(--mesure);margin-bottom:28px}
.certifs-liste{display:flex;flex-wrap:wrap;gap:16px}
/* LA BOITE MONTE DE 112x56 A 132x80, ET C'EST UN AUTRE CRITERE QUE CELUI D'AVANT.
   La decision precedente -- « boite plus basse, moins de blanc autour, heterogeneite
   assumee plutot que maquillee » -- repondait a un probleme de MASSE, et sur ce
   terrain elle avait raison : ni la taille, ni le detourage, ni la desaturation ne
   rendent homogenes cinq logos qui arrivent avec leurs fonds propres.
   Ce reglage-ci repond a un probleme de LISIBILITE, qui n'etait pas le critere.
   Deux des cinq rendaient 40x40 et 44x40 : le sceau du Privacy Protection Pact est
   un disque a texte circulaire, et France Num porte « ACTIVATEUR / FRANCE NUM » en
   deux lignes. A 40 px AUCUN DES DEUX NE SE LIT. Compares a 40, 56, 64 et 80 : ils
   deviennent lisibles a 56, confortables a 64. Un logo de certification qu'on ne
   peut pas lire ne certifie rien.

   ⚠️ ET C'EST LA BOITE QUI BLOQUAIT, CE QUI EXPLIQUE L'ECHEC DU GESTE 7 CI-DESSOUS.
   Il reglait la taille de chaque badge sur sa masse et trois des cinq ne bougeaient
   pas, « deja butes sur la boite ». Tant que la borne interne valait 92x40, un logo
   carre plafonnait a 40x40 en n'occupant que 43 % de la largeur offerte. Aucun
   reglage par logo ne pouvait aboutir ; il fallait relever la borne.

   132 ET NON 140, ET LA CONTRAINTE EST MESUREE. A 768 px la LISTE dispose de 728 px,
   pas les 768 du conteneur -- l'erreur a ete faite une fois. 5x140 + 4x16 = 764
   deborde et casse la rangee en deux lignes ; 5x132 + 4x16 = 724 tient. A 390 px on
   reste a trois lignes, comme avant, donc aucune regression.

   Effet de bord, mesure et favorable : le rapport de surface rendue passe de 2,13 a
   1,64, et le plus plat des cinq -- Alliance Digitale, rapport 3,19 -- monte de 29 a
   35,1 px. Le geste ne rouvre donc pas le grief d'homogeneite, il l'ameliore un peu
   en passant. */
.certif{background:var(--fond);border:1px solid var(--filet);border-radius:var(--rayon-s);
  width:132px;height:80px;padding:8px 10px;display:flex;align-items:center;justify-content:center}
/* BORNES ABSOLUES, ET NON DES POURCENTAGES. Dans une grille dont la ligne est
   auto-dimensionnee, un pourcentage de hauteur n'a pas de reference definie : il
   retombe sur la taille intrinseque, et deux des cinq logos sortaient de leur
   boite en rendant 116 px de haut dans une boite de 78. 118 x 54 = la boite moins
   ses marges internes. */
.certif img{max-width:112px;max-height:64px;width:auto;height:auto;
  object-fit:contain;display:block}

/* GESTE 7 — RETIRE, ET LA RAISON MERITE D'ETRE GARDEE.
   J'avais regle la taille de rendu de chaque badge sur sa masse d'encre. Trois des
   cinq regles redisaient mot pour mot les valeurs de base : elles ne faisaient
   rien, et c'etaient les EXTREMES -- Alliance Digitale au maximum, France Num et
   DMA au minimum, tous trois deja butes sur la boite. Seuls deux badges
   intermediaires ont bouge. J'ai donc reduit le milieu de la distribution en
   laissant ses bornes, ce qui l'a creusee : coefficient de variation de masse
   0,617 -> 0,762, rapport de surface rendue 2,13 -> 4,08. Le geste a fait le
   contraire de ce qu'il annoncait.

   Et le diagnostic etait faux des le depart. Le probleme n'est pas la masse :
   c'est que TROIS FONDS PLEINS ETRANGERS A LA PALETTE sont poses dans des cadres
   blancs. Alliance Digitale a ses quatre coins a rgb(30,30,28), France Num a
   rgb(52,44,93), Signal Spam a rgb(203,137,105). Aucun reglage de taille n'y peut
   rien, et le detourage non plus puisque ces fonds font partie des logos.

   La rangee cesse donc d'etre une composition pour devenir une ligne de bas de
   page : boite plus basse, moins de blanc autour, et l'heterogeneite assumee
   plutot que maquillee. */

/* Deux griefs anterieurs, tous deux traites par la boite normalisee ci-dessus.
   Les logos arrivent avec des fonds propres differents, dont un aplat sombre qui
   serait le seul objet noir de la page s'il etait pose a meme le fond ; la boite
   les neutralise sans detourage ni desaturation, ce qui evite de reproduire le
   grief d'origine, qui visait un opacity cumule a un saturate(0). Et des
   monogrammes dessines a la place des logos ont ete ecartes : sur une page dont
   la norme est la donnee reelle honnetement etiquetee, jusqu'a declarer RFC 5737,
   un sigle invente serait le seul objet a ne pas tenir ce standard. */

footer{background:var(--fond-alt);padding:64px 0 32px;border-top:1px solid var(--filet)}
footer .cols{display:grid;grid-template-columns:1.6fr repeat(3,1fr);gap:40px}
/* Le pied portait des h4 sous des h2 : un saut de niveau sur trois pages. Les balises
   passent en h3, et cette regle reproduit EXACTEMENT le rendu calcule du h4 -- Rubik 16
   / 600 / interligne 25,6 px / approche normale / marge basse 14. Les trois dernieres
   declarations ne sont pas decoratives : la regle globale `h1,h2,h3` pose une approche
   de -.014em, et `h3` pose 22 px, un interligne de 1,35 et une marge de 8. Sans elles,
   corriger la semantique aurait deplace le rendu. */
footer h3{font-family:var(--police-titre);font-size:16px;font-weight:600;
  color:var(--encre-titre);margin:0 0 14px;line-height:1.6;letter-spacing:normal}
footer ul{list-style:none;padding:0;display:grid;gap:9px;font-size:16px}
footer a{color:var(--encre-douce);text-decoration:none}
footer a:hover{color:var(--bleu-encre);text-decoration:underline}
.mentions{margin-top:48px;padding-top:24px;border-top:1px solid var(--filet);
  display:flex;justify-content:space-between;font-size:14px;color:var(--encre-douce)}

/* 32 px laissait le H1 a 3,8 % du premier ecran a 900 px de large pendant que la
   capture en occupait 57 % : un rapport de 15,6, quand le pire du benchmark
   concurrent est a 7,15. La hierarchie y etait inversee.
   56 px et non 52 : a 52 la marge sous le plafond de hauteur n'est que de deux
   points, trop mince pour un seuil. La serie 52/56/60 tient partout sous le
   plafond des 25 % du premier ecran -- 11,0 a 14,4 % selon la largeur. */
@media(max-width:1023px){
  section{padding:56px 0}
  /* .hero garde sa rampe : l'inclure ici la court-circuitait, et c'est ce qui
     rendait la respiration insensible a la hauteur de fenetre sur mobile. */
  /* 40 px laissaient l'encart 3 px sous le pli a 390x844. Trois pixels decident
     ici si le premier ecran mobile porte une signature ou n'en porte aucune.
     Meme raison pour les trois valeurs qui suivent. La charte demande la
     signature UNE FOIS au premier ecran, et le deficit se comptait en dizaines
     de pixels : 1 px a 414x736, 36 a 375x667, 38 a 414x680 -- mesures prises
     sur « 10 668 contacts » lui-meme, jamais sur le cadre qui l'entoure.
     Tout est repris sur des intervalles ; aucun contenu ne bouge. */
  .hero .conteneur{grid-template-columns:1fr;gap:14px}
  .preuve{margin-top:16px}
  .produit{gap:6px}
  .produit-encart{padding:10px 14px 12px}
  .grille-3,.grille-2{grid-template-columns:1fr}
  /* LE PIED A DEUX COLONNES : IL RESTE UN PIED, IL NE DEVIENT PAS UNE PAGE.
     Empile en quatre blocs pleine largeur, il mesurait 1 180 px a 390 px de fenetre
     -- 1,40 fenetre, 8,0 % du document -- pour 431 px en desktop. Un rapport de 2,7
     sur un objet dont le contenu est identique aux deux formats : c'est la definition
     meme du desktop empile. Trois colonnes de six liens de 16 px n'ont aucun besoin
     d'une largeur de 350 px ; le plus long libelle, « Developpement sur mesure »,
     tient dans 163 px.
     Le premier bloc garde la pleine largeur, et ce n'est pas un choix esthetique :
     il porte le bouton « Creer un compte gratuit », large de 199 px, qui deborderait
     une demi-colonne de 163 px a 390 et de 128 a 320.
     Mesure : 1 180 -> 884 px, soit 1,05 fenetre. */
  footer .cols{grid-template-columns:repeat(2,1fr);gap:32px 24px}
  footer .cols>div:first-child{grid-column:1/-1}
  /* Le pied suit le rythme vertical mobile comme toute autre section : 56 px de
     retrait haut, comme `section`, et non les 64 du desktop ; et 32 px avant les
     mentions, valeur de l'echelle, au lieu de 48. */
  footer{padding-top:56px}
  .mentions{margin-top:32px}
  .chiffres-grille{grid-template-columns:repeat(2,1fr);gap:32px}
  /* R3 : la nav etait masquee sans remplacement, donc AUCUNE navigation de
     320 a 1023 px, mesuree a 0 x 0 px. Elle repasse en barre defilante. */
  /* ⚠️ `header nav` ET NON `nav`. Ce bloc vise le menu principal, qui n'a pas de
     classe. Ecrit `nav`, il atteignait AUSSI le rail d'article `.nav-billets` et le
     sommaire lateral `.som-aside`, qui sont des <nav> eux aussi. Le rail y gagnait
     `overflow-x:auto`, le masque de bord, la bordure haute et le `nowrap` -- il se
     comportait donc en barre defilante, avec 759 px de titre dans une carte de 308,
     coupes net par le bord de l'ecran et sans points de suite.
     Le bloc ne servait meme plus sa cible : la nav d'en-tete se REPLIE depuis
     qu'on a prefere la parite des destinations au defilement, et ces regles sont
     surchargees plus bas. Elles n'agissaient donc plus que sur des passants. */
  header nav{gap:18px;overflow-x:auto;-webkit-overflow-scrolling:touch;
      order:3;width:100%;padding:14px 0 2px;border-top:1px solid var(--filet);margin-top:14px;
      /* S5 : 451 px de contenu dans 350 px de champ, sans indice de defilement.
         Degrade de bord droit tant qu'il reste quelque chose a voir. */
      scrollbar-width:none}
  header nav::-webkit-scrollbar{display:none}
  /* Le meme defaut que sur le comparatif, et la plus large des deux occurrences :
     ce degrade etait inconditionnel de 320 a 1023 px alors que la nav cesse de
     deborder des 516. Il effacait jusqu'a 32 px de « Qui sommes-nous » sur
     l'intervalle 516-547. Mesure : debord de 16 px a 500, 1 px a 515, 0 des 516. */
  @media(max-width:515px){
    header nav{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent);
        mask-image:linear-gradient(90deg,#000 calc(100% - 32px),transparent)}
  }
  header nav a{white-space:nowrap}
  header .conteneur{flex-wrap:wrap}
  /* LA NAVIGATION SE REPLIE AU LIEU DE DEFILER, ET C'EST LA PARITE DES DESTINATIONS.
     La barre defilante avait ete posee pour reparer une nav MASQUEE, ce qu'elle a
     fait. Restait le defaut residuel : 476 px de liens dans 350 px de champ a 390,
     soit 126 px hors champ, et « Qui sommes-nous » invisible. Le degre de bord dit
     qu'il y a autre chose, il ne dit pas quoi, et il faut un geste pour le savoir :
     quatre destinations sur cinq atteignables a la vue, contre cinq sur cinq en
     desktop. La charte nomme la parite des destinations entre menu desktop et menu
     mobile comme un point non couvert ; il l'est ici.
     Le corps ne pouvait pas payer : a 14 px -- le plancher de la charte -- la barre
     fait encore 401 px pour 350. Il fallait une seconde ligne.
     ⚠️ CE QU'ELLE COUTE, EN CLAIR, ET OU CA SE PAIE. Une seconde ligne vaut 26 px.
     L'air autour de la barre en rend la moitie : le rang etait separe par 14 px de
     marge PLUS 14 px de retrait au-dessus de son filet -- deux valeurs pour un seul
     intervalle -- et le retrait bas de 2 px ne separait rien du tout. Ramenes a 8, 8
     et 0, avec une gouttiere de rangee de 6, le solde est de +17 px d'en-tete sur les
     quatre pages -- 140 -> 157 a 390 px, mesure. Il se paie sur le premier ecran, et il faut le dire : l'encart de
     preuve de l'accueil descend d'autant. Il n'y etait deja plus -- mesure AVANT
     cette passe, il finissait 16 px sous le pli a 390x844, 31 a 360x800, 92 a 414x736,
     124 a 375x667 et 226 a 320x568, aux six formats testes. La regle du premier ecran
     est donc a rouvrir sur l'accueil, pour une cause qui lui est propre ; ce n'est pas
     une raison pour laisser une destination sur cinq hors du champ sur tout le site.
     ⚠️ SELECTEUR `header nav` ET NON `nav`. Les regles ecrites ici pour la barre
     d'en-tete fuient depuis toujours sur `.som-aside`, qui est un <nav> lui aussi.
     Le masque et le defilement se retirent donc en nommant l'en-tete, sinon on
     retire aussi ce que la colonne d'article avait deja du neutraliser a la main. */
  header nav{flex-wrap:wrap;row-gap:6px;overflow-x:visible;
    margin-top:8px;padding:8px 0 0;
    -webkit-mask-image:none;mask-image:none}
  /* LE RANG SE RESSERRE, IL N'AJOUTE PAS UNE RANGEE. A 320 px le rang
     logo + bouton demandait 281 px pour 280 disponibles -- un pixel -- et le
     bouton passait a la ligne : l'en-tete montait de 162 a 220 px, soit
     38,7 % d'un ecran de 568 px avant le premier mot. A 360 px il manquait
     6 px. L'ecart se prend sur l'intervalle et sur le flanc du bouton, pas
     sur la hauteur de la page. */
  header .conteneur{gap:14px}
  header .btn{padding:0 14px;font-size:15px}
  /* 18 px au-dessus et au-dessous d'un bouton de 44 px sont des valeurs de
     bureau. Sur un ecran de 667 px l'en-tete pesait 152 px, soit 23 % du premier
     ecran pour un logo, un bouton et une nav defilante. */
  header{padding:12px 0}
}
/* Le libelle unique du rendez-vous porte le rang a 285 px pour 280 disponibles a
   320 px : cinq pixels, et seulement sous 340. Le meme arbitrage qu'a la passe
   precedente, un cran plus bas et borne au seul format qui le demande, plutot que
   de rendre l'en-tete a deux rangs et 188 px sur un ecran de 568. */
@media(max-width:339px){
  header .conteneur{gap:10px}
  header .btn{padding:0 12px}

  h2{font-size:24px}
  /* Cette regle redisait simplement font-size:var(--h1) et, a specificite egale
     mais plus loin dans la feuille, elle ecrasait la formule continue du H1. */
}
@media(max-width:767px){
  /* Le bandeau repasse a une ligne : a 390 px il montait a 87 px, soit 10 % du
     premier ecran pour une barre de contact, avec "1 000" coupe entre deux lignes. */
  /* 43 px de barre pour un numero de telephone : les deux autres mentions sont
     deja masquees a cette largeur, la respiration peut suivre. */
  .bandeau{padding:7px 0}
  /* ⚠️ LE TROISIEME SPAN SURVIT, ET C'EST UN CHEMIN D'ACCES, PAS UNE MENTION.
     `:not(:first-child)` masquait les deux autres. Depuis que le troisieme porte le
     lien vers /compte-gratuit/, cette regle eteignait SOUS 768 PX LA SEULE ENTREE
     SITE-WIDE vers la page : sur /tarifs/ a 390, le seul chemin restant etait le
     bouton du pied, a 7,7 ecrans. Un chemin d'acces qui n'existe pas sur la moitie
     du trafic n'est pas un chemin d'acces. C'est donc le DEUXIEME span, l'email --
     une mention, doublee par le pied -- qui se masque seul.
     La mention longue tombe avec lui : « Compte gratuit » rend 99 px et le numero
     120, pour 350 px utiles a 390. Les deux tiennent sur une ligne, et la barre
     reste a 37 px -- les 87 px que la regle d'origine evitait ne reviennent pas. */
  .bandeau .conteneur{gap:16px}
  .bandeau .conteneur>span:nth-child(2){display:none}
  .bandeau-long{display:none}
  .certifs .conteneur{gap:20px 32px;justify-content:flex-start}
}
/* 32 px et non 36 : deux regles de la charte se rencontrent ici et la plus
   contraignante l'emporte. Relever le H1 restaure la hierarchie, mais le plafond
   de 3 lignes vaut a TOUTES les largeurs. Mesure a 390 px : 30 et 32 px tiennent
   en 3 lignes, 34 et 36 passent a 4. 32 px est donc la plus grande valeur
   conforme -- et reste un relevement, puisque le palier etait a 28 px. */
@media(max-width:479px){
  /* Troisieme palier : a 320 px, 32 px donnait encore 4 lignes. Le plafond de
     3 lignes vaut a TOUTES les largeurs, pas seulement au-dela de 1024 px. */
  
  /* La ligne de preuves passait sur deux lignes et laissait sa puce orpheline. */
  .preuve{display:grid;gap:8px;justify-items:start}
  .preuve .puce{display:none}
  .hero .btn,footer .btn{width:100%;justify-content:center}   /* pas le bouton d'en-tete */
}
/* FENETRE COURTE. Le CTA doit rester au-dessus du pli, et c'est une contrainte de
   hauteur qu'aucune requete de largeur ne voit. A 568 px de haut, l'empilement
   barre + en-tete + surtitre + H1 + chapo + appui poussait le bouton 153 px sous
   le pli. On reprend la respiration du hero et on retire la ligne d'appui, dont
   la ligne de preuves sous le CTA porte deja l'essentiel. */
/* Deux paliers, et on ne retire du contenu qu'au second. Le premier reprend de la
   respiration, ce qui ne coute rien ; le second masque la ligne d'appui, dont la
   ligne de preuves sous le CTA porte deja l'essentiel. */
@media(max-height:800px){
  /* remplace par la respiration continue posee sur .hero */
  /* Sur une fenetre courte, le centrage vertical se retourne : l'image devient
     plus haute que la colonne de texte et pousse le CTA sous le pli. */
  .hero .conteneur{align-items:start}
}
/* ⚠️ LE SEUIL EST SUPPRIME, PAS DEPLACE. Il masquait la ligne d'appui et
   compactait trois marges d'un coup : franchir 820 -> 824 px de hauteur coutait
   108 px de marge quand le pli n'en gagnait que 4, et le seuil de largeur 520 en
   creait un second -- 520x680 rendait -9, 540x680 rendait -103. Sur 506 formats
   balayes, 169 echouaient. Deplacer le seuil de 720 a 820 n'avait fait que
   deplacer la falaise : LE SEUIL A BOUGE, LA METHODE DE VERIFICATION NON.

   Les marges du hero se compactent donc en continu avec la hauteur de fenetre,
   et la ligne d'appui n'est plus masquee : un contenu qui apparait et disparait
   ne peut pas se compacter continument, il fait toujours une marche. */
.hero .surtitre{margin-bottom:clamp(4px, calc(2.4vh - 12px), 12px)}
.hero h1{margin-bottom:clamp(10px, calc(5vh - 26px), 24px)}
.hero .chapo{margin-bottom:clamp(8px, calc(3.2vh - 14px), 16px)}
.hero .appui{margin-bottom:clamp(8px, calc(3.2vh - 14px), 16px)}

/* La ligne d'appui reste masquee sous 640 px de haut, et la seule raison est que
   LE CTA passe sinon sous le pli a 320x568. Le seuil est place la ou l'encart de
   signature echoue DEJA des deux cotes : il ne cree donc aucune marche visible
   dans la zone ou la mesure passe. Un seuil pose dans une region qui echoue de
   toute facon ne se voit pas ; c'est la seule place acceptable pour un seuil. */
@media(max-height:640px){
  .hero .appui{display:none}
}
/* Sous 375 px, la fenetre se resserre a y 70 -> 300 : le bandeau d'etapes seul.
   Hauteur : 230 x 760 / 1794 = 98 px. */
@media(max-width:374px){
  .produit-cadre{height:98px}
}

@media(prefers-reduced-motion:reduce){
  /* ⚠️ LE DELAI AUSSI, PAS SEULEMENT LA DUREE. La regle ne coupait que
     `transition-duration`, ce qui suffisait tant qu'aucune declaration n'avait de
     delai. Le menu deroulant en introduit deux -- `visibility 0s 200ms`, qui retarde
     le passage a `hidden` le temps du fondu. Duree a zero mais delai intact, le
     panneau restait 200 ms invisible ET present dans l'arbre d'accessibilite.
     Verifie : ce sont les deux seules declarations a delai de la feuille, donc la
     ligne ne deplace rien d'autre. */
  *,*::before,*::after{transition-duration:0ms!important;transition-delay:0ms!important;
    animation-duration:0ms!important}
}

/* ------------------------------------------------------------------
   Formulaire. Un seul emploi sur le site, /contact/.
   ------------------------------------------------------------------ */
/* ⚠️ CE COMPOSANT N'EST PAS CONCU ICI, IL EST IMPLEMENTE. La charte le specifiait
   deja -- bordure `--bordure-composant`, rayon `--rayon-s`, hauteur 44 px,
   remplissage `0 14px`, corps 16 px, anneau de focus, et en erreur une bordure
   `--erreur` AVEC un message, jamais la couleur seule. La feuille, elle, n'avait
   aucune regle : zero occurrence de `input`, `label`, `textarea` ou `form`.
   La charte parle d'un jeton `--focus-epaisseur` QUI N'EXISTE PAS dans la feuille ;
   la convention reellement en vigueur, ligne 56, est `outline:2px solid var(--focus)`
   avec un decalage de 2. C'est elle qui est suivie, et l'ecart est signale.

   Quatre choses que la charte ne disait pas et qu'il a fallu poser : l'etiquette,
   le `textarea`, l'ecart entre champs, et le message d'aide. */
/* ⚠️ LE COMPOSANT PORTE SA PROPRE MESURE, ET C'EST LA CORRECTION D'UN DEFAUT REEL.
   Sur /contact/ le formulaire rend 696 px parce qu'il vit dans `.pourquoi`, la grille
   a deux pistes : c'est le CADRE qui le mesurait, pas lui. Porte sur /compte-gratuit/
   dans une section a une seule piste, le meme composant s'est etale a 1 160 px, avec
   des demi-champs a 568. Mesure : un champ « Entreprise » de 1 160 px pour un contenu
   dont la chasse fait 217 px en Inter 16, RAPPORT 5,3. La largeur du champ ne disait
   plus rien de la donnee qu'il attend.

   J'avais retire `.pourquoi` de cette section pour supprimer une colonne vide que
   `recette-pilote.mjs` venait de signaler -- et j'ai corrige un defaut en en creant un
   autre, que ce garde-la ne voit pas. La lecon n'est pas la largeur : UN COMPOSANT QUI
   DEPEND DE SON CADRE POUR ETRE BIEN PROPORTIONNE CASSE AU PREMIER DEPLACEMENT. 696 px
   est ici la valeur de /contact/, ou elle est jugee juste ; elle n'y change rien
   puisque la grille l'y donne deja. */
.formulaire{display:grid;grid-template-columns:1fr 1fr;gap:18px 24px;margin:0;
  max-width:696px}
.champ{display:flex;flex-direction:column;min-width:0}
/* Un champ qui court sur les deux pistes : entreprise et message. */
.champ-large{grid-column:1/-1}
/* ⚠️ L'ETIQUETTE EST VISIBLE, TOUJOURS, ET JAMAIS REMPLACEE PAR UN PLACEHOLDER.
   Un placeholder disparait a la saisie : sur six champs, le lecteur relit un
   formulaire dont les champs n'ont plus de nom. */
.champ label{font-size:14px;font-weight:500;color:var(--encre-titre);margin-bottom:6px}
.champ label .requis{color:var(--erreur);margin-left:2px}
.champ input,.champ textarea{width:100%;font-family:var(--police-corps);font-size:16px;
  color:var(--encre);background:var(--fond);border:1px solid var(--bordure-composant);
  border-radius:var(--rayon-s);transition:border-color 150ms}
.champ input{height:44px;padding:0 14px}
/* Le `textarea` suit le champ pour tout sauf la hauteur : 44 px n'a pas de sens pour
   un message. Quatre lignes.
   ⚠️ CE COMMENTAIRE A AFFIRME LE FAUX. Il disait que quatre lignes etaient « la
   valeur mesuree par le directeur artistique comme celle qui garde le bouton d'envoi
   au-dessus du pli a 1440 ». Le bouton tombe a y=1034 pour un pli de 1000, et il n'y
   a jamais ete : le prototype qui avait servi a l'annonce comptait `.entete-appui`
   sur deux lignes quand la production en fait trois, et prenait un rythme de section
   de 48 px -- la derogation de `.plans` -- la ou `.pourquoi` herite des 96 px de
   `section`. La valeur reste bonne pour la raison qui la justifie vraiment, le
   calibre d'un champ de message ; elle n'a jamais eu de rapport avec le pli.
   Et le pli n'est pas le bon objet ici : sur un formulaire, ce qui doit y etre est
   le PREMIER CHAMP, qu'on remplit, pas le bouton, qu'on trouve en remplissant.
   `#nom` est a y=625, soit 375 px au-dessus. */
.champ textarea{padding:11px 14px;line-height:1.5;min-height:118px;resize:vertical}
.champ input:hover,.champ textarea:hover{border-color:var(--encre-douce)}
.champ input:focus-visible,.champ textarea:focus-visible{border-color:var(--bleu);
  outline:2px solid var(--focus);outline-offset:2px}
/* En erreur, la bordure ET le message. La couleur seule ne porte jamais
   l'information : c'est un interdit nomme de la charte. */
.champ-erreur input,.champ-erreur textarea{border-color:var(--erreur)}
.champ-message{margin:6px 0 0;font-size:14px;color:var(--erreur)}
.form-aide{margin:4px 0 0;font-size:14px;color:var(--encre-douce)}
.form-pied{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:16px 24px}
.form-pied .btn{flex:none}
.form-legende{margin:16px 0 0;font-size:14px;color:var(--encre-douce);max-width:var(--mesure)}
.form-legende a{color:var(--bleu-encre)}
/* Le pot de miel n'est pas `display:none` : certains robots ignorent les champs
   masques ainsi. Il sort du champ visuel en restant dans le flux du document. */
.pot-de-miel{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* NAVIGATION ENTRE ARTICLES, PRECEDENT ET SUIVANT.
   Reprise de la production, qui en sert une chronologique et INTER-CATEGORIES : sur
   l'article releve, le precedent est dans email-marketing-b2b et le suivant dans
   technique. Elle ne double donc pas « Articles sur le meme theme », qui reste dans la
   categorie -- l'une propose de continuer a lire, l'autre de creuser le sujet.

   ⚠️ DEUX PISTES MEME QUAND UNE SEULE EST REMPLIE. Le gabarit rend un <span> vide a la
   place du precedent manquant : sans lui, le premier article du site pousserait son
   « Suivant » a gauche, la ou tous les autres l'ont a droite. Une navigation dont la
   position change d'une page a l'autre ne se lit plus, elle se cherche. */
.nav-billets>.conteneur{display:grid;grid-template-columns:1fr 1fr;gap:24px;
  padding-top:32px;padding-bottom:64px;border-top:1px solid var(--filet)}
/* ⚠️ `min-width:0` OU LA GRILLE DEBORDE. Un enfant de grille garde `min-width:auto` :
   sa piste ne descend jamais sous la largeur de son contenu le plus large. Un titre
   d'article de 70 signes elargit donc la piste, la grille, et la page -- mesure a
   390 px : 749 px de conteneur pour 390 de fenetre, 396 px de debord. Meme faute que
   celle deja corrigee sur les tableaux de `.pourquoi`. */
.nav-billet{min-width:0;display:flex;flex-direction:column;gap:6px;padding:16px 20px;
  border:1px solid var(--filet);border-radius:var(--rayon-s);background:var(--fond);
  text-decoration:none;transition:border-color 150ms}
.nav-billet:hover{border-color:var(--encre-douce)}
/* ⚠️ `.nav-prec` PORTE SA REGLE MEME SI ELLE VAUT LE DEFAUT, et le garde des classes
   l'a exige : une classe presente dans le balisage sans aucune regle est soit du
   balisage mort, soit une regle oubliee -- il ne sait pas distinguer les deux, et il a
   raison de refuser. Ecrite, elle dit aussi que les deux sens forment une paire. */
.nav-prec{text-align:left}
.nav-suiv{text-align:right}
.nav-sens{font-size:14px;font-weight:600;color:var(--bleu-encre);
  letter-spacing:.02em;text-transform:uppercase}
.nav-titre{font-size:16px;font-weight:500;color:var(--encre-titre);line-height:1.35}
/* Sous 600 px la grille passe a une piste : deux titres cote a cote y tiendraient sur
   150 px chacun, sous la largeur ou un titre d'article cesse d'etre lisible. */
@media(max-width:599px){
  .nav-billets>.conteneur{grid-template-columns:1fr;padding-bottom:48px}
  .nav-suiv{text-align:left}
}

/* CADRE D'UN FORMULAIRE TIERS, INJECTE PAR SON PROPRE SCRIPT.
   Deux prestataires, deux formes : Beacon injecte un <form> dans la page et se
   dimensionne seul ; mdworks injecte une <iframe> et la REDIMENSIONNE au fil du
   contenu -- mesure a 520 px, le cadre rend 821, ni la valeur posee ici ni celle de
   la media query.

   ⚠️ J'AI D'ABORD ECRIT L'INVERSE ICI. Le commentaire affirmait qu'une iframe
   inter-domaine « ne sait pas dire sa hauteur, il faut donc la lui donner ». C'est
   vrai d'une iframe nue, faux de celle-ci : son script la mesure et la corrige. Les
   deux valeurs ci-dessous ne sont donc pas la hauteur finale, ce sont les hauteurs
   D'AMORCE, avant que le script ne prenne la main -- elles evitent un saut de mise en
   page au chargement, rien de plus. Elles restent calees sur la mesure : 401 a 440 px
   de contenu en deux colonnes au-dessus de 500 px, 811 empile en dessous, la bascule
   etant a 500 px exactement. Verifie ensuite a cinq largeurs sur les deux pages : le
   contenu s'arrete toujours 10 px avant le bas du cadre, aucun bouton n'est coupe. */
.cadre-tiers{max-width:1090px;margin:0 auto}
.cadre-tiers iframe{display:block;width:100%;height:460px;border:0}
@media(max-width:499px){ .cadre-tiers iframe{height:840px} }

/* LE RAIL D'ETAPES. Meme typographie que `.normes` -- surtitre 14/600 en capitales,
   terme 18/500, glose 14/400 -- mais PAS la meme classe, et c'est deliberé :
   `libelles-normes.mjs` compte les `.normes>p` servis et les compare au vocabulaire
   ferme de cinq termes du depot. Un rail d'etapes coiffe de « Comment ça fonctionne ? »
   aurait fait diverger les deux comptes et casse un garde qui n'a rien a voir avec lui.
   Un objet qui n'obeit pas aux memes regles ne prend pas le meme nom.

   ⚠️ PAS DE `position:sticky` ICI, CONTRAIREMENT A `.normes` ET `.coordonnees`, ET LA
   MESURE A TRANCHE PLUTOT QUE LA PRUDENCE. Une colonne collante plus haute que la
   hauteur utile (`innerHeight - 105 - 24`) a son bas coupe et inatteignable. Essai fait,
   collage pose : le rail rend 512 px, et A 1024x600 IL NE RESTE QUE 471 PX UTILES --
   les quatre etapes ne sont plus atteignables sur une fenetre de portable ou un demi-
   ecran. Ca passe a 1024x768, 1440x700 et au-dela.
   ⚠️ ET `recette-pilote.mjs` N'A RIEN VU : il rend 7 formats sur 7 avec le collage en
   place, parce qu'il ne teste pas 1024x600. Le garde ne couvre pas ce cas.
   `align-self:start` suffit : le rail est plus court que le formulaire qu'il accompagne. */
.etapes{border-left:3px solid var(--bleu);padding-left:20px;align-self:start}
.etapes>p{margin:0 0 12px;font-size:14px;color:var(--encre-douce);letter-spacing:.02em;
  text-transform:uppercase;font-weight:600}
.etapes ol{list-style:none;margin:0;padding:0}
.etapes li{font-size:18px;font-weight:500;color:var(--encre-titre);margin-bottom:16px;
  line-height:1.35}
.etapes li:last-child{margin-bottom:0}
.etapes li span{display:block;margin-top:2px;font-size:14px;font-weight:400;
  color:var(--encre-douce);line-height:1.5}
.etapes a{color:var(--bleu-encre)}

/* GROUPE DE CHOIX. Le seul champ du site dont l'etiquette est un <legend> et non un
   <label> : cinq boutons radio partagent une question, et un <label> ne peut pas
   nommer cinq controles a la fois. Le lecteur d'ecran annonce alors la question avant
   chaque option, ce qu'un <label> orphelin ne fait pas.

   ⚠️ BOUTONS RADIO ET NON LISTE DEROULANTE, comme l'original. Une liste deroulante
   aurait tenu dans la grille a deux pistes sans rien ajouter, mais elle CACHE les
   options : sur une echelle de volume, ce sont les bornes qui informent -- « moins de
   1 000 » et « plus de 50 000 » disent au visiteur ou il se situe avant meme qu'il
   reponde. Un <select> lui demande de deviner l'echelle pour la trouver.

   L'anneau de focus est pose sur le bouton natif et non sur l'etiquette : c'est le
   bouton qui recoit le focus au clavier, l'etiquette ne fait que l'etendre au clic. */
.champ-choix{grid-column:1/-1;min-width:0;border:0;margin:0;padding:0}
.champ-choix legend{padding:0;font-size:14px;font-weight:500;color:var(--encre-titre);
  margin-bottom:10px}
.champ-choix legend .requis{color:var(--erreur);margin-left:2px}
/* ⚠️ UNE OPTION PAR LIGNE, ET C'EST UNE COMPOSITION, PAS UN REPLI.
   J'avais laisse `flex-wrap` decider : l'echelle rendait alors 5 sur une ligne a
   1 160 px de cadre, 4+1 a 768 avec « Plus de 50 000 » orphelin, 2+2+1 a 390, 5
   empiles a 320. Quatre etats, aucun choisi -- et des que le formulaire est revenu a
   sa mesure de 696 px, l'orphelin de 768 s'est etendu a TOUTES les largeurs.

   La mesure ferme la question : les cinq etiquettes pesent 707,1 px A ELLES SEULES
   pour 696 px de piste. Elles ne tiennent sur une ligne A AUCUNE GOUTTIERE, et cinq
   colonnes egales donneraient 120 px la ou « 20 000 a 50 000 » en demande 153.
   Il n'existait pas de bonne sortie en ligne.

   Une echelle ordinale se lit donc verticalement, ou chaque cran occupe le meme rang
   et l'ordre se voit. Le meme traitement va au groupe « Usage principal », qui tient
   pourtant en ligne : deux dispositions pour un meme controle dans un meme formulaire
   demanderaient au lecteur de deduire une regle qui n'existe pas. Et la disposition
   ne depend plus de la largeur -- elle est IDENTIQUE de 320 a 1920. */
.choix{display:grid;gap:12px}
.choix label{display:inline-flex;align-items:center;gap:8px;font-size:16px;
  color:var(--encre);cursor:pointer}
.choix input{width:18px;height:18px;margin:0;flex:none;accent-color:var(--bleu)}
.choix input:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

@media(max-width:600px){
  /* Une seule piste sous 600 : deux champs de 44 px cote a cote y font 138 px de
     large, sous les 200 px ou une adresse email cesse d'etre relisable. */
  .formulaire{grid-template-columns:1fr}
}

/* ------------------------------------------------------------------
   Composants de page interieure : en-tete, plans tarifaires, tableau
   comparatif, questions frequentes.
   ------------------------------------------------------------------ */
/* RYTHME DE L'EN-TETE RESSERRE, 72/56 -> 48/32. Il consommait 246 px pour 101 px de
   texte, suivis de 134 px de blanc avant la premiere carte : 380 px de preambule pour
   un objet, le prix, qui etait deja le bon. Le premier CTA tombait a y 1 040 pour un pli
   a 1 000, et 272 px sous le pli en 1366x768. */
.entete-page{padding:48px 0 32px;border-bottom:1px solid var(--filet)}
.entete-page h1{font-size:36px;line-height:1.2;letter-spacing:-.011em;margin-bottom:16px}
.entete-page p{font-size:18px;color:var(--encre-douce);max-width:var(--mesure)}

/* LES GARANTIES SONT COMPOSEES, PLUS SEULEMENT ECRITES. Comptees dans le texte rendu :
   « engagement » 3 fois, « expir- » 4, « palier » 5, « IP dediee » 8. Les trois memes
   garanties etaient enoncees quatre a cinq fois chacune, et PAS UNE n'etait composee --
   toutes en Inter 18, 16 ou 14 px, gris ou gras, noyees dans des paragraphes. La page
   les repetait au lieu de les poser.
   L'anaphore etait deja ecrite dans le chapo ; on lui ajoute la quatrieme clause et on
   la sort du paragraphe. Une clause par ligne A TOUS LES FORMATS : en flux inline le
   meme texte rend 5 lignes a 390 px contre 4 en colonne, et l'anaphore ne se lit plus.
   C'est ce qui met au pli le seul argument que la page possede en propre -- son premier
   ecran ne portait ni action ni signature, surface coloree 0,5 %, quinze fois moins que
   l'accueil. */
.entete-page .entete-clauses{font-family:var(--police-titre);font-weight:600;
  font-size:min(22px, 6.1vw);line-height:1.32;letter-spacing:-.011em;
  color:var(--encre-titre);margin:0 0 14px;max-width:none}
.entete-clauses span{display:block}
.entete-page .entete-appui{margin:0}
/* ⚠️ `margin:0` A ETE ECRIT POUR UN SEUL PARAGRAPHE D'APPUI, et le moule n'en a
   qu'un. /qui-sommes-nous/ en porte trois : ils rendaient 460,7 px de gris et douze
   lignes sans un seul interparagraphe. La regle ne nomme que le cas de plusieurs,
   donc aucune page existante ne bouge. */
.entete-page p + p{margin-top:14px}

/* EN-TETE EN DUO. Employe sur /contact/ et sur elle seule, d'ou le modificateur :
   la regle ne touche aucune des dix-neuf autres pages.
   ⚠️ POURQUOI. « Contactez-nous » fait deux mots la ou le H1 de tarifs en a huit :
   l'entete empile laissait 640 x 328 px de blanc a droite, et la pile de clauses --
   le seul objet de signature de la page -- y flottait au lieu d'etre ancree. Mise en
   colonne de gauche d'une composition, elle devient un objet.
   La montee de corps de 22 a 26 px est ce qui separe « un bloc mieux place » de « un
   objet » : sans elle le geste ne vaut que la moitie de son prix. */
.entete-duo .entete-rang{display:grid;grid-template-columns:1fr 1fr;gap:64px;
  align-items:start}
@media(min-width:1024px){
  /* ⚠️ LA MONTEE EST STRICTEMENT DESKTOP, ET CE N'EST PAS UN CONFORT. A 390 px la
     pile est deja a 22 px dans une mesure de 350, ou « 4 000+ entreprises
     clientes. » rend 303,8 px pour 350 disponibles. Toute augmentation au mobile
     casserait les trois lignes et detruirait exactement ce que la passe valide.
     Le `min(22px, 6.1vw)` du cas general reste donc intact sous 1024. */
  .entete-duo .entete-clauses{font-size:26px}
}
@media(max-width:1023px){
  /* Sous 1024 la grille se defait : deux colonnes de 350 px n'existent pas. */
  .entete-duo .entete-rang{display:block}
  .entete-duo .entete-appui{margin-top:14px}
}
.plans{padding:32px 0 48px}
/* LES RANGEES PARTAGEES LE SONT VRAIMENT. Les trois cartes portent les memes neuf
   rangees -- badge, nom, quota, prix, quota, liste, infrastructure, action, note --
   mais chacune etait une grille independante : leurs listes se replient
   differemment (le premier item de PRO fait 51 px, ceux de PREMIUM 26), et l'ecart
   se propageait aux rangees suivantes. Mesure : 25 px sur .plan-infra de 1120 a
   1920, et 116 px a 1024, ou AGENCE replie trois items sur deux lignes.
   La specification 6 de la charte l'interdit deja ; elle avait ete ecrite pour le
   badge et jamais portee au bas de carte.
   subgrid fait descendre les rangees du conteneur dans les cartes : une rangee
   vaut alors le plus haut de ses trois contenus, pour les trois a la fois.
   L'ecart des colonnes reste a 24, celui des rangees passe a 20 -- c'est
   l'intervalle interne des cartes, le conteneur n'ayant qu'une rangee de cartes. */
/* Gouttiere de RANGEE ramenee de 20 a 12 px. Elle separe les dix rangees du subgrid,
   donc SEPT d'entre elles passent au-dessus du bouton : a 20 px elle y posait 140 px, a
   elle seule le quart du chemin entre le haut de la carte et l'action. Elle avait ete
   reglee quand l'en-tete etait plus aere ; le resserrement de l'en-tete la laissait en
   decalage. La gouttiere de COLONNE ne bouge pas. */
.plans .conteneur{display:grid;grid-template-columns:repeat(3,1fr);gap:12px 24px;
  grid-template-rows:repeat(10,auto)}
.plans .plan{display:grid;grid-template-rows:subgrid;grid-row:span 10}
/* Le padding haut cede 20 px a l'intervalle de rangee que subgrid pose sous le
   filet : 8 + 20 = les 28 px d'origine au-dessus du badge. */
.plans .plan-corps{grid-row:span 9;display:grid;grid-template-rows:subgrid;
  padding:8px 28px 28px}
.plan{background:var(--fond);border:1px solid var(--bordure-composant);
  border-radius:var(--rayon-m);overflow:hidden;display:grid}
.plan-filet{height:4px;background:var(--filet)}
.plan--mis .plan-filet{background:var(--bleu)}
.plan--mis{border-color:var(--bleu)}
.plan-corps{padding:28px;display:grid;gap:20px;align-content:start}
.plan h2{font-size:22px;font-weight:600;color:var(--encre-titre);margin:0}
.plan-badge{font-size:14px;font-weight:600;color:var(--bleu-encre);
  min-height:22px;display:block}
/* ⚠️ L'ESPACE DE RESERVE N'A DE SENS QU'EN COLONNES. Il aligne les trois cartes
   quand elles sont cote a cote ; empilees, il n'aligne plus rien et ajoute 42 px
   de vide en tete des cartes PRO et AGENCE -- assez pour faire sortir le premier
   prix du premier ecran a 320 px. Sur une page de tarifs, c'est le defaut le plus
   cher pour le geste le moins cher. */
@media(min-width:1024px){
  .plan-badge:empty::before{content:"\00a0"}
}
/* Empilees, les cartes n'ont plus rien a aligner : le badge vide disparait au lieu
   de reserver sa place, et la gouttiere de la grille avec lui. */
@media(max-width:1023px){
  .plan-badge:empty{display:none}
}
/* LE PRIX EST L'OBJET D'AFFICHAGE D'UNE PAGE DE TARIFS, et il ne l'etait pas.
   Masse d'encre floutee a 1440, boites serrees : « Sur devis » 2 458, « 198 € »
   1 601, « 98 € » 1 353 -- soit 12 a 23 % du H1. Le seul intitule qui REFUSE
   d'annoncer un prix pesait 1,82 fois le prix d'entree. A trois metres, la page
   disait « sur devis ».
   56 px et non 64 : a 64 px « Sur devis » rend 293,8 px pour 294 px de carte a
   390 -- un pixel de marge. */
.prix{font-family:var(--police-titre);font-size:56px;font-weight:700;line-height:1;
  color:var(--encre-titre)}
/* Le qualificatif passe SOUS le nombre : en ligne, un small de 16 px accole a un
   nombre de 56 px se lit comme une unite du nombre, pas comme sa periode. */
.prix small{display:block;font-family:var(--police-corps);font-size:14px;font-weight:400;
  color:var(--encre-douce);letter-spacing:0;margin:6px 0 0}
/* « Sur devis » N'EST PAS UN PRIX, il ne se compose donc pas comme un. 22 px est
   l'echelon H3 de l'echelle ; 24 n'en est pas un. */
.prix--devis{font-size:22px;font-weight:600;color:var(--encre-douce)}
/* Palier : a 320 px, « 198 € par mois » a 56 px passe sur deux lignes. */
@media(max-width:359px){
  /* ⚠️ L'INSECABLE DE « 4 000+ » A CREE UN DEBORDEMENT, et il fallait le payer ici.
     A 320 px la colonne fait 138 px et la chaine en rend 170 a 48 px : le document
     debordait de 40 px, ce qui cassait l'acquis « zero debordement de 320 a 1920 ».
     48 x 138/170 = 39 ; 38 laisse une marge. Borne au SEUL palier ou le debord existe :
     a 360 px la meme chaine passe deja. */
  .chiffres strong{font-size:38px}

  .prix{font-size:40px}
}
.quota{font-size:16px;color:var(--encre-douce)}
/* align-content:start : la liste s'etire desormais a la rangee partagee, et une
   grille etiree REDISTRIBUE son surplus entre ses rangees. Mesure : PREMIUM
   espacait ses items de 42 px contre 35,6 px chez ses voisines, et a 1024 les
   trois rythmes valaient 67,6 / 48,4 / 61,2. Les cartes etaient alignees, leurs
   listes ne l'etaient plus. Le surplus va au bas de la rangee. */
.plan ul{list-style:none;padding:0;margin:0;display:grid;gap:10px;font-size:16px;
  align-content:start}
.plan li{display:grid;grid-template-columns:20px 1fr;gap:10px;align-items:start}
.plan li svg{width:16px;height:16px;margin-top:4px}
.plan-infra{border-top:1px solid var(--filet);padding-top:16px;display:grid;gap:4px}
.plan-infra b{font-family:var(--police-donnee);font-size:16px;font-weight:500;
  letter-spacing:.02em;color:var(--encre-titre)}
.plan-infra span{font-size:14px;color:var(--encre-douce)}
.plan-infra--nu span{line-height:1.5}
.plan-infra--nu strong{color:var(--encre);font-weight:600}
/* .plan-note etait employee trois fois SANS AUCUNE REGLE : elle retombait sur le p
   par defaut, 16 px en --encre pleine et sans marge, donc rendue plus lourde que
   le .quota gris qui la surplombe. Trouvee par un controle de classes orphelines,
   que la garde des jetons ne faisait pas -- elle verifie les valeurs declarees,
   pas les classes sans regle. */
.plan-note{margin:14px 0 0;font-size:14px;color:var(--encre-douce)}
.plan .btn{width:100%;justify-content:center}
.compare{padding:0 0 72px}
/* CE ZERO SUPPOSE QUE LA BANDE PARTAGE SON FOND AVEC CELLE QUI LA PRECEDE. Il est
   la pour coller le comparatif a la section qui l'introduit, et tant que les deux
   sont blanches personne ne le voit. Des que la bande porte `alt`, le meme zero
   colle le H2 au bord haut du gris : la couleur change pile sur la ligne de
   capitales, sans respiration, et la bande n'a plus d'entree. La page plateforme
   est la premiere a poser un comparatif sur gris -- il fallait rompre 1 688 px de
   blanc continu -- donc la premiere a en avoir besoin. */
.compare.alt{padding-top:96px}
/* LE CHAMP DE DEFILEMENT N'EST PAS LE CHAMP DE MISE EN PAGE. overflow-x et son
   masque etaient poses sur .compare .conteneur, qui porte trois enfants -- le H2,
   la table et .apres-table avec son bouton -- dont UN SEUL deborde. Le masque
   blanchissait donc le second bouton d'action jusqu'a 62,8 % d'opacite sur toute
   la plage 320-479 px, la ou .apres-table .btn{width:100%} le pousse au bord ; et
   le H2 n'y echappait que de 3 px.
   Nommer le bouton pour l'exclure marcherait aujourd'hui et casserait au prochain
   enfant ajoute : c'est une regle attribuee par position dans le DOM plutot que
   par ce qu'elle habille. La table recoit son propre champ, et les deux autres en
   sortent par construction. */
.compare-champ{overflow-x:auto}
.compare table{min-width:640px}
/* LE MASQUE NE SE POSE QUE LA OU IL Y A QUELQUE CHOSE A REVELER. Il etait
   inconditionnel : a 1440 le contenu fait 1 200 px dans un champ de 1 200, rien ne
   defile, et il blanchissait quand meme les 12 derniers pixels -- du filet ici, et
   du second bouton d'action sur la page plateforme.
   ⚠️ SEUIL A 679, ET MES DEUX PREMIERES MESURES ETAIENT FAUSSES. Un releve au pas
   de 20 px m'avait donne 680 ; un second au pixel m'a donne 678, et j'ai « corrige »
   679 en 678 -- ce qui a CREE le defaut, car les deux releves comparaient
   scrollWidth > clientWidth + 1. Cette tolerance d'un pixel cache exactement le cas
   de la borne : a 679 la table deborde de 1 px. Verifie sans tolerance : debord de
   3, 2, 1, 0, 0 px a 677, 678, 679, 680, 681.
   Une tolerance posee pour absorber du sous-pixel efface le seul cas qui decide. */
/* ⚠️ LE MASQUE REVELAIT UN DEFILEMENT QUI N'AURAIT PAS DU EXISTER. Sous 679 px,
   `min-width:640px` mettait 640 px de table dans un champ de 350 a 390x844 et de 280 a
   320 : la colonne « Credits prepayes » commençait a x 449, donc 59 px hors ecran a 390
   et 129 a 320 -- INVISIBLE A 100 %. La section s'intitule « Abonnement ou credits
   prepayes » et le visiteur mobile ne voyait qu'« Abonnement ». Le degrade de bord etait
   conforme a la charte et signalait correctement le defilement : un indice de defilement
   n'est pas une mise en page.

   La table se replie donc au lieu de defiler. Le libelle de rangee passe en pleine
   largeur, les deux options se partagent la ligne en dessous : chacune reçoit ~50 % au
   lieu de 33 %, soit environ 143 px de texte contre 87 en table serree.

   CHAQUE CELLULE PORTE SON PROPRE LIBELLE via `data-opt`, plutot que de compter sur un
   en-tete de colonne : replie, l'en-tete ne surplombe plus rien. C'est ce qui rend le
   tableau lisible sans repere externe.

   RESERVE ASSUMEE : `display:block` sur une table lui retire ses semantiques de tableau.
   Le `<thead>` est donc masque par clip et non par `display:none`, pour rester dans
   l'arbre d'accessibilite. L'association en-tete / cellule y est perdue quand meme ;
   le libelle porte par chaque cellule est le remede visible. */
@media(max-width:679px){
  .compare-champ{overflow-x:visible;-webkit-mask-image:none;mask-image:none}
  .compare table{min-width:0;display:block}
  .compare colgroup{display:none}
  .compare tbody{display:block}
  .compare thead{position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(0 0 0 0);white-space:nowrap}
  .compare tbody tr{display:grid;grid-template-columns:1fr 1fr;gap:0 18px;
    padding:14px 0 2px;border-bottom:1px solid var(--filet)}
  .compare tbody td{border:0;padding:0 0 8px}
  .compare tbody td:first-child{grid-column:1/-1;padding-bottom:10px;
    font-family:var(--police-titre);font-weight:600;color:var(--encre-titre)}
  /* Graisse et famille remises a plat : `.oui` pose 600 et l'encre de titre sur la
     cellule, et le ::before en heritait -- « Abonnement » sortait en gras sur les deux
     rangees ou l'abonnement gagne, et pale sur les autres. Le libelle designe une
     colonne, il ne prend pas parti. */
  .compare tbody td[data-opt]::before{content:attr(data-opt);display:block;
    font-family:var(--police-corps);font-weight:400;font-size:13px;line-height:1.3;
    color:var(--encre-douce);margin-bottom:3px}
}
/* LARGEURS DECLAREES. Sans elles le navigateur repartissait le surplus a parts
   egales : 337 px pour une cellule d'en-tete VIDE de 4 px, 365 et 458 px pour les
   deux options. La colonne des libelles prend ce que son texte demande, les deux
   options se partagent le reste a egalite -- ce sont deux offres de la maison, pas
   un gagnant et un perdant, et rien ne doit en avantager une. */
.compare table{width:100%;border-collapse:collapse;font-size:16px;table-layout:fixed}
.compare col.lib{width:34%}
.compare col.opt{width:33%}
/* Les deux lignes qui disaient EXACTEMENT la meme chose dans les deux colonnes --
   « Sans expiration / Sans expiration » et « Aucun / Aucun » -- occupaient un tiers
   du tableau sans rien departager, et .oui les composait en encre de titre 600 :
   le tableau mettait en avant ce qui ne decide rien. Elles deviennent une garantie
   commune sous la table, ou elles cessent d'etre du bruit pour devenir un argument. */
.compare-commun{margin:20px 0 0;font-size:16px;color:var(--encre-douce)}
.compare-commun strong{color:var(--encre-titre);font-weight:600}
.compare th,.compare td{text-align:left;padding:14px 16px;border-bottom:1px solid var(--filet)}
.compare thead th{font-family:var(--police-titre);font-weight:600;font-size:16px;
  color:var(--encre-titre);border-bottom:2px solid var(--bordure-composant)}
.compare td:first-child{color:var(--encre-douce)}
/* CINQUIEME ENCRE DE TEXTE, et la charte en autorise quatre. Le vert --succes
   portait le TEXTE de douze cellules -- « Incluses », « Sans expiration » --
   c'est-a-dire qu'il servait d'encre et non de marque. La distinction entre la
   colonne qui gagne et celle qui perd se porte desormais sur la valeur et la
   graisse : encre de titre a 600 contre encre douce a 400, un ecart qui survit au
   flou la ou une teinte ne survit pas au daltonisme. --succes reste employe la ou
   il est une marque et non une encre : le picto de coche des cartes de formule. */
.compare .oui{color:var(--encre-titre);font-weight:600}
.compare .non{color:var(--encre-douce)}
.faq{padding:72px 0;background:var(--fond-alt)}
/* ⚠️ GRILLE TRANSPOSEE SANS SON SECOND OBJET. Elle etait en 1fr 400px, reprise de
   .pourquoi, mais .pourquoi a un objet de preuve dans sa seconde colonne et la FAQ
   n'a que des questions. Consequence : les questions alternaient entre 696 et
   400 px de large -- deux largeurs pour un meme objet -- et le H2, seul dans la
   colonne gauche, se retrouvait 36 px SOUS le haut de la premiere question.
   Deux colonnes egales, et le H2 traverse. */
/* Le damier venait de la grille : cinq questions de hauteurs inegales sur deux
   colonnes laissaient 153 px de trous internes (26 et 127) dans 758 px de section,
   parce qu'une rangee de grille vaut le plus haut de ses deux cellules.
   En colonnes de texte, chaque question suit la precedente sans rangee partagee :
   il n'y a plus de trou a combler. */
.faq .conteneur{columns:2;column-gap:64px}
/* ⚠️ LE SEPARATEUR PASSE SOUS LA QUESTION, et cela supprime toute exception.
   En filet SUPERIEUR il fallait dire quelles questions n'en portent pas, et cette
   liste depend de la mecanique : la premiere RANGEE en grille, la premiere de
   CHAQUE COLONNE en colonnes de texte -- que le CSS ne sait pas viser. Apres le
   passage en colonnes, la regle ecrite pour la grille visait les deux premieres
   QUESTIONS : Q1 et Q2 se touchaient sans separateur dans la colonne gauche et Q3
   ouvrait la colonne droite sur un trait que la gauche n'avait pas -- exactement ce
   que le commentaire de la regle precedente disait vouloir eviter.
   En filet INFERIEUR, la premiere de chaque colonne n'a jamais de trait au-dessus,
   quelle que soit la mecanique, et il n'y a plus rien a maintenir. */
.faq .q{break-inside:avoid;border-top:0;border-bottom:1px solid var(--filet);
  padding:0 0 20px;margin-bottom:20px}
.faq .conteneur>h2{column-span:all;margin-bottom:28px}
.q{padding:20px 0;border-top:1px solid var(--filet)}
/* Conserve pour les .q hors FAQ, s'il en existe : la regle de base pose encore un
   filet superieur, et la premiere question n'en porte pas. */
.q:first-of-type{border-top:0;padding-top:0}
.q h3{font-size:18px;font-weight:600;margin-bottom:6px}
.q p{color:var(--encre-douce);font-size:16px;max-width:56ch}
@media(max-width:1023px){
  .plans .conteneur{grid-template-columns:1fr}
  .faq .conteneur{columns:1}
  /* Le premier prix arrivait a y 760 pour un pli de 568. Ce qui le retient n'est pas
     la carte mais ce qui la precede : 177 px de chrome, puis un en-tete de page de
     383 px. Tout ce qui suit est repris sur des intervalles et sur un echelon de
     corps que la charte declare ; aucun mot n'est retire. */
  .entete-page{padding:32px 0 28px}
  .entete-page h1{font-size:28px}
  .entete-page p{font-size:16px}
  .plans{padding:40px 0 56px}
}

/* ------------------------------------------------------------------
   Article de blog : fil d'Ariane, en-tete, corps de texte long,
   encadre, sommaire, articles lies.
   ------------------------------------------------------------------ */
.fil{font-size:14px;color:var(--encre-douce);padding:20px 0 0}
.fil a{color:var(--encre-douce);text-decoration:none}
.fil a:hover{color:var(--bleu-encre);text-decoration:underline}
/* --neutre-1 rend 1,77:1 sur blanc : sous le seuil AA, et c'etait une sixieme
   encre. Le chevron herite simplement de --encre-douce, comme le reste du fil. */
.fil span{margin:0 8px}

/* ⚠️ LE CONTENEUR REPREND LA LARGEUR DU GABARIT. A 860 px centres, il decalait
   tout le contenu de 170 px vers la droite -- mesure constante a 1280, 1440 et
   1920, donc une serie et non un accident. Le fil d'Ariane demarrait 170 px a
   droite du logo qui le surplombe, et il restait une bande vide de 224 x 5 080 px
   a l'interieur du conteneur.

   La reparation n'est PAS d'elargir la prose : 60 signes par ligne en moyenne,
   pointes a 86, on est deja au haut de la fourchette. C'est d'aligner le bord
   GAUCHE sur celui du gabarit et de laisser le vide a droite, ou il devient une
   marge assumee au lieu d'un decentrement. */
.article .conteneur{container-type:inline-size}
/* ⚠️ .prose EST EXCLUE DE CE PLAFOND. Elle porte deja max-width:var(--mesure),
   soit 68ch, et l'inclure ici la portait a 820 px -- au-dela de sa mesure de
   lecture. Un plafond de bloc n'est pas une mesure de texte. */
.article .fil,.article .article-tete,.article .sommaire,
/* LA COLONNE DE LECTURE N'EST PAS LA COLONNE DE GRILLE. Les paragraphes sont tenus
   a la mesure ; les tableaux et les encadres prennent toute la colonne. C'est ce
   qui rend au pire tableau du corpus -- 6 colonnes, largeur minimale 780 px une
   fois l'en-tete autorise a se replier -- de quoi tenir entier, la ou une colonne
   de 659 px lui en cacherait 121. */
.article .encadre,.article .tableau,.article .article-illus{max-width:100%}

/* L'ILLUSTRATION QUE LE PIPELINE FABRIQUE DEJA. Chaque publication produit un WebP
   -- verifie en production : featured_media 49423, has-post-thumbnail -- et le
   gabarit ne declarait aucun emplacement pour le recevoir. Un objet fabrique a
   chaque article, et pas de place ou le poser.

   LE RECADRAGE EST DANS LA FEUILLE, PAS DANS LE FICHIER. La source actuelle est
   carree (1024x1024) et son encre court de y 64 a y 960 : aucun recadrage fixe ne
   la preserve. aspect-ratio + object-fit acceptent le carre d'aujourd'hui comme le
   panoramique de demain, sans qu'un seul fichier soit a refaire.

   ELLE PREND LA COLONNE, PAS LE CONTENEUR. Le directeur artistique demandait
   1 160 px pour traverser la marge vide ; la charte §6 plafonne une illustration a
   50 % du conteneur, soit 580. Ni l'un ni l'autre : elle rejoint les tableaux et
   les encadres a 812 px, la largeur de la colonne de lecture, en vertu de la regle
   deja posee plus haut -- les paragraphes tiennent la mesure, les objets prennent
   la colonne. Un plafond ecrit pour une illustration de section ne se transpose pas
   a l'objet propre d'un article.

   3/1 ET NON 16/9, sur trois mesures concordantes a 1440 : entiere dans le pli
   (y 556-826 contre 556-1012), 291 px de document ajoutes contre 477, et la plus
   faible masse floutee. Aux quatre rapports essayes -- 16/9, 2/1, 5/2, 3/1 --
   l'illustration pese PLUS que le H1 au flou : 3,01 / 2,65 / 2,16 / 1,75. Ce n'est
   pas l'image qui est trop lourde, c'est le H1 qui est trop leger : 36 px, le plus
   petit du panel concurrent, qui en compte trois a 40 et un a 56. */
.article-illus{margin:0 0 32px}
/* height:auto est indispensable : l'attribut height="1024" de la balise sert de
   dimension utilisee et l'emporte sur aspect-ratio sans lui. L'image rendait
   812x1024 au lieu de 812x457. */
/* 16/9 -> 5/2 SOUS 1080 PX, et c'est un retrait de vide, pas un rognage. Le fichier
   pose son dessin entre y 12 et 66 % ; en 16/9 le lecteur voyait tout, donc aussi les
   67 px de fond vide sous le dessin contre 22,8 au-dessus, rapport 3:1. Le dessin
   n'occupait plus que 33,6 % du cadre a 390 px, contre 52 % pour la version precedente.
   En 5/2 avec l'ancrage a 11 %, la bande visible devient y 3,2 a 74,3 % : le dessin y
   tient toujours entier, avec des marges egales.
   MESURE : le dessin ne perd PAS un pixel de hauteur -- 107,1 px a 390 dans les deux
   cas. On retire du vide, on ne fabrique pas une lamelle. Sa surface passe de 33,6 a
   47,3 % du cadre.
   ⚠️ Le commentaire qui craignait « 3/1 tombait a 350x117 » raisonnait sur une image qui
   REMPLISSAIT son cadre. Depuis le placement par mesure, ce n'est plus le cas. */
.article-illus img{display:block;width:100%;height:auto;aspect-ratio:5/2;object-fit:cover;
  object-position:50% 11%;
  border-radius:var(--rayon-m);background:var(--fond-alt)}

/* IMAGE DE CORPS. Elle reprend d'`.article-illus` tout ce qui est du cadre -- meme
   marge basse, meme rayon, meme fond d'attente -- et RIEN de ce qui est du recadrage.
   C'est la difference entiere : `aspect-ratio:5/2` et `object-fit:cover` valent pour
   un fichier compose pour ce cadre, et rognent n'importe quel autre. Aucun jeton
   nouveau, aucune valeur nouvelle.
   `max-width` et non `width` : une capture de 393 px de large ne doit pas etre etiree
   a 812. Les images larges, elles, se reduisent a la colonne. */
.article-corps{margin:0 0 32px}
.article-corps img{display:block;max-width:100%;height:auto;
  border-radius:var(--rayon-m);background:var(--fond-alt)}
/* La legende reprend l'ecriture des libelles secondaires du site -- 14 px de corps
   en `--encre-douce` -- la meme que la barre de rubriques et le sommaire lateral. */
figcaption{margin-top:10px;font-family:var(--police-corps);font-size:14px;
  line-height:1.45;color:var(--encre-douce)}

/* Colonne laterale : sommaire en haut, carte du cocon dessous, RIEN DE COLLANT.
   Mesure a l'appui : le bloc entier fait 1 744 px avec les 10 H2 d'un article du
   corpus et les 17 titres que le plan prevoit au cocon le plus fourni, quand la
   place sous l'en-tete est de 551 px a 680 de fenetre et de 951 a 1080. Meme
   tronque a une ligne il fait 1 469 px. Et le tronquer coupe 9 titres sur 10, au
   mauvais endroit : en francais l'information arrive tard dans la phrase.
   Le sommaire seul tiendrait (518 a 674 px), mais il occuperait alors 71 a 100 %
   de la hauteur utile -- un panneau de navigation aussi haut que la zone de
   lecture, sur une page dont le metier est de se lire. */
/* ⚠️ TROISIEME FUITE DES REGLES DE nav, ET J'EN AVAIS NEUTRALISE UNE SEULE.
   .som-aside est un <nav> : les regles ecrites pour la navigation de l'en-tete s'y
   appliquent toutes. J'avais vu display:flex, qui posait le titre et la liste cote
   a cote. Restaient overflow-x:auto, nav a{white-space:nowrap} et le masque de bord
   sous 515 px -- ensemble ils sortaient du champ 6 entrees sur 7 a 320 px (pire
   coupe 116 px), 4 sur 7 a 390, propre seulement des 455.
   Une regle globale sur un selecteur d'element atteint tout element de ce nom : la
   neutraliser demande de la reprendre EN ENTIER, pas la propriete qu'on a vue. */
/* LA SIGNATURE DU GABARIT D'ARTICLE : le rang de la section en cours de lecture, seul
   objet de titrage de la colonne. Meme composition que le rang de prose -- Rubik 600
   48 px, --encre-douce -- mais permanent et des le premier ecran, aux DEUX formats :
   il est a y 604 en mobile la ou le rang de prose est a y 1 902.
   Reserve de gauche a 60 px, mesuree et non choisie : « 10 » en Rubik 600 48 px fait
   55,1 px et « 17 » 49,8 px ; 46 px n'auraient pas suffi.
   Hauteur figee : le chiffre s'efface dans une section hors rang (la FAQ n'ouvre pas une
   etape du raisonnement, elle n'a pas de rang), et rien ne doit se decaler pour autant. */
/* Le chiffre prend la place du titre de colonne au lieu de s'ajouter au-dessus : pose
   en bloc separe il coutait 66 px et sortait la 9e entree du premier ecran. Sur une
   ligne avec son libelle, il coute 30 px et les 9 entrees restent au-dessus du pli. */
.rang-courant{display:flex;align-items:center;gap:12px;margin:0 0 12px}
.rang-chiffre{flex:0 0 60px;height:48px;
  font-family:var(--police-titre);font-weight:600;font-size:48px;line-height:1;
  letter-spacing:-.02em;color:var(--encre-douce)}
.rang-libelle{font-family:var(--police-corps);font-size:14px;font-weight:600;
  line-height:1.3;letter-spacing:.02em;color:var(--encre-douce)}
.som-aside,.cocon-aside{display:block;font-size:14px;line-height:1.45}
/* LE RESUME DU SOMMAIRE N'EXISTE QU'EN MOBILE. Au-dessus de 1080 la colonne est
   deployee et collante, il n'y a rien a replier : le `<details>` reste `open` et son
   `<summary>` se retire. En dessous il devient le bouton qui rend au premier ecran les
   313 px que le sommaire lui prenait.
   ⚠️ `display:none` SUR UN `<summary>` NE CASSE PAS LE `<details>` tant que celui-ci
   porte `open` : c'est le cas ici, l'attribut est ecrit dans le HTML et seul le script
   le retire, et il ne le retire que sous 1080. */
.som-aside>summary{display:none}
@media(max-width:1079px){
  .som-aside>summary{display:flex;align-items:center;justify-content:space-between;
    gap:12px;cursor:pointer;list-style:none;font-weight:600;color:var(--encre-titre)}
  .som-aside>summary::-webkit-details-marker{display:none}
  /* Le chevron dit le sens du geste. Il tourne quand la boite s'ouvre. */
  .som-aside>summary::after{content:"";width:8px;height:8px;flex:0 0 auto;
    border-right:2px solid var(--encre-douce);border-bottom:2px solid var(--encre-douce);
    transform:rotate(45deg) translate(-2px,-2px);transition:transform .15s}
  .som-aside[open]>summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
  .som-aside[open]>summary{margin-bottom:12px}
}
.som-aside{overflow-x:visible;-webkit-mask-image:none;mask-image:none}
.som-aside a{white-space:normal}
.som-aside a{font-weight:400}
/* Le libelle du cocon est un <p> et non un <h2> : place AVANT la prose dans le DOM, un
   h2 y faisait de « KPIs & Mesure de performance » la premiere section du document,
   au rang des sections de l'article, pour tout ce qui lit le plan (titre a titre au
   lecteur d'ecran, hierarchie relevee par les robots). Le sommaire ne le voyait pas,
   il ne lit que les fragments du markdown. Meme regle, meme rendu, 2 septembre 2026. */
.som-aside h2,.cocon-aside p{font-family:var(--police-corps);font-size:14px;font-weight:600;
  line-height:1.3;letter-spacing:.02em;color:var(--encre-douce);margin:0 0 12px}
.som-aside ol{list-style:none;counter-reset:s;margin:0;padding:0}
.som-aside li{counter-increment:s;margin-bottom:9px;padding-left:32px;position:relative}
/* Le sommaire saute le meme rang que la prose, sinon les deux listes se contredisent
   au lieu de former un seul systeme. */
.som-aside li.hors-rang{counter-increment:none}
.som-aside li.hors-rang::before{content:none}
/* ⚠️ CE COMPTEUR ETAIT EN CHASSE FIXE, et c'est moi qui l'y avais mis. Sept
   occurrences dans une seule section : trois interdits nommes de la charte en une
   regle -- chasse fixe hors donnee d'infrastructure, deux occurrences dans une meme
   section, texte sous 14 px. Et il ne rendait rien : le meme sommaire floute a
   3,2 px rend 5 764 unites d'encre en JetBrains Mono contre 5 768 en Inter, soit
   0,07 % d'ecart. Une signature indiscernable de la fonte de corps ne signe rien,
   elle consomme la rarete que les passes precedentes ont construite. */
/* ⚠️ CE NUMERO A ETE COMPOSE EN RUBIK 600 18 PX, et il faut savoir pourquoi il ne l'est
   plus. L'idee etait de porter la regle au-dessus du pli : le rang de prose n'apparait
   qu'a y 903 en desktop et y 1 902 en mobile, le sommaire est entier au-dessus du pli.
   Mesure du gain : pic floute 50,4 -> 83,1 (+65 %), a hauteur de colonne inchangee.
   Mais l'echelle du premier ecran le replace : texte de l'entree 73,2, numero 83,1,
   prose 125,2, rang de prose 138,4, H1 201,7. Le numero passait de « nettement sous son
   propre texte » a « a peine au-dessus », 1,14x, avec une encre MOYENNE toujours
   inferieure a celle du texte qu'il numerote. Ce qui existait avant le pli, c'etait une
   liste numerotee -- l'objet le plus banal du web, dont aucune regle ne se deduit. Et le
   sommaire etait a son plafond : dans 300 px, neuf entrees de deux lignes et 28 px de
   gouttiere, le chiffre ne pouvait pas monter plus haut.
   La signature est donc passee a UN seul objet, `.rang-courant`. Une signature vaut par
   sa rarete : un numero a 48 px et huit a 18 se seraient annules. Le sommaire garde la
   correspondance, il ne titre plus. */
.som-aside li::before{content:counter(s);position:absolute;left:10px;top:1px;
  font-family:var(--police-corps);font-weight:500;font-size:14px;line-height:1.45;
  color:var(--encre-douce)}
/* Entree courante. C'est l'etat actif que le sommaire n'a jamais eu : ni :target, qui ne
   marche qu'apres un clic, ni la numerotation partagee, qui donne une correspondance et
   pas un etat. Le filet porte la marque plutot que l'encre : --encre et --encre-titre
   sont deux noirs trop proches pour se distinguer, et --bleu-encre est deja le survol. */
/* BARRE DE RUBRIQUES (pages de rubrique et /blog-2/).
   Le cran typographique n'est pas choisi : 14 px / 600 / 0,28 px d'interlettre est
   celui de `.cocon-aside h2` et de `.rang-libelle`, deja en place. Pas de capitales
   -- `uppercase` a ce meme cran appartient a `.nav-sens`, et deux composants de
   chrome au traitement identique cessent de se distinguer.
   ⚠️ FLEX-WRAP, JAMAIS DE DEFILEMENT HORIZONTAL. Une entree hors champ n'est pas une
   entree. Mesure Inter 600/14 : les six libelles et leurs cinq gouttieres font 766 px
   pour un conteneur de 1 200 a 1440 et d'environ 1 000 a 1080 -- une seule ligne. A
   390 la barre se replie sur trois rangs, soit environ 104 px.
   La gouttiere de 24 px est celle de `.billets` et de `.nav-billets`, pas un chiffre
   neuf. */
.barre-rubriques{display:flex;flex-wrap:wrap;column-gap:24px;row-gap:10px;margin-top:20px}
.barre-rubriques a,.barre-rubriques span{font-family:var(--police-corps);font-size:14px;
  font-weight:600;letter-spacing:.28px;text-decoration:none;color:var(--encre-douce)}
.barre-rubriques a:hover{color:var(--bleu-encre);text-decoration:underline}
/* La rubrique courante reprend LITTERALEMENT le marqueur du sommaire -- filet de 3 px
   en `--bleu`, rayon 2 px -- tourne a l'horizontale. Le site possedait deja la regle
   « l'entree courante se marque d'un filet de 3 px en bleu » en un seul exemplaire :
   ce reemploi la porte a deux et la rend deductible, au lieu d'inventer un traitement
   de plus. */
.barre-rubriques span[aria-current]{color:var(--encre-titre);position:relative}
.barre-rubriques span[aria-current]::after{content:"";position:absolute;left:0;right:0;
  bottom:-6px;height:3px;background:var(--bleu);border-radius:2px}
@media(max-width:599px){.barre-rubriques{column-gap:18px}}

/* ⚠️ LE BADGE DE RUBRIQUE DISPARAIT LA OU IL EST CONSTANT. Sur `/technique/`, dix-huit
   cartes portaient dix-huit fois « Délivrabilité & technique » ; sous les quatre
   billets voisins d'un article, quatre fois la meme rubrique. Au plissement a 3,2 px
   cela rend quatre barres bleues identiques en tete de carte : une information nulle
   qui occupe la premiere ligne. Le badge reste sur /blog-2/ et sur l'accueil, ou il
   distingue reellement.
   ⚠️ NE PAS FAIRE DU BADGE UN LIEN vers la rubrique : `.billet` EST deja un <a>, et
   un <a> imbrique est invalide -- le navigateur defait le balisage. La barre porte le
   lien, le badge reste un texte. */
.billets--homogene .cat{display:none}

/* Une rubrique de moins de quatre billets etirait ses cartes sur toute la rangee :
   `/miscellaneous/` rendait UNE carte de 272 px suivie de 888 px de vide. Les pistes
   se figent a la largeur de carte mesuree, les cartes gardent leur taille. Scopee
   au-dessus de 1024 pour ne pas heurter les paliers de la grille a 1023 et 479. */
@media(min-width:1024px){
  .billets--peu{grid-template-columns:repeat(auto-fill,272px);justify-content:start}
}
.som-aside li.actif::after{content:"";position:absolute;left:0;top:2px;bottom:2px;
  width:3px;background:var(--bleu);border-radius:2px}
.som-aside li.actif>a{color:var(--encre-titre)}
.som-aside li.actif::before{color:var(--encre-titre)}
.som-aside a,.cocon-aside a{color:var(--encre);text-decoration:none}
.som-aside a:hover,.cocon-aside a:hover{color:var(--bleu-encre);text-decoration:underline}
.cocon-aside{margin-top:36px;padding-top:24px;border-top:1px solid var(--filet)}
.cocon-aside ul{list-style:none;margin:0;padding:0}
.cocon-aside li{margin-bottom:14px}
/* Le socle du cocon se distingue des satellites : c'est l'article dont les autres
   dependent, et le lecteur qui arrive par un satellite n'a aucun autre moyen de le
   savoir. */
.cocon-aside .socle{padding-bottom:14px;margin-bottom:14px;border-bottom:1px solid var(--filet)}
.cocon-aside .socle a{font-weight:600;color:var(--encre-titre)}
.cocon-aside .rang{display:block;font-size:12px;color:var(--encre-douce);margin-bottom:3px}

/* 1080 et non 1024 : la colonne de lecture doit garder sa mesure entiere. Il lui
   faut 659 px, plus 48 de gouttiere et 300 de colonne laterale, soit 1 007 px de
   conteneur et donc 1 047 px de fenetre. A 1024 la prose tombait a 636 px. */
/* Le 3/1 ne vaut qu'en deux colonnes : il sert a traverser la marge droite que la
   prose laisse vide, et cette marge n'existe pas en une colonne. Sous 1080 px le
   rapport se relache a 16/9, sans quoi l'image tombait a 350x117 a 390 px et a
   280x93 a 320 -- une lamelle. */
@media(min-width:1080px){
  /* L'ancrage est REDECLARE ici, il ne s'herite plus : la valeur de base est passee a
     11 % pour le cadre mobile, et sans cette ligne le desktop l'aurait suivie. */
  .article-illus img{aspect-ratio:3/1;object-position:50% 22%}
}

@media(min-width:1080px){
  /* Les rangees 3 et 4 sont dimensionnees par les seuls blocs de la colonne
     laterale. Sans cela, la prose qui les traverse y REPARTIT sa hauteur : la
     rangee 3 gonflait a 2 299 px et la carte du cocon tombait au milieu de
     l'article, a y 2 712. La rangee 5 absorbe le reste de la prose. */
  .article .conteneur{display:grid;grid-template-columns:minmax(0,1fr) 300px;
    grid-template-rows:auto auto min-content min-content auto;
    gap:0 48px;align-items:start}
  /* Placement EXPLICITE des quatre blocs. En placement automatique, la prose
     declaree apres le sommaire dans le DOM ne remonte pas dans la rangee libre de
     la premiere colonne : elle partait 317 px sous lui. */
  .article .fil{grid-column:1/-1;grid-row:1}
  .article .article-tete{grid-column:1/-1;grid-row:2}
  /* La prose n'est plus plafonnee : c'est chacun de ses blocs de texte qui l'est,
     ce qui laisse la largeur restante aux tableaux et aux encadres. */
  .article .prose{grid-column:1;grid-row:3/6;max-width:none}
  .article .prose>p,.article .prose>h2,.article .prose>h3,
  .article .prose>ul,.article .prose>ol,.article .prose>blockquote{max-width:var(--mesure)}
  /* LA COLONNE COLLE PAR LE BAS, ET LE REGIME COMPTE PLUS QUE LA REGLE.
     Un bloc PLUS COURT que la fenetre se colle par le haut : il tient entier et il
     reste lisible. Un bloc PLUS HAUT se colle par le bas : il defile le temps qu'on
     le lise, puis son bas se cale sur la fenetre et il tient. C'est ce que fait la
     colonne de webfr.org, 938 px dans une fenetre de 900, en JavaScript ; ici c'est
     une declaration.

     ⚠️ MAIS LE COLLAGE PAR LE BAS NE MARCHE DANS AUCUN DES DEUX REGIMES ICI, et la
     raison est structurelle : sticky avec bottom retient un element vers le bas de la
     fenetre TANT QU'IL LUI RESTE DU CONTENEUR AU-DESSUS. Notre colonne commence en
     haut de son conteneur : rien ne la retient. L'effet de webfr.org ne vient pas de
     cette declaration, leur theme le fait en JavaScript en deplacant l'element.

     Mesure a 1440x900, en vue sur 8 points de defilement :
       par le bas    3/8 a 717 px, 3/8 a 1 026 px
       par le haut   8/8 a 717 px, 8/8 a 1 026 px
     Le `top` ci-dessous est la valeur de repos ; assets/colonne.js le deplace entre
     deux bornes au rythme du defilement, ce qui donne les deux bords selon le sens de
     lecture. Une barre de defilement interne a ete refusee, et aucune declaration CSS
     ne sait exprimer ce comportement. */
  .colonne-aside{grid-column:2;grid-row:3/6;position:sticky;top:105px}
}
/* ⚠️ LE COMMENTAIRE QUI TENAIT ICI ETAIT FAUX. Il disait « l'ordre du DOM fait le
   travail : sommaire avant l'article, carte du cocon apres, aucune regle d'ordre a
   ecrire ». Le DOM ne dit pas cela : `.som-aside` ET `.cocon-aside` sont tous deux
   dans `.colonne-aside`, donc tous deux AVANT la prose. Mesure a 390x844 : 783 px de
   mobilier de colonne entre le bas du H1 et le premier mot, et le premier mot a
   y 1 365, soit 1,62 fenetre.

   LE MOBILE N'EST PAS UN DESKTOP EMPILE. En deux colonnes, la colonne laterale est
   un COMPAGNON : elle accompagne la lecture sans jamais la precéder. Empilee telle
   quelle, le compagnon devient un MUR. La reparation n'est pas de la raccourcir,
   c'est de rendre a chacun de ses deux blocs la place que son role lui donne quand
   il n'y a plus qu'une colonne :
     - le sommaire PRECEDE le texte : c'est le seul moyen de naviguer 11 fenetres
       de prose, il doit etre atteignable avant d'entrer ;
     - la carte du cocon SUIT le texte : « quoi lire ensuite » n'a aucun sens avant
       d'avoir lu, et elle coutait 236 px (36 de marge + 200 de bloc) a l'entree.

   `display:contents` sur `.colonne-aside` sort ses trois blocs du wrapper et les
   rend items du meme conteneur flex que le fil, l'en-tete et la prose : c'est ce qui
   permet de les reordonner sans toucher au HTML, que le pipeline impose.

   ⚠️ ET IL FAUT ORDONNER LES CINQ, PAS SEULEMENT CELUI QU'ON DEPLACE. `.som-aside`
   est un <nav> : la regle globale `nav{...order:3...}` de la barre d'en-tete l'atteint
   des que son parent devient flex. C'est la QUATRIEME fuite des regles de nav sur cet
   element, et cette fois elle serait apparue a l'endroit exact ou on croit ordonner.

   ⚠️ CE QUE LE REORDONNANCEMENT COUTE, ET QUI SE PAIE AILLEURS. `order` deplace le
   rendu, pas le DOM : la carte du cocon garde ses trois liens AVANT le corps de
   l'article dans l'ordre de tabulation. Trois arrets de clavier, sur un <aside>
   etiquete -- la navigation par region n'est pas touchee, la navigation lineaire
   l'est. Le trait est assume ici parce que la seule reparation propre est en amont :
   que le convertisseur emette `.cocon-aside` APRES `.prose` et non dans le wrapper de
   colonne. Le jour ou il le fera, `order:6` et `display:contents` tombent tous les
   deux, et rien d'autre ne bouge -- en deux colonnes le placement est explicite, il
   ne depend pas de l'ordre du DOM.

   ⚠️ ET IL FAUT REDECLARER LES MARGES VERTICALES. Un item flex ne fusionne plus ses
   marges avec ses voisins : `.rang-courant{margin-bottom:12}` contre le `margin-top:14`
   que `.som-aside` herite de nav rendait 14 px et rendrait 26. Les trois intervalles
   sont donc poses en clair. */
@media(max-width:1079px){
  /* L'AIR SOUS L'EN-TETE EST COMPTE DEUX FOIS. `.article` est un <section> : il prend
     les 56 px de retrait haut ecrits pour une section de contenu, et le fil d'Ariane
     qui l'ouvre porte deja les siens -- 76 px de blanc entre le filet de la barre de
     navigation et le premier mot du fil, sur une page dont le defaut nomme est son
     entree. Un fil d'Ariane n'est pas une section : il annonce la page, il ne s'en
     detache pas. 24 + 20 = 44 px, une valeur de l'echelle. */
  .article{padding-top:24px}
  .article .conteneur{display:flex;flex-direction:column}
  .article .colonne-aside{display:contents}
  .article .fil{order:1}
  .article .article-tete{order:2}
  /* ⚠️ LE RANG COURANT SORT EN MOBILE, PARCE QUE LE `<summary>` LE REMPLACE. Les deux
     portent le meme libelle, « Sur cette page », a 78 px l'un de l'autre : le doublon
     est ne le jour ou le sommaire est devenu repliable, et il n'existait pas avant.
     Ce n'est pas le seul motif. `colonne.js` ne met a jour QUE le chiffre, jamais le
     libelle, et il ne tourne pas sous 1080 : l'objet annonçait donc « 1 » au repos
     alors que la section 1 commence a y 1 902. Un indicateur de progression qui
     n'avance pas est une donnee fausse, et il coutait 60 px sur l'ecran ou chaque
     pixel se paie.
     En desktop il reste : il y fait office de titre de colonne, le script l'anime, et
     c'est le `<summary>` qui s'efface. */
  .article .rang-courant{display:none}
  .article .som-aside{order:4;margin-top:0;margin-bottom:28px}
  .article .prose{order:5}
  .article .cocon-aside{order:6;margin-top:40px}
  .som-aside{max-width:var(--mesure);padding:18px 20px;
    background:var(--fond-alt);border-radius:var(--rayon-m)}
  .cocon-aside{max-width:var(--mesure)}
}
.article-tete{padding:24px 0 8px}
/* Un titre d'article est un H1 D'EN-TETE DE PAGE, pas un H1 de hero : la charte
   en fait deux objets distincts, et le test du plissement ne vaut que pour le
   second. Sans cette regle, la formule continue du hero s'applique et rend 64 px. */
.article-tete h1{font-size:min(36px, 9.2cqi, 7.7vh);line-height:1.2;
  letter-spacing:-.011em;margin-bottom:16px}
.article-meta{display:flex;flex-wrap:wrap;gap:8px 20px;align-items:center;
  font-size:14px;color:var(--encre-douce);padding-bottom:28px;
  border-bottom:1px solid var(--filet)}
.article-meta .cat{background:var(--bleu-voile);color:var(--bleu-encre);
  font-weight:600;padding:4px 10px;border-radius:var(--rayon-s)}
/* LA SIGNATURE PREND LE SECOND RANG DE LA LIGNE : le nom en encre de corps, mais en 500
   et non en 600 -- arbitrage du directeur artistique, 3 septembre 2026. En 600 son noyau
   au plissement rendait 151 contre 161 a la pastille de categorie : c'etait l'objet le
   plus noir d'une ligne de service. En 500 il rend 161, a egalite avec la pastille, et
   11,4 de densite lineique entre 15,6 (pastille) et 8,1 (date). Le « Par » reste en encre
   douce : il ne pese rien au flou et il est le seul indice qui designe « Bertille » ou
   « Charif » comme une personne. Place mesuree : apres la pastille, cout de hauteur nul a
   1440 comme a 390 (rang 1 pastille + auteur, rang 2 date + duree) ; +30 px a 320, un rang
   par objet. Variantes ecartees : en tete de ligne (la pastille perd son role de porte
   d'entree), sur sa propre ligne (+32 px pour un objet de 14 px), sans « Par », 600 en
   encre douce (le nom devient une nuance). */
.article-meta .auteur b{font-weight:500;color:var(--encre)}

/* La mesure de lecture est la contrainte, pas la largeur du conteneur. */
.prose{max-width:var(--mesure);font-size:18px;line-height:1.7;color:var(--encre)}
.prose>p{margin:0 0 20px}
/* Un H2 DE PROSE n'est pas un H2 de section : il rythme un texte long sous un H1
   d'en-tete de page a 36 px, la ou un H2 de section vit sous un H1 de hero a
   64 px. A 28 px le rapport tombait a 1,29 contre 2,29 sur l'accueil, et la
   couleur jouait contre le titre -- les H2 bleus rythmaient la page pendant que
   le H1 noir s'y fondait. A 24 px le rapport passe a 1,50. */
/* L'ECHELLE DU MILIEU S'OUVRE. Elle etait a quatre niveaux dans 6 px -- H2 24, H3 22,
   « En bref » 20, corps 18 -- avec des rapports voisins de 1,09 / 1,10 / 1,11, pendant
   que le haut venait de gagner 1,33 et 1,50 : la page se dotait d'un sommet et gardait
   son milieu plat. Trois niveaux desormais, 28 / 20 / 18, rapports 1,40 et 1,11.
   L'argument qui avait fait rejeter 28 px le 26 aout -- « le rapport tombe a 1,29 contre
   le H1 » -- est perime : l'echelle a maintenant un sommet a 48, le H1 a 36 ne porte
   plus seul l'ecart, et les H2 ne sont plus bleus. */
.prose h2{font-size:28px;line-height:1.3;letter-spacing:-.014em;margin:8px 0 16px}

/* LE RANG DE SECTION EST L'OBJET D'AFFICHAGE DU GABARIT.
   Il n'est jamais ecrit dans le HTML : compteur CSS, donc aucun geste par article
   et aucune touche au contenu, qui est impose par le pipeline. C'est aussi ce qui
   en fait un OBJET et non un mot dans une phrase -- inline en prefixe, il ne rendrait
   rien au flou.

   Ce qui porte un rang : un H2 qui ouvre une etape du raisonnement. Un seul en sort,
   la FAQ, marquee `hors-rang` par le convertisseur (17 des 23 articles en portent une,
   le libelle varie, et elle n'est pas toujours la derniere). Le compteur ne
   s'incremente pas dessus : la FAQ ne consomme pas un rang, elle n'en a pas.

   Cout mesure : marge haute du H2 ramenee de 44 a 8, le numero coute +12 px par H2. */
.prose{counter-reset:rang}
/* scroll-margin-top valait 0 : apres un clic dans le sommaire, le H2 atterrissait a
   top 0 sous un en-tete collant, entierement recouvert, 9 fois sur 9. En-tete mesure
   81 px, plus 24 px d'air = 105.

   ⚠️ ET J'AVAIS POSE 164 PX SOUS 1024, POUR RIEN. Sous 1024 l'en-tete est
   `position:static` (l.81 de cette feuille) : il defile, il ne peut couvrir aucun
   titre. Mon detecteur comparait la position du titre a la hauteur de l'en-tete sans
   regarder s'il etait collant, et le « 1 titre couvert sur 9 » qu'il annonçait
   n'existait pas. Les 164 px posaient 164 px de la section PRECEDENTE au-dessus du
   titre atteint, 19,4 % d'une fenetre de 844. Il reste la meme air de 24 px, sans
   obstacle a degager. */
.prose>h2{counter-increment:rang;scroll-margin-top:105px}
@media(max-width:1023px){ .prose>h2{scroll-margin-top:24px} }
/* Interligne 0,78 : les chiffres de Rubik n'ont pas de descendante, la boite peut
   serrer le dessin. A 1,00 le numero coutait +204 px de document (+2,1 %), ici +152
   (+1,6 %). Le reste de l'ecart avec le +12 px/H2 vise vient du COLLAPSE : la marge
   haute du H2 ramenee a 8 est plancheee a 32 par la marge basse du paragraphe qui
   precede -- mesure, air avant H2 = 32 px. La reduire demanderait de toucher au
   rythme de toute la prose. */
.prose>h2::before{content:counter(rang);display:block;
  font-family:var(--police-titre);font-weight:600;font-size:48px;line-height:.78;
  letter-spacing:-.02em;color:var(--encre-douce);margin:0 0 4px}
.prose>h2.hors-rang{counter-increment:none;margin-top:44px}
/* PROSE SANS RANG. Employee sur les pages legales, et sur elles seules.
   ⚠️ LA NUMEROTATION AUTOMATIQUE Y AURAIT DOUBLE LES CHIFFRES. La politique de
   confidentialite numerote deja ses sections dans son texte -- « 1. Champ
   d'application », « 2. Collecte des donnees »... -- et le grand chiffre de `.prose`
   serait venu poser un « 1 » de 48 px au-dessus d'un titre qui commence par « 1. ».
   Deux numerotations concurrentes sur le meme titre, et la seconde est celle de
   l'auteur : c'est la nôtre qui se retire.
   Le rang ne se contente pas de disparaitre, il rend sa place : sans le bloc de
   48 px, l'ecart au titre precedent doit etre repris a la main. */
.prose.sans-rang{counter-reset:none}
.prose.sans-rang>h2::before{content:none}
.prose.sans-rang>h2{margin-top:48px}
.prose.sans-rang>h2:first-child{margin-top:0}
/* ⚠️ ET LE MEME SELECTEUR SOUS 1024, SINON IL ECRASE LA REGLE MOBILE. `.prose>h2`
   pese 0-1-1, `.prose.sans-rang>h2` pese 0-2-1 : ma regle l'emportait sur le
   `margin-top:20px` du bloc mobile, et les pages juridiques gardaient 48 px la ou
   l'article passe a 20. Mesure : +28 px onze fois, soit 308 px de document, et un
   filet de titre qui flottait a 48 px au-dessus de ce qu'il introduit. */
@media(max-width:1023px){ .prose.sans-rang>h2{margin-top:20px} }
.prose>h2.hors-rang::before{content:none}
/* ⚠️ IL Y AVAIT ICI `.prose>h2:target::before{color:var(--bleu-encre)}`, cense donner
   au sommaire l'etat actif qui lui manque. Retire : --bleu-encre est EXACTEMENT l'encre
   du texte du H2. Le rang cessait d'etre un objet distinct et fusionnait avec le titre
   au moment precis ou on le sollicite. Un marquage qui efface ce qu'il marque. */
/* Marge haute 32 -> 28, proportionnee au H3 qui passe de 22 a 20. */
.prose h3{font-size:20px;font-weight:600;line-height:1.35;letter-spacing:-.014em;margin:24px 0 12px}
/* LE SECOND RANG, DERIVE DU PREMIER.
   ⚠️ LE H3 ETAIT TYPOGRAPHIQUEMENT INDISCERNABLE D'UN GRAS EN LIGNE. Mesure :
   H3 = Onest 20 px / 600 / #1a1a2e ; `strong` de prose = Inter 18 px / 600 / #1a1a2e.
   Meme graisse, meme encre, deux pixels d'ecart, seule la famille change -- et la
   famille ne se voit pas au flou. Sur `comparatifs/logiciel-emailing`, 24 H3 pour
   6 H2, le H3 « La delivrabilite » rendait une barre plus courte et plus legere que
   trois des quatre amorces grasses de la liste qui le suit : le subordonne pesait
   plus que son titre.
   Le gabarit possedait UN dispositif de rang, le grand chiffre gris du H2, et il
   n'existait qu'a un niveau. Le second ne s'invente donc pas, il SE DERIVE : le H3
   prend l'encre de son parent -- `--bleu-encre`, que `strong` n'a pas -- et un filet
   dans le gris exact du chiffre de rang, `--encre-douce`. Deux traits d'une meme
   famille, un rang plus bas.
   LA REGLE EST SEMANTIQUE ET NON QUANTITATIVE : un H3 ouvre une subdivision d'une
   section numerotee, un `strong` porte une insistance a l'interieur d'une phrase. Un
   plafond sur le nombre de H3 ne produirait aucun systeme ; cette distinction-la, si.
   ⚠️ 24 px ET NON 28. L'ancienne valeur etait hors de l'echelle d'espacement declaree
   (4/8/12/16/24/32/48/64/96). Avec le filet et son air, le texte du H3 se pose a 34 px
   du paragraphe precedent, contre 61 px pour celui du H2 : la hierarchie de l'air est
   tenue, et elle l'etait deja -- les 20 px qu'on croit voir avant un H2 sont l'ecart
   avant SON CHIFFRE, pas avant son titre. */
.prose>h3{color:var(--bleu-encre)}
.prose>h3::before{content:"";display:block;width:28px;height:2px;border-radius:1px;
  background:var(--encre-douce);margin:0 0 8px}
/* QUATRIEME CRAN. Il prolonge l'echelle -- 28, 20, 18 -- au lieu de descendre sous le
   corps, ce qui ferait d'un titre l'objet le plus petit de sa section. A corps egal avec
   le paragraphe, trois choses l'en separent, et chacune survit au flou : la fonte de
   titre, la graisse 600, et l'encre de titre plus dense que celle du corps. La marge
   haute de 24 px, entre les 28 du h3 et les 20 du paragraphe, dit la subordination. */
.prose h4{font-size:18px;font-weight:600;line-height:1.45;letter-spacing:-.014em;margin:24px 0 8px}
.prose ul,.prose ol{margin:0 0 20px;padding-left:22px}
.prose li{margin-bottom:10px}
.prose strong{font-weight:600;color:var(--encre-titre)}
/* ⚠️ CETTE REGLE ECRASAIT LE TITRE QUI LA CONTENAIT. Un `**gras**` ecrit dans un h2
   -- tic recurrent des articles importes de WordPress, 26 titres dans 8 fichiers --
   rendait le titre en `--encre-titre` 600 au lieu du bleu 700 du gabarit. Une page
   entiere perdait ainsi le bleu de rang, qui est la signature la plus reconnaissable
   de ce gabarit, sous un chiffre de rang gris reste en place. Pire, un `**` ferme
   avant la ponctuation donnait UN SEUL h2 EN DEUX COULEURS.
   Les 26 titres sont depouilles a la source ; cette regle protege les suivants. */
.prose h1 strong,.prose h2 strong,.prose h3 strong,.prose h4 strong{font:inherit;color:inherit}
.prose em{font-style:italic}

/* ⚠️ DEUX ELEMENTS QUE LE PIPELINE EMET ET QUE LA FEUILLE IGNORAIT. Releve sur les
   23 articles publies : 54 <code> et 25 <blockquote>, soit 79 occurrences qui
   tombaient sur le rendu par defaut du navigateur. */

/* <code> : sans regle, ces 54 occurrences du corpus tombaient sur la chasse fixe
   SYSTEME, l'interdit que la charte nomme avec sa mesure -- 38,6 % d'ecart de
   chasse entre SF Mono et Menlo. Le retrait de cet interdit est le seul acquis de
   cette regle, et composer un litteral de protocole en chasse fixe est par
   ailleurs typographiquement juste.

   ⚠️ CE N'EST PAS LA SIGNATURE DE LA MAISON, et j'avais pretendu le contraire.
   Deux mesures le refusent. Au flou de 3,2 px, le peigne de la chasse fixe est
   EFFACE : meme pas dominant que le meme texte en Inter (4 px), 6 % d'ecart de
   modulation, 0,8 % d'ecart d'ecart-type sur le paragraphe. Un objet qu'on ne
   distingue pas de son voisin ne signe rien. Et le test 2 de la § 11 ter echoue
   frontalement : « la valeur change-t-elle d'un client a l'autre ? » --
   List-Unsubscribe est le meme nom d'en-tete pour tous les expediteurs du monde.
   Ce n'est pas « la politique DMARC », qui varie avec le domaine : c'est le mot.
   Le refus du test 3 sur l'article n'est donc PAS leve.

   14px et non 0,875em : 0,875em rendait 15,75 px a 1440 et 14 a 390, soit un role
   a deux corps dont l'un n'est pas dans l'echelle declaree -- 26 / 16 / 14,
   « Aucun autre corps ». C'est le « 15 px invente » de tarifs, recommis.
   box-decoration-break:clone : par defaut la pastille se BRISE au retour a la
   ligne, et le second code rendait deux fragments a 1440, 768, 390 et 320. */
/* ⚠️ UN BLOC DE CODE DEFILE DANS SON CADRE, IL NE POUSSE PAS LA PAGE. `<pre>` porte
   `white-space:pre` : son contenu ne se coupe jamais, et une ligne de configuration DNS
   de 75 signes deborde donc la fenetre. Mesure a 390 px sur `spf-dkim-dmarc-guide-
   complet`, qui en compte dix : 396 px de debord, la page entiere decalee.
   ⚠️ ET CE DEFAUT PRECEDE LA NAVIGATION QUE JE VENAIS D'AJOUTER -- verifie en revenant
   au commit anterieur, meme 396 px. J'ai failli l'attribuer a mon propre geste.
   Meme traitement que `.tableau` : le debordement est confie a l'objet, pas a la page. */
.prose pre{overflow-x:auto;max-width:100%;margin:0 0 24px;padding:16px 20px;
  background:var(--fond-alt);border-radius:var(--rayon-s);font-size:14px;line-height:1.5}
.prose pre code{background:none;padding:0;font-size:inherit}
.prose code,.tableau code{font-family:var(--police-donnee);font-weight:500;
  font-size:14px;color:var(--encre-titre);background:var(--fond-alt);
  padding:.1em .35em;border-radius:var(--rayon-s);word-break:break-word;
  -webkit-box-decoration-break:clone;box-decoration-break:clone}

/* <blockquote> : c'est l'« En bref » qui ouvre chaque article, son propre resume,
   rendu jusqu'ici en simple retrait de navigateur. Il tient la mesure comme un
   paragraphe, mais a un corps superieur et sous un filet de marque : le premier
   ecran de l'article, le moins tenu du panel au flou, y gagne un second objet. */
.prose blockquote{margin:0 0 32px;padding:0 0 0 20px;max-width:var(--mesure);
  border-left:3px solid var(--bleu)}
/* Le « En bref » renonce a son corps propre : sa distinction est deja portee par son
   filet et sa graisse, et c'est le seul blockquote de la page -- il n'y a donc pas
   d'echelon « citation » a preserver, seulement un quatrieme niveau qui aplatissait
   l'echelle. */
.prose blockquote p{margin:0;font-size:18px;line-height:1.55;color:var(--encre-titre)}
.prose blockquote strong{font-weight:600}
/* ⚠️ UNE IMAGE DE PROSE NE DEBORDE PAS. Sans cette regle, les logos de la page de
   mentions legales sortaient du document de 340 px a 320 et de 270 a 390 : ils
   viennent de WordPress a leur taille native, 300 px, dans une colonne qui en fait
   280. Le defaut n'est pas propre a cette page -- il attendait les 184 articles a
   porter, dont beaucoup portent des captures. */
.prose img{max-width:100%;height:auto}
.prose figure{margin:0 0 24px}
/* ⚠️ UNE URL BRUTE EN LIBELLE DE LIEN EST UN MOT DE 60 SIGNES SANS ESPACE. Deux
   articles herites de WordPress en portent, et a 320 px ils poussaient la page de
   188 px. `overflow-wrap:anywhere` autorise la coupure a l'interieur du mot, ce que
   `break-word` seul ne fait pas quand le mot tient dans une ligne isolee. */
.prose a{color:var(--bleu-encre);text-decoration:underline;text-underline-offset:2px;
  overflow-wrap:anywhere}
.prose a:hover{color:var(--bleu-profond)}

/* Encadre de mise en garde : un filet a gauche, jamais un aplat de marque.
   Un aplat ici disputerait le premier ecran au H1 sans porter d'argument. */
.encadre{border-left:3px solid var(--bleu);background:var(--fond-alt);
  padding:18px 22px;border-radius:0 var(--rayon-m) var(--rayon-m) 0;margin:0 0 24px}
.encadre p{margin:0;font-size:18px}
.encadre p+p{margin-top:12px}

.sommaire{background:var(--fond-alt);border:1px solid var(--filet);
  border-radius:var(--rayon-m);padding:20px 24px;margin:0 0 32px;max-width:var(--mesure)}
.sommaire h2{font-size:16px;margin:0 0 12px;letter-spacing:0}
.sommaire ol{margin:0;padding-left:20px;font-size:16px;line-height:1.6}
.sommaire li{margin-bottom:6px}
.sommaire a{color:var(--encre);text-decoration:none}
.sommaire a:hover{color:var(--bleu-encre);text-decoration:underline}


/* Tableau de donnees dans un article : il defile, donc il porte son degrade
   de bord, comme toute zone a defilement horizontal. */
.tableau{overflow-x:auto;margin:0 0 24px;max-width:var(--mesure);
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 24px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 24px),transparent)}
.tableau table{width:100%;border-collapse:collapse;font-size:16px;min-width:460px}
.tableau th,.tableau td{padding:12px 16px;text-align:left;border-bottom:1px solid var(--filet)}
/* L'EN-TETE SE REPLIE. `white-space:nowrap` faisait passer la largeur minimale du
   pire tableau du corpus -- 6 colonnes, « meilleurs-logiciels-emailing-francais »
   -- a 925 px, quel que soit le corps : mesure identique a 16 et a 14 px, ce qui
   prouve que le texte ne commandait pas. Replie, le meme tableau descend a
   780 px, et a 707 px si le corps passe a 14. Sur les 136 tableaux du corpus, 120 font
   deux ou trois colonnes et ne sont pas concernes ; les 16 autres cessent de cacher
   153 px de leur contenu.
   ⚠️ CE COMPTE DISAIT « 33 tableaux, 27 » jusqu'au 31/08/2026, et le vrai releve donne
   136 et 120. Le raisonnement tenait, son assiette etait fausse d'un facteur quatre :
   un commentaire qui justifie une regle par un denombrement doit porter le bon.
   Le `nowrap` avait ete pose pour tenir les intitules sur une ligne ; il tenait
   surtout la largeur du tableau au-dessus de sa colonne. */
.tableau thead th{background:var(--fond-alt);font-weight:600;color:var(--encre-titre)}
.tableau td:first-child{font-weight:500}
/* ⚠️ UN TABLEAU A SIX COLONNES OU PLUS SE RESSERRE, SINON IL CACHE SON CONTENU LA OU
   RIEN N'ANNONCE QU'IL DEFILE. Le comparatif de `comparatifs/logiciel-emailing` fait
   912 px dans une mesure de 812 a 1 440 : sa septieme colonne, un concurrent nomme,
   etait coupee EN PLEIN MOT sur ses neuf lignes -- « Autom… », « ~49 $… ». Le champ
   defile bien et le masque de 24 px est la, mais 24 px pour signaler 100 px de contenu
   manquant ne se voit pas : le directeur artistique lui-meme a conclu qu'il n'y avait
   aucun degrade. Un indice qu'un oeil exerce ne perçoit pas n'est pas un indice.
   La largeur vient du rembourrage bien plus que du texte : sept colonnes depensent
   224 px en marges internes. A 14 px de corps et 8 px de rembourrage lateral -- deux valeurs de l'echelle,
   la ou 15 et 10 en sortaient : CHARTE.md consigne que « le 15 px invente de la page
   tarifs est corrige », il n'avait pas a revenir ici -- le meme
   tableau tombe a 812 et ne defile plus du tout au-dessus de 1 024. En dessous il
   defile encore, et c'est normal : la, le lecteur s'y attend.
   ⚠️ `:has()` N'ETAIT EMPLOYE NULLE PART DANS CETTE FEUILLE. Il l'est ici parce que la
   condition est le NOMBRE DE COLONNES, que seul le DOM connait : le hook de tableau
   s'applique a tout tableau markdown et ne peut pas poser de classe selon sa forme.
   Deux tableaux du corpus sont concernes sur 136 : 18 en 2 colonnes,
   102 en 3, 11 en 4, 3 en 5, 1 en 6 et 1 en 7. */
.tableau table:has(thead th:nth-child(6)){font-size:14px}
.tableau table:has(thead th:nth-child(6)) th,
.tableau table:has(thead th:nth-child(6)) td{padding:12px 8px}
/* ⚠️ ET LE MASQUE SE RETIRE LA OU IL N'Y A RIEN A REVELER. `.tableau` le porte sans
   condition. Tant que le tableau debordait, il etait seulement trop faible ; une fois
   le tableau ramene dans sa mesure, il devient MENTEUR : a 1 440, avec zero pixel
   cache, la derniere colonne finit a 0 px du bord et tombe donc entierement dans le
   degrade. Il effacait « ActiveCampaign » dans un tableau dont l'objet est de nommer
   les concurrents.
   ⚠️ 1 102 px, ET LE SEUIL EST MESURE PAR DICHOTOMIE, PAS CHOISI. C'est la fenetre a
   partir de laquelle le tableau a sept colonnes cesse de deborder : a 1 101 il cache
   encore 1 px, a 1 102 il en cache zero. Ce n'est pas un cran du systeme, et c'est
   voulu -- la valeur ne decrit pas une intention de mise en page, elle decrit un fait
   de contenu, et un cran arrondi la trahirait dans un sens ou dans l'autre. Trop haut,
   le masque ment sur une bande de fenetres ou rien n'est cache ; trop bas, il
   disparait alors qu'il y a quelque chose a reveler, ce qui est pire.
   ⚠️ LE SEUIL DEPEND DU CORPS ET DU REMBOURRAGE CI-DESSUS. A 15 px et 10 px il valait
   1 200 ; a 14 px et 8 px il tombe a 1 102. Toucher aux deux lignes precedentes sans
   remesurer celle-ci rend le masque incoherent, ce qui s'est produit une fois : la
   bande 1 102-1 199 gardait un masque devenu inutile. */
@media(min-width:1102px){
  .tableau:has(thead th:nth-child(6)){-webkit-mask-image:none;mask-image:none}
}

@media(max-width:767px){
  .prose{font-size:16px}
  /* ⚠️ LE SUBORDONNE PESAIT PLUS QUE SON TITRE, en mobile seulement. Au plissement de
     3,2 px, « Questions frequentes » en bleu s'effaçait pendant que les H3 noirs qui le
     suivent tenaient. Mesure en MASSE -- surface du texte x encre, mesuree sur les
     rectangles du Range et jamais sur la boite : H2 / H3 rendait 0,81.

     La cause est mecanique : le H3 ne changeait pas d'echelle entre les deux formats,
     20 px des deux cotes, pendant que le H2 descendait de 28 a 22. Et le H2 est en
     --bleu-encre quand le H3 est en --encre-titre : a corps egal, le bleu pese moins.
     L'ecart de corps doit donc compenser l'ecart d'encre, et il ne le faisait plus.

     ⚠️ J'AI D'ABORD MESURE LE PIC, ET C'ETAIT LE MAUVAIS CRITERE. Le pic ne bouge
     pratiquement pas : 0,94 a H2 22, 0,97 a 24, 0,98 a 26, et la graisse du H3 n'y change
     RIEN -- 600 ou 500, meme valeur. C'est normal, le pic d'un texte floute est fixe par
     sa couleur, et aucun corps ne rend un bleu plus sombre qu'un presque-noir. J'allais
     en conclure que le defaut etait chromatique et irreparable au corps. Le rendu
     compare, avant et apres, dit le contraire : c'est la MASSE qui decide de ce qu'on
     lit comme titre, pas le pic.

     H2 22 -> 24 (la valeur mobile de la charte), H3 20 -> 18. Masse H2/H3 : 0,81 -> 1,23
     a 320, 1,23 a 360, 1,24 a 390. Et H1/H2 reste decroissant partout : 1,41 / 1,86 /
     2,21 -- le 320 est le cas serre, le H1 y tombe a 25,8 px. Cout : +19 px de document
     sur 14 658, soit 0,13 %. */
  .prose h2{font-size:24px;margin-top:36px}
  .prose h3{font-size:18px}
  /* ⚠️ SANS CETTE LIGNE, h3 ET h4 SONT LE MEME OBJET EN MOBILE. h3 descend a 18, h4
     restait a sa valeur desktop de 18 : meme fonte, meme corps, meme graisse, meme
     encre. L'echelle annoncait quatre crans et en rendait trois -- exactement le
     defaut qu'on venait de corriger sur desktop, deplace d'un point de rupture.
     17 px garde h4 au-dessus du corps, qui est a 16. */
  .prose h4{font-size:17px}
  /* ⚠️ REGRESSION INTRODUITE PAR LA PASSE PRECEDENTE, retiree ici. En desktop le
     « En bref » est passe de 20 a 18 pour RENONCER a son corps propre et rejoindre celui
     de la prose. En mobile le corps est a 16, pas a 18 : le meme 18 px y ouvrait un cran
     vacant au lieu d'en fermer un. Avant la passe, mobile faisait 22 / 20 / 20 / 16,
     trois crans distincts ; avec 18 il en faisait quatre -- 22 / 20 / 18 / 16, rapports
     1,10 / 1,11 / 1,125. Le « En bref » renonce donc a son corps aux DEUX formats. */
  .prose blockquote p{font-size:16px}
}

/* LE FILET DE SECTION : CE QUI ROMPT LE RUBAN.
   Mesure a 390x844 sur cet article : 9 622 px de document -- 65,6 % du total -- sans
   UN SEUL objet non textuel entre la fin du tableau et le pied. Onze fenetres et demie
   de texte d'affilee. En deux colonnes le meme passage n'est jamais nu : la colonne
   laterale longe le texte, elle borne le regard en permanence. Empilee en haut de page,
   elle ne borne plus rien passe le premier ecran, et le gabarit mobile se retrouve sans
   aucun objet d'articulation. C'est le sens exact de « le mobile n'est pas un gabarit,
   c'est un desktop empile » : le desktop a un objet que le mobile a perdu, et personne
   ne l'a remplace.

   L'OBJET DE REMPLACEMENT NE S'INVENTE PAS, IL EXISTE DEJA. Le rang de section est
   l'objet d'affichage du gabarit ; il est pose en compteur CSS, donc present dans les
   23 articles sans un geste par article -- ce que le pipeline interdit de toute facon.
   Il lui manquait seulement d'etre un OBJET et pas un chiffre pose dans le flux. Le
   filet le fait : il traverse la colonne de lecture, il tient au flou de 3,2 px la ou
   un chiffre en --encre-douce s'efface, et il se lit comme ce qu'il est -- l'ouverture
   d'une section.

   ⚠️ ET IL NE COUTE PAS UN PIXEL, ce qui est la condition : une page ne gagne rien a
   s'allonger. L'air au-dessus d'un H2 vaut 36 px (marge haute 36 contre la marge basse
   de 20 du paragraphe qui precede, fusionnees). Le filet le REDECOUPE au lieu de s'y
   ajouter : marge 20 -- qui fusionne exactement avec les 20 du paragraphe -- plus 1 px
   de filet, plus 15 px de retrait. 20 + 1 + 15 = 36. Meme calcul sur la FAQ, dont la
   marge propre vaut 44 : 28 + 1 + 15 = 44.

   ⚠️ LA SPECIFICITE EST EGALE, DONC C'EST L'ORDRE QUI TRANCHE, et c'est pour cela que
   ce bloc est ICI et pas plus haut. `.prose h2` et `.prose>h2` pesent tous deux 0-1-1 :
   pose avant le bloc des 767 px, `margin-top:20px` aurait ete ecrase par le
   `margin-top:36px` qui y vit, et le filet se serait ajoute au lieu de decouper.

   ⚠️ ET LE FILET A 1 PX EN --filet NE TENAIT PAS AU FLOU, ce qui aurait fait de la
   reparation une declaration. Encre mesuree sur le rendu floute a 3,2 px, en pixels-
   equivalents-noirs sur la colonne de lecture, pic de la ligne du filet contre pic
   d'une ligne de texte du meme cadre (44 a 65) :

     1 px --filet ................  4   soit 6 % d'une ligne de texte
     2 px --filet ................  8   12 %
     2 px --bordure-composant ....  34  52 %
     3 px --bleu .................  76  117 %
     48 x 4 px --bleu, filet court  14  21 %

   `--bordure-composant` et non `--filet` : c'est deja l'arbitrage rendu pour la
   boite des certifications, ou `--filet` s'effaçait sur son fond -- le jeton existe
   pour les bords qui doivent SE VOIR. Et non `--bleu` : a 117 % d'une ligne de texte,
   le filet pesait plus que le titre qu'il introduit, neuf fois par article, et il
   depensait la marque sur du mobilier. 52 % : present, subordonne.

   Resultat mesure : plus grand intervalle sans objet non textuel 9 622 -> 1 544 px,
   de 65,6 % a 10,5 % du document. */
@media(max-width:1079px){
  .prose>h2{border-top:2px solid var(--bordure-composant);padding-top:14px;margin-top:20px}
  .prose>h2.hors-rang{margin-top:28px}
}


/* ------------------------------------------------------------------
   Bloc de ressources : les derniers articles.

   Il portait quatre vignettes carrees de 300 px. Empilees sur mobile,
   elles pesaient 1 200 px a elles seules -- 15 % de la page entiere --
   pour des illustrations de banque en violet et beige, etrangeres aux
   jetons, sur une page dont l'argument est la donnee reelle honnetement
   etiquetee. Le bloc entier occupait 26,5 % du mobile, plus que le hero.

   Elles cedent la place a de la matiere editoriale : categorie, titre,
   accroche tiree de la description reelle de l'article, duree de lecture.
   La fonction du bloc -- le maillage interne vers les articles -- est
   intacte, et il ne dispute plus la page.
   ------------------------------------------------------------------ */
/* Le milieu de page enchainait quatre sections blanches sur 1 970 px, soit 38,5 %
   du document, sans un aplat ni une image : au plissement, ce tiers de page etait
   interchangeable avec n'importe quel concurrent. Le fond alterne rend trois
   masses la ou il n'y en avait qu'une, sans allonger la page d'un pixel.
   Et la duree de lecture passe en chasse fixe : c'est une donnee mesuree, pas un
   argument, et elle porte la signature a 71 % du document au lieu de 22 % --
   une signature qu'on ne revoit jamais apres le premier quart n'est pas la marque
   d'un site, c'est une caracteristique de hero. */
.ressources{background:var(--fond-alt)}
.ressources h2{margin-bottom:8px}
.ressources>.conteneur>p{color:var(--encre-douce);max-width:var(--mesure)}
.billets{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;margin-top:28px}
/* Bord en --bordure-composant et non --filet : sur --fond-alt, --filet rend
   1,193:1 et disparait au flou. Meme raison que pour .preuve-obj. */
.billet{display:flex;flex-direction:column;background:var(--fond);
  border:1px solid var(--bordure-composant);border-radius:var(--rayon-m);
  padding:22px 24px 20px;text-decoration:none;color:inherit;
  transition:box-shadow .15s ease,border-color .15s ease}
.billet:hover{box-shadow:var(--ombre-m);border-color:var(--neutre-1)}
.billet .cat{font-size:14px;font-weight:600;color:var(--bleu-encre);margin-bottom:8px}
.billet h3{font-size:18px;line-height:1.35;letter-spacing:-.011em;
  color:var(--encre-titre);margin:0 0 10px}
.billet p{font-size:16px;line-height:1.55;color:var(--encre-douce);margin:0}
/* Repoussee en bas de carte : les accroches n'ont pas la meme longueur, et
   sans cela les durees de lecture se decalent d'une carte a l'autre. */
/* ⚠️ CETTE DUREE ETAIT EN CHASSE FIXE, et c'etait la meme chaine composee de deux
   facons dans la meme feuille : « 12 min de lecture » en JetBrains Mono ici,
   « 11 min de lecture » en Inter sur .article-meta.

   La charte a tranche : la chasse fixe a trois emplois et la liste est fermee --
   la signature a 26 px sur donnee possedee, <code>, et le contact du bandeau. Une
   duree de lecture n'est aucun des trois. Ce n'est donc pas .article-meta qui
   manquait une signature, c'est celle-ci qui n'en etait pas une.

   Trois choses s'alignent : la meme chaine s'ecrit pareil aux deux endroits ; les
   quatre durees d'une meme section cessent de violer la portee de la signature ; et
   sur l'accueil la chasse fixe ne designe plus que ce que le client possede.
   La perte est nulle a distance de lecture : a 14 px, le rythme a chasse fixe ne
   survit pas au flou de 3,2 px, mesure faite. */
.billet .duree{margin-top:auto;padding-top:14px;font-size:14px;font-weight:500;
  color:var(--encre-titre)}
/* PAGINATION DU BLOG. RIEN N'EST INVENTE ICI, et c'est la contrainte qu'on s'est
   donnee : la charte ne definit pas ce composant et les quatre maquettes de
   reference n'en portent aucun. Tout vient donc de `.barre-rubriques`, qui est le
   voisin exact -- une file de liens courts posee sous un titre de page, dont un
   est courant. Meme fonte, meme corps, meme graisse, meme interlettrage, meme
   couleur au repos, meme survol.
   Le marqueur de la page courante est LITTERALEMENT celui de la barre de rubriques
   et du sommaire lateral : filet de 3 px en `--bleu`, rayon 2 px, a -6 px. Le site
   portait cette regle en deux exemplaires ; elle en a trois, et cesse d'etre une
   coincidence pour devenir deductible.
   Le pas vertical est celui de la grille qu'elle ferme, 28 px, repris de
   `.billets{margin-top:28px}`. Aucun jeton nouveau, aucune valeur nouvelle. */
.pagination{display:flex;flex-wrap:wrap;column-gap:24px;row-gap:10px;margin-top:28px}
.pagination a,.pagination span{font-family:var(--police-corps);font-size:14px;
  font-weight:600;letter-spacing:.28px;text-decoration:none;color:var(--encre-douce)}
.pagination a:hover{color:var(--bleu-encre);text-decoration:underline}
/* La page courante n'est pas un lien -- un lien vers la page qu'on regarde deja
   n'a pas de destination -- donc le selecteur porte sur l'attribut, pas sur span. */
.pagination [aria-current]{color:var(--encre-titre);position:relative}
.pagination [aria-current]::after{content:"";position:absolute;left:0;right:0;
  bottom:-6px;height:3px;background:var(--bleu);border-radius:2px}
@media(max-width:599px){.pagination{column-gap:18px}}
@media(max-width:1023px){.billets{grid-template-columns:repeat(2,1fr)}}
@media(max-width:479px){
  .billets{grid-template-columns:1fr;gap:14px}
  /* Une colonne : quatre accroches empilees ajoutaient 600 px pour une aide a la
     decision que le titre porte deja. Elles sortent, la duree de lecture reste. */
  .billet p{display:none}
  .billet{padding:18px 20px 16px}
  .billet .duree{padding-top:10px}
}


/* ------------------------------------------------------------------
   Carrousel de logos clients.

   Le defilement est en CSS, sans script : la piste porte deux fois la
   serie et se translate de sa moitie exacte, ce qui boucle sans saut.

   ⚠️ L'ANIMATION EST COUPEE SOUS prefers-reduced-motion, et cette clause
   n'est pas seulement une politesse d'accessibilite : elle rend la page
   CAPTURABLE. Une piste animee se photographie a un decalage arbitraire,
   donc deux captures du meme fichier ne se ressemblent pas. Sous mouvement
   reduit, la piste redevient une zone a defilement horizontal ordinaire,
   figee a son origine -- et elle porte alors son degrade de bord, que la
   charte exige de toute zone a defilement, sans exception.

   Les logos restent en couleur. Une desaturation cumulee a une opacite
   reduite est le grief releve sur le site d'origine.

   ⚠️ LA HAUTEUR COMMUNE N'UNIFORMISE PAS, et l'affirmation inverse a figure
   ici. Les dix CANEVAS font bien 450x200, mais l'encre qu'ils contiennent
   non : sa boite va de 449x65 pour France Adresses a 201x199 pour So Muse,
   soit des rapports de 6,91 a 1,01. A hauteur de case egale, la hauteur
   d'encre rendue s'etale de 14,3 a 43,8 px, RAPPORT 3,06. Au flou de 3,2 px
   les plus plats disparaissent quand les plus carres tiennent. Uniformiser
   demande de normaliser l'ENCRE, pas le canevas -- ce que cette feuille ne
   fait pas encore.
   ------------------------------------------------------------------ */
/* Bande resserree et son titre ramene au rang d'etiquette : elle est remontee
   dans le premier ecran, ou chaque pixel qu'elle prend est un pixel de moins
   pour l'aplat de marque qui la suit. Un « ils nous ont fait confiance » en H2
   de section disputait la hierarchie au H1 a deux cents pixels de la. */
/* ⚠️ 8 PX SOUS LES LOGOS ET NON 28, POUR RENDRE SES CHIFFRES A LA BANDE SUIVANTE.
   L'agrandissement du CTA de hero a pousse tout ce qui le suit de 20 px, et ces 20 px
   ont franchi un seuil : la ligne des quatre nombres a 48 px, ENTIEREMENT visible au
   pli de 1000, s'est retrouvee tranchee a mi-hauteur -- « 4 000+ » lisible a 62,6 %
   contre 100 %. Des chiffres tranches sont pires que des chiffres absents : c'est un
   accident de mise en page, pas une invitation a defiler.
   ⚠️ ET L'ERREUR ETAIT DE CHERCHER LES 20 PX SOUS LE BOUTON. Les 74 px qui l'y suivent
   ne rendent rien, la hauteur du hero n'est pas commandee par la. Le rembourrage du
   hero, lui, est une formule fluide indexee sur la fenetre : y toucher deferait la
   composition. Ici la valeur est statique, elle est sur l'echelle, et elle rend
   exactement les 20 px empruntes.
   La bande bleue porte ses propres 40 px de rembourrage haut : l'air entre le dernier
   logo et le premier chiffre reste de 48 px. */
.clients{padding:24px 0 8px;overflow:hidden}
.clients h2{font-family:var(--police-corps);font-size:14px;font-weight:500;
  line-height:1.3;letter-spacing:.02em;color:var(--encre-douce);margin-bottom:16px}
.clients-fenetre{position:relative;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 72px,#000 calc(100% - 72px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 72px,#000 calc(100% - 72px),transparent)}
/* L'intervalle est porte par les logos, pas par la piste. `gap` ne pose rien
   apres le dernier : la piste mesurait alors 10 largeurs + 19 intervalles, la
   copie commencait un demi-intervalle trop tot, et la translation de -50 %
   raccordait a 28 px pres -- un saut lateral visible a chaque tour de 44 s.
   En marge de droite, la piste vaut 10 largeurs + 20 intervalles et -50 %
   tombe exactement sur la copie. (Mesure : couture +28 px avant, 0 px apres,
   a 1440 px, animation figee, polices chargees.) */
.clients-piste{display:flex;align-items:center;width:max-content;
  animation:defilement-clients 44s linear infinite}
.clients-fenetre:hover .clients-piste,
.clients-piste:focus-within{animation-play-state:paused}
/* GESTE 6 — ON NORMALISE L'ENCRE, PAS LE CANEVAS. Les fichiers partageaient un
   canevas de 450x200, ce qui ne dit rien de ce qu'ils contiennent : la boite
   d'encre allait de 450x65 a 201x200, soit des rapports de 6,92 a 1,00, et la
   hauteur d'encre rendue de 14,3 a 44,0 px -- rapport 3,08. Au flou, quatre des
   dix disparaissaient quand deux tenaient seuls.

   ⚠️ Trois normalisations ont ete essayees et MESUREES avant celle-ci.
   Par l'AIRE : laisse un rapport de hauteur de 2,90, car a aire egale un logo
   large est mecaniquement plus plat. Par la MASSE d'encre : So Muse demanderait
   d'etre double et France Adresses elargi de 41 %, tous deux bloques par le
   canevas. Par famille SUR CANEVAS FIXE : rapport de hauteur 2,62 mais masse
   degradee de 8,13 a 8,94, France Adresses etant bute sur la largeur.
   Aucune ne pouvait aboutir tant que le canevas dictait l'echelle.

   Les fichiers ne portent donc plus que leur encre, detouree, et c'est la feuille
   qui porte la regle. Trois familles de rapport, trois hauteurs. */
.clients-piste img{width:auto;flex:0 0 auto;display:block;margin-right:56px}
.clients-piste .logo-large{height:26px}
.clients-piste .logo-moyen{height:32px}
.clients-piste .logo-carre{height:36px}
@keyframes defilement-clients{from{transform:translateX(0)}to{transform:translateX(-50%)}}

@media(prefers-reduced-motion:reduce){
  .clients-fenetre{overflow-x:auto;scrollbar-width:none;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 48px),transparent);
    mask-image:linear-gradient(90deg,#000 calc(100% - 48px),transparent)}
  .clients-fenetre::-webkit-scrollbar{display:none}
  .clients-piste{animation:none}
  /* La copie ne sert qu'a boucler l'animation. Sans elle retiree, une piste
     figee montrerait chaque logo deux fois a qui la fait defiler. */
  .clients-piste img[aria-hidden]{display:none}
}
@media(max-width:767px){
  /* Meme raison qu'au-dessus : l'intervalle se porte en marge, sinon il
     s'ajoute a celui de la regle de base et rouvre la couture (20 px ici). */
  .clients-piste img{margin-right:40px}
  .clients-piste .logo-large{height:22px}
  .clients-piste .logo-moyen{height:27px}
  .clients-piste .logo-carre{height:30px}
}

/* ------------------------------------------------------------------
   Bloc de cloture, avant le pied.

   La page n'en avait pas : un seul bouton plein sur toute sa hauteur,
   celui du hero, et 3 278 px sans aucun bouton en desktop, 6 875 px en
   mobile. Le visiteur qui lisait jusqu'au bout n'avait plus rien a
   cliquer.

   ⚠️ IL A D'ABORD ETE POSE SUR --bleu-voile, ET C'ETAIT UNE FAUTE. Ce
   fond rend 1,007:1 contre celui du pied : sept millieres d'ecart. Avec
   le filet qui les separe a 1,193:1, les 819 px de fin de page -- 19 %
   du document -- formaient une seule masse grise. La charte condamne
   nommement 1,018:1 en ecrivant « la luminance ne le delimite pas ». Le
   bloc reparait un trou en n'existant pas.

   Il prend donc le SECOND et dernier aplat de marque que la charte
   autorise. 4,56:1 contre le pied, la separation est franche. Et le
   raisonnement qui l'en avait ecarte -- « deux bandes bleues se
   repeteraient » -- etait a cote du probleme : 92,7 % du document est a
   moins de 1,09:1 du blanc, la page manque de valeur, elle n'en a pas
   de trop.

   ⚠️ LE CTA N'EST PAS ORANGE ICI, ET C'EST MESURE. --action sur --bleu
   rend 1,018:1, le seuil meme que la charte condamne : le bouton serait
   separe par la seule teinte et disparaitrait au flou. L'effet de rappel
   avec le hero ne survit pas a la mesure -- un bouton orange sur bleu
   n'est pas le meme objet qu'un bouton orange sur blanc. Il passe donc
   en inverse, blanc sur bleu, a 4,94:1.
   ------------------------------------------------------------------ */
/* GESTE 3 — UNE REGLE D'OCCUPATION COMMUNE AUX BANDES PLEINE LARGEUR.
   Les deux seuls aplats de marque de la page laissaient leur moitie droite vide :
   la ligne d'action des chiffres occupait 48,6 % de ses 1 160 px, et le texte de
   cloture s'arretait a 772 px sur 1 200, laissant 408 px de vide bleu sur 253 px
   de haut. Dans du blanc un vide ne se voit pas ; DANS UN APLAT il se voit.
   Les deux bandes ancrent desormais leurs deux bords : le propos a gauche,
   l'action a droite. */
.cloture{background:var(--bleu);color:#fff;padding:72px 0}
.cloture .conteneur{display:grid;grid-template-columns:1fr auto;gap:56px;align-items:center}
.cloture-propos{min-width:0}
.cloture-agir{min-width:0}
.cloture h2{color:#fff;margin-bottom:12px}
.cloture-texte{color:#fff;font-size:18px;max-width:var(--mesure);margin:0}
.cloture-actions{display:flex;flex-wrap:wrap;gap:16px 28px;align-items:center;margin:28px 0 0}
.cloture-2{color:#fff;font-weight:500;text-decoration:underline;text-underline-offset:3px}
/* --bleu-voile sur du blanc rend 1,091:1 ENTRE LES DEUX ETATS : un survol
   invisible n'est pas un survol. L'encre reste blanche -- rien n'est plus clair
   sur un aplat de marque -- et c'est le trait qui double. */
.cloture-2:hover{color:#fff;text-decoration-thickness:2px}
.cloture-note{margin:22px 0 0;font-size:14px;color:#fff}

/* justify-content et non text-align : .btn est en inline-flex, ou text-align
   n'a aucun effet sur un item flex. Le libelle etait cale a gauche entre 360 et
   479 px -- 28 px a gauche contre 186 a droite -- alors que le bouton du hero,
   qui emploie justify-content trois lignes plus haut, etait centre au pixel. */
@media(max-width:1023px){
  .cloture .conteneur{grid-template-columns:1fr;gap:32px}
}
@media(max-width:479px){
  .cloture{padding:48px 0}
  .cloture-actions{gap:14px}
  .cloture-actions .btn{width:100%;justify-content:center}
}

/* ------------------------------------------------------------------
   Modules de la plateforme, et liste d'avantages.

   ⚠️ NI L'UN NI L'AUTRE N'EST UN PANNEAU BORDE ARRONDI. La page en
   comptait deja quinze, tous a 8 px de rayon et 1 px de bord : preuve,
   billets, certifs, cartes, cadre, encart. En ajouter quatre de plus
   appauvrirait le vocabulaire au moment meme ou l'on enrichit le
   contenu. Un filet superieur de marque suffit a delimiter un module,
   et une puce carree a rythmer une liste.
   ------------------------------------------------------------------ */
.modules{display:grid;grid-template-columns:repeat(4,1fr);gap:32px;margin:36px 0 0}
/* Le quatrieme lien pendait 24 px sous les trois autres, constant de 1280 a
   1920 : les accroches n'ont pas la meme longueur et rien ne calait les liens. */
.module{border-top:2px solid var(--bleu);padding-top:18px;display:flex;flex-direction:column}
.module a{margin-top:auto}
.module h3{font-size:18px;line-height:1.35;margin:0 0 8px}
.module p{color:var(--encre-douce);font-size:16px;line-height:1.55;margin:0 0 12px}
.module a{font-size:16px;font-weight:500;color:var(--bleu-encre);text-decoration:none}
.module a:hover{text-decoration:underline}

.sous-titre{font-family:var(--police-titre);font-size:18px;font-weight:600;
  color:var(--encre-titre);margin:56px 0 24px;letter-spacing:-.011em}

.avantages{list-style:none;padding:0;margin:28px 0 0;display:grid;gap:11px}
.avantages li{position:relative;padding-left:24px;font-size:16px;line-height:1.55;
  color:var(--encre)}
.avantages li::before{content:"";position:absolute;left:0;top:.5em;
  width:9px;height:9px;background:var(--bleu);border-radius:2px}
.avantages b{font-weight:600;color:var(--encre-titre)}

/* Les trois temps d'un argument : la promesse, ce qui la tient, ce qu'elle
   rapporte. Le troisieme est en bleu d'encre, pas en gris : c'est la seule
   ligne des trois qui parle du client et non du produit. */
.arg .promesse{font-size:18px;font-weight:500;color:var(--encre-titre);margin:0 0 8px}
.arg .benefice{font-size:16px;font-weight:500;color:var(--bleu-encre);margin:10px 0 0}

@media(max-width:1023px){.modules{grid-template-columns:repeat(2,1fr);gap:28px}}
@media(max-width:479px){.modules{grid-template-columns:1fr;gap:24px}}

/* Point d'action apres un tableau comparatif. Le tableau pose un argument
   « nous contre eux » et le laissait sans suite : sur la page produit, il n'y
   avait que deux boutons pleins pour 71 % de hauteur sans aucun. */
.apres-table{display:flex;flex-wrap:wrap;align-items:center;gap:14px 24px;margin:32px 0 0}
.apres-table span{font-size:14px;color:var(--encre-douce)}
@media(max-width:479px){
  .apres-table .btn{width:100%;justify-content:center}
}


/* Sous 360 px, les libelles de CTA passaient sur deux lignes : 46 px de texte
   dans une boite haute de 44. Laisser le bouton grandir reglait le debordement
   mais poussait le CTA du hero SOUS LE PLI a 320x568 -- une reparation qui en
   casse une autre. On rend au libelle la place de tenir sur une ligne : la
   gouttiere passe de 28 a 14 px, ce qui rend 28 px, et le corps a 15 px. */
@media(max-width:359px){
  .btn{padding:0 14px;font-size:14px}
}

/* La signature du pied portait son corps en style EN LIGNE, hors de toute
   echelle et hors de portee de la garde des jetons. C'est par la qu'une echelle
   derive : six paliers de corps y etaient nes, dont trois hors charte. */
.pied-signature{color:var(--encre-douce);font-size:14px;max-width:34ch}

/* GESTE 1 — LA SIGNATURE COUVRE LA PAGE DE BOUT EN BOUT.
   Sa derniere occurrence etait a 71 % du document ; les 29 % restants -- logos,
   engagements, cloture, pied -- n'en portaient aucune, et la premiere n'arrivait
   qu'au deuxieme ecran. Le contact du bandeau haut la porte desormais au pixel 0.

   Surtout, elle devient DEDUCTIBLE au lieu d'etre constatable. Deux emplois
   isoles ne font pas une regle : trois contextes en font une. Contact,
   infrastructure, mesure -- un identifiant reel est en chasse fixe, une quantite
   d'argumentaire est en fonte de corps. « Compte gratuit : 1 000 mails par mois »
   reste donc en Inter dans le meme bandeau, a deux centimetres : c'est le
   voisinage qui rend la regle lisible. */
/* graisse 500 : seule cette face de JetBrains Mono est chargee. Sans elle la
   specification disait 400 et le rendu tombait sur 500 par substitution -- rendu
   juste, specification fausse. C'est mot pour mot le defaut corrige sur
   .billet .duree et laisse ici, sur les quatre pages. */
/* ⚠️ `>` ET NON UNE DESCENDANCE, ET CE CHEVRON VAUT LA SIGNATURE DU SITE.
   Ecrite `.bandeau span:nth-child(-n+2)`, cette regle etait un selecteur de
   DESCENDANCE : le jour ou le troisieme span a recu un `<span class="bandeau-long">`
   pour masquer sa mention longue sous 768 px, ce nouveau span s'est trouve PREMIER
   ENFANT DE SON `<a>` -- donc `:nth-child(1)`, donc attrape. Mesure : « : 1 000 emails
   par mois » rendait 205 px en JetBrains Mono la ou Inter en fait 157, +30 % de chasse,
   au milieu d'un libelle souligne, sur les 17 pages et 100 % du trafic desktop.

   Le commentaire ci-dessus dit mot pour mot que cette mention DOIT rester en Inter, et
   que « c'est le voisinage qui rend la regle lisible ». Le voisinage disait l'inverse :
   trois mentions en chasse fixe cote a cote, dont un chiffre d'argumentaire que la
   charte range explicitement hors de cet emploi. La seule signature typographique
   revendiquee du site se demontait elle-meme au pixel 0 de chaque page.

   Une regle de position qui vise des enfants directs s'ecrit avec `>`. Sans lui, elle
   ne decrit pas une place dans une fratrie, elle decrit « premier de n'importe quelle
   fratrie sous ce toit » -- et elle attend le prochain balisage imbrique pour se
   tromper de cible. */
.bandeau .conteneur>span:nth-child(-n+2){font-family:var(--police-donnee);font-weight:500;
  letter-spacing:.01em}

/* LE MENU SE REPLIE SOUS 600 PX -- 2 septembre 2026.
   Le <nav> vit dans un <details class="menu" open> dont le <summary> est le burger.
   Au-dessus de 600 px : summary masque, le details tient la place que la nav tenait
   (flex item de l'en-tete, pleine largeur en rang 3 sous 1024). Sous 600 px, avec
   script (`html.js`, pose dans <head>) : le bouton seul reste sur la ligne du logo, le
   panneau se pose en absolu sous l'en-tete et n'y pousse rien ; les trois familles y
   sont depliees a plat, leurs tetes deviennent des intitules, et le bouton d'appel de
   l'en-tete (masque : il ne tenait pas sur 280 px avec le logo et le burger) reparait
   en bas du panneau (`.nav-cta`). Sans script : tout reste en flux sous le logo, deplie,
   l'etat d'avant avec un bouton « Menu » en plus -- le sens de la panne est choisi.
   ⚠️ `html.js details.menu[open]:not([data-pret])>nav{display:none}` : sans cette
   ligne le panneau ouvert s'affiche une image avant que menu.js ne le ferme.
   Mesure avant : bandeau + en-tete = 194 px a 390 (23 % de 844), 222 a 320 (26 %). */
details.menu{display:block;min-width:0}
/* ⚠️ EXPLICITE, ET PAS SEULEMENT PAR L'UA. Chrome rend le contenu d'un <details> ferme
   avec une boite (content-visibility), donc un scrollWidth : debord-mobile mesurait
   « nav 139 px dans 101 » sur un menu que personne ne voyait. */
details.menu:not([open])>nav{display:none}
details.menu>summary.burger{display:none;list-style:none}
details.menu>summary.burger::-webkit-details-marker{display:none}
header nav .nav-cta{display:none}
@media(max-width:1023px){
  header details.menu{order:3;width:100%}
}
@media(max-width:599px){
  header{position:relative}
  header .conteneur{gap:16px}
  header .btn-2{display:none}
  html.js header details.menu{order:0;width:auto;flex:none}
  details.menu>summary.burger{display:inline-flex;align-items:center;gap:10px;height:44px;
    padding:0 14px;border:1px solid var(--bordure-composant);border-radius:var(--rayon-s);
    color:var(--encre);font-size:16px;font-weight:500;cursor:pointer;user-select:none}
  details.menu>summary.burger:hover{color:var(--bleu-encre)}
  details.menu>summary.burger:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
  .burger-trait{position:relative;display:block;width:18px;height:2px;background:currentColor;
    transition:background 150ms}
  .burger-trait::before,.burger-trait::after{content:"";position:absolute;left:0;width:18px;height:2px;
    background:currentColor;transition:transform 200ms}
  .burger-trait::before{top:-6px}
  .burger-trait::after{top:6px}
  details.menu[open] .burger-trait{background:transparent}
  details.menu[open] .burger-trait::before{transform:translateY(6px) rotate(45deg)}
  details.menu[open] .burger-trait::after{transform:translateY(-6px) rotate(-45deg)}
  /* le panneau, avec ou sans script : une colonne, sans masque ni defilement */
  header details.menu>nav{flex-direction:column;align-items:stretch;gap:0;width:auto;
    overflow:visible;-webkit-mask-image:none;mask-image:none;margin-top:0;padding:8px 0 0}
  header nav a{white-space:normal}
  header details.menu>nav>a{padding:12px 0;border-top:1px solid var(--filet);font-size:16px}
  header .nav-groupe{flex-direction:column;align-items:stretch;padding:10px 0 6px}
  header .nav-groupe+.nav-groupe{border-top:1px solid var(--filet)}
  header .nav-tete{font-size:13px;font-weight:600;letter-spacing:.02em;color:var(--encre-douce);
    pointer-events:none;cursor:default}
  header .nav-tete::after{display:none}
  header .sous-panneau{display:grid;grid-template-rows:1fr;flex-basis:auto;width:auto;margin:6px 0 0}
  header .sous-menu{padding:0;border-left:0}
  header .sous-menu a{padding:9px 0;font-size:16px}
  header nav .nav-cta{display:inline-flex;justify-content:center;margin:16px 0 4px}
  /* avec script : en absolu sous l'en-tete, et voile jusqu'a ce que menu.js ait tranche */
  html.js header details.menu>nav{position:absolute;left:0;right:0;top:100%;z-index:20;
    background:#fff;border-top:1px solid var(--filet);border-bottom:1px solid var(--filet);
    box-shadow:var(--ombre-m);padding:8px 20px 20px}
  html.js header details.menu[open]:not([data-pret])>nav{display:none}
}
