diff --git a/public/images/hero-palm-gradient-loop.mp4 b/public/images/hero-palm-gradient-loop.mp4 new file mode 100644 index 000000000..2deff940a Binary files /dev/null and b/public/images/hero-palm-gradient-loop.mp4 differ diff --git a/public/images/hero-palm-gradient-loop.webm b/public/images/hero-palm-gradient-loop.webm new file mode 100644 index 000000000..86fa10355 Binary files /dev/null and b/public/images/hero-palm-gradient-loop.webm differ diff --git a/public/images/hero-palm-gradient-loop.webp b/public/images/hero-palm-gradient-loop.webp new file mode 100644 index 000000000..a05fadb89 Binary files /dev/null and b/public/images/hero-palm-gradient-loop.webp differ diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 277c2bb6f..3a22bb4f2 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -64,6 +64,18 @@ function Index() { } } + const heroVideoRef = React.useRef(null) + + // Autoplay is declarative so the loop starts without waiting for hydration; + // this only walks it back for users who asked for less motion. + React.useEffect(() => { + if (!window.matchMedia('(prefers-reduced-motion: reduce)').matches) return + const video = heroVideoRef.current + if (!video) return + video.pause() + video.currentTime = 0 + }, []) + return ( <>
@@ -74,31 +86,43 @@ function Index() { rather than a theme-flipping semantic. */}
- {/* Wrapper carries the 8px inset + squircle clip so the + {/* Wrapper carries the 8px inset + squircle clip so the