/* ==========================================================================
   VBPV — Design system inscriptions 2026/2027
   Couleurs du club : bleu marine + jaune (logo)
   ========================================================================== */

/* --------------------------------------------------------- Points de rupture
   Échelle mobile-first commune à tout le fichier (public + admin) — toute
   nouvelle règle responsive doit réutiliser l'un de ces seuils plutôt qu'en
   introduire un nouveau :
     - mobile               : base, aucune media query
     - mobile-large          : min-width: 480px
     - tablette-portrait     : min-width: 600px
     - tablette-portrait-large : min-width: 760px — EXCEPTION historique :
       gouverne à elle seule ~20 règles du site public (étapes, formulaire,
       stepper, confirmation, tableaux…) ; fusionner ce seuil dans un autre
       demanderait de réécrire tout ce bloc en mobile-first et changerait le
       rendu réel entre 600-760px sur la quasi-totalité du site public pour
       un gain de pure cohérence numérique — jugé non rentable, conservé tel
       quel en connaissance de cause plutôt que par oubli.
     - tablette-paysage      : min-width: 834px
     - desktop               : min-width: 1024px
   Autres exceptions ponctuelles documentées localement à leur usage : 420px
   (réglages fins mobile petit), 700px (seuil JS approximatif de nav-mobile.js,
   pas une largeur de mise en page), 560px sur le fondu .tarifs (seuil mesuré
   sur le contenu réel du tableau, pas un choix de mise en page). */

/* Oswald (variable, poids 200-700) — un seul fichier auto-hébergé (~21 Ko,
   licence OFL dans public/fonts/OFL.txt, pas de CDN tiers) réservé au planning
   des entraînements (titres de jour, horaires, libellés) pour un rendu plus
   « emploi du temps sportif », affirmé. Le reste du site garde les polices
   système habituelles — voir --police-planning ci-dessous, jamais body. */
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('../fonts/oswald-variable.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --police-planning: 'Oswald', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --bleu: #1b3c8f;
  --bleu-fonce: #122a66;
  --bleu-nuit: #0c1d47;
  --jaune: #ffcc00;
  --jaune-fonce: #e6b400;
  --fond: #f4f6fb;
  --carte: #ffffff;
  --encre: #1a2233;
  --encre-douce: #55607a;
  --ligne: #dde3ef;
  --ok: #1e9e5a;
  --erreur: #d43c3c;
  /* Fond/texte des états erreur et avertissement, répétés tels quels à
     plusieurs endroits (info-bulle, pastilles, badges, récap paiement) —
     variabilisés pour n'écrire chaque couleur qu'une fois. */
  --erreur-fond: #fdecec;
  --erreur-texte: #8f2323;
  --avertissement-fond: #fff3c4;
  --avertissement-texte: #7a6200;
  --rayon: 14px;
  --ombre: 0 6px 24px rgba(18, 42, 102, 0.10);
  --ombre-forte: 0 12px 40px rgba(18, 42, 102, 0.18);
  /* Teintes bleu-clair réutilisées telles quelles à de nombreux endroits
     (fond de champ, survol/actif) — variabilisées pour n'écrire chaque
     couleur qu'une fois plutôt que de reprendre chaque règle une par une. */
  --surface-douce: #fbfcff;
  --surface-teinte: #eef3ff;
  /* Texte adouci sur le fond bleu nuit du bandeau d'accueil (.heros) —
     deux teintes proches mais distinctes (sous-titre plus lisible, note en
     dessous plus discrète), toutes deux variabilisées pour ne plus être
     de simples hex isolés dans les règles qui les utilisent. */
  --hero-texte-douce: #d4ddf6;
  --hero-texte-discrete: #b9c6ec;
  /* Dégradé des lignes/cartes sélectionnées (sélection multiple, admin) —
     configurable dans Paramètres, voir admin.js. */
  --selection-debut: #cfe0ff;
  --selection-fin: #fff3c4;
}

* { box-sizing: border-box; }
/* L'attribut hidden doit toujours l'emporter, même sur les éléments avec
   une classe qui fixe son propre display (ex. .btn { display: inline-flex }
   a la même spécificité que la règle [hidden] du navigateur, et gagne car
   chargée après elle) — sinon `el.hidden = true` reste sans effet visuel. */
[hidden] { display: none !important; }

/* L'en-tête est sticky (position: sticky, top: 0) : sans cette marge, un
   lien d'ancre (#tarifs, #contact…) fait défiler la section pile sous
   l'en-tête, qui cache alors son titre. scroll-padding-top réserve l'espace
   de la hauteur de l'en-tête (~72px large écran, ~107px quand la nav passe
   à la ligne sur mobile) + une marge confortable. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
}
@media (max-width: 700px) {
  html { scroll-padding-top: 128px; }
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  background: var(--fond);
  color: var(--encre);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Footer toujours collé en bas, même sur les pages courtes */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main { flex: 1 0 auto; width: 100%; }
main[hidden] { display: none; }

img { max-width: 100%; }

a { color: var(--bleu); }

/* ------------------------------------------------------------------ En-tête */
.entete {
  background: linear-gradient(135deg, var(--bleu-fonce) 0%, var(--bleu) 70%);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 50;
  box-shadow: var(--ombre);
}

.entete__inner {
  max-width: 1100px;
  margin: 0 auto;
  /* env(safe-area-inset-*) vaut 0 sur un écran sans encoche/coins arrondis
     (Android, desktop…) : ce padding ne change donc rien ailleurs que sur un
     iPhone à encoche/Dynamic Island, avec viewport-fit=cover côté HTML. */
  padding: calc(10px + env(safe-area-inset-top, 0px)) calc(14px + env(safe-area-inset-right, 0px)) 10px calc(14px + env(safe-area-inset-left, 0px));
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.entete__marque {
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
  border-radius: 8px;
  transition: opacity 0.15s;
  min-width: 0;
}
.entete__marque:hover { opacity: 0.88; }
.entete__marque:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.entete__logo { width: 40px; height: 40px; object-fit: contain; flex: none; }
@media (min-width: 480px) {
  .entete__logo { width: 48px; height: 48px; }
}
@media (min-width: 834px) {
  .entete__logo { width: 62px; height: 62px; }
}

.entete__titre {
  margin: 0;
  font-weight: 800;
  font-size: clamp(0.82rem, 3.2vw, 1.05rem);
  letter-spacing: 0.01em;
  line-height: 1.25;
  min-width: 0;
}
.entete__titre small { display: block; font-weight: 500; color: #c9d4f2; font-size: clamp(0.68rem, 2.4vw, 0.78rem); }

.entete__nav { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }

/* Bouton hamburger : masqué sur grand écran, seule la nav classique s'affiche */
.entete__hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  margin-left: auto;
  width: 44px;
  height: 44px;
  background: none;
  border: none;
  border-radius: 8px;
  color: #fff;
  font-size: 1.4rem;
  cursor: pointer;
  flex: none;
}
.entete__hamburger:hover { background: rgba(255, 255, 255, 0.14); }

/* Mode « compact » : basculé en JS (nav-mobile.js) dès que la nav ne tiendrait
   plus sur une seule ligne à la largeur actuelle — pas un seuil fixe en px,
   ça s'adapte au nombre de liens propre à chaque page. Le panneau reste
   toujours en display:flex (jamais none) et s'anime via max-height/opacity :
   c'est ce qui permet une ouverture/fermeture douce plutôt qu'un flash. */
.entete--compacte .entete__inner { flex-wrap: wrap; }
.entete--compacte .entete__hamburger { display: flex; }
.entete--compacte .entete__nav {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  gap: 3px;
  order: 3;
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  padding: 0;
  visibility: hidden;
  transition: max-height 0.28s ease, opacity 0.2s ease, padding 0.28s ease, visibility 0s linear 0.28s;
}
.entete--compacte .entete__nav--ouverte {
  max-height: 480px;
  opacity: 1;
  padding: 10px 0 6px;
  visibility: visible;
  transition: max-height 0.28s ease, opacity 0.22s ease 0.02s, padding 0.28s ease;
}
.entete--compacte .entete__lien { padding: 12px 14px; font-size: 0.92rem; width: 100%; text-align: left; border-radius: 10px; }

.entete__lien {
  color: #e8edfa;
  text-decoration: none;
  font-weight: 600;
  font-size: 0.9rem;
  padding: 8px 14px;
  border-radius: 999px;
  transition: background 0.2s;
}
/* Certains « liens » de la nav sont des <button> (ex. export CSV filtré) :
   on annule les styles par défaut du navigateur pour qu'ils soient identiques
   aux vrais liens <a> voisins. */
button.entete__lien {
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
}
button.entete__lien.entete__lien--actif { background: var(--jaune); }
.entete__lien:hover { background: rgba(255, 255, 255, 0.14); }
.entete__lien--actif { background: var(--jaune); color: var(--bleu-nuit); }
.entete__lien--actif:hover { background: var(--jaune-fonce); }
.entete__lien--danger { background: var(--erreur); color: #fff; }
.entete__lien--danger:hover { background: #b32e2e; }

/* Menu déroulant générique (bouton Export PDF, Télécharger la sélection, et
   le menu "⋮ Actions" par ligne du tableau admin — voir menuActionsFiche). */
.menu-deroulant { position: relative; }
.menu-deroulant__options {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--carte);
  border-radius: 12px;
  box-shadow: var(--ombre-forte);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 260px;
  /* Doit dépasser 100 : #feuille-filtres (et toute .modale-fond) garde ce
     z-index même quand position:static (item flex, voir positionnerMenuActions
     dans admin.js), sans quoi ce menu passerait dessous. */
  z-index: 150;
}
.menu-deroulant__options button, .menu-deroulant__options a {
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--encre);
  background: none;
  border: none;
  text-align: left;
  text-decoration: none;
  padding: 10px 12px;
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
  display: block;
}
.menu-deroulant__options button:hover, .menu-deroulant__options a:hover { background: var(--fond); }

/* Tiroir (panneau latéral) : variante de .modale-fond pour le menu ☰ de
   l'en-tête admin — un vrai panneau qui glisse depuis le bord droit plutôt
   qu'une carte flottante sous le bouton (voir .menu-deroulant ci-dessus,
   réservé aux petits menus d'actions). Réutilise le fond assombri et la pile
   de modales de .modale-fond : seuls le placement et l'anim changent. */
.modale-fond.modale-fond--tiroir { justify-content: flex-end; align-items: stretch; padding: 0; }
.tiroir {
  width: min(320px, 100%);
  height: 100%;
  background: var(--carte);
  box-shadow: var(--ombre-forte);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.28s ease;
}
.modale-fond--tiroir.modale-fond--ouverte .tiroir { transform: translateX(0); }
.tiroir__entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: none;
  padding: 18px 20px;
  background: linear-gradient(135deg, var(--bleu-fonce) 0%, var(--bleu) 70%);
  color: #fff;
}
.tiroir__titre { font-weight: 800; font-size: 1.05rem; }
.tiroir__fermer {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  background: none;
  border: none;
  border-radius: 8px;
  color: #fff;
  font-size: 1.1rem;
  cursor: pointer;
}
.tiroir__fermer:hover { background: rgba(255, 255, 255, 0.16); }
.tiroir__corps { padding: 10px; display: flex; flex-direction: column; gap: 2px; overflow-y: auto; }
.tiroir__pied { flex: none; padding: 10px; border-top: 1.5px solid var(--ligne); }
.tiroir__lien {
  display: flex;
  align-items: center;
  gap: 10px;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--encre);
  background: none;
  border: none;
  text-decoration: none;
  text-align: left;
  width: 100%;
  padding: 13px 14px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.15s;
}
.tiroir__lien:hover { background: var(--surface-douce); }
.tiroir__lien--danger { color: var(--erreur); }
.tiroir__lien--danger:hover { background: rgba(198, 40, 40, 0.08); }

/* Feuille (bottom sheet) : même principe que .tiroir (variante de
   .modale-fond réutilisant le fond assombri et la pile de modales) mais
   ancrée en bas plutôt qu'à droite — utilisée pour les filtres sur mobile
   (voir #feuille-filtres dans admin.html). Neutralisée en simple bloc dans
   la page dès que l'écran a la place d'afficher les filtres directement
   (voir @media dans la section barre-recherche). */
.modale-fond.modale-fond--feuille { justify-content: center; align-items: flex-end; padding: 0; }
.feuille {
  width: 100%;
  max-height: 85vh;
  background: var(--carte);
  border-radius: 18px 18px 0 0;
  box-shadow: var(--ombre-forte);
  display: flex;
  flex-direction: column;
  transform: translateY(100%);
  transition: transform 0.28s ease;
}
.modale-fond--feuille.modale-fond--ouverte .feuille { transform: translateY(0); }
.feuille__entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: none;
  padding: 16px 18px;
  border-bottom: 1.5px solid var(--ligne);
}
.feuille__titre { font-weight: 800; font-size: 1.05rem; color: var(--bleu-fonce); }
.feuille__fermer {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  background: var(--surface-douce);
  border: none;
  border-radius: 8px;
  color: var(--encre-douce);
  font-size: 1.1rem;
  cursor: pointer;
}
.feuille__fermer:hover { background: var(--surface-teinte); }
.feuille__corps {
  padding: 14px 18px calc(18px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* --------------------------------------------------------------------- Héros */
.heros {
  background:
    radial-gradient(1000px 400px at 85% -20%, rgba(255, 204, 0, 0.22), transparent 60%),
    linear-gradient(135deg, var(--bleu-nuit) 0%, var(--bleu) 100%);
  color: #fff;
  padding: 64px 20px 84px;
  text-align: center;
  /* Arrondi du bas via border-radius : contrairement à clip-path, il ne
     provoque pas de bug de rendu quand les boutons s'animent au survol. */
  border-radius: 0 0 50% 50% / 0 0 42px 42px;
}

.heros h1 {
  margin: 0 0 10px;
  font-size: clamp(1.7rem, 4.5vw, 2.7rem);
  font-weight: 900;
  letter-spacing: 0.01em;
}

.heros__sous {
  max-width: 620px;
  margin: 0 auto 30px;
  color: var(--hero-texte-douce);
  font-size: 1.06rem;
}

.heros .btn--jaune { font-size: 1.1rem; padding: 16px 34px; }
.heros__note { margin-top: 14px; font-size: 0.88rem; color: var(--hero-texte-discrete); }

/* ------------------------------------------------------------------- Boutons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: none;
  cursor: pointer;
  text-decoration: none;
  font-weight: 800;
  font-size: 1rem;
  font-family: inherit;
  padding: 13px 26px;
  border-radius: 999px;
  transition: transform 0.15s, box-shadow 0.15s, background 0.2s;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--ombre-forte); }
.btn:active { transform: translateY(0); }

.btn--jaune { background: var(--jaune); color: var(--bleu-nuit); box-shadow: 0 6px 20px rgba(255, 204, 0, 0.35); }
.btn--jaune:hover { background: var(--jaune-fonce); }

.btn--bleu { background: var(--bleu); color: #fff; }
.btn--bleu:hover { background: var(--bleu-fonce); }

.btn--contour {
  background: transparent;
  color: var(--bleu);
  border: 2px solid var(--bleu);
}
.btn--contour:hover { background: var(--bleu); color: #fff; }

.btn--danger { background: transparent; color: var(--erreur); border: 2px solid var(--erreur); }
.btn--danger:hover { background: var(--erreur); color: #fff; }

.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }

/* ----------------------------------------------------------------- Structure */
.conteneur { max-width: 1100px; margin: 0 auto; padding: 0 20px; }
.conteneur--etroit { max-width: 860px; }

/* Pages « pleine largeur » (espace admin) : sous tablette-paysage, la marge
   ne sert à rien (plein écran) ; au-delà, on exploite l'écran à ~94 % pour
   limiter les marges blanches, avec un plafond sur très grands écrans. */
.page-large .entete__inner,
.page-large .conteneur { max-width: 100%; }
@media (min-width: 834px) {
  .page-large .entete__inner,
  .page-large .conteneur { max-width: min(94%, 1900px); }
}

.section { padding: 46px 0; }

.section__titre {
  font-size: 1.5rem;
  font-weight: 900;
  color: var(--bleu-fonce);
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.section__titre::before {
  content: "";
  width: 8px;
  height: 28px;
  border-radius: 4px;
  background: var(--jaune);
  flex: none;
}
.section__sous { color: var(--encre-douce); margin: 0 0 24px; }

.carte {
  background: var(--carte);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 26px 28px;
}

/* ------------------------------------------------------------ Étapes (accueil) */
.etapes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: -46px; position: relative; z-index: 2; }

/* Encadré « venez d'abord essayer » (index.html). Il s'intercale entre le
   bandeau et les 3 étapes : c'est donc LUI qui doit remonter par-dessus
   l'arrondi du bandeau, sinon la remontée de .etapes vient le recouvrir. */
.accroche-essai { margin-top: -46px; margin-bottom: 26px; position: relative; z-index: 2; }
.accroche-essai + .etapes { margin-top: 0; }

.etape { text-align: left; }
.etape__num {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--bleu);
  color: var(--jaune);
  font-weight: 900;
  font-size: 1.15rem;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 12px;
}
.etape h2 { margin: 0 0 6px; font-size: 1.05rem; color: var(--bleu-fonce); }
.etape p { margin: 0; color: var(--encre-douce); font-size: 0.93rem; }

/* ------------------------------------------------------------------ Tarifs */
.tarifs { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
.tarifs th {
  background: var(--bleu);
  color: #fff;
  text-align: left;
  padding: 12px 16px;
  font-weight: 700;
}
.tarifs th:first-child { border-radius: 10px 0 0 0; }
.tarifs th:last-child { border-radius: 0 10px 0 0; }
.tarifs td { padding: 11px 16px; border-bottom: 1px solid var(--ligne); }
.tarifs tr:nth-child(even) td { background: #f8faff; }
.tarifs td:last-child { font-weight: 800; color: var(--bleu-fonce); white-space: nowrap; }

/* Indice visuel de défilement horizontal (fondu sur le bord droit) — même
   motif que .carte:has(> .table-admin)::after en admin. Retiré à partir de
   560px, largeur à laquelle le tableau tient sans déborder (mesuré). */
@media (max-width: 560px) {
  .carte:has(> .tarifs) { position: relative; }
  .carte:has(> .tarifs)::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 28px;
    background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.08));
    pointer-events: none;
    border-radius: 0 var(--rayon) var(--rayon) 0;
  }
}

.badge-maillot {
  display: inline-block;
  background: var(--avertissement-fond);
  color: var(--avertissement-texte);
  border-radius: 6px;
  font-size: 0.78rem;
  font-weight: 700;
  padding: 1px 8px;
  margin-left: 6px;
  white-space: nowrap;
}

/* ---------------------------------------------- Planning des entraînements */
/* Pastilles équipes cliquables : filtre à sélection multiple qui remplace
   l'ancien menu déroulant « Afficher : ». Non cochée = même habillage clair
   que la légende gymnases ; cochée = bascule sur la couleur pleine de
   l'équipe pour qu'une sélection active saute aux yeux dans la liste. */
.planning-chips-bloc { margin-bottom: 16px; }
.planning-chips-bloc__aide {
  display: block;
  color: var(--bleu-fonce);
  font-weight: 700;
  font-size: 0.9rem;
  margin-bottom: 8px;
}
.planning-chips-liste { display: flex; flex-wrap: wrap; gap: 8px; }
.planning-chip { display: inline-flex; position: relative; cursor: pointer; }
.planning-chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.planning-chip__pastille {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 8px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.84rem;
  color: var(--encre);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--couleur, var(--bleu)) 22%, white),
    color-mix(in srgb, var(--couleur, var(--bleu)) 7%, white));
  border: 1.5px solid color-mix(in srgb, var(--couleur, var(--bleu)) 45%, white);
  transition: all 0.15s;
}
.planning-chip__puce {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  flex: none;
  background: linear-gradient(135deg, var(--couleur, var(--bleu)), color-mix(in srgb, var(--couleur, var(--bleu)) 65%, black));
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15);
}
.planning-chip input:checked + .planning-chip__pastille {
  background: var(--couleur, var(--bleu));
  border-color: var(--couleur, var(--bleu));
  color: var(--texte-couleur, #fff);
}
.planning-chip input:focus-visible + .planning-chip__pastille { box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.3); }

/* Légende : chaque gymnase est une pastille pleine teinte de sa couleur
   (fond + bordure dégradés, pas juste un petit carré à côté d'un texte
   neutre) — le rendu se rapproche du bandeau de couleur des cartes du
   planning, pour que le lien « pastille ↔ créneau » saute aux yeux. */
.planning-legende {
  background: #f8faff;
  border: 1.5px solid var(--ligne);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 20px;
}
.planning-legende__aide {
  display: block;
  color: var(--encre-douce);
  font-weight: 700;
  font-size: 0.82rem;
  margin-bottom: 10px;
}
.planning-legende__liste { display: flex; flex-wrap: wrap; gap: 8px; }

.planning-grille {
  display: grid;
  /* Mobile-first : 1 seule colonne (le jour actif, voir les onglets plus
     bas), élargie par paliers jusqu'au nombre de jours réellement affichés
     (1 à 7, ex. dimanche seulement si des créneaux y sont programmés) —
     fixé en JS via --nb-jours ; 6 par défaut si le script n'a pas encore
     tourné. */
  grid-template-columns: 1fr;
  gap: 14px;
}
@media (min-width: 600px) {
  .planning-grille { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 834px) {
  .planning-grille { grid-template-columns: repeat(var(--nb-jours, 6), 1fr); }
}
.planning-jour__titre {
  /* Redondant avec l'onglet actif tant qu'un seul jour est visible à la fois
     (mobile, voir plus bas) — réaffiché dès qu'il y a au moins 2 colonnes. */
  display: none;
  margin: 0 0 10px;
  font-family: var(--police-planning);
  font-size: 1.12rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--bleu-fonce);
  text-align: center;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--jaune);
}
.planning-jour__creneaux { display: flex; flex-direction: column; gap: 10px; }

/* Carte allégée : léger dégradé de la couleur du gymnase vers du blanc (très
   atténué — beaucoup plus clair que le dégradé des pastilles/légende — pour
   distinguer les créneaux d'un coup d'œil sans jamais nuire à la lisibilité
   du texte) + bande de couleur pleine à gauche (même logique que les cartes
   de l'éditeur admin). Épaisseur réglable par l'admin (défaut 7px, voir
   --epaisseur-bande-planning posée sur #planning-grille). */
.planning-creneau {
  position: relative;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--couleur, var(--bleu)) 10%, white),
    white 65%);
  border: 1px solid var(--ligne);
  border-radius: 10px;
  padding: 9px 12px 10px calc(var(--epaisseur-bande-planning, 7px) + 9px);
  box-shadow: var(--ombre);
  transition: transform 0.15s, box-shadow 0.15s;
}
.planning-creneau:hover { transform: translateY(-2px); box-shadow: var(--ombre-forte); }
.planning-creneau::before {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: var(--epaisseur-bande-planning, 7px);
  border-radius: 10px 0 0 10px;
  background: var(--couleur, var(--bleu));
}
.planning-jour__vide { text-align: center; color: var(--encre-douce); font-size: 0.85rem; padding: 14px 0; opacity: 0.6; }
.planning-creneau__horaire {
  font-family: var(--police-planning);
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  color: var(--bleu-fonce);
  margin-bottom: 2px;
}
.planning-creneau__libelle {
  font-family: var(--police-planning);
  font-weight: 600;
  font-size: 1.04rem;
  letter-spacing: 0.01em;
  color: var(--encre);
  line-height: 1.22;
}
.planning-creneau__lieu { font-size: 0.76rem; color: var(--encre-douce); margin-top: 4px; }

/* Onglets « un jour à la fois » : mobile-first, actifs par défaut (1 seule
   colonne, voir .planning-grille plus haut) où faire défiler 7 jours d'un
   coup serait long et peu lisible ; masqués dès qu'il y a la place pour au
   moins 2 colonnes (voir media query plus bas). */
.planning-jours-onglets {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 6px;
  margin-bottom: 14px;
}
.planning-jour[data-jour] { display: none; }
.planning-jour[data-jour].planning-jour--actif { display: block; }
.planning-jour-onglet {
  flex: none;
  font-family: var(--police-planning);
  font-weight: 600;
  font-size: 0.86rem;
  letter-spacing: 0.02em;
  color: var(--encre-douce);
  background: var(--carte);
  border: 1.5px solid var(--ligne);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.15s;
}
.planning-jour-onglet:hover { border-color: var(--bleu); color: var(--bleu); }
.planning-jour-onglet--actif { background: var(--bleu); color: #fff; border-color: var(--bleu); }
.planning-jour-onglet--actif:hover { color: #fff; }

/* Dès qu'il y a la place pour au moins 2 colonnes : tous les jours
   redeviennent visibles (plus besoin de les choisir un par un). */
@media (min-width: 600px) {
  .planning-jours-onglets { display: none; }
  .planning-jour[data-jour] { display: block; }
  .planning-jour__titre { display: block; }
}

/* ------------------------------------------------------------- Listes doc */
.liste-docs { list-style: none; padding: 0; margin: 0; }
.liste-docs li {
  padding: 10px 0 10px 34px;
  position: relative;
  border-bottom: 1px dashed var(--ligne);
}
.liste-docs li:last-child { border-bottom: none; }
.liste-docs li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 9px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: #e3f4ea;
  color: var(--ok);
  font-weight: 900;
  font-size: 0.82rem;
  display: flex; align-items: center; justify-content: center;
}

.grille-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.encart-contact {
  background: linear-gradient(135deg, var(--bleu-fonce), var(--bleu));
  color: #fff;
  border-radius: var(--rayon);
  padding: 26px 28px;
}
.encart-contact h3 { margin: 0 0 10px; }
.encart-contact a { color: var(--jaune); font-weight: 700; text-decoration: none; }

/* -------------------------------------------------------------- Pied de page */
.pied {
  margin-top: auto;
  background: var(--bleu-nuit);
  color: #9fb0d8;
  text-align: center;
  padding: 26px 20px;
  font-size: 0.88rem;
  flex-shrink: 0;
}
.pied a { color: #c7d3ee; text-decoration: underline; }
.pied a:hover { color: #fff; }
.pied__liens { display: block; margin-top: 6px; }
.pied__liens a { margin: 0 6px; }

/* ==========================================================================
   FORMULAIRE
   ========================================================================== */
.stepper {
  display: flex;
  justify-content: center;
  gap: 0;
  margin: 30px auto 26px;
  max-width: 720px;
}
.stepper__etape {
  flex: 1;
  text-align: center;
  position: relative;
  color: var(--encre-douce);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
.stepper__etape:hover::before {
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.15);
}
.stepper__etape::before {
  content: attr(data-num);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  margin: 0 auto 6px;
  border-radius: 50%;
  background: #e6eaf5;
  color: var(--encre-douce);
  font-weight: 800;
  border: 2px solid transparent;
  transition: all 0.2s;
}
.stepper__etape::after {
  content: "";
  position: absolute;
  top: 18px;
  left: calc(50% + 24px);
  width: calc(100% - 48px);
  height: 3px;
  border-radius: 2px;
  background: #e6eaf5;
}
.stepper__etape:last-child::after { display: none; }

.stepper__etape--active { color: var(--bleu-fonce); }
.stepper__etape--active::before { background: var(--jaune); color: var(--bleu-nuit); border-color: var(--jaune-fonce); }

.stepper__etape--faite { color: var(--bleu); }
.stepper__etape--faite::before { content: "✓"; background: var(--bleu); color: #fff; }
.stepper__etape--faite::after { background: var(--bleu); }

.form-panneau { display: none; }
.form-panneau--visible { display: block; animation: apparait 0.25s ease; }

@keyframes apparait { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

fieldset { border: none; padding: 0; margin: 0 0 8px; min-width: 0; }

legend {
  font-weight: 800;
  color: var(--bleu-fonce);
  font-size: 1.02rem;
  padding: 0;
  margin-bottom: 12px;
}

.champs { display: grid; grid-template-columns: repeat(12, 1fr); gap: 14px 16px; }

.champ { display: flex; flex-direction: column; gap: 5px; }
.champ--12 { grid-column: span 12; }
.champ--8 { grid-column: span 8; }
.champ--6 { grid-column: span 6; }
.champ--4 { grid-column: span 4; }
.champ--3 { grid-column: span 3; }

.champ label { font-weight: 600; font-size: 0.88rem; color: var(--encre); }
.champ label .req { color: var(--erreur); }
.champ .aide { font-size: 0.78rem; color: var(--encre-douce); }

/* .entree : même apparence que .champ input/select/textarea, mais
   utilisable sans le wrapper .champ (label + gap) — pour les champs isolés
   d'une liste compacte (ex. suivi des règlements, lignes de coût). */
.champ input, .champ select, .champ textarea, .entree {
  font: inherit;
  padding: 11px 13px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
  color: var(--encre);
  transition: border-color 0.15s, box-shadow 0.15s;
  width: 100%;
}
.champ input:focus, .champ select:focus, .champ textarea:focus, .entree:focus {
  outline: none;
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.14);
  background: var(--carte);
}
/* Champ en erreur : bordure rouge + clignotement pour attirer l'œil */
@keyframes clignote-erreur {
  0%, 100% { box-shadow: 0 0 0 0 rgba(212, 60, 60, 0); }
  20%, 60% { box-shadow: 0 0 0 5px rgba(212, 60, 60, 0.35); }
  40%, 80% { box-shadow: 0 0 0 0 rgba(212, 60, 60, 0); }
}
.invalide,
.champ input.invalide, .champ select.invalide {
  border-color: var(--erreur) !important;
  background: #fff7f7;
  animation: clignote-erreur 1.6s ease 2;
}
.champ .message-erreur { color: var(--erreur); font-size: 0.78rem; display: none; }
.champ input.invalide ~ .message-erreur, .champ select.invalide ~ .message-erreur { display: block; }

/* Bouton "œil" afficher/masquer un mot de passe (voir mdp-toggle.js) —
   partout où l'on tape un mot de passe, le champ est enveloppé dans ce
   conteneur plutôt que d'ajouter le bouton une fois par page. */
.champ-mdp { position: relative; }
.champ-mdp input { padding-right: 54px; }
.champ-mdp__oeil {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: 6px;
  color: var(--encre-douce);
  cursor: pointer;
}
.champ-mdp__oeil:hover { background: var(--surface-douce); color: var(--bleu); }
/* Champ nationalité : l'input est encapsulé dans .pays-select (pour la liste
   déroulante), donc plus un sibling direct du message d'erreur — on rattrape
   via :has(). */
.champ .pays-select:has(input.invalide) ~ .message-erreur { display: block; }

/* Sélecteur recherchable (nationalité) : liste flottante sous le champ */
.pays-select { position: relative; }
.pays-select__liste {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  background: var(--carte);
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  box-shadow: var(--ombre-forte);
  margin: 0;
  padding: 6px;
  list-style: none;
  max-height: 240px;
  overflow-y: auto;
}
.pays-select__liste li {
  padding: 9px 12px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 0.92rem;
}
.pays-select__liste li:hover,
.pays-select__liste li.pays-select__option--actif { background: var(--fond); color: var(--bleu-fonce); }
.champ .date-triple--invalide ~ .message-erreur { display: block; }

/* Sélecteur recherchable (commune) : même recette que .pays-select — 30
   communes de l'agglo par défaut, puis recherche live geo.api.gouv.fr dès 2
   caractères tapés (voir communes.js). */
.champ .commune-select:has(input.invalide) ~ .message-erreur { display: block; }
.commune-select { position: relative; }
.commune-select__liste {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  background: var(--carte);
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  box-shadow: var(--ombre-forte);
  margin: 0;
  padding: 6px;
  list-style: none;
  max-height: 240px;
  overflow-y: auto;
}
.commune-select__liste li {
  padding: 9px 12px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 0.92rem;
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.commune-select__liste li small { color: var(--encre-douce); }
.commune-select__liste li:hover,
.commune-select__liste li.commune-select__option--actif { background: var(--fond); color: var(--bleu-fonce); }

/* --------------------------------------- Sélecteur de date jour / mois / année */
.date-triple {
  display: grid;
  grid-template-columns: 1fr 1.5fr 1.2fr;
  gap: 8px;
}
.date-triple select {
  font: inherit;
  padding: 11px 8px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
  color: var(--encre);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
  width: 100%;
}
.date-triple select:focus {
  outline: none;
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.14);
  background: var(--carte);
}
.date-triple select:hover { border-color: var(--bleu); }

/* Groupe de pastilles radio obligatoire non renseigné */
.choix-cartes--invalide .choix-carte span {
  border-color: var(--erreur);
  background: #fff7f7;
  animation: clignote-erreur 1.6s ease 2;
}

/* Case à cocher obligatoire manquante */
.case--invalide {
  border-color: var(--erreur) !important;
  background: #fff7f7;
  animation: clignote-erreur 1.6s ease 2;
}

/* Cartes radio (type d'inscription, sexe…) */
.choix-cartes { display: flex; gap: 12px; flex-wrap: wrap; }
.choix-carte { position: relative; }
.choix-carte input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.choix-carte span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border: 2px solid var(--ligne);
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--encre-douce);
  background: var(--carte);
  cursor: pointer;
  transition: all 0.15s;
}
.choix-carte input:checked + span {
  border-color: var(--bleu);
  background: var(--bleu);
  color: #fff;
  box-shadow: 0 4px 14px rgba(27, 60, 143, 0.25);
}
.choix-carte input:focus-visible + span { box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.3); }

/* Cases à cocher stylées */
.case {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 13px 16px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  margin-bottom: 10px;
  font-size: 0.93rem;
}
.case:hover { border-color: var(--bleu); }
.case input { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--bleu); flex: none; cursor: pointer; }
.case--cochee { border-color: var(--bleu); background: var(--surface-teinte); }
.case--inline { display: inline-flex; margin: 0 10px 0 0; padding: 8px 14px; }

.info-bulle {
  background: var(--surface-teinte);
  border-left: 4px solid var(--bleu);
  border-radius: 8px;
  padding: 12px 16px;
  font-size: 0.88rem;
  color: var(--bleu-fonce);
  margin: 14px 0;
}
.info-bulle--jaune { background: #fff8de; border-color: var(--jaune-fonce); color: #6d5900; }
.info-bulle--erreur { background: var(--erreur-fond); border-color: var(--erreur); color: var(--erreur-texte); }
.info-bulle--ok { background: #eaf7ef; border-color: var(--ok); color: #145c34; }

/* Pile de notifications flottantes (voir notifier() dans admin.js) — même
   habillage que .info-bulle (pas un nouveau composant), juste posée en fixed
   pour rester visible quelle que soit la page ou la modale ouverte au
   moment où l'action déclenche un message, contrairement aux bannières
   inline (#depot-erreur et consorts) qui ont un emplacement dédié fixe. */
.toast-pile {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 300;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(420px, calc(100vw - 32px));
}
.toast-pile .info-bulle {
  margin: 0;
  box-shadow: var(--ombre-forte);
  cursor: pointer;
}

.categorie-detectee {
  background: linear-gradient(135deg, var(--bleu-fonce), var(--bleu));
  border-radius: 12px;
  color: #fff;
  padding: 18px 22px;
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 18px;
}
.categorie-detectee strong { color: var(--jaune); font-size: 1.2rem; }

/* justify-content:flex-end + margin-right:auto sur le 1er bouton (jamais sur
   un enfant seul) plutôt que justify-content:space-between : avec
   space-between, un bouton secondaire masqué dynamiquement (ex. "Annuler la
   modification" du formulaire créneau, caché hors édition) fait passer le
   bouton principal restant seul tout à GAUCHE — space-between ne pousse rien
   à droite s'il n'y a qu'un seul élément à répartir. Ce réglage reste
   correct dans les deux cas (bouton secondaire visible ou masqué). */
.form-boutons {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid var(--ligne);
}
.form-boutons > :first-child:not(:only-child) { margin-right: auto; }

.separateur { border: none; border-top: 1px solid var(--ligne); margin: 22px 0; }

/* ==========================================================================
   FICHE A4 (page de confirmation — reproduction du PDF)
   ========================================================================== */
.fiche-a4 {
  background: var(--carte);
  width: 100%;
  max-width: 800px;
  margin: 0 auto 30px;
  aspect-ratio: 210 / 297;
  box-shadow: var(--ombre-forte);
  border-radius: 4px;
  padding: 4.2% 4.8%;
  /* Arial en TÊTE, et surtout pas « Helvetica » avant lui : sous Windows,
     demander Helvetica fait souvent remonter une vieille Helvetica héritée
     (Type 1/bitmap, installée par d'anciens logiciels) dont les métriques sont
     fausses. Les glyphes débordent alors sous leur boîte, et la ligne
     pointillée — ancrée en bas de cette boîte — traverse le texte au lieu de
     le souligner (bug remonté depuis un PC Windows). Arial est présent
     partout et métriquement identique à Helvetica : la mise en page reste
     fidèle au PDF officiel, sur tous les systèmes. */
  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
  color: #111;
  font-size: 12px;
  line-height: 1.45;
  overflow: hidden;
}

.fa4-entete { display: flex; align-items: center; gap: 3%; margin-bottom: 4%; }
/* Hauteur commune : les deux logos (rognés au même calibre) paraissent de taille identique */
.fa4-entete img { height: 5.5em; width: auto; max-width: 16%; object-fit: contain; }
.fa4-entete__titre { flex: 1; text-align: center; font-weight: 800; font-size: 1.55em; line-height: 1.3; }

.fa4-bloc-haut { display: flex; gap: 5%; align-items: flex-start; margin-bottom: 3.5%; }
.fa4-types { flex: none; }
.fa4-identite { flex: 1; font-size: 1.25em; font-weight: 600; }

.fa4-case { display: flex; align-items: baseline; gap: 6px; margin: 2px 0; }
.fa4-case__box {
  display: inline-block;
  width: 0.85em; height: 0.85em;
  border: 1.5px solid #111;
  border-radius: 2px;
  flex: none;
  position: relative;
  top: 1px;
  text-align: center;
  line-height: 0.8em;
  font-size: 0.9em;
  font-weight: 900;
}
.fa4-case__box--cochee::before { content: "✕"; position: relative; top: -0.12em; }

.fa4-ligne { margin: 1.6% 0; display: flex; gap: 4px; align-items: baseline; flex-wrap: wrap; }
.fa4-ligne b { font-weight: 700; }

.fa4-valeur {
  flex: 1;
  min-width: 60px;
  /* Ligne pointillée dessinée (identique à l'écran et à l'impression,
     contrairement à border dotted que les navigateurs rendent différemment en PDF) */
  background-image: repeating-linear-gradient(to right, #777 0 2px, transparent 2px 6px);
  background-size: 100% 1.5px;
  background-position: left bottom;
  background-repeat: no-repeat;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
  font-weight: 600;
  color: var(--bleu-fonce);
  /* padding-bottom : la ligne étant ancrée en bas de la boîte de padding, ces
     3px la maintiennent sous les jambages même si la police rendue est un peu
     plus haute que prévu — ceinture et bretelles avec la pile de polices
     ci-dessus, pour ne plus jamais barrer le texte. */
  padding: 0 4px 3px;
  min-height: 1.2em;
}
.fa4-valeur--fixe { flex: none; }

.fa4-titre-section { text-align: center; font-weight: 800; margin: 3.5% 0 2%; }

.fa4-contacts { display: flex; gap: 3%; }
.fa4-contact { flex: 1; border: 1.5px solid #111; padding: 2% 2.5%; }
.fa4-contact__titre { text-align: center; text-decoration: underline; font-weight: 700; margin-bottom: 3%; }

.fa4-note { font-size: 0.78em; margin: 1.5% 0 0; color: #333; }

.fa4-signature { margin-top: 3%; font-style: italic; text-align: center; font-size: 0.92em; }
.fa4-cachet {
  margin: 2% auto 0;
  max-width: 65%;
  border: 2px solid var(--ok);
  color: var(--ok);
  border-radius: 8px;
  text-align: center;
  padding: 1.5% 3%;
  font-weight: 700;
  font-style: normal;
  font-size: 0.9em;
  background: #f2fbf6;
}

/* Page 2 de la fiche : liste des pièces + tableau des cotisations */
.fiche-a4--page2 { font-size: 11px; }

/* Formulaire de licence fédérale (mutation) : image du vrai formulaire FFVolley
   en fond, valeurs superposées en position absolue (mêmes coordonnées que le
   PDF généré par pdf-licence-federale.js) — jamais de recréation de la mise
   en page, la fédération exige un document visuellement identique au sien. */
.fiche-federale {
  position: relative;
  width: 100%;
  max-width: 800px;
  margin: 0 auto 30px;
  aspect-ratio: 210 / 297;
  box-shadow: var(--ombre-forte);
  border-radius: 4px;
  overflow: hidden;
  /* Même pile qu'en .fiche-a4, et pour la même raison (voir le commentaire
     là-bas) : Arial d'abord, jamais Helvetica avant lui. */
  font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}
.fiche-federale img { display: block; width: 100%; height: 100%; object-fit: fill; }
.fa4f-valeur {
  position: absolute;
  color: var(--bleu);
  font-weight: 700;
  font-size: clamp(6px, 1.05vw, 9.5px);
  white-space: nowrap;
  transform: translateY(-85%);
}
.fa4f-actions { text-align: center; margin-top: 10px; }
.fa4f-astuce { font-size: 0.85em; color: var(--encre-douce); margin: 8px 0 0; }

/* Agrandissement du formulaire fédéral dans la modale : le clone du même
   bloc .fiche-federale (mêmes coordonnées, voir fiche.js) est forcé à une
   largeur fixe plus grande que l'écran — le pincer-zoomer natif et le
   défilement de ce conteneur permettent de l'explorer en détail, sans
   toucher au positionnement en % des champs superposés. */
.fa4f-modale-scroll { overflow: auto; -webkit-overflow-scrolling: touch; }
.fa4f-modale-scroll .fiche-federale { width: 900px; max-width: none; margin: 0 auto; box-shadow: none; }

.fa4f-croix {
  position: absolute;
  color: #111;
  font-weight: 900;
  line-height: 1;
  font-size: clamp(7px, 1.3vw, 12px);
  transform: translate(-50%, -50%);
}

.fa4-liste { margin: 1% 0 2%; padding-left: 5%; }
.fa4-liste li { margin: 0.6% 0; }

/* --------------------------------------------------------- Confirmation page */
.barre-confirmation {
  position: sticky;
  bottom: 0;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--ligne);
  padding: 14px 20px;
  display: flex;
  justify-content: center;
  gap: 14px;
  z-index: 40;
  box-shadow: 0 -6px 24px rgba(18, 42, 102, 0.10);
}

/* Overlay d'envoi au secrétariat */
.overlay-envoi {
  position: fixed;
  inset: 0;
  background: rgba(12, 29, 71, 0.82);
  backdrop-filter: blur(5px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
}
.overlay-envoi[hidden] { display: none; }
.overlay-envoi__boite {
  text-align: center;
  color: #fff;
  padding: 30px;
  max-width: 420px;
}
.overlay-envoi__boite h3 { margin: 20px 0 8px; font-size: 1.25rem; }
.overlay-envoi__boite p { margin: 0; color: #c9d4f2; font-size: 0.95rem; }

.spinner {
  width: 66px;
  height: 66px;
  margin: 0 auto;
  border-radius: 50%;
  border: 5px solid rgba(255, 255, 255, 0.2);
  border-top-color: var(--jaune);
  animation: tourne 0.9s linear infinite;
  position: relative;
}
.spinner::after {
  content: "🏐";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  animation: tourne 0.9s linear infinite reverse; /* le ballon reste droit */
}
@keyframes tourne { to { transform: rotate(360deg); } }

.ecran-succes { text-align: center; padding: 60px 20px; }
.ecran-succes__icone {
  width: 84px; height: 84px;
  margin: 0 auto 20px;
  border-radius: 50%;
  background: #e3f4ea;
  color: var(--ok);
  font-size: 2.6rem;
  display: flex; align-items: center; justify-content: center;
}
.ecran-succes h2 { color: var(--bleu-fonce); margin: 0 0 8px; }
.ecran-succes .numero {
  display: inline-block;
  background: var(--bleu);
  color: var(--jaune);
  font-weight: 900;
  font-size: 1.25rem;
  letter-spacing: 0.06em;
  border-radius: 10px;
  padding: 10px 24px;
  margin: 14px 0 20px;
}

/* --------------------------------------------------- Dépôt de documents */
.fichier-liste { list-style: none; padding: 0; margin: 16px 0 0; max-width: 100%; }
.fichier-liste li {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--carte);
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 8px;
  font-size: 0.92rem;
  max-width: 100%;
  overflow: hidden;
}
/* min-width:0 indispensable : sans lui, le nom long pousse la ligne hors du cadre */
.fichier-liste .fichier-nom { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
input.fichier-nom { cursor: text; }
input.fichier-nom:hover { border-color: var(--ligne) !important; }
input.fichier-nom:focus { outline: none; border-color: var(--bleu) !important; background: var(--surface-douce) !important; }

/* Lignes de dépôt : une par type de pièce */
.piece-ligne {
  display: flex;
  align-items: center;
  gap: 14px;
  border: 2px dashed var(--ligne);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.15s;
  background: var(--surface-douce);
  max-width: 100%;
}
.piece-ligne:hover, .piece-ligne--survol { border-color: var(--bleu); background: var(--surface-teinte); }
.piece-ligne--remplie { border-style: solid; border-color: var(--ok); background: #f2fbf6; }
.piece-ligne__icone { font-size: 1.6rem; flex: none; }
.piece-ligne__infos { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.piece-ligne__infos small { color: var(--encre-douce); }
.piece-ligne__fichier {
  font-size: 0.85rem; font-weight: 600; color: var(--ok);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; /* flex item : sans ça, min-width:auto empêche la troncature */
}
.piece-ligne__remplacement { font-size: 0.8rem; font-weight: 600; color: #b5820a; }
.piece-ligne__requis { font-size: 0.8rem; font-weight: 700; color: var(--erreur); }
.piece-ligne__action { flex: none; display: flex; align-items: center; gap: 8px; }
.piece-ligne .fichier-retirer {
  background: none; border: none; cursor: pointer; color: var(--erreur); font-size: 1.05rem;
  /* Zone tactile alignée sur le bouton voisin (.btn--mini, min-height: 40px)
     plutôt que sur la seule taille visuelle du glyphe « ✕ ». */
  min-width: 40px; min-height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
}

/* Bloc captcha de la barre de confirmation */
/* Conteneur du widget hCaptcha : le widget dessine lui-même son cadre,
   on se contente de le centrer proprement dans la barre d'actions. */
.captcha-bloc {
  display: flex;
  align-items: center;
}
.fichier-liste .fichier-taille { color: var(--encre-douce); font-size: 0.82rem; flex: none; }
.fichier-liste .fichier-retirer {
  background: none; border: none; cursor: pointer;
  color: var(--erreur); font-size: 1.05rem; flex: none;
  /* Zone tactile alignée sur le bouton voisin (.btn--mini, min-height: 40px). */
  min-width: 40px; min-height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ---------------------------------------------------------------- Admin */
/* Barre de recherche/filtres — mobile-first :
   - base (< 600px) : seules la recherche et la rangée d'actions (bouton
     Filtres/Tout sélectionner/compteur) restent dans la page ; le reste des
     filtres vit dans #feuille-filtres, une feuille qui glisse depuis le bas
     (voir .modale-fond--feuille plus bas) — 8 select + case archive d'un
     coup au-dessus de la recherche aurait pris tout l'écran.
   - ≥ 600px (tablette portrait) : plus de feuille, tout redevient une
     grille 2 colonnes dans le flux normal de la page.
   - ≥ 834px (tablette paysage/desktop) : grille 3 colonnes comme avant. */
.barre-recherche {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--carte);
  border-radius: 12px;
  box-shadow: var(--ombre);
  padding: 12px 14px;
  margin-bottom: 14px;
}
.barre-recherche input[type="search"] {
  width: 100%;
  font: inherit;
  padding: 10px 14px;
  border: 1.5px solid var(--ligne);
  border-radius: 999px;
  background: var(--surface-douce);
}
.barre-recherche input[type="search"]:focus { outline: none; border-color: var(--bleu); }

.barre-recherche__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.barre-recherche .compteur-resultats { font-size: 0.85rem; color: var(--encre-douce); margin-left: auto; }

/* Pastille "n filtres actifs" sur le bouton Filtres (mobile). */
.filtres-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: 6px;
  border-radius: 999px;
  background: var(--jaune);
  color: var(--bleu-nuit);
  font-size: 0.72rem;
  font-weight: 800;
}

.feuille__corps select {
  font: inherit;
  font-size: 0.88rem;
  padding: 10px 12px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
  cursor: pointer;
  width: 100%;
  min-height: 44px;
}

@media (min-width: 600px) {
  .barre-recherche { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .barre-recherche input[type="search"] { flex: 1 1 240px; width: auto; }
  .barre-recherche__actions { flex: 1 1 auto; }
  #btn-filtres-mobile { display: none; }

  /* Neutralise la feuille en simple bloc du flux normal — même DOM, plus de
     fond assombri ni d'ouverture/fermeture : #filtres-corps est juste une
     grille dans la page. Spécificité 2 classes + !important pour battre
     .modale-fond--ouverte (display:flex) quel que soit l'état d'ouverture
     laissé côté JS sur mobile avant l'agrandissement de la fenêtre. */
  .modale-fond.modale-fond--feuille {
    position: static;
    display: block !important;
    background: none;
    flex-basis: 100%;
    /* Indispensable : le z-index:100 de .modale-fond (pensé pour une modale
       par-dessus toute la page) reste ACTIF ici malgré position:static, parce
       que cette feuille est un item flex de .barre-recherche — le z-index
       s'applique aux items flex même non positionnés. Sans cette remise à
       zéro, les filtres passaient devant l'en-tête collant (z-index:50) et le
       recouvraient au défilement. */
    z-index: auto;
  }
  .feuille {
    max-height: none;
    background: none;
    box-shadow: none;
    border-radius: 0;
    transform: none !important;
    transition: none;
  }
  .feuille__entete { display: none; }
  .feuille__corps {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    padding: 0;
    overflow-y: visible;
  }
}
@media (min-width: 834px) {
  .feuille__corps { grid-template-columns: repeat(3, 1fr); }
}

.barre-selection {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  background: var(--erreur-fond);
  border: 1.5px solid var(--erreur);
  border-radius: 12px;
  padding: 12px 16px;
  margin-bottom: 18px;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--erreur-texte);
}
.table-admin th[data-tri] { cursor: pointer; user-select: none; white-space: nowrap; }
.table-admin th[data-tri]:hover { background: var(--bleu-fonce); }
.table-admin th .fleche-tri { opacity: 0.5; font-size: 0.75rem; }
.table-admin th.tri-actif .fleche-tri { opacity: 1; color: var(--jaune); }

/* Suivi des règlements (modale, format onglet SUIVI LICENCES) : la table
   "règlements reçus" (montant + type + 2 dates + action, 6 colonnes) dépasse
   la largeur d'un téléphone — sans ce conteneur, c'est toute la modale
   (en-tête et bouton Fermer compris) qui devrait défiler horizontalement
   pour l'atteindre. Seule la table défile, le reste de la modale reste fixe. */
.table-scroll { overflow-x: auto; }
/* Indice visuel de défilement horizontal (fondu sur le bord droit) — même
   motif que .carte:has(> .table-admin)::after et .carte:has(> .tarifs)::after.
   Seul le tableau "Règlements reçus" (6 colonnes, le plus large des 3 de la
   modale "Suivi des règlements") déborde réellement sur mobile ; ciblé
   spécifiquement via :has() pour ne pas afficher un fondu inutile sur les
   deux autres tableaux .table-reglements de la même modale, qui tiennent
   sans déborder. Retiré au-delà de la tablette-paysage (mesuré : le
   tableau tient sans déborder dès ~625px). */
.table-scroll:has(#corps-reglements) { position: relative; }
.table-scroll:has(#corps-reglements)::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 28px;
  background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.08));
  pointer-events: none;
}
@media (min-width: 834px) {
  .table-scroll:has(#corps-reglements)::after { display: none; }
}

/* Vue cartes du tableau "Règlements reçus" — mobile-first, même principe et
   même seuil de bascule que .table-admin/#cartes-admin : cartes visibles par
   défaut, thead/tbody du tableau masqués (le tfoot "+Ajouter" reste dans le
   flux normal de la table, scroll horizontal local comme les 2 autres
   tableaux de cette modale). Les data-reglement-encaisse/data-suppr-reglement
   sont identiques à ceux du tableau : mêmes gestionnaires délégués, voir
   admin.js (délégation élargie à #modale-paiement). */
#reglements-cartes { display: flex; flex-direction: column; gap: 10px; margin: 12px 0; }
.table-scroll:has(#corps-reglements) thead,
.table-scroll:has(#corps-reglements) tbody { display: none; }

.reglement-carte {
  background: var(--surface-douce);
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  padding: 6px 12px;
}
.reglement-carte__ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
}
.reglement-carte__ligne + .reglement-carte__ligne { border-top: 1px dashed var(--ligne); }
.reglement-carte__label { font-weight: 700; font-size: 0.82rem; color: var(--encre-douce); flex: none; }
.reglement-carte input[type="date"] {
  font: inherit;
  font-size: 0.9rem;
  min-height: 44px;
  padding: 4px 10px;
  border: 1.5px solid var(--ligne);
  border-radius: 8px;
}
.reglement-carte__actions { display: flex; justify-content: flex-end; padding: 7px 0; }
.reglement-carte .lien-discret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 8px 14px;
  font-size: 0.85rem;
}

@media (min-width: 834px) {
  #reglements-cartes { display: none; }
  .table-scroll:has(#corps-reglements) thead { display: table-header-group; }
  .table-scroll:has(#corps-reglements) tbody { display: table-row-group; }
}
.table-reglements { width: 100%; border-collapse: collapse; font-size: 0.9rem; margin: 12px 0; }
.table-reglements th {
  background: var(--surface-teinte); color: var(--bleu-fonce);
  padding: 8px 10px; text-align: left; font-size: 0.8rem;
}
.table-reglements td { padding: 7px 10px; border-bottom: 1px solid var(--ligne); }
.table-reglements input, .table-reglements select {
  font: inherit; font-size: 0.88rem;
  padding: 7px 9px;
  border: 1.5px solid var(--ligne); border-radius: 8px;
  background: var(--surface-douce); width: 100%;
}

.recap-paiement {
  display: flex; gap: 14px; flex-wrap: wrap;
  margin: 14px 0;
}
.recap-paiement__bloc {
  flex: 1; min-width: 120px;
  background: #f6f8fd; border-radius: 10px;
  padding: 10px 16px; text-align: center;
}
.recap-paiement__bloc strong { display: block; font-size: 1.25rem; color: var(--bleu-fonce); }
.recap-paiement__bloc small { color: var(--encre-douce); }
.recap-paiement__bloc--ok { background: #e3f4ea; }
.recap-paiement__bloc--ko { background: var(--avertissement-fond); }
.recap-paiement__bloc--danger { background: var(--erreur-fond); }
.recap-paiement__bloc--alerte { background: var(--avertissement-fond); }

.stats-mini-barre {
  display: flex; height: 6px; border-radius: 4px; overflow: hidden;
  margin-top: 8px; background: var(--ligne);
}
.stats-mini-barre span { display: block; height: 100%; }

.stats-segments {
  display: flex; height: 22px; border-radius: 8px; overflow: hidden;
  margin: 8px 0; background: var(--ligne);
}
.stats-segments span { display: block; height: 100%; }
.stats-segments-legende {
  display: flex; gap: 14px; flex-wrap: wrap;
  font-size: 0.85rem; color: var(--encre); margin-bottom: 6px;
}
.stats-segments-legende__item { display: inline-flex; align-items: center; gap: 6px; }
.stats-segments-legende__item i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

.stats-barres { margin: 6px 0 14px; }
.stats-barres__ligne {
  display: grid; grid-template-columns: minmax(0, 1fr) 3fr auto;
  align-items: center; gap: 10px; padding: 4px 0; font-size: 0.88rem;
}
.stats-barres__label { color: var(--encre); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stats-barres__piste { height: 12px; border-radius: 6px; background: var(--ligne); overflow: hidden; }
.stats-barres__valeur { display: block; height: 100%; background: var(--bleu); border-radius: 6px; }
.stats-barres__pct { color: var(--encre-douce); font-size: 0.82rem; min-width: 68px; text-align: right; }

.table-admin { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.table-admin th {
  text-align: left; padding: 12px 14px;
  background: var(--bleu); color: #fff; font-weight: 700;
}
.table-admin td { padding: 11px 14px; border-bottom: 1px solid var(--ligne); }

.table-admin tr:not(.ligne-fiche--selectionnee):hover td { background: #f2f6ff; }
/* La ligne entière ouvre la fiche au clic (voir admin.js) — curseur pointeur
   partout sauf sur les zones déjà interactives (case, select, boutons). Rester
   appuyé (souris ou tactile) sélectionne à la place (puis un simple clic
   suffit tant qu'au moins une fiche reste sélectionnée) — voir la détection
   d'appui long dans admin.js. */
.ligne-fiche { cursor: pointer; }
.ligne-fiche input, .ligne-fiche select, .ligne-fiche button, .ligne-fiche a { cursor: pointer; }
/* Ligne/carte sélectionnée : couleur configurable (Paramètres), dégradé ou
   unie selon --selection-mode. Posé sur <tr> (pas sur chaque <td>) pour un
   dégradé continu sur toute la largeur de la ligne plutôt qu'un dégradé
   répété à l'identique dans chaque colonne (rendu "par bandes" du premier
   essai — un <tr> peint sous des <td> sans fond propre, donc le dégradé de
   la ligne apparaît continu à travers toutes les colonnes). */
.table-admin tr.ligne-fiche--selectionnee { background: linear-gradient(135deg, var(--selection-debut), var(--selection-fin)); }
.admin-carte--selectionnee { background: linear-gradient(135deg, var(--selection-debut), var(--selection-fin)) !important; }
:root[data-selection-mode="unie"] .table-admin tr.ligne-fiche--selectionnee { background: var(--selection-debut); }
:root[data-selection-mode="unie"] .admin-carte--selectionnee { background: var(--selection-debut) !important; }

/* Étiquettes : contraste renforcé + bordure pour rester lisibles partout */
.pastille {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 800;
  line-height: 1.3;
  border: 1.5px solid transparent;
  white-space: nowrap;
  margin: 1px 0;
}
.pastille--nouveau { background: #ffe27a; color: #4a3a00; border-color: #d9b52e; }
.pastille--traite { background: #b9ecd0; color: #0b5c33; border-color: #35a56b; }
.pastille--certif { background: #ffd9c2; color: #7a3300; border-color: #e08a4e; }
.pastille--docs { background: #dcd2f7; color: #3c2a80; border-color: #8f78d8; }
/* Paiement en attente — rouge pour sauter aux yeux (de l'argent est dû). */
.pastille--danger { background: var(--erreur-fond); color: var(--erreur-texte); border-color: var(--erreur); }
/* Trop perçu — même jaune que --nouveau, nom explicite pour ne pas laisser
   croire à une nouvelle fiche à traiter : ici il s'agit d'argent à rembourser. */
.pastille--alerte { background: #ffe27a; color: #4a3a00; border-color: #d9b52e; }

/* Affectation d'équipe : select façon pastille (flèche personnalisée, sans le
   rendu natif du navigateur), grisé tant qu'aucune équipe n'est choisie. */
.equipe-select {
  font: inherit;
  font-size: 0.82rem;
  font-weight: 800;
  padding: 5px 28px 5px 13px;
  border: 1.5px solid var(--ligne);
  border-radius: 999px;
  background-color: #f4f6fb;
  color: var(--encre-douce);
  cursor: pointer;
  max-width: 160px;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2355607a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 10px 7px;
  transition: border-color 0.15s, background-color 0.15s;
}
.equipe-select:hover { border-color: var(--bleu); }
.equipe-select:focus { outline: none; border-color: var(--bleu); }
.equipe-select--assignee {
  background-color: #dcd2f7;
  color: #3c2a80;
  border-color: #8f78d8;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%233c2a80' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Deux groupes distincts (statistiques / boutons d'action) plutôt qu'une
   seule rangée flex à plat : un flex-wrap sur une rangée unique fait
   « sauter » les derniers boutons tout à gauche du conteneur dès que ça ne
   tient plus sur une ligne, alors qu'ils devraient rester groupés avec le
   reste des boutons. Chaque groupe gère son propre retour à la ligne. */
.admin-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 10px; margin-bottom: 14px; }

/* Cards de stats — mobile-first :
   - base (< 480px) : rangée qui défile horizontalement avec accroche
     (scroll-snap), chaque carte à largeur fixe — 3 chiffres à la fois sur un
     écran de 360px ne rentrent pas confortablement, mieux vaut les parcourir
     que les écraser.
   - ≥ 480px : assez de place pour les 3 en grille sans défilement.
   - ≥ 834px : cards plus spacieuses (tablette paysage/desktop). */
.admin-actions__stats {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 2px;
  margin: 0 -20px;
  padding-left: 20px;
  padding-right: 20px;
}
@media (min-width: 480px) {
  .admin-actions__stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    overflow-x: visible;
    margin: 0;
    padding: 0;
  }
}
.admin-stat {
  background: var(--carte);
  border-radius: 12px;
  box-shadow: var(--ombre);
  padding: 10px 16px;
  font-size: 0.8rem;
  color: var(--encre-douce);
  flex: 0 0 auto;
  min-width: 132px;
  scroll-snap-align: start;
}
@media (min-width: 480px) { .admin-stat { min-width: 0; } }
@media (min-width: 834px) { .admin-stat { padding: 14px 22px; font-size: 0.9rem; } }
.admin-stat strong { display: block; font-size: 1.2rem; color: var(--bleu-fonce); }
@media (min-width: 834px) { .admin-stat strong { font-size: 1.5rem; } }
/* Compteurs cliquables (à traiter / paiements en attente) : mêmes styles que
   .admin-stat mais un vrai <button> — raccourci pour appliquer le filtre
   correspondant en un tap, pensé d'abord pour l'action rapide sur mobile. */
.admin-stat--action {
  font: inherit;
  border: none;
  cursor: pointer;
  text-align: left;
  transition: transform 0.1s, box-shadow 0.1s;
}
.admin-stat--action:hover { box-shadow: var(--ombre-forte); transform: translateY(-1px); }

/* Actions rapides — mobile-first :
   - base (< 600px) : liste verticale compacte (icône + label), une seule
     carte englobante avec séparateurs fins plutôt que 9 pilules qui prennent
     toute la hauteur de l'écran ; seules 3 actions prioritaires restent en
     accès direct, le reste replié dans #actions-plus (voir accordéon JS).
   - ≥ 600px (tablette portrait) : grille 2 colonnes, #actions-plus toujours
     visible (display:contents — ses boutons rejoignent directement la
     grille du parent) et le bouton "Plus d'actions" disparaît.
   - ≥ 834px (tablette paysage/desktop) : rangée de pilules façon design
     actuel, mais bordure allégée et densité resserrée. */
.admin-actions__boutons {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 14px;
  background: var(--carte);
  border-radius: 12px;
  box-shadow: var(--ombre);
  padding: 4px;
}
.admin-actions__boutons .btn {
  width: 100%;
  justify-content: flex-start;
  gap: 10px;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--encre);
  font-weight: 700;
  font-size: 0.92rem;
  padding: 12px;
  min-height: 44px;
  box-shadow: none;
  transform: none;
}
.admin-actions__boutons .btn:hover { background: var(--surface-douce); transform: none; box-shadow: none; }
/* "Mails de paiement à tous" reste identifiable par sa couleur plutôt qu'un
   fond plein, qui casserait la liste verticale — repris en pilule pleine
   dès que la mise en page en pilules revient (≥ 834px, plus bas). */
.admin-actions__boutons .btn--bleu { color: var(--bleu); }
.actions-plus { display: flex; flex-direction: column; gap: 2px; }
.actions-plus__toggle { justify-content: center !important; color: var(--bleu) !important; border-top: 1px solid var(--ligne) !important; margin-top: 2px; }

@media (min-width: 600px) {
  .admin-actions__boutons {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
    background: none;
    box-shadow: none;
    padding: 0;
  }
  .actions-plus__toggle { display: none; }
  /* display:contents dissout le conteneur : ses boutons rejoignent la grille
     du parent comme s'ils étaient posés directement dedans, plutôt que de
     former une 2e sous-grille imbriquée qui casse l'alignement des lignes
     (align-items:stretch étirerait alors la cellule voisine à la hauteur du
     sous-bloc). Volontairement PAS conditionné à [hidden] : l'attribut peut
     avoir été retiré côté JS (accordéon ouvert sur mobile) avant que l'écran
     ne s'agrandisse, l'id (plus spécifique que l'attribut) doit gagner dans
     les deux cas. */
  #actions-plus { display: contents !important; }
}

@media (min-width: 834px) {
  .admin-actions__boutons {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
  }
  .admin-actions__boutons .btn {
    width: auto;
    justify-content: center;
    border: 1.5px solid var(--bleu);
    background: transparent;
    color: var(--bleu);
    border-radius: 999px;
    padding: 10px 20px;
    font-size: 0.88rem;
    min-height: 44px;
  }
  .admin-actions__boutons .btn:hover { background: var(--bleu); color: #fff; }
  .admin-actions__boutons .btn--bleu { background: var(--bleu); color: #fff; }
  .admin-actions__boutons .btn--bleu:hover { background: var(--bleu-fonce); }
}

/* Liste des fiches — mobile-first, 3 présentations selon la largeur :
   - base (< 834px, mobile + tablette portrait) : cartes tap-to-open
     (#cartes-admin), le tableau est illisible en dessous d'une tablette
     paysage. Pas de défilement horizontal à trouver : chaque fiche est un
     bloc complet.
   - 834-1023px (tablette paysage/petit desktop) : tableau, mais seulement
     les colonnes essentielles (Reçue le / Naissance / Licences masquées) —
     défilement horizontal encore possible pour les atteindre, avec un
     fondu sur le bord droit comme indice visuel qu'il y a plus à voir.
   - ≥ 1024px (desktop) : tableau complet, toutes colonnes. */
#cartes-admin { display: block; }
.carte:has(> .table-admin) { display: none; }
.table-admin { display: none; }

@media (min-width: 834px) {
  #cartes-admin { display: none; }
  .carte:has(> .table-admin) { display: block; position: relative; }
  .table-admin { display: table; }

  /* Colonnes masquées uniquement en tablette paysage — voir ≥1024px plus
     bas qui les réaffiche. Ordre des colonnes : 1 N° dossier, 2 Reçue le,
     3 Licencié, 4 Naissance, 5 Catégorie, 6 Équipe, 7 Règlement, 8 Licences,
     9 Actions (voir <thead> dans admin.html). */
  .table-admin th:nth-child(2), .table-admin td:nth-child(2),
  .table-admin th:nth-child(4), .table-admin td:nth-child(4),
  .table-admin th:nth-child(8), .table-admin td:nth-child(8) { display: none; }

  /* Indice visuel de défilement horizontal (fondu sur le bord droit) —
     retiré dès que le tableau complet tient sans défiler (≥1024px). */
  .carte:has(> .table-admin)::after {
    content: "";
    position: absolute;
    top: 0; right: 0; bottom: 0;
    width: 28px;
    background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.08));
    pointer-events: none;
    border-radius: 0 var(--rayon) var(--rayon) 0;
  }
}
@media (min-width: 1024px) {
  .table-admin th:nth-child(2), .table-admin td:nth-child(2),
  .table-admin th:nth-child(4), .table-admin td:nth-child(4),
  .table-admin th:nth-child(8), .table-admin td:nth-child(8) { display: table-cell; }
  .carte:has(> .table-admin)::after { display: none; }
}
.admin-carte {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--carte);
  border-radius: 12px;
  box-shadow: var(--ombre);
  padding: 12px 14px;
  margin-bottom: 10px;
  cursor: pointer;
  text-align: left;
  width: 100%;
  font: inherit;
  color: inherit;
  border: none;
}
.admin-carte__texte { min-width: 0; }
.admin-carte__nom { font-weight: 700; color: var(--encre); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-carte__dossier { font-size: 0.82rem; color: var(--encre-douce); }
.admin-carte__droite { display: flex; align-items: center; gap: 8px; flex: none; }

/* min-height plutôt qu'un padding plus généreux : garde le bouton compact
   (utile dans un tableau dense) tout en atteignant la zone tactile
   recommandée (~40px), le contenu restant centré via .btn (align-items). */
.btn--mini { padding: 6px 14px; font-size: 0.82rem; min-height: 40px; }

/* Boutons icône-seule des cartes mobiles (mémo, règlements/restaurer) :
   carrés et à ~44px (repère Apple/WCAG pour une zone tactile confortable),
   plus généreux que le repère desktop ci-dessus, dense par nécessité dans le
   tableau. Ne s'applique qu'aux cartes (#cartes-admin), jamais aux mêmes
   boutons dans le tableau desktop qui restent compacts. */
#cartes-admin .btn--mini { min-width: 44px; min-height: 44px; padding: 8px; font-size: 0.95rem; }

/* Panneau d'actions (équipe, règlement, statut, lien paiement, actions) en
   tête de la fiche détaillée — n'a de sens que sur mobile : sur desktop, ces
   mêmes actions restent dans la colonne "Actions" du tableau (voir
   panneauActionsMobile dans admin.js), pas besoin de les dupliquer ici. */
.fiche-actions-mobile { display: block; }
@media (min-width: 834px) {
  .fiche-actions-mobile { display: none; }
}
.fiche-actions-mobile__ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 9px 0;
  border-bottom: 1px solid var(--ligne);
}
.fiche-actions-mobile__ligne:last-child { border-bottom: none; padding-bottom: 0; }
.fiche-actions-mobile__label { font-weight: 700; font-size: 0.8rem; color: var(--encre-douce); flex: none; }
.fiche-actions-mobile__ligne--actions { justify-content: flex-start; padding-top: 12px; }
.fiche-actions-mobile .btn--mini { min-width: 44px; min-height: 44px; padding: 8px; }

.lien-invisible {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  text-align: left;
}

.lien-discret {
  background: none;
  border: none;
  color: var(--bleu);
  font-size: 0.78rem;
  cursor: pointer;
  text-decoration: underline;
  padding: 2px 4px;
  font-family: inherit;
}

/* Ligne d'une liste éditable (tranche d'âge, champ personnalisé…) : cadre
   léger pour que chaque ligne se détache visuellement du fond, plutôt que
   des champs nus qui se fondent dans la page. */
.ligne-editable {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  background: #f3f6ff;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  padding: 8px 10px;
  margin-bottom: 8px;
}

/* Bouton rond « retirer cette ligne » — reprend le look du ✕ du planning
   mais en flux normal (pas en coin de carte), pour remplacer un simple lien
   texte bleu par une action reconnaissable au premier coup d'œil. */
.bouton-retirer-ligne {
  position: relative;
  flex: none;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.08);
  color: var(--encre-douce);
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  transition: background 0.15s, color 0.15s;
}
.bouton-retirer-ligne:hover { background: var(--erreur); color: #fff; }
/* Zone tactile élargie à 44×44 (voir .fichier-retirer) sans agrandir le
   badge visuel : un ::before invisible déborde autour du bouton plutôt que
   de faire grossir le rond, pour ne pas déséquilibrer la ligne de champs. */
.bouton-retirer-ligne::before { content: ""; position: absolute; inset: -9px; }

/* Bouton « + Ajouter » en pointillés — même esprit que .planning-admin-ajouter,
   nommé génériquement pour être réutilisé hors du planning. */
.bouton-ajouter-ligne {
  border: 1.5px dashed var(--ligne);
  border-radius: 8px;
  background: none;
  color: var(--encre-douce);
  font-size: 0.8rem;
  font-weight: 700;
  padding: 8px 12px;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}
.bouton-ajouter-ligne:hover { border-color: var(--bleu); color: var(--bleu); background: var(--surface-teinte); }

/* ------------------------------------------- Éditeur des modèles de mail */
.editeur-mail .champ textarea {
  font: inherit;
  font-size: 0.92rem;
  padding: 12px 14px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
  resize: vertical;
  line-height: 1.5;
}
.editeur-mail .champ textarea:focus {
  outline: none;
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.14);
  background: var(--carte);
}

.onglets-modele {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  border-bottom: 1.5px solid var(--ligne);
  padding-bottom: 10px;
}
.onglet-modele {
  font-family: inherit;
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--encre-douce);
  background: none;
  border: 1.5px solid transparent;
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
  transition: all 0.15s;
}
.onglet-modele:hover { color: var(--bleu); background: #f3f6ff; }
.onglet-modele--actif { color: var(--bleu-fonce); background: var(--surface-teinte); border-color: var(--bleu); }

/* Barre d'outils + zone éditable (mise en forme du corps du mail) */
.editeur-riche__barre {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  padding: 6px 8px;
  border: 1.5px solid var(--ligne);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  background: #f3f5f9;
}
.editeur-riche__barre button {
  font-family: inherit;
  font-size: 0.85rem;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid transparent;
  border-radius: 6px;
  background: var(--carte);
  padding: 5px 9px;
  cursor: pointer;
  color: var(--encre);
}
.editeur-riche__barre button:hover { border-color: var(--bleu); color: var(--bleu); }
.editeur-riche__separateur { width: 1px; align-self: stretch; background: var(--ligne); margin: 2px 4px; }
.editeur-riche {
  min-height: 260px;
  padding: 12px 14px;
  border: 1.5px solid var(--ligne);
  border-radius: 0 0 10px 10px;
  background: var(--surface-douce);
  font-size: 0.92rem;
  line-height: 1.5;
  overflow-y: auto;
}
.editeur-riche:focus {
  outline: none;
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.14);
  background: var(--carte);
}
.editeur-riche a { color: var(--bleu); }
.editeur-riche p { margin: 0 0 10px; }

.chips-variables { display: flex; gap: 8px; flex-wrap: wrap; }
.chip-var {
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--bleu-fonce);
  background: var(--surface-teinte);
  border: 1.5px dashed var(--bleu);
  border-radius: 999px;
  padding: 5px 14px;
  cursor: pointer;
  transition: all 0.15s;
}
.chip-var:hover { background: var(--bleu); color: #fff; }

/* Sélecteur de catégories (planning) : case à cocher stylée en pastille,
   même esprit que .chip-var mais activable (checkbox réel, accessible). */
.categorie-chip { display: inline-flex; position: relative; cursor: pointer; }
.categorie-chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.categorie-chip span {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--encre-douce);
  background: var(--carte);
  border: 1.5px solid var(--ligne);
  border-radius: 999px;
  padding: 6px 14px;
  transition: all 0.15s;
}
.categorie-chip input:checked + span { background: var(--bleu); border-color: var(--bleu); color: #fff; }
.categorie-chip input:focus-visible + span { box-shadow: 0 0 0 3px rgba(27, 60, 143, 0.3); }
.categorie-chips-zone { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
/* La pastille d'une équipe reprend sa couleur une fois cochée, plutôt que le
   bleu générique des catégories — on distingue ainsi visuellement chaque
   équipe cochée par sa propre couleur (cohérent avec le reste du planning).
   --texte-couleur est calculée en JS (voir contraste.js) : une couleur claire
   choisie par l'admin (ex. jaune pâle) a besoin de texte noir, pas blanc. */
.categorie-chip input:checked + span[style*="--couleur"] {
  background: var(--couleur); border-color: var(--couleur); color: var(--texte-couleur, #fff);
}

/* Panneau de gestion des gymnases/équipes : regroupé et clairement distinct
   du reste du formulaire de créneau, pour ne pas laisser croire que c'est un
   simple détail du champ de sélection au-dessus. */
.panneau-listes-planning { margin-top: 10px; }
.panneau-listes-planning > summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--bleu-fonce);
  padding: 10px 14px;
  background: #f4f6fb;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
}
.panneau-listes-planning[open] > summary { border-radius: 10px 10px 0 0; margin-bottom: 0; }
.panneau-listes-planning__grille {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  padding: 16px;
  border: 1.5px solid var(--ligne);
  border-top: none;
  border-radius: 0 0 10px 10px;
  background: var(--surface-douce);
}
@media (min-width: 600px) {
  .panneau-listes-planning__grille { grid-template-columns: 1fr 1fr; }
}
.panneau-listes-planning__bloc h4 { margin: 0 0 8px; color: var(--bleu-fonce); font-size: 0.95rem; }

/* ------------------------------------------- Planning admin (façon emploi du temps) */
.planning-admin-mode {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 18px;
  font-size: 0.9rem;
}
.planning-admin-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 26px;
}
.planning-admin-jour__titre {
  margin: 0 0 8px;
  font-family: var(--police-planning);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bleu-fonce);
  text-align: center;
  padding-bottom: 6px;
  border-bottom: 2px solid var(--jaune);
}
.planning-admin-jour__creneaux { display: flex; flex-direction: column; gap: 6px; min-height: 30px; }

.planning-admin-carte { position: relative; }
.planning-admin-carte__corps {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--carte);
  border: 1.5px solid var(--ligne);
  border-left: 4px solid var(--couleur, var(--bleu));
  border-radius: 8px;
  padding: 7px 22px 7px 9px;
  cursor: pointer;
  font: inherit;
  transition: box-shadow 0.15s, transform 0.1s;
}
.planning-admin-carte__corps:hover { box-shadow: var(--ombre); transform: translateY(-1px); }
.planning-admin-carte__horaire {
  display: block;
  font-family: var(--police-planning);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--bleu-fonce);
}
.planning-admin-carte__libelle {
  display: block;
  font-family: var(--police-planning);
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--encre);
  line-height: 1.25;
}
.planning-admin-carte__suppr {
  position: absolute;
  top: 4px; right: 4px;
  width: 18px; height: 18px;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.08);
  color: var(--encre-douce);
  font-size: 0.68rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.planning-admin-carte__suppr:hover { background: var(--erreur); color: #fff; }
/* Zone tactile élargie à 44×44 sans agrandir le badge visuel ni risquer de
   déborder sur le créneau voisin (voir .bouton-retirer-ligne) : un
   ::before invisible déborde autour du bouton plutôt que le rond lui-même. */
.planning-admin-carte__suppr::before { content: ""; position: absolute; inset: -13px; }

.planning-admin-ajouter {
  border: 1.5px dashed var(--ligne);
  border-radius: 8px;
  background: none;
  color: var(--encre-douce);
  font-size: 0.76rem;
  font-weight: 700;
  padding: 8px;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}
.planning-admin-ajouter:hover { border-color: var(--bleu); color: var(--bleu); background: #f3f6ff; }

/* Formulaire d'ajout de gymnase : flex simple (plutôt qu'une grille .champs
   imbriquée) — le nom grandit pour occuper la place disponible, la couleur
   et le bouton gardent une taille fixe, tout reste aligné en bas quelle que
   soit la largeur de la modale. */
.gestion-gymnases__form { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.gestion-gymnases__champ-nom { flex: 1 1 200px; }
.gestion-gymnases__champ-couleur { flex: none; }
.gestion-gymnases__form label {
  display: block;
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--encre);
  margin-bottom: 5px;
}
.gestion-gymnases__champ-nom input {
  width: 100%;
  font: inherit;
  font-size: 0.92rem;
  padding: 10px 12px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
}
.gestion-gymnases__champ-nom input:focus { outline: none; border-color: var(--bleu); background: var(--carte); }
.gestion-gymnases__champ-couleur input {
  display: block;
  width: 56px;
  height: 42px;
  padding: 3px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  cursor: pointer;
}
.gestion-gymnases__form .btn { flex: none; height: 42px; padding: 0 20px; }

.apercu-mail { margin: 16px 0 4px; }
.apercu-mail summary {
  cursor: pointer;
  font-weight: 700;
  color: var(--bleu);
  font-size: 0.9rem;
  user-select: none;
}
.apercu-mail__cadre {
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  background: var(--surface-douce);
  padding: 16px 18px;
  margin-top: 10px;
  overflow-wrap: anywhere;
}
.apercu-mail__meta { font-size: 0.88rem; color: var(--encre-douce); margin-bottom: 6px; overflow-wrap: anywhere; }
.apercu-mail__sujet {
  font-weight: 800;
  color: var(--bleu-fonce);
  border-bottom: 1px solid var(--ligne);
  padding-bottom: 8px;
  margin-bottom: 10px;
}
/* overflow-wrap:anywhere — un lien de paiement long (raccourcisseur d'URL +
   paramètres) n'a aucun espace où couper naturellement : sans ça, il déborde
   de sa carte au lieu de passer à la ligne, surtout visible sur mobile où le
   conteneur est étroit (voir modale-envoi / modale-facture-mail / etc.). */
.apercu-mail__corps {
  font-family: inherit;
  font-size: 0.9rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0;
  line-height: 1.55;
  color: var(--encre);
}
.apercu-mail__corps--html { white-space: normal; }
.apercu-mail__corps a { overflow-wrap: anywhere; }
.apercu-mail__corps--html p { margin: 0 0 12px; }
.apercu-mail__corps--html p:last-child { margin-bottom: 0; }
.apercu-mail__corps--html a { color: var(--bleu); }

/* Aperçu des documents dans l'admin */
.doc-carte {
  border: 1.5px solid var(--ligne);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 14px;
  background: var(--surface-douce);
}
.doc-carte__entete {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.doc-apercu {
  display: block;
  max-width: 100%;
  max-height: 340px;
  border-radius: 8px;
  border: 1px solid var(--ligne);
  margin: 0 auto;
  object-fit: contain;
  background: var(--carte);
}
.doc-apercu--pdf { width: 100%; height: 380px; }

.modale-fond {
  position: fixed; inset: 0;
  background: rgba(12, 29, 71, 0.6);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 30px 16px;
  overflow-y: auto;
  z-index: 100;
}
.modale-fond--ouverte { display: flex; }
.modale { max-width: 820px; width: 100%; }
.modale--large { max-width: 1100px; }
.modale__fermer {
  position: sticky; top: 0;
  margin-left: auto;
  display: flex;
  margin-bottom: 10px;
}

/* -------------------------------------------------------------- Impression
   Seules les pages A4 de la fiche doivent sortir à l'impression / export PDF. */
@media print {
  @page { size: A4 portrait; margin: 8mm; }

  body { background: #fff !important; display: block; min-height: 0; }

  .entete, .pied, .barre-confirmation, .stepper, .no-print,
  .overlay-envoi, .modale-fond, .admin-actions, .form-boutons { display: none !important; }

  main, .conteneur { padding: 0 !important; margin: 0 !important; max-width: none !important; }

  /* Les conteneurs des fiches ne doivent introduire aucun décalage vertical :
     quelques millimètres de trop et la première page déborde, ce qui insère
     une feuille blanche parasite entre les pages. */
  #apercu-fiche, #apercu-fiche-succes, #conteneur-fiche, #modale-contenu {
    margin: 0 !important;
    padding: 0 !important;
  }

  /* La fiche imprimée doit être STRICTEMENT identique à l'affichage écran :
     mêmes tailles de police (valeurs plafond du clamp écran), couleurs et
     fonds conservés, pointillés dessinés à l'identique. */
  .fiche-a4 {
    box-shadow: none !important;
    border-radius: 0;
    max-width: 100% !important;
    width: 100%;
    margin: 0 !important;
    /* Hauteur calée sous la zone imprimable (297mm - 2×8mm de marges = 281mm)
       pour garantir 1 fiche = 1 feuille, sans page blanche de débordement. */
    aspect-ratio: auto;
    height: 271mm;
    overflow: hidden;
    page-break-after: always;
    break-after: page;
    page-break-inside: avoid;
    font-size: 12.5px;
  }
  .fiche-a4, .fiche-a4 * {
    print-color-adjust: exact !important;
    -webkit-print-color-adjust: exact !important;
  }
  .fiche-a4:last-child { page-break-after: auto; }
  .fiche-a4--page2 { font-size: 11px; }
}

/* --------------------------------------------------------------- Responsive */
@media (max-width: 760px) {
  .etapes { grid-template-columns: 1fr; margin-top: -30px; }
  .accroche-essai { margin-top: -30px; }
  .accroche-essai + .etapes { margin-top: 0; }
  .grille-2 { grid-template-columns: 1fr; }
  .champ--8, .champ--6, .champ--4, .champ--3 { grid-column: span 12; }

  .heros { padding: 40px 16px 64px; }
  .carte { padding: 20px 16px; }
  .section { padding: 32px 0; }

  /* Pas de "reverse" : le DOM place déjà le bouton secondaire avant le
     principal, donc column suffit pour garder le principal en bas sur mobile
     (column-reverse inversait à tort : le principal se retrouvait en haut). */
  .form-boutons { flex-direction: column; }
  .form-boutons .btn { width: 100%; }
  .stepper { gap: 0; }
  .stepper__etape { font-size: 0.62rem; }
  .stepper__etape::before { width: 30px; height: 30px; }
  .stepper__etape::after { top: 15px; left: calc(50% + 20px); width: calc(100% - 40px); }

  .choix-cartes { gap: 8px; }
  .choix-carte span { padding: 10px 16px; font-size: 0.88rem; }

  /* Même pattern que .form-boutons ci-dessus (colonne pleine largeur) plutôt
     qu'un flex-wrap propre à cette barre — le DOM place déjà le bouton
     principal (Confirmer) en dernier, donc il reste bien en bas. */
  .barre-confirmation { flex-direction: column; }
  .barre-confirmation .btn { width: 100%; }
  /* Le widget hCaptcha a une largeur native fixe (~303px) : sur un écran
     étroit (iPhone SE 320-375px), la largeur restante dans .barre-confirmation
     (après padding) peut descendre sous cette valeur. Plutôt que de laisser le
     widget déborder ou forcer un scroll horizontal de toute la page, on
     confine le débordement au seul bloc captcha (scroll horizontal local). */
  .captcha-bloc { max-width: 100%; overflow-x: auto; }

  /* Le tableau "Règlements reçus" (le plus large des 3 de cette modale, 6
     colonnes) a sa propre vue cartes sur mobile (#reglements-cartes, même
     principe que .table-admin/#cartes-admin — voir plus bas). Seul le
     "+Ajouter" du tfoot reste dans une structure de table, avec le même
     indice de défilement horizontal (.table-scroll:has(#corps-reglements)::after)
     que les 2 autres tableaux de cette modale. */
  .recap-paiement { gap: 8px; }
  .recap-paiement__bloc { padding: 8px 10px; min-width: 100px; }
  .table-reglements { font-size: 0.8rem; }
  .table-reglements th, .table-reglements td { padding: 6px 6px; }
  .stats-barres__ligne { grid-template-columns: minmax(0, 1fr) 2fr auto; gap: 6px; font-size: 0.82rem; }
  .stats-barres__pct { min-width: 52px; }

  .modale-fond { padding: 14px 8px; }
  .ecran-succes { padding: 40px 14px; }
  .overlay-envoi__boite { padding: 20px; }
}

@media (max-width: 420px) {
  .heros h1 { font-size: 1.45rem; }
  .tarifs { font-size: 0.82rem; }
  .tarifs th, .tarifs td { padding: 8px 8px; }
  .fichier-liste li { flex-wrap: wrap; }
}
