/* ============================================================
   MHB — Design System
   Dérivé de docs/analyse-lnb-fr-layout.md (formes, fond, encarts)
   Vanilla CSS · nommage BEM
   ============================================================ */

/* ===========================
   1. Polices locales — Quido (principale) + Garet (secondaire)
   =========================== */
/* Quido : un seul fichier, une seule graisse visuelle (condensée, pleine).
   La plage 100–900 fait tenir tous les font-weight du site sur ce même
   fichier, plutôt que de laisser le navigateur simuler un faux gras. */
@font-face {
  font-family: 'Quido';
  src: url('../assets/fonts/Quido.otf') format('opentype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('../assets/fonts/Garet-Font/WOFF2/Garet-Book.woff2') format('woff2'),
       url('../assets/fonts/Garet-Font/OTF/Garet-Book.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('../assets/fonts/Garet-Font/WOFF2/Garet-Book-Italic.woff2') format('woff2'),
       url('../assets/fonts/Garet-Font/OTF/Garet-Book-Italic.otf') format('opentype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('../assets/fonts/Garet-Font/WOFF2/Garet-Medium.woff2') format('woff2'),
       url('../assets/fonts/Garet-Font/OTF/Garet-Medium.otf') format('opentype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('../assets/fonts/Garet-Font/WOFF2/Garet-Bold.woff2') format('woff2'),
       url('../assets/fonts/Garet-Font/OTF/Garet-Bold.otf') format('opentype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('../assets/fonts/Garet-Font/WOFF2/Garet-Bold-Italic.woff2') format('woff2'),
       url('../assets/fonts/Garet-Font/OTF/Garet-Bold-Italic.otf') format('opentype');
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Garet';
  src: url('../assets/fonts/Garet-Font/WOFF2/Garet-Black.woff2') format('woff2'),
       url('../assets/fonts/Garet-Font/OTF/Garet-Black.otf') format('opentype');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

/* ===========================
   2. Tokens / Variables
   =========================== */
:root {
  /* Couleurs de marque MHB (palette rouge / noir / blanc) */
  --c-dark:        #0E0E0E;   /* base immersive (noir adouci) */
  --c-dark-deep:   #000000;   /* fond le plus sombre */
  --c-red:         #C41A38;   /* accent principal / CTA / chiffres clés */
  --c-red-dark:    #8F0B22;   /* hover CTA */
  --c-red-rgb:     196, 26, 56; /* même teinte en canaux, pour les rgba() */
  --c-shade:       #2A1015;   /* noir teinté d'accent (fond des cartes encadrants) */
  --c-white:       #FFFFFF;
  --c-grey-bg:     #D8D8D8;   /* fond clair */
  --c-grey-line:   #BFBFBF;
  --c-ink:         #111111;   /* texte sur fond clair */
  --c-ink-soft:    #808080;   /* texte gris secondaire */

  /* Texte selon le fond */
  --c-text-on-dark:  rgba(255,255,255,.92);
  --c-text-on-light: var(--c-ink);
  --c-muted-on-dark: rgba(255,255,255,.60);

  /* Échelle d'arrondis (cf. analyse §2) */
  --r-sm:   8px;
  --r-md:   12px;
  --r-lg:   16px;   /* cartes vidéo */
  --r-btn:  18px;   /* boutons / CTA */
  --r-xl:   24px;   /* grandes cartes, bannières, photos joueurs */
  --r-pill: 999px;

  /* Espacements */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 16px;
  --sp-4: 24px;
  --sp-5: 32px;
  --sp-6: 48px;
  --sp-7: 64px;
  --sp-8: 96px;

  /* Mise en page */
  --container: 120rem;      /* 1920px — cf. max-w-[120rem] LNB */
  --gutter: 24px;
  --header-h: 84px;
  --sheet-overlap: clamp(52px, 5.5vw, 88px);   /* de combien une "feuille" remonte sur la section précédente */

  /* Ombres */
  --shadow-card: 0 10px 30px rgba(0,0,0,.12);
  --shadow-glow: inset -3.6px 3.6px 3.6px rgba(255,255,255,.10);

  /* Typo — deux familles seulement : Quido (labels, titres, gros chiffres)
     et Garet (texte courant). Les accents auparavant tracés dans une police
     script passent en Garet italique (cf. .script) : plus de 3e famille. */
  --font-title:   'Quido', 'Arial Narrow', sans-serif;
  --font-display: 'Quido', 'Arial Narrow', sans-serif;
  --font-body:    'Garet', system-ui, -apple-system, sans-serif;

  /* Transitions */
  --t-fast: .2s ease;
  --t: .3s ease-in-out;
}

/* Variante de marque — collectifs SUD93
   L'entente inter-clubs ne joue pas sous les couleurs du MHB : ses pages
   remplacent le rouge par le violet. Comme tous les accents du design system
   passent par --c-red, réécrire ces trois tokens sur le conteneur suffit —
   titres, fil d'Ariane, bandeaux, cartes encadrants suivent sans exception.
   Posé sur <main> : le header et le pied de page restent aux couleurs du club. */
.theme-sud93 {
  --c-red:       #6D3BC4;
  --c-red-dark:  #4E2596;
  --c-red-rgb:   109, 59, 196;
  --c-shade:     #1E1024;
}

/* ===========================
   3. Base
   =========================== */
body {
  font-family: var(--font-body);
  background-color: var(--c-dark);
  color: var(--c-text-on-dark);
  overflow-x: clip;   /* clippe l'horizontal sans créer de conteneur de scroll (préserve window.scrollY) */
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  text-transform: uppercase;
  line-height: 1.02;
  letter-spacing: .01em;
  font-weight: 600;
}

/* ===========================
   4. Layout — bandes & conteneur
   (cf. analyse §1 : alternance immersive/clair, full-bleed)
   =========================== */
.band {
  position: relative;
  width: 100%;
  padding: var(--sp-8) 0;
  background-size: cover;
  background-position: center;
}
.band--immersive {
  background-color: var(--c-dark);
  color: var(--c-text-on-dark);
  background-image: linear-gradient(180deg, rgba(0,0,0,.55), rgba(14,14,14,.9)),
                    url('../assets/images/web/fonds/graph-dark.jpg');
}
/* Sections immersives SANS panneau : transparentes → laissent voir le fond du site */
.band--immersive:not(.band--sheet) {
  background-color: transparent;
  background-image: none;
}
.band--light {
  background-color: var(--c-grey-bg);
  color: var(--c-text-on-light);
  background-image: linear-gradient(180deg, rgba(255,255,255,.6), rgba(216,216,216,.6)),
                    url('../assets/images/web/fonds/graph-light.jpg');
  /* Le graffiti est cadré sur la fenêtre, pas sur la bande. En `cover` calé sur
     la bande, une page longue (2000px de haut pour 1200 de large) agrandissait
     l'image à 3000px : on n'en voyait plus que la zone plate du centre, sans
     les coulures rouges ni la ville. D'où l'impression qu'il manquait. */
  background-attachment: scroll, fixed;
}
/* Les navigateurs tactiles gèrent mal `fixed` (saccades, cadrage faux) : on y
   revient au défilement normal, où la bande est de toute façon plus étroite. */
@media (hover: none) {
  .band--light { background-attachment: scroll, scroll; }
}
/* Bande intercalaire centrée entre la section précédente et la "feuille" suivante :
   même respiration visuelle au-dessus et en dessous, à toutes les largeurs.
   — au-dessus, la section précédente apporte déjà son padding bas (--sp-8) ;
   — en dessous, la feuille suivante remonte de --sheet-overlap. */
.band--between {
  --band-gap: 60px;
  margin-top: calc(var(--band-gap) - var(--sp-8));
  padding-top: 0;
  padding-bottom: calc(var(--band-gap) + var(--sheet-overlap));
}

/* "Feuille" : fond en panneau aux 4 coins arrondis qui s'empile.
   Réutilisable sur n'importe quelle bande, sa couleur d'origine est conservée. */
.band--sheet {
  position: relative;
  z-index: 1;
  padding-top: var(--sp-8);
  padding-bottom: var(--sp-8);
  border-radius: 40px;
  /* ombre du haut = "marche" de la pile ; ombre du bas = profondeur sous la dernière */
  box-shadow: 0 -22px 44px rgba(0,0,0,.30), 0 16px 34px rgba(0,0,0,.16);
}
/* Fin liseré qui souligne le bord arrondi (surtout utile sombre sur sombre) */
.band--sheet::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 40px;
  pointer-events: none;
  z-index: 3;
}
/* Remonte sur la section précédente → effet de feuilles empilées */
.band--sheet--overlap { margin-top: calc(-1 * var(--sheet-overlap)); }
/* Passe au premier plan : son bas arrondi recouvre la section d'en dessous */
.band--sheet--front { z-index: 4; }

/* La dernière section de la page est un cas à part : ce qui remonte sur
   elle n'est pas une autre feuille claire mais le pied de page, sombre et
   arrondi, qui passe devant. Les 22 px de --band-gap qui suffisent entre
   deux feuilles y laissaient le dernier bloc collé au pied — on lui rend
   une vraie respiration, en plus de ce que le chevauchement absorbe. */
main > section:last-child {
  padding-bottom: calc(var(--sp-6) + var(--sheet-overlap));
}

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding-inline: clamp(16px, 4vw, 80px);
}

/* En-tête de section */
.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-6);
}
.section-head__title {
  font-size: clamp(2rem, 4vw, 3.5rem);
}
.section-head__title .accent { color: var(--c-red); }

/* ===========================
   5. Boutons (pills 18px — cf. analyse §2/§5)
   =========================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: 63px;            /* hauteur exacte LNB */
  padding: 0 var(--sp-5);
  border: none;
  border-radius: var(--r-btn);
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: .95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t-fast), transform var(--t-fast);
}
.btn:hover { transform: translateY(-2px); }
.btn--primary { background: var(--c-red); color: var(--c-white); }
.btn--primary:hover { background: var(--c-red-dark); }
.btn--light { background: var(--c-white); color: var(--c-dark); }
.btn--sm { height: 44px; font-size: .8rem; padding: 0 var(--sp-4); }
/* Bouton principal d'une page : plus haut, plus large, pastille intégrée */
.btn--xl {
  height: 74px;
  font-size: 1.05rem;
  padding: 0 var(--sp-4) 0 var(--sp-6);
  gap: var(--sp-4);
}

/* ===========================
   6. Header — barre, pill et menu des trois traits
   =========================== */
.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  display: flex;
  justify-content: center;
  padding: clamp(12px, 1.6vw, 22px) clamp(16px, 4vw, 40px);
  pointer-events: none;                 /* la gouttière laisse passer les clics */
}

.header__inner {
  pointer-events: auto;
  width: 100%;
  max-width: var(--container);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: 10px clamp(16px, 2.5vw, 28px);
  border-radius: 999px;
  background: transparent;
  /* La barre avale ses liens au lieu de les laisser déborder pendant qu'elle se referme.
     `contain` isole le recalcul de mise en page au seul header. */
  overflow: hidden;
  contain: layout paint;
  transition:
    max-width .6s cubic-bezier(.22, 1, .36, 1),
    padding .6s cubic-bezier(.22, 1, .36, 1),
    background-color .45s ease,
    box-shadow .45s ease;
}
/* État scrollé : le header se replie en pill sombre centrée.
   Les catégories rejoignent le menu des trois traits, la pill se resserre
   sur le monogramme + le bouton. */
.header.is-scrolled .header__inner {
  max-width: 880px;
  background: rgba(12, 12, 12, .94);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .35);
  padding: 8px 12px;
}
@media (min-width: 821px) {
  .header.is-scrolled .header__inner { max-width: 112px; }   /* monogramme 40 + gap 14 + bouton 34 + padding 24 */
}

.header__brand {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: 0 0 auto;
}
.header__logo {
  display: flex;
  align-items: center;
  text-decoration: none;
  flex: 0 0 auto;
}
.header__mark { flex: 0 0 auto; display: block; }
.header__mark img {
  display: block;
  height: 52px;
  width: auto;
  transition: height .6s cubic-bezier(.22, 1, .36, 1);
}
.header.is-scrolled .header__mark img { height: 40px; }

/* Trois traits à côté du monogramme : ouvrent le menu.

   En haut de page ils n'ont plus rien à ouvrir — les sept catégories sont
   dans la barre — donc ils ne s'affichent pas. Ils reviennent en pill, où
   la barre se replie derrière eux : c'est là qu'ils servent. */
.header__lines {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  height: 18px;
  padding: 6px 8px;
  margin-left: -8px;
  box-sizing: content-box;
  background: none;
  border: 0;
  cursor: pointer;
}
/* Uniquement là où il y a une barre à replier. Sous 821 px, la navigation
   s'ouvre par le burger de droite et ces traits-ci ne servent à rien : les
   allumer donnerait deux menus côte à côte pour la même chose.
   Le média est indispensable ici — sans lui, le poids de ce sélecteur
   (trois classes) écrase le « display:none » du bloc mobile plus bas, qui
   n'en compte qu'une. */
@media (min-width: 821px) {
  .header.is-scrolled .header__lines { display: flex; }
}
.header__lines i {
  display: block;
  width: 26px; height: 2px;
  border-radius: 2px;
  background: var(--c-white);
  transition:
    transform .22s ease,
    opacity .12s ease;
}
/* Menu ouvert : bascule en croix */
.header.is-menu-open .header__lines i:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.header.is-menu-open .header__lines i:nth-child(2) { opacity: 0; }
.header.is-menu-open .header__lines i:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Panneau ouvert par les trois traits : une barre qui se déploie en largeur,
   centrée sous la pill (le déploiement part du centre vers les deux côtés).
   Seuls clip-path et opacity sont animés → tout se joue sur le compositeur. */
.menu {
  position: absolute;
  top: 100%;
  left: 50%;
  z-index: 2;
  display: flex;
  align-items: center;
  padding: 7px;
  border-radius: var(--r-pill);
  background: rgba(12, 12, 12, .97);
  border: 1px solid rgba(255, 255, 255, .08);
  box-shadow: 0 14px 30px rgba(0, 0, 0, .4);
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-50%);
  clip-path: inset(0 50% 0 50% round 999px);
  pointer-events: none;
  will-change: clip-path, opacity;
  transition:
    clip-path .45s cubic-bezier(.22, 1, .36, 1),
    opacity .2s ease;
}
.menu.is-open {
  opacity: 1;
  clip-path: inset(0 0 0 0 round 999px);
  pointer-events: auto;
}
/* Le contenu suit l'ouverture avec un léger retard, sans à-coup */
.menu > * {
  opacity: 0;
  transition: opacity .2s ease;
}
.menu.is-open > * { opacity: 1; transition-delay: .1s; }

/* ===========================
   7. Navigation — entrées de la barre et sous-menus déroulants
   =========================== */
.submenu {
  position: absolute;
  top: 100%;
  left: 50%;
  z-index: 1;
  display: flex;
  align-items: stretch;
  gap: var(--sp-4);
  padding: 16px 20px;
  border-radius: 28px;
  background: rgba(12, 12, 12, .97);
  border: 1px solid rgba(255, 255, 255, .08);
  box-shadow: 0 14px 30px rgba(0, 0, 0, .4);
  opacity: 0;
  transform: translateX(-50%);
  clip-path: inset(0 50% 0 50% round 28px);
  pointer-events: none;
  will-change: clip-path, opacity;
  transition:
    clip-path .45s cubic-bezier(.22, 1, .36, 1),
    opacity .2s ease;
}
.submenu.is-open {
  opacity: 1;
  clip-path: inset(0 0 0 0 round 28px);
  pointer-events: auto;
}
.submenu > * { opacity: 0; transition: opacity .2s ease; }
.submenu.is-open > * { opacity: 1; transition-delay: .1s; }

/* Les équipes : plusieurs colonnes pour rester large et court */
.submenu__teams {
  display: grid;
  grid-template-columns: repeat(4, minmax(140px, 1fr));
  gap: 2px 4px;
}
.submenu__link {
  padding: 8px 12px;
  border-radius: var(--r-md);
  font-family: var(--font-title);
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--c-text-on-dark);
  white-space: nowrap;
  transition: background-color var(--t-fast), color var(--t-fast);
}
.submenu__link:hover { background: rgba(255, 255, 255, .08); color: var(--c-white); }

/* Variante compacte : une seule ligne, chaque colonne à la largeur de son contenu
   (pas de minmax ici : avec des libellés de longueurs différentes, une largeur
   minimale commune laisse un vide avant l'entrée la plus courte) */
.submenu__teams--soutien { grid-template-columns: repeat(2, max-content); gap: 2px var(--sp-3); }

/* Entrée à part, séparée par un filet vertical */
.submenu__aside {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding-left: var(--sp-4);
  border-left: 1px solid rgba(255, 255, 255, .12);
  font-family: var(--font-title);
  font-size: .86rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--c-white);
  white-space: nowrap;
}
.submenu__aside .arrow-dot { width: 30px; height: 30px; }
.submenu__aside .arrow-dot svg { width: 13px; height: 13px; }
.submenu__aside:hover .arrow-dot { background: var(--c-white); }
.submenu__aside:hover .arrow-dot svg { fill: var(--c-red); }
/* Les catégories une fois rangées dans le menu : alignées en ligne
   (double classe : doit l'emporter sur le .nav défini plus bas) */
.nav.nav--in-menu { flex-direction: row; align-items: center; gap: 2px; }
.nav--in-menu .nav__link {
  padding: 9px 16px;
  border-bottom: 0;
  border-radius: var(--r-pill);
  white-space: nowrap;
  transition: background-color var(--t-fast);
}
.nav--in-menu .nav__link:hover { background: rgba(255, 255, 255, .08); }
/* Entrées propres au menu (Boutique, Actualités, Partenaires) */
.menu__extra { display: flex; align-items: center; gap: 2px; }
.menu__link {
  padding: 9px 16px;
  border-radius: var(--r-pill);
  font-family: var(--font-title);
  font-size: .9rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--c-text-on-dark);
  white-space: nowrap;
  transition: background-color var(--t-fast), color var(--t-fast);
}
.menu__link:hover { background: rgba(255, 255, 255, .08); color: var(--c-white); }
/* Filet de séparation quand les catégories sont rangées juste avant */
.nav--in-menu + .menu__extra {
  margin-left: 6px;
  padding-left: 8px;
  border-left: 1px solid rgba(255, 255, 255, .14);
}

@media (prefers-reduced-motion: reduce) {
  .header,
  .header__inner,
  .header__lines i,
  .menu,
  .menu > *,
  .nav,
  .header__mark img {
    transition: none !important;
  }
}

.nav {
  display: flex;
  align-items: center;
  /* Sept catégories, pas quatre : l'écart se resserre avec la fenêtre
     plutôt que de pousser la barre hors de l'écran. */
  gap: clamp(14px, 1.7vw, 32px);
  transition: opacity .2s ease;
}
/* Utilisé le temps de déplacer les liens entre la barre et le menu :
   ils s'effacent, changent de place hors champ, puis reviennent. */
.nav.is-fading { opacity: 0; pointer-events: none; }
.nav__link {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .9rem;
  letter-spacing: .04em;
  color: var(--c-text-on-dark);
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  transition: border-color var(--t-fast), color var(--t-fast);
}
.nav__link:hover { border-color: var(--c-red); }
/* Doublon assumé des entrées du menu trois traits, utile seulement sous 820px
   où ce menu disparaît (cf. le bloc responsive). */
.nav__extra { display: none; }
/* Page courante (posé par js/main.js) */
.nav__link.is-current { color: var(--c-white); border-color: var(--c-red); }
.menu__link.is-current { background: rgba(255, 255, 255, .1); color: var(--c-white); }
/* Entrée de nav qui ouvre un sous-menu : c'est un <button>, il faut lui
   redonner ce qu'il n'hérite pas (typo, interligne, cadre du navigateur). */
.nav__link--sub {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  appearance: none;
  border: 0 solid transparent;
  border-bottom-width: 2px;
  font-family: var(--font-title);
  font-size: .9rem;
  font-weight: inherit;
  line-height: inherit;
  cursor: pointer;
}
.nav__chevron {
  width: 14px; height: 14px;
  fill: currentColor;
  transition: transform .25s ease;
}
.nav__link--sub[aria-expanded="true"] .nav__chevron { transform: rotate(180deg); }
.header__burger {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
}
.header__burger span {
  width: 26px; height: 2px;
  background: var(--c-white);
  transition: var(--t-fast);
}

/* ===========================
   8. Qui sommes-nous (texte + accordéon d'images)
   =========================== */
.about {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: clamp(32px, 5vw, 72px);
}
.about__title {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 5vw, 4rem);
  line-height: .95;
  color: var(--c-white);
  margin-bottom: var(--sp-4);
}
.about__title .accent { color: var(--c-red); font-style: italic; }
.about__lead {
  font-size: 1.1rem;
  line-height: 1.6;
  color: var(--c-muted-on-dark);
  max-width: 48ch;
  margin-bottom: var(--sp-5);
}

.accordion {
  display: flex;
  gap: 14px;
  width: 100%;
  padding: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}
.accordion::-webkit-scrollbar { display: none; }

.accordion__item {
  position: relative;
  flex: 0 0 64px;
  height: 440px;
  padding: 0;
  border: 0;
  border-radius: var(--r-xl);
  overflow: hidden;
  cursor: pointer;
  background: var(--c-dark-deep);
  transition: flex-basis .7s cubic-bezier(.65, 0, .35, 1);
}
.accordion__item.is-active { flex-basis: 380px; }
.accordion__item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.accordion__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.15) 0%, rgba(0,0,0,.2) 45%, rgba(0,0,0,.6) 100%);
}
.accordion__label {
  position: absolute;
  left: 50%;
  bottom: 84px;
  transform: translateX(-50%) rotate(90deg);
  transform-origin: center;
  white-space: nowrap;
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--c-white);
  transition: bottom .4s ease, transform .4s ease;
}
.accordion__item.is-active .accordion__label {
  bottom: 22px;
  transform: translateX(-50%) rotate(0deg);
}
@media (prefers-reduced-motion: reduce) {
  .accordion__item,
  .accordion__label { transition: none !important; }
}

@media (max-width: 820px) {
  .about { grid-template-columns: 1fr; text-align: center; }
  .about__lead { margin-inline: auto; }
  .accordion { justify-content: flex-start; }
}

/* ===========================
   9. Hero (photo full-bleed + texte surimpression — cf. analyse §3)
   =========================== */
.hero {
  position: relative;
  height: 100vh;
  min-height: 600px;
  overflow: hidden;
}
.hero__slides { height: 100%; }
.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .8s ease;
}
.hero__slide.is-active { opacity: 1; }
.hero__slide img {
  width: 100%; height: 100%;
  object-fit: cover;
}
.hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,0) 35%, rgba(0,0,0,.9) 100%);
}
.hero__content {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-width: var(--container);
  margin: 0 auto;
  padding: clamp(16px,4vw,80px);
  padding-bottom: var(--sp-8);
}
.hero__title {
  /* Tient sur une seule ligne à toutes les largeurs : la borne basse du clamp
     est calée pour que « Montreuil Handball » passe même sur petit écran.
     Valeurs recalculées pour Quido, sensiblement plus large que la police
     précédente — les remonter ferait déborder le titre sur mobile. */
  font-size: clamp(1.5rem, 8vw, 5.5rem);
  white-space: nowrap;
  color: var(--c-white);
  margin-bottom: var(--sp-4);
}
.hero__hashtag {
  display: inline-block;
  font-size: clamp(1.1rem, 5.9vw, 2.6rem);
  line-height: 1.25;
}
.hero__dots {
  position: absolute;
  bottom: var(--sp-5);
  right: clamp(16px,4vw,80px);
  display: flex;
  gap: var(--sp-2);
}
.hero__dot {
  width: 40px; height: 4px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.35);
  border: none;
  cursor: pointer;
  transition: background var(--t-fast);
}
.hero__dot.is-active { background: var(--c-red); }

/* ===========================
   10. Footer
   =========================== */
.footer {
  /* Force du blason en filigrane. Un seul nombre à bouger pour l'atténuer
     ou l'appuyer : à .04 il ne se devine plus, à .16 il commence à
     disputer la lecture des colonnes. */
  --filigrane: .05;
  position: relative;
  /* Au-dessus de la section précédente, y compris d'une .band--sheet--front
     (z-index 4) : c'est le pied qui recouvre la feuille claire, et non
     l'inverse. Son coin arrondi, son liseré et son ombre portée vers le
     haut se posent donc sur elle. Reste sous le header (50) et sous les
     bulles (45). */
  z-index: 5;
  /* Le blason déborde volontairement du bloc : c’est ce qui le rogne. */
  overflow: hidden;
  margin-top: clamp(-88px, -5.5vw, -52px);
  border-radius: 40px 40px 0 0;
  box-shadow: 0 -22px 44px rgba(0,0,0,.30);
  background: var(--c-dark-deep);
  color: var(--c-text-on-dark);
  /* Réserve en bas pour le bouton flottant, au cas où il reste dans le coin :
     sans elle, il couvrait la fin de la ligne des mentions, dont l'entrée des
     bénévoles. La règle suivante la retire dès que le relais vers le pied de
     page est en place — c'est-à-dire presque toujours. */
  /* Le pied passant devant, tout son haut est visible : plus besoin de
     compenser le chevauchement, ce padding est celui qu'on voit vraiment. */
  padding: var(--sp-6) 0 calc(var(--sp-4) + 40px);
}
/* Liseré qui souligne le haut arrondi du footer (cf. .band--sheet) */
.footer::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid rgba(255,255,255,.10);
  border-bottom: none;
  border-radius: 40px 40px 0 0;
  pointer-events: none;
  -webkit-mask: linear-gradient(180deg, #000 0, #000 60px, transparent 160px);
          mask: linear-gradient(180deg, #000 0, #000 60px, transparent 160px);
}
/* Le blason, en filigrane, centré et occupant presque toute la hauteur du
   bloc. En fond CSS et non en <img> : il ne dit rien qu'un lecteur d'écran
   doive entendre, et il ne prend aucune place dans la grille. */
.footer::after {
  content: '';
  position: absolute;
  /* Centré, mais bien plus grand que le bandeau : le bloc le rogne en haut
     et en bas, et le masque le dissout avant qu'il n'atteigne les bords.
     On n'en voit qu'une large tranche — le blason est une matière de fond,
     pas une image posée là, comme sur le bloc « club » de l'accueil. */
  top: 50%;
  left: 50%;
  height: 240%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background-image: url('../assets/images/logos/MHB/Logo%20MHB%20blanc.png');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  opacity: var(--filigrane);
  /* Fondu circulaire et non plus seulement vertical : le blason est rond,
     un dégradé haut-bas laissait ses bords gauche et droit nets et il se
     lisait comme un disque posé là. Là, il se dissout dans toutes les
     directions — il ne reste que sa partie centrale, sans contour. */
  -webkit-mask-image: radial-gradient(circle at center, #000 24%, transparent 68%);
          mask-image: radial-gradient(circle at center, #000 24%, transparent 68%);
  pointer-events: none;
  z-index: 0;
}
/* Le contenu repasse devant le filigrane. */
.footer > .container { position: relative; z-index: 1; }
/* Quatre colonnes : la signature du club, deux colonnes de liens, la fiche
   contact. Des largeurs proches, et non plus 208 px contre 444 : la colonne
   contact n'a plus d'adresse électronique à faire tenir depuis qu'elle est
   passée dans la bulle, elle n'avait plus de raison d'être deux fois plus
   large que ses voisines.
   `align-items: start` : chaque colonne s'arrête où son contenu s'arrête,
   au lieu d'être étirée à la hauteur de la plus haute. */
/* Quatre colonnes de même nature — un intitulé, puis son contenu. Leurs
   titres tombent donc tous sur la même ligne, ce que l'ancienne colonne de
   marque (logo, signature, réseaux empilés) rendait impossible. Le blason
   est passé derrière, la signature a été retirée : il ne reste dans le
   bandeau que ce qui sert à naviguer ou à joindre le club.
   La fiche contact est la plus large : c'est la seule qui porte du texte
   qu'on ne peut pas raccourcir. */
.footer__grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1.15fr 1fr;
  align-items: start;
  gap: var(--sp-6);
  margin-bottom: var(--sp-5);
}
.footer__col h4 { font-size: 1rem; margin-bottom: var(--sp-2); color: var(--c-red); }
/* `>` et non un descendant quelconque : les liens de la fiche contact sont,
   eux aussi, dans une .footer__col, et n'ont rien d'une entrée de menu. */
.footer__col > a {
  display: block;
  color: var(--c-muted-on-dark);
  padding: 3px 0;
  font-size: .92rem;
  transition: color var(--t-fast);
}
.footer__col > a:hover { color: var(--c-white); }

/* --- Réseaux sociaux : la quatrième colonne -----------------------------
   Colonne à part entière depuis qu'elle a quitté la pile de la marque :
   son intitulé prend donc le corps des autres, sans réglage particulier.
   Les pastilles sont assez contrastées pour se voir sur le noir du pied —
   à 6 % de fond et 60 % d'encre, elles s'y perdaient. */
.footer__reseaux { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.footer__reseau {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 255, 255, .3);
  background: rgba(255, 255, 255, .12);
  color: var(--c-white);
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
.footer__reseau svg { width: 20px; height: 20px; fill: currentColor; fill-rule: evenodd; }
.footer__reseau:hover,
.footer__reseau:focus-visible {
  color: var(--c-white);
  border-color: var(--c-red);
  background: var(--c-red);
}
/* Réseau dont on n'a pas le glyphe : son nom, plutôt qu'une pastille muette. */
.footer__reseau--texte {
  width: auto;
  padding: 0 16px;
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .68rem;
  letter-spacing: .08em;
}

/* --- Fiche contact ------------------------------------------------------
   Prend la place du formulaire de newsletter : le pied de page donne
   l'adresse du club au lieu de réclamer celle du visiteur. Chaque ligne est
   une action — écrire, appeler, ouvrir l'itinéraire — d'où le traitement en
   bouton plutôt qu'en liste de texte. */
.footer__fiche {
  font-style: normal;
  display: grid;
  gap: var(--sp-2);
  /* Sans borne, la carte d'adresse s'étirait sur toute la colonne dès que
     le pied passe à deux colonnes larges : un grand cadre presque vide
     autour de trois mots. */
  max-width: 34ch;
}
.footer__ligne {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 11px 13px;
  border-radius: var(--r-md);
  border: 1px solid rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .04);
  color: var(--c-text-on-dark);
  transition: border-color var(--t-fast), background var(--t-fast);
}
a.footer__ligne:hover,
a.footer__ligne:focus-visible {
  border-color: var(--c-red);
  background: rgba(255, 255, 255, .09);
}
.footer__ico {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  margin-top: 1px;
  fill: var(--c-red);
  fill-rule: evenodd;
}
.footer__ligne-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.footer__ligne-val {
  font-size: .88rem;
  line-height: 1.35;
  color: var(--c-white);
  /* Filet de sécurité : un mot plus large que la colonne se coupe plutôt que
     de déborder. La coupure choisie reste celle du <wbr> posé après l'arobase
     par js/layout.js — `break-word` ne s'applique que faute de mieux. */
  overflow-wrap: break-word;
}
/* Le domaine d'une adresse électronique ne se coupe pas : c'est ce qui force
   la coupure à se faire sur l'arobase, et non sur le trait d'union du nom. */
.footer__domaine { white-space: nowrap; }

/* Le bouton vers le formulaire : seul élément plein de la fiche, parce que
   c'est l'action attendue de qui n'a pas de logiciel de messagerie. */
.footer__ecrire {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
  padding: 11px 12px 11px 18px;
  /* C'est un <button> : il ouvre la bulle, il ne mène pas à une page.
     Il faut donc lui retirer ce que le navigateur pose d'office. */
  border: none;
  cursor: pointer;
  border-radius: var(--r-pill);
  background: var(--c-red);
  color: var(--c-white);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .78rem;
  letter-spacing: .06em;
  /* Sous les réseaux, séparé d'eux : il clôt la colonne, il n'en fait pas
     partie. */
  margin-top: var(--sp-4);
  justify-self: start;
  transition: background var(--t-fast);
}
.footer__ecrire .arrow-dot--light { width: 30px; height: 30px; }
.footer__ecrire .arrow-dot--light svg { width: 13px; height: 13px; }
.footer__ecrire:hover,
.footer__ecrire:focus-visible { background: var(--c-red-dark); }
.footer__ligne-det {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .66rem;
  letter-spacing: .06em;
  line-height: 1.4;
  color: var(--c-muted-on-dark);
}
.footer__bottom {
  border-top: 1px solid rgba(255,255,255,.12);
  padding-top: var(--sp-4);
  /* Trois colonnes plutôt qu'un space-between : la signature doit rester au
     milieu de la page, pas au milieu de ce qui reste entre ses deux voisins,
     qui n'ont aucune raison d'avoir la même largeur. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-3);
  color: var(--c-muted-on-dark);
  font-size: .85rem;
}
.footer__bottom > .footer__legal { justify-self: end; }

/* Sous 720px les trois blocs s'empilent : chacun prend toute la largeur et se
   centre, sinon le copyright resterait à gauche sous une signature centrée. */
@media (max-width: 720px) {
  .footer__bottom {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }
  .footer__bottom > .footer__legal { justify-self: center; }
}
/* Dernière ligne du site : l'entrée des bénévoles. Volontairement
   effacée — elle ne s'adresse pas aux visiteurs, mais elle doit
   rester trouvable sans qu'on ait à retenir une adresse. */
.footer__legal {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.footer__benevoles {
  color: rgba(255,255,255,.38);
  transition: color var(--t-fast);
}
.footer__benevoles:hover,
.footer__benevoles:focus-visible { color: var(--c-white); }

/* La signature de l'auteur du site, après le copyright. Plus lisible que
   l'entrée des bénévoles — c'est un crédit, pas une porte dérobée — mais
   assez retenue pour ne pas concurrencer le nom du club. */
/* Le cadre de la signature : rien de visible, juste de quoi tenir la phrase
   d'un seul bloc et la centrer. Le point de séparation n'a plus lieu d'être —
   elle ne suit plus le copyright, elle est à part. */
.footer__signature {
  display: inline-flex;
  align-items: baseline;
  gap: .32em;
  justify-self: center;
  white-space: nowrap;
  /* Discrète, mais pas illisible. Sur le noir du pied, .46 donne 4,7:1 —
     juste au-dessus du seuil de lisibilité (4,5:1), filigrane du blason
     compris. En dessous de .44 on passe sous la barre : ne pas descendre. */
  color: rgba(255,255,255,.46);
  letter-spacing: .02em;
}
/* Le nom porte le poids : c'est lui la signature, « Website by » n'est que
   l'amorce. */
.footer__signature b {
  font-weight: 700;
  /* Allégé une seconde fois à la demande du client. À .52 le nom garde
     5,7:1 — confortable — et le gras le tient devant son amorce. L'amorce,
     elle, est déjà au plancher (.46 = 4,6:1) : c'est le nom qui porte
     tout l'allègement. */
  color: rgba(255,255,255,.52);
}
a.footer__signature { transition: color var(--t-fast); }
a.footer__signature:hover,
a.footer__signature:focus-visible { color: var(--c-white); }

/* ===========================
   11. Accent script + CTA « read » réutilisable
   =========================== */
.script {
  font-family: var(--font-body);
  font-style: italic;
  text-transform: none;
  color: var(--c-red);
  font-weight: 400;
}
/* Dans un titre de section, l'accent reprend la police de titrage — le même
   traitement que « MONTREUIL HANDBALL » sur l'accueil : Quido, en italique
   rouge. Le corps 1.1em servait à compenser Garet, plus petit optiquement ;
   à famille égale il n'a plus lieu d'être. */
.section-head__title .script {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1em;
  line-height: inherit;
}

/* Bouton compact : pill semi-transparent + flèche en pastille rouge */
.cta-read {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  background: rgba(255,255,255,.12);
  border: none;
  border-radius: var(--r-btn);
  padding: 10px 12px 10px 22px;
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: .82rem;
  color: var(--c-white);
  cursor: pointer;
}
.cta-read--light { background: var(--c-white); color: var(--c-dark); }
.arrow-dot {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  border-radius: var(--r-pill);
  background: var(--c-red);
  display: grid; place-items: center;
}
.arrow-dot svg { width: 15px; height: 15px; fill: var(--c-white); }
/* Pastille claire, sur un bouton déjà rouge */
.arrow-dot--light { background: var(--c-white); width: 44px; height: 44px; }
.arrow-dot--light svg { fill: var(--c-red); width: 17px; height: 17px; }

/* ===========================
   12. Panneau de section (grand bloc blanc arrondi)
   =========================== */
.section-panel {
  --panel-pad: clamp(20px, 3vw, 40px);
  position: relative;
  /* Contexte d'empilement : permet au blason en filigrane de se placer en
     z-index négatif, donc au-dessus du fond blanc mais sous tout le contenu. */
  isolation: isolate;
  background: var(--c-white);
  border-radius: 32px;
  padding: var(--panel-pad);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
/* Blason du club en filigrane — même principe que le bloc sombre de la page
   inscription (.signup__crest) : grand, débordant sur le bord, et éteint par
   un dégradé de masquage pour que le texte reste sur un fond net. Ici le
   blason noir, très sourd, sur le panneau clair.
   Posé en balise, page par page : seules les pages qui en font la demande le
   portent (annuaire des entraîneurs, partenaires). */
.section-panel__crest {
  position: absolute;
  /* Le blason occupe tout le panneau : `contain` le cale sur la plus petite
     dimension, donc sur la largeur, et il reste centré quelle que soit la
     hauteur du panneau (de quelques centaines à quelques milliers de pixels). */
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: url('../assets/images/logos/MHB/Logo%20MHB%20noir.png') center center / contain no-repeat;
  opacity: .1;
  -webkit-mask-image: linear-gradient(115deg, transparent 8%, #000 55%);
          mask-image: linear-gradient(115deg, transparent 8%, #000 55%);
}
.section-panel .promo-bar { margin-bottom: var(--sp-6); }
/* ===========================
   13. Bandeau horizontal (.promo-bar) — prochain match, créneaux, dates
   =========================== */
.promo-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  background: var(--c-dark);
  border-radius: var(--r-xl);
  padding: clamp(16px, 3vw, 26px) clamp(20px, 3vw, 40px);
}
.promo-bar__icon {
  flex: 0 0 auto;
  width: 56px; height: 56px;
  border-radius: var(--r-md);
  background: var(--c-white);
  display: grid; place-items: center;
}
.promo-bar__icon svg { width: 28px; height: 28px; fill: var(--c-dark); }
.promo-bar__text { flex: 1; min-width: 0; }
.promo-bar__title {
  font-family: var(--font-display);
  text-transform: uppercase;
  color: var(--c-white);
  font-size: clamp(1.2rem, 2.4vw, 1.9rem);
  line-height: 1;
}
.promo-bar__sub { color: var(--c-muted-on-dark); font-size: .95rem; margin-top: 6px; }

/* Variante « prochain match » : même bandeau, avec surtitre */
.promo-bar--next .promo-bar__kicker {
  display: block;
  font-family: var(--font-title);
  font-size: .66rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--c-red);
  margin-bottom: 4px;
}
.promo-bar--next .promo-bar__sub { font-size: .88rem; margin-top: 4px; }

/* ===========================
   14. Calendrier — en-tête et chips de sélection d'équipe
   =========================== */
.cal__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  margin-bottom: var(--sp-6);
}
.cal__controls { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }
.chips { display: flex; gap: var(--sp-2); }
.chip {
  width: 76px; min-height: 76px;
  border-radius: var(--r-md);
  background: var(--c-white);
  border: 2px solid transparent;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-title);
  font-size: .62rem; text-transform: uppercase; letter-spacing: .02em;
  color: var(--c-ink); cursor: pointer;
  text-align: center; line-height: 1.05; padding: 8px 4px;
  box-shadow: var(--shadow-card);
}
.chip__icon { width: 22px; height: 22px; fill: var(--c-ink-soft); transition: fill var(--t-fast); }
.chip.is-active { border-color: var(--c-red); }
.chip.is-active .chip__icon { fill: var(--c-red); }
/* ===========================
   15. Compétition — classement et matchs (Score'n'co)
   ---------------------------
   Les deux viennent de widgets.scorenco.com, dont le script remplace chaque
   bloc .scorenco-widget par un iframe servi depuis SON domaine : l'intérieur
   nous échappe, aucune règle d'ici ne l'atteint. Ce qui suit habille ce que
   l'on maîtrise — les deux cadres et l'attente avant qu'ils arrivent.
   =========================== */
.cal__grille {
  display: grid;
  /* Le classement est borné en largeur, pas seulement en hauteur. Le widget
     décide seul des colonnes qu'il montre selon la place : à 360 px il en
     affiche trois, proprement ; à 440 il en commence une quatrième qu'il
     n'a pas la place de finir, et « DIFF » se retrouve tranchée. On le tient
     donc dans la largeur où son propre gabarit tombe juste. */
  grid-template-columns: minmax(0, 360px) 1fr;
  gap: var(--sp-4);
  align-items: start;
  margin-top: var(--sp-4);
}
.cal__coltitle {
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .72rem;
  color: var(--c-ink-soft);
  margin-bottom: var(--sp-3);
}

/* Le cadre : mêmes filet et arrondi que les autres encarts du panneau blanc,
   pour que les tableaux du fournisseur ne flottent pas comme des pièces
   rapportées. */
.cal__widget {
  border: 1px solid var(--c-grey-line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--c-white);
}
.cal__widget iframe { display: block; width: 100%; }

/* Un seul jeu de widgets à l'écran. Replié SANS display:none : privé de
   largeur de mise en page, un iframe se mesure dans son gabarit le plus
   étroit, et le script Score'n'co ne fixe sa hauteur qu'une fois — elle
   resterait fausse. Ici il garde sa largeur, on ne coupe que la hauteur. */
.cal__widget:not(.is-active) {
  height: 0;
  border-width: 0;
  visibility: hidden;
}

/* Le classement fait près de 800 px à lui seul, deux fois le bloc des matchs
   qui lui fait face. On le borne à la hauteur de son voisin : les deux
   colonnes se terminent ensemble, et le tableau défile pour le reste. */
.cal__bloc--rang .cal__widget.is-active {
  max-height: 476px;
  overflow: auto;
  scrollbar-width: thin;
}

/* L'attente, le temps que l'iframe arrive : aux couleurs du club plutôt qu'au
   bleu du fournisseur — sinon le seul moment où l'habillage nous appartient
   est justement celui qui ne ressemble pas au site. */
.cal__attente {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  height: 380px;
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: .74rem;
  color: var(--c-ink-soft);
}
.cal__spinner {
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  border: 4px solid rgba(0, 0, 0, .08);
  border-top-color: var(--c-red);
  animation: cal-tourne 1s linear infinite;
}
@keyframes cal-tourne { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .cal__spinner { animation-duration: 3.5s; }
}

/* ===========================
   16. Pages intérieures (gabarit commun)
   =========================== */
/* Deux classes, pas une : « .band » reçoit plus bas, sous 480 px, un
   raccourci « padding: … 0 » qui remettrait ce dégagement à zéro — et le
   fil d'Ariane repasserait sous le logo, comme il le faisait. */
.band.page-head {
  /* dégage la hauteur du header fixe, qui recouvrirait le titre */
  padding-top: calc(var(--header-h) + var(--sp-6));
}
/* Fil d'Ariane */
.breadcrumb { margin-bottom: var(--sp-3); }
.breadcrumb__list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .06em;
}
.breadcrumb__list li { display: inline-flex; align-items: center; gap: var(--sp-2); }
.breadcrumb__list li + li::before {
  content: '';
  width: 5px; height: 5px;
  border-top: 1px solid var(--c-muted-on-dark);
  border-right: 1px solid var(--c-muted-on-dark);
  transform: rotate(45deg);
}
.breadcrumb a {
  color: var(--c-muted-on-dark);
  transition: color var(--t-fast);
}
.breadcrumb a:hover { color: var(--c-white); }
.breadcrumb [aria-current="page"] { color: var(--c-red); }
.page-head__title {
  font-size: clamp(2.4rem, 7vw, 5rem);
  color: var(--c-white);
}
.page-head__title .accent { color: var(--c-red); }
.page-head__lead {
  margin-top: var(--sp-3);
  /* pas de largeur maximale : l'accroche tient sur une ligne tant que
     la place le permet, et se replie d'elle-même sur écran étroit */
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--c-muted-on-dark);
}
.page-body { min-height: 30vh; }
/* Texte courant dans un panneau clair */
.prose__title {
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  color: var(--c-ink);
  margin-bottom: var(--sp-4);
}
.prose__title .accent { color: var(--c-red); }
.prose { max-width: 78ch; color: var(--c-ink); }
.prose p { line-height: 1.7; }
.prose p + p { margin-top: var(--sp-3); }

/* Un texte courant n'est pas fait que de paragraphes : il peut porter des
   intertitres, des listes, des liens et du gras. Le reset ayant dépouillé ces
   balises, on les rhabille ici — une seule fois, aux valeurs du reste du
   panneau clair. */
.prose h2 {
  font-size: clamp(1.35rem, 2.4vw, 1.9rem);
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
}
.prose h3 {
  font-size: 1.2rem;
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-2);
}
.prose :is(h2, h3):first-child { margin-top: 0; }
.prose ul, .prose ol { margin-top: var(--sp-3); display: grid; gap: var(--sp-2); }
.prose li { position: relative; padding-left: 22px; line-height: 1.7; }
.prose ul li::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--c-red);
}
.prose ol { counter-reset: prose; }
.prose ol li { counter-increment: prose; }
.prose ol li::before {
  content: counter(prose) '.';
  position: absolute;
  left: 0;
  color: var(--c-red);
  font-weight: 700;
}
.prose a {
  color: var(--c-red);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.prose a:hover { text-decoration-thickness: 2px; }
.prose b, .prose strong { font-weight: 700; }
.prose em { font-style: italic; }

/* --- Encadrants : cartes portrait pleine image ---
   La photo occupe toute la carte, en couleurs naturelles, posée sur le dégradé
   rouge/noir de marque : les portraits détourés (PNG transparent) laissent donc
   voir ce fond. Au survol la photo s'approche : c'est ce mouvement qui rend la
   grille vivante plutôt qu'une simple vignette. */
.staff {
  /* Largeur de carte unique, réglable ici pour toutes les pages d'équipes */
  --staff-card-w: 240px;
  display: grid;
  /* Colonnes de largeur fixe : une carte fait la même taille qu'il y ait un ou
     trois encadrants. En 1fr, la grille étirait les cartes sur toute la largeur
     disponible — sur un grand écran, un encadrant seul occupait un pavé de
     600px de large.
     auto-fit et non auto-fill : les colonnes vides s'effondrent, la rangée
     mesure donc exactement les cartes présentes et peut être centrée dans le
     panneau — sinon les colonnes vides occuperaient la largeur restante et
     caleraient les cartes à gauche. */
  grid-template-columns: repeat(auto-fit, var(--staff-card-w));
  justify-content: center;
  gap: var(--sp-4);
}
/* Une ou deux personnes à l'affiche : la carte garde la taille de référence
   (celle des trois cartes de l'école de hand), on centre simplement la ligne
   au lieu de laisser les cartes calées à gauche devant du vide. Le nombre de
   colonnes est fixé ici, sinon les colonnes vides de auto-fill occuperaient
   toute la largeur et il n'y aurait plus rien à centrer. */
@media (min-width: 621px) {
  .staff--solo,
  .staff--duo {
    /* Largeur de référence : celle de la rangée de trois cartes de l'école de
       hand. Une ou deux cartes se partagent exactement cette largeur, donc le
       bloc occupe la même place dans le panneau blanc, quelle que soit la page. */
    --staff-row-w: calc(3 * var(--staff-card-w) + 2 * var(--sp-4));
    justify-content: center;
  }
  .staff--solo { grid-template-columns: minmax(0, var(--staff-row-w)); }
  .staff--duo {
    grid-template-columns: repeat(2, minmax(0, calc((var(--staff-row-w) - var(--sp-4)) / 2)));
  }
  /* Seule la largeur change : la hauteur reste celle d'une carte de l'école de
     hand (sa largeur de référence × 4/3, le format portrait des cartes). Sans
     cette hauteur fixe, l'aspect-ratio 3/4 rendrait le cadre élargi aussi haut
     que large — plus de 1000px pour un encadrant seul. */
  .staff--solo .staff__card,
  .staff--duo  .staff__card {
    /* aspect-ratio doit être neutralisé : avec une hauteur définie, il
       recalculerait la largeur à 3/4 de celle-ci et la carte refuserait
       de s'étendre sur sa colonne. */
    aspect-ratio: auto;
    height: calc(var(--staff-card-w) * 4 / 3);
  }
  /* Le portrait n'est donc pas recadré : il se pose au centre du cadre, à la
     taille exacte qu'il a sur l'école de hand. En « cover », l'élargissement
     aurait zoomé dans la photo et coupé la tête. */
  .staff--solo .staff__photo,
  .staff--duo  .staff__photo {
    object-fit: contain;
    object-position: center bottom;
  }
}

/* Sous 620px la largeur fixe laisserait un vide disgracieux : les cartes
   reprennent le partage de la ligne, à deux puis à une colonne. */
@media (max-width: 620px) {
  .staff { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* L'annuaire garde ses petites cartes : à deux colonnes pleine largeur, ses
     vingt-deux fiches rallongeraient la page pour rien. */
  .staff--annuaire { grid-template-columns: repeat(auto-fit, var(--staff-card-w)); }
}
@media (max-width: 480px) {
  .staff { grid-template-columns: minmax(0, 1fr); }
  /* Sous 480px deux colonnes de 190px ne tiennent plus : elles se partagent
     la largeur, ce qui reste deux fois plus court qu'une colonne unique. */
  .staff--annuaire { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.staff__card {
  /* Fond de carte commun aux portraits et aux cartes à initiales.
     Déclaré ici et non sur la liste : un var() imbriqué dans une variable est
     résolu sur l'élément qui la déclare. Posé sur la carte, le dégradé suit
     donc les couleurs de la carte — une carte marquée .theme-sud93 dans une
     liste par ailleurs rouge vire au violet, fond compris. */
  --staff-backdrop:
    radial-gradient(120% 90% at 30% 15%, rgba(var(--c-red-rgb), .55), transparent 62%),
    linear-gradient(160deg, var(--c-shade) 0%, #0B0B0D 100%);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-xl);
  background: var(--c-dark);
  transition: transform .45s cubic-bezier(.22, 1, .36, 1),
              box-shadow .45s ease;
}
.staff__card:hover {
  transform: translateY(-6px);
  box-shadow: 0 22px 40px rgba(0, 0, 0, .3);
}
.staff__media {
  position: absolute;
  inset: 0;
  background: var(--staff-backdrop);
}
.staff__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
  transition: transform .6s cubic-bezier(.22, 1, .36, 1);
}
.staff__card:hover .staff__photo {
  transform: scale(1.06);
}

/* En l'absence de photo : aplat de marque + initiales, plutôt qu'un trou */
.staff__fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--staff-backdrop);
  font-family: var(--font-display);
  font-size: 3.2rem;
  letter-spacing: .06em;
  color: rgba(255, 255, 255, .16);
  transition: color .5s ease, transform .6s cubic-bezier(.22, 1, .36, 1);
}
.staff__card:hover .staff__fallback {
  color: rgba(255, 255, 255, .26);
  transform: scale(1.06);
}
/* Voile rouge de marque : réservé aux cartes sans photo, il s'efface au survol */
.staff__fallback::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--c-red);
  mix-blend-mode: color;
  opacity: .85;
  transition: opacity .5s ease;
}
.staff__card:hover .staff__fallback::after { opacity: 0; }

/* Dégradé de lecture sous le nom */
.staff__card::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 62%;
  pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(8, 8, 10, .88) 72%);
}
.staff__info {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 1;
  padding: var(--sp-4);
}
.staff__role {
  position: relative;
  display: inline-block;
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .64rem;
  letter-spacing: .14em;
  color: var(--c-red);
  padding-bottom: 8px;
  white-space: nowrap;
}
/* Le texte reste toujours lisible ; c'est le filet qui se déploie au survol */
.staff__role::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 26px;
  height: 2px;
  background: var(--c-red);
  transition: width .5s cubic-bezier(.22, 1, .36, 1);
}
.staff__card:hover .staff__role::after { width: 100%; }
/* --- Annuaire des entraîneurs ---
   Vingt-deux cartes sur une seule page : elles sont plus petites qu'ailleurs,
   sinon la page n'en finit plus au défilement. */
.staff--annuaire { --staff-card-w: 190px; }
/* Un même encadrant couvre parfois plusieurs collectifs : son rôle tient sur
   deux lignes plutôt que de déborder de la carte. */
.staff--annuaire .staff__role { white-space: normal; font-size: .58rem; }
.staff--annuaire .staff__name { font-size: 1rem; }
.staff--annuaire .staff__fallback { font-size: 2.6rem; }
.staff--annuaire .staff__info { padding: var(--sp-3); }

/* Barre de filtres de l'annuaire : titre à gauche, pôles à droite */
.annuaire-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.annuaire-bar .prose__title { margin-bottom: 0; }
/* Chips en pastille : les chips carrées de 76px sont taillées pour des
   libellés courts (« SM1 »), pas pour « École de hand & U11 ». */
.chips--pill { flex-wrap: wrap; justify-content: flex-end; }
.chip--pill {
  width: auto;
  min-height: 0;
  flex-direction: row;
  border-radius: var(--r-pill);
  padding: 9px 16px;
  font-size: .68rem;
  letter-spacing: .06em;
  box-shadow: none;
  border-color: var(--c-grey-line);
  transition: border-color var(--t-fast), color var(--t-fast);
}
/* L'effectif d'un filtre, dans sa pastille. Assez présent pour se lire,
   assez discret pour rester derrière le libellé. */
.chip__n {
  margin-left: 7px;
  opacity: .55;
  font-variant-numeric: tabular-nums;
}
.chip--pill.is-active .chip__n { opacity: .75; }
.chip--pill:hover { border-color: var(--c-red); }
.chip--pill.is-active { background: var(--c-red); border-color: var(--c-red); color: var(--c-white); }
.staff__name {
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.2rem;
  line-height: 1.1;
  letter-spacing: .01em;
  color: var(--c-white);
}

@media (prefers-reduced-motion: reduce) {
  .staff__card,
  .staff__photo,
  .staff__fallback,
  .staff__fallback::after,
  .staff__role::after { transition: none; }
}

/* Respiration avant un second titre dans le même panneau */
.prose__title--space { margin-top: var(--sp-7); }

/* --- Liste à puces cochées (ce que propose une activité) --- */
.checklist {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-3);
  color: var(--c-ink);
}
.checklist li {
  position: relative;
  padding-left: 34px;
  line-height: 1.5;
}
.checklist li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 1px;
  width: 20px;
  height: 20px;
  border-radius: var(--r-pill);
  background: var(--c-red)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E")
    center / 13px no-repeat;
}

/* --- Stage : flyer à gauche, informations à droite ---
   L'affiche du stage change à chaque période de vacances : son emplacement est
   réservé en permanence, et affiche un cadre d'attente tant qu'aucun fichier
   n'est déposé. */
.stage {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
}
@media (max-width: 820px) {
  .stage { grid-template-columns: minmax(0, 1fr); }
}
/* Colonne d'informations : un même intervalle entre le texte, les chiffres et
   le bandeau de dates. Sans ça, les chiffres clés (marge propre) collaient au
   bandeau qui suit (aucune marge haute) et les trois blocs se touchaient. */
.stage__infos {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
}
.stage__infos .keyfigures { margin-top: 0; }
.stage__infos .promo-bar { margin-bottom: 0; }
.stage__flyer {
  border-radius: var(--r-xl);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--c-grey-bg);
}
.stage__flyer img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Cadre d'attente : visible tant que le club n'a pas d'affiche à mettre */
.stage__flyer--vide {
  display: grid;
  place-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4);
  text-align: center;
  border: 2px dashed var(--c-grey-line);
  background: rgba(0, 0, 0, .03);
  color: var(--c-ink-soft);
}
.stage__flyer--vide b {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .74rem;
  letter-spacing: .12em;
  color: var(--c-ink);
}
.stage__flyer--vide span { font-size: .85rem; line-height: 1.5; max-width: 26ch; }

/* Tarifs : une carte par formule, deux publics */
.tarifs__public {
  margin-top: var(--sp-5);
  margin-bottom: var(--sp-3);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .74rem;
  letter-spacing: .14em;
  color: var(--c-red);
}
.tarifs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-3);
}
.tarif {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--c-dark);
  color: var(--c-white);
}
.tarif__formule {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .1em;
  color: var(--c-muted-on-dark);
}
.tarif__prix {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 3vw, 2.4rem);
  line-height: 1;
  color: var(--c-red);
}
.tarif__prix span {
  display: block;
  margin-top: 6px;
  font-family: var(--font-body);
  font-size: .85rem;
  color: var(--c-muted-on-dark);
}
.tarif .btn { margin-top: auto; align-self: flex-start; }

/* --- Formulaire (soutien scolaire) ---
   Champs clairs sur le panneau blanc, deux colonnes qui retombent à une seule
   sur mobile. Le rouge n'apparaît qu'au focus : c'est le repère de saisie. */
.form { margin-top: var(--sp-5); }
.form__grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-4);
}
.form__champ { display: flex; flex-direction: column; gap: 8px; }
.form__champ--large { grid-column: 1 / -1; }
.form__label {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .7rem;
  letter-spacing: .1em;
  color: var(--c-ink);
}
.form__label span { color: var(--c-red); }
.form__input,
.form__select,
.form__textarea {
  width: 100%;
  padding: 13px 16px;
  border: 1px solid var(--c-grey-line);
  border-radius: var(--r-md);
  background: var(--c-white);
  font-family: var(--font-body);
  font-size: .95rem;
  color: var(--c-ink);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.form__textarea { min-height: 140px; resize: vertical; }
.form__input:focus,
.form__select:focus,
.form__textarea:focus {
  outline: none;
  border-color: var(--c-red);
  box-shadow: 0 0 0 3px rgba(var(--c-red-rgb), .14);
}
.form__envoi {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-5);
}
.form__note { font-size: .85rem; color: var(--c-ink-soft); }

/* --- Coordonnées en cartes cliquables (dans la bulle de contact) ---
   Chaque ligne est une action — ouvrir l'itinéraire, appeler — d'où le
   traitement en bouton plutôt qu'en liste de texte. */
.coords { font-style: normal; display: grid; gap: var(--sp-2); margin-top: var(--sp-4); }
.coords__ligne {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--c-grey-line);
  background: var(--c-white);
  color: var(--c-ink);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
a.coords__ligne:hover,
a.coords__ligne:focus-visible {
  border-color: var(--c-red);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .07);
}
.coords__ico { width: 20px; height: 20px; flex: 0 0 auto; margin-top: 2px; fill: var(--c-red); fill-rule: evenodd; }
.coords__txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.coords__l {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .62rem;
  letter-spacing: .1em;
  color: var(--c-ink-soft);
}
.coords__v {
  font-size: .95rem;
  line-height: 1.35;
  /* Une adresse électronique plus large que la carte se coupe plutôt que
     de déborder — même règle qu'au pied de page. */
  overflow-wrap: break-word;
}
.coords__d { font-size: .82rem; color: var(--c-ink-soft); }

/* ===========================
   16b. Bulle de contact
   ---------------------------
   Il n'y a pas de page « contact » : écrire au club se fait d'où l'on
   est, depuis n'importe quelle page. Le bouton flottant reste au coin
   bas-droit, le panneau s'ouvre au-dessus de lui.
   Sous le header (z-index 50) pour ne jamais recouvrir un menu ouvert.
   =========================== */
/* Les deux bulles partagent ce coin : les réseaux au-dessus, le contact
   en bas — le plus important sous le pouce.
   Chaque bulle ne fait que la taille de son bouton ; ce qui se déplie est
   posé par-dessus, en absolu. Tant que le panneau comptait dans le flux,
   la boîte mesurait 380 × 620 px — un rectangle invisible qui poussait le
   bouton au milieu de l'écran et avalait tous les clics du coin, dont
   celui de « Espace bénévoles » au pied de page.
   pointer-events reste à none par sécurité : ce qui doit être cliquable
   le redemande explicitement. */
.bulles {
  position: fixed;
  right: clamp(14px, 3vw, 28px);
  bottom: clamp(14px, 3vw, 28px);
  z-index: 45;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-2);
  pointer-events: none;
}
.bulle { position: relative; }
.bulle__lanceur {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 54px;
  padding: 0 22px 0 18px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--c-red);
  color: var(--c-white);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .78rem;
  letter-spacing: .07em;
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .28);
  transition: background var(--t-fast), transform var(--t-fast), opacity var(--t-fast);
}
.bulle__lanceur:hover { background: var(--c-red-dark); }
.bulle__lanceur:active { transform: scale(.97); }

/* --- L'atterrissage dans le pied de page ---------------------------------
   Arrivé en bas, le bouton flottant n'a plus lieu d'être : le pied de page
   porte le sien, au milieu des coordonnées. Les deux ne doivent jamais
   paraître ensemble — ce serait deux fois le même bouton à l'écran.
   Le relais se fait par une classe posée sur <html> par js/main.js, qui
   surveille l'entrée du bouton du pied dans la fenêtre. La classe
   `bulle-atterrissage` dit seulement « le script est là » : sans elle, le
   bouton du pied reste visible en toutes circonstances. */
/* Le relais fonctionne : le bouton flottant s'efface avant qu'on arrive en
   bas, la réserve du pied de page n'a plus lieu d'être. */
html.bulle-atterrissage .footer { padding-bottom: var(--sp-4); }

html.bulle-atterrissage .footer__ecrire {
  opacity: 0;
  transform: translateY(10px) scale(.96);
  pointer-events: none;
  transition: opacity var(--t-fast), transform var(--t-fast), background var(--t-fast);
}
/* `:not(.bulle-ouverte)` : bulle ouverte, c'est la poignée du coin qui
   sert, et le bouton du pied s'efface — jamais deux à la fois. */
html.bulle-atterrissage.bulle-posee:not(.bulle-ouverte) .footer__ecrire {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
/* Ouverte, la bulle garde son bouton : c'est devenu la poignée qui referme. */
html.bulle-atterrissage.bulle-posee .bulle:not(.bulle--reso):not(.est-ouverte) .bulle__lanceur {
  opacity: 0;
  transform: translateY(10px) scale(.9);
  pointer-events: none;
}

/* Le même relais pour les réseaux, sur leur propre repère : les pastilles
   du pied de page ne sont pas à la même hauteur que le bouton « Écrire au
   club », les deux échanges ne se font donc pas au même moment. */
html.bulle-atterrissage .footer__suivre {
  opacity: 0;
  transform: translateY(10px) scale(.96);
  pointer-events: none;
  transition: opacity var(--t-fast), transform var(--t-fast);
}
html.bulle-atterrissage.reseaux-poses .footer__suivre {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
html.bulle-atterrissage.reseaux-poses .bulle--reso:not(.est-ouverte) .bulle__lanceur {
  opacity: 0;
  transform: translateY(10px) scale(.9);
  pointer-events: none;
}

/* Le panneau du contact se déplie juste au-dessus du bouton des réseaux et
   le recouvrirait. Tant qu'il est ouvert, les réseaux s'effacent. */
html.bulle-ouverte .bulle--reso {
  opacity: 0;
  transform: translateY(6px) scale(.92);
  pointer-events: none;
  transition: opacity var(--t-fast), transform var(--t-fast);
}
@media (prefers-reduced-motion: reduce) {
  html.bulle-atterrissage .footer__suivre,
  html.bulle-ouverte .bulle--reso,
  html.bulle-atterrissage.reseaux-poses .bulle--reso:not(.est-ouverte) .bulle__lanceur {
    transform: none;
    transition: none;
  }
}
@media (prefers-reduced-motion: reduce) {
  html.bulle-atterrissage .footer__ecrire,
  html.bulle-atterrissage.bulle-posee .bulle:not(.est-ouverte) .bulle__lanceur {
    transform: none;
    transition: none;
  }
}
.bulle__lanceur-i { display: grid; place-items: center; width: 22px; height: 22px; }
.bulle__lanceur-i svg { width: 22px; height: 22px; fill: currentColor; }
/* Ouverte, la bulle n'a plus besoin de s'annoncer : le panneau la remplace
   et le lanceur redevient une simple poignée pour refermer. */
.bulle.est-ouverte .bulle__lanceur-l { display: none; }
.bulle.est-ouverte .bulle__lanceur { padding: 0 16px; }

/* --- La bulle des réseaux -------------------------------------------------
   Au rouge du club, comme celui du contact : en presque noir, il se perdait
   sur les fonds sombres du site. Ce qui les distingue n'est pas la couleur
   mais la forme — un rond contre une pilule — et le dessin qu'il porte. */
.bulle__lanceur--rond {
  width: 48px;
  height: 48px;
  padding: 0;
  justify-content: center;
  background: var(--c-red);
  border: 1px solid var(--c-red);
  box-shadow: 0 8px 20px rgba(0, 0, 0, .28);
}
.bulle__lanceur--rond:hover { background: var(--c-red-dark); border-color: var(--c-red-dark); }
.bulle__lanceur--rond .bulle__lanceur-i svg { width: 20px; height: 20px; }
/* Déplié, le bouton bascule d'un quart de tour et fonce : le signe que le
   geste a été pris, sans changer de dessin. */
.bulle--reso.est-ouverte .bulle__lanceur--rond {
  background: var(--c-red-dark);
  border-color: var(--c-red-dark);
  transform: rotate(90deg);
}

.reso__liste {
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--sp-2));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
}
.reso__lien {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  background: var(--c-white);
  color: var(--c-ink);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .26);
  /* Repliées : rangées derrière le bouton, invisibles et hors clavier.
     Le --i posé par js/layout.js décale chaque pastille, ce qui les fait
     monter l'une après l'autre au lieu d'apparaître en bloc. */
  opacity: 0;
  transform: translateY(14px) scale(.7);
  pointer-events: none;
  transition: opacity .18s ease, transform .18s ease, background var(--t-fast), color var(--t-fast);
  transition-delay: calc(var(--i, 0) * 30ms);
}
.bulle--reso.est-ouverte .reso__lien {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.reso__lien svg { width: 21px; height: 21px; fill: currentColor; fill-rule: evenodd; }
.reso__lien:hover,
.reso__lien:focus-visible { background: var(--c-red); color: var(--c-white); }
/* Réseau dont on n'a pas le glyphe : son nom, plutôt qu'une pastille muette. */
.reso__lien--texte {
  width: auto;
  padding: 0 16px;
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .68rem;
  letter-spacing: .08em;
}
@media (prefers-reduced-motion: reduce) {
  .reso__lien { transform: none; transition-delay: 0s; }
  .bulle--reso.est-ouverte .bulle__lanceur--rond { transform: none; }
}

.bulle__panneau {
  /* Au-dessus du bouton, et hors du flux : c'est ce qui garde la boîte de
     la bulle à la taille du seul bouton. */
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--sp-3));
  width: min(380px, calc(100vw - 28px));
  max-height: min(560px, calc(100vh - 120px));
  display: flex;
  flex-direction: column;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--c-white);
  color: var(--c-ink);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .34);
  /* Fermé, le panneau n'occupe plus l'écran ni le clavier (inert est posé
     par js/main.js) ; visibility l'ôte aussi du lecteur d'écran. */
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(.98);
  transform-origin: bottom right;
  pointer-events: none;
  /* `visibility` ne se fond pas, elle bascule : à la fermeture on retarde
     la bascule jusqu'à la fin du fondu, à l'ouverture elle est immédiate
     (règle suivante). Sans cela, le panneau reste « hidden » pendant toute
     la transition d'ouverture — donc non focusable, et js/main.js ne peut
     pas y poser le curseur. */
  transition: opacity var(--t-fast), transform var(--t-fast), visibility 0s linear .2s;
}
.bulle.est-ouverte .bulle__panneau {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
  transition: opacity var(--t-fast), transform var(--t-fast), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .bulle__panneau { transition: none; transform: none; }
}

.bulle__tete {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 14px 14px 14px 18px;
  background: var(--c-dark-deep);
  color: var(--c-white);
}
.bulle__titre {
  flex: 1;
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1rem;
  letter-spacing: .02em;
}
.bulle__retour,
.bulle__fermer {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: rgba(255, 255, 255, .1);
  color: var(--c-white);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background var(--t-fast);
}
.bulle__retour { padding: 0 12px 0 8px; height: 32px; font-size: .74rem;
  font-family: var(--font-title); text-transform: uppercase; letter-spacing: .07em; }
.bulle__fermer { width: 32px; height: 32px; justify-content: center; }
.bulle__retour:hover,
.bulle__fermer:hover { background: rgba(255, 255, 255, .22); }
.bulle__retour svg { width: 16px; height: 16px; fill: currentColor; }
.bulle__fermer svg { width: 18px; height: 18px; fill: currentColor; }
/* Le retour prend la place du titre quand il paraît : deux lignes de tête
   feraient sauter le panneau à chaque passage d'une vue à l'autre. */
.bulle__retour[hidden] { display: none; }

.bulle__corps {
  padding: var(--sp-4) 18px var(--sp-5);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.bulle__texte { font-size: .92rem; line-height: 1.55; color: var(--c-ink-soft); }
.bulle__choix { display: grid; gap: var(--sp-2); margin-top: var(--sp-4); }

/* Les deux portes. Même forme, une couleur chacune : le rouge du club
   pour l'e-mail, le vert de WhatsApp pour l'autre — c'est à ça qu'on
   les reconnaît sans lire. */
.bulle__porte {
  --porte: var(--c-red);
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 14px 14px 14px 16px;
  border: 1px solid var(--c-grey-line);
  border-radius: var(--r-lg);
  background: var(--c-white);
  color: var(--c-ink);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
}
.bulle__porte:hover,
.bulle__porte:focus-visible {
  border-color: var(--porte);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .09);
}
.bulle__porte:active { transform: scale(.99); }
.bulle__porte--wa { --porte: #25D366; }
.bulle__porte-i {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-pill);
  background: var(--porte);
}
.bulle__porte-i svg { width: 21px; height: 21px; fill: var(--c-white); fill-rule: evenodd; }
.bulle__porte-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.bulle__porte-t {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .82rem;
  letter-spacing: .05em;
}
.bulle__porte-s { font-size: .8rem; line-height: 1.35; color: var(--c-ink-soft); }
.bulle__porte-f .arrow-dot {
  width: 28px; height: 28px;
  background: rgba(0, 0, 0, .06);
}
.bulle__porte-f .arrow-dot svg { width: 13px; height: 13px; fill: var(--c-ink-soft); }
.bulle__porte:hover .bulle__porte-f .arrow-dot { background: var(--porte); }
.bulle__porte:hover .bulle__porte-f .arrow-dot svg { fill: var(--c-white); }

/* Les coordonnées, sous les deux portes : qui veut seulement l'adresse
   du gymnase ou le numéro n'a pas à ouvrir un formulaire. */
.bulle__fiche { margin-top: var(--sp-5); }
.bulle__fiche::before {
  content: 'Ou nous retrouver';
  display: block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .64rem;
  letter-spacing: .1em;
  color: var(--c-ink-soft);
}
/* Le formulaire tient dans 380 px : une colonne, marges resserrées. */
.form--bulle { margin-top: 0; }
.form--bulle .form__grille { grid-template-columns: 1fr; gap: var(--sp-3); }
.form--bulle .form__textarea { min-height: 104px; }
.form--bulle .form__envoi { margin-top: var(--sp-4); flex-direction: column; align-items: stretch; gap: var(--sp-2); }
.form--bulle .form__envoi .btn { justify-content: center; }
.form--bulle .form__note { font-size: .78rem; }
/* L'adresse en clair sous le formulaire : discrète, mais lisible et
   sélectionnable — c'est le seul endroit du site où elle s'écrit. */
.form__adresse {
  color: var(--c-red);
  text-decoration: underline;
  text-underline-offset: 2px;
  overflow-wrap: break-word;
}
.form__adresse:hover { color: var(--c-red-dark); }

@media (max-width: 480px) {
  /* Sur un téléphone, le panneau prend la largeur : à 380 px de large sur
     un écran de 375, il resterait deux bandes de vide sur les côtés.
     Le conteneur, lui, reste calé à droite — c'est le panneau qui s'étire,
     par sa propre position. */
  .bulle__panneau {
    position: fixed;
    left: clamp(10px, 3vw, 28px);
    right: clamp(14px, 3vw, 28px);
    /* juste au-dessus du bouton : sa marge basse + sa hauteur + l'écart */
    bottom: calc(clamp(14px, 3vw, 28px) + 54px + var(--sp-3));
    width: auto;
    max-height: calc(100vh - 140px);
  }
}

/* --- Partenaires : cartes logo + présentation ---
   Cartes sombres sur le panneau clair : les logos fournis sont tous en version
   blanche (assets/images/web/partenaires/*-white.png), invisibles sur blanc.
   Le fond sombre est celui des panneaux `--dark`, l'ensemble reste dans la
   famille visuelle des cartes encadrants. */
.partenaires {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: var(--sp-4);
}
.partenaire {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--r-xl);
  background: linear-gradient(135deg, #1E1E24 0%, #121216 100%);
  transition: border-color var(--t-fast), box-shadow var(--t-fast),
              transform .45s cubic-bezier(.22, 1, .36, 1);
}
.partenaire:hover {
  border-color: var(--c-red);
  box-shadow: 0 22px 40px rgba(0, 0, 0, .3);
  transform: translateY(-4px);
}
/* Hauteur de logo fixe : des logos aux proportions très différentes
   (carré, bandeau, monogramme) s'alignent ainsi sur une même ligne d'appui. */
.partenaire__logo {
  display: flex;
  align-items: center;
  min-height: 60px;
}
.partenaire__logo img {
  max-height: 60px;
  max-width: 72%;
  object-fit: contain;
  object-position: left center;
}
/* Plaque blanche pour les logos qui n'existent qu'en version couleur foncée :
   ils seraient illisibles à même la carte sombre. */
.partenaire__logo--plaque {
  align-self: flex-start;
  padding: 10px 14px;
  border-radius: var(--r-md);
  background: var(--c-white);
}
.partenaire__logo--plaque img { max-height: 40px; max-width: 100%; }
/* Sans fichier de logo, le nom prend sa place dans la typo de titrage */
.partenaire__logo--texte {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--c-white);
}
.partenaire__nom {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .7rem;
  letter-spacing: .14em;
  color: var(--c-red);
}
.partenaire__texte {
  flex: 1;
  color: var(--c-muted-on-dark);
  font-size: .95rem;
  line-height: 1.6;
}
.partenaire__liens {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-4);
  margin-top: auto;
}
.partenaire__lien {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .08em;
  color: var(--c-white);
  transition: color var(--t-fast);
}
.partenaire__lien:hover { color: var(--c-red); }
.partenaire__lien .arrow-dot { width: 30px; height: 30px; }
.partenaire__lien .arrow-dot svg { width: 13px; height: 13px; }
/* Lien secondaire : renvoi vers notre propre article, en retrait */
.partenaire__lien--doux {
  color: rgba(255, 255, 255, .55);
  text-transform: none;
  font-family: var(--font-body);
  letter-spacing: 0;
  font-size: .85rem;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Chiffres clés */
.keyfigures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--sp-3);
  margin-top: var(--sp-6);
}
.keyfigure {
  padding: var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--c-dark);
  text-align: center;
}
.keyfigure b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 3.5vw, 2.8rem);
  line-height: 1;
  color: var(--c-red);
}
.keyfigure span {
  display: block;
  margin-top: 6px;
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .06em;
  color: var(--c-muted-on-dark);
}

/* ===========================
   17. Apparition au défilement (piloté par js/main.js)
   =========================== */
.reveal-actif [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity .5s ease,
    transform .6s cubic-bezier(.22, 1, .36, 1);
}
.reveal-actif [data-reveal].is-visible { opacity: 1; transform: none; }

/* Contenu centré (page d'inscription) */
.section-panel--center { text-align: center; }
.prose--center { margin-inline: auto; max-width: 66ch; }

/* Parcours en trois étapes, reliées par un trait */
.stepper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}
.stepper__item { position: relative; padding-inline: var(--sp-2); }
/* trait de liaison entre deux jalons, à hauteur des pastilles */
.stepper__item + .stepper__item::before {
  content: '';
  position: absolute;
  top: 27px;
  right: 50%;
  width: calc(100% + var(--sp-4));
  height: 2px;
  background: var(--c-grey-line);
  transform-origin: left center;
}
/* Le parcours se dessine : les traits se tirent, les pastilles se posent */
.reveal-actif .stepper[data-reveal] .stepper__item + .stepper__item::before {
  transform: scaleX(0);
  transition: transform .55s cubic-bezier(.22, 1, .36, 1);
}
.reveal-actif .stepper[data-reveal].is-visible .stepper__item + .stepper__item::before {
  transform: scaleX(1);
}
.reveal-actif .stepper[data-reveal] .stepper__num {
  transform: scale(.6);
  opacity: 0;
  transition:
    transform .45s cubic-bezier(.34, 1.4, .64, 1),
    opacity .3s ease;
}
.reveal-actif .stepper[data-reveal].is-visible .stepper__num { transform: none; opacity: 1; }
/* chaque jalon arrive après le précédent */
.reveal-actif .stepper[data-reveal].is-visible .stepper__item:nth-child(2) .stepper__num { transition-delay: .18s; }
.reveal-actif .stepper[data-reveal].is-visible .stepper__item:nth-child(3) .stepper__num { transition-delay: .36s; }
.reveal-actif .stepper[data-reveal].is-visible .stepper__item:nth-child(2)::before { transition-delay: .1s; }
.reveal-actif .stepper[data-reveal].is-visible .stepper__item:nth-child(3)::before { transition-delay: .28s; }
.stepper__num {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 54px; height: 54px;
  margin: 0 auto var(--sp-3);
  border-radius: var(--r-pill);
  background: var(--c-dark);
  color: var(--c-white);
  font-family: var(--font-display);
  font-size: 1.4rem;
  line-height: 1;
  box-shadow: 0 0 0 6px var(--c-white);   /* masque le trait derrière la pastille */
}
.stepper__title { font-size: 1rem; color: var(--c-ink); margin-bottom: 6px; }
.stepper__text {
  max-width: 30ch;
  margin-inline: auto;
  font-size: .9rem;
  line-height: 1.55;
  color: var(--c-ink-soft);
}

/* Bloc d'inscription : le point d'arrivée de la page */
.signup {
  position: relative;
  overflow: hidden;
  isolation: isolate;              /* les fusions de calques restent contenues au bloc */
  margin-top: var(--sp-7);
  border-radius: var(--r-xl);
  background: linear-gradient(135deg, #1E1E24 0%, #0B0B0D 100%);
  box-shadow: 0 24px 50px rgba(0, 0, 0, .28);
}
/* Le blason du club en fond : grand, débordant à droite, en blanc très
   sourd sur le panneau sombre. Un dégradé de masquage l'éteint vers la
   gauche pour que le texte reste sur un fond net. */
.signup__crest {
  position: absolute;
  top: 50%;
  right: -8%;
  height: 210%;
  aspect-ratio: 1;
  transform: translateY(-50%);
  pointer-events: none;
  background-image: url('../assets/images/logos/MHB/Logo%20MHB%20blanc.png');
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  opacity: .1;
  -webkit-mask-image: linear-gradient(100deg, transparent 8%, #000 46%);
          mask-image: linear-gradient(100deg, transparent 8%, #000 46%);
}
/* Grain : casse le côté lisse des aplats numériques */
.signup__grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: .5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23b)' opacity='.42'/%3E%3C/svg%3E");
}
.reveal-actif .signup__crest { opacity: 0; transition: opacity 1.4s ease .3s; }
.reveal-actif [data-reveal].is-visible .signup__crest { opacity: .1; }

@media (prefers-reduced-motion: reduce) {
  .reveal-actif .signup__crest { transition: none; }
}
/* Lueur rouge diffuse derrière le bouton, dans le fond du bloc */
.signup::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -30%;
  width: min(560px, 80%);
  aspect-ratio: 1;
  transform: translateX(-50%);
  background: radial-gradient(closest-side, rgba(196, 26, 56, .12), transparent 70%);
  pointer-events: none;
}
.signup__inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(32px, 5vw, 60px) clamp(24px, 4vw, 56px);
}
.signup__kicker {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .16em;
  color: rgba(255, 255, 255, .8);   /* le rouge se perdrait sur la photo rouge */
}
.signup__title {
  margin-top: var(--sp-2);
  font-size: clamp(1.8rem, 4vw, 3rem);
  color: var(--c-white);
  text-shadow: 0 2px 18px rgba(0, 0, 0, .5);
}
.signup__title .accent { color: var(--c-red); }
.signup__text {
  margin-top: var(--sp-3);
  max-width: 48ch;
  line-height: 1.6;
  color: rgba(255, 255, 255, .82);
  text-shadow: 0 1px 12px rgba(0, 0, 0, .45);
}
/* Signature sous le titre (bloc « Le club » de l'accueil) */
.signup__baseline {
  margin-top: var(--sp-2);
  font-family: var(--font-body);
  font-style: italic;
  font-size: clamp(1.05rem, 1.8vw, 1.45rem);
  color: var(--c-red);
}
/* Liste d'arguments : bloc centré, lignes alignées à gauche pour rester
   lisibles, puces cochées comme sur la page soutien scolaire. */
.signup__list {
  display: grid;
  gap: var(--sp-3);
  margin: var(--sp-5) 0 var(--sp-2);
  text-align: left;
}
.signup__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  line-height: 1.5;
  color: var(--c-text-on-dark);
}
.signup__list li::before {
  content: '';
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  border-radius: var(--r-pill);
  background: var(--c-red)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E")
    center / 13px no-repeat;
}
.signup .stores { margin-top: var(--sp-4); justify-content: center; }

/* Variante alignée à gauche et plus sombre (bloc « Le club » de l'accueil).
   Le bloc d'inscription, lui, reste centré : il conclut sa page, celui-ci
   ouvre une section et s'aligne sur le reste du contenu. */
.signup--gauche {
  background: linear-gradient(135deg, #141418 0%, var(--c-dark-deep) 100%);
}
.signup--gauche .signup__inner { align-items: flex-start; text-align: left; }
.signup--gauche .stores { justify-content: flex-start; }
/* La lueur rouge du bloc d'inscription accompagne son gros bouton rouge ;
   ici il n'y en a pas, elle ne soulignait rien. */
.signup--gauche::before { content: none; }
/* Marges verticales : le bloc est déjà espacé par sa bande, inutile d'en
   rajouter comme sur la page partenaires. */
.signup--gauche.signup--compact { margin-top: 0; margin-bottom: 0; }
.signup--gauche .signup__list { margin: var(--sp-4) 0 var(--sp-2); }
.signup .btn--xl { margin-top: var(--sp-5); }

/* Mention de la plateforme, sous le bouton : repère de confiance */
.signup__platform {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .68rem;
  letter-spacing: .08em;
  color: var(--c-muted-on-dark);
}
.signup__logo {
  height: 24px;
  width: auto;
  border-radius: 5px;
}

/* Variante compacte : le bloc ouvre la page au lieu de la conclure. Moins haut,
   titre plus sage — c'est une porte d'entrée, pas le point d'arrivée. */
.signup--compact { margin-top: var(--sp-5); margin-bottom: var(--sp-6); }
.signup--compact .signup__inner { padding: clamp(24px, 3vw, 38px) clamp(20px, 3vw, 44px); }
.signup--compact .signup__title { font-size: clamp(1.5rem, 3vw, 2.2rem); }
.signup--compact .signup__text { margin-top: var(--sp-2); font-size: .95rem; }
.signup--compact .btn--xl { margin-top: var(--sp-4); }

/* Adresse de contact mise en avant : c'est l'action attendue d'un futur
   partenaire, elle doit se lire d'un coup d'œil, pas se deviner. */
.signup__mail {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding: 10px 18px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .06);
  font-family: var(--font-display);
  font-size: clamp(.95rem, 1.6vw, 1.15rem);
  color: var(--c-white);
  transition: border-color var(--t-fast), background var(--t-fast);
}
.signup__mail:hover { border-color: var(--c-red); background: rgba(255, 255, 255, .1); }
.signup__mail svg { width: 20px; height: 20px; fill: var(--c-red); flex: 0 0 auto; }
.signup__contact {
  margin-top: var(--sp-3);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .68rem;
  letter-spacing: .12em;
  color: var(--c-muted-on-dark);
}

/* Halo rouge sous le bouton : c'est lui qu'on doit voir en premier.
   Il respire lentement — le halo est un pseudo-élément à part, animé en
   transform/opacity, pour ne pas repeindre l'ombre du bouton à chaque image. */
.signup .btn--xl { position: relative; box-shadow: 0 12px 26px rgba(196, 26, 56, .2); }
.signup .btn--xl::after {
  content: '';
  position: absolute;
  inset: -22px;
  z-index: -1;
  border-radius: var(--r-pill);
  background: radial-gradient(closest-side, rgba(196, 26, 56, .32), transparent 72%);
  animation: halo 3.4s ease-in-out infinite;
  pointer-events: none;
}
@keyframes halo {
  0%, 100% { transform: scale(.94); opacity: .3; }
  50%      { transform: scale(1.04); opacity: .55; }
}
/* La flèche avance au survol */
.signup .btn--xl .arrow-dot { transition: transform var(--t-fast); }
.signup .btn--xl:hover .arrow-dot { transform: translateX(4px); }

@media (prefers-reduced-motion: reduce) {
  .signup .btn--xl::after { animation: none; }
}

/* Frise chronologique */
.timeline { display: flex; flex-direction: column; }
.timeline__item {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: var(--sp-4);
  padding: var(--sp-4) 0;
  border-top: 1px solid rgba(0, 0, 0, .1);
}
.timeline__item:first-child { border-top: 0; padding-top: 0; }
.timeline__year {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.15rem;
  line-height: 1.2;
  color: var(--c-red);
}
.timeline__text { max-width: 78ch; color: var(--c-ink); }
.timeline__text p { line-height: 1.7; }
.timeline__text p + p { margin-top: var(--sp-3); }
/* Aparté : liste de noms, anecdote — même texte, moins d'insistance */
.timeline__aside {
  padding-left: var(--sp-3);
  border-left: 2px solid var(--c-grey-line);
  color: var(--c-ink-soft);
  font-size: .92rem;
}
.timeline__item--now .timeline__year { color: var(--c-ink); }
.timeline__item--now .timeline__text { font-size: 1.05rem; }

.error__actions { margin-top: var(--sp-5); }
.error__title {
  font-size: 1.4rem;
  color: var(--c-ink);
  margin-bottom: var(--sp-4);
}
.error__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.error__links a {
  display: inline-block;
  padding: 10px 18px;
  border-radius: var(--r-pill);
  border: 1px solid var(--c-grey-line);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .85rem;
  letter-spacing: .04em;
  color: var(--c-ink);
  transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.error__links a:hover {
  background: var(--c-red);
  border-color: var(--c-red);
  color: var(--c-white);
}
.page-placeholder {
  padding: var(--sp-6) 0;
  text-align: center;
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--c-ink-soft);
}

/* ===========================
   18. Boutons « store » (surtitre + libellé sur deux lignes)
   =========================== */
.stores { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.store {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--c-white); border: none;
  border-radius: var(--r-md); padding: 10px 18px; color: #111;
}
.store svg { width: 28px; height: 28px; fill: #111; }
.store small { display: block; font-size: .58rem; text-transform: uppercase; opacity: .6; letter-spacing: .03em; }
.store b { font-size: 1.1rem; font-family: var(--font-title); }
.store { transition: transform var(--t-fast), box-shadow var(--t-fast); }
.store:hover { transform: translateY(-2px); box-shadow: 0 12px 24px rgba(0, 0, 0, .35); }

/* ===========================
   19. Accueil — actu vedette + liste latérale
   =========================== */
/* Hauteur du panneau blanc (section actus) : marge verticale réduite */
/* Marge basse laissée à la règle générale de la dernière section : le pied
   de page remonte par-dessus et en absorbe une partie, il faut donc la
   calculer à partir du chevauchement — un 88px fixe ne laissait que 22 px
   sous la dernière carte. Et un sélecteur d'identifiant l'emportait sur
   tout le reste, y compris sur ce rattrapage. */
#actualites { padding-top: 88px; }
/* Le panneau de droite empiète sur la photo vedette (cf. capture LNB) :
   le panneau passe au-dessus (z-index sup.) et son bord arrondi mord sur la photo. */
.news-feature {
  /* ============ DIMENSIONS REPRISES DE LNB (un nombre par ligne) ============ */
  --feature-w: 46%;     /* largeur vedette */
  --feature-h: 510px;   /* hauteur vedette */
  --list-w:    51%;     /* largeur panneau */
  --list-pad-y: 40px;   /* marge haut/bas du panneau autour des articles */
  --overlap:   132px;   /* recouvrement : la vedette mord sur le panneau */
  --articles-x: 50px;   /* décalage des articles + traits vers la DROITE */
  --articles-gap: 60px; /* espacement vertical entre les articles */
  --article-h: 120px;   /* hauteur d'UNE ligne d'article (= hauteur de la vignette) */
  --thumb-w:   205px;   /* largeur de la vignette */
  --gap:       0px;     /* écart entre colonnes (0 : le recouvrement gère l'espace) */
  /* Hauteur du panneau (auto) = 3×--article-h + 2×--articles-gap + 2×--list-pad-y */
  /* ======================================================================== */
  display: flex;
  align-items: center;        /* vedette et panneau centrés l'un par rapport à l'autre */
  gap: var(--gap);
}
.feature {
  position: relative;
  z-index: 2;                   /* vedette au-dessus (utile si --overlap > 0) */
  flex: 1 1 var(--feature-w);
  min-height: var(--feature-h);  /* hauteur explicite de la vedette */
  border-radius: var(--r-xl);   /* 24px, comme LNB */
  overflow: hidden;
}
.feature img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.feature__cta { align-self: flex-start; }
.feature__inner {
  position: absolute; inset: 0; z-index: 1;   /* couvre toute la vedette (voile + texte en bas) */
  display: flex; flex-direction: column; justify-content: flex-end; gap: var(--sp-3);
  padding: var(--sp-6);
  background: linear-gradient(180deg, transparent 50%, rgba(0,0,0,.74) 100%);
}
.feature__date { font-family: var(--font-title); text-transform: uppercase; font-size: .8rem; color: var(--c-white); opacity: .85; }
.feature__title { font-family: var(--font-display); text-transform: uppercase; font-size: clamp(1.3rem, .95rem + 1vw, 1.95rem); color: var(--c-white); max-width: none; line-height: 1.06; }
.news-list {
  position: relative;
  z-index: 1;                  /* sous la vedette */
  flex: 1 1 var(--list-w);
  background: var(--c-dark);
  border-radius: var(--r-xl);
  display: flex;
  flex-direction: column;
  justify-content: center;     /* articles centrés verticalement dans le panneau */
  /* recouvrement piloté par --overlap : le panneau glisse sous la vedette… */
  margin-left: calc(-1 * var(--overlap));
  /* haut/bas = marge du panneau (--list-pad-y) ; gauche = recouvrement + décalage des articles. */
  padding: var(--list-pad-y) var(--sp-5) var(--list-pad-y) calc(var(--overlap) + var(--articles-x));
}
.nl-item { display: grid; grid-template-columns: var(--thumb-w) 1fr; gap: var(--sp-4); align-items: center; padding: calc(var(--articles-gap) / 2) 0; }
.nl-item:first-child { padding-top: 0; }   /* bloc d'articles centré : pas d'espace en trop en haut */
.nl-item:last-child  { padding-bottom: 0; }/* … ni en bas */
.nl-item + .nl-item { border-top: 1px solid rgba(255,255,255,.18); }
.nl-item__thumb { height: var(--article-h); border-radius: 12px; overflow: hidden; }
.nl-item__thumb img { width: 100%; height: 100%; object-fit: cover; }
.nl-item__tag { font-family: var(--font-title); text-transform: uppercase; font-size: .82rem; letter-spacing: .03em; color: var(--c-muted-on-dark); }
.nl-item__tag b { color: var(--c-red); }
.nl-item__title {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 1.3rem;
  color: var(--c-white);
  margin: 6px 0 10px;
  line-height: 1.1;
  /* Deux lignes maximum : la hauteur du panneau est calculée sur --article-h
     (la vignette). Les titres réels du club font parfois cinq lignes — sans
     cette limite, chaque article pousse le bloc et la section double de haut. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Rappel de lecture compact : la colonne de texte doit tenir dans la hauteur
   de la vignette (--article-h), sinon c'est elle qui dicte la hauteur du bloc. */
.nl-item .cta-read { padding: 4px 6px 4px 14px; font-size: .74rem; gap: var(--sp-2); }
.nl-item .arrow-dot { width: 28px; height: 28px; }
.nl-item .arrow-dot svg { width: 13px; height: 13px; }

/* ===========================
   20. Partenaires — bandeau de logos défilant
   =========================== */
.section-head--center { justify-content: center; text-align: center; }

.logos-marquee {
  position: relative;
  width: 100%;
  overflow: hidden;
  margin-top: var(--sp-6);
  /* fondu progressif sur les bords gauche/droite */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
}
.logos-marquee__track {
  display: flex;
  width: max-content;
  align-items: center;
  animation: logos-scroll 38s linear infinite;
}
.logos-marquee:hover .logos-marquee__track { animation-play-state: paused; }
.logos-marquee__item {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: clamp(28px, 4vw, 64px);
}
.logos-marquee__item img {
  /* Hauteur propre à chaque logo, posée par build.js : tous occupent la même
     surface optique, sinon un monogramme carré paraît minuscule à côté d'un
     bandeau très allongé. 48 px reste le repli si le format est inconnu. */
  height: var(--logo-h, 48px);
  width: auto;
  max-width: 180px;
  object-fit: contain;
  display: block;
}
@keyframes logos-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .logos-marquee__track { animation: none; }
}

/* Chaque logo mène chez son partenaire. Le bandeau s'arrête déjà au survol
   (règle ci-dessus) : sans cela la cible se déroberait sous le curseur. */
a.logos-marquee__item {
  transition: transform var(--t-fast), opacity var(--t-fast);
}
a.logos-marquee__item:hover { transform: translateY(-3px); }
/* Le bandeau est masqué en fondu sur ses bords : un contour de focus colle au
   logo, là où une ombre portée serait rognée par le masque. */
a.logos-marquee__item:focus-visible {
  outline: 2px solid var(--c-red);
  outline-offset: 6px;
  border-radius: var(--r-md);
}
@media (prefers-reduced-motion: reduce) {
  a.logos-marquee__item:hover { transform: none; opacity: .7; }
}

/* Rappel vers la page Partenaires, sous le bandeau. Le bandeau ne menait
   nulle part : sans ce lien, la seule porte vers la page Partenaires depuis
   l'accueil est le menu.

   Pas un troisième bouton-pilule : « Rejoindre le club », en rouge, est déjà
   une centaine de pixels plus haut, et deux pastilles qui se suivent se
   disputent l'œil. On reprend donc le vocabulaire de la page où il mène
   — même dessin que .partenaire__lien : titrage en capitales, pastille
   rouge, rien de plus. */
.logos-marquee__plus {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-5);
}
.lien-plus {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .72rem;
  letter-spacing: .08em;
  color: var(--c-white);
  transition: color var(--t-fast);
}
.lien-plus:hover { color: var(--c-red); }
.lien-plus .arrow-dot { width: 30px; height: 30px; transition: transform var(--t-fast); }
.lien-plus .arrow-dot svg { width: 13px; height: 13px; }
.lien-plus:hover .arrow-dot { transform: translateX(3px); }

/* ===========================
   21. Page Actualités — une éditoriale + grille
   ---------------------------------------------------
   Le bloc actus de l'accueil (section 20) reste la vitrine « 3 derniers
   articles ». Ici c'est l'index complet : filtres, une vedette, puis une
   grille au rythme éditorial (2 grandes cartes, puis 3 moyennes).
   Namespace `.actu-` pour ne pas marcher sur `.news-feature`/`.nl-item`.
   =========================== */

/* Barre de filtres : les chips à gauche, le compteur à droite */
.actu-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.actu-bar__count {
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .78rem;
  letter-spacing: .06em;
  color: var(--c-ink-soft);
}

/* --- Grille éditoriale ---------------------------------------------------
   Retour au langage du site : panneau clair, cartes arrondies, titre en
   noir SOUS l'affiche. Deux problèmes réglés par rapport à la mosaïque :

   1. Plus aucun titre posé sur l'image. Les couvertures du club sont des
      affiches qui portent déjà leur propre typographie.
   2. Les affiches vont du carré (1080×1080) au bandeau 2.4:1 (izom) en
      passant par le 16:9 (adjan). Aucun ratio de cadre ne convient à
      toutes : le fond du cadre reprend donc l'affiche elle-même, agrandie
      et floutée, et l'affiche nette se pose dessus en `contain`. Pas de
      rognage, et pas de bandes grises mortes.
   --------------------------------------------------------------------- */

.actu-grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6) var(--sp-4);
}

/* L'affiche, bord à bord --------------------------------------------------
   Toutes les cartes de la grille partagent un cadre 16:9 que l'affiche
   remplit entièrement, et qui porte l'arrondi des grandes cartes du site
   (--r-xl, 24px). Seule la plus récente échappe à ce cadre (cf. --nue).

   Historique de ce bloc, pour éviter de refaire le chemin : il y a eu une
   version avec fond flouté (pour masquer le vide autour des affiches d'un
   autre format), puis une version à cadre transparent, puis une sans cadre
   du tout — cette dernière laissait les hauteurs varier et désalignait les
   textes d'une rangée jusqu'à 604px. Le cadre rempli règle les deux.
   --------------------------------------------------------------------- */
.actu-media {
  /* Format unique pour toutes les cartes de la grille, calé sur la carte
     Adjan (nativement 16:9). Il remplit deux rôles : l'affiche occupe toute
     la largeur sans vide autour, et la hauteur étant commune, les textes
     d'une rangée démarrent au même niveau. */
  aspect-ratio: 16 / 9;
  border-radius: var(--r-xl);
  overflow: hidden;
}
/* `cover` fait remplir le cadre. Contrepartie assumée : une affiche d'un autre
   format est recadrée — une carrée perd 44 % de sa hauteur, 22 % en haut et
   22 % en bas. Le cadrage reste centré, là où se trouvent les logos ; ce sont
   les liserés de bord des affiches qui disparaissent. */
.actu-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  border-radius: var(--r-xl);
  transition: transform .5s cubic-bezier(.22, 1, .36, 1);
}

/* La plus récente : seule sur sa ligne, donc aucune hauteur à aligner. Elle
   garde son format d'origine, entière et bord à bord — pas de recadrage.
   `height: auto` et `object-fit: fill` neutralisent le `cover` ci-dessus. */
.actu-media--nue { aspect-ratio: auto; }
.actu-media--nue img { height: auto; object-fit: fill; }

/* La carte */
.actu-carte { display: flex; flex-direction: column; }
/* Léger zoom : le débordement masqué du cadre le rogne proprement. Une
   élévation aurait découvert un vide, l'affiche touchant les bords. */
.actu-carte:hover .actu-media img { transform: scale(1.02); }

.actu-carte__corps { display: flex; flex-direction: column; align-items: flex-start; }

.actu-carte__meta {
  margin-top: var(--sp-3);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .7rem;
  letter-spacing: .07em;
  color: var(--c-ink-soft);
}
.actu-carte__meta b { color: var(--c-red); font-weight: inherit; }

.actu-carte__titre {
  margin-top: 8px;
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: clamp(1rem, .92rem + .3vw, 1.22rem);
  line-height: 1.14;
  color: var(--c-ink);
  transition: color var(--t-fast);
}
.actu-carte:hover .actu-carte__titre { color: var(--c-red); }

.actu-carte__lire {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .74rem;
  letter-spacing: .05em;
  color: var(--c-ink);
}
.actu-carte__lire .arrow-dot { width: 26px; height: 26px; transition: transform var(--t-fast); }
.actu-carte__lire .arrow-dot svg { width: 12px; height: 12px; }
.actu-carte:hover .actu-carte__lire .arrow-dot { transform: translateX(3px); }

/* La une : pleine largeur, affiche à gauche, texte à droite */
.actu-carte--une {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 52px);
  align-items: center;
  padding-bottom: var(--sp-6);
  border-bottom: 1px solid var(--c-grey-line);
}
.actu-carte--une .actu-carte__meta { margin-top: 0; }
.actu-carte--une .actu-carte__titre {
  font-size: clamp(1.45rem, 1.1rem + 1.5vw, 2.4rem);
  line-height: 1.06;
}
.actu-carte__chapo {
  margin-top: var(--sp-3);
  max-width: 46ch;
  font-size: .97rem;
  line-height: 1.65;
  color: var(--c-ink-soft);
}

@media (prefers-reduced-motion: reduce) {
  .actu-media img { transition: none; }
  .actu-carte:hover .actu-media img { transform: none; }
}

/* --- Pagination -----------------------------------------------------------
   La page garde une longueur constante quel que soit le nombre d'articles
   publiés : c'est le seul mécanisme qui tient dans le temps (un « charger
   plus » finirait par rallonger la page indéfiniment).
   La page et le filtre courants sont dans l'URL, donc partageables et
   compatibles avec le bouton Retour.
   --------------------------------------------------------------------- */
.actu-pages {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-6);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-grey-line);
}
.actu-pages__btn {
  min-width: 44px;
  height: 44px;
  padding: 0 14px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--c-grey-line);
  border-radius: var(--r-pill);
  background: var(--c-white);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .82rem;
  letter-spacing: .04em;
  color: var(--c-ink);
  cursor: pointer;
  transition: border-color var(--t-fast), color var(--t-fast), background-color var(--t-fast);
}
.actu-pages__btn:hover:not(:disabled):not(.is-active) { border-color: var(--c-red); color: var(--c-red); }
.actu-pages__btn.is-active {
  background: var(--c-red);
  border-color: var(--c-red);
  color: var(--c-white);
  cursor: default;
}
.actu-pages__btn:disabled { opacity: .3; cursor: default; }
.actu-pages__btn svg { width: 16px; height: 16px; fill: currentColor; }
/* Les « … » entre deux plages de numéros */
.actu-pages__saut {
  min-width: 20px;
  text-align: center;
  font-family: var(--font-title);
  color: var(--c-ink-soft);
}

/* Aucun résultat pour le filtre courant */
.actu-empty {
  padding: var(--sp-7) 0;
  text-align: center;
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--c-ink-soft);
}

/* ===========================
   22. Page article (pages/actus/*.html)
   =========================== */

/* Ligne « catégorie · date · durée », dans l'en-tête sombre */
.article-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  font-family: var(--font-title);
  text-transform: uppercase;
  font-size: .76rem;
  letter-spacing: .06em;
  color: var(--c-muted-on-dark);
}
.article-meta__cat {
  padding: 4px 12px;
  border-radius: var(--r-pill);
  background: var(--c-red);
  color: var(--c-white);
}
.article-meta__sep { opacity: .45; }

/* Le titre d'article est long : il respire plus que .page-head__title */
.page-head__title--article {
  font-size: clamp(1.7rem, 1.1rem + 2vw, 3.1rem);
  line-height: 1.05;
  max-width: 30ch;
}

/* Bloc d'ouverture : l'affiche à gauche, le chapô calé à sa hauteur.
   Les visuels d'actu sont des affiches carrées (1080×1080) composées bord à
   bord — on ne peut pas les recadrer sans manger le bandeau du haut ou la
   ligne sponsors du bas. On ne touche donc pas à l'image : on la sort de la
   colonne de lecture et on lui donne le chapô pour voisin. L'entrée de
   l'article y perd la moitié de sa hauteur sans qu'un pixel soit rogné. */
.article-lead {
  display: grid;
  grid-template-columns: minmax(0, 40%) minmax(0, 1fr);
  gap: clamp(24px, 3vw, 48px);
  /* stretch, pas center : c'est le filet du chapo qui doit courir sur toute
     la hauteur de l'affiche. Le texte, lui, se recentre tout seul (flex). */
  align-items: stretch;
  max-width: 1300px;
  margin: 0 auto var(--sp-6);
}

.article-cover {
  /* Le stretch de .article-lead ne doit profiter qu'au filet du chapô : sans
     ça la figure s'étire aussi et laisse voir son fond gris sous une affiche
     plus basse que son voisin (cas d'IZOM, seule affiche en 1080×450). */
  align-self: center;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--c-grey-bg);
}
.article-cover img { width: 100%; height: auto; display: block; }

/* Chapô : ni aplat ni carte — un filet vertical, calé sur toute la hauteur de
   l'affiche, tient le bloc face au bord franc de l'image. C'est exactement le
   filet des intertitres (même rouge, mêmes 3px, même arrondi), redressé : le
   même signe revient quatre fois plus bas dans l'article.
   Le texte se pose à mi-hauteur, quelle que soit sa longueur — les chapôs vont
   de 20 à 60 mots selon les articles. */
.article-lead__lede {
  position: relative;
  display: flex;
  align-items: center;
  padding-left: clamp(24px, 2.4vw, 40px);
  font-size: clamp(1.12rem, 1rem + .55vw, 1.5rem);
  line-height: 1.45;
  color: var(--c-ink);
  text-wrap: balance;
}
.article-lead__lede::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  border-radius: 2px;
  background: var(--c-red);
}

/* Sous 900px la colonne de droite n'a plus de quoi respirer : l'affiche
   reprend toute la largeur et le chapô repasse dessous. */
@media (max-width: 900px) {
  .article-lead {
    grid-template-columns: 1fr;
    gap: var(--sp-4);
  }
}

/* Corps de texte : une seule colonne étroite, c'est du lecture longue */
.article-body { max-width: 68ch; margin-inline: auto; }
.article-body > p {
  font-size: 1rem;
  line-height: 1.75;
  color: var(--c-ink);
}
.article-body > p + p { margin-top: var(--sp-3); }
.article-body h2 {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: clamp(1.15rem, 1rem + .5vw, 1.5rem);
  line-height: 1.15;
  color: var(--c-ink);
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
}
/* Filet rouge court au-dessus des intertitres : repère de lecture */
.article-body h2::before {
  content: '';
  display: block;
  width: 40px;
  height: 3px;
  margin-bottom: var(--sp-3);
  border-radius: 2px;
  background: var(--c-red);
}
.article-body a { color: var(--c-red); text-decoration: underline; text-underline-offset: 3px; }
.article-body a:hover { color: var(--c-red-dark); }
/* Les listes du site d'origine sont écrites « • … » dans le texte :
   on les rend comme des paragraphes en retrait plutôt qu'en <ul>. */
.article-body > p.article-body__puce { padding-left: var(--sp-3); }

/* Pied d'article */
.article-foot {
  display: flex;
  justify-content: center;
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-grey-line);
}
/* Lien de retour : le bouton compact du site, dont la flèche avance au survol */
.article-foot .cta-read { color: var(--c-ink); background: rgba(0, 0, 0, .06); }
.article-foot .cta-read .arrow-dot { transition: transform var(--t-fast); }
.article-foot .cta-read:hover .arrow-dot { transform: translateX(3px); }

/* « À lire aussi » — réutilise les tuiles de l'index */
.article-related { margin-top: var(--sp-7); }
.article-related__title {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: clamp(1.2rem, 1rem + .6vw, 1.6rem);
  color: var(--c-ink);
  margin-bottom: var(--sp-4);
}
.article-related__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

/* ===========================
   23. Responsive
   =========================== */
@media (max-width: 1024px) {
  /* Trois colonnes rendraient les affiches trop petites pour être lues */
  .actu-grille { grid-template-columns: repeat(2, 1fr); }
  .article-related__grid { grid-template-columns: repeat(2, 1fr); }
  .news-feature { flex-direction: column; gap: var(--sp-4); }
  .feature, .news-list { flex-basis: auto; width: 100%; margin-left: 0; }
  .feature { min-height: 360px; }
  .news-list { padding: var(--sp-3) var(--sp-5); }
  /* Deux par deux : les liens en haut, la fiche et les réseaux dessous.
     C'est l'ordre de lecture, sans placement à la main. */
  .footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 820px) {
  /* La hauteur réelle du header, logo compris : 12 + (40 + 2×10) + 12.
     Elle sert à dégager le haut des pages intérieures et à poser le
     panneau de navigation — un chiffre trop petit les fait passer
     derrière le header. À revoir si le logo change de taille. */
  :root { --header-h: 84px; }

  /* Le monogramme perd 12 px : à 52 il débordait du header et venait
     couvrir le premier mot du fil d'Ariane. */
  .header__mark img { height: 40px; }
  /* --- Panneau de navigation ---------------------------------------------
     Reprend exactement le langage des panneaux desktop (.menu et .submenu) :
     fond sombre translucide rgba(12,12,12,.97), filet clair, ombre portée,
     coins arrondis, et le même dévoilement en clip-path.
     Avant, c'était un aplat noir pur, à angles vifs, collé bord à bord sous
     le header — le seul élément du site à ne suivre aucune de ces règles.
     ------------------------------------------------------------------- */
  .nav {
    position: fixed;
    top: calc(var(--header-h) + 4px);
    left: clamp(12px, 4vw, 28px);
    right: clamp(12px, 4vw, 28px);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--sp-2);
    border-radius: 28px;
    background: rgba(12, 12, 12, .97);
    border: 1px solid rgba(255, 255, 255, .08);
    box-shadow: 0 14px 30px rgba(0, 0, 0, .4);
    /* Sur un petit écran en paysage la liste peut dépasser : elle défile. */
    max-height: calc(100vh - var(--header-h) - 28px);
    overflow-y: auto;
    opacity: 0;
    clip-path: inset(0 0 100% 0 round 28px);
    pointer-events: none;
    will-change: clip-path, opacity;
    transition:
      clip-path .45s cubic-bezier(.22, 1, .36, 1),
      opacity .2s ease;
  }
  .nav.is-open {
    opacity: 1;
    clip-path: inset(0 0 0 0 round 28px);
    pointer-events: auto;
  }
  /* Le contenu suit l'ouverture avec un léger retard, comme .menu */
  .nav > * { opacity: 0; transition: opacity .2s ease; }
  .nav.is-open > * { opacity: 1; transition-delay: .1s; }

  .nav__link {
    width: 100%;
    padding: 15px var(--sp-3);
    border-bottom: 0;
    border-radius: var(--r-md);
    font-size: 1rem;
  }
  /* Les entrées à sous-menu sont des <button> : on pousse le chevron à droite */
  .nav__link--sub { display: flex; justify-content: space-between; text-align: left; }
  .nav__link + .nav__link { border-top: 1px solid rgba(255, 255, 255, .09); }
  .nav__link:hover, .nav__link:focus-visible { background: rgba(255, 255, 255, .07); }
  .nav__link.is-current { background: rgba(255, 255, 255, .1); border-color: transparent; }

  /* Entrées reprises du menu trois traits, séparées par un filet plus marqué */
  .nav__extra {
    display: flex;
    flex-direction: column;
    margin-top: var(--sp-2);
    padding-top: var(--sp-2);
    border-top: 1px solid rgba(255, 255, 255, .18);
  }
  .nav__extra .nav__link:first-child { border-top: 0; }

  /* --- Sous-menus (Collectifs, Soutien & Stage) --------------------------
     Leur grille desktop est figée à 4 colonnes de 140px, soit 572px
     incompressibles : impossible sur un téléphone, la liste des équipes
     débordait de l'écran. Ici deux colonnes fluides, et le panneau se cale
     à la place du panneau de navigation qu'il recouvre — on lit donc soit
     les catégories, soit le détail de l'une d'elles, jamais les deux
     empilés. js/main.js n'applique son `top` en ligne que sur desktop.
     ------------------------------------------------------------------- */
  .submenu {
    top: calc(var(--header-h) + 4px);
    left: clamp(12px, 4vw, 28px);
    right: clamp(12px, 4vw, 28px);
    z-index: 3;                       /* au-dessus de .nav */
    flex-direction: column;
    gap: var(--sp-3);
    padding: var(--sp-3);
    max-height: calc(100vh - var(--header-h) - 28px);
    overflow-y: auto;
    transform: none;
    clip-path: inset(0 0 100% 0 round 28px);
  }
  .submenu.is-open { clip-path: inset(0 0 0 0 round 28px); }
  .submenu__teams { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .submenu__link { white-space: normal; }
  /* Le filet vertical n'a plus de sens en pile */
  .submenu__aside {
    padding-left: 0;
    padding-top: var(--sp-3);
    border-left: 0;
    border-top: 1px solid rgba(255, 255, 255, .12);
    justify-content: space-between;
  }

  .header__burger { display: flex; }
  /* Sur mobile, c'est le burger de droite qui ouvre la navigation */
  .header__lines, .menu { display: none; }
  /* Le repli en petite pill (max-width 112px) est réservé au desktop : ici la
     barre garde 92% de la largeur, et à .94 d'opacité elle formait une dalle
     noire en travers de l'écran. On l'allège et on resserre l'ombre, qui
     s'étalait sur 34px.
     Pas de backdrop-filter ici : il créerait un bloc conteneur pour le
     panneau de navigation (position: fixed) qui est un descendant. */
  .header.is-scrolled .header__inner {
    background: rgba(12, 12, 12, .74);
    box-shadow: 0 6px 16px rgba(0, 0, 0, .16);
  }
  /* Le rognage sert à l'animation de repli en pill, qui n'a pas lieu sous
     821px. Il empêchait le panneau de navigation de sortir de la barre :
     le burger ouvrait un menu invisible et non cliquable. */
  .header__inner { overflow: visible; contain: none; }
  /* En pile, chacun son tour : les liens, la fiche, puis les réseaux. */
  .footer__grid { grid-template-columns: 1fr; gap: var(--sp-5); }
  /* Le pied devient haut et étroit : un blason calé sur sa hauteur ferait
     2 000 px de côté, dont on ne verrait qu'un morceau de dégradé. Sur
     mobile c'est la largeur qui le dimensionne. */
  .footer::after { height: auto; width: 230%; }
  .section-head { flex-direction: column; align-items: flex-start; }
  /* Le bandeau passe en pile : icône, puis le texte, puis l'action.
     Sans le `order`, le bouton se retrouvait à côté de l'icône, donc avant
     le contenu auquel il se rapporte. */
  .promo-bar { flex-wrap: wrap; }
  .promo-bar__text { flex-basis: 100%; }
  .promo-bar .cta-read { order: 1; }
  .cal__head { flex-direction: column; align-items: flex-start; }
  /* Une seule colonne : le classement n'a plus de voisin dont épouser la
     hauteur, il se déroule au lieu de défiler dans une fenêtre. */
  .cal__grille { grid-template-columns: 1fr; }
  .cal__bloc--rang .cal__widget.is-active { max-height: none; overflow: hidden; }
  /* Les 4 chips à largeur fixe dépassaient du panneau : la dernière équipe
     était rognée, donc impossible à sélectionner. Elles passent à la ligne. */
  .chips { flex-wrap: wrap; }
  .article-related__grid { grid-template-columns: 1fr; }
  /* Une seule colonne : la une perd sa mise en deux colonnes */
  .actu-grille { grid-template-columns: 1fr; gap: var(--sp-5); }
  .actu-carte--une { grid-template-columns: 1fr; gap: var(--sp-4); }
  .actu-carte--une .actu-carte__titre { font-size: 1.5rem; }
  .nl-item { grid-template-columns: 110px 1fr; }
  /* la frise passe en pile : l'année au-dessus du texte */
  .timeline__item { grid-template-columns: 1fr; gap: var(--sp-2); }
  /* les étapes s'empilent : le trait de liaison n'a plus de sens */
  .stepper { grid-template-columns: 1fr; gap: var(--sp-5); }
  .stepper__item + .stepper__item::before { display: none; }
}
@media (max-width: 480px) {
  .band { padding: var(--sp-7) 0; }
  .actu-bar { justify-content: flex-start; }
}
