/* ==========================================================================
   Layerly — feuille de style unique
   Palette et typographie definies dans le vault : identite-visuelle.md
   Regle du vert : la menthe ne marque que deux choses, la couche active du
   logo et les prix. Les boutons sont en creme, jamais en menthe.
   ========================================================================== */

/* Work Sans, hebergee ici plutot que chez Google. Charger une police depuis
   un domaine tiers transmet l'adresse IP de chaque visiteur a ce tiers, ce qui
   constitue une communication de donnees a l'etranger a declarer. Un fichier
   de 49 Ko regle la question et supprime une requete externe au passage.
   Fichier variable : un seul fichier couvre les graisses 400 a 700.
   Licence SIL Open Font 1.1, texte dans gabarit/polices/OFL.txt. */
@font-face{
  font-family:"Work Sans";
  src:url("/polices/work-sans.woff2") format("woff2");
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

:root{
  --fleche-sortante:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.2 1h5.8v5.8'/%3E%3Cpath d='M9 1L1 9'/%3E%3C/g%3E%3C/svg%3E");
  --encre:      #171A20;
  --encre-haut: #1E222B;
  --encre-bord: #0E1014;
  --os:         #EDE7DB;
  --os-doux:    #9AA0AB;
  --menthe:     #5FB39A;
  --ligne:      #2C313C;

  /* Un cran plus clair que --os-doux, pour les listes de faits : contraste
     9,4 contre 6,1, et surtout une teinte differente de la prose autour. */
  --os-vif:     #C2C7D0;
  /* Le rouge des limites. Meme teinte que les messages d'erreur du
     formulaire : une seule idee de « attention » sur tout le site. */
  --rouge:      #E09A9E;
  --rouge-trait:#b4646a;

  /* Une seule courbe pour tout le site, longue traine : le mouvement part
     franchement puis s'eteint lentement, ce qui se lit comme de la douceur
     alors qu'une courbe symetrique se lit comme un a-coup.
     Les durees vivent ici aussi, pour pouvoir tout ralentir d'un cran depuis
     un seul endroit. */
  --courbe:      cubic-bezier(.22, 1, .30, 1);
  /* Ancien nom, garde pour ne pas toucher cinquante declarations : c'est la
     meme courbe. Deux courbes voisines donnaient deux rythmes a peine
     differents, qui se lisaient comme un defaut plutot que comme une nuance. */
  --courbe-fine: var(--courbe);
  --t-lent:  1.15s;   /* arrivee d'un bloc au defilement */
  --t-moyen:  .55s;   /* changements de couleur, filets */
  --t-court:  .32s;   /* details tres courts */
  --t-eclair: .12s;   /* retour immediat : appui, mouvement reduit */

  /* Le survol a sa propre duree, sur la courbe commune. C'est la seule
     valeur a changer pour rendre tout le site plus ou moins vif au survol. */
  --t-survol:     .55s;
  --courbe-survol: var(--courbe);

  /* Signal de survol commun a tout le site.
     Amplitude calee sur celle du site provisoire, volontairement discrete :
     l'element se souleve juste assez pour qu'on le sente, pas au point de
     quitter sa place. Monter ces deux valeurs suffit a tout amplifier. */
  --leve:    -3px;    /* blocs : boutons, cartes, lignes cliquables */
  --leve-s:  -2px;    /* liens en ligne : menu, pied de page */
  /* Tous les autres mouvements de survol se calculent depuis --leve, pour
     qu'une seule valeur commande l'amplitude de tout le site. */
  --glisse:  calc(var(--leve) * -1);        /* 3 px vers la droite */
  --glisse-l:calc(var(--leve) * -1.5);      /* 4,5 px, pour une fleche */
  --anneau:  0 0 0 3px rgba(237, 231, 219, .15);
  --anneau-net: 0 0 0 2px var(--os);

  --large:  1100px;
  /* Marge laterale du contenu. Tout ce qui doit deborder de la colonne se
     calcule depuis elle, sinon un debordement ecrit en dur finit par sortir
     de la page le jour ou la marge se resserre. */
  --marge:  22px;
  /* Trois rayons plutot qu'un seul applique partout : les panneaux, les
     petits elements et les images n'ont pas la meme echelle, les arrondir
     identiquement donne le rendu lisse et sans intention des gabarits. */
  --rayon:  12px;   /* panneaux et cartes */
  --rayon-s: 6px;   /* petits blocs, etiquettes carrees */
  --rayon-l: 12px;  /* cadres d'images : meme arrondi que les panneaux */
  --pas:    clamp(56px, 9vw, 104px);
}

*{box-sizing:border-box;margin:0;padding:0}
html{
  -webkit-text-size-adjust:100%;scroll-behavior:smooth;
  /* L'en-tete collant mesure 63 px au doigt et 68 px en grand ecran : sans
     cette reserve, une ancre (/matieres/#m-petg, un onglet vise par
     l'adresse) posait son titre dessous. 16 px d'air en plus. */
  scroll-padding-top:84px;
  /* La place de la barre de defilement reste reservee : ouvrir une photo
     bloque le defilement, la barre disparaissait et toute la page glissait
     de 15 px sur un ecran d'ordinateur. Sans effet sur les barres flottantes
     des telephones. */
  scrollbar-gutter:stable;
  /* Les surfaces que le navigateur dessine seul portent aussi la charte. */
  scrollbar-color:var(--ligne) var(--encre);
}
::selection{background:var(--os);color:var(--encre)}

/* Un halo de lumiere chaude tombe du haut de chaque page, comme l'eclairage
   dans l'enceinte de l'imprimante. Creme et non menthe : la menthe reste au
   logo et aux prix. Il se pose en haut a droite, la ou l'accroche de l'accueil
   laisse la page vide, et s'eteint avant le premier contenu dense : le texte
   reste sur l'encre. Le grain, par-dessus, casse les paliers du degrade.
   Contraste : au coeur du halo, --os-doux tomberait a 3:1, mais ce coeur est
   sous l'en-tete, qui a son propre fond ; aucun texte n'y est pose a nu. Mesure
   le 21.09.2026 sur 15 pages, en 1280 et 375 px : le texte le plus faible pose
   sur le halo reste a 4,85:1. Toute hausse d'intensite se remesure. */
body{
  /* Ancre du calque de remplissage (body::after) : sans elle, il se calerait
     sur la fenetre et allongerait les pages plus courtes que lui. */
  position:relative;
  background-color:var(--encre);
  background-image:
    radial-gradient(ellipse 46% 58% at 82% 0%, rgba(237,231,219,.22), transparent 70%),
    radial-gradient(ellipse 100% 80% at 72% 0%, rgba(237,231,219,.06), transparent 80%);
  background-size:100% 920px;
  background-repeat:no-repeat;
  color:var(--os);
  font-family:"Work Sans","Segoe UI",system-ui,-apple-system,sans-serif;
  font-size:clamp(1rem,.96rem + .2vw,1.06rem);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}

img{max-width:100%;height:auto;display:block}
a{color:inherit}

/* Une couche de grain tres legere sur tout le site. C'est ce qui separe le
   plus nettement une surface imprimee d'un aplat de gabarit, et ca ne coute
   qu'un filtre SVG en ligne : aucune requete, aucune image. */
.grain{
  position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.035;
  /* Bruit plus fin et tuile plus grande : a l'ancienne frequence, le grain
     devenait visible en petits carres sur un ecran a forte densite. */
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='2'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size:150px 150px;
}
/* Sur un telephone, la meme lumiere plus large et plus basse : a 52 % de
   375 px, l'ellipse devenait un trait vertical colle au bord. */
@media (max-width:560px){
  body{
    background-image:
      radial-gradient(ellipse 90% 44% at 88% 0%, rgba(237,231,219,.2), transparent 70%),
      radial-gradient(ellipse 130% 60% at 70% 0%, rgba(237,231,219,.06), transparent 80%);
    background-size:100% 700px;
  }
}
/* ---------- couches ----------
   Les lignes de couche, celles qu'on voit sur le flanc de toute piece imprimee
   et que le logo reprend en quatre strates. Il n'existe
   que dans la lumiere : chaque calque porte le meme masque que la lumiere qu'il
   accompagne, en plus serre, si bien que le motif apparait la ou elle tombe et
   s'efface avec elle. Hors de la lumiere, l'encre reste nue.
   Un simple degrade repete : un trait de 1 px toutes les 7 px, sans image ni
   requete.
   Doses mesurees le 21.09.2026, dans le pire cas d'un texte pose pile sur une
   ligne du motif, lumieres cumulees : 10 % sous le halo en grand ecran, 5 % sur
   telephone, 3,5 % et 3 % dans la lueur. Au-dela, un texte gris passe sous 4,5:1. */
body::after,.lueur::before{
  content:"";pointer-events:none;
  background-image:repeating-linear-gradient(to bottom,
    #EDE7DB 0 1px, transparent 1px 7px);
}
/* Sous le halo du haut : colle au haut du document, il defile avec la page. */
body::after{
  position:absolute;top:0;left:0;right:0;height:920px;max-height:100%;z-index:0;opacity:.1;
  -webkit-mask-image:radial-gradient(ellipse 34% 46% at 82% 0%, #000, transparent);
  mask-image:radial-gradient(ellipse 34% 46% at 82% 0%, #000, transparent);
}
/* Dans la lueur d'accompagnement : il herite de son opacite, donc de son entree
   et de sa sortie au defilement. */
.lueur::before{
  position:absolute;inset:0;opacity:.035;
  -webkit-mask-image:radial-gradient(ellipse 22% 36% at 6% 58%, #000, transparent);
  mask-image:radial-gradient(ellipse 22% 36% at 6% 58%, #000, transparent);
}
@media (max-width:560px){
  body::after{
    height:700px;opacity:.05;
    -webkit-mask-image:radial-gradient(ellipse 50% 30% at 90% 0%, #000, transparent);
    mask-image:radial-gradient(ellipse 50% 30% at 90% 0%, #000, transparent);
  }
  .lueur::before{
    opacity:.03;
    -webkit-mask-image:radial-gradient(ellipse 55% 28% at 0% 62%, #000, transparent);
    mask-image:radial-gradient(ellipse 55% 28% at 0% 62%, #000, transparent);
  }
}

/* Lueur d'accompagnement : fixe a l'ecran, cote gauche pour repondre au halo
   du haut qui est a droite. Le script regle son opacite selon le defilement
   (voir build.py) ; sans script, elle reste a 0. Sous le grain, qui casse les
   paliers du degrade, et sous tout ce qui se lit.
   Elle passe derriere n'importe quel texte pose sur la page : 10 % au plus fort
   est la limite choisie. --os-doux y garde 5,1:1, les prix en menthe 5,4:1. */
.lueur{
  position:fixed;inset:0;z-index:0;pointer-events:none;opacity:0;
  background:radial-gradient(ellipse 40% 60% at 6% 58%, rgba(237,231,219,.10), transparent 70%);
}
@media (max-width:560px){
  .lueur{background:radial-gradient(ellipse 85% 42% at 0% 62%, rgba(237,231,219,.10), transparent 70%)}
}
/* Le grain reste derriere tout ce qui se clique ou se lit. */
.entete,main,.pied,.saut-contenu{position:relative;z-index:2}

.contenu{width:100%;max-width:var(--large);margin-inline:auto;padding-inline:var(--marge)}
.section{padding-block:var(--pas)}
.section--haut{background:var(--encre-haut)}
/* Le bloc de fin de page cumulait son espacement avec celui de la section
   precedente, ce qui doublait le vide. Il en garde un plus court : le
   supprimer entierement collait la boite a la section du dessus, et sur
   l'accueil cette section a exactement la meme teinte que la boite. */
.section--appel{padding-top:calc(var(--pas) * .6)}

/* ---------- titres ---------- */
h1,h2,h3{line-height:1.15;font-weight:400;letter-spacing:-.01em}
h1{font-size:clamp(2.1rem,1.5rem + 3vw,3.5rem)}
h2{font-size:clamp(1.6rem,1.25rem + 1.7vw,2.3rem)}
h3{font-size:clamp(1.12rem,1.05rem + .4vw,1.3rem)}

/* .surtitre ne porte plus qu'un fil d'Ariane, jamais une etiquette au-dessus
   d'un titre. Les capitales et l'interlettrage large venaient de cet ancien
   usage : sur un chemin de navigation ils ralentissent la lecture et donnent
   au bloc l'allure d'une pastille de gabarit. Un chemin se lit, il ne s'annonce
   pas, donc taille legerement superieure et casse normale. */
.surtitre{
  font-size:.84rem;color:var(--os-doux);margin-bottom:14px;
}
.chapeau{max-width:60ch;color:var(--os-doux);margin-top:16px}
.centre{text-align:center}
/* .appel se declare centre : il doit donc beneficier des memes aides que
   .centre, sans quoi seuls les titres (qui ont leur propre marge auto) le
   sont vraiment, et le bouton reste cale a gauche. */
.centre .chapeau,.appel .chapeau{margin-inline:auto}

/* ---------- en-tete ---------- */
.entete{
  position:sticky;top:0;z-index:50;
  background:rgba(23,26,32,.92);
  backdrop-filter:blur(10px);
  border-bottom:1px solid var(--ligne);
}
.entete .contenu{
  display:flex;align-items:center;justify-content:space-between;
  gap:18px;flex-wrap:wrap;padding-block:14px;
}
.marque{
  display:flex;align-items:center;gap:11px;text-decoration:none;flex-shrink:0;
  transition:transform var(--t-survol) var(--courbe-survol);
}
.marque:hover{transform:translateY(var(--leve-s))}
.marque svg{width:22px;height:auto}
.marque span{font-size:1.22rem}

.menu__bouton{display:none}

.nav{display:flex;gap:6px;flex-wrap:wrap}
.nav__lien{
  text-decoration:none;color:var(--os-doux);
  padding:7px 12px;border-radius:999px;font-size:.94rem;
  transition:color var(--t-survol) var(--courbe-survol),
             background var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol);
}
.nav__lien:hover{color:var(--os);background:var(--encre-haut);transform:translateY(var(--leve-s))}
.nav__lien[aria-current="page"]{color:var(--os);background:var(--encre-haut)}
/* On est sur une sous-page : l'entree qui la porte s'eclaire sans fond, pour
   ne pas se confondre avec la page courante elle-meme. */
.nav__lien--parent{color:var(--os)}

/* ---------- menu deroulant ----------
   Une carte qui tombe sous l'entree survolee. Elle remplace une bande pleine
   largeur, qui promenait le regard sur toute la page pour montrer deux ou
   trois liens. Meme fond --encre-haut que le panneau mobile : les deux formes
   du menu restent le meme objet.
   Les deux dernieres entrees ouvrent leur carte vers la gauche : sur un ecran
   de 900 px, une carte calee a gauche sous Contact sortirait de la page.
   L'etat ouvert est pose par le script (.nav__groupe--ouvert), qui gere les
   delais ; sans script, le survol et le focus suffisent. */
.nav__groupe{display:flex;position:relative}
.nav__panneau{
  position:absolute;top:calc(100% + 22px);left:0;z-index:1;
  min-width:260px;max-width:320px;
  background:var(--encre-haut);border:1px solid var(--ligne);border-radius:var(--rayon);
  /* Une ombre qui tombe, et un filet de lumiere sur l'arete haute : la carte
     se detache de l'en-tete au lieu de s'y coller. */
  box-shadow:0 24px 48px -24px rgba(0,0,0,.8),inset 0 1px 0 rgba(237,231,219,.06);
  opacity:0;visibility:hidden;transform:translateY(-6px);transform-origin:top left;
  /* Fermeture : le fondu d'abord, la visibilite ensuite, pour que la carte
     sorte aussi de la tabulation une fois invisible. */
  transition:opacity var(--t-court) var(--courbe),transform var(--t-court) var(--courbe),
             visibility 0s linear var(--t-court);
}
.nav__groupe:nth-last-child(-n+2) .nav__panneau{left:auto;right:0;transform-origin:top right}
/* Pont invisible entre le lien et la carte : le pointeur qui descend ne
   traverse jamais un vide qui refermerait le menu. */
.nav__panneau::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:22px}
.nav__groupe--ouvert .nav__panneau,
html:not(.js) .nav__groupe:hover .nav__panneau,
html:not(.js) .nav__groupe:focus-within .nav__panneau{
  opacity:1;visibility:visible;transform:none;transition-delay:0s;
}
/* D'une entree a l'autre, la nouvelle carte s'affiche sans refaire le fondu. */
.nav--direct .nav__panneau{transition:none}
.nav__liste{list-style:none;display:grid;gap:2px;padding:6px}
.nav__liste a{
  display:grid;gap:2px;padding:10px 12px;
  border-radius:var(--rayon-s);text-decoration:none;
  transition:background var(--t-survol) var(--courbe-survol);
}
.nav__liste a:hover,.nav__liste a[aria-current="page"]{background:var(--encre)}
.nav__titre{color:var(--os);font-size:.94rem;line-height:1.3}
.nav__detail{color:var(--os-doux);font-size:.84rem;line-height:1.4}

/* ---------- boutons ---------- */
/* Un bouton peut etre un <a> ou un <button>. Sans les quatre declarations de
   neutralisation ci-dessous, le <button> garde le fond gris clair et la police
   systeme que le navigateur donne d'office : sur le fond sombre du site, le
   bouton apparait blanc et son libelle creme devient illisible. Le <a> voisin,
   lui, est correct — d'ou deux boutons cote a cote qui ne se ressemblent pas. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  padding:14px 26px;border-radius:999px;
  background:transparent;cursor:pointer;-webkit-appearance:none;appearance:none;
  text-decoration:none;font:inherit;font-size:1rem;line-height:1;
  border:1px solid var(--os);
  transition:opacity var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol),
             background var(--t-survol) var(--courbe-survol),
             border-color var(--t-survol) var(--courbe-survol),
             box-shadow var(--t-survol) var(--courbe-survol);
}
.btn:hover{opacity:1;transform:translateY(var(--leve));box-shadow:var(--anneau)}
.btn--vide:hover{background:var(--encre-haut)}
/* L'enfoncement au clic ramene le bouton sous sa position de repos : sans lui,
   un bouton qui monte de 5 px ne donne aucun retour au moment ou on appuie. */
.btn:active{transform:translateY(0);transition-duration:var(--t-eclair)}
.btn--plein{background:var(--os);color:var(--encre);position:relative}
/* La buse : au survol du bouton principal, un point de lumiere fait une fois le
   tour de son contour, comme une buse qui trace le perimetre avant de remplir.
   Un tour, puis il s'eteint : rien ne tourne en boucle. L'angle est une
   propriete declaree (@property) pour pouvoir s'animer ; un navigateur qui ne
   la connait pas montre simplement l'arc immobile. */
@property --buse{syntax:'<angle>';inherits:false;initial-value:0deg}
.btn--plein:not(:disabled):not([aria-disabled="true"]):not([aria-busy="true"])::before{
  content:"";position:absolute;inset:-5px;border-radius:999px;pointer-events:none;
  padding:1.5px;opacity:0;
  background:conic-gradient(from var(--buse), transparent 0deg 290deg,
                            rgba(237,231,219,.95) 352deg, transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
}
@media (prefers-reduced-motion: no-preference){
  .btn--plein:focus-visible::before{animation:buse 1.2s var(--courbe-fine) both}
}
@media (prefers-reduced-motion: no-preference) and (hover:hover){
  .btn--plein:hover::before{animation:buse 1.2s var(--courbe-fine) both}
}
@keyframes buse{
  0%{--buse:0deg;opacity:0}
  8%{opacity:1}
  80%{opacity:1}
  100%{--buse:360deg;opacity:0}
}
.btn--vide{color:var(--os)}
/* Troisieme niveau : ni fond ni bordure au repos, pour une action qui accompagne
   sans concurrencer les deux autres. La bordure apparait au survol, sinon le
   bouton n'a aucune limite visible au moment ou on le vise. */
.btn--fantome{border-color:transparent;color:var(--os)}
.btn--fantome:hover{background:var(--encre-haut);border-color:var(--ligne)}
/* Variante compacte : plus etroite, jamais plus basse. La cible tactile reste
   a 44 px, le seul chiffre qui ne se negocie pas sur un site ou la visite vient
   d'Instagram, donc du pouce. */
.btn--petit{padding:10px 18px;font-size:.92rem;min-height:44px}

/* ---------- boutons : indisponible et en cours ----------
   Deux etats qui manquaient. Un bouton desactive se distinguait en rien d'un
   bouton actif, et un envoi de formulaire ne donnait aucun signe de vie.
   Les deux couvrent <button disabled> et <a aria-disabled="true"> : le lien
   ne connait pas :disabled, et la moitie des boutons du site sont des liens. */
.btn:disabled,.btn[aria-disabled="true"]{
  /* Pas d'opacite : elle eteint le contraste sous le seuil AA. Une couleur
     explicite garde 5,0:1 en plein et 6,6:1 en vide. */
  color:var(--os-doux);border-color:var(--ligne);background:transparent;
  cursor:not-allowed;
}
.btn--plein:disabled,.btn--plein[aria-disabled="true"]{background:var(--ligne)}
.btn:disabled:hover,.btn[aria-disabled="true"]:hover{
  transform:none;box-shadow:none;background:transparent;
}
.btn--plein:disabled:hover,.btn--plein[aria-disabled="true"]:hover{background:var(--ligne)}
.btn--plein:disabled::after,.btn--plein[aria-disabled="true"]::after{content:none}

.btn[aria-busy="true"]{cursor:progress;pointer-events:none}
.btn[aria-busy="true"]::before{
  content:"";width:15px;height:15px;flex-shrink:0;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;
  animation:btn-tourne .7s linear infinite;
}
.btn--plein[aria-busy="true"]::after{content:none}
@keyframes btn-tourne{to{transform:rotate(360deg)}}
.actions{display:flex;flex-wrap:wrap;gap:14px;margin-top:30px}
.centre .actions,.appel .actions{justify-content:center}

/* ---------- accroche ---------- */
.accroche{padding-block:clamp(60px,10vw,120px)}
.accroche h1{max-width:16ch}
.accroche .chapeau{font-size:clamp(1.05rem,1rem + .4vw,1.22rem)}

/* ---------- bandeau de reassurance ---------- */
.reassurance{
  border-block:1px solid var(--ligne);
  background:var(--encre-haut);
}
/* Quatre coches identiques alignees etaient une signature de gabarit.
   Un filet vertical entre les colonnes suffit a separer, et la premiere ligne
   se lit d'abord parce qu'elle est plus claire, pas parce qu'une icone la
   designe. */
.reassurance ul{
  list-style:none;display:grid;gap:22px 0;
  grid-template-columns:repeat(auto-fit,minmax(min(215px, 100%), 1fr));
  padding-block:30px;font-size:.94rem;
}
.reassurance li{display:grid;gap:2px;padding-inline:26px;border-left:1px solid var(--ligne)}
.reassurance li:first-child{padding-left:0;border-left:none}
.reassurance b{color:var(--os);font-weight:400}
.reassurance span{color:var(--os-doux)}
@media (max-width:700px){
  .reassurance li{padding-inline:0;border-left:none;
    border-top:1px solid var(--ligne);padding-top:16px}
  .reassurance li:first-child{border-top:none;padding-top:0}
}

/* ---------- les trois voies (accueil) ---------- */
.voies{display:grid;gap:0;margin-top:40px;border-top:1px solid var(--ligne)}
.voie{
  display:grid;grid-template-columns:auto 1fr;gap:clamp(18px,4vw,44px);align-items:baseline;
  padding-block:clamp(22px,3vw,32px);border-bottom:1px solid var(--ligne);
  text-decoration:none;position:relative;
  transition:transform var(--t-survol) var(--courbe-survol);
}
/* La ligne n'a pas de cadre : son contour, c'est un fond qui se pose derriere,
   debordant sur les marges pour qu'elle paraisse sortir de la colonne. */
.voie::after{
  content:"";position:absolute;inset:0 calc(var(--marge) * -.8);
  z-index:-1;border-radius:var(--rayon);
  background:var(--encre-haut);opacity:0;
  transition:opacity var(--t-survol) var(--courbe-survol);
}
.voie:hover{transform:translateY(var(--leve-s))}
.voie:hover::after{opacity:1}
/* Le numero grossit et s'eclaircit au survol : le seul mouvement de ce bloc,
   il indique la ligne active sans deplacer une seule autre chose. */
.voie__n{
  font-size:clamp(1.5rem,1.1rem + 1.4vw,2.1rem);line-height:1;color:var(--ligne);
  font-variant-numeric:tabular-nums;
  transition:color var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol);
}
/* Le numero monte et avance : deux axes plutot qu'un, la ligne entiere semble
   se tendre vers la droite sans qu'aucun texte ne bouge. */
.voie:hover .voie__n{color:var(--menthe);transform:translate(var(--glisse),var(--leve))}
.voie__corps{display:grid;gap:6px}
.voie__corps p{color:var(--os-doux);max-width:58ch}
.voie__suite{
  font-size:.82rem;letter-spacing:.14em;text-transform:uppercase;color:var(--os-doux);
  margin-top:4px;display:inline-block;
  transition:color var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol);
}
.voie:hover .voie__suite{color:var(--os);transform:translateX(var(--glisse-l))}
/* Le corps de la ligne se decale d'un cheveu, assez pour que la ligne survolee
   se detache des deux autres sans qu'on sache dire pourquoi. */
.voie__corps{transition:transform var(--t-survol) var(--courbe-survol)}
.voie:hover .voie__corps{transform:translateX(var(--glisse))}

/* ---------- grilles de cartes ---------- */
.grille{
  display:grid;gap:20px;margin-top:38px;
  grid-template-columns:repeat(auto-fill,minmax(min(268px, 100%), 1fr));
}
.carte{
  background:var(--encre-haut);
  border:1px solid var(--ligne);
  border-radius:var(--rayon);
  overflow:hidden;
  display:flex;flex-direction:column;
  text-decoration:none;
  transition:border-color var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol),
             box-shadow var(--t-survol) var(--courbe-survol);
}
/* Le souleve au survol. La carte de piece n'est plus un <a> : son lien tient
   sur le titre et s'etire sur le bloc. On vise donc la carte qui contient un
   lien, ce qui laisse immobile le cadre d'attente, qui lui ne mene nulle part.
   La carte photo, elle, est restee un <a> : les deux selecteurs coexistent. */
.carte:has(.carte__lien):hover,a.carte:hover{
  border-color:var(--os-doux);
  transform:translateY(var(--leve));
  box-shadow:var(--anneau);
}
.carte__visuel{
  aspect-ratio:4/3;background:var(--encre);
  display:flex;align-items:center;justify-content:center;
  border-bottom:1px solid var(--ligne);
  /* Le rognage appartient au conteneur direct de l'image, pas a la carte :
     sinon c'est le compositeur qui decoupe la photo animee, sans lissage. */
  border-radius:calc(var(--rayon) - 1px) calc(var(--rayon) - 1px) 0 0;
  overflow:hidden;
}
.carte__visuel img{
  width:100%;height:100%;object-fit:cover;
  border-radius:calc(var(--rayon) - 1px) calc(var(--rayon) - 1px) 0 0;
}
.carte__visuel{position:relative}
.carte__corps{padding:20px;display:flex;flex-direction:column;gap:9px;flex:1}
.carte__corps h2,.carte__corps h3{font-size:1.12rem;line-height:1.25}
.carte__note{color:var(--os-vif);font-size:.92rem;flex:1}

/* ---------- carte photo, cliquable pour agrandir ---------- */
/* Pas de corps de texte sous l'image : les quatre coins sont arrondis. */
.carte--photo .carte__visuel{
  border-bottom:none;
  border-radius:calc(var(--rayon) - 1px);
}
.carte--photo .carte__visuel img{border-radius:calc(var(--rayon) - 1px)}

/* La loupe n'apparait qu'au survol : elle annonce l'agrandissement sans
   encombrer la grille au repos. */
.loupe{
  position:absolute;right:10px;bottom:10px;
  width:32px;height:32px;border-radius:var(--rayon-s);
  display:grid;place-items:center;
  background:rgba(23,26,32,.72);color:var(--os);
  border:1px solid rgba(237,231,219,.22);
  opacity:0;transform:translateY(4px);
  transition:opacity var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol);
}
.loupe svg{width:15px;height:15px}
.carte--photo{position:relative}
.carte--photo .carte__visuel{position:relative}
.carte--photo:hover .loupe,.carte--photo:focus-visible .loupe{opacity:1;transform:none}

/* ---------- visionneuse ---------- */
.visionneuse{
  /* Bande reservee en haut et en bas : le bouton de fermeture mesure 44 px
     plus sa marge, la legende s'ecrit sous la photo. Sans cette reserve les
     trois se superposent. */
  --bande:clamp(78px,9vh,100px);
  position:fixed;inset:0;z-index:200;
  display:grid;place-items:center;
  padding:var(--bande) clamp(16px,4vw,48px);
  background:rgba(14,16,20,.92);
  backdrop-filter:blur(6px);
}
.visionneuse[hidden]{display:none}
.visionneuse img{
  /* La hauteur se borne sur la fenetre, pas sur la grille : un pourcentage
     se calculerait contre une piste que la photo dimensionne elle-meme, et
     ne retiendrait rien. Une photo verticale depassait ainsi de 900 px. */
  max-width:100%;
  max-height:calc(100vh - var(--bande) * 2);
  max-height:calc(100dvh - var(--bande) * 2);
  width:auto;height:auto;
  border-radius:var(--rayon-l);
  box-shadow:0 40px 90px -50px #000;
}
.visionneuse__fermer{
  position:absolute;top:clamp(12px,2.5vw,26px);right:clamp(12px,2.5vw,26px);
  width:44px;height:44px;border-radius:999px;cursor:pointer;
  background:rgba(23,26,32,.8);color:var(--os);border:1px solid var(--ligne);
  font:inherit;font-size:1.2rem;line-height:1;
  display:grid;place-items:center;
  transition:transform var(--t-survol) var(--courbe-survol),
             border-color var(--t-survol) var(--courbe-survol),
             box-shadow var(--t-survol) var(--courbe-survol);
}
.visionneuse__fermer:hover{
  border-color:var(--os);transform:translateY(var(--leve-s));box-shadow:var(--anneau);
}
.visionneuse__legende{
  position:absolute;left:0;right:0;bottom:clamp(12px,3vw,28px);
  text-align:center;color:var(--os-doux);font-size:.88rem;padding-inline:22px;
}
@media (prefers-reduced-motion: no-preference){
  .visionneuse{animation:voile var(--t-court) var(--courbe) both}
  .visionneuse img{animation:photo calc(var(--t-court) * 1.2) var(--courbe) both}
  @keyframes voile{from{opacity:0}}
  @keyframes photo{from{opacity:0;transform:scale(.97)}}
}

/* placeholder quand la photo n'existe pas encore */
.attente{
  width:100%;height:100%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:12px;color:var(--os-doux);font-size:.8rem;letter-spacing:.14em;
  text-transform:uppercase;
}
.attente svg{width:38px;opacity:.5}

/* ---------- lien etire sur tout un bloc ----------
   Le <a> tient sur le titre, ce qui donne un nom de lien court et laisse le
   texte selectionnable ; le pseudo-element rend le bloc entier cliquable. */
.carte__lien,.voie__lien{text-decoration:none;color:inherit}
.carte__lien::after,.voie__lien::after{content:"";position:absolute;inset:0;z-index:2}
.voie{position:relative}

/* ---------- prose d'accueil ----------
   Un cran en dessous du texte courant : ce bloc explique, il n'annonce pas.
   La colonne est calee sur celle du chapeau, autour de 60 signes par ligne.
   Au-dela, l'oeil retrouve mal le debut de la ligne suivante et le bloc se lit
   comme un pave, quelle que soit la taille des lettres. */
.prose{display:grid;gap:16px;max-width:58ch;margin-top:24px}
.prose p{color:var(--os-doux);font-size:.94rem;line-height:1.7}

/* ---------- galerie ----------
   Des pieces imprimees montrees a titre d'exemple. La legende porte le credit
   de l'auteur du modele, ce que les licences Creative Commons exigent. */
.galerie{
  display:grid;gap:clamp(16px,2.4vw,26px);margin-top:30px;
  grid-template-columns:repeat(auto-fill,minmax(min(230px, 100%), 1fr));
}
.galerie__piece{display:grid;gap:10px}
.galerie__piece figcaption{display:grid;gap:2px}
.galerie__piece b{font-weight:400;line-height:1.3}
.galerie__note{color:var(--os-vif);font-size:.86rem}
/* Matiere, couleur, duree : des faits courts, separes par un point median.
   La pastille reprend celle du nuancier, meme source, meme teinte. */
.galerie__faits{color:var(--os-vif);font-size:.86rem;display:flex;flex-wrap:wrap;gap:4px 0}
.galerie__fait{display:inline-flex;align-items:center;gap:5px}
.galerie__fait + .galerie__fait::before{content:"·";margin:0 7px;color:var(--os-doux)}
.galerie__fait .pastille{width:10px;height:10px}
/* Le lien de matiere est un lien isole, pas un mot dans une phrase : il doit
   se viser au doigt. Le remplissage agrandit la zone touchable, la marge
   negative de meme valeur empeche la ligne de grandir. */
.galerie__fait .lien-guide{padding-block:11px;margin-block:-11px}
.galerie__credit{color:var(--os-doux);font-size:.8rem}
.galerie__credit a{color:var(--os-doux);text-decoration:underline;text-underline-offset:3px}
.galerie__credit a:hover{color:var(--os)}
/* La photo garde le comportement des cartes photo : elle se souleve et
   s'agrandit au clic. La legende, elle, ne bouge pas. */
.galerie__piece .carte{margin:0}

/* ---------- facteurs de prix ---------- */
/* Quatre explications courtes, cote a cote : on les balaie du regard plutot
   que de les lire l'une apres l'autre. */
.facteurs{
  display:grid;gap:22px 28px;margin-top:30px;
  grid-template-columns:repeat(auto-fit,minmax(min(250px, 100%), 1fr));
}
.facteur{
  border-top:1px solid var(--ligne);padding-top:16px;
  display:grid;gap:7px;align-content:start;
}
.facteur h3{font-size:1.08rem}
.facteur p{color:var(--os-doux);font-size:.94rem}

/* La colonne de gauche du tableau des prix porte deux niveaux : le cas, puis
   sa mesure en petit. */
.tableau td b{font-weight:400;display:block}
.tableau td span{color:var(--os-doux);font-size:.86rem}

/* ---------- remise et envoi ---------- */
.zones__cas-liste{
  display:grid;gap:20px;margin-top:26px;
  grid-template-columns:repeat(auto-fit,minmax(min(260px, 100%), 1fr));
}
.zones__cas{display:grid;gap:6px;align-content:start}
.zones__cas h3{font-size:1.05rem}
.zones__cas p{color:var(--os-doux);font-size:.94rem}

/* ---------- prix ---------- */
.prix{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.prix__valeur{color:var(--menthe);font-size:1.5rem;font-weight:700;line-height:1}
.prix__detail{color:var(--os-doux);font-size:.88rem}

/* align-self evite que l'etiquette s'etire sur toute la largeur de la carte.
   La menthe est reservee aux prix : les etiquettes se distinguent par le
   contraste (creme = disponible, attenue = a venir), pas par la couleur. */
.etiquette{
  display:inline-block;align-self:flex-start;
  padding:4px 11px;border-radius:999px;
  font-size:.73rem;letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--ligne);color:var(--os-doux);
}
.etiquette--dispo{color:var(--os);border-color:var(--os-doux)}

/* ---------- bandeau de reassurance du bon de commande ---------- */
.confiance{
  list-style:none;display:grid;gap:18px;margin-top:32px;
  grid-template-columns:repeat(auto-fit,minmax(min(210px, 100%), 1fr));
}
.confiance li{display:grid;gap:4px;border-top:1px solid var(--ligne);padding-top:14px}
.confiance b{font-weight:400}
.confiance span{color:var(--os-doux);font-size:.9rem}

/* ---------- strates : la presentation de l'accueil ----------
   Cinq sujets presentes comme une pile de couches : le titre a gauche, le
   texte a droite, un filet entre chaque. Ils etaient serres en trois colonnes
   de 340 px, ou des paragraphes de soixante-dix mots en petit gris se lisaient
   comme un mur.
   Pendant la lecture, la couche qui passe au centre de l'ecran s'allume :
   son filet devient creme et son texte s'eclaircit. C'est la couche active,
   celle qu'on est en train de lire. Creme et non menthe, comme le reste.
   Le titre garde sa pleine couleur en permanence : la hierarchie ne depend
   pas de l'animation. */
.strates{list-style:none;margin-top:44px;border-bottom:1px solid var(--ligne)}
.strates > li{
  position:relative;display:grid;gap:10px 48px;padding:26px 0;
  grid-template-columns:minmax(190px, 30%) 1fr;align-items:baseline;
}
/* Le filet de la couche. */
.strates > li::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;background:var(--ligne);
}
/* La couche active, par-dessus le filet. */
.strates > li::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:1;
  background:linear-gradient(90deg, rgba(237,231,219,.85), rgba(237,231,219,0) 75%);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform calc(var(--t-lent) * .7) var(--courbe);
}
.strates > li.est-active::before{transform:scaleX(1)}
.strate__titre{font-size:clamp(1.12rem,1.05rem + .4vw,1.3rem);line-height:1.3}
.strate__texte{
  color:var(--os-doux);max-width:64ch;line-height:1.7;
  transition:color var(--t-moyen) var(--courbe);
}
.strates > li.est-active .strate__texte{color:var(--os-vif)}
@media (max-width:700px){
  .strates > li{grid-template-columns:1fr;gap:8px;padding:22px 0}
}

/* ---------- bon de commande ----------
   Le formulaire vit sur un fond --encre-haut : ses champs et ses panneaux
   prennent donc --encre, plus sombre, pour se lire comme des creux. */

.formulaire{
  display:grid;gap:clamp(26px,4vw,38px);
  /* Au-dela d'environ 760 px l'oeil perd la colonne entre une etiquette et
     son champ. La page peut etre large, le formulaire non. */
  max-width:760px;margin-top:38px;
}

/* Un attribut hidden doit toujours l'emporter sur les display poses ici.
   Sans cette regle, un display:grid sur un bloc masque le fait reapparaitre
   vide : c'est exactement ce qui avait laisse un cadre rouge en permanence
   au milieu du formulaire. */
.formulaire [hidden]{display:none !important}

/* Les etapes se separent par un filet, pas par un cadre : trois panneaux
   empiles alourdissaient une page qui est deja longue. */
.formulaire fieldset{border:0;padding:0;display:grid;gap:20px}
.formulaire fieldset + fieldset{
  border-top:1px solid var(--ligne);padding-top:clamp(26px,4vw,38px);
}
.formulaire legend{
  /* float:left sort la legende du placement special que le navigateur lui
     reserve dans la bordure du fieldset, et la remet dans le flux. */
  float:left;width:100%;padding:0;margin-bottom:20px;
  font-size:clamp(1.12rem,1.05rem + .4vw,1.3rem);line-height:1.15;
}

/* ---- champs ---- */
.champ{display:grid;gap:7px}
/* Deux ecritures coexistent : le bon de commande enveloppe son intitule dans un
   <span> a l'interieur d'un <label class="champ">, le calculateur pose un
   <label for> a cote de son champ. Les deux doivent se lire pareil. */
.champ > span,.champ > label{color:var(--os-doux);font-size:.9rem}
.champ i,.bascule i{font-style:normal;color:var(--os-doux);font-size:.84rem}

/* type="number" appartient a cette liste : sans lui, les quatre champs du
   calculateur tombaient sur le style natif du navigateur, fond blanc et texte
   noir au milieu d'une page sombre. */
.formulaire input[type="text"],.formulaire input[type="email"],
.formulaire input[type="tel"],.formulaire input[type="number"],
.formulaire textarea,.formulaire select{
  width:100%;font:inherit;color:var(--os);
  background:var(--encre);border:1px solid var(--ligne);border-radius:10px;
  padding:11px 13px;
  transition:border-color var(--t-moyen) var(--courbe);
}
/* Les fleches d'incrementation sont dessinees par le navigateur : sans cette
   declaration elles restent claires sur le fond sombre qu'on vient de poser. */
.formulaire input[type="number"]{color-scheme:dark}
.formulaire textarea{resize:vertical;min-height:78px;line-height:1.55}
.formulaire input::placeholder,.formulaire textarea::placeholder{color:#6C7381}
.formulaire input:hover,.formulaire textarea:hover,.formulaire select:hover{
  border-color:var(--os-doux);
}
/* Les controles natifs gardent leur comportement, seule leur teinte change. */
.formulaire input[type="radio"],.formulaire input[type="checkbox"]{accent-color:var(--os)}

.duo{display:grid;gap:20px;grid-template-columns:1fr 1fr}
/* Un numero de rue et un NPA tiennent en quatre caracteres : leur donner la
   moitie de la largeur ferait deux cases vides a cote de deux cases pleines. */
.duo--rue{grid-template-columns:3fr 1fr}
.duo--npa{grid-template-columns:1fr 3fr}
/* Plusieurs rangees de champs dans un meme panneau depliant : le fieldset qui
   les espace ne voit que le panneau, pas ce qu'il contient. */
.champs-groupe{display:grid;gap:20px}
@media (max-width:560px){.duo,.duo--rue,.duo--npa{grid-template-columns:1fr}}

/* ---- erreurs ---- */
.erreurs{
  display:grid;gap:5px;list-style:none;
  border:1px solid var(--rouge-trait);border-radius:var(--rayon-s);
  background:rgba(224,154,158,.07);color:var(--rouge);
  padding:14px 16px;font-size:.93rem;
}
.formulaire .invalide{border-color:var(--rouge-trait)}

/* ---- choix exclusifs ---- */
.choix__liste{display:grid;gap:10px}
.choix{
  display:flex;align-items:flex-start;gap:13px;cursor:pointer;
  border:1px solid var(--ligne);border-radius:var(--rayon);
  background:var(--encre);padding:15px 17px;
  transition:transform var(--t-survol) var(--courbe-survol),
             border-color var(--t-survol) var(--courbe-survol);
}
.choix:hover{border-color:var(--os-doux);transform:translateY(var(--leve))}
.choix:has(input:checked){border-color:var(--os)}
.choix input{margin-top:5px;flex-shrink:0}
.choix__corps{display:grid;gap:4px}
.choix__corps b{font-weight:400}
.choix__corps small{color:var(--os-doux);font-size:.88rem;line-height:1.55}

/* ---- pieces du catalogue ---- */
#bloc-catalogue,#bloc-description,#bloc-adresse,#bloc-gravure-texte{display:grid;gap:20px}

.pieces{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(min(190px, 100%), 1fr))}
.piece{
  display:grid;gap:12px;
  border:1px solid var(--ligne);border-radius:var(--rayon);
  background:var(--encre);padding:12px;
  transition:border-color var(--t-survol) var(--courbe-survol);
}
/* Une piece choisie se marque par son cadre : la menthe reste aux prix. */
.piece--prise{border-color:var(--os)}
.piece__visuel{
  overflow:hidden;aspect-ratio:4/3;
  /* Un pixel de moins que le cadre : des rayons egaux laissent un croissant
     clair dans chaque angle, qui se lit comme de la pixelisation. */
  border-radius:calc(var(--rayon) - 1px);
}
.piece__visuel img{width:100%;height:100%;object-fit:cover}
.piece:hover .piece__visuel img{transform:scale(1.035)}
.piece__corps{display:grid;gap:2px}
.piece__corps b{font-weight:400;font-size:.98rem;line-height:1.3}
/* La teinte se choisit dans la piece, parce qu'elle depend de sa matiere. Le
   choix vit dans le corps de la carte plutot qu'en quatrieme ligne de sa grille :
   sur telephone la carte passe a deux colonnes, et une ligne de plus se serait
   rangee sous la vignette. */
.piece__couleur{margin-top:10px}
.piece__couleur-titre{display:block;color:var(--os-doux);font-size:.8rem}
/* Ici la pastille suffit et vaut mieux qu'un rendu photo : la carte fait
   260 px, et le nuancier en grand est a un lien de la. */
/* Une rangee par exemplaire commande. Le numero n'apparait qu'a partir de
   deux : sur une piece unique il n'apprendrait rien. */
.teinte-rangees{display:grid;gap:14px;margin-top:8px}
.teinte-rangee__no{
  display:block;color:var(--os-doux);font-size:.72rem;
  letter-spacing:.12em;text-transform:uppercase;margin-bottom:6px;
}
/* Une colonne par zone : corps, accent, patins. Le nom de la zone tient la
   place du titre general, qui ne peut plus annoncer une matiere unique. */
.teinte-zone + .teinte-zone{margin-top:12px}
.teinte-zone__nom{
  display:block;color:var(--os);font-size:.82rem;margin-bottom:6px;
}
.teinte-zone__nom i{font-style:normal;color:var(--os-doux);font-size:.9em}
.teintes-choix{display:flex;flex-wrap:wrap;gap:7px}
.teinte-choix input{position:absolute;width:1px;height:1px;opacity:0}
.teinte-choix span{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  font-size:.85rem;line-height:1.2;color:var(--os-doux);
  border:1px solid var(--ligne);border-radius:999px;padding:5px 11px 5px 6px;
  transition:color var(--t-survol) var(--courbe-survol),
             border-color var(--t-survol) var(--courbe-survol);
}
.teinte-choix:hover span{color:var(--os)}
.teinte-choix input:checked + span{color:var(--os);border-color:var(--os);background:var(--encre-haut)}
/* Le contour de focus ne peut pas venir de la case, elle est hors de l'ecran. */
.teinte-choix input:focus-visible + span{outline:2px solid var(--os);outline-offset:2px}

.compteur{display:flex;align-items:center;gap:10px}
.compteur button{
  width:32px;height:32px;flex-shrink:0;border-radius:999px;cursor:pointer;
  font:inherit;font-size:1.05rem;line-height:1;
  color:var(--os);background:var(--encre-haut);border:1px solid var(--ligne);
  display:grid;place-items:center;
  transition:transform var(--t-survol) var(--courbe-survol),
             border-color var(--t-survol) var(--courbe-survol);
}
.compteur button:hover{border-color:var(--os);transform:translateY(var(--leve))}
/* Le rond fait 32 px parce que c'est la bonne taille a l'oeil a cote du prix.
   La zone qu'on touche, elle, doit faire 44 : un pseudo-element l'etend sans
   grossir le dessin. C'est le controle le plus manipule du site, et la visite
   arrive d'Instagram, donc au pouce. */
.compteur button{position:relative}
.compteur button::after{
  content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;
  transform:translate(-50%,-50%);
}
/* Le compteur est borne a 0 et 20. Sans cet etat, le bouton de bout de course
   reste actif et n'obeit pas : on appuie, rien ne bouge, on recommence. */
.compteur button:disabled{color:var(--os-doux);border-color:var(--ligne);cursor:not-allowed}
.compteur button:disabled:hover{border-color:var(--ligne);transform:none}
.compteur output{min-width:2ch;text-align:center;font-variant-numeric:tabular-nums}

/* ---- bascule ---- */
.bascule{display:flex;align-items:flex-start;gap:11px;cursor:pointer}
.bascule input{margin-top:6px;flex-shrink:0}

/* ---- recapitulatif ---- */
.recapitulatif{
  border:1px solid var(--ligne);border-radius:var(--rayon);
  background:var(--encre);padding:clamp(20px,3vw,28px);
}
.recapitulatif h2{font-size:clamp(1.25rem,1.1rem + .6vw,1.5rem)}
.recap{list-style:none;display:grid;margin-top:16px}
.recap li{
  display:flex;justify-content:space-between;gap:18px;
  padding-block:10px;border-bottom:1px solid var(--ligne);
}
.recap li:last-child{border-bottom:0}
.recap li span:last-child{color:var(--os-vif);text-align:right;white-space:nowrap}
.recap__vide{color:var(--os-doux)}
.recap__total{
  display:flex;justify-content:space-between;align-items:baseline;gap:18px;
  border-top:1px solid var(--os-doux);margin-top:6px;padding-top:15px;
}
.recap__total b{color:var(--menthe);font-size:1.35rem;line-height:1;white-space:nowrap}
.recapitulatif .actions{margin-top:22px}

/* ---- derniere etape ---- */
.etape-envoi{
  border:1px solid var(--os-doux);border-radius:var(--rayon);
  background:var(--encre);padding:clamp(20px,3vw,28px);
}
.etape-envoi .chapeau{margin-top:12px}
.fichier{margin-top:16px;color:var(--os-doux);font-size:.92rem}
.fichier code{
  font-family:ui-monospace,Consolas,monospace;font-size:.88rem;color:var(--os);
  background:var(--encre-haut);border:1px solid var(--ligne);border-radius:var(--rayon-s);
  padding:2px 7px;
}
.etape-envoi .actions{margin-top:20px}
.etape-envoi .prix__detail{margin-top:16px}
#etape-merci{border-color:var(--menthe)}

/* ---- page de suivi d'une commande (/suivi/<jeton>/, servie par PHP) ---- */
.suivi h2{margin-top:clamp(28px,4vw,40px)}
.suivi__note{margin-top:20px;padding:16px 18px;border:1px solid var(--ligne);
  border-radius:var(--rayon);background:var(--encre)}
.suivi__note p{margin-top:6px}
.suivi__note--ok{border-color:var(--menthe)}
.suivi__etapes{list-style:none;margin:26px 0 0;padding:0;display:grid;gap:0}
.suivi__etape{position:relative;padding:0 0 18px 30px;color:var(--os-doux)}
.suivi__etape::before{content:"";position:absolute;left:5px;top:6px;width:12px;height:12px;
  border-radius:50%;border:2px solid var(--os-doux);background:var(--encre)}
.suivi__etape::after{content:"";position:absolute;left:11px;top:20px;bottom:0;width:2px;
  background:var(--ligne)}
.suivi__etape:last-child::after{display:none}
.suivi__etape small{display:block;font-size:.85rem;color:var(--os-doux)}
.suivi__etape--fait{color:var(--os)}
.suivi__etape--fait::before{background:var(--menthe);border-color:var(--menthe)}
.suivi__etape--courant{color:var(--os);font-weight:600}
.suivi__etape--courant::before{border-color:var(--menthe);box-shadow:0 0 0 4px rgba(95,179,154,.18)}
.suivi__docs{display:grid;gap:12px;margin-top:14px}
.suivi__doc{display:flex;flex-wrap:wrap;align-items:center;gap:12px 20px;padding:14px 16px;
  border:1px solid var(--ligne);border-radius:var(--rayon);background:var(--encre)}
.suivi__doc > div:first-child{flex:1 1 180px}
.suivi__doc small,.suivi__montant small{display:block;color:var(--os-doux);font-size:.85rem}
.suivi__montant{font-variant-numeric:tabular-nums;text-align:right}
.suivi__accepter{margin-top:clamp(28px,4vw,40px);padding:clamp(18px,3vw,26px);
  border:1px solid var(--menthe);border-radius:var(--rayon);background:var(--encre)}
.suivi__accepter .choix{display:flex;gap:10px;align-items:flex-start;margin-top:14px}
.suivi__accepter .actions{margin-top:18px}
.suivi__pied{margin-top:30px}
.suivi__avis .etoiles{display:flex;flex-direction:row-reverse;justify-content:flex-end;gap:4px;margin-top:12px}
.suivi__avis .etoiles input{position:absolute;opacity:0;width:1px;height:1px}
.suivi__avis .etoiles label{font-size:1.9rem;line-height:1;color:var(--os-doux);cursor:pointer}
.suivi__avis .etoiles input:checked ~ label,
.suivi__avis .etoiles label:hover,.suivi__avis .etoiles label:hover ~ label{color:var(--menthe)}
.suivi__avis .etoiles input:focus-visible + label{outline:2px solid var(--menthe);outline-offset:2px}
.suivi__avis textarea{width:100%;margin-top:12px}

/* ---- temoignages (accueil) ---- */
.temoignages{display:grid;gap:14px;margin-top:18px;
  grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.temoignage{margin:0;padding:18px;border:1px solid var(--ligne);border-radius:var(--rayon);
  background:var(--encre)}
.temoignage__note{color:var(--menthe);letter-spacing:3px}
.temoignage blockquote{margin:10px 0 0}
.temoignage figcaption{margin-top:12px;color:var(--os-doux);font-size:.9rem}
#envoi-etat{margin-top:14px}
#envoi-etat.erreur-envoi{color:var(--rouge)}
/* Champ piege du bon de commande : hors de l'ecran, hors du clavier, hors des
   lecteurs d'ecran. display:none le trahirait aux robots qui le verifient. */
.piege{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ---------- etapes numerotees ---------- */
.etapes{list-style:none;counter-reset:e;display:grid;gap:22px;margin-top:36px}
.etapes li{counter-increment:e;display:flex;gap:18px;align-items:flex-start}
.etapes li::before{
  content:counter(e);
  flex-shrink:0;width:34px;height:34px;border-radius:50%;
  border:1px solid var(--ligne);background:var(--encre-haut);
  display:grid;place-items:center;font-size:.9rem;color:var(--os-doux);
}
.etapes h3{margin-bottom:3px}
.etapes p{color:var(--os-doux);font-size:.96rem}

/* ---------- tableaux ---------- */
.tableau{width:100%;overflow-x:auto;margin-top:26px}
table{border-collapse:collapse;width:100%;min-width:420px;font-size:.95rem}
th,td{text-align:left;padding:13px 16px;border-bottom:1px solid var(--ligne)}
th{color:var(--os-doux);font-weight:400;font-size:.8rem;letter-spacing:.1em;text-transform:uppercase}

/* Renvoi vers le guide des matieres. Souligne comme un lien de texte, parce
   qu'il est au milieu d'une information et non dans une zone cliquable. */
.lien-guide{
  color:inherit;text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:4px;
  text-decoration-color:var(--os-doux);
  transition:text-decoration-thickness var(--t-survol) var(--courbe-survol),
             text-underline-offset var(--t-survol) var(--courbe-survol),
             text-decoration-color var(--t-survol) var(--courbe-survol);
}
.lien-guide:hover{
  text-decoration-thickness:2px;text-underline-offset:2px;
  text-decoration-color:var(--os);
}
.guide{
  margin-top:16px;font-size:.92rem;color:var(--os-doux);
}

/* ---------- listes de details ---------- */
.details{list-style:none;display:grid;gap:11px;margin-top:24px}
.details li{display:flex;gap:12px;border-bottom:1px solid var(--ligne);padding-bottom:11px}
.details span:first-child{color:var(--os-doux);min-width:135px}
.details span:last-child{color:var(--os-vif)}

/* ---------- questions ---------- */
.question{border-bottom:1px solid var(--ligne);padding-block:22px}
.question h2{font-size:clamp(1.05rem,1rem + .3vw,1.2rem);margin-bottom:7px}
.question p{color:var(--os-vif)}

/* ---------- bloc d'appel ----------
   La lumiere qui ouvre chaque page revient ici, par en dessous, comme une piece
   eclairee sur son plateau. C'est le seul moment ou le site demande quelque
   chose au visiteur : c'est la qu'elle a du sens, pas semee sur chaque bloc.
   Creme et non menthe, comme le halo du haut. Le filet sur l'arete haute est
   celui de la carte du menu : les surfaces qui se detachent parlent pareil.
   Mesure le 21.09.2026 : le chapeau, texte le plus proche de la lumiere, garde
   5,1:1 en 375 px. Toute hausse d'intensite se remesure. */
.appel{
  border:1px solid var(--ligne);border-radius:var(--rayon);
  background-color:var(--encre-haut);
  background-image:radial-gradient(ellipse 65% 85% at 50% 100%, rgba(237,231,219,.13), transparent 72%);
  box-shadow:inset 0 1px 0 rgba(237,231,219,.06);
  padding:clamp(26px,4vw,46px);
  text-align:center;
}
.appel h2{max-width:22ch;margin-inline:auto}

/* ---------- texte long (pages legales) ---------- */
.texte{max-width:70ch}
.texte h2{margin-top:44px;margin-bottom:12px}
.texte h3{margin-top:28px;margin-bottom:8px}
.texte p,.texte li{color:var(--os-doux);margin-bottom:12px}
.texte ul{padding-left:20px}
.texte strong{color:var(--os);font-weight:400}
/* Sur la page sur-mesure, « ce que je ne fais pas » est une liste de refus :
   elle merite la meme couleur que les limites des matieres. */
#refus .details li span,.details--refus li span{color:var(--rouge)}
/* Un lien au fil du texte ne peut pas monter sans decaler sa ligne. Son
   equivalent, c'est un trait qui s'epaissit et se rapproche.
   Regle posee sur tout lien de paragraphe ou de liste plutot que sur une liste
   de classes : un texte ajoute plus tard herite du comportement sans qu'on ait
   pense a l'inscrire quelque part. */
main p a:not([class]),main li a:not([class]),
.texte a,.avis a,.chapeau a,.fichier a{
  color:var(--os);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:4px;
  transition:text-decoration-thickness var(--t-survol) var(--courbe-survol),
             text-underline-offset var(--t-survol) var(--courbe-survol);
}
main p a:not([class]):hover,main li a:not([class]):hover,
.texte a:hover,.avis a:hover,.chapeau a:hover,.fichier a:hover{
  text-decoration-thickness:2px;text-underline-offset:2px;
}

/* Fil d'Ariane : un retour au catalogue, discret, qui recule vers la gauche. */
.fil{
  color:inherit;text-decoration:none;display:inline-block;
  transition:color var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol);
}
.fil:hover{color:var(--os);transform:translateX(calc(var(--glisse-l) * -1))}


/* Pas d'apparition au defilement : titres, textes et cartes sont a leur
   place des l'affichage. Le mouvement qui les amenait (glissement, titres
   par couches) a ete retire le 30.09.2026, juge trop present a la lecture.
   Restent les mouvements declenches par un geste : survol, menu, onglets,
   changement de page. */

/* Le surtitre porte un filet court sous lui. */
.surtitre{position:relative}
.surtitre::after{
  content:"";position:absolute;left:0;bottom:-5px;width:32px;height:1px;
  background:var(--os-doux);
}

/* ---------- recit : alternance photo / texte (page A propos) ---------- */
.recit{padding-block:clamp(46px,7vw,86px)}
/* Un recit place juste apres l'introduction n'a pas besoin de son propre
   espacement haut : celui de l'introduction fait deja le travail, et les deux
   cumules eloignaient le chapeau du bloc qu'il annonce. */
.accroche + .recit{padding-top:0}
.recit__grille{
  display:grid;gap:clamp(26px,5vw,60px);align-items:center;
  grid-template-columns:repeat(auto-fit,minmax(min(280px, 100%), 1fr));
}
/* alternance pilotee par une classe posee par le generateur : plus fiable
   qu'un nth-child, qui casse des qu'une section est ajoutee avant. */
.recit--inverse .recit__visuel{order:2}

.recit__visuel{
  /* Cadre identique pour toutes les sections, calque sur la 1re image (3:2). */
  position:relative;aspect-ratio:3/2;overflow:hidden;
  border:1px solid var(--ligne);border-radius:var(--rayon-l);
  background:var(--encre-haut);
  display:flex;align-items:center;justify-content:center;
}
/* Une photo remplit tout le cadre : agrandie proportionnellement jusqu'a
   toucher les deux bords, le debord etant rogne. Pas de deformation, pas de
   bande vide. Le sujet reste centre, d'ou l'interet de le cadrer au milieu. */
.recit__visuel img{
  width:100%;height:100%;object-fit:cover;object-position:center;display:block;
  /* Meme raison : l'image porte une animation de parallaxe, donc sa propre
     couche. Elle doit posseder l'arrondi qui la rogne. */
  border-radius:calc(var(--rayon-l) - 1px);
}
.recit__visuel--vide .attente{position:absolute;inset:0}

/* Objet detoure : le rognage n'a pas de sens, on verrait la piece coupee.
   L'image reste entiere et centree sur le fond clair, avec une marge. */
.recit__visuel--clair{background:var(--os)}
.recit__visuel--clair img{object-fit:contain;padding:clamp(18px,3.5vw,38px)}

.recit__texte h2{margin-bottom:14px}
.recit__texte p{color:var(--os-doux);max-width:52ch}

@media (max-width:560px){
  .recit--inverse .recit__visuel{order:0}
}

/* ---------- couleurs : pastilles et nuancier ---------- */
.pastille{
  width:12px;height:12px;border-radius:50%;display:inline-block;flex:none;
  border:1px solid rgba(237,231,219,.4);
}
.couleurs{display:inline-flex;flex-wrap:wrap;gap:14px}
.couleur{display:inline-flex;align-items:center;gap:7px}

/* ---------- nuancier : les teintes, en grand ---------- */
/* Une teinte de 44 px ne se juge pas : elle se reconnait au mieux. Ici le
   rendu reel occupe toute la tuile, et c'est la seule information de la case. */
.onglets-page,.nuancier{display:grid;gap:22px}
.nuancier{margin-top:26px}
/* Un panneau replie doit disparaitre malgre le display pose au-dessus. */
[data-onglet][hidden]{display:none}
.onglets{display:flex;flex-wrap:wrap;gap:9px}
.onglet{
  font:inherit;font-size:1rem;cursor:pointer;
  color:var(--os-doux);background:var(--encre);border:1px solid var(--ligne);
  border-radius:999px;padding:11px 24px;
  transition:color var(--t-survol) var(--courbe-survol),
             border-color var(--t-survol) var(--courbe-survol);
}
.onglet:hover{color:var(--os);border-color:var(--os-doux)}
/* L'onglet actif se marque par le trait et la teinte du texte, pas par un
   aplat : un bouton plein se lirait comme une action a faire. */
.onglet[aria-pressed="true"]{color:var(--os);border-color:var(--os);background:var(--encre-haut)}
/* La barre du nuancier est un filtre a l'interieur d'un onglet, pas un second
   choix de meme rang : elle se tient en retrait de celle du haut de page. */
.nuancier .onglet{font-size:.88rem;padding:7px 17px}
.teintes__matiere{margin-bottom:14px}
.finitions-bloc{margin-top:46px}

.teintes{
  list-style:none;margin:0;display:grid;gap:18px;
  grid-template-columns:repeat(auto-fill,minmax(148px,1fr));
}
.teinte{display:grid;gap:8px;justify-items:start}
.teinte__visuel{
  display:block;width:100%;aspect-ratio:1;overflow:hidden;
  border-radius:var(--rayon);border:1px solid var(--ligne);
}
.teinte__visuel img{width:100%;height:100%;object-fit:cover;display:block}
/* Une bobine sans rendu reel garde son aplat, a la taille de la tuile : elle
   se voit tout de suite comme l'exception qu'elle est. */
.teinte__aplat{display:block;width:100%;height:100%}
.teinte__nom{font-size:.98rem;line-height:1.25}
.teinte__finition{
  color:var(--os-doux);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--ligne);border-radius:999px;padding:2px 9px;
}

/* ---------- finitions ---------- */
.finitions{
  display:grid;gap:18px;margin-top:30px;
  grid-template-columns:repeat(auto-fit,minmax(min(240px, 100%), 1fr));
}
.finition{
  border-top:1px solid var(--ligne);padding-top:16px;
  display:grid;gap:7px;align-content:start;
}
.finition h3{font-size:1.08rem}
.finition p{color:var(--os-doux);font-size:.94rem}

/* ---------- fiches matieres ---------- */
.matieres{display:grid;gap:0}
.matiere{border-top:1px solid var(--ligne);padding-block:clamp(26px,4vw,40px)}
.matiere:first-child{border-top:none;padding-top:0}
.matiere__tete{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.matiere__tete h2{font-size:clamp(1.35rem,1.1rem + 1vw,1.75rem)}
.matiere__resume{color:var(--os-vif);margin-top:8px;max-width:62ch}

/* Deux colonnes de meme poids : ni les qualites ni les limites ne doivent
   paraitre secondaires, c'est la comparaison qui aide a choisir. */
.matiere__colonnes{
  display:grid;gap:clamp(18px,3vw,40px);margin-top:24px;
  grid-template-columns:repeat(auto-fit,minmax(min(270px, 100%), 1fr));
}
/* Le titre de colonne porte la couleur : c'est lui qu'on lit en premier, et
   il annonce la nature de ce qui suit avant meme la premiere puce. */
.matiere__colonnes h3{
  font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;
  margin-bottom:12px;
}
.matiere__colonnes .pour h3{color:var(--menthe)}
.matiere__colonnes .contre h3{color:var(--rouge)}

.points{list-style:none;display:grid;gap:10px;font-size:.94rem}
.points li{position:relative;padding-left:24px;color:var(--os-vif)}
/* Les signes passent a 2 px et s'elargissent : a 1 px, le trait disparaissait
   dans la page et la couleur ne se voyait pas. */
.points li::before{
  content:"";position:absolute;left:0;top:calc(.62em - 1px);width:12px;height:2px;
  border-radius:1px;
}
.points--pour li::before{background:var(--menthe)}
.points--pour li::after{
  content:"";position:absolute;left:5px;top:calc(.62em - 6px);width:2px;height:12px;
  border-radius:1px;background:var(--menthe);
}
.points--contre li::before{background:var(--rouge)}

/* Le conseil est la conclusion de la fiche : il se detache par un filet
   menthe court, la seule marque de couleur que porte un paragraphe entier. */
.matiere__conseil{
  margin-top:24px;font-size:.94rem;color:var(--os-vif);max-width:64ch;
  padding-top:14px;border-top:1px solid var(--ligne);
}
.matiere__conseil b{color:var(--menthe);font-weight:400;margin-right:4px}

/* ---------- atouts de la machine, page matieres ---------- */
/* Deux avantages que le client ne saurait pas nommer seul. Cote a cote plutot
   qu'en liste : ils ne se hierarchisent pas, on choisit celui qui parle. */
.atouts{
  display:grid;gap:clamp(24px,4vw,48px);
  grid-template-columns:repeat(auto-fit,minmax(min(300px, 100%), 1fr));
}
.atout h2{font-size:clamp(1.15rem,1.05rem + .6vw,1.4rem);max-width:22ch}
.atout p{color:var(--os-vif);margin-top:14px;max-width:56ch}

/* ---------- parcours (page savoir-faire) ---------- */
.parcours{list-style:none;margin-top:40px;position:relative}

/* Le trait vertical dit ou en est le parcours. Creme jusqu'a l'etape en
   cours, eteint au-dela : rien n'est promis pour la suite. */
.etape{position:relative;padding:0 0 38px 30px;border-left:1px solid var(--ligne)}
.etape--fait{border-left-color:var(--os)}

/* L'etape en cours : le trait arrive jusqu'a son point puis s'eteint dans le
   vide. Un degrade plutot qu'une coupure nette, pour que ca se lise comme
   « en route » et non comme « interrompu ». */
.etape--en-cours{
  border-left-color:transparent;
  background-image:linear-gradient(to bottom,
    var(--os) 0, var(--os) 22px,
    var(--ligne) 46px, transparent 78%);
  background-size:1px 100%;
  background-repeat:no-repeat;
  background-position:left top;
  /* Sans ca le degrade demarre apres la bordure et le trait se decale d'un
     pixel par rapport a celui des etapes precedentes. */
  background-origin:border-box;
}
.etape:last-child{padding-bottom:0}
.etape:last-child:not(.etape--en-cours){border-left-color:transparent}

/* Point plein pour une etape franchie, creux pour celle en cours. */
/* left = -0,5 - largeur totale / 2, pour centrer le rond sur l'axe du trait.
   Le pseudo-element se place depuis la boite de remplissage, donc apres la
   bordure : sans ce calcul, chaque rond derive vers la droite. */
.etape::before{
  content:"";position:absolute;left:-6px;top:8px;width:9px;height:9px;border-radius:50%;
  background:var(--encre);border:1px solid var(--ligne);
}
.etape--fait::before{background:var(--os);border-color:var(--os)}
.etape--en-cours::before{
  background:var(--encre);border:2px solid var(--os);
  left:-7px;top:7px;
}

.etape__tete{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.etape__duree{
  font-size:.71rem;letter-spacing:.16em;text-transform:uppercase;color:var(--os-doux);
  border:1px solid var(--ligne);border-radius:999px;padding:3px 10px;
}
.etape__resume{color:var(--os-doux);margin-top:8px;max-width:60ch}
.etape__acquis{list-style:none;display:grid;gap:7px;margin-top:16px;font-size:.94rem}
.etape__acquis li{position:relative;padding-left:20px;color:var(--os-vif)}
.etape__acquis li::before{
  content:"";position:absolute;left:0;top:calc(.62em - 1px);width:10px;height:2px;
  border-radius:1px;background:var(--menthe);
}
/* Meme raison : l'indentation seule marque la mise en retrait. */
.etape__utile{
  margin-top:18px;font-size:.94rem;color:var(--os-doux);max-width:62ch;
  padding-left:20px;text-indent:-20px;
}
.etape__utile b{margin-right:2px}
.etape__utile b{color:var(--os);font-weight:400}

/* ---------- micro-details ----------
   Rien de bruyant : des mouvements courts, declenches par une intention de
   l'utilisateur (survol), jamais en boucle. */

/* Le L du logo : la couche menthe glisse, les creme suivent en decalage.
   Seule animation de marque du site, elle reste dans l'en-tete. */
/* Les couches du L se decalent en eventail, la menthe ouvrant la marche.
   Chacune part avec un retard croissant : le logo se deplie au lieu de
   glisser d'un bloc. */
.marque svg rect{transition:transform calc(var(--t-survol) * 1.2) var(--courbe-survol)}
/* A l'arrivee sur le site, les strates du logo se posent l'une sur l'autre,
   de la base a la couche verte, qui vient en dernier : c'est la couche active.
   Une fois par visite : le script d'en-tete pose .logo-vu des la deuxieme page,
   avant le premier affichage, pour que le logo ne rejoue pas a chaque clic.
   Remplissage « backwards » et non « both » : une fois posee, chaque strate
   rend la main a la transition du survol ci-dessus. */
@media (prefers-reduced-motion: no-preference){
  .js:not(.logo-vu) .marque svg rect{animation:strate var(--t-moyen) var(--courbe) backwards}
  .js:not(.logo-vu) .marque svg rect:nth-child(4){animation-delay:.06s}
  .js:not(.logo-vu) .marque svg rect:nth-child(3){animation-delay:.18s}
  .js:not(.logo-vu) .marque svg rect:nth-child(2){animation-delay:.3s}
  .js:not(.logo-vu) .marque svg rect:nth-child(1){animation-delay:.5s}
}
/* En unites du dessin (544 de large pour 22 px) : une chute d'environ 6 px. */
@keyframes strate{from{transform:translateY(-150px);opacity:0}}
.marque:hover svg rect:nth-child(1){transform:translateX(14px)}
.marque:hover svg rect:nth-child(2){transform:translateX(8px);transition-delay:.05s}
.marque:hover svg rect:nth-child(3){transform:translateX(4px);transition-delay:.1s}

/* Lien de navigation : un trait qui se deploie depuis la gauche.
   En creme, pas en menthe : la menthe reste au logo et aux prix. */
.nav__lien{position:relative}
.nav__lien::after{
  content:"";position:absolute;left:12px;right:12px;bottom:3px;height:1px;background:var(--os);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform var(--t-survol) var(--courbe-survol);
}
.nav__lien:hover::after,.nav__groupe--ouvert .nav__lien::after{transform:scaleX(1)}
.nav__lien[aria-current="page"]::after,.nav__lien--parent::after{transform:scaleX(1);background:var(--os-doux)}

/* Carte : la photo respire, et un filet apparait sur l'arete haute. */
.carte{position:relative}
.carte__visuel img{transition:transform calc(var(--t-survol) * 1.5) var(--courbe-survol)}
.carte:has(.carte__lien):hover .carte__visuel img,
a.carte:hover .carte__visuel img{transform:scale(1.035)}
.carte::before{
  content:"";position:absolute;inset:-1px auto auto -1px;height:1px;width:calc(100% + 2px);
  background:var(--os);transform:scaleX(0);transform-origin:0 50%;
  transition:transform var(--t-survol) var(--courbe-survol);z-index:1;
}
.carte:has(.carte__lien):hover::before,a.carte:hover::before{transform:scaleX(1)}

/* Bouton plein : la fleche avance d'un cheveu. */
.btn--plein::after{content:"\2192";transition:transform var(--t-survol) var(--courbe-survol)}
.btn--plein:hover::after{transform:translateX(var(--glisse-l))}

/* En-tete : se resserre des qu'on quitte le haut de page. */
/* L'en-tete garde EXACTEMENT la meme geometrie du haut de page jusqu'en bas.
   Il retrecissait au defilement, ce qui deplacait le logo et les liens sous le
   curseur au moment ou l'on visait justement le menu. Seule la profondeur
   change desormais : le fond se densifie et une ombre tres douce marque le
   decollement du contenu. Aucune taille, aucune marge, aucun deplacement. */
/* Le fond plus dense et l'ombre vivent sur un calque dont seule l'opacite
   change : animer background et box-shadow redessinait tout l'en-tete, flou
   d'arriere-plan compris, a chaque image. 0,625 d'encre posee sur le fond a
   0,92 donne exactement les 0,97 d'avant. */
.entete::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:rgba(23,26,32,.625);
  box-shadow:0 14px 34px -28px #000;
  opacity:0;transition:opacity var(--t-moyen) var(--courbe);
}
.entete--compact::before{opacity:1}

/* Un lien qui part dans un nouvel onglet le signale : sans ca, le bouton
   Retour ne ramene pas ou on croit, et un formulaire en cours inquiete.
   La fleche est tracee, pas ecrite : Work Sans n'a pas de glyphe pour
   U+2197 et le caractere sortait en carre vide. Le masque suit la couleur du
   lien, et hors @supports il ne s'affiche rien plutot qu'un carre plein. */
@supports ((-webkit-mask-image:url("")) or (mask-image:url(""))){
  .lien-guide[target="_blank"]::after{
    content:"";display:inline-block;width:.6em;height:.6em;margin-left:.38em;
    background:currentColor;
    -webkit-mask:var(--fleche-sortante) no-repeat center/contain;
    mask:var(--fleche-sortante) no-repeat center/contain;
  }
}

/* ---------- acces au clavier ----------
   Le meme signal que le survol, en plus net : quelqu'un qui navigue au clavier
   doit voir ou il se trouve au moins aussi bien qu'a la souris. Le contour du
   navigateur est remplace, pas supprime. */
a:focus-visible,button:focus-visible,
input:focus-visible,textarea:focus-visible,select:focus-visible{
  outline:none;
  box-shadow:var(--anneau-net);
  border-radius:var(--rayon-s);
}
.btn:focus-visible,.nav__lien:focus-visible,.compteur button:focus-visible{border-radius:999px}
a.carte:focus-visible,.choix:focus-visible,.piece:focus-visible{border-radius:var(--rayon)}
/* Le lien tient sur le titre mais couvre le bloc : l'anneau doit donc se
   dessiner autour du bloc, sinon il entoure trois mots au milieu d'une carte. */
.carte:has(.carte__lien:focus-visible),.voie:has(.voie__lien:focus-visible){
  box-shadow:var(--anneau-net);border-radius:var(--rayon);
}
.carte__lien:focus-visible,.voie__lien:focus-visible{box-shadow:none;outline:none}
.formulaire input:focus-visible,.formulaire textarea:focus-visible,
.formulaire select:focus-visible{border-radius:10px}

/* ---------- transition entre les pages ----------
   Navigation classique, sans routeur JS : le navigateur gere le fondu.
   Les navigateurs qui ne connaissent pas la regle chargent la page
   normalement, comme avant. */
@view-transition{navigation:auto}
::view-transition-old(root){animation:page-sortie calc(var(--t-court) * .6) var(--courbe) both}
::view-transition-new(root){animation:page-entree calc(var(--t-court) * 1.2) var(--courbe) both}
/* Fondu et glissement seulement : un flou sur une capture pleine page se
   recalcule a chaque image de la transition. */
@keyframes page-sortie{to{opacity:0}}
@keyframes page-entree{from{opacity:0;transform:translateY(10px)}}
/* L'en-tete est exclu du fondu : il porte la navigation, il doit paraitre fixe
   d'une page a l'autre plutot que clignoter a chaque clic. */
.entete{view-transition-name:entete}

/* Changement d'onglet (matiere, couleur) : meme API, dans la page. Le script
   pose .vt-onglet le temps du changement et nomme le panneau qui arrive.
   Seul ce panneau bouge. L'ancienne capture de la page est retiree : elle
   contient encore l'ancien panneau, qui transparaitrait sous le nouveau. */
.vt-onglet::view-transition-old(root){display:none}
.vt-onglet::view-transition-new(root){animation:none}
::view-transition-new(onglet){animation:onglet-entree var(--t-moyen) var(--courbe) both}
@keyframes onglet-entree{from{opacity:0;transform:translateY(8px)}}

/* Repli pour les navigateurs sans View Transitions : le contenu entre en
   fondu au chargement. Scope par @supports pour ne pas doubler l'effet. */
@supports not (view-transition-name: none){
  .js main{animation:page-entree calc(var(--t-court) * 1.3) var(--courbe) both}
}

/* ---------- pied de page ---------- */
.pied{
  border-top:1px solid var(--ligne);padding-block:46px;margin-top:var(--pas);
  /* Une lueur tres basse sous le filet, qui s'eteint avant les colonnes. */
  background-image:radial-gradient(ellipse 45% 150px at 50% 0%, rgba(237,231,219,.06), transparent 100%);
  background-repeat:no-repeat;
}
/* Le filet du pied devient une ligne d'horizon : plus claire au centre, elle
   s'eteint vers les bords. Elle ferme la page sur la lumiere qui l'a ouverte. */
.pied::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1px;
  background:linear-gradient(90deg, transparent 8%, rgba(237,231,219,.34) 50%, transparent 92%);
}
.pied .contenu{
  display:grid;gap:30px;
  grid-template-columns:repeat(auto-fit,minmax(min(210px, 100%), 1fr));
}
/* Balise h2 pour respecter le plan du document, apparence de petit intitule. */
.pied h2{font-size:.75rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--os-doux);font-weight:400;margin-bottom:13px;line-height:1.4}
.pied ul{list-style:none;display:grid;gap:8px;font-size:.94rem}
.pied a{
  color:var(--os-doux);text-decoration:none;display:inline-block;
  transition:color var(--t-survol) var(--courbe-survol),
             transform var(--t-survol) var(--courbe-survol);
}
.pied a:hover{color:var(--os);transform:translateY(var(--leve-s))}
.pied__bas{
  border-top:1px solid var(--ligne);margin-top:34px;padding-top:22px;
  color:var(--os-doux);font-size:.86rem;
  display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;
}

/* ---------- utilitaires ---------- */
/* L'encadre a barre coloree a gauche est, d'apres les sources consultees, le
   signe le plus reconnaissable d'un design genere. Remplace par une note en
   retrait, tenue par un filet superieur : la meme hierarchie, sans le tic. */
.avis{
  margin-top:30px;padding-top:16px;border-top:1px solid var(--ligne);
  color:var(--os-doux);font-size:.94rem;max-width:72ch;
}
.avis strong{color:var(--os);font-weight:400}
.saut-contenu{
  position:absolute;left:-9999px;
}
.saut-contenu:focus{
  left:22px;top:12px;z-index:100;background:var(--os);color:var(--encre);
  padding:10px 16px;border-radius:8px;
}

/* ==========================================================================
   TELEPHONE
   Un doigt ne vise pas comme un curseur. Le seuil retenu est 44 px, celui des
   recommandations WCAG et des deux systemes mobiles. Les liens en pleine
   ligne de texte en sont dispenses : les elargir casserait l'interligne.
   ========================================================================== */

/* ---------- le menu ---------- */
/* 820 et non 760 : a six entrees de menu, la rangee se replie sur deux
   lignes des 800 px et l'en-tete collant double de hauteur.
   (hover:none) en plus de la largeur : le bandeau s'ouvre au survol, et une
   tablette tactile de 1024 px n'en a pas. Elle prend donc le bouton menu, qui
   montre toutes les pages d'un doigt. */
@media (max-width:860px), (hover:none){
  .entete .contenu{padding-block:9px;gap:10px}
  /* Sans JavaScript le panneau reste deplie sous la barre : le bouton n'aurait
     rien a commander, et la barre doit pouvoir se replier sur deux lignes. */
  .js .entete .contenu{flex-wrap:nowrap}
  html:not(.js) .menu__bouton{display:none}

  .menu__bouton{
    display:grid;place-items:center;
    width:44px;height:44px;flex-shrink:0;margin-right:-8px;
    background:none;border:0;border-radius:999px;cursor:pointer;color:var(--os);
    -webkit-tap-highlight-color:transparent;
  }
  /* Trois traits dessines par la bordure et deux pseudo-elements : aucune
     image a charger, et l'animation en croix se fait sur des transformations,
     donc sans redessiner la page. */
  .menu__barres,.menu__barres::before,.menu__barres::after{
    content:"";display:block;width:20px;height:1.5px;background:var(--os);border-radius:2px;
    transition:transform var(--t-court) var(--courbe),opacity var(--t-court) var(--courbe);
  }
  .menu__barres{position:relative}
  .menu__barres::before{position:absolute;top:-6px;left:0}
  .menu__barres::after{position:absolute;top:6px;left:0}
  .menu-ouvert .menu__barres{background:transparent}
  .menu-ouvert .menu__barres::before{transform:translateY(6px) rotate(45deg)}
  .menu-ouvert .menu__barres::after{transform:translateY(-6px) rotate(-45deg)}

  /* Le panneau descend sous la barre. Il est dans le flux du document et non
     en position fixe : la page ne peut donc pas se retrouver bloquee derriere
     un panneau reste ouvert a la suite d'une erreur de script. */
  .js .nav{
    position:absolute;left:0;right:0;top:100%;
    flex-direction:column;gap:0;
    background:var(--encre-haut);border-bottom:1px solid var(--ligne);
    box-shadow:0 26px 40px -34px #000;
    padding:6px var(--marge) 14px;
    max-height:calc(100vh - 62px);max-height:calc(100dvh - 62px);
    overflow-y:auto;overscroll-behavior:contain;
    /* Replie par une transformation plutot que par display:none : la
       transition reste possible, et visibility retire le panneau de la
       tabulation quand il est ferme. */
    transform:translateY(-8px);opacity:0;visibility:hidden;
    transition:transform var(--t-court) var(--courbe),opacity var(--t-court) var(--courbe),
               visibility 0s linear var(--t-court);
  }
  /* .js et .menu-ouvert vivent tous deux sur <html> : c'est donc un selecteur
     compose, pas un descendant. */
  .js.menu-ouvert .nav{
    transform:none;opacity:1;visibility:visible;transition-delay:0s;
  }
  /* Menu ouvert : la page ne defile plus derriere lui, et un voile l'assombrit.
     Un toucher sur le voile referme le menu (voir le script). Le verrou tient a
     la meme classe que le panneau : si le script ne tourne pas, rien n'est
     jamais bloque. Le voile vit sur body et non dans l'en-tete, dont le
     backdrop-filter retiendrait un calque fixe dans sa propre boite.
     Le verrou se pose sur <html> SEULEMENT. Pose aussi sur body, overflow en
     fait un conteneur de defilement bloque a zero : l'en-tete collant s'y
     raccroche et remonte en haut du document, avec le panneau dessous. Apres
     un defilement, le bouton ouvrait donc un menu hors de l'ecran. */
  .js.menu-ouvert{overflow:hidden;overscroll-behavior:none}
  .js body::before{
    content:"";position:fixed;inset:0;z-index:40;
    background:rgba(14,16,20,.62);
    opacity:0;visibility:hidden;
    transition:opacity var(--t-court) var(--courbe),visibility 0s linear var(--t-court);
  }
  .js.menu-ouvert body::before{opacity:1;visibility:visible;transition-delay:0s}

  .nav__lien{
    display:flex;align-items:center;min-height:48px;
    padding:0 14px;border-radius:var(--rayon-s);font-size:1.02rem;
    border-bottom:1px solid var(--ligne);
  }
  /* Une entree et ses sous-pages forment un bloc : le filet passe sous le
     bloc, pas entre l'entree et ce qui en depend. */
  .nav__groupe{display:block;border-bottom:1px solid var(--ligne)}
  .nav__groupe > .nav__lien{border-bottom:0}
  .nav > :last-child{border-bottom:0}
  /* Le trait qui se deploie au survol n'a pas de sens sur un ecran tactile,
     et il se dessinerait ici en travers du texte. */
  .nav__lien::after{display:none}
  .nav__lien:hover{transform:none}

  /* Dans le panneau, le bandeau n'est plus un calque : ses liens sont poses
     en clair sous leur entree, en retrait, toujours visibles. Les details
     restent au bandeau du grand ecran ; ici ils doubleraient la hauteur.
     visibility:inherit et non visible : un enfant en « visible » sort de la
     visibilite cachee de son parent. Menu ferme, ces liens restaient alors
     invisibles mais actifs sur toute la hauteur du panneau, et un toucher sur
     une pastille ou un onglet ouvrait une autre page. */
  .nav__panneau{
    position:static;opacity:1;visibility:inherit;transform:none;
    min-width:0;max-width:none;
    background:none;border:0;border-radius:0;box-shadow:none;transition:none;
  }
  .nav__panneau::before{display:none}
  .nav__liste{display:block;padding:0 0 8px}
  .nav__liste a{
    display:flex;align-items:center;min-height:44px;max-width:none;
    padding:0 14px 0 30px;
  }
  /* Les entrees en creme, leurs sous-pages en retrait et en gris : la
     hierarchie se lit sans filet supplementaire. */
  .nav__lien{color:var(--os)}
  .nav__titre{color:var(--os-doux);font-size:.96rem}
  .nav__liste a[aria-current="page"] .nav__titre{color:var(--os)}
  .nav__detail{display:none}

  .marque{padding-right:6px}
  .marque svg{width:20px}
  .marque span{font-size:1.14rem}
}

/* ---------- largeur ----------
   Ce qui s'empile faute de place. Une tablette a la place : ces regles ne la
   concernent pas, seules celles du bloc « doigt » la suivent. */
@media (max-width:560px){
  /* Un bouton en pleine largeur est plus facile a viser qu'un bouton centre,
     et empile deux actions au lieu de les serrer sur une ligne. */
  .actions{gap:11px}
  .actions .btn{width:100%}
  .pieces{grid-template-columns:1fr}
  .piece{grid-template-columns:92px 1fr;align-items:center;gap:14px;padding:10px}
  .piece__visuel{grid-row:1/3;align-self:center;aspect-ratio:1;border-radius:var(--rayon-s)}
  .piece__corps{grid-column:2}
  .piece .compteur{grid-column:2;justify-content:flex-start}

  /* Le titre de section ne descend pas sous 1,45 rem, sinon la hierarchie
     avec le texte courant disparait. */
  h2{font-size:clamp(1.45rem,1.2rem + 1.6vw,1.8rem)}

  /* Un tableau de deux colonnes en defilement horizontal est un tableau qu'on
     ne lit pas. Empile, chaque valeur porte l'intitule de sa colonne. */
  .tableau{overflow:visible}
  .tableau table{min-width:0;display:block}
  .tableau thead{display:none}
  .tableau tbody,.tableau tr{display:block}
  .tableau tr{border-bottom:1px solid var(--ligne);padding-block:14px}
  .tableau tr:last-child{border-bottom:0}
  .tableau td{display:flex;justify-content:space-between;gap:16px;
    border:0;padding:3px 0;text-align:right}
  .tableau td::before{content:attr(data-col);color:var(--os-doux);text-align:left;flex:none}
  /* La premiere cellule est le titre de la ligne empilee, pas une paire
     intitule/valeur. Elle reste une boite normale : en flex, un titre et sa
     precision se rangeraient cote a cote au lieu de s'empiler, et se
     retrouveraient ecrases en deux colonnes de texte vertical. */
  .tableau td:first-child{
    display:block;text-align:left;font-size:1rem;padding-bottom:5px;
  }
  .tableau td:first-child::before{display:none}

  /* Listes de details : l'intitule au-dessus plutot qu'a cote, sinon la
     valeur se retrouve ecrasee sur trois lignes. */
  .details li{flex-direction:column;gap:2px}
  .details span:first-child{min-width:0;font-size:.86rem}

  .reassurance{padding-block:24px}
  .voie{grid-template-columns:1fr;gap:6px}
  .voie__n{font-size:.86rem}
}

/* Sous 400 px, un intitule de colonne et sa valeur ne tiennent plus sur la
   meme ligne : la valeur se retrouve ecrasee sur cinq lignes alors que la
   place existe juste au-dessus. On les empile. */
@media (max-width:400px){
  .tableau td{flex-direction:column;align-items:flex-start;text-align:left;gap:1px}
  .tableau td::before{font-size:.8rem}
}

/* Tres petits ecrans : le contenu respire moins mais ne deborde jamais. */
@media (max-width:380px){
  :root{--marge:16px}
  .js .nav{padding-inline:var(--marge)}
  .marque span{font-size:1.06rem}
  .btn{padding-inline:16px;font-size:.96rem}
}

/* ---------- doigt ----------
   Le seuil de 44 px vient des recommandations WCAG et des deux systemes
   mobiles. La condition porte sur le pointage, pas sur la largeur : une
   tablette de 1024 px se manipule au doigt exactement comme un telephone.
   Les liens en pleine ligne de texte en sont dispenses, les elargir casserait
   l'interligne. */
@media (max-width:560px), (hover:none){
  .btn{min-height:48px}
  .btn--petit{min-height:44px;padding:12px 20px;font-size:.96rem}

  .nav__lien,.nav__liste a{display:flex;align-items:center;min-height:44px}
  /* Le logo est le seul retour a l'accueil : il se vise comme un bouton. */
  .marque{min-height:44px}

  /* Le pied comptait a lui seul une quinzaine de liens de 22 px de haut,
     serres les uns contre les autres. */
  .pied a{display:inline-flex;align-items:center;min-height:44px}
  .pied ul{gap:0}

  /* Les petites capitales tombaient a 11,5 px. L'interlettrage les rend
     lisibles plus bas que du texte courant, mais pas a ce point. */
  .etiquette{font-size:.82rem;padding:5px 12px}
  .fil{font-size:.8rem}
  .etape__duree{font-size:.8rem}
  .teinte__finition,.fiche small,.choix__corps small{font-size:.86rem}

  /* Formulaire : 48 px de haut, et surtout jamais moins de 16 px de texte.
     En dessous de 16 px, Safari sur iPhone agrandit la page au moment ou le
     champ recoit le focus, et ne la remet jamais comme elle etait. */
  .formulaire input[type="text"],.formulaire input[type="email"],
  .formulaire input[type="tel"],.formulaire input[type="number"],
  .formulaire textarea,.formulaire select{
    min-height:48px;font-size:16px;padding:12px 14px;
  }
  .formulaire textarea{min-height:104px}
  /* Les cases natives font 13 px. On les agrandit sans les remplacer : une
     case dessinee a la main perd son comportement d'origine. */
  .formulaire input[type="radio"],.formulaire input[type="checkbox"]{
    width:22px;height:22px;margin-top:2px;
  }
  .choix{padding:16px;gap:14px}
  .bascule{gap:14px;padding-block:6px}
  .compteur{gap:14px}
  .compteur button{width:44px;height:44px;font-size:1.2rem}
  .compteur output{font-size:1.05rem}

  /* Les onglets du nuancier (39 px) et les pastilles de teinte du bon de
     commande (28 px) se visaient mal au doigt : une teinte voisine partait a
     la place de la bonne. */
  .nuancier .onglet{min-height:44px}
  .teinte-choix span{min-height:44px;padding-block:8px}
  .teintes-choix{gap:8px}
  /* Le fil d'Ariane est un lien isole, pas un mot dans une phrase. Meme
     procede que .galerie__fait : la zone touchable grandit, la ligne non. */
  .fil{padding-block:12px;margin-block:-12px;min-width:44px}
  /* « FAQ », « Tarifs » : un mot court donnait une cible de 40 px de large. */
  .pied a{min-width:44px}
}

/* ---------- ecrans tactiles ----------
   Aucun survol reel sur un ecran tactile : le navigateur simule un :hover qui
   reste colle apres le doigt. On coupe les effets de survol et on garde un
   retour au moment de l'appui, qui lui correspond a un vrai geste. */
@media (hover:none){
  .btn:hover,.carte:hover,.voie:hover,.choix:hover,.piece:hover,
  .compteur button:hover,.nav__lien:hover,.marque:hover{transform:none;box-shadow:none}
  .carte:hover .carte__visuel img{transform:none}
  .carte::before{display:none}
  .btn:active,.choix:active,.compteur button:active{transform:scale(.985)}
  .carte:active,.voie:active{opacity:.72}
  /* La loupe n'apparaissait qu'au survol : au doigt, rien ne disait qu'une
     photo s'agrandit. Elle reste donc affichee. */
  .loupe{opacity:1;transform:none}
  a,button,label,summary{-webkit-tap-highlight-color:rgba(237,231,219,.10)}
}



/* --------------------------------------------------------- consentement
   Bandeau de mesure d'audience. Position fixe : il ne participe pas au flux,
   donc il ne decale aucun contenu a l'affichage. Il ne s'affiche que si la
   mesure est active et que le visiteur n'a pas encore repondu. */
.consentement{
  position:fixed;left:16px;right:16px;bottom:16px;z-index:60;
  max-width:640px;margin:0 auto;padding:20px 22px;
  display:flex;flex-wrap:wrap;align-items:center;gap:14px 20px;
  background:var(--encre-haut);color:var(--os);
  /* Bordure franche et pas d'ombre. Le bandeau cumulait un filet de 1 px et un
     flou de 48 px : les deux disent « je me detache », et ensemble ils se
     brouillent. Ce site parle en filets, pas en elevations — trois ombres dans
     toute la feuille — donc c'est l'arete qui tient le bloc. La bordure passe a
     --os-doux pour porter seule ce que l'ombre appuyait. */
  border:1px solid var(--os-doux);border-radius:16px;
}
.consentement[hidden]{display:none}
/* Menu ouvert : le bandeau passe au-dessus de l'en-tete et masquait le bas
   du panneau, dont les derniers liens ne pouvaient plus etre atteints. Il
   s'efface le temps du menu ; la question reste posee. */
.js.menu-ouvert .consentement{visibility:hidden}
.consentement p{flex:1 1 260px;margin:0;font-size:.92rem;line-height:1.5}
.consentement a{color:inherit}
.consentement__choix{display:flex;gap:10px;flex-wrap:wrap}
/* La neutralisation du fond et de la police des <button> est faite une fois
   pour toutes sur .btn : il ne reste ici que la taille propre au bandeau. */
.consentement .btn{
  font-size:.88rem;line-height:1;padding:11px 20px;color:var(--os);
}
.consentement .btn--plein{background:var(--os);color:var(--encre)}
.consentement .btn--vide:hover{background:rgba(237,231,219,.12)}
@media (max-width:520px){
  .consentement{padding:18px;gap:14px}
  .consentement__choix{width:100%}
  .consentement__choix .btn{flex:1 1 auto;justify-content:center}
}

/* ------------------------------------------------------------------ ecarts
   Ces classes remplacent les attributs style= qui trainaient dans le
   generateur. Un attribut style pese sur chaque page ou il apparait, ne se
   met pas en cache et complique la lecture du HTML ; il y en avait cent
   soixante-neuf. Les valeurs sont celles qui etaient ecrites en ligne : rien
   ne change a l'ecran. */
.mt-8{margin-top:8px}
.mt-10{margin-top:10px}
.mt-12{margin-top:12px}
.mt-14{margin-top:14px}
.mt-16{margin-top:16px}
.mt-18{margin-top:18px}
.mt-20{margin-top:20px}
.mt-22{margin-top:22px}
.mt-24{margin-top:24px}
.mt-26{margin-top:26px}
.mt-30{margin-top:30px}
.mt-pas{margin-top:var(--pas)}
.pt-0{padding-top:0}
/* Une colonne de texte ne se lit plus au-dela d'environ soixante-dix signes. */
.mesure{max-width:70ch}
.grille--large{grid-template-columns:repeat(auto-fit,minmax(280px,1fr));align-items:start}

/* Mouvement reduit : tout est immediat et tout est visible. Derniere regle du
   fichier pour passer devant les precedentes. */
@media (prefers-reduced-motion:reduce){
  *{transition:none !important;animation:none !important;scroll-behavior:auto !important}
  /* La regle ci-dessus fige le temoin d'envoi sur un arc ouvert, qui se lit
     comme un defaut d'affichage. On referme l'anneau : immobile, il redevient
     un temoin, et aria-busy porte l'information pour le reste. */
  .btn[aria-busy="true"]::before{border-top-color:currentColor;opacity:.55}
  ::view-transition-old(root),::view-transition-new(root){animation:none !important}
  /* Ce qui disparait : les mouvements decoratifs, ceux qui accompagnent sans
     rien dire. Agrandissements de photo, depliage du logo, glissements. */
  .btn--plein:hover::after,
  .carte:hover .carte__visuel img,.piece:hover .piece__visuel img,
  .voie:hover .voie__n,.voie:hover .voie__corps,.voie:hover .voie__suite,
  .marque:hover svg rect,.fil:hover{transform:none !important}

  /* Ce qui reste : le souleve au survol. Trois pixels ne sont pas le genre de
     mouvement que ce reglage cherche a eviter, et c'est lui qui dit « cet
     element repond ». On le raccourcit simplement, la regle * ci-dessus ayant
     coupe toutes les transitions. */
  .visionneuse,.visionneuse img{animation:none !important}
  .btn,.carte,.voie,.nav__lien,.nav__liste a,.marque,.pied a,.choix,.piece,.compteur button,
  .visionneuse__fermer{
    transition:transform var(--t-eclair) var(--courbe),box-shadow var(--t-eclair) var(--courbe),
               border-color var(--t-eclair) var(--courbe),background var(--t-eclair) var(--courbe),
               color var(--t-eclair) var(--courbe),opacity var(--t-eclair) var(--courbe) !important;
  }
}

/* Impression : les calques decoratifs fixes n'ont rien a faire sur papier. */
@media print{
  .lueur,.grain{display:none}
}

/* ---------- estimation depuis un fichier STL ----------
   Un seul bloc (.stl-bloc) pose a plusieurs endroits : bon de commande,
   /prix/, calculateur, /devis/. Sa mise en page suit la largeur de SON
   conteneur, pas celle de l'ecran : dans le bon de commande (760 px) il tient
   sur une colonne, sur /prix/ il passe a deux, pieces a gauche, apercu 3D et
   recapitulatif a droite, qui restent en vue pendant les reglages. */
.stl-bloc{container-type:inline-size;display:grid;gap:16px}
.stl-bloc__grille{display:grid;gap:clamp(20px,3vw,32px);align-items:start}
.stl-bloc__principal,.stl-bloc__cote{display:grid;gap:16px;min-width:0}
@container (min-width:860px){
  .stl-bloc__grille{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr)}
  .stl-bloc__cote{position:sticky;top:96px}
}
/* Hors du bon de commande, les champs du bloc prennent l'allure de ceux du
   formulaire : memes creux, memes bordures. */
.stl-bloc :is(select,input[type="number"],textarea){
  width:100%;font:inherit;color:var(--os);
  background:var(--encre);border:1px solid var(--ligne);border-radius:10px;
  padding:11px 13px;transition:border-color var(--t-moyen) var(--courbe);
}
.stl-bloc input[type="number"]{color-scheme:dark}
.stl-bloc textarea{resize:vertical;min-height:78px;line-height:1.55}
.stl-bloc textarea::placeholder{color:#6C7381}
.stl-bloc :is(select,input,textarea):hover{border-color:var(--os-doux)}
.stl-bloc :is(select,input,textarea).invalide{border-color:var(--rouge-trait)}
.stl-bloc input[type="checkbox"]{accent-color:var(--os)}
.stl-bloc [hidden]{display:none !important}
.stl-bloc__note{max-width:72ch}
.stl-bloc__total{
  display:flex;justify-content:space-between;align-items:baseline;gap:18px;
  border-top:1px solid var(--os-doux);padding-top:14px;
}
.stl-bloc__total b{color:var(--menthe);font-size:1.3rem;line-height:1;white-space:nowrap}
.stl-bloc .recapitulatif h3{font-size:clamp(1.12rem,1.05rem + .4vw,1.3rem)}

/* Zone de depot : un creux, comme les champs. Sur fond --encre (bon de
   commande), le creux passe en --encre-haut pour rester lisible. */
.depot{
  display:grid;justify-items:center;gap:8px;text-align:center;
  border:1px dashed var(--os-doux);border-radius:var(--rayon);
  background:var(--encre);padding:clamp(22px,4vw,34px) 18px;
  transition:border-color var(--t-moyen) var(--courbe),background var(--t-moyen) var(--courbe);
}
.depot--survol{border-color:var(--os);border-style:solid;background:var(--encre-haut)}
.depot__titre{font-size:clamp(1.05rem,1rem + .3vw,1.2rem)}

/* Une carte par piece. Choisie = cadre creme : la menthe reste aux prix. */
.stl-liste{list-style:none;display:grid;gap:14px}
.stl-liste:empty{display:none}
.stl{
  display:grid;gap:18px;cursor:pointer;
  border:1px solid var(--ligne);border-radius:var(--rayon);
  background:var(--encre);padding:16px;
  transition:border-color var(--t-survol) var(--courbe-survol);
}
.stl:hover{border-color:var(--os-doux)}
.stl--active,.stl--active:hover{border-color:var(--os)}
.stl--erreur{border-color:var(--rouge-trait);cursor:default}
.stl--erreur .stl__titre .prix__detail{color:var(--rouge)}
.stl--analyse .stl__vignette{animation:stl-lecture 1.2s ease-in-out infinite}
@keyframes stl-lecture{50%{opacity:.35}}
.stl__tete{display:flex;align-items:center;gap:14px}
.stl__vignette{
  width:64px;height:64px;flex-shrink:0;object-fit:contain;
  border-radius:var(--rayon-s);background:var(--encre-haut);
}
.stl__titre{display:grid;gap:2px;min-width:0;flex:1}
.stl__titre b{font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.stl__retirer{
  width:40px;height:40px;flex-shrink:0;display:grid;place-items:center;cursor:pointer;
  border:1px solid transparent;border-radius:999px;background:none;color:var(--os-doux);
  transition:border-color var(--t-survol) var(--courbe-survol),color var(--t-survol) var(--courbe-survol);
}
.stl__retirer svg{width:18px;height:18px;fill:currentColor}
.stl__retirer:hover{color:var(--os);border-color:var(--ligne)}
.stl__corps{display:grid;gap:18px}
.stl__faits{display:grid;grid-template-columns:repeat(auto-fit,minmax(125px,1fr));gap:12px 18px}
.stl__faits dt{color:var(--os-doux);font-size:.8rem}
.stl__faits dt i{font-style:normal}
.stl__faits dd{color:var(--os-vif);font-variant-numeric:tabular-nums}
/* La pastille se pose dans le menu, a gauche du nom de la teinte. */
.stl__teinte{position:relative;display:block}
.stl__teinte i{
  position:absolute;left:13px;top:50%;width:14px;height:14px;border-radius:50%;
  transform:translateY(-50%);box-shadow:inset 0 0 0 1px rgba(237,231,219,.35);pointer-events:none;
}
.stl-bloc .stl__teinte select{padding-left:36px}
.stl__alertes{list-style:none;display:grid;gap:8px}
.stl__alerte{font-size:.88rem;line-height:1.55;border-radius:var(--rayon-s);padding:9px 12px}
.stl__alerte--warn{color:var(--rouge);border:1px solid var(--rouge-trait);background:rgba(224,154,158,.07)}
.stl__alerte--info{color:var(--os-doux);border:1px solid var(--ligne)}
.stl__prix{justify-content:flex-end;border-top:1px solid var(--ligne);padding-top:14px}
.stl__prix:empty{display:none}

/* Apercu 3D */
.apercu3d{position:relative;overflow:hidden;border:1px solid var(--ligne);border-radius:var(--rayon);background:var(--encre)}
.apercu3d__scene{aspect-ratio:4/3;width:100%;cursor:grab;touch-action:none}
.apercu3d__scene:active{cursor:grabbing}
.apercu3d__scene canvas{display:block;width:100%;height:100%}
.apercu3d__vide,.apercu3d__indispo{
  position:absolute;inset:0 0 auto 0;aspect-ratio:4/3;display:none;place-items:center;
  padding:18px;text-align:center;color:var(--os-doux);font-size:.92rem;
}
.apercu3d--vide .apercu3d__vide{display:grid}
.apercu3d--indispo .apercu3d__indispo{display:grid}
.apercu3d--indispo .apercu3d__vide{display:none}
.apercu3d__legende{padding:11px 15px;border-top:1px solid var(--ligne);color:var(--os-doux);font-size:.86rem;line-height:1.55}
.apercu3d__legende:empty{display:none}
.apercu3d__legende b{font-weight:400;color:var(--os)}
.recap li small{display:block;color:var(--os-doux);font-size:.82rem;line-height:1.5;margin-top:2px}
.recap li > span:first-child{min-width:0;overflow-wrap:anywhere}

/* Dans le bon de commande, le formulaire est deja sur --encre-haut et ses
   panneaux sur --encre : l'apercu et le depot gardent ce creux. */
#bloc-stl .apercu3d{max-width:560px}


/* Teintes des bobines. Genere par build.py. */
.t3d3e3f{background:#3D3E3F}.t3d3d3c{background:#3d3d3c}.t424344{background:#424344}.t4f9ccc{background:#4f9ccc}.t888{background:#888}.t8d9499{background:#8d9499}.t9a9da2{background:#9a9da2}.tc7b299{background:#c7b299}.td34651{background:#d34651}.tebebe3{background:#ebebe3}.teceade{background:#eceade}.tf0f1f0{background:#f0f1f0}