/* ============================================================================
   Casa del Árbol · Town Houses — sistema de diseño compartido (site.css)
   Se enlaza en las 15 páginas del sitio. No reemplaza el <style> propio de cada
   página (que sigue definiendo su layout) — añade tokens, tipografía, foco de
   teclado, animaciones y utilidades comunes en un solo lugar.
   ========================================================================= */

:root{
  --ink:#0c0c0c;
  --panel:#111111;
  --paper:#f5f2ec;
  --gold:#e0c48a;
  --gold-dim:rgba(224,196,138,.3);
  --whatsapp:#25D366;
  --success:#8fd19e;
  --error:#e08a8a;

  --font-display:'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body:-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif;

  /* Curva de easing propia — editorial, sin rebote, salida lenta */
  --ease-editorial:cubic-bezier(.22,.61,.36,1);

  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-5:24px; --space-6:32px; --space-7:48px; --space-8:64px;
}

/* ---------------------------------------------------------------------------
   Tipografía: serif editorial en títulos grandes, cuerpo intacto (Helvetica/
   Arial, igual que la carpeta de ventas impresa). Se aplica por selector de
   elemento/ID ya presentes en las 15 páginas — sin tocar el HTML de cada una.
   ------------------------------------------------------------------------- */
h1, h2,
#roomName{
  font-family:var(--font-display);
  font-optical-sizing:auto;
  text-wrap:balance;
}

/* ---------------------------------------------------------------------------
   Foco de teclado — visible y coherente con la paleta oscura. Sustituye el
   contorno default del navegador (invisible sobre fondo negro).
   ------------------------------------------------------------------------- */
a, button, input, textarea, [tabindex]{
  outline:none;
}
a:focus-visible, button:focus-visible, input:focus-visible,
textarea:focus-visible, [tabindex]:focus-visible{
  outline:2px solid var(--gold);
  outline-offset:3px;
  border-radius:2px;
}

/* ---------------------------------------------------------------------------
   Skip link — accesible solo al recibir foco (Tab desde el inicio de la página)
   ------------------------------------------------------------------------- */
.skipLink{
  position:fixed; top:-60px; left:12px; z-index:100;
  background:var(--gold); color:#1a1a1a; font-size:13px; font-weight:600;
  padding:10px 18px; border-radius:2px; text-decoration:none;
  transition:top .2s var(--ease-editorial);
}
.skipLink:focus{ top:12px; }

/* ---------------------------------------------------------------------------
   Micro-interacciones: lift/scale sutil en CTAs y tarjetas de unidad, más
   feedback de presión (:active) en todo elemento clicable — sin esto, ningún
   botón del sitio confirmaba visualmente que "escuchó" el clic/tap.
   ------------------------------------------------------------------------- */
.toggleBtn, .navScroll, #whatsappFab, #contactBtn,
#lightboxClose, #mobileNavCloseBtn, #infoBtn, #closeSpecsBtn,
#hero a, button[type="submit"]{
  transition:transform .18s var(--ease-editorial), border-color .18s var(--ease-editorial),
             box-shadow .18s var(--ease-editorial), background-color .18s var(--ease-editorial);
}
/* Los :hover con transform solo en dispositivos con puntero fino (mouse). En
   móvil el tap dispararía el hover y el botón quedaría "pegado" (criterio Emil:
   touch device hover states). El feedback de móvil es el :active de abajo. */
@media (hover:hover) and (pointer:fine){
  #hero a:hover, .navScroll:hover{
    transform:translateY(-2px);
  }
  #whatsappFab:hover, #infoBtn:hover, #lightboxClose:hover,
  #mobileNavCloseBtn:hover, #closeSpecsBtn:hover{
    transform:translateY(-2px) scale(1.04);
  }
}
#hero a:active, .navScroll:active, button[type="submit"]:active{
  transform:translateY(0) scale(.97);
}
#whatsappFab:active, #infoBtn:active, #lightboxClose:active,
#mobileNavCloseBtn:active, #closeSpecsBtn:active{
  transform:scale(.94);
}
.toggleBtn{ transition:background-color .28s var(--ease-editorial), color .28s var(--ease-editorial), transform .18s var(--ease-editorial); }
.toggleBtn:active{ transform:scale(.97); }

@media (prefers-reduced-motion: reduce){
  .toggleBtn, .navScroll, #whatsappFab, #contactBtn,
  #lightboxClose, #mobileNavCloseBtn, #infoBtn, #closeSpecsBtn, #hero a,
  button[type="submit"]{
    transition:none !important;
  }
  #hero a:hover, .navScroll:hover,
  #whatsappFab:hover, #infoBtn:hover, #lightboxClose:hover,
  #mobileNavCloseBtn:hover, #closeSpecsBtn:hover,
  #hero a:active, .navScroll:active, button[type="submit"]:active,
  #whatsappFab:active, #infoBtn:active, #lightboxClose:active,
  #mobileNavCloseBtn:active, #closeSpecsBtn:active, .toggleBtn:active{
    transform:none !important;
  }
}

/* ---------------------------------------------------------------------------
   Selector de casa: pines numerados sobre el plano de conjunto — mismo patrón
   que la carpeta de ventas (.cwPin en carpeta.css / _plan_interactive() en
   tools/build_carpeta_web.py). Cada pin es un <a> que navega directo a la
   ficha de la casa; el polígono hermano (.unit-poly, inline en index.html)
   se resalta al pasar el cursor tanto por el pin como por el propio polígono.
   ------------------------------------------------------------------------- */
.planPin{
  position:absolute; transform:translate(-50%,-50%); z-index:4;
  min-width:44px; min-height:44px; padding:0; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:rgba(224,196,138,.94); border:2px solid #1a1a1a; color:#1a1a1a;
  font-family:inherit; font-size:12.5px; font-weight:700; letter-spacing:.02em;
  text-decoration:none; cursor:pointer;
  /* manipulation = sin espera de doble-tap-para-zoom: el navegador entrega el toque de
     inmediato en vez de reservarse ~300ms por si viene un segundo. */
  touch-action:manipulation; -webkit-tap-highlight-color:transparent;
  transition:transform .15s var(--ease-editorial), background-color .15s var(--ease-editorial);
}
.unit-poly, .cwUnitPoly{ touch-action:manipulation; }
.planPin:focus-visible{ background:#f5f2ec; transform:translate(-50%,-50%) scale(1.1); }
@media (hover:hover) and (pointer:fine){
  .planPin:hover{ background:#f5f2ec; transform:translate(-50%,-50%) scale(1.1); }
}
@media (prefers-reduced-motion:reduce){
  .planPin{ transition:none !important; }
  .planPin:hover, .planPin:focus-visible{ transform:translate(-50%,-50%) !important; }
}

/* ---------------------------------------------------------------------------
   Reveal on scroll — fade + slide sutil, activado por site.js vía
   IntersectionObserver. Los elementos objetivo reciben la clase .reveal al
   cargar y .is-visible al entrar en viewport.
   ------------------------------------------------------------------------- */
.reveal{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .6s var(--ease-editorial), transform .6s var(--ease-editorial);
}
.reveal.is-visible{
  opacity:1;
  transform:translateY(0);
}
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity:1; transform:none; transition:none; }
}

/* ---------------------------------------------------------------------------
   Selector jardín/roof (index.html): crossfade suave entre paneles en vez de
   display:none instantáneo. site.js agrega/quita .panel-hidden.
   ------------------------------------------------------------------------- */
.selectorPanel{
  transition:opacity .28s var(--ease-editorial), transform .28s var(--ease-editorial);
  opacity:1; transform:translateY(0);
}
.selectorPanel.panel-hidden{
  opacity:0; transform:translateY(8px);
  pointer-events:none;
}
@media (prefers-reduced-motion: reduce){
  .selectorPanel{ transition:none; }
}

/* ---------------------------------------------------------------------------
   Layout del selector — plano + columna sticky (toggle + árbol). El plano de
   conjunto es más alto que el viewport (retrato, ~1.26:1), así que sin sticky
   el toggle se va de pantalla al bajar a ver las casas de abajo (G1/G2/G3) y
   hay que subir para cambiar de nivel. La columna se queda fija en pantalla
   mientras se recorre el plano.

   .planeStack superpone los dos .selectorPanel en la misma celda de grid: de
   paso corrige que durante los ~300ms del crossfade (ambos paneles visibles a
   la vez) la sección ya no se estira al doble de alto y la página no brinca.
   ------------------------------------------------------------------------- */
.selectorLayout{
  display:grid;
  grid-template-columns:minmax(0,1fr) 300px;
  gap:48px;
  align-items:start;
}
.planeStack{
  display:grid;
}
.planeStack > .selectorPanel{
  grid-area:1 / 1;
}
.selectorAside{
  align-self:start;
  position:sticky;
  top:90px;
  display:flex;
  flex-direction:column;
  gap:28px;
}

/* Etiqueta del selector: sin ella los dos botones no comunicaban que hay que ELEGIR uno
   (el inactivo era transparente y sin borde, así que no se leía como control). */
.selectorAsideChooser{ display:flex; flex-direction:column; gap:10px; }
.selectorAsideLabel{
  font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:#e0c48a;
}
.selectorAsideLabel .labelCorto{ display:none; }

.toggleWrap{
  display:flex; flex-direction:column; gap:0;
  border:1px solid rgba(224,196,138,.4); border-radius:14px;
  overflow:hidden;
}
/* Control segmentado real: el inactivo tiene superficie y separador propios (antes era
   transparente y no parecía presionable); el activo va en relleno dorado. */
.toggleWrap .toggleBtn{
  padding:14px 20px;
  justify-content:flex-start;
  width:100%;
  border:none; background:rgba(245,242,236,.05); color:#f5f2ec;
  font-size:13px; letter-spacing:.05em; text-transform:uppercase; font-weight:600;
  cursor:pointer; display:flex; align-items:center; gap:8px;
}
.toggleWrap .toggleBtn + .toggleBtn{ border-top:1px solid rgba(224,196,138,.22); }
.toggleWrap .toggleBtn.is-active{ background:#e0c48a; color:#1a1a1a; }
@media (hover:hover) and (pointer:fine){
  .toggleWrap .toggleBtn:not(.is-active):hover{ background:rgba(245,242,236,.12); }
}

/* Cintillo pegado al plano: el dato del tipo activo (7 casas, nivel) y la instrucción táctil.
   Antes eran un párrafo del mismo tamaño que la bajada de la sección, y las dos cifras
   (14 casas arriba, 7 aquí) se leían como si se contradijeran. */
.planoCintillo{
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; max-width:640px;
}
.planoCintilloTipo{
  font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:#e0c48a; font-weight:600;
}
.planoCintilloHint{
  font-size:12.5px; opacity:.62;
}
.planoCintilloHint::before{ content:"→ "; color:#e0c48a; opacity:.8; }
.treeIndicatorDesktopWrap{
  align-self:center;
}

@media (max-width:900px){
  .selectorLayout{ grid-template-columns:1fr; gap:18px; }
  .selectorAside{
    order:-1;
    position:sticky; top:70px; z-index:6;
    flex-direction:row; align-items:center; justify-content:center; gap:16px;
    margin:0 -20px; padding:10px 20px;
    background:rgba(8,8,8,.85); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
    border-bottom:1px solid rgba(224,196,138,.18);
  }
  /* En la barra sticky móvil no cabe la etiqueta larga: va "Elige:" a la izquierda de las píldoras. */
  .selectorAsideChooser{ flex-direction:row; align-items:center; gap:10px; }
  .selectorAsideLabel .labelLargo{ display:none; }
  .selectorAsideLabel .labelCorto{ display:inline; }
  .selectorAsideLabel{ font-size:10px; letter-spacing:.12em; white-space:nowrap; }
  .toggleWrap{ flex-direction:row; width:fit-content; border-radius:30px; }
  /* min-height 44px: la barra sticky es táctil en todo este rango (tablet incluida). */
  .toggleWrap .toggleBtn{ width:auto; justify-content:center; padding:11px 20px; white-space:nowrap; min-height:44px; }
  .toggleWrap .toggleBtn + .toggleBtn{ border-top:none; border-left:1px solid rgba(224,196,138,.22); }
}
/* Teléfono: los dos nombres completos no caben en una línea a 13px. Se aprieta la tipografía en
   vez de partirlos en dos renglones (que hacía crecer la barra sticky y se veía descuidado) y en
   vez de abreviarlos, que perdería el nombre comercial del tipo. */
@media (max-width:640px){
  .selectorAsideLabel{ font-size:9px; letter-spacing:.1em; }
  /* min-height 44px: objetivo táctil mínimo. Apretar la tipografía para que quepan en una línea
     no debe encoger el área presionable. */
  .toggleWrap .toggleBtn{ font-size:10.5px; padding:10px 12px; gap:6px; letter-spacing:.03em; min-height:44px; }
  .toggleWrap .toggleBtn svg{ width:12px; height:12px; }
  .selectorAsideChooser{ gap:8px; }
  .selectorAside{ gap:10px !important; }
  .planoCintillo{ gap:4px; flex-direction:column; }
}
/* Teléfonos angostos (360px y abajo): a esta anchura los dos nombres completos más la etiqueta
   ya no caben ni apretados, y la barra sticky desbordaba a lo ancho. Se retiran los iconos
   decorativos de los botones (~36px) en vez de abreviar los nombres comerciales o partirlos. */
@media (max-width:400px){
  .toggleWrap .toggleBtn svg{ display:none; }
  .toggleWrap .toggleBtn{ font-size:10px; padding:10px 10px; }
  .selectorAside{ gap:8px !important; padding-left:14px !important; padding-right:14px !important; }
  .treeIndicatorDesktopWrap{ display:none !important; }
  .treeMobileIcon{ display:inline-block !important; }
}

/* ---------------------------------------------------------------------------
   Galería — mosaico editorial: grid con tiles de distinto tamaño (una grande,
   una ancha, una alta) en vez de una grilla uniforme de recortes idénticos.
   Las clases mosaic-* controlan el span; en tablet/móvil se resetean a 1x1
   para no romper el layout en columnas angostas.

   El orden de las imágenes en el HTML está calculado para que las áreas sumen
   exactamente 4 columnas x 5 filas (20 celdas) y el mosaico cierre sin huecos.
   Si se agrega o quita una imagen hay que recalcular los spans; `dense` queda
   como red de seguridad para que un hueco se rellene en vez de quedar visible.
   ------------------------------------------------------------------------- */
.galleryGrid{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  grid-auto-rows:150px;
  grid-auto-flow:row dense;
  gap:12px;
}
/* Los <picture> usan display:contents para que el <img> sea el tile del grid,
   pero eso promueve también al <source>, al que Chrome le da caja (display:block)
   y ocupa una celda vacía. Sin esto el mosaico sale con un hueco por imagen. */
.galleryGrid source{ display:none; }
.galleryItem{
  display:block;
  width:100%; height:100%;
  object-fit:cover; cursor:pointer; border-radius:2px;
  transition:transform .18s var(--ease-editorial), filter .18s var(--ease-editorial);
}
@media (hover:hover) and (pointer:fine){
  .galleryItem:hover{ transform:scale(1.02); filter:brightness(1.06); }
}
.galleryItem:active{ transform:scale(.99); }
.mosaic-big{ grid-column:span 2; grid-row:span 2; }
.mosaic-wide{ grid-column:span 2; grid-row:span 1; }
.mosaic-tall{ grid-column:span 1; grid-row:span 2; }
@media (prefers-reduced-motion: reduce){
  .galleryItem{ transition:none; }
  .galleryItem:hover, .galleryItem:active{ transform:none; filter:none; }
}

@media (max-width:900px) and (min-width:641px){
  /* A 3 columnas los spans de 4 columnas no cierran: se resetea a grilla
     uniforme (12 imágenes / 3 = 4 filas exactas). */
  .galleryGrid{ grid-template-columns:repeat(3, 1fr); grid-auto-rows:130px; }
  .mosaic-big, .mosaic-wide, .mosaic-tall{ grid-column:span 1; grid-row:span 1; }
}
@media (max-width:640px){
  .galleryGrid{ grid-template-columns:repeat(2, 1fr) !important; grid-auto-rows:120px; }
  .mosaic-big, .mosaic-wide, .mosaic-tall{ grid-column:span 1 !important; grid-row:span 1 !important; }
}

/* ---------------------------------------------------------------------------
   Lightbox — fade en vez de aparición abrupta, más flechas prev/next visibles
   y contador para recorrer la galería completa sin cerrar cada vez (además
   del teclado y el swipe táctil, ya cableados en site.js).
   ------------------------------------------------------------------------- */
#lightbox{
  position:fixed; inset:0; z-index:80; display:none;
  align-items:center; justify-content:center;
  background:rgba(6,6,6,.95); padding:40px;
  opacity:0;
  transition:opacity .28s var(--ease-editorial);
}
#lightbox.is-open{ opacity:1; }
@media (prefers-reduced-motion: reduce){
  #lightbox{ transition:none; }
}
#lightboxImg{ max-width:100%; max-height:100%; object-fit:contain; user-select:none; }
#lightboxClose{
  position:absolute; top:24px; right:32px;
  background:none; border:1px solid rgba(245,242,236,.4); color:#f5f2ec;
  width:36px; height:36px; border-radius:50%; cursor:pointer; font-size:16px;
}
.lightboxNavBtn{
  position:absolute; top:50%; transform:translateY(-50%);
  background:rgba(20,20,20,.55); border:1px solid rgba(245,242,236,.3); color:#f5f2ec;
  width:48px; height:48px; border-radius:50%; cursor:pointer; font-size:26px; line-height:1;
  display:flex; align-items:center; justify-content:center;
}
.lightboxPrevBtn{ left:16px; }
.lightboxNextBtn{ right:16px; }
.lightboxCounter{
  position:absolute; bottom:22px; left:50%; transform:translateX(-50%);
  font-size:13px; letter-spacing:.05em; color:rgba(245,242,236,.7);
}
@media (max-width:640px){
  #lightbox{ padding:16px; }
  .lightboxNavBtn{ width:40px; height:40px; font-size:22px; }
  .lightboxPrevBtn{ left:6px; }
  .lightboxNextBtn{ right:6px; }
}

/* ---------------------------------------------------------------------------
   Menú móvil — slide/fade de entrada en vez de aparición abrupta
   ------------------------------------------------------------------------- */
.mobileNavPanel{
  opacity:0;
  transform:translateY(-8px);
  transition:opacity .26s var(--ease-editorial), transform .26s var(--ease-editorial);
}
.mobileNavPanel.open{
  opacity:1;
  transform:translateY(0);
}
@media (prefers-reduced-motion: reduce){
  .mobileNavPanel{ transition:none; }
}

/* ---------------------------------------------------------------------------
   Ficha técnica móvil (#specsPanel, casas/*.html) — fade + slide de entrada en
   vez de display:block/none instantáneo. Abierto/cerrado por
   CDA.toggleSpecsPanel (site.js), que agrega/quita .is-open.
   ------------------------------------------------------------------------- */
#specsPanel{
  opacity:0;
  transform:translateY(14px);
  transition:opacity .26s var(--ease-editorial), transform .26s var(--ease-editorial);
}
#specsPanel.is-open{
  opacity:1;
  transform:translateY(0);
}
@media (prefers-reduced-motion: reduce){
  #specsPanel{ transition:none; }
}

/* ---------------------------------------------------------------------------
   Sheet genérico (CDA.openSheet/closeSheet, site.js) — bottom sheet en móvil
   (88dvh) / panel lateral en escritorio ≥1024px (480px). Pensado para las
   futuras fichas de unidad de la carpeta de ventas web (14 casas). El
   posicionamiento (transform) lo controla el JS del motor de springs frame a
   frame — aquí solo van la posición de reposo por defecto (antes de que el JS
   corra), tamaño, tipografía/superficie y el fallback de movimiento reducido.

   #specsPanel (casas/*.html, ficha técnica móvil ya existente) NO lleva esta
   clase — sigue con su propio bloque de arriba (overlay de pantalla completa)
   sin cambios; se migró al mismo motor JS en modo "legacy" (ver
   CDA.toggleSpecsPanel), que no toca su CSS.
   ------------------------------------------------------------------------- */
.cdaSheetBackdrop{
  position:fixed; inset:0; z-index:59;
  background:rgba(6,6,6,.55);
  opacity:0; visibility:hidden;
  transition:opacity .28s var(--ease-editorial), visibility .28s;
}
.cdaSheetBackdrop.is-open{ opacity:1; visibility:visible; }

.cdaSheet{
  position:fixed; z-index:60;
  box-sizing:border-box;
  background:var(--panel); color:var(--paper);
  box-shadow:0 -10px 34px rgba(0,0,0,.45);
  overflow-y:auto; -webkit-overflow-scrolling:touch;
  left:0; right:0; bottom:0;
  height:88dvh; max-height:88dvh;
  border-radius:18px 18px 0 0;
  padding:14px 24px calc(24px + env(safe-area-inset-bottom));
  transform:translateY(100%);
  visibility:hidden; pointer-events:none;
}
.cdaSheet.is-open{ visibility:visible; pointer-events:auto; }
.cdaSheet.is-dragging{ box-shadow:0 -4px 18px rgba(0,0,0,.3); }
.cdaSheetHandle{
  width:36px; height:4px; border-radius:2px;
  background:rgba(245,242,236,.35);
  margin:0 auto 18px; touch-action:none;
}
@media (min-width:1024px){
  .cdaSheet{
    left:auto; right:0; top:0; bottom:0;
    width:480px; max-width:92vw; height:100%; max-height:100%;
    border-radius:0; padding:28px 32px;
    transform:translateX(100%);
    box-shadow:-10px 0 34px rgba(0,0,0,.45);
  }
  .cdaSheetHandle{ display:none; }
}
@media (prefers-reduced-motion: reduce){
  /* Sin spring ni transform: solo fade de opacidad, 120ms. El JS del motor
     detecta este media query y no anima transform en absoluto en este modo. */
  .cdaSheet{
    transition:opacity .12s linear; transform:none !important;
    opacity:0;
  }
  .cdaSheet.is-open{ opacity:1; }
  .cdaSheetBackdrop{ transition:opacity .12s linear; }
}

/* ---------------------------------------------------------------------------
   Confirmación del formulario de contacto (#formMsg / #formMsgDepto) — fade +
   slide sutil en vez de display:block instantáneo. Mostrado por
   CDA.showFormMessage (site.js), que agrega .is-visible.
   ------------------------------------------------------------------------- */
#formMsg, #formMsgDepto{
  opacity:0;
  transform:translateY(6px);
  transition:opacity .3s var(--ease-editorial), transform .3s var(--ease-editorial);
}
#formMsg.is-visible, #formMsgDepto.is-visible{
  opacity:1;
  transform:translateY(0);
}
@media (prefers-reduced-motion: reduce){
  #formMsg, #formMsgDepto{ transition:none; }
}

/* ---------------------------------------------------------------------------
   Scrollytelling (casas/*.html) — crossfade más lento y con easing propio en
   vez de .05s linear; Ken Burns (zoom+paneo) sincronizado al scroll vía JS
   inline de cada página (variable lp en onScroll) — sin transition en
   transform porque el valor ya se recalcula en cada tick de scroll.
   ------------------------------------------------------------------------- */
.photo{
  transition:opacity .32s var(--ease-editorial) !important;
  transform:scale(1.015);
  will-change:transform;
}
@media (prefers-reduced-motion: reduce){
  .photo{ transition:opacity .15s linear !important; transform:none; }
}

/* ---------------------------------------------------------------------------
   Mapa de contacto (Google Maps embed) — filtro oscuro para que no rompa la
   identidad del sitio (el embed default de Google es blanco). Se aplica a
   cualquier iframe de Google Maps sin tocar el HTML de cada página.
   ------------------------------------------------------------------------- */
iframe[src*="google.com/maps"]{
  filter:invert(92%) hue-rotate(180deg) contrast(88%) brightness(.95) saturate(1.15);
}

/* ---------------------------------------------------------------------------
   Breakpoint intermedio (tablet, ~900px) — hoy el sitio salta directo de
   desktop a 640px. Suaviza el tramo intermedio en los layouts más apretados.
   ------------------------------------------------------------------------- */
@media (max-width:900px) and (min-width:641px){
  .selectorGrid{ gap:32px !important; }
  .contactGrid, .contactGridDepto{ gap:36px !important; }
}

/* ---------------------------------------------------------------------------
   Header del recorrido de casa (casas/*.html): el título arriba-izquierda
   (.houseTitle, ancla en left:66px) y el nav de rooms (#nav, centrado en
   left:50%) comparten fila. Sin límite, el título crece hasta invadir el nav
   (se veía "...Casa R1ESTANCIA" a ~1440px y por debajo). Se acota el título con
   un max-width responsivo — deja de crecer justo antes de donde arranca el nav
   centrado (navLeft ≈ 50% − navW/2; se reserva ~16px de aire) — y se recorta con
   elipsis si no cabe. El piso (110px) evita que desaparezca en anchos chicos.
   Solo aplica donde el nav es visible (>640px); en móvil el nav se oculta.
   ------------------------------------------------------------------------- */
@media (min-width:641px){
  .houseTitle{
    max-width: max(110px, calc(50% - 375px));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ---------------------------------------------------------------------------
   Recorrido de casa en móvil, retrato (casas/*.html) — antes duplicado
   idéntico en las 14 páginas vía <style> inline; centralizado aquí. Oculta el
   plano/ficha de escritorio y muestra la versión compacta (plano chico +
   botón "i" que abre #specsPanel). #whatsappFab también existe en index.html
   con su propio estilo — se ancla a `.stage` (exclusivo de casas/*.html) para
   no filtrar esta regla ahí.
   ------------------------------------------------------------------------- */
@media (max-width:640px){
  #planActiveWrap{ display:none !important; }
  #planMinorStack{ display:none !important; }
  #planMobile{ display:block !important; }
  #infoBtn{ display:flex !important; }
  #specsBox{ display:none !important; }
  #roomName{ font-size:24px !important; }
  #roomDesc{ display:none !important; }
  #nav{ display:none !important; }
  #progress{ display:none !important; }
  #contactBtn{ font-size:10px !important; padding:8px 14px !important; right:20px !important; bottom:24px !important; }
  .stage #whatsappFab{ width:44px !important; height:44px !important; right:20px !important; bottom:66px !important; }
  .contactGridDepto{ display:flex !important; flex-direction:column !important; }
  .contactFormBlockDepto{ order:1 !important; }
  .contactMapBlockDepto{ order:2 !important; }
}

/* ---------------------------------------------------------------------------
   Recorrido de casa en móvil, teléfono en horizontal (landscape) — mismo
   criterio que el bloque de arriba (plano compacto + botón "i" en vez del
   layout de escritorio), con tamaños/posiciones propios: la viewport es corta
   (~375-430px de alto) y ancha (~700-950px), así que los valores de portrait
   (pensados para poco ancho y mucho alto) se solaparían con los botones
   inferiores. El tope de altura (480px) deja fuera tablets (iPad landscape
   ≥744px de alto); pointer:coarse descarta ventanas de escritorio angostas
   redimensionadas con mouse. Valores de partida — ajustados con agent-browser
   contra anchos reales (iPhone SE/8/14 Pro Max) antes de darlos por buenos.
   ------------------------------------------------------------------------- */
@media (max-height:480px) and (orientation:landscape) and (pointer:coarse){
  #planActiveWrap{ display:none !important; }
  #planMinorStack{ display:none !important; }
  #planMobile{
    display:block !important;
    top:50px !important; right:10px !important;
    width:170px !important; max-width:170px !important;
  }
  #infoBtn{
    display:flex !important;
    top:54px !important; left:20px !important;
    width:34px !important; height:34px !important;
    font-size:15px !important;
  }
  #specsBox{ display:none !important; }
  /* Aquí el nav está oculto: el título no compite con él, así que se le
     devuelve ancho (deja aire para el plano compacto a la derecha). */
  .houseTitle{ max-width: calc(100% - 210px) !important; }
  #roomName{ font-size:18px !important; max-width:260px; }
  #roomDesc{ display:none !important; }
  #nav{ display:none !important; }
  #progress{ display:none !important; }
  #contactBtn{ font-size:9px !important; padding:6px 10px !important; right:16px !important; bottom:12px !important; }
  .stage #whatsappFab{ width:36px !important; height:36px !important; right:16px !important; bottom:46px !important; }
  .contactGridDepto{ display:flex !important; flex-direction:column !important; }
  .contactFormBlockDepto{ order:1 !important; }
  .contactMapBlockDepto{ order:2 !important; }
}

/* ---------------------------------------------------------------------------
   CTA sticky (solo index.html) — pastilla "Pedir informes" fija abajo-izquierda
   que complementa el FAB de WhatsApp (abajo-derecha). Oculta durante el hero
   (el hero ya tiene sus propios CTA) y mientras la sección de contacto está a la
   vista; el JS de index.html alterna .is-visible con IntersectionObserver.
   ------------------------------------------------------------------------- */
#stickyCta{
  position:fixed; left:24px; bottom:24px; z-index:20;
  display:inline-flex; align-items:center; gap:8px;
  padding:13px 22px; border-radius:999px;
  background:#e0c48a; color:#1a1a1a; text-decoration:none;
  font-size:12px; letter-spacing:.07em; text-transform:uppercase; font-weight:600;
  box-shadow:0 6px 18px rgba(0,0,0,.4);
  opacity:0; visibility:hidden; transform:translateY(12px);
  transition:opacity .35s ease, transform .35s ease, visibility .35s;
}
#stickyCta.is-visible{ opacity:1; visibility:visible; transform:none; }
#stickyCta svg{ flex-shrink:0; }
@media (prefers-reduced-motion: reduce){
  #stickyCta{ transition:opacity .2s ease, visibility .2s; transform:none; }
  #stickyCta:not(.is-visible){ transform:none; }
}
@media (max-width:640px){
  #stickyCta{ left:16px; bottom:20px; padding:11px 18px; font-size:11px; }
}

/* ---------------------------------------------------------------------------
   Plano a pantalla completa (lightbox compartido, motor en site.js
   CDA.initPlanLightbox). Mismo lenguaje visual que el de la galería. Lo usan la
   carpeta de ventas web (.cwPlanBtn) y las páginas de casa (planos tappables).
   ------------------------------------------------------------------------- */
.cdaPlanLightbox{
  position:fixed; inset:0; z-index:85; display:none; align-items:center; justify-content:center;
  background:rgba(6,6,6,.95); padding:24px; opacity:0; transition:opacity .24s var(--ease-editorial);
}
.cdaPlanLightbox.is-open{ opacity:1; }
.cdaPlanLightbox img{ max-width:100%; max-height:100%; object-fit:contain; background:#f3efe7; border-radius:3px; }
.cdaPlanLightbox #planLightboxClose{
  position:absolute; top:20px; right:24px; background:none; border:1px solid rgba(245,242,236,.4);
  color:var(--paper); width:36px; height:36px; border-radius:50%; cursor:pointer; font-size:16px;
}
/* Navegación entre los planos de una misma casa (F6): reutiliza el lenguaje de las flechas de la
   galería. El JS las oculta cuando el grupo tiene un solo plano. El pie muestra nivel y contador —
   dos plantas del mismo tamaño en blanco y negro se distinguen por su etiqueta, no por la imagen.
   Las reglas cubren los DOS visores: .cdaPlanLightbox (páginas de casa) y .cwPlanLightbox
   (carpeta de ventas), que comparten el mismo motor y los mismos IDs. carpeta.css también carga
   este archivo, así que no hay que duplicar nada allá. */
.cdaPlanLightbox .lightboxNavBtn,
.cwPlanLightbox .lightboxNavBtn{ z-index:2; }
.cdaPlanLightbox img,
.cwPlanLightbox img{ max-height:calc(100% - 56px); }
#planLightboxCaption{
  position:absolute; bottom:20px; left:50%; transform:translateX(-50%);
  font-size:11px; letter-spacing:.12em; text-transform:uppercase;
  color:rgba(245,242,236,.75); white-space:nowrap;
}
@media (max-width:640px){
  .cdaPlanLightbox{ padding:16px; }
  #planLightboxCaption{ font-size:10px; bottom:14px; }
}
@media (prefers-reduced-motion:reduce){ .cdaPlanLightbox{ transition:none !important; } }

/* Botón "Ver planos" bajo la columna de info (solo escritorio: en móvil #specsBox está oculto y
   los planos ya salen dentro de la ficha del botón "i"). Abre el visor en el nivel del cuarto
   activo, con las flechas para recorrer el resto — lo cablea casas.js. */
.specsPlanBtn{
  margin-top:16px; padding:9px 16px; border-radius:999px; cursor:pointer;
  border:1px solid rgba(224,196,138,.55); background:rgba(20,20,20,.45); color:#e0c48a;
  font-size:11px; letter-spacing:.12em; text-transform:uppercase; font-weight:600;
  display:inline-flex; align-items:center; gap:7px;
  transition:background-color .25s var(--ease-editorial), transform 160ms var(--ease-editorial);
  backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);
}
@media (hover:hover) and (pointer:fine){
  .specsPlanBtn:hover{ background:rgba(224,196,138,.16); }
}
.specsPlanBtn:active{ transform:scale(.96); }
@media (prefers-reduced-motion: reduce){
  .specsPlanBtn{ transition:none; }
  .specsPlanBtn:active{ transform:none; }
}

/* Afordancia "ampliar" sobre un plano tappable en las páginas de casa. */
.casaPlanZoom{
  position:absolute; right:6px; bottom:6px; z-index:2; display:inline-flex; align-items:center; gap:4px;
  padding:4px 8px; border-radius:999px; border:1px solid rgba(245,242,236,.3);
  background:rgba(20,20,20,.6); color:#f5f2ec; font-size:8px; letter-spacing:.1em;
  text-transform:uppercase; pointer-events:none; backdrop-filter:blur(2px);
}
[data-plan-src]{ cursor:zoom-in; }
/* El badge "Ampliar" solo en la planta activa (grande), no en las miniaturas. */
#planMinorStack .casaPlanZoom{ display:none; }
/* En móvil el plano del recorrido es chico: badge aún más discreto. */
@media (max-width:640px){ #planMobile .casaPlanZoom{ font-size:7.5px; padding:3px 7px; } }

/* Pista de scroll de las páginas de casa: el chevron baja en bucle para invitar a scrollear.
   El posicionamiento vive aquí (no inline) para que la media query móvil pueda reubicarla. */
.casaScrollHint{ position:absolute; z-index:5; left:50%; bottom:26px; transform:translateX(-50%); }
@keyframes casaScrollBob{ 0%{ transform:translateY(-2px); opacity:.5; } 50%{ transform:translateY(3px); opacity:1; } 100%{ transform:translateY(-2px); opacity:.5; } }
.casaScrollHint .casaScrollChevron{ animation:casaScrollBob 1.7s var(--ease-editorial) infinite; }
@media (prefers-reduced-motion: reduce){ .casaScrollHint .casaScrollChevron{ animation:none; } }
/* En móvil el nombre del cuarto ocupa la esquina inferior: la pista sube al render para no encimarse. */
@media (max-width:640px){ .casaScrollHint{ bottom:auto; top:58%; } }

/* ---------------------------------------------------------------------------
   Feedback táctil (móvil) — Fase 4, criterio Emil Kowalski. Completa los
   presionables que el bloque de micro-interacciones de arriba no cubría con
   :active (nav del recorrido, planos tappables, botón Contacto de la ficha,
   cierre del lightbox de planos). Solo transform (GPU), 160ms, reduced-motion ok.
   ------------------------------------------------------------------------- */
#contactBtn, #nav span, [data-plan-src], #planLightboxClose{
  transition: transform 160ms var(--ease-editorial);
}
#planLightboxClose:active{ transform: scale(.92); }
#contactBtn:active{ transform: scale(.97); }
#nav span:active{ transform: scale(.94); }
[data-plan-src]:active{ transform: scale(.985); }
@media (prefers-reduced-motion: reduce){
  #contactBtn, #nav span, [data-plan-src], #planLightboxClose{ transition: none; }
  #contactBtn:active, #nav span:active, [data-plan-src]:active, #planLightboxClose:active{ transform: none; }
}

/* ---------------------------------------------------------------------------
   Sección "El proyecto" (index) — manifiesto "Casas, no departamentos" + los
   dos tipos (Garden / Roof) con foto. Fase 5. Lenguaje visual del index:
   serif editorial, dorado, tarjetas oscuras, reveal on scroll.
   ------------------------------------------------------------------------- */
.proyectoStats{
  display:flex; gap:clamp(28px,5vw,60px); flex-wrap:wrap; align-items:flex-end;
  margin:0 0 60px; padding-bottom:44px; border-bottom:1px solid rgba(245,242,236,.1);
}
.proyectoStat .n{ font-family:var(--font-display); font-optical-sizing:auto; font-size:clamp(32px,5vw,50px); font-weight:500; color:#f5f2ec; line-height:1; }
.proyectoStat .n small{ font-size:.4em; letter-spacing:.02em; opacity:.75; margin-left:2px; }
.proyectoStat .l{ font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:#e0c48a; margin-top:10px; }

.tiposGrid{ display:grid; grid-template-columns:1fr 1fr; gap:26px; }
@media (max-width:760px){ .tiposGrid{ grid-template-columns:1fr; gap:20px; } }

.tipoCard{
  position:relative; border:1px solid rgba(224,196,138,.2); border-radius:12px; overflow:hidden;
  background:rgba(255,255,255,.02); display:flex; flex-direction:column; cursor:pointer;
  transition:border-color .3s var(--ease-editorial), transform .3s var(--ease-editorial);
}

/* Toda la tarjeta es el área clickeable, no solo el enlace de abajo (patrón "stretched link"):
   el ::after del ancla se estira sobre la tarjeta entera. Se hace así y no con un handler de JS
   sobre el <article> para que siga habiendo UN SOLO elemento interactivo por tarjeta — el ancla
   real, con su destino visible en la barra de estado y navegable por teclado. CDA.initTipoSelect
   (site.js) no cambia: el clic burbujea del ::after al ancla, que ya lleva data-select-tipo. */
.tipoLink::after{ content:""; position:absolute; inset:0; z-index:1; }
/* El tag flota en z-index:2 sobre la foto: sin esto se comería los clics de esa esquina. */
.tipoCardTag{ pointer-events:none; }
/* Foco de teclado: se marca la tarjeta completa, que es lo que el enlace realmente activa. */
.tipoCard:has(.tipoLink:focus-visible){ outline:2px solid #e0c48a; outline-offset:3px; }
.tipoLink:focus-visible{ outline:none; }
.tipoCard:active{ transform:scale(.995); }
@media (hover:hover) and (pointer:fine){
  .tipoCard:hover{ border-color:rgba(224,196,138,.5); transform:translateY(-3px); }
  .tipoCard:hover .tipoCardImg img{ transform:scale(1.045); }
  .tipoCard:hover .tipoLink .arrow{ transform:translateX(4px); }
}
.tipoCardImg{ position:relative; aspect-ratio:16/10; overflow:hidden; background:#161616; }
.tipoCardImg img{ width:100%; height:100%; object-fit:cover; display:block; transition:transform .55s var(--ease-editorial); }
.tipoCardTag{
  position:absolute; left:14px; bottom:14px; z-index:2; font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:#1a1a1a; background:rgba(224,196,138,.92); padding:6px 11px; border-radius:999px;
}
.tipoCardBody{ padding:24px 26px 26px; display:flex; flex-direction:column; gap:13px; flex:1; }
.tipoLabel{ font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:#e0c48a; }
.tipoCard h3{ font-family:var(--font-display); font-optical-sizing:auto; font-size:clamp(23px,3vw,28px); font-weight:500; margin:0; color:#f5f2ec; letter-spacing:-.01em; }
.tipoDesc{ font-size:14.5px; line-height:1.62; opacity:.82; margin:0; }
.tipoChips{ display:flex; gap:8px; flex-wrap:wrap; margin-top:2px; }
.tipoChip{ font-size:10.5px; letter-spacing:.05em; text-transform:uppercase; color:#f5f2ec; border:1px solid rgba(245,242,236,.2); border-radius:999px; padding:5px 11px; opacity:.85; }
.tipoLink{ margin-top:auto; padding-top:10px; font-size:12.5px; letter-spacing:.06em; text-transform:uppercase; color:#e0c48a; text-decoration:none; display:inline-flex; align-items:center; gap:8px; }
.tipoLink .arrow{ transition:transform .18s var(--ease-editorial); }
.tipoLink:active{ opacity:.7; }
@media (prefers-reduced-motion: reduce){
  .tipoCard, .tipoCardImg img, .tipoLink .arrow{ transition:none; }
  .tipoCard:hover, .tipoCard:hover .tipoCardImg img, .tipoCard:hover .tipoLink .arrow{ transform:none; }
}
