import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; // Theme types export type ThemeName = 'cyberpunk' | 'windows-classic' | 'dark-modern' | 'matrix' | 'industrial' | 'otaku' | 'pink-pink'; export interface ThemeColors { primary: string; primaryRgb: string; secondary: string; secondaryRgb: string; accent: string; success: string; error: string; warning: string; bgPrimary: string; bgSecondary: string; bgTertiary: string; textPrimary: string; textSecondary: string; border: string; } export interface Theme { name: ThemeName; displayName: string; colors: ThemeColors; effects: { glow: boolean; scanlines: boolean; gridBg: boolean; animations: boolean; glassMorphism: boolean; }; borderRadius: string; fontStyle: 'tech' | 'classic' | 'modern'; } // Theme Presets export const themes: Record = { 'cyberpunk': { name: 'cyberpunk', displayName: 'Cyberpunk', colors: { primary: '#00f3ff', primaryRgb: '0, 243, 255', secondary: '#bc13fe', secondaryRgb: '188, 19, 254', accent: '#ff0099', success: '#0aff00', error: '#ff0055', warning: '#ffe600', bgPrimary: '#020617', bgSecondary: '#0f172a', bgTertiary: '#1e293b', textPrimary: '#f1f5f9', textSecondary: '#94a3b8', border: 'rgba(0, 243, 255, 0.2)', }, effects: { glow: true, scanlines: true, gridBg: true, animations: true, glassMorphism: true, }, borderRadius: '0px', fontStyle: 'tech', }, 'windows-classic': { name: 'windows-classic', displayName: 'Windows Classic', colors: { primary: '#000080', primaryRgb: '0, 0, 128', secondary: '#008080', secondaryRgb: '0, 128, 128', accent: '#800000', success: '#008000', error: '#ff0000', warning: '#808000', bgPrimary: '#c0c0c0', bgSecondary: '#dfdfdf', bgTertiary: '#ffffff', textPrimary: '#000000', textSecondary: '#404040', border: '#808080', }, effects: { glow: false, scanlines: false, gridBg: false, animations: false, glassMorphism: false, }, borderRadius: '0px', fontStyle: 'classic', }, 'dark-modern': { name: 'dark-modern', displayName: 'Dark Modern', colors: { primary: '#3b82f6', primaryRgb: '59, 130, 246', secondary: '#8b5cf6', secondaryRgb: '139, 92, 246', accent: '#ec4899', success: '#22c55e', error: '#ef4444', warning: '#f59e0b', bgPrimary: '#09090b', bgSecondary: '#18181b', bgTertiary: '#27272a', textPrimary: '#fafafa', textSecondary: '#a1a1aa', border: 'rgba(63, 63, 70, 0.5)', }, effects: { glow: false, scanlines: false, gridBg: false, animations: true, glassMorphism: true, }, borderRadius: '8px', fontStyle: 'modern', }, 'matrix': { name: 'matrix', displayName: 'Matrix', colors: { primary: '#00ff00', primaryRgb: '0, 255, 0', secondary: '#00cc00', secondaryRgb: '0, 204, 0', accent: '#00ff00', success: '#00ff00', error: '#ff0000', warning: '#ffff00', bgPrimary: '#000000', bgSecondary: '#0a0a0a', bgTertiary: '#141414', textPrimary: '#00ff00', textSecondary: '#00aa00', border: 'rgba(0, 255, 0, 0.3)', }, effects: { glow: true, scanlines: true, gridBg: false, animations: true, glassMorphism: false, }, borderRadius: '0px', fontStyle: 'tech', }, 'industrial': { name: 'industrial', displayName: 'Industrial', colors: { primary: '#f97316', primaryRgb: '249, 115, 22', secondary: '#eab308', secondaryRgb: '234, 179, 8', accent: '#dc2626', success: '#16a34a', error: '#dc2626', warning: '#eab308', bgPrimary: '#1c1917', bgSecondary: '#292524', bgTertiary: '#44403c', textPrimary: '#fafaf9', textSecondary: '#a8a29e', border: 'rgba(249, 115, 22, 0.3)', }, effects: { glow: true, scanlines: false, gridBg: false, animations: true, glassMorphism: false, }, borderRadius: '4px', fontStyle: 'tech', }, 'otaku': { name: 'otaku', displayName: 'Otaku Mode', colors: { primary: '#ff6b9d', // 애니메이션 핑크 primaryRgb: '255, 107, 157', secondary: '#c084fc', // 보라색 secondaryRgb: '192, 132, 252', accent: '#fbbf24', // 골드 (별/하이라이트) success: '#4ade80', // 밝은 그린 error: '#f87171', // 소프트 레드 warning: '#fcd34d', // 옐로우 bgPrimary: '#1a1025', // 다크 퍼플 bgSecondary: '#2d1f3d', // 미드 퍼플 bgTertiary: '#3d2a54', // 라이트 퍼플 textPrimary: '#fdf4ff', // 거의 화이트 (핑크톤) textSecondary: '#d8b4fe', // 라벤더 border: 'rgba(255, 107, 157, 0.3)', }, effects: { glow: true, scanlines: false, gridBg: true, animations: true, glassMorphism: true, }, borderRadius: '12px', fontStyle: 'modern', }, 'pink-pink': { name: 'pink-pink', displayName: 'Pink Pink', colors: { primary: '#ff69b4', // 핫핑크 primaryRgb: '255, 105, 180', secondary: '#ff1493', // 딥핑크 secondaryRgb: '255, 20, 147', accent: '#ffb6c1', // 라이트핑크 success: '#98fb98', // 페일그린 error: '#ff6b6b', // 코랄레드 warning: '#ffa07a', // 라이트살몬 bgPrimary: '#fff0f5', // 라벤더블러쉬 (밝은 배경) bgSecondary: '#ffe4e9', // 미스티로즈 bgTertiary: '#ffccd5', // 핑크 textPrimary: '#8b008b', // 다크마젠타 textSecondary: '#c71585', // 미디엄바이올렛레드 border: 'rgba(255, 105, 180, 0.4)', }, effects: { glow: true, scanlines: false, gridBg: false, animations: true, glassMorphism: true, }, borderRadius: '16px', fontStyle: 'modern', }, }; interface ThemeContextType { theme: Theme; themeName: ThemeName; setTheme: (name: ThemeName) => void; availableThemes: ThemeName[]; } const ThemeContext = createContext(undefined); export const useTheme = () => { const context = useContext(ThemeContext); if (!context) { throw new Error('useTheme must be used within ThemeProvider'); } return context; }; interface ThemeProviderProps { children: ReactNode; } export const ThemeProvider: React.FC = ({ children }) => { const [themeName, setThemeName] = useState(() => { // Load from localStorage on initial render const saved = localStorage.getItem('app-theme'); return (saved as ThemeName) || 'cyberpunk'; }); const theme = themes[themeName]; // Apply CSS variables when theme changes useEffect(() => { const root = document.documentElement; const colors = theme.colors; // Set CSS variables root.style.setProperty('--color-primary', colors.primary); root.style.setProperty('--color-primary-rgb', colors.primaryRgb); root.style.setProperty('--color-secondary', colors.secondary); root.style.setProperty('--color-secondary-rgb', colors.secondaryRgb); root.style.setProperty('--color-accent', colors.accent); root.style.setProperty('--color-success', colors.success); root.style.setProperty('--color-error', colors.error); root.style.setProperty('--color-warning', colors.warning); root.style.setProperty('--color-bg-primary', colors.bgPrimary); root.style.setProperty('--color-bg-secondary', colors.bgSecondary); root.style.setProperty('--color-bg-tertiary', colors.bgTertiary); root.style.setProperty('--color-text-primary', colors.textPrimary); root.style.setProperty('--color-text-secondary', colors.textSecondary); root.style.setProperty('--color-border', colors.border); root.style.setProperty('--border-radius', theme.borderRadius); // Set data attribute for theme-specific CSS root.setAttribute('data-theme', themeName); // Save to localStorage localStorage.setItem('app-theme', themeName); }, [theme, themeName]); const setTheme = (name: ThemeName) => { setThemeName(name); }; return ( {children} ); };