/* ==========================================================================
   XL GYM CHARLESBOURG — feuille de style principale
   --------------------------------------------------------------------------
   Sommaire
   01. Jetons (couleurs, typo, espacement)
   02. Réinitialisation et bases
   03. Typographie
   04. Mise en page (wrap, sections, thèmes)
   05. Composants (boutons, cartes, médias, puces)
   06. En-tête et navigation
   07. Hero
   08. Accès — cadran 24 h (élément signature)
   09. Le Gym
   11. Installations
   13. Abonnements
   14. Avis Google
   15. Visionneuse
   16. Devise
   17. Contact
   18. Pied de page
   19. Animations et accessibilité
   ========================================================================== */


/* 01. JETONS ============================================================== */

:root{
  /* Couleurs — dérivées de l'identité XL Gym (rouge brique #AA2E23) */
  --ink:        #0C0C0D;   /* noir de fond */
  --ink-2:      #141416;   /* surface sombre surélevée */
  --ink-3:      #1C1C1F;   /* anthracite — cartes */
  --ink-line:   rgba(255,255,255,.10);
  --chalk:      #F6F5F3;   /* texte sur fond sombre */
  --smoke:      #A5A4A2;   /* texte secondaire sur fond sombre */

  --bone:       #EFEEEB;   /* fond clair */
  --bone-2:     #E4E2DD;   /* surface claire surélevée */
  --bone-line:  rgba(12,12,13,.12);
  --graphite:   #101012;   /* texte sur fond clair */
  --slate:      #5C5B59;   /* texte secondaire sur fond clair */

  --brick:      #AA2E23;   /* accent de marque */
  --brick-hi:   #C4382A;   /* accent survolé */
  --ember:      #F2796A;   /* accent lisible en petit sur fond sombre */

  /* Rôles — redéfinis par les classes de thème */
  --bg: var(--ink);
  --fg: var(--chalk);
  --muted: var(--smoke);
  --line: var(--ink-line);
  --surface: var(--ink-3);
  --accent-text: var(--ember);

  /* Typographie */
  --font-display: "Archivo", "Arial Black", system-ui, sans-serif;
  --font-body: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* Rythme */
  --hdr-h: 84px;
  --wrap: 1240px;
  --gutter: clamp(20px, 5vw, 56px);
  --section-y: clamp(72px, 9vw, 136px);
  --radius: 10px;
  --radius-lg: 16px;

  /* Transitions */
  --ease: cubic-bezier(.2, .7, .3, 1);
  --t-fast: .18s var(--ease);
  --t: .32s var(--ease);
}


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

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

html{
  overflow-x: clip;
  scroll-behavior: smooth;
  scroll-padding-top: 88px;
  -webkit-text-size-adjust: 100%;
}

body{
  margin: 0;
  overflow-x: clip;
  background: var(--ink);
  color: var(--chalk);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

h1, h2, h3, h4, p, figure, blockquote{ margin: 0; }

ul, ol{ margin: 0; padding: 0; list-style: none; }

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

button{ font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

table{ border-collapse: collapse; width: 100%; }

::selection{ background: var(--brick); color: #fff; }

.visually-hidden{
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link{
  position: fixed; top: 12px; left: 12px; z-index: 200;
  padding: 12px 18px; border-radius: var(--radius);
  background: var(--brick); color: #fff;
  font-family: var(--font-mono); font-size: .8rem;
  transform: translateY(-160%);
  transition: transform var(--t);
}
.skip-link:focus-visible{ transform: none; }

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


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

.display{
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 118%;
  /* « Charlesbourg, » est le mot le plus long du titre : l'échelle doit
     descendre assez bas pour qu'il tienne sans être rogné à 320 px. */
  font-size: clamp(2rem, 9.5vw, 5.4rem);
  line-height: .96;
  letter-spacing: -.035em;
  text-wrap: balance;
}

.h2{
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 112%;
  font-size: clamp(1.95rem, 4.2vw, 3.3rem);
  line-height: 1.03;
  letter-spacing: -.028em;
  color: var(--fg);
  text-wrap: balance;
}
.h2 em{ font-style: normal; color: var(--accent-text); }

.eyebrow{
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--accent-text);
  display: flex;
  align-items: center;
  gap: 12px;
}
.eyebrow::before{
  content: "";
  width: 22px; height: 1px;
  background: currentColor;
  flex: none;
}

.lead{
  font-size: clamp(1.05rem, 1.35vw, 1.2rem);
  line-height: 1.62;
  color: var(--muted);
  text-wrap: pretty;
}

.link-arrow{
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-mono);
  font-size: .78rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--line);
  transition: color var(--t-fast), border-color var(--t-fast), gap var(--t-fast);
}
.link-arrow svg{ width: 20px; height: 12px; }
.link-arrow:hover{ color: var(--accent-text); border-color: currentColor; gap: 16px; }
/* Au doigt, 26 px de haut c'est trop peu. Le rembourrage se met au-dessus :
   le filet reste collé au texte, seule la zone touchable grandit. */
@media (max-width: 767px){
  .link-arrow{ padding-top: 10px; }
}


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

.wrap{
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section{
  padding-block: var(--section-y);
  background: var(--bg);
  color: var(--fg);
  position: relative;
}

/* Thèmes — n'agissent que sur la couleur, jamais sur l'espacement */
.theme-ink{
  --bg: var(--ink); --fg: var(--chalk); --muted: var(--smoke);
  --line: var(--ink-line); --surface: var(--ink-3); --accent-text: var(--ember);
}
.theme-ink2{
  --bg: var(--ink-2); --fg: var(--chalk); --muted: var(--smoke);
  --line: var(--ink-line); --surface: #212125; --accent-text: var(--ember);
}
.theme-bone{
  --bg: var(--bone); --fg: var(--graphite); --muted: var(--slate);
  --line: var(--bone-line); --surface: #FFFFFF; --accent-text: var(--brick);
}

.sec-head{
  max-width: 62ch;
  margin-bottom: clamp(40px, 5vw, 72px);
}
.sec-head .eyebrow{ margin-bottom: 22px; }
.sec-head__lead{ margin-top: 22px; }

.sec-head--split{
  max-width: none;
  display: grid;
  gap: clamp(20px, 3vw, 56px);
  align-items: end;
}
@media (min-width: 900px){
  .sec-head--split{ grid-template-columns: minmax(0,1fr) minmax(0,.9fr); }
  .sec-head--split .sec-head__lead{ margin-top: 0; padding-bottom: .35em; }
}


/* 05. COMPOSANTS ========================================================== */

/* --- Boutons --- */
.btn{
  --btn-bg: transparent;
  --btn-fg: var(--fg);
  --btn-bd: var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 26px;
  border: 1px solid var(--btn-bd);
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-mono);
  font-size: .8rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background-color var(--t-fast), border-color var(--t-fast),
              color var(--t-fast), transform var(--t-fast);
}
.btn:hover{ transform: translateY(-2px); }
.btn:active{ transform: translateY(0); }

.btn--accent{ --btn-bg: var(--brick); --btn-fg: #fff; --btn-bd: var(--brick); }
.btn--accent:hover{ --btn-bg: var(--brick-hi); --btn-bd: var(--brick-hi); }

.btn--outline{ --btn-bd: color-mix(in srgb, var(--fg) 32%, transparent); }
.btn--outline:hover{ --btn-bg: var(--fg); --btn-fg: var(--bg); --btn-bd: var(--fg); }

.btn--ghost{
  --btn-bg: rgba(255,255,255,.06);
  --btn-bd: rgba(255,255,255,.24);
  --btn-fg: #fff;
  backdrop-filter: blur(8px);
}
.btn--ghost:hover{ --btn-bg: rgba(255,255,255,.14); --btn-bd: rgba(255,255,255,.5); }

.btn--sm{ min-height: 42px; padding: 0 18px; font-size: .72rem; }

/* --- Emplacements photo --- */
.media{
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background-color: #191A1D;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  isolation: isolate;
}
/* Motif d'attente, remplacé dès qu'une vraie photo est branchée */
.media::before{
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 90% at 25% 15%, rgba(170,46,35,.20), transparent 62%),
    radial-gradient(100% 80% at 85% 90%, rgba(255,255,255,.07), transparent 60%),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.035) 0 1px, transparent 1px 11px),
    linear-gradient(160deg, #232428, #131316);
}
.media::after{
  content: attr(data-hint);
  position: absolute; inset: auto 0 0 0;
  padding: 14px 16px;
  font-family: var(--font-mono);
  font-size: .66rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(246,245,243,.5);
  background: linear-gradient(transparent, rgba(0,0,0,.6));
  text-align: left;
}
.media.has-photo::before,
.media.has-photo::after{ content: none; }

.media--square{ aspect-ratio: 1 / 1; }
.media--wide{ aspect-ratio: 16 / 10; }


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

.hdr{
  position: sticky; top: 0; z-index: 100;
  border-bottom: 1px solid transparent;
  transition: background-color var(--t), border-color var(--t), backdrop-filter var(--t);
}
.hdr.is-stuck{
  background: rgba(12,12,13,.82);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: rgba(255,255,255,.09);
}

.hdr__inner{
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px;
  min-height: var(--hdr-h);
}

/* Le logo fourni par le gym, détouré : trait blanc sur transparent, il se pose
   donc aussi bien sur le noir de l'en-tête que sur la photo du hero.

   L'ensemble porte déjà « XL GYM » et « Depuis 2005 » — le texte qui
   l'accompagnait ferait doublon, il est retiré. La hauteur commande, la
   largeur suit : le rapport de l'image est 2,32 pour 1. */
.logo{
  display: inline-flex; align-items: center;
  flex: none;
}
.logo__img{
  display: block;
  width: auto;
  height: 64px;
  transition: opacity var(--t-fast);
}
.logo:hover .logo__img{ opacity: .82; }

/* Sous 380 px, le logo, le bouton et le menu ne tiennent plus sur la ligne :
   c'est le logo qui cède quelques pixels, il reste lisible. */
@media (max-width: 379px){
  .logo__img{ height: 46px; }
}

/* Sous 980 px, la navigation vit dans le panneau plein écran ouvert par le
   bouton ; le bandeau ne garde que le logo et le bouton. */
.nav__list{ display: none; }
.nav__cta,
.nav__phone{ display: none; }

.hdr__actions{ display: flex; align-items: center; gap: 12px; }
.hdr__cta{ display: none; }

.burger{
  width: 50px; height: 50px;
  display: grid; place-content: center;
  gap: 6px;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--radius);
  background: rgba(255,255,255,.05);
}
.burger span{
  display: block;
  width: 18px; height: 1.5px;
  background: #fff;
  transition: transform var(--t), opacity var(--t-fast);
}
.burger[aria-expanded="true"] span:first-child{ transform: translateY(3.75px) rotate(45deg); }
.burger[aria-expanded="true"] span:last-child{ transform: translateY(-3.75px) rotate(-45deg); }

/* Panneau mobile */
@media (max-width: 979px){
  .nav{
    position: fixed; inset: var(--hdr-h) 0 0 0;
    z-index: 99;
    display: flex; flex-direction: column; justify-content: center;
    gap: 32px;
    padding: 24px var(--gutter) 12vh;
    background: var(--ink);
    overflow-y: auto;               /* écrans courts : le menu défile plutôt que de déborder */
    overscroll-behavior: contain;
    opacity: 0; visibility: hidden;
    transform: translateY(-8px);
    transition: opacity var(--t), transform var(--t), visibility var(--t);
  }
  .nav.is-open{ opacity: 1; visibility: visible; transform: none; }

  .nav__list{ display: flex; flex-direction: column; gap: 2px; }
  .nav__list a{
    display: block;
    padding: 14px 0;
    border-bottom: 1px solid rgba(255,255,255,.08);
    font-family: var(--font-display);
    font-weight: 600; font-stretch: 110%;
    font-size: clamp(1.5rem, 6vw, 2rem);
    letter-spacing: -.02em;
    color: #fff;
    transition: color var(--t-fast), padding-left var(--t-fast);
  }
  .nav__list a:hover{ color: var(--ember); padding-left: 10px; }

  .nav__cta{ display: inline-flex; min-height: 54px; font-size: .8rem; }
  .nav__phone{
    display: block;
    padding-block: 11px;          /* zone touchable, pas décoration */
    font-family: var(--font-mono); font-size: .82rem;
    letter-spacing: .1em; color: var(--smoke);
  }

  body.nav-open{ overflow: hidden; }
}

/* En-tête bureau */
@media (min-width: 980px){
  .burger{ display: none; }
  .hdr__cta{ display: inline-flex; }
  .nav{ display: flex; align-items: center; }
  .nav__list{
    display: flex; align-items: center; gap: clamp(18px, 2.4vw, 36px);
  }
  .nav__list a{
    position: relative;
    font-family: var(--font-mono);
    font-size: .76rem; letter-spacing: .08em; text-transform: uppercase;
    color: rgba(246,245,243,.74);
    padding-block: 6px;
    transition: color var(--t-fast);
  }
  .nav__list a::after{
    content: ""; position: absolute; left: 0; right: 100%; bottom: 0;
    height: 1px; background: var(--ember);
    transition: right var(--t);
  }
  .nav__list a:hover{ color: #fff; }
  .nav__list a:hover::after{ right: 0; }
  .nav__list a.is-current{ color: #fff; }
  .nav__list a.is-current::after{ right: 0; background: var(--brick-hi); }
}


/* 07. HERO ================================================================ */

.hero{
  --cut-h: clamp(56px, 7vw, 104px);   /* hauteur du raccord diagonal vers la section suivante */
  --cut-reveal: 1;
  position: relative;
  /* Le hero remonte sous l'en-tête, il faut donc lui rendre cette hauteur
     pour que son bas tombe pile sur le bas de la fenêtre. Sans ça, la section
     suivante dépassait au premier écran. */
  min-height: calc(100svh + var(--hdr-h));
  margin-top: calc(var(--hdr-h) * -1);
  padding-top: var(--hdr-h);
  display: flex; flex-direction: column; justify-content: center;
  isolation: isolate;
  overflow: hidden;
}

.hero__media{
  position: absolute; inset: 0; z-index: -2;
  background-size: cover;
  background-position: center;
  background-color: #0E0E10;
}
.hero__media::before{
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(70% 55% at 72% 28%, rgba(170,46,35,.30), transparent 70%),
    radial-gradient(55% 50% at 12% 80%, rgba(255,255,255,.06), transparent 70%),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.022) 0 1px, transparent 1px 14px),
    linear-gradient(155deg, #1B1C20 0%, #0B0B0D 62%);
}
/* Les photos du gym sont éclairées au néon, très blanches et très saturées.
   Un léger retrait les fait entrer dans la palette sombre sans les délaver. */
.hero__media.has-photo{ filter: saturate(.86) contrast(1.04); }
.hero__media.has-photo::before{ content: none; }

.hero__scrim{
  position: absolute; inset: 0; z-index: -1;
  background:
    /* Bande du haut : sans elle, la navigation en blanc passe devant le
       plafond éclairé de la photo et devient illisible. */
    linear-gradient(to bottom, rgba(12,12,13,.88), rgba(12,12,13,0) 24%),
    linear-gradient(to top, rgba(12,12,13,.96) 4%, rgba(12,12,13,.62) 46%, rgba(12,12,13,.34) 100%),
    linear-gradient(to right, rgba(12,12,13,.80), rgba(12,12,13,.10) 70%);
}


/* Raccord hero → accès : une entaille diagonale d'une centaine de pixels,
   taillée dans le noir de la section suivante et soulignée d'un filet brique
   qui s'allume au centre puis s'éteint vers les deux bords.
   Elle est posée sur le voile du hero plutôt que sur le hero lui-même : elle
   passe donc au-dessus de la photo, mais reste sous le titre — aucun risque de
   recouvrir le texte sur un écran court. */
.hero__scrim::before,
.hero__scrim::after{
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: var(--cut-h);
  pointer-events: none;
}

/* L'entaille. « to top left » fait passer la coupe pile par le coin bas-gauche
   et le coin haut-droit, quelle que soit la largeur de l'écran : la pente se
   recalcule toute seule. Un angle fixe en degrés, lui, aurait dérivé — trop
   plat sur grand écran, trop raide sur téléphone. */
.hero__scrim::before{
  background: linear-gradient(to top left,
    var(--ink-2) 0 50%, rgba(20,20,22,0) 50%);
}

/* Le filet et son halo, sur cette même diagonale. Les arrêts sont écrits en
   « 50% ± N px » plutôt qu'en pourcentages : l'épaisseur du trait et la portée
   du halo restent donc les mêmes du téléphone au grand écran, alors que des
   pourcentages les auraient écrasés sur les petites largeurs.
   Le masque horizontal éteint le tout vers les bords — le trait respire au
   lieu de traverser l'écran d'une épaisseur égale, et le halo n'est jamais
   coupé net aux deux coins, là où la diagonale touche le bord de la bande. */
.hero__scrim::after{
  background: linear-gradient(to top left,
    rgba(196,56,42,0)    calc(50% - var(--cut-h) * .30),
    rgba(196,56,42,.10)  calc(50% - var(--cut-h) * .155),
    rgba(196,56,42,.32)  calc(50% - var(--cut-h) * .06),
    rgba(196,56,42,.78)  calc(50% - 2px),
    rgba(242,121,106,.88) 50%,
    rgba(196,56,42,.78)  calc(50% + 2px),
    rgba(196,56,42,.32)  calc(50% + var(--cut-h) * .06),
    rgba(196,56,42,.10)  calc(50% + var(--cut-h) * .155),
    rgba(196,56,42,0)    calc(50% + var(--cut-h) * .30));
  /* L'ouverture du filet, pilotée au défilement (js/main.js). 0 : éteint au
     centre. 1 : la largeur ci-dessous, celle d'origine. Les quatre arrêts sont
     écrits en « 50% ± N% » et se referment tous sur 50% quand la valeur tombe
     à zéro — le trait s'ouvre donc vers la gauche et la droite en même temps.
     La valeur par défaut est 1 : sans JavaScript, le filet est simplement là. */
  -webkit-mask-image: linear-gradient(to right,
    rgba(0,0,0,0) calc(50% - 50% * var(--cut-reveal)),
    #000          calc(50% - 20% * var(--cut-reveal)),
    #000          calc(50% + 14% * var(--cut-reveal)),
    rgba(0,0,0,0) calc(50% + 50% * var(--cut-reveal)));
  mask-image: linear-gradient(to right,
    rgba(0,0,0,0) calc(50% - 50% * var(--cut-reveal)),
    #000          calc(50% - 20% * var(--cut-reveal)),
    #000          calc(50% + 14% * var(--cut-reveal)),
    rgba(0,0,0,0) calc(50% + 50% * var(--cut-reveal)));
}

/* Le bloc est centré, puis décalé vers le bas par un padding haut plus fort
   que le bas : il se pose un peu sous le milieu de l'écran plutôt qu'en plein
   centre, ce qui laisse respirer la photo au-dessus. La proportion tient à
   toutes les hauteurs d'écran parce que les deux valeurs sont en vh. */
.hero__inner{
  padding-top: clamp(64px, 13vh, 150px);
  padding-bottom: clamp(24px, 4vh, 48px);
  max-width: min(var(--wrap), 100%);
}

/* Le titre du hero est en Bebas Neue, seul endroit du site où elle sert.
   Trois choses la distinguent d'Archivo et demandent d'annuler les réglages
   hérités de .display :
   — une seule graisse, 400 ; toute autre valeur serait synthétisée ;
   — aucun axe de largeur, donc font-stretch n'a rien à étirer ;
   — un crénage déjà très serré : le -.035em d'Archivo l'étoufferait.
   Elle n'a pas non plus de bas-de-casse : « XL Gym » s'affiche « XL GYM ». */
.hero__title{
  color: #fff;
  font-family: "Bebas Neue", var(--font-display);
  font-weight: 400;
  font-stretch: normal;
  letter-spacing: .012em;
  max-width: none;
  /* Échelle propre à Bebas. À taille égale elle est bien plus étroite
     qu'Archivo : « CHARLESBOURG, » ne remplissait plus qu'un tiers de la
     colonne. Le barème de .display ne convient donc pas ici. */
  font-size: clamp(3rem, 15vw, 9rem);
  /* Bebas n'ayant que des capitales, ses lettres n'occupent qu'environ les
     trois quarts du cadratin : à interligne égal, le blanc entre les lignes
     paraît bien plus grand qu'avec Archivo. D'où ce resserrage franc. */
  line-height: .82;
}

/* Chaque ligne est rognée pour le masque de l'animation d'ouverture. Le
   rembourrage bas lui laisse de quoi contenir ce qui descend sous la ligne de
   base — avec Bebas, seulement la virgule de « Charlesbourg, ». */
.hero__title .line{ display: block; overflow: hidden; padding-bottom: .04em; }
.hero__title .line > span{ display: block; }
.hero__title em{
  font-style: normal;
  color: var(--ember);
  /* Même halo que le filet du raccord, en plus discret : un noyau serré posé
     sur une nappe large. Les deux couches sont en braise et en brique, donc
     l'aura reste dans la palette au lieu de virer au rose. */
  text-shadow:
    0 0 16px rgba(242,121,106,.34),
    0 0 44px rgba(196,56,42,.28);
}

.hero__lead{
  margin-top: clamp(22px, 3.4vh, 36px);
  max-width: 54ch;
  color: rgba(246,245,243,.78);
}

.hero__cta{
  margin-top: clamp(30px, 4.4vh, 46px);
  display: flex; flex-wrap: wrap; gap: 12px;
}

/* La note Google. Pas de cartouche ni de fond : le hero a déjà un voile, une
   pastille de plus en ferait un badge publicitaire. Le chiffre porte seul. */
.hero__note{ margin-top: clamp(18px, 2.4vh, 26px); }
.hero__note-lien{
  display: inline-flex; align-items: center; gap: 10px;
  color: inherit;
  transition: opacity var(--t-fast);
}
.hero__note-lien:hover{ opacity: .78; }
.hero__note-score{
  font-family: var(--font-display);
  font-weight: 700; font-stretch: 112%;
  font-size: 1.24rem; line-height: 1;
  letter-spacing: -.02em;
  color: #fff;
}
.hero__note .stars{ color: var(--ember); }
.hero__note .stars svg{ width: 15px; height: 15px; }
.hero__note-texte{
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(246,245,243,.72);
}

/* Sur un écran peu haut — un portable dont la fenêtre fait 720 à 900 px — le
   hero dépassait la ligne de flottaison une fois la note ajoutée : elle
   tombait 94 px trop bas à 720. Le rythme vertical se resserre, plutôt que
   de laisser la note sous le pli où elle ne servirait plus à rien.

   Sous 780 px l'espacement ne suffit plus et le titre cède un cran. C'est la
   dernière chose que je réduis : trois lignes de Bebas pleine largeur, c'est
   ce qui fait le premier écran. */
@media (max-height: 900px){
  .hero__inner{ padding-top: clamp(44px, 6vh, 96px); }
  .hero__lead{ margin-top: clamp(18px, 2.2vh, 28px); }
  .hero__cta{ margin-top: clamp(22px, 3vh, 34px); }
  .hero__note{ margin-top: clamp(14px, 1.6vh, 20px); }
}
/* Trois paliers plutôt qu'un seul : le titre pèse pour l'essentiel de la
   hauteur du hero, et un unique seuil laissait la note sous le pli à 800 px
   tout en rapetissant le titre pour rien à 760. Bornés à 700 px de large :
   sur téléphone le hero tient déjà, et la contrainte y vient de la largeur,
   pas de la hauteur. */
@media (max-height: 840px) and (min-width: 700px){
  .hero__title{ font-size: clamp(2.8rem, 13.5vw, 7.5rem); }
}
@media (max-height: 780px) and (min-width: 700px){
  .hero__title{ font-size: clamp(2.6rem, 12vw, 6.6rem); }
}
@media (max-height: 740px) and (min-width: 700px){
  .hero__title{ font-size: clamp(2.4rem, 11vw, 5.9rem); }
}

/* 08. ACCÈS — CADRAN 24 H ================================================= */

.access__grid{
  display: grid;
  gap: clamp(40px, 6vw, 80px);
  align-items: center;
}
@media (min-width: 860px){
  .access__grid{ grid-template-columns: minmax(230px, 342px) minmax(0, 1fr); }
}

.dial{
  position: relative;
  width: min(342px, 80vw);
  margin: 0 auto;
}
.dial__svg{ width: 100%; height: auto; overflow: visible; }

.dial__ring{
  fill: none;
  stroke: var(--brick);
  stroke-width: 6;
  opacity: .58;
}

/* Le halo qui fait le tour de l'anneau, en dégradé conique : c'est la seule
   façon d'obtenir une traîne continue autour d'un cercle. Empilé en segments,
   on voyait les paliers d'opacité.

   Le masque le découpe en anneau, à l'aplomb du cercle brique : celui-ci est à
   r = 80 dans un viewBox de 200, soit 80 % du rayon de la boîte. Les bords du
   masque sont volontairement flous — c'est ce qui fait le halo.

   Le dégradé va du transparent (queue) au vif (tête) dans le sens horaire, et
   l'élément tourne dans ce même sens : la tête ouvre donc la marche. */
.dial__comet{
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background: conic-gradient(
    from 0deg,
    rgba(242,121,106,0)    0deg,
    rgba(242,121,106,.05)  20deg,
    rgba(242,121,106,.16)  45deg,
    rgba(242,121,106,.38)  68deg,
    rgba(242,121,106,.72)  84deg,
    rgba(255,168,152,.98)  94deg,
    rgba(242,121,106,0)    97deg,
    rgba(242,121,106,0)    360deg);
  -webkit-mask: radial-gradient(circle closest-side,
    transparent 71%, rgba(0,0,0,.6) 77%, #000 79%,
    #000 81%, rgba(0,0,0,.6) 83%, transparent 89%);
  mask: radial-gradient(circle closest-side,
    transparent 71%, rgba(0,0,0,.6) 77%, #000 79%,
    #000 81%, rgba(0,0,0,.6) 83%, transparent 89%);
  animation: dial-comet 6s linear infinite;
}
@keyframes dial-comet{ to{ transform: rotate(360deg); } }
.dial__staffed{
  fill: none;
  stroke: var(--chalk);
  stroke-width: 3;
  stroke-linecap: butt;
  stroke-dasharray: 0 999;
  transition: stroke-dasharray 1.1s var(--ease) .25s, stroke-dashoffset 1.1s var(--ease) .25s;
}
.dial__tick{ stroke: rgba(255,255,255,.22); stroke-width: 1.2; }
.dial__tick--major{ stroke: rgba(255,255,255,.45); stroke-width: 1.6; }

.dial__hand{ fill: none; stroke-linecap: round; }
.dial__hand--slow{ stroke: var(--brick-hi); stroke-width: 4.5; }
.dial__hand--fast{ stroke: var(--ember); stroke-width: 2.5; }

/* Le repère de la lunette : la pastille ronde du logo. Le disque reprend le
   fond de la section, donc l'anneau se coupe net derrière le repère, et le
   kettlebell évidé dans la pastille laisse voir ce même fond. */
.dial__pip-disc{ fill: var(--bg); }
.dial__pip-logo{ fill: var(--ember); }

.dial__center{
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  pointer-events: none;
}
.dial__time{
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 115%;
  font-size: clamp(2.1rem, 5.2vw, 2.6rem);
  line-height: 1;
  letter-spacing: -.035em;
  color: var(--chalk);
}
.dial__day{
  font-family: var(--font-mono);
  font-size: .64rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--smoke);
  margin-top: 8px;
}


.access__text .h2{ max-width: 20ch; }

.proofs{
  margin-top: clamp(34px, 4vw, 50px);
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 620px){ .proofs{ grid-template-columns: 1fr 1fr; } }

.proof{
  background: var(--bg);
  padding: clamp(20px, 2.4vw, 28px);
}
.proof__val{
  display: block;
  overflow: hidden;          /* le masque dans lequel le chiffre remonte */
  padding-bottom: .08em;
  font-family: var(--font-display);
  font-weight: 700; font-stretch: 112%;
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--fg);
}
.proof__val > span{ display: block; }
.proof__slash{ color: var(--brick-hi); }
.proof__lbl{
  display: block;
  margin-top: 10px;
  font-size: .86rem;
  line-height: 1.5;
  color: var(--muted);
}


/* 09. LE GYM ============================================================== */

.intro{
  position: relative;
  isolation: isolate;   /* garde le fond en z-index négatif dans la section */
  --cut-h: clamp(56px, 7vw, 104px);   /* hauteur du raccord diagonal venant de la section précédente */
}

/* Raccord accès → Le Gym : la coupure est droite, et le noir de la section
   précédente déborde de quelques pixels sur la claire — comme une feuille
   posée par-dessus une autre, dont le bord s'enroule et porte une ombre.

   Tout tient dans un seul dégradé vertical : le retour au plat, la crête, le
   pli, la tranche, puis l'ombre. La bande est en surimpression, elle n'ajoute
   aucune hauteur, et elle reste plus courte que le rembourrage haut de la
   section (--section-y) à toutes les largeurs : elle ne peut jamais toucher le
   texte.

   Le haut de la bande est du --ink-2 plein : il prolonge la section noire
   au-dessus sans jointure visible, c'est ce qui donne l'impression de
   débordement.

   z-index: -1 la place au-dessus de la photo de fond — à valeur égale, c'est
   l'ordre du document qui tranche, et un ::after passe après les enfants. */
.intro::after{
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; z-index: -1;
  pointer-events: none;

  /* --roll : de combien le noir mord sur le clair. En pixels, pas en
     pourcentage — un ourlet a une taille physique, il ne doit pas grandir avec
     l'écran. La portée de l'ombre, elle, suit --cut-h. */
  --roll: 28px;
  height: calc(var(--roll) + var(--cut-h) * .62);

  background-image: linear-gradient(to bottom,
    /* le bord enroulé : le plat, la crête tournée vers la lumière,
       le pli dans l'ombre, la tranche */
    var(--ink-2)        0,
    var(--ink-2)        calc(var(--roll) - 26px),
    #2E2E34             calc(var(--roll) - 19px),
    #212126             calc(var(--roll) - 11px),
    var(--ink)          calc(var(--roll) - 3px),
    var(--ink)          var(--roll),

    /* l'ombre portée, en quatre paliers pour qu'elle plonge vite
       puis s'étale */
    rgba(12,12,13,.36)  var(--roll),
    rgba(12,12,13,.24)  calc(var(--roll) + var(--cut-h) * .14),
    rgba(12,12,13,.12)  calc(var(--roll) + var(--cut-h) * .30),
    rgba(12,12,13,.04)  calc(var(--roll) + var(--cut-h) * .46),
    rgba(12,12,13,0)    calc(var(--roll) + var(--cut-h) * .62));
}

.intro__bg{
  position: absolute; inset: 0; z-index: -1;
  background-size: cover;
  background-position: center;
  filter: grayscale(.4) contrast(.92);
}
/* La photo se cale sur la fenêtre : la section glisse par-dessus au défilement.
   Réservé aux pointeurs fins et aux grands écrans — Safari iOS ignore
   « background-attachment: fixed » ou le rend par à-coups, et sur téléphone le
   cadrage d'une photo calée sur la fenêtre se dégrade vite. */
@media (hover: hover) and (min-width: 900px){
  .intro__bg{ background-attachment: fixed; }
}
/* Le voile. Les valeurs rgba reprennent --bone (#EFEEEB) : il faut la même
   teinte en 0 % d'opacité, sinon le dégradé passe par un gris sale en chemin.
   Verticalement il s'ouvre puis se referme — la photo n'apparaît qu'au centre,
   jamais aux jointures avec les sections voisines. */
.intro__bg::after{
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to bottom,
      rgb(239,238,235) 0%,
      rgba(239,238,235,0) 24%,
      rgba(239,238,235,0) 76%,
      rgb(239,238,235) 100%),
    linear-gradient(to right,
      rgb(239,238,235) 0%,
      rgba(239,238,235,.94) 44%,
      rgba(239,238,235,.84) 100%);
}

/* Section volontairement plus courte que les autres : le texte a été resserré,
   la respiration doit suivre. Le rembourrage haut reste au-dessus de --cut-h,
   sinon la découpe diagonale mordrait sur le contenu. */
.section.intro{ padding-block: clamp(64px, 7.5vw, 108px); }

.intro__grid{
  display: grid;
  gap: clamp(40px, 5vw, 76px);
  align-items: center;   /* le texte est court : les deux colonnes s'équilibrent
                            mieux centrées que calées en haut */
}
@media (min-width: 900px){
  /* La photo prend un peu plus que le texte : c'est elle qui porte la section. */
  .intro__grid{ grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); }
}

.intro__text .eyebrow{ margin-bottom: 20px; }
.intro__text .h2{ margin-bottom: 16px; max-width: 11ch; }
.intro__text p{ color: var(--muted); max-width: 48ch; }

.intro__lead{
  color: var(--fg);
  font-family: var(--font-display);
  font-weight: 600;
  font-stretch: 106%;
  font-size: clamp(1.12rem, 1.75vw, 1.4rem);
  line-height: 1.3;
  letter-spacing: -.018em;
  max-width: 26ch;
}
.intro__lead em{ font-style: normal; color: var(--brick); }
/* Un filet court à l'accent de marque, plutôt qu'un trait de séparation sur
   toute la largeur : il ponctue le titre au lieu de couper la colonne. */
.intro__lead::after{
  content: "";
  display: block;
  width: 54px; height: 2px;
  margin: 22px 0 24px;
  background: var(--brick);
}

.intro__media{ position: relative; }
/* La grande photo est légèrement décollée du fond. Deux couches : une ombre
   courte et serrée juste sous le bord, qui donne le contact, et une nappe large
   et très pâle qui donne la profondeur. Une seule couche donne toujours un
   effet d'autocollant. */
.intro__shot{
  aspect-ratio: 11 / 10;
  box-shadow:
    0 3px 10px rgba(12,12,13,.13),
    0 28px 60px rgba(12,12,13,.21);
}

.intro__inset{
  position: absolute;
  right: -7%; bottom: -13%;
  width: 44%;
  border: 6px solid var(--bg);
  border-radius: 14px;
}
@media (max-width: 599px){
  .intro__inset{ position: static; width: 100%; margin-top: 14px; border: 0; }
}




/* 11. INSTALLATIONS ======================================================= */

.zones{
  margin-top: clamp(34px, 4.5vw, 60px);
  display: grid;
  gap: clamp(24px, 3vw, 40px) clamp(18px, 2.2vw, 28px);
}
@media (min-width: 640px){ .zones{ grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1000px){ .zones{ grid-template-columns: repeat(3, minmax(0,1fr)); } }

/* Les photos de zone sont des boutons : elles s'agrandissent dans la
   visionneuse. C'est ce qui remplace l'ancienne section Galerie. */
.zone__photo{
  padding: 0;
  border: 0;
  width: 100%;
  display: block;
  text-align: left;
}
.zone__photo.has-photo{ cursor: zoom-in; }
.zone__photo.has-photo::after{
  content: "";
  position: absolute; inset: 0;
  background: rgba(12,12,13,0);
  transition: background-color var(--t);
}
.zone__photo.has-photo:hover::after,
.zone__photo.has-photo:focus-visible::after{ background: rgba(12,12,13,.30); }

.zone .media{ margin-bottom: 18px; }
.zone__title{
  font-family: var(--font-display);
  font-weight: 600; font-stretch: 108%;
  font-size: 1.08rem;
  letter-spacing: -.015em;
  color: var(--fg);
  margin-bottom: 8px;
}
.zone p{ color: var(--muted); font-size: .9rem; }


/* 13. ABONNEMENTS ========================================================= */

/* La bande d'essai gratuit, au-dessus des prix. Un fond brique très dilué
   plutôt qu'un aplat : elle se remarque sans se disputer la vedette avec la
   carte « Le plus choisi », qui reste le seul vrai accent de la section. */
.trial{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(14px, 1.6vw, 20px);
  margin-bottom: clamp(20px, 2.4vw, 30px);
  padding: clamp(18px, 2vw, 22px) clamp(20px, 2.2vw, 26px);
  border: 1px solid var(--brick);
  border-radius: var(--radius-lg);
  background: rgba(170,46,35,.055);
}
.trial__icon{
  flex: none;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--brick);
  color: #fff;
}
.trial__icon svg{ width: 20px; height: 20px; }
.trial__text{
  flex: 1 1 22ch;
  font-size: clamp(.98rem, 1.2vw, 1.06rem);
  line-height: 1.5;
  color: var(--muted);
}
.trial__text strong{ font-weight: 600; color: var(--fg); }
/* Le lien file à droite quand il y a la place, et repasse sous le texte
   sinon — pas de point de bascule à entretenir. */
.trial__link{ margin-left: auto; flex: none; }

.plans{
  display: grid;
  gap: clamp(14px, 1.6vw, 18px);
  align-items: stretch;
}
@media (min-width: 700px){ .plans{ grid-template-columns: repeat(2, minmax(0,1fr)); } }
/* Six formules : trois par rangée tombent juste, alors que quatre en
   laisseraient deux seules sur la seconde ligne. */
@media (min-width: 1080px){ .plans{ grid-template-columns: repeat(3, minmax(0,1fr)); } }

/* Sur téléphone, deux colonnes plutôt que six cartes empilées : la section
   passe de six hauteurs de carte à trois. Tout ce qui est écrit dedans est
   réduit d'un cran, sinon les prix se retrouvent à l'étroit dans 165 px.

   Sous 380 px il n'y a plus la place : on retombe sur une seule colonne
   plutôt que d'écraser les montants, qui sont le seul contenu que les gens
   viennent lire ici. */
@media (min-width: 380px) and (max-width: 699px){
  .plans{ grid-template-columns: repeat(2, minmax(0,1fr)); gap: 11px; }
  .plan{ --plan-pad: 15px; }
  .plan__flag{ font-size: .54rem; padding: 4px 9px; letter-spacing: .1em; }
  .plan__name{ font-size: .95rem; }
  .plan__price{ margin-top: 7px; gap: 5px; }
  .plan__amt{ font-size: 1.85rem; letter-spacing: -.03em; }
  .plan__per{ font-size: .62rem; letter-spacing: .04em; }
  .plan__taxe{ font-size: .56rem; letter-spacing: .04em; }
  .plan__term{ font-size: .6rem; margin-top: 7px; padding-bottom: 11px; }
  .plan__list{ padding-top: 11px; gap: 7px; font-size: .8rem; }
  .plan__list li{ gap: 8px; line-height: 1.4; }
  .plan__list li::before{ width: 5px; height: 5px; margin-top: .45em; }
}

.plan{
  /* Le rembourrage est nommé : la pastille « le plus choisi » doit s'aligner
     sur lui, et deux clamp() recopiés à la main finissent toujours par
     diverger. */
  --plan-pad: clamp(20px, 2vw, 26px);
  position: relative;
  display: flex; flex-direction: column;
  padding: var(--plan-pad);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color var(--t), transform var(--t);
}
.plan:hover{ transform: translateY(-3px); }

.plan--feature{
  border-color: var(--brick);
  box-shadow: 0 0 0 1px var(--brick);
}
.plan__flag{
  position: absolute; top: 0; left: var(--plan-pad);
  transform: translateY(-50%);
  padding: 5px 12px;
  background: var(--brick);
  color: #fff;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
}

.plan__name{
  font-family: var(--font-display);
  font-weight: 600; font-stretch: 108%;
  font-size: 1.1rem;
  letter-spacing: -.01em;
  color: var(--muted);
}
.plan__price{
  margin-top: 10px;
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
.plan__amt{
  font-family: var(--font-display);
  font-weight: 700; font-stretch: 115%;
  font-size: clamp(2.3rem, 3.4vw, 2.9rem);
  line-height: 1;
  letter-spacing: -.04em;
  color: var(--fg);
}
.plan__per{
  font-family: var(--font-mono);
  font-size: .74rem; letter-spacing: .08em;
  color: var(--muted);
}
/* « + taxes » suit le montant sans se confondre avec l'unité : même famille,
   un cran plus petit et plus pâle. La mention est sur chaque prix plutôt que
   dans une note en bas — c'est la première question qu'on se pose devant un
   tarif, elle ne doit pas demander de chercher. */
.plan__taxe{
  font-family: var(--font-mono);
  font-size: .66rem; letter-spacing: .06em;
  color: color-mix(in srgb, var(--muted) 78%, transparent);
}
.plan__term{
  margin-top: 9px;
  padding-bottom: 15px;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .04em;
  color: var(--muted);
}
/* Plus de rembourrage sous la liste : il servait à écarter le bouton
   « Choisir cette formule », qui n'existe plus. Sans lui, chaque carte se
   fermait sur 50 px de vide. Celui de la carte suffit. */
.plan__list{
  padding-top: 15px;
  display: flex; flex-direction: column; gap: 9px;
  font-size: .9rem;
  color: var(--muted);
}
.plan__list li{
  display: flex; gap: 11px;
  line-height: 1.45;
}
.plan__list li::before{
  content: "";
  flex: none;
  width: 6px; height: 6px;
  margin-top: .5em;
  border-radius: 50%;
  background: var(--brick);
}

.plans__note{
  margin-top: clamp(26px, 3vw, 36px);
  max-width: 62ch;
  font-size: .88rem;
  color: var(--muted);
}



/* 14. AVIS GOOGLE ========================================================= */

/* Les étoiles. Une seule taille partout, seule la couleur change selon le
   fond — c'est la braise sur sombre, définie par le thème. */
.stars{
  display: inline-flex;
  gap: 3px;
  color: var(--accent-text);
}
.stars svg{
  width: 17px; height: 17px;
  fill: currentColor;
  flex: none;
}

/* Les avis vivent dans la section « Le Gym », à la place des trois piliers.
   Le filet du haut et l'écart reprennent ceux qu'ils avaient : le rythme
   vertical de la section ne bouge pas. */
.avis{ margin-top: clamp(46px, 5vw, 72px); }

/* La barre : la note d'un côté, l'arrêt de l'autre. Le filet du haut est celui
   qui séparait les trois piliers du reste — il porte le même écart, et il est
   posé ici plutôt que sur .avis pour rester aligné sur la colonne de texte :
   le bandeau, lui, va d'un bord à l'autre de l'écran. */
.avis__bar{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(16px, 2vw, 28px);
  padding-top: clamp(30px, 3.4vw, 44px);
  padding-bottom: clamp(20px, 2.4vw, 28px);
  margin-bottom: clamp(22px, 2.6vw, 32px);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.avis__score{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}
.avis__note{
  font-family: var(--font-display);
  font-weight: 700; font-stretch: 112%;
  font-size: clamp(1.7rem, 2.6vw, 2.2rem);
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--fg);
}
.avis__compte{
  font-family: var(--font-mono);
  font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}

/* Un seul bouton là où il y avait deux flèches : le bandeau avance seul, il
   n'y a plus de « précédent / suivant » à commander, seulement à arrêter. */
.avis__pause{
  /* quand la barre passe sur deux lignes, le bouton reste à droite au lieu de
     revenir se coller sous la note */
  margin-left: auto;
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--fg);
  transition: border-color var(--t-fast), color var(--t-fast);
}
/* « display: grid » ci-dessus l'emporte sur le display:none que le navigateur
   applique à [hidden] : sans cette ligne le bouton reste visible alors que le
   script ne l'a jamais activé — mouvement réduit, ou pas de JavaScript. */
.avis__pause[hidden]{ display: none; }
.avis__pause svg{ width: 15px; height: 15px; fill: currentColor; }
.avis__pause:hover{ border-color: currentColor; color: var(--accent-text); }
/* Les deux pictogrammes cohabitent dans le bouton, un seul est montré : rien à
   redessiner au clic, et aucun saut de taille entre les deux états. */
.avis__pause-i{ grid-area: 1 / 1; }
.avis__pause .avis__pause-i--go{ display: none; }
.avis__pause.est-arrete .avis__pause-i--stop{ display: none; }
.avis__pause.est-arrete .avis__pause-i--go{ display: block; }

/* BANDEAU DÉFILANT ---------------------------------------------------------
   D'un bord à l'autre de l'écran : le débordement fait partie du propos, il
   dit qu'il y a plus d'avis que ce qu'on voit.

   Sans JavaScript — et sous « mouvement réduit », où le script s'abstient —
   ça reste une liste qu'on fait défiler au doigt. Le masquage du débordement
   n'arrive qu'avec la classe posée par le script, sinon les huit cartes
   seraient inatteignables.                                                   */
.glisse{
  --gap: 24px;
  overflow-x: auto;
  scrollbar-width: none;
}
.glisse::-webkit-scrollbar{ display: none; }
/* Les cartes se dissolvent aux deux bords au lieu d'être tranchées net : sans
   ça, une carte coupée en plein milieu au bord de l'écran ressemble à un bug
   d'affichage. Réservé au mode animé — sur une liste qu'on fait défiler soi-
   même, un bord estompé cache l'endroit où on met le doigt. */
.glisse.est-anime{
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 5%, #000 95%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 5%, #000 95%, transparent 100%);
}

.glisse__piste{
  display: flex;
  gap: var(--gap);
  width: max-content;
  /* les cartes sont à égalité de hauteur : la plus longue donne le ton */
  align-items: stretch;
  padding-bottom: 4px;
}

.avis-carte{
  flex: 0 0 clamp(268px, 74vw, 372px);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  gap: 18px;
  padding: clamp(22px, 2.4vw, 28px);
}
.avis-carte__texte{
  font-size: clamp(.98rem, 1.2vw, 1.06rem);
  line-height: 1.55;
  color: var(--fg);
  /* Les cartes s'alignent sur la plus haute : la signature reste en bas. */
  flex: 1;
}
/* Une signature, pas une étiquette : la police d'affichage plutôt que la
   monospace, qui donnait à un nom propre l'allure d'un numéro de référence. */
.avis-carte__auteur{
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-display);
  font-weight: 600;
  font-stretch: 106%;
  font-size: .98rem;
  letter-spacing: -.01em;
  color: var(--fg);
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

/* Les initiales, pas la photo de profil Google : republier l'image d'une
   personne sur un site commercial demande son consentement (C.c.Q. art. 36) et
   la photo appartient à qui l'a prise. Google affiche la même pastille pour
   les comptes sans photo. Elle est décorative — le nom est déjà lu à côté,
   d'où aria-hidden dans le HTML. */
.avis-carte__pastille{
  flex: none;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent-text) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-text) 26%, transparent);
  color: var(--accent-text);
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .04em;
  /* la monospace ne descend pas sous la ligne de base ici : le décalage
     optique d'un demi-pixel se corrige mieux à la main qu'avec line-height */
  padding-left: .04em;
}


/* 15. VISIONNEUSE ========================================================= */

.lightbox{
  position: fixed; inset: 0; z-index: 150;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(16px, 4vw, 56px);
  background: rgba(8,8,9,.94);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity var(--t);
}
.lightbox[hidden]{ display: none; }
.lightbox.is-open{ opacity: 1; }
.lightbox__img{
  width: min(1100px, 100%);
  aspect-ratio: 3 / 2;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}
.lightbox__close{
  position: absolute; top: clamp(12px, 2vw, 24px); right: clamp(12px, 2vw, 24px);
  width: 48px; height: 48px;
  display: grid; place-content: center;
  font-size: 2rem; line-height: 1;
  color: #fff;
  border: 1px solid rgba(255,255,255,.2);
  border-radius: var(--radius);
  transition: background-color var(--t-fast);
}
.lightbox__close:hover{ background: rgba(255,255,255,.12); }


/* 16. DEVISE ============================================================== */

/* Un cran de moins que les autres sections : la bande ne porte que trois
   lignes, elle n'a pas besoin d'autant d'air qu'une section pleine. Reste
   proportionnel à la largeur, comme le reste du rythme vertical. */
.devise{ padding-block: clamp(56px, 7vw, 104px); }

.devise__inner{ text-align: center; }

.devise__slogan{
  font-family: var(--font-display);
  font-weight: 600;
  font-stretch: 110%;
  font-size: clamp(1.9rem, 4.8vw, 3.4rem);
  line-height: 1.08;
  letter-spacing: -.03em;
  color: var(--fg);
  max-width: 20ch;
  margin-inline: auto;
  text-wrap: balance;
}
.devise__slogan em{ font-style: normal; color: var(--accent-text); }

.devise__body{
  margin: clamp(24px, 3vw, 34px) auto 0;
  max-width: 54ch;
  font-size: clamp(1.02rem, 1.3vw, 1.15rem);
  line-height: 1.6;
  color: var(--muted);
  text-wrap: pretty;
}


/* 17. CONTACT ============================================================= */

.contact__head{ margin-bottom: clamp(40px, 5vw, 68px); }
.contact__head .eyebrow{ margin-bottom: 22px; }

/* Le titre et la pastille sur une ligne, qui se casse d'elle-même quand la
   place manque : pas de point de bascule à entretenir. */
.contact__headline{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(14px, 2vw, 28px);
}
.contact__title{
  font-family: var(--font-display);
  font-weight: 700;
  font-stretch: 112%;
  font-size: clamp(2.3rem, 5.4vw, 4.1rem);
  line-height: 1;
  letter-spacing: -.035em;
  color: var(--fg);
}
.badge{
  display: inline-flex; align-items: center; gap: 10px;
  padding: 11px 18px;
  border: 1px solid currentColor;
  border-radius: 999px;
  color: var(--accent-text);
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .13em; text-transform: uppercase;
  white-space: nowrap;
}
.badge svg{ width: 15px; height: 15px; flex: none; }

.contact__lead{
  margin-top: clamp(18px, 2vw, 26px);
  max-width: 46ch;
}

.contact__grid{
  display: grid;
  gap: clamp(34px, 4vw, 56px);
  align-items: start;
}
@media (min-width: 940px){
  .contact__grid{ grid-template-columns: minmax(0, .92fr) minmax(0, 1fr); }
}

/* --- Les trois blocs d'information --- */
.info{
  display: flex;
  gap: clamp(16px, 1.8vw, 24px);
  align-items: flex-start;
}
.info + .info{
  margin-top: clamp(24px, 2.8vw, 34px);
  padding-top: clamp(24px, 2.8vw, 34px);
  border-top: 1px solid var(--line);
}
.info__icon{
  flex: none;
  width: 58px; height: 58px;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  color: var(--accent-text);
}
.info__icon svg{ width: 23px; height: 23px; }
.info__body{ min-width: 0; flex: 1; }

.info__title{
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 500;
  color: var(--accent-text);
  margin-bottom: 12px;
}
.info__text{
  font-size: clamp(1rem, 1.3vw, 1.12rem);
  line-height: 1.55;
  color: var(--fg);
}
.info__text a{
  border-bottom: 1px solid var(--line);
  transition: color var(--t-fast), border-color var(--t-fast);
}
.info__text a:hover{ color: var(--accent-text); border-color: currentColor; }
.info__fine{
  margin-top: 14px;
  font-size: .84rem;
  color: var(--muted);
}
.info .link-arrow{ margin-top: 18px; }

/* --- Les horaires --- */
.hours-card{
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 4px clamp(16px, 1.8vw, 22px);
}
.hours th, .hours td{
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: baseline;
}
.hours th{
  font-weight: 400;
  font-size: .95rem;
  color: var(--fg);
}
.hours td{
  text-align: right;
  font-family: var(--font-mono);
  font-size: .86rem;
  color: var(--muted);
  white-space: nowrap;
  padding-left: 16px;
}
.hours tr:last-child th, .hours tr:last-child td{ border-bottom: 0; }

/* Sous 520 px, la pastille d'icône et le tableau ne tiennent plus côte à côte :
   l'icône passe au-dessus, et les valeurs cessent d'être insécables. Sans ça
   « 24 h sur 24, 7 jours » pousse la colonne au-delà de l'écran. */
@media (max-width: 519px){
  .info{ display: block; }
  .info__icon{ margin-bottom: 16px; }
  .hours td{ white-space: normal; }
}

/* --- Carte et stationnement --- */
.contact__aside{
  display: grid;
  gap: clamp(16px, 1.8vw, 22px);
}

/* Sur deux colonnes, la carte prend toute la hauteur de la colonne de gauche :
   les horaires descendaient 200 px plus bas qu'elle, ce qui laissait un grand
   vide à droite. La carte s'étire plutôt que le texte ne se comprime, et ça
   reste juste quelle que soit la longueur des horaires plus tard.

   « 1fr auto » : la carte prend ce qui reste, la note du stationnement garde
   sa hauteur propre. */
@media (min-width: 940px){
  .contact__grid{ align-items: stretch; }
  .contact__aside{ grid-template-rows: 1fr auto; }
  .contact__map{ min-height: 0; }
}
/* LA CARTE ------------------------------------------------------------------
   Le plan est un SVG dessiné à partir des vraies rues d'OpenStreetMap, pas une
   carte chargée chez un tiers : aucune requête, aucune clé, aucun cookie, et
   les couleurs sont celles du site plutôt qu'une approximation.

   Trois épaisseurs de rue, chacune posée deux fois : une gaine noire un peu
   plus large en dessous, la couleur par-dessus. C'est ce qui donne aux rues un
   bord net là où elles se croisent, au lieu d'une bouillie grise. */
.contact__map{
  --carte-fond: #141416;
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.12);
  background: var(--carte-fond);
  /* Le même principe que la grande photo de « Bienvenue au XL Gym », en plus
     appuyé : une ombre courte et serrée sous le bord, qui donne le contact,
     et une nappe large qui donne la profondeur. Une seule couche fait toujours
     un effet d'autocollant.

     Trois couches ici plutôt que deux : la nappe seule, poussée assez loin
     pour se voir, devenait une tache grise aux bords mous. La couche
     intermédiaire fait le pont entre le contact et la nappe, et l'ensemble
     reste une ombre au lieu d'un halo. */
  box-shadow:
    0 4px 12px rgba(12,12,13,.22),
    0 16px 32px rgba(12,12,13,.24),
    0 40px 78px rgba(12,12,13,.36);
}
.carte__plan{
  display: block;
  width: 100%;
  height: clamp(320px, 46vw, 620px);
}
/* Doit venir APRÈS la règle ci-dessus, pas avant : à spécificité égale c'est
   l'ordre d'écriture qui tranche. Placée plus haut, elle était ignorée et le
   SVG restait à 620 px dans un cadre de 821 — d'où une bande de fond nu de
   200 px sous la carte. */
@media (min-width: 940px){
  .carte__plan{ height: 100%; }
}

/* Les surfaces, sous les rues, dans l'ordre où Google les empile en thème
   sombre : les espaces verts, puis les aires (stationnements, serres), puis
   les bâtiments — les rues par-dessus tout. Trois tons très proches du fond :
   on veut la texture d'une ville, pas des blocs qui se disputent l'attention
   avec le marqueur. Aucune de ces formes n'est nommée. */
.carte__vert{ fill: #1A2320; }
.carte__aire{ fill: #19191C; }
.carte__bati{ fill: #212126; }

.carte__gaine{ stroke: #0C0C0D; }
.carte__rue--d{ stroke: #26262A; }   /* rues résidentielles */
.carte__rue--c{ stroke: #313138; }   /* rues collectrices */
.carte__rue--b{ stroke: #3E3E47; }   /* boulevards */

/* Les noms suivent le tracé de leur rue (textPath). Le contour sombre posé
   avant le remplissage — paint-order — les détache du gris de la chaussée ;
   sans lui, un nom qui passe sur son propre boulevard devient illisible. */
.carte__nom{
  font-family: var(--font-mono);
  /* En unités du viewBox, pas en pixels écran : le cadre fait 558 px de large
     pour un viewBox de 1000, donc tout est réduit d'un tiers à l'affichage.
     18 ici valent 11 px à l'écran. */
  font-size: 18px;
  letter-spacing: .02em;
  fill: #9E9D9A;
  stroke: var(--carte-fond); stroke-width: 4.5px;
  paint-order: stroke; stroke-linejoin: round;
}
.carte__nom--c{ fill: #ADACA9; }
.carte__nom--b{ fill: #C2C1BE; font-size: 20px; }

/* La lueur fixe : elle donne du poids au marqueur même entre deux ondes. */
.carte__lueur{ fill: rgba(196,56,42,.16); }

/* Les ondes qui battent autour du point. Des anneaux tracés, pas des disques
   pleins : un disque qui grandit se confond avec le point et le scintillement
   ne se lit plus.

   « transform-box: fill-box » est ce qui rend la chose simple — sans lui,
   scale() en SVG part de l'origine du repère (0,0) et le cercle file en
   diagonale au lieu de grandir sur place. Le marqueur peut donc être déplacé
   sans rien recalculer ici.

   « vector-effect: non-scaling-stroke » garde le trait à épaisseur constante :
   sinon l'anneau s'épaissit en grandissant, et l'onde a l'air de gonfler au
   lieu de s'éloigner. */
.carte__onde{
  fill: none;
  stroke: var(--brick-hi);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  transform-box: fill-box;
  transform-origin: center;
  animation: carte-onde 2.8s cubic-bezier(.15, .6, .3, 1) infinite;
}
.carte__onde--2{ animation-delay: 1.4s; }

@keyframes carte-onde{
  0%   { transform: scale(.4);  opacity: .95; }
  70%  { transform: scale(1.3); opacity: 0;   }
  100% { transform: scale(1.3); opacity: 0;   }
}

/* Le cœur du point respire, sans changer de taille : sur une carte, un point
   qui grossit se lit comme un déplacement. */
.carte__point{
  fill: var(--brick-hi);
  stroke: #0C0C0D; stroke-width: 3;
  animation: carte-coeur 2.8s ease-in-out infinite;
}
@keyframes carte-coeur{
  0%, 100% { fill: var(--brick-hi); }
  50%      { fill: #E8523F; }
}

@media (prefers-reduced-motion: reduce){
  /* Un seul anneau figé, pour que le marqueur garde sa cible. */
  .carte__onde{ animation: none; opacity: .45; }
  .carte__onde--2{ display: none; }
  .carte__point{ animation: none; }
}
.carte__gym-nom{
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 23px;
  fill: #F6F5F3;
  stroke: #0C0C0D; stroke-width: 4px;
  paint-order: stroke; stroke-linejoin: round;
}
/* La ligne du quartier passe au second plan : sur un plan, c'est le nom du
   gym qu'on cherche, la ville ne fait que le situer. */
.carte__gym-lieu{
  font-weight: 500;
  font-size: 17px;
  fill: #BFBEBB;
}

/* Sur téléphone le cadre tombe à ~342 × 320 : le SVG entier se réduit d'autant
   et les noms de rue finiraient à 4,6 px. On zoome donc dans le plan — moins
   de quartier, mais lisible — et on grossit le texte en unités du viewBox pour
   compenser ce qui reste de réduction. C'est ce que fait n'importe quelle carte
   quand la fenêtre rétrécit : elle montre moins, plus gros. */
@media (max-width: 767px){
  .carte__plan{ transform: scale(1.3); }
  .carte__nom{ font-size: 26px; stroke-width: 7px; }
  .carte__nom--b{ font-size: 28px; }
  .carte__gym-nom{ font-size: 30px; stroke-width: 5px; }
  .carte__gym-lieu{ font-size: 22px; }
}

/* Une note sous la carte, pas une carte de plus : le stationnement est un
   détail pratique, il ne doit pas peser autant que l'adresse ou les heures. */
.parking{
  display: flex; align-items: center;
  gap: 9px;
  padding-inline: 2px;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--muted);
}
.parking__icone{
  flex: none;
  width: 19px; height: 19px;
  color: var(--accent-text);
}


/* 18. PIED DE PAGE ======================================================== */

.footer{
  background: var(--ink);
  color: var(--chalk);
  padding-block: clamp(56px, 7vw, 88px) 32px;
  border-top: 1px solid var(--ink-line);
}

.footer__top{
  display: grid;
  gap: clamp(38px, 5vw, 64px);
  padding-bottom: clamp(38px, 5vw, 60px);
}
@media (min-width: 860px){
  .footer__top{ grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
}

.logo--footer .logo__img{ height: 78px; }
.footer__tag{
  margin-top: 20px;
  font-family: var(--font-display);
  font-weight: 500; font-stretch: 106%;
  font-size: 1.16rem;
  letter-spacing: -.015em;
  color: var(--smoke);
}

.footer__nav{
  display: grid;
  gap: clamp(28px, 4vw, 40px);
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.footer__h{
  font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 500;
  color: var(--ember);
  margin-bottom: 16px;
}
.footer__col ul{ display: flex; flex-direction: column; gap: 11px; }
.footer__col a{
  font-size: .92rem;
  color: var(--smoke);
  transition: color var(--t-fast);
}
.footer__col a:hover{ color: #fff; }

.footer__bottom{
  padding-top: 28px;
  border-top: 1px solid var(--ink-line);
  display: flex; flex-wrap: wrap; gap: 14px 28px;
  align-items: center; justify-content: space-between;
}
.footer__copy{
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .06em;
  color: rgba(246,245,243,.6);
}
/* La signature, en retrait dans la même ligne : elle se lit sans peser autant
   que le nom du commerce. */
.footer__credit{ color: rgba(246,245,243,.34); }
.footer__credit a{ color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.footer__credit a:hover{ color: rgba(246,245,243,.7); }

/* Les crédits, repliés. Le mot reste affiché en permanence : la licence ODbL
   demande une source atteignable, pas enfouie. Le triangle natif est retiré au
   profit d'un signe qui suit l'état, plus discret à cette taille. */
.credits{
  font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .06em;
  color: rgba(246,245,243,.34);
}
.credits summary{
  cursor: pointer;
  list-style: none;
  display: inline-flex; align-items: center; gap: 7px;
  padding-block: 4px;
  transition: color var(--t-fast);
}
.credits summary::-webkit-details-marker{ display: none; }
.credits summary::after{
  content: "+";
  font-size: .9em;
  opacity: .7;
}
.credits[open] summary::after{ content: "–"; }
.credits summary:hover{ color: rgba(246,245,243,.7); }
.credits summary:focus-visible{ outline: 2px solid var(--ember); outline-offset: 3px; border-radius: 3px; }
.credits p{
  margin-top: 8px;
  max-width: 46ch;
  line-height: 1.55;
}
.credits a{ color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.credits a:hover{ color: rgba(246,245,243,.7); }

/* Les liens du pied de page faisaient 18 px de haut : trop peu pour le pouce.
   Le rembourrage remplace l'écart, l'espacement visuel ne bouge presque pas
   mais la zone touchable double. */
@media (max-width: 767px){
  .footer__col ul{ gap: 0; }
  .footer__col a{ display: inline-block; padding-block: 9px; }
}

/* Les deux colonnes restent côte à côte jusqu'en bas de l'échelle, comme sur
   grand écran. En auto-fit, minmax(160px, 1fr) + 28 px d'écart réclamait
   348 px : sous 380 px de large les colonnes s'empilaient et le pied de page
   doublait de hauteur. Ici la première colonne se cale sur son plus long
   libellé (« Installations ») et laisse tout le reste à l'adresse, qui tient
   alors sur une seule ligne. */
@media (max-width: 859px){
  .footer__nav{
    grid-template-columns: max-content minmax(0, 1fr);
    gap: clamp(22px, 6vw, 40px);
  }
}


/* 19. ANIMATIONS ET ACCESSIBILITÉ ========================================= */

/* Tout est visible par défaut. Les états masqués ne s'activent que si le
   JavaScript a pu poser la classe « js » sur <html> — pas de page blanche
   si le script ne s'exécute pas. */

.js .reveal{
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: calc(var(--d, 0) * 90ms);
}
.js .reveal.is-in{ opacity: 1; transform: none; }

[data-delay="1"]{ --d: 1; }
[data-delay="2"]{ --d: 2; }
[data-delay="3"]{ --d: 3; }

/* Déclencheur seul : l'élément ne bouge pas lui-même, il sert à lancer
   l'animation de son contenu. Le cadre des preuves reste donc en place —
   le faire glisser ouvrirait des fentes de 1 px entre les cases. */
.js .reveal--bare{ opacity: 1; transform: none; }

/* Les quatre chiffres de la section Accès montent l'un après l'autre. */
.js .proofs .proof__val > span{
  transform: translateY(105%);
  transition: transform .7s var(--ease);
}
.js .proofs .proof__lbl{
  opacity: 0;
  transition: opacity .5s var(--ease);
}
.js .proofs.is-in .proof__val > span{ transform: none; }
.js .proofs.is-in .proof__lbl{ opacity: 1; }

.js .proofs .proof:nth-child(1) .proof__val > span,
.js .proofs .proof:nth-child(1) .proof__lbl{ transition-delay: 40ms; }
.js .proofs .proof:nth-child(2) .proof__val > span,
.js .proofs .proof:nth-child(2) .proof__lbl{ transition-delay: 130ms; }
.js .proofs .proof:nth-child(3) .proof__val > span,
.js .proofs .proof:nth-child(3) .proof__lbl{ transition-delay: 220ms; }
.js .proofs .proof:nth-child(4) .proof__val > span,
.js .proofs .proof:nth-child(4) .proof__lbl{ transition-delay: 310ms; }

/* Séquence d'ouverture du hero */
.js [data-anim]{ opacity: 0; transform: translateY(18px); }
/* 106 % et non 102 : la ligne est un peu plus haute que son interligne à cause
   du rembourrage bas. Trop court, un bout de lettre resterait visible sous le
   masque avant que l'animation démarre. */
.js .hero__title .line > span{ transform: translateY(106%); }
.js .hero__title .line[data-anim]{ opacity: 1; transform: none; }

.js.is-ready [data-anim]{
  opacity: 1;
  transform: none;
  transition: opacity .75s var(--ease), transform .75s var(--ease);
  transition-delay: calc(var(--i, 0) * 95ms + 120ms);
}
.js.is-ready .hero__title .line > span{
  transform: none;
  transition: transform .95s var(--ease);
  transition-delay: calc(var(--i, 0) * 95ms + 120ms);
}

[data-anim="1"]{ --i: 0; }
[data-anim="2"]{ --i: 1; }
[data-anim="3"]{ --i: 2; }
[data-anim="4"]{ --i: 3; }
[data-anim="5"]{ --i: 5; }
[data-anim="6"]{ --i: 6; }
[data-anim="7"]{ --i: 7; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }
  /* Figée, la comète n'est plus qu'une tache claire posée sur l'anneau :
     elle disparaît plutôt que de s'arrêter n'importe où. */
  .dial__comet{ display: none; }
  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .js .reveal,
  .js [data-anim]{ opacity: 1 !important; transform: none !important; }
  .js .hero__title .line > span{ transform: none !important; }
  .js .proofs .proof__val > span{ transform: none !important; }
  .js .proofs .proof__lbl{ opacity: 1 !important; }
  .btn:hover, .plan:hover{ transform: none !important; }
}

