/* ==========================================================================
   AVZ — Feuille de style principale
   --------------------------------------------------------------------------
   Thème clair. Fond béton clair, encre très sombre, orange AVZ en accent.
   Trois respirations photographiques traversent la page (héros, terrain,
   appel final) et le pied de page ferme sur un bloc sombre : ce sont des
   images et un terminus voulus, pas une alternance de thèmes.
   Angles vifs partout : aucun arrondi, cohérent avec l'univers du chantier.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. JETONS DE DESIGN
   -------------------------------------------------------------------------- */

:root {
  /* Fonds, du plus clair au plus dense */
  --fond:        #F4F3F1;
  --fond-2:      #EBE9E6;
  --fond-3:      #E1DFDB;

  /* Encre et texte. Contrastes mesurés sur le fond #F4F3F1 :
     encre 16.5:1, texte 6.9:1, texte sourd 5.4:1. Tous au-delà du
     niveau AA, y compris sur la bande #EBE9E6. */
  --encre:       #151515;
  --texte:       #55534F;
  --texte-sourd: #656360;

  /* Sur les blocs sombres : photographies et pied de page */
  --sur-sombre:      #F4F3F1;
  --sur-sombre-doux: #C9C7C2;

  /* Accent du brand kit, retenu par AVZ pour tous les éléments jaunes du
     site : boutons, surtitres, numéros, filets, frise, liens au survol.
     Sur fond clair, ce jaune contraste peu avec le fond (1.65:1) : il reste
     net sur les grands titres et les filets, plus délicat sur les petits
     textes. Le repère de focus clavier est noir pour rester visible. */
  --accent:       #FFB22A;

  /* Filets */
  --ligne:       rgba(21, 21, 21, 0.14);
  --ligne-forte: rgba(21, 21, 21, 0.30);

  /* Rythme vertical. La densité visuelle est volontairement basse :
     les sections respirent, à la manière d'une revue d'architecture. */
  --section-y:   clamp(5.5rem, 11vw, 10.5rem);
  --gouttiere:   clamp(1.25rem, 2.2vw, 2.25rem);
  --marge-page:  clamp(1.25rem, 5vw, 5rem);
  --largeur-max: 1480px;

  /* Hauteur d'en-tête, réutilisée pour les ancres et le décalage de scroll */
  --header-h: 72px;

  /* Courbe d'accélération commune à toutes les transitions du site */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);

  /* Échelle de plans. Documentée pour éviter les z-index arbitraires. */
  --z-contenu: 1;
  --z-sticky:  20;
  --z-header:  40;
  --z-progression: 45;
  --z-menu:    50;
  --z-modale:  60;
  --z-chargement: 100;

  color-scheme: light;
}

@media (min-width: 900px) {
  :root { --header-h: 78px; }
}

/* --------------------------------------------------------------------------
   2. RÉINITIALISATION ET BASES
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

/* L'attribut hidden doit toujours l'emporter. Sans cette règle, tout
   composant qui déclare son propre display (grille, flex) resterait
   visible alors que le script l'a masqué. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Décale les ancres pour que les titres ne passent pas sous l'en-tête fixe. */
  scroll-padding-top: var(--header-h);
}

body {
  margin: 0;
  background: var(--fond);
  color: var(--encre);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Verrou anti-débordement horizontal, sur toutes les tailles d'écran. */
  overflow-x: hidden;
}

img, svg, video, iframe { display: block; max-width: 100%; }
img { height: auto; }

h1, h2, h3, h4 {
  font-family: "Montserrat", system-ui, sans-serif;
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

a { color: inherit; text-decoration: none; }

button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }

ul, ol { margin: 0; padding: 0; list-style: none; }

::selection { background: var(--accent); color: var(--encre); }

/* Anneau de focus visible et constant sur tout le site. */
:focus-visible {
  outline: 2px solid var(--encre);
  outline-offset: 3px;
}

/* Sur les blocs sombres, l'anneau passe en orange vif pour rester visible. */
.hero :focus-visible,
.terrain :focus-visible,
.final :focus-visible,
.footer :focus-visible,
.menu-mobile :focus-visible { outline-color: var(--accent); }

/* Lien d'évitement pour la navigation au clavier. */
.saut-contenu {
  position: absolute;
  left: var(--marge-page);
  top: 0;
  z-index: var(--z-modale);
  transform: translateY(-120%);
  padding: 0.85rem 1.4rem;
  background: var(--encre);
  color: var(--fond);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: transform 0.25s var(--ease);
}
.saut-contenu:focus { transform: translateY(0); }

/* --------------------------------------------------------------------------
   3. UTILITAIRES DE MISE EN PAGE
   -------------------------------------------------------------------------- */

.zone {
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--marge-page);
}

.section { padding-block: var(--section-y); position: relative; }
.section--serre { padding-block: clamp(3.5rem, 7vw, 6rem); }

.visuellement-cache {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   4. TYPOGRAPHIE DE SECTION
   -------------------------------------------------------------------------- */

/* Surtitre. Volontairement rare : quatre occurrences sur l'ensemble de la page,
   pour éviter le rythme répétitif d'un gabarit. */
.surtitre {
  display: block;
  font-size: clamp(0.82rem, 1.15vw, 1.05rem);
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: clamp(1.25rem, 1.8vw, 1.75rem);
}

.titre-xl {
  font-size: clamp(2.35rem, 7.4vw, 6.4rem);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.035em;
}

.titre-l {
  font-size: clamp(1.95rem, 4.6vw, 3.9rem);
  text-transform: uppercase;
  letter-spacing: -0.03em;
}

.titre-m {
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  letter-spacing: -0.02em;
}

.texte {
  color: var(--texte);
  font-size: clamp(1rem, 1.05vw, 1.1rem);
  font-weight: 400;
  line-height: 1.75;
  max-width: 62ch;
}

/* --------------------------------------------------------------------------
   5. BOUTONS
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  /* Jamais de retour à la ligne dans un libellé de bouton. */
  white-space: nowrap;
  padding: 1rem 1.6rem;
  background: var(--accent);
  color: var(--encre);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border: 1px solid var(--accent);
  transition: background 0.3s var(--ease), color 0.3s var(--ease),
              border-color 0.3s var(--ease), transform 0.12s var(--ease);
}

.btn .fleche { transition: transform 0.35s var(--ease); display: inline-block; }
.btn:hover .fleche { transform: translateX(5px); }

.btn:hover { background: var(--encre); border-color: var(--encre); color: var(--fond); }
.btn:active { transform: translateY(1px); }

/* Variante secondaire sur fond clair : contour d'encre, sans aplat. */
.btn--ligne {
  background: transparent;
  color: var(--encre);
  border-color: var(--ligne-forte);
}
.btn--ligne:hover { background: var(--encre); border-color: var(--encre); color: var(--fond); }

/* Variante posée sur une photographie : contour clair et léger flou. */
.btn--sur-photo {
  background: transparent;
  color: var(--sur-sombre);
  border-color: rgba(244, 243, 241, 0.45);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.btn--sur-photo:hover {
  background: var(--sur-sombre);
  border-color: var(--sur-sombre);
  color: var(--encre);
}

.btn--compact { padding: 0.72rem 1.15rem; font-size: 0.72rem; }
.btn--large { padding: 1.15rem 2rem; }

/* Libellé long par défaut, abrégé sur les petits écrans. Le nom accessible
   du lien est porté par son aria-label et ne change jamais. */
.cta-court { display: none; }
@media (max-width: 599px) {
  .cta-long { display: none; }
  .cta-court { display: inline; }
}

/* Lien texte avec filet qui se déploie au survol. */
.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--encre);
  padding-bottom: 0.45rem;
  position: relative;
}
.lien-fleche::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--ligne-forte);
}
.lien-fleche::before {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 2px;
  background: var(--accent);
  transition: width 0.45s var(--ease);
  z-index: 1;
}
.lien-fleche:hover::before { width: 100%; }
.lien-fleche:hover { color: var(--accent); }
.lien-fleche .fleche { transition: transform 0.35s var(--ease); }
.lien-fleche:hover .fleche { transform: translateX(5px); }

/* --------------------------------------------------------------------------
   6. EMPLACEMENTS PHOTOGRAPHIQUES
   --------------------------------------------------------------------------
   Chaque visuel du site est un emplacement cadré et nommé. Tant que le
   fichier n'est pas déposé dans assets/img/, le bloc affiche une texture
   béton et le nom du fichier attendu : la mise en page reste intacte et
   personne ne voit d'image cassée. Dès que le fichier est déposé sous le
   bon nom, la photographie apparaît, sans aucune modification du code.
   -------------------------------------------------------------------------- */

.photo {
  position: relative;
  overflow: hidden;
  background-color: var(--fond-3);
  /* Texture béton : grain diagonal fin plus voile de lumière. */
  background-image:
    repeating-linear-gradient(
      135deg,
      rgba(21, 21, 21, 0.035) 0 2px,
      transparent 2px 5px
    ),
    radial-gradient(120% 90% at 30% 10%, rgba(21, 21, 21, 0.05), transparent 60%);
  isolation: isolate;
}

/* Sur les grands blocs photographiques, la texture d'attente est sombre :
   le texte blanc posé par-dessus reste lisible avant même la photo. */
.hero .photo, .terrain .photo, .final .photo {
  background-color: #1C1C1C;
  background-image:
    repeating-linear-gradient(135deg, rgba(244,243,241,0.025) 0 2px, transparent 2px 5px),
    radial-gradient(120% 90% at 30% 10%, rgba(244,243,241,0.05), transparent 60%);
}
/* Sur ces blocs, le texte de la section occupe le centre et le bas :
   l'étiquette d'attente se cale donc en haut pour ne rien recouvrir. */
.hero .photo__slot, .terrain .photo__slot, .final .photo__slot {
  color: #6E6C68;
  justify-content: flex-start;
  padding-top: clamp(4.5rem, 13vh, 8rem);
}
.hero .photo__slot b, .terrain .photo__slot b, .final .photo__slot b { color: #8E8C88; }

.photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.7s var(--ease), transform 1.2s var(--ease);
}
.photo.est-chargee img { opacity: 1; }

/* Étiquette de l'emplacement, masquée dès que la photo est chargée. */
.photo__slot {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1.5rem;
  text-align: center;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-sourd);
  transition: opacity 0.4s var(--ease);
  pointer-events: none;
}
.photo__slot b {
  font-weight: 600;
  color: var(--texte);
  letter-spacing: 0.06em;
  text-transform: none;
  font-size: 0.78rem;
}
.photo.est-chargee .photo__slot { opacity: 0; }

/* --------------------------------------------------------------------------
   7. RÉVÉLATIONS AU DÉFILEMENT
   --------------------------------------------------------------------------
   Pilotées par IntersectionObserver, jamais par un écouteur de scroll.
   L'état par défaut est « visible » : sans JavaScript, tout le contenu
   reste lisible.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .js .reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity 0.75s var(--ease), transform 0.75s var(--ease);
    transition-delay: var(--delai, 0ms);
  }
  .js .reveal.est-visible { opacity: 1; transform: none; }
}

/* Grands titres qui montent depuis une ligne.
   Le script enveloppe chaque mot dans .mot (fenêtre qui masque) et
   .mot__int (le mot qui glisse). La fenêtre déborde de 0,15 em en haut et
   en bas, compensés par une marge négative : les accents des capitales
   (É, À) ne sont pas rognés et la hauteur de ligne ne change pas. */
.titre-anime .mot,
.titre-anime .mot__int {
  display: inline-block;
  color: inherit;
}
.titre-anime .mot {
  overflow: hidden;
  vertical-align: top;
  padding-block: 0.15em;
  margin-block: -0.15em;
}
@media (prefers-reduced-motion: no-preference) {
  .js .titre-anime .mot__int {
    transform: translateY(115%);
    transition: transform 0.9s var(--ease);
    transition-delay: calc(var(--delai, 0ms) + var(--i, 0) * 55ms);
  }
  .js .titre-anime.est-visible .mot__int { transform: none; }
}

/* Écran de chargement.
   Visible seulement quand le script de <head> a posé la classe
   chargement-en-cours sur <html>. Le logo sert de jauge : sa forme découpe
   un fond clair très discret, et une bande blanche bordée d'un filet jaune
   la remplit de gauche à droite. Le logo fourni est un noir plus ou
   moins transparent : la découpe reprend donc son reflet métallique, comme
   le logo blanc de l'en-tête posé sur la photo du héros. À la sortie, l'écran remonte comme un
   rideau, avec un filet jaune sur son bord inférieur. */
.chargement { display: none; }

.chargement-en-cours .chargement,
.chargement-sortie .chargement {
  position: fixed;
  inset: 0;
  z-index: var(--z-chargement);
  display: grid;
  place-items: center;
  background: var(--encre);
}

.chargement__logo {
  position: relative;
  width: clamp(190px, 26vw, 300px);
  aspect-ratio: 359 / 120;
  overflow: hidden;
  background: rgba(244, 243, 241, 0.12);
  -webkit-mask: url("../img/logo-avz.png") center / contain no-repeat;
  mask: url("../img/logo-avz.png") center / contain no-repeat;
}

.chargement__jauge {
  position: absolute;
  inset: 0;
  background: var(--sur-sombre);
  transform: translateX(-100%);
}
/* Filet jaune au bord de la jauge, juste devant la partie remplie. */
.chargement__jauge::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 100%;
  width: 5px;
  background: var(--accent);
}
.chargement__jauge.est-pleine {
  transform: none !important;
  transition: transform 0.3s var(--ease);
}

.chargement-sortie .chargement {
  transform: translateY(-100%);
  box-shadow: inset 0 -3px 0 var(--accent);
  transition: transform 0.95s var(--ease);
}
.chargement-sortie .chargement__logo {
  opacity: 0;
  transform: translateY(-1.5rem);
  transition: opacity 0.4s var(--ease), transform 0.6s var(--ease);
}

/* Pendant le chargement, l'entrée du héros attend derrière l'écran : elle
   démarre au moment où le rideau se lève. */
.js.chargement-en-cours .hero__entree > * { animation-play-state: paused; }
.js.chargement-en-cours .hero__titre.titre-anime .mot__int { transform: translateY(115%); }

/* Barre de progression de lecture, en haut de la fenêtre.
   Navigateurs récents : pilotée directement par le défilement, en CSS.
   Les autres reçoivent un relais en JavaScript (main.js, section 3 bis). */
.progression-lecture {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-progression);
  height: 3px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
@supports (animation-timeline: scroll()) {
  .progression-lecture {
    animation: progressionLecture linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes progressionLecture { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* --------------------------------------------------------------------------
   8. EN-TÊTE
   -------------------------------------------------------------------------- */

.header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  border-bottom: 1px solid transparent;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease),
              backdrop-filter 0.4s var(--ease);
}

/* Effet verre dépoli, activé uniquement une fois le héros dépassé. */
.header.est-collee {
  background: rgba(244, 243, 241, 0.72);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: var(--ligne);
}

/* Repli opaque si le navigateur ou l'utilisateur refuse la transparence. */
@media (prefers-reduced-transparency: reduce) {
  .header.est-collee {
    background: var(--fond);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

.header__zone {
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--marge-page);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 3rem);
}

.logo { display: block; flex-shrink: 0; }
.logo img {
  height: 26px;
  width: auto;
  /* Le logo fourni est en dégradé métal. Sur fond clair ce filtre le ramène
     en encre pleine ; le pied de page sombre le repasse en blanc. */
  filter: brightness(0);
  transition: filter 0.3s var(--ease);
}

/* Tant que le héros n'est pas dépassé, le logo repose sur la photographie :
   il doit donc être blanc. */
.header:not(.est-collee) .logo img { filter: brightness(0) invert(1); }

@media (min-width: 900px) { .logo img { height: 29px; } }

.nav { margin-left: auto; }

.nav__liste { display: flex; align-items: center; gap: clamp(1rem, 2.1vw, 2.1rem); }

.nav__lien {
  position: relative;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: var(--encre);
  padding-block: 0.35rem;
  white-space: nowrap;
  transition: color 0.3s var(--ease);
}
.header:not(.est-collee) .nav__lien { color: var(--sur-sombre); }

.nav__lien::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 2px;
  background: var(--accent);
  transition: width 0.35s var(--ease);
}
.header:not(.est-collee) .nav__lien::after { background: var(--accent); }

.nav__lien:hover { color: var(--accent); }
.header:not(.est-collee) .nav__lien:hover { color: var(--accent); }
.nav__lien:hover::after,
.nav__lien[aria-current="true"]::after { width: 100%; }
.nav__lien[aria-current="true"] { color: var(--accent); }
.header:not(.est-collee) .nav__lien[aria-current="true"] { color: var(--accent); }

.header__cta { flex-shrink: 0; }

/* Bouton hamburger, trois barres qui se croisent à l'ouverture. */
.burger {
  display: none;
  width: 44px; height: 44px;
  margin-right: -10px;
  position: relative;
  flex-shrink: 0;
}
.burger span {
  position: absolute;
  left: 11px;
  width: 22px; height: 2px;
  background: var(--encre);
  transition: transform 0.4s var(--ease), opacity 0.2s var(--ease),
              background 0.4s var(--ease);
}
.header:not(.est-collee) .burger span { background: var(--sur-sombre); }

.burger span:nth-child(1) { top: 16px; }
.burger span:nth-child(2) { top: 21px; }
.burger span:nth-child(3) { top: 26px; }

.burger[aria-expanded="true"] span { background: var(--sur-sombre); }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* Panneau de navigation mobile, plein écran. Bloc sombre volontaire :
   il recouvre entièrement la page le temps de la navigation. */
.menu-mobile {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--encre);
  color: var(--sur-sombre);
  padding: calc(var(--header-h) + 2.5rem) var(--marge-page) 2.5rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform 0.55s var(--ease), visibility 0.55s;
  overflow-y: auto;
}
.menu-mobile.est-ouvert { transform: translateY(0); visibility: visible; }

.menu-mobile__liste { display: flex; flex-direction: column; }
.menu-mobile__liste li { border-bottom: 1px solid rgba(244, 243, 241, 0.16); }
.menu-mobile__lien {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding-block: 1.15rem;
  font-family: "Montserrat", sans-serif;
  font-size: 1.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  transition: color 0.3s var(--ease), padding-left 0.35s var(--ease);
}
.menu-mobile__lien:hover { color: var(--accent); padding-left: 0.6rem; }

.menu-mobile__pied { margin-top: auto; display: grid; gap: 1rem; }

@media (max-width: 1023px) {
  .nav { display: none; }
  .burger { display: block; margin-left: auto; }
  .header__cta { order: 2; }
  .header__cta .btn { padding: 0.66rem 1rem; font-size: 0.68rem; }
}

@media (min-width: 1024px) {
  .menu-mobile { display: none; }
}

/* --------------------------------------------------------------------------
   9. HÉROS
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  /* dvh et non vh : évite le saut de mise en page lié à la barre d'adresse iOS. */
  min-height: 100dvh;
  display: flex;
  align-items: flex-end;
  padding-top: calc(var(--header-h) + 1.5rem);
  padding-bottom: clamp(3rem, 8vh, 6rem);
  overflow: hidden;
  background: var(--encre);
  color: var(--sur-sombre);
}

.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media .photo { width: 100%; height: 100%; }

/* Voile double : dégradé vertical pour le texte, vignettage latéral pour
   le cadrage cinématographique. */
.hero__voile {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(12,12,12,0.74) 0%, rgba(12,12,12,0.30) 34%, rgba(12,12,12,0.90) 100%),
    linear-gradient(90deg, rgba(12,12,12,0.70) 0%, transparent 52%);
}

.hero__zone { position: relative; z-index: 2; width: 100%; }
.hero__contenu { max-width: 76rem; }

.hero .surtitre { color: var(--accent); }

/* Échelle calée sur la ligne la plus longue, « Nous construisons. »,
   afin qu'elle tienne sur une seule ligne à toutes les largeurs. */
.hero__titre {
  font-size: clamp(1.8rem, 6.4vw, 5.8rem);
  font-weight: 900;
  line-height: 0.88;
  letter-spacing: -0.04em;
  text-transform: uppercase;
  margin-bottom: 1.75rem;
}
.hero__titre > span { display: block; }
.hero__titre > span:last-child { color: var(--accent); }

.hero__texte {
  font-size: clamp(1rem, 1.35vw, 1.22rem);
  font-weight: 400;
  line-height: 1.6;
  color: rgba(244, 243, 241, 0.90);
  max-width: 44ch;
  margin-bottom: 2.5rem;
}

.hero__actions { display: flex; flex-wrap: wrap; gap: 0.9rem; }

/* Entrée séquencée du héros au chargement. */
@media (prefers-reduced-motion: no-preference) {
  .js .hero__entree > * {
    opacity: 0;
    transform: translateY(30px);
    animation: heroEntree 1s var(--ease) forwards;
    animation-delay: var(--delai, 0ms);
  }
  @keyframes heroEntree { to { opacity: 1; transform: none; } }
  .js .hero__entree > .titre-anime { opacity: 1; transform: none; animation: none; }
}

/* --------------------------------------------------------------------------
   10. BANDEAU DE CONFIANCE (défilement horizontal)
   --------------------------------------------------------------------------
   Unique défilement horizontal du site. Il porte les huit métiers, qui sont
   la promesse centrale d'AVZ : la répétition y est le message.
   -------------------------------------------------------------------------- */

.bandeau {
  border-block: 1px solid var(--ligne);
  background: var(--fond-2);
  padding-block: clamp(2.25rem, 4vw, 3.25rem);
  overflow: hidden;
}

.bandeau__intro {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--texte-sourd);
  margin-bottom: 1.75rem;
}

.bandeau__piste { display: flex; width: max-content; gap: 0; }

@media (prefers-reduced-motion: no-preference) {
  .bandeau__piste { animation: defile 46s linear infinite; }
  .bandeau:hover .bandeau__piste { animation-play-state: paused; }
  @keyframes defile { to { transform: translateX(-50%); } }
}

.bandeau__groupe { display: flex; align-items: center; }

.bandeau__item {
  display: inline-flex;
  align-items: center;
  gap: clamp(1.6rem, 3vw, 3rem);
  padding-inline: clamp(0.8rem, 1.6vw, 1.5rem);
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.1rem, 2.4vw, 2rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.015em;
  color: var(--encre);
  white-space: nowrap;
}

/* Séparateur géométrique repris de l'angle du logo AVZ. */
.bandeau__item::after {
  content: "";
  width: clamp(10px, 1.2vw, 16px);
  height: clamp(10px, 1.2vw, 16px);
  background: var(--accent);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   11. SECTION ÉDITORIALE EN DEUX COLONNES (à propos)
   -------------------------------------------------------------------------- */

.duo { display: grid; gap: clamp(2.5rem, 5vw, 5rem); align-items: center; }

@media (min-width: 900px) {
  .duo { grid-template-columns: 1fr 1.05fr; }
  /* Léger débord vers la marge : casse la symétrie parfaite. */
  .duo__media { margin-left: calc(var(--marge-page) * -0.5); }
}

.duo__media .photo { aspect-ratio: 4 / 5; }
.duo__texte > * + * { margin-top: 1.6rem; }
.duo__texte .lien-fleche { margin-top: 2.25rem; }

/* --------------------------------------------------------------------------
   12. NOS MÉTIERS
   --------------------------------------------------------------------------
   Cartes purement typographiques : numéro, titre, filet orange et
   description, sans image. Sobriété voulue par AVZ.
   -------------------------------------------------------------------------- */

/* La largeur de lecture se pose sur le titre lui-même, et non sur le
   conteneur : l'unité ch suit alors la taille du titre. Placée sur le
   conteneur, elle se calculerait sur le corps de texte et écraserait le
   titre sur cinq ou six lignes. */
.entete-section { margin-bottom: clamp(3rem, 5vw, 4.5rem); }
.entete-section > .titre-l { max-width: 18ch; }

.metiers { display: grid; gap: var(--gouttiere); }

@media (min-width: 640px) { .metiers { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .metiers { grid-template-columns: repeat(4, 1fr); } }

.metier {
  display: flex;
  flex-direction: column;
  background: var(--fond-2);
  border-top: 2px solid var(--encre);
  padding: clamp(1.5rem, 2.2vw, 2.1rem);
}

/* Le numéro ouvre la carte ; son espacement fixe aligne les titres d'une
   même rangée sur la même ligne. */
.metier__num {
  display: block;
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.6rem, 2.2vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--accent);
  line-height: 1;
  margin-bottom: clamp(2rem, 3.2vw, 3rem);
}

.metier__titre {
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.02rem, 1.35vw, 1.22rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  line-height: 1.1;
  margin-bottom: 0.85rem;
}

/* Filet d'accent qui se déploie sous le titre. */
.metier__filet {
  display: block;
  width: 30px; height: 2px;
  background: var(--accent);
  margin-bottom: 0.85rem;
  transition: width 0.5s var(--ease);
}
.metier:hover .metier__filet { width: 62px; }

.metier__desc {
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.65;
  color: var(--texte);
  margin: 0;
}

/* --------------------------------------------------------------------------
   13. DU CHANTIER À LA FINITION (frise horizontale)
   --------------------------------------------------------------------------
   Quatre phases sur une ligne de chantier. Chaque phase porte son propre
   segment de ligne, de son repère jusqu'au repère suivant : ::before pour
   le rail gris, ::after pour le remplissage orange. Ainsi la ligne s'arrête
   net au dernier repère, et chaque phase s'active exactement quand son
   segment arrive, quelle que soit la hauteur des textes.

   Sans JavaScript, ou avec les animations réduites, la frise s'affiche
   directement dans son état final.
   -------------------------------------------------------------------------- */

.phases { position: relative; background: var(--fond-2); }

.phases__frise {
  margin-top: clamp(3rem, 5vw, 4.5rem);
  --pas: 0.55s;            /* durée d'un segment, et délai entre deux phases */
}

.phases__liste { display: grid; gap: 2.25rem; }

.phase { position: relative; }
.phase:nth-child(1) { --etape: 0; }
.phase:nth-child(2) { --etape: 1; }
.phase:nth-child(3) { --etape: 2; }
.phase:nth-child(4) { --etape: 3; }

.phase::before,
.phase::after { content: ""; position: absolute; }
.phase::before { background: var(--ligne-forte); }
.phase::after  { background: var(--accent); }

/* Repère triangulaire, repris de l'angle du logo AVZ, posé sur la ligne. */
.phase__repere {
  position: absolute;
  z-index: 1;
  width: 12px; height: 12px;
  background: var(--accent);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  transform: scale(1.3);
}

.phase__num {
  display: block;
  font-family: "Montserrat", sans-serif;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  line-height: 1;
  color: var(--accent);
  margin-bottom: 0.85rem;
}

.phase__titre {
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.35rem, 2.2vw, 2.1rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--encre);
  margin-bottom: 0.7rem;
}

.phase__metiers {
  font-size: 0.94rem;
  line-height: 1.5;
  color: var(--texte);
}

/* Mobile et tablette : frise verticale. Le segment descend du centre du
   repère jusqu'au centre du repère suivant (hauteur de la phase + espacement). */
@media (max-width: 899px) {
  .phases__liste { padding-left: 2.25rem; }
  .phase__repere { left: -2.25rem; top: 0; }
  .phase::before,
  .phase::after {
    left: calc(-2.25rem + 5px);
    top: 6px;
    width: 2px;
    height: calc(100% + 2.25rem);
    transform-origin: top;
  }
  .phase:last-child::before,
  .phase:last-child::after { content: none; }
}

/* Bureau : frise horizontale au-dessus des quatre colonnes. Le dernier
   segment prolonge la ligne jusqu'au bout de la dernière colonne. */
@media (min-width: 900px) {
  .phases__liste {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--gouttiere);
    padding-top: 2.75rem;
  }
  .phase__repere { left: 0; top: -2.75rem; }
  .phase::before,
  .phase::after {
    left: 6px;
    top: calc(-2.75rem + 5px);
    height: 2px;
    width: calc(100% + var(--gouttiere));
    transform-origin: left;
  }
  .phase:last-child::before,
  .phase:last-child::after { width: calc(100% - 6px); }
}

/* Lancement : la phase n s'active à n × pas, puis son segment se remplit
   pendant un pas, ce qui l'amène au repère suivant à l'instant où celui-ci
   s'active. */
@media (prefers-reduced-motion: no-preference) {
  .js .phase::after {
    transition: transform var(--pas) linear;
    transition-delay: calc(var(--etape) * var(--pas));
  }
  .js .phase__repere,
  .js .phase__num,
  .js .phase__titre,
  .js .phase__metiers {
    transition: background 0.3s var(--ease), transform 0.3s var(--ease), color 0.3s var(--ease);
    transition-delay: calc(var(--etape) * var(--pas));
  }

  .js .phases__frise:not(.est-lancee) .phase__repere { background: var(--ligne-forte); transform: none; }
  .js .phases__frise:not(.est-lancee) .phase__num,
  .js .phases__frise:not(.est-lancee) .phase__titre,
  .js .phases__frise:not(.est-lancee) .phase__metiers { color: var(--texte-sourd); }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 899px) {
  .js .phases__frise:not(.est-lancee) .phase::after { transform: scaleY(0); }
}
@media (prefers-reduced-motion: no-preference) and (min-width: 900px) {
  .js .phases__frise:not(.est-lancee) .phase::after { transform: scaleX(0); }
}

/* --------------------------------------------------------------------------
   14. RÉALISATIONS
   -------------------------------------------------------------------------- */

.filtres {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.filtre {
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--ligne-forte);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.filtre:hover { color: var(--encre); border-color: var(--encre); }
.filtre[aria-pressed="true"] {
  background: var(--encre);
  border-color: var(--encre);
  color: var(--fond);
}

/* Grille asymétrique de type revue d'architecture. */
.projets { display: grid; gap: clamp(2rem, 3vw, 3rem) var(--gouttiere); }

@media (min-width: 700px) {
  .projets { grid-template-columns: repeat(6, 1fr); }
  .projet:nth-child(6n+1) { grid-column: span 4; }
  .projet:nth-child(6n+2) { grid-column: span 2; }
  .projet:nth-child(6n+3) { grid-column: span 2; }
  .projet:nth-child(6n+4) { grid-column: span 4; }
  .projet:nth-child(6n+5) { grid-column: span 3; }
  .projet:nth-child(6n+6) { grid-column: span 3; }
}

.projet {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  cursor: pointer;
  background: none;
}

.projet .photo { aspect-ratio: 4 / 3; }
@media (min-width: 700px) {
  .projet:nth-child(6n+1) .photo,
  .projet:nth-child(6n+4) .photo { aspect-ratio: 16 / 9; }
  .projet:nth-child(6n+2) .photo,
  .projet:nth-child(6n+3) .photo { aspect-ratio: 3 / 4; }
}

/* Largeurs posées par le script (composerGrille, dans main.js) d'après les
   cartes réellement visibles. Elles remplacent le motif nth-child ci-dessus,
   qui ne sert plus que sans JavaScript : ce motif suit la position dans le
   HTML, pas l'affichage, et laisserait des trous une fois un filtre appliqué.
   Chaque largeur a son format d'image. */
@media (min-width: 700px) {
  .projet[data-largeur="2"] { grid-column: span 2; }
  .projet[data-largeur="3"] { grid-column: span 3; }
  .projet[data-largeur="4"] { grid-column: span 4; }
  .projet[data-largeur="6"] { grid-column: 1 / -1; }

  .projet[data-largeur="2"] .photo { aspect-ratio: 3 / 4; }
  .projet[data-largeur="3"] .photo { aspect-ratio: 4 / 3; }
  .projet[data-largeur="4"] .photo { aspect-ratio: 16 / 9; }
  .projet[data-largeur="6"] .photo { aspect-ratio: 21 / 9; }
}

.projet:hover .photo img,
.projet:focus-visible .photo img { transform: scale(1.06); }

/* Volet de chantier : à l'apparition de la carte, un panneau béton bordé
   de jaune glisse vers la droite et découvre la photo, qui se recadre en
   même temps. Le recadrage passe par la propriété scale, distincte de
   transform : il peut ainsi attendre le départ du volet sans retarder le
   zoom au survol. */
@media (prefers-reduced-motion: no-preference) {
  .js .projet .photo::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    background: #C9C5BE;
    border-left: 4px solid var(--accent);
    transition: transform 1.1s var(--ease);
    transition-delay: calc(var(--delai, 0ms) + 250ms);
  }
  .js .projet.est-visible .photo::after { transform: translateX(101%); }

  .js .projet .photo img {
    transition: opacity 0.7s var(--ease), transform 1.2s var(--ease),
                scale 1.6s var(--ease) calc(var(--delai, 0ms) + 250ms);
  }
  .js .projet:not(.est-visible) .photo img { scale: 1.12; }
}

.projet__contenu { padding-top: 1.15rem; }

.projet__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem;
  margin-bottom: 0.6rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.projet__meta .annee { color: var(--texte-sourd); }

.projet__statut {
  border: 1px solid var(--ligne-forte);
  padding: 0.2rem 0.5rem;
  color: var(--texte);
  letter-spacing: 0.1em;
}
.projet__statut[data-statut="cours"] {
  border-color: var(--accent);
  color: var(--accent);
}

.projet__titre {
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.15rem, 1.8vw, 1.6rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1.08;
}

.projet__lieu {
  font-size: 0.88rem;
  font-weight: 400;
  color: var(--texte);
  margin-top: 0.35rem;
}

.projet__action {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  transition: gap 0.35s var(--ease);
}
.projet:hover .projet__action { gap: 0.9rem; }

/* Projet masqué par un filtre. */
.projet[hidden] { display: none; }

/* État vide du portfolio, si un filtre ne renvoie aucun chantier. */
.projets-vide {
  border: 1px solid var(--ligne);
  padding: clamp(2.5rem, 6vw, 4.5rem);
  text-align: center;
}
.projets-vide p { color: var(--texte); margin-bottom: 1.5rem; }

/* --------------------------------------------------------------------------
   15. FICHE PROJET (dialogue)
   -------------------------------------------------------------------------- */

.fiche {
  border: 1px solid var(--ligne);
  padding: 0;
  width: min(1180px, calc(100vw - 2rem));
  max-width: none;
  max-height: calc(100dvh - 2rem);
  background: var(--fond);
  color: var(--encre);
  overflow: hidden;
}
.fiche::backdrop { background: rgba(21, 21, 21, 0.72); backdrop-filter: blur(4px); }

.fiche__corps { display: grid; max-height: calc(100dvh - 2rem); overflow-y: auto; }
@media (min-width: 900px) {
  .fiche__corps { grid-template-columns: minmax(0, 1fr) 360px; align-items: start; }
}

.fiche__media { background: var(--encre); min-width: 0; }

/* Visionneuse : la photo est affichée entière, sans recadrage, pour que
   les clichés verticaux du chantier restent lisibles. */
.fiche__visionneuse { position: relative; }
.fiche__media .photo {
  aspect-ratio: 4 / 3;
  background-color: var(--encre);
  background-image: none;
}
.fiche__media .photo img { object-fit: contain; }
.fiche__media .photo__slot { color: #8E8C88; }
.fiche__media .photo__slot b { color: #B5B3AE; }

.fiche__fleche {
  position: absolute;
  top: 50%;
  z-index: 2;
  width: 48px; height: 48px;
  display: grid;
  place-items: center;
  transform: translateY(-50%);
  background: rgba(21, 21, 21, 0.72);
  color: var(--sur-sombre);
  font-size: 1.15rem;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.fiche__fleche:hover { background: var(--accent); color: var(--encre); }
.fiche__fleche--prec { left: 0.75rem; }
.fiche__fleche--suiv { right: 0.75rem; }

.fiche__legende {
  padding: 0.9rem 1.25rem 0;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--sur-sombre);
}

/* Bandeau de vignettes, défilable à la main sur petit écran. */
.fiche__vignettes {
  position: relative;
  display: flex;
  gap: 6px;
  padding: 0.9rem 1.25rem 1.25rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
}
.fiche__vignette {
  flex: 0 0 auto;
  width: 76px;
  aspect-ratio: 4 / 3;
  padding: 0;
  overflow: hidden;
  scroll-snap-align: start;
  outline-offset: 2px;
  opacity: 0.5;
  transition: opacity 0.3s var(--ease);
}
.fiche__vignette img { width: 100%; height: 100%; object-fit: cover; }
.fiche__vignette:hover { opacity: 0.85; }
.fiche__vignette[aria-current="true"] { opacity: 1; outline: 2px solid var(--accent); }

.fiche__texte { padding: clamp(1.75rem, 3.5vw, 2.5rem); }
.fiche__texte > * + * { margin-top: 1.25rem; }

/* Sur écran large, le bouton de fermeture surplombe la colonne de texte :
   le titre lui laisse la place. */
@media (min-width: 900px) {
  .fiche__texte .titre-m { padding-right: 2.75rem; }
}

.fiche__fermer {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  z-index: 2;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  background: var(--encre);
  color: var(--fond);
  font-size: 1.1rem;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.fiche__fermer:hover { background: var(--accent); color: var(--encre); }

.fiche__liste { display: grid; gap: 0.75rem; }
.fiche__liste div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--ligne);
  font-size: 0.85rem;
}
.fiche__liste dt {
  color: var(--texte-sourd);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.7rem;
}
.fiche__liste dd { margin: 0; text-align: right; }

/* --------------------------------------------------------------------------
   16. RUPTURE PANORAMIQUE (sur le terrain)
   -------------------------------------------------------------------------- */

.terrain {
  position: relative;
  min-height: min(78vh, 700px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  padding-block: clamp(4rem, 9vw, 7rem);
  background: var(--encre);
  color: var(--sur-sombre);
}

.terrain__media { position: absolute; inset: 0; }
.terrain__media .photo { width: 100%; height: 100%; }

/* Parallaxe très légère : la photographie recule un peu plus lentement
   que le texte pendant le défilement. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .terrain__media .photo img {
      animation: terrainParallaxe linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }
    @keyframes terrainParallaxe {
      from { transform: scale(1.14) translateY(-3%); }
      to   { transform: scale(1.14) translateY(3%); }
    }
  }
}

.terrain__voile {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12,12,12,0.46) 0%, rgba(12,12,12,0.28) 40%, rgba(12,12,12,0.92) 100%);
}

.terrain__zone { position: relative; z-index: 1; width: 100%; }
.terrain__titre { max-width: 20ch; margin-bottom: 1.5rem; }
.terrain__texte { color: rgba(244, 243, 241, 0.88); max-width: 48ch; }

/* --------------------------------------------------------------------------
   17. POURQUOI AVZ (grille de filets, sans cartes)
   -------------------------------------------------------------------------- */

.atouts { display: grid; gap: 0; border-top: 1px solid var(--ligne); }

@media (min-width: 700px) { .atouts { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .atouts { grid-template-columns: repeat(4, 1fr); } }

.atout {
  padding: clamp(2rem, 3.2vw, 2.9rem) clamp(1.25rem, 2vw, 2rem) clamp(2rem, 3.2vw, 2.9rem) 0;
  border-bottom: 1px solid var(--ligne);
  position: relative;
}

@media (min-width: 700px) {
  .atout { padding-left: clamp(1.5rem, 2.4vw, 2.4rem); border-left: 1px solid var(--ligne); }
  .atout:first-child { padding-left: 0; border-left: 0; }
  .atout:nth-child(3) { padding-left: 0; border-left: 0; }
}
@media (min-width: 1100px) {
  .atout:nth-child(3) { padding-left: clamp(1.5rem, 2.4vw, 2.4rem); border-left: 1px solid var(--ligne); }
}

/* Filet d'accent qui se dessine à l'apparition de la section. */
.atout::before {
  content: "";
  position: absolute;
  top: -1px; left: 0;
  width: 0; height: 2px;
  background: var(--accent);
  transition: width 0.8s var(--ease);
  transition-delay: var(--delai, 0ms);
}
.atout.est-visible::before { width: 44px; }

.atout__titre {
  font-family: "Montserrat", sans-serif;
  font-size: clamp(1.1rem, 1.5vw, 1.35rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin-bottom: 1rem;
}
.atout__texte { font-size: 0.94rem; font-weight: 400; line-height: 1.7; color: var(--texte); }

/* --------------------------------------------------------------------------
   18. REPÈRES (bande qualitative)
   -------------------------------------------------------------------------- */

.reperes {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  background: var(--fond-2);
  border-block: 1px solid var(--ligne);
  padding: clamp(3rem, 6vw, 5rem) clamp(1.5rem, 3vw, 3rem);
}
@media (min-width: 700px) { .reperes { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .reperes { grid-template-columns: repeat(4, 1fr); } }

.repere__valeur {
  display: block;
  font-family: "Montserrat", sans-serif;
  font-size: clamp(2.6rem, 5.5vw, 4.4rem);
  font-weight: 900;
  line-height: 0.9;
  letter-spacing: -0.045em;
  color: var(--accent);
  margin-bottom: 0.9rem;
}
.repere__valeur--mot {
  font-size: clamp(1.5rem, 2.6vw, 2.2rem);
  letter-spacing: -0.025em;
  text-transform: uppercase;
  color: var(--encre);
}

.repere__libelle {
  font-size: 0.86rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--texte);
  max-width: 24ch;
}

/* --------------------------------------------------------------------------
   19. MANIFESTE (notre entreprise)
   -------------------------------------------------------------------------- */

.manifeste { max-width: 62rem; margin-inline: auto; text-align: center; }
.manifeste .titre-l { margin-bottom: 2.5rem; }
.manifeste .texte { margin-inline: auto; text-align: left; }
.manifeste .texte + .texte { margin-top: 1.4rem; }

/* --------------------------------------------------------------------------
   21. APPEL À L'ACTION FINAL
   -------------------------------------------------------------------------- */

.final {
  position: relative;
  overflow: hidden;
  padding-block: clamp(5rem, 13vw, 11rem);
  background: var(--encre);
  color: var(--sur-sombre);
}

.final__media { position: absolute; inset: 0; }
.final__media .photo { width: 100%; height: 100%; }
.final__voile {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12,12,12,0.88) 0%, rgba(12,12,12,0.74) 50%, rgba(12,12,12,0.94) 100%);
}

.final__zone { position: relative; z-index: 1; }
.final__titre { margin-bottom: 2rem; }
.final__titre > span { display: block; }
.final__titre > span:last-child { color: var(--accent); }
.final__texte { margin-bottom: 2.75rem; color: rgba(244, 243, 241, 0.88); }
.final__actions { display: flex; flex-wrap: wrap; gap: 0.9rem; }

/* --------------------------------------------------------------------------
   22. CONTACT
   -------------------------------------------------------------------------- */

.contact { display: grid; gap: clamp(3rem, 6vw, 5rem); }
@media (min-width: 950px) { .contact { grid-template-columns: 1.25fr 0.75fr; } }

.formulaire { display: grid; gap: 1.5rem; }

.champs { display: grid; gap: 1.5rem; }
@media (min-width: 600px) { .champs--duo { grid-template-columns: repeat(2, 1fr); } }

.champ { display: grid; gap: 0.5rem; }

/* Étiquette toujours au-dessus du champ, jamais de libellé dans le placeholder. */
.champ label,
.champ__titre {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte);
}
.champ label .requis { color: var(--accent); }

.champ input,
.champ select,
.champ textarea {
  width: 100%;
  padding: 0.95rem 1rem;
  background: #FFFFFF;
  border: 1px solid var(--ligne-forte);
  color: var(--encre);
  font-family: inherit;
  font-size: 0.95rem;
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
  appearance: none;
  border-radius: 0;
}
.champ textarea { min-height: 9rem; resize: vertical; }

.champ select {
  background-image: linear-gradient(45deg, transparent 50%, var(--texte) 50%),
                    linear-gradient(135deg, var(--texte) 50%, transparent 50%);
  background-position: calc(100% - 20px) center, calc(100% - 14px) center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 2.75rem;
}

/* Contraste du texte indicatif vérifié sur le fond blanc du champ. */
.champ input::placeholder,
.champ textarea::placeholder { color: var(--texte-sourd); opacity: 1; }

.champ input:hover,
.champ select:hover,
.champ textarea:hover { border-color: var(--encre); }

.champ input:focus,
.champ select:focus,
.champ textarea:focus {
  outline: none;
  border-color: var(--encre);
  box-shadow: inset 0 0 0 2px var(--accent);
}

/* Message d'aide, puis message d'erreur sous le champ. */
.champ__aide { font-size: 0.78rem; color: var(--texte-sourd); }

.champ__erreur {
  font-size: 0.8rem;
  font-weight: 500;
  color: #A4231A;
  display: none;
}
.champ.est-invalide .champ__erreur { display: block; }
.champ.est-invalide input,
.champ.est-invalide select,
.champ.est-invalide textarea { border-color: #A4231A; }

/* Zone de dépôt de fichiers. La zone est une balise label pour rester
   cliquable partout, mais elle porte des phrases : on annule donc la mise
   en capitales héritée des étiquettes de champ. */
.champ label.depot {
  border: 1px dashed var(--ligne-forte);
  padding: 1.6rem;
  text-align: center;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  color: var(--encre);
  background: #FFFFFF;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
  cursor: pointer;
  display: block;
}
.champ label.depot:hover,
.champ label.depot.est-survolee { border-color: var(--accent); background: var(--fond-2); }
.depot input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.depot__titre { font-size: 0.86rem; font-weight: 500; }
.depot__aide { font-size: 0.76rem; color: var(--texte-sourd); margin-top: 0.35rem; display: block; }

.depot-fichiers { display: grid; gap: 0.5rem; margin-top: 0.9rem; }
.depot-fichiers li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.55rem 0.8rem;
  background: #FFFFFF;
  border: 1px solid var(--ligne);
  font-size: 0.8rem;
}
.depot-fichiers .poids { color: var(--texte-sourd); }

.formulaire__pied { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; }

/* Champ piège contre les robots : sorti de l'écran, jamais atteint au clavier. */
.champ-piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* État de chargement du bouton d'envoi. */
.btn[data-etat="envoi"] { pointer-events: none; opacity: 0.75; }
.btn[data-etat="envoi"] .fleche { animation: pulseFleche 0.9s ease-in-out infinite; }
@keyframes pulseFleche { 50% { transform: translateX(5px); opacity: 0.4; } }

/* Retour global du formulaire. */
.formulaire__retour {
  border: 1px solid var(--ligne-forte);
  padding: 1.1rem 1.3rem;
  font-size: 0.9rem;
  line-height: 1.6;
  display: none;
  background: #FFFFFF;
}
.formulaire__retour.est-visible { display: block; }
.formulaire__retour[data-ton="succes"] { border-left: 3px solid var(--accent); }
.formulaire__retour[data-ton="erreur"] { border-left: 3px solid #A4231A; color: #7C1A13; }
.formulaire__retour a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }

/* Colonne des coordonnées. */
.coordonnees { display: grid; gap: 2rem; align-content: start; }

.coordonnee { border-top: 1px solid var(--ligne); padding-top: 1.1rem; }
.coordonnee dt {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-sourd);
  margin-bottom: 0.5rem;
}
.coordonnee dd { margin: 0; font-size: 1rem; line-height: 1.6; }
.coordonnee dd a { transition: color 0.3s var(--ease); }
.coordonnee dd a:hover { color: var(--accent); }

/* Marqueur des informations restant à compléter par AVZ. */
.a-completer {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border: 1px dashed var(--accent);
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em;
}

/* Carte chargée au clic, pour ne poser aucun cookie tiers sans accord. */
.carte {
  position: relative;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--ligne);
  overflow: hidden;
}
.carte iframe { width: 100%; height: 100%; border: 0; filter: grayscale(1) contrast(1.05); }

.carte__invite {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  padding: 1.5rem;
  text-align: center;
  background: var(--fond-3);
  background-image: repeating-linear-gradient(
    135deg, rgba(21,21,21,0.03) 0 2px, transparent 2px 5px);
}
.carte__invite p { font-size: 0.82rem; color: var(--texte); max-width: 32ch; }

/* --------------------------------------------------------------------------
   23. PIED DE PAGE
   --------------------------------------------------------------------------
   Seul bloc sombre non photographique de la page. C'est un terminus voulu,
   qui répond au héros et referme la lecture.
   -------------------------------------------------------------------------- */

.footer {
  background: var(--encre);
  color: var(--sur-sombre);
  padding-block: clamp(3.5rem, 7vw, 6rem) 2rem;
}

.footer__haut {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid rgba(244, 243, 241, 0.16);
}
@media (min-width: 800px) { .footer__haut { grid-template-columns: 1.4fr 1fr 1fr; } }

.footer .logo img { filter: brightness(0) invert(1); height: 34px; }

.footer__phrase {
  margin-top: 1.5rem;
  font-family: "Montserrat", sans-serif;
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sur-sombre-doux);
}

.footer__titre {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sur-sombre-doux);
  margin-bottom: 1.25rem;
}

.footer__liste { display: grid; gap: 0.7rem; }
.footer__liste a, .footer__liste span {
  font-size: 0.92rem;
  color: var(--sur-sombre-doux);
  transition: color 0.3s var(--ease);
}
.footer__liste a:hover { color: var(--accent); }

/* Dans le pied de page sombre, le marqueur repasse en orange vif. */
.footer .a-completer { border-color: var(--accent); color: var(--accent); }

.footer__bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding-top: 2rem;
  font-size: 0.78rem;
  color: var(--sur-sombre-doux);
}
.footer__legal { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.footer__legal a { transition: color 0.3s var(--ease); }
.footer__legal a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   24. PAGES LÉGALES
   -------------------------------------------------------------------------- */

.page-legale {
  padding-top: calc(var(--header-h) + clamp(3rem, 7vw, 6rem));
  padding-bottom: clamp(4rem, 8vw, 7rem);
}
/* Page introuvable : peu de contenu, le pied de page reste en bas de l'écran. */
.page-legale--courte { min-height: calc(100vh - 8rem); }

.page-legale__entete {
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  border-bottom: 1px solid var(--ligne);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.prose { max-width: 68ch; }
.prose > * + * { margin-top: 1.5rem; }

.prose h2 {
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  text-transform: uppercase;
  letter-spacing: -0.015em;
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--ligne);
}
.prose h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

.prose p, .prose li { color: var(--texte); font-weight: 400; line-height: 1.75; }

.prose ul { display: grid; gap: 0.6rem; padding-left: 1.2rem; list-style: disc; }
.prose li::marker { color: var(--accent); }

.prose a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.prose a.btn { color: var(--encre); text-decoration: none; }

.prose dl { display: grid; gap: 0.5rem; }
.prose dt { color: var(--encre); font-weight: 600; }
.prose dd { margin: 0; color: var(--texte); font-weight: 400; }

/* Sur les pages légales, l'en-tête est collée dès le chargement : il n'y a
   pas de photographie derrière. */
.page-legale ~ .footer { margin-top: 0; }

/* --------------------------------------------------------------------------
   25. RÉGLAGES D'ACCESSIBILITÉ GLOBAUX
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .bandeau__piste { animation: none; }
  /* Le bandeau devient une liste défilable à la main. */
  .bandeau { overflow-x: auto; }
}

/* Impression : navigation et grands visuels retirés. */
@media print {
  body { background: #fff; color: #000; }
  .header, .menu-mobile, .bandeau, .filtres, .carte, .final__media, .hero__media { display: none; }
  .hero, .terrain, .final, .footer { background: #fff; color: #000; }
  .progression-lecture, .js .projet .photo::after { display: none; }
  .js .reveal, .js .titre-anime .mot__int { opacity: 1; transform: none; }
  .js .projet:not(.est-visible) .photo img { scale: none; }
}
