Theming & Styling
Learn how to customize colors, themes, and styling with Tailwind CSS and shadcn/ui.
The starter kit uses Tailwind CSS for styling and shadcn/ui components backed by Base UI. This gives you complete control over the visual appearance of your application while keeping accessible interaction behavior in unstyled primitives.
Color System
The color system is based on CSS variables defined in app/globals.css:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark mode colors */
}Tailwind Configuration
The starter kit uses Tailwind CSS v4, which uses CSS-based configuration instead of a config file. All configuration is done in app/globals.css:
@import 'tailwindcss';
@import 'tw-animate-css';
/* Specify content paths */
@source "./**/*.{ts,tsx}";
@source "../components/**/*.{ts,tsx}";
@source "../lib/**/*.{ts,tsx}";
@source "../hooks/**/*.{ts,tsx}";
/* Custom dark mode variant */
@custom-variant dark (&:is(.dark *));
/* Define theme values */
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
}To add new content paths, add more @source directives. To customize theme values, add them to the @theme inline block.
shadcn/ui Components
The starter kit uses the Base UI variant of shadcn/ui. The source lives in components/ui/, so you can change the styles and composition directly. Base UI supplies the accessible behavior for dialogs, menus, selects, tooltips and other interactive primitives.
The repository's components.json sets base-nova as its shadcn style. The CLI therefore installs compatible Base UI components instead of Radix variants.
Installing Components
You can install additional components using the shadcn CLI:
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add dialogCustomizing Components
Components are located in components/ui/ and can be customized directly:
import type * as React from 'react';
import { Button as ButtonPrimitive } from '@base-ui/react/button';
export type ButtonProps = ButtonPrimitive.Props & {
loading?: boolean;
};
function Button({ children, loading = false, ...props }: ButtonProps) {
return (
<ButtonPrimitive
disabled={props.disabled || loading}
{...props}
>
{loading ? 'Loading…' : children}
</ButtonPrimitive>
);
}
export { Button };Base UI uses the render prop for composition. When an installed component documents render, prefer it over Radix's former asChild pattern:
<DialogTrigger render={<Button variant="outline" />}>Open dialog</DialogTrigger>Dark Mode
Dark mode is automatically handled by the theme system. Users can toggle between light and dark themes:
'use client';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
export function ThemeToggle() {
const { theme, setTheme } = useTheme();
return (
<Button
variant="outline"
size="icon"
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
>
{/* Toggle icon */}
</Button>
);
}Global Styles
Customize global styles in app/globals.css:
@import 'tailwindcss';
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}Custom Themes
You can create custom themes by modifying the CSS variables:
[data-theme='custom'] {
--primary: 142 76% 36%;
--primary-foreground: 355 100% 97%;
/* ... other custom colors */
}Then apply the theme:
<html
lang="en"
data-theme="custom"
>
{/* ... */}
</html>