/* =====================================================================
   FUZE TOURNAMENT 2 — page publique (classement live)
   Palette Fnac : jaune/or sur fond sombre.
   ===================================================================== */

:root {
  /* --- Couleurs Fnac --- */
  --fnac: #f2b705;
  --fnac-bright: #ffd84d;
  --fnac-deep: #b57f00;
  --fnac-ink: #141008;

  --bg-0: #0b0a07;
  --bg-1: #17120a;
  --bg-2: #241a09;

  --text: #fff6e2;
  --text-dim: rgba(255, 246, 226, 0.5);

  --panel: rgba(255, 255, 255, 0.045);
  --panel-line: rgba(242, 183, 5, 0.16);

  /* --- Grille du tableau (partagée en-tête / lignes / fonds) --- */
  /* La colonne des noms est mesurée en JS (`--name-w`) : juste la largeur
     qu'il faut pour le plus long nom affiché, et pas un pouce de plus. En
     `1fr` elle mangeait toute la place restante et laissait un gouffre entre
     les noms et la première épreuve. La valeur ci-dessous ne sert qu'avant
     le premier rendu. */
  --name-w: 14rem;
  --name-w-min: 10rem;
  --name-w-max: 26rem;
  --col-event: 7.2rem;
  --col-total: 9.4rem;
  --cols: var(--name-w) repeat(4, var(--col-event)) var(--col-total);
  --row-h: 3.05rem;
  --gap: 0.45rem;
  /* Largeur du tableau, déduite de ses colonnes. En `fit-content`, le
     navigateur la résolvait avant que `--name-w` soit mesuré : les pistes
     étaient rabotées et les noms longs tronqués. */
  --board-w: calc(
    var(--name-w) + 4 * var(--col-event) + var(--col-total) + 5 * var(--gap)
  );
}

/* Échelle typographique liée à la taille d'écran : lisible sur TV comme sur laptop */
html {
  font-size: clamp(11px, 0.78vw + 0.42vh, 21px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg-0);
  color: var(--text);
  font-family: "Barlow Condensed", "Oswald", "Arial Narrow", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ============================= FOND ============================= */

.stage {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  padding: 2.2rem 3rem 1.6rem;
  isolation: isolate;
}

/* Le visuel de fond : dépose /assets/background.png et il remplace
   automatiquement le dégradé de repli.
   L'ORDRE COMPTE : les couches `background-image` se peignent de la première
   à la dernière, donc l'image passe AVANT le dégradé. L'inverse — ce qu'on
   avait — revenait à poser un aplat opaque par-dessus le visuel : l'image
   était bien chargée, simplement invisible. */
.bg-layer {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-color: var(--bg-0);
  background-image:
    url("/assets/background.png"),
    linear-gradient(170deg, var(--bg-1) 0%, var(--bg-0) 55%, #060503 100%);
  background-size: cover, cover;
  background-position: center, center;
  background-repeat: no-repeat, no-repeat;
}

/* Vignettage : assombrit les bords pour que le classement, posé au centre,
   garde son contraste même quand le visuel de fond est chargé. */
.bg-grain {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(118% 88% at 50% 45%, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.52) 42%, rgba(0, 0, 0, 0.82) 100%);
}

/* ============================ EN-TÊTE ============================ */

.topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 2rem;
  margin-bottom: 1.6rem;
}

.title-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 6.6rem;
}

.title-logo {
  max-height: 7.4rem;
  max-width: 34rem;
  object-fit: contain;
}

.title-fallback {
  margin: 0;
  text-align: center;
  font-family: "Bebas Neue", "Barlow Condensed", sans-serif;
  line-height: 0.86;
  letter-spacing: 0.04em;
}
.title-fallback .title-top {
  display: block;
  font-size: 1.6rem;
  letter-spacing: 0.55em;
  text-indent: 0.55em;
  color: var(--fnac);
  opacity: 0.9;
}
.title-fallback .title-main {
  display: block;
  font-size: 4.6rem;
  color: var(--text);
  text-shadow:
    0 0 1.4rem rgba(242, 183, 5, 0.55),
    0 0.22rem 0 var(--fnac-deep);
}
/* Si le logo du tournoi est présent, on masque le texte de repli */
.title-block.has-logo .title-fallback { display: none; }
.title-block:not(.has-logo) .title-logo { display: none; }

/* ------- Emplacements logos (remplis quand l'image existe) ------- */

.logo-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 3.6rem;
}
.slot-topleft { justify-content: flex-start; }

.logo-slot img {
  max-height: 4.2rem;
  max-width: 100%;
  object-fit: contain;
}
.slot-footer img { max-height: 3.2rem; max-width: 12rem; }

/* Image absente : l'emplacement reste réservé mais invisible */
.logo-slot.empty img,
.title-block.no-logo .title-logo { display: none; }

/* Mode repérage des emplacements : ouvrir la page avec ?slots */
body.show-slots .logo-slot.empty::after {
  content: attr(data-slot-label);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 3.4rem;
  border: 1px dashed rgba(242, 183, 5, 0.45);
  border-radius: 0.5rem;
  color: rgba(242, 183, 5, 0.6);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ============================ TABLEAU ============================ */

.board {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.board-inner {
  position: relative;
  /* Aucune colonne n'est élastique : le bloc fait exactement la largeur de
     sa grille, et se centre. */
  width: min(100%, var(--board-w));
  margin-inline: auto;
}

/* Gabarits de mesure : des copies hors écran d'une cellule de nom et de
   l'en-tête, en largeur naturelle. C'est ce que lit le JS pour fixer
   `--name-w` — mesurer sur les vraies cellules est impossible, elles font
   déjà la largeur de la colonne qu'on cherche à calculer. */
.measure {
  position: absolute;
  top: 0;
  left: 0;
  width: max-content;
  visibility: hidden;
  pointer-events: none;
  white-space: nowrap;
}
.measure .pname {
  flex: 0 0 auto;
  overflow: visible;
  text-overflow: clip;
}

/* --- fonds de colonnes, calés sur la même grille --- */
.colbg {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: var(--cols);
  gap: var(--gap);
  pointer-events: none;
  z-index: 0;
}
.colbg-cell { border-radius: 0.9rem; }

.colbg-names {
  background: linear-gradient(100deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.022));
  border: 1px solid rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(2px);
}
.colbg-event {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.015));
  border: 1px solid rgba(255, 255, 255, 0.05);
}
.colbg-total {
  background: linear-gradient(180deg, rgba(242, 183, 5, 0.17), rgba(242, 183, 5, 0.05));
  border: 2px solid var(--fnac);
  box-shadow:
    0 0 1.6rem rgba(242, 183, 5, 0.32),
    inset 0 0 2.4rem rgba(242, 183, 5, 0.1);
}

/* --- lignes --- */
.rows {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  padding: 0.55rem 0;
}

.row {
  display: grid;
  grid-template-columns: var(--cols);
  gap: var(--gap);
  align-items: center;
  height: var(--row-h);
  will-change: transform;
}

.cell {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  min-width: 0;
}

/* ---- en-tête des colonnes ---- */
.row-head {
  height: 4.6rem;
  margin-bottom: 0.2rem;
}

.head-classement {
  justify-content: flex-start;
  padding-left: 1.5rem;
  font-family: "Bebas Neue", sans-serif;
  font-size: 2.15rem;
  letter-spacing: 0.06em;
  color: var(--fnac);
  text-shadow: 0 0 1.2rem rgba(242, 183, 5, 0.5);
}

.head-event {
  flex-direction: column;
  gap: 0.18rem;
}
.head-event .ev-name {
  font-family: "Bebas Neue", sans-serif;
  font-size: 0.92rem;
  letter-spacing: 0.1em;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.head-event .ev-icon,
.head-total .ev-icon {
  width: 1.95rem;
  height: 1.95rem;
  fill: var(--fnac);
  filter: drop-shadow(0 0 0.5rem rgba(242, 183, 5, 0.55));
}
.head-total {
  flex-direction: column;
  gap: 0.18rem;
}
.head-total .ev-name {
  font-family: "Bebas Neue", sans-serif;
  font-size: 1rem;
  letter-spacing: 0.16em;
  color: var(--fnac-bright);
}
.head-total .ev-icon {
  width: 2.2rem;
  height: 2.2rem;
  fill: var(--fnac-bright);
}

/* ---- ligne joueur ---- */
.cell-name {
  justify-content: flex-start;
  gap: 0.7rem;
  padding: 0 1.1rem 0 1.5rem;
}

.rank {
  font-family: "Bebas Neue", sans-serif;
  font-size: 1.45rem;
  color: var(--fnac);
  opacity: 0.85;
  min-width: 2.4rem;
  letter-spacing: 0.02em;
  /* Le style du podium s'installe en fondu : sans ça, il claquait pile au
     moment où la ligne se déplace, et ça se lisait comme un flash. */
  transition: color 520ms ease, opacity 520ms ease;
}

.pname {
  font-family: "Bebas Neue", sans-serif;
  font-size: 1.9rem;
  letter-spacing: 0.035em;
  color: var(--text);
  transition: color 520ms ease, text-shadow 520ms ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.arrow {
  width: 1.5rem;
  height: 1.5rem;
  flex: 0 0 auto;
  opacity: 0.55;
  fill: var(--fnac);
}

.score {
  font-family: "Bebas Neue", sans-serif;
  font-size: 2.1rem;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  transition: color 0.3s ease;
}
.score.empty { color: transparent; }

.cell-total .score {
  font-size: 2.35rem;
  color: var(--fnac-bright);
  text-shadow: 0 0 1rem rgba(242, 183, 5, 0.55);
}

/* Les 3 premiers ressortent légèrement */
.row[data-pos="1"] .pname { color: #fff; text-shadow: 0 0 1.1rem rgba(242, 183, 5, 0.5); }
.row[data-pos="1"] .rank,
.row[data-pos="2"] .rank,
.row[data-pos="3"] .rank { opacity: 1; color: var(--fnac-bright); }

/* ======================= ANIMATIONS CLASSEMENT ======================= */

/* FLIP : on fige la position d'origine puis on laisse la transition jouer.
   `transform` seul est animé — aucune propriété qui force un recalcul de mise
   en page, donc le glissement reste fluide même avec dix lignes en mouvement. */
.row.flip-move {
  transition: transform 760ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Un score qui change se révèle en fondu, à sa place, et rien d'autre ne
   bouge. Le chiffre monte de quelques pixels en apparaissant — pas de
   surbrillance : un `filter: brightness()` sur du texte déjà clair se lit
   comme un flash blanc, c'est précisément ce qu'on ne veut pas.
   Une fois le chiffre lisible, c'est seulement là que les lignes se
   réordonnent (le décalage est tenu par le JS). */
@keyframes score-reveal {
  0%   { opacity: 0; transform: translateY(0.34rem); }
  100% { opacity: 1; transform: none; }
}
.score.reveal { animation: score-reveal 420ms cubic-bezier(0.22, 1, 0.36, 1); }

/* Le total suit le même mouvement, en plus discret : c'est une conséquence
   du score saisi, pas une information neuve. */
.cell-total .score.reveal {
  animation-duration: 520ms;
  animation-delay: 90ms;
  animation-fill-mode: backwards;
}

/* Apparition initiale */
@keyframes row-in {
  from { opacity: 0; transform: translateX(-1.6rem); }
  to   { opacity: 1; transform: none; }
}
.row.enter { animation: row-in 520ms cubic-bezier(0.22, 1, 0.36, 1) backwards; }

/* ============================= PIED ============================= */

.footer {
  margin-top: 1.4rem;
  display: flex;
  justify-content: center;
}
.footer-logos {
  display: flex;
  align-items: center;
  gap: 1.8rem;
  min-height: 3.6rem;
}
.footer-logos .sep {
  width: 1px;
  height: 2.2rem;
  background: linear-gradient(transparent, rgba(242, 183, 5, 0.45), transparent);
}

/* ========================= ÉTAT CONNEXION ========================= */

.conn {
  position: fixed;
  right: 0.9rem;
  bottom: 0.7rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 246, 226, 0.3);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}
.conn.show { opacity: 1; }
.conn .dot {
  width: 0.46rem;
  height: 0.46rem;
  border-radius: 50%;
  background: #ff7b6b;
}
.conn.ok .dot { background: #6ee787; }

/* ========================== RESPONSIVE ========================== */

@media (max-width: 900px) {
  :root {
    --name-w-min: 6rem;
    --name-w-max: 13rem;
    --col-event: 3.6rem;
    --col-total: 5rem;
    --row-h: 2.7rem;
    --gap: 0.3rem;
  }
  .stage { padding: 1.4rem 1rem 1rem; }
  .cell-name { padding: 0 0.4rem 0 0.7rem; gap: 0.35rem; }
  .arrow { display: none; }
  .pname { font-size: 1.5rem; }
  .rank { font-size: 1.1rem; min-width: 1.9rem; }
  .score { font-size: 1.5rem; }
  .cell-total .score { font-size: 1.65rem; }
  .head-event .ev-name { font-size: 0.68rem; }
  .head-event .ev-icon, .head-total .ev-icon { width: 1.3rem; height: 1.3rem; }
  .footer-logos { gap: 0.9rem; flex-wrap: wrap; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .row.flip-move { transition-duration: 1ms; }
  .score.reveal, .row.enter { animation: none; }
  .rank, .pname { transition: none; }
}
