@keyframes fadeInUp {
  0% {
    opacity: 0;
    transform: translateY(20px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Clip-path reveals */
.hisi-anim.ha--clipPathRight {
  clip-path: inset(0 100% 0 0);
}
.hisi-anim.ha--clipPathRight.ha--animated {
  clip-path: inset(0 0 0 0);
}

.hisi-anim.ha--clipPathLeft {
  clip-path: inset(0 0 0 100%);
}
.hisi-anim.ha--clipPathLeft.ha--animated {
  clip-path: inset(0 0 0 0);
}

.hisi-anim.ha--clipPathBottom {
  clip-path: inset(0 0 100% 0);
}
.hisi-anim.ha--clipPathBottom.ha--animated {
  clip-path: inset(0 0 0 0);
}

.hisi-anim.ha--clipPathTop {
  clip-path: inset(100% 0 0 0);
}
.hisi-anim.ha--clipPathTop.ha--animated {
  clip-path: inset(0 0 0 0);
}

/* Scroll-linked effects */
.hisi-anim.ha--scrollBlur {
  animation: blurInOut linear both;
  transition-timing-function: ease;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}

.hisi-anim.ha--scrollBlurRight {
  animation: blurInOutRight linear both;
  transition-timing-function: ease;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}

.hisi-anim.ha--scrollBlurLeft {
  animation: blurInOutLeft linear both;
  transition-timing-function: ease;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}

.hisi-anim.ha--scrollZoom {
  animation: zoom linear both;
  transition-timing-function: ease;
  animation-timeline: view();
  animation-range: entry 0% cover 100%;
}

.hisi-anim.ha--scrollScale {
  animation: scale linear both;
  transition-timing-function: ease;
  animation-timeline: view();
  animation-range: entry 0% cover 30%;
}

@keyframes blurInOut {
  from {
    opacity: 0;
    transform: translateY(20px);
    filter: blur(5px);
  }
  30%,
  80% {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
  to {
    opacity: 0;
    transform: translateY(-20px);
    filter: blur(5px);
  }
}

@keyframes blurInOutRight {
  from {
    opacity: 0;
    transform: translateX(20px);
    filter: blur(5px);
  }
  30%,
  80% {
    opacity: 1;
    transform: translateX(0);
    filter: blur(0);
  }
  to {
    opacity: 0;
    transform: translateX(-20px);
    filter: blur(5px);
  }
}

@keyframes blurInOutLeft {
  from {
    opacity: 0;
    transform: translateX(-20px);
    filter: blur(5px);
  }
  30%,
  80% {
    opacity: 1;
    transform: translateX(0);
    filter: blur(0);
  }
  to {
    opacity: 0;
    transform: translateX(20px);
    filter: blur(5px);
  }
}

@keyframes zoom {
  from {
    background-size: 100%;
  }
  to {
    background-size: 150%;
  }
}

@keyframes scale {
  from {
    transform: scale(0.8);
    border-radius: 16px;
  }
  to {
    transform: scale(1);
    border-radius: 0;
  }
}

/* Scale down progressively while the element exits the viewport. */
.hisi-anim.ha--scrollScaleDown {
  animation: haScaleDown linear both;
  animation-timeline: view();
  animation-range: exit;
  transform-origin: 50% 0%;
}

@keyframes haScaleDown {
  from { transform: scale(1); }
  to   { transform: scale(0.8); }
}

/* Sticky helpers */
.hisi-anim.ha--stickyTop,
.hisi-anim.ha--stickyBottom {
  align-self: flex-start;
  z-index: var(--ha-sticky-z, 10);
}

.hisi-anim.ha--stickyContained.ha--stickyTop,
.hisi-anim.ha--stickyContained.ha--stickyBottom {
  position: sticky;
}

.hisi-anim.ha--stickyContained.ha--stickyTop {
  top: var(--ha-sticky-offset, 0px);
}

.hisi-anim.ha--stickyContained.ha--stickyBottom {
  bottom: var(--ha-sticky-offset, 0px);
}

.hisi-anim.ha--stickyViewport.ha--stickyFixed {
  position: fixed !important;
  left: var(--ha-sticky-left, auto) !important;
  width: var(--ha-sticky-width, auto) !important;
  z-index: var(--ha-sticky-z, 10);
}

.hisi-anim.ha--stickyViewport.ha--stickyTop.ha--stickyFixed {
  top: var(--ha-sticky-offset, 0px) !important;
}

.hisi-anim.ha--stickyViewport.ha--stickyBottom.ha--stickyFixed {
  bottom: var(--ha-sticky-offset, 0px) !important;
}

/* Button hover: Spotless-style pill + sliding arrow */
.hisi-anim.ha--buttonSpotless.ha-button-spotless-target,
.hisi-anim.ha--buttonSpotless .ha-button-spotless-target {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ha-button-gap, 10px);
  overflow: visible;
  border: 0;
  border-radius: 1000px;
  background: transparent;
  text-decoration: none;
  transition: transform 0.6s cubic-bezier(0.76, 0, 0.24, 1);
  will-change: transform;
}

.hisi-anim.ha--buttonSpotless.ha-button-spotless-target::before,
.hisi-anim.ha--buttonSpotless .ha-button-spotless-target::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border: 1px solid currentColor;
  border-radius: inherit;
  background: transparent;
  transform: scaleY(1);
  transform-origin: center;
  transition: transform 0.6s cubic-bezier(0.76, 0, 0.24, 1);
  will-change: transform;
  backface-visibility: hidden;
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-arrow {
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  width: 1em;
  height: 1em;
  overflow: hidden;
  color: currentColor;
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-arrow-icon {
  position: absolute;
  inset: 0;
  display: block;
  transition: transform 0.6s cubic-bezier(0.76, 0, 0.24, 1);
  will-change: transform;
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-arrow-icon::before {
  content: "";
  position: absolute;
  left: 15%;
  top: 50%;
  width: 70%;
  height: 1px;
  background: currentColor;
  transform: translateY(-50%);
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-arrow-icon::after {
  content: "";
  position: absolute;
  right: 15%;
  top: 50%;
  width: 0.45em;
  height: 0.45em;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
  transform-origin: center;
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-custom-icon .ha-button-spotless-arrow-icon::before {
  inset: 0;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: currentColor;
  -webkit-mask: var(--ha-button-icon-url) no-repeat center / contain;
  mask: var(--ha-button-icon-url) no-repeat center / contain;
  transform: none;
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-custom-icon .ha-button-spotless-arrow-icon::after {
  content: none;
}

.hisi-anim.ha--buttonSpotless .ha-button-spotless-arrow-icon:nth-child(2) {
  transform: translateX(-100%);
}

@media (hover: hover) and (pointer: fine) {
  .hisi-anim.ha--buttonSpotless.ha-button-spotless-target:hover::before,
  .hisi-anim.ha--buttonSpotless:hover .ha-button-spotless-target::before {
    transform: scaleY(0.91);
  }

  .hisi-anim.ha--buttonSpotless.ha-button-spotless-target:hover .ha-button-spotless-arrow-icon:nth-child(1),
  .hisi-anim.ha--buttonSpotless:hover .ha-button-spotless-target .ha-button-spotless-arrow-icon:nth-child(1) {
    transform: translateX(100%);
  }

  .hisi-anim.ha--buttonSpotless.ha-button-spotless-target:hover .ha-button-spotless-arrow-icon:nth-child(2),
  .hisi-anim.ha--buttonSpotless:hover .ha-button-spotless-target .ha-button-spotless-arrow-icon:nth-child(2) {
    transform: translateX(0);
  }
}

/* =====================================================================
   v1.0.1 — Nuevos efectos
   Entrada (trigger .ha--animated): estado base + estado final. La duración
   la fija el JS (data-anim-time, 1s por defecto) vía transition-duration;
   aquí solo definimos la curva premium (ease-out expo).
   Scroll-linked (animation-timeline: view()): igual que ha--scrollBlur.
   ===================================================================== */

/* ---- Entrada: Blur up ---- */
.hisi-anim.ha--blurUp {
  opacity: 0;
  transform: translateY(24px);
  filter: blur(12px);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--blurUp.ha--animated {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

/* ---- Entrada: Scale in ---- */
.hisi-anim.ha--scaleIn {
  opacity: 0;
  transform: scale(0.96);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--scaleIn.ha--animated {
  opacity: 1;
  transform: scale(1);
}

/* ---- Entrada: Tilt in (rotateX 3D sutil) ---- */
.hisi-anim.ha--tiltIn {
  opacity: 0;
  transform: perspective(1200px) rotateX(8deg) translateY(22px);
  transform-origin: center top;
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--tiltIn.ha--animated {
  opacity: 1;
  transform: perspective(1200px) rotateX(0deg) translateY(0);
}

/* ---- Entrada: Drift (desplazamiento corto + fade) ---- */
.hisi-anim.ha--drift {
  opacity: 0;
  transform: translateX(-28px);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--drift.ha--animated {
  opacity: 1;
  transform: translateX(0);
}

/* ---- Entrada: Line reveal (máscara clip-path de abajo a arriba) ---- */
.hisi-anim.ha--lineReveal {
  opacity: 0;
  -webkit-clip-path: inset(0 0 100% 0);
  clip-path: inset(0 0 100% 0);
  transform: translateY(14px);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--lineReveal.ha--animated {
  opacity: 1;
  -webkit-clip-path: inset(0 0 0% 0);
  clip-path: inset(0 0 0% 0);
  transform: translateY(0);
}

/* ---- Entrada: Split text (palabras/letras con stagger por CSS) ---- */
.hisi-anim.ha--splitText {
  opacity: 1;
}

.hisi-anim.ha--splitText .ha-split-word {
  display: inline-block;
  white-space: nowrap;
}

.hisi-anim.ha--splitText .ha-split-char {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.35em) scaleY(0.85);
  transform-origin: bottom center;
  transition-property: opacity, transform;
  transition-duration: var(--ha-split-duration, 0.7s);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--ha-split-delay, 0s) + (var(--ha-split-index, 0) * var(--ha-split-stagger, 12ms)));
  will-change: opacity, transform;
}

.hisi-anim.ha--splitText.ha--animated .ha-split-char {
  opacity: 1;
  transform: translateY(0) scaleY(1);
}

/* ---- Entrada: Split lines (cada linea de texto entra enmascarada, con stagger) ---- */
.hisi-anim.ha--splitLines {
  opacity: 1;
}

.hisi-anim.ha--splitLines .ha-line-mask {
  display: block;
  overflow: clip;
}

.hisi-anim.ha--splitLines .ha-line-inner {
  display: block;
  transform: translateY(115%);
  transition-property: transform;
  transition-duration: var(--ha-split-duration, 1.4s);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--ha-split-delay, 0s) + (var(--ha-split-index, 0) * var(--ha-split-stagger, 140ms)));
  will-change: transform;
}

.hisi-anim.ha--splitLines.ha--animated .ha-line-inner {
  transform: translateY(0);
}

/* ---- Scroll-linked: text color reveal by character ---- */
.hisi-anim.ha--textColorReveal.ha-color-text,
.hisi-anim.ha--textColorReveal .ha-color-text {
  view-timeline-name: --ha-text-color-reveal;
  view-timeline-axis: block;
}

.hisi-anim.ha--textColorReveal .ha-color-word {
  display: inline-block;
  white-space: nowrap;
}

.hisi-anim.ha--textColorReveal .ha-color-char {
  display: inline-block;
  color: color-mix(in srgb, var(--ha-text-color-to, currentColor) 18%, transparent);
  animation: haTextColorReveal linear both;
  animation-timeline: --ha-text-color-reveal;
  animation-range: var(--ha-color-start, 8%) var(--ha-color-end, 17%);
}

@keyframes haTextColorReveal {
  to { color: var(--ha-text-color-to, currentColor); }
}

/* ---- Scroll-linked: Parallax (deriva vertical) ---- */
.hisi-anim.ha--scrollParallax {
  animation: haParallax linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}
@keyframes haParallax {
  from { transform: translateY(70px); }
  to   { transform: translateY(-70px); }
}

/* ---- Scroll-linked: Rotate 3D (se endereza en el centro) ---- */
.hisi-anim.ha--scrollRotate {
  animation: haRotate linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
  transform-origin: center center;
}
@keyframes haRotate {
  from { transform: perspective(1100px) rotateX(14deg);  opacity: 0.45; }
  50%  { transform: perspective(1100px) rotateX(0deg);   opacity: 1; }
  to   { transform: perspective(1100px) rotateX(-14deg); opacity: 0.45; }
}

/* ---- Scroll-linked: Dim to light (brillo/contraste al centro) ---- */
.hisi-anim.ha--scrollDim {
  animation: haDim linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}
@keyframes haDim {
  from { filter: brightness(0.4) contrast(0.9); }
  50%  { filter: brightness(1) contrast(1); }
  to   { filter: brightness(0.4) contrast(0.9); }
}

/* ---- Scroll-linked: Skew settle (cizalla que se asienta) ---- */
.hisi-anim.ha--scrollSkew {
  animation: haSkew linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}
@keyframes haSkew {
  from { transform: skewY(4deg) translateY(24px);   opacity: 0.5; }
  50%  { transform: skewY(0deg) translateY(0);      opacity: 1; }
  to   { transform: skewY(-4deg) translateY(-24px); opacity: 0.5; }
}

/* ---- Scroll-linked: Drift X (deriva horizontal / parallax lateral) ---- */
.hisi-anim.ha--scrollDriftX {
  animation: haDriftX linear both;
  animation-timeline: view();
  animation-range: entry 0% exit 100%;
}
@keyframes haDriftX {
  from { transform: translateX(-60px); opacity: 0.55; }
  50%  { transform: translateX(0);     opacity: 1; }
  to   { transform: translateX(60px);  opacity: 0.55; }
}

/* ---- Reveal: Image curtain, horizontal y vertical ----
   Cortina simple via clip-path (mismo mecanismo que ha--clipPathRight /
   ha--clipPathTop, sin envolver la imagen en JS ni mover una segunda capa):
   el propio elemento se recorta y el recorte se retira al activarse.
   ha--imageCurtain = izquierda a derecha (crece el lado derecho).
   ha--imageCurtainVertical = de abajo a arriba (crece el lado superior). */
.hisi-anim.ha--imageCurtain {
  clip-path: inset(0 100% 0 0);
  -webkit-clip-path: inset(0 100% 0 0);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--imageCurtain.ha--animated {
  clip-path: inset(0 0 0 0);
  -webkit-clip-path: inset(0 0 0 0);
}

.hisi-anim.ha--imageCurtainVertical {
  clip-path: inset(100% 0 0 0);
  -webkit-clip-path: inset(100% 0 0 0);
  transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.hisi-anim.ha--imageCurtainVertical.ha--animated {
  clip-path: inset(0 0 0 0);
  -webkit-clip-path: inset(0 0 0 0);
}

/* ---- Respeta a quien reduce el movimiento ---- */
@media (prefers-reduced-motion: reduce) {
  .hisi-anim.ha--blurUp,
  .hisi-anim.ha--scaleIn,
  .hisi-anim.ha--tiltIn,
  .hisi-anim.ha--drift,
  .hisi-anim.ha--lineReveal,
  .hisi-anim.ha--splitText .ha-split-char,
  .hisi-anim.ha--splitLines .ha-line-inner {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    -webkit-clip-path: none !important;
    clip-path: none !important;
  }
  .hisi-anim.ha--textColorReveal .ha-color-char {
    animation: none !important;
    color: var(--ha-text-color-to, currentColor) !important;
  }
  .hisi-anim.ha--imageCurtain,
  .hisi-anim.ha--imageCurtainVertical {
    -webkit-clip-path: none !important;
    clip-path: none !important;
    transition: none !important;
  }
  .hisi-anim.ha--scrollParallax,
  .hisi-anim.ha--scrollScaleDown,
  .hisi-anim.ha--scrollRotate,
  .hisi-anim.ha--scrollDim,
  .hisi-anim.ha--scrollSkew,
  .hisi-anim.ha--scrollDriftX {
    animation: none !important;
  }
  .hisi-anim.ha--buttonSpotless .ha-button-spotless-target,
  .hisi-anim.ha--buttonSpotless .ha-button-spotless-target::before,
  .hisi-anim.ha--buttonSpotless .ha-button-spotless-arrow-icon {
    transition: none !important;
    transform: none !important;
  }
}
