/**
 * PlayAwale — Revoir des parties
 * -----------------------------------------------------------------------------
 * Le tableau d'honneur des victoires contre l'IA, et les dernières parties.
 *
 * ELLE REPREND LE COMPTE
 * Le titre gravé, l'introduction, les cartes de sable : account.css. Cette
 * feuille n'ajoute que ce que la page est seule à porter — les vignettes des IA,
 * le face-à-face, les places du classement et les cartes des dernières parties.
 *
 * UN SEUL VOCABULAIRE
 * Rien n'est inventé : les objets en relief et les creux de tokens.css, l'ambre
 * de la première marche du podium des pays pour la première place, les couleurs
 * d'issue de « Mes parties », et le vert et le rouge des deux rangées du plateau
 * — ceux que le lecteur de parties pose déjà — pour dire qui ouvre.
 *
 * ELLE SE LIT SUR UN TÉLÉPHONE
 * Les deux classements d'une IA passent l'un sous l'autre, chaque place se
 * resserre selon la largeur de SA colonne — requête de conteneur, et non de
 * fenêtre : une colonne est étroite sur un grand écran comme sur un petit —, et
 * les dernières parties défilent de côté.
 *
 * @package   PlayAwale
 * @version   2.0
 * @author    Nicolas Lion — Développeur web — https://nlion.fr
 * @copyright 2026 Nicolas Lion
 */

/* =============================================================================
   MISE EN PAGE
   ============================================================================= */

/* Plus large que le compte : deux classements côte à côte, cinq cartes sur une
   rangée. */
.replays-page .account-block {
  width: min(94vw, 1080px);
}


/* =============================================================================
   L'EN-TÊTE
   -----------------------------------------------------------------------------
   La coupe, sur un jeton d'ambre : c'est la seule chose de la page qui porte
   l'ambre sans qu'on l'ait visée — elle dit « palmarès » avant tout texte.
   ============================================================================= */

.replays-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
}

.replays-hero .account-lead {
  margin-bottom: 0;
}

.replays-hero__emblem {
  display: grid;
  place-items: center;

  width: 4.25rem;
  height: 4.25rem;

  color: var(--color-brand-dark);
  background-color: var(--color-brand-amber);
  background-image: var(--gradient-amber-raised);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-raised-amber);
}

.replays-hero__cup {
  width: 58%;
  height: 58%;
}

/* Le pictogramme d'un titre de bloc : la couronne, la boucle du rejeu. */
.replays-block__title-icon {
  flex: none;
  width: 1em;
  height: 1em;

  color: var(--color-brand-amber-deep);
}


/* =============================================================================
   LES IA
   -----------------------------------------------------------------------------
   Une vignette par IA, portrait au-dessus du nom : on reconnaît un niveau à sa
   figure, la même que sur l'écran de choix et en partie. Sans script, ce sont
   des liens vers chaque classement ; avec lui, des onglets, et celle qu'on
   regarde porte l'ambre.
   ============================================================================= */

.hall-levels {
  margin: var(--space-md) 0 var(--space-lg);
}

.hall-levels__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: var(--space-sm);

  margin: 0;
  padding: 0;
  list-style: none;
}

.hall-level {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);

  height: 100%;
  padding: var(--space-sm) var(--space-xs);

  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
  text-align: center;
  text-wrap: balance;
  color: var(--color-text);
  text-decoration: none;

  background-color: var(--color-surface);
  background-image: var(--gradient-surface-raised);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised);

  transition:
    transform var(--duration-base) ease,
    box-shadow var(--duration-base) ease,
    background-color var(--duration-base) ease;
}

.hall-level:hover,
.hall-level:focus-visible {
  background-color: var(--color-brand-amber-light);
  box-shadow: var(--shadow-raised-hover);
  transform: translateY(-2px);
}

.hall-level:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.hall-level.is-active {
  background-color: var(--color-brand-amber);
  background-image: var(--gradient-amber-raised);
  box-shadow: var(--shadow-raised-amber);
}

.hall-level__robot {
  width: 52px;
  height: 52px;
  object-fit: contain;
}


/* =============================================================================
   LE CLASSEMENT D'UNE IA
   ============================================================================= */

/* Sans script, les six classements se suivent : un peu d'air entre eux. Avec
   lui, un seul se montre, juste sous les onglets. */
.hall-panel + .hall-panel {
  margin-top: var(--space-2xl);
}

.hall-levels.is-tabs ~ .hall-panel {
  margin-top: 0;
}

.hall-panel__head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);

  margin-bottom: var(--space-md);
}

/* Le portrait dans son creux, comme un trou du plateau. */
.hall-panel__robot {
  flex: none;
  width: 84px;
  height: 84px;
  padding: 4px;

  object-fit: contain;
  background-color: var(--color-sand-100);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-hollow);
}

.hall-panel__titles {
  text-align: left;
}

.hall-panel__name {
  margin: 0;

  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.6vw, 1.8rem);
  font-weight: 400;
  line-height: var(--line-height-tight);
  color: var(--color-text);
  text-shadow: var(--shadow-heading);
}

.hall-panel__rate {
  margin: var(--space-2xs) 0 0;

  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Les deux classements côte à côte : l'IA qui ouvre, le joueur qui ouvre. */
.hall-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg);

  /* Une colonne de deux places ne s'étire pas à la hauteur de sa voisine de
     cinq : son fond de sable s'arrête avec elle. */
  align-items: start;

  text-align: left;
}

/* Chaque colonne est un conteneur : ses places se resserrent sur SA largeur. */
.hall-column {
  container-type: inline-size;

  display: flex;
  flex-direction: column;
  gap: var(--space-xs);

  padding: var(--space-md);

  background-color: var(--color-sand-100);
  border-radius: var(--radius-md);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

.hall-column__title {
  display: flex;
  align-items: center;
  gap: var(--space-xs);

  margin: 0;

  font-family: var(--font-display);
  font-size: var(--font-size-lg);
  font-weight: 400;
  line-height: var(--line-height-tight);
  color: var(--color-text);
}

/* Un classement vide se dit : c'est une place à prendre, pas une panne. */
.hall-empty {
  margin: var(--space-sm) 0 0;
  padding: var(--space-md);

  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-base);
  text-align: center;
  color: var(--color-text-muted);

  border: 2px dashed var(--color-sand-400);
  border-radius: var(--radius-md);
}


/* -----------------------------------------------------------------------------
   Qui ouvre
   -----------------------------------------------------------------------------
   Une graine de la couleur de la rangée qui a joué le premier coup : rouge pour
   celle de l'IA, en haut du plateau, verte pour celle du joueur, en bas. Ce sont
   les couleurs que le lecteur de parties pose sur les coups de chaque camp.
   -------------------------------------------------------------------------- */

.opener-seed {
  flex: none;
  width: 0.8em;
  height: 0.8em;

  border-radius: var(--radius-full);
  box-shadow:
    inset 0 -2px 3px rgba(60, 39, 35, 0.3),
    0 1px 0 rgba(255, 255, 255, 0.55);
}

.opener-seed--ai {
  background-color: var(--color-outcome-lost);
}

.opener-seed--player {
  background-color: var(--color-outcome-won);
}


/* =============================================================================
   UNE PLACE
   -----------------------------------------------------------------------------
   Le rang dans son creux, le face-à-face, les faits, et le bouton qui rejoue.
   La première place porte l'ambre et la couronne du podium des pays.
   ============================================================================= */

.exploits {
  display: grid;
  gap: var(--space-xs);

  margin: 0;
  padding: 0;
  list-style: none;
}

.exploit {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "place duel  watch"
    "place facts watch";
  align-items: center;
  gap: var(--space-2xs) var(--space-md);

  padding: var(--space-sm) var(--space-md);

  background-color: var(--color-surface);
  background-image: var(--gradient-surface-raised);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.exploit--place-1 {
  box-shadow: var(--shadow-raised);
}

.exploit__place {
  grid-area: place;
  position: relative;

  display: grid;
  place-items: center;

  width: 2.4rem;
  height: 2.4rem;

  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1;
  color: var(--color-text);

  background-color: var(--color-sand-200);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-hollow);
}

.exploit--place-1 .exploit__place {
  background-color: var(--color-brand-amber);
  background-image: var(--gradient-amber-raised);
  box-shadow: var(--shadow-raised-amber);
}

.exploit__crown {
  position: absolute;
  top: -0.9rem;
  left: 50%;

  width: 1.2rem;
  height: 1.2rem;
  transform: translateX(-50%);

  color: var(--color-brand-amber-deep);
  filter: drop-shadow(0 1px 1px rgba(60, 39, 35, 0.35));
}

.exploit .duel {
  grid-area: duel;
}

.exploit__facts {
  grid-area: facts;
}

.exploit .watch-btn {
  grid-area: watch;
}

/* Une colonne étroite — un téléphone, une tablette tenue droite : le bouton
   descend à côté des faits, et le face-à-face garde toute la première ligne. */
@container (max-width: 26rem) {

  .exploit {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "place duel  duel"
      "facts facts watch";
    gap: var(--space-xs) var(--space-sm);

    padding: var(--space-sm);
  }

  .exploit .duel {
    gap: var(--space-xs);
  }

  .exploit .duel__face {
    width: 42px;
    height: 42px;
  }
}


/* =============================================================================
   LE FACE-À-FACE
   -----------------------------------------------------------------------------
   L'IA, les deux scores, le joueur. Chaque score est collé au visage qu'il
   désigne ; celui du vainqueur est marqué par sa taille et sa couleur, l'autre
   s'efface.
   ============================================================================= */

.duel {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.duel__face {
  flex: none;
  width: 48px;
  height: 48px;

  object-fit: contain;
  background-color: var(--color-sand-100);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-hollow);
}

/* Un joueur sans visage : sa silhouette s'efface un peu, comme dans « Mes
   statistiques » — il n'y a personne à reconnaître. */
.duel__face--player:not(.is-known) {
  opacity: 0.6;
}

/* Un joueur qui a joué avec sa clé : un liseré d'ambre, celui qui distingue le
   joueur reconnu. */
.duel__face--player.is-known {
  box-shadow:
    0 0 0 2px var(--color-surface),
    0 0 0 4px var(--color-brand-amber-deep);
}

/* Le portrait du joueur et son drapeau : la pastille déborde du coin inférieur
   droit, cerclée de sable comme les drapeaux du podium des pays. Elle garde son
   opacité quand la silhouette anonyme s'efface : le pays, lui, est connu. */
.duel__player {
  position: relative;
  flex: none;
  display: inline-flex;
}

.duel__flag {
  position: absolute;
  right: -4px;
  bottom: -3px;

  width: 20px;
  height: 20px;

  border-radius: var(--radius-full);
  box-shadow:
    0 0 0 2px var(--color-surface),
    0 1px 3px rgba(60, 39, 35, 0.35);
}

.duel__scores {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2xs);

  margin: 0;

  font-family: var(--font-display);
  font-size: 1.2rem;
  line-height: 1;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.duel__score.is-winner {
  font-size: 1.55rem;
  color: var(--color-text);
  text-shadow: var(--shadow-heading);
}


/* =============================================================================
   LES FAITS
   ============================================================================= */

.exploit__facts,
.latest-card__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-sm);

  margin: 0;

  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
  color: var(--color-text-muted);
}

.fact {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  white-space: nowrap;
}

.fact__icon {
  flex: none;
  width: 1em;
  height: 1em;
}

/* Le pays se lit en entier, en couleur de texte : c'est le seul fait qui parle
   du joueur, et son drapeau rond tient la place d'un pictogramme. */
.fact--country {
  color: var(--color-text);
}

.fact__flag {
  flex: none;
  width: 1.1em;
  height: 1.1em;

  border-radius: var(--radius-full);
  box-shadow: 0 0 0 1px rgba(60, 39, 35, 0.15);
}


/* =============================================================================
   LE BOUTON QUI REJOUE
   -----------------------------------------------------------------------------
   Une pastille de sable, qui prend l'ambre quand on la vise : il y en a une par
   partie, et une page où quinze boutons porteraient l'ambre ne désignerait plus
   rien.
   ============================================================================= */

.watch-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);

  padding: var(--space-xs) var(--space-md);

  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  color: var(--color-text);
  text-decoration: none;

  background-color: var(--color-surface);
  background-image: var(--gradient-surface-raised);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-raised);

  transition:
    transform var(--duration-fast) ease,
    box-shadow var(--duration-fast) ease,
    background-color var(--duration-fast) ease;
}

.watch-btn:hover,
.watch-btn:focus-visible {
  background-color: var(--color-brand-amber);
  background-image: var(--gradient-amber-raised);
  box-shadow: var(--shadow-raised-amber-hover);
  transform: translateY(-2px);
}

.watch-btn:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.watch-btn:active {
  box-shadow: var(--shadow-sm);
  transform: translateY(1px);
}

.watch-btn__icon {
  flex: none;
  width: 14px;
  height: 14px;
}


/* =============================================================================
   LES DERNIÈRES PARTIES
   -----------------------------------------------------------------------------
   Cinq cartes, côte à côte sur un grand écran. L'issue se lit d'abord — le
   liseré du haut et le mot —, puis l'IA affrontée, le face-à-face et les faits.
   Les cartes d'une rangée ont la même hauteur, et leur bouton le même niveau.
   ============================================================================= */

.latest-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
  gap: var(--space-md);

  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
}

/* « position: relative » N'EST PAS DÉCORATIF
   Les textes réservés aux lecteurs d'écran sont posés en position absolue, et
   se rapportent au plus proche ancêtre positionné — sans ceci, « .page », HORS
   de la liste qui défile sur un téléphone. Ils échappaient alors à son rognage
   et élargissaient la page entière : 1 246 pixels pour 386 visibles, mesuré dans
   un cadre de 390. Rattachés à leur carte, ils défilent et se rognent avec
   elle. */
.latest-card {
  position: relative;

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);

  padding: var(--space-md) var(--space-sm);

  text-align: center;

  background-color: var(--color-surface);
  background-image: var(--gradient-surface-raised);
  border-top: 4px solid var(--color-outcome-drawn);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised);
}

.latest-card.is-player-win { border-top-color: var(--color-outcome-won); }
.latest-card.is-ai-win     { border-top-color: var(--color-outcome-lost); }

.latest-card__outcome {
  margin: 0;

  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-outcome-drawn);
}

.latest-card.is-player-win .latest-card__outcome { color: var(--color-outcome-won); }
.latest-card.is-ai-win .latest-card__outcome     { color: var(--color-outcome-lost); }

.latest-card__level {
  margin: 0;

  font-family: var(--font-display);
  font-size: var(--font-size-base);
  line-height: var(--line-height-tight);
  text-wrap: balance;
  color: var(--color-text);
}

.latest-card .duel {
  gap: var(--space-xs);
  margin: var(--space-2xs) 0;
}

.latest-card .duel__face {
  width: 44px;
  height: 44px;
}

.latest-card__opener {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;

  margin: 0;

  font-family: var(--font-body);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.latest-card__facts {
  justify-content: center;
}

/* Le bouton au pied de la carte, quelle que soit sa hauteur. */
.latest-card .watch-btn {
  margin-top: auto;
}


/* =============================================================================
   ÉCRANS MOYENS ET ÉTROITS
   ============================================================================= */

/* Sous 52 rem, les deux classements d'une IA passent l'un sous l'autre : côte à
   côte, chacun n'aurait plus la place d'un face-à-face. */
@media (max-width: 52rem) {

  .hall-columns {
    grid-template-columns: 1fr;
    gap: var(--space-md);
  }
}

/* Téléphone.

   LES VIGNETTES DES IA SUR TROIS COLONNES
   Deux rangées de trois plutôt que trois rangées de deux : le classement qu'on
   choisit reste à portée de pouce.

   LES DERNIÈRES PARTIES DÉFILENT DE CÔTÉ
   Empilées, cinq cartes feraient treize cents pixels de haut. Côte à côte, la
   suivante dépasse du bord : on voit qu'il y en a d'autres, et on les fait
   glisser. Le clavier les parcourt aussi — le défilement suit le focus des
   boutons. */
@media (max-width: 34rem) {

  .replays-page .account-block {
    padding: var(--space-md);
  }

  .hall-levels__list {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-xs);
  }

  .hall-level {
    padding: var(--space-xs) var(--space-2xs);
    font-size: 0.78rem;
    overflow-wrap: anywhere;
  }

  .hall-level__robot {
    width: 40px;
    height: 40px;
  }

  .hall-panel__robot {
    width: 64px;
    height: 64px;
  }

  .hall-column {
    padding: var(--space-sm);
  }

  .latest-list {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 78%;

    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;

    /* Les ombres des cartes ne se font pas couper par le bord du défilement. */
    padding: var(--space-2xs) var(--space-2xs) var(--space-sm);
  }

  .latest-card {
    scroll-snap-align: center;
  }
}


/* =============================================================================
   SANS ANIMATION
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {

  .hall-level,
  .watch-btn {
    transition: background-color var(--duration-base) ease;
  }

  .hall-level:hover,
  .hall-level:focus-visible,
  .watch-btn:hover,
  .watch-btn:focus-visible,
  .watch-btn:active {
    transform: none;
  }
}
