Design Principles
Learn about SmoothUI's design system, theming, and customization options.
Design Philosophy
SmoothUI is built on the principles of simplicity, accessibility, and performance. Each component is designed to be beautiful by default while remaining highly customizable.
Beautiful by Default
Components look great out of the box with carefully chosen colors, spacing, and typography.
Accessible First
Built with accessibility in mind, following WCAG guidelines and best practices.
Performance Focused
Optimized for performance with minimal bundle size and efficient animations.
Color System
SmoothUI uses a carefully crafted color system based on OKLCH color space for better color consistency and accessibility. The system includes both light and dark variants.
Brand Colors
Brand Primary
oklch(0.72 0.2 352.53)
Brand Secondary
oklch(0.66 0.21 354.31)
Neutral Colors
The neutral color palette provides a range of grays that work well in both light and dark modes.
50
100
200
300
400
500
600
700
800
900
950
1000
Design System CSS
Add this CSS to your global styles to enable the full SmoothUI design system:
global.css
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-brand: var(--color-brand);
--color-brand-secondary: var(--color-brand-secondary);
--color-smooth-50: var(--color-smooth-50);
--color-smooth-100: var(--color-smooth-100);
--color-smooth-200: var(--color-smooth-200);
--color-smooth-300: var(--color-smooth-300);
--color-smooth-400: var(--color-smooth-400);
--color-smooth-500: var(--color-smooth-500);
--color-smooth-600: var(--color-smooth-600);
--color-smooth-700: var(--color-smooth-700);
--color-smooth-800: var(--color-smooth-800);
--color-smooth-900: var(--color-smooth-900);
--color-smooth-950: var(--color-smooth-950);
--color-smooth-1000: var(--color-smooth-1000);
--color-border: var(--color-smooth-500);
--color-sidebar-ring: var(--color-brand);
--color-sidebar-border: var(--color-smooth-400);
--color-sidebar-accent-foreground: var(--color-smooth-900);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--color-smooth-1000);
--color-sidebar-primary: var(--color-brand);
--color-sidebar-foreground: var(--color-smooth-1000);
--color-sidebar: var(--color-smooth-100);
--color-ring: var(--color-brand);
--color-input: var(--color-smooth-400);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--color-smooth-1000);
--color-accent: var(--color-brand);
--color-muted-foreground: var(--color-smooth-800);
--color-muted: var(--color-smooth-200);
--color-background: var(--color-smooth-50);
--color-foreground: var(--color-smooth-1000);
--color-primary: var(--color-smooth-100);
--color-primary-foreground: var(--color-smooth-950);
--color-secondary: var(--color-smooth-200);
--color-secondary-foreground: var(--color-smooth-900);
--color-popover-foreground: var(--color-smooth-1000);
--color-popover: var(--color-smooth-50);
--color-card-foreground: var(--color-smooth-1000);
--color-card: var(--color-smooth-100);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}
:root {
--color-brand: oklch(0.72 0.2 352.53);
--color-brand-secondary: oklch(0.66 0.21 354.31);
--color-smooth-50: oklch(99.11% 0 0);
--color-smooth-100: oklch(97.91% 0 0);
--color-smooth-200: oklch(96.42% 0 0);
--color-smooth-300: oklch(94.61% 0 0);
--color-smooth-400: oklch(93.1% 0 0);
--color-smooth-500: oklch(91.28% 0 0);
--color-smooth-600: oklch(89.14% 0 0);
--color-smooth-700: oklch(82.97% 0 0);
--color-smooth-800: oklch(65% 0 0);
--color-smooth-900: oklch(61.67% 0 0);
--color-smooth-950: oklch(54.17% 0 0);
--color-smooth-1000: oklch(20.46% 0 0);
--border: var(--color-smooth-300);
--text-primary: var(--color-smooth-200);
--text-quaternary: var(--color-smooth-1000);
--radius: 0.625rem;
}
.dark {
--color-smooth-50: oklch(20.02% 0 0);
--color-smooth-100: oklch(22.64% 0 0);
--color-smooth-200: oklch(25.62% 0 0);
--color-smooth-300: oklch(27.68% 0 0);
--color-smooth-400: oklch(30.12% 0 0);
--color-smooth-500: oklch(32.5% 0 0);
--color-smooth-600: oklch(36.39% 0 0);
--color-smooth-700: oklch(43.13% 0 0);
--color-smooth-800: oklch(54.52% 0 0);
--color-smooth-900: oklch(59.31% 0 0);
--color-smooth-950: oklch(70.58% 0 0);
--color-smooth-1000: oklch(94.61% 0 0);
--border: var(--color-smooth-300);
--text-primary: var(--color-smooth-200);
--text-quaternary: var(--color-smooth-1000);
}
/* Component NumberFlow */
@layer utilities {
.slide-in-up {
animation: slideInUp 0.3s forwards;
}
.slide-out-up {
animation: slideOutUp 0.3s forwards;
}
.slide-in-down {
animation: slideInDown 0.3s forwards;
}
.slide-out-down {
animation: slideOutDown 0.3s forwards;
}
@keyframes slideInUp {
from {
transform: translateY(50px);
filter: blur(5px);
}
to {
transform: translateY(0px);
filter: blur(0px);
}
}
@keyframes slideOutUp {
from {
transform: translateY(0px);
filter: blur(0px);
}
to {
transform: translateY(-50px);
filter: blur(5px);
}
}
@keyframes slideInDown {
from {
transform: translateY(-50px);
filter: blur(5px);
}
to {
transform: translateY(0px);
filter: blur(0px);
}
}
@keyframes slideOutDown {
from {
transform: translateY(0px);
filter: blur(0px);
}
to {
transform: translateY(50px);
filter: blur(5px);
}
}
}
/* Component PowerOffSlide */
@layer utilities {
.loading-shimmer {
text-fill-color: transparent;
-webkit-text-fill-color: transparent;
animation-delay: 0.5s;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: loading-shimmer;
background: var(--text-quaternary)
gradient(
linear,
100% 0,
0 0,
from(var(--text-quaternary)),
color-stop(0.5, var(--text-primary)),
to(var(--text-quaternary))
);
background: var(--text-quaternary) -webkit-gradient(
linear,
100% 0,
0 0,
from(var(--text-quaternary)),
color-stop(0.5, var(--text-primary)),
to(var(--text-quaternary))
);
background-clip: text;
-webkit-background-clip: text;
background-repeat: no-repeat;
background-size: 50% 200%;
display: inline-block;
}
.loading-shimmer {
background-position: -100% top;
}
.loading-shimmer:hover {
-webkit-text-fill-color: var(--text-quaternary);
animation: none;
background: transparent;
}
@keyframes loading-shimmer {
0% {
background-position: -100% top;
}
to {
background-position: 250% top;
}
}
}
/* Component AppleInvites */
@layer utilities {
.gradient-mask-t-0 {
-webkit-mask-image: linear-gradient(#0000, #000);
mask-image: linear-gradient(#0000, #000);
}
}
Customization
SmoothUI components are highly customizable. Here are the main ways to customize them:
CSS Variables
Override CSS variables to customize colors, spacing, and other design tokens globally.
Tailwind Classes
Use Tailwind utility classes to customize individual components or create variants.
Component Props
Many components accept props for customization like size, variant, and color options.