/* ============================================================
   TAO México — sistema de la portada
   Réplica de la referencia "azul acero", vestida con la marca:
   la paleta y el ritmo son los de la referencia; las fuentes son
   Stara y Manrope, hospedadas, porque Arial no es de la marca y
   los archivos ya estaban en assets/fonts.
   ============================================================ */

@font-face{
  font-family:Stara; src:url(../../assets/fonts/Stara-Black.woff2) format("woff2");
  font-weight:900; font-style:normal; font-display:swap;
}
@font-face{
  font-family:Stara; src:url(../../assets/fonts/Stara-Medium.woff2) format("woff2");
  font-weight:500; font-style:normal; font-display:swap;
}
/* Manrope va variable: un archivo de 24 KB cubre los cinco pesos. */
@font-face{
  font-family:Manrope; src:url(../../assets/fonts/Manrope-Variable.woff2) format("woff2-variations");
  font-weight:200 800; font-style:normal; font-display:swap;
}

:root{
  --void:#02070c;  --black:#030a10; --night:#071520; --abyss:#0b293b;
  --deep:#123e52;  --steel:#2d667a; --oxid:#54879a;  --silver:#91b2bf;
  --ice:#c9dce3;   --white:#edf4f6;
  --line:rgba(145,178,191,.22);
  --ease:cubic-bezier(.2,.8,.2,1);
  --display:Stara,"Times New Roman",serif;
  --texto:Manrope,system-ui,sans-serif;
}

*{box-sizing:border-box}
/* La barra es fija, así que un salto de ancla deja la sección a ras de
   pantalla y sus primeros 64-78 px quedan por debajo de ella: se perdía
   el rótulo "02 / ECOSISTEMA" de cada bloque. scroll-padding-top le dice
   al navegador dónde está de verdad el borde superior útil. */
html{scroll-behavior:smooth;scroll-padding-top:96px}
body{
  margin:0; background:var(--black); color:var(--white);
  font:400 15px/1.65 var(--texto); overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none}
/* El color va explícito: un <button> trae el suyo del navegador —negro— y
   heredando solo la tipografía, "Enviar" salía en negro sobre fondo
   oscuro. Los <a class="button"> no lo sufrían, y por eso no se vio antes. */
button{font:inherit;color:inherit}
img{display:block;max-width:100%}

/* Stara solo existe en 500 y 900, y la guía la pide SIEMPRE EN CAPS.
   El interletrado no baja de 0: en Black las mayúsculas ya pesan y el
   tracking negativo de la referencia las pegaba unas con otras. */
h1,h2,h3{font-family:var(--display);font-weight:900;text-transform:uppercase;letter-spacing:0;margin-top:0}
p{margin-top:0}

/* ---------- Portada de entrada ---------- */
/* El fondo es el color del borde del vídeo, no el --void: mientras llega
   el primer fotograma se ve este plano, y así el vídeo entra sin que
   cambie el tono. */
.intro{
  position:fixed;inset:0;z-index:999;background:#050e16;cursor:pointer;
  transition:opacity 1s var(--ease),visibility 1s;
}
.intro.done{opacity:0;visibility:hidden;pointer-events:none}
/* Ya se vio en esta visita: la clase la pone un script en el <head>. */
.sin-intro .intro{display:none}
/* cover: la capa es la pantalla entera y no puede dejar franjas. En
   vertical se pierde cielo de los lados; el ensō va al centro y entra. */
.intro-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .6s var(--ease);
}
/* Aparece cuando de verdad reproduce, no al montarse: si no, el primer
   fotograma se pinta en seco sobre el plano de color. */
.intro-video.on{opacity:1}
/* En vertical, cover dejaba ver solo la cuarta parte central del vídeo y
   el ensō, que ocupa el tercio central, salía cortado por los lados. Aquí
   el vídeo mide dos pantallas de ancho: se ve la mitad central, con el
   ensō entero y holgado, y arriba y abajo se funde con el plano de color. */
@media(orientation:portrait){
  .intro{overflow:hidden}
  .intro-video{
    inset:auto;top:50%;left:50%;width:200vw;height:auto;aspect-ratio:16/9;translate:-50% -50%;
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 22%,#000 78%,transparent);
            mask-image:linear-gradient(180deg,transparent,#000 22%,#000 78%,transparent);
  }
}

/* ---------- Encabezado ---------- */
.header{
  /* Por encima del menú de móvil (55): con el panel abierto hay que seguir
     viendo el logo y, sobre todo, el botón con el que se cierra. */
  position:fixed;top:0;left:0;right:0;height:78px;z-index:60;
  display:flex;align-items:center;justify-content:space-between;
  padding:0 clamp(22px,4vw,64px);
  border-bottom:1px solid transparent;transition:.4s;
  background:linear-gradient(#02070cc9,transparent);
}
.header.scrolled{height:64px;background:rgba(2,7,12,.9);backdrop-filter:blur(18px);border-color:var(--line)}
.brand img{width:118px;height:auto}
.header nav{display:flex;gap:34px;font-size:10px;text-transform:uppercase;letter-spacing:.17em;font-weight:700;color:var(--ice)}
.header nav a{transition:.25s}
.header nav a:hover{color:#fff}
.header-fin{display:flex;align-items:center;gap:20px}
.lang{
  font-size:10px;font-weight:700;letter-spacing:.17em;color:var(--silver);
  padding:6px 2px;border-bottom:1px solid transparent;transition:.25s;
}
.lang:hover{color:var(--ice);border-bottom-color:var(--oxid)}

/* ---------- Menú de móvil ---------- */
/* Dos rayas, no tres: al abrirse se cruzan en aspa. Con tres, la del medio
   hay que desvanecerla y la animación queda sucia. */
.burger{
  /* 44x44 es el mínimo para tocar con el pulgar sin fallar; el dibujo de
     las dos rayas mide 22, el resto es zona de toque. */
  display:none;width:44px;height:44px;padding:0;
  background:none;border:0;cursor:pointer;position:relative;
}
.burger i{
  position:absolute;left:11px;width:22px;height:1px;background:var(--ice);
  transition:.35s var(--ease);
}
.burger i:first-child{top:19px}
.burger i:last-child{top:25px}
.burger[aria-expanded="true"] i:first-child{top:22px;rotate:45deg}
.burger[aria-expanded="true"] i:last-child{top:22px;rotate:-45deg}

.menu{
  position:fixed;inset:0;z-index:55;
  display:flex;flex-direction:column;justify-content:center;gap:4px;
  padding:0 24px;
  background:var(--void);
  /* No se usa display:none para poder animar la entrada; mientras está
     cerrado no recibe clics ni foco. */
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .4s var(--ease),visibility .4s;
}
.menu.abierto{opacity:1;visibility:visible;pointer-events:auto}
.menu a{
  font-family:var(--display);font-weight:900;text-transform:uppercase;
  font-size:clamp(28px,8vw,42px);line-height:1.18;color:var(--white);
  transition:.25s;
}
.menu a:hover,.menu a:focus-visible{color:var(--oxid)}
.menu-pie{
  display:flex;flex-direction:column;gap:12px;
  margin-top:44px;padding-top:26px;border-top:1px solid var(--line);
}
.menu-pie a{
  font-family:var(--texto);font-weight:400;text-transform:none;
  font-size:15px;color:var(--silver);
}
.menu-pie .lang{
  font-weight:700;font-size:10px;letter-spacing:.17em;text-transform:uppercase;
  color:var(--ice);width:fit-content;
}

/* ---------- Botón ---------- */
.button{
  display:inline-flex;align-items:center;justify-content:space-between;gap:32px;
  min-width:225px;padding:16px 20px;
  border:1px solid var(--silver);border-radius:999px;
  text-transform:uppercase;letter-spacing:.16em;font-size:10px;font-weight:700;
  background:rgba(7,21,32,.56);backdrop-filter:blur(12px);transition:.35s;
}
.button:hover{background:var(--ice);color:var(--black);transform:translateY(-2px)}
.button-small{min-width:auto;padding:11px 18px;gap:10px}

/* ---------- Hero ---------- */
.hero{
  min-height:100svh;position:relative;overflow:hidden;
  background:radial-gradient(circle at 68% 44%,#16455a 0,transparent 28%),var(--void);
}
#heroCanvas{position:absolute;inset:0;width:100%;height:100%}
.hero-grid{
  position:absolute;inset:0;
  background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:70px 70px;
  mask-image:radial-gradient(circle at 75% 45%,#000,transparent 57%);
  -webkit-mask-image:radial-gradient(circle at 75% 45%,#000,transparent 57%);
  opacity:.15;
}
/* Velo lateral: el titular va a la izquierda y las partículas le quitaban
   contraste justo debajo del texto. */
.hero:after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(2,7,12,.96) 0%,rgba(2,7,12,.54) 48%,rgba(2,7,12,.16) 75%),
             linear-gradient(0deg,var(--black),transparent 28%);
}
.hero-copy{position:relative;z-index:3;padding:clamp(155px,22vh,210px) 6vw 100px;max-width:820px}
.eyebrow,.section-tag{text-transform:uppercase;letter-spacing:.26em;font-size:10px;font-weight:700;color:var(--silver)}
.hero h1{font-size:clamp(44px,6.6vw,92px);line-height:.95;margin:22px 0 34px}
.hero h1 em{font-style:normal;color:var(--ice)}
.lead{max-width:620px;color:var(--silver);font-size:clamp(16px,1.5vw,20px);font-weight:300;margin-bottom:36px}
.hero-orbit{
  position:absolute;z-index:2;right:4vw;top:50%;translate:0 -50%;
  width:min(48vw,660px);aspect-ratio:1;display:grid;place-items:center;
}
.hero-orbit img{position:relative;z-index:2;width:27%;height:auto;filter:grayscale(1) brightness(2.8) hue-rotate(160deg);opacity:.88;animation:breathe 5s ease-in-out infinite}
/* La luz del ensō: un halo que respira a su mismo ritmo (5 s) y una
   corona fina pegada al trazo. Sin ellos el ensō era un recorte blanco
   puesto sobre el fondo; con ellos parece que emite. */
.hero-orbit:before{
  content:"";position:absolute;inset:14%;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(201,220,227,.2) 0,rgba(84,135,154,.14) 28%,rgba(22,69,90,.08) 46%,transparent 64%);
  animation:halo 5s ease-in-out infinite;
}
.hero-orbit:after{
  content:"";position:absolute;inset:33%;border-radius:50%;pointer-events:none;
  border:1px solid rgba(201,220,227,.07);
  box-shadow:0 0 70px 6px rgba(201,220,227,.07),inset 0 0 50px rgba(201,220,227,.05);
}
@keyframes halo{50%{opacity:.7;scale:1.06}}

/* Cada órbita es un filete tenue entero y, encima, un arco de luz que se
   apaga hacia la cola, como un cometa. El punto va en la cabeza del arco
   y gira con él. El arco vive en :before, con la máscara que lo deja en
   un anillo de 2 px; el punto en :after, fuera de esa máscara, o se
   recortaría. */
.orbit{position:absolute;border:1px solid rgba(145,178,191,.13);border-radius:50%}
.orbit:before{
  content:"";position:absolute;inset:-1px;border-radius:50%;
  -webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2px),#000 calc(100% - 1.5px));
          mask:radial-gradient(farthest-side,transparent calc(100% - 2px),#000 calc(100% - 1.5px));
}
.orbit:after{
  content:"";position:absolute;top:-1px;left:50%;translate:-50% -50%;
  width:7px;height:7px;border-radius:50%;background:#fff;
  box-shadow:0 0 6px 1px #fff,0 0 22px 4px rgba(201,220,227,.55);
}
/* Horario: la cabeza está al final del degradado (arriba) y la cola la
   sigue por detrás. */
.orbit-a{inset:8%;animation:spin 30s linear infinite}
.orbit-a:before{background:conic-gradient(from 0deg,transparent 0 58%,rgba(201,220,227,.04) 62%,rgba(201,220,227,.9) 99.5%,transparent 100%)}
/* Antihorario: el degradado va al revés para que la cabeza siga
   delante. */
.orbit-b{inset:22%;animation:spin 22s linear reverse infinite}
.orbit-b:before{background:conic-gradient(from 0deg,transparent 0,rgba(145,178,191,.85) .5%,rgba(145,178,191,.04) 30%,transparent 34%)}
.orbit-b:after{width:5px;height:5px;background:var(--ice)}
.scroll{position:absolute;right:4vw;bottom:34px;z-index:5;font-size:8px;letter-spacing:.3em;color:var(--silver);display:flex;gap:16px;align-items:center}
.scroll i{display:block;width:70px;height:1px;background:var(--silver)}
@keyframes spin{to{rotate:360deg}}
@keyframes breathe{50%{transform:scale(1.05);filter:grayscale(1) brightness(3.5) hue-rotate(160deg)}}

/* ---------- Secciones ---------- */
section{position:relative}
.section-light{background:var(--white);color:var(--night)}

/* Antes eran tres columnas —1fr 1.5fr .8fr— y la primera se quedaba vacía
   con solo el rótulo arriba: media pantalla en blanco y todo empujado a la
   derecha. Ahora el rótulo encabeza a lo ancho, como en las demás
   secciones, y debajo va el bloque de texto. */
.statement{padding:120px 6vw 130px}
.statement h2,.section-heading h2,.path h2,.contact h2{font-size:clamp(32px,4.2vw,62px);line-height:1.02}
.statement h2 span,.section-heading h2 span,.path h2 span,.contact h2 span{color:var(--steel)}
/* El titular manda y el párrafo lo acompaña desde abajo: alineados por la
   última línea, no por la primera, que es como se sostienen entre sí. */
.statement-top{
  display:grid;grid-template-columns:1.55fr 1fr;
  gap:clamp(28px,5vw,80px);align-items:end;margin-top:44px;
}
/* Cuerpo propio, más contenido que el de los demás titulares: aquí hay
   tres frases con salto forzado y a 60 px la más larga partía por ancho,
   dejando cinco líneas donde deben verse tres. */
.statement-top h2{margin:0;font-size:clamp(30px,3.5vw,50px);line-height:1.08}
.statement-top p{max-width:46ch;margin:0 0 .5em;color:var(--steel);font-size:17px;line-height:1.7}

/* Las cifras repiten el patrón de la fila de Destinos —tres columnas
   separadas por filetes, entre dos reglas— para que las dos secciones
   rimen en vez de inventar cada una su propia caja. */
.metrics{
  display:grid;grid-template-columns:repeat(3,1fr);
  margin-top:clamp(56px,8vh,96px);
  border-top:1px solid rgba(45,102,122,.26);
  border-bottom:1px solid rgba(45,102,122,.26);
}
.metrics div{padding:38px clamp(24px,3vw,44px);border-right:1px solid rgba(45,102,122,.26)}
/* Sin sangría en los extremos: la primera cifra cae a plomo con el titular
   y la última cierra contra el margen, como el resto de la página. */
.metrics div:first-child{padding-left:0}
.metrics div:last-child{padding-right:0;border-right:0}
.metrics strong{display:block;font-family:var(--display);font-weight:900;font-size:clamp(34px,4vw,54px);line-height:1;color:var(--deep)}
.metrics span{display:block;margin-top:14px;text-transform:uppercase;letter-spacing:.13em;font-size:8px;font-weight:700;color:var(--steel)}

/* ---------- Ecosistema ---------- */
/* Titular arriba y el vídeo debajo, los dos dentro de UNA pantalla: el
   vídeo tiene que verse entero sin hacer scroll. La sección mide la
   ventana menos la barra compacta (64 px) y el vídeo ocupa lo que deja el
   titular. */
.ecosystem{
  display:flex;flex-direction:column;height:calc(100svh - 64px);min-height:520px;
  padding:clamp(20px,4vh,48px) 6vw clamp(12px,2.5vh,28px);
  /* El mismo color que el fondo del vídeo: así las franjas que deja
     contain a los lados o arriba no se distinguen del propio vídeo. */
  background:#01090e;overflow:hidden;
  /* El ancla del menú deja 96 px arriba (scroll-padding de html); aquí se
     queda en 64, justo bajo la barra, para que la sección entre entera. */
  scroll-margin-top:-32px;
}
.ecosystem .section-tag{flex:none;margin-bottom:clamp(14px,2.5vh,28px)}
.ecosystem .section-heading{flex:none;margin:0}
/* Fuera de la vista pero dentro de la página: lo leen Google y los
   lectores de pantalla. display:none no serviría, porque los dos lo
   ignoran. */
.solo-lectura{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;
}
/* Sin el techo de 22ch cada frase va en su línea: el alto que no gasta el
   titular se lo lleva el vídeo. */
.ecosystem .section-heading h2{max-width:none}
/* El vídeo toma el alto que deja el titular y su ancho sale de ahí a 16:9,
   con el 100% como techo. min-height:0 deja que el hueco del flex encoja;
   sin él el vídeo impondría su alto natural y empujaría la sección fuera
   de pantalla. contain es el seguro: si alguna vez la caja no es 16:9, el
   vídeo encoge en vez de recortarse. */
.eco-video{
  flex:1 1 0;min-height:0;width:auto;max-width:100%;aspect-ratio:16/9;align-self:center;
  margin-top:clamp(8px,2vh,24px);object-fit:contain;background:#01090e;
  /* El fondo del vídeo trae viñeta y sus cantos no son exactamente el
     color de la sección: sin fundido se veía el rectángulo. Solo se
     difumina el borde, que es cielo vacío; los logos quedan lejos. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),linear-gradient(180deg,transparent,#000 9%,#000 91%,transparent);
  -webkit-mask-composite:source-in;
          mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent),linear-gradient(180deg,transparent,#000 9%,#000 91%,transparent);
          mask-composite:intersect;
}
/* Era un flex con space-between: el antetítulo se iba a la izquierda, el
   titular al borde derecho y en medio quedaba un hueco enorme. Ahora el
   antetítulo encabeza al titular, como en el manifiesto y en El camino,
   y las cinco secciones arrancan todas desde el mismo margen. */
.section-heading{position:relative;z-index:2;margin-top:38px}
.section-heading .eyebrow{margin:0 0 16px}
.section-heading h2{max-width:22ch;margin:0}

/* ---------- Propiedades ---------- */
.properties{--gutter:6vw;padding:110px var(--gutter) 130px;background:var(--night)}
.property-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:68px}
.property-card{
  min-height:560px;position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:3px;background:var(--abyss);
  /* Color explícito. Al pasar la sección a fondo claro, el <h3> —lo único
     de la tarjeta sin color propio— heredaba el azul casi negro del
     .section-light y el nombre del desarrollo desaparecía sobre la foto. */
  color:var(--white);
  transition:scale .6s var(--ease),box-shadow .6s var(--ease);
}

/* Flotación en reposo.
   Va en la propiedad `translate` y el hover en `scale`, que en CSS son
   propiedades independientes de `transform`. Si las dos escribieran
   `transform` se pisarían: al pasar el ratón la carta daría un salto y
   perdería la flotación. Así conviven, y además `transform` queda libre
   para lo que le pongamos más adelante.

   Arranca solo cuando la tarjeta entra en pantalla (.on lo pone el
   observador que ya existe): fuera de vista no gasta nada. */
@keyframes flotar{
  0%,100%{translate:0 0}
  50%{translate:0 -10px}
}
.property-card.on{animation:flotar 8s ease-in-out infinite}

/* Desfase por tarjeta. En bloque se moverían todas a la vez y parecería
   que tiembla la página; escalonadas parece que respiran. El retardo es
   negativo para que cada una entre ya empezada, no esperando su turno. */
.property-card:nth-of-type(2).on{animation-delay:-1.3s}
.property-card:nth-of-type(3).on{animation-delay:-2.6s}
.property-card:nth-of-type(4).on{animation-delay:-3.9s}
.property-card:nth-of-type(5).on{animation-delay:-5.2s}
.property-card:nth-of-type(6).on{animation-delay:-6.5s}

.property-card:hover{scale:1.015}
/* Al pasar el ratón la flotación se detiene donde esté: la tarjeta se
   queda quieta bajo el cursor en vez de seguir escapándose. */
.property-card:hover.on{animation-play-state:paused}
/* Cuatro paradas en vez de dos: el corte recto de antes se veía como una
   banda pegada abajo. Así el velo sube como sombra de la propia foto. */
.property-card:after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,
    rgba(2,7,12,.95) 0%,
    rgba(2,7,12,.74) 28%,
    rgba(2,7,12,.26) 54%,
    transparent 80%);
}
/* El hue-rotate arrastra la foto hacia el azul de la paleta: sin él, el
   verde del Pacífico rompe la gama de toda la sección. */
.property-card img{width:100%;height:100%;object-fit:cover;filter:saturate(.65) contrast(1.08) hue-rotate(8deg);transition:1s var(--ease)}
.property-card:hover img{transform:scale(1.04);filter:saturate(.85) contrast(1.12)}
.property-card>div{
  position:absolute;z-index:2;left:28px;right:28px;bottom:28px;
  /* Seguro contra la foto: en Santamar el bloque cae sobre una fachada
     blanca y el velo por sí solo se quedaba corto. La sombra no se ve,
     pero sostiene el texto sea cual sea la imagen que se ponga mañana. */
  text-shadow:0 1px 10px rgba(2,7,12,.6);
}
.property-card span{color:var(--ice);font-size:9px;letter-spacing:.23em;font-weight:700;text-transform:uppercase}
.property-card h3{font-size:clamp(21px,1.7vw,27px);line-height:1.1;margin:11px 0 12px;color:var(--white)}
.property-dato{color:var(--silver);font-size:14px;margin:0 0 18px}

/* Un filete separa el dato del enlace: da estructura al bloque sin añadir
   ni una palabra más.
   El .ver de las tarjetas de avances entra en las mismas reglas: abre el
   visor en la propia página, así que es un <button> y no un enlace —no hay
   destino al que ir—, pero tiene que verse exactamente igual. */
.property-card a,
.property-card .ver{
  display:inline-flex;align-items:center;gap:9px;padding-top:16px;
  font-size:9px;letter-spacing:.18em;font-weight:700;text-transform:uppercase;
  color:var(--ice);border-top:1px solid rgba(201,220,227,.28);transition:.3s var(--ease);
}
.property-card .ver{background:none;border-left:0;border-right:0;border-bottom:0;cursor:pointer;padding-left:0;padding-right:0}
/* Dos acciones en la misma tarjeta —ver el avance y abrir la ficha— comparten
   el filete, así que el hueco va entre ellas y no debajo. */
.property-card .acciones{display:flex;gap:26px;flex-wrap:wrap}
/* La flecha es decoración, por eso va en el CSS y no en el marcado: quien
   use lector de pantalla oye "Ver desarrollo", que es lo que importa. */
.property-card a:after,
.property-card .ver:after{content:"\2192";transition:transform .3s var(--ease)}
.property-card:after{transition:opacity .6s var(--ease)}
.property-card:hover:after{opacity:.88}
.property-card:hover a,
.property-card:hover .ver{color:#fff;border-top-color:rgba(255,255,255,.6)}
.property-card:hover a:after,
.property-card:hover .ver:after{transform:translateX(4px)}

/* ---------- El camino ---------- */
.path{
  min-height:820px;display:grid;grid-template-columns:1fr 1fr;
  position:relative;overflow:hidden;
  background:radial-gradient(ellipse 70% 80% at 22% 50%,rgba(18,62,82,.5),transparent 70%),
             var(--void);
}

/* ---------- El mapa de México ----------
   Ocupa el bloque entero por detrás, no media pantalla: el territorio es
   el fondo de la sección, y el texto va encima. */
.path-mapa{
  position:absolute;inset:0;z-index:0;
  display:grid;align-items:center;justify-items:start;pointer-events:none;
  /* Se apaga hacia la derecha, donde va el texto: sin esto las fronteras
     cruzan por detrás de cada línea y compiten con ella. */
  -webkit-mask-image:linear-gradient(90deg,#000 0%,#000 56%,rgba(0,0,0,.22) 82%,transparent 100%);
          mask-image:linear-gradient(90deg,#000 0%,#000 56%,rgba(0,0,0,.22) 82%,transparent 100%);
}
/* El país entra entero en la mitad libre. Antes ocupaba todo el ancho y
   la península de Yucatán quedaba escondida bajo el texto, que es
   justamente donde está casi todo lo que vende TAO.
   El ancho se cuenta desde la mitad y no como porcentaje suelto: con
   64% del bloque el país invadía la columna del texto en todo lo que
   baja de ~1500 px (iPad horizontal, portátiles de 1280-1440). Así acaba
   2vw antes de la mitad y el texto, que empieza 4vw después, queda
   siempre a 6vw de Yucatán. */
.mapa-mx{width:min(calc(50% - 4vw),760px);height:auto;margin-left:2vw}

/* Tres capas del mismo dibujo. La base deja ver el país siempre; las dos
   estelas son un trazo corto que recorre cada frontera, con un rastro de
   luz alrededor. Dos, con longitudes y tiempos distintos, para que no se
   vea el bucle. */
.mapa-base{stroke:rgba(145,178,191,.17);stroke-width:1}

/* El contorno del país va SIEMPRE encendido: es la silueta que da sentido
   al dibujo. Si también parpadeara, en los momentos apagados no se sabría
   qué se está mirando. Las estelas viajan por dentro; el borde se queda. */
.mapa-pais{
  stroke:var(--ice);stroke-width:1.6;opacity:.9;
  filter:drop-shadow(0 0 4px rgba(201,220,227,.7)) drop-shadow(0 0 16px rgba(84,135,154,.5));
}
.mapa-estela{
  stroke:var(--ice);stroke-width:1.5;
  filter:drop-shadow(0 0 5px rgba(201,220,227,.9)) drop-shadow(0 0 14px rgba(84,135,154,.6));
}
/* El patrón se repite cada pocos cientos de unidades, no una vez por
   trazo. Con un hueco enorme la mayoría de las fronteras se quedaban
   apagadas casi todo el rato, porque muchas son más cortas que el propio
   hueco y la luz no llegaba a entrar en ellas.

   El desplazamiento de la animación vale EXACTAMENTE lo que mide el
   patrón —encendido + apagado—: así al terminar el ciclo la luz cae
   donde estaba la siguiente y el bucle no se ve. */
.mapa-estela-a{stroke-dasharray:90 400;animation:estela-a 7s linear infinite}
.mapa-estela-b{stroke-dasharray:38 250;opacity:.55;animation:estela-b 11s linear infinite}
@keyframes estela-a{to{stroke-dashoffset:-490}}
@keyframes estela-b{to{stroke-dashoffset:-288}}

/* Sin movimiento, el mapa se queda dibujado y quieto: se ve entero, que
   es lo que importa. */
@media(prefers-reduced-motion:reduce){
  .mapa-estela{animation:none;stroke-dasharray:none;opacity:.35}
}

.path-copy{grid-column:2;position:relative;z-index:1;padding:110px 7vw 100px 4vw}
.path h2{margin:32px 0 45px}
.path ol{list-style:none;padding:0;margin:0;border-top:1px solid var(--line)}
.path li{display:grid;grid-template-columns:48px 1fr;gap:15px;padding:19px 0;border-bottom:1px solid var(--line)}
.path li>b{color:var(--silver);font-size:9px;letter-spacing:.18em;font-weight:700}
.path li span{display:grid;grid-template-columns:140px 1fr;color:var(--silver)}
.path li strong{color:var(--white);text-transform:uppercase;letter-spacing:.12em;font-size:10px;font-weight:700}

/* ---------- Destinos ---------- */
.destinations{padding:115px 6vw 130px}
.destination-row{display:grid;grid-template-columns:repeat(3,1fr);margin-top:70px;border-top:1px solid rgba(45,102,122,.26);border-bottom:1px solid rgba(45,102,122,.26)}
.destination-row>div{padding:40px clamp(24px,3vw,44px);border-right:1px solid rgba(45,102,122,.26)}
/* Misma regla que en las cifras del manifiesto: sin sangría en los
   extremos, para que las dos bandas caigan a plomo con los titulares. */
.destination-row>div:first-child{padding-left:0}
.destination-row>div:last-child{padding-right:0;border-right:0}
.destination-row b{color:var(--oxid);font-size:9px;letter-spacing:.2em;font-weight:700}
.destination-row h3{font-size:25px;margin:20px 0 10px}
.destination-row p{color:var(--steel);max-width:320px}

/* ---------- Cierre ---------- */
.contact{text-align:center;padding:140px 6vw 130px;background:radial-gradient(circle,#123e52 0,transparent 46%),var(--void);overflow:hidden}
.contact>img{position:absolute;width:min(560px,70vw);height:auto;left:50%;top:50%;translate:-50% -50%;opacity:.06;filter:grayscale(1) brightness(3)}
.contact>*:not(img){position:relative}
.contact h2{font-size:clamp(40px,5.2vw,72px);margin:28px auto 44px}
.contact .button{min-width:250px}

/* ---------- Pie ---------- */
footer{background:var(--black);border-top:1px solid var(--line);color:var(--silver)}
.ftr-top{
  padding:70px 6vw 55px;display:grid;gap:40px 6vw;
  grid-template-columns:1.6fr 1fr 1fr 1fr;align-items:start;
}
.ftr-brand img{width:138px;height:auto;margin-bottom:18px}
.ftr-brand p{max-width:260px;margin:0;color:var(--silver)}
.ftr-col{display:flex;flex-direction:column;gap:11px}
.ftr-col h4{
  margin:0 0 6px;font-family:var(--texto);font-weight:700;
  font-size:9px;letter-spacing:.24em;text-transform:uppercase;color:var(--ice);
}
.ftr-col a{font-size:14px;color:var(--silver);transition:.25s;width:fit-content}
.ftr-col a:hover{color:var(--ice)}

.social{display:flex;gap:14px;margin-top:2px}
.social a{
  width:38px;height:38px;display:grid;place-items:center;
  border:1px solid var(--line);border-radius:50%;transition:.3s var(--ease);
}
.social svg{width:17px;height:17px;fill:var(--silver);transition:.3s}
.social a:hover{border-color:var(--ice);transform:translateY(-2px)}
.social a:hover svg{fill:var(--ice)}

.ftr-btm{
  padding:22px 6vw;border-top:1px solid var(--line);
  display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;
  font-size:8px;letter-spacing:.2em;font-weight:700;text-transform:uppercase;
}
/* Botones y no enlaces: el aviso abre un panel, no navega a ninguna URL. */
.ftr-legal{display:flex;gap:26px;flex-wrap:wrap}
.ftr-legal button{
  background:none;border:0;padding:0;cursor:pointer;color:var(--silver);
  font-size:8px;letter-spacing:.2em;font-weight:700;text-transform:uppercase;transition:.25s;
}
.ftr-legal button:hover{color:var(--ice)}

/* ---------- Panel de avisos legales ---------- */
.legal{
  width:min(820px,100vw - 32px);max-height:min(86svh,900px);
  padding:0;border:1px solid var(--line);border-radius:4px;
  background:var(--night);color:var(--white);
  flex-direction:column;overflow:hidden;
  animation:legal-in .3s var(--ease);
}
.legal[open]{display:flex}
.legal:not([open]){display:none}
.legal::backdrop{background:rgba(2,7,12,.78);backdrop-filter:blur(6px)}
@keyframes legal-in{from{opacity:0;transform:translateY(14px)}}

.legal-hd{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px 22px;border-bottom:1px solid var(--line);
  background:var(--abyss);flex:0 0 auto;
}
.legal-tabs{display:flex;gap:22px;flex-wrap:wrap}
.legal-tabs button{
  background:none;border:0;padding:4px 0;cursor:pointer;color:var(--silver);
  font-size:9px;letter-spacing:.18em;font-weight:700;text-transform:uppercase;
  border-bottom:2px solid transparent;transition:.25s;
}
.legal-tabs button:hover{color:var(--ice)}
.legal-tabs button[aria-selected="true"]{color:var(--white);border-bottom-color:var(--oxid)}
.legal-x{background:none;border:0;cursor:pointer;color:var(--silver);font-size:26px;line-height:1;padding:0 4px;transition:.25s}
.legal-x:hover{color:var(--white)}

.legal-body{padding:26px 30px 36px;overflow-y:auto;flex:1 1 auto}
.legal-body:focus-visible{outline:2px solid var(--oxid);outline-offset:-4px}
.lg-fecha{
  margin:0 0 22px;padding:12px 15px;border-left:2px solid var(--steel);
  background:rgba(45,102,122,.14);color:var(--ice);font-size:13px;
}
.lg-h{font-family:var(--display);font-weight:900;text-transform:uppercase;font-size:14px;letter-spacing:.06em;color:var(--white);margin:30px 0 10px}
.lg-p{color:var(--silver);font-size:14px;margin:0 0 13px}
.lg-nota{font-size:13px;color:var(--oxid)}
.lg-lista{margin:0 0 15px;padding-left:20px;color:var(--silver);font-size:14px}
.lg-lista li{margin-bottom:7px}
.legal-body a{color:var(--ice);text-decoration:underline}

/* El panel se apodera del scroll: sin esto la página sigue corriendo detrás. */
body.is-locked{overflow:hidden}

/* ---------- Revelado al entrar ---------- */
.reveal{opacity:0;transform:translateY(35px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
.reveal.on{opacity:1;transform:none}

/* ---------- Adaptación ---------- */
@media(max-width:900px){
  .header nav{display:none}
  .burger{display:block}
  /* El botón de contacto ya está dentro del menú: en la barra estorba. */
  .header-fin .button-small{display:none}
  .hero-orbit{opacity:.42;right:-25vw;width:90vw}
  .statement-top{grid-template-columns:1fr;align-items:start;gap:30px}
  .property-grid{grid-template-columns:1fr}
  .property-card{min-height:480px}
  .path{grid-template-columns:1fr}
  .path-copy{grid-column:1}
  /* En una columna el texto ocupa todo el ancho, así que el mapa se
     apaga por abajo en vez de por un lado. */
  /* En una sola columna no hay mitad libre: el mapa pasa a ser una
     textura detrás de todo el bloque, entero y muy tenue, en vez de
     asomar recortado por un borde. */
  .path-mapa{
    justify-items:center;align-items:center;
    -webkit-mask-image:radial-gradient(ellipse 80% 60% at 50% 50%,#000,transparent 85%);
            mask-image:radial-gradient(ellipse 80% 60% at 50% 50%,#000,transparent 85%);
  }
  .mapa-mx{width:112%;margin:0}
  .mapa-base{stroke:rgba(145,178,191,.12)}
  .mapa-estela{opacity:.5}
  .mapa-pais{opacity:.6;stroke-width:1.2}
  .destination-row{grid-template-columns:1fr}
  .destination-row>div{border-right:0;border-bottom:1px solid rgba(45,102,122,.26)}
  /* En vertical una pantalla entera sería casi toda cielo vacío: la
     sección vuelve a su alto natural y el vídeo va a sangre, de borde a
     borde, que es como más grandes se ven los logos. */
  .ecosystem{height:auto;min-height:0;padding-bottom:40px}
  .eco-video{flex:none;width:calc(100% + 12vw);max-width:none;margin:28px -6vw 0;aspect-ratio:16/9}
  .ftr-top{grid-template-columns:1fr 1fr;gap:34px 5vw}
}
@media(max-width:600px){
  .header{height:64px}
  html{scroll-padding-top:80px}
  .brand img{width:100px}
  .hero-copy{padding-top:160px}
  .hero h1{font-size:42px}
  .statement,.destinations{padding-left:24px;padding-right:24px}
  .ecosystem{padding-left:24px;padding-right:24px}
  .eco-video{width:calc(100% + 48px);margin-inline:-24px}
  .properties{--gutter:24px}
  .metrics{grid-template-columns:1fr}
  .metrics div{padding:28px 0;border-right:0;border-bottom:1px solid rgba(45,102,122,.26)}
  .metrics div:last-child{border-bottom:0}
  .path-copy{padding:80px 24px}
  .path li span{grid-template-columns:1fr;gap:5px}
  .ftr-top{grid-template-columns:1fr;gap:32px;padding:52px 24px 40px}
  .ftr-btm{flex-direction:column;align-items:flex-start;gap:16px;padding:22px 24px 30px}
  /* En columna los botones se estiran y su texto se centraría solo. */
  .ftr-legal{flex-direction:column;gap:12px;align-items:flex-start}
  .ftr-legal button{text-align:left}
  .legal{width:100vw;max-width:100vw;max-height:100svh;height:100svh;border:0;border-radius:0}
  .legal-hd{padding:14px 18px}
  .legal-tabs{gap:15px}
  .legal-tabs button{font-size:8px;letter-spacing:.12em}
  .legal-body{padding:22px 18px 40px}
}

/* Quieta, no rota: se ve todo, simplemente no se mueve. */
@media(prefers-reduced-motion:reduce){
  *{scroll-behavior:auto!important;animation:none!important;transition:none!important}
  .intro{display:none}
  .reveal{opacity:1;transform:none}
}

/* ============================================================
   Ficha de desarrollo
   ============================================================ */

/* La barra ya nace compacta: aquí no hay hero a pantalla completa
   contra el que destacar, y el titular arranca justo debajo. */
.pagina-dev{padding-top:64px}

.dev-hero{
  min-height:min(74svh,680px);display:flex;align-items:flex-end;
  background:var(--abyss) center/cover;
}
.dev-hero-video{
  position:relative;overflow:hidden;isolation:isolate;
  background:var(--abyss) center/cover;
}
.dev-hero-video video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:brightness(.7) saturate(.8);
}
.dev-hero-video::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(0deg,var(--void) 4%,rgba(2,7,12,.35) 48%,transparent 78%),
    linear-gradient(90deg,rgba(2,7,12,.88) 0%,rgba(2,7,12,.35) 46%,transparent 72%);
  z-index:1;
}
.dev-hero-copy{padding:0 6vw 64px;max-width:900px;position:relative;z-index:2}
.dev-volver{
  display:inline-block;margin-bottom:26px;
  font-size:9px;letter-spacing:.2em;font-weight:700;text-transform:uppercase;
  color:var(--silver);transition:.25s;
}
.dev-volver:hover{color:var(--ice)}
.dev-hero h1{font-size:clamp(34px,5.4vw,72px);line-height:1;margin:16px 0 18px}
.dev-precio{font-size:clamp(17px,2vw,22px);color:var(--ice);margin:0 0 22px}
.dev-tags{display:flex;flex-wrap:wrap;gap:10px;list-style:none;padding:0;margin:0}
.dev-tags li{
  padding:7px 15px;border:1px solid var(--line);border-radius:999px;
  font-size:10px;letter-spacing:.14em;font-weight:700;text-transform:uppercase;color:var(--silver);
}

.dev-intro{padding:96px 6vw}
.dev-lead{font-size:clamp(19px,2.3vw,27px);line-height:1.45;max-width:880px;margin:0 0 26px;color:var(--deep)}
.dev-cuerpo{font-size:17px;line-height:1.75;max-width:760px;margin:0;color:var(--steel)}

.dev-bloque{padding:88px 6vw}
.dev-h{
  font-size:clamp(22px,2.6vw,34px);margin:0 0 38px;
  padding-bottom:16px;border-bottom:1px solid var(--line);
}
.section-light .dev-h{border-bottom-color:rgba(45,102,122,.26)}

.ficha{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1px;margin:0;background:var(--line)}
.ficha-dato{background:var(--void);padding:24px 26px}
.section-light .ficha-dato{background:var(--white)}
.ficha-dato dt{font-size:9px;letter-spacing:.2em;font-weight:700;text-transform:uppercase;color:var(--silver);margin-bottom:9px}
.section-light .ficha-dato dt{color:var(--steel)}
.ficha-dato dd{margin:0;font-size:16px;color:var(--white)}
.section-light .ficha-dato dd{color:var(--night)}

.amen{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px 34px;
  list-style:none;padding:0;margin:0;
}
.amen li{
  padding-left:22px;position:relative;font-size:16px;color:var(--steel);
}
/* El punto va con ::before y no con list-style para poder colocarlo a la
   altura de la primera línea cuando el nombre ocupa dos. */
.amen li:before{content:"";position:absolute;left:0;top:10px;width:7px;height:7px;border-radius:50%;background:var(--oxid)}

.cerca{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:0 44px}
.cerca-fila{display:flex;justify-content:space-between;gap:18px;padding:16px 0;border-bottom:1px solid var(--line)}
.cerca-fila span{color:var(--silver)}
.cerca-fila b{color:var(--ice);font-weight:400}

.galeria{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:14px}
.galeria img{width:100%;height:100%;aspect-ratio:3/2;object-fit:cover;border-radius:3px;filter:saturate(.75)}

/* ---------- Visor del set de obra ---------- */
/* Hereda el marco del panel de avisos legales —mismo borde, mismo fondo,
   misma entrada— porque es la misma capa del sitio; lo que cambia es que
   aquí manda la foto, así que el cuerpo no tiene relleno. */
.visor{
  width:min(1180px,100vw - 24px);max-height:min(92svh,940px);
  padding:0;border:1px solid var(--line);border-radius:4px;
  background:var(--night);color:var(--white);
  flex-direction:column;overflow:hidden;
  animation:legal-in .3s var(--ease);
}
.visor[open]{display:flex}
.visor:not([open]){display:none}
.visor::backdrop{background:rgba(2,7,12,.88);backdrop-filter:blur(6px)}

.visor-hd{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:14px 20px;border-bottom:1px solid var(--line);
  background:var(--abyss);flex:0 0 auto;
}
.visor-t{margin:0;font-size:13px;color:var(--white)}
.visor-n{margin:3px 0 0;font-size:9px;letter-spacing:.18em;font-weight:700;text-transform:uppercase;color:var(--silver)}

/* El fondo es --void y no --night: sobre el más oscuro de los dos, la foto
   con banda —las de obra no son todas 3:2— no parece recortada a medias. */
.visor-marco{position:relative;flex:1 1 auto;min-height:0;background:var(--void);display:flex}
/* contain y no cover: en un avance de obra el encuadre es el dato. Recortar
   para llenar el marco es justo lo que no se puede hacer aquí. */
.visor-marco img{
  width:100%;height:100%;object-fit:contain;
  opacity:0;transition:opacity .35s var(--ease);
}
.visor-marco img.on{opacity:1}

.visor-paso{
  position:absolute;top:50%;translate:0 -50%;
  width:52px;height:52px;border-radius:50%;cursor:pointer;
  border:1px solid var(--line);background:rgba(2,7,12,.66);
  color:var(--ice);font-size:19px;line-height:1;
  backdrop-filter:blur(6px);transition:.25s var(--ease);
}
.visor-paso:hover{background:rgba(18,62,82,.9);color:#fff;border-color:var(--oxid)}
.visor-prev{left:16px}
.visor-next{right:16px}

@media(max-width:700px){
  .visor{width:100vw;max-height:100svh;border:0;border-radius:0}
  /* En el teléfono el gesto de arrastrar hace el trabajo; los botones se
     quedan pero pequeños y pegados al borde, sin taparle la foto. */
  .visor-paso{width:42px;height:42px;font-size:16px}
  .visor-prev{left:8px}
  .visor-next{right:8px}
}

.dev-cta{text-align:center;padding:110px 6vw 120px;background:radial-gradient(circle,#123e52 0,transparent 48%),var(--void)}
.dev-cta h2{font-size:clamp(28px,3.8vw,52px);margin:0 0 20px}
.dev-cta .lead{margin:0 auto 38px}
.dev-cta-botones{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}

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

.button-wa{border-color:#3f9b6d;color:#bfe6d2}
.button-wa:hover{background:#3f9b6d;color:#fff;border-color:#3f9b6d}

/* Botón flotante, siempre a mano. Va abajo a la derecha porque es donde
   el pulgar llega sin recolocar el teléfono. */
.wa-flota{
  position:fixed;right:20px;bottom:20px;z-index:45;
  width:54px;height:54px;border-radius:50%;
  display:grid;place-items:center;
  background:#25d366;box-shadow:0 8px 28px rgba(0,0,0,.45);
  transition:.3s var(--ease);
}
.wa-flota:hover{transform:scale(1.07)}
.wa-flota svg{width:28px;height:28px;fill:#fff}
/* Con el menú o un aviso abiertos estorba y además queda por debajo. */
body.is-locked .wa-flota{opacity:0;pointer-events:none}

/* ============================================================
   Joy Tree — no es una tarjeta, es un hero dentro de la página
   Va a sangre de lado a lado, saliéndose del margen de la sección, y el
   nombre se lee como en assembla.law: centrado, muy grande, en peso
   Medium y con las letras muy separadas, para que la foto pase por
   debajo en vez de competir con el texto.
   ============================================================ */

.prop-jt{
  grid-column:1 / -1;position:relative;display:block;overflow:hidden;
  /* Sale del margen de la sección exactamente lo que ese margen mide. */
  margin-inline:calc(var(--gutter) * -1);
  height:min(78svh,640px);
}
/* Respiración lenta: acerca y aleja sin parar, como el zoom de un plano
   de cine. Va de ida y vuelta en la misma animación —sin alternate— para
   que el ciclo no tenga un tirón al reiniciarse.
   Se anima transform, que resuelve la tarjeta gráfica sin repintar nada,
   y por eso 24 s de movimiento continuo no cuestan fluidez. */
@keyframes jt-respira{
  0%,100%{scale:1}
  50%{scale:1.09}
}
.prop-jt img{
  width:100%;height:100%;object-fit:cover;
  animation:jt-respira 24s cubic-bezier(.4,0,.6,1) infinite;
  transition:transform 1.2s var(--ease);
  will-change:transform;
}
/* La respiración va en `scale` y el acercamiento del ratón en `transform`.
   No se pisan: son propiedades distintas y el navegador las compone, así
   que el zoom se SUMA al vaivén en vez de cortarlo. Con `transform` en las
   dos, al pasar el ratón la imagen pegaba un salto y se quedaba quieta.
   Por eso el hover se queda en 1.05: sobre el 1.09 del vaivén ya es
   acercamiento de sobra. */
.prop-jt:hover img{transform:scale(1.05)}

/* Dos capas. La plana asienta la foto entera; la radial oscurece solo el
   centro, que es donde da el sol del pabellón y donde justamente van las
   dos líneas pequeñas, que sin ella se perdían. */
.prop-jt:after{
  content:"";position:absolute;inset:0;
  background:radial-gradient(ellipse 68% 62% at 50% 50%,rgba(2,7,12,.58),transparent 74%),
             rgba(2,7,12,.3);
}

.prop-jt-copy{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(18px,3vh,32px);padding:0 24px;text-align:center;
}
.prop-jt-arriba,.prop-jt-abajo{
  margin:0;font-weight:700;text-transform:uppercase;color:var(--white);
  text-shadow:0 1px 14px rgba(2,7,12,.85),0 0 40px rgba(2,7,12,.5);
}
/* La ubicación es un pie: pequeña y muy espaciada. */
.prop-jt-arriba{font-size:10px;letter-spacing:.26em}
/* Esta línea ya no es un rótulo, es la oferta: lleva el precio y es lo
   que decide si alguien entra. A 10 px sobre el turquesa del agua se
   perdía. Sube de cuerpo y baja el interletrado, que a este tamaño ya
   no hace falta tanto para que respire. */
.prop-jt-abajo{
  font-size:clamp(13px,1.3vw,19px);letter-spacing:.13em;
  /* En móvil no cabe de una línea. Con balance parte por la mitad
     —"LOTES RESIDENCIALES / DESDE $999,000 MXN"— en vez de dejar una
     línea larga y un resto corto. La flecha va pegada con un espacio
     duro para que nunca se quede sola abajo. */
  text-wrap:balance;
}
.prop-jt-abajo span{display:inline-block;margin-left:6px;transition:.3s var(--ease)}
.prop-jt:hover .prop-jt-abajo span{transform:translate(3px,-3px)}

/* Stara Medium, no Black: es la otra marca del grupo y el peso ligero con
   interletrado abierto es justo el efecto de Assembla. En caja alta, como
   pide la guía. */
.prop-jt-marca{
  margin:0;font-family:var(--display);font-weight:500;
  font-size:clamp(46px,11vw,150px);line-height:.92;
  letter-spacing:.1em;text-transform:uppercase;
  /* El interletrado añade aire a la derecha de la última letra y descentra
     el conjunto; se compensa con la misma medida. */
  text-indent:.1em;
  color:var(--white);
}

@media(max-width:600px){
  .prop-jt{height:min(68svh,520px)}
  .prop-jt-arriba{font-size:9px;letter-spacing:.2em}
  .prop-jt-abajo{letter-spacing:.1em}
}

/* ============================================================
   Formulario
   ============================================================ */

.form{display:grid;gap:18px;max-width:640px;margin:0 auto;text-align:left}
.form-fila{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.campo{display:flex;flex-direction:column;gap:8px}
.campo label{font-size:9px;letter-spacing:.2em;font-weight:700;text-transform:uppercase;color:var(--silver)}
.campo input,.campo select,.campo textarea{
  font:400 15px/1.5 var(--texto);color:var(--white);
  background:rgba(7,21,32,.6);border:1px solid var(--line);border-radius:3px;
  padding:14px 16px;transition:.25s;
}
.campo textarea{resize:vertical;min-height:110px}
.campo input:focus,.campo select:focus,.campo textarea:focus{
  outline:none;border-color:var(--oxid);background:rgba(7,21,32,.9);
}
.campo select{appearance:none;cursor:pointer}
.campo select option{background:var(--night);color:var(--white)}

.consiente{display:flex;gap:12px;align-items:flex-start;font-size:13px;color:var(--silver);cursor:pointer}
.consiente input{margin-top:3px;accent-color:var(--oxid);width:16px;height:16px;flex:0 0 auto}
/* Enlace dentro de una frase: abre el aviso sin sacar de la página. */
.lnk-in{background:none;border:0;padding:0;cursor:pointer;color:var(--ice);text-decoration:underline;font:inherit}

.form button[type=submit]{justify-self:start;cursor:pointer}
.form-aviso{margin:0;font-size:14px;min-height:21px}
.form-aviso.mal{color:#e8a0a0}
.form-aviso.bien{color:#9fd8b8}
.form-aviso a{color:var(--ice);text-decoration:underline}

@media(max-width:600px){
  .form-fila{grid-template-columns:1fr}
  .dev-hero-copy{padding:0 24px 44px}
  .dev-intro,.dev-bloque{padding-left:24px;padding-right:24px}
  .dev-intro{padding-top:64px;padding-bottom:64px}
  .dev-bloque{padding-top:62px;padding-bottom:62px}
  .galeria{grid-template-columns:1fr}
  .wa-flota{right:14px;bottom:14px;width:50px;height:50px}
}

/* ============================================================
   Ritmo de la portada
   Los bloques alternan claro y oscuro de arriba abajo. Antes había tres
   oscuros seguidos —ecosistema, propiedades, camino— y en ese tramo la
   página dejaba de respirar y todo parecía la misma sección.
   ============================================================ */

/* .properties fija su propio fondo y gana por orden a .section-light. */
.properties.section-light{background:var(--white)}
.properties.section-light .property-grid{margin-top:76px}

/* Sobre blanco, el plateado casi desaparece. */
.section-light .eyebrow,
.section-light .section-tag{color:var(--steel)}

/* Más aire entre bloques: es lo que separa una página densa de una que
   se lee. El límite superior no sube en móvil, donde el alto es el
   recurso escaso. */
.statement{padding-block:clamp(90px,13vh,150px)}
.properties,.destinations{padding-block:clamp(90px,13vh,150px)}
.contact{padding-block:clamp(110px,15vh,170px)}

/* ============================================================
   Acabado: grano, profundidad y degradados en capas
   De la guía de diseño se toma lo que eleva el material sin tocar el ADN:
   nada de cambiar tipografías, radios exagerados ni barra flotante de
   cristal. Solo textura, luz y peso.
   ============================================================ */

/* Grano de película. Es lo que más separa una pantalla plana de algo que
   parece impreso: rompe las bandas de los degradados y le da cuerpo al
   negro. Va fijo y sin capturar clics, que es la única forma de que no
   cueste nada al hacer scroll. */
body:before{
  content:"";position:fixed;inset:0;z-index:70;pointer-events:none;
  opacity:.04;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media(prefers-reduced-motion:reduce){body:before{opacity:.025}}

/* Los fondos oscuros eran un color plano o un solo radial centrado, y a
   pantalla ancha se leían como un rectángulo. Con dos focos desplazados
   y de distinto tamaño el fondo deja de tener centro evidente. */
.hero{
  background:
    radial-gradient(circle at 68% 44%,rgba(22,69,90,.85) 0,transparent 30%),
    radial-gradient(ellipse 70% 50% at 12% 88%,rgba(18,62,82,.4) 0,transparent 70%),
    var(--void);
}
.contact{
  background:
    /* El foco va arriba, detrás del titular: centrado quedaba justo bajo
       el formulario y, con el desenfoque de fondo de los campos, los
       lavaba hasta dejarlos casi blancos. */
    radial-gradient(ellipse 58% 42% at 50% 16%,rgba(18,62,82,.75) 0,transparent 70%),
    radial-gradient(ellipse 60% 45% at 8% 96%,rgba(11,41,59,.7) 0,transparent 72%),
    var(--void);
}

/* Filete con luz propia. Un borde plano de 1 px se lee como dibujo; el
   mismo borde con un reflejo interior arriba se lee como un canto
   biselado, que es de donde viene la sensación de material. */
.property-card,
.campo input,.campo select,.campo textarea{
  box-shadow:inset 0 1px 0 rgba(237,244,246,.07);
}
/* Sombra ambiental muy difusa, no un contorno duro: separa la tarjeta del
   fondo sin que se note de dónde viene la luz. */
.property-card{box-shadow:inset 0 1px 0 rgba(237,244,246,.07),0 26px 60px -30px rgba(2,7,12,.9)}
.property-card:hover{box-shadow:inset 0 1px 0 rgba(237,244,246,.12),0 40px 80px -34px rgba(2,7,12,1)}

/* La banda de cifras sobre fondo claro también gana con un plano propio,
   apenas más frío que el papel. */
.metrics{background:linear-gradient(180deg,rgba(45,102,122,.05),transparent 60%)}

/* La entrada gana peso con un desenfoque que se resuelve: el bloque llega
   como si enfocara, no como si se deslizara. */
.reveal{filter:blur(6px)}
.reveal.on{filter:blur(0)}
.reveal{transition:opacity .9s var(--ease),transform .9s var(--ease),filter .9s var(--ease)}

/* El botón se hunde al pulsarlo y la cruz se separa: masa, no un cambio
   de color instantáneo. */
.button{transition:background .35s var(--ease),color .35s var(--ease),transform .25s var(--ease),border-color .35s var(--ease)}
.button:active{transform:translateY(0) scale(.985)}
.button span{transition:transform .35s var(--ease)}
.button:hover span{transform:translateX(3px)}

@media(prefers-reduced-motion:reduce){
  .reveal{filter:none}
}

/* ---------- Aviso al público en PDF ---------- */
.aviso-modal{
  width:min(1000px,calc(100vw - 32px));height:min(92svh,920px);
  max-width:none;max-height:none;margin:auto;padding:0;
  border:1px solid var(--line);border-radius:4px;
  background:var(--night);color:var(--white);
  flex-direction:column;overflow:hidden;
  animation:legal-in .3s var(--ease);
}
.aviso-modal[open]{display:flex}
.aviso-modal:not([open]){display:none}
.aviso-modal::backdrop{background:rgba(2,7,12,.82);backdrop-filter:blur(6px)}
.aviso-modal-hd{
  min-height:64px;padding:14px 20px;display:flex;align-items:center;
  justify-content:space-between;gap:18px;background:var(--abyss);
  border-bottom:1px solid var(--line);flex:0 0 auto;
}
.aviso-modal-hd h2{margin:0;font-size:15px;line-height:1.35}
.aviso-cerrar{
  border:1px solid var(--line);border-radius:3px;padding:10px 14px;
  background:transparent;color:var(--white);font:inherit;font-size:11px;
  font-weight:700;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;
}
.aviso-cerrar:hover{border-color:var(--ice);color:var(--ice)}
.aviso-cerrar:focus-visible{outline:2px solid var(--oxid);outline-offset:3px}
.aviso-imagen-marco{
  display:flex;align-items:center;justify-content:center;flex:1 1 auto;
  min-height:0;overflow:auto;padding:12px;background:#10171b;
}
.aviso-imagen{display:block;width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain}

@media(max-width:600px){
  .aviso-modal{width:100vw;height:100svh;border:0;border-radius:0}
  .aviso-modal-hd{min-height:60px;padding:12px 16px;gap:12px}
  .aviso-modal-hd h2{font-size:13px}
  .aviso-cerrar{padding:10px;font-size:9px;white-space:nowrap}
}

@media(orientation:landscape) and (max-height:500px){
  .aviso-imagen-marco{align-items:flex-start;justify-content:flex-start}
  .aviso-imagen{width:100%;max-width:none;max-height:none;height:auto}
}
