Customization

Theming

Customize Feather UI to match your brand and design system with powerful theming capabilities.

Theme Structure

Feather UI uses CSS variables for theming, making it easy to customize colors, spacing, and more. These variables are defined in your global CSS file and can be modified to match your design system.

Color System

Base colors that power the entire UI

Primary
Main brand color
Secondary
Supplementary color
Accent
Highlight color
Muted
Subtle background
Destructive
For errors and warnings

User Interface Elements

Variables for UI surfaces and interactions

BackgroundPage background
CardCard surfaces
BorderUI boundaries
InputForm controls
RingFocus indicators

CSS Variables Structure

How our CSS variables are organized

CSS Variable Structure
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* Base colors */
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 0 0% 98%;

/* Semantic colors */
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;

/* Component-specific colors */
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;

/* UI element styles */
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 10% 3.9%;

/* Other */
--radius: 0.5rem;

All color values use the HSL format for easy manipulation. Values like 217.2 91.2% 59.8% represent hue, saturation, and lightness.

Dark Mode Support

Automatic Dark Mode

Use the theme provider for easy switching

Feather UI supports dark mode out of the box using the useTheme hook from next-themes.

Light Mode
Dark Mode

Theme Toggle Component

Add this component to your app for theme switching

components/theme-toggle.tsx
TSX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"use client"
 
import * as React from "react"
import { Moon, Sun } from "lucide-react"
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")}
    >
      <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
      <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </Button>
  )
}
The theme toggle uses smooth transitions for a polished user experience.

Customizing Colors

To customize the colors, modify the CSS variables in your global CSS file. Here are some example themes you can use as starting points:

Choose a theme

Select a preset or customize your own colors.

CSS Variables

globals.css (Blue Theme)
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
:root {
  --background: 0 0% 100%;
  --foreground: 222.2 47.4% 11.2%;
 
  --primary: 217.2 91.2% 59.8%;
  --primary-foreground: 0 0% 98%;
  
  --secondary: 214.3 31.8% 91.4%;
  --secondary-foreground: 222.2 47.4% 11.2%;
  
  --accent: 210 40% 96.1%;
  --accent-foreground: 222.2 47.4% 11.2%;
  
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 0 0% 98%;
}

Theme Generator

Generate a custom theme based on your brand color

How it works

Our theme generator creates a complete theme based on a single color. Visit our theme generator tool to create a custom theme for your project.

Open Theme Generator

The generated code can be pasted directly into your globals.css file.

components/theme-generator.tsx
TSX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
"use client"

import { useState } from "react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { generateThemeFromColor } from "@/lib/theme-generator"

export function ThemeGenerator() {
  const [primaryColor, setPrimaryColor] = useState("#3b82f6")
  const [generated, setGenerated] = useState(false)
  const { setTheme } = useTheme()
  
  const handleGenerate = () => {
    // This would generate CSS variables based on the primary color
    const theme = generateThemeFromColor(primaryColor)
    document.documentElement.style.setProperty('--primary', theme.primary)
    // Apply other theme variables...
    
    setGenerated(true)
    // Optionally save theme to localStorage
  }
  
  return (
    <div className="space-y-4">
      <div className="grid gap-2">
        <Label htmlFor="primary-color">Primary Color</Label>
        <div className="flex gap-2">
          <Input 
            id="primary-color"
            type="color"
            value={primaryColor}
            onChange={(e) => setPrimaryColor(e.target.value)}
            className="w-12 p-1 h-10"
          />
          <Input 
            type="text"
            value={primaryColor}
            onChange={(e) => setPrimaryColor(e.target.value)}
            className="flex-1"
          />
        </div>
      </div>
      <Button onClick={handleGenerate} className="w-full">
        Generate Theme
      </Button>
    </div>
  )
}

Theming Best Practices

Color Contrast

Ensure sufficient contrast between text and background colors for accessibility. Test your color combinations with WCAG guidelines.

Semantic Colors

Use colors consistently across your UI. Primary for main actions, destructive for dangerous operations, etc.

Test Both Modes

Always test your theme in both light and dark modes to ensure good readability and visual hierarchy.