/* =====================================================================
   scores.css — surcouche du TABLEAU DES SCORES
   Chargée APRÈS style.css : reprend la palette et les lignes du roster,
   et n'ajoute que ce qui concerne l'affichage en direct des données.
   (Aucun style de tirage / animation de largage ici.)
   ===================================================================== */

/* ------------------------- Fraîcheur des données ------------------------- */
.freshness {
  font-family: var(--f-mono); font-size: 14px; letter-spacing: 2px;
  color: var(--ink-dim);
  padding: 2px 10px; border: 1px solid var(--od-line); border-radius: 2px;
  min-width: 150px; text-align: center;
}
/* Éclair jaune au moment précis où de nouvelles données arrivent. */
.freshness.pulse { animation: freshPulse .9s ease-out; }
@keyframes freshPulse {
  0%   { background: var(--hazard); color: var(--night); border-color: var(--hazard); }
  100% { background: transparent; color: var(--ink-dim); border-color: var(--od-line); }
}
/* Données périmées (source injoignable depuis trop longtemps). */
.freshness.stale { color: var(--alert); border-color: var(--alert); animation: blink 1.6s steps(2) infinite; }

/* =========================== PLATEAU 2 COLONNES ==========================
   `--vis`  : nombre de lignes visibles par colonne (10 max), injecté par le JS.
   `--rowh` : hauteur d'une ligne, déduite de la place réellement disponible.
   Une seule colonne tant qu'il y a 10 joueurs ou moins (inutile de couper un
   petit classement en deux) ; deux colonnes au-delà.
   ======================================================================== */
.board {
  --vis: 10;
  --gap: 3px;
  --rowh: min(76px, calc((100vh - 350px) / var(--vis)));
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: minmax(0, 1fr);
  align-content: center; justify-content: center;
  gap: 0 48px;
  width: 100%;
}
/* Bandeau de fin de partie affiché (teams.js) : sa hauteur est prise sur les lignes. */
.has-banner .board { --rowh: min(76px, calc((100vh - 350px - 54px) / var(--vis))); }
.board.two-col { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.board:not(.two-col) #col-b { display: none; }

.board-col { display: flex; flex-direction: column; min-width: 0; }

/* Fenêtre de lecture : exactement `--vis` lignes, le reste est masqué. */
.col-viewport {
  overflow: hidden;
  height: calc(var(--vis) * (var(--rowh) + var(--gap)));
}
/* Tapis défilant : la liste + sa copie, pour boucler sans couture. */
.col-track {
  display: flex; flex-direction: column; gap: var(--gap);
  will-change: transform;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
@keyframes marquee {
  from { transform: translateY(0); }
  to   { transform: translateY(calc(-1 * var(--shift))); }
}
/* Les lignes du haut et du bas s'estompent : on voit qu'il y a une suite. */
.board.scrolling .col-viewport {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 6%, #000 94%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}

/* Dans le tapis, la liste ne s'étire pas : chaque ligne fait pile `--rowh`. */
.col-track .roster-list { flex: none; overflow: visible; }
.roster-row {
  flex: 0 0 var(--rowh) !important;
  height: var(--rowh);
  max-height: var(--rowh) !important;
  font-size: clamp(12px, calc(var(--rowh) * .42), 26px);
}

/* Colonne de rang : étoile du leader + flèche de mouvement + numéro, sur une
   seule ligne. Gabarit resserré en mode 2 colonnes (moitié moins de largeur). */
.roster-columns, .roster-row { grid-template-columns: 104px 1fr 160px 120px 120px 130px 150px; }
.board.two-col .roster-columns,
.board.two-col .roster-row {
  grid-template-columns: 74px minmax(0, 1fr) 124px 68px 78px 68px 100px;
  gap: 6px;
}
.board.two-col .roster-columns { font-size: 12px; letter-spacing: 1.5px; }
/* Pastille resserrée : « VIOLETTE » doit tenir en entier dans la colonne. */
.board.two-col .roster-row .team-pill { font-size: .58em; letter-spacing: 1px; }
/* Écran étroit en 2 colonnes : la colonne équipe écraserait les indicatifs →
   retirée. La couleur reste en bordure de ligne, les équipes dans le bandeau. */
@media (max-width: 1700px) {
  .board.two-col .roster-columns,
  .board.two-col .roster-row { grid-template-columns: 74px minmax(0, 1fr) 68px 78px 68px 100px; }
  .board.two-col .team { display: none; }
}
.board.two-col .roster-row { padding: 0 12px; }
.roster-row .rank {
  display: flex; align-items: center; justify-content: flex-start; gap: .18em;
  white-space: nowrap;
}

/* Un peu d'air dans les cellules : le halo de mise à jour a besoin de place. */
.roster-row > span { padding: 2px 6px; border-radius: 3px; }
.roster-row .score { position: relative; }

/* La copie du tapis ne doit pas être annoncée deux fois aux lecteurs d'écran. */
.roster-list.is-clone { pointer-events: none; }

/* ========================= MISE À JOUR EN DIRECT ========================= */
/* Arrivée d'une nouvelle ligne (joueur qui apparaît au classement). */
.roster-row.row-new { animation: rowIn .5s cubic-bezier(.2,1.1,.3,1) both; }
@keyframes rowIn {
  from { opacity: 0; transform: translateX(-40px); }
  to   { opacity: 1; transform: none; }
}

/* Valeur qui vient de changer : flash jaune danger puis retour au calme. */
.cell-flash { animation: cellFlash 1.4s ease-out; }
@keyframes cellFlash {
  0%   { background: rgba(242,194,0,.55); color: var(--night); }
  30%  { background: rgba(242,194,0,.40); color: var(--night); }
  100% { background: transparent; }
}

/* Gain de score : "+120" qui s'envole au-dessus de la valeur. */
.score .delta {
  position: absolute; right: 6px; top: -2px;
  font-family: var(--f-mono); font-size: .72em; font-style: normal;
  color: var(--phosphor); text-shadow: 0 0 10px rgba(143,255,90,.5);
  opacity: 0; pointer-events: none; white-space: nowrap;
}
.score .delta.show { animation: deltaFly 1.8s ease-out; }
.score .delta.down { color: var(--alert); text-shadow: 0 0 10px rgba(209,71,31,.5); }
@keyframes deltaFly {
  0%   { opacity: 0; transform: translateY(6px); }
  18%  { opacity: 1; transform: translateY(-10px); }
  70%  { opacity: 1; transform: translateY(-16px); }
  100% { opacity: 0; transform: translateY(-24px); }
}

/* Mouvement au classement : flèche verte (gagne des places) / rouge (en perd). */
.rank .move {
  display: inline-block; width: 1em; font-style: normal;
  font-size: .8em; text-align: center; opacity: 0;
}
.rank .move.up   { color: var(--phosphor); opacity: 1; }
.rank .move.down { color: var(--alert); opacity: 1; }

/* Le leader respire légèrement pour rester lisible de loin. */
.roster-row.top1 .score { text-shadow: 0 0 18px rgba(242,194,0,.45); }

/* ------------------------------ Pied de page ----------------------------- */
.roster-foot { margin-top: 12px; }          /* message "en attente" (réutilisé) */

.scores-foot {
  display: flex; justify-content: center; align-items: center; gap: 14px;
  font-family: var(--f-mono); font-size: 14px; letter-spacing: 3px;
  color: var(--ink-dim); margin: 10px 0 0;
}
.scores-foot .foot-sep { color: var(--od-line); }
.scores-foot .foot-count { color: var(--sand); }
.scores-foot .foot-updated { color: var(--phosphor); }

/* --------------------------- Accessibilité -------------------------------
   Les animations décoratives (flash, arrivée de ligne, glissement de rang)
   sont coupées si le système demande moins de mouvement. Le défilement des
   colonnes, lui, est conservé : sans lui, les joueurs au-delà du 20e ne
   seraient jamais visibles — c'est le seul moyen d'accéder à l'information.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .cell-flash, .score .delta.show, .roster-row.row-new, .freshness.pulse { animation: none; }
}
