/* =========================================================
   Padel Teambuilding (padel-teambuilding.be)
   Wel Padel (Welkenraedt) & Le Midi - Padel Club (Verviers)
   Site one-page - Thème CLAIR, épuré et premium.
   Charte Wel Padel : OR/DORÉ (#C09020) sur fond blanc/crème, lignes nettes.
   Touches bordeaux (#7A0011) réservées à l'identité du Midi (logo, pastilles).
   Animations reprises du site Le Midi + du site Black Pepper.
   ========================================================= */

/* ---------- Polices auto-hébergées ----------
   DEUX familles, chacune avec son métier. C'est le partage éditorial du design
   Anthropic (claude.com), repris ici tel quel : une serif de labeur pour tout ce
   qui se proclame, une sans humaniste pour tout ce qui se lit.

   - TITRES : Cormorant Garamond, en variable (300 à 700). C'est le substitut
     libre documenté de Copernicus / Tiempos Headline, les serifs propriétaires
     d'Anthropic. On la pose à la graisse 500 avec un interlettrage négatif :
     jamais en gras. Une serif de titre passée à 700 devient tonitruante, et le
     dessin perd exactement ce qu'on est venu y chercher.
   - TEXTE, NAVIGATION, BOUTONS, ÉTIQUETTES : Inter, en variable (100 à 900).
     C'est le substitut libre de StyreneB. Humaniste, dessinée pour l'écran, elle
     tient les petits corps et les capitales espacées sans se déformer.

   Ce que l'ancienne version reprochait au duo serif + sans (« deux alphabets dans
   le même bloc ») venait d'un mauvais partage, pas du principe : le serif y
   descendait jusque dans le texte courant. Ici la frontière est nette. Serif au
   dessus de 1,2 rem et sur les seuls titres, chiffres et prix ; sans partout
   ailleurs. Un bloc de texte ne mélange jamais les deux.

   Les deux fichiers sont servis depuis notre serveur : rien ne part chez Google
   au chargement (RGPD), et la CSP stricte l'exige. Voir assets/fonts/LICENSE.md. */
@font-face {
  font-family: "Cormorant Garamond";
  src: url("../fonts/cormorantgaramond-latin-var.woff2") format("woff2-variations");
  src: url("../fonts/cormorantgaramond-latin-var.woff2") format("woff2");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-latin-var.woff2") format("woff2-variations");
  src: url("../fonts/inter-latin-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- Variables ---------- */
:root {
  /* Base NOIR & BLANC : tons neutres, le doré du logo Wel n'intervient qu'en touches. */
  --paper: #FFFFFF;          /* fond principal blanc pur */
  --paper-2: #F3F3F1;        /* section alternée (gris neutre très clair) */
  --paper-3: #FFFFFF;        /* cartes */
  --paper-4: #F8F8F6;        /* carte hover */
  --ink: #0E0E0E;            /* noir (texte titres) */
  --ink-2: #141414;          /* fonds sombres (bandes) */
  --ink-3: #0A0A0A;          /* fond sombre profond (footer, scrims) */
  --body: #3C3C3C;           /* texte courant sur fond clair */
  --muted: #6F6F6F;          /* texte secondaire sur fond clair - 5,03:1 sur blanc */
  /* SUR FOND SOMBRE UNIQUEMENT. Mesuré à 2,27:1 sur blanc, il n'y passe donc
     aucun texte : sur les bandes noires, il monte à 9,4:1 et fait très bien son
     travail. Trois usages traînaient sur fond clair (mention RGPD, lieux de la
     mosaïque, textes indicatifs des champs), tous repassés en --muted. */
  --muted-2: #ACACAC;        /* texte tertiaire, RÉSERVÉ aux fonds sombres */

  --gold: #C09020;           /* doré EXACT du logo Wel Padel (accent unique) */
  --gold-bright: #D8AE3E;    /* doré éclairci (accents, halos) */
  --gold-soft: #E7CE86;      /* doré pâle (accents sur fond sombre) */
  /* Le doré du texte sur fond clair. #9A7016 tombait à 4,46:1 sur blanc et 4,02:1
     sur le gris des sections alternées, sous le seuil de 4,5:1 - pour treize
     sur-titres, tous les libellés du formulaire et « Afficher la carte ».
     #8A6413 monte à 5,37:1 sans changement de teinte perceptible. */
  --gold-deep: #8A6413;      /* doré foncé (texte doré sur fond clair) */
  --grad-gold: linear-gradient(135deg, #D8AE3E 0%, #C09020 48%, #9A7016 100%);

  --cream: #F7F7F5;          /* presque-blanc neutre (texte sur fond sombre) */

  /* Teintes qui traînaient en dur dans la feuille, désormais nommées. Une couleur
     n'existe vraiment dans un système que si elle porte un nom : sinon on la
     recopie, on l'approxime d'un point, et la charte se disperse sans qu'on le
     voie. --ink-soft, elle, était APPELÉE sans avoir jamais été déclarée : le
     croquis des bulles tombait silencieusement sur sa valeur de repli. */
  --ink-soft: #3A3A38;       /* gris chaud des aplats de croquis */
  --ink-hover: #262626;      /* noir éclairci, survol des boutons pleins */
  --ink-menu: #1D1A12;       /* départ du dégradé du menu mobile */
  --midi: #7A0011;           /* bordeaux EXACT du logo Le Midi - Padel Club */
  --midi-clair: #C4394F;     /* bordeaux éclairci, lisible sur photo sombre */
  --photo-fond: #E9E3D6;     /* fond d'attente d'une image qui charge */
  --erreur: #B3261E;         /* champ fautif, message d'échec */
  --erreur-fond: #FFF7F6;
  --succes: #1F6B3B;         /* demande bien partie */
  --succes-fond: #F0F8F2;
  --facebook: #1877F2;       /* couleur de marque tierce, la seule de la page */
  --line: rgba(14, 14, 14, .14);    /* filet neutre (cartes, séparateurs) */
  --line-soft: rgba(14, 14, 14, .08);
  --line-on-dark: rgba(255, 255, 255, .15);

  --shadow: 0 26px 64px rgba(60, 44, 8, .16);
  --shadow-sm: 0 12px 32px rgba(60, 44, 8, .12);
  --shadow-gold: 0 14px 34px rgba(192, 144, 32, .34);

  --radius: 14px;
  --radius-lg: 22px;
  --container: 1200px;
  --header-h: 88px;
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  /* Les deux piles, et la frontière entre elles.
     `--font-display` ne sert QUE aux titres, aux chiffres et aux prix.
     `--font-body` sert à tout le reste, texte courant compris. */
  --font-display: "Cormorant Garamond", "Tiempos Headline", Garamond, "Times New Roman", serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--header-h) - 10px); -webkit-text-size-adjust: 100%; overflow-x: hidden; }
body {
  font-family: var(--font-body);
  color: var(--body);
  background: var(--paper);
  line-height: 1.6;
  font-size: 17px;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  /* Inter a un axe optique (opsz). Laissé libre, il redessine les lettres quand
     le corps change : deux paragraphes voisins de tailles différentes semblent
     alors composés dans deux polices. On le fige une fois pour toutes, ici, pour
     toute la page : un seul dessin de sans, quelle que soit la taille. */
  font-optical-sizing: none;
}
img { max-width: 100%; display: block; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
section { position: relative; }
::selection { background: var(--gold); color: #fff; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; border-radius: 4px; }
.btn:focus-visible { outline-offset: 4px; border-radius: 10px; }
.carousel__arrow:focus-visible { outline-offset: 4px; border-radius: 50px; }

/* ---------- Layout helpers ---------- */
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 26px; }
.section { padding: clamp(72px, 9vw, 132px) 0; }
.nowrap { white-space: nowrap; }
/* Lien d'évitement. Il ne se voit qu'au clavier, et c'est tout l'intérêt :
   celui qui tabule n'a plus à traverser les quatre entrées de menu, les deux
   pastilles et le bouton de devis avant d'atteindre la page. */
.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: 400;
  transform: translateY(-200%);
  background: var(--ink); color: var(--cream);
  padding: 13px 20px; border-radius: 10px;
  font-family: var(--font-body); font-weight: 500; font-size: .875rem;
  box-shadow: var(--shadow-sm);
  transition: transform .2s ease;
}
.skip-link:focus { transform: none; }
/* Le contenu principal reçoit le focus au clic sur le lien d'évitement ; il ne
   porte pas de contour, il n'est pas une commande. */
#contenu:focus { outline: none; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.split__cta { margin-top: 28px; display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }

/* ---------- Typographie ---------- */
/* LES TITRES SONT EN SERIF, ET JAMAIS EN GRAS.
   Graisse 500 (le réglage documenté pour Cormorant Garamond quand elle remplace
   Copernicus), interlettrage négatif de -.02em. Ces deux valeurs vont ensemble :
   sans le resserrage, une serif de titre s'étale et sonne « document Word » ;
   avec une graisse plus lourde, elle crie. La hiérarchie vient du corps et du
   changement d'alphabet, pas de l'épaisseur du trait. */
h1, h2, h3 {
  font-family: var(--font-display); font-weight: 500; line-height: 1.12;
  color: var(--ink); letter-spacing: -.02em; text-wrap: balance; hyphens: none;
}
/* Cormorant Garamond a une hauteur d'œil basse : à corps égal, ses minuscules
   sont nettement plus petites que celles d'une sans. Tous les corps de titre du
   fichier ont donc été relevés d'environ 12 % pour retrouver la présence
   qu'avaient les anciens titres. Ce n'est pas un choix de mise en page, c'est la
   compensation d'un changement de dessin. */

/* Chiffres alignés partout. Une Garamond compose volontiers en chiffres
   elzéviriens (le 3, le 4, le 7 descendent sous la ligne) : sur les compteurs du
   tableau d'affichage, dont chaque chiffre vit dans une fenêtre d'exactement 1 em,
   les jambages seraient tout simplement rognés. */
h1, h2, h3, .stat__num, .ardoise__montant, .ardoise__devise, .step__num, .odo {
  font-variant-numeric: lining-nums tabular-nums;
}

/* Texte courant : équilibrage des fins de ligne (anti-orphelins) + pas de césure */
p { text-wrap: pretty; hyphens: none; }

/* Les commandes de formulaire n'héritent pas de la police du document : le
   navigateur leur impose Arial 13,33 px. La plupart de nos boutons portent leur
   texte dans un enfant stylé, donc le défaut ne se voyait que sur la croix de
   fermeture de la visionneuse. On le règle une fois pour toutes, plutôt que de
   le rattraper au cas par cas à la prochaine commande ajoutée. */
button, input, select, textarea { font: inherit; color: inherit; }

/* ---- UNE PHRASE NE DÉMARRE JAMAIS EN FIN DE LIGNE ----
   Chaque phrase des paragraphes et des titres est enveloppée dans un
   <span class="phrase"> par la passe de dactylographie. Rendue en boîte en
   ligne, la phrase qui ne tient pas dans ce qui reste de la ligne bascule
   ENTIÈRE à la suivante, au lieu d'y abandonner ses trois premiers mots.
   Une phrase plus longue qu'une ligne, elle, démarre en début de ligne et se
   répartit normalement : rien n'est figé.

   Pourquoi pas l'espace insécable, qui est le réflexe habituel : une insécable
   ne vaut que pour la largeur qu'on avait sous les yeux en la posant. Elle
   règle le défaut en 1440 px et le recrée en 900. La boîte en ligne, elle,
   tient à toutes les largeurs, sans qu'on ait à re-mesurer à chaque texte.
   Les insécables restent, mais pour ce qu'elles font vraiment bien : empêcher
   un petit mot de finir une ligne, et un montant de quitter son symbole. */
.phrase { display: inline-block; }
.kicker {
  display: inline-block;
  font-family: var(--font-body);
  /* Étiquette en capitales : graisse 500 et interlettrage modéré. Le .34em
     d'avant compensait une sans plus étroite ; Inter n'en a pas besoin, et le
     design de référence pose ses capitales à environ .13em. */
  font-weight: 500;
  font-size: .75rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin-bottom: 18px;
  /* Sur mobile, un sur-titre long se coupe et laisse un mot seul en bas
     (« ... PROVINCE DE / LIÈGE »). On équilibre les deux lignes, comme pour
     les titres : plus de mot orphelin, quelle que soit la largeur. */
  text-wrap: balance;
}
.section-title { font-size: clamp(2.15rem, 4.3vw, 3.35rem); margin-bottom: 14px; text-wrap: balance; font-weight: 500; }
/* Le mot en doré ne survit QUE dans le titre du hero. Répété à chaque section,
   il devenait un tic : on lisait la même page huit fois. */
.hero h1 em { font-style: normal; color: var(--gold-soft); }
/* Aucun fichier italique de Cormorant Garamond n'existe dans assets/fonts/ :
   le navigateur penchait les lettres mécaniquement (largeur identique au
   romain au pixel près). On garde l'emphase, portée par le doré, comme le H1.
   Un titre de section est sur fond CLAIR : c'est --gold-deep (5,37:1) qu'il lui
   faut, et non le doré pâle du H1, réservé aux fonds sombres (1,5:1 ici). */
.section-title em { font-style: normal; color: var(--gold-deep); }
.cta-band .section-title em { color: var(--gold-soft); }

/* Sous-titre de section : aligné à gauche, jamais centré. Le centrage systématique
   du couple titre + chapeau est la signature la plus reconnaissable des pages
   générées ; ici chaque section choisit son propre appui. */
.lead { font-size: clamp(1.04rem, 1.5vw, 1.18rem); color: var(--muted); max-width: 56ch; text-align: left; text-wrap: pretty; }

/* ---------- Boutons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-body); font-weight: 500; font-size: .875rem; line-height: 1; letter-spacing: 0;
  padding: 12px 22px; border-radius: 10px; cursor: pointer; border: 1.5px solid transparent;
  transition: transform .25s ease, background .25s ease, color .25s ease, box-shadow .25s ease, border-color .25s ease;
  white-space: nowrap;
  /* 40 px de haut au doigt, c'est quatre de moins que le minimum confortable.
     Le bouton grandit de quatre pixels, personne ne le verra ; ceux qui visent
     mal, si. */
  min-height: 44px;
}
.btn:hover { transform: translateY(-2px); }
/* Système épuré N&B : primaire NOIR sur fond clair, pastille BLANCHE sur fond sombre.
   Plus aucun doré sur les boutons (le doré ne reste que sur les micro-accents). */
.btn-gold { background: var(--ink); color: var(--cream); }
.btn-gold:hover { background: var(--ink-hover); box-shadow: var(--shadow-sm); }
.hero .btn-gold, .cta-band .btn-gold, .mobile-menu .btn-gold, .header .btn-gold { background: var(--cream); color: var(--ink); }
.hero .btn-gold:hover, .cta-band .btn-gold:hover, .mobile-menu .btn-gold:hover, .header .btn-gold:hover { background: #fff; box-shadow: 0 12px 30px rgba(0, 0, 0, .25); }
.header.scrolled .btn-gold { background: var(--ink); color: var(--cream); }
.header.scrolled .btn-gold:hover { background: var(--ink-hover); }
.btn-outline { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .55); }
.btn-outline:hover { background: #fff; color: var(--ink); border-color: #fff; }
/* Bouton secondaire sur fond sombre (ardoise) */
.btn-outline-light { background: transparent; color: var(--cream); border-color: rgba(255, 255, 255, .38); }
.btn-outline-light:hover { background: var(--cream); color: var(--ink); border-color: var(--cream); }
/* LA FLÈCHE EST UN DESSIN, PAS UN CARACTÈRE.
   Elle apparaît 9 fois, toujours sur un appel à l'action, et U+2192 (→) est
   ABSENT des deux .woff2 : ce sont les sous-ensembles « latin » de Google
   Fonts, qui embarquent ↑ et ↓ mais pas →. Élargir la plage unicode-range
   n'y change rien, le glyphe n'existe pas dans le fichier ; la flèche partait
   donc à la police système, avec une graisse étrangère au libellé d'à côté.
   En SVG, elle suit `currentColor`, son trait s'accorde au texte, et elle ne
   dépend plus d'aucune police. */
.arrow { display: inline-flex; align-items: center; vertical-align: -.12em; }
.arrow svg {
  width: .95em; height: .95em; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round;
}
.btn .arrow { transition: transform .25s ease; }
.btn:hover .arrow { transform: translateX(4px); }

/* =========================================================
   HEADER (ultra épuré, transparent puis verre dépoli)
   ========================================================= */
.header {
  position: fixed; inset: 0 0 auto 0; height: var(--header-h); z-index: 100;
  display: flex; align-items: center;
  /* `height` ne fait plus partie de la transition. C'est une propriété de MISE EN
     PAGE : l'animer obligeait le navigateur à refaire la géométrie de la barre à
     chaque image pendant 450 ms, et ce à chaque franchissement du seuil de 60 px
     de défilement, donc plusieurs fois par lecture. Le changement de gabarit est
     désormais net ; ce qui s'anime, ce sont les couleurs, l'ombre et le filet,
     qui ne coûtent qu'une peinture. */
  transition: background .45s ease, box-shadow .45s ease, border-color .45s ease, transform .35s ease;
  border-bottom: 1px solid transparent;
}
.header.is-hidden { transform: translateY(-100%); }
.header__inner { display: flex; align-items: center; justify-content: space-between; width: 100%; }
/* Le logo ne se comprime jamais. La cinquième entrée du menu le rétrécissait
   sous 1000 px, jusqu'à écraser la signature du Midi contre le premier lien :
   c'est le menu qui se resserre, pas la marque. */
.brand { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 5px; flex-shrink: 0; }

/* ---- Logotype « Padel Teambuilding » ----
   Purement typographique (charte du 21/08/2026) : deux graisses d'Inter, un
   filet qui représente le filet de padel (doré en haut, bordeaux en bas), une
   balle. Composé en CSS, jamais en image : net à toutes les tailles, aucun
   asset à charger. Les valeurs (em) et la structure viennent telles quelles
   de la charte graphique fournie par le client. */
.brand__mark {
  display: inline-flex; align-items: center; gap: .42em;
  font-family: var(--font-body); font-size: 22px; font-weight: 300;
  line-height: 1; letter-spacing: -.025em; color: #fff; white-space: nowrap;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .35);
  transition: color .45s ease, text-shadow .45s ease, font-size .45s ease;
}
.brand__mark-b { font-weight: 600; display: inline-flex; align-items: baseline; gap: .1em; }
.brand__mark-rule {
  width: .045em; height: 1.03em; flex: 0 0 auto;
  background: linear-gradient(var(--gold) 0%, var(--gold) 42%, var(--midi-clair) 58%, var(--midi-clair) 100%);
  transition: background .45s ease;
}
.brand__mark-dot { width: .2em; height: .2em; border-radius: 999px; flex: 0 0 auto; background: var(--midi-clair); transition: background .45s ease; }
.header.scrolled .brand__mark { font-size: 19px; color: var(--ink); text-shadow: none; }
.header.scrolled .brand__mark-rule { background: linear-gradient(var(--gold) 0%, var(--gold) 42%, var(--midi) 58%, var(--midi) 100%); }
.header.scrolled .brand__mark-dot { background: var(--midi); }
/* Pied de page : fond toujours sombre, donc toujours la version claire du logo */
.brand__mark--dark { font-size: 26px; color: #fff; text-shadow: none; }

/* ---- Attribution « by Wel Padel · Le Midi », sous le logo commun ----
   Discrète et subordonnée : les deux clubs restent visibles sur chaque page,
   sans reformer un double logo à poids égal avec la marque commune. */
.brand__by { display: flex; align-items: center; gap: 7px; }
/* .75rem = 12px, le plancher typographique du site (skill typographie-web) :
   sous cette taille, un libellé fonctionnel devient illisible en petit corps. */
.brand__by-label {
  font-family: var(--font-body); font-weight: 500; font-size: .75rem;
  letter-spacing: .08em; text-transform: uppercase; color: rgba(255, 255, 255, .55);
  transition: color .45s ease;
}
.header.scrolled .brand__by-label { color: var(--muted); }
.brand__logo { position: relative; display: flex; align-items: center; }
.brand__sep { width: 1px; height: 19px; background: rgba(255, 255, 255, .38); transition: background .45s ease; }
.header.scrolled .brand__sep { background: var(--line); height: 17px; }
/* Même raison que pour la barre : les logos changent de taille d'un coup, en même
   temps qu'elle. Seule l'opacité (logo clair vers logo foncé) reste animée. */
.brand__img { height: 21px; width: auto; display: block; transition: opacity .45s ease; }
.brand__img--light { filter: drop-shadow(0 1px 6px rgba(0, 0, 0, .3)); }
.brand__img--dark { position: absolute; inset: 0; opacity: 0; }
.header.scrolled {
  background: rgba(251, 250, 246, .86);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  height: 72px;
  border-bottom: 1px solid var(--line);
  box-shadow: 0 8px 30px rgba(60, 44, 8, .07);
}
.header.scrolled .brand__img { height: 19px; }
.header.scrolled .brand__img--light { opacity: 0; }
.header.scrolled .brand__img--dark { opacity: 1; }

/* Pied de page : logos des clubs en petit, sous le logo commun. Tailles
   ajustées plus bas, avec le reste des règles `.footer`. */
.brand__by--footer { gap: 10px; }

.nav { display: flex; align-items: center; gap: 28px; }
.nav__links { display: flex; gap: 24px; }
/* Deux états à ne JAMAIS confondre :
   - « actif » = la section où l'on se trouve. Doré, trait plein. Un seul à la fois.
   - « survolé » = la section où l'on pourrait aller. Trait neutre et plus fin.
   Avant, les deux avaient exactement le même style : en survolant un lien, deux
   entrées apparaissaient dorées et soulignées, comme si on était aux deux
   endroits en même temps. */
.nav__links a { font-weight: 500; font-size: .875rem; color: #fff; position: relative; padding: 5px 0; letter-spacing: 0; transition: color .25s ease; text-shadow: 0 1px 10px rgba(0,0,0,.35); }
/* Le trait est là en permanence, replié sur lui-même : on l'ouvre en `scaleX`,
   qui se joue sur le compositeur, au lieu d'animer sa largeur, qui repasse par
   la mise en page. Même mouvement à l'œil, rien à recalculer. */
.nav__links a::after {
  content: ""; position: absolute; left: 0; bottom: -2px; width: 100%; height: 2px;
  background: var(--gold); transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .28s ease;
}
/* Le survol NE SOULIGNE PAS. Le soulignement est réservé à la section courante :
   il ne peut donc jamais y en avoir deux à l'écran. Survoler change seulement la
   teinte du mot, ce qui suffit à dire « ce lien est cliquable ». */
.nav__links a:hover:not(.active) { color: rgba(255, 255, 255, .72); }
.header.scrolled .nav__links a { color: var(--ink); text-shadow: none; }
.header.scrolled .nav__links a:hover:not(.active) { color: var(--muted); }
/* Section courante : le seul doré de la barre */
.nav__links a.active { color: var(--gold-soft); }
.header.scrolled .nav__links a.active { color: var(--gold-deep); }
.nav__links a.active::after { transform: scaleX(1); }

/* Lien social dans le header */
.nav__fb, .nav__gps { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 9px; color: #fff; background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .28); transition: background .25s ease, border-color .25s ease, color .25s ease, transform .25s ease; }
.nav__fb svg { width: 16px; height: 16px; display: block; }
.header.scrolled .nav__fb, .header.scrolled .nav__gps { color: var(--ink); background: rgba(22, 20, 14, .05); border-color: var(--line); }
.nav__fb:hover { background: var(--facebook); border-color: var(--facebook); color: #fff; transform: translateY(-2px); }

/* Pastille GPS : même gabarit que Facebook, doré au survol (couleur de marque,
   là où Facebook prend la sienne). L'épingle est un peu plus grande que le « f » :
   à 16 px son cercle intérieur se bouche et le pictogramme devient une tache. */
.nav__gps svg { width: 19px; height: 19px; display: block; }
.nav__gps:hover { background: var(--gold); border-color: var(--gold); color: #fff; transform: translateY(-2px); }

/* Burger.
   C'est la commande de navigation principale du mobile, et elle faisait 42 × 34 px,
   sous les 44 px recommandés au doigt. Le dessin ne change pas : c'est la zone
   sensible autour qui s'agrandit. */
.burger {
  display: none; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; background: none; border: 0; cursor: pointer;
  padding: 8px; min-width: 44px; min-height: 44px; z-index: 120;
}
.burger span { width: 26px; height: 2.5px; background: #fff; border-radius: 2px; transition: .3s ease; box-shadow: 0 1px 6px rgba(0,0,0,.3); }
.header.scrolled .burger span { background: var(--ink); box-shadow: none; }
.burger.open span { background: #fff; box-shadow: none; }
.burger.open span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.burger.open span:nth-child(2) { opacity: 0; }
.burger.open span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

/* Menu mobile */
.mobile-menu {
  position: fixed; inset: 0; background: linear-gradient(165deg, var(--ink-menu), var(--ink-3)); z-index: 110;
  display: flex; flex-direction: column; align-items: center; justify-content: safe center; gap: 4px;
  padding: calc(var(--header-h) + 10px) 24px calc(30px + env(safe-area-inset-bottom));
  overflow-y: auto;
  opacity: 0; visibility: hidden;
  transition: opacity .4s ease, visibility 0s .4s;
}
.mobile-menu.open { opacity: 1; visibility: visible; transition: opacity .4s ease, visibility 0s 0s; }
.mobile-menu a { font-family: var(--font-display); font-size: 2.3rem; font-weight: 500; letter-spacing: -.02em; color: var(--cream); padding: 9px 0; }
.mobile-menu a:hover { color: var(--gold-soft); }
.mobile-menu .btn { margin-top: 22px; font-family: var(--font-body); font-size: 1rem; }
.mobile-menu__contact { margin-top: 28px; color: var(--gold-soft); font-size: .9rem; letter-spacing: .04em; text-align: center; font-family: var(--font-body); }
.mobile-menu > * { opacity: 0; transform: translateY(16px); transition: opacity .4s ease, transform .4s var(--ease-out); }
.mobile-menu.open > * { opacity: 1; transform: none; }
.mobile-menu.open > *:nth-child(1) { transition-delay: .10s; }
.mobile-menu.open > *:nth-child(2) { transition-delay: .15s; }
.mobile-menu.open > *:nth-child(3) { transition-delay: .20s; }
.mobile-menu.open > *:nth-child(4) { transition-delay: .25s; }
.mobile-menu.open > *:nth-child(5) { transition-delay: .30s; }
.mobile-menu.open > *:nth-child(6) { transition-delay: .35s; }
.mobile-menu.open > *:nth-child(7) { transition-delay: .40s; }
.mobile-menu.open > *:nth-child(8) { transition-delay: .45s; }
body.nav-open .header { z-index: 130; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; border-bottom-color: transparent; box-shadow: none; }
body.nav-open .header .brand__img--light { opacity: 1; }
body.nav-open .header .brand__img--dark { opacity: 0; }
body.nav-open .burger span { background: #fff; }
/* Le verrou de marque est du texte, pas une image : le bloc au-dessus ne le
   couvrait pas, et il restait en noir sur le fond noir du menu (1,11:1). */
body.nav-open .header .brand__mark      { color: #fff; text-shadow: none; }
body.nav-open .header .brand__mark-rule { background: linear-gradient(var(--gold) 0%, var(--gold) 42%, var(--midi-clair) 58%, var(--midi-clair) 100%); }
body.nav-open .header .brand__mark-dot  { background: var(--midi-clair); }
body.nav-open .header .brand__by-label  { color: rgba(251, 250, 246, .65); }

/* =========================================================
   HERO (bannière cinématographique premium)
   ========================================================= */
/* Le contenu s'ancre en bas à gauche, pas au centre géométrique. Un titre centré
   sur une photo plein écran est LE gabarit d'accueil par défaut ; en le calant
   en bas à gauche, la bannière se met à ressembler à une affiche. */
.hero {
  /* Un moteur qui ne connaît pas l'unité svh ignore toute la déclaration et la
     bannière s'effondre à la hauteur de son contenu. La ligne vh la rattrape. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex; align-items: flex-end; justify-content: flex-start;
  text-align: left; overflow: hidden;
  padding: calc(var(--header-h) + 30px) 26px 108px;
}
/* Diptyque : les deux clubs côte à côte, séparés d'une couture diagonale dorée.
   Chaque moitié = un wrapper clippé (clip-path) + une image interne animée (Ken Burns),
   pour que la couture reste parfaitement stable pendant l'animation. */
/* La position de la couture est pilotée par une seule variable : --split (en %).
   50 = équilibre parfait. Le curseur la déplace, elle revient seule au centre. */
@property --split {
  syntax: "<number>";
  inherits: true;
  initial-value: 50;
}
.hero { --split: 50; }
.hero__bg { position: absolute; inset: 0; z-index: -2; }
.hero__half { position: absolute; inset: 0; overflow: hidden; }
.hero__half--wel {
  clip-path: polygon(0 0, calc(var(--split) * 1% + 4.8%) 0, calc(var(--split) * 1% - 4.2%) 100%, 0 100%);
}
.hero__half--midi {
  clip-path: polygon(calc(var(--split) * 1% + 4.2%) 0, 100% 0, 100% 100%, calc(var(--split) * 1% - 4.8%) 100%);
}
.hero__half-img { position: absolute; inset: 0; display: block; background: center / cover no-repeat; animation: kenburns 26s ease-in-out infinite alternate; }
/* WebP avec repli JPEG : la ligne url() sert les navigateurs sans image-set,
   image-set() sert le WebP (environ le quart du poids) à tous les autres. */
.hero__half--wel .hero__half-img {
  background-image: url('../img/hero.jpg');
  background-image: image-set(url('../img/hero-1920.webp') type('image/webp'), url('../img/hero.jpg') type('image/jpeg'));
}
.hero__half--midi .hero__half-img {
  background-image: url('../img/hero-midi.jpg');
  background-image: image-set(url('../img/hero-midi-2048.webp') type('image/webp'), url('../img/hero-midi.jpg') type('image/jpeg'));
  animation-duration: 30s; animation-delay: -9s;
}
/* Petits écrans : on n'envoie pas une image de 1920 px sur un téléphone. */
@media (max-width: 820px) {
  .hero__half--wel .hero__half-img { background-image: image-set(url('../img/hero-1280.webp') type('image/webp'), url('../img/hero.jpg') type('image/jpeg')); }
  .hero__half--midi .hero__half-img { background-image: image-set(url('../img/hero-midi-1280.webp') type('image/webp'), url('../img/hero-midi.jpg') type('image/jpeg')); }
}
/* `will-change` n'est pas un réglage de performance qu'on laisse allumé : c'est
   une réservation de mémoire vive, faite au chargement et jamais rendue. Les
   trois découpes du diptyque la gardaient en permanence, alors qu'elles ne
   bougent que pendant le passage du curseur. Le script pose la classe le temps
   du mouvement, et le navigateur récupère sa place ensuite. */
.hero.is-splitting .hero__half,
.hero.is-splitting .hero__seam { will-change: clip-path; }
.hero__seam {
  position: absolute; inset: 0;
  clip-path: polygon(calc(var(--split) * 1% + 4.32%) 0, calc(var(--split) * 1% + 4.68%) 0, calc(var(--split) * 1% - 4.32%) 100%, calc(var(--split) * 1% - 4.68%) 100%);
  background: linear-gradient(180deg, transparent 4%, rgba(231, 206, 134, .5) 30%, rgba(231, 206, 134, .5) 70%, transparent 96%);
}
/* Bandeau du bas : les deux clubs se nomment, le repère de défilement au milieu.
   Une seule ligne, alignée sur la couture du diptyque. */
.hero__clubs {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 20px; padding: 0 34px 26px;
  border-top: 0;
}
.hero__club {
  font-family: var(--font-body); font-weight: 500; font-size: .75rem;
  letter-spacing: .13em; text-transform: uppercase;
  color: rgba(255, 255, 255, .86); text-shadow: 0 1px 12px rgba(0, 0, 0, .5);
  transition: color .5s ease, letter-spacing .5s ease;
}
.hero__club--wel { justify-self: start; padding-left: 62px; } /* dégage le bouton d'appel flottant */
.hero__club--midi { justify-self: end; text-align: right; }
.hero__club::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 9px; vertical-align: 1px; }
.hero__club--wel::before { background: var(--gold-bright); }
.hero__club--midi::before { background: var(--midi-clair); }
/* Le club dont le côté s'agrandit s'affirme un peu plus */
.hero.is-wel .hero__club--wel, .hero.is-midi .hero__club--midi { color: #fff; letter-spacing: .18em; }
.hero.is-wel .hero__club--midi, .hero.is-midi .hero__club--wel { color: rgba(255, 255, 255, .5); }
.hero__scrim {
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(ellipse 82% 64% at 50% 52%, rgba(16, 13, 7, .26), rgba(16, 13, 7, .62) 78%),
    linear-gradient(180deg, rgba(16, 13, 7, .58) 0%, rgba(16, 13, 7, .14) 30%, rgba(16, 13, 7, .5) 70%, rgba(16, 13, 7, .9) 100%);
}
@keyframes kenburns { from { transform: scale(1) translateY(0); } to { transform: scale(1.09) translateY(-1.2%); } }
.hero__inner {
  position: relative; width: 100%;
  max-width: var(--container); margin: 0 auto;
  padding-left: clamp(0px, 2vw, 26px);
}
/* LE SUR-TITRE DE LA BANNIÈRE EST UN MARQUAGE, PAS UNE MENTION.
   C'est la première phrase de la page, celle qui dit ce qu'on vend et à qui :
   « team building d'entreprise, province de Liège ». En doré pâle de 12 px posé
   à même la photo, elle se lisait comme une mention de service, et il fallait la
   chercher. Elle passe sur un aplat doré, en noir : c'est le seul endroit de la
   page où le doré de marque devient une surface, et il sert à désigner le public.

   Les trois réglages tiennent ensemble :
   - le corps monte de 12 à 14,4 px, et l'interlettrage descend de .18 à .14em.
     Un interlettrage large sur une phrase longue écarte les mots au lieu de les
     poser ; il la rendait floue autant que sa taille ;
   - le texte est NOIR sur l'aplat, jamais blanc. Mesuré : blanc cassé sur ce
     doré donne 2,70:1, noir donne 6,67:1. Le dégradé s'arrête à #C09020 et ne
     descend pas jusqu'au #9A7016 du dégradé de marque, qui tomberait à 4,32:1,
     sous le seuil. Le reflet reste, la lisibilité aussi ;
   - chaque ligne porte sa propre bande (`box-decoration-break: clone`). Sans
     cela, les deux lignes du téléphone seraient enfermées dans un seul
     rectangle, avec du doré vide au bout de la plus courte.

   L'ALIGNEMENT. Le retrait intérieur de la bande décalerait le texte de 11 px
   vers la droite, et le sur-titre ne serait plus sur le même bord gauche que le
   titre juste dessous. C'est le porteur de bloc qui rattrape ce décalage, et non
   une marge négative sur la bande elle-même : une marge négative ne s'applique
   qu'au PREMIER fragment d'un texte en ligne, donc les deux lignes du téléphone
   partiraient de deux bords différents. Les deux valeurs sortent de la même
   variable pour qu'elles ne puissent pas diverger. */
.hero__surtitre {
  --surtitre-retrait: 11px;
  margin: 0 0 20px calc(-1 * var(--surtitre-retrait));
  line-height: 2.45;
  text-wrap: balance;
}
.hero__kicker {
  display: inline;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding: 7px var(--surtitre-retrait);
  border-radius: 3px;
  background-image: linear-gradient(100deg, var(--gold-bright), var(--gold));
  color: var(--ink);
  font-size: .9rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-shadow: none;
  box-shadow: 0 8px 24px rgba(10, 10, 10, .34);
}
/* Le titre d'accueil, le seul endroit où la serif monte aussi haut. Le corps a
   été relevé et l'interlettrage descendu à -.025em : c'est à cette taille que le
   resserrage se voit le plus, et qu'il compte le plus. */
.hero h1 { font-size: clamp(2.7rem, 6.2vw, 4.9rem); line-height: 1.03; margin: 6px 0 22px; color: #fff; text-shadow: 0 4px 44px rgba(0, 0, 0, .5); font-weight: 500; letter-spacing: -.025em; max-width: 17ch; }
.hero__accroche { font-size: clamp(1.05rem, 1.7vw, 1.3rem); color: rgba(255, 255, 255, .92); max-width: 46ch; margin: 0 0 34px; text-shadow: 0 2px 22px rgba(0, 0, 0, .5); }
.hero__cta { display: flex; gap: 24px; justify-content: flex-start; align-items: center; flex-wrap: wrap; }
.hero__meta { margin-top: 26px; font-size: .9rem; letter-spacing: .04em; color: rgba(255, 255, 255, .85); }
.hero__meta strong { color: #fff; }
/* Repère de défilement : le premier segment du fil de terrain, avec la balle
   qui descend. Pas de souris stylisée, pas de chevron. */
.scroll-cue { width: 26px; height: 52px; display: block; position: relative; justify-self: center; }
.scroll-cue__line { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; transform: translateX(-50%); background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(231, 206, 134, .75) 55%, rgba(231, 206, 134, 0)); }
.scroll-cue__line::after {
  content: ""; position: absolute; left: 50%; top: 0; width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold-soft); box-shadow: 0 0 10px rgba(231, 206, 134, .8);
  transform: translateX(-50%); animation: cueDrop 2.4s cubic-bezier(.5, 0, .5, 1) infinite;
}
@keyframes cueDrop {
  0% { top: 2px; opacity: 0; }
  18% { opacity: 1; }
  72% { opacity: 1; }
  100% { top: 44px; opacity: 0; }
}

/* =========================================================
   CONCEPT (split photo + texte)
   ========================================================= */
/* Colonne de texte étroite (5 colonnes sur 12), média large qui déborde du
   conteneur jusqu'au bord droit de la fenêtre. La page cesse d'être une suite
   de blocs sagement rangés dans la même boîte de 1200 px. */
.concept { background: var(--paper); overflow: hidden; }
.split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(32px, 5vw, 64px); align-items: center; }
.split__media { position: relative; }
.split__body p + p { margin-top: 18px; }
.split__body p { color: var(--body); }
/* Le chapeau du concept. Il était à peine 9 % plus gros que le paragraphe qui
   suit : trop peu pour se lire comme une hiérarchie voulue, assez pour se voir
   comme un défaut. Avec en plus un saut de couleur franc et deux interlignes
   différents, l'œil concluait « ce n'est pas la même police ».
   On assume l'écart : nettement plus gros, donc manifestement intentionnel. */
/* Le plancher du clamp compte autant que le plafond : sur mobile, 1.55vw ne vaut
   plus rien et c'est la valeur minimale qui s'applique. Réglée à 1.26rem pour que
   l'écart avec le paragraphe reste franc (~19 %) sur TOUTES les largeurs, et pas
   seulement sur grand écran. */
/* Le chapeau est désormais le SEUL paragraphe du bloc : il reprend le style
   des chapeaux de toutes les autres sections (même corps, même gris), pour
   qu'aucune section ne semble composée autrement que ses voisines. */
.split__body .lead { margin: 18px 0 22px; max-width: 46ch; }
@media (min-width: 1100px) {
  /* le média sort de la grille et file jusqu'au bord de l'écran */
  .concept .split__media { margin-right: calc((100vw - var(--container)) / -2 - 26px); }
  .concept .carousel__viewport { border-radius: var(--radius-lg) 0 0 var(--radius-lg); }
  /* la flèche « suivante » s'écarte du bouton « remonter », lui aussi collé au bord */
  .concept .carousel__arrow--next { right: 74px; }
}

/* =========================================================
   STATS (bande sombre, compteurs animés)
   ========================================================= */
/* Bande sombre asymétrique : une phrase à gauche, les chiffres à droite,
   tous alignés à gauche. Quatre colonnes centrées et identiques, c'était encore
   la même grille que partout ailleurs. */
.stats { background: var(--ink-2); color: var(--cream); overflow: hidden; padding: clamp(50px, 6.5vw, 76px) 0; }
.stats::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse 60% 80% at 82% 6%, rgba(216, 174, 62, .13), transparent 62%); }
.stats__inner { position: relative; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(28px, 5vw, 64px); align-items: end; }
.stats__intro {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.55rem, 2.6vw, 2.1rem); line-height: 1.16;
  color: var(--cream); letter-spacing: -.02em;
}
.stats__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.stat { text-align: left; position: relative; padding-left: 16px; }
.stat::before { content: ""; position: absolute; left: 0; top: 4px; bottom: 4px; width: 1px; background: var(--line-on-dark); }
/* Les chiffres du tableau d'affichage restent en serif : c'est le parti pris du
   design de référence, où même les prix sont composés dans la police de titre. */
.stat__num { font-family: var(--font-display); font-weight: 500; font-size: clamp(2.4rem, 4.1vw, 3.4rem); line-height: 1; color: var(--gold-soft); letter-spacing: -.03em; white-space: nowrap; }
.stat__num .suffix { color: var(--gold); }
.stat__label { margin-top: 10px; font-size: .75rem; text-wrap: balance; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-2); line-height: 1.5; }

/* =========================================================
   RÉFÉRENCES (la bande de logos)
   ========================================================= */
/* Six marques, et l'envie légitime de les montrer toutes en même temps. C'est
   justement ce qu'il ne faut pas faire : six logos alignés d'un bord à l'autre
   se lisent comme un pied de page. Ils défilent donc au pas, très espacés, et
   on n'en regarde qu'un ou deux à la fois.

   Le traitement des logos est le point délicat. Ils arrivent avec six palettes
   qui n'ont rien à voir entre elles, dans une page qui ne s'autorise qu'une
   seule couleur de marque tierce. On les désature donc au repos, et chacun
   reçoit sa correction de densité : sans elle, le bleu clair de Knauf et
   l'orange d'Elia virent au gris pâle et disparaissent à côté du noir de BMW.
   Trois variables par marque, posées dans le HTML : --h la hauteur, --c le
   contraste, --b la luminosité, --o l'opacité. */
/* Trois lignes de texte et une bande de logos : avec le rythme vertical commun
   à toutes les sections, la moitié de l'écran serait vide. On resserre, comme le
   fait déjà la bande des chiffres juste au-dessus. */
.refs { background: var(--paper); overflow: hidden; padding: clamp(58px, 7vw, 100px) 0; }
.refs__head { max-width: 62ch; }
.refs__head .lead { margin-top: 14px; }

/* La piste déborde volontairement du conteneur : elle prend toute la largeur de
   l'écran. Le masque en dégradé fait entrer et sortir les logos en fondu, au
   lieu de les trancher net contre le bord de la fenêtre. */
.refs__piste {
  margin-top: clamp(34px, 4.6vw, 60px);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

/* ÉTAT DE REPOS, celui que voit un visiteur sans JavaScript : les six logos se
   posent au centre, sur une ou deux lignes. Rien ne bouge, mais tout se lit.
   Le défilement n'est ajouté qu'ensuite, par le script, qui recopie la liste
   autant de fois qu'il faut pour couvrir l'écran (--refs-pas) et règle la durée
   pour que la vitesse reste la même sur un téléphone et sur un 27 pouces. */
.refs__ruban { display: flex; flex-wrap: wrap; justify-content: center; }
.refs__file { display: flex; align-items: center; flex-wrap: inherit; justify-content: inherit; margin: 0; padding: 0; list-style: none; }

.refs--anime .refs__ruban {
  flex-wrap: nowrap; justify-content: flex-start; width: max-content;
  animation: refs-defile var(--refs-duree, 40s) linear infinite;
  will-change: transform;
}
.refs--anime .refs__file { flex-wrap: nowrap; }

/* Le sens demandé : les logos vont vers la DROITE. On part donc d'une copie de
   retard pour revenir à zéro. Comme toutes les copies sont identiques, le
   raccord ne se voit pas. Inverser le sens : échanger `from` et `to`. */
@keyframes refs-defile {
  from { transform: translate3d(var(--refs-pas, -33.3333%), 0, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* La bande s'arrête sous la souris : on veut pouvoir lire un logo qui passe,
   pas courir après. Le `focus-within` fait le même service au clavier. */
.refs--anime .refs__piste:hover .refs__ruban,
.refs--anime .refs__piste:focus-within .refs__ruban { animation-play-state: paused; }
/* Et rien ne tourne hors de l'écran : la section est observée avec le hero. */
.refs.is-paused .refs__ruban { animation-play-state: paused; }

/* L'écart entre deux logos est porté par les items eux-mêmes, jamais par un
   `gap` : c'est ce qui garantit le même intervalle à la jonction de deux
   copies qu'à l'intérieur d'une copie. */
.refs__item {
  flex: 0 0 auto; display: grid; place-items: center;
  padding: 14px clamp(30px, 3.4vw, 52px);
}
.refs__logo {
  display: block; width: auto; height: var(--h, 52px);
  filter: grayscale(1) contrast(var(--c, 1)) brightness(var(--b, 1));
  opacity: var(--o, .7);
  transition: opacity .4s var(--ease-out), filter .4s var(--ease-out), transform .4s var(--ease-out);
}
/* Au survol, la marque reprend ses couleurs. C'est la seule dérogation à la
   règle de la couleur unique, et elle ne dure que le temps du geste. */
.refs__item:hover .refs__logo { filter: none; opacity: 1; transform: translateY(-2px) scale(1.04); }

/* LA SECONDE RANGÉE, SUR PETIT ÉCRAN, VA DANS L'AUTRE SENS.
   Elle est posée par le script, qui coupe la liste en deux sous 760 px (voir
   `bandeReferences` dans main.js). Deux réglages suffisent ici : elle se colle
   à la première, et son animation se joue à l'envers.
   `animation-direction: reverse` plutôt qu'un second jeu d'images-clés : c'est
   la MÊME course, lue dans l'autre sens. Deux jeux d'images-clés à maintenir
   finiraient par diverger, et le raccord des copies avec eux. */
.refs__piste--b { margin-top: 0; }
.refs--anime .refs__ruban--inverse { animation-direction: reverse; }

@media (max-width: 760px) {
  .refs__item { padding: 12px clamp(22px, 6vw, 34px); }
  .refs__logo { height: calc(var(--h, 52px) * .84); }
  /* Sur un écran étroit, 9 % de fondu ne font que 35 px : un logo se retrouvait
     tranché plus qu'estompé au bord. On élargit le dégradé. */
  .refs__piste {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 15%, #000 85%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 15%, #000 85%, transparent);
  }
}

/* Mouvement réduit : la bande s'immobilise et redevient la grille du repos.
   Sans le retour au `wrap`, les copies ajoutées par le script resteraient
   alignées en une seule ligne, arrêtée hors de l'écran. */
@media (prefers-reduced-motion: reduce) {
  .refs--anime .refs__ruban { animation: none !important; width: auto; flex-wrap: wrap; justify-content: center; }
  .refs--anime .refs__file { flex-wrap: wrap; justify-content: center; }
  .refs__logo { transition: none; }
}

/* =========================================================
   POURQUOI (cartes atouts)
   ========================================================= */
/* Colonne d'appui à gauche (elle reste à l'écran), arguments en lignes à droite.
   Ni cartes, ni icônes en pastille : c'est la grille de quatre cartes blanches
   qui rendait cette section interchangeable avec n'importe quelle autre page. */
.pourquoi { background: var(--paper-2); }
.pourquoi__inner { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: clamp(32px, 6vw, 90px); align-items: start; }
.pourquoi__aside .lead { margin-top: 16px; }
@media (min-width: 921px) {
  .pourquoi__aside { position: sticky; top: calc(var(--header-h) + 40px); }
}
.args { display: flex; flex-direction: column; }
/* Plus de filet gris pleine largeur entre les arguments : il coupait la colonne
   en tranches et faisait tableau. Le petit trait doré au-dessus de chaque titre
   sépare déjà, en plus discret. On rend l'espace un peu plus généreux pour qu'il
   fasse seul le travail du trait. */
.arg { padding: 32px 0; }
.arg:first-child { padding-top: 0; }
.arg:last-child { padding-bottom: 0; }
.arg h3 { font-size: clamp(1.45rem, 2.25vw, 1.8rem); margin-bottom: 8px; position: relative; }
/* Un simple trait doré qui se tire à l'apparition, à la place du cercle à icône */
.arg h3::before {
  content: ""; position: absolute; left: 0; top: -14px; height: 2px; width: 0;
  background: var(--gold); transition: width .7s var(--ease-out) .1s;
}
.js .arg.in h3::before { width: 34px; }
.arg:first-child h3::before { display: none; }
.arg p { color: var(--muted); font-size: 1rem; max-width: 54ch; }

/* =========================================================
   FORMULES (tarifs)
   ========================================================= */
/* =========================================================
   L'ARDOISE
   Le tableau de prix à deux cartes, badge « le plus demandé » et listes à coches
   vient du logiciel en abonnement. Ici on vend 1h30 de terrain et un repas :
   c'est une ardoise de restaurant qu'il faut, avec les points de conduite qui
   relient chaque ligne à ce qu'elle contient.
   ========================================================= */
.formules { background: var(--paper); }
.formules__head { max-width: 62ch; }
.formules__head .lead { margin-top: 14px; }
.formules__actions { display: flex; justify-content: flex-start; align-items: center; gap: 22px; flex-wrap: wrap; margin-top: 34px; }

.ardoise {
  /* Le retrait intérieur suit celui du formulaire, bordure comprise : les deux
     cartes de la page posent ainsi leur texte sur la même grille, au pixel près,
     à toutes les largeurs. L'ardoise garde seulement une marge plus généreuse
     sur grand écran, où elle est la pièce maîtresse. */
  margin-top: 48px; padding: calc(clamp(26px, 4vw, 51px) + 1px);
  background: var(--ink-3); color: var(--cream); border-radius: var(--radius-lg);
  display: grid; grid-template-columns: 1fr 1fr;
  column-gap: clamp(30px, 5vw, 64px); row-gap: 30px;
  box-shadow: 0 30px 70px rgba(10, 10, 10, .18);
  position: relative; overflow: hidden;
}
/* Sur fond sombre, le bouton principal s'inverse : blanc cassé sur noir. */
.ardoise .btn-gold { background: var(--cream); color: var(--ink); }
.ardoise .btn-gold:hover { background: #fff; box-shadow: 0 12px 30px rgba(0, 0, 0, .3); }
/* Le grain de la craie, très discret */
.ardoise::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: radial-gradient(ellipse 70% 60% at 15% 0%, rgba(231, 206, 134, .09), transparent 62%);
}
.ardoise__col { position: relative; display: flex; flex-direction: column; }
/* Filet de séparation entre les deux formules, comme sur une carte pliée */
.ardoise__col + .ardoise__col::before {
  content: ""; position: absolute; left: calc(clamp(30px, 5vw, 64px) / -2); top: 4px; bottom: 4px;
  width: 1px; background: var(--line-on-dark);
}
.ardoise__nom {
  font-family: var(--font-body); font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; font-size: .75rem; color: var(--gold-soft);
}
/* Montant et devise en ligne, sur une seule boîte de ligne : l'ancien flex
   alignait bien les baselines mais laissait le « € » dans sa propre boîte,
   séparable du nombre. En inline + nowrap, « 55 € » est insécable de fait. */
.ardoise__prix { display: block; white-space: nowrap; margin: 10px 0 4px; }
.ardoise__devise { margin-left: 6px; }
.ardoise__montant {
  font-family: var(--font-display); font-weight: 500; font-size: clamp(3.8rem, 8.8vw, 5.6rem);
  line-height: .92; color: #fff; letter-spacing: -.04em;
}
.ardoise__devise { font-family: var(--font-display); font-weight: 500; font-size: clamp(1.7rem, 3.3vw, 2.35rem); color: var(--gold-soft); }
.ardoise__unite { font-size: .84rem; color: var(--muted-2); letter-spacing: .04em; }

.ardoise__liste { margin: 26px 0 30px; display: flex; flex-direction: column; gap: 15px; }
.ardoise__liste li { display: flex; align-items: baseline; gap: 10px; font-size: .96rem; line-height: 1.5; }
.ardoise__item { color: #fff; font-weight: 500; flex-shrink: 0; }
/* Points de conduite : ils s'étirent pour combler l'espace, comme sur un menu */
.ardoise__pt {
  flex: 1 1 auto; min-width: 18px; align-self: center; height: 1px;
  background-image: radial-gradient(circle, rgba(231, 206, 134, .55) 1px, transparent 1px);
  background-size: 6px 2px; background-repeat: repeat-x; background-position: 0 center;
}
.ardoise__val { color: var(--muted-2); text-align: right; flex-shrink: 1; }
.ardoise__cta { margin-top: auto; width: 100%; }

/* La ligne du bas de l'ardoise : l'option, écrite comme sur un menu. */
.ardoise__option {
  grid-column: 1 / -1; position: relative;
  padding-top: 26px; border-top: 1px solid var(--line-on-dark);
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  font-size: .96rem;
}
/* Étiquette dans le doré de la charte : le vert néon essayé pour évoquer la
   lumière noire était la seule couleur hors charte de la page. */
.ardoise__option-nom {
  font-family: var(--font-body); font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  font-size: .84rem; color: var(--gold-soft);
}
.ardoise__option-prix { color: #fff; font-weight: 600; }
.ardoise__option-note { flex-basis: 100%; color: var(--muted-2); font-size: .86rem; }
.ardoise__option .ardoise__pt { background-image: radial-gradient(circle, rgba(231, 206, 134, .5) 1px, transparent 1px); }
/* Une deuxième option suit la première : elle ne rouvre pas un filet, sinon
   les deux lignes se liraient comme deux blocs sans rapport. Le filet du haut
   ouvre la zone des options, les lignes s'y suivent. */
.ardoise__option--suite { padding-top: 14px; border-top: 0; }

/* =========================================================
   DÉROULÉ (étapes)
   ========================================================= */
/* Le déroulé et l'appel qui le suit partagent le même gris. Partout ailleurs sur
   la page, un trou de 260 px est encadré par un changement de fond qui le
   justifie ; ici le lecteur voyait une dalle grise de 1 327 px avec un vide
   inexpliqué au milieu, et sur mobile ce vide occupait 30 % de l'écran.
   On ne les sépare pas, on les RÉUNIT : « Une date en tête ? » est la conclusion
   du déroulé. Le vide est resserré et coupé par un filet à la largeur du texte,
   comme les autres césures internes du site (équipements, intertitres de la
   mosaïque). Une vraie fin de section, au lieu d'un blanc qui ressemble à un bug. */
.deroule { background: var(--paper-2); padding-bottom: clamp(46px, 5.4vw, 76px); }
/* Le titre bascule à droite : la section précédente s'appuyait à gauche.
   C'est cette alternance qui empêche de relire six fois la même page. */
.deroule__head { max-width: 46ch; margin-left: auto; text-align: right; }
.deroule__head .lead { text-align: right; margin-left: auto; }

/* Les trois étapes suivent la trajectoire de la balle : la deuxième est plus haute,
   comme le sommet de l'échange. Plus de cartes blanches à ombre portée. */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 4vw, 46px); margin-top: 8px; align-items: start; }
.step { position: relative; padding-right: 12px; }
.step--haut { margin-top: -38px; }
/* Le doré clair sur ce fond ne donnait que 2,61:1, sous le seuil de 3:1 exigé pour
   du grand texte. `--gold-deep` est déjà là pour ce cas précis : même teinte à
   l'œil, 5,37:1 mesuré. */
.step__num {
  display: block; font-family: var(--font-display); font-weight: 500; font-size: 2.4rem;
  line-height: 1; color: var(--gold-deep); letter-spacing: -.02em;
}
.step h3 { font-size: clamp(1.4rem, 2.1vw, 1.7rem); margin: 12px 0 8px; }
.step p { color: var(--muted); font-size: .96rem; max-width: 34ch; }
/* L'échange : la balle passe d'une étape à l'autre pendant qu'on descend.
   Remplace les trois flèches génériques. */
.rally { margin: 42px auto 4px; }
.rally__svg { display: block; width: 100%; height: auto; overflow: visible; }
.rally__path {
  fill: none; stroke: var(--gold); stroke-width: 1.6; stroke-linecap: round;
  stroke-dasharray: 5 9; vector-effect: non-scaling-stroke; opacity: .55;
}
/* Les trois piquets qui relient la trajectoire aux cartes */
.rally__net { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
/* La balle de l'échange, en croquis. Le fond très pâle lui garde son rôle de
   repère de progression : au trait seul, elle disparaîtrait sur le papier. */
.rally__ball .balle__fond { fill: rgba(192, 144, 32, .14); stroke: none; }
.rally__ball .balle__trait {
  fill: none; stroke: var(--gold); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.rally__ball .balle__repasse { stroke-width: 1.1; opacity: .5; }
.rally__ball .balle__couture { stroke-width: 1.3; }
/* Sans JavaScript ou avant l'entrée à l'écran : la balle reste au départ, discrète */
.js .rally__ball { opacity: 0; transition: opacity .4s ease; }
.js .rally.is-live .rally__ball { opacity: 1; }
@media (max-width: 920px) { .rally { display: none; } }

/* =========================================================
   CARROUSEL (galerie)
   ========================================================= */
.galerie { background: var(--paper); }
.carousel { position: relative; }
.carousel__viewport { overflow: hidden; border-radius: var(--radius-lg); box-shadow: var(--shadow); touch-action: pan-y; }
.carousel__track { position: relative; aspect-ratio: 16 / 9; }
.carousel__slide { position: absolute; inset: 0; opacity: 0; z-index: 0; background: var(--photo-fond); transition: opacity .8s ease; }
.carousel__slide.is-active { opacity: 1; z-index: 2; }
.carousel__slide.is-prev { opacity: 1; z-index: 1; transition: none; }
.carousel__slide img { width: 100%; height: 100%; object-fit: cover; display: block; user-select: none; -webkit-user-drag: none; }
/* Les légendes du carrousel ont été retirées avec la refonte : plus de titre posé
   sur la photo, donc plus de voile sombre pour le rendre lisible. Les deux règles
   allaient ensemble (le voile était annulé sur les vues sans légende), elles
   partent ensemble - garder le voile seul aurait assombri les six photos. */
.carousel__arrow {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 3;
  width: 52px; height: 52px; border-radius: 50%; cursor: pointer;
  background: rgba(22, 20, 14, .42); border: 1.5px solid rgba(255, 255, 255, .55); color: #fff;
  display: grid; place-items: center; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: background .25s ease, border-color .25s ease, transform .25s ease;
}
.carousel__arrow:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); transform: translateY(-50%) scale(1.06); }
.carousel__arrow svg { width: 22px; height: 22px; }
.carousel__arrow--prev { left: 18px; }
.carousel__arrow--next { right: 18px; }
.carousel__dots { display: flex; gap: 2px; justify-content: center; align-items: center; margin-top: 18px; }
/* La pastille visible fait 8 px : c'est la zone autour qui compte au doigt.
   26 px passaient le seuil de justesse, 32 px se visent sans réfléchir. */
.carousel__dot { position: relative; width: 32px; height: 32px; border: 0; background: transparent; cursor: pointer; padding: 0; }
/* La pastille reste petite à l'œil, mais la zone touchable monte à 44 px : c'est
   le même procédé que le bouton « remonter », un pseudo-élément débordant qui
   agrandit la cible sans agrandir le dessin. */
.carousel__dot::before { content: ""; position: absolute; inset: -6px; }
.carousel__dot::after { content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 8px; height: 8px; border-radius: 5px; background: rgba(22, 20, 14, .2); transition: background .25s ease, width .25s ease; }
.carousel__dot.active::after { background: var(--gold); width: 24px; }

/* La commande de pause. Discrète comme les puces : c'est un utilitaire, pas un
   appel à l'action. Elle prend le doré au survol, comme toutes les commandes
   du site. */
.carousel__pause {
  position: relative;
  display: grid; place-items: center; width: 32px; height: 32px; margin-left: 10px;
  padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--muted);
  transition: background .25s ease, color .25s ease;
}
.carousel__pause::before { content: ""; position: absolute; inset: -6px; }
.carousel__pause svg { width: 15px; height: 15px; display: block; }
.carousel__pause:hover { background: rgba(22, 20, 14, .06); color: var(--ink); }

/* Ken Burns doux sur la slide active */
.carousel__slide.is-active img { animation: slidedrift 9s ease-out forwards; }
.carousel__slide.is-prev img { transform: scale(1.05); }
@keyframes slidedrift { from { transform: scale(1); } to { transform: scale(1.05); } }

/* =========================================================
   GALERIE FILTRABLE PAR INFRASTRUCTURE (Terrains/Bar/Terrasse/Restaurant/Fluo)
   ========================================================= */
/* =========================================================
   MOSAÏQUE ÉDITORIALE
   Avant : 44 photos au même format 4/3, dans une grille de trois colonnes,
   sur près de 40 % de la hauteur de page. Un dossier d'images, pas un parcours.
   Maintenant : 13 photos choisies, réparties en deux séquences (un club, puis
   l'autre). Chaque photo garde SES proportions natives — sa largeur est
   proportionnelle à son ratio, si bien que toutes celles d'une même ligne ont
   exactement la même hauteur. Aucun recadrage, et une hiérarchie réelle :
   une grande image ouvre chaque club, des plus petites suivent.
   ========================================================= */
.galerie__head { max-width: 60ch; }
.galerie__head .lead { margin-top: 14px; }

/* Les trois faits du lieu, remontés depuis « Les bienfaits ». Ils annoncent ce que
   les photos vont montrer, donc ils se lisent comme une légende de la mosaïque :
   un filet, un intitulé, une phrase. Pas de cartes ni de pastilles, le filet du
   haut suffit à séparer, comme les intertitres de clubs juste en dessous. */
/* Même gouttière que les trois étapes du déroulé : deux grilles de trois colonnes
   dans le même conteneur doivent tomber au même endroit, sinon leurs textes se
   décalent d'une section à l'autre (3,42 px mesurés en 1024 px avant correction). */
.cadre__faits {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 4vw, 46px); margin-top: clamp(32px, 4vw, 46px);
}
.cadre__fait { padding-top: 14px; border-top: 1px solid var(--line); }
.cadre__fait strong {
  display: block; font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.12rem, 1.5vw, 1.28rem); line-height: 1.25; color: var(--ink);
  margin-bottom: 6px;
}
.cadre__fait > span { display: block; color: var(--muted); font-size: .95rem; max-width: 32ch; }
@media (max-width: 700px) {
  .cadre__faits { grid-template-columns: 1fr; gap: 18px; }
  .cadre__fait > span { max-width: none; }
}

.mosaic { --gap: 12px; --tile: 190px; margin-top: 44px; }
.mosaic__club {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin: 46px 0 16px; padding-bottom: 12px; border-bottom: 1px solid var(--line);
  font-size: 1rem;
}
.mosaic__club:first-child { margin-top: 0; }
.mosaic__club .club-dot { align-self: center; }
.mosaic__club-nom { font-family: var(--font-body); font-weight: 600; font-size: .84rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink); }
.mosaic__club-lieu { font-family: var(--font-body); font-weight: 500; font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-left: auto; }

.mosaic__row { display: flex; flex-wrap: wrap; gap: var(--gap); margin-bottom: var(--gap); }
/* largeur ∝ ratio : les hauteurs d'une même ligne s'égalisent d'elles-mêmes */
.mosaic__item { flex: var(--r) 1 calc(var(--r) * var(--tile)); }

.gallery-item {
  position: relative; overflow: hidden; border-radius: var(--radius); cursor: pointer;
  padding: 0; border: 0; background: var(--photo-fond); display: block;
  /* La vignette est son propre conteneur de référence : c'est SA largeur qui
     décide si l'étiquette tient, pas celle de la fenêtre. Les vignettes n'ont
     pas la même largeur sur une même ligne (elle est proportionnelle au ratio
     de chaque photo), donc une règle en largeur d'écran ne pouvait pas suffire :
     elle réglait le problème à 390 px et le recréait à 460. */
  container-type: inline-size;
  /* Un <button> est centré par défaut dans le navigateur. Sur une vignette
     étroite, la légende se retrouvait centrée sur deux lignes, avec un mot
     seul en bas. Elle s'aligne à gauche comme tout le reste du site. */
  text-align: left;
}
.gallery-item img { width: 100%; height: auto; aspect-ratio: var(--r); object-fit: cover; display: block; transition: transform .55s cubic-bezier(.2, .7, .2, 1); }
.gallery-item:hover img { transform: scale(1.04); }
/* Le voile qui rend l'étiquette lisible. Il finissait à .55 d'opacité : sur les
   photos les plus claires (l'assiette, la salle de restaurant), l'étiquette crème
   ne montait qu'à 3,30:1 alors qu'il en faut 4,5. Le pied du dégradé passe à .78,
   le haut ne bouge pas : la photo garde sa lumière, seule la bande où se pose le
   texte s'assombrit. Mesuré sur les pixels rendus, les treize étiquettes passent
   le seuil. */
.gallery-item::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 48%, rgba(10, 10, 10, .78)); opacity: 0; transition: opacity .35s ease; }
.gallery-item:hover::after { opacity: 1; }
/* Le liseré de couleur qui marquait le club en bas de chaque vignette a sauté :
   les deux clubs sont maintenant séparés par un intertitre, l'information était
   répétée treize fois pour rien. */
.gallery-item__cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; pointer-events: none;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 16px 14px 14px; text-align: left;
  opacity: 0; transform: translateY(10px);
  transition: opacity .35s ease, transform .45s var(--ease-out);
}
.gallery-item:hover .gallery-item__cap, .gallery-item:focus-visible .gallery-item__cap { opacity: 1; transform: none; }
/* PLANCHER DE 11 PIXELS SUR LE TEXTE FONCTIONNEL.
   Une étiquette qui nomme une photo n'est pas de l'ornement : elle se lit. À
   10,24 px et en capitales espacées, elle demandait un effort à tout le monde,
   et devenait illisible pour une vue un peu basse. */
.gallery-item__tag {
  font-family: var(--font-body); font-weight: 500; font-size: .75rem; letter-spacing: .11em;
  text-transform: uppercase; color: var(--gold-soft); text-shadow: 0 1px 8px rgba(0, 0, 0, .6);
}
/* Sur mobile, pas de survol : la légende reste lisible en permanence */
@media (hover: none) {
  .gallery-item__cap { opacity: 1; transform: none; }
  .gallery-item::after { opacity: 1; }
}
/* Les filtres par club et par infrastructure ont été retirés avec la sélection :
   sur douze photos, la plupart des filtres n'auraient renvoyé qu'une image ou
   deux. Les deux clubs sont maintenant séparés par un intertitre, ce qui est à la
   fois plus lisible et une rangée de pastilles en moins. */

/* Écrans étroits : les lignes se recomposent toutes seules (deux photos par
   ligne environ), sans jamais rogner une image. */
@media (max-width: 760px) { .mosaic { --tile: 118px; --gap: 9px; } }
/* Sur téléphone, la légende reste affichée en permanence (pas de survol au
   doigt) et les vignettes les plus étroites tombent à 105 px : « Tournoi fluo »
   et « Restaurant » y étaient rognés en plein milieu d'un mot. On resserre le
   cadre et l'interlettrage plutôt que le corps, qui ne doit plus descendre
   sous 12 px. */
@media (max-width: 760px) {
  .gallery-item__cap { padding: 13px 12px 11px; }
  .gallery-item__tag { letter-spacing: .03em; }
}
/* En dessous de cette largeur, la plus longue étiquette (« Vue d'ensemble »)
   ne tient plus : elle se ferait couper en plein mot, et sur téléphone elle
   reste affichée en permanence, donc le défaut serait sous les yeux. On la
   retire plutôt que de la tronquer. La photo se suffit, et l'agrandissement
   en donne la description complète.
   C'est cette règle qui fait le travail, et elle seule : la première tentative
   grignotait le cadre de la légende pour gagner cinq pixels, ce qui collait le
   texte au bord de la photo sans même régler le problème à toutes les largeurs.
   Le cadre est donc revenu à une valeur confortable, et le seuil a monté
   d'autant. */
@container (max-width: 140px) {
  .gallery-item__cap { display: none; }
}
@media (max-width: 460px) { .mosaic { --tile: 96px; } }

/* Lightbox */
/* `visibility` bascule SANS DÉLAI à l'ouverture, et seulement à la fin du fondu
   à la fermeture. C'est le même motif que le menu mobile plus haut, et ici il
   n'est pas cosmétique : tant que la boîte est `visibility: hidden`, aucun de
   ses boutons ne peut recevoir le focus. Avec la transition sur `visibility`,
   le focus posé à l'ouverture retombait silencieusement sur la vignette, et la
   boîte s'ouvrait sans que le clavier y entre - ce que `aria-modal` promet
   pourtant à qui l'utilise. */
.lightbox { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: clamp(16px, 4vw, 48px); opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .35s ease, visibility 0s .35s; }
.lightbox.open { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .35s ease, visibility 0s 0s; }
.lightbox__backdrop { position: absolute; inset: 0; background: rgba(8, 8, 8, .9); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.lightbox__img { position: relative; z-index: 1; max-width: 100%; max-height: 86vh; border-radius: var(--radius); box-shadow: var(--shadow); object-fit: contain; transform: scale(.97); transition: transform .35s cubic-bezier(.2, .7, .2, 1); }
.lightbox.open .lightbox__img { transform: scale(1); }
.lightbox__btn { position: absolute; z-index: 2; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 50%; cursor: pointer; color: #fff; background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .35); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); transition: background .25s ease, border-color .25s ease, transform .25s ease; }
.lightbox__btn:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.lightbox__btn svg { width: 22px; height: 22px; }
.lightbox__close { top: 22px; right: 22px; font-size: 1.6rem; line-height: 1; }
.lightbox__prev { left: 18px; top: 50%; transform: translateY(-50%); }
.lightbox__next { right: 18px; top: 50%; transform: translateY(-50%); }
.lightbox__prev:hover, .lightbox__next:hover { transform: translateY(-50%) scale(1.06); }
.lightbox__counter { position: absolute; z-index: 2; bottom: 22px; left: 50%; transform: translateX(-50%); color: rgba(255, 255, 255, .85); font-size: .85rem; font-weight: 500; letter-spacing: .04em; }
body.lightbox-open { overflow: hidden; }

/* Équipements : une ligne de texte, pas huit pastilles à coche verte.
   L'information est la même, elle se lit plus vite et ne ressemble plus à un
   composant de bibliothèque. */
.equipements {
  margin-top: 34px; padding-top: 22px; border-top: 1px solid var(--line);
  max-width: 74ch; color: var(--muted); font-size: .98rem;
}
.equipements b { color: var(--ink); font-weight: 600; }

/* =========================================================
   OCCASIONS (autres événements)
   ========================================================= */
/* La liste en grand reste le parti pris de la section : c'est elle qu'on lit
   d'un coup d'œil. Elle se dédouble en deux colonnes, une par public, parce
   qu'une seule suite de mots ne disait pas qu'on reçoit AUSSI des familles :
   il fallait le déduire de la présence du mot « Communions » au milieu du reste.

   CE QUI A CHANGÉ LE 18/08. La liste était posée à plat sous un simple filet :
   dix mots empilés dans le vide, qui se lisaient comme un brouillon plutôt que
   comme une offre. Chaque public tient maintenant dans son propre panneau, et
   chaque occasion dans sa cellule. Le dégradé n'est pas là pour décorer : il
   s'efface vers la droite et s'allège en descendant, si bien que les dix
   cellules composent une seule nappe en diagonale. C'est elle qui fait tenir le
   bloc comme un objet dessiné, au lieu de deux listes voisines. */
.occasions { background: var(--paper-2); }
.occasions__inner { max-width: 68rem; }
.occasions__head { max-width: 46rem; }

.occasions__duo {
  margin-top: clamp(34px, 4.5vw, 56px);
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(20px, 2.6vw, 32px);
}

/* Une teinte par public, déclarée UNE fois en tête de panneau : tout le dégradé
   en descend, en-tête comme cellules. Repasser les deux colonnes dans le même
   doré tient donc en une ligne, sans toucher au reste.
   Le doré est celui du logo Wel, le bordeaux celui du Midi. Ils ne désignent pas
   un club ici : la section ne nomme plus aucun des deux, elle sépare deux
   publics. Si le raccourci venait à se faire dans la tête d'un visiteur, il
   suffit de retirer la ligne .occasion--proches ci-dessous. */
.occasion {
  --teinte: var(--gold);
  --densite: 0%;
  /* LE RETRAIT INTÉRIEUR EST CELUI DE LA CARTE DE FORMULAIRE.
     Le texte d'une cellule ouvre une colonne de plus dans la page, à
     (bord du panneau + 1 px de bordure + ce retrait). Posée au jugé, cette
     colonne tombe à trois ou quatre pixels d'une colonne déjà en place : l'œil
     n'y lit plus un retrait assumé mais un alignement raté, et l'audit
     typographique le remonte en bloquant. Un clamp en vw arbitraire (21,5 px à
     1024) mettait ainsi le texte à 2 px de la colonne du hero.
     La valeur n'est donc pas choisie, elle est REPRISE : c'est exactement celle
     de .form, la carte de référence du site, qui part du même bord de conteneur.
     Les deux colonnes intérieures coïncident alors au centième à toute largeur
     (47,00 px à 390, 57,72 px à 768, 67,00 px à 1024) au lieu de se frôler.
     Si .form change de padding, celui-ci doit suivre, et l'audit être relancé. */
  --gouttiere: clamp(26px, 4vw, 40px);
  display: flex; flex-direction: column;
  background: var(--paper-3);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.occasion--proches { --teinte: var(--midi); }

/* L'en-tête porte le dégradé le plus dense de la colonne. Sa densité est
   plafonnée par le CONTRASTE, pas par le goût : au-delà de 18 %, le doré foncé
   du texte passe sous 4,5:1 sur son propre fond. Le bordeaux, bien plus sombre,
   est descendu à 13 % pour peser optiquement autant que le doré à 18 %. */
.occasion__titre {
  font-family: var(--font-body); font-weight: 500; font-size: .75rem;
  letter-spacing: .15em; text-transform: uppercase; color: var(--gold-deep);
  padding: 15px var(--gouttiere);
  border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(102deg,
      color-mix(in srgb, var(--teinte) 18%, transparent) 0%,
      color-mix(in srgb, var(--teinte) 7%, transparent) 58%,
      transparent 100%);
}
.occasion--proches .occasion__titre {
  color: var(--midi);
  background: linear-gradient(102deg,
      color-mix(in srgb, var(--teinte) 13%, transparent) 0%,
      color-mix(in srgb, var(--teinte) 5%, transparent) 58%,
      transparent 100%);
}

/* Une occasion par ligne. Les mots étaient posés à la suite, séparés d'un point
   médian : dès que la liste se repliait, ce point restait pendu en bout de ligne.
   En cellules, il n'y a plus de séparateur à placer, et chaque occasion se lit
   pour elle-même, ce qui est exactement ce qu'on cherche ici. */
.occasions__liste {
  list-style: none; margin: 0; padding: 0;
  font-family: var(--font-display); font-weight: 500;
  /* Un cran plus bas qu'avant : la liste tient désormais dans une demi-largeur,
     et deux blocs de la force du titre se seraient disputé la section. */
  font-size: clamp(1.22rem, 1.95vw, 1.6rem); line-height: 1.32;
  color: var(--ink); letter-spacing: -.02em;
}
.occasions__liste li {
  padding: 13px var(--gouttiere);
  border-bottom: 1px solid var(--line-soft);
  /* Le dégradé s'arrête aux trois quarts : le blanc du panneau revient toujours
     à droite, sinon les cellules deviennent des bandes et le tableau, un damier.
     Un navigateur sans color-mix (avant 2023) ne peint rien : il perd la nappe,
     il garde le tableau. */
  background: linear-gradient(90deg,
      color-mix(in srgb, var(--teinte) var(--densite), transparent) 0%,
      transparent 74%);
}
.occasions__liste li:nth-child(1) { --densite: 14%; }
.occasions__liste li:nth-child(2) { --densite: 11%; }
.occasions__liste li:nth-child(3) { --densite: 8%; }
.occasions__liste li:nth-child(4) { --densite: 5%; }
.occasions__liste li:nth-child(5) { --densite: 3%; }
/* Le bordeaux est deux fois plus sombre que le doré à densité égale : sans ce
   rattrapage, la colonne de droite écrase celle de gauche. */
.occasion--proches .occasions__liste li:nth-child(1) { --densite: 10%; }
.occasion--proches .occasions__liste li:nth-child(2) { --densite: 8%; }
.occasion--proches .occasions__liste li:nth-child(3) { --densite: 6%; }
.occasion--proches .occasions__liste li:nth-child(4) { --densite: 4%; }
.occasion--proches .occasions__liste li:nth-child(5) { --densite: 2%; }

/* Le paragraphe suit sa liste, sans être poussé au bas du panneau. Un
   margin-top:auto tenait là, hérité de la mise en page à plat : il alignait les
   deux pieds sur la même ligne, mais creusait un trou d'une ligne entière sous la
   colonne au texte le plus court. Le vide se range maintenant sous le
   paragraphe, où il ne se voit pas, plutôt qu'au milieu du panneau. */
.occasion__texte {
  padding: 17px var(--gouttiere) 22px;
  max-width: 46ch; color: var(--muted); font-size: 1rem;
}

/* Le zoom du hero s'arrête dès qu'il sort de l'écran */
.hero.is-paused .hero__half-img { animation-play-state: paused; }

/* =========================================================
   CTA SOMBRE (avant contact)
   ========================================================= */
/* La nappe de particules et le halo qui suivait le curseur ont été retirés :
   deux composants de catalogue, coûteux (ils tournaient même hors écran) et
   interchangeables d'un site à l'autre. Reste un fond sombre et net. */
/* Bande d'appel : titre à gauche, boutons à droite, sur une même ligne de base.
   Plus de bloc centré titre/sous-titre/boutons empilés. */
.cta-band { text-align: left; overflow: hidden; background: var(--ink-3); }
.cta-band__inner {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(28px, 5vw, 70px); align-items: end;
}
.cta-band .section-title { color: #fff; font-size: clamp(1.92rem, 3.5vw, 2.85rem); margin-bottom: 0; max-width: 22ch; }
.cta-band .kicker { color: var(--gold-soft); margin-bottom: 14px; }
.cta-band__btns { display: flex; gap: 22px; justify-content: flex-start; align-items: center; flex-wrap: wrap; }

/* =========================================================
   CTA MINIMALISTE (port du composant call-to-action-1, 21st.dev)
   Bloc épuré aligné à gauche : titre + sous-titre équilibré + bouton + lien fléché.
   ========================================================= */
.cta-min { background: var(--paper-2); padding-top: 0; }
.cta-min > .container { border-top: 1px solid var(--line); padding-top: clamp(44px, 5.2vw, 72px); }
/* La bande n'occupait que sa gauche. Le calendrier prend la droite ; le texte
   garde exactement la largeur de lecture qu'il avait. */
.cta-min__inner {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 3fr);
  gap: clamp(24px, 5vw, 56px); align-items: center;
}
.cta-min__texte { max-width: 60rem; }
.cta-min .section-title { text-align: left; margin-bottom: 0; }
.cta-min__sub { margin-top: 14px; max-width: 55ch; font-size: clamp(1.1rem, 1.8vw, 1.4rem); color: var(--muted); text-wrap: balance; }
.cta-min__actions { display: flex; align-items: center; gap: 22px; margin-top: 32px; flex-wrap: wrap; }
.btn-link { display: inline-flex; align-items: center; gap: 7px; position: relative; font-family: var(--font-body); font-weight: 500; font-size: .875rem; color: var(--ink); padding: 4px 0; }
/* Le lien fléché ne fait que 30 px de haut, et il ne peut pas grandir : son
   soulignement doré est calé sur le bas du texte, un padding le décrocherait.
   On agrandit donc la ZONE SENSIBLE sans toucher au dessin - une plaque
   invisible de 44 px centrée sur le lien, qui reçoit le doigt à sa place. */
.btn-link::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 44px; transform: translateY(-50%);
}
.btn-link .arrow { transition: transform .25s ease; }
.btn-link:hover .arrow { transform: translateX(4px); }
.btn-link::after { content: ""; position: absolute; left: 0; bottom: -1px; width: 0; height: 1.5px; background: var(--gold); transition: width .28s ease; }
.btn-link:hover::after { width: 100%; }
/* Variante claire (sur fonds sombres : hero, bande CTA) */
.btn-link--light { color: #fff; }
.btn-link--light::after { background: var(--gold-soft); }

/* =========================================================
   CONTACT (formulaire devis + infos)
   ========================================================= */
.contact { background: var(--paper); }
.contact__head { max-width: 56ch; }
.contact__head .lead { margin-top: 14px; }
.contact-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(36px, 5vw, 64px); margin-top: 46px; align-items: start; }
.form { background: var(--paper-3); border: 1px solid var(--line-soft); border-radius: var(--radius-lg); padding: clamp(26px, 4vw, 40px); box-shadow: var(--shadow-sm); }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* Téléphone, nombre de personnes et date : trois champs courts, une seule ligne.
   Le choix du club récupère la largeur entière, où ses intitulés tiennent enfin.
   La colonne du milieu est un peu plus large : « Nombre de personnes » est le
   seul libellé du formulaire qui déborderait d'un tiers, et un libellé qui
   passe sur deux lignes décale son champ, donc désaligne toute la rangée.
   `align-items: end` est la ceinture : si la fenêtre rétrécit assez pour que le
   libellé se coupe quand même, ce sont les CHAMPS qui restent alignés. */
.form__row--3 { grid-template-columns: 1fr 1.22fr 1fr; align-items: end; }
/* Les trois libellés occupent la même hauteur, qu'ils tiennent sur une ligne ou
   sur deux : les libellés démarrent tous au même niveau, les champs finissent
   tous au même niveau. Sans ça, « Nombre de personnes » se coupe en deux et
   fait descendre son champ tout seul - le défaut d'alignement se voit
   immédiatement, et c'est ce qui fait « fait à la va-vite ». */
.form__row--3 .field label { line-height: 1.3; min-height: 2.6em; }
.field { margin-bottom: 18px; }
.field label { display: block; font-size: .78rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--gold-deep); margin-bottom: 8px; }
/* Deux champs sur sept sont obligatoires. `required` le disait aux lecteurs
   d'écran, rien ne le montrait à l'œil : on ne l'apprenait qu'en se faisant
   refuser l'envoi. La marque est annoncée EN TÊTE, pas en légende de bas de
   page : une convention qu'on lit après le formulaire n'aide personne. */
.form__legende { font-size: .78rem; color: var(--muted); margin-bottom: 20px; }
.req { color: var(--gold-deep); font-weight: 600; }
.field input, .field select, .field textarea {
  width: 100%; font-family: var(--font-body); font-size: 1rem; color: var(--ink);
  background: var(--paper); border: 1.5px solid var(--line-soft); border-radius: 12px;
  padding: 13px 15px; transition: border-color .25s ease, box-shadow .25s ease, background .25s ease;
}
.field textarea { resize: vertical; min-height: 120px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 4px rgba(192, 144, 32, .14); background: #fff; }
/* Le texte indicatif d'un champ est du texte comme un autre : à #ACACAC il
   tombait à 2,27:1, illisible pour qui a une vue basse ou un écran au soleil. */
.field input::placeholder, .field textarea::placeholder { color: var(--muted); }
.form .btn { width: 100%; margin-top: 6px; }
/* Aligné à gauche, comme tout le reste : ce bloc fait deux à cinq lignes selon
   la largeur, et un paragraphe de plusieurs lignes n'est jamais centré. */
.form__hint { font-size: .82rem; color: var(--muted); margin-top: 14px; text-align: left; }
.form__hint a { color: var(--body); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line); }
.form__hint a:hover { color: var(--gold-deep); text-decoration-color: var(--gold); }
.form__rgpd { display: inline-block; margin-top: 8px; font-size: .76rem; color: var(--muted); }

/* Champ appât anti-robots : hors écran, jamais atteignable au clavier */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Champ en erreur */
.field--error input, .field--error select, .field--error textarea { border-color: var(--erreur); background: var(--erreur-fond); }
.field--error input:focus, .field--error select:focus, .field--error textarea:focus { border-color: var(--erreur); box-shadow: 0 0 0 4px rgba(179, 38, 30, .12); }
.field--error label { color: var(--erreur); }
.field__error { margin-top: 7px; font-size: .8rem; font-weight: 500; color: var(--erreur); }
.field__error:empty { display: none; }

/* Message de retour après envoi */
.form__status { margin-top: 14px; font-size: .9rem; font-weight: 500; text-align: left; }
/* La région aria-live doit exister dans l'arbre d'accessibilité AVANT le premier
   envoi. En `display: none`, elle apparaissait et recevait son texte dans le même
   cycle : c'est exactement le cas où NVDA et VoiceOver ratent l'annonce. Elle
   reste donc présente, sans occuper la moindre place tant qu'elle est vide. */
.form__status:empty { display: block; margin: 0; padding: 0; min-height: 0; }
.form__status--ok {
  color: var(--succes); background: var(--succes-fond); border: 1px solid rgba(31, 107, 59, .24);
  border-radius: 12px; padding: 14px 18px; text-align: left;
}
.form__status--erreur {
  color: var(--erreur); background: var(--erreur-fond); border: 1px solid rgba(179, 38, 30, .24);
  border-radius: 12px; padding: 14px 18px; text-align: left;
}

/* Pendant l'envoi */
.form.is-sending { opacity: .75; }
.form.is-sending .form__submit { cursor: progress; }
.form__submit[disabled] { opacity: .7; }
.form.is-sending .form__submit .arrow { animation: envoiFleche 1s ease-in-out infinite; }
@keyframes envoiFleche { 0%, 100% { transform: translateX(0); opacity: .5; } 50% { transform: translateX(5px); opacity: 1; } }

.contact-aside { display: flex; flex-direction: column; gap: 16px; }
.info-card { background: var(--paper-3); border: 1px solid var(--line-soft); border-radius: var(--radius-lg); padding: 26px 26px; }
.info-card h3 { font-size: 1.62rem; margin-bottom: 16px; display: flex; align-items: center; gap: 10px; }
.info-card h3 svg { width: 22px; height: 22px; color: var(--gold); }
/* Cartes par club : pastille de couleur (doré Wel / bordeaux Midi) */
.info-card__club { font-size: 1.5rem; }
.club-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.club-dot--wel { background: var(--gold); }
.club-dot--midi { background: var(--midi); }
.info-card--phone { padding-top: 16px; padding-bottom: 16px; }
.info-card--phone .info-line { padding: 0; border-bottom: 0; align-items: center; }
.info-line { display: flex; gap: 13px; padding: 11px 0; border-bottom: 1px solid var(--line-soft); align-items: flex-start; }
.info-line:last-child { border-bottom: 0; }
.info-line svg { width: 19px; height: 19px; color: var(--gold); flex-shrink: 0; margin-top: 4px; }
.info-line span { color: var(--body); font-size: .96rem; }
.info-line strong { font-weight: 600; color: var(--ink); }
/* CIBLES TACTILES DES FICHES DE CONTACT.
   L'adresse mail et le numéro sont ce qu'on cherche à toucher en premier sur un
   téléphone, et c'étaient les cibles les plus courtes de la page : 16 px de haut
   pour le mail, 30 px pour le téléphone. Le lien devient un bloc en ligne dont
   le retrait vertical porte la hauteur touchable à 44 px, sans déplacer le texte
   d'un pixel (le retrait est compensé par une marge négative). */
.info-line a {
  color: var(--body);
  display: inline-block;
  padding-block: 12px;
  margin-block: -12px;
}
.info-line a:hover { color: var(--gold-deep); }
/* Cartes : rien n'est chargé tant que personne ne clique. */
.maps { display: flex; flex-direction: column; gap: 12px; }
/* Une seule carte visuelle par club : le bouton d'affichage et le lien
   d'itinéraire vivent dans le même cadre. */
.map-slot {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px 12px 12px; border-radius: var(--radius-lg);
  background: var(--paper-3); border: 1px solid var(--line-soft);
  transition: border-color .25s ease, background .25s ease;
}
.map-slot:hover { border-color: var(--gold); background: var(--paper-4); }
/* Une fois la carte affichée, le cadre s'efface au profit de l'iframe */
.map-slot.is-loaded { display: block; padding: 0; overflow: hidden; border-color: var(--line); }
.map-slot.is-loaded .map-itin { display: block; padding: 11px 16px; text-align: right; }
.map-load {
  display: flex; align-items: center; gap: 13px; flex: 1 1 auto; text-align: left; cursor: pointer;
  padding: 4px; background: none; border: 0; color: var(--body);
  font-family: var(--font-body); font-size: .9rem; line-height: 1.45;
}
.map-load__pin { flex-shrink: 0; display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; background: rgba(192, 144, 32, .1); color: var(--gold-deep); }
.map-load__pin svg { width: 19px; height: 19px; }
.map-load__txt b { color: var(--ink); font-weight: 600; }
.map-load__cta { color: var(--gold-deep); font-weight: 500; font-size: .8rem; letter-spacing: .02em; }
/* 69 × 20 px, c'était sous le minimum de 24 px de haut. Ici le padding ne gêne
   rien : le cadre a la place, et le lien s'aligne toujours sur le bouton. */
.map-itin { flex-shrink: 0; font-size: .8rem; font-weight: 500; color: var(--muted); white-space: nowrap; padding: 12px 2px; }
.map-itin:hover { color: var(--gold-deep); }
.map-itin .arrow { transition: transform .25s ease; display: inline-block; }
.map-itin:hover .arrow { transform: translateX(3px); }
.map-wrap { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); border: 1px solid var(--line); }
.map-wrap iframe { width: 100%; height: 210px; border: 0; display: block; }

/* =========================================================
   FOOTER
   ========================================================= */
.footer { background: var(--ink-3); color: rgba(251, 250, 246, .7); padding: 74px 0 30px; border-top: 1px solid var(--line); }
.footer__top { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 44px; }
.footer__about .brand--footer { gap: 12px; }
.footer__about .brand--footer img { height: 25px; width: auto; display: block; }
.footer__about .brand--footer .brand__wel { height: 27px; }
.footer__about .brand--footer img[src*="midi"] { height: 22px; }
.brand__sep--footer { height: 21px; background: var(--line-on-dark); }
.footer__contact h4:not(:first-child) { margin-top: 24px; }
.footer__about p { margin-top: 18px; font-size: .94rem; max-width: 340px; }
.footer h4 { font-family: var(--font-body); font-weight: 500; font-size: .76rem; letter-spacing: .14em; text-transform: uppercase; color: var(--gold-soft); margin-bottom: 18px; }
.footer__links a { display: block; padding: 11px 0; font-size: .95rem; transition: color .2s ease; }
.footer__links a:hover { color: var(--cream); }
.footer__contact p { font-size: .95rem; padding: 5px 0; }
.footer__contact a:hover { color: var(--gold-soft); }
.social__label { display: block; margin-top: 20px; font-size: .75rem; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--gold-soft); }
.social { display: flex; gap: 12px; margin-top: 11px; }
/* 44 px, comme le burger et les boutons : deux pixels de plus que la version
   d'origine, invisibles à l'œil, décisifs au pouce. */
.social a { width: 44px; height: 44px; border-radius: 11px; display: grid; place-items: center; background: rgba(251, 250, 246, .06); border: 1px solid var(--line-on-dark); color: var(--cream); transition: background .25s ease, transform .25s ease, color .25s ease, border-color .25s ease; }
.social a:hover { background: var(--grad-gold); border-color: transparent; color: var(--ink); transform: translateY(-3px); }
.social a.social--fb:hover { background: var(--facebook); border-color: var(--facebook); color: #fff; }
.social svg { width: 19px; height: 19px; }
.footer__bottom { margin-top: 50px; padding-top: 26px; border-top: 1px solid var(--line-on-dark); display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; font-size: .84rem; color: var(--muted-2); }
.footer__bottom a { color: var(--gold-soft); }

/* =========================================================
   ÉLÉMENTS FLOTTANTS & BARRES
   ========================================================= */
.scroll-progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 300; pointer-events: none; }
.scroll-progress span {
  display: block; height: 100%; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold-bright));
}

/* Grain : la TEXTURE reste (elle donne la matière premium au papier blanc),
   mais l'animation permanente est retirée. Elle repeignait un calque plein écran
   en boucle, pour un effet que personne ne remarque consciemment. */
/* PLUS DE mix-blend-mode. C'était le poste le plus coûteux de la page : un calque
   plein écran, fixe, en fusion permanente, qui force le navigateur à recomposer
   TOUT ce qu'il y a dessous à chaque peinture - donc à chaque défilement, sur un
   Android d'entrée de gamme comme ailleurs. Pour une texture que personne ne
   remarque consciemment.
   La texture reste, elle se pose maintenant normalement : le bruit est désaturé
   dans le SVG (feColorMatrix), ce qui donne le même voile gris que la fusion
   produisait sur le papier blanc, sans le contexte de fusion. */
.grain {
  position: fixed; inset: 0; z-index: 90; pointer-events: none;
  opacity: .03;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* =========================================================
   FIL DE TERRAIN : la progression de lecture, en bord de page
   Sur grand écran, un trait doré au bord gauche se remplit pendant la lecture
   et une balle en marque la tête. Il remplace la barre du haut, qui est
   l'un des marqueurs les plus vus du web généré.
   ========================================================= */
.rail { display: none; }
@media (min-width: 1280px) {
  .rail {
    display: block; position: fixed; left: 34px; top: 16vh; bottom: 16vh; width: 1px;
    z-index: 88; pointer-events: none;
    /* Le rail non parcouru doit se VOIR : sinon on ne distingue pas ce qui
       reste à lire de ce qui est déjà passé, et le fil n'informe plus de rien. */
    background: linear-gradient(180deg, transparent, var(--line) 6%, var(--line) 94%, transparent);
  }
  /* Portion parcourue */
  .rail__line {
    position: absolute; inset: 0; transform-origin: 0 0;
    transform: scaleY(var(--progress, 0));
    background: linear-gradient(180deg, var(--gold-deep), var(--gold-bright));
  }
  .rail__ball {
    position: absolute; left: 50%; top: calc(var(--progress, 0) * 100%);
    width: 8px; height: 8px; margin-left: -4px; margin-top: -4px; border-radius: 50%;
    background: var(--gold); box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px rgba(192, 144, 32, .3);
  }

  /* --- Graduation : un repère par section, à l'endroit exact où elle commence.
     C'est ce qui manquait : le fil montrait un avancement, mais pas de quoi.
     Maintenant on lit d'un coup d'œil combien de sections restent, et laquelle
     on est en train de lire. --- */
  /* Le repère est un point d'ancrage sans dimension ; le trait visible vit dans
     son pseudo-élément. C'est ce qui permet de le faire grandir en `transform`
     (une seule composition) plutôt qu'en `width` + `margin-left` (deux
     recalculs de mise en page), à chaque changement de section pendant la
     lecture. Et le nom de section, lui, ne subit pas la mise à l'échelle. */
  .rail__etape { position: absolute; left: 50%; width: 0; height: 0; }
  .rail__etape::before {
    content: ""; position: absolute; left: -8.5px; top: -1px; width: 17px; height: 2px;
    background: var(--line); transform: scale(.53, .5); transform-origin: 50% 50%;
    transition: transform .35s var(--ease-out), background .35s ease;
  }
  .rail__etape.is-courant::before { transform: none; background: var(--gold); }
  /* Entre 1280 et 1400 px, la colonne de texte descend trop près du bord :
     on garde les repères, mais pas le nom, qui viendrait mordre sur le contenu. */
  .rail__nom { display: none; }

  /* La barre du haut disparaît : un seul repère de progression à la fois */
  .scroll-progress { display: none; }
}
/* À partir de 1400 px, la marge gauche est assez large : le nom de la section
   courante s'affiche le long du fil, écrit verticalement pour ne jamais
   empiéter sur la colonne de texte. */
@media (min-width: 1400px) {
  .rail__nom {
    /* 12,5 px : le repère n'a plus de largeur propre, son origine est le centre
       du fil. C'est l'écart qu'avait le nom quand il partait du bord du trait. */
    display: block; position: absolute; left: 12.5px; top: 10px;
    writing-mode: vertical-rl;
    font-family: var(--font-body); font-weight: 500; font-size: .75rem;
    letter-spacing: .12em; text-transform: uppercase; white-space: nowrap;
    color: var(--gold-deep);
    opacity: 0; transform: translateY(-6px);
    transition: opacity .4s ease, transform .4s var(--ease-out);
  }
  .rail__etape.is-courant .rail__nom { opacity: 1; transform: none; }
}
@media (min-width: 1280px) and (prefers-reduced-motion: reduce) {
  .rail__etape::before, .rail__nom { transition: none; }
}

/* =========================================================
   CROQUIS
   Les sections respiraient, mais dans le vide : de grandes plages blanches sans
   rien derrière. Deux réponses, toutes deux tirées du padel lui-même plutôt que
   d'une forme décorative interchangeable.

   1. Des dessins au trait (raquette, balle, plan du terrain), tracés à la main
      puis passés au filtre « crayon » qui fait trembler légèrement les lignes.
   2. Deux vraies photos de nos terrains, converties en croquis au crayon et
      posées très en retrait derrière le texte. Ce sont NOS terrains, pas une
      texture achetée.
   ========================================================= */
.defs-croquis { position: absolute; width: 0; height: 0; overflow: hidden; }

.croquis { display: block; overflow: visible; }
.croquis .trait {
  fill: none; stroke: var(--ink); stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.croquis .fin { stroke-width: 1.1; }
.croquis .moyen { stroke-width: 1.7; }
/* Le trait repassé : une deuxième passe légèrement décalée, comme quand on
   appuie une seconde fois sur un contour au crayon. */
.croquis .repasse { stroke-width: 1.1; opacity: .45; }
.croquis .dore { stroke: var(--gold); }

/* Les deux halls ferment la colonne de droite du concept, sous le carrousel.
   Largeur bornée : au-delà, le dessin s'étire et les traits fins se délavent. */
.croquis--duo { width: min(560px, 96%); margin-top: 34px; opacity: .6; }

/* La légende du croquis. Elle chuchote : le dessin porte déjà le message, le texte
   ne fait que le nommer. Alignée à gauche comme tout le reste, et calée sur le
   bord gauche du dessin. */
.duo__legende {
  margin-top: 14px;
  font-size: .95rem;
  color: var(--gold-deep);
  letter-spacing: .01em;
}

/* La balle fait l'aller-retour entre les deux clubs, sur la trajectoire dessinée.
   `transform-box: view-box` est indispensable : sans lui, les coordonnées de
   `offset-path` ne sont plus celles du viewBox et la balle part hors du dessin. */
.duo__balle { transform-box: view-box; offset-path: path("M184 60 Q 273 -8 362 68"); offset-rotate: 0deg; offset-distance: 50%; }
@media (prefers-reduced-motion: no-preference) {
  .duo__balle { animation: duo-echange 4.6s ease-in-out infinite alternate; }
}
@keyframes duo-echange { from { offset-distance: 0%; } to { offset-distance: 100%; } }
/* Rien ne tourne hors de l'écran : même règle que le hero. */
.croquis--duo.is-paused .duo__balle { animation-play-state: paused; }

/* La raquette ferme la colonne de gauche de « Pourquoi » */
.croquis--raquette { width: clamp(96px, 11vw, 132px); margin-top: 46px; opacity: .5; }
/* Le plan du terrain occupe le vide laissé par le titre calé à droite */
.croquis--terrain { width: min(340px, 42vw); opacity: .55; align-self: end; }
/* La balle accompagne le titre des formules. Assez grande pour se lire comme un
   dessin : en dessous de 120 px, elle passait pour un rond perdu dans la marge. */
/* Seule des croquis à monter au-dessus de .5 : c'est le seul qui porte une
   couleur, et le jaune du feutre passé sous une demi-opacité ne se voyait plus. */
.croquis--balle { width: clamp(104px, 12vw, 148px); opacity: .58; justify-self: end; align-self: center; }
/* Le couvert clôt le déroulé : posé à droite, sous l'étape « À table ». */
.croquis--table { width: clamp(88px, 9vw, 116px); opacity: .42; display: block; margin: 18px 8px 0 auto; }
/* Les verres ne sont plus seuls : le mot « Tchin-tchin ! » vit à côté d'eux, en
   HTML. C'est donc le bloc qui porte la place dans la grille, et le dessin qui
   remplit le bloc. Le retrait du haut réserve la ligne du mot. */
.verres-bloc {
  position: relative; justify-self: end; align-self: center;
  width: min(190px, 24vw); padding-top: 1.9em;
}
.croquis--verres { width: 100%; opacity: .45; }
.croquis--bulles { width: min(230px, 26vw); opacity: .5; justify-self: end; align-self: end; }
/* La poignée de main occupe la bande laissée libre sous les boutons du concept. */
.croquis--check { width: min(250px, 28vw); opacity: .45; margin-top: 30px; }
.croquis--calendrier { width: min(160px, 20vw); opacity: .5; justify-self: end; align-self: center; }
/* Les points de la bulle qui parle : pleins, sinon ils disparaissent à cette taille. */
.croquis .plein { fill: currentColor; stroke: none; color: var(--ink-soft); opacity: .8; }
/* Deux en-têtes qui n'occupaient que leur moitié gauche. Le croquis prend la droite,
   sans jamais rétrécir le texte : le titre garde sa colonne de lecture. */
.galerie__haut, .contact__haut {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(24px, 5vw, 56px); align-items: center;
}
.contact__haut { align-items: end; }

/* ---- Arrivée des croquis ----
   ON N'ANIME PAS LE TRACÉ. L'ancienne version posait `stroke-dasharray: 1` pour
   faire « se dessiner » les traits. Ça n'a jamais marché : sans `pathLength`, la
   valeur 1 vaut UNE unité utilisateur, donc des pointillés permanents ; et AVEC
   `pathLength="1"`, le motif de pointillés et la longueur du tracé ne se calculent
   plus dans le même repère à cause de `vector-effect: non-scaling-stroke` — les
   dessins sortaient en morceaux, verres et calendrier troués.
   Le croquis arrive donc entier : il monte, il apparaît, il se pose. */
@media (prefers-reduced-motion: no-preference) {
  .js .croquis.reveal { transform: translateY(22px) scale(.96); transform-origin: 50% 70%; }
  .js .croquis.reveal.in {
    transform: none;
    transition: opacity .8s ease, transform 1s var(--ease-out);
  }
}

/* =========================================================
   LES CROQUIS QUI JOUENT UN GESTE

   Quatre dessins bougent, et rien d'autre. Trois jouent UN geste, une fois,
   quand ils arrivent à l'écran, puis se reposent : le check des raquettes, la
   coche du calendrier, le tchin des verres. Ils se rejouent au survol, pour qui
   veut les revoir. Seule la balle tourne en continu, parce que tourner sur
   elle-même EST son sujet, et elle s'arrête dès qu'elle sort du champ.

   La règle de la maison : une animation guide, ou elle signe. Ces quatre-là
   signent. Elles montrent le geste que le dessin raconte, chacune une seule
   fois : ce qui tourne en boucle pour soi finit par se lire comme un
   chargement qui n'aboutit pas.

   Sous préférence de mouvement réduit, tout ce bloc n'existe pas : les dessins
   restent ce qu'ils étaient, étincelles allumées et coche déjà tracée.
   ========================================================= */

/* Le survol doit atteindre la BOÎTE du dessin, pas seulement ses traits : sans
   cela, un croquis fait de lignes de 1,1 px ne se rejoue qu'au pixel près, et
   personne ne le trouve. Firefox ne connaît pas `bounding-box` et laissera
   simplement tomber la déclaration : le survol y reste possible sur les traits,
   ce qui est une dégradation acceptable pour un geste de confort. */
.js [data-anime] { pointer-events: bounding-box; }

/* ---- LE CHOC : deux objets qui s'écartent, puis se retapent ----
   Le pivot est le bout du manche pour les raquettes, le pied pour les verres.
   Faire tourner autour du centre aurait donné une hélice ; autour du point
   d'appui, on obtient le geste du poignet. */
.choc { transform-box: view-box; }
.croquis--check .choc--g  { transform-origin: 66.9px 125.3px; }
.croquis--check .choc--d  { transform-origin: 173.1px 125.3px; }
.croquis--verres .choc--g { transform-origin: 37.8px 83px; }
.croquis--verres .choc--d { transform-origin: 112.2px 83px; }

/* On arme (l'objet s'écarte, lentement), on lâche (il revient, vite), on
   dépasse un peu, et l'oscillation s'éteint en trois retours de plus en plus
   courts. La détente est dans les courbes de vitesse, pas dans les angles :
   8 degrés suffisent quand le rythme est juste. */
@keyframes choc-gauche {
  0%   { transform: rotate(0deg);     animation-timing-function: cubic-bezier(.32, .05, .6, 1); }
  20%  { transform: rotate(-8deg);    animation-timing-function: cubic-bezier(.7, 0, .84, .3); }
  38%  { transform: rotate(2.4deg);   animation-timing-function: cubic-bezier(.2, .85, .35, 1); }
  54%  { transform: rotate(-2.8deg);  animation-timing-function: cubic-bezier(.3, .7, .4, 1); }
  70%  { transform: rotate(1deg); }
  86%  { transform: rotate(-.35deg); }
  100% { transform: rotate(0deg); }
}
@keyframes choc-droite {
  0%   { transform: rotate(0deg);     animation-timing-function: cubic-bezier(.32, .05, .6, 1); }
  20%  { transform: rotate(8deg);     animation-timing-function: cubic-bezier(.7, 0, .84, .3); }
  38%  { transform: rotate(-2.4deg);  animation-timing-function: cubic-bezier(.2, .85, .35, 1); }
  54%  { transform: rotate(2.8deg);   animation-timing-function: cubic-bezier(.3, .7, .4, 1); }
  70%  { transform: rotate(-1deg); }
  86%  { transform: rotate(.35deg); }
  100% { transform: rotate(0deg); }
}

/* Les étincelles ne préexistent pas au choc : elles naissent à l'instant du
   contact (38 % du geste), grossissent d'un souffle, et restent. Au repos,
   c'est-à-dire hors animation, elles sont simplement là : le dessin d'origine
   ne change pas pour qui ne verra jamais le mouvement. */
.etincelles { transform-box: view-box; }
.croquis--check .etincelles  { transform-origin: 120px 27px; }
.croquis--verres .etincelles { transform-origin: 75px 30px; }
@keyframes etincelles {
  0%, 30% { opacity: 0; transform: scale(.35); }
  40%     { opacity: 1; transform: scale(1.2); }
  58%     { opacity: .9; transform: scale(.97); }
  100%    { opacity: 1; transform: scale(1); }
}

/* ---- LA COCHE DU CALENDRIER ----
   Le trait se tire d'un bout à l'autre. Deux précautions, exactement celles qui
   manquaient à la tentative précédente (voir le bloc « Arrivée des croquis ») :
   `pathLength: 1` met le pointillé et la longueur du tracé dans le même repère,
   et le trait renonce ici à `non-scaling-stroke`, qui les remettait dans deux
   repères différents. Son épaisseur suit donc l'échelle du dessin : 2 unités
   rendent entre 1,6 et 2,3 px selon la largeur, l'écart ne se voit pas. */
.croquis .coche {
  stroke-width: 2; vector-effect: none;
  stroke-linecap: round; stroke-linejoin: round;
}
/* Le premier pour cent sert à éteindre le trait : un pointillé entièrement
   décalé garde son bout arrondi, et ce bout se voit comme un point posé dans
   la case avant même que la coche existe. */
@keyframes coche-trace {
  0%   { stroke-dashoffset: 1; opacity: 0; }
  1%   { stroke-dashoffset: 1; opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 1; }
}

/* ---- LE MOT DES VERRES ----
   Il arrive avec le choc, pas avant : c'est le bruit du verre, il ne peut pas
   précéder le contact. Posé de travers, comme on écrit dans la marge. */
.verres__tchin {
  position: absolute; top: 0; left: 2%;
  font-family: var(--font-display); font-weight: 500; font-size: clamp(1rem, 2.1vw, 1.28rem);
  letter-spacing: -.005em; line-height: 1; white-space: nowrap;
  color: var(--gold-deep); opacity: .78;
  transform: rotate(-5deg); transform-origin: left bottom;
}
@keyframes tchin-arrive {
  0%, 32% { opacity: 0; transform: rotate(-5deg) scale(.6) translateY(5px); }
  46%     { opacity: .78; transform: rotate(-5deg) scale(1.14) translateY(-2px); }
  62%     { transform: rotate(-5deg) scale(.98) translateY(0); }
  100%    { opacity: .78; transform: rotate(-5deg) scale(1) translateY(0); }
}

/* ---- LA BALLE QUI TOURNE ----
   Le jaune est celui de la charte, pas celui des balles de magasin : le doré du
   logo Wel est la seule couleur d'accent du site, et une balle fluo au milieu
   d'un dessin au crayon aurait sonné faux.

   Le feutre est une haleine de doré, pas un aplat. Trois valeurs ont été rendues
   côte à côte (.30, .16, .08) : à .30 la balle vire au sable et cesse d'être un
   croquis, à .08 elle ne dit plus rien. Ce sont les reflets qui portent le jaune,
   le feutre ne fait que les asseoir. */
.croquis .balle__feutre { fill: var(--gold-bright); opacity: .16; stroke: none; }
.croquis .balle__reflet path {
  fill: none; stroke: var(--gold-bright); stroke-width: 2;
  stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.balle__coutures { transform-box: view-box; transform-origin: 50px 50px; }
@keyframes balle-tourne { to { transform: rotate(360deg); } }

/* ---- MISE EN ROUTE ----
   `both` sert deux fois : il applique l'image de départ pendant le retard (les
   étincelles et le mot restent donc éteints le temps que le croquis monte), et
   il garde l'image d'arrivée après coup, qui est l'état de repos du dessin. */
@media (prefers-reduced-motion: no-preference) {
  /* ARMÉ : le geste va se jouer, donc ce qui doit NAÎTRE du choc n'existe pas
     encore. Sans cet état, les étincelles et le mot apparaîtraient avec le
     dessin (le fondu d'arrivée se déclenche plus tôt que le geste), puis
     s'éteindraient d'un coup au démarrage de l'animation : on verrait un
     clignotement. C'est le script lui-même qui pose la classe, et le filet de
     sécurité de fin de `main.js` qui la retire ; si le script ne tourne pas,
     rien n'est armé et rien n'est caché. */
  .js [data-anime].is-arme .etincelles { opacity: 0; }
  .js .croquis--verres.is-arme ~ .verres__tchin { opacity: 0; }
  .js .croquis--calendrier.is-arme .coche { stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; }

  .js [data-anime].is-anime .choc--g      { animation: choc-gauche 1.15s var(--retard, .55s) both; }
  .js [data-anime].is-anime .choc--d      { animation: choc-droite 1.15s var(--retard, .55s) both; }
  .js [data-anime].is-anime .etincelles   { animation: etincelles 1.15s var(--retard, .55s) both; }
  .js .croquis--calendrier.is-anime .coche {
    animation: coche-trace .55s cubic-bezier(.55, .02, .3, 1) var(--retard, .55s) both;
  }
  .js .croquis--verres.is-anime ~ .verres__tchin { animation: tchin-arrive 1.15s var(--retard, .55s) both; }

  /* Le check part plus tard : il attend que sa colonne ait fini de monter. */
  .croquis--check { --retard: .75s; }
  /* Porté par le BLOC et non par le dessin : le mot est le frère du SVG, pas
     son enfant, et une variable posée sur le dessin ne descendrait pas jusqu'à
     lui. Il arriverait alors 50 ms après le choc qu'il est censé nommer. */
  .verres-bloc, .croquis--calendrier { --retard: .5s; }

  /* La seule boucle de la page côté croquis. Lente : un tour prend 14 s, on ne
     la surprend jamais en train de tourner, on la retrouve ailleurs. */
  .js .croquis--balle .balle__coutures { animation: balle-tourne 14s linear infinite; }
  .croquis--balle.is-paused .balle__coutures { animation-play-state: paused; }
}

/* Deux mises en page à deux colonnes, pour loger le croquis à côté du titre */
.deroule__haut, .formules__haut {
  display: grid; gap: clamp(24px, 5vw, 64px); align-items: end;
  margin-bottom: 40px;
}
.deroule__haut { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
.formules__haut { grid-template-columns: minmax(0, 8fr) minmax(0, 3fr); align-items: center; }

/* --- Photos de terrain converties en croquis, posées en fond de section --- */
.pourquoi, .occasions { position: relative; overflow: hidden; }
.pourquoi::before, .occasions::before {
  content: ""; position: absolute; pointer-events: none; z-index: 0;
  background-repeat: no-repeat; background-size: contain;
  opacity: .15;
}
.pourquoi::before {
  background-image: url('../img/croquis/terrain-wel.webp');
  width: min(760px, 68vw); aspect-ratio: 3 / 2;
  right: -8%; bottom: -6%;
  -webkit-mask-image: linear-gradient(215deg, #000 20%, transparent 78%);
  mask-image: linear-gradient(215deg, #000 20%, transparent 78%);
}
/* Calé sur le bord droit et descendu : accroché en haut, le dessin était coupé
   net et ne se lisait plus comme un croquis, juste comme une salissure. */
.occasions::before {
  background-image: url('../img/croquis/terrain-midi.webp');
  width: min(760px, 66vw); aspect-ratio: 3 / 2;
  right: -6%; bottom: -18%;
  -webkit-mask-image: linear-gradient(230deg, #000 22%, transparent 80%);
  mask-image: linear-gradient(230deg, #000 22%, transparent 80%);
}
.pourquoi > .container, .occasions > .container { position: relative; z-index: 1; }

@media (max-width: 920px) {
  .deroule__haut, .formules__haut { grid-template-columns: 1fr; align-items: start; }
  /* En colonne unique, le plan du terrain passe SOUS le titre : au-dessus, il
     repousserait le texte sous la ligne de flottaison pour rien. */
  .croquis--terrain { order: 2; width: min(300px, 62vw); margin-top: 8px; }
  .croquis--balle { justify-self: start; margin-top: 4px; }
  .croquis--raquette { margin-top: 30px; }
  .pourquoi::before, .occasions::before { opacity: .1; width: 88vw; }
  /* En colonne unique, ces deux croquis passent sous leur titre, à gauche comme
     le texte. Le filet, lui, sort : au-dessus d'un formulaire déjà long sur
     mobile, il ne fait que retarder le premier champ. */
  .galerie__haut, .cta-min__inner { grid-template-columns: 1fr; }
  .verres-bloc { justify-self: start; width: min(150px, 40vw); margin-top: 10px; }
  .croquis--calendrier { justify-self: start; width: min(120px, 32vw); margin-top: 20px; }
  .croquis--check { width: min(200px, 52vw); margin-top: 24px; }
  .contact__haut { display: block; }
  /* Les bulles restent sur tablette, où la place ne manque pas : elles passent
     sous le titre, alignées à gauche comme le texte. Elles ne sortent que sur
     téléphone, où elles ne feraient que retarder le premier champ d'un
     formulaire déjà long. */
  .croquis--bulles { width: min(190px, 30vw); margin-top: 18px; }
  /* Les étapes restent sur mobile (seul l'échange sort) : le couvert les clôt
     toujours, mais aligné à gauche comme le texte, et plus discret. */
  .croquis--table { margin: 22px auto 0 0; width: min(84px, 22vw); }
}

/* Hero : entrée cinétique au chargement */
.js .hero__inner > * { opacity: 0; transform: translateY(28px); }
body.loaded .hero__inner > * { animation: heroIn 1s cubic-bezier(.2, .7, .2, 1) forwards; }
body.loaded .hero__inner > *:nth-child(1) { animation-delay: .15s; }
body.loaded .hero__inner > *:nth-child(2) { animation-delay: .30s; }
body.loaded .hero__inner > *:nth-child(3) { animation-delay: .45s; }
body.loaded .hero__inner > *:nth-child(4) { animation-delay: .60s; }
body.loaded .hero__inner > *:nth-child(5) { animation-delay: .72s; }
@keyframes heroIn { to { opacity: 1; transform: none; } }

/* =========================================================
   CHIFFRES EN TABLEAU D'AFFICHAGE
   Les chiffres basculent comme un panneau de score, au lieu du compteur
   qui monte, vu sur tous les sites vitrines. Vocabulaire sportif, pas décoratif.
   ========================================================= */
.odo { display: inline-flex; }
.odo__digit { display: inline-block; height: 1em; overflow: hidden; }
.odo__strip { display: block; transform: translateY(0); }
.odo__strip i { display: block; height: 1em; line-height: 1; font-style: normal; }
@media (prefers-reduced-motion: no-preference) {
  .odo__strip { transition: transform 1.15s cubic-bezier(.2, .85, .25, 1); }
}

/* CTA primaires. Le balayage lumineux en boucle (composant ShinyButton de magicui)
   a été retiré : il tournait en permanence sur huit boutons, y compris hors écran,
   et c'est l'un des effets qui font se ressembler tous les sites générés.
   Il ne reste qu'un balayage bref, DÉCLENCHÉ PAR LE SURVOL, qui accompagne le geste. */
@property --x {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 120%;
}
.btn-gold { position: relative; overflow: hidden; }
.btn-gold::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 1;
  --x: 120%;
  background: linear-gradient(-75deg,
    transparent calc(var(--x) - 12%),
    rgba(255, 255, 255, .3) var(--x),
    transparent calc(var(--x) + 12%));
  transition: --x .55s cubic-bezier(.3, .8, .3, 1);
}
.btn-gold:hover::after, .btn-gold:focus-visible::after { --x: -20%; }
.btn-gold:active { transform: translateY(-2px) scale(.97); }

/* Reveals directionnels */
.js .reveal { opacity: 0; transform: translateY(26px); transition: opacity .8s ease, transform .9s var(--ease-out); }
.js .reveal.in { opacity: 1; transform: none; }
.js .reveal.d1 { transition-delay: .12s; }
.js .reveal.d2 { transition-delay: .24s; }
.js .reveal.d3 { transition-delay: .36s; }
.js .reveal--left { opacity: 0; transform: translateX(-40px); }
.js .reveal--right { opacity: 0; transform: translateX(40px); }
.js .reveal--left.in, .js .reveal--right.in { opacity: 1; transform: none; }

/* Bouton d'appel flottant (bas gauche)
   ------------------------------------------------------------------
   IL LIT LE FOND QU'IL SURVOLE. Noir sur blanc, il était parfait sur les
   sections claires et purement invisible dès qu'une bande sombre passait
   dessous : la bannière, les chiffres, l'ardoise des formules, la bande
   d'appel et le pied de page, soit un bon tiers de la hauteur de la page.
   Un bouton en position fixe ne peut pas savoir en CSS ce qui défile
   derrière lui : c'est le script qui mesure, à chaque image, quel bloc se
   trouve sous la pastille, et qui pose la classe `sur-sombre`.

   L'inversion n'invente rien : crème sur noir, c'est déjà ce que font les
   boutons principaux du site sur ces mêmes fonds (bannière, ardoise, bande
   d'appel). Les quatre couleurs du bouton passent donc par des variables,
   et une seule règle les échange. Le changement se fait en fondu, pour que
   ça se lise comme un parti pris et non comme un défaut d'affichage. */
.call-fab {
  --fab-fond: var(--ink);
  --fab-encre: var(--cream);
  /* Le liseré intérieur ne se voit pas sur fond clair, où l'ombre portée fait
     déjà le travail. Il sert au passage d'une bande à l'autre : le temps du
     fondu, le disque chevauche les deux fonds, et sans lui la moitié qui est
     du côté de sa propre couleur se dissout. */
  --fab-ombre: 0 12px 30px rgba(0, 0, 0, .28), inset 0 0 0 1px rgba(247, 247, 245, .18);
  --fab-halo: rgba(14, 14, 14, .35);
  --fab-halo-nul: rgba(14, 14, 14, 0);

  position: fixed; left: 22px; bottom: 26px; z-index: 95;
  display: inline-flex; align-items: center; height: 58px; width: 58px;
  border-radius: 50px; overflow: hidden; white-space: nowrap;
  background: var(--fab-fond); color: var(--fab-encre);
  box-shadow: var(--fab-ombre);
  transition: width .38s cubic-bezier(.2, .7, .2, 1), transform .25s ease, box-shadow .25s ease;
}
/* SUR FOND SOMBRE. L'ombre portée noire ne sépare plus rien sur du noir : elle
   s'efface au profit d'un liseré intérieur très fin, qui pose le disque sans
   l'alourdir, et d'une ombre plus profonde pour garder du relief. */
.call-fab.sur-sombre {
  --fab-fond: var(--cream);
  --fab-encre: var(--ink);
  --fab-ombre: 0 14px 34px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(14, 14, 14, .1);
  --fab-halo: rgba(247, 247, 245, .34);
  --fab-halo-nul: rgba(247, 247, 245, 0);
}
.call-fab__icon { width: 58px; height: 58px; flex-shrink: 0; display: grid; place-items: center; }
.call-fab__icon svg { width: 23px; height: 23px; }
/* Le libellé s'ouvre avec le bouton au lieu de rester déployé sous un
   overflow: hidden : replié, le contenu débordait de 82 px en permanence. */
.call-fab__label {
  font-family: var(--font-body); font-weight: 500; font-size: .96rem; letter-spacing: 0;
  max-width: 0; padding-right: 0; overflow: hidden; opacity: 0;
  transition: max-width .38s cubic-bezier(.2, .7, .2, 1), padding-right .38s cubic-bezier(.2, .7, .2, 1), opacity .25s ease;
}
.call-fab:hover { width: 180px; transform: translateY(-2px); }
.call-fab:hover .call-fab__label { max-width: 140px; padding-right: 24px; opacity: 1; }
.call-fab::after {
  content: ""; position: absolute; inset: 0; border-radius: 50px; pointer-events: none;
  box-shadow: 0 0 0 0 var(--fab-halo); animation: callpulse 2.6s ease-out infinite;
}
@keyframes callpulse {
  0% { box-shadow: 0 0 0 0 var(--fab-halo); }
  70% { box-shadow: 0 0 0 16px var(--fab-halo-nul); }
  100% { box-shadow: 0 0 0 0 var(--fab-halo-nul); }
}

/* Bouton "remonter" flottant (droite, mi-hauteur) */
.to-top {
  position: fixed; right: 22px; top: 50%; z-index: 90;
  width: 32px; height: 50px; border: 2px solid var(--gold); border-radius: 16px;
  background: rgba(251, 250, 246, .7); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none;
  transform: translateY(-50%) translateX(16px);
  transition: opacity .35s ease, transform .35s ease, border-color .25s ease;
}
.to-top::before { content: ""; position: absolute; inset: -8px; border-radius: 24px; }
.to-top.is-visible { opacity: 1; pointer-events: auto; transform: translateY(-50%) translateX(0); }
.to-top:hover { border-color: var(--gold-deep); }
/* Le chevron ne clignote plus. Il était animé en boucle infinie avec `opacity: 0`
   à 0 % ET à 100 % du cycle : un tiers du temps, le bouton se lisait comme une
   pastille vide, donc comme un défaut de rendu. Le mouvement n'aidait personne à
   comprendre que ça remonte. Il reste posé, net, et ne monte qu'au survol, en
   `transform` (pas en `bottom`, qui recalculait la mise en page à chaque image). */
.to-top::after {
  content: ""; position: absolute; left: 50%; bottom: 16px; width: 8px; height: 8px;
  border-left: 2px solid var(--gold-deep); border-top: 2px solid var(--gold-deep);
  transform: translateX(-50%) translateY(0) rotate(45deg);
  transition: transform .3s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .to-top:hover::after { transform: translateX(-50%) translateY(-5px) rotate(45deg); }
}

/* Masquage des flottants quand le menu mobile est ouvert */
body.nav-open .call-fab, body.nav-open .to-top {
  opacity: 0 !important; visibility: hidden !important; pointer-events: none !important;
}
/* MÊME EFFACEMENT SUR LES QUATRE ZONES QUI SE MANIPULENT AU DOIGT.
   Sur téléphone, les deux pastilles occupent les coins bas de l'écran, et ce
   qu'on y touche est pleine largeur : leurs extrémités passaient dessous.
   Recouvrement mesuré : 19 x 44 px sur « Envoyer ma demande », 19 x 51 px sur un
   champ du formulaire à 360 px. Le doigt visait le devis et appelait le club.

   Les zones concernées sont listées par le script (`#devis-form, .mosaic,
   footer, .carousel`), qui pose `cta-en-vue`. Ce n'est PAS « dès qu'un bouton
   d'action est à l'écran » : une première version faisait cela, et le raccourci
   disparaissait sur quinze écrans sur vingt. Sur un bouton pleine largeur, une
   extrémité recouverte sur 19 px laisse plus de 300 px à toucher. La règle a été
   resserrée aux quatre endroits où le recouvrement empêche vraiment d'agir, et
   la pastille reste visible sur douze écrans sur vingt.
   Le seuil suit celui du menu mobile (920 px) : au-delà, rien n'est pleine
   largeur et il n'y a plus de recouvrement. */
@media (max-width: 920px) {
  body.cta-en-vue .call-fab, body.cta-en-vue .to-top {
    opacity: 0; visibility: hidden; pointer-events: none;
  }
}
.call-fab, .to-top { transition: opacity .25s ease, visibility .25s ease; }
.call-fab {
  transition: width .38s cubic-bezier(.2, .7, .2, 1), transform .25s ease,
              box-shadow .4s ease, opacity .25s ease, visibility .25s ease,
              background-color .4s ease, color .4s ease;
}

@media (hover: none) {
  .grain { opacity: .028; }
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 1080px) {
  .stats__inner { grid-template-columns: 1fr; gap: 30px; align-items: start; }
  .cta-band__inner { grid-template-columns: 1fr; gap: 30px; align-items: start; }
}
/* Premier resserrement. La barre porte SIX entrées depuis l'ajout des
   références : on resserre les écarts au lieu de laisser la marque se faire
   écraser.
   Seuil remonté de 1120 à 1155 px le 2026-08-18, pour la même raison que le
   suivant : la marque a gagné 55 px en portant le nom « Wel Padel » en toutes
   lettres, et le menu venait toucher le logo du Midi dès 1150 px. */
@media (max-width: 1155px) {
  .nav { gap: 20px; }
  .nav__links { gap: 17px; }
}
/* Sous 1105 px, resserrer ne suffit plus : à six entrées, le bouton de devis
   sortait de l'écran. La pastille Facebook s'efface donc ici, et elle seule :
   le lien reste au pied de page, alors que la pastille GPS, elle, mène à un
   contenu qu'on ne trouve nulle part ailleurs dans la barre.
   Seuil remonté de 1080 à 1105 px le 2026-08-18 : la marque porte désormais le
   nom « Wel Padel » en toutes lettres et fait 55 px de plus, si bien que le menu
   touchait le logo du Midi dès 1085 px. Mesuré : plus aucun contact de 925 à
   1512 px. */
@media (max-width: 1105px) {
  .nav__fb { display: none; }
  .nav { gap: 16px; }
  .nav__links { gap: 14px; }
  .nav__links a { font-size: .85rem; }
}
/* Dernier palier avant le menu déroulant : les liens se resserrent encore, pour
   qu'il reste de l'air entre la marque et le premier d'entre eux. */
@media (max-width: 1010px) {
  .nav { gap: 13px; }
  .nav__links { gap: 10px; }
  .nav__links a { font-size: .82rem; }
  .nav .btn { padding: 12px 14px; font-size: .82rem; }
}
@media (max-width: 1000px) {
  .footer__top { grid-template-columns: 1fr 1fr; }
  .footer__about { grid-column: 1 / -1; }
  .stats__grid { grid-template-columns: repeat(2, 1fr); gap: 30px 20px; }
}
/* Passage au menu déroulant. Le seuil était à 920 px du temps des cinq entrées
   et du monogramme carré ; à six entrées et avec la marque nommée en toutes
   lettres, la barre déborde dès 941 px, même resserrée au maximum. Les règles
   de mise en page, elles, restent au seuil de 920 px : c'est la barre qui
   bascule plus tôt, pas la page. */
@media (max-width: 945px) {
  .nav__links { display: none; }
  .nav .btn, .nav__fb, .nav__gps { display: none; }
  .burger { display: flex; }
}
@media (max-width: 920px) {
  .split { grid-template-columns: 1fr; }
  .concept .split__media { order: -1; margin-bottom: 14px; }
  .pourquoi__inner { grid-template-columns: 1fr; gap: 34px; }
  /* La trajectoire de balle disparaît : sans elle, plus de décalage à compenser */
  .steps { grid-template-columns: 1fr; gap: 28px; }
  .step--haut { margin-top: 0; }
  .deroule__head { max-width: none; margin-left: 0; text-align: left; }
  .deroule__head .lead { text-align: left; margin-left: 0; }
  .contact-grid { grid-template-columns: minmax(0, 1fr); }
  .ardoise { grid-template-columns: 1fr; gap: 34px; }
  .ardoise__col + .ardoise__col::before { left: 0; right: 0; top: -17px; bottom: auto; width: auto; height: 1px; }
  /* Les deux publics s'empilent, chacun gardant son panneau et son dégradé. */
  .occasions__duo { grid-template-columns: 1fr; gap: 22px; }
}
@media (max-width: 760px) {
  .stats__grid { grid-template-columns: 1fr 1fr; gap: 26px 18px; }
}
/* Hero mobile : le diptyque passe en split horizontal (Wel en haut, Midi en bas) */
@media (max-width: 700px) {
  .hero__half--wel { clip-path: polygon(0 0, 100% 0, 100% 45.8%, 0 54.8%); }
  .hero__half--midi { clip-path: polygon(0 54.2%, 100% 45.2%, 100% 100%, 0 100%); }
  .hero__seam {
    clip-path: polygon(0 54.28%, 100% 45.28%, 100% 45.72%, 0 54.72%);
    background: linear-gradient(90deg, transparent 3%, rgba(231, 206, 134, .5) 26%, rgba(231, 206, 134, .5) 74%, transparent 97%);
  }
  /* La couture devient horizontale : Wel occupe le haut, Midi le bas.
     Chaque étiquette rejoint donc sa moitié d'image. */
  .hero__clubs { display: block; inset: 0; padding: 0; pointer-events: none; }
  /* Le nom des deux clubs tombait à 9,6 px sur téléphone : c'est la première
     chose qu'on lit sur la bannière, et c'était la plus petite de la page. */
  .hero__club { position: absolute; font-size: .75rem; letter-spacing: .11em; }
  .hero__club--wel { top: calc(var(--header-h) + 14px); left: 20px; padding-left: 0; }
  /* À GAUCHE, et c'est le bouton d'appel flottant qui commande : il est passé
     à droite (il recouvrait la pastille Facebook du pied de page à 93 %), donc
     cette étiquette repasse du côté qu'il a libéré. Mesuré à 390 x 844 : elle
     passait sous le bouton tant qu'elle restait à droite. */
  .hero__club--midi { left: 20px; bottom: 20px; text-align: left; }
  .hero__clubs .scroll-cue { display: none; }
  .hero { padding-bottom: 76px; }
}
@media (max-width: 600px) {
  :root { --header-h: 72px; }
  body { font-size: 16px; }
  .container { padding: 0 20px; }
  .brand { gap: 4px; }
  .brand__mark { font-size: 19px; }
  .header.scrolled .brand__mark { font-size: 17px; }
  .brand__by { gap: 6px; }
  .brand__img { height: 18px; }
  .brand__sep { height: 16px; }
  .header.scrolled .brand__img { height: 17px; }
  .header.scrolled .brand__sep { height: 15px; }
  .brand__mark--dark { font-size: 22px; }
  .footer__about .brand--footer { gap: 8px; }
  .footer__about .brand--footer img { height: 21px; }
  .footer__about .brand--footer .brand__wel { height: 23px; }
  .footer__about .brand--footer img[src*="midi"] { height: 19px; }
  .brand__sep--footer { height: 18px; }
  .hero { padding-left: 20px; padding-right: 20px; }
  .hero__surtitre { --surtitre-retrait: 9px; line-height: 2.5; }
  .hero__kicker { font-size: .82rem; letter-spacing: .13em; padding: 6px var(--surtitre-retrait); }
  .hero__cta { flex-direction: column; align-items: stretch; gap: 16px; }
  .hero__cta .btn { width: 100%; }
  .hero__cta .btn-link { width: 100%; justify-content: center; }
  /* Trop étroit pour une ligne de menu : l'intitulé et son contenu se superposent,
     les points de conduite n'auraient plus la place de relier quoi que ce soit. */
  .ardoise__liste li { flex-wrap: wrap; gap: 0 10px; }
  .ardoise__liste .ardoise__pt { display: none; }
  .ardoise__val { flex-basis: 100%; text-align: left; }
  .carousel__track { aspect-ratio: 4 / 5; }
  .carousel__arrow { width: 44px; height: 44px; }
  .carousel__arrow--prev { left: 10px; }
  .carousel__arrow--next { right: 10px; }
  .carousel__cap { left: 20px; bottom: 20px; }
  .form__row { grid-template-columns: 1fr; }
  /* Le formulaire faisait huit lignes empilées sur mobile. Un nombre et une date
     tiennent à deux sur 390 px : le téléphone garde la largeur entière, les deux
     champs courts se partagent la ligne suivante. Une ligne de moins à faire
     défiler avant le bouton d'envoi. */
  .form__row--3 { grid-template-columns: 1fr 1fr; column-gap: 12px; }
  .form__row--3 > .field:first-child { grid-column: 1 / -1; }
  .scroll-cue { display: none; }
  /* LES DEUX FLOTTANTS PASSENT À DROITE, EMPILÉS.
     Posé à gauche, le bouton d'appel amputait les premiers mots de chaque ligne
     au bas de l'écran, et recouvrait la pastille Facebook du pied de page à
     93 %. Le bord droit d'un texte aligné à gauche est irrégulier : un bouton y
     masque beaucoup moins. Le bouton « remonter » les rejoint plutôt que de
     prendre la place libérée : mesuré à 320 px, à gauche il mangeait le début
     de la dernière question de la FAQ. Le bord GAUCHE, lui, est parfaitement
     régulier, donc tout ce qui s'y pose ampute à chaque ligne.
     Il se cale au-dessus du bouton d'appel (52 px + 10 px d'écart), centré sur
     lui : 14 + 52/2 - 32/2 = 24 px du bord. */
  .call-fab { left: auto; right: 14px; bottom: calc(20px + env(safe-area-inset-bottom)); height: 52px; width: 52px; }
  .call-fab__icon { width: 52px; height: 52px; }
  .to-top { top: auto; bottom: calc(82px + env(safe-area-inset-bottom)); right: 24px; left: auto; transform: translateY(14px); }
  /* La commande de pause du carrousel tombait pile sous le bouton d'appel, de
     320 à 414 px : un doigt qui visait « pause » déclenchait un appel. Elle
     passe du côté que les flottants viennent de libérer. */
  .carousel__pause { order: -1; margin-left: 0; margin-right: 10px; }
  .to-top.is-visible { transform: translateY(0); }
  .footer__top { grid-template-columns: 1fr; }
  .footer__bottom { flex-direction: column; }
  /* Un numéro de téléphone haut de 16 px se rate au doigt. Ce sont les deux
     chemins de conversion du site : ils passent au-dessus du plancher de 24 px
     du WCAG 2.5.8, et le plus près possible des 44 px recommandés. */
  .info-card a, .form__hint a, .footer a[href^="tel:"], .footer a[href^="mailto:"],
  .footer__bottom a {
    display: inline-block; padding: 11px 0;
  }
  /* Le numéro de la bannière ne peut pas s'épaissir par un padding : il vit au
     milieu d'une phrase et pousserait la ligne. Sa zone sensible s'étend donc
     par-dessous, sans toucher au flux ni au rythme du texte. */
  .hero__meta a[href^="tel:"] { position: relative; }
  .hero__meta a[href^="tel:"]::before {
    content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px;
  }
}

/* =========================================================
   QUESTIONS FRÉQUENTES
   Même écriture que les arguments de « Pourquoi » : des lignes séparées d'un
   filet, pas de cartes. On réutilise <details>/<summary> natifs : ça se replie
   sans une ligne de JavaScript, ça reste lisible sans JavaScript, et le contenu
   des réponses est dans le HTML, donc lu par Google même volet fermé.
   ========================================================= */
/* Deuxième césure invisible relevée par l'audit : la FAQ et le contact étaient
   tous deux sur blanc, avec 179 px de vide entre les deux et rien pour dire
   qu'on changeait de sujet. La FAQ prend le gris des sections alternées : la
   page retrouve son rythme (bande sombre, gris, blanc, footer sombre) et le
   formulaire redevient le seul bloc blanc de la fin de page. */
.faq { background: var(--paper-2); }
.faq__liste { max-width: 78ch; margin-top: 40px; }
.faq__item { border-top: 1px solid var(--line); }
.faq__item:last-child { border-bottom: 1px solid var(--line); }
.faq__item summary {
  display: flex; align-items: baseline; gap: 16px; cursor: pointer;
  padding: 26px 0; list-style: none;
}
/* Le chevron par défaut de Safari et Chrome, retiré des deux côtés */
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::marker { content: ""; }
.faq__item summary h3 {
  font-size: clamp(1.2rem, 1.7vw, 1.42rem); font-weight: 500;
  margin: 0; flex: 1; text-wrap: balance;
}
/* Le signe d'ouverture : un simple trait qui devient une croix. Dessiné en CSS,
   donc rien à charger, et il tourne d'un quart de tour à l'ouverture. */
.faq__item summary::after {
  content: ""; flex: none; width: 14px; height: 14px; margin-top: 4px;
  background:
    linear-gradient(var(--gold), var(--gold)) center/14px 1.5px no-repeat,
    linear-gradient(var(--gold), var(--gold)) center/1.5px 14px no-repeat;
  transition: transform .35s var(--ease-out);
}
.faq__item[open] summary::after { transform: rotate(45deg); }
/* Le doré clair sur ce fond ne donne que 2,61:1, et la question de FAQ mesure
   entre 19 et 23 px : c'est du texte courant au sens de la règle, il lui faut
   donc 4,5:1. `--gold-deep` monte à 5,37:1 pour la même teinte à l'œil. */
.faq__item summary:hover h3 { color: var(--gold-deep); }
.faq__item > p {
  color: var(--muted); max-width: 66ch;
  margin: 0 0 28px; padding-right: 30px;
}

@media (max-width: 620px) {
  .faq__item summary { padding: 22px 0; gap: 12px; }
  .faq__item > p { padding-right: 0; }
  .croquis--bulles { display: none; }
}

/* Sous 400 px, « Nombre de personnes » (110,6 px de plancher) et le champ date
   natif (172 px de plancher) ne tiennent plus côte à côte : à eux deux ils
   poussaient la page à 368 px de large dans un écran de 320. On les empile. */
@media (max-width: 400px) {
  .form__row--3 { grid-template-columns: minmax(0, 1fr); }
  .form__row--3 > .field:first-child { grid-column: auto; }
  /* « Itinéraire » ne se replie pas (white-space: nowrap + flex-shrink: 0) :
     à 320 px il poussait le cadre 4 px hors de l'écran. Il passe sous le nom
     du club plutôt que de rogner le reste. */
  .map-slot:not(.is-loaded) { flex-direction: column; align-items: flex-start; gap: 4px; }
  .map-slot:not(.is-loaded) .map-itin { padding: 8px 2px; }
}

/* =========================================================
   LES TITRES SUR LES TRÈS PETITS ÉCRANS (320 À 360 PX)
   =========================================================
   Même défaut que la bannière ci-dessous, au même endroit : le plancher du
   clamp. Les titres de section se figent à 2,15 rem dès 800 px de large, et ne
   redescendent plus. À 320 px il ne reste que 280 px de texte, et « Ce qu'on
   nous demande le plus souvent. » y passait sur trois lignes ; les questions de
   la FAQ aussi. Sous 360 px, le corps redevient donc proportionnel à la largeur,
   avec le plafond d'aujourd'hui : à 360 px rien ne change d'un pixel, et en
   dessous le titre se resserre en même temps que l'écran. */
@media (max-width: 360px) {
  .section-title { font-size: clamp(1.72rem, 9.3vw, 2.15rem); }
  .faq__item summary h3 { font-size: clamp(1rem, 5.2vw, 1.2rem); }
}

/* =========================================================
   LE TITRE DE BANNIÈRE SUR LES PETITS TÉLÉPHONES
   =========================================================
   « Réunissez vos équipes autrement. » passait sur TROIS lignes en dessous de
   400 px. Sur trois lignes, ce n'est plus un titre, c'est un paragraphe en gros.
   Le corps était bloqué à 2,7 rem par le plancher de son clamp, alors qu'il
   n'aurait manqué que deux pixels pour que « Réunissez vos équipes » tienne
   d'un tenant : la place disponible tombe à 350 px à 390, à 280 px à 320, et le
   titre, lui, ne bougeait plus.

   Le corps redevient donc proportionnel à la largeur sous ce seuil, avec le
   même plafond qu'avant (2,7 rem) : à 420 px rien ne change, et plus l'écran se
   resserre, plus le titre se resserre avec lui. Deux lignes de 320 à 430 px.
   Le plancher de 2,05 rem garantit qu'il reste un titre de bannière, très
   au-dessus du corps du chapô qui le suit. */
@media (max-width: 420px) {
  .hero h1 { font-size: clamp(2.05rem, 10.4vw, 2.7rem); }
}

/* =========================================================
   PRÉFÉRENCE : MOUVEMENT RÉDUIT
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
  .js .reveal { opacity: 1 !important; transform: none !important; }
  .scroll-cue__line::after, .hero__half-img { animation: none !important; }
  .to-top::after { transition: none !important; }
  .scroll-cue__line::after { top: 22px; opacity: .9; }
  .carousel__slide { transition: none !important; }
  .carousel__slide img { animation: none !important; transform: none !important; }
  .mobile-menu > * { opacity: 1; transform: none; transition: none; }
  .header, .header.is-hidden { transition: none; transform: none; }
  .call-fab::after { animation: none !important; }
  .hero { --split: 50 !important; }
  .rally__ball { opacity: 1 !important; }
  .odo__strip { transition: none !important; }
  /* La légende reste affichée, DONC le voile aussi. Les deux vont ensemble, comme
     dans le bloc `(hover: none)` plus haut : la légende seule, c'est du crème de
     12 px posé à même la photo, mesuré entre 1,15:1 et 4,38:1 selon l'image. */
  .gallery-item__cap { opacity: 1 !important; transform: none !important; }
  .gallery-item::after { opacity: 1 !important; }
  /* Le trait doré des arguments reste tiré : il sépare, il n'anime pas */
  .js .arg h3::before { width: 34px !important; transition: none !important; }
  .js .hero__inner > * { opacity: 1 !important; transform: none !important; animation: none !important; }
  .btn-gold::after { display: none; }
  .gallery-item:hover img { transform: none; }
  .scroll-progress span { transition: none; }
  .form.is-sending .form__submit .arrow { animation: none !important; }
  .skip-link { transition: none; }
  .duo__balle { animation: none !important; }
  /* Les croquis qui jouent un geste : ils ne jouent rien. Le dessin reste ce
     qu'il était, étincelles allumées, coche tracée, mot en place, balle posée. */
  .choc, .etincelles, .balle__coutures, .verres__tchin, .croquis .coche {
    animation: none !important;
  }
  /* L'inclinaison du mot n'est pas du mouvement, c'est du dessin : elle reste. */
  .choc, .etincelles, .balle__coutures { transform: none !important; }
  .croquis .coche { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
}

/* =========================================================
   COMPENSATION OPTIQUE (mesurée par l'audit typographie-web, 2026-08-10)
   Les capitales rondes ou obliques (C, R, B, T, S, W, À) ne posent pas leur
   encre exactement sur le bord de leur boîte : on rattrape l'écart pour que
   les bords gauches soient alignés à l'œil, pas seulement au pixel CSS.
   ========================================================= */
div.hero__inner > h1                      { text-indent: -0.015em; }
div.galerie__head > h2.section-title      { text-indent: -0.013em; }
div.container > h2.section-title          { text-indent: -0.033em; }
summary > h3                              { text-indent: 0.028em; }
div.footer__about > p                     { text-indent: 0.030em; }
/* Les titres des bienfaits ont changé : trois sur quatre commencent désormais par
   une capitale DROITE (L, T), qui n'a rien à rattraper. L'ancien -0.026em, mesuré
   sur des rondes (C, O, S), les ferait déborder du fil. Valeur remesurée ci-dessous,
   et seulement là où une lettre ronde ou oblique le demande. */
form#devis-form p.form__hint              { text-indent: -0.028em; }
/* Deux capitales qui ne débordent du fil qu'aux corps réduits du mobile */
@media (max-width: 820px) {
  li.step:last-child > h3                 { text-indent: 0.047em; }
  div.deroule__head > h2.section-title    { text-indent: 0.012em; }
}

/* L'INTERLETTRAGE POSE SON ESPACE APRÈS LE DERNIER CARACTÈRE.
   Sur un bloc aligné à gauche, personne ne le voit. Sur un bloc aligné à DROITE,
   ce vide fantôme s'intercale entre le texte et le bord, et le sur-titre paraît
   décalé de deux pixels par rapport au titre qu'il annonce. On le reprend. */
.deroule__head .kicker { margin-right: -.15em; }
.hero__club--midi { margin-right: -.13em; }
@media (max-width: 700px) {
  /* Sous 700 px, cette étiquette n'est plus alignée à droite mais à gauche
     (le bouton d'appel flottant lui a pris le coin droit) : le vide fantôme
     tombe alors du côté qu'on ne regarde pas, et la compensation n'a plus
     lieu d'être. La reprendre décalerait le texte du bord gauche. */
  .hero__club--midi { margin-right: 0; }
}
