diff --git a/web/public/video/pipelinescore-product-720.mp4 b/web/public/video/pipelinescore-product-720.mp4 new file mode 100644 index 0000000..81565c6 Binary files /dev/null and b/web/public/video/pipelinescore-product-720.mp4 differ diff --git a/web/public/video/pipelinescore-product-poster.jpg b/web/public/video/pipelinescore-product-poster.jpg new file mode 100644 index 0000000..a71f836 Binary files /dev/null and b/web/public/video/pipelinescore-product-poster.jpg differ diff --git a/web/public/video/pipelinescore-product.mp4 b/web/public/video/pipelinescore-product.mp4 new file mode 100644 index 0000000..aa16e5c Binary files /dev/null and b/web/public/video/pipelinescore-product.mp4 differ diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx index e7b5489..2bb1442 100644 --- a/web/src/app/page.tsx +++ b/web/src/app/page.tsx @@ -3,6 +3,7 @@ import { DataUnavailable } from "@/components/DataUnavailable"; import { getHardwareBoard, getLeaderboardModels, getStats } from "@/lib/api"; import { BenchTable } from "@/components/BenchTable"; import { CopyCommand } from "@/components/CopyCommand"; +import { ProductFilm } from "@/components/ProductFilm"; import { CATEGORY_LABELS, CATEGORY_WEIGHTS, TIERS } from "@/lib/tiers"; import { modelMatchups, rigMatchups } from "@/lib/matchups"; @@ -28,7 +29,8 @@ export default async function Home() {
{/* Masthead — data-first, no hero. The board is the homepage. */}
-
+
+
LLM benchmarks · v3 testpack · deterministic · no API key
@@ -74,6 +76,8 @@ export default async function Home() { See where you'd rank →
+
+
{/* Instrument strip */} diff --git a/web/src/components/ProductFilm.tsx b/web/src/components/ProductFilm.tsx new file mode 100644 index 0000000..4f06ba7 --- /dev/null +++ b/web/src/components/ProductFilm.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; + +/** + * The 20-second product video, muted and looping. It plays only while on screen, + * and not at all for people who ask for reduced motion: they get the poster and + * the player controls instead. + */ +export function ProductFilm() { + const ref = useRef(null); + const [reduced, setReduced] = useState(false); + + useEffect(() => { + const video = ref.current; + if (!video) return; + const motion = window.matchMedia("(prefers-reduced-motion: reduce)"); + let visible = false; + const sync = () => { + setReduced(motion.matches); + if (visible && !motion.matches && !document.hidden) video.play().catch(() => {}); + else video.pause(); + }; + const observer = new IntersectionObserver(([entry]) => { + visible = entry.isIntersecting; + sync(); + }, { threshold: 0.25 }); + observer.observe(video); + motion.addEventListener("change", sync); + document.addEventListener("visibilitychange", sync); + return () => { + observer.disconnect(); + motion.removeEventListener("change", sync); + document.removeEventListener("visibilitychange", sync); + }; + }, []); + + return ( +
+ +
+ ); +}