/* ============================================================
   LE DESIGN SYSTEM DYMAD
   ============================================================
   Ce fichier etait inline dans index.html tant que le site tenait en une
   page : aucune requete a ouvrir, mise en page instantanee. A partir de deux
   pages l'inline devient un defaut, parce que le visiteur retelechargerait
   la meme feuille a chaque navigation. Sorti ici, il est mis en cache une
   fois et sert toutes les pages (voir les en-tetes de cache du .htaccess).

   Les url() des polices sont ABSOLUES (/assets/fonts/...) et doivent le
   rester : une url relative dans un CSS se resout depuis le CSS, pas depuis
   la page. Ecrite « assets/fonts/... », elle pointerait /assets/assets/.
   ============================================================ */

/* Space Grotesk est une police variable : un seul fichier couvre 400 a 700. */
@font-face{font-family:'Space Grotesk';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/assets/fonts/space-grotesk-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:'Space Grotesk';font-style:normal;font-weight:400 700;font-display:swap;
  src:url(/assets/fonts/space-grotesk-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,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}
@font-face{font-family:'Instrument Sans';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;
  src:url(/assets/fonts/instrument-sans-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:'Instrument Sans';font-style:normal;font-weight:400;font-stretch:100%;font-display:swap;
  src:url(/assets/fonts/instrument-sans-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,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}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(/assets/fonts/space-mono-400-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:'Space Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(/assets/fonts/space-mono-400-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,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}
@font-face{font-family:'Space Mono';font-style:normal;font-weight:700;font-display:swap;
  src:url(/assets/fonts/space-mono-700-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:'Space Mono';font-style:normal;font-weight:700;font-display:swap;
  src:url(/assets/fonts/space-mono-700-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,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{
  /* ================= SURFACES =================
     L'encre n'est plus un gris neutre mais un bleu de nuit : la meme valeur
     sert de couleur de texte sur papier ET de sol aux sections sombres, donc
     la teinte de la marque traverse toute la page sans qu'on la repeigne.
     Trois paliers de nuit : le sol, la surface posee dessus, celle qui avance. */
  --encre:#0B1020;
  --encre-2:#111832;
  --encre-3:#18203C;
  --encre-appui:#050814;
  --papier:#FAF9F7;
  --papier-2:#F2F0EC;
  --blanc:#FFFFFF;

  /* Échelle de gris refroidie pour s'accorder au bleu de nuit. Chaque valeur
     tient WCAG AA (4.5:1) sur papier, papier-2 et blanc :
     --gris 6,89:1 · --gris-clair 4,75:1 sur le fond le plus clair des trois. */
  --gris:#4F5665;
  --gris-clair:#63697A;

  --ligne:rgba(11,16,32,.14);
  --ligne-fine:rgba(11,16,32,.075);

  /* Jetons de la nuit. Valeurs opaques et non plus des alpha : un contraste
     se mesure, il ne s'estime pas. 12,5:1 · 9,0:1 · 5,5:1 sur --encre. */
  --sur-encre:#C9D2E6;
  --sur-encre-2:#A7B2CB;
  --sur-encre-3:#8590AA;
  --ligne-inv:rgba(255,255,255,.14);
  --ligne-inv-fine:rgba(255,255,255,.07);
  --voile-inv:rgba(255,255,255,.05);

  /* ---- Verre ----
     Employe a trois endroits seulement, et toujours parce qu'il y a quelque
     chose derriere : la barre de navigation, les instruments du hero, le
     panneau de l'audit. Jamais comme decor sur une surface pleine. */
  --verre:rgba(255,255,255,.05);
  --verre-bord:rgba(255,255,255,.11);
  --verre-haut:rgba(255,255,255,.20);
  --flou:blur(14px) saturate(140%);

  --display:'Space Grotesk',system-ui,sans-serif;
  --corps:'Instrument Sans',system-ui,sans-serif;
  /* Le monospace est reserve a ce qui se mesure : un chiffre, une unite, une
     source, une date. La navigation et les boutons sont passes au display :
     une chasse fixe sur un libelle d'action est un costume, pas une donnee. */
  --util:'Space Mono',ui-monospace,monospace;
  --etiq:var(--display);

  /* ================= SPECTRE =================
     Un seul intervalle de couleur, du bleu electrique au turquoise, et rien
     en dehors. Le degrade ne va jamais d'un extreme a l'autre sous un texte :
     --degrade-btn reste dans les bleus fonces pour que le blanc tienne 5,1:1
     sur toute sa course. Le turquoise n'apparait que sur la nuit et dans les
     filets, ou il ne porte aucun texte. */
  --accent:#2348C6;        /* 7,19:1 sur papier */
  --accent-vif:#2E5AE0;    /* 5,37:1 - survols */
  --accent-inv:#7FA5FF;    /* 8,25:1 sur encre */
  --accent-inv-2:#5FE3D0;  /* 11,9:1 sur encre - le bout turquoise */
  /* Le bout turquoise du spectre, assombri pour porter du texte sur le papier :
     5,02:1 sur blanc. Le turquoise clair ne sert jamais de couleur de texte
     sur fond clair — a 2,3:1 il serait illisible. */
  --accent-fin:#0C7D71;

  --degrade-btn:linear-gradient(118deg,#2348C6,#3A63DE);
  --degrade-inv:linear-gradient(118deg,#7FA5FF,#5FE3D0);
  --degrade-filet:linear-gradient(90deg,transparent,rgba(35,72,198,.5) 20%,rgba(63,207,192,.5) 70%,transparent);
  --degrade-filet-inv:linear-gradient(90deg,transparent,rgba(127,165,255,.55) 20%,rgba(95,227,208,.5) 70%,transparent);

  /* ---- Elevation ----
     Une surface saturee posee sur du papier assombrit legerement ce qu'elle
     surplombe, et cette ombre prend un peu de sa teinte. C'est tout ce que
     --lueur decrit : une ombre portee, avec un decalage vertical franc et une
     dominante neutre. Ce n'est PAS un halo — un flou centre sans decalage sous
     un bouton ne decrit aucune lumiere reelle et se lit comme un autocollant. */
  --lueur:0 6px 12px -6px rgba(11,16,32,.30), 0 14px 30px -14px rgba(35,72,198,.32);
  --lueur-inv:0 6px 14px -6px rgba(0,0,0,.45), 0 18px 38px -16px rgba(0,0,0,.5);

  --ease:cubic-bezier(.19,1,.22,1);

  /* ---- Jetons de mouvement ----
     Une seule courbe d'arrivee (--ease, expo-out) pour tout le site : depart
     franc, arrivee longue et posee. Rien ne rebondit.
     Les durees expriment la distance parcourue, pas une preference. */
  --t-tact:120ms;      /* accuse reception : survol, pression */
  --t-etat:220ms;      /* changement d'etat : onglet, ouverture */
  --t-plan:420ms;      /* deplacement d'un plan, bascule de panneau */
  --t-scene:760ms;     /* entree composee : une section se decouvre */
  --t-ouverture:1150ms;/* le hero, une seule fois */

  /* ---- Echelle de profondeur ----
     Le site n'a ni arrondi ni ombre diffuse : la profondeur vient donc de la
     perspective, du decalage des plans et de l'epaisseur des filets. Les rares
     ombres portees gardent un decalage vertical et un flou franc — jamais un
     halo centre, qui ne serait qu'une decoration. La teinte des ombres est
     celle du bleu de nuit : une ombre grise sur un site bleu se voit. */
  --z2:0 2px 4px rgba(11,16,32,.05), 0 10px 28px rgba(11,16,32,.075);
  --z3:0 4px 8px rgba(11,16,32,.06), 0 22px 54px rgba(11,16,32,.11);
  /* Sur la nuit, une ombre noire ne se voit pas : la profondeur passe par un
     filet clair en haut de la surface, comme une arete qui prend la lumiere. */
  --z-nuit:0 2px 6px rgba(0,0,0,.35), 0 20px 48px rgba(0,0,0,.42);

  --g:clamp(20px,5vw,60px);
  --max:1160px;

  /* Hauteur de la barre de navigation : logo (56px, 48px sous 560px) + 2 x 11px
     de marge + 1px de filet. Le hero et l'entete des pages s'y glissent
     dessous : ils la reprennent en marge negative et la rendent en padding. */
  --barre:79px;
}
@media(max-width:560px){:root{--barre:71px}}
/* Tres grand ecran : a 1920px et au-dela, 1 160px de contenu laissaient les
   sections papier flotter au milieu de marges de 380px. */
@media(min-width:1800px){:root{--max:1280px}}
*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%;
  /* Le fond du document, et non celui du body : c'est lui que Safari montre
     quand on tire la page au-dela de ses bords. La barre et le pied sont sur
     la nuit ; le rebond l'est aussi, au lieu d'un eclair de papier. */
  background:var(--encre)}
/* Le bloc « mouvement reduit » est en fin de feuille, avec le systeme
   de mouvement qu'il neutralise. */

body{
  margin:0;background:var(--papier);color:var(--encre);
  font-family:var(--corps);font-size:16.5px;
  line-height:1.62;-webkit-font-smoothing:antialiased;
}
/* La gouttiere s'elargit si l'ecran l'exige : en paysage, l'encoche de
   l'iPhone mange le bord gauche ou droit (viewport-fit=cover laisse les fonds
   aller jusqu'au bord, le texte, lui, reste hors de l'encoche). */
.wrap{max-width:var(--max);margin:0 auto;
  padding-left:max(var(--g),env(safe-area-inset-left));
  padding-right:max(var(--g),env(safe-area-inset-right))}
/* balance : les lignes d'un titre s'equilibrent, aucun mot ne reste seul sur
   la derniere (« appels. », « coute. »). */
h1,h2,h3{font-family:var(--display);font-weight:500;line-height:1.06;letter-spacing:-.03em;margin:0;
  text-wrap:balance}
p{margin:0}
a{color:inherit}
img{max-width:100%}
/* Une ancre pose sa section juste sous la barre : ni cachee dessous, ni avec
   un liseré de la section precedente au-dessus. */
section[id],header[id],article[id]{scroll-margin-top:var(--barre)}

/* ---- Surfaces du navigateur ----
   La selection, le curseur de saisie, la barre de defilement et l'anneau de
   focus sont dessines par le navigateur, pas par le systeme graphique du site.
   Laisses par defaut, ils introduisent un bleu Windows et un gris Chrome qui
   n'appartiennent a aucune palette. On les rattache a la nuit et au spectre. */
::selection{background:var(--accent);color:#fff;text-shadow:none}
.fond-encre ::selection,.audit ::selection,.signe ::selection,
.hero ::selection,.contact ::selection,footer ::selection{
  background:var(--accent-inv);color:var(--encre)}
html{scrollbar-color:rgba(127,165,255,.32) transparent;scrollbar-width:thin}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.fond-encre :focus-visible,.audit :focus-visible,.hero :focus-visible,
.contact :focus-visible,footer :focus-visible,
.nav :focus-visible,.bandeau :focus-visible,.sur-nuit :focus-visible,
.saut:focus-visible{outline-color:var(--accent-inv)}
input,textarea,select{caret-color:var(--accent-inv)}
/* Chiffres a chasse fixe partout ou l'on compare une valeur a une autre :
   sans cela un compteur qui monte fait sauter la mise en page a chaque dizaine. */
.montant,.chrono-num,.plaque-val,.compteur{font-variant-numeric:tabular-nums}
a:not(.btn):not([class]){text-underline-offset:.18em;text-decoration-thickness:1px}

.saut{position:absolute;left:-9999px;top:0;background:var(--encre);color:var(--papier);
  padding:12px 18px;font-family:var(--util);font-size:12px;z-index:200}
.saut:focus{left:var(--g);top:10px}

.eyebrow{
  font-family:var(--util);font-size:12px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gris-clair);
}

/* ---- lentille : le motif de la marque ---- */
.lentille{width:1em;height:1em;flex:none;display:block}
.lentille path{fill:none;stroke:currentColor;stroke-width:13;stroke-linecap:round;transition:fill .2s ease}

/* ================= NAVIGATION =================
   La barre flotte sur la nuit du hero : verre, filet clair en bas, et une
   jauge de lecture d'un pixel qui court sur toute la largeur. Le verre est
   legitime ici parce qu'il y a un relief anime derriere ; ailleurs sur la page
   il n'y aurait rien a laisser passer. */
.nav{position:sticky;top:0;z-index:60;
  background:rgba(11,16,32,.72);
  -webkit-backdrop-filter:var(--flou);backdrop-filter:var(--flou);
  border-bottom:1px solid var(--ligne-inv-fine);color:var(--papier)}
/* Repli : sans verre disponible, on opacifie le fond plutot que de laisser le
   texte passer sur le relief anime. */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .nav{background:rgba(11,16,32,.94)}
}
.nav-in{display:flex;align-items:center;justify-content:space-between;gap:14px;padding-top:11px;padding-bottom:11px;position:relative}
/* Le logotype est un SVG en encre, employe tel quel sur la page des mentions
   legales qui est restee claire. Sur la nuit il est ramene au blanc par un
   filtre deterministe plutot que duplique en un second fichier. */
.nav-in .logo{display:block;height:56px;width:auto;filter:brightness(0) invert(1)}
.nav-droite{display:flex;align-items:center;gap:clamp(14px,2vw,26px)}
.nav-links{display:flex;align-items:center;gap:clamp(14px,2vw,26px)}
.nav-links a{font-family:var(--etiq);font-size:13.5px;font-weight:500;
  letter-spacing:-.005em;text-decoration:none;color:var(--sur-encre-2)}
@media(hover:hover){.nav-links a:hover{color:var(--papier)}}

/* La jauge de lecture. Le script pose --lu (0 a 1) ; sans lui elle reste a
   zero et la barre garde simplement son filet. Ce n'est pas un ornement :
   c'est la seule indication de longueur restante sur une page d'un seul flux. */
.nav::after{content:"";position:absolute;left:0;bottom:-1px;height:2px;width:100%;
  background:var(--degrade-inv);transform-origin:left;
  transform:scaleX(var(--lu,0));pointer-events:none}
/* La ou le navigateur sait lier une animation au defilement, c'est lui qui
   mene la jauge, hors du script : elle suit le pouce sans retard sur Safari,
   et elle existe sur toutes les pages (les articles surtout), pas seulement
   sur l'accueil. Ailleurs, le script de l'accueil prend le relais. */
@supports (animation-timeline:scroll()){
  .nav::after{animation:jauge-lecture linear both;animation-timeline:scroll(root block)}
}
@keyframes jauge-lecture{from{transform:scaleX(0)}to{transform:scaleX(1)}}

.nav-menu{display:none;align-items:center;justify-content:center;width:44px;height:44px;
  border:1px solid var(--ligne-inv);background:var(--verre);cursor:pointer;color:var(--papier);padding:0}
.nav-menu svg{width:17px;height:12px;overflow:visible}
/* Les trois traits deviennent une croix : le bouton dit ce qu'il fera au
   prochain appui. Chaque trait tourne sur son propre centre. */
.nav-menu rect{fill:currentColor;transform-box:fill-box;transform-origin:center;
  transition:transform var(--t-plan) var(--ease),opacity var(--t-tact) var(--ease)}
.nav-menu[aria-expanded="true"] rect:nth-child(1){transform:translateY(5.2px) rotate(45deg)}
.nav-menu[aria-expanded="true"] rect:nth-child(2){opacity:0}
.nav-menu[aria-expanded="true"] rect:nth-child(3){transform:translateY(-5.2px) rotate(-45deg)}

@media(max-width:900px){
  .nav-menu{display:inline-flex}
  /* Le panneau part du filet bas de la barre et va d'un bord a l'autre de
     l'ecran. Sous 900px, .nav-in occupe deja toute la largeur : left et right
     a zero suffisent, et le padding retrouve la gouttiere. Avant, il flottait
     13px plus bas (la page se voyait dans l'interstice) et debordait de 20px
     de chaque cote, ce qui rendait la page defilable en largeur.
     Fond opaque et sans flou : le titre du hero transparaissait a travers.
     Hauteur bornee a l'ecran, defilement interne : en paysage, les derniers
     liens etaient hors d'atteinte. */
  .nav-links{
    position:absolute;top:calc(100% + 1px);left:0;right:0;
    display:none;flex-direction:column;align-items:stretch;gap:0;
    max-height:calc(100vh - var(--barre));max-height:calc(100dvh - var(--barre));
    overflow-y:auto;overscroll-behavior:contain;
    background:var(--encre);
    border-bottom:1px solid var(--ligne-inv);
    box-shadow:0 26px 40px -26px rgba(0,0,0,.7);
    padding:4px max(var(--g),env(safe-area-inset-right)) 18px max(var(--g),env(safe-area-inset-left));
    /* Le panneau se deroule depuis la barre, et s'enroule plus vite qu'il ne
       s'ouvre. display suit la transition (allow-discrete) : sans ce mot, la
       fermeture couperait net. */
    clip-path:inset(0 0 100% 0);
    transition:clip-path 220ms var(--ease),display 220ms allow-discrete;
  }
  .nav-links[data-ouvert="true"]{display:flex;clip-path:inset(0 0 0 0);
    transition:clip-path var(--t-plan) var(--ease),display var(--t-plan) allow-discrete}
  @starting-style{.nav-links[data-ouvert="true"]{clip-path:inset(0 0 100% 0)}}
  /* Les liens suivent le deroulement, en cascade courte. */
  .nav-links[data-ouvert="true"] > *{animation:menu-lien var(--t-plan) var(--ease) both;
    animation-delay:calc(var(--i,0) * 35ms + 60ms)}
  .nav-links > :nth-child(2){--i:1}
  .nav-links > :nth-child(3){--i:2}
  .nav-links > :nth-child(4){--i:3}
  .nav-links > :nth-child(5){--i:4}
  .nav-links a{padding-top:15px;padding-bottom:15px;border-top:1px solid var(--ligne-inv-fine);font-size:15px}
  .nav-links a:first-child{border-top:none}
  /* Le reste de la page s'assombrit sous le menu ouvert : on voit qu'on est
     dans le menu, et un appui a cote le referme sans suivre un lien cache
     dessous. Le voile part du bas de la barre (la barre est collante en haut),
     car le flou de la barre fait d'elle le repere des elements fixes. */
  .nav::before{content:"";position:absolute;left:0;right:0;top:100%;height:100vh;height:100dvh;
    z-index:-1;background:rgba(5,8,20,.55);opacity:0;pointer-events:none;
    transition:opacity var(--t-etat) var(--ease)}
  .nav:has(.nav-links[data-ouvert="true"])::before{opacity:1;pointer-events:auto;touch-action:none}
}
@keyframes menu-lien{from{opacity:0;transform:translate3d(0,-6px,0)}}
@media(max-width:560px){
  .nav-in .logo{height:48px}
  .nav-droite{gap:12px}
  .nav-droite .btn{font-size:12px;padding:11px 13px}
}

/* ================= BOUTONS =================
   L'aimantation : le bouton se decale de quelques pixels vers le curseur, ce
   qui donne l'impression qu'il vient au-devant de la main. Le decalage est
   plafonne a 4px et la couche interieure suit un peu plus loin que le cadre :
   c'est ce petit ecart entre les deux qui rend le geste perceptible.
   Le script pose --ax et --ay ; sans lui, tout vaut zero.

   Le libelle est au display et non plus a la chasse fixe : une action se lit,
   elle ne se mesure pas. */
.btn{display:inline-flex;align-items:center;gap:10px;position:relative;
  font-family:var(--etiq);font-size:14px;font-weight:500;letter-spacing:-.005em;
  text-decoration:none;padding:14px 22px;border:1px solid var(--encre);
  background:none;cursor:pointer;overflow:hidden;color:var(--encre);
  transform:translate3d(var(--ax,0),var(--ay,0),0);
  transition:background var(--t-etat) var(--ease),color var(--t-etat) var(--ease),
             border-color var(--t-etat) var(--ease),box-shadow var(--t-plan) var(--ease),
             transform var(--t-plan) var(--ease)}
.btn > *{position:relative;z-index:2}

/* Le bouton plein porte le degrade du spectre. Il reste dans les bleus
   fonces : le blanc tient 5,1:1 sur toute la course du degrade. */
.btn-plein{background:var(--degrade-btn);color:#fff;border-color:transparent;
  box-shadow:var(--lueur)}
/* Au survol, la lumiere balaie le bouton de gauche a droite, une fois. Elle ne
   boucle pas : un reflet qui tourne en permanence est une decoration. */
.btn-plein::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.22) 50%,transparent 80%);
  transform:translate3d(-110%,0,0);
  transition:transform var(--t-scene) var(--ease)}
.btn-plein:focus-visible::after{transform:translate3d(110%,0,0)}
@media(hover:hover){.btn-plein:hover::after{transform:translate3d(110%,0,0)}}
@media(hover:hover){.btn-plein:hover{box-shadow:0 8px 16px -6px rgba(11,16,32,.34), 0 20px 40px -16px rgba(35,72,198,.4)}}

.btn-vide{color:var(--encre);border-color:var(--ligne)}

/* Le remplissage monte depuis le bas au lieu d'apparaitre d'un coup : le
   bouton se remplit, il ne clignote pas. */
.btn-vide::before{content:"";position:absolute;inset:0;z-index:1;background:var(--degrade-btn);
  transform-origin:bottom;transform:scaleY(0);
  transition:transform var(--t-etat) var(--ease)}
.btn-vide:focus-visible::before{transform:scaleY(1)}
@media(hover:hover){.btn-vide:hover::before{transform:scaleY(1)}}
.btn-vide:focus-visible{color:#fff;border-color:transparent;box-shadow:var(--lueur)}
@media(hover:hover){.btn-vide:hover{color:#fff;border-color:transparent;box-shadow:var(--lueur)}}
.btn:active{transform:translate3d(var(--ax,0),calc(var(--ay,0px) + 1px),0)}

/* Au toucher, pas de survol a anticiper : une reponse immediate a l'appui. Le
   voile gris que Safari pose d'office sur tout ce qu'on touche est retire, et
   chaque element tactile porte son propre etat « appuye » : le bouton se
   tasse d'un cran et revient en douceur, le lien s'eteint le temps du geste.
   Safari n'applique :active qu'a une page qui ecoute touchstart : chaque page
   le fait, en une ligne, dans son script. */
html{-webkit-tap-highlight-color:transparent}
@media(hover:none){
  .btn:active{transform:scale(.97);transition-duration:90ms}
  .btn-plein:active{filter:brightness(.94)}
  .btn-vide:active{background:var(--papier-2)}
  .sur-nuit .btn-vide:active,.audit .btn-vide:active,.fond-encre .btn-vide:active,
  .hero .btn-vide:active{background:rgba(255,255,255,.12)}
  a:not(.btn):active,summary:active,.nav-sous-bascule:active,.nav-menu:active{opacity:.62}
  .choix button:active{background:var(--papier-2)}
  .choix button[aria-selected="true"]:active{background:var(--encre-2)}
}

/* Sur la nuit : le bouton plein passe au papier (contraste maximal sur le
   fond le plus sombre), le bouton vide prend le degrade clair. */
.sur-nuit .btn-plein,.audit .btn-plein,.fond-encre .btn-plein,.hero .btn-plein{
  background:var(--papier);color:var(--encre);box-shadow:var(--lueur-inv)}
@media(hover:hover){.sur-nuit .btn-plein:hover,.audit .btn-plein:hover,.fond-encre .btn-plein:hover,.hero .btn-plein:hover{
  background:#fff;box-shadow:0 8px 18px -6px rgba(0,0,0,.5), 0 24px 46px -18px rgba(0,0,0,.55)}}
.sur-nuit .btn-plein::after,.audit .btn-plein::after,
.fond-encre .btn-plein::after,.hero .btn-plein::after{
  background:linear-gradient(100deg,transparent 20%,rgba(35,72,198,.16) 50%,transparent 80%)}
.sur-nuit .btn-vide,.audit .btn-vide,.fond-encre .btn-vide,.hero .btn-vide{
  color:var(--papier);border-color:var(--ligne-inv);background:var(--verre)}
.audit .btn-vide::before,.fond-encre .btn-vide::before,
.hero .btn-vide::before,.sur-nuit .btn-vide::before{background:var(--degrade-inv)}
@media(hover:hover){.audit .btn-vide:hover,.fond-encre .btn-vide:hover,
.hero .btn-vide:hover,.sur-nuit .btn-vide:hover{
  color:var(--encre);border-color:transparent;box-shadow:var(--lueur-inv)}}
.audit .btn-vide:focus-visible,.fond-encre .btn-vide:focus-visible,
.hero .btn-vide:focus-visible,.sur-nuit .btn-vide:focus-visible{
  color:var(--encre);border-color:transparent;box-shadow:var(--lueur-inv)}

/* ================= HERO =================
   Le premier ecran est desormais la nuit. C'est la decision structurante de la
   page : le visiteur arrive dans un poste de pilotage, puis la page s'ouvre sur
   le papier pour lire les prestations. La nuit revient sur les trois moments de
   demonstration — la convergence, l'audit, le cadrage — et sur le contact. On
   alterne donc nuit / papier / nuit, et chaque bascule veut dire quelque chose.

   Quatre couches, du fond vers l'avant :
     0  le sol de nuit et ses deux nappes de lumiere fixes
     1  la trame orthogonale, effacee vers les bords
     2  le relief WebGL, quand il se charge
     3  le halo qui suit le curseur
     4  le contenu */
/* Le hero remonte sous la barre (marge negative) et lui rend sa hauteur en
   padding. Sans cela la barre, collante mais dans le flux, posait son verre sur
   le papier du body : un bandeau gris entre la barre de Safari et la nuit du
   hero, liens a 3,7:1. Desormais le verre floute la nuit, comme prevu. */
.hero{margin-top:calc(var(--barre) * -1);
  padding-top:calc(var(--barre) + clamp(52px,6vw,92px));padding-bottom:clamp(56px,7vw,104px);
  position:relative;overflow:hidden;
  background:var(--encre);color:var(--papier);
  /* Deux nappes de lumiere posees dans les angles : elles donnent la profondeur
     du fond avant toute animation, et restent la si le WebGL ne se charge pas.
     Les deux extremites du spectre, une par angle — c'est la seule endroit de
     la page ou les deux cohabitent. */
  background-image:
    radial-gradient(120% 90% at 78% 8%,rgba(35,72,198,.42) 0%,transparent 62%),
    radial-gradient(90% 80% at 6% 96%,rgba(63,207,192,.16) 0%,transparent 58%),
    linear-gradient(180deg,#0B1020 0%,#0D1428 58%,#0B1020 100%);
}

/* Substrat papier : une trame orthogonale de filets 1px, effacee vers les bords
   par un masque radial. C'est le sol de la scene, present meme sans JavaScript.
   Le relief anime en WebGL, quand il se charge, sort de cette trame. */
.hero::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    repeating-linear-gradient(to right,var(--ligne-inv-fine) 0 1px,transparent 1px 78px),
    repeating-linear-gradient(to bottom,var(--ligne-inv-fine) 0 1px,transparent 1px 78px);
  -webkit-mask-image:radial-gradient(125% 95% at 68% 40%,#000 0%,transparent 74%);
  mask-image:radial-gradient(125% 95% at 68% 40%,#000 0%,transparent 74%);
}

/* Le halo du curseur. Le script pose --mx / --my en pourcentages ; au repos il
   est centre sur la scene, donc l'effet existe deja avant tout mouvement et ne
   saute pas a la premiere image. Le degrade est dessine une fois, au centre de
   la couche, et c'est la couche qui se deplace : auparavant la position du
   degrade changeait, et le navigateur repeignait une surface plus grande que
   le hero a chaque image. Un translate ne repeint rien. */
.hero-lueur{
  position:absolute;inset:-20%;z-index:2;pointer-events:none;
  opacity:0;transition:opacity 1.4s var(--ease);
  background:radial-gradient(38% 38% at 50% 50%,
             rgba(127,165,255,.20) 0%,rgba(95,227,208,.07) 42%,transparent 70%);
  transform:translate3d(calc(var(--mx,66%) - 50%),calc(var(--my,38%) - 50%),0);
}
@media(pointer:fine){.hero-lueur{will-change:transform}}
.hero-lueur.vu{opacity:1}

/* Le substrat anime. Il est masque en dur du cote du texte : le relief est un
   fond, il ne doit jamais passer derriere le titre ni derriere le paragraphe.
   Le masque CSS s'applique quel que soit ce que dessine le module — c'est une
   garantie de lisibilite, pas un reglage esthetique. */
.hero-toile{
  position:absolute;inset:0;width:100%;height:100%;z-index:2;
  pointer-events:none;opacity:0;transition:opacity 1.2s var(--ease);
  -webkit-mask-image:linear-gradient(100deg,transparent 30%,#000 58%),
                     radial-gradient(120% 104% at 72% 46%,#000 42%,transparent 78%);
  mask-image:linear-gradient(100deg,transparent 30%,#000 58%),
             radial-gradient(120% 104% at 72% 46%,#000 42%,transparent 78%);
  -webkit-mask-composite:source-in;
  mask-composite:intersect;
}
.hero-toile.vu{opacity:.85}

/* La colonne du texte prend un peu plus que celle de la scene : a 74px dans
   une colonne de 480, le titre tenait sur cinq lignes, « Votre » seul en
   tete, et les boutons passaient sous la ligne de flottaison en 1366x768. */
.hero-in{position:relative;z-index:4;
  display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);
  gap:clamp(30px,4vw,60px);align-items:start}
/* Le texte tient les deux rangees de la colonne gauche et se centre face a la
   scene : c'est la promesse qui doit etre a hauteur d'oeil, pas la mention. */
.hero-txt{grid-column:1;grid-row:1 / span 2;align-self:center}
/* La taille suit aussi la hauteur de la fenetre : sur un portable, la place
   manque en hauteur bien avant de manquer en largeur. */
.hero h1{font-size:clamp(40px,5.9vw,68px);font-size:clamp(40px,min(5.9vw,8.4svh),68px);
  max-width:15ch;margin-block:0 24px;text-wrap:balance;
  letter-spacing:-.035em;color:var(--papier)}
/* Ce que fait Dymad, avant la promesse. La voix « etiquette » du site, celle
   qui annonce le diagnostic : une information, pas un ornement. */
.hero-surtitre{display:block;margin-bottom:20px;color:var(--sur-encre-2)}
/* Sur telephone la ligne ne tient pas : elle se coupait en laissant « ET PME »
   seul. On la pose sur deux lignes voulues, le metier puis la cible. */
@media(max-width:560px){
  .surtitre-sep{display:none}
  .surtitre-cible{display:block;margin-top:5px}
}
/* Fenetre basse (portable 1366x768 : environ 650px utiles une fois le
   navigateur deduit) : le texte se cale en haut au lieu de se centrer face a
   la scene, pour que les boutons restent dans le premier ecran. */
@media(min-width:1001px) and (max-height:820px){
  .hero{padding-top:calc(var(--barre) + 40px)}
  .hero-txt{align-self:start}
}
/* Le mot qui fait basculer la phrase — « coute » — passe au turquoise. Une
   couleur pleine et non un degrade : un texte en degrade est le raccourci le
   plus reconnaissable de la decennie, et il ne survit ni a la selection ni au
   mode contraste force. Le degrade se depense sur les filets et les surfaces,
   ou il ne porte aucun texte. */
.hero h1 .fin{color:var(--accent-inv-2)}
.hero-p{font-size:20.5px;line-height:1.5;max-width:46ch;color:var(--sur-encre)}
.hero-p b{font-weight:400;color:var(--papier)}
.hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:34px}
/* Sur telephone, les boutons prennent toute la largeur : deux largeurs
   differentes calees a gauche faisaient hesiter l'oeil, et un bouton plein
   largeur se touche au pouce sans viser. */
@media(max-width:560px){
  .hero-cta .btn{flex:1 1 100%;justify-content:center}
}

/* La scene montre des chiffres : la page doit dire d'ou ils viennent. La
   mention appartient a la scene, elle se place donc sous elle, dans sa colonne. */
/* 12px et non 11 : c'est la phrase qui dit que ces chiffres sont un cas type.
   Elle doit se lire sans effort, sinon la scene passe pour une promesse. */
.hero-mention{grid-column:2;margin-top:clamp(16px,2vw,26px);
  font-family:var(--util);font-size:12px;letter-spacing:.04em;line-height:1.7;
  color:var(--sur-encre-3);max-width:48ch}
@media(max-width:1000px){.hero-mention{grid-column:1;max-width:56ch}}

/* ============ La scene d'instruments ============
   Ce que le visiteur voit : le tableau de bord que l'audit produit, pose dans
   l'espace. Les plaques sont du DOM, pas une image : le texte reste net, le
   contraste reste mesurable, et la scene se replie proprement en pile sur
   mobile. La profondeur vient de quatre choses — la perspective, le decalage
   sur l'axe Z, l'ombre portee, et le filet clair sur l'arete haute de chaque
   plaque. C'est ici, et seulement ici, que le verre est employe dans la page :
   il y a un relief anime derriere, donc quelque chose a laisser passer. */
.hero-scene{
  position:relative;z-index:4;
  perspective:1500px;perspective-origin:56% 44%;
  padding:clamp(20px,2.4vw,34px) 0;
}

/* La scene est une grille, pas un empilement d'absolus.
   Chaque plaque occupe une cellule, puis avance ou recule sur l'axe Z. C'est ce
   decalage — et lui seul — qui produit la profondeur : la perspective agrandit
   ce qui s'approche, l'ombre portee s'epaissit, la plaque qui recule pallit.
   Aucune plaque ne recouvre le texte d'une autre. Ce n'est pas une precaution :
   une donnee a moitie masquee ne se lit pas, et une scene qui pretend montrer
   des mesures doit d'abord les rendre lisibles. */
.scene{
  display:grid;
  grid-template-columns:minmax(0,184px) minmax(0,1fr);
  gap:13px clamp(13px,1.5vw,20px);
  align-items:start;
  transform-style:preserve-3d;
  transform:rotateX(var(--sx,6deg)) rotateY(var(--sy,-12deg));
}
/* La scene ne bouge qu'avec la souris : c'est la seulement qu'elle merite sa
   couche. Sur telephone elle est a plat, la couche ne servait a rien. */
@media(pointer:fine) and (min-width:641px){.scene{will-change:transform}}

.plaque{
  position:relative;
  background:rgba(17,24,50,.62);
  -webkit-backdrop-filter:var(--flou);backdrop-filter:var(--flou);
  border:1px solid var(--verre-bord);
  box-shadow:var(--z-nuit);transform-style:preserve-3d;
  padding:14px 15px 12px;color:var(--papier);
}
/* L'arete qui prend la lumiere. Un filet de 1px en haut, plus clair au centre :
   c'est ce qui fait lire la plaque comme une surface epaisse plutot que comme
   un rectangle transparent. */
.plaque::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--verre-haut) 30%,var(--verre-haut) 70%,transparent);
  pointer-events:none}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .plaque{background:rgba(17,24,50,.93)}
}

/* Le plan de reference : la courbe de trafic, la plus grande surface. */
.plaque-maitre{grid-column:2;grid-row:1 / span 2;transform:translateZ(30px)}

/* Les trois instruments de la colonne gauche, a trois distances differentes. */
.plaque-requetes {grid-column:1;grid-row:1;transform:translateZ(84px)}
.plaque-taux     {grid-column:1;grid-row:2;transform:translateZ(-52px)}
.plaque-entonnoir{grid-column:1;grid-row:3;transform:translateZ(58px)}

/* La notification est ce qui est arrive en dernier : c'est donc la plaque la
   plus proche, et la seule a sortir du cadre de la colonne. Le debord est
   recadre par le overflow du hero — aucune barre de defilement. */
.plaque-signal-1{grid-column:2;grid-row:3;justify-self:end;
  width:min(100%,272px);transform:translateZ(112px);
  margin-right:clamp(-72px,-4vw,-24px)}

/* Ce qui recule porte une ombre plus courte et un filet plus pale. La
   perspective l'a deja reduit : c'est suffisant pour dire la distance.
   On n'y touche PAS a l'opacite — une plaque qui montre un chiffre doit rester
   lisible, et un texte a 72 % d'opacite perd son contraste mesure. */
.plaque-loin{box-shadow:0 2px 6px rgba(0,0,0,.28);border-color:var(--ligne-inv-fine)}

.plaque-tete{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding-bottom:11px;border-bottom:1px solid var(--ligne-inv-fine)}
/* Le titre peut passer sur deux lignes ; la source, jamais. Une mention de
   provenance coupee en « MOIS / 6 » ne veut plus rien dire. */
.plaque-titre{font-family:var(--util);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--papier);line-height:1.45;min-width:0}
.plaque-src{font-family:var(--util);font-size:10px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sur-encre-3);line-height:1.45;
  white-space:nowrap;flex:none}

.plaque-chiffre{display:flex;align-items:baseline;gap:8px;padding-top:13px}
.plaque-val{font-family:var(--display);font-weight:700;font-size:clamp(28px,3vw,38px);
  line-height:1;letter-spacing:-.035em;color:var(--accent-inv-2)}
.plaque-unite{font-family:var(--util);font-size:11px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sur-encre-3);line-height:1.45}

/* ---- le graphe ---- */
.graphe{display:block;width:100%;height:auto;margin-top:14px}
.graphe-grille line{stroke:var(--ligne-inv-fine);stroke-width:1}
.graphe-axe{stroke:var(--ligne-inv);stroke-width:1}
/* L'aire sous la courbe est un degrade vertical qui s'eteint vers le bas :
   la courbe semble poser une ombre coloree sur le fond de la plaque. */
.graphe-aire{fill:url(#aire-spectre);opacity:0;transition:opacity 1s var(--ease) .55s}
.graphe-trait{fill:none;stroke:url(#trait-spectre);stroke-width:2.2;
  stroke-linejoin:round;stroke-linecap:round}
.graphe-noeuds rect{fill:var(--accent-inv-2);transform-box:fill-box;transform-origin:center;
  transform:scale(0)}
.graphe-cible{stroke:var(--ligne-inv);stroke-width:1;stroke-dasharray:3 4}

/* L'animation d'entree du graphe. Elle se joue une fois, quand la scene arrive.
   La classe est posee par le script : sans JavaScript, le graphe est deja
   dessine et lisible. */
.js .graphe-trait{stroke-dasharray:var(--long,900);stroke-dashoffset:var(--long,900)}
.js .scene.trace .graphe-trait{stroke-dashoffset:0;
  transition:stroke-dashoffset 1.5s cubic-bezier(.36,0,.16,1) .15s}
.js .scene.trace .graphe-aire{opacity:1}
.js .scene.trace .graphe-noeuds rect{transform:scale(1);
  transition:transform .5s var(--ease);transition-delay:var(--retard,0ms)}

/* Le pied du graphe porte trois reperes : deux extremites et un jalon. Le
   `justify-content:space-between` seul les collerait entre eux — chaque repere
   prend donc un tiers de la largeur et s'aligne sur sa propre extremite. */
.plaque-pied{display:grid;grid-template-columns:repeat(3,1fr);margin-top:9px;
  font-family:var(--util);font-size:10px;letter-spacing:.1em;line-height:1.5;
  text-transform:uppercase;color:var(--sur-encre-3)}
.plaque-pied span:nth-child(2){text-align:center}
.plaque-pied span:last-child{text-align:right}
/* Dans la colonne etroite (164px sous 1180px), « VISITES DEVIS CLIENTS » ne
   tenait pas et les trois mots se touchaient. L'espacement se resserre. */
.plaque-entonnoir .plaque-pied{letter-spacing:.03em;column-gap:4px}

/* ---- instrument : colonnes ---- */
.colonnes{display:flex;align-items:flex-end;gap:5px;height:46px;margin-top:13px}
.colonnes i{flex:1;background:var(--accent-inv);opacity:.34;height:var(--h);
  transform-origin:bottom;transform:scaleY(0)}
/* La derniere colonne est celle du mois en cours : elle passe au turquoise et
   monte au-dessus des autres d'un demi-pixel de filet. On distingue par la
   couleur et la position, pas par un halo. */
.colonnes i:last-child{opacity:1;background:var(--accent-inv-2)}
.js .scene.trace .colonnes i{transform:scaleY(1);
  transition:transform .7s var(--ease);transition-delay:var(--retard,0ms)}

/* ---- instrument : entonnoir ---- */
.entonnoir{list-style:none;margin:11px 0 0;padding:0}
.entonnoir li{display:grid;grid-template-columns:1fr auto;gap:10px;align-items:center;
  font-family:var(--util);font-size:10px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--sur-encre-2);padding-top:7px;padding-bottom:7px}
.entonnoir li + li{border-top:1px solid var(--ligne-inv-fine)}
.entonnoir span{position:relative;display:block;height:7px;background:rgba(255,255,255,.09)}
.entonnoir span::after{content:"";position:absolute;inset:0 auto 0 0;width:var(--w);
  background:var(--degrade-inv);transform-origin:left;transform:scaleX(0)}
.js .scene.trace .entonnoir span::after{transform:scaleX(1);
  transition:transform .85s var(--ease);transition-delay:var(--retard,0ms)}
.entonnoir b{font-weight:400;color:var(--papier);font-variant-numeric:tabular-nums}

/* ---- instrument : signal ---- */
.plaque-signal{display:flex;gap:12px;align-items:flex-start;padding:14px 16px}
.plaque-signal .lentille{width:13px;height:13px;color:var(--accent-inv-2);margin-top:3px;flex:none}
.plaque-signal .lentille path{fill:currentColor}
.plaque-signal b{display:block;font-family:var(--display);font-weight:500;font-size:14px;
  line-height:1.28;letter-spacing:-.01em;margin-bottom:3px;color:var(--papier)}
.plaque-signal span{font-family:var(--util);font-size:10px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sur-encre-3)}

/* ---- placement : rien a ajuster a la main ----
   Le placement est porte par la grille ci-dessus. Sous 1180px, seule la
   colonne gauche se resserre : les plaques restent aux memes distances. */
@media(max-width:1180px){
  .scene{grid-template-columns:minmax(0,164px) minmax(0,1fr)}
  .plaque-signal-1{width:min(100%,248px);margin-right:-18px}
}

/* ---- une colonne : la scene passe sous le texte ---- */
@media(max-width:1000px){
  .hero-in{grid-template-columns:1fr;gap:clamp(34px,6vw,52px)}
  .hero-txt{grid-column:1;grid-row:auto}
  .hero h1{max-width:20ch}
  .hero-p{max-width:54ch}
  .hero-scene{perspective:2100px;perspective-origin:50% 46%;max-width:620px}
  .plaque-signal-1{margin-right:0}
}

/* ---- mobile : la scene s'aplatit ----
   La perspective et le suivi de la souris n'ont aucun sens sans souris, et la
   grille a deux colonnes ne tient pas sur 360px. On garde trois instruments,
   empiles, a plat : la courbe, l'entonnoir, la notification. Le rendu reste le
   meme systeme — plaque de verre, filet clair, ombre portee. Le flou est retire
   sur telephone : sur un fond deja sombre il ne se voit pas, et il coute cher
   sur les GPU mobiles. */
@media(max-width:640px){
  .hero-scene{perspective:none;padding:0;max-width:none}
  /* stretch : sans lui la colonne heritait du align-items:start de la grille
     et chaque plaque prenait la largeur de son contenu (374, 223, 317px). */
  .scene{display:flex;flex-direction:column;align-items:stretch;gap:12px;transform:none !important}
  .plaque{transform:none !important;
    background:rgba(17,24,50,.9);
    -webkit-backdrop-filter:none;backdrop-filter:none;
    box-shadow:0 2px 6px rgba(0,0,0,.3) !important;
    border-color:var(--verre-bord) !important}
  .plaque-signal-1{width:auto;margin-right:0}
  /* Deux plaques de moins : sur un ecran de telephone, cinq surfaces empilees
     repoussent le bandeau des poles trop loin sous la ligne de flottaison. */
  .plaque-requetes,.plaque-taux{display:none}
  .plaque-val{font-size:34px}
}
/* Au doigt, la nappe du hero ne peut pas suivre un curseur : elle derive
   lentement d'un angle a l'autre, et rend au hero la vie que la 3D et le halo
   lui donnent a la souris. Une seule couche, en transform, qui s'arrete des
   que le hero quitte l'ecran (classe posee par le script). */
@media(hover:none){
  .hero-lueur{opacity:1;
    animation:lueur-entree 1.6s var(--ease) both,lueur-derive 18s ease-in-out 1.6s infinite alternate}
  .hero-lueur.hors-champ{animation-play-state:paused}
}
@keyframes lueur-entree{from{opacity:0}}
@keyframes lueur-derive{from{transform:translate3d(16%,-12%,0)}to{transform:translate3d(-14%,8%,0)}}

/* ================= BANDEAU DES 4 PÔLES =================
   La couture entre la nuit du hero et le papier des prestations. Le bandeau
   reste sur la nuit et porte le degrade du spectre sur son bord bas : c'est la
   ligne d'horizon de la page. */
.bandeau{background:var(--encre-2);color:var(--papier);
  padding-top:4px;padding-bottom:4px;position:relative;
  border-top:1px solid var(--ligne-inv-fine)}
.bandeau::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--degrade-filet-inv)}
/* Le rail tient sur UNE rangee : c'est ce qui le fait lire comme un sommaire
   et non comme une seconde navigation. Le nombre de colonnes suit donc le
   nombre de liens — en ajouter un sans toucher ce chiffre renvoie le dernier
   a la ligne, ou il recupere le filet et le retrait des colonnes suivantes. */
.bandeau-in{display:grid;grid-template-columns:repeat(5,1fr);gap:0}
.bandeau-in a{display:flex;align-items:center;gap:10px;padding:16px 16px;text-decoration:none;
  font-family:var(--etiq);font-size:13.5px;font-weight:500;letter-spacing:-.005em;
  color:var(--sur-encre-2);
  border-left:1px solid var(--ligne-inv-fine);transition:color .16s}
.bandeau-in a:first-child{border-left:none;padding-left:0}
@media(hover:hover){.bandeau-in a:hover{color:var(--papier)}}
.bandeau-in .lentille{width:10px;height:10px;color:var(--accent-inv-2)}
/* Sous 1024px, cinq colonnes cassent les libelles en deux lignes et le rail
   se met a ressembler a un second menu. On elargit donc les colonnes plutot
   que de laisser filer le texte. Les filets tombent en meme temps : un filet
   de colonne ne separe proprement que sur une rangee pleine, et a partir
   d'ici il y a un reste. */
@media(max-width:1024px){.bandeau-in{grid-template-columns:repeat(3,1fr)}
  .bandeau-in a{border-left:none;padding-left:0}}
@media(max-width:760px){.bandeau-in{grid-template-columns:repeat(2,1fr)}}

/* ---- en-tête de section ---- */
.sec{padding-top:clamp(58px,8vw,104px);padding-bottom:clamp(58px,8vw,104px)}
.sec-head{max-width:56ch;margin-bottom:44px}
.sec-head h2{font-size:clamp(28px,3.7vw,46px);margin-block:0 16px;letter-spacing:-.032em}
.sec-head p{color:var(--gris);font-size:17.5px;max-width:49ch}
/* Un titre pose directement dans sa section, sans chapeau : c'est le cas des
   tarifs et de la FAQ des pages metiers. Sans cette regle il tombait a la
   taille par defaut du navigateur, colle au bloc qui le suit. Meme echelle et
   meme respiration que les titres de rupture. */
.sec > h2{font-size:clamp(28px,3.7vw,46px);margin-block:0 clamp(26px,3vw,40px);
  max-width:21ch;letter-spacing:-.032em;text-wrap:balance}

/* ================= LES 4 PÔLES =================
   Quatre quadrants separes par des filets, sans arrondi ni carte flottante.
   Ce qui change avec la refonte : chaque pole porte en fond une nappe de
   lumiere qui ne se revele qu'au survol, et son filet de prix passe au degrade
   du spectre. La structure, elle, ne bouge pas — c'est elle qui dit « quatre
   metiers de meme rang ». */
.poles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0;
  border-top:1px solid var(--ligne)}
@media(max-width:840px){.poles{grid-template-columns:1fr}}
/* Les bandes de deux quadrants voisins s'alignent.
   Le filet de prix est la seule ligne coloree de la section : l'oeil la suit
   d'une colonne a l'autre, et vingt-six pixels d'ecart s'y voyaient. L'ecart
   venait des listes, dont le nombre de lignes depend de la longueur des
   textes — un mot de plus dans une puce decalait le filet d'en face. La
   sous-grille aligne les bandes sans qu'on ait a compter les lignes, donc
   sans que la mise en page depende de la redaction.
   Le span doit rester superieur ou egal au plus grand nombre d'enfants d'un
   quadrant : 4 depuis que l'accueil ne porte plus que la carte (titre,
   phrase, prix, lien). En ajouter un sans monter ce chiffre sortirait le
   dernier bloc de l'alignement. Le lien est pose sur la derniere rangee : les
   quatre liens tombent a la meme hauteur.
   Sous @supports : sans sous-grille, display:grid seul reorganiserait les
   quadrants pour rien. Sous 841px il n'y a qu'une colonne, donc rien a aligner. */
@supports (grid-template-rows:subgrid){
  @media(min-width:841px){
    .pole:not(.pole-transverse){display:grid;grid-template-rows:subgrid;
      grid-row:span 4}
    .pole:not(.pole-transverse) > .pole-lien{grid-row:4}
  }
}
.pole{border-bottom:1px solid var(--ligne);padding:clamp(28px,3.2vw,42px) 0;
  position:relative;isolation:isolate}
.pole:nth-child(odd){padding-right:clamp(20px,3vw,44px)}
.pole:nth-child(even){padding-left:clamp(20px,3vw,44px);border-left:1px solid var(--ligne)}
@media(max-width:840px){
  .pole:nth-child(odd),.pole:nth-child(even){padding-inline:0;border-left:none}
}
/* La nappe de lumiere du survol. Elle est posee derriere le contenu (z-index
   negatif dans le contexte isole) et depasse legerement du quadrant pour ne pas
   dessiner de rectangle net. */
.pole::before{content:"";position:absolute;inset:0 -14px;z-index:-1;
  background:radial-gradient(70% 60% at 12% 0%,rgba(35,72,198,.075),transparent 70%);
  opacity:0;transition:opacity var(--t-plan) var(--ease);pointer-events:none}
.pole h3{font-size:clamp(22px,2.4vw,29px);margin-bottom:12px;letter-spacing:-.028em}
.pole > p{color:var(--gris);max-width:44ch;margin-bottom:20px}
/* Deux paliers par offre, et non un plancher unique. Un « a partir de » seul
   ne dit pas au visiteur s'il est a 1 200 ou a 2 800 euros : il le laisse
   supposer le pire, ou demander un devis pour le savoir. La fourchette lui
   permet de se situer tout seul, ce qui est exactement ce que la page promet.
   Le filet degrade reste en tete du bloc entier et non de chaque palier : il
   annonce le prix, il ne le decoupe pas. */
.pole-prix{display:grid;gap:15px;
  padding-top:16px;position:relative}
.palier{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px}
/* Le nom du palier prend sa propre ligne. Cale sur la meme ligne de base que
   le montant, il entrait en concurrence avec lui alors qu'il ne fait que le
   nommer. */
.palier-nom{flex-basis:100%;font-family:var(--util);font-size:11px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--gris);
  margin-bottom:-4px}
/* Le filet du prix : 2px de degrade, pas un trait d'encre. C'est la ligne que
   l'oeil cherche dans un quadrant de prestation, elle a droit a la couleur. */
.pole-prix::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,var(--accent),rgba(63,207,192,.55))}
/* La taille descend de 29px a une echelle fluide : « 1 700 a 2 800 € » fait
   deux fois la longueur d'un plancher seul, et deux montants se suivent
   dans une colonne de demi-largeur. nowrap parce qu'un prix coupe en deux au
   milieu d'une fourchette ne se lit plus comme un prix. */
.pole-prix .montant{font-family:var(--display);font-weight:700;
  font-size:clamp(22px,2.3vw,27px);white-space:nowrap;
  letter-spacing:-.03em;color:var(--accent)}
.pole-prix .mention{font-family:var(--util);font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--gris-clair)}
/* Sur telephone, les etiquettes qui portent une information passent de 11 a
   12px, et les mentions de prix, parfois longues de trois lignes, quittent
   les capitales : une phrase en capitales monospace se dechiffre, elle ne se
   lit pas. */
@media(max-width:640px){
  .palier-nom,.cas-serv li,.chaine h4,.moi-role,.r-pole{font-size:12px}
  .pole-prix .mention{text-transform:none;letter-spacing:.02em;font-size:12.5px;line-height:1.5}
}

/* Le pole transversal.
   L'automatisation n'est pas un cinquieme metier de meme rang que les quatre
   autres : c'est la couche qui les fait tourner. La geometrie le dit avant le
   texte — une bande pleine largeur posee SOUS les quatre quadrants, et non un
   cinquieme quadrant qui laisserait la grille bancale et casserait le motif a
   quatre que porte toute la page (le sceau, la convergence, les titres).
   Le filet degrade en tete reprend celui des prix : c'est le seul endroit du
   site ou la couleur signale un changement de rang. */
/* Ce que le palier contient. Sans elle, deux prix se suivaient sans que rien
   ne dise ce que le second achetait de plus : le lecteur voyait « 1 200 a
   1 700 » puis « 1 700 a 2 800 » et devait deviner. Le contenu est ecrit en
   bas de casse et non dans la mention en petites capitales — c'est une phrase
   a lire, pas une etiquette a scanner. */
/* La ligne occupe toute la largeur du palier (flex-basis), sinon, sur la
   pleine largeur des pages metiers, elle remontait a droite du prix. La mesure
   de lecture reste tenue a 54ch par la marge interieure, et non par un
   max-width : celui-ci plafonnait la base et la laissait remonter. */
.palier-compris{flex-basis:100%;margin-top:1px;
  font-size:13.5px;line-height:1.5;color:var(--gris-clair);
  padding-inline-end:max(0px, 100% - 54ch)}

/* La mention fiscale. Elle ne peut pas vivre seulement dans les mentions
   legales : c'est ici, sous les montants, que le lecteur decide s'il ajoute
   vingt pour cent dans sa tete. En franchise de TVA le prix affiche EST le
   prix facture — l'ecrire est un argument, pas une contrainte. « HT » dirait
   l'inverse : que la taxe s'ajoute, et qu'elle est recuperable. */
.poles-tva{margin-top:clamp(26px,3vw,40px);padding-top:18px;
  border-top:1px solid var(--ligne-fine);
  font-size:14px;line-height:1.55;color:var(--gris-clair);max-width:58ch}
.poles-tva b{font-weight:600;color:var(--gris)}

/* Ce qui fait varier le prix. Une fourchette sans ses variables laisse le
   visiteur supposer le haut de la fourchette ; avec elles, il se place
   lui-meme. C'est la ligne qui remplace le devis a demander. */
.pole-varie{margin-top:13px;font-size:14px;line-height:1.55;
  color:var(--gris-clair);max-width:58ch}
.pole-varie b{font-weight:600;color:var(--gris)}

/* La mention des abonnements. Le filet de prix dit ce que nous facturons ;
   cette ligne dit ce qui reste a la charge du client — avant la signature, et
   non apres. C'est la meme promesse que le refus « Garder vos acces pour
   nous » : les outils sont a son nom, donc ils sont sur sa facture. Un prix
   affiche seul se lit « tout compris », et la surprise arriverait exactement
   la ou la page promet qu'il n'y en a pas. */
.pole-note{margin-top:14px;font-size:14px;line-height:1.55;
  color:var(--gris-clair);max-width:58ch}

/* Le lien vers la page du metier, en pied de quadrant : la voix des actions du
   site, la couleur du prix, et une fleche qui avance au survol. On lit le
   quadrant, on sait ou aller pour en savoir plus. */
.pole-lien{display:inline-flex;align-items:center;gap:9px;margin-top:22px;
  justify-self:start;align-self:start;padding-block:10px;
  font-family:var(--etiq);font-size:14.5px;font-weight:500;letter-spacing:-.005em;
  color:var(--accent);text-decoration:none;transition:color var(--t-tact) var(--ease)}
.fleche{width:14px;height:10px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;transition:transform var(--t-etat) var(--ease)}
@media(hover:hover){
  .pole-lien:hover{color:var(--accent-vif)}
  .pole-lien:hover .fleche,.pole:hover .pole-lien .fleche{transform:translate3d(3px,0,0)}
}

/* ---- la carte de l'accueil ----
   L'accueil ne porte plus que la carte de chaque pole : ce qu'il fait, ses
   deux paliers, le lien vers sa page. Ce que contient chaque palier, les
   delais et ce qui fait varier le prix vivent sur cette page, mot pour mot.
   Sur ordinateur les deux paliers se lisent cote a cote : deux prix se
   comparent en travers, pas en descendant. La mention qui vaut pour les deux
   (sans engagement) court sous les deux. */
/* Le telephone garde les deux colonnes des 375px : empiles, deux paliers
   prenaient la hauteur d'un ecran sur cinq cartes. Le montant descend d'un
   cran pour qu'« A partir de 4 500 € » tienne dans une demi-colonne sans
   passer a la ligne. En dessous de 375px, un palier par ligne. */
@media(min-width:375px){
  .poles .pole-prix{grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:clamp(14px,2.2vw,30px);align-content:start}
  .poles .pole-prix > .mention{grid-column:1 / -1}
}
.poles .palier{align-content:flex-start}
.poles .pole-prix .montant{font-size:clamp(19px,1.7vw,24px)}
@media(max-width:840px){
  .pole{padding-block:24px}
  .pole > p{margin-bottom:16px}
  .poles .palier{gap:4px 8px}
  .poles .palier-nom{margin-bottom:0}
  .pole-lien{margin-top:12px}
}

.pole-transverse{grid-column:1 / -1;border-left:none}
.poles .pole-transverse:nth-child(odd){padding-right:0}
.pole-transverse::after{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;
  background:linear-gradient(90deg,var(--accent),rgba(63,207,192,.55))}
/* Pleine largeur, la carte transversale se lit en deux colonnes : le titre et
   la phrase a gauche, les prix et le lien a droite, a la mesure des quadrants
   du dessus. Sur une colonne, le filet de tete reste : c'est lui qui dit,
   avant le texte, que l'automatisation n'est pas un cinquieme quadrant. */
@media(min-width:841px){
  .pole-transverse{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:"titre prix" "texte prix" "texte lien";
    grid-template-rows:auto auto 1fr;column-gap:clamp(20px,3vw,44px);align-items:start}
  .pole-transverse > h3{grid-area:titre}
  .pole-transverse > p{grid-area:texte;margin-bottom:0}
  .pole-transverse > .pole-prix{grid-area:prix}
  .pole-transverse > .pole-lien{grid-area:lien}
}

/* ============ RÉALISATIONS ============
   Trois projets cote a cote, la maquette au-dessus du texte. L'accueil les
   racontait en trois rangees pleine largeur, soit deux ecrans ; en triptyque
   ils en tiennent un. Pas de cartes pour autant : des filets verticaux, comme
   entre les quadrants des poles, et aucune boite — trois colonnes d'un meme
   journal, pas trois vignettes de catalogue. L'inclinaison des maquettes
   alterne d'une colonne a l'autre : c'est ce qui reste de l'ancienne
   alternance gauche/droite.

   Les maquettes reutilisent exactement le vocabulaire du hero : surface
   blanche, filet 1px, ombre portee de l'echelle --z. Rien de nouveau n'est
   invente ici, et c'est voulu — la page doit sembler avoir toujours ete ainsi. */

.cas{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-template-rows:auto auto;
  border-top:1px solid var(--ligne);border-bottom:1px solid var(--ligne)}
/* Chaque projet prend deux rangees de la grille commune (sous-grille) : les
   trois maquettes ont la meme hauteur, et les trois textes partent de la
   meme ligne, quelle que soit la maquette. La maquette passe au-dessus du
   texte a l'ecran, jamais dans le document : au clavier et au lecteur
   d'ecran, le projet se lit texte d'abord. */
.cas > article{display:grid;grid-row:span 2;grid-template-rows:subgrid;row-gap:0;
  /* minmax(0,…) : la barre d'ecran ne passe pas a la ligne, et une piste
     « auto » l'aurait laissee elargir la colonne au-dela de son filet. */
  grid-template-columns:minmax(0,1fr);
  padding:clamp(30px,3.4vw,46px) clamp(18px,2.2vw,32px) clamp(30px,3.4vw,44px);
  border-left:1px solid var(--ligne)}
.cas > article:first-child{border-left:none;padding-left:0}
.cas > article:last-child{padding-right:0}
.cas > article > .cas-vue{grid-row:1;margin-bottom:clamp(28px,3vw,40px);
  display:flex;flex-direction:column}
.cas > article > .cas-txt{grid-row:2}
.cas .cas-scene{flex:1;display:flex;flex-direction:column}
.cas .ecran{flex:1}
.cas-txt > :last-child{margin-bottom:0}

.cas-num{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;margin-bottom:16px}
.cas-num b{white-space:nowrap}
.cas-num b{font-family:var(--util);font-size:12px;font-weight:400;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent)}
.cas-num span{font-family:var(--util);font-size:12px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gris-clair)}
.cas-txt h3{font-size:clamp(21px,1.9vw,26px);margin-bottom:12px;letter-spacing:-.028em}
.cas-txt > p{color:var(--gris);max-width:42ch;margin-bottom:20px}

/* Les services : des filets, pas des pastilles. Une etiquette arrondie serait
   le premier arrondi du site. */
.cas-serv{list-style:none;margin:0 0 22px;padding:0;display:flex;flex-wrap:wrap;gap:0}
.cas-serv li{font-family:var(--util);font-size:11px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--gris);
  padding:7px 14px;border:1px solid var(--ligne);margin-right:-1px;margin-bottom:-1px;
  transition:color var(--t-tact) var(--ease),border-color var(--t-tact) var(--ease),
             background var(--t-tact) var(--ease)}
@media(hover:hover){.cas > article:hover .cas-serv li{border-color:rgba(35,72,198,.22)}}

/* --- Zone resultats ---
   Aucun article ne porte ce bloc pour l'instant : tant qu'un projet n'a pas de
   mesure verifiable, la liste des services suffit, et un « +XX % » laisse en
   place se lirait comme une promesse creuse. Les regles restent ici, pretes a
   servir des qu'un chiffre reel existe.

   Grille et non flex : trois colonnes egales restent alignees, la ou un flex
   renvoyait le troisieme chiffre a la ligne avec un decalage. */
.cas-chiffres{display:grid;grid-template-columns:repeat(auto-fit,minmax(108px,1fr));
  border-top:1px solid var(--ligne)}
.cas-chiffres > div{padding:14px 18px 0 0}
.cas-chiffres > div + div{border-left:1px solid var(--ligne-fine);padding-left:18px}
.cas-chiffres b{display:block;font-family:var(--display);font-weight:700;
  font-size:clamp(20px,2.1vw,25px);letter-spacing:-.025em;color:var(--accent);
  font-variant-numeric:tabular-nums;line-height:1.1}
/* Un placeholder doit se voir comme tel, y compris a l'ecran. */
.cas-chiffres b[data-vide]{color:var(--gris-clair)}
.cas-chiffres span{font-family:var(--util);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gris-clair);line-height:1.5;display:block;margin-top:5px}

/* ---- la maquette ----
   Trois plans : l'ecran large au fond, l'ecran de telephone devant a gauche, un
   fragment d'interface qui avance encore. Les distances sont les memes que dans
   le hero (30 / 84 / 112px) : un seul systeme de profondeur pour tout le site.

   Les ecrans sont sombres. Deux raisons : une maquette blanche sur un fond
   papier ne se detache pas et il faut un cadre pour la faire exister, alors
   qu'un ecran de nuit se lit immediatement comme un ecran ; et cela rattache
   les realisations au hero, ou le meme vocabulaire est deja pose. */
.cas-vue{position:relative;perspective:1600px;perspective-origin:52% 46%}
.cas-scene{position:relative;transform-style:preserve-3d;
  transform:rotateX(var(--sx,4deg)) rotateY(var(--sy,-9deg));
  transition:transform var(--t-plan) var(--ease)}
@media(hover:hover) and (min-width:941px){.cas-scene{will-change:transform}}
.cas > article:nth-child(even) .cas-scene{
  transform:rotateX(var(--sx,4deg)) rotateY(var(--sy,9deg))}

.ecran{background:var(--encre-2);border:1px solid rgba(255,255,255,.09);
  box-shadow:var(--z3);transform:translateZ(30px);padding:0;overflow:hidden;
  position:relative}
/* Meme arete lumineuse que les plaques du hero : un seul systeme de surface. */
.ecran::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:3;
  background:linear-gradient(90deg,transparent,var(--verre-haut) 30%,var(--verre-haut) 70%,transparent);
  pointer-events:none}
/* La barre de l'ecran : trois filets, pas trois ronds de couleur. Le site n'a
   ni arrondi ni feu tricolore. */
.ecran-barre{display:flex;align-items:center;gap:14px;
  padding:10px 13px;border-bottom:1px solid var(--ligne-inv-fine);
  background:rgba(255,255,255,.04)}
.ecran-barre i{width:13px;height:1px;background:var(--sur-encre-3);flex:none}
.ecran-barre span{font-family:var(--util);font-size:10px;letter-spacing:.08em;
  color:var(--sur-encre-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ecran-corps{padding:clamp(14px,1.6vw,20px);position:relative}

/* Le contenu des maquettes est abstrait : des filets de longueurs variables.
   Un faux texte lisible obligerait a inventer le contenu d'un client. */
.faux{display:grid;gap:7px}
.faux i{display:block;height:7px;background:rgba(255,255,255,.1)}
.faux i.fort{height:15px;background:rgba(255,255,255,.2)}
.faux i.accent{background:var(--degrade-inv);opacity:.85}
.faux-grille{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-top:13px}
.faux-grille div{aspect-ratio:4/3;background:rgba(255,255,255,.055);
  border:1px solid var(--ligne-inv-fine)}

.tel{position:absolute;bottom:-26px;left:-34px;width:min(27%,132px);
  background:var(--encre-3);border:1px solid rgba(255,255,255,.11);box-shadow:var(--z-nuit);
  transform:translateZ(84px);padding:10px 9px}
.cas > article:nth-child(even) .tel{left:auto;right:-34px}
.tel-encoche{width:26px;height:2px;background:rgba(255,255,255,.22);margin:0 auto 10px}

/* Le fragment qui avance le plus : il nomme le levier du projet, pas un chiffre.
   Un indicateur chiffre reviendra ici quand il sera mesure ; en attendant, un
   libelle tient la profondeur sans rien promettre. */
.fragment{position:absolute;top:-24px;right:-30px;
  background:var(--blanc);border:1px solid var(--ligne);box-shadow:var(--z2);
  transform:translateZ(112px);padding:12px 15px;max-width:200px}
.cas > article:nth-child(even) .fragment{right:auto;left:-30px}
.fragment span{display:block;font-family:var(--util);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gris-clair);margin-bottom:5px}
.fragment b{display:block;
  font-family:var(--display);font-weight:700;font-size:17px;line-height:1.25;
  letter-spacing:-.02em;color:var(--accent)}

/* ---- en colonne : deux plans au lieu de trois ----
   Dans un tiers de largeur, le telephone pose en debord mordait sur la
   colonne voisine : il quitte la scene. Le fragment reste, rentre dans le
   cadre en bas de l'ecran, parce qu'il nomme le levier du projet. */
.cas .tel{display:none}
.cas .fragment,.cas > article:nth-child(even) .fragment{top:auto;bottom:-18px;
  left:auto;right:-10px;transform:translateZ(64px);padding:10px 13px}
.cas-scene{margin-right:10px}

/* ---- sous 900px : la bande qui defile au doigt ----
   Trois colonnes n'y tiennent plus, et trois rangees empilees coutaient deux
   ecrans. Les projets passent en bande horizontale : chacun occupe les quatre
   cinquiemes de la largeur, le suivant depasse du bord — c'est ce qui dit
   qu'il y en a d'autres, sans fleche ni pastille. La bande court jusqu'aux
   bords de l'ecran ; sa marge interieure garde l'alignement du texte, et le
   pseudo-element de fin rend la meme marge apres le dernier projet (Safari
   n'en compte aucune dans une zone qui defile).
   Les plans s'aplatissent : un ecran de telephone dessine sur un ecran de
   telephone ne dit rien, reste la maquette large, a plat. */
@media(max-width:899px){
  .cas{grid-template-columns:repeat(3,min(82%,400px));grid-auto-flow:column;
    grid-auto-columns:max(1px,calc(var(--g) - 16px));column-gap:16px;
    overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;
    scroll-padding-inline:var(--g);scroll-behavior:smooth;
    margin-inline:calc(var(--g) * -1);padding:0 var(--g) 6px;
    border:none;scrollbar-width:thin;scrollbar-color:var(--ligne) transparent}
  .cas::after{content:""}
  .cas:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .cas > article,.cas > article:first-child,.cas > article:last-child{
    scroll-snap-align:start;padding:18px 0 0;border-left:none;
    border-top:1px solid var(--ligne)}
  .cas > article > .cas-vue{margin-bottom:18px}
  .cas-vue{perspective:none}
  .cas-scene,.cas > article:nth-child(even) .cas-scene{transform:none !important;margin:0}
  .ecran{transform:none;box-shadow:var(--z2)}
  .cas .fragment{display:none}
  .cas-txt > p{max-width:none}
}
@media(max-width:640px){
  .cas-chiffres > div{padding-right:14px}
  .cas-chiffres > div + div{padding-left:14px}
}

/* ============ ZONES DE PREUVE ============
   Trois emplacements prets a recevoir de vraies preuves. Ils sont volontairement
   VIDES : un logo invente ou un temoignage fabrique detruirait exactement la
   credibilite qu'ils sont censes construire.

   Chaque bloc porte l'attribut [hidden] et ne s'affiche donc pas. Pour en
   activer un : retirer `hidden` de la balise et remplir le contenu. */
.preuves{border-top:1px solid var(--ligne);padding-top:clamp(26px,3vw,38px);
  margin-top:clamp(30px,4vw,52px)}
.preuves > .eyebrow{display:block;margin-bottom:18px}

/* Logos clients : hauteur commune, filet de separation, teinte encre.
   Les logos fournis doivent etre des SVG monochromes pour rester dans le
   systeme — un logo en couleur introduirait des teintes etrangeres. */
.logos{display:flex;flex-wrap:wrap;align-items:center;gap:0;list-style:none;margin:0;padding:0}
.logos li{padding:14px clamp(18px,2.4vw,32px);border-left:1px solid var(--ligne-fine)}
.logos li:first-child{border-left:none;padding-left:0}
.logos img,.logos svg{display:block;height:26px;width:auto;
  filter:grayscale(1);opacity:.72;transition:opacity var(--t-etat) var(--ease)}
@media(hover:hover){.logos li:hover img,.logos li:hover svg{opacity:1}}

/* Temoignages : une citation editoriale, pas une bulle. */
.temoins{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:0;border-top:1px solid var(--ligne)}
.temoins blockquote{margin:0;padding:clamp(20px,2.4vw,30px) clamp(20px,2.4vw,30px) clamp(20px,2.4vw,30px) 0;
  border-bottom:1px solid var(--ligne)}
.temoins blockquote + blockquote{border-left:1px solid var(--ligne);
  padding-left:clamp(20px,2.4vw,30px)}
.temoins p{font-family:var(--display);font-weight:500;font-size:clamp(17px,1.7vw,20px);
  line-height:1.4;letter-spacing:-.015em;margin-bottom:14px}
.temoins footer{border:none;padding:0;font-family:var(--util);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--gris-clair)}

/* Chiffres cles : la meme mecanique de compteur que le hero.
   Ajouter data-compteur="<valeur>" pour que le chiffre monte a l'arrivee. */
.cles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:0;border-top:1px solid var(--ligne);list-style:none;margin:0;padding:0}
.cles li{padding:clamp(18px,2.2vw,26px) 22px clamp(18px,2.2vw,26px) 0;
  border-bottom:1px solid var(--ligne)}
.cles li + li{border-left:1px solid var(--ligne-fine);padding-left:22px}
.cles b{display:block;font-family:var(--display);font-weight:700;
  font-size:clamp(27px,3.2vw,38px);letter-spacing:-.03em;line-height:1;
  color:var(--accent);font-variant-numeric:tabular-nums;margin-bottom:8px}
.cles span{font-family:var(--util);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gris-clair);line-height:1.5}

/* ================= L'AUDIT =================
   Le moment le plus fort de la moitie basse : fond de nuit, une nappe de
   lumiere dans l'angle haut droit, et les quatre livrables presentes comme des
   lignes d'un bordereau. Le titre monte a l'echelle du hero — c'est la seconde
   promesse de la page, elle a droit au meme poids. */
/* L'audit vit desormais dans le bloc de la demande (.contact) : sa nuit, sa
   couture et sa grille propres sont parties avec son ancienne section. Restent
   la promesse, la note et la lentille de fond. */
.audit-p{color:var(--sur-encre);max-width:44ch;margin-bottom:28px;font-size:17.5px}
.audit-note{font-family:var(--util);font-size:12px;color:var(--sur-encre-3);
  margin-top:18px;letter-spacing:.04em;line-height:1.7}

/* Les quatre livrables. Le bloc entier est une surface de verre : c'est le
   document qu'on remet, il doit se lire comme un objet pose sur la nuit. */
.livrable{list-style:none;margin:0;padding:0;counter-reset:liv;
  background:var(--verre);border:1px solid var(--verre-bord);
  -webkit-backdrop-filter:var(--flou);backdrop-filter:var(--flou);
  position:relative}
.livrable::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--verre-haut) 30%,var(--verre-haut) 70%,transparent)}
.livrable li{counter-increment:liv;display:flex;gap:16px;
  padding:18px clamp(18px,2.2vw,26px);
  border-top:1px solid var(--ligne-inv-fine);
  transition:background var(--t-etat) var(--ease)}
.livrable li:first-child{border-top:none}
.livrable li::before{content:counter(liv,decimal-leading-zero);
  font-family:var(--util);font-size:12px;color:var(--sur-encre-3);flex:none;padding-top:4px;
  transition:color var(--t-etat) var(--ease)}
.livrable li > div{min-width:0}
.livrable b{display:block;font-family:var(--display);font-weight:500;font-size:20px;
  line-height:1.3;margin-bottom:5px;letter-spacing:-.02em}
.livrable span{color:var(--sur-encre-2);line-height:1.58}
/* Le survol confirme la ligne lue, rien de plus : le fond s'eclaire d'un cran
   et l'index passe au turquoise. Aucun deplacement — on lit, on ne clique pas. */
@media(hover:hover){
  .livrable li:hover{background:var(--voile-inv)}
  .livrable li:hover::before{color:var(--accent-inv-2)}
}
/* Une ligne qui porte sa lentille n'a pas besoin de son numero : les pages
   metiers emploient la liste pour des arguments, pas pour une sequence. Un seul
   repere par ligne, pas deux. */
.livrable li:has(> .lentille)::before{content:none}
.livrable li > .lentille{width:9px;height:9px;margin-top:9px;color:var(--accent-inv-2)}
.livrable li > .lentille path{fill:currentColor}

/* La meme liste posee sur le papier : le premier bloc des pages metiers. Le
   verre n'a rien a laisser passer sur un fond clair, et le gris de nuit y
   tombait a 2:1. La surface devient la feuille blanche du diagnostic, avec son
   filet de spectre en tete, et le texte reprend les gris du papier. */
/* Le bloc de l'audit porte .sec mais reste sur la nuit : il garde le verre. */
.sec:not(.fond-encre, .contact) .livrable{background:var(--blanc);border-color:var(--ligne);
  -webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:var(--z2)}
.sec:not(.fond-encre, .contact) .livrable::before{height:2px;background:var(--degrade-filet)}
.sec:not(.fond-encre, .contact) .livrable li{border-top-color:var(--ligne-fine)}
.sec:not(.fond-encre, .contact) .livrable span{color:var(--gris)}
.sec:not(.fond-encre, .contact) .livrable li > .lentille{color:var(--accent)}
@media(hover:hover){
  .sec:not(.fond-encre, .contact) .livrable li:hover{background:var(--papier)}
}
.audit-lentille{position:absolute;left:calc(var(--g) * -1);bottom:-28%;width:min(40vw,430px);
  color:var(--accent-inv);opacity:.1;z-index:1;pointer-events:none}
.audit-lentille path{fill:none;stroke:currentColor;stroke-width:5;stroke-linecap:round}
@media(max-width:860px){.audit-lentille{display:none}}

/* ---- diagnostic ---- */
.diag-grid{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.3fr);gap:clamp(18px,3vw,40px);align-items:start}
@media(max-width:920px){.diag-grid{grid-template-columns:1fr}}
/* Sur ordinateur, la question et les six phrases font une seule colonne ; le
   plan d'action occupe la droite des le titre. Pose sous les phrases, il
   laissait vide la moitie droite du chapeau et allongeait la section d'un
   tiers d'ecran. La grille interieure s'efface (display:contents) : les
   phrases et le panneau se placent dans celle de la section. */
@media(min-width:921px){
  #diagnostic{display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.3fr);
    grid-template-rows:auto 1fr;column-gap:clamp(18px,3vw,40px);align-items:start}
  #diagnostic > .sec-head{grid-column:1;grid-row:1;margin-bottom:30px}
  #diagnostic > .diag-grid{display:contents}
  #diagnostic .choix{grid-column:1;grid-row:2}
  #diagnostic .reponse{grid-column:2;grid-row:1 / span 2}
}
.choix{display:flex;flex-direction:column}
.choix button{
  all:unset;box-sizing:border-box;cursor:pointer;display:flex;gap:14px;align-items:center;
  padding:18px 18px;border:1px solid var(--ligne);margin-bottom:-1px;
  font-family:var(--display);font-size:16.5px;font-weight:400;line-height:1.32;color:var(--gris);
  background:var(--blanc);position:relative;
  transition:background .16s,color .16s,border-color .16s;
}
@media(hover:hover){.choix button:hover{color:var(--encre);background:var(--papier-2)}}
/* `all:unset` efface aussi l'anneau de focus du site : on le rend, trace a
   l'interieur du bouton pour que le voisin, qui chevauche d'un pixel, ne le
   masque pas. */
.choix button:focus-visible{outline:2px solid var(--accent);outline-offset:-4px}
.choix button[aria-selected="true"]:focus-visible{outline-color:var(--accent-inv)}
/* La situation retenue passe a la nuit et porte le degrade sur son bord gauche :
   c'est l'onglet actif d'un tableau de bord, pas un bouton coche. */
.choix button[aria-selected="true"]{background:var(--encre);color:var(--papier);
  border-color:var(--encre);position:relative;z-index:2;box-shadow:var(--z2)}
.choix button[aria-selected="true"]::after{content:"";position:absolute;
  left:0;top:0;bottom:0;width:3px;background:var(--degrade-inv)}
.choix button .lentille{width:15px;height:15px}
.choix button[aria-selected="true"] .lentille{color:var(--accent-inv-2)}
.choix button[aria-selected="true"] .lentille path{fill:currentColor}
/* Sur telephone, les six phrases se resserrent : ce sont des choix, pas des
   paragraphes. Le panneau reste masque tant que rien n'est choisi. */
@media(max-width:920px){
  .choix button{padding:14px 16px;font-size:16px;line-height:1.3}
}
.reponse[hidden]{display:none}

.reponse{border:1px solid var(--ligne);padding:clamp(24px,3.2vw,38px);background:var(--blanc);
  min-height:430px;position:relative}
/* Le panneau est le resultat : son arete haute porte le degrade, comme la
   plaque maitresse du hero porte la sienne. */
.reponse::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:var(--degrade-filet)}
.reponse h3{font-size:clamp(22px,2.3vw,29px);margin-bottom:26px;max-width:26ch;
  letter-spacing:-.028em}

/* ============ LA CHAÎNE DU DIAGNOSTIC ============
   Quatre maillons dans l'ordre ou le travail se fait : le probleme constate,
   l'intervention, ce qu'on mesure, ce qu'on cherche a obtenir. C'est la
   methode Dymad rendue visible, pas une decoration.

   La construction : un filet vertical relie les maillons et se dessine de haut
   en bas ; chaque maillon apparait ensuite, dans l'ordre. L'animation est
   lineaire pour le trace (une ligne se tire a vitesse constante) et posee pour
   les blocs. Aucun rebond.

   Le trace est en scaleY sur un pseudo-element : aucune propriete de mise en
   page n'est animee, donc aucun recalcul par image. */
.chaine{list-style:none;margin:0;padding:0;position:relative;counter-reset:maillon}

/* le rail : un seul filet continu, du premier au dernier maillon. Il porte le
   degrade du spectre : le regard descend du bleu vers le turquoise, c'est-a-dire
   du probleme constate vers le resultat recherche. */
.chaine::before{content:"";position:absolute;left:11px;top:6px;bottom:14px;width:1px;
  background:linear-gradient(180deg,var(--accent),rgba(63,207,192,.6));
  transform-origin:top;transform:scaleY(0)}
.js .chaine.tire::before{transform:scaleY(1);transition:transform 1s linear}
@media(prefers-reduced-motion:reduce){
  .chaine::before{transform:scaleY(1) !important;transition:none !important}
}

.chaine > li{counter-increment:maillon;position:relative;
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 18px;
  padding-bottom:24px}
.chaine > li:last-child{padding-bottom:0}

/* La pastille du maillon : un carre de 5px sur le rail. Le site n'a pas
   d'arrondi, donc le point d'ancrage est carre lui aussi. */
.chaine > li::before{content:"";grid-row:1 / span 4;align-self:start;
  width:5px;height:5px;margin-left:9px;margin-top:6px;
  background:var(--accent);outline:4px solid var(--blanc);
  transition:background var(--t-etat) var(--ease)}
/* Le dernier maillon est le resultat : sa pastille passe au turquoise sombre et
   double de largeur. Le changement de forme suffit — pas besoin d'un halo. */
.chaine > li:last-child::before{background:var(--accent-fin);width:9px;margin-left:7px}

.chaine-num{grid-column:2;font-family:var(--util);font-size:11px;letter-spacing:.14em;
  color:var(--gris-clair);margin-bottom:4px;display:block}
.chaine-num b{font-weight:400;color:var(--accent)}
.chaine h4{grid-column:2;margin:0 0 6px;font-family:var(--util);font-weight:400;
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--encre)}
.chaine p{grid-column:2;color:var(--gris);font-size:15.5px;line-height:1.56;max-width:48ch}
.chaine p + p{margin-top:8px}

/* Les trois actions de l'intervention : une liste en filets, comme partout
   ailleurs sur le site. */
.chaine-actions{grid-column:2;list-style:none;margin:0;padding:0}
.chaine-actions li{position:relative;padding-left:15px;padding-top:5px;padding-bottom:5px;
  color:var(--gris);font-size:15.5px;line-height:1.5;max-width:48ch}
.chaine-actions li::before{content:"";position:absolute;left:0;top:.72em;
  width:6px;height:1px;background:var(--accent)}

/* Le dernier maillon porte le resultat recherche : c'est la seule ligne de la
   chaine qui merite l'accent, parce que c'est celle que le client verifiera. */
.chaine > li:last-child h4{color:var(--accent-fin)}

/* Apparition des maillons, en cascade. Masque sous .js uniquement : sans
   JavaScript, la chaine est entierement lisible d'emblee. */
.js .chaine > li{opacity:0;transform:translate3d(0,10px,0)}
.js .chaine.tire > li{opacity:1;transform:none;
  transition:opacity var(--t-plan) var(--ease),transform var(--t-plan) var(--ease);
  transition-delay:calc(var(--rang,0) * 130ms + 200ms)}
@media(prefers-reduced-motion:reduce){
  .js .chaine > li,.js .chaine.tire > li{
    opacity:1 !important;transform:none !important;transition:none !important}
}

/* Le pied du panneau : le pole concerne, et l'action. Le bouton arrive quand
   la chaine a fini de se construire : il en est la conclusion, pas un
   bandeau publicitaire pose avant la lecture. */
.r-pied{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:16px 20px;margin-top:26px;padding-top:18px;border-top:1px solid var(--ligne-fine)}
.js .reponse .r-pied{opacity:0;transform:translate3d(0,6px,0)}
.js .reponse .chaine.tire ~ .r-pied{opacity:1;transform:none;
  transition:opacity var(--t-plan) var(--ease) 700ms,transform var(--t-plan) var(--ease) 700ms}
.reponse{scroll-margin-top:calc(var(--barre) + 14px)}
.r-pole{display:inline-flex;align-items:center;gap:8px;
  font-family:var(--util);font-size:11px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--gris-clair)}
/* Le pole nomme mene a sa carte, plus bas : un lien discret, souligne d'un
   filet, qui passe a l'accent au survol comme les liens de pied de quadrant. */
a.r-pole{color:var(--gris);text-decoration:underline;text-decoration-color:var(--ligne);
  text-underline-offset:5px;padding-block:8px;
  transition:color var(--t-tact) var(--ease),text-decoration-color var(--t-tact) var(--ease)}
@media(hover:hover){a.r-pole:hover{color:var(--accent);text-decoration-color:currentColor}}
.r-pole .lentille{width:9px;height:9px;color:var(--accent)}
.r-pole .lentille path{fill:currentColor}

.fade{animation:fade var(--t-plan) var(--ease)}

/* ============ LA TRANSITION SIGNATURE ============
   Le seul moment vraiment mis en scene de toute la page, et il ne se joue
   qu'une fois : quatre mots — les quatre metiers — se rapprochent jusqu'a se
   ranger autour du symbole de la marque. Ce que ca dit : les quatre chantiers
   n'avancent pas separement, ils convergent.

   La section est sur la nuit, et c'est la seule ou la nuit ne sert pas a
   presenter une offre mais a faire le vide : il n'y a rien d'autre a l'ecran
   pendant la sequence, donc rien qui puisse la concurrencer.

   Mecanique. La section mesure 160svh, son contenu est en position:sticky sur
   100svh : la sequence utile tient en six dixiemes d'ecran de defilement.
   Le visiteur ne se retrouve jamais bloque. svh et non vh : sur iPad et sur
   un iPhone en paysage, vh compte les barres de Safari comme masquees, et la
   scene collante debordait sous elles. Sous 600px de haut, la sequence cede
   la place a la composition du telephone.

   La progression est pilotee par le defilement, pas par une horloge : le script
   ecrit --prog (0 a 1) et --fin (0 a 1 sur le dernier tiers). Tout le reste est
   du calc() sur transform et opacity. Aucune propriete de mise en page n'est
   animee, aucune image n'est calculee quand la section est hors du champ.

   Sans JavaScript : --prog vaut 1 par defaut, la composition est donc affichee
   dans son etat final, lisible. */
.signe{position:relative;height:160vh;height:160svh;background:var(--encre);color:var(--papier);
  background-image:radial-gradient(64% 46% at 50% 46%,rgba(35,72,198,.30) 0%,transparent 68%)}
.signe-scene{position:sticky;top:0;height:100vh;height:100svh;
  display:grid;place-items:center;overflow:hidden;
  perspective:1300px;perspective-origin:50% 48%}
.signe-in{position:relative;width:min(100%,var(--max));height:min(74vh,520px);height:min(74svh,520px);
  padding-inline:var(--g);transform-style:preserve-3d}

/* Les quatre mots. Chacun part d'un point lointain (--dx, --dy, --dz) et
   rejoint une place precise autour du symbole (--ex, --ey). Ils ne se
   superposent jamais au terme de la course : le but est une composition
   rangee, pas un empilement au centre. --prog interpole entre les deux.
   L'opacite suit la course : un mot lointain est plus pale qu'un mot arrive,
   ce qui donne la profondeur que la perspective seule ne rend pas sur du texte.
   Les mots sont a l'echelle du moment : en 16px, un ecran entier de defilement
   pour quatre mots plus petits qu'une question de la FAQ paraissait vide. */
.signe-mot{
  position:absolute;top:50%;left:50%;
  font-family:var(--etiq);font-size:clamp(16px,1.9vw,26px);font-weight:500;
  letter-spacing:-.01em;color:var(--sur-encre);
  white-space:nowrap;
  opacity:calc(.62 + var(--prog,1) * .38);
  transform:
    translate(-50%,-50%)
    translate3d(
      calc(var(--dx) + (var(--ex) - var(--dx)) * var(--prog,1)),
      calc(var(--dy) + (var(--ey) - var(--dy)) * var(--prog,1)),
      calc(var(--dz) * (1 - var(--prog,1)))
    );
}
/* Un filet relie chaque mot au symbole : c'est lui qui rend la convergence
   lisible plutot que devinable. Il se dessine a mesure que le mot arrive —
   l'inverse d'un trait qui se raccourcit, parce que ce qu'on veut montrer
   c'est le lien qui se cree, pas la distance qui se referme. */
.signe-mot::after{
  content:"";position:absolute;top:50%;height:1px;
  background:linear-gradient(90deg,var(--accent-inv),rgba(95,227,208,.2));
  width:calc(26px * var(--prog,1));opacity:var(--prog,1);
}
/* Le filet part du mot VERS le symbole : a droite pour les mots de gauche, a
   gauche pour ceux de droite. Le degrade est retourne du cote droit pour que
   le bleu reste toujours a l'attache du mot. */
.signe-mot[data-lien="vers-droite"]::after{left:100%;margin-left:10px}
.signe-mot[data-lien="vers-gauche"]::after{right:100%;margin-right:10px;
  background:linear-gradient(270deg,var(--accent-inv),rgba(95,227,208,.2))}

/* Depart : les quatre coins de l'espace, a des profondeurs differentes.
   Arrivee : deux de chaque cote du symbole, en vis-a-vis. */
.signe-1{--dx:-372px;--dy:-136px;--dz:-160px;--ex:-196px;--ey:-36px}
.signe-2{--dx: 364px;--dy: -92px;--dz:  96px;--ex: 196px;--ey:-36px}
.signe-3{--dx:-338px;--dy: 142px;--dz:  44px;--ex:-196px;--ey: 36px}
.signe-4{--dx: 350px;--dy: 152px;--dz:-200px;--ex: 196px;--ey: 36px}

/* Le symbole. Deux couches : un trace fantome, toujours present, et le trace a
   l'accent qui se dessine par-dessus a mesure que --fin monte. Sans la couche
   fantome, le centre de la composition serait vide pendant les deux tiers de la
   sequence — un ecran entier de rien. */
.signe-sceau{
  position:absolute;top:50%;left:50%;width:clamp(96px,12vw,158px);height:auto;
  transform:translate(-50%,-50%) scale(calc(.86 + var(--fin,0) * .14));
}
.signe-sceau path{fill:none;stroke-width:6;stroke-linecap:round}
.signe-fantome path{stroke:var(--papier);opacity:.14}
.signe-trace path{stroke:var(--accent-inv-2);stroke-dasharray:240;
  stroke-dashoffset:calc(240 - 240 * var(--fin,0));
  /* Le trace s'epaissit legerement en se fermant : le sceau gagne en presence
     par sa matiere, pas par un halo pose autour de lui. */
  stroke-width:calc(6px + 1.4px * var(--fin,0))}

/* La legende reste lisible d'un bout a l'autre de la sequence : c'est le propos
   de la section, pas sa recompense. Seule la ligne secondaire attend la fin.
   Le decalage est superieur au point de depart le plus bas des mots (152px) :
   la legende n'est donc jamais recouverte, a aucun moment de la course. */
.signe-dit{position:absolute;left:50%;top:calc(50% + clamp(124px,13vw,172px));
  transform:translateX(-50%);text-align:center;width:min(100%,44ch);
  padding-inline:var(--g)}
.signe-dit b{display:block;font-family:var(--display);font-weight:500;text-wrap:balance;
  font-size:clamp(20px,2.5vw,30px);line-height:1.2;letter-spacing:-.03em;
  color:var(--papier);margin-bottom:10px}
.signe-dit span{display:block;font-family:var(--util);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--sur-encre-3);
  line-height:1.6;opacity:var(--fin,1)}

/* ---- tablette : les distances se resserrent ---- */
@media(max-width:900px){
  .signe-1{--dx:-206px;--dy:-124px;--ex:-118px}
  .signe-2{--dx: 202px;--dy: -84px;--ex: 118px}
  .signe-3{--dx:-188px;--dy: 126px;--ex:-118px}
  .signe-4{--dx: 196px;--dy: 136px;--ex: 118px}
  .signe-mot::after{display:none}
}

/* ---- mobile : la composition, pas la colonne ----
   On garde la suppression du sticky : detourner 190vh de defilement sur un
   telephone est agressif, et le pouce n'a pas la patience d'une sequence.

   Mais une colonne de quatre mots surmontee du logo dit l'inverse du propos :
   elle se lit « un symbole, puis quatre mots », quand la section raconte quatre
   metiers qui convergent VERS un symbole. Les mots sont donc places en carre,
   le sceau au milieu — la geometrie du desktop, sans sa mise en scene.

   L'entree se joue une fois a l'arrivee dans le champ, par l'observateur de la
   section 8 : chaque mot rejoint son coin, le sceau se ferme derriere eux. Deux
   transitions CSS sur transform, opacity et stroke-dashoffset ; aucune lecture
   de position a chaque image, contrairement au desktop.

   Les filets ::after restent caches : dans cette grille ils pointeraient a cote
   du sceau au lieu de le rejoindre. Un trait qui ne relie rien ne vaut rien.
   Meme composition sur un ecran bas (iPhone en paysage) : une scene collante
   de moins de 600px y faisait se chevaucher les mots et la legende. */
@media(max-width:640px),(max-height:599px){
  .signe{height:auto;padding-top:clamp(48px,9vw,72px);padding-bottom:clamp(48px,9vw,72px)}
  .signe-scene{position:static;height:auto;display:block;perspective:none}
  .signe-in{height:auto;transform-style:flat;display:grid;justify-items:center;
    align-items:center;grid-template-columns:1fr 1fr;column-gap:10px;row-gap:16px}
  .signe-mot{position:static;top:auto;left:auto;transform:none;opacity:1}
  .signe-mot::after{display:none}
  .signe-1{grid-column:1;grid-row:1}
  .signe-2{grid-column:2;grid-row:1}
  .signe-3{grid-column:1;grid-row:3}
  .signe-4{grid-column:2;grid-row:3}
  .signe-sceau{position:static;top:auto;left:auto;transform:none;
    grid-column:1 / -1;grid-row:2;width:84px;margin-block:4px}
  .signe-fantome{display:none}
  .signe-trace path{stroke-dashoffset:0}
  .signe-dit{position:static;left:auto;top:auto;transform:none;
    grid-column:1 / -1;grid-row:4;padding-inline:0;margin-top:10px}
  .signe-dit span{opacity:1}

  /* L'etat d'avant. Pose par le script seulement — sans JavaScript, en
     mouvement reduit ou si l'observateur echoue, la classe n'arrive jamais et
     la composition reste a son etat final, lisible. */
  .signe-in.anime .signe-mot{opacity:0;
    transform:translate3d(var(--mx),var(--my),0);
    transition:opacity var(--t-scene) var(--ease),
               transform var(--t-scene) var(--ease);
    transition-delay:var(--retard,0ms);will-change:transform,opacity}
  .signe-in.anime .signe-mot.vu{opacity:1;transform:none}
  .signe-in.anime .signe-mot.pose{will-change:auto}
  /* Chaque mot vient de l'exterieur de sa place : le mouvement va vers le
     centre, comme la course du desktop, en vingt fois moins de distance. */
  .signe-1,.signe-3{--mx:-18px}
  .signe-2,.signe-4{--mx: 18px}
  .signe-1,.signe-2{--my:-12px}
  .signe-3,.signe-4{--my: 12px}
  /* Le sceau se ferme pendant que les deux derniers mots finissent d'arriver :
     les gestes se recouvrent, il n'y a pas de temps mort. */
  .signe-in.anime .signe-trace path{stroke-dashoffset:240;
    transition:stroke-dashoffset 900ms var(--ease);transition-delay:200ms}
  .signe-in.anime .signe-trace.vu path{stroke-dashoffset:0}
}

/* ---- mouvement reduit : la meme composition rangee, immobile ----
   Les quatre mots ne peuvent pas rester empiles au centre : sans mouvement,
   ils se superposeraient. On reprend donc la mise en page verticale du mobile,
   qui dit la meme chose sans deplacer quoi que ce soit. */
@media(prefers-reduced-motion:reduce){
  .signe{height:auto;padding-top:clamp(54px,8vw,88px);padding-bottom:clamp(54px,8vw,88px)}
  .signe-scene{position:static;height:auto;display:block;perspective:none}
  .signe-in{height:auto;transform-style:flat;display:grid;justify-items:center;gap:20px}
  .signe-mot{position:static;top:auto;left:auto;
    transform:none !important;opacity:1 !important;order:2}
  .signe-mot::after{display:none}
  .signe-sceau{position:static;top:auto;left:auto;order:1;
    transform:none !important;width:84px;margin-bottom:6px}
  .signe-fantome{display:none}
  .signe-trace path{stroke-dashoffset:0 !important}
  .signe-dit{position:static;left:auto;top:auto;transform:none;order:3;
    padding-inline:0;margin-top:10px}
  .signe-dit span{opacity:1 !important}
}

/* ---- méthode ---- */
.proc h2{font-size:clamp(28px,3.7vw,46px);margin-block:0 46px;max-width:19ch;
  letter-spacing:-.032em}

/* Chronologie : la methode est une sequence, la mise en page doit le dire.
   Un filet continu relie les trois etapes, chaque numero s'y accroche. */
.chrono{list-style:none;margin:0;padding:0}
.chrono li{display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(20px,3vw,40px);position:relative;padding-bottom:clamp(30px,4vw,48px)}
.chrono li:last-child{padding-bottom:0}
.chrono-rail{position:relative;width:clamp(52px,6vw,74px);flex:none}
/* Le numero d'etape, en couleur pleine et non en degrade : c'est un chiffre,
   il doit se lire comme un chiffre. */
.chrono-num{font-family:var(--display);font-weight:700;font-size:clamp(36px,4.8vw,56px);
  line-height:.9;letter-spacing:-.045em;color:var(--accent);display:block}
/* le filet part sous le numero et rejoint l'etape suivante */
.chrono li:not(:last-child) .chrono-rail::after{content:"";position:absolute;
  left:calc(50% - 1px);top:calc(clamp(36px,4.8vw,56px) + 14px);bottom:calc(clamp(30px,4vw,48px) * -1);
  width:2px;background:linear-gradient(180deg,rgba(35,72,198,.45),var(--ligne-fine))}
.chrono-quand{display:block;font-family:var(--util);font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--gris-clair);margin-bottom:8px}
.chrono h3{font-size:22px;margin-bottom:10px;letter-spacing:-.025em}
.chrono p{color:var(--gris);max-width:44ch}
@media(max-width:620px){
  .chrono li{grid-template-columns:1fr;gap:10px}
  .chrono li:not(:last-child) .chrono-rail::after{display:none}
  .chrono-rail{width:auto}
}

/* ---- cadrage ---- */
.franc h2{font-size:clamp(28px,3.7vw,46px);margin-block:0 42px;max-width:21ch;
  letter-spacing:-.032em}

/* Rangees larges plutot qu'une grille 2x2 : quatre refus se lisent mieux
   empiles, un par ligne, que ranges en cases. */
.refus{border-top:1px solid var(--ligne-inv)}
.refus > div{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(18px,4vw,56px);padding:clamp(22px,2.8vw,34px) 0;
  border-bottom:1px solid var(--ligne-inv);position:relative}
/* Un filet vertical apparait a gauche au survol : la rangee lue se designe
   elle-meme, sans que rien ne bouge. */
.refus > div::before{content:"";position:absolute;left:calc(var(--g) * -.5);
  top:0;bottom:0;width:2px;background:var(--degrade-inv);
  transform:scaleY(0);transform-origin:center;
  transition:transform var(--t-plan) var(--ease)}
.refus h3{font-size:clamp(21px,2.2vw,27px);line-height:1.14;letter-spacing:-.025em}
.refus p{color:var(--sur-encre)}
@media(max-width:760px){.refus > div{grid-template-columns:1fr;gap:10px}
  .refus > div::before{display:none}}

/* ---- la direction ----
   Mise en page editoriale : deux colonnes, le portrait a gauche sur toute la
   hauteur, le texte a droite. La profondeur vient d'une difference de vitesse
   au defilement et d'un passe-partout d'un pixel qui ceinture le portrait et
   sa legende — aucune ombre diffuse, aucun cadre flottant. La photo est posee
   dans la colonne comme une illustration de presse. */
.moi-grid{display:grid;grid-template-columns:minmax(0,.68fr) minmax(0,1fr);
  gap:clamp(26px,4vw,58px);align-items:start}
@media(max-width:820px){.moi-grid{grid-template-columns:1fr}}

.moi-photo{position:relative;padding:14px;
  transform:translate3d(0,var(--par,0px),0)}
/* Le passe-partout : un filet de spectre ceinture l'ensemble, photo et
   legende a l'interieur, avec une respiration egale. C'est le dispositif d'un
   tirage encadre avec son cartel — la legende dans le cadre devient logique.
   Le filet repond aux filets de la colonne de droite, donc il entre dans le
   systeme graphique au lieu de flotter. Le padding rentre le contenu, donc
   plus aucun chevauchement avec la photo (z-index:1). */
.moi-photo::before{content:"";position:absolute;inset:0;
  border:1px solid rgba(35,72,198,.28);pointer-events:none;z-index:0}
.portrait{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;
  background:var(--papier-2);border:1px solid var(--ligne);position:relative;z-index:1;
  /* Duotone froid : la photo entre dans le systeme nuit/papier au lieu d'y
     flotter. Le grayscale seul laissait un gris neutre etranger au bleu du
     site ; la rotation de teinte le rattache a l'encre.
     POUR REVENIR A LA COULEUR : supprimer la ligne filter ci-dessous. */
  filter:grayscale(1) contrast(1.05) sepia(.14) hue-rotate(178deg) saturate(1.35)}
.moi-legende{margin-top:22px;font-family:var(--util);font-size:12px;
  letter-spacing:.07em;color:var(--gris-clair);line-height:1.6}

.moi h2{font-size:clamp(28px,3.7vw,46px);margin-bottom:28px;max-width:18ch;
  letter-spacing:-.032em}

/* Le nom et le role : un bloc identitaire, tenu par un filet a gauche.
   Un seul filet de 2px, pas une carte — le site n'encadre jamais du texte. */
.moi-carte{border-left:2px solid transparent;
  border-image:linear-gradient(180deg,var(--accent),rgba(12,125,113,.55)) 1;
  padding:2px 0 2px 16px;margin-bottom:26px}
.moi-nom{font-family:var(--display);font-weight:700;font-size:clamp(22px,2.3vw,28px);
  line-height:1.1;letter-spacing:-.032em;color:var(--encre)}
.moi-role{font-family:var(--util);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--gris-clair);margin-top:7px}

.moi-txt p{margin-bottom:16px;color:var(--gris)}
/* Le nom et le role sont des <p> de la colonne : sans ce renfort, la regle
   ci-dessus les passait tous deux au gris du texte courant. */
.moi-carte .moi-nom{color:var(--encre);margin-bottom:0}
.moi-carte .moi-role{color:var(--gris-clair);margin-bottom:0}
.moi-txt p.fort{color:var(--encre);font-size:21px;line-height:1.45;margin-bottom:26px}

/* Les axes : une liste numerotee automatiquement, en filets.
   Le numero dit l'ordre dans lequel un projet avance — strategie avant
   creation, creation avant acquisition, acquisition avant automatisation (on
   n'automatise pas un canal qui ne fonctionne pas encore) — donc il porte une
   information. Ajouter un axe ne demande rien d'autre qu'un <li> : le compteur
   CSS et l'animation d'entree lisent la liste, jamais un nombre ecrit en dur. */
.axes{list-style:none;margin:0 0 28px;padding:0;counter-reset:axe;
  border-top:1px solid var(--ligne)}
.axes li{counter-increment:axe;display:grid;
  grid-template-columns:auto minmax(0,1fr);gap:0 16px;align-items:baseline;
  padding-top:14px;padding-bottom:14px;border-bottom:1px solid var(--ligne-fine)}
.axes li::before{content:counter(axe,decimal-leading-zero);
  font-family:var(--util);font-size:11px;letter-spacing:.06em;color:var(--accent);
  grid-row:1 / span 2}
.axes b{font-family:var(--util);font-size:12px;font-weight:400;letter-spacing:.14em;
  text-transform:uppercase;color:var(--encre)}
.axes span{grid-column:2;color:var(--gris);font-size:15.5px;line-height:1.55;margin-top:4px}
@media(max-width:520px){
  .axes li{grid-template-columns:1fr;gap:0}
  .axes li::before{grid-row:auto;display:block;margin-bottom:5px}
  .axes span{grid-column:1}
}

/* ---- questions ---- */
.faq{border-top:1px solid var(--ligne)}
.faq details{border-bottom:1px solid var(--ligne);position:relative}
.faq summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;
  gap:20px;padding-top:22px;padding-bottom:22px;font-family:var(--display);font-size:21px;line-height:1.35;
  font-weight:500;letter-spacing:-.025em;transition:color .16s}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-family:var(--util);font-size:21px;color:var(--gris-clair);
  flex:none;line-height:1;transition:transform .3s var(--ease),color .3s var(--ease)}
.faq details[open] summary::after{transform:rotate(45deg)}
/* 45ch et non 66 : le ch se mesure sur le chiffre 0, plus large qu'une lettre
   moyenne d'Instrument Sans ; a 66ch la reponse faisait 102 caracteres par
   ligne. Ici, autour de 70. */
.faq details p{color:var(--gris);max-width:45ch;padding-bottom:24px;margin-top:-4px}
/* La question ouverte porte un filet de spectre a gauche : on voit d'un coup
   d'oeil laquelle est depliee dans une liste de six. */
.faq details[open]{border-left:2px solid transparent;
  border-image:linear-gradient(180deg,var(--accent),transparent) 1;
  padding-left:18px;margin-left:-20px}
@media(max-width:560px){
  .faq details[open]{padding-left:14px;margin-left:-16px}
}
/* ---- derniers articles ----
   Une bande de lecture entre la demande et le pied : les trois derniers
   articles parus, en simples liens, et le chemin vers le blog. Ni chapeau
   ni carte : c'est une etagere, pas une section de plus. Sur ordinateur, les
   trois titres se lisent de front, separes par des filets ; sur telephone,
   ils s'empilent. L'etiquette et le lien final reprennent ceux du sommaire. */
.derniers{padding-block:clamp(38px,5vw,60px)}
.derniers-in{display:grid;grid-template-columns:minmax(0,.62fr) minmax(0,2fr);
  gap:clamp(16px,3vw,44px);align-items:start}
.derniers-titre{margin:0;font-family:var(--util);font-weight:400;font-size:11px;
  line-height:1.6;letter-spacing:.11em;text-transform:uppercase;color:var(--gris-clair)}
.derniers .billet-lire{margin-top:8px}
.faq-articles{list-style:none;margin:0;padding:0}
.derniers .faq-articles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.derniers .faq-articles li{padding:2px clamp(14px,1.8vw,24px);border-left:1px solid var(--ligne)}
.faq-articles a{font-family:var(--display);font-size:18px;line-height:1.4;font-weight:500;
  letter-spacing:-.02em;color:inherit;text-decoration:underline;text-decoration-color:var(--ligne);
  text-underline-offset:4px;transition:color .16s,text-decoration-color .16s}
@media(hover:hover){.faq-articles a:hover{color:var(--accent);text-decoration-color:currentColor}}
@media(max-width:840px){
  .derniers-in{grid-template-columns:1fr}
  .derniers .faq-articles{grid-template-columns:1fr;border-top:1px solid var(--ligne)}
  .derniers .faq-articles li{padding:12px 0;border-left:none;border-bottom:1px solid var(--ligne-fine)}
  .derniers-tete{display:flex;justify-content:space-between;align-items:baseline;gap:16px}
  .derniers .billet-lire{margin-top:0}
}
/* ---- pour aller plus loin ----
   Sous la derniere question d'une page de service, les articles parus qui
   menent a cette page, en simples liens : la reponse courte est au-dessus,
   la reponse longue a un clic. C'est le bloc qui suivait la FAQ de l'accueil
   avant la refonte ; outils/publier.mjs l'ecrit, et il n'existe que si un
   article y mene. L'etiquette et le lien final reprennent ceux du sommaire. */
.faq-suite{margin-top:40px;max-width:66ch}
.faq-suite .billet-meta{margin-bottom:10px}
.faq-suite .faq-articles li{padding:5px 0}
.faq-suite .billet-lire{margin-top:14px}

/* ================= CONTACT =================
   Le dernier ecran est sur la nuit, comme le premier : la page s'ouvre et se
   ferme dans le meme registre, et le formulaire — le seul endroit ou le
   visiteur agit — se detache sur le fond le plus sombre de la page. */
.contact{background:var(--encre);color:var(--papier);position:relative;overflow:hidden;
  background-image:
    radial-gradient(80% 70% at 12% 0%,rgba(35,72,198,.32) 0%,transparent 62%),
    radial-gradient(70% 70% at 96% 100%,rgba(63,207,192,.12) 0%,transparent 60%)}
.contact::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:var(--degrade-filet-inv);z-index:3}
/* Quatre blocs : la promesse, le livrable, la demande, les garanties. Sur
   ordinateur, la promesse, le livrable et les garanties font la colonne de
   gauche, a peu pres de la hauteur du formulaire qui tient la droite. Sous
   840px, une colonne dans l'ordre du document. Les boutons « audit » visent
   #contact, le formulaire : ils arrivent sur les champs. */
.contact-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  grid-template-areas:"tete form" "livrable form" "garanties form";
  grid-template-rows:auto auto 1fr;
  column-gap:clamp(24px,4vw,60px);row-gap:0;align-items:start;position:relative;z-index:2}
.contact-tete{grid-area:tete}
.contact-livrable{grid-area:livrable}
.contact-form{grid-area:form}
.contact-garanties{grid-area:garanties;margin-top:32px}
@media(max-width:640px){
  .contact .livrable li{padding:15px 16px;gap:12px}
  .contact .livrable b{font-size:18px}
  .contact .livrable span{font-size:15.5px}
}
@media(max-width:840px){
  .contact-grid{grid-template-columns:1fr;grid-template-areas:"tete" "livrable" "form" "garanties";
    grid-template-rows:auto}
  .contact-form{margin-top:36px}
}
#contact{scroll-margin-top:calc(var(--barre) + 16px)}
/* Le titre de la demande, dans le verre : il nomme ce qu'on remplit. */
.form-titre{font-size:clamp(22px,2.2vw,27px);line-height:1.2;letter-spacing:-.028em;
  color:var(--papier);margin:0 0 8px}
.form-intro{color:var(--sur-encre);font-size:15.5px;line-height:1.55;margin-bottom:22px;max-width:46ch}
.contact h2{font-size:clamp(29px,4.4vw,56px);margin-block:0 20px;letter-spacing:-.035em;
  color:var(--papier)}
.contact-p{color:var(--sur-encre);max-width:40ch;margin-bottom:28px;font-size:17.5px}
.contact-liste{list-style:none;margin:0;padding:0}
.contact-tel{margin-top:28px;margin-bottom:0}
.contact-liste li{display:flex;align-items:center;gap:12px;
  color:var(--sur-encre);padding-top:13px;padding-bottom:13px;
  border-top:1px solid var(--ligne-inv-fine)}
.contact-liste .lentille{width:9px;height:9px;color:var(--accent-inv-2)}
.contact-liste .lentille path{fill:currentColor}

/* Le formulaire est une surface de verre posee sur la nuit : c'est l'objet avec
   lequel on interagit, il doit avoir une epaisseur. */
.form-verre{background:var(--verre);border:1px solid var(--verre-bord);
  -webkit-backdrop-filter:var(--flou);backdrop-filter:var(--flou);
  padding:clamp(22px,2.8vw,34px);position:relative}
.form-verre::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--verre-haut) 30%,var(--verre-haut) 70%,transparent)}
/* Sur telephone, le flou disparait du formulaire et de la liste de l'audit,
   comme il avait disparu des plaques du hero : sur un fond de nuit presque
   uni il ne se voit pas, et il coute cher a chaque image de defilement. */
@media(max-width:640px){
  .form-verre,.livrable{-webkit-backdrop-filter:none;backdrop-filter:none}
}

.champ{margin-bottom:16px}
.champ label{display:block;font-family:var(--util);font-size:12px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--sur-encre-3);margin-bottom:8px}
.champ input,.champ textarea,.champ select{
  width:100%;background:rgba(5,8,20,.42);border:1px solid var(--ligne-inv);padding:14px 14px;
  color:var(--papier);font-family:var(--corps);font-size:16.5px;border-radius:0}
.champ input::placeholder,.champ textarea::placeholder{color:var(--sur-encre-3)}
/* La liste deroulante native rend ses options avec les couleurs du systeme :
   sans ces deux valeurs, le menu ouvert affiche du texte clair sur fond clair
   sur plusieurs navigateurs. */
.champ select option{background:var(--encre-2);color:var(--papier)}
.champ textarea{min-height:112px;resize:vertical}

/* L'arrivee au formulaire depuis un bouton « audit » : l'arete du verre
   s'allume une fois, et la situation deja choisie dans le diagnostic se
   signale. Le visiteur voit ou il est arrive, et que son choix l'a suivi. */
.form-verre::after{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;
  background:var(--degrade-inv);transform:scaleX(0);transform-origin:left;opacity:0;
  pointer-events:none}
.form-verre.accueille::after{animation:arete-trace 1.5s var(--ease) both}
@keyframes arete-trace{0%{transform:scaleX(0);opacity:1}55%{transform:scaleX(1);opacity:1}
  100%{transform:scaleX(1);opacity:0}}
.form-verre.accueille select:not(:has(option[value=""]:checked)){
  animation:champ-signale 1.6s var(--ease) .3s both}
@keyframes champ-signale{0%,100%{box-shadow:inset 0 -2px 0 transparent}
  35%{box-shadow:inset 0 -2px 0 var(--accent-inv-2),0 0 0 1px rgba(95,227,208,.35)}}
.champ input:focus,.champ textarea:focus,.champ select:focus{
  border-color:var(--accent-inv);outline:none}
/* Tant qu'aucune situation n'est choisie, la liste se lit comme une consigne,
   pas comme une reponse deja donnee. */
.champ select:has(option[value=""]:checked){color:var(--sur-encre-3)}
/* Un champ requis laisse vide ou mal rempli se signale apres la saisie, pas au
   chargement : :user-invalid attend que le visiteur ait interagi. Le filet
   passe en pointilles et le libelle s'allume, dans le spectre du site. */
.champ:has(:user-invalid) label{color:var(--accent-inv-2)}
.champ input:user-invalid,.champ textarea:user-invalid{border-style:dashed;
  border-color:rgba(95,227,208,.55)}
.form-note{font-family:var(--util);font-size:12px;color:var(--sur-encre-3);margin-top:16px;line-height:1.7}
.miel{position:absolute;left:-9999px}

/* Etats du formulaire : chargement, succes, echec. */
.btn[disabled]{opacity:.55;cursor:progress}
.merci{border:1px solid var(--verre-bord);background:var(--verre);padding:clamp(22px,3vw,32px)}
/* Dans le formulaire, le verre du formulaire suffit : un second cadre dedans
   faisait une boite dans la boite. */
.form-verre .merci{border:none;background:none;padding:clamp(6px,1vw,12px) 0}
.merci:focus{outline:none}
.merci:focus-visible{outline:2px solid var(--accent-inv);outline-offset:3px}
/* La demande est partie : le sceau de la marque se trace, le meme geste que
   la convergence. C'est la fin du parcours, elle a droit a sa signature. */
.merci-sceau{display:block;width:44px;height:44px;margin-bottom:18px}
.merci-sceau path{fill:none;stroke:var(--accent-inv-2);stroke-width:6;stroke-linecap:round;
  stroke-dasharray:100;stroke-dashoffset:100;animation:sceau-trace 1s var(--ease) .2s forwards}
@keyframes sceau-trace{to{stroke-dashoffset:0}}
.merci h3{font-size:22px;line-height:1.2;margin-bottom:10px;color:var(--papier);letter-spacing:-.025em}
.merci p{color:var(--sur-encre)}
.echec{border-left:2px solid var(--accent-inv-2);padding:4px 0 4px 14px;margin-top:14px;
  font-size:15px;color:var(--sur-encre)}
.echec a{color:var(--accent-inv)}

/* ================= BARRE D'ACTION DU TELEPHONE =================
   Sous 640px, l'audit et l'appel passent a portee du pouce, en bas de l'ecran.
   Le script la montre une fois le hero passe et la retire quand le formulaire
   ou le pied sont visibles : elle ne double jamais un bouton deja a l'ecran.
   Elle monte en 420ms et redescend plus vite. Pas de flou : un fond presque
   plein coute moins cher au defilement, et le filet du spectre suffit a la
   detacher. La marge basse suit l'indicateur d'accueil de l'iPhone. */
.barre-action{display:none}
@media(max-width:640px){
  .barre-action{position:fixed;left:0;right:0;bottom:0;z-index:55;
    display:grid;grid-template-columns:1fr 1fr;gap:10px;
    padding:10px max(var(--g),env(safe-area-inset-right)) max(10px,env(safe-area-inset-bottom)) max(var(--g),env(safe-area-inset-left));
    background:rgba(11,16,32,.95);
    box-shadow:0 -16px 32px -20px rgba(0,0,0,.6);
    transform:translate3d(0,110%,0);visibility:hidden;
    transition:transform 240ms var(--ease),visibility 0s linear 240ms}
  .barre-action.visible{transform:none;visibility:visible;
    transition:transform var(--t-plan) var(--ease),visibility 0s}
  .barre-action::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
    background:var(--degrade-filet-inv)}
  .barre-action .btn{justify-content:center;padding:13px 10px;min-height:48px}
  /* La barre du haut garde le logo et le menu : son bouton ferait doublon. */
  body:has(.barre-action) .nav-droite > .btn{display:none}
}

/* ---- le blog ---- */
/* La liste des billets est un filet entre chaque, pas une grille de cartes :
   avec un seul article publie, une grille afficherait surtout du vide. Elle
   supportera vingt entrees sans changer de forme. */
.billets{list-style:none;margin:0;padding:0;max-width:74ch}
.billets li{border-top:1px solid var(--ligne)}
.billets li:last-child{border-bottom:1px solid var(--ligne)}
.billets article{padding-top:34px;padding-bottom:34px}
.billet-meta{margin:0 0 14px;font-family:var(--util);font-size:11px;
  letter-spacing:.11em;text-transform:uppercase;color:var(--gris-clair)}
.billets h2{font-size:clamp(24px,3vw,34px);margin:0 0 14px;letter-spacing:-.028em}
.billets h2 a{color:inherit;text-decoration:none}
@media(hover:hover){.billets h2 a:hover{color:var(--accent)}}
.billet-chapo{margin:0;max-width:64ch;color:var(--gris);line-height:1.6}
.billet-lire{margin:18px 0 0}
.billet-lire a{font-family:var(--util);font-size:11px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--accent);text-decoration:none}
@media(hover:hover){.billet-lire a:hover{text-decoration:underline}}

/* ---- corps d'article ---- */
/* Une mesure de lecture courte, autour de 68 caracteres : au-dela, l'oeil
   perd le debut de la ligne suivante en revenant a la marge. C'est la seule
   regle qui compte vraiment dans un texte long. */
/* 50ch mesures sur le corps de la page, soit environ 72 caracteres par ligne
   dans le texte de l'article (17,5px) : a 68ch il en tenait 97. */
.article{max-width:50ch}
.article > p{margin:0 0 20px;font-size:17.5px;line-height:1.65;color:var(--gris)}
.article h2{font-size:clamp(24px,3vw,32px);margin:50px 0 18px;letter-spacing:-.028em}
.article h3{font-size:clamp(18px,2vw,21px);margin:34px 0 12px;letter-spacing:-.02em}
.article ul{margin:0 0 20px;padding-left:0;list-style:none}
.article ul li{position:relative;padding-left:22px;margin-bottom:16px;
  font-size:17.5px;line-height:1.65;color:var(--gris)}
.article ul li::before{content:"";position:absolute;left:0;top:11px;
  width:7px;height:7px;background:var(--accent)}
.article b{color:var(--encre);font-weight:600}
.article .pole-prix{margin:30px 0 0}
.article .pole-note{margin-top:14px}

/* ---- sous-menu de la barre ---- */
/* Cinq prestations ne tiennent pas cote a cote dans la barre. Elles se
   replient sous leur intitule, qui devient une bascule : au clic, jamais au
   survol — un menu de survol est inatteignable au doigt, et sous 900px la
   barre est deja un menu deroulant. */
.nav-sous{position:relative;display:flex;align-items:center}
.nav-sous-bascule{display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  font-family:var(--etiq);font-size:13.5px;font-weight:500;letter-spacing:-.005em;
  color:var(--sur-encre-2);background:none;border:0;padding:0}
.nav-sous[data-ouvert="true"] .nav-sous-bascule{color:var(--papier)}
@media(hover:hover){.nav-sous-bascule:hover{color:var(--papier)}}
/* Le reperage de section marquait « Nos prestations » tant que ce lien etait
   dans la barre ; il est maintenant dans le sous-menu, donc invisible. La
   bascule reprend la marque a son compte quand un lien qu'elle abrite la
   porte, sinon on perdrait le seul reperage de lecture de la barre. */
.nav-sous:has(a[aria-current="true"]) .nav-sous-bascule{color:var(--papier)}
.nav-sous-fleche{width:10px;height:6px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .22s var(--ease)}
.nav-sous[data-ouvert="true"] .nav-sous-fleche{transform:rotate(180deg)}

/* Fond plein, sans flou : a 97 % le chiffre des plaques transparaissait, et un
   verre dans le verre de la barre est ce que Safari rend le plus mal. */
.nav-sous-liste{display:none;position:absolute;top:calc(100% + 18px);left:-18px;
  min-width:236px;flex-direction:column;padding:8px 0;
  background:var(--encre);
  border:1px solid var(--ligne-inv-fine);
  box-shadow:0 26px 52px -22px rgba(0,0,0,.65);
  /* Le sous-menu se pose au lieu d'apparaitre d'un coup : tout le reste de la
     barre est anime, lui seul claquait. Il se retire plus vite qu'il ne vient. */
  opacity:0;transform:translate3d(0,-6px,0);
  transition:opacity 150ms var(--ease),transform 150ms var(--ease),display 150ms allow-discrete}
.nav-sous[data-ouvert="true"] .nav-sous-liste{display:flex;opacity:1;transform:none;
  transition:opacity var(--t-etat) var(--ease),transform var(--t-etat) var(--ease),
             display var(--t-etat) allow-discrete}
@starting-style{.nav-sous[data-ouvert="true"] .nav-sous-liste{opacity:0;transform:translate3d(0,-6px,0)}}
.nav-links .nav-sous-liste a{padding:11px 18px}
/* Le dernier lien renvoie a la vue d'ensemble : un filet le detache des cinq
   pages, il n'est pas une sixieme prestation. */
.nav-sous-tout{margin-top:6px;padding-top:14px;
  border-top:1px solid var(--ligne-inv-fine);color:var(--sur-encre-3)}

@media(max-width:900px){
  /* Dans le menu deroulant le sous-menu ne flotte plus : il s'ouvre en place,
     decale vers la droite pour montrer qu'il depend de son intitule. */
  .nav-sous{display:block}
  .nav-sous-bascule{width:100%;justify-content:space-between;font-size:15px;
    padding-top:15px;padding-bottom:15px}
  .nav-sous-liste{position:static;min-width:0;padding:0 0 8px;border:0;
    background:none;box-shadow:none;
    -webkit-backdrop-filter:none;backdrop-filter:none}
  .nav-links .nav-sous-liste a{padding:12px 0 12px 16px;border-top:none;font-size:14.5px}
  .nav-sous-tout{margin-top:2px;padding-top:12px;
    border-top:1px solid var(--ligne-inv-fine) !important}
  /* Le premier enfant de la barre n'est plus un <a> mais le sous-menu :
     la regle qui supprimait le filet du premier lien ne mordait plus. */
  .nav-links > .nav-sous:first-child .nav-sous-bascule{border-top:none}
  .nav-links > a{border-top:1px solid var(--ligne-inv-fine)}
}

/* ---- entete des pages de prestation ---- */
/* L'accueil ouvre sur une scene animee ; une page de prestation ouvre sur une
   phrase. Meme fond de nuit, meme mesure de lecture, et une seule entree,
   breve : le fil, le titre, le chapeau puis les boutons se posent. Qui arrive
   ici depuis une recherche veut un renseignement, pas un spectacle ; mais il
   doit reconnaitre le monde de l'accueil : la trame du hero passe en fond,
   sans ses nappes de lumiere.
   Comme le hero, l'entete remonte sous la barre : son verre floute la nuit au
   lieu de griser le papier du body. */
.page-tete{background:var(--encre);color:var(--sur-encre);
  margin-top:calc(var(--barre) * -1);
  padding-top:calc(var(--barre) + clamp(48px,6vw,80px));padding-bottom:clamp(56px,7vw,88px);
  border-bottom:1px solid var(--ligne-inv-fine);position:relative;overflow:hidden}
.page-tete::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:
    repeating-linear-gradient(to right,var(--ligne-inv-fine) 0 1px,transparent 1px 78px),
    repeating-linear-gradient(to bottom,var(--ligne-inv-fine) 0 1px,transparent 1px 78px);
  -webkit-mask-image:radial-gradient(100% 120% at 85% 15%,#000 0%,transparent 72%);
  mask-image:radial-gradient(100% 120% at 85% 15%,#000 0%,transparent 72%)}
.page-tete > .wrap{position:relative;z-index:1}
.page-tete :is(.fil,h1,.chapo,.hero-cta){animation:tete-entre 700ms var(--ease) both}
.page-tete h1{animation-delay:60ms}
.page-tete .chapo{animation-delay:140ms}
.page-tete .hero-cta{animation-delay:220ms}
@keyframes tete-entre{from{opacity:0;transform:translate3d(0,14px,0)}}
.page-tete h1{color:var(--papier);max-width:17ch;font-size:clamp(38px,5.6vw,66px)}
.chapo{margin:22px 0 0;font-size:20.5px;line-height:1.5;max-width:46ch;
  color:var(--sur-encre)}

/* Le fil dit d'ou l'on vient sans se donner l'air d'un titre : c'est la voix
   « etiquette » du site, la meme que les intitules de colonne du pied. */
.fil{margin:0 0 24px;font-family:var(--util);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--sur-encre-3)}
.fil a{color:var(--sur-encre-3);text-decoration:none;
  border-bottom:1px solid var(--ligne-inv)}
@media(hover:hover){.fil a:hover{color:var(--papier)}}

/* ---- footer ---- */
/* Quatre colonnes, comme la page a quatre poles : la marque, ce qu'on vend, ce
   qu'on donne a lire, et l'agence. La marque prend un peu plus de large, les
   trois listes se partagent le reste a egalite. */
footer{background:var(--encre-appui);color:var(--sur-encre-2);
  border-top:1px solid var(--ligne-inv-fine);
  padding-top:56px;padding-bottom:26px}
.foot-in{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:44px;align-items:start}
.foot-in img{height:40px;width:auto;opacity:.9;
  /* Le logotype est un SVG en encre : sur la nuit il faut l'inverser. */
  filter:invert(1) brightness(1.6)}
.foot-phrase{margin:16px 0 0;font-size:14px;line-height:1.55;
  color:var(--sur-encre-3);max-width:32ch}

/* Les deux comptes sont les seuls liens du pied qui sortent du site : ils
   restent ensemble, sous la marque, et gardent la voix « etiquette » en mono
   capitale pour ne pas se confondre avec les pages du site. */
.foot-social{display:flex;gap:18px;margin-top:20px}
.foot-social a{font-family:var(--util);font-size:11px;letter-spacing:.09em;
  text-transform:uppercase;text-decoration:none;color:var(--sur-encre-2)}

/* Le titre de colonne est en mono capitale ; les liens sont dans la fonte de
   la nav, pour qu'un lien du pied et un lien du haut se lisent au meme rang. */
.foot-titre{margin:0 0 12px;font-family:var(--util);font-size:11px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--sur-encre-3)}
.foot-col{display:flex;flex-direction:column}
.foot-col a{font-family:var(--etiq);font-size:14px;font-weight:500;
  letter-spacing:-.005em;text-decoration:none;color:var(--sur-encre-2);
  padding-top:7px;padding-bottom:7px}

/* Au doigt, chaque lien du pied, des reseaux, du fil d'Ariane et des articles
   recommandes offre une cible d'au moins 44px de haut : a 18 ou 37px ils se
   touchaient et se manquaient. Le dessin ne change pas, seule la zone
   sensible grandit. */
@media(pointer:coarse){
  .foot-col a{padding-top:11px;padding-bottom:11px}
  .foot-social a,.foot-bas a{display:inline-block;padding-block:13px}
  .faq-articles a,.billet-lire a,.fil a{display:inline-block;padding-block:11px}
  .faq-suite .faq-articles li{padding:0}
  .pole-lien{padding-block:11px}
}

/* La derniere ligne porte ce qui n'appartient a aucune colonne. */
.foot-bas{display:flex;justify-content:space-between;align-items:center;
  flex-wrap:wrap;gap:12px;margin-top:46px;padding-top:22px;
  border-top:1px solid var(--ligne-inv-fine)}
.foot-bas p,.foot-bas a{margin:0;font-family:var(--util);font-size:11px;
  letter-spacing:.05em;text-transform:uppercase;color:var(--sur-encre-3);
  text-decoration:none}

/* La marque repasse pleine largeur des que les quatre colonnes ne tiennent
   plus : elle porte une phrase, pas une liste, et se lit mal en colonne
   etroite. */
@media(max-width:900px){
  .foot-in{grid-template-columns:1fr 1fr;gap:34px}
  .foot-marque{grid-column:1 / -1}
}
/* Sur telephone, les colonnes de liens restent par deux : empilees une a
   une, elles faisaient du pied un ecran et demi de liste. */
@media(max-width:520px){
  .foot-in{grid-template-columns:1fr 1fr;gap:28px 18px}
}

/* ================= RYTHME ET COULEUR =================
   La page alterne deux registres, et l'alternance porte le sens :

     NUIT     hero · convergence · audit et demande
              (page L'agence : cadrage)
              ce que l'agence demontre, ce sur quoi elle s'engage
     PAPIER   diagnostic · prestations · realisations · derniers articles
              (page L'agence : direction · methode · questions)
              ce que le visiteur lit, compare et verifie

   Les sols suffisent a separer les sections : aucun filet plein d'un bord a
   l'autre n'est necessaire, et la couture spectrale marque les bascules.

   Le spectre ne se depense que la ou il y a un enjeu : le prix, la mesure, la
   position dans la page, et ce que le visiteur touche. Nulle part ailleurs. */

.fond-mid{background:var(--papier-2)}

.fond-encre{background:var(--encre);color:var(--papier);position:relative;overflow:hidden}
.fond-encre > .wrap{position:relative;z-index:2}
.fond-encre .eyebrow{color:var(--sur-encre-3)}
/* Le chapeau d'une section sombre. Sans cette ligne il gardait le gris du
   papier, soit 2,6:1 sur la nuit : c'est pourtant la derniere reassurance
   avant le bouton final des pages metiers et du blog. */
.fond-encre .sec-head p{color:var(--sur-encre)}
/* Les deux sections sombres du milieu de page portent la meme nappe de lumiere,
   posee du cote oppose a leur symbole de fond. */
.franc{background-image:radial-gradient(80% 74% at 8% 6%,rgba(35,72,198,.30) 0%,transparent 62%)}
.franc::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:var(--degrade-filet-inv);z-index:3}

/* Le symbole de la marque, a grande echelle, sur les ruptures sombres. */
.lentille-fond{position:absolute;width:min(40vw,430px);color:var(--accent-inv);
  opacity:.11;z-index:1;pointer-events:none}
.lentille-fond path{fill:none;stroke:currentColor;stroke-width:5;stroke-linecap:round}
.lentille-franc{right:calc(var(--g) * -1);top:-18%}
@media(max-width:860px){.lentille-fond{display:none}}

/* --- L'accent, la ou il compte --- */
.livrable li::before{color:var(--sur-encre-3)}

/* --- Ce que le visiteur touche --- */
@media(hover:hover){.nav-links a:hover{color:var(--papier)}}
@media(hover:hover){.bandeau-in a:hover{color:var(--papier)}}
@media(hover:hover){.foot-col a:hover,.foot-social a:hover,.foot-bas a:hover{color:var(--papier)}}
@media(hover:hover){.faq summary:hover{color:var(--accent)}}
.faq details[open] summary::after{color:var(--accent)}
@media(hover:hover){.fond-encre a:hover,.contact a:hover{color:var(--accent-inv)}}

/* ================= SYSTEME DE MOUVEMENT =================
   Une seule courbe d'arrivee pour tout le site (--ease, dite « expo out ») :
   depart franc, arrivee longue et posee. Rien ne rebondit.

   Le systeme compte trois familles, et pas une de plus :

   1. APPARITION — un element entre dans le champ. Deux variantes seulement,
      choisies selon ce que l'element est, jamais au hasard : « leve » pour un
      bloc de texte, « plan » pour une surface bordee qui avance vers le
      lecteur.
   2. REACTION — le visiteur touche quelque chose. Court (var(--t-tact)),
      toujours reversible.
   3. PILOTAGE PAR LE DEFILEMENT — la position dans la page conduit la valeur.
      Amorti dans le script, applique en transform uniquement.

   Regle de securite : tout etat masque est sous la classe .js. Sans
   JavaScript, ou si le script echoue, la page reste integralement lisible et
   rien n'est invisible. */

/* ---- 1. Apparition ----
   Trois variantes, pas quatre : « leve » pour du texte, « plan » pour une
   surface bordee, « voile » quand l'element est deja pilote en transform.
   Une famille supplementaire existe — la ligne qui se trace — mais elle n'a
   que trois usages legitimes dans la page, tous ecrits sur place : la
   trajectoire du graphe du hero, le filet de la chronologie, le rail de la
   chaine du diagnostic. Une variante generique aurait servi a tracer des
   dizaines de filets qui n'ont rien a raconter. */
/* Pas de will-change ici : pose d'office sur les 64 elements a reveler, il
   creait autant de couches des le chargement, lourdes pour la memoire d'un
   iPhone. Le navigateur promeut de lui-meme un element pendant sa transition. */
.js [data-reveal]{opacity:0}
.js [data-reveal].vu{opacity:1;transform:none;
  transition:opacity var(--t-scene) var(--ease),transform var(--t-scene) var(--ease);
  transition-delay:var(--retard,0ms)}

/* leve : le texte remonte de sa ligne. La valeur par defaut. */
.js [data-reveal]{transform:translate3d(0,18px,0)}
/* plan : une surface s'approche. Reserve aux blocs qui portent une bordure. */
.js [data-reveal="plan"]{transform:perspective(1400px) translate3d(0,26px,-70px) rotateX(3.5deg)}
/* voile : opacite seule. Indispensable quand l'element est deja pilote en
   transform par autre chose — la parallaxe du portrait, par exemple. Deux
   regles qui ecrivent transform sur le meme element s'annulent. */
.js [data-reveal="voile"]{transform:translate3d(0,var(--par,0px),0)}
.js [data-reveal="voile"].vu{transform:translate3d(0,var(--par,0px),0);
  transition:opacity var(--t-scene) var(--ease);transition-delay:var(--retard,0ms)}
/* Sur telephone, le contenu doit preceder le pouce : l'apparition dure 500ms au
   lieu de 760 (le script y raccourcit aussi les cascades), et la variante
   « plan », une surface qui s'approche en perspective, devient une simple
   montee : les blocs y font jusqu'a 1 000px de haut. */
@media(max-width:640px){
  .js [data-reveal].vu{transition-duration:.5s}
  .js [data-reveal="plan"]{transform:translate3d(0,18px,0)}
}

/* Titre : chaque mot remonte depuis sa propre ligne de base masquee.
   Le padding compense la coupe des jambages (p, q, g) par overflow:hidden. */
.mot{display:inline-block;overflow:hidden;vertical-align:bottom;
  padding-bottom:.14em;margin-bottom:-.14em}
.mot > i{display:inline-block;font-style:inherit}
.js h1 .mot > i,.js h2[data-lignes] .mot > i{transform:translateY(110%)}
.js h1.pret .mot > i,.js h2[data-lignes].pret .mot > i{transform:none;
  transition:transform var(--t-ouverture) var(--ease);transition-delay:var(--retard,0ms)}

/* ---- 3. Pilotage par le defilement ----
   Le script pose --par (parallaxe, en pixels), --prog (0 a 1), --lu (progression
   de lecture) et --mx / --my (position du pointeur dans le hero). Aucun
   ecouteur ne touche a une propriete de mise en page : uniquement transform,
   opacity et background-position. */
.js [data-parallax]{transform:translate3d(0,var(--par,0px),0)}

/* La nav se resserre des que la page a quitte le hero : le verre s'opacifie,
   une ombre courte apparait, le logo se reduit.
   La hauteur du logo est animee en scale et non en `height` : animer une
   propriete de mise en page forcerait un recalcul de la barre a chaque image.
   L'origine en bas a gauche garde le logo aligne sur son coin. */
.nav{transition:box-shadow var(--t-plan) var(--ease),
                background var(--t-plan) var(--ease),
                border-color var(--t-plan) var(--ease)}
.nav-in .logo{transform-origin:left center;
  transition:transform var(--t-plan) var(--ease)}
.js .nav[data-dense="true"]{background:rgba(9,13,26,.9);
  box-shadow:0 8px 30px -12px rgba(0,0,0,.6);border-bottom-color:var(--ligne-inv)}
.js .nav[data-dense="true"] .logo{transform:scale(.8)}
/* Les pages interieures n'ont pas le script qui resserre la barre : passee
   l'entete, son verre a 72 % grisait de nouveau sur le papier. La ou le
   navigateur sait lier une animation au defilement, la barre s'y opacifie
   sur les 180 premiers pixels, jusqu'a l'etat resserre de l'accueil. */
@supports (animation-timeline:scroll()){
  body:not(:has(.hero)) .nav{animation:barre-dense linear both;
    animation-timeline:scroll(root block);animation-range:0 180px}
}
@keyframes barre-dense{to{background:rgba(9,13,26,.9);
  box-shadow:0 8px 30px -12px rgba(0,0,0,.6);border-bottom-color:var(--ligne-inv)}}

/* Le bouton de la barre prend le relais de ceux du hero. Tant qu'ils sont a
   l'ecran il s'efface : deux boutons identiques au premier ecran se
   disputaient l'oeil. Des qu'ils sortent, il se pose a sa place, qu'il
   n'a jamais quittee (aucun decalage des liens). Sans script, l'attribut
   n'existe pas et le bouton reste visible. */
.nav-droite > .btn{transition:opacity var(--t-etat) var(--ease),visibility 0s,
  background var(--t-etat) var(--ease),color var(--t-etat) var(--ease),
  border-color var(--t-etat) var(--ease),box-shadow var(--t-plan) var(--ease),
  transform var(--t-plan) var(--ease)}
.nav[data-relais="attente"] .nav-droite > .btn{opacity:0;visibility:hidden;
  transform:translate3d(0,-6px,0);
  transition:opacity 160ms var(--ease),transform 160ms var(--ease),visibility 0s linear 160ms}
@media(max-width:560px){.js .nav[data-dense="true"] .logo{transform:scale(.84)}}

/* Le lien de la section lue porte une marque. Ce n'est pas une decoration :
   c'est la seule indication de position dans une page d'un seul ecran. */
.nav-links a{position:relative;transition:color var(--t-tact) var(--ease)}
.nav-links a::after{content:"";position:absolute;left:0;right:0;bottom:-5px;height:1px;
  background:var(--degrade-inv);transform:scaleX(0);transform-origin:left;
  transition:transform var(--t-etat) var(--ease)}
.nav-links a[aria-current="true"]::after{transform:scaleX(1)}
@media(hover:hover){.nav-links a:hover::after{transform:scaleX(1)}}
.nav-links a[aria-current="true"]{color:var(--papier)}
@media(max-width:900px){.nav-links a::after{bottom:12px}}

/* ---- 2. Reaction : les poles ----
   Au survol, la colonne avance de 2px, sa nappe de lumiere se leve et son filet
   de prix s'etend. Le mouvement est minuscule et c'est voulu : il confirme la
   cible sans deplacer le texte qu'on est en train de lire. */
.pole{transition:transform var(--t-plan) var(--ease)}
.pole::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:var(--degrade-filet);transform:scaleX(0);transform-origin:left;
  transition:transform var(--t-plan) var(--ease)}
@media(hover:hover) and (min-width:841px){
  .pole:hover{transform:translate3d(0,-2px,0)}
  .pole:hover::after{transform:scaleX(1)}
  .pole:hover::before{opacity:1}
}
/* Le prix est ce que l'on vient chercher : au survol du quadrant, son filet
   s'etend sur toute la largeur. Le prix lui-meme ne bouge pas — un chiffre qui
   change d'aspect au survol se lit comme une promotion. */
.pole-prix::before{transform:scaleX(.42);transform-origin:left;
  transition:transform var(--t-plan) var(--ease)}
@media(hover:hover) and (min-width:841px){
  .pole:hover .pole-prix::before{transform:scaleX(1)}
}
/* Au doigt, il n'y a pas de survol pour etendre le filet : il restait fige a
   42 %, comme inacheve. Il se trace donc a l'apparition du quadrant. */
@media(hover:none){
  .js .pole .pole-prix::before{transform:scaleX(.42)}
  .js .pole.vu .pole-prix::before{transform:scaleX(1);
    transition:transform 900ms var(--ease) 350ms}
}

/* ---- 2. Reaction : les realisations ----
   La maquette se redresse legerement au survol de la rangee : les trois plans
   se rapprochent du lecteur, comme si l'on se penchait dessus. Rien ne change
   de taille, seule la rotation diminue. */
@media(hover:hover) and (min-width:941px){
  .cas > article:hover .cas-scene{transform:rotateX(1.5deg) rotateY(-4deg)}
  .cas > article:nth-child(even):hover .cas-scene{transform:rotateX(1.5deg) rotateY(4deg)}
}

/* ---- 2. Reaction : la chronologie ----
   Le filet vertical se tire quand son etape arrive dans le champ : la sequence
   se construit sous les yeux au lieu d'etre deja la. Pas de calcul au
   defilement — c'est la revelation de l'etape qui declenche son propre filet.
   Le filet n'est replie que sur une etape qui attend sa revelation
   ([data-reveal]) : les pages metiers n'ont pas ce script, et leurs filets
   restaient replies, invisibles. */
.js .chrono li[data-reveal]:not(:last-child) .chrono-rail::after{
  transform-origin:top;transform:scaleY(0);
  transition:transform var(--t-scene) var(--ease) 180ms}
.js .chrono li[data-reveal].vu:not(:last-child) .chrono-rail::after{transform:scaleY(1)}
.chrono-num{display:block;transition:transform var(--t-plan) var(--ease)}
@media(hover:hover){.chrono li:hover .chrono-num{transform:translate3d(0,-3px,0)}}

/* ---- 2. Reaction : les refus, sur la nuit ---- */
.refus > div{transition:background var(--t-etat) var(--ease)}
@media(hover:hover){
  .refus > div:hover{background:var(--voile-inv)}
  .refus > div:hover::before{transform:scaleY(1)}
}

/* ---- 2. Reaction : le diagnostic ----
   Le panneau ne clignote pas d'un contenu a l'autre : il bascule legerement,
   comme une fiche que l'on retourne. Duree courte — c'est une reponse a un
   clic, pas une mise en scene. */
.choix button{transition:background var(--t-tact) var(--ease),
                         color var(--t-tact) var(--ease),
                         border-color var(--t-tact) var(--ease),
                         box-shadow var(--t-etat) var(--ease),
                         transform var(--t-etat) var(--ease)}
@media(hover:hover){.choix button:hover{transform:translate3d(3px,0,0)}}
.choix button .lentille{transition:transform var(--t-etat) var(--ease)}
.choix button[aria-selected="true"] .lentille{transform:rotate(90deg)}
.reponse{box-shadow:var(--z2);transition:box-shadow var(--t-plan) var(--ease)}
.fade{animation:fade var(--t-plan) var(--ease)}
@keyframes fade{
  from{opacity:0;transform:perspective(1200px) translate3d(0,8px,-24px)}
  to{opacity:1;transform:none}
}

/* ---- 2. Reaction : les questions ----
   L'ouverture d'un details ne peut pas etre animee en hauteur sans recalculer
   la mise en page. On anime donc uniquement le contenu, en fondu-montee, apres
   que le navigateur a fait la place. */
.faq details[open] p{animation:repondre var(--t-plan) var(--ease)}
/* La ou le navigateur sait animer une hauteur « auto » (::details-content),
   la reponse se deploie au lieu de surgir, puis le texte se pose. Ailleurs,
   le fondu ci-dessus suffit. */
@supports (interpolate-size:allow-keywords) and selector(::details-content){
  .faq details{interpolate-size:allow-keywords}
  .faq details::details-content{block-size:0;overflow:clip;
    transition:block-size var(--t-plan) var(--ease),content-visibility var(--t-plan) allow-discrete}
  .faq details[open]::details-content{block-size:auto}
}
@keyframes repondre{from{opacity:0;transform:translate3d(0,-6px,0)}to{opacity:1;transform:none}}
.faq summary::after{transition:transform var(--t-plan) var(--ease),color var(--t-plan) var(--ease)}

/* ---- 2. Reaction : le formulaire ----
   Le champ actif porte une lueur interieure basse, pas un anneau de couleur :
   la ligne de saisie s'allume sous le texte que l'on tape. */
.champ input,.champ textarea,.champ select{
  transition:border-color var(--t-tact) var(--ease),box-shadow var(--t-tact) var(--ease),
             background var(--t-tact) var(--ease)}
.champ input:focus,.champ textarea:focus,.champ select:focus{
  background:rgba(5,8,20,.6);
  box-shadow:inset 0 -2px 0 var(--accent-inv-2),0 0 0 1px rgba(127,165,255,.2)}
.merci{animation:fade var(--t-scene) var(--ease)}

/* ---- Le portrait : le grain se leve a l'arrivee ----
   La photo passe d'un duotone eteint au duotone de reference. C'est le seul
   endroit du site ou un filtre est anime, et il ne tourne qu'une fois.
   Le selecteur cible .moi-photo, qui porte lui-meme la parallaxe : le reveal
   est donc pose sur le meme element, sans conflit de transform. */
.portrait{transition:filter 1.4s var(--ease)}
.js .moi-photo[data-reveal] .portrait{
  filter:grayscale(1) contrast(.92) sepia(.14) hue-rotate(178deg) saturate(1.1) opacity(.84)}
.js .moi-photo[data-reveal].vu .portrait{
  filter:grayscale(1) contrast(1.05) sepia(.14) hue-rotate(178deg) saturate(1.35)}

/* ---- Le bandeau des poles : le trait suit la cible ---- */
.bandeau-in a{position:relative;transition:color var(--t-tact) var(--ease)}
.bandeau-in a .lentille{transition:transform var(--t-etat) var(--ease)}
@media(hover:hover){.bandeau-in a:hover .lentille{transform:scale(1.6)}}

/* ================= ENTRE LES PAGES =================
   Passer d'une page a l'autre ne recharge plus sechement : l'ancienne page
   s'efface, la nouvelle se pose, et la barre, identique d'une page a l'autre,
   ne bouge pas. Chrome, Edge et Safari 18.2 et suivants ; ailleurs, la
   navigation reste celle d'avant. */
@view-transition{navigation:auto}
.nav{view-transition-name:barre}
::view-transition-old(root){animation:vt-sortie 200ms var(--ease) both}
::view-transition-new(root){animation:vt-entree 420ms var(--ease) both}
@keyframes vt-sortie{to{opacity:0}}
@keyframes vt-entree{from{opacity:0;transform:translate3d(0,10px,0)}}

/* ================= MOUVEMENT REDUIT =================
   On supprime le deplacement, on garde les changements d'etat. Les transitions
   de couleur signalent le focus et la selection : les tuer nuirait a la
   comprehension plus que le mouvement ne genait. Tout ce qui etait masque
   redevient visible immediatement, dans sa position finale.

   Les couleurs, les degrades, le verre et les lueurs restent : ce sont des
   surfaces, pas du mouvement. Seul ce qui se deplace ou se declenche est
   neutralise. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .js [data-reveal],.js [data-reveal].vu,
  .js [data-reveal="plan"],.js [data-reveal="voile"]{
    opacity:1 !important;transform:none !important;transition:none !important}
  .js h1 .mot > i,.js h2[data-lignes] .mot > i{transform:none;transition:none}
  .js [data-parallax]{transform:none !important}
  .js .chrono li:not(:last-child) .chrono-rail::after{transform:none !important;transition:none}
  .scene{transform:rotateX(4deg) rotateY(-8deg) !important}
  .cas-scene,.cas > article:hover .cas-scene,
  .cas > article:nth-child(even) .cas-scene,
  .cas > article:nth-child(even):hover .cas-scene{transition:none !important}
  .js .graphe-trait{stroke-dashoffset:0 !important;transition:none}
  .js .graphe-aire{opacity:1 !important;transition:none}
  .js .graphe-noeuds rect,.js .colonnes i{transform:none !important;transition:none}
  .js .entonnoir span::after{transform:scaleX(1) !important;transition:none}
  .hero-toile{display:none}
  /* Le halo du hero reste, immobile : c'est une nappe de lumiere fixe, elle ne
     suit plus le pointeur puisque le script n'ecrit plus --mx / --my. */
  .hero-lueur{opacity:1;transition:none}
  /* La jauge de lecture est une information de position, pas une animation :
     elle reste, mais sans transition. */
  .nav::after{transition:none}
  .btn,.pole,.choix button,.chrono-num{transform:none !important}
  .btn-plein::after{display:none}
  .pole::after,.pole::before,.pole-prix::before,.refus > div::before{transition:none}
  .pole-prix::before{transform:scaleX(1)}
  .nav-in .logo{transform:none !important;transition:none}
  .fade,.merci,.faq details[open] p{animation:none}
  .portrait{transition:none}
  .js .moi-photo[data-reveal] .portrait,
  .js .moi-photo[data-reveal].vu .portrait{
    filter:grayscale(1) contrast(1.05) sepia(.14) hue-rotate(178deg) saturate(1.35)}
  .moi-photo{transform:none !important}
  .signe-trace path{stroke-width:6px}
  /* Le menu s'ouvre et se ferme sans deroulement ; la croix reste une croix. */
  .nav-links,.nav-links[data-ouvert="true"],.nav-sous-liste,
  .nav-sous[data-ouvert="true"] .nav-sous-liste,.nav-menu rect,.nav::before{transition:none !important}
  .nav-links[data-ouvert="true"] > *{animation:none}
  /* Le parcours vers l'audit : tout est la tout de suite, rien ne glisse. */
  .js .reponse .r-pied{opacity:1 !important;transform:none !important;transition:none !important}
  .merci-sceau path{animation:none;stroke-dashoffset:0}
  .form-verre.accueille::after,.form-verre.accueille select{animation:none}
  .barre-action,.barre-action.visible{transition:none}
  .fleche{transition:none}
  .cas{scroll-behavior:auto}
  /* Les pages s'enchainent sans glisser ; l'entete se pose sans monter ; la
     nappe du hero ne derive pas ; la FAQ s'ouvre d'un coup. */
  ::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none !important}
  .page-tete :is(.fil,h1,.chapo,.hero-cta){animation:none}
  .hero-lueur{animation:none}
  .faq details::details-content{transition:none}
  /* Le bouton de la barre passe sans glisser. */
  .nav-droite > .btn,.nav[data-relais="attente"] .nav-droite > .btn{transition:none}
  /* Au doigt, le filet de prix est deja trace. */
  .js .pole .pole-prix::before{transform:scaleX(1) !important;transition:none !important}
}
