/**
 * Premioplus — Components
 * Componentes reutilizables. Cada bloque es independiente y consume
 * únicamente variables de tokens.css.
 */

/* ---------- Eyebrow / Kicker ---------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold-500);
}

.eyebrow::before {
  content: "";
  width: 18px;
  height: 2px;
  background: var(--gold-500);
  border-radius: var(--radius-full);
}

/* ---------- Section Title ---------- */
.section-title {
  max-width: 640px;
  margin-bottom: var(--space-7);
}

/* En mobile, los títulos de sección (izquierda o centrados) podían
   envolver lo bastante ancho como para que su última línea rozara el
   rincón inferior derecho, justo donde viven los FABs fijos de
   contacto, durante el tramo de scroll en el que cada sección entra en
   pantalla. Reserva ese ancho para que el texto envuelva antes de esa
   zona — aplica al texto, no a los FABs ni a su posición. */
@media (max-width: 639px) {
  .section-title {
    max-width: calc(100% - 70px);
    /* 48px (heredado del valor de escritorio) antes de que arranque
       cada grilla de tarjetas era más de lo que el título necesita para
       separarse del contenido — bajarlo acerca la primera tarjeta a la
       pantalla donde ya se lee el título, en vez de dejarla fuera del
       primer scroll. */
    margin-bottom: var(--space-5);
  }
}

.section-title h2 {
  margin-top: var(--space-3);
}

.section-title p {
  margin-top: var(--space-4);
  font-size: var(--fs-body-lg);
  color: var(--text-secondary);
  max-width: 60ch;
}

.section-title--center {
  margin-inline: auto;
  text-align: center;
}

.section-title--center .eyebrow {
  justify-content: center;
}

.section-title--center p {
  margin-inline: auto;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-4) var(--space-6);
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: transform var(--dur-standard) var(--ease-standard),
    box-shadow var(--dur-standard) var(--ease-standard),
    background var(--dur-standard) var(--ease-standard);
}

.btn:active {
  transform: scale(0.97);
}

.btn-gold {
  background: var(--grad-gold-cta);
  color: var(--text-on-gold);
  box-shadow: var(--elev-2);
}

.btn-gold:hover,
.btn-gold:focus-visible {
  box-shadow: var(--elev-gold-glow);
  transform: translateY(-2px);
}

.btn-ghost {
  background: transparent;
  color: var(--text-primary);
  border: 1.5px solid rgba(255, 255, 255, 0.25);
}

.btn-ghost:hover,
.btn-ghost:focus-visible {
  border-color: var(--gold-500);
  background: rgba(255, 215, 0, 0.06);
  transform: translateY(-2px);
}

/* Mismo motivo que .card: sin mouse real no hay hover que "sueltes" al
   alejarte, así que el lift de estos botones podía quedar pegado tras un
   tap. En touch el único feedback es el :active ya existente. */
@media (hover: none) {
  .btn-gold:hover {
    box-shadow: var(--elev-2);
    transform: none;
  }

  .btn-ghost:hover {
    border-color: rgba(255, 255, 255, 0.25);
    background: transparent;
    transform: none;
  }
}

.btn-block {
  width: 100%;
}

/* Botones más redondeados en móvil — el mismo giro "app nativa" que el
   radio de tarjeta ya recibe ahí, aplicado también al componente de
   acción principal. Desktop/tablet no se tocan. */
@media (max-width: 639px) {
  .btn {
    border-radius: 14px;
  }
}

/* Variante compacta — pensada para vivir dentro de una tarjeta chica
   (service-card) en vez de como CTA principal de una sección; mismo
   lenguaje visual (mismo radius, mismo peso de fuente), solo con menos
   presencia para no competir con el título/párrafo que tiene al lado. */
.btn-sm {
  min-height: 40px;
  padding: var(--space-3) var(--space-5);
  font-size: var(--fs-caption);
}

.btn[disabled] {
  opacity: 0.4;
  pointer-events: none;
}

.btn-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  object-fit: contain;
}

.cta-microcopy {
  font-size: var(--fs-caption);
  color: var(--text-muted);
  margin-top: var(--space-3);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
}

/* ---------- Navbar ---------- */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  height: 80px;
  display: flex;
  align-items: center;
  background: transparent;
  transition: background var(--dur-standard) var(--ease-standard),
    box-shadow var(--dur-standard) var(--ease-standard),
    backdrop-filter var(--dur-standard) var(--ease-standard);
}

.navbar.is-scrolled {
  background: var(--bg-glass);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  box-shadow: var(--elev-2);
}

.navbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.navbar__logo {
  display: flex;
  align-items: baseline;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.35rem;
  color: var(--text-primary);
}

.navbar__logo [data-bind="brand-accent"] {
  color: var(--gold-500);
}

.navbar__links {
  display: flex;
  gap: var(--space-6);
}

.navbar__links a {
  font-size: var(--fs-caption);
  font-weight: 500;
  color: var(--text-secondary);
  transition: color var(--dur-micro) var(--ease-standard);
}

.navbar__links a:hover {
  color: var(--text-primary);
}

.navbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/* El CTA del header hereda el mismo tamaño de .btn que un CTA de sección
   completa (48px alto, padding 16/32px) — al lado de un logo de 1.35rem
   eso pesaba más de lo que le corresponde a un botón de encabezado.
   Escalado propio, solo acá: mismo color/tipografía/ícono/animación de
   .btn-gold, proporciones más finas para quedar en equilibrio óptico
   con el logo en vez de competir con él. */
.navbar__actions .btn {
  min-height: 42px;
  padding: var(--space-3) var(--space-5);
  gap: 6px;
  font-size: 0.9375rem;
}

/* En mobile el texto ("WhatsApp") ya está oculto (.navbar__cta-label,
   más abajo) — el botón queda como un ícono solo, pero conservaba el
   padding lateral pensado para acompañar texto, lo que lo dejaba como
   una píldora ancha y desproporcionada al lado del logo. Achica solo
   el padding horizontal (el alto de 42px no se toca) para un botón
   más cuadrado, proporcionado a un ícono de 18px. */
@media (max-width: 1023px) {
  .navbar__actions .btn {
    padding-inline: 14px;
  }
}

/* En mobile los FABs flotantes de WhatsApp/Telegram (esquina inferior
   derecha) ya cubren el contacto rápido — este botón queda redundante.
   Se oculta solo acá; en tablet/desktop sigue exactamente igual. Sin
   segundo hijo en .navbar__actions, el gap que separaba el botón del
   menú hamburguesa no tiene contra qué aplicarse, así que no hace
   falta tocar nada más para que quede equilibrado: el logo sigue a la
   izquierda y el burger solo a la derecha, con el mismo
   justify-content: space-between de .navbar__inner de siempre. */
@media (max-width: 639px) {
  .navbar__actions .btn {
    display: none;
  }
}

.navbar__actions .btn-icon {
  width: 18px;
  height: 18px;
}

.navbar__burger {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
}

.navbar__burger span,
.navbar__burger span::before,
.navbar__burger span::after {
  content: "";
  display: block;
  width: 20px;
  height: 2px;
  background: var(--text-primary);
  position: relative;
  transition: transform var(--dur-standard) var(--ease-standard);
}

.navbar__burger span::before {
  position: absolute;
  top: -6px;
}

.navbar__burger span::after {
  position: absolute;
  top: 6px;
}

@media (max-width: 1023px) {
  .navbar__links {
    display: none;
  }
  .navbar__burger {
    display: inline-flex;
  }
  .navbar__cta-label {
    display: none;
  }
}

/* ---------- Mobile menu drawer ----------
   Panel lateral de alto completo (100dvh) con el lenguaje visual de
   Comparativa (gradiente violeta/dorado 160deg, glow, superficie casi
   opaca para máxima legibilidad — ver nota de opacidad más abajo).
   Geometría recta a propósito: arriba/derecha/abajo ya están a ras del
   viewport (right:0, top:0, height:100dvh) y el borde visible — el que
   de verdad separa el panel del contenido — es el izquierdo, así que
   border-radius queda en 0 en las cuatro esquinas ("panel que nace del
   borde de la pantalla", no una tarjeta flotante). Ese mismo borde
   izquierdo concentra el marco: más ancho/opaco que antes + un glow
   doble (violeta ambiente + dorado ajustado) — como las otras tres
   caras están pegadas al borde físico del viewport, ese glow es
   invisible ahí y solo se nota (a propósito) del lado visible.
   overscroll-behavior:contain evita que un swipe que llega al tope/pie
   del listado de links haga "scroll chaining" hacia el body de atrás
   (el bloqueo real de scroll, necesario para iOS, vive en nav.js — ver
   lockScroll/unlockScroll). */
.mobile-menu {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  height: 100dvh;
  width: 76vw;
  max-width: 340px;
  padding: calc(80px + env(safe-area-inset-top, 0px) + var(--space-4)) 0
    calc(env(safe-area-inset-bottom, 0px) + var(--space-4));
  overflow: hidden auto;
  overscroll-behavior: contain;
  background: linear-gradient(160deg, rgba(255, 215, 0, 0.05), rgba(59, 7, 100, 0.55)), rgba(20, 16, 28, 0.97);
  border-left: 1.5px solid rgba(255, 215, 0, 0.42);
  border-radius: 0;
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  box-shadow: var(--elev-float), 0 0 36px rgba(139, 95, 191, 0.26), 0 0 18px rgba(255, 215, 0, 0.1);
  display: flex;
  flex-direction: column;
  gap: 0;
  transform: translateX(100%);
  transition: transform var(--dur-standard) var(--ease-out-premium);
  z-index: 95;
}

.mobile-menu.is-open {
  transform: translateX(0);
}

/* Scrim a pantalla completa: separa el panel del contenido y también
   funciona como superficie de cierre (nav.js le agrega un click
   listener) — cualquier toque en la franja visible de fondo cae acá.
   Mismo criterio tonal que .benefit-sheet-backdrop (rgba sobre
   --bg-base), pero más sutil: "sin oscurecer demasiado la landing". */
.mobile-menu-overlay {
  position: fixed;
  inset: 0;
  background: rgba(8, 5, 14, 0.5);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-standard) var(--ease-out-premium), visibility 0s linear var(--dur-standard);
  z-index: 90;
}

.mobile-menu-overlay.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--dur-standard) var(--ease-out-premium), visibility 0s linear;
}

.mobile-menu a {
  display: flex;
  align-items: center;
  /* Renglón de ancho completo (no un chip aislado): el padding
     horizontal vive en el link, no en la tarjeta, para que el fondo de
     :active/:hover llegue de borde a borde (el overflow:hidden de
     arriba lo recorta contra el radio de la tarjeta). El borde inferior
     separa cada opción sin convertir el menú en una tabla — el último
     link no lo lleva. */
  width: 100%;
  padding: 15px 20px;
  border-bottom: 1px solid rgba(139, 95, 191, 0.22);
  font-family: var(--font-display);
  /* Peso bajado de 700 a 600 + tracking leve: el 700 a 17px se sentía
     "genérico"/pesado. 600 con letter-spacing lee más fino y preciso
     (registro fintech), sin perder el contraste que da el fondo casi
     opaco de la tarjeta. */
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.02em;
  line-height: 1.5;
  color: var(--text-primary);
  transition: background var(--dur-micro) var(--ease-standard);
}

.mobile-menu a:last-child {
  border-bottom: none;
}

.mobile-menu a:active {
  background: rgba(139, 95, 191, 0.16);
}

@media (hover: hover) {
  .mobile-menu a:hover {
    background: rgba(139, 95, 191, 0.09);
  }
}

/* ---------- Bottom Navigation (solo mobile) ----------
   Reemplaza el menú superior en mobile — mismas 6 secciones/anclas que
   .navbar__links y .mobile-menu, ningún link nuevo. En desktop/tablet no
   existe (el nav horizontal de arriba ya cumple esa función ahí). En
   mobile es la barra de navegación primaria, fija abajo — la zona que
   el pulgar alcanza sin esfuerzo, el mismo patrón que Revolut/Coinbase/
   Robinhood usan para sus 4-6 secciones principales. */
.bottom-nav {
  display: none;
}

@media (max-width: 639px) {
  .bottom-nav {
    display: grid;
    /* Columnas iguales (no flex+justify-around): cada ítem recibe
       exactamente el mismo ancho de área táctil, sin importar cuánto
       texto tenga su etiqueta — "separación uniforme" real, no solo
       aproximada. 7 (no 6): la columna 4 queda RESERVADA/vacía para el
       botón Home central — los 6 accesos reales se reubican
       explícitamente a las columnas 1-3 y 5-7 (ver
       .bottom-nav a[href] más abajo), así el auto-placement del grid
       nunca ocupa la 4ª. Esa columna vacía es lo que evita la
       superposición real medida en vivo a 320px cuando el botón (46px,
       position:absolute + left:50%, ver .bottom-nav__home) flotaba
       centrado SIN espacio propio reservado: sus bordes invadían el
       área táctil de "Juegos" y "Bonos". Con la columna 4 vacía,
       Home cae exactamente sobre esa reserva, sin invadir a sus
       vecinos en ningún ancho. */
    grid-template-columns: repeat(7, 1fr);
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 55;
    /* Vidrio oscuro integrado a la paleta — no un blanco/gris genérico
       de plantilla: mismo tono base que --bg-elevated, con blur real
       encima del contenido que sigue scrolleando detrás. */
    background: rgba(15, 11, 21, 0.88);
    backdrop-filter: blur(20px) saturate(150%);
    -webkit-backdrop-filter: blur(20px) saturate(150%);
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    /* safe-area real: en un iPhone con home-indicator, el padding extra
       evita que la barra (y su primer renglón de toque) quede debajo
       del gesto de sistema. En equipos sin notch, env() resuelve a 0. */
    padding: 6px 2px calc(6px + env(safe-area-inset-bottom)) 2px;
  }

  .bottom-nav a {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: 48px;
    /* min-width:0 es la pieza que faltaba en los 2 intentos previos de
       "columnas iguales" (justify-items:stretch en el contenedor no
       tenía ningún efecto medible). Cada 1fr de grid en realidad es
       minmax(auto,1fr) — el "auto" mínimo de CADA columna se calcula
       por el min-content de su ítem, y el span de la etiqueta tiene
       white-space:nowrap (para el ellipsis), así que su min-content ES
       su ancho de texto completo: "Beneficios" empujaba su columna
       entera a ~55px mientras "FAQ" la dejaba en ~39px, con columnas
       nominalmente "iguales". min-width:0 anula ese piso automático en
       el ítem de grid (el mismo problema/arreglo que existe en flex),
       dejando que las 7 columnas se repartan realmente parejas y cada
       ítem se estire (justify-items normal = stretch) a su ancho real. */
    min-width: 0;
    margin: 0 2px;
    padding: 6px 2px;
    border-radius: 14px;
    color: var(--text-muted);
    transition: color var(--dur-micro) var(--ease-standard),
      background var(--dur-micro) var(--ease-standard),
      transform var(--dur-micro) var(--ease-standard);
  }

  /* Ubicación explícita por columna (1-3 y 5-7, saltando la 4ª
     reservada para Home) — por href, no por nth-child: robusto aunque
     el orden real en el DOM cambie (Home hoy vive entre Juegos y Bonos
     por motivos de foco/lectura de pantalla, no de columna visual). */
  .bottom-nav a[href="#beneficios"] {
    grid-column: 1;
  }
  .bottom-nav a[href="#servicios"] {
    grid-column: 2;
  }
  .bottom-nav a[href="#juegos"] {
    grid-column: 3;
  }
  .bottom-nav a[href="#bonos"] {
    grid-column: 5;
  }
  .bottom-nav a[href="#sportbook"] {
    grid-column: 6;
  }
  .bottom-nav a[href="#faq"] {
    grid-column: 7;
  }

  .bottom-nav a svg {
    width: 21px;
    height: 21px;
    flex-shrink: 0;
    transition: transform var(--dur-micro) var(--ease-standard);
  }

  .bottom-nav a span {
    font-family: var(--font-body);
    font-size: 0.5625rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
  }

  .bottom-nav a:active {
    transform: scale(0.94);
  }

  /* Estado "sección actual" — el mismo lenguaje de una tab bar nativa,
     asignado por bottom-nav.js vía IntersectionObserver mientras el
     usuario scrollea. Un fondo suave detrás del ítem completo (no solo
     el color del ícono) es lo que hace que se sienta "seleccionado",
     no solo resaltado. */
  .bottom-nav a.is-current {
    color: var(--gold-400);
    background: rgba(255, 215, 0, 0.12);
  }

  .bottom-nav a.is-current svg {
    transform: translateY(-1px) scale(1.05);
  }

  /* Botón Home central: redondo, mismo diámetro/radio que .fab en
     Mobile (46px, ver más abajo en este archivo) — misma "sensación" de
     botón flotante, tomando .fab como referencia dimensional explícita
     (pedido puntual), sin copiar sus colores de marca (WhatsApp/
     Telegram) porque Home no es un CTA de contacto: reutiliza la
     paleta dorada ya existente (--grad-gold-cta) en vez de inventar un
     color nuevo.

     Contorno difuminado — misma técnica real que .fab-telegram (la
     referencia elegida, ver ese bloque más abajo): --elev-3 (la sombra
     oscura genérica que ya comparten los 3 botones) + un border 1px
     al 40% de alfa en el color propio del botón, en vez de un
     box-shadow con blur direccional. Antes acá había --elev-gold-glow
     (un blur asimétrico desplazado 8px hacia abajo, alfa 0.18) — se
     veía, pero no como un halo parejo alrededor del contorno, que es
     justo lo que .fab-telegram sí logra con su border simple. No se
     tocó el token --elev-gold-glow en sí (lo siguen usando otros 4
     lugares del proyecto), solo se dejó de referenciar acá.

     position:absolute + left:50% + translateX(-50%) (no grid-column
     placement): sacado del flujo del grid a propósito. Los otros 6
     ítems no se estiran parejo a su columna (su ancho sale de su
     propio texto — "Beneficios" pesa bastante más que "FAQ" — medido
     en vivo incluso con justify-items:stretch forzado), así que
     depender de "columna 4 de 7" dejaba el botón ~10px corrido del
     centro geométrico real de la barra. Centrado absoluto contra el
     ancho total de `.bottom-nav` (que si es simétrico: padding-inline
     igual a los dos lados) es inmune a esa asimetría — geométricamente
     exacto sin importar cómo midan los otros 6. bottom (no margin-top
     negativo) lo sube por encima del resto de la barra, mismo lenguaje
     que un FAB central de tab bar nativa, sin alterar la altura de
     `.bottom-nav` ni la posición de los demás ítems. */
  .bottom-nav a.bottom-nav__home {
    position: absolute;
    left: 50%;
    /* top negativo (no bottom): sube el botón por encima del borde
       superior de la barra sin necesitar saber su alto real (que varía
       con env(safe-area-inset-bottom)) — top:-16px + height:46px deja
       16px asomando arriba de la barra y 30px superpuestos adentro,
       mismo resultado visual que se buscaba con el margin-top negativo
       original, sin la dependencia de grid-stretch que causaba el
       descentrado. */
    top: -16px;
    transform: translateX(-50%);
    flex-direction: row;
    width: 46px;
    height: 46px;
    min-height: 46px;
    margin: 0;
    padding: 0;
    border-radius: var(--radius-full);
    background: var(--grad-gold-cta);
    color: var(--text-on-gold);
    border: 1px solid rgba(255, 215, 0, 0.4);
    box-shadow: var(--elev-3);
  }

  .bottom-nav a.bottom-nav__home:active {
    transform: translateX(-50%) scale(0.94);
  }

  .bottom-nav a.bottom-nav__home svg {
    width: 24px;
    height: 24px;
  }

  /* Estado activo coherente con el resto (mismo mecanismo de
     bottom-nav.js, sin JS nuevo) pero expresado como un aro en vez del
     fondo tenue dorado que usan los otros 6 — ese fondo ya ES el color
     base de este botón, así que un aro es la única forma de que
     "activo" siga leyéndose distinto de "en reposo". */
  .bottom-nav a.bottom-nav__home.is-current {
    background: var(--grad-gold-cta);
    box-shadow: var(--elev-3), 0 0 0 2px rgba(255, 255, 255, 0.55);
  }

  .bottom-nav a.bottom-nav__home.is-current svg {
    transform: none;
  }
}

/* ---------- Benefit sheet (tarjeta flotante centrada, solo mobile) ----------
   Panel compartido (uno solo en el DOM, benefit-sheet.js lo repuebla en
   cada toque) que muestra ícono+título+descripción completa de un
   beneficio — el destino de la interacción de .benefits-grid .feature-
   card en mobile. No existe en desktop/tablet: ahí el texto ya está
   siempre visible en la tarjeta, este panel no tiene función.

   Misma familia visual que las tarjetas principales del Hero
   (.trust-card, que es un .card sin modificar): mismo vidrio neutro
   (rgba(28,21,38,.66) + blur 20px), mismo borde blanco fino
   (rgba(255,255,255,.08)), misma sombra flotante (--elev-float) y el
   mismo radio de 20px que cualquier .card recibe en mobile — nada de
   la calidez dorada/violeta que sí usa Onboarding. Se abandona el
   ::after de borde degradado (era una firma de Onboarding, no de
   Hero) a cambio de un borde real, igual que trust-card. */
.benefit-sheet-backdrop,
.benefit-sheet {
  display: none;
}

@media (max-width: 639px) {
  .benefit-sheet-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(8, 5, 14, 0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-standard) var(--ease-out-premium);
  }

  .benefit-sheet-backdrop.is-open {
    opacity: 1;
    pointer-events: auto;
  }

  /* width: calc(100% - 96px) — 48px de margen lateral por lado (antes
     32px): más aire, tarjeta más angosta y equilibrada, nunca "casi
     todo el ancho del teléfono". */
  .benefit-sheet {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    position: fixed;
    left: 50%;
    top: 50%;
    z-index: 201;
    width: calc(100% - 96px - env(safe-area-inset-left) - env(safe-area-inset-right));
    max-width: 340px;
    max-height: min(560px, calc(100vh - 96px - env(safe-area-inset-top) - env(safe-area-inset-bottom)));
    max-height: min(560px, calc(100dvh - 96px - env(safe-area-inset-top) - env(safe-area-inset-bottom)));
    overflow-y: auto;
    border-radius: 20px;
    padding: var(--space-6) var(--space-5);
    background: rgba(28, 21, 38, 0.66);
    backdrop-filter: blur(20px) saturate(150%);
    -webkit-backdrop-filter: blur(20px) saturate(150%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: var(--elev-float);
    transform: translate(-50%, -50%) scale(0.92);
    opacity: 0;
    pointer-events: none;
    transition: transform var(--dur-standard) var(--ease-out-premium),
      opacity var(--dur-standard) var(--ease-out-premium);
  }

  .benefit-sheet.is-open {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
    pointer-events: auto;
  }

  .benefit-sheet__close {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-secondary);
    transition: background var(--dur-micro) var(--ease-standard),
      transform var(--dur-micro) var(--ease-standard);
  }

  .benefit-sheet__close:active {
    transform: scale(0.92);
    background: rgba(255, 255, 255, 0.12);
  }

  .benefit-sheet__close svg {
    width: 16px;
    height: 16px;
  }

  /* Fondo del círculo teñido con el propio color de categoría del
     ícono (coral/dorado/violeta/cian/verde azulado/verde) — el mismo
     lenguaje que .trust-card__icon--jackpot/--games (círculo con un
     tinte translúcido de su color, no un fondo neutro parejo).
     color-mix() resuelve currentColor (fijado por la clase icon-* que
     benefit-sheet.js ya aplica); el declarativo anterior es el
     fallback si el navegador no soporta color-mix(). */
  .benefit-sheet__icon {
    width: 60px;
    height: 60px;
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-elevated);
    background: color-mix(in srgb, currentColor 14%, transparent);
    margin-top: var(--space-2);
    margin-bottom: var(--space-4);
    flex-shrink: 0;
  }

  .benefit-sheet__icon svg {
    width: 28px;
    height: 28px;
  }

  /* font-weight 600, no 700: la misma corrección "más fino, más
     preciso" que ya se aplicó a .trust-card__value — un titular en
     bold completo se sentía más pesado que el resto del lenguaje
     tipográfico mobile del Hero. */
  .benefit-sheet__title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.25rem;
    color: var(--text-primary);
    margin-bottom: var(--space-3);
  }

  .benefit-sheet__text {
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--text-secondary);
  }
}

@media (max-width: 639px) and (prefers-reduced-motion: reduce) {
  .benefit-sheet {
    transition: opacity var(--dur-standard) var(--ease-standard);
    transform: translate(-50%, -50%) scale(1);
  }

  .benefit-sheet-backdrop {
    transition: none;
  }
}

/* ---------- Age gate (verificación de edad, +18) ----------
   A diferencia de benefit-sheet/mobile-drawer (que arrancan cerrados y
   una clase "is-open" los abre), este componente arranca VISIBLE por
   defecto — debe bloquear desde el primer paint, sin esperar a ningún
   JS diferido (ver el script anti-flash en <head> de index.html y
   "html:not([data-age-gate-skip]) body" en base.css). age-gate.js
   agrega "is-dismissed" recién cuando corresponde ocultarlo (SÍ
   confirmado, con transición) o lo retira directo del DOM.

   Mismo lenguaje visual que .card/.benefit-sheet (vidrio translúcido +
   blur(20px) saturate(150%) + --elev-float), con acento dorado propio
   (borde + --elev-gold-glow) prestado de .bonus-card--featured — se
   siente como una tarjeta premium del propio sistema, no un alert
   genérico. z-index 300/301: por encima de bottom-nav (100), FABs (60)
   y benefit-sheet (200/201), el tope real de la app. Sin scope de
   ancho: a diferencia de benefit-sheet (mobile-only), este cartel debe
   verse igual de bien en Desktop. */
/* Fast-path: sessionStorage ya traía la confirmación de esta sesión
   (marcado por el script anti-flash en <head>, antes de este CSS
   pintar nada) — el gate nunca llega a existir visualmente. */
html[data-age-gate-skip] .age-gate-backdrop,
html[data-age-gate-skip] .age-gate {
  display: none;
}

.age-gate-backdrop {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(8, 5, 14, 0.74);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 1;
  transition: opacity var(--dur-standard) var(--ease-out-premium);
}

.age-gate {
  position: fixed;
  inset: 0;
  z-index: 301;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: max(var(--space-5), env(safe-area-inset-top))
    max(var(--space-5), env(safe-area-inset-right))
    max(var(--space-5), env(safe-area-inset-bottom))
    max(var(--space-5), env(safe-area-inset-left));
  opacity: 1;
  transition: opacity var(--dur-standard) var(--ease-out-premium);
}

/* pointer-events:none evita que el overlay, ya invisible, siga
   interceptando clics durante el fade de salida. */
.age-gate-backdrop.is-dismissed,
.age-gate.is-dismissed {
  opacity: 0;
  pointer-events: none;
}

/* Sin display:flex acá (a diferencia de .age-gate arriba): con
   align-items:center en el padre, un panel flex-item se encoge a su
   propio contenido en el eje cruzado en vez de ocupar el ancho
   disponible, y .age-gate__actions (100% más abajo) quedaría midiendo
   el 100% de ESE ancho encogido, no el del panel real. text-align
   centra el contenido inline (badge, título, párrafos) sin ese
   problema — cada hijo de bloque (incluida .age-gate__actions) ya toma
   el ancho completo por comportamiento default de bloque. */
.age-gate__panel {
  width: 100%;
  max-width: 400px;
  max-height: min(640px, calc(100vh - 2 * var(--space-5)));
  max-height: min(640px, calc(100dvh - 2 * var(--space-5)));
  overflow-y: auto;
  text-align: center;
  border-radius: var(--radius-lg);
  padding: var(--space-6) var(--space-5);
  background: linear-gradient(160deg, rgba(255, 215, 0, 0.07), rgba(28, 21, 38, 0.86));
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid rgba(255, 215, 0, 0.28);
  box-shadow: var(--elev-float), var(--elev-gold-glow);
  outline: none;
  transform: scale(1) translateY(0);
  transition: transform var(--dur-standard) var(--ease-out-premium),
    opacity var(--dur-standard) var(--ease-out-premium);
}

.age-gate.is-dismissed .age-gate__panel {
  transform: scale(0.94) translateY(12px);
  opacity: 0;
}

.age-gate__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  margin-bottom: var(--space-4);
  background: rgba(255, 215, 0, 0.14);
  background: color-mix(in srgb, var(--gold-500) 16%, transparent);
  border: 1px solid rgba(255, 215, 0, 0.35);
  color: var(--gold-400);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
}

/* Estado bloqueado (tocó NO): mismo círculo, tinte rojo de --error en
   vez de dorado — señal semántica de "denegado" sin salir de la
   paleta del sitio ni recurrir a un ícono nuevo. */
.age-gate__badge--blocked {
  background: rgba(239, 68, 68, 0.14);
  background: color-mix(in srgb, var(--error) 16%, transparent);
  border-color: rgba(239, 68, 68, 0.35);
  color: var(--error);
}

.age-gate__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.375rem;
  color: var(--text-primary);
  margin-bottom: var(--space-3);
}

.age-gate__text {
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--text-secondary);
  margin-bottom: var(--space-4);
}

.age-gate__question {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--text-primary);
  margin-bottom: var(--space-5);
}

.age-gate__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: 100%;
}

/* white-space:normal (el .btn base es nowrap): "Sí, soy mayor de 18"
   nunca debe truncarse ni forzar el layout a desbordar en el mobile
   más angosto pedido (320px) — mejor que envuelva a 2 líneas antes que
   perder texto o comprimir tipografía (pedido explícito: no reducir
   el texto para que "entre" horizontal). */
.age-gate__btn {
  white-space: normal;
  line-height: 1.3;
}

/* Desktop (y tablet en adelante): lado a lado si la composición lo
   permite, con flex:1 para que ambos midan exactamente lo mismo — el
   único requisito real es "misma dimensión física", no "mismo layout
   en todos los anchos". */
@media (min-width: 640px) {
  .age-gate__actions {
    flex-direction: row;
  }

  .age-gate__actions .age-gate__btn {
    flex: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .age-gate-backdrop,
  .age-gate,
  .age-gate__panel {
    transition: opacity var(--dur-standard) var(--ease-standard);
  }

  .age-gate.is-dismissed .age-gate__panel {
    transform: none;
  }
}

/* ---------- Badge ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 4px 10px;
  border-radius: var(--radius-full);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.badge-gold {
  background: rgba(255, 215, 0, 0.14);
  color: var(--gold-400);
  border: 1px solid rgba(255, 215, 0, 0.3);
}

.badge-live {
  background: rgba(239, 68, 68, 0.14);
  color: #ff8a8a;
  border: 1px solid rgba(239, 68, 68, 0.35);
}

.badge-live::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--error);
  animation: pulse-dot 1.6s ease-in-out infinite;
}

@keyframes pulse-dot {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.4;
  }
}

@media (prefers-reduced-motion: reduce) {
  .badge-live::before {
    animation: none;
  }
}

/* ---------- Card base ---------- */
.card {
  /* Vidrio translúcido en vez de un color sólido: el glow de fondo se
     insinúa levemente a través de la tarjeta, reforzando que está
     flotando EN la atmósfera del --grad-sky, no pintada encima de ella. */
  background: rgba(28, 21, 38, 0.66);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border-radius: var(--radius-md);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: var(--elev-float);
  /* overflow:hidden no recorta el propio box-shadow (eso solo afecta a
     hijos/contenido) — pero sí es necesario para que el glow de
     cursor-fx.js no se salga de las esquinas redondeadas. */
  overflow: hidden;
  transition: transform var(--dur-standard) var(--ease-standard),
    box-shadow var(--dur-standard) var(--ease-standard),
    border-color var(--dur-standard) var(--ease-standard),
    background-color var(--dur-standard) var(--ease-standard);
}

/* Ahora que el fondo de sección ya no es un bloque sólido, las tarjetas
   necesitan su propio feedback de hover más allá de la sombra — un tinte
   de superficie sutil refuerza que "flotan" sobre --grad-sky. */
.card:hover {
  background: rgba(36, 27, 51, 0.78);
  border-color: rgba(255, 255, 255, 0.14);
}

/* En touch no existe un mouseleave real: el estado :hover puede quedar
   "pegado" en la tarjeta después de tocarla hasta que el usuario toca
   otra cosa. hover:none aísla justo ese caso (cualquier dispositivo sin
   puntero de precisión, sin importar el ancho) y lo reemplaza por un
   :active breve — el mismo lenguaje de feedback táctil que .btn:active
   y .fab:active en el resto del sitio. Los dispositivos con mouse real
   (hover:hover) no ven ningún cambio: siguen exactamente igual. */
@media (hover: none) {
  .card:hover {
    background: rgba(28, 21, 38, 0.66);
    border-color: rgba(255, 255, 255, 0.08);
  }

  .card:active {
    background: rgba(36, 27, 51, 0.78);
    border-color: rgba(255, 255, 255, 0.14);
    transform: scale(0.985);
  }
}

/* Radio más grande en móvil — el mismo lenguaje "app" de las referencias
   fintech premium (Revolut/Coinbase: esquinas muy redondeadas en cada
   tarjeta protagonista) aplicado sobre el sistema de --radius existente,
   sin crear un token nuevo. Los layouts tipo lista (Beneficios, pasos de
   Onboarding/Referidos) ya fijan su propio border-radius:0 y quedan
   intactos. */
@media (max-width: 639px) {
  .card {
    border-radius: 20px;
    transition: transform var(--dur-standard) var(--ease-standard),
      background var(--dur-standard) var(--ease-standard),
      border-color var(--dur-standard) var(--ease-standard),
      box-shadow var(--dur-standard) var(--ease-standard);
  }
}

/* ---------- Glow que sigue al cursor (cursor-fx.js) ----------
   .media-card vive en otro archivo pero comparte este mismo lenguaje de
   iluminación — es a propósito, es el "sistema unificado de
   interacciones" pedido: el mismo brillo violeta/dorado seguido de
   cursor en cualquier tarjeta de la landing, sin importar qué contenido
   tenga adentro. mix-blend-mode en vez de un overlay plano: se funde con
   lo que hay debajo (foto, video, vidrio) en lugar de taparlo con un
   círculo de color. service-card ya hereda esto de .card (misma clase),
   sin necesitar su propia entrada acá. */
.card,
.media-card {
  position: relative;
}

.card::before,
.media-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  background: radial-gradient(260px circle at var(--mx, 50%) var(--my, 50%), rgba(255, 215, 0, 0.16), rgba(139, 95, 191, 0.1) 45%, transparent 70%);
  opacity: 0;
  transition: opacity 400ms ease;
  pointer-events: none;
  mix-blend-mode: overlay;
}

.has-glow::before {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .card::before,
  .media-card::before {
    display: none;
  }
}

/* ---------- Feature / Benefit card ----------
   Mismo padding y tamaño de texto que service-card__body (sections.css):
   antes esta tarjeta era más pesada que las de Servicios (32px de padding
   + párrafo a 1rem vs 24px + 0.875rem) — se notaba como una familia de
   componente distinta en vez de la misma. Ícono más chico por la misma
   razón: 52px llamaba más la atención de la que le corresponde a un
   soporte visual dentro de una tarjeta compacta. */
.feature-card {
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Envuelve h3+p (antes hijos directos de .feature-card) para poder
   reflowarlos como fila ícono+texto en mobile sin tocar el layout de
   escritorio. El gap que antes venía del flex del padre (aplicaba
   parejo entre ícono→h3 y h3→p) se replica acá mismo para ambos, así
   que el espaciado interno queda idéntico en cualquier ancho. */
.feature-card__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.feature-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--elev-purple-glow);
  border-color: rgba(139, 95, 191, 0.35);
}

@media (hover: none) {
  .feature-card:hover {
    transform: none;
    box-shadow: var(--elev-float);
    border-color: rgba(255, 255, 255, 0.08);
  }

  .feature-card:hover .feature-card__icon {
    transform: none;
  }

  .feature-card:active {
    transform: scale(0.985);
  }
}

.feature-card__icon {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-elevated);
  transition: transform var(--dur-standard) var(--ease-standard);
}

.feature-card:hover .feature-card__icon {
  transform: scale(1.1);
}

.feature-card__icon svg {
  width: 20px;
  height: 20px;
}

.feature-card h3 {
  font-size: 1.125rem;
}

.feature-card p {
  font-size: var(--fs-caption);
  color: var(--text-secondary);
}

/* Colores de icono por categoría */
.icon-coral { color: var(--cat-coral); }
.icon-gold { color: var(--gold-500); }
.icon-purple { color: var(--cat-purple); }
.icon-cyan { color: var(--cat-cyan); }
.icon-teal { color: var(--cat-teal); }
.icon-green { color: var(--cat-green); }
/* Verde "premium" deliberadamente distinto del --cat-green brillante de
   arriba (Seguridad y licencia): reutiliza --success, el mismo verde
   discreto que ya usan los chips "Creciendo" de trust-card — la misma
   semántica de disponibilidad/actividad, no un tono nuevo inventado. */
.icon-emerald { color: var(--success); }
.icon-blue { color: var(--info); }

/* ---------- Trust bar ----------
   Una sola línea, fina, tipo Stripe/Apple/Linear: el peso lo dan el
   orden y el espaciado, no el tamaño. flex-wrap:nowrap fuerza una única
   fila siempre — en vez de romper a dos renglones en pantallas angostas,
   la fila se vuelve una tira deslizable (overflow-x:auto), el mismo
   patrón que usan esas marcas para franjas de logos/confianza en mobile.
   Separadores verticales finos entre ítems en vez de gaps grandes: es lo
   que permite que los 7 elementos convivan en una sola línea sin leerse
   apretados, y aporta la sensación de "componente" más que de "fila de
   etiquetas sueltas". */
.trust-bar {
  position: relative;
  padding-block: 20px;
  border-block: 1px solid rgba(255, 255, 255, 0.06);
  overflow: visible;
}

.trust-bar__row {
  display: flex;
  align-items: center;
  /* safe center: centra cuando entra completo (desktop). En anchos donde
     la fila desborda y se vuelve deslizable, "unsafe" center la abriría
     con el scroll ya a mitad de camino — ni el primer ni el último ítem
     visibles ni alcanzables sin saber que hay que scrollear para ambos
     lados. "safe" cae a alineación al inicio en ese caso, para que la
     tira siempre arranque mostrando el primer ítem completo. */
  justify-content: safe center;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}

.trust-bar__row::-webkit-scrollbar {
  display: none;
}

/* .trust-bar__track / .trust-bar__group: envoltorios que agrega
   render.js para el marquee continuo de Mobile (ver bloque @media
   max-width:639px más abajo). En Desktop/Tablet no cambian nada: el
   track y el primer grupo son simples flex containers "en línea" con
   los mismos ítems de siempre, y el segundo grupo (copia exacta para
   el loop, ver render.js) se oculta acá mismo — fuera del media query
   mobile — para que >=640px quede pixel-idéntico a como estaba antes. */
.trust-bar__track {
  display: flex;
  align-items: center;
}

.trust-bar__group {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.trust-bar__group:nth-child(2) {
  display: none;
}

.trust-bar__item {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  padding-inline: 18px;
  position: relative;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: color var(--dur-standard) var(--ease-standard);
}

.trust-bar__item:first-child {
  padding-left: 0;
}

.trust-bar__item:last-child {
  padding-right: 0;
}

/* Separador óptico entre ítems — sutil, no una línea dura — en vez de
   gap para poder controlar el padding de cada lado de forma pareja. */
.trust-bar__item:not(:first-child)::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 1px;
  height: 13px;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.1);
}

.trust-bar__item:hover {
  color: var(--text-primary);
}

.trust-bar__item svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

/* ---------- Trust bar: marquee continuo — Mobile únicamente ----------
   Pedido explícito: movimiento horizontal continuo y constante, loop
   realmente seamless (sin salto visible al reiniciar), sin tocar
   textos/orden/tipografía/colores ni la posición general del renglón,
   sin afectar Desktop, y respetando prefers-reduced-motion.

   Mecanismo: el track trae el grupo real + una copia exacta (aria-hidden,
   ver render.js) y se anima transform: translateX(0) -> translateX(-50%)
   en loop infinito. Como el contenido está EXACTAMENTE duplicado, -50%
   cae pixel a pixel sobre el mismo punto de partida — el reinicio del
   loop es indistinguible de un frame más de la animación. */
@media (max-width: 639px) {
  .trust-bar__row {
    overflow: hidden;
    /* flex-start (no "safe center"): el track es más ancho que la fila
       a propósito (2 grupos), así que translateX(0) tiene que coincidir
       con el borde izquierdo real de la fila para que la animación
       arranque exactamente donde el renglón arrancaba antes de esto. */
    justify-content: flex-start;
  }

  .trust-bar__group:nth-child(2) {
    display: flex;
  }

  /* Costura grupo1 -> grupo2: sin este ajuste, el último ítem real
     (padding-right:0 por :last-child) queda pegado al primero del
     duplicado (padding-left:0 por :first-child), sin separador — un
     salto de espaciado visible una vez por vuelta. Se les da el mismo
     padding/separador que cualquier otro par de ítems consecutivos, sin
     tocar el borde inicial/final real del contenido (esos se quedan
     como estaban). */
  .trust-bar__group:nth-child(1) .trust-bar__item:last-child {
    padding-right: 18px;
  }

  .trust-bar__group:nth-child(2) .trust-bar__item:first-child {
    padding-left: 18px;
  }

  .trust-bar__group:nth-child(2) .trust-bar__item:first-child::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 1px;
    height: 13px;
    transform: translateY(-50%);
    background: rgba(255, 255, 255, 0.1);
  }

  .trust-bar__track {
    width: max-content;
    animation: trust-bar-marquee 30s linear infinite;
    will-change: transform;
  }
}

@keyframes trust-bar-marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (max-width: 639px) and (prefers-reduced-motion: reduce) {
  .trust-bar__track {
    animation: none;
  }
}

/* ---------- Stats / Counters ---------- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-5);
}

@media (max-width: 639px) {
  .stats-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.stat {
  text-align: center;
  padding: var(--space-5);
}

.stat__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.2rem + 1.8vw, 2.5rem);
  color: var(--gold-500);
}

.stat__label {
  margin-top: var(--space-2);
  font-size: var(--fs-caption);
  color: var(--text-muted);
}

/* ---------- Comparison ----------
   Mismo radio de borde que .card (--radius-md, no el --radius-lg que
   tenía antes) y mismo gap que el resto de los grids de la landing
   (--space-5): son dos columnas grandes, no tarjetas chicas, pero deben
   sentirse cortadas con la misma tijera que trust-stats-grid/
   services-grid para leerse como el mismo sistema. Padding y tipografía
   también bajan un escalón (48px→32px, 1rem→0.9375rem) para no pesar
   más que Servicios, que es la referencia de "liviano" pedida. */
.comparison {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}

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

.comparison__col {
  border-radius: var(--radius-md);
  padding: var(--space-6);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  box-shadow: var(--elev-float);
}

.comparison__col--others {
  background: rgba(20, 16, 28, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.06);
  order: 2;
}

.comparison__col--superpro {
  background: linear-gradient(160deg, rgba(255, 215, 0, 0.08), rgba(59, 7, 100, 0.4));
  border: 1px solid rgba(255, 215, 0, 0.25);
  order: 1;
}

.comparison__col h3 {
  font-size: 1.125rem;
  margin-bottom: var(--space-4);
}

.comparison__col--others h3 {
  color: var(--text-muted);
}

.comparison__col--superpro h3 {
  color: var(--gold-400);
}

.comparison__list li {
  display: flex;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.9375rem;
}

.comparison__list li:first-child {
  border-top: none;
}

.comparison__list svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
}

.comparison__col--others svg {
  color: var(--text-muted);
}

.comparison__col--superpro svg {
  color: var(--success);
}

.comparison__col--others li {
  color: var(--text-muted);
}

.comparison__col--superpro li {
  color: var(--text-primary);
}

/* En mobile las dos columnas se apilan (ya no hay "izquierda/derecha"
   para jugar con order:1/2 como en desktop) — pero el order:initial
   volvía al orden del DOM, que arranca con "Otras plataformas" (la
   comparación negativa, en gris) antes que "Con SuperPro" (la
   destacada, con el marco dorado). Empezar con la fortaleza propia es
   mejor narrativa y mejor jerarquía visual: lo destacado arriba, lo
   atenuado después — mismo contenido, mismo texto, solo el orden de
   lectura. */
@media (max-width: 767px) {
  .comparison__col--superpro {
    order: 1;
  }
  .comparison__col--others {
    order: 2;
  }
}

/* Comparativa mobile compacta — mismo criterio de "pantalla completa"
   que Cómo empezar / Referidos: solo UNA columna se ve por vez
   (comparison-toggle.js), así que lo que hay que comprimir es el
   padding interno de esa columna + sus 4 líneas de lista, que son el
   contenido con más peso vertical de toda la sección (~72px c/u, ~288px
   en total). line-height baja de 1.6 (heredado de body, pensado para
   párrafos largos) a 1.4 — de sobra para fragmentos cortos de 2 líneas,
   sin sentirse apretado. Este bloque va DESPUÉS de las reglas base de
   arriba a propósito: misma especificidad que ellas, así que solo así
   el cascade lo deja ganar en mobile (antes vivía arriba y las reglas
   base, más abajo en el archivo, lo pisaban siempre). */
@media (max-width: 639px) {
  .comparison__col {
    border-radius: 20px;
    padding: 20px;
  }

  .comparison__col h3 {
    font-size: 1.0625rem;
    margin-bottom: var(--space-3);
  }

  .comparison__list li {
    gap: var(--space-2);
    padding-block: 7px;
    font-size: 0.875rem;
    line-height: 1.4;
  }
}

/* ---------- Comparison toggle (segmented control, solo mobile) ----------
   En desktop/tablet ambas columnas conviven siempre lado a lado — tiene
   sentido, hay espacio para comparar de un vistazo. En mobile, apiladas,
   son ~650px de scroll pasivo antes de llegar a Bonos: la misma tabla
   de escritorio, solo girada. Un segmented control (mismo patrón que un
   selector de plan en Revolut/Robinhood) deja ver una columna por vez —
   mismo contenido exacto, ahora una decisión activa del usuario en vez
   de scroll pasivo, y la sección ocupa la mitad del alto. */
.comparison__toggle {
  display: none;
}

@media (max-width: 639px) {
  .comparison__toggle {
    display: flex;
    gap: 4px;
    padding: 4px;
    border-radius: var(--radius-full);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    margin-bottom: var(--space-4);
  }

  .comparison__toggle button {
    flex: 1;
    padding: 10px var(--space-3);
    border-radius: var(--radius-full);
    font-family: var(--font-body);
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-muted);
    text-align: center;
    transition: background var(--dur-standard) var(--ease-standard),
      color var(--dur-standard) var(--ease-standard);
  }

  .comparison__toggle button[aria-selected="true"] {
    background: rgba(255, 215, 0, 0.12);
    color: var(--gold-400);
    box-shadow: 0 0 0 1px rgba(255, 215, 0, 0.25);
  }

  .comparison__col.is-inactive {
    display: none;
  }
}

/* ---------- Step cards (Referidos / Cómo empezar) ---------- */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
  position: relative;
}

@media (max-width: 767px) {
  .steps {
    grid-template-columns: 1fr;
    gap: var(--space-7);
  }
}

@media (max-width: 639px) {
  /* 48px entre 3 pasos ya achicados (fila número+texto) era más vacío
     del que el contenido necesita para leerse como una secuencia. */
  .steps {
    gap: var(--space-4);
  }
}

.step-card {
  position: relative;
  padding: var(--space-6);
}

.step-card__number {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.25rem;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--gold-500);
  line-height: 1;
}

.step-card h3 {
  margin-top: var(--space-4);
}

/* .step-card__copy envuelve h3+p (necesario para poder reflowar a fila
   en mobile sin tocar el layout de escritorio, donde el margin-top de
   arriba sigue colapsando a través del wrapper hacia el número, igual
   que antes). El gap de acá adentro reemplaza al margin-top que tenía
   el párrafo. */
.step-card__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* En mobile los 3 pasos pasaban de una fila de 3 a una columna de 3
   cajas altas (número arriba, título, texto abajo) — mismo layout de
   escritorio, solo girado. De costado (número a la izquierda, copy a
   la derecha) cada paso ocupa menos alto y se lee más como una lista
   de instrucciones que como tres tarjetas sueltas, sin perder el marco
   dorado que ya identifica a este componente. */
@media (max-width: 767px) {
  .step-card {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-4);
  }

  .step-card__number {
    flex-shrink: 0;
  }

  .step-card h3 {
    margin-top: 0;
  }
}

@media (max-width: 639px) {
  /* 32px de padding (heredado del layout de escritorio, tarjeta
     vertical) es demasiado para una fila compacta número+texto. */
  .step-card {
    padding: var(--space-4);
  }
}

/* ---------- Referral panel (Sistema de referidos) ----------
   Antes el título, los 3 pasos y el botón vivían sueltos directamente
   sobre --grad-sky, cada uno con su propio ritmo — se leía como tres
   piezas cerca una de otra, no como un módulo. Ahora todo vive dentro
   de un único panel premium: mismo radio grande que .cta-banner (la
   otra "tarjeta contenedora" que ya existe en la landing), mismo
   lenguaje de sombra flotante que el resto de las .card, pero con un
   marco propio — borde dorado casi imperceptible + vidrio sutil — para
   que se sienta exclusivo sin gritarlo. */
.referral-panel {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-7);
  background: linear-gradient(165deg, rgba(59, 7, 100, 0.32) 0%, rgba(23, 0, 34, 0.6) 55%, rgba(10, 7, 16, 0.7) 100%);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  /* Borde iluminado extremadamente sutil: dorado a muy baja opacidad en
     vez de un contorno gris genérico — aporta jerarquía "premium" sin
     leerse como un marco grueso. */
  border: 1px solid rgba(255, 215, 0, 0.16);
  box-shadow: var(--elev-float), 0 0 56px rgba(139, 95, 191, 0.1);
}

.referral-panel__glow {
  position: absolute;
  inset: -25%;
  background: radial-gradient(circle at 18% 12%, rgba(255, 215, 0, 0.09), transparent 45%),
    radial-gradient(circle at 82% 88%, rgba(139, 95, 191, 0.16), transparent 50%);
  pointer-events: none;
}

.referral-panel .section-title,
.referral-panel .steps,
.referral-panel .referral-panel__cta {
  position: relative;
  z-index: 1;
}

/* Los 3 pasos ya no llevan la caja de vidrio completa de .card — eso
   se leía como "tarjetas sobre una tarjeta" dentro del panel. En su
   lugar, cada paso lleva SOLO un borde dorado muy fino (1px, opacidad
   baja) para que los tres se identifiquen de un vistazo sin volver a
   pesar como cajas independientes. El borde es un degradado sutil
   —más luminoso arriba-izquierda, más apagado abajo-derecha— logrado
   con la técnica de mask (content-box XOR border-box): un anillo real,
   no un truco de sombra, así el radio queda perfectamente uniforme en
   las cuatro esquinas. Vive en ::after (no ::before) porque ese
   pseudo-elemento ya lo usa el glow de cursor heredado de .card. */
.referral-panel .step-card {
  position: relative;
  background: rgba(255, 215, 0, 0.025);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: none;
  border-radius: var(--radius-md);
  box-shadow: 0 0 26px rgba(255, 215, 0, 0.05);
  padding: var(--space-6) var(--space-5);
  transition: transform var(--dur-standard) var(--ease-standard), box-shadow var(--dur-standard) var(--ease-standard);
}

.referral-panel .step-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.55) 0%, rgba(255, 215, 0, 0.14) 45%, rgba(255, 215, 0, 0.34) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.referral-panel .step-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 0 34px rgba(255, 215, 0, 0.1);
}

.referral-panel .step-card:hover::after {
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.8) 0%, rgba(255, 215, 0, 0.24) 45%, rgba(255, 215, 0, 0.55) 100%);
}

.referral-panel__cta {
  justify-content: center;
  margin-top: var(--space-8);
}

@media (max-width: 767px) {
  .referral-panel {
    padding: var(--space-7) var(--space-5);
  }

  .referral-panel__cta {
    margin-top: var(--space-6);
  }
}

/* ---------- Onboarding panel (Cómo empezar) ----------
   Mismo tratamiento que .referral-panel, a propósito duplicado en vez
   de reutilizar esa clase: Onboarding necesita su propio marco premium
   (título + pasos, sin botón) sin tocar ni un carácter del HTML/CSS de
   Referidos. Si en algún momento el marco premium se usa en una tercera
   sección, vale la pena extraerlo a una clase compartida — hoy, dos
   usos casi idénticos con contenido distinto, se mantienen separados
   para no arriesgar la otra sección al tocar esta. */
.onboarding-panel {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-7);
  background: linear-gradient(165deg, rgba(59, 7, 100, 0.32) 0%, rgba(23, 0, 34, 0.6) 55%, rgba(10, 7, 16, 0.7) 100%);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid rgba(255, 215, 0, 0.16);
  box-shadow: var(--elev-float), 0 0 56px rgba(139, 95, 191, 0.1);
}

.onboarding-panel__glow {
  position: absolute;
  inset: -25%;
  background: radial-gradient(circle at 18% 12%, rgba(255, 215, 0, 0.09), transparent 45%),
    radial-gradient(circle at 82% 88%, rgba(139, 95, 191, 0.16), transparent 50%);
  pointer-events: none;
}

.onboarding-panel .section-title,
.onboarding-panel .steps {
  position: relative;
  z-index: 1;
}

.onboarding-panel .step-card {
  position: relative;
  background: rgba(255, 215, 0, 0.025);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border: none;
  border-radius: var(--radius-md);
  box-shadow: 0 0 26px rgba(255, 215, 0, 0.05);
  padding: var(--space-6) var(--space-5);
  transition: transform var(--dur-standard) var(--ease-standard), box-shadow var(--dur-standard) var(--ease-standard);
}

.onboarding-panel .step-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.55) 0%, rgba(255, 215, 0, 0.14) 45%, rgba(255, 215, 0, 0.34) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.onboarding-panel .step-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 0 34px rgba(255, 215, 0, 0.1);
}

.onboarding-panel .step-card:hover::after {
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.8) 0%, rgba(255, 215, 0, 0.24) 45%, rgba(255, 215, 0, 0.55) 100%);
}

@media (max-width: 767px) {
  .onboarding-panel {
    padding: var(--space-7) var(--space-5);
  }
}

/* Mismo giro "app" que el resto de las tarjetas en móvil (radio mayor),
   más el mismo ajuste de hover:none que .card: sin mouse real el
   translateY(-3px) de arriba podía quedar pegado tras un tap. */
@media (max-width: 639px) {
  .onboarding-panel .step-card,
  .referral-panel .step-card {
    border-radius: 20px;
  }

  /* 48px/24px (heredado de la regla ≤767) seguía siendo demasiado marco
     alrededor de 3 filas ya compactas — un panel "contenedor premium"
     no necesita tanto aire propio además del que ya separa cada paso. */
  .onboarding-panel,
  .referral-panel {
    padding: var(--space-6) var(--space-4);
  }
}

@media (hover: none) {
  .onboarding-panel .step-card:hover,
  .referral-panel .step-card:hover {
    transform: none;
    box-shadow: 0 0 26px rgba(255, 215, 0, 0.05);
  }

  .onboarding-panel .step-card:hover::after,
  .referral-panel .step-card:hover::after {
    background: linear-gradient(135deg, rgba(255, 215, 0, 0.55) 0%, rgba(255, 215, 0, 0.14) 45%, rgba(255, 215, 0, 0.34) 100%);
  }

  .onboarding-panel .step-card:active,
  .referral-panel .step-card:active {
    transform: scale(0.985);
  }
}

/* ---------- Carousel ---------- */
.carousel-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-6);
}

.carousel-nav {
  display: flex;
  gap: var(--space-2);
  opacity: 1;
  transition: opacity var(--dur-standard) var(--ease-standard);
}

.carousel-nav__btn {
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background: rgba(28, 21, 38, 0.55);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--dur-standard) var(--ease-standard), transform var(--dur-micro);
}

.carousel-nav__btn:hover {
  background: rgba(36, 27, 51, 0.75);
}

.carousel-nav__btn:disabled {
  opacity: 0.35;
  pointer-events: none;
}

.carousel-nav__btn svg {
  width: 18px;
  height: 18px;
}

.carousel-track {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  overflow-y: visible;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding-block: var(--space-2) var(--space-4);
  padding-inline: 2px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.carousel-track::-webkit-scrollbar {
  display: none;
}

.carousel-track > * {
  scroll-snap-align: start;
  flex: 0 0 auto;
}

@media (max-width: 639px) {
  .carousel-nav {
    display: none;
  }
}

/* ---------- Carousel dots (opcional, hoy solo Servicios mobile) ----------
   Indicador mínimo a propósito ("no quiero controles grandes, la propia
   interacción táctil debe ser protagonista"): puntos de 4px que apenas
   crecen y se iluminan en dorado para el activo. Oculto salvo donde se
   pide explícitamente en mobile — en desktop/tablet no existe ningún
   carrusel de este tipo, así que queda display:none por defecto. */
.carousel-dots {
  display: none;
}

.carousel-dots__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.18);
  transition: background var(--dur-standard) var(--ease-standard),
    transform var(--dur-standard) var(--ease-standard),
    width var(--dur-standard) var(--ease-standard);
}

.carousel-dots__dot.is-active {
  width: 16px;
  background: var(--gold-400);
}

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

/* ---------- Carousel peek hint (compartido, Mobile) ----------
   Señal de "esto se desliza" para cualquier carrusel marcado con
   [data-peek-hint] (ver carousel-peek-hint.js): al entrar en viewport,
   la primera tarjeta recibe esta clase una sola vez y vuelve a
   quitársela sola al terminar. `translate` (no `transform`): compone
   sin pisar el transform inline que carousel.js ya escribe en
   [data-carousel-fx] para la tarjeta activa donde ese efecto existe
   (Servicios/Bonos). Genérico a propósito — un solo lugar para los 5
   carruseles que hoy usan este hint, nada de reglas duplicadas por
   sección. */
@media (max-width: 639px) {
  .is-peeking {
    animation: carousel-peek-hint 900ms var(--ease-out-premium);
  }
}

@keyframes carousel-peek-hint {
  0%,
  100% {
    translate: 0 0;
  }
  35% {
    translate: -22px 0;
  }
  65% {
    translate: 4px 0;
  }
}

@media (max-width: 639px) and (prefers-reduced-motion: reduce) {
  .is-peeking {
    animation: none;
  }
}

/* ---------- Game / Sportbook card ----------
   Mismo ancho y proporción que la tarjeta de Deportes (antes 200px /
   3:4 acá vs 180px / 4:5 en .media-card--sport): las dos filas de
   tarjetas ahora comparten exactamente el mismo tamaño, así que
   .media-card--sport ya no necesita sobreescribir nada — queda la regla
   por claridad, pero es redundante con estos valores. */
.media-card {
  position: relative;
  width: 180px;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--bg-surface);
  box-shadow: var(--elev-2);
  isolation: isolate;
}

.media-card__visual {
  position: absolute;
  inset: 0;
  transition: transform 400ms var(--ease-out-premium);
}

.media-card__visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Mismo tratamiento de color que las fotos de service-card: desatura y
   oscurece un toque para que una foto real (Fútbol/Básquet/Tenis) no se
   lea como un recurso pegado encima del sistema violeta de la landing,
   sino como parte de la misma colección — el usuario no debe notar que
   viene de una carpeta distinta a la del resto del sitio. */
/* Más fuerte que el filtro de service-card a propósito: estas fotos
   vienen de tres fuentes muy distintas en luminosidad/saturación (una
   silueta a contraluz, un gimnasio oscuro, un retrato a pleno sol) — un
   filtro "estándar" dejaba la de tenis notablemente más clara y viva que
   las otras dos. Empujar más fuerte el brillo y la saturación hacia
   abajo nivela las tres a la misma temperatura sin tocar el recorte ni
   el encuadre elegido. */
/* Corregido: 0.8 de brillo acá, encima del propio brillo/sombra ya
   apagados de cada foto real (estadio nublado, ring oscuro, etc.),
   apagaba demasiado el detalle. El ajuste de exposición/sombras real
   ahora vive en el archivo (grading por imagen, distinto en cada una) —
   este filtro compartido solo aporta la integración final con la
   paleta del sitio, ya no hace el trabajo de "apagar la imagen". */
.media-card--sport-photo .media-card__visual img {
  filter: saturate(0.92) contrast(1.04) brightness(0.98);
}

/* Mismo criterio que sport-photo (nivelar una colección con fuentes
   dispares a la misma temperatura), pero menos agresivo: son ilustraciones
   de juego, no fotos — el color vívido ES parte de su atractivo premium,
   no hay que apagarlo como a una foto real. Solo se oscurece y ajusta
   contraste lo justo para que la más clara del lote (el dulce rosa/celeste)
   deje de sentirse "pegada" sobre el resto, oscuras y saturadas de púrpura/
   dorado/fuego. */
/* Mismo motivo que sport-photo: 0.86 de brillo compartido + el propio
   grading por imagen (ya aplicado al archivo) duplicaba la corrección
   de sombras — quedaba más oscuro de lo que cualquiera de las dos
   partes buscaba por separado. */
.media-card--game-photo .media-card__visual img {
  filter: saturate(0.98) contrast(1.04) brightness(0.98);
}

.media-card:hover .media-card__visual {
  transform: scale(1.06);
}

@media (hover: none) {
  .media-card:hover .media-card__visual {
    transform: none;
  }

  .media-card:active .media-card__visual {
    transform: scale(1.03);
  }
}

/* Mismo giro de esquinas más redondeadas que el resto de las tarjetas
   protagonistas en móvil — las fotos de Juegos/Deportes quedan con el
   mismo lenguaje que Servicios/Bonos/Trust cards en vez de un radio más
   chico y aparte. */
@media (max-width: 639px) {
  .media-card {
    border-radius: 20px;
  }
}

.media-card__overlay {
  position: absolute;
  inset: 0;
  background: var(--grad-card-overlay);
}

.media-card__badge {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 2;
}

.media-card__title {
  position: absolute;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: 2;
  color: var(--text-primary);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
}

/* .media-card--sport (aspect-ratio:4/5, width:180px) se quitó: son
   exactamente los mismos valores que ya trae .media-card base — la
   clase sigue aplicándose en render.js (no hace falta tocarla), pero
   la regla no aportaba ningún estilo real, solo repetía lo heredado. */

/* ---------- Bonus card ---------- */
.bonus-card {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  width: 280px;
}

/* Wrapper puramente estructural — mismo motivo que .service-card__inner
   (ver carousel.js): en mobile .bonus-card tiene scroll-snap-align, así
   que la microanimación de "tarjeta activa" del carrusel de puntos
   necesita un elemento propio para transformar, nunca la tarjeta en sí.
   Reproduce el mismo layout que antes vivía directo en .bonus-card
   (columna + gap) para que Desktop no cambie ni un píxel. */
.bonus-card__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex: 1;
  width: 100%;
  min-width: 0;
}

.bonus-card:hover {
  transform: translateY(-4px);
  border-color: rgba(255, 215, 0, 0.35);
  box-shadow: var(--elev-gold-glow);
}

@media (hover: none) {
  .bonus-card:hover {
    transform: none;
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: var(--elev-float);
  }

  .bonus-card:active {
    transform: scale(0.985);
  }
}

.bonus-card--featured {
  width: 100%;
  background: linear-gradient(160deg, rgba(255, 215, 0, 0.1), var(--bg-surface));
  border: 1px solid rgba(255, 215, 0, 0.3);
}

.bonus-card__highlight {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 2.5rem;
  color: var(--gold-500);
}

.bonus-card h3 {
  font-size: 1.125rem;
}

.bonus-card p {
  font-size: var(--fs-body);
}

/* ---------- Testimonial ---------- */
.testimonial-card {
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: min(360px, 82vw);
  transition: transform var(--dur-standard) var(--ease-standard),
    box-shadow var(--dur-standard) var(--ease-standard),
    border-color var(--dur-standard) var(--ease-standard);
}

.testimonial-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--elev-purple-glow);
  border-color: rgba(255, 215, 0, 0.2);
}

@media (hover: none) {
  .testimonial-card:hover {
    transform: none;
    box-shadow: var(--elev-float);
    border-color: rgba(255, 255, 255, 0.08);
  }

  .testimonial-card:active {
    transform: scale(0.985);
  }
}

.testimonial-card__stars {
  display: flex;
  gap: 3px;
}

.star-icon {
  width: 16px;
  height: 16px;
}

.star-icon.is-filled {
  color: var(--gold-500);
  fill: var(--gold-500);
}

.star-icon.is-empty {
  color: var(--text-disabled);
  fill: none;
}

.testimonial-card__quote {
  font-size: var(--fs-body-lg);
  color: var(--text-primary);
  line-height: 1.55;
  /* Alto fijo aproximado vía clamp de líneas: mantiene el ritmo del
     carrusel sin forzar todas las citas a la misma longitud exacta. */
  flex: 1;
}

.testimonial-card__author {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.testimonial-card__avatar {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-on-gold);
  border: 1px solid rgba(255, 255, 255, 0.12);
}

.testimonial-card__avatar.avatar-coral { background: linear-gradient(160deg, var(--cat-coral), var(--purple-800)); color: #fff; }
.testimonial-card__avatar.avatar-gold { background: linear-gradient(160deg, var(--gold-400), var(--gold-700)); }
.testimonial-card__avatar.avatar-purple { background: linear-gradient(160deg, var(--cat-purple), var(--purple-900)); color: #fff; }
.testimonial-card__avatar.avatar-cyan { background: linear-gradient(160deg, var(--cat-cyan), var(--purple-800)); color: #fff; }
.testimonial-card__avatar.avatar-teal { background: linear-gradient(160deg, var(--cat-teal), var(--purple-900)); color: #fff; }
.testimonial-card__avatar.avatar-green { background: linear-gradient(160deg, var(--cat-green), var(--purple-900)); color: #fff; }

.testimonial-card__name {
  font-weight: 600;
  color: var(--text-primary);
  font-size: var(--fs-caption);
}

.testimonial-card__meta {
  color: var(--text-muted);
  font-size: 0.8rem;
}

/* ---------- FAQ Accordion ---------- */
.accordion__item {
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.accordion__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-5);
  text-align: left;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--text-primary);
}

/* El "+"/"−" se dibuja en CSS puro con dos barras (::before/::after) en
   vez de depender del <svg> que arma icons.js (sin width/height propios,
   solo viewBox — su tamaño final quedaba resuelto por el algoritmo de
   "tamaño por defecto de elemento reemplazado" del navegador, que
   Chromium resuelve a 24x24 real vía max-width:100% + aspect-ratio del
   viewBox, pero que no todos los motores resuelven igual: es la clase de
   comportamiento que puede dejar un ícono colapsado/invisible sin que
   ninguna regla lo esté ocultando a propósito). Dos barras con ancho/alto
   en px explícitos no dejan nada a interpretación — se ven igual en
   cualquier navegador. No se toca icons.js: sigue siendo el mismo
   componente compartido por el resto de los íconos del sitio. */
.accordion__icon {
  position: relative;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
}

.accordion__icon::before,
.accordion__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: currentColor;
  border-radius: 1px;
  transition: transform var(--dur-standard) var(--ease-standard), opacity var(--dur-standard) var(--ease-standard);
}

/* Barra horizontal: el "−" de cerca — siempre presente. */
.accordion__icon::before {
  width: 14px;
  height: 1.75px;
  transform: translate(-50%, -50%);
}

/* Barra vertical: junto a la horizontal arma el "+"; en el estado abierto
   se esconde (scale + fade) y solo queda la horizontal, es decir un "−". */
.accordion__icon::after {
  width: 1.75px;
  height: 14px;
  transform: translate(-50%, -50%);
}

.accordion__trigger[aria-expanded="true"] .accordion__icon::after {
  transform: translate(-50%, -50%) scaleY(0);
  opacity: 0;
}

.accordion__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-standard) var(--ease-out-premium);
}

.accordion__panel-inner {
  overflow: hidden;
}

.accordion__item.is-open .accordion__panel {
  grid-template-rows: 1fr;
}

.accordion__panel p {
  padding-bottom: var(--space-5);
  color: var(--text-secondary);
  max-width: 65ch;
}

/* La fila de pregunta no tenía ningún feedback al tocar más allá del
   panel abriéndose (con transición, pero no inmediato) — un tap en una
   superficie táctil espera una respuesta visual instantánea. El leve
   sangrado horizontal negativo deja que el fondo de tap se lea como una
   franja completa (mismo truco que una fila de Settings nativa), no una
   caja angosta ceñida solo al texto. */
@media (max-width: 639px) {
  .accordion__trigger {
    border-radius: 12px;
    padding-inline: var(--space-3);
    margin-inline: calc(var(--space-3) * -1);
    transition: background var(--dur-micro) var(--ease-standard);
  }

  .accordion__trigger:active {
    background: rgba(255, 255, 255, 0.05);
  }
}

/* ---------- CTA Banner ---------- */
.cta-banner {
  background: var(--grad-hero);
  border-radius: var(--radius-lg);
  /* padding reducido a propósito: la sección que lo envuelve ya aporta
     --space-9 arriba/abajo, así que --space-9 aquí también duplicaba el aire */
  padding: var(--space-8) var(--space-6);
  text-align: center;
  position: relative;
  overflow: hidden;
  /* El panel usaba el ancho completo de .container (1232px) para
     apenas 560px de contenido (.cta-banner__content) centrado adentro —
     en pantallas grandes (1366-1920px) quedaba mucho degradado vacío a
     los costados y el cierre de la página se sentía "estirado". Un
     max-width propio, centrado con margin-inline:auto, lo vuelve una
     tarjeta de cierre más contenida y proporcionada — sigue viviendo
     dentro del mismo .container que el resto de las secciones (mismos
     márgenes exteriores), solo que ya no ocupa el 100% de su ancho. */
  max-width: 860px;
  margin-inline: auto;
}

.cta-banner__glow {
  position: absolute;
  inset: -20%;
  background: radial-gradient(circle at 30% 20%, rgba(255, 215, 0, 0.12), transparent 45%),
    radial-gradient(circle at 75% 60%, rgba(139, 95, 191, 0.18), transparent 50%);
  animation: mesh-drift 20s linear infinite;
  pointer-events: none;
}

@keyframes mesh-drift {
  0% { transform: translate(0, 0); }
  50% { transform: translate(2%, 3%); }
  100% { transform: translate(0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .cta-banner__glow {
    animation: none;
  }
}

.cta-banner__content {
  position: relative;
  z-index: 1;
  max-width: 560px;
  margin-inline: auto;
}

.cta-banner h2 {
  margin-bottom: var(--space-3);
}

.cta-banner p {
  color: var(--text-secondary);
  margin-bottom: var(--space-6);
}

.cta-banner .cta-row {
  justify-content: center;
}

/* ---------- Contact FABs (desktop + mobile) ---------- */
.contact-fabs {
  position: fixed;
  right: var(--space-5);
  /* env() resuelve a 0 en equipos sin "notch"/home-indicator — ahí
     bottom queda exactamente en var(--space-5), igual que siempre. En
     un iPhone con Face ID, suma el alto real de esa franja de gestos
     para que los botones no queden pegados/tapados por ella. */
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity var(--dur-standard) var(--ease-out-premium),
    transform var(--dur-standard) var(--ease-out-premium);
}

.contact-fabs.is-visible {
  opacity: 1;
  transform: scale(1);
}

.fab {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--elev-3);
  transition: transform var(--dur-standard) var(--ease-standard);
}

.fab:hover {
  transform: scale(1.08);
}

@media (hover: none) {
  .fab:hover {
    transform: none;
  }
}

/* Feedback al tocar en touch — mismo lenguaje que .btn:active en el
   resto del sitio (un leve achique), ya que :hover no siempre se
   percibe en pantallas táctiles. */
.fab:active {
  transform: scale(0.95);
}

.fab svg {
  width: 26px;
  height: 26px;
}

/* Los badges de WhatsApp/Telegram ya son un círculo completo con su
   propio color de marca — a 26px (tamaño pensado para un glyph de línea
   sin fondo) el círculo de fondo propio de .fab-telegram (oscuro) se
   asomaba como un anillo visible alrededor del badge azul. Agrandarlo
   para que ocupe casi todo el botón deja ese anillo como un borde fino
   intencional en vez de un choque de color — mismo tratamiento para
   ambas plataformas, así siguen pesando exactamente igual. */
.fab img {
  width: 50px;
  height: 50px;
  object-fit: contain;
}

/* Un poco más discretos en mobile — mismo diseño (sombra, radio,
   animaciones) a menor escala, sin bajar del mínimo táctil de 44px.
   Ícono reducido en la misma proporción para que siga viéndose igual
   de "lleno" dentro del botón, no más chico en relación al círculo. */
@media (max-width: 639px) {
  .contact-fabs {
    /* La bottom-nav (~60px + safe-area) ahora vive en el mismo rincón
       inferior — los FABs suben para flotar arriba de la barra en vez
       de superponerse. */
    bottom: calc(60px + var(--space-3) + env(safe-area-inset-bottom));
  }
  .fab {
    width: 46px;
    height: 46px;
  }
  .fab img {
    width: 40px;
    height: 40px;
  }
}

.fab-whatsapp {
  background: #25d366; /* verde oficial de marca WhatsApp — no forma parte del design system */
  color: var(--bg-base);
  animation: fab-pulse 4s ease-in-out infinite;
}

.fab-telegram {
  background: var(--bg-surface);
  color: #38a4dc;
  border: 1px solid rgba(56, 164, 220, 0.4);
}

@keyframes fab-pulse {
  0%, 100% { box-shadow: var(--elev-3), 0 0 0 0 rgba(37, 211, 102, 0.4); }
  50% { box-shadow: var(--elev-3), 0 0 0 10px rgba(37, 211, 102, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .fab-whatsapp {
    animation: none;
  }
}

/* Los FABs ahora se usan también en mobile (reemplazan a la barra fija
   inferior que existía antes): mismo componente, mismo estilo, en vez
   de duplicar diseño en dos formatos distintos.

   En mobile, .footer__bottom envuelve el aviso +18 a una segunda línea
   (queda a ancho completo) y termina justo en el rincón inferior
   derecho, exactamente donde viven los FABs — sin este aire, el aviso
   quedaba tapado por los botones al llegar al final de la página. En
   desktop el aviso no envuelve y el footer ya le da suficiente margen
   propio al borde derecho, así que ahí no hace falta. */
@media (max-width: 767px) {
  body {
    padding-bottom: calc(160px + env(safe-area-inset-bottom));
  }
}

/* La bottom-nav se suma como una segunda franja fija abajo — el footer
   (copyright, aviso +18) necesita aire extra para no terminar debajo de
   la barra, no solo debajo de los FABs.

   El valor real necesario es "desde dónde hasta el borde inferior del
   viewport hay algún elemento fijo": [data-contact-fabs] es un
   contenedor de DOS botones (WhatsApp + Telegram, 46px cada uno +
   var(--space-3)=12px de gap = 104px) posicionado a
   bottom:calc(60px + var(--space-3)) = 72px del borde inferior — su
   borde superior queda entonces a 72+104=176px del borde inferior del
   viewport, SIEMPRE, sin importar el alto del viewport. 188px reserva
   ese margen real (176px) más var(--space-3)=12px de aire de cortesía
   — el mismo valor de "gap ajustado" que ya usa el resto del sistema
   (p. ej. el propio hueco entre los FABs y la bottom-nav), en vez de
   los 24px sueltos que había antes. 200px/220px (heredados de
   versiones anteriores, con un footer más alto) dejaban fondo vacío de
   sobra sin que ningún elemento fijo lo justificara — se percibía como
   "espacio muerto" al llegar al final del scroll. */
@media (max-width: 639px) {
  body {
    padding-bottom: calc(176px + var(--space-3) + env(safe-area-inset-bottom));
  }
}

/* ---------- Footer ---------- */
.footer {
  padding-top: var(--space-9);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

/* 96px (var(--space-9)) es el valor de Desktop, nunca reducido para
   mobile — abría un bloque de aire vacío antes de que aparezca
   siquiera "SuperPro". 40px mantiene una separación clara del filete
   superior sin ese sobrante.

   --footer-divider-pad / --footer-section-gap: fuente única de verdad
   para el ritmo vertical de los 3 sectores del cierre (marca → columnas
   → copyright+aviso). Cada transición entre sectores tiene un filete
   divisor (border) en el medio, así que el espacio real se arma en dos
   partes — aire ANTES del filete (padding-bottom del bloque que
   termina) + aire DESPUÉS del filete (row-gap / padding-top del bloque
   que empieza) — pero como las DOS transiciones reutilizan literalmente
   estas mismas dos variables (nunca un número suelto), quedan
   matemáticamente forzadas a sumar siempre lo mismo (16+14=30px): no
   hay forma de que un cambio futuro en una transición deje a la otra
   atrás, como pasaba antes (30px la primera, 48px la segunda). */
@media (max-width: 639px) {
  .footer {
    padding-top: 40px;
    --footer-divider-pad: 16px;
    --footer-section-gap: 14px;
  }
}

.footer__grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--space-6);
  padding-bottom: var(--space-8);
}

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

/* Navegación / Contacto / Juego responsable en 3 columnas, una junto a
   otra, en vez de apiladas — el bloque de marca (primer hijo de
   .footer__grid) se fuerza a ocupar la fila completa con
   grid-column:1/-1, y los tres .footer__col restantes caen solos en
   la fila siguiente, uno por columna.

   Las columnas NO son 1fr/1fr/1fr: "Navegación" y "Contacto" solo
   contienen palabras cortas (Beneficios, WhatsApp...), mientras que
   "Juego responsable" es el título más largo de los tres Y contiene el
   link más largo ("Jugá con responsabilidad"). 0.8fr/0.8fr/1.4fr le da
   a esa tercera columna el espacio real que necesita para que su
   título entre en una sola línea — equilibrio visual según contenido,
   no una grilla matemáticamente pareja. padding-bottom reemplaza el
   var(--space-8)=64px heredado de Desktop, que no correspondía aquí —
   ahora usa --footer-divider-pad (ver .footer arriba), el mismo valor
   que ya separa marca de columnas, para que "columnas → cierre" pese
   exactamente igual que "marca → columnas" en vez de los 48px previos. */
@media (max-width: 639px) {
  .footer__grid {
    grid-template-columns: 0.8fr 0.8fr 1.4fr;
    column-gap: 8px;
    row-gap: var(--footer-section-gap);
    padding-bottom: var(--footer-divider-pad);
  }

  .footer__grid > div:first-child {
    grid-column: 1 / -1;
  }
}

/* El separador que antes marcaba "acá termina la marca, empieza la
   navegación" vivía como border-top del primer .footer__col (tenía
   sentido apilado en una columna). Ahora que marca y columnas son
   filas de grid distintas, el mismo filete se mueve al final del
   bloque de marca (border-bottom) para seguir cumpliendo su función
   sin quedar huérfano en una sola de las tres columnas. 16px de
   padding + 14px de row-gap dan un total de 30px de aire alrededor del
   filete — suficiente para leerse como una pausa real, sin repetir el
   var(--space-5)=24px+24px de la versión anterior. */
@media (max-width: 639px) {
  .footer__col--first {
    margin-top: 0;
    padding-top: 0;
    border-top: none;
  }

  .footer__grid > div:first-child {
    padding-bottom: var(--footer-divider-pad);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    text-align: center;
  }

  .footer__col {
    text-align: center;
  }

  .footer__col ul {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
  }
}

.footer__brand {
  display: flex;
  align-items: baseline;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.35rem;
  color: var(--text-primary);
}

.footer__brand [data-bind="brand-accent"] {
  color: var(--gold-500);
}

.footer__tagline {
  margin-top: var(--space-3);
  max-width: 32ch;
  font-size: var(--fs-caption);
  color: var(--text-muted);
}

/* Va DESPUÉS de las reglas base de arriba a propósito: misma
   especificidad (una sola clase) que .footer__brand/.footer__tagline
   sin scope — puesta antes (como estaba en un intento previo, dentro
   del primer bloque @media de la sección Footer) esas reglas base, por
   quedar más abajo en el archivo, seguían ganando el cascade y el
   max-width:32ch nunca se anulaba. Mismo bug ya documentado para
   Comparativa: un override en @media ubicado ANTES de una regla base
   sin condición, misma especificidad, pierde sin importar el media
   query. */
@media (max-width: 639px) {
  /* .footer__brand es flex (para el baseline entre "Super"/"Pro") —
     text-align no alinea hijos flex, hace falta justify-content propio.
     Antes quedaba pegado al borde izquierdo del bloque de marca (que ya
     ocupa el ancho completo por el grid-column:1/-1 del wrapper), no
     centrado respecto al viewport real. */
  .footer__brand {
    justify-content: center;
  }

  /* max-width:32ch (pensado para la columna angosta de Desktop) es lo
     que forzaba el wrap a 2 líneas acá, donde el bloque de marca ya
     ocupa el ancho completo del footer en mobile. */
  .footer__tagline {
    max-width: none;
    white-space: nowrap;
    font-size: 0.75rem;
  }
}

.footer__col h4 {
  font-family: var(--font-body);
  font-size: var(--fs-caption);
  font-weight: 600;
  color: var(--text-primary);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-4);
}

/* En 3 columnas dentro de un mobile de 375px cada título dispone de
   ~100px reales — "Juego responsable" (el más largo) ya envuelve de
   forma natural en el espacio entre palabras (sin hyphens ni cortes
   forzados); bajar tamaño y letter-spacing evita que ese wrap se vea
   apretado y mantiene los tres títulos con la misma altura de bloque
   para que la fila quede alineada. */
@media (max-width: 639px) {
  .footer__col h4 {
    font-size: 0.6875rem;
    line-height: 1.3;
    letter-spacing: 0.03em;
    margin-bottom: var(--space-2);
  }
}

.footer__col li + li {
  margin-top: var(--space-3);
}

.footer__col a {
  display: inline-block;
  font-size: var(--fs-caption);
  color: var(--text-muted);
  transition: color var(--dur-micro);
}

.footer__col a:hover {
  color: var(--gold-400);
}

/* En mobile (donde importa el dedo, no el mouse) el link medía ~17px de
   alto real — bien corto para tocar con comodidad. padding-block sube
   el área táctil sin agrandar el texto; se descuenta del margin-top
   entre <li> para no separar más los renglones de lo que ya estaban.

   Con 3 columnas de ~100px cada una, mantener el font-size completo de
   14px (--fs-caption) sería demasiado para textos como "Jugá con
   responsabilidad" — se achica un poco (13px) y se ajusta el
   line-height para que, si envuelve a dos líneas, se lea holgado y no
   pegado. */
@media (max-width: 639px) {
  .footer__col li + li {
    margin-top: 2px;
  }
  .footer__col a {
    font-size: 0.8125rem;
    line-height: 1.35;
    padding-block: 6px;
  }
}

.footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-block: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* Antes era una barra propia (background + border-top + padding-block
   16px), una segunda línea completa solo para este aviso. Ahora vive
   como segundo ítem de .footer__bottom (que ya era flex con
   justify-content:space-between, pensado para dos elementos aunque
   solo tuviera uno) — mismo renglón que el copyright, peso y color
   propios para que siga leyéndose como aviso, sin volver a ocupar una
   línea entera. */
.footer__age-notice {
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.01em;
}

/* El cierre (copyright + aviso +18) queda centrado como un bloque final
   intencional en vez de texto ragged a la izquierda — coherente con las
   3 columnas centradas justo encima. Jerarquía: el copyright (dato
   secundario) baja un peldaño de tamaño respecto al aviso +18 (el que
   realmente importa legal/éticamente), que mantiene su peso y color
   propios para seguir leyéndose como lo más importante de esta franja.
   padding-block y gap se ajustan para un ritmo más ceñido que en
   Desktop, sin perder el aire que separa "columnas → cierre → fin". El
   valor de arriba (padding-top) es --footer-section-gap, el mismo que
   ya usa .footer__grid como row-gap — junto con --footer-divider-pad
   (padding-bottom de .footer__grid, justo antes de este bloque) arman
   los mismos 30px que separan marca de columnas. El de abajo
   (padding-bottom:18px) es aire de cierre de página, no de ritmo entre
   sectores — se deja sin tocar. */
@media (max-width: 639px) {
  .footer__bottom {
    flex-direction: column;
    text-align: center;
    padding-block: var(--footer-section-gap) 18px;
    gap: 8px;
  }

  .footer__bottom [data-bind="copyright"] {
    font-size: 0.6875rem;
    line-height: 1.4;
  }

  .footer__age-notice {
    display: block;
    font-size: 0.5625rem;
    letter-spacing: 0;
    line-height: 1.4;
    white-space: nowrap;
  }
}
