/*
 * Scroll-linked motion for the landing page, using native scroll-driven
 * animations (no JS, runs off the main thread). Browsers without support,
 * and visitors who prefer reduced motion, simply see the final state.
 *
 *   .landing-reveal    rises and fades in as it enters the viewport
 *   .landing-parallax  drifts against the scroll; set --parallax (default 60px)
 *   .landing-exit      lifts and fades as it scrolls out of the top
 *   .landing-stack     as it scrolls off the top it lags behind, shrinks and dims,
 *                      so the next block (stacked above it) slides over it. Needs
 *                      an opaque background and a lower z-index than the next
 *   .landing-slide     slides sideways across the screen as the page scrolls;
 *                      add .landing-slide-reverse to go the other way. Its
 *                      parent should be a .landing-slide-track.
 *   .landing-marquee   scrolls endlessly to the left (time-based, not scroll);
 *                      the content must be duplicated once for a seamless loop,
 *                      with the copy marked aria-hidden. Its parent should be a
 *                      .landing-marquee-track
 */

/*
 * Accent color for the demo windows (blog cover, analytics bars, block
 * icons). Brand red by default; a product tour band sets its own color so
 * its window matches.
 */
:root {
  --window-accent: var(--color-primary);
  /* How dark a .landing-stack block gets as it's covered: deep in dark mode,
     light in light mode, where a strong dim turns the band muddy grey. */
  --stack-dim: 0.45;
}

.light {
  --stack-dim: 0.92;
}

@keyframes landing-reveal {
  from {
    opacity: 0;
    transform: translate3d(0, 56px, 0) scale(0.97);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes landing-stack {
  to {
    transform: translate3d(0, 55%, 0) scale(0.92);
    filter: brightness(var(--stack-dim));
  }
}

@keyframes landing-parallax {
  from {
    transform: translate3d(0, var(--parallax, 60px), 0);
  }
  to {
    transform: translate3d(0, calc(var(--parallax, 60px) * -1), 0);
  }
}

@keyframes landing-exit {
  to {
    opacity: 0;
    transform: translate3d(0, -80px, 0);
  }
}

@keyframes landing-slide {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(calc(-100% + 100vw), 0, 0);
  }
}

@keyframes landing-marquee {
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

/* Without scroll-driven animations the rows are swipeable instead. */
.landing-slide-track {
  overflow-x: auto;
  scrollbar-width: none;
}

@media (prefers-reduced-motion: no-preference) {
  .landing-marquee {
    animation: landing-marquee 35s linear infinite;
  }

  .landing-marquee:hover {
    animation-play-state: paused;
  }
}

/*
 * A marquee that isn't moving (reduced motion, or a tile has keyboard focus)
 * becomes a swipeable row, so every item can be reached and focus scrolls
 * into view. The duplicate copy only exists for the loop, so it goes.
 */
.landing-marquee-track:has(:focus-visible) {
  overflow-x: auto;
  scrollbar-width: none;
}

.landing-marquee:has(:focus-visible) {
  animation: none;
}

.landing-marquee:has(:focus-visible) > [aria-hidden] {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .landing-marquee-track {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .landing-marquee > [aria-hidden] {
    display: none;
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .landing-reveal {
      animation: landing-reveal linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 90%;
    }

    .landing-parallax {
      animation: landing-parallax linear both;
      animation-timeline: view();
    }

    .landing-stack {
      transform-origin: 50% 0;
      animation: landing-stack linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%;
    }

    .landing-slide-track {
      overflow-x: clip;
    }

    .landing-slide {
      animation: landing-slide linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }

    .landing-slide-reverse {
      animation-direction: reverse;
    }

    .landing-exit {
      animation: landing-exit linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 100%;
    }
  }
}
