/* Base visual compartida por todas las páginas de cliente/ (prueba de
   conexión, registro, login, perfil, y lo que siga). Misma receta de
   "vidrio 3D marcado": gradiente de color + sombras en capas + brillo diagonal + backdrop-filter. */

:root {
  --azul-oscuro: #082c6b;
  --violeta: #7c3aed;
  --texto: #1a1a1a;

  /* ================================================================
     SISTEMA DE DISEÑO NUEVO — cliente/docs/guia-de-estilo.md (25/09/2026)
     Migración en curso, página por página (ver AVISO más abajo sobre
     ".cristal"). Los tokens de acá abajo son los de la guía §1, tal
     cual — nombres SIN "-rgb" a propósito, para no chocar con la
     paleta vieja de arriba (--c1-rgb..--c6-rgb): los dos conviven
     mientras dura la migración.
     ================================================================ */
  --c1: 255, 0, 110;   /* magenta #FF006E */
  --c2: 0, 217, 255;   /* cian #00D9FF */
  --c3: 244, 208, 63;  /* dorado #F4D03F */
  --c4: 255, 87, 34;   /* naranja #FF5722 */
  --c5: 139, 92, 246;  /* violeta #8B5CF6 */
  --c6: 16, 185, 129;  /* verde #10B981 */
  --peligro: 244, 63, 94;

  --relleno-c1: linear-gradient(145deg, #E00061 0%, #CE0059 40%, #E00061 100%);
  --relleno-c5: linear-gradient(145deg, #774FD2 0%, #6D49C1 40%, #774FD2 100%);
  --relleno-peligro: linear-gradient(145deg, #C7334D 0%, #B72F47 40%, #C7334D 100%);

  /* ===== Tema claro (valor por defecto) ===== */
  --fondo: #f3f4fa;
  /* "--texto-v2": la guía usa "--texto" a secas, pero esa variable YA
     existe arriba (línea 12) y la usan 8 reglas viejas globales (ej.
     html,body{color:var(--texto)}) — si la pisara acá, el modo oscuro
     se colaría en páginas que todavía no migré. Se resuelve al final:
     cuando la última página pase al sistema nuevo, se borra la
     variable vieja y "--texto-v2" pasa a llamarse "--texto". */
  --texto-v2: #0b0b14;
  --texto-v2-suave: rgba(11, 11, 20, 0.62);
  --texto-v2-tenue: rgba(11, 11, 20, 0.4);
  --vidrio-a: rgba(255, 255, 255, 0.8);
  --vidrio-b: rgba(255, 255, 255, 0.55);
  --vidrio-borde: rgba(11, 11, 20, 0.1);
  --vidrio-sombra: 0 18px 40px rgba(20, 20, 40, 0.12), 0 2px 6px rgba(20, 20, 40, 0.1);
  --campo: rgba(255, 255, 255, 0.85);
  --rejilla: rgba(11, 11, 20, 0.05);
  --orbe-alfa: 0.22;
  --tinte: 0.16;
  --ruido: 0.05;
  --linea-alfa: 0.45;
  --placeholder-borde: rgba(11, 11, 20, 0.16);
  --ventana: rgba(250, 250, 255, 0.96);
  --radio: 20px;

  --superficie: #ffffff;
  --superficie-2: #f5f5fa;
  --acento: 214, 0, 92;
  --acento-texto: 214, 0, 92;

  --fuente-titulo: "Sora";
  --fuente-texto: "DM Sans";
  --fuente-logo: "Syne";

  color-scheme: light;
}

/* Modo oscuro: SOLO atado a [data-theme="dark"] (lo pone el botón de
   tema, ver js/tema.js) — a propósito SIN @media(prefers-color-scheme)
   todavía. Mientras la migración esté en curso, activar el oscuro por
   preferencia del sistema afectaría TODAS las páginas a la vez
   (:root es global a todo cliente.css), incluidas las que todavía no
   pasaron a los componentes nuevos y se verían rotas. Se puede sumar
   la detección automática al final, cuando ya no quede ninguna página
   vieja, si se decide en ese momento. */
:root[data-theme="dark"] {
  --fondo: #06060a;
  --texto-v2: #ffffff;
  --texto-v2-suave: rgba(255, 255, 255, 0.6);
  --texto-v2-tenue: rgba(255, 255, 255, 0.36);
  --vidrio-a: rgba(255, 255, 255, 0.1);
  --vidrio-b: rgba(255, 255, 255, 0.035);
  --vidrio-borde: rgba(255, 255, 255, 0.14);
  --vidrio-sombra: 0 20px 50px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.5);
  --campo: rgba(255, 255, 255, 0.06);
  --rejilla: rgba(255, 255, 255, 0.04);
  --orbe-alfa: 0.16;
  --tinte: 0.12;
  --ruido: 0.035;
  --linea-alfa: 0.35;
  --placeholder-borde: rgba(255, 255, 255, 0.16);
  --ventana: rgba(16, 16, 24, 0.94);
  --superficie: #13131b;
  --superficie-2: #1b1b25;
  --acento-texto: 255, 102, 163;
  color-scheme: dark;
}

/* ================================================================
   A partir de acá: componentes del sistema nuevo (guía §2 en
   adelante). Conviven con los componentes viejos más abajo en este
   mismo archivo mientras dura la migración página por página — ver
   cliente/docs/guia-de-estilo.md para el detalle completo de cada uno.
   ================================================================ */

/* ===== Fondo: esferas de luz + rejilla + ruido (guía §2) =====
   Adaptado de la guía: el .contenedor de la guía es de 1160px (pensado
   para pantallas de escritorio); acá se deja en 480px, el mismo ancho
   que ya usaba el <body> — yoisaldo es una app angosta tipo celular,
   no un sitio de escritorio. */
.ambiente { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
.orbe { position: absolute; border-radius: 50%; filter: blur(50px); }
.orbe.m { width: 70vmax; height: 70vmax; top: -25vmax; left: -20vmax;
  background: radial-gradient(circle, rgba(var(--c1), var(--orbe-alfa)) 0%, transparent 65%);
  animation: derivaA 18s ease-in-out infinite; }
.orbe.c { width: 60vmax; height: 60vmax; top: 5vmax; right: -25vmax;
  background: radial-gradient(circle, rgba(var(--c2), var(--orbe-alfa)) 0%, transparent 65%);
  animation: derivaB 22s ease-in-out infinite; }
.orbe.d { width: 50vmax; height: 50vmax; bottom: -25vmax; left: 10vmax;
  background: radial-gradient(circle, rgba(var(--c3), calc(var(--orbe-alfa) * 0.8)) 0%, transparent 65%);
  animation: derivaC 26s ease-in-out infinite; }
.orbe.n { width: 40vmax; height: 40vmax; top: 45%; right: 0;
  background: radial-gradient(circle, rgba(var(--c4), calc(var(--orbe-alfa) * 0.6)) 0%, transparent 65%);
  animation: derivaA 20s ease-in-out infinite reverse; }

@keyframes derivaA { 0%, 100% { transform: translate(0, 0); } 33% { transform: translate(40px, -40px); } 66% { transform: translate(-30px, 30px); } }
@keyframes derivaB { 0%, 100% { transform: translate(0, 0); } 33% { transform: translate(-50px, 30px); } 66% { transform: translate(40px, -20px); } }
@keyframes derivaC { 0%, 100% { transform: translate(0, 0); } 50% { transform: translate(30px, -50px); } }

.linea-brillo { position: absolute; left: 0; right: 0; height: 1px; }
.linea-brillo.a { top: 72px;
  background: linear-gradient(90deg, transparent, rgba(var(--c2), var(--linea-alfa)), rgba(var(--c1), var(--linea-alfa)), transparent); }
.linea-brillo.b { bottom: 18%;
  background: linear-gradient(90deg, transparent, rgba(var(--c2), calc(var(--linea-alfa) / 2)), rgba(var(--c1), calc(var(--linea-alfa) / 2)), transparent); }

.ruido {
  position: absolute; inset: 0; opacity: var(--ruido); background-size: 160px 160px;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Adaptado de la guía: acá NO repite el ancho/padding (el <body> de
   yoisaldo ya los maneja — ver el AVISO en su regla) — si lo repitiera,
   el padding se duplicaría (contenido empujado 40px en vez de 20px).
   El único trabajo de .contenedor en este proyecto es el stacking:
   sin position+z-index, el contenido real queda POR DEBAJO de la capa
   fija .ambiente (esferas/ruido) y no se ve nada. */
.contenedor { position: relative; z-index: 1; }

/* ===== Efecto vidrio nuevo: ".cristal" (guía §3) =====
   AVISO: la guía llama a esto ".vidrio", pero ese nombre ya existe acá
   abajo con una receta totalmente distinta (la que usan hoy TODAS las
   páginas). Reusarlo rompería, a mitad de la migración, cualquier
   página que todavía no pasé al sistema nuevo (CSS no tiene forma de
   "alcanzar" solo una página desde un archivo compartido). Por eso este
   efecto vive bajo ".cristal" hasta que la última página migre — ahí
   se hace un único renombre global .cristal → .vidrio y se borra la
   receta vieja. No cambia nada de lo que se ve, es orden interno. */
.cristal {
  position: relative; overflow: hidden;
  background: linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 50%, var(--vidrio-a) 100%);
  border: 1px solid var(--vidrio-borde);
  box-shadow: var(--vidrio-sombra), inset 0 1px 0 rgba(255, 255, 255, 0.25), inset 0 -2px 4px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  color: var(--texto-v2);
}
.cristal::before {
  content: ""; position: absolute; inset: 0 0 50% 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.14) 0%, transparent 100%);
}
.cristal > * { position: relative; }
.caja { border-radius: var(--radio); padding: 18px; }

.ventana-fondo {
  position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 16px;
  background: rgba(6, 6, 10, 0.72); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.ventana {
  width: 100%; max-width: 440px; border-radius: 28px; padding: 44px 24px 24px;
  display: grid; gap: 14px; color: var(--texto-v2);
  background: linear-gradient(145deg, rgba(var(--c1), 0.08), transparent 45%), var(--ventana);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55), 0 0 0 1px var(--vidrio-borde), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.ventana-icono {
  position: absolute; top: -30px; left: 50%; transform: translateX(-50%);
  width: 60px; height: 60px; border-radius: 50%; display: grid; place-items: center; color: #fff;
  background: linear-gradient(145deg, rgb(var(--c1)), rgb(var(--c4)));
  box-shadow: 0 10px 28px rgba(var(--c1), 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.5);
}

/* Los márgenes negativos cancelan el padding del <body> (ver su AVISO
   más arriba) para que la barra llegue de borde a borde, sin cambiar
   el modelo de layout del resto de la página — mismo truco que ya
   usaba el header viejo (.app-header). */
.barra { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 20; border-radius: 0; border-inline: 0; border-top: 0; margin: -24px -20px 20px; }
.barra .contenedor { display: flex; align-items: center; gap: 12px; padding: 12px 20px; }

/* La guía no trae un título centrado de header (piensa en headers de
   marketplace con buscador/carrito) — acá sí hace falta: es el patrón
   de toda pantalla interna de yoisaldo. */
.titulo-barra {
  flex: 1; text-align: center; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--fuente-titulo), system-ui, sans-serif; font-weight: 800; font-size: 1.05rem; color: var(--texto-v2);
}

/* ===== Tipografía (guía §4) =====
   Las 3 fuentes se cargan desde Google Fonts, con los pesos exactos
   que se usan (nunca la hoja completa) — <link> agregado en el <head>
   de cada página a medida que migra, mismo criterio de "versión fija,
   nunca 'latest'" que ya usamos con Lucide (acá el equivalente es
   pedir familias + pesos exactos, que es lo más parecido a "fijar
   versión" que ofrece Google Fonts). */
h1, h2, h3 {
  font-family: var(--fuente-titulo), system-ui, sans-serif;
  font-weight: 800; letter-spacing: -0.01em; line-height: 1.15; text-wrap: balance;
}
/* El h1{color:var(--azul-oscuro)} viejo (más abajo en este archivo) es
   un selector de elemento sin clase — le gana a la herencia de
   .tarjeta-solida/.contenedor por especificidad, aunque esta regla
   esté antes en el archivo (visto en la Fase 1: "Iniciar sesión" salía
   azul en vez del color nuevo). Se soluciona con MÁS especificidad acá
   (2 clases + elemento le gana a 1 elemento solo), sin tocar la regla
   vieja — las páginas que no migraron no se enteran de este cambio. */
.contenedor h1, .contenedor h2, .contenedor h3,
.pantalla-cuenta h1, .pantalla-cuenta h2, .pantalla-cuenta h3 {
  color: var(--texto-v2);
}
.logo { font-family: var(--fuente-logo), var(--fuente-titulo), sans-serif; }
.degradado-texto {
  background: linear-gradient(90deg, rgb(var(--c1)), rgb(var(--c2)), rgb(var(--c3)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ===== Botones (guía §5) ===== */
.boton {
  --a: var(--c1);
  --relleno: var(--relleno-c1);
  /* La guía no lo trae, pero hace falta: un <a class="boton"> (ej.
     "Ir a iniciar sesión" en restablecer-contrasena.html) sin esto
     sale subrayado — .boton se usa tanto en <button> como en <a>. */
  text-decoration: none;
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 20px; border-radius: 14px; border: 1px solid rgba(var(--a), 0.6); cursor: pointer;
  font-family: var(--fuente-titulo), system-ui, sans-serif; font-weight: 800; font-size: 1rem; letter-spacing: 0.01em;
  color: var(--texto-boton, #fff); text-shadow: var(--sombra-texto-boton, 0 1px 3px rgba(0, 0, 0, 0.5));
  background: var(--relleno, linear-gradient(145deg, rgba(var(--a), 1) 0%, rgba(var(--a), 0.82) 40%, rgba(var(--a), 0.95) 100%));
  box-shadow:
    0 8px 24px rgba(var(--a), 0.4), 0 2px 4px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.45), inset 0 -2px 4px rgba(0, 0, 0, 0.28),
    inset 2px 0 4px rgba(255, 255, 255, 0.12), inset -2px 0 4px rgba(0, 0, 0, 0.2);
  transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}
.boton::before { content: ""; position: absolute; inset: 0 0 50% 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.32) 0%, transparent 100%); }
.boton::after { content: ""; position: absolute; inset: 70% 0 0 0; pointer-events: none;
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.18) 0%, transparent 100%); }
.boton > * { position: relative; }
.boton:hover:not(:disabled) { transform: translateY(-1px) scale(1.02);
  box-shadow: 0 12px 32px rgba(var(--a), 0.55), 0 2px 4px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.5); }
.boton:active:not(:disabled) { transform: scale(0.97); }
.boton:disabled, .boton[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; filter: saturate(0.6); }
.boton.ancho { width: 100%; }
.boton.peligro { --a: var(--peligro); --relleno: var(--relleno-peligro); }
.boton.pequeno { padding: 8px 14px; font-size: 0.88rem; border-radius: 11px; }

.color-1 { --a: var(--c1); --relleno: var(--relleno-c1); } .color-2 { --a: var(--c2); --relleno: initial; }
.color-3 { --a: var(--c3); --relleno: initial; } .color-4 { --a: var(--c4); --relleno: initial; }
.color-5 { --a: var(--c5); --relleno: var(--relleno-c5); } .color-6 { --a: var(--c6); --relleno: initial; }
.color-2, .color-3, .color-4, .color-6 { --texto-boton: #06060a; --sombra-texto-boton: 0 1px 0 rgba(255, 255, 255, 0.35); }

.boton-vidrio {
  position: relative; overflow: hidden; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 14px; border-radius: 12px; font-weight: 700; font-size: 0.9rem;
  background: linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 50%, var(--vidrio-a) 100%);
  border: 1px solid var(--vidrio-borde); color: var(--texto-v2);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  transition: transform 0.2s ease;
}
.boton-vidrio:hover:not(:disabled) { transform: scale(1.05); }
.boton-vidrio:disabled { opacity: 0.45; cursor: default; }
.boton-icono { width: 42px; height: 42px; padding: 0; }
.boton-icono.pequeno { width: 36px; height: 36px; }

.contador {
  position: absolute; top: -5px; right: -5px; min-width: 20px; height: 20px; padding-inline: 5px;
  border-radius: 999px; display: grid; place-items: center;
  font-size: 0.72rem; font-weight: 800; background: rgb(var(--c1)); color: #fff;
  box-shadow: 0 2px 8px rgba(var(--c1), 0.6);
}

/* ===== Chips y pestañas (guía §6) ===== */
.pestanas { display: flex; gap: 10px; overflow-x: auto; padding: 18px 2px 10px; scrollbar-width: none; }
.pestanas::-webkit-scrollbar { display: none; }
.chip {
  --a: var(--c1);
  --relleno: var(--relleno-c1);
  --texto-boton: #fff;
  --sombra-texto-boton: 0 1px 3px rgba(0, 0, 0, 0.45);
  flex: none; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
  padding: 10px 16px; border-radius: 14px; font-weight: 700; font-size: 0.92rem; cursor: pointer; border: none;
  font-family: inherit;
  background: linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.3)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%), var(--vidrio-b);
  border: 1px solid rgba(var(--a), 0.35); color: var(--texto-v2);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  transition: transform 0.2s ease;
}
.chip svg { color: rgb(var(--a)); }
.chip:hover { transform: translateY(-2px); }
.chip.activa {
  color: var(--texto-boton, #fff); text-shadow: var(--sombra-texto-boton, 0 1px 3px rgba(0, 0, 0, 0.45));
  background: var(--relleno, linear-gradient(145deg, rgba(var(--a), 1) 0%, rgba(var(--a), 0.82) 100%));
  box-shadow: 0 8px 22px rgba(var(--a), 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}
.chip.activa svg { color: currentColor; }

.pastilla {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 8px; border-radius: 999px;
  white-space: nowrap; max-width: 100%;
  font-size: 0.7rem; font-weight: 700; color: var(--texto-v2);
  background: var(--vidrio-a); border: 1px solid var(--vidrio-borde);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
.pastilla.destacada { background: rgba(var(--c1), 0.92); border-color: rgb(var(--c1)); color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); }
.pastilla.alerta { background: rgba(var(--peligro), 0.92); border-color: rgb(var(--peligro)); color: #fff; }

/* gap + tamaño de svg: la guía no los trae (sus ejemplos son solo
   texto), pero historial.js usa .etiqueta-estado con ícono + texto. */
.etiqueta-estado { display: inline-flex; align-items: center; gap: 4px; font-size: 0.78rem; font-weight: 800;
  padding: 4px 12px; border-radius: 999px; border: 1px solid; white-space: nowrap; }
.etiqueta-estado svg { width: 12px; height: 12px; }
.etiqueta-estado.neutra { color: var(--texto-v2-suave); border-color: var(--vidrio-borde); background: var(--campo); }
.etiqueta-estado.atencion { color: #06060a; background: rgba(var(--c3), 0.9); border-color: rgb(var(--c3)); }
.etiqueta-estado.ok { color: #06060a; background: rgba(var(--c6), 0.85); border-color: rgb(var(--c6)); }
.etiqueta-estado.error { color: #fff; background: rgba(var(--peligro), 0.85); border-color: rgb(var(--peligro)); }

.estado-suave { font-size: 0.75rem; font-weight: 700; padding: 2px 10px; border-radius: 999px;
  background: var(--superficie-2); color: var(--texto-v2-suave); border: 1px solid var(--vidrio-borde); }
.estado-suave.activo { color: rgb(var(--acento-texto)); border-color: rgba(var(--acento-texto), 0.35); background: rgba(var(--acento-texto), 0.08); }
.estado-suave.ok { color: rgb(var(--c6)); border-color: rgba(var(--c6), 0.4); background: rgba(var(--c6), 0.08); }
.estado-suave.error { color: rgb(var(--peligro)); border-color: rgba(var(--peligro), 0.35); background: rgba(var(--peligro), 0.08); }

/* ===== Tarjetas (guía §7) ===== */
.rejilla { list-style: none; margin: 0; padding: 0; display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(min(250px, 100%), 1fr)); }
.rejilla > li { display: flex; }
.rejilla > li > .tarjeta { flex: 1; }
.rejilla > li:nth-child(6n + 1) { --a: var(--c1); --relleno: var(--relleno-c1); }
.rejilla > li:nth-child(6n + 2) { --a: var(--c2); --relleno: initial; }
.rejilla > li:nth-child(6n + 3) { --a: var(--c3); --relleno: initial; }
.rejilla > li:nth-child(6n + 4) { --a: var(--c4); --relleno: initial; }
.rejilla > li:nth-child(6n + 5) { --a: var(--c5); --relleno: var(--relleno-c5); }
.rejilla > li:nth-child(6n + 6) { --a: var(--c6); --relleno: initial; }
.rejilla > li:nth-child(6n + 2), .rejilla > li:nth-child(6n + 3),
.rejilla > li:nth-child(6n + 4), .rejilla > li:nth-child(6n + 6) {
  --texto-boton: #06060a; --sombra-texto-boton: 0 1px 0 rgba(255, 255, 255, 0.35);
}

.tarjeta {
  position: relative; overflow: hidden; display: flex; flex-direction: column;
  border-radius: 18px; padding: 7px; color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 50%, rgba(var(--a), var(--tinte)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 55%, var(--vidrio-a) 100%);
  border: 1px solid rgba(var(--a), 0.38);
  box-shadow:
    0 18px 44px rgba(var(--a), 0.2), var(--vidrio-sombra),
    inset 0 1px 0 rgba(255, 255, 255, 0.35), inset 0 -2px 4px rgba(0, 0, 0, 0.18),
    inset 2px 0 4px rgba(255, 255, 255, 0.08), inset -2px 0 4px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.tarjeta:hover { transform: translateY(-3px);
  box-shadow: 0 26px 60px rgba(var(--a), 0.3), var(--vidrio-sombra), inset 0 1px 0 rgba(255, 255, 255, 0.35); }
.tarjeta::before { content: ""; position: absolute; top: 0; left: 8%; right: 8%; height: 1px; z-index: 3;
  background: linear-gradient(90deg, transparent, rgb(var(--a)), transparent); }
.tarjeta::after {
  content: ""; position: absolute; inset: -40% auto auto -30%; width: 70%; height: 160%;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, 0.14) 45%, rgba(255, 255, 255, 0.04) 60%, transparent 100%);
  transform: rotate(18deg); pointer-events: none; z-index: 2;
}
.tarjeta > * { position: relative; z-index: 1; }
.tarjeta .boton { --a: inherit; --relleno: inherit; z-index: 4; }

.enlace-tarjeta::after { content: ""; position: absolute; inset: 0; z-index: 3; }

.foto { position: relative; aspect-ratio: 4 / 3; border-radius: 13px; display: grid; place-items: center; isolation: isolate; }
.foto::before {
  content: ""; position: absolute; inset: 8% 22%; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(var(--a), 0.45) 0%, rgba(var(--a), 0.12) 45%, transparent 70%);
  filter: blur(18px);
}
.foto img { width: 82%; height: 82%; object-fit: contain; border-radius: 14px;
  filter: drop-shadow(0 18px 22px rgba(0, 0, 0, 0.35)); }
.marcador-imagen {
  width: 60%; height: 78%; border-radius: 12px; border: 1.5px dashed var(--placeholder-borde);
  display: grid; place-items: center; text-align: center; padding: 8px;
  color: var(--texto-v2-tenue); font-size: 0.65rem; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 700;
}

.cuerpo-tarjeta { padding: 8px 4px 2px; display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 0; }
.cuerpo-tarjeta h2 {
  margin: 0; font-family: var(--fuente-texto), sans-serif; font-weight: 700; font-size: 0.95rem; line-height: 1.25;
  min-height: 2.5em; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pie-tarjeta { margin-top: auto; padding-top: 6px; }
.cifra { font-family: var(--fuente-titulo), sans-serif; font-weight: 800; font-size: 1.45rem;
  letter-spacing: -0.02em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.cifra-anterior { color: var(--texto-v2-tenue); text-decoration: line-through; font-weight: 500; font-size: 0.75rem; }

/* ===== Formularios (guía §8) ===== */
.formulario { display: grid; gap: 16px; }
/* La guía solo define .campo-grupo escapado dentro de .tarjeta-solida
   (§10) — acá una versión general, para que agrupar label+campo+error
   funcione igual en cualquier formulario, no solo en las pantallas de cuenta. */
.campo-grupo { display: grid; gap: 6px; }
.formulario fieldset { border-radius: var(--radio); padding: 18px; margin: 0; display: grid; gap: 14px; border: none; }
.formulario legend { float: left; width: 100%; display: flex; align-items: center; gap: 8px;
  font-family: var(--fuente-titulo), sans-serif; font-weight: 800; font-size: 1.05rem; padding: 0; margin-bottom: 4px; color: var(--texto-v2); }
.formulario legend svg { color: rgb(var(--c1)); }
.formulario label { display: grid; gap: 6px; font-size: 0.8rem; font-weight: 700; color: var(--texto-v2-suave); }
.formulario small { color: var(--texto-v2-tenue); font-weight: 500; }

.campo, .formulario input, .formulario select, .formulario textarea {
  width: 100%; min-width: 0; padding: 11px 14px; font: inherit; font-size: 0.95rem; color: var(--texto-v2);
  background: var(--campo); border: 1px solid var(--vidrio-borde); border-radius: 12px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.campo:focus, .formulario input:focus, .formulario select:focus, .formulario textarea:focus {
  outline: none; border-color: rgba(var(--c2), 0.7); box-shadow: 0 0 0 3px rgba(var(--c2), 0.2);
}
.formulario select option { background: var(--fondo); color: var(--texto-v2); }
.formulario select:disabled { opacity: 0.5; }

.dos-columnas { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

.prefijo { display: flex; align-items: stretch; }
.prefijo span { display: inline-flex; align-items: center; gap: 6px; padding: 0 12px; border-radius: 12px 0 0 12px;
  background: var(--vidrio-a); border: 1px solid var(--vidrio-borde); border-right: 0; font-weight: 700; color: var(--texto-v2); }
.prefijo input { border-radius: 0 12px 12px 0 !important; }

.casilla { display: flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.9rem; color: var(--texto-v2); font-weight: 600; }
.casilla input { width: 18px; height: 18px; padding: 0; accent-color: rgb(var(--acento)); flex: none; }

.opcion { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-radius: 12px; cursor: pointer;
  background: var(--campo); border: 1px solid var(--vidrio-borde); transition: border-color 0.2s ease, background 0.2s ease; }
.opcion:has(input:checked) { border-color: rgba(var(--a), 0.8); background: rgba(var(--a), calc(var(--tinte) * 1.2)); }
.opcion input { accent-color: rgb(var(--a)); }

.cantidad-control { display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: 999px;
  background: var(--campo); border: 1px solid var(--vidrio-borde); }
.cantidad-control button { width: 36px; height: 36px; border-radius: 50%; border: 0; cursor: pointer; display: grid; place-items: center;
  background: var(--vidrio-a); color: var(--texto-v2); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 2px 6px rgba(0, 0, 0, 0.15); }
.cantidad-control output { min-width: 2ch; text-align: center; font-weight: 800; font-variant-numeric: tabular-nums; }

.campo[aria-invalid="true"] { border-color: rgba(var(--peligro), 0.7); }
.error-campo { color: rgb(var(--peligro)); font-size: 0.82rem; font-weight: 600; }
.ayuda-campo { color: var(--texto-v2-tenue); font-size: 0.8rem; }

:focus-visible { outline: 2px solid rgb(var(--c2)); outline-offset: 2px; }

/* ===== Campo de contraseña con ojito (guía §9) =====
   La lógica (no roba el foco, se oculta al enviar, etc.) ya existe y
   funciona en js/ver-contrasena.js — acá solo el CSS nuevo, mismas
   clases que usa ese archivo (.campo-clave/.ojito), sin reescribir
   nada de JS. */
.campo-clave { position: relative; }
.campo-clave .campo { padding-right: 50px; }
.ojito {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 38px; height: 38px; border: 0; border-radius: 10px; cursor: pointer;
  display: grid; place-items: center; background: transparent; color: var(--texto-v2-suave);
}
.ojito:hover { color: var(--texto-v2); background: var(--vidrio-borde); }
.ojito[aria-pressed="true"] { color: rgb(var(--acento-texto)); }

/* ===== Variante sobria: tarjeta sólida (guía §10) =====
   Para login/registro/restablecer-contrasena/perfil. */
.pantalla-cuenta { display: grid; justify-items: center; align-content: start; min-height: calc(100vh - 160px); padding-top: 32px; }
.tarjeta-solida {
  width: 100%; max-width: 420px; display: grid; gap: 18px; padding: 28px 24px; color: var(--texto-v2);
  background: var(--superficie); border: 1px solid var(--vidrio-borde); border-radius: 20px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.14);
}
.tarjeta-solida.ancha { max-width: 720px; }
.tarjeta-solida h1 { font-size: 1.55rem; }
.tarjeta-solida .sub { color: var(--texto-v2-suave); margin: 0; }

.tarjeta-solida .campo { background: var(--superficie-2); padding: 12px 14px; font-size: 1rem; }
.tarjeta-solida .campo:focus { outline: none; border-color: rgba(var(--acento-texto), 0.75); box-shadow: 0 0 0 3px rgba(var(--acento-texto), 0.18); }
.tarjeta-solida .campo-grupo { display: grid; gap: 6px; }
.tarjeta-solida .campo-grupo label { font-size: 0.85rem; font-weight: 700; color: var(--texto-v2); }
.tarjeta-solida :focus-visible { outline-color: rgb(var(--acento-texto)); }

.tarjeta-solida .boton { background: rgb(var(--acento)); border-color: transparent; text-shadow: none; color: #fff;
  box-shadow: 0 6px 18px rgba(var(--acento), 0.28); }
.tarjeta-solida .boton::before, .tarjeta-solida .boton::after { display: none; }
.tarjeta-solida .boton:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 8px 22px rgba(var(--acento), 0.36); }
.tarjeta-solida .boton-vidrio { background: var(--superficie-2); backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }

.enlace-acento { color: rgb(var(--acento-texto)); font-weight: 700; }
.enlace-acento:hover { text-decoration: underline; }
/* La guía no trae esto: un <button> (acción de JS, no navegación) con
   aspecto de enlace — ej. "¿Olvidaste tu contraseña?". Mismo color que
   .enlace-acento, con el reset de botón nativo encima. */
.enlace-acento-boton {
  display: block; margin: 8px auto 0; padding: 10px 8px; border: none; background: none;
  font: inherit; font-weight: 700; color: rgb(var(--acento-texto)); text-decoration: underline; cursor: pointer;
}
.pie-tarjeta-solida { margin: 0; text-align: center; font-size: 0.92rem; color: var(--texto-v2-suave); }

.icono-redondo { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; justify-self: center;
  color: rgb(var(--acento-texto)); background: rgba(var(--acento-texto), 0.12); }

.lista-simple { list-style: none; margin: 0; padding: 0; display: grid; }
.lista-simple > li { border-bottom: 1px solid var(--vidrio-borde); }
.lista-simple > li:last-child { border-bottom: 0; }
.fila { display: flex; align-items: center; gap: 12px; padding: 12px 4px; min-width: 0; }
.fila-principal { display: grid; gap: 2px; flex: 1; min-width: 0; }
.fila-principal small { color: var(--texto-v2-suave); font-size: 0.84rem; }
.bloque-enlace { background: var(--superficie-2); border-radius: 14px; padding: 14px 16px; }

/* ===== Avisos y estados (guía §11) ===== */
.aviso { display: flex; align-items: center; gap: 8px; margin: 0; padding: 10px 14px; border-radius: 12px;
  font-size: 0.9rem; font-weight: 700; border: 1px solid; }
.aviso.ok   { color: rgb(var(--c6)); background: rgba(var(--c6), 0.1); border-color: rgba(var(--c6), 0.35); }
.aviso.no   { color: rgb(var(--peligro)); background: rgba(var(--peligro), 0.1); border-color: rgba(var(--peligro), 0.35); }
.aviso.info { color: var(--texto-v2); background: rgba(var(--c3), 0.14); border-color: rgba(var(--c3), 0.5); }
.aviso a { text-decoration: underline; }

.vacio { padding: 40px 20px; text-align: center; color: var(--texto-v2-suave); border-radius: var(--radio);
  display: grid; justify-items: center; gap: 10px; }
.vacio svg { color: rgb(var(--c1)); }
.vacio a { color: rgb(var(--c2)); font-weight: 700; }

.barra-progreso { height: 8px; border-radius: 999px; background: var(--campo); border: 1px solid var(--vidrio-borde); overflow: hidden; }
.barra-progreso span { display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, rgb(var(--c1)), rgb(var(--c4)), rgb(var(--c3))); }

/* ===== Botón de tema (guía §12, adaptado — ver AVISO junto a
   [data-theme="dark"] más arriba: SOLO por atributo, sin detección
   automática del sistema todavía) ===== */
.tema-oscuro { display: none; }
:root[data-theme="dark"] .tema-oscuro { display: block; }
:root[data-theme="dark"] .tema-claro { display: none; }

/* ===== Adaptación a móvil y movimiento reducido (guía §14) ===== */
@media (max-width: 560px) {
  .dos-columnas { grid-template-columns: 1fr; }
  .pestanas { padding: 10px 2px 6px; gap: 8px; }
  .chip { padding: 7px 12px; font-size: 0.82rem; border-radius: 12px; }
  .rejilla { gap: 14px; }
  .orbe { filter: blur(40px); }
  .tarjeta-solida { padding: 22px 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .orbe { animation: none; }
  .tarjeta, .boton, .boton-vidrio, .chip { transition: none; }
  .tarjeta:hover, .chip:hover { transform: none; }
}

* { box-sizing: border-box; }

/* El atributo [hidden] tiene que ganar SIEMPRE, sin importar qué otra
   clase traiga el elemento. Sin esto, cualquier clase que fije su propio
   "display" (ej. .btn-vidrio, .tab) empata en especificidad con la regla
   [hidden]{display:none} del navegador y, al cargar después en la hoja
   de estilos, gana ella — el elemento queda visible aunque tenga
   "hidden" puesto (bug real encontrado en pago-resultado.html: un botón
   con class="btn-vidrio" y "hidden" a la vez seguía mostrándose). */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  font-size: 18px;
  color: var(--texto);
}

body {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  /* Fondo nuevo (guía §2): reemplaza el degradado plano viejo por uno
     que sí reacciona al tema — con esto + la capa .ambiente (esferas
     grandes animadas, más abajo) el fondo entero pasa a claro/oscuro
     según [data-theme]. Antes de este cambio el fondo se quedaba
     siempre en el degradado claro viejo aunque el tema pasara a
     oscuro (bug encontrado en la prueba visual de la Fase 1). */
  background:
    radial-gradient(ellipse 80% 50% at 50% -20%, rgba(var(--c1), calc(var(--orbe-alfa) * 0.9)) 0%, transparent 100%),
    radial-gradient(ellipse 60% 40% at 100% 50%, rgba(var(--c2), calc(var(--orbe-alfa) * 0.6)) 0%, transparent 100%),
    radial-gradient(ellipse 60% 40% at 0% 60%, rgba(var(--c5), calc(var(--orbe-alfa) * 0.6)) 0%, transparent 100%),
    linear-gradient(var(--rejilla) 1px, transparent 1px),
    linear-gradient(90deg, var(--rejilla) 1px, transparent 1px),
    var(--fondo);
  background-size: auto, auto, auto, 48px 48px, 48px 48px, auto;
  background-attachment: fixed;
  padding: 24px 20px 48px;
}

h1 {
  font-size: 24px;
  color: var(--azul-oscuro);
  margin: 0 0 8px;
}

.subtitulo {
  color: #555;
  font-size: 15px;
  margin: 0 0 24px;
}

.btn-vidrio {
  display: block;
  width: 100%;
  min-height: 56px;
  border-radius: 12px;
  font-size: 18px;
  border: none;
  cursor: pointer;
  transition: transform 0.08s ease;
}

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

.btn-vidrio:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

/* Patrón "etiqueta + valor" dentro de una .tarjeta-vidrio, para mostrar
   un dato (ej. el perfil del cliente). */
.campo-etiqueta {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.85;
  margin-bottom: 2px;
}

.campo-valor {
  font-size: 18px;
  margin: 0;
}

/* ===== Panel lateral (menú hamburguesa) =====
   Restyleado en el lugar con los tokens nuevos (Fase 3, 25/09/2026) —
   mismas clases y mismo comportamiento (js/panel-lateral.js no
   cambia, solo lee ids y .abierto). No hace falta un nombre
   transicional acá como con .vidrio→.cristal: el panel lateral se
   migra completo (HTML + CSS) para las 9 pantallas de esta fase a la
   vez, no queda ninguna versión vieja conviviendo al terminar. */
.panel-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(6, 6, 10, 0.6);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  z-index: 30;
  border: none;
  padding: 0;
  margin: 0;
}

.panel-lateral {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: min(82vw, 300px);
  z-index: 31;
  background: var(--superficie);
  color: var(--texto-v2);
  font-family: var(--fuente-texto), sans-serif;
  box-shadow: 4px 0 24px rgba(0, 0, 0, 0.25);
  padding: 28px 18px;
  overflow-y: auto;
  transform: translateX(-105%);
  transition: transform 0.22s ease;
}

.panel-lateral.abierto {
  transform: translateX(0);
}

.panel-usuario {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-bottom: 20px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--vidrio-borde);
}

.avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 22px;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  background: linear-gradient(145deg, rgb(var(--c1)) 0%, rgb(var(--c5)) 100%);
}

.panel-nombre {
  font-weight: 700;
  margin: 0;
}

.panel-correo {
  font-size: 13px;
  color: var(--texto-v2-suave);
  margin: 2px 0 0;
  word-break: break-all;
}

.panel-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.panel-links a,
.panel-links button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 10px;
  border-radius: 10px;
  border: none;
  background: none;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  color: var(--texto-v2);
  text-decoration: none;
  cursor: pointer;
  text-align: left;
}

.panel-links a:active,
.panel-links button:active {
  background: rgba(var(--c1), 0.08);
}

.panel-links button {
  color: rgb(var(--peligro));
}

.panel-links svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ===== Grilla de accesos rápidos y banner promocional (inicio.html) =====
   Fase 4 (25/09/2026): restyleado en el lugar con los tokens nuevos.
   Solo lo usa inicio.html, así que no hace falta el truco del nombre
   transicional (ver AVISO de .cristal) — se migra HTML + CSS juntos acá. */
.grilla-accesos {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin: 16px 0 20px;
}

/* Es un modificador de layout sobre .tarjeta (icono+texto centrados en
   vez de foto+cuerpo) — el fondo de color lo sigue dando .tarjeta +
   .color-N, acá no se repite esa receta. */
.tarjeta-acceso {
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 26px 12px;
  text-decoration: none;
  text-align: center;
}

.acceso-icono svg {
  width: 36px;
  height: 36px;
  color: rgb(var(--a));
}

.acceso-texto {
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 1rem;
  font-weight: 800;
  color: var(--texto-v2);
}

/* Tarjeta que aún no funciona (ej. Mercado, Fase 7): gris, apagada, con
   candado y borde punteado, para que nadie la confunda con una opción
   activa. No es un enlace ni un botón: tocarla no hace nada. Va sobre
   .cristal (sin color propio), no sobre .tarjeta. */
.tarjeta-acceso-deshabilitada {
  position: relative;
  grid-column: 1 / -1;
  padding: 20px 12px;
  opacity: 0.6;
  filter: grayscale(1);
  border: 2px dashed var(--placeholder-borde);
  box-shadow: none;
  cursor: not-allowed;
  user-select: none;
}

.acceso-candado {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 22px;
  height: 22px;
  color: var(--texto-v2);
}

.badge-proximamente {
  padding: 4px 14px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* ===== Carrusel de promociones (inicio.html, js/inicio.js) =====
   Desplazamiento horizontal nativo con scroll-snap (se desliza con el
   dedo); el JS solo avanza solo cada 4 s y sincroniza los puntos. El
   padding inferior y el margen negativo evitan que el overflow recorte
   la sombra de las tarjetas. */
.carrusel {
  margin-bottom: 20px;
}

.carrusel-pista {
  position: relative;
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding: 4px 0 28px;
  margin-bottom: -12px;
}

.carrusel-pista::-webkit-scrollbar {
  display: none;
}

/* Fondo propio (no reusa .tarjeta: layout de grilla 2 columnas distinto,
   no la pila vertical foto+cuerpo) con la MISMA receta de color que
   .tarjeta — degradado teñido de --a sobre el vidrio nuevo. */
.carrusel-tarjeta {
  flex: 0 0 100%;
  scroll-snap-align: start;
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  align-items: center;
  gap: 6px;
  padding: 24px 14px 24px 24px;
  border-radius: 20px;
  min-height: 228px;
  color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 50%, rgba(var(--a), var(--tinte)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 55%, var(--vidrio-a) 100%);
  border: 1px solid rgba(var(--a), 0.38);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  /* Sombra que solo sale hacia abajo (spread negativo): la pista del
     carrusel recorta lo que se sale por los lados y se notaría un corte. */
  box-shadow:
    0 12px 16px -10px rgba(var(--a), 0.6),
    0 2px 4px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -2px 4px rgba(0, 0, 0, 0.18);
}

.carrusel-contenido {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}

.carrusel-titulo {
  margin: 0;
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 23px;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-wrap: balance; /* evita una palabra huérfana en la última línea */
}

.carrusel-apoyo {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  opacity: 0.9;
}

/* Botón oscuro fijo (no sigue el tema): tiene que resaltar igual sobre
   CUALQUIERA de los colores vivos de la paleta, en claro o en oscuro —
   la guía no trae esta variante ("botón siempre oscuro sobre tarjeta de
   color"), es una necesidad propia de este carrusel. */
.carrusel-tarjeta .boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 0 18px 0 20px;
  border-radius: 999px;
  font-size: 15px;
  white-space: nowrap;
  background: rgba(6, 6, 10, 0.82);
  border-color: transparent;
  color: #fff;
}
.carrusel-tarjeta .boton::before,
.carrusel-tarjeta .boton::after {
  display: none;
}

.carrusel-tarjeta .boton svg {
  width: 18px;
  height: 18px;
}

/* Ilustración protagonista: sobre un resplandor blanco circular (mancha
   de luz) con un anillo tenue, y flotando muy despacio. */
.carrusel-arte {
  position: relative;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

.carrusel-arte::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 118%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(255, 255, 255, 0.6) 42%,
    rgba(255, 255, 255, 0) 70%
  );
  pointer-events: none;
}

.carrusel-arte::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 96%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.55);
  pointer-events: none;
}

.carrusel-arte img {
  position: relative;
  z-index: 1;
  width: 100%;
  max-height: 190px;
  object-fit: contain;
  filter: drop-shadow(0 10px 12px rgba(0, 0, 0, 0.2));
  animation: carrusel-flotar 5s ease-in-out infinite;
}

@keyframes carrusel-flotar {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

@media (prefers-reduced-motion: reduce) {
  .carrusel-arte img { animation: none; }
}

/* Si una ilustración no carga, en su lugar queda el ícono Lucide (ver
   js/inicio.js): burbuja clara con el ícono grande. */
.carrusel-icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  color: var(--texto-v2);
  background: var(--vidrio-a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 3px 8px rgba(0, 0, 0, 0.2);
}

.carrusel-icono svg {
  width: 44px;
  height: 44px;
}

/* Celulares angostos: un poco menos de texto y más lugar para la ilustración. */
@media (max-width: 380px) {
  .carrusel-tarjeta {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    padding: 18px 10px 18px 16px;
  }
  .carrusel-titulo { font-size: 19px; }
  .carrusel-tarjeta .boton { padding: 0 14px 0 16px; font-size: 14px; gap: 6px; }
}

.carrusel-controles {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.carrusel-puntos {
  display: flex;
  align-items: center;
}

/* El punto se ve de 10px, pero el botón mide 32px para poder tocarlo. */
.carrusel-punto {
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.carrusel-punto::before {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--texto-v2-tenue);
  transition: width 0.2s ease, background 0.2s ease;
}

.carrusel-punto[aria-current="true"]::before {
  width: 24px;
  border-radius: 6px;
  background: rgb(var(--c1));
}

.carrusel-pausa {
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--texto-v2);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.carrusel-pausa svg {
  width: 18px;
  height: 18px;
}

.carrusel-punto:focus-visible,
.carrusel-pausa:focus-visible {
  outline: 2px solid rgb(var(--c1));
  outline-offset: 1px;
}

/* ===== Buscador (cliente/contactos.html) =====
   Fase 5 (25/09/2026): restyleado en el lugar con los tokens nuevos.
   Comparte clases con historial.html (.tab/.tabs) — ver AVISO ahí abajo. */
.campo-buscador {
  position: relative;
  margin: 4px 0 16px;
}

.campo-buscador svg {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--texto-v2-tenue);
  pointer-events: none;
}

.campo-buscador input {
  width: 100%;
  font: inherit;
  font-size: 16px;
  padding: 12px 14px 12px 42px;
  border: 1px solid var(--vidrio-borde);
  border-radius: 12px;
  background: var(--campo);
  color: var(--texto-v2);
  margin: 0;
}

.campo-buscador input:focus {
  outline: none;
  border-color: rgba(var(--c2), 0.7);
  box-shadow: 0 0 0 3px rgba(var(--c2), 0.2);
}

/* ===== Tabs (Contactos / Historial) =====
   AVISO: .tab/.tabs también las usa historial.html (nav Contactos↔Historial
   y sub-tabs Móvil/Nauta) — se restylean acá una sola vez, no hace falta
   repetirlo cuando llegue la fase de historial.html. */
.tabs {
  display: flex;
  gap: 20px;
  border-bottom: 1px solid var(--vidrio-borde);
  margin-bottom: 18px;
}

.tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 2px 12px;
  border: none;
  background: none;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  color: var(--texto-v2-suave);
  text-decoration: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
}

.tab svg {
  width: 16px;
  height: 16px;
}

.tab-activa {
  color: var(--texto-v2);
  border-bottom-color: rgb(var(--c1));
}

/* ===== Recientes ===== */
.subtitulo-seccion {
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 0.85rem;
  font-weight: 800;
  color: var(--texto-v2-suave);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 10px;
}

.recientes-fila {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  padding: 4px 2px 12px;
  margin-bottom: 8px;
}

.reciente-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  width: 64px;
  text-decoration: none;
}

.avatar-reciente {
  width: 56px;
  height: 56px;
  font-size: 18px;
}

.reciente-nombre {
  font-size: 12px;
  font-weight: 600;
  color: var(--texto-v2);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
}

/* ===== Lista de contactos ===== */
.lista-contactos {
  list-style: none;
  margin: 0 0 96px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Mismo degradado teñido que .tarjeta/.carrusel-tarjeta, con --a fijado
   por tipo (móvil=cian, nauta=violeta) en vez de por posición — para
   reconocer el tipo de un contacto de un vistazo. */
.contacto-item {
  --a: var(--c2);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 100%);
  border: 1px solid rgba(var(--a), 0.35);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
}

.contacto-item[data-tipo="nauta"] { --a: var(--c5); }

.contacto-bandera {
  width: 28px;
  height: auto;
  flex-shrink: 0;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
}

.contacto-info {
  flex: 1;
  min-width: 0;
}

.contacto-nombre {
  font-weight: 800;
  margin: 0;
}

.contacto-destino {
  font-size: 14px;
  margin: 2px 0 0;
  opacity: 0.85;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btn-icono-chico {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.3);
  color: inherit;
  cursor: pointer;
  text-decoration: none;
}

.btn-icono-chico:active {
  background: rgba(255, 255, 255, 0.5);
}

.btn-icono-chico svg {
  width: 18px;
  height: 18px;
}

/* ===== Botón flotante "Nuevo contacto" (contactos.html) =====
   .boton ya trae el color/relleno/sombra — acá solo la posición fija y
   la forma píldora compacta. right: usa la mitad del ancho de pantalla
   menos la mitad del ancho máximo del body (480px) para quedar en el
   borde de la columna en pantallas anchas; max() lo deja en 20px en
   celular. z-index 15: por debajo del modal y su fondo. */
.btn-nuevo-contacto-flotante {
  position: fixed;
  bottom: 20px;
  right: max(20px, calc(50vw - 220px));
  z-index: 15;
  min-height: 46px;
  padding: 0 20px 0 16px;
}

/* Deja espacio al final para que el botón flotante no tape el último contacto. */
.con-barra-inferior {
  padding-bottom: 88px;
}

/* ===== Modal "Nuevo contacto" =====
   Mismos tokens que .ventana (guía §3), pero se mantiene la posición de
   hoja que sube desde abajo (no el modal centrado de la guía) — es un
   cambio de comportamiento, no solo de estilo, y esta migración es
   solo visual. */
.modal-vidrio {
  position: fixed;
  left: 50%;
  bottom: 0;
  z-index: 41;
  width: min(92vw, 440px);
  max-height: 85vh;
  overflow-y: auto;
  padding: 22px;
  border-radius: 20px 20px 0 0;
  color: var(--texto-v2);
  background: linear-gradient(145deg, rgba(var(--c1), 0.08), transparent 45%), var(--ventana);
  box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.35), 0 0 0 1px var(--vidrio-borde), inset 0 1px 0 rgba(255, 255, 255, 0.2);
  transform: translate(-50%, 105%);
  transition: transform 0.22s ease;
}

.modal-vidrio.abierto {
  transform: translate(-50%, 0);
}

.modal-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.modal-cabecera h2 {
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 1.15rem;
  font-weight: 800;
  margin: 0;
  color: var(--texto-v2);
}

.selector-tipo {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  margin: 8px 0 18px;
}

/* Restyleado en el lugar, MISMO mecanismo que antes (botón +
   aria-pressed, no <input type="radio">: cambiar eso sería lógica, no
   diseño — js/contactos.js sigue exactamente igual). Fondo con el
   mismo degradado teñido de --a que .contacto-item/.tarjeta. */
.btn-tipo {
  --a: var(--c2);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 56px;
  font: inherit;
  font-size: 16px;
  font-weight: 700;
  color: var(--texto-v2);
  border-radius: 12px;
  cursor: pointer;
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 100%);
  border: 1px solid rgba(var(--a), 0.35);
  transition: opacity 0.15s ease, filter 0.15s ease, transform 0.08s ease, border-color 0.15s ease;
}

.btn-tipo[data-tipo="nauta"] { --a: var(--c5); }

.btn-tipo svg {
  width: 20px;
  height: 20px;
  color: rgb(var(--a));
}

/* El no elegido se apaga (opacidad + gris) en vez de quedar igual de vivo
   que el elegido — bug de contraste ya corregido antes (ver commit
   original), se mantiene el mismo criterio con los tokens nuevos. */
.btn-tipo[aria-pressed="false"] {
  opacity: 0.5;
  filter: grayscale(0.7);
}

.btn-tipo[aria-pressed="true"] {
  border-width: 3px;
  border-color: rgb(var(--a));
  transform: scale(1.03);
}

/* ===== Chip de país (form "Nuevo contacto", solo tipo Móvil) =====
   Solo Cuba disponible por ahora, así que es informativo, no un selector
   — por eso no es un <button> ni tiene aria-pressed, y el ícono de check
   refuerza "esto ya está fijo" en vez de "tocá para elegir". Mismos
   tokens que .pastilla (guía §6). */
.chip-pais {
  display: flex;
  align-items: center;
  gap: 10px;
  width: fit-content;
  padding: 10px 16px;
  border-radius: 999px;
  margin: 8px 0 18px;
  color: var(--texto-v2);
  background: var(--vidrio-a);
  border: 1px solid var(--vidrio-borde);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}

.chip-pais-bandera {
  width: 26px;
  height: auto;
  display: block;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
}

.chip-pais-nombre {
  font-size: 16px;
  font-weight: 600;
}

.chip-pais svg {
  width: 16px;
  height: 16px;
  color: rgb(var(--c6));
  margin-left: 2px;
}

/* ===== catalogo-movil.html / catalogo-nauta.html =====
   Fase 6 (25/09/2026): restyleado en el lugar con los tokens nuevos. */
.contacto-contexto {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 14px;
  margin-bottom: 20px;
  color: #fff;
  background: linear-gradient(145deg, rgb(var(--c1)) 0%, rgb(var(--c5)) 100%);
  box-shadow: 0 8px 24px rgba(var(--c1), 0.35), 0 2px 4px rgba(0, 0, 0, 0.3);
}

.contacto-contexto-etiqueta {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.85;
}

.contacto-contexto-nombre {
  font-weight: 800;
  font-size: 17px;
}

.aviso-nauta {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--texto-v2);
}

.aviso-nauta svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-top: 1px;
  color: rgb(var(--c5));
}

.aviso-nauta p {
  margin: 0;
}

.lista-productos {
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Mismo degradado teñido de --a que .tarjeta/.contacto-item, con la
   rotación de paleta puesta en --a (antes --vidrio-rgb) por posición —
   se repite cada 6 productos, para catálogos de cualquier tamaño. */
.tarjeta-producto {
  --a: var(--c1);
  position: relative;
  overflow: hidden;
  border-radius: 16px;
  padding: 18px;
  color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 100%);
  border: 1px solid rgba(var(--a), 0.35);
  box-shadow: var(--vidrio-sombra);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
}

.lista-productos .tarjeta-producto:nth-child(6n+1) { --a: var(--c1); }
.lista-productos .tarjeta-producto:nth-child(6n+2) { --a: var(--c2); }
.lista-productos .tarjeta-producto:nth-child(6n+3) { --a: var(--c4); }
.lista-productos .tarjeta-producto:nth-child(6n+4) { --a: var(--c5); }
.lista-productos .tarjeta-producto:nth-child(6n+5) { --a: var(--c3); }
.lista-productos .tarjeta-producto:nth-child(6n) { --a: var(--c6); }

/* ===== Promoción especial (catalogo-movil.html) =====
   Tarjetas con "esPromoEspecial" de la Edge Function (hoy, las 2 ofertas
   de QvaPay: 500 CUP+internet y 3000 CUP+internet — pueden ser 0, 1 o
   varias a la vez), ubicadas ARRIBA de todo el catálogo normal (así está
   el HTML) y con un diseño propio, no el vidrio genérico de
   .tarjeta-producto: son las ofertas más fuertes y no pueden perderse
   entre las demás. */
/* Degradado dorado -> naranja -> coral: los 3 tonos pasan 4.5:1+ con
   texto NEGRO (verificado con la fórmula de contraste real, mismo
   criterio que el resto del proyecto — ver AVISO de .vidrio más arriba),
   así que esta tarjeta sigue la regla general y NO necesita texto
   blanco. Un rojo más oscuro (ej. #e11d1d) se veía más "urgente" pero
   bajaba el contraste del negro por debajo de 4.5:1 en esa zona. */
.tarjeta-promo-especial {
  /* Mismo degradado dorado->naranja->coral de siempre — es intencional
     que NO reaccione al tema (una oferta "urgente" se ve igual de
     llamativa en claro y en oscuro), y el texto sigue siendo negro fijo
     (no var(--texto-v2), que en oscuro sería blanco e ilegible acá):
     contraste ya verificado con la fórmula real, ver AVISO de guía §13. */
  color: #06060a;
  background: linear-gradient(145deg, #f5b301 0%, #f2751a 55%, #ff6b52 100%);
  border: 3px solid rgba(255, 214, 102, 0.9);
  border-radius: 18px;
  padding: 20px;
  box-shadow:
    0 10px 28px rgba(217, 119, 6, 0.45),
    0 2px 4px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.5);
  /* Sin margin-bottom propio: el <ul> padre (.lista-productos) ya pone
     14px de gap entre tarjetas y 32px antes del catálogo normal — puede
     haber 0, 1 o 2 promos especiales a la vez (ver AVISO arriba). */
}

.promo-especial-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  text-shadow: none;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin-bottom: 10px;
}

.promo-especial-badge svg {
  width: 15px;
  height: 15px;
}

/* Mismo tratamiento que .promo-especial-badge (píldora oscura + texto
   blanco): así su contraste no depende de en qué parte del degradado
   caiga, y además se lee como un aviso independiente, tipo cuenta
   regresiva. */
.promo-especial-urgencia {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  text-shadow: none;
  font-size: 13px;
  font-weight: 800;
  margin: 0 0 12px 8px;
}

.promo-especial-urgencia svg {
  width: 15px;
  height: 15px;
}

.promo-especial-titulo {
  font-size: 22px;
  font-weight: 800;
  margin: 0 0 6px;
  text-wrap: balance;
}

.promo-especial-descripcion {
  font-size: 14px;
  font-weight: 700;
  opacity: 0.95;
  margin: 0 0 16px;
}

/* El grid Recibe/Precio y el botón Comprar reutilizan tal cual las
   clases genéricas (.producto-montos, .btn-comprar-producto) — ya son
   blancas/translúcidas sobre cualquier color de fondo, así que no hacen
   falta ajustes especiales acá. */

.producto-cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}

.producto-nombre {
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 19px;
  font-weight: 800;
}

.badge-promo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--vidrio-a);
  color: rgb(var(--a));
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
  flex-shrink: 0;
}

.badge-promo svg {
  width: 13px;
  height: 13px;
}

.producto-descripcion {
  font-size: 14px;
  opacity: 0.85;
  margin: 0 0 14px;
}

/* Detalle chico y secundario (Minutos/Datos móviles) — nunca el texto
   principal de la tarjeta, solo ayuda a distinguir productos con el
   mismo precio. */
.producto-etiqueta-beneficio {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.6;
  margin: -8px 0 14px;
}

.producto-montos {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-bottom: 16px;
}

/* Productos sin monto "Recibe" (bundles/combos): solo el precio. */
.producto-montos-solo-precio {
  grid-template-columns: 1fr;
}

/* Selector de monto para productos de rango abierto (ver
   catalogo-movil.js) — va ANTES de .producto-montos, a todo el ancho de
   la tarjeta: los botones de monto necesitan más espacio del que le
   tocaría a una sola columna del grid de al lado. */
.selector-monto-abierto {
  margin-bottom: 14px;
}

.montos-sugeridos {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

/* border/background con los tokens de vidrio (--vidrio-borde/--vidrio-a)
   en vez de negro/blanco fijos a propósito: son theme-aware (claros en
   tema claro, translúcidos claros en oscuro) y funcionan igual de bien
   sobre CUALQUIER color de --a de la tarjeta, en los dos temas. */
.btn-monto-sugerido {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 2px solid var(--vidrio-borde);
  background: var(--vidrio-a);
  color: inherit;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}

.btn-monto-sugerido svg {
  width: 14px;
  height: 14px;
}

.btn-monto-sugerido.activo {
  border-color: rgb(var(--a));
  background: rgba(var(--a), 0.3);
}

.btn-monto-personalizado {
  border-style: dashed;
}

/* Campo para escribir un monto propio — oculto por defecto, solo
   aparece al tocar "Otro monto". */
.input-monto-elegido {
  width: 100%;
  font: inherit;
  font-size: 17px;
  padding: 8px 10px;
  border: 2px solid var(--vidrio-borde);
  border-radius: 8px;
  background: var(--campo);
  color: var(--texto-v2);
  margin-top: 8px;
}

.input-monto-elegido:focus {
  outline: none;
  border-color: rgba(var(--c2), 0.7);
  box-shadow: 0 0 0 3px rgba(var(--c2), 0.2);
}

/* Aviso corto cuando se recorta un monto personalizado fuera de rango
   (ver catalogo-movil.js) — negro sobre blanco sólido a propósito, no el
   color de la tarjeta: tiene que notarse como una corrección, no perderse
   como un detalle más sobre el color vivo de fondo. */
.aviso-monto-ajustado {
  margin: 6px 0 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: #fff;
  color: #000;
  font-size: 13px;
  font-weight: 700;
}

/* Fondo tomado de --a (heredado de .tarjeta-producto, nunca declarado
   acá) para que el botón quede tinteado del mismo color de su tarjeta,
   sin repetir la rotación de paleta ni tocar el JS que lo arma. */
.btn-comprar-producto {
  width: 100%;
  min-height: 46px;
  border-radius: 10px;
  border: none;
  font-family: var(--fuente-titulo), sans-serif;
  background: rgba(var(--a), 0.35);
  color: var(--texto-v2);
  font-weight: 800;
  font-size: 15px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.btn-comprar-producto:active {
  background: rgba(var(--a), 0.5);
}

.btn-comprar-producto svg {
  width: 18px;
  height: 18px;
}

/* Tarjeta destacada cuando se llega al catálogo desde "Recargar de nuevo"
   en historial.html, con un producto puntual en mente (?sku=...). */
.tarjeta-producto-destacada {
  box-shadow:
    0 0 0 3px var(--superficie),
    0 0 0 6px rgba(var(--a), 0.9),
    0 8px 24px rgba(var(--a), 0.35);
}

/* ===== Historial de transacciones (historial.html) =====
   Fase 6 (25/09/2026): restyleado en el lugar con los tokens nuevos. */
.lista-transacciones {
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Misma receta que .tarjeta-producto (degradado teñido de --a, rotación
   de paleta cada 6). */
.tarjeta-transaccion {
  --a: var(--c1);
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  padding: 18px;
  color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 100%);
  border: 1px solid rgba(var(--a), 0.35);
  box-shadow: var(--vidrio-sombra);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
}

.lista-transacciones .tarjeta-transaccion:nth-child(6n+1) { --a: var(--c1); }
.lista-transacciones .tarjeta-transaccion:nth-child(6n+2) { --a: var(--c2); }
.lista-transacciones .tarjeta-transaccion:nth-child(6n+3) { --a: var(--c4); }
.lista-transacciones .tarjeta-transaccion:nth-child(6n+4) { --a: var(--c5); }
.lista-transacciones .tarjeta-transaccion:nth-child(6n+5) { --a: var(--c3); }
.lista-transacciones .tarjeta-transaccion:nth-child(6n) { --a: var(--c6); }

.transaccion-cabecera {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--vidrio-borde);
}

.transaccion-fecha {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  opacity: 0.85;
  margin: 0 0 4px;
}

.transaccion-metodo {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  margin: 0;
}

.transaccion-metodo svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.transaccion-monto {
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 22px;
  font-weight: 800;
  white-space: nowrap;
  margin: 0;
  font-variant-numeric: tabular-nums;
}

.lista-recargas {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Fondo translúcido con el token de campo (theme-aware) en vez de otro
   .tarjeta propio a propósito: son "hijas" dentro de la tarjeta de la
   transacción, no compiten por su propio color de la paleta. */
.recarga-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--campo);
  border-radius: 12px;
  padding: 12px;
}

.recarga-bandera {
  width: 24px;
  height: auto;
  flex-shrink: 0;
  margin-top: 3px;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1);
}

.recarga-info {
  flex: 1;
  min-width: 0;
}

.recarga-contacto {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 800;
  margin: 0;
}

.recarga-contacto svg {
  width: 15px;
  height: 15px;
  opacity: 0.75;
  flex-shrink: 0;
}

.recarga-producto-nombre {
  font-size: 14px;
  font-weight: 700;
  margin: 4px 0 0;
}

.recarga-producto-descripcion {
  font-size: 13px;
  opacity: 0.85;
  margin: 2px 0 0;
}

.recarga-pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.recarga-monto {
  font-weight: 800;
  font-size: 15px;
}

/* Los 4 estados (pendiente/enviado/confirmado/fallido) ahora usan
   .etiqueta-estado de la guía (§6) — pendiente=neutra, enviado=atencion,
   confirmado=ok, fallido=error (mapeo hecho en js/historial.js, ver
   MAPA_ETIQUETA_ESTADO). No hace falta un .badge-estado propio. */

.recarga-acciones {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.btn-recarga-accion {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 10px;
  border: none;
  background: var(--vidrio-a);
  color: var(--texto-v2);
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  text-decoration: none;
}

.btn-recarga-accion:active {
  background: var(--vidrio-b);
}

.btn-recarga-accion svg {
  width: 14px;
  height: 14px;
}

.btn-reintentar {
  background: rgba(var(--peligro), 0.85);
  color: #fff;
}

.btn-reintentar:active {
  background: rgba(var(--peligro), 1);
}

/* ===== Estado vacío (sin transacciones / confirmando pago) =====
   Puramente de layout — el color/fondo lo pone quien lo envuelve
   (.tarjeta color-N, en historial.html y pago-resultado.html). */
.estado-vacio {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  padding: 40px 24px;
  color: var(--texto-v2);
}

.estado-vacio svg {
  width: 48px;
  height: 48px;
  opacity: 0.75;
}

.estado-vacio p {
  margin: 0;
  font-size: 16px;
}

.estado-vacio .btn-vidrio,
.estado-vacio .boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-height: 48px;
  padding: 0 24px;
}

/* Ícono "loader-circle" mientras se confirma un pago (pago-resultado.html) */
.girando {
  animation: girar 1s linear infinite;
}

@keyframes girar {
  to { transform: rotate(360deg); }
}

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

/* ===== resumen-pedido.html / pago.html ===== */
.resumen-seccion-titulo {
  font-family: var(--fuente-titulo), sans-serif;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--texto-v2-suave);
  font-weight: 800;
  margin: 0 0 8px;
}

/* .resumen-contacto reutiliza la receta de .contacto-item (mismo "a
   quién le envío"), solo cambia el avatar circular por la bandera. */
.resumen-contacto .contacto-bandera {
  width: 32px;
}

/* .resumen-producto reutiliza la receta de .tarjeta-producto (mismos
   .producto-nombre/.producto-descripcion), fija en violeta (--c5, como
   el acento-violeta viejo) al no estar en una lista con rotación. */
.resumen-producto {
  --a: var(--c5);
}

.resumen-producto-datos {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--vidrio-borde);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.resumen-producto-fila {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.resumen-producto-fila[hidden] {
  display: none;
}

.btn-agregar-contacto {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 50px;
  border-radius: 12px;
  border: 2px dashed var(--vidrio-borde);
  background: none;
  color: rgb(var(--c1));
  font-weight: 700;
  font-size: 15px;
  cursor: pointer;
  text-decoration: none;
  margin: 4px 0 20px;
}

.btn-agregar-contacto svg {
  width: 18px;
  height: 18px;
}

/* El checkbox obligatorio es el <label> completo (clic en cualquier
   parte lo marca), por eso .confirmacion-orden lleva su propia receta
   de vidrio teñido (misma fórmula que .contacto-item/.tarjeta-producto),
   fija en dorado (--c3, como el acento-amarillo viejo). */
.confirmacion-orden {
  --a: var(--c3);
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px;
  border-radius: 14px;
  color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 100%);
  border: 1px solid rgba(var(--a), 0.35);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  cursor: pointer;
}

.confirmacion-orden input[type="checkbox"] {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  margin-top: 2px;
  accent-color: rgb(var(--c1));
}

.confirmacion-orden span {
  font-weight: 500;
  font-size: 14px;
  line-height: 1.4;
}

.btn-tipo:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* Misma receta de vidrio teñido que .contacto-item, fija en cian (--c2,
   como el acento-cian viejo). */
.resumen-pago-corto {
  --a: var(--c2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  border-radius: 14px;
  color: var(--texto-v2);
  background:
    linear-gradient(145deg, rgba(var(--a), calc(var(--tinte) * 1.4)) 0%, rgba(var(--a), calc(var(--tinte) * 0.4)) 100%),
    linear-gradient(145deg, var(--vidrio-a) 0%, var(--vidrio-b) 100%);
  border: 1px solid rgba(var(--a), 0.35);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
}

.resumen-pago-corto-etiqueta {
  font-size: 13px;
  opacity: 0.85;
  margin: 0 0 2px;
}

.resumen-pago-corto-valor {
  font-size: 20px;
  font-weight: 800;
  margin: 0;
}

.aviso-seguridad {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--texto-v2);
  font-size: 13px;
  opacity: 0.75;
  margin: 4px 0 20px;
}

.aviso-seguridad svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}
