/* ==========================================================================
   Compléments applicatifs — espace connecté
   La charte du front public vit dans style.css, repris tel quel de la maquette.
   Ce fichier n'ajoute que ce que la maquette statique ne couvrait pas.
   ========================================================================== */

/* Messages flash ---------------------------------------------------------- */
.alert { border: 0; border-radius: var(--radius-sm); box-shadow: var(--shadow-sm); }
.alert-success { background: #e7f6ef; color: #0b5c3d; box-shadow: inset 3px 0 0 var(--win), var(--shadow-sm); }
.alert-danger  { background: #fdeee7; color: #8a3008; box-shadow: inset 3px 0 0 var(--danger), var(--shadow-sm); }
.alert-info    { background: var(--cp-100); color: var(--cp-900); box-shadow: inset 3px 0 0 var(--cp-500), var(--shadow-sm); }
.alert-warning { background: var(--cy-100); color: var(--cy-800); box-shadow: inset 3px 0 0 var(--cy-500), var(--shadow-sm); }

/* Menu latéral de l'espace connecté --------------------------------------- */
.espace-nav {
  position: sticky;
  top: 90px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: .5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.espace-nav a {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem .8rem;
  border-radius: var(--radius-sm);
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink-700);
  text-decoration: none;
}
.espace-nav a i { color: var(--cp-500); width: 1.1rem; }
.espace-nav a:hover { background: var(--cp-050); color: var(--cp-800); }
.espace-nav a.active {
  background: linear-gradient(150deg, var(--cp-600) 0%, var(--cp-800) 100%);
  color: #fff;
  box-shadow: 0 4px 12px -5px rgba(19, 88, 184, .85);
}
.espace-nav a.active i { color: var(--cy-300); }
.espace-nav .espace-nav-titre {
  padding: .6rem .8rem .3rem;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-300);
}

/* Tableaux de l'espace connecté ------------------------------------------- */
.table-espace { font-size: .85rem; margin-bottom: 0; }
.table-espace thead th {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-500);
  background: var(--cp-050);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.table-espace td { vertical-align: middle; }
.table-espace tr.non-lu td { background: var(--cy-100); }

/* Saisie d'un résultat ---------------------------------------------------- */
.saisie-entete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: .8rem;
  padding: 1rem;
  background: var(--cp-050);
  border-radius: var(--radius-sm);
  margin-bottom: 1.25rem;
}
.saisie-entete .equipe {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--cp-900);
}
.saisie-score-ligne { text-align: center; }
.saisie-score { max-width: 12rem; margin: 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.saisie-set,
.saisie-set-entete { display: grid; grid-template-columns: 78px 1fr 18px 1fr; align-items: center; gap: .5rem; }
.saisie-set-entete { text-align: center; }
.saisie-set-ligne + .saisie-set-ligne { margin-top: .5rem; }
.saisie-set .saisie-set-libelle { font-size: .78rem; font-weight: 700; color: var(--ink-500); text-transform: uppercase; letter-spacing: .06em; }
.saisie-set .saisie-set-sep { text-align: center; color: var(--ink-300); font-weight: 700; }
.saisie-set input { text-align: center; font-variant-numeric: tabular-nums; }
.saisie-forfait { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.saisie-forfait-equipe { margin-top: .5rem; padding-left: 1.6rem; }

.score-resume {
  font-family: "Barlow Condensed", sans-serif;
  font-size: 2rem;
  font-weight: 700;
  color: var(--cp-800);
  line-height: 1;
}

/* Logo de club ------------------------------------------------------------ */
.club-logo {
  width: 56px;
  height: 56px;
  flex: 0 0 56px;
  border-radius: 13px;
  object-fit: cover;
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 6px 14px -8px rgba(19, 88, 184, .9);
}
.club-equipes { display: flex; flex-wrap: wrap; gap: .3rem; }

/* Divers ------------------------------------------------------------------ */
.badge-poule { background: var(--cp-100); color: var(--cp-800); }
.badge-alerte { background: #fdeee7; color: var(--danger); }
.match-row.a-saisir { box-shadow: inset 3px 0 0 var(--cy-500); }
.text-mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .78rem; }

/* Bloc des scores détaillés du classement ---------------------------------- */
/* Plutôt que deux filets, on prolonge dans le corps du tableau la bande que
   l'en-tête donne déjà à la grappe 3-0 … 0-3 (.th-group) : une seule bande
   verticale sépare à la fois les colonnes de synthèse à gauche et les colonnes
   de sets à droite. Le voile passe par box-shadow inset plutôt que par
   background, pour se composer avec le zébrage des lignes, la ligne survolée
   et le podium sans avoir à les surcharger. */
.table-classement .col-groupe {
  --voile: rgba(19, 88, 184, .045);
  box-shadow: inset 0 0 0 999px var(--voile);
}
.table-classement tbody tr:hover .col-groupe { --voile: rgba(19, 88, 184, .075); }

/* Fiche publique d'un club ------------------------------------------------- */
/* Carte de l'annuaire entièrement cliquable : le titre porte un .stretched-link
   dont le calque recouvre la carte. Les liens de contact doivent donc repasser
   au-dessus pour rester utilisables. */
.club-card h2 .stretched-link { color: inherit; text-decoration: none; }
.club-card:hover h2 .stretched-link { color: var(--cp-700); }
.club-card .card-body a:not(.stretched-link) { position: relative; z-index: 2; }

/* Retour à l'annuaire, sur le bandeau sombre de la fiche. */
.page-hero .hero-retour { color: var(--cy-300); text-decoration: none; }
.page-hero .hero-retour:hover { color: var(--cy-200); text-decoration: underline; }

/* Coordonnées du club : icône en gouttière, texte aligné. */
.club-infos li { display: flex; gap: .55rem; margin-bottom: .45rem; }
.club-infos li:last-child { margin-bottom: 0; }
.club-infos li > .bi { color: var(--cp-500); line-height: 1.5; }

/* Tableau des équipes de la fiche club : même habillage que le classement, mais
   sans les deux premières colonnes figées, calibrées pour le classement. */
/* Sélecteur doublé pour l'emporter sur les règles nth-child de style.css. */
.table-classement.table-equipes thead th,
.table-classement.table-equipes tbody td { position: static; box-shadow: none; }

/* Fiche publique d'une équipe ---------------------------------------------- */
/* Nom d'équipe cliquable dans les tableaux : aucun habillage de lien, la
   couleur et la graisse de la maquette sont conservées. */
.lien-equipe { color: inherit; text-decoration: none; }
.lien-equipe:hover { color: var(--cp-700); text-decoration: underline; }

/* Ligne de l'équipe consultée dans le classement de sa poule. Le liseré gauche
   n'est posé que hors podium, pour ne pas effacer la couleur or/argent/bronze. */
.table-classement tbody tr.ligne-active td { background: var(--cy-100); }
.table-classement tbody tr.ligne-active .col-team { font-weight: 700; }
.table-classement tbody tr.ligne-active:not(.rank-1):not(.rank-2):not(.rank-3) td:first-child {
  box-shadow: inset 4px 0 0 var(--cy-500);
}

/* Carte des gymnases ------------------------------------------------------- */
/* Leaflet exige une hauteur explicite sur son conteneur : sans elle, la carte
   se replie sur 0 px et rien ne s'affiche. */
.carte-clubs {
  height: 420px;
  border-bottom-left-radius: inherit;
  border-bottom-right-radius: inherit;
  z-index: 0; /* Les panneaux Leaflet sont empilés ; on les garde sous la barre de navigation. */
}
@media (max-width: 767.98px) {
  .carte-clubs { height: 300px; }
}
/* Sur une fiche de club, un seul marqueur : la carte n'a pas besoin d'autant de place. */
.carte-clubs-compacte { height: 280px; }

/* Marqueur dessiné en CSS — l'icône par défaut de Leaflet réclame des PNG que
   l'importmap ne vendore pas (voir assets/js/carte-clubs.js). */
.marqueur-club-pastille {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: var(--cp-600);
  border: 2px solid var(--surface);
  box-shadow: 0 2px 6px rgba(5, 23, 58, .35);
}
.marqueur-club-pastille > .bi {
  transform: rotate(45deg);
  color: var(--cy-400);
  font-size: .9rem;
  line-height: 1;
}
.leaflet-marker-icon:hover .marqueur-club-pastille { background: var(--cp-800); }

.carte-infobulle { font-size: .875rem; line-height: 1.45; }
.carte-infobulle strong { color: var(--cp-800); }

/* Calendrier filtré côté navigateur : le zébrage de style.css repose sur le
   rang réel des lignes, qui compte aussi celles que le script masque. Dès que
   le script prend la main, c'est lui qui désigne les lignes à teinter. */
.calendrier-js .match-row:nth-of-type(odd) { background: var(--surface); }
.calendrier-js .match-row.rang-pair { background: var(--cp-050); }
.calendrier-js .match-row:hover { background: var(--cy-100); }
.calendrier-js .match-row.derniere { border-bottom: 0; }

/* Calendrier : lien vers la salle d'une rencontre à venir ------------------
   La colonne des points marqués reste vide tant que la rencontre n'est pas
   jouée ; elle accueille alors un lien vers la fiche du club recevant. Une
   icône seule, dimensionnée comme le bloc de score voisin pour que la ligne
   garde son rythme. */
.lien-salle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  color: var(--cp-600);
  background: var(--surface);
  border: 1px solid rgba(7, 36, 81, .13);
  text-decoration: none;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.lien-salle > .bi { font-size: .95rem; line-height: 1; }
.lien-salle:hover,
.lien-salle:focus-visible {
  color: #fff;
  background: var(--cp-600);
  border-color: var(--cp-600);
}

/* ==========================================================================
   Adaptations mobiles
   La maquette d'origine (style.css) est pensée pour le desktop ; les blocs
   ci-dessous ne font que réagencer ses composants sous les points de rupture,
   sans rien redéfinir au-dessus.
   ========================================================================== */

/* Classement : figer l'équipe, replier le détail des scores ---------------- */
/* En dessous de 768 px, style.css relâche les colonnes figées : on fait
   l'inverse, puisque c'est là que le tableau (quinze colonnes, `nowrap`)
   déborde le plus. Tout le détail des scores — la grappe « 3-0 … 0-3 » puis
   Set.P, Set.C et Coeff.S, marqués .col-repli — se replie derrière une
   bascule : il double la largeur du tableau pour un détail secondaire et ne
   laisse visibles que l'équipe et les colonnes de synthèse.
   `:not(.table-equipes)` préserve le tableau de la fiche de club, que la règle
   plus haut dans ce fichier détache justement du figeage. */
.classement-bascule,
.classement-bascule-libelle,
.rang-compact { display: none; }

@media (max-width: 767.98px) {
  .classement-bascule { display: block; }   /* combiné à .visually-hidden : hors écran, mais focusable */

  .classement-bascule-libelle {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    min-height: 44px;
    padding: .4rem 1rem;
    background: var(--cp-050);
    border-bottom: 1px solid var(--line);
    color: var(--cp-700);
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .09em;
    cursor: pointer;
    user-select: none;
  }
  .classement-bascule-libelle .bi { transition: transform .18s ease; }
  .classement-bascule:checked ~ .classement-bascule-libelle .bi { transform: rotate(180deg); }
  .classement-bascule:focus-visible ~ .classement-bascule-libelle {
    outline: 3px solid var(--cp-400);
    outline-offset: -3px;
  }

  .classement-carte .col-repli { display: none; }
  .classement-bascule:checked ~ .table-responsive .col-repli { display: table-cell; }

  .table-classement:not(.table-equipes) thead th,
  .table-classement:not(.table-equipes) tbody td { padding-inline: .35rem; }

  /* Une seule colonne figée, au décalage nul. En figer deux obligerait à coder
     en dur la largeur de la première — or le navigateur ramène les colonnes à
     leur contenu dès que le tableau déborde et ignore le `width` demandé ; le
     décalage de la seconde ne correspondrait plus à rien. Le rang rejoint donc
     la cellule de l'équipe, et sa colonne disparaît. */
  .table-classement:not(.table-equipes) thead th:nth-child(1),
  .table-classement:not(.table-equipes) tbody td:nth-child(1):not([colspan]) { display: none; }

  .table-classement:not(.table-equipes) .rang-compact {
    display: inline-block;
    min-width: 1.4em;
    margin-right: .3rem;
    font-family: "Barlow Condensed", sans-serif;
    font-size: 1rem;
    font-weight: 700;
    text-align: right;
    color: var(--ink-500);
  }
  .table-classement:not(.table-equipes) tr.rank-1 .rang-compact,
  .table-classement:not(.table-equipes) tr.rank-2 .rang-compact,
  .table-classement:not(.table-equipes) tr.rank-3 .rang-compact { color: var(--cp-900); }

  .table-classement:not(.table-equipes) .col-team { min-width: 0; }
  /* La pastille ne dit plus rien que le liseré et le rang ne disent déjà. */
  .table-classement:not(.table-equipes) .col-team .team-dot { display: none; }
  /* Le nom est tronqué sur son propre lien : `max-width` n'a pas d'effet sur
     une cellule de tableau en disposition automatique. */
  .table-classement:not(.table-equipes) .col-team .lien-equipe {
    display: inline-block;
    max-width: 7rem;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
  }

  .table-classement:not(.table-equipes) thead th:nth-child(2),
  .table-classement:not(.table-equipes) tbody td:nth-child(2) {
    position: sticky;
    left: 0;
    z-index: 2;
    box-shadow: 10px 0 12px -10px rgba(7, 36, 81, .3);
  }
  .table-classement:not(.table-equipes) thead th:nth-child(2) { z-index: 3; }

  /* Podium et ligne active portaient leur liseré sur la colonne du rang, que
     l'on vient de masquer : il passe sur la cellule de l'équipe, sans effacer
     l'ombre de défilement. */
  .table-classement:not(.table-equipes) tbody tr.rank-1 td:nth-child(2),
  .table-classement:not(.table-equipes) tbody tr.rank-2 td:nth-child(2),
  .table-classement:not(.table-equipes) tbody tr.rank-3 td:nth-child(2),
  .table-classement:not(.table-equipes) tbody tr.ligne-active td:nth-child(2) {
    box-shadow: inset 4px 0 0 var(--accent, var(--cy-500)), 10px 0 12px -10px rgba(7, 36, 81, .3);
  }
}

/* Classement : fiabiliser le figeage du desktop --------------------------- */
/* style.css fige deux colonnes et cale la seconde sur `left: 46px`, la largeur
   *demandée* pour la première. Or dès que le tableau déborde — toute fenêtre
   entre 768 px et ~1000 px — le navigateur ramène la colonne à son contenu
   (23,5 px mesurés) et ignore le `width` : la colonne « Équipe » se décale de
   22,5 px et recouvre « Points ». On garantit donc la largeur au lieu de la
   demander, via une boîte interne dont la largeur minimale, ajoutée au
   remplissage de la cellule, fait exactement le décalage attendu. */
@media (min-width: 768px) {
  .table-classement .col-rank { padding-inline: .45rem; }
  .table-classement .col-rank .rang-cellule {
    display: inline-block;
    min-width: calc(46px - .9rem);
  }
}

/* Backoffice : menu replié derrière une bascule sous 992 px ---------------- */
/* Le menu latéral précède le contenu dans le flux (colonnes de espace/base) :
   déplié, il repousse sous la ligne de flottaison la raison d'être de chaque
   page. Sous 992 px il se replie donc derrière une bascule (collapse Bootstrap,
   déjà chargé pour la barre publique) ; au-dessus, il reprend sa colonne et la
   bascule disparaît. */
.espace-nav-liste {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.espace-nav-bascule {
  display: none;
  align-items: center;
  gap: .6rem;
  width: 100%;
  padding: .55rem .8rem;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  font-size: .85rem;
  font-weight: 700;
  color: var(--cp-800);
}
.espace-nav-bascule > .bi-list { font-size: 1.15rem; color: var(--cp-500); }
.espace-nav-bascule .espace-nav-chevron {
  margin-left: auto;
  font-size: .8rem;
  color: var(--ink-500);
  transition: transform .2s ease;
}
.espace-nav-bascule .badge + .espace-nav-chevron { margin-left: 0; }
.espace-nav-bascule[aria-expanded="true"] { background: var(--cp-050); }
.espace-nav-bascule[aria-expanded="true"] .espace-nav-chevron { transform: rotate(180deg); }

@media (max-width: 991.98px) {
  /* Collé en haut, un menu replié puis déplié recouvrirait le contenu. */
  .espace-nav { position: static; }
  .espace-nav-bascule { display: flex; min-height: 44px; }
  .espace-nav-liste { padding-top: .35rem; }
  .espace-nav-liste a { min-height: 44px; }
  /* La bascule porte déjà « Mon espace » : l'intertitre ferait doublon. */
  .espace-nav-liste .espace-nav-titre:first-child { display: none; }
}

@media (min-width: 992px) {
  /* Hors mobile la liste ne se replie plus : on neutralise `.collapse`, comme
     Bootstrap le fait lui-même pour `.navbar-collapse`. */
  .espace-nav-liste { display: flex !important; }
}

/* Espace connecté : tableaux en cartes sous 768 px ------------------------- */
/* Les listes de l'espace ont cinq à six colonnes et poussent leur bouton
   d'action en dernière colonne, donc hors écran sur mobile. Empilées en
   cartes, chaque cellule porte son intitulé via `data-libelle` (l'en-tête du
   tableau ayant disparu) et l'action revient en pied de carte. */
@media (max-width: 767.98px) {
  .table-espace > thead { display: none; }
  .table-espace,
  .table-espace > tbody { display: block; }

  .table-espace > tbody > tr {
    display: flex;
    flex-direction: column;
    padding: .7rem .85rem;
    margin-bottom: .6rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
  }
  .table-espace > tbody > tr:last-child { margin-bottom: 0; }
  .table-espace > tbody > tr.non-lu { background: var(--cy-100); }

  .table-espace > tbody > tr > td {
    display: block;
    padding: .15rem 0;
    border: 0;
    background: transparent;
    text-align: left !important;
  }

  /* Cellule-titre : en tête de carte quel que soit l'ordre des colonnes. */
  .table-espace > tbody > tr > td[data-titre] {
    order: -1;
    margin-bottom: .45rem;
    padding-bottom: .45rem;
    border-bottom: 1px solid var(--line);
    font-size: .95rem;
  }

  /* Intitulé en gouttière : la grille garde toutes les valeurs dans la
     deuxième colonne, y compris quand la cellule contient plusieurs éléments. */
  .table-espace > tbody > tr > td[data-libelle] {
    display: grid;
    grid-template-columns: 7.5rem 1fr;   /* « Rattachements » tient sur une ligne */
    gap: .1rem .6rem;
    align-items: baseline;
  }
  .table-espace > tbody > tr > td[data-libelle]::before {
    content: attr(data-libelle);
    grid-column: 1;
    white-space: nowrap;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--ink-500);
  }
  /* Une adresse longue se coupe plutôt que de déborder de sa colonne. */
  .table-espace > tbody > tr > td[data-libelle] > * { grid-column: 2; overflow-wrap: anywhere; }
  /* Un badge est une pastille, pas une barre : il ne s'étire pas sur la colonne. */
  .table-espace > tbody > tr > td[data-libelle] > .badge { justify-self: start; }

  /* Pied de carte : les actions, au pouce. `:not([colspan])` écarte les états
     vides, dont l'unique cellule est aussi la dernière — sans quoi la règle
     suivante les escamoterait. */
  .table-espace > tbody > tr > td:last-child:not([colspan]) {
    order: 1;
    display: flex;
    gap: .5rem;
    margin-top: .7rem;
  }
  .table-espace > tbody > tr > td:last-child:not([colspan]):not(:has(.btn, button)) { display: none; }
  .table-espace > tbody > tr > td:last-child .btn { min-height: 42px; min-width: 48px; }
  /* Une action nommée — « Saisir », « Corriger » — occupe toute la largeur de
     la carte : c'est la raison d'être de la ligne. Une action réduite à son
     icône (`.btn-icone`) garde sa taille, sinon elle devient une boîte vide. */
  .table-espace > tbody > tr > td:last-child > .btn:not(.btn-icone),
  .table-espace > tbody > tr > td:last-child > form:not(:has(.btn-icone)) { flex: 1 1 auto; }
  .table-espace > tbody > tr > td:last-child > form:not(:has(.btn-icone)) > .btn { width: 100%; }

  /* Étirée, l'action nommée devenait un aplat bleu avec deux mots perdus au
     centre. Elle se lit maintenant comme une barre d'action : pictogramme et
     libellé calés à gauche, chevron à droite pour dire qu'elle ouvre une page.
     Le liseré jaune est celui que la charte pose déjà sur les en-têtes de
     carte, les titres de journée et les rencontres à saisir. */
  .table-espace > tbody > tr > td:last-child .btn:not(.btn-icone) {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: .3rem;
    min-height: 46px;
    padding-inline: .95rem;
    font-size: .88rem;
    font-weight: 700;
  }
  .table-espace > tbody > tr > td:last-child .btn:not(.btn-icone) > .bi { font-size: 1.05em; }
  .table-espace > tbody > tr > td:last-child .btn:not(.btn-icone)::after {
    content: "\f285";                 /* bi-chevron-right */
    font-family: bootstrap-icons;
    margin-left: auto;
    font-size: .95em;
    opacity: .65;
  }
  .table-espace > tbody > tr > td:last-child .btn-primary:not(.btn-icone) {
    background-image: linear-gradient(150deg, var(--cp-600) 0%, var(--cp-800) 100%);
    border-color: transparent;
    box-shadow: inset 4px 0 0 var(--cy-500), 0 6px 16px -9px rgba(19, 88, 184, .95);
  }
  .table-espace > tbody > tr > td:last-child .btn-outline-primary:not(.btn-icone) {
    box-shadow: inset 4px 0 0 var(--cp-200);
  }

  /* Les états vides (« Aucune rencontre… ») restent une simple ligne centrée. */
  .table-espace > tbody > tr:has(> td[colspan]) {
    display: block;
    padding: 0;
    border: 0;
    background: transparent;
  }
  .table-espace > tbody > tr > td[colspan] {
    display: block;
    margin: 0;
    text-align: center !important;
  }
}
