/*
  Projet   : 15a Business Connect
  Fichier  : Feuille de style principale du site
  Version  : 0.123.0 — 2026-08-11 19:25
  Objectif : Habillage complet du site. Direction « carton d'invitation » :
             fond ivoire chaud, encre anthracite, un unique accent bleu nuit
             posé du bout des doigts (filets, survols). Mobile d'abord.
             Deux peaux : une claire (par défaut) et une sombre (nuit bleue),
             pilotées par l'attribut data-theme et un bouton lune/soleil.
             Toute la couleur passe par des jetons : seule la peau change.
*/

@import url("fonts.css");
@import url("pied-legal.css");

/* ================================================================== */
/*  1. Jetons                                                          */
/* ================================================================== */

:root {
  /* Fonds — ivoire chaud, du papier. Du plus clair au plus « posé ».
     (Les noms « encre » sont conservés de la première charte pour ne pas
     casser les 200 références ; ici ce sont bien les tons CLAIRS du fond.) */
  --encre: #f6f4ef;
  --encre-2: #efece4;
  --encre-3: #e7e3d8;

  /* Surfaces translucides posées sur l'ivoire. */
  --verre: rgba(28, 42, 74, 0.035);
  --verre-fort: rgba(28, 42, 74, 0.06);
  --bord: rgba(34, 30, 24, 0.13);
  --bord-fort: rgba(34, 30, 24, 0.26);

  /* Accent unique : bleu nuit d'encre, la Méditerranée à la nuit tombée.
     Posé seulement sur des arêtes, des filets, des survols. Jamais un aplat. */
  --tranche: #1c2e52;
  --tranche-sourd: #4a5b7e;
  --tranche-voile: rgba(28, 46, 82, 0.14);

  /* Textes — encre anthracite chaude, jamais du noir pur. */
  --ivoire: #22201c;
  --ivoire-2: #6a6459;
  --ivoire-3: #9a9284;

  /* Typographie. Fraunces (serif couture) porte les grands titres et les
     paroles ; Archivo (grotesque) tient labels, navigation, corps et chiffres. */
  --titre: "Fraunces", "Times New Roman", Georgia, serif;
  --corps: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --chiffres: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --parole: "Fraunces", Georgia, serif;

  /* Rythme vertical fluide. */
  --pas-1: 0.5rem;
  --pas-2: 1rem;
  --pas-3: 1.5rem;
  --pas-4: 2.5rem;
  --pas-5: clamp(3.5rem, 8vw, 7rem);
  --pas-6: clamp(4rem, 9vw, 7.5rem);

  /* Largeurs. */
  --large: 78rem;
  --texte: 38rem;

  /* Hauteur de la barre du haut. Une seule source : toute page qui doit
     dégager la barre s'y réfère, plus personne ne recopie « 68px ». */
  --barre-hauteur: 68px;

  /* Mouvement — rien ne dépasse trois dixièmes de seconde. */
  --vite: 140ms;
  --normal: 220ms;
  --lent: 300ms;
  --sortie: cubic-bezier(0.16, 1, 0.3, 1);
  --doux: cubic-bezier(0.4, 0, 0.2, 1);

  /* Jetons de surface auparavant écrits « en dur » dans les composants.
     Sortis ici pour que la peau sombre puisse les reprendre proprement. */
  --sur-tranche: #f5f1e8;               /* texte posé sur l'accent bleu */
  --entete-verre: rgba(245, 241, 232, 0.78);
  --tiroir-verre: rgba(245, 241, 232, 0.96);
  --tuile-survol: #efe9dc;
  --champ-fond: #fbf9f3;
  --champ-focus: #ffffff;
  --remonter-verre: rgba(245, 241, 232, 0.85);
  --trame-ligne: rgba(34, 30, 24, 0.04);
  --numero-fantome: rgba(34, 30, 24, 0.16);
  --tooltip-fond: #22201c;
  --tooltip-texte: #f2eee4;
  --vide-a: #ece7db;
  --vide-b: #e2dbcb;

  /* La houle du fond : deux teintes posées sur l'ivoire — un bleu nuit
     dilué et un or pâle. Assez présentes pour qu'on voie le fond vivre,
     assez diluées pour ne jamais se lire comme des taches. */
  --houle-froide: rgba(28, 42, 74, 0.14);
  --houle-chaude: rgba(176, 141, 87, 0.15);

  /* Les quatre durées de la houle. Deux pour la DÉRIVE (le glissement),
     deux pour le SOUFFLE (la lumière qui monte et se retire). Quatre
     nombres premiers entre eux : leur combinaison ne se répète pas avant
     des heures, donc l'œil n'y trouve jamais de boucle. */
  --houle-derive-a: 23s;
  --houle-derive-b: 31s;
  --houle-souffle-a: 17s;
  --houle-souffle-b: 29s;

  color-scheme: light;
}

/* ================================================================== */
/*  1 bis. La peau sombre — une nuit bleue                             */
/*         Mêmes composants, mêmes gestes : seuls les jetons changent.  */
/*         Le fond devient une encre bleu nuit, les textes passent en   */
/*         ivoire, l'accent bleu s'éclaircit pour tenir sur le sombre.  */
/* ================================================================== */

:root[data-theme="sombre"] {
  /* Fonds — encre bleu nuit, du plus profond au plus « relevé ». */
  --encre: #12151d;
  --encre-2: #171c27;
  --encre-3: #1f2532;

  /* Surfaces translucides posées sur l'encre : de l'ivoire, très voilé. */
  --verre: rgba(236, 233, 224, 0.045);
  --verre-fort: rgba(236, 233, 224, 0.08);
  --bord: rgba(236, 233, 224, 0.14);
  --bord-fort: rgba(236, 233, 224, 0.28);

  /* Accent bleu éclairci : la Méditerranée sous la lune, il doit ressortir. */
  --tranche: #7ea0da;
  --tranche-sourd: #93aede;
  --tranche-voile: rgba(126, 160, 218, 0.2);

  /* Textes — ivoire clair, jamais du blanc pur. */
  --ivoire: #ece9e0;
  --ivoire-2: #aea89a;
  --ivoire-3: #7f7a6c;

  /* Reprises des surfaces « en dur ». */
  --sur-tranche: #12151d;
  --entete-verre: rgba(18, 21, 29, 0.82);
  --tiroir-verre: rgba(18, 21, 29, 0.97);
  --tuile-survol: #1c212d;
  --champ-fond: #171c27;
  --champ-focus: #1f2532;
  --remonter-verre: rgba(18, 21, 29, 0.85);
  --trame-ligne: rgba(236, 233, 224, 0.05);
  --numero-fantome: rgba(236, 233, 224, 0.12);

  /* La houle du fond, sous la nuit : un bleu de lune et une braise chaude.
     Plus francs qu'en plein jour — sur du sombre, l'œil perd beaucoup plus
     vite les écarts de ton. */
  --houle-froide: rgba(126, 160, 218, 0.2);
  --houle-chaude: rgba(198, 162, 106, 0.15);
  --tooltip-fond: #ece9e0;
  --tooltip-texte: #171c27;
  --vide-a: #1a1f2a;
  --vide-b: #141822;

  color-scheme: dark;
}

/* ================================================================== */
/*  2. Réinitialisation                                                */
/* ================================================================== */

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

* {
  margin: 0;
}

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

body {
  /* Les deux nappes de la houle vivent dans des calques posés DERRIÈRE le
     contenu. Sans cette isolation, elles passeraient sous la couleur de
     fond de la page et on ne verrait jamais rien. */
  position: relative;
  isolation: isolate;
  min-height: 100vh;
  background-color: var(--encre);
  color: var(--ivoire);
  font-family: var(--corps);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.65;
  letter-spacing: 0.005em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  transition: background-color var(--lent) var(--doux), color var(--lent) var(--doux);
}

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

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

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

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

::selection {
  background: var(--tranche-voile);
  color: var(--ivoire);
}

/* ================================================================== */
/*  3. Typographie                                                     */
/* ================================================================== */

h1,
h2,
h3,
h4 {
  font-family: var(--titre);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -0.015em;
  text-wrap: balance;
  font-optical-sizing: auto;
}

h1 {
  font-size: clamp(3rem, 8vw, 6.5rem);
  font-weight: 380;
  line-height: 0.98;
  letter-spacing: -0.02em;
}

h2 {
  font-size: clamp(2.15rem, 5vw, 3.75rem);
  font-weight: 400;
  letter-spacing: -0.018em;
}

h3 {
  font-size: clamp(1.35rem, 2.2vw, 1.65rem);
  font-weight: 450;
  letter-spacing: -0.01em;
}

/* Un mot mis en italique dans un titre : le geste couture de Fraunces. */
h1 em,
h2 em,
h3 em,
.parole em {
  font-style: italic;
  font-weight: 380;
}

p {
  text-wrap: pretty;
}

.plomb {
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  line-height: 1.6;
  color: var(--ivoire-2);
  max-width: var(--texte);
}

.mention {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--tranche);
}

.sourdine {
  color: var(--ivoire-2);
}

/* ================================================================== */
/*  4. Ossature                                                        */
/* ================================================================== */

.contenance {
  width: 100%;
  max-width: var(--large);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 3.5rem);
}

.section {
  position: relative;
  padding-block: var(--pas-6);
}

.section--serre {
  padding-block: var(--pas-5);
}

/* La trame de lignes fines — les lignes du terrain sous le contenu. */
.trame {
  position: relative;
}

.trame::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    0deg,
    var(--trame-ligne),
    var(--trame-ligne) 1px,
    transparent 1px,
    transparent 34px
  );
  mask-image: linear-gradient(180deg, transparent, #000 25%, #000 75%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 25%, #000 75%, transparent);
}

.trame > * {
  position: relative;
  z-index: 1;
}

/* Le filet : une règle horizontale qui s'affirme en son milieu. */
.filet {
  height: 1px;
  border: 0;
  background: linear-gradient(
    90deg,
    transparent,
    var(--bord) 15%,
    var(--tranche-sourd) 50%,
    var(--bord) 85%,
    transparent
  );
}

/* ================================================================== */
/*  5. Le rideau d'entrée                                              */
/*     Carrés emboîtés qui se déploient. Joue une fois, puis se lève.   */
/* ================================================================== */

.rideau {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background: var(--encre);
  transition: opacity 420ms var(--doux), visibility 420ms;
}

.rideau[hidden] {
  display: none;
}

.rideau.est-leve {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.rideau__scene {
  position: relative;
  width: 148px;
  height: 74px; /* proportions d'un court : 2 pour 1 */
}

.rideau__cadre {
  position: absolute;
  border: 1px solid var(--bord);
  animation: deploie 1.4s ease-in-out infinite;
}

.rideau__cadre:nth-child(1) {
  inset: 40%;
  border-color: var(--tranche);
}
.rideau__cadre:nth-child(2) {
  inset: 26%;
  border-color: rgba(28, 46, 82, 0.55);
  animation-delay: 0.12s;
}
.rideau__cadre:nth-child(3) {
  inset: 13%;
  border-color: rgba(28, 46, 82, 0.32);
  animation-delay: 0.24s;
}
.rideau__cadre:nth-child(4) {
  inset: 0%;
  border-color: rgba(28, 46, 82, 0.16);
  animation-delay: 0.36s;
}

/* Le filet central du court. */
.rideau__scene::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: var(--tranche-sourd);
  opacity: 0.5;
}

@keyframes deploie {
  0%,
  100% {
    transform: scale(1);
    opacity: 0.85;
  }
  50% {
    transform: scale(1.12);
    opacity: 1;
  }
}

/* ================================================================== */
/*  6. Navigation — verre clair, le contenu défile dessous             */
/* ================================================================== */

.entete {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  transition: background var(--lent) var(--doux),
    border-color var(--lent) var(--doux), backdrop-filter var(--lent);
  border-bottom: 1px solid transparent;
}

.entete.est-posee {
  background: var(--entete-verre);
  backdrop-filter: blur(16px) saturate(120%);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
  border-bottom-color: var(--bord);
}

.entete__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pas-3);
  height: var(--barre-hauteur);
}

/* La marque : le logo du club.
   Il est posé ICI, en une seule règle, et non dans le code de chaque page :
   seize pages portent cette barre, et elles doivent toutes dire la même
   chose. L'ancien monogramme dessiné et le nom écrit à côté sont retirés —
   le logo contient déjà les deux.
   Le nom du club reste annoncé aux lecteurs d'écran par le lien lui-même. */
.marque {
  display: inline-flex;
  align-items: center;
  padding-block: 0.25rem;
}

.marque__signe,
.marque__mot {
  display: none;
}

.marque::before {
  content: "";
  display: block;
  /* Le logo est un peu plus haut que large (« BUSINESS CONNECT » y tient
     sur deux lignes). Les deux mesures suivent donc ses proportions
     exactes : toute approximation le déformerait.
     La hauteur est calée pour qu'il RESPIRE dans la barre — mesuré, il
     lui reste quatre points de dégagement en haut comme en bas. Plus
     grand, il collait aux bords et la barre paraissait pleine. */
  width: 3.11rem;
  height: 3.25rem;
  background-image: url("../img/logo/15a-bc-encre.png");
  background-image: image-set(
    url("../img/logo/15a-bc-encre.png") 1x,
    url("../img/logo/15a-bc-encre@2x.png") 2x
  );
  background-size: contain;
  background-repeat: no-repeat;
  background-position: left center;
  transition: opacity var(--normal) var(--doux);
}

.marque:hover::before {
  opacity: 0.7;
}

/* Sur la nuit bleue, le logo passe en ivoire. Deux fichiers distincts
   plutôt qu'un filtre : un logo retourné par calcul vire au bleu froid,
   alors que la charte veut un ivoire chaud. */
:root[data-theme="sombre"] .marque::before {
  background-image: url("../img/logo/15a-bc-ivoire.png");
  background-image: image-set(
    url("../img/logo/15a-bc-ivoire.png") 1x,
    url("../img/logo/15a-bc-ivoire@2x.png") 2x
  );
}

/* Sur téléphone, la barre est plus basse : le logo se resserre pour ne pas
   la faire déborder. */
@media (max-width: 40rem) {
  .marque::before {
    width: 2.51rem;
    height: 2.63rem;
  }

  /* L'en-tête des pages connectées (espace membre et administration) porte
     jusqu'à trois entrées à droite : Gestion, Retour au site, Se déconnecter,
     plus la bascule jour/nuit. Mesuré sur un téléphone : il lui fallait 422
     points là où l'écran n'en offre que 350. Les libellés se cassaient sur
     deux lignes et « Se déconnecter » passait hors champ.

     Plutôt que d'empiler un menu de plus — la barre d'onglets, juste en
     dessous, en est déjà un —, on retire l'entrée qui faisait doublon :
     « Retour au site » mène exactement où mène le logo, à quelques points
     de là. Rien n'est perdu, et tout tient.

     La règle vit ICI, dans la feuille que chargent les treize pages
     concernées, et non dans celle de l'espace membre que six d'entre elles
     ignorent. */
  .entete__droite--nav .nav__lien[href="index.html"] {
    display: none;
  }
}

/* Les tout petits écrans (320 points, les anciens téléphones). Une fois
   « Retour au site » retiré, il manquait encore vingt-deux points : on les
   récupère sur les espacements et la taille des libellés, sans rien retirer
   de plus. */
@media (max-width: 22rem) {
  .entete__droite--nav {
    gap: 0.4rem;
  }

  .entete__droite--nav .nav__lien,
  .entete__droite--nav .bouton-nu {
    font-size: 0.72rem;
  }

  .entete__droite--nav .bouton-nu {
    padding: 0.35rem 0.5rem;
  }

  .entete__droite--nav .theme-bascule {
    width: 30px;
    height: 30px;
  }
}

.nav {
  display: none;
  align-items: center;
  gap: clamp(1.25rem, 2.5vw, 2.25rem);
}

.nav__lien {
  position: relative;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ivoire-2);
  padding-block: 0.4rem;
  transition: color var(--normal) var(--doux);
}

.nav__lien::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--tranche);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--normal) var(--sortie);
}

.nav__lien:hover {
  color: var(--ivoire);
}

.nav__lien:hover::after {
  transform: scaleX(1);
}

/* Bouton d'ouverture du menu, mobile seulement. */
.bascule {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0 8px;
  background: none;
  border: 0;
  cursor: pointer;
}

.bascule span {
  height: 1px;
  background: var(--ivoire);
  transition: transform var(--normal) var(--sortie), opacity var(--vite);
}

.bascule[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.bascule[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}
.bascule[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* Le groupe d'actions à droite de l'en-tête : bascule de thème + menu. */
.entete__droite {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

/* Variante « liens de navigation » : quand ce groupe porte des LIENS texte
   (espaces membre et gestion : « Gestion », « Retour au site », « Espace
   membre ») et non seulement des icônes, on aère l'espacement pour qu'ils ne se
   touchent pas, et on affirme leur encre pour qu'ils se lisent bien. Scopée à
   cette variante : le site public (qui n'ajoute pas « --nav ») n'est pas touché. */
.entete__droite--nav {
  gap: clamp(1rem, 2.4vw, 1.75rem);
}
.entete__droite--nav .nav__lien {
  color: var(--ivoire);
  font-weight: 600;
}
.entete__droite--nav .nav__lien:hover {
  color: var(--tranche);
}

/* Le bouton lune / soleil : bascule entre les deux peaux. Discret, un cercle
   de verre qui s'affirme au survol. Présent sur mobile comme sur grand écran. */
.theme-bascule {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: transparent;
  color: var(--ivoire);
  cursor: pointer;
  transition: color var(--normal) var(--doux),
    border-color var(--normal) var(--doux),
    background var(--normal) var(--doux), transform var(--vite) var(--doux);
}

.theme-bascule:hover {
  color: var(--tranche);
  border-color: var(--bord);
  background: var(--verre);
}

.theme-bascule:active {
  transform: scale(0.92);
}

.theme-bascule svg {
  width: 19px;
  height: 19px;
}

/* Lune en peau claire (elle invite à passer au sombre) ; soleil en peau
   sombre (il invite à revenir au clair). */
.theme-bascule__soleil {
  display: none;
}

:root[data-theme="sombre"] .theme-bascule__lune {
  display: none;
}

:root[data-theme="sombre"] .theme-bascule__soleil {
  display: block;
}

.tiroir {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--lent) var(--sortie);
  background: var(--tiroir-verre);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.tiroir.est-ouvert {
  grid-template-rows: 1fr;
  border-bottom: 1px solid var(--bord);
}

.tiroir__interieur {
  overflow: hidden;
}

.tiroir__liste {
  display: flex;
  flex-direction: column;
  padding-block: var(--pas-2) var(--pas-3);
}

.tiroir__liste a {
  padding-block: 0.75rem;
  font-size: 1.0625rem;
  font-weight: 500;
  border-bottom: 1px solid var(--bord);
}

.tiroir__liste a:last-child {
  border-bottom: 0;
}

/* ================================================================== */
/*  7. Boutons                                                         */
/*     Principal : encre bleue pleine, l'appel à l'action assumé.       */
/* ================================================================== */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background: transparent;
  cursor: pointer;
  font-family: var(--corps);
  transition: transform var(--vite) var(--doux);
}

.bouton__corps {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.9rem 1.7rem;
  border-radius: 9px;
  background: var(--tranche);
  color: var(--sur-tranche);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: 0 1px 2px rgba(28, 42, 74, 0.18);
  transition: background var(--normal) var(--doux),
    box-shadow var(--normal) var(--doux);
}

.bouton:hover .bouton__corps {
  background: #24396a;
  box-shadow: 0 10px 26px -12px rgba(28, 42, 74, 0.55);
}

.bouton:active {
  transform: scale(0.97);
}

.bouton svg {
  width: 14px;
  height: 14px;
  flex: none;
  transition: transform var(--normal) var(--sortie);
}

.bouton:hover svg {
  transform: translateX(3px);
}

/* Le bouton logé dans la navigation reste secondaire : plus compact et cerné
   d'un simple filet, jamais plein. Il ne doit pas voler la vedette au grand
   appel à l'action de l'ouverture ni alourdir un en-tête tout en finesse. */
.nav .bouton__corps {
  padding: 0.52rem 1.1rem;
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  background: transparent;
  color: var(--tranche);
  box-shadow: inset 0 0 0 1px var(--bord-fort);
}

.nav .bouton:hover .bouton__corps {
  background: var(--tranche);
  color: var(--sur-tranche);
  box-shadow: inset 0 0 0 1px var(--tranche);
}

.nav .bouton svg {
  width: 12px;
  height: 12px;
}

/* Bouton discret : un trait fin qui se remplit à peine. */
.bouton-nu {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.9rem 1.6rem;
  border: 1px solid var(--bord-fort);
  border-radius: 9px;
  background: transparent;
  color: var(--ivoire);
  font-size: 0.9375rem;
  font-weight: 500;
  cursor: pointer;
  transition: border-color var(--normal) var(--doux),
    background var(--normal) var(--doux), transform var(--vite) var(--doux);
}

.bouton-nu:hover {
  border-color: var(--tranche);
  background: var(--verre);
}

.bouton-nu:active {
  transform: scale(0.97);
}

/* Variante à filet : un geste secondaire, discret. Le même partout —
   « Les soirées » comme « Ma fiche » — pour qu'un bouton de second plan
   ait toujours la même allure d'un écran à l'autre. */
.bouton-nu--filet {
  padding: 0.55rem 1rem;
  font-size: 0.8125rem;
  color: var(--ivoire-2);
  border-color: var(--bord);
}

.bouton-nu--filet:hover {
  color: var(--ivoire);
}

.bouton-nu--filet[hidden] {
  display: none;
}

/* Lien fléché. */
.lien-fleche {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--tranche);
  padding-block: 0.35rem;
}

.lien-fleche svg {
  width: 13px;
  transition: transform var(--normal) var(--sortie);
}

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

/* ================================================================== */
/*  8. L'ouverture                                                     */
/* ================================================================== */

.ouverture {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding-bottom: var(--pas-5);
  padding-top: 120px;
  overflow: hidden;
}

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

.ouverture__fond img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.9;
}

/* Emplacement réservé tant que la photographie n'est pas là :
   un ivoire travaillé, deux halos très doux, rien de criard. */
.ouverture__fond--vide {
  background: radial-gradient(
      120% 80% at 80% 26%,
      rgba(28, 46, 82, 0.08) 0%,
      transparent 60%
    ),
    radial-gradient(90% 70% at 12% 92%, rgba(34, 30, 24, 0.05) 0%, transparent 62%),
    linear-gradient(180deg, #f7f3ea 0%, #f1ecdf 100%);
}

/* Sur fond clair, le voile n'assombrit pas : il éclaircit juste la zone
   du texte pour garantir le contraste si une photo est posée. */
.ouverture__voile {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
      90deg,
      var(--encre) 0%,
      rgba(245, 241, 232, 0.72) 42%,
      rgba(245, 241, 232, 0.15) 100%
    ),
    linear-gradient(180deg, transparent 45%, var(--encre) 100%);
}

.ouverture__contenu {
  position: relative;
  z-index: 2;
  width: 100%;
}

.ouverture h1 {
  margin-top: var(--pas-2);
  max-width: 16ch;
}

.ouverture .plomb {
  margin-top: var(--pas-3);
}

.ouverture__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pas-2);
  margin-top: var(--pas-4);
}

/* La ligne de faits, en bas de l'ouverture. */
.faits {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pas-3) var(--pas-4);
  margin-top: var(--pas-4);
  padding-top: var(--pas-3);
  border-top: 1px solid var(--bord);
}

.fait {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.fait__valeur {
  font-family: var(--titre);
  font-size: 1.85rem;
  font-weight: 380;
  letter-spacing: -0.01em;
  color: var(--tranche);
}

.fait__mot {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

/* Le plan du court en filigrane, sur la moitié droite. */
.plan-court {
  display: none;
  position: absolute;
  z-index: 1;
  top: 46%;
  right: clamp(1.25rem, 4vw, 3.5rem);
  width: min(40%, 30rem);
  transform: translateY(-50%);
  overflow: visible;
}

.plan-court__paroi {
  fill: none;
  stroke: rgba(34, 30, 24, 0.16);
  stroke-width: 0.7;
}

.plan-court__ligne {
  stroke: rgba(34, 30, 24, 0.1);
  stroke-width: 0.45;
}

.plan-court__tranche {
  stroke: var(--tranche);
  stroke-width: 1.4;
  opacity: 0.85;
}

/* ================================================================== */
/*  9. Blocs de contenu                                                */
/* ================================================================== */

.entete-section {
  max-width: var(--texte);
  margin-bottom: var(--pas-4);
}

.entete-section h2 {
  margin-top: var(--pas-2);
}

.entete-section p {
  margin-top: var(--pas-3);
  color: var(--ivoire-2);
  font-size: 1.0625rem;
}

/* Le duo image / texte, alterné. */
.duo {
  display: grid;
  gap: var(--pas-4);
  align-items: center;
}

.duo + .duo {
  margin-top: var(--pas-6);
}

.duo__texte h3 {
  margin-top: var(--pas-2);
}

.duo__texte p {
  margin-top: var(--pas-3);
  color: var(--ivoire-2);
}

.duo__texte .lien-fleche {
  margin-top: var(--pas-3);
}

/* Le cadre autour d'une image : une arête d'encre bleue s'affirme. */
.cadre-verre {
  position: relative;
  border-radius: 4px;
  overflow: hidden;
  background: var(--encre-2);
  border: 1px solid var(--bord);
  aspect-ratio: 16 / 10;
}

.cadre-verre::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-left: 2px solid var(--tranche);
}

.cadre-verre img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Emplacement réservé, tant que les photographies ne sont pas là. */
.cadre-verre--vide {
  display: grid;
  place-items: center;
  background: linear-gradient(150deg, var(--vide-a) 0%, var(--vide-b) 100%);
}

.cadre-verre--vide span {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

/* Les cartes de contenu. */
.grille {
  display: grid;
  gap: 1px;
  background: var(--bord);
  border: 1px solid var(--bord);
}

.tuile {
  position: relative;
  padding: var(--pas-4) var(--pas-3);
  background: var(--encre);
  transition: background var(--normal) var(--doux);
}

.tuile::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 2px;
  height: 100%;
  background: var(--tranche);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--lent) var(--sortie);
}

.tuile:hover {
  background: var(--tuile-survol);
}

.tuile:hover::before {
  transform: scaleY(1);
}

.tuile__rang {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--tranche-sourd);
}

.tuile h3 {
  margin-top: var(--pas-2);
  font-size: 1.125rem;
}

.tuile p {
  margin-top: 0.65rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

/* Le déroulé horaire de la soirée. */
.deroule {
  display: grid;
  gap: 0;
  margin-top: var(--pas-4);
}

.moment {
  display: grid;
  grid-template-columns: 1.75rem 4.5rem 1fr;
  gap: var(--pas-3);
  padding-block: var(--pas-3);
  border-top: 1px solid var(--bord);
  align-items: baseline;
}

/* Filet de sécurité : un moment bâti SANS dessin (c'est le cas partout où le
   déroulé est reconstruit à partir de ce que le club a écrit) n'a que deux
   cases à placer. Sans cette règle, elles tombent dans les deux premières
   colonnes — le texte se serre dans la case de l'heure et toute la largeur
   utile reste vide à droite. On retire donc la colonne du dessin. */
.moment:not(:has(.moment__picto)) {
  grid-template-columns: 4.5rem 1fr;
}

/* Le pictogramme se cale sur la ligne de l'heure, pas sur la ligne de base
   du texte : sans quoi il flotterait un cheveu trop bas. */
.moment__picto {
  --picto-taille: 24px;
  align-self: start;
  margin-top: -0.15rem;
}

/* Sur téléphone, la colonne des dessins disparaît : la place manque, et
   c'est le texte qui compte. */
/* Sur un écran étroit, on ne met plus les trois en rang : le dessin et
   l'heure se posent côte à côte sur la première ligne, et le texte prend
   TOUTE la largeur en dessous.

   ⚠️ Ce qu'il ne faut surtout pas refaire : passer la grille à deux
   colonnes en comptant masquer le dessin. Le masquage ne prenait pas — la
   règle générale des pictogrammes, déclarée bien plus bas dans cette
   feuille, le rallumait — si bien qu'il restait trois éléments pour deux
   colonnes : le texte était renvoyé à la ligne dans la colonne de l'heure
   et s'écrivait sur soixante-douze points de large, un mot par ligne. */
@media (max-width: 30rem) {
  .moment {
    grid-template-columns: auto 1fr;
    gap: 0.75rem;
    align-items: center;
  }

  .moment__picto {
    grid-row: 1;
    margin-top: 0;
  }

  .moment__heure {
    grid-row: 1;
  }

  .moment__quoi {
    grid-column: 1 / -1;
    margin-top: 0.35rem;
  }
}

.moment:last-child {
  border-bottom: 1px solid var(--bord);
}

.moment__heure {
  font-family: var(--chiffres);
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--tranche);
  letter-spacing: 0.06em;
}

.moment__quoi h3 {
  font-size: 1.0625rem;
}

.moment__quoi p {
  margin-top: 0.4rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

/* La parole d'un membre : le seul endroit où la serif apparaît. */
.parole {
  max-width: 46rem;
}

.parole blockquote {
  font-family: var(--parole);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.375rem, 3vw, 2rem);
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: var(--ivoire);
}

.parole figcaption {
  margin-top: var(--pas-3);
  font-size: 0.875rem;
  color: var(--ivoire-3);
}

/* ================================================================== */
/*  10. Le bloc adhésion, tarifs en attente                            */
/* ================================================================== */

.formules {
  display: grid;
  gap: var(--pas-3);
  margin-top: var(--pas-4);
}

.formule {
  padding: var(--pas-4) var(--pas-3);
  border: 1px solid var(--bord);
  border-radius: 4px;
  background: var(--verre);
}

.formule__prix {
  margin-top: var(--pas-2);
  font-family: var(--titre);
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--ivoire-3);
}

.formule ul {
  margin-top: var(--pas-3);
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
}

.formule li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

.formule li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 8px;
  height: 1px;
  background: var(--tranche);
}

/* ================================================================== */
/*  11. Formulaire de candidature                                      */
/* ================================================================== */

.formulaire {
  display: grid;
  gap: var(--pas-3);
  max-width: 40rem;
  margin-top: var(--pas-4);
}

.duo-champs {
  display: grid;
  gap: var(--pas-3);
}

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

.champ label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

.champ input,
.champ textarea,
.champ select {
  width: 100%;
  padding: 0.9rem 1rem;
  background: var(--champ-fond);
  border: 1px solid var(--bord);
  border-radius: 4px;
  color: var(--ivoire);
  font-size: 1rem;
  outline: none;
  transition: border-color var(--normal) var(--doux),
    background var(--normal) var(--doux), box-shadow var(--normal) var(--doux);
}

.champ textarea {
  min-height: 8rem;
  resize: vertical;
}

.champ input::placeholder,
.champ textarea::placeholder {
  color: var(--ivoire-3);
}

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

.champ input:focus,
.champ textarea:focus,
.champ select:focus {
  background: var(--champ-focus);
  border-color: var(--tranche);
  box-shadow: 0 0 0 3px var(--tranche-voile);
}

.champ__aide {
  font-size: 0.8125rem;
  color: var(--ivoire-3);
}

/* L'état de l'envoi d'une candidature. La confirmation prend la couleur de
   tranche et un peu de corps : une bonne nouvelle ne se lit pas en gris pâle,
   sinon on ne sait pas si on a cliqué. Le refus reste sobre, jamais alarmiste
   — personne n'a rien fait de mal, il manque juste quelque chose. */
.champ__aide--envoi {
  margin-top: var(--pas-1);
  font-size: 0.9rem;
  line-height: 1.6;
}

.champ__aide--succes {
  color: var(--tranche);
}

.champ__aide--refus {
  color: var(--ivoire);
}

/* La case de consentement. */
.consentement {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  cursor: pointer;
}

.consentement input {
  display: none;
}

.consentement__marque {
  position: relative;
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 0.15rem;
  border: 1px solid var(--bord-fort);
  border-radius: 50%;
  transition: border-color var(--normal) var(--doux);
}

.consentement__marque::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: var(--tranche);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity var(--vite), transform var(--normal) var(--sortie);
}

.consentement input:checked + .consentement__marque {
  border-color: var(--tranche);
}

.consentement input:checked + .consentement__marque::after {
  opacity: 1;
  transform: scale(1);
}

.consentement span:last-child {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ivoire-2);
}

.consentement a {
  color: var(--tranche);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Le piège à robots : invisible, jamais rempli par un humain. */
.piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ================================================================== */
/*  12. Infobulle                                                      */
/* ================================================================== */

.infobulle {
  position: relative;
  display: inline-block;
  border-bottom: 1px dotted var(--tranche-sourd);
  cursor: help;
}

.infobulle__texte {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  z-index: 20;
  width: max-content;
  /* Jamais plus large que l'écran, même sur un téléphone étroit. */
  max-width: min(17rem, calc(100vw - 2rem));
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--bord);
  border-radius: 4px;
  background: var(--tooltip-fond);
  color: var(--tooltip-texte);
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  box-shadow: 0 12px 30px -14px rgba(34, 30, 24, 0.5);
  opacity: 0;
  visibility: hidden;
  /* Centrée sur le mot, plus le recalage que pose le script quand elle
     toucherait le bord de l'écran (nul le reste du temps). */
  transform: translate(calc(-50% + var(--infobulle-decalage, 0px)), 4px);
  transition: opacity var(--normal) var(--doux),
    transform var(--normal) var(--sortie), visibility var(--normal);
}

.infobulle:hover .infobulle__texte,
.infobulle:focus-visible .infobulle__texte {
  opacity: 1;
  visibility: visible;
  transform: translate(calc(-50% + var(--infobulle-decalage, 0px)), 0);
}

/* ================================================================== */
/*  13. Retour en haut                                                 */
/* ================================================================== */

.remonter {
  position: fixed;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 90;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--bord);
  border-radius: 50%;
  background: var(--remonter-verre);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity var(--normal) var(--doux),
    transform var(--normal) var(--sortie), visibility var(--normal),
    border-color var(--normal);
}

.remonter.est-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.remonter:hover {
  border-color: var(--tranche);
}

.remonter svg {
  width: 15px;
  height: 15px;
  stroke: var(--ivoire);
  transition: transform var(--normal) var(--sortie);
}

.remonter:hover svg {
  transform: translateY(-3px);
}

.remonter:active {
  transform: scale(0.94);
}

/* ================================================================== */
/*  14. Pied de page                                                   */
/* ================================================================== */

.pied {
  border-top: 1px solid var(--bord);
  padding-block: var(--pas-5) var(--pas-4);
}

.pied__haut {
  display: grid;
  gap: var(--pas-4);
}

.pied__liens {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pas-2) var(--pas-3);
}

.pied__liens a {
  font-size: 0.875rem;
  color: var(--ivoire-2);
  transition: color var(--normal) var(--doux);
}

.pied__liens a:hover {
  color: var(--tranche);
}

.pied__bas {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--pas-2);
  margin-top: var(--pas-5);
  padding-top: var(--pas-3);
  border-top: 1px solid var(--bord);
  font-size: 0.8125rem;
  color: var(--ivoire-3);
}

/* ================================================================== */
/*  15. Le mouvement                                                   */
/* ================================================================== */

.apparait {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--lent) var(--doux), transform var(--lent) var(--sortie);
}

.apparait.est-la {
  opacity: 1;
  transform: none;
}

.cascade > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity var(--lent) var(--doux), transform var(--lent) var(--sortie);
}

.cascade.est-la > * {
  opacity: 1;
  transform: none;
}

.cascade.est-la > *:nth-child(1) { transition-delay: 0ms; }
.cascade.est-la > *:nth-child(2) { transition-delay: 60ms; }
.cascade.est-la > *:nth-child(3) { transition-delay: 120ms; }
.cascade.est-la > *:nth-child(4) { transition-delay: 180ms; }
.cascade.est-la > *:nth-child(5) { transition-delay: 240ms; }
.cascade.est-la > *:nth-child(6) { transition-delay: 300ms; }

/* La révélation en essuyage : l'image se découvre de gauche à droite.
   On observe le PARENT (une image entièrement découpée n'est jamais vue). */
.essuyage {
  clip-path: inset(0 100% 0 0);
  transition: clip-path 640ms var(--sortie) 80ms;
}

.essuyage.est-la,
.est-la .essuyage,
.est-la > .essuyage {
  clip-path: inset(0 0 0 0);
}

/* ================================================================== */
/*  16. Écrans larges                                                  */
/* ================================================================== */

@media (min-width: 40rem) {
  .duo-champs {
    grid-template-columns: 1fr 1fr;
  }

  .grille {
    grid-template-columns: repeat(2, 1fr);
  }

  .formules {
    grid-template-columns: repeat(3, 1fr);
  }

  .moment {
    grid-template-columns: 1.75rem 6rem 1fr;
  }
}

@media (min-width: 62rem) {
  .nav {
    display: flex;
  }

  .bascule,
  .tiroir {
    display: none;
  }

  .grille {
    grid-template-columns: repeat(4, 1fr);
  }

  .tuile {
    padding: var(--pas-4) var(--pas-3) var(--pas-5);
  }

  /* L'image prend nettement le dessus sur le texte : sur les références
     haut de gamme, c'est la photographie qui porte le standing. */
  .duo {
    grid-template-columns: 1.45fr 1fr;
    gap: var(--pas-4);
  }

  .duo--inverse {
    grid-template-columns: 1fr 1.45fr;
  }

  .duo--inverse .duo__media {
    order: 2;
  }

  .pied__haut {
    grid-template-columns: 1.2fr 1fr;
    align-items: start;
  }

  .ouverture h1 {
    max-width: 13ch;
  }

  .plan-court {
    display: block;
  }
}

/* ================================================================== */
/*  17. Mouvement réduit — on respecte le réglage du système           */
/* ================================================================== */

/* ================================================================== */
/*  18. Photographies — hero immersif, bande, galerie                  */
/* ================================================================== */

/* --- Le hero devient immersif : photo plein écran, texte clair. --- */
.ouverture--photo .ouverture__fond img {
  opacity: 1;
}

/* Le voile protège la lisibilité du titre SANS écraser la photographie :
   teinte chaude (pas bleu-noir), concentrée à gauche et en bas, la moitié
   droite reste pleinement lumineuse. C'est la photo qui doit vivre. */
.ouverture--photo .ouverture__voile {
  background: linear-gradient(
      90deg,
      rgba(26, 18, 10, 0.74) 0%,
      rgba(26, 18, 10, 0.42) 46%,
      rgba(26, 18, 10, 0.04) 100%
    ),
    linear-gradient(
      180deg,
      rgba(26, 18, 10, 0.34) 0%,
      transparent 26%,
      transparent 58%,
      rgba(26, 18, 10, 0.62) 100%
    );
}

.ouverture--photo .mention {
  color: #a9c0e2;
}

.ouverture--photo h1 {
  color: #f7f5f0;
}

.ouverture--photo .plomb {
  color: rgba(247, 245, 240, 0.82);
}

.ouverture--photo .fait__valeur {
  color: #f7f5f0;
}

.ouverture--photo .fait__mot {
  color: rgba(247, 245, 240, 0.62);
}

/* --- La navigation posée SUR la photographie d'ouverture ---
   Tant qu'on n'a pas défilé, l'en-tête flotte sur l'image : le texte doit
   passer en clair, sinon il se noie dans le décor. Dès que l'en-tête se pose
   sur son verre ivoire (au défilement), il reprend sa couleur d'encre. */
body.a-ouverture-photo .entete:not(.est-posee) .nav__lien,
body.a-ouverture-photo .entete:not(.est-posee) .marque__quinze {
  color: #f7f5f0;
}

body.a-ouverture-photo .entete:not(.est-posee) .marque__signe {
  color: #f7f5f0;
}

body.a-ouverture-photo .entete:not(.est-posee) .marque__suite {
  color: rgba(247, 245, 240, 0.72);
}

body.a-ouverture-photo .entete:not(.est-posee) .nav__lien:hover {
  color: #ffffff;
}

body.a-ouverture-photo .entete:not(.est-posee) .nav__lien::after {
  background: #f7f5f0;
}

body.a-ouverture-photo .entete:not(.est-posee) .bascule span {
  background: #f7f5f0;
}

body.a-ouverture-photo .entete:not(.est-posee) .theme-bascule {
  color: #f7f5f0;
}

/* Tant que la barre flotte sur la photographie, le logo passe en ivoire :
   posé en encre sombre, il disparaîtrait dans l'image. */
body.a-ouverture-photo .entete:not(.est-posee) .marque::before {
  background-image: url("../img/logo/15a-bc-ivoire.png");
  background-image: image-set(
    url("../img/logo/15a-bc-ivoire.png") 1x,
    url("../img/logo/15a-bc-ivoire@2x.png") 2x
  );
}

/* Un léger dégradé sous l'en-tête garantit la lisibilité quel que soit
   l'endroit clair ou sombre de la photographie. */
body.a-ouverture-photo .entete:not(.est-posee)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(26, 18, 10, 0.5) 0%, transparent 100%);
}

.ouverture--photo .faits {
  border-top-color: rgba(247, 245, 240, 0.22);
}

/* Sur la photo sombre, le bouton de la navigation reste un simple filet clair
   qui ne se remplit qu'au survol : discret, jamais une pastille pleine. */
body.a-ouverture-photo .entete:not(.est-posee) .nav .bouton__corps {
  color: #f7f5f0;
  box-shadow: inset 0 0 0 1px rgba(247, 245, 240, 0.5);
}

body.a-ouverture-photo .entete:not(.est-posee) .nav .bouton:hover .bouton__corps {
  background: #f7f5f0;
  color: var(--tranche);
  box-shadow: inset 0 0 0 1px #f7f5f0;
}

/* Sur la photo sombre, le bouton principal passe en ivoire : il claque. */
.ouverture--photo .bouton__corps {
  background: #f7f5f0;
  color: var(--tranche);
}

.ouverture--photo .bouton:hover .bouton__corps {
  background: #ffffff;
  box-shadow: 0 12px 30px -12px rgba(0, 0, 0, 0.6);
}

.ouverture--photo .bouton-nu {
  border-color: rgba(247, 245, 240, 0.42);
  color: #f7f5f0;
}

.ouverture--photo .bouton-nu:hover {
  border-color: #f7f5f0;
  background: rgba(247, 245, 240, 0.1);
}

/* --- La bande immersive : citation posée sur une photographie. --- */
.bande {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 58vh;
  padding-block: clamp(4.5rem, 11vw, 8.5rem);
  overflow: hidden;
}

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

.bande__fond img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Voile chaud et allégé : il assure la lisibilité de la citation sans
   éteindre la photographie, qui doit rester lumineuse. */
.bande__voile {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
      90deg,
      rgba(26, 18, 10, 0.78) 0%,
      rgba(26, 18, 10, 0.48) 52%,
      rgba(26, 18, 10, 0.14) 100%
    ),
    linear-gradient(180deg, rgba(26, 18, 10, 0.26), rgba(26, 18, 10, 0.34));
}

/* --- La grande photographie pleine largeur : le format qui donne l'échelle.
   Réservée aux moments forts (l'américano), là où la photo doit parler seule. */
.photo-large {
  position: relative;
  margin: 0;
  margin-top: var(--pas-4);
  border-radius: 4px;
  overflow: hidden;
  background: var(--encre-2);
  border: 1px solid var(--bord);
  aspect-ratio: 3 / 2;
}

.photo-large::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-left: 2px solid var(--tranche);
}

.photo-large img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-large figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: var(--pas-4) var(--pas-3) var(--pas-3);
  font-size: 0.9375rem;
  color: #f7f5f0;
  background: linear-gradient(180deg, transparent, rgba(26, 18, 10, 0.72));
}

@media (min-width: 40rem) {
  .photo-large {
    aspect-ratio: 21 / 9;
  }

  .photo-large figcaption {
    padding: var(--pas-5) var(--pas-4) var(--pas-3);
    font-size: 1.0625rem;
    max-width: 46rem;
  }
}

.bande .contenance {
  position: relative;
  z-index: 2;
}

.parole--clair blockquote {
  color: #f7f5f0;
}

.parole--clair figcaption {
  color: rgba(247, 245, 240, 0.6);
}

/* --- La galerie mosaïque. --- */
.galerie {
  display: grid;
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
  grid-template-columns: 1fr;
}

.cliche {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: 4px;
  border: 1px solid var(--bord);
  background: var(--encre-2);
  aspect-ratio: 4 / 3;
}

.cliche img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--sortie);
}

.cliche:hover img {
  transform: scale(1.05);
}

.cliche::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-left: 2px solid var(--tranche);
  opacity: 0;
  transition: opacity var(--normal) var(--doux);
}

.cliche:hover::after {
  opacity: 1;
}

@media (min-width: 48rem) {
  .galerie {
    grid-template-columns: 1fr 1fr;
  }

  .cliche--large {
    grid-column: 1 / -1;
    aspect-ratio: 21 / 8;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .apparait,
  .cascade > * {
    opacity: 1;
    transform: none;
  }

  .essuyage {
    clip-path: none;
  }
}

/* ================================================================== */
/*  19. Les pages de texte (mentions légales, confidentialité)         */
/*      Elles héritaient de la charte sans aucune mise en page :       */
/*      texte collé au bord, titres démesurés, aucun rythme.           */
/*      Ici on leur donne la tenue d'un document de club.              */
/* ================================================================== */

.page-texte {
  background: var(--encre);
}

/* Ces pages n'ont pas d'ouverture plein écran : le document commence
   juste sous la barre du haut, qui est posée par-dessus. On dégage donc
   sa hauteur, puis on laisse respirer. */
.page-texte .contenu-texte {
  padding-top: calc(var(--barre-hauteur) + var(--pas-5));
}

/* --- Le corps du document : une colonne étroite, faite pour lire. --- */
.contenu-texte {
  width: 100%;
  max-width: 44rem;
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 2rem);
  padding-bottom: var(--pas-6);
}

.contenu-texte h1 {
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  margin-bottom: var(--pas-2);
}

.contenu-texte h2 {
  font-size: clamp(1.4rem, 2.6vw, 1.75rem);
  margin-top: var(--pas-4);
  margin-bottom: var(--pas-2);
  padding-top: var(--pas-3);
  border-top: 1px solid var(--bord);
}

.contenu-texte h2:first-of-type {
  margin-top: var(--pas-3);
}

.contenu-texte h3 {
  font-size: 1.125rem;
  margin-top: var(--pas-3);
  margin-bottom: var(--pas-1);
}

.contenu-texte p,
.contenu-texte li {
  color: var(--ivoire-2);
  font-size: 0.9688rem;
  line-height: 1.72;
}

.contenu-texte p + p {
  margin-top: var(--pas-2);
}

.contenu-texte ul,
.contenu-texte ol {
  margin-top: var(--pas-2);
  padding-left: 1.25rem;
  display: grid;
  gap: 0.5rem;
}

.contenu-texte a {
  color: var(--tranche);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* La date de dernière mise à jour, discrète sous le titre. */
.contenu-texte .maj {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ivoire-3);
  margin-bottom: var(--pas-4);
}

/* --- Les listes de définitions (éditeur, hébergeur…) : deux colonnes
   sur écran large, empilées sur téléphone. --- */
.contenu-texte dl {
  margin-top: var(--pas-3);
  display: grid;
  gap: 0.25rem 1.5rem;
  border-top: 1px solid var(--bord);
  padding-top: var(--pas-2);
}

.contenu-texte dt {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ivoire-3);
  padding-top: 0.35rem;
}

.contenu-texte dd {
  margin: 0 0 var(--pas-2);
  color: var(--ivoire);
  font-size: 0.9688rem;
}

/* --- Ce qui reste à renseigner avant la mise en ligne : bien visible,
   pour que ça ne parte jamais en production par inadvertance. --- */
.a-completer {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border: 1px dashed rgba(160, 96, 40, 0.55);
  border-radius: 3px;
  background: rgba(200, 140, 60, 0.12);
  color: #8a5a1e;
  font-size: 0.875rem;
  font-style: italic;
}

@media (min-width: 40rem) {
  .contenu-texte dl {
    grid-template-columns: 14rem 1fr;
  }

  .contenu-texte dt {
    padding-top: 0;
  }

  .contenu-texte dd {
    margin-bottom: 0.5rem;
  }
}

/* ================================================================== */
/*  21. Les engagements de discrétion                                  */
/*      Un format volontairement différent des grilles de tuiles :     */
/*      des lignes séparées par des filets, comme les clauses d'une    */
/*      charte. Le ton est celui d'un engagement, pas d'un argumentaire.*/
/* ================================================================== */

.engagements {
  display: grid;
  gap: 0;
  margin-top: var(--pas-4);
  border-top: 1px solid var(--bord);
}

.engagement {
  position: relative;
  padding-block: var(--pas-3);
  border-bottom: 1px solid var(--bord);
}

.engagement h3 {
  font-size: 1.125rem;
}

.engagement p {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
  max-width: 46rem;
}

/* Une arête d'encre bleue se dessine à gauche au survol, comme sur
   les tuiles : le même geste, pour que la page reste d'une seule main. */
.engagement::before {
  content: "";
  position: absolute;
  top: 0;
  left: calc(var(--pas-3) * -1);
  width: 2px;
  height: 100%;
  background: var(--tranche);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--lent) var(--sortie);
}

.engagement:hover::before {
  transform: scaleY(1);
}

@media (min-width: 48rem) {
  .engagement {
    display: grid;
    grid-template-columns: 18rem 1fr;
    gap: var(--pas-4);
    align-items: baseline;
    padding-block: var(--pas-4);
  }

  .engagement p {
    margin-top: 0;
  }
}

/* ================================================================== */
/*  22. LA VIE DANS LES IMAGES                                         */
/*                                                                      */
/*      Le site était propre mais figé : de belles photographies, et    */
/*      aucun souffle. Une photo immobile derrière un titre, c'est une  */
/*      affiche ; une photo qui respire, c'est un lieu.                 */
/*                                                                      */
/*      Trois gestes, et pas un de plus :                               */
/*        — les grandes images RESPIRENT en permanence (très lentement) */
/*        — les images encadrées s'APPROCHENT au survol                 */
/*        — la galerie se DÉCALE légèrement, comme une pile qu'on remue */
/*                                                                      */
/*      Tout est en transformation seule (accéléré par la carte         */
/*      graphique) et tout se fige si le visiteur demande moins de      */
/*      mouvement.                                                      */
/* ================================================================== */

/* --- Le souffle : un zoom imperceptible qui va et vient. Vingt-huit
   secondes pour un aller, c'est-à-dire un mouvement qu'on ne voit pas
   bouger mais qu'on sent vivre. --- */
@keyframes souffle {
  from {
    transform: scale(1.02) translate3d(0, 0, 0);
  }
  to {
    transform: scale(1.11) translate3d(-1.6%, -1.2%, 0);
  }
}

@keyframes souffle-inverse {
  from {
    transform: scale(1.1) translate3d(1.4%, 0.8%, 0);
  }
  to {
    transform: scale(1.02) translate3d(0, 0, 0);
  }
}

/* La photographie d'ouverture a son propre traitement, plus bas dans la
   feuille : ce n'est plus un souffle, c'est un plan. Voir « Le plan
   d'ouverture ». */

/* Les bandes pleine largeur respirent dans l'autre sens, pour que deux
   images voisines ne bougent jamais à l'unisson. */
.bande__fond img {
  transform-origin: 40% 50%;
  animation: souffle-inverse 34s ease-in-out infinite alternate;
  will-change: transform;
}

/* --- L'approche : au survol, l'image avance vers vous. Lente (neuf
   dixièmes de seconde), pour rester élégante et jamais nerveuse. --- */
.cadre-verre,
.photo-large,
.galerie a,
.galerie figure,
.galerie div {
  overflow: hidden;
}

.cadre-verre img,
.photo-large img {
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

.cadre-verre:hover img,
.photo-large:hover img {
  transform: scale(1.055);
}

/* La grande photographie va un cran plus loin : son arête d'encre
   s'épaissit en même temps que l'image s'approche. */
.photo-large::after {
  transition: border-left-width 900ms cubic-bezier(0.16, 1, 0.3, 1);
}

.photo-large:hover::after {
  border-left-width: 5px;
}

/* --- La galerie : chaque vignette s'approche et se détache
   légèrement, comme une photo qu'on remonte d'une pile. --- */
.galerie img {
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

.galerie img:hover {
  transform: scale(1.06);
}

/* --- Les cartes de contenu prennent le même souffle : elles montent
   d'un cheveu au survol. Le même geste partout, pour que la page reste
   d'une seule main. --- */
.tuile,
.formule,
.cercle--ouvert {
  transition: background var(--normal) var(--doux),
    transform var(--lent) var(--sortie),
    box-shadow var(--lent) var(--doux);
}

.tuile:hover,
.formule:hover,
.cercle--ouvert:hover {
  transform: translateY(-3px);
}

.formule:hover,
.cercle--ouvert:hover {
  box-shadow: 0 18px 40px -28px rgba(28, 42, 74, 0.55);
}

/* --- Le mouvement réduit fige tout : plus aucun souffle, plus aucune
   approche. La photographie reste belle, simplement immobile. --- */
@media (prefers-reduced-motion: reduce) {
  .ouverture--photo .ouverture__fond img,
  .bande__fond img {
    animation: none;
    transform: scale(1.02);
  }

  .cadre-verre:hover img,
  .photo-large:hover img,
  .galerie img:hover,
  .tuile:hover,
  .formule:hover,
  .cercle--ouvert:hover {
    transform: none;
  }
}

/* ================================================================== */
/*  24. L'adhésion en attente de ses montants                          */
/*      Trois cartes « Formule à venir » identiques répétaient la      */
/*      même absence trois fois — long sur téléphone, et creux.        */
/*      Un bloc unique dit la même chose honnêtement, et convertit.    */
/* ================================================================== */

.adhesion-attente {
  display: grid;
  gap: var(--pas-4);
  margin-top: var(--pas-4);
  padding: var(--pas-4) var(--pas-3);
  border: 1px solid var(--bord);
  border-radius: 4px;
  background: var(--verre);
}

.adhesion-attente__inclus .cercle__liste {
  margin-top: var(--pas-3);
  margin-bottom: 0;
}

/* Ce qui est compris dans l'adhésion : le dessin remplace la puce. Chacun
   se trace quand la carte entre à l'écran. */
.inclus {
  list-style: none;
  padding-left: 0;
}

.inclus li {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding-block: 0.42rem;
}

.inclus .picto {
  --picto-taille: 22px;
  margin-top: 0.1rem;
  color: var(--tranche);
  opacity: 0.75;
}

/* La phrase d'attente : assumée en serif, comme une note manuscrite
   posée sur le carton — pas comme un message d'erreur. */
.adhesion-attente__phrase {
  font-family: var(--parole);
  font-style: italic;
  font-size: clamp(1.25rem, 2.2vw, 1.5rem);
  line-height: 1.4;
  color: var(--ivoire);
}

.adhesion-attente__mot p:not(.adhesion-attente__phrase) {
  margin-top: var(--pas-2);
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

.adhesion-attente__mot .lien-fleche {
  margin-top: var(--pas-3);
}

@media (min-width: 48rem) {
  .adhesion-attente {
    grid-template-columns: 1fr 1fr;
    gap: var(--pas-5);
    padding: var(--pas-5) var(--pas-4);
    align-items: start;
  }

  /* Un filet sépare ce qui est acquis de ce qui reste à venir. */
  .adhesion-attente__mot {
    padding-left: var(--pas-4);
    border-left: 1px solid var(--bord);
  }
}

/* ================================================================== */
/*  23. La tuile à photographie visible                                */
/*                                                                      */
/*      La synthèse de deux retours : on voit la photographie POUR DE   */
/*      VRAI, en pleine lumière et sans voile — et la tuile garde       */
/*      TOUTE son animation d'origine (arête qui monte, fond qui        */
/*      change, soulèvement).                                           */
/*                                                                      */
/*      L'image occupe le haut de la tuile, bord à bord, et le texte    */
/*      reste dessous sur l'ivoire : chacun sa zone, aucun compromis    */
/*      ni sur l'image ni sur la lisibilité.                            */
/* ================================================================== */

/* Pas de découpe au niveau de la tuile : ce qui doit être coupé, c'est
   l'image (elle a sa propre découpe juste dessous, qui contient son
   approche au survol). Une découpe posée ici rognait l'infobulle du mot
   « américano », qui doit pouvoir sortir de la tuile. */
.tuile--photo {
  padding-top: 0;
}

/* Marges négatives pour que la photographie touche les bords de la
   tuile, sans avoir à changer le padding du texte. */
.tuile__image {
  margin-inline: calc(var(--pas-3) * -1);
  margin-bottom: var(--pas-3);
  overflow: hidden;
  background: var(--encre-2);
  aspect-ratio: 3 / 2;
}

.tuile__image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.01);
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

/* Au survol, la photographie s'approche — le même geste que sur toutes
   les autres images du site. */
.tuile--photo:hover .tuile__image img {
  transform: scale(1.07);
}

@media (min-width: 62rem) {
  /* En grille de quatre, le texte respire davantage sous l'image. */
  .tuile--photo {
    padding-bottom: var(--pas-4);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tuile__image img,
  .tuile--photo:hover .tuile__image img {
    transform: none;
  }
}

/* ================================================================== */
/*  25. LE 15 — la porte, puis la page                                 */
/*                                                                      */
/*      Les deux mondes ne se comparent plus côte à côte : ce site      */
/*      appartient à Business Connect, et LE 15 n'y a qu'une porte.     */
/*      Sur la page d'accueil, cette porte est volontairement dépouillée*/
/*      — pas de photographie, pas de liste, pas de formulaire. Le      */
/*      monde ouvert accueille et parle ; celui-ci est muet.            */
/* ================================================================== */

.porte-15 {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--pas-2);
  max-width: 48rem;
  margin-inline: auto;
  padding: clamp(3rem, 6vw, 5rem) clamp(1.75rem, 5vw, 4rem);
  border: 1px solid var(--bord-fort);
  border-radius: 6px;
  background: var(--verre);
}

/* Un filet gravé à l'intérieur, comme le liseré d'un carton d'invitation :
   c'est lui qui donne à la porte du 15 son air de pièce d'apparat. */
.porte-15::before {
  content: "";
  position: absolute;
  inset: 11px;
  border: 1px solid var(--bord);
  border-radius: 3px;
  pointer-events: none;
}

.porte-15__signe {
  width: 76px;
  color: var(--ivoire-3);
  margin-bottom: var(--pas-2);
  transition: color var(--lent) var(--doux);
}

.porte-15:hover .porte-15__signe {
  color: var(--tranche);
}

.porte-15__signe svg {
  width: 100%;
  height: auto;
}

.porte-15__etat {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

.porte-15__nom {
  font-family: var(--titre);
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-weight: 400;
  letter-spacing: 0.02em;
}

.porte-15__phrase {
  max-width: 34rem;
  color: var(--ivoire-2);
  font-size: 1.0625rem;
  line-height: 1.6;
}

.porte-15__note {
  font-family: var(--parole);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--ivoire);
  max-width: 30rem;
}

.porte-15__lien {
  margin-top: var(--pas-2);
}

/* ================================================================== */
/*  26. La page du 15 — une autre maison                               */
/*      Fond sombre, monochrome, aucun jaune, aucune photographie :     */
/*      l'identité se distingue au premier coup d'œil de celle du site  */
/*      Business Connect. C'est la sobriété qui la marque.              */
/* ================================================================== */

.page-15 {
  background: var(--encre);
  color: var(--ivoire);
}

.quinze {
  position: relative; /* la sortie en haut à gauche s'y accroche */
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--pas-5) clamp(1.25rem, 5vw, 3rem);
}

.quinze__centre {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 40rem;
}

/* Le logo du 15, c'est la PORTE — la même que celle de l'accueil, celle
   qu'on vient de franchir. L'ancienne plaque gravée ne servait plus : deux
   signes différents pour un seul cercle, c'était un de trop. */
.quinze__porte {
  margin: 0 0 var(--pas-4);
  line-height: 0;
}

.quinze__porte img {
  display: block;
  width: clamp(12rem, 30vw, 16.5rem);
  height: auto;
  border-radius: 4px;
  border: 1px solid var(--bord);
  box-shadow: 0 18px 44px -30px rgba(28, 42, 74, 0.55);
}

/* La sortie, en haut à gauche : on doit savoir comment repartir dès qu'on
   arrive, sans avoir à descendre toute la page. Elle reste discrète — on
   vient d'entrer quelque part, on n'invite pas à en ressortir. */
.quinze__sortie {
  position: absolute;
  top: var(--pas-3);
  left: var(--pas-3);
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--ivoire-3);
  transition: color var(--normal) var(--doux);
}

.quinze__sortie svg {
  width: 13px;
  transition: transform var(--normal) var(--sortie);
}

.quinze__sortie:hover {
  color: var(--ivoire);
}

.quinze__sortie:hover svg {
  transform: translateX(-3px);
}

@media (max-width: 40rem) {
  .quinze__sortie {
    top: var(--pas-2);
    left: var(--pas-2);
    font-size: 0.75rem;
  }
}

.quinze__signe {
  width: 92px;
  color: var(--ivoire);
}

.quinze__signe svg {
  width: 100%;
  height: auto;
}

.quinze__etat {
  margin-top: var(--pas-4);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

.quinze__nom {
  margin-top: var(--pas-2);
  font-family: var(--titre);
  font-size: clamp(2.5rem, 6vw, 3.75rem);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--ivoire);
}

.quinze__filet {
  width: 3rem;
  height: 1px;
  border: 0;
  margin-block: var(--pas-4);
  background: var(--bord-fort);
}

.quinze__phrase {
  font-size: clamp(1.125rem, 2vw, 1.3125rem);
  line-height: 1.6;
  color: var(--ivoire);
  max-width: 34rem;
}

.quinze__points {
  display: grid;
  gap: var(--pas-3);
  margin-top: var(--pas-5);
  text-align: left;
  max-width: 32rem;
}

.quinze__points p {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--ivoire-2);
  padding-left: var(--pas-3);
  border-left: 1px solid var(--bord);
}

.quinze__points span {
  display: block;
  margin-bottom: 0.25rem;
  font-weight: 600;
  color: var(--ivoire);
}

.quinze__note {
  margin-top: var(--pas-5);
  font-family: var(--parole);
  font-style: italic;
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ivoire-2);
  max-width: 28rem;
}

.quinze__retour {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  margin-top: var(--pas-5);
  padding-top: var(--pas-4);
  border-top: 1px solid var(--bord);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: var(--ivoire-3);
  transition: color var(--normal) var(--doux);
}

.quinze__retour svg {
  width: 13px;
  transition: transform var(--normal) var(--sortie);
}

.quinze__retour:hover {
  color: var(--ivoire);
}

.quinze__retour:hover svg {
  transform: translateX(-3px);
}

/* ================================================================== */
/*  27. Ce qui nous sépare — le créneau contre la soirée               */
/*      Deux colonnes qui ne se valent pas, et qui ne prétendent pas   */
/*      se valoir : celle de gauche est grise et sourde, celle de      */
/*      droite est posée sur le verre du club, avec son arête d'encre. */
/* ================================================================== */

.ecart {
  display: grid;
  gap: var(--pas-3);
  margin-top: var(--pas-4);
}

.ecart__colonne {
  position: relative;
  padding: var(--pas-4) var(--pas-3);
  border: 1px solid var(--bord);
  border-radius: 4px;
}

.ecart__titre {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

.ecart__colonne ul {
  margin-top: var(--pas-3);
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.7rem;
}

.ecart__colonne li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

.ecart__colonne li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 8px;
  height: 1px;
  background: var(--ivoire-3);
}

/* La nôtre : sur le verre du club, arête d'encre, texte affirmé. */
.ecart__colonne--nous {
  background: var(--verre);
  border-color: var(--bord-fort);
}

.ecart__colonne--nous::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background: var(--tranche);
}

.ecart__colonne--nous .ecart__titre {
  color: var(--tranche);
}

.ecart__colonne--nous li {
  color: var(--ivoire);
}

.ecart__colonne--nous li::before {
  background: var(--tranche);
}

.ecart__note {
  margin-top: var(--pas-4);
  font-family: var(--parole);
  font-style: italic;
  font-size: clamp(1.0625rem, 1.8vw, 1.25rem);
  line-height: 1.5;
  color: var(--ivoire);
  max-width: 40rem;
}

@media (min-width: 48rem) {
  .ecart {
    grid-template-columns: 1fr 1fr;
    gap: var(--pas-4);
  }
}

/* --- Ce que LE 15 apporte, sur sa porte : la raison d'y aller. --- */
.porte-15__gains {
  display: grid;
  gap: 0.7rem;
  margin-top: var(--pas-3);
  margin-bottom: var(--pas-2);
  text-align: left;
}

.porte-15__gains p {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

.porte-15__gains p::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 8px;
  height: 1px;
  background: var(--tranche);
}

.porte-15__gains span {
  color: var(--ivoire);
  font-weight: 600;
}

/* ================================================================== */
/*  27. Ce qui nous sépare — le créneau contre la soirée               */
/*      Deux colonnes qui ne se valent pas et ne prétendent pas se     */
/*      valoir : celle de gauche reste sourde, la nôtre est posée sur  */
/*      le verre du club avec son arête d'encre.                       */
/* ================================================================== */

.ecart {
  display: grid;
  gap: var(--pas-3);
  margin-top: var(--pas-4);
}

/* Un pictogramme en trait fin coiffe chaque colonne : la raquette pour le jeu,
   le verre pour la table. Il prend l'accent de sa colonne (sourd à gauche,
   bleu nuit à droite). */
.ecart__picto {
  --picto-taille: 30px;
  display: block;
  width: 30px;
  height: 30px;
  margin-bottom: var(--pas-2);
  color: var(--ivoire-3);
}

.ecart__colonne--nous .ecart__picto {
  color: var(--tranche);
}

.ecart__colonne {
  position: relative;
  padding: var(--pas-4) var(--pas-3);
  border: 1px solid var(--bord);
  border-radius: 4px;
}

.ecart__titre {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

.ecart__colonne ul {
  margin-top: var(--pas-3);
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.7rem;
}

.ecart__colonne li {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

.ecart__colonne li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 8px;
  height: 1px;
  background: var(--ivoire-3);
}

.ecart__colonne--nous {
  background: var(--verre);
  border-color: var(--bord-fort);
}

.ecart__colonne--nous::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 3px;
  height: 100%;
  background: var(--tranche);
}

.ecart__colonne--nous .ecart__titre {
  color: var(--tranche);
}

.ecart__colonne--nous li {
  color: var(--ivoire);
}

.ecart__colonne--nous li::before {
  background: var(--tranche);
}

.ecart__note {
  margin-top: var(--pas-4);
  font-family: var(--parole);
  font-style: italic;
  font-size: clamp(1.0625rem, 1.8vw, 1.25rem);
  line-height: 1.5;
  color: var(--ivoire);
  max-width: 40rem;
}

@media (min-width: 48rem) {
  .ecart {
    grid-template-columns: 1fr 1fr;
    gap: var(--pas-4);
  }
}

/* --- Ce que LE 15 apporte, sur sa porte : la raison d'y aller. --- */
.porte-15__gains {
  display: grid;
  gap: 0.7rem;
  margin-top: var(--pas-3);
  margin-bottom: var(--pas-2);
  text-align: left;
  max-width: 30rem;
}

.porte-15__gains p {
  position: relative;
  padding-left: 1.35rem;
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

.porte-15__gains p::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.68em;
  width: 8px;
  height: 1px;
  background: var(--tranche);
}

.porte-15__gains span {
  color: var(--ivoire);
  font-weight: 600;
}

/* ================================================================== */
/*  28. Les formats — les façons de venir                              */
/*                                                                      */
/*      Un carrousel éditorial : une seule façon de venir en scène à   */
/*      la fois, la photographie en grand à gauche, le texte et le     */
/*      sommaire nommé à droite. Le passage d'un volet à l'autre est   */
/*      un ESSUYAGE — la page suivante se découvre par-dessus la       */
/*      précédente — pas un glissement de cartes.                      */
/*                                                                      */
/*      Les cinq volets sont superposés au même endroit de la grille : */
/*      la hauteur de la scène est celle du plus long, donc rien ne    */
/*      saute jamais au changement.                                     */
/* ================================================================== */

/* Le texte réservé aux lecteurs d'écran. */
.hors-vue {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.carrousel {
  /* Les colonnes et l'écart sont posés UNE fois ici : la scène et chaque
     volet s'en resservent, ce qui garantit que la conduite tombe pile
     sous la colonne de texte. */
  --carr-colonnes: minmax(0, 1fr);
  --carr-gap: var(--pas-3);

  /* Le sens de l'essuyage. Le comportement bascule l'attribut ; c'est
     cette variable qui dit d'où arrive le volet entrant. */
  --carr-entree: inset(0 0 0 100%);

  display: grid;
  grid-template-columns: var(--carr-colonnes);
  gap: var(--carr-gap);
  margin-top: var(--pas-4);
}

.carrousel[data-sens="precedent"] {
  --carr-entree: inset(0 100% 0 0);
}

.carrousel__scene {
  display: grid;
  grid-column: 1 / -1;
}

/* ---------------------------------------------------------------- */
/*  Le volet                                                         */
/* ---------------------------------------------------------------- */

.volet {
  grid-area: 1 / 1; /* tous les volets au même endroit */
  display: grid;
  grid-template-columns: var(--carr-colonnes);
  gap: var(--carr-gap);
  visibility: hidden;
  z-index: 0;
}

/* Le volet en scène. */
.volet.est-la {
  visibility: visible;
  z-index: 2;
}

/* Le volet qui sort : il reste entier et visible SOUS l'entrant le
   temps de l'essuyage, puis il disparaît d'un coup. */
.volet.sort {
  visibility: visible;
  z-index: 1;
}

/* --- La photographie --- */

.volet__vue {
  position: relative;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--encre-2);
  border: 1px solid var(--bord);
  border-radius: 3px;
  clip-path: var(--carr-entree);
  transition: clip-path var(--lent) var(--sortie),
    border-color var(--normal) var(--doux);
}

.volet.est-la .volet__vue,
.volet.sort .volet__vue {
  clip-path: inset(0 0 0 0);
}

.volet__vue img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Le souffle, seulement sur la photographie en scène : trente secondes
   pour un aller. On ne la voit pas bouger, on la sent vivre. La valeur
   est prise entre les 28 s de l'ouverture et les 34 s des bandes, pour
   que deux images voisines ne battent jamais à l'unisson. */
.volet.est-la .volet__vue img {
  transform-origin: 55% 50%;
  animation: souffle 30s ease-in-out infinite alternate;
  will-change: transform;
}

/* --- La colonne de texte --- */

.volet__dire {
  align-self: end;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity var(--vite) var(--doux),
    transform var(--vite) var(--doux);
}

.volet.est-la .volet__dire {
  opacity: 1;
  transform: translateY(0);
  transition: opacity var(--normal) var(--sortie) 80ms,
    transform var(--normal) var(--sortie) 80ms;
}

/* Le grand numéro : l'unique audace de la section. Tout le reste
   autour reste calme. */
.volet__rang {
  font-family: var(--titre);
  font-size: clamp(3.25rem, 6vw, 5rem);
  line-height: 0.85;
  letter-spacing: -0.02em;
  color: var(--numero-fantome);
}

.volet__filet {
  height: 1px;
  margin: var(--pas-3) 0;
  border: 0;
  background: var(--bord-fort);
}

.volet__dire h3 {
  font-size: clamp(1.75rem, 3vw, 2.375rem);
  line-height: 1.1;
}

.volet__quand {
  margin-top: 0.75rem;
  font-family: var(--corps);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ivoire-3);
}

.volet__texte {
  margin-top: var(--pas-2);
  font-size: 0.9375rem;
  color: var(--ivoire-2);
}

/* --- Celui du 15 : trois touches, aucun aplat. --- */

.volet--rare .volet__vue {
  border-color: var(--tranche);
}

.volet--rare .volet__rang {
  color: var(--tranche-voile);
}

.volet--rare .volet__quand {
  color: var(--tranche);
}

/* ---------------------------------------------------------------- */
/*  La conduite : le sommaire, puis le compteur et les flèches       */
/* ---------------------------------------------------------------- */

.carrousel__conduite {
  grid-column: 1 / -1;
}

.sommaire {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--bord);
}

.somm {
  display: flex;
  align-items: baseline;
  gap: var(--pas-2);
  width: 100%;
  padding: 0.75rem 0 0.6875rem;
  border: 0;
  border-bottom: 1px solid var(--bord);
  background: none;
  text-align: left;
  cursor: pointer;
  color: var(--ivoire-2);
  transition: color var(--vite) var(--doux),
    transform var(--vite) var(--doux);
}

.somm__rang {
  flex: none;
  font-family: var(--corps);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ivoire-3);
  transition: color var(--vite) var(--doux);
}

/* Le nom, et sous lui le filet qui pousse quand le volet est en scène. */
.somm__nom {
  position: relative;
  flex: 1;
  font-family: var(--titre);
  font-size: 1.0625rem;
  line-height: 1.25;
}

.somm__nom::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 0;
  height: 1px;
  background: var(--tranche);
  transition: width var(--lent) var(--sortie),
    background var(--vite) var(--doux);
}

.somm[aria-current="true"] {
  color: var(--ivoire);
}

.somm[aria-current="true"] .somm__rang {
  color: var(--tranche);
}

.somm[aria-current="true"] .somm__nom::after {
  width: 100%;
}

.somm:focus-visible {
  outline: 1px solid var(--tranche);
  outline-offset: 4px;
}

/* Le sceau du cercle fermé, et le filet qui détache son entrée. */
.somm--rare {
  margin-top: var(--pas-1);
  border-top: 1px solid var(--bord);
}

.somm__sceau {
  flex: none;
  align-self: center;
  font-family: var(--corps);
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tranche);
  border: 1px solid var(--tranche-voile);
  border-radius: 2px;
  padding: 0.25rem 0.4375rem;
}

/* --- Le compteur et les deux flèches --- */

.carrousel__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pas-3);
  margin-top: var(--pas-3);
}

.carrousel__compte {
  font-family: var(--corps);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ivoire-3);
}

.carrousel__compte-n {
  color: var(--ivoire);
}

/* Deux boutons carrés accolés, séparés par un filet. Pas de chevrons
   ronds flottant sur la photographie : ici on est dans un magazine,
   pas dans une boutique. */
.carrousel__fleches {
  display: flex;
  border: 1px solid var(--bord);
  border-radius: 3px;
  overflow: hidden;
}

.fleche {
  display: grid;
  place-items: center;
  width: 2.875rem;
  height: 2.625rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ivoire);
  cursor: pointer;
  transition: color var(--vite) var(--doux),
    background var(--vite) var(--doux),
    transform var(--vite) var(--doux);
}

.fleche + .fleche {
  border-left: 1px solid var(--bord);
}

.fleche svg {
  width: 17px;
  height: 17px;
}

.fleche:focus-visible {
  outline: 1px solid var(--tranche);
  outline-offset: -3px;
}

/* ---------------------------------------------------------------- */
/*  Survols : réservés au vrai pointeur                              */
/* ---------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
  .somm:hover {
    color: var(--ivoire);
  }

  .somm:hover .somm__nom::after {
    width: 40%;
    background: var(--tranche-sourd);
  }

  .somm[aria-current="true"]:hover .somm__nom::after {
    width: 100%;
    background: var(--tranche);
  }

  .fleche:hover {
    color: var(--tranche);
    background: var(--verre);
  }
}

.somm:active,
.fleche:active {
  transform: scale(0.97);
}

/* ---------------------------------------------------------------- */
/*  Écrans larges : le diptyque se déploie                           */
/* ---------------------------------------------------------------- */

@media (min-width: 48rem) {
  .carrousel {
    --carr-colonnes: minmax(0, 1.35fr) minmax(0, 1fr);
    --carr-gap: clamp(2rem, 4vw, 3.5rem);
  }

  /* Le vrai diptyque : la conduite ne descend PAS sous la photographie,
     elle se cale en pied de la colonne de droite, dans la même rangée.
     Sans ça, la moitié gauche se retrouve avec un grand vide sous
     l'image — l'accident qui trahit la mise en page bricolée. */
  .carrousel__scene {
    grid-row: 1;
    min-height: 30rem;
  }

  .carrousel__conduite {
    grid-column: 2;
    grid-row: 1;
    z-index: 3;
    align-self: end;
    margin-top: 0;
  }

  /* La photographie prend alors toute la hauteur du diptyque. */
  .volet__vue {
    aspect-ratio: auto;
    height: 100%;
  }

  /* Le texte se réserve, sous lui, la place exacte qu'occupe la conduite
     (mesurée au chargement). C'est ce qui empêche les deux de se
     chevaucher, quelle que soit la longueur du texte. */
  .volet__dire {
    align-self: start;
    padding-bottom: calc(var(--carr-conduite, 24rem) + var(--pas-4));
  }

  .somm__nom {
    font-size: 1.125rem;
  }
}

@media (min-width: 64rem) {
  .carrousel {
    --carr-colonnes: minmax(0, 1.55fr) minmax(0, 1fr);
  }
}

/* ---------------------------------------------------------------- */
/*  Mouvement réduit : tout se fige, rien ne se casse                */
/* ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .volet__vue {
    clip-path: none !important;
  }

  .volet.est-la .volet__vue img {
    animation: none;
  }

  .volet__dire {
    transform: none;
  }

  .somm:active,
  .fleche:active {
    transform: none;
  }
}

/* --- La discrétion, désormais sur la page du 15 --- */
.quinze__discretion {
  margin-top: var(--pas-5);
  padding-top: var(--pas-4);
  border-top: 1px solid var(--bord);
  text-align: left;
  max-width: 32rem;
}

.quinze__discretion-titre {
  font-family: var(--titre);
  font-size: 1.25rem;
  color: var(--ivoire);
  margin-bottom: var(--pas-2);
}

.quinze__discretion p:not(.quinze__discretion-titre) {
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--ivoire-2);
}

.quinze__discretion p + p {
  margin-top: var(--pas-2);
}

/* Lien « Se connecter » : posé dans la zone d'actions (à droite, près du
   bouton clair/sombre), séparé des liens de sections pour ne pas surcharger
   la navigation. Masqué en mobile — il est déjà dans le tiroir — et révélé
   au même point de rupture que la navigation de bureau. */
.lien-acces {
  display: none;
}

@media (min-width: 62rem) {
  /* Chaque libellé de la barre reste sur UNE seule ligne : jamais de coupure
     « Le / principe ». L'espacement de la navigation se resserre juste ce
     qu'il faut pour que l'ensemble (liens + candidature + « Se connecter »)
     tienne sur une ligne, même sur les écrans de bureau les plus étroits. */
  .nav {
    gap: clamp(0.55rem, 1.4vw, 1.6rem);
  }

  .nav__lien,
  .bouton__corps {
    white-space: nowrap;
  }

  .lien-acces {
    display: inline-flex;
    margin-inline: 0.4rem 0.5rem;
    white-space: nowrap;
  }
}

/* ================================================================== */
/*  29. Le sceau « LE 15 »                                              */
/*                                                                      */
/*      Le logo du cercle fermé : une plaque bleu nuit gravée, « LE »   */
/*      en petites capitales espacées au-dessus, « 15 » en grand dans   */
/*      la serif Frank Ruhl, encadré de deux filets clairs — écho des   */
/*      lignes du court. Ses couleurs sont FIXES (identité de marque) : */
/*      elles ne suivent pas la bascule clair/sombre du site.           */
/* ================================================================== */

.plaque-15 {
  --plaque-fond: #1e3a5f; /* bleu nuit de la marque */
  --plaque-encre: #ece7d8; /* crème gravé */
  --plaque-num: 2.9rem;
  --plaque-le: 0.72rem;

  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  padding: 1.05rem 1.5rem 1.2rem;
  background: var(--plaque-fond);
  color: var(--plaque-encre);
  border-radius: 3px;
  font-family: "Frank Ruhl Libre", Georgia, "Times New Roman", serif;
  line-height: 1;
  user-select: none;
}

.plaque-15__le {
  font-size: var(--plaque-le);
  font-weight: 500;
  letter-spacing: 0.44em;
  text-indent: 0.44em; /* recompense l'espacement pour recentrer « LE » */
  opacity: 0.92;
}

.plaque-15__num {
  position: relative;
  font-size: var(--plaque-num);
  font-weight: 500;
  letter-spacing: 0.03em;
  padding-inline: 0.62em;
}

/* Les deux filets verticaux qui encadrent le nombre. */
.plaque-15__num::before,
.plaque-15__num::after {
  content: "";
  position: absolute;
  top: 9%;
  bottom: 9%;
  width: 1px;
  background: currentColor;
  opacity: 0.34;
}

.plaque-15__num::before {
  left: 0;
}

.plaque-15__num::after {
  right: 0;
}

/* Grand format, pour la page dédiée du 15. */
.plaque-15--grand {
  --plaque-num: 3.7rem;
  --plaque-le: 0.82rem;
  padding: 1.3rem 1.9rem 1.5rem;
}

/* Posée sur un fond sombre (la page du 15) : un liseré clair la détache. */
.plaque-15--sombre {
  border: 1px solid var(--bord);
}

/* Sur la porte de l'accueil, la plaque remplace l'ancien monogramme :
   elle se soulève d'un cheveu au survol, comme les autres éléments. */
.porte-15__plaque {
  /* Sur la porte de l'accueil, le sceau est un cran plus grand pour qu'il
     ressorte franchement dans sa carte. */
  --plaque-num: 3.3rem;
  --plaque-le: 0.78rem;
  margin: 0 0 var(--pas-2);
  transition: transform var(--lent) var(--sortie),
    box-shadow var(--lent) var(--doux);
}

.porte-15:hover .porte-15__plaque {
  transform: translateY(-3px);
  box-shadow: 0 18px 40px -24px rgba(28, 42, 74, 0.6);
}

@media (prefers-reduced-motion: reduce) {
  .porte-15:hover .porte-15__plaque {
    transform: none;
  }
}

/* ================================================================== */
/*  29 bis bis. LE PLAN D'OUVERTURE                                     */
/*                                                                      */
/*      En attendant un vrai film, la photographie du haut de page est  */
/*      traitée comme un plan de cinéma. Trois gestes superposés, sur   */
/*      des durées qui ne tombent jamais juste — de sorte qu'on ne      */
/*      puisse jamais y lire de boucle :                                */
/*                                                                      */
/*        1. LE TRAVELLING — la caméra glisse lentement vers la droite  */
/*           en s'approchant. C'est le fond du mouvement.               */
/*        2. LA LUMIÈRE QUI PASSE — un reflet chaud très diffus         */
/*           traverse l'image en biais, comme le soleil sur le verre    */
/*           du court. C'est ÇA qu'on voit : la leçon de la houle est   */
/*           qu'un glissement seul reste invisible, une variation de    */
/*           lumière non.                                               */
/*        3. LE GRAIN — un voile de pellicule très fin qui frémit.      */
/*           Imperceptible seul, il enlève l'aspect « photo figée ».    */
/*                                                                      */
/*      Tout est en déplacement et en opacité : porté par la carte      */
/*      graphique, donc gratuit. Tout se fige pour qui a demandé moins  */
/*      de mouvement — la photographie reste alors belle, simplement    */
/*      immobile.                                                       */
/* ================================================================== */

.ouverture--photo .ouverture__fond {
  overflow: hidden;
}

.ouverture--photo .ouverture__fond img {
  transform-origin: 58% 52%;
  animation: plan-travelling 38s ease-in-out infinite alternate;
  will-change: transform;
}

@keyframes plan-travelling {
  from {
    transform: scale(1.06) translate3d(-2.2%, -1%, 0);
  }
  to {
    transform: scale(1.15) translate3d(2.6%, 1.2%, 0);
  }
}

/* La lumière qui passe. Elle traverse tout le cadre en biais puis
   disparaît, et revient. Son opacité monte et retombe à l'intérieur du
   trajet : jamais d'apparition ni de coupure franche sur un bord. */
.ouverture--photo .ouverture__fond::after {
  content: "";
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: 0;
  width: 46%;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 232, 190, 0.1) 34%,
    rgba(255, 240, 214, 0.17) 50%,
    rgba(255, 232, 190, 0.1) 66%,
    transparent 100%
  );
  transform: translate3d(-120%, 0, 0) rotate(9deg);
  animation: plan-lumiere 21s ease-in-out infinite;
  will-change: transform, opacity;
}

@keyframes plan-lumiere {
  0% {
    transform: translate3d(-120%, 0, 0) rotate(9deg);
    opacity: 0;
  }
  18% {
    opacity: 1;
  }
  78% {
    opacity: 1;
  }
  100% {
    transform: translate3d(320%, 0, 0) rotate(9deg);
    opacity: 0;
  }
}

/* Le grain de pellicule : un bruit très fin, dessiné une fois et jamais
   rechargé, qui se déplace de quelques pixels. Il ne se voit pas — il
   s'entend, si l'on peut dire : l'image cesse d'avoir l'air d'un aplat. */
.ouverture--photo .ouverture__voile::after {
  content: "";
  position: absolute;
  inset: -6%;
  pointer-events: none;
  opacity: 0.42;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23g)' opacity='0.42'/%3E%3C/svg%3E");
  animation: plan-grain 1.6s steps(4) infinite;
  will-change: transform;
}

@keyframes plan-grain {
  0% {
    transform: translate3d(0, 0, 0);
  }
  25% {
    transform: translate3d(-2%, 1%, 0);
  }
  50% {
    transform: translate3d(1%, -2%, 0);
  }
  75% {
    transform: translate3d(-1%, -1%, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

/* Le grain est le seul des trois gestes qui coûte quelque chose : sa façon
   de se fondre à l'image oblige le téléphone à recomposer tout l'écran à
   chaque image. Or c'est justement là qu'il ne se voit pas — l'écran est
   trop petit et la densité de points trop élevée. On le retire donc en
   dessous d'une tablette : on ne perd rien, on économise beaucoup. */
@media (max-width: 48rem) {
  .ouverture--photo .ouverture__voile::after {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ouverture--photo .ouverture__fond img {
    animation: none;
    transform: scale(1.06);
  }

  .ouverture--photo .ouverture__fond::after {
    animation: none;
    opacity: 0;
  }

  .ouverture--photo .ouverture__voile::after {
    animation: none;
  }
}

/* ================================================================== */
/*  29 ter. Les pictogrammes qui se dessinent                           */
/*                                                                      */
/*      Chaque pictogramme est un dessin au trait qui se TRACE quand    */
/*      sa section entre à l'écran, comme une main qui l'écrirait.      */
/*      C'est le geste des génériques de film : lent, net, sans effet.  */
/*                                                                      */
/*      Comment ça tient : chaque trait porte une longueur déclarée à   */
/*      1 (l'attribut pathLength dans le dessin). On peut alors le      */
/*      masquer entièrement puis le découvrir, sans avoir à connaître   */
/*      sa vraie longueur — la même règle marche pour un cercle comme   */
/*      pour une courbe compliquée.                                     */
/*                                                                      */
/*      Les points pleins (une poignée, une balle) n'ont pas de tracé : */
/*      ils se posent en fondu, une fois le dessin fini.                */
/* ================================================================== */

.picto {
  display: block;
  width: var(--picto-taille, 26px);
  height: var(--picto-taille, 26px);
  color: var(--ivoire-3);
  flex: none;
}

.picto [stroke] {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1000ms cubic-bezier(0.65, 0, 0.35, 1);
}

.picto [fill="currentColor"] {
  opacity: 0;
  transition: opacity 420ms var(--doux) 760ms;
}

.est-la .picto [stroke],
.picto.est-la [stroke] {
  stroke-dashoffset: 0;
}

.est-la .picto [fill="currentColor"],
.picto.est-la [fill="currentColor"] {
  opacity: 1;
}

/* Les traits d'un même dessin ne partent pas ensemble : le contour
   d'abord, les détails ensuite. C'est ce décalage qui donne l'impression
   d'une main, et non d'un rideau qui se lève. */
.picto [stroke]:nth-child(2) {
  transition-delay: 180ms;
}

.picto [stroke]:nth-child(3) {
  transition-delay: 340ms;
}

.picto [stroke]:nth-child(4) {
  transition-delay: 480ms;
}

/* Moins de mouvement : le dessin est là, entier, tout de suite. */
@media (prefers-reduced-motion: reduce) {
  .picto [stroke] {
    stroke-dashoffset: 0;
  }

  .picto [fill="currentColor"] {
    opacity: 1;
  }
}

/* ================================================================== */
/*  29 bis. La houle du fond                                            */
/*                                                                      */
/*      L'ivoire de la page n'est plus tout à fait immobile : deux      */
/*      nappes de lumière très diluées y dérivent l'une contre l'autre, */
/*      en sens inverse, sur plus d'une minute chacune. On ne voit pas  */
/*      le mouvement — on sent que la page respire.                     */
/*                                                                      */
/*      Trois exigences tenues :                                        */
/*        — INVISIBLE À L'ARRÊT. Les nappes sont si diluées qu'on ne    */
/*          peut pas dire où elles se trouvent sur une image figée.     */
/*        — GRATUIT. Rien que des déplacements, portés par la carte     */
/*          graphique : aucune redécoupe de la page, aucun calcul à     */
/*          chaque image. C'est ce qui permet de la laisser tourner en  */
/*          continu sans chauffer un téléphone.                         */
/*        — DERRIÈRE TOUT. Les nappes sont fixées à l'écran et ne       */
/*          défilent pas avec la page : c'est une atmosphère, pas un    */
/*          décor qui suit.                                             */
/* ================================================================== */

body::before,
body::after {
  content: "";
  position: fixed;
  /* Elles débordent juste ce qu'il faut : en dérivant et en respirant, leur
     propre bord ne doit jamais apparaître sur un côté de l'écran. Le calcul
     est serré exprès — ces deux calques vivent en mémoire vidéo en
     permanence, et un débord généreux se paierait sur les téléphones les
     plus modestes. Déplacement maximal : 8 % + 9 % de respiration. */
  inset: -26%;
  z-index: -1;
  pointer-events: none;
  will-change: transform;
}

/* La première nappe : la houle froide, large et basse, comme une lame de
   fond qui traverse l'écran de la gauche vers la droite. */
body::before {
  background-image:
    radial-gradient(
      70% 34% at 22% 34%,
      var(--houle-froide) 0%,
      transparent 68%
    ),
    radial-gradient(
      58% 28% at 78% 72%,
      var(--houle-froide) 0%,
      transparent 66%
    );
  /* Deux gestes à la fois, sur des durées différentes : la nappe DÉRIVE, et
     elle RESPIRE (elle s'éclaire et se retire). Le glissement seul ne se
     voyait pas — un dégradé sans contour ne donne rien à suivre à l'œil.
     La variation de lumière, elle, se remarque : c'est elle qui fait qu'on
     sent le fond vivre. */
  animation:
    houle-avant var(--houle-derive-a) ease-in-out infinite alternate,
    respire-avant var(--houle-souffle-a) ease-in-out infinite alternate;
}

/* La seconde : la houle chaude, plus haute et plus courte, qui remonte en
   sens inverse. Deux vitesses qui ne tombent jamais juste — c'est ce
   décalage qui empêche l'œil d'attraper un cycle. */
body::after {
  background-image:
    radial-gradient(
      62% 30% at 68% 22%,
      var(--houle-chaude) 0%,
      transparent 70%
    ),
    radial-gradient(
      52% 26% at 26% 82%,
      var(--houle-chaude) 0%,
      transparent 66%
    );
  animation:
    houle-arriere var(--houle-derive-b) ease-in-out infinite alternate,
    respire-arriere var(--houle-souffle-b) ease-in-out infinite alternate;
}

@keyframes houle-avant {
  from {
    transform: translate3d(-7%, -4%, 0) scale(1);
  }
  to {
    transform: translate3d(8%, 4.6%, 0) scale(1.18);
  }
}

@keyframes houle-arriere {
  from {
    transform: translate3d(7.6%, 4.2%, 0) scale(1.16);
  }
  to {
    transform: translate3d(-8%, -3.6%, 0) scale(1);
  }
}

/* La respiration : la nappe passe de presque effacée à pleine. C'est ce
   qu'on remarque en premier — bien avant le glissement. Quatre durées qui
   ne tombent jamais juste (dérive et souffle, avant et arrière) : la
   combinaison ne se répète qu'au bout de plusieurs dizaines de minutes,
   donc on ne peut pas y lire de boucle. */
@keyframes respire-avant {
  from {
    opacity: 0.45;
  }
  to {
    opacity: 1;
  }
}

@keyframes respire-arriere {
  from {
    opacity: 1;
  }
  to {
    opacity: 0.4;
  }
}

/* Moins de mouvement : la houle se fige. Les nappes restent — le fond garde
   sa profondeur — mais plus rien ne dérive. */
@media (prefers-reduced-motion: reduce) {
  body::before,
  body::after {
    animation: none;
  }
}

/* ================================================================== */
/*  29 quater. L'arrivée sur la page du 15                              */
/*                                                                      */
/*      Le film se termine sur la lumière du couloir. Cette page s'ouvre */
/*      SOUS cette même lumière, qui se retire — d'où l'impression       */
/*      d'être entré, et non d'avoir changé de page.                     */
/*                                                                      */
/*      Le voile est posé dans le code de la page, pas ajouté par le    */
/*      script : il doit être là dès le premier rendu, sinon on          */
/*      apercevrait la page nue le temps d'un battement de cil.          */
/* ================================================================== */

/* ⚠️ Le voile n'existe QUE si la page a reconnu qu'on arrivait par la
   porte. Sans cette précaution, une page ouverte sans script actif
   resterait blanche pour toujours — le voile n'ayant personne pour le
   retirer. La règle par défaut est donc « pas de voile ». */
.entree-15 {
  display: none;
}

.vient-de-la-porte .entree-15 {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 120;
  /* Exactement la couleur du voile de fin du passage, et exactement celle
     du fond de cette page : les trois se confondent, donc le changement de
     page ne se voit pas. */
  background: var(--arrivee-15);
  pointer-events: none;
  opacity: 1;
  transition: opacity 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}

.vient-de-la-porte .entree-15[hidden] {
  display: none;
}

.entree-15.est-partie {
  opacity: 0;
}

/* Ce qui se pose une fois la lumière retirée. Tant que la page n'a pas
   déclaré qu'on venait de la porte, RIEN n'est masqué : une page ouverte
   par un lien direct ne doit jamais rester blanche si le script échoue. */
.vient-de-la-porte .surgit {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 900ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 1000ms cubic-bezier(0.22, 1, 0.28, 1);
}

.vient-de-la-porte .surgit.est-la {
  opacity: 1;
  transform: none;
}

/* La porte arrive la première, et d'un peu plus loin : c'est elle qu'on
   vient de franchir, et c'est elle qu'on retrouve. */
.vient-de-la-porte .quinze__porte.surgit {
  transform: translateY(26px) scale(0.94);
  transition-duration: 1100ms;
}

.vient-de-la-porte .quinze__porte.surgit.est-la {
  transform: none;
}

/* La sortie ne se donne pas tout de suite : on laisse la page s'installer
   avant de montrer par où repartir. */
.vient-de-la-porte .quinze__sortie.surgit {
  transition-delay: 1100ms;
}

/* Le filet se TRACE, du centre vers les deux bords. */
.vient-de-la-porte .quinze__filet.surgit {
  transform: scaleX(0);
  transition: transform 1200ms cubic-bezier(0.22, 1, 0.28, 1) 260ms,
    opacity 600ms var(--doux) 260ms;
}

.vient-de-la-porte .quinze__filet.surgit.est-la {
  transform: scaleX(1);
}

/* Chacun son tour, dans l'ordre de lecture. */
.vient-de-la-porte .quinze__etat.surgit {
  transition-delay: 120ms;
}

.vient-de-la-porte .quinze__phrase.surgit {
  transition-delay: 420ms;
}

.vient-de-la-porte .quinze__points.surgit {
  transition-delay: 580ms;
}

.vient-de-la-porte .quinze__discretion.surgit {
  transition-delay: 740ms;
}

.vient-de-la-porte .quinze__note.surgit {
  transition-delay: 860ms;
}

.vient-de-la-porte .quinze__retour.surgit {
  transition-delay: 980ms;
}

/* Les trois points du cercle se posent l'un après l'autre, et non en bloc. */
.vient-de-la-porte .surgit--suite > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 800ms var(--doux), transform 900ms cubic-bezier(0.22, 1, 0.28, 1);
}

.vient-de-la-porte .surgit--suite.est-la > *:nth-child(1) {
  transition-delay: 620ms;
}

.vient-de-la-porte .surgit--suite.est-la > *:nth-child(2) {
  transition-delay: 760ms;
}

.vient-de-la-porte .surgit--suite.est-la > *:nth-child(3) {
  transition-delay: 900ms;
}

.vient-de-la-porte .surgit--suite.est-la > * {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .entree-15 {
    display: none;
  }

  .vient-de-la-porte .surgit,
  .vient-de-la-porte .surgit--suite > * {
    opacity: 1;
    transform: none;
  }
}

/* ================================================================== */
/*  30. L'enseigne du 15 : la porte, fermée                             */
/*                                                                      */
/*      Sur l'accueil, le sceau gravé cède la place à la porte elle-    */
/*      même — celle du film. On la voit fermée ; un clic l'ouvre.      */
/*      Ses couleurs sont celles de la marque, donc elle ne suit pas    */
/*      la bascule clair/sombre : c'est un objet, pas une surface.      */
/* ================================================================== */

.porte-15__enseigne {
  margin: 0 0 var(--pas-2);
  line-height: 0; /* pas de blanc parasite sous l'image */
}

.porte-15__battant {
  display: inline-block;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid rgba(28, 42, 74, 0.18);
  box-shadow: 0 14px 34px -26px rgba(28, 42, 74, 0.5);
  transition: transform var(--lent) var(--sortie),
    box-shadow var(--lent) var(--doux);
  /* Aucune surbrillance au moment du clic : le navigateur en pose une par
     défaut sur les liens tactiles, et elle éclaircissait la porte pendant
     la fraction de seconde qui précède le passage. */
  -webkit-tap-highlight-color: transparent;
}

.porte-15__battant:active {
  background: transparent;
}

.porte-15__battant img {
  display: block;
  width: clamp(10.5rem, 26vw, 14.5rem);
  height: auto;
}

/* Toute la carte réagit d'un seul geste : survoler le lien du bas soulève
   la porte, et inversement. On ne se demande jamais où cliquer. */
.porte-15:hover .porte-15__battant,
.porte-15__battant:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 22px 46px -24px rgba(28, 42, 74, 0.62);
}

/* ================================================================== */
/*  31. Le passage de la porte                                          */
/*                                                                      */
/*      Au clic, la page s'efface derrière un voile de la couleur du    */
/*      site, la porte s'ouvre en grand, et la lumière du couloir prend */
/*      toute la place avant que la page du 15 n'arrive. Trois          */
/*      secondes, une seule fois, et on peut couper court d'un clic.    */
/* ================================================================== */

/* La couleur de l'arrivée : celle du fond de la page du 15, et rien
   d'autre. C'est elle qui fait la couture de la fin du passage.

   ⚠️ Erreur à ne pas refaire : on avait pris ici la couleur claire du
   couloir. Le film finit clair, le voile montait clair, puis la page du 15
   — qui est sombre — arrivait : cela donnait un clair, sombre, clair très
   désagréable. La règle est simple : LE VOILE DE FIN A LA COULEUR DE LA
   PAGE OÙ L'ON VA. La lumière du couloir s'éteint doucement pendant qu'on
   entre, et le cercle fermé apparaît dans sa pénombre. */
:root {
  --arrivee-15: var(--encre);
}

/* ⚠️ Le voile ne porte PAS l'opacité lui-même : c'est son fond, posé en
   calque séparé, qui monte. Sinon le film — qui vit dedans — monterait avec
   lui : il restait invisible pendant le premier dixième de seconde alors
   que la porte de la page était déjà masquée, et ce trou laissait voir le
   fond clair de la carte. C'était l'éclair blanc au moment du clic. */
.passage {
  position: fixed;
  inset: 0;
  z-index: 200;
  cursor: pointer;
}

.passage::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--encre);
  opacity: 0;
  transition: opacity 440ms var(--doux);
}

.passage.est-ouvert::before {
  opacity: 1;
}

/* ⚠️ Sans cette ligne, le voile reste étendu sur toute la page — invisible,
   mais il avale TOUS les clics. Une règle d'affichage écrite ici l'emporte
   sur le masquage que le navigateur applique d'ordinaire à un élément caché :
   il faut donc le redire nous-mêmes, explicitement. */
.passage[hidden] {
  display: none;
}

/* Le film n'est pas posé au centre par la mise en page : c'est le script
   qui le place, au pixel près, SUR la petite porte de la page — puis le
   fait grandir jusqu'à sa taille d'écran. C'est ce qui donne le sentiment
   d'entrer DANS la porte qu'on vient de regarder, au lieu de voir surgir
   une vidéo par-dessus la page. */
.passage__film {
  position: fixed;
  margin: 0;
  object-fit: cover;
  border-radius: 4px;
  transform-origin: top left;
  will-change: transform;
  backface-visibility: hidden;
  /* ⚠️ Filet contre l'éclair blanc du clic. Pendant la première image, une
     vidéo qui n'a pas encore peint quoi que ce soit est TRANSPARENTE : on
     voyait alors le voile clair au travers, juste à l'endroit de la porte.
     Ce fond met la porte fermée derrière la vidéo — il n'y a plus de trou
     possible, et il disparaît sous la première image du film. */
  background: url("../images/porte-15-depart.jpg") center / cover no-repeat;
}

/* L'AGRANDISSEMENT — c'est le geste le plus important du passage, et il
   doit prendre son temps : une seconde et demie. Trop court, on ne le vit
   pas comme une approche, on le subit comme un surgissement. La courbe part
   franchement puis s'installe très longuement : on avance d'un pas, et on
   s'arrête devant la porte. */
.passage__film.avance {
  /* ⚠️ La courbe compte autant que la durée. Une courbe qui part vite
     (type 0.2, 0.9) avale 80 % du chemin dans le premier quart du temps :
     on allonge la durée et ça reste « trop rapide », parce que le
     mouvement, lui, est déjà fini. Celle-ci démarre doucement, tient le
     milieu, et s'installe longuement — le pas en avant se voit du début
     à la fin. */
  transition: transform 1500ms cubic-bezier(0.45, 0.05, 0.25, 1);
}

/* Le voile de fin : il a la couleur de la page où l'on va, pas celle du
   couloir qu'on quitte. Il monte pendant qu'on avance encore, si bien que
   la lumière du couloir s'éteint dans le mouvement même. */
.passage__lumiere {
  position: absolute;
  inset: 0;
  background: var(--arrivee-15);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1000ms cubic-bezier(0.4, 0, 0.2, 1);
}

.passage.est-entree .passage__lumiere {
  opacity: 1;
}

/* Le dernier pas : on avance dans le couloir pendant que la lumière monte.
   Le déplacement exact est calculé par le script — le point de départ du
   film étant son coin, un simple agrandissement partirait de travers. */
.passage__film.entre {
  transition: transform 1100ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Moins de mouvement : aucun passage, aucun film. Le lien redevient un lien
   ordinaire et la page du 15 s'ouvre directement. */
@media (prefers-reduced-motion: reduce) {
  .porte-15:hover .porte-15__battant {
    transform: none;
  }

  .passage {
    display: none;
  }
}

/* ================================================================== */
/*  32. Les questions fréquentes                                       */
/*      Une liste de filets fins, comme un sommaire de carton          */
/*      d'invitation : la question en serif, son rang en petit, et un  */
/*      signe « + » qui devient « − ». Le repli est celui du           */
/*      navigateur (details/summary) — aucun script, et le clavier y   */
/*      accède sans qu'on ait rien à écrire.                           */
/* ================================================================== */

.questions {
  margin-top: var(--pas-4);
  border-top: 1px solid var(--bord);
}

.question {
  border-bottom: 1px solid var(--bord);
}

/* Le marqueur natif (triangle) est retiré : le signe « + » le remplace. */
.question__titre {
  display: grid;
  grid-template-columns: 2.5rem 1fr auto;
  align-items: baseline;
  gap: var(--pas-2);
  padding-block: var(--pas-3);
  cursor: pointer;
  list-style: none;
  color: var(--ivoire);
  transition: color var(--normal) var(--doux);
}

.question__titre::-webkit-details-marker {
  display: none;
}

.question__rang {
  font-family: var(--chiffres);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--ivoire-3);
  font-variant-numeric: tabular-nums;
  transition: color var(--normal) var(--doux);
}

.question__mot {
  font-family: var(--titre);
  font-weight: 450;
  font-size: clamp(1.0625rem, 1.8vw, 1.3125rem);
  line-height: 1.28;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* Le signe : une barre horizontale toujours là, une verticale qui se
   rétracte à l'ouverture. Le « + » devient « − » sans rien redessiner. */
.question__signe {
  position: relative;
  width: 13px;
  height: 13px;
  align-self: center;
}

.question__signe::before,
.question__signe::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: var(--ivoire-3);
  transition:
    transform var(--normal) var(--doux),
    background var(--normal) var(--doux);
}

.question__signe::before {
  width: 13px;
  height: 1px;
  transform: translate(-50%, -50%);
}

.question__signe::after {
  width: 1px;
  height: 13px;
  transform: translate(-50%, -50%);
}

.question[open] .question__signe::after {
  transform: translate(-50%, -50%) scaleY(0);
}

/* Survol et ouverture : l'accent bleu, posé du bout des doigts. */
.question__titre:hover,
.question[open] .question__titre {
  color: var(--tranche);
}

.question__titre:hover .question__rang,
.question[open] .question__rang {
  color: var(--tranche);
}

.question__titre:hover .question__signe::before,
.question__titre:hover .question__signe::after,
.question[open] .question__signe::before,
.question[open] .question__signe::after {
  background: var(--tranche);
}

.question__titre:focus-visible {
  outline-offset: -2px;
}

/* La réponse : elle s'aligne sous la question, jamais sous le rang. */
.question__reponse {
  padding-bottom: var(--pas-4);
  padding-left: calc(2.5rem + var(--pas-2));
  max-width: calc(var(--texte) + 2.5rem + var(--pas-2));
}

.question__reponse p {
  color: var(--ivoire-2);
  font-size: 1.0625rem;
  line-height: 1.62;
}

.question__renvoi {
  margin-top: var(--pas-2);
}

/* L'ouverture : la réponse se pose, elle ne surgit pas. */
@media (prefers-reduced-motion: no-preference) {
  .question[open] .question__reponse {
    animation: question-se-pose 260ms var(--sortie) both;
  }
}

@keyframes question-se-pose {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* Sur téléphone, le rang mange la largeur du texte : on le rentre. */
@media (max-width: 30rem) {
  .question__titre {
    grid-template-columns: 1.75rem 1fr auto;
    gap: 0.75rem;
  }

  .question__reponse {
    padding-left: calc(1.75rem + 0.75rem);
  }
}
