Theme provider + useTheme hook (next-themes). ThemeProvider injects a blocking script that sets the dark class before first paint (no flash on reload); useTheme reads/sets the active theme. The React/Next equivalent of the Vue useTheme composable.
npx shadcn@latest add https://uipkge.dev/r/react/use-theme.jsonuse-theme