new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

shadcn/ui · all subjects

theming

40 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Use shadcn/create to preview and generate themes

shadcn/create is a tool that allows you to build your theme visually by previewing colors, radius, fonts, and icons, then generate a preset for your project.

Enable CSS variables in components.json

To use CSS variables for theming, set tailwind.cssVariables to true in your components.json file. This is the default configuration.

CSS variables map to Tailwind utilities

Tailwind maps CSS variable tokens into utilities like bg-background, text-foreground, border-border, and ring-ring.

Dark mode uses .dark selector override

Dark mode works by overriding the same CSS variable tokens inside a .dark selector. See the dark mode documentation for adding a theme provider and toggling the .dark class.

CSS variables enable semantic theming

shadcn/ui uses CSS variables for theming, providing semantic tokens like background, foreground, and primary that components use by default. You override these tokens in your CSS to change the look of your app without rewriting component classes.

Semantic token convention: background and foreground pairs

shadcn/ui uses semantic background and foreground pairs. The base token controls the surface color and the -foreground token controls the text and icon color that sits on that surface. The background suffix is omitted for the surface token. For example, primary pairs with primary-foreground.

Complete theme tokens reference table

Theme tokens and their purposes: | Token | What it controls | Used by | |-------|-----------------|--------| | background / foreground | The default app background and text color | The page shell, page sections, and default text | | card / card-foreground | Elevated surfaces and the content inside them | Card, dashboard panels, settings panels | | popover / popover-foreground | Floating surfaces and the content inside them | Popover, DropdownMenu, ContextMenu, and other overlays | | primary / primary-foreground | High-emphasis actions and brand surfaces | Default Button, selected states, badges, and active accents | | secondary / secondary-foreground | Lower-emphasis filled actions and supporting surfaces | Secondary buttons, secondary badges, and supporting UI | | muted / muted-foreground | Subtle surfaces and lower-emphasis content | Descriptions, placeholders, empty states, helper text, and subdued surfaces | | accent / accent-foreground | Interactive hover, focus, and active surfaces | Ghost buttons, menu highlight states, hovered rows, and selected items | | destructive | Destructive actions and error emphasis | Destructive buttons, invalid states, and destructive menu items | | border | Default borders and separators | Cards, menus, tables, separators, and layout dividers | | input | Form control borders and input surface treatment | Input, Textarea, Select, and outline-style controls | | ring | Focus rings and outlines | Buttons, inputs, checkboxes, menus, and other focusable controls | | chart-1 ... chart-5 | The default chart palette | Charts and chart-driven dashboard blocks | | sidebar / sidebar-foreground | The base sidebar surface and default sidebar text | The Sidebar container and its default content | | sidebar-primary / sidebar-primary-foreground | High-emphasis actions inside the sidebar | Active items, icon tiles, badges, and sidebar CTAs | | sidebar-accent / sidebar-accent-foreground | Hover and selected states inside the sidebar | Sidebar menu hover states, open items, and interactive rows | | sidebar-border | Sidebar-specific borders and separators | Sidebar headers, groups, and internal dividers | | sidebar-ring | Sidebar-specific focus rings | Focused controls inside the sidebar | | radius | The base corner radius scale | Cards, inputs, buttons, popovers, and the derived radius-* tokens |

Radius scale derivation from base --radius token

The --radius token is the base radius for your theme. A small radius scale is derived from it so components can use consistent corner sizes while sharing a single source of truth. The derived tokens are: --radius-sm (0.6x), --radius-md (0.8x), --radius-lg (1x base), --radius-xl (1.4x), --radius-2xl (1.8x), --radius-3xl (2.2x), --radius-4xl (2.6x). Changing --radius updates the entire radius scale.

Radius scale CSS variables configuration

Example CSS configuration for radius scale in app/globals.css: ```css @theme inline { --radius-sm: calc(var(--radius) * 0.6); --radius-md: calc(var(--radius) * 0.8); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) * 1.4); --radius-2xl: calc(var(--radius) * 1.8); --radius-3xl: calc(var(--radius) * 2.2); --radius-4xl: calc(var(--radius) * 2.6); } ```

Add custom theme tokens via CSS variables

To add a new token, define it under :root and .dark selectors, then expose it to Tailwind with @theme inline. Example: define --warning and --warning-foreground in both :root and .dark, then use @theme inline to map them as --color-warning and --color-warning-foreground. You can then use bg-warning and text-warning-foreground in your components.

Add custom token example code

Example of adding a warning token to app/globals.css: ```css :root { --warning: oklch(0.84 0.16 84); --warning-foreground: oklch(0.28 0.07 46); } .dark { --warning: oklch(0.41 0.11 46); --warning-foreground: oklch(0.99 0.02 95); } @theme inline { --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); } ``` You can then use `bg-warning` and `text-warning-foreground` in your components.

Available base colors for theme initialization

The tailwind.baseColor setting controls the default token values generated when you run init or use a preset. The available base colors are: Neutral, Stone, Zinc, Mauve, Olive, Mist, and Taupe.

Default neutral theme scaffold with all tokens and colors

Complete default neutral theme CSS scaffold with all color tokens, sidebar tokens, radius scale, and layer base styles. The theme defines colors in oklch format for both light (:root) and dark (.dark) modes, includes a @theme inline block mapping all tokens to Tailwind color utilities, and applies default border and outline styling to all elements with border-border and outline-ring/50.

Disable CSS variables and use inline Tailwind colors

If you do not want to use CSS variables, run `npx shadcn@latest init --no-css-variables` to generate components with inline Tailwind color utilities instead. This sets tailwind.cssVariables to false in your components.json file. Components will use colors like bg-zinc-950, text-zinc-50, dark:bg-white, and dark:text-zinc-950.

CSS variables is an installation-time choice

Choosing to use CSS variables or inline Tailwind colors is a decision made at installation time. To switch an existing project between the two approaches, you must delete and re-install your components.

Display ModeToggle in Astro with client:load

In an Astro page, import the ModeToggle component and render it with `<ModeToggle client:load />` to hydrate it on page load. This allows the React component to function interactively in the Astro static site.

Astro inline theme script for dark mode

In Astro, create an inline theme script using `<script is:inline>` to initialize dark mode. The script checks localStorage for a stored theme preference, falls back to `window.matchMedia('(prefers-color-scheme: dark)')` to detect system preference, and adds or removes the 'dark' class on `document.documentElement`. Use a MutationObserver to watch for class changes and sync them to localStorage.

ModeToggle component for Astro dark mode

Create a ModeToggle React component that provides three theme options: 'theme-light', 'dark', and 'system'. The component uses useState to track theme preference and useEffect to sync with `document.documentElement` classList. It renders a DropdownMenu with Sun and Moon icons from lucide-react that scale and rotate based on dark mode state, using Tailwind classes like `dark:scale-0` and `dark:-rotate-90` for transitions.

Astro dark mode theme preference states

The ModeToggle component for Astro supports three theme preference states: 'theme-light' for light mode, 'dark' for dark mode, and 'system' for system preference detection using `window.matchMedia('(prefers-color-scheme: dark)')`.

Dark mode setup by framework

The shadcn/ui documentation provides dark mode implementation guides for multiple frameworks: Next.js, Vite, Astro, Remix, and TanStack Start. Each framework has its own dedicated documentation page for setting up dark mode.

Dark mode setup for Next.js

To add dark mode to a Next.js app, install next-themes with `npm install next-themes`.

ThemeProvider wrapper component for Next.js

Create a theme provider component at components/theme-provider.tsx that wraps the NextThemesProvider from next-themes. It should be marked with 'use client' and accept children and other props to pass through to NextThemesProvider.

Next.js root layout ThemeProvider setup

In app/layout.tsx, wrap the children with the ThemeProvider component. Add suppressHydrationWarning to the html tag. Configure ThemeProvider with attribute="class", defaultTheme="system", enableSystem, and disableTransitionOnChange.

ThemeProvider attributes for Next.js dark mode

The ThemeProvider in Next.js dark mode setup uses the following attributes: attribute="class" (stores theme as class on html element), defaultTheme="system" (defaults to system preference), enableSystem (enable system theme detection), disableTransitionOnChange (prevent CSS transitions when switching themes).

Add mode toggle component for dark mode switching

Place a mode toggle component on your site to allow users to toggle between light and dark modes.

Default theme CSS variables - light mode

Light mode (:root) defaults: --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); --card: oklch(1 0 0); --card-foreground: oklch(0.145 0 0); --popover: oklch(1 0 0); --popover-foreground: oklch(0.145 0 0); --primary: oklch(0.205 0 0); --primary-foreground: oklch(0.985 0 0); --secondary: oklch(0.97 0 0); --secondary-foreground: oklch(0.205 0 0); --muted: oklch(0.97 0 0); --muted-foreground: oklch(0.556 0 0); --accent: oklch(0.97 0 0); --accent-foreground: oklch(0.205 0 0); --destructive: oklch(0.577 0.245 27.325); --border: oklch(0.922 0 0); --input: oklch(0.922 0 0); --ring: oklch(0.708 0 0); --chart-1: oklch(0.646 0.222 41.116); --chart-2: oklch(0.6 0.118 184.704); --chart-3: oklch(0.398 0.07 227.392); --chart-4: oklch(0.828 0.189 84.429); --chart-5: oklch(0.769 0.188 70.08); --sidebar: oklch(0.985 0 0); --sidebar-foreground: oklch(0.145 0 0); --sidebar-primary: oklch(0.205 0 0); --sidebar-primary-foreground: oklch(0.985 0 0); --sidebar-accent: oklch(0.97 0 0); --sidebar-accent-foreground: oklch(0.205 0 0); --sidebar-border: oklch(0.922 0 0); --sidebar-ring: oklch(0.708 0 0);

Default theme CSS variables - dark mode

Dark mode (.dark) defaults: --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --card: oklch(0.205 0 0); --card-foreground: oklch(0.985 0 0); --popover: oklch(0.205 0 0); --popover-foreground: oklch(0.985 0 0); --primary: oklch(0.922 0 0); --primary-foreground: oklch(0.205 0 0); --secondary: oklch(0.269 0 0); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.269 0 0); --muted-foreground: oklch(0.708 0 0); --accent: oklch(0.269 0 0); --accent-foreground: oklch(0.985 0 0); --destructive: oklch(0.704 0.191 22.216); --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); --ring: oklch(0.556 0 0); --chart-1: oklch(0.488 0.243 264.376); --chart-2: oklch(0.696 0.17 162.48); --chart-3: oklch(0.769 0.188 70.08); --chart-4: oklch(0.627 0.265 303.9); --chart-5: oklch(0.645 0.246 16.439); --sidebar: oklch(0.205 0 0); --sidebar-foreground: oklch(0.985 0 0); --sidebar-primary: oklch(0.488 0.243 264.376); --sidebar-primary-foreground: oklch(0.985 0 0); --sidebar-accent: oklch(0.269 0 0); --sidebar-accent-foreground: oklch(0.985 0 0); --sidebar-border: oklch(1 0 0 / 10%); --sidebar-ring: oklch(0.556 0 0);

Tailwind theme configuration for radius variables

In @theme inline, configure radius scale variables: --radius-sm: calc(var(--radius) * 0.6); --radius-md: calc(var(--radius) * 0.8); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) * 1.4); --radius-2xl: calc(var(--radius) * 1.8); --radius-3xl: calc(var(--radius) * 2.2); --radius-4xl: calc(var(--radius) * 2.6);

RTL first-class support

shadcn/ui components have first-class support for right-to-left (RTL) layouts. Text alignment, positioning, and directional styles automatically adapt for languages like Arabic, Hebrew, and Persian.

RTL automatic transformation requires new styles

Automatic RTL transformation via the CLI is only available for projects created using shadcn create with the new styles (base-nova, radix-nova, etc.). For other styles, manual migration is needed.

Components requiring manual RTL migration

The following components are not automatically migrated by the CLI and require manual migration: Calendar, Pagination, and Sidebar. Each has an RTL support section in its documentation.

Icon flipping for RTL

Some icons like ArrowRightIcon or ChevronLeftIcon might need the rtl:rotate-180 class to be flipped correctly in RTL contexts.

RTL animation transformation

The CLI handles animation classes, automatically transforming physical directional animations to their logical equivalents. For example, slide-in-from-right becomes slide-in-from-end. This ensures animations like dropdowns, popovers, and tooltips animate in the correct direction based on the document's text direction.

tw-animate-css library RTL issue

There is a known issue with the tw-animate-css library where logical slide utilities are not working as expected. As a workaround, pass the dir="rtl" prop to portal elements like PopoverContent and TooltipContent.

RTL workaround for Popover with tw-animate-css

When using Popover with tw-animate-css library, add dir="rtl" to PopoverContent to work around the known issue with logical slide utilities.

RTL workaround for Tooltip with tw-animate-css

When using Tooltip with tw-animate-css library, add dir="rtl" to TooltipContent to work around the known issue with logical slide utilities.

Font recommendation for RTL languages

For best RTL experience, use the Noto font family which has proper support for various target languages. Noto pairs well with Inter and Geist fonts.

Installing Noto Sans Arabic font

Install Noto Sans Arabic using Fontsource with: npm install @fontsource-variable/noto-sans-arabic. Then import it in index.css with: @import "@fontsource-variable/noto-sans-arabic";

Noto Sans font variants for different languages

For Hebrew language support, use @fontsource-variable/noto-sans-hebrew instead of the Arabic variant.

Setting Noto Sans as default font in theme

In index.css, set Noto Sans Arabic as the default sans font using @theme inline { --font-sans: "Noto Sans Arabic Variable", sans-serif; }

Give your agent this brain