Extract and centralize the complete theme/design system from the Frontend App project into a standalone, reusable configuration.
This skill teaches you how to extract, centralize, and replicate the complete theme/design system from the Frontend App project into a standalone, reusable configuration. The current codebase uses Tailwind CSS v4 with colors, typography, and spacing scattered across components. This skill shows how to consolidate all design tokens into a single TypeScript configuration module that can be:
@tailwindcss/vite plugintailwind.config.js)@import "tailwindcss"| Token | Value | Usage |
|---|---|---|
| Primary Orange | #F68833 | Main action buttons, links, accents |
| Secondary Orange | #EF6C00 | Hover/active states for primary actions |
| Light Orange BG | #FEF3EB, #FFF3ED | Background highlights |
| Status | Color | Background | File |
|---|---|---|---|
| New | #4285F4 | #ECF3FE | GetStatusStyle.tsx |
| Deal | #27AE60 | #E9F7EF | GetStatusStyle.tsx |
| Rejected | #E40000 | #FCE6E6 | GetStatusStyle.tsx |
| Default | #344054 | #F2F4F7 | GetStatusStyle.tsx |
| Name | Color |
|---|---|
| Orange | #F68833 |
| Purple | #8E63F7 |
| Blue | #1DAEFF |
| Red | #FE7062 |
| Green | #56CA00 |
| Yellow | #FFB400 |
| Teal | #00B9AE |
| Deep Purple | #AB47BC |
| Pink | #F06292 |
| Grey | #90A4AE |
| State | Background | Text |
|---|---|---|
| Assigned | #E9F7EF | text-green-500 |
| Pending | bg-yellow-50 | text-yellow-500 |
| Danger | bg-red-100 | text-red-500 |
#FFFFFF, #F4F5F6gray-50 through gray-900)#ECECEC, #A8A8A8, #CBD5E0| Property | Value |
|---|---|
| Font Family | Roboto, sans-serif |
| Font Weight Regular | 400 |
| Font Weight Medium | 500 |
| Font Weight Bold | 700 |
Uses Tailwind's default spacing: 0, 0.5, 1, 1.5, 2, 2.5, 3, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96
none, sm, base, md, lg, xl, 2xl, 3xl, fullrounded-[4px], rounded-fullsrc/
└── lib/
└── config/
└── theme.ts # Centralized theme configuration
src/
└── types/
└── theme-types.ts # TypeScript interfaces for theme
The theme configuration exports a single theme object with the following shape:
const theme = {
colors: {
primary: { ... },
secondary: { ... },
status: { ... },
avatar: { ... },
badge: { ... },
neutral: { ... }
},
typography: { ... },
spacing: { ... },
borderRadius: { ... }
}
Colors are organized by purpose:
Typography includes:
Spacing references Tailwind scale or custom values.
Review how colors are currently scattered:
colors array)Follow the reference implementation in references/theme-template.ts to create src/lib/config/theme.ts. This consolidates all design tokens into a single source of truth.
Use references/theme-types.ts as a template to create src/types/theme-types.ts. This ensures type safety when using theme values in components.
Replace hardcoded color values with imports from the centralized theme. See references/component-examples.tsx for before/after examples.
Import theme config in src/providers/AppProviders.tsx or create a theme context to make it globally accessible. Components can then consume it via import or context.
Extract all color tokens from the current codebase:
grep -r "#[A-Fa-f0-9]\{6\}" src/ # Find hex colors
grep -r "bg-\|text-" src/components # Find Tailwind colors
Create src/lib/config/theme.ts:
export const theme = {
colors: {
primary: {
main: '#F68833',
dark: '#EF6C00',
light: '#FEF3EB'
},
status: { /* ... */ },
// ... other color groups
},
typography: { /* ... */ },
spacing: { /* ... */ }
}
Create src/types/theme-types.ts:
Define interfaces describing the theme shape for TypeScript completeness.
Update components to use import { theme } from '@/lib/config/theme' instead of hardcoded values.
Export from src/lib/config/index.ts for convenience:
export { theme } from './theme'
Before (hardcoded):
const colors = ['#F68833', '#8E63F7', '#1DAEFF']
const styles = {
background: color,
borderColor: '#ECECEC'
}
After (theme-based):
import { theme } from '@/lib/config/theme'
const colors = theme.colors.avatar.palette
const styles = {
background: color,
borderColor: theme.colors.neutral.border
}
To apply the theme as your project's default:
Create a theme context (optional):
const ThemeContext = React.createContext(theme)
Apply theme on app init in src/App.tsx or src/main.tsx:
document.documentElement.style.setProperty('--color-primary', theme.colors.primary.main)
Import and use in components automatically via centralized imports.
Copy config/theme.ts from this project to your new project's src/lib/config/
Update colors if customizing:
export const theme = {
colors: {
primary: {
main: '#YOUR_COLOR' // Modify as needed
}
}
}
Import in components:
import { theme } from '@/lib/config/theme'
Use CSS variables (optional, for dynamic theming):
:root {
--color-primary: #F68833;
--color-status-new: #4285F4;
}
The same theme.ts can be used as a data source. The theme object is framework-agnostic TypeScript:
// In a Vue component
<script setup>
import { theme } from '@/lib/config/theme'
const primaryColor = theme.colors.primary.main
</script>
<template>
<button :style="{ background: primaryColor }">Click me</button>
</template>
To add a new semantic color group (e.g., error, success):
export const theme = {
colors: {
// ... existing
success: {
main: '#27AE60',
light: '#E9F7EF'
},
error: {
main: '#E40000',
light: '#FCE6E6'
}
}
}
Create separate theme files for different environments:
src/lib/config/
├── theme.base.ts # Shared tokens
├── theme.light.ts # Light theme
├── theme.dark.ts # Dark theme (future)
└── index.ts # Export active theme based on env
Create tailwind.config.ts to use your theme:
import { theme } from './src/lib/config/theme'
export default {
theme: {
colors: {
primary: theme.colors.primary,
status: theme.colors.status,
// ...
}
}
}
Before:
// src/components/button/Button.tsx
const classStyles = {
primary: 'bg-[#F68833] text-white hover:bg-[#EF6C00]',
outline: 'bg-white border-[#ECECEC] border text-black'
}
After:
import { theme } from '@/lib/config/theme'
const classStyles = {
primary: `bg-[${theme.colors.primary.main}] text-white hover:bg-[${theme.colors.primary.dark}]`,
outline: `bg-white border-[${theme.colors.neutral.border}] border text-black`
}
Before:
// src/features/layouts/sidebar/Avatar.tsx
const colors = ['#F68833', '#8E63F7', '#1DAEFF', '#FE7062', '#56CA00', '#FFB400', '#00B9AE', '#AB47BC', '#F06292', '#90A4AE']
After:
import { theme } from '@/lib/config/theme'
const colors = theme.colors.avatar.palette
Before:
// src/components/statusBadge/StatusBadge.tsx
const statusStyles = {
assigned: { bg: '#E9F7EF', text: 'text-green-500' },
pending: { bg: 'bg-yellow-50', text: 'text-yellow-500' }
}
After:
import { theme } from '@/lib/config/theme'
const statusStyles = {
assigned: theme.colors.badge.assigned,
pending: theme.colors.badge.pending
}
src/lib/config/theme.ts - Centralized theme configurationsrc/lib/config/index.ts - Theme barrel exportsrc/types/theme-types.ts - TypeScript type definitions (optional)primary, status) instead of color names (blue123)src/lib/config for easy importsPrerequisites
Often Used Together
Can Reference
references/theme-template.ts for a complete theme.ts implementationreferences/theme-types.ts for TypeScript type definitionsreferences/component-examples.tsx for before/after component usage examples