/* ============================================================
   EcomDev — site vitrine
   Sombre, profond, moderne. La profondeur vient des ombres,
   jamais d'un trait de bordure. Les surfaces vivent grâce à
   une goutte de lumière qui circule sur leur contour.
   ============================================================ */

/* la goutte a besoin d'un angle animable */
@property --tour{ syntax:"<angle>"; initial-value:0deg; inherits:false }

/* ---------- 1. Jetons ---------- */
/* Le thème sombre est le thème du site : il vit dans :root.
   Le clair est une variante, activée par [data-theme="light"].
   Conséquence utile : sans JavaScript, le visiteur voit le sombre. */
:root{
  /* marque — identiques dans les deux thèmes */
  --bleu:    #0177FF;
  --indigo:  #2B4CF5;
  --ciel:    #6AA6FF;
  --or:      #FFB800;

  --grot: "Poppins", "Century Gothic", sans-serif;
  --sans: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;

  --large:   1240px;
  --gout:    clamp(22px, 3.4vw, 56px);
  --section: clamp(78px, 9vw, 132px);
  --r:       15px;
  --r-l:     22px;
  --r-btn:   13px;

  /* Le verre dépoli ne sert plus qu'à l'en-tête collé. Ailleurs, il coûtait
     cher pour rien : derrière une carte il n'y a qu'un dégradé lisse, et
     flouter un dégradé lisse ne change rien à l'image. Mesuré sur la page
     entière, 48 surfaces floutées faisaient passer le pire des images de
     10,9 à 16,6 ms — c'est ça qu'on ressent comme une saccade. */
  --verre:   blur(22px) saturate(135%);


  /* ── Le thème du site : le sombre. ──
     Il vit dans :root, donc il s'applique même sans JavaScript.
     Le clair est la variante, plus bas, sous [data-theme="light"]. */
  --fond:        #010206;
  --titre:       #FFFFFF;
  /* Les paragraphes tirent au plus près du blanc. On garde deux crans très
     serrés sous le titre : assez pour que la hiérarchie tienne, pas assez
     pour que le texte paraisse gris sur ce fond très sombre. */
  --texte:       #F4F7FC;
  --texte-2:     #DEE6F2;
  --texte-3:     rgba(255,255,255,.52);   /* textes d'attente, logos clients */
  --or-txt:      #FFB800;                 /* l'or, quand il porte du texte */
  --lien:        var(--ciel);

  --surface:     rgba(255,255,255,.058);  /* verre au repos */
  --surface-2:   rgba(255,255,255,.085);  /* verre survolé */
  --surface-3:   rgba(255,255,255,.045);  /* creux : barre, vue, icône */
  --pastille:    var(--surface-2);        /* en sombre, le verre suffit */
  --rail-vif:    rgba(255,184,0,.55);      /* le rail du parcours */

  /* le pied de page — mêmes valeurs dans les deux thèmes, il est toujours sombre */
  --pied-fond:     #070E1E;
  --pied-titre:    #FFFFFF;
  --pied-titre-k:  rgba(226,236,250,.52);   /* les intitulés de colonnes */
  --pied-texte:    rgba(226,236,250,.82);
  --pied-texte-2:  rgba(226,236,250,.55);
  --pied-lien:     #7FB4FF;
  --pied-filet:    rgba(255,255,255,.09);
  --pied-surface:  rgba(255,255,255,.07);
  --erreur:      #FF8A8A;                  /* messages de formulaire */
  --succes:      #4ADE9B;
  --trame-pt:    rgba(255,255,255,.10);    /* les points de la trame */
  --reflet:      rgba(255,255,255,.10);   /* l'arête claire du verre */
  --reflet-fort: rgba(255,255,255,.16);
  --filet:       rgba(255,255,255,.07);   /* séparateurs internes */

  --ombre:      0 18px 44px rgba(0,0,0,.44), inset 0 1px 0 var(--reflet);
  --ombre-haut: 0 30px 70px rgba(0,0,0,.55), inset 0 1px 0 var(--reflet-fort);
  --ombre-bleu: 0 12px 30px rgba(1,119,255,.34);

  --goutte-halo: rgba(120,175,255,.30);
  --goutte-vif:  rgba(232,242,255,.95);

  --btn2-fond:        rgba(61,123,255,.20);
  --btn2-fond-survol: rgba(61,123,255,.34);
  --btn2-reflet:      rgba(180,212,255,.30);
  --btn2-texte:       #FFFFFF;

  /* en sombre, les cartes restent du verre comme le reste */
  --proj-fond:        var(--surface-3);
  --proj-fond-survol: var(--surface-2);
  --proj-titre:       var(--titre);
  --proj-texte:       var(--texte-2);
  --proj-accent:      var(--or-txt);   /* l'étiquette de métier, seule touche d'or */
  --proj-lien:        var(--ciel);     /* l'action « voir le site » reste un lien */
  --proj-filet:       var(--filet);

  --puce-fond:  rgba(255,168,20,.12);      /* pastilles des numéros d'étape */
  --ic-fond:    linear-gradient(150deg, rgba(255,168,20,.22), rgba(255,120,10,.08));
  --ic-reflet:  rgba(255,214,120,.28);
  --ic-ombre:   0 8px 20px rgba(0,0,0,.30);
  --rond-ombre: 0 8px 18px rgba(43,76,245,.40);

  --entete-fond: rgba(9,17,38,.82);
  --menu-fond:   rgba(14,26,56,.96);
  --grain:       .04;

  /* fonds dégradés de la page */
  --nappe:
    radial-gradient(1100px 760px at 8% -6%,  rgba(38,88,235,.34), transparent 58%),
    radial-gradient(900px 640px at 92% 2%,   rgba(1,119,255,.18), transparent 56%),
    radial-gradient(1000px 700px at 88% 96%, rgba(24,72,190,.24), transparent 58%),
    radial-gradient(820px 600px at 10% 72%,  rgba(1,119,255,.12), transparent 58%),
    linear-gradient(168deg, #0A1633 0%, #04091A 46%, #061029 100%);

  --encart:
    radial-gradient(760px 420px at 20% 0%, rgba(30,80,190,.45), transparent 62%),
    radial-gradient(620px 400px at 84% 100%, rgba(1,119,255,.22), transparent 62%),
    linear-gradient(160deg,#152A55,#0A1330);

  --lueur-heros:
    radial-gradient(circle at 34% 32%, rgba(61,123,255,.85), transparent 56%),
    radial-gradient(circle at 74% 72%, rgba(24,72,205,.7), transparent 58%);

  color-scheme:dark;
}

/* ── variante claire ──
   Doit rester APRÈS le bloc :root : à spécificité égale, c'est
   l'ordre du fichier qui tranche. Déplacée au-dessus, elle serait
   écrasée par le sombre et la bascule ne ferait plus rien. */
[data-theme="light"]{
  --fond:        #EEF2F9;
  --titre:       #071129;
  --texte:       #2E3C56;
  --texte-2:     #5B6A85;
  --texte-3:     rgba(10,25,55,.4);
  --or-txt:      #0F5FD0;                 /* en clair, les petits textes passent en bleu */
  --lien:        #0F5FD0;

  /* Les cartes sont blanches d'emblée, pas au survol. Un blanc translucide
     sur la nappe dégradée prenait une teinte bleutée qui donnait l'impression
     d'un élément en attente. Le survol n'ajoute donc plus de couleur : il
     soulève la carte et creuse son ombre, ce qui suffit à répondre au geste. */
  --surface:     #FFFFFF;
  --surface-2:   #FFFFFF;
  --surface-3:   #FFFFFF;
  /* la pastille des questions, qui ne peut plus être blanche sur blanc */
  --pastille:    rgba(10,30,70,.07);
  --rail-vif:    rgba(15,95,208,.42);
  --erreur:      #C6304A;
  --succes:      #0F8A55;
  --trame-pt:    rgba(15,95,208,.16);
  --reflet:      rgba(255,255,255,.9);
  --reflet-fort: rgba(255,255,255,1);
  --filet:       rgba(10,30,70,.09);

  --ombre:      0 12px 30px rgba(14,40,95,.10), inset 0 1px 0 var(--reflet);
  --ombre-haut: 0 22px 50px rgba(14,40,95,.16), inset 0 1px 0 var(--reflet-fort);
  --ombre-bleu: 0 12px 28px rgba(1,119,255,.3);

  --goutte-halo: rgba(1,119,255,.28);
  --goutte-vif:  rgba(1,90,220,.9);

  /* bouton secondaire : fond encre translucide, texte blanc.
     Sur fond clair c'est le seul fond qui tienne du blanc lisible,
     et il garde une vraie hiérarchie face au bleu du bouton principal. */
  --btn2-fond:        rgba(12,28,64,.86);
  --btn2-fond-survol: rgba(12,28,64,1);
  --btn2-reflet:      rgba(255,255,255,.18);
  --btn2-texte:       #FFFFFF;

  /* Les cartes de réalisation sont blanches, comme toutes les autres cartes.
     Le gris clair d'avant coupait la tuile en deux — maquette sur blanc, texte
     sur gris — et cette couture se voyait plus que le projet lui-même. Un seul
     blanc, un filet sous la maquette, et la carte redevient un objet entier. */
  --proj-fond:        #FFFFFF;
  --proj-fond-survol: #FFFFFF;
  --proj-titre:       var(--titre);
  --proj-texte:       var(--texte-2);
  --proj-accent:      var(--lien);
  --proj-lien:        var(--lien);
  --proj-filet:       rgba(10,30,70,.10);

  --puce-fond:  rgba(1,119,255,.12);
  --ic-fond:    linear-gradient(150deg, rgba(1,119,255,.20), rgba(43,76,245,.08));
  --ic-reflet:  rgba(120,175,255,.36);
  /* sur fond clair, une ombre portée sur un élément de 46 px se voit
     tout de suite comme une salissure : on la réduit au strict minimum */
  --ic-ombre:   0 1px 3px rgba(14,40,95,.06);
  --rond-ombre: 0 2px 6px rgba(43,76,245,.16);

  --entete-fond: rgba(238,242,249,.86);
  --menu-fond:   rgba(255,255,255,.98);
  --grain:       .022;

  --nappe:
    radial-gradient(1100px 760px at 8% -6%,  rgba(1,119,255,.16), transparent 58%),
    radial-gradient(900px 640px at 92% 2%,   rgba(43,76,245,.10), transparent 56%),
    radial-gradient(1000px 700px at 88% 96%, rgba(1,119,255,.13), transparent 58%),
    radial-gradient(820px 600px at 10% 72%,  rgba(43,76,245,.08), transparent 58%),
    linear-gradient(168deg, #FFFFFF 0%, #E9EFF9 46%, #F4F7FC 100%);

  --encart:
    radial-gradient(760px 420px at 20% 0%, rgba(1,119,255,.16), transparent 62%),
    radial-gradient(620px 400px at 84% 100%, rgba(43,76,245,.12), transparent 62%),
    linear-gradient(160deg,#FFFFFF,#E7EEFA);

  --lueur-heros:
    radial-gradient(circle at 34% 32%, rgba(61,123,255,.34), transparent 56%),
    radial-gradient(circle at 74% 72%, rgba(43,76,245,.24), transparent 58%);

  color-scheme:light;
}

/* ---------- 2. Base ---------- */
*,*::before,*::after{ box-sizing:border-box }
html{ scroll-behavior:smooth; -webkit-text-size-adjust:100% }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto } }

body{
  margin:0; color:var(--texte);
  font-family:var(--sans); font-size:16.5px; line-height:1.68;
  -webkit-font-smoothing:antialiased;
  /* clip, pas hidden : hidden crée un conteneur de défilement et casse
     le position:sticky de l'en-tête. clip coupe sans rien créer. */
  overflow-x:clip;
  background:var(--fond);
}

h1,h2,h3,h4{
  font-family:var(--grot); color:var(--titre); margin:0;
  font-weight:600; line-height:1.12; letter-spacing:-.025em;
}
h1{ font-size:clamp(35px, 4.4vw, 56px); letter-spacing:-.035em }
h2{ font-size:clamp(27px, 3vw, 39px); letter-spacing:-.028em }
h3{ font-size:clamp(17.5px, 1.45vw, 20px); letter-spacing:-.012em; line-height:1.32 }
p{ margin:0 }
a{ color:inherit; text-decoration:none }
img{ max-width:100%; display:block }
ul{ margin:0; padding:0; list-style:none }
button{ font-family:inherit; cursor:pointer; border:0; background:none; color:inherit }
::selection{ background:var(--bleu); color:#fff }
:focus-visible{ outline:2px solid var(--ciel); outline-offset:3px; border-radius:8px }

/* ---------- 3. Le fond ---------- */
/* Pleine largeur. Pas de overflow:hidden ici : ça casserait le
   position:sticky de l'en-tête. */
.panneau{
  width:100%; position:relative;
  background:var(--nappe);
  background-attachment:fixed;
}
.env{ width:100%; max-width:var(--large); margin:0 auto; padding:0 var(--gout) }
.sec{ padding:var(--section) 0; position:relative }

/* ---------- 4. La goutte de lumière ---------- */
/* Une goutte claire tourne le long du contour. Pas de trait fixe :
   au repos elle est discrète, au survol elle s'accélère et s'éclaire. */
.goutte{ position:relative; isolation:isolate }
/* Au repos, le contour n'a NI dégradé NI masque.
   C'est une décision de performance, pas d'esthétique. Il y a 39 surfaces
   « goutte » sur la page, dont 21 rien que dans le rail d'avis. Un
   conic-gradient découpé au mask-composite est l'une des choses les plus
   coûteuses à peindre en CSS, et une opacité nulle n'empêche pas la peinture.
   Le dégradé et le masque n'apparaissent donc qu'au survol, ou sur les trois
   surfaces qui portent goutte-vive. */
.goutte::before{
  content:""; position:absolute; inset:0; border-radius:inherit; padding:1.4px;
  opacity:0; transition:opacity .45s ease; pointer-events:none; z-index:3;
}
.goutte:hover::before,
.goutte-vive::before{
  background:conic-gradient(from var(--tour),
    transparent 0deg 244deg,
    var(--goutte-halo) 298deg,
    var(--goutte-vif) 333deg,
    var(--goutte-halo) 350deg,
    transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
  animation:tourner 7s linear infinite;
}
.goutte:hover::before{
  opacity:.9; animation-duration:2.4s;
}
@keyframes tourner{ to{ --tour:360deg } }

/* Les seules surfaces qui gardent la goutte au repos : les appels
   à l'action principaux. Trois sur toute la page, pas quarante. */
.goutte-vive::before{ opacity:.5 }

/* variante rapide et plus serrée, pour les boutons */
.goutte-v::before{ animation-duration:4s; padding:1.2px }
.goutte-v:hover::before{ animation-duration:1.5s }

/* ---------- 5. Surtitre ---------- */
.sur{
  font-family:var(--mono); font-size:11px; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase; color:var(--or-txt);
  margin:0 0 16px;
}
.chapo{ font-size:clamp(15.5px,1.4vw,17.5px); color:var(--texte-2); max-width:62ch; margin-top:18px }
/* un nom, une marque : ça prend la couleur des titres, sans changer de graisse */
.chapo b{ color:var(--titre); font-weight:600 }
.centre{ text-align:center }
.centre .chapo{ margin-left:auto; margin-right:auto }

/* ---------- 6. Boutons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  font-family:var(--sans); font-weight:600; font-size:12.5px;
  letter-spacing:.07em; text-transform:uppercase;
  padding:16px 28px; border-radius:var(--r-btn); position:relative;
  transition:transform .28s cubic-bezier(.2,.9,.2,1), box-shadow .28s, background .28s, color .28s;
}
.btn-plein{
  background:linear-gradient(150deg, #2A72E8 0%, #1258C9 52%, #17389E 100%);
  color:#fff; box-shadow:var(--ombre-bleu), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn-plein:hover{ transform:translateY(-2px); box-shadow:0 18px 44px rgba(1,119,255,.46), inset 0 1px 0 rgba(255,255,255,.24) }
.btn-fant{ background:var(--btn2-fond); color:var(--btn2-texte);
  box-shadow:inset 0 1px 0 var(--btn2-reflet), 0 10px 26px rgba(0,0,0,.18) }
.btn-fant:hover{ transform:translateY(-2px); background:var(--btn2-fond-survol) }
.btn-petit{ padding:12px 21px; font-size:11.5px }
/* Un picto dans un bouton se cale sur la hauteur des majuscules, pas sur la
   taille du texte : à 12,5 px en capitales, 16 px d'icône est l'équivalent
   optique. Le flex:0 0 auto l'empêche de s'écraser sur un libellé long. */
.btn svg{ width:16px; height:16px; flex:0 0 auto }
.btn-petit svg{ width:15px; height:15px }

.lienf{
  display:inline-flex; align-items:center; gap:9px; font-weight:600; font-size:14.5px;
  color:var(--lien); transition:gap .3s cubic-bezier(.2,.9,.2,1), color .3s;
}
.lienf:hover{ gap:15px; color:var(--titre) }

/* ---------- 7. En-tête ---------- */
.tete{ position:sticky; top:0; z-index:80; padding:20px 0; transition:padding .3s, background .3s }
.tete.colle{
  background:var(--entete-fond); backdrop-filter:blur(18px);
  -webkit-backdrop-filter:blur(18px); padding:12px 0;
  box-shadow:0 14px 40px rgba(0,0,0,.18);
}
.tete .env{ display:flex; align-items:center; gap:clamp(16px,2.4vw,34px) }
.sig{ display:flex; align-items:center; gap:11px; flex:0 0 auto }
.sig img{ height:30px; width:auto }
.sig b{ font-family:var(--grot); font-weight:700; font-size:21px; letter-spacing:-.03em; color:var(--titre) }

/* Les deux marges automatiques répartissent également le vide de part et
   d'autre : le menu se pose entre le logo et les commandes. */
.nav{ display:flex; gap:clamp(14px,1.8vw,28px); margin:0 auto; align-items:center }

/* Mais « au milieu du vide » n'est pas « au milieu de la page » : le groupe de
   droite étant plus large que le logo, le menu tombait 33 px trop à gauche.
   Au-delà de 1200 px on le sort donc du flux pour le caler sur l'axe réel.
   Pas en dessous : la place manquerait et il chevaucherait le logo. */
@media (min-width:1201px){
  .tete .env{ position:relative }
  .nav{ position:absolute; left:50%; transform:translateX(-50%); margin:0 }
  .bascule{ margin-left:auto }   /* le menu ne pousse plus, il faut le relayer */
}
.nav a{ font-size:14.5px; font-weight:500; color:var(--texte); transition:color .25s; white-space:nowrap }
.nav a:hover{ color:var(--titre) }
.puce-neuf{
  font-size:9.5px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  background:var(--puce-fond); color:var(--or-txt); padding:3px 7px; border-radius:4px;
  margin-right:7px; vertical-align:2px;
}

.burger{ display:none; width:42px; height:42px; border-radius:12px;
  align-items:center; justify-content:center; background:var(--surface-3) }
.burger i{ display:block; width:17px; height:1.6px; background:var(--titre); position:relative; border-radius:2px }
.burger i::before,.burger i::after{
  content:""; position:absolute; left:0; width:17px; height:1.6px; background:var(--titre);
  border-radius:2px; transition:transform .3s, top .3s;
}
.burger i::before{ top:-5.5px } .burger i::after{ top:5.5px }
.burger.on i{ background:transparent }
.burger.on i::before{ top:0; transform:rotate(45deg) }
.burger.on i::after{ top:0; transform:rotate(-45deg) }

@media (max-width:1080px){
  .nav{
    position:absolute; inset:100% var(--gout) auto var(--gout); flex-direction:column;
    align-items:stretch; gap:0; background:var(--menu-fond); border-radius:var(--r);
    /* le menu déplié n'est plus un élément de la rangée : les marges
       automatiques du bureau doivent être annulées, sinon il se décale */
    padding:10px; box-shadow:var(--ombre-haut); margin:0;
    opacity:0; visibility:hidden; transform:translateY(-10px);
    transition:opacity .3s, transform .3s, visibility .3s;
  }
  .nav.on{ opacity:1; visibility:visible; transform:none }
  .nav a{ padding:14px 16px; border-radius:11px; font-size:15.5px }
  .nav a:hover{ background:var(--surface-3) }
  .tete .btn{ display:none }
  .burger{ display:flex; margin-left:auto }
}

/* ---------- 8. Héros ---------- */
.heros{ padding:clamp(46px,6vw,86px) 0 clamp(56px,7vw,100px) }
.heros-g{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.06fr);
  gap:clamp(50px,4vw,84px); align-items:center }
@media (max-width:1000px){ .heros-g{ grid-template-columns:1fr; gap:52px } }

.heros h1{ margin-bottom:16px }
.heros .accroche{ font-family:var(--grot); font-weight:700; font-size:clamp(19px,2vw,26px);
  color:var(--titre); letter-spacing:-.02em; margin-bottom:20px }
.heros p.d{ color:var(--texte-2); max-width:46ch; font-size:16.5px }
.heros .act{ display:flex; gap:14px; flex-wrap:wrap; margin-top:36px }

/* la composition : une maquette inclinée qui portera tes captures */
.compo{ position:relative; perspective:1500px }
.compo .lueur{
  position:absolute; inset:-8% 0; border-radius:50%; z-index:0;
  background:var(--lueur-heros);
  filter:blur(84px); pointer-events:none;
}
.ecran{
  position:relative; z-index:2; border-radius:var(--r-l); overflow:hidden;
  background:var(--surface);
  box-shadow:var(--ombre-haut);
  transform:rotateY(-7deg) rotateX(3deg);
  transform-style:preserve-3d;
  transition:transform .7s cubic-bezier(.2,.9,.2,1);
}
.compo:hover .ecran{ transform:rotateY(-3deg) rotateX(1deg) }
.ecran .barre{ display:flex; align-items:center; gap:7px; padding:14px 18px;
  background:var(--surface-3) }
.ecran .barre i{ width:9px; height:9px; border-radius:50%; background:var(--filet) }
/* la barre d'adresse : creusée, sinon elle disparaît dans la barre blanche */
.ecran .barre .u{ margin-left:10px; flex:1; background:var(--pastille); border-radius:7px;
  padding:6px 12px; font-family:var(--mono); font-size:11px; color:var(--texte-2) }
.ecran .vue{ aspect-ratio:1440/900; background:var(--surface-3);
  display:grid; place-items:center; overflow:hidden }
.ecran .vue img{ width:100%; height:100%; object-fit:cover; object-position:top center }
.att{ font-family:var(--mono); font-size:10.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--texte-3); text-align:center; padding:14px; line-height:2 }

/* les deux appareils posés devant l'écran : tablette et téléphone.
   Le cadre sombre et les angles très arrondis suffisent à les identifier. */
.appareil{
  position:absolute; z-index:4; overflow:hidden;
  background:linear-gradient(160deg,#2A3550,#0D1424);
  box-shadow:0 26px 54px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.22);
}
.appareil .vue{ overflow:hidden; background:var(--surface-3); display:grid; place-items:center }
.appareil .vue img{ width:100%; height:100%; object-fit:cover; object-position:top center }

/* tablette : bordure fine, angles moyens */
.tablette{
  width:32%; left:-7%; bottom:-13%;
  border-radius:16px; padding:7px;
}
.tablette .vue{ aspect-ratio:768/1024; border-radius:9px }

/* téléphone : bordure plus fine encore, angles très marqués */
.tel{
  width:16%; right:3%; bottom:-17%;
  border-radius:19px; padding:5px;
}
.tel .vue{ aspect-ratio:420/820; border-radius:15px }
/* l'encoche : deux pixels de barre suffisent à faire lire « téléphone » */
.tel::after{
  content:""; position:absolute; z-index:2; top:9px; left:50%; transform:translateX(-50%);
  width:26%; height:4px; border-radius:99px; background:rgba(0,0,0,.55);
}

@media (max-width:1000px){
  .tablette{ width:30%; left:0; bottom:-8% }
  .tel{ width:15%; right:2%; bottom:-10% }
}
@media (max-width:560px){
  .tablette{ width:32%; left:0; bottom:-6%; border-radius:12px; padding:5px }
  .tablette .vue{ border-radius:8px }
  .tel{ width:17%; right:1%; bottom:-8%; border-radius:15px; padding:4px }
  .tel .vue{ border-radius:12px }
  .tel::after{ top:7px; height:3px }
}

/* ---------- 9. Barre de preuve ---------- */
.preuve{ display:flex; flex-wrap:wrap; gap:clamp(18px,3vw,44px); margin-top:44px;
  padding-top:32px; box-shadow:inset 0 1px 0 var(--filet) }
.preuve div b{ display:block; font-family:var(--grot); font-weight:700;
  font-size:clamp(24px,2.4vw,30px); color:var(--titre); line-height:1.1; letter-spacing:-.03em }
.preuve div span{ font-size:12.5px; color:var(--texte-2) }

/* ---------- 10. Clients ---------- */
.clients{ padding:clamp(50px,6vw,80px) 0 }
.clients h4{ text-align:center; font-family:var(--grot); font-size:clamp(19px,2vw,25px);
  color:var(--titre); margin-bottom:clamp(30px,3.6vw,48px) }
/* ---------- Le bandeau défilant ----------
   Deux lots identiques dans une piste, et l'animation translate d'exactement
   la moitié : à l'instant où le premier lot sort, le second est à sa place au
   pixel près, donc la boucle ne se voit pas.
   Le masque en dégradé fait mourir les logos aux deux bords plutôt que de les
   couper net — sans lui, ils apparaissent et disparaissent d'un coup. */
/* 15 px de plus que la marge basse du titre (48 px) : les deux marges se
   rejoignent, donc c'est la plus grande qui fixe l'écart — 63 px. */
.bandeau{ overflow:hidden; margin-top:clamp(45px,4.5vw,63px);
  /* le fondu est plus court qu'en pleine largeur : sur 1240 px, 7 % de chaque
     côté avalait un logo entier */
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
          mask-image:linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent) }
.bandeau-piste{ display:flex; width:max-content;
  animation:defiler 38s linear infinite }
.bandeau:hover .bandeau-piste{ animation-play-state:paused }
@keyframes defiler{ to{ transform:translateX(-50%) } }

.bandeau-lot{ display:flex; align-items:center;
  gap:clamp(38px,5vw,76px); padding-right:clamp(38px,5vw,76px);
  --h-logo:clamp(21px,2.3vw,29px) }

/* les partenaires sans logo : même poids optique que les images */
.bandeau-lot b{ font-family:var(--grot); font-weight:700;
  font-size:clamp(17px,1.8vw,22px); letter-spacing:-.02em; white-space:nowrap;
  color:var(--titre); opacity:.6; transition:opacity .3s }
.bandeau-lot b:hover{ opacity:1 }
[data-theme="light"] .bandeau-lot b{ opacity:.5 }

.logos{ display:flex; flex-wrap:wrap; justify-content:center; gap:clamp(26px,4vw,64px);
  align-items:center; --h-logo:clamp(21px,2.3vw,29px) }
/* Un seul jeu de fichiers pour les deux thèmes : brightness(0) écrase toutes
   les couleurs en noir sans toucher à la transparence, et invert(1) le renvoie
   en blanc. Les logos gardent donc leurs teintes d'origine dans les fichiers,
   ce qui laisse la porte ouverte à un affichage en couleur un jour. */
.logos img,
.bandeau-lot img{ height:var(--h-logo); width:auto; max-width:132px; object-fit:contain;
  filter:brightness(0) invert(1); opacity:.6;
  transition:opacity .3s, filter .3s }
.logos img:hover,
.bandeau-lot img:hover{ opacity:1 }
/* Un logo empilé — marque au-dessus, texte en dessous — a besoin de plus de
   hauteur pour peser autant qu'un logotype en ligne. */
.logos img.empile,
.bandeau-lot img.empile{ height:calc(var(--h-logo) * 1.5) }
[data-theme="light"] .logos img,
[data-theme="light"] .bandeau-lot img{ filter:brightness(0); opacity:.5 }

/* ---------- 11. Cartes ---------- */
/* Aucune bordure : c'est l'ombre et le fond légèrement plus clair qui détachent. */
.carte{
  border-radius:var(--r-l); padding:clamp(24px,2.6vw,32px);
  background:var(--surface);
  box-shadow:var(--ombre); position:relative; overflow:hidden;
  transition:transform .4s cubic-bezier(.2,.9,.2,1), box-shadow .4s, background .4s;
}
.carte:hover{
  transform:translateY(-5px); box-shadow:var(--ombre-haut);
  background:var(--surface-2);
}
.carte .ic{
  width:46px; height:46px; border-radius:14px; display:grid; place-items:center;
  background:var(--ic-fond); color:var(--or-txt);
  box-shadow:inset 0 1px 0 var(--ic-reflet), var(--ic-ombre);
  margin-bottom:20px; font-family:var(--mono); font-size:12px; font-weight:700;
  letter-spacing:.04em;
}
.carte .ic svg{ width:19px; height:19px; stroke-width:1.5;
}
/* Les pictos de services : des SVG dessinés, pas des traits de police.
   Ils portent leurs propres couleurs et leur propre dégradé, donc pas de
   pastille autour — elle ferait un cadre dans un cadre. Ils sont plus grands
   que les icônes de trait qu'ils remplacent : c'est ce qui les rend lisibles
   d'un coup d'œil, et c'est le premier élément que l'œil rencontre. */
.carte .pict{ display:block; width:clamp(54px,5vw,66px); height:auto;
  margin-bottom:20px }
/* Deux fichiers par picto : le doré pour le fond sombre, le bleu pour le fond
   clair. Un SVG posé en <img> ne se recolore pas en CSS — il faudrait
   l'intégrer au HTML, ce qui alourdirait la page de trois fois 2 Ko à chaque
   chargement. Le thème n'étant pas une media query mais un attribut, on
   bascule à la main, exactement comme le logo. */
.carte .pict.clair{ display:none }
[data-theme="light"] .carte .pict.sombre{ display:none }
[data-theme="light"] .carte .pict.clair{ display:block }
.carte h3{ margin-bottom:11px }
.carte p{ font-size:15px; color:var(--texte-2) }

.g3{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(16px,2vw,24px) }
@media (max-width:940px){ .g3{ grid-template-columns:1fr } }
.g4{ display:grid; grid-template-columns:repeat(4,1fr); gap:clamp(16px,2vw,24px) }
@media (max-width:1000px){ .g4{ grid-template-columns:repeat(2,1fr) } }
@media (max-width:560px){ .g4{ grid-template-columns:1fr } }
/* la ligne qui suit une grille de cartes, quand il reste une chose à dire */
.apres-g3{ margin-top:clamp(20px,2.2vw,28px); text-align:center; font-size:14.5px;
  color:var(--texte-2) }

/* ---------- 11 bis. La trame ----------
   Le demi-ton de la charte, en CSS plutôt qu'en image : des points sur une
   grille, effacés par un masque radial pour qu'ils soient denses dans un coin
   et disparaissent vers le centre. C'est exactement le motif des visuels
   Instagram, mais il pèse quelques octets, suit le thème, et reste net à
   n'importe quelle taille d'écran. */
.trame{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:radial-gradient(circle, var(--trame-pt) 1.4px, transparent 1.5px);
  background-size:16px 16px;
  -webkit-mask-image:radial-gradient(110% 110% at 100% 100%, #000 0%, transparent 58%);
          mask-image:radial-gradient(110% 110% at 100% 100%, #000 0%, transparent 58%);
}
/* deux coins opposés, pour un bloc centré qui serait déséquilibré avec un seul */
.trame-double{
  -webkit-mask-image:
    radial-gradient(70% 90% at 100% 100%, #000 0%, transparent 62%),
    radial-gradient(70% 90% at 0% 0%,    #000 0%, transparent 62%);
          mask-image:
    radial-gradient(70% 90% at 100% 100%, #000 0%, transparent 62%),
    radial-gradient(70% 90% at 0% 0%,    #000 0%, transparent 62%);
}
/* tout ce qui porte une trame doit tenir son contenu au-dessus d'elle */
.final-b > :not(.trame){ position:relative; z-index:1 }

/* ---------- 12. Comment ça marche ---------- */
.duo{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(34px,5vw,76px); align-items:center }
@media (max-width:940px){ .duo{ grid-template-columns:1fr; gap:46px } }
.etapes{ display:grid; gap:14px; margin-top:34px }
.etape{
  display:grid; grid-template-columns:46px 1fr; gap:20px; align-items:start;
  padding:19px 21px; border-radius:var(--r);
  background:var(--surface-3);
  box-shadow:var(--ombre); transition:transform .35s cubic-bezier(.2,.9,.2,1), background .35s;
}
.etape:hover{ transform:translateX(4px); background:var(--surface-2) }
.etape .n{ font-family:var(--mono); font-weight:700; font-size:12px; color:var(--or-txt);
  background:var(--puce-fond); border-radius:11px; padding:8px 0; text-align:center }
.etape h4{ font-size:16.5px; margin-bottom:5px; color:var(--titre) }
.etape p{ font-size:14.5px; color:var(--texte-2) }

/* ---------- 12 bis. Le parcours ----------
   Quatre cartes alignées ne disent pas « étapes », elles disent « options ».
   Ce qui fait la différence, c'est le rail : les numéros sortent des cartes,
   se posent sur une ligne continue, et chacun pointe vers le suivant.
   Le regard suit la ligne, donc l'ordre se lit sans avoir à l'expliquer. */
.parcours{ display:grid; grid-template-columns:repeat(4,1fr);
  gap:clamp(16px,2vw,24px); list-style:none; --rail:34px }
.jalon{ position:relative; display:flex; flex-direction:column }

/* la pastille du numéro : le plus gros caractère de la section */
.jalon-n{
  position:relative; z-index:2; flex:0 0 auto;
  width:68px; height:68px; border-radius:22px; margin-bottom:20px;
  display:grid; place-items:center;
  font-family:var(--grot); font-weight:700; font-size:26px; letter-spacing:-.03em;
  color:var(--or-txt); background:var(--ic-fond);
  box-shadow:inset 0 1px 0 var(--ic-reflet), var(--ic-ombre);
}

/* Le rail. Il part du bord de la pastille et va jusqu'à la pastille suivante :
   la largeur du trou de la grille, d'où le right négatif. Le dégradé le fait
   mourir avant l'arrivée, ce qui donne le sens de la marche. */
.jalon:not(:last-child)::before{
  content:""; position:absolute; z-index:0;
  top:var(--rail); left:68px; right:calc(-1 * clamp(16px,2vw,24px)); height:2px;
  background:linear-gradient(90deg, var(--rail-vif) 0%, var(--rail-vif) 55%, transparent 100%);
}
/* la pointe : trois pixels qui suffisent à dire dans quel sens ça va */
.jalon:not(:last-child)::after{
  content:""; position:absolute; z-index:1;
  top:calc(var(--rail) - 3px); right:calc(-1 * clamp(16px,2vw,24px) + 9px);
  width:7px; height:7px; border-top:2px solid var(--rail-vif);
  border-right:2px solid var(--rail-vif); transform:rotate(45deg);
  opacity:.55;
}

.jalon-c{ flex:1; display:flex; flex-direction:column }
.jalon-c h3{ margin-bottom:11px }
.jalon-c p{ font-size:15px; color:var(--texte-2) }

/* Deux colonnes : le rail ne doit plus relier la 2e à la 3e, sinon il
   traverserait le vide en fin de rangée. */
@media (max-width:1000px){
  .parcours{ grid-template-columns:repeat(2,1fr); row-gap:clamp(30px,4vw,44px) }
  .jalon:nth-child(2n)::before,
  .jalon:nth-child(2n)::after{ display:none }
}
/* Une colonne : le rail bascule à la verticale et descend d'un jalon à l'autre. */
@media (max-width:560px){
  .parcours{ grid-template-columns:1fr; row-gap:clamp(26px,6vw,34px) }
  .jalon{ display:grid; grid-template-columns:60px 1fr; column-gap:20px; align-items:start }
  .jalon-n{ width:60px; height:60px; border-radius:19px; font-size:23px; margin-bottom:0 }
  .jalon:not(:last-child)::before,
  .jalon:nth-child(2n)::before{
    display:block; top:60px; left:29px; right:auto;
    width:2px; height:calc(100% - 60px + clamp(26px,6vw,34px));
    background:linear-gradient(180deg, var(--rail-vif) 0%, var(--rail-vif) 55%, transparent 100%);
  }
  .jalon::after{ display:none }
}

/* ---------- 13. Travaux ---------- */
.travaux{ display:grid; grid-template-columns:repeat(3,1fr); gap:clamp(16px,2vw,24px) }
@media (max-width:1000px){ .travaux{ grid-template-columns:repeat(2,1fr) } }
@media (max-width:640px){ .travaux{ grid-template-columns:1fr } }
.proj{
  border-radius:var(--r-l); overflow:hidden; position:relative; display:block;
  background:var(--proj-fond);
  box-shadow:var(--ombre);
  transition:transform .4s cubic-bezier(.2,.9,.2,1), box-shadow .4s;
}
.proj:hover{ transform:translateY(-5px); box-shadow:var(--ombre-haut);
  background:var(--proj-fond-survol) }
.proj .vue{ aspect-ratio:3/2; overflow:hidden; display:grid; place-items:center;
  background:#fff }
.proj .vue img{ width:100%; height:100%; object-fit:cover; object-position:center;
  transition:transform .7s cubic-bezier(.2,.9,.2,1) }
.proj:hover .vue img{ transform:scale(1.05) }
/* Le filet qui pose la maquette sur le texte. En sombre il n'a rien à
   séparer — le creux de la vue s'en charge — donc il n'existe qu'en clair. */
.proj .bas{ padding:22px 24px 26px }
[data-theme="light"] .proj .bas{ box-shadow:inset 0 1px 0 var(--proj-filet) }
.proj .k{ font-family:var(--mono); font-size:10.5px; font-weight:700; letter-spacing:.16em;
  text-transform:uppercase; color:var(--proj-accent); display:block; margin-bottom:9px }
.proj h3{ margin-bottom:7px; color:var(--proj-titre) }
.proj p{ font-size:14px; color:var(--proj-texte) }
.proj .res{ margin-top:16px; padding-top:16px; display:flex; align-items:baseline; gap:9px;
  box-shadow:inset 0 1px 0 var(--proj-filet) }
.proj .res b{ font-family:var(--mono); font-weight:700; font-size:13px; color:var(--proj-titre);
  letter-spacing:-.01em }
/* Le « voir le site » prend le bleu du lien, pas l'accent de la carte.
   Deux touches d'or par tuile — l'étiquette de métier ET l'action — faisaient
   douze taches orange sur la grille. L'or ne garde que l'étiquette. */
.proj .res span{ font-size:12px; color:var(--proj-lien); margin-left:auto }

/* ---------- 14. Chiffres ----------
   À plat, sans carte. Ce sont quatre faits, pas un objet : ils se posent
   directement sur la page, tenus ensemble par de simples filets. Les tuiles
   d'origine faisaient quatre cartes de plus dans une page qui en compte déjà
   beaucoup ; l'encart qui les remplaçait faisait un deuxième gros bloc à
   quelques écrans de celui du contact. Rien, c'est plus calme. */
.bande{
  padding:clamp(6px,1vw,14px) 0;
  text-align:center;
}
.bande .sur{ margin-bottom:clamp(22px,2.4vw,32px) }
.chiffres{ display:grid; grid-template-columns:repeat(4,1fr) }
@media (max-width:780px){ .chiffres{ grid-template-columns:repeat(2,1fr); row-gap:34px } }
/* Le filet de séparation, plutôt qu'un écart : il tient les quatre ensemble.
   Il est retiré sur la première colonne de chaque rangée, sinon il pendrait
   au bord de la bande. */
.chiffre{ text-align:center; padding:6px clamp(10px,1.6vw,22px);
  box-shadow:inset 1px 0 0 var(--filet) }
.chiffre:first-child{ box-shadow:none }
@media (max-width:780px){ .chiffre:nth-child(odd){ box-shadow:none } }
/* Montserrat et non Poppins : ses chiffres sont plus étroits et plus droits,
   ils s'alignent mieux en rangée. Le resserrement passe de -.045 à -.03em —
   à -.045 le « 4,9/5 » de Montserrat se collait sur sa virgule. */
.chiffre b{ display:block; font-family:var(--sans); font-weight:700;
  font-size:clamp(40px,4.6vw,60px); line-height:1; letter-spacing:-.03em;
  color:var(--titre) }
.chiffre span{ display:block; margin-top:12px; font-size:13px; color:var(--texte-2);
  max-width:15ch; margin-left:auto; margin-right:auto }

/* ---------- 15. Avis ---------- */
/* La carte est une colonne : la signature descend au pied, quelle que soit
   la longueur de la citation. Sans ça, les lignes de la grille se déséquilibrent. */
.avis{ display:flex; flex-direction:column }
.avis blockquote{ font-size:16px; color:var(--texte); margin:0 0 24px; line-height:1.72 }
.avis .qui{ display:flex; align-items:center; gap:13px; padding-top:20px; margin-top:auto;
  box-shadow:inset 0 1px 0 var(--filet) }
.avis .rond{ width:44px; height:44px; border-radius:50%; flex:0 0 auto; display:grid;
  place-items:center; position:relative; overflow:hidden;
  font-family:var(--grot); font-weight:700; font-size:16px;
  color:#fff !important;   /* toujours blanc : le rond est bleu dans les deux thèmes */
  background:linear-gradient(150deg,#3D7BFF,#2B4CF5); box-shadow:var(--rond-ombre) }
/* La photo se pose par-dessus l'initiale. Si le fichier manque, le onerror
   du HTML retire l'image et l'initiale reprend sa place — jamais d'icône cassée. */
.avis .rond img{ position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; border-radius:50% }
.avis .qui b{ display:block; font-size:14.5px; color:var(--titre); font-weight:600 }
.avis .qui span{ font-size:12.5px; color:var(--texte-2) }
.etoiles{ color:var(--or-txt); font-size:13px; letter-spacing:2px; margin-bottom:16px }
.avis .qui sup{ font-size:.72em; vertical-align:.35em }
/* Le client qui revient : la preuve la plus forte, donc on la nomme. */
.fidele{ display:inline-block; margin-left:7px; padding:2px 8px; border-radius:999px;
  font-style:normal; font-size:10.5px; font-weight:600; letter-spacing:.02em;
  color:var(--or-txt); background:var(--puce-fond) }

/* Le rail d'avis.
   Le défilement est natif : le doigt, le trackpad et la molette suffisent.
   Les flèches et le défilement automatique ne sont qu'un confort en plus,
   d'où le `.js` qui les fait apparaître seulement si le script a tourné. */
.carrousel{ position:relative }
.piste{
  --rail-gap:clamp(16px,2vw,24px);
  /* 3,2 cartes et non 3 : le fragment de la quatrième dit « ça continue »
     mieux que n'importe quelle flèche. */
  --carte-l:calc((100% - 3 * var(--rail-gap)) / 3.2);
  display:grid; grid-auto-flow:column; grid-auto-columns:var(--carte-l);
  gap:var(--rail-gap);
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x proximity; scroll-behavior:smooth;
  /* la marge négative rend la place que le rembourrage prend aux ombres */
  padding:8px 6px 20px; margin:-8px -6px -20px;
  scrollbar-width:none; -ms-overflow-style:none;
}
.piste::-webkit-scrollbar{ display:none }
/* Vingt et une cartes dans un rail de 7 500 px : sur un écran retina, la
   texture approche la limite du navigateur. content-visibility laisse ignorer
   celles qui sont hors du cadre — la taille annoncée évite que la mise en
   page saute quand elles entrent. */
.piste > figure{ scroll-snap-align:start;
  content-visibility:auto; contain-intrinsic-size:auto 360px auto 380px }
.piste:focus-visible{ outline:2px solid var(--lien); outline-offset:2px;
  border-radius:var(--r-l) }
@media (max-width:1000px){ .piste{ --carte-l:calc((100% - 2 * var(--rail-gap)) / 2.15) } }
@media (max-width:700px){ .piste{ --carte-l:86% } }

/* Les commandes n'existent que si le JavaScript répond. */
.carrousel-cmd{ display:none }
.js .carrousel-cmd{ display:flex; align-items:center; justify-content:center;
  gap:clamp(14px,2vw,22px); margin-top:clamp(22px,2.6vw,32px) }
.fleche{ width:46px; height:46px; border-radius:var(--r-btn); flex:0 0 auto;
  display:grid; place-items:center; cursor:pointer;
  background:var(--surface-3); color:var(--titre);
  box-shadow:inset 0 1px 0 var(--reflet), var(--ombre);
  transition:background .3s, transform .3s }
.fleche:hover{ background:var(--surface-2); transform:translateY(-2px) }
.fleche:active{ transform:translateY(0) }
.fleche svg{ width:19px; height:19px }
/* La jauge dit deux choses d'un coup : où on en est, et combien il en reste. */
.jauge{ width:min(260px,40vw); height:3px; border-radius:99px;
  background:var(--filet); overflow:hidden }
.jauge i{ display:block; height:100%; border-radius:99px;
  background:linear-gradient(90deg,#3D7BFF,#0177FF);
  transition:width .3s ease-out, margin-left .3s ease-out }

/* ---------- 16. Questions ---------- */
.faq{ max-width:860px; margin:0 auto; display:grid; gap:12px }
.q{ border-radius:var(--r); overflow:hidden;
  background:var(--surface-3);
  box-shadow:var(--ombre); transition:background .35s }
.q[open]{ background:var(--surface-2) }
.q summary{ display:flex; align-items:center; gap:20px; padding:22px 26px; cursor:pointer;
  list-style:none; font-family:var(--grot); font-weight:700; font-size:clamp(15.5px,1.5vw,18px);
  color:var(--titre); letter-spacing:-.02em; transition:color .25s }
.q summary::-webkit-details-marker{ display:none }
.q summary:hover{ color:var(--lien) }
/* la pastille + / − : creusée, sinon elle serait blanche sur blanc */
.q .pl{ margin-left:auto; flex:0 0 auto; width:27px; height:27px; border-radius:9px;
  background:var(--pastille); display:grid; place-items:center; position:relative;
  transition:background .3s }
.q[open] .pl{ background:var(--bleu) }
.q[open] .pl::before,.q[open] .pl::after{ background:#fff }
.q .pl::before,.q .pl::after{ content:""; position:absolute; background:var(--titre); border-radius:2px }
.q .pl::before{ width:11px; height:1.6px }
.q .pl::after{ width:1.6px; height:11px; transition:transform .35s cubic-bezier(.2,.9,.2,1) }
.q[open] .pl::after{ transform:scaleY(0) }
.q .rep{ padding:0 26px 26px; font-size:15px; color:var(--texte-2) }
.q .rep p + p{ margin-top:13px }

/* ---------- 17. Appel final ---------- */
.final-b{
  border-radius:var(--r-l); padding:clamp(42px,5.4vw,80px) clamp(26px,4vw,64px);
  text-align:center; position:relative; overflow:hidden;
  background:var(--encart);
  box-shadow:var(--ombre-haut);
}
.final-b h2{ max-width:17ch; margin:0 auto }
.final-b .act{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; margin-top:36px }

/* ---------- Les paires de boutons sur téléphone ----------
   Deux boutons empilés mangent un tiers de l'écran. On les garde côte à côte
   en resserrant la typographie et le rembourrage, et en leur donnant la même
   largeur : flex:1 1 0 les fait partager la ligne au lieu de la déborder.
   Sous 380 px, le picto saute — c'est lui ou le libellé sur deux lignes. */
/* Trois paliers, réglés sur la mesure du libellé le plus long — « Voir les
   réalisations », 147 px en capitales à 11 px. Sous chaque seuil, on retire
   ce qui coûte le plus de largeur : d'abord le picto, puis un demi-point de
   corps et le crénage. C'est ce qui évite le libellé sur deux lignes, qui
   fait toujours plus bricolé qu'un texte un peu plus petit. */
@media (max-width:620px){
  .heros .act,
  .final-b .act{ gap:10px; flex-wrap:nowrap }
  .heros .act .btn,
  .final-b .act .btn{ flex:1 1 0; min-width:0; gap:7px;
    padding:15px 12px; font-size:11px; letter-spacing:.035em }
  .heros .act .btn svg,
  .final-b .act .btn svg{ width:15px; height:15px }
}
@media (max-width:480px){
  .heros .act .btn svg,
  .final-b .act .btn svg{ display:none }
}
@media (max-width:400px){
  .heros .act .btn,
  .final-b .act .btn{ padding:15px 8px; font-size:9.5px; letter-spacing:0 }
  /* l'encart de contact ajoute son propre rembourrage : sur 360 px il prend
     52 px aux deux boutons, soit un demi-mot de libellé */
  .final-b{ padding-left:18px; padding-right:18px }
}
.rass{ display:flex; gap:26px; justify-content:center; flex-wrap:wrap; margin-top:30px;
  font-size:13px; color:var(--texte-2) }
.rass span::before{ content:"✓ "; color:var(--or-txt); font-weight:700 }

/* ---------- 18. Pied de page ----------
   Le pied a son propre jeu de couleurs, indépendant du thème de la page.
   En clair, il reste sur fond encre : posé sur la nappe pâle il paraissait
   flotter, sans début ni fin. Un pied sombre ferme la page — et il donne le
   dernier mot à l'identité de la marque, qui est sombre. */
.pied{ position:relative; overflow:hidden;
  padding:var(--section) 0 0;
  background:var(--pied-fond);
  box-shadow:inset 0 1px 0 var(--pied-filet) }
/* Un pied réduit à sa barre du bas — pages contact et mentions — n'a pas
   besoin du grand rembourrage de tête : ce serait un bloc sombre vide. */
.pied.mince{ padding-top:0 }
.pied > .env,
.pied > .trame ~ .env{ position:relative; z-index:1 }
.pied-g{ display:grid; grid-template-columns:2fr 1fr 1fr 1.3fr; gap:var(--gout);
  padding-bottom:clamp(42px,5vw,70px) }
@media (max-width:900px){ .pied-g{ grid-template-columns:1fr 1fr } }
/* Deux colonnes plutôt qu'une seule empilée : sur un téléphone, le pied
   passait de quatre blocs à quatre écrans de défilement. Le premier bloc —
   logo, description, réseaux — garde toute la largeur, il ne tiendrait pas
   dans une demi-colonne. */
@media (max-width:560px){
  .pied-g{ grid-template-columns:repeat(2,1fr); gap:34px var(--gout) }
  .pied-g > :first-child{ grid-column:1 / -1 }
}
.pied h4{ font-size:13px; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--pied-titre-k); margin:0 0 20px }
.pied .sig b{ color:var(--pied-titre) }
/* Le logo blanc, quel que soit le thème de la page : le fond est sombre ici.
   Le sélecteur vise img pour passer devant [data-theme="light"] .sig .clair,
   qui a la même spécificité mais arrive plus bas dans le fichier. */
.pied .sig img.clair{ display:none }
.pied .sig img.sombre{ display:block }
/* la couleur porte sur le li, pas sur le a : certaines lignes de la colonne
   contact sont du texte nu, et elles restaient en encre sur fond encre */
.pied ul{ display:grid; gap:12px }
.pied li{ font-size:14.5px; color:var(--pied-texte-2) }
.pied a{ font-size:14.5px; color:var(--pied-texte); transition:color .25s }
.pied a:hover{ color:var(--pied-lien) }
.pied .desc{ margin:20px 0 24px; font-size:14.5px; color:var(--pied-texte-2); max-width:32ch }
.pied .rs{ display:flex; gap:10px }
/* Bleu dès le repos, pas au survol : ce sont les deux seuls liens du pied
   qu'on veut voir. Le bleu ne dépend pas du thème — le fond du pied non plus. */
.pied .rs a{ width:38px; height:38px; border-radius:12px; display:grid; place-items:center;
  color:#fff; background:var(--bleu);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22), 0 6px 16px rgba(1,119,255,.32);
  transition:background .3s, transform .3s, box-shadow .3s }
.pied .rs a:hover{ background:#0A62D8; transform:translateY(-3px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28), 0 10px 24px rgba(1,119,255,.46) }
.pied .rs svg{ width:17px; height:17px }
.pied-b{ display:flex; gap:22px; flex-wrap:wrap; padding:22px 0 30px; font-size:13px;
  color:var(--pied-texte-2); box-shadow:inset 0 1px 0 var(--pied-filet) }
.pied-b .grow{ flex:1 }
.pied-b nav{ display:flex; gap:22px }
/* la trame du pied part du coin bas droit, comme sur l'encart de contact */
.pied .trame{ --trame-pt:rgba(255,255,255,.09) }

/* ---------- 19. Apparitions ---------- */
.rv{ opacity:0; transform:translateY(22px);
  transition:opacity .8s cubic-bezier(.2,.9,.2,1), transform .8s cubic-bezier(.2,.9,.2,1) }
.rv.vu{ opacity:1; transform:none }
.rv1{ transition-delay:.08s } .rv2{ transition-delay:.16s }
.rv3{ transition-delay:.24s } .rv4{ transition-delay:.32s }

@media (prefers-reduced-motion:reduce){
  .rv{ opacity:1 !important; transform:none !important; transition:none !important }
  .goutte::before{ animation:none !important }
  .piste{ scroll-behavior:auto }   /* le rail saute au lieu de glisser */
  .bandeau-piste{ animation:none }  /* le bandeau se fige sur le premier lot */
  *{ transition-duration:.01ms !important }
}

/* ---------- 20. Appel mobile ---------- */
/* Une pastille, pas une barre. La barre pleine largeur mangeait un bandeau
   en bas de chaque écran et se faisait prendre pour un bandeau de cookies.
   56 px de côté : au-dessus des 44 px minimum recommandés pour une cible
   tactile, sans occuper le pouce. */
.tel-mob{ display:none; position:fixed; right:16px; bottom:16px; z-index:90;
  width:56px; height:56px; border-radius:50%;
  place-items:center; color:#fff;
  background:linear-gradient(140deg,#3D7BFF,#0177FF 48%,#2B4CF5);
  box-shadow:0 10px 26px rgba(1,119,255,.46), inset 0 1px 0 rgba(255,255,255,.26);
  transition:transform .25s cubic-bezier(.2,.9,.2,1), box-shadow .25s }
.tel-mob svg{ width:23px; height:23px }
.tel-mob:active{ transform:scale(.93);
  box-shadow:0 6px 16px rgba(1,119,255,.4), inset 0 1px 0 rgba(255,255,255,.26) }
/* la marge du bas laisse respirer la dernière ligne du pied de page,
   que la pastille recouvrirait sinon */
@media (max-width:620px){ .tel-mob{ display:grid } body{ padding-bottom:24px } }
/* sous la barre d'adresse des navigateurs mobiles récents */
@supports (bottom: env(safe-area-inset-bottom)){
  @media (max-width:620px){
    .tel-mob{ bottom:calc(16px + env(safe-area-inset-bottom)) }
  }
}

/* ---------- 21. Pages de texte ---------- */
.txt-page{ padding:clamp(50px,6vw,80px) 0 var(--section) }
.txt-page .env{ max-width:800px }
.txt-page h1{ margin-bottom:14px }
.txt-page .maj{ font-family:var(--mono); font-size:11.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--texte-2); margin-bottom:48px }
.txt-page h2{ font-size:clamp(22px,2.4vw,29px); margin:48px 0 16px }
.txt-page h3{ font-size:18px; margin:28px 0 10px }
.txt-page p{ margin-bottom:15px }
.txt-page ul{ margin:0 0 20px; padding-left:22px; list-style:disc }
.txt-page li{ margin-bottom:9px }
.txt-page a{ color:var(--ciel) }
.txt-page a:hover{ text-decoration:underline }
.acompleter{ background:rgba(255,184,0,.18); color:var(--or); padding:2px 9px;
  border-radius:6px; font-family:var(--mono); font-size:.84em; font-weight:700 }

/* ---------- 22. Grain ---------- */
/* Un bruit très faible sur toute la page : il enlève l'aspect plastique
   des dégradés et donne de la matière. Invisible consciemment, senti. */
body::after{
  content:""; position:fixed; inset:0; z-index:200; pointer-events:none; opacity:var(--grain);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}


/* ---------- 23. Bascule de thème ---------- */
.bascule{
  width:44px; height:44px; border-radius:var(--r-btn); flex:0 0 auto;
  display:grid; place-items:center; position:relative; overflow:hidden;
  background:var(--surface-3); color:var(--titre);
  box-shadow:inset 0 1px 0 var(--reflet);
  transition:background .3s, transform .3s;
}
.bascule:hover{ background:var(--surface-2); transform:translateY(-2px) }
.bascule svg{ width:19px; height:19px; grid-area:1/1;
  transition:transform .45s cubic-bezier(.2,.9,.2,1), opacity .3s }
/* La lune sort quand le soleil entre, et inversement.
   L'état par défaut est celui du thème du site — le sombre, donc le soleil,
   puisque le bouton propose ce vers quoi on va. Le clair est l'exception. */
.bascule .lune{ opacity:0; transform:rotate(-90deg) scale(.5) }
.bascule .soleil{ opacity:1; transform:none }
[data-theme="light"] .bascule .soleil{ opacity:0; transform:rotate(90deg) scale(.5) }
[data-theme="light"] .bascule .lune{ opacity:1; transform:none }

/* le logo suit le thème — blanc par défaut, bleu en clair */
.sig .clair{ display:none }
.sig .sombre{ display:block }
[data-theme="light"] .sig .sombre{ display:none }
[data-theme="light"] .sig .clair{ display:block }

@media (max-width:1080px){ .bascule{ margin-left:auto; width:42px; height:42px } }

/* ============================================================
   24. La page contact
   ============================================================ */
.contact-page{ padding-top:clamp(46px,6vw,80px) }
.contact-page h1{ font-size:clamp(30px,4.4vw,54px) }

/* Une seule colonne, centrée, assez étroite pour qu'on lise une ligne d'un
   seul regard. Au-delà de ~760 px, un champ devient un couloir. */
.contact-page #formulaire{ max-width:640px; margin:0 auto;
  padding:clamp(26px,3.2vw,42px) }
.contact-page .centre .chapo{ max-width:56ch }

.contact-direct{ margin-top:clamp(24px,3vw,34px); text-align:center;
  font-size:14.5px; color:var(--texte-2) }
.contact-direct a{ color:var(--lien); font-weight:600 }
.contact-direct a:hover{ text-decoration:underline }

/* ---------- le formulaire ---------- */
.form{ display:grid; gap:clamp(16px,1.8vw,20px) }
.champ{ display:grid; gap:8px }
.champ-duo{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(14px,1.6vw,18px) }
@media (max-width:560px){ .champ-duo{ grid-template-columns:1fr } }

.champ label{ font-size:13.5px; font-weight:600; color:var(--titre);
  display:flex; align-items:baseline; gap:7px }
.req{ color:var(--or-txt) }
.fac{ font-size:11.5px; font-weight:500; color:var(--texte-3); letter-spacing:.01em }

/* Aucune bordure ici non plus : le champ est un creux, tenu par son ombre
   interne. C'est la même grammaire que les cartes, en négatif. */
.champ input,
.champ select,
.champ textarea{
  width:100%; font-family:var(--sans); font-size:15px; color:var(--titre);
  background:var(--pastille); border:0; border-radius:var(--r);
  padding:14px 16px; outline:0;
  box-shadow:inset 0 0 0 1px transparent;
  transition:box-shadow .25s, background .25s;
}
.champ textarea{ resize:vertical; min-height:130px; line-height:1.6 }
.champ input::placeholder,
.champ textarea::placeholder{ color:var(--texte-3) }
.champ input:focus,
.champ select:focus,
.champ textarea:focus{
  background:var(--surface-2);
  box-shadow:inset 0 0 0 2px var(--lien), 0 0 0 4px var(--puce-fond);
}
/* la flèche du menu déroulant, dessinée en fond pour rester identique partout */
.champ select{
  appearance:none; -webkit-appearance:none; cursor:pointer; padding-right:42px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 21px) calc(50% + 1px), calc(100% - 15px) calc(50% + 1px);
  background-size:6px 6px, 6px 6px;
  background-repeat:no-repeat;
}
.champ select option{ background:var(--menu-fond); color:var(--titre) }

/* le message d'erreur n'apparaît qu'une fois rempli par le script */
.err{ font-size:12.5px; color:var(--erreur); min-height:0 }
.err:empty{ display:none }
.champ.faux input,
.champ.faux textarea{ box-shadow:inset 0 0 0 2px var(--erreur) }

/* le piège à robots : hors écran, jamais dans l'ordre de tabulation */
.miel{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden }

.envoyer{ width:100%; justify-content:center }
.envoyer[disabled]{ opacity:.6; pointer-events:none }

.form-etat{ font-size:14px; line-height:1.6; padding:14px 16px; border-radius:var(--r);
  background:var(--pastille); color:var(--texte) }
.form-etat:empty{ display:none }
.form-etat.ok{ color:var(--titre); box-shadow:inset 0 0 0 2px var(--succes) }
.form-etat.ko{ color:var(--titre); box-shadow:inset 0 0 0 2px var(--erreur) }
.form .rass{ margin-top:6px }


