import { useLayoutEffect, useState } from "react" /** matchMedia with rAF batching — avoids resize storms re-rendering every pixel. */ export function useMatchMedia(query: string): boolean { const [matches, setMatches] = useState(false) useLayoutEffect(() => { const mql = window.matchMedia(query) let raf = 0 const sync = () => { cancelAnimationFrame(raf) raf = requestAnimationFrame(() => { const next = mql.matches setMatches((prev) => (prev === next ? prev : next)) }) } sync() mql.addEventListener("change", sync) return () => { mql.removeEventListener("change", sync) cancelAnimationFrame(raf) } }, [query]) return matches }