import { useTheme, useThemeName } from '@tamagui/core'; export const ADMIN_COLORS = { primary: '#4F46E5', // Indigo 600 primaryStrong: '#4338CA', // Indigo 700 accent: '#F43F5E', // Rose 500 accentSoft: '#E0E7FF', // Indigo 100 accentWarm: '#FFE4E6', // Rose 100 warning: '#F59E0B', // Amber 500 success: '#10B981', // Emerald 500 danger: '#EF4444', // Red 500 text: '#0F172A', // Slate 900 textMuted: '#64748B', // Slate 500 textSubtle: '#94A3B8', // Slate 400 border: '#E2E8F0', // Slate 200 surface: '#FFFFFF', surfaceMuted: '#F8FAFC', // Slate 50 backdrop: '#0F172A', }; export const ADMIN_ACTION_COLORS = { settings: '#64748B', // Slate 500 tasks: '#F43F5E', // Rose 500 (Accent) qr: '#10B981', // Emerald 500 images: '#4F46E5', // Indigo 600 (Primary) liveShow: '#F59E0B', // Amber 500 liveShowSettings: '#6366F1', // Indigo 500 guests: '#334155', // Slate 700 guestMessages: '#4F46E5', branding: '#6366F1', photobooth: '#8B5CF6', // Violet 500 recap: '#94A3B8', packages: '#4F46E5', analytics: '#10B981', invites: '#10B981', }; export const ADMIN_GRADIENTS = { primaryCta: `linear-gradient(135deg, ${ADMIN_COLORS.primary}, ${ADMIN_COLORS.primaryStrong})`, softCard: 'linear-gradient(145deg, rgba(255,255,255,1), rgba(248,250,252,0.95))', loginBackground: 'linear-gradient(135deg, #0F172A, #1E293B, #0F172A)', appBackground: 'linear-gradient(180deg, #F1F5F9 0%, #F1F5F9 100%)', appBackgroundDark: 'linear-gradient(180deg, #0F172A 0%, #1E293B 100%)', }; export const ADMIN_MOTION = { tileStaggerMs: 40, }; type Rgb = { r: number; g: number; b: number }; function parseRgb(color: string): Rgb | null { const trimmed = color.trim(); if (trimmed.startsWith('#')) { const hex = trimmed.slice(1); const normalized = hex.length === 3 ? hex.split('').map((ch) => ch + ch).join('') : hex; if (normalized.length === 6) { return { r: Number.parseInt(normalized.slice(0, 2), 16), g: Number.parseInt(normalized.slice(2, 4), 16), b: Number.parseInt(normalized.slice(4, 6), 16), }; } } const rgb = trimmed.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i); if (rgb) { return { r: Number(rgb[1]), g: Number(rgb[2]), b: Number(rgb[3]) }; } const rgba = trimmed.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*([0-9.]+)\)$/i); if (rgba) { return { r: Number(rgba[1]), g: Number(rgba[2]), b: Number(rgba[3]) }; } return null; } export function withAlpha(color: string, alpha: number): string { const rgb = parseRgb(color); if (! rgb) { return color; } return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`; } export function useAdminTheme() { const theme = useTheme(); const themeName = useThemeName(); const themeLabel = String(themeName ?? '').toLowerCase(); const isDark = themeLabel.includes('dark') || themeLabel.includes('night'); const resolveThemeValue = (value: unknown, fallback: string): string => { if (value === undefined || value === null || value === '') { return fallback; } return String(value); }; const background = resolveThemeValue(theme.background?.val, ADMIN_COLORS.surfaceMuted); // Resolve core colors const primary = resolveThemeValue(theme.primary?.val, ADMIN_COLORS.primary); const surface = resolveThemeValue(theme.surface?.val, isDark ? '#0F1B36' : ADMIN_COLORS.surface); const border = resolveThemeValue(theme.borderColor?.val, isDark ? '#1F2A4A' : ADMIN_COLORS.border); const text = resolveThemeValue(theme.color?.val, isDark ? '#F8FAFF' : ADMIN_COLORS.text); // Muted/Subtle should NOT use theme.muted (which is a background color in Tamagui standard) // Instead, we derive them from Text with opacity or use specific palette values if available // But safer is Alpha since it works in both Light (Dark Text) and Dark (Light Text) modes. const muted = withAlpha(text, 0.65); const subtle = withAlpha(text, 0.45); const surfaceMuted = resolveThemeValue(theme.muted?.val, isDark ? '#121F3D' : ADMIN_COLORS.surfaceMuted); const glassSurface = withAlpha(surface, isDark ? 0.90 : 0.85); const glassSurfaceStrong = withAlpha(surface, isDark ? 0.96 : 0.95); const glassBorder = withAlpha(border, 0.5); const glassShadow = isDark ? 'rgba(0, 0, 0, 0.55)' : 'rgba(15, 23, 42, 0.08)'; const appBackground = `linear-gradient(180deg, ${background} 0%, ${isDark ? surface : surfaceMuted} 100%)`; return { theme, background, surface, surfaceMuted, border, text, textStrong: text, // Alias textMuted: muted, // Alias for legacy usage textSubtle: subtle, // Alias for legacy usage muted, // Now properly derived from text color subtle, // Now properly derived from text color primary, accent: resolveThemeValue(theme.accent?.val, ADMIN_COLORS.accent), accentSoft: resolveThemeValue(theme.blue3?.val, ADMIN_COLORS.accentSoft), accentStrong: resolveThemeValue(theme.blue11?.val, ADMIN_COLORS.primaryStrong), successBg: resolveThemeValue(theme.backgroundStrong?.val, '#DCFCE7'), successText: resolveThemeValue(theme.green10?.val, ADMIN_COLORS.success), dangerBg: resolveThemeValue(theme.red3?.val, '#FEE2E2'), dangerText: resolveThemeValue(theme.red11?.val, ADMIN_COLORS.danger), warningBg: resolveThemeValue(theme.yellow3?.val, '#FEF3C7'), warningBorder: resolveThemeValue(theme.yellow6?.val, '#FCD34D'), warningText: resolveThemeValue(theme.yellow11?.val, ADMIN_COLORS.warning), infoBg: resolveThemeValue(theme.blue3?.val, ADMIN_COLORS.accentSoft), infoText: resolveThemeValue(theme.blue10?.val, ADMIN_COLORS.primaryStrong), danger: resolveThemeValue(theme.danger?.val, ADMIN_COLORS.danger), backdrop: resolveThemeValue(theme.backgroundStrong?.val, ADMIN_COLORS.backdrop), overlay: withAlpha(resolveThemeValue(theme.backgroundStrong?.val, ADMIN_COLORS.backdrop), 0.7), shadow: resolveThemeValue(theme.shadowColor?.val, 'rgba(15, 23, 42, 0.08)'), glassSurface, glassSurfaceStrong, glassBorder, glassShadow, appBackground, }; }