/**
 * juegos.css — Vista Juegos. Archivo propio, aislado: no toca
 * sportbook.css ni ninguna regla existente. Reutiliza únicamente clases
 * ya establecidas como base COMPARTIDA del sitio (.card, .btn, .eyebrow,
 * .cta-row, .cta-banner, .section-glow — todas viven en components.css/
 * sections.css, ya usadas por Home Y Sportbook antes de esta vista) y
 * los tokens de tokens.css. Todo lo estructural propio de Juegos
 * (topbar, hero, tarjetas, carrusel) tiene su propia clase acá — mismo
 * criterio que ya separa sportbook.css de Home: cero acoplamiento
 * cruzado entre vistas.
 */

.juegos-view {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  padding-top: 80px; /* mismo alto que .navbar fija — ver css/components.css */
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 380ms var(--ease-out-premium), transform 380ms var(--ease-out-premium);
}

.juegos-view.is-active {
  opacity: 1;
  transform: translateY(0);
}

.juegos-view__content {
  padding-top: var(--space-6);
}

.juegos-section {
  margin-bottom: var(--space-6);
}

.juegos-section__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.juegos-section__header h2 {
  font-size: 1.0625rem;
  font-family: var(--font-display);
  color: var(--text-primary);
}

.juegos-section__caption {
  font-size: 0.6875rem;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ---------- Hero Juegos ----------
   Título (eyebrow+h2) → banner casino (marco propio) → descripción: tres
   bloques secuenciales dentro de un wrapper SIN tratamiento de tarjeta
   propio (sin fondo/borde/padding — así los tres comparten el mismo eje
   izquierdo/derecho que el resto de la vista, .juegos-view__content, sin
   el doble-padding que tendría un "card" anidado). El look de tarjeta
   (fondo degradado + borde + radius) que antes tenía TODO el bloque como
   overlay ahora vive únicamente en .juegos-hero__banner-frame, que
   envuelve solo la foto — así el texto queda completamente fuera de la
   imagen, nunca superpuesto. Sin CTA: WhatsApp/Telegram ya están en la
   navbar y en los FABs flotantes, no hacían falta acá también. */
.juegos-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-bottom: var(--space-6);
}

.juegos-hero__icon {
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: linear-gradient(160deg, rgba(255, 215, 0, 0.22), rgba(255, 215, 0, 0.04));
  color: var(--gold-400);
  margin-bottom: var(--space-4);
  box-shadow: 0 0 32px rgba(255, 215, 0, 0.12);
}

.juegos-hero__icon svg {
  width: 28px;
  height: 28px;
}

/* Fila título: "Juegos" (ancla izquierda) + h2 (centro real de la fila,
   ver comentario en el HTML) + espejo invisible. margin-top acá en vez
   de en el h2: ahora los 3 elementos comparten una sola línea, el
   espaciado "Juegos ↔ h2" pasa a ser horizontal (gap), no vertical.
   align-items:flex-start (no center): en Mobile angosto el h2 puede
   envolver a 3-4 líneas — con center, "Juegos" queda flotando a mitad
   del bloque de título (se lee pegado a una línea del medio, no al
   título); con flex-start queda alineado arriba, junto al inicio real
   del título, igual que el diseño original. */
.juegos-hero__titlebar {
  display: flex;
  align-items: flex-start;
  width: 100%;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

.juegos-hero__titlebar .eyebrow {
  flex: 0 0 auto;
  padding-top: 0.3em;
}

.juegos-hero__titlebar-mirror {
  visibility: hidden;
  pointer-events: none;
}

.juegos-hero h2 {
  flex: 1 1 auto;
  margin: 0 auto;
  text-align: center;
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.25rem);
  max-width: 20ch;
}

/* aspect-ratio en vez de una altura fija: reserva el espacio exacto
   desde el primer layout (cero CLS al cargar la foto) y hace que el
   ancho:100% del marco escale a la altura correcta en cualquier viewport
   sin necesitar overrides por breakpoint. 2233/704 es la proporción REAL
   del archivo fuente (assets/img/juegos/banner-casino.webp, medida en
   vivo) — con eso object-fit:cover no tiene que recortar nada, coincide
   exacto con el marco. */
.juegos-hero__banner-frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-md);
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: linear-gradient(160deg, rgba(28, 21, 38, 0.75), rgba(15, 10, 22, 0.9));
  width: 100%;
  aspect-ratio: 2233 / 704;
  margin-top: var(--space-4);
}

.juegos-hero__banner {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;
}

.juegos-hero__text {
  margin-top: var(--space-3);
  color: var(--text-secondary);
  max-width: 46ch;
}

@media (max-width: 639px) {
  .juegos-hero__icon {
    width: 38px;
    height: 38px;
    margin-bottom: var(--space-3);
  }

  .juegos-hero__icon svg {
    width: 20px;
    height: 20px;
  }

  /* "Juegos" solo en Mobile: display:none (no visibility:hidden) saca
     tanto al eyebrow real como a su espejo del flujo flex — sin esto el
     espejo quedaría ocupando espacio a la derecha sin nada que
     balancear, o el hueco de "Juegos" seguiría reservado a la
     izquierda. Con los dos fuera, el h2 (único hijo visible de la fila,
     flex:1 1 auto + margin:0 auto) queda centrado por sí solo, sin
     necesitar la técnica del espejo (esa sigue existiendo intacta para
     Desktop, ver @media min-width:1024px). */
  .juegos-hero__titlebar .eyebrow {
    display: none;
  }

  /* Reducción sutil pedida (~6.25%, dentro del 5-8% sugerido): 16px base
     medido en vivo → 15px. line-height no necesita override propio —
     body usa un ratio sin unidad (1.6), así que se recalcula
     proporcional al nuevo font-size automáticamente. */
  .juegos-hero__text {
    font-size: 0.9375rem;
  }
}

/* ---------- Buscador ---------- */
.juegos-search {
  position: relative;
  margin-bottom: var(--space-5);
}

.juegos-search__icon {
  position: absolute;
  left: var(--space-4);
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--text-muted);
  pointer-events: none;
}

.juegos-search input {
  width: 100%;
  padding: 13px var(--space-4) 13px 44px;
  border-radius: var(--radius-full);
  background: rgba(28, 21, 38, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--text-primary);
  font-size: var(--fs-caption);
  font-family: inherit;
  transition: border-color var(--dur-standard) var(--ease-standard);
}

.juegos-search input::placeholder {
  color: var(--text-muted);
}

.juegos-search input:focus {
  outline: none;
  border-color: rgba(255, 215, 0, 0.35);
}

/* ---------- Categorías (chips) ----------
   Mismo mecanismo que .league-chip-row de Sportbook (scroll horizontal
   + snap proximity), pero copiado acá como clase propia — sin
   depender de sportbook.css. */
.juegos-category-row {
  display: flex;
  gap: var(--space-2);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-block: 2px;
  scrollbar-width: none;
  margin-bottom: var(--space-6);
}

.juegos-category-row::-webkit-scrollbar {
  display: none;
}

.juegos-category-chip {
  flex: 0 0 auto;
  scroll-snap-align: start;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  background: rgba(28, 21, 38, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
  transition: color var(--dur-standard) var(--ease-standard), border-color var(--dur-standard) var(--ease-standard),
    background var(--dur-standard) var(--ease-standard);
}

.juegos-category-chip.is-active {
  color: #1a1420;
  background: var(--gold-400);
  border-color: var(--gold-400);
}

/* ---------- Proveedores ----------
   Base compartida por todos los anchos: forma de la píldora (padding,
   border-radius, background, border), separación entre tarjetas (gap),
   flex:0 0 auto — nada de esto cambia con este pedido. overflow-x:auto
   se mantiene SIEMPRE (Mobile y Desktop): es lo que permite que el
   movimiento automático (juegos-provider-marquee.js, mueve scrollLeft
   con requestAnimationFrame, no una animación de transform) conviva
   con swipe/drag/click/trackpad nativos sin reimplementarlos — el
   usuario sigue arrastrando el mismo elemento scrolleable de siempre,
   la única diferencia es que además se mueve solo cuando nadie lo toca.
   scroll-snap se quita (antes x proximity acá, x mandatory en Desktop
   más abajo): un scroll continuo cuadro a cuadro y un motor de snap
   compiten por la posición de reposo y producen tirones — no hay
   forma de tener las dos cosas a la vez, y el pedido explícito es
   "continuo, suave, uniforme, sin saltos".

   Lo que muestra CADA chip por dentro (texto vs. logo) se resuelve en
   los dos media queries de abajo: <1024px (Mobile/tablet) y ≥1024px
   (Desktop) — mismo criterio de siempre, cada uno define su propio
   tamaño exterior fijo (ver comentario del bloque Mobile) y trata su
   imagen igual: 100%×100% del chip, sin padding. font-size/font-weight/
   color quedan acá para que el nombre (oculto solo visualmente en
   Mobile, ver .juegos-provider-chip__name más abajo) siga siendo el
   mismo texto de siempre para quien lo lea con lector de pantalla. */
.juegos-provider-row {
  display: flex;
  overflow-x: auto;
  padding-block: 2px;
  scrollbar-width: none;
}

.juegos-provider-row::-webkit-scrollbar {
  display: none;
}

/* .juegos-provider-track: envoltorio que arma juegos-render.js alrededor
   de los chips (antes vivían directo dentro de .juegos-provider-row) —
   el gap que antes tenía la fila se muda acá (con el track de por medio,
   el gap de la fila ya no tendría a quién separar: pasa a tener un solo
   hijo). En Desktop sigue siendo un simple contenedor flex "en línea",
   cero cambio de comportamiento — juegos-provider-marquee.js sigue
   leyendo scrollLeft/clientWidth/querySelector sobre la fila
   (data-juegos-providers no se movió), un nivel de anidamiento de más no
   afecta esas mediciones. En Mobile es lo que se anima con transform
   (ver @media max-width:1023px más abajo) — mismo mecanismo que
   .trust-bar__track del renglón informativo de Home. */
.juegos-provider-track {
  display: flex;
  gap: var(--space-2);
}

.juegos-provider-chip {
  flex: 0 0 auto;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-full);
  background: rgba(28, 21, 38, 0.42);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}

/* ---------- Proveedores — Mobile/tablet (<1024px) ----------
   Ajuste puntual de tamaño: el 81.5×37px anterior (ratio 2.2027:1) no
   coincidía con la relación de aspecto real de los logos — inspeccionado
   en vivo (canvas de cada .webp vía getImageData, no a ojo): 23 de 27
   proveedores reales son EXACTAMENTE 400×160 = 2.5:1, el resto (Play'n
   GO 3.125:1, Gamzix/CT Interactive 2.439:1, MrSlotty 2.484:1) está
   cerca de ese mismo valor. Con object-fit:cover, un chip 2.2:1
   recortaba ~14.75% de cada lado de esos logos dominantes — confirmado
   visualmente (Play'n GO se veía "LAY'n GO", con la P cortada).
   Corrección: ancho 81.5→92.5px (chip crece, no se achica — igualando
   el chip al ratio 2.5:1 de la imagen dominante), alto 37px SIN TOCAR
   (el desajuste era de proporción, no de tamaño absoluto — no hacía
   falta agrandar los dos ejes). Con esto el recorte desaparece por
   completo en los 23 logos 2.5:1 y se reduce (de ~35px a ~16px por
   lado, sobre un logo de 335px de "tinta" real) en el caso más extremo
   (Play'n GO) — eliminarlo del todo ahí exigiría subir a ~2.75:1,
   ensanchando innecesariamente el resto de la fila para un solo
   proveedor atípico, así que no vale ese costo visual. Desktop
   (más abajo) ya usa aspect-ratio:5/2 = 2.5:1 exacto — coincide con la
   imagen dominante desde antes (confirmado igual, sin recorte visible
   en Play'n GO tampoco ahí), así que no necesitó ningún cambio acá.

   object-fit:cover, position:relative+overflow:hidden en el chip e
   inset:-1px en el logo (compensa el border:1px del chip, mismo
   criterio que .sport-feature-card__inner): sin cambios, mismo
   mecanismo que ya usaba Desktop.

   .juegos-provider-chip__name sigue "visually-hidden" (mismo patrón
   que .visually-hidden de utilities.css, repetido acá para no
   depender de otro archivo): desaparece visualmente y deja de ocupar
   espacio en el layout, pero el texto sigue en el DOM — el chip
   entero (role="listitem", title=nombre) conserva su nombre accesible
   real para lectores de pantalla, no es solo el atributo title. */
@media (max-width: 1023px) {
  .juegos-provider-chip {
    flex: 0 0 92.5px;
    height: 37px;
    padding: 0;
    position: relative;
    overflow: hidden;
  }

  .juegos-provider-chip__logo {
    position: absolute;
    inset: -1px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: auto;
    height: auto;
    padding: 0;
    background: none;
  }

  .juegos-provider-chip__logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  /* Solo aplica a Foxi/Netgame (sin logo real confirmado, ver
     juegos-config.js) — mismo glyph placeholder de siempre, a un
     tamaño que respira dentro del chip fijo de 37px de alto. */
  .juegos-provider-chip__logo .game-card__placeholder-icon {
    width: 18px;
    height: 18px;
    color: var(--text-muted);
  }

  .juegos-provider-chip__name {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* ---------- Proveedores: marquee continuo — Mobile únicamente ----------
   Mismo sistema, mismo mecanismo, que el renglón informativo de Home
   Mobile (.trust-bar__track, ver components.css): .juegos-provider-row
   pasa de overflow-x:auto a overflow:hidden (deja de ser el contenedor
   que se arrastra) y .juegos-provider-track — que ya trae el set real +
   una copia exacta aria-hidden (ver juegos-render.js/
   data-provider-duplicate) — se anima transform: translateX(0) ->
   translateX(-50%) en loop infinito. Como el duplicado es pixel-idéntico
   al real, -50% cae exactamente sobre el punto de partida: el reinicio
   del loop es indistinguible de un frame más de la animación, igual que
   en el renglón informativo. CSS puro, sin JS corriendo por frame —
   juegos-provider-marquee.js (rAF + scrollLeft, pensado para el
   scroll-arrastrable nativo de Desktop) se desactiva a este ancho, ver
   guard al inicio de ese archivo.

   Velocidad — segunda revisión: 60px/s (ronda anterior) se siguió
   reportando lento en vivo. Medido de nuevo antes de tocar nada (pedido
   explícito, no cambiar animation-duration a ciegas): @390px el track
   mide 5821px totales → un grupo (el 50% que recorre el keyframe) mide
   2910.5px, igual que la ronda anterior — .juegos-provider-chip mide
   92.5px fijos (no vw), así que esta distancia NO depende del ancho de
   viewport, un animation-duration fijo alcanza para dar el mismo px/s
   en cualquier ancho Mobile (a diferencia de Ligas populares, donde el
   ancho de tarjeta SÍ es función de 100vw). Nueva velocidad objetivo:
   +50% sobre esos 60px/s → 90px/s. duración = distancia/velocidad =
   2910.5 / 90 ≈ 32.34s. Mismo valor en Desktop
   (juegos-provider-marquee.js, SPEED_PX_PER_SEC) para mantener
   Mobile/Desktop coherentes entre sí. linear (no ease): sin
   aceleración/desaceleración entre tarjetas. */
@media (max-width: 1023px) {
  .juegos-provider-row {
    overflow: hidden;
  }

  .juegos-provider-track {
    width: max-content;
    animation: juegos-provider-marquee 32.34s linear infinite;
    will-change: transform;
  }
}

/* translate3d (no translateX): fuerza capa de composición GPU en más
   motores/versiones que translateX solo — mismo resultado visual, más
   robusto en Android WebView viejos. */
@keyframes juegos-provider-marquee {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

@media (max-width: 1023px) and (prefers-reduced-motion: reduce) {
  .juegos-provider-track {
    animation: none;
  }
}

/* ---------- Proveedores — Desktop (≥1024px) ----------
   Carrusel real de 7 tarjetas completas simultáneas (pedido explícito),
   flechas ya heredadas gratis del componente compartido .carousel-nav.
   Track SIN padding-inline propio, así que NO hace falta compensar el
   padding en el flex-basis: calc((100% - 6*gap)/7) alcanza para que la
   7ª tarjeta termine justo en el borde. aspect-ratio (5/2, sin cambios
   desde el ajuste de altura anterior) garantiza mismo ancho/alto en
   las 7 sin depender de un px fijo. Nada de esto se toca en este
   pedido — "no modifiques ancho/alto/aspect-ratio/cantidad visible/
   gap/orden/carrusel/border-radius/posición" es exactamente lo que ya
   había, solo cambia el CONTENIDO interno de la tarjeta.

   Pedido nuevo: tarjeta = imagen completa, sin ícono ni título visibles.
   .juegos-provider-chip pasa de fila flex (ícono+nombre) a un simple
   contenedor position:relative + overflow:hidden (para que la imagen
   respete el border-radius sin sobresalir) y padding:0 (la imagen debe
   llegar a los 4 bordes internos). .juegos-provider-chip__logo (el logo
   real o, para los 2 proveedores sin logo confirmado — Foxi/Netgame,
   ver juegos-config.js — el ícono placeholder) pasa a llenar la
   tarjeta entera vía position:absolute+inset:0, en vez de la caja fija
   chica de antes. .juegos-provider-chip__name (el nombre) se oculta
   por completo acá — el nombre completo sigue disponible como tooltip
   nativo vía el atributo title en el <span> padre (juegos-render.js,
   sin tocar). La tarjeta NO era clickeable antes de este cambio (span
   role="listitem", sin ningún addEventListener en el proyecto) y sigue
   sin serlo — nada que preservar ahí, no se agregó ni quitó
   interactividad. */
@media (min-width: 1024px) {
  /* width:100% acá es lo que hace que el calc() de abajo (100% - 6*gap)
     siga resolviendo contra el ancho real de .juegos-provider-row
     (1232px dentro del .container de 1440px, por ejemplo) — igual que
     antes de que existiera este track intermedio. Sin este width
     explícito, .juegos-provider-track (flex item de la fila
     scrolleable, sin flex:1) se dimensiona por su propio contenido
     (shrink-to-fit): el 100% del calc() de cada chip pasaría a resolver
     contra ESE ancho indeterminado en vez del ancho real de la fila,
     achicando las 7 tarjetas (confirmado en vivo: 162.29px→158px sin
     este fix). overflow:visible por default en el track deja que sus
     58 chips (2 grupos) sigan desbordando ese 100% para que
     .juegos-provider-row los seguir scrolleando exactamente igual que
     antes — mismo mecanismo, con un nivel de anidamiento neutral de
     más. */
  .juegos-provider-track {
    flex: 0 0 100%;
    min-width: 100%;
    gap: var(--space-4);
  }

  .juegos-provider-chip {
    flex: 0 0 calc((100% - 6 * var(--space-4)) / 7);
    aspect-ratio: 5 / 2;
    display: block;
    padding: 0;
    border-radius: var(--radius-md);
    overflow: hidden;
    position: relative;
  }

  /* inset:-1px (no 0): .juegos-provider-chip hereda border:1px de la
     regla base — inset:0 posiciona esto contra la caja de padding (1px
     más angosta/baja que el border-box real), dejando una línea de 1px
     del borde/fondo de la tarjeta asomando en los 4 lados. -1px extiende
     esto exactamente esos 2px extra por eje para que su content-box
     iguale el border-box real — mismo criterio ya usado en
     .sport-feature-card__inner (sportbook.css). */
  .juegos-provider-chip__logo {
    position: absolute;
    inset: -1px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: auto;
    height: auto;
    padding: 0;
    border-radius: 0;
    background: none;
  }

  /* Solo aplica a Foxi/Netgame (sin logo real confirmado) — mismo
     glyph genérico de siempre, centrado, tamaño fijo razonable dentro
     de la tarjeta completa (ya no una caja chica de 28px). */
  .juegos-provider-chip__logo .game-card__placeholder-icon {
    width: 28px;
    height: 28px;
    color: var(--text-muted);
  }

  /* Logo real: object-fit:cover (no contain) — pedido explícito de que
     la imagen llegue a los 4 bordes sin espacios vacíos. Nunca deforma
     (cover preserva la proporción siempre); las fotos ya vienen
     recortadas ~2.5:1 (ver juegos-config.js), la misma proporción
     exacta de la tarjeta (aspect-ratio:5/2 = 2.5), así que en la
     mayoría no recorta nada real — solo el margen sub-px que pueda
     sobrar si algún archivo no calzó exacto. */
  .juegos-provider-chip__logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  .juegos-provider-chip__name {
    display: none;
  }
}

/* ---------- Tarjeta de juego ----------
   Mismo criterio que .sport-feature-card: foto a pantalla completa,
   sin ícono, degradado mínimo solo bajo el texto, nombre integrado.
   Clase propia (.game-card) — misma receta visual, cero dependencia de
   sportbook.css. */
.game-card {
  position: relative;
  flex: 0 0 auto;
  scroll-snap-align: start;
  cursor: pointer;
  transition: box-shadow var(--dur-standard) var(--ease-standard), transform var(--dur-standard) var(--ease-standard);
}

.game-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--elev-float), var(--elev-purple-glow);
}

.game-card__inner {
  position: absolute;
  inset: 0;
  transition: transform 480ms var(--ease-out-premium), opacity 480ms var(--ease-out-premium);
}

@media (max-width: 1023px) {
  .game-card__inner {
    opacity: 0.75;
  }

  .game-card.is-centered .game-card__inner {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .game-card__inner {
    transition: none;
  }
}

.game-card__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
  display: block;
}

.game-card__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(8, 5, 14, 0.88) 0%, rgba(8, 5, 14, 0.5) 38%, transparent 68%);
  pointer-events: none;
}

.game-card__badge {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 1;
  padding: 3px var(--space-2);
  border-radius: var(--radius-full);
  background: rgba(255, 215, 0, 0.16);
  border: 1px solid rgba(255, 215, 0, 0.35);
  color: var(--gold-400);
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.game-card__label {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-4);
  text-align: left;
}

.game-card__name {
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Superficie neutra para tarjetas sin imagen todavía (ver g.image en
   gameCardHtml, juegos-render.js) — degradado violeta/negro muy sutil
   + ícono "imagen" discreto, nada inventado ni genérico. Mismo <span>
   que después reemplaza un <img class="game-card__photo">: mismo
   inset:0 dentro de .game-card__inner, cero reestructuración cuando
   llegue la foto real. */
.game-card__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, rgba(139, 95, 191, 0.22), rgba(10, 7, 16, 0.94));
}

.game-card__placeholder-icon {
  width: 22%;
  height: 22%;
  color: rgba(255, 255, 255, 0.22);
}

/* ---------- Carrusel Pragmatic ----------
   A diferencia de .game-row (grilla que envuelve en Desktop, pensada
   para mostrar TODO el set a la vez), esto es un carrusel real en
   cualquier ancho — reutiliza tal cual el motor compartido
   carousel.js/.carousel-track (mismo contrato que ya usan Servicios/
   Bonos/Mejores Juegos de Home y "Deportes destacados" de Sportbook:
   flechas con estado disabled en los extremos, scroll nativo con
   snap, trackpad/drag gratis por ser overflow-x real). Ancho de
   tarjeta FIJO (no calc() atado a "encajar N tarjetas"): agregar más
   juegos a pragmaticPlaceholders solo agrega más scroll, nunca rompe
   el layout ni exige tocar este CSS — así es como se sostiene
   "10, 20, 30 o más sin reconstruir". select .game-card (no el .card
   share) para pisar con más especificidad las reglas de .game-row de
   abajo sin afectarlas (esos selectores son .game-row .game-card /
   bare .game-card dentro de sus propios @media — un .game-card que
   vive dentro de .game-carousel jamás matchea .game-row .game-card,
   así que no hay conflicto real, solo hace falta ganarle a la regla
   bare con selectores más específicos acá). */
.game-carousel .game-card {
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
}

/* Mobile: EXACTAMENTE 4 tarjetas completas por pantalla (pedido
   explícito — reemplaza el ancho fijo que traía antes). Misma técnica
   ya usada en Deportes destacados/Destacados-Juegos para "N tarjetas
   sin fragmentos": flex-basis en % del content-box del track (el % ya
   excluye el padding-inline propio del contenedor) + el padding-right
   sumado de vuelta, porque el recorte de overflow-x ocurre en el
   border-box (que sí lo incluye) — sin sumarlo, la 4ª tarjeta queda
   justo en el borde del content-box y deja un hueco por el que asoma
   un fragmento de la 5ª. gap más chico que el resto de la vista
   (var(--space-2) en vez de --space-3) a propósito: con 4 tarjetas en
   ~360-430px de ancho útil, cada px de gap/padding recortado es un px
   más de tarjeta real — es el "mejor equilibrio" pedido sin llegar a
   verse apretado. */
@media (max-width: 639px) {
  .game-carousel {
    gap: var(--space-2);
    padding-inline: var(--space-4);
    scroll-padding-inline: var(--space-4);
    margin-inline: calc(var(--space-4) * -1);
  }

  /* Sin este bloque, la regla bare ".game-card" de más abajo (el
     snap agrupado de a 3 de .game-row) también matchea las tarjetas
     de acá — mismo selector, más específico gana: se repite acá
     flex/scroll-snap-align con el selector compuesto para que este
     carrusel quede con snap POR TARJETA (el comportamiento real de
     carousel.js en cualquier otro carrusel del sitio), no agrupado. */
  .game-carousel .game-card {
    flex: 0 0 calc((100% + var(--space-4) - (3 * var(--space-2))) / 4);
    scroll-snap-align: start;
  }
}

@media (min-width: 640px) {
  .game-carousel .game-card {
    width: 190px;
  }
}

/* Desktop (≥1024px): EXACTAMENTE 7 tarjetas completas por carrusel
   (pedido explícito) — pisa el ancho fijo de 190px de arriba (mayor
   especificidad de cascada por venir después con el mismo selector;
   flex-basis además le gana a "width" en un flex item). Se define acá,
   en el selector COMPARTIDO ".game-carousel .game-card" — no hay
   overrides por proveedor: como cada carrusel de proveedor
   (providerCarouselHtml en juegos-render.js) usa exactamente esta
   misma clase, cualquier proveedor nuevo hereda el 7-visible
   automáticamente, sin tocar este archivo. Misma técnica que ya usa el
   4-up de Mobile arriba y el carrusel de Proveedores: flex-basis en %
   del content-box del track + 1 padding-inline del track (2px, el de
   .carousel-track base — acá NO hay truco full-bleed de margen
   negativo, así que el ajuste es mínimo) sumado de vuelta para que la
   7ª tarjeta termine justo en el borde real de recorte, sin que asome
   un fragmento de la 8ª. Mismo gap que ya trae .carousel-track base
   (var(--space-4)) — no se pisa. Breakpoint 1024px (no 640px) a
   propósito: coincide con el que ya usa el carrusel de "Proveedores"
   para su propio Desktop — un solo criterio de "qué es Desktop" en
   toda la vista. Entre 640-1023px (tablet) se mantiene el ancho fijo
   de 190px + aspect-ratio 4/5 de arriba, sin tocar.

   Nota: la reducción de altura −40% pedida en un momento para estas
   tarjetas se corrigió y en realidad correspondía a la tarjeta de
   "Proveedores" (.juegos-provider-chip, arriba) — estas tarjetas de
   juego vuelven a heredar sin overrides el aspect-ratio 4/5 de la
   regla base de más arriba, igual que antes de ese cambio. */
@media (min-width: 1024px) {
  .game-carousel .game-card {
    width: auto;
    flex: 0 0 calc((100% + 2px - (6 * var(--space-4))) / 7);
  }
}

/* ---------- Filas de juegos: Mobile (carrusel 4-up) ----------
   Mismo mecanismo ya construido para Deportes destacados: flex-basis
   responsive (sin fórmulas por breakpoint), gap chico, snap agrupado
   de a 4 (:nth-child(4n+1)) para que cada swipe avance un grupo
   completo. Pedido explícito: 4 tarjetas completas (antes 3) — mismo
   selector bare .game-row/.game-card cubre Destacados
   (.game-row--destacados) Y Casino en vivo por igual, así que un solo
   cambio acá ya les da a las dos el mismo sistema dimensional
   coherente pedido, sin duplicar reglas. */
@media (max-width: 639px) {
  .game-row {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-inline: var(--space-4);
    scroll-padding-inline: var(--space-4);
    margin-inline: calc(var(--space-4) * -1);
    scrollbar-width: none;
  }

  .game-row::-webkit-scrollbar {
    display: none;
  }

  .game-card {
    flex: 0 0 calc((100% + var(--space-4) - (3 * var(--space-2))) / 4);
    aspect-ratio: 4 / 5;
    border-radius: var(--radius-md);
    overflow: hidden;
    scroll-snap-align: none;
  }

  .game-card:nth-child(4n + 1) {
    scroll-snap-align: start;
  }

  .game-card:hover {
    transform: none;
  }

  .game-card__label {
    padding: var(--space-2);
  }

  .game-card__name {
    font-size: 0.75rem;
    line-height: 1.25;
  }

  .game-card__badge {
    top: var(--space-2);
    left: var(--space-2);
    font-size: 0.5625rem;
    padding: 2px 6px;
  }
}

/* ---------- Filas de juegos: ≥640px (grid, envuelve) ----------
   A diferencia de Deportes destacados (9 elementos fijos, una sola
   fila), acá el conteo real varía por sección (Casino en vivo: 3) —
   un grid que envuelve es la solución honesta, no forzar una fila de
   9 con contenido que no la llena. */
@media (min-width: 640px) {
  .game-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: var(--space-4);
  }

  .game-card {
    width: auto;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius-md);
    overflow: hidden;
  }

  .game-card__name {
    font-size: 0.875rem;
  }
}

@media (min-width: 1024px) {
  .game-row--destacados {
    grid-template-columns: repeat(9, 1fr);
  }

  .game-card__inner {
    opacity: 1;
  }
}

/* Centrado explícito con flex (no solo text-align) — el renglón entero
   (no solo el texto) queda centrado en los dos ejes: justify-content
   para el horizontal, align-items para el vertical dentro de su
   propia altura. padding-block simétrico (antes solo padding-top, el
   texto quedaba pegado al border-top sin aire debajo) es lo que
   define esa altura — con eso el "renglón" deja de ser solo la línea
   de texto y pasa a ser un bloque real con arriba/abajo equilibrado.
   width:100% explícito para que nunca dependa de un ancho implícito
   heredado del contenedor. */
.juegos-legal-notice {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: var(--space-6);
  padding-block: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  text-align: center;
  color: var(--text-muted);
  font-size: clamp(0.5625rem, 0.52rem + 0.3vw, 0.75rem);
  line-height: 1.4;
  white-space: nowrap;
}


@media (min-width: 1024px) {
  .juegos-view__content {
    padding-top: var(--space-8);
  }

  .juegos-section {
    margin-bottom: var(--space-8);
  }

  .juegos-section__header h2 {
    font-size: 1.375rem;
  }

  .juegos-hero__icon {
    width: 44px;
    height: 44px;
    margin-bottom: var(--space-3);
  }

  .juegos-hero__icon svg {
    width: 22px;
    height: 22px;
  }

  .juegos-hero__banner-frame {
    margin-top: var(--space-5);
  }

  /* max-width:20ch (heredado de la Mobile base) es el que forzaba el
     salto "Miles de juegos, / una sola cuenta" — acá en Desktop sobra
     espacio de sobra (fila ≈1000px+ disponibles para el h2 solo), así
     que se saca el tope y se fuerza una sola línea con nowrap. */
  .juegos-hero h2 {
    max-width: none;
    white-space: nowrap;
  }

  .juegos-hero__text {
    margin-top: var(--space-4);
    max-width: none;
    white-space: nowrap;
  }
}

@media (prefers-reduced-motion: reduce) {
  .juegos-view {
    transition: none;
  }
}
