:root {
  --bg: #0f172a;
  --surface: #1e293b;
  --surface2: #273449;
  --border: #334155;
  --text: #e2e8f0;
  --muted: #94a3b8;
  --accent: #6366f1;
  --accent-hover: #4f46e5;
  --success: #22c55e;
  --danger: #ef4444;
  --radius: 10px;
  --sans: 'Segoe UI', system-ui, sans-serif;
}

* { box-sizing: border-box; }

/* Scrollbar propia (por defecto el navegador dibuja una gris generica que
   desentona con el tema oscuro/glass del resto de la UI) — fina, con
   esquinas redondeadas como el resto de los componentes (var(--radius)),
   colores del mismo set que tarjetas/bordes/acento. Firefox usa las
   propiedades estandar (scrollbar-width/scrollbar-color); Chrome/Edge/
   Safari usan los pseudo-elementos ::-webkit-scrollbar-*. Se define una
   sola vez a nivel global para que aplique tanto al scroll de la pagina
   como al scroll interno del modal de efectos (.effect-apply-modal) y
   cualquier otro contenedor con overflow, sin repetirlo por componente. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background-color: var(--border);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background-color: var(--accent); }
::-webkit-scrollbar-corner { background: transparent; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.5;
  position: relative;
  overflow-x: hidden;
}

/* Fondo tipo "aurora": manchas de color muy tenues que se mueven despacio
   detras de todo. Es lo que hace que un panel oscuro se sienta "vivo" en
   vez de plano, sin animar nada que distraiga del contenido. */
body::before {
  content: '';
  position: fixed;
  inset: -20%;
  background:
    radial-gradient(circle at 20% 20%, rgba(99, 102, 241, 0.25), transparent 40%),
    radial-gradient(circle at 80% 25%, rgba(34, 197, 94, 0.12), transparent 40%),
    radial-gradient(circle at 50% 85%, rgba(99, 102, 241, 0.18), transparent 45%);
  filter: blur(60px);
  z-index: -1;
  animation: aurora-drift 18s ease-in-out infinite alternate;
  pointer-events: none;
}
@keyframes aurora-drift {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(3%, -3%) scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
}

.hidden { display: none !important; }

/* Banner de resultado de pago */
.banner {
  padding: 12px 20px;
  text-align: center;
  font-weight: 600;
}
.banner-success { background: rgba(34, 197, 94, 0.15); color: var(--success); }
.banner-cancel { background: rgba(239, 68, 68, 0.15); color: var(--danger); }

/* Barra superior */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}
.brand { font-weight: 700; font-size: 1.1rem; }
.topbar-right { display: flex; align-items: center; gap: 14px; font-size: 0.9rem; }
.credits-pill { background: var(--surface2); padding: 6px 12px; border-radius: 999px; }
.topbar-link { color: var(--muted); text-decoration: none; font-size: 0.9rem; transition: color 0.2s ease; }
.topbar-link:hover { color: var(--text); }

/* Mencion moderada de los medios de pago (Wompi/Nequi son marcas
   confiables en Colombia, ayuda contra la desconfianza a pagar con
   tarjeta online) — una linea discreta, no una tarjeta grande. */
.wompi-nequi-note {
  margin: 0 0 20px;
  padding: 10px 16px;
  background: rgba(99, 102, 241, 0.08);
  border: 1px solid rgba(99, 102, 241, 0.25);
  border-radius: 8px;
  font-size: 0.85rem;
  color: var(--muted);
  line-height: 1.5;
}
.wompi-nequi-note strong { color: var(--text); }
.wompi-nequi-note a { color: var(--accent); font-weight: 600; text-decoration: none; white-space: nowrap; }
.wompi-nequi-note a:hover { text-decoration: underline; }

main { max-width: 1000px; margin: 0 auto; padding: 24px; }
/* La pantalla de login/registro (#authView) es full-bleed a proposito (fondo
   de galeria ocupando todo el ancho, como en la referencia de Lanta AI):
   no debe heredar el max-width de 1000px pensado para el dashboard. */
main:has(#authView:not(.hidden)) { max-width: none; padding: 0; }
/* El dashboard suma una barra lateral al costado del contenido, necesita
   mas ancho que el resto de las pantallas (que son una sola columna). */
main:has(#dashboardView:not(.hidden)) { max-width: 1240px; }

/* Fondo con galeria de ejemplos tambien en el dashboard (antes era un
   azul plano) — mismo patron que el login: .gallery-bg va fixed detras de
   todo, .dashboard-view necesita su propio stacking context para quedar
   arriba de ese fondo (y de su degrade de legibilidad). */
.dashboard-view { position: relative; z-index: 1; }

/* Barra lateral de navegacion: panel fijo pegado al borde izquierdo de la
   pantalla, ocupando todo el alto disponible debajo del topbar (72px),
   estilo "rail" de dashboard moderno (ref. lantaai.com/home). Al ser
   position:fixed queda fuera del flujo, por eso .dashboard-main compensa
   con margin-left para que las cards no queden tapadas. */
.dashboard-layout { display: block; }
.sidebar {
  position: fixed;
  top: 72px;
  left: 0;
  bottom: 0;
  width: 240px;
  overflow-y: auto;
  background: rgba(30, 41, 59, 0.65);
  border-right: 1px solid rgba(51, 65, 85, 0.7);
  padding: 18px 14px;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  z-index: 5;
}
.sidebar-nav { display: flex; flex-direction: column; gap: 4px; }
.sidebar-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.88rem;
  font-weight: 500;
  transition: background 0.2s ease, color 0.2s ease;
}
.sidebar-link svg { width: 18px; height: 18px; flex-shrink: 0; }
.sidebar-link:hover { background: var(--surface2); color: var(--text); }
.sidebar-link.active {
  background: linear-gradient(90deg, rgba(99, 102, 241, 0.22), rgba(168, 85, 247, 0.1));
  color: var(--text);
  box-shadow: inset 3px 0 0 var(--accent);
}
.dashboard-main { margin-left: 264px; }

@media (max-width: 900px) {
  /* No hay lugar para un riel fijo de 240px: la barra vuelve al flujo
     normal, como una fila horizontal con scroll arriba del contenido
     (mismo patron que una tab bar movil). */
  .sidebar {
    position: static;
    width: 100%;
    height: auto;
    border-right: none;
    border-bottom: 1px solid rgba(51, 65, 85, 0.7);
    padding: 8px;
    margin-bottom: 16px;
  }
  .sidebar-nav { flex-direction: row; overflow-x: auto; gap: 4px; }
  .sidebar-link {
    flex-direction: column;
    gap: 4px;
    padding: 8px 10px;
    font-size: 0.7rem;
    white-space: nowrap;
    text-align: center;
  }
  .sidebar-link svg { width: 20px; height: 20px; }
  .sidebar-link.active { box-shadow: inset 0 -3px 0 var(--accent); }
  .dashboard-main { margin-left: 0; }
}

/* Cards: "vidrio esmerilado" (fondo semitransparente + blur) para que se
   note el degrade animado de body::before por detras — es la misma tecnica
   que usan la mayoria de los paneles oscuros modernos (davinci.ai incluido). */
.card {
  background: rgba(30, 41, 59, 0.65);
  border: 1px solid rgba(51, 65, 85, 0.7);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 20px;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition: border-color 0.25s ease;
}
.card:hover { border-color: rgba(99, 102, 241, 0.35); }
.card h2 { margin-top: 0; font-size: 1.1rem; }

/* Titulo de card + link de ayuda a la derecha (ej. "Generador de Imagenes"
   -> guia de prompts, abre en pestaña nueva para no perder el form). */
.card-header-with-link { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.card-header-with-link h2 { margin: 0; }
.card-header-link { color: var(--accent); font-size: 0.85rem; text-decoration: none; white-space: nowrap; }
.card-header-link:hover { text-decoration: underline; }

.grid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 20px; }
@media (max-width: 720px) {
  .grid { grid-template-columns: 1fr; }
}

/* Galeria rotativa de ejemplos (login de fondo + tarjeta en el dashboard).
   Dos capas de <img>/<video> superpuestas que se cruzan con un fade; una
   barra de progreso por item marca el avance, igual que el patron que usan
   la mayoria de los paneles de "ejemplos" en apps de IA generativa. */
.gallery { position: relative; overflow: hidden; background: var(--surface2); }
.gallery-media-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
}
.gallery-media-layer.visible { animation: gallery-fade-in 1.1s ease forwards; }
@keyframes gallery-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.gallery-progress { position: absolute; z-index: 2; display: flex; gap: 6px; }
.gallery-progress-dot {
  flex: 1;
  height: 3px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.25);
  overflow: hidden;
}
.gallery-progress-fill { height: 100%; width: 0; background: white; }
.gallery-progress-fill.active { animation-name: gallery-fill; animation-timing-function: linear; animation-fill-mode: forwards; }
.gallery-progress-fill.done { width: 100%; }
@keyframes gallery-fill { from { width: 0; } to { width: 100%; } }

.gallery-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
}
.gallery-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(15, 23, 42, 0.5) 0%, rgba(15, 23, 42, 0.88) 65%, rgba(15, 23, 42, 0.98) 100%);
  z-index: 1;
}
.gallery-bg .gallery-progress { bottom: 20px; left: 50%; transform: translateX(-50%); width: min(320px, 70%); }

.gallery-card-wrap { padding-bottom: 14px; }
.gallery-card { height: 400px; border-radius: 8px; }
.gallery-card .gallery-media-layer { border-radius: 8px; }
.gallery-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(15, 23, 42, 0.75) 0%, rgba(15, 23, 42, 0) 45%);
  border-radius: 8px;
  z-index: 1;
}
.gallery-card .gallery-progress { bottom: 10px; left: 10px; right: 10px; }

@media (prefers-reduced-motion: reduce) {
  .gallery-media-layer.visible { animation: none; opacity: 1; }
  .gallery-progress-fill.active { animation: none; width: 100%; }
}

/* Login / registro */
.auth-view { display: flex; justify-content: flex-start; align-items: center; min-height: 100vh; padding: clamp(24px, 3vw, 56px); position: relative; }

/* La tarjeta de login/registro ya no esta siempre visible: vive dentro de
   un modal (#authModal) que se abre solo cuando el usuario aprieta algun
   CTA (ver data-auth-open en el HTML y app.js). */
.auth-modal {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(5, 8, 16, 0.75);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.auth-card { width: 100%; max-width: 380px; position: relative; z-index: 1; }
.auth-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface2);
  color: var(--text);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s ease;
}
.auth-modal-close:hover { background: var(--border); }

/* Franja superior tipo encabezado (igual patron que Lanta AI): marca a la
   izquierda, navegacion (Precios, Iniciar sesion, CTA de registro) a la
   derecha, fija arriba de todo. */
.auth-topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px clamp(24px, 3vw, 56px);
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.auth-topbar-brand {
  font-weight: 700;
  font-size: clamp(1.4rem, 1.6vw, 1.9rem);
  background: linear-gradient(90deg, var(--text), var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.auth-topbar-nav { display: flex; align-items: center; gap: 18px; }
.auth-topbar-link {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.9rem;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: color 0.2s ease;
}
.auth-topbar-link:hover { color: var(--text); }
.auth-topbar-free {
  background: linear-gradient(90deg, var(--accent), #a855f7);
  border: none;
  color: white;
  border-radius: 999px;
  padding: 10px 20px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.15s ease, box-shadow 0.2s ease;
}
.auth-topbar-free:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(99, 102, 241, 0.4); }

/* Columna izquierda completa (hero + beneficios), sobre la galeria de
   fondo. El padding-top deja lugar al .auth-topbar fijo de arriba. */
.auth-left {
  position: relative;
  z-index: 1;
  flex: 1;
  max-width: min(58vw, 760px);
  padding: 130px clamp(24px, 3vw, 56px) 40px 0;
  display: flex;
  flex-direction: column;
  gap: clamp(28px, 3vw, 40px);
}

/* Mensaje principal + llamados a la accion — llevan al usuario a "Crear
   cuenta" (ver app.js), no generan nada todavia: eso requiere estar
   logueado, asi que el gancho es siempre el registro. Los tamaños usan
   clamp() para que crezcan en pantallas anchas en vez de quedar chicos y
   apretados a la izquierda con espacio vacio al costado. */
.auth-hero { display: flex; flex-direction: column; gap: 14px; }
.auth-hero-title { margin: 0; font-size: clamp(2.1rem, 3vw, 3.4rem); line-height: 1.22; font-weight: 700; color: var(--text); }
.auth-hero-prompt { display: flex; justify-content: center; }
.auth-hero-prompt input {
  width: 100%;
  padding: clamp(18px, 1.6vw, 26px) clamp(20px, 2vw, 30px);
  font-size: clamp(1.05rem, 1.2vw, 1.3rem);
  text-align: center;
  border-radius: 14px;
}
.auth-hero-submit {
  align-self: center;
  padding: clamp(14px, 1.2vw, 18px) clamp(32px, 3vw, 48px);
  font-size: clamp(1rem, 1.1vw, 1.15rem);
  margin: 4px 0 6px;
}
.auth-hero-ctas { display: flex; gap: 10px; }
.auth-hero-ctas .btn { flex: 1; font-size: clamp(0.95rem, 1vw, 1.05rem); padding: clamp(10px, 1vw, 14px) 16px; }
.auth-hero-note { margin: 0; color: var(--muted); font-size: clamp(0.8rem, 0.85vw, 0.95rem); }

.auth-benefits { display: flex; flex-direction: column; gap: clamp(24px, 2.5vw, 34px); }
.benefit { display: flex; gap: 16px; align-items: flex-start; }
.benefit-num { font-weight: 700; font-size: clamp(1.1rem, 1.1vw, 1.3rem); color: var(--accent); min-width: 34px; }
.benefit h3 { margin: 0 0 4px; font-size: clamp(1.15rem, 1.2vw, 1.4rem); font-weight: 600; color: var(--text); }
.benefit p { margin: 0; font-size: clamp(0.9rem, 0.95vw, 1.05rem); color: var(--muted); line-height: 1.55; max-width: 520px; }

/* Mosaico de ejemplos (imagenes/videos ya generados) debajo de los
   beneficios, como muestra de lo que se puede lograr. */
.auth-showcase-title { margin: 0 0 4px; font-size: clamp(1.15rem, 1.2vw, 1.4rem); font-weight: 600; color: var(--text); }
.auth-showcase {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-top: 6px;
  max-width: min(58vw, 640px);
}
.auth-showcase-item {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.auth-showcase-item:hover {
  transform: translateY(-3px) scale(1.03);
  box-shadow: 0 10px 24px rgba(99, 102, 241, 0.35);
  border-color: rgba(99, 102, 241, 0.5);
}
.auth-showcase-item img, .auth-showcase-item video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.auth-showcase-item { cursor: zoom-in; }

/* Lightbox: click en un ejemplo lo muestra ampliado, con controles reales
   si es video (el thumbnail va mudo/en loop, el ampliado no). */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(5, 8, 16, 0.9);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  cursor: zoom-out;
}
.lightbox-content { max-width: 90vw; max-height: 90vh; cursor: default; }
.lightbox-content img, .lightbox-content video {
  display: block;
  max-width: 90vw;
  max-height: 90vh;
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
}
.lightbox-close {
  position: absolute;
  top: 20px;
  right: 24px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: rgba(255, 255, 255, 0.08);
  color: white;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s ease;
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.2); }

@media (max-width: 900px) {
  /* Los beneficios y la galeria de ejemplos se ocultan (no hay lugar para
     dos columnas), pero el hero (mensaje + CTAs + boton de creditos
     gratis) se mantiene — son el gancho de conversion, importan mas en
     mobile que en desktop, no menos. */
  .auth-benefits { display: none; }
  .auth-view { justify-content: flex-start; padding: 24px; }
  .auth-left { max-width: 480px; padding: 130px 0 0; gap: 0; }
  .auth-hero-title { font-size: 1.6rem; text-align: center; }
  .auth-hero-ctas { flex-direction: column; }
  .auth-topbar { padding: 12px 16px; flex-wrap: wrap; row-gap: 10px; }
  .auth-topbar-brand { font-size: 1.1rem; }
  .auth-topbar-nav { width: 100%; justify-content: space-between; flex-wrap: wrap; row-gap: 8px; }
  .auth-topbar-free { font-size: 0.8rem; padding: 8px 14px; }
}
.auth-brand { text-align: center; margin-bottom: 20px; }
.auth-brand-tagline { color: var(--muted); font-size: 0.85rem; margin: 6px 0 0; }

.auth-card-brand {
  font-weight: 700;
  font-size: 1.5rem;
  background: linear-gradient(90deg, var(--text), var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* .tabs/.tab/.tab-panel: login/registro (ver switchAuthTab). .video-
   subtabs/.video-subtab/.video-subtab-panel: mismo look para "Efectos en
   Video" (Video a Video / Imagen a Video) pero con SU PROPIA clase — un
   listener global (`$$('.tab').forEach(...)`, ver switchAuthTab) escucha
   cualquier click en ".tab" en toda la pagina, asi que reusar esa clase
   ahi cerraba el modal de video-efecto por accidente (dos listeners
   pisandose entre si). */
.tabs, .video-subtabs { display: flex; gap: 8px; margin-bottom: 16px; }
.tab, .video-subtab {
  flex: 1;
  padding: 10px;
  background: var(--surface2);
  border: none;
  border-radius: var(--radius);
  color: var(--muted);
  cursor: pointer;
  font-weight: 600;
  transition: background 0.2s ease, color 0.2s ease;
}
.tab.active, .video-subtab.active { background: var(--accent); color: white; }
.tab-panel, .video-subtab-panel { display: none; flex-direction: column; gap: 8px; }
.tab-panel.active, .video-subtab-panel.active { display: flex; }

label { font-size: 0.85rem; color: var(--muted); margin-top: 6px; }
.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 0.85rem;
}
.checkbox-label input[type="checkbox"] { width: auto; margin: 0; }
.checkbox-label a { color: var(--accent); }
input, textarea {
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
  width: 100%;
}
input:focus, textarea:focus { outline: 2px solid var(--accent); }

.btn { border: none; border-radius: 8px; padding: 10px 16px; font-weight: 600; cursor: pointer; font-size: 0.95rem; transition: box-shadow 0.25s ease, transform 0.15s ease, background 0.2s ease; }
.btn-primary { background: var(--accent); color: white; margin-top: 10px; }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); box-shadow: 0 0 20px rgba(99, 102, 241, 0.5); transform: translateY(-1px); }
.btn-primary:disabled { opacity: 0.6; cursor: default; }
.btn-ghost { background: transparent; border: 1px solid var(--border); color: var(--text); }

.form-error { color: var(--danger); font-size: 0.85rem; min-height: 1.2em; }
.form-hint {
  background: rgba(99, 102, 241, 0.12);
  border: 1px solid rgba(99, 102, 241, 0.35);
  color: var(--text);
  border-radius: 8px;
  padding: 10px 12px;
  font-size: 0.85rem;
  margin: 0 0 4px;
}

/* Paquetes de creditos */
.value-prop { color: var(--muted); font-size: 0.85rem; margin: -6px 0 14px; }
.packages { display: flex; flex-direction: column; gap: 10px; }
.package-btn {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  color: var(--text);
  cursor: pointer;
  font-size: 0.9rem;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.15s ease;
}
.package-btn:hover { border-color: var(--accent); box-shadow: 0 0 16px rgba(99, 102, 241, 0.25); transform: translateY(-1px); }
.package-btn span { color: var(--muted); }
.package-btn-popular { border-color: var(--accent); box-shadow: 0 0 14px rgba(99, 102, 241, 0.2); }
.popular-badge {
  position: absolute;
  top: -9px;
  left: 14px;
  background: var(--accent);
  color: white;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
}

/* Formulario de generacion (Generador de Imagenes / Generador de Videos,
   cada uno en su propia vista del dashboard — ver .dashboard-subview) */
#imageGenerateForm, #videoGenerateForm { display: flex; flex-direction: column; gap: 6px; }

/* Selector de modelo: lista de tarjetas clickeables (mismo patron visual
   que .package-btn de la pagina de precios), una por modelo del catalogo
   (GET /generate/models), mostrando su costo en creditos antes de generar. */
.model-options { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 4px; }
/* Generador de Imagenes tiene 4 modelos: se acomodan en 2x2 en vez de una
   sola columna larga. Generador de Videos tiene 3: auto-fit en vez de un
   2x2 fijo, para no dejar un hueco vacio en la segunda fila. */
#imageModelOptions.model-options { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 900px) {
  #imageModelOptions.model-options { grid-template-columns: 1fr; }
}
#videoModelOptions.model-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.model-option {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.model-option:hover { border-color: rgba(99, 102, 241, 0.5); }
.model-option.selected { border-color: var(--accent); box-shadow: 0 0 14px rgba(99, 102, 241, 0.25); }
/* Ejemplo real generado con el modelo (ver app/models_catalog.py), a la
   izquierda de cada tarjeta. Kontext (edicion pura) muestra un par
   antes/despues en vez de una sola imagen. Reducido a 100px (desde 224px)
   al pasar la grilla de modelos a 2x2: con el thumb grande las dos columnas
   quedaban de ancho desparejo y el texto se apretaba. */
.model-option-thumb { flex-shrink: 0; width: 100px; height: 100px; border-radius: 10px; overflow: hidden; }
.model-option-thumb img, .model-option-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.model-option-thumb-pair { display: flex; gap: 4px; width: 172px; }
.model-option-thumb-pair img { width: 50%; border-radius: 10px; }

/* Ampliacion flotante al dejar el cursor 3s quieto sobre una imagen o
   video-ejemplo (ver attachThumbZoomHandlers en app.js) — deja ver el
   detalle real del modelo sin tener que agrandar el thumb fijo en la
   tarjeta. Contiene un <img> y un <video>, se muestra el que corresponda. */
.model-thumb-zoom {
  position: fixed;
  z-index: 200;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 0.18s ease, transform 0.18s ease;
  border-radius: 14px;
  overflow: hidden;
  border: 2px solid var(--accent);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55);
  background: var(--surface2);
}
.model-thumb-zoom.visible { opacity: 1; transform: scale(1); }
.model-thumb-zoom img, .model-thumb-zoom video { display: block; width: 380px; height: 380px; object-fit: cover; }

.model-option-body { flex: 1; min-width: 0; }
.model-option-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.model-option-label { font-weight: 600; font-size: 0.9rem; }
.model-option-credits { color: var(--accent); font-weight: 600; font-size: 0.8rem; white-space: nowrap; }
.model-option-desc { margin: 4px 0 0; color: var(--muted); font-size: 0.8rem; line-height: 1.4; }
.model-option-tag {
  display: inline-block;
  margin-top: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(239, 68, 68, 0.12);
  color: #fca5a5;
  font-size: 0.7rem;
  font-weight: 600;
}

/* Inicio: 4 accesos directos a las secciones principales, debajo de
   Inspirate. Mismos iconos que el sidebar (ver index.html) para reforzar
   que llevan al mismo lugar. */
.nav-cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin-bottom: 20px; }
.nav-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  text-align: left;
  background: rgba(30, 41, 59, 0.65);
  border: 1px solid rgba(51, 65, 85, 0.7);
  border-radius: var(--radius);
  padding: 20px;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  cursor: pointer;
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.nav-card:hover { border-color: rgba(99, 102, 241, 0.5); transform: translateY(-3px); }
.nav-card svg {
  width: 26px;
  height: 26px;
  color: var(--accent);
  padding: 8px;
  border-radius: 8px;
  background: rgba(99, 102, 241, 0.15);
}
.nav-card h3 { margin: 4px 0 0; font-size: 0.95rem; color: var(--text); }
.nav-card p { margin: 0; color: var(--muted); font-size: 0.8rem; line-height: 1.4; }

/* Explora: mosaico de ejemplos (galeria + resultados de efectos), reusa el
   patron visual del showcase de la pantalla de login. */
.explore-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }
.explore-item {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: transform 0.2s ease;
}
.explore-item:hover { transform: translateY(-3px); }
.explore-item img, .explore-item video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Tarjetas conectadas a un efecto/modelo real (ver data-explore-kind en
   app.js) — click lleva directo a usarlo. Los items sin origen rastreable
   (galeria generica) quedan sin esta clase: mismo look, no clickeables. */
.explore-item-clickable { cursor: pointer; }
.explore-item-clickable:hover { border-color: var(--accent); }
.explore-item-clickable span {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 8px 10px;
  background: linear-gradient(0deg, rgba(15, 23, 42, 0.9), transparent);
  color: white;
  font-size: 0.78rem;
  font-weight: 600;
}

/* Efectos en Imagen: grilla de tarjetas (una por efecto, ver GET /effects),
   cada una con un par antes/despues de ejemplo generado con el mismo
   pipeline (no son fotos de personas reales). */
.effects-intro { color: var(--muted); font-size: 0.9rem; margin: -6px 0 16px; }
.effects-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.effect-card {
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: border-color 0.2s ease;
}
.effect-card:hover { border-color: rgba(99, 102, 241, 0.4); }
.effect-card h3 { margin: 0; font-size: 0.95rem; }
.effect-card-desc { margin: 0; color: var(--muted); font-size: 0.78rem; line-height: 1.4; flex: 1; }
.effect-example { display: flex; gap: 6px; }
.effect-example-item { position: relative; flex: 1; aspect-ratio: 1 / 1; border-radius: 6px; overflow: hidden; }
.effect-example-item img, .effect-example-item video { width: 100%; height: 100%; object-fit: cover; display: block; }
.effect-example-item span {
  position: absolute;
  left: 4px;
  bottom: 4px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.75);
  color: white;
  font-size: 0.65rem;
  font-weight: 600;
}
/* Placeholder cuando falta el video-ejemplo de un efecto (ver
   videoEffectExampleHtml en app.js) — el efecto funciona igual, solo no
   tiene todavia el antes/despues real generado. */
.effect-example-pending {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface2);
  border: 1px dashed var(--border);
}
.effect-example-pending-text { font-size: 0.68rem; color: var(--muted); text-align: center; padding: 0 6px; }

.effect-use-btn { width: 100%; font-size: 0.85rem; }

.effect-how-to { color: var(--muted); font-size: 0.88rem; line-height: 1.5; margin: 0; }
#effectApplyForm { display: flex; flex-direction: column; }

/* Panel de "aplicar efecto": header con icono + titulo + cerrar, y el form
   dividido en secciones rotuladas (Imagen, Opciones...) en vez de labels
   sueltos — mismo lenguaje visual que el resto del panel (glass cards) pero
   con mas jerarquia. */
.effect-apply-card { padding: 22px 24px; }

/* Modal centrado para "aplicar efecto": antes el usuario tenia que hacer
   click en "Ver mas estilos" y despues scrollear hasta el fondo de la
   pagina para recien ahi ver las opciones — ahora aparece como overlay
   centrado en el viewport, mostrando todos los estilos de una sola vez sin
   moverse de donde ya estaba mirando la grilla de efectos. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 11, 20, 0.72);
  backdrop-filter: blur(2px);
  z-index: 200;
}
body.modal-open { overflow: hidden; }
.effect-apply-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(720px, 92vw);
  max-height: 88vh;
  overflow-y: auto;
  z-index: 201;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
@media (max-width: 640px) {
  .effect-apply-modal { width: 100vw; max-height: 100vh; height: 100vh; top: 0; left: 0; transform: none; border-radius: 0; }
}
.effect-apply-header {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: -4px 0 20px;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(51, 65, 85, 0.6);
}
.effect-apply-header > div { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.effect-apply-header h2 { margin: 0; }
.effect-apply-icon {
  width: 42px;
  height: 42px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(99, 102, 241, 0.3), rgba(168, 85, 247, 0.18));
}
.effect-apply-close {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface2);
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s ease, color 0.2s ease;
}
.effect-apply-close:hover { background: var(--border); color: var(--text); }

.effect-apply-section { margin-bottom: 20px; }
.effect-apply-section-label {
  display: block;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0 0 8px;
}
#effectParamsContainer label.effect-apply-section-label:not(:first-child) { margin-top: 14px; }

/* Zona de subida de archivo: reemplaza el input[type=file] nativo (que se
   veia con el estilo por defecto del navegador, sin coherencia visual con
   el resto). El <input> real queda invisible y estirado sobre toda la
   zona (position:absolute + opacity:0) para que siga siendo clickeable y
   accesible por teclado; el drag&drop se maneja aparte en app.js. */
.upload-dropzone {
  position: relative;
  border: 2px dashed rgba(148, 163, 184, 0.35);
  border-radius: 12px;
  padding: 20px;
  text-align: center;
  background: rgba(15, 23, 42, 0.3);
  transition: border-color 0.2s ease, background 0.2s ease;
}
.upload-dropzone:hover, .upload-dropzone.dragover {
  border-color: var(--accent);
  background: rgba(99, 102, 241, 0.08);
}
.upload-dropzone-input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.upload-dropzone-empty { display: flex; flex-direction: column; align-items: center; gap: 4px; pointer-events: none; }
.upload-dropzone-empty svg { width: 26px; height: 26px; color: var(--accent); margin-bottom: 4px; }
.upload-dropzone-empty p { margin: 0; font-size: 0.88rem; color: var(--text); }
.upload-dropzone-empty span { font-size: 0.74rem; color: var(--muted); }
.upload-dropzone-preview { display: flex; align-items: center; gap: 12px; text-align: left; pointer-events: none; }
.upload-dropzone-preview img {
  width: 52px;
  height: 52px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
  border: 1px solid var(--border);
}
/* El preview de video tiene controles nativos (el usuario necesita poder
   reproducirlo para chequear que subio el clip correcto) — por eso, a
   diferencia del preview de imagen, recupera pointer-events pese a que el
   contenedor los desactiva. */
.upload-dropzone-preview video {
  width: 120px;
  height: 68px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
  border: 1px solid var(--border);
  pointer-events: auto;
}
.upload-dropzone-preview-info { min-width: 0; }
.upload-dropzone-filename {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.upload-dropzone-change { font-size: 0.76rem; color: var(--accent); }

.effect-apply-submit { width: 100%; padding: 13px; font-size: 0.98rem; margin-top: 2px; }

/* Tarjetas seleccionables con imagen/color/icono ilustrativo, reemplazan
   los <select> nativos en los parametros de cada efecto (ver
   renderSwatchVisual en app.js). auto-fill + minmax deja que los grupos
   con pocas opciones (ej. 2 fondos) se vean grandes y los que tienen mas
   (ej. 8 estilos) se acomoden en varias columnas sin desbordar. */
.option-swatch-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
.option-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px;
  background: var(--surface2);
  border: 2px solid transparent;
  border-radius: 12px;
  cursor: pointer;
  transition: border-color 0.2s ease, transform 0.15s ease, background 0.2s ease;
}
.option-swatch:hover { transform: translateY(-2px); }
.option-swatch.selected { border-color: var(--accent); background: rgba(99, 102, 241, 0.14); }
/* Duplicado a proposito (antes 56px): las miniaturas generadas quedaban
   muy chicas para distinguir el estilo/color de un vistazo. */
.option-swatch-visual { width: 112px; height: 112px; border-radius: 10px; object-fit: cover; display: block; }
.option-swatch-color { border: 1px solid rgba(255, 255, 255, 0.25); }
.option-swatch-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(99, 102, 241, 0.14);
  color: var(--accent);
}
.option-swatch-icon svg { width: 48px; height: 48px; }
.option-swatch-label { font-size: 0.78rem; text-align: center; color: var(--muted); line-height: 1.25; }
.option-swatch.selected .option-swatch-label { color: var(--text); font-weight: 600; }
/* Opcional: solo algunos efectos (ej. Retocar) traen "description" por
   opcion — se omite por completo si el efecto no la define. */
.option-swatch-desc { font-size: 0.7rem; text-align: center; color: var(--muted); line-height: 1.3; opacity: 0.85; }

/* Canvas de mascara ("Eliminar Personas/Objetos"): el usuario pinta encima
   de la foto para marcar que borrar. cursor:crosshair da la pista visual de
   que es un area para dibujar, no una imagen estatica; touch-action:none
   evita que el navegador scrollee la pagina mientras se pinta con el dedo. */
.mask-canvas-wrap {
  margin: 0 0 8px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface2);
  line-height: 0;
}
#effectMaskCanvas { display: block; width: 100%; height: auto; cursor: crosshair; touch-action: none; }
.mask-controls { display: flex; align-items: center; gap: 10px; }
.mask-brush-label { margin: 0; white-space: nowrap; }
#effectBrushSize { flex: 1; }

.active-job {
  margin-top: 16px;
  padding: 12px;
  background: var(--surface2);
  border-radius: 8px;
  font-size: 0.9rem;
}

.spinner-row { display: flex; align-items: center; gap: 10px; }
.spinner-row p { margin: 0; }
.spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
  flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.4s; }
}

/* Historial */
.history-header { display: flex; justify-content: space-between; align-items: center; }
.history { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.history-item {
  display: flex;
  gap: 12px;
  background: var(--surface2);
  border-radius: 8px;
  padding: 10px;
  animation: item-in 0.4s ease both;
}
@keyframes item-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .history-item { animation: none; }
}
.thumb { width: 90px; height: 90px; object-fit: cover; border-radius: 6px; background: #000; flex-shrink: 0; }
.history-item-body { flex: 1; min-width: 0; }
.job-prompt { margin: 4px 0; font-size: 0.9rem; word-break: break-word; }
.job-meta { color: var(--muted); font-size: 0.8rem; margin: 0; }
.job-error { color: var(--danger); font-size: 0.85rem; }
.job-expired { color: var(--muted); font-size: 0.85rem; font-style: italic; }
.empty { color: var(--muted); }

.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 0.75rem; font-weight: 600; }
.badge-queued, .badge-in_progress { background: rgba(99, 102, 241, 0.2); color: #a5b4fc; }
.badge-completed { background: rgba(34, 197, 94, 0.2); color: var(--success); }
.badge-failed { background: rgba(239, 68, 68, 0.2); color: var(--danger); }

.job-actions { display: flex; gap: 8px; margin-top: 8px; }
.btn-small {
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 0.8rem;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}
.btn-small:hover { background: var(--surface2); }
.btn-danger { color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: rgba(239, 68, 68, 0.1); }

/* ---------- Pagina de precios ---------- */
.pricing-main { max-width: 1000px; margin: 0 auto; padding: 130px 24px 80px; position: relative; z-index: 1; }

.pricing-hero { text-align: center; max-width: 640px; margin: 0 auto 56px; }
.pricing-hero h1 { font-size: 2.3rem; font-weight: 700; line-height: 1.3; margin: 0 0 16px; color: var(--text); }
.pricing-hero-accent {
  background: linear-gradient(90deg, var(--accent), #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.pricing-hero p { color: var(--muted); font-size: 1.05rem; margin: 0; }

.pricing-plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 20px; margin-bottom: 32px; }
.pricing-loading { grid-column: 1 / -1; text-align: center; color: var(--muted); }

.payment-methods { text-align: center; max-width: 680px; margin: 0 auto 72px; }
.payment-methods-label { color: var(--muted); font-size: 0.9rem; margin: 0 0 16px; }
.payment-methods-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.payment-method {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(30, 41, 59, 0.55);
  border: 1px solid rgba(51, 65, 85, 0.7);
  border-radius: 999px;
  padding: 10px 18px;
  font-size: 0.88rem;
  color: var(--text);
}
.payment-method-featured { border-color: var(--accent); box-shadow: 0 0 16px rgba(99, 102, 241, 0.2); }
.payment-method-icon { display: flex; width: 18px; height: 18px; color: var(--accent); flex-shrink: 0; }
.payment-method-icon svg { width: 100%; height: 100%; }
.pricing-plan {
  position: relative;
  text-align: center;
  background: rgba(30, 41, 59, 0.65);
  border: 1px solid rgba(51, 65, 85, 0.7);
  border-radius: var(--radius);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  padding: 28px 20px;
  transition: border-color 0.25s ease, transform 0.2s ease;
}
.pricing-plan:hover { transform: translateY(-4px); border-color: rgba(99, 102, 241, 0.35); }
.pricing-plan-popular { border-color: var(--accent); box-shadow: 0 0 24px rgba(99, 102, 241, 0.25); }
.pricing-plan h3 { margin: 8px 0 18px; font-size: 0.9rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; }
.pricing-plan-price { font-size: 2.1rem; font-weight: 700; color: var(--text); }
.pricing-plan-credits { color: var(--accent); font-weight: 600; font-size: 0.9rem; margin: 4px 0 22px; }
.pricing-plan-btn { width: 100%; text-decoration: none; display: block; box-sizing: border-box; }

.pricing-faq { display: flex; flex-direction: column; gap: 30px; max-width: 680px; margin: 0 auto 80px; }

.pricing-cta { text-align: center; }
.pricing-cta h2 { font-size: 1.6rem; margin: 0 0 22px; color: var(--text); }
.pricing-cta-btn { display: inline-block; padding: 16px 40px; font-size: 1.05rem; text-decoration: none; }

.app-footer-credit { position: relative; z-index: 1; text-align: center; color: var(--muted); font-size: 0.8rem; margin: 40px 0 12px; }
