/*
  motion.css (2026-09-04, actualizado)
  Capa de movimiento para todo el sitio publico: reveal-on-scroll (mas perceptible
  que la primera version), hover/tactile feedback, y skeleton loading para las
  cargas via AJAX (catalogo de proyectos). Sin dependencias nuevas.
  Respeta prefers-reduced-motion en su totalidad.
*/

/* ---------- CLS fix: reserva de altura para los carruseles hero ---------- */
/* owl-carousel oculta el carrusel (display:none) hasta que su JS termina de
   inicializarlo -- eso hace que el contenedor pase de 0px a ~720px de golpe,
   justo arriba del pliegue, lo que explica gran parte del CLS de 0.81 medido
   en PageSpeed Insights (2026-09-04). Se reserva la altura conocida desde el
   primer render para que ese salto no exista. overflow:hidden recorta las
   demas slides mientras tanto -- solo se ve la primera, como una imagen fija,
   hasta que owl.js las organiza en carrusel real. #carrouselBannerProyecto
   (2026-09-05: ya no usa Owl, era un carrusel de un solo item) nunca llega
   a tener .owl-loaded, asi que esta regla le queda permanente -- coincide
   a proposito con la altura fija que ya trae su imagen (720px/678.75px). */
#carrouselBannerHome:not(.owl-loaded),
#carrouselBannerHomeMobile:not(.owl-loaded),
#carrouselBannerProyecto:not(.owl-loaded) {
    display: block !important;
    overflow: hidden;
    height: 80vh;
}

@media (min-width: 1300px) {
    #carrouselBannerHome:not(.owl-loaded),
    #carrouselBannerHomeMobile:not(.owl-loaded),
    #carrouselBannerProyecto:not(.owl-loaded) {
        height: 720px;
    }
}

/* ---------- Reveal on scroll ---------- */
.reveal-on-scroll {
    opacity: 0;
    transform: translateY(32px);
    transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
    will-change: transform, opacity;
}

.reveal-on-scroll.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* ---------- Hover / tactile feedback (tarjetas, botones) ---------- */
.bannerProyecto,
.btnAmarillo,
.btnTransparente,
.pDeptos_proyecto,
.contenedorEquipamiento_proyecto > div {
    transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.bannerProyecto:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
}

/* Zoom tipo Ken Burns al pasar el mouse sobre la foto de portada de un
   proyecto (catalogo de /proyectos-venta): mismo efecto del banner hero
   del home, pero solo sobre la <img> -- las pildoras de estado
   (ULTIMAS UNIDADES, etc.) y el texto del proyecto son hermanos de la
   imagen, nunca hijos, asi que no se ven afectados por este transform. */
.bannerProyecto {
    overflow: hidden;
}

/* CLS real (2026-09-05): estas fotos son dinamicas (portada_web de cada
   proyecto, tamano variable desde la BD), asi que no se les puede poner
   width/height explicito como al resto de las imagenes del sitio -- pero
   la convencion de subida de archivos es siempre 1920x1080 (confirmado
   revisando los nombres de archivo reales: toesca_1920x1080.jpg,
   zanartu_1920x1080-...jpg, neoflorida-3_1920x1080.jpg, etc.), asi que
   aspect-ratio reserva el espacio real sin necesitar el pixel exacto.
   Verificado con CrUX real: CLS de campo 0.53 en /proyectos-venta, el
   contenedor colapsaba a 0 hasta que la imagen cargaba. */
.bannerProyecto img {
    aspect-ratio: 1920 / 1080;
    width: 100%;
    height: auto;
    display: block;
    transition: transform 0.6s ease-out;
}

/* Mismo CLS real, en las fotos de equipamiento de la ficha de proyecto
   (galeria "Lavanderia/Hall/Gimnasio/..."): tambien dinamicas por
   proyecto, tambien con convencion de aspect-ratio consistente en los
   archivos reales (1920x1200 / 3840x2400, ambos 8:5). */
.imgEquipamientoFoto {
    aspect-ratio: 8 / 5;
    width: 100%;
    height: auto;
    display: block;
}

.bannerProyecto:hover img {
    transform: scale(1.08);
}

/* ---------- Menu amarillo de anclas: indicador que se desliza con el scroll ---------- */
/* Un triangulito debajo del item activo (BENEFICIOS/EL PROYECTO/UBICACION/
   DEPTOS/EQUIPAMIENTO/PLANTAS) que se desplaza suavemente de un item a otro
   a medida que el usuario hace scroll por la ficha de proyecto -- ver
   menuAmarilloScrollSpy() en public/js/proyecto/main.js. */
.contenedorMenuAmarillo.proyecto {
    position: relative;
}

.indicadorMenuAmarillo {
    position: absolute;
    bottom: 2px;
    left: 0;
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-bottom: 6px solid #1a1a1a;
    opacity: 0;
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.25s ease;
    pointer-events: none;
}

.indicadorMenuAmarillo.indicadorMenuAmarillo--activo {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .indicadorMenuAmarillo {
        transition: opacity 0.25s ease;
    }
}

/* ---------- CTA principal "Solicitud de cotizacion": negro solido + pulso ---------- */
/* Es el punto de conversion mas importante del sitio -- se invierte el
   patron habitual de .btnTransparente (outline por defecto, solido al
   hacer hover) para que este boton parta solido y destaque desde el
   primer render, y se agrega un pulso lento e infinito para llamar la
   atencion sin ser invasivo. El pulso se detiene al hacer hover (el
   usuario ya esta interactuando) y respeta prefers-reduced-motion. */
.btnTransparente.cotizar_depto {
    background-color: #000000;
    border-color: #000000;
    color: #ffffff;
    animation: cotizar-pulse 2.6s ease-in-out infinite;
}

.btnTransparente.cotizar_depto:hover {
    background-color: #FFB719;
    border-color: #FFB719;
    color: #1a1a1a;
    animation: none;
}

@keyframes cotizar-pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.035);
    }
}

.btnAmarillo:active,
.btnTransparente:active {
    transform: scale(0.98);
}

/* ---------- Skeleton loading ---------- */
.skeleton-card {
    border-radius: 6px;
    overflow: hidden;
    background: #eceff1;
}

.skeleton-shimmer {
    position: relative;
    overflow: hidden;
    background: #e4e7eb;
}

.skeleton-shimmer::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(
        90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.55) 50%,
        rgba(255, 255, 255, 0) 100%
    );
    animation: skeleton-shimmer-sweep 1.4s ease-in-out infinite;
}

.skeleton-card__imagen {
    width: 100%;
    aspect-ratio: 4 / 3;
}

.skeleton-card__linea {
    height: 14px;
    margin: 10px 14px;
    border-radius: 4px;
    background: #e4e7eb;
}

.skeleton-card__linea--corta {
    width: 55%;
}

@keyframes skeleton-shimmer-sweep {
    100% {
        transform: translateX(100%);
    }
}

/* ---------- Cotizador de plantas: estado de carga al cambiar de tipologia ---------- */
/* La imagen del plano se atenua mientras espera la respuesta de
   api/plantas/traerplanta, en vez de quedar estatica sin ningun feedback. */
#imgCotizador {
    transition: opacity 0.2s ease-out;
}

#imgCotizador.cotizador-cargando {
    opacity: 0.35;
}

/* ---------- Banner hero del home: zoom tipo "camara entrando en la foto" ---------- */
/* Ken Burns clasico: la slide activa del carrusel escala lentamente hacia
   adentro durante todo el tiempo que esta visible. El desborde lo recorta
   .owl-stage-outer (overflow:hidden, ya viene asi de owl.carousel core).
   Se anima background-size (no transform): el texto/botones del banner son
   hijos del mismo <div class="item bannerHome"> que tiene la imagen de
   fondo -- animar transform:scale() en ese div escalaba tambien el texto y
   los botones. background-size solo afecta el fondo, nunca a los hijos. */
#carrouselBannerHome,
#carrouselBannerHomeMobile {
    position: relative;
}

#carrouselBannerHome .item.bannerHome,
#carrouselBannerHomeMobile .item.bannerHome {
    background-size: 100%;
    will-change: background-size;
}

#carrouselBannerHome .owl-item.active .item.bannerHome,
#carrouselBannerHomeMobile .owl-item.active .item.bannerHome {
    animation: kenburns-zoom-hero 6.5s ease-out forwards;
}

@keyframes kenburns-zoom-hero {
    from {
        background-size: 100%;
    }
    to {
        background-size: 114%;
    }
}

/* ---------- Banner hero de la ficha de proyecto: mismo zoom, sin carrusel ---------- */
/* A diferencia del home, esto no es un carrusel real -- corre una sola vez
   al cargar la pagina (forwards), no depende de .owl-item.active. La
   version mobile es background-image (mismo enfoque que el home); la
   version desktop es un <img> real, asi que ahi se anima transform en vez
   de background-size -- el <img> no tiene hijos de texto, es seguro. */
#carrouselBannerProyecto {
    position: relative;
}

/* Bug real encontrado al quitar el carrusel (2026-09-05): Owl Carousel
   envolvia el <img>/background-image en su propio .owl-item con posicion
   y z-index que -de hecho- dejaban el texto arriba. Sin ese wrapper, el
   texto (position:absolute, z-index:auto) quedaba tapado por la imagen
   -- verificado forzando z-index en el navegador real, no una hipotesis.
   Se fija explicitamente el orden correcto. */
#carrouselBannerProyecto .contenedorInformacionBanner.proyecto {
    z-index: 2;
}

#carrouselBannerProyecto .bannerProyectoHeroImgMobile {
    animation: kenburns-zoom-hero 6.5s ease-out forwards;
}

/* Bug real reportado por el usuario: la imagen no llegaba al ancho
   completo en viewports anchos. Owl Carousel forzaba el ancho del
   <img> vía JS (inline width en .owl-item); sin ese wrapper, el <img>
   solo tenía `height:720px` inline y sin `width:100%`, el navegador
   calculaba el ancho a partir del aspect-ratio real de la foto
   (1920x1080), quedando más angosto que el contenedor en pantallas
   anchas. object-fit:cover llena el ancho completo y recorta el sobrante
   verticalmente, igual que hace `background-size:cover` en la mobile. */
#carrouselBannerProyecto .bannerProyectoHeroImg {
    width: 100%;
    object-fit: cover;
    transform: scale(1);
    will-change: transform;
    animation: kenburns-zoom-img 6.5s ease-out forwards;
}

@keyframes kenburns-zoom-img {
    from {
        transform: scale(1);
    }
    to {
        transform: scale(1.08);
    }
}

/* ---------- Indicador de puntos del banner hero ---------- */
#carrouselBannerHome .owl-dots,
#carrouselBannerHomeMobile .owl-dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 8px;
    z-index: 5;
    display: flex;
    justify-content: center;
    gap: 10px;
    line-height: 0;
}

#carrouselBannerHome .owl-dots .owl-dot span,
#carrouselBannerHomeMobile .owl-dots .owl-dot span {
    width: 8px;
    height: 8px;
    margin: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.45);
    transition: background-color 0.3s ease-in-out, transform 0.3s ease-in-out;
}

#carrouselBannerHome .owl-dots .owl-dot:hover span,
#carrouselBannerHomeMobile .owl-dots .owl-dot:hover span {
    background: rgba(255, 255, 255, 0.75);
}

#carrouselBannerHome .owl-dots .owl-dot.active span,
#carrouselBannerHomeMobile .owl-dots .owl-dot.active span {
    background: #FFB719;
    transform: scale(1.25);
}

/* ---------- Reduced motion: todo colapsa a estado final, sin animacion ---------- */
@media (prefers-reduced-motion: reduce) {
    .reveal-on-scroll {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .bannerProyecto,
    .btnAmarillo,
    .btnTransparente {
        transition: none;
    }

    .btnTransparente.cotizar_depto {
        animation: none;
    }

    .bannerProyecto:hover {
        transform: none;
    }

    .bannerProyecto img {
        transition: none;
    }

    .bannerProyecto:hover img {
        transform: none;
    }

    .skeleton-shimmer::after {
        animation: none;
    }

    #imgCotizador {
        transition: none;
    }

    #carrouselBannerHome .owl-item.active .item.bannerHome,
    #carrouselBannerHomeMobile .owl-item.active .item.bannerHome {
        animation: none;
        background-size: cover;
    }

    #carrouselBannerProyecto .bannerProyectoHeroImgMobile {
        animation: none;
        background-size: cover;
    }

    #carrouselBannerProyecto .bannerProyectoHeroImg {
        animation: none;
        transform: none;
    }
}
