/* MINUIT — socle visuel commun (tokens du contrat §4, classes communes, barre du haut, hall) */
/* ORDRE DES COUCHES (z-index) — UX-OVERLAYS 30/09 : une seule échelle pour tout le casino ; toute couche nouvelle s'y range.
   Les jeux gardent leurs z internes sous 100 (dans #view).
     50  .topbar (barre du haut)
    900  body::after (grain) · .rp-tools (🔑 🚪, hall seulement, posés à une place libre) · .cf-cards (défis, games/coinflip.css, posées
         à une place libre depuis P2-D) · .an-tools .df-tools (outils de l'hôte 🎡 📣 ⚡, hall seulement)
         · .rc-btn (tableau d'honneur des records, hall seulement, posé à une place libre)
    901  .vx-btn (🎙 la voix du croupier, js/voix.js, posé à une place libre par Casino.ux.libre)
    930  .route-fx (battants du changement de salle, 420 ms, non cliquable)
    940  .so-dock (réglette des potes)   942 .df-banner (défi flash, Casino.ux.libre)   944 .so-bubbles (bulles, astuce)
    945  .so-discret (fil discret des gros coups)   946 .so-ticker (grand bandeau des coups légendaires)
    947  .so-rain (pluie du cadeau, non cliquable)   948 .so-giftbanner   950 .so-drawer (tiroir)   952 .so-chat (comptoir)
    956  .sx-btn (médaille du cabinet, épinglée sur l'avatar : voulu, elle couvre ~6 % du bouton du profil)
    960  .net-veil (connexion perdue)
   1000  .join (écran d'entrée)   1010 .rp-wait (attente de l'accord de l'hôte, au-dessus de l'entrée)   1050 .invite-screen
   1090  .rp-pop (code de reprise, porte) · .vx-pop (réglage de la voix)   1095 .sx-overlay (cabinet des trophées)   1096 .rc-overlay (tableau d'honneur)   1100 .modal-back (modales)
   1090  .an-pop .df-pop (fenêtres de l'hôte, animateur et défis)   1140 .an-roue (Roue du destin plein écran)   1145 .an-card (rassemblement, 5 s)
   1150  .fds-stage (podium)   1160 .so-flies (réactions, combo : jamais cliquables)   1165 .sx-plaques (succès des potes)   1166 .rc-annonce (« NOUVEAU RECORD ! »)
   1170  .fds-recap   1175 .ct-apercu (aperçu de la carte de soirée)   1180 .sx-stage (annonce de MON succès, non cliquable)   1190 .rp-stack (demandes de reprise, chez l'hôte)
   1200  .toasts (dans la barre, non cliquables : depuis POP, la seule popup du casino, celle des gros coups — Casino.ui.coup)
         · .appui-anneau (l'anneau d'or sous le doigt pendant un appui long sur une mise, N9, non cliquable)
   1210  .signal (message près du bouton, Casino.ui.signal, non cliquable)   1250 .float-text   1290 .fds-banner   1300 .fx-canvas
   1301  .fx-banner (bandeau « Gros gain » de Casino.ui.celebrate ; la popup d'un gros coup ne l'appelle pas)
   Règles : les annonces automatiques (bulles, fil, plaques et scène des succès, cadeau, combo) passent par Casino.ux.libre (js/boot.js)
   et ne se posent jamais sur une commande ou un résultat du jeu ; les panneaux ouverts par le joueur (tiroir, cabinet, comptoir,
   petite fenêtre de reprise) se ferment d'un clic dehors ou avec Échap. Mesure : node dev/ux/collisions.mjs <port> <sortie>. */
:root {
  --topbar-h: 64px;
  --bg-0:#05060b; --bg-1:#0a0d18; --bg-2:#11152a; --bg-3:#1a2040;
  --line: rgba(222,184,92,.20); --line-strong: rgba(222,184,92,.45);
  --text:#f4ecd8; --text-dim:#a9a28e; --text-faint:#6f6a5c;
  --gold:#deb85c; --gold-hi:#f7dd8f; --gold-lo:#8c6a22;
  --felt:#0f5a44; --felt-hi:#16775a; --felt-lo:#073527;
  --red:#d2323f; --black:#15161c; --green:#1fbf75; --win:#3ee08f; --lose:#ff5a67; --warn:#ffb547;
  --neon-cyan:#3be8ff; --neon-pink:#ff4fd8; --neon-violet:#9b6bff;
  --radius:16px; --radius-sm:10px; --shadow-1: 0 6px 18px rgba(0,0,0,.35); --shadow-2: 0 18px 50px rgba(0,0,0,.55);
  --font-display:'Limelight','Bodoni MT',Georgia,serif;
  --font-ui:'Jost','Segoe UI',system-ui,sans-serif;
  --font-num:'Chakra Petch',Consolas,monospace;
  --anim-k: 1;
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 .9 0 0 0 0 .7 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  color-scheme: dark;
}
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  background: radial-gradient(1200px 700px at 50% -10%, #16204a 0%, transparent 60%), radial-gradient(900px 600px at 100% 100%, #120f2a 0%, transparent 60%), var(--bg-0);
  color: var(--text); font-family: var(--font-ui); font-size: 15px; line-height: 1.45;
  overflow: hidden; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
body::after { content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 900; background-image: var(--grain); opacity: .07; mix-blend-mode: overlay; }
button, input, select, textarea { font: inherit; color: inherit; }
::selection { background: rgba(222,184,92,.35); }
:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 2px; }
.noscript { padding: 40px; text-align: center; }
.view { position: relative; height: calc(100vh - var(--topbar-h)); overflow: hidden; }
.game-root { position: relative; height: calc(100vh - var(--topbar-h)); overflow: hidden; }

/* ---------- l'échelle de l'écran (ECHELLE, 04/10 : revue de design n° 2 de l'Armurerie, point 1 ; audit du code §3.1) ----------
   Le casino est dessiné pour une vue de 1920 × 1020. Sur un écran plus grand, la racine d'un jeu qui le demande grandit d'un facteur
   --echelle par `zoom` (qui refait la mise en page : les textes restent nets, les bords de 1 px restent à 1 px). Un jeu le demande
   en posant la classe a-l-echelle sur sa racine (root.classList.add dans son mount), ou sur un conteneur : l'Armurerie la première.
   --echelle-ecran : le palier de l'écran, largeur ET hauteur. Des rapports exacts (16/15, 6/5, 4/3, 3/2, 5/3, 2) : la vue fait
       1920 px de mise en page juste à 2048, 2304, 2560, 2880, 3200 et 3840 px de large, 12 px en font 16 à 2560, et sous un palier
       la vue garde toujours au moins 1800 × 937 px de mise en page (sinon c'est le palier d'en dessous) ;
   --echelle : l'échelle de l'endroit où l'on est (1 hors d'une racine à l'échelle) ;
   --vw, --vh : le centième de la vue en px de la mise en page (`vw` et `vh` ne suivent pas le zoom : ils mesurent la vraie fenêtre) ;
   --filet : un px d'écran (une boîte de 1 px en ferait 1,33 à 2560, peinte en 1 ou 2 px selon sa place).
   Ce qu'il faut savoir quand on écrit dans une racine à l'échelle :
   - les tailles s'écrivent en px à l'échelle 1 ; on ne touche ni à zoom ni à --echelle, et on n'emboîte pas deux racines à l'échelle ;
   - pas de `vw` ni de `vh` nus : calc(N * var(--vw, 1vw)) et calc(N * var(--vh, 1vh)) (dev/outils/unites-echelle.mjs convertit une
     feuille et signale les unités nues) ;
   - une longueur fixe à l'écran, hors de l'échelle (la barre du casino), se divise : calc(var(--topbar-h) / var(--echelle, 1)) ;
   - un filet tracé par une boîte (height: 1px, pas un bord) s'écrit var(--filet, 1px) ;
   - en JS, getBoundingClientRect, innerWidth et la souris (clientX) sont en px de l'écran ; les styles, les transform, offsetWidth,
     clientWidth et scrollTop sont en px de la mise en page : Casino.echelle(el) rend le rapport, et une longueur lue sur un rectangle
     puis posée en style se divise par lui ;
   - un canevas se dessine à clientWidth × Casino.echelle(el) × la densité de l'écran (sinon il est étiré, donc flou), et son pointeur
     se lit par clientX moins le rectangle, jamais par offsetX ;
   - les @media lisent la vraie fenêtre : sous un palier, aucune adaptation « petit écran » (≤ 1699 px, ≤ 860 px de haut) ne joue.
   Seuls les moteurs où `zoom` suit la norme reçoivent un palier (classe zoom-norme de <html>, posée par js/core.js : Chromium 128+,
   Firefox 126+) ; ailleurs --echelle-ecran reste à 1 et rien ne change. */
:root { --echelle-ecran: 1; --echelle: 1; --vw: 1vw; --vh: 1vh; --filet: 1px; }
@media (min-width: 2000px) and (min-height: 1000px) { .zoom-norme { --echelle-ecran: 1.0666667; } }
@media (min-width: 2200px) and (min-height: 1125px) { .zoom-norme { --echelle-ecran: 1.2; } }
@media (min-width: 2400px) and (min-height: 1250px) { .zoom-norme { --echelle-ecran: 1.3333334; } }
@media (min-width: 2700px) and (min-height: 1410px) { .zoom-norme { --echelle-ecran: 1.5; } }
@media (min-width: 3000px) and (min-height: 1565px) { .zoom-norme { --echelle-ecran: 1.6666667; } }
@media (min-width: 3600px) and (min-height: 1880px) { .zoom-norme { --echelle-ecran: 2; } }
.coque-a-l-echelle :is(.topbar, .so-dock, .so-bubbles, .so-chat, .so-ticker, .so-drawer, .toasts, .signal, .signal-voix, .sx-btn, .sx-stage, .sx-plaques, .sx-overlay, .rc-annonce, .rc-overlay, .vx-btn, .vx-pop, .modal-back):not(.a-l-echelle *),
.a-l-echelle { --echelle: var(--echelle-ecran, 1); --vw: calc(1vw / var(--echelle)); --vh: calc(1vh / var(--echelle)); --filet: calc(1px / var(--echelle)); zoom: var(--echelle); }
.game-root.a-l-echelle { height: calc((100vh - var(--topbar-h)) / var(--echelle)); }
/* ---------- la coque à l'échelle du jeu monté (MESSAGES, 04/10 : revue n° 3 de l'Armurerie, défaut 8) ----------
   Un jeu à l'échelle sous une barre et des messages restés à leur taille de 1920, ce sont deux échelles à l'écran. Tant que la racine
   du jeu monté porte a-l-echelle, js/core.js pose coque-a-l-echelle sur <html> (Casino.jeuALEchelle()) : les couches du casino
   nommées dans la règle ci-dessus prennent le MÊME palier, par la même règle que la racine du jeu — la barre, la réglette, ses bulles,
   son comptoir, le tiroir des potes, le grand bandeau, la pile des popups, les messages près d'un bouton, le trophée, les plaques,
   l'annonce de record, le bouton de la voix, les fenêtres (réglages, cabinet, tableau d'honneur). Hors d'un jeu à l'échelle (le hall,
   tous les autres jeux), la classe est absente et rien de ceci ne joue.
   - --topbar-h reste la hauteur de la barre À L'ÉCRAN (64 px × le palier) : `100vh - var(--topbar-h)` reste juste partout ; dans une
     couche à l'échelle elle se divise, comme toute longueur de l'écran : calc(var(--topbar-h) / var(--echelle, 1)).
   - Ces couches sont en position fixe et se placent en JS sur des rectangles de l'écran : left, top, width et les variables qu'on leur
     pose sont des px de LEUR mise en page. Une longueur de l'écran s'y pose divisée par Casino.echelle(couche), une taille lue par
     offsetWidth s'y compte multipliée ; à l'échelle 1 ces opérations ne changent rien (les témoins de
     dev/tests-client/q-messages-captures.mjs le prouvent au pixel).
   - Ajouter une couche : son sélecteur dans la règle ci-dessus, ses vw / vh en var(--vw) / var(--vh), son placement JS passé par
     Casino.echelle. Une couche qui n'y est pas reste à l'échelle 1, à sa place (le fil discret, la bannière de cadeau, les outils de
     l'hôte, les défis, les émojis qui volent : pas encore). */
.coque-a-l-echelle { --topbar-h: calc(64px * var(--echelle-ecran, 1)); }
/* cinq textes de ces couches sont sous 12 px de feuille (la coche d'un message, le nom d'une bulle, le compte du cabinet, le titre d'une
   popup de gros coup, la rareté d'une plaque) : dans un jeu à l'échelle ils montent à 12 (16 px à 2560) ; ailleurs ils gardent leur taille */
.coque-a-l-echelle :is(.signal-ico, .so-bub-n, .sx-btn-n, .coup-k, .sx-pl-rar) { font-size: 12px; }
/* le compte du cabinet fait partie de son bouton : il prend le clic, et ne passe plus pour un texte couvert */
.coque-a-l-echelle .sx-btn-n { pointer-events: auto; }

/* ---------- utilitaires ---------- */
.num { font-family: var(--font-num); font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.muted { color: var(--text-dim); }
.win { color: var(--win); }
.lose { color: var(--lose); }
.row { display: flex; align-items: center; gap: 10px; }
.stack { display: flex; flex-direction: column; gap: 10px; }
.scroll { overflow: auto; scrollbar-width: thin; scrollbar-color: var(--gold-lo) transparent; }
.scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll::-webkit-scrollbar-thumb { background: var(--gold-lo); border-radius: 8px; }
.kbd { display: inline-block; min-width: 1.6em; padding: 1px 6px; border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 6px; font: 600 11px/1.5 var(--font-num); color: var(--text-dim); text-align: center; background: rgba(255,255,255,.03); }
.badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 9px; border-radius: 999px; font: 600 11px/1.6 var(--font-ui); letter-spacing: .08em; text-transform: uppercase; color: var(--gold-hi); border: 1px solid var(--line-strong); background: rgba(222,184,92,.08); }

/* ---------- boutons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 40px; padding: 0 18px; border-radius: 999px; border: 1px solid var(--line-strong); background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.01)); color: var(--text); font: 600 14px/1 var(--font-ui); letter-spacing: .04em; cursor: pointer; user-select: none; white-space: nowrap; transition: transform .12s, background .2s, border-color .2s, box-shadow .2s, opacity .2s; }
.btn:hover { border-color: var(--gold); background: rgba(222,184,92,.10); }
.btn:active { transform: translateY(1px) scale(.98); }
.btn-gold { border-color: transparent; color: #241904; background: linear-gradient(180deg, var(--gold-hi) 0%, var(--gold) 45%, #b8913b 100%); box-shadow: 0 0 0 1px rgba(255,236,170,.5) inset, 0 6px 18px rgba(222,184,92,.25); text-transform: uppercase; letter-spacing: .1em; }
.btn-gold:hover { background: linear-gradient(180deg, #fff0bd 0%, var(--gold-hi) 50%, var(--gold) 100%); box-shadow: 0 0 0 1px rgba(255,236,170,.7) inset, 0 8px 26px rgba(222,184,92,.4); }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--text-dim); }
.btn-ghost:hover { color: var(--text); }
.btn-danger { border-color: rgba(255,90,103,.55); color: #ffd9dc; background: rgba(210,50,63,.18); }
.btn-danger:hover { background: rgba(210,50,63,.32); border-color: var(--lose); }
.btn-sm { height: 30px; padding: 0 11px; font-size: 12.5px; }
.btn-lg { height: 52px; padding: 0 30px; font-size: 16px; }
.btn[disabled], .btn.is-disabled { opacity: .38; cursor: not-allowed; pointer-events: none; }

/* ---------- panneaux & champs ---------- */
.panel { position: relative; background: linear-gradient(180deg, rgba(26,32,64,.72), rgba(10,13,24,.86)); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-1), inset 0 1px 0 rgba(247,221,143,.06); padding: 16px; }
.panel-title { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; font: 400 17px/1.2 var(--font-display); letter-spacing: .06em; color: var(--gold-hi); }
.panel-title::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, var(--line-strong), transparent); }
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label, .field > .label { font: 600 11px/1 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.input, .select { height: 40px; padding: 0 12px; border-radius: var(--radius-sm); border: 1px solid var(--line-strong); background: rgba(5,6,11,.6); color: var(--text); outline: none; transition: border-color .2s, box-shadow .2s; min-width: 0; }
.input:focus, .select:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(222,184,92,.18); }
.select { appearance: none; padding-right: 30px; background-image: linear-gradient(45deg, transparent 50%, var(--gold) 50%), linear-gradient(135deg, var(--gold) 50%, transparent 50%); background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%; background-size: 5px 5px; background-repeat: no-repeat; }
.select option { background: var(--bg-2); color: var(--text); }
.seg { display: inline-flex; padding: 3px; gap: 2px; border-radius: 999px; border: 1px solid var(--line); background: rgba(5,6,11,.55); }
.seg > button { height: 32px; padding: 0 14px; border: 0; border-radius: 999px; background: transparent; color: var(--text-dim); font: 600 13px/1 var(--font-ui); letter-spacing: .03em; cursor: pointer; transition: background .2s, color .2s; }
.seg > button:hover { color: var(--text); }
.seg > button.is-on { background: linear-gradient(180deg, var(--gold-hi), var(--gold)); color: #241904; box-shadow: 0 2px 10px rgba(222,184,92,.3); }
input[type=range] { accent-color: var(--gold); }
/* Compat Firefox (FIREFOX 30/09, posée ici par UX-OVERLAYS) : sans ces règles, toute réglette y garde un thème clair (piste blanche,
   curseur gris cerclé de blanc). Même allure que Chrome/Edge ; les ::-moz-* sont ignorées ailleurs. Poker et Plinko gardent les leurs. */
input[type=range] { background: transparent; }
input[type=range]::-moz-range-track { height: 8px; border-radius: 999px; background: #3a3a3f; border: 1.5px solid rgba(255,255,255,.4); box-sizing: border-box; }
input[type=range]::-moz-range-progress { height: 8px; border-radius: 999px; background: var(--gold); }
input[type=range]::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--gold); border: 0; }

/* ---------- tapis ---------- */
.felt { background: radial-gradient(ellipse at 50% 35%, var(--felt-hi) 0%, var(--felt) 45%, var(--felt-lo) 100%); position: relative; box-shadow: inset 0 0 0 2px rgba(222,184,92,.35), inset 0 0 90px rgba(0,0,0,.55); }
.felt::before { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; background-image: var(--grain); opacity: .22; mix-blend-mode: soft-light; }

/* ---------- cartes à jouer ---------- */
/* Le dessin des faces et du dos vient de js/cartes.js (une toile par face, à la taille exacte de l'écran) ; ici : le carton.
   Proportions 5 × 7 (63 × 88 mm), coins de 3,4 mm (5,4 % de la largeur), liseré d'un cheveu, ombre courte et douce d'une carte
   posée sur le feutre. --card-w : la largeur d'une carte, que chaque table règle sur sa propre taille. */
.pcard { width: var(--card-w, 88px); aspect-ratio: 5/7; position: relative; perspective: 900px; flex: none; container-type: inline-size; user-select: none; border-radius: 5.4% / 3.857%; box-shadow: 0 1px 2px rgba(0,0,0,.42), 0 3px 9px rgba(0,0,0,.28); }
.pcard.pcard-sm { width: var(--card-w-sm, 58px); }
.pcard-inner { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform var(--flip-ms, 460ms) cubic-bezier(.3,.75,.25,1); }
.pcard.is-down .pcard-inner { transform: rotateY(180deg); }
.pcard.no-anim .pcard-inner { transition: none !important; }
.pcard-face { position: absolute; inset: 0; border-radius: 5.4% / 3.857%; backface-visibility: hidden; -webkit-backface-visibility: hidden; overflow: hidden; }
.pcard-face > .pc-toile { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* par-dessus la toile : le liseré du carton, et un rien de lumière venue du haut gauche (un carton, pas un aplat) */
.pcard-face::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; box-shadow: inset 0 0 0 1px rgba(52,40,18,.30), inset 0 1px 0 rgba(255,255,255,.5); background: linear-gradient(142deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 34%, rgba(40,28,8,.05) 100%); }
.pcard-front { background: #fbf7ee; }
.pcard-back { transform: rotateY(180deg); background: #111a45; }
.pcard-back::after { box-shadow: inset 0 0 0 1px rgba(52,40,18,.30); }

/* ---------- jetons ---------- */
.chip { --chip-c:#efe9dc; --chip-edge:#2462c4; --chip-ink:#1a1a1a; width: var(--chip-size, 44px); height: var(--chip-size, 44px); flex: none; border-radius: 50%; position: relative; display: inline-grid; place-items: center; user-select: none; background: repeating-conic-gradient(from 11.25deg, var(--chip-c) 0 33.75deg, var(--chip-edge) 33.75deg 45deg); box-shadow: inset 0 0 0 1.5px rgba(0,0,0,.28), 0 2px 0 rgba(0,0,0,.4), 0 5px 10px rgba(0,0,0,.35); }
.chip::before { content: ""; position: absolute; inset: 15%; border-radius: 50%; background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.28), transparent 60%), var(--chip-c); box-shadow: 0 0 0 1.5px rgba(0,0,0,.18), inset 0 0 0 2px rgba(255,255,255,.18); }
.chip::after { content: ""; position: absolute; inset: 21%; border-radius: 50%; border: 1.5px dashed color-mix(in srgb, var(--chip-edge) 70%, transparent); }
/* N23 (revue finale R2, n° 16, AU PC) : 0,3 × la taille du jeton, et 12 px au moins dès 37,5 px de jeton (le min() monte de 0 à 12 px
   entre 37 et 37,5 px) : les jetons de 38 px des râteliers (Grande Roue, blackjack en ligne) passent de 11,4 à 12 px, comme au téléphone
   (N1c) ; dessous (32 px du Derby : « 100 » et « 500 » sortiraient de leur face) et dès 40 px, rien ne change. Le jeton garde son dessin,
   mesuré (dev/tests-client/s5-r2-petits.mjs, J) : même taille, l'encre de chaque valeur dans la face, celles qui tenaient dans le cercle
   tireté y tiennent encore. */
.chip-v { position: relative; z-index: 1; font: 700 max(calc(var(--chip-size, 44px) * .3), min(12px, calc((var(--chip-size, 44px) - 37px) * 24)))/1 var(--font-num); color: var(--chip-ink); letter-spacing: -.02em; }
.chip-long .chip-v { font-size: calc(var(--chip-size, 44px) * .24); }
.chip.chip-sm { --chip-size: 32px; }
.chip.chip-lg { --chip-size: 60px; }
.chip-rack { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.chip-slot { padding: 3px; border: 0; background: transparent; border-radius: 50%; cursor: pointer; transition: transform .15s; }
.chip-slot:hover { transform: translateY(-3px); }
.chip-slot.is-on { transform: translateY(-5px); }
.chip-slot.is-on .chip { box-shadow: 0 0 0 2px var(--gold-hi), 0 0 18px rgba(247,221,143,.55), 0 5px 10px rgba(0,0,0,.4); }
.bet-input { display: inline-flex; align-items: center; gap: 6px; padding: 4px 4px 4px 10px; border-radius: 999px; border: 1px solid var(--line-strong); background: rgba(5,6,11,.6); }
.bet-input .bet-field { width: 96px; height: 32px; border: 0; background: transparent; box-shadow: none; padding: 0 4px; font-size: 17px; font-weight: 700; color: var(--gold-hi); }
.bet-input .bet-field:focus { box-shadow: none; }
.bet-coin { width: 16px; height: 16px; border-radius: 50%; flex: none; background: radial-gradient(circle at 35% 30%, var(--gold-hi), var(--gold) 50%, var(--gold-lo)); box-shadow: 0 0 0 1.5px rgba(0,0,0,.35) inset; }
.bet-btn { padding: 0 10px; min-width: 38px; }

/* ---------- pastille joueur ---------- */
.ptag { --pc: var(--gold); display: inline-flex; align-items: center; gap: 7px; padding: 3px 11px 3px 3px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--pc) 55%, transparent); background: color-mix(in srgb, var(--pc) 12%, rgba(5,6,11,.7)); white-space: nowrap; }
.ptag-emoji { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; font-size: 15px; background: color-mix(in srgb, var(--pc) 28%, #0a0d18); box-shadow: 0 0 0 1.5px var(--pc); }
.ptag-name { font-weight: 600; font-size: 13.5px; }
.ptag-bal { font-weight: 700; color: var(--gold-hi); font-size: 13.5px; }
.live-bal.bump-up { animation: bumpUp .7s ease; }
.live-bal.bump-down { animation: bumpDown .7s ease; }
@keyframes bumpUp { 0% { color: var(--win); text-shadow: 0 0 12px var(--win); transform: scale(1.12); } 100% { transform: none; } }
@keyframes bumpDown { 0% { color: var(--lose); transform: scale(.94); } 100% { transform: none; } }

/* ---------- toasts, modales, effets ---------- */
/* Toasts : « l'annonce du croupier » loge DANS la barre du haut, sur le logo et le nom du jeu (zone purement informative).
   Plus rien ne recouvre les en-têtes ni les boutons des jeux. Pile en cartes : la plus récente devant, les autres dessous. */
.toasts { position: fixed; top: var(--toast-t, 7px); left: var(--toast-l, 12px); z-index: 1200; width: var(--toast-w, clamp(280px, calc(50vw - 300px), 440px)); height: 50px; pointer-events: none; }
/* UX-OVERLAYS 30/09 : --toast-l / --toast-w / --toast-t posés par js/boot.js (poserToasts) à chaque toast : dans la barre après le
   nom du jeu s'il reste ≥ 300 px, sinon sous la barre à la place libre la plus proche du coin haut-gauche (playtest G2 : plus
   jamais sur le logo ni sur le nom du jeu). */
.toast { --d: 0; position: absolute; inset: 0; display: flex; align-items: center; gap: 10px; padding: 0 16px 0 8px; border-radius: 14px;
  background: linear-gradient(180deg, rgba(24,29,58,.985), rgba(8,10,20,.985)); border: 1px solid var(--line-strong);
  box-shadow: 0 12px 30px rgba(0,0,0,.6), inset 0 1px 0 rgba(247,221,143,.14), inset 0 0 0 3px rgba(5,6,11,.55);
  transform-origin: 50% 0; transform: translateY(calc(var(--d) * 6px)) scale(calc(1 - var(--d) * .045)); opacity: calc(1 - var(--d) * .38);
  z-index: calc(10 - var(--d)); transition: transform .3s cubic-bezier(.2,.9,.3,1), opacity .3s; animation: toastIn .38s cubic-bezier(.2,.9,.3,1.12) backwards; overflow: hidden; }
.toast::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: linear-gradient(90deg, transparent, var(--tc, var(--gold)), transparent);
  transform-origin: 0 50%; animation: toastLife var(--life, 2.7s) linear both; opacity: .8; }
.toast-msg { font-size: 13.5px; line-height: 1.25; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.toast.out { opacity: 0; transform: translateY(-14px) scale(.97); transition: opacity .3s, transform .3s; }
.toast-ico { width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center; font-weight: 700; font-size: 14px; background: rgba(222,184,92,.16); color: var(--gold-hi); flex: none; box-shadow: inset 0 0 0 1px rgba(222,184,92,.35); }
@keyframes toastIn { from { opacity: 0; transform: translateY(-22px) scale(.94); } }
@keyframes toastLife { from { transform: scaleX(1); } to { transform: scaleX(0); } }
/* La popup d'un gros coup (Casino.ui.coup) : une carte de cette pile, la seule popup qui reste. Mon gros gain : l'or, le montant en grand,
   et la pluie de pièces derrière ; ma grosse perte : sobre, sans éclat ; le très gros gain d'un autre : son emoji sur sa couleur. */
.toast.coup { gap: 12px; padding: 0 16px 0 9px; box-shadow: 0 6px 8px rgba(0,0,0,.5), inset 0 1px 0 rgba(247,221,143,.14); }
.coup-corps { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; flex: 0 1 auto; }
.coup-k { font: 600 11.5px/1.15 var(--font-ui); letter-spacing: .03em; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.coup-k2 { font-weight: 500; }
.coup-v { font-size: 19px; font-weight: 700; line-height: 1.05; color: var(--text); white-space: nowrap; }
.coup-ou { flex: 1 1 auto; min-width: 0; font-size: 13px; line-height: 1.2; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
.coup-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.toast.coup.is-gain.is-moi { --tc: var(--gold-hi); border-color: rgba(247,221,143,.8); background: linear-gradient(180deg, rgba(48,39,13,.99), rgba(15,12,5,.99)); }
.toast.coup.is-gain.is-moi .coup-ico { background: radial-gradient(circle at 35% 30%, var(--gold-hi), var(--gold) 55%, var(--gold-lo)); color: #2a1d02; box-shadow: none; font-size: 16px; }
.toast.coup.is-gain.is-moi .coup-k, .toast.coup.is-gain.is-moi .coup-v { color: var(--gold-hi); }
.toast.coup.is-perte { --tc: rgba(255,143,152,.55); border-color: rgba(255,90,103,.38); }
.toast.coup.is-perte .coup-ico { background: rgba(255,90,103,.12); color: #ff8f98; box-shadow: inset 0 0 0 1px rgba(255,90,103,.3); }
.toast.coup.is-perte .coup-v { color: #ff8f98; }
.toast.coup.is-autre { --tc: var(--pc, var(--gold)); }
.toast.coup.is-autre .coup-av { border-radius: 50%; font-size: 17px; background: color-mix(in srgb, var(--pc, var(--gold)) 28%, #0a0d18); box-shadow: 0 0 0 1.5px var(--pc, var(--gold)); }
.toast.coup.is-autre .coup-k { color: var(--text); }
.toast.coup.is-autre .coup-v { color: var(--win); }
/* Le message près du bouton (Casino.ui.signal) : un refus, une erreur, une confirmation discrète. Petit, lisible (texte ≥ 4,5:1), il ne
   prend aucun clic, se pose au-dessus de l'élément du geste (dessous s'il n'y a pas la place), ne sort jamais de l'écran (core.js). */
.signal { position: fixed; z-index: 1210; left: 0; top: 0; width: max-content; max-width: min(320px, calc(100vw - 16px)); display: flex; align-items: flex-start; gap: 8px;
  padding: 7px 12px 7px 8px; border-radius: 10px; pointer-events: none; background: #0d1124; border: 1px solid var(--line-strong); color: var(--text);
  font: 500 13.5px/1.3 var(--font-ui); box-shadow: 0 4px 8px rgba(0,0,0,.55); animation: signalIn .18s cubic-bezier(.22,1,.36,1) both; }
.signal::after { content: ""; position: absolute; left: var(--pointe, 50%); bottom: -6px; width: 10px; height: 10px; margin-left: -5px; background: #0d1124;
  border: inherit; border-top: 0; border-left: 0; transform: rotate(45deg); }
.signal.is-dessous { animation-name: signalInBas; }
.signal.is-dessous::after { bottom: auto; top: -6px; transform: rotate(-135deg); }
/* ancré dans la barre du haut (sous le solde) : une étiquette basse, sans pointe, qui tient dans la marge sous la barre */
.signal.is-barre { align-items: center; gap: 6px; padding: 2px 10px 2px 5px; border-radius: 8px; font-size: 12.5px; line-height: 1.2; }
.signal.is-barre .signal-ico { width: 16px; height: 16px; font-size: 12px; }
.signal.is-barre::after { display: none; }
.signal.sans-pointe::after { display: none; }
.signal-ico { flex: none; width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; font: 700 11.5px/1 var(--font-ui); background: rgba(222,184,92,.16); color: var(--gold-hi); }
.signal-msg { min-width: 0; overflow-wrap: anywhere; }
.signal-warn { border-color: rgba(255,181,71,.75); }
.signal-warn .signal-ico { background: var(--warn); color: #2a1a00; }
.signal-ok { border-color: rgba(62,224,143,.55); }
.signal-ok .signal-ico { background: rgba(62,224,143,.18); color: var(--win); }
.signal.out { opacity: 0; transition: opacity .18s; }
.signal-voix { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
@keyframes signalIn { from { opacity: 0; transform: translateY(4px) scale(.98); } }
@keyframes signalInBas { from { opacity: 0; transform: translateY(-4px) scale(.98); } }
@media (prefers-reduced-motion: reduce) { .signal, .signal.is-dessous, .toast.coup { animation-name: fadeIn; } }   /* un fondu, sans glissé */
.modal-back { position: fixed; inset: 0; z-index: 1100; display: grid; place-items: center; padding: 16px; background: rgba(3,4,8,.7); backdrop-filter: blur(4px); animation: fadeIn .2s ease; }
.modal-back.out { opacity: 0; transition: opacity .18s; pointer-events: none; }
.modal { width: min(460px, 100%); max-height: calc(100 * var(--vh, 1vh) - 40px); overflow: auto; border-radius: 18px; border: 1px solid var(--line-strong); background: linear-gradient(180deg, #151a36, #0a0d18); box-shadow: var(--shadow-2), 0 0 0 6px rgba(222,184,92,.05); animation: popIn .26s cubic-bezier(.2,.9,.3,1.15); }
.modal-wide { width: min(780px, 100%); }
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 18px 20px 8px; }
.modal-title { margin: 0; font: 400 22px/1.2 var(--font-display); color: var(--gold-hi); letter-spacing: .04em; }
.modal-x { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: transparent; color: var(--text-dim); font-size: 20px; line-height: 1; cursor: pointer; }
.modal-x:hover { color: var(--text); border-color: var(--gold); }
.modal-body { padding: 8px 20px 12px; color: var(--text); }
.modal-body p { margin: 0 0 10px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; padding: 10px 20px 20px; }
@keyframes fadeIn { from { opacity: 0; } }
@keyframes popIn { from { opacity: 0; transform: translateY(10px) scale(.96); } }
.fx-canvas { position: fixed; inset: 0; z-index: 1300; pointer-events: none; }
.fx-banner { position: fixed; left: 50%; top: 42%; z-index: 1301; pointer-events: none; text-align: center; transform: translate(-50%,-50%); animation: bannerIn 3.3s cubic-bezier(.2,.9,.3,1.1) forwards; }
.fx-banner-k { font: 400 clamp(26px, 4vw, 48px)/1 var(--font-display); color: var(--gold-hi); letter-spacing: .12em; text-transform: uppercase; text-shadow: 0 0 30px rgba(247,221,143,.6), 0 4px 0 #5a4210; }
.fx-banner-v { margin-top: 8px; font-size: clamp(34px, 6vw, 76px); font-weight: 700; color: #fff; text-shadow: 0 0 24px rgba(62,224,143,.8), 0 4px 0 rgba(0,0,0,.5); }
@keyframes bannerIn { 0% { opacity: 0; transform: translate(-50%,-50%) scale(.6); } 12% { opacity: 1; transform: translate(-50%,-50%) scale(1.06); } 20% { transform: translate(-50%,-50%) scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%,-60%) scale(1); } }
.float-text { position: fixed; z-index: 1250; pointer-events: none; transform: translate(-50%,-50%); font-weight: 700; font-size: 22px; text-shadow: 0 2px 8px rgba(0,0,0,.7); animation: floatUp 1.25s ease-out forwards; }
@keyframes floatUp { 0% { opacity: 0; transform: translate(-50%,-30%) scale(.8); } 15% { opacity: 1; transform: translate(-50%,-60%) scale(1.1); } 100% { opacity: 0; transform: translate(-50%,-220%) scale(1); } }
.game-error { max-width: 420px; margin: 80px auto; text-align: center; }

/* ---------- barre du haut ---------- */
.topbar { position: relative; z-index: 50; height: calc(var(--topbar-h) / var(--echelle, 1)); display: flex; align-items: center; gap: 14px; padding: 0 18px; background: linear-gradient(180deg, rgba(17,21,42,.97), rgba(10,13,24,.97)); border-bottom: 1px solid var(--line-strong); box-shadow: 0 8px 24px rgba(0,0,0,.35); }
.topbar::after { content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 3px; background: linear-gradient(90deg, transparent, rgba(222,184,92,.35) 20%, rgba(222,184,92,.35) 80%, transparent); opacity: .5; pointer-events: none; }
.tb-logo { display: inline-flex; align-items: center; gap: 10px; border: 0; background: none; cursor: pointer; padding: 0; color: var(--gold-hi); }
.tb-logo-mark { width: 30px; height: 30px; }
.tb-logo-word { font: 400 25px/1 var(--font-display); letter-spacing: .16em; background: linear-gradient(180deg, #fff3c4, var(--gold) 55%, var(--gold-lo)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.tb-sep { width: 1px; height: 28px; background: var(--line-strong); }
.tb-game { font: 600 13px/normal var(--font-ui); letter-spacing: .18em; text-transform: uppercase; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tb-game b { color: var(--text); font-weight: 600; }
.tb-spacer { flex: 1; }
.tb-player { display: flex; align-items: center; gap: 8px; }
.tb-select { max-width: 190px; height: 36px; }
.tb-balance { display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 14px 0 8px; border-radius: 999px; border: 1px solid var(--line-strong); background: rgba(5,6,11,.65); font-size: 17px; font-weight: 700; color: var(--gold-hi); }
.tb-balance .bet-coin { width: 20px; height: 20px; }
.tb-icon { width: 38px; height: 38px; padding: 0; border-radius: 50%; font-size: 17px; }
.tb-refill { animation: pulseGold 1.6s ease-in-out infinite; }
@keyframes pulseGold { 50% { box-shadow: 0 0 0 1px rgba(255,236,170,.5) inset, 0 0 26px rgba(222,184,92,.6); } }

/* ---------- hall ---------- */
.hall { height: 100%; overflow-y: auto; overflow-x: hidden; scrollbar-width: thin; scrollbar-color: var(--gold-lo) transparent; }
.hall-inner { max-width: 1320px; margin: 0 auto; padding: 22px 24px 30px; display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 24px; align-items: start; }
.hero { grid-column: 1 / -1; position: relative; overflow: hidden; border-radius: 22px; border: 1px solid var(--line-strong); min-height: 230px; display: grid; place-items: center; text-align: center; padding: 28px 20px 30px; background: radial-gradient(ellipse at 50% 120%, rgba(222,184,92,.22), transparent 60%), linear-gradient(180deg, #0c1230, #070913); box-shadow: var(--shadow-2), inset 0 0 0 6px rgba(5,6,11,.6), inset 0 0 0 7px rgba(222,184,92,.25); }
.hero-sun { position: absolute; left: 50%; bottom: -380px; width: 900px; height: 900px; margin-left: -450px; border-radius: 50%; background: repeating-conic-gradient(from 0deg, rgba(222,184,92,.16) 0 4deg, transparent 4deg 12deg); -webkit-mask: radial-gradient(circle, #000 20%, transparent 62%); mask: radial-gradient(circle, #000 20%, transparent 62%); animation: sunSpin calc(120s * var(--anim-k, 1)) linear infinite; }
.hero-arcs { position: absolute; left: 50%; bottom: -120px; width: 520px; height: 260px; margin-left: -260px; border-radius: 260px 260px 0 0; border: 1px solid rgba(222,184,92,.35); border-bottom: 0; box-shadow: 0 0 0 18px rgba(5,6,11,.0), 0 0 0 19px rgba(222,184,92,.18), 0 0 0 38px rgba(5,6,11,0), 0 0 0 39px rgba(222,184,92,.10); }
.hero::after { content: ""; position: absolute; inset: 0; background-image: var(--grain); opacity: .12; mix-blend-mode: overlay; pointer-events: none; }
@keyframes sunSpin { to { transform: rotate(360deg); } }
.hero-content { position: relative; z-index: 1; }
.hero-kicker { font: 600 12px/1 var(--font-ui); letter-spacing: .5em; text-transform: uppercase; color: var(--gold); margin-bottom: 14px; }
.hero-title { margin: 0; font: 400 clamp(64px, 9vw, 116px)/.9 var(--font-display); letter-spacing: .14em; padding-left: .14em; background: linear-gradient(180deg, #fff6d6 0%, var(--gold-hi) 35%, var(--gold) 60%, var(--gold-lo) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero-sub { margin-top: 14px; font: 400 18px/1.4 var(--font-ui); color: var(--text-dim); letter-spacing: .04em; }
.hero-sub em { font-style: normal; color: var(--gold-hi); }
.hero-rule { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 16px auto 0; color: var(--gold); font-size: 12px; }
.hero-rule::before, .hero-rule::after { content: ""; width: 90px; height: 1px; background: linear-gradient(90deg, transparent, var(--gold)); }
.hero-rule::after { transform: scaleX(-1); }
@keyframes heroIn { from { opacity: 0; letter-spacing: .4em; } }
.hall-main { display: flex; flex-direction: column; gap: 26px; min-width: 0; }
.sec-head { display: flex; align-items: baseline; gap: 14px; margin: 0 0 12px; }
.sec-title { margin: 0; font: 400 26px/1 var(--font-display); letter-spacing: .06em; color: var(--text); }
.sec-sub { color: var(--text-faint); font-size: 13px; letter-spacing: .04em; }
.sec-head::after { content: ""; flex: 1; height: 1px; align-self: center; background: linear-gradient(90deg, var(--line-strong), transparent); }
.games-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.games-empty { padding: 18px; border-radius: 14px; border: 1px dashed var(--line); color: var(--text-faint); font-size: 14px; }
.gcard { --accent: var(--gold); position: relative; display: flex; flex-direction: column; gap: 6px; min-height: 150px; padding: 16px 16px 14px; border-radius: 16px; border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); background: radial-gradient(120% 90% at 100% 0%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 60%), linear-gradient(180deg, rgba(26,32,64,.8), rgba(10,13,24,.92)); color: var(--text); text-align: left; cursor: pointer; overflow: hidden; transition: transform .2s cubic-bezier(.2,.9,.3,1.3), box-shadow .25s, border-color .25s; animation: cardIn .5s cubic-bezier(.2,.9,.3,1) both; animation-delay: calc(var(--i, 0) * 60ms); }
.gcard::before { content: ""; position: absolute; right: -40px; top: -40px; width: 150px; height: 150px; background: repeating-conic-gradient(from 180deg at 50% 50%, color-mix(in srgb, var(--accent) 22%, transparent) 0 5deg, transparent 5deg 15deg); -webkit-mask: radial-gradient(circle, #000 25%, transparent 70%); mask: radial-gradient(circle, #000 25%, transparent 70%); opacity: .7; transition: transform .6s; }
.gcard:hover { transform: translateY(-4px); border-color: var(--accent); box-shadow: 0 14px 34px rgba(0,0,0,.5), 0 0 30px color-mix(in srgb, var(--accent) 35%, transparent); }
.gcard:hover::before { transform: rotate(40deg) scale(1.1); }
.gcard-icon { position: relative; width: 52px; height: 52px; display: grid; place-items: center; font-size: 30px; line-height: 1; border-radius: 14px; background: color-mix(in srgb, var(--accent) 16%, rgba(5,6,11,.6)); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 25%, transparent); }
.gcard-icon svg { width: 32px; height: 32px; }
.gcard-name { position: relative; margin-top: 6px; font: 400 21px/1.1 var(--font-display); letter-spacing: .04em; }
.gcard-tag { position: relative; color: var(--text-dim); font-size: 13.5px; line-height: 1.35; }
.gcard-foot { position: relative; margin-top: auto; padding-top: 8px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.gcard-go { font: 600 11px/1 var(--font-ui); letter-spacing: .2em; text-transform: uppercase; color: var(--accent); }
.gcard-multi { color: var(--neon-pink); border-color: rgba(255,79,216,.45); background: rgba(255,79,216,.1); }
@keyframes cardIn { from { opacity: 0; transform: translateY(14px); } }
.hall-side { display: flex; flex-direction: column; gap: 16px; position: sticky; top: 0; }
.plist { display: flex; flex-direction: column; gap: 6px; }
.prow { display: flex; align-items: center; gap: 10px; padding: 7px 8px; border-radius: 12px; border: 1px solid transparent; transition: background .2s, border-color .2s; }
.prow:hover { background: rgba(255,255,255,.03); }
.prow.is-active { border-color: color-mix(in srgb, var(--pc, var(--gold)) 55%, transparent); background: color-mix(in srgb, var(--pc, var(--gold)) 9%, transparent); }
.prow-av { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; font-size: 18px; flex: none; background: color-mix(in srgb, var(--pc, var(--gold)) 25%, #0a0d18); box-shadow: 0 0 0 1.5px var(--pc, var(--gold)); }
.prow-main { flex: 1; min-width: 0; }
.prow-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.prow-bal { font-size: 13px; color: var(--gold-hi); }
.prow-act { display: flex; gap: 4px; opacity: .55; transition: opacity .2s; }
.prow:hover .prow-act, .prow.is-active .prow-act { opacity: 1; }
.prow-act .btn { width: 30px; padding: 0; }
.rank { display: flex; flex-direction: column; gap: 4px; counter-reset: rk; }
.rank-row { display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 8px; padding: 6px 4px; border-bottom: 1px solid rgba(222,184,92,.08); font-size: 13.5px; }
.rank-row:last-child { border-bottom: 0; }
.rank-pos { font: 400 16px/1 var(--font-display); color: var(--gold); text-align: center; }
.rank-row:first-child .rank-pos { color: var(--gold-hi); text-shadow: 0 0 10px rgba(247,221,143,.6); }
.rank-net { font-size: 13px; }
.picker { display: flex; flex-wrap: wrap; gap: 6px; }
.picker > button { width: 38px; height: 38px; border-radius: 10px; border: 1px solid var(--line); background: rgba(5,6,11,.5); cursor: pointer; font-size: 19px; line-height: 1; transition: border-color .15s, transform .15s; }
.picker > button:hover { transform: translateY(-2px); }
.picker > button.is-on { border-color: var(--gold-hi); box-shadow: 0 0 0 2px rgba(247,221,143,.35); }
.picker.colors > button { width: 30px; height: 30px; border-radius: 50%; }
.hall-foot { grid-column: 1 / -1; text-align: center; color: var(--text-faint); font-size: 12.5px; letter-spacing: .12em; text-transform: uppercase; padding-top: 6px; }
.hall-foot::before { content: "✦"; color: var(--gold-lo); margin-right: 10px; }
.hall-foot::after { content: "✦"; color: var(--gold-lo); margin-left: 10px; }
.set-grid { display: flex; flex-direction: column; gap: 16px; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

@media (max-width: 1100px) {
  .hall-inner { grid-template-columns: 1fr; }
  .hall-side { position: static; }
  .tb-game { display: none; }
}
@media (max-width: 720px) {
  .topbar { gap: 8px; padding: 0 10px; }
  .tb-logo-word { font-size: 20px; }
  .tb-sep { display: none; }
  .tb-select { max-width: 120px; }
  .hall-inner { padding: 14px 12px 24px; }
}
/* =====================================================================================================
   EN LIGNE — écran « Rejoindre la salle » (les portes du salon), barre réseau, voile de reconnexion,
   hall vivant (présences, classement, fil), panneau d'hôte (QR). Rien de tout cela n'apparaît en local.
   ===================================================================================================== */
.join { position: fixed; inset: 0; z-index: 1000; overflow: hidden; display: grid; place-items: center; color: var(--text); }
.join-door { position: absolute; top: 0; bottom: 0; width: 50.2%; z-index: 1; overflow: hidden;
  background:
    radial-gradient(90% 55% at var(--seam) 50%, rgba(222,184,92,.13), transparent 62%),
    repeating-linear-gradient(90deg, rgba(222,184,92,.06) 0 1px, transparent 1px 72px),
    linear-gradient(180deg, #111a40 0%, #0a0e24 48%, #06070f 100%);
  box-shadow: inset 0 0 160px rgba(0,0,0,.65); }
.join-door.l { left: 0; --seam: 100%; border-right: 1px solid rgba(247,221,143,.6); animation: doorInL 1.1s cubic-bezier(.7,0,.25,1) both; }
.join-door.r { right: 0; --seam: 0%; border-left: 1px solid rgba(247,221,143,.6); animation: doorInR 1.1s cubic-bezier(.7,0,.25,1) both; }
.join-door::after { content: ""; position: absolute; top: 0; bottom: 0; width: 10px; background: linear-gradient(90deg, rgba(247,221,143,.0), rgba(247,221,143,.35), rgba(247,221,143,0)); }
.join-door.l::after { right: 0; } .join-door.r::after { left: 0; }
.jd-art { position: absolute; top: 7%; bottom: 7%; left: 10%; right: 10%; border: 1px solid rgba(222,184,92,.24);
  box-shadow: inset 0 0 0 12px rgba(5,6,11,.28), inset 0 0 0 13px rgba(222,184,92,.12); }
.jd-art::before, .jd-art::after { content: ""; position: absolute; left: 50%; width: 360px; height: 180px; margin-left: -180px;
  background: repeating-conic-gradient(from -90deg at 50% 0%, rgba(222,184,92,.26) 0 2.5deg, transparent 2.5deg 9deg);
  -webkit-mask: radial-gradient(circle at 50% 0, #000 0 58%, transparent 59%); mask: radial-gradient(circle at 50% 0, #000 0 58%, transparent 59%); }
.jd-art::before { top: 13px; }
.jd-art::after { bottom: 13px; transform: scaleY(-1); }
.join-glow { position: absolute; top: -10%; bottom: -10%; left: 50%; width: 46vw; margin-left: -23vw; z-index: 2; opacity: 0; pointer-events: none; transform: scaleX(.015);
  background: radial-gradient(closest-side, rgba(255,248,222,.95) 0%, rgba(247,221,143,.55) 35%, rgba(222,184,92,.18) 65%, transparent 100%); mix-blend-mode: screen; }
.join-dust { position: absolute; inset: 0; z-index: 3; pointer-events: none; width: 100%; height: 100%; }
.join-clock { position: absolute; left: 50%; top: 50%; z-index: 3; width: min(98vh, 1000px); aspect-ratio: 1; transform: translate(-50%, -50%); opacity: .2; pointer-events: none; animation: clockIn 2s ease both; }
.join-clock svg { display: block; width: 100%; height: 100%; }
.ck-ring { fill: none; stroke: var(--gold); stroke-width: 2.5; }
.ck-ring2 { fill: none; stroke: rgba(222,184,92,.55); stroke-width: 1; }
.ck-ticks line { stroke: var(--gold); }
.ck-nums text { fill: var(--gold-hi); font: 400 34px/1 var(--font-display); text-anchor: middle; letter-spacing: .04em; }
.ck-fan path { stroke: rgba(222,184,92,.3); stroke-width: 1; }
.ck-hour, .ck-min, .ck-sec { transform-box: view-box; transform-origin: 50% 50%; }
.ck-hour { transform: rotate(359.5deg); transition: transform .7s cubic-bezier(.3,1.6,.5,1); }
.ck-hour path { stroke: var(--gold-hi); stroke-width: 11; stroke-linecap: round; }
.ck-hour circle, .ck-min path + path { fill: var(--gold-hi); }
.ck-min { transform: rotate(354deg); transition: transform .55s cubic-bezier(.3,1.8,.5,1); }
.ck-min path:first-child { stroke: var(--gold-hi); stroke-width: 6; stroke-linecap: round; }
.ck-sec { animation: ckSec 60s steps(60) infinite; }
.ck-sec path { stroke: #ff5a67; stroke-width: 2.5; stroke-linecap: round; }
.ck-hub { fill: var(--gold); stroke: #0a0d18; stroke-width: 3; }
/* FINITIONS (S4.8a) : la scène défile en hauteur, jamais en largeur : la lueur derrière le titre (.join-head::before, 170 % de large) la
   débordait sous 765 px de large, et le téléphone la faisait glisser de côté sous le doigt (rien ne déborde sur grand écran) */
.join-stage { position: relative; z-index: 5; display: flex; flex-direction: column; align-items: center; gap: 16px; width: 100%; max-height: 100vh; overflow: hidden auto; padding: 22px 16px; scrollbar-width: none; }
.join-head { position: relative; text-align: center; }
.join-head::before { content: ""; position: absolute; left: 50%; top: 50%; width: 170%; height: 230%; transform: translate(-50%, -50%); z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(7,9,22,.96) 0%, rgba(7,9,22,.9) 38%, rgba(7,9,22,.55) 66%, rgba(7,9,22,.18) 86%, transparent 100%); }
.join-kicker { font: 600 12px/1 var(--font-ui); letter-spacing: .55em; padding-left: .55em; text-transform: uppercase; color: var(--gold); animation: fadeDown .9s ease both .15s; }
.join-title { margin: 10px 0 0; font: 400 clamp(76px, 9.5vw, 138px)/.92 var(--font-display); letter-spacing: .16em; padding-left: .16em; filter: drop-shadow(0 0 26px rgba(247,221,143,.22)); animation: titleGlow 5s ease-in-out infinite 2s; }
.join-title span { display: inline-block; background: linear-gradient(180deg, #fff7da 0%, var(--gold-hi) 34%, var(--gold) 62%, var(--gold-lo) 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: jLetter 1s cubic-bezier(.2,.9,.3,1.15) both; animation-delay: calc(.3s + var(--i) * .075s); }
.join-sub { margin-top: 12px; font: 400 17px/1.4 var(--font-ui); color: var(--text-dim); letter-spacing: .05em; animation: fadeDown .9s ease both .8s; }
.join-sub em { font-style: normal; color: var(--gold-hi); }
.join-foot { font: 600 11px/1 var(--font-ui); letter-spacing: .3em; text-transform: uppercase; color: var(--text-faint); animation: fadeDown 1s ease both 1.4s; }
.join-foot::before, .join-foot::after { content: "✦"; color: var(--gold-lo); margin: 0 10px; }
/* la carte d'invitation */
.jc-card { position: relative; width: min(800px, 100%); display: grid; grid-template-columns: 236px minmax(0, 1fr); gap: 28px; padding: 26px 30px 24px;
  border-radius: 6px; border: 1px solid var(--line-strong);
  background: radial-gradient(120% 90% at 0% 0%, rgba(222,184,92,.10), transparent 55%), linear-gradient(180deg, rgba(22,28,62,.95), rgba(8,10,22,.97));
  box-shadow: 0 0 0 6px rgba(5,6,11,.85), 0 0 0 7px rgba(222,184,92,.38), 0 30px 80px rgba(0,0,0,.7), 0 0 120px rgba(222,184,92,.10);
  animation: cardRise 1s cubic-bezier(.2,.9,.3,1) both .6s; }
.jc-corner { position: absolute; width: 26px; height: 26px; border: 0 solid var(--gold); pointer-events: none; }
.jc-corner::after { content: ""; position: absolute; width: 9px; height: 9px; border: 0 solid var(--gold-lo); }
.jc-corner.tl { top: 8px; left: 8px; border-top-width: 2px; border-left-width: 2px; } .jc-corner.tl::after { top: 4px; left: 4px; border-top-width: 1px; border-left-width: 1px; }
.jc-corner.tr { top: 8px; right: 8px; border-top-width: 2px; border-right-width: 2px; } .jc-corner.tr::after { top: 4px; right: 4px; border-top-width: 1px; border-right-width: 1px; }
.jc-corner.bl { bottom: 8px; left: 8px; border-bottom-width: 2px; border-left-width: 2px; } .jc-corner.bl::after { bottom: 4px; left: 4px; border-bottom-width: 1px; border-left-width: 1px; }
.jc-corner.br { bottom: 8px; right: 8px; border-bottom-width: 2px; border-right-width: 2px; } .jc-corner.br::after { bottom: 4px; right: 4px; border-bottom-width: 1px; border-right-width: 1px; }
.jc-left { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; text-align: center; padding: 6px 18px 6px 0; border-right: 1px solid var(--line); }
.jc-ticket { display: flex; align-items: center; gap: 10px; font: 600 11px/1 var(--font-ui); letter-spacing: .4em; text-transform: uppercase; color: var(--gold); }
.jc-ticket::before, .jc-ticket::after { content: ""; width: 26px; height: 1px; background: var(--gold-lo); }
.jc-medal { --pc: var(--gold); position: relative; width: 148px; height: 148px; border-radius: 50%; display: grid; place-items: center; margin: 10px 0 18px;
  background: radial-gradient(circle at 36% 30%, color-mix(in srgb, var(--pc) 55%, #fff) 0%, color-mix(in srgb, var(--pc) 45%, #0a0d18) 45%, #0a0d18 100%);
  box-shadow: 0 0 0 3px var(--pc), 0 0 0 10px rgba(5,6,11,.92), 0 0 0 11px rgba(222,184,92,.55), 0 0 60px color-mix(in srgb, var(--pc) 45%, transparent);
  transition: box-shadow .35s, background .35s; }
.jc-medal::before { content: ""; position: absolute; inset: -28px; border-radius: 50%; z-index: -1;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--pc) 40%, transparent) 0 4deg, transparent 4deg 12deg);
  -webkit-mask: radial-gradient(circle, transparent 0 52%, #000 53% 64%, transparent 72%); mask: radial-gradient(circle, transparent 0 52%, #000 53% 64%, transparent 72%);
  animation: sunSpin calc(40s * var(--anim-k, 1)) linear infinite; }
.jc-medal-e { font-size: 74px; line-height: 1; filter: drop-shadow(0 6px 10px rgba(0,0,0,.45)); }
.jc-medal.pop .jc-medal-e { animation: medalPop .45s cubic-bezier(.2,.9,.3,1.6); }
.jc-who { max-width: 100%; font: 400 25px/1.1 var(--font-display); letter-spacing: .04em; color: var(--gold-hi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jc-who.is-empty { color: var(--text-faint); font-size: 19px; }
.jc-hint { font-size: 12.5px; color: var(--text-dim); line-height: 1.4; }
.jc-hint b { color: var(--gold-hi); font-weight: 600; }
.jc-right { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.jc-field { display: flex; flex-direction: column; gap: 8px; }
.jc-field > .label { font: 600 11px/1 var(--font-ui); letter-spacing: .16em; text-transform: uppercase; color: var(--text-dim); }
.pin { display: flex; gap: 10px; }
.pin-d { width: 58px; height: 66px; padding: 0; text-align: center; font-size: 34px; font-weight: 700; color: var(--gold-hi); caret-color: var(--gold);
  border-radius: 10px; border: 1px solid var(--line-strong); outline: none;
  background: linear-gradient(180deg, rgba(3,4,9,.92), rgba(24,30,62,.75));
  box-shadow: inset 0 3px 10px rgba(0,0,0,.65), 0 1px 0 rgba(247,221,143,.14);
  transition: border-color .2s, box-shadow .2s, transform .15s;
  animation: pinIn .6s cubic-bezier(.2,.9,.3,1.3) both; animation-delay: calc(1s + var(--i) * .08s); }
.pin-d:focus { border-color: var(--gold-hi); box-shadow: inset 0 3px 10px rgba(0,0,0,.65), 0 0 0 3px rgba(222,184,92,.22), 0 0 24px rgba(222,184,92,.25); transform: translateY(-2px); }
.pin.is-bad .pin-d, .jc-name.is-bad { border-color: var(--lose); }
.pin.is-bad, .jc-name.is-bad { animation: shake .45s cubic-bezier(.36,.07,.19,.97) both; }
/* sprint 3 : 6 cases (code de 6 chiffres) à peu près dans la place des 4 d'avant ; sur un écran étroit elles rétrécissent (34 px au
   moins), jamais de défilement */
.pin.is-6 { gap: 8px; }
.pin.is-6 .pin-d { flex: 0 1 52px; min-width: 34px; font-size: 31px; }
.pin.is-redessine .pin-d { animation-delay: calc(var(--i) * .05s); }   /* 4 → 6 cases après un refus : sans le délai d'entrée de l'écran */
.jc-name { height: 46px; font-size: 17px; font-weight: 600; letter-spacing: .02em; }
.jc-avs { display: grid; grid-template-columns: repeat(8, 1fr); gap: 7px; }
.jc-av { height: 42px; border-radius: 11px; border: 1px solid var(--line); background: rgba(5,6,11,.55); font-size: 22px; line-height: 1; cursor: pointer;
  transition: transform .15s, border-color .15s, background .15s, box-shadow .15s; animation: avIn .45s cubic-bezier(.2,.9,.3,1.5) both; animation-delay: calc(1.05s + var(--i) * .025s); }
.jc-av:hover { transform: translateY(-3px); border-color: var(--line-strong); background: rgba(222,184,92,.08); }
.jc-av.is-on { border-color: var(--gold-hi); background: rgba(222,184,92,.16); box-shadow: 0 0 0 2px rgba(247,221,143,.3), 0 6px 18px rgba(222,184,92,.25); transform: translateY(-2px) scale(1.06); }
.jc-cols { display: flex; flex-wrap: wrap; gap: 10px; }
.jc-col { width: 32px; height: 32px; border-radius: 50%; border: 0; cursor: pointer; background: var(--c); box-shadow: inset 0 -3px 6px rgba(0,0,0,.35), 0 0 0 2px rgba(5,6,11,.9); transition: transform .15s, box-shadow .2s; }
.jc-col:hover { transform: scale(1.12); }
.jc-col.is-on { box-shadow: inset 0 -3px 6px rgba(0,0,0,.35), 0 0 0 3px #0a0d18, 0 0 0 5px var(--c), 0 0 18px var(--c); transform: scale(1.08); }
.jc-msg { min-height: 20px; margin-top: -2px; font-size: 13.5px; font-weight: 600; color: var(--lose); }
.jc-msg.show { animation: msgIn .35s ease both; }
.jc-resume { padding: 12px 14px; border-radius: 12px; border: 1px solid var(--line-strong); background: rgba(222,184,92,.08); display: flex; flex-direction: column; gap: 10px; animation: msgIn .35s ease both; }
.jc-resume[hidden] { display: none; }
.jc-resume-t { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.jc-actions { margin-top: 2px; }
.jc-go { position: relative; width: 100%; overflow: hidden; height: 54px; font-size: 16px; letter-spacing: .22em; }
.jc-go::after { content: ""; position: absolute; top: -10%; bottom: -10%; left: -60%; width: 38%; transform: skewX(-22deg);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.65), transparent); animation: sweep 3.6s ease-in-out infinite 2.2s; }
.jc-again { display: block; margin: 10px auto 0; padding: 4px 8px; border: 0; background: none; cursor: pointer; font: 500 13px/1.3 var(--font-ui); color: var(--text-dim); letter-spacing: .02em; transition: color .2s; }
.jc-again b { color: var(--gold-hi); font-weight: 600; }
.jc-again:hover { color: var(--text); text-decoration: underline; text-decoration-color: var(--gold-lo); text-underline-offset: 3px; }
.jc-card.is-busy .jc-go { opacity: .75; }
.jc-card.is-busy .jc-go::after { animation-duration: .9s; animation-delay: 0s; }
.jc-wait { position: relative; z-index: 5; display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 26px 34px; border-radius: 16px; border: 1px solid var(--line-strong);
  background: rgba(8,10,22,.9); box-shadow: 0 0 0 6px rgba(5,6,11,.8), 0 0 0 7px rgba(222,184,92,.3), var(--shadow-2); animation: cardRise .6s ease both .2s; }
.jc-wait[hidden], .jc-card[hidden] { display: none; }
.jc-wait-ring { width: 54px; height: 54px; border-radius: 50%; border: 3px solid rgba(222,184,92,.18); border-top-color: var(--gold-hi); animation: spin .9s linear infinite; }
.jc-wait-t { font: 400 20px/1.2 var(--font-display); letter-spacing: .06em; color: var(--gold-hi); }
/* ouverture des portes (entrée réussie) et fondu (reprise) */
.join.is-opening, .join.is-leaving { pointer-events: none; }
.join.is-opening .join-stage { animation: stageOut .5s cubic-bezier(.5,0,.8,.4) forwards; }
.join.is-opening .join-door.l { animation: doorOutL 1.2s cubic-bezier(.75,0,.2,1) .3s both; }
.join.is-opening .join-door.r { animation: doorOutR 1.2s cubic-bezier(.75,0,.2,1) .3s both; }
.join.is-opening .join-glow { animation: glowBurst 1.3s ease .15s both; }
.join.is-opening .join-clock { animation: clockOut 1.3s ease .2s both; }
.join.is-opening .ck-min, .join.is-opening .ck-hour { transform: rotate(360deg); }
.join.is-opening .join-dust { animation: fadeOut .8s ease .6s both; }
.join.is-leaving { animation: fadeOut .42s ease both; }
@keyframes doorInL { from { transform: translateX(-101%); } }
@keyframes doorInR { from { transform: translateX(101%); } }
@keyframes doorOutL { from { transform: none; } to { transform: translateX(-102%); } }
@keyframes doorOutR { from { transform: none; } to { transform: translateX(102%); } }
@keyframes glowBurst { 0% { opacity: 0; transform: scaleX(.015); } 20% { opacity: 1; transform: scaleX(.08); } 55% { opacity: .9; transform: scaleX(1); } 100% { opacity: 0; transform: scaleX(2.4); } }
@keyframes clockIn { from { opacity: 0; transform: translate(-50%, -50%) scale(.9) rotate(-8deg); } }
@keyframes clockOut { 0% { opacity: .2; } 25% { opacity: .55; transform: translate(-50%, -50%) scale(1); } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.25); } }
@keyframes ckSec { to { transform: rotate(360deg); } }
@keyframes jLetter { from { opacity: 0; transform: translateY(-34px) scale(1.3); filter: blur(10px); } }
@keyframes titleGlow { 50% { filter: drop-shadow(0 0 34px rgba(247,221,143,.42)); } }
@keyframes fadeDown { from { opacity: 0; transform: translateY(-10px); } }
@keyframes fadeOut { to { opacity: 0; } }
@keyframes cardRise { from { opacity: 0; transform: translateY(34px) scale(.97); } }
@keyframes stageOut { to { opacity: 0; transform: scale(.94); filter: blur(4px); } }
@keyframes pinIn { from { opacity: 0; transform: rotateX(90deg) translateY(-8px); } }
@keyframes avIn { from { opacity: 0; transform: scale(.4); } }
@keyframes medalPop { 0% { transform: scale(.5) rotate(-12deg); } 70% { transform: scale(1.12) rotate(3deg); } 100% { transform: none; } }
@keyframes sweep { 0% { left: -60%; } 55%, 100% { left: 130%; } }
@keyframes shake { 10%, 90% { transform: translateX(-2px); } 20%, 80% { transform: translateX(4px); } 30%, 50%, 70% { transform: translateX(-7px); } 40%, 60% { transform: translateX(7px); } }
@keyframes msgIn { from { opacity: 0; transform: translateY(-4px); } }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- barre du haut en ligne ---------- */
.tb-count { color: var(--text-faint); font-weight: 600; letter-spacing: .14em; }
.net-pill { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 12px 0 11px; border-radius: 999px; border: 1px solid var(--line); background: rgba(5,6,11,.6); font-size: 12.5px; color: var(--text-dim); white-space: nowrap; }
.np-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--text-faint); }
.net-pill[data-s=ok] .np-dot { background: var(--win); box-shadow: 0 0 10px var(--win); animation: npPulse 2.4s ease-in-out infinite; }
.net-pill[data-s=lent] .np-dot { background: var(--warn); box-shadow: 0 0 10px var(--warn); }
.net-pill[data-s=wait] { border-color: rgba(255,181,71,.45); color: var(--warn); }
.net-pill[data-s=wait] .np-dot { background: var(--warn); animation: npBlink .8s ease-in-out infinite; }
.net-pill[data-s=off] { border-color: rgba(255,90,103,.45); color: var(--lose); }
.net-pill[data-s=off] .np-dot { background: var(--lose); }
@keyframes npPulse { 50% { box-shadow: 0 0 2px var(--win); opacity: .7; } }
@keyframes npBlink { 50% { opacity: .2; } }
.tb-host { color: var(--gold-hi); border-color: var(--line-strong); }
.tb-me { --pc: var(--gold); display: inline-flex; align-items: center; gap: 9px; height: 42px; padding: 0 4px 0 5px; border-radius: 999px; cursor: pointer; color: var(--text);
  border: 1px solid color-mix(in srgb, var(--pc) 50%, transparent); background: color-mix(in srgb, var(--pc) 10%, rgba(5,6,11,.72)); transition: border-color .2s, background .2s; }
.tb-me:hover { border-color: var(--pc); background: color-mix(in srgb, var(--pc) 18%, rgba(5,6,11,.72)); }
.tb-me-av { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; font-size: 18px; flex: none; background: color-mix(in srgb, var(--pc) 28%, #0a0d18); box-shadow: 0 0 0 1.5px var(--pc); }
.tb-me-name { font-weight: 600; font-size: 14px; max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tb-me .tb-balance { height: 34px; }
body.net-down .topbar { border-bottom-color: rgba(255,90,103,.7); }

/* ---------- voile de reconnexion ---------- */
.net-veil { position: fixed; left: 0; right: 0; top: var(--topbar-h); bottom: 0; z-index: 960; display: grid; place-items: center; opacity: 0; pointer-events: none;
  background: radial-gradient(60% 50% at 50% 45%, rgba(10,13,24,.55), rgba(3,4,8,.8)); backdrop-filter: blur(3px) saturate(.6); transition: opacity .35s; }
.net-veil.show { opacity: 1; pointer-events: auto; }
.nv-card { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 28px 40px 24px; border-radius: 18px; text-align: center;
  border: 1px solid rgba(255,90,103,.45); background: linear-gradient(180deg, rgba(30,14,24,.95), rgba(10,8,16,.96));
  box-shadow: 0 0 0 6px rgba(5,6,11,.8), 0 0 0 7px rgba(255,90,103,.25), var(--shadow-2); transform: translateY(8px); transition: transform .35s; }
.net-veil.show .nv-card { transform: none; }
.nv-ring { width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center; border: 2px solid rgba(222,184,92,.2); border-top-color: var(--gold-hi); animation: spin 1.1s linear infinite; }
.nv-ring span { color: var(--gold-hi); font-size: 20px; animation: spin 1.1s linear infinite reverse; }
.nv-t { font: 400 24px/1.1 var(--font-display); letter-spacing: .06em; color: #ffd9dc; }
.nv-s { font-size: 14px; color: var(--text-dim); }
.nv-dots { display: flex; gap: 6px; }
.nv-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); animation: npBlink 1s ease-in-out infinite; }
.nv-dots i:nth-child(2) { animation-delay: .2s; } .nv-dots i:nth-child(3) { animation-delay: .4s; }

/* ---------- hall vivant ---------- */
.av { --pc: var(--gold); display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; flex: none; font-size: 16px; line-height: 1;
  background: color-mix(in srgb, var(--pc) 30%, #0a0d18); box-shadow: 0 0 0 1.5px var(--pc), 0 0 0 3px rgba(5,6,11,.92); }
.av-sm { width: 26px; height: 26px; font-size: 14px; }
.av-xs { width: 23px; height: 23px; font-size: 12.5px; }
.av-more { font: 700 10px/1 var(--font-num); color: var(--text); --pc: var(--line-strong); }
.hero-live { display: inline-flex; align-items: center; gap: 11px; margin-top: 16px; min-height: 36px; padding: 5px 14px 5px 13px; border-radius: 999px; border: 1px solid var(--line-strong); background: rgba(5,6,11,.6); font: 600 13px/1 var(--font-ui); letter-spacing: .08em; color: var(--text); }
.hl-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--win); box-shadow: 0 0 10px var(--win); animation: npPulse 2.4s ease-in-out infinite; }
.hl-avs { display: inline-flex; padding-left: 6px; }
.hl-avs .av { margin-left: -6px; animation: seatIn .45s cubic-bezier(.2,.9,.3,1.5) both; }
.gcard-seats { display: inline-flex; align-items: center; margin-left: auto; padding-left: 6px; }
.gcard-seats .av { margin-left: -6px; animation: seatIn .45s cubic-bezier(.2,.9,.3,1.5) both; animation-delay: calc(var(--k, 0) * 70ms); }
.gcard.has-players { border-color: color-mix(in srgb, var(--accent) 65%, transparent); }
.gcard.has-players .gcard-icon::after { content: ""; position: absolute; top: -4px; right: -4px; width: 11px; height: 11px; border-radius: 50%; background: var(--win); border: 2px solid #0a0d18; box-shadow: 0 0 10px var(--win); animation: npPulse 2.4s ease-in-out infinite; }
.gcard.is-soon { cursor: not-allowed; filter: saturate(.35) brightness(.72); }
.gcard.is-soon:hover { transform: none; box-shadow: none; border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.gcard.is-soon .gcard-go { color: var(--text-faint); }
@keyframes seatIn { from { opacity: 0; transform: scale(.3) translateY(6px); } }
.plist-live .prow { position: relative; }
.plist-live .prow-av { position: relative; }
.prow-dot { position: absolute; right: -3px; bottom: -3px; width: 11px; height: 11px; border-radius: 50%; background: var(--win); border: 2px solid #0a0d18; box-shadow: 0 0 8px var(--win); }
.prow.is-off { opacity: .48; }
.prow.is-off .prow-dot { background: var(--text-faint); box-shadow: none; }
.prow-where { font-size: 12px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.prow-where.is-table { color: var(--gold); }
.prow-where.flash { animation: whereFlash 1.3s ease; }
.plist-live .prow-bal { font-size: 13.5px; font-weight: 700; color: var(--gold-hi); flex: none; }
.prow-crown { margin-left: 6px; font-size: 12px; }
.prow-me { margin-left: 7px; font-size: 9px; padding: 0 6px; vertical-align: 2px; }
.prow.is-new { animation: rowIn .6s cubic-bezier(.2,.9,.3,1.3) both; }
.prow.is-gone { animation: rowOut .38s ease forwards; }
@keyframes rowIn { from { opacity: 0; transform: translateX(22px) scale(.96); background: rgba(222,184,92,.18); } }
@keyframes rowOut { to { opacity: 0; transform: translateX(-18px); } }
@keyframes whereFlash { 0% { color: var(--gold-hi); text-shadow: 0 0 10px rgba(247,221,143,.8); } }
.rank-row.is-me { background: color-mix(in srgb, var(--pc, var(--gold)) 10%, transparent); border-radius: 10px; }
.rank-who { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 9px; align-items: center; min-width: 0; }
.rank-who .av { grid-row: span 2; }
.rank-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-sub { font-size: 11.5px; }
.rank-row.top1 .rank-pos { color: var(--gold-hi); font-size: 19px; text-shadow: 0 0 12px rgba(247,221,143,.75); }
.rank-row.top2 .rank-pos { color: #dcdce8; }
.rank-row.top3 .rank-pos { color: #d69a5f; }
.rank-row.is-up { animation: rankUp 1.4s ease; }
.rank-row.is-up .rank-name::after { content: " ▲"; color: var(--win); font-size: 10px; animation: fadeOut 1.4s ease 1s both; }
@keyframes rankUp { 0% { background: rgba(62,224,143,.22); box-shadow: inset 3px 0 0 var(--win); } 100% { background: transparent; box-shadow: inset 3px 0 0 transparent; } }
.feed { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.feed-row { display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 8px; padding: 5px 2px; border-bottom: 1px solid rgba(222,184,92,.07); }
.feed-row:last-child { border-bottom: 0; }
.feed-row.is-new { animation: rowIn .55s ease both; }
.feed-time { color: var(--gold-lo); font-size: 12px; }
.feed-empty { font-size: 12.5px; }

/* ---------- panneau d'hôte ---------- */
.hp { display: flex; flex-direction: column; gap: 16px; }
.hp-invite { position: relative; padding: 14px 16px 14px; border-radius: 14px; border: 1px solid var(--line-strong);
  background: radial-gradient(120% 140% at 0% 0%, rgba(222,184,92,.14), transparent 60%), rgba(5,6,11,.55); box-shadow: inset 0 1px 0 rgba(247,221,143,.08); }
.hp-invite-k { font: 600 11px/1 var(--font-ui); letter-spacing: .18em; text-transform: uppercase; color: var(--gold); margin-bottom: 8px; }
.hp-big { font-size: clamp(20px, 2.3vw, 27px); font-weight: 700; line-height: 1.15; color: var(--gold-hi); letter-spacing: .01em; word-break: break-all; user-select: all; text-shadow: 0 0 18px rgba(247,221,143,.25); }
.hp-hint { margin-top: 4px; font-size: 12.5px; color: var(--text-dim); }
.hp-invite-row { margin-top: 12px; flex-wrap: wrap; gap: 8px; }
.hp-which .seg { flex-wrap: wrap; }
.hp-which .seg > button { height: 30px; padding: 0 11px; font-size: 12px; }
.hp-grid { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 22px; align-items: start; }
.hp-left { display: flex; flex-direction: column; gap: 12px; }
.hp-qr-frame { padding: 10px; border-radius: 16px; background: linear-gradient(145deg, var(--gold-hi), var(--gold) 45%, var(--gold-lo)); box-shadow: 0 12px 34px rgba(0,0,0,.55), 0 0 44px rgba(222,184,92,.28); animation: popIn .4s cubic-bezier(.2,.9,.3,1.2); }
.hp-qr { border-radius: 8px; overflow: hidden; line-height: 0; background: #f7f0dc; min-height: 120px; display: grid; place-items: center; }
.hp-qr svg { display: block; width: 100%; height: auto; }
.hp-left .seg { flex-wrap: wrap; border-radius: 14px; }
.hp-left .seg > button { height: 28px; padding: 0 10px; font-size: 12px; }
.hp-urlrow { gap: 8px; }
.hp-url { flex: 1; height: 34px; font-size: 12px; }
.hp-pin { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.hp-pin .label { font: 600 11px/1.2 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); }
.hp-pin-v { display: inline-flex; gap: 6px; }
.hp-pin-v b { width: 38px; height: 46px; display: grid; place-items: center; font-size: 26px; color: var(--gold-hi); border: 1px solid var(--line-strong); border-radius: 8px; background: rgba(5,6,11,.75); box-shadow: inset 0 2px 8px rgba(0,0,0,.6); }
.hp-pin-v.is-6 { gap: 4px; }   /* sprint 3 : 6 chiffres sous le QR code, sans déborder sur la colonne voisine */
.hp-pin-v.is-6 b { width: 27px; height: 40px; font-size: 21px; border-radius: 7px; }
.hp-right { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.hp-players { display: flex; flex-direction: column; gap: 6px; max-height: 250px; overflow: auto; scrollbar-width: thin; }
.hp-prow { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 10px; border: 1px solid var(--line); background: rgba(5,6,11,.35); }
.hp-prow.is-off { opacity: .55; }
.hp-prow.is-new { animation: rowIn .6s cubic-bezier(.2,.9,.3,1.3) both; }
.hp-warn { padding: 8px 10px; border-radius: 10px; border: 1px solid rgba(255,181,71,.45); background: rgba(255,181,71,.08); color: var(--warn); font-size: 12.5px; line-height: 1.35; }
.hp-warn[hidden] { display: none; }
.hp-invite .hp-warn { margin-top: 10px; }
.hp-players { max-height: 190px; }

/* ---------- écran d'invitation plein écran (écran projeté) ---------- */
.invite-screen { position: fixed; inset: 0; z-index: 1050; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3vh; padding: 4vh 4vw;
  background: radial-gradient(1200px 800px at 50% 40%, #16204a 0%, #0a0d1c 55%, #04050a 100%); animation: fadeIn .45s ease both; }
.invite-screen.is-leaving { animation: fadeOut .4s ease both; pointer-events: none; }
.iv-sun { position: absolute; left: 50%; top: 42%; width: 170vmax; height: 170vmax; margin: -85vmax 0 0 -85vmax; border-radius: 50%; pointer-events: none;
  background: repeating-conic-gradient(from 0deg, rgba(222,184,92,.09) 0 3deg, transparent 3deg 10deg);
  -webkit-mask: radial-gradient(circle, #000 8%, transparent 55%); mask: radial-gradient(circle, #000 8%, transparent 55%); animation: sunSpin calc(160s * var(--anim-k, 1)) linear infinite; }
.iv-x { position: absolute; top: 18px; right: 22px; z-index: 3; width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--line-strong); background: rgba(5,6,11,.6); color: var(--text-dim); font-size: 26px; line-height: 1; cursor: pointer; }
.iv-x:hover { color: var(--text); border-color: var(--gold); }
.iv-stage { position: relative; z-index: 2; display: flex; align-items: center; gap: 5vw; }
.iv-qr { padding: 14px; border-radius: 22px; background: linear-gradient(145deg, var(--gold-hi), var(--gold) 45%, var(--gold-lo)); box-shadow: 0 30px 80px rgba(0,0,0,.6), 0 0 90px rgba(222,184,92,.3); animation: cardRise .8s cubic-bezier(.2,.9,.3,1) both .1s; }
.iv-qr .hp-qr { width: min(46vh, 440px); border-radius: 12px; }
.iv-main { display: flex; flex-direction: column; align-items: flex-start; gap: 1.2vh; max-width: 52vw; animation: cardRise .8s cubic-bezier(.2,.9,.3,1) both .25s; }
.iv-k { font: 600 clamp(12px, 1.1vw, 16px)/1 var(--font-ui); letter-spacing: .5em; text-transform: uppercase; color: var(--gold); }
.iv-title { font: 400 clamp(44px, 5.6vw, 96px)/1 var(--font-display); letter-spacing: .06em; background: linear-gradient(180deg, #fff7da 0%, var(--gold-hi) 35%, var(--gold) 62%, var(--gold-lo) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; margin-bottom: 1.4vh; }
.iv-step { font: 600 clamp(12px, 1vw, 15px)/1 var(--font-ui); letter-spacing: .2em; text-transform: uppercase; color: var(--text-dim); margin-top: 1vh; }
.iv-url { font-size: clamp(24px, 2.6vw, 50px); font-weight: 700; color: #fff4cf; letter-spacing: .01em; text-shadow: 0 0 30px rgba(247,221,143,.35); }
.iv-url span { white-space: nowrap; }
.iv-url span + span { color: var(--gold-hi); }
.iv-pin { display: flex; gap: 1.2vw; }
.iv-pin b { display: grid; place-items: center; width: clamp(56px, 5.4vw, 104px); height: clamp(68px, 6.6vw, 128px); font-size: clamp(40px, 4.4vw, 84px); color: var(--gold-hi); border-radius: 14px; border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, rgba(3,4,9,.92), rgba(24,30,62,.75)); box-shadow: inset 0 4px 14px rgba(0,0,0,.65), 0 0 30px rgba(222,184,92,.12);
  animation: pinIn .7s cubic-bezier(.2,.9,.3,1.3) both; animation-delay: calc(.45s + var(--k, 0) * .1s); }
.iv-alt { margin-top: 1.4vh; font-size: clamp(13px, 1.1vw, 18px); color: var(--text-dim); }
.iv-alt .num { color: var(--gold); }
.iv-foot { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 1.6vh; }
.iv-count { font: 600 clamp(13px, 1.1vw, 17px)/1 var(--font-ui); letter-spacing: .24em; text-transform: uppercase; color: var(--gold); }
.iv-avs { display: flex; flex-wrap: wrap; justify-content: center; gap: 1.6vw; min-height: 90px; }
.iv-av { --pc: var(--gold); display: flex; flex-direction: column; align-items: center; gap: 8px; animation: ivPop .7s cubic-bezier(.2,.9,.3,1.6) both; animation-delay: calc(var(--k, 0) * 60ms); }
.iv-av-e { width: clamp(52px, 4.4vw, 80px); height: clamp(52px, 4.4vw, 80px); border-radius: 50%; display: grid; place-items: center; font-size: clamp(28px, 2.4vw, 44px);
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--pc) 55%, #fff) 0%, color-mix(in srgb, var(--pc) 40%, #0a0d18) 50%, #0a0d18 100%);
  box-shadow: 0 0 0 3px var(--pc), 0 0 0 7px rgba(5,6,11,.9), 0 0 30px color-mix(in srgb, var(--pc) 55%, transparent); }
.iv-av-n { font-weight: 600; font-size: clamp(13px, 1vw, 16px); color: var(--text); }
.iv-av.is-gone { animation: fadeOut .4s ease both; }
@keyframes ivPop { 0% { opacity: 0; transform: scale(.2) translateY(30px); } 60% { opacity: 1; transform: scale(1.15); } 100% { transform: none; } }
.hp-pname { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-height: 820px) {
  .join-stage { gap: 12px; padding: 14px 16px; }
  .join-title { font-size: clamp(60px, 8vw, 96px); margin-top: 6px; }
  .join-sub { margin-top: 8px; font-size: 15.5px; }
  .jc-card { padding: 20px 26px 18px; gap: 24px; }
  .jc-right { gap: 11px; }
  .jc-medal { width: 124px; height: 124px; }
  .jc-medal-e { font-size: 60px; }
  .pin-d { width: 52px; height: 58px; font-size: 30px; }
  .jc-av { height: 38px; font-size: 20px; }
  .jc-go { height: 50px; }
}
/* C11 (P2-D, 30/09) : un portable 1366×768 n'offre que 600 à 660 px de haut au navigateur (barre des tâches, onglets) ;
   l'entrée se resserre pour que tout, « Pousser la porte » et le pied compris, tienne sans défiler. */
@media (max-height: 700px) {
  .join-stage { gap: 8px; padding: 8px 16px; }
  .join-title { font-size: clamp(48px, 6.4vw, 76px); margin-top: 4px; }
  .join-sub { margin-top: 4px; font-size: 14.5px; }
  .jc-card { padding: 16px 24px 14px; gap: 20px; }
  .jc-right { gap: 8px; }
  .jc-field { gap: 6px; }
  .jc-medal { width: 104px; height: 104px; margin: 6px 0 12px; }
  .jc-medal-e { font-size: 52px; }
  .pin-d { width: 48px; height: 52px; font-size: 27px; }
  .pin.is-6 .pin-d { flex-basis: 44px; font-size: 25px; }
  .jc-name { height: 40px; font-size: 16px; }
  .jc-av { height: 34px; font-size: 19px; }
  .jc-col { width: 28px; height: 28px; }
  .jc-msg { min-height: 16px; }
  .jc-go { height: 46px; }
  .jc-again { margin-top: 4px; }
}
/* FINITIONS (S4.8a) : au téléphone (≤ 480 px de large), « MINUIT » tient sur UNE ligne. Ses six lettres (inline-block, interlettrage et
   retrait de .16em) font 4,99 fois la taille de police ; la scène laisse 100vw − 32 px. La taille ne fait que DESCENDRE sous celle du
   palier de hauteur (76, 60 ou 48 px, mêmes paliers qu'au-dessus), jamais monter ; même police, même or, même lueur ; au-delà de
   480 px de large, rien ne change. */
@media (max-width: 480px) { .join-title { white-space: nowrap; font-size: min(76px, calc((100vw - 32px) / 5.1)); } }
@media (max-width: 480px) and (max-height: 820px) { .join-title { font-size: min(60px, calc((100vw - 32px) / 5.1)); } }
@media (max-width: 480px) and (max-height: 700px) { .join-title { font-size: min(48px, calc((100vw - 32px) / 5.1)); } }
@media (max-width: 860px) {
  .jc-card { grid-template-columns: 1fr; gap: 16px; }
  .jc-left { flex-direction: row; justify-content: flex-start; border-right: 0; border-bottom: 1px solid var(--line); padding: 0 0 14px; text-align: left; }
  .jc-ticket, .jc-hint { display: none; }
  .jc-medal { width: 76px; height: 76px; margin: 0; }
  .jc-medal::before { display: none; }
  .jc-medal-e { font-size: 40px; }
  .jc-avs { grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 5px; }
  .hp-grid { grid-template-columns: 1fr; }
  .tb-me-name, .tb-count { display: none; }
}
@media (max-width: 480px) {
  /* Sur un téléphone, afficher les champs avant le choix facultatif de l'avatar. */
  .join { height: 100dvh; }
  .join-stage { max-height: 100dvh; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
  .jc-card { display: flex; flex-direction: column; }
  .jc-right { order: -1; }
  .jc-mdp { font-size: 16px; }
}

/* =====================================================================================================
   PASSE BEAUTÉ — le hall en relief (lumière qui glisse sur l'or, poussière d'or, cartes 3D et reflets), transitions
   hall <-> tables (battants art déco), focus clavier visible, barre du haut vivante. Tout s'apaise avec « Animations : réduites ».
   ===================================================================================================== */
/* lumière d'ambiance derrière le hall : peinte une fois sur le fond de la vue (aucun calque, aucun coût par image) */
body[data-route="hall"] .view { background: radial-gradient(36vw 30vh at 26% 40%, rgba(222,184,92,.07), transparent 70%), radial-gradient(30vw 34vh at 76% 74%, rgba(155,107,255,.05), transparent 70%); }
.hall-inner { position: relative; z-index: 1; }

/* héros : cadre art déco aux quatre coins, halo derrière le titre, reflet qui glisse sur l'or */
.hero::before { content: ""; position: absolute; inset: 14px; pointer-events: none; z-index: 1; opacity: .9;
  background:
    linear-gradient(var(--gold), var(--gold)) 0 0 / 34px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) 0 0 / 1px 34px no-repeat,
    linear-gradient(var(--gold), var(--gold)) 100% 0 / 34px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) 100% 0 / 1px 34px no-repeat,
    linear-gradient(var(--gold), var(--gold)) 0 100% / 34px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) 0 100% / 1px 34px no-repeat,
    linear-gradient(var(--gold), var(--gold)) 100% 100% / 34px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) 100% 100% / 1px 34px no-repeat; }
.hero-dust { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
.hero-content { z-index: 2; }
.hero-content::before { content: ""; position: absolute; left: 50%; top: 52%; width: 620px; height: 190px; margin: -95px 0 0 -310px; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(247,221,143,.16), rgba(222,184,92,.05) 55%, transparent); filter: blur(6px); }
.hero-title {
  background: linear-gradient(100deg, transparent 0 42%, rgba(255,251,232,.95) 49%, rgba(255,246,214,.55) 52%, transparent 60% 100%) no-repeat,
    linear-gradient(180deg, #fff6d6 0%, var(--gold-hi) 35%, var(--gold) 60%, var(--gold-lo) 100%);
  background-size: 300% 100%, 100% 100%; background-position: 100% 0, 0 0;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: heroIn .9s cubic-bezier(.2,.8,.2,1) both, goldSweep calc(8s * var(--anim-k, 1)) ease-in-out 1.4s infinite; }
@keyframes goldSweep { 0%, 58% { background-position: 100% 0, 0 0; } 88%, 100% { background-position: 0% 0, 0 0; } }
.hero-kicker { text-shadow: 0 0 18px rgba(222,184,92,.35); }

/* titres de section : losange d'or */
.sec-title { display: inline-flex; align-items: center; gap: 12px; }
.sec-title::before { content: ""; width: 9px; height: 9px; transform: rotate(45deg); flex: none; background: linear-gradient(135deg, var(--gold-hi), var(--gold-lo)); box-shadow: 0 0 10px rgba(247,221,143,.45); }

/* cartes de jeux : relief 3D qui suit la souris, reflet de vitre, cadre intérieur */
.gcard { animation-fill-mode: backwards; transform: perspective(900px) rotateX(calc(var(--ty, 0) * -6deg)) rotateY(calc(var(--tx, 0) * 8deg)) translateY(var(--lift, 0px));
  transition: transform .45s cubic-bezier(.2,.9,.3,1), box-shadow .25s, border-color .25s;
  box-shadow: 0 10px 26px rgba(0,0,0,.34), inset 0 0 0 4px rgba(5,6,11,.35), inset 0 0 0 5px color-mix(in srgb, var(--accent) 14%, transparent), inset 0 1px 0 rgba(255,240,205,.08); }
.gcard.is-tilting { transition: transform .1s linear, box-shadow .25s, border-color .25s; }
.gcard:hover { --lift: -6px; transform: perspective(900px) rotateX(calc(var(--ty, 0) * -6deg)) rotateY(calc(var(--tx, 0) * 8deg)) translateY(var(--lift, 0px));
  box-shadow: 0 22px 44px rgba(0,0,0,.55), 0 0 34px color-mix(in srgb, var(--accent) 32%, transparent), inset 0 0 0 4px rgba(5,6,11,.3), inset 0 0 0 5px color-mix(in srgb, var(--accent) 30%, transparent); }
.gcard::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0; transition: opacity .35s;
  background: radial-gradient(360px circle at calc(50% + var(--tx, 0) * 50%) calc(50% + var(--ty, 0) * 50%), rgba(255,240,205,.15), transparent 48%),
    linear-gradient(112deg, transparent 38%, rgba(255,244,214,.13) 47%, rgba(255,244,214,.04) 53%, transparent 62%) no-repeat;
  background-size: 100% 100%, 280% 100%; background-position: 0 0, 100% 0; }
.gcard:hover::after { opacity: 1; background-position: 0 0, 0% 0; transition: opacity .35s, background-position 1.1s cubic-bezier(.2,.8,.2,1); }
.gcard-icon { transition: transform .35s cubic-bezier(.2,.9,.3,1.3); }
.gcard:hover .gcard-icon { transform: translate(calc(var(--tx, 0) * -3px), calc(var(--ty, 0) * -3px)) scale(1.06); }
.gcard-name { font-size: 22px; }
.gcard.is-soon::after { display: none; }
/* aperçu vivant (en ligne) : qui est à la table */
.gcard-live { position: relative; display: inline-flex; align-items: center; gap: 7px; font: 600 11.5px/1.2 var(--font-ui); letter-spacing: .06em; color: var(--win); }
.gcard-live::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--win); box-shadow: 0 0 8px var(--win); animation: npPulse 2.4s ease-in-out infinite; flex: none; }
.gcard-live:empty { display: none; }
.prow-duel { width: 30px; padding: 0; flex: none; }
.prow.is-off .prow-duel { display: none; }

/* barre du haut : un reflet parcourt le filet d'or */
/* (le reflet reste DANS la largeur de la barre : un transform qui déborde élargirait la page) ; calque propre = 1 px repeint */
.topbar::before { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; pointer-events: none; will-change: transform;
  background: linear-gradient(90deg, transparent, #fff3c4, transparent) no-repeat; background-size: 24% 100%; background-position: -40% 0;
  animation: tbGlint calc(10s * var(--anim-k, 1)) ease-in-out 2.5s infinite; }
@keyframes tbGlint { 0%, 70% { background-position: -40% 0; } 100% { background-position: 140% 0; } }

/* transition hall <-> tables : deux battants s'ouvrent sur la nouvelle salle (420 ms), sans rien bloquer */
.route-fx { position: fixed; left: 0; right: 0; top: var(--topbar-h); bottom: 0; z-index: 930; pointer-events: none; overflow: hidden; }
.rf-door { position: absolute; top: 0; bottom: 0; width: 50.5%; overflow: hidden; will-change: transform;
  background: radial-gradient(80% 60% at var(--seam) 50%, rgba(222,184,92,.16), transparent 60%), repeating-linear-gradient(90deg, rgba(222,184,92,.07) 0 1px, transparent 1px 64px),
    linear-gradient(180deg, #121b42 0%, #0a0e24 50%, #06070f 100%); box-shadow: inset 0 0 120px rgba(0,0,0,.6); }
.rf-door.l { left: 0; --seam: 100%; border-right: 1px solid rgba(247,221,143,.75); animation: rfL .42s cubic-bezier(.65,0,.35,1) both; }
.rf-door.r { right: 0; --seam: 0%; border-left: 1px solid rgba(247,221,143,.75); animation: rfR .42s cubic-bezier(.65,0,.35,1) both; }
.rf-fan { position: absolute; top: 50%; width: 460px; height: 460px; margin-top: -230px; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(222,184,92,.24) 0 3deg, transparent 3deg 10deg);
  -webkit-mask: radial-gradient(circle, #000 10%, transparent 62%); mask: radial-gradient(circle, #000 10%, transparent 62%); }
.rf-door.l .rf-fan { right: -230px; } .rf-door.r .rf-fan { left: -230px; }
.rf-seam { position: absolute; left: 50%; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: linear-gradient(180deg, transparent, #fff3c4 30%, #fff3c4 70%, transparent);
  box-shadow: 0 0 26px 7px rgba(247,221,143,.5); animation: rfSeam .42s ease-out both; }
@keyframes rfL { 0%, 14% { transform: none; } 100% { transform: translateX(-101%); } }
@keyframes rfR { 0%, 14% { transform: none; } 100% { transform: translateX(101%); } }
@keyframes rfSeam { 0% { opacity: .3; transform: scaleY(.4); } 14% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scaleX(3); } }

/* focus clavier : un double anneau d'or, net sur tous les fonds */
.btn:focus-visible, .gcard:focus-visible, .seg > button:focus-visible, .chip-slot:focus-visible, .tb-logo:focus-visible, .tb-me:focus-visible,
.picker > button:focus-visible, .modal-x:focus-visible, .jc-av:focus-visible, .jc-col:focus-visible, .jc-again:focus-visible, .iv-x:focus-visible {
  outline: 2px solid var(--gold-hi); outline-offset: 3px; box-shadow: 0 0 0 6px rgba(247,221,143,.16); }
.input:focus-visible, .select:focus-visible { outline: none; }
input[type=range]:focus-visible { outline-offset: 5px; border-radius: 999px; }
/* boutons : même pression partout, reflet discret sur les boutons d'or */
.btn-gold { background-size: 100% 100%; }
.btn-gold:not([disabled]):hover { filter: saturate(1.08); }

/* grands écrans : le hall prend de l'ampleur (cartes plus grandes, héros plus haut) */
@media (min-width: 1600px) {
  .hall-inner { max-width: 1520px; grid-template-columns: minmax(0, 1fr) 360px; gap: 28px; padding-top: 26px; }
  .games-grid { grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 18px; }
  .gcard { min-height: 172px; padding: 20px 20px 16px; }
  .gcard-icon { width: 58px; height: 58px; font-size: 34px; }
  .gcard-name { font-size: 25px; }
}
@media (min-height: 950px) { .hero { min-height: 290px; } }
.hp-warn { font-variant-ligatures: none; }

/* gros gain : rayons d'or dessinés dans le canvas de celebrate (core.js), montant qui défile */
.fx-banner-k { background: linear-gradient(180deg, #fff6d6, var(--gold-hi) 40%, var(--gold) 70%, var(--gold-lo)); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: none; filter: drop-shadow(0 3px 0 #4a360c) drop-shadow(0 0 22px rgba(247,221,143,.5)); }
.fx-banner-v { letter-spacing: .02em; }
.fx-banner::before { content: ""; position: absolute; left: 50%; top: 50%; width: 170%; height: 200%; transform: translate(-50%, -50%); z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(5,6,11,.78), rgba(5,6,11,.4) 62%, transparent); }

/* motifs art déco propres à chaque jeu (SVG embarqués), en filigrane à droite de la carte ; ils bougent au survol */
.gcard[data-game]::before { right: -30px; top: auto; bottom: -34px; width: 176px; height: 176px; opacity: .55;
  -webkit-mask: linear-gradient(105deg, transparent 6%, #000 52%); mask: linear-gradient(105deg, transparent 6%, #000 52%);
  background-position: center; background-size: contain; background-repeat: no-repeat; transition: transform .7s cubic-bezier(.2,.9,.3,1), opacity .3s; }
.gcard[data-game]:hover::before { opacity: .78; }
.gcard[data-game="roulette"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath d='M100.0 20.0A80 80 0 0 1 120.7 22.7L114.5 45.9A56 56 0 0 0 100.0 44.0Z' fill='%231fbf75' fill-opacity='.55'/%3E%3Cpath d='M120.7 22.7A80 80 0 0 1 140.0 30.7L128.0 51.5A56 56 0 0 0 114.5 45.9Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M140.0 30.7A80 80 0 0 1 156.6 43.4L139.6 60.4A56 56 0 0 0 128.0 51.5Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M156.6 43.4A80 80 0 0 1 169.3 60.0L148.5 72.0A56 56 0 0 0 139.6 60.4Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M169.3 60.0A80 80 0 0 1 177.3 79.3L154.1 85.5A56 56 0 0 0 148.5 72.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M177.3 79.3A80 80 0 0 1 180.0 100.0L156.0 100.0A56 56 0 0 0 154.1 85.5Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M180.0 100.0A80 80 0 0 1 177.3 120.7L154.1 114.5A56 56 0 0 0 156.0 100.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M177.3 120.7A80 80 0 0 1 169.3 140.0L148.5 128.0A56 56 0 0 0 154.1 114.5Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M169.3 140.0A80 80 0 0 1 156.6 156.6L139.6 139.6A56 56 0 0 0 148.5 128.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M156.6 156.6A80 80 0 0 1 140.0 169.3L128.0 148.5A56 56 0 0 0 139.6 139.6Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M140.0 169.3A80 80 0 0 1 120.7 177.3L114.5 154.1A56 56 0 0 0 128.0 148.5Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M120.7 177.3A80 80 0 0 1 100.0 180.0L100.0 156.0A56 56 0 0 0 114.5 154.1Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M100.0 180.0A80 80 0 0 1 79.3 177.3L85.5 154.1A56 56 0 0 0 100.0 156.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M79.3 177.3A80 80 0 0 1 60.0 169.3L72.0 148.5A56 56 0 0 0 85.5 154.1Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M60.0 169.3A80 80 0 0 1 43.4 156.6L60.4 139.6A56 56 0 0 0 72.0 148.5Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M43.4 156.6A80 80 0 0 1 30.7 140.0L51.5 128.0A56 56 0 0 0 60.4 139.6Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M30.7 140.0A80 80 0 0 1 22.7 120.7L45.9 114.5A56 56 0 0 0 51.5 128.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M22.7 120.7A80 80 0 0 1 20.0 100.0L44.0 100.0A56 56 0 0 0 45.9 114.5Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M20.0 100.0A80 80 0 0 1 22.7 79.3L45.9 85.5A56 56 0 0 0 44.0 100.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M22.7 79.3A80 80 0 0 1 30.7 60.0L51.5 72.0A56 56 0 0 0 45.9 85.5Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M30.7 60.0A80 80 0 0 1 43.4 43.4L60.4 60.4A56 56 0 0 0 51.5 72.0Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M43.4 43.4A80 80 0 0 1 60.0 30.7L72.0 51.5A56 56 0 0 0 60.4 60.4Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cpath d='M60.0 30.7A80 80 0 0 1 79.3 22.7L85.5 45.9A56 56 0 0 0 72.0 51.5Z' fill='%2315161c' fill-opacity='.55'/%3E%3Cpath d='M79.3 22.7A80 80 0 0 1 100.0 20.0L100.0 44.0A56 56 0 0 0 85.5 45.9Z' fill='%23d2323f' fill-opacity='.55'/%3E%3Cg fill='none' stroke='%23deb85c' stroke-opacity='.7'%3E%3Ccircle cx='100' cy='100' r='95' stroke-width='3'/%3E%3Ccircle cx='100' cy='100' r='86' stroke-width='1'/%3E%3Ccircle cx='100' cy='100' r='80' stroke-width='1.4'/%3E%3Ccircle cx='100' cy='100' r='56' stroke-width='1.4'/%3E%3Ccircle cx='100' cy='100' r='16' stroke-width='2.5'/%3E%3Cg stroke-width='3' stroke-linecap='round'%3E%3Cline x1='112.7' y1='112.7' x2='135.4' y2='135.4'/%3E%3Cline x1='87.3' y1='112.7' x2='64.6' y2='135.4'/%3E%3Cline x1='87.3' y1='87.3' x2='64.6' y2='64.6'/%3E%3Cline x1='112.7' y1='87.3' x2='135.4' y2='64.6'/%3E%3C/g%3E%3C/g%3E%3Ccircle cx='100' cy='13' r='5' fill='%23f4ecd8' fill-opacity='.8'/%3E%3C/svg%3E"); }
.gcard[data-game="roulette"]:hover::before { transform: rotate(75deg) scale(1.06); }
.gcard[data-game="blackjack"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg transform='translate(78 104) rotate(-14)'%3E%3Crect x='-38' y='-54' width='76' height='108' rx='9' fill='%23f4ecd8' fill-opacity='.10' stroke='%23deb85c' stroke-opacity='.7' stroke-width='2'/%3E%3Crect x='-31' y='-47' width='62' height='94' rx='5' fill='none' stroke='%23deb85c' stroke-opacity='.35'/%3E%3Cpath d='M0 14C-12 4 -17 -3 -12 -9C-8 -13 -3 -11 0 -6C3 -11 8 -13 12 -9C17 -3 12 4 0 14Z' fill='%23d2323f' fill-opacity='.6'/%3E%3C/g%3E%3Cg transform='translate(122 96) rotate(12)'%3E%3Crect x='-38' y='-54' width='76' height='108' rx='9' fill='%23f4ecd8' fill-opacity='.10' stroke='%23deb85c' stroke-opacity='.7' stroke-width='2'/%3E%3Crect x='-31' y='-47' width='62' height='94' rx='5' fill='none' stroke='%23deb85c' stroke-opacity='.35'/%3E%3Cpath d='M0 -17C9 -7 17 -1 11 8C7 12 2 10 1 7L4 17H-4L-1 7C-2 10 -7 12 -11 8C-17 -1 -9 -7 0 -17Z' fill='%23f4ecd8' fill-opacity='.55' transform='scale(1.3)'/%3E%3C/g%3E%3C/svg%3E"); }
.gcard[data-game="blackjack"]:hover::before { transform: rotate(-6deg) translateY(-6px) scale(1.05); }
.gcard[data-game="crash"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='%23f4ecd8' fill-opacity='.55'%3E%3Ccircle cx='30' cy='40' r='1.6'/%3E%3Ccircle cx='60' cy='22' r='1.2'/%3E%3Ccircle cx='150' cy='150' r='1.4'/%3E%3Ccircle cx='92' cy='60' r='1.0'/%3E%3Ccircle cx='180' cy='110' r='1.5'/%3E%3Ccircle cx='40' cy='110' r='1.1'/%3E%3Ccircle cx='120' cy='30' r='1.3'/%3E%3C/g%3E%3Cpath d='M8 192C80 188 130 158 168 52' fill='none' stroke='%239b6bff' stroke-opacity='.8' stroke-width='4' stroke-linecap='round'/%3E%3Cpath d='M8 192C80 188 130 158 168 52' fill='none' stroke='%23ff4fd8' stroke-opacity='.35' stroke-width='12' stroke-linecap='round'/%3E%3Cg transform='translate(170 46) rotate(22)'%3E%3Cpath d='M0 -22C9 -12 10 4 7 14H-7C-10 4 -9 -12 0 -22Z' fill='%23f4ecd8' fill-opacity='.75'/%3E%3Ccircle cx='0' cy='-4' r='4' fill='%233be8ff' fill-opacity='.9'/%3E%3Cpath d='M-7 8L-14 18L-6 15ZM7 8L14 18L6 15Z' fill='%23ff4fd8' fill-opacity='.8'/%3E%3Cpath d='M-4 16L0 30L4 16Z' fill='%23ffb547' fill-opacity='.85'/%3E%3C/g%3E%3C/svg%3E"); }
.gcard[data-game="crash"]:hover::before { transform: translate(8px, -10px) scale(1.05); }
.gcard[data-game="plinko"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='%23f4ecd8' fill-opacity='.6'%3E%3Ccircle cx='100.0' cy='30' r='3.2'/%3E%3Ccircle cx='88.0' cy='52' r='3.2'/%3E%3Ccircle cx='112.0' cy='52' r='3.2'/%3E%3Ccircle cx='76.0' cy='74' r='3.2'/%3E%3Ccircle cx='100.0' cy='74' r='3.2'/%3E%3Ccircle cx='124.0' cy='74' r='3.2'/%3E%3Ccircle cx='64.0' cy='96' r='3.2'/%3E%3Ccircle cx='88.0' cy='96' r='3.2'/%3E%3Ccircle cx='112.0' cy='96' r='3.2'/%3E%3Ccircle cx='136.0' cy='96' r='3.2'/%3E%3Ccircle cx='52.0' cy='118' r='3.2'/%3E%3Ccircle cx='76.0' cy='118' r='3.2'/%3E%3Ccircle cx='100.0' cy='118' r='3.2'/%3E%3Ccircle cx='124.0' cy='118' r='3.2'/%3E%3Ccircle cx='148.0' cy='118' r='3.2'/%3E%3Ccircle cx='40.0' cy='140' r='3.2'/%3E%3Ccircle cx='64.0' cy='140' r='3.2'/%3E%3Ccircle cx='88.0' cy='140' r='3.2'/%3E%3Ccircle cx='112.0' cy='140' r='3.2'/%3E%3Ccircle cx='136.0' cy='140' r='3.2'/%3E%3Ccircle cx='160.0' cy='140' r='3.2'/%3E%3Ccircle cx='28.0' cy='162' r='3.2'/%3E%3Ccircle cx='52.0' cy='162' r='3.2'/%3E%3Ccircle cx='76.0' cy='162' r='3.2'/%3E%3Ccircle cx='100.0' cy='162' r='3.2'/%3E%3Ccircle cx='124.0' cy='162' r='3.2'/%3E%3Ccircle cx='148.0' cy='162' r='3.2'/%3E%3Ccircle cx='172.0' cy='162' r='3.2'/%3E%3C/g%3E%3Crect x='6.0' y='188' width='20' height='9' rx='2' fill='%23ffb547' fill-opacity='.6'/%3E%3Crect x='30.0' y='188' width='20' height='9' rx='2' fill='%23ff4fd8' fill-opacity='.6'/%3E%3Crect x='54.0' y='188' width='20' height='9' rx='2' fill='%239b6bff' fill-opacity='.6'/%3E%3Crect x='78.0' y='188' width='20' height='9' rx='2' fill='%233be8ff' fill-opacity='.6'/%3E%3Crect x='102.0' y='188' width='20' height='9' rx='2' fill='%233be8ff' fill-opacity='.6'/%3E%3Crect x='126.0' y='188' width='20' height='9' rx='2' fill='%239b6bff' fill-opacity='.6'/%3E%3Crect x='150.0' y='188' width='20' height='9' rx='2' fill='%23ff4fd8' fill-opacity='.6'/%3E%3Crect x='174.0' y='188' width='20' height='9' rx='2' fill='%23ffb547' fill-opacity='.6'/%3E%3Cpath d='M100 8C104 40 84 60 90 88S116 120 112 150' fill='none' stroke='%23ff4fd8' stroke-opacity='.45' stroke-width='3' stroke-dasharray='2 5' stroke-linecap='round'/%3E%3Ccircle cx='112' cy='156' r='7' fill='%23ff4fd8' fill-opacity='.85'/%3E%3C/svg%3E"); }
.gcard[data-game="plinko"]:hover::before { transform: translateY(5px) scale(1.04); }
.gcard[data-game="mines"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='%233be8ff' fill-opacity='.06' stroke='%233be8ff' stroke-opacity='.55' stroke-width='1.6'%3E%3Crect x='22' y='22' width='34' height='34' rx='7'/%3E%3Crect x='62' y='22' width='34' height='34' rx='7'/%3E%3Crect x='102' y='22' width='34' height='34' rx='7'/%3E%3Crect x='142' y='22' width='34' height='34' rx='7'/%3E%3Crect x='22' y='62' width='34' height='34' rx='7'/%3E%3Crect x='62' y='62' width='34' height='34' rx='7'/%3E%3Crect x='102' y='62' width='34' height='34' rx='7'/%3E%3Crect x='142' y='62' width='34' height='34' rx='7'/%3E%3Crect x='22' y='102' width='34' height='34' rx='7'/%3E%3Crect x='62' y='102' width='34' height='34' rx='7'/%3E%3Crect x='102' y='102' width='34' height='34' rx='7'/%3E%3Crect x='142' y='102' width='34' height='34' rx='7'/%3E%3Crect x='22' y='142' width='34' height='34' rx='7'/%3E%3Crect x='62' y='142' width='34' height='34' rx='7'/%3E%3Crect x='102' y='142' width='34' height='34' rx='7'/%3E%3Crect x='142' y='142' width='34' height='34' rx='7'/%3E%3C/g%3E%3Cg transform='translate(99 99)'%3E%3Cpath d='M-11 -5L-5 -12H5L11 -5L0 12Z' fill='%233be8ff' fill-opacity='.75'/%3E%3Cpath d='M-11 -5H11M-5 -12L0 12L5 -12' fill='none' stroke='%23f4ecd8' stroke-opacity='.6'/%3E%3C/g%3E%3Cg transform='translate(139 59)'%3E%3Cpath d='M-11 -5L-5 -12H5L11 -5L0 12Z' fill='%233be8ff' fill-opacity='.75'/%3E%3Cpath d='M-11 -5H11M-5 -12L0 12L5 -12' fill='none' stroke='%23f4ecd8' stroke-opacity='.6'/%3E%3C/g%3E%3Cg transform='translate(59 139)'%3E%3Ccircle r='10' fill='%23ff5a67' fill-opacity='.6'/%3E%3Cpath d='M6 -8L11 -14' stroke='%23ffb547' stroke-width='2.5'/%3E%3C/g%3E%3C/svg%3E"); }
.gcard[data-game="mines"]:hover::before { transform: scale(1.08) rotate(3deg); }
.gcard[data-game="coinflip"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Ccircle cx='100' cy='100' r='95' fill='%23deb85c' fill-opacity='.10'/%3E%3Cg fill='none' stroke='%23deb85c' stroke-opacity='.7'%3E%3Ccircle cx='100' cy='100' r='95' stroke-width='3'/%3E%3Ccircle cx='100' cy='100' r='70' stroke-width='1.5'/%3E%3Cg stroke-width='2'%3E%3Cline x1='184.0' y1='100.0' x2='192.0' y2='100.0'/%3E%3Cline x1='183.3' y1='111.0' x2='191.2' y2='112.0'/%3E%3Cline x1='181.1' y1='121.7' x2='188.9' y2='123.8'/%3E%3Cline x1='177.6' y1='132.1' x2='185.0' y2='135.2'/%3E%3Cline x1='172.7' y1='142.0' x2='179.7' y2='146.0'/%3E%3Cline x1='166.6' y1='151.1' x2='173.0' y2='156.0'/%3E%3Cline x1='159.4' y1='159.4' x2='165.1' y2='165.1'/%3E%3Cline x1='151.1' y1='166.6' x2='156.0' y2='173.0'/%3E%3Cline x1='142.0' y1='172.7' x2='146.0' y2='179.7'/%3E%3Cline x1='132.1' y1='177.6' x2='135.2' y2='185.0'/%3E%3Cline x1='121.7' y1='181.1' x2='123.8' y2='188.9'/%3E%3Cline x1='111.0' y1='183.3' x2='112.0' y2='191.2'/%3E%3Cline x1='100.0' y1='184.0' x2='100.0' y2='192.0'/%3E%3Cline x1='89.0' y1='183.3' x2='88.0' y2='191.2'/%3E%3Cline x1='78.3' y1='181.1' x2='76.2' y2='188.9'/%3E%3Cline x1='67.9' y1='177.6' x2='64.8' y2='185.0'/%3E%3Cline x1='58.0' y1='172.7' x2='54.0' y2='179.7'/%3E%3Cline x1='48.9' y1='166.6' x2='44.0' y2='173.0'/%3E%3Cline x1='40.6' y1='159.4' x2='34.9' y2='165.1'/%3E%3Cline x1='33.4' y1='151.1' x2='27.0' y2='156.0'/%3E%3Cline x1='27.3' y1='142.0' x2='20.3' y2='146.0'/%3E%3Cline x1='22.4' y1='132.1' x2='15.0' y2='135.2'/%3E%3Cline x1='18.9' y1='121.7' x2='11.1' y2='123.8'/%3E%3Cline x1='16.7' y1='111.0' x2='8.8' y2='112.0'/%3E%3Cline x1='16.0' y1='100.0' x2='8.0' y2='100.0'/%3E%3Cline x1='16.7' y1='89.0' x2='8.8' y2='88.0'/%3E%3Cline x1='18.9' y1='78.3' x2='11.1' y2='76.2'/%3E%3Cline x1='22.4' y1='67.9' x2='15.0' y2='64.8'/%3E%3Cline x1='27.3' y1='58.0' x2='20.3' y2='54.0'/%3E%3Cline x1='33.4' y1='48.9' x2='27.0' y2='44.0'/%3E%3Cline x1='40.6' y1='40.6' x2='34.9' y2='34.9'/%3E%3Cline x1='48.9' y1='33.4' x2='44.0' y2='27.0'/%3E%3Cline x1='58.0' y1='27.3' x2='54.0' y2='20.3'/%3E%3Cline x1='67.9' y1='22.4' x2='64.8' y2='15.0'/%3E%3Cline x1='78.3' y1='18.9' x2='76.2' y2='11.1'/%3E%3Cline x1='89.0' y1='16.7' x2='88.0' y2='8.8'/%3E%3Cline x1='100.0' y1='16.0' x2='100.0' y2='8.0'/%3E%3Cline x1='111.0' y1='16.7' x2='112.0' y2='8.8'/%3E%3Cline x1='121.7' y1='18.9' x2='123.8' y2='11.1'/%3E%3Cline x1='132.1' y1='22.4' x2='135.2' y2='15.0'/%3E%3Cline x1='142.0' y1='27.3' x2='146.0' y2='20.3'/%3E%3Cline x1='151.1' y1='33.4' x2='156.0' y2='27.0'/%3E%3Cline x1='159.4' y1='40.6' x2='165.1' y2='34.9'/%3E%3Cline x1='166.6' y1='48.9' x2='173.0' y2='44.0'/%3E%3Cline x1='172.7' y1='58.0' x2='179.7' y2='54.0'/%3E%3Cline x1='177.6' y1='67.9' x2='185.0' y2='64.8'/%3E%3Cline x1='181.1' y1='78.3' x2='188.9' y2='76.2'/%3E%3Cline x1='183.3' y1='89.0' x2='191.2' y2='88.0'/%3E%3C/g%3E%3Cg stroke-opacity='.4' stroke-width='1.2'%3E%3Cline x1='130.0' y1='100.0' x2='162.0' y2='100.0'/%3E%3Cline x1='129.0' y1='107.8' x2='159.9' y2='116.0'/%3E%3Cline x1='126.0' y1='115.0' x2='153.7' y2='131.0'/%3E%3Cline x1='121.2' y1='121.2' x2='143.8' y2='143.8'/%3E%3Cline x1='115.0' y1='126.0' x2='131.0' y2='153.7'/%3E%3Cline x1='107.8' y1='129.0' x2='116.0' y2='159.9'/%3E%3Cline x1='100.0' y1='130.0' x2='100.0' y2='162.0'/%3E%3Cline x1='92.2' y1='129.0' x2='84.0' y2='159.9'/%3E%3Cline x1='85.0' y1='126.0' x2='69.0' y2='153.7'/%3E%3Cline x1='78.8' y1='121.2' x2='56.2' y2='143.8'/%3E%3Cline x1='74.0' y1='115.0' x2='46.3' y2='131.0'/%3E%3Cline x1='71.0' y1='107.8' x2='40.1' y2='116.0'/%3E%3Cline x1='70.0' y1='100.0' x2='38.0' y2='100.0'/%3E%3Cline x1='71.0' y1='92.2' x2='40.1' y2='84.0'/%3E%3Cline x1='74.0' y1='85.0' x2='46.3' y2='69.0'/%3E%3Cline x1='78.8' y1='78.8' x2='56.2' y2='56.2'/%3E%3Cline x1='85.0' y1='74.0' x2='69.0' y2='46.3'/%3E%3Cline x1='92.2' y1='71.0' x2='84.0' y2='40.1'/%3E%3Cline x1='100.0' y1='70.0' x2='100.0' y2='38.0'/%3E%3Cline x1='107.8' y1='71.0' x2='116.0' y2='40.1'/%3E%3Cline x1='115.0' y1='74.0' x2='131.0' y2='46.3'/%3E%3Cline x1='121.2' y1='78.8' x2='143.8' y2='56.2'/%3E%3Cline x1='126.0' y1='85.0' x2='153.7' y2='69.0'/%3E%3Cline x1='129.0' y1='92.2' x2='159.9' y2='84.0'/%3E%3C/g%3E%3C/g%3E%3Cpath d='M100 76L124 100L100 124L76 100Z' fill='%23f7dd8f' fill-opacity='.55' stroke='%23deb85c'/%3E%3C/svg%3E"); }
.gcard[data-game="coinflip"]:hover::before { transform: rotateY(180deg); }
.gcard[data-game="crash"]::before { right: -6px; bottom: -26px; }
.gcard-tag { max-width: 78%; }
@media (min-width: 1600px) { .gcard[data-game]::before { width: 196px; height: 196px; } }
html.reduce-motion .gcard[data-game]:hover::before { transform: none; }
/* fin des motifs */

/* solde : un éclat d'or traverse la pastille et la pièce se retourne quand il monte */
.tb-balance { position: relative; }
.tb-balance::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0;
  background: linear-gradient(105deg, transparent 30%, rgba(255,246,214,.5) 48%, transparent 66%) no-repeat; background-size: 250% 100%; background-position: 120% 0; }
.tb-balance:has(.bump-up)::after { animation: balGlint .9s ease-out; }
.tb-balance:has(.bump-up) .bet-coin { animation: coinTurn .7s ease; }
@keyframes balGlint { 0% { opacity: 1; background-position: 120% 0; } 100% { opacity: 1; background-position: -20% 0; } }
@keyframes coinTurn { 50% { transform: rotateY(180deg) scale(1.18); } }

/* modales : les quatre coins d'or du salon */
.modal { background:
  linear-gradient(var(--gold), var(--gold)) 12px 12px / 22px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) 12px 12px / 1px 22px no-repeat,
  linear-gradient(var(--gold), var(--gold)) calc(100% - 12px) 12px / 22px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) calc(100% - 12px) 12px / 1px 22px no-repeat,
  linear-gradient(var(--gold), var(--gold)) 12px calc(100% - 12px) / 22px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) 12px calc(100% - 12px) / 1px 22px no-repeat,
  linear-gradient(var(--gold), var(--gold)) calc(100% - 12px) calc(100% - 12px) / 22px 1px no-repeat, linear-gradient(var(--gold), var(--gold)) calc(100% - 12px) calc(100% - 12px) / 1px 22px no-repeat,
  radial-gradient(120% 60% at 50% 0%, rgba(222,184,92,.10), transparent 60%), linear-gradient(180deg, #151a36, #0a0d18); }

/* Animations réduites : le hall se tient tranquille */
html.reduce-motion .hero-dust, html.reduce-motion .route-fx, html.reduce-motion .topbar::before { display: none; }
html.reduce-motion .gcard, html.reduce-motion .gcard:hover { transform: none; }
html.reduce-motion .gcard::after { display: none; }

/* Réglage du casino « Animations : réduites » (core.js pose html.reduce-motion). On ne suit plus prefers-reduced-motion :
   Windows l'annonce dès que ses propres animations sont coupées, ce qui éteignait tout le casino. */
html.reduce-motion *, html.reduce-motion *::before, html.reduce-motion *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }

/* ---------- qualité allégée : PC sans accélération graphique ou trop lent (core.js pose html.perf-low, voir Casino.perf) ----------
   En rendu logiciel, un calque en fusion (mix-blend-mode) ou un flou d'arrière-plan oblige à recomposer tout l'écran à chaque image.
   Le grain y est presque invisible (fusion « overlay » sur fond nuit) : on le retire, le reste du décor ne bouge pas. */
html.perf-low body::after, html.perf-low .hero::after, html.perf-low .felt::before { display: none; }
html.perf-low .modal-back { backdrop-filter: none; background: rgba(3,4,8,.8); }
html.perf-low .net-veil { backdrop-filter: none; }

/* =====================================================================================================
   PASSE INTÉGRATION (30/09) — un hall à 10 jeux conçu d'un seul tenant.
   1. Grilles selon le nombre de cartes de la salle (data-n, posé par boot.js) : ni carte orpheline ni trou.
   2. Motifs art déco des 4 nouveaux jeux (Plus ou Moins, Derby, Grande Roue, Poker), dans le style des 6 premiers.
   3. Badge « en ligne seulement » (file://) pour les jeux qui exigent le serveur.
   4. Arrivée dans le hall (une fois par page) : le cadre se pose, les filets d'or se tirent, les cartes sont distribuées
      et un reflet les balaie. Transformations et opacité seulement ; reflet coupé en qualité allégée (html.perf-low).
   ===================================================================================================== */
.games-grid[data-n="2"], .games-grid[data-n="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.games-grid[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (min-width: 1600px) {
  .games-grid[data-n="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .games-grid[data-n="4"] .gcard-name { font-size: 22px; }
  .games-grid[data-n="4"] .gcard-tag { max-width: 92%; }
}
/* P2-D 30/09 (Z4) : salles de 5 à 7 jeux (jeux de la phase 2) — grille de 6 colonnes, rangées pleines sans trou :
   5 = 3 + 2 (les 2 derniers plus larges) · 6 = 3 + 3 · 7 = 3 + 2 + 2 */
.games-grid[data-n="5"], .games-grid[data-n="6"], .games-grid[data-n="7"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.games-grid[data-n="5"] > *, .games-grid[data-n="6"] > *, .games-grid[data-n="7"] > * { grid-column: span 2; }
.games-grid[data-n="5"] > :nth-child(n+4), .games-grid[data-n="7"] > :nth-child(n+4) { grid-column: span 3; }
@media (max-width: 720px) { .games-grid[data-n] { grid-template-columns: 1fr; } .games-grid[data-n] > * { grid-column: auto; } }
/* 1920×1080 : les 10 jeux tiennent sous le héros sans défiler (cartes et héros un peu plus compacts) */
@media (min-width: 1600px) {
  .gcard { min-height: 164px; padding: 16px 18px 13px; gap: 4px; }
  .gcard-icon { width: 48px; height: 48px; font-size: 28px; }
  .gcard-icon svg { width: 30px; height: 30px; }
  .hall-main { gap: 20px; }
}
@media (min-width: 1600px) and (max-height: 1120px) {
  .hall-inner { padding-top: 18px; }
  .hero { min-height: 0; padding: 20px 20px 22px; }
  .hero-title { font-size: 94px; }
  .sec-head { margin-bottom: 10px; }
  .hall-main { gap: 18px; }
  .hero-kicker { margin-bottom: 10px; }
  .hero-sub { margin-top: 10px; }
  .hero-live { margin-top: 12px; }
  .hero-rule { margin-top: 12px; }
}

.gcard-net { position: absolute; top: 14px; right: 14px; z-index: 1; color: var(--neon-cyan); border-color: rgba(59,232,255,.42); background: rgba(5,6,11,.72); white-space: nowrap; box-shadow: 0 0 14px rgba(59,232,255,.18); }
.gcard-net::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px currentColor; flex: none; }
.gcard.is-net-only .gcard-go { color: var(--text-dim); }
/* barre du haut jusqu'à ~1500 px : « · 3 en salle » redit ce que montrent déjà la réglette sociale (👥 3) et le héros du hall ;
   on le retire pour que la réglette reste DANS la barre, en entier si possible (sinon elle se replie, voire flotte par-dessus le jeu) */
@media (max-width: 1500px) { .tb-count { display: none; } }
/* 1280 px (bas de la cible PC) : le nom à côté de l'avatar s'efface aussi (avatar et solde restent) */
@media (max-width: 1320px) { .tb-me-name { display: none; } }
/* aperçu vivant « Momo y joue » : une pastille en haut à droite de la carte (même place que le badge « en ligne seulement »),
   au lieu d'une ligne de plus : les cartes d'une rangée gardent la même hauteur, qu'on y joue ou non */
.gcard-live { position: absolute; top: 14px; right: 14px; z-index: 1; max-width: calc(100% - 96px); padding: 4px 10px 4px 9px; border-radius: 999px;
  background: rgba(5,6,11,.74); border: 1px solid rgba(62,224,143,.38); box-shadow: 0 0 14px rgba(62,224,143,.16); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.hall-arrive .hero::before { animation: arrFrame .9s cubic-bezier(.2,.8,.2,1) var(--arr, 0ms) both; }
.hall-arrive .hero-sun { animation: arrFade 1.6s ease var(--arr, 0ms) both, sunSpin calc(120s * var(--anim-k, 1)) linear infinite; }
.hall-arrive .hero-title { animation-delay: var(--arr, 0ms), calc(var(--arr, 0ms) + 1.4s); }
.hall-arrive .hero-kicker, .hall-arrive .hero-sub, .hall-arrive .hero-rule, .hall-arrive .hero-live { animation: arrUp .7s cubic-bezier(.2,.8,.2,1) both; }
.hall-arrive .hero-kicker { animation-delay: calc(var(--arr, 0ms) + .05s); }
.hall-arrive .hero-sub { animation-delay: calc(var(--arr, 0ms) + .3s); }
.hall-arrive .hero-rule, .hall-arrive .hero-live { animation-delay: calc(var(--arr, 0ms) + .45s); }
.hall-arrive .sec-title { animation: arrUp .55s cubic-bezier(.2,.8,.2,1) calc(var(--arr, 0ms) + .3s + var(--s, 0) * .16s) both; }
.hall-arrive .sec-sub { animation: arrFade .6s ease calc(var(--arr, 0ms) + .45s + var(--s, 0) * .16s) both; }
.hall-arrive .sec-head::after { transform-origin: 0 50%; animation: arrRule .8s cubic-bezier(.2,.8,.2,1) calc(var(--arr, 0ms) + .4s + var(--s, 0) * .16s) both; }
.hall-arrive .gcard { animation: arrDeal .62s cubic-bezier(.2,.9,.3,1) calc(var(--arr, 0ms) + .38s + var(--i, 0) * 60ms) backwards; }
.hall-arrive .gcard::after { animation: arrSheen .95s ease-out calc(var(--arr, 0ms) + .78s + var(--i, 0) * 60ms) backwards; }
.hall-arrive .hall-side > * { animation: arrSide .6s cubic-bezier(.2,.8,.2,1) calc(var(--arr, 0ms) + .5s) backwards; }
.hall-arrive .hall-side > :nth-child(2) { animation-delay: calc(var(--arr, 0ms) + .62s); }
.hall-arrive .hall-side > :nth-child(3) { animation-delay: calc(var(--arr, 0ms) + .74s); }
@keyframes arrFrame { from { opacity: 0; transform: scale(1.04); } }
@keyframes arrFade { from { opacity: 0; } }
@keyframes arrUp { from { opacity: 0; transform: translateY(12px); } }
@keyframes arrRule { from { transform: scaleX(0); } }
@keyframes arrDeal { from { opacity: 0; transform: perspective(900px) translateY(38px) rotateX(26deg) scale(.95); } 55% { opacity: 1; } }
@keyframes arrSheen { 0% { opacity: 0; background-position: 0 0, 100% 0; } 18% { opacity: 1; } 100% { opacity: 0; background-position: 0 0, 0% 0; } }
@keyframes arrSide { from { opacity: 0; transform: translateX(26px); } }
html.perf-low .hall-arrive .gcard::after { animation: none; }

/* motifs des 4 nouveaux jeux (fabriqués par dev/integration/motifs.mjs) ; ils bougent au survol comme les autres */
.gcard[data-game="hilo"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg transform='translate(84 112) rotate(-14)'%3E%3Crect x='-34' y='-50' width='68' height='100' rx='9' fill='%230a0d18' fill-opacity='.55' stroke='%23deb85c' stroke-opacity='.6' stroke-width='2'/%3E%3Crect x='-26' y='-42' width='52' height='84' rx='5' fill='none' stroke='%23deb85c' stroke-opacity='.3'/%3E%3Cpath d='M-26 -42L26 42M26 -42L-26 42' stroke='%23deb85c' stroke-opacity='.3' stroke-width='1.4'/%3E%3Cpath d='M0 -9L9 0L0 9L-9 0Z' fill='%23f7dd8f' fill-opacity='.6'/%3E%3C/g%3E%3Cg transform='translate(122 104) rotate(8)'%3E%3Crect x='-36' y='-52' width='72' height='104' rx='9' fill='%23f4ecd8' fill-opacity='.13' stroke='%23deb85c' stroke-opacity='.8' stroke-width='2'/%3E%3Crect x='-29' y='-45' width='58' height='90' rx='5' fill='none' stroke='%23deb85c' stroke-opacity='.35'/%3E%3Cpath d='M0 -22L15 0L0 22L-15 0Z' fill='%23d2323f' fill-opacity='.7'/%3E%3C/g%3E%3Cg fill='%233be8ff' fill-opacity='.85'%3E%3Cpath d='M168 58L180 74H156Z'/%3E%3Cpath d='M168 40L180 56H156Z' fill-opacity='.45'/%3E%3C/g%3E%3Cg fill='%23ff4fd8' fill-opacity='.85'%3E%3Cpath d='M58 170L70 154H46Z'/%3E%3Cpath d='M58 188L70 172H46Z' fill-opacity='.45'/%3E%3C/g%3E%3Cpath d='M124 8C137 24 142 36 134 48C130 55 118 56 113 49C107 40 115 27 124 8Z' fill='%23ffb547' fill-opacity='.7'/%3E%3Cpath d='M123 26C129 33 131 40 127 45C124 49 118 49 116 45C113 40 118 33 123 26Z' fill='%23fff3c4' fill-opacity='.75'/%3E%3C/svg%3E"); }
.gcard[data-game="hilo"]:hover::before { transform: translateY(-6px) rotate(-4deg) scale(1.05); }
.gcard[data-game="derby"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg fill='none' stroke='%23deb85c' stroke-linecap='round'%3E%3Cpath d='M4 196C54 128 120 88 200 74' stroke-opacity='.55' stroke-width='2.2'/%3E%3Cpath d='M4 176C52 110 116 68 200 54' stroke-opacity='.3' stroke-width='1.2' stroke-dasharray='5 7'/%3E%3Cpath d='M4 156C50 92 112 48 200 34' stroke-opacity='.55' stroke-width='2.2'/%3E%3C/g%3E%3Cg transform='translate(150 12)'%3E%3Crect x='-1.5' y='0' width='3' height='62' fill='%23deb85c' fill-opacity='.75'/%3E%3Crect x='3' y='1' width='28' height='22' fill='%230a0d18' fill-opacity='.45' stroke='%23deb85c' stroke-opacity='.5'/%3E%3Cg fill='%23f4ecd8' fill-opacity='.8'%3E%3Crect x='4' y='2' width='7' height='7'/%3E%3Crect x='18' y='2' width='7' height='7'/%3E%3Crect x='11' y='9' width='7' height='7'/%3E%3Crect x='25' y='9' width='7' height='7'/%3E%3Crect x='4' y='16' width='7' height='7'/%3E%3Crect x='18' y='16' width='7' height='7'/%3E%3C/g%3E%3C/g%3E%3Cg transform='translate(108 112) rotate(-12)'%3E%3Cpath d='M-36 -34C-40 18 -20 42 0 42C20 42 40 18 36 -34' fill='none' stroke='%23e8572e' stroke-opacity='.75' stroke-width='17' stroke-linecap='round'/%3E%3Cpath d='M-36 -34C-40 18 -20 42 0 42C20 42 40 18 36 -34' fill='none' stroke='%23f7dd8f' stroke-opacity='.55' stroke-width='2'/%3E%3Cg fill='%230a0d18' fill-opacity='.75'%3E%3Ccircle cx='-36' cy='-16' r='2.6'/%3E%3Ccircle cx='-33' cy='6' r='2.6'/%3E%3Ccircle cx='-23' cy='26' r='2.6'/%3E%3Ccircle cx='36' cy='-16' r='2.6'/%3E%3Ccircle cx='33' cy='6' r='2.6'/%3E%3Ccircle cx='23' cy='26' r='2.6'/%3E%3C/g%3E%3C/g%3E%3Cg fill='%23f7dd8f' fill-opacity='.7'%3E%3Cpath d='M60 44l3 7 7 3-7 3-3 7-3-7-7-3 7-3z'/%3E%3Cpath d='M170 128l2 5 5 2-5 2-2 5-2-5-5-2 5-2z'/%3E%3C/g%3E%3C/svg%3E"); }
.gcard[data-game="derby"]:hover::before { transform: translateX(10px) rotate(-3deg) scale(1.04); }
.gcard[data-game="wheel"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cpath d='M100.0 82.0L100.0 20.0A84 84 0 0 1 128.7 25.1L107.5 83.3A22 22 0 0 0 100.0 82.0Z' fill='%23ff4fd8' fill-opacity='.5'/%3E%3Cpath d='M107.5 83.3L128.7 25.1A84 84 0 0 1 154.0 39.7L114.1 87.1A22 22 0 0 0 107.5 83.3Z' fill='%233be8ff' fill-opacity='.5'/%3E%3Cpath d='M114.1 87.1L154.0 39.7A84 84 0 0 1 172.7 62.0L119.1 93.0A22 22 0 0 0 114.1 87.1Z' fill='%23ffb547' fill-opacity='.5'/%3E%3Cpath d='M119.1 93.0L172.7 62.0A84 84 0 0 1 182.7 89.4L121.7 100.2A22 22 0 0 0 119.1 93.0Z' fill='%239b6bff' fill-opacity='.5'/%3E%3Cpath d='M121.7 100.2L182.7 89.4A84 84 0 0 1 182.7 118.6L121.7 107.8A22 22 0 0 0 121.7 100.2Z' fill='%231fbf75' fill-opacity='.5'/%3E%3Cpath d='M121.7 107.8L182.7 118.6A84 84 0 0 1 172.7 146.0L119.1 115.0A22 22 0 0 0 121.7 107.8Z' fill='%23ff5a6c' fill-opacity='.5'/%3E%3Cpath d='M119.1 115.0L172.7 146.0A84 84 0 0 1 154.0 168.3L114.1 120.9A22 22 0 0 0 119.1 115.0Z' fill='%23ff4fd8' fill-opacity='.5'/%3E%3Cpath d='M114.1 120.9L154.0 168.3A84 84 0 0 1 128.7 182.9L107.5 124.7A22 22 0 0 0 114.1 120.9Z' fill='%233be8ff' fill-opacity='.5'/%3E%3Cpath d='M107.5 124.7L128.7 182.9A84 84 0 0 1 100.0 188.0L100.0 126.0A22 22 0 0 0 107.5 124.7Z' fill='%23ffb547' fill-opacity='.5'/%3E%3Cpath d='M100.0 126.0L100.0 188.0A84 84 0 0 1 71.3 182.9L92.5 124.7A22 22 0 0 0 100.0 126.0Z' fill='%239b6bff' fill-opacity='.5'/%3E%3Cpath d='M92.5 124.7L71.3 182.9A84 84 0 0 1 46.0 168.3L85.9 120.9A22 22 0 0 0 92.5 124.7Z' fill='%231fbf75' fill-opacity='.5'/%3E%3Cpath d='M85.9 120.9L46.0 168.3A84 84 0 0 1 27.3 146.0L80.9 115.0A22 22 0 0 0 85.9 120.9Z' fill='%23ff5a6c' fill-opacity='.5'/%3E%3Cpath d='M80.9 115.0L27.3 146.0A84 84 0 0 1 17.3 118.6L78.3 107.8A22 22 0 0 0 80.9 115.0Z' fill='%23ff4fd8' fill-opacity='.5'/%3E%3Cpath d='M78.3 107.8L17.3 118.6A84 84 0 0 1 17.3 89.4L78.3 100.2A22 22 0 0 0 78.3 107.8Z' fill='%233be8ff' fill-opacity='.5'/%3E%3Cpath d='M78.3 100.2L17.3 89.4A84 84 0 0 1 27.3 62.0L80.9 93.0A22 22 0 0 0 78.3 100.2Z' fill='%23ffb547' fill-opacity='.5'/%3E%3Cpath d='M80.9 93.0L27.3 62.0A84 84 0 0 1 46.0 39.7L85.9 87.1A22 22 0 0 0 80.9 93.0Z' fill='%239b6bff' fill-opacity='.5'/%3E%3Cpath d='M85.9 87.1L46.0 39.7A84 84 0 0 1 71.3 25.1L92.5 83.3A22 22 0 0 0 85.9 87.1Z' fill='%231fbf75' fill-opacity='.5'/%3E%3Cpath d='M92.5 83.3L71.3 25.1A84 84 0 0 1 100.0 20.0L100.0 82.0A22 22 0 0 0 92.5 83.3Z' fill='%23ff5a6c' fill-opacity='.5'/%3E%3Cg fill='none' stroke='%23deb85c' stroke-opacity='.75'%3E%3Ccircle cx='100' cy='104' r='84' stroke-width='1.6'/%3E%3Ccircle cx='100' cy='104' r='93' stroke-width='7' stroke-opacity='.45'/%3E%3Ccircle cx='100' cy='104' r='22' stroke-width='2.4'/%3E%3C/g%3E%3Cg fill='%23fff3c4' fill-opacity='.85'%3E%3Ccircle cx='100.0' cy='11.0' r='2.8'/%3E%3Ccircle cx='131.8' cy='16.6' r='2.8'/%3E%3Ccircle cx='159.8' cy='32.8' r='2.8'/%3E%3Ccircle cx='180.5' cy='57.5' r='2.8'/%3E%3Ccircle cx='191.6' cy='87.9' r='2.8'/%3E%3Ccircle cx='191.6' cy='120.1' r='2.8'/%3E%3Ccircle cx='180.5' cy='150.5' r='2.8'/%3E%3Ccircle cx='159.8' cy='175.2' r='2.8'/%3E%3Ccircle cx='131.8' cy='191.4' r='2.8'/%3E%3Ccircle cx='100.0' cy='197.0' r='2.8'/%3E%3Ccircle cx='68.2' cy='191.4' r='2.8'/%3E%3Ccircle cx='40.2' cy='175.2' r='2.8'/%3E%3Ccircle cx='19.5' cy='150.5' r='2.8'/%3E%3Ccircle cx='8.4' cy='120.1' r='2.8'/%3E%3Ccircle cx='8.4' cy='87.9' r='2.8'/%3E%3Ccircle cx='19.5' cy='57.5' r='2.8'/%3E%3Ccircle cx='40.2' cy='32.8' r='2.8'/%3E%3Ccircle cx='68.2' cy='16.6' r='2.8'/%3E%3C/g%3E%3Ccircle cx='100' cy='104' r='20' fill='%230a0d18' fill-opacity='.7'/%3E%3Cpath d='M106 94A12 12 0 1 0 106 114A9 9 0 1 1 106 94Z' fill='%23f7dd8f' fill-opacity='.85'/%3E%3Cpath d='M100 20L90 2H110Z' fill='%23ff5a6c' fill-opacity='.9' stroke='%23f7dd8f' stroke-opacity='.7'/%3E%3C/svg%3E"); }
.gcard[data-game="wheel"]:hover::before { transform: rotate(-80deg) scale(1.05); }
.gcard[data-game="holdem"]::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cg transform='translate(92 76) rotate(-16)'%3E%3Crect x='-30' y='-44' width='60' height='88' rx='8' fill='%23f4ecd8' fill-opacity='.12' stroke='%23deb85c' stroke-opacity='.75' stroke-width='2'/%3E%3Cpath d='M0 -17C9 -7 17 -1 11 8C7 12 2 10 1 7L4 17H-4L-1 7C-2 10 -7 12 -11 8C-17 -1 -9 -7 0 -17Z' fill='%23f4ecd8' fill-opacity='.6' transform='scale(1.25)'/%3E%3C/g%3E%3Cg transform='translate(134 70) rotate(12)'%3E%3Crect x='-30' y='-44' width='60' height='88' rx='8' fill='%23f4ecd8' fill-opacity='.14' stroke='%23deb85c' stroke-opacity='.8' stroke-width='2'/%3E%3Cpath d='M0 14C-12 4 -17 -3 -12 -9C-8 -13 -3 -11 0 -6C3 -11 8 -13 12 -9C17 -3 12 4 0 14Z' fill='%23d2323f' fill-opacity='.7' transform='scale(1.35)'/%3E%3C/g%3E%3Cellipse cx='118' cy='154' rx='30' ry='10' fill='%230a0d18' fill-opacity='.6'/%3E%3Cellipse cx='118' cy='150' rx='30' ry='10' fill='%231fbf75' fill-opacity='.62' stroke='%23deb85c' stroke-opacity='.65' stroke-width='1.2'/%3E%3Cellipse cx='118' cy='150' rx='30' ry='10' fill='none' stroke='%23f4ecd8' stroke-opacity='.7' stroke-width='2.4' stroke-dasharray='5 9'/%3E%3Cellipse cx='118' cy='145' rx='30' ry='10' fill='%230a0d18' fill-opacity='.6'/%3E%3Cellipse cx='118' cy='141' rx='30' ry='10' fill='%231fbf75' fill-opacity='.62' stroke='%23deb85c' stroke-opacity='.65' stroke-width='1.2'/%3E%3Cellipse cx='118' cy='141' rx='30' ry='10' fill='none' stroke='%23f4ecd8' stroke-opacity='.7' stroke-width='2.4' stroke-dasharray='5 9'/%3E%3Cellipse cx='118' cy='136' rx='30' ry='10' fill='%230a0d18' fill-opacity='.6'/%3E%3Cellipse cx='118' cy='132' rx='30' ry='10' fill='%231fbf75' fill-opacity='.62' stroke='%23deb85c' stroke-opacity='.65' stroke-width='1.2'/%3E%3Cellipse cx='118' cy='132' rx='30' ry='10' fill='none' stroke='%23f4ecd8' stroke-opacity='.7' stroke-width='2.4' stroke-dasharray='5 9'/%3E%3Cellipse cx='118' cy='127' rx='30' ry='10' fill='%230a0d18' fill-opacity='.6'/%3E%3Cellipse cx='118' cy='123' rx='30' ry='10' fill='%231fbf75' fill-opacity='.62' stroke='%23deb85c' stroke-opacity='.65' stroke-width='1.2'/%3E%3Cellipse cx='118' cy='123' rx='30' ry='10' fill='none' stroke='%23f4ecd8' stroke-opacity='.7' stroke-width='2.4' stroke-dasharray='5 9'/%3E%3Cellipse cx='118' cy='118' rx='30' ry='10' fill='%230a0d18' fill-opacity='.6'/%3E%3Cellipse cx='118' cy='114' rx='30' ry='10' fill='%231fbf75' fill-opacity='.62' stroke='%23deb85c' stroke-opacity='.65' stroke-width='1.2'/%3E%3Cellipse cx='118' cy='114' rx='30' ry='10' fill='none' stroke='%23f4ecd8' stroke-opacity='.7' stroke-width='2.4' stroke-dasharray='5 9'/%3E%3Cg transform='translate(62 150)'%3E%3Ccircle r='32' fill='%231fbf75' fill-opacity='.5' stroke='%23deb85c' stroke-opacity='.75' stroke-width='2'/%3E%3Cg fill='%23f4ecd8' fill-opacity='.75'%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(0)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(45)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(90)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(135)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(180)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(225)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(270)'/%3E%3Crect x='-3.5' y='-30' width='7' height='9' rx='1.5' transform='rotate(315)'/%3E%3C/g%3E%3Ccircle r='19' fill='%230a0d18' fill-opacity='.55' stroke='%23deb85c' stroke-opacity='.6'/%3E%3Cpath d='M0 -17C9 -7 17 -1 11 8C7 12 2 10 1 7L4 17H-4L-1 7C-2 10 -7 12 -11 8C-17 -1 -9 -7 0 -17Z' fill='%23f7dd8f' fill-opacity='.8' transform='scale(.72)'/%3E%3C/g%3E%3C/svg%3E"); }
.gcard[data-game="holdem"]:hover::before { transform: translateY(-7px) rotate(3deg) scale(1.05); }

/* UX-OVERLAYS 30/09 — « Pousser la porte » infaillible. La carte d'invitation entre en fondu SANS glisser : avant, elle montait de
   34 px pendant 1,6 s et un clic visé pendant l'entrée (machine chargée) pouvait tomber à côté du bouton. Occupé : un anneau tourne
   dans le bouton ; au bout de 3 s, « la porte résiste » (js). */
.jc-card { animation-name: cardFade; }
@keyframes cardFade { from { opacity: 0; transform: scale(.985); } }
.jc-card.is-busy .jc-go-t::before { content: ""; display: inline-block; width: 14px; height: 14px; margin: -3px 12px 0 0; vertical-align: middle;
  border-radius: 50%; border: 2px solid rgba(10,13,24,.28); border-top-color: rgba(10,13,24,.9); animation: spin .8s linear infinite; }
.jc-card.is-slow .jc-go { opacity: .92; }
html.reduce-motion .jc-card.is-busy .jc-go-t::before { animation-duration: 2.4s; }

/* =====================================================================================================
   ACCUEIL (01/10) — la colonne de droite du hall, rangée : mêmes largeurs, mêmes marges, rien par-dessus.
   1. Grand écran : la colonne reste à l'écran (collante) et défile seule quand elle dépasse ; sa barre loge dans la marge de
      droite, les panneaux restent alignés sur le héros. Écran moyen : les panneaux en grille sous les jeux ; téléphone : en pile.
   2. Listes longues : « Dans la salle » et le classement défilent dans leur panneau ; ta ligne reste épinglée (en tête de la salle,
      au bord du classement quand elle en sort).
   3. Ligne de joueur en grille (avatar · nom et lieu · solde · duel) : le solde garde sa colonne, avec ou sans bouton de duel ;
      le contenu des lignes s'aligne sur le titre du panneau.
   4. Le quai : la bande du bas du hall en ligne, hors du défilement ; s'y rangent les boutons discrets (🎙 🔑 🚪 à gauche, posés
      par Casino.ux ; outils de l'hôte et tableau d'honneur à droite). Hauteur : --quai-h.
   5. Contrastes ≥ 4,5:1 pour les textes de la colonne (lieu, heure du fil, joueurs hors ligne) et les sous-titres du hall.
   ===================================================================================================== */
:root { --quai-h: 52px; }
.hall { --hall-h: calc(100vh - var(--topbar-h)); }
.hall.has-quai { height: calc(100% - var(--quai-h)); --hall-h: calc(100vh - var(--topbar-h) - var(--quai-h)); }

.hall-side { gap: 14px; min-width: 0; }
.hall-side > .panel { padding: 14px; }
.hall-side .panel-title { margin-bottom: 10px; }
.hall-arrive .hall-side > * { animation-name: arrFade; }
@media (min-width: 1101px) {
  /* marges compensées : l'ombre des panneaux n'est pas coupée par le défilement, les panneaux restent à leur place (la marge de
     droite, qui loge la barre de défilement, est posée au pixel près par js/boot.js : caleColonne) */
  .hall-side { position: sticky; top: 14px; max-height: calc(var(--hall-h) - 28px); overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
    margin: 0 -12px -14px -14px; padding: 0 0 14px 14px; scrollbar-gutter: stable; scrollbar-width: thin; scrollbar-color: var(--gold-lo) transparent; }
}
@media (max-width: 1100px) {
  .hall-side { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); align-items: start; }
}

/* listes : le contenu des lignes s'aligne sur le titre (la ligne déborde de 8 px de chaque côté, sa surbrillance aussi) */
.hall-side .plist, .hall-side .rank, .hall-side .feed, .hall-side .pf-s-liste { margin-inline: -8px; }
.hall-side .plist-live, .hall-side .rank { max-height: min(325px, 40vh); overflow-x: hidden; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--gold-lo) transparent; }
.hall-side .prow, .hall-side .pf-srow { padding-inline: 7px; }
.hall-side .rank-row, .hall-side .feed-row { padding-inline: 8px; }
.hall-side .prow:focus-visible, .hall-side .rank-row:focus-visible, .hall-side .pf-srow:focus-visible { outline-offset: -2px; }

/* « Dans la salle » : grille de ligne, lignes plus serrées */
.plist-live { gap: 4px; }
.plist-live .prow { display: grid; grid-template-columns: 32px minmax(0, 1fr) auto 30px; column-gap: 10px; padding-block: 5px; }
.plist-live .prow-av { width: 32px; height: 32px; font-size: 17px; }
.plist-live .prow-main { grid-column: 2; }
.plist-live .prow-patri { grid-column: 3; }
.plist-live .prow-duel { grid-column: 4; }
.plist-live .prow-name { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 14px; line-height: 1.3; }
.plist-live .prow-nom { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plist-live .prow-crown, .plist-live .prow-me { flex: none; margin-left: 0; }
.plist-live .prow-where { line-height: 1.3; color: var(--text-dim); }
.plist-live .prow-where.is-table { color: var(--gold); }
/* hors ligne : l'avatar s'éteint, les textes passent en gris lisible (plus d'opacité sur toute la ligne) */
.plist-live .prow.is-off { opacity: 1; }
.plist-live .prow.is-off .prow-av { opacity: .45; filter: grayscale(.8); }
.plist-live .prow.is-off .prow-name, .plist-live .prow.is-off .prow-bal { color: var(--text-dim); }
/* toi : épinglé en tête de la liste quand elle défile (fond plein : les lignes passent dessous) */
.plist-live .prow.is-active { position: sticky; top: 0; z-index: 2;
  background: linear-gradient(color-mix(in srgb, var(--pc, var(--gold)) 11%, transparent), color-mix(in srgb, var(--pc, var(--gold)) 11%, transparent)), #141a35; }

/* classement : ta ligne reste à sa place, et se colle au bord haut ou bas quand elle sortirait de la liste */
.hall-side .rank { gap: 2px; }
.hall-side .rank-row.is-me { position: sticky; top: 0; bottom: 0; z-index: 2;
  background: linear-gradient(color-mix(in srgb, var(--pc, var(--gold)) 12%, transparent), color-mix(in srgb, var(--pc, var(--gold)) 12%, transparent)), #141a35; }
.panel-rang .panel-title::after { order: 1; }
.panel-note { order: 2; flex: none; font: 600 10.5px/1 var(--font-ui); letter-spacing: .14em; text-transform: uppercase; color: var(--text-dim); cursor: help; }

/* le fil */
.hall-side .feed-time { color: var(--gold); opacity: .85; }

/* contrastes du hall : sous-titres des salles et pied (le gris le plus pâle passait sous 4,5:1) */
.hall .sec-sub, .hall-foot { color: var(--text-dim); }

/* ---------- le quai ---------- */
.hall-quai { position: relative; height: var(--quai-h); display: flex; align-items: center; gap: 12px; padding: 0 12px 0 0;
  background: linear-gradient(180deg, rgba(10,13,24,.94), rgba(5,6,11,.98)); border-top: 1px solid var(--line); }
.hall-quai::before { content: ""; position: absolute; left: 50%; top: -4px; width: 7px; height: 7px; margin-left: -3.5px; transform: rotate(45deg);
  background: var(--bg-1); border: 1px solid var(--line-strong); pointer-events: none; }
.hq-place { flex: 1; align-self: stretch; min-width: 0; }
.hq-outils { flex: none; display: flex; align-items: center; gap: 8px; }
.hq-outils:empty { display: none; }
/* rangés dans le quai, les boutons ne flottent plus */
.hall-quai .an-tools, .hall-quai .df-tools { position: static; left: auto; top: auto; bottom: auto; padding: 0; border: 0; background: none; box-shadow: none; gap: 6px; }
.hall-quai .an-tool, .hall-quai .df-tool { width: 34px; height: 34px; border-radius: 10px; font-size: 16px; }
.hall-quai .rc-btn { position: static; left: auto; top: auto; right: auto; bottom: auto; }
@media (max-width: 400px) { .hall-quai .rc-btn-lab { display: none; } .hall-quai .rc-btn { padding: 0 6px; } }
.hall-quai .an-tools, .hall-quai .df-tools { order: 1; }
.hall-quai .rc-btn { order: 2; }
/* la réglette des potes flotte (barre du haut trop pleine : téléphone, tournoi en cours) : au hall, une voie lui est réservée au-dessus
   du hall (js/social.js pose body.so-dock-flotte et --so-dock-h) ; à une table, rien ne change */
body[data-route="hall"].so-dock-flotte .view { padding-top: calc(var(--so-dock-h, 42px) + 20px); }
/* téléphone : le héros ne force plus la largeur de la page (il faisait 403 px pour un écran de 390) */
@media (max-width: 1100px) { .hall-inner { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 520px) {
  .hero { padding: 22px 14px 24px; }
  .hero-kicker { letter-spacing: .26em; }
  .hero-title { font-size: min(14vw, 64px); letter-spacing: .1em; padding-left: .1em; }
  .hero-live { max-width: 100%; }
  .hl-avs .av:nth-child(n+5) { display: none; }
}
body[data-route="hall"].so-dock-flotte .hall.has-quai { --hall-h: calc(100vh - var(--topbar-h) - var(--quai-h) - var(--so-dock-h, 42px) - 20px); }
/* téléphone : l'accroche du héros laisse la place au cadeau du jour (en haut à droite) au lieu de passer dessous */
@media (max-width: 520px) { .hall .hero-kicker { padding-inline: 58px; line-height: 1.6; } }
/* téléphone : la barre du haut ne force plus la page plus large que l'écran (elle faisait 465 px chez un joueur, 640 chez l'hôte :
   le navigateur dézoomait tout le hall). Le losange suffit pour le logo (MINUIT s'écrit en grand juste dessous), la pastille réseau
   garde sa couleur, « Soirée » et « Hôte » leur icône ; s'il reste trop de boutons (renflouement, tournoi), la barre défile. */
@media (max-width: 480px) {
  .topbar { gap: 6px; padding: 0 8px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain; }
  .topbar::-webkit-scrollbar { display: none; }
  .topbar > * { flex-shrink: 0; }
  .topbar > .tb-spacer { flex-shrink: 1; min-width: 0; }
  .tb-logo-word { display: none; }
  .net-pill { padding: 0 10px; }
  .net-pill .np-t { display: none; }
  .tb-host-lab { display: none; }
  .fds-host-btn { font-size: 0; gap: 0; }
  .fds-host-btn .fds-host-ico { font-size: 15px; }
}
/* la barre de la colonne, plus discrète que celle des listes qu'elle contient */
@media (min-width: 1101px) { .hall-side { scrollbar-color: rgba(140,106,34,.55) transparent; } }
/* téléphone : le titre d'une salle tient sur une ligne, son sous-titre passe dessous (au lieu de couper « Les / Tables ») */
@media (max-width: 520px) { .hall .sec-head { flex-wrap: wrap; row-gap: 4px; } .hall .sec-title { white-space: nowrap; } .hall .sec-head::after { display: none; } }
/* =====================================================================================================
   TÉLÉPHONE — N1c (revue au téléphone du 13/10, défaut n° 31) : la barre du haut TIENT dans l'écran dans tous ses états (« Récap »,
   tournoi et son compte à rebours, dernier tour, « ♛ Soirée » et « 👑 Hôte » de l'hôte, hors ligne, mode local). Avant : à 360 et
   390 px, le solde était rogné, le son et les réglages sortaient de l'écran (la barre défilait, sans indice, et la médaille du cabinet,
   épinglée sur l'avatar, restait en place : un doigt sur ⚙ ouvrait le cabinet) ; couchée, la barre de l'hôte débordait de 45 px.
   On réarrange, on ne redessine pas : mêmes pastilles d'or, mêmes polices ; des écarts plus serrés, des boutons ronds de 34 px. Pendant
   un tournoi ou le dernier tour, la pastille du compte à rebours ouvre déjà le panneau de la soirée chez l'hôte : son « ♛ » s'efface.
   Si la barre déborde encore (hôte, tournoi, gros solde), js/boot.js (serrerBarre, au téléphone SEULEMENT) la resserre par paliers :
   .tb-serre-1 (libellés de la pastille, pièce du solde, icône d'un compte à rebours ; écarts de 3 px), .tb-serre-2 (la pastille réseau
   en point sur le losange ; ronds de 32 px), .tb-serre-3 (avatar de 24 px, solde en 14 px, boutons de l'hôte de 32 px). Règles bornées
   au téléphone (portrait ≤ 480 px de large, paysage ≤ 560 px de haut) : le PC ne change pas.
   ===================================================================================================== */
@media (orientation: portrait) and (max-width: 480px) {
  #topbar { gap: 5px; padding: 0 6px; }
  #topbar .tb-logo { min-width: 34px; min-height: 34px; justify-content: center; }
  #topbar .fds-pill { gap: 6px; height: 32px; padding: 0 11px 0 9px; }
  #topbar .fds-pill[data-mode="recap"] .fds-pill-t, #topbar .fds-pill[data-mode="podium"] .fds-pill-t { display: none; }
  #topbar .fds-pill-t { font-size: 15px; min-width: 0; }
  #topbar .net-pill { padding: 0 8px; }
  #topbar .fds-host-btn, #topbar .tb-host { width: 34px; padding: 0; }
  #topbar:has(.fds-pill[data-mode="tournoi"]:not([hidden]), .fds-pill[data-mode="dernier"]:not([hidden])) .fds-host-btn { display: none; }
  #topbar .tb-icon { width: 34px; height: 34px; font-size: 16px; }
  #topbar .tb-me { gap: 5px; height: 40px; padding: 0 3px; }
  #topbar .tb-me-av { width: 28px; height: 28px; font-size: 16px; }
  #topbar .tb-balance { gap: 5px; padding: 0 10px 0 6px; font-size: 15px; }
  #topbar .tb-me .tb-balance { height: 32px; }
  #topbar .tb-balance .bet-coin { width: 16px; height: 16px; }
}
/* couchée (844 × 390) : le losange suffit (comme en portrait), la pastille réseau garde sa couleur ; les éléments ne s'écrasent plus
   (le son et les réglages tombaient à 26 et 17 px de large) : la barre se resserre par paliers comme en portrait */
@media (orientation: landscape) and (max-height: 560px) {
  #topbar { gap: 8px; padding: 0 12px; }
  #topbar > * { flex-shrink: 0; }
  #topbar > .tb-spacer { flex-shrink: 1; min-width: 0; }
  #topbar .tb-logo-word { display: none; }
  #topbar .net-pill { padding: 0 10px; }
  #topbar .net-pill .np-t { display: none; }
}
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  /* le signal « au téléphone » des JS de N1c (js/boot.js : serrerBarre, focus de la porte ; js/voix.js : le micro après un défilement) :
     les bornes ne sont écrites qu'ici */
  :root { --minuit-telephone: 1; }
  #topbar.tb-serre-1, #topbar.tb-serre-1 .tb-me, #topbar.tb-serre-1 .tb-balance { gap: 3px; }
  #topbar.tb-serre-1 .fds-pill .fds-pill-lab, #topbar.tb-serre-1 .tb-balance .bet-coin { display: none; }
  #topbar.tb-serre-1 .fds-pill:is([data-mode="tournoi"], [data-mode="dernier"]) .fds-pill-ico { display: none; }
  #topbar.tb-serre-1 .fds-pill { padding: 0 10px; }
  #topbar.tb-serre-2 .net-pill { position: absolute; left: 30px; top: 13px; z-index: 1; width: 14px; height: 14px; padding: 0; justify-content: center;
    border-color: rgba(5,6,11,.9); background: rgba(5,6,11,.9); pointer-events: none; }
  #topbar.tb-serre-2 .tb-icon { width: 32px; height: 32px; }
  #topbar.tb-serre-3 .tb-me-av { width: 24px; height: 24px; font-size: 14px; }
  #topbar.tb-serre-3 .tb-balance { padding: 0 8px 0 5px; font-size: 14px; }
  #topbar.tb-serre-3 .fds-host-btn, #topbar.tb-serre-3 .tb-host { width: 32px; }
}
/* TÉLÉPHONE — N1c (revue au téléphone du 13/10, n° 29) : la valeur inscrite sur les jetons des râteliers (à choisir au doigt) tombait
   à 11,4 px (jetons de 38 px : Grande Roue, blackjack), 9,8 px à la Roulette à 360 : 12 px au moins. Les piles posées sur les tapis
   (décor, le montant est écrit à côté) ne changent pas. Bornée au téléphone : le PC ne change pas. */
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  .chip-slot .chip-v { font-size: max(12px, calc(var(--chip-size, 44px) * .3)); }
  .chip-slot .chip-long .chip-v { font-size: max(12px, calc(var(--chip-size, 44px) * .24)); }
}
/* TÉLÉPHONE — N1c (annexe A de la revue au téléphone : textes sous 12 px, les plus visibles de l'interface commune) : au hall
   « Jouer → » et « multi » des cartes (11 px), « toi » (9 px), « net » (10,5 px) ; les libellés des Réglages et du salon de l'hôte,
   son « en ligne » et son invitation (11 et 11,5 px) : 12 px. Mêmes polices, même interlettrage. Bornée au téléphone. */
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  #view .gcard .gcard-go, #view .gcard .gcard-multi, #view .prow-me, #view .panel-rang .panel-note { font-size: 12px; }
  .modal .field > .label, .modal .field > label, .modal .hp-pin .label, .modal .hp-invite-k, .modal .hp-prow .hp-vu { font-size: 12px; }
}
/* TÉLÉPHONE — N5 (annexe B de la revue au téléphone, REMESURÉE sur d1cc705 ; règle de l'orchestrateur, 13/10 15:5x : au doigt, toute
   cible a 32 px au moins sur son petit côté). Les pièces communes ; on agrandit la zone de toucher, on ne redessine pas (mêmes pastilles,
   même or, mêmes polices) :
   - les petits boutons (.btn-sm, 30 px de haut : « Défier », ♛ et 👑 de l'hôte, « Mon compte », les Réglages, le salon de l'hôte, la cave
     du Hold'em et « ⇄ Tournoi », ½ ×2 MAX des mises, « Table des gains », « Me retirer », 🎙 du Derby) : 32 px ; les ronds « Défier » du
     hall (30 × 30) : 32 × 32. Pas dans la Grande Roue, la Fusée, le Plinko ni les Mines (leurs feuilles sont au lot N4 : « après N4 ») ;
   - le × des fenêtres ne se laisse plus serrer (28,5 px de large dans le registre de l'hôte à 360) ;
   - le curseur du volume (Réglages) : 32 px de haut, sa piste native reste fine, au milieu ;
   - le logo MINUIT de la barre, couchée : 34 px, comme en portrait (N1c) ;
   - le micro du croupier (🎙, js/voix.js : 30 px) : 32 px ; il se pose à une place libre d'après SA taille (Casino.ux.libre).
   Bornées au téléphone : le PC ne change pas (dev/tests-client/s5-tel-cibles.mjs, sections D et D2). */
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  .btn-sm:not(:is(.g-wheel, .g-crash, .g-plinko, .g-mines) *) { min-height: 32px; }
  #view .plist .prow .btn-sm { min-width: 32px; }
  .modal-x { flex: none; min-width: 32px; min-height: 32px; }
  .modal .set-row input[type="range"] { height: 32px; }
  #topbar .tb-logo { min-width: 34px; min-height: 34px; justify-content: center; }
  body .vx-btn { width: 32px; height: 32px; }
}
/* TÉLÉPHONE — N11 (annexe A de la revue au téléphone, REMESURÉE sur 1bedc6a ; suite du bloc d'annexe A de N1c ci-dessus) : au téléphone, aucun texte
   lisible sous 12 px calculés (décor aria-hidden exclu). Ici les pièces communes : les pastilles (.badge : « toi », le rang « 1 » des panneaux), les touches
   (.kbd : 1 … 8, T, P de l'astuce de la salle) et le solde des lignes du classement du hall (« 50 000 ») : 12 px. Les textes d'un jeu ou d'un écran sont à la fin de
   LEUR feuille, sous la même requête. Mêmes polices, même interlettrage, même couleur ; on agrandit le texte, on ne redessine pas. Bornée au téléphone : le PC ne
   change pas (dev/tests-client/s5-tel-textes.mjs, sections D et D2). */
@media (orientation: portrait) and (max-width: 480px), (orientation: landscape) and (max-height: 560px) {
  .badge, .kbd, .rank-sub { font-size: 12px; }
}
/* RETIRER AU DOIGT — N9 (D6 Q1 « Q1-RETRAIT », D7) : l'appui long sur la mise reprend UN jeton (Casino.ui.retrait, js/core.js).
   .appui-cible : posée par l'assistant sur la racine des cibles de mise ; au doigt, l'appui long n'y sélectionne aucun texte et n'ouvre
   pas le « callout » d'iOS. Sans effet au PC à la souris (any-pointer: coarse est faux, mesuré par dev/tests-client/s5-tel-retrait.mjs).
   .appui-anneau : l'anneau d'or sous le doigt, un seul, dans <body> (z 1200 : sous .signal), qui ne prend aucun toucher. Rien avant
   150 ms ; de 150 à 450 ms, sur une piste de 2 px, un arc --gold-hi de 3 px se remplit dans le sens horaire depuis midi ; à
   l'aboutissement, une pulsation (160 ms) ; à l'abandon, un fondu (120 ms). Animations réduites (html.reduce-motion écrase les
   durées) : l'anneau paraît plein et s'efface, sans pulsation. */
@media (any-pointer: coarse) {
  .appui-cible { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
}
.appui-anneau { position: fixed; z-index: 1200; left: 0; top: 0; width: 56px; height: 56px; margin: -28px 0 0 -28px; pointer-events: none; }
.appui-anneau svg { display: block; width: 100%; height: 100%; overflow: visible; transform: rotate(-90deg); }
.appui-piste { fill: none; stroke: rgba(247,221,143,.25); stroke-width: 2; }
.appui-arc { fill: none; stroke: var(--gold-hi); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 163.4; stroke-dashoffset: 163.4; animation: appuiArc .3s linear forwards; }
.appui-anneau.is-fait { animation: appuiPulse .16s ease-out forwards; }
.appui-anneau.is-lache { opacity: 0; transition: opacity .12s; }
html.reduce-motion .appui-anneau.is-fait { animation-name: none; }
@keyframes appuiArc { to { stroke-dashoffset: 0; } }
@keyframes appuiPulse { to { transform: scale(1.12); opacity: 0; } }
/* TÉLÉPHONE COUCHÉ — N28 (dev/tests-client/s5-tel-holdem-hote.mjs ; N26, question n° 2) : la barre du haut de L'HÔTE. « ♛ Soirée » (84 px)
   et « 👑 Hôte » (79 px) ne laissaient à la réglette des potes que 183 px à 740, 119 à 667 et 92 à 640 (sa forme compacte en fait 234) :
   elle flottait sous la barre, et chaque jeu lui cédait sa voie (au Hold'em, une salle de 114 px de haut au lieu de 160). Couchée, la
   barre de l'hôte prend les règles du portrait (N1c, plus haut) : « Soirée » et « Hôte » en ronds de 34 px (leur icône, leur titre et leur
   pastille restent ; pendant un tournoi ou le dernier tour, la pastille du compte à rebours ouvre déjà le panneau de la soirée : son « ♛ »
   s'efface, comme en portrait), le son et les réglages à 34 px, l'avatar et le solde resserrés ; l'écart de 8 px entre les éléments reste
   (la médaille du cabinet, épinglée 9 px à gauche de l'avatar, n'y touche pas « Hôte »). La réglette y tient ; sinon elle se serre encore
   (css/social.css, js/social.js : N28). Seulement sous 800 px de large : à 844, la réglette tenait déjà, compacte (resserrée, la barre lui
   laissait la place de ses réactions de 22 px en ligne au lieu de leur menu de 34 px). Mêmes pastilles, même or, mêmes polices. Bornée au
   téléphone couché : le PC ne change pas (D et D2). */
@media (orientation: landscape) and (max-height: 560px) and (max-width: 800px) {
  #topbar:has(.tb-host) .fds-host-btn, #topbar:has(.tb-host) .tb-host { width: 34px; padding: 0; }
  #topbar:has(.tb-host) .tb-host-lab { display: none; }
  #topbar:has(.tb-host) .fds-host-btn { font-size: 0; gap: 0; }
  #topbar:has(.tb-host) .fds-host-btn .fds-host-ico { font-size: 15px; }
  #topbar:has(.tb-host):has(.fds-pill[data-mode="tournoi"]:not([hidden]), .fds-pill[data-mode="dernier"]:not([hidden])) .fds-host-btn { display: none; }
  #topbar:has(.tb-host) .fds-pill { gap: 6px; height: 32px; padding: 0 11px 0 9px; }
  #topbar:has(.tb-host) .tb-icon { width: 34px; height: 34px; font-size: 16px; }
  #topbar:has(.tb-host) .tb-me { gap: 5px; height: 40px; padding: 0 3px; }
  #topbar:has(.tb-host) .tb-me-av { width: 28px; height: 28px; font-size: 16px; }
  #topbar:has(.tb-host) .tb-balance { gap: 5px; padding: 0 10px 0 6px; font-size: 15px; }
  #topbar:has(.tb-host) .tb-me .tb-balance { height: 32px; }
  #topbar:has(.tb-host) .tb-balance .bet-coin { width: 16px; height: 16px; }
}
