Theming

AppShell uses CSS custom properties for theming, making it fully compatible with shadcn/ui and easy to customize.

9:41

CSS Variables

AppShell components use these CSS custom properties. Values use HSL format without the hsl() wrapper:

globals.css
1:root {
2 /* Background colors */
3 --background: 0 0% 100%;
4 --foreground: 0 0% 3.9%;
5
6 /* Card colors */
7 --card: 0 0% 100%;
8 --card-foreground: 0 0% 3.9%;
9
10 /* Primary colors */
11 --primary: 0 0% 9%;
12 --primary-foreground: 0 0% 98%;
13
14 /* Muted colors */
15 --muted: 0 0% 96.1%;
16 --muted-foreground: 0 0% 45.1%;
17
18 /* Accent colors */
19 --accent: 0 0% 96.1%;
20 --accent-foreground: 0 0% 9%;
21
22 /* Border and input */
23 --border: 0 0% 89.8%;
24 --input: 0 0% 89.8%;
25 --ring: 0 0% 3.9%;
26
27 /* Radius */
28 --radius: 0.5rem;
29}

Dark Mode

Add a .dark class to your root element to enable dark mode:

globals.css
1.dark {
2 --background: 0 0% 3.9%;
3 --foreground: 0 0% 98%;
4
5 --card: 0 0% 3.9%;
6 --card-foreground: 0 0% 98%;
7
8 --primary: 0 0% 98%;
9 --primary-foreground: 0 0% 9%;
10
11 --muted: 0 0% 14.9%;
12 --muted-foreground: 0 0% 63.9%;
13
14 --accent: 0 0% 14.9%;
15 --accent-foreground: 0 0% 98%;
16
17 --border: 0 0% 14.9%;
18 --input: 0 0% 14.9%;
19 --ring: 0 0% 83.1%;
20}

Toggling Theme

Toggle the dark class on the root element, or use a library like next-themes:

tsx
1// Toggle dark mode
2document.documentElement.classList.toggle("dark");
3
4// Or with next-themes
5import { useTheme } from "next-themes";
6
7function ThemeToggle() {
8 const { theme, setTheme } = useTheme();
9
10 return (
11 <button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
12 Toggle Theme
13 </button>
14 );
15}

Custom Themes

Override the default variables to create your own brand theme:

globals.css
1/* Custom brand theme */
2:root {
3 --primary: 221 83% 53%; /* Blue */
4 --primary-foreground: 0 0% 100%;
5
6 --accent: 142 76% 36%; /* Green */
7 --accent-foreground: 0 0% 100%;
8}
9
10.dark {
11 --primary: 217 91% 60%; /* Lighter blue for dark mode */
12 --primary-foreground: 0 0% 100%;
13}

Safe Area Variables

AppShell also sets safe area variables for notched devices:

css
1/* Set automatically by AppShell when safeArea is enabled */
2:root {
3 --sa-top: env(safe-area-inset-top);
4 --sa-bottom: env(safe-area-inset-bottom);
5 --sa-left: env(safe-area-inset-left);
6 --sa-right: env(safe-area-inset-right);
7}
8
9/* Header height for sticky positioning */
10:root {
11 --header-height: 3.5rem;
12}

shadcn/ui Compatibility

AppShell uses the same CSS variable naming convention as shadcn/ui. If you're already using shadcn/ui, AppShell will automatically use your existing theme.