:root {
  --bg: #0F2440;
  --bg-glow: rgba(58, 168, 173, 0.20);
  --dot-color: rgba(255, 255, 255, 0.035);
  --surface: rgba(255, 255, 255, 0.06);
  --surface-2: rgba(255, 255, 255, 0.10);
  --surface-solid: #273A53;
  --border: rgba(255, 255, 255, 0.14);
  --border-strong: rgba(255, 255, 255, 0.26);
  --text: #FFFFFF;
  --text-secondary: rgba(255, 255, 255, 0.72);
  --text-muted: rgba(255, 255, 255, 0.50);
  /* accent-start: extraído por muestreo real de logo-ticket-loop.png /
     icono-ticket-loop.png (promedio de píxeles teal saturados en ambos
     archivos), no una aproximación a ojo. accent-end: ya no es el naranja
     muestreado del logo -- se ajustó a mano a pedido (#FF8C00 -> #FF9647
     -> #FFB300 -> #FF9E00). */
  --accent-start: #339689;
  --accent-end: #FF9E00;
  /* Antes era un degradé verde-naranja (accent-start -> accent-end); ahora
     es sólido, el mismo naranja de accent-end. Se deja el nombre para no
     tocar los ~15 lugares que lo consumen. Los estados hover/disabled de
     todo lo que usa este color son un opacity sobre este mismo valor
     (ver .btn-primary:hover, .btn:disabled), no un tono aparte -- se
     ajustan solos, no hace falta tocarlos. */
  --accent-gradient: var(--accent-end);
  --accent: var(--accent-start);
  --accent-soft: rgba(51, 150, 137, 0.18);
  /* Texto/ícono sobre fondos accent-gradient (botones, chips, banner de
     éxito, etc.): un azul oscuro, no blanco, porque accent-end ya es un
     naranja bastante claro (contraste ~8.4:1 con #FF9E00, de sobra sobre
     el mínimo de 4.5:1). Ya era así antes de este cambio de tono. */
  --on-accent: #0B1B30;
  --success: #3FCB82;
  --success-soft: rgba(94, 140, 255, 0.18);
  --warning: #FF8A3D;
  --warning-soft: rgba(255, 138, 61, 0.18);
  --danger: #F1616B;
  --danger-soft: rgba(241, 97, 107, 0.16);
  /* Rojo coral más fuerte que --danger, pedido puntual para "Cancelar
     reserva" en purchase_detail.html -- no reemplaza a --danger en el
     resto del sitio (textos de error, badges), que sigue con su tono. */
  --danger-strong: #E5484D;
  /* Azul "comprador", exclusivo del camino vendedor/comprador de
     how_it_works.html -- no se usa en ningún otro lado del sitio, que es
     naranja/teal de punta a punta. Es intencional: separa visualmente el
     rol de comprador (azul) del de vendedor (naranja de marca) en esa
     única pantalla. */
  --buyer-color: #4F8FE0;
  --radius: 10px;
  --radius-lg: 16px;
  /* Montserrat (Google Fonts, cargada en app_base.html) para absolutamente
     todo el sitio -- login, registro, Mis Tickets, panel, checkout,
     footer, lo que sea, ya que --sans es el font-family de <body> y todo
     lo hereda salvo que algo lo pise explícitamente. Solo estas cosas lo
     pisan y se quedan con la tipografía de impacto que ya tenían (ver
     --display-font/Avega Italic más abajo): .section-title (Destacados,
     Próximos eventos) y .all-events-title (Ver todos los eventos). El
     stack de sistema queda de fallback nada más, por si Montserrat no
     llegara a cargar. */
  --sans: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  /* Fuente de marca de .section-title (Destacados, Próximos eventos),
     Google Fonts, cargada en app_base.html. NO es la misma que
     .all-events-title (ver 'Avega Italic' más abajo): son dos fuentes de
     impacto distintas, cada una en su propio lugar. */
  --display-font: 'Anton', var(--sans);
}
/* 'Avega Italic': la fuente original de "Ver todos los eventos" (ver
   commit 7089c8b), exclusiva de .all-events-title -- no la usa nada más
   del sitio. Se había sacado por error al sumar Anton (--display-font)
   para otros títulos, dando a entender que era la misma fuente que se
   reemplazaba; no lo eran, son dos fuentes de impacto distintas que
   convivían. Se restaura desde el historial de git (mismo archivo
   .ttf). */
@font-face {
  font-family: 'Avega Italic';
  src: url("../fonts/Avega-Italic.4cbd7bd1fb6d.ttf") format('truetype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--text); font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}
.app {
  max-width: 480px; margin: 0 auto; min-height: 100vh; position: relative;
  /* Deja lugar de sobra para que .bottom-nav (fija, presente en todas las
     pantallas) no tape el final del contenido. */
  padding-bottom: 82px;
  background-color: var(--bg);
  background-image:
    radial-gradient(ellipse 120% 60% at 50% 100%, rgba(0, 0, 0, 0.45), transparent 100%),
    radial-gradient(circle at 1px 1px, var(--dot-color) 1px, transparent 1.5px),
    radial-gradient(ellipse 900px 560px at 50% 20%, var(--bg-glow), transparent 70%);
  background-repeat: no-repeat, repeat, no-repeat;
  background-size: 100% 100%, 16px 16px, 100% 100%;
}

/* Header: logo + tagline alineados a la izquierda. Panel (admin) va
   aparte, arriba a la derecha (ver .header-corner) -- position:
   sticky también sirve de contenedor para ese position:absolute. Mis
   tickets/Perfil/Notificaciones ya no viven acá: están en la barra de
   navegación inferior (ver .bottom-nav, más abajo). */
.header {
  display: flex; align-items: center; justify-content: flex-start; gap: 10px; padding: 10px 16px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  position: sticky; top: 0; z-index: 20;
}
/* Sin sesión iniciada, a la derecha van Ingresar/Registrarme. Logo +
   tagline siguen uno al lado del otro sin ocultar nada (segundo intento:
   ocultar el tagline en mobile no era lo que se quería) -- lo que se
   achica en pantallas chicas es el tamaño de estos elementos y el
   espaciado entre ellos, mobile-first como el resto del sitio, para que
   todo entre en un solo renglón (logo, tagline e Ingresar/Registrarme);
   vuelven a su tamaño de siempre a partir de 768px, donde ya sobra
   lugar. flex-shrink: 0 en .logo-block es clave: sin eso, flexbox lo
   achica por debajo de lo que mide su contenido real y el tagline
   (nowrap, no se achica solo) queda pintado afuera de su propia caja,
   superpuesto con Ingresar/Registrarme en vez de ceder lugar de verdad. */
.header--guest .logo-block { gap: 5px; flex-shrink: 0; }
.header--guest .logo-img { height: 22px; }
.header--guest .logo-divider { height: 16px; }
.header--guest .logo-tagline { font-size: 6.5px; letter-spacing: 0; }
.header--guest .header-guest-actions { gap: 6px; }
.header--guest .header-auth-link { font-size: 10px; }
.header--guest .header-auth-link-cta { padding: 3px 9px; }
@media (min-width: 768px) {
  .header--guest .logo-block { gap: 10px; }
  .header--guest .logo-img { height: 34px; }
  .header--guest .logo-divider { height: 26px; }
  .header--guest .logo-tagline { font-size: 9.5px; letter-spacing: 0.01em; }
  .header--guest .header-guest-actions { gap: 14px; }
  .header--guest .header-auth-link { font-size: 12.5px; }
  .header--guest .header-auth-link-cta { padding: 5px 12px; }
}

.logo-block { display: flex; align-items: center; gap: 10px; text-decoration: none; min-width: 0; }
.logo-img { height: 34px; width: auto; display: block; flex-shrink: 0; }
.logo-divider { width: 1px; height: 26px; background: var(--border-strong); flex-shrink: 0; }
.logo-tagline {
  font-family: var(--sans); font-weight: 700; text-transform: uppercase;
  font-size: 9.5px; line-height: 1.35; letter-spacing: 0.01em; color: var(--text-secondary);
  white-space: nowrap;
}
.logo-tagline-line { display: block; }

.header-guest-actions { display: flex; align-items: center; gap: 14px; margin-left: auto; flex-shrink: 0; }
.header-auth-link { font-weight: 700; font-size: 12.5px; color: #fff; text-decoration: none; white-space: nowrap; }
/* "Registrarme" es el único header-auth-link con más peso que "Ingresar":
   una píldora naranja de marca en vez de texto plano, para invitar más a
   la acción. Mismo color de texto que el resto de los fondos
   accent-gradient (btn-primary, badges, etc.), no blanco -- de sobra de
   contraste igual (ver comentario de --on-accent). */
.header-auth-link-cta {
  background: var(--accent-gradient); color: var(--on-accent); font-weight: 700;
  padding: 5px 12px; border-radius: 999px;
}
.header-corner { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); }

/* Accesos con ícono en cuadrado de bordes redondeados + label debajo:
   Panel (header, arriba a la derecha) y los de la barra de navegación
   inferior (Inicio, Mis tickets, Perfil, Notificaciones). El ítem activo
   se resuelve en el template comparando request.resolver_match.url_name,
   no hace falta pasar nada especial desde cada vista. */
.nav-item {
  display: flex; flex-direction: column; align-items: center; gap: 2px; flex-shrink: 0;
  text-decoration: none; color: var(--text-secondary); cursor: pointer;
  background: none; border: none; padding: 0; font-family: inherit;
}
.nav-icon {
  width: 32px; height: 32px; border-radius: 9px; display: flex; align-items: center; justify-content: center;
  font-size: 15px; border: 1.5px solid var(--border-strong); background: var(--surface); position: relative;
}
.nav-label { font-size: 9px; font-weight: 700; }
.nav-item.active { color: var(--accent-end); }
.nav-item.active .nav-icon { border-color: var(--accent-end); }
.notif-dot {
  position: absolute; top: -2px; right: -2px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger); border: 1.5px solid var(--surface);
}

/* Desplegable de notificaciones: vive en la barra de navegación inferior
   (ver .bottom-nav), así que se abre hacia arriba (bottom: 100%) -- si
   abriera hacia abajo como cuando estaba en el header, quedaría afuera
   de la pantalla. */
.notif-wrap { position: relative; }
.notif-dropdown {
  display: none; position: absolute; bottom: 100%; right: 0; margin-bottom: 10px;
  width: min(280px, calc(100vw - 32px)); max-height: 360px; overflow-y: auto;
  background: var(--surface-solid); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: 0 -10px 30px rgba(0, 0, 0, .4); z-index: 30;
}
.notif-dropdown.open { display: block; }
.notif-dropdown-title { font-size: 12.5px; font-weight: 700; color: var(--text); margin: 0; padding: 12px 14px 8px; }
.notif-item { display: block; padding: 10px 14px; text-decoration: none; border-top: 1px solid var(--border); }
.notif-item:hover { background: var(--surface-2); }
.notif-item-unread { background: var(--accent-soft); }
.notif-item-unread .notif-text { font-weight: 600; }
.notif-text { font-size: 12.5px; color: var(--text); margin: 0; line-height: 1.4; }
.notif-date { font-size: 11px; color: var(--text-muted); margin: 4px 0 0; }
.notif-empty { padding: 6px 14px 14px; margin: 0; }

.screen { padding: 16px; position: relative; }

/* Mensajes globales (Django messages) */
.app-messages { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.app-message { font-size: 13px; padding: 10px 14px; border-radius: var(--radius); border: 1px solid var(--border); background: var(--surface); color: var(--text); }
.app-message-success { background: var(--success-soft); border-color: rgba(63, 203, 130, 0.4); }
.app-message-error { background: var(--danger-soft); border-color: rgba(241, 97, 107, 0.4); }
.app-message-warning { background: var(--warning-soft); border-color: rgba(255, 138, 61, 0.4); }
.app-message-info, .app-message-debug { background: var(--accent-soft); border-color: rgba(51, 150, 137, 0.4); }

/* Pie de página: mismo en toda la app (vive en app_base.html, no en cada
   pantalla). Datos de contacto todavía placeholder -- ver comentario en
   el template. */
.app-footer {
  margin-top: 8px; padding: 20px 16px 24px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
}
.app-footer-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; }
.app-footer-link { font-size: 12px; color: var(--text-secondary); text-decoration: none; }
.app-footer-link:hover { color: var(--text); }
.app-footer-copy { font-size: 11px; color: var(--text-muted); margin: 4px 0 0; }

/* Home search */
.search-bar { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; font-size: 13px; color: var(--text-muted); margin-bottom: 18px; display: flex; align-items: center; gap: 8px; }
.search-bar input { border: none; background: none; outline: none; font-size: 13px; color: var(--text); flex: 1; font-family: inherit; }
.search-bar input::placeholder { color: var(--text-muted); }

/* Fila del buscador + Publicar entrada (Home): apilados en mobile,
   lado a lado a partir de 768px (mismo corte que el resto del sitio). */
.home-search-row { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.home-search-row .search-bar { margin-bottom: 0; }
.home-publish-btn { height: 44px; font-size: 14px; white-space: nowrap; }

@media (min-width: 768px) {
  .home-search-row { flex-direction: row; align-items: stretch; }
  .home-search-row .search-bar { flex: 2; }
  .home-publish-btn { flex: 1; }
}
/* Misma tipografía de impacto que .all-events-title (Anton solo tiene un
   peso -- ya es bien grueso de por sí, no hace falta font-weight: 700,
   que acá se vería como un bold sintético del navegador, inconsistente
   con el resto de la marca). */
.section-title {
  font-family: var(--display-font); font-weight: 400; text-transform: uppercase;
  font-size: 19px; letter-spacing: 0.01em; margin: 0 0 10px; color: var(--text);
}

/* Destacados: carrusel deslizante continuo (scroll horizontal con snap),
   de a una tarjeta por vez, en vez de páginas fijas de a 4 — así nunca
   queda un grupo incompleto con espacio vacío al final. */
.featured-carousel {
  display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-behavior: smooth; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.featured-carousel::-webkit-scrollbar { display: none; }
.featured-card {
  /* 46% + .featured-img a 145px de alto (en vez de 78px) para que el
     aspect ratio quede parecido al de tablet/desktop (.featured-img a
     140-200px con la card mucho más ancha en proporción) -- antes en
     mobile se recortaba bastante más que en PC para la misma imagen, así
     que ajustar el foco (Event.image_focal_y) desde el admin mirando la
     preview de PC no quedaba bien en el celular, y viceversa. */
  flex: 0 0 auto; width: 46%; scroll-snap-align: start;
  border-radius: 12px; overflow: hidden; border: 1px solid var(--border); text-decoration: none; display: block;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.featured-card:hover {
  transform: scale(1.035); box-shadow: 0 8px 20px rgba(0, 0, 0, .3); border-color: var(--border-strong);
}
.featured-img {
  position: relative;
  height: 145px; display: flex; align-items: center; justify-content: center; font-size: 22px; background-size: cover;
  /* Fallback nada más: con imagen, el template pisa esto con
     Event.image_focal_y en un style inline (0-100, default 30 -- mismo
     valor que este fallback), para que el organizador pueda subir el
     foco si el recorte por default corta el nombre del DJ/evento en el
     flyer. Sin imagen (ícono de color playo) no aplica. */
  background-position: center 30%;
  /* Fondo neutro de base: bg-{{ event.color }} (el color según categoría
     del evento) solo se aplica en el template cuando NO hay imagen -- si
     el flyer tiene alguna zona transparente (PNG), antes se filtraba ese
     color de categoría ahí y quedaba un rectángulo raro superpuesto. Con
     imagen, este gris/azul neutro de tarjeta es lo que se ve en esas
     zonas transparentes en vez de eso. */
  background-color: var(--surface-solid);
}
/* min-height reservando siempre 2 líneas de nombre (aunque el evento
   tenga uno solo): .featured-carousel es flex con el align-items:stretch
   por default, así que una card con nombre de una sola línea quedaba
   más baja que la de al lado con nombre de dos líneas -- se estiraba
   igual (stretch), pero .featured-card no tiene background propio, así
   que ese espacio de más quedaba transparente (se veía el fondo de la
   página). line-clamp trunca si un nombre fuera excepcionalmente largo,
   para que el alto de acá sea de verdad fijo, no solo un mínimo. */
.featured-info { padding: 8px 10px; background: var(--surface); min-height: 66px; }
.featured-info .name {
  font-size: 12.5px; font-weight: 700; margin: 0; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.featured-info .meta { font-size: 11px; color: var(--text-secondary); margin: 2px 0 0; }

/* Badge de disponibilidad (cantidad de entradas) en Próximos eventos del
   Home -- mismo .badge/.badge-success que ya usa "Mejor precio" en el
   detalle de evento. Apilado bajo el precio, ver .upcoming-price-col.
   No va en Destacados: sobre la imagen competía mal con el badge de
   fecha y quedaba muy apretado en una card angosta. */
.availability-badge { font-size: 10px; padding: 2px 7px; }

/* Badge de fecha superpuesto en la esquina superior izquierda de la
   imagen del evento (ver templates/_date_badge.html) -- solo en
   Destacados, donde la imagen tiene lugar de sobra; reemplaza al texto
   de fecha que antes iba en .meta junto al venue ahí, no se duplica. En
   Próximos eventos del Home la miniatura es muy chica para que se lea
   bien, así que ahí se mantuvo el texto de fecha de siempre. date-badge-sm
   (la versión reducida) sigue en pie para el catálogo ("Todos los
   eventos"), cuyo ícono es bastante más grande (60-100px). */
.date-badge {
  position: absolute; top: 6px; left: 6px; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: rgba(11, 27, 48, 0.78); border-radius: 8px; padding: 4px 7px; line-height: 1.05;
}
.date-badge-day { font-size: 15px; font-weight: 800; color: var(--text); }
.date-badge-month { font-size: 9px; font-weight: 700; color: var(--accent-end); text-transform: uppercase; letter-spacing: 0.02em; margin-top: 1px; }
.date-badge-sm { top: 3px; left: 3px; padding: 2px 4px; border-radius: 5px; }
.date-badge-sm .date-badge-day { font-size: 9.5px; }
.date-badge-sm .date-badge-month { font-size: 5.5px; margin-top: 0; }

.carousel-dots { display: flex; justify-content: center; align-items: center; gap: 7px; margin: 12px 0 22px; }
.carousel-dots .dot { width: 7px; height: 7px; border-radius: 4px; background: var(--border-strong); border: none; padding: 0; cursor: pointer; transition: width .18s ease, background .18s ease; }
.carousel-dots .dot.active { width: 20px; background: var(--accent-gradient); }

/* Proximos eventos */
.upcoming-row {
  display: flex; align-items: center; gap: 12px; border: 1px solid var(--border); border-radius: var(--radius);
  padding: 10px 12px; margin-bottom: 8px; background: var(--surface); text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.upcoming-row:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, .28); border-color: var(--border-strong); }
/* Card destacada "Ver todos los eventos": el título es el protagonista,
   centrado y grande, no una fila más de la lista. */
.all-events-card {
  container-type: size;
  height: 78px; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  padding: 0 16px; margin-bottom: 20px;
  background: var(--accent-soft); border: 1px solid rgba(51, 150, 137, 0.4); border-radius: var(--radius-lg);
  text-decoration: none;
  animation: all-events-card-pulse 4.5s ease-in-out infinite;
}
/* Pulso sutil cada 4.5s: la card entera (título y subtítulo juntos, como
   una sola unidad) se agranda levemente y vuelve. */
@keyframes all-events-card-pulse {
  0%, 85%, 100% { transform: scale(1); }
  92.5% { transform: scale(1.035); }
}
@media (prefers-reduced-motion: reduce) {
  .all-events-card { animation: none; }
  .featured-card, .upcoming-row, .card.clickable { transition: none; }
  .featured-card:hover, .upcoming-row:hover, .card.clickable:hover { transform: none; }
}
.all-events-title {
  display: block; width: 100%; text-align: justify; text-align-last: justify;
  white-space: nowrap; text-transform: uppercase; font-weight: 400;
  font-family: 'Avega Italic', var(--sans);
  /* 6.6cqw deja el texto natural en ~93% del ancho de la card en cualquier
     tamaño (medido con la métrica real de Avega Italic); text-align-last:
     justify hace el último estirón para llegar a 100% de punta a punta. */
  font-size: clamp(15px, 6.6cqw, 90px);
  color: var(--text); margin: 0; line-height: 1.05;
}
/* Mismo tamaño que .featured-info .meta (subtítulo de fecha/lugar en las
   tarjetas de Destacados) — ya no escala con el breakpoint. */
.all-events-subtitle { font-size: 11px; color: var(--text-secondary); margin: 3px 0 0; }
.upcoming-icon {
  position: relative;
  width: 38px; height: 38px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 16px; background-size: cover; background-position: center;
  /* Ver comentario igual en .featured-img: fondo neutro de base para las
     zonas transparentes de un flyer en PNG, ya que bg-{{ event.color }}
     ahora solo se aplica sin imagen. */
  background-color: var(--surface-solid);
}
.upcoming-row .name { font-size: 13.5px; font-weight: 700; margin: 0; color: var(--text); }
.upcoming-row .meta { font-size: 11.5px; color: var(--text-secondary); margin: 2px 0 0; }
.upcoming-price-col { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; margin-left: auto; }
.upcoming-price { font-size: 12px; font-weight: 700; color: var(--accent-end); white-space: nowrap; text-align: right; }
/* "Desde" en su propio renglón arriba del monto, en blanco -- distinto
   del monto en sí (naranja, bold), que sigue heredando el color/peso de
   .upcoming-price sin necesidad de un span propio. */
.upcoming-price-label { display: block; color: var(--text); font-weight: 400; font-size: 10px; }
.upcoming-price-unavailable { color: var(--text-muted); font-style: italic; font-weight: 400; }

.bg-accent { background-color: var(--accent-soft); }
.bg-success { background-color: var(--success-soft); }
.bg-warning { background-color: var(--warning-soft); }

.empty-note { font-size: 12.5px; color: var(--text-muted); }
/* Link de marca (naranja) para invitaciones dentro de texto muted, como
   "¿Querés saber más? Mirá cómo funciona →" en listing_form.html --
   .empty-note a por default hereda el azul de link del navegador, que no
   es un accent de la marca. */
.link-accent { color: var(--accent-end); font-weight: 600; text-decoration: none; }

/* Botones genéricos */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 36px; padding: 0 14px;
  border-radius: var(--radius); border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text); font-size: 13px; font-weight: 700; cursor: pointer; text-decoration: none;
}
.btn:hover { background: var(--surface-2); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { background: var(--surface); }
.btn-sm { height: 32px; font-size: 12.5px; padding: 0 12px; }

/* Encabezado de pantalla con evento (catálogo) */
.page-title { font-size: 18px; font-weight: 700; margin: 12px 0 2px; color: var(--text); letter-spacing: -.01em; }
.page-sub { font-size: 12.5px; color: var(--text-secondary); margin: 0 0 16px; }

/* Nombres de evento en mayúscula en todo el sitio, sin tocar el dato
   guardado: aplica también a eventos ya cargados y a los que se carguen
   después, sin importar cómo se haya escrito el nombre originalmente. */
.event-name { text-transform: uppercase; }

/* Filtros */
.filters-row { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.filters-row select {
  background-color: var(--surface-solid); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 7px 9px; font-size: 12.5px; font-family: inherit;
}
.filters-row select option { background-color: var(--surface-solid); color: var(--text); }
.filters-row select:last-child { margin-left: auto; }

/* Banner + datos del evento (catálogo): apilados en mobile (banner
   arriba); a partir de tablet van lado a lado, banner angosto pegado a
   la izquierda (~1/4 del ancho) y los datos ocupando el resto a la
   derecha, en la misma fila. */
.event-hero-row { display: flex; flex-direction: column; gap: 14px; margin: 12px 0 16px; }

/* Imagen/portada del evento: la imagen (recortada en origen a 4:5 por
   Cloudinary, ver cloudinary_fill en event_catalog.html) llena toda la
   card con background-size: cover, sin fondo de color detrás -- antes se
   armaba en capas (una copia desenfocada y teñida de naranja atrás, la
   imagen sin recortar encima) para disimular el espacio vacío que dejaba
   un flyer con otra proporción; ya no hace falta porque todas las
   imágenes llegan con la misma proporción. Sin foto, sigue el ícono
   centrado sobre el color del evento, como antes. */
.event-hero {
  height: 150px; border-radius: var(--radius-lg); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  position: relative; overflow: hidden;
}
.event-hero-icon { font-size: 40px; }
.event-hero-fg { position: absolute; inset: 0; background-size: cover; background-position: center; background-repeat: no-repeat; }

/* Datos del evento (nombre, ticketera, lugar y fecha), al costado del banner */
.event-info { margin: 0; min-width: 0; }

/* Barra "Vende [evento]" (catálogo): separada del todo del listado de
   tickets, al pie de la página -- antes vivía en .event-hero-row, pegada
   al banner, y se confundía visualmente con la lista de tickets
   disponibles. Mismo degradé de marca que btn-primary/fab-pill.sell,
   lleva directo a publicar con este evento ya precargado (sin pasar por
   el buscador de eventos del FAB). */
.event-sell-section { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
.event-sell-cta {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 44px; padding: 9px 14px; border-radius: var(--radius);
  background: var(--accent-gradient); color: var(--on-accent);
  font-weight: 600; font-size: 13.5px; line-height: 1.3; text-decoration: none;
}
.event-sell-cta:hover { opacity: .92; }

@media (min-width: 768px) {
  .event-hero-row { flex-direction: row; align-items: center; }
  .event-hero-row .event-hero { flex: 0 0 25%; min-width: 0; }
  .event-hero-row .event-info {
    flex: 0 1 auto; display: flex; flex-direction: column; justify-content: center;
  }
  .event-sell-cta { max-width: 320px; margin: 0 auto; }
}

/* Publicaciones */
.listing-grid { display: flex; flex-direction: column; gap: 10px; }
.card { display: block; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px; text-decoration: none; color: inherit; }
.card.clickable { cursor: pointer; transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.card.clickable:hover {
  border-color: var(--border-strong); transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, .28);
}
/* Miniatura del evento en cada publicación (catálogo del evento): misma
   imagen del banner, mismo patrón que .event-summary-img/.upcoming-icon. */
.listing-card-inner { display: flex; gap: 12px; }
.listing-thumb {
  width: 56px; height: 56px; border-radius: var(--radius); flex-shrink: 0; border: 1px solid var(--border);
  background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; font-size: 22px;
  /* Ver comentario igual en .featured-img: fondo neutro de base para las
     zonas transparentes de un flyer en PNG. */
  background-color: var(--surface-solid);
}
.listing-body { flex: 1; min-width: 0; }
.listing-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; margin-bottom: 10px; }
.listing-top .sector { font-size: 15px; font-weight: 700; color: var(--text); margin: 0; }
.listing-top .meta { font-size: 12.5px; color: var(--text-secondary); margin: 4px 0 0; }
.listing-price { font-size: 20px; font-weight: 700; color: var(--accent-end); }
.listing-price small { font-size: 12px; color: var(--text-secondary); font-weight: 400; }
/* Precio destacado dentro de una línea de texto más larga (ej. el
   renglón de Mis Tickets con sector/cantidad/precio en un solo .meta) --
   mismo criterio de color que .listing-price/.upcoming-price/.total-row,
   pero sin tamaño ni display propio porque va inline en texto ya chico. */
.price-highlight { color: var(--accent-end); font-weight: 700; }
.seller-row { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--border); padding-top: 10px; margin-top: 10px; }
/* Reutilizable en cualquier lado que necesite representar a un usuario
   (no solo dentro de .seller-row): foto real si tiene, iniciales si no. */
.mini-avatar {
  width: 24px; height: 24px; border-radius: 50%; background: var(--accent-gradient); color: var(--on-accent);
  font-size: 10px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.mini-avatar-lg { width: 34px; height: 34px; font-size: 12px; }
.mini-avatar-xs { width: 16px; height: 16px; font-size: 8px; }
.avatar-img { object-fit: cover; }

/* Fila de contraparte (Estado de la compra, Mis entradas): avatar + texto */
.counterparty-line { display: flex; align-items: center; gap: 6px; margin-top: 6px; text-decoration: none; width: fit-content; }
.counterparty-line span { font-size: 12.5px; color: var(--text-secondary); }
.counterparty-line-sm { gap: 5px; margin-top: 2px; }
.counterparty-line-sm span { font-size: 11.5px; }
.seller-row .name { font-size: 12.5px; color: var(--text); flex: 1; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Avatar + nombre como link al perfil público, sin romper el layout del
   resto de la fila (reputación, verificado) que queda afuera del link. */
.seller-identity { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.seller-identity .name { flex: 1; min-width: 0; }
.seller-row .verified { color: var(--accent-start); font-size: 12px; }
.seller-row .reputation { font-size: 11.5px; color: var(--text-secondary); white-space: nowrap; }

.badge { font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 20px; white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; }
.badge-success { background: rgba(63, 203, 130, 0.16); color: var(--success); }

/* Detalle de publicación */
.btn-primary { background: var(--accent-gradient); border-color: transparent; color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-gradient); opacity: .92; }
.btn-danger { background: var(--danger-strong); border-color: transparent; color: #fff; }
.btn-danger:hover { background: var(--danger-strong); opacity: .9; }

/* Cartel de confirmación al publicar una entrada */
.publish-success-banner {
  display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center;
  background: var(--accent-gradient); color: var(--on-accent); border-radius: var(--radius-lg);
  padding: 20px 18px; margin: 12px 0 0;
}
.publish-success-text { font-size: 15px; font-weight: 700; margin: 0; }
.publish-success-banner .btn {
  background: rgba(11, 27, 48, .18); border: 1px solid rgba(11, 27, 48, .35); color: var(--on-accent); font-weight: 700;
}
.publish-success-banner .btn:hover { background: rgba(11, 27, 48, .28); }
.btn-block { width: 100%; height: 44px; font-size: 14px; }
.qty-row { display: flex; gap: 10px; align-items: center; margin: 14px 0; }
.qty-row label { font-size: 12.5px; color: var(--text-secondary); white-space: nowrap; }
.qty-row select { width: 70px; background-color: var(--surface-solid); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 7px 9px; font-size: 13px; font-family: inherit; }
.qty-row select option { background-color: var(--surface-solid); color: var(--text); }
.total-row { margin-left: auto; text-align: right; font-size: 13px; color: var(--text-secondary); }
.total-row b { display: block; font-size: 17px; color: var(--accent-end); font-weight: 700; }
.field-error { color: var(--danger); font-size: 12.5px; margin: 4px 0 10px; }

/* Formularios genéricos (editar datos personales, etc.) */
.form-group { margin-bottom: 14px; }
.form-group label { display: block; font-size: 12.5px; color: var(--text-secondary); margin-bottom: 6px; }
.form-group input, .form-group select {
  width: 100%; background-color: var(--surface-solid); border: 1px solid var(--border); border-radius: 8px;
  padding: 9px 11px; font-size: 13px; color: var(--text); font-family: inherit;
}
.form-group select option { background-color: var(--surface-solid); color: var(--text); }

/* Precio: se carga solo escribiendo el número, sin la ruedita de subir/
   bajar del input numérico nativo (Chrome/Safari y Firefox usan mecanismos
   distintos para ocultarla). */
.no-spinner::-webkit-outer-spin-button,
.no-spinner::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.no-spinner {
  -moz-appearance: textfield;
}

/* Editar precio (listing_detail, dueño de la publicación): arranca en
   modo lectura (precio actual + botón "Cambiar precio"); el campo real
   vive siempre en el DOM pero oculto, para no depender de JS para
   mostrarlo si hay un error de validación al reenviar el form (ver
   listing_detail.html). */
.price-edit-current { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.price-edit-current-value { font-size: 18px; font-weight: 700; color: var(--text); }

.checkbox-row { display: flex; align-items: flex-start; gap: 10px; margin: 16px 0; }
.checkbox-row input[type=checkbox] { width: 18px; height: 18px; margin-top: 1px; flex-shrink: 0; accent-color: var(--accent-start); }
.checkbox-row label { font-size: 12px; color: var(--text-secondary); line-height: 1.4; }

.payment-row.emphasis { background: var(--accent-soft); border-color: rgba(51, 150, 137, 0.4); }
.payment-row.emphasis .label { color: var(--text-secondary); }
.payment-row.emphasis .value { font-size: 18px; color: var(--accent-start); }

/* Mi cuenta */
.account-header { display: flex; flex-direction: column; align-items: center; text-align: center; }
.account-photo {
  width: 72px; height: 72px; border-radius: 50%; object-fit: cover; flex-shrink: 0;
}
.account-photo-fallback {
  display: flex; align-items: center; justify-content: center; background: var(--accent-gradient);
  color: var(--on-accent); font-size: 22px; font-weight: 700;
}
.badge-danger { background: var(--danger-soft); color: var(--danger); }

.account-section-title { font-size: 12.5px; font-weight: 700; color: var(--text); margin: 0 0 12px; }
.account-section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.account-data-row { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-top: 1px solid var(--border); }
.account-data-row:first-of-type { border-top: none; padding-top: 0; }
.account-data-row .label { font-size: 12.5px; color: var(--text-secondary); }
.account-data-row .value { font-size: 13px; color: var(--text); font-weight: 600; text-align: right; }

.account-summary { display: flex; gap: 28px; }
.account-summary-number { font-size: 22px; font-weight: 700; color: var(--text); margin: 0; }

.account-actions { padding: 0; overflow: hidden; }
.account-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 14px 16px; border-bottom: 1px solid var(--border);
  background: none; border-left: none; border-right: none; border-top: none;
  color: var(--text); font-size: 13.5px; font-weight: 600; font-family: inherit;
  text-decoration: none; cursor: pointer; text-align: left;
}
.account-row:last-child { border-bottom: none; }
.account-row-arrow { color: var(--text-muted); font-size: 16px; }
.account-row-danger { color: var(--danger); }

/* Estado de la compra */
.event-summary { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; }
.event-summary-img {
  width: 64px; height: 64px; border-radius: var(--radius); flex-shrink: 0; border: 1px solid var(--border);
  background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; font-size: 24px;
  /* Ver comentario igual en .featured-img: fondo neutro de base para las
     zonas transparentes de un flyer en PNG. */
  background-color: var(--surface-solid);
}
.event-summary .name { font-size: 16px; font-weight: 700; color: var(--text); margin: 0; }
.event-summary .meta { font-size: 12px; color: var(--text-secondary); margin: 2px 0 0; }

/* Seguimiento del reclamo (dispute_detail): 3 pasos con puntitos y
   conector, sin relación con .loop-progress de más abajo (esa es la
   barra de estado de la compra/venta, en purchase_detail). */
.progress-track { display: flex; align-items: flex-start; margin: 18px 0 22px; }
.progress-step { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 74px; flex-shrink: 0; }
.progress-step .dot { width: 14px; height: 14px; border-radius: 50%; background: var(--surface-2); border: 2px solid var(--border-strong); box-sizing: border-box; }
.progress-step.done .dot { background: var(--accent-gradient); border-color: transparent; }
.progress-step.current .dot { border-color: var(--accent-start); box-shadow: 0 0 0 4px var(--accent-soft); }
.progress-step .label { font-size: 10.5px; color: var(--text-muted); text-align: center; line-height: 1.25; }
.progress-step.done .label, .progress-step.current .label { color: var(--text); font-weight: 600; }
.progress-connector { flex: 1; height: 2px; background: var(--border-strong); margin: 6px -1px 0; }
.progress-connector.filled { background: var(--accent-gradient); }

/* Estado de la operación (purchase_detail): el símbolo ∞ de la marca
   (mismo recurso que .loop-icon, el glifo Unicode de verdad, no un
   dibujo aparte) hace de barra de progreso -- dos copias superpuestas,
   una siempre entera en gris (el tercio/los tercios que todavía no
   llegaron, para que se note la forma completa en todo momento) y otra
   en naranja recortada con clip-path a 1/3, 2/3 o 3/3 según la etapa,
   como si fuera una barra de progreso recta pero con forma de infinito.
   Los tercios quedan unidos en un solo ícono continuo (misma fuente,
   mismo glifo, apenas uno tapando al otro), no como 3 elementos separados. */
.loop-progress-wrap { display: flex; flex-direction: column; align-items: center; gap: 4px; margin: 18px 0 22px; }
.loop-progress { position: relative; font-size: 44px; font-weight: 700; line-height: 1; }
.loop-progress-icon { display: block; }
.loop-progress-icon-base { color: var(--surface-2); }
.loop-progress-icon-fill { position: absolute; top: 0; left: 0; color: var(--accent-end); }
.loop-progress-fill-1 { clip-path: inset(0 66.667% 0 0); }
.loop-progress-fill-2 { clip-path: inset(0 33.333% 0 0); }
.loop-progress-fill-3 { clip-path: inset(0 0 0 0); }
.loop-progress-label { font-size: 12.5px; font-weight: 600; color: var(--text); margin: 0; }

.highlight-box { background: var(--warning-soft); border: 1px solid rgba(255, 138, 61, 0.4); border-radius: var(--radius-lg); padding: 14px; margin-bottom: 14px; }
.highlight-box .field-label { font-size: 12.5px; font-weight: 600; color: var(--text); margin: 0 0 8px; }
.highlight-box .field-row { display: flex; gap: 8px; }
.highlight-box input[type=email] { flex: 1; background-color: var(--surface-solid); border: 1px solid var(--border); border-radius: 8px; padding: 9px 11px; font-size: 13px; color: var(--text); font-family: inherit; }
.highlight-box .note { font-size: 11.5px; color: var(--text-secondary); margin: 8px 0 0; }

.payment-data { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.payment-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; }
.payment-row .label { font-size: 11px; color: var(--text-muted); margin: 0; }
.payment-row .value { font-size: 14px; font-weight: 600; color: var(--text); margin: 2px 0 0; font-variant-numeric: tabular-nums; }
.copy-btn { background: none; border: 1px solid var(--border-strong); color: var(--text); border-radius: 8px; width: 32px; height: 32px; cursor: pointer; font-size: 14px; flex-shrink: 0; }
.copy-btn:hover { background: var(--surface-2); }

.countdown-box { text-align: center; margin-bottom: 14px; }
.countdown-box .countdown { font-size: 28px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.countdown-box .caption { font-size: 11.5px; color: var(--text-secondary); }

/* "Cancelar reserva" (purchase_detail.html, reserva activa sin
   comprobante): línea divisoria + recuadro de borde rojo coral, y un panel
   de confirmación aparte que se muestra/oculta con la clase .open (mismo
   patrón vanilla JS que .notif-dropdown en app_base.html, sin JS extra). */
.cancel-reservation-box { border-top: 1px solid var(--border); padding-top: 14px; margin-bottom: 14px; }
.cancel-reservation-trigger {
  display: block; width: 100%; background: var(--surface); border: 1px solid var(--danger-strong);
  border-radius: var(--radius-lg); padding: 11px 14px; font-size: 13.5px; font-weight: 700;
  color: var(--danger-strong); text-align: center; cursor: pointer;
}
.cancel-reservation-confirm { display: none; margin-top: 12px; }
.cancel-reservation-confirm.open { display: block; }
.cancel-reservation-title { font-size: 13px; font-weight: 700; color: var(--text); margin: 0 0 6px; }
.cancel-reservation-note { font-size: 12px; color: var(--text-secondary); margin: 0 0 12px; line-height: 1.45; }

.actions-row { display: flex; gap: 10px; }
.actions-row .btn { flex: 1; }

/* Calificación de 1 a 5 estrellas entre comprador y vendedor (reemplaza a
   la vieja recomendación booleana) */
.rate-prompt { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 16px; margin-top: 12px; }
.rate-prompt .field-label { margin-bottom: 12px; }

/* Estrellas tocables (paso de calificar) -- .star-rating envuelve los 5
   <button>, vacíos por default (var(--border-strong)) y naranja al
   tocarlos (clase .filled agregada por JS, ver purchase_detail.html). */
.star-rating { display: flex; gap: 6px; margin-bottom: 14px; }
.star-rating .star {
  background: none; border: none; padding: 0; cursor: pointer;
  font-size: 30px; line-height: 1; color: var(--border-strong); font-family: inherit;
}
.star-rating .star.filled { color: var(--accent-end); }

.rate-prompt textarea {
  width: 100%; background-color: var(--surface-solid); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 11px; font-size: 13px; color: var(--text); font-family: inherit; resize: vertical;
  min-height: 70px; margin-bottom: 12px; box-sizing: border-box;
}
.rate-prompt textarea::placeholder { color: var(--text-muted); }

/* Estrellas de solo lectura (promedio del perfil, parcialmente rellena
   según el decimal -- ej. 4.7 = 94% -- y cada comentario individual, sin
   fracción: 1 a 5 estrellas enteras). Dos <span> superpuestos: abajo las
   5 vacías de siempre, arriba las 5 llenas recortadas al ancho justo
   (--fill, un % fijado inline por el template) -- el recorte (overflow:
   hidden) es lo que simula el relleno parcial de la última estrella. */
.star-display { position: relative; display: inline-block; font-size: 18px; line-height: 1; letter-spacing: 2px; }
.star-display-sm { font-size: 12px; }
.star-display-track { color: var(--border-strong); }
.star-display-fill {
  position: absolute; top: 0; left: 0; overflow: hidden; width: var(--fill, 0%);
  color: var(--accent-end); white-space: nowrap;
}

/* Resumen de calificación (Mi cuenta / perfil público) */
.rating-summary { margin-top: 12px; }
.rating-headline { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
.rating-average { font-size: 34px; font-weight: 700; color: var(--text); }
.rating-average.is-new { font-size: 20px; color: var(--text-secondary); }

/* Comentarios recibidos */
.comment-card { padding: 14px; }
.comment-card + .comment-card { margin-top: 10px; }
.comment-stars { font-size: 13px; color: var(--accent-end); letter-spacing: 2px; }
.comment-date { font-size: 11px; color: var(--text-muted); float: right; }
.comment-text { font-size: 13px; color: var(--text); margin: 8px 0 0; line-height: 1.45; clear: both; }

/* Mis entradas */
.tabs { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 14px; }
.tab { border: none; background: none; padding: 8px 4px; font-size: 14px; font-weight: 600; color: var(--text-muted); cursor: pointer; border-bottom: 2px solid transparent; margin-right: 18px; font-family: inherit; }
.tab.active { color: var(--text); border-color: var(--accent-start); }

.chip-row { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.chip { font-size: 12px; padding: 6px 13px; border-radius: 20px; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text-secondary); cursor: pointer; font-family: inherit; }
.chip.active { background: var(--accent-gradient); color: var(--on-accent); border-color: transparent; font-weight: 600; }

.ticket-status { margin-left: auto; }
.upcoming-row-dispute { border-color: var(--danger); }
.dispute-flag { margin-left: 6px; }
.badge-accent { background: var(--accent-soft); color: var(--accent-start); }
.badge-warning { background: rgba(255, 138, 61, 0.16); color: var(--warning); }
.badge-muted { background: var(--surface-2); color: var(--text-muted); }
.bg-danger { background-color: var(--danger-soft); }

/* Columnas lado a lado (Validar pago, Resolver reclamo): apiladas en
   mobile, en fila a partir de tablet. */
.dual-column { display: flex; flex-direction: column; gap: 16px; margin-top: 14px; }
.dual-column > div { flex: 1; min-width: 0; }
@media (min-width: 768px) {
  .dual-column { flex-direction: row; }
}

/* Panel de administración */
.panel-metrics { display: flex; flex-direction: column; gap: 10px; margin: 16px 0 22px; }
.panel-metric-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 14px 16px; }
.panel-metric-card.alert { border-color: rgba(241, 97, 107, 0.4); }
.panel-metric-card .value { font-size: 26px; font-weight: 700; color: var(--text); margin: 0; font-variant-numeric: tabular-nums; }
.panel-metric-card.alert .value { color: var(--danger); }
.panel-metric-card .label { font-size: 12px; color: var(--text-secondary); margin: 4px 0 0; }
@media (min-width: 768px) {
  .panel-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
}

.panel-queue { display: flex; flex-direction: column; gap: 8px; }
.panel-queue-item { display: flex; align-items: center; gap: 12px; border: 1px solid var(--border); border-radius: var(--radius); padding: 12px 14px; background: var(--surface); text-decoration: none; color: inherit; }
.panel-queue-item:hover { border-color: var(--border-strong); }
.panel-queue-item .kind-icon { width: 38px; height: 38px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.panel-queue-item .title { font-size: 13px; font-weight: 600; color: var(--text); margin: 0; }
.panel-queue-item .subtitle { font-size: 11.5px; color: var(--text-secondary); margin: 2px 0 0; }
.panel-queue-item .age { font-size: 11px; color: var(--text-muted); margin-left: auto; white-space: nowrap; }

/* Barra de navegación inferior (ver templates/_bottom_nav.html): fija,
   presente en todas las pantallas. Reutiliza .nav-item/.nav-icon/
   .nav-label, los mismos que Panel en el header (ver más arriba) --
   mismo tratamiento visual en los dos lugares. safe-area-inset-bottom
   evita que el home indicator de iPhone quede pegado a las etiquetas. */
.bottom-nav {
  position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 480px; z-index: 20;
  display: flex; justify-content: space-around; align-items: center;
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom));
  background: var(--surface-solid); border-top: 1px solid var(--border);
}
.bottom-nav .nav-item { flex: 1; }
/* Notificaciones es el único ítem envuelto en un div propio (.notif-wrap,
   para el desplegable) en vez de ser directamente un .nav-item: sin
   flex:1 acá, ese div quedaba angosto (ajustado al ancho del botón) en
   vez de ocupar el mismo cuarto que los demás, y su ícono terminaba
   descentrado respecto al resto de la barra. */
.bottom-nav .notif-wrap { flex: 1; display: flex; justify-content: center; }
/* Íconos de la barra inferior: un solo color, solo contorno naranja de
   marca (SVG con fill none + stroke currentColor, ver _bottom_nav.html),
   sin el cuadrado con fondo que usa .nav-icon en Panel. Perfil es una
   silueta genérica, no la foto del usuario. El label debajo también va
   en naranja (antes solo el ícono), no solo cuando el ítem está activo. */
.bottom-nav .nav-icon {
  border: none; background: transparent; border-radius: 0; color: var(--accent-end);
}
.bottom-nav .nav-icon svg { width: 24px; height: 24px; display: block; }
.bottom-nav .nav-item.active .nav-icon svg { stroke-width: 2.3; }
.bottom-nav .nav-label { color: var(--accent-end); }

/* Contenido angosto (detalle/estado/listas) para no estirar formularios
   de punta a punta en pantallas anchas */
.screen--narrow { max-width: 640px; margin: 0 auto; }

/* Lista de próximos eventos (home) */
.upcoming-list { display: flex; flex-direction: column; gap: 8px; }

/* "Todos los eventos" (catálogo): mismas filas que "Próximos eventos" del
   Home, pero con más presencia visual — tarjetas más grandes, no tan
   compactas. Se escala en cada breakpoint junto con el resto del sitio. */
.event-list-large .upcoming-row { padding: 16px 18px; gap: 16px; }
.event-list-large .upcoming-row > div:nth-child(2) { flex: 1 1 auto; min-width: 0; }
.event-list-large .upcoming-icon { width: 60px; height: 60px; font-size: 24px; border-radius: 10px; }
/* El ícono de catálogo (60-100px según breakpoint) tiene bastante más
   lugar que el de Próximos eventos del Home (38-44px): el badge de
   fecha se ve proporcionalmente chico si se queda en el tamaño mínimo
   de .date-badge-sm. */
.event-list-large .date-badge-sm { padding: 3px 5px; }
.event-list-large .date-badge-sm .date-badge-day { font-size: 12px; }
.event-list-large .date-badge-sm .date-badge-month { font-size: 7px; }
/* Título: máximo 2 líneas, con puntos suspensivos si no entra, y un
   tamaño más proporcional al resto de la tarjeta (antes quedaba
   desproporcionado frente a lugar/fecha/precio). */
.event-list-large .name {
  font-size: 14px; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.event-list-large .meta { font-size: 13px; margin-top: 3px; }
.event-list-large .upcoming-price { font-size: 14px; }

/* "¿Cómo funciona Ticket Loop?" (how_it_works.html) */
.how-works-intro { margin: 12px 0 20px; }
.how-works-intro .page-title { font-size: 20px; }

/* Acordeón de preguntas frecuentes: <details>/<summary> nativos (sin JS)
   -- el browser ya maneja abrir/cerrar y accesibilidad de teclado.
   "display: flex" en <summary> es lo que saca el triángulo nativo del
   navegador, sin necesidad de ::-webkit-details-marker aparte. */
.hiw-faq { display: flex; flex-direction: column; gap: 10px; }
.hiw-faq-item {
  background: #232e48; border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28); transition: border-color 0.15s;
}
.hiw-faq-item[open] { border-color: var(--accent-end); }
.hiw-faq-q {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px; font-size: 13.5px; font-weight: 700; color: var(--text);
  cursor: pointer; list-style: none;
}
.hiw-faq-arrow { width: 16px; height: 16px; flex-shrink: 0; color: var(--accent-end); transition: transform 0.2s; }
.hiw-faq-item[open] .hiw-faq-arrow { transform: rotate(180deg); }
.hiw-faq-a { font-size: 12.5px; color: var(--text-secondary); margin: 0; padding: 0 14px 14px; line-height: 1.45; }

/* Camino único vendedor+comprador (hiw = "how it works"): arranca en el
   logo real de Ticket Loop, con un resplandor sutil alrededor (drop-shadow,
   no box-shadow, porque el logo es un PNG con transparencia y forma
   irregular -- así el resplandor sigue el contorno real del dibujo en vez
   de encerrarlo en un rectángulo/círculo que no le corresponde), y baja por
   una línea punteada central que conecta los 6 pasos en zigzag (a la
   izquierda o a la derecha de esa línea, alternados). Cada paso es
   vendedor (naranja) o comprador (azul), marcado en tres lugares a la
   vez -- la etiqueta de rol, el circulito numerado sobre la línea, y el
   borde de 4px de la tarjeta que mira hacia esa línea -- para que se
   entienda de un vistazo sin tener que leer el texto. */
.hiw-path { margin: 4px 0 8px; }
/* 24px fijo: separación entre el logo y el primer paso. .hiw-step
   (:first-child)::before usa este mismo valor (top: -24px) para que la
   línea punteada arranque justo en la base del logo sin cortes, sin
   necesidad de un tramo aparte -- ver más abajo. */
.hiw-path-icon-wrap { display: flex; justify-content: center; margin-bottom: 24px; }
.hiw-path-icon {
  height: 60px; width: auto; display: block;
  filter: drop-shadow(0 0 6px rgba(255, 158, 0, 0.45)) drop-shadow(0 0 16px rgba(255, 158, 0, 0.3));
}

/* Envuelve los 6 pasos: acá vive la franja de fondo de cada columna
   (.hiw-path-columns), de arriba a abajo de todo eso -- no se extiende
   hacia arriba, detrás del logo, porque ese es el punto de partida neutro,
   ni de vendedor ni de comprador. */
.hiw-path-body { position: relative; }
.hiw-path-columns { position: absolute; inset: 0; display: flex; z-index: 0; pointer-events: none; }
.hiw-path-columns::before { content: ''; flex: 1; background: rgba(255, 158, 0, 0.035); }
.hiw-path-columns::after { content: ''; flex: 1; background: rgba(79, 143, 224, 0.04); }

.hiw-steps { position: relative; z-index: 1; display: flex; flex-direction: column; }
.hiw-step { position: relative; margin-bottom: 18px; }
.hiw-step:last-child { margin-bottom: 0; }
/* La línea vertical continua, armada en dos mitades por paso (de su propio
   borde superior a su propio centro, y de su centro a su borde inferior +
   el espacio hasta el siguiente paso) en vez de una única raya de punta a
   punta del contenedor: así cada tramo se ancla al alto real de CADA
   tarjeta (con top/bottom en % o relativos a su propio borde), sin
   importar cuánto ocupe el texto -- nunca se corta ni se pasa de largo.
   Por detrás de todo (z-index implícito 0); los circulitos numerados
   (z-index 1, fondo sólido) tapan el tramo que les toca, así no se ve la
   raya atravesando el número. */
.hiw-step::before {
  content: ''; position: absolute; left: 50%; top: 0; bottom: 50%; width: 0;
  border-left: 2px dashed var(--border-strong);
}
.hiw-step::after {
  content: ''; position: absolute; left: 50%; top: 50%; bottom: -18px; width: 0;
  border-left: 2px dashed var(--border-strong);
}
/* Primer paso: en vez de no dibujar nada arriba (::before), lo estira
   hacia arriba hasta la base del logo (-24px, ver .hiw-path-icon-wrap) en
   vez de arrancar en su propio borde -- une el logo con el paso 1 sin la
   costura que dejaba el tramo aparte anterior. */
.hiw-step:first-child::before { top: -24px; }
/* Último paso: no sigue de largo después de su propio centro (nodo 6). */
.hiw-step:last-child::after { display: none; }
.hiw-step-card {
  width: 150px; min-height: 64px; background: #232e48; border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 8px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28); box-sizing: border-box;
  display: flex; align-items: center; gap: 8px;
}
/* Vendedor: siempre columna izquierda. Comprador: siempre columna
   derecha. Fijo, no alterna por número de paso -- lo único que va en
   zigzag es a qué lado le toca el paso siguiente en la secuencia 1 a 6,
   no el lado en sí, que depende únicamente del rol. */
.hiw-step-seller .hiw-step-card { margin-right: auto; }
.hiw-step-buyer .hiw-step-card { margin-left: auto; }
/* Conector horizontal punteado, del borde de la tarjeta (ancho fijo) a la
   línea central (al 50%) -- calc() porque una punta está en px y la otra
   en %. */
.hiw-step-connector { position: absolute; top: 50%; width: calc(50% - 150px); border-top: 2px dashed var(--border-strong); }
.hiw-step-seller .hiw-step-connector { left: 150px; }
.hiw-step-buyer .hiw-step-connector { right: 150px; }
.hiw-step-num {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1;
  width: 25px; height: 25px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 700; color: var(--on-accent);
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.35);
}
.hiw-step-seller .hiw-step-num { background: var(--accent-end); }
.hiw-step-buyer .hiw-step-num { background: var(--buyer-color); color: #fff; }

/* Tarjeta rectangular: ícono a la izquierda, texto (rol + título +
   descripción) a la derecha en una columna -- en vez de ícono arriba y
   texto abajo, que la hacía ver cuadrada. */
.hiw-step-icon-box {
  width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
.hiw-step-icon-box svg { width: 19px; height: auto; display: block; }
.hiw-step-icon-box .hiw-icon-flip { transform: scaleX(-1); }
.hiw-step-seller .hiw-step-icon-box { background: rgba(255, 158, 0, 0.16); color: var(--accent-end); }
.hiw-step-buyer .hiw-step-icon-box { background: rgba(79, 143, 224, 0.16); color: var(--buyer-color); }

.hiw-step-info { min-width: 0; }
.hiw-step-role { display: block; font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.hiw-step-seller .hiw-step-role { color: var(--accent-end); }
.hiw-step-buyer .hiw-step-role { color: var(--buyer-color); }

.hiw-step-title { font-size: 10.5px; font-weight: 700; color: var(--text); margin: 0 0 2px; line-height: 1.25; }
.hiw-step-text { font-size: 8.5px; color: var(--text-secondary); margin: 0; line-height: 1.3; }

.hiw-step-seller .hiw-step-card { border-right: 4px solid var(--accent-end); }
.hiw-step-buyer .hiw-step-card { border-left: 4px solid var(--buyer-color); }

/* ============ Responsive: tablet / desktop ============
   Mobile-first: por debajo de 768px el diseño no cambia (look de celular).
   A partir de acá se aprovecha el ancho extra de tablet/PC. */
@media (min-width: 768px) {
  .app { max-width: 760px; }
  .bottom-nav { max-width: 760px; }
  .screen { padding: 22px 32px; }

  /* Destacados sigue siendo el mismo carrusel deslizante; a partir de acá
     se ven más tarjetas por vez (el ancho relativo de cada una baja).
     150px, no menos que los 145px de mobile -- si no, la imagen se
     achicaría de golpe justo al cruzar este breakpoint. */
  .featured-carousel { gap: 14px; }
  .featured-card { width: 22%; }
  .featured-img { height: 150px; font-size: 28px; }

  .card { padding: 20px; }
  .upcoming-row { padding: 13px 16px; }
  .upcoming-icon { width: 44px; height: 44px; font-size: 18px; }
  .all-events-card { height: 140px; padding: 0 28px; }

  .event-list-large .upcoming-row { padding: 20px 22px; gap: 18px; }
  .event-list-large .upcoming-icon { width: 76px; height: 76px; font-size: 30px; }
  .event-list-large .name { font-size: 15px; }
  .event-list-large .meta { font-size: 14px; }
  .event-list-large .upcoming-price { font-size: 15.5px; }

  .event-hero { height: 210px; }

  .listing-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px;
  }

  .upcoming-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .upcoming-list .upcoming-row { margin-bottom: 0; }
}

@media (min-width: 1024px) {
  .app { max-width: 1280px; }
  .bottom-nav { max-width: 1280px; }
  .screen { padding: 30px 48px; }

  .featured-carousel { gap: 16px; }
  .featured-img { height: 170px; font-size: 32px; }

  .event-hero { height: 260px; }

  .listing-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }

  .upcoming-list { grid-template-columns: repeat(3, 1fr); }

  .screen--narrow { max-width: 680px; }

  .all-events-card { height: 170px; padding: 0 36px; }

  .event-list-large .upcoming-row { padding: 22px 24px; gap: 20px; }
  .event-list-large .upcoming-icon { width: 88px; height: 88px; font-size: 34px; }
  .event-list-large .name { font-size: 16px; }
  .event-list-large .meta { font-size: 14.5px; }
  .event-list-large .upcoming-price { font-size: 16.5px; }
}

@media (min-width: 1440px) {
  .app { max-width: 1440px; }
  .bottom-nav { max-width: 1440px; }
  .screen { padding: 34px 64px; }

  .featured-img { height: 200px; }
  .event-hero { height: 300px; }

  .all-events-card { height: 200px; }

  .event-list-large .upcoming-icon { width: 100px; height: 100px; font-size: 38px; }
  .event-list-large .name { font-size: 17px; }
}
