/* ============================================================
   Saunas Durán · capa de movimiento
   Vanilla. Sin librerías. ~5 KB con motion.js.
   Todo se apaga solo si el visitante pide menos movimiento.
   ============================================================ */

:root{
  --ease-out-expo:cubic-bezier(.22,1,.36,1);
  --ease-out-soft:cubic-bezier(.33,1,.68,1);
  --dur:900ms;
}

/* ---- Base: solo se oculta si el JS arrancó (evita el flash) ---- */
.js-motion [data-reveal]{
  opacity:0;
  transform:translate3d(0,28px,0);
  transition:opacity var(--dur) var(--ease-out-expo),
             transform var(--dur) var(--ease-out-expo);
  transition-delay:var(--d,0ms);
  will-change:opacity,transform;
}
.js-motion [data-reveal="left"]  {transform:translate3d(-32px,0,0)}
.js-motion [data-reveal="right"] {transform:translate3d(32px,0,0)}
.js-motion [data-reveal="scale"] {transform:scale(.94);opacity:0}
.js-motion [data-reveal="fade"]  {transform:none}

.js-motion [data-reveal].is-in{
  opacity:1;
  transform:none;
}
/* una vez dentro, soltamos el will-change para no gastar GPU */
.js-motion [data-reveal].is-done{will-change:auto}

/* ---- Máscara de línea: el texto sube desde abajo ----
   Ojo: va scopeado a .js-motion igual que el resto. Si el
   motor se cae y quitamos la clase, el titular tiene que
   volver a verse. */
/* La caja que recorta se amplía por arriba y por abajo, y el margen negativo
   lo devuelve: el titular no se mueve ni un píxel. Sin esto, con el
   interlineado de 1,08 de los titulares, Playfair se sale de su caja y el
   recorte se comía los rabos de g, j, p, q, y (y las tildes de arriba, la
   remata de la serif que sobresale por la izquierda de la V, y la sombra
   del texto en las cabeceras oscuras). Visto por Manu en
   /generadores-de-vapor/profesionales/ el 23 sep 2026; medido comparando
   píxeles con y sin el recorte: pasaba en 20 de las 31 páginas. */
.ln{display:block;overflow:hidden;padding:.2em .1em .36em;margin:-.2em -.1em -.36em}
.js-motion .ln-i{
  display:block;
  /* Más abajo que antes, para que siga escondida bajo la caja ampliada. */
  transform:translate3d(0,calc(110% + .5em),0);
  transition:transform 1100ms var(--ease-out-expo);
  transition-delay:var(--d,0ms);
}
.js-motion .is-in .ln-i,.js-motion .ln.is-in .ln-i{transform:none}

/* ---- HERO: la foto entra con un zoom lento que nunca se detiene del todo ---- */
.js-motion .hero img.bg{
  transform:scale(1.14);
  transition:transform 2600ms var(--ease-out-soft);
  will-change:transform;
}
.js-motion .hero.is-in img.bg{transform:scale(1)}

/* Terminada la entrada, el scroll toma el mando (motion.js).
   Hay que quitar la transición o cada movimiento del scroll
   arrastraría 2,6 s de retraso y se sentiría pegajoso. */
.js-motion .hero.hs-on img.bg{transition:none}
.js-motion .hero.hs-on .wrap{will-change:transform,opacity}

/* el degradado sube después de la foto */
.js-motion .hero::after{opacity:0;transition:opacity 1400ms ease 200ms}
.js-motion .hero.is-in::after{opacity:1}

/* señal de "sigue bajando" */
.scrollcue{
  position:absolute;left:50%;bottom:26px;z-index:3;
  width:1px;height:54px;background:linear-gradient(180deg,transparent,rgba(255,255,255,.85));
  transform:translateX(-50%);transform-origin:top;
  animation:cue 2.4s var(--ease-out-soft) infinite;
}
@keyframes cue{
  0%  {transform:translateX(-50%) scaleY(0);opacity:0}
  35% {transform:translateX(-50%) scaleY(1);opacity:1}
  70% {transform:translateX(-50%) scaleY(1);opacity:1}
  100%{transform:translateX(-50%) scaleY(1) translateY(54px);opacity:0}
}

/* ---- Parallax: la imagen se mueve más lento que el scroll ---- */
.js-motion [data-parallax]{will-change:transform}
.js-motion [data-parallax] img{
  transform:translate3d(0,var(--py,0px),0) scale(1.16);
}

/* ---- Header que se compacta al bajar ---- */
header{transition:height .35s var(--ease-out-expo),
                  box-shadow .35s ease,
                  background .35s ease}
header .nav{transition:height .35s var(--ease-out-expo)}
header.scrolled{box-shadow:0 10px 34px rgba(29,25,21,.09)}
header.scrolled .nav{height:62px}
header.scrolled .logo small{opacity:0;transition:opacity .25s ease}

/* ---- Contadores ---- */
.stat b{font-variant-numeric:tabular-nums}

/* ---- Galería sticky de proyectos ---- */
.sticky-gal{position:relative}
.sticky-gal .sticky-txt{position:sticky;top:120px;align-self:start}

/* ---- Subrayado que crece en los enlaces "go" ---- */
.lin .go{position:relative;border-bottom-color:transparent}
.lin .go::after{
  content:"";position:absolute;left:0;bottom:-3px;height:1px;width:100%;
  background:var(--bord);transform:scaleX(0);transform-origin:left;
  transition:transform .45s var(--ease-out-expo);
}
.lin:hover .go::after{transform:scaleX(1)}

/* ---- Botones con brillo al pasar ---- */
.btn-p{position:relative;overflow:hidden}
.btn-p::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(120deg,transparent 30%,rgba(255,255,255,.22) 50%,transparent 70%);
  transform:translateX(-120%);transition:transform .7s var(--ease-out-expo);
}
.btn-p:hover::after{transform:translateX(120%)}

/* ---- FAQ ----
   styles.css ya lo abre y lo cierra, y las páginas largas
   (.faq-lg, .npc-faq) suben el max-height. NO tocamos eso:
   solo suavizamos la curva del despliegue y del icono. */
.fitem .fa{transition:max-height .5s var(--ease-out-expo)}
.fitem .fq .p{transition:transform .4s var(--ease-out-expo)}

/* ============================================================
   RESPETO POR EL USUARIO
   Si pidió menos movimiento en su sistema, todo queda quieto.
   Esto es lo que evita que las animaciones bajen el PageSpeed
   y lo que hace la web accesible de verdad.
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  .js-motion [data-reveal],
  .js-motion [data-reveal].is-in,
  .ln-i,
  .js-motion .hero img.bg,
  .js-motion .hero::after{
    opacity:1!important;
    transform:none!important;
    transition:none!important;
  }
  .js-motion [data-parallax] img{transform:none!important}
  .scrollcue{animation:none;opacity:.6}
  html{scroll-behavior:auto}
  .btn-p::after{display:none}
}
