2 * EverydayPOS Theme System
3 * Defines color palettes and styling for different themes
6export interface Theme {
35export const themes: Record<string, Theme> = {
39 description: 'Classic teal and mint - the original EverydayPOS look',
55 shadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
56 shadowSm: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
62 focus: '0 0 0 3px rgba(16, 185, 129, 0.2)',
68 description: 'Deep blues and purples for a sophisticated dark aesthetic',
84 shadow: '0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.3)',
85 shadowSm: '0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -1px rgba(0, 0, 0, 0.2)',
91 focus: '0 0 0 3px rgba(139, 92, 246, 0.4)',
97 description: 'Vibrant coral, magenta and gold - tropical energy',
113 shadow: '0 18px 48px rgba(255,107,157,0.25)',
114 shadowSm: '0 8px 20px rgba(255,107,157,0.15)',
120 focus: '0 0 0 4px rgba(255,107,157,0.3)',
125 name: 'Emerald Forest',
126 description: 'Vibrant emerald and lime - fresh and energizing',
142 shadow: '0 18px 48px rgba(16,185,129,0.25)',
143 shadowSm: '0 8px 20px rgba(16,185,129,0.15)',
149 focus: '0 0 0 4px rgba(16,185,129,0.3)',
154 name: 'Electric Ocean',
155 description: 'Bright turquoise and aqua - refreshing and modern',
171 shadow: '0 18px 48px rgba(0,188,212,0.3)',
172 shadowSm: '0 8px 20px rgba(0,188,212,0.2)',
178 focus: '0 0 0 4px rgba(0,188,212,0.35)',
184 description: 'Bold fuchsia and magenta - confident and energetic',
200 shadow: '0 18px 48px rgba(233,30,99,0.25)',
201 shadowSm: '0 8px 20px rgba(233,30,99,0.15)',
207 focus: '0 0 0 4px rgba(233,30,99,0.3)',
213 description: '80s inspired with electric purple, hot pink and cyan',
229 shadow: '0 18px 48px rgba(156,39,176,0.25)',
230 shadowSm: '0 8px 20px rgba(156,39,176,0.15)',
236 focus: '0 0 0 4px rgba(156,39,176,0.3)',
241 name: 'Cosmic Purple',
242 description: 'Vivid violet and electric purple - otherworldly',
258 shadow: '0 18px 48px rgba(142,36,170,0.3)',
259 shadowSm: '0 8px 20px rgba(142,36,170,0.2)',
265 focus: '0 0 0 4px rgba(142,36,170,0.35)',
271 description: 'Bright yellow and orange - cheerful and optimistic',
287 shadow: '0 18px 48px rgba(255,193,7,0.3)',
288 shadowSm: '0 8px 20px rgba(255,193,7,0.2)',
294 focus: '0 0 0 4px rgba(255,193,7,0.3)',
300 description: 'Vibrant cyans and magentas for a bold, modern look',
316 shadow: '0 18px 48px rgba(6,182,212,0.4)',
317 shadowSm: '0 8px 20px rgba(6,182,212,0.3)',
323 focus: '0 0 0 4px rgba(6,182,212,0.4)',
329 description: 'Futuristic gradients and neon accents for the decentralized era',
345 shadow: '0 18px 48px rgba(124,58,237,0.5), 0 0 80px rgba(124,58,237,0.15)',
346 shadowSm: '0 8px 20px rgba(124,58,237,0.3), 0 0 40px rgba(124,58,237,0.1)',
352 focus: '0 0 0 4px rgba(124,58,237,0.4), 0 0 20px rgba(124,58,237,0.2)',
357 name: 'Cartridge World',
358 description: 'Bold orange and red - powered by Cartridge World',
374 shadow: '0 18px 48px rgba(255,102,0,0.25)',
375 shadowSm: '0 8px 20px rgba(255,102,0,0.15)',
381 focus: '0 0 0 4px rgba(255,102,0,0.3)',
387 description: 'Pure black and white for maximum contrast and focus',
403 shadow: '0 18px 48px rgba(0,0,0,0.15)',
404 shadowSm: '0 8px 20px rgba(0,0,0,0.1)',
410 focus: '0 0 0 3px rgba(0,0,0,0.2)',
414export const defaultTheme = 'fieldpine';
416const CUSTOM_THEMES_KEY = 'everydaypos_custom_themes';
418// Load custom themes from localStorage
419export function loadCustomThemes(): Record<string, Theme> {
420 if (typeof window === 'undefined') return {};
423 const stored = localStorage.getItem(CUSTOM_THEMES_KEY);
425 return JSON.parse(stored);
428 console.error('Error loading custom themes:', error);
433// Save custom theme to localStorage
434export function saveCustomTheme(theme: Theme): void {
435 if (typeof window === 'undefined') return;
438 const customThemes = loadCustomThemes();
439 customThemes[theme.id] = theme;
440 localStorage.setItem(CUSTOM_THEMES_KEY, JSON.stringify(customThemes));
442 console.error('Error saving custom theme:', error);
446// Delete custom theme from localStorage
447export function deleteCustomTheme(themeId: string): void {
448 if (typeof window === 'undefined') return;
451 const customThemes = loadCustomThemes();
452 delete customThemes[themeId];
453 localStorage.setItem(CUSTOM_THEMES_KEY, JSON.stringify(customThemes));
455 console.error('Error deleting custom theme:', error);
459// Get all themes (built-in + custom)
460export function getAllThemes(): Record<string, Theme> {
461 return { ...themes, ...loadCustomThemes() };
464export function getTheme(themeId: string): Theme {
465 const allThemes = getAllThemes();
466 return allThemes[themeId] || themes[defaultTheme];
469export function getThemeList(): { id: string; name: string; description: string; isCustom?: boolean }[] {
470 const allThemes = getAllThemes();
471 return Object.values(allThemes).map(theme => ({
474 description: theme.description,
475 isCustom: !themes[theme.id],