"use client"; import { useTheme } from "next-themes"; import { useSyncExternalStore } from "react"; import { flushSync } from "react-dom"; const subscribe = () => () => {}; const getSnapshot = () => true; const getServerSnapshot = () => false; export function ThemeToggle() { const { resolvedTheme, setTheme } = useTheme(); const mounted = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); const toggle = () => { const next = resolvedTheme === "dark" ? "light" : "dark"; if ( !document.startViewTransition || window.matchMedia("(prefers-reduced-motion: reduce)").matches ) { setTheme(next); return; } document.startViewTransition(() => { flushSync(() => { setTheme(next); }); }); }; const isDark = mounted ? resolvedTheme === "dark" : true; return ( ); } // Render a stable SVG subtree so theme flips don't unmount/mount icon nodes. export function ThemeIcon({ mounted, isDark }: { mounted: boolean; isDark: boolean }) { const base = "transition-opacity"; const shown = "opacity-100"; const hidden = "opacity-0"; return ( ); }