/* LuxHaven motion — everything the Style panel cannot hold (keyframes and
   motion rules). Hover transitions live in luxhavenlife.webflow.css.
   js/motion.js decides when section reveals play, and runs the scroll-linked
   effects in browsers without native scroll-driven animation.

   Performance: every animation here moves only opacity, translate, scale,
   rotate or clip-path, so the browser can hand it to the graphics card.
   All of it is skipped for visitors who prefer reduced motion. */

/* Starts dim rather than invisible, so the hero photo counts as shown
   from the first frame (speed tests ignore fully transparent images) */
@keyframes motion-brighten {
  from {
    opacity: 0.35;
  }
}

@keyframes motion-fade-up {
  from {
    opacity: 0;
    translate: 0 28px;
  }
}

/* Slides up from behind its own bottom edge: moving the element down while
   clipping the same amount off its bottom keeps the hidden edge still */
@keyframes motion-mask-reveal {
  from {
    translate: 0 100%;
    clip-path: inset(0 0 100% 0);
  }
  to {
    translate: 0 0;
    clip-path: inset(0 0 0 0);
  }
}

@keyframes motion-draw-down {
  from {
    clip-path: inset(0 0 100% 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes motion-wipe-up {
  from {
    clip-path: inset(100% 0 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

@keyframes motion-spin {
  to {
    rotate: 360deg;
  }
}

/* Weather icons (js/weather.js draws them) */
@keyframes weather-rock {
  from {
    rotate: -10deg;
  }
  to {
    rotate: 10deg;
  }
}

@keyframes weather-drift {
  from {
    translate: -1.5px 0;
  }
  to {
    translate: 1.5px 0;
  }
}

@keyframes weather-fall {
  from {
    opacity: 0;
    translate: 0 -2px;
  }
  30% {
    opacity: 1;
  }
  to {
    opacity: 0;
    translate: 0 3px;
  }
}

@keyframes weather-flash {
  0%, 78%, 86%, 100% {
    opacity: 1;
  }
  82%, 90% {
    opacity: 0.15;
  }
}

/* Scroll-linked (used natively below; js/motion.js mirrors these values) */
@keyframes motion-parallax {
  from {
    translate: 0 -18%;
  }
  to {
    translate: 0 18%;
  }
}

@keyframes motion-drift-away {
  to {
    opacity: 0.25;
    translate: 0 -120px;
  }
}

@keyframes motion-drift-up {
  to {
    translate: 0 -120px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* ---- Home hero: plays once on load, in every browser ---- */

  /* The photo brightens up out of the hero's dark brown base */
  .hero-section.is-home .hero-image-wrapper {
    animation: motion-brighten 1600ms ease-out backwards;
  }
  .hero-section.is-home .hero-grid-lines {
    animation: motion-draw-down 1800ms cubic-bezier(0.65, 0, 0.35, 1) 200ms backwards;
  }
  /* "LuxHaven Life" slides up from behind a hidden edge */
  .hero-title-box .display-large-h1 {
    animation: motion-mask-reveal 1300ms cubic-bezier(0.77, 0, 0.175, 1) 400ms backwards;
  }
  /* On phones the title reveals at once and quickly, so the page's main
     content counts as shown sooner on slower connections */
  @media (max-width: 767px) {
    .hero-title-box .display-large-h1 {
      animation-duration: 700ms;
      animation-delay: 0ms;
    }
  }
  /* The cream card wipes up, then its words follow */
  .hero-section.is-home .hero-meta-wrapper.is-editorial {
    animation: motion-wipe-up 1100ms cubic-bezier(0.65, 0, 0.35, 1) 700ms backwards;
  }
  .hero-meta.is-panel > * {
    animation: motion-fade-up 900ms cubic-bezier(0.2, 0.7, 0.2, 1) 1150ms backwards;
  }
  .hero-meta.is-panel > :nth-child(2) {
    animation-delay: 1280ms;
  }
  .hero-meta.is-panel > :nth-child(3) {
    animation-delay: 1410ms;
  }
  /* The details column arrives last */
  .hero-section.is-home .hero-meta-wrapper.is-centered > * {
    animation: motion-fade-up 1000ms cubic-bezier(0.2, 0.7, 0.2, 1) 1300ms backwards;
  }
  .hero-section.is-home .hero-meta-wrapper.is-centered > :nth-child(2) {
    animation-delay: 1500ms;
  }

  /* Rotating phrases in the cream card: js/motion.js adds .is-running and
     moves .is-active along every 3.5s. All phrases share one grid cell, so
     the heading keeps the height of the tallest and the button never jumps. */
  .text-slider.is-running {
    display: grid;
    overflow: hidden;
    /* Trim only the sides, so letter tails like the y in Exclusivity show */
    overflow: clip visible;
  }
  /* Waiting phrases sit hidden off to the right */
  .text-slider.is-running > .text-slide {
    grid-area: 1 / 1;
    opacity: 0;
    translate: 100% 0;
  }
  /* The next phrase glides in from the right, just after the last one
     has begun to fade */
  .text-slider.is-running > .is-active {
    opacity: 1;
    translate: 0 0;
    transition: translate 1200ms cubic-bezier(0.22, 1, 0.36, 1) 350ms,
      opacity 1200ms cubic-bezier(0.22, 1, 0.36, 1) 350ms;
  }
  /* The outgoing phrase fades out where it stands */
  .text-slider.is-running > .is-leaving {
    translate: 0 0;
    transition: opacity 700ms ease;
  }

  /* Weather icons: every one has its own quiet motion */
  .weather-icon .is-sun {
    animation: motion-spin 16s linear infinite;
  }
  .weather-icon .is-moon {
    animation: weather-rock 5s ease-in-out infinite alternate;
  }
  .weather-icon .is-cloud,
  .weather-icon .wx-drift {
    animation: weather-drift 3s ease-in-out infinite alternate;
  }
  .weather-icon .wx-drift.is-reverse {
    animation-direction: alternate-reverse;
  }
  /* Rain drops and snowflakes fall in turn; snow falls more slowly */
  .weather-icon .wx-fall > * {
    animation: weather-fall 1.2s linear infinite;
  }
  .weather-icon .is-snow .wx-fall > * {
    animation-duration: 2.4s;
  }
  .weather-icon .wx-fall > :nth-child(2) {
    animation-delay: -0.4s;
  }
  .weather-icon .wx-fall > :nth-child(3) {
    animation-delay: -0.8s;
  }
  .weather-icon .wx-fall > :nth-child(4) {
    animation-delay: -1.4s;
  }
  .weather-icon .wx-fall > :nth-child(5) {
    animation-delay: -1.9s;
  }
  .weather-icon .wx-bolt {
    animation: weather-flash 3s linear infinite;
  }

  /* Sub-page heroes settle in once */
  .hero-title-wrapper.sub-hero {
    animation: motion-fade-up 1100ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
  }

  /* ---- Section reveals: js/motion.js adds .reveal to each section block,
     and .is-revealed while it is inside the middle band of the screen
     (off again while it is only in the top or bottom edge strip) ---- */
  /* One transition both ways, so a block caught mid-fade simply turns
     around. (color is listed so the pricing cards keep their hover fade.) */
  html.js-motion .reveal {
    transition: opacity 700ms cubic-bezier(0.2, 0.7, 0.2, 1),
      translate 700ms cubic-bezier(0.2, 0.7, 0.2, 1), color 400ms ease;
  }
  html.js-motion .reveal:not(.is-revealed) {
    opacity: 0;
    translate: 0 28px;
  }

  /* ---- Scroll-linked effects, run by the browser itself where it can.
     Elsewhere js/motion.js plays the same keyframes. ---- */
  @supports (animation-timeline: view()) {
    /* Hero content drifts up as the page scrolls; the title and details
       fade as they go, the cream card stays solid */
    .hero-wrapper.is-editorial {
      view-timeline-name: --hero;
    }
    .hero-title-box,
    .hero-section.is-home .hero-meta-wrapper.is-centered {
      animation: motion-drift-away linear both;
      animation-timeline: --hero;
      animation-range: exit 0% exit 100%;
    }
    .hero-section.is-home .hero-meta-wrapper.is-editorial {
      animation: motion-wipe-up 1100ms cubic-bezier(0.65, 0, 0.35, 1) 700ms backwards,
        motion-drift-up linear both;
      animation-timeline: auto, --hero;
      animation-range: normal, exit 0% exit 100%;
    }

    /* Parallax: the photo drifts against the scroll inside its frame,
       enlarged so its edges never show */
    .parallax-frame,
    .img-parrallx {
      view-timeline-name: --parallax;
    }
    .parallax-frame > img,
    .parallax-bg {
      scale: 1.4;
      animation: motion-parallax linear both;
      animation-timeline: --parallax;
      animation-range: cover 0% cover 100%;
    }
  }
}
