/* ==========================================================================
   KEVIN KLEIN AVOCAT — Feuille de style principale
   Borgia — 2026
   --------------------------------------------------------------------------
   Sommaire
   01. Variables & jetons de design
   02. Réinitialisation & bases
   03. Typographie
   04. Mise en page & utilitaires
   05. Animations au défilement
   06. En-tête & navigation
   07. Section héro
   08. Sections éditoriales
   09. Champs de pratique
   10. Bio & portrait
   11. Section sombre / appel à l'action
   12. Formulaire
   13. Pied de page
   14. Adaptation mobile
   15. Accessibilité & mouvement réduit
   ========================================================================== */


/* 01. VARIABLES & JETONS DE DESIGN
   ========================================================================== */

:root {
  /* --- Palette : tons naturels --- */
  --creme:          #F7F4EE;
  --creme-clair:    #FBF9F5;
  --sable:          #EFE9DD;
  --beige:          #E3DACB;
  /* Le taupe d'origine (#A79B89) ne donnait que 2,49:1 sur le crème — très
     en dessous du seuil AA de 4,5:1. Il servait aux sur-titres, aux numéros
     et aux étiquettes, donc à du texte qu'on doit pouvoir lire. Assombri
     jusqu'à 5,04:1 sur crème et 4,57:1 sur sable, en gardant la teinte. */
  --taupe:          #736754;
  --taupe-clair:    #A79B89;   /* réservé au décoratif, jamais au texte */
  --taupe-fonce:    #6F6558;

  /* --- Accents sobres --- */
  --charbon:        #1B1917;  /* brun charbon — texte principal & fonds sombres */
  --charbon-doux:   #2A2724;
  --olive:          #57603F;  /* vert olive — accent principal */
  --olive-clair:    #6E784F;
  --terre-cuite:    #B0603C;  /* terre cuite — accent rare, jamais dominant */

  --blanc:          #FFFFFF;

  /* --- Rôles sémantiques --- */
  --fond:           var(--creme);
  --fond-alt:       var(--sable);
  --texte:          var(--charbon);
  --texte-doux:     var(--taupe-fonce);
  --texte-tenu:     var(--taupe);
  --trait:          rgba(27, 25, 23, 0.14);
  --trait-fort:     rgba(27, 25, 23, 0.28);
  /* Accent des liens actifs et du focus. L'olive est illisible sur le
     charbon (contraste 1,6:1) : le thème sombre le remplace par une terre
     cuite éclaircie, qui atteint 6:1. */
  --accent:         var(--olive);

  /* --- Typographie --- */
  --police-sans:  'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --police-serif: 'Newsreader', Georgia, 'Times New Roman', serif;

  /* Échelle fluide — se règle toute seule entre 360px et 1600px.

     Plancher de lisibilité tenu partout : aucun texte courant, libellé de
     bouton ou lien de navigation ne descend sous 16 px sur téléphone ni sous
     17 px sur ordinateur. Le 14-15 px est réservé aux éléments réellement
     secondaires — étiquettes en capitales, numérotation, mentions du pied de
     page. Rien en dessous de 14 px. */
  --t-xs:   clamp(0.875rem, 0.86rem + 0.07vw, 0.9375rem);   /* 14 → 15 px */
  --t-sm:   clamp(1rem, 0.98rem + 0.10vw, 1.0625rem);       /* 16 → 17 px */
  --t-base: clamp(1.0625rem, 1.03rem + 0.18vw, 1.1875rem);  /* 17 → 19 px */
  --t-md:   clamp(1.1875rem, 1.11rem + 0.35vw, 1.4375rem);  /* 19 → 23 px */
  --t-lg:   clamp(1.375rem, 1.2rem + 0.8vw, 2rem);
  --t-xl:   clamp(1.75rem, 1.35rem + 1.9vw, 3rem);
  --t-2xl:  clamp(2.25rem, 1.5rem + 3.4vw, 4.5rem);
  --t-3xl:  clamp(2.75rem, 1.3rem + 6.4vw, 7.5rem);

  /* --- Rythme vertical --- */
  --e-1: 0.5rem;
  --e-2: 1rem;
  --e-3: 1.5rem;
  --e-4: 2rem;
  --e-5: 3rem;
  --e-6: 4rem;
  --e-7: 6rem;
  --e-8: clamp(4rem, 9vw, 9rem);
  --e-9: clamp(6rem, 13vw, 13rem);

  /* --- Structure ---
     Marge latérale à 5 % de la largeur d'écran, plafonnée à 100 px : au-delà de
     2000 px de viewport, la marge se fige et le contenu se centre au lieu de
     s'étirer indéfiniment. En dessous, elle ne descend jamais sous 20 px pour
     que le texte ne colle pas au bord sur téléphone. */
  --marge-page: clamp(1.25rem, 5vw, 100px);
  --largeur-max: 2000px;
  --largeur-texte: 62ch;
  --hauteur-entete: 84px;

  /* --- Mouvement ---
     Règle de base : une animation d'interface reste sous 300 ms. Au-delà, elle
     se met en travers de l'utilisateur au lieu de l'accompagner. Seules les
     révélations au défilement, qui sont narratives, ont le droit d'être lentes.
     Jamais d'ease-in sur de l'interface : ça retarde l'instant précis que
     l'utilisateur regarde. */
  --sortie: cubic-bezier(0.22, 1, 0.36, 1);      /* décélération douce */
  --entree: cubic-bezier(0.65, 0, 0.35, 1);      /* symétrique */
  --vif:    cubic-bezier(0.16, 1, 0.3, 1);       /* révélations */

  --duree-pression: 140ms;   /* retour au clic */
  --duree-survol: 180ms;     /* survol */
  --duree-court: 0.24s;
  --duree-moyen: 0.6s;
  --duree-long: 1.1s;        /* révélations au défilement uniquement */

  --pas-cascade: 60ms;       /* décalage entre éléments d'un même groupe */
  --duree-fond: 550ms;       /* fondu du fond de page entre deux sections */
}


/* --- Thèmes de fond de page ---------------------------------------------
   Chaque thème redéfinit les rôles sémantiques. Comme les transitions portent
   sur la valeur calculée, changer la variable suffit à déclencher le fondu. */

body[data-fond="sable"] {
  --fond: var(--sable);
}

body[data-fond="charbon"] {
  --accent:     #C87A52;
  --fond:       var(--charbon);
  --texte:      var(--creme);
  --texte-doux: rgba(247, 244, 238, 0.72);
  --texte-tenu: rgba(247, 244, 238, 0.68);
  --trait:      rgba(247, 244, 238, 0.16);
  --trait-fort: rgba(247, 244, 238, 0.32);
}


/* 02. RÉINITIALISATION & BASES
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* --- Fond de page qui glisse d'une section à l'autre ---------------------
   La couleur n'est plus peinte par chaque section mais par la page entière.
   main.js pose data-fond sur <body> selon la section traversée, et la
   transition fait le fondu. Les sections deviennent transparentes.

   Le basculement est déclenché tôt — quand le haut de la section atteint le
   dernier tiers de l'écran — pour que le fond soit déjà en place avant que le
   texte de la section n'arrive vraiment en vue. Sinon on lirait du texte clair
   sur un fond encore clair pendant une demi-seconde. */

body {
  margin: 0;
  background-color: var(--fond);
  color: var(--texte);
  transition: background-color var(--duree-fond) var(--sortie),
              color var(--duree-fond) var(--sortie);
  font-family: var(--police-sans);
  font-size: var(--t-base);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Verrouille le défilement quand le menu mobile est ouvert */
body.menu-ouvert { overflow: hidden; }

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

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

a { color: inherit; }

::selection {
  background: var(--charbon);
  color: var(--creme);
}


/* 03. TYPOGRAPHIE
   ========================================================================== */

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

p { margin: 0; }

/* --- Titres d'affichage --- */
.titre-geant {
  font-size: var(--t-3xl);
  font-weight: 700;
  line-height: 0.92;
  letter-spacing: -0.045em;
}

.titre-grand {
  font-size: var(--t-2xl);
  font-weight: 600;
  line-height: 1.0;
  letter-spacing: -0.04em;
}

.titre-moyen {
  font-size: var(--t-xl);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.titre-petit {
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.025em;
}

/* --- Texte éditorial en serif ---
   Newsreader est dessinée pour la lecture à l'écran, mais elle était employée
   ici en Light (300). Un poids maigre sur du texte courant réduit l'épaisseur
   des jambages et pénalise nettement les personnes malvoyantes, ainsi que
   toute lecture sur écran non-Retina : le contraste mesuré reste bon, mais le
   contraste PERÇU s'effondre.

   Le texte courant est donc en 400. Les poids maigres ne subsistent que sur
   les très grands énoncés, où l'épaisseur de trait absolue reste suffisante. */
.texte-editorial {
  font-family: var(--police-serif);
  font-size: var(--t-md);
  font-weight: 400;
  line-height: 1.58;
  letter-spacing: -0.008em;
  color: var(--texte);
}

.texte-doux { color: var(--texte-doux); }

.mesure { max-width: var(--largeur-texte); }
.mesure-large { max-width: 78ch; }

/* --- Sur-titre / étiquette de section --- */
.surtitre {
  display: flex;
  align-items: baseline;
  gap: 0.75em;
  margin: 0 0 var(--e-4);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-tenu);
}

/* Numérotation discrète des sections */
.surtitre .num {
  font-variant-numeric: tabular-nums;
  color: var(--taupe);
}

/* Mot mis en relief dans un titre.
   Réservé aux mots qui nomment la situation du visiteur — accusé, arrêté,
   détenue. Jamais sur de la ponctuation : colorer un « ? » n'ajoute aucun sens.
   La terre cuite reste un accent rare : deux ou trois mots par page, pas plus. */
.accent-mot { color: var(--terre-cuite); }


/* 04. MISE EN PAGE & UTILITAIRES
   ========================================================================== */

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

.section {
  padding-block: var(--e-8);
}

.section--serree { padding-block: var(--e-6); }
.section--ample  { padding-block: var(--e-9); }

/* Le fond est porté par <body> (voir « Thèmes de fond de page »).
   Cette classe ne sert plus qu'à déclarer le thème dans le HTML. */
.section--sable { background: transparent; }

/* Filet de séparation fin */
.filet {
  height: 1px;
  border: 0;
  margin: 0;
  background: var(--trait);
}

/* Grille éditoriale à deux colonnes : titre à gauche, texte à droite */
.duo {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 6vw, 7rem);
  align-items: start;
}

.duo--inverse { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }

/* Assoit les deux colonnes sur la même ligne de base plutôt que de les aligner
   par le haut. Sur une rangée titre + texte, les deux blocs n'ont jamais la
   même hauteur : les caler en bas donne un appui commun, beaucoup plus
   équilibré qu'un alignement haut qui laisse un vide sous le plus court. */
.duo--bas { align-items: end; }

/* En colonne unique, l'alignement n'a plus de sens */
@media (max-width: 900px) {
  .duo--bas { align-items: start; }
}

.duo__colonne-collante {
  position: sticky;
  top: calc(var(--hauteur-entete) + var(--e-4));
}

.pile   { display: grid; gap: var(--e-3); }
.pile-4 { display: grid; gap: var(--e-4); }
.pile-5 { display: grid; gap: var(--e-5); }

/* --- Bouton --- */
.bouton {
  /* Se déduit du thème : charbon sur crème en section claire,
     crème sur charbon en section sombre. Aucune variante à gérer. */
  --bouton-fond: var(--texte);
  --bouton-texte: var(--fond);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7em;
  padding: 1.05em 1.9em;
  border: 1px solid var(--bouton-fond);
  border-radius: 999px;
  background: var(--bouton-fond);
  color: var(--bouton-texte);
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--duree-survol) var(--sortie),
              border-color var(--duree-survol) var(--sortie),
              transform var(--duree-pression) var(--sortie);
}

/* Remplissage qui monte au survol */
.bouton::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--olive);
  transform: translateY(101%);
  transition: transform var(--duree-survol) var(--sortie);
}

/* Le mouvement au survol est réservé aux vrais pointeurs : sur écran tactile,
   un simple appui déclenche un faux survol qui reste collé. */
@media (hover: hover) and (pointer: fine) {
  .bouton:hover::after { transform: translateY(0); }
  .bouton:hover { color: var(--creme); border-color: var(--olive); }
  .bouton:hover .fleche { transform: translateX(0.25em); }
}

.bouton:focus-visible::after { transform: translateY(0); }
.bouton:focus-visible { color: var(--creme); border-color: var(--olive); }

/* Retour au clic : rien de plus convaincant qu'un enfoncement franc et bref. */
.bouton:active { transform: scale(0.97); }

.bouton .fleche {
  transition: transform var(--duree-survol) var(--sortie);
}

/* Variante contour */
.bouton--contour {
  --bouton-fond: transparent;
  --bouton-texte: var(--texte);
  border-color: var(--trait-fort);
}

.bouton--contour:hover,
.bouton--contour:focus-visible { border-color: var(--olive); }

/* Variante claire, pour les fonds sombres */
/* .bouton--clair n'a plus lieu d'être : le thème inverse déjà le bouton.
   La classe est conservée dans le HTML sans effet propre. */
.bouton--clair { --bouton-fond: var(--texte); --bouton-texte: var(--fond); }

.bouton--clair::after { background: var(--terre-cuite); }

/* --- Lien souligné animé --- */
.lien {
  position: relative;
  display: inline-block;
  color: inherit;
  text-decoration: none;
  padding-bottom: 0.12em;
}

.lien::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(1);
  transform-origin: right;
  transition: transform var(--duree-survol) var(--sortie);
}

.lien:hover::after,
.lien:focus-visible::after {
  transform: scaleX(0);
}

/* Lien avec flèche, style « en savoir plus » */
.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  color: var(--texte);
}

.lien-fleche svg { transition: transform var(--duree-survol) var(--sortie); }
.lien-fleche:hover svg { transform: translateX(0.3em); }

.lien-fleche span {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-position: left bottom;
  background-repeat: no-repeat;
  transition: background-size var(--duree-survol) var(--sortie);
  padding-bottom: 0.15em;
}

.lien-fleche:hover span { background-size: 100% 1px; }

/* --- Logo (masque : recolorable via currentColor) --- */
.logo-marque {
  /* display:block indispensable : un <span> inline ignore width/height */
  display: block;
  width: 100%;
  height: 100%;
  background-color: currentColor;
  -webkit-mask-image: url('../img/logo-kk.png');
  mask-image: url('../img/logo-kk.png');
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}


/* 05. ANIMATIONS AU DÉFILEMENT
   ========================================================================== */

/* État initial — retiré par main.js dès que l'élément entre dans l'écran.
   La classe .js-anim n'est posée sur <html> que si le JS tourne, pour que
   le contenu reste visible si le script échoue. */

.js-anim [data-anim] {
  opacity: 0;
  will-change: opacity, transform;
}

.js-anim [data-anim="monte"]   { transform: translateY(2.5rem); }
.js-anim [data-anim="fondu"]   { transform: none; }
.js-anim [data-anim="glisse"]  { transform: translateX(-2rem); }
.js-anim [data-anim="echelle"] { transform: scale(0.96); }

.js-anim [data-anim].est-visible {
  opacity: 1;
  transform: none;
  transition: opacity var(--duree-long) var(--vif),
              transform var(--duree-long) var(--vif);
  transition-delay: var(--retard, 0ms);
}

/* --- Révélation ligne par ligne (héro) --- */
/* Le masque rogne au-dessus et en dessous de la ligne. En français, il faut
   laisser passer les accents (É, À, ê) en haut et les jambages (p, q, g) en
   bas : on ouvre la zone visible par du padding, qu'on annule en marge pour
   ne pas décaler la mise en page. */
.ligne-masque {
  display: block;
  overflow: hidden;
  padding-top: 0.2em;
  margin-top: -0.2em;
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}

.ligne-masque > span {
  display: block;
  /* 130% et non 105% : la ligne doit sortir sous le padding, sinon un
     liseré de texte reste visible avant l'animation. */
  transform: translateY(130%);
}

.js-anim .ligne-masque > span {
  transition: transform 1.05s var(--vif);
  transition-delay: var(--retard, 0ms);
}

.est-visible .ligne-masque > span,
.ligne-masque.est-visible > span { transform: translateY(0); }

/* Sans JS, tout est visible d'emblée */
html:not(.js-anim) .ligne-masque > span { transform: none; }

/* --- Trait qui se déploie --- */
.js-anim .trait-anime {
  transform: scaleX(0);
  transform-origin: left;
}

.js-anim .trait-anime.est-visible {
  transform: scaleX(1);
  transition: transform 1s var(--vif);
  transition-delay: var(--retard, 0ms);
}


/* 06. EN-TÊTE & NAVIGATION
   ========================================================================== */

.entete {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--hauteur-entete);
  display: flex;
  align-items: center;
  transition: background-color var(--duree-court) var(--sortie),
              box-shadow 0.45s var(--sortie),
              transform 0.5s var(--sortie);
}

/* Fond qui apparaît au défilement */
.entete::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--fond);
  border-bottom: 1px solid var(--trait);
  opacity: 0;
  transition: background-color var(--duree-fond) var(--sortie),
              border-color var(--duree-fond) var(--sortie), opacity 0.24s var(--sortie);
  transition: opacity var(--duree-court) var(--sortie);
}

.entete.est-detachee::before { opacity: 1; }

/* Masque l'en-tête quand on descend, la ramène quand on remonte */
.entete.est-cachee { transform: translateY(-100%); }

.entete__interieur {
  width: 100%;
  max-width: var(--largeur-max);
  margin-inline: auto;
  padding-inline: var(--marge-page);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
}

/* --- Bloc-marque --- */
.marque {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
  color: var(--texte);
}

.marque__symbole {
  width: 34px;
  height: 40px;
  flex: none;
  color: var(--charbon);
  transition: color var(--duree-court) var(--sortie);
}

.marque__texte {
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  line-height: 1;
}

.marque__nom {
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  white-space: nowrap;
}

.marque__role {
  /* 14 px : plancher absolu du site. L'interlettrage est réduit en compensation
     pour que le bloc-marque ne devienne pas plus large que le nom au-dessus. */
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--texte-tenu);
  white-space: nowrap;
}

/* --- Navigation bureau --- */
.nav {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
}

.nav__lien {
  position: relative;
  font-size: var(--t-sm);
  font-weight: 500;
  text-decoration: none;
  color: var(--texte);
  padding-block: 0.4em;
  white-space: nowrap;
}

.nav__lien::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duree-survol) var(--sortie);
}

.nav__lien:hover::after,
.nav__lien:focus-visible::after { transform: scaleX(1); }

.nav__lien[aria-current="page"] { color: var(--accent); }
.nav__lien[aria-current="page"]::after {
  transform: scaleX(1);
  background: var(--accent);
}

.entete__actions {
  display: flex;
  align-items: center;
  gap: var(--e-3);
}

/* --- Sélecteur de langue --- */
.langue {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0.06em;
}

.langue__option {
  padding: 0.35em 0.5em;
  text-decoration: none;
  color: var(--texte-tenu);
  border-radius: 4px;
  transition: color var(--duree-court) var(--sortie);
}

.langue__option:hover { color: var(--texte); }

.langue__option[aria-current="true"] {
  color: var(--texte);
  font-weight: 600;
}

.langue__separateur { color: var(--trait-fort); }

/* --- Bouton menu mobile --- */
.bascule-menu {
  display: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  align-items: center;
  justify-content: center;
}

.bascule-menu__barres {
  position: relative;
  width: 22px;
  height: 10px;
}

.bascule-menu__barres span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1.5px;
  background: var(--texte);
  transition: transform var(--duree-survol) var(--sortie), opacity 0.15s linear;
}

.bascule-menu__barres span:nth-child(1) { top: 0; }
.bascule-menu__barres span:nth-child(2) { bottom: 0; }

.bascule-menu[aria-expanded="true"] .bascule-menu__barres span:nth-child(1) {
  transform: translateY(4.25px) rotate(45deg);
}

.bascule-menu[aria-expanded="true"] .bascule-menu__barres span:nth-child(2) {
  transform: translateY(-4.25px) rotate(-45deg);
}

/* --- Panneau mobile --- */
.panneau-mobile {
  position: fixed;
  inset: 0;
  z-index: 99;
  /* Suit le thème : en crème figé, le texte du thème sombre devenait
     invisible sur ce fond. */
  background: var(--fond);
  padding: calc(var(--hauteur-entete) + var(--e-4)) var(--marge-page) var(--e-5);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--e-5);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-1.5rem);
  transition: opacity 0.4s var(--sortie),
              transform 0.5s var(--vif),
              visibility 0s linear 0.5s;
}

.panneau-mobile.est-ouvert {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition-delay: 0s;
}

.panneau-mobile__nav {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
}

.panneau-mobile__lien {
  font-size: clamp(1.75rem, 8vw, 2.5rem);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.15;
  text-decoration: none;
  color: var(--texte);
  padding-block: 0.35em;
  border-bottom: 1px solid var(--trait);
  opacity: 0;
  transform: translateY(1rem);
}

.panneau-mobile.est-ouvert .panneau-mobile__lien {
  opacity: 1;
  transform: none;
  transition: opacity 0.3s var(--sortie), transform 0.4s var(--sortie);
  transition-delay: calc(0.12s + var(--i, 0) * 0.06s);
}

.panneau-mobile__lien[aria-current="page"] { color: var(--accent); }

.panneau-mobile__pied {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  font-size: var(--t-sm);
  color: var(--texte-doux);
}

/* L'en-tête reste au-dessus du panneau (z-index 100 > 99) : son sélecteur de
   langue demeure visible et cliquable. Celui du panneau ferait doublon. */
.panneau-mobile__pied .langue { display: none; }


/* 07. SECTION HÉRO
   ========================================================================== */

.hero {
  position: relative;
  min-height: min(100svh, 900px);
  display: flex;
  align-items: flex-end;
  padding-top: calc(var(--hauteur-entete) + var(--e-6));
  padding-bottom: var(--e-6);
  overflow: hidden;
}

/* Dégradé très léger, donne de la profondeur sans image.
   Sert de repli tant que la photo n'est pas chargée. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(120% 80% at 78% 12%, var(--sable) 0%, transparent 62%),
    radial-gradient(90% 70% at 8% 95%, var(--beige) 0%, transparent 58%);
  opacity: 0.85;
}

/* --- Photo de fond du héro --- */

.hero__photo {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}

.hero__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 38%;

  /* Même traitement que le bandeau ville : la photo d'origine a un ciel bleu
     saturé qui jure avec les tons naturels. On la désature et on la réchauffe
     pour qu'elle devienne une texture, pas une image couleur.
     Pour revenir à la photo brute : retirer filter et .hero__voile. */
  filter: grayscale(0.86) sepia(0.24) contrast(1.04) brightness(0.96);

  /* Léger recul à l'arrivée, une seule fois */
  transform: scale(1.05);
  transition: transform 1.6s var(--sortie);
}

.hero.est-visible .hero__photo img { transform: scale(1); }

/* Voile crème : la typographie doit rester lisible en noir par-dessus.
   C'est le voile qui fait tout le travail de contraste, pas la photo. */
.hero__voile {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    /* Vertical : ne masque que les bords, pour fondre sous l'en-tête et vers
       la section suivante. Transparent au centre, sinon tout serait délavé. */
    linear-gradient(180deg,
      rgba(247, 244, 238, 0.88) 0%,
      rgba(247, 244, 238, 0) 26%,
      rgba(247, 244, 238, 0) 58%,
      rgba(247, 244, 238, 1) 100%),
    /* Horizontal : c'est lui qui protège la lisibilité. Opaque à gauche sous
       le titre, presque transparent à droite pour laisser lire les colonnes. */
    linear-gradient(90deg,
      rgba(247, 244, 238, 0.97) 0%,
      rgba(247, 244, 238, 0.92) 26%,
      rgba(247, 244, 238, 0.55) 58%,
      rgba(247, 244, 238, 0.14) 100%);
}

/* Le filigrane du monogramme faisait double emploi avec la photo. */
.hero:has(.hero__photo) .hero__filigrane { display: none; }

/* Filigrane du monogramme, très discret */
.hero__filigrane {
  position: absolute;
  right: calc(var(--marge-page) * -0.35);
  bottom: -8%;
  width: clamp(320px, 42vw, 720px);
  aspect-ratio: 1363 / 1650;
  z-index: -1;
  color: var(--charbon);
  opacity: 0.045;
  pointer-events: none;
}

.hero__contenu {
  width: 100%;
  display: grid;
  gap: var(--e-5);
}

.hero__titre {
  font-size: var(--t-3xl);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.05em;
  text-wrap: balance;
  margin: 0;
}

/* Le point qui suit chaque mot : accent terre cuite, rythme visuel discret */
.hero__titre .point { color: var(--terre-cuite); }

.hero__bas {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: end;
  border-top: 1px solid var(--trait);
  padding-top: var(--e-4);
}

.hero__accroche {
  font-family: var(--police-serif);
  font-size: var(--t-lg);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: -0.015em;
  max-width: 24ch;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-3);
  justify-content: flex-end;
}

/* Indicateur de défilement */
.indicateur-defilement {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-tenu);
}

.indicateur-defilement__trait {
  width: 2.5rem;
  height: 1px;
  background: var(--trait-fort);
  position: relative;
  overflow: hidden;
}

.indicateur-defilement__trait::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--terre-cuite);
  transform: translateX(-100%);
  animation: glisse-trait 2.4s linear infinite;
}

@keyframes glisse-trait {
  0%   { transform: translateX(-100%); }
  55%  { transform: translateX(0); }
  100% { transform: translateX(100%); }
}

/* --- Héro des pages intérieures --- */
.hero-page {
  padding-top: calc(var(--hauteur-entete) + var(--e-7));
  padding-bottom: var(--e-6);
  background: linear-gradient(180deg, var(--sable) 0%, var(--creme) 100%);
}

.hero-page__titre {
  font-size: var(--t-2xl);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.042em;
  max-width: 20ch;
}

.fil-ariane {
  display: flex;
  align-items: center;
  gap: 0.6em;
  margin-bottom: var(--e-4);
  font-size: var(--t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--texte-tenu);
}

.fil-ariane a { text-decoration: none; }
.fil-ariane a:hover { color: var(--texte); }


/* 08. SECTIONS ÉDITORIALES
   ========================================================================== */

/* Paragraphe d'ouverture, plus grand */
.intro-editoriale {
  font-family: var(--police-serif);
  font-size: var(--t-lg);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: -0.012em;
  max-width: 34ch;
}

/* Bandeau de faits — uniquement des données vérifiables.

   Les filets sont de vraies bordures, pas un gap sur fond coloré : avec des
   colonnes de largeur fractionnaire (344,75 px), un gap de 1px tombe entre
   deux pixels physiques et certains traits disparaissent au rendu.

   Chaque cellule porte sa bordure gauche et haute ; le conteneur ne ferme que
   la droite et le bas. Résultat : la grille reste fermée même quand les
   cellules passent sur plusieurs rangées en format réduit. */
.faits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  border: 1px solid var(--trait);
  border-left: 0;
  border-top: 0;
}

.fait {
  padding: var(--e-4) var(--e-3);
  border-left: 1px solid var(--trait);
  border-top: 1px solid var(--trait);
  display: grid;
  gap: 0.5rem;
  align-content: start;
}

/* La valeur est masquée : son contenu monte en place à l'arrivée dans l'écran.
   Le cadre, lui, ne bouge jamais — ce sont les données qui montent dedans. */
.fait__valeur {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em;
  font-size: var(--t-xl);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Enveloppe posée par main.js autour du texte de la valeur */
.fait__valeur-interne { display: block; }

.fait__etiquette {
  display: block;
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-tenu);
  max-width: 22ch;
}

/* --- Animation d'arrivée du bandeau de faits --- */

.js-anim [data-faits] .fait__valeur-interne { transform: translateY(115%); }

.js-anim [data-faits] .fait__etiquette {
  opacity: 0;
  transform: translateY(0.6rem);
}

.js-anim [data-faits].est-visible .fait__valeur-interne {
  transform: translateY(0);
  transition: transform 0.95s var(--vif);
  transition-delay: calc(var(--i, 0) * var(--pas-cascade));
}

.js-anim [data-faits].est-visible .fait__etiquette {
  opacity: 1;
  transform: none;
  transition: opacity 0.7s var(--sortie), transform 0.8s var(--vif);
  transition-delay: calc(var(--i, 0) * var(--pas-cascade) + 130ms);
}

/* Les cellules n'ont plus de fond propre : elles laissent voir celui de la
   section, donc rien à ajuster sur fond sable. */

/* Citation / mise en exergue */
/* Le filet n'est plus une bordure mais un élément à part : il doit pouvoir
   se dessiner de haut en bas, au rythme de l'apparition des mots. */
.exergue {
  position: relative;
  font-family: var(--police-serif);
  font-size: var(--t-xl);
  font-weight: 400;
  font-style: italic;
  line-height: 1.3;
  letter-spacing: -0.02em;
  max-width: 24ch;
  padding-left: var(--e-4);
}

.exergue::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--accent);
  transform-origin: top center;
}

/* Durée calée sur la cascade des mots : 22 mots × 34 ms + la transition de
   chacun. Le filet finit sa course en même temps que le dernier mot. */
.js-anim .exergue[data-mots]::before { transform: scaleY(0); }

.js-anim .exergue[data-mots].est-visible::before {
  transform: scaleY(1);
  transition: transform 1.15s var(--sortie);
}

@media (prefers-reduced-motion: reduce) {
  .js-anim .exergue[data-mots]::before { transform: none !important; }
}


/* 09. CHAMPS DE PRATIQUE
   ========================================================================== */

.liste-pratiques {
  border-top: 1px solid var(--trait);
}

.pratique {
  border-bottom: 1px solid var(--trait);
}

.pratique__entete {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr) 3rem;
  align-items: center;
  gap: var(--e-3);
  padding: clamp(1.35rem, 2.6vw, 2.1rem) 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  color: var(--texte);
  transition: color var(--duree-survol) var(--sortie);
}

/* Voile qui glisse au survol */
.pratique__entete::before {
  content: '';
  position: absolute;
  inset: 0 calc(var(--marge-page) * -0.4);
  z-index: -1;
  background: var(--sable);
  opacity: 0;
  transform: scaleY(0.6);
  transform-origin: center;
  transition: opacity var(--duree-survol) var(--sortie), transform var(--duree-survol) var(--sortie);
}

.pratique__entete:hover::before,
.pratique__entete:focus-visible::before {
  opacity: 1;
  transform: scaleY(1);
}

.section--sable .pratique__entete::before { background: var(--sable); filter: brightness(0.97); }

.pratique__num {
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--texte-tenu);
  transition: color var(--duree-survol) var(--sortie);
}

.pratique__titre {
  font-size: clamp(1.15rem, 2.4vw, 1.85rem);
  font-weight: 500;
  letter-spacing: -0.028em;
  line-height: 1.15;
  transition: transform var(--duree-survol) var(--sortie);
}

.pratique__entete:hover .pratique__titre { transform: translateX(0.6rem); }
.pratique__entete:hover .pratique__num   { color: var(--accent); }

/* Signe + / − */
.pratique__signe {
  justify-self: end;
  position: relative;
  width: 15px;
  height: 15px;
  flex: none;
}

.pratique__signe::before,
.pratique__signe::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--charbon);
  transition: transform var(--duree-survol) var(--sortie), background-color var(--duree-survol) var(--sortie);
}

.pratique__signe::before {
  width: 15px;
  height: 1.5px;
  transform: translate(-50%, -50%);
}

.pratique__signe::after {
  width: 1.5px;
  height: 15px;
  transform: translate(-50%, -50%);
}

.pratique__entete[aria-expanded="true"] .pratique__signe::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.pratique__entete[aria-expanded="true"] .pratique__signe::before,
.pratique__entete[aria-expanded="true"] .pratique__signe::after {
  background: var(--olive);
}

.pratique__entete[aria-expanded="true"] { color: var(--olive); }

/* Panneau dépliant — animé par grid-template-rows (pas de hauteur en JS) */
.pratique__panneau {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--sortie);
}

.pratique__panneau > div { overflow: hidden; }

.pratique.est-ouverte .pratique__panneau { grid-template-rows: 1fr; }

.pratique__texte {
  padding: 0 3rem var(--e-4) 4rem;
  max-width: 68ch;
  font-family: var(--police-serif);
  font-size: var(--t-base);
  font-weight: 400;
  line-height: 1.62;
  color: var(--texte-doux);
  opacity: 0;
  transform: translateY(0.75rem);
  transition: opacity 0.28s var(--sortie) 0.08s, transform 0.34s var(--sortie) 0.08s;
}

.pratique.est-ouverte .pratique__texte {
  opacity: 1;
  transform: none;
}

/* --- Grille d'aperçu (page d'accueil) --- */
/* Mêmes filets que le bandeau de faits : de vraies bordures, jamais un gap sur
   fond coloré — sinon des traits sautent quand les colonnes tombent sur des
   largeurs fractionnaires. Chaque carte porte sa bordure gauche et haute. */
/* Nombre de colonnes fixé par palier, jamais auto-fill : avec auto-fill, une
   largeur d'écran suffisante crée des colonnes VIDES en fin de rangée. Ces
   colonnes n'ont pas de carte, donc pas de bordure — d'où des filets
   interrompus. Avec 8 cartes et 4 colonnes, les deux rangées sont toujours
   pleines, et les cartes grandissent avec l'écran au lieu de se réaligner. */
.grille-pratiques {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--trait);
  border-left: 0;
  border-top: 0;
}

@media (max-width: 1100px) {
  .grille-pratiques { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .grille-pratiques { grid-template-columns: minmax(0, 1fr); }
}

.carte-pratique {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  /* La carte grandit avec l'écran plutôt que de rester figée */
  min-height: clamp(210px, 15vw, 340px);
  padding: clamp(1.5rem, 2vw, 2.75rem);
  background: transparent;
  border-left: 1px solid var(--trait);
  border-top: 1px solid var(--trait);
  text-decoration: none;
  color: var(--texte);
  overflow: hidden;
  isolation: isolate;
  transition: color var(--duree-survol) var(--sortie), transform var(--duree-pression) var(--sortie);
}

.carte-pratique::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--charbon);
  transform: translateY(100%);
  transition: transform var(--duree-survol) var(--sortie);
}

/* Survol réservé aux vrais pointeurs : sur mobile, un appui laisserait la
   carte figée en noir après la navigation. */
@media (hover: hover) and (pointer: fine) {
  .carte-pratique:hover { color: var(--creme); }
  .carte-pratique:hover::before { transform: translateY(0); }
  .carte-pratique:hover .carte-pratique__num { color: var(--taupe-clair); }
  .carte-pratique:hover .carte-pratique__fleche { opacity: 1; transform: none; }
}

.carte-pratique:focus-visible { color: var(--creme); }
.carte-pratique:focus-visible::before { transform: translateY(0); }

.carte-pratique:active { transform: scale(0.99); }

.carte-pratique__num {
  font-size: var(--t-xs);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--texte-tenu);
  transition: color var(--duree-survol) var(--sortie);
}

.carte-pratique__titre {
  font-size: var(--t-md);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.2;
  margin-top: auto;
}

.carte-pratique__fleche {
  opacity: 0;
  transform: translate(-0.5rem, 0.5rem);
  transition: opacity var(--duree-survol) var(--sortie), transform var(--duree-survol) var(--sortie);
}



/* 10. BIO & PORTRAIT
   ========================================================================== */

.portrait {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--beige);
  overflow: hidden;
}

.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

/* Espace réservé tant que les photos ne sont pas fournies */
.portrait--attente {
  display: grid;
  place-items: center;
  background:
    linear-gradient(135deg, var(--beige) 0%, var(--sable) 100%);
}

.portrait--attente__marque {
  width: 45%;
  aspect-ratio: 1363 / 1650;
  color: var(--taupe);
  opacity: 0.35;
}

.portrait__legende {
  margin-top: var(--e-2);
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-tenu);
}

/* Variante « phrase » : quand la légende est une vraie phrase et non une
   étiquette, elle se lit comme du texte — pas de capitales, pas
   d'interlettrage, et la serif éditoriale du reste de la page. */
.portrait__legende--phrase {
  margin-top: var(--e-3);
  font-family: var(--police-serif);
  font-size: var(--t-base);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.008em;
  text-transform: none;
  color: var(--texte-doux);
  max-width: 34ch;
}

/* --- Bandeau ville pleine largeur --- */

.bandeau-ville {
  position: relative;
  /* Nettement plus haut qu'un simple bandeau : c'est un temps d'arrêt dans la
     page, pas une transition. Le fond charbon est peint ici même, pas hérité
     du thème — le bandeau reste donc sombre quoi qu'il arrive. */
  height: clamp(360px, 62vw, 820px);
  overflow: hidden;
  background: var(--charbon);
}

.bandeau-ville img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;

  /* La photo d'origine a un ciel bleu très saturé qui jure avec la palette de
     tons naturels. On la désature fortement et on la réchauffe pour qu'elle
     devienne une texture plutôt qu'une image couleur.
     Pour revenir à la photo brute : supprimer filter et .bandeau-ville__voile. */
  filter: grayscale(0.82) sepia(0.22) contrast(1.06) brightness(0.92);
  transform: scale(1.06);
  will-change: transform;
}

/* Voile chaud : raccorde la photo au brun charbon des sections sombres */
.bandeau-ville__voile {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(27, 25, 23, 0.55) 0%, rgba(27, 25, 23, 0.15) 32%, rgba(27, 25, 23, 0.62) 72%, rgba(27, 25, 23, 0.92) 100%),
    linear-gradient(90deg, rgba(87, 96, 63, 0.28) 0%, transparent 55%);
  mix-blend-mode: multiply;
}

.bandeau-ville__contenu {
  position: absolute;
  inset: auto 0 0 0;
  /* Plus d'air sous l'énoncé maintenant qu'il est grand */
  padding-block: var(--e-5);
  color: var(--creme);
}

/* Énoncé de pleine largeur : il doit porter, pas légender. D'où une taille
   propre plutôt qu'un cran de l'échelle courante — 24 px sur téléphone,
   jusqu'à 52 px sur grand écran. La mesure est resserrée à 20ch pour garder
   deux ou trois lignes bien empilées. */
/* Chaque ligne est masquée puis remonte : même effet que le héro, pour que
   l'énoncé arrive au lieu d'être simplement là. */
.bandeau-ville__texte .ligne-masque + .ligne-masque { margin-top: 0.02em; }

.bandeau-ville__texte {
  font-family: var(--police-serif);
  font-size: clamp(1.5rem, 3.2vw, 3.25rem);
  font-weight: 350;
  line-height: 1.16;
  letter-spacing: -0.022em;
  /* 34ch : assez large pour tenir sur deux lignes sur ordinateur.
     `balance` répartit ensuite les mots également entre les deux. */
  max-width: 34ch;
  text-wrap: balance;
  text-shadow: 0 1px 30px rgba(27, 25, 23, 0.55);
}

/* Léger effet de profondeur au défilement (désactivé si mouvement réduit) */
@media (prefers-reduced-motion: no-preference) {
  .bandeau-ville img {
    transition: transform 1.4s var(--vif);
  }
  .bandeau-ville.est-visible img {
    transform: scale(1);
  }
}


/* 11. SECTION SOMBRE / APPEL À L'ACTION
   ========================================================================== */

.sombre {
  position: relative;
  background: transparent;
  overflow: hidden;
}

/* Halo olive : il n'a de sens que sur le fond charbon. Depuis que la couleur
   est portée par la page, ce halo restait peint sur le crème pendant toute
   l'approche de la section — un lavis vert qui coupait la page en deux.
   Il n'apparaît donc qu'avec le thème sombre, au même rythme que lui. */
.sombre::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(90% 90% at 85% 8%, rgba(87, 96, 63, 0.35) 0%, transparent 60%);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--duree-fond) var(--sortie);
}

body[data-fond="charbon"] .sombre::before { opacity: 1; }

/* Même logique pour le filigrane du monogramme */
.sombre__filigrane {
  position: absolute;
  left: -6%;
  bottom: -22%;
  width: clamp(300px, 38vw, 620px);
  aspect-ratio: 1363 / 1650;
  color: var(--texte);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--duree-fond) var(--sortie);
}

body[data-fond="charbon"] .sombre__filigrane { opacity: 0.05; }

.sombre .enveloppe { position: relative; z-index: 1; }

/* Plus de couleurs figées ici : le thème « charbon » redéfinit --texte,
   --texte-doux, --texte-tenu et --trait, et tout fond ensemble. */

.appel-action {
  padding-block: var(--e-9);
}

.appel-action__titre {
  font-size: var(--t-2xl);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.042em;
  max-width: 18ch;
  margin-bottom: var(--e-5);
}

.appel-action__bas {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--e-4);
  align-items: end;
  border-top: 1px solid var(--trait);
  padding-top: var(--e-4);
}

/* Coordonnées directes, en gros */
.contact-direct {
  display: grid;
  gap: var(--e-2);
}

.contact-direct__lien {
  font-size: var(--t-lg);
  font-weight: 500;
  letter-spacing: -0.03em;
  text-decoration: none;
  width: fit-content;
}


/* 12. FORMULAIRE
   ========================================================================== */

.formulaire {
  display: grid;
  gap: var(--e-4);
}

.champs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e-3) var(--e-4);
}

.champ {
  position: relative;
  display: grid;
  gap: 0.45rem;
}

.champ--pleine-largeur { grid-column: 1 / -1; }

.champ__etiquette {
  font-size: var(--t-sm);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--texte-doux);
}

.champ__requis { color: var(--terre-cuite); }

.champ__saisie {
  width: 100%;
  padding: 0.9em 0;
  border: 0;
  border-bottom: 1px solid var(--trait-fort);
  border-radius: 0;
  background: transparent;
  font-size: var(--t-base);
  color: var(--texte);
  transition: border-color var(--duree-survol) var(--sortie);
  appearance: none;
}

textarea.champ__saisie {
  min-height: 8rem;
  resize: vertical;
  line-height: 1.55;
}

.champ__saisie::placeholder { color: var(--taupe); opacity: 0.7; }

.champ__saisie:focus {
  outline: none;
  border-bottom-color: var(--accent);
}

/* Trait qui se déploie sous le champ actif */
.champ__trait {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.22s var(--sortie);
  pointer-events: none;
}

.champ__saisie:focus ~ .champ__trait { transform: scaleX(1); }

/* Menu déroulant : flèche personnalisée */
select.champ__saisie {
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' stroke='%236F6558' stroke-width='1.4' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.25rem center;
  padding-right: 2rem;
}

/* État d'erreur */
.champ__erreur {
  font-size: var(--t-sm);
  color: var(--terre-cuite);
  min-height: 1.1em;
  opacity: 0;
  transform: translateY(-0.25rem);
  transition: opacity 0.3s var(--sortie), transform 0.3s var(--sortie);
}

.champ.est-invalide .champ__saisie { border-bottom-color: var(--terre-cuite); }
.champ.est-invalide .champ__erreur { opacity: 1; transform: none; }

/* Avis juridiques sous le formulaire */
.avis-juridique {
  display: grid;
  gap: var(--e-2);
  padding: var(--e-3) 0 0;
  border-top: 1px solid var(--trait);
  font-size: var(--t-base);
  line-height: 1.55;
  color: var(--texte-doux);
  max-width: 68ch;
}

/* Message de confirmation */
.message-formulaire {
  display: none;
  gap: var(--e-2);
  padding: var(--e-4);
  border: 1px solid var(--olive);
  background: rgba(87, 96, 63, 0.06);
}

.message-formulaire.est-visible { display: grid; }

.message-formulaire--erreur {
  border-color: var(--terre-cuite);
  background: rgba(176, 96, 60, 0.06);
}

.message-formulaire__titre {
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* Champ anti-pourriel, invisible pour les humains */
.pot-de-miel {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* État d'envoi */
.bouton[data-etat="envoi"] {
  pointer-events: none;
  opacity: 0.65;
}


/* 13. PIED DE PAGE
   ========================================================================== */

.pied {
  background: transparent;
  padding-top: var(--e-7);
  padding-bottom: var(--e-4);
}

.pied__haut {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: var(--e-5) var(--e-4);
  padding-bottom: var(--e-6);
}

.pied__marque {
  display: grid;
  gap: var(--e-3);
  align-content: start;
  max-width: 30ch;
}

.pied__symbole {
  width: 44px;
  height: 52px;
  color: var(--creme);
}

.pied__baseline {
  font-family: var(--police-serif);
  font-size: var(--t-md);
  font-weight: 400;
  line-height: 1.35;
  color: var(--texte-doux);
}

.pied__colonne {
  display: grid;
  gap: var(--e-2);
  align-content: start;
}

.pied__titre-colonne {
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texte-tenu);
  margin-bottom: var(--e-1);
}

.pied__lien {
  font-size: var(--t-sm);
  text-decoration: none;
  color: var(--texte-doux);
  width: fit-content;
  transition: color var(--duree-survol) var(--sortie);
  position: relative;
  padding-bottom: 0.15em;
}

.pied__lien::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duree-survol) var(--sortie);
}

.pied__lien:hover { color: var(--texte); }
.pied__lien:hover::after { transform: scaleX(1); }

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--e-2) var(--e-4);
  padding-top: var(--e-3);
  border-top: 1px solid var(--trait);
  font-size: var(--t-xs);
  color: var(--texte-tenu);
}

.pied__mentions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
}

/* Grand mot-symbole en bas, façon signature.
   La taille est calée sur « KEVIN KLEIN AVOCAT » (18 signes) pour tenir sur
   une seule ligne : si le texte change, il faut réajuster le clamp. */
.pied__signature {
  font-size: clamp(1.4rem, 7.7vw, 6.6rem);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 0.85;
  color: var(--texte);
  opacity: 0.09;
  padding-block: var(--e-4) var(--e-2);
  text-align: center;
  user-select: none;
  white-space: nowrap;
  overflow: hidden;
}


/* 14. ADAPTATION MOBILE
   ========================================================================== */

@media (max-width: 1080px) {
  .pied__haut { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pied__marque { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
  :root { --hauteur-entete: 72px; }

  .nav,
  .entete__actions .bouton { display: none; }

  .bascule-menu { display: flex; }

  .duo,
  .duo--inverse {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--e-4);
  }

  .duo__colonne-collante { position: static; }

  .hero__bas {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--e-4);
  }

  .hero__actions { justify-content: flex-start; }

  .appel-action__bas { grid-template-columns: minmax(0, 1fr); }

  .champs { grid-template-columns: minmax(0, 1fr); }

  .pratique__entete {
    grid-template-columns: 2.5rem minmax(0, 1fr) 2rem;
    gap: var(--e-2);
  }

  .pratique__texte { padding: 0 0 var(--e-3) 2.5rem; }

  .indicateur-defilement { display: none; }
}

@media (max-width: 900px) {
  /* Le texte occupe toute la largeur : le dégradé horizontal ne suffit plus
     à protéger la lisibilité, il faut un voile plus uniforme. */
  .hero__voile {
    background:
      linear-gradient(180deg,
        rgba(247, 244, 238, 0.9) 0%,
        rgba(247, 244, 238, 0.62) 30%,
        rgba(247, 244, 238, 0.78) 62%,
        rgba(247, 244, 238, 1) 100%);
  }

  .hero__photo img { object-position: center 30%; }
}

@media (max-width: 560px) {
  .hero { min-height: auto; padding-bottom: var(--e-5); }
  .hero__filigrane { opacity: 0.03; bottom: auto; top: 18%; }

  .marque__role { display: none; }

  .fait { padding-right: var(--e-2); }

  .pied__haut { grid-template-columns: minmax(0, 1fr); }

  .pied__bas { flex-direction: column; align-items: flex-start; }
}


/* 15. ACCESSIBILITÉ & MOUVEMENT RÉDUIT
   ========================================================================== */

/* Lien d'évitement pour la navigation au clavier */
.saut-contenu {
  position: absolute;
  top: 0;
  left: var(--marge-page);
  z-index: 200;
  padding: 0.75em 1.25em;
  background: var(--charbon);
  color: var(--creme);
  font-size: var(--t-sm);
  text-decoration: none;
  transform: translateY(-120%);
  transition: transform 0.25s var(--sortie);
}

.saut-contenu:focus { transform: translateY(0); }

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

/* Réservé aux lecteurs d'écran */
.lecteur-ecran-seulement {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Respect du réglage système « réduire les animations ».

   « Réduire » ne veut pas dire « supprimer ». On retire ce qui bouge dans
   l'espace — translations, mises à l'échelle, révélations glissées — et on
   garde les fondus et les changements de couleur, qui aident à comprendre ce
   qui vient de changer. Tout couper rendrait l'interface sèche et priverait
   ces personnes des repères que le mouvement apporte. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    /* Les animations en boucle n'ont aucune justification ici. */
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    /* Aucun déplacement : on neutralise la translation, pas la transition. */
    transition-property: opacity, color, background-color, border-color, box-shadow !important;
    transition-duration: 200ms !important;
  }

  .js-anim [data-anim] {
    opacity: 1 !important;
    transform: none !important;
  }

  .js-anim .ligne-masque > span { transform: none !important; }
  .js-anim .trait-anime { transform: scaleX(1) !important; }

  .js-anim [data-faits] .fait__valeur-interne { transform: none !important; }
  .js-anim [data-faits] .fait__etiquette { opacity: 1 !important; transform: none !important; }
}

/* Impression : version sobre, sans fioritures */
@media print {
  .entete, .panneau-mobile, .indicateur-defilement,
  .hero__filigrane, .sombre__filigrane, .pied__signature { display: none !important; }

  body { background: #fff; color: #000; }
  .sombre, .pied { background: #fff !important; color: #000 !important; }
  .pratique__panneau { grid-template-rows: 1fr !important; }
  .pratique__texte { opacity: 1 !important; transform: none !important; }
}


/* --- Accompagnement du fondu de fond -------------------------------------
   Ces éléments tirent leur couleur ou leur filet des variables de thème.
   Sans transition propre, ils basculeraient d'un coup pendant que le fond,
   lui, fond en douceur. */

.surtitre, .texte-doux, .texte-editorial, .fait__etiquette, .fait__valeur,
.pratique__num, .pratique__titre, .carte-pratique__num, .portrait__legende,
.fil-ariane, .pied__baseline, .pied__titre-colonne, .pied__lien, .pied__bas,
.pied__signature, .intro-editoriale, .exergue, .bandeau-ville__texte,
.contact-direct__lien, .lien-fleche, .marque__nom, .marque__role, .nav__lien,
.langue__option, .champ__etiquette, .avis-juridique {
  transition: color var(--duree-fond) var(--sortie);
}

.faits, .fait, .grille-pratiques, .carte-pratique, .liste-pratiques,
.pratique, .filet, .hero__bas, .appel-action__bas, .avis-juridique,
.exergue, .portrait {
  transition: border-color var(--duree-fond) var(--sortie),
              background-color var(--duree-fond) var(--sortie);
}

/* Le survol reste prioritaire : il doit rester vif (180 ms) même pendant un
   changement de thème. */
.carte-pratique {
  transition: color var(--duree-survol) var(--sortie),
              transform var(--duree-pression) var(--sortie),
              border-color var(--duree-fond) var(--sortie);
}

.pratique__entete, .bouton, .lien, .nav__lien, .pied__lien {
  transition-duration: var(--duree-survol);
}

/* Le monogramme et les filigranes suivent la couleur du texte */
.marque__symbole, .pied__symbole, .hero__filigrane, .sombre__filigrane {
  transition: color var(--duree-fond) var(--sortie);
}
.pied__symbole, .sombre__filigrane { color: var(--texte); }

/* Le bouton doit suivre le fondu de fond comme le reste */
.bouton {
  transition: color var(--duree-survol) var(--sortie),
              border-color var(--duree-survol) var(--sortie),
              transform var(--duree-pression) var(--sortie),
              background-color var(--duree-fond) var(--sortie);
}


/* ==========================================================================
   ÉTAPES DU PROCESSUS JUDICIAIRE
   --------------------------------------------------------------------------
   Ce ne sont pas des statistiques : ce sont des jalons ordonnés. D'où une
   liste numérotée verticale reliée par un filet, et surtout AUCUN compteur —
   voir des chiffres défiler ici laissait croire à des données chiffrées.

   La verticale est le bon axe : elle épouse le sens de lecture et celui du
   défilement, et elle laisse la place à des libellés vraiment grands.

   Le filet se remplit au fil du défilement : main.js pose --progression
   (0 → 1) sur le conteneur, le CSS s'en sert pour la barre et pour
   l'activation de chaque jalon.
   ========================================================================== */

.etapes {
  --taille-pastille: clamp(3rem, 4.2vw, 4.5rem);
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
}

/* --- Filet de liaison ---
   Deux traits superposés : la piste, puis la progression par-dessus.
   Il court du centre de la première pastille au centre de la dernière. */

.etapes__piste,
.etapes__progression {
  position: absolute;
  left: calc(var(--taille-pastille) / 2);
  top: calc(var(--taille-pastille) / 2);
  bottom: calc(var(--taille-pastille) / 2);
  width: 1px;
  pointer-events: none;
}

.etapes__piste {
  background: var(--trait);
  transition: background-color var(--duree-fond) var(--sortie);
}

.etapes__progression {
  background: var(--terre-cuite);
  transform: scaleY(var(--progression, 0));
  transform-origin: center top;
  /* Pas de transition : la barre est pilotée image par image par le
     défilement, une transition la ferait traîner derrière le doigt. */
}

.etape {
  position: relative;
  display: grid;
  grid-template-columns: var(--taille-pastille) minmax(0, 1fr);
  align-items: center;
  gap: clamp(1.25rem, 2.4vw, 2.75rem);
  padding-block: clamp(0.75rem, 1.6vw, 1.5rem);
}

.etape__pastille {
  position: relative;
  z-index: 1;
  width: var(--taille-pastille);
  height: var(--taille-pastille);
  display: grid;
  place-items: center;
  border: 1px solid var(--trait-fort);
  border-radius: 50%;
  background: var(--fond);
  font-size: var(--t-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--texte-tenu);
  transition: border-color 0.45s var(--sortie),
              color 0.45s var(--sortie),
              background-color var(--duree-fond) var(--sortie);
}

/* Le libellé porte la section : il est traité comme un titre, pas comme une
   étiquette. Plafonné sous le titre de section pour ne pas lui voler la vedette. */
.etape__titre {
  font-size: clamp(1.375rem, 2.4vw, 2.5rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--texte-tenu);
  transition: color 0.45s var(--sortie), transform 0.55s var(--vif);
}

/* --- Jalon atteint --- */

.etape.est-atteinte .etape__pastille {
  border-color: var(--terre-cuite);
  color: var(--terre-cuite);
}

.etape.est-atteinte .etape__titre {
  color: var(--texte);
}

@media (hover: hover) and (pointer: fine) {
  .etape.est-atteinte .etape__titre { transform: translateX(0.15em); }
}

/* Sans JavaScript ou en mouvement réduit, tout est déjà atteint */
html:not(.js-anim) .etape .etape__pastille {
  border-color: var(--terre-cuite);
  color: var(--terre-cuite);
}
html:not(.js-anim) .etape .etape__titre { color: var(--texte); }
html:not(.js-anim) .etapes__progression { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .etapes__progression { transform: none !important; }
  .etape .etape__pastille { border-color: var(--terre-cuite) !important; color: var(--terre-cuite) !important; }
  .etape .etape__titre { color: var(--texte) !important; transform: none !important; }
}


/* ==========================================================================
   RÉVÉLATION MOT À MOT
   --------------------------------------------------------------------------
   Les mots arrivent en cascade, en sortant d'un léger flou. Réservé aux
   citations mises en exergue : c'est un effet qui appelle l'attention, il
   perdrait tout son sens s'il servait sur du texte courant.

   Les mots sont découpés par main.js, pas dans le HTML : le texte source
   reste intact et lisible dans le fichier — important, c'est du texte client.
   ========================================================================== */

.mot {
  display: inline-block;
  white-space: pre-wrap;
}

.js-anim [data-mots] .mot {
  opacity: 0;
  transform: translateY(0.32em);
  filter: blur(5px);
  will-change: opacity, transform, filter;
}

.js-anim [data-mots].est-visible .mot {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition: opacity 0.5s var(--sortie),
              transform 0.62s var(--vif),
              filter 0.5s var(--sortie);
  /* 34 ms entre deux mots : au-delà, la phrase se traîne. */
  transition-delay: calc(var(--i, 0) * 34ms);
}

/* L'animation terminée, on rend la main au navigateur */
.js-anim [data-mots].est-visible .mot { will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  .js-anim [data-mots] .mot {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
}
