/* ==========================================================================
   Donut Rush — feuille de style unique.

   Parti pris visuel : sombre bleu-nuit facon casino crypto, accent ambre
   "donut glaze" + rose sur les degrades. Pas de framework : le site doit
   rester servable en statique, sans etape de build.
   ========================================================================== */

:root {
  --fond: #070910;
  --fond-2: #0f131f;
  --fond-3: #161c2d;
  --fond-4: #1e2538;
  --bordure: #202940;
  --bordure-claire: #2c3651;
  --texte: #eef1fa;
  --texte-doux: #8a94b0;
  --accent: #ffb03a;
  --accent-fonce: #ff8f2e;
  --rose: #ff6fb8;
  --vert: #35d98a;
  --rouge: #ff5566;
  --rayon: 16px;
  --ombre: 0 20px 60px rgba(0, 0, 0, .5);
  /* Hauteur reelle de la topbar : 14px de padding haut + 44px de contenu
     (le bloc de solde, l element le plus haut) + 14px bas + 1px de bordure. */
  --hauteur-topbar: 73px;
  /* Hauteur de la barre de menu, et total entete + barre. Les deux sont
     MESUREES par calerPanneaux() : une valeur en dur derive des que la
     police, le zoom ou le contenu changent. */
  --hauteur-menu: 44px;
  --hauteur-nav: 117px;
}

* { box-sizing: border-box; }

/*
 * L'attribut `hidden` doit TOUJOURS gagner.
 *
 * Le navigateur applique `display: none` a [hidden] via sa feuille par defaut,
 * qui a une priorite plus faible que n'importe quelle regle de classe. Donc
 * `.modal { display: flex }` ecrase `hidden` et la modale s'affiche alors que
 * le HTML la declare masquee — c'est ce qui ouvrait la fenetre de depot des le
 * chargement de la page, avec les deux modales empilees et infermables.
 *
 * Tout le JS pilote la visibilite par `hidden` (setAttribute/toggleAttribute),
 * donc cette regle doit rester en tete de feuille et ne jamais etre retiree.
 */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background:
    radial-gradient(1200px 620px at 80% -14%, rgba(255, 111, 184, .12), transparent 62%),
    radial-gradient(1000px 560px at 6% -4%, rgba(255, 176, 58, .10), transparent 62%),
    var(--fond);
  color: var(--texte);
  font: 15px/1.65 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/*
 * MOTIF DE FOND — illustration casino (jetons, cartes, des, roulette...).
 *
 * Un aplat noir uniforme donne un site plat ; ce fond donne de la profondeur
 * sans jamais entrer en concurrence avec le contenu.
 *
 * POURQUOI UN PSEUDO-ELEMENT ET PAS UN CALQUE DANS `background` DE BODY :
 * le fond doit rester FIXE quand la page defile (sinon il glisse derriere le
 * contenu et attire l'oeil), et il doit avoir sa PROPRE opacite. Un calque de
 * `background` partagerait l'opacite du body et emporterait le texte avec lui.
 *
 * UNE SEULE IMAGE, JAMAIS REPETEE. `no-repeat` est explicite : la valeur par
 * defaut de `background-repeat` est `repeat`, et laisser faire transformait le
 * fond en mosaique — le meme revolver et la meme roulette revenaient tous les
 * 1024 px, ce qui saute aux yeux et fait cheap.
 *
 * `contain` ET PAS `cover` : `cover` remplit l'ecran en ROGNANT ce qui
 * depasse, et comme l'image est large (1024x496) sur un ecran plus carre,
 * elle perdait tout le haut et toute la gauche — le sac de billets, le
 * revolver et les piles de jetons sortaient du cadre.
 *
 * `contain` fait l'inverse : l'image tient ENTIEREMENT dans la zone, quitte a
 * laisser du fond visible au-dessus et en dessous. Ce fond est le noir du
 * site, donc les bandes ne se voient pas — alors qu'un motif ampute, si.
 *
 * `z-index: -1` le place derriere tout le contenu, et `pointer-events: none`
 * garantit qu'il n'intercepte jamais un clic : un fond decoratif qui avale
 * les clics est un bug invisible et exasperant.
 */
body::before {
  content: '';
  position: fixed;

  /*
   * LE CADRE S'ARRETE OU COMMENCE LE CONTENU VISIBLE.
   *
   * CE QUI ETAIT FAUX : `inset: 0` etalait l'image sur la fenetre ENTIERE,
   * bords compris. Or le rail de gauche (176 px) et l'entete (~200 px) sont
   * opaques et posés par-dessus : ils mangeaient tout le bord gauche et tout
   * le haut de l'image. Le revolver, les piles de jetons et le sac de billets
   * disparaissaient sous le menu — l'image etait bien entiere, mais on n'en
   * voyait que les deux tiers.
   *
   * On cale donc le calque sur la zone reellement VISIBLE. Les deux variables
   * sont deja tenues a jour par `has-rail` et le menu horizontal, donc le
   * cadrage suit automatiquement l'ouverture du rail ou du chat.
   */
  top: var(--hauteur-nav, 0px);
  left: var(--decalage-rail, 0px);
  bottom: 0;

  /*
   * LE CHAT N'EST PAS DEDUIT DU CADRE, contrairement au rail.
   *
   * Le rail est OPAQUE : deduire sa largeur evite que l'image passe dessous,
   * inutilement. Le chat, lui, est semi-transparent — l'image doit continuer
   * DERRIERE lui. En le deduisant, le fond se recadrait a chaque ouverture :
   * l'image sautait vers la gauche, se retrecissait, et le simple fait
   * d'ouvrir le chat faisait bouger tout le decor. Tres visible, et laid.
   *
   * Le cadre s'arrete donc au bord droit de la fenetre dans les deux cas :
   * ouvrir ou fermer le chat ne deplace plus un seul pixel du fond.
   */
  right: 0;

  /*
   * z-index 0, PAS -1.
   *
   * A -1 le calque passait derriere le fond OPAQUE du body : l'image restait
   * visible sur les zones vides, mais aucun `backdrop-filter` ne pouvait la
   * capter — le chat translucide ne floutait donc que du noir uni, et on ne
   * voyait rien a travers.
   *
   * A 0 il est dans le flux normal, au-dessus du fond du body et en dessous
   * de tout contenu (qui est positionne ou vient plus tard dans le DOM).
   */
  z-index: 0;
  pointer-events: none;

  background-image: url('/img/fond-casino.jpg');
  background-repeat: no-repeat;

  /*
   * `100% auto` : l'image occupe TOUTE la largeur du cadre, et sa hauteur
   * suit ses proportions.
   *
   * `contain` laissait une bande sombre sur les cotes des que le cadre etait
   * plus "carre" que l'image : il ajuste sur la dimension la plus
   * contraignante, et c'etait la hauteur. En imposant la largeur, il ne reste
   * plus un pixel de vide a gauche ni a droite.
   *
   * Le debordement eventuel en hauteur est rogne sans consequence : c'est un
   * fond, et les motifs sont repartis sur toute la surface.
   */
  background-size: 100% auto;
  background-position: center;

  /*
   * PAS de `background-color` ici : le calque porte `opacity`, donc une
   * couleur de fond s'appliquerait a TOUTE la surface et poserait un voile
   * sombre sur la page. Les zones non couvertes laissent voir le fond du
   * body, qui est deja le bon noir.
   *
   * L'image est tres sombre : a 22 % les motifs se devinent sans jamais
   * gener la lecture du contenu pose dessus.
   */
  opacity: .22;
}

/* Moins de bruit visuel pour qui demande moins d'animation : la meme
   preference systeme couvre les deux. */
@media (prefers-reduced-motion: reduce) {
  body::before { opacity: .12; }
}

a { color: inherit; text-decoration: none; }
code { font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace; font-size: .92em; }
h1, h2, h3 { letter-spacing: -.8px; }

/* ================= Barre du haut ================= */

.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 30px;
  padding: 14px 30px;
  background: rgba(7, 9, 16, .82);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--bordure);
}

.brand { display: flex; align-items: center; gap: 10px; font-size: 19px; letter-spacing: -.5px; }
.brand strong { color: var(--accent); font-weight: 800; }
/* Logo Donut Rush. Le degrade CSS qui simulait un donut est remplace par le
   vrai dessin de Sam. La version 64px sert partout : a 21px affiches, elle
   reste nette sur ecran Retina sans trainer les 218 Ko du 512. */
.brand-dot {
  width: 26px; height: 26px; flex: none;
  background: url('/img/logo-64.png') center/contain no-repeat;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .45));
}

.nav { display: flex; gap: 24px; margin-right: auto; color: var(--texte-doux); font-weight: 500; font-size: 14.5px; }
.nav a { transition: color .14s ease; }
.nav a:hover { color: var(--texte); }

.account { display: flex; align-items: center; gap: 12px; }

.balance {
  display: flex; flex-direction: column; align-items: flex-end;
  padding: 6px 15px; border-radius: 11px;
  background: var(--fond-2); border: 1px solid var(--bordure);
}
.balance-label { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--texte-doux); }
.balance-value { font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }

/* ================= Boutons ================= */

.btn {
  border: 0; border-radius: 11px; padding: 10px 19px;
  font: inherit; font-weight: 600; cursor: pointer;
  transition: transform .12s ease, filter .12s ease, background .12s ease, border-color .12s ease;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-fonce));
  color: #1c1300;
  box-shadow: 0 6px 20px rgba(255, 176, 58, .22);
}
.btn-primary:hover { filter: brightness(1.08); }
.btn-ghost { background: var(--fond-3); color: var(--texte); border: 1px solid var(--bordure); }
.btn-ghost:hover { background: var(--fond-4); border-color: var(--bordure-claire); }
.btn-lg { padding: 15px 30px; font-size: 16px; }
.btn-sm { padding: 6px 13px; font-size: 13px; }
.btn-block { width: 100%; margin-top: 14px; }
.btn:disabled { opacity: .55; cursor: not-allowed; }

/* ================= Structure ================= */

/*
 * CENTRAGE ENTRE LES PANNEAUX FIXES, pas dans la fenetre entiere.
 *
 * CE QUI ETAIT FAUX : le rail de gauche et le chat de droite sont en
 * `position: fixed`, et on compensait leur largeur par un `padding` sur
 * `main`. Mais `main` est une boite centree (`max-width` + `margin: auto`) :
 * un padding rogne son INTERIEUR sans deplacer la boite. Chat ouvert, le
 * contenu se retrouvait donc comprime ET toujours centre sur la fenetre
 * entiere — c'est-a-dire pousse a droite, sous le panneau, alors qu'il
 * restait largement la place a gauche.
 *
 * MAINTENANT les panneaux posent de vraies MARGES. La boite est reduite a
 * l'espace disponible, et `margin: auto` la recentre DANS cet espace : le
 * contenu glisse vers la gauche a l'ouverture du chat au lieu de retrecir
 * sur place.
 *
 * Les variables sont posees sur `body` par `has-rail` et `chat-open`, et
 * remises a zero en dessous de leurs points de rupture respectifs, la ou les
 * panneaux ne prennent plus de colonne.
 */
:root {
  --decalage-rail: 0px;
  --decalage-chat: 0px;
}

/*
 * Le contenu passe au-dessus du calque de fond (z-index 0).
 *
 * UNIQUEMENT `main` et `footer` : ce sont les seuls elements NON positionnes,
 * donc les seuls qui se peindraient derriere le calque. Le rail, l'entete, le
 * chat et les modales sont deja en `position: fixed` avec leur propre
 * z-index — leur imposer `position: relative` ici les decrocherait de
 * l'ecran et casserait toute la mise en page.
 */
main, footer {
  position: relative;
  z-index: 1;
}

main {
  /*
   * Les marges laterales valent AU MOINS la largeur du panneau fixe de ce
   * cote, et sinon tout l'espace libre a repartir — ce que `auto` fait deja.
   * Les deux etant `auto` quand il reste de la place, la boite se recentre
   * d'elle-meme dans l'espace restant, sans calcul a tenir a jour.
   */
  max-width: 1140px;
  margin-inline: auto;
  padding: 0 24px 90px;

  /*
   * Le decalage passe par une bordure transparente, pas par un padding.
   *
   * En `border-box` (le reglage global du site), un padding est COMPRIS dans
   * `max-width` : il rogne le contenu sans deplacer la boite, ce qui etait
   * exactement le bug. Une bordure s'ajoute au contraire a l'exterieur de la
   * largeur, donc elle POUSSE la boite — et `margin-inline: auto` la compte
   * quand il recentre dans l'espace restant.
   *
   * On garde donc le `border-box` global : `max-width` continue de designer
   * la meme largeur qu'avant, padding compris.
   */
  border-left: var(--decalage-rail) solid transparent;
  border-right: var(--decalage-chat) solid transparent;
}

.section { padding: 62px 0; }
.section-head { margin-bottom: 30px; }
.section-head h2 { font-size: 30px; margin: 0 0 6px; }
.section-sub { color: var(--texte-doux); margin: 0; }
.center { text-align: center; }

/* ================= Hero ================= */

.hero { padding: 78px 0 56px; text-align: center; }

.pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 16px; border-radius: 100px; margin-bottom: 24px;
  background: var(--fond-2); border: 1px solid var(--bordure);
  font-size: 13px; color: var(--texte-doux);
}
.pill-dot {
  width: 7px; height: 7px; border-radius: 50%; background: var(--vert);
  box-shadow: 0 0 0 3px rgba(53, 217, 138, .18);
}

.hero h1 {
  font-size: clamp(34px, 5.6vw, 60px); line-height: 1.06;
  letter-spacing: -2px; margin: 0 0 20px;
  background: linear-gradient(115deg, #fff 22%, var(--accent) 72%, var(--rose) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-sub { max-width: 640px; margin: 0 auto 32px; color: var(--texte-doux); font-size: 16.5px; }
.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

.hero-stats {
  display: flex; gap: 52px; justify-content: center; margin-top: 58px; flex-wrap: wrap;
}
.hero-stats div { display: flex; flex-direction: column; gap: 2px; }
.hero-stats strong { font-size: 26px; color: var(--accent); letter-spacing: -1px; }
.hero-stats span { font-size: 11.5px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--texte-doux); }

/* ================= Cartes de jeu ================= */

.game-grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fill, minmax(244px, 1fr));
}

.game-card {
  background: var(--fond-2); border: 1px solid var(--bordure);
  border-radius: var(--rayon); overflow: hidden;
  transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.game-card:hover {
  transform: translateY(-5px);
  border-color: var(--accent);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .4);
}
.game-card.soon { opacity: .55; pointer-events: none; }

.game-art {
  height: 128px; display: flex; align-items: center; justify-content: center;
  position: relative;
}
.art-glyph { font-size: 44px; filter: drop-shadow(0 4px 12px rgba(0, 0, 0, .45)); }

.art-dice   { background: linear-gradient(135deg, #1e2a55, #4256a8); }
.art-limbo  { background: linear-gradient(135deg, #12503c, #2bbf7a); }
.art-mines  { background: linear-gradient(135deg, #551d33, #d9455a); }
.art-coin   { background: linear-gradient(135deg, #5a4212, var(--accent)); }
.art-crash  { background: linear-gradient(135deg, #4a1f52, #a34fb8); }
.art-plinko { background: linear-gradient(135deg, #1d4553, #37a0c4); }

.game-body { padding: 16px 18px 18px; }
.game-body h3 { margin: 0 0 5px; font-size: 17.5px; }
.game-body p { margin: 0 0 10px; color: var(--texte-doux); font-size: 13.5px; }

.game-tag {
  display: inline-block; padding: 3px 10px; border-radius: 100px;
  background: var(--fond-4); border: 1px solid var(--bordure-claire);
  font-size: 11.5px; font-weight: 600; color: var(--accent);
}
.tag-soon { color: var(--texte-doux); }

/* ================= How it works ================= */

.how-grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(272px, 1fr));
}

.how-step {
  background: var(--fond-2); border: 1px solid var(--bordure);
  border-radius: var(--rayon); padding: 24px;
}
.how-step h3 { margin: 14px 0 8px; font-size: 17px; }
.how-step p { margin: 0; color: var(--texte-doux); font-size: 14px; }
.how-step code {
  background: var(--fond-4); padding: 2px 7px; border-radius: 5px; color: var(--accent);
}

.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 10px;
  background: linear-gradient(135deg, var(--accent), var(--accent-fonce));
  color: #1c1300; font-weight: 800; font-size: 15px;
}

.callout {
  margin-top: 20px; padding: 20px 24px;
  background: var(--fond-2); border: 1px solid var(--bordure);
  border-left: 3px solid var(--accent); border-radius: 12px;
}
.callout strong { display: block; margin-bottom: 6px; }
.callout p { margin: 0; color: var(--texte-doux); font-size: 14px; }

/* ================= FAQ ================= */

.faq { display: grid; gap: 10px; }
.faq details {
  background: var(--fond-2); border: 1px solid var(--bordure);
  border-radius: 12px; padding: 16px 20px;
}
.faq details[open] { border-color: var(--bordure-claire); }
.faq summary {
  cursor: pointer; font-weight: 600; list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; color: var(--accent); font-size: 20px; line-height: 1; }
.faq details[open] summary::after { content: '\2212'; }
.faq p { margin: 12px 0 0; color: var(--texte-doux); font-size: 14px; }

/* ================= Pied de page ================= */

footer { border-top: 1px solid var(--bordure); padding: 34px 24px 40px; }
.footer-inner {
  max-width: 1140px; margin: 0 auto 22px;
  display: flex; justify-content: space-between; align-items: center; gap: 24px; flex-wrap: wrap;
}
.footer-brand { display: flex; flex-direction: column; gap: 6px; }
.footer-links { display: flex; gap: 22px; flex-wrap: wrap; color: var(--texte-doux); font-size: 14px; }
.footer-links a:hover { color: var(--texte); }
footer .center { max-width: 640px; margin: 0 auto; }

/* ================= Modales ================= */

.modal {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: rgba(3, 5, 10, .78); backdrop-filter: blur(6px);
  padding: 20px;
}
.modal-card {
  position: relative; width: 100%; max-width: 430px;
  background: var(--fond-2); border: 1px solid var(--bordure-claire);
  border-radius: 18px; padding: 32px; box-shadow: var(--ombre);
}
.modal-card h2 { margin: 0 0 10px; font-size: 22px; }
.modal-close {
  position: absolute; top: 14px; right: 17px;
  background: none; border: 0; color: var(--texte-doux);
  font-size: 27px; line-height: 1; cursor: pointer;
}
.modal-close:hover { color: var(--texte); }

label { display: block; margin: 16px 0 6px; font-size: 13px; color: var(--texte-doux); font-weight: 600; }
input[type=text], input[type=number] {
  width: 100%; padding: 12px 15px; border-radius: 11px;
  background: var(--fond); border: 1px solid var(--bordure);
  color: var(--texte); font: inherit;
}
input:focus { outline: none; border-color: var(--accent); }

.cmd-box {
  display: flex; align-items: center; gap: 10px; margin: 14px 0;
  padding: 13px 16px; border-radius: 11px;
  background: var(--fond); border: 1px solid var(--bordure);
}
.cmd-box code { flex: 1; color: var(--accent); word-break: break-all; }

.muted { color: var(--texte-doux); font-size: 14px; }
.small { font-size: 12.5px; }
.error { color: var(--rouge); font-size: 13.5px; margin: 10px 0 0; }
.success { color: var(--vert); font-size: 13.5px; margin: 10px 0 0; }

.waiting { display: flex; align-items: center; gap: 10px; color: var(--texte-doux); margin: 18px 0 8px; }
.spinner {
  width: 16px; height: 16px; border-radius: 50%; flex: none;
  border: 2px solid var(--bordure-claire); border-top-color: var(--accent);
  animation: tourne .8s linear infinite;
}
@keyframes tourne { to { transform: rotate(360deg); } }

.wallet-tabs { display: flex; gap: 8px; margin: 18px 0; }
.tab {
  flex: 1; padding: 10px; border-radius: 10px; cursor: pointer;
  background: var(--fond); border: 1px solid var(--bordure);
  color: var(--texte-doux); font: inherit; font-weight: 600;
}
.tab.active { background: var(--fond-4); color: var(--texte); border-color: var(--accent); }

/* ================= Ecran de jeu ================= */

.game-layout {
  display: grid; gap: 20px; margin-top: 26px;
  grid-template-columns: 330px minmax(0, 1fr);
}

/*
 * La colonne de jeu ne descend jamais sous 420 px : en dessous, un plateau
 * plinko ou une grille de mines deviennent illisibles. Quand la place manque
 * vraiment, on passe en UNE colonne (media query plus bas) plutot que de
 * comprimer les deux — un jeu ecrase est pire qu'un jeu empile.
 */
@media (min-width: 881px) and (max-width: 1320px) {
  body.chat-open .game-layout { grid-template-columns: 300px minmax(420px, 1fr); }
}
@media (max-width: 880px) {
  .game-layout { grid-template-columns: 1fr; }
  .nav { display: none; }
  .hero-stats { gap: 30px; }
}

.panel {
  background: var(--fond-2); border: 1px solid var(--bordure);
  border-radius: var(--rayon); padding: 24px;
}
.stage {
  background: var(--fond-2); border: 1px solid var(--bordure);
  border-radius: var(--rayon); padding: 32px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 360px;

  /*
   * `min-width: 0` sur un enfant de grille.
   *
   * La valeur par defaut est `auto`, ce qui INTERDIT a la colonne de passer
   * sous la largeur de son contenu. Combine a un `1fr`, la colonne gonflait
   * puis debordait, et le navigateur rattrapait en ecrasant le reste — d'ou
   * des plateaux minuscules des que le chat prenait sa place.
   */
  min-width: 0;
}

/*
 * Les enfants du plateau s'ETIRENT sur toute la largeur.
 *
 * `align-items: center` sur un conteneur en colonne centre les enfants ET
 * les empeche de s'etirer : chacun se reduit a la largeur de son contenu.
 * Un SVG en `width: 100%` n'avait donc plus de reference et se repliait sur
 * sa taille intrinseque — le plateau devenait une vignette alors que la
 * colonne faisait 700 px.
 *
 * On force donc l'etirement, et le centrage reste assure par le `max-width`
 * de chaque plateau plus ses marges automatiques.
 */
.stage > * { max-width: 100%; }
.stage .plinko-board,
.stage .mines-grid,
.stage .road,
.stage .revolver-stage { align-self: stretch; margin-inline: auto; }

.result-big { font-size: 60px; font-weight: 800; letter-spacing: -2.5px; font-variant-numeric: tabular-nums; }
.result-win { color: var(--vert); }
.result-lose { color: var(--rouge); }
.result-note { color: var(--texte-doux); margin-top: 10px; }

.mines-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; width: min(100%, 350px); }
.mine-tile {
  aspect-ratio: 1; border-radius: 11px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  display: flex; align-items: center; justify-content: center; font-size: 22px;
  transition: transform .12s ease, background .12s ease;
}
.mine-tile:hover { transform: translateY(-2px); background: var(--fond-4); }
.mine-tile.picked { background: var(--accent); border-color: var(--accent); }
.mine-tile.safe { background: rgba(53, 217, 138, .22); border-color: var(--vert); }
.mine-tile.bomb { background: rgba(255, 85, 102, .22); border-color: var(--rouge); }

.stat-row { display: flex; justify-content: space-between; padding: 7px 0; font-size: 13.5px; }
.stat-row span:first-child { color: var(--texte-doux); }
.stat-row span:last-child { font-weight: 600; font-variant-numeric: tabular-nums; }

.seg { display: flex; gap: 8px; margin-top: 8px; }
.seg button {
  flex: 1; padding: 10px; border-radius: 10px; cursor: pointer;
  background: var(--fond); border: 1px solid var(--bordure);
  color: var(--texte-doux); font: inherit; font-weight: 600;
}
.seg button.active { background: var(--fond-4); color: var(--texte); border-color: var(--accent); }

.history { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 22px; justify-content: center; }
.chip {
  padding: 4px 11px; border-radius: 100px; font-size: 12px; font-weight: 700;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.chip.win { color: var(--vert); border-color: rgba(53, 217, 138, .4); }
.chip.lose { color: var(--rouge); border-color: rgba(255, 85, 102, .4); }

/* Apercu sous un champ montant : "10k" -> "= $10,000".
   Confirme au joueur ce qu'il vient de taper avant qu'il valide — a neuf
   chiffres, une lettre de travers coute cher. */
.amount-preview {
  margin: 6px 0 0;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* ------------------------------------------------------------------ */
/* Raccourcis de montant et steppers                                   */
/* ------------------------------------------------------------------ */

.presets { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.presets button {
  flex: 1 1 auto; min-width: 54px;
  padding: 7px 10px; border-radius: 9px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  color: var(--texte-2); font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  transition: border-color .15s, color .15s, background .15s;
}
.presets button:hover { border-color: var(--accent); color: var(--texte); }
.presets button.active {
  border-color: var(--accent); color: #1a1206;
  background: linear-gradient(135deg, var(--accent), var(--accent-fonce));
}

.stepper { display: flex; align-items: stretch; gap: 6px; }
.stepper input {
  flex: 1; text-align: center; font-weight: 700;
  font-variant-numeric: tabular-nums; cursor: default;
}
.stepper button {
  width: 44px; border-radius: 10px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  color: var(--texte); font-size: 19px; font-weight: 700; line-height: 1;
  transition: border-color .15s, background .15s;
}
.stepper button:hover:not(:disabled) { border-color: var(--accent); }
.stepper button:disabled { opacity: .35; cursor: not-allowed; }

/* ------------------------------------------------------------------ */
/* Coinflip — piece doree                                              */
/* ------------------------------------------------------------------ */

/*
 * Version volontairement simple. La precedente empilait une tranche de 72
 * segments 3D, un reflet pilote a la frame et des rebonds en cascade : trop
 * de pieces mobiles pour un resultat qui cassait au premier maillon lache.
 *
 * Deux faces DOREES — les deux cotes sont en or, seule la lettre change.
 * L'epaisseur est suggeree par une bordure sombre et une ombre portee, ce
 * qui suffit largement a l'echelle affichee.
 */

.coin-scene {
  position: relative;
  width: 100%; height: 210px;
  display: grid; place-items: center;
  perspective: 900px;
  user-select: none; -webkit-user-select: none;
}

.coin-shadow {
  position: absolute; left: 50%; bottom: 18px;
  width: 120px; height: 16px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .5);
  filter: blur(8px);
  transform: translateX(-50%);
  opacity: .55;
  pointer-events: none;
}

/* Flottement au repos. PORTE PAR LE PARENT, jamais par l'element qui
   tourne : animer une translation sur un noeud en preserve-3d aplatit son
   contexte 3D, les deux faces se superposent, et backface-visibility cesse
   d'agir (on voyait alors HEADS en miroir sur un resultat tails). */
.coin-flotte {
  display: grid; place-items: center;
  animation: coin-idle 3.6s ease-in-out infinite;
}
.coin-flotte.flipping { animation: none; }
@keyframes coin-idle {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}

.coin3d {
  position: relative;
  width: 150px; height: 150px;
  transform-style: preserve-3d;
  will-change: transform;
}

.coin3d-face {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px;
  border-radius: 50%;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  /* Bordure sombre epaisse : c'est elle qui suggere la tranche. */
  border: 6px solid #8a6410;
  background:
    radial-gradient(circle at 34% 28%,
      rgba(255, 255, 225, .95) 0%, rgba(255, 250, 200, .4) 14%, transparent 34%),
    linear-gradient(140deg, #fff0ad 0%, #ffd98a 24%, #f5c542 52%, #d49e16 76%, #a8780c 100%);
  box-shadow:
    inset 0 4px 8px rgba(255, 255, 220, .85),
    inset 0 -7px 12px rgba(120, 76, 0, .55),
    0 12px 26px rgba(0, 0, 0, .5);
  color: #6b4a00;
}

.coin3d-heads { transform: translateZ(6px); }
/* La face pile est au dos, pre-tournee : elle apparait quand la piece a fait
   un demi-tour. */
.coin3d-tails { transform: rotateY(180deg) translateZ(6px); }

.coin-mark {
  font-size: 58px; font-weight: 900; line-height: 1; letter-spacing: -3px;
  /* Clair en haut, sombre en bas : la lettre parait frappee dans le metal. */
  text-shadow: 1px 1px 0 rgba(255, 240, 160, .9), -1px -1px 0 rgba(90, 60, 0, .6);
}
.coin-word {
  font-size: 11px; font-weight: 800; letter-spacing: 2.6px; opacity: .62;
}

/* Halo de resultat, pose par coinflip.js sur le CONTENEUR.
   Jamais sur .coin3d : un filter aplatit le preserve-3d de l'element qui le
   porte, les deux faces se superposent, et on voit la face arriere en
   miroir a travers l'avant. */
.coin-flotte.win  { filter: drop-shadow(0 0 16px rgba(53, 217, 138, .65)); }
.coin-flotte.lose { filter: drop-shadow(0 0 16px rgba(255, 85, 102, .55)); }

@media (max-width: 560px) {
  .coin3d { width: 118px; height: 118px; }
  .coin-mark { font-size: 46px; }
}
@media (prefers-reduced-motion: reduce) {
  .coin-flotte { animation: none; }
  .coin3d { transition: none !important; }
}

/* ------------------------------------------------------------------ */
/* Rail de jeux — toujours visible                                     */
/* ------------------------------------------------------------------ */

.rail {
  position: fixed; left: 0; top: var(--hauteur-nav); bottom: 0; width: 176px; z-index: 40;
  display: flex; flex-direction: column; gap: 1px;
  padding: 12px 10px; overflow-y: auto;
  background: var(--fond-2); border-right: 1px solid var(--bordure);
  /* Barre fine : avec 14 jeux la liste depasse souvent, mais une barre
     epaisse mangerait la largeur du libelle. */
  scrollbar-width: thin;
}
.rail::-webkit-scrollbar { width: 5px; }
.rail::-webkit-scrollbar-thumb { background: var(--bordure-claire); border-radius: 100px; }

.rail-title {
  font-size: 9.5px; font-weight: 800; letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--texte-2);
  padding: 0 10px 6px;
}

.rail-item {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: 9px;
  color: var(--texte-2); text-decoration: none;
  font-size: 13.5px; font-weight: 600;
  border: 1px solid transparent;
  transition: background .15s, color .15s, border-color .15s;
}
.rail-item:hover { background: var(--fond-3); color: var(--texte); }

.rail-item.active {
  background: var(--fond-3); color: var(--texte);
  border-color: rgba(255, 176, 58, .42);
}
/* Liseré ambre : repere l'ecran courant sans alourdir le rail. */
.rail-item.active .rail-icon {
  display: flex; align-items: center; justify-content: center;
  width: 20px; flex: 0 0 20px;
  opacity: .78;
}
.rail-item:hover .rail-icon,
.rail-item.active .rail-icon { opacity: 1; }
.ds-icone { display: block; }

.rail-icon { font-size: 15px; line-height: 1; width: 19px; text-align: center; }
.rail-name { flex: 1; }

.rail-soon { opacity: .42; cursor: not-allowed; pointer-events: none; }
.rail-tag {
  font-size: 9px; font-weight: 800; letter-spacing: .6px;
  padding: 2px 6px; border-radius: 100px;
  background: var(--fond-4); color: var(--texte-2);
}

/* Le rail est en position fixe : le contenu se decale, sinon il passe dessous. */
/* Le rail reserve sa colonne : `main` se recentre dans ce qui reste. */
/* 177px et non 176 : le rail fait 176 px PLUS sa bordure droite de 1 px.
   Un pixel de decalage laissait une fine ligne du fond visible a cote. */
body.has-rail { --decalage-rail: 177px; }
body.has-rail footer { padding-left: 176px; }

/* Sous 880px le rail passe en barre horizontale collee en bas : sur telephone
   une colonne de 188px mangerait la moitie de l'ecran. */
@media (max-width: 880px) {
  .rail {
    top: auto; right: 0; bottom: 0; width: auto; height: auto;
    flex-direction: row; gap: 6px; overflow-x: auto; overflow-y: hidden;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
    border-right: none; border-top: 1px solid var(--bordure);
  }
  .rail-title, .rail-tag { display: none; }
  .rail-item { flex-direction: column; gap: 3px; padding: 7px 12px; font-size: 11px; }
  .rail-soon { display: none; }
  /* Rail en barre horizontale : plus rien a reserver sur le cote. */
  body.has-rail { --decalage-rail: 0px; }
  body.has-rail main { padding-bottom: 104px; }
  body.has-rail footer { padding-left: 0; padding-bottom: 76px; }
}

/* ------------------------------------------------------------------ */
/* Roulette                                                            */
/* ------------------------------------------------------------------ */

.wheel-stage { position: relative; width: 100%; max-width: 400px; margin: 0 auto 18px; }
.wheel { width: 100%; height: auto; display: block; filter: drop-shadow(0 18px 40px rgba(0,0,0,.55)); }

/* Pointeur fixe en haut : c'est lui qui designe la case gagnante. */
.wheel-pointer {
  position: absolute; top: -4px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; z-index: 3;
  border-left: 13px solid transparent; border-right: 13px solid transparent;
  border-top: 22px solid var(--accent);
  filter: drop-shadow(0 3px 6px rgba(0,0,0,.6));
}

/*
 * LA BILLE. Superposee a la roue, meme viewBox, donc meme centre.
 *
 * Une premiere version utilisait une orbite CSS : elle derivait de la roue
 * des que la fenetre changeait de taille, parce que les deux transformations
 * n'avaient pas le meme repere. En SVG superpose le probleme disparait —
 * `200 200` designe le meme point dans les deux calques, a toute taille.
 */
.wheel-ball {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 2; pointer-events: none;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .7));
}

/* L'orbite tourne autour du centre exact du viewBox. */
#ballOrbit { transform-origin: 200px 200px; }

@media (prefers-reduced-motion: reduce) {
  #ballOrbit { transition: none !important; }
}

.seg-colors button {
  flex-direction: column; gap: 2px; padding: 9px 4px; color: #fff;
  transition: background .15s, border-color .15s, box-shadow .15s, transform .1s;
}
.seg-mult { font-size: 10px; opacity: .62; font-weight: 700; }

.seg-colors .seg-red { background: #8e1c29; border-color: #b02a3c; }
.seg-colors .seg-red:hover { background: #ad2333; }
.seg-colors .seg-black { background: #1b2130; border-color: #3d4762; }
.seg-colors .seg-black:hover { background: #262f44; }
.seg-colors .seg-green { background: #1f7a45; border-color: #2a9a58; }
.seg-colors .seg-green:hover { background: #279654; }

.seg-colors button.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(255,176,58,.55), 0 4px 12px rgba(0,0,0,.4);
  transform: translateY(-2px);
}
.seg-colors .seg-red.active { background: #a8202f; }
.seg-colors .seg-black.active { background: #222a3c; }
.seg-colors .seg-green.active { background: #269052; }

.roulette-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 4px; margin-top: 8px;
}
.rn {
  padding: 8px 0; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--bordure); color: #fff;
  font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums;
  transition: transform .1s, box-shadow .15s, border-color .15s;
}
.rn-zero { grid-column: 1 / -1; }
.rn-red { background: #8e1c29; }
.rn-black { background: #1b2130; }
.rn-green { background: #1f7a45; }
.rn:hover { transform: translateY(-1px); border-color: var(--accent); }
.rn.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(255,176,58,.55), 0 4px 12px rgba(0,0,0,.4);
  transform: translateY(-2px);
}

.roulette-result {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 12px; width: 100%; max-width: 430px; margin-top: 6px;
  padding: 16px; border-radius: var(--rayon);
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.rr-cell { display: flex; flex-direction: column; gap: 3px; }
.rr-label { font-size: 10px; letter-spacing: 1.1px; text-transform: uppercase; color: var(--texte-2); }
.rr-value { font-size: 21px; font-weight: 800; font-variant-numeric: tabular-nums; }
.rr-red { color: #ff6b78; }
.rr-black { color: #9aa6c4; }
.rr-green { color: var(--vert); }

.chip-red { border-color: rgba(168,32,47,.6); color: #ff8a94; }
.chip-black { border-color: rgba(90,100,128,.6); color: #9aa6c4; }
.chip-green { border-color: rgba(53,217,138,.5); color: var(--vert); }

@media (prefers-reduced-motion: reduce) {
  .wheel { transition: none !important; }
}

/* ------------------------------------------------------------------ */
/* Plinko                                                              */
/* ------------------------------------------------------------------ */

.stage-plinko { justify-content: flex-start; padding: 22px 18px; }

.plinko-board {
  position: relative; width: 100%; max-width: 600px;
  border-radius: 14px; overflow: hidden;
  background: radial-gradient(ellipse at 50% 0%, #161c28 0%, #0c1017 70%);
  border: 1px solid var(--bordure);
}
.plinko-board svg { width: 100%; height: auto; display: block; }

.plinko-ball {
  position: absolute; width: 17px; height: 17px; margin: -8px 0 0 -8px;
  border-radius: 50%; z-index: 3; pointer-events: none;
  background: radial-gradient(circle at 34% 30%, #ffd98a 0%, var(--accent) 52%, var(--accent-fonce) 100%);
  box-shadow: 0 0 13px rgba(255,176,58,.75), 0 3px 7px rgba(0,0,0,.55);
}

/* Cases de multiplicateur — dessinees DANS le SVG du plateau, au meme
   repere que les clous : alignement garanti par la geometrie, et aucun
   defilement possible. */
.bk rect { transition: transform .18s, filter .18s; transform-origin: center; }
.bk text { font-weight: 800; fill: currentColor; pointer-events: none; }

.bk-cold rect { fill: #22283a; }
.bk-cold text { fill: #7b86a3; }
.bk-warm rect { fill: #3a3122; }
.bk-warm text { fill: #e2b467; }
.bk-hot  rect { fill: url(#bkHot); }
.bk-hot  text { fill: #1a1206; }

/* La case encaisse l'arrivee de la bille : un enfoncement bref, qui donne
   le poids de l'impact. */
@keyframes bkRecu {
  0%   { transform: translateY(0) scaleY(1); }
  35%  { transform: translateY(3px) scaleY(.86); }
  100% { transform: translateY(0) scaleY(1); }
}
.bk-recu rect { animation: bkRecu .42s cubic-bezier(.3, .9, .3, 1); }

.bk-hit rect {
  filter: drop-shadow(0 0 7px rgba(255, 176, 58, .9));
  stroke: var(--accent); stroke-width: 2;
}

@media (prefers-reduced-motion: reduce) {
  .plinko-ball { transition: none !important; }
}

/* ------------------------------------------------------------------ */
/* Blackjack — tapis vert                                              */
/* ------------------------------------------------------------------ */

.stage-felt {
  position: relative; justify-content: space-between; gap: 14px;
  min-height: 470px; padding: 26px 22px;
  background-color: #0d3324;
  border-color: #1d5c3f;
  box-shadow: inset 0 0 90px rgba(0, 0, 0, .55);
}
/* Tapis : degrade radial pour donner du volume au centre de la table. */
.stage-felt { background-image: radial-gradient(ellipse at 50% 38%, #1e7049 0%, #123f2c 58%, #081d14 100%); }

.felt-logo {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  font-size: 42px; font-weight: 800; letter-spacing: -1px;
  color: rgba(255, 255, 255, .05); pointer-events: none; user-select: none;
}
.felt-logo strong { color: rgba(255, 176, 58, .1); }

.bj-row { position: relative; z-index: 1; width: 100%; text-align: center; }
.bj-who {
  display: block; font-size: 10px; font-weight: 800; letter-spacing: 1.6px;
  text-transform: uppercase; color: rgba(255, 255, 255, .52); margin-bottom: 9px;
}
.bj-total { color: var(--accent); font-size: 13px; letter-spacing: 0; }

.bj-cards { display: flex; justify-content: center; gap: 8px; min-height: 108px; flex-wrap: wrap; }

.card {
  position: relative; width: 74px; height: 104px; border-radius: 8px;
  background: linear-gradient(160deg, #fdfdfd, #e6e8ee);
  border: 1px solid #b9bdc9; color: #161a22;
  box-shadow: 0 5px 14px rgba(0, 0, 0, .45);
  font-weight: 800; flex: 0 0 auto;
}
.card-red { color: #c62839; }

.card-corner { position: absolute; font-size: 12px; line-height: 1.05; text-align: center; }
.card-tl { top: 5px; left: 6px; }
.card-br { bottom: 5px; right: 6px; transform: rotate(180deg); }
.card-pip {
  position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; font-size: 33px;
}

.card-back {
  background:
    repeating-linear-gradient(45deg, #2b3a6b 0 7px, #1d2950 7px 14px);
  border-color: #47589a;
}

.card-deal { animation: card-in .3s cubic-bezier(.2,.9,.3,1.1) both; }
@keyframes card-in {
  from { opacity: 0; transform: translateY(-28px) rotate(-9deg) scale(.88); }
  to   { opacity: 1; transform: none; }
}

.bj-outcome {
  position: relative; z-index: 1; min-height: 34px;
  font-size: 25px; font-weight: 900; letter-spacing: 2.5px;
  opacity: 0; transition: opacity .25s;
}
.bj-outcome.visible { opacity: 1; }

.bj-actions { display: flex; gap: 7px; margin-top: 10px; }
.bj-actions .btn { flex: 1; padding: 11px 6px; font-size: 13px; }

@media (max-width: 560px) {
  .card { width: 58px; height: 82px; }
  .card-pip { font-size: 26px; }
  .felt-logo { font-size: 30px; }
}
@media (prefers-reduced-motion: reduce) {
  .card-deal { animation: none; }
}

/* ------------------------------------------------------------------ */
/* Items Minecraft — textures reelles                                  */
/* ------------------------------------------------------------------ */

/*
 * Textures WebP fournies par Sam, servies depuis /img. La regle
 * image-rendering: pixelated est indispensable : sans elle le navigateur
 * lisse les 16x16 d origine et l item devient flou des qu on l agrandit.
 */
.mc-item {
  display: block; width: 54px; height: 54px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  image-rendering: pixelated;
  filter: drop-shadow(0 3px 6px rgba(0,0,0,.5));
}

.mc-cobblestone { background-image: url('/img/mc/cobble.png'); }
.mc-paper       { background-image: url('/img/mc/paper.png'); }
.mc-shears      { background-image: url('/img/mc/shears.png'); }

.mc-unknown {
  display: flex; align-items: center; justify-content: center;
  background: var(--fond-4); border: 2px dashed var(--bordure);
  border-radius: 6px; color: var(--texte-2);
  font-size: 27px; font-weight: 900;
}

/* ------------------------------------------------------------------ */
/* Duel — selecteur de mode                                            */
/* ------------------------------------------------------------------ */

.mode-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px;
}
.mode-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: 11px 11px 10px; border-radius: 12px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  text-align: left; font-family: inherit;
  transition: border-color .15s, transform .12s, background .15s;
}
.mode-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.mode-card.active {
  border-color: var(--accent); background: rgba(255, 176, 58, .10);
}
.mode-icons { display: flex; align-items: center; gap: 3px; height: 28px; }
.mode-sprite { display: flex; }
.mode-sprite .mc-item { width: 26px; height: 26px; }
.mode-glyph { font-size: 23px; line-height: 1; }
.mode-name {
  font-size: 13px; font-weight: 800; color: var(--texte); letter-spacing: .2px;
}
.mode-rule { font-size: 10.5px; line-height: 1.35; color: var(--texte-doux); }

@media (max-width: 520px) {
  .mode-grid { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------------ */
/* RPS                                                                 */
/* ------------------------------------------------------------------ */

.rps-picker { display: flex; gap: 7px; margin-top: 8px; }
.rps-pick {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 13px 6px; border-radius: 12px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  color: var(--texte-2); font-size: 11px; font-weight: 700;
  transition: border-color .15s, transform .12s, background .15s;
}
.rps-pick .mc-item { width: 40px; height: 40px; }
.rps-pick:hover { border-color: var(--accent); transform: translateY(-2px); }
.rps-pick.active { border-color: var(--accent); background: var(--fond-4); color: var(--texte); }

.rps-arena {
  display: flex; align-items: center; justify-content: center;
  gap: 22px; margin-bottom: 16px;
}
.rps-side { display: flex; flex-direction: column; align-items: center; gap: 9px; }
.rps-label {
  font-size: 10px; font-weight: 800; letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--texte-2);
}
.rps-slot {
  display: flex; align-items: center; justify-content: center;
  width: 104px; height: 104px; border-radius: 15px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.rps-slot .mc-item { width: 62px; height: 62px; }
.rps-slot.shaking { animation: rps-shake .16s ease-in-out infinite; }
@keyframes rps-shake {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-9px) rotate(-5deg); }
}
.rps-slot.win  { border-color: var(--vert); box-shadow: 0 0 0 3px rgba(53,217,138,.26); }
.rps-slot.lose { border-color: var(--rouge); box-shadow: 0 0 0 3px rgba(255,85,102,.24); }

.rps-vs { font-size: 15px; font-weight: 900; color: var(--texte-2); letter-spacing: 1.4px; }

@media (prefers-reduced-motion: reduce) {
  .rps-slot.shaking { animation: none; }
}

/* ------------------------------------------------------------------ */
/* Chicken Road                                                        */
/* ------------------------------------------------------------------ */

.stage-road { justify-content: center; gap: 18px; }

/*
 * CADRE FIXE, ROUTE MOBILE.
 *
 * La route defile a l interieur de ce cadre ; le cadre, lui, ne bouge jamais.
 * Avant ce confinement, avancer au-dela de la case 6 faisait defiler la page
 * entiere et le panneau de mise sortait de l ecran.
 *
 * `max-width` la garde compacte : 25 cases de 66 px feraient 1825 px de large,
 * bien plus que la place disponible a cote du panneau.
 */
.road {
  position: relative; width: 100%; max-width: 640px;
  margin: 0 auto; padding: 40px 0 14px;
  overflow-x: auto; overflow-y: hidden;
  /* Le defilement est pilote en JS : on masque la barre, qui sauterait a
     chaque pas. */
  scrollbar-width: none;
  /* Isole le defilement : un scroll dans la route ne remonte pas a la page. */
  overscroll-behavior-x: contain;
}
.road::-webkit-scrollbar { display: none; }
/* Contexte de positionnement du poulet : il vit DANS la voie, donc il suit
   le defilement au lieu de rester colle au cadre. */
.road-lane { position: relative; display: flex; gap: 7px; padding: 0 6px; }

.tile {
  flex: 0 0 auto; width: 66px; height: 78px; border-radius: 11px;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
  background: linear-gradient(180deg, #232a3a 0%, #171d29 100%);
  border: 1px solid var(--bordure);
  transition: transform .18s, border-color .18s, box-shadow .18s, background .18s;
}
.tile-mult { font-size: 13px; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.tile-num { font-size: 10px; color: var(--texte-2); font-weight: 700; }

.tile-safe {
  background: linear-gradient(180deg, #1c4d36 0%, #123626 100%);
  border-color: var(--vert);
  box-shadow: 0 0 0 1px rgba(53,217,138,.28);
}
.tile-dead {
  background: linear-gradient(180deg, #5c1c24 0%, #3a1117 100%);
  border-color: var(--rouge);
  transform: translateY(3px);
}
.tile-goal { background: var(--fond-4); border-style: dashed; }
.tile-goal .tile-mult { font-size: 24px; }

.chicken {
  position: absolute; top: -34px; left: 0; z-index: 3;
  font-size: 30px; line-height: 1; width: 38px; text-align: center;
  transition: left .28s cubic-bezier(.3,.8,.35,1);
  filter: drop-shadow(0 3px 5px rgba(0,0,0,.55));
}
.chicken.dead { animation: splat .3s ease-out both; }
@keyframes splat {
  from { transform: scale(1); }
  to   { transform: scale(1.45); }
}

@media (prefers-reduced-motion: reduce) {
  .chicken { transition: none; }
  .chicken.dead { animation: none; }
}

/* Mines — grille revelee en fin de manche. */
.mine-tile.missed { opacity: .3; }
/*
 * Grille verrouillee : hors manche, les cases ne sont plus cliquables. Garder
 * le curseur "pointer" et l'effet de survol laissait croire qu'on pouvait
 * ouvrir une case sans avoir mise.
 */
.mines-grid.grid-locked .mine-tile { cursor: default; }
.mines-grid.grid-locked .mine-tile:hover { transform: none; background: var(--fond-3); }
.mines-grid.grid-locked .mine-tile.safe:hover { background: rgba(53, 217, 138, .22); }
.mines-grid.grid-locked .mine-tile.bomb:hover { background: rgba(255, 85, 102, .22); }

/* Bombe jamais ouverte, revelee a la cloture : elle prouve que la grille
   etait reelle, sans voler l'oeil a celle qui a fait sauter la manche. */
.mine-tile.bomb-quiet {
  background: rgba(255, 85, 102, .08);
  border-color: rgba(255, 85, 102, .25);
  opacity: .5;
}

.mine-tile.bomb-hit {
  box-shadow: 0 0 0 3px var(--rouge), 0 0 18px rgba(255,85,102,.5);
  z-index: 1;
}
.btn-replay {
  background: linear-gradient(135deg, var(--vert), #24a869) !important;
  color: #06251a !important;
}

/* Presets de vitesse : neuf paliers, donc plus petits que les presets money. */
.presets-speed button { min-width: 0; flex: 1 1 17%; padding: 6px 2px; font-size: 11px; }

/* Chicken — course interactive. */
.run-actions { display: flex; flex-direction: column; gap: 7px; }
.btn-cashout {
  background: linear-gradient(135deg, var(--vert), #24a869);
  color: #06251a; font-weight: 800; border: none;
}
.btn-cashout:disabled { opacity: .4; cursor: not-allowed; }

/* Case suivante : le pari que le joueur s apprete a prendre. */
.tile-next {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(255,176,58,.4);
  transform: translateY(-4px);
}

/* ------------------------------------------------------------------ */
/* Console d administration                                            */
/* ------------------------------------------------------------------ */

.admin-main { max-width: 1320px; }

.admin-gate {
  display: flex; align-items: center; justify-content: center;
  min-height: 72vh;
}
.admin-gate-card { width: 100%; max-width: 380px; }

.admin-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin: 26px 0 16px; flex-wrap: wrap;
}
.admin-head h1 { font-size: 26px; margin: 0; }
.admin-head-right { display: flex; align-items: center; gap: 9px; }

.admin-tabs { display: flex; gap: 6px; margin-bottom: 18px; flex-wrap: wrap; }

.kpi-grid {
  display: grid; gap: 11px;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
}
.kpi {
  display: flex; flex-direction: column; gap: 4px;
  padding: 15px; border-radius: var(--rayon);
  background: var(--fond-2); border: 1px solid var(--bordure);
}
.kpi-label {
  font-size: 10px; font-weight: 800; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--texte-2);
}
.kpi-value { font-size: 23px; font-weight: 800; font-variant-numeric: tabular-nums; }
.kpi-note { font-size: 10px; color: var(--texte-2); }
.kpi-good { color: var(--vert); }
.kpi-bad { color: var(--rouge); }

.table-wrap {
  overflow-x: auto; border-radius: var(--rayon);
  border: 1px solid var(--bordure); background: var(--fond-2);
}
.admin-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.admin-table th {
  text-align: left; padding: 11px 13px; white-space: nowrap;
  font-size: 10px; font-weight: 800; letter-spacing: 1px; text-transform: uppercase;
  color: var(--texte-2); border-bottom: 1px solid var(--bordure);
}
.admin-table td {
  padding: 10px 13px; white-space: nowrap;
  border-bottom: 1px solid rgba(255,255,255,.04);
  font-variant-numeric: tabular-nums;
}
.admin-table tbody tr:last-child td { border-bottom: none; }
.admin-table-sm { font-size: 12px; margin-top: 8px; }
.row-click { cursor: pointer; }
.row-click:hover td { background: var(--fond-3); }

.admin-search { display: flex; gap: 8px; margin-bottom: 13px; }
.admin-search input { flex: 1; }

.admin-split { display: grid; gap: 15px; grid-template-columns: 1fr 380px; align-items: start; }
@media (max-width: 980px) { .admin-split { grid-template-columns: 1fr; } }

.admin-profile h3 { margin: 0 0 10px; }
.admin-profile h4 { margin: 16px 0 6px; font-size: 12px; color: var(--texte-2); text-transform: uppercase; letter-spacing: 1px; }
.profile-stats { display: flex; flex-direction: column; }
.profile-actions { display: flex; gap: 7px; margin-top: 14px; flex-wrap: wrap; }

.ip-list { margin-top: 14px; }
.ip-row {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 7px 0; border-bottom: 1px solid rgba(255,255,255,.05);
}
.ip-row code { font-size: 12px; color: var(--accent); }

.field-row { display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.field-row label { flex: 0 0 140px; margin: 0; font-size: 12px; text-transform: none; letter-spacing: 0; }
.field-row input { flex: 1; padding: 7px 9px; font-size: 13px; }

/* L entree Admin se distingue du reste du rail sans crier. */
.rail-admin { margin-top: auto; border-top: 1px solid var(--bordure); padding-top: 9px; border-radius: 0; }
.rail-admin:hover { color: var(--accent); }

/* ------------------------------------------------------------------ */
/* Chat live                                                           */
/* ------------------------------------------------------------------ */

.chat-panel {
  position: fixed; top: var(--hauteur-nav); right: 0; bottom: 0; width: 306px; z-index: 45;
  display: none; flex-direction: column;

  /*
   * PANNEAU TRANSLUCIDE : le decor de fond continue derriere.
   *
   * 38 % d'opacite : assez pour que les messages restent nets, assez peu pour
   * qu'on reconnaisse les motifs. Le flou est indispensable — sans lui, les
   * traits de l'image passeraient entre les lignes de texte.
   *
   * Le `backdrop-filter` ne fonctionne que parce que le calque de fond est
   * passe en `z-index: 0` : a -1 il etait DERRIERE le fond opaque du body, et
   * le flou ne captait que du noir uni.
   *
   * `color-mix` n'est pas universel : la ligne juste au-dessus sert de repli,
   * sinon le panneau serait totalement transparent et le texte illisible.
   */
  background: rgba(15, 19, 31, .72);
  background: color-mix(in srgb, var(--fond-2) 38%, transparent);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  border-left: 1px solid var(--bordure);
}
.chat-panel.open { display: flex; }

.chat-head {
  display: flex; align-items: center; gap: 9px;
  padding: 13px 14px; border-bottom: 1px solid var(--bordure);
}
.chat-title { font-size: 13px; font-weight: 800; }
.chat-online {
  margin-left: auto; display: flex; align-items: center; gap: 5px;
  font-size: 11px; color: var(--texte-2);
}
.dot-online {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--vert); box-shadow: 0 0 7px var(--vert);
}
.chat-close {
  background: none; border: none; color: var(--texte-2);
  font-size: 21px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.chat-close:hover { color: var(--texte); }

.chat-messages {
  flex: 1; overflow-y: auto; padding: 11px 12px;
  display: flex; flex-direction: column; gap: 9px;
}

.chat-msg { display: flex; flex-direction: column; gap: 2px; }
.chat-msg-head { display: flex; align-items: baseline; gap: 7px; }
.chat-user { font-size: 12px; font-weight: 800; color: var(--accent); }
.chat-user.chat-me { color: var(--vert); }
.chat-time { font-size: 10px; color: var(--texte-2); }
.chat-text {
  font-size: 13px; line-height: 1.42; color: var(--texte);
  word-break: break-word; overflow-wrap: anywhere;
}
.chat-sys .chat-text {
  color: var(--accent); font-size: 12px; font-style: italic;
  padding: 7px 9px; border-radius: 8px;
  background: rgba(255, 176, 58, .08);
}
.chat-flag {
  font-size: 10px; color: var(--rouge);
  padding: 3px 6px; border-radius: 5px;
  background: rgba(255, 85, 102, .1);
}

.chat-input-row {
  display: flex; gap: 6px; padding: 10px;
  border-top: 1px solid var(--bordure);
}
.chat-input-row input { flex: 1; padding: 9px 11px; font-size: 13px; }
.chat-send {
  width: 40px; border: none; border-radius: 9px; cursor: pointer;
  background: linear-gradient(135deg, var(--accent), var(--accent-fonce));
  color: #1a1206; font-size: 14px;
}

.chat-error {
  margin: 0; padding: 7px 12px; font-size: 11px;
  color: var(--rouge); background: rgba(255, 85, 102, .1);
}

.chat-toggle {
  position: fixed; right: 16px; bottom: 16px; z-index: 46;
  width: 46px; height: 46px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--bordure); background: var(--fond-3);
  font-size: 19px; box-shadow: 0 5px 16px rgba(0, 0, 0, .5);
}
.chat-toggle:hover { border-color: var(--accent); }

/* Le panneau est en position fixe : le contenu se decale pour ne pas passer
   dessous, comme pour le rail de gauche. */
body.chat-open { --decalage-chat: 306px; }
body.chat-open footer { padding-right: 306px; }
body.chat-open .chat-toggle { right: 322px; }

@media (max-width: 1180px) {
  .chat-panel { width: 100%; max-width: 340px; }
  /* Ecran etroit : le chat passe par-dessus plutot que de comprimer le jeu. */
  body.chat-open { --decalage-chat: 0px; }
  body.chat-open footer { padding-right: 24px; }
  body.chat-open .chat-toggle { right: 16px; }
}
@media (max-width: 880px) {
  .chat-panel { top: var(--hauteur-nav); bottom: 62px; }
  .chat-toggle { bottom: 74px; }
}

/* ------------------------------------------------------------------ */
/* Caisses                                                             */
/* ------------------------------------------------------------------ */

.case-grid {
  display: grid; gap: 14px; margin-top: 22px;
  grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
}
.case-card {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 24px 16px 18px; cursor: pointer;
  border-radius: var(--rayon); border: 1px solid var(--bordure);
  background: var(--fond-2); color: var(--texte);
  transition: transform .16s, border-color .16s, box-shadow .16s;
}
.case-card:hover {
  transform: translateY(-4px);
  border-color: var(--case-color, var(--accent));
  box-shadow: 0 12px 30px rgba(0, 0, 0, .45);
}
.case-icon {
  font-size: 54px; line-height: 1;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .55));
}
.case-name { font-size: 15px; font-weight: 800; }
.case-price {
  font-size: 14px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.case-top { font-size: 11px; color: var(--texte-2); }

.case-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.case-head-icon { font-size: 42px; line-height: 1; }

/* Fenetre de defilement : la bande glisse derriere, seul le centre compte. */
.reel-window {
  position: relative; overflow: hidden;
  height: 112px; border-radius: 12px;
  background: linear-gradient(180deg, #10151f, #0a0e15);
  border: 1px solid var(--bordure);
}
.reel-marker {
  position: absolute; top: 0; bottom: 0; left: 50%; width: 2px; z-index: 3;
  background: var(--vert); box-shadow: 0 0 14px var(--vert);
  transform: translateX(-1px);
}
/* Degrades lateraux : les objets entrent et sortent sans bord net. */
.reel-window::before, .reel-window::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 68px; z-index: 2;
  pointer-events: none;
}
.reel-window::before { left: 0; background: linear-gradient(90deg, #0a0e15, transparent); }
.reel-window::after { right: 0; background: linear-gradient(270deg, #0a0e15, transparent); }

.reel-strip { display: flex; height: 100%; will-change: transform; }
.reel-item {
  flex: 0 0 104px; height: 100%;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px;
  border-right: 1px solid rgba(255, 255, 255, .04);
}
.reel-icon { font-size: 34px; line-height: 1; }
.reel-value {
  font-size: 11px; font-weight: 700; color: var(--texte-2);
  font-variant-numeric: tabular-nums;
}

.case-actions { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.fast-spin { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--texte-2); }
.fast-spin input { width: auto; margin: 0; }

.case-result {
  display: flex; align-items: center; gap: 13px; flex-wrap: wrap;
  margin-top: 15px; padding: 15px 18px; border-radius: 12px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.cr-icon { font-size: 38px; line-height: 1; }
.cr-name { font-size: 16px; font-weight: 800; }
.cr-value {
  font-size: 18px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.cr-profit { margin-left: auto; font-size: 19px; font-weight: 800; }

.item-grid {
  display: grid; gap: 11px;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
}
.item-card {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 17px 12px; border-radius: 12px;
  background: var(--fond-2); border: 1px solid var(--bordure);
}
.item-icon { font-size: 38px; line-height: 1; }
.item-name { font-size: 13px; font-weight: 700; text-align: center; }
.item-value {
  font-size: 14px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.item-chance { font-size: 11px; color: var(--texte-2); }
.item-rarity {
  font-size: 9px; font-weight: 800; letter-spacing: .8px;
  padding: 2px 7px; border-radius: 100px; margin-top: 3px;
}

/* Rarete : la couleur est le langage universel des caisses. */
.rarity-common { --rar: #7b86a3; }
.rarity-rare { --rar: #4a9eff; }
.rarity-epic { --rar: #b464ff; }
.rarity-legendary { --rar: #ffb03a; }

.item-card.rarity-common { border-color: rgba(123, 134, 163, .35); }
.item-card.rarity-rare { border-color: rgba(74, 158, 255, .45); }
.item-card.rarity-epic { border-color: rgba(180, 100, 255, .45); }
.item-card.rarity-legendary { border-color: rgba(255, 176, 58, .55); }

.item-rarity.rarity-common { background: rgba(123, 134, 163, .2); color: #9aa6c4; }
.item-rarity.rarity-rare { background: rgba(74, 158, 255, .2); color: #6fb4ff; }
.item-rarity.rarity-epic { background: rgba(180, 100, 255, .2); color: #c68aff; }
.item-rarity.rarity-legendary { background: rgba(255, 176, 58, .22); color: var(--accent); }

.reel-item.rarity-rare { background: rgba(74, 158, 255, .07); }
.reel-item.rarity-epic { background: rgba(180, 100, 255, .09); }
.reel-item.rarity-legendary { background: rgba(255, 176, 58, .11); }

.case-result.rarity-legendary { border-color: rgba(255, 176, 58, .6); }
.case-result.rarity-epic { border-color: rgba(180, 100, 255, .5); }
.case-result.rarity-rare { border-color: rgba(74, 158, 255, .5); }

@media (prefers-reduced-motion: reduce) {
  .reel-strip { transition: none !important; }
}

/* ------------------------------------------------------------------ */
/* Recompenses                                                         */
/* ------------------------------------------------------------------ */

.bonus-grid {
  display: grid; gap: 13px; margin: 24px 0 20px;
  grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
}
.bonus-card {
  display: flex; flex-direction: column; gap: 8px;
  padding: 19px 17px; border-radius: var(--rayon);
  background: var(--fond-2); border: 1px solid var(--bordure);
}
/* Un bonus disponible doit sauter aux yeux : c'est la raison de la visite. */
.bonus-ready {
  border-color: rgba(255, 176, 58, .5);
  box-shadow: 0 0 0 1px rgba(255, 176, 58, .18), 0 8px 22px rgba(0, 0, 0, .35);
}
.bonus-label {
  font-size: 10px; font-weight: 800; letter-spacing: 1.3px;
  text-transform: uppercase; color: var(--texte-2);
}
/* Explication du calcul : le montant vient des mises, il faut que ca se
   voie sans avoir a le deviner. */
.bonus-source {
  font-size: 11px; line-height: 1.4; color: var(--texte-doux);
  margin-top: 2px;
}
.bonus-volume {
  font-size: 11px; font-weight: 700;
  color: var(--texte); opacity: .8;
  padding: 5px 8px; margin: 8px 0 2px;
  border-radius: 7px;
  background: var(--fond); border: 1px solid var(--bordure);
  font-variant-numeric: tabular-nums;
}

.bonus-amount {
  font-size: 25px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.rakeback-amount {
  font-size: 34px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums; margin-bottom: 4px;
}

/* Logo du hero : grande version, avec une respiration flottante discrete. */
.hero-logo {
  display: block; width: 128px; height: 128px; margin: 0 auto 18px;
  filter: drop-shadow(0 14px 34px rgba(255, 143, 46, .3));
  animation: logo-float 5s ease-in-out infinite;
}
@keyframes logo-float {
  0%, 100% { transform: translateY(0) rotate(-2deg); }
  50%      { transform: translateY(-11px) rotate(2deg); }
}
@media (prefers-reduced-motion: reduce) { .hero-logo { animation: none; } }
@media (max-width: 560px) { .hero-logo { width: 92px; height: 92px; } }

/* Sprites d objets : rendu pixel, jamais lisse. */
.sprite { display: block; image-rendering: pixelated; }
/*
 * Les coffres sont des SVG DESSINES, plus des textures 16x16.
 * `image-rendering: pixelated` herite de .sprite crenelerait leurs
 * diagonales : on revient au rendu lisse pour eux seulement. Les sprites
 * d'objets, eux, restent pixelises — ce sont de vraies textures Minecraft.
 */
.sprite-case {
  filter: drop-shadow(0 5px 12px rgba(0, 0, 0, .5));
  image-rendering: auto;
}
.case-icon, .item-icon, .reel-icon, .cr-icon, .case-head-icon {
  display: flex; align-items: center; justify-content: center;
}
.case-rtp {
  font-size: 10px; font-weight: 700; color: var(--vert);
  padding: 2px 8px; border-radius: 100px;
  background: rgba(53, 217, 138, .12);
}

/* Case a cocher alignee (se souvenir de moi, options). */
.checkbox-row {
  display: flex; align-items: center; gap: 8px;
  margin: 10px 0 0; font-size: 12.5px; color: var(--texte-2);
  text-transform: none; letter-spacing: 0; font-weight: 500;
  cursor: pointer;
}
.checkbox-row input { width: auto; margin: 0; cursor: pointer; }

/* ------------------------------------------------------------------ */
/* Des 3D — deux cubes qui roulent                                     */
/* ------------------------------------------------------------------ */

/*
 * Un vrai cube : six faces tournees puis poussees vers l'exterieur par
 * translateZ. On voit donc les aretes et les faces laterales pendant la
 * roulade, contrairement a un carre plat qui changerait juste de chiffre.
 *
 * ATTENTION : les rotations ci-dessous doivent correspondre exactement a
 * `POSES` dans des.js. Ce fichier definit ou chaque face est posee, des.js en
 * derive la rotation a appliquer pour l'amener devant. Changer l'un sans
 * l'autre fait afficher une face differente du resultat serveur.
 */

.dice-table {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(18px, 6vw, 46px);
  min-height: 190px;
  perspective: 1000px;
  perspective-origin: 50% 45%;
}

.die-scene {
  position: relative;
  width: var(--die-size, 72px);
  height: calc(var(--die-size, 72px) + 42px);
  display: grid; place-items: center;
  transform-style: preserve-3d;
}

.die-shadow {
  position: absolute; left: 50%; bottom: 6px;
  width: 78%; height: 14px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .5);
  filter: blur(7px);
  transform: translateX(-50%) scale(1);
  opacity: .55;
  pointer-events: none;
  transition: transform 160ms ease-out, opacity 160ms ease-out;
}

.die {
  position: relative;
  width: var(--die-size, 72px);
  height: var(--die-size, 72px);
  transform-style: preserve-3d;
  will-change: transform;
}

.die-face {
  position: absolute; inset: 0;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  padding: 13%;
  box-sizing: border-box;
  border-radius: 13%;
  background: linear-gradient(145deg, #fdfdfd 0%, #eceff5 55%, #d2d7e2 100%);
  border: 1px solid #b6bcc9;
  box-shadow:
    inset 0 2px 4px rgba(255, 255, 255, .95),
    inset 0 -3px 6px rgba(120, 128, 145, .45);
  backface-visibility: visible;
}

/* Poses des six faces. Miroir de POSES dans des.js. */
.die-front  { transform: translateZ(calc(var(--die-size, 72px) / 2)); }
.die-back   { transform: rotateY(180deg) translateZ(calc(var(--die-size, 72px) / 2)); }
.die-right  { transform: rotateY(90deg)  translateZ(calc(var(--die-size, 72px) / 2)); }
.die-left   { transform: rotateY(-90deg) translateZ(calc(var(--die-size, 72px) / 2)); }
.die-top    { transform: rotateX(90deg)  translateZ(calc(var(--die-size, 72px) / 2)); }
.die-bottom { transform: rotateX(-90deg) translateZ(calc(var(--die-size, 72px) / 2)); }

/* Les points : pastilles creusees dans la face. */
.pip {
  align-self: center; justify-self: center;
  width: 74%; aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #4a5163 0%, #1d2130 70%, #12151f 100%);
  box-shadow:
    inset 1px 1px 2px rgba(0, 0, 0, .8),
    0 1px 0 rgba(255, 255, 255, .7);
}

/* Halo de resultat, pose par dice.js. */
.die.win { box-shadow: 0 0 18px rgba(53, 217, 138, .6); border-radius: 13%; }
.die.lose { box-shadow: 0 0 18px rgba(255, 85, 102, .5); border-radius: 13%; }

@media (max-width: 560px) { .dice-table { --die-size: 58px; } }
@media (prefers-reduced-motion: reduce) {
  .die, .die-shadow { transition: none !important; animation: none !important; }
}

/* Grille des sommes : la cote de chaque nombre est affichee dessous, pour
   que le joueur voie que le 7 sort six fois plus que le 2. */
.sum-grid {
  display: grid; grid-template-columns: repeat(6, 1fr);
  gap: 5px; margin-top: 8px;
}
.sum-cell {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 7px 2px; border-radius: 8px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  color: var(--texte-2);
  transition: border-color .15s, transform .12s, background .15s;
}
.sum-value { font-size: 14px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sum-odds { font-size: 9px; opacity: .7; }
.sum-cell:hover:not(.sum-dead) { border-color: var(--accent); transform: translateY(-2px); }
.sum-cell.active {
  border-color: var(--accent); background: var(--fond-4); color: var(--texte);
  box-shadow: 0 0 0 1px rgba(255, 176, 58, .4);
}
/* Somme injouable pour le type de pari courant. */
.sum-dead { opacity: .38; cursor: not-allowed; }
.sum-dead:active { transform: none; }

/* ------------------------------------------------------------------ */
/* Titre de resultat — commun aux jeux                                 */
/* ------------------------------------------------------------------ */

/* Volontairement modeste : le chiffre du gain porte l information, le titre
   ne fait que donner le verdict d un coup d oeil. */
.result-title {
  min-height: 26px;
  font-size: 21px; font-weight: 900; letter-spacing: 2px;
  margin-bottom: 2px;
}
.title-win { color: var(--vert); }
.title-lose { color: var(--rouge); }

/* ------------------------------------------------------------------ */
/* Mines — echelle des gains et grille revelee                         */
/* ------------------------------------------------------------------ */


/* Case piochee mais jamais ouverte : la manche s est arretee avant. */
.mine-tile.tile-unopened {
  border-style: dashed;
  border-color: rgba(255, 255, 255, .16);
  opacity: .55;
}

/* ------------------------------------------------------------------ */
/* Admin — pourcentages, bots, journaux                                */
/* ------------------------------------------------------------------ */

/* Un house edge se regle au dixieme de point : les boutons evitent de
   retaper le champ pour un ajustement fin. */
.pct-group { display: flex; align-items: center; gap: 4px; flex: 1; }
.pct-btn {
  width: 28px; height: 28px; flex: none;
  border-radius: 7px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  color: var(--texte); font-size: 15px; font-weight: 700; line-height: 1;
}
.pct-btn:hover { border-color: var(--accent); }
.pct-input {
  width: 70px; flex: none; text-align: center;
  font-variant-numeric: tabular-nums; font-weight: 700;
}
.pct-unit { font-size: 12px; color: var(--texte-2); }

.bot-add { display: flex; gap: 8px; margin-top: 14px; }
.bot-add input { flex: 1; }

.log-controls { display: flex; gap: 7px; margin-bottom: 8px; flex-wrap: wrap; }
.log-controls select { width: auto; padding: 6px 9px; font-size: 12px; }

.log-output {
  max-height: 420px; overflow-y: auto;
  border-radius: var(--rayon);
  background: #070a10; border: 1px solid var(--bordure);
  padding: 9px 11px;
  font-family: 'JetBrains Mono', Consolas, monospace; font-size: 11.5px;
}
.log-line {
  display: grid; grid-template-columns: 92px 64px 54px 1fr;
  gap: 9px; padding: 2px 0;
  border-bottom: 1px solid rgba(255, 255, 255, .03);
}
.log-time { color: #4c5568; }
.log-profile { color: var(--texte-2); }
.log-type { font-weight: 700; }
.log-text { word-break: break-word; color: var(--texte); }

/* Les evenements rares doivent sauter aux yeux dans le flot du chat. */
.log-chat .log-type { color: #4c5568; }
.log-connect .log-type { color: var(--vert); }
.log-disconnect .log-type { color: #b8863a; }
.log-kick .log-type { color: #ff9f43; }
.log-ban .log-type { color: var(--rouge); }
.log-ban { background: rgba(255, 85, 102, .07); }
.log-switch .log-type { color: var(--accent); }
.log-switch { background: rgba(255, 176, 58, .06); }

/* ------------------------------------------------------------------ */
/* Curseur (vitesse, rangees)                                          */
/* ------------------------------------------------------------------ */

.slider {
  width: 100%; height: 6px; margin: 10px 0 4px;
  -webkit-appearance: none; appearance: none;
  border-radius: 100px; cursor: pointer;
  background: linear-gradient(90deg, var(--accent) 0%, var(--fond-4) 0%);
  background: var(--fond-4);
  border: 1px solid var(--bordure);
}
.slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 17px; height: 17px; border-radius: 50%; cursor: pointer;
  background: linear-gradient(135deg, var(--accent), var(--accent-fonce));
  border: 2px solid var(--fond);
  box-shadow: 0 2px 7px rgba(0, 0, 0, .5);
}
.slider::-moz-range-thumb {
  width: 15px; height: 15px; border-radius: 50%; cursor: pointer;
  background: var(--accent);
  border: 2px solid var(--fond);
}
.slider:disabled { opacity: .45; cursor: not-allowed; }

/* La bille roule : la rotation est posee en JS, on ne la transitionne pas. */
.plinko-ball { transition: none; }

/* ------------------------------------------------------------------ */
/* Limbo                                                              */
/* ------------------------------------------------------------------ */

.limbo-label {
  font-size: 10px; font-weight: 800; letter-spacing: 2px;
  text-transform: uppercase; color: var(--texte-2);
}
.limbo-value {
  font-size: clamp(52px, 13vw, 86px); font-weight: 900;
  letter-spacing: -3px; line-height: 1.05;
  font-variant-numeric: tabular-nums;
  /* Chiffres a largeur fixe : sans ca le nombre tremble pendant le defilement. */
  font-feature-settings: 'tnum';
  color: var(--texte);
  margin: 4px 0 14px;
}
.limbo-verdict {
  padding: 10px 18px; border-radius: 11px;
  font-size: 13px; font-weight: 700;
}
.verdict-win { background: rgba(53, 217, 138, .14); color: var(--vert); }
.verdict-lose { background: rgba(255, 85, 102, .13); color: var(--rouge); }

.target-row { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.target-row input {
  flex: 1; text-align: center; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ */
/* Roulette russe — barillet                                           */
/* ------------------------------------------------------------------ */

.revolver-stage {
  position: relative;
  width: 100%; max-width: 330px;
  margin: 0 auto 4px;
}
.barillet-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* Les balles n'apparaissent qu'au chargement et a la revelation finale :
   pendant la partie, leur position est secrete. */
.b-balle {
  opacity: 0;
  transition: opacity .26s;
  transition-delay: var(--retard, 0ms);
}
.b-pleine .b-balle { opacity: 1; }

/* Etats de REVELATION, poses seulement en fin de partie. */
.b-ch-bord { transition: stroke .25s, stroke-width .25s; }
/* La COULEUR dit le contenu : rouge = balle, vert = vide. */
.b-vue-pleine .b-ch-bord { stroke: #ff5566; stroke-width: 4; }
.b-vue-vide   .b-ch-bord { stroke: #35d98a; }

/*
 * Chambre passee sous le percuteur : trait plus epais, rien d'autre.
 *
 * Il y avait un halo orange en drop-shadow. Retire : l'ambre est la couleur
 * d'accent du site, elle ne veut rien dire sur un barillet, et elle bavait
 * sur les cercles verts voisins au point de faire croire a un troisieme
 * etat. La couleur dit le CONTENU (rouge = balle, vert = vide), l'epaisseur
 * dit le PASSAGE. Deux canaux, deux lectures, zero halo.
 */
.b-vue-tiree .b-ch-bord {
  stroke-width: 6;
}

/* Percuteur arme : il recule avant de tomber. */
#bPercuteur {
  transition: transform .2s cubic-bezier(.3, .9, .2, 1);
  transform-origin: 150px 150px;
}
#bPercuteur.b-arme { transform: translateY(-9px); }

/* Claquement de mise en place. */
@keyframes bVerrou {
  0%   { transform: translateX(-10px) rotate(-4deg); }
  55%  { transform: translateX(3px)   rotate(1.5deg); }
  100% { transform: translateX(0)     rotate(0); }
}

/* Depart de coup : secousse vers le bas, comme un vrai recul. */
@keyframes bRecul {
  0%   { transform: translate(0, 0) rotate(0); }
  12%  { transform: translate(0, 13px) scale(1.035) rotate(-2deg); }
  38%  { transform: translate(0, 5px)  scale(1.015) rotate(.8deg); }
  100% { transform: translate(0, 0) rotate(0); }
}

/* Percussion a vide : un sursaut, pas un recul. La difference doit se
   sentir sans lire le texte. */
@keyframes bClic {
  0%   { transform: translate(0, 0); }
  34%  { transform: translate(0, 4px); }
  100% { transform: translate(0, 0); }
}

/*
 * DEPART DU COUP. Trois animations qui partent ensemble.
 *
 * Toutes tournent autour du percuteur (150px, 58px) et pas du centre du SVG :
 * un `transform-origin` par defaut ferait grossir l'explosion depuis le
 * milieu du barillet, donc a cote de l'endroit ou le coup part.
 */
#bFlash, #bOnde, #bEclats, #bVide { transform-origin: 150px 58px; }

@keyframes bFlash {
  0%   { opacity: 0;   transform: scale(.25); }
  9%   { opacity: 1;   transform: scale(1.15); }
  40%  { opacity: .72; transform: scale(1.5); }
  100% { opacity: 0;   transform: scale(2.05); }
}

/* Onde de choc : un anneau qui s'ecarte et s'efface. C'est elle qui donne
   l'echelle de l'explosion, la boule de feu seule paraissait plate. */
@keyframes bOnde {
  0%   { opacity: .9; transform: scale(.3); stroke-width: 8; }
  100% { opacity: 0;  transform: scale(2.4); stroke-width: 1; }
}

/* Eclats projetes vers l'exterieur. Ils partent plus vite que l'onde et
   s'eteignent avant elle : c'est ce decalage qui fait lire "projection". */
@keyframes bEclats {
  0%   { opacity: 0;   transform: scale(.4); }
  18%  { opacity: 1;   transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.7); }
}

/*
 * PERCUSSION A VIDE. Meme geste que le depart de coup — un anneau qui
 * s'ecarte — mais gris, deux fois plus petit et deux fois plus court. Le
 * joueur voit qu'il s'est passe quelque chose, sans jamais confondre avec un
 * vrai tir.
 */
@keyframes bVide {
  0%   { opacity: 0;   transform: scale(.5); }
  22%  { opacity: .85; transform: scale(1); }
  100% { opacity: 0;   transform: scale(1.55); }
}

@keyframes bFumee {
  0%   { opacity: 0;   transform: translateY(0) scale(.55); }
  20%  { opacity: .8;  transform: translateY(-14px) scale(1); }
  100% { opacity: 0;   transform: translateY(-58px) scale(1.8); }
}

/* ---------------- BANDEAU ET DECISIONS ---------------- */

.rv-bandeau {
  display: flex; gap: 8px; justify-content: center; flex-wrap: wrap;
  margin: 4px 0 12px;
}
.rv-jeton {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  min-width: 74px; padding: 7px 12px; border-radius: 10px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.rv-jeton-valeur {
  font-size: 15px; font-weight: 800; color: var(--texte);
  font-variant-numeric: tabular-nums;
}
.rv-jeton-etiquette {
  font-size: 9px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--texte-doux);
}
.rv-jeton.chaud { border-color: var(--accent); }
.rv-jeton.chaud .rv-jeton-valeur { color: var(--accent); }

/* Encaisser doit etre aussi atteignable que tirer, jamais releguee. */
.rv-decision { display: flex; gap: 9px; margin-top: 6px; }
.rv-decision .btn { flex: 1; }

.rv-tirs { display: flex; gap: 5px; justify-content: center; flex-wrap: wrap; margin-top: 11px; }
.rv-tir {
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 800;
  background: rgba(53, 217, 138, .13);
  border: 1px solid rgba(53, 217, 138, .5); color: #35d98a;
}
.rv-tir.mortel {
  background: rgba(255, 85, 102, .15);
  border-color: rgba(255, 85, 102, .6); color: var(--rouge);
}

@media (max-width: 560px) {
  .revolver-stage { max-width: 260px; }
}

@media (prefers-reduced-motion: reduce) {
  .barillet-svg *, #bBarillet {
    animation: none !important; transition: none !important;
  }
}

/* ------------------------------------------------------------------ */
/* Duel                                                                */
/* ------------------------------------------------------------------ */

.invite-list { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
.invite-card {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  padding: 13px 16px; border-radius: var(--rayon);
  background: rgba(255, 176, 58, .1);
  border: 1px solid rgba(255, 176, 58, .45);
  font-size: 13.5px;
}

.queue-list { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.queue-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 13px; border-radius: 10px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.queue-bet { font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }

.duel-head {
  display: grid; grid-template-columns: 1fr auto 1fr;
  gap: 14px; align-items: center; margin-top: 22px;
  padding: 16px 20px; border-radius: var(--rayon);
  background: var(--fond-2); border: 1px solid var(--bordure);
}
.duel-side { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.duel-name { font-size: 13px; font-weight: 700; }
.duel-score {
  font-size: 30px; font-weight: 900; color: var(--accent);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.duel-mid { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.duel-game {
  font-size: 10px; font-weight: 800; letter-spacing: 1.2px;
  text-transform: uppercase; color: var(--texte-2); text-align: center;
}
.duel-pot { font-size: 12px; color: var(--vert); font-weight: 700; }

.duel-timer {
  font-size: 15px; font-weight: 800; color: var(--texte-2);
  font-variant-numeric: tabular-nums;
}
/* Les dix dernieres secondes : le joueur doit sentir l'urgence. */
.duel-timer-urgent { color: var(--rouge); animation: pulse-timer .6s ease-in-out infinite; }
@keyframes pulse-timer { 50% { opacity: .45; } }

.duel-board { min-height: 96px; display: grid; place-items: center; }
.duel-versus { display: flex; align-items: center; gap: 26px; }
.duel-slot {
  display: grid; place-items: center; gap: 6px;
  min-width: 92px; min-height: 84px;
  padding: 12px 16px; border-radius: 13px;
  background: var(--fond-3); border: 1px solid var(--bordure);
  font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.duel-bust { border-color: rgba(255, 85, 102, .5); color: var(--rouge); }
.duel-flip { font-size: 34px; font-weight: 900; letter-spacing: 2px; color: var(--accent); }

.duel-actions { display: flex; gap: 9px; margin-top: 16px; flex-wrap: wrap; justify-content: center; }
.duel-btn {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  min-width: 104px; padding: 12px 14px; font-size: 12px;
}

@media (max-width: 560px) {
  .duel-versus { gap: 12px; }
  .duel-slot { min-width: 74px; padding: 10px; font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  .duel-timer-urgent { animation: none; }
}

/* ------------------------------------------------------------------ */
/* Paiements en attente                                                */
/* ------------------------------------------------------------------ */

/* Cote joueur : bandeau d'information, pas d'alarme. L'argent n'est pas
   perdu, il est en route — le ton doit le dire. */
.payout-attente {
  display: flex; flex-direction: column; gap: 4px;
  padding: 11px 13px; margin-bottom: 14px;
  border-radius: 10px;
  background: rgba(255, 176, 58, .08);
  border: 1px solid rgba(255, 176, 58, .35);
}
.payout-attente-titre {
  font-size: 12px; font-weight: 800; letter-spacing: .3px;
  text-transform: uppercase; color: var(--accent);
}
.payout-attente-texte { font-size: 12px; line-height: 1.45; color: var(--texte-doux); }

/* Cote admin : le total du a payer, et le bouton qui lance la file. */
.payout-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 14px 16px; border-radius: var(--rayon);
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.payout-somme { display: flex; flex-direction: column; gap: 2px; }
.payout-etiquette {
  font-size: 10px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--texte-doux);
}
.payout-total {
  font-size: 24px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Pastille de l'onglet : le nombre de joueurs en attente doit se voir sans
   ouvrir l'onglet. */
.tab-pastille {
  display: inline-grid; place-items: center;
  min-width: 17px; height: 17px; padding: 0 5px; margin-left: 5px;
  border-radius: 100px;
  background: var(--accent); color: #1a1200;
  font-size: 10px; font-weight: 800; line-height: 1;
}

/* ------------------------------------------------------------------ */
/* Barre de menu horizontale                                           */
/* ------------------------------------------------------------------ */

/*
 * Porte ce qui n'est PAS un jeu : equite, promotions, recompenses,
 * classement, profil, boutique. Le rail de gauche reste aux jeux, donc
 * chaque zone a un role lisible.
 *
 * Posee en fixe sous l'entete plutot que dans le flux : l'entete est
 * generee par partiels.js, et inserer la barre dedans obligerait a
 * toucher les 15 pages.
 */
.top-menu {
  position: fixed; left: 0; right: 0; top: var(--hauteur-topbar);
  z-index: 41;
  display: flex; align-items: center; gap: 2px;
  padding: 0 16px;
  background: var(--fond-2);
  border-bottom: 1px solid var(--bordure);
  /* Defilement horizontal en dernier recours sur petit ecran, sans barre
     visible : mieux qu'un menu tronque. */
  overflow-x: auto; scrollbar-width: none;
}
.top-menu::-webkit-scrollbar { display: none; }

.menu-item {
  display: flex; align-items: center; gap: 7px;
  flex: 0 0 auto;
  padding: 12px 13px;
  color: var(--texte-doux); text-decoration: none;
  font-size: 12.5px; font-weight: 700; letter-spacing: .2px;
  text-transform: uppercase;
  border-bottom: 2px solid transparent;
  transition: color .15s, border-color .15s;
  white-space: nowrap;
}
.menu-item:hover { color: var(--texte); }
.menu-item.active { color: var(--accent); border-bottom-color: var(--accent); }

/* Les deux entrees promotionnelles sont ambre en permanence : ce sont
   elles qui doivent attirer l'oeil. */
.menu-chaud { color: var(--accent); }
.menu-chaud:hover { color: var(--accent-fonce); }

.menu-soon { cursor: default; opacity: .5; }
.menu-soon em {
  font-style: normal; font-size: 9px; font-weight: 800;
  padding: 2px 5px; border-radius: 100px;
  background: var(--fond-4); color: var(--texte-doux);
}

.top-menu .ds-icone { flex: 0 0 auto; }

/* Le contenu des pages commence sous les DEUX barres. */
body.has-menu main { padding-top: var(--hauteur-menu); }

@media (max-width: 900px) {
  .menu-item { padding: 11px 10px; font-size: 11.5px; gap: 5px; }
  .menu-item span { display: none; }
  /* Sur petit ecran on garde les libelles des entrees promotionnelles :
     ce sont les seules dont l'icone ne suffit pas a deviner le contenu. */
  .menu-chaud span { display: inline; }
}

/* ------------------------------------------------------------------ */
/* Provably Fair                                                       */
/* ------------------------------------------------------------------ */

.fair-hero {
  margin-top: 26px; padding: 22px 24px;
  border-radius: var(--rayon);
  background:
    radial-gradient(ellipse at 8% 0%, rgba(255, 176, 58, .13) 0%, transparent 58%),
    var(--fond-2);
  border: 1px solid var(--bordure);
}
.fair-kicker {
  font-size: 10px; font-weight: 800; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--accent);
}
.fair-hero h1 { margin: 6px 0 6px; font-size: 27px; }
.fair-hero p { margin: 0; max-width: 60ch; }

.fair-badges { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.fair-badge {
  display: flex; flex-direction: column; gap: 2px;
  padding: 9px 14px; border-radius: 10px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.fair-badge span {
  font-size: 9.5px; font-weight: 700; letter-spacing: .5px;
  text-transform: uppercase; color: var(--texte-doux);
}
.fair-badge strong { font-size: 13px; }

/* Les quatre etapes : numerotees, parce que l'ordre EST l'explication. */
.fair-steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 12px; margin: 12px 0 0; padding: 0; list-style: none;
  counter-reset: etape;
}
.fair-steps li {
  counter-increment: etape;
  position: relative;
  padding: 13px 14px 13px 42px;
  border-radius: 11px;
  background: var(--fond-3); border: 1px solid var(--bordure);
  font-size: 12px; line-height: 1.5; color: var(--texte-doux);
}
.fair-steps li::before {
  content: counter(etape);
  position: absolute; left: 13px; top: 13px;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent); color: #1a1200;
  font-size: 11px; font-weight: 800;
}
.fair-steps strong { display: block; color: var(--texte); margin-bottom: 3px; font-size: 12.5px; }
.fair-steps em { font-style: normal; color: var(--accent); }

.fair-row { display: flex; gap: 10px; margin-top: 12px; }
.fair-row > div { flex: 1; }

/* Les valeurs tirees, en chiffres tabulaires pour qu'elles s'alignent. */
.fair-values { display: flex; flex-direction: column; gap: 5px; margin-top: 8px; }
.fair-value {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 7px 11px; border-radius: 8px;
  background: var(--fond); border: 1px solid var(--bordure);
  font-variant-numeric: tabular-nums;
}
.fair-value-i { font-size: 10px; color: var(--texte-doux); font-weight: 700; }

/* Les seeds sont des chaines a comparer caractere par caractere : une
   police a chasse fixe est la seule qui rende ca praticable. */
.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px; word-break: break-all;
}

/* ------------------------------------------------------------------ */
/* Profil et classement                                                */
/* ------------------------------------------------------------------ */

/* Vert / rouge sur le net : c'est la seule ligne qu'on lit en diagonale. */
.kpi-win .kpi-value  { color: var(--vert); }
.kpi-lose .kpi-value { color: var(--rouge); }
.cell-win  { color: var(--vert); font-weight: 700; }
.cell-lose { color: var(--rouge); font-weight: 700; }

/* Sa propre ligne, dans une liste de cinquante. */
.lb-moi { background: rgba(255, 176, 58, .09); }
.lb-moi td { color: var(--texte); font-weight: 700; }

.lb-medaille {
  display: inline-grid; place-items: center;
  width: 22px; height: 22px; border-radius: 50%;
  font-size: 11px; font-weight: 800; color: #1a1200;
}
.lb-1 { background: linear-gradient(160deg, #ffd873, #d9a233); }
.lb-2 { background: linear-gradient(160deg, #d8dde8, #9aa3b5); }
.lb-3 { background: linear-gradient(160deg, #e0a172, #a86f3c); }

/*
 * Champ obligatoire non renseigne : un pulse rouge bref.
 *
 * Le message d'erreur seul se rate — le joueur regarde le bouton sur lequel
 * il vient de cliquer, pas le texte. Le pulse designe l'endroit ou agir.
 */
@keyframes champManquant {
  0%   { box-shadow: 0 0 0 0 rgba(255, 85, 102, .55); }
  70%  { box-shadow: 0 0 0 7px rgba(255, 85, 102, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 85, 102, 0); }
}
.champ-manquant {
  border-radius: 11px;
  animation: champManquant .9s ease-out 2;
}

/* Cartes de classement du profil. Trois colonnes, une par palmares. */
.rank-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.rank-card {
  display: flex; flex-direction: column; gap: 3px;
  padding: 16px; border-radius: 12px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.rank-label { color: var(--texte-doux); font-size: 12.5px; text-transform: uppercase; letter-spacing: .4px; }
.rank-position { font-size: 26px; font-weight: 800; line-height: 1.1; }
.rank-detail { color: var(--texte-doux); font-size: 12.5px; }

/* Or pour la premiere place, ambre pour le podium : le rang se lit d'un coup
   d'oeil sans avoir a comparer les chiffres. */
.rank-card.rank-1 { border-color: #ffd873; }
.rank-card.rank-1 .rank-position { color: #ffd873; }
.rank-card.rank-3 { border-color: rgba(255, 176, 58, .45); }
.rank-card.rank-3 .rank-position { color: var(--accent); }

/* Champ "invited by" de l'inscription : separe du reste par un trait, pour
   qu'on voie que c'est optionnel et pas une etape de plus a franchir. */
.referrer-box {
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--bordure);
}
.referrer-box label { display: block; margin-bottom: 6px; font-size: 13.5px; }
.muted.small.error { color: var(--rouge); }

/* Case a cocher alignee avec son libelle, dans les reglages admin. */
.check-row {
  display: flex; align-items: center; gap: 9px;
  margin: 10px 0; font-size: 13.5px; cursor: pointer;
}
.check-row input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }

/* Code Microsoft — autorisation d'un compte bot */
.ms-code {
  margin: 14px 0 4px; padding: 14px 16px;
  border: 1px solid var(--accent); border-radius: 12px;
  background: rgba(255, 176, 58, .07);
}
.ms-code-title { font-weight: 700; margin-bottom: 2px; }
.ms-code-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Le code se lit CARACTERE PAR CARACTERE pour etre recopie sans erreur :
   chasse fixe, gros, et espace entre les lettres. */
.ms-code-value {
  font-size: 20px; font-weight: 800; letter-spacing: 3px;
  padding: 6px 12px; border-radius: 8px;
  background: var(--fond-1, #0b0e14); border: 1px solid var(--bordure);
  user-select: all;
}

/* ------------------------------------------------------------------ */
/* Classement — podium et trois colonnes                               */
/* ------------------------------------------------------------------ */

/*
 * PODIUM. L'ordre du DOM est 2 / 1 / 3 (l'ordre visuel), pas 1 / 2 / 3 :
 * reordonner en CSS seul laisserait la lecture au clavier dans un ordre qui
 * ne correspond a rien de visible.
 */
.podium {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: 10px;
  max-width: 680px;
  margin: 26px auto 4px;
}

.podium-place { display: flex; flex-direction: column; align-items: center; min-width: 0; }

/* La couronne flotte au-dessus du premier, sans pousser les autres : elle est
   en position absolue dans un conteneur de hauteur nulle. */
.podium-crown { font-size: 22px; line-height: 1; margin-bottom: 4px; }

.podium-head {
  width: 76px; height: 76px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--fond-3);
  border: 2px solid var(--bordure);
  display: grid; place-items: center;
}
/*
 * image-rendering: pixelated — une tete de skin fait 8x8 pixels a l'origine.
 * Sans ca, le navigateur la lisse et elle devient une bouillie floue au lieu
 * d'un visage Minecraft net.
 */
.podium-head img { width: 100%; height: 100%; display: block; image-rendering: pixelated; }

.podium-name {
  margin-top: 8px; font-weight: 700; font-size: 13.5px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.podium-value { color: var(--accent); font-weight: 800; font-size: 14px; margin-top: 2px; }

/* La marche. Sa HAUTEUR porte le classement : premier le plus haut. */
.podium-step {
  width: 100%; margin-top: 10px;
  border-radius: 10px 10px 0 0;
  display: grid; place-items: center;
  font-size: 20px; font-weight: 900; color: #1a1200;
  border: 1px solid var(--bordure); border-bottom: none;
}
.podium-1 .podium-step { height: 92px; background: linear-gradient(160deg, #ffd873, #d9a233); }
.podium-2 .podium-step { height: 66px; background: linear-gradient(160deg, #d8dde8, #9aa3b5); }
.podium-3 .podium-step { height: 50px; background: linear-gradient(160deg, #e0a172, #a86f3c); }

.podium-1 .podium-head { border-color: #ffd873; width: 92px; height: 92px; }
.podium-2 .podium-head { border-color: #d8dde8; }
.podium-3 .podium-head { border-color: #e0a172; }

/* Sa propre place est signalee : dans un podium, on se cherche d'abord. */
.podium-moi .podium-name { color: var(--accent); }
.podium-moi .podium-head { box-shadow: 0 0 0 3px rgba(255, 176, 58, .35); }

/*
 * TROIS COLONNES, puis une seule sous 1000px. Trois tableaux serres sur un
 * telephone deviennent illisibles bien avant d'etre etroits.
 */
/*
 * PLEINE LARGEUR. Trois tableaux dans le gabarit standard de 1140 px, ca fait
 * 350 px par colonne : la colonne "Player" etait rognee et chaque tableau
 * defilait horizontalement pour lui-meme. Le classement devient illisible
 * exactement la ou il devrait etre le plus lisible.
 *
 * Cette page sort donc du gabarit. Le chat reste pris en compte : la bordure
 * transparente heritee de `main` reserve sa colonne, donc rien ne passe
 * dessous quand il s'ouvre.
 */
main.main-large { max-width: 1720px; }

.lb-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin-top: 18px;
  align-items: start;
}

/* Les tableaux remplissent leur colonne : sans `width: 100%`, un tableau se
   reduit a son contenu et les entetes flottent au-dessus du vide. */
.lb-col table { width: 100%; }
.lb-col .table-wrap { overflow-x: visible; }

/* Le pseudo prend la place restante, les montants ne se coupent jamais. */
.lb-col th:first-child, .lb-col td:first-child { width: 44px; }
.lb-col .lb-joueur { width: 100%; }
.lb-col td:not(:first-child):not(:nth-child(2)) { white-space: nowrap; text-align: right; }
.lb-col th:not(:first-child):not(:nth-child(2)) { text-align: right; }

/* Sous 1500 px les trois colonnes deviennent trop etroites : on passe a deux,
   puis a une. Mieux vaut faire defiler que de rendre illisible. */
@media (max-width: 1500px) {
  .lb-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.lb-col { min-width: 0; }
.lb-titre { margin: 0; font-size: 16px; }
.lb-sous { margin: 2px 0 10px; }

@media (max-width: 980px) {
  .lb-grid { grid-template-columns: 1fr; }
}

/* Tete de skin dans les lignes : elle sert a reconnaitre, pas a decorer. */
.lb-joueur { display: flex; align-items: center; gap: 7px; min-width: 0; }
.lb-joueur span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-tete { border-radius: 5px; image-rendering: pixelated; flex: 0 0 auto; }

/* Joueur masque : une case neutre a la place de la tete. Charger le vrai skin
   revelerait le pseudo complet par l'URL de l'image. */
.lb-tete-vide {
  display: inline-block; width: 22px; height: 22px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}

/* La mise de depart et son multiplicateur vivent dans la meme cellule : un
   profit ne se lit pas sans savoir de quelle mise il vient. */
.lb-mise { white-space: nowrap; }
.lb-mult {
  display: inline-block; margin-left: 5px; padding: 1px 5px;
  border-radius: 5px; font-size: 11px; font-weight: 700;
  color: var(--accent); background: rgba(255, 176, 58, .12);
}
.lb-gain  { color: var(--vert); font-weight: 700; white-space: nowrap; }
.lb-perte { color: var(--rouge); font-weight: 700; white-space: nowrap; }

/* ------------------------------------------------------------------ */
/* Machines a sous                                                     */
/* ------------------------------------------------------------------ */

/* Choix de la machine : cinq vignettes, chacune dans son theme. */
.machine-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px; margin-top: 18px;
}
.machine-card {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 13px 10px; border-radius: 13px; cursor: pointer;
  background: var(--fond-3); border: 1px solid var(--bordure);
  font-family: inherit;
  transition: border-color .15s, transform .12s, background .15s;
}
.machine-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.machine-card.active { border-color: var(--accent); background: rgba(255,176,58,.09); }

.machine-vignette {
  display: grid; place-items: center;
  width: 54px; height: 54px; border-radius: 12px;
}
/* Chaque theme a son fond : c'est ce qui distingue les machines d'un coup
   d'oeil, avant meme de lire leur nom. */
.machine-fruits    { background: linear-gradient(150deg, #7b1e2b, #3a0d14); }
.machine-money     { background: linear-gradient(150deg, #1b5e20, #0b2410); }
.machine-minecraft { background: linear-gradient(150deg, #3e5c3a, #16221a); }
.machine-vegas     { background: linear-gradient(150deg, #4a148c, #1a0629); }
.machine-luxury    { background: linear-gradient(150deg, #b8860b, #3d2c05); }

.machine-nom { font-size: 13px; font-weight: 800; color: var(--texte); }
.machine-mise {
  font-size: 10px; font-weight: 700; color: var(--texte-doux);
  font-variant-numeric: tabular-nums;
}
.machine-courante { font-size: 16px; font-weight: 800; color: var(--accent); }

/* ---------------- Le meuble ---------------- */

.cabinet {
  position: relative;
  width: 100%; max-width: 560px;
  padding: 0 0 16px; border-radius: 18px;
  background: linear-gradient(170deg, #2a2f3d 0%, #171b25 60%, #0d1016 100%);
  border: 2px solid #3d4454;
  box-shadow: 0 16px 42px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.08);
}
/* Le meuble prend la couleur du theme : une machine fruits et une machine
   luxe ne doivent pas se ressembler. */
.cabinet-fruits    { border-color: #8e2b38; }
.cabinet-money     { border-color: #2e7d32; }
.cabinet-minecraft { border-color: #5a7a52; }
.cabinet-vegas     { border-color: #7b1fa2; }
.cabinet-luxury    { border-color: #c9a227; }

.cabinet-top {
  position: relative;
  padding: 14px 20px 12px; border-radius: 16px 16px 0 0;
  background: linear-gradient(180deg, rgba(255,255,255,.07), transparent);
  text-align: center;
}
.cabinet-name {
  font-size: 19px; font-weight: 900; letter-spacing: 2.5px;
  color: var(--accent);
  text-shadow: 0 0 14px rgba(255,176,58,.6);
}

/* Ampoules du fronton : elles clignotent en decale, comme une enseigne. */
.cabinet-lights {
  display: flex; justify-content: center; gap: 7px; margin-top: 9px;
}
.cab-light {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  animation: cabLight 1.5s ease-in-out infinite;
}
@keyframes cabLight {
  0%, 100% { opacity: .25; box-shadow: none; }
  50%      { opacity: 1; box-shadow: 0 0 8px var(--accent); }
}

/* ---------------- Les rouleaux ---------------- */

.reels {
  display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 5px; padding: 14px;
  background: #05070c; border-top: 2px solid #3d4454; border-bottom: 2px solid #3d4454;
}
.reel {
  position: relative;
  border-radius: 9px;
  background: linear-gradient(180deg, #1a1f2c, #0d1119);
  /* Fenetre de 3 cases : la bande qui defile derriere est masquee. */
  overflow: hidden;
  padding: 5px;
  /* 3 cases carrees + 2 gaps de 5px. La largeur d'une case vient de la
     grille, donc la hauteur suit automatiquement. */
  aspect-ratio: 1 / 3.1;
}

.reel-bande {
  display: flex; flex-direction: column; gap: 5px;
  will-change: transform;
}
.reel-cell {
  display: grid; place-items: center;
  /* Hauteur figee en proportion de la largeur du rouleau : la bande empile
     des cases identiques, et `hauteurCase()` la mesure pour calculer la
     translation. */
  aspect-ratio: 1; flex: 0 0 auto; border-radius: 7px;
  background: radial-gradient(circle at 40% 30%, #232a3a, #12161f);
  transition: box-shadow .2s, transform .2s;
}

/* Flou de rotation : c'est ce qui fait lire "ca tourne" plutot que
   "ca clignote". */
/* Flou pendant la rotation : c'est lui qui fait lire "ca tourne vite"
   plutot que "ca glisse". Pose sur les cases et non sur la bande, pour ne
   pas interferer avec sa transform. */
.reel-spin .reel-cell { filter: blur(1.2px); }

/* Rebond a l'arret : le rouleau depasse d'un cran puis revient. */
/* Secousse a l'arret : le rouleau encaisse le choc. Pose sur le ROULEAU et
   non sur la bande, dont la transform porte deja la position du defilement —
   les deux s'ecraseraient. */
.reel-stop { animation: reelStop .2s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes reelStop {
  0%   { transform: translateY(-5px); }
  60%  { transform: translateY(2px); }
  100% { transform: translateY(0); }
}

/* Case gagnante : halo ambre et leger agrandissement. */
.cell-gagnante {
  box-shadow: 0 0 0 2px var(--accent), 0 0 16px rgba(255,176,58,.65);
  transform: scale(1.06);
  z-index: 2;
}

.slot-sym, .slot-mc { display: block; }
.slot-mc { image-rendering: pixelated; }

/* ---------------- Les compteurs ---------------- */

.cabinet-bottom {
  display: flex; gap: 10px; padding: 14px 16px 0;
}
.cabinet-screen {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 8px 10px; border-radius: 9px;
  background: #05070c; border: 1px solid #2a3142;
}
.screen-label {
  font-size: 9px; font-weight: 800; letter-spacing: 1px;
  text-transform: uppercase; color: var(--texte-doux);
}
.screen-value {
  font-size: 16px; font-weight: 900; color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 10px rgba(255,176,58,.45);
}

/* ---------------- Le levier ---------------- */

.cabinet-lever {
  position: absolute; right: -26px; top: 42%;
  width: 26px; height: 92px; cursor: pointer;
  transform-origin: 50% 100%;
  transition: transform .18s cubic-bezier(.3, .9, .3, 1);
}
.cabinet-lever:hover { transform: rotate(-4deg); }
.lever-pull { transform: rotate(26deg); }

.lever-stick {
  position: absolute; left: 50%; top: 16px; bottom: 0;
  width: 7px; margin-left: -3.5px; border-radius: 4px;
  background: linear-gradient(90deg, #6b7488, #b6bdcc 45%, #3d4454);
}
.lever-ball {
  position: absolute; left: 50%; top: 0;
  width: 26px; height: 26px; margin-left: -13px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #ff8a8a, #c62828 55%, #7f1414);
  box-shadow: 0 3px 8px rgba(0,0,0,.5);
}

/* Le levier deborde du meuble : sur petit ecran il sortirait de l'ecran. */
@media (max-width: 680px) {
  .cabinet-lever { display: none; }
}

/* ---------------- Table des gains ---------------- */

.modal-large { max-width: 560px; }

.paytable { display: flex; flex-direction: column; gap: 5px; margin-top: 14px; }
.pt-row {
  display: grid; grid-template-columns: 42px 1fr auto auto auto;
  align-items: center; gap: 9px;
  padding: 7px 10px; border-radius: 9px;
  background: var(--fond-3); border: 1px solid var(--bordure);
}
.pt-sym { display: grid; place-items: center; }
.pt-nom { font-size: 12px; font-weight: 700; color: var(--texte); }
.pt-gain {
  font-size: 11px; font-weight: 800; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.pt-gain em {
  font-style: normal; font-size: 9px; color: var(--texte-doux);
  margin-right: 3px;
}
.pt-wild { grid-template-columns: 42px 1fr auto; border-color: var(--accent); }
.pt-note { font-size: 10.5px; color: var(--texte-doux); }

/* ------------------------------------------------------------------ */
/* Vignettes de l'accueil                                              */
/* ------------------------------------------------------------------ */

/*
 * Les emojis sont remplaces par les memes icones SVG que le rail : un
 * emoji se dessine differemment sur chaque systeme, et sa couleur se bat
 * avec le fond. Ici l'icone herite de la couleur, donc elle s'accorde
 * toujours.
 */
.game-art .ds-icone {
  stroke-width: 1.5;
  color: rgba(255, 255, 255, .92);
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, .45));
}

/* Un fond par jeu : c'est ce qui les distingue d'un coup d'oeil dans une
   grille de quinze. */
.art-slots     { background: linear-gradient(150deg, #b8860b, #4a3405); }
.art-duel      { background: linear-gradient(150deg, #8e2b38, #3a0d14); }
.art-blackjack { background: linear-gradient(150deg, #1b5e20, #0b2410); }
.art-roulette  { background: linear-gradient(150deg, #7b1e2b, #2a0a10); }
.art-mines     { background: linear-gradient(150deg, #b3162c, #3d0710); }
.art-plinko    { background: linear-gradient(150deg, #00695c, #032420); }
.art-chicken   { background: linear-gradient(150deg, #ef6c00, #4a2200); }
.art-rps       { background: linear-gradient(150deg, #455a64, #171f24); }
.art-russian   { background: linear-gradient(150deg, #37474f, #12181c); }
.art-coinflip  { background: linear-gradient(150deg, #c9a227, #4a3a05); }
.art-dice      { background: linear-gradient(150deg, #3949ab, #131a44); }
.art-limbo     { background: linear-gradient(150deg, #00897b, #052421); }
.art-cases     { background: linear-gradient(150deg, #6a1b9a, #240a33); }
.art-bonus     { background: linear-gradient(150deg, #f9a825, #4a3005); }
.art-crash     { background: linear-gradient(150deg, #4a148c, #1a0629); }

/* ------------------------------------------------------------------ */
/* Note explicative sous le jeu                                        */
/* ------------------------------------------------------------------ */

/*
 * Deplacee du haut vers le bas : en haut, le titre et l'explication
 * mangeaient ~90 px et repoussaient le plateau sous le pli sur petit ecran.
 * Le rail de gauche dit deja quel jeu est ouvert.
 */
.game-note {
  max-width: 70ch;
  margin: 22px auto 8px;
  padding: 12px 16px;
  border-radius: var(--rayon);
  background: var(--fond-2);
  border: 1px solid var(--bordure);
  color: var(--texte-doux);
  font-size: 12.5px; line-height: 1.55;
  text-align: center;
}

/* Le contenu commence plus haut, maintenant qu'il n'y a plus de titre. */
body.has-menu main > .game-layout:first-child,
body.has-menu main > .machine-grid:first-child { margin-top: 18px; }

/* Fast spin actif : l'etat doit se voir sans lire le libelle. */
#fastBtn.active {
  border-color: var(--accent);
  color: var(--accent);
}

/* ------------------------------------------------------------------ */
/* Rotation des rouleaux                                               */
/* ------------------------------------------------------------------ */

/*
 * ROTATION EN BOUCLE, A VITESSE CONSTANTE.
 *
 * Une transition unique etiree sur toute la duree du tour faisait freiner le
 * dernier rouleau pendant 7 secondes : un glissement mou, pas une rotation.
 * Ici la bande defile en boucle (`linear`, donc aucune deceleration), et
 * l'arret est une transition COURTE posee par le JS. Les deux phases sont
 * separees, chacune fait une seule chose.
 *
 * `--tour` est la hauteur d'un cycle complet, posee par le JS : l'animation
 * ne peut pas connaitre la taille des cases, qui depend de la largeur de
 * l'ecran.
 */
@keyframes bandeTourne {
  /* La bande MONTE, donc les symboles descendent a l'ecran. Le sens compte :
     l'arret vise la meme direction, sinon la bande s'inverserait au moment
     de s'immobiliser. */
  from { transform: translateY(0); }
  to   { transform: translateY(calc(var(--tour) * -1)); }
}

.bande-tourne {
  animation-name: bandeTourne;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  /* La duree vient du JS (animationDuration). */
}

@media (prefers-reduced-motion: reduce) {
  .bande-tourne { animation: none !important; }
}

/* La mise d'une machine est FIXE : on l'affiche comme un prix, pas comme un
   reglage. C'est elle qui decide du choix de la machine. */
.stake-fixe {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px; border-radius: 12px;
  background: var(--fond-3); border: 1px solid var(--accent);
}
.stake-label {
  font-size: 9.5px; font-weight: 800; letter-spacing: .6px;
  text-transform: uppercase; color: var(--texte-doux);
}
.stake-valeur {
  font-size: 22px; font-weight: 900; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
