/* ==========================================================================
   Portal publico — cara al viajero.
   Tokens y modo oscuro viven en theme.css, que se carga despues de este
   archivo. Aqui solo hay composicion y componentes.
   ========================================================================== */

/* ==========================================================================
   Capa sobre imagen.

   Lo que se apoya en la foto del hero o en la bandeja oscura NO sigue el tema:
   su fondo es siempre oscuro, asi que el texto es blanco en claro y en oscuro.
   Estos nombres viven aqui y no en `theme.css` porque solo esta superficie los
   usa, y estaban repetidos hasta cinco veces con el valor escrito a mano.

   Los dos velos traen azules distintos —`15 24 42` y `8 14 26`— que venian por
   separado. Se conservan tal cual: unificarlos cambiaria lo que se ve, y esa es
   una decision de diseno, no una limpieza.
   ========================================================================== */

:root {
  --on-photo: #fff;
  /* El blanco con transparencia aparece con varias opacidades: el panel de
     busqueda, su borde y el separador del total. Un solo origen para todas. */
  --on-photo-rgb: 255 255 255;
  --on-photo-soft: rgb(var(--on-photo-rgb) / .78);
  --on-photo-muted: rgb(var(--on-photo-rgb) / .68);
  --on-photo-accent: rgb(var(--on-photo-rgb) / .86);
  --hero-veil-rgb: 15 24 42;
  --panel-veil-rgb: 8 14 26;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--bg);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
.public-brand,
.panel-empty h3,
.no-package strong {
  font-family: var(--font-display);
}

button,
input,
select,
textarea {
  font: inherit;
}

button,
a,
summary,
select,
input {
  -webkit-tap-highlight-color: transparent;
}

.hidden {
  display: none !important;
}

.skip-link {
  position: fixed;
  top: -80px;
  left: var(--sp-4);
  z-index: 40;
  padding: var(--sp-3) var(--sp-4);
  color: var(--on-navy);
  background: var(--navy);
  border-radius: var(--r-md);
  font-weight: var(--fw-bold);
  text-decoration: none;
  box-shadow: var(--shadow-lg);
}

.skip-link:focus {
  top: var(--sp-3);
}

/* ==========================================================================
   Encabezado
   ========================================================================== */

.public-header {
  position: sticky;
  top: 0;
  z-index: 12;
  min-height: 72px;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) max(var(--sp-5), calc((100vw - 1440px) / 2));
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-xs);
}

.public-brand {
  margin-right: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  color: inherit;
  text-decoration: none;
}

.public-brand img {
  width: 206px;
  height: 46px;
  object-fit: contain;
  object-position: left center;
}

/* "Acceso equipo" es una salida secundaria: no debe competir con la accion
   de compra, asi que va en navy discreto y no en magenta. */
.internal-link {
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sp-4);
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.internal-link:hover {
  color: var(--brand-text);
  background: var(--brand-tint);
  border-color: var(--brand-line-strong);
}

/* ==========================================================================
   Lienzo
   ========================================================================== */

main {
  padding: var(--sp-7) max(var(--sp-4), calc((100vw - 1440px) / 2)) var(--sp-10);
}

/* ---------- Selector de modo, control segmentado ---------- */

.catalog-modes {
  max-width: 560px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-1);
  margin: 0 0 var(--sp-4);
  padding: 3px;
  /* Una sola pieza y el elegido en relieve, como el control segmentado de la
     Plataforma Palma: antes el elegido iba relleno de rosa y parecia otro
     boton de accion. */
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

.catalog-mode {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: var(--sp-2) var(--sp-4);
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-lg);
  text-align: left;
  cursor: pointer;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease),
    border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.catalog-mode strong {
  color: var(--ink-2);
  font-size: var(--fs-md);
}

.catalog-mode span {
  color: var(--muted);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  line-height: var(--lh-snug);
}

.catalog-mode:hover {
  background: var(--surface-2);
  filter: none;
}

.catalog-mode.active {
  background: var(--surface);
  border-color: var(--line);
  box-shadow: var(--shadow-xs);
}

.catalog-mode.active strong,
.catalog-mode.active svg {
  color: var(--brand-text);
}

.catalog-mode svg {
  flex: none;
  color: var(--muted);
}

.catalog-mode strong {
  font-family: var(--font-body);
  font-weight: var(--fw-semibold);
}

/* ==========================================================================
   Hero de busqueda
   ========================================================================== */

.search-shell {
  position: relative;
  /* Medido a 1770x1000: con 244 el primer paquete empezaba en y=548, el 55% de
     la ventana gastado antes de ensenar nada que se venda. La banda no tiene
     que llenar pantalla: tiene que dejar sitio al producto. */
  min-height: 168px;
  display: grid;
  align-content: center;
  overflow: hidden;
  padding: clamp(var(--sp-6), 4vw, var(--sp-9)) clamp(var(--sp-5), 4vw, var(--sp-10));
  color: var(--on-photo);
  background: var(--navy) url("./assets/caribbean-hero.webp") center 48% / cover no-repeat;
  border: 0;
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
}

/* Velo en degradado: oscurece lo justo para el texto y deja respirar la foto. */
.search-shell::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg, rgb(var(--hero-veil-rgb) / .86) 0%, rgb(var(--hero-veil-rgb) / .62) 46%, rgb(var(--hero-veil-rgb) / .34) 100%),
    linear-gradient(180deg, rgb(var(--hero-veil-rgb) / .18), rgb(var(--hero-veil-rgb) / .52));
}

.search-shell > * {
  position: relative;
  z-index: 1;
}

.search-heading {
  display: grid;
  gap: var(--sp-2);
  max-width: 620px;
  margin-bottom: var(--sp-7);
}

.search-heading p {
  margin: 0;
  color: var(--on-photo-accent);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.search-heading h1 {
  margin: 0;
  color: var(--on-photo);
  font-size: clamp(22px, 2.2vw, 30px);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  letter-spacing: -.015em;
  text-shadow: 0 2px 14px rgb(var(--panel-veil-rgb) / .38);
}

.search-heading > span {
  max-width: 52ch;
  color: var(--on-photo-soft);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  text-align: left;
  text-shadow: 0 1px 6px rgb(var(--panel-veil-rgb) / .42);
}

.public-search {
  display: grid;
  grid-template-columns: 1.15fr 1.15fr 1fr repeat(3, minmax(76px, .4fr)) auto;
  gap: var(--sp-3);
  align-items: end;
  padding: var(--sp-4);
  color: var(--ink);
  background: rgb(var(--on-photo-rgb) / .97);
  border: 1px solid rgb(var(--on-photo-rgb) / .6);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(10px);
}

label {
  display: grid;
  gap: var(--sp-2);
  color: var(--ink-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

.public-search label {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

input,
select,
textarea {
  width: 100%;
  min-height: var(--tap);
  padding: var(--sp-2) var(--sp-3);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  /* Dentro de <label>, que va en negrita: el valor la heredaba. */
  font-weight: var(--fw-regular);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--muted-2);
}

textarea {
  min-height: 84px;
  resize: vertical;
  line-height: var(--lh-snug);
}

input::placeholder,
textarea::placeholder {
  color: var(--muted-2);
}

select {
  cursor: pointer;
}

button {
  min-height: var(--tap);
  padding: 0 var(--sp-5);
  color: var(--on-brand);
  background: var(--brand);
  border: 1px solid transparent;
  border-radius: var(--r-lg);
  font-weight: var(--fw-extrabold);
  letter-spacing: .01em;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}

button:hover {
  background: var(--brand-hover);
  filter: none;
}

button:active {
  transform: translateY(1px);
}

button:disabled {
  color: var(--muted);
  background: var(--surface-3);
  border-color: var(--line);
  cursor: not-allowed;
  filter: none;
  opacity: 1;
  transform: none;
}

.public-search button {
  min-height: var(--ctl-h-lg);
  box-shadow: var(--shadow-brand);
}

.child-ages {
  display: flex;
  align-items: end;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}

.child-ages:empty {
  display: none;
}

.child-ages > span {
  align-self: center;
  color: var(--on-photo-soft);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-shadow: 0 1px 4px rgb(var(--panel-veil-rgb) / .45);
}

.child-ages label {
  width: 96px;
  color: var(--on-photo-soft);
  text-shadow: 0 1px 4px rgb(var(--panel-veil-rgb) / .45);
}

.child-ages input {
  min-height: 40px;
}

.search-status {
  min-height: 20px;
  margin: var(--sp-3) 0 0;
  color: var(--on-photo);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-shadow: 0 1px 6px rgb(var(--panel-veil-rgb) / .55);
}

/* ==========================================================================
   Resultados
   ========================================================================== */

.catalog-section {
  margin-top: var(--sp-9);
}

.section-title {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--sp-5);
  margin-bottom: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--line);
}

/* `.package-copy > p` estaba aqui por error: esta regla viste rotulos tipo
   "PRERESERVA", pero esos tres parrafos de la tarjeta son la ruta, el bloque de
   precio y los servicios. Los pintaba a 11px extrabold en mayusculas con
   tracking de rotulo, anulando el --fs-sm que cada uno declara, de modo que
   tres roles distintos gritaban con la misma voz. */
.section-title p,
.overline,
.package-panel-heading p {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.section-title h2 {
  margin: var(--sp-1) 0 0;
  color: var(--ink);
  font-size: var(--fs-3xl);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  letter-spacing: -.01em;
}

.section-title > span {
  flex: 0 0 auto;
  padding: var(--sp-1) var(--sp-3);
  color: var(--muted);
  background: var(--surface-3);
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

.public-journey {
  display: grid;
  grid-template-columns: minmax(300px, .68fr) minmax(0, 1.6fr);
  gap: var(--sp-5);
  align-items: start;
}

/* ---------- Tarjeta de salida ---------- */

.public-blockings {
  display: grid;
  gap: var(--sp-3);
}

.departure-card {
  width: 100%;
  display: grid;
  gap: var(--sp-1);
  padding: var(--sp-4);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid transparent;
  border-radius: var(--r-lg);
  text-align: left;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    background var(--dur) var(--ease);
}

.departure-card:hover {
  background: var(--surface);
  border-color: var(--line-strong);
  border-left-color: var(--brand-line-strong);
  box-shadow: var(--shadow-sm);
  filter: none;
}

.departure-card.active {
  color: var(--ink);
  background: var(--brand-tint);
  border-color: var(--brand-line-strong);
  border-left-color: var(--brand);
  box-shadow: var(--shadow-sm);
}

.departure-date {
  color: var(--brand-text);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.departure-route {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
}

.departure-route span {
  color: var(--muted-2);
}

.departure-meta {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.departure-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line-soft);
  font-size: var(--fs-xs);
}

.seat-count {
  color: var(--ok-text);
  font-weight: var(--fw-bold);
}

.seat-count strong {
  font-size: var(--fs-lg);
}

.package-count {
  color: var(--muted);
  font-weight: var(--fw-bold);
  text-align: right;
}

/* El precio va en tinta, como en las tarjetas de paquete; el magenta es de las acciones. */
.package-count .departure-price {
  color: var(--ink);
  font-weight: var(--fw-extrabold);
}

/* ---------- La salida por dentro (2026-11-06) ----------
   Fecha y regreso arriba, la ruta, y debajo la aerolinea con el horario de
   ida: lo que el equipo pidio ver sin abrir la salida. */

.departure-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-3);
}

.departure-nights {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.departure-flight {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
}

.departure-legs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.departure-leg {
  display: grid;
  gap: 2px;
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2);
  border-radius: var(--radius-sm, 8px);
}

.departure-card.active .departure-leg {
  background: var(--surface);
}

.departure-leg-label {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.departure-card.active .departure-flight {
  background: var(--surface);
}

.aerolinea {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
}

/* Insignia de la aerolinea: monograma en su color (no es el logo oficial). */
/* Solo logos oficiales, como imagen (2026-11-06). */
.aerolinea-logo {
  flex: none;
  height: 24px;
  width: auto;
  max-width: 96px;
  object-fit: contain;
}

/* Logos que la aerolinea publica solo en blanco: sobre su propio color. */
.aerolinea-placa {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: 3px 8px;
  border-radius: 6px;
}

.aerolinea-placa .aerolinea-logo {
  height: 18px;
}

.horario {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.horario strong {
  font-size: var(--fs-md);
  font-weight: var(--fw-extrabold);
}

.horario small {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--track-caps);
}

.horario sup {
  color: var(--muted);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-bold);
}

.horario-linea {
  width: 20px;
  align-self: center;
  margin: 0 var(--sp-1);
  border-top: 1px dashed var(--line-strong);
}

.horario-pendiente {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

/* El vuelo de la salida elegida, debajo del encabezado del panel. */
.salida-vuelo {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line);
}

.salida-vuelo-cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-4);
}

.salida-vuelo-cabeza > span:last-child {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.salida-vuelo .vuelo-bloque {
  margin: 0;
}

.vuelo-numero {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.vuelo-numero .aerolinea-logo {
  height: 18px;
}

.salida-vuelo .horario-pendiente,
.salida-equipaje {
  margin: 0;
}

.salida-equipaje {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.salida-equipaje strong {
  color: var(--ink);
}

/* Sin paquete el aviso ya no necesita el alto de un panel vacio. */
.salida-vuelo + .no-package {
  min-height: 0;
  padding-top: var(--sp-6);
}

/* ---------- Panel de paquetes de una salida ---------- */

.package-panel {
  min-height: 280px;
  overflow: clip;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
}

.panel-empty,
.no-package {
  min-height: 268px;
  display: grid;
  place-content: center;
  justify-items: center;
  padding: var(--sp-7) var(--sp-5);
  color: var(--muted);
  text-align: center;
}

.panel-empty h3,
.no-package strong {
  margin: var(--sp-3) 0 var(--sp-1);
  color: var(--ink);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-extrabold);
}

.panel-empty p,
.no-package p {
  max-width: 48ch;
  margin: 0;
}

.step-number {
  width: 32px;
  height: 32px;
  display: inline-grid;
  place-items: center;
  color: var(--on-navy);
  background: var(--navy);
  border-radius: 50%;
  font-size: var(--fs-sm);
  font-weight: var(--fw-extrabold);
}

.package-panel-heading {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-1) var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}

.package-panel-heading > div {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}

.package-panel-heading > strong {
  align-self: center;
  font-size: var(--fs-md);
}

.package-panel-heading > span {
  grid-column: 2;
  color: var(--muted);
  font-size: var(--fs-xs);
  text-align: right;
}

.package-list {
  display: grid;
}

/* ---------- Catalogo de ofertas ---------- */

.public-package-catalog {
  position: relative;
}

/* Una oferta por fila, a todo el ancho. Con dos columnas las tarjetas tienen
   alturas muy distintas (2 a 8 hoteles) y la rejilla queda con huecos enormes;
   asi ademas las tarifas se comparan alineadas en una sola grilla. */
/* Una sola columna hacia que cada paquete ocupara la pantalla entera: con
   nueve publicados eran seis pantallas de scroll y ninguna forma de comparar
   precios entre destinos. En rejilla caben varios por pantalla y la
   comparacion deja de exigir memoria. `auto-fill` con un minimo de 340px da
   tres columnas en un escritorio, dos en un portatil y una en el telefono, sin
   puntos de corte que mantener. */
.package-catalog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: var(--sp-5);
  align-items: start;
}

.catalog-offer {
  overflow: clip;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.catalog-offer:hover {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-md);
}

/* Un paquete solo ocupaba las tres columnas, asi que con uno publicado la
   pantalla se veia igual de vacia y de enorme que antes de la rejilla: era
   justo lo que habia que corregir. Ahora usa una columna como los demas y la
   rejilla se llena a medida que se publican mas. */

/* En rejilla la tarjeta es vertical: la banda del destino arriba y el texto
   debajo. Con la banda al lado no cabria ninguna de las dos cosas. */
.catalog-offer .package-overview {
  grid-template-columns: minmax(0, 1fr);
  min-height: 0;
}

/* Proporcion fija 16:9 y recorte. El flyer es un cartel vertical de imprenta
   —el de prueba mide 900x1200—, asi que sin esto la imagen estira la tarjeta a
   lo alto y la rejilla vuelve a ser una torre. La pieza completa sigue
   disponible al expandir. Con la misma proporcion en las tres variantes, todas
   las tarjetas de una fila miden igual haya flyer o no. */
.catalog-offer .flyer-pending,
.catalog-offer .flyer-preview,
.catalog-offer .flyer-document {
  min-height: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

.catalog-offer .flyer-preview img {
  width: 100%;
  height: 100%;
  /* Encuadre por arriba: en un cartel, el titular y la imagen principal estan
     en la mitad superior. */
  object-fit: cover;
  object-position: top center;
}

.catalog-offer .package-copy {
  gap: var(--sp-2);
}

.package-offer + .package-offer {
  border-top: 1px solid var(--line);
}

.package-overview {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  min-height: 200px;
}

/* Arte del paquete. Si la imagen no resuelve, el texto alternativo cae sobre
   una superficie navy disenada en lugar de un hueco roto. */
.flyer-preview,
.flyer-pending,
.flyer-document {
  position: relative;
  min-height: 200px;
  display: grid;
  place-content: center;
  overflow: hidden;
  color: var(--on-navy);
  background: linear-gradient(155deg, var(--navy) 0%, var(--navy-strong) 100%);
  font-size: var(--fs-xs);
  text-decoration: none;
}

.flyer-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  color: rgb(var(--on-photo-rgb) / .72);
  font-size: var(--fs-xs);
}

.flyer-pending {
  gap: var(--sp-2);
  padding: var(--sp-5);
  text-align: center;
}

.flyer-pending strong {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-tight);
  letter-spacing: -.01em;
  text-transform: capitalize;
}

.flyer-pending span {
  color: rgb(var(--on-photo-rgb) / .72);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
}

.flyer-document {
  padding: var(--sp-5);
  font-weight: var(--fw-extrabold);
  text-align: center;
}

.flyer-document:hover {
  background: linear-gradient(155deg, var(--navy-hover) 0%, var(--navy) 100%);
}

.package-copy {
  padding: var(--sp-6);
}

/* La primera cifra que se lee tiene que ser la que invita a comprar, no la
   tarifa de habitacion sencilla, que es la mas cara. */
.package-price-lead {
  display: grid;
  gap: 0;
  /* Hueco y interlineado apretados: con los anteriores, la cifra y su
     calificador se leian como tres parrafos sueltos en vez de como un precio. */
  gap: 0 var(--sp-2);
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1.25;
}

/* Lo que incluye el paquete es un hecho, no un logro: iba en ocho pastillas
   verdes —el token de exito— que sumaban 94px por tarjeta y son casi las
   mismas en todos los paquetes, asi que no ayudaban a comparar. Una linea
   neutra dice lo mismo en dos. */
/* La acomodacion mas barata, cuando no es la que lidera: se dice, pero en
   pequenio y sin color, para que no compita con el precio de la busqueda. */
.price-alt {
  display: block;
  margin: 2px 0 var(--sp-3);
  color: var(--muted);
  font-size: var(--fs-xs);
}

.price-caption {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.package-price-lead strong {
  color: var(--ink);
  font-family: var(--font-display);
  /* 30 contra los 18 del titulo: en una rejilla de veinte, lo que decide es la
     cifra. Antes ambos median 21 y no ganaba ninguno. */
  font-size: var(--fs-3xl);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-extrabold);
  letter-spacing: -.01em;
}

.package-copy h3 {
  margin: var(--sp-1) 0 var(--sp-2);
  color: var(--ink);
  font-size: var(--fs-xl);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-snug);
  letter-spacing: -.01em;
}

.package-copy > span {
  display: block;
  max-width: 62ch;
  color: var(--muted);
  font-size: var(--fs-md);
  line-height: var(--lh-base);
}

.departure-chip-row,
.include-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}

/* En la tarjeta del catalogo la fecha va en texto, sin globo: es un dato de
   lectura, no una alerta, y con pastilla competia con el precio. La escasez
   real sigue avisando, pero solo tinendo el texto. */
.catalog-offer .departure-chip-row span {
  padding: 0;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

.catalog-offer .departure-chip-row .seats-low {
  color: var(--warn-text);
  background: none;
  border: 0;
}

.departure-chip-row span {
  padding: var(--sp-1) var(--sp-3);
  color: var(--ink-2);
  background: var(--navy-tint);
  border: 1px solid var(--navy-line);
  border-radius: var(--r-pill);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
}

/* Neutras, no verdes: lo que incluye el paquete es un hecho, no un logro, y
   --ok es el token de exito. Se conserva la forma de etiqueta —quitarla las
   convirtio en una linea corrida que no se leia— y baja el tamanio para que
   las seis quepan en dos filas. */
.include-row span {
  padding: 3px var(--sp-2);
  color: var(--ink-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--fs-2xs);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
}

/* ---------- Tarifas ---------- */

.package-options {
  border-top: 1px solid var(--line);
}

.package-options summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  color: var(--ink);
  background: var(--surface-2);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: var(--fw-extrabold);
  list-style: none;
}

.package-options summary::-webkit-details-marker {
  display: none;
}

.package-options summary::after {
  content: "";
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  margin-right: 3px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur) var(--ease);
}

.package-options[open] summary::after {
  transform: rotate(-135deg) translateY(-2px);
}

.package-options summary:hover {
  color: var(--brand-text);
  background: var(--brand-tint);
}

.rate-options {
  border-top: 1px solid var(--line);
}

/* En el catalogo la tarjeta mide unos 450 px. Con la copia y las tarifas lado a
   lado, la copia se quedaba con sus 220 px minimos y a las tarifas les tocaban
   175: una sola columna, con los cuatro precios apilados. Puestas debajo, la
   copia usa el ancho entero y los precios cogen dos columnas; la tarjeta pasa
   de 1.017 a 917 px sin perder ningun dato. */
.catalog-offer .rate-option {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-3);
}

/* auto-fill, no auto-fit: con dos tarifas los chips conservan su ancho en vez
   de estirarse y alejar la etiqueta del precio. */
.catalog-offer .rate-grid {
  /* 128: dos acomodaciones por fila en el ancho que deja una tarjeta de
     342px. Con 112 entraban tres y el precio quedaba apretado. */
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
}

.catalog-offer .rate-choice {
  min-height: 48px;
}

/* Dentro de la tarjeta del catalogo, la copia del hotel y sus tarifas se
   apilan. La regla base pide 200px para la copia y 340 para las tarifas, 540
   minimos: en una tarjeta de 342 la rejilla no puede darlos y las tarifas se
   salian 40px por la derecha. Medido al expandir: 12 elementos fuera del
   borde. */
.catalog-offer .rate-option {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
}

.rate-option {
  display: grid;
  grid-template-columns: minmax(200px, .8fr) minmax(340px, 1.2fr);
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
}

.rate-option + .rate-option {
  border-top: 1px solid var(--line-soft);
}

.rate-option:nth-of-type(even) {
  background: var(--surface-2);
}

.rate-option-copy {
  display: grid;
  align-content: start;
  gap: 2px;
}

/* El nombre del hotel encabeza sus habitaciones en vez de repetirse en cada
   una. Se separa del hotel anterior con una linea mas marcada que la que divide
   habitaciones, para que se lea donde acaba uno y empieza otro. */
.rate-hotel + .rate-hotel {
  border-top: 1px solid var(--line);
}

.rate-hotel-name {
  margin: 0;
  padding: var(--sp-4) var(--sp-5) 0;
  color: var(--ink);
  font-size: var(--fs-md);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-snug);
}

.rate-option-copy > span {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.rate-option-copy > small {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

/* Una sola linea reservada para las tarifas de menores, y solo cuando el paquete
   tiene alguna. Antes eran dos <small> apilados que aparecian o no, de modo que
   una fila con tarifa de nino quedaba dos lineas mas alta que su vecina. */
.rate-option-copy > .rate-option-minors {
  min-height: calc(var(--fs-xs) * var(--lh-snug));
}

/* La linea reservada se queda vacia a proposito: iguala el alto de las filas sin
   escribir nada. Por eso no se oculta cuando esta vacia. */
.rate-option-copy > .rate-option-minors:empty {
  display: block;
}

.rate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--sp-2);
}

/* Tarjeta de precio: etiqueta de acomodacion arriba, valor abajo. En vertical
   el chip necesita ~120px, cabe en cualquier ancho y los importes quedan
   alineados en columna para compararlos de un vistazo. */
.rate-choice {
  min-width: 0;
  min-height: 58px;
  display: grid;
  align-content: center;
  gap: 2px;
  padding: var(--sp-2) var(--sp-3);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  text-align: left;
  transition: color var(--dur) var(--ease), background var(--dur) var(--ease),
    border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.rate-choice span {
  color: var(--muted);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.rate-choice strong {
  font-size: var(--fs-md);
  font-weight: var(--fw-extrabold);
  white-space: nowrap;
}

.rate-choice:hover:not(:disabled) {
  color: var(--brand-text);
  background: var(--brand-tint);
  border-color: var(--brand-line-strong);
  filter: none;
}

.rate-choice:hover:not(:disabled) span {
  color: var(--brand-text);
}

.rate-choice.active,
.rate-choice.active:hover {
  color: var(--on-brand);
  background: var(--brand);
  border-color: var(--brand);
  box-shadow: var(--shadow-brand-sm);
}

/* Blanco pleno: sobre magenta un blanco al 82% cae a 3.2:1 y no cumple AA. */
.rate-choice.active span,
.rate-choice.active:hover span {
  color: var(--on-brand);
}

.rate-choice:disabled {
  color: var(--muted-2);
  background: transparent;
  border-style: dashed;
  border-color: var(--line);
}

.rate-choice:disabled span {
  color: var(--muted-2);
}

.package-warning {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  color: var(--warn-text);
  background: var(--warn-tint);
  border-top: 1px solid var(--warn-line);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

/* ---------- Bandeja de seleccion ---------- */

.selection-tray {
  position: sticky;
  bottom: var(--sp-3);
  z-index: 4;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-5);
  margin: var(--sp-4) var(--sp-3) 0;
  padding: var(--sp-4) var(--sp-5);
  color: var(--on-photo);
  background: var(--navy);
  border: 1px solid var(--navy-line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-xl);
}

.selection-tray > div {
  display: grid;
  gap: 2px;
}

.quote-route {
  color: var(--on-photo-accent);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.selection-tray > div > strong {
  font-size: var(--fs-lg);
}

.selection-tray > div > span {
  color: var(--on-photo-muted);
  font-size: var(--fs-xs);
}

.quote-lines {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px var(--sp-5);
  margin-top: var(--sp-2);
  color: var(--on-photo-muted);
  font-size: var(--fs-xs);
}

.quote-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: 1px solid rgb(var(--on-photo-rgb) / .22);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.quote-total strong {
  color: var(--on-photo);
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  letter-spacing: 0;
  text-transform: none;
}

.selection-tray > button {
  min-height: var(--ctl-h-lg);
  white-space: nowrap;
  box-shadow: var(--shadow-brand-lg);
}

/* ---------- Vacios ---------- */

.empty-catalog {
  padding: var(--sp-9) var(--sp-5);
  color: var(--muted);
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-xl);
  text-align: center;
}

.empty-catalog strong {
  display: block;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-lg);
}

.empty-catalog p {
  margin: var(--sp-2) 0 0;
}

/* Accion secundaria del vacio: contorno, para no competir con «Consultar». */
.empty-catalog-action {
  margin-top: var(--sp-4);
  min-height: var(--ctl-h);
  padding: 0 var(--sp-4);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font: inherit;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  cursor: pointer;
}

.empty-catalog-action:hover {
  color: var(--brand-text);
  background: var(--brand-tint);
  border-color: var(--brand-line-strong);
}

/* ==========================================================================
   Dialogo de cotizacion
   ========================================================================== */

dialog {
  width: min(720px, calc(100% - var(--sp-6)));
  max-height: min(90vh, 940px);
  padding: 0;
  overflow: hidden;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-xl);
}

dialog::backdrop {
  background: var(--overlay);
  backdrop-filter: blur(2px);
}

/* El boton de crear la prereserva estaba pegajoso sobre el propio formulario:
   al rodar tapaba los contadores de viajeros y la leyenda de quien reserva.
   Ahora el dialogo tiene cuerpo que rueda y pie que no se mueve, asi el boton
   sigue siempre a la vista sin robarle sitio a ningun campo. */
.contact-form {
  position: relative;
  display: flex;
  flex-direction: column;
  max-height: min(90vh, 940px);
  overflow: hidden;
}

.contact-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-6) var(--sp-6) var(--sp-5);
}

.contact-footer {
  flex: 0 0 auto;
  padding: var(--sp-4) var(--sp-6) var(--sp-5);
  background: var(--surface);
  border-top: 1px solid var(--line);
}

.contact-form h2 {
  margin: var(--sp-1) 0;
  color: var(--ink);
  font-size: var(--fs-3xl);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
}

.contact-form .overline {
  color: var(--brand-text);
}

.contact-package {
  margin: 0 0 var(--sp-5);
  color: var(--muted);
  font-size: var(--fs-sm);
}

.dialog-close {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-4);
  z-index: 3;
  width: 40px;
  min-height: 40px;
  padding: 0;
  display: grid;
  place-items: center;
  color: var(--muted);
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: 22px;
  line-height: 1;
}

.dialog-close:hover {
  color: var(--danger-text);
  background: var(--danger-tint);
  border-color: var(--danger-line);
}

.quote-summary {
  display: grid;
  gap: 2px;
  margin-bottom: var(--sp-5);
  padding: var(--sp-4);
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--ok);
  border-radius: var(--r-lg);
}

.quote-summary:empty {
  display: none;
}

.quote-summary > strong {
  font-size: var(--fs-lg);
}

.quote-summary > span {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.quote-summary .quote-route {
  color: var(--ok-text);
}

.quote-summary .quote-lines {
  color: var(--muted);
}

.quote-summary .quote-total {
  color: var(--muted);
  border-top-color: var(--line);
}

.quote-summary .quote-total strong {
  color: var(--ink);
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin: var(--sp-3) 0;
}


.consent {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin: var(--sp-4) 0;
  padding: var(--sp-3);
  color: var(--ink-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
}

.consent input {
  width: 20px;
  min-height: 20px;
  height: 20px;
  margin: 1px 0 0;
  flex: 0 0 auto;
}

.submit-lead {
  width: 100%;
  min-height: var(--ctl-h-lg);
  box-shadow: var(--shadow-brand-lg);
}

.lead-status:empty {
  display: none;
}

.lead-status {
  min-height: 20px;
  margin: var(--sp-3) 0 0;
  color: var(--ink-2);
  font-weight: var(--fw-bold);
  text-align: center;
}

/* El mismo nodo lleva el progreso, la advertencia de tarifa sin precio y el
   error del servidor. Sin variante, "no se pudo crear la prereserva" se leia
   en el verde de confirmacion. */
.lead-status[data-kind="ok"] {
  color: var(--ok-text);
}

.lead-status[data-kind="warn"] {
  color: var(--warn-text);
}

.lead-status[data-kind="error"] {
  color: var(--danger-text);
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1400px) {
  .public-search {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .public-search button {
    grid-column: span 1;
  }
}

@media (max-width: 1200px) {
  .public-journey {
    grid-template-columns: minmax(270px, .8fr) minmax(0, 1.4fr);
  }

  .rate-option,
  .catalog-offer .rate-option {
    grid-template-columns: 1fr;
    gap: var(--sp-3);
  }

  .rate-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
}

/* 899, no 900: con 900 este bloque y el "min-width: 900px" de mas abajo se
   aplicaban los dos a la vez a esa anchura exacta, dejando la maqueta estrecha
   sin su control de filtros. */
@media (max-width: 899px) {
  main {
    padding-top: var(--sp-6);
  }

  .public-search {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .public-journey {
    grid-template-columns: 1fr;
  }

  .package-panel {
    min-height: 0;
  }

  .package-overview {
    grid-template-columns: 160px minmax(0, 1fr);
  }

  /* La tarjeta del catalogo se queda vertical tambien aqui. Con 170px de
     imagen al lado, la copia bajaba a 181px y la cifra del precio —que por
     regla propia no se parte nunca— se salia 11px por la derecha. */
  .catalog-offer .package-overview {
    min-height: 0;
  }

  .package-copy {
    padding: var(--sp-5);
  }

  .selection-tray {
    position: static;
    grid-template-columns: 1fr;
    margin-inline: 0;
  }
}

@media (max-width: 600px) {
  .public-header {
    min-height: 64px;
    padding-inline: var(--sp-4);
  }

  .public-brand img {
    width: 154px;
    height: 40px;
  }

  .internal-link {
    display: none;
  }

  main {
    padding: var(--sp-5) var(--sp-4) var(--sp-9);
  }

  .catalog-modes {
    grid-template-columns: 1fr;
    gap: var(--sp-1);
  }

  .catalog-mode {
    min-height: 56px;
  }

  .search-shell {
    min-height: 0;
    padding: var(--sp-6) var(--sp-5);
    background-position: 68% center;
  }

  .search-heading {
    margin-bottom: var(--sp-5);
  }

  .search-heading h1 {
    font-size: 32px;
  }

  .search-heading > span {
    font-size: var(--fs-md);
  }

  /* Origen/destino/mes a lo ancho; adultos, ninos e infantes en una sola fila. */
  .public-search {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
    padding: var(--sp-3);
  }

  .public-search label:nth-of-type(-n + 3),
  .public-search button {
    grid-column: 1 / -1;
  }

  .public-search label:nth-of-type(n + 4) {
    grid-column: auto;
  }

  .public-search label {
    font-size: var(--fs-2xs);
    letter-spacing: .03em;
  }

  .child-ages label {
    width: 84px;
  }

  .section-title {
    align-items: flex-start;
    flex-direction: column;
    gap: var(--sp-3);
  }

  .section-title h2 {
    font-size: var(--fs-2xl);
  }

  .package-overview,
  .catalog-offer .package-overview {
    grid-template-columns: 1fr;
  }

  .flyer-preview,
  .flyer-pending,
  .flyer-document {
    min-height: 168px;
    max-height: 280px;
  }

  .package-copy {
    padding: var(--sp-4);
  }

  .package-copy h3 {
    font-size: var(--fs-xl);
  }

  .package-options summary,
  .rate-option {
    padding-inline: var(--sp-4);
  }

  .rate-grid,
  .catalog-offer .rate-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .package-panel-heading {
    grid-template-columns: 1fr;
    padding: var(--sp-4);
  }

  .package-panel-heading > span {
    grid-column: auto;
    text-align: left;
  }

  .departure-route {
    flex-wrap: wrap;
  }

  .selection-tray {
    padding: var(--sp-4);
  }

  .contact-body {
    padding: var(--sp-5) var(--sp-4) var(--sp-4);
  }

  .contact-footer {
    padding: var(--sp-3) var(--sp-4) var(--sp-4);
  }

  .contact-form h2 {
    font-size: var(--fs-2xl);
  }

  .form-grid {
    grid-template-columns: 1fr;
  }

  dialog {
    width: calc(100% - var(--sp-4));
  }
}

@media (max-width: 400px) {
  .rate-grid {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Tarjeta de catalogo en rejilla
   ========================================================================== */

/* Los cupos escasos se distinguen ademas del numero: quien no distingue el
   color sigue leyendo "quedan 6". */
.departure-chip-row .seats-low {
  color: var(--warn-text);
  background: var(--warn-tint);
  border-color: var(--warn-line);
  font-weight: var(--fw-extrabold);
}

.departure-chip-row .departure-chip-more {
  color: var(--muted);
  background: var(--surface-3);
  border-color: var(--line);
  font-weight: var(--fw-bold);
}

.catalog-offer .package-options > summary {
  padding: var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--line-soft);
  color: var(--brand-text);
  font-weight: var(--fw-extrabold);
  cursor: pointer;
}

.catalog-offer .package-options > summary:hover {
  background: var(--brand-tint);
}

/* ==========================================================================
   Viajeros de la prereserva
   ========================================================================== */

.booker,
.traveller-counts,
.traveller-list {
  margin: 0;
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface-2);
}

.booker legend,
.traveller-counts legend,
.traveller-list legend {
  padding: 0 var(--sp-2);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: var(--fw-extrabold);
}

/* El nombre del titular se hereda de quien reserva: se ve que es un dato
   traido, no un campo por llenar, y la nota dice de donde sale. */
.passenger-card input[readonly] {
  color: var(--muted);
  background: var(--surface-3);
  cursor: not-allowed;
}

.passenger-hint {
  margin-top: var(--sp-1);
  color: var(--muted);
  font-size: var(--fs-xs);
}

.booker .consent {
  margin-top: var(--sp-3);
}

.field-help {
  margin: 0 0 var(--sp-3);
  color: var(--muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}

/* Cada viajero es una tarjeta propia: con cuatro campos por persona y varias
   personas, una rejilla continua vuelve imposible saber que dato es de quien. */
.passenger-card {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}

.passenger-card + .passenger-card {
  margin-top: var(--sp-3);
}

.passenger-role {
  margin: 0 0 var(--sp-3);
  color: var(--brand-text);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

/* ---------- Confirmacion de la prereserva ----------
   Sustituye al formulario ya enviado. Lo que el cliente necesita anotar es el
   codigo, asi que va grande y solo; debajo, una salida que devuelve al catalogo. */
.lead-confirmacion {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-7) var(--sp-5) var(--sp-5);
  text-align: center;
}

.lead-confirmacion h2 {
  margin: 0;
  color: var(--ink);
  font-size: var(--fs-3xl);
  letter-spacing: -.01em;
}

.lead-confirmacion-total {
  margin: 0;
  color: var(--ink);
  font-size: var(--fs-xl);
  font-weight: var(--fw-extrabold);
}

.lead-confirmacion p {
  color: var(--muted);
}

.lead-confirmacion-resumen {
  margin: 0;
  color: var(--ink-2) !important;
  font-weight: var(--fw-semibold);
}

.lead-confirmacion-acciones {
  margin-top: var(--sp-2);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-3);
}

.lead-confirmacion-acciones .submit-lead {
  width: auto;
  min-width: 240px;
}

/* ---------- Entrada mas directa al producto ----------
   El primer paquete aparecia en y=691 de una ventana de 900: casi una pantalla
   entera de encabezados antes de enseñar lo que se vende. El titulo y su lema
   comparten linea, y el modo de exploracion pierde las descripciones que
   repetian lo que ya dice cada boton. */
.search-heading {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-4);
}

.search-heading h1 {
  margin: 0;
}

/* El boton de modo es una linea desde que perdio su descripcion: que mida lo
   que mide, y con el aire justo. */
.catalog-mode {
  min-height: 0;
  padding-top: var(--sp-3);
  padding-bottom: var(--sp-3);
}

/* Dos elementos que solo hablan a veces —las edades de los ninos y el aviso de
   la busqueda— reservaban 44 px cada carga aunque estuvieran vacios. Vacios no
   ocupan; cuando tengan algo que decir, vuelven. */
#childAges:empty,
.search-status:empty {
  display: none;
}

/* 48 px arriba y abajo eran 96 de relleno en la banda que hay que atravesar
   para llegar al producto; 32 seguian siendo 64. Con 20 la barra respira y el
   catalogo sube 24px. */
.search-shell {
  padding-top: var(--sp-5);
  padding-bottom: var(--sp-5);
}

/* ---------- Filtros plegables ----------
   En pantalla estrecha el formulario ocupa 396 px y empuja el producto fuera de
   la vista. Se pliega, y el control dice si estan abiertos o cerrados. */
.toggle-filtros {
  min-height: var(--ctl-h-sm);
  margin-left: auto;
  padding: 0 var(--sp-3);
  color: var(--ink-2);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  cursor: pointer;
}

.toggle-filtros:hover {
  color: var(--brand-text);
  background: var(--brand-tint);
  border-color: var(--brand-line-strong);
}

/* El plegado solo existe donde estorba. Acotarlo por ancho evita el caso que
   dejaba el formulario oculto sin control para mostrarlo: al pasar de telefono
   a escritorio la clase seguia puesta y el boton ya no estaba. */
@media (max-width: 899px) {
  .search-shell.filtros-plegados #publicSearch,
  .search-shell.filtros-plegados #childAges {
    display: none;
  }
}

/* En pantalla ancha caben sin estorbar: el control sobra. */
@media (min-width: 900px) {
  .toggle-filtros {
    display: none;
  }
}

/* Las tarifas se ven de entrada, pero con techo: sin el, un hotel con muchas
   habitaciones estiraba la tarjeta hasta llenar la pantalla y no se podian
   comparar dos paquetes. Con el techo se ve la primera opcion completa y se
   intuye que hay mas. */
.catalog-offer .package-options[open] .rate-options {
  max-height: 420px;
  overflow-y: auto;
}

/* ---------- Ruta, urgencia, servicios y confianza ---------- */
.package-route {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.urgencia {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.chip-urgencia {
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-pill);
  color: var(--ink-2);
  background: var(--surface-3);
  border: 1px solid var(--line);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
}

/* Solo lo que aprieta va en ambar: si todo urge, nada urge. */
.chip-urgencia.escaso {
  color: var(--warn-text);
  background: var(--warn-tint);
  border-color: var(--warn-line);
}

.package-servicios {
  margin: var(--sp-2) 0 0;
  color: var(--muted);
  font-size: var(--fs-sm);
}

/* La salida de bajo compromiso: presente pero por debajo de las tarifas, que
   son la accion principal. */
.package-contacto {
  padding: var(--sp-3) var(--sp-5) var(--sp-4);
  border-top: 1px solid var(--line-soft);
}

.reservar-paquete {
  width: 100%;
  min-height: var(--ctl-h);
  font-size: var(--fs-md);
  font-weight: var(--fw-extrabold);
}

.pie-publico {
  margin-top: var(--sp-8);
  padding: var(--sp-6) var(--sp-5);
  border-top: 1px solid var(--line);
}

.pie-contenido {
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  gap: var(--sp-1);
}

.pie-marca {
  margin: 0;
  color: var(--ink);
  font-weight: var(--fw-bold);
}

.pie-dato {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
}

/* "Desde COP 764.769 por persona en cuadruple" se partia en tres lineas y el
   precio quedaba cortado a la mitad. La cifra no se parte nunca; la acomodacion
   baja entera cuando no cabe. */
.package-price-lead {
  flex-wrap: wrap;
}

.package-price-lead strong {
  white-space: nowrap;
}

.package-price-lead span:last-child {
  flex: 1 1 100%;
}

@media (min-width: 1200px) {
  .package-price-lead span:last-child {
    flex: 0 1 auto;
  }
}

/* ---------- Tarjeta mas ancha y menos alta ----------
   Con columnas de 340 px minimos salian tres por fila: 453 px de ancho y 1.176
   de alto, una torre estrecha donde el flyer, las fechas y las tarifas se
   apilaban. Pidiendo mas ancho caben dos, la imagen se acuesta al lado de la
   copia y la tarjeta baja de golpe. */
.package-catalog-grid {
  /* 560 y no menos: probado a 430, la tarjeta cae a 463px de ancho, su
     interior se parte y CRECE de 564 a 765 de alto, con el precio
     desbordandose. Estrechar sin rediseniar el interior no gana scroll, lo
     pierde. Con 560, auto-fill ya da tres columnas desde ~1740px de ventana. */
  /* 300 y no 560: con la foto arriba y las tarifas plegadas, la tarjeta ya no
     necesita ancho de ficha. Da tres columnas desde ~1000px y cuatro desde
     ~1320. */
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

@media (min-width: 1080px) {
  /* La tarjeta se queda vertical tambien en pantalla ancha. Esta regla la
     devolvia a horizontal porque en vertical salia "una torre de 1.176px":
     cierto mientras las tarifas se pintaban desplegadas dentro de la tarjeta.
     Cerradas, la torre desaparece y la vertical permite cuatro por fila. */

  /* La imagen deja de mandar en el alto: acompaña. */
  .catalog-offer .flyer-frame,
  .catalog-offer .flyer-pending {
    height: 100%;
    min-height: 0;
    max-height: 260px;
  }

  /* Las dos anulaciones que habia aqui —tarifas de tres en tres y la copia del
     hotel en columna aparte— se escribieron para la tarjeta ancha de dos por
     fila. Con la tarjeta vertical de 342px pedian 350px minimos donde solo hay
     310, y las tarifas se salian 40px por la derecha al expandir. */
}

/* Campo trampa del formulario de prereserva: fuera de la vista y del foco. */
.campo-trampa {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Compartir un paquete: secundario junto a «Reservar» (2026-10-04). */
.package-contacto {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* Con «Ver el viaje» (paquetes de circuito) son tres botones y no caben en una
   linea: «Reservar» se salia de la tarjeta (2026-10-24). Va en su propia fila. */
.package-contacto:has([data-ver-viaje]) .compartir-paquete {
  flex: 1 1 0;
}

.package-contacto:has([data-ver-viaje]) .reservar-paquete {
  flex-basis: 100%;
}

.package-contacto .reservar-paquete {
  flex: 1;
}

.compartir-paquete {
  flex: none;
  min-height: var(--ctl-h);
  padding: 0 var(--sp-4);
  font-weight: var(--fw-semibold);
  border: 1px solid var(--line-strong, var(--line));
  background: var(--surface);
  color: var(--ink);
  box-shadow: none;
}

.compartir-paquete:hover {
  background: var(--surface-2);
  color: var(--ink);
}

/* La tarjeta a la que lleva un enlace compartido. */
.catalog-offer.destacada {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
}

/* En el celular la foto de portada pesa 43 KB en vez de 270 (2026-10-04). */
@media (max-width: 900px) {
  .search-shell {
    background-image: url("./assets/caribbean-hero-900.webp");
  }
}

/* Salida con menos cupos que viajeros: se ve, con el motivo, pero no se elige. */
.departure-card.sin-cupo {
  opacity: .6;
  cursor: not-allowed;
  background: var(--surface-2);
}

.departure-card.sin-cupo .seat-count {
  color: var(--muted);
  font-weight: var(--fw-semibold);
}

.seats-short {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

/* ---------- Revision visual del 2026-10-09 ---------- */

/* El flyer se encuadra por arriba (titular y destino). Como grilla centrada,
   la imagen medía 595 px de alto en una caja de 188 y se veia su mitad: la
   tabla de precios de otros hoteles. */
.catalog-offer .flyer-preview {
  display: block;
  position: relative;
}

.catalog-offer .flyer-preview img {
  position: absolute;
  inset: 0;
}

/* Un solo paquete no deja dos tercios de la pantalla vacios: la tarjeta se
   ensancha y la imagen va al lado del texto. */
@media (min-width: 900px) {
  .package-catalog-grid:has(> :only-child) {
    grid-template-columns: minmax(0, 960px);
  }

  .package-catalog-grid:has(> :only-child) .package-overview {
    grid-template-columns: minmax(0, 420px) minmax(0, 1fr);
    align-items: start;
  }
}

/* La bandeja de seleccion es fija abajo: al saltar a una tarifa se deja su
   alto libre, para que no tape lo que se acaba de elegir. */
html:has(.selection-tray) {
  scroll-padding-bottom: 190px;
}

.reservar-paquete.sin-cupo {
  background: var(--surface-2);
  color: var(--muted);
  border: 1px solid var(--line);
  box-shadow: none;
  cursor: not-allowed;
}

/* ---------- Flyer: se ve entero (2026-10-09) ----------
   Como la foto de portada de un portal de viajes: la tarjeta muestra la parte
   de arriba del flyer con un «Ver flyer» encima, y al tocarla se abre entero. */
.catalog-offer .flyer-preview,
.catalog-offer .flyer-document {
  aspect-ratio: 3 / 2;
}

.flyer-preview {
  cursor: zoom-in;
}

.flyer-preview img {
  transition: transform .25s ease;
}

.flyer-preview:hover img {
  transform: scale(1.03);
}

.flyer-ver {
  position: absolute;
  right: var(--sp-3);
  bottom: var(--sp-3);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  color: #fff;
  background: rgb(10 16 32 / .72);
  border-radius: 999px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  line-height: 1;
  backdrop-filter: blur(4px);
}

.flyer-document .flyer-ver {
  position: static;
}

.flyer-preview:focus-visible .flyer-ver,
.flyer-preview:hover .flyer-ver {
  background: var(--magenta, #e6005c);
}

/* Lo que es el paquete, antes del nombre: «Vuelo + Hotel + Traslados». */
.product-tag {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: .04em;
  text-transform: uppercase;
}

.price-note {
  color: var(--ok-text, var(--muted));
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

/* El visor ocupa la pantalla, con fondo oscuro como una galeria de fotos. */
dialog.flyer-visor {
  width: min(1100px, calc(100vw - 32px));
  height: calc(100dvh - 32px);
  max-width: none;
  max-height: none;
  color: #fff;
  background: rgb(8 12 24 / .96);
  border: 0;
  border-radius: var(--r-lg);
}

dialog.flyer-visor[open] {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
}

dialog.flyer-visor::backdrop {
  background: rgb(4 8 18 / .82);
}

.flyer-visor-barra {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-5);
}

.flyer-visor-barra h2 {
  flex: 1;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-size: var(--fs-md, 1rem);
  font-weight: var(--fw-bold);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.flyer-visor-barra a {
  color: #fff;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.flyer-visor-cerrar {
  width: 44px;
  min-height: 44px;
  padding: 0;
  color: #fff;
  background: rgb(255 255 255 / .12);
  border: 0;
  border-radius: 999px;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}

.flyer-visor-cerrar:hover {
  background: rgb(255 255 255 / .24);
}

.flyer-visor-lienzo {
  min-height: 0;
  /* Flex y no grid: en una pista de grid automatica el max-height: 100% de la
     imagen no tiene contra que medirse y el flyer se salia por abajo. */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--sp-4);
  overflow: auto;
}

.flyer-visor-lienzo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  cursor: zoom-in;
  border-radius: var(--r-sm, 4px);
}

dialog.flyer-visor.ampliado .flyer-visor-lienzo {
  display: block;
  padding: 0;
}

dialog.flyer-visor.ampliado .flyer-visor-lienzo img {
  margin: 0 auto;
  max-width: none;
  max-height: none;
  cursor: zoom-out;
  border-radius: 0;
}

.flyer-visor-ayuda {
  margin: 0;
  padding: var(--sp-2) var(--sp-4) var(--sp-3);
  color: rgb(255 255 255 / .66);
  font-size: var(--fs-xs);
  text-align: center;
}

@media (max-width: 640px) {
  dialog.flyer-visor {
    width: 100vw;
    height: 100dvh;
    border-radius: 0;
  }

  .flyer-visor-barra a {
    display: none;
  }

  .flyer-visor-lienzo {
    padding: 0;
  }
}


/* Con un dialogo abierto, la pagina de atras no rueda bajo el dedo. */
html:has(dialog[open]) {
  overflow: hidden;
}

/* ---------- Prereserva: auditoria del 2026-10-09 ---------- */

/* Cabecera fija con la X dentro: antes la X flotaba sobre los campos al rodar. */
.contact-head {
  position: relative;
  flex: 0 0 auto;
  padding: var(--sp-5) 72px var(--sp-4) var(--sp-6);
  border-bottom: 1px solid var(--line);
}

.contact-head .contact-package {
  margin: 0;
}

.contact-promesa {
  margin: var(--sp-2) 0 0;
  color: var(--ok-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.contact-head .dialog-close {
  top: var(--sp-4);
  right: var(--sp-4);
  width: 44px;
  min-height: 44px;
}

/* Los bloques iban pegados (la leyenda de cada grupo tocaba el campo de
   arriba): la regla que los separaba apuntaba a hijos que ya no existian. */
.contact-body {
  scrollbar-gutter: stable;
}

.contact-body > * + * {
  margin-top: var(--sp-5);
}

.contact-body .quote-summary {
  margin-bottom: 0;
}

.contact-form .form-grid label {
  align-content: start;
}

/* Las tres cantidades en una fila, tambien en el celular. */
.traveller-counts .form-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.traveller-counts label small,
.contact-form label small {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
}

.obligatorio {
  color: var(--danger-text);
}

.contact-form :is(input, select, textarea):user-invalid {
  border-color: var(--danger-line);
  box-shadow: 0 0 0 2px var(--danger-tint);
}

/* Con una sola fecha, el desplegable se ve como dato y no como eleccion. */
.una-sola-fecha select {
  pointer-events: none;
  appearance: none;
  background-image: none;
  background-color: var(--surface-2);
}

/* Total fijo junto al boton. */
.lead-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-3);
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.lead-total:empty {
  display: none;
}

.lead-total strong {
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--fs-xl);
}

.quote-total {
  flex-wrap: wrap;
  letter-spacing: 0;
  text-transform: none;
}

.quote-total strong {
  white-space: nowrap;
}

.contact-body {
  padding-top: var(--sp-4);
}

.quote-lines em {
  color: var(--warn-text);
  font-style: normal;
  font-weight: var(--fw-semibold);
  text-align: right;
}

/* En el celular, 16 px en los campos: con menos, iOS amplia la pagina al
   tocarlos. */
@media (max-width: 760px) {
  .contact-form :is(input, select, textarea) {
    font-size: 16px;
  }

  .contact-head {
    padding: var(--sp-4) 64px var(--sp-3) var(--sp-4);
  }

  .contact-head h2 {
    font-size: var(--fs-2xl);
  }
}

/* ---------- Circuitos (2026-10-19) ---------- */
.circuito-detalle {
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}

.circuito-detalle h4 {
  margin: var(--sp-4) 0 var(--sp-2);
  font-size: var(--fs-md);
}

.circuito-detalle h4:first-child {
  margin-top: 0;
}

.circuito-detalle ol,
.circuito-detalle ul {
  margin: 0;
  padding-left: var(--sp-5);
}

.circuito-detalle li + li {
  margin-top: var(--sp-2);
}

.circuito-detalle li p {
  margin: var(--sp-1) 0 0;
  color: var(--ink-2);
}


/* Con circuitos publicados hay tres modos: van en una fila en pantalla ancha. */
@media (min-width: 601px) {
  .catalog-modes:has(> [data-catalog-mode="circuits"]:not([hidden])) {
    max-width: 720px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ---------- Vista del viaje de un circuito ---------- */
/* El dialogo no rueda: rueda el cuerpo, y la X queda fija en su esquina. */
dialog.circuito-vista {
  width: min(860px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  overflow: hidden;
  padding: 0;
}

.circuito-vista-cuerpo {
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}

.circuito-vista .dialog-close {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  z-index: 3;
  width: 44px;
  min-height: 44px;
}

.vista-portada {
  min-height: 300px;
  display: flex;
  align-items: flex-end;
  background: linear-gradient(155deg, var(--navy) 0%, var(--navy-strong) 100%) center / cover no-repeat;
}

.vista-portada-texto {
  width: 100%;
  padding: var(--sp-8) var(--sp-6) var(--sp-5);
  color: #fff;
  background: linear-gradient(180deg, rgb(0 0 0 / 0) 0%, rgb(8 12 24 / .82) 70%);
}

.vista-tipo {
  margin: 0;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .85;
}

.vista-portada h2 {
  margin: var(--sp-1) 0 var(--sp-2);
  font-family: var(--font-display);
  font-size: clamp(24px, 4vw, 34px);
  line-height: 1.1;
}

.vista-precio {
  margin: 0;
  font-size: var(--fs-md);
}

.vista-precio strong {
  font-size: var(--fs-2xl);
}

.vista-datos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin: 0;
  padding: var(--sp-5) var(--sp-6) 0;
  list-style: none;
}

.vista-datos li {
  flex: 1 1 150px;
  display: grid;
  gap: 2px;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.vista-datos span {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.vista-ruta,
.vista-nota {
  margin: var(--sp-4) var(--sp-6) 0;
  color: var(--ink-2);
  font-weight: var(--fw-semibold);
}

.vista-seccion {
  padding: var(--sp-6) var(--sp-6) 0;
}

.vista-seccion h3 {
  margin: 0 0 var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--fs-xl);
}

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

.vista-dias > li {
  position: relative;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: var(--sp-4);
  padding-bottom: var(--sp-5);
}

/* La linea que une los dias. */
.vista-dias > li:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 19px;
  top: 40px;
  bottom: 0;
  width: 2px;
  background: var(--line);
}

.vista-dia-numero {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  color: #fff;
  background: var(--navy);
  border-radius: 50%;
  font-weight: var(--fw-extrabold);
}

.vista-dia-titulo {
  margin: 8px 0 var(--sp-1);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
}

.vista-dia-titulo em {
  color: var(--ink-2);
  font-style: normal;
  font-weight: var(--fw-semibold);
}

.vista-comidas {
  display: inline-block;
  margin: 0 0 var(--sp-2);
  padding: 2px 10px;
  color: var(--ok-text);
  background: var(--ok-tint, #e6f4ea);
  border-radius: 999px;
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

.vista-dia-texto {
  margin: 0;
  color: var(--ink-2);
  line-height: 1.6;
}

.vista-columnas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-5);
}

.vista-incluye,
.vista-no-incluye {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--sp-2);
}

.vista-incluye li,
.vista-no-incluye li {
  position: relative;
  padding-left: 26px;
  line-height: 1.45;
}

.vista-incluye li::before,
.vista-no-incluye li::before {
  position: absolute;
  left: 0;
  font-weight: var(--fw-extrabold);
}

.vista-incluye li::before {
  content: "✓";
  color: var(--ok-text);
}

.vista-no-incluye li::before {
  content: "✕";
  color: var(--danger-text);
}

.vista-hoteles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--sp-3);
}

.vista-hoteles > div {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.vista-hoteles p {
  margin: 0;
}

.vista-categoria {
  margin-bottom: var(--sp-1) !important;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
}

.vista-fechas {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.vista-fechas li {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
}

.vista-accion {
  position: sticky;
  bottom: 0;
  margin-top: var(--sp-6);
  padding: var(--sp-4) var(--sp-6);
  background: var(--surface);
  border-top: 1px solid var(--line);
}

.vista-accion .reservar-paquete {
  width: 100%;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@media (max-width: 640px) {
  dialog.circuito-vista {
    width: 100vw;
    max-height: 100dvh;
    border-radius: 0;
  }

  .circuito-vista-cuerpo {
    max-height: 100dvh;
  }

  .vista-seccion,
  .vista-datos {
    padding-left: var(--sp-4);
    padding-right: var(--sp-4);
  }

  .vista-ruta,
  .vista-nota {
    margin-left: var(--sp-4);
    margin-right: var(--sp-4);
  }
}

/* Auditoria visual 2026-10-19. */
.circuito-oferta .flyer-preview {
  width: 100%;
  padding: 0;
  border: 0;
  cursor: pointer;
}

.vista-extras {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--sp-2);
}

.vista-extras li {
  position: relative;
  padding-left: 26px;
}

.vista-extras li::before {
  content: "+";
  position: absolute;
  left: 2px;
  color: var(--brand-text);
  font-weight: var(--fw-extrabold);
}


/* ==========================================================================
   Catalogo parejo y ventana de hoteles y tarifas (2026-10-25)
   ========================================================================== */

/* Tarjetas de una fila igual de altas y con los botones a la misma altura: con
   textos de distinto largo quedaban disparejas. */
/* auto-fit: con tres paquetes en una pantalla de cuatro columnas quedaba una
   columna vacia a la derecha. Un paquete solo no se estira a todo el ancho. */
.package-catalog-grid {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  align-items: stretch;
}

.package-catalog-grid:has(> .catalog-offer:only-child) {
  grid-template-columns: minmax(300px, 460px);
}

.catalog-offer {
  display: flex;
  flex-direction: column;
}

.catalog-offer .package-overview {
  flex: 1 1 auto;
}

/* Lo que incluye y los servicios, en dos lineas como maximo: el detalle
   completo esta en la ventana del paquete. */
.catalog-offer .package-servicios {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ver-opciones {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--sp-5);
  color: var(--brand-text);
  background: var(--surface);
  border: 0;
  border-top: 1px solid var(--line-soft);
  border-radius: 0;
  box-shadow: none;
  font-size: var(--fs-sm);
  font-weight: var(--fw-extrabold);
  text-align: left;
}

.ver-opciones::after {
  content: "›";
  float: right;
  font-size: var(--fs-lg);
  line-height: 1;
}

.ver-opciones:hover {
  color: var(--brand-text);
  background: var(--brand-tint);
  filter: none;
}

/* El vuelo en la tarjeta: una linea por tramo. */
.package-vuelo {
  display: grid;
  gap: 2px;
  margin-top: var(--sp-1);
}

.package-vuelo p {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.package-vuelo span {
  display: inline-block;
  min-width: 68px;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
}

/* El vuelo en las ventanas: ida y regreso lado a lado. */
.vuelo-bloque {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-3);
  margin: var(--sp-4) var(--sp-6) 0;
}

.vuelo-tramo {
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

.vuelo-tramo p {
  margin: 0;
}

.vuelo-nombre {
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
}

.vuelo-horas {
  margin: var(--sp-1) 0 !important;
  font-size: var(--fs-md);
}

.vuelo-horas strong {
  font-size: var(--fs-lg);
}

.vuelo-horas small,
.vuelo-numero {
  color: var(--muted);
  font-size: var(--fs-xs);
}

/* La ventana: cuerpo que rueda y pie fijo con la eleccion. */
dialog.opciones-vista {
  width: min(1040px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  overflow: hidden;
}

.opciones-cuerpo {
  display: flex;
  flex-direction: column;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}

.opciones-cabeza {
  display: grid;
  gap: var(--sp-1);
  padding: var(--sp-6) var(--sp-8) 0 var(--sp-6);
}

.opciones-cabeza h2 {
  margin: 0;
  font-size: var(--fs-2xl);
  line-height: var(--lh-tight);
}

.opciones-cabeza .package-route {
  margin: 0;
}

.opciones-cuerpo > .package-warning {
  margin: var(--sp-4) var(--sp-6) 0;
}

.opciones-ayuda {
  margin: var(--sp-5) var(--sp-6) var(--sp-2);
  color: var(--muted);
  font-size: var(--fs-sm);
}

.opciones-hoteles {
  display: grid;
  gap: var(--sp-3);
  padding: 0 var(--sp-6) var(--sp-5);
}

.opcion-hotel {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
}

.opcion-foto {
  position: relative;
  overflow: hidden;
  min-height: 160px;
  display: grid;
  place-items: center;
  background: linear-gradient(155deg, var(--navy) 0%, var(--navy-strong, var(--navy)) 100%);
}

.opcion-foto img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.opcion-foto span {
  color: #fff;
  font-size: var(--fs-4xl);
  font-weight: var(--fw-extrabold);
  opacity: .7;
}

.opcion-hotel-cuerpo {
  display: grid;
  align-content: start;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
}

.opcion-hotel-cuerpo h3 {
  margin: 0;
  font-size: var(--fs-lg);
}

.opcion-habitacion {
  display: grid;
  gap: var(--sp-2);
}

.opcion-habitacion + .opcion-habitacion {
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line-soft);
}

.opcion-habitacion-nombre {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.opcion-habitacion-nombre span {
  color: var(--muted);
  font-weight: var(--fw-regular);
}

.opcion-menores {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
}

/* Las mismas columnas en todas las habitaciones del paquete: la doble siempre
   debajo de la doble. */
.opcion-tarifas {
  display: grid;
  grid-template-columns: repeat(var(--columnas, 4), minmax(0, 1fr));
  gap: var(--sp-2);
}

.opcion-tarifas .rate-choice {
  min-height: 56px;
}

/* La casilla de una acomodacion que no existe: se ve que es un hueco a
   proposito, sin escribir nada. */
.tarifa-vacia {
  min-height: 56px;
  border: 1px dashed var(--line);
  border-radius: var(--r-lg);
}

.opciones-pie {
  position: sticky;
  bottom: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding: var(--sp-4) var(--sp-6);
  background: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: 0 -8px 20px rgb(0 0 0 / .06);
}

.opciones-eleccion {
  flex: 1 1 320px;
  display: grid;
  gap: 2px;
  margin: 0;
  font-size: var(--fs-sm);
}

.opciones-eleccion.vacia {
  color: var(--muted);
}

.opciones-eleccion span {
  color: var(--muted);
}

.opciones-eleccion .opciones-total {
  color: var(--ink);
}

.opciones-total strong {
  font-size: var(--fs-lg);
}

.opciones-pie .reservar-paquete {
  width: auto;
  min-width: 240px;
}

@media (max-width: 720px) {
  .opcion-hotel {
    grid-template-columns: minmax(0, 1fr);
  }

  .opcion-foto {
    min-height: 0;
    aspect-ratio: 16 / 9;
  }

  .opcion-tarifas {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tarifa-vacia {
    display: none;
  }

  .opciones-cabeza,
  .opciones-hoteles,
  .opciones-pie {
    padding-left: var(--sp-4);
    padding-right: var(--sp-4);
  }

  .opciones-cabeza {
    padding-right: 64px;
  }

  .vuelo-bloque,
  .opciones-ayuda,
  .opciones-cuerpo > .package-warning {
    margin-left: var(--sp-4);
    margin-right: var(--sp-4);
  }

  .opciones-pie .reservar-paquete {
    width: 100%;
  }
}

/* ==========================================================================
   Catalogo en filas (2026-10-25): foto | viaje | precio y accion
   ========================================================================== */

.package-catalog-grid {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
}

.package-catalog-grid:has(> .catalog-offer:only-child) {
  grid-template-columns: minmax(0, 1fr);
}

.catalog-offer.catalogo-fila {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr) 260px;
  min-height: 240px;
  border-radius: var(--r-xl);
}

/* La foto llena su columna a la altura de la tarjeta. El flyer es un cartel
   vertical: se encuadra por arriba, donde va el titular. */
.catalogo-foto {
  position: relative;
  min-height: 240px;
  overflow: hidden;
  background: var(--navy);
}

.catalogo-foto > .flyer-preview,
.catalogo-foto > .flyer-pending,
.catalogo-foto > .flyer-document {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  min-height: 0;
  border-radius: 0;
}

.catalogo-foto .flyer-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

.catalogo-info {
  display: grid;
  align-content: start;
  gap: var(--sp-2);
  min-width: 0;
  padding: var(--sp-5) var(--sp-6);
}

.catalogo-info .product-tag {
  margin: 0;
}

.catalogo-info h3 {
  margin: 0;
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
}

.catalogo-info .package-route,
.catalogo-resumen {
  margin: 0;
}

.catalogo-resumen {
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.catalogo-info .package-servicios {
  margin: 0;
}

/* El precio a la derecha, alineado como en los listados: arriba la cifra,
   abajo la accion. */
.catalogo-precio {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-1);
  padding: var(--sp-5);
  text-align: right;
  border-left: 1px solid var(--line-soft);
}

.catalogo-precio .package-price-lead {
  justify-items: end;
  text-align: right;
}

.catalogo-opciones {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
}

.catalogo-acciones {
  display: grid;
  gap: var(--sp-2);
  width: 100%;
  margin-top: auto;
  padding-top: var(--sp-3);
}

.catalogo-acciones .reservar-paquete {
  width: 100%;
}

.catalogo-secundarias {
  display: flex;
  gap: var(--sp-4);
  justify-content: flex-end;
}

.enlace-accion {
  min-height: 32px;
  padding: 0;
  color: var(--ink-2);
  background: none;
  border: 0;
  box-shadow: none;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.enlace-accion:hover {
  color: var(--brand-text);
  background: none;
  filter: none;
}

/* Portatil: la columna del precio se angosta. */
@media (max-width: 1100px) {
  .catalog-offer.catalogo-fila {
    grid-template-columns: 240px minmax(0, 1fr) 220px;
  }
}

/* Telefono y tableta: foto arriba, el viaje y debajo el precio con su accion. */
@media (max-width: 820px) {
  .catalog-offer.catalogo-fila {
    grid-template-columns: minmax(0, 1fr);
  }

  .catalogo-foto {
    min-height: 0;
    aspect-ratio: 16 / 9;
  }

  .catalogo-info {
    padding: var(--sp-4) var(--sp-4) var(--sp-2);
  }

  .catalogo-precio {
    align-items: stretch;
    text-align: left;
    padding: var(--sp-3) var(--sp-4) var(--sp-4);
    border-left: 0;
    border-top: 1px solid var(--line-soft);
  }

  .catalogo-precio .package-price-lead {
    justify-items: start;
    text-align: left;
  }

  .catalogo-secundarias {
    justify-content: center;
  }
}

/* En oscuro los logos a color (azul marino de JetSMART y LATAM) se perderian:
   van sobre una placa clara, como en el sitio de cada aerolinea. Los blancos
   ya traen su placa de color. */
html[data-theme="dark"] img.aerolinea-logo:not(.aerolinea-placa img) {
  padding: 2px 6px;
  background: #fff;
  border-radius: 6px;
  box-sizing: content-box;
}

/* ---------- Tarjeta del catalogo, 2026-11-07 ----------
   Referencia: los listados de Booking. Lo incluido con chulo verde, la
   salida en un bloque con borde, el hotel con nombre, para quien es el precio
   y la urgencia real junto a la cifra. Magenta sigue solo en la accion. */
.catalogo-titulo {
  display: inline;
  min-height: 0;
  padding: 0;
  color: var(--ink);
  background: none;
  border: 0;
  box-shadow: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.catalogo-titulo:hover,
.catalogo-titulo:focus-visible {
  color: var(--ink);
  background: none;
  filter: none;
  text-decoration: underline;
  text-underline-offset: 4px;
}

.catalogo-salida {
  display: grid;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-3);
  border-left: 3px solid var(--line);
}

.catalogo-salida-fecha {
  margin: 0;
  color: var(--ink);
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
}

.catalogo-salida-fecha span {
  color: var(--ink-2);
  font-weight: var(--fw-semibold);
}

.catalogo-salida .departure-chip-row {
  margin: 0;
}

.catalogo-salida-vuelo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-3);
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.catalogo-horas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
  font-variant-numeric: tabular-nums;
}

.catalogo-tramo small {
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.catalogo-equipaje {
  color: var(--muted);
}

.catalogo-hoteles {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.catalogo-hoteles strong {
  color: var(--ink);
}

.catalogo-hoteles span {
  color: var(--muted);
}

.catalogo-incluye {
  display: flex;
  flex-wrap: wrap;
  gap: 2px var(--sp-4);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-sm);
}

.catalogo-incluye li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-2);
}

.catalogo-incluye li svg {
  flex: none;
  color: var(--ok-text);
}

.catalogo-incluye-mas {
  color: var(--muted);
  font-weight: var(--fw-semibold);
}

.catalogo-servicios {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.catalogo-servicios span {
  margin-right: 4px;
  color: var(--muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
}

.catalogo-contexto {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-xs);
}

.catalogo-total {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-xs);
}

.catalogo-quedan {
  margin: var(--sp-1) 0 0;
  color: var(--danger-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
}
