/* ============================================================
   Page d'accueil
   ============================================================ */

/* ----------------------------------------------------------
   Hero

   Le texte est calé en bas, pas centré : le regard descend le long
   du visuel et atterrit sur l'accroche, juste avant le pli.
   ---------------------------------------------------------- */

.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: min(88vh, 720px);
  margin-top: var(--header-h);
  overflow: hidden;
  background: var(--bg-ph);
}

.hero__video,
.hero__poster {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Le recadrage se fait en hauteur sur un écran large : on privilégie
     le haut de l'image, où sont les visages, plutôt que son centre. */
  object-position: center 38%;
  /* Désaturation et assombrissement : le texte blanc doit rester
     lisible quelle que soit la scène filmée. */
  filter: var(--media-filter);
}

/* En portrait, une image paysage recadrée en « cover » se réduit à un
   gros plan : plus le cadre est haut, plus il rogne en largeur. On abaisse
   donc le hero pour élargir le champ, et on vise les deux visages. */
@media (max-width: 700px) {
  .hero { min-height: min(72vh, 600px); }
  .hero__video,
  .hero__poster { object-position: 52% 24%; }
}

.hero__poster {
  z-index: 1;
  opacity: 1;
  transition: opacity 0.6s var(--ease);
}
/* Posé par le JavaScript dès que la vidéo affiche ses premières images.
   Sans vidéo, l'affiche reste simplement visible. */
.hero__bg[data-playing='true'] .hero__poster { opacity: 0; }

/* ----------------------------------------------------------
   Animation du hero

   Le mouvement vient d'un zoom lent sur une image fixe, pas d'une
   vidéo : 24 Ko sur mobile contre 534 Ko, aucun décodage, et une
   animation de `transform` que le navigateur compose sur le GPU —
   donc sans recalcul de mise en page à chaque image.

   Le débordement est absorbé par `overflow: hidden` sur .hero.
   ---------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .hero__bg:not([data-playing='true']) .hero__poster {
    transform-origin: 62% 38%;
    animation: hero-zoom 28s ease-in-out infinite alternate;
  }

  /*
   * Impact : une secousse brève et un éclair rouge, toutes les six
   * secondes. Le mouvement dure moins d'une demi-seconde sur un cycle
   * de six — c'est cette rareté qui le rend lisible plutôt que
   * fatigant.
   *
   * La secousse porte sur le conteneur et non sur l'image : sur
   * l'image elle écraserait le zoom, `transform` n'acceptant qu'une
   * seule animation à la fois. Les deux propriétés animées ici,
   * `transform` et `opacity`, sont composées par le GPU : aucun
   * recalcul de mise en page.
   */
  .hero__bg:not([data-playing='true']) {
    animation: hero-impact 6s ease-out infinite;
  }

  .hero__bg:not([data-playing='true']) .hero__fx {
    animation: hero-flash 6s ease-out infinite;
  }
}

@keyframes hero-zoom {
  from { transform: scale(1); }
  to   { transform: scale(1.14); }
}

@keyframes hero-impact {
  0%   { transform: scale(1); }
  1.2% { transform: scale(1.035); }
  4%   { transform: scale(1.008); }
  9%   { transform: scale(1); }
  100% { transform: scale(1); }
}

@keyframes hero-flash {
  0%   { opacity: 0; }
  1.2% { opacity: 1; }
  3%   { opacity: 0.28; }
  9%   { opacity: 0; }
  100% { opacity: 0; }
}

/*
 * La couche d'impact reste dans .hero__bg, dont le `z-index: 0` crée
 * un contexte d'empilement : l'éclair passe donc au-dessus de l'image
 * mais sous le voile, qui continue d'ancrer le texte.
 *
 * `opacity: 0` par défaut : sans animation — mouvement réduit demandé,
 * ou vidéo en lecture — la couche reste strictement invisible.
 */
.hero__fx {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(
    120% 80% at 62% 38%,
    rgba(232, 20, 44, 0.55),
    rgba(232, 20, 44, 0.12) 55%,
    transparent 78%
  );
}

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

/* Voile dégradé : opaque en bas pour ancrer le texte, transparent en
   haut pour laisser voir l'image. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(
    0deg,
    var(--bg) 4%,
    rgba(var(--bg-rgb), 0.15) 60%,
    rgba(var(--bg-rgb), 0.5) 100%
  );
}

.hero__content {
  position: relative;
  z-index: 3;
  padding-block: clamp(48px, 8vw, 88px);
}

.hero__inner { max-width: 780px; }

.hero__title { margin-block: 20px 22px; }

.hero__lede {
  max-width: 56ch;
  margin-bottom: 34px;
  font-weight: 300;
  font-size: clamp(15px, 1.8vw, 17px);
  line-height: 1.7;
  color: var(--text-80);
}

.hero__ctas { display: flex; flex-wrap: wrap; gap: var(--gap-sm); }

/* ----------------------------------------------------------
   Activités

   Grille à gouttière d'un pixel : le fond de la grille transparaît
   entre les cellules et dessine les filets. Aucune bordure à gérer
   cellule par cellule, donc aucun doublon aux jonctions.
   ---------------------------------------------------------- */

/*
 * Paliers explicites plutot qu'`auto-fit`.
 *
 * Avec `repeat(auto-fit, minmax(240px, 1fr))`, une largeur intermediaire
 * donnait TROIS colonnes — donc, depuis l'ajout du Pilates, une quatrieme
 * tuile seule sur sa ligne. Les paliers 1 / 2 / 4 divisent toujours
 * exactement quatre elements.
 */
.activities {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}

@media (min-width: 560px) {
  .activities { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1080px) {
  .activities { grid-template-columns: repeat(4, 1fr); }
}

.activity {
  display: flex;
  flex-direction: column;
  padding: clamp(28px, 3.4vw, 40px) clamp(22px, 2.6vw, 34px);
  background: var(--bg);
}

.activity__media {
  position: relative;
  aspect-ratio: 4 / 5;
  margin-bottom: 26px;
  overflow: hidden;
  background: var(--bg-ph);
}

/* Vidéo et image d'attente se superposent exactement : le passage de
   l'une à l'autre ne déplace aucun pixel. */
.activity__video,
.activity__poster,
.activity__media picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.activity__video,
.activity__poster {
  object-fit: cover;
  filter: var(--media-filter-soft);
  transition: transform 0.6s var(--ease), opacity 0.5s var(--ease);
}
.activity__poster { z-index: 1; }

/* Posé par le JavaScript quand la vidéo affiche ses premières images. */
.activity__media[data-playing='true'] .activity__poster { opacity: 0; }

.activity:hover .activity__video,
.activity:hover .activity__poster { transform: scale(1.03); }

.activity__num {
  margin-bottom: 14px;
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.1em;
  color: var(--red);
}

.activity__title { margin-bottom: 12px; }

.activity__text {
  font-weight: 300;
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-60);
}

/* ----------------------------------------------------------
   Association
   ---------------------------------------------------------- */

.about__title { margin-block: 18px 20px; }

/* ----------------------------------------------------------
   Événements
   ---------------------------------------------------------- */

.events { border-top: 1px solid var(--line); }

.event {
  display: grid;
  grid-template-columns: 150px 1fr auto;
  align-items: center;
  gap: 28px;
  padding-block: 26px;
  border-bottom: 1px solid var(--line);
}

.event__date {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1;
  text-transform: uppercase;
  color: var(--red);
}
.event__place {
  display: block;
  margin-top: 6px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--text-50);
}

.event__title {
  margin-bottom: 6px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: 0;
  text-transform: none;
}
.event__desc {
  font-weight: 300;
  font-size: 14px;
  color: var(--text-60);
}

/* ----------------------------------------------------------
   Tarifs

   Le cadre extérieur porte la bordure ; chaque cellule n'ajoute que
   son filet droit et bas. Les filets en trop sont retirés au bord.
   ---------------------------------------------------------- */

.pricing {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border: 1px solid var(--line-strong);
}

.plan {
  display: flex;
  flex-direction: column;
  position: relative;
  padding: clamp(30px, 3.6vw, 40px) clamp(24px, 2.8vw, 34px);
  border-right: 1px solid var(--line-strong);
}
.plan:last-child { border-right: none; }

.plan--featured {
  background: rgba(var(--red-rgb), 0.07);
  box-shadow: inset 0 0 0 1px var(--red);
}

.plan__badge {
  position: absolute;
  top: -11px;
  left: clamp(24px, 2.8vw, 34px);
  padding: 5px 12px;
  background: var(--red);
  color: var(--text);
  font-weight: 700;
  font-size: 10px;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.plan__label {
  margin-bottom: 16px;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-80);
}

.plan__note {
  margin-top: -14px;
  margin-bottom: 22px;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--text-50);
}

.plan__price {
  margin-bottom: 22px;
  font-family: var(--font-display);
  font-size: 34px;
  line-height: 1;
  text-transform: uppercase;
}

.plan__features {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: var(--gap-sm);
  margin-bottom: 28px;
}
.plan__features li {
  position: relative;
  padding-left: 22px;
  font-weight: 300;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-70);
}
.plan__features li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--red);
}

.pricing-note {
  margin-top: 20px;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--text-50);
}

/* ----------------------------------------------------------
   Espace membres
   ---------------------------------------------------------- */

.members {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-xl);
  flex-wrap: wrap;
  padding: clamp(32px, 4vw, 48px);
  border: 1px solid var(--line-strong);
}
.members__title { margin-block: 16px 12px; }
.members__text  { max-width: 52ch; font-weight: 300; font-size: 14px; line-height: 1.7; color: var(--text-60); }

/* ----------------------------------------------------------
   Adaptation mobile
   ---------------------------------------------------------- */

@media (max-width: 760px) {
  .hero__inner { max-width: 100%; }

  .event {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  /* En colonne unique, c'est le filet du bas qui sépare les formules. */
  .plan {
    border-right: none;
    border-bottom: 1px solid var(--line-strong);
  }
  .plan:last-child { border-bottom: none; }

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

@media (max-width: 600px) {
  .hero__ctas .btn { width: 100%; }
}

/* ----------------------------------------------------------
   Bandeau des partenaires

   Les logos fournis sont majoritairement noirs sur fond blanc : poses
   tels quels sur le fond sombre du site, ils disparaitraient. Chacun est
   donc depose sur une vignette claire, ce qui preserve aussi l'integrite
   des chartes institutionnelles — on ne teinte pas un logo d'Etat.

   Repos : desature et attenue. Survol, ou passage au centre sur mobile :
   couleur pleine.
   ---------------------------------------------------------- */

.partenaires { padding-block: clamp(32px, 4vw, 52px); }

.partenaires__title {
  margin-bottom: 22px;
  color: var(--text-50);
}

/*
 * Le masque en degrade fait entrer et sortir les logos en fondu plutot
 * que de les couper net au bord de l'ecran.
 */
/*
 * La zone porte les fleches en position absolue. Elles sont posees a
 * l'exterieur de la piste : a l'interieur, le degrade de masquage les
 * effacerait en meme temps que les logos.
 */
.partenaires__zone { position: relative; }

.partenaires__fleche {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  transform: translateY(-50%);
  border: 1px solid var(--line);
  border-radius: 50%;
  /* Fond opaque : la fleche doit se detacher des logos qui defilent
     dessous. */
  background: var(--bg);
  color: var(--text-70);
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.partenaires__fleche--avant { left: 10px; }
.partenaires__fleche--apres { right: 10px; }

.partenaires__fleche:hover,
.partenaires__fleche:focus-visible {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

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

/* Ecrans etroits : le bandeau se manipule au doigt, les fleches
   n'apporteraient rien et mangeraient la largeur utile. */
@media (max-width: 640px) {
  .partenaires__fleche { display: none; }
}

.partenaires__piste {
  /*
   * `auto` en horizontal, `hidden` en vertical : la piste devient
   * defilable au doigt et a la molette, sans jamais laisser apparaitre
   * de barre verticale parasite.
   */
  overflow-x: auto;
  overflow-y: hidden;

  /* Le geste ne doit pas se propager a la page ni declencher le retour
     arriere du navigateur en bout de course. */
  overscroll-behavior-x: contain;

  /* Barre masquee : le bandeau defile deja seul, une barre ne ferait
     qu'alourdir. Le defilement reste possible partout. */
  scrollbar-width: none;
  -ms-overflow-style: none;

  cursor: grab;

  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

/*
 * Fondu des bords reduit de moitie sur mobile.
 *
 * ⚠️ Cette regle doit venir APRES `.partenaires__piste`, pas avant :
 * a specificite egale, c'est la derniere declaree qui l'emporte, et
 * placee plus haut elle etait purement et simplement ecrasee.
 *
 * A 8 %, le degrade couvre 30 px de chaque cote — pres de la moitie
 * d'une vignette de 132 px, et le premier logo devenait illisible.
 */
@media (max-width: 640px) {
  .partenaires__piste {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  }
}

.partenaires__piste::-webkit-scrollbar { display: none; }

.partenaires__piste.est-saisie { cursor: grabbing; }

/* Pendant et juste apres une manipulation, le defilement automatique se
   met en pause : sinon les logos fuiraient sous le doigt. */
.partenaires__piste.est-manuelle .partenaires__defile { animation-play-state: paused; }

.partenaires__defile {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 26px);
  width: max-content;
  animation: partenaires-defile 46s linear infinite;
}

/* La piste contient deux copies : la translation de la moitie exacte
   ramene la seconde a la place de la premiere, sans discontinuite. */
@keyframes partenaires-defile {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* Laisser le temps de lire un logo que l'on vise. */
.partenaires__piste:hover .partenaires__defile,
.partenaires__piste:focus-within .partenaires__defile { animation-play-state: paused; }

/*
 * Bloc simple, PAS une grille ni un flex.
 *
 * En grille, `height: 100%` sur l'image ne se resolvait pas — la piste
 * etant dimensionnee par son contenu, la hauteur de reference restait
 * indefinie et le pourcentage retombait sur `auto`. Les logos hauts
 * debordaient alors de leur carte, et la partie qui depassait, noire sur
 * fond noir, disparaissait.
 *
 * Un bloc a hauteur explicite en `border-box` a, lui, une hauteur de
 * contenu parfaitement definie : 76 - 28 = 48 px. Le pourcentage de
 * l'image s'y resout sans ambiguite.
 */
.partenaire {
  display: block;
  flex: 0 0 auto;
  width: clamp(132px, 15vw, 176px);
  height: clamp(76px, 8.5vw, 96px);
  padding: 14px 18px;
  border-radius: 10px;
  /* Fond clair : la moitie des logos sont noirs et disparaitraient sur
     le fond sombre du site. */
  background: #fff;
  overflow: hidden;
  transition: background 0.35s ease, transform 0.35s ease;
}

/*
 * ⚠️ `max-width/max-height: 100%` avec `width/height: auto` NE CONTRAINT
 * PAS ici : l'image est centree dans une grille, son bloc conteneur n'a
 * donc pas de hauteur definie a resoudre, et le pourcentage est ignore.
 * Les logos hauts — MMA en 600x640, le Val-d'Oise en 640x700 — se
 * rendaient en 96x105 dans une zone utile de 96x48 : ils debordaient de
 * la carte blanche, et la partie qui depassait, noire sur fond noir,
 * disparaissait purement et simplement.
 *
 * Dimensions pleines + `object-fit: contain` : l'image occupe la zone,
 * et c'est le cadrage qui l'y inscrit, quel que soit son rapport.
 */
.partenaire img {
  display: block;
  width: 100%;
  height: 100%;
  /* Neutralise le `max-width: 100%` global : il n'a plus d'objet ici,
     et laisserait croire a une contrainte qui n'agit pas. */
  max-width: none;
  object-fit: contain;
  /*
   * Gris au repos, couleur au survol — a PLEINE opacite dans les deux
   * cas. C'est la baisse d'opacite qui delavait les logos et les faisait
   * paraitre absents ; la desaturation seule les laisse entiers.
   */
  filter: grayscale(1);
  transition: filter 0.35s ease;
}

.partenaire:hover,
.partenaire:focus-visible,
.partenaire.est-au-centre {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

.partenaire:hover img,
.partenaire:focus-visible img,
.partenaire.est-au-centre img { filter: grayscale(0); }

a.partenaire:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }

/*
 * Mouvement reduit : plus de defilement automatique. Le bandeau devient
 * une bande que l'on fait glisser au doigt, et tous les logos passent en
 * couleur — sans animation, la desaturation n'a plus de contrepartie.
 */
@media (prefers-reduced-motion: reduce) {
  .partenaires__piste {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .partenaires__defile { animation: none; }
  .partenaire { scroll-snap-align: center; }
  .partenaire img { filter: none; }
  /* La copie decorative n'a plus d'utilite si rien ne defile. */
  .partenaires__defile > [aria-hidden='true'] { display: none; }
}
