/* La tienda. Mobile-first sin framework: son cinco pantallas que tienen que ir
   muy rápidas, y el andamiaje de Gestión aquí solo pesaría (M1). */

/* La marca GoPass.In (guía de gopass_platform/docs/marca/GUIA_MARCA.md, Luis,
   5-oct-2026; aplicada aquí el 6-oct). Fuentes servidas desde la propia pieza,
   no desde un CDN de terceros: Montserrat en títulos, Inter en el texto. Su
   licencia (OFL) va al lado, en app/assets/fonts/gopassin/. */
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap;
             src: url("/assets/gopassin/inter-latin-400-normal-1e94a563.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap;
             src: url("/assets/gopassin/inter-latin-500-normal-5949f5fc.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap;
             src: url("/assets/gopassin/inter-latin-600-normal-a957bd0d.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap;
             src: url("/assets/gopassin/inter-latin-700-normal-cbc762c0.woff2") format("woff2"); }
@font-face { font-family: "Montserrat"; font-style: normal; font-weight: 700; font-display: swap;
             src: url("/assets/gopassin/montserrat-latin-700-normal-4cbfa40d.woff2") format("woff2"); }
@font-face { font-family: "Montserrat"; font-style: normal; font-weight: 800; font-display: swap;
             src: url("/assets/gopassin/montserrat-latin-800-normal-a35a0e81.woff2") format("woff2"); }

:root {
  /* La paleta de la guía. */
  --marino: #0A1727;
  --marino-800: #13233A;
  --marino-700: #1E3350;
  --marino-500: #4A5D78;
  --marino-300: #A9B4C4;
  --marino-100: #E6EAF0;
  --marino-50: #F4F6F9;
  --rojo-marca: #E53935;      /* solo logo y detalles finos: NUNCA un relleno de botón */
  --error: #C62828;
  --error-fondo: #FDE8E7;
  --error-borde: #F4C2BF;
  --info: #0B7285;
  --info-fondo: #E0F3F6;
  --blanco: #FFFFFF;
  /* Las sombras, en marino y no en negro: la guía no admite el negro puro. */
  --sombra: 10, 23, 39;

  /* Los nombres de siempre, ya con la paleta. El botón principal es marino con
     texto blanco (contraste 18:1); el texto, marino, nunca negro puro. */
  --tinta: var(--marino);
  --tinta-suave: var(--marino-500);
  --fondo: var(--blanco);
  --fondo-alt: var(--marino-50);
  --borde: var(--marino-100);
  --borde-fuerte: var(--marino-300);
  --acento: var(--marino);
  --acento-tinta: var(--blanco);
  --aviso: #8A5A00;
  --aviso-fondo: #FFF4D6;
  --bien: #17794B;
  --bien-fondo: #E3F4EC;
  --apagado: var(--marino-300);

  /* El plano: estos son FUNCIONALES, no de marco (guía, «En el plano»). */
  --butaca-no-disponible: #D5DBE4;
  --butaca-rota: var(--error);
  --butaca-aviso: #F59E0B;

  --tipo: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --tipo-titulo: "Montserrat", var(--tipo);

  /* Tamaño táctil mínimo. Es un parámetro y no un número clavado (M8): se parte
     de 44 px y se calibra probando en un teléfono de verdad. */
  --tocable: 44px;

  --radio: 12px;
  --hueco: 16px;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--fondo);
  color: var(--tinta);
  font: 16px/1.5 var(--tipo);
  /* Sin rebote elástico: en un mapa a pantalla completa se confunde con el
     arrastre del propio mapa. */
  overscroll-behavior-y: none;
}

/* --- cabeceras ---------------------------------------------------------- */

/* UNA sola barra arriba. Antes eran dos —marca y contexto— y sumaban 230px de
   los 812 de un teléfono antes de enseñar una butaca. La marca se queda en una
   línea pequeña: es la tienda de alguien, pero lo que hay que leer sin dudar es
   QUÉ y CUÁNDO se está comprando. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  padding: 8px var(--hueco) 10px;
  background: var(--fondo);
  border-bottom: 1px solid var(--borde);
}

.topbar__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.topbar__brand { display: flex; align-items: center; min-width: 0; }
/* Pequeño a propósito: la cabecera es del contexto —qué y cuándo—, no de la
   marca (ver arriba). 22 px de alto se leen en un teléfono sin quitarle sitio. */
.topbar__logo { display: block; height: 22px; width: auto; }
/* El del organizador (K45): algo más alto, con su nombre al lado, que es lo
   que se lee. El alto manda; el ancho, el que dé su proporción. */
.topbar__brand { gap: 8px; }
.topbar__logo--org { height: 28px; max-width: 140px; object-fit: contain; }
.topbar__org {
  font: 700 13px/1.2 var(--tipo-titulo);
  color: var(--tinta);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.context {
  margin-top: 2px;
  display: flex;
  align-items: center;
  gap: 10px;
}

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

/* Solo el número. Lo que significa se cuenta al pasar por encima (title) en
   escritorio y con una frase en el carrito: un reloj con su explicación al
   lado ocuparía en el móvil una línea entera para decir algo que solo importa
   la primera vez que se ve. */
.context__clock[hidden] { display: none; }

.context__clock {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  color: var(--tinta-suave);
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--fondo-alt);
  border: 1px solid var(--borde);
  cursor: default;
}

/* El rojo se lo gana al final: un reloj que grita desde el minuto catorce mete
   prisa sin motivo, y uno que aparece de golpe pilla desprevenido a quien
   creía tener tiempo. */
.context__clock--warn {
  color: var(--error);
  border-color: var(--error-borde);
  background: var(--error-fondo);
}

.context__title {
  font-weight: 700;
  font-size: 16px;
  line-height: 1.25;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.context__meta { font-size: 13px; color: var(--tinta-suave); }

/* --- contenido ---------------------------------------------------------- */

.main {
  padding: var(--hueco);
  /* Aire al final para que el último elemento no quede pegado a la barra del
     navegador ni bajo la muesca. */
  padding-bottom: calc(var(--hueco) + env(safe-area-inset-bottom, 0px));
  max-width: 640px;
  margin: 0 auto;
}

.h1 { margin: 4px 0 6px; font: 800 22px/1.25 var(--tipo-titulo); }
.lead { margin: 0 0 18px; color: var(--tinta-suave); font-size: 14px; }
.foot { margin-top: 22px; }
.link { color: var(--acento); text-decoration: none; font-size: 14px; }

/* --- lista de fechas ---------------------------------------------------- */

.sessions { list-style: none; margin: 0; padding: 0; }

.session {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--borde);
}

.session--off { opacity: .55; }

/* El día, grande y a la izquierda: se escanea la columna sin leer.
   Alineado arriba y no al centro: si la fila crece —por un aviso, por un
   nombre de recinto largo— la columna de fechas tiene que seguir formando una
   línea recta, o deja de poder escanearse. */
.session__date {
  flex: 0 0 52px;
  align-self: flex-start;
  padding-top: 2px;
  text-align: center;
  line-height: 1;
}

.session__month {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--tinta-suave);
}

.session__day { display: block; font-size: 28px; font-weight: 700; }

.session__body { flex: 1 1 auto; min-width: 0; }
.session__when { font-weight: 600; font-size: 15px; }
.session__where {
  font-size: 13px;
  color: var(--tinta-suave);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.session__go { flex: 0 0 auto; align-self: flex-start; }

.badge {
  display: inline-block;
  margin-top: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
}

.badge--warn { background: var(--aviso-fondo); color: var(--aviso); }
.badge--gone { background: var(--fondo-alt); color: var(--tinta-suave); }

/* --- botones ------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tocable);
  padding: 0 18px;
  border: 0;
  border-radius: var(--radio);
  background: var(--acento);
  color: var(--acento-tinta);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  /* Sin retardo de 300 ms al tocar. */
  touch-action: manipulation;
}

.btn--small { min-height: 38px; padding: 0 14px; font-size: 14px; }
.btn--off { background: var(--fondo-alt); color: var(--apagado); }

/* --- quitar del carrito -------------------------------------------------- */

.cart__remove-form { flex: none; margin-left: 8px; }
.cart__remove {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%;
  background: var(--fondo-alt); color: var(--apagado);
  font-size: 18px; line-height: 1; cursor: pointer;
  touch-action: manipulation;
}
.cart__remove:hover { color: var(--tinta); }

/* --- descarga de entradas ------------------------------------------------ */

.download { margin: 20px 0; text-align: center; }
.download__btn { width: 100%; gap: 10px; }
.download__icon { flex: none; }

/* --- empezar otra compra ------------------------------------------------- */

/* Separado del pie por una línea: cierra la compra y abre la siguiente, así
   que no debe leerse como parte del texto que hay encima. */
.again {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--borde);
  text-align: center;
}
.again__btn { width: 100%; }

/* --- la bifurcación ----------------------------------------------------- */

.choices { display: grid; gap: 12px; }

.choice {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  padding: 14px 16px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--fondo);
  color: var(--tinta);
  text-decoration: none;
  touch-action: manipulation;
}

.choice--primary {
  border-color: var(--acento);
  background: var(--acento);
  color: var(--acento-tinta);
}

.choice__icon { font-size: 24px; line-height: 1; }
.choice__body { display: flex; flex-direction: column; }
.choice__title { font-weight: 700; font-size: 16px; }
.choice__hint { font-size: 13px; opacity: .8; }

/* --- avisos ------------------------------------------------------------- */

.notice { padding: 32px 0; }
.notice__title { margin: 0 0 8px; font-size: 20px; }
.notice__text { margin: 0; color: var(--tinta-suave); }

/* La confirmación se distingue de un aviso cualquiera por el color, pero no
   SOLO por el color: lleva su propio título y su propio texto. Quien no
   distingue verde de ámbar tiene que poder saber igual si ha comprado. */
.notice--ok {
  background: var(--bien-fondo);
  border-radius: var(--radio);
  padding: 24px 20px;
  margin-bottom: 20px;
}
.notice--ok .notice__title { color: var(--bien); }
.notice--ok .notice__text { color: var(--bien); }

/* --- formularios --------------------------------------------------------- */

.form { margin: 0 0 24px; }

.field { margin-bottom: 20px; }
.field__label {
  display: block;
  margin-bottom: 6px;
  font-size: 14px;
  font-weight: 600;
}
.field__input {
  width: 100%;
  /* 16px o más: por debajo de eso, Safari en iPhone hace zoom al enfocar el
     campo y descoloca la pantalla entera. Es la razón del número, no el gusto. */
  font-size: 16px;
  min-height: var(--tocable);
  padding: 10px 12px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--fondo);
  color: var(--tinta);
  -webkit-appearance: none;
  appearance: none;
}
.field__input:focus {
  outline: 2px solid var(--acento);
  outline-offset: 1px;
  border-color: var(--acento);
}
.field__hint { margin: 6px 0 0; font-size: 13px; color: var(--tinta-suave); }
.field__error { margin: 6px 0 0; font-size: 13px; color: var(--error); font-weight: 600; }
.field__warn {
  margin: 6px 0 0;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--aviso);
  background: var(--aviso-fondo);
  border-radius: 8px;
}
.field__warn-text { margin: 0 0 8px; }
.field__warn-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin: 0;
}
/* Los dos botones tienen que distinguirse por algo más que el color: el que
   corrige es un botón y el que insiste es un enlace. */
.field__warn-actions .link {
  background: none;
  border: 0;
  padding: 0;
  font-size: 13px;
  color: var(--aviso);
  text-decoration: underline;
  cursor: pointer;
  min-height: var(--tocable);
}

/* La casilla y su texto van juntos en una etiqueta: así el área tocable es la
   frase entera y no un cuadradito de 13 px, que en un móvil no se acierta. */
.check {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  min-height: var(--tocable);
  cursor: pointer;
}
.check__box { width: 22px; height: 22px; margin-top: 2px; flex: 0 0 auto; }
.check__text { font-size: 14px; color: var(--tinta-suave); line-height: 1.4; }

/* --- acceso a la cuenta -------------------------------------------------- */

.zonelist__price {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 14px;
  font-weight: 600;
  color: var(--tinta-suave);
  white-space: nowrap;
}
.zonelist__item--gone .zonelist__price { display: none; }

/* La descripción de la zona en su pantalla: aparte del bloque de compra. */
/* De qué bloque de la zona se está comprando: va pegado al título, porque es
   parte de dónde estás y no un dato más de la pantalla. */
.zone-block {
  margin: -4px 0 12px;
  font-size: 15px;
  font-weight: 600;
  color: var(--tinta-suave);
}

/* El bloque en una fila de la lista, cuando la zona tiene más de uno: si no,
   el mismo ítem en dos bloques son dos filas gemelas. */
.offer__block {
  margin-left: 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--tinta-suave);
}

.zone-about {
  margin: 2px 0 14px;
  max-width: 560px;
  font-size: 14px;
  color: var(--tinta-suave);
}

/* El globo de descripción de zona (escritorio): flota FUERA de la zona que
   se está mirando, hacia el lado con sitio. Lo coloca boot.js. */
.zonetip {
  position: absolute;
  max-width: 220px;
  padding: 10px 12px;
  background: rgba(255, 255, 255, 0.97);
  border: 1px solid var(--borde);
  border-radius: 10px;
  box-shadow: 0 4px 14px rgba(var(--sombra), 0.12);
  pointer-events: none;
  z-index: 4;
}
.zonetip__name { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.zonetip__text { margin: 0; font-size: 13px; color: var(--tinta-suave); }

/* La [i] de la zona en la lista (teléfono y donde no hay hover). */
.zonelist__info { margin-left: 8px; }
.zonelist__info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--borde);
  border-radius: 50%;
  font: italic 700 12px Georgia, serif;
  color: var(--tinta-suave);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.zonelist__info-btn::-webkit-details-marker { display: none; }
.zonelist__info[open] .zonelist__info-btn { background: var(--borde); }
.zonelist__info-text {
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--tinta-suave);
  flex-basis: 100%;
}

/* El plano de referencia, flotando en la esquina del mapa. Pequeño y
   atenuado: es orientación, no protagonista. */
.map__minimap {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 96px;
  height: 72px;
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid var(--borde);
  border-radius: 8px;
  cursor: pointer;
}

/* El mismo plano, en línea en la pantalla de aforo: ahí no flota sobre ningún
   mapa, y al ser la única pista espacial puede ser algo mayor. */
.map__minimap--inline {
  position: static;
  display: block;
  width: 180px;
  height: 135px;
  margin: 0 0 16px;
}

/* El globo del ratón. position:fixed no: vive dentro del contenedor del mapa
   y se coloca respecto a él. pointer-events:none para que el globo no robe el
   ratón de la butaca que lo abrió — sin eso parpadea. */
.seattip {
  position: absolute;
  z-index: 5;
  max-width: 240px;
  padding: 8px 10px;
  background: var(--marino);
  color: var(--blanco);
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.45;
  pointer-events: none;
  box-shadow: 0 4px 12px rgba(var(--sombra), 0.25);
}
.seattip strong { display: block; font-size: 14px; }
/* Sobre marino: el estado y el tipo, en los fondos claros de la paleta (que
   sobre marino se leen bien) y no en rojo: el rojo no es para la venta. */
.seattip .seattip__estado { color: var(--error-fondo); }
.seattip .seattip__tipo { color: var(--info-fondo); }

/* --- zona de aforo -------------------------------------------------------- */

.blockchoice { display: flex; flex-direction: column; gap: 10px; margin: 0 0 20px; }
.blockcard {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--tocable);
  padding: 12px 14px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  cursor: pointer;
}
.blockcard:has(.blockcard__radio:checked) { border-color: var(--acento); outline: 1px solid var(--acento); }
.blockcard__radio { width: 20px; height: 20px; flex: 0 0 auto; }
.blockcard__body { display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; }
.blockcard__name { font-weight: 600; }
.blockcard__price { color: var(--tinta-suave); }
.blockcard__left { font-size: 13px; color: var(--aviso); font-weight: 600; }

/* Cantidad como radios visuales: mismo aspecto que los botones de "elígelas
   por mí", pero dentro de un formulario. */
.qty__option--radio { position: relative; cursor: pointer; }
.qty__radio { position: absolute; opacity: 0; pointer-events: none; }
.qty__option--radio:has(.qty__radio:checked) {
  background: var(--acento);
  color: var(--acento-tinta);
  border-color: var(--acento);
}

.cart__includes {
  display: block;
  font-size: 13px;
  color: var(--tinta-suave);
  overflow-wrap: anywhere;
}
/* El texto largo del pack no puede empujar el importe fuera de la pantalla. */
.cart__seat { flex: 1 1 auto; min-width: 0; }
.cart__amount { flex: 0 0 auto; white-space: nowrap; }

.offers { display: flex; flex-direction: column; gap: 12px; margin: 0 0 16px; }
/* El título de cada grupo de ampliaciones, cuando hay dos o más categorías
   (opción B, 5-oct-2026). */
.offers__group-title {
  margin: 10px 0 -4px; font-size: 13px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--tinta-suave);
}
.offers__group-title:first-child { margin-top: 0; }
.offer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
}
.offer__info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.offer__name { font-weight: 600; }
.offer__price { font-size: 14px; color: var(--tinta); }
.offer__fee { color: var(--tinta-suave); font-size: 13px; }
.offer__seats { font-size: 13px; color: var(--tinta-suave); }
.offer__includes { font-size: 13px; color: var(--tinta-suave); }

.stepper { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.stepper__btn {
  width: var(--tocable);
  height: var(--tocable);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: var(--fondo);
  font-size: 22px;
  color: var(--tinta);
  cursor: pointer;
}
.stepper__value {
  width: 44px;
  height: var(--tocable);
  text-align: center;
  font-size: 16px;
  font-weight: 600;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  -moz-appearance: textfield;
  appearance: textfield;
}
.stepper__value::-webkit-inner-spin-button { -webkit-appearance: none; }

.offers__left { font-size: 14px; color: var(--tinta-suave); }

/* --- elígelas por mí ----------------------------------------------------- */

/* El selector de cantidad. Botones y no un desplegable: un <select> en un móvil
   abre una rueda que tapa media pantalla para elegir entre diez números. */
.qty { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 20px; }
.qty__option {
  min-width: var(--tocable);
  min-height: var(--tocable);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  font-size: 16px;
  font-weight: 600;
  color: var(--tinta);
  text-decoration: none;
}
.qty__option--on { background: var(--acento); color: var(--acento-tinta); border-color: var(--acento); }

.chip {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 12px;
  margin: 0 6px 6px 0;
  border: 1px solid var(--borde);
  border-radius: 999px;
  font-size: 14px;
  color: var(--tinta);
  text-decoration: none;
}
.chip--on { background: var(--acento); color: var(--acento-tinta); border-color: var(--acento); }

.proposal { margin: 20px 0; }
.proposal__where { margin: 0; font-size: 17px; }
.proposal__note { margin: 4px 0 12px; font-size: 14px; color: var(--tinta-suave); }
.proposal__note--warn { color: var(--aviso); font-weight: 600; }

/* La propuesta no reserva, y se dice donde se decide: pegado al botón.
   Con el color de aviso pero sin peso de alarma — es un dato honesto, no una
   advertencia de que algo va mal. */
.proposal__hold {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: var(--radio);
  background: var(--aviso-fondo);
  color: var(--aviso);
  font-size: 14px;
  font-weight: 600;
}
.proposal__hold-icon { flex: none; font-size: 15px; }

.account { margin: 0 0 20px; }

/* La cuenta en la cabecera. Comparte fila con la marca, que estaba medio
   vacía, y deja intacta la de abajo: ahí vive el reloj de la reserva y nada
   puede restarle atención mientras corre (D51). */
.account--header { margin: 0; }

.account__top {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  /* Alto de dedo aunque el texto sea pequeño: es un enlace de barra, y los de
     barra se fallan al tocarlos más que ninguno. */
  min-height: var(--tocable);
  padding-left: 8px;
  color: var(--tinta-suave);
  text-decoration: none;
  font-size: 13px;
}
.account__top:hover { color: var(--tinta); }

/* Identificado: el nombre pesa más que "entrar", porque de quién seas depende
   a dónde van tus entradas. */
.account__text--top {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: var(--tocable);
  font-size: 13px;
  color: var(--tinta);
}
.account__text { margin: 0 0 10px; font-size: 14px; color: var(--tinta-suave); }
.account__actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.account__text .account__icon { margin-right: 4px; }
.account__text .link { margin-left: 8px; }

/* Botón secundario: se ve y se toca igual que el principal, pero no compite
   con él. Los dos accesos a la cuenta son atajos, nunca el camino. */
/* El secundario de la guía: fondo blanco, borde marino 300. */
.btn--ghost {
  background: var(--fondo);
  color: var(--acento);
  border: 1px solid var(--borde-fuerte);
}
.account__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tocable);
  color: var(--tinta);
  text-decoration: none;
  font-size: 14px;
}
.account__icon { font-size: 18px; }

/* El correo de entrega. Grande porque es la última oportunidad de detectar una
   errata, y con `word-break` porque un correo largo no puede desbordar en un
   móvil estrecho. */
.delivery {
  margin: 20px 0;
  padding: 16px;
  background: var(--fondo-alt);
  border-radius: var(--radio);
}
.delivery__label { margin: 0; font-size: 13px; color: var(--tinta-suave); }
.delivery__email {
  margin: 4px 0 8px;
  font-size: 17px;
  font-weight: 600;
  word-break: break-all;
}
.delivery__hint { margin: 0; font-size: 13px; color: var(--tinta-suave); }

/* --- camino al banco ----------------------------------------------------- */

/* La pantalla que se ve un instante mientras el formulario se envía solo.
   Centrada porque es lo único que hay: si tarda, que no parezca una página a
   medio cargar. */
.redirect {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  margin: 0;
  padding: 24px;
  font-family: var(--tipo, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
  background: var(--fondo);
  color: var(--tinta);
}
.redirect__box { max-width: 380px; text-align: center; }
.redirect__title { margin: 0 0 8px; font-size: 18px; font-weight: 600; }
.redirect__text { margin: 0; color: var(--tinta-suave); font-size: 15px; }

/* El botón de pagar va dentro de un form, y el form no debe romper la barra. */
.zonebar__form { flex: 0 0 auto; margin: 0; }

/* --- el mapa ------------------------------------------------------------- */

.map {
  position: relative;
  /* Alto por viewport y no fijo: en un móvil el mapa tiene que ocupar lo que
     hay, y `dvh` descuenta la barra del navegador cuando aparece y desaparece
     al hacer scroll. Con `vh` el mapa queda cortado por debajo. */
  height: min(62dvh, 520px);
  margin: 0 0 16px;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--fondo-alt);
}

.map__canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* Sin esto el navegador se queda el gesto para hacer scroll de la página y el
     mapa no se puede arrastrar hacia abajo. */
  touch-action: none;
  /* Un arrastre largo no debe seleccionar texto ni sacar el menú de iOS. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.map__status {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0 24px;
  text-align: center;
  color: var(--tinta-suave);
  font-size: 14px;
  pointer-events: none;
}

/* Respaldo sin JavaScript, y ayuda de lectura con él: la misma información que
   el mapa, en una lista que se puede recorrer con el lector de pantalla. */
.zonelist { list-style: none; margin: 0 0 8px; padding: 0; }

/* `display: flex` gana al `display: none` que el navegador da a [hidden], así
   que sin esta línea las filas escondidas se seguían viendo: en el estadio se
   veían las 204, gradas y sectores mezclados. */
.zonelist__item[hidden] { display: none; }

.zonelist__item {
  display: flex;
  align-items: center;
  /* wrap: el texto de la [i] abierta cae a su propia línea bajo la fila. */
  flex-wrap: wrap;
  gap: 10px;
  min-height: var(--tocable);
  padding: 6px 0;
  border-bottom: 1px solid var(--borde);
}

.zonelist__item--gone { opacity: .5; }

.zonelist__dot {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  border-radius: 3px;
}

.zonelist__name { flex: 1 1 auto; font-weight: 600; font-size: 15px; }

.zonelist__badge {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--tinta-suave);
}

/* --- la barra de la zona elegida ----------------------------------------- */

/* La barra de abajo: UNA, con dos filas. Antes cada pantalla ponía la suya
   —zona tocada, butacas elegidas, contadores de aforo— y ninguna decía lo que
   llevas ni cuánto te queda de reserva. Ahora eso va arriba, fijo, y la acción
   de cada pantalla debajo. */
.actionbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  background: var(--fondo);
  border-top: 1px solid var(--borde);
  box-shadow: 0 -6px 20px rgba(var(--sombra), .08);
  /* El hueco de la muesca: sin esto, en un iPhone el botón queda debajo de la
     barra de gestos y no se puede pulsar. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* Con la barra fija de dos filas abajo, el final del contenido quedaba debajo:
   el enlace de "seguir eligiendo" no se podía pulsar. */
body:has(.actionbar) .main { padding-bottom: 148px; }

/* La navegación que no cambia nunca: volver a la izquierda y el carrito a la
   derecha, SIEMPRE en el mismo sitio. Antes "seguir eligiendo" y "volver al
   mapa" eran dos enlaces distintos, en dos sitios distintos del pie, para el
   mismo gesto — y había que buscarlos con la vista cada vez. */
.actionbar__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 16px;
  background: var(--fondo-alt);
  border-top: 1px solid var(--borde);
}

.actionbar__back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* 40px de alto: es un objetivo de toque, aunque parezca un enlace. */
  min-height: 40px;
  color: var(--acento);
  text-decoration: none;
  font-size: 14px;
}

/* A la derecha aunque no haya botón de volver, para que no baile de sitio. */
.actionbar__cart[hidden] { display: none; }

.actionbar__cart {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  margin-left: auto;
  color: inherit;
  text-decoration: none;
  font-size: 14px;
}

.actionbar__cart-icon { position: relative; display: inline-flex; }

.actionbar__cart-count {
  position: absolute;
  top: -6px;
  right: -8px;
  min-width: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--acento);
  color: var(--blanco);
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

.actionbar__cart-total { font-weight: 700; }

.zonebar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
}

.zonebar[hidden] { display: none; }

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

.zonebar__name {
  display: block;
  font-weight: 700;
  font-size: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.zonebar__detail { display: block; font-size: 13px; color: var(--tinta-suave); }

.zonebar__go { flex: 0 0 auto; }
.zonebar__go[hidden] { display: none; }

/* Sitio para la barra, para que no tape el final de la lista de zonas. */
.map ~ .zonelist { margin-bottom: 132px; }

/* --- el mapa de butacas -------------------------------------------------- */

/* El aviso flotante del mapa: "acércate para elegir", "esa butaca ya está
   ocupada". Va sobre el mapa y no debajo, porque en un móvil lo de debajo cae
   fuera de la pantalla justo cuando hace falta leerlo. */
.map__hint {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 12px;
  margin: 0;
  padding: 10px 14px;
  border-radius: var(--radio);
  background: rgba(var(--sombra), .88);
  color: var(--blanco);
  font-size: 13px;
  text-align: center;
  pointer-events: none;
}

.map__hint[hidden] { display: none; }

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  font-size: 13px;
  color: var(--tinta-suave);
}

.legend__item { display: flex; align-items: center; gap: 6px; }

.legend__dot {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  border: 1px solid var(--blanco);
  box-shadow: 0 0 0 1px var(--borde);
}

.legend__dot--free { background: var(--marino-500); }
.legend__dot--sold { background: var(--butaca-no-disponible); }
.legend__dot--warn { background: var(--butaca-aviso); }
.legend__dot--dead { background: var(--fondo-alt); border-color: var(--butaca-rota); }

/* La lista de zonas: mismo camino que el mapa, en texto. */
.zonelist__title {
  margin: 4px 0 6px;
  font-size: 13px;
  color: var(--tinta-suave);
}

.zonelist__name--link {
  color: var(--tinta);
  text-decoration: none;
  /* Toda la fila es tocable, no solo las letras: 44 px de alto ya los pone
     `.zonelist__item`. */
  display: block;
  padding: 10px 0;
}

/* El diagnóstico de ?debug=1. Feo a propósito: no es para el comprador. */
.mapdebug {
  position: absolute;
  left: 8px;
  right: 8px;
  top: 8px;
  margin: 0;
  padding: 8px;
  border-radius: 8px;
  background: rgba(var(--sombra), .9);
  color: #7CFFB2; /* el panel de diagnóstico (?debug): no es marca, lo ve quien depura */
  font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: pre-wrap;
  pointer-events: none;
  z-index: 5;
}

/* --- la nota de la reserva (el reloj vive en la cabecera) ----------------- */

/* Explica QUÉ significa el reloj de arriba, en la pantalla donde el comprador
   se para a mirar. Sin número: dos cuentas atrás en la misma página acaban
   desacompasadas y una de las dos miente. */
.holdclock {
  position: sticky;
  /* Justo debajo de la cabecera de contexto, y pegado: es lo más importante de
     la pantalla (D51) y no puede irse con el scroll. */
  top: 58px;
  z-index: 9;
  margin: 0 0 12px;
  padding: 10px 14px;
  border-radius: var(--radio);
  background: var(--info-fondo);
  color: var(--info);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
}

.holdclock[hidden] { display: none; }

/* --- el carrito ---------------------------------------------------------- */

.cart { list-style: none; margin: 0 0 20px; padding: 0; }

.cart__line {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--borde);
}

.cart__seat { flex: 0 0 auto; min-width: 0; }
.cart__label { display: block; font-weight: 600; font-size: 15px; }
.cart__zone { display: block; font-size: 12px; color: var(--tinta-suave); }

.cart__fare { flex: 1 1 auto; min-width: 0; }
.cart__form { margin: 0; }

.cart__item { font-size: 14px; color: var(--tinta-suave); }

/* El localizador de la confirmación: lo que el comprador tiene que poder
   leer en voz alta o teclear en la app (Luis, 2-oct-2026). */
.notice__locator { margin: 8px 0 0; font-size: 16px; }
.notice__locator-code { font-size: 22px; letter-spacing: 0.08em; font-variant-numeric: tabular-nums; }

/* Las tarifas como botones (opción B, Luis, 1-oct-2026): su propia fila bajo
   la butaca, en teléfono y en PC, y cada una del alto del dedo. */
.cart__line { flex-wrap: wrap; }
.cart__fares { flex: 1 0 100%; order: 10; }
.cart__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.cart__chip {
  min-height: var(--tocable);
  padding: 0 12px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--fondo);
  color: var(--tinta);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.cart__chip--on {
  border: 2px solid var(--acento);
  color: var(--acento);
  font-weight: 600;
}
.cart__amount { flex: 0 0 auto; font-weight: 700; font-size: 16px; }

/* El desglose. Va entero y a la vista: el gasto de gestión se dice antes de
   pagar (D74), no escondido dentro del total. */
.breakdown { margin: 0 0 8px; padding: 0; }

.breakdown__row {
  display: flex;
  justify-content: space-between;
  padding: 6px 0;
  font-size: 15px;
}

.breakdown__row dt, .breakdown__row dd { margin: 0; }
.breakdown__row--tax { color: var(--tinta-suave); font-size: 13px; }

.breakdown__row--total {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--borde);
  font-weight: 700;
  font-size: 18px;
}

/* Sitio para la barra fija de abajo. */
.breakdown { margin-bottom: 92px; }

/* --- filtros del mapa ---------------------------------------------------- */

/* Plegados. La pantalla es del mapa: un panel abierto que nadie ha pedido se
   come justo lo que se ha venido a ver. */
.filters { margin: 0 0 12px; }

/* Tres, cada una con su icono y su valor a la vista: así se sabe por qué se
   está filtrando sin abrir nada. Icono Y palabra —"tarifa" y "tipo de zona" no
   tienen un dibujo que todo el mundo reconozca, y un icono que hay que
   adivinar es peor que una palabra que se lee. */
.filters__tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
}

.filters__tabs::-webkit-scrollbar { display: none; }

.filtertab {
  /* Lo que necesite, no un tercio exacto: repartir a partes iguales cortaba
     "Entrada general" en una pestaña mientras "Zona" sobraba sitio. Si no
     caben, se desplazan de lado. */
  flex: 0 0 auto;
  max-width: 60%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  padding: 0 10px;
  border: 1px solid var(--borde);
  border-radius: 10px;
  background: var(--fondo);
  color: var(--tinta);
  font-size: 13px;
  cursor: pointer;
}

.filtertab__icon { flex: 0 0 auto; color: var(--tinta-suave); }

.filtertab__value {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Puesta = hay un filtro activo por ahí. Abierta = su panel está desplegado.
   Son cosas distintas y se ven distintas. */
.filtertab--on {
  border-color: var(--tinta);
  font-weight: 600;
}

.filtertab--on .filtertab__icon { color: var(--tinta); }

.filtertab--abierta {
  background: var(--fondo-alt);
  border-color: var(--tinta);
}

.filters__panel { padding: 10px 0 2px; }

/* En fila y con desbordamiento lateral: con cinco tarifas, apilarlas empujaría
   el mapa fuera de la pantalla. */
.chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}

.chips::-webkit-scrollbar { display: none; }

.chip {
  flex: 0 0 auto;
  /* 36px de alto: por debajo de eso el dedo falla y se acaba tocando el de al
     lado. */
  min-height: 36px;
  padding: 0 14px;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--fondo);
  color: var(--tinta);
  font-size: 14px;
  white-space: nowrap;
  cursor: pointer;
}

.chip--on {
  background: var(--tinta);
  border-color: var(--tinta);
  color: var(--blanco);
  font-weight: 600;
}

.filters__empty { margin: 12px 0 0; font-size: 13px; color: var(--tinta-suave); }

/* Fuera del filtro: se ve que sigue ahí, pero apagada. Distinto de --gone
   (agotada), que es gris: son dos cosas distintas y pintarlas igual le quita
   fuerza a la que de verdad importa. */
.zonelist__item--filtered { opacity: .3; }

/* "Últimas plazas" no es lo mismo que "pocas": si se pintan igual, el
   comprador no puede distinguir el 9% del 2%. */
.zonelist__badge--last { background: var(--aviso-fondo); color: var(--aviso); }

/* Dónde estás cuando has bajado a los sectores de una grada.
   El [hidden] primero: `display: flex` gana al `display: none` que el
   navegador le da, y el rótulo se veía también en el nivel de arriba. */
.maplevel[hidden] { display: none; }

.maplevel {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 10px;
}

.maplevel__name { font-weight: 700; font-size: 16px; }
.maplevel__hint { font-size: 13px; color: var(--tinta-suave); }

/* --- El escritorio: la misma pantalla, de pie ------------------------------
   Hasta ahora la tienda era el móvil estirado: una columna de 640 px centrada
   en un monitor de 1400. En el PC no hay pulgar que alcanzar ni pantalla que
   se acabe, así que lo que en el móvil va uno detrás de otro cabe a la vez —
   y el plano, que es lo que se está mirando, se lleva todo el sitio que sobra.

   La rejilla la lleva el <body> y no un envoltorio: la barra de selección es
   hermana de <main>, no hija, y así se coloca a la derecha sin sacarla del
   flujo ni pelearse con la cabecera. */
@media (min-width: 900px) {
  body.pantalla-mapa {
    display: grid;
    /* El plano manda: las dos columnas laterales tienen el ancho que
       necesitan y NADA más, y todo lo que sobra es para el centro. En una
       pantalla ancha eso significa un plano grande — antes, agrandar la
       ventana solo añadía margen vacío (encargo de Luis, 2-sep-2026). */
    grid-template-columns: minmax(0, 1fr) 320px;
    grid-template-rows: auto minmax(0, 1fr);
    height: 100dvh;
    /* Cada columna hace su propio scroll: la página entera no se mueve, y el
       plano no se va nunca de la vista al bajar por la lista de zonas. */
    overflow: hidden;
  }

  body.pantalla-mapa .topbar { grid-column: 1 / -1; }

  body.pantalla-mapa .main {
    grid-column: 1;
    grid-row: 2;
    /* Ancho explícito y no "lo que herede": el `max-width: none` quita el tope
       del móvil, pero no garantiza que se estire. Con `width: 100%` y
       `justify-self: stretch` la columna se llena siempre, venga de donde
       venga el contenedor. */
    width: 100%;
    justify-self: stretch;
    max-width: none;
    min-width: 0;
    min-height: 0;
    padding: 0;
  }

  /* El aire que la barra de abajo reservaba en el móvil sobra: aquí no hay
     nada tapando el final del contenido, porque la barra ya no está encima. */
  body.pantalla-mapa .main { padding-bottom: 0; }

  .mapscreen {
    display: grid;
    /* Lo mismo aquí: una rejilla dentro de un contenedor que no la estire se
       encoge a lo que ocupen sus columnas, y entonces el plano se queda con lo
       justo mientras sobra media pantalla al lado. */
    width: 100%;
    max-width: none;
    /* La lista, con su ancho; el plano, con TODO lo demás y un mínimo por
       debajo del cual no baja: un plano de un palmo no se puede usar, y antes
       que encogerlo hasta ahí es mejor que empuje. */
    grid-template-columns: 300px minmax(420px, 1fr);
    /* Cuatro filas en la columna izquierda —precio, "elígelas por mí", filtros
       y la lista, que es la que se estira— y el plano ocupándolas todas. */
    grid-template-rows: auto auto auto minmax(0, 1fr);
    gap: 10px var(--hueco);
    padding: var(--hueco);
    height: 100%;
    min-height: 0;
  }

  .mapscreen .lead--price { grid-column: 1; grid-row: 1; margin: 0; }
  .mapscreen .bestlink { grid-column: 1; grid-row: 2; margin: 0; }
  .mapscreen .filters { grid-column: 1; grid-row: 3; margin: 0; }

  /* "O elige la zona de la lista" es de la pila del móvil, donde la lista va
     DEBAJO del plano y hay que anunciarla. Aquí está al lado, a la vista. */
  .mapscreen .zonelist__title { display: none; }

  .mapscreen .zonelist {
    grid-column: 1;
    grid-row: 4;
    min-height: 0;
    overflow-y: auto;
    margin: 0;
  }

  .mapscreen .maplevel { grid-column: 2; grid-row: 1 / 3; margin: 0; }
  .mapscreen .maplevel[hidden] { display: none; }

  .mapscreen .map {
    grid-column: 2;
    grid-row: 3 / -1;
    /* Sin tope: en el móvil el plano se limita para no comerse la pantalla,
       pero aquí crece con la ventana, a lo ancho y a lo alto. */
    max-width: none;
    max-height: none;
    /* El plano manda: se come todo el alto que quede, sin el tope de 520 px
       que en el móvil evita que se coma la pantalla entera. */
    height: 100%;
    min-height: 0;
    margin: 0;
  }

  /* La barra, de pie a la derecha. Las acciones abajo del todo, que es donde
     se las busca —el mismo sitio que en el móvil, solo que en su columna. */
  body.pantalla-mapa .actionbar {
    position: static;
    grid-column: 2;
    grid-row: 2;
    /* (fila 2 del BODY, que es donde va el contenido; nada que ver con las
       filas internas de .mapscreen) */
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 0;
    overflow-y: auto;
    border-top: 0;
    border-left: 1px solid var(--borde);
    box-shadow: -6px 0 20px rgba(var(--sombra), .06);
    padding-bottom: 0;
  }

  body.pantalla-mapa .actionbar__nav { gap: 8px; }

  /* El nombre de la columna arriba y todo lo demás abajo: el `auto` de aquí es
     lo que empuja las acciones al pie, donde se las busca. */
  body.pantalla-mapa .actionbar__head {
    display: block;
    margin-bottom: auto;
    padding: 14px 16px;
    border-bottom: 1px solid var(--borde);
  }
  .actionbar__title {
    margin: 0;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--tinta-suave);
  }
  .actionbar__empty {
    margin: 8px 0 0;
    font-size: 14px;
    line-height: 1.4;
    color: var(--tinta-suave);
  }

  /* La lista dentro de la columna: la misma de la pantalla del carrito, en
     menos sitio. Se aprieta en vez de recortarse — quitar la tarifa o el aspa
     dejaría media función fuera, que es justo lo que se venía a arreglar. */
  body.pantalla-mapa .actionbar__head .cart {
    margin: 12px 0 0;
    max-height: 46dvh;
    overflow-y: auto;
  }
  body.pantalla-mapa .actionbar__head .cart__line {
    gap: 6px;
    padding: 8px 0;
    font-size: 14px;
  }
}

/* En el móvil la barra es una franja de dos filas bajo el pulgar: presentarse
   ahí sería gastar en un rótulo el sitio del botón. */
.actionbar__head { display: none; }

/* --- El panel de cantidad, dentro del mapa ---------------------------------
   Elegir cuántas entradas de un bloque de aforo SIN salir del mapa: al
   cerrarlo, el comprador sigue exactamente donde estaba. En el móvil sube
   desde abajo, que es donde llega el pulgar; en el escritorio se queda
   centrado sobre el plano. */
.qtypanel {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 82dvh;
  overflow-y: auto;
  padding: 14px var(--hueco);
  padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  background: var(--fondo);
  border-top: 1px solid var(--borde);
  border-radius: var(--radio) var(--radio) 0 0;
  box-shadow: 0 -10px 30px rgba(var(--sombra), .18);
}

.qtypanel__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.qtypanel__name { margin: 0; font-size: 18px; font-weight: 700; }
.qtypanel__block { margin: 2px 0 0; font-size: 14px; color: var(--tinta-suave); }
.qtypanel__block[hidden] { display: none; }

.qtypanel__close {
  flex: 0 0 auto;
  width: var(--tocable);
  height: var(--tocable);
  font-size: 24px;
  line-height: 1;
  color: var(--tinta-suave);
  background: var(--fondo-alt);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}

/* El aviso del servidor —"como mucho 10 plazas"— se lee AQUÍ: mandar a otra
   pantalla a leer un error es lo que se venía a quitar. */
.qtypanel__warn {
  margin: 0;
  padding: 8px 10px;
  font-size: 14px;
  color: var(--aviso);
  background: var(--aviso-fondo);
  border-radius: 8px;
}
.qtypanel__warn[hidden] { display: none; }

.qtypanel__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--borde);
}
.qtypanel__text { display: flex; flex-direction: column; }
.qtypanel__total { font-size: 18px; font-weight: 700; }
.qtypanel__count { font-size: 13px; color: var(--tinta-suave); }

@media (min-width: 900px) {
  .qtypanel {
    left: 50%;
    top: 50%;
    right: auto;
    bottom: auto;
    width: min(440px, 90vw);
    transform: translate(-50%, -50%);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: 0 18px 50px rgba(var(--sombra), .22);
  }
}

/* "Elígelas por mí" en el mapa: era una pantalla previa que obligaba a decidir
   antes de ver nada, y ahora es una oferta más de la pantalla del plano. */
.bestlink {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tocable);
  margin: 0 0 10px;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 600;
  color: var(--acento);
  text-decoration: none;
  background: var(--fondo-alt);
  border: 1px solid var(--borde);
  border-radius: 999px;
}

/* El precio desde el que se vende, bajo el título. */
.lead--price { margin: 0 0 10px; font-size: 15px; }

/* Los bloques de una zona de aforo cuando no se sabe dónde caen (K29 sin
   emitir todavía): botones sobre el plano, en vez de manchas en un sitio que
   no es. Flotan abajo del mapa, donde llega el pulgar. */
.blockbtns {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  padding: 0 12px;
}
.blockbtns[hidden] { display: none; }

.blockbtn {
  min-height: var(--tocable);
  padding: 0 18px;
  font-size: 15px;
  font-weight: 600;
  color: var(--acento-tinta);
  background: var(--acento);
  border: 0;
  border-radius: 999px;
  box-shadow: 0 2px 10px rgba(var(--sombra), .18);
  cursor: pointer;
}

/* Solo en desarrollo: la versión del catálogo con la que compra este navegador.
   Por encima de la barra de abajo, y sin capturar clics: no puede tapar nada. */
.dev-version {
  position: fixed;
  right: 8px;
  bottom: 96px;
  z-index: 9999;
  padding: 2px 8px;
  font: 600 11px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--blanco);
  background: rgba(var(--sombra), .72);
  border-radius: 999px;
  pointer-events: none;
}

/* --- marca GoPass.In (6-oct-2026) ----------------------------------------- */

/* Títulos en Montserrat; el resto, Inter (guía de marca). */
.h1, .h2, h1, h2, h3, .notice__title, .context__title { font-family: var(--tipo-titulo); }
.h2, h2 { font-weight: 700; }

/* Cifras tabulares en precios y totales: los importes se alinean y no bailan
   al cambiar una tarifa. */
.cart__amount, .offer__price, .breakdown dd, .zonebar__name, .zonelist__price,
.session__price, .lead--price, .qty__price { font-variant-numeric: tabular-nums; }

/* El pie: GoPass.In firma (guía de marca). Discreto, debajo de todo. */
.storefoot {
  max-width: 640px;
  margin: 8px auto 0;
  padding: 14px var(--hueco) calc(18px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--borde);
  font-size: 12px;
  color: var(--tinta-suave);
}
.storefoot__firma { display: inline-flex; align-items: center; gap: 8px; }
.storefoot__logo { display: block; height: 18px; width: auto; }

/* En la pantalla del mapa de escritorio el cuerpo es una rejilla de altura fija
   (cabecera + plano + selección): un pie ahí rompería el encaje. */
@media (min-width: 900px) {
  body.pantalla-mapa .storefoot { display: none; }
}

/* --- identificarse para elegir (§8.1, 16-oct-2026) ---------------------------
   El aviso FIJO, arriba del mapa: se ve antes de tocar nada. Al tocar una
   butaca sin identificarse, se resalta un momento (`--realce`) en vez de un
   globo que se va. */
.loginwall {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: var(--radio);
  background: var(--aviso-fondo);
  color: var(--aviso);
}
.loginwall__text { margin: 0; font-weight: 600; line-height: 1.3; }
.loginwall__btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: var(--tocable);
  padding: 0 14px;
  border-radius: 8px;
  background: var(--marino);
  color: #fff;
  font-weight: 700;
  text-decoration: none;
}
.loginwall--realce { outline: 3px solid #f59e0b; transition: outline-color 0.2s; }
