/* ==========================================================================
   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;
}

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

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

.site-header .navContainer {
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 var(--spacing-8);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.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);
}

.site-header .navGroup:hover .dropdownContent,
.site-header .navGroup:focus-within .dropdownContent,
.site-header .navGroup.is-open .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);
}

.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;
  }
}

@media (max-width: 768px) {
  /* Nav bureau -> pile mobile (fusion des règles .mobileNav d'origine) */
  .site-header .desktopNav {
    position: absolute;
    top: 80px;
    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 - 80px);
    max-height: calc(100dvh - 80px);
    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;
  }

  .site-header .navGroup:hover .dropdownContent,
  .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;
  }

  .site-footer .footerContent {
    grid-template-columns: 1fr;
    gap: var(--spacing-8);
  }
}

@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;
  }
}
