/* ==========================================================================
   Components — structural + visual styles for reusable UI pieces.
   ========================================================================== */

/* Buttons — premium: soft lift + shadow on hover, a real press state (not
   just a hover state minus itself), primary gets a tinted glow shadow
   instead of a flat generic one. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  border-radius: var(--radius-md);
  border: 2px solid transparent;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--fs-200);
  text-decoration: none;
  cursor: pointer;
  min-height: 48px; /* accessible tap target */
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast), border-color var(--transition-fast);
  will-change: transform;
}

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

.btn:active {
  transform: translateY(-1px) scale(0.98);
  transition-duration: 80ms;
}

.btn:focus-visible {
  transform: translateY(-3px);
}

.btn--primary {
  background-color: var(--color-primary);
  color: var(--color-white);
  box-shadow: 0 4px 14px rgba(var(--color-primary-rgb), 0.35);
}

.btn--primary:hover,
.btn--primary:focus-visible {
  background-color: var(--color-primary-dark);
  box-shadow: var(--shadow-primary);
}

/* En tema oscuro el secundario ya no puede ser "borde tinta sobre blanco":
   se invierte a borde claro sobre negro, y al pasar el ratón se rellena en
   blanco (el único relleno que gana contraste sobre el fondo de página). */
.btn--secondary {
  background-color: transparent;
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.btn--secondary:hover,
.btn--secondary:focus-visible {
  background-color: var(--color-white);
  border-color: var(--color-white);
  color: var(--color-ink);
  box-shadow: var(--shadow-md);
}

/* Used on dark surfaces (hero, cta-banner) — border needs to be visible
   against ink/photo backgrounds, and hover fills white-on-dark instead of
   dark-on-dark. */
.btn--on-dark {
  border-color: rgba(255, 255, 255, 0.55);
  color: var(--color-white);
}

.btn--on-dark:hover,
.btn--on-dark:focus-visible {
  background-color: var(--color-white);
  border-color: var(--color-white);
  color: var(--color-ink);
  box-shadow: var(--shadow-lg);
}

.btn--tertiary {
  background-color: transparent;
  color: var(--color-text-muted);
}

.btn--lg {
  padding: var(--space-4) var(--space-8);
  font-size: var(--fs-300);
  min-height: 56px;
}

/* Header — fixed (not sticky): removed from flow so a hero can extend
   full-bleed behind it (pages without a hero reserve --header-height of
   top padding instead, see base.css). Permanently glass: dark, blurred,
   translucent on every page from first paint — this is what makes the nav
   read as premium chrome rather than a plain bar, and it means the exact
   same header design works identically whether it's floating over a photo
   or over a solid page-header band. On scroll it intensifies (more opaque
   + shadow) via [data-scrolled="true"], toggled by
   assets/js/header-scroll.js watching a sentinel element
   (IntersectionObserver — no scroll-listener jank). */
.site-header {
  position: fixed;
  top: 0;
  inset-inline: 0;
  z-index: var(--z-header);
  height: var(--header-height);
  display: flex;
  align-items: center;
  background-color: rgba(14, 14, 16, 0.38);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  transition: background-color var(--transition-standard), box-shadow var(--transition-standard), border-color var(--transition-standard), backdrop-filter var(--transition-standard);
}

/* Sobre un hero de vídeo y sin haber desplazado, la cabecera desaparece
   del todo: su cristal oscuro sumado al velo del hero convertía la franja
   superior en una barra plana que cortaba el vídeo en seco. Sin fondo, el
   logo y el menú flotan sobre el metraje y la imagen llega hasta arriba.
   La legibilidad la sostiene el propio velo del hero, que ya oscurece esa
   franja, más la sombra de texto de abajo. En cuanto se desplaza un píxel,
   header-scroll.js pone data-scrolled y vuelve el cristal opaco. */
body.has-hero .site-header:not([data-scrolled="true"]) {
  background-color: transparent;
  border-bottom-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.site-header[data-scrolled="true"] {
  background-color: rgba(12, 12, 14, 0.86);
  border-bottom-color: transparent;
  box-shadow: var(--shadow-md);
}

.site-header__inner {
  position: relative; /* anchors the mobile nav dropdown below */
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.site-header__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  /* Belt-and-suspenders against the logo ever dictating header height:
     the flex item itself is capped independently of its content's
     intrinsic size (859x311 native — if the image ever rendered at
     anywhere near that, it would break the whole navbar, which is
     exactly what happened in production off stale cached CSS). */
  max-height: var(--header-height);
  overflow: hidden;
}

/* Logo sizing is deliberately NOT left to the image's natural dimensions
   (859x311) — max-height + max-width caps it at every breakpoint, with
   width/height:auto so it scales down proportionally rather than
   stretching or cropping, and object-fit:contain as a second guarantee
   for the same. This must survive even if some other rule or a stale
   cache momentarily fails to apply — the max-* pair is the hard ceiling. */
.site-header__logo-img {
  display: block;
  width: auto;
  height: auto;
  max-height: 34px;
  max-width: 140px;
  object-fit: contain;
}

@media (min-width: 600px) {
  .site-header__logo-img {
    max-height: 40px;
    max-width: 160px;
  }
}

@media (min-width: 900px) {
  .site-header__logo-img {
    max-height: 44px;
    max-width: 180px;
  }
}

/* Es un <a> desde que abre "Explora": un enlace no tiene caja propia, así
   que sin display no habría dónde dibujar las tres barras ni área que tocar. */
.site-header__menu-toggle {
  display: inline-flex;
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: none;
  cursor: pointer;
  position: relative;
}

/* Hamburger icon drawn in pure CSS (three bars) so it never depends on a
   missing icon asset, and can cleanly morph into a close (X) state. */
.site-header__menu-toggle::before,
.site-header__menu-toggle::after,
.site-header__menu-toggle span[data-bar] {
  content: '';
  position: absolute;
  left: 50%;
  width: 22px;
  height: 2px;
  background-color: var(--color-white);
  transform: translateX(-50%);
  transition: transform var(--transition-fast), opacity var(--transition-fast), top var(--transition-fast);
}

.site-header__menu-toggle::before { top: 16px; }
.site-header__menu-toggle span[data-bar] { top: 22px; }
.site-header__menu-toggle::after { top: 28px; }

.site-header__menu-toggle[aria-expanded="true"]::before {
  top: 22px;
  transform: translateX(-50%) rotate(45deg);
}

.site-header__menu-toggle[aria-expanded="true"] span[data-bar] {
  opacity: 0;
}

.site-header__menu-toggle[aria-expanded="true"]::after {
  top: 22px;
  transform: translateX(-50%) rotate(-45deg);
}

@media (min-width: 900px) {
  .site-header__menu-toggle { display: none; }
}

/* Desktop-only booking CTA (Phase 2) — mobile already has "Reservar" in
   the sticky bottom bar, so showing it here too would be redundant. */
.site-header__cta {
  display: none;
}

@media (min-width: 900px) {
  .site-header__cta {
    display: inline-flex;
  }
}

/* Nav — collapsed by default on mobile, toggled via assets/js/mobile-menu.js
   setting data-nav-open on #primary-nav; always visible from 900px up. */
.site-nav {
  display: none;
  position: absolute;
  inset-inline: 0;
  top: 100%;
  background-color: var(--color-ink);
  box-shadow: var(--shadow-lg);
}

.site-nav[data-nav-open="true"] {
  display: block;
  animation: nav-drop-in var(--transition-standard) var(--ease-premium) both;
}

@keyframes nav-drop-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (min-width: 900px) {
  .site-nav {
    display: block;
    position: static;
    box-shadow: none;
    background-color: transparent;
  }
}

.site-nav__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  padding: var(--space-2) 0;
}

.site-nav__link {
  display: block;
  padding: var(--space-4) var(--space-6);
  min-height: 44px;
  color: var(--color-white);
  text-decoration: none;
  font-weight: 500;
  position: relative;
}

@media (min-width: 900px) {
  .site-nav__list {
    flex-direction: row;
    gap: var(--space-6);
    padding: 0;
  }

  .site-nav__link {
    padding: 0;
    min-height: auto;
  }

  /* Animated underline on hover — a small, elegant micro-interaction
     rather than an instant color swap. */
  .site-nav__link::after {
    content: '';
    position: absolute;
    left: 0;
    right: 100%;
    bottom: -6px;
    height: 2px;
    background-color: var(--color-primary);
    transition: right var(--transition-standard) var(--ease-premium);
  }

  .site-nav__link:hover::after,
  .site-nav__link[aria-current="page"]::after {
    right: 0;
  }
}

/* ==========================================================================
   Dock flotante de móvil (partials/mobile-dock.php) — sustituye a la barra
   inferior a todo el ancho que había antes.

   Píldora que flota sobre el contenido, con el botón de reservar como
   círculo saliente en el centro. Solo hasta 899px: de ahí arriba están la
   navegación completa y el CTA de la cabecera, y repetirlos abajo sería
   ruido.

   viewport-fit=cover (partials/head.php) es requisito para que el env()
   de safe-area resuelva a algo distinto de 0 en móviles con barra gestual;
   sin él esta regla es silenciosamente inerte y el dock queda pegado al
   indicador del sistema.
   ========================================================================== */
.mobile-dock {
  position: fixed;
  z-index: var(--z-mobile-cta);
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1);
  width: min(calc(100vw - var(--space-8)), 420px);
  padding: var(--space-3) var(--space-5);
  border-radius: 100px;
  background-color: rgba(14, 14, 18, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
}

@media (min-width: 900px) {
  .mobile-dock { display: none; }
}

.mobile-dock__item {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 44px de alto real de zona táctil aunque el texto ocupe 14px: el dock
     es estrecho y sin esto los objetivos quedarían por debajo del mínimo
     accesible. */
  min-height: 44px;
  padding: 0 var(--space-1);
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.82);
  text-decoration: none;
  background: none;
  border: none;
  cursor: pointer;
  transition: color var(--transition-fast);
}

.mobile-dock__item:active {
  color: var(--color-primary-bright);
}

/* currentColor: los iconos se tiñen con el color del dock y cambian solos
   al pulsar, igual que hace el texto de los demás. Sin esto habría que
   repetir el color y el estado activo para cada uno. */
.mobile-dock__icono {
  width: 22px;
  height: 22px;
  fill: currentColor;
  display: block;
}

/* El círculo se sale por arriba de la píldora, que es lo que lo convierte
   en el único elemento con relieve de la pantalla. El hueco lo abre el
   propio gap del flex más este ancho fijo; no hace falta posicionamiento
   absoluto, así que el orden del DOM sigue coincidiendo con el orden
   visual y con el de tabulación. */
.mobile-dock__book {
  flex: 0 0 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: 80px;
  height: 80px;
  margin-block: -22px;
  border-radius: 50%;
  background-color: var(--color-white);
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-decoration: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  transition: transform var(--transition-fast), background-color var(--transition-fast);
}

.mobile-dock__book:active {
  transform: scale(0.94);
  background-color: var(--color-primary);
  color: var(--color-white);
}

/* Deja sitio bajo el contenido para que el dock no tape nunca lo último de
   la página. No basta con el alto de la píldora: el círculo de RESERVAR
   sobresale 22px por encima, así que el dock ocupa unos 87px contados desde
   el borde inferior de la ventana. Con --space-8 (32px) el colchón se
   quedaba en 94px y los últimos enlaces de 60 min y Tabarca seguían
   cayendo debajo. --space-12 deja 110px, que es el alto real más un margen
   que se ve. */
@media (max-width: 899px) {
  body {
    padding-bottom: calc(var(--mobile-cta-height) + var(--space-12) + env(safe-area-inset-bottom, 0px));
  }
}

/* Footer */
.site-footer {
  background-color: var(--color-ink);
  color: var(--color-white);
  padding-block: var(--space-24) var(--space-16);
}

.site-footer a {
  color: var(--color-white);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--color-primary);
}

.site-footer__inner {
  display: grid;
  gap: var(--space-8);
}

.site-footer__logo {
  display: inline-block;
  margin-bottom: var(--space-4);
}

.site-footer__logo img {
  display: block;
  height: 38px;
  width: auto;
}

.site-footer__business-name {
  font-family: var(--font-display);
  font-size: var(--fs-400);
  font-weight: 700;
  margin-bottom: var(--space-2);
}

.site-footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.site-footer__copyright {
  color: rgba(255, 255, 255, 0.5);
  font-size: var(--fs-100);
  margin-top: var(--space-8);
  padding-top: var(--space-8);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

/* Booking widget wrapper — reserves space so the third-party widget never
   causes layout shift while its script loads/lazy-instantiates. */
/* Isla clara deliberada: el widget de Nautisync trae su propia interfaz en
   claro dentro de un shadow DOM que este CSS no puede alcanzar. Forzar el
   fondo oscuro alrededor solo conseguiría que pareciera un fallo de carga,
   así que se le da un panel blanco propio y pasa a leerse como la ficha de
   reserva del sitio. */
.booking-widget-wrapper {
  min-height: 420px;
  background-color: var(--color-panel-light);
  color: var(--color-panel-light-text);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

/* Las tarjetas de experiencia (.experience-card) vivían aquí. Sustituidas
   por .tour-card en video.css: mismo sitio en la página, pero con vídeo a
   sangre y el texto flotando encima en vez de foto arriba y cuerpo blanco
   debajo. Reglas retiradas para no dejar CSS muerto pesando en cada carga.
   Historial en git. */

/* Breadcrumbs */
.breadcrumbs__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0;
  margin: 0;
  font-size: var(--fs-100);
  color: var(--color-text-muted);
}

.breadcrumbs__list a {
  color: var(--color-text-muted);
}

.breadcrumbs__list a:hover {
  color: var(--color-primary);
}

/* On a dark hero/page-header, the default muted-grey breadcrumb text is
   invisible — lighten it contextually rather than adding a markup variant. */
.hero-cinematic .breadcrumbs,
.page-header .breadcrumbs {
  margin-bottom: var(--space-6);
}

.page-header .breadcrumbs__list {
  justify-content: center;
}

.hero-cinematic .breadcrumbs__list,
.hero-cinematic .breadcrumbs__list a,
.page-header .breadcrumbs__list,
.page-header .breadcrumbs__list a {
  color: rgba(255, 255, 255, 0.65);
}

.hero-cinematic .breadcrumbs__list a:hover,
.page-header .breadcrumbs__list a:hover {
  color: var(--color-white);
}

/* FAQ accordion — smooth height + opacity transition via the CSS grid-rows
   technique (animating a 0fr -> 1fr track is interpolable, unlike height:
   auto), plus a rotating chevron. No JS height calculation needed. */
.faq-item {
  border-bottom: 1px solid var(--color-border);
}

.faq-item__question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  text-align: left;
  background: none;
  border: none;
  padding: var(--space-5) 0;
  font-family: var(--font-display);
  font-size: var(--fs-300);
  font-weight: 600;
  cursor: pointer;
  color: var(--color-text);
}

.faq-item__icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: var(--color-surface-2);
  position: relative;
  transition: background-color var(--transition-standard) var(--ease-premium);
}

/* Chevron drawn from a rotated border-corner (classic CSS trick) — points
   down at rest, flips to point up when the panel opens. Pure transform,
   GPU-accelerated. */
.faq-item__icon::before {
  content: '';
  position: absolute;
  top: 42%;
  left: 50%;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--color-primary);
  border-bottom: 2px solid var(--color-primary);
  transform: translate(-50%, -50%) rotate(45deg);
  transition: transform var(--transition-standard) var(--ease-premium);
}

.faq-item__question[aria-expanded="true"] .faq-item__icon {
  background-color: var(--color-primary);
}

.faq-item__question[aria-expanded="true"] .faq-item__icon::before {
  border-color: var(--color-white);
  transform: translate(-50%, -35%) rotate(225deg);
}

.faq-item__answer {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--transition-standard) var(--ease-premium), opacity var(--transition-fast) ease;
}

.faq-item__answer.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
}

.faq-item__answer > div {
  overflow: hidden;
}

.faq-item__answer p {
  padding-bottom: var(--space-5);
  color: var(--color-text-muted);
  margin: 0;
}

/* Consent banner. On mobile it must stack above the sticky CTA bar, not
   overlap it — both are fixed/bottom:0, so on first visit (before a
   consent choice is made) they'd otherwise render on top of each other. */
.consent-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--z-consent-banner);
  background-color: var(--color-surface);
  border-top: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
}

/* En móvil se aprieta todo lo que se puede. Con el texto a tamaño de párrafo
   y los botones a 48px apilados, el aviso ocupaba casi la mitad de la
   pantalla de un teléfono: por encima del dock, tapando el contenido y
   dejando a la vista una franja donde no cabía ni el titular. Un aviso de
   cookies tiene que verse, no adueñarse de la primera pantalla. */
@media (max-width: 899px) {
  .consent-banner {
    bottom: calc(var(--mobile-cta-height) + var(--space-6) + env(safe-area-inset-bottom, 0px));
    padding: var(--space-3) var(--space-4);
  }

  .consent-banner__text {
    font-size: 0.8125rem;
    line-height: 1.4;
    margin: 0;
  }

  .consent-banner__actions {
    margin-top: var(--space-3);
  }

  /* Los tres en una fila: apilados sumaban 150px de alto ellos solos. */
  .consent-banner .btn {
    flex: 1 1 auto;
    min-height: 40px;
    padding: var(--space-2) var(--space-3);
    font-size: 0.8125rem;
  }
}

.consent-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* Language switcher */
.language-switcher {
  display: flex;
  gap: var(--space-2);
}

.language-switcher a {
  color: inherit;
  text-decoration: none;
  opacity: 0.7;
  transition: opacity var(--transition-fast);
}

.language-switcher a:hover {
  opacity: 1;
}

.language-switcher a[aria-current="true"] {
  font-weight: 700;
  opacity: 1;
}

/* Aquí estaban .hero-cinematic (heroes de foto de las páginas de producto)
   y .hero-split (hero partido de la portada), más su fila de confianza
   .hero-trust. Los tres los sustituye .hero-video en video.css. Retirados
   por lo mismo: ninguna página los usaba ya y sumaban ~19 KB de CSS que
   se descargaba en todas. Historial en git. */

/* Non-hero page intro band — precios/contacto/legal pages. Dark, branded,
   consistent with the hero's palette so no page feels like a different
   site, without the full cinematic height (would be excessive for a
   utility page). */
.page-header {
  position: relative;
  background-color: var(--color-ink);
  color: var(--color-white);
  text-align: center;
  padding-block: var(--space-24) var(--space-16);
  overflow: hidden;
  isolation: isolate;
}

.page-header::before {
  content: '';
  position: absolute;
  top: -30%;
  right: -10%;
  width: 60%;
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(237, 42, 145, 0.35) 0%, rgba(237, 42, 145, 0) 70%);
  z-index: -1;
}

.page-header h1 {
  color: var(--color-white);
  margin-bottom: var(--space-4);
}

.page-header p {
  color: rgba(255, 255, 255, 0.75);
  max-width: 640px;
  margin-inline: auto;
  font-size: var(--fs-300);
}

/* Icon strip — compact, horizontally scrollable on mobile, evenly spaced
   on desktop. Used for the intro strip (sin licencia / location / duration). */
.icon-strip {
  display: flex;
  gap: var(--space-6);
  overflow-x: auto;
  padding-block: var(--space-5);
  background-color: var(--color-ink);
  border-block: 1px solid var(--color-border);
}

@media (min-width: 900px) {
  .icon-strip {
    justify-content: center;
    overflow-x: visible;
  }
}

.icon-strip__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  white-space: nowrap;
  font-size: var(--fs-200);
  font-weight: 500;
}

/* Same premium circular-badge treatment as .feature-card__icon, sized to
   this component's own scale (a dense single-line strip, not a card grid —
   64px badges here would double the strip's height and fight its ticker
   role). Consistent stroke/weight/palette either way. */
.icon-strip__item-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, rgba(237, 42, 145, 0.14), rgba(237, 42, 145, 0.04) 70%);
}

.icon-strip__item img {
  width: 22px;
  height: 22px;
}

/* ==========================================================================
   Feature grid — "what's included" sections (homepage, precios.php, each
   experience page). Replaces the old plain icon+text columns: this is a
   card grid, designed to raise perceived value, not a documentation list.
   4 columns desktop / 2 tablet / 1 mobile, every card the same height
   (grid's default row-stretch + height:100% on the card — content length
   differences never produce a taller first card).
   ========================================================================== */
/* margin-bottom intentionally matches the global h2 rule (base.css) exactly
   — a bare <h2> and a <h2>+subtitle .section-heading must leave the same
   gap before whatever content follows, so heading spacing reads as one
   standard regardless of which pattern a given section uses. */
.section-heading {
  max-width: 620px;
  margin-inline: auto;
  margin-bottom: var(--space-6);
  text-align: center;
}

@media (min-width: 900px) {
  .section-heading {
    margin-bottom: var(--space-8);
  }
}

.section-heading__subtitle {
  color: var(--color-text-muted);
  font-size: var(--fs-300);
  margin: 0;
}

.feature-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
  align-items: stretch;
}

@media (min-width: 600px) {
  .feature-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

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

.feature-card {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: var(--space-3);
  background:
    radial-gradient(circle at 85% -10%, rgba(var(--color-primary-rgb), 0.16) 0%, rgba(var(--color-primary-rgb), 0) 55%),
    linear-gradient(165deg, var(--color-surface-2) 0%, var(--color-surface) 120%);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8) var(--space-6) var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-standard) var(--ease-premium), box-shadow var(--transition-standard) var(--ease-premium), border-color var(--transition-standard) var(--ease-premium);
}

.feature-card:hover,
.feature-card:focus-within {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
  border-color: rgba(237, 42, 145, 0.3);
}

.feature-card__icon {
  width: 72px;
  height: 72px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%, rgba(237, 42, 145, 0.16), rgba(237, 42, 145, 0.05) 70%);
  margin-bottom: var(--space-1);
  transition: transform var(--transition-standard) var(--ease-premium);
}

.feature-card:hover .feature-card__icon {
  transform: scale(1.08) rotate(-4deg);
}

.feature-card__icon img {
  width: 32px;
  height: 32px;
}

.feature-card__title {
  font-size: var(--fs-400);
  margin: 0;
  line-height: var(--lh-tight);
}

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

/* CTA banner — reusable dark band, used for both the mid-page and final
   closing CTAs. */
.cta-banner {
  position: relative;
  background-color: var(--color-ink);
  color: var(--color-white);
  text-align: center;
  padding-block: var(--space-12);
  overflow: hidden;
  isolation: isolate;
}

.cta-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 0%, rgba(237, 42, 145, 0.22) 0%, rgba(237, 42, 145, 0) 60%);
  z-index: -1;
}

.cta-banner a {
  color: var(--color-white);
}

/* Two-column narrative layout — reusable for Fleet & Equipment and any
   future "photo + text" section. */
.narrative {
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 900px) {
  .narrative {
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: var(--space-16);
  }
}

.narrative img {
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
}

.narrative__list {
  list-style: none;
  margin: var(--space-6) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.narrative__list li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  color: var(--color-text-muted);
}

.narrative__list img {
  flex-shrink: 0;
  border-radius: 0;
  box-shadow: none;
  margin-top: 2px;
}

/* Contact grid — map + details, reused wherever location content appears. */
.contact-grid {
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 900px) {
  .contact-grid {
    grid-template-columns: 60fr 40fr;
  }
}

.contact-grid__location-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-300);
  margin-bottom: var(--space-2);
}

.contact-grid__map {
  min-height: 320px;
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

/* El mapa incrustado de Google se sirve siempre en claro y no admite tema.
   Se invierte y se rota el tono para dejarlo en oscuro: es el mismo truco
   que usan los mapas nocturnos incrustados. Al pasar el ratón vuelve al
   original, porque para leer una dirección real el mapa auténtico es más
   fiable que la versión teñida. */
/* En una pantalla táctil el iframe se traga el gesto de arrastrar: al pasar
   el dedo por encima del mapa, la página deja de desplazarse y se queda
   atascada ahí. Con el puntero grueso se desactivan los eventos del mapa —
   se sigue viendo, pero el dedo lo atraviesa— y para interactuar de verdad
   está el botón "Abrir en Google Maps", que además es lo que quiere quien
   va a conducir hasta allí. En ratón se deja interactivo. */
@media (pointer: coarse) {
  .contact-grid__map iframe { pointer-events: none; }
}

.contact-grid__map iframe {
  filter: invert(0.92) hue-rotate(180deg) saturate(0.75) contrast(0.92);
  transition: filter var(--transition-standard);
}

.contact-grid__map:hover iframe,
.contact-grid__map:focus-within iframe {
  filter: none;
}

.contact-grid__map iframe {
  width: 100%;
  height: 100%;
  min-height: 320px;
  border: 0;
  display: block;
}

@media (min-width: 900px) {
  .contact-grid__map {
    min-height: 100%;
  }
}

/* Gallery carousel — scroll-position-based, not a transform reimplementation,
   so touch devices get native momentum scrolling. Media-agnostic:
   .gallery-carousel__item can hold <img> today or <video> later with no
   CSS change (see docs/component-contracts.md). Clicking an item opens the
   lightbox (assets/js/lightbox.js). */
.gallery-carousel {
  position: relative;
}

.gallery-carousel__track {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  list-style: none;
  margin: 0;
  padding: var(--space-2) var(--space-1) var(--space-2);
}

.gallery-carousel__item {
  flex: 0 0 85%;
  scroll-snap-align: center;
  border-radius: var(--radius-lg);
  overflow: hidden;
  position: relative;
}

@media (min-width: 900px) {
  .gallery-carousel__item {
    flex-basis: 31%;
  }
}

.gallery-carousel__item button {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
  aspect-ratio: 4 / 3;
}

.gallery-carousel__item img,
.gallery-carousel__item video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--transition-slow) var(--ease-premium);
}

.gallery-carousel__item:hover img {
  transform: scale(1.06);
}

.gallery-carousel [data-carousel-prev],
.gallery-carousel [data-carousel-next] {
  display: none;
}

@media (min-width: 900px) {
  .gallery-carousel [data-carousel-prev],
  .gallery-carousel [data-carousel-next] {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: none;
    background-color: var(--color-surface-2);
    border: 1px solid var(--color-border-strong);
    color: var(--color-text);
    box-shadow: var(--shadow-lg);
    cursor: pointer;
    z-index: 1;
    transition: transform var(--transition-fast), background-color var(--transition-fast);
  }

  .gallery-carousel [data-carousel-prev]:hover,
  .gallery-carousel [data-carousel-next]:hover {
    background-color: var(--color-primary);
    color: var(--color-white);
    transform: translateY(-50%) scale(1.08);
  }

  .gallery-carousel [data-carousel-prev] { left: var(--space-2); }
  .gallery-carousel [data-carousel-next] { right: var(--space-2); }
}

.gallery-carousel__dots {
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.gallery-carousel__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: none;
  padding: 0;
  background-color: var(--color-border);
  cursor: pointer;
  transition: background-color var(--transition-fast), transform var(--transition-fast);
}

.gallery-carousel__dot[aria-current="true"] {
  background-color: var(--color-primary);
  transform: scale(1.3);
}

/* Lightbox — opens on gallery item click. Video-ready: swaps in whatever
   media type the triggering .gallery-carousel__item holds. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(15, 15, 17, 0.94);
  padding: var(--space-6);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--transition-standard) ease, visibility 0s linear var(--transition-standard);
}

.lightbox[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--transition-standard) ease;
}

.lightbox__figure {
  max-width: min(1100px, 92vw);
  max-height: 86vh;
  transform: scale(0.96);
  transition: transform var(--transition-standard) var(--ease-premium);
}

.lightbox[data-open="true"] .lightbox__figure {
  transform: scale(1);
}

.lightbox__figure img {
  max-width: 100%;
  max-height: 86vh;
  width: auto;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

.lightbox__close,
.lightbox__prev,
.lightbox__next {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background-color: rgba(255, 255, 255, 0.12);
  color: var(--color-white);
  cursor: pointer;
  transition: background-color var(--transition-fast), transform var(--transition-fast);
}

.lightbox__close:hover,
.lightbox__prev:hover,
.lightbox__next:hover {
  background-color: var(--color-primary);
}

.lightbox__close {
  top: var(--space-6);
  right: var(--space-6);
}

.lightbox__prev,
.lightbox__next {
  top: 50%;
  transform: translateY(-50%);
}

.lightbox__prev:hover,
.lightbox__next:hover {
  transform: translateY(-50%) scale(1.08);
}

.lightbox__prev { left: var(--space-4); }
.lightbox__next { right: var(--space-4); }

@media (max-width: 599px) {
  .lightbox__prev, .lightbox__next { display: none; }
}

/* ==========================================================================
   Scroll reveal — IntersectionObserver-driven (assets/js/scroll-reveal.js)
   fade/slide-up, GPU-only properties (opacity/transform). Staggered
   children via --reveal-delay, set inline per item. One-time (unobserved
   after first reveal), inert entirely under prefers-reduced-motion via the
   global override in base.css.
   ========================================================================== */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--transition-slow) var(--ease-premium), transform var(--transition-slow) var(--ease-premium);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Pricing cards — same visual language as .experience-card (rounded,
   shadow, hover lift) but no image: price/duration is the visual anchor
   instead of a photo. Used on precios.php and as the summary block
   repeated on each experience page. */
.pricing-cards {
  display: grid;
  gap: var(--space-6);
}

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

.pricing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  padding: var(--space-8) var(--space-6) var(--space-6);
  transition: transform var(--transition-standard) var(--ease-premium), box-shadow var(--transition-standard) var(--ease-premium);
}

.pricing-card:hover,
.pricing-card:focus-within {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}

.pricing-card--featured {
  border-color: var(--color-primary);
  border-width: 2px;
}

.pricing-card--featured::before {
  content: 'Más popular';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: var(--color-primary);
  color: var(--color-white);
  font-size: var(--fs-100);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: var(--space-1) var(--space-4);
  border-radius: 100px;
  white-space: nowrap;
}

.pricing-card__duration {
  margin: 0;
  font-size: var(--fs-400);
}

.pricing-card__price {
  font-family: var(--font-display);
  font-size: var(--fs-600);
  font-weight: 700;
  color: var(--color-primary);
  margin: 0;
}

.pricing-card__price small {
  font-family: var(--font-body);
  font-size: var(--fs-100);
  font-weight: 400;
  color: var(--color-text-muted);
}

.pricing-card__cta {
  width: 100%;
  margin-top: auto;
}

/* Feature list — icon + text rows, used on experience pages ("qué incluye")
   and pricing cards alike. Reuses .icon-grid__item's icon sizing idiom but
   as a left-aligned row list rather than a centered grid. */
.feature-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
}

.feature-list__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.feature-list__item img {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
}

/* Trust stat strip — social proof band (real aggregate figures, sourced
   from the same operating business, PROJECT.md §12). */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-8);
  text-align: center;
  max-width: 720px;
  margin-inline: auto;
}

@media (min-width: 600px) {
  .stat-strip {
    grid-template-columns: repeat(3, 1fr);
  }
}

.stat-strip__number {
  font-family: var(--font-display);
  font-size: var(--fs-600);
  font-weight: 700;
  color: var(--color-primary);
  line-height: 1;
  margin-bottom: var(--space-2);
}

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

/* Booking panel — merges the price/features summary and the Nautisync
   widget into one designed object instead of two separately-floating
   pieces stacked on the page. This is the page's single pricing moment,
   positioned immediately before the widget it belongs to. */
.booking-panel {
  display: grid;
  gap: var(--space-8);
  background-color: var(--color-panel-light);
  color: var(--color-panel-light-text);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  border: 1px solid rgba(0, 0, 0, 0.08);
  padding: var(--space-8);
}

/* Dentro del panel claro se invierten los tokens de texto y de línea: es la
   única zona del sitio con fondo blanco, y heredar el gris claro de fuera
   la dejaría ilegible. Se hace por variables, no por selectores hijos uno a
   uno, para que cualquier componente que caiga aquí dentro herede bien. */
.booking-panel,
.booking-panel * {
  --color-text: var(--color-panel-light-text);
  --color-text-muted: var(--color-panel-light-muted);
  --color-border: rgba(0, 0, 0, 0.12);
  --color-border-strong: rgba(0, 0, 0, 0.28);
}

.booking-panel h2,
.booking-panel h3,
.booking-panel p {
  color: var(--color-panel-light-text);
}

.booking-panel .booking-widget-wrapper {
  box-shadow: none;
}

@media (min-width: 900px) {
  .booking-panel {
    grid-template-columns: 34fr 66fr;
    gap: var(--space-12);
    padding: var(--space-12);
  }
}

.booking-panel__price {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

@media (min-width: 900px) {
  .booking-panel__price {
    padding-inline-end: var(--space-12);
    border-inline-end: 1px solid var(--color-border);
  }
}

.booking-panel__duration {
  color: var(--color-text-muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--fs-100);
  margin: 0;
}

.booking-panel__price-value {
  font-family: var(--font-display);
  font-size: var(--fs-700);
  font-weight: 700;
  color: var(--color-primary);
  line-height: 1;
  margin: 0;
}

.booking-panel__price-value small {
  display: block;
  font-family: var(--font-body);
  font-size: var(--fs-100);
  font-weight: 500;
  color: var(--color-text-muted);
  margin-top: var(--space-2);
}

.booking-panel .booking-widget-wrapper {
  min-height: 460px;
}

/* Contact form */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  max-width: 640px;
  margin-inline: auto;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.form-field label {
  font-weight: 600;
  font-size: var(--fs-100);
}

.form-field input,
.form-field textarea {
  font-family: var(--font-body);
  font-size: var(--fs-200);
  padding: var(--space-3);
  background-color: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  min-height: 48px;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast);
}

.form-field input::placeholder,
.form-field textarea::placeholder {
  color: var(--color-text-muted);
}

.form-field input:hover,
.form-field textarea:hover {
  border-color: rgba(255, 255, 255, 0.38);
  background-color: var(--color-surface-2);
}

.form-field textarea {
  min-height: 140px;
  resize: vertical;
}

.form-field input:focus-visible,
.form-field textarea:focus-visible {
  outline: none;
  border-color: var(--color-primary);
  background-color: var(--color-surface-2);
  box-shadow: 0 0 0 4px rgba(var(--color-primary-rgb), 0.24);
}

.form-field--error input,
.form-field--error textarea {
  border-color: var(--color-primary);
}

.form-field__error {
  color: var(--color-primary);
  font-size: var(--fs-100);
}

/* Honeypot field — must stay visually and programmatically hidden from
   real users while remaining in the tab/DOM order bots crawl (see
   forms/contact-handler.php). Never `display:none`, which some bots skip. */
.form-field--honeypot {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.form-status {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  font-weight: 600;
}

.form-status[hidden] {
  display: none;
}

.form-status--success {
  background-color: rgba(var(--color-primary-rgb), 0.12);
  color: var(--color-text);
  border: 1px solid rgba(var(--color-primary-rgb), 0.55);
}

.form-status--error {
  background-color: rgba(var(--color-primary-rgb), 0.12);
  color: var(--color-primary-bright);
  border: 1px solid rgba(var(--color-primary-rgb), 0.55);
}

/* Legal prose — privacy/legal-notice/cookies pages. Plain, readable
   long-form content; deliberately not a generic ".prose" reset since this
   project has no other long-form content type yet. */
.legal-content {
  max-width: 760px;
}

.legal-content h2 {
  font-size: var(--fs-500);
  margin-top: var(--space-12);
}

.legal-content h3 {
  font-size: var(--fs-400);
  margin-top: var(--space-8);
}

.legal-content ul,
.legal-content ol {
  padding-left: var(--space-6);
  margin: 0 0 var(--space-4);
}

.legal-content li {
  margin-bottom: var(--space-2);
}

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

.legal-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 var(--space-6);
  font-size: var(--fs-100);
}

/* La tabla de cookies tiene cuatro columnas de texto y a 390px no cabe:
   desbordaba el documento 52px y hacía que TODA la página se pudiera
   arrastrar en horizontal, no solo la tabla. display:block la convierte en
   su propia caja de desplazamiento sin tocar el marcado; -webkit-overflow-
   scrolling mantiene la inercia en iOS. */
@media (max-width: 699px) {
  .legal-content table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }

  .legal-content td {
    white-space: normal;
    min-width: 12ch;
  }
}

.legal-content th,
.legal-content td {
  text-align: left;
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
}

/* ==========================================================================
   Explora — el mosaico de tarjetas (partials/explora-mosaico.php)

   Sustituye a la lista de enlaces de texto del menú de móvil y, además, es
   una página con URL propia (/explora.php). El mismo marcado sirve para los
   dos sitios; lo único que cambia es el contenedor.

   La rejilla mezcla tamaños a propósito. Doce tarjetas idénticas se leen
   como una tabla y obligan a repasarlas una a una; con dos anchas repartidas
   el ojo tiene dónde apoyarse y el recorrido tiene ritmo. Las anchas ocupan
   todas las columnas, así que el patrón se mantiene igual en móvil (2
   columnas) que en escritorio (4).
   ========================================================================== */

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

/* El número de columnas NO es libre: tiene que ser múltiplo del patrón. Las
   tarjetas van en grupos de tres —normal, normal, ancha— y la ancha ocupa dos
   columnas, así que cada grupo suma cuatro. Con 2 columnas cada grupo llena
   dos filas exactas; con 4, una. Con 3 columnas quedaría media fila vacía
   detrás de cada par, que es justo lo que pasaba antes de escribir esto. */
@media (min-width: 900px) {
  .explora__grid {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-4);
  }
}

.explora__celda--ancha {
  grid-column: span 2;
}

/* La proporción va en la CELDA y no en la tarjeta: así una tarjeta ancha y
   una normal pueden tener formas distintas sin que la rejilla se descuadre,
   y el alto no depende del texto que lleve dentro —un título de dos líneas
   estiraría una tarjeta y dejaría a su compañera de fila con un hueco. */
.explora__celda {
  aspect-ratio: 4 / 3;
}

.explora__celda--ancha {
  aspect-ratio: 16 / 8;
}

/* De 900px arriba la ancha comparte fila con dos normales, así que su alto
   ya lo fijan ellas: imponerle además una proporción propia la descuadraría
   respecto a sus compañeras de fila. */
@media (min-width: 900px) {
  .explora__celda--ancha { aspect-ratio: auto; }
}

.explora-card {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
  color: var(--color-white);
  text-decoration: none;
  isolation: isolate;
  transition: transform var(--transition-standard) var(--ease-premium),
              box-shadow var(--transition-standard) var(--ease-premium);
}

@media (hover: hover) {
  .explora-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lg);
  }

  .explora-card:hover .explora-card__go {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
  }
}

.explora-card:active {
  transform: scale(0.985);
}

.explora-card:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

/* Fondo: el clip (media-layer) o una foto quieta. Los dos se colocan igual
   y por debajo de todo lo demás. */
.explora-card .media-layer,
.explora-card__foto {
  position: absolute;
  inset: 0;
  z-index: 0;
}

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

/* Degradado, no una capa oscura plana: el texto va abajo y ahí hace falta
   contraste, mientras que arriba oscurecer solo apagaría la imagen. */
.explora-card__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.82) 0%,
    rgba(0, 0, 0, 0.45) 42%,
    rgba(0, 0, 0, 0.10) 72%,
    rgba(0, 0, 0, 0.28) 100%
  );
}

.explora-card__num,
.explora-card__pastilla,
.explora-card__body {
  position: relative;
  z-index: 2;
}

.explora-card__num {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  padding: 3px 9px;
  border-radius: 999px;
  background-color: rgba(8, 8, 10, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--color-white);
}

.explora-card__pastilla {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background-color: rgba(8, 8, 10, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* El punto de color es lo que se ve antes de leer la palabra, igual que en
   una etiqueta de estado. Verde = no te hace falta nada; ámbar = hay algo
   que saber. */
.explora-card__pastilla::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background-color: currentColor;
}

.explora-card__pastilla--ok { color: #4ADE80; }
.explora-card__pastilla--aviso { color: #FACC15; }

.explora-card__body {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
}

@media (min-width: 900px) {
  .explora-card__body { padding: var(--space-4); }
}

.explora-card__titulo {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.0625rem, 3.6vw, 1.5rem);
  line-height: 1.15;
  /* Sombra en vez de una caja detrás: el texto cae sobre vídeo, y sobre un
     fotograma claro el degradado solo no siempre llega. */
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
}

.explora__celda--ancha .explora-card__titulo {
  font-size: clamp(1.375rem, 5vw, 2.25rem);
}

.explora-card__pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}

.explora-card__sub {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.86);
  /* Un subtítulo cortado a mitad de palabra no informa: mejor que se
     recorte con puntos suspensivos y se lea el principio entero. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 900px) {
  .explora-card__sub { font-size: 0.8125rem; }
}

.explora-card__go {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.45);
  font-size: 0.9375rem;
  line-height: 1;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

@media (min-width: 900px) {
  .explora-card__go { width: 38px; height: 38px; font-size: 1.0625rem; }
}

/* Legal y contacto: texto pequeño, sin foto. Están para poder llegar, no
   para competir con las excursiones. */
.explora__pie {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3) var(--space-5);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.explora__pie a {
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  text-decoration: none;
  min-height: 24px;
}

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

/* --------------------------------------------------------------------------
   El panel a pantalla completa (partials/explora-panel.php)
   -------------------------------------------------------------------------- */

.explora-panel {
  position: fixed;
  inset: 0;
  z-index: 400;
  background-color: var(--color-black);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.explora-panel[data-abierto="true"] {
  animation: explora-entra var(--transition-standard) var(--ease-premium) both;
}

@keyframes explora-entra {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

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

.explora-panel__inner {
  /* El dock flota sobre el contenido: sin este hueco, la última fila de
     enlaces legales queda justo debajo y no se puede tocar. */
  padding: 0 var(--space-4) calc(var(--space-24) + env(safe-area-inset-bottom));
  max-width: 1200px;
  margin-inline: auto;
}

@media (min-width: 900px) {
  .explora-panel__inner { padding-bottom: var(--space-16); }
}

/* La cabecera se queda arriba al desplazar: en una rejilla larga, la única
   forma de salir no puede irse de pantalla. */
.explora-panel__head {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: calc(var(--space-4) + env(safe-area-inset-top)) 0 var(--space-4);
  background-color: var(--color-black);
}

.explora-panel__volver {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--color-border-strong);
  background: none;
  color: var(--color-white);
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.explora-panel__volver:hover {
  background-color: var(--color-surface-2);
}

.explora-panel__volver svg {
  width: 22px;
  height: 22px;
}

.explora-panel__titulo {
  flex: 1 1 auto;
  text-align: center;
  /* Compensa el ancho del botón para que el título quede centrado de verdad
     respecto a la pantalla y no respecto al hueco que sobra. */
  margin-right: 44px;
}

.explora-panel__eyebrow {
  margin: 0;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.explora-panel__titulo h2 {
  margin: 2px 0 0;
  font-size: clamp(1.125rem, 4.5vw, 1.5rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   La versión página (/explora.php)
   -------------------------------------------------------------------------- */

.explora-pagina {
  padding-top: var(--space-16);
  padding-bottom: var(--space-24);
}

.explora-pagina__head {
  margin-bottom: var(--space-8);
  text-align: center;
}

.explora-pagina__eyebrow {
  margin: 0 0 var(--space-2);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-primary);
}

.explora-pagina__lead {
  max-width: 56ch;
  margin-inline: auto;
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   Retoques de páginas nuevas
   -------------------------------------------------------------------------- */

/* Contenedor de las preguntas frecuentes agrupadas. Los .faq-item ya traen
   lo suyo; esto solo separa el bloque del título de su grupo. */
.faq-list {
  margin-top: var(--space-6);
}

.opiniones-nota {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  text-align: center;
  padding: var(--space-8) var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background-color: var(--color-surface);
}

.opiniones-nota__texto {
  margin: 0;
  max-width: 42ch;
  color: var(--color-text-muted);
}

.opiniones-nota__acciones {
  margin: 0;
}

.rating-google--grande {
  transform: scale(1.35);
  transform-origin: center;
  margin-block: var(--space-2);
}
