/* ==========================================================================
   En-tête et pied de page d'origine — porté depuis
   _floot-export/components/SharedLayout.module.css (le composant que nous
   n'avions jamais pu extraire jusqu'ici : header.php/nav.php/footer.php le
   reproduisent maintenant avec ses vrais noms de classes).

   Cloisonnement : .site-header et .site-footer sont deux classes DÉDIÉES,
   posées directement sur les éléments <header> (inc/nav.php) et <footer>
   (inc/footer.php) du layout — jamais sur <body>. Avant cette tâche, tout
   était préfixé par .site-layout, posée sur <body> : comme <main> est aussi
   un descendant de <body>, ".site-layout .header { position: sticky;
   height: 80px }" s'appliquait EN PLUS aux <div class="header"> internes de
   pages/horaires.php et pages/tarifs.php (30 noms de classes dupliqués
   relevés dans les *.module.css de pages, cf. rapport de tâche) : leur
   contenu réel (224-229px) se retrouvait comprimé dans une boîte sticky de
   80px, chevauchant la première rangée de contenu. .site-header/.site-footer
   ne pouvant apparaître QUE sur les deux éléments du layout (aucune page ne
   les utilise, vérifié), aucune règle ci-dessous ne peut plus jamais
   atteindre un descendant de <main>. .site-layout reste posée sur <body>
   uniquement pour la mise en page flex colonne pleine hauteur ci-dessous
   (elle ne cible jamais un .header/.footer par ce biais).

   Adaptations nécessaires par rapport à l'original (documentées aussi dans
   le rapport de tâche) :
   - L'original est une SPA React : le menu déroulant desktop utilise Radix
     DropdownMenu (portail + attribut data-state) et le menu mobile utilise
     Radix Collapsible, un <nav> DESKTOP et un <nav> MOBILE totalement
     séparés dans le DOM (le mobile n'existe même pas dans le DOM tant que
     isMobileMenuOpen est faux). Un site sans JS n'aurait alors aucune
     navigation du tout. Le contrat no-js de ce projet (bloquant) interdit
     cette approche : un seul <nav id="menu-principal" class="desktopNav">
     sert donc pour le bureau ET le mobile, restylé en pile verticale sous
     768px / en no-js. Les règles visuelles de .mobileNav / .mobileNavLink /
     .mobileSubNav / .mobileNavFooter / .mobileCta de l'original sont donc
     fusionnées ici dans les media queries de .desktopNav / .navLink /
     .dropdownContent / .navCta plutôt que dupliquées sous leur propre nom.
   - [data-state="open"] (posé par Radix) devient [aria-expanded="true"],
     synchronisé par assets/js/main.js sur clic/survol/focus. Les sous-menus
     s'ouvrent par :hover, :focus-within ET .is-open (contrat bloquant).
   - .navGroup est un ajout pragmatique : Radix n'a pas besoin d'un wrapper
     DOM stable (portail + Popper gèrent le positionnement), notre CSS pur a
     besoin d'un ancêtre position:relative pour positionner .dropdownContent
     et pour que :hover/:focus-within fonctionnent sur le groupe complet.
   - backdrop-filter/rgba (flou + transparence du header original) sont
     remplacés par un fond opaque var(--background) : contrainte projet
     "jamais de flou ni d'opacité" (cf. rapport).
   - Le mode sombre (:global(.dark) .header) est omis : aucun sélecteur de
     thème n'existe sur ce site statique (Mode: Light Mode Only).
   ========================================================================== */

.site-layout {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  /* svh = plus petit viewport, barre d'URL DÉPLOYÉE. vh vaut le plus grand :
     sur mobile la boîte dépassait donc l'écran puis sursautait quand la barre
     se repliait. La déclaration vh reste en repli pour les navigateurs
     antérieurs aux unités dynamiques (adaptation mobile du 11 août 2026). */
  min-height: 100svh;
}

/* --------------------------------------------------------------------------
   En-tête
   -------------------------------------------------------------------------- */

/* Hauteur de l'en-tête, déclarée une seule fois.

   Elle était écrite en dur à trois endroits qui DOIVENT rester d'accord : la
   hauteur de .site-header, la position verticale du menu mobile (top) et sa
   hauteur maximale (calc(100dvh - ...)). Les faire varier séparément produirait
   soit un menu décollé de l'en-tête, soit un menu qui dépasse l'écran. Un token
   les lie : changer la valeur en un point les met tous les trois à jour.

   Ce n'est pas une précaution théorique — c'est ce qui rend possible la
   réduction en paysage plus bas dans ce fichier. */
:root {
  --hauteur-entete: 80px;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-nav-sticky);
  background-color: var(--background);
  border-bottom: 1px solid var(--border);
  height: var(--hauteur-entete);
}

/* --------------------------------------------------------------------------
   Zones sûres (encoche, coins arrondis, barre d'accueil)

   inc/header.php déclare viewport-fit=cover : le fond du site s'étend jusqu'aux
   bords physiques de la dalle, ce qui évite les bandes noires d'iOS autour de
   l'encoche. La contrepartie est que le contenu peut alors passer DESSOUS. En
   orientation paysage — un téléphone tenu à l'horizontale, cas courant pour
   consulter des horaires — l'encoche mord sur le bord gauche ou droit selon le
   sens de rotation, soit 44 à 59px sur les iPhone récents.

   Les insets sont posés sur les trois conteneurs internes plutôt que sur <body>
   ou .site-layout : les fonds (en-tête papier, pied de page ivoire, bandes
   colorées des pages) restent ainsi pleine largeur, seul le contenu se décale.
   max() garantit qu'on ne RÉDUIT jamais le remplissage existant : sur un écran
   sans encoche, env() vaut 0 et les valeurs d'origine s'appliquent telles
   quelles. (Adaptation mobile du 11 août 2026.) */
.site-header .navContainer {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 var(--spacing-8);
  padding-left: max(var(--spacing-8), env(safe-area-inset-left));
  padding-right: max(var(--spacing-8), env(safe-area-inset-right));
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Le contenu des pages porte son propre remplissage horizontal, variable d'une
   page à l'autre : on ne le remplace pas, on ajoute seulement de quoi dégager
   l'encoche quand elle existe. */
.site-layout > main {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

.site-header .logo {
  display: flex;
  align-items: center;
  text-decoration: none;
}

.site-header .logoImage {
  height: 55px;
  width: auto;
}

/* Nav (sert à la fois de desktopNav bureau et de nav empilée mobile/no-js) */
.site-header .desktopNav {
  display: flex;
  align-items: center;
  gap: var(--spacing-8);
}

.site-header .navLink {
  font-family: var(--font-family-base);
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  color: var(--muted-foreground);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: color 0.2s ease;
  position: relative;
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
  /* Remplissage vertical purement fonctionnel : les liens de navigation ne
     mesuraient que 18px de haut, sous la cible minimale de 24px. Il agrandit
     la zone cliquable sans rien changer à l'apparence — le fond reste
     transparent, la hauteur de l'en-tête est fixée à 80px et les éléments y
     restent centrés (audit du 6 août 2026, P3). La media query mobile
     redéfinit ce padding pour sa propre mise en page. */
  padding: var(--spacing-2) 0;
}

.site-header .navLink:hover,
.site-header .navLink[aria-expanded="true"] {
  color: var(--foreground);
}

.site-header .navLink.active {
  color: var(--primary);
}

.site-header .navLink.active::after {
  content: "";
  position: absolute;
  /* Le lien porte désormais var(--spacing-2) (8px) de remplissage vertical
     pour atteindre 24px de cible tactile. Le soulignement était calé à -4px
     du bord du texte ; il est recalé à +4px du bord de la boîte remplie, ce
     qui le laisse exactement au même endroit à l'écran qu'avant. */
  bottom: 4px;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: var(--primary);
}

/* Groupe déroulant (LE CLUB, LE KARATÉ, INFOS PRATIQUES) */
.site-header .navGroup {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.site-header .dropdownTrigger {
  outline: none;
}

.site-header .dropdownIcon {
  width: 14px;
  height: 14px;
  transition: transform 0.2s ease;
}

.site-header .dropdownTrigger[aria-expanded="true"] .dropdownIcon {
  transform: rotate(180deg);
}

.site-header .dropdownContent {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 12rem;
  display: none;
  flex-direction: column;
  background-color: var(--card);
  list-style: none;
  border-radius: 0; /* Brutalist */
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
  margin-top: var(--spacing-2);
  padding: var(--spacing-2) 0;
  z-index: var(--z-nav);
}

/* Passerelle invisible au-dessus du sous-menu.

   Le sous-menu est décollé du déclencheur par margin-top (8px, repris tel quel
   de l'export Floot). Or .navGroup ne contient pas cet espace : le sous-menu
   est en position absolue, il ne compte donc pas dans la hauteur du groupe, et
   les 8px qui les séparent n'appartiennent à aucun élément survolable. En
   descendant du bouton vers le sous-menu, la souris traversait cette bande
   morte, :hover retombait et le menu se refermait avant d'être atteint —
   impossible d'ouvrir un sous-menu à la souris sans passer par le clic.

   Ce ::before comble exactement cette bande. Il n'a ni fond ni bordure, donc
   rien ne change à l'écran, mais il reçoit le survol ; comme il appartient au
   sous-menu, donc à .navGroup, :hover reste vrai pendant la traversée. Il
   n'existe que lorsque le sous-menu est déployé (un ::before d'un élément en
   display:none n'est pas rendu), il ne peut donc pas intercepter un clic
   destiné à autre chose quand le menu est fermé.

   Les 2px de rabiot couvrent la bordure de 1px du sous-menu et évitent un
   liseré d'un pixel non survolable entre la passerelle et le bloc. */
.site-header .dropdownContent::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(-1 * var(--spacing-2) - 2px);
  height: calc(var(--spacing-2) + 2px);
}

/* Ouverture au clavier et au clic : les deux seules qui valent partout. */
.site-header .navGroup:focus-within .dropdownContent,
.site-header .navGroup.is-open .dropdownContent {
  display: flex;
}

/* Ouverture au survol réservée aux appareils qui savent survoler. Sur une
   tablette, :hover s'accroche au premier appui et ne se relâche qu'au toucher
   suivant : le sous-menu restait ouvert alors que le doigt était reparti
   ailleurs, et l'état visuel contredisait aria-expanded, piloté lui par le
   clic. En le limitant ici, le tactile ne dépend plus que de .is-open, posé
   par assets/js/main.js — un seul mécanisme, déterministe. */
@media (hover: hover) {
  .site-header .navGroup:hover .dropdownContent {
    display: flex;
  }
}

.site-header .dropdownItemLink {
  text-decoration: none;
  color: var(--foreground);
  width: 100%;
  font-family: var(--font-family-base);
  font-size: 0.9rem;
  font-weight: 500;
  padding: var(--spacing-2) var(--spacing-4);
  display: block;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.site-header .dropdownItemLink:hover {
  background-color: var(--accent);
  color: var(--accent-foreground);
}

.site-header .dropdownItemLink.activeDropdownItem {
  color: var(--primary);
  font-weight: 700;
  background-color: var(--accent);
}

/* Bouton "ESSAI GRATUIT" (Button size="sm" variant="primary" + overrides navCta) */
.site-header .navCta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-2);
  height: 1.5rem;
  padding: 0 var(--spacing-2);
  background-color: var(--primary);
  color: var(--primary-foreground);
  border: 1px solid var(--primary);
  border-radius: 0;
  font-family: var(--font-family-heading);
  letter-spacing: 0.05em;
  font-size: 1.1rem;
  text-transform: none;
  /* En line-height:normal, Teko à 17,6px produit une boîte de texte de 25px
     dans un bouton haut de 24px : le texte débordait d'un pixel de part et
     d'autre. line-height:1 ramène la ligne à 17,6px, largement contenue, sans
     toucher à la hauteur du bouton — aucun changement visible, juste un texte
     qui ne force plus sa boîte (audit du 6 août 2026, P3). */
  line-height: 1;
}

.site-header .navCta:hover {
  color: var(--primary-foreground);
}

/* Bouton burger (mobileToggle) */
.site-header .mobileToggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--foreground);
  /* var(--spacing-2)=8px donnait un bouton de 40x45 (WCAG 2.5.5 exige
     44x44) ; l'icône elle-même ne change pas de taille, seul le remplissage
     grandit. */
  padding: 0.75rem;
}

.site-header .mobileToggleIcon--close {
  display: none;
}

.site-header .mobileToggle[aria-expanded="true"] .mobileToggleIcon--open {
  display: none;
}

.site-header .mobileToggle[aria-expanded="true"] .mobileToggleIcon--close {
  display: block;
}

/* --------------------------------------------------------------------------
   Contrat no-js (bloquant) : sans JavaScript, la classe no-js reste sur
   <html> et le site doit rester utilisable — nav visible et empilée sous
   l'en-tête, sous-menus toujours dépliés, bouton burger masqué, y compris
   sous 768px où le CSS masquerait sinon la navigation par défaut.
   -------------------------------------------------------------------------- */
/* La hauteur fixe de 80px et le position:sticky de .site-header sont pensés
   pour une barre sur UNE ligne. En mode no-js, .navContainer passe en
   flex-wrap:wrap et la nav dépliée (flex-basis:100%) descend sur une seconde
   ligne : l'en-tête, lui, restait haut de 80px. La nav débordait donc de sa
   boîte — 488px mesurés à 1280px de large, 713px à 390px — et, comme
   .site-header porte z-index:var(--z-nav-sticky), elle se peignait PAR-DESSUS
   le <main>, qui commence toujours à y=80. Résultat : hero, <h1> et boutons
   entièrement recouverts, et le menu suivait au défilement à cause du sticky.
   Le contrat no-js est bloquant pour ce projet (PRODUCT.md) et le README
   l'annonçait vérifié : la recette avait contrôlé que la nav restait visible,
   jamais où elle atterrissait. Corrigé par l'audit du 6 août 2026 (P0).

   height:auto laisse l'en-tête englober ses deux lignes ; position:static
   évite qu'un en-tête devenu haut de plusieurs centaines de pixels ne se
   colle en haut de l'écran et ne mange le viewport au défilement. Le padding
   vertical remplace l'espacement que les 80px fournissaient implicitement. */
.no-js .site-header {
  height: auto;
  position: static;
}

.no-js .site-header .navContainer {
  flex-wrap: wrap;
  padding-top: var(--spacing-4);
  padding-bottom: var(--spacing-4);
}

.no-js .site-header .desktopNav {
  position: static;
  display: flex;
  flex-basis: 100%;
  flex-direction: column;
  align-items: stretch;
  background-color: var(--card);
  border-bottom: 1px solid var(--border);
  padding: var(--spacing-4);
  gap: var(--spacing-4);
  max-height: none;
  overflow-y: visible;
  box-shadow: none;
  animation: none;
}

.no-js .site-header .navGroup {
  flex-direction: column;
  align-items: stretch;
}

.no-js .site-header .dropdownContent {
  position: static;
  display: flex;
  box-shadow: none;
  border: 0;
  margin-top: 0;
  padding-left: var(--spacing-4);
}

/* La passerelle de survol n'a de sens que pour le sous-menu flottant du
   bureau. Ici le sous-menu est en position:static et collé au déclencheur
   (margin-top:0) : il n'y a aucune bande à combler, et le ::before —
   position:absolute — se raccrocherait à .navGroup au lieu du sous-menu,
   recouvrant une zone de la pile verticale et interceptant des clics. */
.no-js .site-header .dropdownContent::before {
  content: none;
}

.no-js .site-header .mobileToggle {
  display: none;
}

/* --------------------------------------------------------------------------
   Contenu principal
   -------------------------------------------------------------------------- */

.site-layout > main {
  flex: 1;
  background-color: var(--background);
}

/* --------------------------------------------------------------------------
   Pied de page
   -------------------------------------------------------------------------- */

.site-footer {
  background-color: var(--card);
  border-top: 1px solid var(--border);
  padding: var(--spacing-16) var(--spacing-8) var(--spacing-8);
  /* Zones sûres — voir l'explication en tête de .navContainer. L'inset du bas
     compte ici en plus des côtés : c'est la barre d'accueil des iPhone sans
     bouton, qui recouvrirait sinon la ligne de copyright et les derniers liens
     du pied de page. */
  padding-left: max(var(--spacing-8), env(safe-area-inset-left));
  padding-right: max(var(--spacing-8), env(safe-area-inset-right));
  padding-bottom: max(var(--spacing-8), env(safe-area-inset-bottom));
}

.site-footer .footerContent {
  max-width: 1400px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--spacing-12);
  margin-bottom: var(--spacing-12);
}

.site-footer .footerLogo {
  font-family: var(--font-family-heading);
  font-size: 2rem;
  margin: 0 0 var(--spacing-4) 0;
  color: var(--foreground);
}

.site-footer .footerDesc {
  color: var(--muted-foreground);
  line-height: 1.6;
}

/* L'opacity:0.8 d'origine ramenait --muted-foreground à 3,92:1 sur --card,
   sous le seuil AA de 4,5:1 — et sur les neuf pages, puisque c'est le pied de
   page partagé. Elle est retirée : la mise en retrait de cette précision
   (« Fédération Française de Karaté et Disciplines Associées ») est déjà
   portée par le font-size, et la couleur remonte à 6,16:1 (audit du 6 août
   2026, P2). */
.site-footer .footerDesc__note {
  font-size: 0.8em;
}

.site-footer .footerLinks h3,
.site-footer .footerContact h3,
.site-footer .footerSocial h3 {
  font-family: var(--font-family-monospace);
  font-size: 0.875rem;
  text-transform: uppercase;
  color: var(--foreground);
  margin: 0 0 var(--spacing-6) 0;
  letter-spacing: 0.1em;
}

.site-footer .footerLinks ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  /* Le remplissage vertical ajouté ci-dessous à chaque lien (pour atteindre
     44px de cible tactile, WCAG 2.5.5) fournit déjà l'espacement entre les
     liens : le gap de la liste est retiré pour ne pas cumuler les deux. */
  gap: 0;
}

.site-footer .footerLinks a {
  text-decoration: none;
  color: var(--muted-foreground);
  transition: color 0.2s ease;
  /* display:inline-block (plutôt que block) : la cible s'agrandit
     verticalement sans s'étirer sur toute la largeur de la colonne — la
     largeur (déjà ≥44px pour ces libellés) et la composition visuelle du
     pied de page restent inchangées. */
  display: inline-block;
  padding: 0.75rem 0;
}

.site-footer .footerLinks a:hover {
  color: var(--primary);
}

.site-footer .footerContact p {
  color: var(--muted-foreground);
  line-height: 1.6;
  margin: 0 0 var(--spacing-3) 0;
}

.site-footer .footerContact a {
  display: inline-block;
  padding: 0.75rem 0;
}

.site-footer .socialIcons {
  display: flex;
  gap: var(--spacing-4);
}

.site-footer .socialLink {
  color: var(--muted-foreground);
  transition: color 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 44x44 (WCAG 2.5.5) au lieu de 40x40 : l'icône elle-même (svg, 20x20)
     ne change pas de taille, seul le cadre cliquable grandit légèrement. */
  width: 44px;
  height: 44px;
  border: 1px solid var(--border);
  background-color: var(--surface);
}

.site-footer .socialLink svg {
  width: 20px;
  height: 20px;
}

.site-footer .socialLink:hover {
  color: var(--primary);
  border-color: var(--primary);
}

.site-footer .footerBottom {
  max-width: 1400px;
  margin: 0 auto;
  padding-top: var(--spacing-8);
  border-top: 1px solid var(--border);
  text-align: center;
  color: var(--muted-foreground);
  font-size: 0.875rem;
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1024px) {
  .site-footer .footerContent {
    grid-template-columns: 1fr 1fr;
  }
}

/* Point de rupture de la navigation : 1023px, et non 768px.

   768 était un chiffre d'APPAREIL, pas de contenu. La navigation bureau
   réclame 793px à elle seule ; avec le logo (~126px) et le remplissage du
   conteneur (2 x 32px), l'en-tête a besoin d'environ 985px pour la présenter
   sur une ligne. Entre 769 et ~1000px, elle était donc servie quand même, mais
   comprimée — jusqu'à 146px de trop à 844px de large : « LE CLUB »,
   « LE KARATÉ » et « INFOS PRATIQUES » se cassaient en deux lignes dans une
   boîte haute de 34px, et le bouton ESSAI GRATUIT, de hauteur fixe, voyait son
   texte coupé par la bordure de l'en-tête.

   Cette bande n'a rien de théorique : c'est TOUT téléphone tenu à l'horizontale
   (844x390, 852x393, 926x428, 932x430...) et la plupart des tablettes en
   portrait (810, 820, 1024x768), sans compter les fenêtres de bureau réduites
   ou en écran partagé. Le public premier du site étant un parent sur son
   téléphone (PRODUCT.md), l'orientation paysage n'est pas un cas marginal.

   1023 est mesuré, pas choisi : c'est la dernière largeur à laquelle la nav
   bureau tient sans être comprimée d'un seul pixel (vérifié à 1024 : 793px
   disponibles pour 793px nécessaires). En dessous, le burger prend le relais —
   une pile verticale lisible plutôt qu'une barre écrasée.

   La mise en page du pied de page, elle, ne dépend pas de la largeur de la nav
   et garde son propre point de rupture à 768px, plus bas dans ce fichier.
   (Adaptation mobile du 11 août 2026.) */
@media (max-width: 1023px) {
  /* Nav bureau -> pile mobile (fusion des règles .mobileNav d'origine) */
  .site-header .desktopNav {
    position: absolute;
    top: var(--hauteur-entete);
    left: 0;
    width: 100%;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: var(--spacing-4);
    background-color: var(--background);
    border-bottom: 1px solid var(--border);
    padding: var(--spacing-4);
    box-shadow: var(--shadow-lg);
    /* 100vh puis 100dvh : sur mobile, 100vh vaut la hauteur du viewport
       barre d'URL RÉTRACTÉE, donc le menu pouvait dépasser sous la barre
       d'adresse tant qu'elle est déployée. 100dvh suit la hauteur réellement
       visible. La première déclaration reste comme repli pour les navigateurs
       antérieurs aux unités dynamiques (audit du 6 août 2026, P3). */
    max-height: calc(100vh - var(--hauteur-entete));
    max-height: calc(100dvh - var(--hauteur-entete));
    overflow-y: auto;
    animation: site-layout-slide-down 0.3s ease;
  }

  .site-header .desktopNav.is-open {
    display: flex;
  }

  .site-header .navGroup {
    flex-direction: column;
    align-items: stretch;
  }

  .site-header .navLink {
    font-family: var(--font-family-heading);
    font-size: 1.5rem;
    padding: var(--spacing-2);
    border-bottom: 1px solid var(--border);
    justify-content: space-between;
    width: 100%;
  }

  .site-header .navLink.active {
    border-color: var(--primary);
  }

  .site-header .navLink.active::after {
    content: none;
  }

  .site-header .dropdownContent {
    position: static;
    display: none;
    box-shadow: none;
    border: 0;
    margin-top: 0;
    padding: var(--spacing-2) var(--spacing-2) var(--spacing-2) var(--spacing-6);
    background-color: var(--surface);
    border-bottom: 1px solid var(--border);
  }

  /* Même raison qu'en mode no-js : sous-menu empilé et collé au déclencheur,
     aucune bande morte à combler, et un ::before absolu se raccrocherait à
     .navGroup en recouvrant une partie du menu déroulé. */
  .site-header .dropdownContent::before {
    content: none;
  }

  /* Menu empilé : le survol n'ouvre plus rien. Sous 1023px on est presque
     toujours au doigt, et un :hover accroché faisait s'ouvrir un sous-menu au
     simple passage du pouce pendant le défilement. Le clic (.is-open) et le
     clavier (:focus-within) suffisent, et ce sont les deux mécanismes que
     assets/js/main.js synchronise avec aria-expanded. */
  .site-header .navGroup:focus-within .dropdownContent,
  .site-header .navGroup.is-open .dropdownContent {
    display: flex;
  }

  .site-header .dropdownItemLink {
    font-family: var(--font-family-base);
    font-size: 1.1rem;
    color: var(--muted-foreground);
    padding: var(--spacing-2);
  }

  .site-header .dropdownItemLink.activeDropdownItem {
    color: var(--primary);
    background-color: transparent;
  }

  .site-header .navCta {
    margin-top: var(--spacing-4);
    width: 100%;
    height: 2.5rem;
  }

  .site-header .mobileToggle {
    display: block;
  }
}

/* Le pied de page garde son point de rupture d'origine : ses quatre colonnes
   tiennent encore très bien à 900px, elles n'ont aucune raison de suivre la
   navigation dans son passage anticipé au mode empilé. */
@media (max-width: 768px) {
  .site-footer .footerContent {
    grid-template-columns: 1fr;
    gap: var(--spacing-8);
  }
}

/* --------------------------------------------------------------------------
   Écrans bas : téléphone tenu à l'horizontale

   Sur un téléphone couché, la hauteur devient la ressource rare — 390 à 430px
   en tout. L'en-tête collant y prélevait 80px, soit 21% de l'écran, en
   permanence, pour n'afficher qu'un logo et un bouton. Ramené à 56px, il n'en
   prend plus que 14% : un septième d'écran rendu au contenu, sur toute la
   hauteur de la page. Concrètement, sur la page Horaires, c'est une ligne de
   créneau de plus visible sans défiler.

   L'en-tête RESTE collant : c'est en paysage qu'on consulte des horaires ou des
   tarifs en faisant défiler, et perdre l'accès à la navigation à ce moment-là
   coûterait plus cher que les 56px qu'il occupe. On réduit, on ne supprime pas.

   Le seuil de 500px de haut vise les téléphones couchés (390, 393, 428, 430) et
   ne peut atteindre ni une tablette en paysage (768px de haut au minimum) ni un
   écran d'ordinateur. Il ne dépend volontairement PAS de l'orientation
   déclarée : une fenêtre de navigateur basse sur un portable a exactement le
   même besoin.

   Le logo suit — 55px de haut dans une barre de 56 ne laisserait pas un pixel
   de respiration. À 34px il reste parfaitement lisible, le sigle du club étant
   dessiné pour tenir en petit (c'est aussi le favicon).

   Grâce au token --hauteur-entete, la position et la hauteur maximale du menu
   déroulant suivent automatiquement : rien d'autre à ajuster.
   (Adaptation mobile du 11 août 2026.) */
@media (max-height: 500px) {
  :root {
    --hauteur-entete: 56px;
  }

  .site-header .logoImage {
    height: 34px;
  }
}

@keyframes site-layout-slide-down {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-header .desktopNav {
    animation: none;
  }
}
