
/* =============================================================================
   AGENDA DE INICIO

   El inicio tiene dos modos: "Agenda" (por defecto) y "Explorar" (el feed
   inmersivo de siempre). Estas reglas son las del modo agenda.

   El feed a pantalla completa bloquea el viewport (body.tt-feed-active), porque
   el scroll lo lleva el propio feed con snap. La agenda es lo contrario: es una
   pagina que se lee de arriba abajo, asi que aqui se devuelve el scroll normal
   sin tocar las reglas del feed, solo anadiendo el modo al selector.
   ============================================================================= */

body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] {
  overflow: auto;
}

body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] .app {
  height: auto;
  min-height: 100dvh;
  overflow: visible;
}

body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] [data-main-panel="posts"] > main {
  display: block;
  padding: 0 0 calc(64px + env(safe-area-inset-bottom, 0px));
}

/* --- Lista --- */

.agenda-inicio {
  max-width: 720px;
  margin: 0 auto;
  padding: 4px 14px 24px;
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.agenda-bloque-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 2px 2px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 4px;
}

.agenda-bloque-head h2 {
  margin: 0;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* "Hoy" manda: es la respuesta a la pregunta con la que entra el usuario. */
.agenda-bloque.is-destacado .agenda-bloque-head h2 {
  font-size: 24px;
  color: var(--primary, #d2f365);
}

.agenda-bloque-sub {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-soft, #757c5d);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agenda-bloque-n {
  flex: 0 0 auto;
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-muted, #c7d2a5);
  font-size: 11.5px;
  font-weight: 700;
}

/* "Este finde" y "Mas adelante" contienen VARIOS dias, cada uno con su propio
   .agenda-bloque (cabecera + filas). Sin este gap se apilaban pegados: la
   ultima fila de un dia tocaba directamente la cabecera del siguiente, y la
   pantalla se leia como un bloque de texto continuo en vez de dias separados.
   Mismo aire que entre "Hoy", "Manana" y "Este finde" en .agenda-inicio. */
.agenda-finde,
.agenda-despues {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

/* La cabecera de grupo ("Este finde", "Mas adelante") es un titulo de
   seccion, no de dia: mas discreta que la de cada dia de dentro para que no
   compitan por la atencion en una lista ya larga. */
.agenda-grupo-head {
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: -6px;
}

.agenda-grupo-head h2 {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-muted, #c7d2a5);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.agenda-lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* Una linea fina entre filas. Sin ella, con el hueco de 6px y 3px entre las
   lineas internas de cada fila, el precio de una parecia el antetitulo de la
   siguiente. */
.agenda-fila + .agenda-fila {
  border-top: 1px solid rgba(255, 255, 255, 0.05);
}

.agenda-fila-btn {
  width: 100%;
  appearance: none;
  border: 1px solid transparent;
  border-radius: 14px;
  padding: 13px 10px;
  display: grid;
  grid-template-columns: 52px 54px 1fr 16px;
  align-items: center;
  gap: 11px;
  cursor: pointer;
  background: transparent;
  color: inherit;
  font-family: inherit;
  text-align: left;
  transition: background 0.16s ease, border-color 0.16s ease;
}

.agenda-fila-btn:hover {
  background: rgba(255, 255, 255, 0.035);
  border-color: rgba(255, 255, 255, 0.07);
}

.agenda-hora {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
}

.agenda-hora b {
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.agenda-hora small {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* La unica urgencia que se senala es la real: empieza en menos de 3 horas. */
.agenda-hora.is-pronto b,
.agenda-hora.is-pronto small {
  color: #ff9a6c;
}

.agenda-cartel {
  width: 54px;
  height: 54px;
  border-radius: 10px;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-soft, #757c5d);
}

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

.agenda-datos {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.agenda-titulo {
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agenda-lugar {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--text-muted, #c7d2a5);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agenda-lugar i {
  flex: 0 0 auto;
  font-size: 10px;
  opacity: 0.7;
}

.agenda-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.agenda-precio,
.agenda-tag,
.agenda-van {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-muted, #c7d2a5);
  font-size: 10.5px;
  font-weight: 600;
}

.agenda-precio.is-gratis {
  background: rgba(210, 243, 101, 0.14);
  color: var(--primary, #d2f365);
}

.agenda-flecha {
  color: var(--text-soft, #757c5d);
  font-size: 11px;
  text-align: right;
}

.agenda-vermas {
  appearance: none;
  border: 1px dashed rgba(255, 255, 255, 0.12);
  border-radius: 12px;
  width: 100%;
  min-height: 40px;
  margin-top: 8px;
  cursor: pointer;
  background: transparent;
  color: var(--text-muted, #c7d2a5);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
}

.agenda-vermas:hover {
  border-color: var(--line, rgba(210, 243, 101, 0.24));
  color: var(--text, #f4f4f3);
}

/* --- Sin planes hoy --- */

.agenda-vacia {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 30px 20px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  text-align: center;
}

.agenda-vacia-ic {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-muted, #c7d2a5);
  font-size: 18px;
}

.agenda-vacia h2 {
  margin: 0;
  font-size: 18px;
  font-weight: 800;
}

.agenda-vacia p {
  margin: 0;
  max-width: 40ch;
  color: var(--text-muted, #c7d2a5);
  font-size: 13px;
  line-height: 1.45;
}

.agenda-vacia-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin-top: 4px;
}

.agenda-vacia-btn {
  appearance: none;
  border: 1px solid var(--line, rgba(210, 243, 101, 0.24));
  border-radius: 12px;
  min-height: 42px;
  padding: 0 16px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  background: transparent;
  color: var(--text, #f4f4f3);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
}

.agenda-vacia-btn.is-primary {
  background: var(--primary, #d2f365);
  border-color: var(--primary, #d2f365);
  color: #14200a;
  font-weight: 700;
}

/* --- Movil --- */

@media (max-width: 480px) {
  .agenda-inicio {
    padding: 4px 10px 20px;
    gap: 18px;
  }

  .agenda-fila-btn {
    grid-template-columns: 46px 48px 1fr 12px;
    gap: 9px;
    padding: 8px 6px;
  }

  .agenda-cartel {
    width: 48px;
    height: 48px;
  }

  .agenda-bloque.is-destacado .agenda-bloque-head h2 {
    font-size: 21px;
  }
}

/* La barra superior se saca del flujo (position:absolute) para el feed, porque
   ahi el viewport esta bloqueado y el scroll lo lleva el propio feed. La agenda
   es una pagina normal que se desplaza, asi que si la barra sigue fuera del
   flujo se come los primeros 60px de contenido: en movil el logo tapaba
   literalmente el selector de modo. Aqui vuelve al flujo, pegajosa, para que
   ademas la busqueda siga a mano mientras se baja por la agenda. */
body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] .topbar {
  position: sticky;
  top: 0;
  z-index: 60;
}

/* Sin el viewport bloqueado, el panel de inicio deja de ser una columna flex de
   altura fija: si no se le devuelve el alto automatico, el contenido de la
   agenda se comprime dentro de una caja de la altura de la pantalla. */
body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] .main-panels-layout,
body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] .main-panels-content,
body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"] [data-main-panel="posts"] {
  min-height: 0;
  height: auto;
}

/* NADA de la agenda se encoge.

   La agenda vive dentro del panel de inicio, que en el modo feed es una columna
   flex de altura fija. Aunque aqui se le devuelve el alto automatico, los
   contenedores siguen siendo flex, y en flex lo normal es que los hijos se
   compriman cuando no caben. El efecto era este: cada fila se quedaba en 44px
   con 58px de contenido dentro, asi que el precio de un evento se salia de su
   fila y se pintaba encima del titulo del siguiente. Las filas miden lo que mide
   su contenido, siempre. */
.agenda-inicio > *,
.agenda-bloque > *,
.agenda-lista,
.agenda-fila {
  flex: 0 0 auto;
}

/* La base del proyecto fija `input, select, button { height: 44px }`. Esta fila
   ES un boton (toda ella es el area pulsable, que en movil es lo correcto), asi
   que heredaba 44px de alto con 58px de contenido dentro: el precio se salia y
   se pintaba sobre el titulo de la fila siguiente. La fila mide su contenido. */
.agenda-fila-btn {
  height: auto;
  min-height: 0;
}

/* --- Cabecera de la agenda: donde y para quien --- */

.agenda-cabecera {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 2px 2px 2px;
}

.agenda-ciudad,
.agenda-estilos {
  appearance: none;
  height: auto;
  min-height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid var(--line, rgba(210, 243, 101, 0.24));
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  background: transparent;
  color: var(--text, #f4f4f3);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
}

.agenda-ciudad i:last-child {
  font-size: 9px;
  opacity: 0.6;
}

.agenda-estilos {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--text-muted, #c7d2a5);
  text-transform: lowercase;
}

.agenda-ciudad:hover,
.agenda-estilos:hover {
  background: rgba(210, 243, 101, 0.08);
}

/* Marca de "esto encaja con lo tuyo". Discreta a proposito: explica el orden
   sin competir con el titulo del evento. */
.agenda-tuyo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(210, 243, 101, 0.13);
  color: var(--primary, #d2f365);
  font-size: 10.5px;
  font-weight: 700;
}

.agenda-tuyo i {
  font-size: 8.5px;
}

/* --- Hoja de preferencias --- */

.prefs-capa {
  position: fixed;
  inset: 0;
  z-index: 2100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 16px;
  background: rgba(5, 6, 5, 0.62);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.prefs-capa.is-in {
  opacity: 1;
}

.prefs-panel {
  position: relative;
  width: min(100%, 520px);
  max-height: min(86vh, 720px);
  overflow-y: auto;
  padding: 26px 22px 22px;
  border-radius: 22px;
  border: 1px solid var(--line, rgba(210, 243, 101, 0.24));
  background: linear-gradient(180deg, rgba(20, 22, 18, 0.98), rgba(11, 12, 11, 0.99));
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
  transform: translateY(14px);
  transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}

.prefs-capa.is-in .prefs-panel {
  transform: translateY(0);
}

/* En pantallas grandes deja de ser una hoja inferior y se centra. */
@media (min-width: 620px) {
  .prefs-capa {
    align-items: center;
  }
}

.prefs-cerrar {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 34px;
  height: 34px;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-muted, #c7d2a5);
}

.prefs-kicker {
  margin: 0 0 4px;
  color: var(--primary, #d2f365);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.prefs-panel h2 {
  margin: 0 0 6px;
  font-size: clamp(20px, 5vw, 25px);
  font-weight: 800;
  line-height: 1.12;
  padding-right: 32px;
}

.prefs-sub {
  margin: 0 0 18px;
  color: var(--text-muted, #c7d2a5);
  font-size: 13px;
  line-height: 1.45;
}

.prefs-bloque {
  margin-bottom: 18px;
}

.prefs-bloque h3 {
  margin: 0 0 9px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.prefs-bloque h3 small {
  margin-left: 6px;
  color: var(--text-soft, #757c5d);
  font-size: 11px;
  font-weight: 600;
  text-transform: lowercase;
}

.prefs-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}

.prefs-chip {
  appearance: none;
  height: auto;
  min-height: 38px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  cursor: pointer;
  background: transparent;
  color: var(--text-muted, #c7d2a5);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.prefs-chip:hover {
  border-color: var(--line, rgba(210, 243, 101, 0.24));
  color: var(--text, #f4f4f3);
}

.prefs-chip.is-on {
  background: var(--primary, #d2f365);
  border-color: var(--primary, #d2f365);
  color: #14200a;
  font-weight: 700;
}

.prefs-nota {
  margin: 9px 0 0;
  color: var(--text-soft, #757c5d);
  font-size: 11.5px;
  line-height: 1.4;
}

.prefs-acciones {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 22px;
}

.prefs-btn {
  appearance: none;
  height: auto;
  min-height: 48px;
  padding: 0 18px;
  border-radius: 14px;
  border: 1px solid transparent;
  cursor: pointer;
  background: transparent;
  color: var(--text, #f4f4f3);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
}

.prefs-btn.is-primary {
  background: var(--primary, #d2f365);
  color: #14200a;
  font-weight: 700;
}

.prefs-btn.is-quiet {
  color: var(--text-soft, #757c5d);
  min-height: 40px;
}

/* =============================================================================
   EXPLORAR CON FORMA DE MOVIL EN VERTICAL

   El feed se diseño como experiencia de movil: una pantalla, un contenido, gesto
   vertical. En escritorio se estiraba a todo lo ancho y eso rompia las dos cosas
   que lo sostienen: los carteles (que siempre son verticales) se recortaban a una
   banda central por el `object-fit: cover`, y los paneles -musica, hilos,
   directos, mapa- quedaban como tiras horizontales enormes con el contenido
   perdido en el centro.

   La restriccion NO se pone en el cartel sino en `.tt-slide-frame`, que es el
   marco comun de TODAS las pantallas del feed (evento, musica, comunidad,
   directos, gente, tablon, sorteo, instalar, cierre). Asi el formato es uno solo
   para todo Explorar en vez de un parche por tipo de pantalla.

   El ancho maximo es la proporcion 9:16 de la altura disponible MAS los 64px de
   la botonera lateral, que va pegada al contenido como en un movil y no
   descolgada en el borde de la ventana.

   En pantallas estrechas el limite queda por encima del ancho real, asi que en
   movil no cambia nada: sigue a sangre, como estaba.
   ============================================================================= */

body[data-inicio-modo="feed"] .tt-slide-frame {
  width: 100%;
  /* Proporcion 10:16 en vez de 9:16: menos alargada, sin dejar de ser
     vertical (los carteles siguen siendo verticales). */
  max-width: calc((100dvh - var(--tt-chrome-offset, 132px)) * 10 / 16 + 64px);
  margin-inline: auto;
}

/* --- Quien va -----------------------------------------------------------

   PC-13. El "voy" existia desde siempre pero era un contador aislado: decia
   cuanta gente va y no si va ALGUIEN, que es lo que de verdad decide una
   noche. Dos piezas:

   - En la agenda (lista densa) no caben caras, asi que la pildora cambia de
     contenido: si va alguien a quien sigues, sale su nombre y se enciende en
     lima; si no, el numero de siempre en gris.
   - En la ficha del evento si hay sitio para caras, y van arriba de los
     botones: se ve antes de decidir, no despues.

   Con nadie apuntado no se pinta nada. Un "0 personas van" convierte un
   evento tranquilo en un evento fracasado.
   ---------------------------------------------------------------------- */

.agenda-van.is-conocidos {
  background: rgba(210, 243, 101, 0.14);
  color: var(--primary, #d2f365);
  max-width: 148px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.agenda-van.is-conocidos i {
  font-size: 9.5px;
  opacity: 0.9;
}

/* --- Ficha del evento --- */

.asisten-fila {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  width: 100%;
  margin: 0 0 10px;
  padding: 8px 10px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-muted, #c7d2a5);
  font-size: 12.5px;
  line-height: 1.35;
}

/* Si va alguien conocido, la fila deja de ser un dato y pasa a ser un aviso. */
.asisten-fila.is-conocidos {
  background: rgba(210, 243, 101, 0.1);
  border: 1px solid rgba(210, 243, 101, 0.22);
  color: var(--text, #f4f4f3);
}

.asisten-fila b {
  font-weight: 700;
  color: var(--text, #f4f4f3);
}

.asisten-caras {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
}

/* Solapadas, como en el racimo del feed: ocupan menos y se leen como grupo.
   El margen negativo va en todas menos la primera. */
.asisten-cara {
  width: 26px;
  height: 26px;
  border-radius: 999px;
  overflow: hidden;
  display: inline-grid;
  place-items: center;
  border: 2px solid #131315;
  background: rgba(255, 255, 255, 0.08);
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-muted, #c7d2a5);
}

.asisten-cara + .asisten-cara {
  margin-left: -9px;
}

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

.asisten-mas {
  padding: 0 5px;
  min-width: 26px;
  width: auto;
}

.asisten-texto {
  min-width: 0;
  flex: 1 1 auto;
}

@media (max-width: 420px) {
  .asisten-fila {
    font-size: 12px;
  }
  .agenda-van.is-conocidos {
    max-width: 112px;
  }
}

/* --- Voy / Me interesa / Guardar, en la ficha ---------------------------

   Estos botones existian en el JS desde siempre (renderPostInterestControls),
   pero pintaban sobre un contenedor que no estaba en ninguna plantilla, asi
   que nunca se vieron. El resultado: desde la agenda -que es la home y por
   tanto el camino principal- no se podia marcar "Voy" ni guardar un evento;
   solo desde el feed inmersivo. Y sin guardar no hay recordatorio, ni permiso
   de avisos, ni asistentes que ensenar.

   Se pintan como pildoras oscuras, y la activa se enciende en lima: es el
   mismo lenguaje que las pildoras de la agenda, no un sistema de botones
   nuevo.
   ---------------------------------------------------------------------- */

.detail-interest-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin: 0 0 10px;
}

/* La fila de "quien va" ocupa el ancho entero y va encima de los botones: se
   lee antes de decidir, no despues. */
.detail-interest-panel .asisten-fila {
  flex: 1 1 100%;
  margin: 0;
}

.interest-btn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-muted, #c7d2a5);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}

.interest-btn i {
  font-size: 12px;
}

.interest-btn:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.14);
  color: var(--text, #f4f4f3);
}

.interest-btn.is-active {
  background: rgba(210, 243, 101, 0.14);
  border-color: rgba(210, 243, 101, 0.45);
  color: var(--primary, #d2f365);
}

/* El contador del "Voy" vive dentro del boton: es el mismo dato, no otro. */
.interest-count {
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.interest-btn.is-active .interest-count {
  background: rgba(210, 243, 101, 0.22);
}

@media (max-width: 420px) {
  .interest-btn {
    flex: 1 1 auto;
    justify-content: center;
    padding: 10px 10px;
    font-size: 12.5px;
  }
}

/* La fila de la ficha tenia TRES grupos compitiendo por el mismo ancho: likes,
   las tres senales (Voy / Me interesa / Guardar) y las acciones rapidas. Ni
   siquiera en escritorio cabian: a 706 px el boton de like se comprimia hasta
   partir "0 likes" en dos lineas.

   No se arregla quitando texto. Se arregla reconociendo que "Voy" es la accion
   principal de la ficha y merece su propia fila: arriba quedan los likes y las
   acciones sobre el evento (calendario, compartir), que son secundarias, y
   debajo las tres senales a lo ancho.

   Por eso esto NO va dentro de una media query: el problema no era el movil. */
.detail-stats-actions {
  flex-wrap: wrap;
}

.detail-interest-panel {
  order: 2;
  flex: 1 1 100%;
  width: 100%;
  margin-top: 2px;
}

/* El like no se encoge ni parte linea: es un corazon y un numero. */
.detail-like-btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

@media (max-width: 560px) {
  /* En movil, ademas, las tres se reparten el ancho: el "Voy" entero y las
     otras dos a mitad cada una. */
  .detail-interest-panel .interest-btn {
    flex: 1 1 calc(50% - 4px);
  }

  .detail-interest-panel .interest-btn[data-interest-toggle="going"] {
    flex: 1 1 100%;
  }
}

/* --- Reservas con QR (antes "Configurar entradas") ----------------------

   El modal ofrecia aforo, limite por persona, edad minima y validadores sin
   decir en ningun sitio que aqui NO se cobra. Quien lo activaba esperando
   vender no cobraba nada; quien sabia que no cobraba no entendia para que
   servia. Cero eventos lo usaron en 30 dias.

   Estos estilos son para lo que se anadio: la nota que lo explica, la ayuda
   bajo cada campo, y el atenuado de los ajustes cuando las reservas estan
   apagadas.
   ---------------------------------------------------------------------- */

.ticket-config-nota {
  display: flex;
  gap: 12px;
  margin: 0 0 16px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid rgba(210, 243, 101, 0.22);
  background: rgba(210, 243, 101, 0.07);
  color: var(--text-muted, #c7d2a5);
  font-size: 13px;
  line-height: 1.55;
}

.ticket-config-nota i {
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--primary, #d2f365);
  font-size: 15px;
}

.ticket-config-nota strong {
  color: var(--text, #f4f4f3);
  font-weight: 700;
}

/* La salida para quien SI vende: visible, pero no compitiendo con lo de arriba. */
.ticket-config-nota-venta {
  display: block;
  margin-top: 6px;
  color: var(--text-soft, #757c5d);
}

/* Cada fila pasa a tener dos lineas: que es, y para que sirve. */
.ticket-config-row-texto {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
  text-align: left;
}

.ticket-config-help {
  font-size: 11.5px;
  line-height: 1.45;
  font-weight: 400;
  color: var(--text-soft, #757c5d);
}

.ticket-config-row--principal {
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.03);
  padding-left: 14px;
  padding-right: 14px;
}

/* Apagado: los ajustes siguen visibles -para saber que existen- pero no
   invitan a tocarlos, porque no harian nada. */
.ticket-config-ajustes {
  transition: opacity 0.18s ease;
}

.ticket-config-ajustes.is-apagado {
  opacity: 0.42;
  pointer-events: none;
}

@media (max-width: 480px) {
  .ticket-config-nota {
    font-size: 12.5px;
  }
  .ticket-config-help {
    font-size: 11px;
  }
}

/* --- Line-up del evento -------------------------------------------------

   Antes, para nombrar a un artista habia que encontrarlo en la base de usuarios
   de DondeVoy o mandarle una invitacion. Aqui se escribe y ya. El formulario es
   deliberadamente pequeno -nombre, Instagram opcional, Anadir- porque un cartel
   se rellena de seguido: escribes, Enter, escribes, Enter.
   ---------------------------------------------------------------------- */

.post-lineup-panel {
  max-width: 520px;
}

.lineup-alta {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 14px 0 6px;
}

.lineup-alta-fila {
  display: flex;
  gap: 8px;
}

.lineup-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text, #f4f4f3);
  font-family: inherit;
  font-size: 14px;
}

.lineup-input::placeholder {
  color: var(--text-soft, #757c5d);
}

.lineup-input:focus {
  outline: none;
  border-color: rgba(210, 243, 101, 0.45);
  background: rgba(255, 255, 255, 0.06);
}

.lineup-add-btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

.lineup-error {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: #ff9a6c;
}

/* Sugerencias: una ayuda, nunca un requisito. Por eso van despues del boton de
   anadir y no delante, y no bloquean nada. */
.lineup-sugerencias {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 2px 0;
}

.lineup-sug-titulo {
  width: 100%;
  font-size: 11.5px;
  color: var(--text-soft, #757c5d);
}

.lineup-sug {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border-radius: 999px;
  border: 1px solid rgba(210, 243, 101, 0.3);
  background: rgba(210, 243, 101, 0.1);
  color: var(--primary, #d2f365);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.lineup-lista {
  display: flex;
  flex-direction: column;
  margin-top: 14px;
}

.lineup-fila {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 2px;
}

.lineup-fila + .lineup-fila {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

/* El numero de orden: un cartel tiene cabeza y no es alfabetico. */
.lineup-pos {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  display: inline-grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-soft, #757c5d);
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.lineup-datos {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.lineup-nombre {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--text, #f4f4f3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lineup-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.lineup-tag {
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(210, 243, 101, 0.14);
  color: var(--primary, #d2f365);
  font-size: 10.5px;
  font-weight: 700;
}

.lineup-ig {
  color: var(--text-muted, #c7d2a5);
  font-size: 12px;
  text-decoration: none;
}

.lineup-ig:hover {
  color: var(--text, #f4f4f3);
}

.lineup-quitar {
  flex: 0 0 auto;
}

.lineup-vacio {
  text-align: center;
  padding: 26px 12px 8px;
  color: var(--text-soft, #757c5d);
}

.lineup-vacio i {
  font-size: 30px;
  opacity: 0.35;
  display: block;
  margin-bottom: 12px;
}

.lineup-vacio p {
  margin: 0 0 4px;
  font-size: 14px;
  color: var(--text-muted, #c7d2a5);
}

.lineup-vacio span {
  font-size: 12.5px;
}

@media (max-width: 480px) {
  .lineup-alta-fila {
    flex-direction: column;
  }
  .lineup-add-btn {
    width: 100%;
    justify-content: center;
  }
}

/* --- Colaboradores: un solo sitio --------------------------------------

   Eran dos modales encadenados con dos botones gigantes a ancho completo y
   una caja vacia enorme debajo. Para anadir a alguien habia que abrir el
   segundo modal, buscar, pulsar "Listo" y volver al primero a ver si habia
   pasado algo. Y el boton de invitar leia un campo que estaba en el otro
   modal, asi que no hacia nada.

   Ahora es uno: buscador arriba, resultados justo debajo, lista al final. El
   mismo campo sirve para buscar y para invitar por email.
   ---------------------------------------------------------------------- */

.colab-alta {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 14px 0 4px;
}

.colab-buscar {
  position: relative;
  display: flex;
  align-items: center;
}

.colab-buscar-ic {
  position: absolute;
  left: 14px;
  font-size: 13px;
  color: var(--text-soft, #757c5d);
  pointer-events: none;
}

.colab-input {
  width: 100%;
  padding: 12px 14px 12px 38px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text, #f4f4f3);
  font-family: inherit;
  font-size: 14px;
}

.colab-input::placeholder {
  color: var(--text-soft, #757c5d);
}

.colab-input:focus {
  outline: none;
  border-color: rgba(210, 243, 101, 0.45);
  background: rgba(255, 255, 255, 0.06);
}

/* Los resultados aparecen bajo el campo y no ocupan sitio si no hay nada:
   la caja vacia permanente era la mitad del problema visual. */
.colab-resultados:empty {
  display: none;
}

.colab-sin-resultados {
  padding: 10px 2px;
  line-height: 1.5;
}

.colab-sin-resultados strong {
  color: var(--text-muted, #c7d2a5);
}

/* Invitar deja de ser un boton suelto del tamano de la pantalla y pasa a ser
   lo que es: la salida para cuando la busqueda no encuentra a nadie. */
.colab-invitar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px dashed rgba(255, 255, 255, 0.12);
}

.colab-invitar-texto {
  font-size: 12.5px;
  color: var(--text-soft, #757c5d);
}

.colab-invitar-btn {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: 13px;
}

.colab-lista {
  margin-top: 8px;
  min-height: 0;
}

@media (max-width: 480px) {
  .colab-invitar {
    flex-direction: column;
    align-items: stretch;
  }
  .colab-invitar-btn {
    width: 100%;
    justify-content: center;
  }
}

/* --- Tamaño de los paneles de line-up y colaboradores -------------------

   Por debajo de 900 px estos modales van a pantalla completa a propósito
   (07-feed-4.css). Eso se respeta; lo que estaba roto era el cómo:

   1. `width: 100vw`. `100vw` NO descuenta la barra de scroll, así que en
      cuanto hay barra el panel es ~25 px más ancho que el hueco real y
      aparece scroll horizontal. Se mide contra el contenedor (`100%`), que sí
      la descuenta. Hace falta la misma especificidad (con el id) para poder
      corregirlo.

   2. La lista es un grid que se estira con el panel, así que con una sola
      fila esa fila se iba al fondo y quedaba un palmo de vacío en medio. El
      contenido se alinea arriba, que es como se lee una lista.

   Y por encima de 900 px, 880 px de ancho para una lista de nombres era
   demasiado: el ojo tenía que cruzar la pantalla entera para ir del nombre al
   botón de quitar.
   ---------------------------------------------------------------------- */

.post-artists-panel,
.post-lineup-panel {
  width: min(560px, 100% - 28px);
  height: auto;
  max-height: min(760px, 100dvh - 28px);
  overflow-y: auto;
  overflow-x: hidden;
}

@media (max-width: 900px) {
  #postArtistsModal .post-artists-panel,
  #postLineupModal .post-lineup-panel {
    width: 100%;
    min-width: 0;
    max-width: 100%;
  }
}

/* El contenido, arriba. No repartido por todo el alto de la pantalla. */
#postArtistsModal .post-artists-inline-list,
#postLineupModal .lineup-lista {
  align-content: start;
}

/* La lista deja de ser una caja con borde y suelo propio: dentro de un panel
   que ya es una caja, era una caja dentro de otra. */
.post-artists-panel .post-artists-inline-list {
  min-height: 0;
  border: 0;
  background: transparent;
  padding: 0;
}

/* Las filas se reparten como las del line-up: avatar, datos y la acción a la
   derecha, sin que el nombre y el botón queden a dos palmos. */
.post-artists-panel .post-invite-item,
.post-artists-panel .post-owner-search-item {
  min-height: 0;
  padding: 10px 2px;
}

.post-artists-panel .post-invite-actions-stack {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* --- Resultados de la búsqueda de colaboradores -------------------------

   Estaban en bruto: cada fila llevaba un botón `primary` lima a tamaño
   completo, así que lo único que se veía de la pantalla era una columna verde
   chillón de once botones. Y la etiqueta "Usuario" se repetía en todas las
   filas sin distinguir nada, porque la llevaban todas.

   El botón de añadir pasa a ser un círculo discreto que solo se enciende al
   pasar por encima: la acción está, pero no grita.
   ---------------------------------------------------------------------- */

.colab-resultados {
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Con seis resultados no hace falta scroll propio; si lo hubiera, sería un
     scroll dentro de otro scroll. */
  max-height: none;
  overflow: visible;
}

.colab-resultados .post-artist-candidate-item {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 0;
  padding: 8px 10px;
  border-radius: 12px;
  transition: background 0.14s ease;
}

.colab-resultados .post-artist-candidate-item:hover {
  background: rgba(255, 255, 255, 0.04);
}

.colab-resultados .post-owner-search-avatar {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}

.colab-resultados .post-owner-search-main {
  font-size: 14px;
  font-weight: 600;
  color: var(--text, #f4f4f3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.colab-resultados .post-owner-search-sub {
  font-size: 11.5px;
  color: var(--text-soft, #757c5d);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Aquí estaba el ruido: un botón lima sólido por fila. Ahora es un círculo
   apagado que se enciende al acercarse. */
.colab-resultados .post-artist-add-btn {
  width: 32px;
  height: 32px;
  min-width: 32px;
  /* `.post-artist-add-btn` trae min-height:38px de 06-post-editor.css, y la
     regla global `input, select, button { height: 44px }` de 00-base.css tira
     de este botón hacia arriba. Sin esto sale un óvalo de 32x38 en vez de un
     círculo. */
  min-height: 32px;
  padding: 0;
  border-radius: 999px;
  display: inline-grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-muted, #c7d2a5);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease;
}

.colab-resultados .post-artist-candidate-item:hover .post-artist-add-btn,
.colab-resultados .post-artist-add-btn:hover,
.colab-resultados .post-artist-add-btn:focus-visible {
  background: rgba(210, 243, 101, 0.16);
  border-color: rgba(210, 243, 101, 0.45);
  color: var(--primary, #d2f365);
}

.colab-mas {
  padding: 8px 10px 2px;
  font-size: 11.5px;
  color: var(--text-soft, #757c5d);
}

/* --- Invitaciones enviadas (ficha del evento) ---------------------------

   La fila eran tres bloques sueltos: el email arriba, la etiqueta "Pendiente"
   cayéndose a una segunda línea debajo, y "Copiar link" a media pantalla de
   distancia. No parecían la misma fila.

   Ahora: email a la izquierda, estado pegado a él, acción a la derecha. Y el
   <input readonly> con la URL entera que había dentro se quitó — nadie lee una
   URL de 60 caracteres, para eso está el botón de copiar.
   ---------------------------------------------------------------------- */

.invite-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 0;
  padding: 10px 2px;
}

.invite-fila + .invite-fila {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.invite-datos {
  flex: 1 1 auto;
  min-width: 0;
}

.invite-email {
  font-size: 13.5px;
  color: var(--text, #f4f4f3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.invite-estado {
  flex: 0 0 auto;
}

.invite-fila .post-invite-copy-btn {
  flex: 0 0 auto;
  white-space: nowrap;
  font-size: 12.5px;
}

.invite-aceptada {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--primary, #d2f365);
}

/* La URL en un input readonly dentro de la fila solo servía para ensancharla. */
.invite-fila .post-invite-link-field {
  display: none;
}

@media (max-width: 480px) {
  .invite-fila {
    flex-wrap: wrap;
  }
  .invite-datos {
    flex: 1 1 100%;
  }
}

/* --- Pestaña "Artistas" de la ficha -------------------------------------

   Va dentro de la columna derecha del modal, que en escritorio mide ~378 px.
   La fila de invitación (email + estado + acción) no cabe en esa anchura en una
   sola línea, así que se envuelve: identidad arriba, estado y acción debajo.
   No es un caso de móvil — es el ancho normal de esa columna.
   ---------------------------------------------------------------------- */

.detail-tab-panel .invite-fila {
  flex-wrap: wrap;
  row-gap: 6px;
  padding: 10px 0;
}

.detail-tab-panel .invite-datos {
  flex: 1 1 100%;
}

.detail-tab-panel .invite-estado {
  margin-left: 0;
}

.detail-tab-panel .invite-fila .post-invite-copy-btn {
  margin-left: auto;
}

/* Los títulos de sección respiran y se distinguen del contenido. */
.detail-tab-panel .post-owner-search-section-title {
  margin: 14px 0 6px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-soft, #757c5d);
}

.detail-tab-panel .post-owner-search-section-title:first-child {
  margin-top: 2px;
}

.detalle-vacio {
  padding: 14px 2px;
  color: var(--text-soft, #757c5d);
}

/* --- Filas del line-up en la ficha --- */

.lineup-fila-detalle {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 0;
  padding: 9px 0;
}

.lineup-fila-detalle + .lineup-fila-detalle {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.lineup-fila-detalle .post-owner-search-avatar {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  object-fit: cover;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-soft, #757c5d);
  font-size: 13px;
}

.lineup-fila-detalle .post-owner-search-main {
  font-size: 14px;
  font-weight: 700;
  color: var(--text, #f4f4f3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lineup-fila-detalle .lineup-ig {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  color: var(--text-muted, #c7d2a5);
  text-decoration: none;
}

.lineup-fila-detalle .lineup-ig:hover {
  color: var(--primary, #d2f365);
}

/* --- El fondo negro de las listas de la ficha ---------------------------

   `#detailArtistsList` y `#detailArtistInvitesManage` venían con
   `background: rgba(8,8,8,0.7)`: un negro casi opaco, sin borde, sin radio y
   sin padding, metido dentro de un panel que SÍ es una caja (degradado
   #1a1b24 → #12121a, borde claro, radio 20). El resultado era un rectángulo
   plano recortado contra el panel, que es lo que se veía mal — no el color en
   sí, sino una caja dentro de otra sin relación entre las dos.

   La caja ya la pone el panel. Estas listas se vuelven transparentes y la
   separación la hacen los títulos de sección y las líneas finas entre filas,
   como en la agenda. Es el mismo criterio que se aplicó al panel de
   colaboradores.
   ---------------------------------------------------------------------- */

#detailArtistsList,
#detailArtistInvitesManage,
.detail-tab-panel .post-artists-assigned-list {
  background: transparent;
  border: 0;
  padding: 0;
}

/* Las invitaciones sí se separan del cartel: son otra cosa (gente que todavía
   no ha aceptado). Una línea, no una caja. */
#detailArtistInvitesManage {
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

#detailArtistInvitesManage:empty {
  display: none;
}

/* Las filas se encienden al pasar por encima, en vez de vivir sobre un fondo
   plano permanente. */
.detail-tab-panel .lineup-fila-detalle,
.detail-tab-panel .invite-fila {
  border-radius: 10px;
  padding-left: 8px;
  padding-right: 8px;
  margin-left: -8px;
  margin-right: -8px;
  transition: background 0.14s ease;
}

.detail-tab-panel .lineup-fila-detalle[role="button"]:hover {
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
}

/* --- El editor de evento en vertical ------------------------------------

   Mismo patrón que ya apareció en los modales de colaboradores: por debajo de
   640 px el panel va a pantalla completa con `width: 100vw`, y `100vw` NO
   descuenta la barra de scroll. El panel quedaba ~15 px más ancho que el hueco
   real y aparecía scroll horizontal en un formulario, que es donde peor sienta.

   Se corrige con la misma especificidad (hace falta el id) midiendo contra el
   contenedor.
   ---------------------------------------------------------------------- */

@media (max-width: 860px) {
  #postModal .post-panel-compose {
    width: min(680px, 100% - 22px);
  }
}

@media (max-width: 640px) {
  #postModal .post-panel-compose,
  #postInstagramImportModal .post-import-modal {
    width: 100%;
    min-width: 0;
    max-width: 100%;
  }
}

/* El cartel subido medía 412 px de alto dentro de un panel de 680: dejaba el
   resto del formulario fuera de pantalla y obligaba a hacer scroll para
   descubrir que había más. Una vista previa es una confirmación de que la
   imagen correcta está puesta, no la imagen en tamaño real. */
.post-compose-dropzone img,
.post-compose-dropzone .upload-preview img,
#postImagePreview img {
  max-height: 42vh;
  width: auto;
  object-fit: contain;
}

@media (max-height: 720px) {
  .post-compose-dropzone img,
  .post-compose-dropzone .upload-preview img,
  #postImagePreview img {
    max-height: 34vh;
  }
}

/* --- Con un modal abierto, el fondo no se mueve -------------------------

   ESTA es la causa de raíz del scroll horizontal que aparecía en todos los
   modales, y la había introducido este mismo archivo.

   `body.modal-open { overflow: hidden }` (04-feed-2.css) existe desde siempre y
   es lo que bloquea el fondo mientras hay un modal. Pero la regla de más arriba
   —`body[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"]
   { overflow: auto }`, la que devuelve el scroll normal a la agenda— tiene
   bastante más especificidad y la anulaba. Desde que la agenda es el inicio,
   ningún modal bloqueaba el fondo.

   Consecuencia: la barra de scroll del documento seguía ocupando ~15 px con el
   modal abierto. Y como medio CSS del proyecto dimensiona los paneles con
   `100vw` —que NO descuenta la barra— cada modal quedaba 15 px más ancho que el
   hueco real y aparecía scroll horizontal. Son 76 reglas repartidas en 12
   archivos; no hay que tocar ninguna: basta con que no haya barra.

   El segundo efecto es igual de importante: se acabó el fondo desplazándose por
   detrás del modal al hacer scroll.
   ---------------------------------------------------------------------- */

body.modal-open,
body.modal-open[data-inicio-modo="agenda"].tt-feed-active[data-main-tab="posts"],
body.modal-open[data-inicio-modo="feed"].tt-feed-active[data-main-tab="posts"] {
  overflow: hidden;
}

/* --- El editor de evento en vertical: cabecera, contenido, botones ------

   Tres cosas que se veian mal en 430 px de ancho.

   1. Los botones "Publicar" / "Guardar para mas tarde" flotaban por encima del
      formulario. No era una decision de este modal: `.post-actions`
      (09-admin.css) es `position: sticky; bottom: 0` para TODOS los paneles, y
      el editor lo heredaba. Tapaban el ultimo campo, que en vertical es
      justamente el que estas rellenando. Van al final, en su sitio.

   2. El panel entero scrolleaba. Con el paso de datos abierto eso son 1065 px
      de formulario dentro de una pantalla de 680: la cabecera con "Siguiente"
      se iba arriba y te quedabas sin saber en que paso estabas ni como salir.
      Ahora la columna es fija (cabecera / contenido / botones) y lo unico que
      se mueve es el contenido.

   3. `--post-sections-height` le impone al carrusel el alto exacto del paso.
      Eso es lo correcto en horizontal, donde hay sitio; en vertical convierte
      el panel en un documento larguisimo. En vertical el paso ocupa el hueco
      que haya y scrollea por dentro.
   ---------------------------------------------------------------------- */

@media (max-width: 640px) {
  #postModal .post-panel-compose {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    max-height: 100dvh;
    overflow: hidden;
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
  }

  #postModal .post-panel-compose .post-head-compose {
    flex: 0 0 auto;
    margin-bottom: 10px;
  }

  #postModal .post-panel-compose #postSections.post-sections-compose {
    flex: 1 1 auto;
    /* Sin esto un hijo flex no baja de su contenido y no scrollea nada. */
    min-height: 0;
    height: auto;
    max-height: none;
    overflow-y: auto;
    overflow-x: hidden;
    /* Que el ultimo campo no quede pegado a los botones. */
    padding-bottom: 8px;
    -webkit-overflow-scrolling: touch;
  }

  #postModal .post-panel-compose #postSections.post-sections-compose .post-section.is-active {
    height: auto;
  }
}

/* Los botones, al final del formulario y no encima. Fuera de la media query
   porque en horizontal el problema es el mismo, solo que se nota menos. */
#postModal .post-panel-compose .post-actions-compose {
  position: static;
  bottom: auto;
  z-index: auto;
  flex: 0 0 auto;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(210, 243, 101, 0.16);
}

/* --- El hueco negro de la topbar --------------------------------------

   Lo que se veia: la barra superior ocupaba 360 px de negro con las tres
   lupas flotando en medio y nada mas. No habia nada que ver ahi, y aun asi
   empujaba la agenda casi media pantalla hacia abajo.

   La causa: el buscador cerrado se esconde con
   `#searchCluster { max-width: 0; opacity: 0; overflow: hidden }`
   (14-base-3.css). `max-width: 0` colapsa el ANCHO, no el ALTO. Y con cero
   ancho, los chips de dentro ("Hoy", "Mañana", "Este finde", "Gratis",
   "techno", "hardcore") no caben en fila y se apilan uno por linea: siete
   lineas de contenido invisible que si reservan alto. Cuantos mas chips,
   mas negro.

   Se cierra tambien en vertical. La transicion lo acompaña para que siga
   abriendose y cerrandose con la misma animacion.
   ---------------------------------------------------------------------- */

body.tt-feed-active[data-main-tab="posts"] #searchCluster {
  height: 0;
  transition:
    max-width 0.28s ease,
    height 0.28s ease,
    opacity 0.22s ease,
    transform 0.28s ease;
}

body.tt-feed-active[data-main-tab="posts"] .topbar.is-searching #searchCluster {
  height: auto;
}

/* --- Calendario de eventos --------------------------------------------

   El panel se abria sin respirar: el titulo pegado al aspa, la rejilla
   tocando los bordes y la leyenda como una linea de texto suelta abajo a la
   izquierda, sin relacion visual con lo que explica.
   ---------------------------------------------------------------------- */

#agendaModal .agenda-modal-panel {
  gap: 14px;
  padding: 16px 16px calc(env(safe-area-inset-bottom, 0px) + 16px);
}

#agendaModal .agenda-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

#agendaModal .agenda-modal-head h3 {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  /* Cabia justo hasta que el aspa se le echaba encima. */
  font-size: clamp(17px, 4.6vw, 21px);
  letter-spacing: -0.01em;
}

#agendaModal .agenda-modal-head .modal-close {
  position: static;
  flex: 0 0 auto;
}

/* La leyenda explica dos iconos: que se lea como una leyenda y no como el
   pie de un documento. */
#agendaModal .agenda-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid rgba(210, 243, 101, 0.14);
  font-size: 12px;
  color: var(--text-soft, #757c5d);
}

#agendaModal .agenda-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

#agendaModal .agenda-legend i {
  color: var(--text-muted, #c7d2a5);
  font-size: 11px;
}

@media (max-width: 640px) {
  /* Los dias son botones que se pulsan con el pulgar: un cuadrado, no una
     tira aplastada. */
  #agendaModal .feed-calendar-cell {
    aspect-ratio: 1 / 1;
    min-height: 0;
  }
}

/* --- Los chips de busqueda, en una fila ---------------------------------

   `#searchChips` no tenia ninguna regla: era un `div` normal, asi que sus
   seis botones se apilaban uno por linea. Con el buscador abierto eso son
   360 px de topbar, y cada chip nuevo suma otra linea. Es ademas la otra
   mitad del hueco negro de arriba: cerrado no se veian, pero seguian
   apilados.

   Una fila que se desliza, que es como se navegan los filtros con el pulgar.
   ---------------------------------------------------------------------- */

#searchChips.search-chips {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  /* Que el primero y el ultimo no queden cortados contra el borde. */
  padding: 2px 2px 4px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}

#searchChips.search-chips::-webkit-scrollbar {
  display: none;
}

#searchChips.search-chips .search-chip {
  flex: 0 0 auto;
  white-space: nowrap;
  scroll-snap-align: start;
}

/* --- Por que el formulario se cortaba a media frase ---------------------

   Lo que se veia: el campo "Colaboradores" aparecia partido por la mitad y
   borroso, y debajo solo negro, aunque la barra de scroll decia que habia
   mas. Scrollear no arreglaba nada: siempre se cortaba en el mismo punto.

   La causa no estaba en nada de lo que se toco hasta ahora. Es el sistema de
   pasos tipo carrusel (09-admin.css): cada `.post-section` es
   `position: absolute; inset: 0` con un `clip-path` que la recorta
   exactamente al tamaño de `#postSections`, para animar la transicion entre
   pasos con un desvanecido. Con el alto fijo de escritorio (
   `--post-sections-height`, calculado por JS para caber TODO el paso) el
   recorte no se notaba: la caja ya media lo que hacia falta.

   En vertical el bloque de arriba (`height: auto` en el propio media query)
   hace que `#postSections` mida solo el hueco que le queda tras la cabecera y
   los botones — bastante menos que el paso completo. La caja del paso sigue
   siendo `inset: 0`, así que se encoge con el contenedor, y el `clip-path`
   sigue recortando al ras de esa caja. Todo lo que no cabe ahi se pierde:
   no es que falte scroll, es que el contenido real esta cortado ANTES de
   llegar a la zona que se puede scrollear.

   El desvanecido solo hace falta para animar el cambio DE UN PASO A OTRO. En
   vertical el contenedor ya no tiene un alto fijo que anime (usa `height:
   auto`), asi que el paso activo se puede devolver al flujo normal: ocupa lo
   que su contenido pida y es `#postSections`, ya con su `overflow-y: auto`,
   quien decide que se scrollea.
   ---------------------------------------------------------------------- */

@media (max-width: 640px) {
  #postModal .post-panel-compose #postSections.post-sections-compose .post-section.is-active {
    position: static;
    inset: auto;
    padding-top: 0;
    clip-path: none;
    filter: none;
    transform: none;
  }
}

/* =============================================================================
   EL CARTEL COMO TARJETA FLOTANTE EN PC, NO A SANGRE

   Ya se limito el ANCHO de `.tt-slide-frame` a la proporcion del cartel (ver
   "EXPLORAR CON FORMA DE MOVIL EN VERTICAL" mas arriba), asi que la botonera
   iba pegada al contenido y no perdida en el borde de la ventana. Pero el
   cartel seguia ocupando el 100% del ALTO de la pantalla con esquinas a
   escuadra: en un monitor ancho quedaba un rectangulo perfecto tocando arriba
   y abajo, flotando en un vacio negro sin mas relacion con el resto de la
   interfaz. TikTok en PC no hace eso: ahi el video es una TARJETA -esquinas
   redondeadas, sombra propia, aire arriba y abajo- no un recorte de pantalla
   completa reubicado al centro.

   El aire se pone en el propio cartel (`margin-block`), no en el marco: asi
   la formula del ancho (que ya depende de la altura disponible) no hay que
   tocarla, y la botonera sigue centrada a su misma altura porque comparte
   contenedor con el cartel.
   ============================================================================= */

@media (min-width: 1025px) {
  body[data-inicio-modo="feed"] .tt-media-card {
    margin-block: 28px;
    border-radius: 20px;
    overflow: hidden;
    box-shadow:
      0 30px 70px rgba(0, 0, 0, 0.55),
      0 0 0 1px rgba(210, 243, 101, 0.1);
  }

  /* El vacio alrededor de la tarjeta deja de ser negro plano: un resplandor
     muy tenue centrado, como el halo que usan los reproductores de musica
     alrededor de una portada. No compite con el cartel, solo evita que la
     pantalla parezca rota. */
  body[data-inicio-modo="feed"] .tt-slide-event,
  body[data-inicio-modo="feed"] .tt-slide-panel {
    background: radial-gradient(60% 55% at 50% 50%, rgba(130, 108, 246, 0.12), transparent 72%);
  }
}

/* --- El modo mirar (pulsacion mantenida) debe ensenar el cartel ENTERO ---

   `body.tt-peeking` quita toda la interfaz para dejar solo la imagen (ver
   14-base-3.css), pero la imagen seguia con `object-fit: cover`: la misma
   regla que recorta el cartel en el feed normal para llenar la tarjeta
   9:16/10:16. Eso esta bien cuando hay texto encima que hay que poder leer,
   pero el modo mirar existe justo para lo contrario -ver la foto sin nada
   encima- y ahi un cartel (que casi nunca es 9:16) seguia perdiendo los
   bordes. Mientras se mantiene pulsado se cambia a `contain`: el cartel
   completo, con barras de color detras en vez de recortado.
   ---------------------------------------------------------------------- */

body.tt-peeking .tt-media-img {
  object-fit: contain;
  background: #000;
}

/* --- Explorar debe encogerse cuando suena la radio/un set -----------------

   La barra de reproduccion (#communityLiveRadioBar) se ancla encima de la
   navegacion inferior cuando hay una emision o un set sonando
   (`body.sets-player-active` / `body.community-live-radio-active`), pero
   `#feed.is-social` seguia midiendo su alto SOLO contra la barra superior y
   la navegacion (`--tt-chrome-offset`), sin saber que la barra de radio
   tambien ocupa sitio. Resultado: la ultima pantalla del feed (el cartel, los
   iconos) quedaba por detras de la barra de radio, tapada.

   La botonera (`.tt-actions`) no hace falta tocarla: su `bottom` esta medido
   desde el propio borde inferior del cartel, asi que en cuanto el cartel
   encoge con el nuevo alto, la botonera se recoloca sola.
   ---------------------------------------------------------------------- */

@media (max-width: 980px) {
  body.sets-player-active #feed.is-social,
  body.community-live-radio-active #feed.is-social {
    --tt-chrome-offset: 176px;
  }
}

/* =============================================================================
   CARRUSEL DEL CARTEL EN EL FEED (fotos / mapa / musica)

   Restaurado: este bloque entero desaparecio por accidente en el commit
   "Grandes cambios" (2026-09-10), que recorto este mismo fichero de 1931 a 665
   lineas. El JS (app-feed-social.js: tt-gallery-dots, tt-piece, tt-gallery-nav,
   tt-gallery-counter...) nunca dejo de generar este marcado, asi que desde
   entonces el carrusel se pintaba sin ningun estilo: los puntos sin centrar, las
   piezas de mapa/musica una encima de otra sin "display:none" que las separe, y
   sin las flechas ni el contador. Recuperado tal cual de esa version anterior.
   ============================================================================= */
/* --- Carrusel del cartel dentro del feed -------------------------------------
   Los controles van por encima del degradado (`.tt-media-scrim`, que no recibe
   clics) y por debajo de la botonera lateral. En movil las flechas se esconden:
   ahi se pasa de foto deslizando y dos botones de 40px encima del cartel solo
   estorban al toque que abre el evento. */
.tt-gallery-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 4;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: rgba(8, 8, 10, 0.55);
  color: #fff;
  font-size: 13px;
  cursor: pointer;
  opacity: 0.85;
}

.tt-gallery-nav:hover {
  opacity: 1;
  background: rgba(8, 8, 10, 0.75);
}

.tt-gallery-nav.is-prev {
  left: 8px;
}

.tt-gallery-nav.is-next {
  right: 8px;
}

.tt-gallery-counter {
  position: absolute;
  top: var(--sp-4, 14px);
  right: var(--sp-4, 14px);
  z-index: 4;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(8, 8, 10, 0.6);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  pointer-events: none;
}

/* Los puntos viven DENTRO del bloque de texto, como primera linea y encima del
   dia. Antes iban sobre la foto a `bottom: 38%` -un porcentaje elegido a ojo
   para esquivar el titulo- y ahi no leian como el indice de un carrusel: leian
   como una mancha en mitad del cartel. En el flujo del texto se colocan solos
   por encima del titulo, sin porcentaje que se rompa cuando el titulo ocupa dos
   lineas.

   Centrados en la fila. A plomo con el dia y el titulo dejaban un punto y un
   icono arrinconados en la esquina con toda la linea vacia a su derecha: no
   leian como el indice de un carrusel, leian como un resto de otra cosa. El
   grupo centrado se sostiene igual con dos piezas que con ocho, y es donde ya
   se buscan los puntos de un carrusel. */
.tt-gallery-dots {
  display: flex;
  /* El grupo se centra en el ancho del bloque de texto; lo que no cambia es el
     texto de debajo, que sigue alineado a la izquierda. */
  justify-content: center;
  /* La fila mezcla puntos de 7px con iconos mas altos. Sin centrarlos en el eje
     transversal cada uno se apoyaba en el borde de arriba y la fila salia
     escalonada. Un alto comun para todos los indicadores hace que las cajas
     midan igual aunque el simbolo de dentro no. */
  align-items: center;
  min-height: 16px;
  /* Separacion pequena porque cada caja ya trae su propio aire: el punto mide
     7px dentro de 16px, asi que un hueco de 7px aqui se veia como 16px y la fila
     quedaba desperdigada en vez de leerse como un indice. */
  gap: 2px;
  margin-bottom: 6px;
}

/* Todos los indicadores ocupan la MISMA caja (16x16) y dibujan dentro lo suyo:
   un punto de 7px las fotos, un glifo las piezas de mapa y musica. Antes cada
   uno tenia su propio tamano de caja y la fila salia escalonada, con el icono
   pisando la linea de abajo. */
.tt-gallery-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.tt-gallery-dot:not(.is-icon)::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.42);
  transition: background 0.16s ease, transform 0.16s ease;
}

/* Zona de toque real. El punto mide 7px y con el dedo eso no se acierta: sobre
   la foto casi daba igual porque nadie los pulsaba, pero ahora estan en el
   bloque de texto y si invitan a tocarlos. El area crece; el punto no.

   A los lados crece 1px: justo la mitad del hueco de 2px, asi las areas de dos
   puntos vecinos se tocan pero no se montan. Con 2px se solapaban y en la banda
   compartida ganaba siempre el de la derecha, asi que a veces se pasaba a la
   foto equivocada. */
.tt-gallery-dot::after {
  content: "";
  position: absolute;
  inset: -6px -1px;
}

.tt-gallery-dot:not(.is-icon).is-active::before {
  background: #fff;
  transform: scale(1.3);
}

/* Mientras se mantiene pulsado para mirar el cartel, los controles estorban. */
body.tt-peeking .tt-gallery-nav,
body.tt-peeking .tt-gallery-counter,
body.tt-peeking .tt-gallery-dots {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}

@media (hover: none), (max-width: 760px) {
  .tt-gallery-nav {
    display: none;
  }
}

/* Flecha en el extremo del carrusel: sin foto a la que ir. Se apaga y deja de
   recibir el dedo, para que no parezca un boton roto. */
.tt-gallery-nav.is-disabled {
  opacity: 0.22;
  pointer-events: none;
}

/* --- Piezas del carrusel -----------------------------------------------------
   El carrusel dejo de ser "las fotos del post": ahora recorre las caras de la
   fiesta -fotos, donde es, y a que suena quien la monta-. Cada pieza que no es
   una foto es una capa a pantalla completa dentro del mismo hueco, para que
   pasar de una foto al mapa se sienta como pasar de foto y no como abrir otra
   cosa. */
.tt-piece {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: none;
  flex-direction: column;
  background: #0a0b0d;
}

.tt-piece.is-active {
  display: flex;
}

.tt-media-img.is-hidden {
  visibility: hidden;
}

.tt-piece-map {
  flex: 1;
  min-height: 0;
  background: #11131a;
}

/* Sin coordenadas o sin libreria no se deja un rectangulo gris mudo. */
.tt-piece-map.is-empty::after {
  content: "";
  display: block;
  height: 100%;
  background:
    radial-gradient(circle at 30% 30%, rgba(210, 243, 101, 0.09), transparent 60%),
    repeating-linear-gradient(45deg, #12141a 0 12px, #0f1116 12px 24px);
}

/* El pie se aparta del bloque de texto del cartel, que se pinta ENCIMA de esta
   capa. `--tt-overlay-h` lo mide el JS por tarjeta (`ttSyncOverlayHeight`): un
   numero fijo aqui se quedaria corto con un titulo de dos lineas o una direccion
   larga, que es justo cuando se solapaban las letras. El valor de reserva cubre
   el caso normal por si se pinta antes de la primera medida. */
.tt-piece-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px calc(14px + var(--tt-overlay-h, 132px));
  background: linear-gradient(180deg, rgba(8, 9, 11, 0), rgba(8, 9, 11, 0.92) 42%);
}

.tt-piece-place {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 700;
  color: #e9ebee;
}

.tt-piece-place i,
.tt-piece-cta i {
  color: var(--primary);
}

.tt-piece-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid rgba(220, 251, 116, 0.55);
  border-radius: 999px;
  color: var(--primary);
  font-size: 12.5px;
  font-weight: 800;
  text-decoration: none;
}

/* La musica: una sola pista por persona, centrada. No es una lista de
   reproduccion; es "a esto suena quien monta esto". */
.tt-piece-musica {
  align-items: center;
  justify-content: center;
  padding: 24px 18px calc(24px + var(--tt-overlay-h, 132px));
  background:
    radial-gradient(circle at 50% 35%, rgba(130, 108, 246, 0.22), transparent 62%),
    linear-gradient(180deg, #0d0e12, #08090b);
}

.tt-piece-music-inner {
  width: min(340px, 100%);
}

.tt-piece-kicker {
  margin: 0 0 12px;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.6);
  text-align: center;
}

.tt-piece-track {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.05);
}

.tt-piece-avatar {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.7);
}

.tt-piece-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tt-piece-track-copy {
  flex: 1;
  min-width: 0;
  display: grid;
  gap: 2px;
}

.tt-piece-track-copy strong {
  font-size: 14px;
  color: #f1f1f0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tt-piece-track-copy small {
  font-size: 11.5px;
  color: rgba(255, 255, 255, 0.55);
  text-transform: capitalize;
}

.tt-piece-play {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex: 0 0 auto;
  border: 0;
  border-radius: 999px;
  background: var(--primary);
  color: #161c04;
  font-size: 14px;
  cursor: pointer;
}

/* La entrada: el contenido nuevo llega DESDE EL LADO del que viene el gesto, asi
   el dedo y la pantalla cuentan la misma historia. Cambiar de golpe se leia como
   un parpadeo, no como haber pasado de pantalla. */
@keyframes ttPieceInNext {
  from { opacity: 0; transform: translateX(14%); }
  to { opacity: 1; transform: none; }
}

@keyframes ttPieceInPrev {
  from { opacity: 0; transform: translateX(-14%); }
  to { opacity: 1; transform: none; }
}

.tt-piece-in-next {
  animation: ttPieceInNext 0.26s ease-out;
}

.tt-piece-in-prev {
  animation: ttPieceInPrev 0.26s ease-out;
}

/* Quien pide menos movimiento no lo recibe: el cambio sigue ocurriendo, solo que
   sin desplazamiento. */
@media (prefers-reduced-motion: reduce) {
  .tt-piece-in-next,
  .tt-piece-in-prev {
    animation: none;
  }
}

/* Indicador de una pieza que no es foto: lleva su icono (mapa, musica) para que
   se sepa QUE hay detras antes de deslizar. Ensancha lo justo. */
.tt-gallery-dot.is-icon {
  color: rgba(255, 255, 255, 0.5);
  font-size: 11px;
  line-height: 1;
}

.tt-gallery-dot.is-icon.is-active {
  color: var(--primary);
}

/* Sin coordenadas la pieza no finge ser un mapa: una ficha centrada con el sitio
   y como llegar, con la MISMA forma que la pieza de musica. Que las dos piezas
   que no son foto se parezcan es lo que hace que se lean como pantallas del
   carrusel y no como huecos donde algo ha fallado.

   Se centra en el hueco VISIBLE: `--tt-overlay-h` descuenta el bloque de texto
   del cartel, que se pinta encima de esta capa. Centrar en la caja entera dejaba
   la ficha detras del titulo. */
.tt-piece-mapa.is-sin-mapa {
  align-items: center;
  justify-content: center;
  padding: 24px 18px calc(24px + var(--tt-overlay-h, 132px));
  background:
    radial-gradient(circle at 50% 38%, rgba(210, 243, 101, 0.14), transparent 62%),
    linear-gradient(180deg, #0d0e12, #08090b);
}

.tt-piece-centro {
  display: grid;
  justify-items: center;
  gap: 10px;
  width: min(320px, 100%);
  text-align: center;
}

.tt-piece-icono {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 999px;
  background: rgba(210, 243, 101, 0.12);
  color: var(--primary);
  font-size: 20px;
}

.tt-piece-lugar {
  font-size: 16px;
  line-height: 1.3;
  color: #f1f1f0;
}

.tt-piece-centro .tt-piece-kicker {
  margin: 0;
}

.tt-piece-centro .tt-piece-cta {
  margin-top: 4px;
}
