/* =========================================================================
   SOCLE « BASCULE » — feuille commune aux deux univers.
   Extrait de interieur.html : aucune regle n'est dupliquee entre PRO et
   PARTICULIER, seuls les jetons changent.
   ========================================================================= */

/* =========================================================================
   LES DEUX UNIVERS. Une seule feuille, deux jeux de jetons, choisis par
   l'attribut `data-univers` sur <html>. C'est le mecanisme que le theme
   WordPress reprendra tel quel : aucune regle n'est dupliquee.

   Chaque arret des degrades porteurs de texte blanc tient au moins 4,5 :
     PRO  #2B5BE0 5,7 · #7B3FD4 6,0 · #C2410C 5,2
     PART #C2410C 5,2 · #B03A6E 5,8 · #2B5BE0 5,7
   ========================================================================= */
:root[data-univers="pro"]{
  --acc:#2B5BE0; --acc-vif:#4C7DFF; --acc-clair:#8FB4FF; --acc-voile:#EAF0FF;
  --sec:#FF8A2B; --sec-fonce:#C2410C; --sec-clair:#FFC489; --sec-voile:#FFF1E4;
  --autre:#FF9A44;                       /* la couleur de l'autre univers */
  --signal:linear-gradient(100deg,#2B5BE0 0%,#7B3FD4 52%,#C2410C 100%);
  --signal-90:linear-gradient(90deg,#2B5BE0 0%,#7B3FD4 55%,#FF8A2B 100%);
  --signal-180:linear-gradient(180deg,#8FB4FF 0%,#2B5BE0 34%,#7B3FD4 68%,#FF8A2B 100%);
  --signal-clair:linear-gradient(100deg,#4C7DFF 0%,#A78BFA 50%,#FF8A2B 100%);
  --signal-nuit:linear-gradient(100deg,#8FB4FF 0%,#C9B8FF 46%,#FFC489 100%);
  --nuee-1:#D7E4FF; --nuee-2:#FFE1C6; --nuee-3:#E6D9FF;
  --mediane:#A78BFA;      /* l'arret central des degrades */
}
:root[data-univers="part"]{
  --acc:#C2410C; --acc-vif:#F97316; --acc-clair:#FDBA74; --acc-voile:#FFF3E8;
  --sec:#4C7DFF; --sec-fonce:#2B5BE0; --sec-clair:#8FB4FF; --sec-voile:#EAF0FF;
  --autre:#4C7DFF;
  --signal:linear-gradient(100deg,#C2410C 0%,#B03A6E 50%,#2B5BE0 100%);
  --signal-90:linear-gradient(90deg,#C2410C 0%,#B03A6E 55%,#4C7DFF 100%);
  --signal-180:linear-gradient(180deg,#FDBA74 0%,#C2410C 34%,#B03A6E 68%,#4C7DFF 100%);
  --signal-clair:linear-gradient(100deg,#F97316 0%,#E0629B 50%,#4C7DFF 100%);
  --signal-nuit:linear-gradient(100deg,#FDBA74 0%,#F0A9CE 46%,#8FB4FF 100%);
  --nuee-1:#FFE1C6; --nuee-2:#D7E4FF; --nuee-3:#FFD9E8;
  --mediane:#E0629B;
}

/* =========================================================================
   DIRECTION « BASCULE » — univers PROFESSIONNELS.
   -------------------------------------------------------------------------
   Le contenu vient du corpus (_refonte/corpus/accueil-pro.md), dans son
   ORDRE d'origine. Rien n'est invente, rien n'est reordonne.

   Troisieme passe, apres « ca manque d'effet de section enchaine ». Le
   probleme n'etait pas le style des sections mais leur ISOLEMENT : sept
   blocs poses bout a bout, chacun commencant a zero. Trois dispositifs les
   relient desormais :

     1. LE FIL. Un trait vertical court le long de toute la page, se remplit
        au defilement et allume un noeud a chaque section atteinte. Il donne
        au visiteur la carte de la page et relie physiquement les blocs.
     2. LES COUTURES. Aucune section ne commence par un bord droit : peigne
        de tiges, diagonale, ou remontee de la nuit. La section suivante
        mord toujours sur la precedente.
     3. LA CONTINUITE DU MOTIF. Le champ de tiges du portail traverse la
        page : en 3D dans la tete, en CSS dans les coutures et derriere les
        chiffres. C'est le meme objet, vu de plusieurs facons.

   Trois regles tenues, comme sur le portail :
     - rien ne nait invisible : aucune animation ne part d'`opacity: 0` ;
     - la page est complete sans WebGL, sans JavaScript, au clavier ;
     - zero appel a un tiers : Three.js, Outfit et les 21 logos sont ici.
   ========================================================================= */

@font-face{font-family:'Outfit';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('vendor/fonts/outfit-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Outfit';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('vendor/fonts/outfit-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}

:root{

  --encre:#070A12; --encre-2:#0B1223; --encre-3:#0E1830;
  --papier:#FFFFFF; --papier-2:#F3F6FC; --trait:#D9E0EC;
  --texte:#0D1420; --texte-2:#43536D;

  /* L'ORANGE. Il etait reserve a l'univers Particulier ; il devient la
     couleur d'energie commune a IF2M. Les deux univers restent distincts par
     leur couleur DOMINANTE — bleu ici, ambre en face — pas par exclusivite.
     avec du blanc : tout texte blanc sur orange emploie la version foncee. */

  /* Les degrades. Chaque arret d'un degrade portant du texte blanc tient
     au moins 4,5 : #2B5BE0 → 5,7 · #7B3FD4 → 6,0 · #C2410C → 5,2. */
  --r:18px;
  --t:cubic-bezier(.22,.61,.36,1);
  --ressort:cubic-bezier(.34,1.56,.64,1);
  --accgression:0;              /* 0 → 1, ecrit par le script au defilement */

  /* Les ombres : jamais du noir pur, toujours teintees de l'encre. */
  --ombre-1:0 1px 2px rgba(13,20,32,.05), 0 6px 18px -12px rgba(13,20,32,.22);
  --ombre-2:0 2px 6px rgba(13,20,32,.06), 0 30px 60px -34px rgba(13,20,32,.55);
}

/* Le grain. 1,4 Ko de SVG en ligne, aucune requete. Il casse le lisse des
   degrades — sans lui, un aplat large « bande » sur les grands ecrans. */
body::after{content:"";position:fixed;inset:0;z-index:90;pointer-events:none;opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")}

/* Le fond « nuee » : trois taches de couleur diffuses au lieu d'un blanc
   plat. C'est ce qui fait la difference entre une page propre et une page
   dessinee, et ca ne coute aucune image. */
.nuee{background:
  radial-gradient(42% 38% at 10% 4%, var(--nuee-1) 0%, transparent 66%),
  radial-gradient(38% 34% at 92% 10%, var(--nuee-2) 0%, transparent 68%),
  radial-gradient(46% 42% at 74% 96%, var(--nuee-3) 0%, transparent 68%),
  var(--papier)}
.nuee-2{background:
  radial-gradient(40% 40% at 86% 6%, var(--nuee-2) 0%, transparent 66%),
  radial-gradient(44% 40% at 6% 88%, var(--nuee-1) 0%, transparent 68%),
  var(--papier-2)}
*,*::before,*::after{box-sizing:border-box}
/* La barre d'action collee au bas de l'ecran mesure ~90 px sous 820 px :
   sans reserve basse, le navigateur amene l'element « dans le viewport » et
   le laisse DERRIERE elle — l'anneau de focus devient invisible. */
html{scroll-behavior:smooth;scroll-padding-top:5.5rem;scroll-padding-bottom:6.5rem}
body{margin:0;background:var(--papier);color:var(--texte);
  font-family:'Outfit',system-ui,-apple-system,'Segoe UI',sans-serif;font-weight:350;
  font-size:clamp(1rem,.4vw + .92rem,1.09rem);line-height:1.62;-webkit-font-smoothing:antialiased;
  overflow-x:hidden}
img{max-width:100%;height:auto}
h1,h2,h3{line-height:1.03;letter-spacing:-.03em;margin:0;font-weight:300}
h2{font-size:clamp(2rem,4.6vw,3.9rem)}
h3{font-size:1.22rem;font-weight:500;letter-spacing:-.015em;line-height:1.2}
p{margin:0}
.large{width:min(1240px,100% - 2.5rem);margin-inline:auto}
.etroit{width:min(780px,100% - 2.5rem);margin-inline:auto}
section{padding-block:clamp(3.6rem,8vw,7rem);position:relative}
.oeil{font-size:.75rem;letter-spacing:.26em;text-transform:uppercase;font-weight:600;color:var(--acc);
  display:flex;align-items:center;gap:.6rem}
.oeil::before{content:"";width:2.4rem;height:2px;border-radius:2px;flex:0 0 auto;
  background:var(--signal-clair)}
.nuit .oeil::before{background:var(--signal-nuit)}
.nuit .oeil{color:var(--acc-clair)}
.nuit{background:var(--encre);color:#fff}

/* =========================================================================
   1. LE FIL — la colonne vertebrale de la page
   ========================================================================= */
/* =========================================================================
   2. LES COUTURES — aucune section ne commence par un bord droit
   ========================================================================= */
/* Le peigne : les tiges du portail, vues de face, qui montent dans la nuit. */
.couture-peigne{position:absolute;left:0;right:0;height:clamp(70px,9vw,130px);pointer-events:none;z-index:1}
.couture-peigne::before{content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(90deg,transparent 0 8px,currentColor 8px 10px,transparent 10px 19px)}
.couture-peigne--haut{top:0;color:color-mix(in oklab,var(--acc-clair) 34%,transparent)}
.couture-peigne--haut::before{-webkit-mask-image:linear-gradient(180deg,#000,transparent);mask-image:linear-gradient(180deg,#000,transparent)}
.couture-peigne--bas{bottom:0;color:color-mix(in oklab,var(--acc-clair) 30%,transparent)}
.couture-peigne--bas::before{-webkit-mask-image:linear-gradient(180deg,transparent,#000);mask-image:linear-gradient(180deg,transparent,#000)}
/* La diagonale : la section suivante mord sur la precedente. */
.couture-diagonale{clip-path:polygon(0 clamp(28px,4.2vw,74px),100% 0,100% 100%,0 100%);
  margin-top:calc(-1 * clamp(28px,4.2vw,74px))}
.couture-diagonale-inv{clip-path:polygon(0 0,100% clamp(28px,4.2vw,74px),100% 100%,0 100%);
  margin-top:calc(-1 * clamp(28px,4.2vw,74px))}

/* =========================================================================
   En-tete
   ========================================================================= */
/* Le fond de l'en-tete etait assez transparent pour que le contraste des
   liens depende de ce qui defile dessous : mesure a 4,01 sur certaines
   zones grises, et 2,94 pour la rubrique active. Un fond n'est pas une
   variable d'ambiance quand du texte est pose dessus. */
/* C9 — la pile du site : .remonter 45 < .barre-action 46. Le panneau du
   mega menu doit passer au-dessus des deux. .entete est collee en haut, ils
   sont colles en bas : ils ne se recouvrent jamais, la montee est donc sans
   condition — et sans :has(), que Firefox ne connait que depuis la 121. */
.entete{position:sticky;top:0;z-index:47;background:rgba(255,255,255,.94);
  backdrop-filter:blur(20px) saturate(1.4);border-bottom:1px solid transparent;
  transition:background .35s var(--t),border-color .35s var(--t),box-shadow .35s var(--t)}
/* L'en-tete ne s'annonce qu'une fois qu'on a quitte le haut : au repos elle
   flotte sur l'en-tete sombre, ensuite elle se pose sur le papier. */
.entete.posee{background:rgba(255,255,255,.98);border-bottom-color:var(--trait);box-shadow:var(--ombre-1)}
.entete .rang{display:flex;align-items:center;gap:.9rem;padding-block:.65rem;
  transition:padding .35s var(--t)}
.entete.posee .rang{padding-block:.42rem}
.logo{display:flex;align-items:baseline;gap:.45rem;text-decoration:none;color:var(--texte);
  font-weight:700;font-size:1.25rem;letter-spacing:-.03em;flex:0 0 auto}
.logo span{font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:var(--acc);font-weight:700}
.menu{display:flex;gap:.05rem;margin-left:auto;flex-wrap:nowrap}
.menu a{padding:.44rem .5rem;border-radius:9px;text-decoration:none;color:var(--texte-2);
  font-size:.845rem;font-weight:450;white-space:nowrap;transition:background .2s,color .2s}
.menu a:hover,.menu a:focus-visible{background:var(--acc-voile);color:var(--acc)}
.menu a[aria-current]{color:var(--acc);font-weight:600}
.bascule-lien{display:inline-flex;align-items:center;gap:.45rem;padding:.42rem .8rem;border-radius:99px;
  border:1px solid var(--trait);text-decoration:none;color:var(--texte-2);font-size:.82rem;white-space:nowrap}
.bascule-lien:hover{border-color:var(--autre);color:var(--sec-fonce);
  background:color-mix(in oklab,var(--autre) 12%,#fff)}
.bascule-lien i{width:.5rem;height:.5rem;border-radius:50%;background:var(--autre);display:inline-block}
/* Au telephone, l'intitule long faisait passer la pastille sur son propre
   rang et l'en-tete tenait sur trois lignes. */
.bascule-lien .court{display:none}
@media (max-width:560px){
  .bascule-lien .long{display:none}
  .bascule-lien .court{display:inline}
}
/* ---------------------------------------------------------------------
   A. LE MÉGA MENU — « le plan de l'atelier »
   Le panneau est un <details> natif : sans JavaScript il s'ouvre au clic,
   au clavier, et tous les liens restent atteignables. Le script n'ajoute
   que l'ouverture au survol et la fermeture par Échap.
   ------------------------------------------------------------------ */
.menu--mega{align-items:center;gap:.04rem}
.menu--mega .mm-simple{padding:.44rem .46rem;border-radius:9px;text-decoration:none;
  color:var(--texte-2);font-size:.82rem;font-weight:450;white-space:nowrap;
  transition:background .2s,color .2s}
.menu--mega .mm-simple:hover,.menu--mega .mm-simple:focus-visible{background:var(--acc-voile);color:var(--acc)}
.menu--mega .mm-simple[aria-current]{color:var(--acc);font-weight:600}

/* CINQ ENTREES AU LIEU DE NEUF : la barre tombe de 770 a 527 px (mesure a
   1280 px, interieur.html). Le seuil ou l'intitule long de la pastille doit
   ceder passe donc de 1360 a 1080 px. Mesure du pire cas — pvente.html, dont
   la pastille dit « La boutique, cote particuliers » : le rang y demande
   936 px, et `.large` en offre 1040 a 1080 px de viewport. */
@media (max-width:1080px){
  .bascule-lien .long{display:none}
  .bascule-lien .court{display:inline}
}
/* `.menu a` pose white-space:nowrap — juste pour les entrees de la BARRE, faux
   pour tout ce qui vit dans un panneau. Mesure a 390 px, tiroir ouvert,
   panneau « Se faire connaitre » : le titre « Affichage dynamique et ecran
   interactif » et « Nos realisations sur les reseaux sociaux » sortaient de
   57 px, et `overflow-x:hidden` sur le tiroir les COUPAIT en plein mot au lieu
   de les signaler — la page ne debordait pas, le controle passait au vert. */
.mm-panneau a{white-space:normal}
.mm-groupe{position:static}
.mm-groupe:not([open])>.mm-panneau{display:none}
.mm-titre{display:inline-flex;align-items:center;gap:.24rem;padding:.44rem .46rem;
  border-radius:9px;color:var(--texte-2);font-size:.82rem;font-weight:450;
  white-space:nowrap;cursor:pointer;list-style:none;user-select:none;
  transition:background .2s,color .2s}
.mm-titre::-webkit-details-marker{display:none}
.mm-titre:hover,.mm-titre:focus-visible{background:var(--acc-voile);color:var(--acc)}
.mm-titre:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.mm-groupe[open]>.mm-titre{background:var(--acc-voile);color:var(--acc);font-weight:600}
.mm-titre svg{width:.58rem;height:.58rem;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;
  transition:transform .28s var(--t)}
.mm-groupe[open]>.mm-titre svg{transform:rotate(180deg)}

/* Le panneau. `.entete` porte un backdrop-filter : elle est donc déjà le
   bloc conteneur de ses descendants absolus. On s'y ancre, pleine largeur. */
.mm-panneau{position:absolute;left:0;right:0;top:100%;
  background:var(--papier);border-top:1px solid var(--trait);
  border-bottom:1px solid var(--trait);box-shadow:var(--ombre-2);
  padding-block:1.8rem 1.5rem;max-height:calc(100vh - 5rem);overflow-y:auto;
  background-image:
    radial-gradient(34% 60% at 6% 0%,var(--nuee-1) 0%,transparent 70%),
    radial-gradient(30% 60% at 96% 8%,var(--nuee-2) 0%,transparent 72%),
    radial-gradient(40% 70% at 62% 100%,var(--nuee-3) 0%,transparent 70%),
    linear-gradient(var(--papier),var(--papier))}
/* AUCUNE PISTE DE CE MENU N'EST DIMENSIONNEE PAR SON CONTENU : partout
   `minmax(0,1fr)`, jamais `1fr`. `1fr` vaut `minmax(auto,1fr)`, et ce minimum
   `auto` est le min-content de la colonne : un mot trop long, une adresse, un
   libelle qui ne se coupe pas, et la piste devient plus large que le panneau
   qui la contient. Mesure a 390 px avant correction : 330,7 px de piste dans
   un conteneur de 273,2. Le garde-fou reste meme une fois la cause traitee. */
.mm-plan{display:grid;gap:1.4rem 2.6rem;
  grid-template-columns:minmax(15rem,20rem) minmax(0,1fr);align-items:start}
.mm-tete{display:grid;grid-template-columns:auto 1fr;gap:1rem;align-items:start}
.mm-glyphe{width:72px;height:72px;flex:0 0 auto;color:var(--acc);
  fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.mm-oeil{font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;font-weight:700;
  color:var(--texte-2);margin:0 0 .3rem}
.mm-pilier{display:inline-flex;align-items:baseline;gap:.45rem;font-size:1.3rem;
  font-weight:600;letter-spacing:-.025em;color:var(--texte);text-decoration:none;line-height:1.14}
/* LA REGLE PRECEDENTE NE POSE NI COULEUR NI GRAISSE NI TAILLE, et c'est un
   piege de specificite : le titre vit dans `.menu`, ou `.menu a` (0,1,1)
   surclasse `.mm-pilier` (0,1,0). Mesure a 1280 px avant correction : le titre
   de colonne rendait rgb(67,83,109) en graisse 450 pendant que les mots
   d'appel de sa PROPRE liste rendaient rgb(13,20,32) en graisse 600 — la
   hierarchie sur laquelle repose toute la composition a trois colonnes etait
   exactement inversee, et le seul titre correct etait celui du 3e panneau,
   parce que c'est un <p class="mm-theme"> que `.menu a` n'atteint pas.
   Tout ce qui doit gagner passe donc par (0,2,0). La taille reste tenue par
   `.mm-colonne .mm-pilier`, pose plus bas a specificite egale ; le survol
   reste celui de `.menu a:hover` (0,2,1), volontairement. */
.menu--mega .mm-pilier{color:var(--texte);font-weight:600;font-size:1.3rem}
.mm-pilier:hover{color:var(--acc)}
/* « L'atelier » est un THEME, pas un pilier : il n'a pas de page a lui. Son
   titre a donc le poids d'un titre de pilier, sans etre un lien. */
.mm-theme{margin:0;font-size:1.3rem;font-weight:600;letter-spacing:-.025em;
  color:var(--texte);line-height:1.14}
.mm-resume{margin:.5rem 0 0;font-size:.87rem;line-height:1.5;color:var(--texte-2);max-width:34ch}
/* Hors colonne — c'est-a-dire dans « L'atelier », le seul panneau a tete unique
   — la liste tient en DEUX colonnes serrees, remplies DE HAUT EN BAS. Le
   remplissage par rangs (le defaut de la grille) faisait lire les huit entrees
   en zigzag, et `auto-fill` sur 1fr ecartait les deux colonnes de 400 px. Une
   liste se lit vers le bas. Quatre rangs : c'est le partage des huit entrees
   en 4 + 4. */
.mm-liste{list-style:none;margin:0;padding:0 0 0 2.4rem;display:grid;gap:.15rem .9rem;
  grid-template-rows:repeat(4,auto);grid-auto-flow:column;
  grid-auto-columns:minmax(0,20rem);justify-content:start;
  border-left:1px solid var(--trait)}

/* --- LES COLONNES DE PILIER --------------------------------------------
   Trois piliers dans un panneau, ce n'est pas trois listes collees. Chaque
   pilier tient une COLONNE : son dessin, son nom, sa phrase, puis ses pages.
   L'oeil traverse les tetes, choisit sa colonne, puis descend. Le filet qui
   separe deux colonnes est pose au MILIEU de la gouttiere par un pseudo, et
   non en border-left : sinon les colonnes n'ont plus la meme largeur utile. */
.mm-plan--3{grid-template-columns:repeat(3,minmax(0,1fr));align-items:stretch}
/* Deux piliers seulement, et huit liens en tout : le plan doit s'arreter la ou
   le contenu s'arrete. Il garde donc la largeur de `.large` et n'occupe que
   DEUX de ses TROIS pistes — jamais un `max-width` sur ce meme element, qui
   porte aussi `.large`, donc `margin-inline:auto` : le retrecir ne l'arrete
   pas a gauche, il le fait GLISSER vers la droite. Mesure avant correction,
   bord gauche du premier bloc : 176 px a 1280, 256 a 1440, 496 a 1920, contre
   20 / 100 / 340 pour le logo — soit 156 px de saut de tout le contenu du
   panneau, bande de pied comprise, en passant d'un theme a l'autre.
   Trois pistes plutot que deux, aussi, pour que les colonnes tombent
   exactement sur celles du panneau a trois piliers. */
.mm-plan--2{grid-template-columns:repeat(3,minmax(0,1fr));align-items:stretch}
.mm-colonne{position:relative;display:grid;grid-template-columns:minmax(0,1fr);
  align-content:start;gap:.55rem}
.mm-colonne+.mm-colonne::before{content:"";position:absolute;left:-1.3rem;top:.1rem;bottom:.1rem;
  width:1px;background:var(--trait)}
.mm-colonne .mm-pilier{display:grid;grid-template-columns:auto minmax(0,1fr);gap:.7rem;align-items:center;
  font-size:1.05rem;letter-spacing:-.02em;line-height:1.2}
.mm-colonne .mm-glyphe{width:42px;height:42px}
.mm-colonne .mm-nom i{font-style:normal;color:var(--acc);display:inline-block;
  transition:transform .24s var(--t)}
.mm-colonne .mm-pilier:hover .mm-nom i{transform:translateX(3px)}
/* min-height de DEUX lignes : sans elle, la phrase d'un pilier tient sur une
   ligne, celle du voisin sur deux, et les trois listes ne demarrent plus a la
   meme hauteur. On lit alors trois listes cote a cote, pas une composition. */
.mm-colonne .mm-resume{margin:0;font-size:.81rem;line-height:1.45;max-width:40ch;
  min-height:2.9em}
/* Dans une colonne de pilier, la liste est deja la colonne : un seul rang de
   large, remplie par rangs. On defait le remplissage par colonnes pose plus
   haut pour « L'atelier ». */
.mm-colonne .mm-liste{grid-template-columns:minmax(0,1fr);grid-template-rows:none;
  grid-auto-flow:row;grid-auto-columns:auto;gap:0;padding:.45rem 0 0;
  border-left:0;border-top:1px solid var(--trait);margin-top:.15rem}
/* UN LIBELLE EST UNE PHRASE, PAS DEUX COLONNES. Le lien etait un conteneur
   flex : le mot en gras et sa suite y devenaient deux elements cote a cote, et
   des que la place manquait ils se repliaient CHACUN de leur cote. Mesure a
   390 px : « Nos realisations sur les reseaux sociaux » se lisait sur deux
   colonnes de deux lignes. Le lien revient donc au flux normal, la pastille
   devient une PUCE PENDANTE : `text-indent` negatif de la largeur de la
   pastille plus son ecart (.32rem + .5rem = .82rem), retrait gauche d'autant
   en plus. La pastille pend dans la marge, toutes les lignes s'alignent, et
   le texte demarre au meme pixel qu'avant : 9,6 px de retrait + 5,12 de
   pastille + 8 d'ecart = 22,72 px, soit 1,42rem. Rien a recalculer quand le
   retrait change au tiroir — seul le padding-left suit. */
.mm-liste a{display:block;padding:.4rem .6rem .4rem 1.42rem;text-indent:-.82rem;
  border-radius:9px;text-decoration:none;color:var(--texte-2);font-size:.875rem;
  line-height:1.35;transition:background .18s,color .18s}
.mm-liste a::before{content:"";display:inline-block;text-indent:0;
  width:.32rem;height:.32rem;border-radius:50%;margin-right:.5rem;
  background:var(--acc-clair);translate:0 -.18em;transition:background .18s,scale .18s}
.mm-liste a:hover,.mm-liste a:focus-visible{background:var(--acc-voile);color:var(--acc)}
.mm-liste a:hover::before{background:var(--sec-fonce);scale:1.5}
/* Un lien du menu qui traverse vers l'autre univers porte la pastille de
   l'autre univers. `.db-autre::before` seule perdait contre `.mm-liste
   a::before`, plus specifique : la pastille restait de la couleur d'ici et
   seul le libelle disait le passage. */
.mm-liste a.db-autre::before{background:var(--autre)}
.mm-liste a.db-autre:hover::before{background:var(--autre)}
/* Le flux normal donne une espace de mot la ou la grille flex donnait .5rem :
   on rend l'ecart, sinon le mot d'appel se colle a sa suite. */
.mm-liste a b{font-weight:600;color:var(--texte);margin-right:.25rem}
.mm-liste a:hover b{color:var(--acc)}
/* LA PAGE COURANTE. `.mm-liste a b` (0,2,0) bat la couleur HERITEE de
   `.menu a[aria-current]` (0,1,1) : le mot d'appel reste noir. Une entree dont
   TOUT le libelle tient dans le <b> — « Boutique », « Actualites » — ne portait
   donc aucune marque au bureau, le fond `[aria-current]` ne vivant que sous
   1024 px ; mesure sur pvente.html a 1280 px : lien rgb(43,91,224), <b>
   rgb(13,20,32), fond transparent. Sur un libelle a deux temps, seule la
   QUEUE virait au bleu et la tete restait noire. Meme demi-application au
   clavier : `:hover b` existait, `:focus-visible b` non — le meme lien ne se
   lisait pas pareil a la souris et au Tab. */
.mm-liste a[aria-current]{background:var(--acc-voile)}
.mm-liste a[aria-current] b,
.mm-liste a:focus-visible b{color:var(--acc)}
.mm-note{grid-column:1/-1;margin:0;font-size:.8rem;color:var(--texte-2)}
.mm-appui{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;
  justify-content:flex-start;gap:.55rem 1.4rem;
  margin-top:.4rem;padding-top:.9rem;border-top:1px solid var(--trait);
  font-size:.83rem;color:var(--texte-2)}
.mm-appui>*{flex:0 0 auto}
.mm-appui b{color:var(--texte);font-weight:600}
.mm-appui a{color:var(--acc);text-decoration:none;font-weight:500}
.mm-appui a:hover{text-decoration:underline}
.mm-appui .mm-tel{display:inline-flex;align-items:center;gap:.4rem;padding:.34rem .8rem;
  border-radius:99px;border:1px solid var(--trait);background:var(--papier);color:var(--texte)}
.mm-appui .mm-tel:hover{border-color:var(--acc);color:var(--acc);text-decoration:none}
/* Un pilier n'a pas de lien en barre : c'est un <summary>. Il se declare
   courant comme les autres entrees, sinon la barre ne dit jamais ou l'on est. */
.mm-titre[aria-current]{color:var(--acc);font-weight:600}


/* =========================================================================
   Tete : on est DANS le couloir, la 3D continue
   ========================================================================= */
.tete{position:relative;background:var(--encre);color:#fff;overflow:hidden;isolation:isolate;
  min-height:min(86vh,760px);display:grid;align-items:end;
  padding-block:clamp(4rem,11vw,8rem) clamp(3.5rem,8vw,6rem)}
#couloir{position:absolute;inset:0;z-index:-2;display:block;width:100%;height:100%}
.tete::before{content:"";position:absolute;inset:0;z-index:-3;
  background:
    repeating-linear-gradient(90deg,transparent 0 9px,color-mix(in oklab,var(--acc-vif) 30%,transparent) 9px 11px,transparent 11px 22px),
    radial-gradient(80% 70% at 50% 100%,color-mix(in oklab,var(--acc) 35%,transparent),transparent 65%),
    linear-gradient(180deg,#05080F,#0A1226);
  -webkit-mask-image:linear-gradient(180deg,transparent 12%,#000 70%);
  mask-image:linear-gradient(180deg,transparent 12%,#000 70%)}
/* LE VOILE DE LISIBILITE. Le texte de la tete vit dans la colonne GAUCHE ;
   les scenes 3D, elles, occupent toute la largeur. Sur six pages, l'objet
   passait sous le titre et sous le paragraphe — et la sonde de contraste ne
   pouvait pas le voir : elle lit les fonds CSS, le canevas WebGL lui est
   invisible. On garantit donc la lisibilite par construction, avec un voile
   horizontal du cote du texte, qui ne depend pas de ce que fait la scene. */
/* Sous 900 px le texte occupe TOUTE la largeur : un voile horizontal n'y peut
   rien, il faut donc assombrir franchement la bande ou il se pose. La scene
   reste lisible au-dessus et en dessous. */
.tete::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(7,10,18,.94) 0%,rgba(7,10,18,.86) 30%,
    rgba(7,10,18,.8) 62%,rgba(7,10,18,.9) 84%,rgba(7,10,18,.97) 100%)}
@media (min-width:900px){
  .tete::after{background:
    linear-gradient(90deg,rgba(7,10,18,.97) 0%,rgba(7,10,18,.93) 26%,rgba(7,10,18,.66) 44%,rgba(7,10,18,.18) 60%,transparent 72%),
    linear-gradient(180deg,rgba(7,10,18,.9) 0%,rgba(7,10,18,.32) 38%,rgba(7,10,18,.5) 72%,rgba(7,10,18,.96) 100%)}
  /* Le texte reste dans les deux premiers tiers : au-dela, la scene respire. */
  .tete h1,.tete .chapo{max-width:min(46rem,58%)}
}

/* =========================================================================
   LE MENU AU DOIGT
   -------------------------------------------------------------------------
   Neuf entrees dans 350 px : le menu defilait horizontalement, sans aucune
   affordance, et cinq entrees sur neuf etaient inatteignables. Le bouton est
   ajoute par le socle a l'execution, donc les 88 pages en beneficient sans
   qu'une seule ligne de balisage change.
   ========================================================================= */
.menu-bouton{display:none;align-items:center;justify-content:center;gap:.28rem;
  width:2.7rem;height:2.7rem;border-radius:11px;flex-direction:column;
  border:1px solid var(--trait);background:var(--papier);cursor:pointer;
  transition:.24s var(--t)}
.menu-bouton span{display:block;width:1.05rem;height:2px;border-radius:2px;background:var(--texte);
  transition:.28s var(--ressort)}
.menu-bouton:hover{border-color:var(--acc)}
.menu-bouton:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.entete.menu-ouvert .menu-bouton span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.entete.menu-ouvert .menu-bouton span:nth-child(2){opacity:0}
.entete.menu-ouvert .menu-bouton span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* Le fil d'Ariane est CLAIR par defaut et blanc seulement dans la tete
   sombre. Ecrit en blanc sans portee, il sortait invisible sur les 71 pages
   generees, dont le fond est du papier. Meme faute que le bouton contour. */
.fil-ariane{display:flex;gap:.55rem;align-items:center;flex-wrap:wrap;
  font-size:.8rem;color:var(--texte-2);margin-bottom:1.6rem}
.fil-ariane a{color:var(--acc);text-decoration:none}
.fil-ariane a:hover{text-decoration:underline}
.tete .fil-ariane{color:rgba(255,255,255,.5)}
.tete .fil-ariane a{color:rgba(255,255,255,.72)}
.tete .fil-ariane a:hover{color:#fff;text-decoration:none}
.tete h1{font-size:clamp(2.3rem,6.6vw,5.4rem);font-weight:200;max-width:17ch;margin-block:.6rem 1.1rem}
/* Le degrade du titre se DEPLACE, tres lentement. C'est le seul mouvement
   perpetuel de la page hors 3D, et il suffit a la rendre vivante. */
.tete h1 b{font-weight:500;background:var(--signal-nuit);background-size:220% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:derive 14s ease-in-out infinite alternate}
@keyframes derive{from{background-position:0% 0}to{background-position:100% 0}}
/* La lueur chaude : l'orange entre par la lumiere, pas par un aplat. */
.tete .halo{position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(38% 46% at 82% 22%,color-mix(in oklab,var(--sec) 34%,transparent),transparent 68%),
    radial-gradient(46% 52% at 8% 74%,color-mix(in oklab,var(--acc-vif) 32%,transparent),transparent 70%)}
.tete .chapo{color:rgba(255,255,255,.78);max-width:52ch;font-size:clamp(1.02rem,1.3vw,1.2rem)}
.boutons{display:flex;gap:.7rem;flex-wrap:wrap;margin-top:2.2rem}
.bouton{display:inline-flex;align-items:center;gap:.55rem;padding:.85rem 1.5rem;border-radius:99px;
  text-decoration:none;font-weight:500;font-size:.97rem;border:1px solid transparent;
  cursor:pointer;font-family:inherit;transition:.24s var(--t)}
/* Le degrade du bouton est double : le fond nominal reste un aplat bleu, de
   sorte qu'un navigateur sans `background-image` garde un contraste tenu. */
.bouton--plein{background-color:var(--acc);background-image:var(--signal);
  background-size:180% 100%;background-position:0 0;color:#fff}
.bouton--plein:hover{background-position:100% 0;transform:translateY(-2px);
  box-shadow:0 14px 32px -14px color-mix(in oklab,var(--sec-fonce) 70%,transparent)}
/* Le bouton contour est CLAIR par defaut et blanc seulement sur la nuit.
   L'inverse etait pose au depart, avec une exception `.clair` : des qu'il est
   apparu ailleurs — dans une carte tarifaire — il s'est retrouve blanc sur
   blanc, a 1,09 de contraste. Le defaut doit couvrir le cas le plus frequent. */
.bouton--fil{border-color:var(--trait);color:var(--texte);background:transparent}
.bouton--fil:hover{background:var(--papier-2);transform:translateY(-2px);border-color:var(--acc)}
.tete .bouton--fil,.nuit .bouton--fil{border-color:rgba(255,255,255,.3);color:#fff;background:transparent}
.tete .bouton--fil:hover,.nuit .bouton--fil:hover{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.55)}
/* La descente : un signe que la page continue. */
.descente{position:absolute;left:50%;bottom:1.4rem;translate:-50% 0;z-index:3;
  width:1px;height:2.6rem;background:linear-gradient(180deg,transparent,rgba(255,255,255,.6));overflow:hidden}
.descente::after{content:"";position:absolute;inset:0;background:var(--acc-clair);
  animation:goutte 2.4s var(--t) infinite}
@keyframes goutte{0%{transform:translateY(-100%)}60%,100%{transform:translateY(100%)}}

/* Le bandeau qui court sous la tete */
.bandeau{position:relative;z-index:2;background:var(--encre-3);
  border-block:1px solid color-mix(in oklab,var(--acc-clair) 18%,transparent);overflow:hidden;padding-block:.85rem}
.bandeau ul{display:flex;gap:2.6rem;margin:0;padding:0;list-style:none;white-space:nowrap;
  color:rgba(255,255,255,.62);font-size:.83rem;letter-spacing:.13em;text-transform:uppercase;
  animation:defile 34s linear infinite;width:max-content}
.bandeau li::before{content:"◆";color:var(--acc-vif);margin-right:.7rem;font-size:.6em;vertical-align:middle}
.bandeau li:nth-child(odd)::before{color:var(--sec)}
.marque:hover{border-color:var(--sec);background:var(--sec-voile)}
@keyframes defile{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* =========================================================================
   Services : colonne collante + mur de portes
   ========================================================================= */
.intro{display:grid;gap:1rem;max-width:64ch}
.intro p:not(.oeil){color:var(--texte-2);font-size:clamp(1.02rem,1.2vw,1.15rem)}
.nuit .intro p:not(.oeil){color:rgba(255,255,255,.76)}
.deux-colonnes{display:grid;gap:clamp(2rem,4vw,3.4rem);align-items:start}
@media (min-width:1080px){.deux-colonnes{grid-template-columns:minmax(280px,.82fr) 2fr}}
.colonne-collante{position:sticky;top:6.5rem;display:grid;gap:1.4rem}
.compteur-section{display:flex;align-items:baseline;gap:.5rem;font-weight:200;letter-spacing:-.04em;
  line-height:1}
.compteur-section b{font-size:clamp(3rem,5vw,4.6rem);font-weight:200;
  background:var(--signal);-webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent}
.compteur-section span{font-size:1.1rem;color:var(--texte-2)}

/* --- Les objets 3D animes ---------------------------------------------
   Deux scenes en plus du couloir. Chacune se met en pause des qu'elle sort
   de l'ecran, et le bloc entier disparait si WebGL manque : ce sont des
   ornements, jamais du contenu.                                        */
.scene-objet{display:block;width:100%;aspect-ratio:1/.86;border-radius:var(--r);
  background:
    radial-gradient(60% 60% at 30% 25%,var(--acc-voile),transparent 70%),
    radial-gradient(58% 58% at 76% 78%,var(--sec-voile),transparent 72%);
  border:1px solid var(--trait)}
.nuit .scene-objet,.manufacture .scene-objet{border-color:rgba(255,255,255,.14);
  background:
    radial-gradient(58% 58% at 28% 24%,color-mix(in oklab,var(--acc-vif) 20%,transparent),transparent 70%),
    radial-gradient(58% 58% at 78% 80%,color-mix(in oklab,var(--sec) 16%,transparent),transparent 72%)}
.socle-objet{position:relative}
/* La legende est posee sur une pastille : sans fond, elle passait sous
   l'objet et l'on n'en lisait plus que la moitie. */
.socle-objet figcaption{position:absolute;left:.8rem;bottom:.8rem;font-size:.7rem;
  letter-spacing:.16em;text-transform:uppercase;font-weight:600;color:var(--texte-2);
  background:rgba(255,255,255,.86);backdrop-filter:blur(6px);
  padding:.3rem .66rem;border-radius:99px;border:1px solid var(--trait);
  max-width:calc(100% - 1.6rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nuit .socle-objet figcaption,.manufacture .socle-objet figcaption{
  color:rgba(255,255,255,.82);background:rgba(10,15,31,.72);border-color:rgba(255,255,255,.16)}
@media (max-width:1079px){.colonne-collante .socle-objet{display:none}}

.mur{display:grid;gap:1.1rem;grid-template-columns:repeat(auto-fit,minmax(270px,1fr))}
/* La grille dictee par Cedric en reunion : Informatique en grand, puis Fibre
   et Telephonie cote a cote, Agence Web et Manufacture, Affichage et Mobile.
   Il faut DEUX colonnes strictes — en `auto-fit`, un ecran large en met trois
   et les paires qu'il a demandees ne sont plus des paires. */
@media (min-width:900px){ .mur--dicte{grid-template-columns:repeat(2,1fr)} }
/* La bordure est un DEGRADE, pas un trait gris : deux fonds superposes, l'un
   cale sur la boite interieure, l'autre sur la bordure. Aucun pseudo-element
   n'est mobilise, donc les deux restent libres pour la lumiere. */
.pOrte{--mx:50%;--my:0%;
  position:relative;display:flex;flex-direction:column;gap:.85rem;
  padding:1.7rem 1.6rem 1.5rem;text-decoration:none;color:inherit;
  border:1px solid transparent;border-radius:var(--r);
  background:
    linear-gradient(var(--papier),var(--papier)) padding-box,
    linear-gradient(140deg,color-mix(in oklab,var(--acc) 12%,#fff),color-mix(in oklab,var(--acc-clair) 22%,#fff) 46%,color-mix(in oklab,var(--sec) 18%,#fff)) border-box;
  box-shadow:var(--ombre-1);
  overflow:hidden;isolation:isolate;
  transition:transform .36s var(--ressort),box-shadow .36s var(--t),background .36s var(--t)}
.pOrte::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;z-index:-1;
  background:var(--signal-clair);
  transform:scaleX(0);transform-origin:left;transition:transform .42s var(--t)}
/* La lueur qui SUIT LE CURSEUR : la carte cesse d'etre une surface morte.
   Deux variables suffisent, ecrites au pointeur. */
.pOrte::after{content:"";position:absolute;inset:0;z-index:-2;opacity:0;
  background:
    radial-gradient(230px 230px at var(--mx) var(--my),color-mix(in oklab,var(--sec) 24%,transparent),transparent 70%),
    radial-gradient(360px 300px at calc(100% - var(--mx)) 120%,color-mix(in oklab,var(--acc-vif) 18%,transparent),transparent 72%);
  transition:opacity .4s var(--t)}
.pOrte:hover,.pOrte:focus-visible{transform:translateY(-7px);
  background:
    linear-gradient(var(--papier),var(--papier)) padding-box,
    var(--signal-clair) border-box;
  box-shadow:var(--ombre-2),var(--ombre-chaude)}
.pOrte:hover::after,.pOrte:focus-visible::after{opacity:1}
.pOrte:hover svg{color:var(--sec-fonce)}
.pOrte:hover .aller{color:var(--sec-fonce)}
.pOrte:hover::before,.pOrte:focus-visible::before{transform:scaleX(1)}
.pOrte:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
.pOrte .haut{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem}
/* #93A3BE ne donnait que 2,50 de contraste sur le papier : le numero d'ordre
   reste discret, mais il se lit. */
.pOrte .num{font-size:.78rem;font-weight:600;letter-spacing:.2em;color:#64738F}
.pOrte svg{width:60px;height:60px;flex:0 0 auto;color:var(--acc);
  transition:color .3s var(--t),transform .5s var(--t)}
.pOrte:hover svg{transform:translateY(-2px) scale(1.05)}
.pOrte p{color:var(--texte-2);font-size:.95rem;flex:1}
.pOrte .aller{font-weight:500;color:var(--acc);font-size:.94rem;display:inline-flex;align-items:center;gap:.4rem}
.pOrte .aller svg{width:1.05rem;height:1.05rem}
.pOrte:hover .aller svg{transform:translateX(3px)}
.pOrte--phare{background:linear-gradient(158deg,color-mix(in oklab,var(--acc-voile) 52%,#fff),var(--acc-voile));border-color:color-mix(in oklab,var(--acc) 22%,#fff)}
.pOrte--phare .num{color:var(--acc)}
/* Le meme gris assombri pour tenir sur le papier tombe a 3,99 sur une
   section de nuit : la couleur du numero suit donc son fond. */
.nuit .pOrte .num,.sombre .pOrte .num{color:#A9B6CE}
@media (min-width:1300px){
  .pOrte--phare{grid-column:span 2}
  .pOrte--phare h3{font-size:1.6rem;font-weight:400;letter-spacing:-.03em}
  .pOrte--phare svg{width:76px;height:76px}
}

/* =========================================================================
   Chiffres : tres grands, sur la nuit, avec le champ derriere
   ========================================================================= */
.chiffres{overflow:hidden;isolation:isolate}
.chiffres .fond{position:absolute;inset:-10% 0 -10% 0;z-index:-1;opacity:.8;
  background:repeating-linear-gradient(90deg,transparent 0 10px,color-mix(in oklab,var(--acc-vif) 42%,transparent) 10px 12px,transparent 12px 24px);
  -webkit-mask-image:radial-gradient(70% 80% at 50% 60%,#000,transparent 78%);
  mask-image:radial-gradient(70% 80% at 50% 60%,#000,transparent 78%)}
/* Une braise chaude sous les chiffres : l'orange arrive par la lumiere. */
.chiffres .braise{position:absolute;inset:auto 0 -30% 0;height:80%;z-index:-1;pointer-events:none;
  background:radial-gradient(50% 60% at 72% 60%,color-mix(in oklab,var(--sec) 30%,transparent),transparent 70%)}
.rangee{display:grid;gap:2rem;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));margin-top:2.8rem}
.chiffre b{display:block;font-size:clamp(3.2rem,8vw,6.4rem);font-weight:200;letter-spacing:-.05em;
  line-height:.9;font-variant-numeric:tabular-nums;
  color:#fff;background:linear-gradient(150deg,#FFFFFF 18%,var(--sec-clair) 96%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.chiffre span{color:var(--acc-clair);font-size:.95rem}
.chiffre:nth-child(2) b{background:linear-gradient(150deg,#FFFFFF 12%,var(--sec-clair) 90%);
  -webkit-background-clip:text;background-clip:text}
.chiffre:nth-child(4) b{background:linear-gradient(150deg,#FFFFFF 12%,var(--acc-clair) 92%);
  -webkit-background-clip:text;background-clip:text}

/* =========================================================================
   Piliers : panneaux alternes, gros chiffre fantome
   ========================================================================= */
.piliers{border-block:1px solid var(--trait);
  background:
    radial-gradient(40% 40% at 88% 6%, var(--nuee-2) 0%, transparent 66%),
    radial-gradient(44% 40% at 4% 86%, var(--nuee-1) 0%, transparent 68%),
    var(--papier-2)}
.pilier{position:relative;background:var(--papier);border:1px solid var(--trait);border-radius:var(--r);
  padding:1.8rem 1.7rem;display:flex;flex-direction:column;gap:.7rem;overflow:hidden}
/* Le chiffre fantome tient DANS la carte : deborde en haut, il paraissait
   tronque par accident plutot que cadre. */
.pilier::before{content:attr(data-num);position:absolute;right:.9rem;top:.7rem;
  font-size:4rem;font-weight:200;letter-spacing:-.06em;color:var(--acc-voile);line-height:1;z-index:0}
.pilier>*{position:relative;z-index:1}
.puces{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:auto;padding-top:.9rem}
.puce{font-size:.78rem;padding:.26rem .66rem;border-radius:99px;background:var(--acc-voile);
  color:var(--acc);font-weight:500}
.mots-cles{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.4rem}
.mots-cles span{font-size:.8rem;padding:.3rem .74rem;border:1px solid var(--trait);border-radius:99px;
  color:var(--texte-2);background:var(--papier)}
.conclusion{margin-top:2.4rem;font-size:clamp(1.1rem,1.7vw,1.42rem);font-weight:300;max-width:60ch;
  border-left:3px solid var(--acc-vif);padding-left:1.3rem;line-height:1.42}

/* =========================================================================
   Les marques : les VRAIS logos, en deux rubans contraires
   ========================================================================= */
.marques{overflow:hidden;padding-bottom:clamp(2.6rem,5vw,4rem);
  background:
    radial-gradient(42% 38% at 8% 6%, var(--nuee-1) 0%, transparent 66%),
    radial-gradient(38% 34% at 94% 14%, var(--nuee-2) 0%, transparent 68%),
    var(--papier)}
/* Le voile commence a 12 % : a 9 %, le fil passait sur une tuile encore
   visible et l'on croyait a une collision. */
.ruban{position:relative;overflow:hidden;margin-top:1.4rem;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.ruban ul{display:flex;gap:1rem;margin:0;padding:.4rem 0;list-style:none;width:max-content;
  animation:defile 44s linear infinite}
.ruban--retour ul{animation-duration:52s;animation-direction:reverse}
.ruban:hover ul{animation-play-state:paused}
.marque{position:relative;display:grid;place-items:center;width:184px;height:104px;flex:0 0 auto;
  border:1px solid var(--trait);border-radius:12px;background:var(--papier);
  transition:.3s var(--t)}
.marque img{max-width:124px;max-height:52px;width:auto;height:auto;
  filter:grayscale(1);opacity:.5;transition:.3s var(--t)}
.marque:hover{border-color:var(--acc-clair);background:var(--acc-voile);transform:translateY(-4px);
  box-shadow:0 18px 34px -26px rgba(13,20,32,.7)}
.marque:hover img{filter:none;opacity:1}
.marque figcaption{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* =========================================================================
   LA PROSE — le gabarit des pages terminales
   -------------------------------------------------------------------------
   Articles, pages legales, fiches produit et pages de formulaire : leur
   contenu est du HTML SEMANTIQUE NU, sans classe. On l'habille donc par ses
   balises, pas par des classes. C'est ce qui permet de generer 71 pages sans
   en dessiner une seule a la main — et ce qui les rendra reprises telles
   quelles par l'editeur WordPress plus tard.
   ========================================================================= */
.contenu{max-width:74ch;font-size:1.04rem;line-height:1.72}
.contenu>*+*{margin-top:1.1rem}
.contenu h2{font-size:clamp(1.5rem,2.6vw,2.1rem);font-weight:400;margin-top:2.8rem;letter-spacing:-.025em}
.contenu h3{font-size:1.22rem;font-weight:500;margin-top:2rem}
.contenu h4{font-size:1.05rem;font-weight:600;margin-top:1.6rem;color:var(--acc)}
.contenu h2+*,.contenu h3+*,.contenu h4+*{margin-top:.6rem}
.contenu p,.contenu li{color:var(--texte-2)}
.contenu strong,.contenu b{color:var(--texte);font-weight:600}
.contenu a{color:var(--acc);text-underline-offset:.18em;text-decoration-thickness:1px}
.contenu a:hover{color:var(--sec-fonce)}
.contenu ul,.contenu ol{padding-left:1.3rem;display:grid;gap:.45rem}
.contenu li::marker{color:var(--acc)}
.contenu blockquote{margin-left:0;padding-left:1.2rem;border-left:3px solid var(--acc-vif);
  font-size:1.1rem;color:var(--texte)}
.contenu img{border-radius:12px;border:1px solid var(--trait)}
.contenu figure{margin:1.6rem 0}
.contenu figcaption{font-size:.86rem;color:var(--texte-2);margin-top:.5rem}
.contenu hr{border:0;border-top:1px solid var(--trait);margin-block:2.4rem}
.contenu table{margin-top:1rem}
/* Un tableau large ne doit jamais faire deborder la PAGE : on l'enferme. */
.contenu .tableau-cadre{max-width:none}
.contenu section{margin-top:2.4rem}
.contenu section:first-child{margin-top:0}
/* Les formulaires des pages de demande, en balises nues. */
.contenu form{display:grid;gap:1rem;margin-top:1.6rem;max-width:none}
.contenu label{display:grid;gap:.34rem;font-size:.86rem;font-weight:500;color:var(--texte-2)}
.contenu button{display:inline-flex;align-items:center;gap:.55rem;padding:.85rem 1.5rem;border-radius:99px;
  font-weight:500;font-size:.97rem;border:0;cursor:pointer;font-family:inherit;
  background-color:var(--acc);background-image:var(--signal);color:#fff;justify-self:start}
.contenu button:hover{transform:translateY(-2px)}

/* La colonne laterale des pages terminales : sommaire et rappel de contact. */
.aparte{position:sticky;top:6.5rem;display:grid;gap:1.2rem;font-size:.94rem}
.aparte .carte{padding:1.3rem 1.35rem;border-radius:var(--r);border:1px solid var(--trait);
  background:var(--papier);box-shadow:var(--ombre-1)}
.aparte h2{font-size:.76rem;letter-spacing:.18em;text-transform:uppercase;font-weight:700;
  color:var(--acc);margin:0 0 .8rem}
.aparte a{display:block;padding-block:.3rem;color:var(--texte-2);text-decoration:none;font-size:.93rem}
.aparte a:hover{color:var(--acc)}
/* Le lien de liste et le bouton d'appel sont deux objets differents : la
   couleur de liste ecrasait le blanc du bouton plein (0-1-1 contre 0-1-0) et
   le numero de telephone tombait a 1,36 de contraste sur son degrade. */
.aparte a.bouton{display:inline-flex;padding-block:.8rem}
.aparte a.bouton--plein,.aparte a.bouton--plein:hover{color:#fff}
@media (max-width:1079px){.aparte{position:static}}

/* =========================================================================
   LES COMPOSANTS DES PAGES PILIERS
   Tarifs, comparatif, arguments numerotes, renvoi d'article et FAQ. Ils
   servent les sept piliers PRO comme les cinq Particulier.
   ========================================================================= */

/* --- Les offres chiffrees ---------------------------------------------- */
.tarifs{display:grid;gap:1.2rem;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));margin-top:2.4rem}
.tarif{position:relative;display:flex;flex-direction:column;gap:.9rem;padding:1.8rem 1.6rem 1.6rem;
  border:1px solid transparent;border-radius:var(--r);
  background:linear-gradient(var(--papier),var(--papier)) padding-box,
    linear-gradient(150deg,color-mix(in oklab,var(--acc) 14%,#fff),color-mix(in oklab,var(--sec) 18%,#fff)) border-box;
  box-shadow:var(--ombre-1);transition:transform .34s var(--ressort),box-shadow .34s var(--t)}
.tarif:hover{transform:translateY(-5px);box-shadow:var(--ombre-2)}
.tarif--phare{background:linear-gradient(158deg,color-mix(in oklab,var(--acc-voile) 55%,#fff),var(--acc-voile)) padding-box,
  var(--signal-clair) border-box}
.tarif .marqueur{align-self:flex-start;font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;
  font-weight:700;padding:.28rem .7rem;border-radius:99px;
  background:var(--acc-voile);color:var(--acc)}
.tarif--phare .marqueur{background:var(--signal);color:#fff}
.tarif h3{font-size:1.5rem;font-weight:400}
.tarif .prix{display:flex;align-items:baseline;gap:.35rem;font-weight:300;letter-spacing:-.03em;
  background:var(--signal);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.tarif .prix b{font-size:clamp(2.1rem,3.4vw,2.9rem);font-weight:300}
.tarif .prix span{font-size:1rem;-webkit-text-fill-color:var(--texte-2)}
.tarif>p{color:var(--texte-2);font-size:.96rem}
.tarif ul{margin:0;padding:0;list-style:none;display:grid;gap:.5rem;font-size:.94rem}
.tarif li{display:flex;gap:.55rem;align-items:flex-start;color:var(--texte-2)}
.tarif li::before{content:"";flex:0 0 auto;width:1.05rem;height:1.05rem;margin-top:.22rem;border-radius:50%;
  background:var(--acc-voile);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/78% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/78% no-repeat;
  background-color:var(--acc)}
.tarif .pour{margin-top:auto;padding-top:.9rem;border-top:1px dashed var(--trait);
  font-size:.88rem;color:var(--texte-2)}
.note{margin-top:1.4rem;font-size:.84rem;color:var(--texte-2);max-width:70ch}

/* --- Le comparatif ------------------------------------------------------
   Enferme dans son propre cadre defilant : une table large ne doit jamais
   faire deborder la PAGE. */
.tableau-cadre{margin-top:2.4rem;overflow-x:auto;border:1px solid var(--trait);border-radius:var(--r);
  background:var(--papier);box-shadow:var(--ombre-1)}
table{border-collapse:collapse;width:100%;min-width:34rem;font-size:.94rem}
caption{text-align:left;padding:1.1rem 1.3rem .2rem;font-weight:600;color:var(--texte)}
th,td{padding:.85rem 1.3rem;text-align:left;vertical-align:top;border-top:1px solid var(--trait)}
thead th{border-top:0;font-weight:600;color:var(--acc);white-space:nowrap}
tbody th{font-weight:500;color:var(--texte-2);width:14rem}
tbody tr:nth-child(odd) td,tbody tr:nth-child(odd) th{background:color-mix(in oklab,var(--acc-voile) 45%,transparent)}

/* --- Les arguments numerotes ------------------------------------------- */
.arguments{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));margin-top:2.2rem}
.argument{position:relative;padding:1.5rem 1.4rem;border-radius:var(--r);
  border:1px solid var(--trait);background:var(--papier);box-shadow:var(--ombre-1);
  display:flex;flex-direction:column;gap:.5rem}
.argument .rang{font-size:.78rem;font-weight:700;letter-spacing:.18em;color:var(--acc)}
.argument h3{font-size:1.08rem}
.argument p{color:var(--texte-2);font-size:.94rem}
.nuit .argument{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.14);box-shadow:none}
.nuit .argument p{color:rgba(255,255,255,.72)}
.nuit .argument .rang{color:var(--acc-clair)}

/* --- Le renvoi vers un article ----------------------------------------- */
.pour-aller-plus-loin{display:flex;gap:1.1rem;align-items:flex-start;margin-top:2.2rem;
  padding:1.35rem 1.5rem;border-radius:var(--r);text-decoration:none;color:inherit;
  border:1px solid transparent;
  background:linear-gradient(var(--papier),var(--papier)) padding-box,
    linear-gradient(100deg,color-mix(in oklab,var(--acc) 16%,#fff),color-mix(in oklab,var(--sec) 22%,#fff)) border-box;
  box-shadow:var(--ombre-1);transition:.3s var(--t)}
.pour-aller-plus-loin:hover{transform:translateY(-3px);box-shadow:var(--ombre-2);
  background:linear-gradient(var(--papier),var(--papier)) padding-box,var(--signal-clair) border-box}
.pour-aller-plus-loin .etiquette{flex:0 0 auto;font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;
  font-weight:700;color:var(--acc);padding-top:.2rem}
.pour-aller-plus-loin h3{font-size:1.12rem;margin-bottom:.3rem}
.pour-aller-plus-loin p{color:var(--texte-2);font-size:.94rem}
.pour-aller-plus-loin .aller{display:inline-block;margin-top:.5rem;color:var(--acc);font-weight:500;font-size:.92rem}
.nuit .pour-aller-plus-loin{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.16);color:#fff}
.nuit .pour-aller-plus-loin p{color:rgba(255,255,255,.72)}
.nuit .pour-aller-plus-loin .etiquette,.nuit .pour-aller-plus-loin .aller{color:var(--acc-clair)}

/* --- La FAQ ------------------------------------------------------------
   `<details>` natif : elle s'ouvre sans JavaScript, se navigue au clavier,
   et son contenu est trouvable par la recherche du navigateur meme replie.
   Aucune reponse ne nait a `opacity: 0`. */
.faq{display:grid;gap:.7rem;margin-top:2.2rem}
.faq details{border:1px solid var(--trait);border-radius:14px;background:var(--papier);
  box-shadow:var(--ombre-1);overflow:hidden;transition:border-color .3s var(--t)}
.faq details[open]{border-color:color-mix(in oklab,var(--acc) 34%,var(--trait))}
.faq summary{display:flex;align-items:flex-start;gap:.9rem;padding:1.1rem 1.3rem;cursor:pointer;
  font-weight:500;font-size:1.02rem;list-style:none;transition:background .25s var(--t)}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{background:var(--acc-voile)}
.faq summary:focus-visible{outline:2px solid var(--acc);outline-offset:-2px}
.faq summary::after{content:"";flex:0 0 auto;margin-left:auto;width:1.1rem;height:1.1rem;margin-top:.22rem;
  background:var(--acc);transition:rotate .3s var(--ressort);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 5v14M5 12h14' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 5v14M5 12h14' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat}
.faq details[open] summary::after{rotate:135deg}
.faq .reponse{padding:0 1.3rem 1.2rem 1.3rem;color:var(--texte-2);font-size:.98rem;max-width:78ch}

/* =========================================================================
   Formulaire
   ========================================================================= */
.contact{border-top:1px solid var(--trait);
  background:
    radial-gradient(46% 44% at 12% 8%, var(--nuee-1) 0%, transparent 68%),
    radial-gradient(40% 40% at 90% 88%, var(--nuee-2) 0%, transparent 68%),
    var(--papier-2)}
/* Le formulaire sur une plaque de verre, pas a meme le fond. */
.contact form{background:color-mix(in oklab,var(--papier) 76%,transparent);
  backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,.7);
  box-shadow:var(--ombre-1);border-radius:var(--r);padding:clamp(1.3rem,3vw,2rem)}
form{display:grid;gap:1rem;grid-template-columns:1fr 1fr;margin-top:2rem}
form .plein{grid-column:1/-1}
label{display:grid;gap:.34rem;font-size:.86rem;font-weight:500;color:var(--texte-2)}
input,select,textarea{font:inherit;font-size:.98rem;padding:.78rem .9rem;border:1px solid var(--trait);
  border-radius:11px;background:var(--papier);color:var(--texte);width:100%}
input:focus,select:focus,textarea:focus{outline:2px solid var(--acc);outline-offset:1px;border-color:transparent}
textarea{min-height:8.5rem;resize:vertical}
.mention{font-size:.82rem;color:var(--texte-2)}

/* =========================================================================
   Manufacture
   ========================================================================= */
.manufacture{background:linear-gradient(158deg,#0A0F1F 0%,#12203F 58%,#0C1428 100%);color:#fff;
  overflow:hidden;isolation:isolate}
.manufacture h2{max-width:20ch;background:var(--signal-nuit);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.manufacture .chapo{color:rgba(255,255,255,.78);max-width:60ch;margin-top:1.2rem}
.manufacture .mur{margin-top:2.6rem}
@media (min-width:1000px){
  .manufacture .deux-colonnes{grid-template-columns:1.5fr .95fr !important}
}
.manufacture .pOrte{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.15);color:#fff}
.manufacture .pOrte:hover{border-color:color-mix(in oklab,var(--acc-clair) 55%,transparent);box-shadow:none;background:rgba(255,255,255,.08)}
.manufacture .pOrte p{color:rgba(255,255,255,.72)}
.manufacture .pOrte svg{color:var(--acc-clair)}
.manufacture .pOrte .num{color:rgba(255,255,255,.45)}
.produits{display:flex;flex-wrap:wrap;gap:.45rem;margin-top:2rem}
.produits span{font-size:.85rem;padding:.34rem .8rem;border-radius:99px;
  border:1px solid rgba(255,255,255,.22);color:rgba(255,255,255,.84)}

/* =========================================================================
   Pied
   ========================================================================= */
.pied{background:var(--encre);color:rgba(255,255,255,.7);padding-block:3.4rem 2rem}
.pied .rangee{grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:2rem;margin-top:0}
.pied h3{color:#fff;font-size:.76rem;letter-spacing:.2em;text-transform:uppercase;margin-bottom:.9rem;font-weight:700}
.pied a{color:rgba(255,255,255,.7);text-decoration:none;display:block;padding-block:.2rem;font-size:.92rem}
.pied a:hover{color:#fff}
.pied .bas{display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem;
  margin-top:2.6rem;padding-top:1.5rem;border-top:1px solid rgba(255,255,255,.1);font-size:.84rem}

/* =========================================================================
   Apparition au defilement — TRANSFORM SEULEMENT
   Rien ne part d'`opacity: 0`. Si le script ne tourne pas, si l'observateur
   ne se declenche jamais, le texte est deja la et deja lisible.
   ========================================================================= */
.monte{transform:translateY(20px);transition:transform .75s var(--t)}
.monte.vu{transform:none}
/* 20 px, ET PAS 26 : c'est exactement le retrait de `.large`
   (`width:min(1240px,100% - 2.5rem)`, soit 20 px de chaque cote). Un bloc
   colle au bord droit de `.large` n'a que ces 20 px devant lui ; a 26 il
   depasse de 6, et `body{overflow-x:hidden}` MASQUE ce debordement au lieu de
   le signaler. Mesure au chargement frais, une page neuve par largeur, avec
   `overflow-x` neutralise (un simple redimensionnement ne le montre pas :
   l'animation a deja remis `transform` a `none`) : +6 px sur interieur.html a
   901, 960, 1024, 1080 et 1120 px, et sur interieur-part.html aux memes
   largeurs plus 1180 et 1280 — 1280 etant la derniere ou `.large` vaut encore
   « 100% - 2.5rem ». Au-dela, la marge s'ouvre et le probleme disparait tout
   seul. Meme chiffre que `.monte`, meme raison. */
.glisse-g{transform:translateX(-20px);transition:transform .8s var(--t)}
.glisse-d{transform:translateX(20px);transition:transform .8s var(--t)}
/* Au telephone, meme cause a une autre echelle : le decalage lateral pousse la
   carte hors du cadre tant qu'elle n'est pas revelee. La montee dit la meme
   chose sans deborder. */
@media (max-width:900px){.glisse-g,.glisse-d{transform:translateY(20px)}}
.glisse-g.vu,.glisse-d.vu{transform:none}

/* =========================================================================
   UX : deux ajouts qui ne relevent pas du decor
   ========================================================================= */
/* Retour en haut — la page fait 6 700 px, la remonter a la molette est une
   corvee. Il ne parait qu'une fois la moitie franchie. */
.remonter{position:fixed;right:clamp(1rem,3vw,2rem);bottom:clamp(1rem,3vw,2rem);z-index:45;
  width:3rem;height:3rem;display:grid;place-items:center;border-radius:50%;
  background:color-mix(in oklab,var(--papier) 78%,transparent);backdrop-filter:blur(14px);
  border:1px solid var(--trait);box-shadow:var(--ombre-1);color:var(--texte);
  translate:0 140%;opacity:.001;transition:translate .5s var(--ressort),opacity .35s var(--t),
    background .3s,border-color .3s}
.remonter.parait{translate:0;opacity:1}
.remonter:hover{background:var(--papier);border-color:var(--sec);color:var(--sec-fonce)}
.remonter svg{width:1.15rem;height:1.15rem;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

/* Barre d'action au telephone : appeler ou ecrire sans remonter la page.
   Sur un site de depannage, c'est l'element le plus utile de la page. */
.barre-action{position:fixed;left:0;right:0;bottom:0;z-index:46;display:none;
  gap:.55rem;padding:.6rem .7rem calc(.6rem + env(safe-area-inset-bottom));
  background:color-mix(in oklab,var(--papier) 88%,transparent);backdrop-filter:blur(16px);
  border-top:1px solid var(--trait)}
.barre-action a{flex:1;display:flex;align-items:center;justify-content:center;gap:.45rem;
  padding:.8rem .6rem;border-radius:12px;text-decoration:none;font-weight:600;font-size:.92rem}
.barre-action .appeler{background-color:var(--acc);background-image:var(--signal);color:#fff}
.barre-action .ecrire{border:1px solid var(--trait);color:var(--texte)}
@media (max-width:820px){
  .barre-action{display:flex}
  body{padding-bottom:4.6rem}
  .remonter{bottom:5.4rem}
}

@media (prefers-reduced-motion:reduce){
  .monte,.glisse-g,.glisse-d{transform:none;transition:none}
  .bandeau ul,.ruban ul,.descente::after,.tete h1 b{animation:none}
  .fil,.remonter{transition:none}
  *{transition-duration:.01ms !important}
}
/* LE SEUIL DU TIROIR PASSE DE 1180 A 1024 PX. Il etait a 1180 parce que neuf
   entrees demandaient 770 px ; cinq n'en demandent plus que 527 (mesure a
   1280 px, interieur.html). Mesure du point de rupture, pastille courte et
   tiroir neutralise, sur pvente.html : le rang y demande 814 px, tient jusqu'a
   857 px de viewport et deborde a 856. Avec la pastille LONGUE — meme page,
   rang de 936 px — il tient jusqu'a 977. Le seuil est donc pose a 1024 px, largeur d'une tablette
   en paysage : entre 1024 et 1180 px, on gagne une vraie barre horizontale la
   ou il y avait un hamburger. `body{overflow-x:hidden}` MASQUE un debordement
   au lieu de le signaler : ces chiffres viennent de la mesure, pas de l'oeil.
   Sous le seuil, chaque theme devient un accordeon et le panneau reprend le
   flux normal.
   ⚠ socle.js porte la meme borne en `matchMedia('(min-width:1025px)')` (le
   survol n'a de sens que quand la barre est horizontale) : les deux se
   changent ENSEMBLE. */
@media (max-width:1024px){
  .entete .rang{flex-wrap:wrap;gap:.55rem .7rem}
  .menu-bouton{display:flex;order:2;margin-left:auto}
  .bascule-lien{order:3}
  .entete .menu{display:none;order:4;width:100%;margin-left:0;flex-wrap:wrap;
    overflow:visible;padding:.35rem 0 .5rem;border-top:1px solid var(--trait)}
  /* Le tiroir porte cinq entrees : fermees elles tiennent (245 px mesures a
     390 px, pour 769 visibles), mais un panneau ouvert le fait deborder de
     l'ecran — 1444 px pour « Faire tourner l'entreprise ». L'en-tete est
     collante : faire glisser la page ne rattrape rien, les entrees basses
     restent inatteignables. Le tiroir defile donc lui-meme. */
  .entete.menu-ouvert .menu{display:flex;max-height:calc(100dvh - 4.6rem);
    overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
    padding-inline:4px;scrollbar-width:thin}
  .entete .menu a{width:100%;padding:.68rem .55rem;border-radius:10px}
  .entete .menu a[aria-current]{background:var(--acc-voile)}
  /* CORRECTION D'UN DÉFAUT EXISTANT : socle.css met « .entete .menu » en
     display:none sous le seuil, sans condition. Sans JavaScript, la
     navigation des 90 pages qui portent une en-tete (62 PRO + 28 PART)
     disparaissait sans moyen de la révéler. */
  html:not(.js) .entete .menu{display:flex}
  /* Sans script, le tiroir ne peut pas s'ouvrir : le menu reste donc a
     l'ecran. Il y tient en deux rangs serres plutot qu'en cinq lignes
     pleine largeur, et chaque theme s'ouvre au clic, nativement. */
  html:not(.js) .menu--mega .mm-simple,
  html:not(.js) .mm-titre{width:auto;padding:.45rem .6rem;font-size:.86rem;font-weight:450}
  html:not(.js) .mm-groupe{width:auto}
  html:not(.js) .mm-groupe[open]{width:100%}
  html:not(.js) .mm-groupe[open]>.mm-titre{font-weight:600}
  .menu--mega{gap:.1rem}
  .menu--mega .mm-simple{width:100%;padding:.68rem .55rem;border-radius:10px}
  .mm-groupe{width:100%}
  .mm-titre{width:100%;justify-content:space-between;padding:.68rem .55rem;border-radius:10px;
    font-size:.95rem;font-weight:500}
  .mm-titre svg{width:.7rem;height:.7rem}
  /* max-height ET overflow SONT REMIS A ZERO. Le panneau de bureau est un
     tiroir deroulant plafonne a « 100vh - 5rem » ; laisse tel quel dans le
     tiroir, il devient un SECOND defileur imbrique, sans poignee visible.
     Mesure a 390 px, panneau « Faire tourner l'entreprise » ouvert : le
     panneau demandait 1021 px, en montrait 764, et la colonne Telephonie plus
     la bande telephone-adresse etaient injoignables — la page etait pourtant
     servie entiere et le controle passait au vert. Le seul defileur est
     desormais le tiroir. */
  .mm-panneau{position:static;box-shadow:none;border:0;border-radius:12px;
    background-image:none;background:var(--papier-2);
    padding:.9rem .9rem 1rem;margin:.25rem 0 .5rem;
    max-height:none;overflow:visible}
  .mm-plan{grid-template-columns:minmax(0,1fr);gap:.9rem}
  /* Les colonnes s'empilent. Le filet vertical de la gouttiere n'a plus de
     gouttiere : il devient le trait horizontal qui separe deux piliers. */
  .mm-plan--2,.mm-plan--3{grid-template-columns:minmax(0,1fr)}
  .mm-colonne+.mm-colonne::before{display:none}
  .mm-colonne+.mm-colonne{border-top:1px solid var(--trait);padding-top:.8rem}
  .mm-colonne .mm-glyphe{width:34px;height:34px}
  .mm-colonne .mm-pilier{font-size:1rem;gap:.6rem}
  /* Les colonnes sont l'une SOUS l'autre : rien a aligner, et une ligne vide
     de plus par pilier coute cher dans un tiroir qui defile deja. */
  .mm-colonne .mm-resume{min-height:0}
  .mm-glyphe{width:46px;height:46px}
  .mm-pilier{font-size:1.08rem}
  .mm-liste{grid-template-columns:minmax(0,1fr);grid-template-rows:none;grid-auto-flow:row;
    grid-auto-columns:auto;gap:0;padding-left:0;border-left:0;
    border-top:1px solid var(--trait);padding-top:.4rem}
  /* Le retrait gauche garde la place de la puce pendante : .5rem de retrait
     + .82rem de puce. Sans ca, la pastille se pose sur la premiere lettre. */
  .mm-liste a{padding:.6rem .5rem .6rem 1.32rem}
  /* socle.css pose « .entete .menu a{width:100%} » sous 1024 px. C'est bon
     pour les entrees du tiroir, pas pour la pastille de telephone ni pour
     le nom du pilier : on leur rend leur largeur de contenu. */
  .entete .menu .mm-pilier{width:auto;padding:0;border-radius:0}
  .entete .menu .mm-appui a{width:auto}
  .entete .menu .mm-appui .mm-tel{padding:.34rem .85rem}
  .mm-appui{margin-top:.2rem}
}
@media (max-width:560px){
  .entete .rang{gap:.5rem}
  .bascule-lien{font-size:.76rem;padding:.36rem .66rem}
}
@media (max-width:820px){
  form{grid-template-columns:1fr}
  .tete{min-height:auto}
  .pilier::before{font-size:5.5rem}
}


/* =========================================================================
   LES DEUX COMPOSANTS FUSIONNÉS — ils étaient deux feuilles à part.

   Ils arrivent EN FIN DE FEUILLE, et nulle part ailleurs : c'est la place
   exacte qu'ils occupaient quand les pages les chargeaient après le socle.
   Entre deux règles de même poids, c'est la dernière lue qui gagne — les
   remonter plus haut changerait l'arbitrage, donc l'écran.
   ========================================================================= */

/* =========================================================================
   COMPOSANT FORMULAIRE — maquette de bascule.

   Les classes sont celles que `class-if2m-forms-rendu.php` ecrit deja
   (`if2m-form-*`) : la maquette et le site rendent le meme balisage, le
   portage se reduit donc a poser cette feuille dans le theme. Rien n'est
   invente ici qui n'existe pas cote PHP.

   Trois partis pris tiennent tout le fichier :

   1. RIEN NE SE REMPLIT. Le repere d'etapes est une liste numerotee :
      pastilles, rang courant marque, etapes faites cochees. Aucune jauge,
      aucune barre qui progresse — refusees deux fois sur ce projet.
   2. SANS SCRIPT, TOUT EST LA. Les <fieldset> d'etape sont visibles a la
      suite ; ce sont le script et lui seul qui posent `hidden`. Aucune regle
      de cette feuille ne masque une etape, sinon le repli sans JavaScript
      afficherait un formulaire vide.
   3. AUCUN CONTENU NE NAIT INVISIBLE. Pas d'`opacity: 0` de base. Le seul
      element sorti de l'ecran est le piege a robots, qui n'est pas du
      contenu, et les libelles reserves aux lecteurs d'ecran.

   POURQUOI TOUT EST PREFIXE PAR `.if2m-form-bloc` : le socle habille deja les
   formulaires ecrits a la main, avec des selecteurs de la forme `.contenu
   label` ou `.contenu ol`. A poids egal, c'est la derniere regle qui gagne.
   Le prefixe donne au composant le poids qu'il faut pour tenir dans une page
   d'article comme dans une section de contact, quelle que soit la regle du
   socle qu'il croise.
   ========================================================================= */

/* Le socle pose `form{display:grid;grid-template-columns:1fr 1fr}` pour les
   formulaires ecrits a la main. Le composant gere sa propre grille, etape
   par etape : on lui rend un flux normal. */
.if2m-form-bloc .if2m-formulaire,
.contenu .if2m-form-bloc .if2m-formulaire {
  display: block;
  grid-template-columns: none;
  margin-top: 0;
  max-width: none;
}

.if2m-form-bloc {
  --if2m-fond: var(--papier);
  --if2m-fond-2: var(--papier-2);
  --if2m-trait: var(--trait);
  --if2m-texte: var(--texte);
  --if2m-texte-2: var(--texte-2);
  --if2m-alerte: #B42318;
  --if2m-alerte-voile: #FEF3F2;
  --if2m-succes: #05603A;
  --if2m-succes-voile: #ECFDF3;
  color: var(--if2m-texte);
  margin-top: 1.6rem;
}

/* Sur fond sombre le formulaire remonte sur une plaque claire : un champ de
   saisie blanc pose a meme la nuit fait tache, et un champ sombre fait fuir. */
.nuit .if2m-form-bloc,
.manufacture .if2m-form-bloc {
  background: var(--if2m-fond);
  border-radius: var(--r);
  padding: clamp(1rem, 2.6vw, 1.6rem);
  box-shadow: var(--ombre-2);
}

/* -------------------------------------------------------------------------
   Le formulaire, sa plaque et ses mentions
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-intro {
  color: var(--if2m-texte-2);
  font-size: .95rem;
  margin: 0 0 1.2rem;
  max-width: 62ch;
}

/* La mention de maquette est permanente et non pliable : le visiteur doit
   savoir avant de saisir quoi que ce soit que rien ne partira. */
.if2m-form-bloc .if2m-form-maquette {
  margin: 0 0 1.2rem;
  padding: .6rem .85rem;
  border-radius: 11px;
  border: 1px dashed var(--if2m-trait);
  background: var(--if2m-fond-2);
  color: var(--if2m-texte-2);
  font-size: .82rem;
  line-height: 1.5;
}
.if2m-form-bloc .if2m-form-maquette b { color: var(--if2m-texte); font-weight: 700; }

/* -------------------------------------------------------------------------
   Le repere d'etapes. Une liste numerotee, jamais une jauge.
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-fil { margin: 0 0 1.7rem; }

.if2m-form-bloc .if2m-form-fil-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .45rem .5rem;
}

.if2m-form-bloc .if2m-form-fil-item {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .3rem .85rem .3rem .32rem;
  border: 1px solid var(--if2m-trait);
  border-radius: 99px;
  background: var(--if2m-fond);
  color: var(--if2m-texte-2);
  font-size: .84rem;
  line-height: 1.25;
  transition: border-color .3s var(--t), color .3s var(--t), background .3s var(--t);
}
.if2m-form-bloc .if2m-form-fil-item::marker { content: none; }
/* `display` pose ici l'emporte sur le `display:none` que le navigateur donne
   a `[hidden]` : sans cette ligne, une etape sautee par une condition reste
   affichee dans le repere alors qu'on ne la traversera jamais. */
.if2m-form-bloc .if2m-form-fil-item[hidden] { display: none; }

.if2m-form-bloc .if2m-form-fil-rang {
  display: inline-grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--if2m-fond-2);
  color: var(--if2m-texte-2);
  font-size: .78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* L'etape en cours : marquee par la couleur et par le trait, pas par un
   remplissage progressif. */
.if2m-form-bloc .if2m-form-fil-item--courante {
  border-color: var(--acc);
  color: var(--texte);
  background: var(--acc-voile);
  font-weight: 600;
}
.if2m-form-bloc .if2m-form-fil-item--courante .if2m-form-fil-rang {
  background: var(--acc);
  color: #fff;
}

/* Une etape deja traversee garde son chiffre — lisible pour qui ne distingue
   pas la couleur — et gagne une coche. */
.if2m-form-bloc .if2m-form-fil-item--faite {
  border-color: color-mix(in oklab, var(--acc) 40%, var(--trait));
}
.if2m-form-bloc .if2m-form-fil-item--faite .if2m-form-fil-rang {
  background: color-mix(in oklab, var(--acc) 18%, var(--papier));
  color: var(--acc);
}
.if2m-form-bloc .if2m-form-fil-item--faite .if2m-form-fil-titre::after {
  content: " ✓";
  color: var(--acc);
  font-weight: 700;
}

/* -------------------------------------------------------------------------
   Les etapes
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-etape {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0; /* un fieldset refuse de retrecir sans cette ligne */
}
/* Le filet entre deux etapes n'a de sens que quand elles se suivent a
   l'ecran, c'est-a-dire SANS JavaScript. Des que le script n'en montre
   qu'une, la precedente porte `hidden` : le filet s'efface, sinon un trait
   flotterait au-dessus d'une etape seule. */
.if2m-form-bloc .if2m-form-etape + .if2m-form-etape {
  margin-top: 2.4rem;
  padding-top: 2rem;
  border-top: 1px solid var(--if2m-trait);
}
.if2m-form-bloc .if2m-form-etape[hidden] + .if2m-form-etape {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.if2m-form-bloc .if2m-form-etape-legende {
  display: block;
  float: none;
  width: 100%;
  padding: 0 0 1rem;
  margin: 0;
}

.if2m-form-bloc .if2m-form-etape-rang {
  display: block;
  /* Le repere d'etape est le SEUL indicateur de position du formulaire : il ne
     peut pas etre le plus petit texte de l'ecran. */
  font-size: .88rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--acc);
}

.if2m-form-bloc .if2m-form-etape-titre {
  margin: .3rem 0 0;
  /* Le titre recoit le focus au changement d'etape : sur toute la largeur,
     son anneau ressemblerait a un champ de saisie. Il se serre sur le texte. */
  width: fit-content;
  max-width: 100%;
  font-size: 1.34rem;
  font-weight: 500;
  letter-spacing: -.015em;
  line-height: 1.2;
  color: var(--if2m-texte);
}
/* Le script pose le focus sur ce titre au changement d'etape : il doit se
   voir, sinon le repere est perdu pour qui navigue au clavier. */
.if2m-form-bloc .if2m-form-etape-titre:focus-visible {
  outline: 2px solid var(--acc);
  outline-offset: 4px;
  border-radius: 6px;
}

/* -------------------------------------------------------------------------
   Les sections, a l'interieur d'une etape
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-partie + .if2m-form-partie,
.if2m-form-bloc .if2m-form-grille + .if2m-form-partie,
.if2m-form-bloc .if2m-form-partie + .if2m-form-grille { margin-top: 1.5rem; }

.if2m-form-bloc .if2m-form-partie-titre {
  margin: 0 0 .75rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--if2m-texte);
}
.if2m-form-bloc .if2m-form-partie-texte {
  margin: -.5rem 0 .85rem;
  font-size: .88rem;
  color: var(--if2m-texte-2);
}

/* -------------------------------------------------------------------------
   La grille de champs. Douze colonnes, comme la largeur enregistree en base.
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-grille {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1.05rem;
  align-items: start;
}
.if2m-form-bloc .if2m-form-grille:empty { display: none; }

.if2m-form-bloc .if2m-form-champ { grid-column: span 12; min-width: 0; }
.if2m-form-bloc .if2m-form-champ--6 { grid-column: span 6; }
.if2m-form-bloc .if2m-form-champ--4 { grid-column: span 4; }
.if2m-form-bloc .if2m-form-champ--3 { grid-column: span 3; }

@media (max-width: 760px) {
  .if2m-form-bloc .if2m-form-champ,
  .if2m-form-bloc .if2m-form-champ--6,
  .if2m-form-bloc .if2m-form-champ--4,
  .if2m-form-bloc .if2m-form-champ--3 { grid-column: span 12; }
}

/* -------------------------------------------------------------------------
   Les controles
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-etiquette {
  display: block;
  margin: 0 0 .34rem;
  /* Ce qu'on demande au visiteur se lit sans effort : au-dessus de 14 px. */
  font-size: .95rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--if2m-texte-2);
}
.if2m-form-bloc .if2m-form-requis { color: var(--sec-fonce); }

.if2m-form-bloc .if2m-form-champ input,
.if2m-form-bloc .if2m-form-champ select,
.if2m-form-bloc .if2m-form-champ textarea {
  font: inherit;
  font-size: .98rem;
  width: 100%;
  padding: .74rem .9rem;
  border: 1px solid var(--if2m-trait);
  border-radius: 11px;
  background: var(--if2m-fond);
  color: var(--if2m-texte);
}
.if2m-form-bloc .if2m-form-champ textarea { min-height: 7rem; resize: vertical; }
.if2m-form-bloc .if2m-form-champ input:focus,
.if2m-form-bloc .if2m-form-champ select:focus,
.if2m-form-bloc .if2m-form-champ textarea:focus {
  outline: 2px solid var(--acc);
  outline-offset: 1px;
  border-color: transparent;
}

.if2m-form-bloc .if2m-form-aide {
  margin: .35rem 0 0;
  font-size: .82rem;
  color: var(--if2m-texte-2);
}

.if2m-form-bloc .if2m-form-message-erreur {
  margin: .35rem 0 0;
  /* Pourquoi ca bloque se lit aussi bien que ce qu'on demande. */
  font-size: .9rem;
  font-weight: 500;
  color: var(--if2m-alerte);
}
.if2m-form-bloc .if2m-form-champ--erreur input,
.if2m-form-bloc .if2m-form-champ--erreur select,
.if2m-form-bloc .if2m-form-champ--erreur textarea {
  border-color: var(--if2m-alerte);
  background: var(--if2m-alerte-voile);
}

/* Cases a cocher, boutons radio, consentement */
.if2m-form-bloc .if2m-form-case {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .6rem;
  align-items: start;
  margin: 0;
  font-size: .9rem;
  font-weight: 400;
  line-height: 1.45;
  color: var(--if2m-texte-2);
  cursor: pointer;
}
.if2m-form-bloc .if2m-form-champ .if2m-form-case input {
  width: 1.15rem;
  height: 1.15rem;
  margin-top: .16rem;
  padding: 0;
  accent-color: var(--acc);
}
/* Le lien de la politique vit hors du <label> — il intercepterait sinon le
   clic destine a la case. On le range sous le texte du consentement, pas
   sous la case, pour qu'il se lise comme sa suite. */
.if2m-form-bloc .if2m-form-case-lien {
  display: inline-block;
  /* Rater le consentement, c'est quitter la page et perdre sa saisie : le lien
     s'ecarte de la case et offre une cible qu'un pouce atteint. */
  margin: .55rem 0 0 1.75rem;
  padding: .45rem .1rem;
  font-size: .9rem;
  color: var(--acc);
}

.if2m-form-bloc .if2m-form-groupe {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}
.if2m-form-bloc .if2m-form-legende {
  padding: 0;
  margin-bottom: .5rem;
  font-size: .86rem;
  font-weight: 500;
  color: var(--if2m-texte-2);
}
.if2m-form-bloc .if2m-form-choix {
  display: grid;
  gap: .45rem;
  grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
}
.if2m-form-bloc .if2m-form-choix .if2m-form-case {
  padding: .55rem .8rem;
  border: 1px solid var(--if2m-trait);
  border-radius: 11px;
  background: var(--if2m-fond);
}

/* Le piege a robots quitte l'ecran sans quitter le document : `display:none`
   se repere trop bien, et un robot l'eviterait. */
.if2m-form-bloc .if2m-form-piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* -------------------------------------------------------------------------
   Commandes : parcours, envoi, mentions
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1rem;
  margin-top: 1.9rem;
  padding-top: 1.35rem;
  border-top: 1px solid var(--if2m-trait);
}

.if2m-form-bloc .if2m-form-nav { display: flex; gap: .6rem; flex-wrap: wrap; }
.if2m-form-bloc .if2m-form-nav[hidden] { display: none; }

.if2m-form-bloc .if2m-form-pas,
.if2m-form-bloc .if2m-form-envoi {
  font: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  margin: 0;
  padding: .8rem 1.5rem;
  border-radius: 99px;
  border: 1px solid transparent;
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  transition: transform .3s var(--ressort), background .3s var(--t), border-color .3s var(--t);
}
.if2m-form-bloc .if2m-form-pas--suivant,
.if2m-form-bloc .if2m-form-envoi {
  background-color: var(--acc);
  background-image: var(--signal);
  background-size: 200% 100%;
  color: #fff;
}
.if2m-form-bloc .if2m-form-pas--precedent {
  background: transparent;
  background-image: none;
  border-color: var(--if2m-trait);
  color: var(--if2m-texte);
}
.if2m-form-bloc .if2m-form-pas:hover,
.if2m-form-bloc .if2m-form-envoi:hover { transform: translateY(-2px); }
.if2m-form-bloc .if2m-form-pas--precedent:hover {
  border-color: var(--acc);
  background: var(--if2m-fond-2);
}
.if2m-form-bloc .if2m-form-pas:focus-visible,
.if2m-form-bloc .if2m-form-envoi:focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; }
.if2m-form-bloc .if2m-form-envoi[hidden],
.if2m-form-bloc .if2m-form-pas[hidden] { display: none; }
.if2m-form-bloc .if2m-form-envoi[aria-busy="true"] { opacity: .75; cursor: progress; }

.if2m-form-bloc .if2m-form-mention {
  flex: 1 1 17rem;
  margin: 0;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--if2m-texte-2);
}
.if2m-form-bloc .if2m-form-mention-lien { color: var(--acc); }

/* -------------------------------------------------------------------------
   Zone de retour et ecran de confirmation
   ---------------------------------------------------------------------- */
.if2m-form-bloc .if2m-form-retour:empty { display: none; }
.if2m-form-bloc .if2m-form-retour {
  margin: 0 0 1.15rem;
  padding: .85rem 1.05rem;
  border-radius: 12px;
  font-size: .92rem;
}
.if2m-form-bloc .if2m-form-retour p { margin: 0; color: inherit; }
.if2m-form-bloc .if2m-form-retour--erreur {
  background: var(--if2m-alerte-voile);
  border: 1px solid color-mix(in oklab, var(--if2m-alerte) 34%, transparent);
  color: var(--if2m-alerte);
}
.if2m-form-bloc .if2m-form-retour--succes {
  background: var(--if2m-succes-voile);
  border: 1px solid color-mix(in oklab, var(--if2m-succes) 34%, transparent);
  color: var(--if2m-succes);
}
.if2m-form-bloc .if2m-form-retour:focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; }

.if2m-form-bloc .if2m-form-confirmation {
  padding: clamp(1.2rem, 3vw, 1.9rem);
  border-radius: var(--r);
  border: 1px solid color-mix(in oklab, var(--if2m-succes) 30%, transparent);
  background: var(--if2m-succes-voile);
}
/* Le script pose le focus sur ce bloc a l'envoi : l'anneau par defaut du
   navigateur, noir et carre, jurerait sur la plaque verte. */
.if2m-form-bloc .if2m-form-confirmation:focus-visible {
  outline: 2px solid var(--if2m-succes);
  outline-offset: 3px;
}
.if2m-form-bloc .if2m-form-confirmation h3 {
  margin: 0;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--if2m-succes);
}
.if2m-form-bloc .if2m-form-confirmation p {
  margin: .75rem 0 0;
  color: var(--if2m-texte-2);
  font-size: .95rem;
  max-width: 62ch;
}
.if2m-form-bloc .if2m-form-recommencer {
  margin-top: 1.15rem;
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  padding: .62rem 1.15rem;
  border-radius: 99px;
  border: 1px solid var(--if2m-trait);
  background: var(--if2m-fond);
  background-image: none;
  color: var(--if2m-texte);
  cursor: pointer;
}
.if2m-form-bloc .if2m-form-recommencer:hover { border-color: var(--acc); }

/* Dans une page d'article, le formulaire est pose au milieu de la prose : il
   lui faut une bordure pour se lire comme un objet et non comme la suite du
   texte. Dans une section de contact, le socle lui donne deja sa plaque de
   verre — on ne repasse pas par-dessus. */
.contenu > .if2m-form-bloc {
  margin-block: 1.8rem;
  padding: clamp(1.1rem, 2.6vw, 1.7rem);
  border: 1px solid var(--if2m-trait);
  border-radius: var(--r);
  background: var(--if2m-fond);
  box-shadow: var(--ombre-1);
}

/* -------------------------------------------------------------------------
   Neuf formulaires sur une page : l'accordeon natif, sans script.
   ---------------------------------------------------------------------- */
/* Un formulaire ne se lit pas sur 1240 px de large : l'oeil perd la ligne
   entre l'etiquette et son champ. Les blocs de contenu du socle plafonnent
   deja a 56ch, l'accordeon s'aligne dessus. */
.if2m-form-accordeons {
  display: grid;
  gap: .7rem;
  margin-top: 1.6rem;
  max-width: 52rem;
}
.if2m-form-accordeon {
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 14px;
  background: rgba(255, 255, 255, .05);
}
.if2m-form-accordeon > summary {
  cursor: pointer;
  padding: .95rem 1.15rem;
  font-size: .98rem;
  font-weight: 500;
  color: #fff;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.if2m-form-accordeon > summary::-webkit-details-marker { display: none; }
.if2m-form-accordeon > summary::after {
  content: "+";
  font-size: 1.35rem;
  line-height: 1;
  color: var(--acc-clair);
}
.if2m-form-accordeon[open] > summary::after { content: "–"; }
.if2m-form-accordeon > summary:focus-visible { outline: 2px solid var(--acc-clair); outline-offset: -3px; }
.if2m-form-accordeon > .if2m-form-bloc { margin: 0 .6rem .6rem; }

/* -------------------------------------------------------------------------
   Utilitaires
   ---------------------------------------------------------------------- */
.if2m-form-hors-ecran {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* -------------------------------------------------------------------------
   Telephone. La grille passe a une colonne au-dessus ; il reste a resserrer
   le repere d'etapes et les commandes pour qu'ils tiennent a 390 px.
   ---------------------------------------------------------------------- */
@media (max-width: 560px) {
  .if2m-form-bloc .if2m-form-fil-liste { gap: .35rem; }
  .if2m-form-bloc .if2m-form-fil-item {
    padding: .3rem .65rem .3rem .28rem;
    font-size: .88rem;
    gap: .4rem;
  }
  .if2m-form-bloc .if2m-form-fil-rang { width: 1.45rem; height: 1.45rem; font-size: .72rem; }
  .if2m-form-bloc .if2m-form-etape-titre { font-size: 1.18rem; }
  .if2m-form-bloc .if2m-form-nav { width: 100%; }
  .if2m-form-bloc .if2m-form-nav .if2m-form-pas { flex: 1 1 auto; }
  .if2m-form-bloc .if2m-form-envoi { width: 100%; }
  .if2m-form-bloc .if2m-form-mention { flex-basis: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .if2m-form-bloc .if2m-form-fil-item,
  .if2m-form-bloc .if2m-form-pas,
  .if2m-form-bloc .if2m-form-envoi { transition: none; }
  .if2m-form-bloc .if2m-form-pas:hover,
  .if2m-form-bloc .if2m-form-envoi:hover { transform: none; }
}

/* =========================================================================
   COMPOSANT « TARIFS MOBILE » — le sélecteur en quatre clics.

   Mêmes jetons que tout le reste de cette feuille (--acc, --trait, --papier,
   --r, --t, --ombre-1…), même idiome : rien n'a été renommé en entrant dans
   le socle. Attention à `.tarifs`, plus haut : c'est la grille de cartes de
   prix des pages piliers, un autre objet — aucun sélecteur n'est partagé
   avec les `.tarifs-*` d'ici.

   Trois contraintes ont dessiné ce composant :

   1. LA PAGE DOIT RESTER ENTIÈRE SANS JAVASCRIPT. Rien ici ne masque le
      repli de sa propre initiative : c'est le script qui pose
      `data-etat="pret"` sur le conteneur, une fois le catalogue lu ET le
      premier écran peint. Tant que cet attribut manque — script coupé,
      catalogue introuvable, erreur — la table des 28 modèles reste à
      l'écran, telle qu'elle est aujourd'hui.
   2. AUCUNE RÈGLE NE PART D'`opacity: 0`. Les changements d'écran ne jouent
      que sur `transform`, comme le reste du socle.
   3. LA GRILLE DE LOGOS TIENT À 390 px. Elle est écrite mobile d'abord, à
      trois colonnes, et chaque colonne est `minmax(0, 1fr)` : un nom de
      marque long ne peut pas pousser la grille hors de l'écran.
   ========================================================================= */

/* Le conteneur enveloppe le widget ET son repli. Le repli disparaît
   seulement quand le widget a réellement démarré ; il revient à la demande,
   déplié par le lien du pied de widget. */
.tarifs-mobile{margin-top:2.4rem}
.tarifs-mobile[data-etat="pret"] .tarifs-repli{display:none}
.tarifs-mobile[data-etat="pret"] .tarifs-repli[data-deplie]{display:block}
/* Sans script, le point de montage reste vide : il ne doit pas creuser un
   trou dans la page. */
.tarifs-widget:empty{display:none}

.tarifs-widget{border-radius:var(--r);border:1px solid var(--trait);background:var(--papier);
  box-shadow:var(--ombre-1);padding:clamp(1rem,2.6vw,1.7rem);display:grid;gap:1.1rem}
.nuit .tarifs-widget{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.14);box-shadow:none}

/* --- Le repère d'étapes -------------------------------------------------
   Quatre pastilles numérotées, pas une jauge qui se remplit : les barres de
   progression ont été refusées deux fois sur ce projet. Une pastille dit
   « où j'en suis » ; une jauge dit « combien il en reste ». */
.tw-fil{margin:0;padding:0;list-style:none;display:flex;flex-wrap:wrap;gap:.35rem .5rem;
  font-size:.82rem;color:var(--texte-2)}
.tw-fil li{display:inline-flex;align-items:center;gap:.4rem;padding:.28rem .6rem .28rem .3rem;
  border-radius:99px;border:1px solid transparent}
.tw-fil .n{width:1.45rem;height:1.45rem;flex:0 0 auto;display:grid;place-items:center;border-radius:99px;
  background:var(--papier-2);color:var(--texte-2);font-size:.76rem;font-weight:700;
  border:1px solid var(--trait)}
.tw-fil li[data-fait] .n{background:var(--acc-voile);color:var(--acc);border-color:transparent}
.tw-fil li[aria-current="step"]{border-color:var(--trait);background:var(--papier-2);color:var(--texte);
  font-weight:500}
.tw-fil li[aria-current="step"] .n{background-color:var(--acc);background-image:var(--signal);color:#fff;
  border-color:transparent}
.nuit .tw-fil{color:rgba(255,255,255,.7)}
.nuit .tw-fil .n{background:rgba(255,255,255,.09);color:#fff;border-color:rgba(255,255,255,.2)}
.nuit .tw-fil li[aria-current="step"]{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.2);
  color:#fff}

/* --- La tête de l'écran courant ---------------------------------------- */
.tw-tete{display:grid;gap:.35rem}
/* La commande la plus sollicitee du parcours, dans le coin le plus difficile
   a atteindre au pouce : elle passe la barre des 44 px. */
.tw-retour{justify-self:start;margin-bottom:.2rem;display:inline-flex;align-items:center;gap:.4rem;
  min-height:44px;padding:.6rem 1rem .6rem .8rem;border-radius:99px;border:1px solid var(--trait);background:transparent;
  color:var(--texte);font-family:inherit;font-size:.88rem;font-weight:450;cursor:pointer;
  transition:.24s var(--t)}
.tw-retour:hover{background:var(--papier-2);border-color:var(--acc);color:var(--acc)}
.tw-retour:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.tw-retour svg{width:1rem;height:1rem;flex:0 0 auto}
.nuit .tw-retour{color:#fff;border-color:rgba(255,255,255,.24)}
/* Le titre reçoit le focus à chaque changement d'étape : c'est ce qui dit au
   lecteur d'écran, et à l'œil, que l'écran a changé. `justify-self:start`
   pour que l'anneau de focus épouse le texte au lieu de barrer toute la
   largeur du widget. */
.tw-titre{font-size:clamp(1.12rem,2.4vw,1.32rem);font-weight:500;margin:0;justify-self:start}
.tw-titre:focus-visible{outline:2px solid var(--acc);outline-offset:4px;border-radius:4px}
.tw-rappel{margin:0;font-size:.9rem;color:var(--texte-2);display:flex;align-items:center;gap:.5rem;
  flex-wrap:wrap}
.nuit .tw-rappel{color:rgba(255,255,255,.72)}

/* La pastille de rappel — étape 2 et écran du tarif. Elle DOIT borner
   l'image : le logo porte ses dimensions natives en attributs (Apple fait
   814 × 1000) et, sans cette règle, il s'affichait à sa taille réelle et
   poussait la page à 851 px de large sur un écran de 390. Mesuré, pas
   supposé : `_diag-debordement.mjs` le donne élément par élément. */
.tw-rappel .logo,.tw-recap .logo{width:38px;height:26px;flex:0 0 auto;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  padding:.15rem;border-radius:6px;background:#fff;border:1px solid rgba(13,85,135,.16)}
.tw-rappel .logo img,.tw-recap .logo img{max-width:100%;max-height:100%;width:auto;height:auto;
  object-fit:contain;display:block}
.tw-rappel .logo .lettre,.tw-recap .logo .lettre{flex:1 1 auto;align-self:stretch;display:flex;
  align-items:center;justify-content:center;
  border-radius:4px;background:var(--acc-voile);color:var(--acc);font-weight:800;font-size:.8rem}

/* L'annonce du lecteur d'écran est VISIBLE aussi : ce qu'un aveugle entend,
   un voyant doit pouvoir le lire. */
.tw-annonce{margin:0;font-size:.82rem;color:var(--texte-2);letter-spacing:.02em}
.nuit .tw-annonce{color:rgba(255,255,255,.7)}

/* --- L'écran ------------------------------------------------------------
   Il glisse de 10 px au changement d'étape. TRANSFORM seulement. */
.tw-ecran{display:grid;gap:1rem}
.tw-ecran[data-anime]{animation:tw-entre .32s var(--t)}
@keyframes tw-entre{from{transform:translateY(10px)}to{transform:none}}
@media (prefers-reduced-motion:reduce){.tw-ecran[data-anime]{animation:none}}

/* --- Étape 1 : la grille de logos --------------------------------------
   Mobile d'abord, TROIS colonnes. `minmax(0,1fr)` et non `1fr` : sans le
   zéro, une case au contenu insécable impose sa largeur et fait déborder la
   grille — le défaut classique de CSS Grid. */
.tw-marques{list-style:none;margin:0;padding:0;display:grid;gap:.6rem;
  grid-template-columns:repeat(3,minmax(0,1fr))}
@media (min-width:560px){.tw-marques{grid-template-columns:repeat(4,minmax(0,1fr));gap:.75rem}}
@media (min-width:820px){.tw-marques{grid-template-columns:repeat(5,minmax(0,1fr))}}

/* FLEX, ET SURTOUT PAS GRID — la leçon coûte une capture d'écran.
   En grid, le conteneur de chaque carte était `display:grid;justify-items:
   center` : la colonne implicite se dimensionne alors sur le CONTENU, donc
   sur les 814 px natifs du logo Apple, et `width:100%` sur la pastille
   comme `max-height:100%` sur l'image se résolvaient contre une taille
   indéfinie — donc contre rien. Résultat vu à l'écran : les logos sortaient
   de leur carte et se chevauchaient. En flex, le bloc conteneur d'un enfant
   est la boîte de contenu du parent, dont la largeur est définie. */
.tw-marque{width:100%;min-width:0;display:flex;flex-direction:column;align-items:center;gap:.45rem;
  padding:.6rem .35rem .7rem;
  border-radius:14px;border:1px solid var(--trait);background:var(--papier);color:var(--texte);
  font-family:inherit;font-size:.84rem;font-weight:500;line-height:1.25;text-align:center;cursor:pointer;
  transition:transform .28s var(--ressort),border-color .24s var(--t),box-shadow .28s var(--t)}
.tw-marque:hover{transform:translateY(-3px);border-color:var(--acc);box-shadow:var(--ombre-1)}
.tw-marque:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.tw-marque .nom{display:block;width:100%;min-width:0;overflow-wrap:anywhere}

/* La pastille de logo est BLANCHE EN DUR, insensible au thème de la page.
   Raison mesurée sur la planche `_essai-logos-marques.html` : quatre logos
   sont des tracés noirs sur transparent (Apple, Asus, Oppo, Autres) et
   disparaissent sur fond sombre ; d'autres traînent un fond blanc opaque et
   y font une brique. Un fond clair fixe règle les deux cas d'un coup.
   `overflow:hidden` est la ceinture par-dessus les bretelles : quoi qu'il
   arrive au dimensionnement, un logo ne peut plus envahir la carte voisine. */
.tw-marque .logo{width:100%;aspect-ratio:3/2;overflow:hidden;
  display:flex;align-items:center;justify-content:center;padding:.3rem;
  border-radius:8px;background:#fff;border:1px solid rgba(13,85,135,.16)}
.tw-marque .logo img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;display:block}
/* Le repli quand le fichier manque ou ne charge pas : la pastille-lettre. */
.tw-marque .lettre{flex:1 1 auto;align-self:stretch;display:flex;align-items:center;justify-content:center;
  border-radius:6px;background:var(--acc-voile);color:var(--acc);font-weight:800;
  font-size:clamp(1.1rem,4.4vw,1.6rem)}

/* --- Étapes 2 et 3 : les listes de choix -------------------------------- */
.tw-liste{list-style:none;margin:0;padding:0;display:grid;gap:.5rem;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,13rem),1fr))}
.tw-choix{width:100%;height:100%;display:flex;align-items:center;justify-content:space-between;gap:.7rem;
  padding:.8rem 1rem;border-radius:12px;border:1px solid var(--trait);background:var(--papier);
  color:var(--texte);font-family:inherit;font-size:.96rem;font-weight:450;text-align:left;cursor:pointer;
  transition:transform .26s var(--t),border-color .24s var(--t),background-color .24s var(--t)}
.tw-choix:hover{transform:translateX(3px);border-color:var(--acc);background:var(--acc-voile)}
.tw-choix:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.tw-choix .fleche{flex:0 0 auto;width:1.05rem;height:1.05rem;color:var(--acc)}
.nuit .tw-marque,.nuit .tw-choix{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.16);
  color:#fff}
.nuit .tw-choix:hover{background:rgba(255,255,255,.1)}

/* --- Étape 4 : le tarif -------------------------------------------------
   C'est l'écran qui justifie tout le parcours : le prix y est l'objet le
   plus gros du bloc. `clamp` en vw pour qu'à 390 px il reste dedans. */
.tw-resultat{display:grid;gap:1rem;padding:clamp(1rem,3vw,1.5rem);border-radius:var(--r);
  border:1px solid transparent;box-shadow:var(--ombre-1);
  background:linear-gradient(158deg,color-mix(in oklab,var(--acc-voile) 55%,#fff),var(--acc-voile)) padding-box,
    var(--signal-clair) border-box}
.tw-recap{margin:0;display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;font-size:.94rem;
  color:var(--texte-2)}
.tw-recap b{color:var(--texte);font-weight:600}

.tw-prix{margin:0;display:flex;align-items:baseline;gap:.2rem;flex-wrap:wrap;line-height:1;
  font-weight:600;color:var(--acc);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.tw-prix .montant{font-size:clamp(3rem,13vw,4.6rem);letter-spacing:-.02em}
.tw-prix .devise{font-size:clamp(1.5rem,6vw,2.2rem);font-weight:500}
/* « Sur devis » n'est pas un nombre : il lui faut sa propre taille pour
   tenir sur une ligne à 390 px. */
.tw-prix .devis{font-size:clamp(1.8rem,7.6vw,2.8rem);letter-spacing:-.01em}
.tw-prix-libelle{margin:0;font-size:1.02rem;font-weight:500;color:var(--texte)}
.tw-prix-mention{margin:0;font-size:.86rem;color:var(--texte-2)}

/* Délai et garantie n'apparaissent QUE si le catalogue les renseigne : à ce
   jour `reglages.delai` et `reglages.garantie` sont vides et listés dans
   `a_renseigner`. Les remplir d'office ferait afficher au site un engagement
   que personne n'a pris. */
.tw-reperes{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.5rem}
.tw-reperes li{display:inline-flex;align-items:center;gap:.45rem;padding:.4rem .85rem;border-radius:99px;
  background:var(--papier);border:1px solid var(--trait);font-size:.88rem;color:var(--texte)}
.tw-reperes svg{width:1.05rem;height:1.05rem;flex:0 0 auto;color:var(--acc)}

.tw-actions{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:.2rem}
.tw-actions .bouton{font-size:.94rem;padding:.78rem 1.25rem}

/* Les autres réparations du même modèle : repliées, pour comparer sans
   refaire le parcours. `<details>` natif — il s'ouvre au clavier et son
   contenu reste trouvable par la recherche du navigateur, même replié. */
.tw-autres{border-top:1px dashed var(--trait);padding-top:.85rem}
.tw-autres summary{cursor:pointer;font-size:.95rem;font-weight:500;color:var(--acc);list-style:none;
  display:flex;align-items:center;gap:.45rem;min-height:44px;padding-block:.5rem}
.tw-autres summary::-webkit-details-marker{display:none}
.tw-autres summary::before{content:"";width:.5rem;height:.5rem;flex:0 0 auto;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;rotate:-45deg;
  transition:rotate .24s var(--t);translate:0 -1px}
.tw-autres[open] summary::before{rotate:45deg;translate:0 -2px}
.tw-autres summary:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:4px}
.tw-autres ul{list-style:none;margin:.7rem 0 0;padding:0;display:grid;font-size:.9rem}
.tw-autres li{border-bottom:1px solid color-mix(in oklab,var(--trait) 60%,transparent)}
.tw-autres li:last-child{border-bottom:0}
/* Chaque ligne est un bouton : comparer les autres réparations ne doit pas
   obliger à refaire le parcours depuis la marque. */
/* Six cibles de 34 px collees les unes aux autres, c'est le mauvais tarif
   ouvert par erreur : on les espace et on les grandit. */
.tw-autre{width:100%;display:flex;align-items:center;justify-content:space-between;gap:1rem;
  min-height:44px;padding:.7rem .5rem;border:0;border-radius:8px;background:transparent;font-family:inherit;
  font-size:.9rem;font-weight:450;color:var(--texte-2);text-align:left;cursor:pointer;
  transition:background-color .22s var(--t),color .22s var(--t)}
.tw-autre:hover{background:rgba(255,255,255,.62);color:var(--acc)}
.tw-autre:focus-visible{outline:2px solid var(--acc);outline-offset:1px}
.tw-autres .m{font-variant-numeric:tabular-nums;font-weight:600;color:var(--texte);white-space:nowrap}

/* --- Le pied du widget -------------------------------------------------- */
.tw-pied{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem 1rem;
  border-top:1px solid var(--trait);padding-top:.9rem}
/* C'est la seule porte de sortie du visiteur qui ne trouve pas son modele :
   elle ne peut pas faire 18 px de haut pour un pouce. */
.tw-table{background:transparent;border:0;padding:.7rem .2rem;min-height:44px;display:inline-flex;
  align-items:center;font-family:inherit;font-size:.9rem;font-weight:500;
  color:var(--acc);cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.tw-table:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:4px}
.tw-pied .mention{margin:0;font-size:.82rem;color:var(--texte-2)}
.nuit .tw-pied{border-color:rgba(255,255,255,.14)}
.nuit .tw-pied .mention{color:rgba(255,255,255,.7)}

/* Le message d'échec du chargement. Il ne s'affiche que si le script a
   démarré mais n'a pas su lire le catalogue — auquel cas la table complète
   reste affichée en dessous, et cette phrase explique pourquoi. */
.tw-panne{margin:0;padding:.85rem 1.05rem;border-radius:12px;font-size:.9rem;color:var(--texte);
  border:1px solid var(--trait);background:var(--papier-2)}

/* =========================================================================
   CE QUE LE REPLI DOIT DIRE, ET CE QU'IL NE DOIT PAS LAISSER FAIRE
   ========================================================================= */

/* --- La maquette n'envoie rien : elle le dit AVANT, pas apres ------------
   Le bouton « Envoyer ma demande » d'une maquette, sans JavaScript, faisait
   recharger la page (`action="#"`), effacait toute la saisie et n'affichait
   AUCUN message. Ce n'est plus le cas : `action="envoi.php"` mene a un vrai
   recepteur, et le bouton d'envoi reste donc VISIBLE sans script — le
   formulaire part, la demande arrive. L'encart ne dit plus que le formulaire
   n'envoie rien (il le disait encore le 09/09, au-dessus d'un bouton qui
   marchait) : il explique seulement que les etapes s'affichent d'un coup,
   faute du parcours pas a pas. Avec script, il disparait. */
/* La regle ne s'ecrit qu'en NEGATIF : elle doit depasser la specificite de
   `.if2m-form-bloc .if2m-form-envoi`, posee plus haut, sans jamais l'emporter
   sur `[hidden]` — c'est ainsi que le parcours par etapes range le bouton
   d'envoi tant qu'on n'est pas sur la derniere. */
.if2m-form-nojs{flex:1 1 100%;margin:0;padding:.85rem 1rem;border-radius:10px;
  border:1px solid color-mix(in oklab,var(--acc) 32%,var(--trait));
  background:var(--acc-voile);color:var(--texte);font-size:.95rem;line-height:1.5}
html.js .if2m-form-nojs{display:none}

/* Sans JavaScript, personne n'ecoute le bouton d'affichage de la carte : on ne
   montre pas une commande qui ne repond pas. L'adresse, la mention Google et
   les deux liens d'itineraire, eux, restent — rien n'est perdu.
   Au premier niveau, surtout pas dans la media query du tiroir : la regle vaut
   a toutes les largeurs, pas seulement sous 1024 px. */
html:not(.js) #plan-acces-afficher{display:none}

/* --- Le rappel de ce qui vient d'etre clique ----------------------------
   Le selecteur annonce « 279 € pour un ecran d'iPhone 13 », puis renvoie ici.
   Sans rappel, le visiteur arrive sur un formulaire anonyme et n'a plus aucun
   moyen de verifier qu'il demande bien la reparation qu'on lui a chiffree. */
.if2m-form-rappel{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem .8rem;
  margin:0 0 1.1rem;padding:.8rem 1rem;border-radius:12px;
  border:1px solid color-mix(in oklab,var(--acc) 26%,var(--trait));
  background:var(--acc-voile);font-size:.95rem}
.if2m-form-rappel-tete{font-weight:700;color:var(--acc);letter-spacing:.02em}
.if2m-form-rappel-item{color:var(--texte)}
.if2m-form-rappel-item b{font-weight:500;color:var(--texte-2)}
.if2m-form-rappel-tarif{font-weight:700}

/* --- Les consignes du selecteur ne survivent pas au selecteur ------------
   « Cliquez sur le logo de la marque » n'a aucun sens quand il n'y a pas de
   logo a cliquer : ces cartes restaient affichees sans JavaScript, au-dessus
   d'une simple table. Elles ne se montrent donc qu'une fois le selecteur
   REELLEMENT peint — c'est le meme drapeau qui replie la table. */
[data-tarifs-consignes]:not([data-vu]){display:none}
/* La note de repli dit ce que le visiteur a REELLEMENT sous les yeux quand le
   selecteur ne se peint pas ; elle s'efface des qu'il se peint. */
[data-tarifs-repli-note][data-vu]{display:none}
[data-tarifs-repli-note]{margin:1.6rem 0 0;padding:.9rem 1.1rem;border-radius:12px;
  border:1px solid var(--trait);background:var(--papier);color:var(--texte-2);font-size:.95rem}

/* --- Les autres reparations : des cibles distinctes ---------------------- */
.tw-autres li + li{margin-top:.15rem}

/* --- Reflow a 320 px ----------------------------------------------------
   Le contenu de la carte « pour aller plus loin » ne pouvait pas se retrecir
   sous sa largeur minimale : la page reclamait 335 px pour 320 disponibles. */
.pour-aller-plus-loin > *{min-width:0}
@media (max-width:400px){.pour-aller-plus-loin{flex-wrap:wrap;padding:1.1rem}}

/* --- La marque dans le repli : le meme logo que dans le selecteur --------
   Le selecteur montre quinze logos ; la table de repli n'en montrait que sept
   sur une page et aucun sur l'autre. Deux vues des memes donnees ne doivent
   pas se ressembler si peu. La pastille-lettre reste le repli du repli. */
.logo-marque{display:flex;align-items:center;gap:.6rem;font-weight:500;color:var(--texte)}
.logo-marque img{width:34px;height:24px;object-fit:contain;flex:0 0 auto}
.logo-marque .lettre{width:34px;height:24px;flex:0 0 auto;display:grid;place-items:center;
  border-radius:6px;background:var(--acc-voile);color:var(--acc);font-weight:700;font-size:.86rem}


/* =====================================================================
   « LE DOUBLE » — ce qui traverse d'un univers a l'autre.
   Un seul principe : TOUT LIEN QUI FAIT CHANGER D'EN-TETE PORTE LA
   PASTILLE DE L'AUTRE UNIVERS. La pastille existe deja (.bascule-lien i) ;
   on ne fait que la sortir de l'en-tete.

   C2 — le ruban de retour a ete ABANDONNE : .db-ruban n'est PAS ici, et sa
   promesse a ete retiree de la carte de pvente-part.html. On ne laisse pas
   dans la feuille un dispositif que rien n'emploie.
   ================================================================== */
.db-autre{display:inline-flex;align-items:center;gap:.4rem}
.db-autre::before{content:"";width:.5rem;height:.5rem;border-radius:50%;
  background:var(--autre);flex:0 0 auto}
/* Un lien de corps qui traverse vers l'autre espace le DIT. Sans cette mention,
   l'en-tete, le pied et la barre d'action basculent sans que rien ne l'annonce —
   exactement ce que le decoupage en deux univers cherche a eviter. */
.db-note{display:inline-flex;align-items:center;gap:.32rem;margin-left:.4rem;
  font-size:.76rem;font-weight:500;letter-spacing:.02em;color:var(--texte-2);
  white-space:nowrap;vertical-align:baseline}
.db-note::before{content:"";width:.42rem;height:.42rem;border-radius:50%;
  background:var(--autre);flex:0 0 auto}
.db-renvoi{margin-top:2.6rem;padding:1.5rem 1.6rem;border-radius:var(--r);
  border:1px solid var(--trait);border-left:3px solid var(--autre);
  background:var(--papier);box-shadow:0 14px 34px -26px rgba(13,20,32,.5)}
.db-renvoi .db-oeil{margin:0;font-size:.74rem;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sec-fonce)}
.db-renvoi h2{margin:.55rem 0 0;font-size:1.22rem;font-weight:500;letter-spacing:-.015em}
.db-renvoi p{margin:.55rem 0 0;font-size:.93rem;color:var(--texte-2);max-width:68ch}
/* La carte NOMME les fiches d'en face : un renvoi qui dit « allez voir
   ailleurs » sans dire quoi ne fait que deplacer le lecteur. */
.db-liste{list-style:none;margin:.9rem 0 0;padding:0;display:grid;gap:.1rem}
.db-liste li{display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .7rem;
  padding-block:.34rem;border-top:1px solid var(--trait)}
.db-liste a{font-size:.93rem;font-weight:500;color:var(--texte);text-decoration:none}
.db-liste a:hover{color:var(--acc);text-decoration:underline}
.db-liste span{font-size:.74rem;letter-spacing:.07em;text-transform:uppercase;
  font-weight:700;color:var(--texte-2)}
.db-renvoi-lien{display:inline-flex;align-items:center;gap:.45rem;margin-top:1rem;
  padding:.6rem 1.1rem;border-radius:99px;font-size:.9rem;font-weight:500;
  border:1px solid var(--trait);background:var(--papier-2);color:var(--sec-fonce);
  text-decoration:none;transition:.22s var(--t)}
.db-renvoi-lien:hover{border-color:var(--autre);transform:translateY(-2px)}

/* =========================================================================
   LA FICHE — le gabarit des pages article
   -------------------------------------------------------------------------
   Ce bloc est colle a la fin de site/socle.css. Il ne modifie aucune regle
   existante : tous ses selecteurs sont prefixes « fi- » et portes par « .fi »,
   ce qui les met a (0-2-0) au minimum — au-dessus des « .contenu h2 »,
   « .contenu ul », « .contenu a » du socle, qui sont a (0-1-1). Sans cette
   precaution, le titre d'oeil sort a 2,1 rem et les listes reprennent la puce
   du socle : constate a la capture, pas devine.

   LE PROBLEME RESOLU. Une page d'article ne portait qu'un <h1> et son corps,
   dans une colonne de 74ch calee A GAUCHE d'une grille de 1240 px. Trois
   defauts mesures : la ligne faisait 103 signes (« ch » vaut la largeur du
   zero ; celui d'Outfit est large, l'unite ment de 40 %), la moitie droite de
   l'ecran restait vide sur toute la hauteur, et l'aparte « Dans la meme
   rubrique » listait Accueil / Accueil PRO / Accueil PART / KUBB / Newsletter
   — les memes cinq liens sur les treize articles.

   LE PARTI. Un article d'IF2M n'est pas un billet : c'est une fiche technique
   ecrite par des gens qui ouvrent des machines. Elle a donc une TETE (de quoi
   il s'agit, depuis quand, pour combien de temps de lecture), des POINTS DE
   CONTROLE, un PLAN pose dans la marge, un CORPS numerote, une PORTE vers
   l'atelier et une SUITE. Aucun article n'a de photo et ce n'est pas
   provisoire : c'est le glyphe de la rubrique — un objet du metier, deja
   dessine dans outils/lib/symboles.mjs — qui porte l'image.

   CE QU'IL N'Y A PAS, volontairement : aucun fil de lecture, aucune jauge de
   defilement, aucun sommaire qui se remplit, aucune entree courante, aucun
   position:sticky. Les numeros de section sont une numerotation de document,
   immobile ; rien ne dit jamais « 3 sur 7 » et rien ne suit le lecteur.
   ========================================================================= */

/* La display a empattements. Les deux fichiers sont DEJA dans le depot
   (site/vendor/fonts/dmserif-*.woff2) et n'etaient references par aucune
   page : aucun octet de plus a telecharger pour le reste du site, aucun appel
   tiers. Elle ne sert QUE dans les articles — h1, h2 de section, h2 de la
   porte — et rien d'autre. Sur une page sans photo, le changement de FAMILLE
   fait la hierarchie : un h3 qui revient en Outfit apres un h2 a empattements
   se lit sans avoir besoin d'etre plus gros. Pour la retirer, repointer
   --fi-titre sur la pile du site : rien d'autre ne bouge. */
@font-face{font-family:'IF2M Titre';font-style:normal;font-weight:400;font-display:swap;
  src:url('vendor/fonts/dmserif-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'IF2M Titre';font-style:normal;font-weight:400;font-display:swap;
  src:url('vendor/fonts/dmserif-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}

:root{
  --fi-titre:'IF2M Titre',Georgia,'Times New Roman',serif;
  --fi-sans:'Outfit',system-ui,-apple-system,'Segoe UI',sans-serif;
}

/* La coquille pose « class="contenu contenu--fiche » et le socle borne
   .contenu a 74ch. La fiche porte elle-meme ses largeurs. La regle est ecrite
   « .contenu.contenu--fiche » (0-2-0) et non « .contenu--fiche » (0-1-0) :
   a specificite egale elle dependrait de l'ordre de declaration, donc de la
   position de ce bloc dans le fichier. */
.contenu.contenu--fiche{max-width:none;
  /* « min-width:0 » N'EST PAS DECORATIF. La coquille pose le contenu dans une
     grille « grid-template-columns:1fr », c'est-a-dire « minmax(auto,1fr) » :
     la piste se dimensionne alors sur le contenu le plus large et non sur la
     place disponible. Un tableau de 28 rem enferme dans son cadre a defilement
     poussait la colonne a 579 px dans un telephone de 390 — 209 px de
     debordement, que « body{overflow-x:hidden} » du socle masquait au lieu de
     le signaler. Trouve sur la page d'epreuve, aucun article n'ayant encore de
     tableau. */
  min-width:0}

.fi{
  /* LA MESURE, EN SIGNES REELS. 38,5 rem donnent 66 a 73 signes par ligne
     selon la largeur de fenetre — mesure au navigateur, en divisant la
     longueur du texte par le nombre de lignes rendues. C'est un PLAFOND EN
     REM pose sur la colonne, pas une consequence de la grille : la mesure ne
     depend donc d'aucun point de rupture. Le defaut le plus grave releve dans
     ce chantier etait exactement l'inverse — une colonne qui n'existait
     qu'au-dessus de 1080 px et courait bord a bord a 1024, a 115 signes. */
  --mesure:35rem;
  /* LA COULEUR D'APPUI. Mesure sur les pixels rendus, pas sur les jetons :
     sous une tache de la nuee, --acc PART (#C2410C, 5,18 sur papier blanc)
     tombe entre 4,17 et 4,59 des qu'il porte de PETIT texte — petites
     capitales, numeros de section, amorces en gras. Le fond n'y peut rien :
     c'est la nuee, elle est voulue. On assombrit donc l'accent LA OU il porte
     du petit texte. Ailleurs (liens du corps, boutons, glyphes), l'accent
     reste l'accent. */
  --fi-appui:color-mix(in oklab,var(--acc) 74%,var(--encre));
  max-width:62rem;margin-inline:auto}

/* Un nombre a tirets ne se coupe pas. « la regle 3-2-1 » sortait en « 3-2- »
   puis « 1 » a la ligne suivante, dans un titre de 2,9 rem : a cette taille ca
   se lit comme une coquille. construire.mjs pose la classe autour des suites
   de chiffres relies par des tirets, dans le h1, dans les h2 et dans le plan. */
.fi .fi-nb{white-space:nowrap}

/* Le socle pose « section{padding-block:clamp(3.6rem,8vw,7rem)} » pour les
   sections de PAGE. Les sections de la fiche sont des sections de DOCUMENT :
   sans cette remise a zero, chacune emportait 102 px de blanc en haut ET en
   bas a 1280 px, et « La suite » flottait au milieu de 205 px de vide. Rien
   ne le signalait — ni la CI, ni le HTML, ni la page qui repondait. */
.fi section{padding-block:0}

/* Le titre d'oeil : le meme objet cinq fois — points de controle, plan,
   porte, suite. Il porte du petit texte a meme le fond, donc l'appui. */
.fi .fi-titret{display:flex;align-items:center;gap:.6rem;margin:0;
  font-size:.73rem;letter-spacing:.19em;text-transform:uppercase;font-weight:700;
  line-height:1.3;color:var(--fi-appui)}
.fi .fi-titret::before{content:"";width:2.1rem;height:2px;border-radius:2px;flex:0 0 auto;
  background:var(--signal-clair)}

/* -------------------------------------------------------------------------
   1. LA TETE — le cartouche de la fiche
   ---------------------------------------------------------------------- */
.fi .fi-tete{margin:0 0 clamp(1.4rem,2.8vw,2.1rem)}
.fi .fi-plaque{position:relative;overflow:hidden;isolation:isolate;
  padding:clamp(1.4rem,3.2vw,2.6rem) clamp(1.2rem,3.2vw,2.8rem);
  border:1px solid transparent;border-radius:calc(var(--r) + 6px);
  background:
    linear-gradient(152deg,color-mix(in oklab,var(--nuee-1) 66%,#fff) 0%,
      #fff 48%,color-mix(in oklab,var(--nuee-2) 62%,#fff) 100%) padding-box,
    linear-gradient(140deg,color-mix(in oklab,var(--acc) 30%,#fff),
      color-mix(in oklab,var(--mediane) 34%,#fff) 48%,
      color-mix(in oklab,var(--sec) 34%,#fff)) border-box;
  box-shadow:var(--ombre-1)}
/* Les hachures de .fa-tete, reprises telles quelles : c'est le motif de la
   vignette des cartes d'actualites, donc la meme famille d'objets. */
.fi .fi-plaque::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:repeating-linear-gradient(115deg,rgba(255,255,255,.5) 0 2px,transparent 2px 22px);
  -webkit-mask-image:linear-gradient(205deg,#000,transparent 66%);
          mask-image:linear-gradient(205deg,#000,transparent 66%)}
/* Le trait de signal en tete de plaque : 3 px, decoratif. Il ne porte JAMAIS
   de texte — var(--signal) finit sur #C2410C (5,18), mais un filet de 3 px
   n'a de toute facon rien a porter. */
.fi .fi-plaque::after{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:var(--signal)}

/* LE FILIGRANE. Il occupe la place que prendrait un cliche, assez pale pour
   ne rien couter au contraste du texte pose devant. Il est coupe par
   l'overflow:hidden de la plaque : la page ne deborde pas d'un pixel. */
.fi .fi-filigrane{position:absolute;z-index:-1;pointer-events:none;
  right:-2.4rem;top:50%;translate:0 -50%;
  width:clamp(9rem,25vw,18rem);height:auto;aspect-ratio:1;
  color:var(--acc);opacity:.13;
  fill:none;stroke:currentColor;stroke-width:1.05;stroke-linecap:round;stroke-linejoin:round}
@media (max-width:719px){
  .fi .fi-filigrane{top:-1.4rem;right:-3rem;translate:none;width:10.5rem;opacity:.075}
}

.fi .fi-oeil{display:flex;align-items:center;gap:.55rem;flex-wrap:wrap;margin:0;
  font-size:.73rem;letter-spacing:.19em;text-transform:uppercase;font-weight:700;
  color:var(--fi-appui);line-height:1.3;text-decoration:none}
.fi .fi-oeil svg{width:1.6rem;height:1.6rem;flex:0 0 auto;color:var(--acc);
  fill:none;stroke:currentColor;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
.fi a.fi-oeil .fi-rub{border-bottom:1px solid transparent;transition:border-color .22s var(--t)}
.fi a.fi-oeil:hover .fi-rub{border-bottom-color:currentColor}
.fi a.fi-oeil:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:6px}
.fi .fi-oeil .fi-genre{color:var(--texte-2);font-weight:600;letter-spacing:.16em}
.fi .fi-oeil .fi-sep{color:color-mix(in oklab,var(--texte-2) 45%,transparent);font-weight:400}

.fi .fi-plaque h1{font-family:var(--fi-titre);margin:.95rem 0 0;max-width:19ch;
  font-size:clamp(1.85rem,4vw,2.9rem);font-weight:400;
  line-height:1.06;letter-spacing:-.012em;color:var(--texte)}

/* LE CHAPO. C'est le premier paragraphe de l'article lui-meme, remonte ici
   par construire.mjs — PAS le champ « resume » du front-matter : celui-ci est
   une troncature a 26 mots du meme paragraphe, terminee par des points de
   suspension sur les treize fiches. Afficher les deux serait une redite ;
   n'afficher que la version tronquee serait un recul. Quatre parametres le
   separent du corps : la taille, la graisse, la couleur et la largeur. */
.fi .fi-chapo{margin:1.05rem 0 0;max-width:52ch;
  font-size:clamp(1.04rem,.92rem + .5vw,1.18rem);line-height:1.58;
  color:var(--texte);font-weight:400}

.fi .fi-reperes{display:flex;flex-wrap:wrap;gap:.85rem 0;margin:1.4rem 0 0;padding-top:1.1rem;
  border-top:1px solid color-mix(in oklab,var(--acc) 20%,var(--trait))}
.fi .fi-reperes>div{display:grid;gap:.1rem;padding-right:1.7rem}
.fi .fi-reperes>div+div{padding-left:1.7rem;
  border-left:1px solid color-mix(in oklab,var(--acc) 16%,var(--trait))}
.fi .fi-reperes dt{font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;
  font-weight:700;color:var(--texte-2)}
.fi .fi-reperes dd{margin:0;font-size:.92rem;font-weight:500;color:var(--texte);
  font-variant-numeric:tabular-nums}
/* AU TELEPHONE LES REPERES RESTENT EN LIGNE. Empiles, les trois couples
   coutaient 150 px de sas avant la premiere phrase de l'article, sur une page
   dont le seul travail est de faire lire. Mesure faite a 390 px. */
@media (max-width:560px){
  .fi .fi-reperes{display:grid;grid-template-columns:auto auto;
    justify-content:start;gap:.6rem 1.7rem}
  .fi .fi-reperes>div{padding-right:0}
  .fi .fi-reperes>div+div{padding-left:0;border-left:0}
  .fi .fi-reperes>div:nth-child(3){grid-column:1 / -1}
  .fi .fi-reperes dd{font-size:.86rem}
  /* La barre oblique separait deux libelles qui ne sont plus sur la meme
     ligne : elle restait pendue au bout de la premiere. */
  .fi .fi-oeil .fi-sep{display:none}
}

/* -------------------------------------------------------------------------
   3. LE PLAN — un sommaire ancre, immobile
   Construit a partir des h2 du corps, en dur, a la construction.
   ---------------------------------------------------------------------- */
.fi .fi-plan{--mx:50%;--my:0%;position:relative;isolation:isolate;
  margin:0 0 clamp(1.5rem,3vw,2.2rem);
  padding:clamp(1rem,2.2vw,1.4rem) clamp(1.05rem,2.3vw,1.6rem) clamp(.45rem,1.3vw,.8rem);
  border:1px solid transparent;border-radius:var(--r);
  background:
    linear-gradient(var(--papier),var(--papier)) padding-box,
    linear-gradient(120deg,color-mix(in oklab,var(--acc) 20%,#fff),
      color-mix(in oklab,var(--acc-clair) 26%,#fff) 50%,
      color-mix(in oklab,var(--sec) 26%,#fff)) border-box;
  box-shadow:var(--ombre-1)}
/* La meme lueur au curseur que les cartes du site : socle.js ecrit --mx/--my.
   Sans le script, la carte reste exactement ce qu'elle est. */
.fi .fi-plan::before{content:"";position:absolute;inset:0;z-index:-1;opacity:0;border-radius:var(--r);
  background:radial-gradient(300px 260px at var(--mx) var(--my),
    color-mix(in oklab,var(--sec) 15%,transparent),transparent 72%);
  transition:opacity .4s var(--t)}
.fi .fi-plan:hover::before{opacity:1}
/* Deux colonnes en flux COLONNE : 01-04 a gauche, 05-07 a droite. Une grille
   remplit par RANGEES et donnerait 01-02 / 03-04, c'est-a-dire un plan lu en
   zigzag pour un objet qui est une suite — et sur les trois fiches dont
   l'auteur numerote ses propres titres, une table des matieres qui presente
   l'article dans le desordre. `columns` equilibre tout seul, quel que soit le
   nombre de sections : six ici, onze sur la fiche telephonie. */
.fi .fi-plan ol{list-style:none;margin:.75rem 0 0;padding:0;display:block;counter-reset:fiplan}
@media (min-width:760px) and (max-width:1079px){.fi .fi-plan ol{columns:2;column-gap:2.4rem}}
.fi .fi-plan li{break-inside:avoid;margin:0;counter-increment:fiplan}
.fi .fi-plan a{display:grid;grid-template-columns:2.3rem 1fr;align-items:baseline;gap:.2rem;
  padding:.42rem .1rem;text-decoration:none;color:var(--texte);
  font-size:.91rem;line-height:1.32;
  border-bottom:1px solid var(--trait);transition:color .22s var(--t)}
/* LA COLONNE DE REPERE. Trois fiches sur treize numerotent DEJA leurs propres
   titres (« 1. Le passage en SSD… ») : y ajouter « 02 » donnait « 02  1. Le
   passage en SSD ». Quand le texte se numerote lui-meme, la fiche renonce a
   son compteur et pose un losange — le signe du bandeau du site.
   construire.mjs pose la classe, la CSS ne fait qu'obeir. */
.fi .fi-plan a::before{font-size:.72rem;font-weight:700;letter-spacing:.11em;
  color:var(--fi-appui);font-variant-numeric:tabular-nums}
.fi--numerote .fi-plan a::before{content:counter(fiplan,decimal-leading-zero)}
/* Le losange est DESSINE, pas ecrit : Outfit ne porte pas U+25C6 et le
   caractere sortait en tofu. Constate a la capture. */
.fi:not(.fi--numerote) .fi-plan a::before{content:"";align-self:center;justify-self:start;
  margin-left:.5rem;width:.4rem;height:.4rem;rotate:45deg;border-radius:1px;
  border:1.6px solid var(--acc)}
/* La couleur seule ne signale rien : le survol souligne aussi. */
.fi .fi-plan a:hover{color:var(--acc)}
.fi .fi-plan a:hover span{text-decoration:underline;text-underline-offset:.18em}
.fi .fi-plan a:hover::before{color:var(--sec-fonce)}
.fi .fi-plan a:focus-visible{outline:2px solid var(--acc);outline-offset:2px;border-radius:8px}
.fi .fi-plan li:last-child a{border-bottom:0}
/* -------------------------------------------------------------------------
   4. LES POINTS DE CONTROLE — « ce qu'il faut retenir »
   Le contenu vient d'un champ « a_retenir » ECRIT dans le front-matter, pas
   d'un resume calcule : une machine qui condense un texte technique finit par
   affirmer un delai, un prix ou une garantie que personne n'a promis. Champ
   absent, bloc absent — la fiche tient sans lui.
   ---------------------------------------------------------------------- */
.fi .fi-retenir{position:relative;overflow:hidden;
  margin:0 0 clamp(1.7rem,3.4vw,2.6rem);
  padding:clamp(1rem,2.2vw,1.35rem) clamp(1.05rem,2.3vw,1.5rem)
          clamp(1rem,2.2vw,1.35rem) clamp(1.4rem,2.9vw,1.9rem);
  border-radius:var(--r);background:var(--acc-voile);
  border:1px solid color-mix(in oklab,var(--acc) 22%,var(--acc-voile))}
.fi .fi-retenir::before{content:"";position:absolute;left:0;top:0;bottom:0;width:5px;
  background:var(--signal-180)}
.fi .fi-retenir ul{list-style:none;margin:.75rem 0 0;padding:0;display:grid;gap:.55rem}
.fi .fi-retenir li{display:grid;grid-template-columns:1.1rem 1fr;gap:.65rem;align-items:start;
  color:var(--texte);font-size:.94rem;line-height:1.44;margin:0}
.fi .fi-retenir li::before{content:"";width:1.1rem;height:1.1rem;margin-top:.18rem;
  background:var(--acc);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 12.5l5.2 5.2L20 6.8' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 12.5l5.2 5.2L20 6.8' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}

/* -------------------------------------------------------------------------
   5. LE CORPS — la lecture longue
   ---------------------------------------------------------------------- */
.fi .fi-corps{width:min(100%,var(--mesure));margin-inline:auto;
  font-size:1.115rem;line-height:1.74;counter-reset:fisec}
.fi .fi-corps>section{margin-top:clamp(2.4rem,4.8vw,3.6rem);counter-increment:fisec;
  /* « html{scroll-padding-top:5.5rem} » du socle reserve deja la place de
     l'en-tete collante. 6,5 rem de plus posaient le titre 192 px sous le haut
     de l'ecran, pour une en-tete qui en mesure 51. Mesure au clic reel. */
  scroll-margin-top:.5rem;min-width:0}
.fi .fi-corps>section:first-child{margin-top:0}
.fi .fi-corps>section>*+*{margin-top:1.05rem}
.fi .fi-preambule>*+*{margin-top:1.05rem}

.fi .fi-corps h2{position:relative;margin:0;font-family:var(--fi-titre);
  font-size:clamp(1.38rem,2.4vw,1.82rem);font-weight:400;
  letter-spacing:-.008em;line-height:1.16;color:var(--texte)}
/* LE NUMERO DE SECTION. Numerotation de document, comme sur un plan
   d'atelier : il ne bouge pas, ne s'allume pas, et aucun total n'est affiche
   nulle part. Il rend le plan cliquable utile — « 05 » renvoie a la section
   « 05 ». Au-dessus de 900 px il pend dans la gouttiere de gauche ; en
   dessous il se pose au-dessus du titre. */
.fi--numerote .fi-corps h2::before{content:counter(fisec,decimal-leading-zero);
  display:block;margin-bottom:.65rem;
  font-size:.73rem;font-weight:700;letter-spacing:.22em;color:var(--fi-appui);
  font-variant-numeric:tabular-nums;font-family:var(--fi-sans)}
/* Titres deja numerotes par l'auteur : le repere devient un filet de signal,
   a la meme place. La gouttiere garde son role, la fiche son rythme. */
.fi:not(.fi--numerote) .fi-corps h2::before{content:"";display:block;
  width:3.2rem;height:2px;border-radius:2px;background:var(--signal-clair);
  margin-bottom:.85rem}
@media (min-width:900px){
  .fi--numerote .fi-corps h2::before{position:absolute;left:-4.9rem;top:.45rem;margin:0;
    width:3.5rem;text-align:right;padding-bottom:.4rem;
    border-bottom:2px solid color-mix(in oklab,var(--acc) 38%,transparent)}
  .fi:not(.fi--numerote) .fi-corps h2::before{position:absolute;left:-4.9rem;top:.8rem;
    margin:0;width:3.5rem}
}
/* LE SOUS-TITRE REVIENT EN OUTFIT. C'est le changement de FAMILLE qui fait la
   hierarchie, pas une demi-taille de plus : un h3 sans empattements apres un
   h2 a empattements se lit d'un coup d'oeil sans avoir a grossir. */
.fi .fi-corps h3{position:relative;margin-top:2rem;padding-left:1.15rem;
  font-size:1.21rem;font-weight:600;line-height:1.3;letter-spacing:-.014em;
  color:var(--texte)}
/* Le losange du bandeau du site, en petit : le meme signe, moins fort. */
.fi .fi-corps h3::before{content:"";position:absolute;left:0;top:.52em;
  width:.4rem;height:.4rem;border-radius:1px;rotate:45deg;background:var(--sec-fonce)}
.fi .fi-corps h2+*,.fi .fi-corps h3+*{margin-top:.7rem}
.fi .fi-corps p{color:var(--texte-2)}
.fi .fi-corps strong,.fi .fi-corps b{color:var(--texte);font-weight:600}
/* L'AMORCE EN GRAS. Le corpus en est plein : « <strong>Combien de travail
   acceptez-vous de refaire ?</strong> Si la sauvegarde tourne… ». C'etait
   deja une entree en matiere de paragraphe ; elle n'etait pas composee comme
   telle. Deux lignes, et le dispositif le plus present du corpus existe. La
   couleur est l'APPUI et non l'accent : sur --acc PART, mesure sur les pixels
   rendus, l'accent tombe a 4,34 sous une tache de nuee, et l'article
   Particulier porte huit amorces sur la meme page. */
.fi .fi-corps p.fi-amorce>strong:first-child{color:var(--fi-appui);letter-spacing:-.004em}
.fi .fi-corps a{color:var(--acc);text-underline-offset:.18em;text-decoration-thickness:1px}
.fi .fi-corps a:hover{color:var(--sec-fonce)}

/* Les listes deviennent un encart : dans un texte de fond, une liste est un
   decrochage, pas une suite de paragraphes a puces. Les trois listes du
   corpus portent quatre a cinq entrees ouvertes par un gras — elles ponctuent
   la lecture, autant que ca se voie. */
.fi .fi-corps ul{list-style:none;margin-top:1.3rem;
  padding:clamp(.95rem,2vw,1.25rem) clamp(1rem,2.1vw,1.4rem);
  border-radius:var(--r);border:1px solid var(--trait);
  background:color-mix(in oklab,var(--papier) 76%,transparent);
  display:grid;gap:.6rem}
.fi .fi-corps ul>li{position:relative;padding-left:1.5rem;color:var(--texte-2);margin:0}
.fi .fi-corps ul>li::before{content:"";position:absolute;left:.15rem;top:.62em;
  width:.42rem;height:.42rem;rotate:45deg;border-radius:1px;
  border:1.6px solid var(--acc)}
@media (min-width:900px){
  /* L'encart deborde legerement de la mesure : ce decalage donne du relief a
     une colonne unique. Sous 900 px il mordrait sur le bord de la page. */
  .fi .fi-corps>section>ul{width:calc(100% + 2.4rem);margin-inline:-1.2rem}
}
/* Une liste imbriquee reste une liste, pas un second encart. */
.fi .fi-corps li>ul,.fi .fi-corps li>ol{margin-top:.5rem;padding:0;border:0;background:none;
  border-radius:0;width:auto;margin-inline:0}
.fi .fi-corps ol{list-style:none;padding:0;margin-top:1.05rem;
  display:grid;gap:.55rem;counter-reset:fili}
.fi .fi-corps ol>li{position:relative;padding-left:1.9rem;color:var(--texte-2);
  counter-increment:fili;margin:0}
.fi .fi-corps ol>li::before{content:counter(fili,decimal-leading-zero);position:absolute;left:0;top:.1em;
  font-size:.73rem;font-weight:700;letter-spacing:.08em;color:var(--fi-appui);
  font-variant-numeric:tabular-nums}
/* Une citation : le filet reprend le degrade vertical du site, jamais un gris.
   Aucun article n'en porte aujourd'hui ; le style existe pour le premier qui
   en portera, et il a ete regarde sur une page d'epreuve. */
.fi .fi-corps blockquote{position:relative;margin:1.7rem 0 0;padding:.15rem 0 .15rem 1.35rem;
  border:0;font-size:1.1rem;line-height:1.52;font-weight:400;color:var(--texte);max-width:52ch}
.fi .fi-corps blockquote::before{content:"";position:absolute;left:0;top:.25em;bottom:.25em;
  width:3px;border-radius:2px;background:var(--signal-180)}
.fi .fi-corps blockquote p{color:var(--texte)}
.fi .fi-corps blockquote cite{display:block;margin-top:.7rem;font-size:.82rem;
  font-style:normal;letter-spacing:.06em;color:var(--texte-2)}
/* Un tableau ne fait JAMAIS deborder la page : construire.mjs l'enferme dans
   .tableau-cadre, qui defile dans son propre cadre. « minmax(0,…) » sur la
   colonne de grille est l'autre moitie de la garantie — une piste implicite
   se dimensionne sur son contenu le plus large, et un cadre de 30 rem
   poussait la colonne a 558 px dans un telephone de 390. */
.fi .fi-corps .tableau-cadre{max-width:none;overflow-x:auto;margin-top:1.6rem;
  border:1px solid var(--trait);border-radius:var(--r);background:var(--papier)}
/* LE CADRE DOIT DIRE QU'IL DEFILE. Un bord qui s'efface se lit comme « ca
   continue » ; un bord net se lit comme « c'est coupe ». Meme masque que les
   coutures en peigne du socle. */
@media (max-width:820px){
  .fi .fi-corps .tableau-cadre{
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 2.6rem),transparent);
            mask-image:linear-gradient(90deg,#000 calc(100% - 2.6rem),transparent)}
}
.fi .fi-corps table{width:100%;min-width:28rem;margin:0;border-collapse:collapse;font-size:.94rem}
.fi .fi-corps thead th{text-align:left;padding:.72rem .95rem;
  font-size:.71rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;
  color:var(--fi-appui);white-space:nowrap;
  border-bottom:2px solid color-mix(in oklab,var(--acc) 30%,var(--papier))}
.fi .fi-corps tbody th{text-align:left;font-weight:600;color:var(--texte)}
.fi .fi-corps td,.fi .fi-corps tbody th{padding:.68rem .95rem;
  border-top:1px solid var(--trait);color:var(--texte-2);vertical-align:top}
.fi .fi-corps tbody tr:nth-child(even){background:color-mix(in oklab,var(--papier-2) 60%,transparent)}
.fi .fi-corps figure{margin:1.6rem 0 0}
.fi .fi-corps hr{border:0;height:1px;background:var(--trait);margin-block:2.2rem}

/* -------------------------------------------------------------------------
   6. LA PORTE — l'atelier repond au cas du lecteur
   ---------------------------------------------------------------------- */
.fi .fi-fin{position:relative;overflow:hidden;isolation:isolate;
  margin-top:clamp(2.6rem,5.4vw,4.2rem);
  padding:clamp(1.8rem,3.6vw,2.8rem) clamp(1.3rem,3.4vw,2.8rem);
  border-radius:calc(var(--r) + 6px);background:var(--encre);color:#fff}
/* Le halo de la tete du site, transpose. */
.fi .fi-fin::before{content:"";position:absolute;inset:0;z-index:-1;
  background:
    radial-gradient(46% 62% at 88% 12%,color-mix(in oklab,var(--sec) 32%,transparent),transparent 68%),
    radial-gradient(54% 66% at 4% 98%,color-mix(in oklab,var(--acc-vif) 30%,transparent),transparent 70%)}
/* Le peigne du site — les tiges du portail — en couture haute du bloc. */
.fi .fi-fin::after{content:"";position:absolute;left:0;right:0;top:0;z-index:-1;
  height:clamp(54px,7vw,96px);pointer-events:none;
  color:color-mix(in oklab,var(--acc-clair) 26%,transparent);
  background:repeating-linear-gradient(90deg,transparent 0 8px,currentColor 8px 10px,transparent 10px 19px);
  -webkit-mask-image:linear-gradient(180deg,#000,transparent);
          mask-image:linear-gradient(180deg,#000,transparent)}
.fi .fi-fin .fi-titret{color:var(--acc-clair)}
.fi .fi-fin .fi-titret::before{background:var(--signal-nuit)}
.fi .fi-fin-rang{display:grid;gap:1.2rem;align-items:start}
@media (min-width:820px){.fi .fi-fin-rang{grid-template-columns:auto 1fr;gap:2rem}}
.fi .fi-fin-glyphe{width:clamp(3.2rem,6.5vw,4.8rem);height:auto;aspect-ratio:1;
  color:var(--acc-clair);opacity:.9;
  fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.fi .fi-fin h2{font-family:var(--fi-titre);margin:.7rem 0 0;max-width:22ch;
  font-size:clamp(1.45rem,2.7vw,2.05rem);font-weight:400;letter-spacing:-.01em;
  line-height:1.12;color:#fff}
/* Le degrade « nuit » du site : #8FB4FF, #C9B8FF, #FFC489 sur l'encre — les
   trois arrets sont tres au-dessus de 4,5. Sous @supports, pour qu'un
   navigateur sans background-clip:text garde du blanc plutot que du vide. */
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  .fi .fi-fin h2{background:var(--signal-nuit);
    -webkit-background-clip:text;background-clip:text;color:transparent}
}
.fi .fi-fin p{color:rgba(255,255,255,.78);max-width:56ch;font-size:.98rem}
.fi .fi-fin-actions{display:flex;flex-wrap:wrap;gap:.65rem;margin-top:1.4rem}
/* DEUX EXCEPTIONS DE CONTRASTE, constatees a la capture sur le bloc sombre.
   « .contenu a » (0-1-1) l'emporte sur « .bouton--plein » et « .bouton--fil »
   (0-1-0) : le libelle du bouton plein revenait en bleu sur son propre
   degrade, et celui du bouton contour sortait a 3,31 sur l'encre. Le blanc
   sur l'encre et sur var(--signal) est l'idiome deja employe par le socle,
   qui en compte une quarantaine. */
.fi a.bouton--plein{color:#fff}
.fi .fi-fin .bouton--fil{border-color:rgba(255,255,255,.32);color:#fff;background:transparent}
.fi .fi-fin .bouton--fil:hover{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.58)}
.fi .fi-fin-adresse{margin-top:1.05rem;font-size:.91rem;color:rgba(255,255,255,.7)}
.fi .fi-fin-adresse b{color:#fff;font-weight:600}
.fi .fi-fin a:not(.bouton){color:var(--acc-clair)}
.fi .fi-fin a:not(.bouton):hover{color:#fff}

/* -------------------------------------------------------------------------
   7. LA SUITE — un enchainement, pas une grille
   ---------------------------------------------------------------------- */
.fi .fi-suite{margin-top:clamp(2.4rem,4.8vw,3.6rem)}
.fi .fi-suite-note{margin:.8rem 0 0;font-size:.93rem;color:var(--texte-2);max-width:62ch}
.fi .fi-suite-liste{list-style:none;margin:1.2rem 0 0;padding:0;display:grid;gap:.7rem}
.fi .fi-suite-liste li{margin:0}
.fi .fi-suite-lien{--mx:50%;--my:0%;position:relative;isolation:isolate;
  display:grid;grid-template-columns:auto 1fr;gap:.35rem 1rem;align-items:center;
  padding:.9rem 1.1rem;text-decoration:none;color:inherit;
  border:1px solid transparent;border-radius:var(--r);
  background:
    linear-gradient(var(--papier),var(--papier)) padding-box,
    linear-gradient(120deg,color-mix(in oklab,var(--acc) 14%,#fff),
      color-mix(in oklab,var(--acc-clair) 24%,#fff) 50%,
      color-mix(in oklab,var(--sec) 20%,#fff)) border-box;
  box-shadow:var(--ombre-1);
  transition:transform .32s var(--ressort),box-shadow .32s var(--t),background .32s var(--t)}
.fi .fi-suite-lien::before{content:"";position:absolute;inset:0;z-index:-1;opacity:0;
  border-radius:var(--r);
  background:radial-gradient(280px 240px at var(--mx) var(--my),
    color-mix(in oklab,var(--sec) 18%,transparent),transparent 70%);
  transition:opacity .4s var(--t)}
.fi .fi-suite-lien:hover,.fi .fi-suite-lien:focus-visible{transform:translateY(-4px);
  background:
    linear-gradient(var(--papier),var(--papier)) padding-box,
    var(--signal-clair) border-box;
  box-shadow:var(--ombre-2)}
.fi .fi-suite-lien:hover::before{opacity:1}
.fi .fi-suite-lien:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
/* La vignette : le meme objet du metier, sur les memes hachures que la carte
   d'actualite. C'est la seule image dont le site dispose, et elle suffit. */
.fi .fi-vignette{grid-row:span 2;display:grid;place-items:center;position:relative;
  width:clamp(3rem,8vw,3.5rem);aspect-ratio:1;border-radius:12px;overflow:hidden;
  background:linear-gradient(135deg,var(--nuee-1) 0%,var(--nuee-3) 52%,var(--nuee-2) 100%)}
.fi .fi-vignette::before{content:"";position:absolute;inset:0;
  background:repeating-linear-gradient(115deg,rgba(255,255,255,.45) 0 2px,transparent 2px 22px)}
.fi .fi-vignette svg{position:relative;width:62%;height:auto;
  color:var(--acc);fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;transition:color .3s var(--t)}
.fi .fi-suite-lien:hover .fi-vignette svg{color:var(--sec-fonce)}
.fi .fi-suite-rub{font-size:.69rem;letter-spacing:.13em;text-transform:uppercase;font-weight:700;
  color:var(--fi-appui);align-self:end;line-height:1.2}
.fi .fi-suite-titre{font-size:1.01rem;font-weight:500;line-height:1.32;color:var(--texte);
  letter-spacing:-.015em;align-self:start;transition:color .2s var(--t)}
.fi .fi-suite-lien:hover .fi-suite-titre{color:var(--acc)}
.fi .fi-suite-duree{font-size:.78rem;color:var(--texte-2);font-variant-numeric:tabular-nums;
  white-space:nowrap}
/* Deux mises en page, une seule liste. Au large, la duree tient sa propre
   colonne, separee par un filet. Au telephone elle remonte a cote de la
   rubrique et le titre passe sous les deux : posee en bas a gauche, sous la
   vignette, elle avait l'air d'une legende de l'image. Constate a 390 px. */
@media (min-width:560px){
  .fi .fi-suite-lien{grid-template-columns:auto 1fr auto}
  .fi .fi-suite-rub,.fi .fi-suite-titre{grid-column:2}
  .fi .fi-suite-duree{grid-column:3;grid-row:span 2;align-self:center;
    padding-left:1rem;border-left:1px solid var(--trait)}
}
@media (max-width:559px){
  .fi .fi-suite-lien{grid-template-columns:auto 1fr auto;align-items:start}
  .fi .fi-suite-rub{grid-column:2;grid-row:1;align-self:center}
  .fi .fi-suite-duree{grid-column:3;grid-row:1;align-self:center}
  .fi .fi-suite-titre{grid-column:2 / 4;grid-row:2}
}
.fi .fi-suite-tout{display:inline-flex;align-items:center;gap:.45rem;margin-top:1.1rem;
  font-size:.93rem;font-weight:500;color:var(--fi-appui);text-decoration:none}
.fi .fi-suite-tout:hover{color:var(--sec-fonce);text-decoration:underline;text-underline-offset:.18em}
.fi .fi-suite-tout:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:6px}

/* -------------------------------------------------------------------------
   8. MOUVEMENT REDUIT
   Le socle coupe deja toutes les transitions par un « * ». La regle est
   ecrite quand meme : ce qui est explicite ne depend pas d'une autre regle.
   ---------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .fi .fi-suite-lien:hover,.fi .fi-suite-lien:focus-visible{transform:none}
  .fi .fi-plan::before,.fi .fi-suite-lien::before{transition:none}
}

/* -------------------------------------------------------------------------
   9. LA MARGE HABITEE — au-dessus de 1080 px
   -------------------------------------------------------------------------
   Le vrai defaut mesure du gabarit de depart : « grid-template-columns:1fr »
   laissait 500 px de vide a droite sur toute la hauteur de la page. La marge
   de droite recoit donc le plan puis les points de controle, et la gouttiere
   de gauche les numeros de section. Deux restes deviennent deux colonnes.

   CE BLOC VIENT EN DERNIER, ET IL DOIT Y RESTER. A specificite egale, c'est
   l'ordre de declaration qui tranche : place plus haut, son « width:auto » se
   faisait ecraser par le « width:min(100%,var(--mesure)) » du corps, et la
   colonne de lecture tombait a 537 px au-dessus de 1080 px contre 612 en
   dessous — deux mesures de lecture differentes sur la meme page selon la
   fenetre, sans que rien ne le signale.
   ---------------------------------------------------------------------- */
@media (min-width:1080px){
  .fi .fi-colonnes{display:grid;align-items:start;
    grid-template-columns:minmax(0,calc(4.9rem + var(--mesure))) minmax(12rem,18rem);
    justify-content:space-between;column-gap:clamp(1.6rem,3vw,2.6rem)}
  /* Le texte rentre de 4,9 rem ; les numeros de section, eux, gardent le bord
     gauche — celui du cartouche et du titre. C'est le geste de marge d'un
     document technique, et c'est ce qui donne au h2 son assise. */
  .fi .fi-corps{grid-column:1;grid-row:1;
    padding-left:4.9rem;width:calc(4.9rem + var(--mesure));max-width:100%;margin-inline:0}
  /* La marge est UN objet : le plan, puis les points de controle. Une
     premiere version les posait en deux rangees de grille, le corps couvrant
     les deux ; la grille repartissait alors les 5 000 px du corps sur les
     rangees, et les points de controle tombaient au milieu de l'article. Vu
     a la capture, jamais signale autrement. */
  .fi .fi-marge{grid-column:2;grid-row:1}
  /* LE PLAN N'EST PAS COLLANT. Il ne suit pas le lecteur, ne s'allume pas, ne
     se remplit pas : il est POSE en haut de la marge, en flux. Un sommaire
     qui accompagne le defilement est la forme refusee deux fois sur ce
     projet ; une note de marge n'en est pas une. Et dans la marge le cadre
     disparait : deux plaques a bordure en degrade pour une page de texte,
     c'etait une de trop. */
  .fi .fi-plan{border:0;border-radius:0;box-shadow:none;background:none;
    padding:.2rem 0 0 1.1rem;margin-bottom:0;
    border-left:1px solid var(--trait)}
  .fi .fi-plan::before{display:none}
  .fi .fi-plan a{font-size:.875rem;padding:.45rem 0;grid-template-columns:1.9rem 1fr}
  /* Les points de controle passent SOUS le plan, dans la marge. Ils ne
     coutent alors plus un pixel avant la premiere phrase de l'article — le
     prix d'entree reste a ~880 px au lieu de passer a ~1150 — et la marge est
     habitee sur ses mille premiers pixels au lieu de trois cents. */
  .fi .fi-retenir{margin:1.7rem 0 0;
    padding:1rem 1.05rem 1rem 1.3rem;font-size:.95rem}
  .fi .fi-retenir li{font-size:.88rem;line-height:1.42;
    grid-template-columns:.95rem 1fr;gap:.55rem}
  .fi .fi-retenir li::before{width:.95rem;height:.95rem}
}

/* =========================================================================
   LA MODALE DE DEMANDE — le formulaire revient DANS la section.

   POURQUOI ELLE EXISTE. Le site d'origine ouvrait ses formulaires en pop-up
   depuis la section qui les concerne (le corpus de production porte encore
   les declencheurs : `data-modal-target="#modalDevisFibre"`, avec les memes
   libelles de bouton que ceux d'ici — « Demander un devis Dediee », « Etre
   rappele par un expert »). La refonte avait aplati ces pop-up en pages
   `paccueil-*` : le visiteur quittait la page pour remplir quatre champs.

   COMMENT ELLE TIENT SANS JAVASCRIPT. Le declencheur n'est pas un bouton :
   c'est un VRAI LIEN vers la page `paccueil-*`, qui existe toujours et reste
   servie. Script coupe, le lien ouvre la page — le comportement d'aujourd'hui,
   inchange. Script present, il est intercepte et la page est chargee dans le
   <dialog> ci-dessous. Rien ici ne masque quoi que ce soit : ce fichier ne
   decrit qu'une fenetre que seul `showModal()` peut afficher.

   L'IDIOME EST CELUI DE LA MAISON. `#vue` dans pilier-agence-web.html ouvre
   deja la vue rapide du portfolio avec un <dialog> natif : meme fermeture a
   Echap, meme clic dehors, meme piege de focus offert par le navigateur.
   ========================================================================= */

#if2m-modale{border:0;padding:0;width:min(760px,94vw);max-height:92vh;overscroll-behavior:contain;
  border-radius:var(--r);overflow:hidden;background:var(--papier);
  color:var(--texte);box-shadow:var(--ombre-2)}
#if2m-modale::backdrop{background:color-mix(in srgb, var(--encre) 72%, transparent);backdrop-filter:blur(4px)}

/* LA FENETRE REPARTIT SA HAUTEUR, elle ne la devine plus. La tete prend ce
   qu'il lui faut, le corps prend le reste. L'ancien `calc(92vh - 3.6rem)`
   supposait une tete d'une seule ligne : des que le titre passait a deux
   lignes — ce que font la plupart de ces titres a 390 px — le corps
   depassait de 10 px sous le bord et se faisait couper par l'`overflow:hidden`
   du <dialog>. Le padding bas l'absorbait ; un titre sur trois lignes ou une
   police plus grosse chez le visiteur, et c'etait le bouton d'envoi.
   Le selecteur porte [open], et ce n'est pas un detail : une regle `display:`
   sur `#if2m-modale` nu l'emporterait sur le `dialog:not([open]){display:none}`
   de la feuille du navigateur, et la fenetre s'afficherait fermee. */
#if2m-modale[open]{display:flex;flex-direction:column}

/* La tete reste visible pendant que le formulaire defile : c'est elle qui
   porte le bouton de fermeture, et un formulaire de trois etapes est long. */
#if2m-modale .modale-tete{flex:0 0 auto;display:flex;align-items:flex-start;gap:.9rem;
  padding:.85rem 1rem;border-bottom:1px solid var(--trait);
  background:var(--papier-2);position:sticky;top:0;z-index:2}
#if2m-modale .modale-titre{flex:1;min-width:0;margin:0;
  font-size:1.02rem;line-height:1.25;font-weight:650;color:var(--texte)}
/* Le titre recoit le focus a l ouverture (voir socle.js) : il est la cible
   programmee, jamais un arret de tabulation. Pas d anneau, donc — il n y a
   aucune action a y faire — mais le lecteur d ecran, lui, annonce le titre. */
#if2m-modale .modale-titre:focus{outline:none}
#if2m-modale .modale-fermer{flex:0 0 auto;font:inherit;font-size:.85rem;font-weight:600;
  cursor:pointer;border:1px solid var(--trait);background:var(--papier);color:var(--texte);
  border-radius:99px;padding:.34rem .85rem;transition:.2s var(--t)}
#if2m-modale .modale-fermer:hover{border-color:var(--acc);color:var(--acc)}
#if2m-modale .modale-fermer:focus-visible{outline:2px solid var(--acc);outline-offset:2px}

/* `overscroll-behavior:contain` retient le defilement DANS la fenetre. Sans
   lui, la molette (ou le doigt) poussait le corps jusqu'a sa butee puis
   emportait la page derriere : mesure a 390 px, le corps bougeait de 182 px
   et le site de 3300 px, et a la fermeture le visiteur se retrouvait 384 px
   plus bas, le bouton qu'il avait clique hors de l'ecran. */
#if2m-modale .modale-corps{overflow-y:auto;overscroll-behavior:contain;flex:1 1 auto;min-height:0;
  padding:1.1rem 1.15rem 1.35rem;-webkit-overflow-scrolling:touch}
#if2m-modale .modale-corps > :first-child{margin-top:0}
/* Le chapo de la page `paccueil-*` : il dit a quoi sert la demande. */
#if2m-modale .modale-chapo{margin:0 0 1rem;color:var(--texte-2);font-size:.95rem;line-height:1.55}
#if2m-modale .modale-chapo strong{color:var(--texte)}

/* L'AIGUILLAGE — « Etes-vous au bon endroit ? », repris de la page de demande
   quand elle en porte un. Il arrive avec un <h2> dimensionne pour une page
   entiere : on le ramene a l'echelle de la fenetre. Encadre, pour qu'il se
   lise comme un avertissement et non comme le debut du formulaire. */
#if2m-modale .modale-aiguillage{margin:0 0 1.15rem;padding:.9rem 1rem .15rem;
  border:1px solid var(--trait);border-left:3px solid var(--acc);
  border-radius:var(--r);background:var(--papier-2)}
#if2m-modale .modale-aiguillage h2{margin:0 0 .55rem;font-size:1rem;line-height:1.3;
  font-weight:650;color:var(--texte)}
#if2m-modale .modale-aiguillage p{margin:0 0 .8rem;color:var(--texte-2);
  font-size:.92rem;line-height:1.55}
#if2m-modale .modale-aiguillage strong{color:var(--texte)}
#if2m-modale .modale-aiguillage a{color:var(--acc);font-weight:600}

/* L'attente et la panne. Le message d'echec n'est pas un cul-de-sac : il
   porte le lien vers la page, qui elle marche toujours. */
#if2m-modale .modale-attente,
#if2m-modale .modale-echec{margin:0;padding:1.4rem .2rem;color:var(--texte-2);font-size:.95rem}
#if2m-modale .modale-echec a{color:var(--acc);font-weight:600}

@media (max-width:560px){
  /* Au telephone la fenetre prend la largeur et se cale en bas : le pouce
     atteint le bouton de fermeture, et le clavier virtuel ne pousse plus la
     tete hors de l'ecran. */
  #if2m-modale{width:100vw;max-width:100vw;max-height:94vh;
    margin:auto auto 0;border-radius:var(--r) var(--r) 0 0}
  #if2m-modale .modale-corps{padding:1rem .9rem 1.6rem}
  #if2m-modale .modale-titre{font-size:.98rem}
}

/* =========================================================================
   LA FICHE DE SERVICE — la variante « fi--service »
   -------------------------------------------------------------------------
   Les 37 pages « paccueil-* » reprennent le gabarit « .fi » de la fiche
   d'article sans y toucher : meme tete, meme plan, meme corps, meme suite.
   Ce bloc ne decrit QUE les trois endroits ou une prestation n'est pas un
   article. Rien ici ne redefinit une regle de « .fi » : les selecteurs sont
   soit nouveaux (.fi-demande, .fi-lieu), soit portes par « .fi.fi--service »
   (0-3-0), au-dessus des « .fi .fi-suite-lien » (0-2-0) qu'ils corrigent —
   y compris dans les deux media queries de la suite, ou l'ordre de
   declaration ne peut donc pas les departager.
   ========================================================================= */

/* 1. LA VIGNETTE DE SUITE N'A PAS DE TROISIEME COLONNE. Celle d'un article
      porte sa duree de lecture (« 6 min ») ; une prestation n'en a pas, et
      n'en aura pas — inventer « 15 min d'intervention » serait annoncer un
      delai que personne n'a promis. Sans cette correction la grille garde sa
      piste « auto » vide : 1 rem de gouttiere pendue a droite de chaque
      vignette, et le filet separateur du grand format trace sur du vide. */
.fi.fi--service .fi-suite-lien{grid-template-columns:auto 1fr}
@media (min-width:560px){
  .fi.fi--service .fi-suite-lien{grid-template-columns:auto 1fr}
}
@media (max-width:559px){
  .fi.fi--service .fi-suite-lien{grid-template-columns:auto 1fr}
  /* Le titre s'etendait « 2 / 4 » pour passer sous la duree ; a deux colonnes
     cette borne ouvrirait une troisieme piste implicite. */
  .fi.fi--service .fi-suite-titre{grid-column:2;grid-row:2}
}

/* 2. LE LIEU. Sept pages finissent sur « Intervention a domicile a Montauban
      et dans les environs. », precede d'une epingle d'editeur WordPress. La
      phrase est vraie et utile : elle reste. L'emoji part, et la ligne recoit
      l'epingle dessinee du site — meme procede de masque que les coches et
      les croix du socle, aucun appel, aucun tiers. */
.fi .fi-lieu{display:flex;gap:.55rem;align-items:flex-start;
  margin-top:1.5rem;padding-top:1.1rem;border-top:1px solid var(--trait);
  font-size:.95rem;color:var(--texte-2)}
.fi .fi-lieu::before{content:"";flex:0 0 auto;width:1.05rem;height:1.05rem;
  margin-top:.28rem;background:var(--fi-appui);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21s7-6.3 7-11a7 7 0 1 0-14 0c0 4.7 7 11 7 11z' fill='none' stroke='%23000' stroke-width='1.7' stroke-linejoin='round'/%3E%3Ccircle cx='12' cy='10' r='2.6' fill='none' stroke='%23000' stroke-width='1.7'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21s7-6.3 7-11a7 7 0 1 0-14 0c0 4.7 7 11 7 11z' fill='none' stroke='%23000' stroke-width='1.7' stroke-linejoin='round'/%3E%3Ccircle cx='12' cy='10' r='2.6' fill='none' stroke='%23000' stroke-width='1.7'/%3E%3C/svg%3E") center/contain no-repeat}

/* 3. LA SECTION DE DEMANDE. Vingt des trente-sept pages portent un formulaire
      a trois etapes. Il etait pose DANS la colonne de lecture, que « .fi »
      borne a 35 rem : deux champs cote a cote (« Code postal » / « Ville »)
      y tombent a 12 rem chacun. La section sort donc de la colonne et prend
      la largeur de la fiche.

      ELLE PORTE AUSSI LE POIDS DE LA FIN DE PAGE. Sur ces vingt pages le
      generateur n'ecrit pas le bloc sombre « L'atelier » : le formulaire EST
      la porte, et un second appel a l'action trois lignes sous « Envoyer ma
      demande » ne ferait que disperser. D'ou le cadre : sans lui, la page
      s'arreterait sur un champ de saisie pose a meme le papier. */
.fi .fi-demande{margin-top:clamp(2.6rem,5vw,4rem);
  padding:clamp(1.4rem,3.2vw,2.4rem);
  border:1px solid transparent;border-radius:var(--r);
  background:
    linear-gradient(var(--papier),var(--papier)) padding-box,
    linear-gradient(120deg,color-mix(in oklab,var(--acc) 16%,#fff),
      color-mix(in oklab,var(--acc-clair) 26%,#fff) 52%,
      color-mix(in oklab,var(--sec) 22%,#fff)) border-box;
  box-shadow:var(--ombre-1)}
/* Le titre de la section reprend la famille a empattements des titres de
   section du corps : la demande est une section de la fiche, pas un encart
   rapporte. « .fi .fi-corps h2 » ne la couvre pas, elle est hors du corps. */
.fi .fi-demande>h2{position:relative;margin:0;font-family:var(--fi-titre);
  font-size:clamp(1.38rem,2.4vw,1.82rem);font-weight:400;
  letter-spacing:-.008em;line-height:1.16;color:var(--texte)}
.fi .fi-demande>h2+p{margin-top:.7rem;max-width:62ch;
  font-size:1.02rem;line-height:1.6;color:var(--texte-2)}
.fi .fi-demande .if2m-form-bloc{margin-top:1.5rem}


/* ==========================================================================
   L ETABLI — les pages secondaires cessent d etre une colonne de texte.

   POURQUOI. Mesure sur le site : une page pilier passe 68 a 79 % de sa
   hauteur en fonds pleine largeur et pose 28 a 39 blocs reveles au
   defilement. Une page « paccueil » : 0 % de fond pleine largeur, UN bloc
   revele, aucune image, et 1,1 a 5,4 ancres visuelles pour 1 000 px contre
   8,5 a 16,1 sur les pages riches. A 1280 px, la moitie de l ecran est vide
   sur toute la hauteur — la colonne .fi-marge existe, est reservee, et n est
   remplie qu a 16 %.

   TROIS PARTIS ONT CONCOURU, deux juges les ont notes, trois sceptiques ont
   cherche a casser le gagnant. « L Etabli » l emporte 47/60 et coutait deja
   le moins cher des trois.

   CE QUE CE CSS NE FERA PAS, et il faut le savoir avant de le lire : il ne
   sauve pas une page qui n a rien a dire. Le corps d une « paccueil » fait
   543 signes en mediane, et 20 pages sur 37 consacrent leur seule section a
   reciter les noms des champs du formulaire. Aucun octet de style ne corrige
   ca — la reprise editoriale de ces 20 pages reste devant.
   ========================================================================== */
/* =========================================================================
   L'ETABLI — la variante « fi--etabli » du gabarit de fiche.
   -------------------------------------------------------------------------
   POURQUOI. Mesure faite sur les 55 pages en gabarit « .fi » : aucune rupture
   pleine largeur (0 %), une ancre visuelle tous les 200 a 900 px, zero image,
   un objet le plus large a 992 px pour une grille qui en offre 1240, et une
   colonne de marge de 288 px vide sur 86 436 px cumules. La page se lit ; elle
   ne se REGARDE pas.

   LE PARTI. Une page secondaire est un ETABLI vu de dessus : une plaque de
   fonte gravee en tete, un plan de travail clair ou les numeros de section
   sont frappes en grand, une etiquette de comptoir accrochee dans la marge,
   une planche de matiere (le cliche d'atelier, ou le poincon du metier quand
   il n'y a pas de cliche), et le comptoir lui-meme en bas de page. La presence
   vient de la MATIERE, de l'ECHELLE et du RYTHME — pas du mouvement : ce bloc
   n'ajoute AUCUNE animation, AUCUN @keyframes, AUCUNE transformation.

   CE QU'IL NE REDEFINIT PAS. Aucune regle de « .fi » n'est dupliquee : les
   selecteurs sont soit nouveaux (.fi-planche, .fi-poincon, .fi-etiquette,
   .fi-fin-tel), soit portes par « .fi.fi--etabli » (0-3-0), au-dessus des
   « .fi .fi-xxx » (0-2-0) qu'ils habillent. Aucune couleur en dur : tout
   descend des jetons d'univers, donc PRO et PART changent de peau sans qu'une
   seule regle soit ecrite deux fois.

   TROIS CONSTANTES SONT REPRISES D'AILLEURS, et doivent le rester :
   62rem = « .fi{max-width} », 1240px et 2.5rem = « .large ». Elles ne servent
   qu'a calculer le debord (voir --at-debord).
   ========================================================================= */

/* -------------------------------------------------------------------------
   0. LA PALETTE D'ATELIER — quatre teintes derivees, zero teinte nouvelle
   -------------------------------------------------------------------------
   La fonte est l'encre du site legerement teintee de la couleur DOMINANTE de
   l'univers ; l'etabli est le papier teinte de la couleur SECONDAIRE. Comme
   --acc et --sec s'echangent d'un univers a l'autre, l'atelier vire tout seul
   de l'acier bleute (PRO) a la fonte chaude (PART) sans une regle de plus. Le
   burin est le filet grave, toujours le meme objet.
   ---------------------------------------------------------------------- */
.fi{
--at-fonte:color-mix(in oklab,var(--encre) 90%,var(--acc));
  --at-fonte-2:color-mix(in oklab,var(--encre) 76%,var(--sec-fonce));
  --at-etabli:color-mix(in oklab,var(--papier-2) 78%,var(--sec-voile));
  /* La craie : le trait clair pose sur la fonte. Blanc casse de la couleur
     claire de l'univers — sur l'encre, tres au-dessus de 4,5. */
  --at-craie:color-mix(in oklab,var(--papier) 88%,var(--acc-clair));
  --at-craie-2:color-mix(in oklab,var(--papier) 68%,var(--acc-clair));
  --at-burin:color-mix(in oklab,var(--acc) 24%,var(--trait));
  /* LE DEBORD. De combien un objet de la fiche peut sortir des 62rem pour
     atteindre la largeur de la grille du site. Sous 1032 px de fenetre il
     tombe a 0 et l objet reste dans la colonne : rien a annuler en media query.
     (Le commentaire d origine affirmait ici que la gouttiere de .large
     absorbait la barre de defilement. C etait FAUX : elle est retranchee des
     deux cotes et n annule rien. Voir juste en dessous.) */

  /* LE DEBORD MESURE LE CONTENEUR, PAS LA FENETRE. 100vw compte la barre de
     defilement, .large vaut 100% et ne la compte pas : les comparer faisait
     deborder la planche de la largeur de la barre, des deux cotes, sur toute
     fenetre de bureau entre 1032 et 1294 px. body{overflow-x:hidden} rognait
     le filet en silence et scrollWidth === clientWidth restait vrai.
     100cqi vaut la largeur reelle du conteneur, barre deja deduite.
     La premiere declaration est le repli : si les requetes de conteneur
     manquent, le debord vaut zero et la planche reste dans la grille. */
  --at-debord:0px;
}
@supports (container-type:inline-size){
  .contenu.contenu--fiche{container-type:inline-size}
  .fi{--at-debord:max(0px,calc((min(1240px,100cqi) - 62rem) / 2))}
}

/* -------------------------------------------------------------------------
   1. LA PLAQUE DE FONTE — la tete de fiche
   -------------------------------------------------------------------------
   La premiere vue decide de l'impression. Celle d'une fiche etait un cartouche
   pale de 435 px de haut portant un h1 de 46 px ; celle d'un pilier est une
   affiche sombre de 784 px portant un h1 de 84. On ne copie pas l'affiche —
   elle a une scene WebGL et une descente. On coule la meme surface en fonte :
   sombre, gravee, avec le titre a l'echelle et le poincon du metier frappe
   dans l'angle.
   ---------------------------------------------------------------------- */
.fi.fi--etabli .fi-plaque{
  padding-block:clamp(1.9rem,5.2vw,3.4rem);
  background:
    linear-gradient(166deg,var(--at-fonte-2) 0%,var(--at-fonte) 58%,var(--encre) 100%)
      padding-box,
    var(--signal) border-box;
  box-shadow:var(--ombre-2)}
/* LES STRIES. Le motif de hachures de la plaque claire, retourne : un trait
   clair tous les 9 px, tres faible, qui donne a l'aplat la texture d'une piece
   usinee. Sans lui, un aplat sombre de 1000 px de large « bande » sur un grand
   ecran, exactement comme le blanc plat que le grain du socle corrige. */
.fi.fi--etabli .fi-plaque::before{
  background:repeating-linear-gradient(90deg,
    color-mix(in oklab,var(--at-craie) 8%,transparent) 0 1px,transparent 1px 9px);
  -webkit-mask-image:linear-gradient(200deg,var(--encre),transparent 78%);
          mask-image:linear-gradient(200deg,var(--encre),transparent 78%)}
/* LE POINCON. Le glyphe de rubrique cesse d'etre un filigrane a 13 % : il
   devient la marque frappee dans la piece. Plus grand, plus clair, toujours
   coupe par l'overflow de la plaque — la page ne deborde pas d'un pixel. */
.fi.fi--etabli .fi-filigrane{
  width:clamp(11rem,30vw,21rem);color:var(--at-craie);opacity:.11;stroke-width:.9}
.fi.fi--etabli .fi-oeil{color:var(--at-craie-2)}
.fi.fi--etabli .fi-oeil svg{color:var(--acc-clair)}
.fi.fi--etabli .fi-oeil .fi-genre{color:color-mix(in oklab,var(--at-craie-2) 72%,var(--encre))}
.fi.fi--etabli .fi-oeil .fi-sep{color:color-mix(in oklab,var(--at-craie-2) 45%,transparent)}
/* L'ECHELLE. 2,15rem au telephone (contre 1,85), 3,7rem au large (contre 2,9).
   Le rapport au h1 d'un pilier passe de 1,82 a 1,43. Le titre est borne a 16
   signes de large : a 3,7rem, au-dela, il couvrirait le poincon. */
.fi.fi--etabli .fi-plaque h1{
  font-size:clamp(2.15rem,5.4vw,3.7rem);max-width:16ch;
  letter-spacing:-.022em;color:var(--papier)}
/* LE CHAPO PORTE UN <strong>. Ce n'est pas cosmetique : la modale de demande
   ne reprend le chapo que « si le premier <p> apres le <h1> contient un
   <strong> » (socle.js, extraire()). Sans lui, les 20 formulaires ouverts en
   fenetre s'affichent sans une ligne d'explication. */
.fi.fi--etabli .fi-chapo{color:var(--at-craie);max-width:46ch}
.fi.fi--etabli .fi-chapo strong{color:var(--papier);font-weight:500}
/* Les reperes restent lisibles sur la fonte pour les 13 articles et les 4
   pages legales, qui gardent le cartouche a trois couples. Sur les 37 pages de
   prestation ils descendent dans l'etiquette (dispositif 5). */
.fi.fi--etabli .fi-reperes{border-top-color:color-mix(in oklab,var(--at-craie) 26%,transparent)}
.fi.fi--etabli .fi-reperes>div+div{border-left-color:color-mix(in oklab,var(--at-craie) 20%,transparent)}
.fi.fi--etabli .fi-reperes dt{color:var(--at-craie-2)}
.fi.fi--etabli .fi-reperes dd{color:var(--papier)}

/* -------------------------------------------------------------------------
   2. LES NUMEROS FRAPPES — le rythme du plan d'atelier
   -------------------------------------------------------------------------
   Le gabarit sait deja numeroter ses sections (« fi--numerote », compteur
   « fisec ») : les 13 articles s'en servent, les 42 pages de service jamais.
   On ne reecrit pas le compteur, on lui donne l'echelle d'un numero de piece :
   chiffre pale, ajoure d'un trait plus soutenu, sans fond. C'est le seul objet
   « geant » de la page — il tient lieu d'image la ou il n'y en a pas.
   ---------------------------------------------------------------------- */
.fi.fi--etabli.fi--numerote .fi-corps h2::before{
  font-size:clamp(2.4rem,9vw,3.2rem);line-height:.86;letter-spacing:-.045em;
  font-weight:700;margin-bottom:.35rem;
  color:color-mix(in oklab,var(--acc) 15%,var(--papier));
  -webkit-text-stroke:1px color-mix(in oklab,var(--acc) 34%,var(--papier))}
@media (min-width:900px){
  /* Il pend dans la gouttiere de gauche, aligne a droite sur le bord du texte,
     cale sur la ligne de base du titre. 6,1 rem de tirage : au point de
     rupture le plus serre (1080 px), il reste 5 px a l'interieur de .large. */
  .fi.fi--etabli.fi--numerote .fi-corps h2::before{
    left:-6.1rem;top:-.5rem;width:4.6rem;
    font-size:clamp(2.9rem,4.4vw,3.9rem);
    border-bottom:0;padding-bottom:0;margin:0}
}

/* -------------------------------------------------------------------------
   3. LES FILETS GRAVES — une section ne commence plus a zero
   -------------------------------------------------------------------------
   Deux sections separees par 3,6 rem de blanc se lisent comme un seul bloc.
   Un filet de 1 px et une amorce de 3 px en couleur de signal suffisent a
   marquer la coupe : une ancre visuelle a chaque section, sur les 55 pages.
   ---------------------------------------------------------------------- */
.fi.fi--etabli .fi-corps>section+section{
  position:relative;padding-top:clamp(1.9rem,3.8vw,2.6rem);
  border-top:1px solid var(--at-burin)}
.fi.fi--etabli .fi-corps>section+section::before{
  content:"";position:absolute;left:0;top:-1px;width:3.4rem;height:3px;
  background:var(--signal)}

/* -------------------------------------------------------------------------
   4. LA PLANCHE — la matiere, a la largeur de la grille
   -------------------------------------------------------------------------
   L'objet le plus large d'une page secondaire mesure aujourd'hui 992 px dans
   une grille qui en offre 1240, et aucune des 55 pages ne porte d'image. La
   planche fait les deux : elle prend les 1240 px et elle porte un cliche.

   DEUX REMPLISSAGES, UNE SEULE REGLE. Quand la page a une photographie — les
   9 cliches d'atelier de vendor/watercooling, les 47 captures de
   vendor/vitrines, les 49 logos de vendor/marques, tous deja servis en local —
   c'est un <img>. Quand elle n'en a pas, c'est le POINCON : le glyphe de la
   rubrique, grave sur la fonte. Rien n'est invente : on montre ce qu'on a.
   ---------------------------------------------------------------------- */
.fi .fi-planche{
  position:relative;isolation:isolate;overflow:hidden;
  margin:clamp(2.4rem,5vw,3.6rem) calc(-1 * var(--at-debord,0px));
  border-radius:calc(var(--r) + 6px);
  background:linear-gradient(166deg,var(--at-fonte-2) 0%,var(--at-fonte) 62%,var(--encre) 100%);
  box-shadow:var(--ombre-2)}
.fi .fi-planche::after{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:var(--signal)}
.fi .fi-planche-rang{display:grid;gap:clamp(1.2rem,2.8vw,2.2rem);align-items:center;
  padding:clamp(1.3rem,3.2vw,2.2rem)}
@media (min-width:720px){
  .fi .fi-planche-rang{grid-template-columns:minmax(0,1.02fr) minmax(0,1fr)}
  .fi .fi-planche--droite .fi-planche-rang>figure{order:2}
}
/* Le cliche. « object-fit:cover » sur un rapport impose : les photographies du
   depot sont en 3/4 (atelier) comme en 16/9 (captures de site), elles entrent
   toutes dans la meme fenetre sans se deformer. */
.fi .fi-planche figure{margin:0}
.fi .fi-planche img{display:block;width:100%;aspect-ratio:4 / 3;object-fit:cover;
  border-radius:var(--r);
  border:1px solid color-mix(in oklab,var(--at-craie) 18%,transparent)}
.fi .fi-planche figcaption{margin-top:.6rem;font-size:.8rem;line-height:1.4;
  color:color-mix(in oklab,var(--at-craie) 74%,var(--at-fonte))}
/* LE POINCON. Le glyphe de rubrique frappe sur la fonte, avec les memes stries
   que la plaque. C'est la reponse aux 35 pages sur 37 qui n'ont qu'UN dessin
   disponible : au lieu de le repeter en petit huit fois, on le montre une fois
   en grand. */
.fi .fi-poincon{display:grid;place-items:center;aspect-ratio:4 / 3;
  border-radius:var(--r);position:relative;overflow:hidden;
  background:
    repeating-linear-gradient(115deg,
      color-mix(in oklab,var(--at-craie) 9%,transparent) 0 1px,transparent 1px 13px),
    linear-gradient(150deg,color-mix(in oklab,var(--acc) 26%,var(--encre)) 0%,var(--encre) 100%);
  border:1px solid color-mix(in oklab,var(--at-craie) 16%,transparent)}
.fi .fi-poincon svg{width:54%;height:auto;color:var(--acc-clair);
  fill:none;stroke:currentColor;stroke-width:1.1;stroke-linecap:round;stroke-linejoin:round}
.fi .fi-planche .fi-titret{color:var(--acc-clair)}
.fi .fi-planche .fi-titret::before{background:var(--signal-nuit)}
.fi .fi-planche h2{font-family:var(--fi-titre);font-weight:400;margin:.7rem 0 0;
  font-size:clamp(1.5rem,3vw,2.15rem);line-height:1.1;letter-spacing:-.012em;
  color:var(--papier);max-width:20ch}
.fi .fi-planche p{margin-top:.8rem;color:var(--at-craie);font-size:.99rem;max-width:48ch}
.fi .fi-planche a:not(.bouton){color:var(--acc-clair)}

/* -------------------------------------------------------------------------
   5. L'ETIQUETTE D'ATELIER — la marge enfin habitee
   -------------------------------------------------------------------------
   La colonne de droite du gabarit est reservee, dessinee, payee — et vide sur
   86 436 px cumules. On y accroche l'objet que le comptoir produit vraiment :
   l'etiquette du materiel pris en charge. Papier d'atelier, oeillet perfore,
   filet de signal en tete, chiffres tabulaires.

   Elle remplace la bande de reperes du cartouche, qui affichait « Atelier /
   53 rue Voltaire » a l'identique sur 37 pages sur 37, a l'endroit le plus
   visible de la page. Sous 1080 px la marge repasse au-dessus du corps : elle
   arrive donc exactement la ou etaient les reperes, en plus utile.

   ELLE NE PROMET RIEN. Chaque couple vient de la page ou du corpus. Quand
   l'information n'existe pas, on pose le marqueur visible — c'est la regle du
   projet, et c'est ce qui rend l'objet honnete.
   ---------------------------------------------------------------------- */
.fi .fi-etiquette{position:relative;margin:1.6rem 0 0;
  padding:1.7rem 1.15rem 1.15rem;
  border:1px solid var(--at-burin);border-radius:var(--r);
  background:
    radial-gradient(circle at 1.5rem 1rem,transparent 0 .34rem,var(--at-etabli) .34rem);
  box-shadow:var(--ombre-1)}
.fi .fi-etiquette::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  border-radius:var(--r) var(--r) 0 0;background:var(--signal)}
.fi .fi-etiquette-titre{margin:0 0 .9rem;padding-left:2.6rem;
  font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;font-weight:700;
  color:var(--fi-appui)}
.fi .fi-etiquette dl{margin:0;display:grid;gap:.75rem 1.4rem}
.fi .fi-etiquette dt{font-size:.63rem;letter-spacing:.18em;text-transform:uppercase;
  font-weight:700;color:var(--texte-2)}
.fi .fi-etiquette dd{margin:.12rem 0 0;font-size:.9rem;font-weight:500;line-height:1.35;
  color:var(--texte);font-variant-numeric:tabular-nums}
.fi .fi-etiquette dd a{color:var(--acc)}
/* Le marqueur d'information manquante. Il doit se VOIR : une donnee absente
   qui se fond dans la page est une donnee qu'on oublie de demander. */

/* Sous 1080 px l'etiquette est pleine largeur : les couples se rangent en
   colonnes de 9 rem au minimum, donc une seule colonne a 390 px et trois a
   1024. Aucune valeur fixe, aucun debordement possible. */
@media (max-width:1079px){
  .fi .fi-etiquette dl{grid-template-columns:repeat(auto-fit,minmax(9rem,1fr))}
}

/* -------------------------------------------------------------------------
   6. LE COMPTOIR — la fin de page a la largeur de la grille
   -------------------------------------------------------------------------
   Le bloc sombre « L'atelier » existe deja et fonctionne ; il est simplement
   trop etroit et trop discret pour clore une page. Il prend les 1240 px, la
   texture de la plaque, et le numero de telephone passe en display : c'est le
   geste le moins cher pour une entreprise locale — le numero EST l'appel a
   l'action, il n'a pas besoin d'un bouton pour le dire.
   ---------------------------------------------------------------------- */
.fi.fi--etabli .fi-fin{
  margin-inline:calc(-1 * var(--at-debord));
  padding:clamp(1.9rem,4.6vw,3.2rem) clamp(1.5rem,4vw,3.2rem)}
.fi.fi--etabli .fi-fin::before{
  background:
    repeating-linear-gradient(90deg,
      color-mix(in oklab,var(--at-craie) 7%,transparent) 0 1px,transparent 1px 9px),
    linear-gradient(166deg,var(--at-fonte-2) 0%,var(--at-fonte) 62%,var(--encre) 100%)}
.fi.fi--etabli .fi-fin h2{font-size:clamp(1.65rem,3.4vw,2.5rem);max-width:20ch}
/* Le numero en display. « .fi .fi-fin a:not(.bouton) » pese 0-3-1 : le
   selecteur ci-dessous pese autant et doit donc rester APRES lui dans la
   feuille. C'est la seule dependance a l'ordre de ce bloc. */
.fi .fi-fin a.fi-fin-tel{display:inline-block;margin-top:1.2rem;
  font-family:var(--fi-titre);font-size:clamp(1.9rem,4.4vw,3rem);
  line-height:1;letter-spacing:-.02em;text-decoration:none;
  font-variant-numeric:tabular-nums;color:var(--papier)}
.fi .fi-fin a.fi-fin-tel:hover{color:var(--acc-clair)}
.fi .fi-fin a.fi-fin-tel:focus-visible{outline:2px solid var(--acc-clair);
  outline-offset:4px;border-radius:8px}
/* LE PLAN DE TRAVAIL. La section de demande cesse d'etre une carte blanche
   posee sur du blanc : elle prend le fond d'etabli. Elle NE s'elargit PAS —
   des champs de 1200 px de large sont plus durs a remplir que des champs de
   700, et le formulaire pese deja 25 % de la hauteur de page. */
.fi.fi--etabli .fi-demande{
  background:
    linear-gradient(var(--at-etabli),var(--at-etabli)) padding-box,
    var(--signal) border-box}
.fi.fi--etabli .fi-demande>h2{font-size:clamp(1.5rem,2.8vw,2.05rem)}

/* -------------------------------------------------------------------------
   7. MOUVEMENT REDUIT
   Ce bloc n'ajoute ni @keyframes, ni transform, ni transition de position :
   il n'y a donc rien a couper. La regle est ecrite quand meme — la seule
   transition heritee est celle de la couleur du numero de telephone, et ce
   qui est explicite ne depend pas d'une autre regle.
   ---------------------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  .fi .fi-fin a.fi-fin-tel{transition:none}
}

/* ============================================================ LE MARQUEUR
   « A FOURNIR » — il n'avait de style que dans les <style> locaux de huit
   pages, ecrit en rgba() EN DUR : une couleur codee en clair, et l'accent
   Particuliers pose sur des pages PRO. Les 37 fiches n'ont aucun <style>
   local — sans cette regle, le <mark> retombe sur le jaune fluo du
   navigateur, en pleine tete de page.
   C'est aussi un CONTRAT : outils/marqueurs.mjs lit exactement
   <mark class="a-fournir"><b>A fournir</b> la question</mark> pour engendrer
   PHASE2-A-DEMANDER-A-CEDRIC.md. Ne pas changer cette forme.
   Contraste mesure : #C2410C sur --sec-voile = 4,67 (PRO), #2B5BE0 sur
   #EAF0FF = 5,01 (PART). Au-dessus de 4,5 dans les deux univers. */
.a-fournir{background:none;color:var(--sec-fonce);font-style:italic;
  border-bottom:1px dashed color-mix(in oklab,var(--sec-fonce) 45%,transparent)}
.a-fournir b{font-style:normal;font-weight:600;font-size:.8em;letter-spacing:.08em;
  text-transform:uppercase;margin-right:.3em;color:var(--sec-fonce)}
