/* ==========================================================================
   Imagerie GS — feuille de style principale
   Palette échantillonnée directement dans le logo (vert #00B030, bleu #0070B0)
   ========================================================================== */

:root {
  --ink:        #070908;
  --ink-2:      #0E1211;
  --ink-3:      #171C1A;
  --blanc:      #F2F5F3;
  --gris:       #9AA5A0;
  --gris-fonce: #5A625E;
  --vert:       #00B140;
  --vert-clair: #3ED47A;
  --bleu:       #0F86C6;

  --nav-h: 72px;

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --ease: cubic-bezier(.22, .61, .36, 1);
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--blanc);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video { display: block; max-width: 100%; }

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

/* Accessibilité : cible de saut clavier */
.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--vert); color: #04140A;
  padding: .75rem 1.25rem; z-index: 999; font-weight: 600;
}
.skip:focus { left: 0; }

:focus-visible {
  outline: 2px solid var(--vert-clair);
  outline-offset: 3px;
}

/* ==========================================================================
   Navigation
   ========================================================================== */

/* ⚠️ z-index 70 : AU-DESSUS du menu (60). Sinon le panneau recouvre la barre
   et le bouton de fermeture devient inaccessible — on ouvre le menu sans
   pouvoir le refermer autrement qu'au clavier. */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 70;
  height: var(--nav-h);
  display: flex; align-items: center; gap: 1.5rem;
  padding: 0 clamp(1rem, 4vw, 2.75rem);
  transition: background-color .45s var(--ease), backdrop-filter .45s var(--ease);
}

/* Fond seulement une fois sorti du hero — sur le hero, la vidéo respire */
.nav.is-stuck {
  background: rgba(7, 9, 8, .82);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, .07);
}

/* Le logo de la barre reste caché tant que le grand logo du hero est visible :
   sinon on afficherait deux fois la même marque à l'écran.
   Version couleur ici : sur le fond sombre de la barre elle ne concurrence
   aucune image, contrairement au hero où le blanc reste de mise. */
/* ⚠️ LE LIEN DU LOGO NE DOIT JAMAIS SE COMPRIMER.
   La barre est un conteneur flex : par défaut, chaque enfant accepte de
   rétrécir. Sur téléphone, le bouton d'appel à l'action prenait 251 px des
   504 disponibles et le logo se retrouvait écrasé à 60 px au lieu de 126,
   avec un rapport de 1,99 au lieu de 4,2. Autrement dit déformé, illisible,
   et le visiteur n'avait plus de chemin vers l'accueil.
   `flex: 0 0 auto` règle ça définitivement : c'est aux autres de céder. */
.nav > a:first-child { flex: 0 0 auto; }
.nav__burger { flex: 0 0 auto; }

.nav__logo {
  height: 30px; width: auto;
  opacity: 0; transform: translateY(-6px);
  transition: opacity .45s var(--ease), transform .45s var(--ease);
  pointer-events: none;
}
.nav.is-stuck .nav__logo { opacity: 1; transform: none; pointer-events: auto; }

/* Deux libellés pour le bouton de la barre : le long sur grand écran, un
   court sur téléphone. Le HTML porte les deux, le CSS n'en montre qu'un. */
.nav__cta-court { display: none; }

.nav__spacer { flex: 1; }

.nav__menu {
  display: flex; align-items: center; gap: clamp(1rem, 2.5vw, 2.25rem);
  list-style: none; margin: 0; padding: 0;
}

.nav__link {
  font-size: .82rem; font-weight: 500;
  letter-spacing: .11em; text-transform: uppercase;
  color: rgba(242, 245, 243, .8);
  position: relative; padding: .35rem 0;
  transition: color .25s var(--ease);
}
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: var(--vert);
  transform: scaleX(0); transform-origin: left;
  transition: transform .35s var(--ease);
}
.nav__link:hover { color: var(--blanc); }
.nav__link:hover::after { transform: scaleX(1); }

.nav__cta {
  font-size: .8rem; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  padding: .7rem 1.35rem; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .28);
  transition: background-color .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease);
  white-space: nowrap;
}
.nav__cta:hover {
  background: var(--vert); border-color: var(--vert); color: #04140A;
}

/* Masqué sur ordinateur : le menu en ligne y suffit, et afficher les deux
   côte à côte donne l'impression d'une navigation inachevée. Il réapparaît
   sous 861 px, où le menu en ligne disparaît. Le saut d'un service à l'autre
   sur ordinateur passe par les liens « Voir aussi » en bas de chaque page de
   service. */
.nav__burger {
  display: none; align-items: center;
  background: none; border: 0; padding: .5rem; cursor: pointer;
  color: var(--blanc);
  transition: color .25s var(--ease);
}
.nav__burger:hover { color: var(--vert-clair); }
.nav__burger .icone-fermer { display: none; }
.nav__burger[aria-expanded="true"] .icone-ouvrir { display: none; }
.nav__burger[aria-expanded="true"] .icone-fermer { display: block; }

/* ==========================================================================
   Menu complet (ouvert par le burger)
   ========================================================================== */

.menu {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(7, 9, 8, .97);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  overflow-y: auto;
  padding: calc(var(--nav-h) + 2.5rem) clamp(1.25rem, 5vw, 3rem) 3rem;
}

/* ⚠️ L'animation ne touche QUE la position, jamais l'opacité.
   Une première version faisait apparaître le panneau depuis `opacity: 0` :
   si l'animation ne se déclenche pas — navigateur qui la gèle, moteur de
   rendu particulier — le menu reste totalement invisible alors qu'il est
   ouvert et qu'il bloque le défilement. Mesuré : `opacity` calculée à 0
   sur un menu pourtant ouvert. Avec un simple déplacement, le pire cas est
   un panneau décalé de 10 px, jamais un panneau introuvable. */
@keyframes menu-apparait {
  from { transform: translateY(-10px); }
  to   { transform: none; }
}

.menu__inner {
  max-width: 62rem; margin: 0 auto;
  animation: menu-apparait .3s var(--ease);
}

.menu__titre {
  margin: 0 0 1.25rem;
  font-size: .74rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--vert-clair);
}

.menu__liste { list-style: none; margin: 0 0 2.75rem; padding: 0; }
.menu__liste li + li { border-top: 1px solid rgba(255, 255, 255, .08); }

.menu__liste a {
  display: flex; align-items: baseline; gap: 1rem;
  padding: 1.05rem 0;
  font-size: clamp(1.15rem, 1rem + .8vw, 1.6rem);
  font-weight: 600; letter-spacing: -.015em; line-height: 1.2;
  color: rgba(242, 245, 243, .9);
  transition: color .25s var(--ease), padding-left .25s var(--ease);
}
.menu__liste a:hover { color: var(--vert-clair); padding-left: .6rem; }

/* La page où l'on se trouve : elle est en vert, SANS cadre. Le cadre vert est
   réservé à la mise au point au clavier, et confondre les deux induit en
   erreur. */
.menu__liste a[aria-current="page"] { color: var(--vert-clair); }

/* Le panneau reçoit la mise au point à l'ouverture, pour que la tabulation
   entre dedans. Mais il ne doit rien dessiner : ce n'est pas un élément sur
   lequel on agit, et un cadre autour de tout le menu n'a aucun sens. */
.menu:focus { outline: none; }

.menu__no {
  flex: 0 0 auto;
  font-size: .78rem; font-weight: 600; letter-spacing: .12em;
  color: var(--gris-fonce);
}

.menu__liste--simple a { font-size: clamp(1rem, .95rem + .4vw, 1.2rem); }

@media (prefers-reduced-motion: reduce) {
  .menu__inner { animation: none; }
}

/* ==========================================================================
   Hero d'ouverture
   ========================================================================== */

.hero {
  position: relative;
  min-height: 560px;
  height: 100svh;
  display: grid; place-items: center;
  overflow: hidden;
  background: var(--ink);
}

.hero__media { position: absolute; inset: 0; }

.hero__video,
.hero__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* La vidéo apparaît en fondu une fois qu'elle a réellement des images à montrer,
   ce qui évite le flash noir entre le poster et la première frame. */
.hero__video { opacity: 0; transition: opacity .9s var(--ease); }
.hero__video.is-ready { opacity: 1; }

/* Voile de lisibilité.
   Le montage est LUMINEUX (basilique au soleil, écume blanche du barrage,
   ciel de montgolfière) : sans ce voile, le logo blanc disparaît sur
   plusieurs plans. Il est concentré au centre et aux bords, pas uniforme,
   pour assombrir le moins d'image possible. */
.hero__scrim {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 82% 58% at 50% 50%,
      rgba(0, 0, 0, .60) 0%, rgba(0, 0, 0, .28) 52%, rgba(0, 0, 0, 0) 76%),
    linear-gradient(to bottom,
      rgba(0, 0, 0, .58) 0%, rgba(0, 0, 0, 0) 24%,
      rgba(0, 0, 0, 0) 58%, rgba(0, 0, 0, .78) 100%);
}

.hero__inner {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  padding: var(--nav-h) 1.5rem 0;
  width: 100%;
}

/* Colonne flex centrée : un enfant prend la largeur de son contenu et rien
   ne le plafonne. Les largeurs en `ch` (46ch pour la phrase d'offre) et les
   lignes qui ne se coupent pas débordaient alors de l'écran sur mobile —
   logo, texte et boutons se retrouvaient rognés à droite. Ce plafond règle
   le cas une fois pour toutes, y compris pour ce qu'on ajoutera ici. */
.hero__inner > * { max-width: 100%; }

.hero__logo {
  width: min(76vw, 560px);
  height: auto;
  /* Ombre portée douce : sépare le logo du feuillage clair sans halo visible */
  filter: drop-shadow(0 6px 26px rgba(0, 0, 0, .65));
}

.hero__tagline {
  margin: 1.75rem 0 0;
  /* 46ch : la phrase d'offre tient sur deux lignes équilibrées. Plus étroit,
     le dernier mot se retrouve seul sur une troisième ligne. */
  max-width: 46ch;
  font-size: clamp(1rem, 1.05rem + .35vw, 1.28rem);
  font-weight: 400;
  line-height: 1.55;
  color: rgba(242, 245, 243, .93);
  text-shadow: 0 2px 18px rgba(0, 0, 0, .75);
}

/* Mention de territoire : une étiquette d'items séparés par des puces,
   PAS une phrase. Elle a été essayée en phrase complète — trois lignes qui
   faisaient un second slogan sous le premier et repoussaient les boutons.
   Courte et sur une seule ligne, elle informe sans concurrencer l'offre. */
.hero__accroche {
  margin: 1.1rem 0 0;
  font-size: clamp(.8rem, .78rem + .2vw, .94rem);
  font-weight: 500;
  letter-spacing: .05em;
  line-height: 1.6;
  color: rgba(242, 245, 243, .78);
  text-shadow: 0 2px 14px rgba(0, 0, 0, .8);
}

/* Les puces structurent la lecture sans peser : plus pâles que les mots. */
.hero__puce {
  color: rgba(242, 245, 243, .38);
  margin: 0 .28em;
}

.hero__actions {
  margin-top: 2.4rem;
  display: flex; flex-wrap: wrap; gap: .9rem; justify-content: center;
}

.btn {
  display: inline-flex; align-items: center; gap: .6rem;
  font-size: .84rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 1rem 1.9rem; border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .3s var(--ease), background-color .3s var(--ease),
              border-color .3s var(--ease), color .3s var(--ease);
}
.btn:hover { transform: translateY(-2px); }

.btn--primaire { background: var(--vert); color: #04140A; }
.btn--primaire:hover { background: var(--vert-clair); }

.btn--fantome {
  border-color: rgba(255, 255, 255, .4);
  color: var(--blanc);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.btn--fantome:hover { border-color: var(--blanc); background: rgba(255, 255, 255, .1); }

.btn__fleche { transition: transform .3s var(--ease); }
.btn:hover .btn__fleche { transform: translateX(3px); }

/* Indice de défilement */
.hero__scroll {
  position: absolute; left: 50%; bottom: 2rem; z-index: 2;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: .6rem;
  font-size: .68rem; letter-spacing: .22em; text-transform: uppercase;
  color: rgba(242, 245, 243, .62);
}
.hero__souris {
  width: 24px; height: 38px; border-radius: 12px;
  border: 1px solid rgba(242, 245, 243, .45);
  position: relative;
}
.hero__souris::after {
  content: ""; position: absolute; left: 50%; top: 8px;
  width: 3px; height: 6px; border-radius: 2px;
  background: var(--vert-clair);
  transform: translateX(-50%);
  animation: molette 2s var(--ease) infinite;
}
@keyframes molette {
  0%, 18%  { opacity: 0; transform: translate(-50%, 0); }
  35%      { opacity: 1; }
  70%,100% { opacity: 0; transform: translate(-50%, 13px); }
}

/* Réseaux sociaux, colonne discrète à gauche */
.hero__social {
  position: absolute; left: clamp(1rem, 3vw, 2.5rem); bottom: 2rem; z-index: 2;
  display: flex; flex-direction: column; gap: 1.1rem;
}
.hero__social a {
  color: rgba(242, 245, 243, .68);
  transition: color .25s var(--ease), transform .25s var(--ease);
}
.hero__social a:hover { color: var(--vert-clair); transform: translateY(-2px); }
.hero__social svg { width: 19px; height: 19px; fill: currentColor; }

/* ==========================================================================
   Sections de catégorie — une par service, plein écran, vidéo en fond
   ========================================================================== */

.cat {
  position: relative;
  min-height: 560px;
  height: 100svh;
  display: flex; align-items: flex-end;
  overflow: hidden;
  background: var(--ink);
}

.cat__media { position: absolute; inset: 0; }

.cat__video,
.cat__poster {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

.cat__video { opacity: 0; transition: opacity .9s var(--ease); }
.cat__video.is-ready { opacity: 1; }

/* Voile orienté vers le bas-gauche, là où se pose le texte.
   Contrairement au hero d'ouverture (voile centré parce que le logo est au
   milieu), ici on assombrit un coin et on laisse le reste de l'image nette.

   Valeurs mesurées, pas estimées : 14 images prélevées dans chacune des
   4 vidéos, voile appliqué, contraste calculé sous le titre et sous le
   texte. Le pire cas donne 11,1:1 pour le titre et 13,2:1 pour le texte,
   là où WCAG AA demande 3:1 et 4,5:1. Un voile plus lourd (première
   version : .80 / .76) montait à 15:1 sans rien apporter, en assombrissant
   l'image pour rien. Ne pas le renforcer sans remesurer. */
.cat__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(to right,
      rgba(0, 0, 0, .64) 0%, rgba(0, 0, 0, .32) 36%, rgba(0, 0, 0, 0) 66%),
    linear-gradient(to top,
      rgba(0, 0, 0, .66) 0%, rgba(0, 0, 0, .08) 40%, rgba(0, 0, 0, 0) 60%);
}

.cat__inner {
  position: relative; z-index: 2;
  max-width: 46rem;
  padding: 0 clamp(1.25rem, 5vw, 4.5rem) clamp(3.25rem, 9vh, 6rem);
}

.cat__no {
  display: flex; align-items: center; gap: .8rem;
  margin: 0 0 1.1rem;
  font-size: .74rem; letter-spacing: .26em; text-transform: uppercase;
  color: rgba(242, 245, 243, .62);
}
.cat__no span {
  color: var(--vert-clair);
  font-weight: 600; letter-spacing: .12em;
}
/* Filet qui prolonge le numéro, discret */
.cat__no::after {
  content: ""; flex: 0 0 clamp(2rem, 6vw, 4.5rem);
  height: 1px; background: rgba(242, 245, 243, .28);
}

.cat__titre {
  margin: 0 0 .9rem;
  font-size: clamp(2rem, 1.15rem + 3.4vw, 3.6rem);
  font-weight: 600; line-height: 1.08; letter-spacing: -.025em;
  text-shadow: 0 2px 24px rgba(0, 0, 0, .6);
}
.cat__titre a {
  background-image: linear-gradient(var(--vert-clair), var(--vert-clair));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size .4s var(--ease);
}
.cat__titre a:hover { background-size: 100% 2px; }

.cat__desc {
  margin: 0 0 2.2rem;
  max-width: 40ch;
  font-size: clamp(1rem, .98rem + .3vw, 1.18rem);
  color: rgba(242, 245, 243, .88);
  text-shadow: 0 2px 16px rgba(0, 0, 0, .7);
}

/* ==========================================================================
   Accrochage entre sections plein écran

   CSS pur, aucun JavaScript : le défilement reste celui du navigateur.
   Un coup de molette se cale sur la section suivante, mais la molette
   maintenue, le clavier et la barre de défilement répondent normalement.

   Comportement voulu par Guillaume, dans l'ordre de la page :
     hero, puis les 4 catégories, puis « Pour le plaisir »
       -> un geste de molette = une section, on s'arrête à chacune ;
     « À propos » et « Contact »
       -> libre, on descend d'un trait si on veut.

   ⚠️ TOUT CE BLOC EST RÉSERVÉ À L'ACCUEIL, via `html.accueil`. Les six
   autres pages n'ont AUCUN accrochage, et c'est volontaire (voir piège 4).

   ⚠️ CE CSS NE RACONTE QUE LA MOITIÉ DE L'HISTOIRE. `main.js` éteint
   `scroll-snap-type` dès que le visiteur dépasse les catégories, et le
   rallume s'il remonte. Sans ce complément, le bas de la page s'accroche
   quand même, parce que « mandatory » oblige la page à se reposer sur un
   point d'accrochage : retirer l'alignement ne libère rien, ça aggrave
   (mesuré, voir piège 5). Le CSS seul reste la position de repli si le
   JavaScript ne tourne pas : imparfait, mais utilisable.

   ⚠️⚠️ QUATRE PIÈGES, TOUS VÉRIFIÉS À LA DURE. Lire avant de toucher.

   1. NE PAS PASSER EN « proximity ». Essayé, mesuré à 0 px de dérive au
      navigateur pilote, et pourtant CASSÉ à l'usage : un vrai coup de
      molette ne s'accroche plus d'un hero à l'autre. Le pilotage
      programmatique (`scrollTo`) ne reproduit PAS le comportement d'une
      molette, il ne peut donc rien prouver ici. Seul l'essai à la main
      compte pour cette propriété.

   2. NE PAS RETIRER `scroll-snap-align` DE « À propos » ET « Contact ».
      Mesuré : en « mandatory », sans point d'accrochage, 2683 px de page
      deviennent inatteignables. C'est l'alignement qui reste, c'est
      `scroll-snap-stop` qui part. Ce sont deux propriétés différentes :
        - `scroll-snap-align` dit OÙ la page se pose ;
        - `scroll-snap-stop: always` interdit d'en sauter une d'un geste.
      C'est la seconde, et elle seule, qui rendait le bas pénible.

   3. `.pied { scroll-snap-align: end }` N'EST PAS DÉCORATIF. Sans cette
      ligne, les 348 derniers pixels du pied de page sont INATTEIGNABLES en
      mode « mandatory » : la page est ramenée au début de « Contact ». Le
      bug existait depuis le début et personne ne l'avait vu. Mesuré avant
      et après.

   4. `.pied` EXISTE SUR LES SEPT PAGES, PAS SEULEMENT SUR L'ACCUEIL. Quand
      la règle du piège 3 n'était pas limitée à `html.accueil`, le pied de
      page devenait le SEUL point d'accrochage des six autres pages. En mode
      « mandatory », un point unique aimante toute la page : le défilement
      de « Photos » et des pages de service était cassé. D'où `html.accueil`
      partout ici, et la classe correspondante sur le <html> de index.html
      seulement. Ne jamais rendre ces règles globales.

   5. ON NE LIBÈRE PAS LE BAS DE PAGE EN RETIRANT `scroll-snap-align`.
      Contre-intuitif mais mesuré, dérive lors d'un arrêt volontaire dans
      « À propos » :
        align sur À propos et Contact        114 px
        sans align, avec point sur le pied   767 px
        sans align, sans point sur le pied   767 px, et 1973 px de page perdus
        sans align, pied en `start`          767 px
      Retirer l'alignement ne libère rien : la page est happée vers un point
      plus lointain. C'est pour ça que la bascule se fait en JavaScript.

   Désactivé sous 861 px : sur mobile, le défilement reste entièrement
   naturel, comme convenu au départ.
   ========================================================================== */

@media (min-width: 861px) and (prefers-reduced-motion: no-preference) {
  html.accueil { scroll-snap-type: y mandatory; }

  /* Un geste de molette = une section. UNIQUEMENT le hero et les 4
     catégories : ce sont les seules à remplir l'écran d'une image. L'arrêt
     forcé se justifie parce qu'il y a quelque chose à voir. */
  .accueil .hero,
  .accueil .cat {
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }

  /* ⚠️ `.portfolio` (« Pour le plaisir ») A ÉTÉ RETIRÉ DU GROUPE CI-DESSUS,
     volontairement. Ce bloc ne fait que 417 px de haut : lui imposer un arrêt
     revenait à immobiliser le visiteur sur un écran presque vide, juste pour
     un surtitre, deux lignes et un bouton. Passé les catégories, on ne
     découvre plus, on cherche à descendre.

     L'alignement reste, sur les trois (voir piège 2) : c'est ce qui les rend
     atteignables en mode « mandatory ». */
  .accueil .portfolio,
  .accueil .apropos,
  .accueil .contact,
  .accueil .provisoire {
    scroll-snap-align: start;
  }

  /* Voir pièges 3 et 4. */
  .accueil .pied { scroll-snap-align: end; }
}

/* ==========================================================================
   Pages de service

   En-tête illustrée par le poster de la catégorie — le même fichier que la
   section de l'accueil, donc déjà en cache quand on arrive par le lien.
   Aucune vidéo ici : la page est faite pour être lue, pas contemplée.
   ========================================================================== */

.svc__entete {
  position: relative;
  min-height: 400px;
  display: flex; align-items: flex-end;
  overflow: hidden;
  background: var(--ink-2);
  padding: calc(var(--nav-h) + 3rem) 0 0;
}

.svc__fond {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* Voile plus dense que sur l'accueil : ici le texte occupe toute la largeur
   et doit rester lisible par-dessus l'image entière, pas seulement un coin.
   Dégradé en biais : opaque en bas à gauche sous le texte, nettement plus
   clair en haut à droite pour qu'on voie de quelle catégorie il s'agit. */
.svc__voile {
  position: absolute; inset: 0;
  background:
    linear-gradient(to top,
      rgba(7, 9, 8, .95) 0%, rgba(7, 9, 8, .72) 45%, rgba(7, 9, 8, .34) 100%),
    linear-gradient(to right,
      rgba(7, 9, 8, .55) 0%, rgba(7, 9, 8, .18) 55%, rgba(7, 9, 8, 0) 100%);
}

.svc__entete-inner {
  position: relative; z-index: 2;
  width: 100%;
  max-width: 62rem;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 5vw, 3rem) clamp(2.5rem, 6vh, 4rem);
}

.svc__surtitre {
  display: flex; align-items: center; gap: .8rem;
  margin: 0 0 1rem;
  font-size: .74rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--vert-clair);
}
.svc__surtitre::after {
  content: ""; flex: 0 0 clamp(2rem, 6vw, 4rem);
  height: 1px; background: rgba(242, 245, 243, .25);
}

.svc__titre {
  margin: 0 0 1.4rem;
  font-size: clamp(1.6rem, 1.1rem + 2vw, 2.5rem);
  font-weight: 600; line-height: 1.1; letter-spacing: -.02em;
}

/* La phrase d'accroche : plus grande que le corps, c'est elle qui porte la
   promesse au client. */
.svc__accroche {
  margin: 0 0 1.1rem;
  max-width: 26ch;
  font-size: clamp(1.45rem, 1rem + 1.9vw, 2.35rem);
  font-weight: 600; line-height: 1.18; letter-spacing: -.02em;
  color: var(--blanc);
}

.svc__intro {
  margin: 0;
  max-width: 60ch;
  font-size: clamp(1rem, .98rem + .25vw, 1.12rem);
  line-height: 1.65;
  color: rgba(242, 245, 243, .84);
}

/* --- Corps de page --- */

.svc__corps {
  max-width: 62rem;
  margin: 0 auto;
  padding: clamp(3rem, 7vw, 5rem) clamp(1.25rem, 5vw, 3rem) clamp(4rem, 9vw, 7rem);
}

.svc__bloc + .svc__bloc { margin-top: clamp(2.75rem, 6vw, 4.5rem); }
/* Même respiration quand un bloc suit une grille posée directement dans le
   corps de page, sans section autour (cas de la page Réalisations). */
.reals + .svc__bloc { margin-top: clamp(2.75rem, 6vw, 4.5rem); }

.svc__bloc-titre {
  margin: 0 0 1.5rem;
  font-size: .78rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--gris);
  font-weight: 600;
}

/* --- Bloc de confiance --- */

.confiance {
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 10px;
  background: var(--ink-2);
  padding: clamp(1.5rem, 3.5vw, 2.25rem);
}

.confiance__liste {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .95rem;
}
@media (min-width: 760px) {
  .confiance__liste { grid-template-columns: 1fr 1fr; gap: 1.1rem 2rem; }
}

.confiance__liste li {
  display: flex; align-items: flex-start; gap: .75rem;
  font-size: .98rem; line-height: 1.5;
  color: rgba(242, 245, 243, .9);
}

.confiance__coche {
  flex: 0 0 auto;
  color: var(--vert-clair);
  font-weight: 700;
  line-height: 1.5;
}

/* --- Types de projets --- */

/* Liste à puces, PAS des tuiles.
   Première version : encadrés à fond et coins arrondis — ils avaient tous les
   signaux d'un bouton alors que rien n'est cliquable. Un faux repère pour le
   visiteur, qui essaie de cliquer et ne se passe rien. Une liste annonce ce
   qu'elle est : une énumération. */
.projets {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .7rem 2.5rem;
}
@media (min-width: 620px) { .projets { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .projets { grid-template-columns: 1fr 1fr 1fr; } }

.projets li {
  position: relative;
  padding-left: 1.2rem;
  font-size: 1rem; line-height: 1.55;
  color: rgba(242, 245, 243, .84);
}
.projets li::before {
  content: ""; position: absolute; left: 0; top: .66em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--vert-clair);
}

/* --- Note discrète (précisions réglementaires, nuances) --- */

.svc__note {
  margin: 1.25rem 0 0;
  padding-left: 1rem;
  border-left: 2px solid rgba(62, 212, 122, .45);
  font-size: .92rem; line-height: 1.6;
  color: var(--gris);
}

/* --- Appel à l'action de fin de page --- */

.svc__cta {
  margin-top: clamp(3rem, 7vw, 5rem);
  border-top: 1px solid rgba(255, 255, 255, .1);
  padding-top: clamp(2.5rem, 6vw, 3.5rem);
  text-align: center;
}

.svc__cta p {
  margin: 0 auto 1.9rem;
  max-width: 34ch;
  font-size: clamp(1.15rem, 1rem + .7vw, 1.5rem);
  font-weight: 500; line-height: 1.35; letter-spacing: -.01em;
  color: var(--blanc);
}

/* Liens croisés entre services. Remplacent, sur ordinateur, le saut direct
   qu'offrait le burger — et améliorent le maillage interne pour le
   référencement, ce que le burger ne faisait pas. */
.voir-aussi {
  margin-top: clamp(3rem, 7vw, 4.5rem);
  border-top: 1px solid rgba(255, 255, 255, .1);
  padding-top: clamp(2rem, 5vw, 2.75rem);
}

.voir-aussi__liste {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .7rem;
}
@media (min-width: 760px) {
  .voir-aussi__liste { grid-template-columns: repeat(3, 1fr); }
}

.voir-aussi__liste a {
  display: flex; align-items: baseline; gap: .7rem;
  height: 100%;
  background: var(--ink-2);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 8px;
  padding: 1.05rem 1.25rem;
  font-size: .98rem; font-weight: 600; line-height: 1.35;
  color: rgba(242, 245, 243, .88);
  transition: border-color .25s var(--ease), color .25s var(--ease),
              background-color .25s var(--ease);
}
.voir-aussi__liste a:hover {
  border-color: rgba(62, 212, 122, .5);
  background: var(--ink-3);
  color: var(--blanc);
}
.voir-aussi__no {
  flex: 0 0 auto;
  font-size: .74rem; font-weight: 600; letter-spacing: .12em;
  color: var(--vert-clair);
}

/* Le raccourci vers la page Réalisations, posé sous les 3 catégories.

   ⚠️ `grid-column: 1 / -1` n'est PAS cosmétique : la liste est en 3 colonnes,
   donc sans ça ce 4e élément resterait seul dans la première colonne d'une
   deuxième rangée et se lirait comme une catégorie orpheline. En pleine
   largeur, il se lit pour ce qu'il est : une sortie vers autre chose.

   Fond transparent plutôt que `--ink-2` : même dessin que les catégories,
   mais clairement d'un autre ordre. */
.voir-aussi__tout { grid-column: 1 / -1; }
.voir-aussi__tout a {
  justify-content: center;
  background: transparent;
  color: var(--vert-clair);
}
.voir-aussi__tout a:hover {
  background: var(--ink-2);
  color: var(--blanc);
}
.voir-aussi__fleche {
  flex: 0 0 auto;
  transition: transform .25s var(--ease);
}
.voir-aussi__tout a:hover .voir-aussi__fleche { transform: translateX(3px); }

.svc__retour {
  display: inline-flex; align-items: center; gap: .5rem;
  margin-top: clamp(2.5rem, 6vw, 3.5rem);
  font-size: .78rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--gris);
  transition: color .25s var(--ease);
}
.svc__retour:hover { color: var(--vert-clair); }
.svc__retour span { transition: transform .3s var(--ease); }
.svc__retour:hover span { transform: translateX(-4px); }

/* ==========================================================================
   Lecteur YouTube à chargement différé (« click-to-play »)

   Aucune <iframe> n'est posée dans le HTML : ce sont des centaines de Ko de
   scripts tiers PAR vidéo, sur un site qui charge déjà 126 Mo de vidéo à la
   demande. On affiche une vignette + un bouton ; main.js remplace le tout
   par le lecteur au premier clic seulement.
   ========================================================================== */

.yt {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--ink-3);
  border-radius: 10px;
  overflow: hidden;
}

.yt iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.yt__btn {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  padding: 0; border: 0; background: none; cursor: pointer;
}

.yt__vignette {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .5s var(--ease), opacity .3s var(--ease);
}
.yt__btn:hover .yt__vignette { transform: scale(1.03); opacity: .82; }

/* Centrage en absolu, PAS par une grille sur le bouton.
   Le bouton contient un <picture> dont les éléments internes créaient une
   rangée fantôme de hauteur nulle : la grille se retrouvait avec deux
   rangées et le bouton de lecture, centré dans la seconde, tombait 104 px
   sous le centre de l'image. Mesuré, pas supposé — `grid-template-rows`
   valait « 208.594px 274.594px ». Le positionnement absolu ne dépend
   d'aucun élément voisin.
   ⚠️ Si l'échelle au survol change, garder le translate DANS le transform,
   sinon il écrase le centrage. */
.yt__play {
  position: absolute; z-index: 2;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 66px; height: 66px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(7, 9, 8, .62);
  border: 1px solid rgba(255, 255, 255, .55);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  transition: background-color .3s var(--ease), transform .3s var(--ease),
              border-color .3s var(--ease);
}
.yt__btn:hover .yt__play {
  background: var(--vert); border-color: var(--vert);
  transform: translate(-50%, -50%) scale(1.07);
}
.yt__play svg { width: 22px; height: 22px; fill: var(--blanc); margin-left: 3px; }
.yt__btn:hover .yt__play svg { fill: #04140A; }

/* État d'attente : la structure est en place, l'identifiant YouTube manque.
   Se veut visiblement volontaire, pas cassé. */
.yt--attente {
  display: grid; place-items: center;
  border: 1px dashed rgba(255, 255, 255, .2);
  background: var(--ink-2);
}
.yt--attente span {
  font-size: .8rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gris-fonce);
  text-align: center; padding: 0 1rem;
}

/* ==========================================================================
   Réalisations — grille, étiquettes et filtres
   ========================================================================== */

/* Flex plutôt que grid, pour une raison précise : une grille laisse la
   dernière rangée incomplète collée à gauche, ce qui se lit comme un trou.
   En flex centré, une rangée partielle se centre et paraît voulue. Le nombre
   de réalisations peut donc varier librement — 4, 5, 7, 10 — sans jamais
   obliger à retirer un vrai projet pour « faire carré ». */
.reals {
  --gap-reals: clamp(1.25rem, 3vw, 2rem);
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--gap-reals);
}

.reals > li { flex: 0 1 100%; }

@media (min-width: 680px) {
  .reals > li { flex-basis: calc((100% - var(--gap-reals)) / 2); }
}
@media (min-width: 1080px) {
  .reals--trois > li {
    flex-basis: calc((100% - 2 * var(--gap-reals)) / 3);
  }
}

/* Formats courts : la vidéo est verticale, la vignette aussi. Des tuiles
   étroites, sinon un 9:16 large devient démesurément haut. */
.reals--courts > li { flex: 0 1 clamp(150px, 30%, 230px); }
.yt--vertical { aspect-ratio: 9 / 16; }
.yt--vertical .yt__play { width: 52px; height: 52px; }
.yt--vertical .yt__play svg { width: 18px; height: 18px; }

/* ==========================================================================
   Photos

   La grille reprend `.reals` : mêmes colonnes, mêmes gouttières, pour que la
   page des photos respire comme celle des vidéos. Seule la tuile diffère,
   puisqu'il n'y a rien à cliquer.

   ⚠️ `.photo__cadre` est un <span> avec `display: block`, pas un <div> :
   il vit à l'intérieur d'un <figure>, et un <div> autour d'un <picture>
   passe encore, mais le <span> évite toute surprise d'imbrication. C'est lui
   qui porte le 16/9 et le rognage, jamais l'image elle-même.
   ========================================================================== */

.photo figure { margin: 0; }

.photo__btn {
  display: block; width: 100%;
  padding: 0; border: 0; background: none;
  cursor: zoom-in;
  border-radius: 10px;
}
.photo__btn:focus-visible {
  outline: 2px solid var(--vert-clair);
  outline-offset: 3px;
}
/* Le zoom se fait sur l'IMAGE, à l'intérieur du cadre qui masque le
   débordement. Agrandir le cadre lui-même ferait bouger la grille. */
.photo__btn img { transition: transform .45s var(--ease); }
.photo__btn:hover img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .photo__btn img { transition: none; }
  .photo__btn:hover img { transform: none; }
}

.photo__cadre {
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  overflow: hidden;
  background: var(--ink-3);
}

/* `object-fit: cover` fait le travail de recadrage à l'affichage, mais les
   fichiers sont DÉJÀ en 16/9 : c'est une ceinture de sécurité, pas le
   mécanisme principal. Si une photo était un jour remplacée par un fichier
   d'un autre format, elle serait rognée plutôt que déformée. */
.photo__cadre img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
}

.photo__legende {
  margin: .7rem 0 0;
  font-size: .92rem; font-weight: 500; line-height: 1.35;
  color: rgba(242, 245, 243, .82);
}

/* ==========================================================================
   Visionneuse (clic sur une photo pour l'agrandir)

   Le balisage est construit par main.js à la première ouverture : inutile de
   le poser dans le HTML de toutes les pages alors qu'une seule s'en sert.

   ⚠️ `position: fixed` + `inset: 0`, PAS de hauteur en `vh` : sur mobile, la
   barre d'adresse qui se rétracte fausse le `vh` et laisse une bande vide.
   ========================================================================== */

.visionneuse {
  position: fixed; inset: 0; z-index: 90;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 1rem;
  padding: clamp(1rem, 4vw, 3rem);
  /* Presque opaque : à .94 la barre de navigation transparaissait encore
     derrière et parasitait la photo. */
  background: rgba(4, 6, 5, .97);
}

/* ⚠️ L'attribut `hidden` est le SEUL interrupteur. `display: none` doit donc
   l'emporter sur le `display: flex` ci-dessus.

   ⚠️⚠️ AUCUNE ANIMATION D'OPACITÉ ICI, ET C'EST VOULU. Une première version
   ouvrait la visionneuse par un fondu `opacity: 0 -> 1` piloté en JavaScript.
   Mesure à l'appui : 900 ms après l'ouverture, l'opacité calculée valait
   encore 0. Une visionneuse invisible ET étendue sur tout l'écran avale
   chaque clic sans que rien ne se voie. C'est exactement ce qui était arrivé
   au menu burger. La règle du projet tient : on anime `transform`, jamais la
   visibilité. */
.visionneuse[hidden] { display: none; }

/* Le fondu se fait sur l'IMAGE, par une mise à l'échelle. Si l'animation ne
   joue pas, l'image est simplement là : rien ne peut rester coincé. */
@keyframes photo-apparait {
  from { transform: scale(.985); }
  to   { transform: none; }
}

/* L'image ne doit jamais déborder, ni en largeur ni en hauteur : les deux
   contraintes sont nécessaires, une photo very large et une photo très haute
   ne se limitent pas de la même façon. */
.visionneuse__image {
  max-width: 100%;
  max-height: calc(100% - 5rem);
  width: auto; height: auto;
  object-fit: contain;
  border-radius: 8px;
  animation: photo-apparait .25s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .visionneuse__image { animation: none; }
}

.visionneuse__legende {
  margin: 0;
  font-size: .95rem; font-weight: 500;
  color: rgba(242, 245, 243, .9);
  text-align: center;
}
.visionneuse__compte {
  margin-left: .6rem;
  font-size: .8rem; letter-spacing: .1em;
  color: var(--gris-fonce);
}

.visionneuse__bouton {
  position: absolute;
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px;
  padding: 0; border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 50%;
  background: rgba(0, 0, 0, .45);
  color: var(--blanc);
  cursor: pointer;
  transition: background-color .2s var(--ease), border-color .2s var(--ease);
}
.visionneuse__bouton:hover {
  background: rgba(0, 0, 0, .8);
  border-color: rgba(62, 212, 122, .55);
}
.visionneuse__bouton:focus-visible {
  outline: 2px solid var(--vert-clair);
  outline-offset: 2px;
}
.visionneuse__bouton svg { width: 22px; height: 22px; }

.visionneuse__fermer { top: clamp(.75rem, 3vw, 1.5rem); right: clamp(.75rem, 3vw, 1.5rem); }
.visionneuse__prec   { left:  clamp(.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }
.visionneuse__suiv   { right: clamp(.5rem, 2vw, 1.5rem); top: 50%; transform: translateY(-50%); }

/* Sur petit écran les flèches passeraient par-dessus la photo : on les
   descend au niveau de la légende, en ligne. */
@media (max-width: 560px) {
  .visionneuse__prec, .visionneuse__suiv { top: auto; bottom: 1rem; transform: none; }
}

/* Le défilement de la page est bloqué pendant l'ouverture. */
body.visionneuse-ouverte { overflow: hidden; }

.real__titre {
  margin: .9rem 0 .35rem;
  font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em;
  line-height: 1.3;
}

.real__etiquettes {
  margin: 0;
  font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gris-fonce);
}

/* Client qui revient. Une grille de trois vignettes quasi identiques ne dit
   pas « il me reprend chaque année » — elle donne l'impression d'un doublon.
   Une ligne de texte le dit, sans coûter de place ni diluer la variété des
   types d'événements montrés à côté. */
.real__reprise {
  margin: .5rem 0 0;
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .78rem; font-weight: 500;
  color: var(--vert-clair);
}
.real__reprise::before {
  content: "↻";
  font-size: .95rem; line-height: 1;
}

/* Projet unique mis en avant : la vidéo prend toute la largeur, le texte
   d'explication vient dessous. */
.projet-unique__titre {
  margin: 0 0 1.25rem;
  font-size: clamp(1.2rem, 1rem + .8vw, 1.6rem);
  font-weight: 600; letter-spacing: -.015em; line-height: 1.25;
}
/* Mesure élargie : sous une vidéo pleine largeur, un paragraphe étroit
   laisse un grand vide à droite et donne l'impression d'un texte « collé à
   gauche ». 74 caractères restent confortables à lire tout en équilibrant
   le bloc avec l'image au-dessus. */
.projet-unique__texte {
  margin: 1.5rem 0 0;
  max-width: 74ch;
  font-size: 1.02rem; line-height: 1.7;
  color: rgba(242, 245, 243, .84);
}

/* --- Filtres --- */

.filtres {
  display: flex; flex-wrap: wrap; gap: .55rem;
  margin: 0 0 clamp(1.75rem, 4vw, 2.5rem);
}

.filtre {
  font-family: inherit;
  font-size: .76rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  padding: .6rem 1.1rem; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .2);
  background: none; color: rgba(242, 245, 243, .78);
  cursor: pointer;
  transition: background-color .25s var(--ease), border-color .25s var(--ease),
              color .25s var(--ease);
}
.filtre:hover { border-color: rgba(255, 255, 255, .5); color: var(--blanc); }
.filtre[aria-pressed="true"] {
  background: var(--vert); border-color: var(--vert); color: #04140A;
}

.filtres__compte {
  margin: -1rem 0 clamp(1.75rem, 4vw, 2.5rem);
  font-size: .8rem; color: var(--gris-fonce);
}

/* ==========================================================================
   Invitation vers le portfolio, après les heroes de l'accueil
   ========================================================================== */

.portfolio {
  background: var(--ink-2);
  border-top: 1px solid rgba(255, 255, 255, .07);
  padding: clamp(4rem, 10vw, 7rem) clamp(1.25rem, 5vw, 3rem);
  text-align: center;
}

.portfolio__surtitre {
  margin: 0 0 1.1rem;
  font-size: .74rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--vert-clair);
}
.portfolio__texte {
  margin: 0 auto 2.2rem;
  max-width: 48ch;
  font-size: clamp(1.1rem, 1rem + .6vw, 1.4rem);
  font-weight: 500; line-height: 1.45; letter-spacing: -.01em;
  color: var(--blanc);
}

/* Deux volets côte à côte, un par destination. Ils s'empilent sous 820 px de
   place disponible, grâce au `flex-basis` généreux et à `flex-wrap`. */
.portfolio__duo {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(2rem, 5vw, 4rem);
  max-width: 980px; margin: 0 auto;
}
.portfolio__volet {
  flex: 1 1 340px; max-width: 440px;
  display: flex; flex-direction: column; align-items: center;
  gap: 1.1rem;
}

.portfolio__etiquette {
  margin: 0;
  font-size: .72rem; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--gris-fonce);
}

/* Trois vignettes en avant-goût. */
.portfolio__apercu {
  list-style: none; margin: 0; padding: 0; width: 100%;
  display: flex; justify-content: center;
  gap: clamp(.4rem, 1.2vw, .7rem);
}
/* `flex: 1 1 0` + `min-width: 0` : les trois se partagent la rangée à toutes
   les largeurs. Avec une base en pixels, elles passaient à 2 + 1 sur
   téléphone, et une vignette orpheline se remarque. */
.portfolio__apercu li { flex: 1 1 0; min-width: 0; }
.portfolio__apercu a { display: block; position: relative; }
.portfolio__apercu img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 16 / 9; object-fit: cover;
  border-radius: 8px;
  opacity: .82;
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.portfolio__apercu a:hover img { opacity: 1; transform: translateY(-3px); }
@media (prefers-reduced-motion: reduce) {
  .portfolio__apercu img { transition: none; }
  .portfolio__apercu a:hover img { transform: none; }
}

/* La pastille de lecture distingue les vignettes vidéo des photos d'un coup
   d'œil. Centrage en absolu, comme pour `.yt__play` : une grille sur le lien
   décalerait la pastille dès que l'image a sa propre rangée. */
.portfolio__play {
  position: absolute; z-index: 2;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  border: 1px solid rgba(255, 255, 255, .35);
  pointer-events: none;
}
.portfolio__play svg { width: 13px; height: 13px; fill: var(--blanc); margin-left: 1px; }

/* ==========================================================================
   À propos

   Seul endroit du site où la mascotte a sa place : son style illustratif
   concurrencerait les images partout ailleurs, mais ici c'est le sujet.
   ========================================================================== */

.apropos {
  background: var(--ink);
  border-top: 1px solid rgba(255, 255, 255, .07);
  padding: clamp(4rem, 10vw, 7rem) clamp(1.25rem, 5vw, 3rem);
}

.apropos__inner {
  max-width: 68rem; margin: 0 auto;
  display: grid; gap: clamp(2.5rem, 6vw, 4.5rem);
  align-items: center;
}
@media (min-width: 900px) {
  .apropos__inner { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
}

.apropos__image {
  justify-self: center;
  max-width: 420px; width: 100%;
}
.apropos__image img {
  width: 100%; height: auto;
  filter: drop-shadow(0 18px 44px rgba(0, 0, 0, .55));
}

.apropos__surtitre {
  display: flex; align-items: center; gap: .8rem;
  margin: 0 0 1.1rem;
  font-size: .74rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--vert-clair);
}
.apropos__surtitre::after {
  content: ""; flex: 0 0 clamp(2rem, 6vw, 4rem);
  height: 1px; background: rgba(242, 245, 243, .25);
}

.apropos__titre {
  margin: 0 0 1.6rem;
  font-size: clamp(1.7rem, 1.2rem + 2.2vw, 2.6rem);
  font-weight: 600; line-height: 1.12; letter-spacing: -.025em;
}

.apropos__texte p {
  margin: 0 0 1.15rem;
  max-width: 58ch;
  font-size: clamp(1rem, .98rem + .25vw, 1.1rem);
  line-height: 1.7;
  color: rgba(242, 245, 243, .84);
}
.apropos__texte p:last-child { margin-bottom: 0; }

.apropos__signature {
  margin-top: 1.9rem;
  font-size: 1.05rem; font-weight: 600;
  color: var(--blanc);
}

/* Encart destiné aux gens du métier — boîtes de production, photographes.
   Volontairement distinct du reste : ce n'est pas le même lecteur ni la
   même demande qu'un client final. */
.collab {
  margin-top: 2.25rem;
  padding: 1.4rem 1.6rem;
  border-left: 2px solid var(--vert);
  background: rgba(0, 177, 64, .07);
  border-radius: 0 8px 8px 0;
}
.collab strong {
  display: block; margin-bottom: .5rem;
  font-size: 1.02rem; color: var(--blanc);
}
.apropos__texte .collab p {
  margin: 0;
  max-width: 54ch;
  font-size: .98rem; line-height: 1.65;
  color: rgba(242, 245, 243, .82);
}

/* ==========================================================================
   Contact / demande de soumission
   ========================================================================== */

.contact {
  background: var(--ink-2);
  border-top: 1px solid rgba(255, 255, 255, .07);
  padding: clamp(4rem, 10vw, 7rem) clamp(1.25rem, 5vw, 3rem);
}

.contact__inner {
  max-width: 62rem; margin: 0 auto;
  display: grid; gap: clamp(2.5rem, 6vw, 4rem);
}
@media (min-width: 880px) {
  .contact__inner { grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); }
}

.contact__intro p {
  margin: 0 0 1.1rem;
  max-width: 40ch;
  font-size: 1.02rem; line-height: 1.7;
  color: rgba(242, 245, 243, .84);
}

.coords {
  list-style: none; margin: 2.25rem 0 0; padding: 0;
  display: grid; gap: 1.05rem;
}
.coords li {
  display: grid; gap: .2rem;
  padding-top: 1.05rem;
  border-top: 1px solid rgba(255, 255, 255, .09);
}
.coords li:first-child { padding-top: 0; border-top: 0; }

.coords__etiquette {
  font-size: .72rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--gris-fonce);
}
.coords a,
.coords__valeur {
  font-size: 1.02rem; line-height: 1.5;
  color: rgba(242, 245, 243, .92);
}
.coords a {
  font-weight: 600;
  transition: color .25s var(--ease);
  word-break: break-word;
}
.coords a:hover { color: var(--vert-clair); }

/* --- champs --- */

.champ { display: block; margin-bottom: 1.25rem; }

.champ__etiquette {
  display: block; margin-bottom: .45rem;
  font-size: .78rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--gris);
}

.champ input,
.champ select,
.champ textarea {
  width: 100%;
  font-family: inherit; font-size: 1rem;
  color: var(--blanc);
  background: var(--ink);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 8px;
  padding: .85rem 1rem;
  transition: border-color .25s var(--ease), background-color .25s var(--ease);
}
.champ textarea { min-height: 150px; resize: vertical; line-height: 1.6; }

.champ input:focus,
.champ select:focus,
.champ textarea:focus {
  outline: none;
  border-color: var(--vert);
  background: var(--ink-3);
}

.champ select { appearance: none; cursor: pointer; }
/* La flèche du menu déroulant, dessinée en CSS pour rester cohérente
   d'un navigateur à l'autre. */
.champ--select { position: relative; }
.champ--select::after {
  content: ""; position: absolute; right: 1.1rem; bottom: 1.25rem;
  width: 8px; height: 8px;
  border-right: 2px solid var(--gris);
  border-bottom: 2px solid var(--gris);
  transform: rotate(45deg);
  pointer-events: none;
}

/* Piège à pourriels : invisible pour le visiteur, rempli par les robots.
   Le script refuse l'envoi si ce champ contient quoi que ce soit. */
.pot-de-miel {
  position: absolute; left: -9999px;
  width: 1px; height: 1px; overflow: hidden;
}

.contact__envoi { margin-top: 1.75rem; }

.contact__message {
  margin-top: 1.25rem;
  padding: 1rem 1.25rem;
  border-radius: 8px;
  font-size: .96rem; line-height: 1.6;
}
.contact__message--ok {
  background: rgba(0, 177, 64, .12);
  border: 1px solid rgba(62, 212, 122, .45);
  color: var(--vert-clair);
}
.contact__message--erreur {
  background: rgba(255, 90, 90, .1);
  border: 1px solid rgba(255, 120, 120, .45);
  color: #ffb3b3;
}

/* ==========================================================================
   Pied de page
   ========================================================================== */

.pied {
  background: var(--ink);
  border-top: 1px solid rgba(255, 255, 255, .09);
  padding: clamp(3rem, 7vw, 4.5rem) clamp(1.25rem, 5vw, 3rem) 2rem;
}

.pied__inner {
  max-width: 68rem; margin: 0 auto;
  display: grid; gap: clamp(2rem, 5vw, 3.5rem);
}
@media (min-width: 760px) {
  .pied__inner { grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 1fr)); }
}

.pied__logo { width: 150px; height: auto; margin-bottom: 1.1rem; }

.pied__phrase {
  margin: 0 0 1.4rem;
  max-width: 32ch;
  font-size: .95rem; line-height: 1.6;
  color: var(--gris);
}

.pied__titre {
  margin: 0 0 1rem;
  font-size: .74rem; font-weight: 600;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--gris-fonce);
}

.pied__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; }
.pied__liste a,
.pied__liste span {
  font-size: .95rem; line-height: 1.45;
  color: rgba(242, 245, 243, .82);
}
.pied__liste a { transition: color .25s var(--ease); }
.pied__liste a:hover { color: var(--vert-clair); }

.pied__social { display: flex; gap: 1.1rem; margin-top: 1.3rem; }
.pied__social a {
  color: var(--gris);
  transition: color .25s var(--ease), transform .25s var(--ease);
}
.pied__social a:hover { color: var(--vert-clair); transform: translateY(-2px); }
.pied__social svg { width: 20px; height: 20px; fill: currentColor; display: block; }

.pied__bas {
  max-width: 68rem; margin: clamp(2.5rem, 6vw, 3.5rem) auto 0;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, .07);
  display: flex; flex-wrap: wrap; gap: .5rem 1.5rem;
  justify-content: space-between;
  font-size: .82rem; color: var(--gris-fonce);
}

/* ==========================================================================
   Bande provisoire des 4 catégories (structure seulement, à remplacer)
   ========================================================================== */

.provisoire { padding: clamp(4rem, 9vw, 7.5rem) clamp(1.25rem, 5vw, 3rem); }

.provisoire__entete { max-width: 62rem; margin: 0 auto 3rem; }
.provisoire__surtitre {
  font-size: .74rem; letter-spacing: .26em; text-transform: uppercase;
  color: var(--vert); margin: 0 0 .9rem;
}
.provisoire__titre {
  font-size: clamp(1.9rem, 1.3rem + 2.4vw, 3rem);
  font-weight: 600; line-height: 1.15; letter-spacing: -.02em; margin: 0;
}
.provisoire__note {
  margin: 1rem 0 0; color: var(--gris); max-width: 56ch;
}

.grille { max-width: 62rem; margin: 0 auto; display: grid; gap: 1px; background: rgba(255,255,255,.08); }
@media (min-width: 720px) { .grille { grid-template-columns: 1fr 1fr; } }

.carte {
  background: var(--ink-2);
  padding: clamp(1.75rem, 3vw, 2.5rem);
  min-height: 190px;
  display: flex; flex-direction: column; justify-content: space-between;
  transition: background-color .35s var(--ease);
}
.carte:hover { background: var(--ink-3); }
.carte__no {
  font-size: .72rem; letter-spacing: .2em; color: var(--gris-fonce);
  margin: 0 0 1.5rem;
}
.carte__titre { font-size: 1.3rem; font-weight: 600; margin: 0 0 .5rem; letter-spacing: -.01em; }
.carte__desc { margin: 0 0 1.5rem; color: var(--gris); font-size: .95rem; }
.carte__lien {
  font-size: .78rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--vert-clair); display: inline-flex; align-items: center; gap: .5rem;
}
.carte__lien span { transition: transform .3s var(--ease); }
.carte:hover .carte__lien span { transform: translateX(4px); }

.chantier {
  max-width: 62rem; margin: 2.5rem auto 0;
  border: 1px dashed rgba(255,255,255,.18); border-radius: 8px;
  padding: 1.25rem 1.5rem; color: var(--gris); font-size: .9rem;
}
.chantier strong { color: var(--blanc); font-weight: 600; }

/* ==========================================================================
   Adaptations mobile
   ========================================================================== */

@media (max-width: 860px) {
  .nav__menu { display: none; }
  .nav__burger { display: inline-flex; }
}

/* Téléphone : on bascule sur le libellé court et on réduit un peu le logo.
   Le libellé complet reste dans le menu burger, où la place ne manque pas. */
@media (max-width: 620px) {
  .nav__cta-long  { display: none; }
  .nav__cta-court { display: inline; }
  .nav__cta { padding-inline: .9rem; }
  .nav__logo { height: 24px; }
  .nav { gap: .75rem; }
}

@media (max-width: 860px) {
  .hero__social { display: none; }
  .hero__logo { width: min(84vw, 420px); }

  /* Le voile latéral n'a plus de sens sur un écran étroit : le texte occupe
     toute la largeur, on assombrit donc seulement le bas. */
  .cat__scrim {
    background: linear-gradient(to top,
      rgba(0, 0, 0, .82) 0%, rgba(0, 0, 0, .30) 46%, rgba(0, 0, 0, 0) 72%);
  }
  .cat__desc { margin-bottom: 1.8rem; }
}

@media (max-width: 480px) {
  .hero__actions { flex-direction: column; width: 100%; max-width: 320px; }
  .btn { justify-content: center; width: 100%; }
  .hero__scroll { display: none; }
}

/* ==========================================================================
   Respect de « réduire les animations »
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  /* Les vidéos ne sont jamais lancées par le script dans ce mode :
     les posters fixes tiennent lieu de fond. */
  .hero__video,
  .cat__video { display: none; }
}
