/* =========================================================================
   Le Lieu — feuille de style principale
   Palette : sauge très clair en fond, vert profond en primaire, doré en
   accent — clin d'œil discret à un lieu de musique et d'arts vivants.
   ========================================================================= */

:root {
  --couleur-fond: #F4F4F4;
  --couleur-surface: #FFFFFF;
  --couleur-primaire: #333333;
  --couleur-primaire-clair: #4D4D4D;
  --couleur-accent: #8A8A8A;
  --couleur-accent-clair: #B0B0B0;
  --couleur-texte: #1A1A1A;
  --couleur-texte-att: #666666;
  --couleur-bordure: #E0E0E0;
  --couleur-erreur: #B3261E;
  --couleur-erreur-fond: #FBEAEA;
  /* Bandeau du site (07/09/2026) : noir, distinct du gris plus clair des
     bandeaux de titre de page (--couleur-primaire) — hiérarchie visuelle
     voulue par Bruno ("noir le fond du bandeau du site... gris assez
     foncés pour les fonds de bandeau titre des pages"), suite à la
     fourniture du logo (noir et blanc). Les couleurs SÉMANTIQUES
     (--couleur-erreur ci-dessus, orange "champ obligatoire" en dur dans
     .champ-erreur, rose "sans professeur", vert accepté/rouge refusé,
     ambre "verrou perdu") sont volontairement CONSERVÉES telles quelles
     dans tout ce fichier : elles portent une information fonctionnelle
     (état, validation) que le passage au gris ferait perdre — seule la
     palette structurelle/de marque (fond, surface, primaire, accent,
     texte, bordure) passe au gris.
     */
  --couleur-bandeau-app: #161616;
  /* Bandeaux de titre de page (07/09/2026, ajusté) : plus clair que
     --couleur-primaire (#333333, resté pour les boutons/liens) pour une
     vraie nuance avec le bandeau du site (--couleur-bandeau-app,
     #161616) — Bruno : "pas assez de nuance". */
  --couleur-bandeau-page: #4A4A4A;

  --police-affichage: "Fraunces", Georgia, serif;
  --police-texte: "Public Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --rayon: 10px;
  --ombre: 0 1px 2px rgba(27, 36, 32, 0.06), 0 8px 24px rgba(27, 36, 32, 0.06);
}

* { box-sizing: border-box; }

/* Garantit que l'attribut "hidden" l'emporte toujours sur toute autre règle
   de display définie plus bas (ex. .champ-valeur-figee { display: flex }),
   qui aurait sinon la même spécificité et pourrait l'emporter selon l'ordre
   des règles — bug classique. */
[hidden] { display: none !important; }

/* Champ obligatoire manquant/incorrect (façon Excel) : fond orange clair,
   redevient normal dès que le champ est correctement renseigné. */
.champ-erreur,
.table-lignes .champ-erreur,
fieldset input.champ-erreur,
fieldset select.champ-erreur {
  background: #FDEBD3 !important;
  border-color: #E0A339 !important;
}

/* Discipline/professeur reconduits à la réinscription mais introuvables
   dans le catalogue de la nouvelle saison (renommés/retirés — voir
   sql/14_disciplines_par_saison_2627.sql et resoudreDisciplineLignePour
   Saison() dans assets/formulaire.js, 31/08/2026) : rouge plutôt que
   l'orange de .champ-erreur, volontairement — ce n'est pas une erreur de
   saisie qui bloque l'enregistrement, juste un signal informationnel pour
   le trésorier (comportement historique d'Excel, repris sur demande de
   Bruno pour ne pas le dérouter). */
.table-lignes .champ-discipline-obsolete {
  background: var(--couleur-erreur-fond) !important;
  border-color: var(--couleur-erreur) !important;
  color: var(--couleur-erreur) !important;
}
/* color est une propriété héritée : sans cette ligne, TOUTES les <option>
   de la liste déroulante héritent du rouge du <select> (visible seulement
   liste ouverte, signalé par Bruno sur capture) — on la réinitialise
   explicitement pour qu'elles restent lisibles normalement, seule la case
   fermée du select doit apparaître en rouge. */
.table-lignes .champ-discipline-obsolete option {
  color: var(--couleur-texte);
}

/* Cours en préinscription : professeur pas encore affecté (06/09/2026,
   demande de Bruno) — rose clair, couleur EXACTE demandée (#DA9EC6),
   volontairement distincte du rouge "discipline obsolète" ci-dessus et de
   l'orange ".champ-erreur" : ce n'est ni une erreur ni un signal de
   catalogue, juste "en attente d'affectation pédagogique", et ça doit le
   rester visuellement tant que la case reste vide (pas seulement le temps
   d'une validation). */
.table-lignes .cours-sans-professeur {
  background: #DA9EC6 !important;
  border-color: #B5709E !important;
  color: #401F32 !important;
}
.table-lignes .cours-sans-professeur option {
  color: var(--couleur-texte);
}

/* Ligne grisée (06/09/2026) : inscription pas encore pédagogiquement
   validée, dans la file trésorerie de la page Validations — reste visible
   (pas filtrée) mais visuellement en retrait, pour que le trésorier priorise
   naturellement les lignes déjà prêtes. */
.ligne-grisee {
  opacity: 0.5;
}

/* Colonne Réduction (€) réservée à admin/trésorier (07/09/2026) — masque
   l'en-tête ET chaque cellule via une classe portée par le tableau
   entier, pour couvrir automatiquement toute ligne de cours ajoutée
   après coup sans avoir à la masquer une par une côté JS. */
.masquer-colonne-reduction #entete-colonne-reduction,
.masquer-colonne-reduction .cellule-colonne-reduction {
  display: none;
}

body {
  margin: 0;
  font-family: var(--police-texte);
  color: var(--couleur-texte);
  background: var(--couleur-fond);
  -webkit-font-smoothing: antialiased;
}

/* ---------------------------------------------------------------------
   Page de connexion
   --------------------------------------------------------------------- */

.page-connexion {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background:
    radial-gradient(circle at 15% 10%, rgba(22, 66, 60, 0.05), transparent 45%),
    radial-gradient(circle at 85% 90%, rgba(201, 162, 39, 0.08), transparent 40%),
    var(--couleur-fond);
}

.carte-connexion {
  width: 100%;
  max-width: 380px;
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 40px 32px 32px;
}

.entete-connexion { margin-bottom: 28px; }

.repere {
  display: inline-block;
  font-family: var(--police-texte);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--couleur-accent);
  margin-bottom: 10px;
}

/* Logo (07/09/2026, remplace .repere texte "Le Lieu") — un peu plus
   généreux ici que dans le bandeau applicatif, la carte de connexion
   étant plus spacieuse. */
.logo-connexion { display: block; height: 44px; width: auto; margin-bottom: 14px; }

.entete-connexion h1 {
  font-family: var(--police-texte);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.25;
  margin: 0 0 8px;
  color: var(--couleur-primaire);
}

.sous-titre {
  margin: 0;
  color: var(--couleur-texte-att);
  font-size: 0.92rem;
}

form { display: flex; flex-direction: column; }

label {
  font-size: 0.85rem;
  font-weight: 500;
  margin: 14px 0 6px;
  color: var(--couleur-texte);
}

input[type="email"],
input[type="password"],
input[type="text"] {
  font-family: var(--police-texte);
  font-size: 1rem;
  padding: 10px 12px;
  border: 1px solid var(--couleur-bordure);
  border-radius: 8px;
  background: var(--couleur-fond);
  color: var(--couleur-texte);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:focus-visible {
  outline: none;
  border-color: var(--couleur-primaire-clair);
  box-shadow: 0 0 0 3px rgba(22, 66, 60, 0.15);
}

button {
  font-family: var(--police-texte);
  font-size: 0.98rem;
  font-weight: 600;
  cursor: pointer;
  border: none;
  border-radius: 8px;
  padding: 12px 16px;
  transition: background-color 0.15s ease, transform 0.05s ease;
}

button:active { transform: translateY(1px); }

#bouton-connexion {
  margin-top: 22px;
  background: var(--couleur-primaire);
  color: white;
}
#bouton-connexion:hover { background: var(--couleur-primaire-clair); }
#bouton-connexion:disabled { opacity: 0.6; cursor: not-allowed; }

.message-erreur {
  margin: 14px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--couleur-erreur-fond);
  color: var(--couleur-erreur);
  font-size: 0.88rem;
}

.message-succes {
  margin: 14px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: #E6F2E9;
  color: #1F6B3A;
  font-size: 0.88rem;
}

.lien-mot-de-passe-oublie {
  margin: 14px 0 0;
  text-align: center;
  font-size: 0.82rem;
}
.lien-mot-de-passe-oublie a { color: var(--couleur-primaire-clair); }

/* ---------------------------------------------------------------------
   Application (après connexion)
   --------------------------------------------------------------------- */

/* v67 (30/08/2026) : la barre n'utilise plus justify-content: space-between
   (qui ne gérait bien que 3 enfants) mais une structure explicite en 4
   zones : [logo+nav] [recherche, flex:1 — absorbe tout l'espace libre et
   pousse ce qui suit à droite] [bouton Nouvel adhérent, optionnel]
   [infos-utilisateur]. */
.barre-app {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
  row-gap: 10px;
  padding: 8px 24px;
  background: var(--couleur-bandeau-app);
  color: white;
}

/* v70/v71 posaient flex-wrap à chaque niveau imbriqué, mais ça ne suffisait
   toujours pas (constaté par Bruno le 31/08/2026 sur Galaxy S8+ 360px —
   "Import" toujours coupé). Cause réelle, plus subtile : un conteneur flex
   avec flex-wrap ne fait passer ses enfants à la ligne que si SA PROPRE
   largeur est contrainte. Sans max-width, .barre-app-gauche se dimensionne
   à la largeur qu'aurait son contenu SANS retour à la ligne (comportement
   par défaut d'un item flex-shrink:0 à base "auto") — donc rien ne force
   jamais nav-app à réellement wrapper, quel que soit le flex-wrap posé sur
   elle. max-width:100% (qui se résout par rapport à .barre-app, son
   conteneur flex parent) impose enfin cette contrainte, et déclenche le
   wrap en cascade jusqu'aux liens de nav. */
.barre-app-gauche { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; row-gap: 6px; flex-shrink: 0; max-width: 100%; min-width: 0; position: relative; }

/* Logo image (07/09/2026, remplace le texte "Le Lieu") — deux tailles
   fournies par Bruno, PC (34px de haut) et mobile (26px), une seule
   affichée à la fois selon la largeur d'écran (voir @media plus bas). */
.logo-app-lien { display: inline-flex; align-items: center; line-height: 0; }
.logo-app-image { display: block; height: 34px; width: auto; }
.logo-app-mobile { display: none; }

/* "Inscriptions" (07/09/2026) : nom de ce module/outil, à côté du logo. */
.libelle-app {
  font-family: var(--police-affichage);
  font-weight: 600;
  font-size: 1.1rem;
  color: white;
}

/* Loupe repliable (07/09/2026, demande de Bruno — gagner de la hauteur sur
   mobile) : bouton qui affiche/masque .recherche-globale, voir
   initialiserRechercheRepliable() dans assets/entete.js. */
.bouton-loupe-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: white;
  border: 1px solid rgba(255,255,255,0.35);
  border-radius: 6px;
  width: 32px;
  height: 32px;
  padding: 0;
}
.bouton-loupe-toggle:hover, .bouton-loupe-toggle.actif { background: rgba(255,255,255,0.1); }

.barre-app .infos-utilisateur {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  row-gap: 6px;
  font-size: 0.85rem;
  flex-shrink: 0;
  max-width: 100%;
  min-width: 0;
  margin-left: auto;
}

.barre-app button.lien-deconnexion {
  background: transparent;
  color: white;
  border: 1px solid rgba(255,255,255,0.35);
  padding: 5px 11px;
  font-weight: 500;
  font-size: 0.8rem;
}
.barre-app button.lien-deconnexion:hover { background: rgba(255,255,255,0.1); }

/* Bouton "+ Nouvel adhérent" : historique — v67 dans le panneau de liste,
   v67-v74 dans le bandeau global du site, v75 déplacé dans le bandeau de
   titre de chaque page concernée (Formulaire, Liste adhérents), aux côtés
   de Réinscrire/Dupliquer — voir .bouton-action-fiche plus bas et SYNTHESE
   section 9. */

.contenu-app {
  max-width: 1360px;
  margin: 24px auto;
  padding: 0 20px;
}

.contenu-app h1 {
  font-family: var(--police-texte);
  font-weight: 600;
  font-size: 1.25rem;
  color: var(--couleur-primaire);
}

/* ---------------------------------------------------------------------
   Navigation dans la barre d'app
   --------------------------------------------------------------------- */

.nav-app {
  display: none;
  position: fixed;
  top: calc(var(--hauteur-bandeau-app, 52px) + 8px);
  right: 14px;
  left: auto;
  min-width: 220px;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  background: var(--couleur-bandeau-app);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 8px;
  padding: 6px;
  box-shadow: 0 6px 16px rgba(0,0,0,0.2);
  z-index: 20;
}
.nav-app.ouvert { display: flex; }
.nav-app a { padding: 9px 12px; }
.nav-app a {
  color: rgba(255,255,255,0.75);
  text-decoration: none;
  font-size: 0.84rem;
  font-weight: 500;
  padding: 5px 11px;
  border-radius: 6px;
}
.nav-app a:hover { background: rgba(255,255,255,0.08); color: white; }
.nav-app a.actif { background: rgba(255,255,255,0.14); color: white; }
/* Petit point d'alerte répété sur le lien du menu concerné (07/09/2026,
   demande de Bruno) — même information que la cloche, redondance
   volontaire pour qu'elle reste visible même une fois le menu ouvert
   (la cloche seule n'est plus visible sur l'écran une fois le menu
   déroulé par-dessus). */
.nav-app a.a-des-alertes::after {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: #DA9EC6;
  margin-left: 7px;
  vertical-align: middle;
}

/* Icône "Tableau de bord" (maison, remplace le libellé texte depuis le
   30/08/2026 — voir SYNTHESE section 9) : même comportement actif/hover que
   les autres liens de nav, mais carrée et centrée sur l'icône plutôt que sur
   du texte. */
.nav-icone-accueil { display: inline-flex; align-items: center; justify-content: flex-start; padding: 9px 12px; }
.nav-icone-accueil svg { display: block; }
/* Libellé texte de l'icône maison : masqué sur PC (l'icône seule suffit,
   comme avant), affiché uniquement dans le menu déroulant mobile où elle
   côtoie des liens en texte — voir @media plus bas (31/08/2026). */
.libelle-nav-mobile { display: inline; margin-left: 8px; }
/* Lien "Se déconnecter" dans le menu mobile, masqué par défaut (PC) — voir
   @media (max-width: 700px) plus bas pour l'affichage et le style complet. */
.lien-deconnexion-nav {
  display: block;
  margin-top: 4px;
  padding-top: 13px;
  border-top: 1px solid rgba(255,255,255,0.15);
}
/* Le bouton "Se déconnecter" autonome devient redondant : le menu (toujours
   présent depuis le 07/09/2026) contient déjà son propre lien. */
.infos-utilisateur #bouton-deconnexion { display: none; }

/* Bouton "menu" (hamburger) — unifié PC/mobile le 07/09/2026 (demande de
   Bruno, auparavant mobile uniquement). Toujours affiché, à droite du
   bandeau ; nav-app reste dans le DOM sous barre-app-gauche mais s'ouvre
   ici via position:fixed (voir plus bas), indépendamment de sa position
   réelle. margin-left:auto (07/09/2026, correctif) : pousse ce bouton —
   et tout ce qui le suit dans le DOM (cloche, nom) — jusqu'au bord droit
   du bandeau ; sans lui, rien ne comblait l'espace entre la recherche
   (capée à 320px) et ce groupe, qui flottait au milieu du bandeau au lieu
   de longer le bord droit. */
.bouton-menu-mobile {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: transparent;
  color: white;
  border: 1px solid rgba(255,255,255,0.35);
  border-radius: 6px;
  padding: 6px 10px;
  font-family: var(--police-texte);
  font-size: 0.84rem;
  font-weight: 500;
}
.bouton-menu-mobile:hover { background: rgba(255,255,255,0.1); }

/* Cloche d'alerte (07/09/2026) — juste à côté du bouton menu. */
.bouton-cloche-alerte {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  background: transparent;
  color: white;
  border: 1px solid rgba(255,255,255,0.35);
  border-radius: 6px;
  width: 32px;
  height: 32px;
  padding: 0;
}
.bouton-cloche-alerte:hover { background: rgba(255,255,255,0.1); }
.pastille-alerte {
  display: none;
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 999px;
  background: #DA9EC6;
  color: #401F32;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
.pastille-alerte.visible { display: block; }

/* ---------------------------------------------------------------------
   Recherche globale d'adhérent, dans le bandeau du site (30/08/2026)
   --------------------------------------------------------------------- */

/* flex: 1 absorbe tout l'espace disponible entre le groupe de gauche et le
   groupe de droite — c'est ce qui pousse naturellement le bouton "Nouvel
   adhérent" et les infos utilisateur contre le bord droit, sans avoir besoin
   de justify-content sur le conteneur parent. max-width évite qu'elle ne
   s'étire de façon disproportionnée sur un très grand écran. */
.recherche-globale { position: relative; flex: 1; max-width: 320px; }
.recherche-globale input {
  width: 100%;
  padding: 7px 12px 7px 32px;
  border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.3);
  background: rgba(255,255,255,0.14);
  color: white;
  font-size: 0.85rem;
  font-family: var(--police-texte);
}
.recherche-globale input::placeholder { color: rgba(255,255,255,0.65); }
.recherche-globale input:focus {
  background: white;
  color: var(--couleur-texte);
  outline: none;
  border-color: white;
}
.recherche-globale .icone-loupe {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: rgba(255,255,255,0.75); pointer-events: none;
}
.recherche-globale:focus-within .icone-loupe { color: var(--couleur-texte-att); }

/* Réutilise le style de .liste-suggestions (dropdowns de recherche du
   formulaire) pour la cohérence visuelle — voir plus bas dans ce fichier.
   Correctif du 30/08/2026 : sans cette ligne, le texte (prénom/nom) hérite
   du "color: white" de .barre-app et devient invisible sur le fond blanc du
   dropdown — seul le sous-titre restait visible car lui fixait déjà sa
   propre couleur via .suggestion-details. */
.recherche-globale .liste-suggestions { top: calc(100% + 4px); color: var(--couleur-texte); }
.recherche-globale .suggestion-vide { padding: 7px 9px; font-size: 0.85rem; color: var(--couleur-texte-att); }
.recherche-globale .suggestion-details { display: block; font-size: 0.72rem; color: var(--couleur-texte-att); }

/* Libellé court sur mobile, réutilisable pour tout futur libellé trop long
   (ex. "Code postal" -> "CP" — voir formulaire.php). Doit impérativement
   être défini AVANT les @media qui le réaffichent : à spécificité égale,
   une règle sans condition de media passée APRÈS un bloc @media reprend le
   dessus même quand la condition du @media est vraie — c'est exactement ce
   qui rendait "CP" invisible sur mobile (constaté par Bruno le 31/08/2026),
   cette règle était placée bien plus bas dans le fichier. */
.libelle-court { display: none; }

/* Sur petit écran (30/08/2026, corrige un bug signalé par Bruno : le bouton
   "+ Nouvel adhérent" se retrouvait poussé hors de l'écran visible). Cause
   racine : .barre-app-gauche / .recherche-globale / .bouton-nouveau-bandeau
   / .infos-utilisateur avaient tous flex-shrink:0 et .barre-app n'avait pas
   de flex-wrap — rien ne pouvait rétrécir NI passer à la ligne, donc la
   barre débordait purement et simplement hors du viewport. flex-wrap (posé
   plus haut sur .barre-app) est le vrai correctif : il garantit qu'aucun
   élément ne peut plus finir hors écran, quel que soit le contenu futur du
   bandeau. La ligne masquant le nom faute de place (30/08/2026) est retirée
   le 07/09/2026 : le nom affiché est désormais juste le prénom (ex.
   "Bruno"), largement assez court pour rester visible même ici. */
@media (max-width: 780px) {
  .recherche-globale { order: 3; flex-basis: 100%; max-width: none; }
}

/* ---------------------------------------------------------------------
   Mobile (31/08/2026) : menu hamburger — voir SYNTHESE section 9.
   Le reste des ajustements mobiles (cadres réduits, titre de page collé
   au bandeau) est regroupé en fin de fichier : ces règles surchargent
   .panneau-formulaire/.entete-liste/etc., définies plus bas — les
   regrouper là-bas évite l'erreur d'ordre de cascade qui les a rendues
   inopérantes en v73 (une règle sans condition de media, définie APRÈS un
   bloc @media dans le fichier, reprend le dessus même quand la condition
   du @media est vraie).
   --------------------------------------------------------------------- */
@media (max-width: 700px) {
  /* "Code postal" -> "CP" : le libellé complet passait sur deux lignes et
     déformait la grille de champs sur petit écran. */
  .libelle-long { display: none; }
  .libelle-court { display: inline; }

  /* Logo : version mobile plus compacte, "Inscriptions" masqué pour
     gagner de la place (07/09/2026). */
  .logo-app-pc { display: none; }
  .logo-app-mobile { display: block; }
  .libelle-app { display: none; }
}

/* ---------------------------------------------------------------------
   Pages Formulaire et Liste adhérents (30/08/2026)
   --------------------------------------------------------------------- */

/* Anciennement une seule page à deux colonnes (.contenu-adherents,
   360px liste | 1fr formulaire) — scindée en deux pages distinctes, chacune
   avec un conteneur simple centré (voir SYNTHESE section 9). */

.contenu-formulaire {
  max-width: 1360px;
  margin: 14px auto;
  padding: 0 14px 30px;
}

.contenu-liste-adherents {
  max-width: 1360px;
  margin: 14px auto;
  padding: 0 14px 30px;
}

.panneau-liste {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: 8px;
  /* Pas de padding ici, comme .panneau-formulaire : le bandeau de titre doit
     occuper toute la largeur pour aller bord-à-bord (coins arrondis inclus).
     Le padding est porté par .corps-liste. */
}

.corps-liste { padding: 14px; }

/* Titre de page homogénéisé avec .entete-formulaire (31/08/2026, sur
   demande de Bruno : "même format que celui du formulaire" — à reprendre
   pour toute future page du portail, par souci de cohérence visuelle
   d'ensemble). */
.entete-liste {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  background: var(--couleur-bandeau-page);
  border-radius: 8px 8px 0 0;
}
.entete-liste h1 {
  font-family: var(--police-texte);
  font-weight: 700;
  color: white;
  margin: 0;
  font-size: 1.15rem;
}
.panneau-formulaire {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: 8px;
  /* Pas de padding ici : le bandeau sticky doit occuper toute la largeur
     sans marge négative (les marges négatives cassent le calcul de
     position sticky). Le padding est porté par .corps-formulaire. */
}

.corps-formulaire { padding: 14px; }

.filtres-liste { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.filtres-liste select, .filtres-liste input {
  font-family: var(--police-texte);
  padding: 6px 8px;
  border: 1px solid var(--couleur-bordure);
  border-radius: 6px;
  font-size: 0.85rem;
}
.filtres-liste .case-filtre {
  font-size: 0.78rem;
  color: var(--couleur-texte-att);
  padding: 2px 2px 0;
}

.table-scroll { max-height: 66vh; overflow: auto; border: 1px solid var(--couleur-bordure); border-radius: 6px; }

.table-adherents { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.table-adherents th {
  position: sticky; top: 0;
  background: #EEF0EA;
  text-align: left;
  padding: 6px 8px;
  font-weight: 700;
  border-bottom: 1px solid var(--couleur-bordure);
}
.table-adherents td { padding: 5px 8px; border-bottom: 1px solid var(--couleur-bordure); }
.table-adherents tbody tr { cursor: pointer; }
.table-adherents tbody tr:nth-child(even) { background: #FAFBF8; }
.table-adherents tbody tr:hover { background: #EFF3EC; }
.table-adherents tbody tr.ligne-selectionnee {
  background: rgba(22, 66, 60, 0.09);
  box-shadow: inset 3px 0 0 var(--couleur-primaire);
}
/* Inscription "payée par un autre adhérent" annoncée mais non encore
   désignée (voir validerFormulaire() dans formulaire.js, et rafraichirListe()
   dans liste_adherents.js) : liseré doré discret + icône, pour la repérer
   sans la confondre avec une vraie erreur (rouge, réservé à
   .champ-erreur/.message-erreur). */
.table-adherents tbody tr.ligne-payeur-a-preciser {
  box-shadow: inset 3px 0 0 var(--couleur-accent);
}
.indicateur-payeur-a-preciser { font-size: 0.78rem; }
.table-adherents .col-montant { text-align: right; }
.table-adherents td.col-montant { text-align: right; font-variant-numeric: tabular-nums; }
.etat-vide { text-align: center; color: var(--couleur-texte-att); padding: 20px 10px; font-size: 0.85rem; }

/* Rendu tactile de la liste (tablette/smartphone), 30/08/2026 — voir
   SYNTHESE section 9. Générées à partir des MÊMES données que le tableau
   ci-dessus (assets/liste_adherents.js remplit les deux en une passe) ;
   seul le basculement ci-dessous décide laquelle des deux s'affiche. On
   croise la largeur d'écran ET le type de pointeur : une tablette tactile en
   mode paysage peut avoir une largeur proche d'un PC portable, mais reste un
   usage au doigt qui a besoin de cibles larges — d'où (pointer: coarse) en
   plus du seuil de largeur, plutôt qu'un seul @media (max-width). */
.liste-cartes-adherents { display: none; flex-direction: column; gap: 8px; }
.carte-adherent {
  border: 1px solid var(--couleur-bordure);
  border-radius: 8px;
  padding: 12px 14px;
  min-height: 44px; /* cible tactile confortable, voir principe déjà appliqué au bouton-nouveau-bandeau */
  background: var(--couleur-surface);
  cursor: pointer;
}
.carte-adherent:active { background: #EFF3EC; }
.carte-adherent.carte-payeur-a-preciser { box-shadow: inset 3px 0 0 var(--couleur-accent); }
.carte-adherent-ligne1 { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.carte-adherent-nom { font-weight: 700; font-size: 0.92rem; }
.carte-adherent-montant { font-size: 0.85rem; font-variant-numeric: tabular-nums; white-space: nowrap; }
.carte-adherent-details { margin: 4px 0 0; font-size: 0.78rem; color: var(--couleur-texte-att); }

@media (pointer: coarse) and (max-width: 820px) {
  /* .table-scroll est réutilisée telle quelle dans formulaire.php
     (Disciplines/Prestations/Paiements) — sans ce scope à .panneau-liste
     (qui n'existe que sur cette page), cette règle masquait aussi ces
     tableaux sur tout appareil tactile, donc systématiquement sur mobile.
     C'est LA cause du bug "Disciplines/Paiements ne s'affichent pas sur
     mobile" signalé à plusieurs reprises par Bruno (31/08/2026) — la
     table SE MASQUAIT, elle ne débordait pas et n'était pas mal dimensionnée. */
  .panneau-liste .table-scroll { display: none; }
  .liste-cartes-adherents { display: flex; }

  /* Page Validations (06/09/2026) : réutilise .panneau-liste pour le style
     visuel de base, mais n'a PAS d'équivalent "cartes" comme la liste
     adhérents — sans cette règle, ses tableaux (Cours en attente,
     Trésorerie) se retrouvaient masqués sur mobile par la règle
     ci-dessus, sans aucun remplacement (signalé par Bruno). Même
     spécificité CSS que la règle qu'elle neutralise : gagne parce qu'elle
     vient après dans le fichier. */
  .panneau-validations .table-scroll { display: block; }
}

/* Formulaire — sections plus compactes, moins "cartes", plus "feuille de calcul" */
fieldset {
  border: 1px solid var(--couleur-bordure);
  border-radius: 6px;
  padding: 12px 14px;
  margin: 0 0 10px;
  background: #FCFCFA;
}
legend {
  font-family: var(--police-texte);
  font-weight: 700;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--couleur-primaire);
  padding: 0 6px;
}

/* Bandeau flottant : nom/n° dossier uniquement, toujours visible au défilement.
   --hauteur-bandeau-app (31/08/2026, voir assets/entete.js ajusterHauteurBandeau())
   remplace un ancien "top: 52px" codé en dur, faux dès que le bandeau du site
   passe sur plusieurs lignes (recherche pleine largeur, menu hamburger...) —
   Bruno avait signalé que ce bandeau ne restait plus fixé/visible au défilement
   sur mobile pour cette raison. */
.bandeau-fiche {
  position: sticky;
  top: calc(var(--hauteur-bandeau-app, 52px) + 8px);
  z-index: 6;
  box-shadow: 0 2px 8px rgba(27, 36, 32, 0.1);
}

/* Traçabilité de la saisie (08/09/2026) — discrète, sous le bandeau de
   titre du formulaire, alignée à droite. */
.ligne-saisie-par {
  text-align: right;
  font-size: 0.72rem;
  color: var(--couleur-texte-att);
  font-style: italic;
  margin: 4px 14px 0 0;
}

.entete-formulaire {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px;
  background: var(--couleur-bandeau-page);
  border-radius: 8px 8px 0 0;
}
.entete-formulaire h2 {
  font-family: var(--police-texte); font-weight: 700; color: white;
  margin: 0; font-size: 1.02rem;
  white-space: nowrap; overflow: hidden;
  flex-shrink: 1; min-width: 60px;
}
.badge-num-dossier {
  font-size: 0.8rem; font-weight: 700; color: white;
  background: rgba(255,255,255,0.16); padding: 3px 9px; border-radius: 999px;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.groupe-boutons-entete { margin-left: auto; display: flex; align-items: center; gap: 8px; position: relative; flex-shrink: 0; }

/* Boutons d'action du bandeau de fiche (+ Nouvel adhérent, Réinscrire,
   Dupliquer) : version compacte du bouton secondaire habituel — trois
   boutons doivent tenir aux côtés du titre, réduits sur demande de Bruno
   (31/08/2026). */
.bouton-action-fiche { padding: 5px 10px; font-size: 0.76rem; white-space: nowrap; }

/* Bouton kebab (⋮), mobile uniquement — regroupe les 3 actions ci-dessus en
   menu déroulant. Masqué sur PC : .menu-actions-fiche y reste affichée en
   ligne, comme avant. Même mécanique que le menu hamburger du bandeau du
   site (voir assets/entete.js, initialiserMenuMobile()), dupliquée ici
   volontairement plutôt que généralisée : les actions concernées (fiche vs.
   navigation globale) et leur logique d'affichage (etat.inscriptionCourante)
   sont propres à assets/formulaire.js. */
.bouton-kebab-fiche {
  display: none;
  align-items: center; justify-content: center;
  width: 30px; height: 30px;
  padding: 0; /* sans ça, hérite du padding:12px 16px de la règle générique
                 "button" — avec box-sizing:border-box, ce padding dévore la
                 totalité d'une boîte fixée à 30x30px, écrasant l'icône SVG à
                 zéro (cause exacte du "cadre vide, pas d'icône" signalé par
                 Bruno). */
  background: transparent; color: white;
  border: 1px solid rgba(255,255,255,0.35); border-radius: 6px;
}
.bouton-kebab-fiche:hover { background: rgba(255,255,255,0.1); }
.menu-actions-fiche { display: flex; align-items: center; gap: 8px; }

@media (max-width: 700px) {
  .bouton-kebab-fiche { display: inline-flex; }
  .menu-actions-fiche {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 210px;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    background: var(--couleur-bandeau-app);
    border: 1px solid rgba(255,255,255,0.2);
    border-radius: 8px;
    padding: 6px;
    box-shadow: 0 6px 16px rgba(0,0,0,0.2);
    z-index: 20;
  }
  .menu-actions-fiche.ouvert { display: flex; }
  .menu-actions-fiche .bouton-action-fiche { text-align: left; }
}

/* Calculatrice de paiements (Total dû / Montant engagé / Total payé / Reste dû)
   — volontairement discrète, à la différence du bandeau flottant */
.recapitulatif-totaux {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
  background: var(--couleur-fond); border: 1px solid var(--couleur-bordure);
  border-radius: 6px; padding: 8px 12px; margin-bottom: 12px;
}
.recapitulatif-totaux div { display: flex; flex-direction: column; gap: 0; }
.recapitulatif-totaux span { font-size: 0.66rem; color: var(--couleur-texte-att); text-transform: uppercase; letter-spacing: 0.02em; font-weight: 600; }
.recapitulatif-totaux strong { font-size: 0.82rem; color: var(--couleur-texte); font-weight: 600; font-variant-numeric: tabular-nums; }

@media (max-width: 640px) {
  .recapitulatif-totaux { grid-template-columns: repeat(2, 1fr); }
}

.grille-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 6px; }
.grille-3 { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 10px; margin-bottom: 6px; }
.grille-3 .col-large { grid-column: span 1; }
fieldset label { font-size: 0.76rem; font-weight: 600; margin: 0 0 3px; display: block; color: var(--couleur-texte-att); }
/* Hauteur et interligne fixés explicitement (31/08/2026, signalé par Bruno) :
   le champ Email paraissait plus haut que Date de naissance (visible surtout
   en mobile, mais déjà vrai en version PC). Cause : chaque navigateur rend le
   "chrome" interne de certains types natifs (date notamment, avec son icône
   de calendrier) avec une hauteur intrinsèque différente d'un champ texte
   classique, même à padding/font-size identiques en CSS. Fixer height +
   line-height explicitement force tous les types de champ à la même boîte,
   quel que soit leur rendu natif. */
fieldset input:not([type="checkbox"]):not([type="radio"]), fieldset select {
  width: 100%;
  height: 34px;
  line-height: 1.2;
  font-family: var(--police-texte);
  padding: 6px 8px;
  border: 1px solid var(--couleur-bordure);
  border-radius: 5px;
  font-size: 0.87rem;
  background: white;
}
/* Cases à cocher/radio : la règle ci-dessus les étirait en grands
   rectangles blancs (width:100%; height:34px), particulièrement visible
   sur la case "Payé" du tableau Paiements — signalé "disproportionnée et
   bleue" par Bruno (31/08/2026). Taille native cohérente à la place,
   couleur de coche alignée sur l'identité visuelle du site
   (--couleur-primaire) plutôt que le bleu système par défaut. */
fieldset input[type="checkbox"],
fieldset input[type="radio"] {
  width: 16px;
  height: 16px;
  accent-color: var(--couleur-primaire);
  flex-shrink: 0;
}
fieldset input[type="checkbox"]:disabled,
fieldset input[type="radio"]:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
/* Pilotée en JS par ajusterTaillePoliceChamp() (assets/entete.js,
   31/08/2026) quand le texte du placeholder ne tiendrait pas dans le champ
   à la taille normale — ex. "Rechercher le référent famille pour cette
   saison…" sur un champ étroit en mobile. Hérite de la taille du champ par
   défaut (inchangé tant que le JS ne fixe rien). */
fieldset input::placeholder,
.champ-recherche-personne input::placeholder,
.recherche-globale input::placeholder {
  font-size: var(--taille-police-placeholder, inherit);
}
.case-a-cocher { display: flex; align-items: center; gap: 7px; font-weight: 600; font-size: 0.84rem; color: var(--couleur-texte); }
.case-a-cocher input { width: auto; }

.champ-recherche-personne { position: relative; margin-bottom: 10px; }
/* Les champs Adresse/Ville/Code postal utilisent la même taille de police
   que les autres champs d'identité (Email, Téléphone, Prénom, Nom...) —
   déjà le cas via la règle générale "fieldset input" ci-dessus, réaffirmé
   ici explicitement à la demande de Bruno (30/08/2026), au cas où un futur
   ajout de style viendrait la faire dévier par erreur. */
#p-adresse, #p-ville, #p-cp { font-size: 0.87rem; }
.liste-suggestions {
  list-style: none; margin: 4px 0 0; padding: 4px;
  position: absolute; z-index: 10; left: 0; right: 0;
  background: var(--couleur-surface); border: 1px solid var(--couleur-bordure);
  border-radius: 6px; box-shadow: var(--ombre); max-height: 220px; overflow: auto;
}
.liste-suggestions li { padding: 7px 9px; border-radius: 5px; cursor: pointer; font-size: 0.85rem; }
.liste-suggestions li:hover { background: var(--couleur-fond); }

/* Champ à valeur figée (référent famille, responsable) : même gabarit qu'un
   champ de saisie normal, mais en lecture seule avec une croix pour retirer. */
.champ-valeur-figee {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  height: 34px; box-sizing: border-box;
  padding: 6px 8px; margin-top: 3px;
  background: #EEF0EA; border: 1px solid var(--couleur-bordure); border-radius: 5px;
  font-size: 0.87rem; color: var(--couleur-texte);
}

/* Croix-bouton unifiée pour tous les éléments supprimables (lignes de
   tableau, champs à valeur figée) : même forme, alignée avec son champ. */
.bouton-croix {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; flex-shrink: 0;
  background: white; border: 1px solid var(--couleur-bordure); border-radius: 5px;
  color: var(--couleur-erreur); cursor: pointer; font-size: 0.85rem; line-height: 1; padding: 0;
}
.bouton-croix:hover { background: var(--couleur-erreur-fond); border-color: rgba(179,38,30,0.3); }

/* Champ date + bouton d'effacement (05/09/2026) : sur mobile, il est
   difficile voire impossible de vider un champ <input type="date"> déjà
   rempli via le clavier/sélecteur natif — un petit bouton dédié à côté
   règle ça simplement, sans alourdir le champ lui-même. */
.groupe-date { display: flex; align-items: center; gap: 6px; }
.groupe-date input[type="date"] { flex: 1; min-width: 0; }

/* width:100% seul ne suffit pas à déclencher le défilement horizontal de
   .table-scroll (overflow:auto) sur petit écran : sans butée basse, le
   navigateur écrase les colonnes jusqu'à l'illisibilité plutôt que de
   forcer le scroll — c'est ce qui rendait Disciplines/Paiements invisibles
   en pratique sur mobile (signalé par Bruno, 31/08/2026). min-width par
   tableau (nombre de colonnes différent selon le tableau) résout ça : au
   lieu de s'écraser, le tableau garde une largeur lisible et le conteneur
   scrolle horizontalement. */
.table-lignes { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
#table-disciplines { min-width: 700px; }
#table-prestations { min-width: 420px; }
#table-paiements { min-width: 440px; }
.table-lignes th { text-align: left; padding: 5px 6px; background: #EEF0EA; border-bottom: 1px solid var(--couleur-bordure); font-weight: 700; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.02em; color: var(--couleur-texte-att); }
.table-lignes tbody tr:nth-child(even) { background: #FAFBF8; }
.table-lignes tbody tr:focus-within { background: rgba(22, 66, 60, 0.06); }
.table-lignes td { padding: 4px 6px; border-bottom: 1px solid var(--couleur-bordure); text-align: center; }

/* Colonnes Début/Fin du bloc Cours en "autofit" (07/09/2026, demande de
   Bruno) : width: 1% force un tableau en table-layout auto à réduire ces
   colonnes à leur contenu minimal plutôt que de leur laisser une part
   égale de l'espace disponible, libérant de la place pour les colonnes
   plus utiles à lire en un coup d'œil (Professeur, Cours). */
#table-disciplines th:nth-child(5), #table-disciplines th:nth-child(6),
#table-disciplines td:nth-child(5), #table-disciplines td:nth-child(6) {
  width: 1%;
  white-space: nowrap;
}
.table-lignes input, .table-lignes select { padding: 4px 5px; font-size: 0.81rem; border: 1px solid var(--couleur-bordure); border-radius: 4px; width: 100%; background: white; }
.table-lignes input[readonly] {
  background: #EEF0EA; color: var(--couleur-texte-att); font-variant-numeric: tabular-nums;
  text-align: right; cursor: default;
}
.table-lignes input:focus-visible, .table-lignes select:focus-visible {
  outline: none; border-color: var(--couleur-primaire-clair); box-shadow: 0 0 0 2px rgba(22, 66, 60, 0.15);
}

.boutons-ligne { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

.total-ligne {
  font-size: 0.85rem; color: var(--couleur-texte-att); margin: 8px 0;
}
.total-ligne strong { color: var(--couleur-texte); font-variant-numeric: tabular-nums; }
.total-ligne-droite { text-align: right; }

.aide-champ { font-size: 0.78rem; color: var(--couleur-texte-att); margin: 4px 0 10px; font-style: italic; }

/* Icônes DANS les champs de contact (email, téléphones, adresse) — même
   principe visuel que l'icône native du sélecteur de date d'un
   <input type="date"> : discrète, à l'intérieur du champ, et non un bouton
   séparé à côté. Ouvrent l'appli mail/téléphone/carte du système — utile
   dès maintenant sur ordinateur, et pensé pour un usage futur sur
   smartphone. Mises à jour en direct pendant la saisie par
   actualiserLiensContact() dans adherents.js. */
.champ-avec-action { position: relative; }
.champ-avec-action input { padding-right: 32px; }
.lien-action-champ {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 4px;
  text-decoration: none; line-height: 1;
  color: var(--couleur-texte-att); /* gris, homogène pour email/téléphone/adresse — les icônes sont
                                        des SVG (fill="currentColor"), pas des emojis qui ignoreraient cette couleur */
}
.lien-action-champ:hover { background: var(--couleur-fond); color: var(--couleur-primaire); }
.lien-action-champ[aria-disabled="true"] { opacity: 0.35; pointer-events: none; }
/* Icône d'adresse (pin) : légèrement plus grosse, façon repère de carte (Google Maps). */
.lien-action-champ-pin { width: 26px; height: 26px; }

/* Champs moins prioritaires que l'identité de l'élève (ex. nom/prénom/lien
   de parenté du responsable) : taille réduite pour marquer la hiérarchie. */
.champ-secondaire label { font-size: 0.7rem; }
.champ-secondaire input { font-size: 0.8rem; padding: 5px 7px; }

/* Liste extensible de responsables (familles recomposées, 30/08/2026) —
   même mécanisme que les lignes Disciplines/Autres prestations (+/✕) :
   chaque responsable tient sur une seule ligne compacte (30/08/2026), avec
   une recherche de personne existante affichée UNIQUEMENT juste après
   l'ajout d'une ligne (aide ponctuelle, disparaît ensuite — voir
   ajouterLigneResponsable() dans adherents.js). */
#liste-responsables { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.carte-responsable {
  border: 1px solid var(--couleur-bordure); border-radius: 6px;
  padding: 8px 10px; background: var(--couleur-fond);
}
.carte-responsable .champ-recherche-personne { margin: 0 0 8px; }

/* Tableau de bord (07/09/2026) : grille de cartes-liens vers les
   fonctionnalités accessibles, colonnes auto-adaptatives (une seule sur
   mobile, plusieurs sur PC selon la largeur disponible). */
.grille-tableau-bord {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.carte-tableau-bord {
  border: 1px solid var(--couleur-bordure);
  border-radius: 8px;
  padding: 16px;
  background: var(--couleur-fond);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.carte-tableau-bord h3 { margin: 0; font-family: var(--police-affichage); color: var(--couleur-primaire); }
.carte-tableau-bord p { margin: 0; font-size: 0.85rem; color: var(--couleur-texte-att); flex: 1; }
.carte-tableau-bord .bouton-principal { align-self: flex-start; }

/* Icônes de contact d'un professeur affecté (07/09/2026, page d'accueil). */
.icone-contact { text-decoration: none; margin-left: 2px; }
.ligne-responsable { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; }
.ligne-responsable > div { flex: 1 1 120px; min-width: 0; }
.ligne-responsable .bouton-croix { margin-bottom: 1px; } /* aligné avec le bas des champs, sans label au-dessus */

.valeur-selectionnee {
  font-size: 0.82rem; color: var(--couleur-primaire-clair); font-weight: 600;
  margin: 4px 0 10px; display: flex; align-items: center; gap: 8px;
}

/* Champs calculés en lecture seule dans les fieldsets (ex. Prix de
   l'adhésion) : même gabarit que les autres champs, juste grisés. */
fieldset input[readonly] {
  background: #EEF0EA; color: var(--couleur-texte-att); cursor: default;
  font-size: 0.87rem; font-family: var(--police-texte); padding: 6px 8px;
}

/* Case à cocher grisée/verrouillée (ex. Référent famille quand un référent est désigné) */
.case-a-cocher.desactivee { opacity: 0.5; cursor: not-allowed; }
.case-a-cocher.desactivee input { cursor: not-allowed; }

.bouton-principal { background: var(--couleur-primaire); color: white; border: none; border-radius: 6px; padding: 8px 15px; font-weight: 600; font-size: 0.85rem; cursor: pointer; }
.bouton-principal:hover { background: var(--couleur-primaire-clair); }
.bouton-secondaire { background: white; border: 1px solid var(--couleur-bordure); border-radius: 6px; padding: 6px 11px; font-size: 0.8rem; font-weight: 600; cursor: pointer; color: var(--couleur-texte); }
.bouton-secondaire:hover { background: var(--couleur-fond); border-color: var(--couleur-primaire-clair); }

/* État visuel accepté/refusé (06/09/2026) : le bouton correspondant à la
   réponse déjà donnée reste identifiable en couleur pleine — l'autre reste
   neutre, cliquable pour changer d'avis. */
.bouton-reponse-acceptee { background: #2E7D4F; border-color: #2E7D4F; color: white; }
.bouton-reponse-acceptee:hover { background: #256640; border-color: #256640; }
.bouton-reponse-refusee { background: var(--couleur-erreur); border-color: var(--couleur-erreur); color: white; }
.bouton-reponse-refusee:hover { background: #96201a; border-color: #96201a; }
.bouton-texte { background: transparent; border: none; color: var(--couleur-texte-att); font-size: 0.82rem; cursor: pointer; text-decoration: underline; }
.bouton-danger { background: var(--couleur-erreur-fond); color: var(--couleur-erreur); border: 1px solid rgba(179,38,30,0.25); border-radius: 6px; padding: 7px 13px; font-weight: 600; font-size: 0.82rem; cursor: pointer; }
.bouton-danger:hover { background: #f6d8d6; }

.barre-actions-formulaire { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }

/* Bloc "Fiches payées par cet adhérent" (paiements multiples) */
.bloc-paye-pour { margin-bottom: 14px; }
.bloc-paye-pour > label { font-size: 0.76rem; font-weight: 600; color: var(--couleur-texte-att); display: block; margin-bottom: 6px; }
.liste-payees { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.liste-payees li {
  display: flex; align-items: center; justify-content: space-between;
  background: white; border: 1px solid var(--couleur-bordure); border-radius: 6px;
  padding: 6px 10px; font-size: 0.85rem;
}

/* Message "payé par" et désactivation du bloc Paiements */
.message-paye-par {
  background: rgba(22, 66, 60, 0.06); border: 1px solid rgba(22, 66, 60, 0.15);
  border-radius: 6px; padding: 10px 12px; font-size: 0.85rem; margin: 0 0 10px;
}
.lien-fiche {
  background: none; border: none; padding: 0; color: var(--couleur-primaire);
  font-weight: 700; text-decoration: underline; cursor: pointer; font-size: inherit;
}
#contenu-paiements.desactive { opacity: 0.45; pointer-events: none; }

/* Verrouillage collaboratif (30/08/2026) : empêche deux opérateurs de
   modifier la même inscription en même temps — voir chargerFiche() et
   api/verrous.php. Trois variantes : bloqué (rouge, quelqu'un d'autre édite
   déjà), libéré (vert, l'opérateur en attente peut recharger), repris en
   cours d'édition (orange, cas rare où le verrou a expiré et a été repris
   pendant qu'on modifiait encore la fiche). */
.bandeau-verrou {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 10px; padding: 12px 14px; border-radius: 8px; margin: 0 0 16px; font-size: 0.88rem;
}
.bandeau-verrou-bloque {
  background: var(--couleur-erreur-fond); border: 1px solid rgba(179,38,30,0.25); color: var(--couleur-erreur);
}
.bandeau-verrou-libre {
  background: rgba(22, 66, 60, 0.08); border: 1px solid rgba(22, 66, 60, 0.2); color: var(--couleur-primaire);
}
.bandeau-verrou-perdu { background: #FDF6E3; border: 1px solid #E9CE8A; color: #6B4A00; }
.bandeau-verrou .bouton-secondaire { flex-shrink: 0; }

/* ---------------------------------------------------------------------
   Page Import (import.php / import.js) — ajouté en v52. La mise en page
   (.contenu-import dédiée) a été retirée en v74 : la page réutilise
   maintenant .contenu-liste-adherents/.panneau-liste/.entete-liste/
   .corps-liste (homogénéisation du bandeau de titre demandée par Bruno,
   voir SYNTHESE section 9) — pas besoin de règles séparées.
   --------------------------------------------------------------------- */

.groupe-radio { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }

/* Bloc FONCTIONS (04/09/2026) : cases à cocher cumulables, en grille pour
   ne pas s'étirer sur toute la largeur en PC — s'empile naturellement sur
   mobile grâce à minmax(). */
.grille-fonctions {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 8px 16px;
}

.recapitulatif-import {
  grid-template-columns: repeat(4, 1fr);
  margin-top: 4px;
}
@media (max-width: 720px) {
  .recapitulatif-import { grid-template-columns: repeat(2, 1fr); }
}

.titre-section-rapport {
  font-family: var(--police-texte);
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 18px 0 8px;
}
.titre-section-rapport.titre-erreur { color: var(--couleur-erreur); }
.titre-section-rapport.titre-avertissement { color: #8A5A00; }

/* Purge des adhérents avant import (ajouté 29/08/2026) */
.bloc-purge-avant {
  margin-top: 14px;
  padding: 10px 12px;
  border: 1px solid var(--couleur-erreur);
  border-radius: 8px;
  background: var(--couleur-erreur-fond);
}
.bloc-purge-avant .case-a-cocher { font-weight: 600; color: var(--couleur-erreur); }
.bloc-purge-avant .aide-avertissement { margin: 6px 0 0; color: var(--couleur-erreur); }
#rapport-section-purge {
  padding: 10px 12px;
  border: 1px solid var(--couleur-erreur);
  border-radius: 8px;
  background: var(--couleur-erreur-fond);
  margin-bottom: 10px;
}
#rapport-purge-titre { margin-top: 0 !important; color: var(--couleur-erreur) !important; }

.liste-rapport {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.85rem;
}
.liste-rapport li {
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid var(--couleur-bordure);
}
.liste-rapport-erreur li {
  background: var(--couleur-erreur-fond);
  border-color: rgba(179,38,30,0.25);
  color: var(--couleur-erreur);
}
.liste-rapport-avertissement li {
  background: #FDF6E3;
  border-color: #E9CE8A;
  color: #6B4A00;
}

/* ---------------------------------------------------------------------
   Mobile (31/08/2026, suite) : cadres réduits, titre de page collé au
   bandeau du site — voir SYNTHESE section 9. Regroupé ici, en toute fin de
   fichier, PARCE QUE ces règles surchargent .contenu-formulaire/
   .contenu-liste-adherents/.panneau-formulaire/.panneau-liste/
   .entete-formulaire/.entete-liste/.bandeau-fiche, qui doivent donc être
   déjà définies plus haut dans le fichier pour que cette surcharge
   s'applique — une règle sans condition de media placée APRÈS un @media
   reprend le dessus à spécificité égale, même quand la condition du
   @media est vraie (piège identique à celui de .libelle-court, cause du
   même bug une deuxième fois dans cette même livraison v73).
   --------------------------------------------------------------------- */
@media (max-width: 700px) {
  .contenu-formulaire, .contenu-liste-adherents {
    margin-top: 0;
    padding-left: 0;
    padding-right: 0;
  }
  .panneau-formulaire, .panneau-liste {
    border-left: none;
    border-right: none;
    border-top: none;
    border-radius: 0;
  }
  .bandeau-fiche, .entete-formulaire, .entete-liste {
    border-radius: 0;
  }

  /* Adresse/Ville/CP (31/08/2026) : sur PC, .grille-3 met les trois champs
     sur une ligne (2fr/1fr/1fr) — sur mobile, Adresse prend toute la
     largeur en première ligne, Ville et CP passent en dessous, CP étant
     nettement plus étroit (juste assez pour 5 chiffres) que Ville. */
  .grille-3 {
    grid-template-columns: 1fr 76px;
    grid-template-rows: auto auto;
  }
  .grille-3 > div:first-child { grid-column: 1 / -1; }

  /* ---------------------------------------------------------------------
     Tableaux Disciplines/Prestations/Paiements -> cartes empilées
     (31/08/2026, sur demande de Bruno : le défilement horizontal, même
     fonctionnel, restait peu confortable sur mobile — trop de colonnes
     pour un usage tactile). Technique "responsive table" classique :
     l'entête est masqué, chaque ligne devient un bloc de champs
     étiquetés (via l'attribut data-label posé sur chaque <td> dans
     assets/formulaire.js), au lieu d'une ligne de tableau qu'il fallait
     faire défiler horizontalement. .table-scroll garde son défilement
     VERTICAL (max-height/overflow) pour les listes longues — seule la
     contrainte de largeur minimale (qui forçait le défilement horizontal)
     est neutralisée ici, elle n'a plus lieu d'être en mode carte.
     Scopé à .table-lignes, exclusive aux 3 tableaux du formulaire (la
     liste adhérents utilise .table-adherents, un nom différent — pas de
     risque de collision comme celle déjà rencontrée avec .table-scroll). */
  #table-disciplines, #table-prestations, #table-paiements { min-width: 0; }
  #table-disciplines th:nth-child(5), #table-disciplines th:nth-child(6),
  #table-disciplines td:nth-child(5), #table-disciplines td:nth-child(6) {
    width: auto;
    white-space: normal;
  }

  .table-lignes thead { display: none; }
  .table-lignes, .table-lignes tbody, .table-lignes tr { display: block; width: 100%; }
  .table-lignes tr {
    border: 1px solid var(--couleur-bordure);
    border-radius: 8px;
    padding: 8px 10px;
    margin-bottom: 8px;
    background: var(--couleur-surface);
  }
  .table-lignes tr:last-child { margin-bottom: 0; }
  .table-lignes td {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 5px 0;
    border: none;
  }
  .table-lignes td[data-label]::before {
    content: attr(data-label);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--couleur-texte-att);
  }
  .table-lignes td select,
  .table-lignes td input:not([type="checkbox"]) {
    width: 100%;
  }
  .table-lignes td .groupe-date {
    width: 100%;
  }
  /* Colonne "supprimer" (pas de data-label, juste le bouton ✕) : détachée
     visuellement en pied de carte plutôt que traitée comme un champ de
     plus. */
  .table-lignes td:last-child {
    flex-direction: row;
    justify-content: flex-end;
    padding-top: 8px;
    margin-top: 4px;
    border-top: 1px solid var(--couleur-bordure);
  }
}

/* Bloc "Le virement de NN,NN € doit s'effectuer en : NN fois" (08/09/2026,
   bascule vers Virement le 08/09/2026, correctif de largeur le 09/09/2026)
   — le champ est ciblé par ID (#i-nb-echeances-prelevement), PAS par
   attribut de type : la règle générale fieldset input:not(...):not(...)
   (width:100%, plus haut dans ce fichier) a une spécificité CSS
   supérieure à .bloc-prelevement-echeances input[type="number"] et
   l'emportait malgré cette règle, gardant le champ pleine largeur malgré
   la demande explicite de Bruno de le garder compact (2 chiffres max). */
.bloc-prelevement-echeances {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 10px; padding: 10px 12px;
  background: #F4F1E9; border-radius: 8px; font-size: 0.87rem;
}
.bloc-prelevement-echeances label { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
#i-nb-echeances-prelevement {
  width: 44px; padding: 4px 6px; border: 1px solid var(--couleur-bordure); border-radius: 4px; text-align: center;
}
#i-nb-echeances-prelevement.champ-erreur { border-color: var(--couleur-erreur); background: var(--couleur-erreur-fond); }

/* Popup de confirmation à l'enregistrement (08/09/2026) — non bloquant, disparaît seul. */
.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translate(-50%, 16px);
  background: var(--couleur-primaire); color: white; padding: 12px 20px; border-radius: 8px;
  font-size: 0.9rem; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease; z-index: 1000;
}
.toast.toast-visible { opacity: 1; transform: translate(-50%, 0); }

/* Page Paramètres (08/09/2026) — liste de réglages avec interrupteur on/off. */
.liste-parametres { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.carte-parametre {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 14px 16px; border: 1px solid var(--couleur-bordure); border-radius: 10px; background: white;
}
.carte-parametre-texte h3 { margin: 0 0 4px; font-size: 0.95rem; }
.carte-parametre-texte p { margin: 0; font-size: 0.83rem; color: var(--couleur-texte-att); line-height: 1.4; }
.interrupteur { position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0; }
.interrupteur input { opacity: 0; width: 0; height: 0; }
.interrupteur-curseur {
  position: absolute; cursor: pointer; inset: 0; background: #CCC; border-radius: 24px; transition: background 0.2s ease;
}
.interrupteur-curseur::before {
  content: ""; position: absolute; height: 18px; width: 18px; left: 3px; bottom: 3px;
  background: white; border-radius: 50%; transition: transform 0.2s ease;
}
.interrupteur input:checked + .interrupteur-curseur { background: var(--couleur-primaire); }
.interrupteur input:checked + .interrupteur-curseur::before { transform: translateX(20px); }
.interrupteur input:disabled + .interrupteur-curseur { opacity: 0.6; cursor: default; }