/* ==========================================================================
   Componentes — navegación, botones, formularios y pie.
   Lo que se repite en todas las páginas.
   ========================================================================== */

/* ==========================================================================
   Navegación
   ========================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  padding: var(--s4) var(--margen);
  /* El fondo va en un pseudoelemento y no en la propia barra para poder
     fundirlo con el scroll sin tocar la opacidad del contenido: si se atenúa
     la barra entera, el texto del menú se va con ella. */
  isolation: isolate;
  /* El color del texto se funde al mismo ritmo que el fondo: en la home pasa
     de claro (sobre el hero oscuro) a tinta (sobre el papel) al hacer scroll. */
  transition: color var(--t-base) var(--entra);
}

.nav::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--page);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transition: opacity var(--t-base) var(--entra);
}

/* Sobre el hero la barra flota sin fondo; en cuanto se baja, aparece el papel.
   Sin esto, el menú se lee ENCIMA de la fotografía y no hay contraste que
   valga. La clase la pone main.js al pasar el primer umbral de scroll. */
.nav.posado::before { opacity: 1; }

/* El hero de la home es oscuro: mientras la barra flota sobre él (ni scroll
   ni menú abierto), marca, enlaces y botón van en claro. En cuanto aparece el
   papel —.posado al hacer scroll, o el panel abierto en el móvil— vuelve la
   tinta, que es lo que se lee sobre ese fondo. */
[data-hero-oscuro] .nav:not(.posado):not(.nav--abierto) {
  color: var(--on-dark);
}

[data-hero-oscuro] .nav:not(.posado):not(.nav--abierto) .nav__boton {
  border-color: rgba(244, 244, 242, 0.45);
}

.nav__marca {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 400;   /* Instrument Serif solo tiene este peso; ver base.css */
  letter-spacing: -0.005em;
  text-decoration: none;
  white-space: nowrap;
}

.nav__enlaces {
  display: flex;
  align-items: center;
  gap: clamp(var(--s4), 2.4vw, var(--s7));
  list-style: none;
  padding: 0;
}

.nav__enlace {
  position: relative;
  font-size: var(--fs-pequeno);
  font-weight: 500;
  text-decoration: none;
  padding-block: var(--s2);
  white-space: nowrap;
}

/* El subrayado crece desde la izquierda. Va en un ::after y no en
   text-decoration porque así se puede animar el ancho, que es lo que hace
   que el gesto se lea como un trazo y no como un encendido. */
.nav__enlace::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-base) var(--entra);
}

.nav__enlace:hover::after,
.nav__enlace:focus-visible::after { transform: scaleX(1); }

/* La página en la que ya estás: subrayado fijo y en el color del ambiente.
   Se marca con aria-current, así que el lector de pantalla lo dice igual que
   lo enseña el color — no se depende solo de la vista. */
.nav__enlace[aria-current='page'] { color: var(--acento-texto); }
.nav__enlace[aria-current='page']::after {
  transform: scaleX(1);
  background: var(--acento);
}

/* El botón del menú solo existe en pantalla estrecha y con JavaScript: sin
   JS no hay quien abra el desplegable, así que el botón no se enseña y el
   menú queda en su forma de respaldo (dos filas, ver la media query). */
.nav__boton {
  display: none;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line-fuerte);
  border-radius: var(--radio);
  background: transparent;
  color: inherit;
}

/* En pantalla estrecha, el clásico menú desplegable.
   `min-width: 0` en el <nav> intermedio sigue siendo la pieza clave: el item
   flex de la cabecera es ese <nav> (no el <ul>), y con su mínimo automático
   exigía el ancho de todo el menú — la barra desbordaba el borde de la
   pantalla y el menú se veía cortado. */
@media (max-width: 620px) {
  /* Respaldo sin JS (y mientras carga el guion): la cabecera rompe en dos
     filas y, como último recurso, la fila del menú puede desplazarse. */
  .nav { flex-wrap: wrap; gap: var(--s2) var(--s4); padding-inline: var(--s4); }
  .nav > nav { min-width: 0; }
  .nav__enlaces {
    gap: var(--s4);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .nav__enlaces::-webkit-scrollbar { display: none; }

  /* Con JS: el desplegable. El botón aparece y el menú se esconde hasta que
     se abre; entonces cae en panel bajo la barra, a todo lo ancho. */
  html.js .nav { flex-wrap: nowrap; }
  html.js .nav__boton { display: grid; place-items: center; }
  html.js .nav > nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: var(--s3) var(--s4) var(--s4);
    background: var(--page);
    border-bottom: 1px solid var(--line);
  }
  html.js .nav--abierto > nav { display: block; }
  /* Con el panel abierto, la barra toma fondo aunque no se haya hecho scroll:
     si no, sobre el hero la marca y el panel quedan visualmente partidos. */
  html.js .nav--abierto::before { opacity: 1; }
  html.js .nav__enlaces {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    overflow: visible;
  }
  /* Los enlaces del panel van a fila entera: un objetivo táctil de una palabra
     corta es de los fallos que solo se notan usando el móvil de verdad. */
  html.js .nav__enlace { display: block; padding-block: var(--s3); }
}

/* ==========================================================================
   Botones
   ========================================================================== */

.boton {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s4) var(--s6);
  border: 1px solid var(--ink);
  border-radius: var(--radio);
  background: var(--ink);
  color: var(--paper);
  font-size: var(--fs-pequeno);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--t-micro) var(--entra),
    color var(--t-micro) var(--entra),
    transform var(--t-micro) var(--entra);
}

.boton:hover,
.boton:focus-visible {
  background: var(--acento-texto);
  border-color: var(--acento-texto);
  transform: translateY(-2px);
}

.boton:active { transform: translateY(0); }

.boton[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
  transform: none;
}

/* La variante de contorno, para la acción secundaria de un par. */
.boton--linea {
  background: transparent;
  color: var(--ink);
}

.boton--linea:hover,
.boton--linea:focus-visible {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

/* La flecha del botón. Sale acelerando y vuelve frenando: la curva va POR
   FOTOGRAMA y no en el atajo, porque una timing-function del atajo se aplica
   a CADA tramo y haría que también la salida frenase. */
.boton__flecha {
  transition: transform var(--t-micro) var(--sale);
}
.boton:hover .boton__flecha,
.boton:focus-visible .boton__flecha {
  transform: translateX(4px);
  transition-timing-function: var(--entra);
}

/* ==========================================================================
   Formularios
   ========================================================================== */

.campo {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.campo__rotulo {
  font-size: var(--fs-pequeno);
  font-weight: 600;
}

/* La ayuda va DEBAJO del rótulo y encima del campo, no como marcador de
   posición dentro: un placeholder desaparece justo cuando se empieza a
   escribir, que es cuando hace falta. */
.campo__ayuda {
  font-size: var(--fs-etiqueta);
  color: var(--muted);
}

.campo__entrada,
.campo__area,
.campo__seleccion {
  width: 100%;
  /* Los input type=date traen un ancho mínimo intrínseco (sobre todo en iOS);
     sin esto, en la rejilla .par de entrada/salida desbordan en móvil. */
  min-width: 0;
  padding: var(--s4);
  border: 1px solid var(--line-fuerte);
  border-radius: var(--radio);
  background: var(--paper);
  color: var(--ink);
  transition:
    border-color var(--t-micro) var(--entra),
    box-shadow var(--t-micro) var(--entra);
}

.campo__area {
  min-height: 8rem;
  resize: vertical;
  line-height: 1.55;
}

.campo__entrada:focus-visible,
.campo__area:focus-visible,
.campo__seleccion:focus-visible {
  outline: none;                     /* se sustituye por el borde + halo */
  border-color: var(--acento-texto);
  box-shadow: 0 0 0 3px var(--acento-suave);
}

/* El campo con error se marca por COLOR Y por texto. Solo con color no vale:
   quien no distingue el rojo se queda sin saber cuál falla. */
.campo[data-error='si'] .campo__entrada,
.campo[data-error='si'] .campo__area {
  border-color: #9B3B2E;
}

.campo__error {
  font-size: var(--fs-etiqueta);
  font-weight: 600;
  color: #8A3327;   /* 5.9:1 sobre el crema */
}

/* La trampa para bots. Se saca de la pantalla en vez de usar display:none
   porque hay bots que ignoran los campos ocultos por CSS; así lo rellenan.
   Y lleva tabindex/autocomplete apagados para que ningún humano caiga aquí
   navegando con el tabulador. */
.trampa {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* La respuesta del envío. Es aria-live, así que el lector de pantalla la
   anuncia sin que haya que mover el foco. */
.aviso {
  padding: var(--s4) var(--s5);
  border-left: 3px solid var(--acento);
  background: var(--acento-suave);
  font-size: var(--fs-pequeno);
}

.aviso[data-tono='mal'] {
  border-left-color: #8A3327;
  background: #F6E4E0;
  color: #6E281E;
}

.aviso:empty { display: none; }   /* que no deje un hueco cuando no dice nada */

/* ==========================================================================
   Resumen — la franja de datos clave bajo la cabecera de un alojamiento
   (habitaciones, baños, superficie…). Es el formato de ficha técnica que se
   ve en los portales inmobiliarios (Idealista, Airbnb): cifras concretas en
   una sola línea, sin adjetivos. Aquí conviven con la tipografía y la foto
   editorial del resto del sitio — no sustituyen nada, resumen lo de abajo.
   ========================================================================== */

.resumen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) var(--s4);
  margin-top: var(--s5);
  font-size: var(--fs-pequeno);
  color: var(--muted);
}

.resumen__icono {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
}

.resumen__icono svg { flex-shrink: 0; }

/* ==========================================================================
   Pie
   ========================================================================== */

.pie {
  margin-top: var(--s11);
  padding-block: var(--s9) var(--s7);
  background: var(--dark);
  color: var(--on-dark);
}

.pie__reja {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--s7);
}

.pie__titulo {
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 400;
  margin-bottom: var(--s4);
}

.pie__lista {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  font-size: var(--fs-pequeno);
}

.pie__lista a {
  color: var(--on-dark-muted);
  text-decoration: none;
  transition: color var(--t-micro) var(--entra);
}

.pie__lista a:hover,
.pie__lista a:focus-visible { color: var(--on-dark); }

.pie__abajo {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s4);
  margin-top: var(--s8);
  padding-top: var(--s5);
  border-top: 1px solid rgba(244, 241, 234, 0.18);
  font-size: var(--fs-etiqueta);
  color: var(--on-dark-muted);
}

/* El crédito del estudio: un enlace apagado como el resto de la fila, que se
   enciende al pasar por encima igual que los del listado de arriba. */
.pie__creditos {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(244, 241, 234, 0.35);
  transition:
    color var(--t-micro) var(--entra),
    border-color var(--t-micro) var(--entra);
}

.pie__creditos:hover,
.pie__creditos:focus-visible {
  color: var(--on-dark);
  border-color: var(--on-dark);
}

/* ==========================================================================
   WhatsApp

   Fijo abajo a la derecha porque es la vía por la que de verdad escribe la
   gente. Es un enlace normal a wa.me: ni SDK, ni script de terceros, ni un
   solo byte que salga del dominio — así la CSP sigue cerrada y nadie manda
   la visita a Meta antes de que el visitante decida escribir.
   ========================================================================== */

.whatsapp {
  position: fixed;
  right: clamp(var(--s4), 3vw, var(--s7));
  /* Un poco más alto de lo normal: pegado al borde tapaba el final del
     footer al terminar de hacer scroll. */
  bottom: calc(clamp(var(--s4), 3vw, var(--s7)) + var(--s6));
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-size: var(--fs-pequeno);
  font-weight: 600;
  text-decoration: none;
  box-shadow: 0 6px 20px rgba(46, 53, 50, 0.22);
  transition: transform var(--t-micro) var(--entra),
              background-color var(--t-micro) var(--entra);
}

.whatsapp:hover,
.whatsapp:focus-visible {
  transform: translateY(-3px);
  background: #25d366;
}

/* En el móvil solo el icono: el rótulo se come media pantalla y tapa el
   contenido justo donde está el pulgar. */
@media (max-width: 560px) {
  .whatsapp { padding: var(--s4); }
  .whatsapp__texto { display: none; }
}

@media print {
  .whatsapp, .nav { display: none; }
}
