import { useEffect, useState } from "react"; /** Mobile breakpoint (must match Tailwind `md:` and the OpenSpec spec R1.2). */ const MOBILE_QUERY = "(max-width: 768px)"; /** * Single source of truth for the mobile/desktop responsive cut. * * Returns `true` when the viewport matches `max-width: 768px` (phone portrait), * `false` at `md:` and above. SSR-safe: returns `false` when `window` is * undefined so server-rendered markup stays on the desktop path. * * Replaces the ad-hoc `window.matchMedia("(max-width: 768px)")` reads scattered * across pages (App.tsx, Media.tsx) — see OpenSpec change * `mobile-responsive-parity`, design §`useIsMobile`. */ export function useIsMobile(): boolean { const [isMobile, setIsMobile] = useState( () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(MOBILE_QUERY).matches, ); useEffect(() => { if ( typeof window === "undefined" || typeof window.matchMedia !== "function" ) return; const mql = window.matchMedia(MOBILE_QUERY); const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches); mql.addEventListener("change", handler); return () => mql.removeEventListener("change", handler); }, []); return isMobile; }