/* ==========================================================================
   Marea Verde — TIPOGRAFÍA ENORME SOBRE FOTO O SOBRE VERDE
   Nació como la opción de diseño "opc4" (19/9/2026) y el 22/9/2026 el cliente
   la eligió como sitio oficial: pasó de /opc4/ a la raíz. La raíz anterior
   (la v2) quedó en _opciones/v2-raiz/. Los comentarios "opc4 —" que siguen
   explican en qué se apartó de aquella v2. Cambios de fondo respecto de la v2:
   1. La display pasa a Bodoni Moda variable y deja de aparecer fina sobre
      crema. Regla de la opción: la didona va en MAYÚSCULAS, a escala de cartel
      y en crema sobre foto o sobre verde. Donde tiene que ir más chica (filas de
      servicios, pasarela) usa el eje óptico bajo y peso 500, que engordan los
      filetes sin cambiar el dibujo.
   2. .presentacion: foto a sangre con el titular enorme + banda verde compacta.
   3. .decada: verde sólido a todo el ancho, camioneta a sangre a la izquierda.
   El resto de la página conserva el layout de la raíz.
   --------------------------------------------------------------------------
   Marea Verde — v2
   Referencia madre: Secret Gardens (composición, aire, titulares).
   Contrastes: Formed Gardens (CTA circular, corte a oscuro).
   Formulario: Myles Baldwin (campos subrayados).
   ========================================================================== */

/* ----------------------------------- tokens ------------------------------ */

:root {
  --verde: #2A372D;
  --crema: #DDE0D7;
  --crema-claro: #EDEFE9;
  --crema-hueso: #F6F7F3;
  --verde-suave: #5A6A5C;
  --linea: rgba(42, 55, 45, .18);
  --linea-clara: rgba(221, 224, 215, .28);

  /* Cambiar SOLO estas dos lineas para pasar a otras fuentes.
     Ninguna regla depende de metricas propias de la fuente. */
  --font-display: 'Bodoni Moda', Georgia, serif;
  /* opc4 — tres cortes de la misma variable, por rol. El eje opsz va a mano
     y no con font-optical-sizing:auto: en auto el navegador usa opsz = tamaño
     en px, y a 100px+ cae en el corte 96, el de filetes más finos — justo lo
     que se lavaba. 28 es el corte de cartel (elegancia, filete de ~3px a
     120px); 14 el de titulares medianos; 11 el más robusto, para lo que va
     chico o sobre crema. Elegidos renderizando las candidatas en crema sobre
     la foto real y sobre el verde (_loop/opc4-qa/prueba-fuentes/). */
  --didona-cartel: 'opsz' 28;
  --didona-media: 'opsz' 14;
  --didona-robusta: 'opsz' 11;
  --font-body: 'Inter', system-ui, -apple-system, sans-serif;

  --e-1: 8px;  --e-2: 12px; --e-3: 20px; --e-4: 32px;  --e-5: 48px;
  --e-6: 64px; --e-7: 96px; --e-8: 128px; --e-9: 160px; --e-10: 200px;

  --margen: clamp(20px, 5vw, 88px);
  --ancho-max: 1440px;

  /* easing de la casa: sale rápido, aterriza suave */
  --curva: cubic-bezier(.25, .1, 0, 1);
}

/* ---------------------------- kerning a mano ------------------------------ */
/* La Bodoni Moda en MAYÚSCULAS de cartel deja tres pares abiertos: N·A
   (IGNACIO), R·A (INTEGRAL) y D·A (CUIDADO, CUIDANDO). Su tabla de kerning
   está pensada para caja baja. Se corrige envolviendo la PRIMERA letra del
   par en un span sin semántica y restándole tracking (el letter-spacing se
   aplica después del glifo, o sea, entre las dos letras). Medido a 150px en
   _loop/opc4-qa/kerning.png: N·A abría ~15px contra ~5px del resto. Valores
   en em: escalan con el cuerpo. */
.kern-na { letter-spacing: -.07em; }
.kern-ra { letter-spacing: -.05em; }
.kern-da { letter-spacing: -.035em; }

/* ----------------------------------- base -------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
html.lenis { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--crema-claro);
  color: var(--verde);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, p, ul, figure { margin: 0; padding: 0; }
/* h2/h3 sin cuerpo ni peso propios: desde el 22/9/2026 los eyebrows, la
   década y los títulos de servicios son encabezados reales (SEO), y cada uno
   ya trae su clase con tamaño y peso — esto evita que el negrita/1.5em del
   navegador se filtre donde la clase no lo pisa (p. ej. al botón del
   acordeón, que hereda con font: inherit). */
h2, h3 { font-size: inherit; font-weight: inherit; }
img { display: block; max-width: 100%; height: auto; }
ul { list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }

:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

::selection { background: var(--verde); color: var(--crema); }

.saltar {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--verde); color: var(--crema);
  padding: var(--e-2) var(--e-3); font-size: .875rem;
}
.saltar:focus { left: 0; }

/* medios: la imagen vive dentro de una ventana que recorta su movimiento */
.media { overflow: hidden; }
.media img { will-change: transform; }

/* ------------------------------- logos por máscara ------------------------ */
/* Un SVG en <img> no hereda currentColor: van como mask + background.        */

.logo {
  display: inline-block;
  background-color: currentColor;
  mask-repeat: no-repeat; mask-position: center; mask-size: contain;
  -webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain;
}

/* ------------------------------- tipografía ------------------------------ */

.eyebrow {
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--verde);
}

.eyebrow--sobre-verde { color: var(--crema); }

/* "10 años" bajo el logo, siempre que aparezca (pedido del cliente, 10/8/2026).
   Inter espaciado y chico: acompaña al lockup sin competirle. */
.anios {
  font-family: var(--font-body);
  font-size: .75rem;
  font-weight: 400;
  letter-spacing: .3em;
  text-indent: .3em;               /* compensa el tracking del último carácter */
  text-transform: uppercase;
  line-height: 1;
}

.parrafo-grande {
  font-size: 1.25rem;
  line-height: 1.55;
  max-width: 34ch;
}

/* opc4 — la display de cartel: mayúsculas, peso 500, corte óptico 28 y
   crema. Sólo vive sobre foto (presentación) o sobre verde (década). El
   tracking levemente positivo abre las mayúsculas de la didona, que de
   fábrica vienen apretadas para caja baja. */
.titular-doble__linea,
.decada__titular {
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: var(--didona-cartel);
  text-transform: uppercase;
  letter-spacing: .01em;
  color: var(--crema);
}

/* ------------------------------- header ---------------------------------- */

.cabecera {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: clamp(16px, 2vw, 26px) clamp(20px, 2.6vw, 40px);
  color: var(--verde);
  transition: transform .6s var(--curva), color .4s ease;
  pointer-events: none;              /* la barra es aire: solo logo y botón reciben clicks */
}

.cabecera > * { pointer-events: auto; }

.cabecera--oculta { transform: translateY(-115%); }

.cabecera--sobre-oscuro { color: var(--crema); }

/* wordmark ↔ isotipo, cruzados en el mismo punto */
.cabecera__marca {
  position: relative;
  height: 44px;
  display: flex; align-items: center;
}
/* Sin píldoras de protección: el cliente las sacó (7/8/2026). El contraste
   sobre fotos queda a cargo del cambio de tinta por sección (--sobre-oscuro). */

.cabecera__wordmark {
  width: clamp(216px, 19vw, 260px); height: 34px;
  mask-image: url('../img/logotipo.svg');
  -webkit-mask-image: url('../img/logotipo.svg');
  mask-position: left center; -webkit-mask-position: left center;
  transition: opacity .45s var(--curva), transform .45s var(--curva);
}

/* Los trazos hairline del logotipo, a cuerpo de header, pierden ~40% de tinta
   por anti-aliasing: el color era el más oscuro de la paleta y aun así se veía
   gris (cliente, 7/8/2026). El halo de 0.5px en el MISMO color repone el trazo
   sin leerse como sombra. */
.cabecera__wordmark,
.cabecera__isotipo { filter: drop-shadow(0 0 .5px currentColor); }

/* 108×46: por debajo de eso el trazo fino de la ola cae bajo 2px y el
   anti-aliasing lo diluye a ~75% de tinta (medido contra SG: 5.2:1 vs 14.7:1) */
.cabecera__isotipo {
  position: absolute; left: 0; top: 0; bottom: 0;
  margin-top: auto; margin-bottom: auto;
  width: 108px; height: 46px;
  mask-image: url('../img/isotipo.svg');
  -webkit-mask-image: url('../img/isotipo.svg');
  mask-position: left center; -webkit-mask-position: left center;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .45s var(--curva), transform .45s var(--curva);
}

.cabecera--compacta .cabecera__wordmark { opacity: 0; transform: translateY(-6px); }
.cabecera--compacta .cabecera__isotipo { opacity: 1; transform: translateY(0); }

/* La hamburguesa SOLO existe de 1024px para abajo. De 1025 para arriba los
   cuatro links están fijos en la barra (pedido textual del cliente, 10/9/2026:
   "el menu desplegable que no sea desplegable, que siempre figure asi fijo"),
   así que el botón no tiene nada que abrir. Va display:none y no visibility:
   además de esconderlo, lo saca del orden de tabulación — un botón invisible
   que igual recibe foco es peor que no tener botón.
   El bloque de la sábana (max-width: 1024px) le devuelve el display: flex. */
.hamburguesa {
  display: none; flex-direction: column; justify-content: center;
  align-items: flex-end;
  gap: 8px;
  width: 44px; height: 44px;
}

.hamburguesa span {
  display: block; width: 30px; height: 2px;   /* 2px como Secret Gardens, medido */
  background: currentColor;
  transition: width .35s var(--curva), transform .4s var(--curva);
}

.hamburguesa:hover span:first-child { width: 22px; }

/* abierta, muta a X en el lugar: gap 8 + trazo 2 → los centros están a ±5px */
.cabecera--abierta .hamburguesa span:first-child { transform: translateY(5px) rotate(45deg); }
.cabecera--abierta .hamburguesa span:last-child { transform: translateY(-5px) rotate(-45deg); }
.cabecera--abierta .hamburguesa span:first-child,
.cabecera--abierta .hamburguesa:hover span:first-child { width: 30px; }

/* --------------------------- menú inline en la barra ----------------------- */
/* Los links viven EN la barra (pedido del cliente, 7/8/2026 — el patrón de
   Mark Tessier). Reemplaza al overlay de pantalla completa.

   10/9/2026 — el cliente pidió que en escritorio dejen de ser desplegables
   ("el menu desplegable que no sea desplegable, que siempre figure asi fijo").
   Con eso, el estado por defecto de este bloque pasó a ser el ABIERTO: los
   cuatro links siempre a la vista, sin cascada, sin hamburguesa. La cascada de
   entrada y el estado cerrado ya no viven acá — se mudaron enteros al bloque
   de la sábana (max-width: 1024px), donde el menú sigue siendo desplegable
   igual que desde el 7/8. Ese comportamiento en angosto NO se toca: en una
   barra de 390px los cuatro links no entran. */

.cabecera__nav-grupo {
  display: flex; align-items: center;
  gap: clamp(20px, 2.5vw, 44px);
}

.nav-inline__lista {
  display: flex; align-items: center;
  gap: clamp(18px, 2.2vw, 38px);
}

.nav-inline__lista a {
  display: inline-block;
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  padding: var(--e-1) 0;
  position: relative;
}

/* subrayado que se dibuja al pasar, heredado del overlay anterior */
.nav-inline__lista a::after {
  content: '';
  position: absolute; left: 0; bottom: 2px;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .4s var(--curva);
}

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

/* En escritorio no hay estado cerrado: los li quedan con sus valores
   naturales (opaco, visible, sin desplazar) y sin transición de entrada. La
   cascada con --retraso existía sólo para la apertura y desapareció con ella;
   de 1024px para abajo se vuelve a declarar completa, con sus propios delays. */

/* En angosto los cuatro links no entran en la barra: el nav toma la pantalla
   entera en verde, con los links grandes en caja baja separados por filetes
   hairline, entrando de a uno de arriba a abajo (referencia Secret Gardens,
   pedido del cliente 7/8/2026). */
@media (max-width: 1024px) {
  .cabecera {
    transition: transform .6s var(--curva), color .4s ease, background-color .35s ease;
  }

  /* acá sí: es el único disparador del menú */
  .hamburguesa { display: flex; }

  .cabecera--abierta {
    background: var(--verde);   /* respaldo de la X mientras la sábana termina de aparecer */
    color: var(--crema);
    pointer-events: auto;
  }

  /* la sábana es el posicionado más tardío del header y pintaría encima de la
     X: el botón vuelve arriba para seguir clickeable (el logo queda tapado a
     propósito, como en la referencia) */
  .cabecera--abierta .hamburguesa { position: relative; z-index: 2; }

  .nav-inline {
    position: fixed;
    inset: 0;
    background: var(--verde);
    color: var(--crema);
    padding: clamp(96px, 24vh, 240px) clamp(20px, 5vw, 40px) var(--e-5);
    overflow-y: auto;
    opacity: 0;
    visibility: hidden;
    transition: opacity .3s var(--curva), visibility 0s linear .3s;
  }

  .cabecera--abierta .nav-inline {
    opacity: 1;
    visibility: visible;
    transition: opacity .45s var(--curva), visibility 0s;
  }

  .nav-inline__lista { flex-direction: column; align-items: stretch; gap: 0; }

  .nav-inline__lista li { border-top: 1px solid rgba(221, 224, 215, .32); }
  .nav-inline__lista li:last-child { border-bottom: 1px solid rgba(221, 224, 215, .32); }

  .nav-inline__lista a {
    display: block;
    font-size: clamp(1.625rem, 6.5vw, 2rem);
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    padding: .5em 0 .55em;
  }

  /* el filete divisor ya dibuja la línea: el subrayado de hover acá sobra */
  .nav-inline__lista a::after { content: none; }

  /* cerrado: apagados y apenas hundidos. visibility (y no display:none, que
     mataría la transición) los saca del tab order mientras la sábana no está.
     Estas tres declaraciones vivían en el bloque general hasta el 10/9/2026;
     desde que el escritorio quedó siempre abierto, el estado cerrado es
     exclusivo de este breakpoint. */
  .nav-inline__lista li {
    opacity: 0;
    visibility: hidden;
    transform: translateY(18px);
    transition: opacity .25s var(--curva), transform .25s var(--curva), visibility 0s linear .25s;
  }

  /* abierto: fluido, de a poco, de arriba a abajo */
  .cabecera--abierta .nav-inline__lista li {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition:
      opacity .65s var(--curva) var(--retraso, 0s),
      transform .65s var(--curva) var(--retraso, 0s),
      visibility 0s linear var(--retraso, 0s);
  }

  /* cuatro delays para cuatro links; el quinto quedó huérfano cuando la barra
     bajó a cuatro entradas y se fue con la limpieza del 10/9/2026 */
  .nav-inline__lista li:nth-child(1) { --retraso: .10s; }
  .nav-inline__lista li:nth-child(2) { --retraso: .18s; }
  .nav-inline__lista li:nth-child(3) { --retraso: .26s; }
  .nav-inline__lista li:nth-child(4) { --retraso: .34s; }
}

/* --------------------------------- hero ---------------------------------- */
/* opc4 — "didona enorme sobre foto" también en la apertura. La bajada es el
   titular: mayúsculas de cartel, fijas abajo a la izquierda (el gesto de
   Gloster), mientras detrás las cuatro fotos se relevan con una CORTINA que
   sube — la foto nueva se descubre de abajo hacia arriba sobre la vieja, que
   queda quieta debajo: nunca asoma el fondo. Cada foto sigue respirando con
   un zoom muy lento. El lockup se achica a firma a la derecha con su
   "10 años"; cuatro rayas hairline marcan el turno de cada foto y son el
   reloj del slider (main.js pasa de foto cuando termina la raya).           */

.hero {
  position: relative;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
  background: var(--verde);
}

.hero__slides { position: absolute; inset: 0; }

.hero__slide {
  position: absolute; inset: 0;
  opacity: 0;
}

.hero__slide--activa { opacity: 1; z-index: 1; }

/* la entrante va encima y se descubre de abajo hacia arriba */
.hero__slide--entrante {
  opacity: 1;
  z-index: 2;
  animation: hero-cortina 1.8s var(--curva) both;
}

@keyframes hero-cortina {
  from { clip-path: inset(100% 0 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

.hero__foto {
  width: 100%; height: 100%;
  object-fit: cover;
}

/* Ken Burns muy lento: 4% en 12s, casi imperceptible. Mismo valor de
   animation en activa y entrante: al pasar de una clase a la otra el zoom no
   se reinicia (el nombre de la animación no cambia). */
@keyframes hero-respira {
  from { transform: scale(1); }
  to   { transform: scale(1.04); }
}

.hero__slide--activa .hero__foto,
.hero__slide--entrante .hero__foto {
  animation: hero-respira 12s linear forwards;
}

/* Velo medido sobre las CUATRO fotos reales con _loop/opc4-qa/medir-hero.mjs
   (misma vara que la presentación: contraste del crema contra el 1% de píxeles
   de fondo más claros dentro de las cajas del titular, peor foto de las
   cuatro). Dos capas: arriba el scrim corto de la raíz para el header; abajo
   un degradado que sostiene el titular y la firma y se apaga antes de la
   mitad de la foto. Medido el 19/9/2026 en 320/390/768/1024/1440/1920 × 4 fotos:
     sin velo ...... 0,87:1 (piedra y cielo blancos: más claros que el crema)
     meseta .60 .... 2,89:1 peor caso (chacra, 1440) — no alcanza
     meseta .63 .... 3,06:1 titular / 3,05:1 firma — el mínimo que cumple 3:1
     meseta .65 .... la elegida: mínimo + margen para el zoom lento, que
                     corre la foto hasta 4% bajo el titular. Peor caso con
                     ella: 3,18:1 titular, 3,23:1 firma (chacra y casa).
   La meseta cubre el 38% de abajo (44% en teléfono) y se apaga al 68% (76%). */
.hero__velo {
  position: absolute; inset: 0; z-index: 3;
  background:
    linear-gradient(rgba(42, 55, 45, .42), rgba(42, 55, 45, 0) 22%),
    linear-gradient(to top,
      rgba(42, 55, 45, var(--hero-velo, .65)) 0%,
      rgba(42, 55, 45, var(--hero-velo, .65)) var(--hero-velo-alto, 38%),
      rgba(42, 55, 45, 0) var(--hero-velo-fin, 68%));
}

.hero__contenido {
  position: absolute; inset: 0; z-index: 4;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-content: end;
  column-gap: var(--e-6);
  max-width: calc(var(--ancho-max) + 2 * var(--margen));
  margin: 0 auto;
  padding: 0 var(--margen) var(--e-5);
  color: var(--crema);
}

.hero__bajada {
  grid-column: 1; grid-row: 1;
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: var(--didona-cartel);
  text-transform: uppercase;
  letter-spacing: .01em;
  font-size: clamp(2rem, 5.6vw, 5.5rem);
  line-height: 1.04;
}

/* Los cortes van por frase — CUIDADO INTEGRAL / DE JARDINES / Y EXTERIORES —
   con tres spans sin semántica (el h1 se lee igual). Las dos últimas frases
   no se parten nunca; la primera sí puede, en teléfono. */
.hero__bajada > span { display: block; }
.hero__bajada > span + span { white-space: nowrap; }

.hero__firma {
  grid-column: 2; grid-row: 1;
  align-self: end;
  display: flex; flex-direction: column; align-items: center;
  gap: var(--e-2);
  /* la firma asienta sobre la base del último renglón del titular */
  padding-bottom: .9em;
}

.hero__logo {
  width: clamp(156px, 13vw, 220px);
  aspect-ratio: 2122.58 / 1000.91;
  mask-image: url('../img/logo.svg');
  -webkit-mask-image: url('../img/logo.svg');
  filter: drop-shadow(0 1px 10px rgba(42, 55, 45, .5));
}

.hero__anios { font-size: .6875rem; }

/* las cuatro rayas: hairline crema tenue; la del turno se llena en lo que
   dura el turno. La animación ES el reloj: main.js escucha su animationend */
.hero__progreso {
  grid-column: 1 / -1; grid-row: 2;
  display: flex;
  gap: var(--e-1);
  margin-top: var(--e-5);
}

.hero__progreso span {
  position: relative;
  flex: 1;
  height: 1px;
  background: rgba(221, 224, 215, .32);
  overflow: hidden;
}

.hero__progreso span::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--crema);
  transform: scaleX(0);
  transform-origin: left center;
}

.hero__progreso .hero__marca--vista::after { transform: scaleX(1); }

.hero__progreso .hero__marca--activa::after {
  animation: hero-turno 7s linear forwards;
}

@keyframes hero-turno { to { transform: scaleX(1); } }

/* con la pestaña oculta el reloj se detiene (y con él el slider) */
.hero--pausado .hero__progreso span::after,
.hero--pausado .hero__foto { animation-play-state: paused; }

/* sin JS no hay slider: las rayas no tendrían nada que medir */
html:not(.js) .hero__progreso { visibility: hidden; }

/* ------------------------------ presentación ------------------------------ */
/* opc4 — una escena a sangre y una banda. La escena es la foto del pastizal
   costero a todo el ancho con "PUNTA DEL ESTE / A JOSÉ IGNACIO" a escala de
   cartel encima; la banda verde de abajo lleva "Quiénes somos" en columnas.
   Nada flota: la escena llena la pantalla y la banda es compacta.            */

.presentacion {
  background: var(--verde);
  color: var(--crema);
}

.presentacion__escena {
  position: relative;
  overflow: hidden;
  min-height: max(600px, 100svh);
  display: flex;
  align-items: flex-start;
  /* el titular se apoya en el cielo: arranca bajo el header y deja libre el
     tercio de abajo, donde están el horizonte y los caballos */
  padding: clamp(128px, 20vh, 216px) var(--margen) var(--e-8);
}

.presentacion__fondo {
  position: absolute;
  inset: 0;
}

.presentacion__fondo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* horizonte en el último tercio del cuadro: cielo arriba para el titular,
     caballos y mar abajo como remate */
  object-position: center 66%;
}

/* El velo es el mínimo que sostiene el contraste, medido sobre la foto real
   (no a ojo) con _loop/opc4-qa/medir-velo.mjs: se esconde el titular, se lee
   la luminancia de cada píxel de fondo dentro de las cajas de sus líneas y se
   calcula el contraste del crema contra el percentil 95 más claro. El cielo
   del pastizal es un celeste medio-claro: pelado da ~1,9:1 y no alcanza ni el
   3:1 de texto grande. El velo es verde de la casa (no negro: no ensucia el
   celeste) y está concentrado arriba, donde vive el titular; hacia el
   horizonte se abre y la foto queda limpia.
   Medido el 19/9/2026 (contraste del crema contra el píxel de fondo más claro
   del 1%, en 320/390/768/1024/1440/1920):
     sin velo ........ 1,12–1,25:1  (el cielo viene casi blanco del grade)
     meseta .50 ...... 2,83:1 en 1920 — no llega a 3:1
     meseta .54 ...... 3,07:1 peor caso — el mínimo que cumple
     meseta .56 ...... la elegida: el mínimo más un margen para el parallax,
                       que corre la foto ±2,4% bajo el titular. Peor caso
                       medido con ella: 3,2:1 (1440/1920); 3,7:1 en 768.
   Volver a medir si cambia la foto, el encuadre o el cuerpo del titular. */
.presentacion__velo {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgba(42, 55, 45, .56) 0%,
      rgba(42, 55, 45, .56) 58%,
      rgba(42, 55, 45, .08) 78%,
      rgba(42, 55, 45, .2) 100%);
}

.presentacion__titular {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--ancho-max);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

.titular-doble__linea {
  font-size: clamp(2.75rem, 8.6vw, 10.5rem);
  /* 1.1: con menos, el acento de JOSÉ se clavaba en la base de DEL */
  line-height: 1.1;
}

/* la segunda línea remata contra el margen derecho: el titular cruza la foto
   de lado a lado, que es el recorrido que nombra */
.titular-doble__linea:last-child { align-self: flex-end; text-align: right; }

/* el filete de la raíz queda, en crema y corto, como costura entre las dos
   líneas: marca la distancia sin ocupar lugar */
.presentacion .filete-vertical {
  display: block;
  width: 1px;
  height: clamp(40px, 7vh, 88px);
  margin: var(--e-3) 0 var(--e-3) 50%;
  background: rgba(221, 224, 215, .64);
}

/* la banda (variante "L", elegida por el usuario el 22/9/2026 tras tres rondas
   de comparación en _loop/qs-opciones/): "Quiénes somos" a la izquierda y los
   cuatro párrafos del cliente como UN texto corrido en dos columnas,
   justificado y estilo libro — sin renglón en blanco entre párrafos, cada uno
   arranca con sangría. Pedido textual: mismo tamaño en todo el texto y que las
   dos columnas "cierren bien y se vea simétrico". El balanceo de columnas deja
   a lo sumo un renglón de diferencia; ese último renglón lo resuelve el bloque
   "cierre de columnas" de main.js angostando el texto unos px.
   Descartado en el camino: 3 columnas, 4 columnas, 2×2, entrada en Bodoni
   grande (no quiere tamaños distintos), filas numeradas, columna tipo revista. */
.presentacion__texto {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--e-4);
  max-width: calc(var(--ancho-max) + 2 * var(--margen));
  margin: 0 auto;
  padding: clamp(64px, 9vh, 104px) var(--margen) clamp(72px, 10vh, 120px);
}

.presentacion__texto .eyebrow { grid-column: 1 / span 3; padding-top: .6em; }

.presentacion__columnas {
  grid-column: 4 / -1;
  columns: 2;
  column-gap: var(--e-6);
  column-fill: balance;
}

.presentacion__columnas .parrafo-grande {
  font-size: 1.125rem;
  line-height: 1.7;
  max-width: none;
  text-align: justify;
  hyphens: auto;             /* división en sílabas: lang="es-UY" en el <html> */
  -webkit-hyphens: auto;
}

.presentacion__columnas .parrafo-grande + .parrafo-grande { text-indent: 2em; }

/* mientras main.js mide dónde termina cada columna (cierre de columnas): sin
   el desplazamiento de entrada de los reveals, que no es parejo */
.columnas--midiendo .rv { transform: none !important; }

/* bajo 1200px el eyebrow sube y las dos columnas toman el ancho entero: al
   costado quedaban en ~30 caracteres y el justificado abría ríos */
@media (max-width: 1200px) {
  /* una sola pista: la grilla de 12 con sus 11 huecos de 32px mide 352px y a
     320 metía scroll horizontal */
  .presentacion__texto { grid-template-columns: minmax(0, 1fr); }
  .presentacion__texto .eyebrow,
  .presentacion__columnas { grid-column: 1; }
  .presentacion__texto .eyebrow { padding-top: 0; }
}

/* teléfono: una columna. Sin justificar — en ~350px el justificado abre
   huecos, y con una sola columna no hay nada que alinear */
@media (max-width: 760px) {
  .presentacion__columnas { columns: 1; }
  .presentacion__columnas .parrafo-grande { font-size: 1.0625rem; text-align: left; }
}

/* ----------------------- década — statement a sangre ---------------------- */
/* opc4 — verde sólido a todo el ancho. La camioneta ocupa la mitad izquierda
   de borde a borde y de arriba abajo; el titular en mayúsculas llena la otra
   mitad. No queda crema en ningún lado de la sección.                        */

.decada {
  background: var(--verde);
  color: var(--crema);
}

.decada__composicion {
  display: grid;
  grid-template-columns: var(--margen) repeat(12, minmax(0, 1fr)) var(--margen);
  align-items: stretch;
}

.decada__foto {
  grid-column: 1 / 6;
  grid-row: 1;
}

.decada__foto img {
  width: 100%;
  height: 100%;
  min-height: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  /* la camioneta está en la mitad derecha del original: sin correr el
     encuadre, la media columna la cortaba al medio */
  object-position: 78% 72%;
}

.decada__texto {
  grid-column: 7 / 14;
  grid-row: 1;
  align-self: center;
  padding: var(--e-8) 0;
}

.decada__titular {
  /* medido para que a 1024–1920 corte en cinco renglones con sentido
     (DIEZ AÑOS / CUIDANDO / JARDINES ENTRE / PUNTA DEL ESTE / Y JOSÉ
     IGNACIO.) y nunca deje "ENTRE" o "Y" huérfanos. Sin text-wrap:balance:
     con mayúsculas de este cuerpo, balance repartía los cortes al revés. */
  font-size: clamp(2.5rem, 5.3vw, 6rem);
  /* 1.08 y no 1: a interlínea 1 el acento de JOSÉ tocaba la T de PUNTA */
  line-height: 1.08;
}

/* "jardines entre" no se separa: sin esto "ENTRE" quedaba solo en un renglón
   en casi todos los anchos. Es un span sin semántica; el texto no cambia. */
.decada__junto { white-space: nowrap; }

/* -------------------------------- servicios ------------------------------- */

.servicios {
  background: var(--verde);
  color: var(--crema);
  /* abajo cede espacio: Confían es el remate del mismo bloque verde y tiene
     que leerse pegado (tercera pasada del cliente, 10/8/2026).
     Compactado en vertical a pedido del cliente (14/8/2026: "quedó muy larga") */
  padding: clamp(88px, 12vh, 136px) var(--margen) clamp(48px, 7vh, 88px);
}

.servicios__interior {
  max-width: var(--ancho-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--e-4);
  align-items: center;
}

.servicios__lista { grid-column: 1 / span 6; }

.servicios__lista .eyebrow { color: var(--crema); margin-bottom: var(--e-6); }

.filas { display: flex; flex-direction: column; }

.fila { position: relative; }

/* El disparador toma el ancho entero: el área de click es la fila completa,
   no sólo el texto — era el reclamo de fondo, la fila parecía clickeable. */
.fila__disparador {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-4);
  padding: var(--e-4) 0;
  background: none; border: 0; border-radius: 0;
  color: inherit; font: inherit; text-align: left;
  cursor: pointer;
}

.fila::after {
  content: '';
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--linea-clara);
  transform-origin: left center;
  transition: transform 1.1s var(--curva);
}

.fila:first-child::before {
  content: '';
  position: absolute; left: 0; top: 0;
  width: 100%; height: 1px;
  background: var(--linea-clara);
  transform-origin: left center;
  transition: transform 1.1s var(--curva);
}

/* al entrar en viewport los filetes se dibujan en cascada. Son tres filas
   desde el 10/9/2026 (se fue "Cercos, pérgolas y decks"): el cuarto delay
   quedó huérfano y se sacó. Los pasos siguen siendo de .12s — la cascada
   entera dura ahora .36s en vez de .48s, que es lo que corresponde a tres
   filetes; estirar los delays para llenar el mismo tiempo dejaría el gesto
   más lento sin motivo. */
.filas--vista .fila:first-child::before { transform: scaleX(1); }
.filas--vista .fila:nth-child(1)::after { transform: scaleX(1); transition-delay: .12s; }
.filas--vista .fila:nth-child(2)::after { transform: scaleX(1); transition-delay: .24s; }
.filas--vista .fila:nth-child(3)::after { transform: scaleX(1); transition-delay: .36s; }

.fila__titulo {
  font-family: var(--font-display);
  /* opc4 — crema sobre verde, pero a 24–34px: corte óptico medio y 500 para
     que los filetes no bajen de ~1,5px. Caja baja: son títulos largos y en
     mayúsculas no entran en la media columna. */
  font-weight: 500;
  font-variation-settings: var(--didona-media);
  font-size: clamp(1.5rem, 2.2vw, 2.125rem);
  line-height: 1.1;
}

.flecha { width: 32px; height: 12px; flex: none; }

.fila .flecha { transition: transform .45s var(--curva); }

.fila__disparador:hover .flecha { transform: translateX(10px); }

/* abierta: la misma flecha del resto del sitio, girada un cuarto — no se
   introduce un chevron nuevo sólo para esto */
.fila__disparador[aria-expanded='true'] .flecha { transform: rotate(90deg); }
.fila__disparador[aria-expanded='true']:hover .flecha { transform: rotate(90deg) translateX(6px); }

/* 0fr → 1fr anima la altura sin medirla en JS ni fijar un max-height a ojo */
.fila__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .6s var(--curva);
}

.fila__panel-interior { overflow: hidden; }

/* 22/9/2026 — el botón va dentro de un <h3> (patrón de acordeón de la APG, y
   para que los tres servicios sean encabezados para los buscadores): ya no es
   hermano del panel, así que el estado se lee desde el h3 con :has(). */
.fila__encabezado:has(> [aria-expanded='true']) + .fila__panel { grid-template-rows: 1fr; }

.fila__texto {
  max-width: 46ch;
  padding-bottom: var(--e-4);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .5s var(--curva), transform .5s var(--curva);
}

.fila__encabezado:has(> [aria-expanded='true']) + .fila__panel .fila__texto {
  opacity: 1;
  transform: none;
  transition-delay: .16s;
}

.servicios__foto { grid-column: 8 / span 5; }

/* la foto dicta el alto de la sección: el recorte bajó de 4/5.8 a 4/4.6 en la
   compactación del 14/8/2026 — con las filas cerradas sigue siendo la más alta */
.servicios__foto img { aspect-ratio: 4 / 4.6; object-fit: cover; }

/* -------------------------------- marquee ---------------------------------- */
/* Banda que gira en loop continuo (pedido del cliente, 10/8/2026: "tipo slide
   y no tan larga hacia abajo"). Dos grupos idénticos en fila; cada uno se
   desplaza su propio ancho y el cierre del loop no tiene costura. Pausa al
   posar el cursor. Es CSS puro: gira aunque el vendor de motion no cargue —
   y desde el 10/9/2026 gira también con prefers-reduced-motion, sólo que más
   lento (la excepción está argumentada en el bloque de reduced-motion).      */

.marquee { overflow: hidden; }

.marquee__pista { display: flex; width: max-content; }

.marquee__grupo {
  display: flex;
  align-items: center;
  gap: var(--marquee-gap, clamp(56px, 7vw, 112px));
  padding-right: var(--marquee-gap, clamp(56px, 7vw, 112px));
  animation: marquee-gira var(--marquee-dur, 50s) linear infinite;
}

.marquee__grupo li { white-space: nowrap; }

.marquee:hover .marquee__grupo { animation-play-state: paused; }

@keyframes marquee-gira {
  to { transform: translate3d(-100%, 0, 0); }
}

/* ------------------------------- confían ---------------------------------- */
/* Banda deslizante sobre verde, pegada a servicios como remate del mismo
   bloque (tercera pasada del cliente, 10/8/2026: "más integrado a los
   servicios, yo lo centraría"). El eyebrow va centrado.                      */

.confian {
  background: var(--verde);
  color: var(--crema);
  padding: clamp(40px, 6vh, 80px) 0 clamp(72px, 10vh, 128px);
}

.confian__interior {
  max-width: var(--ancho-max);
  margin: 0 auto;
  padding: 0 var(--margen);
}

.confian__eyebrow {
  text-align: center;
  margin-bottom: clamp(48px, 7vh, 80px);
}

/* si alguna marca vuelve a texto (sin OK para el logo), la fila la recibe así */
.confian__marquee li {
  font-family: var(--font-display);
  font-weight: 500;
  font-variation-settings: var(--didona-media);
  font-size: clamp(1.5rem, 2.4vw, 2.25rem);
  line-height: 1.15;
}

/* Logos de clientes: máscara + tinta currentColor, el mecanismo del logo
   propio. Del archivo solo importa el canal alfa; quedan crema plenos.
   Las alturas emparejan la MASA visual, no la caja: los wordmarks anchos
   van bajos, los emblemas (Aguerrebere, Casa Flor) necesitan más cuerpo. */
.logo-cliente { display: block; }

/* condensada y pesada: a la altura de los demás grita — va un paso más baja */
.logo-cliente--etiqueta-negra {
  height: clamp(15px, 1.5vw, 20px); aspect-ratio: 480 / 61;
  mask-image: url('../img/clientes/etiqueta-negra.png');
  -webkit-mask-image: url('../img/clientes/etiqueta-negra.png');
}
.logo-cliente--porsche {
  height: clamp(16px, 1.6vw, 22px); aspect-ratio: 1800 / 120;
  mask-image: url('../img/clientes/porsche.svg');
  -webkit-mask-image: url('../img/clientes/porsche.svg');
}
.logo-cliente--engel-volkers {
  height: clamp(24px, 2.4vw, 34px); aspect-ratio: 239 / 48;
  mask-image: url('../img/clientes/engel-volkers.svg');
  -webkit-mask-image: url('../img/clientes/engel-volkers.svg');
}
.logo-cliente--caro-criado {
  height: clamp(20px, 2vw, 28px); aspect-ratio: 745 / 124;
  mask-image: url('../img/clientes/caro-criado.svg');
  -webkit-mask-image: url('../img/clientes/caro-criado.svg');
}
.logo-cliente--aguerrebere {
  height: clamp(44px, 4.2vw, 60px); aspect-ratio: 480 / 303;
  mask-image: url('../img/clientes/aguerrebere.png');
  -webkit-mask-image: url('../img/clientes/aguerrebere.png');
}
.logo-cliente--casa-flor {
  height: clamp(48px, 4.6vw, 66px); aspect-ratio: 480 / 259;
  mask-image: url('../img/clientes/casa-flor.png');
  -webkit-mask-image: url('../img/clientes/casa-flor.png');
}
.logo-cliente--la-guadalupe {
  height: clamp(16px, 1.6vw, 22px); aspect-ratio: 342 / 33;
  mask-image: url('../img/clientes/la-guadalupe.svg');
  -webkit-mask-image: url('../img/clientes/la-guadalupe.svg');
}
/* sumado el 19/9/2026 (pedido del cliente). Es el script "Bom fin" en dos
   renglones, casi cuadrado: se trata como emblema, no como wordmark */
.logo-cliente--bomfin {
  height: clamp(40px, 3.8vw, 54px); aspect-ratio: 83 / 80;
  mask-image: url('../img/clientes/bomfin.svg');
  -webkit-mask-image: url('../img/clientes/bomfin.svg');
}

/* -------------------------------- zonas ----------------------------------- */
/* Tipo hero (elección del cliente, 10/8/2026, "opción 2" entre 5 armadas):
   la foto del olivo a lo ancho completo con velo degradado desde la derecha
   y el bloque entero — eyebrow, pasarela, índice — alineado a la derecha en
   crema; el olivo respira a la izquierda. Pasarela + índice: CSS puro con un
   reloj compartido y los MISMOS delays nth-child en los dos — si cambia la
   cantidad de barrios hay que retocar ciclo, keyframes y delays a la par.

   10/9/2026 — la lista pasó de 12 a 21 barrios. A 2,4s por nombre la vuelta
   se iba a 50,4s (casi un minuto), así que el turno bajó a 2s y el ciclo
   quedó en 42s (21×2). Todos los porcentajes de los keyframes se recalcularon
   sobre 1/21 = 4,7619% en vez de 1/12 = 8,3333%, manteniendo las proporciones
   internas del gesto: entrada al 19,2% del turno, meseta hasta el 82,8%,
   salida al 99,6% y reposición al 100,8% (ya dentro del turno siguiente).    */

/* El alto es un PISO, no un techo (10/9/2026). Con 12 barrios el índice
   entraba en cualquier pantalla y la sección podía ser una caja de 88vh que
   recortaba; con 21 el índice envuelve en 13 filas a 320px y el bloque entero
   se pasaba 15px del borde inferior — recortado, sin aviso, porque el
   overflow:hidden de acá se lo comía. Ahora el alto lo pide el contenido: la
   sección sigue midiendo 88vh cuando sobra lugar (el gesto de pantalla que
   eligió el cliente el 10/8) y crece cuando no. El piso vive en el contenido
   y no en la sección para que el centrado vertical siga siendo real. */
.zonas--panorama {
  position: relative;
  overflow: hidden;
  color: var(--crema);
}

.zonas-panorama__foto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;   /* olivo y flores; el pie del cuadro cede */
}

/* el velo entra desde la derecha: legibilidad donde vive el texto,
   la foto limpia donde vive el olivo */
.zonas-panorama__velo {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to left,
    rgba(42, 55, 45, .62) 0%,
    rgba(42, 55, 45, .28) 45%,
    rgba(42, 55, 45, 0) 72%);
}

.zonas-panorama__contenido {
  position: relative;
  min-height: max(560px, 88vh);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  text-align: right;
  /* el aire vertical sólo se nota cuando el índice llena la sección: hasta
     entonces el centrado se come el sobrante */
  padding: clamp(64px, 9vh, 112px) var(--margen);
}

/* más presencia que un eyebrow común (pedido del cliente, 7/8/2026) */
.zonas .eyebrow { font-size: 1.0625rem; margin-bottom: clamp(28px, 4.5vh, 48px); }

/* escala hero para la pasarela; los nombres rematan contra el margen derecho.
   flex:none porque el contenido es un flex column: sin eso, en una pantalla
   corta el índice largo la comprimía y los nombres quedaban cortados por la
   mitad (medido a 320×640 con 21 barrios). */
.zonas--panorama .pasarela {
  flex: none;
  width: min(100%, 720px);
  height: clamp(96px, 13vw, 168px);
}
.zonas--panorama .pasarela li {
  justify-content: flex-end;
  font-size: clamp(2rem, 4.2vw, 4.25rem);
}
.zonas--panorama .pasarela__progreso { background: var(--linea-clara); }
.zonas--panorama .pasarela__progreso::after { background: var(--crema); }

.zonas--panorama .zonas-lista__indice {
  justify-content: flex-end;
  margin-top: clamp(28px, 4.5vh, 48px);
}
/* sobre la foto el índice invierte el juego: reposo crema, turno en crema sólido */
.zonas--panorama .zonas-lista__indice li {
  animation-name: pasarela-marca-invertida;
  color: var(--crema);
}

@keyframes pasarela-marca-invertida {
  0%, 4.69%   { background: var(--crema); color: var(--verde); }
  4.8%, 100%  { background: transparent; color: var(--crema); }
}

/* la pasarela: un barrio por vez en Bodoni grande; los li viven apilados en
   absoluto y el keyframe les reparte el turno (1/21 del ciclo cada uno) */
.pasarela {
  position: relative;
  height: clamp(88px, 12vw, 128px);
  overflow: hidden;
}

.pasarela ul { position: absolute; inset: 0 0 2px; }

.pasarela li {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  /* opc4 — sobre foto con velo, de 32 a 68px: el corte medio a 500 */
  font-weight: 500;
  font-variation-settings: var(--didona-media);
  font-size: clamp(1.5rem, 3vw, 3rem);
  line-height: 1.1;
  opacity: 0;
  animation: pasarela-desfile 42s linear infinite;
}

/* el turno dura 4.7619% del ciclo (2s): entra de abajo, reina, sale arriba */
@keyframes pasarela-desfile {
  0%           { opacity: 0; transform: translateY(36px); }
  0.91%, 3.94% { opacity: 1; transform: none; }
  4.74%        { opacity: 0; transform: translateY(-36px); }
  4.8%, 100%   { opacity: 0; transform: translateY(36px); }
}

/* la línea de base es también la barra de progreso del turno */
.pasarela__progreso {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--linea);
}

.pasarela__progreso::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--verde);
  transform: scaleX(0);
  transform-origin: left center;
  animation: pasarela-progreso 2s linear infinite;   /* exactamente un turno */
}

@keyframes pasarela-progreso { to { transform: scaleX(1); } }

/* el índice: los veintiuno siempre a la vista; el que desfila se invierte a
   verde. El ancho lo dicta la pasarela, no un número redondo: los dos bloques
   rematan contra el mismo margen derecho, y compartir el techo de 720px hace
   que el índice envuelva en la misma medida en que desfilan los nombres.
   (Con 12 barrios el techo era 560px; con 21 eso daba una fila más y el bloque
   se comía el aire de la sección — 10/9/2026.) */
.zonas-lista__indice {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-1) var(--e-3);
  margin-top: var(--e-6);
  max-width: 720px;
}

.zonas-lista__indice li {
  font-size: .8125rem;
  letter-spacing: .06em;
  padding: 2px var(--e-1);
  animation: pasarela-marca 42s linear infinite;
}

@keyframes pasarela-marca {
  0%, 4.69%   { background: var(--verde); color: var(--crema); }
  4.8%, 100%  { background: transparent; color: var(--verde); }
}

/* Un delay por barrio, en pasos de 2s (el turno), pasarela e índice en la
   misma línea para que no se puedan desincronizar al editar. 21 líneas =
   21 barrios: si la lista del HTML cambia, esta tabla cambia con ella. */
.pasarela li:nth-child(1),  .zonas-lista__indice li:nth-child(1)  { animation-delay: 0s; }
.pasarela li:nth-child(2),  .zonas-lista__indice li:nth-child(2)  { animation-delay: 2s; }
.pasarela li:nth-child(3),  .zonas-lista__indice li:nth-child(3)  { animation-delay: 4s; }
.pasarela li:nth-child(4),  .zonas-lista__indice li:nth-child(4)  { animation-delay: 6s; }
.pasarela li:nth-child(5),  .zonas-lista__indice li:nth-child(5)  { animation-delay: 8s; }
.pasarela li:nth-child(6),  .zonas-lista__indice li:nth-child(6)  { animation-delay: 10s; }
.pasarela li:nth-child(7),  .zonas-lista__indice li:nth-child(7)  { animation-delay: 12s; }
.pasarela li:nth-child(8),  .zonas-lista__indice li:nth-child(8)  { animation-delay: 14s; }
.pasarela li:nth-child(9),  .zonas-lista__indice li:nth-child(9)  { animation-delay: 16s; }
.pasarela li:nth-child(10), .zonas-lista__indice li:nth-child(10) { animation-delay: 18s; }
.pasarela li:nth-child(11), .zonas-lista__indice li:nth-child(11) { animation-delay: 20s; }
.pasarela li:nth-child(12), .zonas-lista__indice li:nth-child(12) { animation-delay: 22s; }
.pasarela li:nth-child(13), .zonas-lista__indice li:nth-child(13) { animation-delay: 24s; }
.pasarela li:nth-child(14), .zonas-lista__indice li:nth-child(14) { animation-delay: 26s; }
.pasarela li:nth-child(15), .zonas-lista__indice li:nth-child(15) { animation-delay: 28s; }
.pasarela li:nth-child(16), .zonas-lista__indice li:nth-child(16) { animation-delay: 30s; }
.pasarela li:nth-child(17), .zonas-lista__indice li:nth-child(17) { animation-delay: 32s; }
.pasarela li:nth-child(18), .zonas-lista__indice li:nth-child(18) { animation-delay: 34s; }
.pasarela li:nth-child(19), .zonas-lista__indice li:nth-child(19) { animation-delay: 36s; }
.pasarela li:nth-child(20), .zonas-lista__indice li:nth-child(20) { animation-delay: 38s; }
.pasarela li:nth-child(21), .zonas-lista__indice li:nth-child(21) { animation-delay: 40s; }

/* ------------------------- cta circular a lo formed ------------------------ */

.cta {
  background: var(--crema-hueso);
  padding: clamp(64px, 9vh, 112px) var(--margen) clamp(72px, 10vh, 136px);
}

/* un clúster compacto y centrado, como el "Get in Touch" de Formed:
   el círculo pegado al titular, no en la otra punta de la pantalla */
.cta__interior {
  max-width: var(--ancho-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(48px, 7vw, 112px);
}

.cta .eyebrow { margin-bottom: var(--e-5); }

/* opc4 — el único titular display que queda sobre crema. Resuelto con la
   misma didona pero sin ninguno de sus puntos débiles: mayúsculas, corte
   óptico 11 (el más robusto de la variable) y peso 600, en verde pleno. Así el
   filete más fino mide ~2,5px a 56px y ya no se lava. Se descartó moverlo a
   verde: quedaría pegado al verde de Contacto y el círculo verde del cliente
   perdería su fondo; y se descartó pasarlo a la sans, porque es el cierre de
   la página y la didona es la voz de los titulares en toda la opc4. */
.cta__titular {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: var(--didona-robusta);
  text-transform: uppercase;
  letter-spacing: .02em;
  font-size: clamp(2.25rem, 2.6vw + 1.2rem, 3.75rem);
  line-height: 1;
  color: var(--verde);
  max-width: 12ch;
}

/* Círculo sólido — el recurso de Formed Gardens pedido por el cliente.
   Única curva permitida en toda la página (excepción del brief al radio 0). */
/* jerarquía texto > círculo: Formed lleva su círculo a ~1.8x el bloque del
   titular; más grande que eso, el acento compite con el mensaje */
.cta__circulo {
  flex: none;
  width: clamp(160px, 13.5vw, 196px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--verde);
  color: var(--crema);
  display: flex;
  align-items: center; justify-content: center;
  gap: .55em;
  text-decoration: none;
  font-size: .9375rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-indent: .18em;
  transition: transform .5s var(--curva);
}

.cta__circulo:hover { transform: scale(1.05); }

/* el efectito: la flecha da la vuelta entera, como en la referencia */
.cta__circulo .flecha { width: 26px; transition: transform .45s var(--curva); }
.cta__circulo:hover .flecha { transform: rotate(180deg); }

/* ------------------------------- contacto ---------------------------------- */

.contacto {
  background: var(--verde);
  color: var(--crema);
  padding: clamp(80px, 11vh, 136px) var(--margen);
}

.contacto__interior {
  max-width: var(--ancho-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--e-4);
}

.contacto__directos-bloque { grid-column: 1 / span 4; }

.contacto__directos { margin-top: var(--e-6); display: flex; flex-direction: column; gap: var(--e-3); }

.contacto__directos a {
  align-self: flex-start;
  font-size: 1.0625rem;
  line-height: 1.65;
  text-decoration: none;
  border-bottom: 1px solid var(--linea-clara);
  padding: var(--e-1) 0 2px;
  transition: border-color .3s ease;
}

.contacto__directos a:hover { border-color: var(--crema); }

.contacto__meta {
  margin-top: var(--e-6);
  font-size: .875rem;
  line-height: 1.5;
  opacity: .64;
}

.formulario {
  grid-column: 6 / span 7;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: var(--e-6);
  row-gap: var(--e-5);
  align-content: start;
}

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

.campo--ancho { grid-column: 1 / -1; }

.campo label {
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.campo input,
.campo textarea {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--linea-clara);
  border-radius: 0;
  padding: var(--e-1) 0 var(--e-2);
  transition: border-color .3s ease;
  min-height: 44px;
}

/* Autocompletado del navegador: Chrome pinta el campo de celeste con un
   background !important propio que no se puede pisar. El truco de la sombra
   inset está vetado (sin sombras, lo mira audit.mjs), así que se demora la
   transición de ese fondo para que nunca llegue a verse, y el texto se fuerza
   a crema (Chrome también lo cambia a negro). Reportado por el usuario 22/9. */
.campo input:-webkit-autofill,
.campo input:-webkit-autofill:hover,
.campo input:-webkit-autofill:focus,
.campo textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--crema);
  caret-color: var(--crema);
  transition: background-color 600000s 0s, color 600000s 0s;
}

.campo input:focus,
.campo textarea:focus {
  outline: none;
  border-color: var(--crema);
}

.campo textarea { resize: vertical; min-height: 96px; }

.campo__error { font-size: .875rem; opacity: .85; }

/* respuesta del envío del formulario (22/9/2026) */
.formulario__estado {
  grid-column: 1 / -1;
  font-size: .9375rem;
  line-height: 1.5;
  max-width: 46ch;
}

.formulario__estado a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }

.boton[disabled] { opacity: .5; cursor: progress; }

.boton {
  grid-column: 1 / -1;
  justify-self: start;
  display: inline-flex; align-items: center; gap: var(--e-3);
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .22em;
  text-transform: uppercase;
  padding: var(--e-3) 0 var(--e-2);
  border-bottom: 1px solid var(--crema);
  min-height: 44px;
}

.boton .flecha { transition: transform .45s var(--curva); }
.boton:hover .flecha { transform: translateX(10px); }

/* --------------------------------- footer ---------------------------------- */

.pie {
  background: var(--verde);
  color: var(--crema);
  padding: clamp(64px, 8vh, 104px) var(--margen) var(--e-5);
  border-top: 1px solid var(--linea-clara);
}

/* minmax(0, 1fr) y no 1fr: un track `1fr` no puede achicarse por debajo del
   min-content de su contenido, así que una palabra larga ensancha la grilla
   entera y empuja la página. Pasó el 10/9/2026 con el mail real
   (luis@mareaverdeeste.com, 188px indivisibles): el audit marcaba
   scroll-horizontal a 1024px y el culpable estaba acá, no en la sección que
   se veía desbordada. */
.pie__interior {
  max-width: var(--ancho-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--e-4);
}

.pie__marca { grid-column: 1 / span 4; }

.pie__logo {
  width: clamp(140px, 13vw, 190px);
  aspect-ratio: 2122.58 / 1000.91;
  mask-image: url('../img/logo.svg');
  -webkit-mask-image: url('../img/logo.svg');
  mask-position: left top; -webkit-mask-position: left top;
}

.pie__anios {
  margin-top: var(--e-3);
  font-size: .6875rem;
}

/* Reparto de columnas del 10/9/2026: el bloque de contacto pasó de 2 a 3
   columnas porque el mail real necesita 188px y dos columnas dan 127 a 1024px
   (y 165 a 1280). La columna se la cede el bloque de links, cuya entrada más
   larga —"Quiénes somos"— mide 103px y entra holgada en dos. */
.pie__links { grid-column: 5 / span 2; display: flex; flex-direction: column; }

.pie__links a {
  text-decoration: none;
  font-size: .9375rem;
  line-height: 1.6;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: border-color .3s ease;
}

.pie__links a:hover { border-color: var(--crema); }

.pie__zonas { grid-column: 7 / span 3; font-size: .9375rem; line-height: 2.2; }

/* overflow-wrap además del ancho: entre 900 y ~935px ni tres columnas alcanzan,
   y ahí se prefiere un mail cortado en dos líneas antes que scroll horizontal */
.pie__contacto {
  grid-column: 10 / span 3;
  font-size: .9375rem; line-height: 2.2;
  overflow-wrap: anywhere;
}

.pie__contacto a { text-decoration: none; border-bottom: 1px solid var(--linea-clara); transition: border-color .3s ease; }
.pie__contacto a:hover { border-color: var(--crema); }

.pie__legal {
  max-width: var(--ancho-max);
  margin: clamp(48px, 7vh, 80px) auto 0;
  font-size: .875rem;
  opacity: .66;
}

/* ------------------------------ reveals (js) ------------------------------- */
/* Los estados ocultos solo existen si hay JS: sin JS la página es plana y
   entera. GSAP toma estos elementos y los anima al entrar en viewport.       */

html.js .rv,
html.js .rv-titular { opacity: 0; }

html.js .media img { transform: scale(1.08); }

html.js .filete-vertical { transform: scaleY(0); transform-origin: top center; }

html.js .fila::after,
html.js .fila:first-child::before { transform: scaleX(0); }

/* con reduced motion no se oculta nada: página quieta y completa */
@media (prefers-reduced-motion: reduce) {
  html.js .rv,
  html.js .rv-titular { opacity: 1; }
  html.js .media img { transform: none; }
  html.js .filete-vertical { transform: none; }
  html.js .fila::after,
  html.js .fila:first-child::before { transform: none; }

  /* el acordeón sigue funcionando, pero abre y cierra de golpe */
  .fila__panel { transition: none; }
  .fila .flecha { transition: none; }
  .fila__texto { transition: none; }

  html { scroll-behavior: auto; }

  /* opc4: quieto en la primera foto, sin zoom ni cortina, y sin las rayas
     (no hay turnos que marcar) */
  .hero__slide--activa .hero__foto,
  .hero__slide--entrante .hero__foto { animation: none; }
  .hero__slide--entrante { animation: none; }
  .hero__progreso { visibility: hidden; }

  /* EXCEPCIÓN — el marquee sigue girando con reduced-motion. Es la única de
     todo el sitio y está pedida por el cliente (10/9/2026): con las
     animaciones desactivadas en su sistema veía los siete logos partidos en
     dos líneas y pidió "estos que sigan todos en una misma linea, tipo
     pasando". La lista envuelta era justamente esta excepción: `.marquee__pista`
     pasaba a display:block y el grupo a flex-wrap:wrap.

     Se acepta romper la preferencia SOLO acá porque este movimiento es el caso
     benigno del criterio de la WCAG: traslación lineal, constante, sin
     parpadeo, sin rebote, sin parallax y sin nada que dependa de él para
     leerse (los logos llevan su aria-label y el grupo duplicado va
     aria-hidden). La concesión que queda es la velocidad: 1,5× más lento que
     el giro normal — 75s en vez de 50s por vuelta — y se sigue pausando al
     posar el cursor con la regla `.marquee:hover` de arriba.

     El resto de este bloque no cambia: reveals, hero, acordeón y pasarela de
     zonas siguen respetando la preferencia. */
  .marquee__grupo { animation-duration: calc(var(--marquee-dur, 50s) * 1.5); }

  /* la pasarela de zonas no desfila: queda el primer barrio en escena, la
     barra de progreso quieta y el índice como lista plana en verde */
  .pasarela li { animation: none; }
  .pasarela li:first-child { opacity: 1; transform: none; }
  .pasarela__progreso::after { animation: none; }
  .zonas-lista__indice li { animation: none; }

  /* el menú inline abre y cierra de golpe: los estados son por clase, así que
     sin transición siguen funcionando */
  .nav-inline { transition: none; }
  .nav-inline__lista li { transition: none; }
  .hamburguesa span { transition: none; }
  .cabecera { transition: none; }
}

/* ------------------------------- responsive -------------------------------- */

@media (max-width: 1024px) {
  .contacto__directos-bloque { grid-column: 1 / span 4; }
  .formulario { grid-column: 5 / span 8; }
}

@media (max-width: 900px) {
  /* la década se apila ya desde acá: con media pantalla, "JARDINES ENTRE" no
     entra a un cuerpo de cartel. Titular primero sobre verde, la camioneta
     después a todo el ancho, apaisada para no pasar de una pantalla. */
  .decada__composicion { display: flex; flex-direction: column; }
  .decada__texto { padding: var(--e-7) var(--margen) var(--e-6); }
  .decada__foto { width: 100%; }
  .decada__foto img { aspect-ratio: 3 / 2; }
  .decada__titular { font-size: clamp(2.125rem, 7vw, 4rem); }

  .servicios__interior { display: block; }
  .servicios__foto { margin-top: var(--e-6); width: 86%; }

  /* angosto: sin franja limpia para el olivo — velo parejo y bloque a lo ancho */
  .zonas-panorama__contenido { min-height: max(480px, 88vh); }
  .zonas-panorama__velo { background: rgba(42, 55, 45, .46); }

  .contacto__interior { display: block; }
  .formulario { margin-top: var(--e-7); }

  .pie__interior { display: flex; flex-direction: column; gap: var(--e-6); }

  /* el clúster se mantiene: círculo pegado al titular, no en la otra esquina */
  .cta__interior { flex-direction: column; align-items: flex-start; gap: var(--e-6); }
  .cta__circulo { align-self: flex-start; margin-left: clamp(24px, 8vw, 96px); }
}

@media (max-width: 600px) {
  .hero { min-height: 480px; }

  /* la bajada envuelve a dos líneas acá: sin corrección, tracking .34em +
     line-height 2 la convierten en un bloque que compite con el lockup */
  /* opc4 — en teléfono: firma arriba a la izquierda, titular debajo en
     cuatro renglones, rayas al pie. Mismo velo, más alto. */
  .hero__contenido { grid-template-columns: minmax(0, 1fr); padding-bottom: var(--e-4); }
  .hero__firma { grid-column: 1; grid-row: 1; align-items: flex-start; padding-bottom: 0; margin-bottom: var(--e-4); }
  .hero__logo { width: 152px; mask-position: left center; -webkit-mask-position: left center; }
  .hero__anios { text-indent: 0; }
  .hero__bajada { grid-row: 2; font-size: clamp(2rem, 10vw, 2.875rem); line-height: 1.06; max-width: none; }
  .hero__progreso { grid-row: 3; margin-top: var(--e-4); }
  .hero { --hero-velo-alto: 44%; --hero-velo-fin: 76%; }

  /* opc4 — en teléfono la foto vertical del pastizal entra casi entera: el
     titular va en cuatro renglones de cartel, alineados a la izquierda (a
     este ancho el cruce izquierda/derecha se lee como un error de maquetado) */
  .presentacion__escena { min-height: max(560px, 92svh); padding-top: clamp(128px, 22svh, 200px); }
  /* "del&nbsp;Este" en el HTML: corta PUNTA / DEL ESTE y no PUNTA DEL / ESTE */
  .titular-doble__linea { font-size: clamp(2.5rem, 14.2vw, 4.5rem); line-height: .98; }
  /* entre las dos frases, un respiro: si no, los cuatro renglones se leen
     como un solo bloque */
  .titular-doble__linea:last-child { align-self: flex-start; text-align: left; margin-top: var(--e-3); }

  /* en teléfono la camioneta vuelve a 4:5: apaisada quedaba una tira */
  .decada__foto img { aspect-ratio: 4 / 5; }
  .decada__titular { font-size: clamp(2.125rem, 9.4vw, 3.5rem); }

  /* 21 nombres en ~280px de ancho: con el gap lateral de 20px casi ninguno
     comparte fila. A 12px entran de a dos donde son cortos y el índice baja
     un par de filas, sin tocar el cuerpo tipográfico (10/9/2026). */
  .zonas-lista__indice { column-gap: var(--e-2); }

  .fila__disparador { gap: var(--e-2); align-items: flex-start; }
  /* dos títulos largos envuelven acá sí o sí (copy fijo): balance evita la
     palabra huérfana y empareja la silueta de las dos líneas */
  .fila__titulo { font-size: 1.1875rem; text-wrap: balance; }
  .fila .flecha { width: 26px; margin-top: .45em; }
  .fila__texto { font-size: .9375rem; }

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

  .cta__circulo { width: clamp(168px, 46vw, 200px); }
}

@media (max-width: 360px) {
  /* opc4 — a 320 "IGNACIO" en mayúsculas es la palabra más larga: el piso
     del clamp baja para que entre sin partirse */
  .titular-doble__linea { font-size: 2.5rem; }
  .decada__titular { font-size: 1.875rem; }
}
