/* =====================================================================
   exesrivas · Efectos
   Portado tal cual de aitorinmobiliario.com/assets/fx.css (que a su vez
   viene de Allora) y recoloreado al rojo de exesrivas. Todo opt-in por data-attr o clase,
   todo con guarda de prefers-reduced-motion y con el móvil aligerado.
   ===================================================================== */

/* ---------- 1) BackgroundPaths: trazos SVG que fluyen tras el hero ----- */
.bg-paths{position:absolute;inset:0;width:100%;height:100%;overflow:hidden;pointer-events:none;z-index:0}
.bg-paths svg{position:absolute;inset:0;width:100%;height:100%}
.bg-paths path{fill:none;stroke:currentColor;stroke-linecap:round}
.bg-paths--rojo{color:var(--red)}
.bg-paths--suave{color:var(--red-2)}
@keyframes bgp-flow{0%{stroke-dashoffset:1;opacity:.22}50%{opacity:.55}100%{stroke-dashoffset:0;opacity:.22}}
.bg-paths path{stroke-dasharray:.42 .58;animation:bgp-flow var(--bgp-dur,22s) linear infinite;animation-delay:var(--bgp-delay,0s)}
@media (prefers-reduced-motion:reduce){.bg-paths path{animation:none;stroke-dasharray:none;opacity:.24}}

/* ---------- 2) Aparición palabra a palabra con desenfoque -------------- */
/* La pieza clave para que un bloque de texto no se lea como un muro:
   entra por cascada al llegar a viewport en lugar de estar ya ahí. */
.fx [data-textfx] .tfx-w{display:inline-block;opacity:0;filter:blur(9px);transform:translateY(14px) scale(.97);
  transition:opacity .6s ease var(--d,0s),filter .6s ease var(--d,0s),transform .6s cubic-bezier(.22,.61,.36,1) var(--d,0s)}
.fx [data-textfx].tfx-on .tfx-w{opacity:1;filter:blur(0);transform:none}
@media (prefers-reduced-motion:reduce){.fx [data-textfx] .tfx-w{opacity:1;filter:none;transform:none;transition:none}}

/* ---------- 3) Reveal de bloque al hacer scroll ------------------------ */
.fx [data-reveal]{opacity:0;transform:translateY(22px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.61,.36,1)}
.fx [data-reveal].rv-on{opacity:1;transform:none}
.fx [data-reveal][data-delay="1"]{transition-delay:.10s}
.fx [data-reveal][data-delay="2"]{transition-delay:.20s}
.fx [data-reveal][data-delay="3"]{transition-delay:.30s}
.fx [data-reveal][data-delay="4"]{transition-delay:.40s}
@media (prefers-reduced-motion:reduce){.fx [data-reveal]{opacity:1;transform:none;transition:none}}

/* ---------- 4) La pieza se asienta al hacer scroll --------------------- */
/* Aquí había un rotateX con perspective. En Chromium, un contexto 3D con un
   descendiente que tiene overflow:hidden + border-radius deja de pintar la
   imagen: la tarjeta salía en blanco. Con transform 2D el efecto se percibe
   igual y no hay bug de composición. */
.tilt-scroll{position:relative}
.tilt-scroll__inner{transform:scale(.955) translateY(14px);
  transition:transform .12s linear;will-change:transform;transform-origin:50% 100%}
@media (prefers-reduced-motion:reduce){.tilt-scroll__inner{transform:none!important}}
@media (max-width:760px){.tilt-scroll{perspective:none}.tilt-scroll__inner{transform:none!important}}

/* ---------- 5) Malla animada para la banda CTA ------------------------- */
.mesh-cta{position:relative;overflow:hidden;isolation:isolate}
.mesh-cta::before{content:"";position:absolute;inset:-30%;z-index:-1;pointer-events:none;
  background:
    radial-gradient(38% 42% at 22% 28%, var(--red) 0%, transparent 55%),
    radial-gradient(42% 46% at 82% 22%, #6E0C05 0%, transparent 58%),
    radial-gradient(46% 50% at 72% 82%, #4A0803 0%, transparent 60%),
    radial-gradient(40% 44% at 18% 78%, #C7452F 0%, transparent 58%);
  filter:blur(26px) saturate(112%);
  animation:mesh-move 20s ease-in-out infinite alternate}
@keyframes mesh-move{
  0%{transform:translate3d(-3%,-2%,0) scale(1.05) rotate(0deg)}
  50%{transform:translate3d(3%,2%,0) scale(1.12) rotate(4deg)}
  100%{transform:translate3d(-2%,3%,0) scale(1.06) rotate(-3deg)}}
@media (prefers-reduced-motion:reduce){.mesh-cta::before{animation:none}}

/* ---------- 6) TypewriterLoop: palabra que muta en el titular ---------- */
.typeloop{display:inline-flex;align-items:baseline;vertical-align:baseline}
.typeloop__slot{position:relative;display:inline-flex;align-items:baseline;overflow:hidden}
.typeloop__word{display:inline-block;white-space:nowrap;padding-right:.04em;will-change:opacity,transform;color:var(--red)}
.typeloop__cursor{flex:none;width:.055em;min-width:3px;height:.86em;margin-left:.07em;border-radius:2px;
  align-self:center;background:var(--red);animation:tlBlink .9s steps(1) infinite}
@keyframes tlBlink{0%,49%{opacity:1}50%,100%{opacity:.15}}
@media (prefers-reduced-motion:reduce){.typeloop__cursor{animation:none;opacity:.6}}

/* ---------- 8) Contador que sube al entrar en pantalla ----------------- */
.cifras{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:20px;margin:0}
.cifra{text-align:center}
.cifra-n{font-family:Fraunces,serif;font-size:clamp(34px,5vw,52px);font-weight:800;
  line-height:1;letter-spacing:-.03em;color:var(--red);font-variant-numeric:tabular-nums}
.cifra-l{font-size:14.5px;color:var(--ink-3);margin-top:9px;line-height:1.45}
.section-dark .cifra-l{color:#a9a29b}

/* tono claro para fondos oscuros */
.bg-paths--claro{color:#E0A79E}

/* ---------- 9) Aurora: focos que respiran tras una sección oscura ------ */
.aurora{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.aurora::before,.aurora::after{content:"";position:absolute;inset:-30%;
  background:
    radial-gradient(40% 44% at 26% 30%, rgba(140,16,7,.62) 0%, transparent 62%),
    radial-gradient(36% 40% at 76% 70%, rgba(214,84,62,.34) 0%, transparent 60%);
  animation:auroraRespira 26s ease-in-out infinite alternate}
.aurora::after{animation-duration:37s;animation-direction:alternate-reverse;
  opacity:.65;filter:blur(18px)}
.aurora-grano{position:absolute;inset:0;opacity:.05;mix-blend-mode:screen;background-size:170px 170px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
@keyframes auroraRespira{
  0%{transform:translate3d(-4%,-3%,0) scale(1.04)}
  100%{transform:translate3d(5%,4%,0) scale(1.16)}}
@media (prefers-reduced-motion:reduce){
  .aurora::before,.aurora::after{animation:none;transform:none}}
