// A shelf of videos remixed in the Studio app: each card plays HeyGen's remix on hover, credits the original // (linked to its post), and says how to remix it yourself. Originals are never hosted here. export const RemixShelf = ({ items, tall = false }) => { // Hover previews follow the visitor's reduced-motion setting, known on the first render; the film is a button, so // playing it on purpose works for keyboard and touch, and under reduced motion. // The setting lives in a ref, not state: a preference change must not re-render the shelf, which would remount // every card (RemixCard is declared in here, as Mintlify snippets keep helpers inside the export) and lose a // playing film, focus and open instructions. const shelfRef = useRef(null); const reduced = useRef(null); if (reduced.current === null) reduced.current = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches; useEffect(() => { const query = window.matchMedia("(prefers-reduced-motion: reduce)"); const follow = (event) => { reduced.current = event.matches; // Turned on mid-visit: stop any hover preview that is running. if (event.matches) for (const v of shelfRef.current?.querySelectorAll("video") ?? []) if (v.dataset.hover) v.pause(); }; query.addEventListener("change", follow); return () => query.removeEventListener("change", follow); }, []); const RemixCard = ({ item }) => { const videoRef = useRef(null); const [open, setOpen] = useState(false); const [copied, setCopied] = useState(false); const [chosen, setChosen] = useState(false); // One film at a time across the page: any other video starting with sound (another remix, the full-film dialog, a // replica pair) is a deliberate choice, so this card stops and lets go of its own. useEffect(() => { const onPlay = (event) => { const v = event.target; const own = videoRef.current; if (!(v instanceof HTMLVideoElement) || v.muted || v === own || !own) return; own.pause(); own.muted = true; setChosen(false); }; document.addEventListener("play", onPlay, true); return () => document.removeEventListener("play", onPlay, true); }, []); const preview = (on) => { const v = videoRef.current; const filmWithSound = [...document.querySelectorAll("video")].some((x) => !x.paused && !x.muted); if (!v || chosen || (on && filmWithSound)) return; if (on && !reduced.current) { v.dataset.hover = "1"; v.play().catch(() => {}); } else if (!on) { delete v.dataset.hover; v.pause(); v.currentTime = 0; } }; const toggle = () => { const v = videoRef.current; if (!v) return; // A chosen film plays with its sound; hover previews stay muted. if (chosen && !v.paused) { v.pause(); v.muted = true; setChosen(false); } else { delete v.dataset.hover; v.muted = false; v.play().catch(() => {}); setChosen(true); } }; const copy = async () => { try { await navigator.clipboard.writeText(item.post); setCopied(true); setTimeout(() => setCopied(false), 1600); } catch {} }; return (