/* ==========================================================================
   Secciones — hero a pantalla completa, tarjetas de experiencia, vídeo
   explicativo, parte del día, recorrido, menú "Explora", selector de
   experiencias y botón flotante de WhatsApp.

   SE LLAMABA video.css. El cambio de nombre no es cosmético: en el servidor
   ese archivo se quedó devolviendo 403 y solo él, porque al descomprimir un
   ZIP encima de otro los permisos del archivo que YA existía no siempre se
   actualizan, y la primera versión que se subió tenía los suyos mal. El
   resultado era un sitio en el que todo lo demás cargaba y las paradas del
   recorrido no se veían: sin este archivo no tienen ni forma ni color.
   Un nombre nuevo es un archivo nuevo, y un archivo nuevo se crea con los
   permisos que le tocan. Si vuelve a pasar con otro, la solución de fondo es
   borrar la carpeta antes de subir — que ya se puede, porque el mapa viaja
   dentro del ZIP.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Vídeo de fondo

   Regla común a todo el archivo: el vídeo NUNCA es el contenido, siempre
   es el fondo. Debajo de cada <video> hay un póster que se pinta primero
   (es lo que mide el LCP) y encima un degradado que garantiza el contraste
   del texto pase lo que pase con el metraje. Si el vídeo no llega a cargar
   —conexión lenta, ahorro de datos, prefers-reduced-motion, un móvil que
   niega el autoplay— la sección se ve exactamente igual de acabada con el
   póster solo. Ese es el criterio: el vídeo suma, nunca sostiene.

   El elemento <video> se escribe sin src: assets/js/video-bg.js inyecta la
   fuente cuando toca. Ver ahí las condiciones de carga.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Capa de medios reutilizable — la comparten hero, tarjetas y banda del
   parte. El póster va como <img> real y no como background-image para que
   entre en el preload scanner del navegador y pueda ser el LCP.
   -------------------------------------------------------------------------- */
.media-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background-color: var(--color-ink);
}

.media-layer__poster,
.media-layer__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.media-layer__video {
  opacity: 0;
  transition: opacity 700ms var(--ease-premium);
}

/* video-bg.js marca el vídeo como listo solo cuando hay fotogramas reales
   pintables (readyState >= 3). Hasta entonces sigue viéndose el póster, así
   que nunca hay un parpadeo en negro entre uno y otro. */
.media-layer__video[data-video-ready="true"] {
  opacity: 1;
}

/* --------------------------------------------------------------------------
   Hero de vídeo
   -------------------------------------------------------------------------- */
.hero-video {
  position: relative;
  /* Columna con el contenido abajo, y NO 'row + align-items:flex-end'.
     Parece equivalente y no lo es: en fila, la altura es el eje
     transversal, min-height no actúa como suelo del que crecer y, si el
     contenido supera la caja, flex-end lo desborda por ARRIBA — donde
     overflow:hidden se lo come. En la página de Tabarca las migas de pan
     y el antetítulo desaparecían literalmente debajo de la cabecera por
     esto. En columna la altura es el eje principal: la sección crece con
     su contenido y min-height vuelve a ser lo que dice ser, un mínimo. */
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  isolation: isolate;
  color: var(--color-white);
  background-color: var(--color-black);
  /* svh y no vh: en móvil, vh mide el viewport con la barra del navegador
     retraída, así que un hero a 100vh queda cortado por abajo justo al
     cargar, que es cuando la barra está desplegada. */
  min-height: 88svh;
  /* El padding inferior reserva sitio para el dock flotante: sin él, la
     última línea del hero queda justo debajo de la píldora. De 900px
     arriba el dock no existe y el valor vuelve a lo normal. */
  padding-block: calc(var(--header-height) + var(--space-12))
                 calc(var(--mobile-cta-height) + var(--space-10));
}

@media (min-width: 900px) {
  .hero-video {
    min-height: 92svh;
    padding-block: calc(var(--header-height) + var(--space-16)) var(--space-12);
  }
}

/* Portada de una sola pantalla, al estilo de la referencia. Ocupa el
   viewport exacto y el scroll se bloquea en <html> y <body> (ver más
   abajo): sin ese bloqueo, el rebote elástico de iOS deja asomar una
   franja negra bajo el vídeo al arrastrar, que es justo lo que delata
   que "no hay scroll" es un apaño y no una decisión.

   100svh y no 100dvh: dvh se recalcula mientras la barra del navegador se
   retrae al desplazar, y en una pantalla que no desplaza eso solo
   introduce saltos de layout. svh es el valor estable con la barra
   desplegada, que es como se ve al entrar. */
.hero-video--full {
  min-height: 100svh;
  height: 100svh;
}

html.home-fija,
body.home-fija {
  height: 100%;
  overflow: hidden;
  /* Corta el rebote elástico en iOS y en los trackpads de macOS. */
  overscroll-behavior: none;
}

/* Enlaces legales dentro del hero: en una portada sin scroll no hay pie
   al que llegar y son obligatorios. Discretos pero presentes. */
.hero-video__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-6);
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.45);
}

.hero-video__legal a {
  color: rgba(255, 255, 255, 0.55);
  text-decoration: none;
}

.hero-video__legal a:hover,
.hero-video__legal a:focus-visible {
  color: var(--color-white);
  text-decoration: underline;
}

/* Variante corta para páginas de producto: el panel de reserva es el punto
   de esas páginas y tiene que caber en la primera pantalla en escritorio. */
.hero-video--compact {
  min-height: 62svh;
  padding-block: calc(var(--header-height) + var(--space-10))
                 calc(var(--mobile-cta-height) + var(--space-8));
}

@media (min-width: 900px) {
  .hero-video--compact {
    min-height: 66svh;
    padding-block: calc(var(--header-height) + var(--space-12)) var(--space-10);
  }
}

.hero-video .media-layer {
  z-index: -2;
}

/* Dos degradados, cada uno con un trabajo distinto:
   · el vertical asienta el bloque de texto de abajo
   · el lateral protege el texto en escritorio, donde la columna es estrecha
     y a su derecha el metraje debe quedar limpio y a todo color
   Además un velo plano muy leve, porque el spray al sol tiene zonas casi
   blancas que se comen el texto por sí solas. */
.hero-video__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(
      180deg,
      rgba(8, 8, 10, 0.42) 0%,
      rgba(8, 8, 10, 0.10) 22%,
      rgba(8, 8, 10, 0.28) 50%,
      rgba(8, 8, 10, 0.94) 100%
    ),
    rgba(8, 8, 10, 0.10);
}

@media (min-width: 900px) {
  .hero-video__scrim {
    background:
      linear-gradient(
        180deg,
        rgba(8, 8, 10, 0.50) 0%,
        rgba(8, 8, 10, 0.10) 30%,
        rgba(8, 8, 10, 0.25) 60%,
        rgba(8, 8, 10, 0.90) 100%
      ),
      linear-gradient(
        90deg,
        rgba(8, 8, 10, 0.80) 0%,
        rgba(8, 8, 10, 0.45) 26%,
        rgba(8, 8, 10, 0) 52%
      ),
      rgba(8, 8, 10, 0.10);
  }
}

/* AQUÍ ESTABA EL FALLO DEL SCROLL. Léelo antes de tocar nada.
   ---------------------------------------------------------------------
   Esto era:

       max-height: 100%;
       overflow-y: auto;
       overscroll-behavior: contain;

   La intención era buena: con flex-direction:column + justify-content:
   flex-end, un contenido más alto que la caja se desborda por ARRIBA, y
   arriba está la cabecera fija, así que en pantallas cortas el logo tapaba
   el sello de valoración. Aquello lo convertía en un desplazamiento dentro
   del propio hero.

   El efecto real en un móvil era otro. En cuanto el contenido del hero no
   cabe —y en un teléfono no cabe casi nunca— este bloque se convierte en un
   contenedor con scroll propio. El dedo aterriza SIEMPRE sobre él, porque
   ocupa todo el hero. Así que arrastrar movía unos píxeles de esta caja y
   se paraba en seco: `overscroll-behavior: contain` impide expresamente que
   el gesto pase a la página de detrás.

   Desde fuera eso es "la web no hace scroll". Y encajaba con todo lo que se
   reportó: no se llegaba a las preguntas frecuentes, ni a los detalles de
   una excursión, ni a "lo que incluye"; y en cuanto se pulsaba Reservar
   —que salta a #booking, ya por debajo del hero— el scroll "volvía".

   Nunca se reprodujo en las pruebas porque en un viewport de escritorio el
   contenido del hero SÍ cabe, no hay desbordamiento y la caja no atrapa
   nada.

   Ahora el hero crece con su contenido, que es lo que ya permitía su
   min-height, y la página se desplaza como cualquier otra. El problema del
   contenido tapado por la cabecera se resuelve donde toca: en el
   padding-block superior del hero, que reserva --header-height.

   La única excepción es la portada de una sola pantalla (--full), que sí
   tiene altura fija y donde la página de detrás no se desplaza: ahí el
   scroll interno es correcto y sigue puesto, más abajo. */
.hero-video__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  /* Sin esto, en columna el navegador podría encoger el bloque por debajo
     de su contenido para hacerlo caber en min-height. */
  flex-shrink: 0;
}

/* Solo la portada de una pantalla: ahí la altura es fija (100svh) y el
   documento no se desplaza, así que atrapar el gesto dentro del hero no
   quita nada — y evita que el contenido se salga por arriba, detrás de la
   cabecera. */
.hero-video--full .hero-video__inner {
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Migas de pan sobre vídeo: el gris apagado por defecto se pierde encima
   del metraje. (La regla equivalente de components.css apunta a
   .hero-cinematic, que ya no existe en ninguna página.) */
.hero-video .breadcrumbs {
  margin-bottom: var(--space-5);
}

.hero-video .breadcrumbs__list,
.hero-video .breadcrumbs__list a {
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.7);
}

.hero-video .breadcrumbs__list a:hover {
  color: var(--color-white);
}

.hero-video__content {
  max-width: 640px;
}

.hero-video h1 {
  font-size: clamp(2.5rem, 1.6rem + 3.6vw, 4.75rem);
  color: var(--color-white);
  margin-bottom: var(--space-5);
  text-wrap: balance;
  letter-spacing: -0.025em;
}

.hero-video--compact h1 {
  font-size: clamp(2rem, 1.5rem + 1.9vw, 3.25rem);
}

.hero-video__lead {
  font-size: var(--fs-300);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.88);
  max-width: 48ch;
  margin-bottom: var(--space-6);
}

/* Fila superior: valoración y sello de confianza, al estilo de las fichas
   de producto de las OTA. Va arriba del titular a propósito — es lo que
   convierte una portada bonita en una portada que vende. */
.hero-video__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.rating-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.8125rem;
  background: rgba(255, 255, 255, 0.10);
  border: 1px solid rgba(255, 255, 255, 0.20);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-radius: 100px;
  padding: 5px var(--space-3);
  color: var(--color-white);
}

.rating-badge__score {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-300);
  line-height: 1;
}

.rating-badge__stars {
  color: var(--color-primary-bright);
  letter-spacing: 0.06em;
  line-height: 1;
}

.rating-badge__count {
  color: rgba(255, 255, 255, 0.72);
}

.hero-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  background: rgba(var(--color-primary-rgb), 0.18);
  border: 1px solid rgba(var(--color-primary-rgb), 0.55);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-radius: 100px;
  padding: 5px var(--space-3);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-white);
}

/* Fila de argumentos bajo los botones: sin licencia, seguro, confirmación.
   Separadas por un punto magenta, no por bordes: menos ruido a esta escala. */
.hero-video__facts {
  display: none;
}

@media (min-width: 900px) {
  .hero-video__facts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  }
}

.hero-video__fact {
  position: relative;
  font-size: var(--fs-100);
  font-weight: 600;
  color: rgba(255, 255, 255, 0.86);
}

.hero-video__fact + .hero-video__fact::before {
  content: '';
  position: absolute;
  left: calc(var(--space-5) / -2);
  top: 50%;
  transform: translate(-50%, -50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: var(--color-primary);
}

/* Indicador de scroll — solo en escritorio, donde hay hero a pantalla
   completa y cabe la duda de si hay algo más abajo. */
.hero-video__cue {
  display: none;
}

@media (min-width: 900px) {
  .hero-video__cue {
    position: absolute;
    z-index: 1;
    right: var(--space-8);
    bottom: var(--space-10);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    font-size: var(--fs-100);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: rgba(255, 255, 255, 0.55);
    writing-mode: vertical-rl;
  }

  .hero-video__cue::after {
    content: '';
    width: 1px;
    height: 56px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
    animation: cue-slide 2.2s var(--ease-premium) infinite;
  }
}

@keyframes cue-slide {
  0%   { transform: scaleY(0); transform-origin: top; }
  45%  { transform: scaleY(1); transform-origin: top; }
  55%  { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* --------------------------------------------------------------------------
   Tarjetas de experiencia con vídeo — el bloque "elige tu experiencia".
   El vídeo va a pantalla completa dentro de la tarjeta y el texto flota
   encima sobre un degradado, en vez de ir en un cuerpo blanco debajo: es
   lo que hace que tres tarjetas juntas se lean como tres ventanas al mar
   y no como tres fichas de catálogo.
   -------------------------------------------------------------------------- */
.tour-cards {
  display: grid;
  gap: var(--space-5);
}

@media (min-width: 700px) {
  .tour-cards {
    grid-template-columns: repeat(3, 1fr);
  }
}

.tour-card {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-xl);
  overflow: hidden;
  isolation: isolate;
  text-decoration: none;
  color: var(--color-white);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  transition:
    transform var(--transition-standard) var(--ease-premium),
    box-shadow var(--transition-standard) var(--ease-premium),
    border-color var(--transition-standard) var(--ease-premium);
}

@media (min-width: 700px) {
  .tour-card {
    aspect-ratio: 4 / 5;
  }
}

.tour-card:hover,
.tour-card:focus-visible {
  transform: translateY(-8px);
  border-color: rgba(var(--color-primary-rgb), 0.55);
  box-shadow: var(--shadow-lg);
}

.tour-card .media-layer {
  z-index: -2;
  background-color: var(--color-surface);
}

.tour-card .media-layer__poster,
.tour-card .media-layer__video {
  transition: transform var(--transition-slow) var(--ease-premium), opacity 700ms var(--ease-premium);
}

.tour-card:hover .media-layer__poster,
.tour-card:hover .media-layer__video {
  transform: scale(1.06);
}

.tour-card__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    rgba(8, 8, 10, 0.45) 0%,
    rgba(8, 8, 10, 0.05) 30%,
    rgba(8, 8, 10, 0.62) 68%,
    rgba(8, 8, 10, 0.94) 100%
  );
}

.tour-card__body {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-6);
}

.tour-card__badge {
  position: absolute;
  top: var(--space-5);
  left: var(--space-5);
  background-color: var(--color-primary);
  color: var(--color-white);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: var(--space-1) var(--space-3);
  border-radius: 100px;
}

.tour-card__duration {
  font-size: var(--fs-100);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--color-primary-bright);
}

.tour-card__name {
  font-family: var(--font-display);
  font-size: var(--fs-500);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--color-white);
}

.tour-card__desc {
  font-size: var(--fs-100);
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.78);
  margin: 0;
}

.tour-card__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.20);
}

.tour-card__price {
  font-family: var(--font-display);
  font-size: var(--fs-500);
  font-weight: 700;
  line-height: 1;
  color: var(--color-white);
}

.tour-card__price small {
  font-family: var(--font-body);
  font-size: var(--fs-100);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.65);
}

/* Flecha en vez de botón: la tarjeta entera ya es el enlace, así que un
   botón dentro sería un objetivo de clic dentro de otro. La flecha indica
   la acción sin fingir ser un control aparte. */
.tour-card__go {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background-color: var(--color-primary);
  color: var(--color-white);
  font-size: 1.1rem;
  line-height: 1;
  transition: transform var(--transition-fast), background-color var(--transition-fast);
}

.tour-card:hover .tour-card__go {
  transform: translateX(4px);
  background-color: var(--color-primary-bright);
}

/* --------------------------------------------------------------------------
   Vídeo explicativo — este sí es contenido, no fondo: arranca parado, con
   controles, y solo suena si el visitante lo decide.
   -------------------------------------------------------------------------- */
.explainer {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  aspect-ratio: 16 / 9;
}

.explainer video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.explainer__play {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  width: 100%;
  border: none;
  cursor: pointer;
  color: var(--color-white);
  background: linear-gradient(180deg, rgba(8, 8, 10, 0.25) 0%, rgba(8, 8, 10, 0.55) 100%);
  transition: background-color var(--transition-standard), opacity var(--transition-standard);
}

.explainer__play[hidden] {
  display: none;
}

.explainer__play-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 76px;
  height: 76px;
  border-radius: 50%;
  background-color: var(--color-primary);
  box-shadow: var(--shadow-primary);
  transition: transform var(--transition-standard) var(--ease-premium);
}

/* Triángulo en CSS puro: un icono más que cargar por un play sería
   desproporcionado, y así nunca puede faltar el archivo. */
.explainer__play-icon::before {
  content: '';
  border-style: solid;
  border-width: 13px 0 13px 21px;
  border-color: transparent transparent transparent var(--color-white);
  margin-left: 5px;
}

.explainer__play:hover .explainer__play-icon,
.explainer__play:focus-visible .explainer__play-icon {
  transform: scale(1.09);
}

.explainer__play-label {
  font-family: var(--font-display);
  font-size: var(--fs-300);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6);
}

/* --------------------------------------------------------------------------
   Parte del día — estado del mar en Alicante, sobre metraje de mar abierto.
   Los datos los sirve api/parte-del-dia.php (Open-Meteo) y los pinta
   assets/js/parte-del-dia.js. Si la API falla, el bloque se oculta entero
   en vez de enseñar guiones: un parte del mar vacío da peor impresión que
   no tener parte.
   -------------------------------------------------------------------------- */
.parte {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background-color: var(--color-ink);
  border-block: 1px solid var(--color-border);
  padding-block: var(--space-12);
}

.parte .media-layer {
  z-index: -2;
}

.parte__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(8, 8, 10, 0.94) 0%, rgba(8, 8, 10, 0.78) 45%, rgba(8, 8, 10, 0.55) 100%),
    rgba(8, 8, 10, 0.35);
}

.parte__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-3) var(--space-5);
  margin-bottom: var(--space-6);
}

.parte__title {
  font-family: var(--font-display);
  font-size: var(--fs-400);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--color-white);
}

.parte__place {
  font-size: var(--fs-100);
  color: var(--color-text-muted);
}

/* Punto latiendo: señala que el dato es de ahora mismo y no un texto fijo
   escrito una vez. */
.parte__live {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-100);
  font-weight: 600;
  color: var(--color-primary-bright);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.parte__live::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--color-primary);
  box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0.7);
  animation: parte-pulse 2.4s ease-out infinite;
}

@keyframes parte-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0.65); }
  70%  { box-shadow: 0 0 0 12px rgba(var(--color-primary-rgb), 0); }
  100% { box-shadow: 0 0 0 0 rgba(var(--color-primary-rgb), 0); }
}

.parte__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-3);
}

@media (min-width: 700px) {
  .parte__grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.parte__stat {
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

.parte__stat-label {
  display: block;
  font-size: var(--fs-100);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.parte__stat-value {
  font-family: var(--font-display);
  font-size: var(--fs-500);
  font-weight: 700;
  line-height: 1;
  color: var(--color-white);
}

.parte__stat-value small {
  font-family: var(--font-body);
  font-size: var(--fs-100);
  font-weight: 500;
  color: var(--color-text-muted);
  margin-left: 2px;
}

/* Veredicto en una línea: la mayoría de la gente no sabe traducir "0,4 m de
   ola" a "¿puedo salir hoy?". Esta frase lo traduce. */
.parte__verdict {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  background: rgba(var(--color-primary-rgb), 0.12);
  border: 1px solid rgba(var(--color-primary-rgb), 0.35);
  font-weight: 600;
  color: var(--color-white);
}

.parte__updated {
  margin: var(--space-4) 0 0;
  font-size: var(--fs-100);
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   WhatsApp flotante. En móvil ya existe la barra fija inferior con WhatsApp
   dentro, así que aquí solo aparece de 900px arriba: repetir la misma
   acción dos veces en una pantalla de 390px es robarle sitio al contenido.
   -------------------------------------------------------------------------- */
.wa-float {
  display: none;
}

@media (min-width: 900px) {
  .wa-float {
    position: fixed;
    right: var(--space-6);
    bottom: var(--space-6);
    z-index: var(--z-mobile-cta);
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5) var(--space-3) var(--space-3);
    border-radius: 100px;
    background-color: #25D366;
    color: #06301A;
    font-weight: 700;
    font-size: var(--fs-100);
    text-decoration: none;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
  }

  .wa-float:hover,
  .wa-float:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 16px 38px rgba(0, 0, 0, 0.6);
    color: #06301A;
  }
}

.wa-float__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.92);
  flex-shrink: 0;
}

.wa-float__icon svg {
  width: 20px;
  height: 20px;
  fill: #25D366;
}

/* --------------------------------------------------------------------------
   Cabecera de sección al estilo de la referencia: antetítulo pequeño en
   magenta sobre un titular grande, alineado a la izquierda.
   -------------------------------------------------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-3);
  color: var(--color-primary-bright);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: var(--fs-100);
  margin-bottom: var(--space-3);
}

.eyebrow::before {
  content: '';
  flex: 0 0 32px;
  height: 2px;
  /* Centrada sobre la primera línea de texto (0.875rem × 1.6 de
     interlineado ≈ 22px), no sobre el bloque entero: si el antetítulo
     parte en dos líneas, la rayita debe seguir junto a la primera. */
  margin-top: 0.65rem;
  background-color: var(--color-primary);
}

.section-title {
  font-size: var(--fs-600);
  letter-spacing: -0.025em;
  margin-bottom: var(--space-4);
  text-wrap: balance;
}

.section-intro {
  color: var(--color-text-muted);
  font-size: var(--fs-300);
  max-width: 58ch;
  margin-bottom: var(--space-10);
}

/* --------------------------------------------------------------------------
   Movimiento reducido: se congela todo lo que se mueve solo. video-bg.js
   además no llega ni a pedir los archivos en este caso, así que esto es la
   red de seguridad para el vídeo explicativo (que el usuario sí arranca a
   mano) y para las animaciones decorativas.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .media-layer__video {
    display: none;
  }

  .hero-video__cue::after,
  .parte__live::before {
    animation: none;
  }

  .tour-card:hover .media-layer__poster,
  .tour-card:hover .media-layer__video {
    transform: none;
  }
}

/* ==========================================================================
   Selector de experiencias — panel a pantalla completa que abre "Reservar"
   (partials/selector-experiencias.php).

   La rejilla es de tres filas: cabecera y pie se dimensionan por su
   contenido (auto) y las tarjetas se quedan con TODO lo que sobra (1fr).
   Así las tres caben siempre en la pantalla sin altura fija ni cálculos en
   JavaScript, y se adaptan solas a un iPhone SE o a un monitor de 27".
   ========================================================================== */
.selector {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  overflow: hidden;
  isolation: isolate;
  color: var(--color-white);
  background-color: var(--color-black);
}

.selector[hidden] {
  display: none;
}

.selector .media-layer {
  z-index: -2;
}

.selector__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg, rgba(8, 8, 10, 0.92) 0%, rgba(8, 8, 10, 0.78) 50%, rgba(8, 8, 10, 0.95) 100%),
    rgba(8, 8, 10, 0.45);
}

.selector__inner {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-4);
  height: 100%;
  padding: var(--space-2) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
}

@media (min-width: 900px) {
  .selector__inner {
    gap: var(--space-5);
    padding: var(--space-5) var(--space-8) var(--space-8);
    max-width: 1200px;
    margin-inline: auto;
  }
}

/* Entrada: sube y aparece. Corta bajo prefers-reduced-motion (base.css ya
   anula las duraciones globalmente, esto solo evita el desplazamiento). */
.selector[data-abierto="true"] .selector__inner {
  animation: selector-entrar 340ms var(--ease-premium) both;
}

@keyframes selector-entrar {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .selector[data-abierto="true"] .selector__inner { animation: none; }
}

/* ---- Cabecera ---- */
.selector__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.selector__close {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* 36px de caja visible pero 44 de zona táctil por el ::after invisible
     de abajo: la fila de cabecera la marca este botón, y a 44 visibles
     robaba alto a las tarjetas sin necesidad. */
  position: relative;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.20);
  background: rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: var(--color-white);
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color var(--transition-fast), transform var(--transition-fast);
}

.selector__close::after {
  content: '';
  position: absolute;
  inset: -6px;    /* zona táctil de 44px sobre un botón de 32 visibles */
}

.selector__close:hover,
.selector__close:focus-visible {
  background: rgba(255, 255, 255, 0.18);
  transform: scale(1.06);
}

.selector__title {
  min-width: 0;   /* deja que el título se encoja antes que empujar el chip */
  flex: 1;
}

.selector__eyebrow {
  margin: 0;
  font-size: 0.5625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-primary-bright);
  line-height: 1.15;
}

.selector__title h2 {
  margin: 0;
  font-size: clamp(0.9375rem, 0.82rem + 0.7vw, 1.3125rem);
  letter-spacing: -0.02em;
  line-height: 1.08;
}

.selector__parte {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: 100px;
  /* El color del chip lo pone data-tono (ver más abajo) y NO el magenta de
     marca: el estado del mar es información semántica —verde se sale,
     ámbar precaución— y mezclarla con el color de marca haría que un día
     de marejada se viera igual de "de marca" que uno en calma. */
  border: 1px solid var(--tono-borde, rgba(255, 255, 255, 0.22));
  background: var(--tono-fondo, rgba(255, 255, 255, 0.08));
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  text-decoration: none;
  line-height: 1.15;
}

.selector__parte-texto {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
}

/* --- Icono de ola: cuatro trazos, se enseña el del nivel actual --- */
.ola {
  width: 22px;
  height: 13px;
  flex-shrink: 0;
  overflow: visible;
}

.ola__p {
  fill: none;
  stroke: var(--tono-color, var(--color-white));
  stroke-width: 1.8;
  stroke-linecap: round;
  display: none;
}

/* Las reglas van sobre [data-ola] y no sobre una clase concreta, para que
   valgan igual en el chip del selector y en el panel del parte. Sin dato de
   nivel se dibuja el trazo plano, que es el estado neutro. */
.ola__p[data-nivel="0"] { display: inline; }

[data-ola="1"] .ola__p[data-nivel="0"],
[data-ola="2"] .ola__p[data-nivel="0"],
[data-ola="3"] .ola__p[data-nivel="0"] { display: none; }

[data-ola="1"] .ola__p[data-nivel="1"],
[data-ola="2"] .ola__p[data-nivel="2"],
[data-ola="3"] .ola__p[data-nivel="3"] { display: inline; }

/* Solo el nivel más alto se mueve: una animación permanente en el estado
   normal sería ruido, pero en marejada el movimiento es justamente el
   aviso. */
[data-ola="3"] .ola__p[data-nivel="3"] {
  animation: ola-agita 1.6s ease-in-out infinite alternate;
  transform-origin: center;
}

@keyframes ola-agita {
  from { transform: translateY(-0.5px) scaleY(0.92); }
  to   { transform: translateY(0.5px) scaleY(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  [data-ola="3"] .ola__p[data-nivel="3"] { animation: none; }
}

/* --- Color semántico según el veredicto --- */
.selector__parte[data-tono="optimo"],
.selector__parte[data-tono="bueno"] {
  --tono-color: #35D07F;
  --tono-borde: rgba(53, 208, 127, 0.45);
  --tono-fondo: rgba(53, 208, 127, 0.14);
}

.selector__parte[data-tono="aviso"] {
  --tono-color: #FFB020;
  --tono-borde: rgba(255, 176, 32, 0.5);
  --tono-fondo: rgba(255, 176, 32, 0.15);
}

.selector__parte[data-tono="neutro"] {
  --tono-color: rgba(255, 255, 255, 0.8);
}

.selector__parte[hidden] { display: none; }

.selector__parte-label {
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.6);
}

.selector__parte-estado {
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-white);
}

/* ---- Tarjetas ---- */
/* Una lista que se desplaza, no una retícula de tres filas exactas.
   ------------------------------------------------------------------------
   Antes las tres tarjetas se repartían el alto de la pantalla con
   grid-template-rows: repeat(3, 1fr). Con el calendario desplegándose debajo
   de la que se elige, esa retícula ya no vale: el panel tiene que empujar a
   las de abajo, y con filas de 1fr no hay hueco que empujar.
   Ahora las tarjetas miden lo suyo y la lista se desplaza. overscroll-behavior
   evita que el gesto se propague a la página de detrás. */
.selector__cards {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* En escritorio NO se pasa a tres columnas. Con el calendario debajo de su
   tarjeta, tres columnas obligarían al panel a ocupar el ancho completo y a
   romper la fila, dejando las tarjetas descolocadas al abrirlo. La misma
   lista vertical, centrada y con un ancho de lectura, se comporta igual en
   las dos pantallas — que además es lo que ya hace precios.php. */
@media (min-width: 900px) {
  .selector__cards {
    gap: var(--space-4);
    max-width: 720px;
    width: 100%;
    margin-inline: auto;
  }
}

.pick-card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 148px;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--radius-lg);
  /* Marco fino continuo alrededor de la tarjeta. Va como box-shadow inset
     y no como border para que quede POR ENCIMA del vídeo: un border se
     dibuja fuera del área de recorte y el vídeo, que llena la tarjeta a
     sangre, lo tapaba por los cuatro lados. */
  border: none;
  background-color: var(--color-surface);
}

/* Marco magenta, en LAS TRES tarjetas —igual que el dorado de la
   referencia—: es lo que hace que se lean como tres piezas de la misma
   colección y no como tres tarjetas sueltas sobre un fondo.
   
   Va como pseudo-elemento por encima y NO como border ni como box-shadow
   inset. Los dos se pintan junto al fondo del elemento, y los hijos con
   z-index negativo —que es lo que es la capa de vídeo— se pintan DESPUÉS
   del fondo: el marco quedaba dibujado debajo del vídeo y no se veía. Con
   pointer-events:none para no robarle el clic al atajo de la tarjeta. */
.pick-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  border: 1px solid rgba(var(--color-primary-rgb), 0.6);
  border-radius: inherit;
  transition: border-color var(--transition-standard);
}

/* La más vendida sube la intensidad del mismo marco y añade un halo muy
   leve. La jerarquía se marca con la fuerza del acento, no cambiándole el
   color a una y dejando las otras dos en gris. */
.pick-card--destacada::after {
  border-color: rgba(var(--color-primary-rgb), 1);
  box-shadow:
    0 0 14px rgba(var(--color-primary-rgb), 0.35),
    inset 0 0 14px rgba(var(--color-primary-rgb), 0.12);
}

.pick-card:hover::after {
  border-color: var(--color-primary);
}

/* El alto de las tarjetas en móvil lo decide el reparto en 1fr, no un
   número fijo: en un móvil normal salen a ~223px y en uno corto (iPhone SE,
   667px) se encogen a ~165px, que sigue siendo suficiente para leer nombre,
   precio y los dos botones. El min-height es solo un suelo por debajo del
   cual la tarjeta dejaría de parecer una ventana al mar; está puesto para
   que NUNCA obligue a deslizar en las alturas de pantalla reales. */
@media (max-width: 899px) {
  .pick-card {
    /* Crecen para llenar la pantalla cuando no hay ningún calendario
       abierto, con un techo para que no se conviertan en carteles. Y NO
       encogen (flex-shrink: 0): al abrir un panel, lo que tiene que pasar es
       que la lista se desplace, no que las tres tarjetas se aplasten. */
    flex: 1 0 auto;
    min-height: 150px;
    max-height: 260px;
  }
}

@media (min-width: 900px) {
  .pick-card {
    /* Ya no se reparten el alto de la pantalla: una tarjeta de 560px en una
       lista vertical dejaría la tercera siempre fuera de vista. Crecen hasta
       un techo razonable y no encogen, igual que en móvil. */
    flex: 1 0 auto;
    min-height: 200px;
    max-height: 300px;
    border-radius: var(--radius-xl);
  }
}

/* El calendario va pegado a su tarjeta: el margen negativo que usa en
   precios.php lo encaja bajo el borde inferior, y aquí la lista además
   tiene su propio gap que hay que anular para que no quede una franja
   entre la tarjeta y su panel. */
.selector-reserva {
  margin-top: calc(var(--space-3) * -1);
}

@media (min-width: 900px) {
  .selector-reserva {
    margin-top: calc(var(--space-4) * -1);
  }
}

.pick-card .media-layer { z-index: -2; }

.pick-card__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    rgba(8, 8, 10, 0.55) 0%,
    rgba(8, 8, 10, 0.15) 32%,
    rgba(8, 8, 10, 0.70) 70%,
    rgba(8, 8, 10, 0.94) 100%
  );
}

.pick-card__chips {
  position: absolute;
  top: var(--space-3);
  inset-inline: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.pick-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px var(--space-2);
  border-radius: 100px;
  border: 1px solid rgba(255, 255, 255, 0.20);
  background: rgba(8, 8, 10, 0.55);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  font-size: 0.5625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-white);
}

.pick-chip--ok::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #35D07F;
}

.pick-chip--time {
  font-family: var(--font-display);
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
}

.pick-card__badge {
  position: absolute;
  top: calc(var(--space-3) + 26px);
  right: var(--space-3);
  padding: 2px var(--space-2);
  border-radius: 100px;
  background-color: var(--color-primary);
  color: var(--color-white);
  font-size: 0.5625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.pick-card__body {
  /* Poco aire arriba y abajo: el bloque de texto se pega al borde inferior
     del recuadro, que es donde debe leerse, y todo lo que sobra por arriba
     queda para el vídeo. */
  padding: var(--space-3) var(--space-4) 10px;
}

.pick-card__name {
  margin: 0 0 var(--space-2);
  font-size: clamp(1.125rem, 0.95rem + 0.8vw, 1.5rem);
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.pick-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.20);
}

.pick-card__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0;
}

.pick-card__price span {
  font-size: 0.5625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.6);
}

.pick-card__price strong {
  font-family: var(--font-display);
  font-size: clamp(1.1875rem, 1rem + 0.9vw, 1.625rem);
  font-weight: 700;
  line-height: 1;
}

.pick-card__actions {
  display: flex;
  gap: 6px;
}

/* Tocar el vídeo de la tarjeta lleva a reservar esa experiencia. Lo resuelve
   assets/js/paneles.js reenviando el clic al botón RESERVAR, y no el truco
   CSS del pseudo-elemento estirado: ese depende de que no haya ningún
   ancestro posicionado entre el botón y la tarjeta, y aquí el botón vive
   dentro de dos contenedores flex anidados donde el área acababa
   ancorándose donde no debía. Envolver la tarjeta en otro <a> tampoco vale:
   un enlace dentro de otro no es marcado válido.

   Los dos botones siguen siendo enlaces de verdad, así que con el teclado y
   sin JavaScript todo funciona igual; el clic en el vídeo es un atajo para
   quien usa el dedo o el ratón. */

.pick-card:hover .pick-btn--go {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-white);
}

/* Al pasar el ratón por cualquier punto de la tarjeta se nota que es
   pulsable, no solo sobre los botones. */
.pick-card {
  cursor: pointer;
  transition:
    transform var(--transition-standard) var(--ease-premium),
    box-shadow var(--transition-standard) var(--ease-premium);
}

.pick-card:hover {
  transform: translateY(-3px);
}

.pick-card:hover .media-layer__poster,
.pick-card:hover .media-layer__video {
  transform: scale(1.05);
}

.pick-card .media-layer__poster,
.pick-card .media-layer__video {
  transition: transform var(--transition-slow) var(--ease-premium), opacity 700ms var(--ease-premium);
}

@media (prefers-reduced-motion: reduce) {
  .pick-card:hover { transform: none; }
  .pick-card:hover .media-layer__poster,
  .pick-card:hover .media-layer__video { transform: none; }
}

/* Botones propios y no .btn: los del sitio miden 48px de alto y tres
   tarjetas con dos botones de 48 no caben en una pantalla de móvil. Estos
   bajan a 38 manteniendo el ancho suficiente para seguir siendo un objetivo
   táctil cómodo. */
.pick-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 28px;
  padding: 0 10px;
  border-radius: 100px;
  border: 1px solid rgba(255, 255, 255, 0.32);
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-decoration: none;
  color: var(--color-white);
  white-space: nowrap;
  transition: background-color var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}

.pick-btn:hover,
.pick-btn:focus-visible {
  background: rgba(255, 255, 255, 0.14);
  transform: translateY(-2px);
}

.pick-btn--go {
  background-color: var(--color-white);
  border-color: var(--color-white);
  color: var(--color-ink);
}

.pick-btn--go:hover,
.pick-btn--go:focus-visible {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-white);
}

/* ---- Pie ---- */
.selector__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: 0;
  text-align: center;
  font-size: 0.75rem;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.66);
}

.selector__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background-color: rgba(var(--color-primary-rgb), 0.25);
  color: var(--color-primary-bright);
  font-size: 0.6875rem;
  font-weight: 700;
}

/* Con el panel abierto se congela la página de debajo. En iOS hace falta
   además overscroll-behavior, o el arrastre atraviesa el panel y desplaza
   el documento de detrás. */
html.selector-abierto,
body.selector-abierto {
  overflow: hidden;
  overscroll-behavior: none;
}

/* ==========================================================================
   Panel del parte del día (partials/parte-panel.php) — se abre desde el
   chip del selector y desde "Parte del día" en el menú.

   A diferencia del selector, este SÍ se desplaza: es información para
   consultar, no una lista de la que elegir, y recortar un dato para que
   todo quepa sería peor que dejar deslizar.
   ========================================================================== */
.parte-panel {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  overflow: hidden;
  isolation: isolate;
  color: var(--color-white);
  background-color: var(--color-black);
}

.parte-panel[hidden] { display: none; }

.parte-panel .media-layer { z-index: -2; }

.parte-panel__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg, rgba(8, 8, 10, 0.95) 0%, rgba(8, 8, 10, 0.88) 60%, rgba(8, 8, 10, 0.97) 100%),
    rgba(8, 8, 10, 0.5);
}

.parte-panel__inner {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  gap: var(--space-4);
  height: 100%;
  padding: var(--space-2) var(--space-4) 0;
}

@media (min-width: 900px) {
  .parte-panel__inner {
    max-width: 900px;
    margin-inline: auto;
    padding: var(--space-5) var(--space-8) 0;
  }
}

.parte-panel[data-abierto="true"] .parte-panel__inner {
  animation: selector-entrar 340ms var(--ease-premium) both;
}

@media (prefers-reduced-motion: reduce) {
  .parte-panel[data-abierto="true"] .parte-panel__inner { animation: none; }
}

.parte-panel__scroll {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: calc(var(--mobile-cta-height) + var(--space-10) + env(safe-area-inset-bottom, 0px));
}

/* Veredicto: primero y más grande, porque es lo único que responde a la
   pregunta que trae el visitante. Los doce números de abajo son el respaldo. */
.parte-veredicto {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-6);
  border-radius: var(--radius-lg);
  border: 1px solid var(--tono-borde, rgba(255, 255, 255, 0.18));
  background: var(--tono-fondo, rgba(255, 255, 255, 0.06));
}

.parte-veredicto[data-tono="optimo"],
.parte-veredicto[data-tono="bueno"] {
  --tono-color: #35D07F;
  --tono-borde: rgba(53, 208, 127, 0.42);
  --tono-fondo: rgba(53, 208, 127, 0.12);
}

.parte-veredicto[data-tono="aviso"] {
  --tono-color: #FFB020;
  --tono-borde: rgba(255, 176, 32, 0.48);
  --tono-fondo: rgba(255, 176, 32, 0.13);
}

.ola--grande {
  width: 54px;
  height: 31px;
}

.ola--grande .ola__p { stroke-width: 1.5; }

.parte-veredicto__estado {
  margin: 0 0 2px;
  font-family: var(--font-display);
  font-size: var(--fs-400);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--color-white);
}

.parte-veredicto__texto {
  margin: 0;
  font-size: var(--fs-100);
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.72);
}

/* Los datos van agrupados por tema —mar, tiempo, luz— y no en una rejilla
   corrida de doce casillas: quien mira esto está decidiendo si sale hoy, y
   agrupado se lee de un vistazo en vez de tener que buscar. */
.parte-panel__grupo {
  margin: 0 0 var(--space-2);
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-primary-bright);
}

.parte-panel__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  margin-bottom: var(--space-6);
}

@media (min-width: 700px) {
  .parte-panel__grid {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--space-3);
  }
}

.parte-panel .parte__stat {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
}

.parte-panel .parte__stat-label {
  font-size: 0.625rem;
  margin-bottom: 4px;
}

.parte-panel .parte__stat-value {
  font-size: var(--fs-400);
}

.parte-panel .parte__updated {
  margin: 0 0 var(--space-5);
}

.parte-panel__cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.parte-panel__cta .pick-btn {
  min-height: 40px;
  font-size: 0.6875rem;
}

/* ==========================================================================
   Valoración de Google (partials/rating-google.php) — nota, estrellas
   proporcionales en el ámbar de Google, y la procedencia.
   ========================================================================== */
.rating-google {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.rating-google__nota {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  color: var(--color-white);
  /* Los dígitos de ancho fijo evitan que "4,9" y "5,0" ocupen distinto y
     el bloque entero se mueva el día que cambie la nota. */
  font-variant-numeric: tabular-nums;
}

.rating-google__estrellas {
  /* 5 estrellas en un lienzo de 100x20: la proporción manda el alto. */
  width: 64px;
  height: 12.8px;
  flex-shrink: 0;
  display: block;
}

.rating-google__fuente {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: rgba(255, 255, 255, 0.62);
}

/* Dentro del sello del hero, que ya trae su propio cristal y borde. */
.rating-badge .rating-google {
  gap: 6px;
}

.rating-badge .rating-google__nota {
  font-size: 1.0625rem;
}

.rating-badge .rating-google__fuente {
  font-size: 0.625rem;
}

/* ==========================================================================
   Pantallas cortas — la portada de una sola pantalla tiene altura fija
   (100svh) y su contenido no es negociable: sello, titular, botón y los
   enlaces legales obligatorios. En un móvil de 640-700px de alto útil eso
   no cabe con la entradilla entera.

   Se recorta la entradilla a dos líneas en vez de ocultarla: la primera
   frase es la que vende ("Sal al Mediterráneo con motos Sea-Doo de última
   generación") y la segunda repite lo que ya dicen los argumentos de
   abajo. Se consultan a la vez alto y orientación para no aplicarlo en un
   portátil apaisado, donde sí cabe todo.
   ========================================================================== */
@media (max-height: 740px) and (orientation: portrait) {
  .hero-video--full {
    padding-block: calc(var(--header-height) + var(--space-6))
                   calc(var(--mobile-cta-height) + var(--space-6));
  }

  .hero-video--full h1 {
    font-size: clamp(1.875rem, 1.4rem + 2.4vw, 2.5rem);
    margin-bottom: var(--space-3);
  }

  .hero-video--full .hero-video__lead {
    margin-bottom: var(--space-4);
  }

  /* Se oculta la segunda frase completa, no se recorta el párrafo con
     puntos suspensivos: el recorte cortaba a media palabra ("…Sin
     licenc…"), que parece un error de la página y no una decisión. La
     frase que queda es la que vende; la que se va repite lo que ya dicen
     los argumentos de más abajo y la tira de iconos. */
  .hero-video--full .hero-video__lead-extra {
    display: none;
  }

  .hero-video--full .hero-video__legal {
    margin-top: var(--space-4);
  }
}

/* ==========================================================================
   El recorrido (partials/ruta-contenido.php) — mapa real con el trazado
   animado encima.

   Dos capas que comparten sistema de coordenadas: la imagen del mapa y un
   SVG con el mismo viewBox. Se apilan con position:absolute sobre un
   contenedor de proporción fija, así que escalan juntas y no hay forma de
   que se desalineen al cambiar de ancho.

   El mapa manda en escritorio y pasa arriba en móvil, con la lista debajo:
   en una pantalla estrecha una columna lateral dejaría el mapa en ~200px de
   alto y sería ilegible.
   ========================================================================== */
.ruta__grid {
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 900px) {
  .ruta__grid {
    grid-template-columns: 58fr 42fr;
    gap: var(--space-10);
    align-items: start;
  }
}

.ruta__mapa {
  margin: 0;
  border-radius: var(--radius-xl);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background-color: #070B12;
}

/* El lienzo cambia de forma según la ruta —la de 30 minutos sale vertical
   porque sube por la costa— y una vertical a todo el ancho de la columna se
   iría a 800 px de alto. Se limita por ALTO, pero expresado como ancho
   máximo (alto deseado x relación del lienzo): tocar el ancho encoge la caja
   entera y mantiene la proporción. Limitarlo con max-height rompería la
   proporción y con ella la alineación entre la imagen y el trazado, que es
   justo lo que no se puede permitir. */
@media (min-width: 900px) {
  .ruta__mapa {
    max-width: calc(660px * var(--mapa-relacion, 1.4));
    margin-inline: auto;
  }
}

/* aspect-ratio con los mismos números que el viewBox: el hueco del mapa ya
   tiene su altura antes de que la imagen llegue, así que nada salta cuando
   carga. */
.ruta__lienzo {
  position: relative;
  aspect-ratio: 1100 / 800;
  background-color: #0A1626;
}

.ruta__base,
.ruta__capa {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.ruta__base {
  object-fit: cover;
  /* El mapa base viene bastante más claro que el resto del sitio. Bajarle
     algo el brillo y la saturación lo mete en la paleta y, sobre todo, deja
     que el magenta del trazado destaque: sobre un mapa a pleno color la
     línea compite con los rótulos de las calles. */
  filter: brightness(0.82) saturate(0.85) contrast(1.05);
}

/* Si la imagen no llega —no se ha generado todavía, o falta el archivo— queda el trazado
   sobre un fondo de mar liso. Sigue siendo la geometría real; lo que falta
   es el mapa, no el recorrido. */
.ruta__lienzo--sinbase {
  background-image: radial-gradient(120% 90% at 20% 10%, #0E2438 0%, #071523 55%, #040C15 100%);
}

.ruta__atribucion {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  margin: 0;
  display: flex;
  gap: var(--space-2);
  padding: 3px var(--space-2);
  border-top-left-radius: var(--radius-sm);
  background-color: rgba(6, 10, 18, 0.72);
  font-size: 0.625rem;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.55);
}

/* Obligatoria por licencia: se atenúa, no se esconde. */
.ruta__atribucion a {
  color: inherit;
  text-decoration: none;
}

.ruta__atribucion a:hover,
.ruta__atribucion a:focus-visible {
  color: var(--color-text);
  text-decoration: underline;
}

.ruta__pie {
  padding: var(--space-2) var(--space-4) var(--space-3);
  font-size: 0.6875rem;
  color: var(--color-text-muted);
  border-top: 1px solid var(--color-border);
}

/* --- Trazado --- */
.ruta__estela {
  stroke: rgba(255, 255, 255, 0.30);
  stroke-width: 3.5;
  stroke-dasharray: 7 9;
  stroke-linecap: round;
}

/* --ruta-largo lo escribe assets/js/ruta.js con getTotalLength(): la
   longitud de un trazo solo se sabe midiéndola, pero quien la usa vive
   aquí. Con la variable, el CSS no lleva números mágicos y el JS no
   escribe estilos de presentación. */
.ruta__linea {
  stroke: var(--color-primary);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: var(--ruta-largo, 0);
  stroke-dashoffset: var(--ruta-largo, 0);
  /* Doble sombra: una oscura muy cerrada que despega la línea del mapa
     pase lo que pase debajo, y el resplandor magenta encima. Sin la
     oscura, la línea se pierde al cruzar una zona clara del mapa. */
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.9))
          drop-shadow(0 0 11px rgba(var(--color-primary-rgb), 0.65));
  /* La duración la escribe assets/js/ruta.js, que es quien lleva el ritmo
     del ciclo completo. El valor de reserva solo actúa si el JS no llegó a
     correr, en cuyo caso tampoco hay ciclo que sincronizar. */
  transition: stroke-dashoffset var(--ruta-trazo, 2600ms) cubic-bezier(0.33, 0, 0.2, 1);
}

[data-ruta-lista="true"] .ruta__linea {
  stroke-dashoffset: 0;
}

/* Al empezar otra vuelta la línea vuelve a cero de golpe, sin transición:
   verla "desdibujarse" hacia atrás sería un movimiento que no significa
   nada. Se apaga el trazo, se rebobina y se vuelve a dibujar. */
[data-ruta-lista="false"] .ruta__linea {
  transition: none;
}

/* Flujo: guiones cortos y muy separados que avanzan por la línea en bucle.
   El desplazamiento de la animación vale exactamente un periodo del patrón
   (2 + 26 = 28), y por eso el bucle no tiene costura: al terminar, cada
   destello está justo donde arrancó el siguiente.

   Va con retardo para entrar cuando el trazado ya se ha dibujado; lanzarlo a
   la vez haría que dos animaciones se pelearan por la misma propiedad. */
.ruta__flujo {
  stroke: rgba(255, 255, 255, 0.95);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 2 26;
  opacity: 0;
  filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.7));
  transition: opacity 700ms ease 2400ms;
}

[data-ruta-lista="true"] .ruta__flujo {
  opacity: 1;
  animation: ruta-fluir 2.2s linear infinite;
}

@keyframes ruta-fluir {
  to { stroke-dashoffset: -28; }
}

/* --- Escala --- */
.ruta__escala-barra {
  fill: none;
  stroke: rgba(255, 255, 255, 0.85);
  stroke-width: 2.5;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.95));
}

.ruta__escala-texto {
  fill: var(--color-white);
  font-family: var(--font-body);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: 0.03em;
  paint-order: stroke;                 /* el contorno se dibuja DEBAJO del relleno */
  stroke: rgba(5, 10, 18, 0.85);
  stroke-width: 4;
  stroke-linejoin: round;
}

/* --- Paradas --- */
.ruta__punto {
  opacity: 0;
  transform: scale(0.6);
  transform-origin: center;
  transform-box: fill-box;   /* sin esto, scale() en SVG orbita el origen del lienzo */
  transition: opacity 420ms ease, transform 420ms var(--ease-premium);
}

/* El encendido lo reparte assets/js/ruta.js con temporizadores, no un
   retardo escalonado en CSS: el ciclo se repite en bucle y tiene tantos
   pasos como paradas tenga la ruta, y eso en keyframes obligaría a unos
   distintos por cada longitud posible. */
.ruta__punto.is-encendido {
  opacity: 1;
  transform: scale(1);
}

.ruta__halo {
  fill: rgba(var(--color-primary-rgb), 0.20);
  opacity: 0;
  transition: opacity var(--transition-standard);
}

.ruta__punto--parada.is-encendido .ruta__halo { opacity: 1; }

.ruta__punto.is-activo .ruta__halo {
  opacity: 1;
  fill: rgba(var(--color-primary-rgb), 0.36);
}

.ruta__disco {
  fill: var(--color-black);
  stroke: var(--color-primary);
  stroke-width: 2.5;
  transition: fill var(--transition-fast);
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.8));
}

.ruta__punto--parada .ruta__disco {
  fill: var(--color-primary);
  stroke: var(--color-white);
}

.ruta__punto.is-activo .ruta__disco { fill: var(--color-primary); }

.ruta__numero {
  fill: var(--color-white);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  pointer-events: none;
}

/* El nombre de la parada, al lado del disco. Aparece con su parada y se
   queda hasta que el ciclo entero se apaga, así que al final de la vuelta
   están los cuatro escritos y el mapa se lee completo.

   paint-order: stroke dibuja el contorno DEBAJO del relleno, que es lo que
   permite usar un borde grueso como separación del fondo sin engordar la
   letra. Sin él, sobre una foto de satélite el texto se pierde. */
.ruta__rotulo {
  fill: var(--color-white);
  font-family: var(--font-body);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.01em;
  paint-order: stroke;
  stroke: rgba(5, 10, 18, 0.92);
  stroke-width: 5;
  stroke-linejoin: round;
  pointer-events: none;
  opacity: 0;
  transform: translateX(-6px);
  transform-box: fill-box;
  /* Algo más lenta que la entrada del disco: el punto aparece y el nombre
     lo alcanza medio segundo después, que es el orden en que se miran. */
  transition: opacity 620ms ease, transform 620ms var(--ease-premium);
}

.ruta__punto.is-encendido .ruta__rotulo {
  opacity: 1;
  transform: translateX(0);
}

/* --- Lista de pasos --- */
.ruta__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.ruta__paso {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
}

.ruta__paso:last-child { border-bottom: none; }

/* Los cuatro números arrancan apagados y se encienden AL MISMO TIEMPO que su
   punto en el mapa (assets/js/ruta.js). Antes, el de la parada con chapa
   —"Frente al Postiguet"— salía ya en magenta por ser especial, y eso rompía
   la lectura: si uno está encendido de entrada, la secuencia 01→02→03→04 deja
   de leerse como una secuencia. Esa parada ya se distingue por su etiqueta
   "Parada", que dice lo mismo con palabras. */
.ruta__paso {
  transition: border-color var(--transition-standard);
}

.ruta__paso-numero {
  flex-shrink: 0;
  width: 38px;
  font-family: var(--font-display);
  font-size: var(--fs-400);
  font-weight: 700;
  line-height: 1;
  color: rgba(255, 255, 255, 0.28);
  transition: color var(--transition-standard), text-shadow var(--transition-standard);
}

.ruta__paso-nombre,
.ruta__paso-texto {
  transition: color var(--transition-standard);
}

/* Apagado: el texto se lee, pero en segundo plano. */
.ruta__paso:not(.is-encendido):not(.is-activo) .ruta__paso-nombre {
  color: rgba(255, 255, 255, 0.62);
}

/* Encendido — el mismo halo que lleva el punto en el mapa, para que se
   reconozcan como lo mismo. */
.ruta__paso.is-encendido .ruta__paso-numero,
.ruta__paso.is-activo .ruta__paso-numero {
  color: var(--color-primary);
  text-shadow: 0 0 14px rgba(var(--color-primary-rgb), 0.55);
}

.ruta__paso.is-encendido .ruta__paso-nombre,
.ruta__paso.is-activo .ruta__paso-nombre {
  color: var(--color-white);
}

.ruta__paso.is-encendido {
  border-bottom-color: rgba(var(--color-primary-rgb), 0.32);
}

.ruta__paso-nombre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0 0 4px;
  font-size: var(--fs-300);
  letter-spacing: -0.01em;
}

.ruta__etiqueta {
  padding: 2px var(--space-2);
  border-radius: 100px;
  background-color: var(--color-primary);
  color: var(--color-white);
  font-family: var(--font-body);
  font-size: 0.5625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.ruta__paso-texto {
  margin: 0;
  font-size: var(--fs-100);
  line-height: 1.5;
  color: var(--color-text-muted);
}

@media (prefers-reduced-motion: reduce) {
  .ruta__linea { transition: none; stroke-dashoffset: 0; }
  .ruta__punto,
  .ruta__rotulo {
    opacity: 1;
    transform: none;
    transition: none;
  }
  /* El flujo desaparece entero, no se queda quieto: unos guiones parados
     sobre la línea se leerían como un error de dibujo. */
  .ruta__flujo {
    display: none;
    animation: none;
  }
}

/* En un móvil el mapa se queda en unos 320x233: el viewBox no se puede
   cambiar desde CSS, pero sí engordar los elementos en unidades del propio
   lienzo, que es lo mismo que acercar la cámara solo para lo que importa.
   r, cx y cy son propiedades de geometría SVG y se pueden fijar por CSS; si
   algún navegador no las soporta, se queda el valor del atributo del
   marcado, que ya es legible. */
@media (max-width: 699px) {
  .ruta__linea { stroke-width: 11; }
  .ruta__estela { stroke-width: 7; stroke-dasharray: 14 18; }
  /* El patrón se engorda igual que el resto: a un tercio del ancho, unos
     guiones de 2 px no se ven. Se mantiene la proporción 1:13 para que el
     desplazamiento del bucle siga cuadrando. */
  .ruta__flujo { stroke-width: 6; stroke-dasharray: 4 52; }
  @keyframes ruta-fluir { to { stroke-dashoffset: -56; } }

  .ruta__disco { r: 34px; stroke-width: 5; }
  .ruta__punto--parada .ruta__disco { r: 42px; }
  .ruta__halo { r: 58px; }
  .ruta__numero { font-size: 32px; }
  .ruta__rotulo { font-size: 34px; stroke-width: 8; }

  .ruta__escala-barra { stroke-width: 5; }
  .ruta__escala-texto { font-size: 34px; stroke-width: 7; }

  /* El mapa base trae rótulos de calle pensados para verse a tamaño
     completo; a un tercio del ancho son manchas. Un poco de desenfoque los
     convierte en textura y deja que manden el trazado y las paradas. */
  .ruta__base { filter: brightness(0.72) saturate(0.8) blur(0.4px); }
}


/* ==========================================================================
   Panel del recorrido (partials/ruta-panel.php) — lo abre "Detalles".

   Este sí se desplaza: el mapa más cuatro paradas descritas no caben en una
   pantalla de móvil, y aquí el visitante viene a leer, no a elegir de un
   vistazo. El padding inferior deja libre el dock flotante: sin él, la
   última parada y el botón de reservar quedaban debajo de la píldora y no
   se podían tocar.
   ========================================================================== */
.panel-ruta {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  overflow: hidden;
  isolation: isolate;
  color: var(--color-white);
  background-color: var(--color-black);
}

.panel-ruta[hidden] { display: none; }

.panel-ruta .media-layer { z-index: -2; }

.panel-ruta__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg, rgba(8, 8, 10, 0.95) 0%, rgba(8, 8, 10, 0.9) 60%, rgba(8, 8, 10, 0.97) 100%),
    rgba(8, 8, 10, 0.5);
}

.panel-ruta__inner {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr;
  gap: var(--space-4);
  height: 100%;
  padding: var(--space-2) var(--space-4) 0;
}

@media (min-width: 900px) {
  .panel-ruta__inner {
    max-width: 1100px;
    margin-inline: auto;
    padding: var(--space-5) var(--space-8) 0;
  }
}

.panel-ruta[data-abierto="true"] .panel-ruta__inner {
  animation: selector-entrar 340ms var(--ease-premium) both;
}

@media (prefers-reduced-motion: reduce) {
  .panel-ruta[data-abierto="true"] .panel-ruta__inner { animation: none; }
}

.panel-ruta__scroll {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: calc(var(--mobile-cta-height) + var(--space-12) + env(safe-area-inset-bottom, 0px));
}

.panel-ruta__entrada {
  max-width: 62ch;
  margin: 0 0 var(--space-5);
  font-size: var(--fs-100);
  line-height: 1.55;
  color: var(--color-text-muted);
}

.panel-ruta__cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-6);
}

.panel-ruta__cta .pick-btn {
  min-height: 42px;
  font-size: 0.6875rem;
}

/* Dentro del panel el mapa y la lista van en columna hasta bastante ancho:
   el panel ya es estrecho de por sí y una columna lateral de 42% dejaría la
   lista en un canal ilegible. */
.panel-ruta .ruta__grid {
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

@media (min-width: 1000px) {
  .panel-ruta .ruta__grid {
    grid-template-columns: 55fr 45fr;
    gap: var(--space-8);
  }
}

/* ==========================================================================
   Anclas y cabecera fija: cualquier destino de #ancla tiene que dejar libre
   la altura de la cabecera, o el navegador lo alinea con el borde superior
   de la ventana y la cabecera lo tapa. Pasaba con "Reservar", que aterrizaba
   con el calendario medio escondido detrás del logo.
   ========================================================================== */
[id] {
  scroll-margin-top: calc(var(--header-height) + var(--space-4));
}

/* ==========================================================================
   Elige tu experiencia (precios.php) — las tres excursiones en columna, con
   su calendario desplegable debajo.

   Se reaprovechan las fichas del selector en espíritu, no en clases: allí
   las tarjetas compiten por el alto de una pantalla y aquí se apilan a lo
   largo, así que las medidas no se parecen en nada y compartir clases habría
   obligado a deshacer con anulaciones lo que la otra impone.
   ========================================================================== */
.elige {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 340px;
  margin-bottom: var(--space-5);
  padding: var(--space-6);
  border-radius: var(--radius-xl);
  overflow: hidden;
  cursor: pointer;
  isolation: isolate;
}

@media (min-width: 700px) {
  .elige { min-height: 400px; padding: var(--space-8); }
}

/* El marco magenta va en un ::after y no en el borde de la caja: un borde
   se pinta con el fondo, y las capas de vídeo llevan z-index negativo, así
   que se dibujan DESPUÉS y lo taparían. Encima y sin capturar el ratón. */
.elige::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  border: 1px solid rgba(var(--color-primary-rgb), 0.55);
  border-radius: inherit;
}

.elige--destacada::after {
  border-color: rgba(var(--color-primary-rgb), 1);
  box-shadow: 0 0 14px rgba(var(--color-primary-rgb), 0.35);
}

.elige .media-layer { z-index: -2; }

.elige__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top,
              rgba(8, 8, 10, 0.94) 0%,
              rgba(8, 8, 10, 0.72) 45%,
              rgba(8, 8, 10, 0.30) 100%);
}

.elige__chips {
  position: absolute;
  top: var(--space-4);
  left: var(--space-4);
  z-index: 2;
  display: flex;
  gap: var(--space-2);
}

.elige__badge {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  z-index: 2;
  padding: 4px var(--space-3);
  border-radius: 100px;
  background-color: var(--color-primary);
  color: var(--color-white);
  font-size: 0.625rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.elige__body { position: relative; z-index: 2; }

.elige__name {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-500);
  letter-spacing: -0.02em;
}

.elige__resumen {
  margin: 0 0 var(--space-5);
  max-width: 46ch;
  color: var(--color-text-muted);
  font-size: var(--fs-100);
}

.elige__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.elige__price {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.elige__price span {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
}

.elige__price strong {
  font-family: var(--font-display);
  font-size: var(--fs-600);
  line-height: 1;
}

.elige__actions { display: flex; gap: var(--space-3); }

.elige__foot {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-6) 0 0;
  font-size: var(--fs-100);
  color: var(--color-text-muted);
}

.elige__tick { color: var(--color-primary); font-weight: 700; }

/* --- El calendario desplegable ---
   Va pegado a su tarjeta y con la isla clara que necesita el widget de
   Nautisync, cuya interfaz vive en un shadow DOM que este CSS no alcanza. */
.elige-reserva {
  margin: calc(var(--space-5) * -1) 0 var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-top: none;
  border-radius: 0 0 var(--radius-xl) var(--radius-xl);
  background-color: var(--color-panel-light);
  animation: elige-desplegar 320ms var(--ease-premium);
}

.elige-reserva[hidden] { display: none; }

@keyframes elige-desplegar {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .elige-reserva { animation: none; }
}

.elige-reserva__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

/* Dentro de la isla clara mandan los colores oscuros, igual que en el panel
   de reserva de las páginas de producto. */
.elige-reserva__cabecera h3 {
  margin: 0;
  font-size: var(--fs-300);
  color: #14141A;
}

.elige-reserva__cerrar {
  flex: none;
  padding: 6px var(--space-4);
  border-radius: 100px;
  border: 1px solid rgba(0, 0, 0, 0.18);
  background: none;
  color: #14141A;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  cursor: pointer;
}

.elige-reserva__cerrar:hover { border-color: rgba(0, 0, 0, 0.42); }

/* ==========================================================================
   Incluido en el precio (partials/incluye.php)

   Cuatro cosas en una fila, no cuatro tarjetas en una cuadrícula. En móvil
   se parten en dos columnas en vez de apilarse en cuatro filas: son
   etiquetas cortas y una sola columna dejaba media pantalla vacía a la
   derecha para decir cuatro palabras.
   ========================================================================== */
.incluye__titulo {
  margin: 0 0 var(--space-5);
  font-size: var(--fs-300);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
  font-family: var(--font-body);
  font-weight: 700;
}

.incluye {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4) var(--space-5);
}

@media (min-width: 780px) {
  .incluye { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.incluye__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.incluye__icono {
  flex: none;
  width: 22px;
  height: 22px;
  opacity: 0.85;
}

.incluye__texto { display: flex; flex-direction: column; min-width: 0; }

.incluye__texto strong {
  font-size: var(--fs-100);
  font-weight: 700;
  line-height: 1.25;
}

.incluye__texto span {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

/* Pantallas bajas: el hero deja de imponer una altura mínima.
   ------------------------------------------------------------------------
   Con 88svh de mínimo, en una pantalla corta —un móvil con la barra del
   navegador desplegada, o la web dentro de un visor que se queda con parte
   de arriba— el hero crece más que la ventana y el botón acaba justo debajo
   del dock flotante, tapado. El padding inferior reserva sitio para el dock,
   pero solo protege al ÚLTIMO elemento; el botón va antes.
   Sin mínimo, el hero mide lo que mide su contenido y todo cae por encima
   del dock. */
@media (max-width: 899px) and (max-height: 720px) {
  .hero-video,
  .hero-video--compact {
    min-height: 0;
    padding-block: calc(var(--header-height) + var(--space-6))
                   calc(var(--mobile-cta-height) + var(--space-6));
  }
}
