inogen/app/lib/theme.ts

292 lines
7.1 KiB
TypeScript

// Theme configuration for the application
export const themeConfig = {
colors: {
// Primary colors (Green)
primary: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d',
950: '#052e16',
},
// Secondary colors (Blue)
secondary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554',
},
// Neutral colors
neutral: {
50: '#fafafa',
100: '#f5f5f5',
200: '#e5e5e5',
300: '#d4d4d4',
400: '#a3a3a3',
500: '#737373',
600: '#525252',
700: '#404040',
800: '#262626',
900: '#171717',
950: '#0a0a0a',
},
// Status colors
success: {
50: '#f0fdf4',
100: '#dcfce7',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
900: '#14532d',
},
error: {
50: '#fef2f2',
100: '#fee2e2',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
900: '#7f1d1d',
},
warning: {
50: '#fffbeb',
100: '#fef3c7',
500: '#f59e0b',
600: '#d97706',
700: '#b45309',
900: '#78350f',
},
info: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
900: '#1e3a8a',
},
},
// Semantic color tokens
semantic: {
light: {
background: '#ffffff',
foreground: '#0a0a0a',
card: '#ffffff',
cardForeground: '#0a0a0a',
popover: '#ffffff',
popoverForeground: '#0a0a0a',
primary: '#22c55e',
primaryForeground: '#ffffff',
secondary: '#f5f5f5',
secondaryForeground: '#0a0a0a',
muted: '#f5f5f5',
mutedForeground: '#737373',
accent: '#f5f5f5',
accentForeground: '#0a0a0a',
destructive: '#ef4444',
destructiveForeground: '#ffffff',
border: '#e5e5e5',
input: '#e5e5e5',
ring: '#22c55e',
},
dark: {
background: '#0a0a0a',
foreground: '#fafafa',
card: '#171717',
cardForeground: '#fafafa',
popover: '#171717',
popoverForeground: '#fafafa',
primary: '#22c55e',
primaryForeground: '#0a0a0a',
secondary: '#262626',
secondaryForeground: '#fafafa',
muted: '#262626',
mutedForeground: '#a3a3a3',
accent: '#262626',
accentForeground: '#fafafa',
destructive: '#ef4444',
destructiveForeground: '#fafafa',
border: '#262626',
input: '#262626',
ring: '#22c55e',
},
},
// Typography
typography: {
fontFamily: {
sans: ['Vazirmatn', 'Inter', 'ui-sans-serif', 'system-ui', 'sans-serif'],
mono: ['ui-monospace', 'SFMono-Regular', 'Consolas', 'monospace'],
},
fontSize: {
xs: '0.75rem',
sm: '0.875rem',
base: '1rem',
lg: '1.125rem',
xl: '1.25rem',
'2xl': '1.5rem',
'3xl': '1.875rem',
'4xl': '2.25rem',
'5xl': '3rem',
},
fontWeight: {
light: '300',
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
extrabold: '800',
},
},
// Spacing
spacing: {
0: '0px',
1: '0.25rem',
2: '0.5rem',
3: '0.75rem',
4: '1rem',
5: '1.25rem',
6: '1.5rem',
8: '2rem',
10: '2.5rem',
12: '3rem',
16: '4rem',
20: '5rem',
24: '6rem',
},
// Border radius
borderRadius: {
none: '0px',
sm: '0.125rem',
base: '0.25rem',
md: '0.375rem',
lg: '0.5rem',
xl: '0.75rem',
'2xl': '1rem',
full: '9999px',
},
// Shadows
boxShadow: {
sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
base: '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
md: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)',
lg: '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
xl: '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
none: '0 0 #0000',
},
};
// CSS custom properties generator
export const generateCSSVariables = (theme: 'light' | 'dark' = 'light') => {
const semanticColors = themeConfig.semantic[theme];
const cssVars: Record<string, string> = {};
// Generate semantic color variables
Object.entries(semanticColors).forEach(([key, value]) => {
cssVars[`--color-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`] = value;
});
// Generate primary color scale
Object.entries(themeConfig.colors.primary).forEach(([key, value]) => {
cssVars[`--color-primary-${key}`] = value;
});
// Generate secondary color scale
Object.entries(themeConfig.colors.secondary).forEach(([key, value]) => {
cssVars[`--color-secondary-${key}`] = value;
});
// Generate neutral color scale
Object.entries(themeConfig.colors.neutral).forEach(([key, value]) => {
cssVars[`--color-neutral-${key}`] = value;
});
// Generate status colors
['success', 'error', 'warning', 'info'].forEach(status => {
Object.entries(themeConfig.colors[status as keyof typeof themeConfig.colors]).forEach(([key, value]) => {
cssVars[`--color-${status}-${key}`] = value;
});
});
// Generate spacing variables
Object.entries(themeConfig.spacing).forEach(([key, value]) => {
cssVars[`--spacing-${key}`] = value;
});
// Generate border radius variables
Object.entries(themeConfig.borderRadius).forEach(([key, value]) => {
cssVars[`--radius-${key}`] = value;
});
return cssVars;
};
// Theme utilities
export const theme = {
// Get color with opacity
color: (colorPath: string, opacity?: number) => {
const baseColor = `var(--color-${colorPath.replace('.', '-')})`;
if (opacity !== undefined) {
return `oklch(from ${baseColor} l c h / ${opacity})`;
}
return baseColor;
},
// Get spacing value
spacing: (size: keyof typeof themeConfig.spacing) => {
return `var(--spacing-${size})`;
},
// Get border radius
radius: (size: keyof typeof themeConfig.borderRadius) => {
return `var(--radius-${size})`;
},
// Quick color access
colors: {
primary: (shade: keyof typeof themeConfig.colors.primary = '500') =>
`var(--color-primary-${shade})`,
secondary: (shade: keyof typeof themeConfig.colors.secondary = '500') =>
`var(--color-secondary-${shade})`,
neutral: (shade: keyof typeof themeConfig.colors.neutral = '500') =>
`var(--color-neutral-${shade})`,
success: (shade: keyof typeof themeConfig.colors.success = '500') =>
`var(--color-success-${shade})`,
error: (shade: keyof typeof themeConfig.colors.error = '500') =>
`var(--color-error-${shade})`,
warning: (shade: keyof typeof themeConfig.colors.warning = '500') =>
`var(--color-warning-${shade})`,
info: (shade: keyof typeof themeConfig.colors.info = '500') =>
`var(--color-info-${shade})`,
},
};
// Export individual color palettes for easy access
export const { colors, typography, spacing, borderRadius, boxShadow } = themeConfig;
export default themeConfig;