/* ==========================================================================
   NEONBET — sistema visual
   Oscuro, con profundidad, un acento por juego y arte propio.
   Mobile-first. Sin dependencias, sin fuentes externas.
   ========================================================================== */

:root{
  /* --- fondo y superficies ------------------------------------------------ */
  --bg:#08080f;
  --bg-2:#0c0b18;
  --surface:linear-gradient(180deg,#17162b 0%,#12111f 100%);
  --surface-flat:#151426;
  --surface-2:#1c1b33;
  --surface-3:#262445;
  --line:#2e2c52;
  --line-soft:#221f3d;

  /* --- texto -------------------------------------------------------------- */
  --text:#eef0ff;
  --muted:#9a9ac4;
  --muted-2:#6b6a95;

  /* --- marca -------------------------------------------------------------- */
  --brand:#7c5cff;
  --brand-2:#b14cff;
  --brand-grad:linear-gradient(135deg,#7c5cff 0%,#b14cff 100%);

  /* --- semánticos --------------------------------------------------------- */
  --win:#25e59a;
  --win-2:#12b87c;
  --lose:#ff4d6d;
  --gold:#ffc53d;
  --gold-2:#ff9f1c;
  --info:#38bdf8;

  /* --- acento del juego activo (lo pisa .view[data-game]) ------------------ */
  --game:#7c5cff;
  --game-2:#b14cff;
  --game-glow:rgba(124,92,255,.45);

  --radius:18px;
  --radius-sm:12px;
  --radius-xs:9px;
  --tap:48px;
  --font:"Inter","SF Pro Text",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --mono:"SFMono-Regular",ui-monospace,Menlo,Consolas,monospace;
  --sidebar-w:244px;
  --topbar-h:62px;
  --shadow:0 18px 46px rgba(0,0,0,.55);
  --shadow-sm:0 6px 18px rgba(0,0,0,.4);
}

/* acento por juego */
.view[data-game="dice"]  { --game:#22d3ee; --game-2:#3b82f6; --game-glow:rgba(34,211,238,.4) }
.view[data-game="sicbo"]{ --game:#b06cff; --game-2:#7de3ff; --game-glow:rgba(176,108,255,.42) }
.view[data-game="dragontower"]{ --game:#ff5a2b; --game-2:#ffb43d; --game-glow:rgba(255,90,43,.45) }
.view[data-game="blackjack"]{ --game:#28e0a0; --game-2:#ffd873; --game-glow:rgba(40,224,160,.40) }
.view[data-game="andarbahar"]{ --game:#ffb02e; --game-2:#ff6ec7; --game-glow:rgba(255,176,46,.42) }
.view[data-game="videopoker"]{ --game:#3fa9f5; --game-2:#4ff0c0; --game-glow:rgba(63,169,245,.42) }
.view[data-game="craps"]{ --game:#3ee08a; --game-2:#ffd873; --game-glow:rgba(62,224,138,.40) }
.view[data-game="threecardpoker"]{ --game:#c8323f; --game-2:#f5b53d; --game-glow:rgba(200,50,63,.42) }
.view[data-game="tormenta"]{ --game:#39d98a; --game-2:#ffc53d; --game-glow:rgba(57,217,138,.42) }
.view[data-game="crash"] { --game:#ff7a3d; --game-2:#ff3d6e; --game-glow:rgba(255,122,61,.45) }
.view[data-game="slots"] { --game:#ffc53d; --game-2:#ff5ec7; --game-glow:rgba(255,197,61,.4) }
.view[data-game="home"]  { --game:#7c5cff; --game-2:#b14cff; --game-glow:rgba(124,92,255,.45) }
.view[data-game="plinko"]{ --game:#4dabff; --game-2:#a855f7; --game-glow:rgba(77,171,255,.42) }
.view[data-game="roulette"]{ --game:#2fd38a; --game-2:#c9922a; --game-glow:rgba(47,211,138,.38) }
.view[data-game="limbo"] { --game:#22d3ee; --game-2:#a855f7; --game-glow:rgba(34,211,238,.4) }
.view[data-game="wheel"] { --game:#c77dff; --game-2:#ffc53d; --game-glow:rgba(199,125,255,.42) }
.view[data-game="keno"]  { --game:#2fd38a; --game-2:#22d3ee; --game-glow:rgba(47,211,138,.4) }
.view[data-game="mines"] { --game:#25e5c8; --game-2:#4dabff; --game-glow:rgba(37,229,200,.4) }
.view[data-game="hilo"]  { --game:#a855f7; --game-2:#ff5ec7; --game-glow:rgba(168,85,247,.42) }
.view[data-game="baccarat"]{ --game:#2fd38a; --game-2:#ffc53d; --game-glow:rgba(47,211,138,.38) }

*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
/* Red de proteccion contra scroll horizontal.
   ---------------------------------------------------------------------------
   OJO: va SOLO en <body>, NUNCA tambien en <html>.
   Si el overflow de <html> deja de ser `visible`, deja de propagarse al
   viewport y <body> pasa a ser un contenedor de scroll independiente. Como el
   alto de <body> crece con el contenido, ese contenedor no tiene nada propio
   que scrollear: la pagina deja de moverse con el dedo y con la rueda, aunque
   window.scrollTo() siga funcionando (por eso un test programatico no lo ve).
   Puesto solo en <body>, su overflow se propaga al viewport y queda un unico
   contenedor de scroll. Lo cubre tools/mobile_check.sh con un gesto real. */
html{max-width:100%}
body{max-width:100%;overflow-x:hidden}
body{
  margin:0;color:var(--text);
  background:
    radial-gradient(1100px 620px at 78% -8%, rgba(124,92,255,.20), transparent 62%),
    radial-gradient(900px 520px at 4% 8%, rgba(255,92,199,.10), transparent 58%),
    var(--bg);
  background-attachment:fixed;
  font-family:var(--font);font-size:15px;line-height:1.45;
  -webkit-font-smoothing:antialiased;overscroll-behavior-y:none;
}
button,input,select,textarea{font:inherit;color:inherit}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;font-weight:700;letter-spacing:-.02em}
p{margin:0}
::selection{background:var(--brand);color:#fff}

*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--surface-3);border-radius:8px;border:3px solid transparent;background-clip:padding-box}

/* --- Boot ---------------------------------------------------------------- */
.boot{position:fixed;inset:0;display:grid;place-items:center;background:var(--bg);z-index:200}
/* Adentro ya no hay texto con degrade: hay una sola imagen, el lockup entero.
   Las reglas de recorte de fondo sobre el texto se sacaron porque no tenian a
   quien aplicarse y confundian al leer el archivo. */
.boot-mark{display:flex;flex-direction:column;align-items:center;gap:14px}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:1}}

/* ==========================================================================
   Layout
   ========================================================================== */
.app{min-height:100dvh}
/* Ninguna capa decorativa puede correr la pagina de costado.
   Va `clip` y no `hidden` a proposito: `hidden` convertiria a body en el
   contenedor de scroll y la barra de arriba dejaria de quedarse pegada.
   El contenido de verdad ya entra —lo que se pasaba eran los orbes de
   ambiente y el arte de fondo, que son adorno. */
html,body{overflow-x:clip}

.topbar{
  position:sticky;top:0;z-index:60;height:var(--topbar-h);
  display:flex;align-items:center;gap:10px;padding:0 12px;
  background:rgba(8,8,15,.86);backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line-soft);
  padding-top:env(safe-area-inset-top);
}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:6px}

/* --- bote progresivo en la barra --- */
.bote-pill{
  display:none;align-items:center;gap:10px;margin-left:22px;
  padding:6px 15px 6px 11px;border-radius:999px;
  border:1px solid rgba(255,197,61,.28);
  background:linear-gradient(100deg,rgba(255,197,61,.12),rgba(255,197,61,.03));
  transition:border-color .18s,transform .18s cubic-bezier(.22,1.2,.36,1);
}
.bote-pill[hidden]{display:none!important}
.bote-pill:hover{border-color:rgba(255,197,61,.6);transform:translateY(-1px)}
@media(min-width:900px){.bote-pill:not([hidden]){display:inline-flex}}
.bp-luz{
  width:8px;height:8px;flex:0 0 auto;border-radius:50%;background:var(--gold);
  box-shadow:0 0 10px var(--gold);animation:botePulso 2.4s ease-in-out infinite;
}
@keyframes botePulso{0%,100%{opacity:.45;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}
.bp-txt{display:flex;flex-direction:column;line-height:1.15;min-width:0}
.bp-k{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2)}
.bp-v{
  font-size:15px;font-weight:900;color:var(--gold);letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;
}
/* El numero late cuando sube: el bote crece con cada apuesta de la casa. */
.bp-v.sube{animation:bump .5s cubic-bezier(.22,1.4,.36,1)}
@media (prefers-reduced-motion: reduce){
  .bp-luz{animation:none;opacity:.9}
  .bp-v.sube{animation:none}
}

/* ==========================================================================
   LA MARCA
   ==========================================================================
   El logo llega como un lockup de 1536x1024 y 1,9 MB con corona, ficha,
   cartas y dados. Meterlo entero en la barra no funciona por tres motivos
   medidos: 1,9 MB en cada carga de una PWA es inaceptable; a los 62 px de
   alto de la barra el detalle de la corona y los dados se hace una mancha; y
   el fondo negro viene horneado —las cartas del logo SON negras, asi que no
   se puede recortar por color sin agujerearlas—.
   Se parte en tres piezas, cada una donde rinde:
     logo.webp     720x523  59 KB  lockup entero, para el arranque y el login
     palabra.webp  560x131  16 KB  "NEOBET", que se lee perfecto a 110 px
     emblema.webp  200x189  12 KB  corona+ficha+N, la marca chica (con @2x)
   Total 118 KB contra 1,9 MB, y cada una legible en su tamano.
   Todas van sobre fondos casi negros (barra, arranque, login), asi que el
   fondo horneado del PNG se funde y no se ve el rectangulo. */
.brand{display:flex;align-items:center;gap:9px;font-weight:900;font-size:17px;letter-spacing:-.01em}
.brand-name{
  /* Ya no es texto: es la palabra dibujada del logo. El alto manda y el ancho
     sale solo, asi que la proporcion no se deforma en ningun ancho. */
  height:22px;width:auto;display:block;
  filter:drop-shadow(0 1px 6px rgba(124,92,255,.35));
}
.brand-mark{
  width:34px;height:34px;flex:0 0 auto;overflow:visible;object-fit:contain;
  filter:drop-shadow(0 0 9px rgba(124,92,255,.55));
  transition:filter .18s;
}
.brand:hover .brand-mark{filter:drop-shadow(0 0 14px rgba(124,92,255,.8))}
/* El lockup entero: arranque y login. Se topa por ancho y por alto para que
   en un telefono apaisado no se coma la pantalla. */
/* El lockup entero: arranque y login.
   El tope por ALTO no es un adorno. Puesto solo con min(320px,72vw), en una
   laptop de 1366x768 —que despues del cromo del navegador deja unos 657 px
   utiles— el logo mide 320x232 y empuja la tarjeta de login a 635 px de alto:
   se sale de la pantalla y hay que achicar el zoom para poder entrar. Es la
   primera pantalla que ve alguien, asi que ahi no se puede fallar.
   El 32vh ata el ancho al alto disponible (el lockup es 720x523, o sea 1,377
   de proporcion), y con eso la tarjeta entra en 600 px de viewport. */
.marca-logo{
  width:min(320px,72vw,32vh);height:auto;display:block;
  filter:drop-shadow(0 10px 34px rgba(124,92,255,.35));
}
/* El alto de la palabra en la barra. La marca ya no es texto, asi que el
   font-size no hace nada: lo que manda es el alto de la imagen. */
.brand-mobile .brand-name{height:20px}

.icon-btn{
  width:var(--tap);height:var(--tap);display:grid;place-items:center;
  background:transparent;border:0;border-radius:var(--radius-sm);cursor:pointer;color:var(--text);
  font-size:22px;line-height:1;flex:0 0 auto
}
.icon-btn:active{background:var(--surface-2)}
.burger,.burger::before,.burger::after{content:"";display:block;width:18px;height:2px;background:currentColor;border-radius:2px;transition:.18s}
.burger::before{transform:translateY(-6px)}
.burger::after{transform:translateY(4px)}

/* El saldo y el "+" son una sola pieza: la accion pegada a la plata. Antes el
   boton "Cajera" estaba suelto al lado y competia con el saldo por atencion. */
.saldo-caja{
  display:flex;align-items:stretch;border-radius:var(--radius-sm);overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--shadow-sm);
  background:linear-gradient(180deg,var(--surface-2),var(--surface-flat));
}
.balance-chip{
  display:flex;flex-direction:column;align-items:flex-end;
  background:none;border:0;border-radius:0;
  padding:6px 12px;min-height:42px;cursor:pointer
}
.saldo-mas{
  display:grid;place-items:center;width:40px;flex:0 0 auto;
  font-size:21px;font-weight:800;line-height:1;color:#0a0713;
  background:linear-gradient(135deg,var(--brand),var(--brand-2));
  transition:filter .16s;
}
.saldo-mas:hover{filter:brightness(1.12)}
.saldo-mas[hidden]{display:none}
.balance-label{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2)}
.balance-value{
  font-variant-numeric:tabular-nums;font-weight:800;font-size:14px;
  background:linear-gradient(180deg,#fff,#ffd98a);-webkit-background-clip:text;background-clip:text;color:transparent
}
.balance-value.bump{animation:bump .5s cubic-bezier(.22,1.4,.36,1)}
@keyframes bump{0%{transform:scale(1)}35%{transform:scale(1.16)}100%{transform:scale(1)}}

/* --- Sidebar ------------------------------------------------------------- */
.sidebar{
  position:fixed;inset:0 auto 0 0;width:min(84vw,var(--sidebar-w));z-index:80;
  background:linear-gradient(180deg,#141327,#0d0c18);
  border-right:1px solid var(--line-soft);
  display:flex;flex-direction:column;
  transform:translateX(-102%);transition:transform .24s cubic-bezier(.4,0,.2,1);
  padding-top:env(safe-area-inset-top);box-shadow:var(--shadow)
}
.sidebar.open{transform:none}
.sidebar-head{display:flex;align-items:center;justify-content:space-between;height:var(--topbar-h);padding:0 8px 0 16px}
.sidebar-foot{margin-top:auto;padding:12px;border-top:1px solid var(--line-soft)}
.scrim{position:fixed;inset:0;background:rgba(3,3,8,.68);z-index:70;backdrop-filter:blur(3px)}

.nav{padding:8px;display:flex;flex-direction:column;gap:3px;overflow-y:auto}
.nav-group{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2);padding:16px 12px 6px}
.nav a{
  position:relative;display:flex;align-items:center;gap:12px;min-height:var(--tap);padding:0 12px;
  border-radius:var(--radius-sm);color:var(--muted);font-weight:600;font-size:14px;transition:.15s
}
.nav a:active{background:var(--surface-2)}
.nav a.active{background:linear-gradient(90deg,rgba(124,92,255,.20),rgba(124,92,255,.04));color:#fff}
.nav a.active::before{
  content:"";position:absolute;left:0;top:12px;bottom:12px;width:3px;border-radius:0 3px 3px 0;
  background:var(--brand-grad);box-shadow:0 0 12px var(--brand)
}
.nav-ico{width:22px;display:grid;place-items:center;color:var(--muted-2);flex:0 0 auto;transition:.15s}
.nav a.active .nav-ico{color:var(--brand-2)}
.nav-ico svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

.view{padding:14px 12px 96px;max-width:1240px;margin:0 auto;min-width:0}

/* El menu es un cajon que se abre con el boton, en telefono y en escritorio
   igual. Antes era una barra fija que listaba los 19 juegos, que es la misma
   lista que ya esta en el inicio con la portada de cada uno: ocupaba un cuarto
   de la pantalla para repetir algo que se ve mejor mas grande. Ahora adentro
   quedan solo las cosas de la cuenta. */
@media (min-width:900px){
  .sidebar{width:var(--sidebar-w)}
  .view{padding:22px 28px 60px;max-width:1320px}
  .topbar{padding:0 20px}
}

/* ==========================================================================
   Piezas
   ========================================================================== */
.card{
  background:var(--surface);border:1px solid var(--line-soft);
  border-radius:var(--radius);padding:16px;min-width:0;box-shadow:var(--shadow-sm)
}
.card+.card{margin-top:12px}
.card-title{
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted-2);
  margin-bottom:12px;font-weight:700
}
.card-glow{position:relative;overflow:hidden}
.card-glow::before{
  content:"";position:absolute;inset:-1px;border-radius:inherit;padding:1px;
  background:linear-gradient(135deg,var(--game),transparent 42%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none;opacity:.55
}

.grid{display:grid;gap:12px;min-width:0}
.game-layout{display:grid;gap:12px;min-width:0}
.gl-stage,.gl-panel,.gl-info{min-width:0}
/* El corte de la vista de juego es 901, el mismo punto donde app.js deja de
   montar la barra de accion al pie (MQ_TELEFONO) y donde la .view pasa a
   padding de escritorio. Los tres numeros tienen que ser EL MISMO.
   Estaba en 980 y eso abria una banda muerta de 901 a 979: ahi ya no habia
   barra fija —el CSS de la barra corta en 900— pero tampoco dos columnas, asi
   que el panel con el monto y el boton de apostar caia debajo del escenario y
   fuera de pantalla. Medido a 960x900: el panel arrancaba en y=621 con 455 px
   de scroll por delante, que es exactamente el problema que la barra del
   telefono habia venido a resolver.
   A 901 el escenario se queda con 481 px (845 utiles menos el panel de 352 y
   el hueco de 12) y crece con la ventana hasta 900 a partir de 1400. */
@media (min-width:901px){
  .game-layout{
    grid-template-columns:352px minmax(0,1fr);
    grid-template-areas:"panel stage" "panel info";align-items:start
  }
  .gl-panel{grid-area:panel;position:sticky;top:calc(var(--topbar-h) + 16px)}
  .gl-stage{grid-area:stage}
  .gl-info{grid-area:info}
}

/* --- Botones ------------------------------------------------------------- */
.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:var(--tap);padding:0 18px;border-radius:var(--radius-sm);
  background:linear-gradient(180deg,var(--surface-3),var(--surface-2));
  border:1px solid var(--line);color:var(--text);
  font-weight:700;font-size:15px;cursor:pointer;overflow:hidden;
  transition:transform .09s ease,filter .16s ease,opacity .15s;
  -webkit-tap-highlight-color:transparent;user-select:none
}
.btn:active{transform:scale(.97)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn-accent{
  background:linear-gradient(135deg,var(--game),var(--game-2));
  border:0;color:#0a0713;
  box-shadow:0 6px 22px var(--game-glow),inset 0 1px 0 rgba(255,255,255,.35)
}
.btn-accent:hover:not(:disabled){filter:brightness(1.08)}
.btn-accent:disabled{background:var(--surface-2);color:var(--muted);box-shadow:none}
.btn-gold{
  background:linear-gradient(135deg,var(--gold),var(--gold-2));border:0;color:#241500;
  box-shadow:0 6px 22px rgba(255,197,61,.35),inset 0 1px 0 rgba(255,255,255,.4)
}
.btn-danger{background:linear-gradient(135deg,#ff4d6d,#c81e4a);border:0;color:#fff;box-shadow:0 6px 22px rgba(255,77,109,.32)}
.btn-warn{background:linear-gradient(135deg,#ffb020,#ff7a3d);border:0;color:#2a1300;box-shadow:0 6px 24px rgba(255,140,40,.4)}
.btn-ghost{background:transparent}
.btn-block{width:100%}
.btn-sm{min-height:38px;padding:0 14px;font-size:13px;border-radius:10px}
.btn-xs{min-height:32px;padding:0 10px;font-size:12px;border-radius:8px}
.btn-lg{min-height:60px;font-size:17px;border-radius:var(--radius-sm)}

/* brillo que cruza el boton principal */
.btn-accent::after,.btn-gold::after,.btn-warn::after{
  content:"";position:absolute;top:0;left:0;width:40%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.42),transparent);
  will-change:transform;animation:sheen 3.6s ease-in-out infinite
}
/* transform, no `left`: el navegador lo resuelve en el compositor. */
@keyframes sheen{
  0%,72%{transform:translateX(-160%) skewX(-18deg)}
  88%,100%{transform:translateX(330%) skewX(-18deg)}
}

/* --- Formularios --------------------------------------------------------- */
.field{margin-bottom:12px}
.label{display:block;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2);margin-bottom:6px;font-weight:600}
.input,select.input{
  width:100%;min-width:0;min-height:var(--tap);padding:0 14px;border-radius:var(--radius-sm);
  background:rgba(8,8,18,.6);border:1px solid var(--line);color:var(--text);
  font-variant-numeric:tabular-nums;font-weight:600;outline:none;appearance:none;transition:.15s
}
.input:focus{border-color:var(--game);box-shadow:0 0 0 3px var(--game-glow)}
.input.err{border-color:var(--lose)}
textarea.input{min-height:84px;padding:12px 14px;resize:vertical}
.input-group{display:flex;gap:6px;min-width:0}
.input-group .input{flex:1 1 0;min-width:0}
.input-group .btn{flex:0 0 auto;padding:0 12px}
.hint{font-size:12px;color:var(--muted-2);margin-top:6px}
.err-text{font-size:12px;color:var(--lose);margin-top:6px}

.seg{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:4px;min-width:0;
  background:rgba(8,8,18,.6);border:1px solid var(--line);border-radius:var(--radius-sm);padding:4px
}
.seg button{
  min-height:42px;border:0;border-radius:9px;background:transparent;color:var(--muted);
  font-weight:700;font-size:14px;cursor:pointer;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 6px;transition:.15s
}
.seg button.on{
  background:linear-gradient(180deg,var(--surface-3),var(--surface-2));color:#fff;
  box-shadow:0 2px 10px rgba(0,0,0,.4)
}
.seg button.on[data-v="under"],.seg button.on[data-v="over"]{color:var(--game)}

/* Variante para barras de MUCHAS pestanas, como la del panel de admin.
   .seg reparte el ancho en partes iguales, que es lo correcto con dos o tres
   opciones. Con nueve y en un telefono, cada una queda en 38 px y los nombres
   se cortan en la primera letra: la barra pasa a decir "D... S... P..." y deja
   de servir para nada. Aca cada boton se queda con su ancho y la barra se
   desliza, que es como funciona cualquier barra de pestanas en un telefono. */
.seg-scroll{
  grid-auto-columns:max-content;overflow-x:auto;scrollbar-width:none;
  -webkit-overflow-scrolling:touch
}
.seg-scroll::-webkit-scrollbar{display:none}
.seg-scroll button{padding:0 14px}

.row{display:flex;align-items:center;gap:10px;min-width:0}
.row>.input{min-width:0}
.row-wrap{flex-wrap:wrap}
.row-between{display:flex;align-items:center;justify-content:space-between;gap:10px}
.stack{display:flex;flex-direction:column;gap:12px}

/* --- Stats --------------------------------------------------------------- */
.stat{
  background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.012));
  border:1px solid var(--line-soft);border-radius:var(--radius-sm);padding:10px;
  min-width:0;overflow:hidden
}
.stat .k{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600}
.stat .v{font-size:15px;font-weight:800;font-variant-numeric:tabular-nums;margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:-.01em}
@media(min-width:520px){.stat .v{font-size:17px}}
/* En pantallas angostas el numero se achica antes que cortarse.
   .stat recorta con puntos suspensivos, y sobre un importe eso es peligroso:
   "$1.189.800,00" se muestra como "$1.189.8..." y se lee como cien mil. En
   pesos los importes tienen muchos digitos, asi que el caso es la regla y no
   la excepcion. Perder dos pixeles de tamano es mejor que perder tres cifras. */
@media(max-width:460px){
  .stat .v{font-size:13px;letter-spacing:-.02em}
}
.stats-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.stats-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.stats-4{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
/* Y en las pantallas mas angostas, tres columnas de importes no entran ni
   achicando la letra: "$1.189.800,00" son trece caracteres en 118 px. Pasan a
   dos y se lee todo. Dice se queda en tres porque ahi los valores son cortos
   —un multiplicador, un porcentaje— y las tres cifras se comparan de un
   vistazo mientras se mueve la barra. */
@media(max-width:430px){
  .stats-3{grid-template-columns:repeat(2,minmax(0,1fr))}
  .stats-3.dice-stats{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media(min-width:760px){.stats-4{grid-template-columns:repeat(4,minmax(0,1fr))}}

/* --- Chips / tablas / badges --------------------------------------------- */
.chips{display:flex;gap:6px;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.chips::-webkit-scrollbar{display:none}
.chip{
  flex:0 0 auto;min-width:62px;text-align:center;padding:7px 11px;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--line);
  font-size:12px;font-weight:800;font-variant-numeric:tabular-nums;color:var(--muted)
}
.chip.win{color:var(--win);border-color:rgba(37,229,154,.4);background:rgba(37,229,154,.12);box-shadow:0 0 14px rgba(37,229,154,.14)}
.chip.lose{color:var(--lose);border-color:rgba(255,77,109,.32);background:rgba(255,77,109,.08)}
.chip.c-low{color:#ff8f6e;border-color:rgba(255,143,110,.32);background:rgba(255,143,110,.08)}
.chip.c-mid{color:var(--gold);border-color:rgba(255,197,61,.32);background:rgba(255,197,61,.09)}
.chip.c-hi{color:var(--win);border-color:rgba(37,229,154,.36);background:rgba(37,229,154,.1)}
.chip.c-max{color:#7cc4ff;border-color:rgba(124,196,255,.4);background:rgba(124,196,255,.12);box-shadow:0 0 16px rgba(124,196,255,.22)}

.table{width:100%;border-collapse:collapse;font-size:13px}
.table th{
  text-align:left;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted-2);
  padding:9px 10px;border-bottom:1px solid var(--line-soft);font-weight:700;white-space:nowrap
}
.table td{padding:11px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
.table tr:last-child td{border-bottom:0}
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 -16px;padding:0 16px}

.badge{display:inline-block;padding:3px 9px;border-radius:999px;font-size:11px;font-weight:800;background:var(--surface-3);color:var(--muted)}
.badge.ok{background:rgba(37,229,154,.14);color:var(--win)}
.badge.bad{background:rgba(255,77,109,.14);color:var(--lose)}
.badge.wait{background:rgba(255,197,61,.14);color:var(--gold)}

.empty{padding:38px 16px;text-align:center;color:var(--muted-2)}
.muted{color:var(--muted)}
.dim{color:var(--muted-2)}
.pos{color:var(--win)}
.neg{color:var(--lose)}
.gold{color:var(--gold)}
.center{text-align:center}
.nowrap{white-space:nowrap}
.mono{font-family:var(--mono);font-size:12px;word-break:break-all}

/* --- Toasts / Modal ------------------------------------------------------ */
.toasts{position:fixed;left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));z-index:300;display:flex;flex-direction:column;gap:8px;pointer-events:none}
@media(min-width:700px){.toasts{left:auto;width:352px}}
.toast{
  background:linear-gradient(180deg,var(--surface-3),var(--surface-2));
  border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:13px 15px;font-size:14px;font-weight:600;box-shadow:var(--shadow);
  animation:toastIn .24s cubic-bezier(.22,1.2,.36,1);pointer-events:auto
}
.toast.err{border-color:rgba(255,77,109,.5);box-shadow:var(--shadow),0 0 26px rgba(255,77,109,.16)}
.toast.ok{border-color:rgba(37,229,154,.45);box-shadow:var(--shadow),0 0 26px rgba(37,229,154,.16)}
@keyframes toastIn{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:none}}

.modal-back{position:fixed;inset:0;background:rgba(3,3,10,.72);z-index:400;display:flex;align-items:flex-end;justify-content:center;backdrop-filter:blur(6px)}
@media(min-width:700px){.modal-back{align-items:center}}
.modal{
  width:100%;max-width:540px;max-height:88dvh;overflow:auto;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius) var(--radius) 0 0;padding:20px;
  padding-bottom:calc(20px + env(safe-area-inset-bottom));
  animation:sheetIn .26s cubic-bezier(.32,.72,0,1);box-shadow:var(--shadow)
}
@media(min-width:700px){.modal{border-radius:var(--radius)}}
@keyframes sheetIn{from{transform:translateY(28px);opacity:0}to{transform:none;opacity:1}}

/* ==========================================================================
   HOME / lobby
   ========================================================================== */
.hero{
  position:relative;overflow:hidden;border-radius:var(--radius);
  background:linear-gradient(120deg,#241a4d 0%,#17132e 55%,#120f22 100%);
  border:1px solid var(--line);padding:22px 20px;box-shadow:var(--shadow)
}
.hero::after{
  content:"";position:absolute;right:-70px;top:-90px;width:280px;height:280px;border-radius:50%;
  background:radial-gradient(circle,rgba(177,76,255,.4),transparent 66%);pointer-events:none
}
.hero-label{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2);font-weight:700}
.hero-balance{
  font-size:clamp(34px,10vw,46px);font-weight:900;letter-spacing:-.03em;line-height:1.05;margin-top:4px;
  background:linear-gradient(180deg,#fff 20%,#ffd98a 100%);-webkit-background-clip:text;background-clip:text;color:transparent
}
.hero-actions{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap;position:relative;z-index:1}
.hero-actions .btn{min-height:46px;padding:0 16px;font-size:14px}
.hero{padding:20px 18px}
@media(min-width:620px){.hero{padding:26px 24px}}

.game-grid{display:grid;gap:12px;grid-template-columns:1fr}
@media(min-width:620px){.game-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
.game-card{
  position:relative;display:block;border-radius:var(--radius);overflow:hidden;
  isolation:isolate;
  border:1px solid var(--line-soft);background:var(--surface-flat);
  box-shadow:var(--shadow-sm);transition:transform .18s cubic-bezier(.22,1.2,.36,1),box-shadow .18s
}
.game-card:hover{transform:translateY(-4px);box-shadow:0 20px 44px rgba(0,0,0,.55)}
.game-card:active{transform:scale(.985)}
/* Sin object-fit el navegador ESTIRA la foto para llegar al 16/10 y las caras
   y las cartas salen deformadas. Con cover recorta, que es lo correcto. */
.game-card .cover{
  display:block;width:100%;aspect-ratio:16/10;object-fit:cover;object-position:center;
  background:var(--surface-flat);
  transition:transform .45s cubic-bezier(.22,.9,.3,1),filter .3s;
}
.game-card:hover .cover{transform:scale(1.06)}
.game-card .meta{
  position:absolute;left:0;right:0;bottom:0;padding:26px 16px 13px;z-index:1;
  /* Opaco abajo a proposito. Las portadas traen el nombre del juego escrito
     adentro; se recorta casi todo en portadas.php y esta franja tapa lo que
     sobra, para que el nombre no se lea dos veces encimado. */
  background:linear-gradient(180deg,
    transparent 0%, rgba(6,5,14,.55) 34%, rgba(6,5,14,.94) 60%, #06050e 100%)
}
.game-card .gname{display:block;font-size:19px;font-weight:900;letter-spacing:-.02em;line-height:1.15}
.game-card .gsub{display:block;font-size:12px;color:var(--muted);margin-top:3px;font-weight:600}
.game-card .meta{display:block}

/* ==========================================================================
   DICE
   ========================================================================== */
.dice-stage{
  position:relative;overflow:hidden;
  display:flex;flex-direction:column;justify-content:center;
  min-height:340px;padding:34px 26px 30px;
  /* Mesa de casino insinuada: un halo del color del juego arriba y el paño
     oscuro abajo. Antes era un degrade plano y el escenario parecia una caja. */
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(60,90,190,.28), transparent 62%),
    linear-gradient(180deg,#161d36 0%,#101527 55%,#0b0e1c 100%);
  border:1px solid var(--line-soft);border-radius:var(--radius);
  box-shadow:var(--shadow-sm),inset 0 1px 0 rgba(255,255,255,.05)
}
/* vinieta: cierra los bordes y empuja la vista al centro */
.dice-stage::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:radial-gradient(110% 75% at 50% 45%,transparent 55%,rgba(3,4,10,.55) 100%);
}
.dice-stage::before{
  content:"";position:absolute;left:50%;top:-40%;width:min(560px,140%);height:300px;transform:translateX(-50%);
  background:radial-gradient(ellipse at center,var(--game-glow),transparent 68%);opacity:.5;pointer-events:none;
  transition:opacity .4s
}
.dice-stage.flash-win::before{opacity:1}

.dice-roll{
  position:relative;z-index:1;text-align:center;
  font-size:clamp(52px,14vw,84px);font-weight:900;
  font-variant-numeric:tabular-nums;color:var(--muted-2);
  letter-spacing:-.04em;line-height:1;margin-bottom:44px;transition:color .25s
}
.dice-roll.win{color:var(--win);text-shadow:0 0 46px rgba(37,229,154,.55)}
.dice-roll.lose{color:var(--lose);text-shadow:0 0 38px rgba(255,77,109,.4)}
.dice-roll.pop{animation:rollPop .5s cubic-bezier(.22,1.5,.36,1)}
@keyframes rollPop{0%{transform:scale(.7);opacity:.3}60%{transform:scale(1.1)}100%{transform:scale(1)}}

/* --- la barra es el juego, no una rayita --- */
.dice-bar{
  position:relative;z-index:1;height:34px;border-radius:999px;
  background:#080b14;
  box-shadow:inset 0 3px 10px rgba(0,0,0,.75),inset 0 -1px 0 rgba(255,255,255,.06),
             0 2px 0 rgba(255,255,255,.03)
}
.dice-bar .zone{
  position:absolute;top:3px;bottom:3px;overflow:hidden;
  display:flex;align-items:center;
  transition:left .2s,width .2s
}
.dice-bar .zone-lose{
  background:linear-gradient(180deg,#ff6a83,#b81b3d 78%,#8f1330);
  box-shadow:inset 0 -3px 8px rgba(0,0,0,.4),inset 0 2px 0 rgba(255,255,255,.22);
  justify-content:flex-end
}
.dice-bar .zone-win{
  background:linear-gradient(180deg,#3df7b0,#0d9d69 78%,#087a51);
  box-shadow:inset 0 -3px 8px rgba(0,0,0,.35),inset 0 2px 0 rgba(255,255,255,.3),
             0 0 26px rgba(37,229,154,.3)
}
.dice-bar .zone:first-of-type{border-radius:999px 4px 4px 999px}
.dice-bar .zone:nth-of-type(2){border-radius:4px 999px 999px 4px}
/* Que color es que: sin esto hay que mirar el panel para saberlo. */
.dice-etq{
  padding:0 12px;font-size:11px;font-weight:900;letter-spacing:.1em;
  white-space:nowrap;overflow:hidden;text-overflow:clip;
  font-variant-numeric:tabular-nums;
}
.zone-win .dice-etq{color:#03291b;text-shadow:0 1px 0 rgba(255,255,255,.25)}
.zone-lose .dice-etq{color:#3d0512;text-shadow:0 1px 0 rgba(255,255,255,.2)}

/* --- la nube de tiros anteriores, arriba del numero -----------------------
   El escenario tenia 340 px de alto para un numero, una barra y una regla: el
   resto era fondo. Cada punto es un tiro anterior en el mismo eje 0-100 de la
   barra, los mas nuevos abajo y mas brillantes. Llena el vacio con lo unico
   que se mira en un juego asi: de que lado viene cayendo. */
.dice-huellas{
  position:relative;z-index:1;height:74px;margin-bottom:6px;pointer-events:none
}
.dice-huellas i{
  position:absolute;width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;
}
.dice-huellas i.win{background:var(--win);box-shadow:0 0 6px rgba(37,229,154,.6)}
.dice-huellas i.lose{background:var(--lose);box-shadow:0 0 5px rgba(255,77,109,.5)}

/* --- donde cayeron los ultimos tiros --- */
.dice-pines{position:absolute;inset:0;pointer-events:none;z-index:2}
.dice-pines i{
  position:absolute;top:-7px;width:2px;height:calc(100% + 14px);
  transform:translateX(-1px);border-radius:2px;
}
.dice-pines i.win{background:rgba(190,255,228,.85);box-shadow:0 0 6px rgba(37,229,154,.8)}
.dice-pines i.lose{background:rgba(255,200,210,.8);box-shadow:0 0 6px rgba(255,77,109,.7)}

/* --- el golpe al aterrizar --- */
.dice-onda{
  position:absolute;top:50%;width:26px;height:26px;margin-left:-13px;margin-top:-13px;
  border-radius:50%;pointer-events:none;opacity:0;z-index:3;
  border:2px solid #fff;
}
.dice-onda.activa{animation:diceGolpe .5s cubic-bezier(.2,.7,.3,1)}
.dice-onda.win{border-color:var(--win)}
.dice-onda.lose{border-color:var(--lose)}
@keyframes diceGolpe{
  0%{opacity:.9;transform:scale(.3)}
  100%{opacity:0;transform:scale(3.4)}
}

/* El globo con el tiro va ARRIBA de la barra, no encima.
   Estaba en top:50%, o sea centrado sobre la barra, y como mide 58 px de ancho
   y las etiquetas de cada zona viven en los extremos de la barra, cualquier
   tiro que cayera cerca de una punta se le sentaba encima. Medido en un tiro
   real: a 390 px el globo tapaba 39 de los 100 px de "50.00 – 100", y a 1440
   un 9.88 tapaba la mitad de "GANÁS 0 – 50.00" — justo la etiqueta que dice si
   ese tiro entraba o no, que es lo unico que se quiere leer en ese momento.
   Subido, la flecha sigue apuntando al punto exacto del tiro y la barra queda
   entera: la onda del impacto y los pines de los tiros anteriores, que si van
   sobre la barra, no se tapan con nada.
   El hueco de 44 px que deja .dice-roll es lo que necesita el globo (38 de
   alto mas la flecha) con 2 px de aire. */
.dice-marker{
  position:absolute;top:-42px;left:0;width:58px;height:38px;margin-left:-29px;
  transition:transform .42s cubic-bezier(.18,1.5,.35,1);
  z-index:4;pointer-events:none;opacity:0;will-change:transform
}
.dice-marker.win,.dice-marker.lose{opacity:1}
/* Mientras barre y mientras frena lo mueve el rAF cuadro a cuadro: con la
   transicion CSS encima las dos animaciones pelean y el marcador se arrastra
   por detras. Y hay que hacerlo visible, que si no barre sin verse. */
.dice-marker.buscando{opacity:.9;transition:none}
.dice-marker.buscando i{background:linear-gradient(180deg,#e8ecff,#aab4d8);color:#1a1d2e}
/* estela: se ve solo mientras barre y da sensacion de velocidad */
.dice-marker.buscando::before{
  content:"";position:absolute;top:50%;right:50%;width:70px;height:3px;margin-top:-1px;
  border-radius:3px;background:linear-gradient(270deg,rgba(255,255,255,.5),transparent);
}
.dice-marker i{
  display:grid;place-items:center;width:58px;height:38px;border-radius:10px;
  transform:translateX(var(--dx,0px));
  background:linear-gradient(180deg,#fff,#dfe4f5);color:#0a0d18;font-style:normal;
  font-size:13px;font-weight:900;font-variant-numeric:tabular-nums;
  box-shadow:0 6px 18px rgba(0,0,0,.6),inset 0 -2px 0 rgba(0,0,0,.12)
}
.dice-marker i::after{
  content:"";position:absolute;left:50%;bottom:-5px;width:10px;height:10px;
  /* Compensa el corrimiento del globo: la flecha queda en el tiro de verdad. */
  margin-left:calc(-5px - var(--dx,0px));
  background:inherit;transform:rotate(45deg);border-radius:2px
}
.dice-marker.win i{background:linear-gradient(180deg,#5cffc0,#12b87c);color:#03291b}
.dice-marker.lose i{background:linear-gradient(180deg,#ff7f95,#d02347);color:#fff}
@media (prefers-reduced-motion: reduce){
  .dice-onda.activa{animation:none}
  .dice-marker.buscando::before{display:none}
}
/* Los huecos del panel de dice. Estaban como estilo inline en dice.js, o sea
   imposibles de ajustar desde el CSS: en una laptop baja el boton de apostar
   quedaba abajo del pliegue y no habia forma de apretarlos. */
.dice-racha{text-align:center;min-height:24px;margin-bottom:12px}
.dice-mults{gap:6px;margin-bottom:12px}
.dice-stats{margin-bottom:14px}
.gl-panel .btn-ghost.btn-block{margin-top:8px}

.dice-scale{position:relative;z-index:1;display:flex;justify-content:space-between;margin-top:8px;font-size:11px;color:var(--muted-2);font-variant-numeric:tabular-nums;font-weight:600}

.slider{-webkit-appearance:none;appearance:none;width:100%;height:36px;background:transparent;margin:0;cursor:pointer}
.slider::-webkit-slider-runnable-track{height:10px;border-radius:999px;background:linear-gradient(90deg,var(--game),var(--game-2))}
.slider::-webkit-slider-thumb{
  -webkit-appearance:none;width:30px;height:30px;border-radius:50%;
  background:radial-gradient(circle at 34% 30%,#fff,#cfd6ff 42%,#8f9bd6);
  border:0;margin-top:-10px;box-shadow:0 3px 12px rgba(0,0,0,.6),0 0 0 4px rgba(255,255,255,.08)
}
.slider::-moz-range-track{height:10px;border-radius:999px;background:linear-gradient(90deg,var(--game),var(--game-2))}
.slider::-moz-range-thumb{width:26px;height:26px;border-radius:50%;background:#fff;border:0;box-shadow:0 3px 12px rgba(0,0,0,.6)}

/* ==========================================================================
   CRASH
   ========================================================================== */
/* En vuelo el escenario es un boton: lo dice el cartel del medio y ahora lo
   cumple (ver el listener en crash.js). El cursor lo anuncia en escritorio. */
.crash-stage:has(.crash-mult.running){cursor:pointer}
.crash-stage{
  position:relative;border-radius:var(--radius);overflow:hidden;
  border:1px solid var(--line-soft);aspect-ratio:16/11;min-height:280px;
  background:linear-gradient(180deg,#1a1030 0%,#120c22 48%,#0a0714 100%);
  box-shadow:var(--shadow-sm)
}
/* 901 y no 980: es el corte unico de escritorio (ver .game-layout). */
@media(min-width:901px){.crash-stage{aspect-ratio:16/9}}
#crashCanvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.crash-mult{position:absolute;inset:0;display:grid;place-content:center;text-align:center;pointer-events:none}
.crash-mult .m{
  font-size:clamp(46px,15vw,88px);font-weight:900;font-variant-numeric:tabular-nums;
  letter-spacing:-.045em;line-height:1;color:#fff;text-shadow:0 0 40px rgba(255,255,255,.28)
}
.crash-mult .s{font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted);margin-top:10px;font-weight:700}
.crash-mult.busted .m{color:var(--lose);text-shadow:0 0 46px rgba(255,77,109,.6);animation:shake .45s}
.crash-mult.cashed .m{color:var(--win);text-shadow:0 0 46px rgba(37,229,154,.6);animation:rollPop .5s cubic-bezier(.22,1.5,.36,1)}
.crash-mult.running .m{color:#fff}
@keyframes shake{
  0%,100%{transform:translateX(0)}
  15%{transform:translateX(-9px)}35%{transform:translateX(8px)}
  55%{transform:translateX(-5px)}78%{transform:translateX(3px)}
}
.crash-stage.busted{animation:redflash .5s}
@keyframes redflash{0%{box-shadow:inset 0 0 0 0 rgba(255,77,109,0)}25%{box-shadow:inset 0 0 120px 0 rgba(255,77,109,.35)}100%{box-shadow:inset 0 0 0 0 rgba(255,77,109,0)}}

/* ==========================================================================
   SLOTS
   ========================================================================== */
.slot-stage{
  position:relative;border-radius:var(--radius);padding:14px;
  background:linear-gradient(180deg,#2a1348 0%,#1b0f33 46%,#120a22 100%);
  border:1px solid #4a2a7a;
  box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.07)
}
.slot-frame{
  position:relative;border-radius:14px;padding:8px;
  background:linear-gradient(180deg,#0d0718,#08040f);
  border:1px solid rgba(255,197,61,.28);
  box-shadow:inset 0 3px 16px rgba(0,0,0,.8),0 0 0 1px rgba(0,0,0,.5)
}
.reels{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;position:relative}
.reel{
  position:relative;border-radius:10px;overflow:hidden;
  background:linear-gradient(180deg,#181030,#100a20);
  box-shadow:inset 0 6px 14px rgba(0,0,0,.6)
}
.reel-strip{display:grid;gap:6px;padding:6px;will-change:transform}
.cell{
  position:relative;aspect-ratio:1/1;border-radius:9px;
  background:linear-gradient(180deg,#241a44,#1a1233);
  display:grid;place-items:center;overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06)
}
.cell svg{width:78%;height:78%;display:block}
.cell.hl{
  background:linear-gradient(180deg,#3c2a6b,#2a1c52);
  box-shadow:inset 0 0 0 2px var(--gold),0 0 22px rgba(255,197,61,.4);
  animation:cellPulse .85s ease-in-out infinite alternate
}
.cell.hl-sc{box-shadow:inset 0 0 0 2px #ff5ec7,0 0 22px rgba(255,94,199,.42)}
.cell.dimmed{opacity:.26;filter:saturate(.4)}
@keyframes cellPulse{from{transform:scale(1)}to{transform:scale(1.045)}}

.winline-svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:3;overflow:visible}
.winline-svg path{
  fill:none;stroke:var(--gold);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 0 7px rgba(255,197,61,.85));
  stroke-dasharray:1000;stroke-dashoffset:1000;animation:drawline .5s ease forwards
}
@keyframes drawline{to{stroke-dashoffset:0}}

.slot-topbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;gap:10px}
.slot-title{
  font-size:15px;font-weight:900;letter-spacing:.06em;
  background:linear-gradient(180deg,#ffe9a8,var(--gold-2));-webkit-background-clip:text;background-clip:text;color:transparent
}
.slot-win{
  text-align:center;min-height:44px;margin-top:12px;transition:opacity .25s;opacity:0
}
.slot-win small{display:block;font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold);font-weight:800}
.slot-win span{
  display:block;font-size:30px;font-weight:900;font-variant-numeric:tabular-nums;line-height:1.1;
  background:linear-gradient(180deg,#fff6d5,var(--gold-2));-webkit-background-clip:text;background-clip:text;color:transparent;
  text-shadow:0 0 30px rgba(255,197,61,.35)
}
.slot-win.big span{animation:rollPop .55s cubic-bezier(.22,1.5,.36,1)}
.fs-banner{
  margin-top:12px;padding:11px 14px;border-radius:var(--radius-sm);text-align:center;
  background:linear-gradient(135deg,rgba(255,94,199,.2),rgba(255,197,61,.16));
  border:1px solid rgba(255,197,61,.42);color:#ffe08a;font-weight:800;letter-spacing:.04em;
  animation:cellPulse 1.1s ease-in-out infinite alternate
}
.paytable-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(126px,1fr));gap:8px;min-width:0}
.pt-item{
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.015));
  border:1px solid var(--line-soft);border-radius:var(--radius-sm);padding:10px;
  display:flex;gap:10px;align-items:center;min-width:0
}
.pt-item>svg{width:40px;height:40px;flex:0 0 auto}
.pt-rows{flex:1;min-width:0}
.pt-name{font-size:11px;font-weight:800;letter-spacing:.06em;color:var(--muted);margin-bottom:3px}
.pt-row{display:flex;justify-content:space-between;font-size:12px;color:var(--muted-2);font-variant-numeric:tabular-nums;font-weight:600}
.pt-row b{color:var(--gold);font-weight:800}

/* ==========================================================================
   Auth
   ========================================================================== */
.auth-wrap{
  min-height:100dvh;display:grid;place-items:center;padding:24px 16px;
  background:
    radial-gradient(900px 520px at 76% 6%, rgba(124,92,255,.26), transparent 60%),
    radial-gradient(760px 460px at 12% 90%, rgba(255,92,199,.16), transparent 60%),
    var(--bg)
}
.auth-card{
  width:100%;max-width:412px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--radius);padding:26px;box-shadow:var(--shadow)
}
.auth-brand{display:flex;align-items:center;gap:10px;justify-content:center;font-weight:900;letter-spacing:-.01em;margin-bottom:6px;font-size:22px}
.auth-brand .brand-mark{width:32px;height:32px;flex:0 0 auto;filter:drop-shadow(0 0 10px rgba(124,92,255,.55))}
.auth-sub{text-align:center;color:var(--muted-2);font-size:13px;margin-bottom:22px}
.auth-switch{text-align:center;margin-top:16px;font-size:14px;color:var(--muted)}
.auth-switch button{background:none;border:0;color:var(--brand-2);font-weight:700;cursor:pointer;padding:8px}

/* --- utilidades ---------------------------------------------------------- */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.fineprint{font-size:11px;color:var(--muted-2);text-align:center;margin-top:10px}
.spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.25);border-top-color:currentColor;border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.skeleton{
  background:linear-gradient(90deg,var(--surface-2),var(--surface-3),var(--surface-2));
  background-size:200% 100%;animation:sk 1.2s linear infinite;border-radius:var(--radius-sm)
}
@keyframes sk{to{background-position:-200% 0}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}

/* ==========================================================================
   CAPA 2 — casino de verdad: ambiente, celebracion, ticker, cabina
   ========================================================================== */

/* --- tipografia de display ----------------------------------------------- */
:root{
  --display:"Avenir Next Condensed","HelveticaNeue-CondensedBold","Arial Narrow",
            "Inter",-apple-system,BlinkMacSystemFont,sans-serif;
}
.display{font-family:var(--display);font-weight:800;letter-spacing:.02em}

/* --- orbes de ambiente que respiran de fondo ----------------------------- */
.ambient{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
.ambient i{
  position:absolute;display:block;border-radius:50%;opacity:.75;
  will-change:transform;animation:drift 26s ease-in-out infinite alternate
}
.ambient i:nth-child(1){width:54vmax;height:54vmax;left:-18vmax;top:-20vmax;
  background:radial-gradient(circle,rgba(124,92,255,.34),rgba(124,92,255,0) 68%)}
.ambient i:nth-child(2){width:46vmax;height:46vmax;right:-16vmax;top:4vmax;
  background:radial-gradient(circle,rgba(255,92,199,.24),rgba(255,92,199,0) 68%);
  animation-duration:34s;animation-delay:-8s}
.ambient i:nth-child(3){width:42vmax;height:42vmax;left:18vmax;bottom:-20vmax;
  background:radial-gradient(circle,rgba(34,211,238,.20),rgba(34,211,238,0) 68%);
  animation-duration:40s;animation-delay:-16s}
@keyframes drift{
  0%{transform:translate3d(0,0,0) scale(1)}
  50%{transform:translate3d(4vmax,-3vmax,0) scale(1.12)}
  100%{transform:translate3d(-3vmax,4vmax,0) scale(.95)}
}

/* --- toggle de sonido ---------------------------------------------------- */
.sound-btn{
  /* Discreto a proposito: antes tenia borde violeta y brillo, y competia por
     atencion con el boton de la cajera, que si es una accion. */
  width:var(--tap);height:var(--tap);display:grid;place-items:center;
  background:transparent;border:0;border-radius:var(--radius-sm);
  color:var(--muted-2);cursor:pointer;transition:color .16s,background .16s;
}
.sound-btn:hover{color:var(--text);background:var(--surface-2)}
.sound-btn.on{color:var(--muted)}
.sound-btn.on:hover{color:var(--text)}
.sound-btn svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* --- celebracion de premio ----------------------------------------------- */
.celebrate{
  position:fixed;inset:0;z-index:500;display:grid;place-items:center;
  background:radial-gradient(circle at 50% 42%,rgba(40,20,70,.72),rgba(4,3,10,.9));
  backdrop-filter:blur(3px);animation:celIn .22s ease
}
.celebrate.out{animation:celOut .26s ease forwards}
@keyframes celIn{from{opacity:0}to{opacity:1}}
@keyframes celOut{to{opacity:0}}
.celebrate canvas{position:absolute;inset:0;width:100%;height:100%}
.celebrate-box{
  position:relative;text-align:center;z-index:1;
  padding:26px clamp(24px,7vw,54px);border-radius:24px;
  background:linear-gradient(180deg,rgba(38,22,70,.82),rgba(14,8,28,.88));
  border:1px solid rgba(255,197,61,.45);
  box-shadow:0 26px 80px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,255,255,.14),0 0 70px rgba(255,197,61,.18);
  backdrop-filter:blur(3px);
  animation:celPop .5s cubic-bezier(.22,1.6,.36,1)
}
.celebrate-box::before{
  content:"";position:absolute;inset:6px;border-radius:18px;pointer-events:none;
  border:1px solid rgba(255,197,61,.18)
}
.celebrate-label{
  font-family:var(--display);font-size:clamp(26px,8vw,46px);font-weight:900;letter-spacing:.16em;
  background:linear-gradient(180deg,#fff8dd 10%,var(--gold) 55%,#e07f10 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 4px 22px rgba(255,197,61,.55));
  animation:celPop .5s cubic-bezier(.22,1.6,.36,1)
}
.celebrate-amount{
  font-size:clamp(40px,13vw,78px);font-weight:900;font-variant-numeric:tabular-nums;
  letter-spacing:-.03em;color:#fff;margin-top:6px;text-shadow:0 0 40px rgba(255,255,255,.4)
}
.celebrate-hint{margin-top:18px;font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.42)}
.celebrate-amount::after{
  content:"";display:block;width:64px;height:2px;margin:14px auto 0;border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--gold),transparent)
}
@keyframes celPop{0%{transform:scale(.6);opacity:0}70%{transform:scale(1.08)}100%{transform:scale(1);opacity:1}}

/* --- ticker de jugadas en vivo ------------------------------------------- */
.ticker{
  position:relative;overflow:hidden;border-radius:var(--radius-sm);
  background:linear-gradient(90deg,rgba(255,255,255,.05),rgba(255,255,255,.02));
  border:1px solid var(--line-soft);height:46px
}
.ticker::before,.ticker::after{
  content:"";position:absolute;top:0;bottom:0;width:44px;z-index:2;pointer-events:none
}
.ticker::before{left:0;background:linear-gradient(90deg,var(--bg),transparent)}
.ticker::after{right:0;background:linear-gradient(270deg,var(--bg),transparent)}
.ticker-track{display:flex;gap:8px;align-items:center;height:100%;padding:0 10px;width:max-content;animation:slide 46s linear infinite}
.ticker:hover .ticker-track{animation-play-state:paused}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.tick-item{
  display:flex;align-items:center;gap:7px;flex:0 0 auto;padding:5px 11px;border-radius:999px;
  background:rgba(8,8,18,.55);border:1px solid var(--line-soft);font-size:12px;font-weight:700;white-space:nowrap
}
.tick-item .u{color:var(--muted-2)}
.tick-item .g{color:var(--muted)}
.tick-item .x{color:var(--gold);font-variant-numeric:tabular-nums}
.tick-item.w .x{color:var(--win)}
.tick-dot{width:6px;height:6px;border-radius:50%;background:var(--win);box-shadow:0 0 8px var(--win)}

/* --- lobby: hero con arte ------------------------------------------------ */
.hero-art{position:absolute;right:-8px;bottom:-10px;width:min(46%,240px);opacity:.9;pointer-events:none}
@media(max-width:520px){.hero-art{width:150px;opacity:.55;right:-14px}}
.hero-tag{
  display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:999px;
  background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);
  font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:#e5dcff;margin-bottom:10px
}

/* --- lobby: tiles -------------------------------------------------------- */
.game-card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07);transition:box-shadow .2s
}
.game-card:hover::after{box-shadow:inset 0 0 0 2px var(--game),0 0 34px var(--game-glow)}
.game-card .play{
  position:absolute;inset:0;display:grid;place-items:center;z-index:2;
  background:linear-gradient(180deg,rgba(8,6,18,.2),rgba(8,6,18,.62));
  opacity:0;transition:opacity .2s
}
.game-card:hover .play{opacity:1}
.game-card .play span{
  padding:12px 26px;border-radius:999px;font-weight:900;letter-spacing:.12em;font-size:13px;
  background:linear-gradient(135deg,var(--game),var(--game-2));color:#0a0713;
  box-shadow:0 8px 26px var(--game-glow);transform:translateY(8px);transition:transform .2s
}
.game-card:hover .play span{transform:none}
.game-card[data-g="dice"]  { --game:#22d3ee; --game-2:#3b82f6; --game-glow:rgba(34,211,238,.4) }
.game-card[data-g="crash"] { --game:#ff7a3d; --game-2:#ff3d6e; --game-glow:rgba(255,122,61,.45) }
.game-card[data-g="slots"] { --game:#ffc53d; --game-2:#ff5ec7; --game-glow:rgba(255,197,61,.4) }
.game-card[data-g="plinko"]{ --game:#4dabff; --game-2:#a855f7; --game-glow:rgba(77,171,255,.42) }
.game-card[data-g="roulette"]{ --game:#2fd38a; --game-2:#c9922a; --game-glow:rgba(47,211,138,.38) }
.game-card[data-g="limbo"]{ --game:#22d3ee; --game-2:#a855f7; --game-glow:rgba(34,211,238,.4) }
.game-card[data-g="wheel"]{ --game:#c77dff; --game-2:#ffc53d; --game-glow:rgba(199,125,255,.42) }
.game-card[data-g="keno"] { --game:#2fd38a; --game-2:#22d3ee; --game-glow:rgba(47,211,138,.4) }
.game-card[data-g="mines"]{ --game:#25e5c8; --game-2:#4dabff; --game-glow:rgba(37,229,200,.4) }
.game-card[data-g="hilo"] { --game:#a855f7; --game-2:#ff5ec7; --game-glow:rgba(168,85,247,.42) }
.game-card[data-g="baccarat"]{ --game:#2fd38a; --game-2:#ffc53d; --game-glow:rgba(47,211,138,.38) }
.game-card .gname{font-family:var(--display);letter-spacing:.03em}

.section-head{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:20px 0 10px
}
.section-head h2{font-size:13px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2)}
.section-head a{font-size:12px;color:var(--brand-2);font-weight:700}

/* --- slots: cabina ornamentada ------------------------------------------- */
.slot-cabinet{
  position:relative;border-radius:22px;padding:3px;
  background:linear-gradient(160deg,#ffe9a8 0%,#c9922a 18%,#6b4a12 38%,#c9922a 62%,#ffe9a8 82%,#8a6318 100%);
  box-shadow:var(--shadow),0 0 46px rgba(255,197,61,.14)
}
.slot-stage{border-radius:19px;border:0;box-shadow:inset 0 1px 0 rgba(255,255,255,.09)}
.slot-marquee{
  position:relative;text-align:center;padding:10px 12px 12px;margin:-2px -2px 12px;
  border-radius:18px 18px 12px 12px;
  background:linear-gradient(180deg,#3a1a63,#22103d);
  border-bottom:1px solid rgba(255,197,61,.28);overflow:hidden
}
.slot-marquee::after{
  content:"";position:absolute;left:0;top:0;width:32%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.16),transparent);
  animation:sheen 5s ease-in-out infinite
}
.slot-marquee h3{
  font-family:var(--display);font-size:clamp(18px,5.2vw,26px);font-weight:900;letter-spacing:.14em;
  background:linear-gradient(180deg,#fff6d5 10%,var(--gold) 50%,#d1810c 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 2px 10px rgba(255,197,61,.4))
}
.slot-marquee p{font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:rgba(255,220,150,.6);margin-top:3px;font-weight:700}
.slot-bulbs{position:absolute;left:0;right:0;top:6px;display:flex;justify-content:space-around;padding:0 14px}
.slot-bulbs i{
  width:5px;height:5px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 8px var(--gold);animation:bulb 1.4s ease-in-out infinite
}
@keyframes bulb{0%,100%{opacity:.25}50%{opacity:1}}
.reel{border:1px solid rgba(255,197,61,.1)}
.reel::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(180deg,rgba(0,0,0,.45),transparent 22%,transparent 78%,rgba(0,0,0,.45))
}
.reel.anticipate{
  box-shadow:inset 0 0 0 2px var(--gold),0 0 26px rgba(255,197,61,.4);
  animation:bulb .5s ease-in-out infinite
}
.cell.land{animation:land .28s cubic-bezier(.3,1.6,.4,1)}
@keyframes land{0%{transform:scaleY(1.12) translateY(-6%)}60%{transform:scaleY(.94)}100%{transform:none}}

/* --- crash: marco --------------------------------------------------------- */
.crash-stage{border:1px solid rgba(255,122,61,.22)}
.crash-badge{
  position:absolute;left:12px;top:12px;z-index:2;display:flex;gap:6px;align-items:center;
  padding:5px 10px;border-radius:999px;background:rgba(8,5,16,.6);border:1px solid rgba(255,255,255,.12);
  font-size:11px;font-weight:800;letter-spacing:.08em;color:var(--muted);backdrop-filter:blur(8px)
}

/* --- dice: tablero -------------------------------------------------------- */
.dice-ticks{position:relative;z-index:1;height:10px;margin-top:10px}
.dice-ticks i{position:absolute;top:0;width:1px;height:6px;background:rgba(255,255,255,.2)}
.streak{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;
  background:rgba(255,197,61,.12);border:1px solid rgba(255,197,61,.3);
  font-size:11px;font-weight:800;color:var(--gold)
}


/* --- topbar: en pantallas chicas queda el simbolo, sin la palabra ---------
   Con la palabra dibujada esto sigue valiendo igual: a 520 px la barra tiene
   que hacerle lugar al saldo y al bote, y el emblema solo ya identifica. */
@media (max-width:520px){
  .brand-mobile .brand-name{display:none}
  .balance-chip{padding:6px 11px}
  .topbar{gap:8px;padding:0 10px}
}

/* --- slots: barra de estado bajo los rodillos ---------------------------- */
.slot-status{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:12px;
  padding:10px;border-radius:12px;
  background:linear-gradient(180deg,rgba(0,0,0,.42),rgba(0,0,0,.24));
  border:1px solid rgba(255,197,61,.16)
}
.slot-status>div{text-align:center;min-width:0}
.slot-status b{
  display:block;font-size:9px;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,220,150,.5);font-weight:800
}
.slot-status span{
  display:block;font-size:17px;font-weight:900;font-variant-numeric:tabular-nums;
  color:#e9e2ff;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis
}
.slot-status .amt.on{
  background:linear-gradient(180deg,#fff6d5,var(--gold-2));
  -webkit-background-clip:text;background-clip:text;color:transparent;
  text-shadow:0 0 26px rgba(255,197,61,.4)
}
.slot-status .amt.big{animation:rollPop .55s cubic-bezier(.22,1.5,.36,1)}

/* Loop de giro de los rodillos. La tira lleva el relleno duplicado, asi que
   desplazar media tira y reiniciar es imperceptible. */
@keyframes reelLoop{from{transform:translateY(0)}to{transform:translateY(var(--loop-y))}}

/* ==========================================================================
   PLINKO
   ========================================================================== */
.plinko-stage{
  position:relative;border-radius:var(--radius);overflow:hidden;padding:12px 12px 14px;
  /* Halo arriba, donde cae la bola, y el fondo cerrandose hacia abajo: el
     tablero deja de ser un rectangulo plano con puntitos. */
  background:
    radial-gradient(90% 55% at 50% -8%, rgba(77,171,255,.22), transparent 60%),
    linear-gradient(180deg,#111c3c 0%,#0c1128 55%,#07091a 100%);
  border:1px solid rgba(77,171,255,.2);box-shadow:var(--shadow-sm)
}
.plinko-stage::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:radial-gradient(120% 80% at 50% 40%,transparent 58%,rgba(3,4,12,.5) 100%);
}
.plinko-board{position:relative;width:100%;aspect-ratio:5/4;min-height:260px}
/* 901 y no 980: es el corte unico de escritorio (ver .game-layout). */
@media(min-width:901px){.plinko-board{aspect-ratio:16/10}}
#plinkoCanvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.plinko-buckets{display:flex;gap:3px;margin-top:8px}
.pk-bucket{
  position:relative;flex:1 1 0;min-width:0;text-align:center;border-radius:5px 5px 7px 7px;
  padding:7px 1px;
  font-size:clamp(8px,2.3vw,13px);font-weight:900;font-variant-numeric:tabular-nums;
  color:#22110a;line-height:1.1;
  transition:transform .16s cubic-bezier(.22,1.3,.36,1),box-shadow .16s;
  overflow:hidden;white-space:nowrap;letter-spacing:-.03em;
  /* Brillo arriba y sombra abajo: son canaletas, no rectangulos de color. */
  box-shadow:inset 0 2px 0 rgba(255,255,255,.45),inset 0 -3px 6px rgba(0,0,0,.35),
             0 2px 4px rgba(0,0,0,.4);
}
.plinko-buckets{gap:2px}
@media(min-width:520px){.plinko-buckets{gap:4px}.pk-bucket{padding:7px 3px;border-radius:8px}}
.pk-bucket.hit{
  transform:translateY(-9px) scale(1.12);z-index:2;
  box-shadow:inset 0 2px 0 rgba(255,255,255,.6),0 10px 26px rgba(255,197,61,.6),
             0 0 0 2px rgba(255,255,255,.55);
}
.plinko-last{
  text-align:center;margin-top:10px;min-height:30px;font-size:20px;font-weight:900;
  font-variant-numeric:tabular-nums;color:var(--muted-2)
}
.plinko-last.win{
  background:linear-gradient(180deg,#fff6d5,var(--gold-2));
  -webkit-background-clip:text;background-clip:text;color:transparent
}

/* ==========================================================================
   RULETA
   ========================================================================== */
.rl-stage{
  position:relative;border-radius:var(--radius);padding:14px;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.014) 0 2px, transparent 2px 4px),
    repeating-linear-gradient(-45deg, rgba(0,0,0,.05) 0 2px, transparent 2px 4px),
    radial-gradient(120% 80% at 50% 0%, #1a5a3c 0%, #0f3324 46%, #08160f 100%);
  border:2px solid transparent;
  background-clip:padding-box;
  box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.06),0 0 0 2px rgba(201,146,42,.35)
}
.rl-stage::before{
  content:"";position:absolute;inset:6px;border-radius:12px;pointer-events:none;
  border:1px solid rgba(255,226,160,.14)
}
.rl-wheel-wrap{position:relative;width:min(300px,72vw);margin:0 auto;aspect-ratio:1/1}
#rlCanvas{position:absolute;inset:0;width:100%;height:100%}
.rl-pointer{
  position:absolute;left:50%;top:-2px;transform:translateX(-50%);
  width:0;height:0;border-left:11px solid transparent;border-right:11px solid transparent;
  border-top:18px solid var(--gold);filter:drop-shadow(0 2px 6px rgba(0,0,0,.6));z-index:2
}
.rl-result{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:30%;aspect-ratio:1/1;border-radius:50%;display:grid;place-items:center;
  font-size:clamp(24px,7vw,38px);font-weight:900;font-variant-numeric:tabular-nums;
  color:#fff;pointer-events:none;z-index:2
}
.rl-result.red{background:radial-gradient(circle,#c4123c,#7a0a24);box-shadow:0 0 34px rgba(196,18,60,.6)}
.rl-result.black{background:radial-gradient(circle,#2a2320,#100c0a);box-shadow:0 0 34px rgba(0,0,0,.7)}
.rl-result.green{background:radial-gradient(circle,#1c9c5c,#0c5130);box-shadow:0 0 34px rgba(28,156,92,.6)}
.rl-result.idle{background:rgba(10,7,5,.62);color:var(--muted-2);font-size:12px;letter-spacing:.16em}
/* rollPop usa transform:scale y pisaba el translate(-50%,-50%) que centra el
   circulo: durante la animacion se iba a la esquina. Keyframes propios que
   conservan el centrado. */
@keyframes rlPop{
  0%{transform:translate(-50%,-50%) scale(.7);opacity:.25}
  60%{transform:translate(-50%,-50%) scale(1.12)}
  100%{transform:translate(-50%,-50%) scale(1)}
}
.rl-result:not(.idle){animation:rlPop .5s cubic-bezier(.22,1.5,.36,1)}
.rl-wheel-wrap{filter:drop-shadow(0 18px 34px rgba(0,0,0,.6))}

/* Tapete clasico: 0 a la izquierda, 12x3 numeros, columnas 2:1 a la derecha,
   docenas y sencillas abajo. En telefono se desliza en horizontal. */
.rl-board-wrap{
  margin-top:14px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;padding-bottom:4px;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%)
}
.rl-board-wrap::-webkit-scrollbar{display:none}
.rl-board{
  display:grid;gap:3px;min-width:max-content;padding:0 14px;
  grid-template-columns:46px repeat(12,46px) 50px;
  grid-template-rows:repeat(3,44px) 40px 40px
}
/* Columnas fluidas desde el mismo 901 en que .game-layout se parte en dos y le
   pone al escenario un panel de 352 px al lado: la columna del escenario pasa
   de (ancho - 56) a (ancho - 420) y la mesa clasica, que mide 715 px fijos,
   deja de entrar. Medido a 1024x768: se salian 153 px y 11 casillas quedaban
   fuera del tapete, con el mismo arrastre invisible que en telefono. Con
   columnas fluidas la mesa se acomoda a la columna que tenga y no desborda en
   ningun ancho. Este numero sigue al de .game-layout: si uno se mueve y el
   otro no, vuelve el desborde. */
@media(min-width:901px){
  .rl-board{grid-template-columns:52px repeat(12,minmax(0,1fr)) 58px;min-width:0;padding:0}
  .rl-board-wrap{-webkit-mask-image:none;mask-image:none;overflow:visible}
}
.rl-zero{border-radius:10px 4px 4px 10px}
/* La posicion de cada casilla llega en variables desde roulette.js, que le
   pone las dos: --gc/--gr para la mesa clasica y --mc/--mr para la vertical de
   telefono. La media query de mas abajo cambia cual de las dos rige. */
.rl-col{font-size:12px;letter-spacing:.02em}

/* --- casillas del tapete -------------------------------------------------- */
.rl-cell{
  grid-column:var(--gc);grid-row:var(--gr);
  position:relative;border-radius:6px;display:grid;place-items:center;
  font-weight:800;font-size:15px;color:#fff;cursor:pointer;
  border:1px solid rgba(255,226,160,.28);
  -webkit-tap-highlight-color:transparent;user-select:none;
  transition:transform .1s,box-shadow .15s;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 2px 5px rgba(0,0,0,.45);
  text-shadow:0 1px 2px rgba(0,0,0,.65)
}
.rl-cell:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.24),0 0 16px rgba(255,226,160,.28)}
.rl-cell:active{transform:scale(.94)}
.rl-cell.red   {background:linear-gradient(180deg,#e0294f,#8c0d2b)}
.rl-cell.black {background:linear-gradient(180deg,#3a302c,#120d0b)}
.rl-cell.green {background:linear-gradient(180deg,#1fb56c,#0b5433)}
.rl-cell.outside{
  background:linear-gradient(180deg,rgba(255,255,255,.13),rgba(255,255,255,.05));
  font-size:11.5px;letter-spacing:.02em;font-weight:800
}
.rl-cell.outside.red  {background:linear-gradient(180deg,#e0294f,#8c0d2b)}
.rl-cell.outside.black{background:linear-gradient(180deg,#3a302c,#120d0b)}
.rl-cell.winner{
  outline:3px solid var(--gold);outline-offset:-2px;z-index:3;
  box-shadow:0 0 26px rgba(255,197,61,.7),inset 0 0 20px rgba(255,197,61,.28);
  animation:winnerPulse .9s ease-in-out 3
}
@keyframes winnerPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}

/* Ficha de verdad sobre la casilla: circulo con canto rayado, como en la mesa. */
.rl-chip-on{
  position:absolute;right:0;bottom:0;width:23px;height:23px;border-radius:50%;
  display:grid;place-items:center;font-size:7.5px;font-weight:900;
  font-variant-numeric:tabular-nums;letter-spacing:-.04em;z-index:2;
  box-shadow:0 3px 8px rgba(0,0,0,.65),inset 0 -2px 4px rgba(0,0,0,.3),inset 0 2px 3px rgba(255,255,255,.35);
  animation:chipDrop .22s cubic-bezier(.3,1.6,.4,1)
}
.rl-chip-on::before{
  content:"";position:absolute;inset:2px;border-radius:50%;
  border:2px dashed rgba(255,255,255,.6)
}
.rl-chip-on.c0 {background:radial-gradient(circle at 35% 30%,#fff,#c3cadd);color:#1b2140}
.rl-chip-on.c1 {background:radial-gradient(circle at 35% 30%,#ff8a9e,#c0102f);color:#fff}
.rl-chip-on.c5 {background:radial-gradient(circle at 35% 30%,#6df0ae,#0e7a48);color:#042a19}
.rl-chip-on.c25{background:radial-gradient(circle at 35% 30%,#ffe9a8,#b8862a);color:#2a1a04}
@keyframes chipDrop{0%{transform:translateY(-14px) scale(.6);opacity:0}100%{transform:none;opacity:1}}

.rl-chips{display:flex;gap:6px;margin-bottom:12px}
.rl-chip{
  flex:1;min-width:0;height:46px;border-radius:50%;border:2px dashed rgba(255,255,255,.3);
  background:linear-gradient(180deg,var(--surface-3),var(--surface-2));
  color:var(--text);font-weight:900;font-size:12px;cursor:pointer;
  font-variant-numeric:tabular-nums;transition:transform .12s
}
.rl-chip.on{
  border:2px solid var(--gold);color:#2a1a04;
  background:linear-gradient(180deg,#fff3c4,var(--gold-2));
  box-shadow:0 4px 16px rgba(255,197,61,.4);transform:translateY(-2px)
}


/* ==========================================================================
   CAPA 3 — mas color de casino
   ========================================================================== */

/* Filo superior de color en las tarjetas de juego y paneles */
.card-glow::after{
  content:"";position:absolute;left:14px;right:14px;top:0;height:2px;border-radius:0 0 3px 3px;
  background:linear-gradient(90deg,transparent,var(--game),transparent);opacity:.7
}

/* Banda promo del lobby */
.promo{
  position:relative;overflow:hidden;border-radius:var(--radius);
  padding:14px 18px;margin-top:12px;
  background:linear-gradient(100deg,#7c1fa8 0%,#c4123c 34%,#ff7a3d 62%,#ffc53d 100%);
  background-size:280% 100%;animation:promoShift 9s ease-in-out infinite alternate;
  box-shadow:var(--shadow-sm),0 0 34px rgba(255,122,61,.22)
}
@keyframes promoShift{from{background-position:0% 50%}to{background-position:100% 50%}}
.promo b{display:block;font-family:var(--display);font-size:clamp(17px,4.6vw,23px);letter-spacing:.06em;color:#fff;
  text-shadow:0 2px 10px rgba(0,0,0,.35)}
.promo span{display:block;font-size:12.5px;font-weight:600;color:rgba(255,255,255,.88);margin-top:2px}
.promo i{
  position:absolute;right:-18px;top:-24px;width:118px;height:118px;border-radius:50%;
  background:radial-gradient(circle,rgba(255,255,255,.34),transparent 66%)
}

/* Chips de categoria */
.cats{display:flex;gap:7px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
.cats::-webkit-scrollbar{display:none}
.cat{
  flex:0 0 auto;padding:8px 15px;border-radius:999px;cursor:pointer;
  background:var(--surface-2);border:1px solid var(--line);
  font-size:12.5px;font-weight:700;color:var(--muted);transition:.15s;white-space:nowrap
}
.cat.on{
  background:var(--brand-grad);border-color:transparent;color:#fff;
  box-shadow:0 4px 16px rgba(124,92,255,.36)
}

/* Franja de estadisticas del lobby */
.lobby-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:12px}
.lobby-stats .stat{text-align:center;background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.015))}
.lobby-stats .stat .v{font-size:17px}
/* Estas etiquetas si pueden partirse en dos lineas: cortarlas con puntos
   suspensivos las volvia ilegibles ("JUGADAS H..."). */
.lobby-stats .stat .k{white-space:normal;overflow:visible;text-overflow:clip;line-height:1.25;letter-spacing:.08em}

/* ==========================================================================
   MOVIL — verificado por tools/mobile_check.sh
   En pantalla tactil todo control llega a 44px (minimo de Apple HIG) y
   ninguna etiqueta baja de 11px. En mouse se mantienen mas compactos.
   ========================================================================== */
/* Se combinan las dos condiciones a proposito: `pointer:coarse` no es fiable
   en todos los navegadores ni en emuladores, y el ancho solo no distingue una
   tablet con mouse. Con cualquiera de las dos alcanza. */
@media (pointer: coarse), (max-width: 900px) {
  .btn        { min-height:48px }
  .btn-sm     { min-height:44px; padding:0 15px }
  .btn-xs     { min-height:44px; padding:0 13px; font-size:13px }
  .btn-lg     { min-height:60px }
  .seg button { min-height:46px }
  .sound-btn  { width:46px; height:46px }
  .icon-btn   { width:48px; height:48px }
  .cat        { padding:12px 17px; font-size:13px }
  .rl-chip    { height:52px }
  /* El tapete define su propio alto con grid-template-rows: forzar
     min-height aca lo desalineaba. Las filas ya miden 44px y 40px. */
  .rl-board   { grid-template-rows:repeat(3,46px) 44px 44px }

  /* tipografia minima legible */
  .stat .k        { font-size:11px }
  .table th       { font-size:11px }
  .card-title     { font-size:11.5px }
  .hint, .fineprint, .pt-name, .pt-row { font-size:11.5px }
  .slot-status b  { font-size:11px }
  .slot-marquee p { font-size:11px }
  .balance-label  { font-size:10px }
  .hero-tag, .badge, .tick-item { font-size:11.5px }
  .nav-group      { font-size:11px }
  .celebrate-hint { font-size:11.5px }
  .crash-badge    { font-size:11.5px }
  .crash-mult .s  { font-size:11.5px }

  /* margen extra abajo: barra del navegador + gesto de inicio */
  .view { padding-bottom:calc(110px + env(safe-area-inset-bottom)) }
}

/* Los cubos de Plinko son una tira densa tipo eje de grafico: hasta 17 en
   pantalla. Se les da el maximo tamano posible sin romper la fila. */
.pk-bucket{font-size:clamp(9px,2.5vw,13px)}

/* ==========================================================================
   LIMBO
   ========================================================================== */
.limbo-stage{
  position:relative;overflow:hidden;display:flex;align-items:stretch;gap:clamp(14px,3vw,30px);
  min-height:340px;padding:22px 24px;
  background:linear-gradient(180deg,#0b1430 0%,#0a0f1f 60%,#080a16 100%);
  border:1px solid var(--line-soft);border-radius:var(--radius);
}
/* estrellas quietas al fondo: la altura se lee mejor con referencias fijas */
.limbo-stage::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background-image:
    radial-gradient(1.4px 1.4px at 18% 22%,rgba(255,255,255,.55),transparent),
    radial-gradient(1.2px 1.2px at 72% 12%,rgba(255,255,255,.4),transparent),
    radial-gradient(1.6px 1.6px at 45% 62%,rgba(255,255,255,.32),transparent),
    radial-gradient(1.2px 1.2px at 88% 44%,rgba(255,255,255,.42),transparent),
    radial-gradient(1.3px 1.3px at 30% 82%,rgba(255,255,255,.28),transparent),
    radial-gradient(1.1px 1.1px at 62% 34%,rgba(255,255,255,.35),transparent);
}

/* ---- el medidor de altura: es el fondo del escenario, no un grafico aparte ---- */
.limbo-stage{--rail:clamp(52px,8vw,74px)}
.lb-medidor{position:absolute;inset:22px 24px;pointer-events:none}
/* el riel vertical */
.lb-medidor::before{
  content:'';position:absolute;left:var(--rail);top:0;bottom:0;width:1px;
  background:linear-gradient(180deg,transparent,rgba(255,255,255,.16) 12%,rgba(255,255,255,.16));
}
.lb-ticks{position:absolute;inset:0}
/* Las ultimas jugadas, a la altura que alcanzaron.
   El campo del medidor estaba vacio: solo la columna pegada al riel y el
   numero grande. Cada marca es un resultado anterior puesto en la MISMA
   escala logaritmica, asi que se ve de un golpe cuantos quedaron por encima
   de la linea del objetivo y cuantos por debajo — que es la unica pregunta
   que se hace alguien mirando limbo. Van detras de la columna y del cohete
   (z-index) para no competir con la jugada en curso. */
.lb-huellas{position:absolute;left:var(--rail);right:0;top:0;bottom:0;pointer-events:none}
.lb-huellas i{
  position:absolute;width:7px;height:7px;margin:-3.5px 0 0 -3.5px;
  border-radius:50%;transition:opacity .3s;
}
.lb-huellas i.win{background:var(--win);box-shadow:0 0 7px rgba(37,229,154,.7)}
.lb-huellas i.lose{background:var(--lose);box-shadow:0 0 6px rgba(255,77,109,.55)}
.lb-tick{
  position:absolute;left:var(--rail);right:0;top:0;height:100%;
  border-bottom:1px dashed rgba(255,255,255,.07);
}
.lb-tick span{
  position:absolute;right:calc(100% + 8px);bottom:-7px;font-size:10px;font-weight:700;
  color:var(--muted);letter-spacing:.03em;font-variant-numeric:tabular-nums;white-space:nowrap;
}
/* la columna que sube, pegada al riel */
.lb-columna{
  position:absolute;left:0;bottom:0;width:var(--rail);height:100%;
  transform:scaleY(0);transform-origin:bottom center;border-radius:0 3px 0 0;
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--game,#7c5cff) 42%,transparent),
    color-mix(in srgb,var(--game,#7c5cff) 5%,transparent));
  transition:transform .5s cubic-bezier(.16,.9,.3,1);
}
.lb-columna.buscando{transition:transform .09s linear}
.lb-columna.directo{transition:none}
.lb-columna.win{background:linear-gradient(180deg,rgba(37,229,154,.42),rgba(37,229,154,.04))}
.lb-columna.lose{background:linear-gradient(180deg,rgba(255,77,109,.34),rgba(255,77,109,.03))}
/* la punta que marca la altura alcanzada */
/* riel de alto completo: el rombo va arriba y el riel se baja con translateY,
   asi el % es del medidor y no del rombo */
.lb-cohete{
  position:absolute;left:var(--rail);bottom:0;width:0;height:100%;
  transform:translateY(0);color:color-mix(in srgb,var(--game,#7c5cff) 45%,transparent);
  transition:transform .5s cubic-bezier(.16,.9,.3,1);
}
.lb-cohete::before{
  content:'';position:absolute;left:0;bottom:0;width:12px;height:12px;
  transform:translate(-50%,50%) rotate(45deg);border-radius:3px;
  background:var(--game,#7c5cff);
  box-shadow:0 0 16px 2px color-mix(in srgb,var(--game,#7c5cff) 65%,transparent);
}
.lb-cohete::after{  /* la linea de altura alcanzada cruzando el escenario */
  content:'';position:absolute;left:0;bottom:0;width:40vw;max-width:760px;height:1px;
  background:linear-gradient(90deg,currentColor,transparent 70%);opacity:.5;
}
.lb-cohete.buscando{transition:transform .09s linear}
.lb-cohete.directo{transition:none}
.lb-cohete.win{color:rgba(37,229,154,.5)}
.lb-cohete.win::before{background:var(--win);box-shadow:0 0 22px 3px rgba(37,229,154,.6)}
.lb-cohete.lose{color:rgba(255,77,109,.4)}
.lb-cohete.lose::before{background:var(--lose);box-shadow:0 0 16px 2px rgba(255,77,109,.45)}
/* la marca del objetivo cruza todo: se ve de una si el numero la paso o no */
.lb-objetivo{
  position:absolute;left:calc(var(--rail) - 6px);right:0;top:0;height:100%;
  border-bottom:1px dashed var(--gold);opacity:.75;
  transform:translateY(0);transition:transform .25s ease;
}
.lb-obj-txt{
  position:absolute;right:0;bottom:-9px;
  font-size:10px;font-weight:800;color:var(--gold);
  background:rgba(6,5,14,.85);padding:2px 7px;border-radius:5px;
  border:1px solid rgba(255,197,61,.35);white-space:nowrap;
  font-variant-numeric:tabular-nums;
}

/* ---- el numero vive adentro de la escala ---- */
.lb-centro{
  position:relative;flex:1;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  min-width:0;margin-left:var(--rail);
}
.limbo-num{
  position:relative;font-weight:900;line-height:.95;letter-spacing:-.03em;
  font-size:clamp(46px,9vw,86px);font-variant-numeric:tabular-nums;
  color:var(--game,#7c5cff);
  text-shadow:0 0 44px color-mix(in srgb,var(--game,#7c5cff) 45%,transparent);
}
.limbo-num.esperando{opacity:.45;animation:lbLatido 1s ease-in-out infinite}
@keyframes lbLatido{0%,100%{opacity:.32}50%{opacity:.6}}
/* Mientras trepa no se sabe si gano: neutro a proposito, para que uno mire
   la linea dorada y no el color del numero. */
.limbo-num.subiendo{color:#dfe6ff;text-shadow:0 0 40px rgba(160,180,255,.35)}
.limbo-num.win{color:var(--win);text-shadow:0 0 44px rgba(37,229,154,.5)}
.limbo-num.lose{color:var(--lose);text-shadow:0 0 38px rgba(255,77,109,.38)}
.limbo-num.pop{animation:rollPop .5s cubic-bezier(.22,1.5,.36,1)}
.limbo-sub{
  position:relative;margin-top:16px;font-size:13px;color:var(--muted);font-weight:600;
  padding:5px 12px;border-radius:999px;           /* escudo: las lineas pasan por detras */
  background:rgba(8,10,22,.78);border:1px solid var(--line-soft);
}

/* ==========================================================================
   RUEDA
   ========================================================================== */
.wh-stage{
  border-radius:var(--radius);padding:18px;
  background:radial-gradient(120% 90% at 50% 0%, #3a1250 0%, #1d0d30 52%, #0d0718 100%);
  border:1px solid rgba(199,125,255,.24);box-shadow:var(--shadow)
}
.wh-wrap{position:relative;width:min(340px,80vw);margin:0 auto;aspect-ratio:1/1;
  filter:drop-shadow(0 16px 30px rgba(0,0,0,.6))}
#whCanvas{position:absolute;inset:0;width:100%;height:100%}
.wh-pointer{
  position:absolute;left:50%;top:-4px;transform:translateX(-50%);z-index:2;
  width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;
  border-top:20px solid var(--gold);filter:drop-shadow(0 2px 6px rgba(0,0,0,.6))
}
/* El resultado en el eje de la rueda.
   ---------------------------------------------------------------------------
   Ganar y perder se distinguian SOLO por el color del texto, y los dos colores
   eran casi negros sobre el oro del hub: #03291b contra #3a1119 dan 1,05:1 de
   contraste ENTRE si (1,0 seria el mismo color exacto; hacen falta unos 3:1
   para distinguir dos textos de un vistazo). O sea que el unico aviso de si la
   ronda pago o no era invisible, y habia que ir a mirar el saldo o el toast.
   Ahora el numero vive en una pastilla que cambia de fondo, que es como el
   resto de la aplicacion marca ganado y perdido (.chip.win / .chip.lose).
   Medido: el texto queda en 6,0:1 sobre la pastilla verde y 5,6:1 sobre la
   roja, las dos por encima del 4,5:1 que pide WCAG AA.
   Entre las dos pastillas el contraste de luminancia es 2,19:1 —mejor que el
   1,05:1 de antes, pero por debajo de 3:1—, y eso no alcanza por si solo: lo
   que separa los dos estados es el TONO (verde contra rojo) mas dos senales
   que no dependen del color, el texto que se invierte de oscuro a blanco y el
   numero mismo, que es 0.00x cuando no paga. Con eso la ronda se lee sin
   depender de distinguir verde de rojo. */
.wh-center{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
  font-size:clamp(15px,4.2vw,20px);font-weight:900;font-variant-numeric:tabular-nums;
  color:#2a1a04;pointer-events:none;text-shadow:0 1px 0 rgba(255,255,255,.35);
  padding:5px 12px;border-radius:999px;line-height:1.05;
  transition:background .2s,color .2s,box-shadow .2s
}
.wh-center.win{
  color:#032a1c;background:linear-gradient(180deg,#5cffc0,#12b87c);
  box-shadow:0 3px 12px rgba(0,0,0,.45),0 0 20px rgba(37,229,154,.45);
  text-shadow:0 1px 0 rgba(255,255,255,.4)
}
.wh-center.lose{
  color:#fff;background:linear-gradient(180deg,#ff7f95,#c81e4a);
  box-shadow:0 3px 12px rgba(0,0,0,.45);
  text-shadow:0 1px 2px rgba(0,0,0,.45)
}
.wh-legend{display:grid;gap:6px}
.wh-leg{display:flex;align-items:center;gap:9px;font-size:13px;font-variant-numeric:tabular-nums}
.wh-leg b{color:var(--text);min-width:62px}
.wh-dot{width:13px;height:13px;border-radius:4px;flex:0 0 auto}

/* ==========================================================================
   KENO
   ========================================================================== */
.keno-stage{
  border-radius:var(--radius);padding:16px;
  background:radial-gradient(120% 90% at 50% 0%, #10513f 0%, #0a2b2a 52%, #07161a 100%);
  border:1px solid rgba(47,211,138,.26);box-shadow:var(--shadow)
}
.keno-status{
  text-align:center;font-size:15px;font-weight:800;margin-bottom:14px;min-height:22px;
  color:#d9f5e8;letter-spacing:.01em
}
/* Igual que en mines: sin tope las 40 casillas se estiraban a 106 px cada una
   y el tablero medía media pantalla para mostrar numeros de dos digitos. */
.keno-grid{
  display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:7px;
  width:100%;max-width:620px;margin-inline:auto
}
.keno-cell{
  position:relative;aspect-ratio:1/1;border-radius:50%;display:grid;place-items:center;
  cursor:pointer;overflow:hidden;
  background:radial-gradient(circle at 34% 28%,rgba(255,255,255,.16),rgba(255,255,255,.05) 46%,rgba(255,255,255,.02));
  border:1px solid rgba(255,255,255,.13);color:#cfe6e0;
  font-weight:800;font-size:clamp(11px,3.2vw,16px);font-variant-numeric:tabular-nums;
  box-shadow:inset 0 -6px 12px rgba(0,0,0,.3),0 2px 6px rgba(0,0,0,.35);
  transition:transform .14s cubic-bezier(.22,1.2,.36,1),box-shadow .15s;
  -webkit-tap-highlight-color:transparent;user-select:none
}
.keno-cell:not(.picked):not(.drawn):hover{
  transform:translateY(-2px);
  box-shadow:inset 0 -6px 12px rgba(0,0,0,.3),0 8px 16px rgba(0,0,0,.45),
             0 0 0 1px rgba(77,214,255,.45)
}
.keno-cell:active{transform:scale(.9)}
.keno-cell.picked{
  background:radial-gradient(circle at 34% 26%,#a8ecff,#4dd6ff 40%,#1c7fd6);
  color:#04202e;border-color:rgba(255,255,255,.5);
  box-shadow:inset 0 -5px 10px rgba(0,0,0,.22),0 3px 12px rgba(34,211,238,.45)
}
.keno-cell.drawn{animation:kenoDrop .3s cubic-bezier(.3,1.6,.4,1)}
.keno-cell.drawn:not(.hit){
  background:linear-gradient(180deg,rgba(255,255,255,.2),rgba(255,255,255,.08));color:#fff
}
.keno-cell.hit{
  background:radial-gradient(circle at 35% 30%,#fff3c4,#e07f10);color:#2a1a04;
  border-color:#fff;box-shadow:0 0 18px rgba(255,197,61,.6);z-index:1
}
.keno-cell.miss{opacity:.42}
@keyframes kenoDrop{0%{transform:scale(.4) rotate(-12deg);opacity:0}100%{transform:none;opacity:1}}
/* marcador durante el sorteo */
.keno-status{display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap}
.kn-marcador{
  font-size:17px;font-weight:900;font-variant-numeric:tabular-nums;color:#fff;
  padding:2px 10px;border-radius:999px;background:rgba(255,255,255,.07)
}
.kn-marcador.pega{
  background:rgba(255,197,61,.18);color:var(--gold);
  animation:knPega .34s cubic-bezier(.22,1.5,.36,1)
}
@keyframes knPega{0%{transform:scale(1)}40%{transform:scale(1.22)}100%{transform:scale(1)}}
.kn-bolillas{font-size:12px;color:var(--muted-2);font-variant-numeric:tabular-nums}
.kn-va{font-size:13px;font-weight:800;color:var(--gold)}
.kn-va.dim{color:var(--muted-2);font-weight:600}

.keno-pay{display:grid;gap:4px;max-height:210px;overflow-y:auto}
.keno-pay-row{
  display:flex;justify-content:space-between;font-size:12.5px;padding:5px 9px;border-radius:7px;
  background:rgba(255,255,255,.045);font-variant-numeric:tabular-nums;color:var(--muted)
}
.keno-pay-row b{color:var(--gold)}

/* ==========================================================================
   FONDO POR JUEGO
   Cada vista de juego usa su propia portada (/assets/img/games/<juego>.svg)
   como ambiente. Va muy atenuada y desvanecida hacia abajo: tiene que dar
   identidad, no competir con el tablero ni con los numeros.
   ========================================================================== */
.view.has-art::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--game-art);
  background-size:cover;background-position:50% 0;background-repeat:no-repeat;
  opacity:.26;filter:blur(2px) saturate(1.2);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 38%,transparent 72%);
          mask-image:linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 38%,transparent 72%);
  animation:artIn .5s ease
}
@keyframes artIn{from{opacity:0;transform:scale(1.04)}to{opacity:.26;transform:none}}
/* Antes esto corria el arte 260px a la derecha para no meterse debajo del
   sidebar fijo. Ese sidebar ya no existe —ahora es un cajon que se abre— asi
   que el arte va de borde a borde. */

/* --- encabezado del juego: la portada con el nombre encima ---------------- */
.game-head{
  position:relative;overflow:hidden;border-radius:var(--radius);
  margin-bottom:12px;min-height:66px;display:flex;align-items:flex-end;
  border:1px solid var(--line-soft);box-shadow:var(--shadow-sm)
}
/* 901 y no 980: es el corte unico de escritorio (ver .game-layout). */
@media(min-width:901px){.game-head{min-height:96px}}
/* Se encuadra hacia la derecha: las portadas tienen el motivo decorativo de
   ese lado y el texto grande a la izquierda, justo donde va el titulo. */
.game-head img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:78% 45%;opacity:.62
}
.game-head::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(8,8,15,.97) 0%,rgba(8,8,15,.86) 30%,rgba(8,8,15,.32) 72%,rgba(8,8,15,.12) 100%)
}
.game-head .gh{position:relative;z-index:1;padding:12px 16px;display:flex;align-items:center;gap:10px;width:100%}
.game-head h1{
  font-family:var(--display);font-size:clamp(19px,5.4vw,30px);font-weight:900;letter-spacing:.05em;
  background:linear-gradient(180deg,#fff,#cbb8ff);-webkit-background-clip:text;background-clip:text;color:transparent
}
/* ==========================================================================
   MINES
   ========================================================================== */
/* OJO: aca habia un selector cortado por la mitad —un `.game-head ` suelto, sin
   bloque— justo antes de este comentario. El parser de CSS no se detiene ahi:
   sigue leyendo hasta la primera llave y arma un solo selector con las dos
   partes, `.game-head .mines-stage`, que no existe en ningun DOM. Resultado:
   mines era el UNICO de los cinco juegos de grilla sin panel; sus casillas
   flotaban sobre el fondo de la pagina y el arte del juego se veia por detras,
   mientras keno, la torre, tormenta y la ruleta si tenian su mesa. No habia
   ningun error en consola y la regla estaba escrita correctamente: el defecto
   estaba una linea mas arriba. Verificado con getComputedStyle: background
   'none', border '0px none', padding '0px' donde el archivo pedia un degrade,
   un borde turquesa y 16px. */
.mines-stage{
  border-radius:var(--radius);padding:16px;
  background:radial-gradient(120% 90% at 50% 0%, #0f4a52 0%, #0a2634 52%, #070d1a 100%);
  border:1px solid rgba(37,229,200,.26);box-shadow:var(--shadow)
}
.mines-status{
  text-align:center;font-size:15px;font-weight:800;margin-bottom:14px;min-height:22px;color:#d3f7f0
}
/* Las casillas son cuadradas, asi que sin tope el tablero crece con el ancho:
   en escritorio daban 172 px cada una y el tablero medía 900 px de alto. Con
   tope de 500 px quedan de 92 px, que es tamano de ficha y entra en pantalla. */
.mines-grid{
  display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:9px;
  width:100%;max-width:500px;margin-inline:auto
}
.mines-cell{
  position:relative;aspect-ratio:1/1;border-radius:13px;cursor:pointer;
  display:grid;place-items:center;overflow:hidden;
  background:linear-gradient(158deg,#24485a 0%,#1a3546 46%,#102534 100%);
  border:1px solid rgba(255,255,255,.09);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.13),inset 0 -10px 18px rgba(0,0,0,.35),
             0 4px 10px rgba(0,0,0,.45);
  transition:transform .14s cubic-bezier(.22,1.2,.36,1),box-shadow .16s;
  -webkit-tap-highlight-color:transparent
}
/* brillo diagonal fijo: da volumen sin animar nada */
.mines-cell::before{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(146deg,rgba(255,255,255,.16) 0%,transparent 42%);
}
.mines-cell:not(.gem):not(.bomb):hover{
  transform:translateY(-3px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 10px 20px rgba(0,0,0,.5),
             0 0 0 1px rgba(37,229,200,.4),0 0 20px rgba(37,229,200,.22)
}
.mines-cell:active{transform:scale(.93)}
.mines-cell svg{width:74%;height:74%;display:block}
.mines-cell.gem::before,.mines-cell.bomb::before{opacity:.35}
.mines-cell.gem{
  background:linear-gradient(180deg,#123f4a,#0b2b36);
  box-shadow:inset 0 0 0 2px rgba(37,229,200,.55),0 0 18px rgba(37,229,200,.28);
  animation:kenoDrop .28s cubic-bezier(.3,1.6,.4,1)
}
.mines-cell.bomb{
  background:linear-gradient(180deg,#3a1420,#1c0a11);
  box-shadow:inset 0 0 0 1px rgba(255,77,109,.35)
}
.mines-cell.bomb.hit{
  box-shadow:inset 0 0 0 2px var(--lose),0 0 26px rgba(255,77,109,.6);
  animation:shake .45s
}
.mines-cell.faded{opacity:.26}

/* ==========================================================================
   HI-LO
   ========================================================================== */
.hl-stage{
  border-radius:var(--radius);padding:22px 16px 16px;text-align:center;
  background:radial-gradient(120% 90% at 50% 0%, #3d2260 0%, #1e1338 52%, #0d0818 100%);
  border:1px solid rgba(168,85,247,.28);box-shadow:var(--shadow)
}
.hl-card{
  width:min(150px,44vw);aspect-ratio:5/7;margin:0 auto;border-radius:14px;
  background:linear-gradient(180deg,#fff,#d8dced);
  display:grid;place-items:center;gap:2px;position:relative;
  box-shadow:0 12px 30px rgba(0,0,0,.55),inset 0 -3px 0 rgba(0,0,0,.1)
}
.hl-card.in{animation:rollPop .35s cubic-bezier(.22,1.5,.36,1)}
/* --- la carta antes de la primera jugada ---------------------------------
   El escenario de hi-lo es UNA carta y nada mas. Hasta la primera apuesta esa
   carta se pintaba con el degrade de la cara —blanco— y sin nada encima: un
   rectangulo blanco vacio en medio del pano, que se lee como una imagen que no
   cargo, no como una carta esperando. En escritorio, ademas, mide 190x266 px,
   asi que es lo mas grande de la pantalla.
   Se le pone dorso, que es lo que de verdad hay sobre la mesa antes de dar:
   el mismo tramado en diagonal que ya usan .bj-card.back y .tp-card.back, en
   el violeta del juego, con el filete claro que llevan los dorsos reales y un
   rombo al medio. Va sin media query: el rectangulo blanco estaba igual de mal
   en el telefono.
   Se detecta con :empty porque el JS deja el nodo vacio hasta la primera carta
   (hilo.js:27) y lo llena con el rango y el palo despues; no hace falta tocar
   la vista. */
.hl-card:empty{
  background:
    repeating-linear-gradient(45deg,#31205e 0 8px,#412a7d 8px 16px);
  box-shadow:
    inset 0 0 0 3px rgba(255,255,255,.14),
    inset 0 0 0 5px rgba(0,0,0,.28),
    0 12px 30px rgba(0,0,0,.55);
}
.hl-card:empty::before{
  content:"";width:38%;aspect-ratio:1;border-radius:6px;
  border:2px solid rgba(255,255,255,.22);
  background:linear-gradient(140deg,rgba(255,255,255,.14),rgba(255,255,255,.03));
  transform:rotate(45deg);
}
.hl-rank{font-size:clamp(38px,11vw,54px);font-weight:900;color:#15100f;line-height:1}
.hl-suit{font-size:clamp(22px,6vw,30px);color:#15100f;line-height:1}
.hl-rank.red,.hl-suit.red{color:#c4123c}
.hl-status{margin-top:14px;font-size:13.5px;font-weight:700;color:#d9c9ff;min-height:20px}
.hl-guess{justify-content:flex-start;gap:10px;font-size:14px}
.hl-guess b{font-variant-numeric:tabular-nums;color:var(--game)}
.hl-guess.weak b{color:var(--muted-2)}

/* ==========================================================================
   BACARÁ
   ========================================================================== */
.bc-stage{
  border-radius:var(--radius);padding:16px;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.012) 0 2px, transparent 2px 4px),
    radial-gradient(120% 90% at 50% 0%, #12563c 0%, #0b3025 52%, #06160f 100%);
  border:1px solid rgba(47,211,138,.3);box-shadow:var(--shadow)
}
.bc-side{
  border-radius:12px;padding:12px;margin-bottom:10px;
  background:rgba(0,0,0,.24);border:1px solid rgba(255,255,255,.08)
}
.bc-side.banker{border-color:rgba(255,197,61,.28)}
.bc-name{
  display:flex;align-items:center;justify-content:space-between;
  font-size:11px;letter-spacing:.2em;font-weight:900;color:rgba(255,255,255,.5);margin-bottom:10px
}
.bc-side.banker .bc-name{color:rgba(255,197,61,.75)}
.bc-total{font-size:26px;font-weight:900;color:#fff;font-variant-numeric:tabular-nums;letter-spacing:0}
.bc-hand{display:flex;gap:8px;min-height:78px}
.bc-card{
  width:54px;height:76px;border-radius:8px;flex:0 0 auto;
  background:linear-gradient(180deg,#fff,#dde3f0);color:#15100f;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  box-shadow:0 4px 12px rgba(0,0,0,.5);animation:rollPop .3s cubic-bezier(.22,1.5,.36,1)
}
.bc-card.red{color:#c4123c}
.bc-card .r{font-size:20px;font-weight:900;line-height:1}
.bc-card .s{font-size:17px;line-height:1.1}
.bc-status{
  text-align:center;font-size:15px;font-weight:800;margin-top:12px;min-height:22px;color:#d6f5e6
}

/* ==========================================================================
   SIC BO
   ========================================================================== */
.sb-stage{display:flex;flex-direction:column;gap:12px}
/* El cubilete.
   ---------------------------------------------------------------------------
   Antes esto era una caja violeta y los tres dados flotaban en el medio, sin
   nada debajo: en escritorio son 900x170 px de fondo liso con tres dados de 62
   y un guion al costado. Sic bo se juega con un cubilete sobre un pano, y sin
   ninguna de las dos cosas el escenario no se lee como una mesa.
   Se le pone la BANDEJA: un ovalo de fieltro con su reborde, del ancho justo
   para los tres dados y el total. Es un pseudo-elemento, asi que no toca el
   DOM ni la posicion de nada. */
.sb-shaker{display:flex;align-items:center;justify-content:center;gap:18px;
  padding:20px 16px;border-radius:var(--r-lg);position:relative;isolation:isolate;
  background:radial-gradient(circle at 50% 40%,rgba(176,108,255,.20),transparent 70%),
             linear-gradient(160deg,#231242,#120c22);
  border:1px solid rgba(255,255,255,.07)}
.sb-shaker::before{
  content:'';position:absolute;z-index:-1;left:50%;top:50%;translate:-50% -50%;
  width:min(420px,84%);aspect-ratio:2.4/1;border-radius:50%;
  background:
    radial-gradient(60% 70% at 50% 22%,rgba(255,255,255,.07),transparent 70%),
    radial-gradient(circle at 50% 55%,#3a1f5e 0%,#261440 55%,#170c28 100%);
  box-shadow:
    inset 0 10px 26px rgba(0,0,0,.55),
    inset 0 -2px 0 rgba(255,255,255,.06),
    0 0 0 2px rgba(255,197,61,.16),
    0 18px 40px rgba(0,0,0,.5);
}
.sb-dice{display:flex;gap:12px}
.sb-die{width:46px;height:46px;border-radius:12px;display:grid;
  grid-template:repeat(3,1fr)/repeat(3,1fr);gap:2px;padding:7px;
  background:linear-gradient(150deg,#fffdf8,#d9cfe4);
  box-shadow:0 6px 14px rgba(0,0,0,.45),inset 0 -3px 6px rgba(0,0,0,.18)}
.sb-die i{border-radius:50%;background:#2a1440;align-self:center;justify-self:center;
  width:9px;height:9px}
/* El total de los tres dados. Era un numero suelto al costado —y en reposo,
   un guion amarillo de 30px que no se leia como nada—. Ahora es una pastilla
   con su etiqueta: se entiende que es el TOTAL, que es lo que decide casi
   todas las apuestas de la mesa. */
.sb-sum{
  min-width:60px;text-align:center;font-size:30px;font-weight:800;
  color:var(--gold);text-shadow:0 0 18px rgba(255,197,61,.45);
  position:relative;padding:10px 18px 8px;border-radius:14px;line-height:1;
  background:linear-gradient(180deg,rgba(255,197,61,.14),rgba(255,197,61,.04));
  border:1px solid rgba(255,197,61,.3);
  font-variant-numeric:tabular-nums;
}
.sb-sum::before{
  content:'TOTAL';position:absolute;left:0;right:0;top:-9px;
  font-size:9px;letter-spacing:.16em;font-weight:900;color:rgba(255,197,61,.75);
  text-shadow:none;
}
.sb-history{display:flex;gap:5px;flex-wrap:wrap;min-height:22px}
.sb-h{min-width:24px;text-align:center;padding:2px 5px;border-radius:6px;
  font-size:12px;font-weight:700;background:rgba(255,255,255,.06);color:var(--txt-2)}
.sb-h.small{background:rgba(63,169,245,.18);color:#8fd0ff}
.sb-h.big{background:rgba(255,90,60,.18);color:#ffab8f}
.sb-h.t{background:rgba(255,197,61,.22);color:var(--gold)}

.sb-table{display:flex;flex-direction:column;gap:10px;max-height:none}

/* --- pestanas de la mesa --- */
.sb-solapas{display:flex;gap:6px;flex-wrap:wrap}
.sb-solapa{
  position:relative;display:inline-flex;align-items:center;gap:6px;
  /* min-height 44: las solapas eligen el tipo de apuesta y quedaban en 40 px */
  padding:7px 14px;min-height:44px;border-radius:999px;cursor:pointer;
  background:var(--surface-2);border:1px solid var(--line-soft);
  color:var(--muted);font-size:12px;font-weight:700;letter-spacing:.01em;
  transition:color .15s,border-color .15s,background .15s;
}
.sb-solapa:hover{color:var(--text);border-color:rgba(176,108,255,.45)}
.sb-solapa.on{
  color:#0a0713;border-color:transparent;
  background:linear-gradient(135deg,#c77dff,#7c5cff);
}
/* el puntito avisa que esa pestana tiene fichas puestas */
.sb-solapa i{width:6px;height:6px;border-radius:50%;background:var(--gold);opacity:0;transition:opacity .15s}
.sb-solapa.con i{opacity:1}
.sb-solapa.on.con i{background:#2a1140}
.sb-cuerpo{min-height:104px}
.sb-sec-t{font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--txt-3);margin-bottom:5px}
.sb-grid{display:grid;gap:5px}
.sb-sec.simple .sb-grid{grid-template-columns:repeat(4,1fr)}
.sb-sec.totals .sb-grid{grid-template-columns:repeat(7,1fr)}
.sb-sec.six .sb-grid{grid-template-columns:repeat(6,1fr)}
.sb-sec.combos .sb-grid{grid-template-columns:repeat(8,1fr)}
.sb-sec.triples .sb-grid{grid-template-columns:repeat(6,1fr)}
.sb-sec.triples .sb-cell.wide{grid-column:span 6}

.sb-cell{position:relative;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:1px;min-height:46px;padding:5px 3px;
  border-radius:9px;border:1px solid rgba(255,255,255,.09);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.015));
  color:var(--txt-1);cursor:pointer;transition:transform .12s,border-color .15s,background .15s}
.sb-cell:hover{border-color:rgba(176,108,255,.55);transform:translateY(-1px)}
.sb-cell .l{font-size:13px;font-weight:700;line-height:1}
.sb-cell .x{font-size:10px;color:var(--txt-3);line-height:1}
.sb-cell.has{border-color:var(--gold);background:rgba(255,197,61,.10)}
.sb-cell.won{border-color:#3ee08a;background:rgba(62,224,138,.18);
  animation:sbWon .5s ease}
@keyframes sbWon{0%{transform:scale(1)}45%{transform:scale(1.09)}100%{transform:scale(1)}}
.sb-cell .chip-on{position:absolute;top:-6px;right:-4px;font-size:10px;font-weight:800;
  padding:1px 5px;border-radius:8px;background:var(--gold);color:#3a2400;
  box-shadow:0 2px 6px rgba(0,0,0,.45)}
.sb-cell .chip-on:empty{display:none}
.sb-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}
.sb-hint{font-size:11px;color:var(--txt-3);text-align:center;margin:0}

/* ==========================================================================
   TORRE DEL DRAGON
   ========================================================================== */
.dt-stage{display:flex;flex-direction:column;gap:10px}
.dt-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}
.dt-tower{display:flex;flex-direction:column;gap:5px;padding:14px;
  border-radius:var(--r-lg);
  background:radial-gradient(circle at 50% 0%,rgba(255,90,43,.16),transparent 65%),
             linear-gradient(180deg,#2a1020,#0d0812);
  border:1px solid rgba(255,255,255,.07)}
.dt-row{display:flex;align-items:center;gap:5px;border-radius:10px;padding:3px;
  transition:background .18s}
.dt-row.active{background:rgba(255,180,61,.10);
  box-shadow:inset 0 0 0 1px rgba(255,180,61,.30)}
.dt-x{width:72px;flex:none;font-size:11px;font-weight:700;color:var(--txt-3);
  text-align:right;padding-right:4px}
.dt-row.active .dt-x{color:var(--gold)}
.dt-cell{flex:1;min-height:38px;border-radius:9px;cursor:default;
  border:1px solid rgba(255,255,255,.08);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.015));
  display:flex;align-items:center;justify-content:center;padding:3px;
  transition:transform .12s,border-color .15s,background .15s}
.dt-cell svg{width:24px;height:24px}
.dt-row.active .dt-cell{cursor:pointer}
.dt-row.active .dt-cell:hover{border-color:#ffb43d;transform:translateY(-1px);
  background:rgba(255,180,61,.14)}
.dt-cell.locked{opacity:.35}
.dt-cell.egg{border-color:#39d98a;background:rgba(57,217,138,.16)}
.dt-cell.dragon{border-color:#e0453a;background:rgba(224,69,58,.18)}
.dt-cell.dragon.hit{animation:dtHit .45s ease}
@keyframes dtHit{0%{transform:scale(1)}40%{transform:scale(1.14)}100%{transform:scale(1)}}
.dt-cell.faded{opacity:.32}
.dt-modes{display:grid;grid-template-columns:repeat(2,1fr);gap:6px}
.dt-mode{display:flex;flex-direction:column;gap:1px;padding:8px 6px;border-radius:10px;
  border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.04);
  color:var(--txt-1);cursor:pointer;transition:border-color .15s,background .15s}
.dt-mode:hover{border-color:rgba(255,180,61,.5)}
.dt-mode.on{border-color:var(--gold);background:rgba(255,197,61,.12)}
.dt-mode .n{font-size:13px;font-weight:700;line-height:1.1}
.dt-mode .p{font-size:10px;color:var(--txt-3)}

/* ==========================================================================
   BLACKJACK
   ========================================================================== */
.bj-stage{display:flex;flex-direction:column;gap:10px;padding:18px 16px;
  border-radius:var(--r-lg);
  background:radial-gradient(ellipse at 50% 45%,rgba(40,224,160,.14),transparent 68%),
             linear-gradient(165deg,#0c4a37,#07211d 55%,#050f14);
  border:1px solid rgba(255,255,255,.07)}
.bj-side{display:flex;flex-direction:column;gap:7px;align-items:center}
.bj-name{font-size:11px;letter-spacing:.10em;color:var(--txt-3);
  display:flex;align-items:center;gap:8px}
.bj-total{font-size:15px;font-weight:800;color:var(--txt-1);
  padding:1px 9px;border-radius:8px;background:rgba(0,0,0,.35)}
.bj-hand{display:flex;gap:7px;min-height:82px;align-items:center;flex-wrap:wrap;
  justify-content:center}
.bj-felt{text-align:center;font-size:10px;letter-spacing:.09em;color:rgba(255,216,115,.55);
  padding:5px 0;border-top:1px solid rgba(255,216,115,.16);
  border-bottom:1px solid rgba(255,216,115,.16)}
.bj-card{width:56px;height:80px;border-radius:8px;background:linear-gradient(180deg,#fff,#e3eaee);
  border:1px solid #b9c4cb;color:#182028;position:relative;flex:none;
  box-shadow:0 5px 12px rgba(0,0,0,.42);animation:bjIn .26s ease}
.bj-card .r{position:absolute;top:5px;left:6px;font-size:16px;font-weight:800;line-height:1}
.bj-card .s{position:absolute;bottom:4px;right:6px;font-size:20px;line-height:1}
.bj-card.red{color:#c8323f}
.bj-card.back{background:repeating-linear-gradient(45deg,#1d2b52,#1d2b52 5px,#2b3d6d 5px,#2b3d6d 10px);
  border-color:#0e1730}
@keyframes bjIn{from{opacity:0;transform:translateY(-14px) rotate(-6deg)}
  to{opacity:1;transform:none}}
.bj-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}

/* --- movil ------------------------------------------------------------- */
@media (pointer: coarse), (max-width: 900px){
  .sb-die{width:44px;height:44px}
  .sb-die i{width:8px;height:8px}
  .sb-sum{font-size:28px}
  .sb-cell{min-height:48px}
  .sb-cell .l{font-size:14px}
  .sb-cell .x{font-size:11px}
  .sb-sec.totals .sb-grid{grid-template-columns:repeat(5,1fr)}
  .sb-sec.combos .sb-grid{grid-template-columns:repeat(5,1fr)}
  .dt-x{width:60px;font-size:12px}
  .dt-cell{min-height:46px}
  .dt-mode .n{font-size:14px}
  .dt-mode .p{font-size:11px}
  /* El paño se lee a 10px en escritorio, pero en telefono cualquier texto
     por debajo de 11px es ilegible: la auditoria movil lo marca. */
  .bj-felt{font-size:11px;letter-spacing:.06em}
  .bj-card{width:50px;height:72px}
  .bj-card .r{font-size:15px}
  .bj-card .s{font-size:18px}
  .bj-hand{min-height:74px}
}

/* ==========================================================================
   ANDAR BAHAR
   ========================================================================== */
.ab-stage{display:flex;flex-direction:column;gap:10px;padding:16px 14px;
  border-radius:var(--r-lg);
  background:radial-gradient(ellipse at 50% 45%,rgba(255,176,46,.16),transparent 68%),
             linear-gradient(160deg,#3a1d08,#1d1226 55%,#08060f);
  border:1px solid rgba(255,255,255,.07)}
.ab-line{display:flex;align-items:center;gap:10px;min-height:64px}
.ab-name{flex:none;width:60px;font-size:10px;letter-spacing:.12em;color:#ffd27a;opacity:.85}
.ab-name.bahar{color:#9fd8ff}
.ab-row{display:flex;gap:4px;flex-wrap:wrap;flex:1;min-height:56px;align-items:center}
.ab-joker{display:flex;align-items:center;justify-content:center;gap:10px;
  padding:6px 0;border-top:1px solid rgba(255,216,115,.18);
  border-bottom:1px solid rgba(255,216,115,.18)}
.ab-jlabel{font-size:10px;letter-spacing:.16em;color:#ffd27a}
.ab-card{width:38px;height:54px;border-radius:6px;flex:none;position:relative;
  background:linear-gradient(180deg,#fffdf6,#e0dccf);border:1px solid #b8b0a0;
  color:#1d2430;box-shadow:0 3px 8px rgba(0,0,0,.4);animation:abIn .2s ease}
.ab-card .r{position:absolute;top:3px;left:4px;font-size:13px;font-weight:800;line-height:1}
.ab-card .s{position:absolute;bottom:2px;right:4px;font-size:15px;line-height:1}
.ab-card.red{color:#c8323f}
.ab-card.match{border-color:#3ee08a;box-shadow:0 0 0 2px rgba(62,224,138,.55),0 3px 10px rgba(0,0,0,.5)}
.ab-joker .ab-card{width:44px;height:62px;border-color:#f2ac2b;
  box-shadow:0 0 0 2px rgba(242,172,43,.4),0 4px 12px rgba(0,0,0,.5)}
@keyframes abIn{from{opacity:0;transform:translateY(-8px) scale(.9)}to{opacity:1;transform:none}}
.ab-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}
.ab-sides{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.ab-side{display:flex;flex-direction:column;gap:1px;padding:9px 6px;border-radius:10px;
  border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.04);
  color:var(--txt-1);cursor:pointer;transition:border-color .15s,background .15s}
.ab-side:hover{border-color:rgba(255,210,122,.5)}
.ab-side.on{border-color:var(--gold);background:rgba(255,197,61,.12)}
.ab-side .n{font-size:13px;font-weight:800;line-height:1.1}
.ab-side .x{font-size:12px;color:var(--gold)}
.ab-side .p{font-size:10px;color:var(--txt-3)}

/* ==========================================================================
   VIDEO POKER
   ========================================================================== */
.vp-stage{display:flex;flex-direction:column;gap:12px}
.vp-pays{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;padding:10px;
  border-radius:var(--r-lg);background:linear-gradient(160deg,#101c3d,#080d1c);
  border:1px solid rgba(125,227,255,.18)}
.vp-pay{display:flex;justify-content:space-between;align-items:center;gap:6px;
  padding:4px 7px;border-radius:6px;font-size:11px;
  border:1px solid transparent;transition:background .2s,border-color .2s}
.vp-pay .l{color:var(--txt-2)}
.vp-pay .x{font-weight:800;color:#7de3ff}
.vp-pay.on{background:rgba(125,227,255,.16);border-color:#7de3ff;
  animation:vpHit .5s ease}
.vp-pay.on .l{color:#fff}
@keyframes vpHit{0%{transform:scale(1)}45%{transform:scale(1.05)}100%{transform:scale(1)}}
.vp-hand{display:flex;gap:8px;justify-content:center;padding:16px 10px;
  border-radius:var(--r-lg);
  background:radial-gradient(ellipse at 50% 40%,rgba(63,169,245,.16),transparent 70%),
             linear-gradient(165deg,#0f1c3f,#060a16);
  border:1px solid rgba(255,255,255,.07)}
.vp-slot{display:flex;flex-direction:column;align-items:center;gap:6px}
.vp-card{width:60px;height:86px;border-radius:8px;position:relative;cursor:pointer;
  background:linear-gradient(180deg,#fff,#dee5ec);border:1px solid #aab6c4;color:#182028;
  box-shadow:0 5px 12px rgba(0,0,0,.45)}
.vp-card .r{position:absolute;top:5px;left:6px;font-size:17px;font-weight:800;line-height:1}
.vp-card .s{position:absolute;bottom:4px;right:6px;font-size:21px;line-height:1}
.vp-card.red{color:#c8323f}
.vp-card.back{background:repeating-linear-gradient(45deg,#122046,#122046 5px,#1d3068 5px,#1d3068 10px);
  border-color:#0a1024;cursor:default}
.vp-card.in{animation:vpIn .28s ease}
@keyframes vpIn{from{opacity:0;transform:translateY(-16px) rotateY(40deg)}to{opacity:1;transform:none}}
.vp-hold{font-size:9px;letter-spacing:.09em;padding:3px 7px;border-radius:6px;
  border:1px solid rgba(125,227,255,.35);background:rgba(10,16,36,.7);
  color:#7de3ff;cursor:pointer;transition:background .15s,color .15s}
.vp-slot.held .vp-card{box-shadow:0 0 0 2px #ffc53d,0 5px 14px rgba(0,0,0,.5);
  transform:translateY(-5px)}
.vp-slot.held .vp-hold{background:var(--gold);color:#3a2400;border-color:var(--gold);font-weight:800}
.vp-slot.locked .vp-card,.vp-slot.locked .vp-hold{cursor:default;pointer-events:none}
.vp-slot.locked .vp-hold{opacity:.35}
.vp-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}

/* ==========================================================================
   CRAPS
   ========================================================================== */
.cr-stage{display:flex;flex-direction:column;gap:10px}
.cr-felt{display:flex;align-items:center;justify-content:center;gap:20px;
  padding:24px 16px;border-radius:var(--r-lg);
  background:radial-gradient(ellipse at 50% 45%,rgba(62,224,138,.16),transparent 68%),
             linear-gradient(160deg,#0d3f2c,#0a2320 55%,#050d12);
  border:1px solid rgba(255,255,255,.07);position:relative}
.cr-point{position:absolute;top:12px;left:14px;display:flex;flex-direction:column;
  align-items:center;gap:1px;padding:5px 10px;border-radius:10px;
  border:2px solid #ffd873;background:rgba(255,216,115,.12)}
.cr-point .k{font-size:8px;letter-spacing:.12em;color:#ffd873}
.cr-point .v{font-size:17px;font-weight:800;color:#fff;line-height:1}
.cr-point.off{border-color:rgba(255,255,255,.18);background:rgba(255,255,255,.04)}
.cr-point.off .k,.cr-point.off .v{color:var(--txt-3)}
.cr-dice{display:flex;gap:14px}
.cr-die{width:54px;height:54px;border-radius:11px;display:grid;
  grid-template:repeat(3,1fr)/repeat(3,1fr);gap:2px;padding:8px;
  background:linear-gradient(150deg,#fffefa,#d8d2c6);
  box-shadow:0 6px 14px rgba(0,0,0,.5),inset 0 -3px 6px rgba(0,0,0,.16)}
.cr-die i{border-radius:50%;background:#1b2a1f;align-self:center;justify-self:center;
  width:9px;height:9px}
.cr-sum{min-width:56px;text-align:center;font-size:36px;font-weight:800;
  color:#ffd873;text-shadow:0 0 18px rgba(255,216,115,.45)}
.cr-history{display:flex;gap:5px;flex-wrap:wrap;min-height:22px}
.cr-h{min-width:24px;text-align:center;padding:2px 5px;border-radius:6px;
  font-size:12px;font-weight:700;background:rgba(255,255,255,.06);color:var(--txt-2)}
.cr-h.win{background:rgba(62,224,138,.2);color:#8affc4}
.cr-h.lose{background:rgba(224,69,58,.2);color:#ffa79f}
.cr-h.point{background:rgba(255,216,115,.2);color:#ffd873}
.cr-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}
.cr-sides{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.cr-side{display:flex;flex-direction:column;gap:1px;padding:9px 6px;border-radius:10px;
  border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.04);
  color:var(--txt-1);cursor:pointer;transition:border-color .15s,background .15s}
.cr-side:hover:not(:disabled){border-color:rgba(62,224,138,.5)}
.cr-side.on{border-color:#3ee08a;background:rgba(62,224,138,.12)}
.cr-side:disabled{opacity:.45;cursor:default}
.cr-side .n{font-size:12px;font-weight:800;line-height:1.1}
.cr-side .p{font-size:10px;color:var(--txt-3)}

/* --- movil ------------------------------------------------------------- */
@media (pointer: coarse), (max-width: 900px){
  /* En telefono nada baja de 11px ni de 44px de area tactil: lo marca la
     auditoria movil, y estos tres se colaron. */
  .ab-jlabel{font-size:11px;letter-spacing:.10em}
  .ab-card{width:34px;height:48px}
  .ab-card .r{font-size:12px}
  .ab-card .s{font-size:13px}
  .ab-name{width:52px;font-size:11px}
  .ab-side .n{font-size:14px}
  .ab-side .p{font-size:11px}
  .vp-pays{grid-template-columns:repeat(2,1fr)}
  .vp-pay{font-size:12px}
  .vp-card{width:52px;height:76px}
  .vp-card .r{font-size:15px}
  .vp-card .s{font-size:18px}
  .vp-hold{font-size:11px;padding:0 9px;min-height:44px;min-width:44px;
    display:flex;align-items:center;justify-content:center}
  .vp-hand{gap:5px;padding:12px 6px}
  .cr-point .k{font-size:11px;letter-spacing:.08em}
  .cr-point .v{font-size:19px}
  .cr-die{width:46px;height:46px}
  .cr-die i{width:8px;height:8px}
  .cr-sum{font-size:30px}
  .cr-felt{gap:12px}
  .cr-side .n{font-size:13px}
  .cr-side .p{font-size:11px}
}

/* ==========================================================================
   POKER DE 3 CARTAS
   ========================================================================== */
.tp-stage{display:flex;flex-direction:column;gap:10px;padding:16px 14px;
  border-radius:var(--r-lg);
  background:radial-gradient(ellipse at 50% 45%,rgba(55,214,240,.14),transparent 68%),
             linear-gradient(165deg,#0f3a4d,#0a1c30 55%,#05080f);
  border:1px solid rgba(255,255,255,.07)}
.tp-side{display:flex;flex-direction:column;gap:6px;align-items:center}
.tp-name{font-size:11px;letter-spacing:.10em;color:var(--txt-3);
  display:flex;align-items:center;gap:8px}
.tp-cat{font-size:11px;font-weight:700;color:#7de3ff;padding:1px 8px;
  border-radius:8px;background:rgba(0,0,0,.35)}
.tp-cat:empty{display:none}
.tp-hand{display:flex;gap:7px;min-height:80px;align-items:center;justify-content:center}
.tp-felt{text-align:center;font-size:10px;letter-spacing:.09em;color:rgba(255,216,115,.55);
  padding:5px 0;border-top:1px solid rgba(255,216,115,.16);
  border-bottom:1px solid rgba(255,216,115,.16)}
.tp-card{width:54px;height:78px;border-radius:8px;position:relative;flex:none;
  background:linear-gradient(180deg,#fff,#dde6ec);border:1px solid #aab6c4;color:#182028;
  box-shadow:0 5px 12px rgba(0,0,0,.44);animation:tpIn .26s ease}
.tp-card .r{position:absolute;top:5px;left:6px;font-size:16px;font-weight:800;line-height:1}
.tp-card .s{position:absolute;bottom:4px;right:6px;font-size:20px;line-height:1}
.tp-card.red{color:#c8323f}
.tp-card.back{background:repeating-linear-gradient(45deg,#123246,#123246 5px,#1c4a63 5px,#1c4a63 10px);
  border-color:#08202e}
@keyframes tpIn{from{opacity:0;transform:translateY(-14px) rotate(-5deg)}to{opacity:1;transform:none}}
.tp-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}
.tp-paywrap{border-top:1px solid rgba(255,255,255,.07);padding-top:8px}
.tp-paytitle{font-size:10px;letter-spacing:.14em;color:var(--gold);text-align:center;
  margin-bottom:5px}
.tp-pays{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
.tp-pay{display:flex;justify-content:space-between;gap:6px;padding:4px 7px;border-radius:6px;
  font-size:11px;border:1px solid transparent;transition:background .2s,border-color .2s}
.tp-pay .l{color:var(--txt-3)}
.tp-pay .x{font-weight:800;color:var(--gold)}
.tp-pay.on{background:rgba(255,197,61,.16);border-color:var(--gold);animation:tpHit .5s ease}
.tp-pay.on .l{color:#fff}
@keyframes tpHit{0%{transform:scale(1)}45%{transform:scale(1.05)}100%{transform:scale(1)}}
.tp-toggle{width:100%;display:flex;flex-direction:column;gap:1px;padding:9px 10px;
  border-radius:10px;border:1px solid rgba(255,255,255,.09);background:rgba(255,255,255,.04);
  color:var(--txt-1);cursor:pointer;transition:border-color .15s,background .15s}
.tp-toggle .n{font-size:13px;font-weight:800;line-height:1.1}
.tp-toggle .p{font-size:10px;color:var(--txt-3)}
.tp-toggle.on{border-color:var(--gold);background:rgba(255,197,61,.12)}
.tp-toggle.on .n{color:var(--gold)}

@media (pointer: coarse), (max-width: 900px){
  .tp-card{width:50px;height:72px}
  .tp-card .r{font-size:15px}
  .tp-card .s{font-size:18px}
  .tp-hand{min-height:74px}
  .tp-felt{font-size:11px;letter-spacing:.06em}
  .tp-pays{grid-template-columns:repeat(2,1fr)}
  .tp-pay{font-size:12px}
  .tp-paytitle{font-size:11px}
  .tp-toggle .n{font-size:14px}
  .tp-toggle .p{font-size:11px}
}

/* ==========================================================================
   TORMENTA (racimos con cascadas)
   ========================================================================== */
.tz-stage{display:flex;flex-direction:column;gap:10px;padding:14px;
  border-radius:var(--r-lg);
  background:radial-gradient(ellipse at 50% 40%,rgba(255,94,199,.16),transparent 68%),
             linear-gradient(160deg,#33115a,#160f30 55%,#06060f);
  border:1px solid rgba(255,255,255,.07)}
.tz-top{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:34px}
.tz-mult{font-size:19px;font-weight:800;color:#ff8ede;padding:3px 12px;border-radius:10px;
  border:2px solid #ff8ede;background:rgba(255,94,199,.12);
  transition:transform .2s,opacity .2s}
.tz-mult.off{color:var(--txt-3);border-color:rgba(255,255,255,.16);
  background:rgba(255,255,255,.04);opacity:.6}
.tz-mult:not(.off){animation:tzPop .3s ease}
@keyframes tzPop{0%{transform:scale(1)}45%{transform:scale(1.18)}100%{transform:scale(1)}}
.tz-win{font-size:17px;font-weight:800;color:var(--gold);min-height:20px}
.tz-grid{display:grid;gap:3px}
.tz-cell{aspect-ratio:1;border-radius:7px;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.02));
  border:1px solid rgba(255,255,255,.06);padding:2px}
.tz-cell svg{width:100%;height:100%;display:block}
.tz-cell.cae{animation:tzCae .28s ease}
@keyframes tzCae{from{opacity:0;transform:translateY(-26px)}to{opacity:1;transform:none}}
.tz-cell.gana{border-color:#ff8ede;background:rgba(255,94,199,.24);
  box-shadow:0 0 12px rgba(255,94,199,.55);animation:tzGana .42s ease}
@keyframes tzGana{0%{transform:scale(1)}40%{transform:scale(1.12)}100%{transform:scale(1)}}
.tz-status{font-size:13px;color:var(--txt-2);text-align:center;min-height:18px}
.tz-ladder{margin-top:12px}
.tz-steps{display:flex;gap:3px;flex-wrap:wrap}
.tz-step{flex:1;min-width:28px;text-align:center;font-size:11px;font-weight:700;
  padding:4px 2px;border-radius:6px;background:rgba(255,255,255,.05);color:var(--txt-3);
  border:1px solid transparent;transition:background .2s,color .2s,border-color .2s}
.tz-step.on{background:rgba(255,94,199,.22);color:#ff8ede;border-color:#ff8ede}
.tz-pays{margin-top:12px;display:flex;flex-direction:column;gap:3px}
.tz-payhead,.tz-payrow{display:grid;grid-template-columns:34px repeat(5,1fr);gap:4px;align-items:center}
.tz-payhead span{font-size:10px;color:var(--txt-3);text-align:center;letter-spacing:.04em}
.tz-payrow .sym{width:26px;height:26px}
.tz-payrow .sym svg{width:100%;height:100%;display:block}
.tz-payrow .x{font-size:10.5px;text-align:center;color:var(--txt-2);font-variant-numeric:tabular-nums}

@media (pointer: coarse), (max-width: 900px){
  .tz-mult{font-size:20px}
  .tz-win{font-size:18px}
  .tz-grid{gap:2px}
  .tz-cell{border-radius:6px;padding:1px}
  /* .tz-step: lo fija la grilla de 5x2 del bloque TORMENTA del final. */
  .tz-payhead span{font-size:11px}
  .tz-payrow .x{font-size:11px}
  .tz-payhead,.tz-payrow{grid-template-columns:26px repeat(5,1fr);gap:2px}
  .tz-payrow .sym{width:22px;height:22px}
}

/* ==========================================================================
   PANEL DE ADMIN — RTP
   ========================================================================== */
.rtp-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
.rtp-card{padding:12px;border-radius:12px;border:1px solid rgba(255,255,255,.09);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.015))}
.rtp-card.locked{opacity:.72;border-style:dashed}
.rtp-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:8px}
.rtp-name{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}
.rtp-val{font-size:19px;font-weight:800;color:var(--gold);font-variant-numeric:tabular-nums}
.rtp-val.dirty{color:#7de3ff}
.rtp-card .slider{width:100%;margin:2px 0 8px}
.rtp-foot{display:flex;align-items:center;justify-content:space-between;gap:8px}
.rtp-badge{display:inline-block;font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  padding:2px 7px;border-radius:6px;background:rgba(255,255,255,.08);color:var(--txt-3)}
.rtp-why{font-size:11px;line-height:1.45;color:var(--txt-3);margin:6px 0 0}

/* --- panel: salud de la casa ------------------------------------------- */
.salud-bar{position:relative;height:26px;margin:6px 0 4px;border-radius:13px;
  background:linear-gradient(90deg,
    rgba(224,69,58,.35) 0%, rgba(255,180,61,.28) 25%,
    rgba(62,224,138,.30) 44%, rgba(62,224,138,.30) 56%,
    rgba(255,180,61,.28) 75%, rgba(224,69,58,.35) 100%);
  border:1px solid rgba(255,255,255,.10)}
.salud-bar .zona{position:absolute;left:31.25%;right:31.25%;top:0;bottom:0;
  border-left:1px dashed rgba(255,255,255,.35);border-right:1px dashed rgba(255,255,255,.35)}
.salud-bar .marca{position:absolute;top:-4px;width:4px;height:34px;border-radius:2px;
  background:#fff;box-shadow:0 0 10px rgba(255,255,255,.7);transform:translateX(-2px)}
.salud-bar .lbl{position:absolute;top:5px;font-size:10px;color:var(--txt-3)}
.salud-bar .lbl.izq{left:8px} .salud-bar .lbl.der{right:8px}
.salud-z{text-align:center;font-size:20px;font-weight:800;font-variant-numeric:tabular-nums;
  color:var(--txt-1);margin-bottom:10px}
.salud-veredicto{padding:10px 12px;border-radius:10px;font-size:13px;line-height:1.5;
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.09)}
.salud-veredicto.ok{border-color:rgba(62,224,138,.45);background:rgba(62,224,138,.10)}
.salud-veredicto.wait{border-color:rgba(255,180,61,.45);background:rgba(255,180,61,.10)}
.salud-veredicto.err{border-color:rgba(224,69,58,.55);background:rgba(224,69,58,.14)}

/* --- mis numeros -------------------------------------------------------- */
.st-chart{width:100%;height:180px;margin:4px 0 8px}
.st-chart svg{width:100%;height:100%;display:block}
.stat .v.pos{color:#3ee08a}
.stat .v.neg{color:#ff8a7a}
td.pos{color:#3ee08a} td.neg{color:#ff8a7a}

/* --- promos en el lobby ------------------------------------------------- */
.lobby-top:empty{display:none}

/* --- carrusel de portada --- */
.lb-carrusel{
  position:relative;overflow:hidden;margin-bottom:14px;
  border-radius:var(--radius);border:1px solid var(--line-soft);
  box-shadow:var(--shadow-sm);background:var(--surface-flat);
  touch-action:pan-y;                 /* deja bajar la pagina, el gesto lateral es del carrusel */
}
.lb-pista{
  display:flex;
  transition:transform .5s cubic-bezier(.3,.9,.25,1);
  will-change:transform;
}
.lb-lamina{flex:0 0 100%;display:block;min-width:0}
.lb-lamina img{
  display:block;width:100%;
  /* En telefono queda una banda fina; en escritorio crece con el ancho hasta
     420 px, que es donde la imagen se ve como imagen y no como una tira. Se
     sigue recortando arriba y abajo porque a todo lo ancho medía 726 px y ahi
     los juegos se van de la pantalla. */
  aspect-ratio:1376/768;height:180px;object-fit:cover;object-position:center 34%;
  background:var(--surface-flat);
}
@media(min-width:901px){
  /* El encuadre sube al agrandar: las tres imagenes tienen texto arriba (el
     cartel, y en la del jackpot un "NUEVOS PREMIOS DIARIOS" pegado al borde)
     y con el encuadre al medio quedaba cortado por la mitad. */
  .lb-lamina img{height:clamp(300px,29vw,420px);object-position:center 20%}
}
/* Un fondo mientras la lamina todavia no bajo, para que no salte el alto. */
.lb-lamina img:not([src]){background:linear-gradient(110deg,#171430,#221c40,#171430)}

.lb-puntos{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;justify-content:center;gap:2px;
  padding:8px 0 2px;
  /* Sin esto los puntos blancos desaparecen sobre las partes claras de la
     imagen. Un velo de nada abajo y siempre se ven. */
  background:linear-gradient(180deg,transparent,rgba(6,5,14,.55));
  pointer-events:none;
}
/* El boton es grande para el dedo (38x38) y el punto que se ve es chico.
   Antes el boton medía 9x9: imposible de acertar en un telefono.

   OJO CON LOS DOS ARREGLOS DE ACA:

   1) Habia un `.lb-puntos` suelto delante de este comentario, sin bloque. El
      parser de CSS no se frena ahi: junta las dos partes y arma
      `.lb-puntos .lb-punto`. Como el punto ES hijo del contenedor, el selector
      seguia matcheando y el defecto no se veia... salvo por lo que viene.

   2) ...que el contenedor lleva `pointer-events:none` —esta puesto a proposito,
      para que el velo que hace legibles los puntos sobre una imagen clara no
      se coma el toque de la lamina— y eso se HEREDA. Sin devolverselo al
      boton, los tres puntos del carrusel no se podian tocar en ningun ancho:
      medido con elementFromPoint sobre el centro del punto, quien recibia el
      toque era la <img> de atras. O sea que el area tactil de 38x38 que este
      mismo comentario dice haber agrandado nunca llego a existir.
      Se reactiva solo en el boton, que es lo unico que tiene que recibir
      toques; el velo sigue siendo transparente al dedo. */
.lb-punto{
  /* 44x44: es el minimo que un dedo acierta sin pensar. El punto que se ve
     sigue midiendo 9 px (lo dibuja el ::before); lo que crece es la zona
     sensible, que es invisible y no cambia el diseno. */
  position:relative;width:44px;height:44px;padding:0;border:0;background:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  pointer-events:auto;
}
.lb-punto::before{
  content:'';position:absolute;left:50%;top:50%;width:9px;height:9px;
  transform:translate(-50%,-50%);border-radius:50%;
  border:1px solid rgba(255,255,255,.75);background:rgba(8,6,18,.55);
  box-shadow:0 1px 4px rgba(0,0,0,.7);
  transition:transform .2s cubic-bezier(.22,1.4,.36,1),background .2s,border-color .2s;
}
.lb-punto:hover::before{background:rgba(255,255,255,.6)}
.lb-punto.on::before{
  background:#fff;border-color:#fff;
  transform:translate(-50%,-50%) scale(1.4);
  box-shadow:0 0 10px rgba(255,255,255,.65);
}

@media(max-width:760px){
  .lb-lamina img{height:158px}
  .lb-puntos{padding:6px 0 1px}
}
@media (prefers-reduced-motion: reduce){
  .lb-pista{transition:none}
}
/* --- premios: dos fichas cortas, lado a lado tambien en telefono ---------
   Antes eran dos filas anchas apiladas que se comian 128 px de la primera
   pantalla, con el subtitulo cortado con puntos suspensivos. Ahora el numero
   manda y el texto se acomoda debajo. */
.promo-row{display:grid;gap:8px;grid-template-columns:1fr 1fr;margin-bottom:14px}
.promo-chip{
  position:relative;display:flex;flex-direction:column;gap:2px;
  padding:10px 12px 11px;min-width:0;overflow:hidden;
  border-radius:var(--radius-sm);border:1px solid var(--line-soft);
  background:linear-gradient(150deg,var(--surface-2),var(--surface-flat));
  transition:transform .16s cubic-bezier(.22,1.2,.36,1),border-color .16s;
}
.promo-chip:hover{transform:translateY(-2px)}
.promo-chip .pc-ico{
  position:absolute;right:-6px;top:-8px;width:52px;height:52px;
  display:grid;place-items:center;font-size:34px;line-height:1;
  opacity:.13;pointer-events:none;
}
.promo-chip .pt{
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted-2);
}
.promo-chip .pv{
  font-weight:900;font-size:clamp(19px,5.4vw,25px);letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;line-height:1.05;
}
.promo-chip .ps{
  font-size:11px;line-height:1.3;color:var(--muted-2);
  /* Dos renglones y corta: el subtitulo entero no entra en un telefono y
     cortarlo con puntos a mitad de palabra se veia peor que acortarlo. */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
}
.promo-chip .pc-txt{display:contents}
.promo-chip.bote{border-color:rgba(255,197,61,.26)}
.promo-chip.bote:hover{border-color:rgba(255,197,61,.55)}
.promo-chip.bote .pc-ico{color:var(--gold)}
.promo-chip.bote .pv{color:var(--gold)}
.promo-chip.carrera{border-color:rgba(124,92,255,.26)}
.promo-chip.carrera:hover{border-color:rgba(124,92,255,.55)}
.promo-chip.carrera .pc-ico{color:#c9b6ff}
.promo-chip.carrera .pv{color:#d6c8ff}

/* --- reloj de la carrera --- */
.promo-chip .pt{display:flex;align-items:center;gap:7px}
.pc-reloj{
  font-size:10px;font-weight:800;letter-spacing:.02em;
  padding:2px 7px;border-radius:999px;
  background:rgba(255,255,255,.08);color:var(--muted);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.pc-reloj:empty{display:none}
.pc-reloj.urgente{background:rgba(255,77,109,.18);color:#ff9db0}

/* --- seguir jugando --- */
.seguir-fila{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
@media(min-width:620px){.seguir-fila{grid-template-columns:repeat(4,minmax(0,1fr))}}
.seguir-card{
  position:relative;display:block;overflow:hidden;border-radius:var(--radius-sm);
  border:1px solid var(--line-soft);background:var(--surface-flat);
  transition:transform .16s cubic-bezier(.22,1.2,.36,1),border-color .16s;
}
.seguir-card:hover{transform:translateY(-3px);border-color:var(--game,#7c5cff)}
.seguir-card img{
  display:block;width:100%;aspect-ratio:16/9;object-fit:cover;object-position:center;
  transition:transform .4s cubic-bezier(.22,.9,.3,1);
}
.seguir-card:hover img{transform:scale(1.07)}
.sg-nombre{
  position:absolute;left:0;right:0;bottom:0;padding:16px 10px 8px;
  font-family:var(--display);font-size:12px;font-weight:900;letter-spacing:.03em;
  background:linear-gradient(180deg,transparent,rgba(6,5,14,.9) 62%,#06050e);
}

/* --- premios recientes (reemplaza la marquesina) --- */
.premios-card{padding:6px 8px}
.premio-fila{
  display:flex;align-items:center;gap:11px;padding:9px 8px;border-radius:9px;
}
.premio-fila + .premio-fila{border-top:1px solid var(--line-soft)}
.pr-pos{
  width:22px;height:22px;flex:0 0 auto;display:grid;place-items:center;border-radius:6px;
  font-size:11px;font-weight:900;background:rgba(255,255,255,.06);color:var(--muted-2);
}
.premio-fila:first-child .pr-pos{background:rgba(255,197,61,.18);color:var(--gold)}
.pr-quien{display:flex;flex-direction:column;min-width:0;gap:1px}
.pr-quien b{font-size:13px;font-weight:800;letter-spacing:.01em}
.pr-juego{font-size:11px;color:var(--muted-2)}
.pr-mult{
  margin-left:auto;font-size:11px;font-weight:700;color:var(--muted);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.pr-pago{
  font-size:14px;font-weight:900;color:var(--win);font-variant-numeric:tabular-nums;
  min-width:74px;text-align:right;white-space:nowrap;
}

/* --- tres razones, para el que entra por primera vez --- */
.confianza{
  display:grid;gap:12px;grid-template-columns:1fr;margin-top:26px;
  padding:18px;border-radius:var(--radius);
  border:1px solid var(--line-soft);
  background:linear-gradient(140deg,rgba(124,92,255,.07),rgba(34,211,238,.04) 60%,transparent);
}
@media(min-width:760px){.confianza{grid-template-columns:repeat(3,1fr);gap:22px;padding:22px 24px}}
.cf-item{display:flex;gap:12px;align-items:flex-start;min-width:0}
.cf-ico{width:22px;height:22px;flex:0 0 auto;color:var(--brand-2);margin-top:1px}
.cf-t{font-size:13px;font-weight:800;letter-spacing:.01em;margin-bottom:2px}
.cf-p{font-size:12px;line-height:1.45;color:var(--muted-2)}

/* --- esqueleto mientras baja la portada --- */
.game-card.cargando{background:linear-gradient(110deg,#14122a,#1e1a3a 40%,#14122a 70%)}
.game-card.cargando::before{
  content:'';position:absolute;inset:0;z-index:0;
  background:linear-gradient(100deg,transparent 20%,rgba(255,255,255,.07) 45%,transparent 70%);
  animation:brilloCarga 1.25s linear infinite;
}
/* Se anima transform, no background-position: lo resuelve la placa de video. */
@keyframes brilloCarga{from{transform:translateX(-100%)}to{transform:translateX(100%)}}
@media (prefers-reduced-motion: reduce){.game-card.cargando::before{animation:none}}
.promo-card{position:relative;overflow:hidden;padding:14px 16px;border-radius:var(--r-lg);
  border:1px solid rgba(255,255,255,.10)}
.promo-card.bote{background:radial-gradient(circle at 80% 0%,rgba(255,197,61,.28),transparent 65%),
  linear-gradient(150deg,#2b1d05,#140e18)}
.promo-card.carrera{background:radial-gradient(circle at 80% 0%,rgba(176,108,255,.28),transparent 65%),
  linear-gradient(150deg,#1e1240,#100c1e)}
.promo-card .pt{font-size:11px;letter-spacing:.10em;text-transform:uppercase;color:var(--txt-3)}
.promo-card .pv{font-size:26px;font-weight:800;margin:2px 0 4px;font-variant-numeric:tabular-nums}
.promo-card.bote .pv{color:var(--gold);text-shadow:0 0 20px rgba(255,197,61,.35)}
.promo-card.carrera .pv{color:#c9a6ff}
.promo-card .ps{font-size:12px;color:var(--txt-2);line-height:1.45}
.promo-lista{margin-top:8px;display:flex;flex-direction:column;gap:3px}
.promo-lista div{display:flex;gap:8px;font-size:12px;align-items:baseline}
.promo-lista .pos{width:16px;color:var(--txt-3);font-weight:700}
.promo-lista .nm{flex:1;color:var(--txt-1)}
.promo-lista .pr{color:var(--gold);font-weight:700}

/* ==========================================================================
   CHAT DEL SALON
   ========================================================================== */
.chat-card{display:flex;flex-direction:column;max-height:calc(100vh - 190px)}
.chat-lista{flex:1;min-height:280px;overflow-y:auto;display:flex;flex-direction:column;gap:7px;
  padding:8px;border-radius:10px;background:rgba(0,0,0,.22);
  border:1px solid rgba(255,255,255,.06);margin-bottom:10px}
.chat-msg{max-width:82%;padding:6px 10px;border-radius:12px;
  background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.07)}
.chat-msg.mio{align-self:flex-end;background:rgba(176,108,255,.16);border-color:rgba(176,108,255,.30)}
.chat-msg.sistema{align-self:center;max-width:100%;text-align:center;font-size:12px;
  background:rgba(255,197,61,.12);border-color:rgba(255,197,61,.30);color:var(--gold)}
.chat-msg .cab{display:flex;align-items:baseline;gap:7px;margin-bottom:2px}
.chat-msg .quien{font-size:12px;font-weight:700;color:#c9a6ff}
.chat-msg.mio .quien{color:#e6d4ff}
.chat-msg .rol{font-size:9px;letter-spacing:.06em;text-transform:uppercase;padding:1px 5px;
  border-radius:5px;background:rgba(255,197,61,.20);color:var(--gold)}
.chat-msg .hora{font-size:10px;color:var(--txt-3);margin-left:auto}
.chat-msg .txt{font-size:13px;line-height:1.45;color:var(--txt-1);
  overflow-wrap:anywhere;white-space:pre-wrap}
.chat-x{background:none;border:0;color:var(--txt-3);cursor:pointer;font-size:15px;
  line-height:1;padding:0 2px}
.chat-x:hover{color:#ff8a7a}
.chat-form{display:flex;gap:8px}
.chat-form .input{flex:1}
.chat-aviso{font-size:12px;color:#ffab8f;padding:6px 8px;border-radius:8px;
  background:rgba(224,69,58,.12);margin-bottom:8px}

@media (pointer: coarse), (max-width: 900px){
  .chat-card{max-height:calc(100vh - 210px)}
  .chat-msg{max-width:90%}
  .chat-msg .txt{font-size:14px}
  .chat-msg .hora{font-size:11px}
}

/* --- progreso del bono -------------------------------------------------- */
.bono-card{border-color:rgba(255,197,61,.32);
  background:linear-gradient(160deg,rgba(255,197,61,.10),rgba(255,255,255,.02))}
.bono-cifras{display:flex;justify-content:space-between;align-items:baseline;
  font-size:14px;margin-bottom:6px}
.bono-cifras .pct{font-size:20px;font-weight:800;color:var(--gold);
  font-variant-numeric:tabular-nums}
.bono-barra{height:10px;border-radius:5px;background:rgba(0,0,0,.35);overflow:hidden;
  border:1px solid rgba(255,255,255,.08)}
.bono-barra i{display:block;height:100%;border-radius:5px;
  background:linear-gradient(90deg,#f5b53d,#ffe89a);transition:width .4s ease}

/* ==========================================================================
   EFECTOS COMPARTIDOS
   --------------------------------------------------------------------------
   Regla unica: solo se anima `transform` y `opacity`.
   
   Son las dos propiedades que el navegador resuelve en la GPU sin volver a
   calcular la posicion de nada. Animar `left`, `width`, `filter: blur()` o
   `box-shadow` obliga a recalcular el diseño en CADA cuadro, y ahi es donde
   aparecen los tirones. Todo lo de abajo respeta eso, y por eso se puede
   agregar sin costo medible.
   ========================================================================== */

/* --- respiracion del escenario ------------------------------------------
   Un brillo lento detras del area de juego para que la pantalla no se vea
   muerta cuando nadie toca nada. Es un pseudo-elemento con un degradado ya
   pintado: animarlo es mover una textura, no redibujarla. */
.gl-stage{position:relative}
.gl-stage::before{
  content:'';position:absolute;inset:-10%;z-index:0;pointer-events:none;
  background:radial-gradient(circle at 50% 35%,
    var(--game-glow, rgba(124,92,255,.45)), transparent 62%);
  opacity:.55;
  animation:respira 7s ease-in-out infinite;
  will-change:transform,opacity;
}
.gl-stage > *{position:relative;z-index:1}
@keyframes respira{
  0%,100%{transform:scale(1);opacity:.42}
  50%    {transform:scale(1.06);opacity:.62}
}

/* --- reparto escalonado de cartas ---------------------------------------
   Las cartas entran una detras de otra en vez de aparecer todas juntas. El
   retraso lo pone una variable, asi cada juego elige su ritmo sin JS. */
@keyframes cartaEntra{
  from{opacity:0;transform:translateY(-18px) rotate(-7deg) scale(.92)}
  to  {opacity:1;transform:none}
}
.reparte > *{animation:cartaEntra .30s cubic-bezier(.2,.9,.3,1.2) backwards}
.reparte > *:nth-child(1){animation-delay:0ms}
.reparte > *:nth-child(2){animation-delay:70ms}
.reparte > *:nth-child(3){animation-delay:140ms}
.reparte > *:nth-child(4){animation-delay:210ms}
.reparte > *:nth-child(5){animation-delay:280ms}
.reparte > *:nth-child(6){animation-delay:350ms}
.reparte > *:nth-child(7){animation-delay:420ms}

/* --- respuesta al toque --------------------------------------------------
   Una celda que se hunde al tocarla se siente solida. Sin esto, en el
   telefono no hay forma de saber si el toque entro. */
.mines-cell,.kn-cell,.sb-cell,.dt-cell,.vp-slot,.rl-cell{
  transition:transform .10s ease, border-color .15s ease, background .15s ease;
}
.mines-cell:active,.kn-cell:active,.sb-cell:active,
.dt-row.active .dt-cell:active,.vp-slot:active,.rl-cell:active{
  transform:scale(.94);
}

/* --- latido del premio ---------------------------------------------------
   Se dispara agregando la clase y se saca sola: no deja estado colgado. */
@keyframes gana{
  0%  {transform:scale(1)}
  22% {transform:scale(1.10)}
  45% {transform:scale(.98)}
  100%{transform:scale(1)}
}
.late{animation:gana .5s cubic-bezier(.2,.9,.3,1.2)}

/* --- brillo que cruza un premio ----------------------------------------- */
.destello{position:relative;overflow:hidden}
.destello::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,
    rgba(255,255,255,.42) 50%,transparent 62%);
  transform:translateX(-140%);
  animation:cruza .7s ease-out;
}
@keyframes cruza{to{transform:translateX(140%)}}

/* Quien pidio menos movimiento, no lo recibe. */
@media (prefers-reduced-motion: reduce){
  .gl-stage::before{animation:none}
  .reparte > *{animation:none}
  .late,.destello::after{animation:none}
}

/* ==========================================================================
   DADOS QUE RUEDAN DE VERDAD
   --------------------------------------------------------------------------
   Antes las caras se cambiaban cada 40 ms: eso parpadea, no rueda. Ahora el
   dado gira en 3D mientras cambian las caras, que es lo que el ojo lee como
   "esta rodando".
   
   `rotate3d` lo resuelve la GPU sin recalcular nada, igual que translate. El
   `perspective` va en el contenedor para que los dos dados compartan el mismo
   punto de fuga y no parezcan girar cada uno en su mundo.
   ========================================================================== */
.cr-dice,.sb-dice{perspective:600px}
.cr-die,.sb-die{transform-style:preserve-3d;will-change:transform}

@keyframes ruedaDado{
  0%  {transform:rotateX(0deg)    rotateY(0deg)   translateY(0)}
  25% {transform:rotateX(180deg)  rotateY(90deg)  translateY(-14px)}
  50% {transform:rotateX(360deg)  rotateY(180deg) translateY(0)}
  75% {transform:rotateX(540deg)  rotateY(270deg) translateY(-8px)}
  100%{transform:rotateX(720deg)  rotateY(360deg) translateY(0)}
}
.rodando{animation:ruedaDado .62s cubic-bezier(.35,.05,.35,1) both}
/* El segundo dado arranca un pelo despues: dos dados girando en perfecta
   sincronia se ven mecanicos, no tirados. */
.rodando:nth-child(2){animation-delay:.06s}
.rodando:nth-child(3){animation-delay:.11s}

/* El dado ya frenado da un golpe seco contra el paño. */
@keyframes asientaDado{
  0%  {transform:translateY(-10px) scale(1.06)}
  55% {transform:translateY(0)     scale(.96)}
  100%{transform:none}
}
.asienta{animation:asientaDado .22s ease-out}

/* --- el numero del resultado entra con peso -------------------------- */
@keyframes numeroEntra{
  0%  {opacity:0;transform:scale(.4)}
  55% {opacity:1;transform:scale(1.22)}
  100%{opacity:1;transform:scale(1)}
}
.numero-pop{animation:numeroEntra .34s cubic-bezier(.2,.9,.3,1.3)}

/* --- huecos donde van a caer las cartas -------------------------------
   Un contorno tenue en el lugar exacto donde va a aparecer cada carta. Sin
   esto la mesa vacia se ve como un error de carga; con esto se lee como una
   mesa esperando. */
.hueco-carta{
  border:1.5px dashed rgba(255,255,255,.14);
  border-radius:8px;background:rgba(255,255,255,.02);
  animation:huecoLate 3.2s ease-in-out infinite;
  /* El hueco lleva TAMBIEN la clase de carta del juego, para medir exactamente
     lo que va a medir la carta. De ahi se hereda la sombra proyectada, que en
     un contorno vacio se ve como una carta a medio cargar. */
  box-shadow:none;
}
/* Los huecos laten desfasados: si los cuatro parpadean juntos parece un error
   intermitente; escalonados se lee como una mesa respirando. */
.hueco-carta:nth-child(2){animation-delay:.4s}
.hueco-carta:nth-child(3){animation-delay:.8s}
.hueco-carta:nth-child(4){animation-delay:1.2s}
.hueco-carta:nth-child(5){animation-delay:1.6s}
@keyframes huecoLate{
  0%,100%{opacity:.45}
  50%    {opacity:.8}
}

@media (prefers-reduced-motion: reduce){
  .rodando,.asienta,.numero-pop,.hueco-carta{animation:none}
}

/* --- andar bahar: la mesa en reposo -------------------------------------- */
.ab-row .hueco-carta{width:38px;height:54px}
/* Los desfases ahora son generales, arriba en .hueco-carta. */

/* ==========================================================================
   VOLTEO DE CARTA
   --------------------------------------------------------------------------
   Una carta que se da vuelta es el gesto mas reconocible de una mesa. Se hace
   girando el elemento sobre su eje Y y cambiando el contenido justo cuando
   esta de canto (a los 50%), que es cuando el ojo no puede ver el cambio.
   Es una sola propiedad animada —transform— asi que no cuesta nada.
   ========================================================================== */
@keyframes voltea{
  0%  {transform:rotateY(0deg)}
  50% {transform:rotateY(90deg)}
  100%{transform:rotateY(0deg)}
}
.voltea{animation:voltea .42s cubic-bezier(.4,0,.3,1); backface-visibility:hidden}

/* --- video poker: la carta guardada se levanta ------------------------- */
.vp-slot{transition:transform .16s cubic-bezier(.2,.9,.3,1.3), box-shadow .16s ease}
.vp-slot.held{
  transform:translateY(-10px);
  box-shadow:0 10px 22px rgba(0,0,0,.5), 0 0 0 2px var(--game,#3fa9f5);
}
/* El renglon de la tabla que pagó se enciende. */
@keyframes renglonGana{
  0%  {background:transparent}
  25% {background:rgba(255,197,61,.28)}
  100%{background:rgba(255,197,61,.10)}
}
.vp-pay.gano{animation:renglonGana .8s ease-out forwards}

/* --- mines: la gema aparece con rebote --------------------------------- */
@keyframes gemaSale{
  0%  {opacity:0;transform:scale(.3) rotate(-25deg)}
  60% {opacity:1;transform:scale(1.18) rotate(6deg)}
  100%{opacity:1;transform:scale(1) rotate(0)}
}
.mines-cell.gem svg{animation:gemaSale .34s cubic-bezier(.2,.9,.3,1.4)}

/* La mina que te mató tiembla. */
@keyframes minaEstalla{
  0%  {transform:scale(.5)}
  40% {transform:scale(1.3)}
  60% {transform:scale(1) rotate(-6deg)}
  75% {transform:rotate(5deg)}
  100%{transform:none}
}
.mines-cell.bomb.hit svg{animation:minaEstalla .5s ease-out}

/* --- torre: el huevo aparece, el dragon sacude -------------------------- */
.dt-cell.egg svg{animation:gemaSale .32s cubic-bezier(.2,.9,.3,1.4)}
.dt-cell.dragon.hit svg{animation:minaEstalla .5s ease-out}

/* --- limbo / crash: el numero sube desde abajo ------------------------- */
@keyframes numeroSube{
  from{opacity:0;transform:translateY(16px) scale(.85)}
  to  {opacity:1;transform:none}
}
.numero-sube{animation:numeroSube .3s cubic-bezier(.2,.9,.3,1.2)}

@media (prefers-reduced-motion: reduce){
  .voltea,.vp-pay.gano,.mines-cell.gem svg,.mines-cell.bomb.hit svg,
  .dt-cell.egg svg,.dt-cell.dragon.hit svg,.numero-sube{animation:none}
  .vp-slot.held{transform:none}
}

/* --- tope de pago en el encabezado del juego ---------------------------- */
.gh-tope{
  display:inline-block;margin-left:8px;padding:3px 9px;border-radius:999px;
  font-size:11px;font-weight:700;letter-spacing:.04em;
  color:#ffd873;background:rgba(255,216,115,.12);
  border:1px solid rgba(255,216,115,.35);white-space:nowrap;
}
@media (max-width: 900px){ .gh-tope{font-size:11px;padding:2px 7px} }

@media (pointer: coarse), (max-width: 900px){
  .limbo-stage{min-height:300px;padding:18px 16px;gap:12px}
  .limbo-stage{--rail:46px}
  .lb-cohete::after{width:52vw}
  /* 11 px es el piso legible en un telefono: por debajo hay que acercar la
     cara, y estos son justamente los numeros que se miran mientras sube. */
  .lb-tick span{font-size:11px}
  .lb-obj-txt{font-size:11px;padding:1px 5px}
}


/* ==========================================================================
   PROVABLY FAIR — la idea antes que las formulas
   ========================================================================== */
.pf-idea{
  background:linear-gradient(140deg,rgba(124,92,255,.10),rgba(34,211,238,.05) 55%,transparent);
  border-color:rgba(124,92,255,.24);
}
.pf-bajada{font-size:14px;line-height:1.55;color:var(--text);margin:-2px 0 18px;max-width:70ch}
.pf-pasos{display:grid;gap:16px;grid-template-columns:1fr}
@media(min-width:820px){.pf-pasos{grid-template-columns:repeat(3,1fr);gap:22px}}
.pf-paso{display:flex;gap:12px;align-items:flex-start;min-width:0}
.pf-num{
  width:26px;height:26px;flex:0 0 auto;display:grid;place-items:center;border-radius:50%;
  font-size:12px;font-weight:900;color:#0a0713;
  background:linear-gradient(135deg,#22d3ee,#8b5cff);
  box-shadow:0 0 14px rgba(124,92,255,.45);
}
.pf-paso-t{font-size:13px;font-weight:800;margin-bottom:4px;letter-spacing:.01em}
.pf-paso-p{font-size:12.5px;line-height:1.5;color:var(--muted-2)}

.pf-fila{display:grid;gap:10px;grid-template-columns:1fr}
@media(min-width:560px){.pf-fila{grid-template-columns:1fr 1fr}}
.pf-dato{
  padding:11px 14px;border-radius:var(--radius-sm);
  background:var(--surface-2);border:1px solid var(--line-soft);
}
.pf-dato .k{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2);margin-bottom:4px}
.pf-dato .v{font-size:16px;font-weight:800;letter-spacing:-.01em}

.pf-huella{
  display:flex;align-items:center;gap:12px;margin-top:10px;
  padding:11px 14px;border-radius:var(--radius-sm);
  background:var(--surface-2);border:1px solid var(--line-soft);
}
.pf-huella .k{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2);margin-bottom:4px}
.pf-huella .btn{margin-left:auto;flex:0 0 auto}
/* La huella completa son 64 caracteres. Se muestra recortada porque nadie la
   lee: se copia. El valor entero queda en el title y en el portapapeles. */
.pf-hash{font-size:12.5px;color:var(--muted);letter-spacing:.02em}

.pf-tecnico{padding:0}
.pf-tecnico>summary{
  cursor:pointer;padding:16px 18px;font-size:13px;font-weight:700;color:var(--muted);
  list-style:none;display:flex;align-items:center;gap:9px;
}
.pf-tecnico>summary::-webkit-details-marker{display:none}
.pf-tecnico>summary::before{
  content:'';width:0;height:0;flex:0 0 auto;
  border-left:5px solid currentColor;border-top:4px solid transparent;border-bottom:4px solid transparent;
  transition:transform .18s;
}
.pf-tecnico[open]>summary::before{transform:rotate(90deg)}
.pf-tecnico>summary:hover{color:var(--text)}
.pf-tecnico>*:not(summary){margin-left:18px;margin-right:18px}
.pf-tecnico>*:last-child{margin-bottom:16px}
.pf-tecnico pre{
  white-space:pre-wrap;background:var(--surface-2);padding:12px;border-radius:10px;
  overflow-x:auto;font-size:12px;line-height:1.6;
}


/* --- nada de zoom al tocar dos veces -------------------------------------
   En un juego se toca rapido y repetido: destapar casillas, subir la apuesta,
   apretar cobrar. El navegador interpreta dos toques seguidos como "acercar" y
   te deja la pantalla con zoom en el medio de una ronda.

   Va `manipulation` y NO `user-scalable=no` en el viewport: eso ultimo tambien
   mata el pellizco para agrandar, que hay gente que necesita para leer. Asi se
   apaga solo el doble toque y el pellizco sigue andando.

   Sobre todo lo que se toca, no sobre body: en el texto el doble toque para
   seleccionar una palabra tiene que seguir funcionando. */
button, a, input, select, textarea, label, summary,
.game-card, .mines-cell, .keno-cell, .sb-cell, .dt-cell, .rl-cell, .vp-slot,
.pk-bucket, .chip, .cat, .lb-punto, .seguir-card, .promo-chip{
  touch-action:manipulation;
}

/* ==========================================================================
   TELEFONO — la mayoria juega desde el celular
   ==========================================================================
   Dos problemas medidos, no supuestos:

   1) En 14 de los 19 juegos habia que BAJAR para llegar al boton de apostar.
      En Dice eran 531 px de scroll. El boton principal ahora vive fijo al pie
      de la pantalla, siempre al alcance del pulgar.

   2) El escenario ocupaba media pantalla o mas antes de que empezaran los
      controles. Se le pone un techo en vertical para que el juego y sus
      controles entren juntos.
   ========================================================================== */
@media (max-width:900px){
  /* --- barra de accion al pie --- */
  .acciones-movil{
    position:fixed;left:0;right:0;bottom:0;z-index:120;
    display:flex;flex-direction:column;gap:8px;
    padding:14px 12px calc(12px + env(safe-area-inset-bottom));
    /* Fondo propio: el boton solo, flotando sobre el contenido que pasa por
       debajo, se lee mal justo cuando hay que apretarlo. */
    background:linear-gradient(180deg,rgba(6,6,14,0),rgba(6,6,14,.9) 34%,#06050e 70%);
  }
  .acciones-movil > *{margin:0}
  .acciones-movil .btn-lg{min-height:54px;font-size:16px}
  /* El monto adentro de la barra: el campo manda y los ½ / 2× / Max se
     achican a lo justo para no comerse el ancho. */
  .acciones-movil .input-group{display:flex;gap:6px}
  .acciones-movil .input-group .input{flex:1 1 auto;min-width:0;text-align:center;font-size:17px}
  .acciones-movil .input-group .btn-sm{flex:0 0 auto;min-width:46px;padding:0 10px}
  /* La fila de fichas de ruleta y sic bo, ya en la barra: se reparte el ancho. */
  .acciones-movil .rl-chips{display:flex;gap:6px;margin:0}
  .acciones-movil .rl-chips > *{flex:1 1 0;min-width:0}
  /* El campo del que se mudo el monto: se queda la etiqueta y la pista sin
     nada debajo. Se esconde la etiqueta y la pista pasa a ser un renglon
     chico, para no perder el minimo y el maximo. */
  .monto-mudado{margin-bottom:8px}
  .monto-mudado > .label{display:none}
  .monto-mudado > .hint{margin-top:0;font-size:11px}
  .monto-mudado:not(:has(> .hint)){display:none}
  /* Las filas alternativas (PEDIR/PLANTARSE, PAGAR/RETIRARSE) van a lo ancho. */
  .acciones-movil > div{display:flex;gap:8px}
  .acciones-movil > div > .btn{flex:1 1 0;min-width:0}
  .acciones-movil > [hidden]{display:none!important}
  /* Hueco en el panel: sin esto el resto de los controles pega un salto. */
  .acciones-hueco{height:0}
  /* Y hueco al final de la vista, del alto REAL de la barra: lo mide app.js y
     lo escribe en --alto-acciones. Con un numero fijo el final de la pagina
     quedaba 24 px tapado en los juegos cuya barra lleva tambien el monto. */
  .view{padding-bottom:calc(var(--alto-acciones,0px) + 16px + env(safe-area-inset-bottom))}

  /* Los avisos flotantes viven justo donde ahora esta la barra: se suben POR
     ENCIMA de ella. El 96 fijo que puse primero servia para una barra de un
     solo boton; en los juegos cuya barra lleva tambien el monto (136 px) el
     aviso se dibujaba sobre el campo — y encima es el aviso que dice "monto
     invalido", tapando justo el campo que hay que corregir. Se ata al alto
     real de la barra, que app.js escribe en --alto-acciones. */
  .toasts{bottom:calc(var(--alto-acciones,0px) + 14px + env(safe-area-inset-bottom))}

  /* NO va techo de alto en el escenario.
     Lo probe: .gl-stage > *{max-height:52vh} rompio 11 de los 19 juegos. Un
     max-height sobre una caja cuyo contenido no puede achicarse no la achica:
     la desborda. Medido a 375x667, a la ruleta se le salian 306 px, a keno
     257, a la torre 259 — y en 8 juegos ese contenido se pintaba ENCIMA del
     panel del monto, robandole el toque a los botones.
     Lo que hacia falta era que el boton y el monto se alcanzaran, y eso lo
     resuelve la barra fija de arriba, no recortar el escenario. */

  /* Estos dos escenarios tienen alturas minimas pensadas para escritorio y
     dejaban el monto de la apuesta fuera de pantalla: medido, 646 px en dice y
     613 px en la rueda, con la pantalla util en 605. En el telefono se dejan
     encoger hasta su contenido. */
  .dice-stage{min-height:0;padding:22px 16px 20px}
  /* 44 y no 26: el globo del tiro ahora vive arriba de la barra y necesita su
     hueco. Son 18 px mas de escenario, que en el telefono ya no aprietan: el
     monto y el boton se mudaron a la barra fija del pie. */
  .dice-roll{margin-bottom:44px}
  .wh-stage{min-height:0;padding:14px 10px}
  .wh-wrap{width:min(260px,68vw)}

  /* --- hallazgos de la auditoria por juego ------------------------------ */

  /* DICE — la zona sensible de un range es la caja del input, no el pulgar que
     se ve. Con 36 px el dedo entra justo, y errarle mueve el objetivo y con el
     la chance y el multiplicador de un toque. */
  .view[data-game="dice"] .slider{height:48px}

  /* Las fichas de ultimas jugadas se deslizan pero la barra esta oculta a
     proposito, asi que nadie adivina que hay mas. El degrade del borde es la
     unica pista que le queda al dedo. Mismo recurso que ya usa .rl-board-wrap. */
  .chips{
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent);
            mask-image:linear-gradient(90deg,#000 calc(100% - 26px),transparent)
  }

  /* HI-LO — la cadena llega a 26 fichas y con el min-width generico de 62 px
     entraban cuatro. Estas no se tocan, solo se leen: no necesitan area de dedo. */
  .hl-stage .chip{min-width:0;padding:5px 8px;font-size:11px}

  /* MINES — el numero de minas elegido caia en un renglon aparte, en 11 px
     gris y en mayusculas. Es el dato que se mira mientras se arrastra la barra
     y era el texto mas chico de la pantalla. */
  .view[data-game="mines"] .label{display:flex;align-items:baseline;gap:6px}
  .view[data-game="mines"] .label .v{
    font-size:15px;font-weight:800;letter-spacing:0;text-transform:none;
    color:var(--text);font-variant-numeric:tabular-nums
  }

  /* --- escenarios que se achican DE VERDAD ------------------------------
     Estos siete dejaban el monto abajo del borde. No se recortan (probado: un
     max-height sobre contenido que no cede lo desborda y lo pinta encima del
     panel); se les baja el tamano propio. */

  /* Keno: 6 columnas dan bolillas de 49 px —arriba de los 40 del dedo— y siete
     filas en vez de ocho. Con 8 columnas quedaban en 35 px. */
  .keno-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:7px}

  /* Torre del dragon: nueve pisos son nueve pisos, no se pueden achicar sin
     romper el area de toque. Lo que si cede es el aire entre ellos. */
  .dt-row{gap:4px;padding:2px}
  .dt-tower{gap:4px}
  .dt-stage{gap:7px}

  /* Ruleta: la rueda ocupaba 80vw. En el telefono alcanza con menos y la mesa
     de apuestas, que es lo que se toca, sube. */
  .rl-wheel-wrap{width:min(210px,58vw)}

  /* Sic Bo: la banda del cubilete tenia aire de escritorio. */
  .sb-shaker{padding:10px;gap:12px}
  .sb-die{width:38px;height:38px}
  .sb-sum{font-size:24px;min-width:48px}

  /* --- lo que un dedo tiene que poder acertar ---------------------------
     Medido a 375 px: las bolillas de keno median 34x34 y son cuarenta; los
     cubos de plinko, 17 px de ancho con un numero adentro; las pestanas de
     sic bo, 33 px de alto. Un dedo cubre unos 40 px. */

  /* Plinko: los cubos no se tocan, pero a 17 px de ancho no se leen. Se les
     achica la letra y se les saca el relleno lateral para que el numero entre. */
  .pk-bucket{font-size:9px;padding:6px 0;letter-spacing:-.04em}

  /* Sic Bo: las pestanas suben a 40 de alto. */
  /* 44 y no 40: son los botones que eligen el tipo de apuesta, y en una mesa
     con cincuenta y dos apuestas errarle a la solapa es errarle a todo. */
  .sb-solapa{min-height:44px;padding:0 14px}

  /* Los ½ y 2× del monto: 38 px de ancho es justo el borde. */
  .input-group .btn-sm{min-width:44px}

  /* Los enlaces de los encabezados median 17 px de alto: con el dedo no se
     aciertan. Se les da alto de toque sin cambiar como se ven. */
  .section-head a{display:inline-flex;align-items:center;min-height:40px;padding:0 2px}
  .section-head{margin:14px 0 8px}

  /* Los controles respiran menos: en el telefono cada pixel cuenta. */
  .gl-panel{padding:13px}
  .gl-panel .field{margin-bottom:10px}
  .card+.card{margin-top:10px}
}




/* ==========================================================================
   HALLAZGOS DE LA AUDITORIA DE TELEFONO
   ==========================================================================
   Un agente por juego reviso su vista y su CSS buscando que se rompe en
   375x667 y 360x800, y otro agente trato de refutar cada hallazgo antes de
   aceptarlo. Lo que sigue son los 22 que sobrevivieron esa refutacion.
   Los comentarios explican POR QUE, con el numero medido que lo motiva.
   ========================================================================== */

/* --- CRASH · menor ---
   El escenario mide 280px de alto en TODO teléfono aunque su propio aspect-ratio pida 241 a 375 y 231 a 360: son 39-49px de cielo vacío de más, arriba de un panel que ya arranca debajo del pliegue. */
@media (pointer: coarse), (max-width: 900px){
  /* CRASH — el escenario declara aspect-ratio:16/11, pero el min-height:280px
     lo deja mudo en todo telefono: a 375 el stage mide 351 y el ratio pide
     241; a 360 mide 336 y pide 231. El piso solo deja de mandar con 407px de
     stage, o sea a partir de ~431 de viewport. Son 39-49px de cielo vacio
     empujando hacia abajo el auto cashout, que es lo unico que le queda al
     panel despues de que el monto y el boton se mudaron a la barra fija.
     Ojo: ese piso NO viene del escritorio —alli rige aspect-ratio:16/9 sobre
     un stage de 560-1020px, o sea 315-574px de alto, y ningun piso llega a
     intervenir—; nacio para el telefono y es justo ahi donde estorba.
     Se baja a un valor que no llega a mandar (a 320 el ratio ya da 203) pero
     que sigue cubriendo al navegador sin aspect-ratio: canvas, numero y sello
     son position:absolute y sin piso el escenario quedaria en 0.
     No es un techo y no recorta: el canvas se redibuja con su ResizeObserver
     y el dibujo es proporcional al alto. Misma maniobra que .limbo-stage. */
  .view[data-game="crash"] .crash-stage{min-height:200px}
}

/* --- CRASH · menor ---
   El sello PROVABLY FAIR desenfoca lo que tiene detrás mientras el canvas se repinta a 60fps durante todo el vuelo: el teléfono rehace ese blur en cada cuadro, en el único momento del juego en que no le */
@media (pointer: coarse), (max-width: 900px){
  /* El sello está clavado encima de un canvas que se repinta entero en cada
     cuadro durante todo el vuelo, así que el navegador rehace el desenfoque
     60 veces por segundo para decorar algo que no se mueve. Sobre un cielo
     casi negro el blur no aporta: alcanza con subirle un poco la opacidad al
     fondo para que el texto siga despegado. */
  .view[data-game="crash"] .crash-badge{
    backdrop-filter:none;-webkit-backdrop-filter:none;
    background:rgba(8,5,16,.82)
  }
}

/* --- SLOTS · rompe ---
   En cada giro el rodillo se estira de 149 a 948 px de alto: la maquina tapa toda la pantalla y la barra APUESTA/LINEAS/GANANCIA se va de y=430 a y=1229 (fuera de pantalla) mientras dura el giro. La pag */
/* SLOTS — el rodillo es una VENTANA de 3 filas, no una caja que crece con la
   tira. beginSpin() le mete 20 celdas de relleno y, como .reel saca su alto de
   .reel-strip (que esta en el flujo), el rodillo, el .slot-frame, el
   .slot-stage y todo lo que va abajo crecian con ella. Medido: a 375 el
   rodillo pasa de 149 a 948 px y la pagina de 1143 a 1942 — 800 px de salto
   por tirada, tres veces (reposo, giro, aterrizaje), justo mientras el jugador
   mira. Y encima se veian las 20 celdas de relleno a la vez.
   El alto sale de un relleno porcentual, que se mide contra el ANCHO del
   rodillo: tres celdas cuadradas de W-12 mas dos huecos y dos rellenos de 6
   = 3W-12. Da el mismo alto que ya tenia en reposo, al pixel. La tira pasa a
   absoluta para que su largo no vuelva a empujar el layout; el overflow:hidden
   que .reel ya traia hace de ventana.
   Sin @media a proposito: el defecto es identico y peor en escritorio (a 1280
   el rodillo iba de 448,4 a 2944,3 px). Verificado que en reposo no cambia
   nada a 320, 360, 375 ni 1280. */
.view[data-game="slots"] .reel::before{content:"";display:block;padding-top:calc(300% - 12px)}
.view[data-game="slots"] .reel-strip{position:absolute;top:0;left:0;right:0}

/* --- ROULETTE · rompe ---
   Arrastrar el tapete hasta el tope encadena el gesto al navegador: en Chrome de Android eso dispara el "volver atras" y te saca de la ruleta con las fichas ya puestas y sin girar. Medido a 375: el tape */
/* El tapete es el unico scroller de la app donde llegar al tope es obligatorio
   y no accidental: 715px de mesa en 319px utiles a 375 (396px siempre ocultos,
   411 a 360), y el propio juego imprime "Deslizá el tapete para ver toda la
   mesa". Sin cortar el encadenamiento, el arrastre sobrante se lo queda el
   navegador y en Android sale el gesto de "volver atras", perdiendo las fichas
   ya puestas. body ya hace esto en el eje vertical (overscroll-behavior-y:none);
   faltaba el horizontal.
   Sin media query a proposito: el tapete conserva columnas fijas (715px) hasta
   los 901px, asi que entre 771 y 900 tambien desborda, y el historial (18
   fichas de 62px = 1218px) desborda a cualquier ancho. Sobre un elemento que no
   scrollea la propiedad es un no-op, y no toca ni una medida de layout. */
.view[data-game="roulette"] .rl-board-wrap,
.view[data-game="roulette"] .rl-stage .chips{overscroll-behavior-x:contain}

/* --- ROULETTE · molesta ---
   La ficha que se apoya sobre la casilla —el unico lugar que dice cuanta plata tenes en ese numero— se pinta a 7,5px dentro de un circulo de 23x23. Es el texto mas chico de toda la app y esta 3,5px por  */
/* Ficha sobre la casilla: es el unico cartel que dice cuanta plata hay en ese
   numero y estaba a 7,5px, muy por debajo del piso de 11px que el propio
   archivo se fijo (bloque "tipografia minima legible" y tools/mobile_audit.mjs).
   Se escapaba del audit porque el audit nunca apuesta y el elemento no existe
   hasta que hay una ficha puesta.

   Pasa de circulo fijo de 23px a pastilla de ancho automatico: el monto manda
   el ancho. El max-width la deja siempre adentro de la casilla — sin el, una
   apuesta de "100.00" mide 49,7px y una de "1,000.00" 61,3px contra casillas
   de 46px, y como esta anclada con right:0 y z-index:2 el sobrante se pinta
   sobre la casilla vecina y le tapa el numero. Ojo: la etiqueta NO son siempre
   cuatro caracteres — hay ficha de 25 ("25.00") y el apilado por casilla no
   tiene tope propio (roulette.js:383; el limite de la linea 381 es sobre el
   total de la mesa), asi que con max_bet=$1.000 una sola casilla puede llegar
   a "1,000.00".

   Medido a 375px con la grilla real de 46px: "0.10"->34,7x24 · "25.00"->42,2
   · "100.00" y "1,000.00" topean en 44 y ninguna se sale de la casilla.
   Tapa entre 39% y 50% de un pleno (antes 25%); el numero se sigue leyendo
   arriba a la izquierda, y el monto era lo ilegible de los dos.

   Va con (pointer:coarse) ademas del ancho, que es la convencion que ya usa
   este archivo para la tipografia minima legible. Escritorio con mouse no
   entra; el tapete pasa a columnas fluidas en @media(min-width:901px).
   Este bloque tiene que quedar DESPUES de la regla base de la linea 1190. */
@media (pointer: coarse), (max-width: 900px){
  .rl-chip-on{
    width:auto;min-width:24px;max-width:100%;height:24px;padding:0 4px;
    border-radius:999px;font-size:11px;letter-spacing:-.02em
  }
  /* El canto rayado tiene que seguir el contorno nuevo: con border-radius:50%
     sobre una caja mas ancha que alta quedaba una elipse. */
  .rl-chip-on::before{border-radius:999px}
}

/* --- ROULETTE · molesta ---
   El historial de salidas muestra 4,7 de 18 numeros a 375px (4,5 a 360px). Cada bolilla ocupa 62px para un numero de uno o dos digitos, y como la barra de scroll esta oculta a proposito, la fila mide 12 */
@media (max-width:900px){
  /* RULETA — mismo caso que .hl-stage .chip, unos renglones mas arriba: el
     min-width de 62 px del .chip generico esta pensado para "+12.50", no para
     "17". Con el, las 18 salidas miden 18x62 + 17x6 = 1218 px dentro de los
     319 utiles del .rl-stage a 375 px (375 - 24 del .view - 28 del padding -
     4 del borde), y se ven 4,7 bolillas; a 360 px, 4,5. Sin el, la bolilla de
     dos digitos queda en ~35 px y entran unas 8. El historial es lo que se
     mira antes de apostar, asi que la mitad de la tira no alcanza.
     Estas bolillas no se tocan, solo se leen: no necesitan area de dedo. Que
     la tira sigue ya lo avisa el degrade de .chips. */
  .rl-stage .chip{min-width:0;padding:5px 9px;font-size:12px}
}

/* --- ROULETTE · molesta ---
   Deshacer / Limpiar / Repetir quedaron a 141px por debajo del borde inferior del tapete, con las dos estadisticas de por medio. Como la barra fija se come 140px de los 667 de la pantalla, a 375x667 sol */
@media (max-width:900px){
  /* Deshacer se usa justo despues de errarle a una casilla, y al tapete se le
     erra: son 715px de mesa arrastrados con el pulgar en una ventana de 319px.
     Estaba a 141px del borde del tapete, con las estadisticas en el medio, y
     como la barra fija ocupa 140px de los 667 solo quedaba una franja de 38px
     de scroll con el tapete entero y Deshacer juntos. Subiendolo al tope del
     panel la distancia baja a 66px y la franja pasa a 113px. Las estadisticas
     bajan 54px: son un dato que se mira, no un boton que se toca. */
  .view[data-game="roulette"] .gl-panel{display:flex;flex-direction:column}
  .view[data-game="roulette"] .gl-panel > .input-group{order:-1}
}

/* --- KENO · molesta ---
   En pantalla tactil el :hover se queda pegado en la ultima bolilla tocada: queda levantada 2 px y con un aro celeste de 1 px, sin estar elegida. El celeste del aro (rgba(77,214,255,.45)) es el mismo ce */
@media (pointer: coarse), (max-width: 900px){
  /* En una pantalla tactil el :hover no se va cuando levantas el dedo: se queda
     clavado en la ultima bolilla tocada, levantada y con el aro celeste, que es
     el mismo celeste con el que se pinta una bolilla elegida. Todo lo que el
     jugador lee de su jugada es cuales estan encendidas: una bolilla que finge
     estarlo le cambia la cuenta de cuantos numeros lleva. */
  .keno-cell:not(.picked):not(.drawn):hover{
    transform:none;
    box-shadow:inset 0 -6px 12px rgba(0,0,0,.3),0 2px 6px rgba(0,0,0,.35)
  }
}

/* --- KENO · menor ---
   El numero de la bolilla se dibuja a 12 px dentro de una bolilla de 47 px, y a 11,5 px en 360 px de ancho: es el texto mas chico del escenario y hay que barrerlo cuarenta veces para encontrar los propi */
/* Los dos hallazgos de keno que siguen se habian pegado SIN media query, con
   el comentario "pegar dentro del bloque @media (max-width:900px)" como unica
   instruccion. Al quedar al ras del archivo regian tambien en escritorio, que
   es justo lo que decian no querer tocar. Van en su @media propio en vez de
   mudarlos al bloque grande de arriba: la condicion es la misma y asi el
   comentario que explica cada medida no se separa de su regla. */
@media (max-width:900px){
  /* El tamano del numero venia atado al ancho de pantalla, de cuando la
     grilla eran 8 columnas y la bolilla media 35 px. Con 6 columnas la
     bolilla pasa a 47 y el numero se quedo en 12 px (11,5 a 360): un
     cuarto de bolilla de aire alrededor de lo unico que hay que leer, y
     son cuarenta para barrer buscando los propios. Se fija el mismo
     tamano que ya usa el escritorio, que entra de sobra hasta en la
     bolilla de 37,8 px de un telefono de 320. */
  .keno-cell{font-size:16px}

  /* --- KENO · menor ---
     Al caer la primera bolilla el tablero entero baja 7 px de golpe.

     El alto reservado por la linea de estado es el del reposo, no el del
     sorteo. En reposo hay texto plano de 15 px (15 x 1,45 = 21,75 -> 22 por el
     min-height); apenas cae la primera bolilla la linea se llena con la pastilla
     del marcador, que sin interlinea propia hereda el 1,45 del body: 17 x 1,45 =
     24,65 mas 4 de relleno = 28,65 px. Son casi 7 px que corren las cuarenta
     bolillas hacia abajo justo en el momento en que el jugador no despega la
     vista del tablero, y otros 7 hacia arriba cuando termina el sorteo y vuelve
     el texto plano. Se le saca a la pastilla la interlinea de parrafo, que no
     necesita, y se reserva de entrada el alto que va a pedir: 17 x 1,15 + 4 =
     23,55, o sea 24. Con 24 los dos estados miden lo mismo y el arreglo cuesta
     2 px, no 4. */
  .kn-marcador{line-height:1.15}
  .keno-status{min-height:24px}
}

/* --- MINES · molesta ---
   El renglon de estado pasa de 22 a 43,5 px de alto segun que texto le toque, asi que la grilla entera se corre 21,5 px hacia abajo al abrir la ronda y otros 21,5 hacia arriba en el primer destape, just */
@media (max-width:900px){
  /* MINES — el renglon de estado cambia de largo en cada destape y el ancho
     util del escenario (317 px a 375) no le alcanza al texto de apertura: pasa
     de una linea a dos y de vuelta, y arrastra la grilla 21,5 px arriba y
     abajo entre toque y toque. En un tablero de 5x5 eso es media casilla: el
     dedo apunta a una y aterriza en otra. Se le reserva de entrada el alto de
     las dos lineas y se centra adentro, asi el texto cambia y la grilla no se
     mueve. Con align-content (y no place-items) el parrafo sigue ocupando todo
     el ancho, que es lo que necesita el text-align:center que ya tenia. */
  .mines-status{
    min-height:38px;display:grid;align-content:center;
    font-size:14px;line-height:1.3;margin-bottom:10px
  }
}

/* --- MINES · molesta ---
   La barra de minas es un input[type=range] de 36 px de alto: el dedo queda 4 px abajo del minimo de 40, y errarle cambia la cantidad de minas de la ronda que estas por abrir. */
@media (max-width:900px){
  /* MINES — mismo caso que dice, que ya se arreglo pero acotado a ese juego: lo
     que el dedo tiene que acertar en un range es la caja del input, no el
     pulgar dibujado. A 36 px se queda corto, y errarle no es un detalle
     estetico: cambia cuantas minas hay y con eso todos los multiplicadores de
     la ronda. */
  .view[data-game="mines"] .slider{height:48px}
}

/* --- MINES · molesta ---
   Al tocar una casilla no se ve el hundido del toque sino el efecto contrario, la casilla LEVANTADA con halo verde; y si el juego ignora ese toque (doble toque rapido, o ronda ya terminada) la casilla s */
/* Reemplaza las lineas 1603-1607 de public/assets/css/app.css.

   Sin puntero no hay hover que valga: el navegador tactil lo deja pegado a lo
   ultimo que tocaste. Una casilla que el juego ignoro se quedaba levantada,
   como si estuviera por destaparse — y el juego ignora bastante: reveal()
   sale por `if (busy || !bet) return` sin ningun aviso, y paintFinished()
   deja bet = null, asi que con la ronda cerrada las 25 casillas se tocan y no
   pasa nada. Las gastadas quedan .faded, que no es .gem ni .bomb, o sea que
   siguen entrando aca.

   Y ademas este :hover pesa (0,4,0) contra los (0,2,0) de .mines-cell:active
   (hay dos, lineas 1608 y 2469), asi que en mines el hundido del toque que se
   agrego a proposito no llegaba a verse nunca.

   Se acota el hover a los aparatos con puntero en vez de contrapesarlo: en
   tactil deja de existir y el scale(.94) de la linea 2469 sale solo. No se
   duplica la sombra base de la linea 1594 y no depende de donde se pegue.
   En escritorio con mouse (hover:hover) queda exactamente igual que hoy,
   incluso en una ventana angosta. */
@media (hover:hover){
  .mines-cell:not(.gem):not(.bomb):hover{
    transform:translateY(-3px);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 10px 20px rgba(0,0,0,.5),
               0 0 0 1px rgba(37,229,200,.4),0 0 20px rgba(37,229,200,.22)
  }
}

/* --- SICBO · molesta ---
   Los puntos de los tres dados se salen de la cara: la grilla de 3x3 pide 28 px y en el dado de 38 entran 24, asi que las filas se corren hacia abajo (7 px de aire arriba, 3 abajo) y quedan a 2 px entre */
@media (max-width:900px){
  /* El dado bajo a 38 px pero el punto se quedo en los 8 px calculados para el
     de 44. Como las pistas de `repeat(3,1fr)` tienen minimo `auto`, esos 8 px
     las estiran: la cara de 3x3 pide 28 px donde hay 24 (38 - 14 de relleno) y,
     al no haber espacio libre que repartir, la grilla se alinea al arranque y
     queda corrida 4 px hacia abajo Y hacia la derecha (medido: 7 px de aire
     arriba e izquierda, 3 abajo y derecha). No se sale del dado, pero la cara
     queda descentrada. Con el punto en 6 la cara pide 22 y sobran 2 px que las
     pistas 1fr reparten solas: vuelve a quedar centrada (7,33 / 7,34) y de paso
     la separacion entre puntos sube de 2 a 2,7 px, que es lo que hace que el 5
     y el 6 se lean como cara y no como mancha. No se toca el relleno: dejarlo
     en 7 mantiene holgura; cerrarlo justo con padding:8 devuelve el desborde
     ante cualquier cambio futuro de tamano o de gap. */
  .sb-die i{width:6px;height:6px}
  /* Red de seguridad: mientras la cara entra esto no hace nada (las pistas 1fr
     ya se comieron el espacio libre); solo actua si alguna vez vuelve a
     desbordar, y ahi centra en vez de correr todo al vertice. */
  .sb-die{place-content:center}
}

/* --- SICBO · molesta ---
   El renglon del resultado ('6 · 5 · 4 = 15 · cobras $128.40') se escribe en y=570, y la barra fija arranca en y=465: sin bajar la pagina, tirar no muestra en ningun lado cuanto se cobro. Los dados y el */
/* El renglon del resultado se agrega al final del escenario (sicbo.js:369,
   stage.append(statusLine) despues de .sb-table) y en el telefono la mesa lo
   empuja 408 px abajo del cubilete: medido a 375x667 queda en y=621,9 con la
   barra fija arrancando en 527, y elementFromPoint sobre el devuelve el boton
   TIRAR. Se tira y el resultado se pinta DETRAS del boton que acabas de
   apretar. Va pegado al cubilete, que es adonde se mira cuando frenan los
   dados. Los cuatro order hacen falta: con dos, los otros dos quedan en
   order:0 y se van arriba de todo.

   OJO: esto estaba pegado SIN media query, con un comentario que decia "va
   dentro del @media (max-width:900px)" y afirmaba que arriba de 900 el
   escenario mantenia el orden del DOM. Al ras del archivo no lo mantenia: el
   DOM es cubilete, historial, mesa, resultado, y estos order lo reordenaban
   tambien en escritorio, subiendo el resultado por encima del historial. En
   escritorio no hay barra fija tapando nada y el resultado al pie del
   escenario es donde lo pone el diseno, asi que el arreglo se acota al
   telefono, que es donde nacio el problema. */
@media (max-width:900px){
  .sb-shaker {order:1}
  .sb-status {order:2}
  .sb-history{order:3}
  .sb-table  {order:4}
}

/* --- BLACKJACK · molesta ---
   En la fila PEDIR/PLANTARSE/DOBLAR de la barra del pie, la etiqueta PLANTARSE se recorta por los dos lados: el boton mide 111,67 px (tercio exacto de 351 menos dos gaps de 8), el relleno se come 36 y q */
@media (max-width:900px){
  /* Tres botones repartidos en tercios exactos dejan 74,3 px de texto util a
     375 px (111,67 menos 36 de relleno y 2 de borde), y PLANTARSE mide 89 a
     15 px en negrita. Como es una sola palabra es el min-content del item
     flex: no encoge ni parte, y con overflow:hidden se recorta 7,4 px por
     lado — 9,9 a 360 px. Lo que sobra es el relleno de 18 px pensado para un
     boton suelto en la columna de 352 del escritorio; los 48 px de alto del
     dedo no se tocan, solo cede el aire horizontal.
     Va sobre .row y no sobre div: el .input-group del monto tambien es un div
     hijo directo de la barra, y con esta especificidad le ganaria a la regla
     de .acciones-movil .input-group .btn-sm, cambiandole el ½ y el 2×. */
  .view[data-game="blackjack"] .acciones-movil > .row > .btn{
    padding:0 6px;font-size:14px;letter-spacing:-.01em
  }
}

/* --- BLACKJACK · menor ---
   El .gl-panel queda como una tarjeta iluminada de ~50 px de alto con un solo renglon gris de 11 px adentro. En blackjack el panel tenia exactamente tres hijos (el .field del monto, REPARTIR y la fila a */
@media (max-width:900px){
  /* Panel que quedó con la sola pista de mínimo y máximo adentro.
     montarBarraAccion() se lleva el monto y los botones a la barra del pie; en
     blackjack y en videopoker el panel no tenía nada más, así que lo único que
     sobrevive es un renglón gris de 11 px dentro de una tarjeta con borde de
     acento, filo superior y 13 px de relleno: se lee como un bloque que no
     cargó. Se le saca la piel de tarjeta y la pista pasa a ser el pie del
     escenario, que es lo que en realidad es.

     Se apagan los DOS pseudo-elementos de .card-glow: el ::before del borde
     degradado y también el ::after (el filo de 2 px de var(--game) pegado a
     top:0). Si se deja sólo el ::before, el filo queda flotando solo encima
     del renglón, sin caja que lo sostenga, que es peor que el problema.

     Se detecta por estructura y no por data-game: así cubre blackjack y
     videopoker —los únicos dos de los 19 cuyo panel se vacía del todo— y deja
     de aplicar solo si mañana alguno recupera un control. */
  .gl-panel:not(:has(> :not(.monto-mudado):not(.acciones-hueco))){
    background:none;border:0;box-shadow:none;padding:0
  }
  .gl-panel:not(:has(> :not(.monto-mudado):not(.acciones-hueco)))::before,
  .gl-panel:not(:has(> :not(.monto-mudado):not(.acciones-hueco)))::after{
    content:none
  }
  /* Sin relleno ni borde, el margen del campo ya no colapsa (el panel es item
     de grilla): queda como hueco muerto al pie. Se saca. */
  .gl-panel:not(:has(> :not(.monto-mudado):not(.acciones-hueco))) .field{
    margin-bottom:0
  }
}

/* --- BLACKJACK · menor ---
   El escenario conserva el relleno y las separaciones de escritorio: .bj-stage con padding 18/16 y gap 10, .bj-side con gap 7. Son ~25 px verticales muertos sobre los ~407 utiles que quedan entre el enc */
@media (max-width:900px){
  /* El pano todavia respira como en un monitor. Entre el encabezado pegajoso
     y la barra del pie quedan ~407 px y la mesa mide ~330: los 25 que se
     recuperan de relleno y separaciones son los que hacen que la linea de
     estado entre sin bajar. No se recorta nada, no cambia ningun tamano de
     carta ni de letra. */
  .view[data-game="blackjack"] .bj-stage{padding:12px;gap:7px}
  .view[data-game="blackjack"] .bj-side{gap:5px}
  /* Con 327 px de ancho util y gap 5, seis cartas entran en una fila (325):
     antes la sexta abria una segunda fila y el escenario crecia 79 px en
     plena mano. A 360 px siguen entrando cinco, igual que hoy. */
  .view[data-game="blackjack"] .bj-hand{gap:5px}
}

/* --- CRAPS · molesta ---
   Con RESPALDAR CON ODDS oculto —que es el estado durante casi toda la partida, porque el odds solo se puede poner con punto establecido y sin respaldar— la barra fija del pie mide 152px y los ultimos 1 */
@media (max-width:900px){
  /* Craps sube al pie el DIV que envuelve a RESPALDAR CON ODDS, y el hidden
     vive en el boton, no en el div. La regla generica `> [hidden]` pide el
     atributo en el hijo directo de la barra —asi estan blackjack y poker de 3,
     que lo ponen en la fila— y por eso a craps no lo agarra; y el
     margin-top:8px inline le gana a `> *{margin:0}`, que es un selector de
     clase. Quedaba un div de alto 0 cobrando igual 8px de gap del flex mas 8px
     de margen propio: 16px de barra vacia, degrade sin nada adentro, justo en
     el estado en que el odds no se puede poner —salida, tirada en curso, ronda
     cerrada o ya respaldada—, que es casi toda la partida. Medido: 152px de
     barra contra 136.
     Se esconde la fila cuando no le queda ningun boton a la vista. El grupo del
     monto se excluye a proposito: tambien es un div hijo de la barra y no tiene
     que depender de que lleve el ½ y el 2× adentro para seguir existiendo.
     Con el odds visible la fila vuelve sola, y --alto-acciones lo recalcula el
     ResizeObserver de app.js, asi que el hueco al pie de la vista acompaña. */
  .view[data-game="craps"] .acciones-movil > div:not(.input-group):not(:has(> .btn:not([hidden]))){
    display:none
  }
}

/* --- ANDARBAHAR · molesta ---
   El escenario tira 62 de los 321 px de ancho en la etiqueta ANDAR/BAHAR y 16 px de alto por línea en min-heights calculados para la carta de escritorio. Resultado: entran 6 cartas por fila en vez de 7, */
@media (max-width:900px){
  /* ANDAR BAHAR — la mesa se quedo con las medidas del escritorio: 62 px de
     ancho para una etiqueta de cinco letras y min-heights pensados para la
     carta de 54 px cuando aca mide 48. Recuperado ese aire la fila pasa de
     259 a 273 px, que es lo justo para 7 cartas (7x34 + 6x4 = 262) en vez de
     6: la mano tipica de 25 cartas baja de 411 a 345 px de mesa, la maxima de
     51 de 671 a 552, y la mesa en reposo de 241 a 195. Nada se achica: lo
     que se va es el relleno. */
  .view[data-game="andarbahar"] .ab-stage{padding:12px 10px;gap:8px}
  .view[data-game="andarbahar"] .ab-line{gap:8px;min-height:0}
  .view[data-game="andarbahar"] .ab-name{width:48px}
  /* La fila igual no se puede desplomar: mientras se da vuelta el joker queda
     vacia 360 ms, y el minimo la sostiene en el alto exacto de una carta. */
  .view[data-game="andarbahar"] .ab-row{min-height:48px}
  /* Los huecos seguian en 38x54: .ab-row .hueco-carta pesa mas que el
     .ab-card{34x48} de telefono y encima vive fuera de toda media query. Por
     eso la mesa en reposo media 54 de alto por linea —el min-height:48 de
     arriba no llegaba a aplicarse— y las cartas NO caian sobre el contorno
     que las esperaba: 5 huecos ocupan 206 px y las 5 primeras cartas, 186.
     Se los iguala a la carta de telefono. */
  .view[data-game="andarbahar"] .ab-row .hueco-carta{width:34px;height:48px}
}

/* --- TORMENTA · molesta ---
   La linea de estado (.tz-status) queda 100% tapada por la barra de accion fija: arranca en y=544 y la barra empieza en y=469. En una ronda que no paga es el unico aviso que existe, asi que se gira y no */
/* La linea de estado vive al pie del escenario: en 375x667 arranca en y=544 y
   la barra de accion fija empieza en y=469, asi que no se lee nunca sin bajar.
   En una ronda que no paga es el UNICO aviso que queda —el badge se apaga y
   .tz-win queda vacia—, o sea que se gira y no pasa nada visible. Sube arriba
   de la grilla, que es donde mines ya pone su .mines-status. Se le reservan los
   dos renglones que ocupa de verdad: los 51 caracteres del texto de arranque no
   entran en los 321 px del escenario, y al pasar a "Girando…" la pagina pegaba
   un salto de 19 px justo cuando arranca la animacion.
   Los 8 px de aire que se recortan salen del gap y del padding de ARRIBA y
   ABAJO: el lateral no se toca porque ese manda el ancho de la grilla y, con
   celdas aspect-ratio:1, el ancho es tambien el alto. */
@media (max-width:900px){
  .tz-stage{gap:8px;padding:12px 14px}
  .tz-status{order:1;min-height:38px;display:flex;align-items:center;justify-content:center}
  .tz-grid{order:2}
}

/* --- TORMENTA · molesta ---
   La escalera de multiplicadores se parte en 9 + 1: el ultimo escalon (×10) cae solo en un segundo renglon y, como lleva flex:1, se estira a lo ancho de toda la tarjeta. En 320px se parte en 8 + 2. */
/* Los 10 escalones piden 10x30 + 9x3 = 327 px de minimo y el panel por dentro
   mide 317 px en 375, 302 en 360 y 262 en 320: el flex-wrap corta la fila en
   9+1 (en 320, en 8+2) y el escalon que sobra, que lleva flex:1, se estira solo
   a lo ancho de toda la tarjeta. Como el numero de cascada no se escribe en
   ningun lado —va en data-i y se lee por la posicion—, una fila partida en dos
   renglones desparejos deja de leerse como escalera. Grilla fija de 5x2: los
   diez caen siempre en el mismo lugar, a 60 px cada uno (48 en 320), y sobra
   lugar para subir la tipografia al piso legible del proyecto. No se tocan:
   syncLadder solo les pone la clase .on, asi que no les corre el minimo de 40.

   OJO: esto tambien estaba pegado SIN media query, y la grilla de 5x2 regia en
   escritorio. Ahi la escalera no se parte —el panel mide 318 px por dentro y
   los 10 escalones piden 327 de minimo... por 9 px— pero de todas formas la
   grilla de dos renglones era lo que se veia en un monitor, que es donde la
   escalera SI entra de una. Se acota al telefono, y el min-width de escritorio
   baja a 28 px para que la fila de 10 entre entera en la columna de 352.
   El .tz-step del bloque de arriba (font-size:11px;padding:6px 2px;
   min-width:30px) ya no hace falta: esta regla lo reemplaza entero. */
@media (pointer: coarse), (max-width: 900px){
  .tz-steps{display:grid;grid-template-columns:repeat(5,1fr);gap:4px}
  .tz-step{min-width:0;padding:7px 2px;font-size:12px}
}


/* ==========================================================================
   RULETA EN TELEFONO — LA MESA SE PARA DE COSTADO
   ==========================================================================
   La mesa clasica mide 715 px de ancho fijos. En un telefono de 375 el hueco
   util del escenario es de 319: sobran 396 px, o sea que MAS DE LA MITAD de
   las casillas solo se alcanzaban arrastrando de costado, a ciegas y sin barra
   que avisara donde estabas. Medido con la vista abierta y sin tocar nada, del
   tapete se veian el 0 y los numeros hasta el 15; el 16 al 36, las tres
   docenas, las seis sencillas y los tres 2:1 quedaban afuera. Y llegar al tope
   arrastrando encadenaba el gesto al navegador, que en Android es el "volver
   atras" — te ibas del juego con las fichas puestas (eso ya esta cortado unos
   bloques mas arriba con overscroll-behavior-x).

   Aca la mesa se para: 0 arriba, los 36 numeros en 3 columnas x 12 filas, el
   2:1 al pie de su columna, y docenas y sencillas debajo. Es la disposicion
   que usan las mesas de telefono de verdad, y no es capricho: el telefono
   tiene alto de sobra y ancho ninguno. Se pasa de arrastrar de costado 396 px
   invisibles a bajar con el scroll de siempre, el de la pagina, que ademas es
   seguro porque la barra de accion deja GIRAR fijo al pie.

   Las casillas quedan de unos 104x40 en vez de 46x46: mas grandes que el dedo
   en las dos direcciones, y errarle a un numero de costado ya es imposible.

   El corte va en 770 px y no en los 900 del resto del telefono porque 770 es
   justo donde la mesa clasica deja de entrar: el hueco util es (ancho - 56) y
   la mesa pide 715. Arriba de eso la mesa clasica entra sola y no hay nada que
   arreglar. El ancho maximo evita que en una tableta angosta las casillas se
   estiren a 240 px de ancho.
   ========================================================================== */
@media (max-width:770px){
  .rl-cell{grid-column:var(--mc);grid-row:var(--mr)}
  .rl-board{
    grid-template-columns:repeat(3,minmax(0,1fr));
    /* 0 · 12 filas de numeros · 2:1 · 3 docenas · 2 filas de sencillas */
    /* Todas las filas a 44 px o mas: es el minimo que un dedo acierta sin
       mirar. Las docenas estaban en 32 y el 2:1 en 36, que con la mesa en
       vertical son las mas faciles de errar porque van pegadas entre si.
       El tapete crece 84 px en total, y como la pagina se desliza no molesta. */
    grid-template-rows:44px repeat(12,44px) 44px repeat(3,44px) repeat(2,46px);
    min-width:0;padding:0;max-width:460px;margin:0 auto
  }
  /* Ya no hay nada que deslizar: sin el degrade de los bordes, que ahora
     apagaria la primera y la ultima columna de una mesa que entra entera. */
  .rl-board-wrap{
    overflow:visible;padding-bottom:0;
    -webkit-mask-image:none;mask-image:none
  }
  /* El 0 pasa de franja vertical a la izquierda a franja horizontal arriba. */
  .rl-zero{border-radius:10px 10px 4px 4px}
  /* Las de afuera pasan de casillas angostas a renglones de 104 px o mas: el
     11,5 px que necesitaban para entrar en la mesa clasica ya no hace falta. */
  .rl-cell.outside{font-size:13px}
  .rl-col{font-size:13px}
}


/* ==========================================================================
   ESCRITORIO
   ==========================================================================
   Todo lo de arriba es mobile-first: la base es telefono y los @media suben.
   El problema no era que faltaran reglas de escritorio, era que sobraban
   reglas de telefono SIN media query. Tres bloques de la auditoria movil se
   habian pegado al ras del archivo con un comentario que decia "pegar dentro
   del @media (max-width:900px)" — y nadie los pego adentro. Regian en las dos
   pantallas. Ya estan acotados en su seccion; esto es lo que le faltaba al
   escritorio de verdad.

   El corte entre las dos mitades es UNO SOLO, 900/901 px, y esta escrito en
   tres lugares que tienen que moverse juntos:
     · app.js         → MQ_TELEFONO, monta o no la barra de accion al pie
     · @media (max-width:900px)  → el aspecto de esa barra y los ajustes de mano
     · @media (min-width:901px)  → .view, .game-layout y el tapete de la ruleta
   ========================================================================== */

/* --- el lobby deja de crecer para siempre --------------------------------
   La grilla de juegos se quedaba en 3 columnas desde los 620 px hasta el
   infinito. En 1440 eso son fichas de 411x257 px: la portada de Dice ocupaba
   mas que el escenario del juego, y los 19 juegos pedian 3.857 px de pagina
   (cuatro pantallas y media de scroll para elegir a que jugar).
   Con la .view topada en 1320, cuatro columnas dan fichas de 307 px, que es el
   mismo tamano que tienen a 1000 px de ventana con tres. El lobby baja a 2.900
   px y la ficha mide igual en toda la franja de escritorio. */
@media(min-width:1180px){
  .game-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
}

/* --- TORMENTA: la grilla no puede crecer con la ventana -------------------
   .tz-grid es 7x7 de celdas aspect-ratio:1 y no tenia tope, asi que se comia
   todo el ancho del escenario: a 1440 media 872x872 y el escenario entero,
   976 px. Con la barra de arriba y el encabezado del juego, el boton GIRAR
   quedaba a 1.684 px de pagina — habia que bajar para jugar, en un monitor.
   Y una cereza de 123 px no se lee mejor que una de 77: la grilla es una
   grilla, no un poster.
   El tope es hermano de los que ya tienen keno (620 para 8 columnas -> 70 px
   de bolilla) y mines (500 para 5 -> 87 px). 560 para 7 da celdas de 77 px.
   En telefono no ata nada: alli el escenario mide 320 y manda el ancho. */
.tz-grid{max-width:560px;width:100%;margin-inline:auto}

/* --- CAJERA: las dos columnas se deciden en CSS, no una sola vez en JS ----
   wallet.js leia matchMedia('(min-width:980px)') UNA vez, al pintar, y escribia
   grid-template-columns en el atributo style. Un valor inline no se recalcula:
   la cajera abierta en una ventana angosta se quedaba en una columna para
   siempre por mucho que se agrandara la ventana, y abierta ancha y despues
   achicada dejaba las dos columnas apretadas hasta recargar. Es la definicion
   de no ser responsive. Ahora lo decide el CSS y sigue a la ventana sola.
   Va a 901 como el resto del escritorio. */
.cajera-grid{grid-template-columns:1fr}
@media(min-width:901px){
  .cajera-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* --- ventanas de escritorio BAJAS ----------------------------------------
   El panel de escritorio volvio a cargar dos filas que en telefono se lleva la
   barra del pie: el campo del monto y el boton principal. Sumadas, en la
   ventana mas baja que se usa de verdad —una laptop de 1280x800— el panel de
   dice terminaba 9 px abajo del borde y el "Auto ×10" quedaba cortado por la
   mitad. Es el unico de los 19 que se pasa: el que le sigue, crash, termina en
   632 de 800.
   Se le aprieta el aire vertical al panel, que es lo mismo que ya hace el
   bloque de telefono por el mismo motivo (ahi son 13 px de relleno y 10 de
   separacion entre campos). Con relleno 13 y campos a 10 el panel de dice pasa
   de 617 a 605 px y entra con 3 px de sobra. No cambia ningun tamano de letra
   ni de area de click, y arriba de 860 px de alto no rige: en 1440x900 y
   1920x1080 el panel se ve exactamente igual que antes. */
@media (min-width:901px) and (max-height:860px){
  .gl-panel{padding:13px}
  .gl-panel .field{margin-bottom:10px}
}

/* --- pantallas DE VERDAD bajas -------------------------------------------
   Lo de arriba recupera 12 px, que alcanza para 800 px de alto. Pero una
   laptop de 1366x768 deja ~657 px utiles y una de 1280x720, ~600: ahi el
   panel de dice se cortaba 140 y 197 px, o sea que el boton de apostar
   quedaba abajo del pliegue. Es exactamente el defecto que la barra fija
   arregla en el telefono, apareciendo por el otro lado.
   Se recorta donde no cuesta nada: el encabezado del juego, que es una
   imagen decorativa con el nombre, y el aire entre controles. No se toca
   ningun tamano de letra ni area de click. */
@media (min-width:901px) and (max-height:760px){
  .game-head{min-height:64px}
  .game-head .gh{padding:8px 16px}
  .view{padding-top:14px}
  .game-layout{gap:10px}
  .gl-panel{padding:11px}
  .gl-panel .field{margin-bottom:8px}
  .gl-panel .btn-lg{min-height:48px}
  .card+.card{margin-top:10px}
  .stats-2,.stats-3,.stats-4{gap:6px}
  .stat{padding:8px}
  /* Dice es el panel mas alto de los 19 —nueve grupos de control— y el unico
     cuyo boton quedaba abajo del pliegue: 20 px a 1366x657 y 77 a 1280x600.
     Estos cuatro huecos suman los ~70 px que faltaban. La racha se esconde:
     es un aviso ocasional, no un control. */
  .dice-racha{display:none}
  .dice-mults{margin-bottom:8px}
  .dice-stats{margin-bottom:9px}
  .gl-panel .btn-ghost.btn-block{margin-top:5px}
  .dice-roll{margin-bottom:34px}

  /* Ultimos px, para las pantallas de 600. Se recorta alto de control, nunca
     tipografia: con mouse un objetivo de 40 px se acierta de sobra —el minimo
     de 44 es para el dedo, y este bloque no corre en telefono (min-width:901).
     El slider de dice es la excepcion que ya tenia trato aparte en movil por
     lo mismo, al reves. */
  .gl-panel .input,.gl-panel select.input{min-height:42px}
  .gl-panel .seg button{min-height:38px}
  .gl-panel .label{margin-bottom:4px}
  .gl-panel .slider{height:30px}
  .gl-panel .btn-sm{min-height:34px}
}


/* ==========================================================================
   ESCRITORIO · LAS PIEZAS DE JUEGO A ESCALA
   ==========================================================================
   Las cartas, los dados y las fichas estaban dimensionados en px fijos para un
   telefono, y en el monitor no crecian: el escenario pasa a 900 px de ancho y
   el juego se quedaba en el mismo puñado de piezas de 50 px flotando en el
   medio de una caja vacia. Medido a 1440x900: en video poker las cinco cartas
   ocupaban 332 de 900 px; en andar bahar, 5 huecos de 38 px con 600 px de
   fieltro vacio al lado; en bacara, dos cajas de 860x110 con una carta de 54.

   No se toca ninguna medida de telefono: todo va en el @media de escritorio y
   los factores estan entre 1,3x y 1,5x, que es lo que hace falta para que una
   carta se lea como carta a la distancia de un monitor sin desbordar la fila
   mas larga de cada juego (blackjack 6 cartas, video poker 5, andar bahar 13).
   ========================================================================== */
@media (min-width:901px){

  /* --- BLACKJACK ------------------------------------------------------- */
  /* 6 cartas de 82 + 5 huecos de 10 = 542 px sobre los 868 utiles. */
  .bj-card{width:82px;height:117px;border-radius:11px}
  .bj-card .r{font-size:23px;top:8px;left:9px}
  .bj-card .s{font-size:29px;bottom:6px;right:9px}
  .bj-card.back{background:repeating-linear-gradient(45deg,#1d2b52,#1d2b52 7px,#2b3d6d 7px,#2b3d6d 14px)}
  .bj-hand{min-height:119px;gap:10px}
  .bj-stage{padding:26px 22px;gap:14px}
  .bj-side{gap:10px}

  /* --- VIDEO POKER ----------------------------------------------------- */
  /* Las cinco cartas son EL juego: se tocan una por una para retenerlas. */
  .vp-card{width:92px;height:132px;border-radius:11px}
  .vp-card .r{font-size:26px;top:8px;left:9px}
  .vp-card .s{font-size:31px;bottom:6px;right:9px}
  .vp-hand{gap:12px;padding:22px 14px}

  /* --- POKER DE 3 CARTAS ----------------------------------------------- */
  .tp-card{width:80px;height:116px;border-radius:11px}
  .tp-card .r{font-size:23px;top:8px;left:9px}
  .tp-card .s{font-size:29px;bottom:6px;right:9px}
  .tp-card.back{background:repeating-linear-gradient(45deg,#123246,#123246 7px,#1c4a63 7px,#1c4a63 14px)}
  .tp-hand{min-height:118px;gap:10px}

  /* --- BACARA ---------------------------------------------------------- */
  .bc-card{width:78px;height:110px;border-radius:11px}
  .bc-card .r{font-size:29px}
  .bc-card .s{font-size:24px}
  .bc-hand{min-height:112px;gap:11px}
  .bc-side{padding:16px}
  .bc-total{font-size:34px}

  /* --- ANDAR BAHAR ----------------------------------------------------- */
  /* Sube menos que el resto (1,3x) porque su fila llega a 51 cartas: a 50 px
     entran 13 por renglon y la mano tipica de 25 sigue en dos. */
  .ab-card{width:50px;height:71px;border-radius:8px}
  .ab-card .r{font-size:16px;top:4px;left:5px}
  .ab-card .s{font-size:19px;bottom:3px;right:5px}
  .ab-joker .ab-card{width:58px;height:82px}
  .ab-row{gap:6px;min-height:71px}
  .ab-row .hueco-carta{width:50px;height:71px}
  .ab-line{min-height:83px;gap:14px}
  .ab-name{width:70px;font-size:11px}

  /* --- HI-LO ----------------------------------------------------------- */
  /* La carta es lo unico que hay en el escenario: que sea la pieza grande. */
  .hl-card{width:190px;border-radius:18px}
  .hl-rank{font-size:68px}
  .hl-suit{font-size:38px}
  .hl-stage{padding:30px 16px 22px}
  .hl-status{font-size:15px;margin-top:18px}

  /* --- SIC BO ---------------------------------------------------------- */
  .sb-die{width:62px;height:62px;border-radius:15px;padding:9px;gap:3px}
  .sb-die i{width:12px;height:12px}
  .sb-sum{font-size:40px;min-width:78px}
  .sb-shaker{padding:26px 18px;gap:24px}
  .sb-dice{gap:16px}

  /* --- CRAPS ----------------------------------------------------------- */
  /* Era el escenario mas flaco de los 19: 165 px de alto, con dos dados de 54
     perdidos en una franja de 900 de ancho, y el pano —que en craps ES la
     mesa— reducido a un filete verde de 130 px. Los dados suben a 76 y el
     pano a un alto de mesa: el degrade radial recien se lee como fieltro
     cuando tiene lugar para abrirse. */
  .cr-die{width:76px;height:76px;border-radius:16px;padding:11px;gap:3px}
  .cr-die i{width:14px;height:14px}
  .cr-dice{gap:20px}
  .cr-felt{padding:52px 24px;gap:26px;min-height:210px}
  .cr-sum{font-size:52px;min-width:96px}
  /* El punto es EL estado de la partida —define que numero hay que repetir— y
     estaba en una pastilla de 8 px arriba a la izquierda, mas chica que el
     resto. Sube a tamano de cartel sin moverse de su esquina. */
  .cr-point{top:18px;left:20px;padding:9px 16px;border-radius:14px;gap:2px}
  .cr-point .k{font-size:10px}
  .cr-point .v{font-size:24px}

  /* --- SIC BO: el cubilete tambien es una mesa --------------------------- */
  .sb-shaker{min-height:170px}

  /* --- LA RUEDA ---------------------------------------------------------
     Estaba topada en min(340px,80vw): en el telefono manda el 80vw y esta
     bien, pero en un escenario de 900 px se quedaba en 340 fijos con 560 px
     de violeta vacio alrededor. Y la rueda es TODO el juego: los numeros de
     cada segmento se leen a 9 px con 30 segmentos. A 440 px pasan a 12. */
  .wh-wrap{width:min(440px,58vw)}
  .wh-center{font-size:26px;padding:6px 15px}

  /* --- TORRE DEL DRAGON -------------------------------------------------- */
  /* Las puertas son `flex:1` sin tope, asi que a 900 px de escenario cada una
     medía 265x36: una barra apaisada que se lee como un campo de formulario
     vacio, no como una puerta que se elige. La torre se topa a un ancho donde
     la puerta queda cerca del cuadrado (168x48) y se centra; el alto sube
     porque la puerta es lo que se toca nueve veces por partida. */
  .dt-tower{max-width:600px;margin-inline:auto;padding:20px;gap:7px;width:100%}
  .dt-cell{min-height:48px;border-radius:11px}
  .dt-cell svg{width:30px;height:30px}
  .dt-row{gap:7px;padding:4px}
  .dt-x{font-size:13px;width:76px}
}


/* ==========================================================================
   ESCRITORIO · FILAS DE FICHAS Y TABLA DE PAGOS
   ========================================================================== */

/* --- las tiras de historial dejan de cortarse -----------------------------
   .chips es un scroller horizontal: en el telefono eso esta bien —deslizar de
   costado es el gesto natural y el degrade del borde avisa que sigue—, pero en
   un monitor con mouse no hay como moverlo y lo unico que se ve es contenido
   cortado contra el borde del escenario. Medido a 1440 con la caja en 866-874
   px de ancho util:

       crash     1641 px de fichas  ->  se veian 53%
       bacara    1626 px            ->  53%   (el "road" de la mesa)
       limbo     1376 px            ->  63%
       dice      1354 px            ->  65%
       ruleta    1218 px            ->  71%

   En los cinco, la ultima ficha quedaba partida al medio contra el borde. Se
   pasa a envolver: el historial es informacion que se lee de un vistazo, no
   una fila que se recorre, y en dos renglones entra entero.
   El scroller se conserva tal cual abajo de 901: ahi el gesto existe y el
   degrade ya lo indica. */
@media (min-width:901px){
  .chips{flex-wrap:wrap;overflow-x:visible;row-gap:6px}
  /* Dos renglones es historial; cinco es una pared que empuja el resto de la
     vista. El tope son dos renglones exactos (30 de ficha + 6 de hueco, x2, mas
     los 4 de relleno inferior).
     Va `auto` y no `hidden` a proposito: medido, los seis juegos con historial
     entran hoy en dos renglones justos —crash 24 fichas, bacara 24, limbo 20,
     dice 20, rueda 19, ruleta 18—, pero si alguno crece, un `hidden` esconderia
     el resto sin avisar, que es exactamente el defecto que este bloque vino a
     arreglar. Con `auto` aparece la barra y se ve que sigue. */
  .chips{max-height:76px;overflow-y:auto}

  /* La cadena de hi-lo llega a 26 cartas y con el min-width de 62 px del .chip
     generico pediria tres renglones. Estas fichas no se tocan, solo se leen:
     es la misma compactacion que el bloque de telefono ya les hace por el
     mismo motivo. Con 26 fichas de ~46 px entran en dos. */
  .hl-stage .chip{min-width:0;padding:6px 10px}
}

/* --- VIDEO POKER: la tabla de pagos es parte de la maquina ----------------
   En una maquina de video poker la tabla de pagos es lo primero que se mira y
   ocupa el frente del gabinete: es lo que distingue una 9/6 —la buena, la que
   tiene esta sala— de una 8/5. Aca eran nueve renglones de 12 px sin titulo ni
   separaciones, apretados en una franja de 108 px de alto, con el mismo peso
   visual que una nota al pie. Royal Fortune, que es el otro juego con tabla,
   la muestra como una grilla de fichas con el simbolo y se lee de un vistazo.

   No se cambia la estructura ni el JS: se le da el peso que ya tenia que
   tener. Renglones separados por una linea, el nombre de la mano y el
   multiplicador en columnas alineadas, y numeros tabulares para que las
   comas caigan una debajo de la otra. */
@media (min-width:901px){
  .vp-pays{padding:16px 18px;gap:2px 26px;border-radius:var(--radius)}
  .vp-pay{
    padding:9px 10px;font-size:14px;border-radius:8px;
    border-bottom:1px solid rgba(255,255,255,.06);border-radius:0
  }
  /* El ultimo de cada columna no lleva linea: son tres columnas de tres. */
  .vp-pay:nth-child(3n){border-bottom:0}
  .vp-pay .l{color:var(--text);font-weight:600}
  .vp-pay .x{font-size:15px;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
  .vp-pay.on{border-radius:8px;border-bottom-color:transparent}
}

/* ==========================================================================
   TABLERO DEL ADMINISTRADOR
   --------------------------------------------------------------------------
   El panel tenia volumen y GGR en cuatro cajitas iguales. Todo pesaba lo
   mismo, asi que no habia nada que mirar primero. Estas piezas ordenan la
   pantalla por urgencia: lo que hay que atender arriba y con color, la plata
   despues, y el detalle al final.
   ========================================================================== */

/* --- lo que necesita atencion -------------------------------------------- */
/* Solo aparece si hay algo. Un tablero que siempre muestra una franja de
   avisos ensena a ignorarla; si esta, es porque hay que hacer algo. */
.av-lista{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
.av{
  display:flex;align-items:center;gap:10px;padding:11px 13px;
  border-radius:var(--radius-sm);border:1px solid var(--line-soft);
  background:var(--surface-flat);font-size:13px
}
.av-punto{width:8px;height:8px;border-radius:50%;flex:0 0 8px;background:var(--muted-2)}
.av.urge{border-color:rgba(255,197,61,.34);background:rgba(255,197,61,.07)}
.av.urge .av-punto{background:var(--gold)}
.av.mal{border-color:rgba(255,77,109,.34);background:rgba(255,77,109,.07)}
.av.mal .av-punto{background:var(--lose)}
.av-txt{flex:1;min-width:0}
.av-txt b{color:var(--text)}
.av .btn{flex:0 0 auto}

/* --- numeros grandes ------------------------------------------------------ */
/* Como .stat pero con el valor al doble: son las tres o cuatro cifras que uno
   viene a mirar, y tienen que leerse desde lejos. */
.kpi{
  background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.012));
  border:1px solid var(--line-soft);border-radius:var(--radius-sm);
  padding:13px 14px;min-width:0;overflow:hidden
}
.kpi .k{
  font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted-2);font-weight:600
}
.kpi .v{
  font-size:22px;font-weight:800;font-variant-numeric:tabular-nums;
  margin-top:4px;letter-spacing:-.02em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis
}
.kpi .sub{font-size:11px;color:var(--muted-2);margin-top:3px}

/* Los numeros grandes NO se apretan en tres columnas en un telefono. Con
   .stats-3 cada caja quedaba en 120 px y "$1.085.805,00" no entra: el numero
   se cortaba justo donde estan los millones, que es la parte que importa.
   En pesos los importes tienen muchos digitos, asi que se apilan y recien se
   ponen al lado cuando hay lugar de verdad. */
.kpis{display:grid;grid-template-columns:1fr;gap:8px}
@media(min-width:560px){.kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:900px){.kpis{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:760px){.kpi .v{font-size:26px}}

/* --- grafico de barras ---------------------------------------------------- */
/* Con divs y no con una libreria: son dos barras por dia y meter un paquete
   de graficos para esto costaria mas kilobytes que toda la aplicacion. */
.graf{display:flex;align-items:flex-end;gap:6px;height:120px;margin-top:10px}
/* Las dos barras van UNA AL LADO DE LA OTRA y no apiladas. Apiladas, sus
   alturas se suman y con un dia bueno se salian de la caja; ademas invitan a
   leer el total, que aca no significa nada: volumen y ganancia no se suman. */
.graf-col{
  flex:1;min-width:0;max-width:64px;display:flex;align-items:flex-end;
  justify-content:center;gap:3px;height:100%
}
.graf-b{
  width:100%;max-width:16px;border-radius:3px 3px 0 0;min-height:2px;
  transition:height .25s ease
}
.graf-b.vol{background:var(--surface-3)}
.graf-b.ggr{background:linear-gradient(180deg,var(--win),var(--win-2))}
.graf-b.ggr.neg{background:linear-gradient(180deg,var(--lose),#c0203f)}
.graf-pie{
  display:flex;gap:6px;margin-top:6px;font-size:9px;color:var(--muted-2);
  text-align:center
}
.graf-pie span{flex:1;min-width:0;max-width:64px;overflow:hidden;white-space:nowrap}
.graf-ref{display:flex;gap:14px;font-size:11px;color:var(--muted-2);margin-top:10px}
.graf-ref i{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:5px}

/* --- cabecera de seccion con el selector de periodo ----------------------- */
.tb-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:12px
}
.tb-head h2{font-size:16px;margin:0}
