/* ==========================================================================
   Accueil
   ========================================================================== */

/* --------------------------------------------------------------------------
   Héros
   -------------------------------------------------------------------------- */

.hero {
  border-bottom: 1px solid var(--filet-sombre);
  display: flex;
  flex-wrap: wrap;
  background: var(--charbon);
}

.hero__texte {
  flex: 1.1 1 460px;
  min-height: 700px;
  box-sizing: border-box;
  padding: clamp(56px, 7vw, 104px) var(--gouttiere);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 30px;
}

.hero__titre { max-width: 15ch; }

.hero__sous {
  font: 500 17.5px/1.75 var(--courant);
  color: var(--texte-sombre-2);
  max-width: 46ch;
}

/* L'appel à l'action arrive après le titre et le sous-titre : le regard a eu
   le temps de lire, le mouvement le ramène alors sur le bouton. */
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 10px;
  opacity: 0;
  transform: scale(.72);
  transform-origin: center;
  animation: entree-appel .75s cubic-bezier(.34, 1.4, .5, 1) 1.15s forwards;
}

/* Le bouton grandit jusqu'à sa taille : la courbe dépasse légèrement avant
   de se poser, ce qui accroche l'œil sans faire sursauter la mise en page. */
@keyframes entree-appel {
  from { opacity: 0; transform: scale(.72); }
  to   { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .hero__actions { opacity: 1; transform: none; animation: none; }
}

.btn--large {
  font-size: 14px;
  padding: 21px 32px;
}

.hero__photo {
  flex: 1 1 420px;
  min-height: 700px;
  position: relative;
  overflow: hidden;
  background-image: url('../img/hero-atelier-1400.webp');
  background-size: cover;
  background-position: 62% 38%;
}

/* Écrans larges ou à forte densité : version 1800 px. */
@media (min-width: 1200px), (min-resolution: 2dppx) {
  .hero__photo { background-image: url('../img/hero-atelier-1800.webp'); }
}

.hero__voile {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(14, 14, 13, .86) 0%, rgba(14, 14, 13, .16) 32%, rgba(14, 14, 13, 0) 100%);
}

/* --------------------------------------------------------------------------
   Bascule particulier / architecte
   -------------------------------------------------------------------------- */

.profil { background: var(--blanc); }

.profil__inner {
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  box-sizing: border-box;
  padding: clamp(32px, 3.6vw, 52px) var(--gouttiere);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 22px clamp(28px, 4vw, 56px);
}

.profil__intro {
  flex: 0 1 300px;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.profil__intro .surtitre { font-size: 11px; }

.profil__question {
  font: 400 clamp(23px, 2.2vw, 31px)/1.14 var(--titre);
  color: var(--texte-clair-1);
  text-wrap: pretty;
}

.profil__row {
  flex: 1 1 460px;
  min-width: 280px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px clamp(16px, 2vw, 26px);
}

/* Les deux libellés et l'interrupteur sont de vrais boutons : accessibles au
   clavier, contrairement aux <span onClick> de la maquette. */
.profil__label,
.profil__switch {
  font: inherit;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  text-align: left;
}

.profil__label {
  flex: 1 1 200px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: color .3s;
  color: var(--texte-clair-2);
}
.profil__label.is-actif { color: var(--charbon); }

/* Le libellé de gauche est aligné à droite, contre l'interrupteur : les deux
   textes sont alors à égale distance de lui. Sans ça, « PARTICULIER » étant
   court, il restait collé au bord gauche de sa colonne, très loin du bouton,
   alors que le libellé de droite en part directement. */
.profil__label:first-child {
  align-items: flex-end;
  text-align: right;
}

.profil__label-nom  { font: 600 13.5px/1.25 var(--courant); letter-spacing: .1em; }
.profil__label-sous { font: 500 12px/1.5 var(--courant); opacity: .75; }

.profil__switch {
  position: relative;
  flex: none;
  width: 82px;
  height: 44px;
  border-radius: 22px;
  background: var(--texte-clair-1);
  display: block;
  --knob-course: 38px;
}

.profil__knob {
  position: absolute;
  top: 5px;
  left: 5px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--laiton);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .3);
  transform: translateX(0);
  transition: transform .42s cubic-bezier(.22, .8, .3, 1);
  display: block;
}
.profil__switch[aria-checked="true"] .profil__knob { transform: translateX(var(--knob-course)); }

/* --------------------------------------------------------------------------
   Arguments
   -------------------------------------------------------------------------- */

.args {
  background: var(--zinc);
  border-bottom: 1px solid var(--filet-sombre);
}

.args__inner {
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  box-sizing: border-box;
  padding: clamp(60px, 7vw, 110px) var(--gouttiere) clamp(44px, 5vw, 80px);
  display: flex;
  flex-wrap: wrap;
  gap: clamp(30px, 4vw, 72px);
}

.args__intro {
  flex: 0 1 300px;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.args__titre {
  font: 400 clamp(30px, 3vw, 42px)/1.08 var(--titre);
  color: var(--texte-clair-1);
  text-wrap: pretty;
}

.args__liste {
  flex: 1 1 520px;
  min-width: 300px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 0 clamp(30px, 4vw, 64px);
}

.arg {
  display: flex;
  gap: clamp(18px, 2.4vw, 36px);
  align-items: flex-start;
  padding: clamp(26px, 3vw, 40px) 0;
  border-top: 1px solid var(--filet-clair);
}

.arg__num {
  font: 400 clamp(30px, 3vw, 44px)/1 var(--titre);
  color: var(--or-fonce);
  flex: none;
  width: clamp(48px, 5vw, 74px);
}

.arg__corps {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 200px;
}

.arg__titre {
  font: 400 clamp(22px, 2vw, 29px)/1.18 var(--titre);
  color: var(--texte-clair-1);
  text-wrap: pretty;
}

.arg__desc {
  font: 500 15px/1.8 var(--courant);
  color: var(--texte-clair-2);
  max-width: 44ch;
}

/* --------------------------------------------------------------------------
   Bande défilante — sélection de réalisations

   La piste contient la liste deux fois ; l'animation la translate de la
   moitié de sa largeur, ce qui reboucle sans saut visible. L'écart entre
   cartes est une marge, pas un `gap` : avec un `gap`, la moitié exacte ne
   tomberait pas sur une frontière de carte et la boucle sauterait.
   -------------------------------------------------------------------------- */

.selection {
  display: flex;
  align-items: center;
  overflow: hidden;
  /* La marge gauche est portée par la colonne de texte ; seule la droite est
     à rétablir ici, la galerie ne doit plus bavier hors du cadre. */
  padding: clamp(56px, 6vw, 96px) var(--gouttiere) clamp(56px, 6vw, 96px) 0;
}

/* Colonne de gauche : le dégradé la fond dans la bande, qui semble passer
   dessous. Le chevauchement négatif évite une frontière nette entre les deux. */
.selection__texte {
  position: relative;
  z-index: 2;
  flex: 0 0 clamp(280px, 32%, 480px);
  box-sizing: border-box;
  align-self: stretch;
  padding: 0 clamp(56px, 6vw, 110px) 0 var(--gouttiere);
  margin-right: clamp(-110px, -6vw, -56px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 14px;
  background: linear-gradient(90deg,
    var(--charbon) 0%,
    var(--charbon) 52%,
    rgba(14, 14, 13, .92) 72%,
    rgba(14, 14, 13, 0) 100%);
}
.selection__texte .t-h2 { font-size: clamp(32px, 3.4vw, 46px); }

.selection__lien {
  font: 500 13px/1 var(--courant);
  letter-spacing: .14em;
  color: var(--laiton);
  border-bottom: 1px solid var(--laiton);
  padding-bottom: 5px;
  align-self: flex-start;
  margin-top: 6px;
}
.selection__lien a { color: inherit; }

/* --------------------------------------------------------------------------
   Bande défilante des réalisations

   La piste porte la liste deux fois et se translate de la moitié de sa
   largeur : le rebouclage tombe exactement sur une frontière de carte, donc
   invisible. L'écart entre cartes est une marge et non un `gap`, sans quoi la
   moitié exacte ne coïnciderait pas avec une carte et la boucle sauterait.

   À l'entrée dans l'écran, chaque carte descend du coin haut droit et se pose.
   L'entrée agit sur la carte, le défilement sur la piste : deux éléments
   différents, donc deux transformations qui ne se contrarient pas.
   -------------------------------------------------------------------------- */

/* La bande est une zone réellement défilante, pas une piste translatée : le
   défilement automatique est piloté par le script, et le glissement au doigt
   — ou à deux doigts sur pavé tactile — fonctionne alors nativement, dans les
   deux sens, sans qu'aucun bouton soit nécessaire. */
.expo {
  /* Hauteur de chute des cartes. Le rembourrage haut réserve la place : une
     zone défilante horizontalement rogne ce qui dépasse en haut. */
  --levee: 78px;

  flex: 1 1 auto;
  min-width: 0;

  /* Le rembourrage réserve la place de la chute, mais il creusait un vide
     sous « toute la galerie ». La marge négative remonte la bande : les
     cartes au repos se rapprochent du texte, et les cartes encore hautes
     occupent l'espace vide à droite du lien, là où il n'y a rien. */
  padding-top: var(--levee);
  margin-top: calc(var(--levee) * -0.62);
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.expo::-webkit-scrollbar { display: none; }

.expo__piste {
  display: flex;
  width: max-content;
}

.expo__vue {
  position: relative;
  display: block;
  flex: none;
  width: clamp(240px, 22vw, 320px);
  height: clamp(280px, 26vw, 380px);
  margin-right: 16px;
  overflow: hidden;
  background: var(--charbon);
  text-decoration: none;
  color: inherit;

  /* Le décalage d'entrée est posé image par image par le script, en fonction
     de la position de la carte dans la bande — pas par une transition. Une
     transition ne jouerait qu'une fois ; ici chaque carte qui arrive par la
     droite se remet en file, en continu. Sans JavaScript, les cartes sont
     simplement alignées. */
  will-change: transform, opacity;
}

.expo__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .7s cubic-bezier(.16, 1, .3, 1);
}
.expo__vue:hover .expo__photo { transform: scale(1.06); }

.expo__voile {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    transparent 38%,
    rgba(14, 14, 13, .62) 64%,
    rgba(14, 14, 13, .95) 100%);
}

.expo__legende {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  text-align: left;
}

.expo__metal {
  font: 500 10px/1 var(--courant);
  letter-spacing: .16em;
  color: var(--or-profond);
  white-space: nowrap;
}

.expo__titre {
  font: 400 20px/1.16 var(--titre);
  color: var(--texte-sombre-1);
  text-wrap: pretty;
}

/* Sans JavaScript, ou si l'utilisateur a demandé moins d'animations, les
   cartes sont visibles d'emblée et la bande ne défile pas. */
@media (prefers-reduced-motion: reduce) {
  .expo__vue { opacity: 1; transform: none; }
  .expo { scroll-behavior: auto; }

  .sf__num {
    background-image: none;
    color: var(--or-fonce);
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   Savoir-faire — huit domaines
   -------------------------------------------------------------------------- */

.sf {
  background: var(--charbon);
  border-bottom: 1px solid var(--filet-sombre);
  overflow: hidden;
}

.sf__inner {
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  box-sizing: border-box;
  padding: clamp(56px, 6vw, 104px) 0 clamp(56px, 6vw, 104px) var(--gouttiere);
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0;
}

.sf__head {
  flex: 0 1 340px;
  min-width: 260px;
  padding: clamp(24px, 3vw, 48px) clamp(32px, 4vw, 56px) clamp(24px, 3vw, 48px) 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
}
.sf__titre { font-size: clamp(32px, 3.4vw, 46px); line-height: 1.06; }

.sf__intro {
  font: 500 14px/1.8 var(--courant);
  color: var(--texte-sombre-3);
  max-width: 30ch;
}
/* « Survolez » n'a pas de sens au doigt : la consigne change sous 680 px. */
.sf__intro-mobile { display: none; }

.sf__panneau {
  flex: 1 1 560px;
  min-width: 320px;
  background: var(--zinc);
  padding: clamp(32px, 3.6vw, 56px) calc(clamp(28px, 3.4vw, 56px) + var(--gouttiere)) clamp(32px, 3.6vw, 56px) clamp(28px, 3.4vw, 56px);
  margin: clamp(-28px, -3vw, -16px) calc(-1 * var(--gouttiere)) clamp(-28px, -3vw, -16px) 0;
  box-sizing: border-box;
}

.sf__liste {
  display: flex;
  flex-direction: column;
}

.sf__ligne {
  border-top: 1px solid var(--filet-clair-fort);
  cursor: pointer;
  transition: background .25s;
}
.sf__ligne:hover { background: #dedcd8; }

/* Ni filet avant le premier domaine, ni après le dernier : ils fermaient la
   liste sans rien séparer. Seuls les filets intérieurs subsistent. */
.sf__liste > .sf__ligne:first-child { border-top: none; }
.sf__ligne--derniere { border-bottom: none; }

/* L'en-tête est un bouton : au doigt il déplie la ligne, au clavier il est
   atteignable. En desktop il garde l'apparence d'une simple ligne, le survol
   continuant de piloter la vignette. */
.sf__entete {
  display: flex;
  align-items: baseline;
  gap: 14px 28px;
  padding: 22px 4px;
  flex-wrap: wrap;
  width: 100%;
  font: inherit;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
}

/* Le signe d'ouverture n'a de sens que là où la ligne se déplie. */
.sf__signe { display: none; }

.sf__num  { font: 500 12px/1 var(--courant); letter-spacing: .1em; color: var(--or-fonce); width: 30px; }
.sf__nom  { font: 400 24px/1.22 var(--titre); color: var(--texte-clair-1); flex: 1 1 220px; }
.sf__desc { font: 500 14px/1.7 var(--courant); color: var(--texte-clair-2); flex: 1 1 230px; }

/* Soulignement qui se déploie sous le titre survolé. */
.sf__nom-texte { position: relative; }
.sf__nom-texte::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 0;
  height: 2px;
  background: var(--or-profond);
  transition: width .4s cubic-bezier(.25, .46, .45, .94);
}
.sf__ligne:hover .sf__nom-texte::after { width: 100%; }

/* En desktop, la photo n'est plus dépliée dans la page : elle apparaît dans
   une vignette qui suit le curseur (voir .apercu). Le bloc reste dans le
   balisage pour le mobile. */
.sf__revele { display: none; overflow: hidden; }

/* --------------------------------------------------------------------------
   Vignette de survol — desktop uniquement
   -------------------------------------------------------------------------- */

.apercu {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1000;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(var(--x, 0), var(--y, 0), 0) translateY(10px) scale(.96);
  transition: opacity .25s ease, transform .25s cubic-bezier(.34, 1.56, .64, 1);
  will-change: transform, opacity;
}
.apercu.est-visible {
  opacity: 1;
  transform: translate3d(var(--x, 0), var(--y, 0), 0) translateY(0) scale(1);
}

.apercu__cadre {
  width: 320px;
  background: var(--charbon);
  border: 1px solid var(--filet-sombre);
  border-left: 4px solid var(--or-profond);
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, .8), 0 0 60px rgba(207, 144, 32, .12);
}

.apercu__photo {
  display: block;
  width: 100%;
  height: 210px;
  object-fit: cover;
}

.apercu__texte {
  padding: 14px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.apercu__metal   { font: 600 10px/1 var(--courant); letter-spacing: .16em; color: var(--laiton); }
.apercu__legende { font: 400 20px/1.16 var(--titre); color: var(--texte-sombre-1); }

/* La vignette suppose un curseur : elle ne sert qu'au-dessus de 680 px et
   seulement sur un pointeur fin. */
@media (min-width: 681px) and (pointer: fine) {
  .apercu { display: block; }
}

.sf__carte {
  margin: 0 4px 26px;
  display: flex;
  align-items: stretch;
  gap: 0;
}

.sf__photo {
  width: min(360px, 42%);
  height: 230px;
  flex: none;
  object-fit: cover;
  display: block;
}

.sf__cartouche {
  flex: 1;
  background: var(--texte-clair-1);
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 6px;
  border-left: 4px solid var(--or-profond);
}

.sf__metal   { font: 600 10px/1 var(--courant); letter-spacing: .16em; color: var(--laiton); }
.sf__legende { font: 400 22px/1.16 var(--titre); color: var(--texte-sombre-1); }

@keyframes glisse {
  from { max-height: 0; opacity: 0; }
  to   { max-height: 320px; opacity: 1; }
}

/* --------------------------------------------------------------------------
   Repères et matières
   -------------------------------------------------------------------------- */

.reperes__inner {
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  box-sizing: border-box;
  padding: clamp(48px, 5vw, 84px) var(--gouttiere);
  display: flex;
  flex-direction: column;
  gap: clamp(34px, 4vw, 56px);
}

.reperes {
  display: flex;
  flex-wrap: wrap;
  gap: 34px 0;
  margin: 0 calc(-1 * clamp(18px, 2.4vw, 40px));
}

.repere {
  flex: 1 1 200px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0 clamp(18px, 2.4vw, 40px);
}
.repere + .repere { border-left: 1px solid var(--filet-sombre); }

.repere__valeur  { font: 400 clamp(38px, 4vw, 58px)/1 var(--titre); color: var(--texte-sombre-1); }
.repere__libelle { font: 600 11px/1.4 var(--courant); letter-spacing: .2em; color: var(--or-profond); }

.matieres {
  display: flex;
  flex-wrap: wrap;
  gap: 16px 40px;
  align-items: center;
  padding-top: clamp(28px, 3vw, 44px);
  border-top: 1px solid var(--filet-sombre);
}

.matieres__titre {
  font: 500 11px/1 var(--courant);
  letter-spacing: .24em;
  color: var(--texte-sombre-3);
  margin-right: 8px;
}

.matiere {
  font: 400 19px/1 var(--titre);
  letter-spacing: .06em;
  color: var(--texte-sombre-1);
}

/* --------------------------------------------------------------------------
   Chiffres qui défilent

   Le rouleau porte deux fois la suite 0-9 et glisse d'un tour complet avant
   de s'arrêter sur le chiffre visé. La hauteur d'une case est mesurée par
   chiffres.js : elle suit la taille fluide du titre.

   Sans JavaScript, aucun rouleau n'est créé et les chiffres s'affichent
   normalement.
   -------------------------------------------------------------------------- */

.chiffres {
  display: inline-flex;
  align-items: baseline;
}

.chiffres__fixe { white-space: pre; }

.chiffre {
  position: relative;
  display: inline-block;
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}

.chiffre__gabarit { visibility: hidden; }

.chiffre__ruban {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  transform: translateY(0);
  transition: transform .95s cubic-bezier(.22, 1, .36, 1);
  transition-delay: calc(var(--rang, 0) * 70ms);
}

.chiffre__case {
  display: block;
  height: var(--hauteur, 1em);
  line-height: var(--hauteur, 1em);
  text-align: center;
}

/* Le rouleau s'arrête sur la seconde occurrence du chiffre : dix cases plus
   loin, donc après un tour entier. */
.est-lance .chiffre__ruban {
  transform: translateY(calc(-1 * var(--arret, 0) * var(--hauteur, 1em)));
}

/* --------------------------------------------------------------------------
   Demande de devis
   -------------------------------------------------------------------------- */

.devis {
  background: var(--charbon);
  border-bottom: 1px solid var(--filet-sombre);
  overflow: hidden;
}

.devis__inner {
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  box-sizing: border-box;
  padding: clamp(56px, 6vw, 104px) var(--gouttiere) clamp(56px, 6vw, 104px) 0;
  display: flex;
  flex-wrap: wrap-reverse;
  align-items: stretch;
  gap: 0;
}

.devis__panneau {
  flex: 1 1 520px;
  min-width: 320px;
  background: var(--blanc);
  padding: clamp(32px, 3.6vw, 56px) clamp(28px, 3.4vw, 56px) clamp(32px, 3.6vw, 56px) calc(clamp(28px, 3.4vw, 56px) + var(--gouttiere));
  margin: clamp(-28px, -3vw, -16px) 0 clamp(-28px, -3vw, -16px) calc(-1 * var(--gouttiere));
  box-sizing: border-box;
}

.devis__texte {
  flex: 0 1 360px;
  min-width: 260px;
  padding: clamp(24px, 3vw, 48px) 0 clamp(24px, 3vw, 48px) clamp(32px, 4vw, 56px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
}

.devis__titre { font-size: clamp(32px, 3.4vw, 46px); line-height: 1.06; }

.devis__ligne {
  font: 500 15px/1.8 var(--courant);
  color: var(--texte-sombre-3);
  max-width: 34ch;
}

.devis__tel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
  padding-top: 24px;
  border-top: 1px solid var(--filet-sombre);
}

.devis__tel-libelle { font: 600 10px/1 var(--courant); letter-spacing: .2em; color: var(--or-profond); }
.devis__tel-numero  { font: 600 27px/1.2 var(--courant); color: var(--laiton); white-space: nowrap; }
.devis__tel-numero a { color: inherit; }

/* Le formulaire est posé sur un panneau blanc : les encoches du bouton
   doivent être blanches, sinon elles dessinent quatre points noirs. */
.devis__panneau .bouton { --fond: var(--blanc); }

/* ==========================================================================
   Mobile
   ========================================================================== */

@media (max-width: 680px) {

  /* Héros : la photo passe au-dessus, le texte en dessous sur fond plein.

     Le texte était auparavant posé sur la photo. Sur un écran de téléphone,
     cela revenait à faire lire un titre de trois lignes et un paragraphe de
     quatre par-dessus un visage et un mur de briques : le contraste variait
     d'une ligne à l'autre. Séparer les deux règle la lisibilité et laisse la
     photo se voir entièrement. */
  .hero { flex-direction: column; }

  .hero__photo {
    display: block;
    order: -1;
    flex: none;
    /* Bande resserrée : tout le héros — photo, titre, sous-titre et bouton —
       doit tenir dans un écran, sinon l'appel à l'action passe sous la ligne
       de flottaison. Le cadrage coupe juste au-dessus de l'oreille de
       l'artisan, ce qui rend au texte une soixantaine de pixels. */
    height: 30vh;
    min-height: 200px;
    max-height: 248px;
    background-image: url('../img/hero-atelier-900.webp');
    /* 42 % en vertical.

       La barre incandescente est à 58 % de la hauteur du cliché, le visage
       autour de 30 %. La bande n'en montre que 37 % : il n'existe qu'une
       fenêtre étroite qui tienne les deux. À 50 % la tête sortait par le
       haut, à 38 % la barre filait par le bas. À 42 %, la tranche visible
       court de 26 à 63 % — visage entier, barre et main gantée comprises.

       Le fichier fait exactement la largeur de l'écran : la valeur
       horizontale n'a aucun effet. */
    background-position: 50% 42%;
  }

  /* Le bas de la photo se fond dans le charbon : pas de frontière nette
     entre l'image et le texte. */
  /* Le fondu du bas commence plus tard et monte moins vite : à 84 % il
     couvrait déjà la barre incandescente, qui tombe précisément dans cette
     zone. La jonction avec le charbon reste franche sur les derniers pour
     cent, sans frontière visible. */
  .hero__voile {
    background: linear-gradient(180deg,
      rgba(14, 14, 13, .30) 0%,
      rgba(14, 14, 13, 0) 38%,
      rgba(14, 14, 13, .18) 82%,
      rgba(14, 14, 13, .72) 94%,
      var(--charbon) 100%);
  }

  /* Bloc centré : la composition est courte — un sur-titre, un titre, deux
     lignes et un bouton pleine largeur. Le centrage lui donne de l'assise.
     Il supposait de resserrer le sous-titre, qui faisait quatre lignes. */
  .hero__texte {
    min-height: auto;
    /* Le `flex: 1.1 1 460px` du desktop fixait une largeur ; en colonne, ces
       460 px deviennent une hauteur imposée à un contenu qui en fait 341.
       Les 119 px de trop se répartissaient autour du texte — d'où la longue
       plage noire sous le bouton, et la section suivante repoussée hors de
       l'écran. */
    flex: 0 0 auto;
    padding: 22px 22px 30px;
    gap: 13px;
    background: none;
    align-items: center;
    text-align: center;
  }

  /* Le sur-titre tenait sur deux lignes en coupant « NANS-LES-PINS ». */
  .hero__texte .surtitre {
    font-size: 10px;
    letter-spacing: .16em;
  }

  .hero__titre { max-width: none; }

  .hero__sous {
    font-size: 15.5px;
    line-height: 1.6;
    max-width: 34ch;
  }

  /* Appel à l'action pleine largeur : cible franche sous le pouce. */
  .hero__actions { margin-top: 4px; }
  .hero__actions .bouton {
    width: 100%;
    justify-content: center;
    padding-left: 20px;
    padding-right: 20px;
  }

  /* Bascule de profil */
  .profil__row {
    flex-wrap: nowrap;
    gap: 10px;
    justify-content: center;
    text-align: center;
  }
  .profil__label {
    flex: 1 1 0;
    min-width: 0;
    gap: 0;
  }
  .profil__label-nom {
    font-size: 10.5px;
    letter-spacing: .05em;
    line-height: 1.25;
  }
  .profil__label-sous { display: none; }
  .profil__switch {
    flex: none;
    width: 68px;
    height: 38px;
    --knob-course: 30px;
  }
  .profil__knob { width: 28px; height: 28px; }

  /* Arguments */
  .arg { justify-content: center; }

  /* Bande défilante : le texte repasse au-dessus, sans dégradé. */
  .selection {
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
    padding: 44px 0;
  }
  .selection { padding-right: 0; }
  .selection__texte {
    flex: none;
    align-self: auto;
    margin-right: 0;
    padding: 0 22px;
    background: none;
    gap: 10px;
  }
  /* Même bande défilante au doigt, en cartes plus étroites. */
  .expo {
    --levee: 96px;
  }

  .expo__vue {
    width: 62vw;
    height: 260px;
    margin-right: 12px;
  }
  .expo__titre { font-size: 18px; }

  /* Savoir-faire */
  .sf__intro-desktop { display: none; }
  .sf__intro-mobile { display: inline; }

  .sf__inner { padding: 0; }
  .sf__head {
    padding: 34px 22px 20px;
    min-width: 0;
    flex: 1 1 100%;
  }
  .sf__panneau {
    margin: 0;
    padding: 24px 22px 30px;
    flex: 1 1 100%;
    min-width: 0;
  }
  .sf__entete {
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 14px;
    padding: 20px 0;
  }
  .sf__num {
    font-family: var(--titre);
    font-weight: 400;
    font-size: 34px;
    line-height: 1;
    letter-spacing: 0;
    width: 52px;

    /* Le reflet n'est posé qu'ici : en desktop le numéro fait 12 px, un
       dégradé animé y serait illisible. La règle commune est dans base.css. */
    background-image: linear-gradient(100deg,
      var(--or-fonce) 0%, var(--or-fonce) 38%,
      var(--or-profond) 50%,
      var(--or-fonce) 62%, var(--or-fonce) 100%);
    background-size: 260% 100%;
    background-position: 100% 0;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    animation: reflet-numero 3.4s linear infinite;
  }

  /* Un décalage par ligne évite que les huit chiffres brillent ensemble. */
  .sf__ligne:nth-child(2n) .sf__num { animation-delay: .5s; }
  .sf__ligne:nth-child(3n) .sf__num { animation-delay: 1s; }
  .sf__ligne:nth-child(4n) .sf__num { animation-delay: 1.6s; }
  /* L'intitulé prend la place restante de la ligne, sans la remplir : le
     signe d'ouverture doit tenir à côté, pas en dessous. */
  .sf__nom {
    flex: 1 1 0;
    min-width: 0;
    font-size: 20px;
  }
  .sf__desc {
    flex: 1 1 100%;
    min-width: 0;
    padding-left: 66px;
    font-size: 13px;
    line-height: 1.6;
    margin-top: 4px;
  }

  /* Accordéon : la section faisait près de 2 800 px à faire défiler, chaque
     domaine dépliant son texte et une photo de 250 px. Fermée, la liste tient
     désormais en un écran ; une seule ligne s'ouvre à la fois. */
  .sf__signe {
    display: block;
    margin-left: auto;
    font: 500 22px/1 var(--courant);
    color: var(--or-fonce);
    width: 22px;
    text-align: center;
  }

  .sf__entete {
    align-items: center;
    min-height: 56px;
  }

  /* Fermée, la ligne ne montre que son numéro et son intitulé. */
  .sf__ligne:not(.est-ouvert) .sf__desc { display: none; }

  .sf__ligne.est-ouvert .sf__revele {
    display: block;
    animation: glisse-mobile .5s cubic-bezier(.22, .8, .3, 1) both;
  }

  @keyframes glisse-mobile {
    from { max-height: 0; opacity: 0; transform: translateX(28px); }
    to   { max-height: 340px; opacity: 1; transform: none; }
  }

  /* Repères en carré 2 × 2 */
  .reperes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 28px 18px;
    margin: 0;
  }
  .repere,
  .repere + .repere {
    border-left: none;
    padding: 0;
    flex: none;
  }
  .repere__valeur { font-size: 31px; line-height: 1.1; }

  /* Matières : bande compacte sur une ligne */
  .matieres {
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0 9px;
    background: var(--charbon-clair);
    padding: 14px 12px;
    border-top: none;
    margin: 6px -28px 0;
  }
  .matieres__titre,
  .matiere {
    font-size: 9.5px;
    letter-spacing: .08em;
  }

  /* Devis en pleine largeur, sans décalage */
  .devis__inner { padding: 0; }
  .devis__panneau {
    flex: 1 1 100%;
    min-width: 0;
    margin: 0;
    padding: 26px 22px 34px;
  }
  .devis__texte {
    flex: 1 1 100%;
    min-width: 0;
    padding: 30px 22px 32px;
    align-items: center;
    text-align: center;
  }
  .devis__tel { align-items: center; }
}

/* --------------------------------------------------------------------------
   Réalisations sur ordinateur — l'accordéon d'ouverture au survol

   La bande qui défile a été demandée pour le mobile ; sur ordinateur, la
   section garde sa disposition d'origine : des vues étroites alignées, dont
   celle qu'on survole s'ouvre en grand pendant que les autres se resserrent.
   La première est ouverte au repos ; dès qu'on survole la rangée, elle cède
   la place à celle qu'on désigne — le tout sans une ligne de script.
   -------------------------------------------------------------------------- */

@media (min-width: 681px) {
  .expo {
    padding-top: 0;
    margin-top: 0;
    overflow: hidden;
  }

  .expo__piste {
    /* Les dix vues doivent tenir dans la largeur disponible, quelle qu'elle
       soit : la vue ouverte prend sa taille, les neuf autres se partagent
       exactement ce qui reste. Sans ce calcul, des largeurs fixes débordaient
       et la rangée se retrouvait tronquée à droite. */
    --ouvert: min(24rem, 40%);
    --ferme: calc((100% - var(--ouvert) - 9 * 4px) / 9);

    width: 100%;
    gap: 4px;
    align-items: stretch;
  }

  /* La bande est doublée pour boucler ; l'accordéon n'a besoin que du premier
     jeu, le second portant déjà aria-hidden. */
  .expo__vue[aria-hidden="true"] { display: none; }

  .expo__vue {
    width: var(--ferme);
    height: 24rem;
    margin-right: 0;
    min-width: 0;
    /* Le script de la bande ne tourne pas ici : aucune position en ligne à
       neutraliser, l'ouverture se joue sur la seule largeur. */
    transition: width .3s ease-in-out;
  }

  /* Ouverte au repos, puis rendue à la vue survolée. */
  .expo__vue:first-child,
  .expo__vue:hover,
  .expo__vue:focus-visible { width: var(--ouvert); }

  .expo__piste:hover .expo__vue:first-child:not(:hover) { width: var(--ferme); }

  /* Voile et légende n'apparaissent que sur la vue ouverte : sur une colonne
     de 5 rem, le titre serait illisible. */
  .expo__voile,
  .expo__legende {
    opacity: 0;
    transition: opacity .3s ease-in-out;
  }

  .expo__vue:first-child .expo__voile,
  .expo__vue:first-child .expo__legende,
  .expo__vue:hover .expo__voile,
  .expo__vue:hover .expo__legende,
  .expo__vue:focus-visible .expo__voile,
  .expo__vue:focus-visible .expo__legende { opacity: 1; }

  .expo__piste:hover .expo__vue:first-child:not(:hover) .expo__voile,
  .expo__piste:hover .expo__vue:first-child:not(:hover) .expo__legende { opacity: 0; }

  /* Le grossissement de la photo au survol ferait double emploi avec
     l'ouverture. */
  .expo__vue:hover .expo__photo { transform: none; }
}

/* --------------------------------------------------------------------------
   Cibles tactiles — mobile

   Le doigt n'a pas la précision du pointeur : les commandes doivent offrir
   44 px de haut, seuil du critère 2.5.8 des règles d'accessibilité. Les liens
   posés au fil d'un paragraphe en sont dispensés, et gardent donc leur taille.
   -------------------------------------------------------------------------- */

@media (max-width: 680px) {
  .profil__label {
    min-height: 44px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .profil__switch {
    min-height: 44px;
    /* La pastille garde son gabarit : c'est la zone sensible qu'on agrandit,
       autour d'elle, sans toucher au dessin. */
    display: flex;
    align-items: center;
  }
}

/* --------------------------------------------------------------------------
   Le lien du formulaire, posé sur la photo du domaine

   Il couvre toute la carte : c'est la photo elle-même qu'on touche, comme
   sur les tuiles de la galerie. Sans texte visible — l'intitulé du domaine
   le précède déjà — mais avec un aria-label, faute de quoi le lien serait
   muet au lecteur d'écran.
   -------------------------------------------------------------------------- */

.sf__carte { position: relative; }

.sf__lien {
  position: absolute;
  inset: 0;
  z-index: 2;
}

.sf__lien:focus-visible {
  outline: 2px solid var(--laiton);
  outline-offset: -4px;
}

/* --------------------------------------------------------------------------
   Domaines sans photo

   Deux des huit domaines — la restauration d'ouvrages, la conception des
   plans — n'ont pas de cliché qui les illustre honnêtement. Plutôt qu'une
   image approchante, leur ligne ne montre rien et mène directement au
   formulaire. La flèche remplace le plus : elle annonce un départ, pas un
   dépliage.
   -------------------------------------------------------------------------- */

.sf__entete--lien {
  text-decoration: none;
  color: inherit;
}

.sf__signe--fleche {
  font-size: 18px;
  transition: transform .3s cubic-bezier(.16, 1, .3, 1);
}

.sf__entete--lien:hover .sf__signe--fleche { transform: translateX(4px); }

/* Un plan ne se recadre pas.

   Les photos remplissent leur cadre en débordant — c'est ce qu'on attend
   d'une image d'ouvrage. Un dessin coté, lui, perd tout sens dès qu'on en
   coupe un bord : il s'inscrit donc en entier, sur le fond du dessin. */
.sf__photo--plan,
.apercu__photo[src$=".svg"] {
  object-fit: contain;
  background: #12110f;
}
