/* --- Tipografia de marca (2026-08-10) ------------------------------------
   Antes todo caia en la fuente por defecto del sistema en bold -- generica,
   sin personalidad para una marca streetwear. Ahora:
   - Titulos grandes (h1, incluye "KOLIZION" en la bienvenida): Clash
     Display (Fontshare, gratis) -- "Anton" (Google Fonts) queda como
     respaldo en la lista de fuentes si Clash Display no llega a cargar
     (CDN caido, sin internet, etc.), pedido explicito del usuario.
   - Botones principales: Archivo Black (Google Fonts) -- mas simple que
     Clash Display pero igual de bold, para no sobrecargar TODA la
     interfaz con letras anchas (a proposito, el texto de cuerpo --
     descripciones, parrafos -- sigue con la sans-serif de siempre, sin
     tocar).
   Se cargan por CDN (no hay build/Node en este proyecto -- ver CLAUDE.md),
   asi que hace falta internet para que se vean estas 2 fuentes; si no hay
   internet, el navegador cae solo a la sans-serif del sistema (ultimo
   nombre de cada lista de fuentes), la app nunca se rompe por esto. */
@import url('https://api.fontshare.com/v2/css?f[]=clash-display@500,600,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Archivo+Black&family=Anton&display=swap');

:root {
  /* Modo oscuro YA NO sigue la preferencia del sistema operativo (decision
     explicita 2026-08-10). Default: OSCURO (ajustado 2026-08-07, tras
     probar los dos) -- estas variables claras solo se usan si la persona
     eligio "claro" a mano en /perfil (interruptor "Modo oscuro", guardado
     en localStorage "temaKolizion" como "light"). Ver _tema_inline.html
     (aplica el data-theme antes del primer pintado, para que no haya
     parpadeo) y perfil.js (el interruptor en si). */
  color-scheme: light;
  /* Paleta de marca (2026-08-10): rojo exacto extraído del logo de
     KOLIZION (static/img/kolizion-logo.png), pixel-sampleado del archivo
     original -- no aproximado. Fondo/tarjetas en blanco-negro neutro (no
     el cream/marron calido de antes) para que el rojo sea el unico color
     con fuerza, tal como pidio el dueño del proyecto: "el rojo SOLO para
     acentos, nunca de fondo en grandes superficies". */
  --bg: #f5f5f5;
  --card: #ffffff;
  --text: #1a1a1a;
  --accent: #e60106;
  --border: #e2e2e2;
  /* Insignia "neutra" (Tendencias en Vitrina) -- deliberadamente NO roja,
     para no competir con el acento de marca ni con la insignia de Ofertas
     (que si usa el rojo, como un sale tag clasico). Se re-invierte en modo
     oscuro (ver :root[data-theme="dark"] abajo), igual que --bg/--card/--text. */
  --insignia-neutral-bg: #1a1a1a;
  --insignia-neutral-texto: #ffffff;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  margin: 0;
  /* Nunca scroll horizontal (todo lo ancho -- carruseles, etc. -- ya
     maneja su propio overflow-x en su contenedor). */
  overflow-x: hidden;
  /* padding-bottom extra para que la barra de navegacion fija de abajo
     nunca tape el final del contenido -- con margen de sobra a proposito.
     Subido de 6rem a 7rem (2026-09-29) al agrandar la barra (iconos/texto
     mas grandes, mas padding vertical, pedido del usuario). */
  padding: 2rem 1rem calc(7rem + env(safe-area-inset-bottom, 0px));
}

main {
  max-width: 640px;
  margin: 0 auto;
}

/* --- Animaciones "choque": identidad de marca (colision), sutiles a
   proposito -- un golpe/rebote breve al aparecer los titulos, un shake
   chico al pasar el mouse/tocar los botones principales (mas abajo, junto
   a la regla base de "button"). Nunca en iconos fijos chicos (estrella,
   cerrar, flechas de carrusel, etc.), para no saturar la interfaz.
   "Electrica" (2026-08-09, a pedido del usuario): en vez de un solo
   rebote suave, varios micro-golpes en X/Y/rotacion (como una descarga)
   con un destello de text-shadow en --accent en los picos -- simula una
   chispa sin llegar a parpadear (nunca se toca opacity despues del
   primer frame, para que no se sienta como un glitch roto). */
@keyframes choque-entrada {
  0% { opacity: 0; transform: translate(-6px, 2px) scale(0.85) rotate(-3deg); text-shadow: none; }
  15% { opacity: 1; transform: translate(4px, -3px) scale(1.05) rotate(2deg); text-shadow: 0 0 12px var(--accent); }
  30% { transform: translate(-3px, 2px) scale(0.98) rotate(-1.5deg); text-shadow: none; }
  45% { transform: translate(3px, -2px) scale(1.02) rotate(1deg); text-shadow: 0 0 9px var(--accent); }
  60% { transform: translate(-2px, 1px) scale(1) rotate(-0.5deg); text-shadow: none; }
  75% { transform: translate(1px, -1px) rotate(0.3deg); text-shadow: 0 0 5px var(--accent); }
  100% { opacity: 1; transform: translate(0, 0) scale(1) rotate(0deg); text-shadow: none; }
}

h1 {
  margin-bottom: 0.25rem;
  animation: choque-entrada 0.75s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  font-family: "Clash Display", "Anton", -apple-system, "Segoe UI", Roboto, sans-serif;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.subtitulo { color: var(--accent); margin-top: 0; margin-bottom: 1.5rem; }

.logo-kolizion {
  display: block;
  width: 96px;
  height: 96px;
  margin: 0 auto 1rem;
}

/* --- Splash de apertura (2026-08-11): 2 rayos que entran de lados
   opuestos, se cruzan en el centro y ahi mismo aparece el logo real --
   estilo apps grandes (ej. Uber Eats). Solo vive en index.html (la
   "puerta de entrada" de la app) y solo una vez por sesion de pestaña
   (ver el script inline en el <head> de index.html, agrega la clase
   "sin-splash" al <html> si ya se vio en esta sesion).

   Todo con transform/opacity nomas (nunca left/top/width) -- corre en la
   capa de composicion de la GPU, no dispara layout/reflow, para que sea
   liviano de verdad y no se sienta como que "atrasa" la app. */
.sin-splash .splash-overlay { display: none; }

.splash-overlay {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* Se desvanece sola a los ~1.75s y queda invisible + fuera del hit-test
     (visibility:hidden) -- no hace falta JS para sacarla de encima. */
  animation: splash-desvanecer 0.3s ease 1.75s forwards;
}

@keyframes splash-desvanecer {
  to { opacity: 0; visibility: hidden; }
}

.splash-rayo {
  position: absolute;
  width: 60vmin;
  height: 3vmin;
  min-height: 14px;
  max-height: 22px;
  background: linear-gradient(90deg, transparent, #e60106 18%, #e60106 82%, transparent);
  border-radius: 999px;
  opacity: 0;
  /* 2 animaciones en paralelo: la de entrada (mueve + aparece, distinta
     por rayo -- cada uno viaja en su propia diagonal) y la de salida
     (compartida, solo baja la opacidad) justo cuando el logo ya esta
     apareciendo encima. */
  animation: splash-rayo-salida 0.25s ease 0.75s forwards;
}

.splash-rayo-1 {
  animation-name: splash-rayo-1-entrada, splash-rayo-salida;
  animation-duration: 0.65s, 0.25s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1), ease;
  animation-delay: 0.1s, 0.75s;
  animation-fill-mode: forwards, forwards;
}
.splash-rayo-2 {
  animation-name: splash-rayo-2-entrada, splash-rayo-salida;
  animation-duration: 0.65s, 0.25s;
  animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1), ease;
  animation-delay: 0.1s, 0.75s;
  animation-fill-mode: forwards, forwards;
}

@keyframes splash-rayo-1-entrada {
  0% { opacity: 0; transform: rotate(-45deg) translateX(-120vmax); }
  15% { opacity: 1; }
  100% { opacity: 1; transform: rotate(-45deg) translateX(0); }
}
@keyframes splash-rayo-2-entrada {
  0% { opacity: 0; transform: rotate(45deg) translateX(120vmax); }
  15% { opacity: 1; }
  100% { opacity: 1; transform: rotate(45deg) translateX(0); }
}
@keyframes splash-rayo-salida {
  to { opacity: 0; }
}

.splash-logo {
  position: relative;
  width: 42vmin;
  max-width: 220px;
  opacity: 0;
  transform: scale(0.8);
  animation: splash-logo-entrada 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) 0.7s forwards;
}

@keyframes splash-logo-entrada {
  to { opacity: 1; transform: scale(1); }
}

/* Mensaje de bienvenida -- colores de marca (ver :root). Antes tenia negro
   fijo (#000): se veia bien en modo claro pero era ilegible en modo
   oscuro -- ahora usa var(--text), que ya se invierte solo. */
h1.bienvenida { color: var(--text); margin-bottom: 0.5rem; }
h1.bienvenida .marca { color: var(--accent); }
.tagline { color: var(--text); margin: 0 0 0.5rem; }
.pregunta-bienvenida {
  color: var(--accent);
  font-weight: 600;
  margin: 0 0 1.5rem;
  animation: choque-entrada 0.75s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  animation-delay: 0.25s;
}

/* El golpe electrico de entrada ahora es solo para la primera vez que se
   entra a la app y la primera vez que se entra a cada pagina/pestaña --
   ver _titulos_vistos.html (agrega esta clase al <html> ANTES de pintar,
   mismo patron que el tema oscuro, para que nunca se alcance a ver un
   frame de la animacion en una revisita). */
.titulo-visto h1,
.titulo-visto .pregunta-bienvenida {
  animation: none;
}

form {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Admin de tiendas: el formulario de reporte va anidado dentro de una
   tarjeta que ya tiene fondo/borde propios -- sin esto se ve una tarjeta
   duplicada dentro de otra. */
.form-reporte {
  background: none;
  border: none;
  padding: 0;
  margin-top: 0.75rem;
}

.lista-reportes {
  margin: 0.35rem 0 0;
  padding-left: 1.1rem;
  font-size: 0.85rem;
  color: #666;
}

/* --- Panel de admin (/admin/tiendas, /admin/clics, /admin/login) -------- */
.admin-nav {
  flex-wrap: wrap;
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}
.admin-nav a {
  color: var(--text);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
}
.admin-nav a.admin-nav-activo { color: var(--accent); }
.admin-nav-logout { margin-left: auto; }
.admin-nav-logout button {
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 600;
  font-size: 0.8rem;
  padding: 0.4rem 0.75rem;
}

.form-rango-clics { max-width: 260px; margin-bottom: 1.5rem; }

.resumen-copiable {
  margin-top: 0.9rem;
  padding: 0.75rem 0.9rem;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  justify-content: space-between;
}
.resumen-copiable p { margin: 0; font-size: 0.85rem; }
.btn-copiar-resumen {
  flex-shrink: 0;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 6px;
  padding: 0.4rem 0.7rem;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

/* Codigos de seguimiento KLZ-#### en /admin/clics (2026-09-28, Offside
   Club/Enfasis) -- tabla simple, sin estilo de tabla generico previo en el
   proyecto. */
.tabla-codigos-seguimiento {
  width: 100%;
  border-collapse: collapse;
  margin: 0.35rem 0 0;
  font-size: 0.82rem;
}
.tabla-codigos-seguimiento th, .tabla-codigos-seguimiento td {
  border-bottom: 1px solid var(--border);
  padding: 0.35rem 0.5rem;
  text-align: left;
}
.tabla-codigos-seguimiento th { color: #888; font-weight: 600; }

label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.9rem;
  font-weight: 600;
}

.campo-checkboxes { display: flex; flex-direction: column; gap: 0.5rem; }
.campo-checkboxes .ayuda { margin: 0; font-weight: 600; font-size: 0.9rem; color: var(--text); }
.grid-checkboxes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}
.checkbox-inline {
  flex-direction: row !important;
  align-items: center;
  gap: 0.4rem;
  font-weight: 400 !important;
}
.checkbox-inline input { width: auto; padding: 0; }

/* Selector compacto "Que no quieres ver" (2026-08-29) -- dropdown chico en
   vez del bloque grande de checkboxes, mismo patron visual que .vp-chip. */
.selector-exclusiones { position: relative; margin-bottom: 1.5rem; }
.selector-exclusiones-boton {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.65rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 500;
  text-align: left;
}
.selector-exclusiones-flecha { color: var(--accent); margin-left: 0.5rem; }
.selector-exclusiones-panel {
  position: absolute;
  z-index: 5;
  margin-top: 0.35rem;
  width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.selector-exclusiones-opcion {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  font-weight: 400;
  padding: 0.35rem 0.4rem;
  border-radius: 6px;
}
.selector-exclusiones-opcion:hover { background: var(--bg); }
.selector-exclusiones-opcion input { width: auto; padding: 0; }
.selector-exclusiones-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

/* Preferencia de calce/ajuste (2026-09-07) -- 3 opciones simples, siempre
   visibles (a diferencia del dropdown de exclusiones, aca no hace falta
   colapsar). */
.ajuste-talla-opciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1rem;
}
.ajuste-talla-opcion {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  font-weight: 400;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  cursor: pointer;
}
.ajuste-talla-opcion input { width: auto; }
.ajuste-talla-opcion:has(input:checked) { border-color: var(--accent); color: var(--accent); }
.selector-exclusiones-chip {
  display: inline-flex;
  align-items: center;
  background: var(--bg);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 0.25rem 0.5rem;
  font-size: 0.78rem;
  font-weight: 600;
}
.selector-exclusiones-chip button {
  background: none;
  border: none;
  color: inherit;
  padding: 0;
  margin: 0;
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
}

input, select, textarea {
  font-size: 1rem;
  padding: 0.6rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  font-family: inherit;
}

textarea { min-height: 4rem; resize: vertical; }

button {
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 12px;
  padding: 0.8rem;
  font-size: 1rem;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
}

button:disabled { opacity: 0.6; cursor: wait; }

/* Shake de "impacto" al pasar el mouse o tocar un boton principal --
   :hover y :active juntos para que se sienta tanto con mouse como con el
   dedo (touch dispara :active, no :hover). Excluye los iconos/controles
   fijos chicos (avatar de Koko, ayuda, cerrar, estrella de favorito,
   vista previa, miniaturas, barra de nav, flechas de carrusel) para que
   el efecto quede en los botones principales, no en toda la interfaz. */
button:not(.fab-koko, .fab-ayuda, .btn-cerrar-koko, .btn-cerrar-tour, .btn-favorito, .btn-vista-previa, .vp-miniatura, .barra-nav-item, .fila-flecha, .vp-flecha):hover,
button:not(.fab-koko, .fab-ayuda, .btn-cerrar-koko, .btn-cerrar-tour, .btn-favorito, .btn-vista-previa, .vp-miniatura, .barra-nav-item, .fila-flecha, .vp-flecha):active {
  animation: choque-shake 0.35s ease;
}

/* "Electrico" (2026-08-09): mas pasos, jitter en X e Y (no solo X), y un
   destello blanco (box-shadow) en los picos que simula una chispa/arco
   electrico -- el rojo de --accent ya es el fondo del boton, por eso el
   destello va en blanco para que se note. */
@keyframes choque-shake {
  0%, 100% { transform: translate(0, 0); box-shadow: none; }
  10% { transform: translate(-2px, 1px); }
  20% { transform: translate(3px, -2px); box-shadow: 0 0 10px rgba(255, 255, 255, 0.6); }
  30% { transform: translate(-3px, 2px); box-shadow: none; }
  40% { transform: translate(2px, -1px); box-shadow: 0 0 6px rgba(255, 255, 255, 0.4); }
  50% { transform: translate(-2px, 2px); box-shadow: none; }
  60% { transform: translate(3px, -1px); box-shadow: 0 0 10px rgba(255, 255, 255, 0.6); }
  70% { transform: translate(-1px, 1px); box-shadow: none; }
  80% { transform: translate(2px, -1px); }
  90% { transform: translate(-1px, 0); }
}

.oculto { display: none !important; }

.ayuda { color: #666; font-size: 0.9rem; }

.tarjeta-recordado {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 1.5rem;
  margin: 1rem 0;
  text-align: center;
}

.botones-quien {
  display: flex;
  gap: 1rem;
  margin: 1rem 0;
}

.botones-quien button {
  flex: 1;
}

a.volver, #link-editar-perfil, a.limpiar-filtros {
  color: var(--accent);
  font-size: 0.9rem;
}

.btn-cambiar-filtros {
  display: block;
  margin: 0.75rem 0 1rem;
}

/* Toggle Scroll/Grid (2026-09-23) -- ver comentario junto a #resultados
   mas abajo. Boton chico tipo pildora, igual de discreto que el resto de
   los controles de esta cabecera, no compite con "Cambiar requisitos". */
.btn-vista-toggle {
  display: inline-block;
  margin: 0 0 1rem;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

/* Boton "Continuar con Google" (/login, /registro) -- fondo blanco fijo a
   proposito (no usa las variables de tema oscuro/claro) porque asi es como
   Google recomienda mostrar su boton, para que se reconozca igual en
   cualquier sitio. */
.btn-google {
  display: block;
  width: 100%;
  text-align: center;
  background: white;
  color: #1f1f1f;
  border: 1px solid #dadce0;
  font-weight: 600;
  border-radius: 8px;
  padding: 0.8rem;
  margin-bottom: 0.5rem;
}

.btn-visitar-tienda, .btn-editar-perfil {
  display: block;
  text-align: center;
  background: var(--accent);
  color: white;
  font-weight: 500;
  font-family: inherit;
  border-radius: 12px;
  padding: 0.8rem;
  text-decoration: none;
  margin-top: 0.75rem;
}

/* --- "Llegan rápido a ti" (2026-08-17): boton para autocompletar la
   direccion del perfil con la ubicacion actual, reusa el mismo patron de
   "preguntar antes de preguntar" que tenia el mapa. --- */
.btn-ubicacion-actual {
  display: block;
  width: 100%;
  margin: 0.5rem 0 1rem;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
}

/* --- "Marca de autor" / diseño independiente (2026-08-19) --- */
.insignia-marca-autor {
  display: inline-block;
  margin: 0.2rem 0 0.4rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: transparent;
}

/* "Con modelo" (2026-09-23, pedido del usuario): insignia por PRODUCTO --
   mismo tamaño/forma que .insignia-marca-autor pero con relleno solido
   (no solo borde) para distinguirla a simple vista, con un color propio
   que no compita con el rojo de "Confianza"/oferta ni con --accent de
   "Marca de autor". */
.insignia-con-modelo {
  display: inline-block;
  margin: 0.2rem 0.3rem 0.4rem 0;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  border: 1px solid #2f6f4f;
  color: #fff;
  background: #2f6f4f;
}

/* "Revendedor, no es tienda oficial de la marca" (2026-09-29/30, pedido
   del usuario para Leaked -- ver TIENDAS_REVENDEDOR_NO_OFICIAL en
   construir_catalogo_real.py): mismo tamaño/forma que .insignia-con-modelo
   pero color ambar de aviso (ni el verde "con modelo" ni el rojo
   "Confianza", para que se lea como una aclaracion, no como algo malo). */
.insignia-codigo-kolizion {
  display: inline-block;
  margin: 0.2rem 0.3rem 0.4rem 0;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
}
.insignia-revendedor {
  display: inline-block;
  margin: 0.2rem 0.3rem 0.4rem 0;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  border: 1px solid #9a6a00;
  color: #fff;
  background: #b8790a;
}

/* "Confianza KOLIZION" (2026-09-02, en rojo llamativo a pedido del usuario):
   a primera vista solo se lee "Nivel X" -- el desglose completo (que
   criterios cumple) va en el title (tooltip) y en el acordeon de la ficha
   completa, ver #vp-det-confianza. */
.insignia-confianza {
  display: inline-block;
  margin: 0.2rem 0.3rem 0.4rem 0;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 700;
  border: 1px solid #e11d2e;
  color: #fff;
  background: #e11d2e;
  cursor: pointer;
}

/* Popup de "Confianza KOLIZION" (2026-09-03): se abre al tocar/clickear el
   sello "Nivel X" de cualquier tarjeta (ver _abrirPopupConfianza en
   comun.js) -- reemplaza el title (tooltip), que en mobile no se ve con
   un tap. */
.popup-confianza {
  position: fixed;
  z-index: 200;
  width: 220px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  padding: 0.6rem 0.8rem;
  font-size: 0.8rem;
}
.popup-confianza strong {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.78rem;
  color: #e11d2e;
}
.popup-confianza p {
  margin: 0;
  line-height: 1.6;
  color: var(--text);
}

.vp-confianza-lista {
  list-style: none;
  margin: 0.3rem 0;
  padding: 0;
  font-size: 0.85rem;
  line-height: 1.6;
}
.vp-confianza-si { color: var(--text); }
.vp-confianza-no { color: #888; }

/* Sello "por que es tendencia" en la ficha completa (2026-08-29, pedido del
   usuario: N.1 en clics, recien llegado, etc. -- mismo texto que ya se veia
   en la tarjeta de Tendencias, ahora tambien visible al abrir el producto).
   Mismo patron visual que .insignia-marca-autor, colores de .insignia-tendencia. */
.vp-insignia-tendencia,
.vp-insignia-nuevo {
  display: inline-block;
  margin: 0.2rem 0 0.4rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  background: var(--insignia-neutral-bg);
  color: var(--insignia-neutral-texto);
}
/* Oferta en la ficha (2026-09-12): mismo formato de insignia, colores de
   .insignia-oferta (ya usada en tarjetas de vitrina). */
.vp-insignia-oferta {
  display: inline-block;
  margin: 0.2rem 0 0.4rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  background: var(--accent);
  color: #fff;
}
.vp-precio-original { margin: -0.5rem 0 0.5rem; font-size: 0.85rem; color: var(--text); opacity: 0.6; text-decoration: line-through; }

#estado { margin-top: 1rem; color: #666; }

/* Pantalla completa de carga (2026-08-28, reemplaza el skeleton de tarjetas
   grises de antes): solo los rayos del logo pulsan en loop mientras se
   busca (el texto "KOLIZION" queda fijo -- ver comentario en
   _cargando.html sobre las 3 capas recortadas). Cuando llegan resultados,
   buscarConAnimacion() agrega "cargando-exito": los rayos dejan de pulsar y
   el logo entero se ilumina, mostrando "cargando-exito-texto" en vez de las
   frases rotativas, un instante antes de revelar los resultados. */
.cargando-overlay {
  position: fixed;
  inset: 0;
  z-index: 350;
  background: #000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
}

.cargando-logo-wrap {
  position: relative;
  width: 30vmin;
  max-width: 150px;
  aspect-ratio: 1 / 1;
}

.cargando-logo-capa {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Franjas medidas a mano sobre el PNG (1254x1254): fila vacia real entre
   rayos y texto en 546-559px (arriba) y 638-654px (abajo) -- se corta a la
   mitad de cada hueco para no dejar ni un pixel de un lado pisando el otro. */
.cargando-logo-rayos-arriba { clip-path: inset(0 0 56% 0); }
.cargando-logo-texto { clip-path: inset(44% 0 48.5% 0); }
.cargando-logo-rayos-abajo { clip-path: inset(51.5% 0 0 0); }

.cargando-logo-rayos {
  animation: cargando-logo-pulso 1.6s ease-in-out infinite alternate;
}

@keyframes cargando-logo-pulso {
  0% { opacity: 1; }
  100% { opacity: 0.2; }
}

.cargando-overlay.cargando-exito .cargando-logo-rayos {
  animation: none;
  opacity: 1;
}

.cargando-overlay.cargando-exito .cargando-logo-capa {
  filter: drop-shadow(0 0 20px var(--accent));
  transition: filter 0.25s ease;
}

.cargando-texto {
  color: #ccc;
  font-size: 0.85rem;
  font-weight: 600;
  margin: 0;
  transition: opacity 0.2s ease;
}

.cargando-overlay.cargando-exito .cargando-texto { opacity: 0; }

.cargando-exito-texto {
  display: none;
  color: var(--accent);
  font-weight: 700;
  font-size: 1.3rem;
  margin: 0;
}

.cargando-overlay.cargando-exito .cargando-exito-texto {
  display: block;
  animation: cargando-exito-entrada 0.3s ease;
}

@keyframes cargando-exito-entrada {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

#feedback-busqueda {
  margin-top: 1.5rem;
  padding: 1rem 1.25rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
}

#feedback-busqueda p { margin-top: 0; font-weight: 600; }

.pregunta-relajar-prefs {
  margin-top: 1rem;
  padding: 1rem 1.25rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
}

.pregunta-relajar-prefs p { margin-top: 0; font-weight: 600; }

#resultados-plan-b {
  margin-top: 1rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 0.75rem;
}

/* El titulo de cada tanda, el aviso de "no encontramos nada mas" y la
   pregunta de "seguir viendo" son hijos directos mezclados con las
   tarjetas (ver resultados.js) -- sin esto quedarian metidos en una sola
   celda de la grilla en vez de ocupar todo el ancho. */
#resultados-plan-b > h3,
#resultados-plan-b > p.aviso-alternativas,
#resultados-plan-b > .pregunta-mas-opciones {
  grid-column: 1 / -1;
}

#resultados-plan-b h3 { margin: 0.5rem 0 0; }

/* Aviso antes de las alternativas de "mostrar mas opciones" que ya no
   cumplen el corte pedido -- distinto del h3 normal para que se note que
   es un aviso, no una coincidencia exacta. */
#resultados-plan-b h3.aviso-alternativas {
  color: var(--accent);
  font-style: italic;
  font-weight: 600;
  border-top: 1px dashed var(--border);
  padding-top: 1rem;
}

#resultados {
  margin-top: 1.5rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 0.75rem;
}

/* Toggle de vista Scroll/Grid (2026-09-23, pedido del usuario): Scroll
   (1 columna ancha, feed vertical) pasa a ser el default nuevo -- antes
   solo existia la grilla chica de abajo, que el usuario encontro "muy
   chica" para apreciar bien las fotos (mas relevante ahora que se suman
   fotos con modelo, ver .insignia-con-modelo). No se toca el tamaño de
   .resultado-card-mini -- alcanza con angostar/ensanchar el contenedor,
   la imagen ya llena el ancho disponible (object-fit: cover). El
   interruptor (#btn-vista-resultados en resultados.html) solo agrega/saca
   la clase "vista-grid" en <body> y la guarda en localStorage (mismo
   patron que el interruptor de tema oscuro/claro en perfil.js) -- ver
   aplicarVistaResultados() en resultados.js. Alcance explicito: SOLO
   /resultados (#resultados, #resultados-plan-b), no /vitrina ni otras
   vistas de listado (pedido del usuario, 2026-09-23).
   "Mostrar mas opciones" sigue pidiendo confirmacion entre tanda y tanda
   en los dos modos -- no se convirtio en scroll infinito automatico, eso
   deshace a proposito la confirmacion "¿Quieres ver aun mas opciones?"
   agregada el 2026-08-28. */
#resultados,
#resultados-plan-b {
  grid-template-columns: minmax(0, 480px);
  justify-content: center;
}

body.vista-grid #resultados,
body.vista-grid #resultados-plan-b {
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  justify-content: initial;
}

.resultado-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.25rem;
  position: relative;
}

/* Perfil opcional (2026-10-12, pedido explicito del usuario): tarjeta
   descartable en la home ("Cuéntanos tu talla...") y aviso en la pantalla
   de perfil completo -- misma tarjeta que .resultado-card, con sus 2
   botones uno al lado del otro. */
.tarjeta-perfil-opcional { margin: 1rem 0; text-align: left; }
.tarjeta-perfil-opcional .botones-perfil-opcional,
.aviso-perfil-opcional .botones-perfil-opcional {
  display: flex;
  gap: 0.6rem;
  margin-top: 0.75rem;
  flex-wrap: wrap;
}
.aviso-perfil-opcional {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
  text-align: left;
}
.btn-secundario {
  background: transparent;
  color: var(--accent);
  border: 1.5px solid var(--accent);
}

.lista-resultados {
  margin-top: 1rem;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 0.75rem;
}

/* Estrella de favorito -- flotante sobre la tarjeta (esquina superior
   derecha para no chocar con la insignia de Vitrina, que va a la
   izquierda). Un solo boton reutilizado en resultados/vitrina/perfil, ver
   marcadorFavoritoHtml/conectarBotonFavorito en comun.js. */
.btn-favorito {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 2;
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.btn-favorito svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linejoin: round;
}

.btn-favorito.activo svg {
  fill: var(--accent);
  stroke: var(--accent);
}

.btn-favorito:disabled {
  opacity: 0.6;
  cursor: wait;
}

/* Rebote + brillo momentaneo al tocar la estrella (clase agregada por JS en
   cada click, se saca sola al terminar -- ver conectarBotonFavorito en
   comun.js). Se dispara SIEMPRE al tocar, tanto al marcar como al
   desmarcar -- no depende de si quedo activa o no. */
.btn-favorito svg.pulso {
  animation: favorito-pulso 0.4s ease;
}

@keyframes favorito-pulso {
  0% { transform: scale(1); filter: drop-shadow(0 0 0 transparent); }
  35% { transform: scale(1.45); filter: drop-shadow(0 0 6px var(--accent)); }
  65% { transform: scale(0.9); }
  100% { transform: scale(1); filter: drop-shadow(0 0 0 transparent); }
}

.tarjeta-vitrina .btn-favorito {
  width: 26px;
  height: 26px;
  top: 0.4rem;
  right: 0.4rem;
}
.tarjeta-vitrina .btn-favorito svg {
  width: 14px;
  height: 14px;
}

.resultado-card .imagen-producto {
  display: block;
  width: 100%;
  max-width: 160px;
  height: auto;
  margin: 0 auto 0.25rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.resultado-card .aviso-imagen {
  margin: 0 0 0.75rem;
  text-align: center;
  font-size: 0.7rem;
  color: #999;
  font-style: italic;
}
.resultado-card h3 { margin: 0 0 0.25rem; }
.resultado-card .tienda { color: var(--accent); font-weight: 600; font-size: 0.9rem; }
.resultado-card .marca { margin: 0; font-size: 0.85rem; color: #666; }
.resultado-card .precio { margin: 0.25rem 0 0; font-weight: 700; }
.resultado-card .razon { margin: 0.5rem 0; }
.resultado-card a { color: var(--accent); font-weight: 600; }

/* Cuadradito de la grilla de resultados/favoritos (2026-08-28): solo foto +
   nombre + precio, tocarlo abre la ficha completa (ver renderResultados en
   comun.js) -- reusa el fondo/borde/radio de .resultado-card de arriba,
   solo saca el padding (la foto ocupa el ancho entero) y achica la
   tipografia. No toca .tarjeta-vitrina (Descubre), que sigue usando
   .resultado-card como base con su propio layout de carrusel. */
.resultado-card-mini {
  padding: 0;
  overflow: hidden;
  cursor: pointer;
}

.resultado-card-mini .imagen-producto {
  max-width: none;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  margin: 0;
  border: none;
  border-radius: 0;
}

.resultado-card-mini .badge-ilustrativa {
  position: absolute;
  left: 0.4rem;
  bottom: 0.4rem;
  z-index: 1;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.62rem;
  font-style: italic;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
}

/* Sello "Unisex" (2026-08-29): mismo dato que ya usaba el buscador para
   mostrar unisex en busquedas de Hombre y Mujer (motor_recomendacion.py),
   ahora visible -- pedido del usuario para que se note que el catalogo
   reconoce esto en vez de asumir un solo genero. */
.resultado-card-mini .badge-unisex {
  position: absolute;
  right: 0.4rem;
  bottom: 0.4rem;
  z-index: 1;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.62rem;
  font-weight: 600;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
}
.insignia-unisex {
  display: inline-block;
  margin: 0.2rem 0 0.4rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  border: 1px solid var(--border);
  color: var(--text);
}

/* Insignia "Guia de tallas real" (2026-09-22): misma familia visual que
   .insignia-marca-autor, en la ficha de tienda (tienda_perfil.html). */
.insignia-guia-tallas-tienda {
  display: inline-block;
  margin: 0.2rem 0 0.8rem;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  border: 1px solid var(--accent);
  color: var(--accent);
  background: transparent;
}

.resultado-card-mini-info {
  padding: 0.5rem 0.6rem 0.65rem;
}

.resultado-card-mini h3 {
  margin: 0 0 0.15rem;
  font-size: 0.8rem;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.resultado-card-mini .precio {
  margin: 0;
  font-size: 0.85rem;
}

/* Producto "oficial" listo para vender pero sin checkout interno todavia
   (ver TIENDAS_OFICIALES en construir_catalogo_real.py / botonAccionProductoHtml
   en comun.js): reemplaza el link de compra por un texto inerte. */
.boton-proximamente {
  color: #999;
  font-weight: 600;
  cursor: default;
}

/* Borrar todos los favoritos de una vez (2026-08-25): boton secundario
   (borde rojo, sin relleno) para no confundirlo con una accion principal --
   siempre pide confirmacion antes de borrar (ver favoritos.js). */
.btn-borrar-favoritos {
  display: block;
  margin: 0 0 1rem;
  padding: 0.55rem 1rem;
  background: none;
  border: 1px solid var(--accent);
  border-radius: 8px;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
}

/* --- Onboarding: pregunta + tour, solo la primera vez que se crea el
   perfil (ver ONBOARDING_KEY en script.js) --- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 110;
  /* 2026-09-29, bug real reportado por el usuario: en el tour de
     onboarding, al reproducir el video de ejemplo (boton "No entendi") la
     tarjeta crecia mas alta que la pantalla y no habia forma de hacer
     scroll para llegar a la cruz de cerrar -- quedaba atascado. */
  overflow-y: auto;
}

.tarjeta-modal {
  position: relative;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 1.75rem 1.5rem;
  max-width: 360px;
  width: 100%;
  text-align: center;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
}

.tarjeta-modal h2 { margin: 0.5rem 0; }
.tarjeta-modal p { color: var(--text); margin: 0 0 1rem; }

/* Modal de "Mi cuenta" (2026-08-30): mismo .tarjeta-modal de siempre, pero
   con el formulario alineado a la izquierda -- centrado (el default) se ve
   mal en inputs/labels. */
.tarjeta-modal-cuenta { text-align: left; }
.tarjeta-modal-cuenta h2 { text-align: center; }

/* Icono fijo "Mi cuenta" (avatar), arriba a la derecha en TODAS las
   paginas -- mismo patron visual que .fab-koko (circulo con foto), pero
   arriba en vez de abajo para no chocar con .fab-koko/.fab-ayuda/la barra
   de navegacion inferior. */
.fab-cuenta {
  position: fixed;
  top: 1rem;
  right: 1rem;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 2px solid var(--card);
  padding: 0;
  overflow: hidden;
  background: var(--accent);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  z-index: 96;
  display: block;
}
.fab-cuenta img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Cierre del tour -- solo el tour lo tiene (la pregunta inicial no, ahi
   se elige Si/No). Se puede cerrar en cualquier slide, no solo al llegar
   al final -- importante para cuando se reabre a mano despues, sin querer
   repasar las 3 pantallas de nuevo. */
.btn-cerrar-tour {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: none;
  border: none;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--text);
  cursor: pointer;
  padding: 0.5rem;
}

/* 2026-09-29, bug real reportado por el usuario: con el video de ejemplo
   reproduciendose (pantalla "El buscador" del tour), la tarjeta queda mas
   alta que la pantalla y la cruz (position:absolute, arriba de la tarjeta)
   se iba scrolleando fuera de vista junto con el resto del contenido --
   quedaba atascado sin forma de cerrar. Se fija a la ventana (mismo patron
   ya usado en #modal-zoom-imagen mas abajo) para que siempre este
   alcanzable, sin importar cuanto haya que scrollear para ver el video. */
#modal-onboarding-tour .btn-cerrar-tour {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 111;
  background: var(--card);
  border-radius: 50%;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
}
.tarjeta-modal .botones-quien { margin-bottom: 0; }

.tour-slide svg {
  width: 56px;
  height: 56px;
  stroke: var(--accent);
  fill: none;
  stroke-width: 1.6;
  margin: 0 auto;
  display: block;
}

.tour-puntos {
  display: flex;
  justify-content: center;
  gap: 0.4rem;
  margin: 1rem 0;
}
.tour-punto {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--border);
}
.tour-punto.activo { background: var(--accent); }

/* Menu de tarjetas de categoria en Descubre (2026-09-11) -- 2 columnas,
   mismo alto (grid + flex-column empuja el boton siempre abajo). */
.grid-categorias-descubre {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-bottom: 1.75rem;
}
.tarjeta-categoria {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.tarjeta-categoria h3 {
  margin: 0;
  font-size: 0.92rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.tarjeta-categoria-emoji { font-size: 1.25rem; }
.tarjeta-categoria p {
  margin: 0;
  font-size: 0.78rem;
  color: var(--text);
  opacity: 0.75;
  flex-grow: 1;
}
.btn-tarjeta-categoria {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 999px;
  padding: 0.6rem 0.8rem;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}

/* Boton "Llevame a la tienda" (2026-09-11, pedido del usuario: el link
   subrayado se veia aburrido; 2026-09-13, se saco el icono de Koko, solo
   texto) -- mismo rojo/blanco que el CTA de la ficha completa. Compartido
   via botonAccionProductoHtml() en comun.js. */
/* Bug real (2026-09-21, reportado por el usuario -- "boton rojo sin
   texto"): ".resultado-card a { color: var(--accent) }" (mas arriba en
   este archivo) le gana en especificidad a ".btn-llevame-tienda { color:
   #fff }" (1 clase+1 elemento vs. 1 sola clase) -- el texto quedaba del
   mismo rojo que el fondo, invisible pero presente en el HTML. Selector
   calificado con ".resultado-card" para subir la especificidad y ganarle
   a esa regla sin tocarla (la necesitan otros links dentro de la
   tarjeta). btn-llevame-tienda solo se genera dentro de .resultado-card
   (ver botonAccionProductoHtml en comun.js), asi que no hace falta
   duplicar la regla para ningun otro caso. */
.resultado-card .btn-llevame-tienda {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  font-size: 0.8rem;
  text-decoration: none;
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin-top: 0.4rem;
  text-align: center;
}

.btn-no-entendi {
  display: block;
  margin: 0.6rem auto 0;
  background: none;
  border: none;
  color: var(--accent);
  text-decoration: underline;
  font-size: 0.85rem;
  cursor: pointer;
}
.video-ejemplo-tour {
  display: block;
  width: 100%;
  border-radius: 10px;
  margin-top: 0.6rem;
}

/* --- Ficha de producto (2026-08-27): componente global, ver
   _vista_previa.html / abrirVistaPrevia en comun.js. En mobile se apila
   todo en una columna (comportamiento de siempre); a partir de 768px pasa
   a 2 columnas anchas (galeria | info) para sentirse como una pagina de
   producto real, no una tarjeta angosta. --- */
.modal-overlay-producto { align-items: flex-start; overflow-y: auto; padding: 2rem 1rem; }

/* Boton de cerrar la ficha de producto (2026-10-08, pedido del usuario: "la
   cruz de cerrar es dificil de tocar"). Fijo a la ventana (no al modal, que
   tiene su propio scroll) para que nunca se vaya con el scroll -- mismo bug
   ya resuelto antes para el tour de bienvenida (#modal-onboarding-tour
   .btn-cerrar-tour mas arriba). Area tactil 44x44 (minimo recomendado),
   fondo oscuro semitransparente para contraste sobre cualquier foto clara,
   y respeta el notch de iPhone con env(safe-area-inset-*). Mismo estilo
   para el zoom de foto (#modal-zoom-imagen), que antes solo tenia el texto
   blanco sin fondo ni area minima. */
#modal-vista-previa .btn-cerrar-tour,
#modal-zoom-imagen .btn-cerrar-tour {
  position: fixed;
  top: calc(0.6rem + env(safe-area-inset-top, 0px));
  right: calc(0.6rem + env(safe-area-inset-right, 0px));
  z-index: 120;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(0, 0, 0, 0.6);
  color: #ffffff;
  border-radius: 50%;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.tarjeta-vista-previa { text-align: left; max-width: 340px; max-height: none; }
.tarjeta-vista-previa h2 { margin: 0.4rem 0 0.25rem; font-size: 1.2rem; }
.tarjeta-vista-previa .tienda { color: var(--accent); font-weight: 600; font-size: 0.85rem; }
.tarjeta-vista-previa .vp-precio-grande { font-weight: 700; font-size: 1.4rem; margin: 0.35rem 0; }
.tarjeta-vista-previa a.vp-cta {
  display: block;
  text-align: center;
  background: var(--accent);
  color: white;
  font-weight: 600;
  border-radius: 8px;
  padding: 0.8rem;
  text-decoration: none;
  margin-top: 0.5rem;
}
.tarjeta-vista-previa a.vp-cta.boton-proximamente {
  background: #999;
  cursor: default;
}
.vp-cta-nota { font-size: 0.8rem; color: #999; margin: 0.4rem 0 0; }

/* Boton "Compartir" (2026-10-08, pedido del usuario): secundario, debajo
   del CTA de ir a la tienda -- nunca compite visualmente con el boton
   principal (fondo neutro con borde en vez del rojo de marca). */
.tarjeta-vista-previa button.vp-compartir {
  display: block;
  width: 100%;
  text-align: center;
  background: transparent;
  color: var(--text);
  font-weight: 600;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.7rem;
  margin-top: 0.5rem;
  cursor: pointer;
}
.aviso-producto-no-disponible {
  background: rgba(229, 35, 27, 0.08);
  border: 1px solid var(--accent);
  color: var(--text);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.9rem;
}

.vp-compartir-aviso {
  font-size: 0.8rem;
  color: var(--accent);
  text-align: center;
  margin: 0.4rem 0 0;
  min-height: 1.1em;
}

/* Modal de contacto por Instagram (2026-09-24) -- ver _modal_contacto_
   instagram.html/comun.js. Botones/textarea propios (no reusan .vp-cta,
   que esta acotado a .tarjeta-vista-previa) pero mismo look general. */
.contacto-instagram-textarea {
  width: 100%;
  box-sizing: border-box;
  resize: none;
  font: inherit;
  padding: 0.6rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin: 0.6rem 0;
  background: var(--card);
  color: var(--text);
}
.btn-copiar-mensaje-instagram {
  display: block;
  width: 100%;
  text-align: center;
  background: var(--card);
  color: var(--accent);
  font-weight: 600;
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 0.8rem;
  margin-bottom: 0.6rem;
  cursor: pointer;
}
.btn-copiar-mensaje-instagram.copiado {
  background: var(--accent);
  color: white;
}
#modal-contacto-instagram a#link-abrir-instagram {
  display: block;
  text-align: center;
  background: var(--accent);
  color: white;
  font-weight: 600;
  border-radius: 8px;
  padding: 0.8rem;
  text-decoration: none;
}
/* Bloqueado hasta copiar el mensaje (2026-09-24, pedido del usuario) --
   pointer-events:none es el cinturon extra ademas del preventDefault en
   comun.js, por si algun navegador dispara el click antes del listener. */
#modal-contacto-instagram a#link-abrir-instagram.deshabilitado {
  background: var(--border);
  color: #888;
  pointer-events: none;
  cursor: default;
}
#modal-codigo-tienda .codigo-tienda-valor {
  display: block;
  text-align: center;
  font-size: 1.6rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  border: 2px dashed var(--accent);
  border-radius: 8px;
  padding: 0.7rem;
  margin: 0.6rem 0;
  color: var(--text);
}
#modal-codigo-tienda a#link-ir-tienda {
  display: block;
  text-align: center;
  background: var(--accent);
  color: white;
  font-weight: 600;
  border-radius: 8px;
  padding: 0.8rem;
  text-decoration: none;
}
#modal-codigo-tienda a#link-ir-tienda.deshabilitado {
  background: var(--border);
  color: #888;
  pointer-events: none;
  cursor: default;
}
.contacto-instagram-instruccion {
  text-align: center;
  font-weight: 600;
  margin: 0 0 0.6rem;
}

@media (min-width: 768px) {
  .tarjeta-vista-previa { max-width: 940px; padding: 2rem; }
  .vp-layout { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: 2rem; }
  .vp-imagen-principal { max-height: 540px; }
  .tarjeta-vista-previa h2 { font-size: 1.5rem; }
}

.vp-layout { display: flex; flex-direction: column; gap: 1rem; }

.vp-imagen-principal-wrap { position: relative; }

.vp-imagen-principal {
  display: block;
  width: 100%;
  max-height: 260px;
  object-fit: contain;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: zoom-in;
}

/* Flechitas para pasar de foto (2026-08-28, pedido del usuario) -- a
   diferencia de .fila-flecha (Descubre) estas NO se ocultan en celular: el
   usuario las pidio explicitamente para compu Y celular. Mismo boton se
   reusa en la galeria de la ficha y dentro del zoom (ver vp-flecha-izq/der
   duplicados por id en cada lugar). */
.vp-flecha {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  font-size: 1.3rem;
  line-height: 1;
  padding: 0;
  cursor: pointer;
}
.vp-flecha-izq { left: 0.5rem; }
.vp-flecha-der { right: 0.5rem; }

/* Flechas para pasar al producto SIGUIENTE/ANTERIOR del listado (2026-09-29,
   pedido del usuario; agrandadas y pasadas a rojo el 2026-09-30, mismo
   pedido: que se note a simple vista la diferencia con .vp-flecha de arriba
   -- chica/negra = cambiar de FOTO, grande/roja = cambiar de PRODUCTO).
   Pegadas al borde de la TARJETA entera, no de la foto.
   .tarjeta-vista-previa ya es position:relative (heredado de
   .tarjeta-modal). */
.vp-flecha-producto {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 2px solid var(--card);
  background: var(--accent);
  color: #ffffff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
  font-size: 2rem;
  line-height: 1;
  padding: 0;
  cursor: pointer;
}
.vp-flecha-producto-izq { left: -0.9rem; }
.vp-flecha-producto-der { right: -0.9rem; }
@media (max-width: 480px) {
  /* En pantallas chicas la tarjeta ocupa casi todo el ancho -- se meten
     hacia adentro para no quedar cortadas por el borde de la pantalla, y
     un poco mas chicas para no comerse tanto espacio de la foto. */
  /* 2026-10-03: en celular las flechas de producto se ocultan -- caian a
     mitad de altura, justo encima de las flechas de foto, y se pisaban.
     Ahora se cambia de producto tocando los costados de la foto (ver
     _zonaTapGaleria en comun.js). En escritorio siguen visibles. */
  .vp-flecha-producto {
    display: none;
  }
}

.vp-miniaturas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.6rem 0 0.9rem;
}

.vp-miniatura {
  width: 56px;
  height: 56px;
  padding: 0;
  border-radius: 8px;
  border: 2px solid var(--border);
  background: var(--bg);
  overflow: hidden;
  cursor: pointer;
}
.vp-miniatura img { width: 100%; height: 100%; object-fit: contain; display: block; }
.vp-miniatura.activa { border-color: var(--accent); }

/* Zoom de foto a pantalla completa (2026-08-28) -- fondo casi negro para
   que la prenda resalte. El wrap tiene scroll propio (overflow: auto) para
   poder desplazarse cuando la foto esta agrandada, con touch-action que
   deja el gesto de pellizco del navegador funcionar normal ademas del
   scroll. */
.modal-overlay-zoom {
  background: rgba(0, 0, 0, 0.92);
  padding: 0;
}

.zoom-imagen-wrap {
  width: 100%;
  height: 100%;
  overflow: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: pinch-zoom pan-x pan-y;
}

#zoom-imagen {
  max-width: 100%;
  max-height: 100vh;
  object-fit: contain;
  cursor: zoom-in;
  transition: transform 0.2s ease;
}

#zoom-imagen.zoom-agrandada {
  max-width: none;
  max-height: none;
  width: auto;
  height: 220%;
  cursor: zoom-out;
}

#modal-zoom-imagen .vp-flecha { position: fixed; }

/* Talla: solo informativo desde 2026-09-12 (Preview no compra en la app),
   color sigue siendo chips seleccionables mas abajo si el producto los trae. */
.vp-selector { margin: 0.85rem 0; }
.vp-selector-label { display: block; font-weight: 600; font-size: 0.85rem; margin-bottom: 0.4rem; }
.vp-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.vp-chip {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 0.45rem 0.85rem;
  border-radius: 6px;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: default;
}
.vp-chip.agotada {
  opacity: 0.4;
  text-decoration: line-through;
}
/* Color si sigue siendo seleccionable (chips <button>, ver
   _renderChipsColor) -- talla ahora son <span> informativos (comun.js). */
#vp-chips-color .vp-chip { cursor: pointer; }
/* Talla del modal de contacto por DM/WhatsApp (2026-10-11): a diferencia
   de la talla informativa de la ficha, estos SI son botones clickeables. */
#contacto-tienda-chips-talla .vp-chip { cursor: pointer; font: inherit; }
#contacto-tienda-chips-talla .vp-chip.agotada { cursor: not-allowed; }
.vp-chip.activa { border-color: var(--accent); color: var(--accent); }
/* Talla recomendada segun tu cuerpo + preferencia de calce (2026-09-07) --
   se mantiene marcada aunque el usuario elija otro chip despues (a
   diferencia de .activa, que se mueve al hacer clic). */
.vp-chip.sugerida { border-style: dashed; border-color: var(--accent); }

/* "¿Cuál es mi talla?" (2026-10-12): link chico, no un boton lleno -- es
   una accion secundaria junto a las tallas, no la accion principal de la
   ficha (esa sigue siendo "Ver en tienda"). */
.vp-link-talla {
  display: block;
  margin-top: 0.5rem;
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-weight: 600;
  font-size: 0.85rem;
  text-decoration: underline;
  cursor: pointer;
}

/* "Detalles del producto" en tabla (2026-09-12, pedido del usuario):
   etiqueta en mayuscula y negrita, un dato por fila -- reemplaza el texto
   corrido "Campo: valor · Campo: valor" de antes. */
.vp-tabla-detalles { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.vp-tabla-detalles tr { border-bottom: 1px solid var(--border); }
.vp-tabla-detalles tr:last-child { border-bottom: none; }
.vp-tabla-detalles th,
.vp-tabla-detalles td { padding: 0.5rem 0.25rem; text-align: left; font-weight: normal; }
.vp-tabla-detalles th { font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; white-space: nowrap; padding-right: 1rem; }

/* Acordeon de detalles (descripcion/detalles/materiales/envio) -- <details>
   nativo, sin JS extra para abrir/cerrar. */
.vp-acordeon { margin-top: 1.25rem; border-top: 1px solid var(--border); }
.vp-acordeon details { border-bottom: 1px solid var(--border); padding: 0.75rem 0; }
.vp-acordeon summary { cursor: pointer; font-weight: 600; }
.vp-acordeon p { margin: 0.5rem 0 0; color: var(--text); white-space: pre-line; }

/* Estrellas y resenas */
.vp-estrellas { color: #d4a017; letter-spacing: 1px; }
.vp-estrellas-resumen { font-size: 0.9rem; margin: 0.15rem 0 0.5rem; }
.vp-resenas { margin-top: 1.75rem; border-top: 1px solid var(--border); padding-top: 1.25rem; }
.vp-resenas h3 { margin: 0 0 0.85rem; }
.vp-estrellas-grande { font-size: 1.6rem; }
.vp-resumen-numero { font-weight: 600; margin: 0.25rem 0 0.85rem; }
.vp-barras { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 1.25rem; max-width: 280px; }
.vp-barra-estrella { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; }
.vp-barra-fondo { flex: 1; height: 6px; background: var(--border); border-radius: 3px; overflow: hidden; }
.vp-barra-relleno { height: 100%; background: #d4a017; }
.vp-resena { border-top: 1px solid var(--border); padding: 0.85rem 0; }
.vp-resena-cabecera { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.vp-resena-usuario { font-weight: 600; }
.vp-compra-verificada {
  font-size: 0.7rem;
  color: #2e7d32;
  border: 1px solid #2e7d32;
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
}
.vp-resena-comentario { margin: 0.4rem 0; }
.vp-resena-fecha { font-size: 0.75rem; color: #999; }
.vp-resenas-vacio { color: #999; font-style: italic; }

/* Boton "Agregar al carrito" a nivel tarjeta (abre la ficha, ver
   conectarVistaPrevia en comun.js) -- reusa el estilo base de <button>
   (fondo rojo, blanco) ya definido mas arriba en el archivo. */
.btn-abrir-ficha-carrito { display: block; width: 100%; font-size: 0.95rem; }

/* Boton "Vista previa rapida" dentro de cada tarjeta -- secundario, no
   compite con el link de "Ver producto" (que sigue siendo el acento rojo). */
.btn-vista-previa {
  display: block;
  width: 100%;
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.55rem;
  border-radius: 8px;
  cursor: pointer;
  margin-bottom: 0.5rem;
}

.tarjeta-vitrina .btn-vista-previa { font-size: 0.72rem; padding: 0.4rem; }

/* --- Animacion antes de ir a una tienda externa (ver abrirEnlaceConAnimacion
   en comun.js) -- "Te llevamos a {tienda}..." + cuenta regresiva corta con
   Koko rebotando, estilo apps grandes de e-commerce. Rapida a proposito
   (~1.1s totales), nunca alarga la espera real. */
.tarjeta-redireccion { text-align: center; max-width: 300px; }
.tarjeta-redireccion #redireccion-texto { margin: 0.75rem 0 0.5rem; font-weight: 600; }

.redireccion-koko {
  width: 84px;
  height: 84px;
  object-fit: cover;
  object-position: top;
  border-radius: 50%;
  margin: 0 auto;
  display: block;
  border: 3px solid var(--accent);
  animation: redireccion-rebote 0.6s ease-in-out infinite;
}

@keyframes redireccion-rebote {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-10px) scale(1.05); }
}

.redireccion-cuenta {
  font-size: 2.2rem;
  font-weight: 800;
  color: var(--accent);
  margin: 0.25rem 0 0;
  animation: choque-entrada 0.28s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* --- Koko: acceso, panel de chat, burbujas, animacion --- */

/* Icono flotante chico (aparte del item "Koko" de la barra de navegacion)
   -- abre el panel en modo ventana chica, arriba de la barra de nav para
   no taparla. */
.fab-koko {
  position: fixed;
  right: 1rem;
  /* Corrido mas arriba (antes 5.25rem) para dejarle espacio abajo a
     .fab-ayuda, que ocupa el lugar que este boton tenia antes -- ver mas
     abajo. Subido de 8.25rem a 9.5rem (2026-09-29) al agrandar
     .barra-nav-inferior, para mantener el mismo espacio libre arriba de
     la barra. */
  bottom: calc(9.5rem + env(safe-area-inset-bottom, 0px));
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 2px solid var(--card);
  padding: 0;
  overflow: hidden;
  background: var(--accent);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  z-index: 95;
}

.fab-koko img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
}

/* Boton flotante "Volver a Koko" en /resultados -- antes era un boton mas
   arriba de la pagina (misma clase que "Cambiar requisitos"), habia que
   scrollear hasta arriba para verlo. Ahora queda fijo (position: fixed)
   mientras se hace scroll por los resultados, chico y discreto, abajo a la
   izquierda para no chocar con .fab-koko/.fab-ayuda (abajo a la derecha).
   El click sigue abriendo el MISMO panel de Koko sin reiniciar nada (ver
   resultados.js) -- esto es solo el cambio visual/posicion. */
.btn-volver-koko-flotante {
  position: fixed;
  left: 1rem;
  /* Subido de 5.25rem a 6.5rem (2026-09-29) al agrandar .barra-nav-inferior. */
  bottom: calc(6.5rem + env(safe-area-inset-bottom, 0px));
  z-index: 95;
  padding: 0.5rem 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 600;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2);
  cursor: pointer;
}

/* Icono fijo debajo del avatar de Koko -- reabre la guia de bienvenida
   (tour de 3 pantallas) en cualquier momento, no solo la primera vez. Mismo
   punto de anclaje (esquina inferior derecha) que .fab-koko, pero mas chico
   -- es una accion secundaria. */
.fab-ayuda {
  position: fixed;
  right: 1rem;
  /* Subido de 5.25rem a 6.5rem (2026-09-29) al agrandar .barra-nav-inferior. */
  bottom: calc(6.5rem + env(safe-area-inset-bottom, 0px));
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: none;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--card);
  color: var(--accent);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  z-index: 95;
}

.fab-ayuda svg {
  width: 20px;
  height: 20px;
}

/* Boton de tips (2026-10-05): va a la izquierda del "?", a la misma altura. */
.fab-tips {
  right: calc(1rem + 38px + 0.5rem);
}

.modal-tips {
  max-height: 85vh;
  overflow-y: auto;
}

.lista-tips {
  padding-left: 1.25rem;
  margin: 0.5rem 0 0;
  line-height: 1.45;
}

.lista-tips li {
  margin-bottom: 0.75rem;
}

/* Overlay del chat: por defecto es una ventana chica flotante (abierta
   desde .fab-koko); con la clase "pantalla-completa" (agregada por
   koko.js cuando se abre desde el item "Koko" de la barra de navegacion)
   pasa a cubrir toda la pantalla, como una app de mensajeria. */
.panel-koko-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 1rem;
  /* Subido de 5.25rem a 6.5rem (2026-09-29) al agrandar .barra-nav-inferior. */
  padding-bottom: calc(6.5rem + env(safe-area-inset-bottom, 0px));
  z-index: 100;
}

.panel-koko-overlay.pantalla-completa {
  background: none;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
}

.panel-koko {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 16px;
  width: 100%;
  max-width: 360px;
  max-height: 75vh;
  display: flex;
  /* Apilado (personaje arriba, chat abajo) por defecto -- ventana chica
     SIEMPRE se ve asi (no hay ancho para 2 columnas en un popup de
     360px), y pantalla completa tambien parte apilada en celular angosto.
     Se vuelve fila (2 columnas) solo en pantalla completa + pantalla
     ancha, ver el @media mas abajo. */
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
}

.panel-koko-overlay.pantalla-completa .panel-koko {
  max-width: none;
  max-height: none;
  width: 100%;
  height: 100%;
  border-radius: 0;
  box-shadow: none;
}

/* Columna derecha completa (header + mensajes + input) -- envuelta en su
   propio contenedor para poder ponerla al lado del personaje en pantalla
   ancha sin cambiar nada de adentro. min-width:0 es necesario para que un
   hijo flex se pueda achicar bien (si no, el texto largo lo empuja). */
.panel-koko-chat {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Diseño de app de chat de verdad (tipo Discord/WhatsApp Web: panel
   lateral fijo + conversacion) -- solo cuando hay espacio real para 2
   columnas. Debajo de este ancho, pantalla completa se sigue viendo
   apilada (celular angosto), igual que la ventana chica siempre. */
@media (min-width: 768px) {
  .panel-koko-overlay.pantalla-completa .panel-koko {
    flex-direction: row;
  }

  .panel-koko-overlay.pantalla-completa .panel-koko-personaje {
    width: 340px;
    height: 100%;
    min-height: 0;
    max-height: none;
    flex-shrink: 0;
    border-bottom: none;
    border-right: 1px solid var(--border);
    /* Margen chico a proposito -- con object-fit:cover de aca abajo la
       imagen ya llena casi toda la columna sola, este padding es solo un
       respiro, no el hueco grande que habia antes. */
    padding: 1.25rem;
  }

  /* La imagen de Koko es angosta y alta (proporcion 2:3) dentro de una
     columna todavia mas angosta y mucho mas alta -- con "contain" (el
     valor de siempre, bueno para la franja horizontal apilada) quedaba
     chica en el medio de un hueco enorme arriba/abajo. "cover" la escala
     para llenar el alto completo de la columna sin estirarla ni deformarla
     -- solo recorta un poco los costados (fondo alrededor del personaje,
     no al personaje en si). Object-position:center reparte ese recorte
     parejo a los 2 lados. */
  .panel-koko-overlay.pantalla-completa .personaje-koko {
    object-fit: cover;
    object-position: center;
  }
}

.panel-koko-header {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}

.panel-koko-header h2 {
  margin: 0;
  font-size: 1.1rem;
  flex: 1;
}

.btn-cerrar-koko {
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--text);
  cursor: pointer;
  /* Padding generoso a proposito: 44px de alto/ancho es el minimo
     recomendado para tocar con el dedo comodo. */
  padding: 0.65rem;
}

/* Misma clase que el boton de cerrar (×, texto) -- el de reiniciar
   (#btn-reiniciar-koko) usa un icono SVG en vez de texto, necesita su
   propio tamano. */
.btn-cerrar-koko svg {
  width: 20px;
  height: 20px;
  display: block;
}

/* Personaje de cuerpo completo -- presencia visual real, no un icono
   circular chico. Altura fija (no la imagen completa a tamano natural,
   que es muy alta) con object-fit:contain para nunca recortarlo. Mas
   grande en pantalla completa; en ventana chica se reduce para dejarle
   espacio de sobra al chat en si. */
.panel-koko-personaje {
  flex-shrink: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 130px;
  min-height: 100px;
  max-height: 150px;
  background: linear-gradient(180deg, var(--bg), var(--card));
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}

/* BUG encontrado y corregido (2026-08-10): esta regla no tenia @media, asi
   que tambien se aplicaba en pantalla ancha -- y como viene DESPUES en el
   archivo que la regla de la columna lateral (arriba, dentro de
   @media min-width:768px), con la MISMA especificidad le ganaba en la
   cascada y volvia a topear la columna a 340px de alto (una cajita chica
   arriba), sin importar que la imagen ya tuviera object-fit:cover. Ahora
   queda scopeada SOLO a pantalla angosta (celular, franja apilada) para
   que nunca pueda pisar a la regla de la columna ancha. */
@media (max-width: 767px) {
  .panel-koko-overlay.pantalla-completa .panel-koko-personaje {
    height: 34vh;
    min-height: 220px;
    max-height: 340px;
  }
}

.personaje-koko {
  /* width/height 100% (en vez de solo height) para que object-fit:contain
     calce bien tanto en una franja ancha y baja (apilado) como en una
     columna angosta y alta (barra lateral, pantalla ancha) -- la misma
     regla sirve para los 2 layouts, no hace falta duplicarla. */
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom;
  /* opacity: usada por iniciarAnimacionKoko() (koko.js) para un fundido
     cortito entre emotes, en vez de un corte seco de una foto a otra. */
  transition: transform 0.2s ease, opacity 0.12s ease;
}

.mensajes-koko {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.burbuja-koko {
  max-width: 85%;
  padding: 0.55rem 0.8rem;
  border-radius: 14px;
  font-size: 0.9rem;
  line-height: 1.35;
  /* Respeta los saltos de linea reales del texto (ej: linea en blanco
     entre "Opcion 1" y "Opcion 2") sin necesidad de convertirlos a <br> a
     mano en JS -- ver formatearTextoKoko() en koko.js. */
  white-space: pre-wrap;
}

.burbuja-koko-koko {
  align-self: flex-start;
  background: var(--bg);
  border: 1px solid var(--border);
  border-bottom-left-radius: 4px;
}

.burbuja-koko-usuario {
  align-self: flex-end;
  background: var(--accent);
  color: white;
  border-bottom-right-radius: 4px;
}

/* Boton "?" que abre la guia -- antes era un simple "?" sin texto y nadie
   entendia para que servia (pedido del usuario, 2026-08-27); ahora es un
   circulo "?" con la palabra "Guia" abajo, para que se entienda de un
   vistazo sin necesidad de leer el aria-label. */
.btn-guia-koko {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  background: none;
  border: none;
  color: var(--text);
  cursor: pointer;
  padding: 0.35rem 0.4rem;
  line-height: 1;
}
.btn-guia-koko-glifo {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-guia-koko-etiqueta {
  font-size: 0.6rem;
  font-weight: 600;
}

/* Guia "que le puedo preguntar a Koko" -- reusa .modal-overlay/.tarjeta-modal
   (mismo z-index 110, arriba del panel de chat que es z-index 100), solo se
   agrega lo especifico: mas ancho/alto que la tarjeta chica del onboarding
   (aca hay bastante mas contenido) y el estilo de las categorias/preguntas. */
.tarjeta-guia-koko {
  max-width: 420px;
  max-height: 85vh;
  overflow-y: auto;
  text-align: left;
}
.tarjeta-guia-koko h2 { text-align: center; }
.tarjeta-guia-koko > p { text-align: center; font-size: 0.85rem; }

.guia-koko-categoria {
  border-top: 1px solid var(--border);
  padding: 0.5rem 0;
}
.guia-koko-categoria summary {
  cursor: pointer;
  font-weight: 600;
  padding: 0.25rem 0;
}
.guia-koko-preguntas {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
}
.pregunta-guia-koko {
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.5rem 0.7rem;
  font-size: 0.82rem;
  color: var(--text);
  cursor: pointer;
}

.sugerencia-koko {
  margin: 0 1rem 0.75rem;
  padding: 0.75rem;
  background: var(--bg);
  border: 1px dashed var(--accent);
  border-radius: 10px;
}

/* Mismo aviso que "Encontramos productos para ti hace un momento" del chat
   de Koko (.sugerencia-koko), pero para el buscador normal (formulario) --
   aparece en el paso "¿Para quien es esta busqueda?" cuando queda una
   busqueda de la sesion actual sin ver (ver script.js). */
.aviso-resultados-pendientes {
  margin: 0 0 1rem;
  padding: 0.75rem;
  background: var(--bg);
  border: 1px dashed var(--accent);
  border-radius: 10px;
}

.aviso-resultados-pendientes p {
  margin: 0 0 0.5rem;
  font-weight: 600;
  font-size: 0.9rem;
}

.aviso-resultados-pendientes .botones-quien {
  margin: 0;
}

.sugerencia-koko p {
  margin: 0 0 0.5rem;
  font-weight: 600;
  font-size: 0.9rem;
}

.sugerencia-koko .botones-quien {
  margin: 0;
}

.form-koko {
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem;
  border-top: 1px solid var(--border);
}

.form-koko input {
  flex: 1;
}

/* Rebote/balanceo mientras Koko "esta pensando" una respuesta -- se agrega
   y saca la clase desde koko.js, nunca queda pegada. */
/* Antes se aplicaba a un icono chico de 40px (giro sutil bastaba); ahora es
   el personaje de cuerpo completo, asi que el rebote se nota mas fuerte y
   se le suma un pulso de escala para que se lea como un salto/baile real,
   no solo un tambaleo. */
/* Pulso de RESPALDO -- solo se usa cuando no hay poses/frames disponibles
   todavia (ver KOKO_FRAMES en koko.js). A proposito NO mueve al personaje
   de lugar (nada de translate/rotate): la correccion fue justamente esa,
   que la imagen entera se desplazaba en vez de sentirse un personaje vivo.
   Con las poses ya generadas, esto casi no se llega a ver -- la animacion
   real es el cambio de pose. */
@keyframes koko-pulso {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

.koko-pensando {
  animation: koko-pulso 0.9s ease-in-out infinite;
}

/* Activado a mano (atributo data-theme en <html>), no por preferencia del
   sistema -- ver nota en :root de arriba. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0d0d0d;
  --card: #1c1c1c;
  --text: #f5f5f5;
  --border: #333333;
  /* --accent se mantiene igual -- el rojo funciona bien sobre ambos
     fondos, tal como se pidio ("el logo funciona en ambos"). */
  --insignia-neutral-bg: #f5f5f5;
  --insignia-neutral-texto: #0d0d0d;
}

/* --- Banner "instalar en iPhone" (2026-09-29) -----------------------------
   Fijo arriba (no abajo, para no pelear con .barra-nav-inferior en las
   paginas que la tienen, y para que igual se vea bien en login/registro,
   que no la tienen). Armado por JS (ver comun.js), no vive en el HTML de
   ninguna plantilla. */
.banner-instalar-ios {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* Mas alto que el resto de los iconos flotantes fijos arriba (fab-koko/
     fab-ayuda/fab-llegan-rapido, todos z-index 95) para que este banner
     quede claramente por encima mientras esta visible, sin quedar la
     mitad tapado -- por debajo del splash de apertura (z-index 300). */
  z-index: 150;
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.6rem 2.6rem 0.6rem calc(0.9rem + env(safe-area-inset-left, 0px));
  padding-top: calc(0.6rem + env(safe-area-inset-top, 0px));
  background: var(--accent);
  color: #ffffff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
}

.banner-instalar-ios-icono {
  font-size: 1.3rem;
  flex-shrink: 0;
  margin-top: 0.1rem;
}

/* Con el banner abierto, la pagina baja lo que mide (ver comun.js) para que
   nada quede tapado al entrar; al cerrarlo se quita la clase y vuelve todo. */
body.banner-ios-visible {
  padding-top: var(--alto-banner-ios, 0px);
}

body.banner-ios-visible .fab-cuenta,
body.banner-ios-visible .fab-llegan-rapido {
  top: calc(var(--alto-banner-ios, 0px) + 0.6rem);
}

.banner-instalar-ios-texto {
  min-width: 0;
  flex: 1;
}

.banner-instalar-ios p {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.35;
}

.banner-instalar-ios-pasos {
  margin: 0.25rem 0;
  padding-left: 1.1rem;
  font-size: 0.8rem;
  line-height: 1.35;
}

.banner-instalar-ios-cierre {
  font-size: 0.8rem;
  opacity: 0.92;
}

.banner-instalar-ios-svg-compartir {
  width: 15px;
  height: 15px;
  vertical-align: -2px;
  margin: 0 1px;
}

#btn-cerrar-banner-instalar-ios {
  position: absolute;
  top: calc(0.4rem + env(safe-area-inset-top, 0px));
  right: calc(0.6rem + env(safe-area-inset-right, 0px));
  background: none;
  border: none;
  color: #ffffff;
  font-size: 1.4rem;
  line-height: 1;
  padding: 0.2rem 0.4rem;
  cursor: pointer;
}

/* --- Barra de navegacion fija abajo (Buscar / Koko / Vitrina / Mi perfil) --- */

.barra-nav-inferior {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 90;
  display: flex;
  background: var(--card);
  border-top: 1px solid var(--border);
  /* 2026-09-30, pedido del usuario: env(safe-area-inset-bottom) solo, sin
     nada de mas, dejaba los botones tocando justo el borde de la zona
     segura (la barra de gestos del celular) -- se le suma un colchon fijo
     aparte para que quede aire real antes de esa zona, no pegado. */
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 0.6rem);
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
  /* 2026-09-30 (segunda vuelta, pedido del usuario): causa real de "pegada
     al borde" encontrada -- a las etiquetas <meta name="viewport"> de TODAS
     las plantillas les faltaba "viewport-fit=cover". Sin eso, iOS nunca
     entrega el alto real en env(safe-area-inset-bottom) (siempre da 0px),
     asi que el calc() de arriba llevaba anos sumando "0 + colchon" nomas,
     nunca el espacio real de la barra de gestos. Ya se agrego
     viewport-fit=cover en el <meta viewport> de cada plantilla -- ver
     docs/ui_features.md.
     Ademas, en la pantalla del buscador ("/") especificamente se veia
     "flotando" al enfocar un campo del formulario (nombre/gmail/altura/
     etc, esa es la unica pantalla con tanto input de texto abierto de
     entrada) -- bug conocido de iOS/WebKit: al abrir el teclado, un
     elemento position:fixed que no esta en su propia capa de composicion
     GPU puede recalcular mal su posicion contra el viewport visual y
     quedar "flotando" a mitad de pantalla. translateZ(0) fuerza esa capa
     propia para que seguir pegado al fondo real, siempre. */
  transform: translateZ(0);
}

/* Instalada como app (2026-09-30, pedido del usuario: "en la PWA... queda
   demasiado pegada al borde") -- ahi no hay ninguna barra de navegador
   propia debajo, asi que el safe-area-inset-bottom del celular es la unica
   referencia real, y el colchon de arriba solo no alcanzaba a sentirse
   comodo para tocar. display-mode:standalone es como Chrome/Safari marcan
   "esto se abrio desde el icono de inicio, no desde el navegador normal". */
@media (display-mode: standalone) {
  .barra-nav-inferior {
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 1.1rem);
  }
}

.barra-nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.9rem 0.25rem 0.75rem;
  background: none;
  border: none;
  color: #888;
  text-decoration: none;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.barra-nav-item svg {
  width: 28px;
  height: 28px;
}

.barra-nav-item.activo {
  color: var(--accent);
}

.barra-nav-icono-koko {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
}

/* --- Vitrina: navegacion libre, tarjetas en cuadricula por seccion --- */

/* La pagina de Vitrina es mas compacta que el resto (filas chicas, no
   tarjetas grandes apiladas) para que Tendencias y Ofertas quepan
   visibles al mismo tiempo, sin scroll vertical. */
.pagina-vitrina { padding-top: 1.25rem; }
.vitrina-main h1 { margin-bottom: 0.15rem; }
.vitrina-main .subtitulo { margin-bottom: 1rem; }

/* Escritorio (2026-08-25): "main" por defecto tiene max-width:640px (pensado
   para formularios angostos) -- en pantallas de escritorio eso dejaba mucho
   espacio vacio a los costados de las filas de Descubre. Solo se ensancha
   ACA (clase propia de /vitrina), nunca toca el resto de las paginas ni la
   version movil (el media query ni se activa bajo 1024px). */
@media (min-width: 1024px) {
  .vitrina-main { max-width: 1280px; }
}

.fila-seccion {
  margin-top: 1rem;
}

.fila-seccion h2 {
  font-size: 0.95rem;
  margin: 0 0 0.4rem;
}

.fila-carrusel {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.fila-vitrina {
  display: flex;
  gap: 0.75rem;
  overflow-x: auto;
  /* proximity, no mandatory (2026-08-29): "mandatory" fuerza al navegador a
     re-snapear la posicion apenas se suelta el arrastre, lo que se sentia
     como que el carrusel "se recentraba solo" al llegar al extremo
     izquierdo (bug reportado por el usuario). "proximity" solo ajusta si ya
     quedaste naturalmente cerca de una tarjeta, sin forzar saltos en los
     bordes. */
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 0.35rem;
  flex: 1;
  min-width: 0;
  /* Barra de scroll mas fina en todas las filas de Descubre (pedido del
     usuario, 2026-08-28), no solo la nativa gruesa por defecto. */
  scrollbar-width: thin;
}

.fila-vitrina::-webkit-scrollbar {
  height: 4px;
}

.fila-vitrina::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}

.fila-vitrina::-webkit-scrollbar-track {
  background: transparent;
}

/* Flechas para navegar el carrusel sin depender solo del gesto de swipe.
   Se ocultan solas en pantallas angostas (touch), donde el swipe alcanza y
   sobrarian ocupando espacio. */
.fila-flecha {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

@media (max-width: 480px) {
  .fila-flecha { display: none; }
}

.tarjeta-vitrina {
  flex: 0 0 148px;
  scroll-snap-align: start;
  padding: 0.75rem 0.85rem;
  position: relative;
}

.tarjeta-vitrina .imagen-producto { max-width: 100px; }
.tarjeta-vitrina h3 { font-size: 0.85rem; line-height: 1.25; }
.tarjeta-vitrina .tienda { font-size: 0.75rem; }
.tarjeta-vitrina .marca { font-size: 0.72rem; }
.tarjeta-vitrina .razon { font-size: 0.72rem; margin: 0.35rem 0 0; }
.tarjeta-vitrina a { font-size: 0.8rem; }

/* "Llegan rápido a ti" (2026-08-25): ya no es una fila del feed ni un
   boton inline -- ahora es un icono fijo arriba, mismo tamaño/estilo
   flotante que .fab-koko (abajo a la derecha), para que sea un acceso
   constante en vez de una fila mas entre Ofertas/Destacados. El click abre
   el mismo modal de siempre (reusa .modal-overlay/.tarjeta-modal) con solo
   INFO de tiendas, nunca un catalogo de productos.
   2026-09-02: con el icono de "Mi cuenta" (.fab-cuenta) agregado despues en
   ese mismo punto (arriba a la derecha, en TODAS las paginas), quedaban los
   dos exactamente encimados y este quedaba tapado -- ahora va pegado al
   lado izquierdo de .fab-cuenta (40px + 0.5rem de separacion), a la misma
   altura, en vez de en la esquina opuesta. */
.fab-llegan-rapido {
  position: fixed;
  top: calc(1rem - 6px + env(safe-area-inset-top, 0px));
  right: calc(1rem + 40px + 0.5rem);
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 2px solid var(--card);
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  font-size: 1.4rem;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  z-index: 95;
}

.tarjeta-llegan-rapido { max-width: 420px; text-align: left; }

.lista-llegan-rapido {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 55vh;
  overflow-y: auto;
}

.item-llegan-rapido {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
}
.item-llegan-rapido:last-child { border-bottom: none; }

.item-llegan-rapido-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.item-llegan-rapido-envio { color: var(--accent); font-weight: 600; font-size: 0.85rem; }
.item-llegan-rapido-ubicacion { color: #666; font-size: 0.8rem; }
.item-llegan-rapido a { color: var(--accent); font-weight: 600; white-space: nowrap; }

.insignia-vitrina {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 1;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  max-width: calc(100% - 1rem);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Oferta usa el rojo de marca (sale tag clasico); Tendencia usa el par
   neutro (negro en modo claro, blanco en modo oscuro) para no competir
   con el rojo -- ver variables en :root. */
.insignia-tendencia { background: var(--insignia-neutral-bg); color: var(--insignia-neutral-texto); }
.insignia-oferta { background: var(--accent); color: white; }

.precio-vitrina {
  margin: 0.3rem 0 0;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.precio-vitrina .precio { margin: 0; font-weight: 700; font-size: 0.85rem; }
.precio-vitrina .precio-tachado {
  color: #999;
  font-size: 0.75rem;
  text-decoration: line-through;
}

/* --- Mi perfil: resumen de datos guardados --- */

.perfil-resumen {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.25rem 1.25rem;
  margin-bottom: 1rem;
}

.perfil-fila {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
}

.perfil-fila:last-child {
  border-bottom: none;
}

/* Fila de "Busquedas recientes" en el historial (2026-08-28) que si guardo
   el payload para volver a correrse -- ver pintarHistorial en perfil.js.
   2026-09-07: la sola flecha "›" no se notaba (sobre todo en mobile, sin
   hover) -- ahora se agrega un texto explicito "Buscar de nuevo" debajo,
   por eso pasa a wrap (2 lineas) en vez de una sola fila de una linea. */
.perfil-fila-clickable {
  cursor: pointer;
  flex-wrap: wrap;
}
.perfil-fila-clickable:hover {
  background: var(--bg);
}
.perfil-fila-accion {
  width: 100%;
  font-size: 0.78rem;
  color: var(--accent);
  font-weight: 600;
}

.perfil-etiqueta {
  color: #888;
  font-size: 0.85rem;
}

.perfil-valor {
  font-weight: 600;
  text-align: right;
}

/* Interruptor de modo oscuro -- mismo lugar donde se edita el perfil. */
.fila-ajuste {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.9rem 1.25rem;
  margin-bottom: 1rem;
}

.interruptor {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 26px;
  flex-shrink: 0;
}

.interruptor input {
  opacity: 0;
  width: 0;
  height: 0;
}

.interruptor-riel {
  position: absolute;
  inset: 0;
  background: var(--border);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.interruptor-riel::before {
  content: "";
  position: absolute;
  height: 20px;
  width: 20px;
  left: 3px;
  bottom: 3px;
  background: white;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.2s ease;
}

.interruptor input:checked + .interruptor-riel {
  background: var(--accent);
}

.interruptor input:checked + .interruptor-riel::before {
  transform: translateX(18px);
}

/* Koko OFF temporalmente (2026-08-30, pedido del usuario) -- se saca del
   frontend sin borrar nada de HTML/JS/backend, para poder reactivarlo
   despues solo borrando este bloque. Oculta los 3 puntos de entrada al
   chat: el item de la barra de navegacion, el icono flotante, y el boton
   "Ver conversacion con Koko" del historial en /perfil. */
#btn-abrir-koko,
.fab-koko,
#btn-hablar-koko-historial {
  display: none !important;
}


/* Tip del dia (2026-09-20/21, pedido del usuario): tarjeta de /vitrina, 4ta
   en la grilla -- mismo patron emoji+titulo que las demas tarjeta-categoria
   (sin imagen ni boton "Ver X" propio, ver vitrina.html), asi que no
   necesita estilos aparte. */

/* Pantalla de bienvenida de Koko en el tour de onboarding (2026-09-20,
   pedido del usuario): a diferencia de las demas pantallas del tour (icono
   SVG chico), esta usa la foto real de Koko -- mas grande, sin el stroke de
   --accent que llevan los SVG. */
.tour-koko-img {
  width: 140px;
  height: 140px;
  object-fit: contain;
  margin: 0 auto;
  display: block;
}

/* Koko + globo de dialogo: componente compartido (2026-09-21) -- imagen de
   Koko con el mensaje en un globo de dialogo, en vez de texto plano
   suelto. Nacio en el estado "sin resultados" de /resultados (Koko
   aburrido) y se reusa igual en el modal de "Tip del dia" de /vitrina
   (Koko apuntando, ver vitrina.html/vitrina.js) -- mismas clases, 2
   imagenes distintas. Fondo gris de estudio removido con rembg -- WebP con
   transparencia real, asi que la imagen se integra directo contra el
   fondo de la tarjeta/modal, sin recuadro.
   Bug real (2026-09-21): el globo iba superpuesto ENCIMA de la imagen
   (position:absolute) -- funcionaba con Koko aburrido (tiene espacio
   vacio arriba de la cabeza en esa foto) pero en Koko apuntando la cabeza
   esta pegada arriba del todo, asi que el globo le tapaba la cara entera.
   Ahora el globo va en flujo normal ARRIBA de la imagen (no superpuesto),
   con la colita apuntando hacia abajo -- funciona igual de bien sin
   importar cuanto espacio tenga cada foto arriba de la cabeza. */
.estado-sin-resultados {
  display: flex;
  justify-content: center;
}
.koko-globo-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(80vw, 320px);
}
.koko-globo-wrap img {
  display: block;
  width: 100%;
  height: auto;
}
.globo-koko {
  position: relative;
  width: 92%;
  margin: 0 0 12px;
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 0.65rem 0.85rem;
  font-size: 0.85rem;
  font-weight: 600;
  text-align: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}
.globo-koko::after {
  content: "";
  position: absolute;
  bottom: -9px;
  left: 28%;
  border-width: 9px 7px 0 7px;
  border-style: solid;
  border-color: var(--card) transparent transparent transparent;
}

/* --- Admin: "Lo mas buscado" y "Embudo" (2026-10-06) ------------------- */
main.admin-analitica { max-width: 1100px; }
.form-rango-analitica, .form-tendencia, .form-vista-embudo, .form-metricas-mes {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  padding: 1rem;
  align-items: flex-end;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.form-rango-analitica label, .form-tendencia label, .form-vista-embudo label, .form-metricas-mes label {
  flex: 1 1 160px;
  min-width: 0;
}
.btn-aplicar-rango, .btn-exportar-csv {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 0.55rem 0.9rem;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.analitica-cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.analitica-total { margin: 0; }
.analitica-bloque {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1rem;
  margin-bottom: 1rem;
  min-width: 0;
}
.analitica-bloque h2 { font-size: 1rem; margin: 0 0 0.5rem; }
.analitica-destacado { border-color: var(--accent); }
.analitica-contador {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0 0.45rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 0.8rem;
}
.analitica-vacio { opacity: 0.7; font-size: 0.85rem; }
.analitica-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1rem;
}
.analitica-grilla .analitica-bloque { margin-bottom: 0; }
.tabla-scroll { overflow-x: auto; }
.tabla-analitica {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
}
.tabla-analitica th, .tabla-analitica td {
  border-bottom: 1px solid var(--border);
  padding: 0.35rem 0.5rem;
  text-align: left;
  vertical-align: middle;
  overflow-wrap: break-word;
}
.tabla-analitica th { opacity: 0.7; font-weight: 600; }
.tabla-analitica .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tabla-analitica th.num { white-space: normal; }
.tabla-scroll .tabla-analitica { min-width: 900px; }
.tabla-scroll .tabla-analitica td:first-child { min-width: 8rem; }
.tabla-analitica a { color: var(--text); }
.barra-pct {
  display: inline-block;
  width: 48px;
  height: 6px;
  border-radius: 3px;
  background: var(--border);
  vertical-align: middle;
  margin-right: 0.3rem;
  overflow: hidden;
}
.barra-pct span { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.grafico-tendencia { margin: 0.5rem 0; }
.grafico-tendencia svg { width: 100%; height: auto; display: block; }
.grafico-grilla { stroke: var(--border); stroke-width: 1; }
.grafico-eje { stroke: var(--text); stroke-opacity: 0.4; stroke-width: 1; }
.grafico-texto { fill: var(--text); fill-opacity: 0.7; font-size: 11px; }
.grafico-linea { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.grafico-punto circle { fill: var(--accent); stroke: var(--card); stroke-width: 2; }
.grafico-hit { fill: transparent; }
.grafico-punto:hover .grafico-hit { fill: var(--text); fill-opacity: 0.06; }
.grafico-punto:hover circle { r: 6; }
.tabla-tendencia summary { cursor: pointer; font-size: 0.85rem; margin-bottom: 0.5rem; }
.embudo-pasos { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.embudo-paso {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  align-items: baseline;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 8px;
}
.embudo-titulo { font-weight: 600; flex: 1 1 220px; }
.embudo-caida { flex-basis: 100%; font-size: 0.8rem; opacity: 0.75; }
.embudo-paso-general { border-left-color: var(--border); }
.embudo-fuera { border-style: dashed; border-left: 4px dashed var(--border); opacity: 0.85; }
.embudo-na { opacity: 0.65; font-size: 0.82rem; }
.form-borrar-metrica { margin: 0; padding: 0; border: none; background: none; }
.form-tendencia, .form-metricas-mes { background: none; border: none; padding: 0; }
.btn-borrar-metrica {
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 0.2rem 0.5rem;
  font-size: 0.75rem;
  cursor: pointer;
}
