/* ============================================================
   LA FICHE D'UN MATCH — ce que cette feuille ajoute, et rien de
   plus.

   Le socle donne les couleurs et les polices. analyse.css donne
   la grammaire des pages de résultat : la carte, le surtitre
   coloré, la note de provenance, et la ligne « libellé — barre —
   valeur » que les statistiques réutilisent telle quelle.

   Ne sont écrits ici que les quatre objets que cette page est
   seule à posséder : le tableau d'affichage, la ligne du temps,
   le film du match, et la feuille de composition.

   ------------------------------------------------------------
   LA SEULE AUDACE DE LA PAGE, ET POURQUOI ELLE EST LÀ.

   La direction visuelle du site s'appelle « Nocturne » : le
   bleu-noir d'un stade le soir, l'ambre des projecteurs. Jusqu'ici
   l'ambre servait à écrire des chiffres.

   Sur un match en cours, elle devient littérale. La ligne du
   temps est un axe de 0 à 90 minutes ; ce qui a déjà été joué est
   éclairé par le projecteur, ce qui reste est dans le noir, et le
   curseur de la minute en cours EST la lampe. Un match qui vient
   de commencer est une page presque noire ; un match fini est
   éclairé de bout en bout. La forme de la page dit où on en est
   avant qu'on ait lu un chiffre.

   LE VOCABULAIRE DES MARQUES VIENT DU FOOTBALL, PAS D'UNE
   BIBLIOTHÈQUE D'ICÔNES. Un but est un disque — un ballon. Un
   carton est un petit rectangle debout — la forme d'un carton.
   Un remplacement est un chevron. La FORME porte le sens, la
   couleur ne fait que dire le camp : c'est ce qui rend la ligne
   lisible pour qui distingue mal les couleurs, et c'est ce qui
   permet de réutiliser exactement les mêmes marques dans le film
   du match, en dessous. On apprend le vocabulaire une fois.
   ============================================================ */

:root {
  /* Le jaune et le rouge d'un carton. Ce sont les deux seules couleurs
     que cette page ajoute au site, et elles ne servent qu'à ça.

     L'ambre du site (#F2A73B) ne pouvait pas faire l'affaire : il désigne
     déjà l'équipe qui reçoit, et un carton ambre sur la moitié ambre de
     la ligne aurait été illisible. Celui-ci est plus froid et plus clair,
     franchement distinct du camp à domicile. */
  --carton-j: #F5D547;
  --carton-r: #E8483C;
}

:root[data-theme="light"] {
  /* De jour, un jaune clair sur fond blanc ne passe pas le seuil de
     contraste. On descend les deux d'un cran, la forme reste la même. */
  --carton-j: #9A7400;
  --carton-r: #B3311F;
}

/* ============================================================
   LE TABLEAU D'AFFICHAGE
   ============================================================ */

.tableau {
  padding: clamp(1.2rem, 3vw, 2rem) clamp(1rem, 3vw, 1.9rem);
  display: flex;
  flex-direction: column;
  gap: var(--s5);
}

.tab-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  flex-wrap: wrap;
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--line);
}

.tab-lg {
  font-family: var(--body);
  font-size: var(--t-xs);
  font-weight: 650;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* L'état du match : « 63' », « Mi-temps », « Terminé ». En mono, parce que
   c'est une horloge, et que le chiffre ne doit pas danser d'une seconde à
   l'autre pendant qu'il se met à jour. */
.tab-etat {
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: var(--s2);
}

/* Le point rouge du direct : le seul élément clignotant du site, et il ne
   clignote que quand le match est réellement en cours. */
.tab-etat.direct { color: var(--live); }

.tab-etat.direct::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--live);
  animation: battement 2s ease-in-out infinite;
}

@keyframes battement {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.82); }
}

.tab-score {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s4);
}

.tab-eq {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s2);
  text-align: center;
  min-width: 0;
}

.tab-eq img, .tab-eq .ecusson {
  width: clamp(2.6rem, 7vw, 3.6rem);
  height: clamp(2.6rem, 7vw, 3.6rem);
}

.tab-eq .nom {
  font-family: var(--display);
  font-stretch: var(--w-serre);
  font-weight: 650;
  font-size: clamp(1rem, 2.6vw, 1.35rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

.tab-eq .cote {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}
.tab-eq.a .cote { color: var(--a); }
.tab-eq.b .cote { color: var(--b); }

/* Le score. C'est le plus gros caractère de tout le site, et c'est
   normal : c'est la seule chose que la moitié des visiteurs vient voir. */
.tab-nb {
  font-size: clamp(2.6rem, 11vw, 4.4rem);
  font-weight: 500;
  letter-spacing: -0.06em;
  line-height: 0.9;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.tab-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
  border-top: 1px solid var(--line);
  padding-top: var(--s5);
}

.tab-lieu {
  font-size: var(--t-sm);
  color: var(--ink-faint);
  text-align: center;
  line-height: 1.5;
}

/* ============================================================
   LA LIGNE DU TEMPS
   ============================================================ */

.ldt {
  --joue: 0%;
  display: grid;
  grid-template-rows: 1.5rem auto 1.5rem auto;
  gap: var(--s1);
  position: relative;
}

/* les deux bandes où se posent les marques, au-dessus et en dessous */
.ldt-camp { position: relative; height: 1.5rem; }
.ldt-camp.a { grid-row: 1; align-self: end; }
.ldt-camp.b { grid-row: 3; align-self: start; }

.ldt-piste {
  grid-row: 2;
  position: relative;
  height: var(--bar-fin);
  border-radius: var(--r-pill);
  background: var(--surface-alt);
  overflow: hidden;
}

/* LA LUMIÈRE : ce qui a été joué. Elle part sombre à gauche et monte vers
   l'ambre à droite, comme une nappe de projecteur qui s'arrête net à la
   minute en cours. */
.ldt-lumiere {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--joue);
  background: linear-gradient(to right,
    color-mix(in srgb, var(--a) 28%, transparent),
    var(--a));
  border-radius: var(--r-pill);
  animation: ldtBalaye 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  transform-origin: left;
}

@keyframes ldtBalaye {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* le repère de la mi-temps : un cran dans la piste, pas une décoration */
.ldt-mitemps {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--ground);
  opacity: 0.9;
}

/* LE CURSEUR : la lampe. Il n'existe que pendant le match. */
.ldt-curseur {
  position: absolute;
  top: -0.35rem;
  bottom: -0.35rem;
  left: var(--joue);
  width: 2px;
  margin-left: -1px;
  background: var(--a-haut);
  border-radius: var(--r-pill);
  box-shadow: 0 0 0.5rem 0.15rem color-mix(in srgb, var(--a) 55%, transparent);
  animation: lampe 2.4s ease-in-out infinite;
}

@keyframes lampe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* ---- les marques ----
   Toutes posées en pourcentage de la durée du match. Chacune est un
   bouton : on peut la survoler au doigt comme à la souris, et le nom du
   joueur s'affiche dans son infobulle. */
/* LA MARQUE EST UN GLYPHE, PAS UNE POSITION.

   Elle était définie comme « position: absolute », parce qu'elle est née
   sur la ligne du temps où elle se pose à une minute précise. Mais elle
   sert à trois endroits — la ligne, le film, et à côté d'un nom dans la
   composition — et dans les deux derniers elle doit se comporter comme une
   lettre au milieu d'un texte. Absolue par défaut, elle se décrochait de
   sa ligne et venait s'empiler sur ses voisines.

   C'est donc la LIGNE DU TEMPS qui positionne, pas la marque. Partout
   ailleurs, elle coule dans le texte sans rien demander. */
.ldt-marque {
  display: inline-block;
  padding: 0;
  border: none;
  background: none;
  cursor: default;
  line-height: 0;
  vertical-align: middle;
}

.ldt-camp .ldt-marque {
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
}

/* UN BUT EST UN DISQUE — un ballon vu de loin. C'est la marque la plus
   grosse : c'est le seul événement qui change le score. */
.ldt-marque.but::before {
  content: "";
  display: block;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--a);
  box-shadow: 0 0 0 2px var(--surface);
}
.ldt-camp.b .ldt-marque.but::before { background: var(--b); }

/* UN CARTON EST UN RECTANGLE DEBOUT — la forme de l'objet. La couleur dit
   lequel des deux ; la forme dit que c'est un carton, même en noir et
   blanc. */
.ldt-marque.carton::before {
  content: "";
  display: block;
  width: 0.34rem;
  height: 0.55rem;
  border-radius: 1px;
  background: var(--carton-j);
}
.ldt-marque.carton.rouge::before { background: var(--carton-r); }

/* UN REMPLACEMENT EST UN CHEVRON. Il pointe vers la piste : vers le bas
   au-dessus, vers le haut en dessous — le mouvement va vers le terrain. */
.ldt-marque.change::before {
  content: "";
  display: block;
  width: 0;
  height: 0;
  border-left: 0.28rem solid transparent;
  border-right: 0.28rem solid transparent;
  border-top: 0.36rem solid var(--ink-faint);
}
.ldt-camp.b .ldt-marque.change::before {
  border-top: none;
  border-bottom: 0.36rem solid var(--ink-faint);
}

.ldt-echelle {
  grid-row: 4;
  position: relative;
  height: 1rem;
  font-family: var(--mono);
  font-size: var(--t-xs);
  color: var(--ink-faint);
}
.ldt-echelle span { position: absolute; transform: translateX(-50%); }
.ldt-echelle span:first-child { transform: none; }
.ldt-echelle span:last-child { transform: translateX(-100%); }

/* La légende des marques : sans elle, trois formes ne sont que trois
   formes. Elle est discrète mais elle est là — c'est la même règle que le
   code de couleur des surtitres sur la page d'analyse. */
.ldt-legende {
  grid-row: 5;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  padding-top: var(--s2);
  font-size: var(--t-xs);
  color: var(--ink-faint);
}
.ldt-legende span { display: inline-flex; align-items: center; gap: var(--s2); }
.ldt-legende i { flex: none; }

/* ============================================================
   LE FILM DU MATCH
   ============================================================ */

.film { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }

.film-li {
  display: grid;
  grid-template-columns: 3.2rem 1.2rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s3);
  padding: var(--s3) var(--s3) var(--s3) var(--s2);
  border-bottom: 1px solid var(--line-soft);
  border-left: 3px solid transparent;
}
.film .film-li:last-child { border-bottom: none; }

/* ---- les deux poids ----

   Un but change le score, un remplacement non. Sur un match à neuf
   changements, tout afficher au même poids donnait une liste où les deux
   buts ne se voyaient plus. On ne retire rien — on hiérarchise.

   Le but monte d'un cran et reçoit le score du moment ; le remplacement
   descend d'un cran et passe en gris. Les cartons restent au milieu :
   ils ne changent pas le score mais ils changent le match. */
.film-li.majeur { padding-top: var(--s4); padding-bottom: var(--s4); }
.film-li.majeur .film-txt b { font-size: var(--t-lg); line-height: 1.25; }
.film-li.majeur .film-min { color: var(--ink); }

.film-li.mineur .film-txt b { font-weight: 500; color: var(--ink-soft); font-size: var(--t-sm); }

/* Le score après le but, à droite : c'est le tableau d'affichage de cet
   instant-là. Il n'apparaît QUE sur les buts, et seulement si le compte
   retombe sur le score final donné par le fournisseur. */
.film-sc {
  font-family: var(--mono);
  font-size: var(--t-md);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: var(--surface-alt);
  padding: var(--s1) var(--s2);
  border-radius: var(--r-sm);
  white-space: nowrap;
}

/* Le camp se lit au filet de gauche, pas au texte : la liste se parcourt
   alors en diagonale, un camp après l'autre, sans lire les noms. */
.film-li.a { border-left-color: var(--a); }
.film-li.b { border-left-color: var(--b); }

.film-min {
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  text-align: right;
}

/* la marque, exactement celle de la ligne du temps */
.film-marque { display: block; line-height: 0; align-self: center; }

.film-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.film-txt b { font-weight: 650; font-size: var(--t-md); line-height: 1.3; }
.film-txt span { font-size: var(--t-sm); color: var(--ink-faint); line-height: 1.4; }

.film-vide { font-size: var(--t-md); color: var(--ink-soft); line-height: 1.65; max-width: var(--mesure); }

/* ============================================================
   LES COMPOSITIONS
   ============================================================ */

.compo-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  flex-wrap: wrap;
}

.compo-forme {
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.compo-coach { font-size: var(--t-sm); color: var(--ink-faint); }

.compo-groupe {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-faint);
  margin-top: var(--s3);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--line-soft);
}

.compo-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }

.compo-j {
  display: grid;
  grid-template-columns: 2.2rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s3);
  padding: var(--s2) 0;
  font-size: var(--t-md);
}

.compo-n {
  font-family: var(--mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
  text-align: right;
}

.compo-p {
  font-family: var(--mono);
  font-size: var(--t-xs);
  color: var(--ink-faint);
}

/* Un joueur qui a marqué, pris un carton ou changé pendant le match porte
   sa marque à côté de son nom. C'est la troisième apparition du même
   vocabulaire sur la page, et c'est voulu : on l'a appris en haut. */
.compo-marques { display: inline-flex; gap: 4px; align-items: center; margin-left: var(--s2); }
.compo-marques i { flex: none; }

.compo-nom { overflow-wrap: anywhere; }

/* ============================================================
   LES DEUX BOUTONS D'ACTION

   Ils sont au bas du tableau d'affichage, et dans cet ordre : on
   vient de voir le score, on peut vouloir creuser la rencontre ou
   l'envoyer à quelqu'un. Le premier est plein, le second est un
   contour — un seul des deux est le geste principal, et la page
   doit dire lequel sans qu'on ait à lire les deux.
   ============================================================ */

.tab-boutons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s3);
}

/* Les pictogrammes suivent la taille et la couleur du texte du bouton :
   ils sont dessinés en « currentColor », donc ils changent tout seuls
   entre le thème sombre et le thème clair. */
.tab-boutons .ico { width: 1.05em; height: 1.05em; flex: none; }
.tab-boutons .btn-ghost { gap: var(--s2); }
.tab-boutons .btn-ghost .ico { opacity: 0.75; }

/* La confirmation du partage. En mono et en petit : c'est un accusé de
   réception, pas une phrase à lire. */
.tab-dit {
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--a);
  text-align: center;
}

/* ============================================================
   LES ONGLETS

   Une barre unique, collée en haut, qui ne se déplie jamais sur
   deux rangs : sur un écran étroit elle défile latéralement plutôt
   que de doubler de hauteur. Une barre de navigation qui grandit
   quand l'écran rétrécit prend la place de ce qu'elle sert à
   atteindre.

   L'ONGLET OUVERT EST ÉCLAIRÉ, PAS SOULIGNÉ. Le site s'appelle
   « Nocturne » : le fond du stade la nuit, l'ambre des
   projecteurs. Le filet ambre posé sur l'onglet ouvert est
   exactement celui du curseur de la ligne du temps — même
   couleur, même halo. Sur cette page, l'ambre veut dire « c'est
   ici que ça se passe », que ce soit une minute ou une rubrique.

   La couleur n'est pas seule à porter l'information : l'onglet
   ouvert a aussi un fond, une graisse et un halo. Qui distingue
   mal l'ambre du gris voit quand même lequel est ouvert.
   ============================================================ */

.onglets {
  /* --haut-barre est posée par match.js : c'est la hauteur réelle de la
     barre du site, mesurée après le chargement des polices. Écrite en dur,
     elle aurait été fausse le jour où la barre change d'un pixel — et sur
     petit écran la barre du site ne colle plus, donc l'onglet doit remonter
     à zéro. */
  position: sticky;
  top: var(--haut-barre, 0px);
  z-index: 5;

  display: flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);

  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.onglets::-webkit-scrollbar { display: none; }

/* Même règle que la barre du site : translucide seulement si le navigateur
   sait flouter ce qu'il y a derrière. Sinon, le film du match défilerait au
   travers des onglets. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .onglets {
    background: var(--topbar-fond);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
  }
}

.onglet {
  position: relative;
  flex: 1 1 auto;
  min-width: max-content;
  min-height: 40px;
  padding: var(--s2) var(--s4);
  border: none;
  background: none;
  border-radius: var(--r-pill);
  font-family: var(--body);
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.006em;
  color: var(--ink-faint);
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}

.onglet:hover { color: var(--ink); background: var(--surface-alt); }

.onglet[aria-selected="true"],
.onglet[aria-selected="true"]:hover {
  color: var(--a);
  background: var(--a-soft);
}

/* LA LAMPE — le même filet que le curseur de la ligne du temps. */
.onglet[aria-selected="true"]::before {
  content: "";
  position: absolute;
  left: 26%;
  right: 26%;
  top: 3px;
  height: 2px;
  border-radius: var(--r-pill);
  background: var(--a-haut);
  box-shadow: 0 0 0.5rem 0.1rem color-mix(in srgb, var(--a) 55%, transparent);
}

/* CEINTURE ET BRETELLES.

   La hauteur est mesurée par match.js, mais une mesure dépend d'un
   événement — et un événement peut manquer : un navigateur qui ne prévient
   pas d'un changement de largeur laisserait la barre décalée de cent
   pixels vers le bas, avec un trou au-dessus. Sous 46 rem, le socle décide
   que la barre du site ne colle plus ; on remet donc l'onglet à zéro ici
   aussi, en CSS, où aucun événement n'est nécessaire. C'est le même seuil,
   écrit deux fois, volontairement.
   ------------------------------------------------------------ */
@media (max-width: 46rem) {
  .onglets { top: 0; }
}

/* Le panneau ouvert reçoit le focus au clavier ; il ne doit pas se cerner
   d'un trait à chaque clic de souris sur un onglet. */
.panneau:focus { outline: none; }

/* ============================================================
   MOUVEMENT — la règle du site : aucun pour qui n'en veut pas.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .ldt-lumiere, .tab-etat.direct::before, .ldt-curseur {
    animation: none;
  }
}

/* ============================================================
   ÉCRANS ÉTROITS

   La ligne du temps reste horizontale : c'est un coup d'œil, pas une
   lecture. Le détail se lit dans le film juste en dessous, qui lui est
   déjà vertical. Deux objets, deux rôles — on ne duplique pas.
   ============================================================ */

@media (max-width: 34rem) {
  .tab-score { gap: var(--s2); }
  .film-li { grid-template-columns: 2.6rem 1.1rem minmax(0, 1fr) auto; gap: var(--s2); }
  .ldt-legende { font-size: 0.7rem; gap: var(--s2) var(--s3); }
}

/* ============================================================
   L'ÉLÉMENT D'ACCUEIL DE LA PAGE match.html

   Le squelette de la fiche est posé dans un conteneur vide, ce qui
   ajoutait un étage : les blocs devenaient les enfants de ce
   conteneur, et non plus ceux du <main>. Ils perdaient donc l'espace
   que le <main> met entre ses enfants, et la fiche se retrouvait
   tassée — le tableau d'affichage collé à la légende, la légende
   collée aux onglets.

   « display: contents » fait disparaître l'étage sans toucher au
   contenu : le conteneur ne dessine plus rien, ses enfants
   redeviennent ceux du <main>, et l'espacement revient tout seul.
   ============================================================ */
#hoteFiche { display: contents; }

/* ============================================================
   LA FENÊTRE DE MATCH

   La même fiche, posée au milieu de l'écran par-dessus la liste
   des rencontres, au lieu de remplacer la page.

   POURQUOI ELLE EST PLUS PETITE QUE LA PAGE, ET POURQUOI C'EST
   LE POINT. On ouvre un match d'un coup d'œil, pendant qu'on
   parcourt la journée. Une fiche qui prend tout l'écran fait de
   ce coup d'œil une visite : on perd la liste, sa position, et
   il faut un retour en arrière pour reprendre. La fenêtre laisse
   voir le bord de la liste derrière elle — c'est cette bande
   sombre qui dit « vous n'êtes pas parti ».

   ELLE S'ARRÊTE À 44 REM DE LARGE, ET C'EST VOLONTAIREMENT
   ÉTROIT. Une fenêtre large finit par ressembler à une page :
   elle couvre la liste, et l'effet « je jette un œil sans
   partir » disparaît. À 44 rem, les deux colonnes de composition
   tiennent encore côte à côte, et il reste du fond sombre tout
   autour. La page entière, elle, va jusqu'à la largeur du site :
   c'est la même fiche, mais on y vient pour s'installer.
   ============================================================ */

/* Pendant qu'une fenêtre est ouverte, la page derrière ne défile plus.
   Sans ça, un doigt qui glisse sur le fond sombre fait bouger la liste
   dessous — on referme et on ne retrouve plus sa place, ce que la fenêtre
   était précisément censée éviter. */
.fenetre-figee { overflow: hidden; }

.modale {
  /* <dialog> arrive avec des marges, une bordure et un fond de navigateur.
     On repart de zéro : tout ce qui suit est à nous. */
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--ground);
  color: var(--ink);

  width: min(44rem, 92vw);
  max-height: min(82vh, 46rem);
  overflow: hidden;

  /* FIXE, PAS RELATIF — ET LA NUANCE COÛTE CHER.

     La croix de fermeture est posée dans le coin de la fenêtre : il lui
     faut donc un ancrage. Écrit « relative », cet ancrage remettait la
     fenêtre dans le flux de la page : elle se calait sous la liste au lieu
     du milieu de l'écran, et suivait le défilement — ouverte après avoir
     descendu la liste, elle apparaissait décalée vers le bas, une partie
     hors de l'écran.

     « fixed » ancre la croix tout aussi bien et arrime la fenêtre à
     l'écran, où qu'on en soit dans la page. */
  position: fixed;
  flex-direction: column;

  /* L'ombre porte la fenêtre au-dessus du reste. Elle est large et douce :
     une ombre courte et dure ferait un autocollant, pas un objet posé. */
  box-shadow: 0 1.5rem 3.5rem rgba(0, 0, 0, 0.55);
}

/* LA FENÊTRE REÇOIT LE CURSEUR DU CLAVIER, MAIS N'EST PAS UN BOUTON.

   On lui donne le curseur à l'ouverture pour que la touche Échap et la
   tabulation restent à l'intérieur. Le site cerne d'un anneau ambre tout
   ce qui reçoit le curseur — c'est juste pour les commandes, mais ici cela
   entourait la fenêtre entière d'un cadre lumineux, comme si elle attendait
   qu'on appuie dessus. */
.modale:focus, .modale:focus-visible { outline: none; }

/* Un <dialog> fermé doit rester invisible : on ne peut donc pas écrire
   « display: flex » tout court. */
.modale[open] { display: flex; }

/* LE FOND SOMBRE. Il assombrit sans effacer : on doit deviner la liste
   derrière, sinon la fenêtre ressemble à une nouvelle page et l'effet
   recherché est perdu. */
.modale::backdrop {
  background: rgba(6, 9, 12, 0.7);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* Le contenu défile DANS la fenêtre, pas la fenêtre dans la page.
   « overscroll-behavior » empêche le défilement de continuer sur la page
   du dessous quand on arrive en bas de la liste. */
.modale-corps {
  overflow-y: auto;
  overscroll-behavior: contain;
  max-width: none;
  padding: var(--s4) var(--s4) var(--s5);
  gap: var(--s4);
}

/* La croix flotte au-dessus du contenu qui défile dessous. Elle a la taille
   d'une cible tactile, pas d'une icône : 44 pixels, la règle du site. */
.modale-fermer {
  position: absolute;
  top: var(--s3);
  right: var(--s3);
  z-index: 10;

  width: 2.4rem;
  height: 2.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;

  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink-soft);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.modale-fermer svg { width: 1.05rem; height: 1.05rem; }
.modale-fermer:hover { color: var(--ink); border-color: var(--ink-faint); }

/* LES ONGLETS COLLENT AU HAUT DE LA FENÊTRE, PAS AU HAUT DE LA PAGE.

   Dans la page, ils se calent sous la barre du site — d'où la hauteur
   mesurée. Dans la fenêtre, il n'y a pas de barre du site au-dessus : le
   décalage laisserait un trou de cent pixels au-dessus des onglets, avec
   du contenu qui défile dedans. */
.modale .onglets { top: 0; }

/* Le tableau d'affichage occupe déjà le haut de la fenêtre ; la croix vient
   se poser dessus, à droite du championnat. On lui réserve la place. */
.modale .tab-tete { padding-right: 3rem; }

/* Une fenêtre ne se ferme pas par un lien qui recharge une page : le bouton
   de retour du bloc de panne n'a rien à y faire, match.js le remplace. */
.modale .suite { display: none; }

/* L'ENTRÉE : la fenêtre monte de quelques pixels et le fond s'assombrit.
   Deux dixièmes de seconde — le temps qu'il faut pour comprendre d'où elle
   vient, pas assez pour attendre. */
@keyframes modaleEntre {
  from { opacity: 0; transform: translateY(0.75rem) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes fondEntre {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.modale[open] { animation: modaleEntre 0.2s cubic-bezier(0.16, 1, 0.3, 1); }
.modale[open]::backdrop { animation: fondEntre 0.2s ease; }

@media (prefers-reduced-motion: reduce) {
  .modale[open], .modale[open]::backdrop { animation: none; }
}

/* ------------------------------------------------------------
   SUR TÉLÉPHONE, CE N'EST PLUS UNE FENÊTRE : C'EST UNE FEUILLE
   QUI MONTE DU BAS.

   Une petite fenêtre centrée sur un écran de six pouces laisse
   quatre bandes de fond inutiles et deux colonnes de composition
   à trente caractères. La feuille prend toute la largeur, s'ancre
   en bas — là où est le pouce — et garde une bande de liste
   visible en haut, qui reste le repère « je n'ai pas quitté ».
   ------------------------------------------------------------ */
@media (max-width: 40rem) {
  .modale {
    width: 100vw;
    max-width: 100vw;
    max-height: 92vh;
    margin: auto auto 0;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-bottom: none;
  }

  .modale-corps { padding: var(--s4) var(--s3) var(--s5); }

  @keyframes modaleEntre {
    from { opacity: 0; transform: translateY(2rem); }
    to   { opacity: 1; transform: none; }
  }
}
