/* ==========================================================================
   Casa Verde Services — Hoja de estilos principal
   Autor: Desarrollo web · Fase HTML/CSS/JS (previa a Astro)
   Organización:
     1. Tokens de diseño (variables)
     2. Reset y base
     3. Utilidades / layout
     4. Componentes reutilizables (botones, píldoras, etiquetas)
     5. Header y navegación
     6. Secciones (hero, servicios, ... , footer)
     7. Formulario de cotización
     8. Botón flotante de WhatsApp
     9. Responsive
    10. Accesibilidad / motion
   ========================================================================== */

/* 1. TOKENS DE DISEÑO ------------------------------------------------------ */
:root {
  /* Colores de marca */
  --green-900: #112C20;
  --green-800: #1B4332;
  --green-700: #23583F;
  --green-600: #2C6D4F;
  --green-400: #4CAF7D;
  --green-100: #EAF5F0;
  --green-50:  #F3F9F6;

  --cream:     #FBFAF7;
  --cream-2:   #F3F1EA;
  --ink:       #22262B;
  --muted:     #4A5158;
  --muted-2:   #6B7278;
  --line:      #E6E3DA;
  --line-2:    #E0DDD2;
  --white:     #ffffff;

  /* Tipografía */
  --font-head: "Montserrat", system-ui, sans-serif;
  --font-body: "Rubik", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  /* Escala tipográfica fluida */
  --fs-hero:  clamp(2.375rem, 5.2vw, 3.75rem);
  --fs-h2:    clamp(1.8rem, 3.4vw, 2.625rem);
  --fs-h3:    clamp(1.3rem, 2.4vw, 1.5rem);
  --fs-lead:  clamp(1.05rem, 1.6vw, 1.16rem);

  /* Espaciado */
  --space-section: clamp(4rem, 8vw, 6rem);
  --container: 1240px;
  --gutter: clamp(1.125rem, 3vw, 1.5rem);

  /* Formas */
  --radius-sm: 12px;
  --radius: 20px;
  --radius-lg: 26px;
  --radius-pill: 999px;

  /* Sombras */
  --shadow-sm: 0 1px 3px rgba(27, 67, 50, .06);
  --shadow: 0 12px 34px rgba(27, 67, 50, .10);
  --shadow-lg: 0 24px 60px rgba(17, 44, 32, .16);

  /* Transiciones */
  --t-fast: .18s ease;
  --t: .28s ease;

  --header-h: 108px;
}

/* 2. RESET Y BASE ---------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* Sin `scroll-behavior: smooth`. En móvil el documento mide 20.135px (unas 27
   pantallas) y cualquier salto largo se convertía en una animación eterna que
   además impide ver dónde has aterrizado. Las anclas siguen cayendo en su sitio
   gracias al `scroll-margin-top` de más abajo. Ver qa/informe-errores.html E1. */
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--cream);
  font-family: var(--font-body);
  font-weight: 300;
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -.02em;
  color: var(--green-800);
  text-wrap: balance;
}
p { margin: 0; }

/* Evita las viudas: la última línea suelta con una o dos palabras. Estaba
   aplicado solo a la entradilla del hero, y quedaban entre 12 y 14 párrafos
   por página terminando en un jirón — la entradilla de Servicios al 16 % del
   ancho, la de Nosotros al 17 %. Ver qa/informe-errores.html B4. */
p, blockquote, li, figcaption { text-wrap: pretty; }
img { max-width: 100%; display: block; height: auto; }

a { color: var(--green-600); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--green-400); }

ul { margin: 0; padding: 0; list-style: none; }

button { font-family: inherit; }

::selection { background: var(--green-400); color: var(--green-900); }

:focus-visible {
  outline: 3px solid var(--green-400);
  outline-offset: 2px;
  border-radius: 4px;
}
/* Secciones que reciben el foco al llegar por un ancla (main.js): sin marco. */
[tabindex="-1"]:focus { outline: none; }

/* Enlace de salto para accesibilidad */
.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  background: var(--green-800);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  font-family: var(--font-head);
  font-weight: 600;
  transition: top var(--t-fast);
}
.skip-link:focus { top: 12px; color: #fff; }

/* 3. UTILIDADES / LAYOUT --------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--space-section); }

/* Compensa el header sticky al saltar a un ancla del menú */
section[id], main[id] { scroll-margin-top: calc(var(--header-h) + 14px); }

.eyebrow {
  font-family: var(--font-head);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--green-400);
  margin-bottom: .9rem;
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.62;
  color: var(--muted);
  font-weight: 300;
}

.section-head { max-width: 660px; margin-bottom: 2.75rem; }
.section-head h2 { font-size: var(--fs-h2); }
.section-head .lead { margin-top: 1.1rem; }

/* Acento en cursiva verde dentro de los títulos */
.accent {
  font-style: italic;
  font-weight: 500;
  color: var(--green-600);
}
.on-dark .accent, .accent--light { color: var(--green-400); }

.grid { --grid-gap: 1.125rem; display: grid; gap: var(--grid-gap); }
.auto-fit { grid-template-columns: repeat(auto-fit, minmax(min(100%, 270px), 1fr)); }
.auto-fit--sm { grid-template-columns: repeat(auto-fit, minmax(min(100%, 215px), 1fr)); }

/* Repartos exactos, sin tarjeta huérfana ------------------------------------
   `auto-fit` reparte por espacio disponible, no por número de tarjetas: con 3
   tarjetas en 2 columnas dejaba un hueco vacío al final de la fila, y con 4 en
   3 columnas lo mismo. A 768px eso pasaba en cuatro secciones seguidas.
   Aquí el número de columnas siempre divide al de tarjetas. Ver C1. */
.grid--3 { grid-template-columns: 1fr; }
@media (min-width: 620px) {
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  /* Tramo de 2 columnas: la tercera no se estira a lo ancho ni se queda
     colgada a la izquierda — mide lo mismo que sus dos hermanas y va centrada.
     Ocupa las dos columnas para poder centrarse dentro de ellas, y recupera el
     ancho de una sola descontando media separación. */
  .grid--3 > :last-child {
    grid-column: 1 / -1;
    width: calc(50% - var(--grid-gap) / 2);
    justify-self: center;
  }
}
@media (min-width: 880px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--3 > :last-child { grid-column: auto; width: auto; justify-self: stretch; }
}

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

/* Nunca más de dos columnas. Para bloques de texto largo: a cuatro columnas
   los testimonios quedaban en tiras de 233px, siete líneas de unos 23
   caracteres — medida de columna de periódico dentro de una tarjeta. A dos
   columnas son 536px y 54 caracteres, dentro de la horquilla cómoda de
   lectura (45–75). Ver qa/informe-errores.html B1. */
.grid--2 { grid-template-columns: 1fr; }
@media (min-width: 620px) { .grid--2 { grid-template-columns: repeat(2, 1fr); } }

/* Utilidades de espaciado y variantes puntuales */
.eyebrow--green { color: var(--green-600); }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.6rem; }
.mt-4 { margin-top: 1.75rem; }
.self-start { align-self: flex-start; }

/* 4. COMPONENTES ----------------------------------------------------------- */
.btn {
  --btn-bg: var(--green-800);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  padding: 1.05rem 1.75rem;
  border: 1.5px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
.btn:hover { background: var(--green-600); color: #fff; transform: translateY(-2px); box-shadow: var(--shadow); }
.btn:active { transform: translateY(0) scale(.99); box-shadow: none; }
.btn:focus-visible { outline: 3px solid var(--green-400); outline-offset: 3px; }

.btn--sm { padding: .8rem 1.35rem; font-size: .9rem; }

.btn--ghost {
  --btn-bg: #fff;
  --btn-fg: var(--green-800);
  border-color: var(--line-2);
}
.btn--ghost:hover { background: #fff; color: var(--green-800); border-color: var(--green-400); }

/* Texto en BLANCO por pedido de Diego (14-10-2026), revirtiendo P-19.
   Ojo: blanco sobre #4CAF7D da 2,71:1 (AA pide 4,5:1 en texto normal).
   Si hay que volver a cumplir AA sin perder el blanco: --btn-bg: var(--green-600). */
.btn--accent {
  --btn-bg: var(--green-400);
  --btn-fg: #fff;
}
.btn--accent:hover { background: #fff; color: var(--green-800); }

.btn--on-dark.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: #fff;
  border-color: rgba(255,255,255,.28);
}
.btn--on-dark.btn--ghost:hover { background: rgba(255,255,255,.08); color: #fff; border-color: var(--green-400); }

.btn--block { width: 100%; }

/* Enlace de texto con subrayado de acento */
.link-underline {
  display: inline-block;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .95rem;
  color: var(--green-800);
  border-bottom: 2px solid var(--green-400);
  padding-bottom: 4px;
}
.link-underline:hover { color: var(--green-400); }
.on-dark .link-underline { color: #fff; }
button.link-underline { background: none; cursor: pointer; border: 0; border-bottom: 2px solid var(--green-400); margin-top: .5rem; }

.link-arrow {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .92rem;
  color: var(--green-600);
}
.link-arrow:hover { color: var(--green-400); }

/* Flecha animable dentro de enlaces */
.arw { display: inline-block; margin-left: .25em; transition: transform var(--t-fast); }
.link-arrow:hover .arw,
.link-underline:hover .arw { transform: translateX(5px); }

.pill {
  display: inline-block;
  font-size: .84rem;
  font-weight: 300;
  color: var(--green-600);
  background: var(--green-100);
  padding: .5rem .9rem;
  border-radius: var(--radius-pill);
}

/* Marcador de posición de imagen (fallback si una foto no carga) */
.ph {
  background-color: #EDEAE1;
  background-image: repeating-linear-gradient(135deg, #E2DED2 0 8px, #EDEAE1 8px 16px);
}

/* Marco de imagen reutilizable */
.frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--cream-2);
}
.frame img { width: 100%; height: 100%; object-fit: cover; transition: transform .45s ease; }
/* <picture> (WebP + JPG) dentro de .frame: que no rompa el 100% de alto del img. */
.frame picture { display: block; width: 100%; height: 100%; }

/* Zoom sutil de la imagen al hacer hover en tarjetas con foto */
.card:hover .frame img,
.service-card:hover .frame img,
.biz-card:hover .frame img,

/* Cursor de "ampliable" en imágenes con lightbox */
[data-lightbox] { cursor: zoom-in; }

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  transition: border-color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast);
}
.card:hover { border-color: var(--green-400); transform: translateY(-3px); box-shadow: var(--shadow); }

/* 5. HEADER Y NAVEGACIÓN --------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(251, 250, 247, .9);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow var(--t), background var(--t);
}
/* Al hacer scroll el header solo gana sombra y opacidad: NO cambia de tamaño.
   Antes encogía el relleno a .5rem y el logo de 76 a 60px, así que la barra
   se movía bajo el cursor mientras se navegaba. */
.site-header.is-scrolled { box-shadow: 0 6px 24px rgba(17, 44, 32, .09); background: rgba(251, 250, 247, .96); }
.header-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding-block: .9rem;
  transition: padding var(--t);
}
.brand { display: flex; align-items: center; flex-shrink: 0; }
.brand img { height: 76px; width: auto; transition: height var(--t); }

.nav {
  display: flex;
  align-items: center;
  gap: 1.4rem;
  margin-left: auto;
  font-size: .93rem;
  font-weight: 400;
}
.nav a { color: #3A4046; position: relative; }
.nav a:hover { color: var(--green-600); }
.nav a.is-active { color: var(--green-800); }
/* Subrayado animado (solo escritorio, donde el menú es horizontal).
   El corte va a 1160px, no a 901: el header horizontal pide 1129px de contenido
   (logo 257 + nav 524 + acciones 323 + separaciones). El .98 evita el hueco de
   subpixel: a 1159px exactos el viewport real es 1159,xx y no casaba ninguna
   de las dos. Ver qa/informe-errores.html A1. */
@media (min-width: 1160px) {
  .nav a::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -6px;
    height: 2px;
    background: var(--green-400);
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--t-fast);
  }
  .nav a:hover::after,
  .nav a.is-active::after { transform: scaleX(1); }
}

.header-actions { display: flex; align-items: center; gap: .6rem; flex-shrink: 0; }
/* Relleno con el verde acento de marca (#4CAF7D). Antes era un pill de borde
   beige sobre cabecera crema: no se leia como boton. El acento va de fondo y
   no de texto, porque sobre el crema se queda en 2,3:1. El borde repite el
   color del fondo para conservar la caja de 1,5px y no descuadrar el CTA que
   va al lado.
   OJO: el rotulo va en blanco por peticion del cliente. Sobre #4CAF7D se
   queda en 2,55:1 y el minimo de AA para este cuerpo (14px / 600) es 4,5:1.
   Si hay que corregirlo, la salida es bajar el fondo a --green-600, que deja
   el blanco en 7,7:1 sin tocar el rotulo. */
.header-phone {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: .88rem;
  background: var(--green-400);
  /* Rotulo en BLANCO por pedido de Diego (14-10-2026), igual que .btn--accent.
     Revierte P-19: blanco sobre menta da 2,71:1 (AA pide 4,5:1). Si hay que
     volver a cumplir AA: color: var(--green-900) (5,51:1). */
  color: #fff;
  padding: .7rem 1rem;
  border: 1.5px solid var(--green-400);
  border-radius: var(--radius-pill);
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
/* Al pasar por encima baja al verde medio, el mismo salto que hace .btn. Ahi el
   rotulo si vuelve al blanco: sobre el verde 600 da 6,16:1. */
.header-phone:hover { background: var(--green-600); border-color: var(--green-600); color: #fff; }

/* Botón hamburguesa (oculto en escritorio) */
.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1.5px solid var(--line-2);
  border-radius: 12px;
  cursor: pointer;
  margin-left: auto;
}
.nav-toggle span {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--green-800);
  border-radius: 2px;
  transition: transform var(--t-fast), opacity var(--t-fast);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* 6. SECCIONES ------------------------------------------------------------- */

/* Hero */
/* Servicios */
.services-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 2.5rem; flex-wrap: wrap; margin-bottom: 2.9rem;
}
.services-head > div { max-width: 640px; }

/* Grid de servicios: 3 columnas fijas para que no queden huecos.
   (Con auto-fit, la tarjeta ancha 1/-1 "ocupaba" una 4ª columna y dejaba un vacío.) */
/* Dos columnas, no tres. Hay 4 tarjetas con foto y 2 sin ella: en filas de 3
   la fila 2 mezclaba jardinería (con foto) con las dos de solo texto, que se
   estiraban hasta su altura y quedaban con 304px de vacío debajo. En filas de
   2 cada fila es homogénea — foto, foto, texto — y el CTA cierra a lo ancho. */
.services .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 760.98px) { .services .grid { grid-template-columns: 1fr; } }
.service-card { overflow: hidden; display: flex; flex-direction: column; }
.service-card .frame { border-radius: 0; aspect-ratio: 1.5; }
/* A dos columnas la tarjeta mide el doble de ancho, y con el recorte 1.5 la
   foto se iba a 390px de alto. Con 2.0 la tarjeta vuelve a la altura que tenía
   a tres columnas (479px frente a 492) sin que la sección se dispare. */
.services .service-card .frame { aspect-ratio: 2; }
.service-card .body { padding: 1.6rem 1.5rem 1.75rem; display: flex; flex-direction: column; flex: 1; }
.service-card h3 { font-size: 1.44rem; }
.service-card p { margin-top: .75rem; font-size: .97rem; color: var(--muted); flex: 1; }
.service-card .link-arrow { margin-top: 1.25rem; }

/* La tarjeta de jardinería era `.service-wide` y ocupaba la fila entera. Ahora
   es una tarjeta normal, así que quedan 6 tarjetas + el CTA: en 3 columnas eso
   daría 3-3-1 y una última fila con dos huecos. El CTA pasa a ocupar la fila
   completa, que además le sienta mejor como cierre de sección. */
.service-cta { grid-column: 1 / -1; }

/* A fila completa se lee mejor en horizontal: el texto a la izquierda y el
   botón a la derecha. En estrecho vuelve a apilarse. */
.service-cta {
  background: var(--green-800); border-color: var(--green-800);
  padding: 1.9rem 1.75rem;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 1.25rem 2rem;
}
.service-cta > div { max-width: 44rem; }
.service-cta .btn { flex: 0 0 auto; }

/* RETIRADO (P-19). Aqui vivia `--btn-fg: #fff` para los `btn--accent`, puesto
   en su dia por decision de diseno del cliente y con el incumplimiento ya
   anotado: 2,55:1 con la paleta vieja, 2,71:1 con la de G4, contra el 4,5:1
   que pide AA. Al quitarlo, el boton recupera su valor por defecto
   (`--btn-fg: var(--green-900)`), que sobre el verde menta da 5,51:1 medidos.
   No hay regla nueva: la correccion es borrar la excepcion.
   PENDIENTE: reconfirmar con el cliente, porque el blanco lo pidio el.
   El hover no se toca: `.btn--accent:hover` fija verde oscuro sobre blanco. */
.service-cta h3 { color: #fff; }
.service-cta p { color: #B9CFC3; }
.service-cta:hover { transform: translateY(-3px); }

/* Empresas */
.business { background: var(--cream-2); border-block: 1px solid var(--line); }
.biz-card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; transition: border-color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast); }
.biz-card .frame { border-radius: 0; aspect-ratio: 1.7; }
.biz-body { padding: 1.6rem 1.6rem 1.75rem; display: flex; flex-direction: column; gap: .75rem; flex: 1; }
.biz-card:hover { border-color: var(--green-400); transform: translateY(-3px); box-shadow: var(--shadow); }
.biz-card:hover .biz-num { background: var(--green-400); color: var(--green-900); }
.biz-num { transition: background var(--t-fast), color var(--t-fast); }
.biz-num {
  width: 36px; height: 36px; border-radius: 10px; background: var(--green-100);
  display: flex; align-items: center; justify-content: center;
  color: var(--green-600); font-family: var(--font-head); font-weight: 700; font-size: .88rem;
}
.biz-card h3 { font-size: 1.32rem; }
.biz-card p { font-size: .97rem; color: var(--muted); flex: 1; }

/* Compromiso (oscuro) */
.commitment { background: var(--green-800); color: #fff; }
.commitment h2, .commitment h3 { color: #fff; }
.commitment .glass {
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: var(--radius);
  padding: 1.6rem 1.5rem;
}
.commitment .glass h3 { font-size: 1.18rem; line-height: 1.3; }
.commitment .glass p { margin-top: .75rem; font-size: .94rem; color: #B9CFC3; }
.commitment .split { margin-top: 1rem; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 1rem; }
.commitment .frame { min-height: 300px; background: var(--green-700); }
.commitment .promo {
  border-radius: var(--radius); background: var(--white); padding: clamp(1.75rem, 3vw, 2.25rem);
  display: flex; flex-direction: column; justify-content: center; color: var(--green-900);
}
.commitment .promo h3 { color: var(--green-900); font-size: 1.5rem; line-height: 1.2; }
.promo-list { list-style: none; margin: 1.4rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 1rem; }
.promo-list li { display: flex; flex-direction: column; gap: .15rem; }
.promo-list strong { font-family: var(--font-head); font-weight: 700; font-size: 1.02rem; color: var(--green-900); }
.promo-list span { font-size: .92rem; line-height: 1.5; color: #0F3323; }

/* Nosotros */
.about-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.about-media { margin-top: 2rem; aspect-ratio: 1.3; }
.about-list { display: flex; flex-direction: column; }
.about-item {
  padding: 1.5rem 0;
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: auto 1fr; gap: 1.15rem;
}
.about-item:last-child { border-bottom: 1px solid var(--line); }
.about-item .n { font-family: var(--font-head); font-weight: 700; font-size: .82rem; color: var(--green-400); padding-top: 4px; }
.about-item h3 { font-size: 1.18rem; }
.about-item p { margin-top: .5rem; font-size: .97rem; color: var(--muted); }

/* Antes y después */
/* El texto va encima y la galeria se queda con todo el ancho.
   Antes eran dos columnas al 50%, y como la galeria se parte a su vez en dos,
   cada comparador acababa en 258px a 1440 y en 213px a 1024 — mas pequeno a
   1024 que a 768, porque justo ahi la rejilla exterior pasaba a dos columnas.
   Es la prueba visual del negocio: ahora crece con la pantalla en vez de
   encoger. Ver qa/informe-errores.html B2. */
.ba-wrap {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: clamp(1.75rem, 3vw, 2.75rem);
  display: grid; grid-template-columns: 1fr;
  gap: clamp(1.75rem, 3vw, 2.75rem);
}
/* El bloque de texto no se estira a todo el ancho: se le deja medida de lectura. */
.ba-wrap > div:first-child { max-width: 46rem; }
/* Dos columnas solo cuando cada comparador puede medir 340px o mas. Con
   `1fr 1fr` fijo, al pasar de 560px el comparador caia de 467 a 265px de golpe:
   partir en dos siempre reduce a la mitad, asi que el corte tiene que decidirlo
   el espacio disponible, no un ancho de pantalla escrito a mano. */
.ba-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: .9rem;
}
.ba-gallery figure { margin: 0; }
.ba-gallery .frame { aspect-ratio: 1.25; border-radius: 18px; }
.ba-tag {
  position: absolute; top: 12px; left: 12px;
  font-family: var(--font-head); font-weight: 700; font-size: .72rem; letter-spacing: .1em;
  padding: .38rem .75rem; border-radius: var(--radius-pill);
}
.ba-tag.antes { color: var(--green-800); background: #fff; }
.ba-tag.despues { color: #fff; background: var(--green-800); }

/* Testimonios */
.testimonials { background: var(--cream-2); border-block: 1px solid var(--line); }

/* Carrusel de reseñas -------------------------------------------------------
   Se apoya en el scroll nativo con anclaje, no en transformaciones por JS: así
   funciona con el dedo, con la rueda, con las flechas del teclado y sin JS.
   Los botones solo empujan ese mismo scroll. */
/* A todo el ancho del contenedor. Lo que estrecha las tarjetas ya no es un
   tope de ancho sino el número que se muestra: con tres visibles cada una cae
   en unos 346px a 1440px. */
.carrusel { position: relative; }

.carrusel-pista {
  display: flex;
  gap: var(--grid-gap, 1.125rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* El recorrido es corto (4 tarjetas), aquí el suave sí ayuda a ver que se
     ha movido. No tiene nada que ver con el scroll largo de la página. */
  scroll-padding-inline: 0;
  padding-bottom: .25rem;   /* aire para el anillo de foco */
  scrollbar-width: none;
}
.carrusel-pista::-webkit-scrollbar { display: none; }
.carrusel-pista:focus-visible { outline: 3px solid var(--green-400); outline-offset: 4px; border-radius: var(--radius); }

/* Tres por pantalla en escritorio. Bajan a dos y luego a una conforme el ancho
   no da: el criterio es que la tarjeta no se quede estrecha para leer, no un
   número fijo. A 800px tres darían 200px por tarjeta y 149 de texto. */
.carrusel-pista > .quote-card {
  flex: 0 0 calc((100% - var(--grid-gap, 1.125rem) * 2) / 3);
  scroll-snap-align: start;
  min-height: 21rem;
}
@media (max-width: 1099.98px) {
  .carrusel-pista > .quote-card { flex-basis: calc((100% - var(--grid-gap, 1.125rem)) / 2); }
}
@media (max-width: 799.98px) {
  /* Una por pantalla hasta que dos quepan con holgura: a 620px cada una se
     quedaba en 224px de ancho con 173 de texto. */
  .carrusel-pista > .quote-card { flex-basis: 100%; min-height: 19rem; }
}

/* Los mandos no ocupan sitio: sus dos botones van en absoluto, así que el
   contenedor se queda a cero de alto y no empuja nada. */
.carrusel-mandos { position: static; }

.carrusel-btn {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 52px; height: 52px; border-radius: 50%;
  background: #fff; border: 1px solid var(--line-2); color: var(--green-800);
  line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
/* Antes eran los caracteres ‹ ›, que se veian finos y de tamano irregular segun la
   fuente cargada. Ahora es un trazo real, del mismo grosor y con las mismas
   puntas redondeadas que la flecha del hero. Aqui va solo la cabeza: en un
   boton circular el asta no cabe sin achicar la punta. */
.carrusel-btn svg { width: 36px; height: 36px; }
.carrusel-btn[data-car="prev"] { left: 0; }
.carrusel-btn[data-car="next"] { right: 0; }
.carrusel-btn:hover { background: var(--green-800); border-color: var(--green-800); color: #fff; }

/* Desde 800px la pista se aparta de los botones, así que ninguno pisa el texto.
   Cuesta 58px por lado de ancho de tarjeta, asumible cuando hay dos visibles. */
@media (min-width: 800px) {
  .carrusel { padding-inline: 64px; }
}

@media (max-width: 799.98px) {
  /* En móvil apartar la pista costaría un tercio del ancho de lectura (273px
     caían a 181). Los botones se quedan encima y es la tarjeta la que abre
     margen interior para que el texto no quede debajo: cuesta 41px en vez de
     92 y las citas siguen respirando. */
  .carrusel-btn { width: 40px; height: 40px; }
  .carrusel-btn svg { width: 28px; height: 28px; }
  .carrusel-btn[data-car="prev"] { left: 4px; }
  .carrusel-btn[data-car="next"] { right: 4px; }
  .carrusel-pista > .quote-card { padding-inline: 3.125rem; }
}
.quote-card { background: #fff; border-radius: var(--radius); padding: 1.75rem 1.6rem; display: flex; flex-direction: column; gap: 1.1rem; margin: 0; }
.stars { color: var(--green-400); font-size: .95rem; letter-spacing: 2px; }
.quote-card blockquote { margin: 0; font-size: 1rem; line-height: 1.62; color: #3A4046; flex: 1; }
.quote-card figcaption { display: flex; align-items: center; gap: .75rem; border-top: 1px solid #EFEDE6; padding-top: 1rem; }
.quote-card .who { width: 38px; height: 38px; border-radius: 50%; background: #DFEAE4; flex-shrink: 0; }
.quote-card figcaption strong { font-family: var(--font-head); font-size: .95rem; color: var(--green-800); display: block; }
.quote-card figcaption small { font-size: .82rem; color: var(--muted-2); }

/* Cómo funciona */
.step-card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.9rem 1.75rem; }
/* El numero va en el verde de acento a plena opacidad. Antes era `--green-100`
   (#EAF5F0), casi blanco: sobre la tarjeta blanca no se distinguia. Ese tono
   pasa ahora al estado destacado, donde el fondo verde oscuro si lo sostiene. */
.step-card .num { font-family: var(--font-head); font-weight: 800; font-size: 2.4rem; color: var(--green-400); line-height: 1; }
.step-card h3 { margin-top: .9rem; font-size: 1.32rem; }
.step-card p { margin-top: .65rem; font-size: .97rem; color: var(--muted); }
/* El verde oscuro ya no lo lleva fijo el paso 03: es el estado de hover de
   cualquiera de los tres. En reposo los tres se ven como el paso 01.
   Las reglas de hover viven en la sección 12, después del bloque de reveal:
   aquel redefine `transition` por completo con la misma especificidad, así que
   puestas aquí se perdería la transición de color. */

/* Zonas (oscuro) */
.zones { background: var(--green-800); color: #fff; }
.zones h2 { color: #fff; }
.zones .lead { color: #B9CFC3; }
/* RETIRADO (P-19). Aqui iba `--btn-fg: #fff` con esta justificacion: "el verde
   900 por defecto sobre el verde 400 del boton se queda corto de contraste".
   Medido, es al reves: verde 900 sobre verde menta da 5,51:1 y el blanco 2,71:1.
   El boton vuelve a su valor por defecto, que es el que cumple AA. */
.zones-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 330px), 1fr)); gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.zone-list { display: flex; flex-wrap: wrap; gap: .6rem; align-content: flex-start; }
.zone-chip {
  font-family: var(--font-head); font-weight: 500; font-size: .9rem; color: #fff;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  padding: .7rem 1.1rem; border-radius: var(--radius-pill);
}
.zone-chip:hover { background: var(--green-400); color: var(--green-900); border-color: var(--green-400); }

/* Teléfono dentro de un párrafo (G3: que "call us" marque desde el celular).
   Hereda el color del texto que lo rodea para funcionar igual sobre crema y
   sobre verde oscuro; lo que lo distingue es el subrayado, no un color nuevo. */
.tel-inline {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: .18em;
  text-decoration-thickness: 1px;
  font-weight: 500;
}
.tel-inline:hover { text-decoration-thickness: 2px; }

/* Subtítulo "And nearby" dentro de la lista de pueblos. Ocupa una fila entera
   (flex-basis 100%) para cortar la banda de chips en dos grupos: los del
   condado primero, los de fuera después. */
.zone-sub {
  flex: 0 0 100%;
  margin: .9rem 0 0;
  font-family: var(--font-mono, var(--font-head));
  font-size: .78rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,.62);
}

/* FAQ */
.faq-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.faq-item { border-top: 1px solid var(--line); }
.faq-item:last-of-type { border-bottom: 1px solid var(--line); }
.faq-q {
  width: 100%; background: none; border: 0; padding: 1.4rem 0; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 1.25rem;
  text-align: left; font-family: var(--font-head); font-weight: 600; font-size: 1.16rem; color: var(--green-800);
}
.faq-q:hover { color: var(--green-600); }
.faq-icon {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 50%;
  background: var(--green-100); color: var(--green-600);
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem;
  transition: transform var(--t), background var(--t-fast);
}
.faq-q[aria-expanded="true"] .faq-icon { transform: rotate(45deg); }
/* `grid-template-rows: 0fr` deja el panel a cero de alto, pero NO lo saca del
   árbol de accesibilidad: el texto seguía existiendo y un lector de pantalla
   leía las seis respuestas siempre, aunque `aria-expanded` dijera "false".
   Con `visibility: hidden` desaparece de verdad (y de la tabulación).
   El retardo de la transición es lo que evita que el texto se esfume de golpe
   mientras el panel aún se está cerrando. Ver qa/informe-errores.html E2. */
.faq-a {
  overflow: hidden;
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows var(--t), visibility 0s linear var(--t);
}
.faq-q[aria-expanded="true"] + .faq-a {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows var(--t), visibility 0s;
}
.faq-a > div { min-height: 0; }
.faq-a p { font-size: 1rem; line-height: 1.65; color: var(--muted); max-width: 640px; padding-bottom: 1.5rem; }



/* 7. FORMULARIO DE COTIZACIÓN --------------------------------------------- */
.quote-panel {
  background: var(--green-800); border-radius: 28px;
  padding: clamp(1.75rem, 4vw, 3.5rem);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: clamp(2rem, 4vw, 3.25rem); align-items: start;
}
/* Al 50% el formulario se quedaba en 365px a 1024 y 442px a 1440: demasiado
   estrecho para poner los campos en dos columnas, que es lo que evita que el
   paso 4 sea el doble de alto que los demás. El texto de al lado necesita menos
   sitio que el formulario. Ver qa/informe-errores.html D1. */
@media (max-width: 999.98px) {
  /* Entre 900 y 1000 el reparto en dos daba 372px al formulario: ni columna
     doble de campos ni campos cómodos. Mejor apilado y a todo el ancho. */
  .quote-panel { grid-template-columns: 1fr; }
}
@media (min-width: 1000px) {
  .quote-panel { grid-template-columns: minmax(280px, .85fr) minmax(0, 1.15fr); }
}
/* Sin `sticky` por defecto. El pegado solo tiene sentido cuando el texto y el
   formulario van lado a lado: apilados, el bloque viajaba hacia abajo con el
   scroll y se montaba encima del formulario — medido, hasta 336px de solape
   entre 561 y 999px. Se activa mas abajo, en el media query de escritorio. */
.quote-intro { position: static; }
.quote-intro h2 { color: #fff; font-size: var(--fs-h2); }
.quote-intro .lead { color: #B9CFC3; margin-top: 1.25rem; max-width: 460px; }

/* El pegado solo en dos columnas: ahi el texto acompaña mientras se rellena el
   formulario y no tiene sobre que montarse, porque cada uno va en su columna.
   Tiene que ir DESPUES de la regla base de arriba: misma especificidad, gana
   la ultima. Puesta junto al `grid-template-columns` de mas arriba no aplicaba. */
@media (min-width: 1000px) {
  .quote-intro { position: sticky; top: calc(var(--header-h) + 20px); }
}
.quote-phone {
  display: inline-flex; align-items: center; gap: .75rem; margin-top: 1.75rem;
  font-family: var(--font-head); font-weight: 700; font-size: 1.35rem; color: #fff;
  border-bottom: 2px solid var(--green-400); padding-bottom: 6px;
}
.quote-phone:hover { color: var(--green-400); }
.quote-meta { margin-top: 2.1rem; display: flex; flex-direction: column; gap: 1rem; }
.quote-meta .k { font-family: var(--font-mono); font-size: .7rem; color: var(--green-400); letter-spacing: .08em; }
.quote-meta .v { margin-top: .35rem; font-size: 1rem; line-height: 1.55; color: #fff; }
.quote-meta .v a { color: #fff; }
.quote-meta .v a:hover { color: var(--green-400); }

/* Con el panel apilado, zona/horario/correo van en fila y no en lista: en
   columna sumaban 177px de alto que empujaban el formulario hacia abajo.
   Solo por debajo de 1000px — en escritorio el bloque vive en una columna
   estrecha y repartirlo en tres dejaria celdas de 130px con "ZONA" partida en
   tres lineas. Va despues de la regla base a proposito: tienen la misma
   especificidad, asi que puesto dentro del media query de mas arriba perdia. */
@media (max-width: 999.98px) {
  .quote-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 120px), 1fr));
    gap: 1rem 1.5rem;
  }
  /* El correo es una cadena sin espacios: sin esto se sale de su celda. */
  .quote-meta .v { overflow-wrap: anywhere; }
}

.quote-form-wrap { background: var(--cream); border-radius: 22px; padding: clamp(1.75rem, 3vw, 2.25rem); }


/* Reset de fieldset (evita borde y el bug de min-inline-size) */
.quote-form fieldset { border: 0; margin: 0; padding: 0; min-inline-size: 0; }
.quote-form legend { padding: 0; }



.field { display: flex; flex-direction: column; gap: .4rem; }
.field label { font-family: var(--font-head); font-weight: 600; font-size: .82rem; color: var(--green-800); }
.field input,
.field select,
.field textarea {
  width: 100%; font-family: var(--font-body); font-size: .95rem; font-weight: 300; color: var(--ink);
  background: #fff; border: 1.5px solid var(--line-2); border-radius: var(--radius-sm);
  padding: .85rem 1rem; outline: none; transition: border-color var(--t-fast);
}
.field textarea { resize: vertical; min-height: 5.5rem; line-height: 1.55; }
/* La flecha nativa del select no se puede dar estilo, asi que la dibujo aqui
   y dejo sitio a la derecha para que no pise el texto de la opcion larga. */
.field select {
  appearance: none; padding-right: 2.4rem; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231B4332' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9.5 12 15.5 18 9.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .9rem center; background-size: 1.05rem;
}
.field input:focus,
.field select:focus,
.field textarea:focus { border-color: var(--green-400); }
.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] { border-color: #C0392B; }
.field .error { font-size: .8rem; color: #C0392B; min-height: 1em; }
/* Los cuatro campos en dos columnas cuando hay sitio. Apilados hacían el paso 4
   casi el doble de alto que los otros tres, y el panel pegaba un salto de 355px
   al pasar del paso 3 al 4. Ver qa/informe-errores.html D1. */
.fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 1rem;
  margin-top: 1.25rem;
}

/* `flex-wrap` y una base explícita porque los botones no pueden encogerse por
   debajo de su texto (`min-width: auto` de los ítems flex). En un móvil de
   360px "Atrás" y "Continuar" pedían 293px en una fila de 212: se salían 120px
   de la pantalla a partir del paso 2. Ahora, cuando no caben al lado, el
   segundo baja a su propia línea. */
.step-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.6rem; }
.step-actions .btn { flex: 1 1 9rem; min-width: 0; }

.form-note { margin-top: .9rem; font-size: .8rem; line-height: 1.5; color: #8A8F86; }

/* Estado enviado */
.quote-success { display: none; flex-direction: column; align-items: flex-start; gap: 1rem; padding: 1.25rem 0; }
.quote-success .check {
  width: 52px; height: 52px; border-radius: 50%; background: var(--green-100); color: var(--green-600);
  display: flex; align-items: center; justify-content: center; font-size: 1.5rem;
}
.quote-success h3 { font-size: 1.6rem; }
.quote-fallback,
.quote-error { display: none; flex-direction: column; align-items: flex-start; gap: 1rem; padding: 1.25rem 0; }
.quote-fallback h3,
.quote-error h3 { font-size: 1.6rem; }

.quote-form-wrap.is-sent .quote-form,
.quote-form-wrap.is-fallback .quote-form,
.quote-form-wrap.is-error .quote-form { display: none; }

.quote-form-wrap.is-sent .quote-success { display: flex; }
.quote-form-wrap.is-fallback .quote-fallback { display: flex; }
.quote-form-wrap.is-error .quote-error { display: flex; }

/* Modo multipaso: solo activo cuando JS está disponible */
.quote-form[data-js="on"] .step:not(.is-active) { display: none; }

/* 8. BOTÓN FLOTANTE DE WHATSAPP ------------------------------------------- */
.wa-float {
  position: fixed; right: 20px; bottom: 20px; z-index: 70;
  display: inline-flex; align-items: center; gap: .5rem;
  background: #25D366; color: #fff; font-family: var(--font-head); font-weight: 700; font-size: .9rem;
  padding: .85rem 1.15rem; border-radius: var(--radius-pill);
  box-shadow: var(--shadow-lg);
  transition: transform var(--t-fast);
}
.wa-float:hover { transform: translateY(-2px) scale(1.02); color: #fff; }

/* Barra fija de llamada (punto 12 del documento de cambios).
   Nace oculta y la enciende el breakpoint de 1160px, mas abajo: es el ancho al
   que el telefono sale del encabezado. Por encima no hace falta, porque ahi el
   numero ya vive fijo arriba y la barra seria repetirlo. */
.call-bar { display: none; }
.wa-float svg { width: 20px; height: 20px; }
.wa-float .label { white-space: nowrap; }

/* 9. FOOTER ---------------------------------------------------------------- */
.site-footer { background: var(--green-900); color: #fff; }
.footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); gap: 2.5rem; padding-top: 4.5rem; }
/* El logotipo sustituye al "CASA VERDE / SERVICES" que antes iba en texto.
   Es la versión en blanco, que es la que corresponde sobre el verde del pie.
   `width` manda y el alto sale solo del `aspect-ratio` del archivo (3,39:1),
   así que no hay salto de maqueta mientras carga. */
.footer-brand .footer-logo {
  width: 100%;
  max-width: 232px;
  height: auto;
}
.footer-brand p { margin-top: 1.25rem; font-size: .95rem; color: #9FB6A9; max-width: 280px; }
.socials { display: flex; gap: .6rem; margin-top: 1.4rem; }
.socials a {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.18);
  display: flex; align-items: center; justify-content: center;
  font-size: .8rem; color: #fff; font-family: var(--font-head); font-weight: 600;
}
.socials a:hover { background: var(--green-400); color: var(--green-900); border-color: var(--green-400); }
.footer-col h4 { font-family: var(--font-head); font-weight: 700; font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; color: var(--green-400); margin-bottom: .9rem; }
.footer-col a, .footer-col .addr { font-size: .95rem; color: #D6E2DA; font-weight: 300; display: block; padding-block: .35rem; }
.footer-col a:hover { color: var(--green-400); }
.footer-col .addr { color: #9FB6A9; line-height: 1.55; }
.footer-bottom {
  margin-top: 3.5rem; padding: 1.5rem 0 2rem; border-top: 1px solid rgba(255,255,255,.12);
  display: flex; justify-content: space-between; gap: 1.25rem; flex-wrap: wrap;
  font-size: .84rem; color: #7F998A;
}
.footer-bottom nav { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.footer-bottom a { color: #7F998A; }
.footer-bottom a:hover { color: var(--green-400); }

/* 10. RESPONSIVE ----------------------------------------------------------- */

/* Hasta 1159px manda la hamburguesa. Antes el corte estaba en 900px y dejaba
   una banda muerta de 901 a 1159 en la que el header horizontal no cabia y
   tampoco habia hamburguesa: el boton "Pedir cotizacion" quedaba fuera de la
   pantalla (hasta 229px fuera a 901px).
   El .98 no es capricho: con `max-width: 1159px` a secas quedaba un hueco de
   subpixel en 1159 exactos (el viewport real es 1159,xx), donde no casaba ni
   esta regla ni el `min-width: 1160px` de arriba, y volvia el header ancho.
   Ver qa/informe-errores.html A1. */
@media (max-width: 1159.98px) {
  /* El header mide 87px aquí (y 75 por debajo de 560), no los 108 del tramo
     ancho. De este valor cuelgan el `scroll-margin-top` de las anclas y el
     `top` del panel pegajoso de la cotización. */
  :root { --header-h: 92px; }
  .nav-toggle { display: flex; margin-left: 0; }
  .header-inner { gap: .6rem; flex-wrap: nowrap; }
  .brand { margin-right: auto; }
  .brand img { height: 58px; }
  .header-actions .btn { padding: .68rem 1rem; font-size: .82rem; white-space: nowrap; }
  .nav {
    /* Anclado al propio header (que es sticky, asi que hace de contenedor):
       antes iba a `top: var(--header-h)`, un valor fijo que dejaba de cuadrar
       en cuanto el header cambiaba de alto. Ahora sigue su borde inferior. */
    position: absolute; top: 100%; left: 0; right: 0;
    max-height: 72vh; overflow-y: auto; overscroll-behavior: contain;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--cream); border-bottom: 1px solid var(--line);
    padding: .5rem var(--gutter) 1.25rem;
    margin: 0;
    box-shadow: var(--shadow);
    transform: translateY(-8px);
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
  }
  .nav.is-open { opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0); }
  .nav a { padding: .85rem .25rem; border-bottom: 1px solid var(--line); font-size: 1rem; }
  /* El telefono sale del encabezado a este ancho, asi que la barra fija de
     llamada entra AQUI y no mas abajo: el punto 12 pide que el numero este
     siempre a la vista, y entre 561px y 1159px no lo estaba en ningun sitio.
     Cubre desde 1159px hasta el movil, que es la misma banda en la que el
     menu ya es hamburguesa. */
  .call-bar {
    position: fixed; inset: auto 0 0 0; z-index: 75;
    display: flex; align-items: center; justify-content: center; gap: .6rem;
    background: var(--green-800); color: #fff;
    font-family: var(--font-head); font-weight: 700; font-size: 1rem;
    /* El padding de abajo respeta la franja del gesto de inicio en iPhone. */
    padding: .95rem 1rem calc(.95rem + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -6px 24px rgba(17, 44, 32, .22);
  }
  .call-bar:hover, .call-bar:focus-visible { background: var(--green-700); color: #fff; }
  .call-bar svg { width: 20px; height: 20px; }

  /* La barra ocupa el borde inferior: el boton flotante sube por encima y el
     final de la pagina gana ese alto para que no quede nada tapado. */
  .wa-float { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
  body { padding-bottom: calc(60px + env(safe-area-inset-bottom, 0px)); }
  .header-actions .header-phone { display: none; }
  .header-actions { margin-left: 0; }
}

@media (max-width: 560.98px) {
  .step-actions { width: 100%; }
  .wa-float .label { display: none; }
  .wa-float { padding: .95rem; }

  /* Barra fija de llamada (punto 12). Entra aqui, en el mismo ancho en el que
     el telefono desaparece del encabezado, asi que no hay momento en que el
     numero no este a un toque. */

  .footer-bottom { flex-direction: column; }
  .btn { width: 100%; }
  .header-actions .btn { width: auto; }

  /* El logo a 58px se pinta 196px de ancho y, con el CTA al lado, el header
     pedia 413px pasara lo que pasara. Se ajustan las dos piezas fijas. */
  .brand img { height: 46px; }
  .header-actions .btn { padding: .58rem .8rem; font-size: .77rem; }
}

/* Por debajo de 400px las tres piezas no caben con el rotulo largo. En vez de
   retirar el CTA (que es la llamada principal), se acorta a "Cotizar" y se
   aprieta el logo. Asi el boton sobrevive hasta 320px.
   Ver qa/informe-errores.html A2. */
.btn-corto { display: none; }

@media (max-width: 400.98px) {
  .btn-largo { display: none; }
  .btn-corto { display: inline; }
  .brand img { height: 40px; }
  .header-inner { gap: .45rem; }
  .header-actions .btn { padding: .5rem .72rem; font-size: .75rem; }
}

/* 11. ACCESIBILIDAD / MOTION ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* Utilidad: solo lectores de pantalla */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ==========================================================================
   12. INTERACCIONES Y ANIMACIONES (mejora progresiva — todo bajo .js)
   ========================================================================== */

/* --- Reveal al entrar en viewport ---
   El estado oculto SOLO aplica cuando hay JS (.js en <html>), así que sin JS
   todo se ve. El observador de main.js añade .is-visible. */
/* Grupo A — elementos no interactivos: revelan con opacidad + desplazamiento */
.js :where(.section-head, .services-head, .step-card, .glass, .about-item,
  .ba-wrap, .zones-grid > div, .commitment .split > *) {
  transition: opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);
}
.js :where(.section-head, .services-head, .step-card, .glass, .about-item,
  .ba-wrap, .zones-grid > div, .commitment .split > *):not(.is-visible) {
  opacity: 0; transform: translateY(22px);
}

/* --- Los tres pasos: el verde oscuro es el hover ---
   Se redeclara `transition` incluyendo opacity y transform para no anular el
   reveal de arriba, que es la regla inmediatamente anterior. */
.step-card {
  transition: background var(--t), border-color var(--t),
              opacity .7s cubic-bezier(.16,1,.3,1), transform .7s cubic-bezier(.16,1,.3,1);
}
.step-card .num,
.step-card h3,
.step-card p { transition: color var(--t); }

/* Solo donde se puede pasar el cursor. Sin esta guarda, en una pantalla táctil
   `:hover` se dispara al TOCAR y se queda pegado hasta que tocas en otro sitio:
   parece un "seleccionado" que nadie pidió.
   Se usa `hover: hover` a secas y no `and (pointer: fine)` a propósito: en un
   portátil con pantalla táctil el puntero primario puede reportarse como grueso
   y la condición estricta dejaría la tarjeta sin efecto incluso con ratón. */
/* El destacado NO usa `:hover` ni media queries de puntero. Motivo medido: hay
   equipos (portátiles con pantalla táctil) que reportan `hover: none` aunque
   tengan ratón. Sin guarda, `:hover` se disparaba al tocar y se quedaba pegado;
   con guarda, esos equipos se quedaban sin ningún efecto.
   Lo gobierna el JS con eventos de puntero (ver initPasos en js/main.js), que
   distingue ratón de dedo por `pointerType` y no depende de lo que el navegador
   diga sobre sus capacidades. Con ratón entra y sale; con dedo, solo mientras
   se mantiene pulsado. Sin JS, las tres tarjetas se quedan iguales. */
.step-card.is-destacada        { background: var(--green-800); border-color: var(--green-800); }
.step-card.is-destacada h3     { color: #fff; }
.step-card.is-destacada p      { color: #B9CFC3; }
.step-card.is-destacada .num   { color: var(--green-100); }

/* Grupo B — tarjetas interactivas: revelan SOLO con opacidad, para no
   bloquear el hover (elevación) ni el tilt 3D que usan `transform`. */
.js :where(.card, .biz-card) {
  transition: border-color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast), opacity .7s ease;
}
.js :where(.card, .biz-card):not(.is-visible) { opacity: 0; }

/* --- Botón "volver arriba" --- */
.to-top {
  position: fixed; right: 20px; bottom: 84px; z-index: 69;
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--green-800); color: #fff; border: 0; cursor: pointer;
  font-size: 1.25rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast), background var(--t-fast);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { background: var(--green-600); transform: translateY(-3px); }

/* --- Lightbox (galería a pantalla completa) --- */
body.no-scroll { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: 120;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 5vw, 4rem);
  background: rgba(17, 44, 32, .93);
  opacity: 0; visibility: hidden;
  transition: opacity var(--t), visibility var(--t);
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lb-figure { margin: 0; display: flex; flex-direction: column; gap: .85rem; align-items: center; max-width: 1100px; }
.lb-img { max-width: 100%; max-height: 78vh; width: auto; height: auto; object-fit: contain; border-radius: 12px; box-shadow: var(--shadow-lg); background: var(--cream-2); }
.lb-cap { color: #E7EFE9; font-size: .95rem; text-align: center; }
.lb-close, .lb-prev, .lb-next {
  position: absolute; background: rgba(255,255,255,.14); color: #fff; border: 0; cursor: pointer;
  width: 48px; height: 48px; border-radius: 50%; font-size: 1.5rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--t-fast), transform var(--t-fast);
}
.lb-close:hover, .lb-prev:hover, .lb-next:hover { background: var(--green-400); color: var(--green-900); }
.lb-close { top: 18px; right: 18px; }
.lb-prev { left: 18px; top: 50%; transform: translateY(-50%); }
.lb-next { right: 18px; top: 50%; transform: translateY(-50%); }
.lb-prev:hover { transform: translateY(-50%) scale(1.08); }
.lb-next:hover { transform: translateY(-50%) scale(1.08); }
@media (max-width: 560.98px) {
  .lb-prev { left: 8px; } .lb-next { right: 8px; }
  .lb-close { top: 10px; right: 10px; }
  /* El comparador a una columna en móvil ya no se fuerza aquí: lo resuelve
     el minmax(340px) de .ba-gallery, que además evita el salto en 561px. */
}

/* --- Comparador interactivo antes/después --- */
.ba-slider {
  position: relative; overflow: hidden; border-radius: 18px;
  aspect-ratio: 1.25; container-type: inline-size; user-select: none; --pos: 50%;
}
.ba-slider > img,
.ba-before img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.ba-before { position: absolute; inset: 0; width: var(--pos); overflow: hidden; }
.ba-before img { width: 100cqi; max-width: none; }
.ba-divider { position: absolute; top: 0; bottom: 0; left: var(--pos); width: 3px; background: #fff; transform: translateX(-1.5px); box-shadow: 0 0 0 1px rgba(17, 44, 32,.12); pointer-events: none; }
.ba-handle {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 42px; height: 42px; border-radius: 50%; background: #fff; color: var(--green-800);
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem; font-weight: 700;
  box-shadow: var(--shadow);
  transition: transform var(--t-fast), box-shadow var(--t-fast);
}

/* Latido de invitación: sin él nadie sabe que el tirador se arrastra.
   Se detiene solo — al pasar por encima, al enfocar con teclado y, en cuanto se
   ha movido una vez, para siempre (el JS marca `.ba-usado`). Un pulso infinito
   que sigue latiendo después de entenderlo es ruido, no ayuda. */
@media (prefers-reduced-motion: no-preference) {
  .ba-slider:not(.ba-usado) .ba-handle { animation: ba-latido 2.6s ease-in-out infinite; }
  .ba-slider:hover .ba-handle,
  .ba-slider:focus-within .ba-handle { animation: none; }
}
@keyframes ba-latido {
  0%   { transform: translate(-50%, -50%) scale(1);    box-shadow: var(--shadow), 0 0 0 0    rgba(76,175,125, .55); }
  70%  { transform: translate(-50%, -50%) scale(1.07); box-shadow: var(--shadow), 0 0 0 13px rgba(76,175,125, 0); }
  100% { transform: translate(-50%, -50%) scale(1);    box-shadow: var(--shadow), 0 0 0 0    rgba(76,175,125, 0); }
}

/* Al acercarse, el tirador crece y refuerza la sombra: confirma que es agarrable. */
.ba-slider:hover .ba-handle,
.ba-slider:focus-within .ba-handle {
  transform: translate(-50%, -50%) scale(1.12);
  box-shadow: var(--shadow-lg);
}

.ba-range {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0;
  -webkit-appearance: none; appearance: none; background: transparent; cursor: ew-resize;
}
.ba-range:focus-visible { outline: 3px solid var(--green-400); outline-offset: 3px; }
.ba-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 46px; height: 260px; background: transparent; cursor: ew-resize; }
.ba-range::-moz-range-thumb { width: 46px; height: 260px; border: 0; background: transparent; cursor: ew-resize; }
.ba-range::-moz-range-track { background: transparent; }
.ba-slider .ba-tag { z-index: 2; }
.ba-slider .ba-tag.despues { right: 12px; left: auto; }

/* Overrides de accesibilidad de movimiento para lo nuevo */
@media (prefers-reduced-motion: reduce) {
  .js :where(.section-head, .services-head, .card, .biz-card,
    .step-card, .glass, .about-item, .ba-wrap,
    .zones-grid > div, .commitment .split > *) {
    opacity: 1 !important; transform: none !important;
  }
  .scroll-progress { display: none !important; }
}

/* ==========================================================================
   13. CINEMÁTICO PREMIUM
   ========================================================================== */

/* Barra de progreso de scroll */
/* Pegada al borde inferior del header, no al borde superior de la ventana.
   `absolute` contra el header (que es sticky, así que hace de contenedor) en
   lugar de `fixed`: así sigue su altura real, que cambia de 73 a 105px según
   el ancho. El -1px la coloca sobre el filete del borde, no debajo. */
.scroll-progress {
  position: absolute; bottom: -1px; left: 0; right: 0; height: 3px; z-index: 2;
  transform: scaleX(0); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--green-600), var(--green-400));
  will-change: transform;
}

/* Tilt 3D de tarjetas (el JS aplica el transform en hover) */
.card, .biz-card { transform-style: preserve-3d; }
.tilt-media { will-change: transform; }

/* Profundidad (glow) en la sección de cotización */
#estimate { position: relative; isolation: isolate; }
#estimate::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  left: -6%; bottom: -8%; width: min(520px, 60vw); aspect-ratio: 1;
  background: radial-gradient(circle, rgba(76,175,125,.16), rgba(76,175,125,0) 70%);
}

.field--full { margin-top: 1rem; }
