/*
  WEBASTIDE — feuille de style du site
  Un site réalisé par Webastide · Antoine Lachaize · webastide.fr
  Direction retenue le 14/08/2026. Registre dépouillé : une seule famille
  typographique, un accent unique, aucun ornement.

  Ce qui est repris de la référence : UNE seule famille typographique, un
  accent unique, un titre qui porte tout, et aucun ornement (pas de surtitre
  en majuscules, pas de carte numérotée, pas de mot en italique coloré, pas
  de pilule, pas d'apparition au défilement).
  Une seule exception, décidée le 15/08/2026 : le carré ocre devant les titres
  de section, et les traits ocre qui les séparent. Les filets gris ne se
  voyaient pas, on ne savait plus où une section s'arrêtait. Le carré n'est
  pas un ornement de plus : c'est celui du logo. Hiérarchie à respecter, un
  trait ocre épais sépare deux SECTIONS, un filet gris fin ouvre une LISTE
  à l'intérieur d'une section. Ne pas mettre d'ocre partout.
  Ce qui en est écarté : le hero sans contenu. Ici le texte est dense, parce
  que ce site doit se référencer.
  La palette est celle de webastide.fr, conservée à la demande d'Antoine.
*/

@font-face {
  font-family: 'Switzer';
  src: url('../fonts/Switzer-Variable.woff2') format('woff2-variations');
  font-weight: 100 900; font-style: normal; font-display: swap;
}

/* Palette d'origine de webastide.fr, conservée telle quelle.
   Ce qui change par rapport au site actuel n'est pas la couleur : c'est la
   typographie (une seule famille au lieu de Fraunces + Inter), la densité du
   texte, et la suppression de tous les ornements. */
:root {
  --fond:    #F6F3EB;   /* papier */
  --fond-2:  #E7E2D6;   /* pierre, pour les blocs */
  --trait:   #D5CEBD;
  --texte:   #15231F;   /* encre */
  --gris:    #55645B;   /* encre secondaire */
  --ocre:    #8A5510;   /* ocre foncé : lisible en TEXTE sur fond clair */
  --ocre-a:  #D88C22;   /* l'ocre du logo, pour les aplats et le carré */
  --plein:   #15231F;   /* fond des boutons pleins */
  --plein-t: #F6F3EB;   /* texte des boutons pleins */
  --f: 'Switzer', -apple-system, 'Helvetica Neue', Arial, sans-serif;
  --large: 1280px;
}
/* Version sombre. Trois états possibles :
   - aucun choix fait + système clair  -> clair (le :root ci-dessus)
   - aucun choix fait + système sombre -> sombre (la media query)
   - choix fait par le visiteur        -> il l'emporte dans les deux sens */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="clair"]) {
    --fond: #0F0E0D; --fond-2: #171614; --trait: #2B2825;
    --texte: #F4F1EC; --gris: #9C968D;
    --ocre: #E9A54B; --ocre-a: #D88C22;
    --plein: #F0C078; --plein-t: #0F0E0D;
  }
}
:root[data-theme="sombre"] {
  --fond: #0F0E0D; --fond-2: #171614; --trait: #2B2825;
  --texte: #F4F1EC; --gris: #9C968D;
  --ocre: #E9A54B; --ocre-a: #D88C22;
  --plein: #F0C078; --plein-t: #0F0E0D;
}
:root { color-scheme: light; }
:root[data-theme="sombre"] { color-scheme: dark; }

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 90px; }
body {
  font-family: var(--f);
  font-size: 17px; line-height: 1.6;
  background: var(--fond); color: var(--texte);
  -webkit-font-smoothing: antialiased;
}

/* ── Mouvement ────────────────────────────────────────────────────────── */
/* Deux régimes, et un seul de chaque :
   1. une séquence d'ARRIVÉE, jouée une fois, échelonnée du titre aux chiffres ;
   2. une révélation liée au DÉFILEMENT, en CSS natif (animation-timeline),
      donc pilotée par la position réelle de la page et non par un
      déclenchement binaire : elle suit le doigt au lieu de sauter.
   Tout est neutralisé si le système demande moins d'animations. */
@media (prefers-reduced-motion: no-preference) {
  .anim {
    animation: entree .7s cubic-bezier(.16,.84,.28,1) backwards;
    animation-delay: calc(var(--i, 0) * 65ms);
  }
  @keyframes entree {
    from { opacity: 0; transform: translateY(14px); }
  }

  @supports (animation-timeline: view()) {
    .liste li, .coords > div, .sec__corps > .chapo {
      animation: revele linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 70%;
    }
    /* Pas d'opacité ici : pendant le défilement, un texte à 45 % d'opacité
       tombe à 2,23 de contraste, très en dessous du seuil de 4,5. Le
       glissement seul marque l'arrivée sans rendre le texte illisible. */
    @keyframes revele {
      from { transform: translateY(8px); }
    }
  }
}
a { color: inherit; text-decoration: none; }
:focus-visible { outline: 2px solid var(--ocre); outline-offset: 3px; }

.skip { position: absolute; left: 16px; top: -60px; background: var(--texte); color: var(--fond);
  padding: 10px 18px; font-weight: 600; z-index: 50; }
.skip:focus { top: 16px; }

/* ── Barre ───────────────────────────────────────────────────────────── */
.barre {
  position: relative;
  display: flex; align-items: center; gap: 34px;
  max-width: var(--large); margin: 0 auto; padding: 22px 40px;
}
/* Un trait ocre ferme l'en-tête, mais court : les traits de section font
   3 px sur toute la largeur, celui-ci fait 2 px sur la largeur du bloc logo
   + nom, mesurée à 120 px. Il ponctue sans concurrencer la structure. */
.barre::after {
  content: ""; position: absolute; bottom: 0; left: 40px;
  width: 120px; height: 2px; background: var(--ocre-a);
}
.marque { display: inline-flex; align-items: center; gap: 10px; font-weight: 700; font-size: 1.12rem; letter-spacing: -.02em; }
/* La zone touchable du logo passe de 29 a 45 px de haut sans decaler la
   barre : le padding agrandit la cible, la marge negative annule son
   effet sur la mise en page. */
a.marque { padding: 8px 0; margin: -8px 0; }
.marque svg { width: 22px; height: 22px; }
.barre__nav { display: flex; gap: 26px; margin-left: 12px; }
.barre__nav a { color: var(--gris); font-size: .95rem; font-weight: 500; transition: color .15s; }
.barre__nav a:hover { color: var(--texte); }

/* La page courante. L'information existait deja dans le HTML, via
   aria-current="page" pose sur chaque page : un lecteur d'ecran l'annoncait
   deja, mais rien ne le montrait a l'oeil. */
.barre__nav a[aria-current="page"] { color: var(--texte); position: relative; }
.barre__nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -7px;
  height: 2px; background: var(--ocre-a);
}
.barre__cta { margin-left: 0; }
.barre__droite { margin-left: auto; display: flex; align-items: center; gap: 12px; }

/* Bouton de thème : une seule icône à la fois, celle de ce qui va se passer */
.theme {
  display: inline-flex; align-items: center; justify-content: center;
  width: 50px; height: 50px; flex-shrink: 0;
  background: none; border: 1px solid var(--trait); border-radius: 4px;
  color: var(--texte); cursor: pointer;
  transition: border-color .2s, background .2s;
}
.theme:hover { border-color: var(--gris); background: var(--fond-2); }
/* Ne pas remettre `display: block` ici. `.theme svg` compte une classe et un
   type (0,1,1), `.theme__soleil` une seule classe (0,1,0) : la première
   l'emporte quel que soit l'ordre, et le `display: none` qui doit cacher
   l'icône inutile ne s'applique plus. Les deux icônes s'affichaient alors
   côte à côte en thème clair. C'est aux règles ci-dessous, et à elles
   seules, de décider laquelle des deux se montre. */
.theme svg { width: 18px; height: 18px; }
/* L'icône annonce l'ACTION, pas l'état : en clair on voit la lune, parce que
   cliquer amène la nuit. Cohérent avec le libellé lu par les lecteurs d'écran. */
.theme__soleil { display: none; }
.theme__lune { display: block; }
:root[data-theme="sombre"] .theme__soleil { display: block; }
:root[data-theme="sombre"] .theme__lune { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="clair"]) .theme__soleil { display: block; }
  :root:not([data-theme="clair"]) .theme__lune { display: none; }
  :root[data-theme="clair"] .theme__soleil { display: none; }
  :root[data-theme="clair"] .theme__lune { display: block; }
}

/* ── Boutons : rectangles francs, aucun arrondi de pilule ─────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--f); font-size: .95rem; font-weight: 600;
  padding: 12px 20px; border: 1px solid transparent; border-radius: 4px;
  transition: background .15s, border-color .15s, color .15s;
}
.btn--plein { background: var(--plein); color: var(--plein-t); }
.btn--plein:hover { background: var(--ocre-a); color: var(--texte); }
.btn--ligne { border-color: var(--trait); color: var(--texte); }
.btn--ligne:hover { border-color: var(--gris); background: var(--fond-2); }

/* ── Hero : le titre porte tout, il n'y a rien d'autre ────────────────── */
.hero { max-width: var(--large); margin: 0 auto; padding: 76px 40px 0; }
.hero__titre {
  font-size: clamp(2.6rem, 6.4vw, 5.6rem);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -.035em;
  max-width: 17ch;
}
.hero__bas {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 40px; align-items: end;
  margin-top: 30px;
}
.hero__sous { color: var(--gris); font-size: 1.06rem; max-width: 56ch; }
.hero__actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* Bandeau de chiffres, en tête de page : des faits, pas des slogans */
.chiffres {
  display: grid; grid-template-columns: repeat(4, 1fr);
  margin-top: 72px; border-top: 3px solid var(--ocre-a);
}
.chiffres > div { padding: 24px 26px; border-right: 1px solid var(--trait); }
/* La premiere colonne ne suit aucun trait : elle reste alignee sur la marge
   de la page, comme les titres et les paragraphes. */
.chiffres > div:first-child { padding-left: 0; }
.chiffres > div:last-child { border-right: none; }
.chiffres dt { font-size: .82rem; color: var(--gris); margin-bottom: 6px; }
.chiffres dd { font-size: 1.55rem; font-weight: 600; letter-spacing: -.02em; }
.chiffres > div:nth-child(4) dd { color: var(--ocre); }

/* ── Sections de contenu ──────────────────────────────────────────────── */
.sec { max-width: var(--large); margin: 0 auto; padding: 96px 40px; }
.sec--bord { border-top: 3px solid var(--ocre-a); }
.sec__grille { display: grid; grid-template-columns: minmax(0, 38%) minmax(0, 1fr); gap: 60px; }
/* Titre et repère descendent ensemble. Deux niveaux sont nécessaires et le
   raccourci ne marche pas : la cellule .sec__tete doit s'étirer sur toute la
   hauteur de la section pour donner sa course au collant, et c'est le bloc
   intérieur .sec__colle qui colle. Rendre .sec__tete lui-même collant avec
   align-self: start le réduit à la hauteur du titre, et il n'y a alors plus
   qu'un seul point de défilement où il tient, mesuré. */
.sec__colle { position: sticky; top: 34px; }
.sec__tete h2 {
  font-size: clamp(1.85rem, 3.4vw, 2.9rem);
  font-weight: 500; line-height: 1.06; letter-spacing: -.03em;
  position: relative; top: auto;
}
.chapo { font-size: 1.24rem; line-height: 1.5; letter-spacing: -.012em; margin-bottom: 22px; }
.sec__corps p { color: var(--gris); margin-bottom: 18px; max-width: 68ch; }
.sec__corps .chapo { color: var(--texte); }

/* ── Prose des pages légales ───────────────────────────────────────────────
   Mentions légales et CGPS sont du texte suivi : des sous-titres, des listes
   et des tableaux, que les autres pages n'emploient pas. Ces règles ne
   servent qu'à elles, d'où le préfixe .legal qui les tient à l'écart du
   reste du site. */
.legal .sec__corps h3 {
  font-size: 1.06rem; font-weight: 600; color: var(--texte);
  margin: 26px 0 10px; letter-spacing: -.01em;
}
.legal .sec__corps h3:first-child { margin-top: 0; }
.legal .sec__corps ul, .legal .sec__corps ol {
  color: var(--gris); margin: 0 0 18px; padding-left: 20px; max-width: 68ch;
}
.legal .sec__corps li { margin-bottom: 9px; line-height: 1.65; }
.legal .sec__corps li::marker { color: var(--ocre); }
.legal .sec__corps strong { color: var(--texte); font-weight: 600; }
/* Un tableau de CGPS est plus large qu'un téléphone. Il défile dans sa
   propre boîte : sans ça, c'est la page entière qui partirait de travers. */
.legal__tableau { overflow-x: auto; margin: 0 0 20px; max-width: 68ch; }
.legal__tableau table { border-collapse: collapse; width: 100%; font-size: .93rem; }
.legal__tableau th, .legal__tableau td {
  border: 1px solid var(--trait); padding: 9px 12px;
  text-align: left; vertical-align: top; color: var(--gris);
}
.legal__tableau th { color: var(--texte); font-weight: 600; background: var(--fond-2); }
.legal__maj { font-size: .88rem; color: var(--gris); margin-top: 8px; }
.legal__retour { margin-top: 4px; }

/* Fil d'Ariane. Les sept pages intérieures en portent un ; l'accueil non,
   puisqu'il est la racine et n'aurait rien à afficher avant lui-même. Le
   balisage BreadcrumbList décrit exactement ce qui est affiché ici, jamais
   un chemin invisible. */
.ariane {
  font-size: .9rem; color: var(--gris); margin-bottom: 20px;
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
}
.ariane a { color: var(--gris); text-decoration: none; border-bottom: 1px solid var(--trait); }
.ariane a:hover { color: var(--texte); border-bottom-color: currentColor; }
.ariane [aria-current] { color: var(--texte); }

/* Repère de colonne : une phrase courte sous le titre de section. La colonne
   de gauche restait vide sur toute la hauteur du corps, ce qui coûtait de la
   surface de contenu sans rien apporter. Le repère n'est pas collant, à la
   différence du titre : il s'efface au défilement et laisse le titre seul,
   comme avant. */
.sec__repere {
  margin-top: 20px; padding-left: 24px; max-width: 34ch;
  font-size: .96rem; line-height: 1.5; color: var(--gris);
}
@media (max-width: 900px) { .sec__repere { padding-left: 20px; margin-top: 12px; } }

.liste { list-style: none; margin-top: 34px; border-top: 1px solid var(--trait); }
.liste li {
  padding: 18px 0; border-bottom: 1px solid var(--trait);
  color: var(--gris); display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 24px;
}
.liste li > span:first-child { color: var(--texte); font-weight: 600; }

/* Le marqueur d'état passe SOUS le libellé, pour tous les items et pas
   seulement ceux qui débordent. « Référencement naturel » suivi du marqueur
   demande 265 px là où la colonne en fait 210 : il partait à la ligne tout
   seul, et les trois lignes ne s'alignaient plus entre elles. */
.liste li > span:first-child .marqueur { display: block; width: fit-content; margin: 7px 0 0; vertical-align: baseline; }

/* ── Tarifs : carrousel en perspective, sans JavaScript ───────────────── */
/* Coverflow et non cylindre : sur un cylindre à quatre faces, les cartes
   voisines sont perpendiculaires à l'écran, donc invisibles, et l'effet de
   rotation disparaît. Ici la carte choisie vient au centre et face au
   lecteur, les autres s'inclinent de chaque côté et reculent.
   L'état vit dans des boutons radio : clavier natif, aucun JavaScript, et
   tout le contenu reste dans le code donc indexable. */
/* clip et non hidden : hidden crée un contexte de défilement qui neutraliserait
   le position: sticky des titres de section. Les cartes latérales partent à
   translateX(152%) et sortaient de la fenêtre, ce qui donnait 112 px de
   défilement horizontal sur toute la page, mesuré. */
.carrousel { position: relative; max-width: var(--large); margin: 44px auto 0; padding: 0 40px; overflow-x: clip; }
/* position: fixed et non absolute, et ce n'est pas un detail de style.
   Un bouton radio masque en absolute se place en haut de son conteneur :
   cliquer sur son label lui donne le focus, et le navigateur fait defiler la
   page jusqu'a lui. Mesure avant correction, en cliquant sur une bulle en bas
   de section : saut de 779 px vers le haut. En fixed, il est toujours dans la
   fenetre, donc il n'y a plus rien a atteindre. Il reste focalisable au
   clavier et lisible par un lecteur d'ecran. */
.offres__etat { position: fixed; top: 0; left: 0; opacity: 0; width: 1px; height: 1px; pointer-events: none; }

/* Les flèches du carrousel de tarifs. Huit labels, deux visibles à la fois :
   celui qui recule et celui qui avance depuis la formule affichée. Le tour
   boucle, la quatrième ramène à la première. */
.offres__fleche {
  position: absolute; top: 200px; z-index: 6;
  width: 44px; height: 44px; display: none;
  align-items: center; justify-content: center;
  cursor: pointer; background: var(--fond); border: 1px solid var(--trait);
  transition: background .2s, border-color .2s, color .2s;
}
.offres__fleche:hover { background: var(--plein); border-color: var(--plein); color: var(--plein-t); }
.offres__fleche--g { left: 40px; }
.offres__fleche--d { right: 40px; }
.offres__fleche::before {
  content: ""; width: 11px; height: 11px;
  border-top: 2px solid currentColor; border-right: 2px solid currentColor;
}
.offres__fleche--g::before { transform: rotate(-135deg); margin-left: 4px; }
.offres__fleche--d::before { transform: rotate(45deg); margin-right: 4px; }

.offres__etat:nth-of-type(1):checked ~ .offres__nav .offres__fleche[data-de="1"],
.offres__etat:nth-of-type(2):checked ~ .offres__nav .offres__fleche[data-de="2"],
.offres__etat:nth-of-type(3):checked ~ .offres__nav .offres__fleche[data-de="3"],
.offres__etat:nth-of-type(4):checked ~ .offres__nav .offres__fleche[data-de="4"] { display: flex; }

.offres { height: 480px; margin-bottom: 34px; }
.offres__scene { position: relative; width: 100%; height: 100%; }

.offre {
  position: absolute; top: 0; left: 50%;
  width: 370px; margin-left: -185px; height: 100%;
  display: flex; flex-direction: column;
  border: 1px solid var(--trait); background: var(--fond);
  transform-origin: center center;
  transition: transform .68s cubic-bezier(.3,.72,.26,1), opacity .55s,
              box-shadow .55s, border-color .55s, filter .55s;
  /* Ce sont le flou et l'inclinaison qui disent qu'une carte est en
     arrière-plan, pas la transparence. Valeur calculée et non choisie à
     l'oeil : en dessous de 0.9, le texte composé sur le fond tombe sous
     4,5:1, et le thème clair est le plus exigeant des deux (0.9 contre 0.8
     en sombre). Mesuré le 15/08/2026. */
  opacity: .9;
  filter: blur(2.4px);
}
/* Sur telephone la liste est depliante : aucune carte n'est en arriere-plan,
   donc ni flou ni transparence, et la 3D est neutralisee. */
@media (max-width: 900px) {
  .offre { opacity: 1; filter: none; transform: none; }
}
/* Le coverflow ne vaut que sur grand ecran. Ces regles sont tres
   specifiques : laissees hors requete media, elles battaient la version
   mobile, qui remet pourtant tout a plat. Resultat mesure sur 390 px : les
   trois formules non choisies restaient floutees a 2,4 px et projetees hors
   du cadre, donc illisibles et hors d'atteinte. */
@media (min-width: 901px) {
  .offres__etat:nth-of-type(1):checked ~ .offres .offre:nth-of-type(1) { transform: perspective(1600px) rotateY(0deg) translateX(0) translateZ(70px) scale(1); opacity: 1; z-index: 3; filter: none; }
  .offres__etat:nth-of-type(1):checked ~ .offres .offre:nth-of-type(2) { transform: perspective(1600px) rotateY(-36deg) translateX(80%) translateZ(-40px) scale(.94); opacity: .9; z-index: 2; }
  .offres__etat:nth-of-type(1):checked ~ .offres .offre:nth-of-type(3) { transform: perspective(1600px) rotateY(-46deg) translateX(152%) translateZ(-170px) scale(.86); opacity: .9; z-index: 1; }
  .offres__etat:nth-of-type(1):checked ~ .offres .offre:nth-of-type(4) { transform: perspective(1600px) rotateY(-46deg) translateX(152%) translateZ(-170px) scale(.86); opacity: .9; z-index: 1; }
  .offres__etat:nth-of-type(2):checked ~ .offres .offre:nth-of-type(1) { transform: perspective(1600px) rotateY(36deg) translateX(-80%) translateZ(-40px) scale(.94); opacity: .9; z-index: 2; }
  .offres__etat:nth-of-type(2):checked ~ .offres .offre:nth-of-type(2) { transform: perspective(1600px) rotateY(0deg) translateX(0) translateZ(70px) scale(1); opacity: 1; z-index: 3; filter: none; }
  .offres__etat:nth-of-type(2):checked ~ .offres .offre:nth-of-type(3) { transform: perspective(1600px) rotateY(-36deg) translateX(80%) translateZ(-40px) scale(.94); opacity: .9; z-index: 2; }
  .offres__etat:nth-of-type(2):checked ~ .offres .offre:nth-of-type(4) { transform: perspective(1600px) rotateY(-46deg) translateX(152%) translateZ(-170px) scale(.86); opacity: .9; z-index: 1; }
  .offres__etat:nth-of-type(3):checked ~ .offres .offre:nth-of-type(1) { transform: perspective(1600px) rotateY(46deg) translateX(-152%) translateZ(-170px) scale(.86); opacity: .9; z-index: 1; }
  .offres__etat:nth-of-type(3):checked ~ .offres .offre:nth-of-type(2) { transform: perspective(1600px) rotateY(36deg) translateX(-80%) translateZ(-40px) scale(.94); opacity: .9; z-index: 2; }
  .offres__etat:nth-of-type(3):checked ~ .offres .offre:nth-of-type(3) { transform: perspective(1600px) rotateY(0deg) translateX(0) translateZ(70px) scale(1); opacity: 1; z-index: 3; filter: none; }
  .offres__etat:nth-of-type(3):checked ~ .offres .offre:nth-of-type(4) { transform: perspective(1600px) rotateY(-36deg) translateX(80%) translateZ(-40px) scale(.94); opacity: .9; z-index: 2; }
  .offres__etat:nth-of-type(4):checked ~ .offres .offre:nth-of-type(1) { transform: perspective(1600px) rotateY(46deg) translateX(-152%) translateZ(-170px) scale(.86); opacity: .9; z-index: 1; }
  .offres__etat:nth-of-type(4):checked ~ .offres .offre:nth-of-type(2) { transform: perspective(1600px) rotateY(46deg) translateX(-152%) translateZ(-170px) scale(.86); opacity: .9; z-index: 1; }
  .offres__etat:nth-of-type(4):checked ~ .offres .offre:nth-of-type(3) { transform: perspective(1600px) rotateY(36deg) translateX(-80%) translateZ(-40px) scale(.94); opacity: .9; z-index: 2; }
  .offres__etat:nth-of-type(4):checked ~ .offres .offre:nth-of-type(4) { transform: perspective(1600px) rotateY(0deg) translateX(0) translateZ(70px) scale(1); opacity: 1; z-index: 3; filter: none; }
}

.offres__etat:nth-of-type(1):checked ~ .offres .offre:nth-of-type(1),
.offres__etat:nth-of-type(2):checked ~ .offres .offre:nth-of-type(2),
.offres__etat:nth-of-type(3):checked ~ .offres .offre:nth-of-type(3),
.offres__etat:nth-of-type(4):checked ~ .offres .offre:nth-of-type(4) {
  border-color: var(--gris);
  box-shadow: 0 22px 52px -26px rgba(21, 35, 31, .4);
  background: var(--fond-2);
}

.offre__tete {
  display: flex; flex-direction: column; gap: 8px;
  padding: 26px 26px 20px; cursor: pointer;
  border-bottom: 1px solid var(--trait);
}
.offre__nom { font-weight: 600; font-size: 1.02rem; letter-spacing: -.015em; }
.offre__prix { font-size: 2rem; font-weight: 600; letter-spacing: -.03em; line-height: 1.05; color: var(--ocre); }
.offre__prix em {
  display: block; font-style: normal; font-size: .8rem; font-weight: 500;
  color: var(--gris); letter-spacing: 0; margin-bottom: 2px;
}
.offre__prix--texte { font-size: 1.45rem; }

/* Le marqueur porte un margin-left, utile quand il suit un libellé. En tête
   de ligne il décalait le badge de 8 px vers la droite, alors que le titre et
   la nature de la prestation, eux, partent du bord. */
.offre__prix .marqueur { margin-left: 0; vertical-align: baseline; }
.offre__prix .marqueur + em { margin-top: 7px; margin-bottom: 0; }
.offre__corps { padding: 20px 26px 24px; overflow: auto; }
.offre__corps p { color: var(--gris); margin-bottom: 14px; font-size: .97rem; }
.offre__corps ul { list-style: none; display: grid; gap: 8px; }
.offre__corps li { color: var(--texte); font-size: .95rem; padding-left: 18px; position: relative; }
.offre__corps li::before {
  content: ""; position: absolute; left: 0; top: .8em;
  width: 8px; height: 1px; background: var(--ocre-a);
}
.offre__note { font-size: .86rem; margin-top: 14px; margin-bottom: 0 !important; }

.offres__etat:focus-visible ~ .offres .offres__scene { outline: 2px solid var(--ocre); outline-offset: 8px; }

/* ── Repères : les formules restent comparables sans cliquer ──────────── */
/* Le choix de la formule, sous le carrousel, en bulles centrées.
   Deux niveaux à ne pas confondre : la FAMILLE est une bulle pleine, la
   FORMULE une bulle au contour. */
.reperes {
  list-style: none; display: flex; flex-wrap: wrap; justify-content: center;
  gap: 9px; margin: 28px auto 0; padding: 0 40px;
}
.reperes label {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 8px 17px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--trait); color: var(--gris);
  transition: border-color .2s, color .2s, background .2s;
}
.reperes span { font-size: .88rem; }
.reperes b { font-size: .88rem; font-weight: 600; letter-spacing: -.01em; }
.reperes label:hover { border-color: var(--gris); color: var(--texte); }
.offres__etat:nth-of-type(1):checked ~ .reperes li:nth-child(1) label,
.offres__etat:nth-of-type(2):checked ~ .reperes li:nth-child(2) label,
.offres__etat:nth-of-type(3):checked ~ .reperes li:nth-child(3) label,
.offres__etat:nth-of-type(4):checked ~ .reperes li:nth-child(4) label {
  border-color: var(--ocre-a); color: var(--ocre); background: var(--fond-2);
}


/* Formules à venir : annoncées, mais visiblement pas vendables aujourd'hui */
.offre--venir { background: transparent; }
.offre--venir .offre__nom { color: var(--gris); }
.offre--venir .offre__prix { color: var(--ocre); font-size: 1.3rem; }
.offres__etat:checked + .offre--venir { background: var(--fond-2); }
.offre--venir .offre__tete { border-left: 2px solid var(--ocre-a); margin-left: -1px; padding-left: 22px; }

/* ── Coordonnées ──────────────────────────────────────────────────────── */
.coords { display: grid; grid-template-columns: 1fr 1fr; gap: 0; margin-top: 32px; border-top: 1px solid var(--trait); }
.coords > div { padding: 18px 24px 18px 0; border-bottom: 1px solid var(--trait); }
.coords dt { font-size: .8rem; color: var(--gris); margin-bottom: 5px; }
.coords dd { font-size: 1.06rem; font-weight: 500; }
.coords a { border-bottom: 1px solid var(--trait); transition: border-color .2s; }
.coords a:hover { border-color: var(--ocre-a); }

/* ── Pied ─────────────────────────────────────────────────────────────── */
.pied { max-width: var(--large); margin: 0 auto; padding: 40px; border-top: 3px solid var(--ocre-a); }
.pied p { color: var(--gris); font-size: .86rem; }
.pied__haut { display: flex; align-items: center; justify-content: space-between; gap: 30px; flex-wrap: wrap; margin-bottom: 26px; }
.pied__nav { display: flex; gap: 24px; flex-wrap: wrap; }
.pied__nav a { color: var(--gris); font-size: .93rem; transition: color .18s; }
.pied__nav a:hover { color: var(--texte); }
.pied__legal { padding-top: 22px; border-top: 1px solid var(--trait); }
.pied__legal strong { color: var(--texte); }
.pied__maquette { margin-top: 16px; }

/* ── Responsive ───────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .barre { flex-wrap: wrap; gap: 16px; padding: 18px 22px; }
  .barre::after { left: 22px; }
  /* la nav défile horizontalement plutôt que de passer sur deux lignes */
  .barre__nav {
    order: 3; width: 100%; margin-left: 0;
    overflow-x: auto; flex-wrap: nowrap; gap: 20px;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .barre__nav::-webkit-scrollbar { display: none; }
  .barre__nav a { white-space: nowrap; font-size: .92rem; }
  /* Le menu déborde tant que la fenêtre fait moins de 558 px, mesuré au
     pixel près, et « Réalisations » se retrouve hors écran. La barre de
     défilement étant masquée juste au-dessus, rien ne disait qu'on pouvait
     la faire glisser : ce fondu sur le bord droit le dit. Au-dessus, les
     six liens tiennent et un fondu y mentirait.

     ⚠️ Ce seuil dépend du nombre de liens du menu, et il se remesure, il
     ne se devine pas. Six liens : 558 px. Sept liens : 646 px, constaté
     le 17/08 en ajoutant une page, puis revenu à 558 en la retirant.
     Toute entrée ajoutée ou renommée dans `outils/navigation.py` oblige à
     remesurer, sinon le fondu disparaît sur une bande d'écrans où le menu
     déborde encore, ou apparaît là où il ne déborde plus. */
  @media (max-width: 557px) {
    .barre__nav {
      -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 38px), transparent);
              mask-image: linear-gradient(to right, #000 calc(100% - 38px), transparent);
    }
  }
  .hero { padding: 44px 22px 0; }
  .hero__bas { grid-template-columns: 1fr; gap: 26px; align-items: start; margin-top: 30px; }
  .chiffres { grid-template-columns: 1fr 1fr; margin-top: 48px; }
  .chiffres > div { padding: 18px 20px; }
  /* Sur deux colonnes, ce sont les cellules de gauche qui ouvrent la ligne. */
  .chiffres > div:nth-child(odd) { padding-left: 0; }
  .chiffres > div:nth-child(2) { border-right: none; }
  .chiffres > div:nth-child(3), .chiffres > div:nth-child(4) { border-top: 1px solid var(--trait); }
  .sec { padding: 60px 22px; }
  .sec__grille { grid-template-columns: 1fr; gap: 26px; }
  .liste li { grid-template-columns: 1fr; gap: 4px; }
  .pied { padding: 30px 22px; }
  /* Un accordéon horizontal est illisible sur un téléphone : il s'empile,
     et c'est la hauteur qui s'ouvre au lieu de la largeur. */
  .offres { flex-direction: column; padding: 0 22px; margin-top: 30px; }
  /* en colonne, flex-basis:0 écraserait chaque bloc à une hauteur nulle :
     chaque formule reprend sa hauteur naturelle et c'est le contenu qui
     s'ouvre, plus la largeur */
  .offre { flex: 0 0 auto; border-right: 1px solid var(--trait); border-bottom: none; }
  .offres .offre:last-of-type { border-bottom: 1px solid var(--trait); }
  .offres__etat:checked + .offre { flex-grow: 0; }
  .offre__tete { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 16px; padding: 18px 20px; }
  .offre__prix { font-size: 1.45rem; }
  /* Sur un téléphone, la 3D est illisible : on repasse en liste dépliante. */
  .carrousel { padding: 0 22px; margin-top: 30px; }
  /* Les flèches pilotent un défilement qui n'existe plus une fois la liste
     dépliée, et elles se posaient par-dessus le texte de la carte ouverte. */
  .offres__nav { display: none; }
  .offres { perspective: none; height: auto; margin-bottom: 22px; }
  .offres__scene { position: static; transform: none; transform-style: flat; height: auto; }
  .offre,
  .offres__etat:checked ~ .offres .offre {
    position: static; width: auto; height: auto; margin: 0 0 -1px;
    opacity: 1; transform: none; box-shadow: none; z-index: auto;
  }
  .offre__tete { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 16px; padding: 16px 18px; }
  .offre__prix { font-size: 1.4rem; }
  .offre__prix em { display: inline; font-size: .78rem; margin: 0 5px; }
  .offre__corps { display: none; padding: 0 18px 20px; }
  .offres__etat:nth-of-type(1):checked ~ .offres .offre:nth-of-type(1) .offre__corps,
  .offres__etat:nth-of-type(2):checked ~ .offres .offre:nth-of-type(2) .offre__corps,
  .offres__etat:nth-of-type(3):checked ~ .offres .offre:nth-of-type(3) .offre__corps,
  .offres__etat:nth-of-type(4):checked ~ .offres .offre:nth-of-type(4) .offre__corps { display: block; }
  .reperes { display: none; }
  .barre__droite { gap: 8px; }
  .coords { grid-template-columns: 1fr; margin-top: 24px; }
  .coords > div { padding: 15px 0; }
  .pied__haut { margin-bottom: 20px; }
  /* Le courriel et le telephone du pied sont des actions, pas de la mention
     legale : sur un telephone on appuie dessus pour appeler ou ecrire. Ils
     faisaient 16 px de haut. Le padding les rend atteignables au pouce sans
     changer la mise en page. */
  .pied__legal a { display: inline-block; padding: 7px 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: .001ms !important;
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
  }
}

/* ── Pages intérieures ────────────────────────────────────────────────── */
.hero--page { padding-bottom: 24px; }
.hero--page .hero__titre { font-size: clamp(2.2rem, 4.6vw, 3.9rem); max-width: 20ch; }
.hero--page .hero__sous { margin-top: 26px; max-width: 62ch; }

/* Les liens dans le texte se voient : soulignés, pas seulement colorés */
.sec__corps p a, .liste span a {
  color: var(--ocre); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
  transition: color .18s;
}
.sec__corps p a:hover, .liste span a:hover { color: var(--texte); }
/* Un bouton dans un paragraphe ne doit pas hériter du soulignement des liens
   de texte. La couleur, elle, dépend du type de bouton : ne la forcer que
   sur le bouton plein. Forcée sur tous, elle rendait un bouton à simple
   contour invisible, son fond étant transparent : texte couleur du fond sur
   le fond, rapport de contraste 1,00. */
.sec__corps p a.btn { text-decoration: none; }
.sec__corps p a.btn--plein { color: var(--plein-t); }
.sec__corps p a.btn--plein:hover { color: var(--texte); }
.sec__corps p a.btn--ligne { color: var(--texte); }

/* Marqueur « À venir » dans une liste de services.
   Le plancher de 12 px est délibéré : .68rem seul donnait 10,9 px, en
   capitales espacées, ce qui est le pire cas de lisibilité. Le `max` laisse
   le marqueur grandir avec le reste si la police de base augmente, mais
   l'empêche de redescendre sous le seuil. */
.marqueur {
  display: inline-block; margin-left: 8px; vertical-align: 2px;
  font-size: max(.68rem, 12px); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ocre); border: 1px solid var(--ocre-a); padding: 2px 7px; border-radius: 3px;
}

/* ── Étapes : une vraie séquence, donc numérotée ──────────────────────── */
.etapes { list-style: none; counter-reset: etape; margin-top: 30px; border-top: 1px solid var(--trait); }
.etapes li {
  counter-increment: etape;
  padding: 20px 0 20px 46px; border-bottom: 1px solid var(--trait);
  color: var(--gris); position: relative;
}
.etapes li::before {
  content: counter(etape); position: absolute; left: 0; top: 20px;
  font-weight: 600; font-size: .95rem; color: var(--ocre);
  font-variant-numeric: tabular-nums;
}
.etapes span { display: block; color: var(--texte); font-weight: 600; margin-bottom: 4px; }

/* ── Formulaire ───────────────────────────────────────────────────────── */
.formulaire { display: grid; gap: 16px; margin-top: 44px; max-width: 34rem; }
.formulaire__intro { color: var(--texte) !important; font-weight: 600; margin-bottom: 0 !important; }
.formulaire label { display: grid; gap: 7px; font-size: .9rem; font-weight: 600; }
.formulaire input, .formulaire textarea {
  font-family: var(--f); font-size: 1rem; font-weight: 400;
  padding: 12px 14px; border: 1px solid var(--trait); border-radius: 4px;
  background: var(--fond); color: var(--texte); resize: vertical;
  transition: border-color .18s;
}
.formulaire input:focus, .formulaire textarea:focus { outline: none; border-color: var(--ocre-a); }
.formulaire button { justify-self: start; }
.formulaire__note { font-size: .84rem; color: var(--gris); font-weight: 400; }

@media (max-width: 900px) {
  .hero--page { padding-bottom: 10px; }
  .hero--page .hero__sous { margin-top: 20px; }
  .formulaire { margin-top: 32px; }
  .etapes li { padding-left: 38px; }
}

/* ── Questions fréquentes ─────────────────────────────────────────────── */
/* Réponses en clair, pas en accordéon : c'est du contenu, il doit se lire
   et se référencer sans qu'on ait à cliquer. */
.qr { padding: 26px 0; border-bottom: 1px solid var(--trait); }
.qr:first-of-type { border-top: 1px solid var(--trait); margin-top: 34px; }
.qr h3 {
  font-size: 1.14rem; font-weight: 600; letter-spacing: -.015em;
  margin-bottom: 10px; max-width: 60ch;
}
.qr p { color: var(--gris); margin-bottom: 12px; max-width: 68ch; }
.qr p:last-child { margin-bottom: 0; }

/* ── Emblème de page ──────────────────────────────────────────────────── */
/* Tous les emblèmes dérivent de l'arche du logo. Ce sont des traits, pas des
   images : quelques centaines d'octets, nets à toutes les tailles, et ils
   suivent la couleur du thème. Le tracé se dessine à l'arrivée, comme sur le
   site d'origine. */
/* Deux colonnes : le texte prend la largeur qu'il lui faut, l'emblème occupe
   tout le reste et se centre dedans, horizontalement ET verticalement. C'est
   ce qui le pose au milieu du vide à droite du titre au lieu de le coller en
   haut à droite. */
.hero { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 40px; align-items: center; }
.hero__texte { min-width: 0; }
.hero .chiffres, .hero__bas { grid-column: 1 / -1; }
.embleme { display: flex; align-items: center; justify-content: center; align-self: center; }
.embleme__svg { width: 210px; height: 210px; color: var(--texte); display: block; }
/* Sur l'accueil, le titre fait quatre lignes : l'emblème peut respirer. */
.hero:not(.hero--page) .embleme__svg { width: 260px; height: 260px; }

@media (prefers-reduced-motion: no-preference) {
  /* Les traits se dessinent, le carré ocre se pose en dernier. */
  .embleme__svg .t, .embleme__svg .t1, .embleme__svg .t2, .embleme__svg .t3,
  .embleme__svg .s, .embleme__svg .s2, .embleme__svg .fl,
  .embleme__svg .o1, .embleme__svg .o2, .embleme__svg .g {
    stroke-dasharray: 700; stroke-dashoffset: 700;
    animation: tracer 1.5s cubic-bezier(.3,.7,.3,1) forwards;
  }
  .embleme__svg .g  { animation-duration: 1s; animation-delay: .05s; }
  .embleme__svg .s, .embleme__svg .s2 { animation-duration: .8s; }
  .embleme__svg .t2 { animation-delay: .16s; }
  .embleme__svg .t3 { animation-delay: .32s; }
  .embleme__svg .o1 { animation-delay: .5s; animation-duration: 1.2s; }
  .embleme__svg .o2 { animation-delay: .66s; animation-duration: 1.2s; }
  .embleme__svg .fl { animation-delay: .8s; animation-duration: .7s; }
  .embleme__svg .c, .embleme__svg .c2 {
    opacity: 0; transform-origin: center;
    animation: poser .55s cubic-bezier(.2,1.2,.4,1) forwards 1.15s;
  }
  @keyframes tracer { to { stroke-dashoffset: 0; } }
  @keyframes poser { from { opacity: 0; transform: scale(.55); } to { opacity: 1; transform: scale(1); } }
}

@media (max-width: 1180px) {
  .hero { gap: 28px; }
  .embleme__svg { width: 168px; height: 168px; }
  .hero:not(.hero--page) .embleme__svg { width: 200px; height: 200px; }
}
@media (max-width: 860px) {
  .hero { grid-template-columns: 1fr; gap: 22px; }
  .embleme { justify-content: flex-start; order: -1; padding-top: 0; }
  .embleme__svg,
  .hero:not(.hero--page) .embleme__svg { width: 116px; height: 116px; }
}

/* ── Pictogramme et chiffre ───────────────────────────────────────────── */
/* Le pictogramme dit de quoi parle la page, le chiffre dit ce qu'il faut en
   retenir. Même épaisseur de trait et même accent ocre que le logo. */
.cote { position: relative; width: 240px; text-align: center; }
.cote__picto { width: 108px; height: 108px; display: block; margin: 0 auto 22px; color: var(--texte); }
.cote__chiffre {
  display: block; font-size: 2.3rem; font-weight: 600;
  letter-spacing: -.04em; line-height: 1; color: var(--ocre); white-space: nowrap;
}
.cote__label { display: block; margin-top: 8px; font-size: .84rem; color: var(--gris); }

@media (max-width: 1180px) {
  .cote { width: 200px; }
  .cote__picto { width: 88px; height: 88px; margin-bottom: 16px; }
  .cote__chiffre { font-size: 1.9rem; }
}
@media (max-width: 860px) {
  .cote { width: auto; display: flex; align-items: center; gap: 14px; text-align: left; }
  .cote__picto { width: 54px; height: 54px; margin: 0; flex-shrink: 0; }
  .cote__chiffre { font-size: 1.5rem; }
  .cote__label { margin-top: 2px; font-size: .76rem; }
}

/* ── Marquage des sections ────────────────────────────────────────────── */
/* Les traits gris ne se voyaient pas : on ne savait pas où une section
   s'arrêtait. Ils passent en ocre épais, et chaque titre reçoit le carré du
   logo. Ce n'est pas un ornement pris ailleurs, c'est le carré de l'arche. */
.sec__tete h2 { padding-left: 24px; }   /* position: relative plus haut, cela ancre le carre */
.sec__tete h2::before {
  content: ""; position: absolute; left: 0; top: .38em;
  width: 11px; height: 11px; background: var(--ocre-a);
}
@media (max-width: 900px) {
  /* Sur une colonne unique, le collant n'a plus de sens : le titre resterait
     plaqué en haut de l'écran pendant que son propre texte défile dessous.
     Le carré, lui, garde son ancrage relatif sur le titre. */
  .sec__colle { position: static; }
  .sec__tete h2 { position: relative; top: auto; padding-left: 20px; }
  .sec__tete h2::before { width: 9px; height: 9px; }
}

/* ── Gamme : trois familles, un seul carrousel affiché ────────────────── */
/* Les trois carrousels coexistent dans le code, un seul est affiché. Le
   choix vit dans des boutons radio, comme les formules elles-mêmes : pas de
   JavaScript, navigation au clavier native, et tout le contenu reste dans la
   page donc indexable. */
/* La gamme passe en colonne flex pour une seule raison : l'ordre. Le
   carrousel doit s'afficher AVANT ses sélecteurs, alors que les boutons radio
   doivent rester avant tout le monde dans le code pour que le combinateur ~
   les atteigne. order règle ça sans toucher au HTML. */
.gamme { display: flex; flex-direction: column; max-width: var(--large); margin: 40px auto 0; }
.gamme__etat { position: fixed; top: 0; left: 0; opacity: 0; width: 1px; height: 1px; }

.gamme > .carrousel { order: 1; }
.gamme__barre { order: 2; }

/* Les familles : bulles pleines quand actives, pour dominer les formules. */
.gamme__barre {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  padding: 0 40px; margin-top: 30px;
}
.gamme__onglet {
  padding: 9px 20px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--trait); color: var(--gris);
  font-weight: 600; font-size: .93rem;
  transition: background .2s, border-color .2s, color .2s;
}
.gamme__onglet:hover { border-color: var(--gris); color: var(--texte); }
.gamme__onglet .marqueur { margin-left: 7px; }

/* Le fond ocre est le même dans les deux thèmes : le texte est donc fixé en
   encre foncée, et non sur une variable qui s'inverserait avec le thème. */
#cat-site:checked ~ .gamme__barre [for="cat-site"],
#cat-vis:checked  ~ .gamme__barre [for="cat-vis"],
#cat-pack:checked ~ .gamme__barre [for="cat-pack"] {
  background: var(--ocre-a); border-color: var(--ocre-a); color: #15231F;
}
#cat-site:checked ~ .gamme__barre [for="cat-site"] .marqueur,
#cat-vis:checked  ~ .gamme__barre [for="cat-vis"] .marqueur,
#cat-pack:checked ~ .gamme__barre [for="cat-pack"] .marqueur {
  color: #15231F; border-color: #15231F;
}
#cat-site:focus-visible ~ .gamme__barre [for="cat-site"],
#cat-vis:focus-visible  ~ .gamme__barre [for="cat-vis"],
#cat-pack:focus-visible ~ .gamme__barre [for="cat-pack"] {
  outline: 2px solid var(--ocre); outline-offset: 3px;
}

.gamme > .carrousel { display: none; }
#cat-site:checked ~ .carrousel--site,
#cat-vis:checked  ~ .carrousel--vis,
#cat-pack:checked ~ .carrousel--pack { display: block; }

@media (max-width: 900px) {
  .gamme__barre { padding: 0 22px; }
  .gamme__onglet { padding: 8px 15px; font-size: .88rem; }
  .reperes { padding: 0 22px; gap: 7px; }
  .reperes label { padding: 7px 14px; }
}

/* ── Bande des réalisations ───────────────────────────────────────────── */
/* Motif retenu le 15/08/2026 : une rangée de panneaux verticaux, la
   référence réelle en grand à gauche, les six démonstrations à droite.
   Chaque panneau montre une photo du métier au repos, et la capture du site
   au survol : on garde l'allure, et la preuve arrive quand le visiteur
   s'y intéresse. Le panneau survolé s'élargit, les autres se resserrent. */

.bande { max-width: var(--large); margin: 40px auto 0; padding: 0 40px; }
.bande__rail { display: flex; gap: 8px; height: 540px; }

.panneau {
  position: relative; overflow: hidden;
  flex: 1 1 0; min-width: 0;
  display: block; color: #fff; text-decoration: none;
  background: #14120F;
  /* Animer flex-grow oblige le navigateur a recalculer la mise en page des
     sept panneaux a chaque image. C'est le prix d'un accordeon, mais on lui
     evite tout le reste : plus aucun filtre a recalculer pendant que la
     taille change, et une seule duree pour tout ce qui bouge. */
  transition: flex-grow .5s cubic-bezier(.22,.61,.24,1);
}
/* Prevenu seulement quand la souris entre dans la bande : garder sept couches
   en permanence couterait plus cher que le gain. */
.bande__rail:hover .panneau { will-change: flex-grow; }
/* Les sept panneaux ont la même largeur, référence client comprise. Elle
   dominait à 3,4 contre 1 : ça se tenait tant qu'il n'y avait qu'un client,
   mais le motif ne survivrait pas au deuxième, et rien ne justifie de mettre
   un client en vitrine quand les suivants n'auront pas donné leur accord.
   La distinction reste dans le libellé « Client · en ligne », pas dans la
   taille. Décidé le 16/08/2026. */
.panneau:hover { flex-grow: 3.6; }

.panneau img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: opacity .5s cubic-bezier(.22,.61,.24,1);
}
/* La capture est cadrée par le HAUT. Quand le panneau s'élargit, un cadrage
   centré couperait l'en-tête du site, c'est-à-dire ce qui l'identifie : son
   logo, son menu, son titre. */
/* La capture ne sert qu'au survol. En balise <img>, le navigateur la
   telecharge quand meme : sept images inutiles au chargement, 290 Ko. En fond
   CSS pose seulement quand la souris entre dans la bande, rien ne part tant
   que personne ne regarde. La variable --site porte l'adresse, c'est une
   donnee et non une regle de presentation. */
/* La capture du site au survol est retiree le 16/08/2026 : les photos de
   metier tiennent seules, et l'echange photo/capture faisait charger 296 Ko
   de captures des que la souris entrait dans la bande. Le survol ne fait plus
   qu'elargir le panneau et reveler le lien. */
/* La photo est désaturée au repos : la bande se lit comme un ensemble, et la
   couleur revient sur le panneau que l'on regarde. */
/* Les photos sont livrees deja desaturees et assombries : ce que faisait
   filter: grayscale(.55) brightness(.72) est cuit dans le WebP. Un filtre sur
   une image qui change de taille se recalcule a chaque image. */
/* Le nom reste affiche au survol : plus rien ne vient le porter a la place. */
.panneau__nom { transition: opacity .5s; }

/* Un voile assombri en bas, pour que le texte tienne sur n'importe quelle photo */
.panneau::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 62%;
  background: linear-gradient(to top, rgba(10,9,8,.92) 12%, rgba(10,9,8,.55) 48%, transparent);
  pointer-events: none; transition: opacity .4s;
}
.panneau__texte {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 20px 14px; pointer-events: none;
  text-align: center;
}
.panneau__metier {
  display: block; font-size: max(.68rem, 12px); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ocre-a);
  margin-bottom: 7px;
}
/* Le nom occupe TOUJOURS la hauteur de deux lignes, qu'il en fasse une ou
   deux. Le bloc de texte est ancré en bas : sans cette réserve, un nom d'une
   seule ligne fait remonter le libellé ocre de 20 px par rapport à son voisin
   sur deux lignes, et les sept panneaux ne s'alignent plus. Mesuré le
   02/09/2026 avant correction : 59,7 px d'écart entre le libellé le plus haut
   et le plus bas sur les six démonstrations, 159 px en comptant le panneau
   client. Le nombre de lignes change aussi avec la largeur de la fenêtre,
   donc l'écart bougeait pendant le redimensionnement. */
.panneau__nom {
  display: block; font-size: 1.02rem; font-weight: 600; letter-spacing: -.01em;
  line-height: 1.2;
  min-height: 2.4em;
}
.panneau__voir {
  display: block; margin-top: 10px; font-size: .82rem; font-weight: 600;
  color: rgba(255,255,255,.62);
  opacity: 0; transform: translateY(6px);
  transition: opacity .5s, transform .5s;
}
.panneau:hover .panneau__voir { opacity: 1; transform: none; }
/* Le panneau client n'a plus ni nom plus gros ni retrait plus large.
   Supprimé le 02/09/2026 : c'était le reste de l'époque où il occupait 3,4
   fois la largeur des autres. Cette largeur a été égalisée le 16/08/2026 avec
   pour motif écrit « la distinction reste dans le libellé Client · en ligne,
   pas dans la taille » — mais la taille du nom, elle, n'avait pas suivi.
   Mesure avant correction : 24 px contre 16,32 px, soit 47 % d'écart, et un
   retrait de 26/24 px contre 16/10 px qui décalait tout le bloc. */

/* ── Alignement des sept panneaux ──────────────────────────────────────
   Le bloc de texte est ancré en bas du panneau, donc TOUT ce qui grandit
   au-dessus du bas pousse les lignes visibles vers le haut. Deux des trois
   lignes changeaient de hauteur d'un panneau à l'autre :

   1. Le libellé ocre passe à deux lignes sur « Chambres d'hôtes » et sur
      « Client · en ligne », et le seuil dépend de la largeur de la fenêtre.
   2. La ligne de survol va de 1 à 4 lignes selon la longueur du texte, et
      elle occupe la place MÊME QUAND ELLE EST INVISIBLE. C'était la cause
      principale, et la moins visible : un élément à `opacity: 0` reste dans
      le flux et pousse ses voisins.

   Mesures du 02/09/2026 sur les sept panneaux, avant correction :
   libellé ocre à 1657 px pour le plus haut et 1699 px pour le plus bas,
   soit 42 px d'écart après avoir déjà égalisé la taille et le retrait.

   On réserve donc une hauteur fixe aux deux, uniquement au-dessus de 901 px
   où la ligne de survol est cachée au repos. En dessous, elle est toujours
   affichée et doit pouvoir prendre la place qu'il lui faut. */
@media (min-width: 901px) {
  .panneau__texte { padding: 16px 10px; }
  /* Deux lignes réservées, texte calé en bas pour rester collé au nom. */
  .panneau__metier {
    display: flex; align-items: flex-end; justify-content: center;
    min-height: 3.2em;
  }
  /* Deux lignes réservées. Au repos le texte est invisible, au survol le
     panneau est 3,6 fois plus large et le texte y tient. */
  .panneau__voir { height: 3.2em; overflow: hidden; }
}
/* La note tient sur une seule ligne. La phrase sur le survol n'a aucun sens
   au doigt : elle disparaît sur téléphone, où il ne reste que la mention du
   fictif, qui elle vaut partout. */
.bande__note { font-size: .82rem; color: var(--gris); margin: 16px 40px 0; }

/* Sur un téléphone, six colonnes de 50 px n'ont aucun sens : la bande
   devient une file que l'on fait défiler au doigt. */
@media (max-width: 900px) {
  .bande { padding: 0; }
  .bande__rail {
    height: 400px; gap: 10px; padding: 0 22px;
    overflow-x: auto; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }
  .bande__rail::-webkit-scrollbar { display: none; }
  .panneau { flex: 0 0 200px; scroll-snap-align: start; }
  .panneau--reel, .bande__rail:hover .panneau--reel, .panneau:hover { flex: 0 0 260px; }
  /* Sans survol possible, la capture ne se declenche pas : on montre la photo,
     et le lien ouvre le site. */
  .panneau__voir { opacity: 1; transform: none; }
  .bande__note { margin: 12px 22px 0; }
  .bande__note-souris { display: none; }
}

/* ── Sommaire, intégré au hero ────────────────────────────────────────
   Ajouté le 08/09/2026. Le cours « Quelle taille de contenu » demande un
   sommaire au-delà de 800 mots : quatre pages sont concernées.

   POURQUOI UN <details> ET PAS UNE SIMPLE LISTE
   Mesuré le 08/09/2026 sur un écran de 390 px : déplié, le sommaire occupe
   200 px et repousse le premier titre de section en fin de premier écran.
   Le lecteur voit de la navigation avant de voir de la matière, alors que
   le même cours demande de répondre à l'intention « au début ». Il est donc
   replié sur petit écran, et déplié à partir de 720 px où la place existe.
   Le repli est natif, sans JavaScript : rien à recalculer côté CSP.

   L'accueil n'a pas de sommaire : son hero porte déjà deux boutons et
   quatre chiffres, et on ne la consulte pas, on la parcourt. */
.hero__somm { margin: 30px 0 0; max-width: 40ch; }
.hero__somm > summary {
  cursor: pointer; list-style: none; padding: 9px 0;
  border-top: 1px solid var(--trait); border-bottom: 1px solid var(--trait);
  font-size: .78rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gris); font-weight: 600;
}
.hero__somm > summary::-webkit-details-marker { display: none; }
.hero__somm > summary::after { content: "+"; float: right; font-size: 1.05rem; line-height: 1; }
.hero__somm[open] > summary::after { content: "\2212"; }
.hero__somm > summary:hover, .hero__somm > summary:focus-visible { color: var(--ocre); }
.hero__somm ul { margin: 0; padding: 0; list-style: none; }
.hero__somm li { margin: 0; border-bottom: 1px solid var(--trait); }
.hero__somm a {
  display: block; padding: 9px 2px 9px 0;
  color: var(--gris); text-decoration: none;
  font-size: .93rem; line-height: 1.35;
  transition: color .15s ease, padding-left .15s ease;
}
.hero__somm a::after { content: "\2192"; float: right; opacity: .45; }
.hero__somm a:hover, .hero__somm a:focus-visible { color: var(--ocre); padding-left: 6px; }
.hero__somm a:hover::after, .hero__somm a:focus-visible::after { opacity: 1; }

/* À partir de 720 px la place existe : on masque le déclencheur et on
   affiche la liste, que le visiteur ait ouvert le bloc ou non. */
/* À partir de 720 px, le script ouvre le bloc et le déclencheur devient
   inutile : on le masque. On ne le masque QUE s'il est ouvert, sinon une
   page sans JavaScript n'afficherait plus rien du tout.
   Mesuré le 08/09/2026 : masquer le summary et forcer `display:block` sur
   la liste ne suffit pas, un <details> fermé masque son contenu par un
   mécanisme interne au navigateur que le CSS ne surcharge pas. */
@media (min-width: 720px) {
  .hero__somm[open] > summary { display: none; }
  .hero__somm[open] { border-top: 1px solid var(--trait); }
}
@media (prefers-reduced-motion: reduce) { .hero__somm a { transition: none; } }
/* La cible d'une ancre ne doit pas se coller au bord haut de l'écran. */
[id] { scroll-margin-top: 24px; }

/* ── Retour en haut ────────────────────────────────────────────────────
   Demandé le 08/09/2026 : sur les pages longues, revenir en tête exigeait
   de remonter à la main. Le bouton est créé par le script de thème, il
   n'apparaît qu'après 600 px de défilement, et il disparaît à l'impression. */
.haut {
  position: fixed; right: 20px; bottom: 20px; z-index: 40;
  width: 42px; height: 42px; display: grid; place-items: center;
  background: var(--plein); color: var(--plein-t);
  border: 1px solid var(--trait); border-radius: 50%;
  text-decoration: none; font-size: 1.05rem; line-height: 1;
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.haut--vu { opacity: .92; visibility: visible; transform: none; }
.haut:hover, .haut:focus-visible { opacity: 1; }
@media print { .haut { display: none; } }
@media (prefers-reduced-motion: reduce) { .haut { transition: none; } }
