Theming
Learn how to style your application.
shadcn/ui
The starter kit uses shadcn/ui, which is essentially a set of Tailwind CSS-styled components based on Radix UI and enhanced with Embla Carousel, Vaul, Sonner and custom implementations.
Tailwind
In the tooling/tailwind/index.js
file you can configure the Tailwind CSS theme. It's used across the monorepo, ensuring a consistent theme. This includes colors, spacing, border radius and animations.
import animate from 'tailwindcss-animate';
import { fontFamily } from 'tailwindcss/defaultTheme';
/** @type {import("tailwindcss").Config} */
const config = {
darkMode: ['class'],
content: [
'../../apps/dashboard/**/*.{ts,tsx}',
'../../apps/marketing/**/*.{ts,tsx}',
'../../packages/ui/**/*.{ts,tsx}',
'!**/.next',
'!**/.cache',
'!**/.content-collections',
'!**/.turbo',
'!**/node_modules',
'!**/build',
'!**/dist'
],
theme: {
container: {
center: true,
padding: '2rem',
screens: {
'2xl': '1400px'
}
},
extend: {
fontFamily: {
sans: ['var(--font-sans)', ...fontFamily.sans],
mono: ['var(--font-mono)', ...fontFamily.mono]
},
colors: {
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))'
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))'
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))'
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))'
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))'
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))'
},
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))'
},
sidebar: {
DEFAULT: 'hsl(var(--sidebar-background))',
foreground: 'hsl(var(--sidebar-foreground))',
primary: 'hsl(var(--sidebar-primary))',
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
accent: 'hsl(var(--sidebar-accent))',
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
border: 'hsl(var(--sidebar-border))',
ring: 'hsl(var(--sidebar-ring))'
}
},
backgroundImage: {
'diagonal-lines':
'repeating-linear-gradient(-45deg, hsl(var(--background)), hsl(var(--border)) 1px, hsl(var(--background)) 1px, hsl(var(--background)) 8px)'
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
},
keyframes: {
// ...
},
animation: {
// ...
}
}
},
plugins: [animate]
};
export default config;
Font
You change the font individually for each app. Open
- Dashboard:
apps/dashboard/app/layout.tsx
- Marketing:
apps/marketing/app/layout.tsx
and change the current font
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'] });
to some other font, e.g. Geist
font.
Global styles
If you need to modify the global css style, have a look at packages/ui/src/styles/globals.css
. We configured a few global styles like disabled the chrome number input spinner in favor of our own number input component.
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type='number'] {
-moz-appearance: textfield;
}