/* CandelaBet — hoja de estilos del producto.
   Implementa el design system (repo `candelabet-design`, proyecto CandelaBet en Claude
   Design). Móvil primero: el mercado venezolano es teléfono casi puro.

   Los dos registros del sistema:
     BRASA (.hero, .game, mesas de juego) — halo de brasa, cifras grandes, movimiento.
     SALA  (.card: cajero, retiros, límites, cuenta) — plana, sin brillo, sin animación.
   El dinero no arde: en SALA el naranja aparece una sola vez por tarjeta, en el botón
   primario, y las cifras van en hueso, no en oro. */

:root {
  /* Base carbón */
  --carbon: #0b0d12;
  --carbon-2: #12151d;
  --carbon-3: #1a1f2b;
  --borde: #262c3a;
  --borde-claro: #333b4d;

  /* Fuego */
  --llama: #ff6a1f;
  --llama-alta: #ffa02e;
  --llama-honda: #d94b0c;
  --tinta-llama: #2a0d00;
  --oro: #ffc857;
  --brasa: #2a1206;

  /* Texto */
  --hueso: #f3f5fa;
  --humo: #8d95a8;
  /* El tercer gris de texto. Estaba en #5b6376 y NO pasaba AA en ninguna de las
     tres superficies (2,74 sobre carbon-3, 3,03 sobre carbon-2), con sus nueve
     usos en texto de 0,62-0,72rem — o sea por debajo del umbral de «texto
     grande», así que la excepción de 3:1 no aplicaba. Entre ellos las etiquetas
     del retiro, que es la pantalla que el sistema llama diferenciadora, y los
     montos perdidos del feed.
     Ahora 4,51 sobre carbon-3 y 5,32 sobre carbon: el gris MÁS TENUE que pasa.
     La jerarquía se comprime a 1,26x contra --humo, y es la consecuencia
     honesta: tres grises de texto legibles sobre fondo oscuro no caben. El
     tercer escalón lo llevan el tamaño y el peso, que ya lo hacían. */
  --ceniza: #7b869f;

  /* Estado */
  --sube: #2fd07a;
  --cae: #ff4d57;
  --aviso: #ffbb38;

  /* Prueba: todo lo que el jugador puede comprobar va en frío, nunca en naranja.
     Si el hash brillara como el botón de apostar, se leería como publicidad. */
  --frio: #4aa8ff;
  --frio-tenue: rgba(74, 168, 255, .12);
  --sube-tenue: rgba(47, 208, 122, .12);
  --cae-tenue: rgba(255, 77, 87, .12);
  --aviso-tenue: rgba(255, 187, 56, .12);

  --halo-hero: radial-gradient(120% 100% at 0% 0%, var(--brasa) 0%, var(--carbon-2) 58%);
  --halo-juego: radial-gradient(90% 70% at 50% 110%, var(--brasa) 0%, var(--carbon-2) 62%);
  --grad-llama: linear-gradient(180deg, var(--llama-alta), var(--llama));

  /* MATERIALES.
     Las mesas se dibujaban con el mismo lenguaje que el resto de la app —rectángulo,
     borde de un píxel, fondo liso—, que es el lenguaje de un formulario. Una mesa de
     juego tiene dos cosas que un formulario no: PIEZAS que se cogen y una SUPERFICIE
     donde caen. Las dos se dibujan con sombras, no con colores más vivos, así que la
     paleta no cambia y la accesibilidad tampoco: lo que cambia es que las piezas dejan
     de estar impresas sobre la mesa y pasan a estar encima.

     `--relieve` es una pieza posada: luz en el canto de arriba, sombra bajo el de abajo
     y una sombra proyectada corta. `--hundido` es lo contrario, y sirve para dos cosas
     que son la misma: la superficie de juego, y una pieza mientras se PULSA. Que pulsar
     invierta la sombra es lo que da el clic físico.
     `--cara` es el barniz: apenas un 5 % de luz arriba y un 7 % de sombra abajo. Sin él
     las piezas son planas con un borde bonito. */
  --relieve: inset 0 1px 0 rgba(255, 255, 255, .07), inset 0 -2px 0 rgba(0, 0, 0, .36), 0 2px 5px rgba(0, 0, 0, .4);
  --relieve-alto: inset 0 1px 0 rgba(255, 255, 255, .13), inset 0 -3px 0 rgba(0, 0, 0, .42), 0 5px 13px rgba(0, 0, 0, .52);
  --hundido: inset 0 4px 12px rgba(0, 0, 0, .5), inset 0 -1px 0 rgba(255, 255, 255, .035);
  --cara: linear-gradient(180deg, rgba(255, 255, 255, .055), rgba(0, 0, 0, .07));

  --r-chico: 8px;
  /* Objetivo mínimo de toque. La primera apuesta del sistema es «móvil de un
     pulgar», y estaba escrita en la guía pero no en el código: los controles más
     tocados del producto —los chips de apuesta, Manual/Auto, el «atrás»— venían
     entre 30 y 40px. Vive aquí para que la regla se aplique, no se recuerde. */
  --toque: 44px;
  --r: 12px;
  --r-tarjeta: 16px;
  --sombra: 0 8px 28px rgba(0, 0, 0, .45);
  --safe: env(safe-area-inset-bottom, 0px);
  --alto-nav: 59px;   /* alto real de la barra de abajo: lo necesita la apuesta pegada */
  /* Instalada en iOS la app se dibuja de borde a borde: el reloj y la batería quedan
     ENCIMA de la barra superior si no se reserva el alto de la barra de estado. */
  --safe-top: env(safe-area-inset-top, 0px);
  /* Alto real de la barra superior: lo mide el JS al arrancar y al girar el teléfono.
     El valor de aquí es sólo el respaldo hasta que eso ocurra. */
  --alto-barra: calc(56px + var(--safe-top));

  --display: ui-rounded, "SF Pro Rounded", "Arial Rounded MT Bold", "Arial Black", system-ui, sans-serif;

  /* Movimiento: se mueve el juego, no el dinero. */
  --dur-toque: 90ms;
  --dur-ui: 160ms;
  --ease: cubic-bezier(.2, .7, .3, 1);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { overscroll-behavior-y: none; }
body {
  margin: 0; background: var(--carbon); color: var(--hueso);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  padding-bottom: calc(72px + var(--safe));
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { margin: 0; letter-spacing: -.03em; font-weight: 900; }
a { color: var(--llama); text-underline-offset: 3px; }
:focus-visible { outline: 2px solid var(--frio); outline-offset: 2px; }

/* Cifras siempre tabulares: sin ancho fijo, el saldo y el multiplicador saltan en cada
   actualización y se leen como un error. */
.cifra, .wallet b, .big, table, .hist span, .slots div, .crashnum b, .wheelnum {
  font-variant-numeric: tabular-nums;
}

/* ---------- barra superior ---------- */
.top {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: .7rem;
  padding: calc(.6rem + var(--safe-top)) .8rem .6rem;
  background: rgba(11, 13, 18, .9); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--borde);
}
/* La marca cede antes que el saldo. En un teléfono de 320 px con saldo de cuatro
   cifras la barra se desbordaba y arrastraba a TODA la página en horizontal: el
   saldo y el botón de depositar no se encogen, así que el que tiene que ceder es
   el nombre — el jugador ya sabe en qué app está. */
.logo { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.logo b { font-weight: 900; font-size: 1.05rem; letter-spacing: -.035em; white-space: nowrap; }
.wallet, .sonido { flex-shrink: 0; }
/* En 320 px —medio mercado venezolano— el saldo de cuatro cifras más el botón de
   depositar no dejan sitio al nombre, y la barra arrastraba a TODA la página en
   horizontal. Se queda el isotipo solo: cortar «CANDELABET» a la mitad se lee
   como un error, y el jugador ya sabe en qué app está. */
@media (max-width: 359px) { .logo b { display: none; } }
.logo span { color: var(--llama); }
.logo svg { display: block; flex-shrink: 0; }
.spacer { flex: 1; }
/* El interruptor de sonido va visible en la barra, no enterrado en ajustes: el jugador
   puede estar en un autobús y tiene que poder callarlo en un toque. */
.sonido {
  display: grid; place-items: center;
  width: var(--toque); height: var(--toque); min-height: var(--toque); padding: 0;
  border-radius: 50%; background: var(--carbon-2); border: 1px solid var(--borde);
  color: var(--humo); cursor: pointer;
}
.sonido:hover:not(:disabled) { filter: none; border-color: var(--borde-claro); color: var(--hueso); }
.sonido:not(.mudo) { color: var(--llama); }
.wallet {
  display: flex; align-items: center; gap: .5rem;
  background: var(--carbon-2); border: 1px solid var(--borde);
  border-radius: 99px; padding: .25rem .25rem .25rem .75rem;
}
.wallet b { font-size: 1rem; font-weight: 900; line-height: 1.15; display: block; }
/* Saldo de bono aparte, en ámbar: si se suma al retirable, el jugador pide un retiro que
   el sistema tiene que rechazar, y ese rechazo cuesta soporte y cuenta. */
.wallet .bono { display: block; font-size: .62rem; font-weight: 800; color: var(--aviso); }
.wallet .add {
  width: 30px; height: 30px; border-radius: 50%; border: none;
  background: var(--grad-llama); color: var(--tinta-llama); font-weight: 900; font-size: 1.05rem;
  line-height: 1; cursor: pointer;
}

/* ---------- layout ---------- */
.wrap { max-width: 760px; margin: 0 auto; padding: .75rem; }
.view { display: none; }
.view.on { display: block; animation: fade var(--dur-ui) var(--ease); }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* SALA — la superficie del dinero y de la cuenta */
.card {
  background: var(--carbon-2); border: 1px solid var(--borde);
  border-radius: var(--r-tarjeta); padding: 1rem; margin-bottom: .8rem;
}
.card h2 {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--humo); margin-bottom: .8rem; font-weight: 800;
}

/* BRASA — la superficie del juego. Un carbón plano no es la marca: lleva halo. */
.hero {
  border-radius: var(--r-tarjeta); padding: 1.1rem; margin-bottom: .8rem;
  background: var(--halo-hero); border: 1px solid var(--borde);
}
.hero h1 { font-size: 1.35rem; margin-bottom: .35rem; }
.hero p { color: var(--humo); font-size: .88rem; margin: 0; }
/* Banda de marca del lobby: compacta, para que los juegos empiecen arriba. */
/* `clip` y no `hidden`: con `hidden` el hero es un contenedor DESPLAZABLE, y como la
   llama sobresale por la derecha, enfocar un botón de dentro corría el contenido 56 px a
   la izquierda y el titular se salía de la pantalla. `clip` recorta sin poder desplazar.
   El `hidden` delante queda de respaldo para navegadores sin `clip`. */
.banda { position: relative; overflow: hidden; overflow: clip; padding: .9rem 1rem; }
.banda > * { position: relative; z-index: 1; }
.banda .hero-arte { width: 44%; max-width: 150px; }
.banda::after {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg, var(--carbon-2) 30%, rgba(18, 21, 29, .4) 55%, transparent 74%);
}
.banda p { max-width: 26ch; }

/* ---------- portada (la vista sin sesión) ---------- */
/* Es la primera impresión de quien llega sin cuenta. Vive en la misma página que la app:
   un origen, un sistema visual, sin segundo despliegue que mantener sincronizado. */
/* La portada es un cartel: la llama grande, recortada contra el borde, con su brasa
   detrás. Sin ella el hero es texto sobre negro, que es justo lo que hace que la marca
   parezca chica al lado de un competidor lleno de fotos. */
.portada { position: relative; overflow: hidden; overflow: clip; padding: 1.7rem 1.2rem; }
.portada > * { position: relative; z-index: 1; }
.hero-arte {
  position: absolute; z-index: 0;
  right: -16%; top: 50%; transform: translateY(-50%);
  width: 56%; max-width: 240px; aspect-ratio: 1;
}
.hero-arte.tenue { opacity: .45; }
/* Velo desde la izquierda: el titular se lee entero aunque la llama quede debajo. */
.portada::after {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(100deg, var(--carbon-2) 24%, rgba(18, 21, 29, .38) 46%, transparent 66%);
}
.portada h1 { font-size: 2.05rem; line-height: 1.05; margin-bottom: .5rem; max-width: 11ch; }
.portada p { font-size: .95rem; max-width: 25ch; }
.portada-principal {
  min-height: 360px; display: flex; flex-direction: column; justify-content: center;
  background-color: var(--carbon-2);
  background-image: url('/hero-candela-v2.jpg');
  background-size: cover; background-position: 62% center;
  box-shadow: inset 0 0 60px rgba(0,0,0,.18), var(--sombra);
  animation: hero-revela 600ms var(--ease) both;
}
.portada-principal::after {
  background: linear-gradient(90deg, rgba(11,13,18,.99) 0%, rgba(11,13,18,.93) 36%, rgba(11,13,18,.38) 68%, rgba(11,13,18,.08) 100%);
}
.hero-kicker {
  color: var(--llama-alta); font-size: .63rem; font-weight: 900;
  letter-spacing: .17em; margin-bottom: .55rem;
}
.portada-principal h1 { font-family: var(--display); letter-spacing: -.045em; text-wrap: balance; }
@keyframes hero-revela { from { opacity: .35; transform: scale(.992); } to { opacity: 1; transform: none; } }
.cierre h1, .cierre p { max-width: none; }
.fila-cta { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: 1.1rem; }
.fila-cta button { flex: 1 1 auto; min-width: 140px; }
.cierre { margin-top: 1.2rem; text-align: center; }
.cierre .fila-cta { justify-content: center; }
.cierre .hint { margin-top: .9rem; }

.bloque h2 { color: var(--llama); }
/* Barra de conversión del visitante sin sesión. Los dos competidores locales la tienen
   fija abajo, y es donde entra el registro. */
.cta-fija {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; gap: .5rem; padding: .6rem .8rem calc(.6rem + var(--safe));
  background: rgba(11, 13, 18, .94); backdrop-filter: blur(14px);
  border-top: 1px solid var(--borde);
}
.cta-fija button { flex: 1; }
body.con-cta { padding-bottom: calc(84px + var(--safe)); }
.cta-fija.hero-visible #btnRegister3 { display: none; }

.auth-panel { box-shadow: 0 18px 60px rgba(0,0,0,.38); border-color: var(--borde-claro); }
.auth-cabecera { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.auth-cabecera h2 { color: var(--hueso); font-size: 1.2rem; text-transform: none; letter-spacing: -.02em; margin: .15rem 0 .8rem; }
.cerrar-panel { min-width: var(--toque); padding: 0; background: transparent; color: var(--humo); border: 1px solid var(--borde); font-size: 1.35rem; }
.auth-intro { color: var(--humo); margin: -.2rem 0 1rem; font-size: .86rem; }
.auth-campos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .65rem; }
.auth-campos > div:only-child { grid-column: 1 / -1; }
.input-clave { position: relative; }
.input-clave input { padding-right: 3.3rem; }
.input-clave button { position: absolute; right: 5px; top: 5px; min-height: 34px; padding: .25rem .55rem; background: transparent; color: var(--humo); border: 0; font-size: .72rem; }
.clave-fuerza { position: relative; display: flex; align-items: center; gap: .55rem; color: var(--humo); font-size: .72rem; margin-top: .6rem; }
.clave-fuerza::before { content: ''; flex: 1; height: 4px; border-radius: 99px; background: var(--borde); }
.clave-fuerza i { position: absolute; width: var(--fuerza, 0%); max-width: 46%; height: 4px; border-radius: 99px; background: var(--fuerza-color, var(--cae)); pointer-events: none; }
.acepto { display: flex; align-items: flex-start; gap: .55rem; margin: .85rem 0; color: var(--humo); text-transform: none; letter-spacing: 0; font-size: .78rem; font-weight: 600; }
.acepto input { width: 18px; min-height: 18px; margin-top: 1px; accent-color: var(--llama); }
.auth-principal { width: 100%; }
.auth-links { display: flex; justify-content: space-between; align-items: center; gap: .7rem; flex-wrap: wrap; margin-top: .75rem; }
.auth-enviado { text-align: center; padding: .7rem .3rem .3rem; }
.correo-icono { display: grid; place-items: center; width: 48px; height: 48px; margin: 0 auto .8rem; border-radius: 50%; color: var(--carbon); background: var(--sube); font-size: 1.2rem; font-weight: 900; box-shadow: 0 0 0 8px var(--sube-tenue); }
.auth-enviado h3 { margin: 0; font-family: var(--display); font-size: 1.35rem; }
.auth-enviado p { color: var(--humo); font-size: .86rem; max-width: 38ch; margin: .45rem auto 1rem; }
.auth-enviado .ghost { width: 100%; margin-bottom: .8rem; }
.auth-enviado .auth-principal { width: 100%; margin-bottom: .8rem; }
@media (max-width: 520px) { .auth-campos { grid-template-columns: 1fr; } }

.seccion-titulo { display: flex; align-items: end; justify-content: space-between; gap: 1rem; margin: 1.15rem 0 .65rem; }
.seccion-titulo > div { display: flex; align-items: center; gap: .45rem; }
.seccion-titulo .micro { color: var(--hueso); }
.seccion-nota { color: var(--humo); font-size: .72rem; text-align: right; }
.pulso { width: 7px; height: 7px; border-radius: 50%; background: var(--sube); box-shadow: 0 0 0 5px var(--sube-tenue); animation: pulso-vivo 1.8s ease-out infinite; }
@keyframes pulso-vivo { 0%, 45%, 100% { box-shadow: 0 0 0 4px var(--sube-tenue); } 20% { box-shadow: 0 0 0 9px transparent; } }
.pruebas-titulo { margin-top: 1.35rem; }
.pruebas-titulo .micro { color: var(--frio); }
.micro.frio { color: var(--frio); }

.games.games-live { grid-template-columns: repeat(2, 1fr); }
.games-live .game { min-height: 194px; }
.games-live .game .nm { font-size: 1.2rem; }
.games-live .game .arte { width: 88%; right: -7%; }

.pagos-portada { padding: 1.15rem; margin-top: 1.2rem; }
.pagos-portada .seccion-titulo { margin: 0 0 1rem; }
.pagos-portada .seccion-titulo > div { display: block; }
.pagos-portada h2 { color: var(--hueso); text-transform: none; letter-spacing: -.02em; font-size: 1.35rem; margin: .15rem 0 0; }
.ruta-pago { display: grid; grid-template-columns: repeat(3, 1fr); gap: .55rem; }
.paso-pago { position: relative; padding: .85rem; border-radius: var(--r); background: var(--carbon); border: 1px solid var(--borde); }
.paso-pago > span { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--brasa); color: var(--llama-alta); font-weight: 900; font-size: .78rem; margin-bottom: .65rem; }
.paso-pago b { font-size: .88rem; }
.paso-pago p { color: var(--humo); font-size: .76rem; line-height: 1.4; margin: .25rem 0 0; }
.legal-portada { color: var(--ceniza); font-size: .72rem; text-align: center; margin: 1rem 0 0; }

/* Centro de confianza: no se esconde en términos ni usa el naranja de conversión. El
   azul identifica comprobación; el ámbar, una dependencia que todavía no está lista. */
.confianza-portada { padding: 1.15rem; border-color: rgba(74, 168, 255, .28); }
.confianza-cabecera { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; margin-bottom: .9rem; }
.confianza-cabecera h2 { color: var(--hueso); text-transform: none; letter-spacing: -.025em; font-size: 1.35rem; margin: .15rem 0 0; }
.sello-demo {
  flex: 0 0 auto; padding: .3rem .55rem; border-radius: 99px;
  color: var(--frio); background: var(--frio-tenue); border: 1px solid rgba(74, 168, 255, .3);
  font-size: .58rem; font-weight: 900; letter-spacing: .08em;
}
.confianza-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .55rem; }
.confianza-grid article { padding: .8rem; background: var(--carbon); border: 1px solid var(--borde); border-radius: var(--r); }
.confianza-grid b { display: block; font-size: .84rem; margin-top: .55rem; }
.confianza-grid p { color: var(--humo); font-size: .74rem; line-height: 1.4; margin: .25rem 0 0; }
.estado { display: inline-block; padding: .18rem .4rem; border-radius: 99px; font-size: .55rem; font-weight: 900; letter-spacing: .08em; }
.estado.listo { color: var(--frio); background: var(--frio-tenue); }
.estado.pendiente { color: var(--aviso); background: var(--aviso-tenue); }
.instalar-fila { display: flex; align-items: center; justify-content: space-between; gap: .8rem; margin-top: .75rem; padding: .75rem .8rem; border-radius: var(--r); background: var(--frio-tenue); }
.instalar-fila b { font-size: .84rem; }
.instalar-fila p { color: var(--humo); font-size: .72rem; margin: .1rem 0 0; }
.instalar-fila button { flex: 0 0 auto; border-color: rgba(74, 168, 255, .35); color: var(--frio); }

.todos-titulo { margin-top: .35rem; }
.recientes { margin-bottom: .2rem; }
.games-recientes .game { min-height: 132px; }

@media (max-width: 520px) {
  .portada-principal { min-height: 370px; background-position: 66% center; }
  .portada-principal::after { background: linear-gradient(90deg, rgba(11,13,18,.98) 0%, rgba(11,13,18,.88) 52%, rgba(11,13,18,.22) 100%); }
  .seccion-nota { max-width: 18ch; }
  .ruta-pago { grid-template-columns: 1fr; }
  .paso-pago { display: flex; gap: .75rem; }
  .paso-pago > span { flex: 0 0 26px; margin: 0; }
  .games-live .game { min-height: 168px; }
  .confianza-cabecera { display: block; }
  .sello-demo { display: inline-block; margin-top: .65rem; }
  .confianza-grid { grid-template-columns: 1fr; }
  .confianza-grid article { display: grid; grid-template-columns: auto 1fr; column-gap: .65rem; align-items: start; }
  .confianza-grid article .estado { grid-row: 1 / span 2; margin-top: .1rem; }
  .confianza-grid article b { margin-top: 0; }
  .confianza-grid article p { grid-column: 2; }
}

/* Un enlace que en realidad es un botón: no puede parecer un botón. */
button.enlace {
  background: none; border: none; padding: 0; min-height: 0;
  color: var(--llama); font: inherit; font-size: .78rem; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
button.enlace:hover { filter: none; }

/* Aviso de red y empujón al primer depósito ------------------------------------- */
.sinred {
  position: sticky; top: var(--alto-barra); z-index: 29;
  margin: 0; padding: .55rem .9rem;
  /* Opaco por la misma razón que la barra de prueba: pegado arriba, lo de abajo se leía
     a través del aviso. */
  background: linear-gradient(var(--aviso-tenue), var(--aviso-tenue)), var(--carbon);
  color: var(--aviso);
  border-bottom: 1px solid rgba(255, 187, 56, .3);
  font-size: .8rem; font-weight: 700; text-align: center;
}
.primer-deposito { border-color: var(--llama); background: var(--halo-hero); }
.primer-deposito h2 { color: var(--llama); }

/* ---------- modo prueba ---------- */
/* En este sistema el fuego es el dinero. La prueba va en el azul frío de la verificación
   justamente porque aquí no hay dinero: el jugador tiene que poder ver de un vistazo, en
   cualquier pantalla, que lo que está moviendo no es suyo. */
.demo-barra {
  /* Un peldaño por debajo del aviso de red: si no hay conexión, eso manda. */
  position: sticky; top: var(--alto-barra); z-index: 28;
  display: flex; align-items: center; gap: .45rem; flex-wrap: wrap;
  padding: .5rem .8rem;
  /* El tinte azul sobre carbón OPACO: translúcido, el contenido de la página se leía
     por debajo del texto de la barra al desplazar. */
  background: linear-gradient(var(--frio-tenue), var(--frio-tenue)), var(--carbon);
  border-bottom: 1px solid rgba(74, 168, 255, .3);
  font-size: .78rem;
}
.demo-barra .etq {
  font-size: .6rem; font-weight: 900; letter-spacing: .1em;
  color: var(--carbon); background: var(--frio);
  padding: .18rem .38rem; border-radius: var(--r-chico);
}
.demo-barra .txt { color: var(--frio); font-weight: 700; margin-right: auto; }
.demo-barra button { min-height: var(--toque); padding: .25rem .7rem; font-size: .74rem; }
.demo-barra button:not(.ghost) { background: var(--frio); color: var(--carbon); border-color: var(--frio); }
/* El saldo de prueba lleva su etiqueta pegada al número, no en otra esquina: una captura
   del saldo tiene que llevarla dentro. */
.wallet .prueba { display: block; font-size: .62rem; font-weight: 800; color: var(--frio); }
.modo-demo .wallet { border-color: rgba(74, 168, 255, .45); }
.modo-demo .wallet .add { display: none; }   /* no hay cajero que abrir sin cuenta */

/* ---------- rejilla de juegos ---------- */
/* Cada juego trae su color y su escena dibujada a medida (ver ARTE en app.js). La escena
   se recorta contra la esquina: da profundidad sin quitarle sitio al nombre. */
.games { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; }
@media (min-width: 620px) { .games { grid-template-columns: repeat(3, 1fr); } }
.game {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; flex-direction: column; justify-content: flex-end;
  border: 1px solid var(--borde); border-radius: var(--r-tarjeta);
  /* El tablero es la superficie por donde cae la bola: hundido, como las demás mesas. */
  box-shadow: var(--hundido);
  padding: .8rem; min-height: 158px; text-align: left; cursor: pointer;
  background:
    radial-gradient(120% 95% at 100% 0%, color-mix(in srgb, var(--acento) 26%, transparent), transparent 62%),
    linear-gradient(165deg, var(--carbon-3), var(--carbon-2));
  color: var(--hueso); font: inherit;
  transition: transform var(--dur-toque) var(--ease), border-color var(--dur-toque) var(--ease);
}
.game.destacado { border-color: var(--acento); }
.game:hover { border-color: var(--acento); transform: translateY(-2px); }
.game:active { transform: scale(.97); }

.game .arte {
  position: absolute; z-index: -1;
  right: -10%; top: -4%; width: 80%; height: auto; aspect-ratio: 1;
  opacity: .95; pointer-events: none;
  transition: transform 420ms var(--ease), opacity var(--dur-ui) var(--ease);
}
/* Velo bajo el texto: el nombre se lee sobre cualquier escena, sin apagar el color. */
.game .txt {
  position: relative; display: block;
  padding-top: 2.2rem;
  background: linear-gradient(to top, var(--carbon-2) 42%, transparent);
  margin: -.8rem; padding: 2.2rem .8rem .1rem;
}
.game .nm { display: block; font-family: var(--display); font-weight: 900; font-size: 1.02rem; letter-spacing: -.035em; }
.game:hover .arte { transform: translate3d(-3px, 3px, 0) scale(1.035); }
.game .ed { display: block; font-size: .72rem; color: var(--humo); line-height: 1.3; margin-top: .1rem; }
.game .etiquetas { position: absolute; top: .55rem; left: .55rem; }
.game .live {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .6rem; font-weight: 800; letter-spacing: .06em;
  color: var(--carbon); background: var(--sube); padding: .22rem .5rem; border-radius: 99px;
}
.game .live::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--carbon); opacity: .7; }
/* Sólo en la portada, y sólo en lo que SÍ se puede tocar sin cuenta. Las dos rondas en
   vivo ya llevan su etiqueta —EN VIVO, la cuenta atrás—: añadirles una segunda que diga
   lo que les falta llena la esquina de la tarjeta de letra pequeña. */
.game .prueba {
  display: inline-block;
  font-size: .58rem; font-weight: 900; letter-spacing: .07em;
  padding: .22rem .45rem; border-radius: 99px;
  color: var(--carbon); background: var(--frio);
}

/* La portada usa las mismas tarjetas: lo que ves antes de registrarte es lo que hay. */
.bloque-juegos { margin-bottom: .8rem; }

/* ---------- controles ---------- */
label { display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; color: var(--humo); margin-bottom: .35rem; font-weight: 800; }
input, select {
  width: 100%; min-height: var(--toque); padding: .65rem .75rem; font: inherit; font-weight: 600;
  background: var(--carbon); color: var(--hueso);
  border: 1px solid var(--borde); border-radius: var(--r);
}
input:focus, select:focus { outline: 2px solid var(--frio); outline-offset: -1px; }
button {
  font: inherit; font-weight: 800; border: none; border-radius: var(--r);
  min-height: var(--toque); padding: .7rem 1rem; cursor: pointer;
  background: var(--grad-llama); color: var(--tinta-llama);
  transition: filter var(--dur-toque) var(--ease), transform var(--dur-toque) var(--ease);
  touch-action: manipulation;
}
button:hover:not(:disabled) { filter: brightness(1.07); }
button:active:not(:disabled) { transform: scale(.98); }
button:disabled { opacity: .4; cursor: not-allowed; }
button.ghost { background: var(--carbon-3); color: var(--hueso); border: 1px solid var(--borde); font-weight: 700; }
button.ghost:hover:not(:disabled) { border-color: var(--borde-claro); filter: none; }
/* Cobrar es la acción que le da dinero al jugador: el único verde grande del sistema. */
button.cobrar { background: var(--sube); color: #04170d; font-weight: 900; }
button.mini {
  position: relative; min-height: 34px; padding: .4rem .6rem; font-size: .8rem;
  border-radius: var(--r-chico);
}
/* Estos botones se dibujan pequeños a propósito, pero el pulgar no acierta en
   32-36px. La zona sensible se extiende a `--toque` sin mover un pixel de lo que
   se ve: encoger el dibujo es una decisión de diseño; encoger la zona donde el
   dedo acierta, no. */
button.mini::after, button.copiar::after,
.input-clave button::after, .cta-fija button::after {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%); height: var(--toque);
}
.row { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: .55rem; align-items: end; }
.chips { display: flex; gap: .4rem; flex-wrap: wrap; }
/* Los chips son FICHAS, y una ficha se coge. Es la pieza que más veces se toca en todo
   el producto —la barra de apuesta está en los once juegos—, así que es donde más rinde
   que se sienta física: relieve en reposo, sombra invertida al pulsar. */
.chip {
  min-height: var(--toque); min-width: var(--toque); padding: .4rem .7rem;
  border-radius: 99px; border: 1px solid var(--borde);
  background: var(--cara), var(--carbon-3); color: var(--hueso);
  font-size: .82rem; font-weight: 800; cursor: pointer;
  box-shadow: var(--relieve);
  transition: transform var(--dur-toque) var(--ease), box-shadow var(--dur-toque) var(--ease);
}
.chip:active:not(:disabled) { transform: translateY(2px); box-shadow: var(--hundido); }
.chip.on {
  background: var(--grad-llama); color: var(--tinta-llama); border-color: var(--llama-alta);
  box-shadow: var(--relieve-alto);
}

/* Etiqueta de sección del sistema. */
.micro {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .12em;
  font-weight: 800; color: var(--humo);
}

/* ---------- barra de apuesta ---------- */
/* El control más usado de la app. Vive al pie de la pantalla de juego, se maneja con un
   pulgar y enseña el pago potencial ANTES de apostar. */
.apuesta {
  margin-top: .9rem; padding: .85rem;
  background: var(--carbon); border: 1px solid var(--borde); border-radius: var(--r-tarjeta);
  display: flex; flex-direction: column; gap: .7rem;
}
.apuesta-cifras { display: flex; align-items: flex-end; justify-content: space-between; gap: .7rem; }
.apuesta-cifras .der { text-align: right; }
.apuesta-cifras .micro { display: block; margin-bottom: .3rem; }
/* Apuesta por encima del saldo. No es un error del jugador —está ajustando— así que
   no se pinta como fallo: `--aviso` es el color de «esto pide atención», y el pago
   deja de leerse como cifra firme porque no puede ocurrir con ese saldo. */
.fondo-corto {
  margin: -.2rem 0 0; font-size: var(--fs-pie, .78rem); line-height: 1.45; color: var(--aviso);
}
.apuesta .cifra.sin-fondo { color: var(--humo); }
/* El acumulado late al crecer. Un solo pulso en 550 ms (1,8 Hz), dentro del techo de
   3 Hz. `inline-block` porque un `<b>` en línea no acepta `transform`. */
.cifra.sube-pago { display: inline-block; animation: subePago .55s var(--ease); }
@keyframes subePago {
  38% { color: var(--sube); transform: scale(1.1); }
}
.monto {
  display: flex; align-items: baseline; gap: 2px;
  font-size: var(--fs-cifra-m, 1.6rem); font-weight: 900; letter-spacing: -.04em;
}
.monto input {
  width: 5.2ch; min-height: 0; padding: 0; border: none; background: none;
  font: inherit; color: var(--hueso); font-variant-numeric: tabular-nums;
  border-bottom: 2px dashed var(--borde-claro); border-radius: 0;
}
/* El anillo se quita SÓLO cuando el foco no vino del teclado: aquí el subrayado
   naranja ya dice dónde estás con el dedo, pero quien navega con tabulador se
   quedaba sin ninguna marca, porque esta regla le ganaba en especificidad a la
   de `:focus-visible` de arriba. */
.monto input:focus:not(:focus-visible) { outline: none; }
.monto input:focus { border-bottom-color: var(--llama); }
.apuesta .chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.apuesta .chips::-webkit-scrollbar { display: none; }
.apuesta .chips .sep { flex: 0 0 1px; background: var(--borde); margin: .2rem 2px; }
.apuesta .chip { flex: 0 0 auto; }
/* El botón que cierra la jugada. Es el elemento más pulsado del producto y era lo único
   plano que quedaba de la barra: ahora se hunde como las fichas, con el mismo gesto.
   El canto claro va arriba, sobre el naranja, así que la sombra interior se calcula en
   blanco y no en negro — sobre un fondo encendido, una sombra negra arriba lo ensucia. */
button.grande {
  min-height: 56px; font-size: 1.05rem; font-weight: 900; width: 100%;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), inset 0 -3px 0 rgba(0, 0, 0, .22), 0 4px 12px rgba(0, 0, 0, .38);
  transition: transform var(--dur-toque) var(--ease), box-shadow var(--dur-toque) var(--ease);
}
button.grande:active:not(:disabled) {
  transform: translateY(2px);
  box-shadow: inset 0 3px 8px rgba(0, 0, 0, .32), 0 1px 2px rgba(0, 0, 0, .3);
}
button.grande.jugando {
  position: relative; opacity: 1; color: transparent; overflow: hidden;
  background-size: 180% 100%; animation: botonVivo .75s linear infinite;
}
button.grande.jugando::after {
  content: ''; position: absolute; left: 50%; top: 50%; width: 20px; height: 20px;
  margin: -10px; border: 3px solid rgba(42,13,0,.28); border-top-color: var(--tinta-llama);
  border-radius: 50%; animation: giraCarga .55s linear infinite;
}
@keyframes botonVivo { 50% { filter: brightness(1.16); } }
@keyframes giraCarga { to { transform: rotate(360deg); } }
button.grande.parando { background: var(--carbon-3); color: var(--cae); border: 1px solid rgba(255,77,87,.4); }

/* Manual / Auto: dos modos del mismo control, no dos pantallas. */
/* Lo que se decide una vez, antes de la barra: no viaja pegado al borde de abajo. */
.apuesta-previa { display: grid; gap: .6rem; margin-top: .9rem; }
.apuesta-previa:empty { display: none; }
.modos { display: flex; gap: .3rem; background: var(--carbon-2); border-radius: var(--r); padding: .2rem; }
.modo {
  flex: 1; min-height: var(--toque); padding: .35rem; border: none; border-radius: var(--r-chico);
  background: none; color: var(--humo); font: 800 .8rem var(--font, inherit); cursor: pointer;
}
.modo.on { background: var(--carbon-3); color: var(--hueso); }
.modo:hover:not(.on) { filter: none; color: var(--hueso); }

.auto-panel { border-top: 1px solid var(--borde); padding-top: .7rem; }
.auto-campos { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.auto-campos label {
  display: block; font-size: .62rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--humo); font-weight: 800; margin: 0;
}
.auto-campos input, .auto-campos select {
  margin-top: .25rem; min-height: var(--toque); padding: .4rem .5rem; font-size: .85rem; font-weight: 600;
}
#autoEstado { color: var(--llama); font-variant-numeric: tabular-nums; }
.apuesta-pie {
  display: flex; justify-content: space-between; gap: .5rem;
  font-size: var(--fs-pie, .78rem); color: var(--humo);
}
.apuesta-pie b { color: var(--hueso); font-variant-numeric: tabular-nums; }

/* ---------- el momento del resultado ---------- */
/* La jugada es lo único que el jugador vino a ver: se muestra con el peso de una cifra,
   no como una línea de texto. La luz queda contenida en la mesa y la derrota no se
   celebra ni se dramatiza. */
.resultado {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin-top: .7rem; padding: .8rem .9rem; border-radius: var(--r);
  animation: entra var(--dur-juego, 420ms) var(--ease);
}
.resultado b { font-size: 1.9rem; font-weight: 900; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.resultado span { font-size: var(--fs-menor, .84rem); color: var(--humo); }
.resultado.gana { background: var(--sube-tenue); }
.resultado.gana b { color: var(--sube); }
.resultado.pierde { background: var(--carbon-3); }
.resultado.pierde b { color: var(--ceniza); }
.resultado .compartir { margin-left: auto; }
@keyframes entra { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: none; } }

/* ---------- escenario vivo común ---------- */
body.juego-abierto .cta-fija { display: none; }
#gameHost { position: relative; isolation: isolate; }
#gameHost > .juego-card {
  position: relative; overflow: hidden; overflow: clip;
  border-color: color-mix(in srgb, var(--acento, var(--llama)) 30%, var(--borde));
  box-shadow: 0 16px 44px rgba(0,0,0,.46), inset 0 1px 0 rgba(255,255,255,.03);
}
#gameHost > .juego-card::before {
  content: ''; position: absolute; z-index: 0; pointer-events: none;
  left: -15%; right: -15%; top: -70px; height: 180px;
  background:
    radial-gradient(circle at 24% 45%, color-mix(in srgb, var(--acento, var(--llama)) 32%, transparent) 0 2px, transparent 4px),
    radial-gradient(circle at 50% 35%, color-mix(in srgb, var(--acento, var(--llama)) 42%, transparent) 0 2px, transparent 4px),
    radial-gradient(circle at 76% 45%, color-mix(in srgb, var(--acento, var(--llama)) 32%, transparent) 0 2px, transparent 4px),
    radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--acento, var(--llama)) 16%, transparent), transparent 68%);
  filter: blur(.2px); opacity: .72; animation: lucesMesa 2.8s ease-in-out infinite;
}
#gameHost > .juego-card > * { position: relative; z-index: 1; }
#gameHost > .juego-card h2::before {
  content: ''; display: inline-block; width: 6px; height: 6px; margin-right: .45rem;
  border-radius: 50%; background: var(--acento, var(--llama));
  box-shadow: 0 0 10px var(--acento, var(--llama)); vertical-align: 1px;
}
@keyframes lucesMesa { 0%,100% { opacity: .48; transform: translateY(0); } 50% { opacity: .95; transform: translateY(4px); } }
#gameHost.ronda-gana > .juego-card { animation: mesaGana .85s var(--ease); }
#gameHost.ronda-pierde > .juego-card { animation: mesaPierde .48s var(--ease); }
@keyframes mesaGana {
  0%,100% { box-shadow: 0 16px 44px rgba(0,0,0,.46); }
  38% { border-color: var(--oro); box-shadow: 0 0 0 1px var(--oro), 0 0 34px rgba(255,200,87,.34), inset 0 0 34px rgba(47,208,122,.08); }
}
@keyframes mesaPierde { 38% { border-color: color-mix(in srgb, var(--cae) 48%, var(--borde)); transform: translateX(1px); } }
/* El premio grande enciende más y durante más rato. DOS pulsos en 1,1 s son 1,8 Hz,
   muy por debajo de los 3 Hz a partir de los cuales un destello puede provocar una
   crisis fotosensible; ese techo manda sobre lo vistoso. La derrota no tiene versión
   grande a propósito: se cuenta, no se subraya. */
#gameHost.ronda-gana.gana-grande > .juego-card { animation: mesaGanaGrande 1.15s var(--ease); }
@keyframes mesaGanaGrande {
  0%, 100% { box-shadow: 0 16px 44px rgba(0, 0, 0, .46); }
  26% {
    border-color: var(--oro);
    box-shadow: 0 0 0 2px var(--oro), 0 0 62px rgba(255, 200, 87, .5), inset 0 0 52px rgba(255, 200, 87, .13);
  }
  62% {
    border-color: var(--oro);
    box-shadow: 0 0 0 1px var(--oro), 0 0 38px rgba(255, 200, 87, .3), inset 0 0 30px rgba(255, 200, 87, .07);
  }
}
.chispa {
  position: absolute; z-index: 8; left: 50%; top: 46%; width: 5px; height: 5px;
  pointer-events: none; border-radius: 50%; background: var(--oro);
  box-shadow: 0 0 9px var(--oro); animation: saltaChispa .72s var(--ease) var(--d) both;
}
@keyframes saltaChispa {
  0% { opacity: 0; transform: translate(-50%,-50%) scale(.3); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(1.15); }
}

/* ---------- mesas de juego ---------- */
.mesa {
  /* El halo toma el color del juego abierto: entrar a Plinko se siente distinto a entrar
     a Ruleta sin cambiar una sola pieza de la interfaz. */
  background:
    radial-gradient(90% 70% at 50% 115%, color-mix(in srgb, var(--acento, #ff6a1f) 22%, transparent), transparent 70%),
    var(--halo-juego);
  border: 1px solid var(--borde);
  border-radius: var(--r-tarjeta); padding: 1rem .9rem;
}
.mesa-cifra { display: grid; place-items: center; gap: .3rem; min-height: 130px; }
.mesa-cifra .cifra.grande { font-size: var(--fs-cifra-xl, 3.4rem); font-weight: 900; letter-spacing: -.04em; }
.mesa-cifra .cifra.sube { color: var(--sube); } .mesa-cifra .cifra.cae { color: var(--cae); }
.mesa-cifra .sub { font-size: var(--fs-pie, .78rem); color: var(--humo); }

/* Dados: la pista ES la probabilidad. El jugador ve el precio de subir el multiplicador
   sin tener que entender el porcentaje. */
.pista {
  position: relative; height: 46px; border-radius: 99px;
  background: var(--carbon-3); border: 1px solid var(--borde); overflow: hidden;
  /* Un canal por donde rueda la bola, no una barra de progreso: la superficie de juego
     va HUNDIDA en la mesa y la bola se posa encima. */
  box-shadow: var(--hundido);
}
.pista .zona { position: absolute; top: 0; bottom: 0; background: rgba(47, 208, 122, .22); box-shadow: inset 0 0 0 1px rgba(47, 208, 122, .5); transition: left var(--dur-ui) var(--ease), width var(--dur-ui) var(--ease); }
/* El tramo que el juego NO ofrece: ahí el pago no llegaría a lo apostado. Se
   dibuja en vez de dejar que el control tope en seco — un límite invisible se
   siente como un fallo, y uno dibujado se entiende de un vistazo. */
.pista .veto {
  position: absolute; top: 0; bottom: 0; background: var(--carbon);
  background-image: repeating-linear-gradient(-45deg,
    transparent 0 5px, rgba(255, 255, 255, .07) 5px 10px);
  box-shadow: inset 0 0 0 1px var(--borde);
  transition: left var(--dur-ui) var(--ease), width var(--dur-ui) var(--ease);
}
.pista .marca { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--hueso); transform: translateX(-1px); }
/* La bola RUEDA por el canal: va posada encima, con su sombra, no impresa en el fondo. */
.pista .bola {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  min-width: 54px; padding: .3rem .5rem; text-align: center;
  background: var(--cara), var(--carbon-2); border: 1px solid var(--borde-claro); border-radius: 99px;
  font-size: .82rem; font-weight: 900; font-variant-numeric: tabular-nums;
  box-shadow: var(--relieve-alto);
  transition: left var(--dur-juego, 420ms) var(--ease), border-color var(--dur-toque) var(--ease);
}
.pista .bola.gana { border-color: var(--sube); color: var(--sube); }
.pista .bola.pierde { border-color: var(--cae); color: var(--cae); }
.pista.resuelve { animation: pistaPulso .62s var(--ease); }
.pista.resuelve .bola { box-shadow: var(--relieve-alto), 0 0 18px color-mix(in srgb, currentColor 55%, transparent); }
@keyframes pistaPulso { 35% { border-color: var(--acento, var(--llama)); transform: scale(1.012); } }
.pista-etq { display: flex; justify-content: space-between; margin-top: .4rem; font-size: var(--fs-micro, .68rem); color: var(--ceniza); font-variant-numeric: tabular-nums; }

/* ---------- mensajes ---------- */
.msg { padding: .65rem .8rem; border-radius: var(--r); font-size: .85rem; margin-top: .7rem; }
.msg.err { background: var(--cae-tenue); color: #ffb9bd; }
.msg.ok { background: var(--sube-tenue); color: #9df0c4; }
.hint { font-size: .78rem; color: var(--humo); margin: .5rem 0 0; }
.big { font-size: 1.7rem; font-weight: 900; letter-spacing: -.04em; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .74rem; color: var(--frio); word-break: break-all; }

/* ---------- perfil y nivel ---------- */
/* El nivel es el gancho de retención: se ve al entrar a Cuenta, con la barra de lo que
   falta. Las cifras salen de las rondas jugadas, no de un contador aparte. */
.perfil-alto { display: flex; align-items: center; justify-content: space-between; gap: .7rem; }
.rango {
  font-size: 1.1rem; font-weight: 900; letter-spacing: -.02em;
  padding: .25rem .7rem; border-radius: 99px;
  background: var(--carbon-3); border: 1px solid var(--borde);
}
.rango[data-nivel="bronce"]  { color: #c98a4b; border-color: rgba(201,138,75,.5); }
.rango[data-nivel="plata"]   { color: #cbd5e1; border-color: rgba(203,213,225,.5); }
.rango[data-nivel="oro"]     { color: var(--oro); border-color: rgba(255,200,87,.5); }
.rango[data-nivel="platino"] { color: #a5f3fc; border-color: rgba(165,243,252,.5); }
.rango[data-nivel="candela"] { color: var(--tinta-llama); background: var(--grad-llama); border-color: transparent; }
.perfil-sig { font-size: .74rem; color: var(--humo); text-align: right; }
.barra-nivel { height: 8px; border-radius: 99px; background: var(--carbon); overflow: hidden; margin: .7rem 0 .9rem; }
.barra-nivel i { display: block; height: 100%; background: var(--grad-llama); transition: width var(--dur-juego, 420ms) var(--ease); }
.perfil-cifras { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.perfil-cifras div { background: var(--carbon); border-radius: var(--r); padding: .55rem .7rem; }
.perfil-cifras small { display: block; font-size: .6rem; text-transform: uppercase; letter-spacing: .1em; color: var(--humo); font-weight: 800; }
.perfil-cifras b { font-size: 1.05rem; font-weight: 900; font-variant-numeric: tabular-nums; }

/* Verificación progresiva: aparece como trámite corto, no como muro de registro. */
.kyc-cabecera { display: flex; align-items: flex-start; justify-content: space-between; gap: .7rem; }
.kyc-cabecera h2 { margin-bottom: .55rem; }
.kyc-estado {
  flex-shrink: 0; padding: .18rem .5rem; border: 1px solid var(--borde-claro);
  border-radius: 99px; color: var(--aviso); font-size: .65rem; font-weight: 900;
  text-transform: uppercase; letter-spacing: .06em;
}
.kyc-estado.verificado { color: var(--sube); border-color: color-mix(in srgb, var(--sube) 45%, var(--borde)); }
.kyc-pasos { display: grid; grid-template-columns: repeat(3, 1fr); gap: .35rem; margin: .25rem 0 .7rem; }
.kyc-paso { border-top: 2px solid var(--borde); padding-top: .35rem; color: var(--ceniza); font-size: .68rem; }
.kyc-paso b { display: block; color: inherit; font-size: .72rem; }
.kyc-paso.hecho { border-color: var(--sube); color: var(--hueso); }
.kyc-paso.actual { border-color: var(--aviso); color: var(--hueso); }
.kyc-card form { margin-top: .8rem; }
.kyc-card .row { align-items: end; }
.kyc-card .kyc-ancho { flex: 2 1 180px; }
.kyc-resumen { padding: .7rem; border-radius: var(--r); background: var(--carbon); }
.kyc-resumen b { display: block; margin-bottom: .2rem; }

/* ---------- estado de un retiro ---------- */
/* El punto donde la competencia pierde jugadores: piden su plata y no vuelven a saber
   nada. Aquí el retiro es algo que se puede mirar. */
.pasos { display: flex; align-items: flex-start; margin: .2rem 0 .6rem; }
.paso { flex: 1; text-align: center; position: relative; }
.paso i {
  display: grid; place-items: center; margin: 0 auto .35rem;
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--borde); background: transparent;
  font-style: normal; font-size: .7rem; font-weight: 900; color: var(--carbon);
}
.paso.hecho i { background: var(--sube); border-color: var(--sube); }
.paso.malo i { border-color: var(--cae); color: var(--cae); }
.paso b { display: block; font-size: .62rem; text-transform: uppercase; letter-spacing: .1em; color: var(--ceniza); }
.paso.hecho b, .paso.actual b { color: var(--hueso); }
.paso small { display: block; font-size: .62rem; color: var(--humo); }
.paso::after {
  content: ''; position: absolute; top: 10px; left: 60%; right: -40%; height: 2px; background: var(--borde);
}
.paso.unido::after { background: var(--sube); }
.paso:last-child::after { display: none; }

/* Requisitos de retiro: cumplido en verde, pendiente en ámbar. Ámbar y no rojo — el rojo
   es el color de perder una ronda, no el de un trámite que falta. */
.req { display: flex; align-items: flex-start; gap: .45rem; margin-bottom: .25rem; }
.req::before { content: ''; flex: 0 0 7px; height: 7px; margin-top: .42rem; border-radius: 50%; }
.req.ok::before { background: var(--sube); }
.req.falta::before { background: var(--aviso); }
.req.falta { color: var(--aviso); }

/* ---------- rollover del bono ---------- */
.rollover { height: 8px; border-radius: 99px; background: var(--carbon-3); overflow: hidden; margin: .5rem 0 .3rem; }
.rollover i { display: block; height: 100%; background: var(--aviso); }

/* ---------- crash ---------- */
/* Sin conexión el número deja de ser el multiplicador vivo y pasa a ser el último
   que se supo. Se apaga para que no se lea como un dato fresco: la cifra es el
   héroe tipográfico de esta pantalla y a pleno brillo promete un cobro que puede
   que ya no exista. */
.crashwrap.incierto .crashnum b { opacity: .45; }
.crashwrap.incierto canvas { opacity: .3; }
.crashwrap { position: relative;
  background:
    radial-gradient(90% 70% at 50% 115%, color-mix(in srgb, var(--acento, #ff6a1f) 22%, transparent), transparent 70%),
    var(--halo-juego); border: 1px solid var(--borde); border-radius: var(--r-tarjeta); padding: .7rem; }
#crashCanvas { width: 100%; height: 190px; display: block; }
.crashwrap.volando { animation: motorCrash 1.25s ease-in-out infinite; }
.crashwrap.volando::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  box-shadow: inset 0 -28px 52px color-mix(in srgb, var(--sube) 13%, transparent);
}
.crashwrap.revienta { animation: golpeCrash .5s var(--ease); }
@keyframes motorCrash { 50% { border-color: color-mix(in srgb, var(--sube) 48%, var(--borde)); box-shadow: 0 0 22px rgba(47,208,122,.09); } }
@keyframes golpeCrash { 30% { border-color: var(--cae); transform: translateX(-2px); } 55% { transform: translateX(2px); } }
/* La cifra manda: ocupa la franja de arriba y la curva vive debajo, sin cruzarla. */
.crashnum { position: absolute; left: 0; right: 0; top: .9rem; display: flex; flex-direction: column; align-items: center; pointer-events: none; }
.crashnum b { font-size: 2.9rem; font-weight: 900; letter-spacing: -.04em; line-height: 1; }
.crashnum small { color: var(--humo); font-size: .76rem; margin-top: .3rem; }
.up b { color: var(--sube); } .boom b { color: var(--cae); } .wait b { color: var(--ceniza); }
/* Acercándose a TU salida automática. El halo crece con la proximidad —`--cerca` va de
   .2 a 1— y NO parpadea: es intensidad, no destello, así que no hay frecuencia que medir
   contra el techo de 3 Hz. Va en oro porque lo que se acerca es el cobro. */
.crashnum.cerca b {
  color: color-mix(in srgb, var(--oro) calc(var(--cerca, 0) * 70%), var(--sube));
  text-shadow: 0 0 calc(8px + var(--cerca, 0) * 20px) rgba(255, 200, 87, calc(.22 + var(--cerca, 0) * .48));
}
/* El historial se desplaza en su propia caja y se desvanece a la derecha: nunca empuja
   el ancho de la página. */
.hist {
  display: flex; gap: .35rem; margin-top: .6rem; overflow-x: auto; scrollbar-width: none;
  mask-image: linear-gradient(90deg, #000 88%, transparent);
}
.hist::-webkit-scrollbar { display: none; }
.hist span {
  flex: 0 0 auto; font-size: .74rem; font-weight: 800; padding: .25rem .5rem;
  border-radius: var(--r-chico); background: var(--carbon-3);
}
.hist span.hi { color: var(--sube); } .hist span.lo { color: var(--cae); }

/* ---------- animalitos ---------- */
/* El registro es BRASA: es juego, no dinero. La cuadrícula es el tablero de la agencia
   traducido al teléfono — 38 animalitos que caben sin desplazar y se tocan con el
   pulgar. La barra fina de cada celda es lo cargado de VERDAD en ese animalito. */
.sorteo-cab {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem;
  padding-bottom: .7rem; border-bottom: 1px solid var(--borde);
}
.sorteo-cab .der { text-align: right; }
.sorteo-cab .cifra { display: block; font-size: 1.6rem; font-weight: 900; letter-spacing: -.03em; }
.sorteo-cab .oro { color: var(--oro); }

.sorteo-escena {
  display: flex; align-items: center; gap: .9rem; min-height: 106px; margin: .7rem 0 .2rem;
  padding: .8rem 1rem; border-radius: var(--r-tarjeta);
  background: var(--halo-juego); border: 1px solid var(--borde);
  color: var(--acento, var(--llama));
}
.sorteo-escena .vacio { color: var(--humo); font-size: .86rem; }
/* Nombres propios y no `.num`/`.nom`: `.num` ya es la casilla de la ruleta, y
   heredarla metía aquí un cuadrado con borde. */
.sorteo-escena .an-num {
  display: block; font-size: 2rem; font-weight: 900; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; line-height: 1;
}
.sorteo-escena .an-nom { display: block; font-weight: 800; color: var(--hueso); font-size: 1.02rem; }
.sorteo-escena .micro { display: block; }
/* El animalito que sale entra con peso; el que estás por jugar, no. Celebrar la entrada
   de cualquier animal quitaría sentido a la del que ganó. */
.sorteo-escena.sale { border-color: var(--acento, var(--llama)); animation: sale .5s ease-out; }
@keyframes sale {
  from { transform: scale(.94); opacity: .4; }
  to { transform: scale(1); opacity: 1; }
}

.animalitos {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: .32rem; margin: .8rem 0;
}
/* Con sitio de sobra la rejilla reparte en más columnas y baja de alto. Seis fijas
   hacían lo contrario: celdas más grandes y siete filas que no cabían. El mínimo de
   58 px mantiene el toque cómodo y el arte legible — no se aprieta el dibujo para
   ganar píxeles, se usa el ancho que hay. */
@media (min-width: 900px) {
  body[data-juego="lottery"] .tablero-zona .animalitos { grid-template-columns: repeat(auto-fit, minmax(58px, 1fr)); }
}
.animalito {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; gap: .1rem;
  padding: .38rem .1rem .42rem; min-height: 68px;
  background: var(--carbon-3); border: 1px solid transparent; border-radius: var(--r-chico);
  color: var(--humo); cursor: pointer;
}
.animalito .an { color: var(--hueso); opacity: .82; }
.animalito .n {
  font-size: .68rem; font-weight: 900; color: var(--hueso); font-variant-numeric: tabular-nums;
}
.animalito .nm {
  font-size: .54rem; line-height: 1; text-align: center; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.animalito .carga {
  position: absolute; left: 0; bottom: 0; height: 2px; width: var(--p, 0);
  background: var(--acento, var(--llama)); opacity: .8;
}
/* El que salió, señalado entre los 38. Mismo reparto que en el tapete de la ruleta:
   hueso para «aquí cayó», oro sólo si era el tuyo. Dos pulsos en 1,4 s = 1,4 Hz. */
.animalito.salio { animation: animalitoSalio 1.4s var(--ease) both; z-index: 2; }
@keyframes animalitoSalio {
  0%, 100% { box-shadow: none; }
  24% { box-shadow: 0 0 0 2px var(--hueso), 0 0 20px rgba(243, 245, 250, .45); }
  60% { box-shadow: 0 0 0 1px var(--hueso), 0 0 11px rgba(243, 245, 250, .24); }
}
.animalito.salio.gano { animation-name: animalitoSalioGana; }
@keyframes animalitoSalioGana {
  0%, 100% { box-shadow: none; }
  24% { box-shadow: 0 0 0 2px var(--oro), 0 0 26px rgba(255, 200, 87, .6); }
  60% { box-shadow: 0 0 0 1px var(--oro), 0 0 14px rgba(255, 200, 87, .32); }
}
.animalito:active { transform: scale(.95); }
.animalito.on {
  border-color: var(--acento, var(--llama)); background: var(--brasa);
}
.animalito.on .an, .animalito.on .n { color: var(--acento, var(--llama)); opacity: 1; }

.mis-tickets { margin-top: .8rem; display: grid; gap: .3rem; }
.mis-tickets .ticket {
  display: flex; align-items: center; gap: .55rem; font-size: .82rem;
  padding: .4rem .6rem; background: var(--carbon-3); border-radius: var(--r-chico);
  color: var(--acento, var(--llama));
}
.mis-tickets .ticket b { color: var(--hueso); }
.mis-tickets .ticket span { color: var(--humo); font-variant-numeric: tabular-nums; }
.mis-tickets .ticket span.oro { margin-left: auto; color: var(--oro); font-weight: 800; }

/* El contador de la tarjeta del lobby: dato, no urgencia. Va en frío por eso. */
.game .cuenta {
  display: inline-block; font-size: .62rem; font-weight: 900; letter-spacing: .04em;
  padding: .16rem .42rem; border-radius: 999px;
  background: var(--frio-tenue); color: var(--frio); font-variant-numeric: tabular-nums;
}
.hist span .an { vertical-align: -3px; margin-right: .2rem; }

/* ---------- rueda giratoria (ruleta y rueda) ---------- */
.rueda-caja { position: relative; display: grid; place-items: center; padding: .4rem 0 .8rem; }
.rueda { width: min(78vw, 260px); height: auto; display: block; filter: drop-shadow(0 10px 24px rgba(0,0,0,.5)); }
#ruedaGiro { transform-box: fill-box; transform-origin: center; }
.rueda-punta {
  position: absolute; top: -2px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent;
  border-top: 16px solid var(--hueso);
}
.rueda-cifra {
  position: absolute; font-size: 2.1rem; font-weight: 900; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums; pointer-events: none;
}
.rueda-caja.girando .rueda { filter: drop-shadow(0 12px 30px color-mix(in srgb, var(--acento, var(--llama)) 32%, transparent)); }
.rueda-caja.girando .rueda-punta { animation: puntaGolpea .15s ease-in-out infinite alternate; }
@keyframes puntaGolpea { to { transform: translateX(-50%) rotate(5deg) translateY(2px); } }

/* Sin recorrido si el jugador pidió menos movimiento: el resultado igual se ve. */
@media (prefers-reduced-motion: reduce) { #ruedaGiro { transition: none !important; } }

::view-transition-old(root), ::view-transition-new(root) { animation-duration: .18s; }

/* ---------- plinko ---------- */
#plinkoCanvas {
  /* Las casillas de pago van dentro del lienzo, bajo el último clavo: el alto las incluye. */
  width: 100%; height: 292px; display: block;
  background:
    radial-gradient(90% 70% at 50% 115%, color-mix(in srgb, var(--acento, #ff6a1f) 22%, transparent), transparent 70%),
    var(--halo-juego);
  border: 1px solid var(--borde); border-radius: var(--r-tarjeta);
}
#plinkoCanvas.cayendo { border-color: color-mix(in srgb, var(--acento, var(--llama)) 58%, var(--borde)); box-shadow: 0 0 24px color-mix(in srgb, var(--acento, var(--llama)) 14%, transparent); }
.slots { display: flex; gap: 2px; margin-top: .4rem; overflow-x: auto; scrollbar-width: none; }
.slots::-webkit-scrollbar { display: none; }
.slots div {
  flex: 1 0 auto; min-width: 30px; text-align: center; font-size: .58rem; font-weight: 800;
  padding: .25rem .15rem; border-radius: 4px; background: var(--carbon-3);
}
/* Dónde cayó, dentro de todo lo que podía tocar. Mismo reparto que el tapete y los
   animalitos: hueso para «aquí cayó», oro sólo si ese gajo pagó. Dos pulsos en 1,3 s. */
.slots div.salio { animation: casillaSalio 1.3s var(--ease) both; }
.slots div.salio.gano { animation-name: casillaSalioGana; }

/* ---------- mines ---------- */
.tablero-layout { display: grid; gap: 1rem; }
.tablero-zona, .tablero-controles { min-width: 0; }
.tablero-controles .apuesta .chips { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); overflow: visible; }
.tablero-controles .apuesta .chips .sep { display: none; }
/* En escritorio el tablero y la apuesta se ven juntos. En móvil conservan el
   orden de lectura: estado, tablero, configuración y acción. */
@media (min-width: 760px) {
  .tablero-layout { grid-template-columns: minmax(0, 1fr) 280px; align-items: start; gap: 1.2rem; }
  .tablero-controles { border-left: 1px solid var(--borde); padding-left: 1.2rem; }
  .tablero-controles .apuesta { padding: .7rem; }
}
/* La app vive en 760 px porque esa es una medida cómoda para LEER, y eso se respeta.
   Los 38 animalitos son la única rejilla que MEJORA con más ancho: reparte en más
   columnas y baja de alto. A las demás les pasa lo contrario —sus celdas son cuadradas
   y crecer de ancho es crecer de alto—, así que el ensanche va sólo donde sirve.
   Medido: ensanchar para todos arreglaba animalitos y rompía minas (+180 → −100),
   rueda y plinko.
   La carretera del pollito entra por la misma puerta y por el motivo contrario al de las
   rejillas: es una tira HORIZONTAL de alto fijo, así que todo el ancho que se le dé son
   carriles que se ven sin desplazar, y ni un píxel de alto. En 736 px se veían seis de
   doce. */
@media (min-width: 900px) {
  body[data-juego="lottery"] .wrap,
  body[data-juego="pollo"] .wrap,
  body[data-juego="roulette"] .wrap { max-width: 1040px; }
  /* La ruleta entra con una condición: el ancho de más se gasta en poner la rueda AL
     LADO del tapete, no en estirarlo. Apilados pedían 653 px de zona y la mesa no cabía
     en 1280×800 —se pasaba 37, y bajar a apostar era el viaje que Pedro reportó—; en dos
     columnas la zona baja a 337 y sobran 25.

     El tope de 320 px del tapete es lo que hace esto seguro: sin él, ensanchar volvía a
     crecer las casillas y las siete filas subían con ellas. */
  body[data-juego="roulette"] .tablero-zona {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 1rem; align-items: start;
  }
}
/* MÓVIL. Aquí no hay ancho que repartir: tablero, ajustes y apuesta van en una sola
   columna y no caben juntos (la ruleta pedía 1161 px contra 738 de pantalla). El jugador
   bajaba a apostar y volvía a subir para ver la jugada.
   La apuesta se queda pegada sobre la barra de abajo: la acción está siempre a un dedo
   y lo que se desplaza es la mesa.
   Las dos columnas se disuelven con `display: contents` porque un `sticky` sólo tiene
   recorrido dentro de SU contenedor, y `.tablero-controles` es apenas más alto que la
   propia barra — pegada ahí no se movía ni un píxel. Disueltas, la barra se pega
   respecto a la tarjeta entera, que es lo que se desplaza de verdad. */
@media (max-width: 759px) {
  .tablero-layout { gap: 0; }
  .tablero-zona, .tablero-controles { display: contents; }
  /* LA BARRA DE ACCIÓN.
     Reportado por Pedro: «el sticker ese que se mueve para el menú de apuestas se ve
     clunky y wacky». Y lo era, por tres motivos medibles:

     1. Con `sticky` la barra viaja en el flujo hasta que choca con su borde y AHÍ se
        despega. Ese salto es el «se mueve». Fija no se mueve nunca.
     2. Conservaba su forma de tarjeta —borde entero, esquinas redondeadas, sombra de
        objeto levantado— flotando encima de la mesa. Una barra de acción no es una
        tarjeta que flota: está anclada al borde de la pantalla, y lo que la separa del
        contenido es una línea y un desenfoque, no un marco.
     3. Medía 285 px, el 35 % de una pantalla de 818, y dejaba diecinueve elementos
        debajo — incluidas casillas de minas, que son lo que hay que TOCAR.

     Ahora mide 181 px (22 %) sin quitar ni un control: los seis chips caben en una fila,
     las cifras van compactas y el saldo se va, porque ya está en la cabecera y verlo dos
     veces a la vez en 375 px es gastar el sitio que necesita la mesa. */
  body.juego-abierto .tablero-controles .apuesta {
    position: fixed; z-index: 12; left: 0; right: 0;
    bottom: calc(var(--alto-nav) + var(--safe));
    margin: 0 auto; max-width: 760px;
    padding: .55rem .7rem .65rem; gap: .5rem;
    border: 0; border-top: 1px solid var(--borde-claro); border-radius: 0;
    background: color-mix(in srgb, var(--carbon) 90%, transparent);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 -12px 30px rgba(0, 0, 0, .6);
  }
  /* Etiqueta encima de su cifra y las dos en una línea cada una. En fila se partían:
     «Si aciertas la primera» no cabe al lado de un importe en 375 px. */
  body.juego-abierto .apuesta .apuesta-cifras .micro { margin: 0 0 1px; font-size: .58rem; line-height: 1.2; }
  body.juego-abierto .apuesta .monto { font-size: 1.2rem; }
  body.juego-abierto .apuesta .cifra { font-size: 1.15rem; }
  body.juego-abierto .tablero-controles .apuesta .chips { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: .3rem; }
  body.juego-abierto .apuesta .chip { padding: .4rem .2rem; font-size: .78rem; min-width: 0; }
  body.juego-abierto .apuesta .pie-saldo { display: none; }
  /* Y la mesa reserva el sitio de la barra, medido: sin esto, el final del tablero queda
     bajo ella y no hay scroll que lo saque. */
  body.juego-abierto #gameHost .card { padding-bottom: calc(var(--alto-apuesta, 190px) + .9rem); }
  /* El resultado se apoya JUSTO ENCIMA de la barra, sobre la misma medida.
     Quedándose en el flujo, la barra le tapaba la mitad —82 px de alto con 34 visibles—
     y el jugador leía «Atropell…» sin la cifra. Es lo más importante que aparece en toda
     la ronda: no puede ser lo único que hay que ir a buscar con el dedo. */
  body.juego-abierto #gameHost > .card > #gMsg,
  body.juego-abierto #gameHost #gMsg:not(:empty) {
    position: fixed; z-index: 11; left: 0; right: 0;
    bottom: calc(var(--alto-nav) + var(--safe) + var(--alto-apuesta, 190px));
    margin: 0 auto; max-width: 760px; padding: 0 .7rem .5rem;
  }
}

.tablero-estado {
  min-height: 44px; display: flex; align-items: center;
  margin: -.2rem 0 .6rem; padding: .55rem .7rem;
  border: 1px solid var(--borde); border-radius: var(--r-chico);
  background: var(--carbon); color: var(--hueso);
  font-size: .85rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.tablero-leyenda { display: flex; flex-wrap: wrap; gap: .4rem 1rem; margin-top: .7rem; color: var(--humo); font-size: .75rem; }
.tablero-leyenda span { display: inline-flex; align-items: center; gap: .35rem; }
.tablero-leyenda svg { flex-shrink: 0; }
/* La mesa donde caen las fichas. Sin una superficie que las contenga, las piezas con
   relieve flotan sobre el fondo de la tarjeta y el relieve no se lee como relieve: hace
   falta algo hundido detrás para que haya contra qué destacar. */
.grid5, .torre, .hilo-mesa {
  padding: .5rem; border-radius: var(--r-tarjeta);
  background: var(--halo-juego); box-shadow: var(--hundido);
}
.grid5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: .4rem; }
/* Una casilla por destapar es una ficha boca abajo: tiene que verse que se puede coger.
   Antes era un cuadro con borde y un punto en medio, o sea el hueco donde iría una ficha. */
.cell {
  min-width: 0; min-height: var(--toque); padding: 0; color: var(--hueso);
  aspect-ratio: 1; border-radius: var(--r); border: 1px solid var(--borde);
  background: var(--cara), var(--carbon-3); display: flex; align-items: center; justify-content: center;
  font-size: 1.2rem; cursor: pointer; box-shadow: var(--relieve);
  transition: transform var(--dur-toque) var(--ease), box-shadow var(--dur-toque) var(--ease);
  touch-action: manipulation; position: relative;
}
/* Pulsar HUNDE la ficha en la mesa: la sombra se invierte y baja dos píxeles. Antes sólo
   encogía, que es lo que hace un icono, no lo que hace una pieza. */
.cell:active:not(:disabled) { transform: translateY(2px) scale(.98); box-shadow: var(--hundido); }
.cell:disabled { opacity: 1; cursor: default; }
/* `:disabled` NO significa lo mismo en los dos juegos, y tratarlo igual dejaba la torre
   en blanco.
   En MINAS la rejilla entera se juega mientras la ronda vive, así que una casilla
   deshabilitada es de una ronda TERMINADA: deja de ser pieza y vuelve a ser mesa.
   En la TORRE sólo se juega el piso vivo, así que los de arriba están deshabilitados
   porque todavía no te tocan. Son el futuro de la ronda, no sus restos: siguen siendo
   fichas, sólo que un poco más lejos. */
.grid5 .cell:disabled:not(.safe):not(.mine) {
  background: var(--carbon-2); border-style: dashed; box-shadow: none;
}
.torre .cell:disabled:not(.safe):not(.mine) { opacity: .8; }
/* El DORSO de la pieza por destapar. Era un punto `·` de 1,5 rem en medio de la casilla:
   el hueco donde iría algo, no algo. Ahora lleva el mismo enrejado que el dorso del naipe
   de hi-lo, así que todo lo que en este casino está boca abajo se dibuja igual.
   El carácter se queda en el HTML —tres pantallas lo emiten y va con `aria-hidden`—, sólo
   deja de verse: lo que se ve es el patrón. */
/* Va posicionado y no dimensionado en porcentaje: las casillas de la TORRE son anchas y
   bajas, su alto sale de `min-height` y contra eso un `height: 58%` no resuelve — el
   dorso salía de altura cero y los pisos se veían en blanco. */
.casilla-tapa {
  position: absolute; inset: 23%;
  font-size: 0; color: transparent; line-height: 0; border-radius: 5px;
  background:
    repeating-linear-gradient(45deg, rgba(233, 238, 250, .07) 0 2px, transparent 2px 6px),
    repeating-linear-gradient(-45deg, rgba(233, 238, 250, .07) 0 2px, transparent 2px 6px);
}
/* En una casilla muerta el dorso se apaga: ya no hay nada que destapar ahí. */
.grid5 .cell:disabled:not(.safe):not(.mine) .casilla-tapa { opacity: .4; }
.cell.pick { background: var(--llama); border-color: var(--llama); }
.cell.mine { background: var(--cae-tenue); border-color: var(--cae); }
.cell.safe { background: var(--sube-tenue); border-color: var(--sube); }
.cell.safe svg { color: var(--sube); }
.cell.mine svg { color: var(--cae); }
.cell.revelada { animation: revelaCasilla .38s var(--ease) calc(var(--i, 0) * 18ms) both; }
/* Una casilla viva se toca; una del pasado, no. La diferencia tiene que verse antes
   de tocarla, no después. */
.cell.viva { cursor: pointer; border-color: var(--borde-claro); box-shadow: var(--relieve-alto); }
.cell.viva:hover:not(:disabled) { background: var(--carbon-3); border-color: var(--humo); filter: none; }

/* Torre: los pisos se apilan de abajo arriba y sólo el vivo invita a tocarlo.
   Las casillas son anchas y bajas, no cuadradas: con 3 columnas a todo el ancho, una
   casilla cuadrada mide un tercio de la pantalla y la torre no cabe entera. */
.torre { display: grid; gap: .34rem; }
.torre-piso { display: grid; gap: .34rem; align-items: center; }
.piso-numero { color: var(--humo); font-size: .75rem; font-weight: 800; text-align: center; font-variant-numeric: tabular-nums; }
.torre-piso .cell { aspect-ratio: auto; min-height: var(--toque); }
.torre-piso.activo .piso-numero { color: var(--hueso); border-left: 3px solid var(--acento); }
.torre-piso.activo .cell { cursor: pointer; border-color: var(--acento); box-shadow: inset 0 0 0 1px var(--acento); }
.torre-piso.activo .cell:hover:not(:disabled) { background: var(--carbon-3); filter: none; }

/* Hi-Lo: la carta es el juego entero, así que ocupa el sitio de una. */
.hilo-mesa { display: grid; justify-items: center; gap: .5rem; padding: 1.1rem 0 .4rem; }
/* Sin ronda abierta se ve el DORSO, y al repartir la carta se voltea y enseña la cara.
   Antes las dos caras eran el mismo rectángulo oscuro con un número dentro, así que la
   vuelta —que ya estaba animada— no volteaba nada: cambiaba una cifra. */
.carta {
  position: relative;
  width: 92px; height: 128px; border-radius: 14px; display: grid; place-items: center;
  border: 1px solid var(--borde); color: var(--ceniza);
  font-size: 3rem; font-weight: 900; letter-spacing: -.04em; font-variant-numeric: tabular-nums;
  background:
    repeating-linear-gradient(45deg, rgba(255, 106, 31, .16) 0 3px, transparent 3px 9px),
    repeating-linear-gradient(-45deg, rgba(255, 106, 31, .16) 0 3px, transparent 3px 9px),
    var(--carbon-3);
}
/* La cara: papel claro, como un naipe. Es el elemento que decide la jugada y tiene que
   ser lo más luminoso de la mesa. */
.carta.viva {
  color: #151922; border-color: #b9c1d2;
  background: linear-gradient(158deg, #f8fafd 0%, #e2e7f0 100%);
  box-shadow: 0 10px 24px rgba(0, 0, 0, .5), 0 0 0 3px color-mix(in srgb, var(--acento) 22%, transparent);
}
/* El índice de las esquinas, que es lo que hace que un rectángulo con un número parezca
   una carta. Sale del mismo valor que el centro, puesto en `data-cara`: no hay dos
   sitios de donde pueda salir distinto. */
.carta.viva::before, .carta.viva::after {
  content: attr(data-cara);
  position: absolute; font-size: .82rem; font-weight: 900; letter-spacing: 0; line-height: 1;
}
.carta.viva::before { top: 8px; left: 10px; }
.carta.viva::after { bottom: 8px; right: 10px; transform: rotate(180deg); }
/* Vuelta de carta: mismo lenguaje que el destape de casillas en minas, en su eje. */
.carta.gira { animation: giraCarta .34s var(--ease); }
@keyframes giraCarta {
  from { transform: perspective(340px) rotateY(76deg) scale(.92); opacity: .28; }
  to { transform: none; opacity: 1; }
}
.hilo-restan { color: var(--humo); font-size: .78rem; }
.hilo-lados { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
/* Los dos lados SON la jugada de hi-lo: son las piezas que se tocan, no dos etiquetas. */
.hilo-lados .lado {
  display: grid; gap: .15rem; padding: .7rem .5rem; min-height: 62px;
  background-image: var(--cara); box-shadow: var(--relieve);
  transition: transform var(--dur-toque) var(--ease), box-shadow var(--dur-toque) var(--ease);
}
.hilo-lados .lado:active:not(:disabled) { transform: translateY(2px); box-shadow: var(--hundido); }
/* Un lado retirado no se toca: deja de ser pieza. */
.hilo-lados .lado.retirado { box-shadow: none; background-image: none; }
.hilo-lados .lado span { font-size: .78rem; color: var(--humo); }
.hilo-lados .lado b { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
/* Un lado que todavía deja por debajo de lo apostado: se puede jugar y el acumulado lo
   arregla en el paso siguiente, pero no es un cobro. Mismo tratamiento que los carriles
   del pollito, porque es la misma idea. */
.hilo-lados .lado.bajo-par b { color: var(--ceniza); }
.hilo-lados .lado:disabled { opacity: .45; }
.hilo-lados .lado .chance { font-size: .72rem; color: var(--ceniza); font-variant-numeric: tabular-nums; }
.hilo-lados .lado .chance:empty { display: none; }
/* Un lado retirado ya no es un botón roto con un guion: lleva el motivo, así que tiene
   que LEERSE. La opacidad de `:disabled` lo dejaba muy por debajo del contraste mínimo,
   de modo que se distingue por trazo discontinuo y color, no por transparencia. */
.hilo-lados .lado.retirado { opacity: 1; border-style: dashed; }
.hilo-lados .lado.retirado b { font-size: .78rem; font-weight: 700; color: var(--ceniza); }
.hilo-regla { margin-top: .55rem; }
@keyframes revelaCasilla { from { opacity: .25; transform: perspective(180px) rotateX(72deg) scale(.78); } to { opacity: 1; transform: none; } }

/* ---------- pollito ---------- */
/* Una carretera, no una fila de botones. El asfalto es una sola superficie continua y las
   marcas viales son el borde derecho discontinuo de cada carril, así que la separación
   entre carriles la dibuja la propia calzada. Va en horizontal y se desplaza sola hasta
   el carril vivo: con veinticuatro no caben en pantalla, y el jugador no tiene por qué
   buscar dónde está su pollo. */
.carretera {
  display: flex; margin-top: .1rem;
  /* Sin `width: max-content`: la carretera vive dentro de un grid, y en móvil las dos
     columnas se disuelven con `display: contents`, así que su ancho intrínseco pasa a
     ser el de la columna y arrastra la tarjeta entera fuera de la pantalla. El asfalto
     que sobra cuando hay pocos carriles se lo queda la meta. */
  overflow-x: auto; scrollbar-width: none;
  border-radius: var(--r-chico); border: 1px solid var(--borde);
  background: linear-gradient(180deg, #0a0c11, #131721 42%, #0a0c11);
  box-shadow: var(--hundido);
}
.carretera::-webkit-scrollbar { display: none; }

/* Los dos arcenes. La acera de salida es de donde arranca el pollito y la meta a cuadros
   es adónde va: sin ellos la carretera no tiene principio ni final, y el jugador no sabe
   cuánto le queda. */
.via-borde {
  flex: 0 0 auto; width: 40px; align-self: stretch;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  position: relative;
}
.via-borde.salida { background: linear-gradient(90deg, var(--carbon-3), #10141c); border-right: 2px solid var(--borde-claro); }
.via-borde.salida i { width: 16px; height: 2px; border-radius: 2px; background: var(--borde-claro); }
/* La meta se queda con el asfalto que sobre. Con pocos carriles la carretera es más
   corta que la caja, y una franja de asfalto suelto después de la línea de llegada se
   lee como carretera que sigue: exactamente lo contrario de lo que dice. */
/* La meta se queda con lo que quede DESPUÉS de que los carriles lleguen a su tope: entre
   una franja de calzada suelta tras la línea de llegada —que se lee como carretera que
   sigue— y una zona de meta ancha, la zona de meta es lo que hay en un circuito. */
.via-borde.meta {
  flex: 1 0 32px; border-left: 2px solid var(--borde-claro);
  background-image: conic-gradient(#c3cad9 0 25%, #191d27 0 50%, #c3cad9 0 75%, #191d27 0);
  background-size: 18px 18px;
  box-shadow: inset 16px 0 22px -16px rgba(0, 0, 0, .85);
}
.via-borde.meta i { display: none; }
/* Con el pollito en la meta hace falta sitio para él: 30 px de banda son menos que el
   propio pollo. El velo oscuro es para que se lea encima de los cuadros. */
.via-borde.meta.llego { flex-basis: 58px; }
.via-borde.meta.llego .pollo-aqui { background: radial-gradient(closest-side, rgba(10, 12, 17, .82), transparent); }

/* El asfalto que sobra se lo reparten los CARRILES, no la meta. Con pocos carriles la
   carretera es más corta que la caja, y las dos alternativas eran peores: una franja de
   calzada suelta tras la línea de llegada se lee como carretera que sigue, y una meta que
   lo absorba todo es un damero del tamaño de la mesa. Así los carriles se ensanchan hasta
   el tope y no sobra nada.
   El alto NO depende del ancho —lo fija `min-height`—, que es la condición por la que a
   este juego se le abre el ensanche de escritorio. */
.carril {
  flex: 1 0 auto; width: 64px; max-width: 104px; min-height: 116px; padding: .34rem 0 .3rem;
  display: flex; flex-direction: column; align-items: center; gap: .18rem;
  border: 0; border-right: 2px dashed rgba(233, 238, 250, .13);
  background: transparent; color: var(--humo); cursor: default;
  touch-action: manipulation; transition: background var(--dur-toque) var(--ease);
}
.carril:last-of-type { border-right: 0; }
.carril:disabled { opacity: 1; }
/* Lo que paga cada carril, en el carril. Estaba sólo en una línea de texto bajo la mesa:
   el jugador tenía que leer una frase para saber qué compra el paso siguiente, y no veía
   en absoluto lo que compran los de más allá. */
.carril-mult { font-size: .67rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.carril-via { position: relative; flex: 1; width: 100%; display: flex; align-items: center; justify-content: center; }

/* Camino, no cobro: los carriles cuyo acumulado todavía no llega a lo apostado enseñan
   su número —esconderlo sería esconder que ahí no se puede salir— pero en gris, no en el
   color del premio. Y el primero que SÍ paga se marca: es la meta corta de la ronda. */
.carril.bajo-par .carril-mult { color: var(--ceniza); font-weight: 700; }
.carril.primer-cobro .carril-mult { color: var(--sube); }
.carril.primer-cobro { box-shadow: inset 2px 0 0 var(--sube); }
.carril.cruzado { background: linear-gradient(180deg, rgba(47, 208, 122, .1), transparent); }
.carril.cruzado .carril-mult { color: var(--sube); }
.carril.coche { background: linear-gradient(180deg, rgba(255, 77, 87, .14), transparent); }
.carril.coche .carril-mult { color: var(--cae); }
/* El carril vivo es el único que se toca, y tiene que verse antes de tocarlo. */
.carril.vivo {
  cursor: pointer; background: rgba(255, 106, 31, .1);
  box-shadow: inset 0 0 0 2px var(--acento, var(--llama)), inset 0 -22px 26px -18px var(--acento, var(--llama));
}
.carril.vivo .carril-mult { color: var(--oro); }
.carril.vivo:active { background: rgba(255, 106, 31, .2); }

/* El paso de cebra del carril que toca cruzar.
   Reportado por Pedro: con la apuesta viva no se entendía dónde hay que tocar, y pensó en
   una manita. Una manita es un icono de interfaz encima del tablero; un paso de cebra es
   señalización de carretera de verdad y dice exactamente lo mismo —«por aquí se cruza»—
   sin salirse del mundo del juego. Late medio hercio, muy por debajo del techo de 3 Hz. */
.cebra {
  position: absolute; inset: 14% 22%; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(180deg,
    rgba(243, 245, 250, .5) 0 5px, transparent 5px 13px);
  animation: cebraLlama 2s ease-in-out infinite;
}
/* Marca vial, no código de barras: rayas más finas y más separadas, y el latido va de
   apagada a media luz. A pleno blanco tapaba el multiplicador del propio carril, que es
   el otro dato que hay que leer antes de tocarlo. */
@keyframes cebraLlama { 0%, 100% { opacity: .42; } 50% { opacity: .8; } }

/* El pollito. Es el personaje y por eso pisa por encima del coche parado y del tráfico. */
.pollito { width: 34px; height: 37px; display: block; }
.pollo-aqui {
  position: relative; z-index: 3; display: block;
  filter: drop-shadow(0 4px 5px rgba(0, 0, 0, .55));
  animation: polloEspera 2s var(--ease) infinite;
}
/* Un bote cada dos segundos: medio hercio, y el techo del casino son tres. */
@keyframes polloEspera {
  0%, 62%, 100% { transform: none; }
  70% { transform: translateY(-3px) rotate(-3deg); }
  82% { transform: translateY(-1px) rotate(1.5deg); }
}
/* Las patas sólo se mueven cuando el pollito se mueve: quieto en el arcén, quieto. */
.po-pata { transform-origin: 50% 68%; }
.pollo-aqui.salta .po-pata.a { animation: pataAdelante .42s var(--ease); }
.pollo-aqui.salta .po-pata.b { animation: pataAtras .42s var(--ease); }
@keyframes pataAdelante { 0%, 100% { transform: none; } 50% { transform: rotate(-22deg); } }
@keyframes pataAtras   { 0%, 100% { transform: none; } 50% { transform: rotate(20deg); } }
/* El salto al carril siguiente. Sólo corre cuando el pollito CAMBIÓ de carril: el tablero
   se repinta también al mover los controles, y un pollo saltando cada vez que tocas el
   número de carriles es ruido, no juego. */
.pollo-aqui.salta { animation: polloSalta .42s var(--ease); }
@keyframes polloSalta {
  0%   { transform: translateX(-62px) scale(.92); }
  48%  { transform: translateX(-26px) translateY(-19px) scale(1.06); }
  78%  { transform: translateY(2px) scale(.97); }
  100% { transform: none; }
}
/* Atropellado: el pollito se queda tumbado y DEBAJO del coche, que es lo que cuenta lo
   que pasó. Sin destello y sin rebote — la derrota se cuenta, no se celebra. */
.carril.pilla .pollo-aqui {
  animation: none; z-index: 1;
  transform: translate(11px, 13px) rotate(74deg); opacity: .72;
}

/* El coche baja por el carril, que es como circula el tráfico en una carretera vista
   desde arriba. */
.coche-arte { width: 30px; height: 48px; display: block; }
.atropello { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 2; color: #56607a; }
.carril.pilla .atropello { color: var(--cae); animation: cocheEmbiste .34s var(--ease) both; }
@keyframes cocheEmbiste {
  from { transform: translateY(-118%); }
  72%  { transform: translateY(5%); }
  to   { transform: none; }
}
/* Tráfico de fondo. Un coche cada nueve segundos por uno de cada tres carriles todavía
   sin jugar: la carretera tiene que estar viva, o el riesgo es una palabra en un `hint`.
   Por el carril vivo NO pasa nunca — un coche rozando al pollito justo donde hay que
   decidir sería un susto inventado, y los sustos los reparte el servidor. */
.trafico {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #333c52; opacity: 0; z-index: 1; pointer-events: none;
  animation: traficoPasa 9s linear infinite; animation-delay: var(--retraso, 0s);
}
@keyframes traficoPasa {
  0%        { opacity: 0; transform: translateY(-135%); }
  5%        { opacity: .55; }
  20%       { opacity: .55; }
  25%, 100% { opacity: 0; transform: translateY(135%); }
}
/* La huella del carril ya cruzado. */
.huella { width: 15px; height: 15px; fill: var(--sube); opacity: .5; }

/* Sin movimiento no hay tráfico de fondo: la regla global deja las animaciones en .01 ms,
   y un coche que cruza la carretera en una centésima es un parpadeo, no una decoración. */
@media (prefers-reduced-motion: reduce) {
  .trafico { display: none; }
  .pollo-aqui { animation: none; }
  /* La cebra pierde el latido pero NO se va: es la señal que dice dónde hay que tocar,
     no una decoración. Sin movimiento, se queda encendida del todo. */
  .cebra { animation: none; opacity: 1; }
}

/* ---------- ruleta ---------- */
.roul { display: grid; grid-template-columns: repeat(6, 1fr); gap: .3rem; }
/* Las seis columnas del tapete son las del tapete de verdad: no se reparten distinto
   por tener más sitio. Sin tope, cada número crecía con el ancho y las siete filas
   subían con él — en 1280 px la ruleta pedía 1500 de alto. */
.tablero-zona .roul { max-width: 320px; }
.num {
  aspect-ratio: 1; border-radius: var(--r-chico); border: 1px solid var(--borde);
  display: flex; align-items: center; justify-content: center;
  min-height: var(--toque); padding: 0; color: var(--hueso);
  font-size: .82rem; font-weight: 800; cursor: pointer; touch-action: manipulation;
  background-image: var(--cara); box-shadow: var(--relieve);
  transition: transform var(--dur-toque) var(--ease), box-shadow var(--dur-toque) var(--ease);
}
.num:active { transform: translateY(2px); box-shadow: var(--hundido); }
/* Dónde cayó la bola, señalado en el tapete. Dos pulsos en 1,3 s son 1,5 Hz, dentro
   del techo de 3 Hz que se respeta en todo el casino. */
.num.salio { animation: casillaSalio 1.3s var(--ease) both; z-index: 2; }
@keyframes casillaSalio {
  0%, 100% { box-shadow: none; }
  25% { box-shadow: 0 0 0 2px var(--hueso), 0 0 18px rgba(243, 245, 250, .5); }
  62% { box-shadow: 0 0 0 1px var(--hueso), 0 0 10px rgba(243, 245, 250, .26); }
}
/* En oro sólo si ese número era tuyo: el oro es premio cobrado, no «aquí cayó». */
.num.salio.gano { animation-name: casillaSalioGana; }
@keyframes casillaSalioGana {
  0%, 100% { box-shadow: none; }
  25% { box-shadow: 0 0 0 2px var(--oro), 0 0 24px rgba(255, 200, 87, .62); }
  62% { box-shadow: 0 0 0 1px var(--oro), 0 0 13px rgba(255, 200, 87, .34); }
}
.num.r { background: rgba(255, 77, 87, .22); }
.num.b { background: rgba(255, 255, 255, .06); }
.num.g { background: var(--sube-tenue); }
.num.on { outline: 2px solid var(--llama); outline-offset: -2px; }
.num.on { box-shadow: inset 0 0 14px color-mix(in srgb, var(--llama) 24%, transparent); transform: translateY(-1px); }
.wheelnum { text-align: center; font-size: 3rem; font-weight: 900; letter-spacing: -.04em; padding: .6rem 0; }

/* ---------- carreras y torneos ---------- */
.carrera-meta {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: .15rem .6rem; margin-bottom: .5rem;
}
/* En el teléfono no caben rótulo y premio en la misma línea: antes que partir el
   rótulo en tres, el premio baja entero a la suya. */
.carrera-meta .micro { flex: 1 1 12rem; }
/* El premio es lo que convierte un marcador en una razón para volver: va en oro
   y no se encoge cuando el nombre de la carrera es largo. */
.carrera-meta .premio { color: var(--oro); font-size: .8rem; flex: 0 0 auto; }
.carrera ol { list-style: none; margin: 0; padding: 0; counter-reset: puesto; }
.carrera li {
  display: flex; align-items: center; gap: .4rem;
  font-size: .8rem; padding: .3rem 0; border-bottom: 1px solid var(--borde);
  counter-increment: puesto;
}
.carrera li:last-child { border-bottom: none; }
.carrera li::before {
  content: counter(puesto); flex: 0 0 16px;
  color: var(--ceniza); font-size: .68rem; font-weight: 800;
}
.carrera li:first-child::before { color: var(--oro); }
.carrera li span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.carrera li b { font-variant-numeric: tabular-nums; }
/* El premio de cada puesto, a la derecha del marcador: se lee la fila entera como
   "quién va, con cuánto, y qué se lleva". */
.carrera li em {
  font-style: normal; color: var(--oro); font-size: .74rem; font-weight: 700;
  flex: 0 0 auto; font-variant-numeric: tabular-nums;
}

/* ---------- feed en vivo ---------- */
/* Apuestas reales de la ronda. Con las pérdidas dentro el feed se lee como actividad de
   verdad; sin ellas, como un banner. */
.feed { display: flex; flex-direction: column; gap: .3rem; max-height: 220px; overflow-y: auto; }
.feed .f {
  display: flex; align-items: center; gap: .5rem; font-size: .8rem;
  padding: .4rem .55rem; border-radius: var(--r-chico); background: var(--carbon);
}
.feed .f .ico { color: var(--humo); line-height: 0; }
.feed .f .quien { font-weight: 800; min-width: 58px; }
.feed .f.mio .quien { color: var(--llama); }
.feed .f .g { color: var(--humo); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed .f .mx { color: var(--humo); font-variant-numeric: tabular-nums; min-width: 46px; text-align: right; }
.feed .f b { min-width: 66px; text-align: right; }
.feed .f.w b { color: var(--sube); } .feed .f.l b { color: var(--ceniza); }
/* Una jugada gorda se ve gorda. En oro porque ese premio SÍ está cobrado, y con un
   destello al entrar —uno solo, 0,9 s— para que se note sin quedarse parpadeando en la
   lista. Las pérdidas no tienen versión gorda: perder mucho no se subraya. */
.feed .f.gorda { background: color-mix(in srgb, var(--brasa) 55%, var(--carbon)); animation: feedGorda .9s var(--ease); }
/* Tu propia jugada gorda NO destella en el feed. El destello sirve para avisar de algo
   que no estás mirando —la jugada de otro—, y la tuya la estás celebrando ya en grande:
   la mesa enciende, la casilla enciende y salta el confeti. Un cuarto destello a la vez
   no añade, reparte la atención. El color se queda: al repasar la lista después, tu
   jugada gorda tiene que verse igual que las demás. */
.feed .f.gorda.mio { animation: none; }
.feed .f.gorda b { color: var(--oro); }
.feed .f.gorda .mx { color: var(--oro); font-weight: 800; }
@keyframes feedGorda {
  0%, 100% { box-shadow: none; }
  35% { box-shadow: 0 0 0 1px var(--oro), 0 0 22px rgba(255, 200, 87, .4); }
}

/* ---------- tabla ---------- */
table { width: 100%; border-collapse: collapse; font-size: .82rem; }
th { text-align: left; font-size: .64rem; text-transform: uppercase; letter-spacing: .1em; color: var(--humo); font-weight: 800; }
th, td { padding: .45rem .3rem; border-bottom: 1px solid var(--borde); }

/* ---------- retos, salas y mercados ---------- */
/* El registro aquí es SALA, no BRASA: se está mirando dinero comprometido con otra
   persona, no jugando una mano. Nada de naranja salvo el botón que abre el reto. */
.separa { display: flex; align-items: center; gap: .6rem; margin: 1rem 0 .8rem; }
.separa::before, .separa::after { content: ''; flex: 1; height: 1px; background: var(--borde); }
.separa span { font-size: .62rem; font-weight: 800; letter-spacing: .12em; color: var(--ceniza); text-transform: uppercase; }

.reto, .sala, .mercado {
  padding: .7rem .75rem; margin-top: .55rem;
  border: 1px solid var(--borde); border-radius: var(--r); background: var(--carbon);
}
.reto-alto, .sala-alto { display: flex; align-items: center; gap: .5rem; }
.reto-quien { flex: 1; font-size: .8rem; color: var(--humo); }
.sala-alto b { flex: 1; font-size: .9rem; }
.reto-alto > b, .tabla-sala b { font-variant-numeric: tabular-nums; font-size: .88rem; }
.gano { color: var(--sube); }
.pierde { color: var(--cae); }
.neutro { color: var(--humo); }
.reto-baja { margin-top: .5rem; }
.reto-acciones { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .4rem; }
.prueba-reto { margin-top: .5rem; }
.prueba-reto .datos { margin: 0; }

/* El resultado del reto aceptado: los dos números lado a lado, porque la comparación
   ES el juego. Ninguno de los dos se dibuja más grande que el otro. */
.reto-fin { margin-top: .8rem; padding: .85rem; border-radius: var(--r); background: var(--carbon-3); border: 1px solid var(--borde); }
.reto-fin.gana { border-color: var(--sube); background: var(--sube-tenue); }
.reto-fin.pierde { border-color: var(--borde-claro); }
.reto-cifras { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-top: .45rem; }
.reto-cifras small { display: block; font-size: .62rem; text-transform: uppercase; letter-spacing: .1em; color: var(--humo); }
.reto-cifras b { font-size: 1.5rem; font-weight: 900; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }

.tabla-sala { list-style: none; margin: .5rem 0 0; padding: 0; }
.tabla-sala li { display: flex; align-items: center; gap: .5rem; font-size: .8rem; padding: .28rem 0; border-bottom: 1px solid var(--borde); }
.tabla-sala li:last-child { border-bottom: none; }
.tabla-sala span { flex: 1; }
.tabla-sala small { color: var(--humo); font-size: .68rem; }
.mercado b { font-size: .92rem; }
.mercado .chip em { font-style: normal; color: var(--frio); font-variant-numeric: tabular-nums; }

/* ---------- navegación inferior ---------- */
/* Cinco destinos, abajo, al alcance del pulgar. La competencia arrastra menús de
   escritorio a una pantalla que se usa con una mano en el autobús. */
.nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: rgba(18, 21, 29, .96); backdrop-filter: blur(14px);
  border-top: 1px solid var(--borde); padding-bottom: var(--safe);
}
.nav button {
  background: none; border: none; color: var(--humo);
  font-size: .62rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  min-height: 58px; padding: .5rem 0; display: flex; flex-direction: column; align-items: center; gap: .25rem;
}
.nav button svg { display: block; }
.nav button.on { color: var(--llama); }
/* Con cinco destinos cada uno mide 64 px en el teléfono más estrecho que soportamos:
   el rótulo se aprieta antes que partirse en dos líneas y descuadrar la barra. */
@media (max-width: 359px) {
  .nav button { font-size: .58rem; letter-spacing: .02em; }
}

/* ---------- cajero: métodos y datos de pago ---------- */
/* En la portada son un sello de "sí puedes pagar como pagas todo"; en el cajero son
   la elección. Misma pieza, dos registros. */
.metodos { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .9rem; }
.metodos span {
  font-size: .68rem; font-weight: 800; letter-spacing: .04em; color: var(--humo);
  border: 1px solid var(--borde); border-radius: 99px; padding: .32rem .7rem;
  background: var(--carbon);
}
.metodos span.operacion-abierta { color: var(--sube); border-color: rgba(47,208,122,.35); background: var(--sube-tenue); }
.metodos span.operacion-pendiente { color: var(--aviso); border-color: rgba(255,187,56,.35); background: var(--aviso-tenue); }
.metodos.elige { margin: 0 0 .9rem; }

/* Cada dato que hay que copiar, con su botón: nadie transcribe a mano una dirección
   de 34 caracteres ni un monto con céntimos exactos. */
.datos { display: grid; gap: .4rem; margin: .8rem 0 .2rem; }
.dato {
  display: flex; align-items: center; gap: .6rem;
  background: var(--carbon); border: 1px solid var(--borde); border-radius: var(--r);
  padding: .55rem .7rem;
}
.dato small {
  flex: 0 0 6.2rem; color: var(--humo); font-size: .6rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .1em;
}
.dato b { flex: 1; font-size: .95rem; font-variant-numeric: tabular-nums; word-break: break-all; }
button.copiar { position: relative; min-height: 32px; padding: .3rem .6rem; font-size: .72rem; flex: 0 0 auto; }

/* La dirección de cripto es el dato más frágil del cajero: se muestra entera, en
   monoespaciada y sin recortar. Un carácter mal leído es dinero perdido. */
.direccion {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .82rem; line-height: 1.5; word-break: break-all;
  background: var(--carbon); border: 1px solid var(--borde-claro); border-radius: var(--r);
  padding: .7rem .8rem; margin: .3rem 0 .6rem;
}
.dato-semilla {
  min-height: var(--toque); display: flex; align-items: center;
  padding: .65rem .75rem; border: 1px solid var(--borde); border-radius: var(--r);
  background: var(--carbon); font-variant-numeric: tabular-nums; font-weight: 800;
}
.pruebas-ronda { margin-top: .8rem; }
.pruebas-ronda details { border-top: 1px solid var(--borde); padding: .65rem 0; }
.pruebas-ronda details:last-child { padding-bottom: 0; }
.pruebas-ronda summary { text-transform: none; letter-spacing: 0; font-size: .78rem; }
/* La hora de cada jugada, bajo el nombre del juego. En `--ceniza` para que el ojo
   siga bajando por las cifras, que es lo que se compara en un historial. */
.cuando { display: block; color: var(--ceniza); font-size: .7rem; font-weight: 600; font-variant-numeric: tabular-nums; }

.prueba-json {
  max-height: 250px; overflow: auto; margin: .6rem 0;
  padding: .7rem; border-radius: var(--r); border: 1px solid var(--borde);
  background: var(--carbon); color: var(--humo); white-space: pre-wrap; word-break: break-all;
  font: .72rem/1.45 ui-monospace, SFMono-Regular, Menlo, monospace;
}
.hint.aviso-red { color: var(--aviso); }

.fila-dep {
  display: flex; align-items: center; gap: .7rem; padding: .55rem 0;
  border-top: 1px solid var(--borde); font-size: .85rem;
}
.fila-dep:first-child { border-top: none; }
.fila-dep b { font-variant-numeric: tabular-nums; }
.fila-dep span { flex: 1; color: var(--humo); font-size: .78rem; }
.fila-dep small { color: var(--humo); font-size: .72rem; }

.hide { display: none !important; }
details summary { cursor: pointer; color: var(--humo); font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .12em; }
/* Acción secundaria de una tarjeta: es un enlace, no un segundo botón. La regla
   del sistema es UNA acción primaria por tarjeta, y dos botones compiten. */
button.enlace {
  display: block; width: 100%; margin-top: .55rem; padding: .35rem 0;
  min-height: var(--toque);
  background: none; border: none; color: var(--humo);
  font-size: .82rem; font-weight: 700; text-decoration: underline;
  text-underline-offset: 3px; cursor: pointer;
}
button.enlace:hover { filter: none; color: var(--hueso); }

.back {
  background: none; border: none; color: var(--humo); font-weight: 700;
  padding: 0 .6rem .6rem 0; font-size: .85rem;
  min-height: var(--toque); display: inline-flex; align-items: center;
}
.back:hover { filter: none; color: var(--hueso); }

/* La mesa en teléfono ocupa el ancho útil y evita desplazamientos innecesarios. Los
   controles principales conservan 44 px o más y la conversión fija se aparta mientras
   se juega para dejarle el pulgar al juego. */
@media (max-width: 520px) {
  body.juego-abierto .wrap { padding-left: .55rem; padding-right: .55rem; }
  #vGame .back { padding-left: .15rem; }
  #gameHost > .juego-card { padding: .72rem; border-radius: 14px; }
  #gameHost > .juego-card h2 { margin-bottom: .62rem; }
  .apuesta { padding: .7rem; gap: .58rem; margin-top: .7rem; }
  .apuesta .chip { min-height: var(--toque); padding-inline: .68rem; }
  button.grande { min-height: 58px; }
  #plinkoCanvas { height: 238px; }
  .rueda { width: min(62vw, 224px); }
  .rueda-caja { padding-top: .1rem; padding-bottom: .55rem; }
  .grid5 { gap: .32rem; }
  .roul { gap: .24rem; }
  .num { min-height: var(--toque); aspect-ratio: auto; border-radius: 7px; }
  #crashCanvas { height: 168px; }
  .crashnum b { font-size: 2.55rem; }
}
@media (max-width: 359px) {
  #plinkoCanvas { height: 190px; }
  .rueda { width: min(62vw, 190px); }
  .apuesta { padding: .62rem; gap: .5rem; }
  .apuesta .chips { gap: .28rem; }
  .apuesta .chip { padding-inline: .58rem; }
}

/* ---------- escritorio ---------- */
/* Codex, 2026-08-13. A partir de 900 px deja de estirarse la maqueta de teléfono:
   portada editorial ancha, contenido en dos columnas y navegación dentro del header.
   La ilustración conserva su proporción completa (`auto 100%`) en vez de recortarse
   con `cover`; el carbón que sobra a la izquierda es el espacio natural del copy. */
@media (min-width: 900px) {
  body:has(#vAuth.on), body:has(.nav:not(.hide)) { padding-bottom: 1.5rem; }

  /* La medida. En teléfono ninguna línea llega a ser larga, así que el problema
     sólo existe aquí: a 1280 px el párrafo de la tarjeta del cajero —la más
     importante del lobby— medía 161 caracteres por línea, y el ojo pierde el
     renglón al volver pasados unos 75. La portada ya acota su medida (25ch, 11ch,
     38ch); esto extiende la misma decisión a las tarjetas de la app.
     No toca tablas ni rejillas: sólo el texto corrido.

     El 55 parece bajo y no lo es: `ch` mide el glifo «0», que en esta fuente son
     8,9 px, mientras el carácter MEDIO del texto son 6,8. Medido en el navegador,
     55ch aterriza en ~72 caracteres reales por línea, que es la medida cómoda.
     Fiarse de la regla «65ch» habría dejado 89. */
  .card > p, .card > .hint { max-width: 55ch; }
  body:has(#vAuth.on) .wrap,
  body:has(#vCasino.on) .wrap { max-width: 1240px; padding: 1.5rem; }

  /* Portada pública: un cartel completo arriba y una columna de producto con una
     columna lateral de confianza. En móvil estos bloques siguen apilados. */
  #vAuth.on {
    display: grid; grid-template-columns: minmax(0, 1.75fr) minmax(330px, .75fr);
    column-gap: 1.25rem; align-items: start;
  }
  #vAuth > .portada-principal {
    grid-column: 1 / -1; min-height: 540px; padding: 3.5rem;
    border-radius: 24px; background-size: auto 100%; background-position: right center;
    background-repeat: no-repeat;
  }
  #vAuth > .portada-principal::after {
    background: linear-gradient(90deg, rgba(11,13,18,1) 0%, rgba(11,13,18,.98) 23%, rgba(11,13,18,.78) 44%, rgba(11,13,18,.12) 72%, transparent 100%);
  }
  #vAuth > .portada-principal h1 { max-width: 8.5ch; font-size: clamp(3.4rem, 5vw, 4.7rem); line-height: .96; }
  #vAuth > .portada-principal p { max-width: 38ch; font-size: 1.05rem; line-height: 1.55; }
  #vAuth > .portada-principal .hero-kicker { font-size: .72rem; }
  #vAuth > .portada-principal .fila-cta { width: min(500px, 48%); margin-top: 1.5rem; }
  #vAuth > .portada-principal .metodos { max-width: 500px; }

  #vAuth > .lobby-portada { grid-column: 1; grid-row: 2 / span 2; margin: 0; }
  #vAuth > .confianza-portada { grid-column: 2; grid-row: 2; margin-top: 1.15rem; }
  #vAuth > .pagos-portada { grid-column: 2; grid-row: 3; margin-top: .45rem; }
  #vAuth #juegosPortada { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #vAuth .games-live .game { min-height: 224px; }
  #vAuth .confianza-grid, #vAuth .ruta-pago { grid-template-columns: 1fr; }
  #vAuth .confianza-grid article { display: grid; grid-template-columns: auto 1fr; column-gap: .65rem; align-items: start; }
  #vAuth .confianza-grid article .estado { grid-row: 1 / span 2; margin-top: .1rem; }
  #vAuth .confianza-grid article b { margin-top: 0; }
  #vAuth .confianza-grid article p { grid-column: 2; }
  #vAuth .paso-pago { display: flex; gap: .75rem; }
  #vAuth .paso-pago > span { flex: 0 0 26px; margin: 0; }

  /* En escritorio el registro es un diálogo. No empuja el catálogo hacia abajo ni
     repite la composición móvil; el sombreado también funciona como velo de fondo. */
  body:has(#cardAuth:not(.hide)) { overflow: hidden; }
  #cardAuth:not(.hide) {
    position: fixed; z-index: 70; left: 50%; top: 50%;
    width: min(720px, calc(100vw - 3rem)); max-height: calc(100vh - 3rem);
    overflow-y: auto; transform: translate(-50%, -50%);
    box-shadow: 0 0 0 100vmax rgba(3, 4, 7, .76), 0 28px 90px rgba(0,0,0,.72);
  }

  /* La conversión deja de ser una barra de teléfono. Entrar queda como acción compacta
     del header, al lado del sonido; Crear cuenta ya está en el hero. */
  .cta-fija {
    left: auto; right: 4.15rem; top: calc(.55rem + var(--safe-top)); bottom: auto;
    width: auto; padding: 0; background: transparent; border: 0; backdrop-filter: none;
  }
  .cta-fija #btnRegister3 { display: none; }
  .cta-fija button { position: relative; flex: 0 0 auto; min-height: 36px; padding: .45rem 1rem; font-size: .8rem; }

  /* Dentro de la cuenta, la navegación sube al centro del header y el lobby aprovecha
     el ancho para separar mesas y actividad. */
  .nav {
    left: 50%; right: auto; top: var(--safe-top); bottom: auto;
    width: auto; transform: translateX(-50%); display: flex;
    padding: 0; background: transparent; border: 0; backdrop-filter: none;
  }
  .nav button {
    min-width: 82px; min-height: 55px; padding: .45rem .75rem;
    flex-direction: row; justify-content: center; gap: .4rem; font-size: .66rem;
  }
  .nav button svg { width: 15px; height: 15px; }
  #vCasino.on {
    display: grid; grid-template-columns: minmax(0, 1fr) 340px;
    column-gap: 1.25rem; align-items: start;
  }
  #vCasino > .banda,
  #vCasino > .primer-deposito,
  #vCasino > .recientes { grid-column: 1 / -1; }
  #vCasino > .banda { min-height: 150px; padding: 2rem; }
  #vCasino > .banda h1 { font-size: 2.1rem; }
  #vCasino > .todos-titulo,
  #vCasino > #gameGrid,
  #vCasino > #carreras { grid-column: 1; }
  #vCasino > #gameGrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #vCasino > .card:last-child { grid-column: 2; grid-row: 3 / span 5; margin-top: 1.15rem !important; }
}

@media (prefers-reduced-motion: reduce) {
  .portada-principal, .pulso { animation: none !important; }
  .game .arte { transition: none; }
  .game:hover .arte { transform: none; }
  .chispa { display: none !important; }
  /* El botón «jugando» esconde su texto (`color: transparent`) y pone un spinner. Sin
     animación eso queda en un botón VACÍO con un anillo parado: parece roto justo cuando
     hace falta saber que la apuesta salió. Se cambia el círculo por la palabra — misma
     estructura, sin JavaScript, y dice lo que pasa. */
  button.grande.jugando::after {
    content: 'Jugando…'; width: auto; height: auto; margin: 0;
    border: 0; border-radius: 0; transform: translate(-50%, -50%);
    color: var(--tinta-llama); font-size: .95rem; font-weight: 900; letter-spacing: .01em;
  }
  /* Se apaga el recorrido, nunca el resultado: el jugador sigue viendo en cuánto reventó.
     Sin acotar las repeticiones, las seis animaciones `infinite` —el motor del crash,
     el spinner, las luces de mesa, la punta de la ruleta— seguían ciclando para siempre
     a .01ms: invisibles, pero despertando al compositor en teléfonos baratos. Quien pide
     menos movimiento no pide que no se note, pide que pare. */
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
