roadmap-kit 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,8 +8,10 @@ import {
8
8
  HelpCircle, GitCommit, Bot, Wrench, Activity, Grid, Play,
9
9
  ArrowRight, Minus as MinusIcon, PlusCircle, MinusCircle, GitBranch,
10
10
  Globe, Command, Columns, List, Link2, MessageSquare, Timer,
11
- BarChart3, FileDown, History, Bell, Keyboard, Filter
11
+ BarChart3, FileDown, History, Bell, Keyboard, Filter, Palette,
12
+ Sun, Moon
12
13
  } from 'lucide-react';
14
+ import { themes, DEFAULT_THEME, getTheme } from './themes.js';
13
15
 
14
16
  // ============ TOAST NOTIFICATION SYSTEM ============
15
17
  const ToastContext = createContext();
@@ -75,6 +77,86 @@ const useToast = () => {
75
77
  return context.toast;
76
78
  };
77
79
 
80
+ // ============ THEME SYSTEM ============
81
+ const ThemeContext = createContext();
82
+
83
+ function ThemeProvider({ children, initialTheme = DEFAULT_THEME, initialColorMode = 'light' }) {
84
+ const [currentTheme, setCurrentTheme] = useState(initialTheme);
85
+ const [colorMode, setColorModeState] = useState(initialColorMode);
86
+
87
+ // Apply theme and color mode to document
88
+ useEffect(() => {
89
+ document.documentElement.setAttribute('data-theme', currentTheme);
90
+ // Apply light/dark class
91
+ if (colorMode === 'dark') {
92
+ document.documentElement.classList.add('dark');
93
+ document.documentElement.classList.remove('light');
94
+ } else {
95
+ document.documentElement.classList.add('light');
96
+ document.documentElement.classList.remove('dark');
97
+ }
98
+ }, [currentTheme, colorMode]);
99
+
100
+ const setTheme = useCallback(async (themeId) => {
101
+ if (!themes[themeId]) return;
102
+ setCurrentTheme(themeId);
103
+
104
+ // Save to server
105
+ try {
106
+ await fetch('/api/auth/profile', {
107
+ method: 'PUT',
108
+ headers: { 'Content-Type': 'application/json' },
109
+ body: JSON.stringify({ theme: themeId })
110
+ });
111
+ } catch (err) {
112
+ console.error('Error saving theme:', err);
113
+ }
114
+ }, []);
115
+
116
+ const setColorMode = useCallback(async (mode) => {
117
+ if (!['light', 'dark'].includes(mode)) return;
118
+ setColorModeState(mode);
119
+
120
+ // Save to server
121
+ try {
122
+ await fetch('/api/auth/profile', {
123
+ method: 'PUT',
124
+ headers: { 'Content-Type': 'application/json' },
125
+ body: JSON.stringify({ colorMode: mode })
126
+ });
127
+ } catch (err) {
128
+ console.error('Error saving color mode:', err);
129
+ }
130
+ }, []);
131
+
132
+ const toggleColorMode = useCallback(() => {
133
+ setColorMode(colorMode === 'dark' ? 'light' : 'dark');
134
+ }, [colorMode, setColorMode]);
135
+
136
+ const value = useMemo(() => ({
137
+ theme: currentTheme,
138
+ themeConfig: getTheme(currentTheme),
139
+ setTheme,
140
+ themes,
141
+ colorMode,
142
+ setColorMode,
143
+ toggleColorMode,
144
+ isDark: colorMode === 'dark'
145
+ }), [currentTheme, setTheme, colorMode, setColorMode, toggleColorMode]);
146
+
147
+ return (
148
+ <ThemeContext.Provider value={value}>
149
+ {children}
150
+ </ThemeContext.Provider>
151
+ );
152
+ }
153
+
154
+ const useTheme = () => {
155
+ const context = useContext(ThemeContext);
156
+ if (!context) throw new Error('useTheme must be used within ThemeProvider');
157
+ return context;
158
+ };
159
+
78
160
  // ============ GLOBAL SEARCH MODAL ============
79
161
  function GlobalSearchModal({ isOpen, onClose, roadmap, onNavigate, t }) {
80
162
  const [query, setQuery] = useState('');
@@ -237,9 +319,9 @@ function useKeyboardShortcuts(handlers) {
237
319
  return;
238
320
  }
239
321
 
240
- // Number keys 1-7 for tab navigation
322
+ // Number keys 1-8 for tab navigation
241
323
  if (!e.ctrlKey && !e.metaKey && !e.altKey) {
242
- if (e.key >= '1' && e.key <= '7') {
324
+ if (e.key >= '1' && e.key <= '8') {
243
325
  e.preventDefault();
244
326
  handlers.onTabChange?.(parseInt(e.key) - 1);
245
327
  return;
@@ -318,7 +400,7 @@ const translations = {
318
400
  setup: 'SETUP',
319
401
  features: 'FEATURES',
320
402
  resources: 'RESOURCES',
321
- debt: 'DEBT',
403
+ debt: 'TECH DEBT',
322
404
  info: 'INFO',
323
405
  settings: 'SETTINGS',
324
406
  help: 'HELP'
@@ -432,7 +514,39 @@ const translations = {
432
514
  effort: 'Effort',
433
515
  source: 'Source',
434
516
  bySeverity: 'BY SEVERITY',
435
- items: 'items'
517
+ items: 'items',
518
+ // Severity levels
519
+ high: 'HIGH',
520
+ medium: 'MEDIUM',
521
+ low: 'LOW',
522
+ // Status
523
+ status: 'STATUS',
524
+ pending: 'PENDING',
525
+ inProgress: 'IN PROGRESS',
526
+ resolved: 'RESOLVED',
527
+ // Actions
528
+ filter: 'FILTER',
529
+ all: 'ALL',
530
+ clear: 'CLEAR',
531
+ addDebt: 'ADD DEBT',
532
+ addFirstDebt: 'ADD FIRST DEBT',
533
+ noMatch: 'NO ITEMS MATCH FILTERS',
534
+ // Details
535
+ description: 'DESCRIPTION',
536
+ impact: 'IMPACT',
537
+ solution: 'PROPOSED SOLUTION',
538
+ affectedFiles: 'AFFECTED FILES',
539
+ feature: 'FEATURE',
540
+ task: 'TASK',
541
+ priority: 'PRIORITY',
542
+ notEstimated: 'Not estimated',
543
+ // Dates
544
+ created: 'Created',
545
+ resolvedAt: 'Resolved',
546
+ assigned: 'Assigned',
547
+ due: 'Due',
548
+ // Schema
549
+ jsonSchema: 'JSON SCHEMA FOR TECHNICAL DEBT'
436
550
  },
437
551
  // Info
438
552
  info: {
@@ -664,7 +778,7 @@ const translations = {
664
778
  setup: 'ASISTENTE',
665
779
  features: 'ESTADO',
666
780
  resources: 'RECURSOS',
667
- debt: 'DEUDA',
781
+ debt: 'DEUDA TÉCNICA',
668
782
  info: 'INFO',
669
783
  settings: 'CONFIG',
670
784
  help: 'AYUDA'
@@ -778,7 +892,39 @@ const translations = {
778
892
  effort: 'Esfuerzo',
779
893
  source: 'Origen',
780
894
  bySeverity: 'POR SEVERIDAD',
781
- items: 'elementos'
895
+ items: 'elementos',
896
+ // Niveles de severidad
897
+ high: 'ALTA',
898
+ medium: 'MEDIA',
899
+ low: 'BAJA',
900
+ // Estado
901
+ status: 'ESTADO',
902
+ pending: 'PENDIENTE',
903
+ inProgress: 'EN PROGRESO',
904
+ resolved: 'RESUELTO',
905
+ // Acciones
906
+ filter: 'FILTRAR',
907
+ all: 'TODOS',
908
+ clear: 'LIMPIAR',
909
+ addDebt: 'AÑADIR DEUDA',
910
+ addFirstDebt: 'AÑADIR PRIMERA DEUDA',
911
+ noMatch: 'NINGÚN ELEMENTO COINCIDE CON LOS FILTROS',
912
+ // Detalles
913
+ description: 'DESCRIPCIÓN',
914
+ impact: 'IMPACTO',
915
+ solution: 'SOLUCIÓN PROPUESTA',
916
+ affectedFiles: 'ARCHIVOS AFECTADOS',
917
+ feature: 'CARACTERÍSTICA',
918
+ task: 'TAREA',
919
+ priority: 'PRIORIDAD',
920
+ notEstimated: 'Sin estimar',
921
+ // Fechas
922
+ created: 'Creado',
923
+ resolvedAt: 'Resuelto',
924
+ assigned: 'Asignado',
925
+ due: 'Vence',
926
+ // Schema
927
+ jsonSchema: 'ESQUEMA JSON PARA DEUDA TÉCNICA'
782
928
  },
783
929
  // Info
784
930
  info: {
@@ -1207,6 +1353,9 @@ function App() {
1207
1353
  const [loginError, setLoginError] = useState(null);
1208
1354
  const [teamMembers, setTeamMembers] = useState([]); // Users for task assignment
1209
1355
 
1356
+ // Theme
1357
+ const { setTheme } = useTheme();
1358
+
1210
1359
  // Confirmation modal state
1211
1360
  const [confirmModal, setConfirmModal] = useState({
1212
1361
  show: false,
@@ -1280,6 +1429,14 @@ function App() {
1280
1429
  authEnabled: data.authEnabled,
1281
1430
  user: data.user || null
1282
1431
  });
1432
+ // Sync theme and color mode from user
1433
+ if (data.user?.theme) {
1434
+ document.documentElement.setAttribute('data-theme', data.user.theme);
1435
+ }
1436
+ if (data.user?.colorMode) {
1437
+ document.documentElement.classList.remove('light', 'dark');
1438
+ document.documentElement.classList.add(data.user.colorMode);
1439
+ }
1283
1440
  if (data.authenticated || !data.authEnabled) {
1284
1441
  loadRoadmap();
1285
1442
  loadTeamMembers();
@@ -1307,6 +1464,14 @@ function App() {
1307
1464
  authEnabled: true,
1308
1465
  user: data.user
1309
1466
  });
1467
+ // Sync theme and color mode from user
1468
+ if (data.user?.theme) {
1469
+ document.documentElement.setAttribute('data-theme', data.user.theme);
1470
+ }
1471
+ if (data.user?.colorMode) {
1472
+ document.documentElement.classList.remove('light', 'dark');
1473
+ document.documentElement.classList.add(data.user.colorMode);
1474
+ }
1310
1475
  loadRoadmap();
1311
1476
  } else {
1312
1477
  setLoginError(data.error || 'Error de autenticacion');
@@ -1339,8 +1504,31 @@ function App() {
1339
1504
  return;
1340
1505
  }
1341
1506
  }
1342
- if (!response.ok) throw new Error('No se pudo cargar roadmap.json');
1343
1507
  const data = await response.json();
1508
+ // Handle case when roadmap.json doesn't exist - redirect to setup
1509
+ if (data.exists === false || data.redirectToSetup) {
1510
+ setRoadmap({ project_info: { name: '', description: '', stack: [] }, features: [] });
1511
+ setActiveTab('setup');
1512
+ setLoading(false);
1513
+ return;
1514
+ }
1515
+ if (!response.ok) throw new Error('No se pudo cargar roadmap.json');
1516
+ // Recalculate progress on load to ensure consistency
1517
+ if (data.features) {
1518
+ data.features.forEach(feature => {
1519
+ if (feature.tasks?.length > 0) {
1520
+ const completed = feature.tasks.filter(t => t.status === 'completed').length;
1521
+ feature.progress = Math.round((completed / feature.tasks.length) * 100);
1522
+ } else {
1523
+ feature.progress = 0;
1524
+ }
1525
+ });
1526
+ const allTasks = data.features.flatMap(f => f.tasks || []);
1527
+ if (allTasks.length > 0) {
1528
+ const totalCompleted = allTasks.filter(t => t.status === 'completed').length;
1529
+ data.project_info.total_progress = Math.round((totalCompleted / allTasks.length) * 100);
1530
+ }
1531
+ }
1344
1532
  setRoadmap(data);
1345
1533
  setHasChanges(false);
1346
1534
  } catch (err) {
@@ -1597,13 +1785,13 @@ function App() {
1597
1785
  if (error) {
1598
1786
  return (
1599
1787
  <div className="min-h-screen flex items-center justify-center bg-black p-4">
1600
- <div className="terminal-card p-8 max-w-md w-full">
1788
+ <div className="theme-card p-8 max-w-md w-full">
1601
1789
  <div className="flex items-center gap-3 mb-6">
1602
- <div className="led led-red" />
1790
+ <div className="led theme-led theme-led-danger" />
1603
1791
  <span className="font-mono text-alert text-sm tracking-wider">ERROR</span>
1604
1792
  </div>
1605
1793
  <p className="font-mono text-gray-400 text-sm mb-6">{error}</p>
1606
- <button onClick={loadRoadmap} className="btn-terminal w-full">
1794
+ <button onClick={loadRoadmap} className="theme-btn-primary w-full">
1607
1795
  RETRY
1608
1796
  </button>
1609
1797
  </div>
@@ -1621,7 +1809,7 @@ function App() {
1621
1809
  {/* <div className="scanlines" /> */}
1622
1810
 
1623
1811
  {/* Sidebar */}
1624
- <aside className={`fixed left-0 top-0 h-full sidebar-terminal z-50 transition-all duration-300 ${sidebarCollapsed ? 'w-16' : 'w-64'}`}>
1812
+ <aside className={`fixed left-0 top-0 h-full theme-sidebar z-50 transition-all duration-300 ${sidebarCollapsed ? 'w-16' : 'w-64'}`}>
1625
1813
  <div className="flex flex-col h-full">
1626
1814
  {/* Logo */}
1627
1815
  <div className="p-4 border-b border-matrix/10">
@@ -1646,8 +1834,8 @@ function App() {
1646
1834
  <span className="font-mono text-[10px] text-gray-500 tracking-widest">{language === 'es' ? 'PROGRESO' : 'PROGRESS'}</span>
1647
1835
  <span className="font-display text-2xl text-matrix">{projectInfo.total_progress || 0}%</span>
1648
1836
  </div>
1649
- <div className="progress-brutal">
1650
- <div className="progress-brutal-fill" style={{ width: `${projectInfo.total_progress || 0}%` }} />
1837
+ <div className="theme-progress">
1838
+ <div className="theme-progress-fill" style={{ width: `${projectInfo.total_progress || 0}%` }} />
1651
1839
  </div>
1652
1840
  </div>
1653
1841
  <div className="grid grid-cols-3 gap-2 text-center">
@@ -1676,7 +1864,7 @@ function App() {
1676
1864
  <button
1677
1865
  key={item.id}
1678
1866
  onClick={() => setActiveTab(item.id)}
1679
- className={`nav-terminal w-full flex items-center gap-3 px-4 py-3 transition-all ${
1867
+ className={`theme-nav-item w-full flex items-center gap-3 px-4 py-3 transition-all ${
1680
1868
  isActive ? 'active' : 'text-gray-500 hover:text-gray-300 hover:bg-white/[0.02]'
1681
1869
  } ${sidebarCollapsed ? 'justify-center px-2' : 'pl-8'}`}
1682
1870
  >
@@ -1699,7 +1887,7 @@ function App() {
1699
1887
  </div>
1700
1888
  )}
1701
1889
  {hasChanges && !sidebarCollapsed && (
1702
- <button onClick={saveRoadmap} disabled={saving} className="btn-terminal w-full flex items-center justify-center gap-2">
1890
+ <button onClick={saveRoadmap} disabled={saving} className="theme-btn-primary w-full flex items-center justify-center gap-2">
1703
1891
  {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
1704
1892
  {t('common.save')}
1705
1893
  </button>
@@ -1772,7 +1960,7 @@ function App() {
1772
1960
  </header>
1773
1961
 
1774
1962
  {/* Content Area */}
1775
- <div className="p-6 pb-24 grid-bg min-h-[calc(100vh-120px)]">
1963
+ <div className="p-6 pb-24 theme-grid-bg min-h-[calc(100vh-120px)]">
1776
1964
  {activeTab === 'features' && (
1777
1965
  <FeaturesTab
1778
1966
  features={filteredFeatures}
@@ -1814,7 +2002,7 @@ function App() {
1814
2002
  )}
1815
2003
  {activeTab === 'metrics' && <MetricsTab roadmap={roadmap} language={language} />}
1816
2004
  {activeTab === 'resources' && <ResourcesTab resources={projectInfo.shared_resources || {}} />}
1817
- {activeTab === 'debt' && <DebtTab roadmap={roadmap} setRoadmap={setRoadmap} setHasChanges={setHasChanges} />}
2005
+ {activeTab === 'debt' && <DebtTab roadmap={roadmap} setRoadmap={setRoadmap} setHasChanges={setHasChanges} t={t} />}
1818
2006
  {activeTab === 'info' && <InfoTab projectInfo={projectInfo} />}
1819
2007
  {activeTab === 'settings' && <SettingsTab roadmap={roadmap} setRoadmap={setRoadmap} setHasChanges={setHasChanges} authState={authState} showConfirm={showConfirm} showAlert={showAlert} t={t} language={language} changeLanguage={changeLanguage} />}
1820
2008
  {activeTab === 'help' && <HelpTab t={t} language={language} />}
@@ -2256,7 +2444,7 @@ function AIGeneratorModal({ roadmap, setRoadmap, setHasChanges, onClose }) {
2256
2444
  - Notificaciones por email
2257
2445
  - Integración con Stripe para pagos
2258
2446
  - API REST documentada con Swagger`}
2259
- className="w-full h-64 input-terminal p-4 text-sm resize-none"
2447
+ className="w-full h-64 theme-input p-4 text-sm resize-none"
2260
2448
  spellCheck={false}
2261
2449
  />
2262
2450
  <p className="mt-2 font-mono text-[10px] text-gray-600">
@@ -2268,7 +2456,7 @@ function AIGeneratorModal({ roadmap, setRoadmap, setHasChanges, onClose }) {
2268
2456
  <button
2269
2457
  onClick={analyzeWithAI}
2270
2458
  disabled={analyzing || !requirements.trim() || (!claudeStatus.available && !claudeStatus.checking)}
2271
- className="btn-terminal flex-1 py-3 disabled:opacity-50 flex items-center justify-center gap-2"
2459
+ className="theme-btn-primary flex-1 py-3 disabled:opacity-50 flex items-center justify-center gap-2"
2272
2460
  >
2273
2461
  <Sparkles className="w-4 h-4" />
2274
2462
  GENERAR CON IA
@@ -2350,7 +2538,7 @@ function AIGeneratorModal({ roadmap, setRoadmap, setHasChanges, onClose }) {
2350
2538
  <div className="flex gap-3">
2351
2539
  <button
2352
2540
  onClick={mergeResults}
2353
- className="btn-terminal flex-1 py-3 flex items-center justify-center gap-2"
2541
+ className="theme-btn-primary flex-1 py-3 flex items-center justify-center gap-2"
2354
2542
  >
2355
2543
  <Plus className="w-4 h-4" />
2356
2544
  AÑADIR AL ROADMAP
@@ -2533,13 +2721,13 @@ function FeaturesTab({
2533
2721
  placeholder={t ? t('common.search') : "search tasks..."}
2534
2722
  value={searchTerm}
2535
2723
  onChange={(e) => setSearchTerm(e.target.value)}
2536
- className="input-terminal w-full pl-10 pr-4 py-2.5 text-sm"
2724
+ className="theme-input w-full pl-10 pr-4 py-2.5 text-sm"
2537
2725
  />
2538
2726
  </div>
2539
2727
  <select
2540
2728
  value={statusFilter}
2541
2729
  onChange={(e) => setStatusFilter(e.target.value)}
2542
- className="input-terminal px-4 py-2.5 text-sm cursor-pointer"
2730
+ className="theme-input px-4 py-2.5 text-sm cursor-pointer"
2543
2731
  >
2544
2732
  <option value="all">{language === 'es' ? 'TODOS' : 'ALL STATUS'}</option>
2545
2733
  <option value="pending">{language === 'es' ? 'PENDIENTE' : 'PENDING'}</option>
@@ -2568,17 +2756,17 @@ function FeaturesTab({
2568
2756
  {/* Advanced Filters Toggle */}
2569
2757
  <button
2570
2758
  onClick={() => setShowFilters(!showFilters)}
2571
- className={`btn-terminal flex items-center gap-2 ${showFilters ? 'border-cyber/50 text-cyber' : ''}`}
2759
+ className={`theme-btn-primary flex items-center gap-2 ${showFilters ? 'border-cyber/50 text-cyber' : ''}`}
2572
2760
  >
2573
2761
  <Filter className="w-4 h-4" />
2574
2762
  {language === 'es' ? 'FILTROS' : 'FILTERS'}
2575
2763
  </button>
2576
2764
 
2577
- <button onClick={() => setShowAddFeature(true)} className="btn-terminal flex items-center gap-2">
2765
+ <button onClick={() => setShowAddFeature(true)} className="theme-btn-primary flex items-center gap-2">
2578
2766
  <Plus className="w-4 h-4" />
2579
2767
  {language === 'es' ? 'NUEVA FEATURE' : 'NEW FEATURE'}
2580
2768
  </button>
2581
- <button onClick={() => setShowAIGenerator(true)} className="btn-terminal flex items-center gap-2 bg-gradient-to-r from-cyber/20 to-matrix/20 border-cyber/50 hover:border-cyber">
2769
+ <button onClick={() => setShowAIGenerator(true)} className="theme-btn-primary flex items-center gap-2 bg-gradient-to-r from-cyber/20 to-matrix/20 border-cyber/50 hover:border-cyber">
2582
2770
  <Sparkles className="w-4 h-4 text-cyber" />
2583
2771
  AI
2584
2772
  </button>
@@ -2592,7 +2780,7 @@ function FeaturesTab({
2592
2780
  <select
2593
2781
  value={priorityFilter}
2594
2782
  onChange={(e) => setPriorityFilter(e.target.value)}
2595
- className="input-terminal px-3 py-1.5 text-xs cursor-pointer"
2783
+ className="theme-input px-3 py-1.5 text-xs cursor-pointer"
2596
2784
  >
2597
2785
  <option value="all">{language === 'es' ? 'TODAS' : 'ALL'}</option>
2598
2786
  <option value="high">{language === 'es' ? 'ALTA' : 'HIGH'}</option>
@@ -2605,7 +2793,7 @@ function FeaturesTab({
2605
2793
  <select
2606
2794
  value={assigneeFilter}
2607
2795
  onChange={(e) => setAssigneeFilter(e.target.value)}
2608
- className="input-terminal px-3 py-1.5 text-xs cursor-pointer"
2796
+ className="theme-input px-3 py-1.5 text-xs cursor-pointer"
2609
2797
  >
2610
2798
  <option value="all">{language === 'es' ? 'TODOS' : 'ALL'}</option>
2611
2799
  <option value="">{language === 'es' ? 'SIN ASIGNAR' : 'UNASSIGNED'}</option>
@@ -2654,7 +2842,7 @@ function FeaturesTab({
2654
2842
  )}
2655
2843
 
2656
2844
  {features.length === 0 && viewMode === 'list' && (
2657
- <div className="terminal-card p-12 text-center">
2845
+ <div className="theme-card p-12 text-center">
2658
2846
  <Search className="w-10 h-10 mx-auto mb-4 text-gray-700" />
2659
2847
  <p className="font-mono text-gray-600 text-sm">{language === 'es' ? 'NO HAY TAREAS' : 'NO TASKS FOUND'}</p>
2660
2848
  </div>
@@ -2684,7 +2872,7 @@ function FeatureCard({ feature, onUpdateTaskStatus, onAddTask, showAddTask, setS
2684
2872
  {/* Progress Ring */}
2685
2873
  <div className="relative w-14 h-14 flex-shrink-0">
2686
2874
  <svg className="w-full h-full -rotate-90" viewBox="0 0 36 36">
2687
- <circle cx="18" cy="18" r="15" fill="none" stroke="#1a1a1a" strokeWidth="3" />
2875
+ <circle cx="18" cy="18" r="15" fill="none" stroke="var(--bg-secondary)" strokeWidth="3" />
2688
2876
  <circle
2689
2877
  cx="18" cy="18" r="15" fill="none"
2690
2878
  stroke="url(#progressGradient)"
@@ -2695,8 +2883,8 @@ function FeatureCard({ feature, onUpdateTaskStatus, onAddTask, showAddTask, setS
2695
2883
  />
2696
2884
  <defs>
2697
2885
  <linearGradient id="progressGradient" x1="0%" y1="0%" x2="100%" y2="0%">
2698
- <stop offset="0%" stopColor="#00ff88" />
2699
- <stop offset="100%" stopColor="#00d4ff" />
2886
+ <stop offset="0%" stopColor="var(--accent-primary)" />
2887
+ <stop offset="100%" stopColor="var(--accent-tertiary)" />
2700
2888
  </linearGradient>
2701
2889
  </defs>
2702
2890
  </svg>
@@ -2726,8 +2914,8 @@ function FeatureCard({ feature, onUpdateTaskStatus, onAddTask, showAddTask, setS
2726
2914
  <span>{feature.tasks.filter(t => t.status === 'completed').length} / {feature.tasks.length} TASKS</span>
2727
2915
  <span>{feature.progress}%</span>
2728
2916
  </div>
2729
- <div className="progress-brutal">
2730
- <div className="progress-brutal-fill" style={{ width: `${feature.progress}%` }} />
2917
+ <div className="theme-progress">
2918
+ <div className="theme-progress-fill" style={{ width: `${feature.progress}%` }} />
2731
2919
  </div>
2732
2920
  </div>
2733
2921
 
@@ -2764,8 +2952,8 @@ function TaskList({ tasks = [], featureId = '', onUpdateStatus, team = [], onAss
2764
2952
  };
2765
2953
 
2766
2954
  const statusConfig = {
2767
- completed: { led: 'led-green', label: 'DONE', color: 'text-matrix' },
2768
- in_progress: { led: 'led-amber', label: 'ACTIVE', color: 'text-signal' },
2955
+ completed: { led: 'theme-led theme-led-success', label: 'DONE', color: 'text-matrix' },
2956
+ in_progress: { led: 'theme-led theme-led-warning', label: 'ACTIVE', color: 'text-signal' },
2769
2957
  pending: { led: 'led-gray', label: 'QUEUE', color: 'text-gray-500' }
2770
2958
  };
2771
2959
 
@@ -2970,7 +3158,7 @@ function TaskList({ tasks = [], featureId = '', onUpdateStatus, team = [], onAss
2970
3158
  const member = team.find(m => m.id === e.target.value);
2971
3159
  onAssignTask?.(featureId, task.id, e.target.value, member?.name || '');
2972
3160
  }}
2973
- className="input-terminal px-3 py-1.5 text-[11px]"
3161
+ className="theme-input px-3 py-1.5 text-[11px]"
2974
3162
  >
2975
3163
  <option value="">Sin asignar</option>
2976
3164
  {team.map((member) => (
@@ -3063,27 +3251,27 @@ function MetricsTab({ roadmap, language }) {
3063
3251
  <div className="space-y-6 animate-fade-in">
3064
3252
  {/* Summary Cards */}
3065
3253
  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
3066
- <div className="terminal-card p-5">
3254
+ <div className="theme-card p-5">
3067
3255
  <div className="font-mono text-[10px] text-gray-500 mb-2">{language === 'es' ? 'TOTAL TAREAS' : 'TOTAL TASKS'}</div>
3068
3256
  <div className="font-display text-3xl text-white">{stats.total}</div>
3069
3257
  </div>
3070
- <div className="terminal-card p-5 border-matrix/20">
3258
+ <div className="theme-card p-5 border-matrix/20">
3071
3259
  <div className="font-mono text-[10px] text-gray-500 mb-2">{language === 'es' ? 'COMPLETADAS' : 'COMPLETED'}</div>
3072
3260
  <div className="font-display text-3xl text-matrix">{stats.completed}</div>
3073
3261
  <div className="font-mono text-[10px] text-matrix/60 mt-1">{completionRate}%</div>
3074
3262
  </div>
3075
- <div className="terminal-card p-5 border-signal/20">
3263
+ <div className="theme-card p-5 border-signal/20">
3076
3264
  <div className="font-mono text-[10px] text-gray-500 mb-2">{language === 'es' ? 'EN PROGRESO' : 'IN PROGRESS'}</div>
3077
3265
  <div className="font-display text-3xl text-signal">{stats.inProgress}</div>
3078
3266
  </div>
3079
- <div className="terminal-card p-5">
3267
+ <div className="theme-card p-5">
3080
3268
  <div className="font-mono text-[10px] text-gray-500 mb-2">{language === 'es' ? 'PENDIENTES' : 'PENDING'}</div>
3081
3269
  <div className="font-display text-3xl text-gray-500">{stats.pending}</div>
3082
3270
  </div>
3083
3271
  </div>
3084
3272
 
3085
3273
  {/* Progress Overview */}
3086
- <div className="terminal-card p-5">
3274
+ <div className="theme-card p-5">
3087
3275
  <h3 className="font-mono text-sm text-white mb-4">{language === 'es' ? 'PROGRESO GENERAL' : 'OVERALL PROGRESS'}</h3>
3088
3276
  <div className="relative h-8 bg-void-100 border border-white/5 overflow-hidden">
3089
3277
  <div
@@ -3104,7 +3292,7 @@ function MetricsTab({ roadmap, language }) {
3104
3292
  </div>
3105
3293
 
3106
3294
  {/* By Priority */}
3107
- <div className="terminal-card p-5">
3295
+ <div className="theme-card p-5">
3108
3296
  <h3 className="font-mono text-sm text-white mb-4">{language === 'es' ? 'POR PRIORIDAD' : 'BY PRIORITY'}</h3>
3109
3297
  <div className="grid grid-cols-3 gap-4">
3110
3298
  <div className="p-4 bg-alert/5 border border-alert/20">
@@ -3132,7 +3320,7 @@ function MetricsTab({ roadmap, language }) {
3132
3320
  </div>
3133
3321
 
3134
3322
  {/* By Feature */}
3135
- <div className="terminal-card p-5">
3323
+ <div className="theme-card p-5">
3136
3324
  <h3 className="font-mono text-sm text-white mb-4">{language === 'es' ? 'POR FEATURE' : 'BY FEATURE'}</h3>
3137
3325
  <div className="space-y-3">
3138
3326
  {stats.byFeature.map((feature, idx) => (
@@ -3156,7 +3344,7 @@ function MetricsTab({ roadmap, language }) {
3156
3344
  </div>
3157
3345
 
3158
3346
  {/* Export Options */}
3159
- <div className="terminal-card p-5">
3347
+ <div className="theme-card p-5">
3160
3348
  <h3 className="font-mono text-sm text-white mb-4">{language === 'es' ? 'EXPORTAR DATOS' : 'EXPORT DATA'}</h3>
3161
3349
  <div className="flex gap-3">
3162
3350
  <button
@@ -3176,7 +3364,7 @@ function MetricsTab({ roadmap, language }) {
3176
3364
  a.download = 'roadmap-export.csv';
3177
3365
  a.click();
3178
3366
  }}
3179
- className="btn-terminal flex items-center gap-2"
3367
+ className="theme-btn-primary flex items-center gap-2"
3180
3368
  >
3181
3369
  <FileDown className="w-4 h-4" />
3182
3370
  CSV
@@ -3190,7 +3378,7 @@ function MetricsTab({ roadmap, language }) {
3190
3378
  a.download = 'roadmap-backup.json';
3191
3379
  a.click();
3192
3380
  }}
3193
- className="btn-terminal flex items-center gap-2"
3381
+ className="theme-btn-primary flex items-center gap-2"
3194
3382
  >
3195
3383
  <FileDown className="w-4 h-4" />
3196
3384
  JSON
@@ -3216,23 +3404,23 @@ function ResourcesTab({ resources }) {
3216
3404
  <div className="space-y-6 animate-fade-in">
3217
3405
  {/* Summary */}
3218
3406
  <div className="grid grid-cols-3 gap-4">
3219
- <div className="terminal-card p-5">
3407
+ <div className="theme-card p-5">
3220
3408
  <div className="flex items-center gap-3 mb-3">
3221
- <div className="led led-green" />
3409
+ <div className="led theme-led theme-led-success" />
3222
3410
  <span className="font-mono text-[10px] text-gray-500 tracking-wider">UI COMPONENTS</span>
3223
3411
  </div>
3224
3412
  <div className="metric-display text-3xl text-matrix">{ui_components.length}</div>
3225
3413
  </div>
3226
- <div className="terminal-card p-5">
3414
+ <div className="theme-card p-5">
3227
3415
  <div className="flex items-center gap-3 mb-3">
3228
- <div className="led led-amber" />
3416
+ <div className="led theme-led theme-led-warning" />
3229
3417
  <span className="font-mono text-[10px] text-gray-500 tracking-wider">UTILITIES</span>
3230
3418
  </div>
3231
3419
  <div className="metric-display text-3xl text-signal">{utilities.length}</div>
3232
3420
  </div>
3233
- <div className="terminal-card p-5">
3421
+ <div className="theme-card p-5">
3234
3422
  <div className="flex items-center gap-3 mb-3">
3235
- <div className="led led-green" />
3423
+ <div className="led theme-led theme-led-success" />
3236
3424
  <span className="font-mono text-[10px] text-gray-500 tracking-wider">DB TABLES</span>
3237
3425
  </div>
3238
3426
  <div className="metric-display text-3xl text-cyber">{database_tables.length}</div>
@@ -3241,7 +3429,7 @@ function ResourcesTab({ resources }) {
3241
3429
 
3242
3430
  {/* UI Components */}
3243
3431
  {ui_components.length > 0 && (
3244
- <div className="terminal-card p-5">
3432
+ <div className="theme-card p-5">
3245
3433
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4"># UI_COMPONENTS</h3>
3246
3434
  <div className="space-y-3">
3247
3435
  {ui_components.map((comp, idx) => (
@@ -3265,7 +3453,7 @@ function ResourcesTab({ resources }) {
3265
3453
 
3266
3454
  {/* Utilities */}
3267
3455
  {utilities.length > 0 && (
3268
- <div className="terminal-card p-5">
3456
+ <div className="theme-card p-5">
3269
3457
  <h3 className="font-mono text-sm text-signal tracking-wider mb-4"># UTILITIES</h3>
3270
3458
  <div className="space-y-3">
3271
3459
  {utilities.map((util, idx) => (
@@ -3302,7 +3490,7 @@ function ResourcesTab({ resources }) {
3302
3490
 
3303
3491
  {/* Database Tables */}
3304
3492
  {database_tables.length > 0 && (
3305
- <div className="terminal-card p-5">
3493
+ <div className="theme-card p-5">
3306
3494
  <h3 className="font-mono text-sm text-cyber tracking-wider mb-4"># DATABASE_TABLES</h3>
3307
3495
  <div className="space-y-3">
3308
3496
  {database_tables.map((table, idx) => (
@@ -3324,7 +3512,7 @@ function ResourcesTab({ resources }) {
3324
3512
  }
3325
3513
 
3326
3514
  // ============ DEBT TAB ============
3327
- function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3515
+ function DebtTab({ roadmap, setRoadmap, setHasChanges, t }) {
3328
3516
  const [expandedDebt, setExpandedDebt] = useState(null);
3329
3517
  const [filterSeverity, setFilterSeverity] = useState('all');
3330
3518
  const [filterStatus, setFilterStatus] = useState('all');
@@ -3368,9 +3556,9 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3368
3556
  });
3369
3557
 
3370
3558
  const statusConfig = {
3371
- pending: { led: 'led-gray', label: 'PENDING', color: 'text-gray-500' },
3372
- in_progress: { led: 'led-amber', label: 'IN PROGRESS', color: 'text-signal' },
3373
- resolved: { led: 'led-green', label: 'RESOLVED', color: 'text-matrix' }
3559
+ pending: { led: 'led-gray', label: t('debt.pending'), color: 'text-gray-500' },
3560
+ in_progress: { led: 'theme-led theme-led-warning', label: t('debt.inProgress'), color: 'text-signal' },
3561
+ resolved: { led: 'theme-led theme-led-success', label: t('debt.resolved'), color: 'text-matrix' }
3374
3562
  };
3375
3563
 
3376
3564
  // Update debt status
@@ -3454,70 +3642,70 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3454
3642
 
3455
3643
  return (
3456
3644
  <div className="space-y-6 animate-fade-in">
3457
- {/* Summary */}
3645
+ {/* Resumen */}
3458
3646
  <div className="grid grid-cols-3 gap-4">
3459
3647
  <button
3460
3648
  onClick={() => setFilterSeverity(filterSeverity === 'high' ? 'all' : 'high')}
3461
- className={`terminal-card p-5 transition-all ${filterSeverity === 'high' ? 'border-alert glow-alert' : 'border-alert/30 hover:border-alert/50'}`}
3649
+ className={`theme-card p-5 transition-all ${filterSeverity === 'high' ? 'border-alert glow-alert' : 'border-alert/30 hover:border-alert/50'}`}
3462
3650
  >
3463
3651
  <div className="flex items-center gap-3 mb-3">
3464
- <div className="led led-red" />
3465
- <span className="font-mono text-[10px] text-gray-500 tracking-wider">HIGH</span>
3652
+ <div className="led theme-led theme-led-danger" />
3653
+ <span className="font-mono text-[10px] text-gray-500 tracking-wider">{t('debt.high')}</span>
3466
3654
  </div>
3467
3655
  <div className="metric-display text-3xl text-alert">{bySeverity.high.length}</div>
3468
3656
  </button>
3469
3657
  <button
3470
3658
  onClick={() => setFilterSeverity(filterSeverity === 'medium' ? 'all' : 'medium')}
3471
- className={`terminal-card p-5 transition-all ${filterSeverity === 'medium' ? 'border-signal glow-signal' : 'border-signal/30 hover:border-signal/50'}`}
3659
+ className={`theme-card p-5 transition-all ${filterSeverity === 'medium' ? 'border-signal glow-signal' : 'border-signal/30 hover:border-signal/50'}`}
3472
3660
  >
3473
3661
  <div className="flex items-center gap-3 mb-3">
3474
- <div className="led led-amber" />
3475
- <span className="font-mono text-[10px] text-gray-500 tracking-wider">MEDIUM</span>
3662
+ <div className="led theme-led theme-led-warning" />
3663
+ <span className="font-mono text-[10px] text-gray-500 tracking-wider">{t('debt.medium')}</span>
3476
3664
  </div>
3477
3665
  <div className="metric-display text-3xl text-signal">{bySeverity.medium.length}</div>
3478
3666
  </button>
3479
3667
  <button
3480
3668
  onClick={() => setFilterSeverity(filterSeverity === 'low' ? 'all' : 'low')}
3481
- className={`terminal-card p-5 transition-all ${filterSeverity === 'low' ? 'border-cyber glow-cyber' : 'border-cyber/30 hover:border-cyber/50'}`}
3669
+ className={`theme-card p-5 transition-all ${filterSeverity === 'low' ? 'border-cyber glow-cyber' : 'border-cyber/30 hover:border-cyber/50'}`}
3482
3670
  >
3483
3671
  <div className="flex items-center gap-3 mb-3">
3484
- <div className="led led-green" />
3485
- <span className="font-mono text-[10px] text-gray-500 tracking-wider">LOW</span>
3672
+ <div className="led theme-led theme-led-success" />
3673
+ <span className="font-mono text-[10px] text-gray-500 tracking-wider">{t('debt.low')}</span>
3486
3674
  </div>
3487
3675
  <div className="metric-display text-3xl text-cyber">{bySeverity.low.length}</div>
3488
3676
  </button>
3489
3677
  </div>
3490
3678
 
3491
- {/* Filters & Add Button */}
3679
+ {/* Filtros y Botón Añadir */}
3492
3680
  <div className="flex items-center gap-3 flex-wrap">
3493
- <span className="font-mono text-[10px] text-gray-600">FILTER:</span>
3681
+ <span className="font-mono text-[10px] text-gray-600">{t('debt.filter')}:</span>
3494
3682
  <select
3495
3683
  value={filterStatus}
3496
3684
  onChange={(e) => setFilterStatus(e.target.value)}
3497
- className="input-terminal px-3 py-2 text-xs"
3685
+ className="theme-input px-3 py-2 text-xs"
3498
3686
  >
3499
- <option value="all">ALL STATUS</option>
3500
- <option value="pending">PENDING</option>
3501
- <option value="in_progress">IN PROGRESS</option>
3502
- <option value="resolved">RESOLVED</option>
3687
+ <option value="all">{t('debt.all')}</option>
3688
+ <option value="pending">{t('debt.pending')}</option>
3689
+ <option value="in_progress">{t('debt.inProgress')}</option>
3690
+ <option value="resolved">{t('debt.resolved')}</option>
3503
3691
  </select>
3504
3692
  {(filterSeverity !== 'all' || filterStatus !== 'all') && (
3505
3693
  <button
3506
3694
  onClick={() => { setFilterSeverity('all'); setFilterStatus('all'); }}
3507
3695
  className="font-mono text-[10px] text-gray-500 hover:text-white transition-all"
3508
3696
  >
3509
- CLEAR
3697
+ {t('debt.clear')}
3510
3698
  </button>
3511
3699
  )}
3512
3700
  <span className="font-mono text-[10px] text-gray-600">
3513
- {filteredDebts.length} / {allDebts.length} items
3701
+ {filteredDebts.length} / {allDebts.length} {t('debt.items')}
3514
3702
  </span>
3515
3703
  <button
3516
3704
  onClick={() => setShowAddDebt(true)}
3517
- className="ml-auto btn-terminal flex items-center gap-2"
3705
+ className="ml-auto theme-btn-primary flex items-center gap-2"
3518
3706
  >
3519
3707
  <Plus className="w-4 h-4" />
3520
- ADD DEBT
3708
+ {t('debt.addDebt')}
3521
3709
  </button>
3522
3710
  </div>
3523
3711
 
@@ -3533,8 +3721,8 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3533
3721
 
3534
3722
  {/* Debt Items */}
3535
3723
  {filteredDebts.length > 0 ? (
3536
- <div className="terminal-card p-5">
3537
- <h3 className="font-mono text-sm text-signal tracking-wider mb-4"># TECHNICAL_DEBT</h3>
3724
+ <div className="theme-card p-5">
3725
+ <h3 className="font-mono text-sm text-signal tracking-wider mb-4"># {t('debt.title')}</h3>
3538
3726
  <div className="space-y-2">
3539
3727
  {filteredDebts.map((debt) => {
3540
3728
  const isExpanded = expandedDebt === debt.id;
@@ -3583,9 +3771,9 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3583
3771
  {/* Expanded Content */}
3584
3772
  {isExpanded && !isEditing && (
3585
3773
  <div className="px-4 pb-4 pt-2 border-t border-white/5 space-y-4 animate-fade-in">
3586
- {/* Status Controls */}
3774
+ {/* Controles de Estado */}
3587
3775
  <div className="flex items-center gap-2 p-3 bg-black/30 border border-white/5">
3588
- <span className="font-mono text-[10px] text-gray-600">STATUS:</span>
3776
+ <span className="font-mono text-[10px] text-gray-600">{t('debt.status')}:</span>
3589
3777
  <div className="flex gap-1">
3590
3778
  {['pending', 'in_progress', 'resolved'].map((s) => {
3591
3779
  const cfg = statusConfig[s];
@@ -3622,36 +3810,36 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3622
3810
  </div>
3623
3811
  </div>
3624
3812
 
3625
- {/* Full Description */}
3813
+ {/* Descripción Completa */}
3626
3814
  <div>
3627
- <h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2"># DESCRIPTION</h5>
3815
+ <h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2"># {t('debt.description')}</h5>
3628
3816
  <p className="font-mono text-xs text-gray-400">{debt.description}</p>
3629
3817
  </div>
3630
3818
 
3631
- {/* Impact */}
3819
+ {/* Impacto */}
3632
3820
  {debt.impact && (
3633
3821
  <div className="p-3 border border-alert/20 bg-alert/5">
3634
3822
  <h5 className="font-mono text-[10px] text-alert tracking-wider mb-2 flex items-center gap-2">
3635
- <AlertTriangle className="w-3 h-3" /> IMPACT
3823
+ <AlertTriangle className="w-3 h-3" /> {t('debt.impact')}
3636
3824
  </h5>
3637
3825
  <p className="font-mono text-xs text-gray-400">{debt.impact}</p>
3638
3826
  </div>
3639
3827
  )}
3640
3828
 
3641
- {/* Solution */}
3829
+ {/* Solución */}
3642
3830
  {debt.solution && (
3643
3831
  <div className="p-3 border border-matrix/20 bg-matrix/5">
3644
3832
  <h5 className="font-mono text-[10px] text-matrix tracking-wider mb-2 flex items-center gap-2">
3645
- <Wrench className="w-3 h-3" /> PROPOSED SOLUTION
3833
+ <Wrench className="w-3 h-3" /> {t('debt.solution')}
3646
3834
  </h5>
3647
3835
  <p className="font-mono text-xs text-gray-400">{debt.solution}</p>
3648
3836
  </div>
3649
3837
  )}
3650
3838
 
3651
- {/* Affected Files */}
3839
+ {/* Archivos Afectados */}
3652
3840
  {debt.affected_files && debt.affected_files.length > 0 && (
3653
3841
  <div>
3654
- <h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2"># AFFECTED FILES</h5>
3842
+ <h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2"># {t('debt.affectedFiles')}</h5>
3655
3843
  <div className="flex flex-wrap gap-2">
3656
3844
  {debt.affected_files.map((file, idx) => (
3657
3845
  <code key={idx} className="font-mono text-[11px] px-2 py-1 bg-black/50 border border-white/10 text-cyber">
@@ -3665,19 +3853,19 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3665
3853
  {/* Metadata Grid */}
3666
3854
  <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
3667
3855
  <div className="bg-black/30 p-3 border border-white/5">
3668
- <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">FEATURE</div>
3856
+ <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.feature')}</div>
3669
3857
  <div className="font-mono text-xs text-white truncate">{debt.featureName}</div>
3670
3858
  </div>
3671
3859
  <div className="bg-black/30 p-3 border border-white/5">
3672
- <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">TASK</div>
3860
+ <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.task')}</div>
3673
3861
  <div className="font-mono text-xs text-white truncate">{debt.taskName}</div>
3674
3862
  </div>
3675
3863
  <div className="bg-black/30 p-3 border border-white/5">
3676
- <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">EFFORT</div>
3677
- <div className="font-mono text-xs text-signal">{debt.estimated_effort || 'Not estimated'}</div>
3864
+ <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.effort')}</div>
3865
+ <div className="font-mono text-xs text-signal">{debt.estimated_effort || t('debt.notEstimated')}</div>
3678
3866
  </div>
3679
3867
  <div className="bg-black/30 p-3 border border-white/5">
3680
- <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">PRIORITY</div>
3868
+ <div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.priority')}</div>
3681
3869
  <div className={`font-mono text-xs ${
3682
3870
  debt.priority === 'critical' ? 'text-alert' :
3683
3871
  debt.priority === 'high' ? 'text-signal' :
@@ -3689,16 +3877,16 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3689
3877
  {/* Additional Info */}
3690
3878
  <div className="flex items-center gap-4 pt-3 border-t border-white/5 font-mono text-[10px] text-gray-600 flex-wrap">
3691
3879
  {debt.created_at && (
3692
- <span>Created: {new Date(debt.created_at).toLocaleDateString()}</span>
3880
+ <span>{t('debt.created')}: {new Date(debt.created_at).toLocaleDateString()}</span>
3693
3881
  )}
3694
3882
  {debt.resolved_at && (
3695
- <span className="text-matrix">Resolved: {new Date(debt.resolved_at).toLocaleDateString()}</span>
3883
+ <span className="text-matrix">{t('debt.resolvedAt')}: {new Date(debt.resolved_at).toLocaleDateString()}</span>
3696
3884
  )}
3697
3885
  {debt.assigned_to && (
3698
- <span className="text-signal">Assigned: @{debt.assigned_to}</span>
3886
+ <span className="text-signal">{t('debt.assigned')}: @{debt.assigned_to}</span>
3699
3887
  )}
3700
3888
  {debt.due_date && (
3701
- <span className="text-alert">Due: {new Date(debt.due_date).toLocaleDateString()}</span>
3889
+ <span className="text-alert">{t('debt.due')}: {new Date(debt.due_date).toLocaleDateString()}</span>
3702
3890
  )}
3703
3891
  </div>
3704
3892
 
@@ -3734,28 +3922,28 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
3734
3922
  </div>
3735
3923
  </div>
3736
3924
  ) : (
3737
- <div className="terminal-card p-12 text-center">
3925
+ <div className="theme-card p-12 text-center">
3738
3926
  <CheckCircle2 className="w-10 h-10 mx-auto mb-4 text-matrix" />
3739
3927
  <p className="font-mono text-sm text-gray-600">
3740
- {allDebts.length === 0 ? 'NO TECHNICAL DEBT REGISTERED' : 'NO ITEMS MATCH FILTERS'}
3928
+ {allDebts.length === 0 ? t('debt.noDebt') : t('debt.noMatch')}
3741
3929
  </p>
3742
3930
  {allDebts.length === 0 && (
3743
3931
  <button
3744
3932
  onClick={() => setShowAddDebt(true)}
3745
- className="btn-terminal mt-4 inline-flex items-center gap-2"
3933
+ className="theme-btn-primary mt-4 inline-flex items-center gap-2"
3746
3934
  >
3747
3935
  <Plus className="w-4 h-4" />
3748
- ADD FIRST DEBT
3936
+ {t('debt.addFirstDebt')}
3749
3937
  </button>
3750
3938
  )}
3751
3939
  </div>
3752
3940
  )}
3753
3941
 
3754
3942
  {/* Debt Schema Info */}
3755
- <div className="terminal-card p-4">
3943
+ <div className="theme-card p-4">
3756
3944
  <details>
3757
3945
  <summary className="font-mono text-[10px] text-gray-600 cursor-pointer hover:text-white">
3758
- JSON SCHEMA FOR TECHNICAL DEBT
3946
+ {t('debt.jsonSchema')}
3759
3947
  </summary>
3760
3948
  <pre className="mt-4 p-4 bg-void-100 border border-white/5 font-mono text-[10px] text-gray-500 overflow-x-auto">
3761
3949
  {`{
@@ -3826,7 +4014,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3826
4014
  };
3827
4015
 
3828
4016
  return (
3829
- <form onSubmit={handleSubmit} className="terminal-card p-5 space-y-4">
4017
+ <form onSubmit={handleSubmit} className="theme-card p-5 space-y-4">
3830
4018
  <h3 className="font-mono text-sm text-signal tracking-wider">
3831
4019
  {isEdit ? '# EDIT DEBT' : '# NEW TECHNICAL DEBT'}
3832
4020
  </h3>
@@ -3838,7 +4026,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3838
4026
  <select
3839
4027
  value={featureId}
3840
4028
  onChange={(e) => { setFeatureId(e.target.value); setTaskId(''); }}
3841
- className="input-terminal w-full px-3 py-2 text-sm"
4029
+ className="theme-input w-full px-3 py-2 text-sm"
3842
4030
  required
3843
4031
  >
3844
4032
  <option value="">Select feature...</option>
@@ -3852,7 +4040,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3852
4040
  <select
3853
4041
  value={taskId}
3854
4042
  onChange={(e) => setTaskId(e.target.value)}
3855
- className="input-terminal w-full px-3 py-2 text-sm"
4043
+ className="theme-input w-full px-3 py-2 text-sm"
3856
4044
  required
3857
4045
  disabled={!featureId}
3858
4046
  >
@@ -3872,7 +4060,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3872
4060
  onChange={(e) => setDescription(e.target.value)}
3873
4061
  placeholder="Describe the technical debt..."
3874
4062
  rows={2}
3875
- className="input-terminal w-full px-3 py-2 text-sm resize-none"
4063
+ className="theme-input w-full px-3 py-2 text-sm resize-none"
3876
4064
  required
3877
4065
  />
3878
4066
  </div>
@@ -3880,7 +4068,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3880
4068
  <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
3881
4069
  <div>
3882
4070
  <label className="font-mono text-[10px] text-gray-500 tracking-wider mb-2 block">SEVERITY</label>
3883
- <select value={severity} onChange={(e) => setSeverity(e.target.value)} className="input-terminal w-full px-3 py-2 text-sm">
4071
+ <select value={severity} onChange={(e) => setSeverity(e.target.value)} className="theme-input w-full px-3 py-2 text-sm">
3884
4072
  <option value="high">HIGH</option>
3885
4073
  <option value="medium">MEDIUM</option>
3886
4074
  <option value="low">LOW</option>
@@ -3888,7 +4076,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3888
4076
  </div>
3889
4077
  <div>
3890
4078
  <label className="font-mono text-[10px] text-gray-500 tracking-wider mb-2 block">PRIORITY</label>
3891
- <select value={priority} onChange={(e) => setPriority(e.target.value)} className="input-terminal w-full px-3 py-2 text-sm">
4079
+ <select value={priority} onChange={(e) => setPriority(e.target.value)} className="theme-input w-full px-3 py-2 text-sm">
3892
4080
  <option value="critical">CRITICAL</option>
3893
4081
  <option value="high">HIGH</option>
3894
4082
  <option value="medium">MEDIUM</option>
@@ -3902,12 +4090,12 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3902
4090
  value={estimatedEffort}
3903
4091
  onChange={(e) => setEstimatedEffort(e.target.value)}
3904
4092
  placeholder="e.g. 2h, 1d"
3905
- className="input-terminal w-full px-3 py-2 text-sm"
4093
+ className="theme-input w-full px-3 py-2 text-sm"
3906
4094
  />
3907
4095
  </div>
3908
4096
  <div>
3909
4097
  <label className="font-mono text-[10px] text-gray-500 tracking-wider mb-2 block">ASSIGNED</label>
3910
- <select value={assignedTo} onChange={(e) => setAssignedTo(e.target.value)} className="input-terminal w-full px-3 py-2 text-sm">
4098
+ <select value={assignedTo} onChange={(e) => setAssignedTo(e.target.value)} className="theme-input w-full px-3 py-2 text-sm">
3911
4099
  <option value="">Unassigned</option>
3912
4100
  {team.map(m => (
3913
4101
  <option key={m.id} value={m.name}>{m.name}</option>
@@ -3923,7 +4111,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3923
4111
  onChange={(e) => setImpact(e.target.value)}
3924
4112
  placeholder="What happens if not fixed?"
3925
4113
  rows={2}
3926
- className="input-terminal w-full px-3 py-2 text-sm resize-none"
4114
+ className="theme-input w-full px-3 py-2 text-sm resize-none"
3927
4115
  />
3928
4116
  </div>
3929
4117
 
@@ -3934,7 +4122,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3934
4122
  onChange={(e) => setSolution(e.target.value)}
3935
4123
  placeholder="How to fix this?"
3936
4124
  rows={2}
3937
- className="input-terminal w-full px-3 py-2 text-sm resize-none"
4125
+ className="theme-input w-full px-3 py-2 text-sm resize-none"
3938
4126
  />
3939
4127
  </div>
3940
4128
 
@@ -3946,7 +4134,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3946
4134
  value={affectedFiles}
3947
4135
  onChange={(e) => setAffectedFiles(e.target.value)}
3948
4136
  placeholder="src/file1.js, src/file2.js"
3949
- className="input-terminal w-full px-3 py-2 text-sm"
4137
+ className="theme-input w-full px-3 py-2 text-sm"
3950
4138
  />
3951
4139
  </div>
3952
4140
  <div>
@@ -3956,7 +4144,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3956
4144
  value={tags}
3957
4145
  onChange={(e) => setTags(e.target.value)}
3958
4146
  placeholder="security, performance"
3959
- className="input-terminal w-full px-3 py-2 text-sm"
4147
+ className="theme-input w-full px-3 py-2 text-sm"
3960
4148
  />
3961
4149
  </div>
3962
4150
  </div>
@@ -3965,7 +4153,7 @@ function DebtForm({ features, team, initialData, onSave, onCancel, isEdit }) {
3965
4153
  <button type="button" onClick={onCancel} className="px-4 py-2 border border-white/10 text-gray-500 font-mono text-xs hover:text-white transition-all">
3966
4154
  CANCEL
3967
4155
  </button>
3968
- <button type="submit" className="btn-terminal flex-1 py-2">
4156
+ <button type="submit" className="theme-btn-primary flex-1 py-2">
3969
4157
  {isEdit ? 'UPDATE' : 'ADD DEBT'}
3970
4158
  </button>
3971
4159
  </div>
@@ -3980,7 +4168,7 @@ function InfoTab({ projectInfo }) {
3980
4168
  return (
3981
4169
  <div className="space-y-6 animate-fade-in">
3982
4170
  {/* Stack */}
3983
- <div className="terminal-card p-5">
4171
+ <div className="theme-card p-5">
3984
4172
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4"># STACK</h3>
3985
4173
  <div className="flex flex-wrap gap-2">
3986
4174
  {(projectInfo.stack || []).map((tech, idx) => (
@@ -3996,7 +4184,7 @@ function InfoTab({ projectInfo }) {
3996
4184
 
3997
4185
  {/* Architecture */}
3998
4186
  {projectInfo.architecture && (
3999
- <div className="terminal-card p-5">
4187
+ <div className="theme-card p-5">
4000
4188
  <h3 className="font-mono text-sm text-cyber tracking-wider mb-4"># ARCHITECTURE</h3>
4001
4189
  <p className="font-mono text-xs text-gray-400 leading-relaxed">{projectInfo.architecture}</p>
4002
4190
  </div>
@@ -4004,7 +4192,7 @@ function InfoTab({ projectInfo }) {
4004
4192
 
4005
4193
  {/* Conventions */}
4006
4194
  {Object.keys(conventions).length > 0 && (
4007
- <div className="terminal-card p-5">
4195
+ <div className="theme-card p-5">
4008
4196
  <h3 className="font-mono text-sm text-signal tracking-wider mb-4"># CONVENTIONS</h3>
4009
4197
  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
4010
4198
  {conventions.naming && (
@@ -4054,7 +4242,7 @@ function InfoTab({ projectInfo }) {
4054
4242
 
4055
4243
  {/* Purpose */}
4056
4244
  {projectInfo.purpose && (
4057
- <div className="terminal-card p-5">
4245
+ <div className="theme-card p-5">
4058
4246
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4"># PURPOSE</h3>
4059
4247
  <p className="font-mono text-xs text-gray-400 leading-relaxed">{projectInfo.purpose}</p>
4060
4248
  </div>
@@ -4071,6 +4259,267 @@ function InfoTab({ projectInfo }) {
4071
4259
  );
4072
4260
  }
4073
4261
 
4262
+ // ============ APPEARANCE SECTION ============
4263
+ function AppearanceSection({ language }) {
4264
+ const { theme: currentTheme, setTheme, colorMode, setColorMode, isDark } = useTheme();
4265
+ const [saving, setSaving] = useState(false);
4266
+ const [savingMode, setSavingMode] = useState(false);
4267
+ const toast = useToast();
4268
+
4269
+ const handleThemeChange = async (themeId) => {
4270
+ if (themeId === currentTheme) return;
4271
+ setSaving(true);
4272
+ try {
4273
+ await setTheme(themeId);
4274
+ toast.success(language === 'es' ? 'Tema actualizado' : 'Theme updated');
4275
+ } catch (err) {
4276
+ toast.error(language === 'es' ? 'Error al guardar el tema' : 'Error saving theme');
4277
+ }
4278
+ setSaving(false);
4279
+ };
4280
+
4281
+ const handleColorModeChange = async (mode) => {
4282
+ if (mode === colorMode) return;
4283
+ setSavingMode(true);
4284
+ try {
4285
+ await setColorMode(mode);
4286
+ toast.success(language === 'es' ? 'Modo de color actualizado' : 'Color mode updated');
4287
+ } catch (err) {
4288
+ toast.error(language === 'es' ? 'Error al guardar el modo' : 'Error saving mode');
4289
+ }
4290
+ setSavingMode(false);
4291
+ };
4292
+
4293
+ // Theme preview SVG components
4294
+ const GlassPreview = () => (
4295
+ <svg viewBox="0 0 120 80" className="w-full h-full">
4296
+ {/* Background */}
4297
+ <rect width="120" height="80" fill="#f1f5f9" />
4298
+ {/* Sidebar */}
4299
+ <rect x="0" y="0" width="30" height="80" fill="#ffffff" fillOpacity="0.7" />
4300
+ <rect x="4" y="8" width="22" height="4" rx="2" fill="#10b981" />
4301
+ <rect x="4" y="16" width="22" height="3" rx="1.5" fill="#e2e8f0" />
4302
+ <rect x="4" y="22" width="22" height="3" rx="1.5" fill="#e2e8f0" />
4303
+ <rect x="4" y="28" width="22" height="3" rx="1.5" fill="#e2e8f0" />
4304
+ {/* Cards */}
4305
+ <rect x="36" y="8" width="38" height="28" rx="4" fill="#ffffff" stroke="#e2e8f0" strokeWidth="1" />
4306
+ <rect x="40" y="12" width="20" height="3" rx="1.5" fill="#1e293b" />
4307
+ <rect x="40" y="18" width="30" height="2" rx="1" fill="#94a3b8" />
4308
+ <rect x="40" y="24" width="30" height="4" rx="2" fill="#e2e8f0" />
4309
+ <rect x="40" y="24" width="18" height="4" rx="2" fill="#10b981" />
4310
+ <rect x="80" y="8" width="34" height="28" rx="4" fill="#ffffff" stroke="#e2e8f0" strokeWidth="1" />
4311
+ <rect x="84" y="12" width="16" height="3" rx="1.5" fill="#1e293b" />
4312
+ <rect x="84" y="18" width="26" height="2" rx="1" fill="#94a3b8" />
4313
+ {/* Bottom cards */}
4314
+ <rect x="36" y="44" width="78" height="28" rx="4" fill="#ffffff" stroke="#e2e8f0" strokeWidth="1" />
4315
+ <rect x="40" y="48" width="24" height="3" rx="1.5" fill="#1e293b" />
4316
+ <rect x="40" y="54" width="70" height="2" rx="1" fill="#94a3b8" />
4317
+ <rect x="40" y="60" width="70" height="2" rx="1" fill="#94a3b8" />
4318
+ </svg>
4319
+ );
4320
+
4321
+ const MatrixPreview = () => (
4322
+ <svg viewBox="0 0 120 80" className="w-full h-full">
4323
+ {/* Background with grid */}
4324
+ <rect width="120" height="80" fill="#0a0a0a" />
4325
+ <defs>
4326
+ <pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse">
4327
+ <path d="M 10 0 L 0 0 0 10" fill="none" stroke="#00ff88" strokeWidth="0.2" strokeOpacity="0.1" />
4328
+ </pattern>
4329
+ </defs>
4330
+ <rect width="120" height="80" fill="url(#grid)" />
4331
+ {/* Sidebar */}
4332
+ <rect x="0" y="0" width="30" height="80" fill="#050505" />
4333
+ <line x1="30" y1="0" x2="30" y2="80" stroke="#00ff88" strokeWidth="0.5" strokeOpacity="0.3" />
4334
+ <rect x="0" y="8" width="2" height="6" fill="#00ff88" />
4335
+ <rect x="6" y="9" width="20" height="4" fill="#00ff88" fillOpacity="0.2" />
4336
+ <text x="8" y="12.5" fill="#00ff88" fontSize="3" fontFamily="monospace">&gt; MENU</text>
4337
+ <rect x="6" y="16" width="20" height="3" fill="#333" />
4338
+ <rect x="6" y="22" width="20" height="3" fill="#333" />
4339
+ <rect x="6" y="28" width="20" height="3" fill="#333" />
4340
+ {/* Cards */}
4341
+ <rect x="36" y="8" width="38" height="28" fill="#0d0d0d" stroke="#00ff88" strokeWidth="0.5" strokeOpacity="0.3" />
4342
+ <line x1="36" y1="8" x2="74" y2="8" stroke="#00ff88" strokeWidth="1" strokeOpacity="0.5" />
4343
+ <rect x="40" y="14" width="20" height="3" fill="#e0e0e0" />
4344
+ <rect x="40" y="20" width="30" height="2" fill="#555" />
4345
+ <rect x="40" y="26" width="30" height="4" fill="#1a1a1a" stroke="#333" strokeWidth="0.5" />
4346
+ <rect x="40" y="26" width="18" height="4" fill="#00ff88" />
4347
+ <rect x="80" y="8" width="34" height="28" fill="#0d0d0d" stroke="#00ff88" strokeWidth="0.5" strokeOpacity="0.3" />
4348
+ <line x1="80" y1="8" x2="114" y2="8" stroke="#00ff88" strokeWidth="1" strokeOpacity="0.5" />
4349
+ <rect x="84" y="14" width="16" height="3" fill="#e0e0e0" />
4350
+ <rect x="84" y="20" width="26" height="2" fill="#555" />
4351
+ {/* Bottom card */}
4352
+ <rect x="36" y="44" width="78" height="28" fill="#0d0d0d" stroke="#00ff88" strokeWidth="0.5" strokeOpacity="0.3" />
4353
+ <line x1="36" y1="44" x2="114" y2="44" stroke="#00ff88" strokeWidth="1" strokeOpacity="0.5" />
4354
+ <rect x="40" y="50" width="24" height="3" fill="#e0e0e0" />
4355
+ <rect x="40" y="56" width="70" height="2" fill="#555" />
4356
+ <rect x="40" y="62" width="70" height="2" fill="#555" />
4357
+ </svg>
4358
+ );
4359
+
4360
+ const themeOptions = [
4361
+ {
4362
+ id: 'glass',
4363
+ name: 'Glass',
4364
+ description: language === 'es' ? 'Interfaz moderna y limpia' : 'Modern and clean interface',
4365
+ preview: GlassPreview
4366
+ },
4367
+ {
4368
+ id: 'matrix',
4369
+ name: 'Matrix',
4370
+ description: language === 'es' ? 'Estética cyberpunk terminal' : 'Cyberpunk terminal aesthetic',
4371
+ preview: MatrixPreview
4372
+ }
4373
+ ];
4374
+
4375
+ return (
4376
+ <div className="theme-card p-6">
4377
+ <div className="flex items-center gap-3 mb-6">
4378
+ <div className="w-10 h-10 rounded-theme-md flex items-center justify-center" style={{ background: 'var(--accent-primary)', opacity: 0.15 }}>
4379
+ <Palette className="w-5 h-5" style={{ color: 'var(--accent-primary)' }} />
4380
+ </div>
4381
+ <div>
4382
+ <h3 className="font-heading text-lg" style={{ color: 'var(--text-primary)' }}>
4383
+ {language === 'es' ? 'Apariencia' : 'Appearance'}
4384
+ </h3>
4385
+ <p className="text-sm" style={{ color: 'var(--text-muted)' }}>
4386
+ {language === 'es' ? 'Personaliza el aspecto del dashboard' : 'Customize the dashboard appearance'}
4387
+ </p>
4388
+ </div>
4389
+ </div>
4390
+
4391
+ <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
4392
+ {themeOptions.map((themeOpt) => {
4393
+ const isSelected = currentTheme === themeOpt.id;
4394
+ const Preview = themeOpt.preview;
4395
+
4396
+ return (
4397
+ <button
4398
+ key={themeOpt.id}
4399
+ onClick={() => handleThemeChange(themeOpt.id)}
4400
+ disabled={saving}
4401
+ className={`group relative p-4 text-left transition-all rounded-theme-lg ${
4402
+ isSelected
4403
+ ? 'ring-2'
4404
+ : 'hover:ring-1'
4405
+ }`}
4406
+ style={{
4407
+ background: 'var(--bg-card)',
4408
+ border: '1px solid var(--border-color)',
4409
+ ringColor: isSelected ? 'var(--accent-primary)' : 'var(--border-color-strong)'
4410
+ }}
4411
+ >
4412
+ {/* Preview */}
4413
+ <div
4414
+ className="w-full aspect-[3/2] mb-4 overflow-hidden rounded-theme-md"
4415
+ style={{ border: '1px solid var(--border-color)' }}
4416
+ >
4417
+ <Preview />
4418
+ </div>
4419
+
4420
+ {/* Info */}
4421
+ <div className="flex items-center justify-between">
4422
+ <div>
4423
+ <h4 className="font-heading font-medium" style={{ color: 'var(--text-primary)' }}>
4424
+ {themeOpt.name}
4425
+ </h4>
4426
+ <p className="text-xs mt-0.5" style={{ color: 'var(--text-muted)' }}>
4427
+ {themeOpt.description}
4428
+ </p>
4429
+ </div>
4430
+
4431
+ {/* Radio indicator */}
4432
+ <div
4433
+ className={`w-5 h-5 rounded-full border-2 flex items-center justify-center transition-all ${
4434
+ isSelected ? 'border-transparent' : ''
4435
+ }`}
4436
+ style={{
4437
+ borderColor: isSelected ? 'var(--accent-primary)' : 'var(--border-color-strong)',
4438
+ background: isSelected ? 'var(--accent-primary)' : 'transparent'
4439
+ }}
4440
+ >
4441
+ {isSelected && (
4442
+ <Check className="w-3 h-3" style={{ color: 'var(--text-inverse)' }} />
4443
+ )}
4444
+ </div>
4445
+ </div>
4446
+
4447
+ {/* Loading overlay */}
4448
+ {saving && isSelected && (
4449
+ <div className="absolute inset-0 flex items-center justify-center rounded-theme-lg" style={{ background: 'rgba(0,0,0,0.5)' }}>
4450
+ <Loader2 className="w-6 h-6 animate-spin" style={{ color: 'var(--accent-primary)' }} />
4451
+ </div>
4452
+ )}
4453
+ </button>
4454
+ );
4455
+ })}
4456
+ </div>
4457
+
4458
+ {/* Color Mode Toggle */}
4459
+ <div className="mt-6 pt-6" style={{ borderTop: '1px solid var(--border-color)' }}>
4460
+ <div className="flex items-center justify-between">
4461
+ <div className="flex items-center gap-3">
4462
+ {isDark ? (
4463
+ <Moon className="w-5 h-5" style={{ color: 'var(--accent-primary)' }} />
4464
+ ) : (
4465
+ <Sun className="w-5 h-5" style={{ color: 'var(--accent-secondary)' }} />
4466
+ )}
4467
+ <div>
4468
+ <h4 className="font-heading font-medium" style={{ color: 'var(--text-primary)' }}>
4469
+ {language === 'es' ? 'Modo de color' : 'Color Mode'}
4470
+ </h4>
4471
+ <p className="text-xs" style={{ color: 'var(--text-muted)' }}>
4472
+ {language === 'es'
4473
+ ? isDark ? 'Modo oscuro activado' : 'Modo claro activado'
4474
+ : isDark ? 'Dark mode enabled' : 'Light mode enabled'}
4475
+ </p>
4476
+ </div>
4477
+ </div>
4478
+
4479
+ <div className="flex gap-2">
4480
+ <button
4481
+ onClick={() => handleColorModeChange('light')}
4482
+ disabled={savingMode}
4483
+ className={`px-4 py-2 rounded-theme-md transition-all flex items-center gap-2 ${
4484
+ !isDark ? 'ring-2' : ''
4485
+ }`}
4486
+ style={{
4487
+ background: !isDark ? 'var(--accent-primary)' : 'var(--bg-secondary)',
4488
+ color: !isDark ? 'var(--text-inverse)' : 'var(--text-secondary)',
4489
+ ringColor: 'var(--accent-primary)'
4490
+ }}
4491
+ >
4492
+ <Sun className="w-4 h-4" />
4493
+ <span className="text-sm font-medium">{language === 'es' ? 'Claro' : 'Light'}</span>
4494
+ </button>
4495
+ <button
4496
+ onClick={() => handleColorModeChange('dark')}
4497
+ disabled={savingMode}
4498
+ className={`px-4 py-2 rounded-theme-md transition-all flex items-center gap-2 ${
4499
+ isDark ? 'ring-2' : ''
4500
+ }`}
4501
+ style={{
4502
+ background: isDark ? 'var(--accent-primary)' : 'var(--bg-secondary)',
4503
+ color: isDark ? 'var(--text-inverse)' : 'var(--text-secondary)',
4504
+ ringColor: 'var(--accent-primary)'
4505
+ }}
4506
+ >
4507
+ <Moon className="w-4 h-4" />
4508
+ <span className="text-sm font-medium">{language === 'es' ? 'Oscuro' : 'Dark'}</span>
4509
+ </button>
4510
+ </div>
4511
+ </div>
4512
+ </div>
4513
+
4514
+ <p className="text-xs mt-4" style={{ color: 'var(--text-muted)' }}>
4515
+ {language === 'es'
4516
+ ? 'El tema y modo se guardan automáticamente en tu perfil'
4517
+ : 'Theme and mode are automatically saved to your profile'}
4518
+ </p>
4519
+ </div>
4520
+ );
4521
+ }
4522
+
4074
4523
  // ============ SETTINGS TAB ============
4075
4524
  function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfirm, showAlert, t, language, changeLanguage }) {
4076
4525
  const [copiedItem, setCopiedItem] = useState(null);
@@ -4408,6 +4857,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4408
4857
  // Settings sub-tabs configuration
4409
4858
  const settingsTabs = [
4410
4859
  { id: 'profile', label: t('settings.profile'), icon: User, show: !!authState?.user },
4860
+ { id: 'appearance', label: language === 'es' ? 'APARIENCIA' : 'APPEARANCE', icon: Palette, show: true },
4411
4861
  { id: 'users', label: t('settings.users'), icon: Lock, show: isAdmin },
4412
4862
  { id: 'history', label: t('settings.history'), icon: Clock, show: true },
4413
4863
  { id: 'files', label: t('settings.files'), icon: FileCode, show: true },
@@ -4446,7 +4896,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4446
4896
 
4447
4897
  {/* PROFILE TAB */}
4448
4898
  {settingsSubTab === 'profile' && authState?.user && (
4449
- <div className="terminal-card p-5 space-y-5">
4899
+ <div className="theme-card p-5 space-y-5">
4450
4900
  <div className="flex items-center gap-3 mb-2">
4451
4901
  <div className="w-12 h-12 border border-cyber/30 bg-cyber/10 flex items-center justify-center font-display text-cyber text-xl">
4452
4902
  {authState.user.name?.charAt(0).toUpperCase() || 'U'}
@@ -4483,7 +4933,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4483
4933
  type="text"
4484
4934
  value={profileData.name}
4485
4935
  onChange={(e) => setProfileData(prev => ({ ...prev, name: e.target.value }))}
4486
- className="w-full input-terminal px-3 py-2 text-sm"
4936
+ className="w-full theme-input px-3 py-2 text-sm"
4487
4937
  placeholder="Your name"
4488
4938
  />
4489
4939
  </div>
@@ -4493,7 +4943,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4493
4943
  type="email"
4494
4944
  value={profileData.email}
4495
4945
  onChange={(e) => setProfileData(prev => ({ ...prev, email: e.target.value }))}
4496
- className="w-full input-terminal px-3 py-2 text-sm"
4946
+ className="w-full theme-input px-3 py-2 text-sm"
4497
4947
  placeholder="your@email.com"
4498
4948
  />
4499
4949
  </div>
@@ -4508,7 +4958,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4508
4958
  type="password"
4509
4959
  value={profileData.currentPassword}
4510
4960
  onChange={(e) => setProfileData(prev => ({ ...prev, currentPassword: e.target.value }))}
4511
- className="w-full input-terminal px-3 py-2 text-sm"
4961
+ className="w-full theme-input px-3 py-2 text-sm"
4512
4962
  placeholder="Required"
4513
4963
  />
4514
4964
  </div>
@@ -4518,7 +4968,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4518
4968
  type="password"
4519
4969
  value={profileData.newPassword}
4520
4970
  onChange={(e) => setProfileData(prev => ({ ...prev, newPassword: e.target.value }))}
4521
- className="w-full input-terminal px-3 py-2 text-sm"
4971
+ className="w-full theme-input px-3 py-2 text-sm"
4522
4972
  placeholder="Min 6 chars"
4523
4973
  />
4524
4974
  </div>
@@ -4528,7 +4978,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4528
4978
  type="password"
4529
4979
  value={profileData.confirmPassword}
4530
4980
  onChange={(e) => setProfileData(prev => ({ ...prev, confirmPassword: e.target.value }))}
4531
- className="w-full input-terminal px-3 py-2 text-sm"
4981
+ className="w-full theme-input px-3 py-2 text-sm"
4532
4982
  placeholder="Repeat"
4533
4983
  />
4534
4984
  </div>
@@ -4538,7 +4988,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4538
4988
  <button
4539
4989
  onClick={updateProfile}
4540
4990
  disabled={savingProfile}
4541
- className="btn-terminal py-2 px-6 disabled:opacity-50 flex items-center gap-2"
4991
+ className="theme-btn-primary py-2 px-6 disabled:opacity-50 flex items-center gap-2"
4542
4992
  >
4543
4993
  {savingProfile ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
4544
4994
  SAVE CHANGES
@@ -4546,9 +4996,14 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4546
4996
  </div>
4547
4997
  )}
4548
4998
 
4999
+ {/* APPEARANCE TAB */}
5000
+ {settingsSubTab === 'appearance' && (
5001
+ <AppearanceSection language={language} />
5002
+ )}
5003
+
4549
5004
  {/* HISTORY TAB */}
4550
5005
  {settingsSubTab === 'history' && (
4551
- <div className="terminal-card p-5">
5006
+ <div className="theme-card p-5">
4552
5007
  <div className="flex items-center justify-between mb-4">
4553
5008
  <div>
4554
5009
  <h3 className="font-mono text-sm text-white">VERSION HISTORY</h3>
@@ -4559,7 +5014,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4559
5014
  <button
4560
5015
  onClick={loadVersions}
4561
5016
  disabled={loadingVersions}
4562
- className="btn-terminal py-2 px-4 text-xs"
5017
+ className="theme-btn-primary py-2 px-4 text-xs"
4563
5018
  >
4564
5019
  {loadingVersions ? <Loader2 className="w-4 h-4 animate-spin" /> : <RefreshCw className="w-4 h-4" />}
4565
5020
  </button>
@@ -4571,7 +5026,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4571
5026
  <Clock className="w-10 h-10 mx-auto mb-3 text-gray-800" />
4572
5027
  <p className="font-mono text-xs text-gray-600">NO VERSIONS YET</p>
4573
5028
  <p className="font-mono text-[10px] text-gray-700 mt-1">Versions are saved automatically when you save changes</p>
4574
- <button onClick={loadVersions} className="mt-4 btn-terminal py-2 px-4 text-xs">
5029
+ <button onClick={loadVersions} className="mt-4 theme-btn-primary py-2 px-4 text-xs">
4575
5030
  LOAD HISTORY
4576
5031
  </button>
4577
5032
  </div>
@@ -4636,7 +5091,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4636
5091
  <button
4637
5092
  onClick={() => restoreVersion(selectedVersion.id)}
4638
5093
  disabled={restoringVersion}
4639
- className="btn-terminal py-2 px-4 text-xs flex items-center gap-2"
5094
+ className="theme-btn-primary py-2 px-4 text-xs flex items-center gap-2"
4640
5095
  >
4641
5096
  {restoringVersion ? <Loader2 className="w-4 h-4 animate-spin" /> : <RefreshCw className="w-4 h-4" />}
4642
5097
  RESTORE THIS VERSION
@@ -4778,7 +5233,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4778
5233
  {settingsSubTab === 'users' && isAdmin && (
4779
5234
  <div className="space-y-5">
4780
5235
  {/* Auth Settings */}
4781
- <div className="terminal-card p-5">
5236
+ <div className="theme-card p-5">
4782
5237
  <div className="flex items-center justify-between">
4783
5238
  <div>
4784
5239
  <h3 className="font-mono text-sm text-white">Authentication Required</h3>
@@ -4794,7 +5249,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4794
5249
  </div>
4795
5250
 
4796
5251
  {/* Add User */}
4797
- <div className="terminal-card p-5">
5252
+ <div className="theme-card p-5">
4798
5253
  <h3 className="font-mono text-sm text-white mb-4">ADD NEW USER</h3>
4799
5254
  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 mb-3">
4800
5255
  <input
@@ -4802,26 +5257,26 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4802
5257
  placeholder="Name *"
4803
5258
  value={newUser.name}
4804
5259
  onChange={(e) => setNewUser(prev => ({ ...prev, name: e.target.value }))}
4805
- className="input-terminal px-3 py-2 text-sm"
5260
+ className="theme-input px-3 py-2 text-sm"
4806
5261
  />
4807
5262
  <input
4808
5263
  type="email"
4809
5264
  placeholder="Email *"
4810
5265
  value={newUser.email}
4811
5266
  onChange={(e) => setNewUser(prev => ({ ...prev, email: e.target.value }))}
4812
- className="input-terminal px-3 py-2 text-sm"
5267
+ className="theme-input px-3 py-2 text-sm"
4813
5268
  />
4814
5269
  <input
4815
5270
  type="password"
4816
5271
  placeholder="Password *"
4817
5272
  value={newUser.password}
4818
5273
  onChange={(e) => setNewUser(prev => ({ ...prev, password: e.target.value }))}
4819
- className="input-terminal px-3 py-2 text-sm"
5274
+ className="theme-input px-3 py-2 text-sm"
4820
5275
  />
4821
5276
  <select
4822
5277
  value={newUser.role}
4823
5278
  onChange={(e) => setNewUser(prev => ({ ...prev, role: e.target.value }))}
4824
- className="input-terminal px-3 py-2 text-sm"
5279
+ className="theme-input px-3 py-2 text-sm"
4825
5280
  >
4826
5281
  <option value="member">Member</option>
4827
5282
  <option value="admin">Admin</option>
@@ -4835,14 +5290,14 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4835
5290
  <button
4836
5291
  onClick={createUser}
4837
5292
  disabled={!newUser.name.trim() || !newUser.email.trim() || !newUser.password.trim()}
4838
- className="btn-terminal py-2 px-4 disabled:opacity-50"
5293
+ className="theme-btn-primary py-2 px-4 disabled:opacity-50"
4839
5294
  >
4840
5295
  <Plus className="w-4 h-4 inline mr-1" /> CREATE USER
4841
5296
  </button>
4842
5297
  </div>
4843
5298
 
4844
5299
  {/* Users List */}
4845
- <div className="terminal-card p-5">
5300
+ <div className="theme-card p-5">
4846
5301
  <h3 className="font-mono text-sm text-white mb-4">REGISTERED USERS ({users.length})</h3>
4847
5302
  {loadingUsers ? (
4848
5303
  <div className="py-8 text-center">
@@ -4895,9 +5350,9 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4895
5350
  {settingsSubTab === 'files' && (
4896
5351
  <div className="space-y-5">
4897
5352
  {/* Deploy */}
4898
- <div className="terminal-card p-5">
5353
+ <div className="theme-card p-5">
4899
5354
  <div className="flex items-center gap-3 mb-4">
4900
- <div className="led led-green" />
5355
+ <div className="led theme-led theme-led-success" />
4901
5356
  <div>
4902
5357
  <h3 className="font-mono text-sm text-matrix tracking-wider">DEPLOY CONFIG</h3>
4903
5358
  <p className="font-mono text-[10px] text-gray-600">Copy files to project root</p>
@@ -4920,7 +5375,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4920
5375
  Also create .cursorrules (for Cursor IDE)
4921
5376
  </label>
4922
5377
 
4923
- <button onClick={deployToProject} disabled={deploying} className="btn-terminal flex items-center gap-2">
5378
+ <button onClick={deployToProject} disabled={deploying} className="theme-btn-primary flex items-center gap-2">
4924
5379
  {deploying ? <Loader2 className="w-4 h-4 animate-spin" /> : <Rocket className="w-4 h-4" />}
4925
5380
  DEPLOY FILES
4926
5381
  </button>
@@ -4942,7 +5397,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4942
5397
  </div>
4943
5398
 
4944
5399
  {/* .clinerules */}
4945
- <div className="terminal-card">
5400
+ <div className="theme-card">
4946
5401
  <button
4947
5402
  onClick={() => setClineruleExpanded(!clineruleExpanded)}
4948
5403
  className="w-full p-4 flex items-center justify-between hover:bg-white/[0.01] transition-colors"
@@ -4978,7 +5433,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4978
5433
  <textarea
4979
5434
  value={clinerules}
4980
5435
  onChange={(e) => setClinerules(e.target.value)}
4981
- className="w-full h-[400px] input-terminal p-4 text-xs resize-none"
5436
+ className="w-full h-[400px] theme-input p-4 text-xs resize-none"
4982
5437
  spellCheck={false}
4983
5438
  />
4984
5439
  ) : (
@@ -4991,7 +5446,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
4991
5446
  </div>
4992
5447
 
4993
5448
  {/* roadmap.json */}
4994
- <div className="terminal-card">
5449
+ <div className="theme-card">
4995
5450
  <button
4996
5451
  onClick={() => setJsonExpanded(!jsonExpanded)}
4997
5452
  className="w-full p-4 flex items-center justify-between hover:bg-white/[0.01] transition-colors"
@@ -5051,7 +5506,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
5051
5506
  <textarea
5052
5507
  value={jsonContent}
5053
5508
  onChange={(e) => { setJsonContent(e.target.value); setJsonError(null); }}
5054
- className="w-full h-[400px] input-terminal p-4 text-xs resize-none"
5509
+ className="w-full h-[400px] theme-input p-4 text-xs resize-none"
5055
5510
  spellCheck={false}
5056
5511
  />
5057
5512
  <p className="mt-2 font-mono text-[10px] text-gray-600">
@@ -5071,7 +5526,7 @@ function SettingsTab({ roadmap, setRoadmap, setHasChanges, authState, showConfir
5071
5526
 
5072
5527
  {/* LANGUAGE TAB */}
5073
5528
  {settingsSubTab === 'language' && (
5074
- <div className="terminal-card p-5">
5529
+ <div className="theme-card p-5">
5075
5530
  <h3 className="font-mono text-sm text-white mb-2">{t('settings.language')}</h3>
5076
5531
  <p className="font-mono text-[10px] text-gray-600 mb-6">
5077
5532
  {language === 'es' ? 'Selecciona el idioma de la interfaz' : 'Select interface language'}
@@ -5188,7 +5643,7 @@ function HelpTab({ t, language }) {
5188
5643
  {/* Templates */}
5189
5644
  {activeSection === 'templates' && (
5190
5645
  <div className="space-y-6">
5191
- <div className="terminal-card p-5">
5646
+ <div className="theme-card p-5">
5192
5647
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4">{t('help.referenceFiles')}</h3>
5193
5648
  <p className="font-mono text-[11px] text-gray-500 mb-4">{t('help.sharePaths')}</p>
5194
5649
  <div className="space-y-2">
@@ -5212,7 +5667,7 @@ function HelpTab({ t, language }) {
5212
5667
  </div>
5213
5668
  </div>
5214
5669
 
5215
- <div className="terminal-card p-5">
5670
+ <div className="theme-card p-5">
5216
5671
  <h3 className="font-mono text-sm text-cyber tracking-wider mb-4">{t('help.aiInstructions')}</h3>
5217
5672
  <div className="bg-void-100 border border-white/5 p-4 font-mono text-[11px] text-gray-400 overflow-x-auto">
5218
5673
  <pre className="whitespace-pre-wrap">{`Read the example files in:
@@ -5247,7 +5702,7 @@ Then generate a roadmap.json for my project following this structure:
5247
5702
  </div>
5248
5703
  </div>
5249
5704
 
5250
- <div className="terminal-card p-5 border-matrix/20">
5705
+ <div className="theme-card p-5 border-matrix/20">
5251
5706
  <div className="flex items-center justify-between mb-3">
5252
5707
  <h4 className="font-mono text-sm text-matrix">{t('help.quickPrompt')}</h4>
5253
5708
  <button
@@ -5276,7 +5731,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5276
5731
  {/* Commits */}
5277
5732
  {activeSection === 'commits' && (
5278
5733
  <div className="space-y-6">
5279
- <div className="terminal-card p-5">
5734
+ <div className="theme-card p-5">
5280
5735
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4">{t('help.commitFormat')}</h3>
5281
5736
  <p className="font-mono text-[11px] text-gray-500 mb-4">{t('help.commitFormatDesc')}</p>
5282
5737
  <div className="bg-void-100 border border-white/5 p-4 mb-6">
@@ -5314,7 +5769,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5314
5769
  </div>
5315
5770
  </div>
5316
5771
 
5317
- <div className="terminal-card p-5">
5772
+ <div className="theme-card p-5">
5318
5773
  <h4 className="font-mono text-xs text-gray-400 mb-4">{t('help.examples')}</h4>
5319
5774
  <div className="space-y-3">
5320
5775
  {[
@@ -5330,7 +5785,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5330
5785
  </div>
5331
5786
  </div>
5332
5787
 
5333
- <div className="terminal-card p-5 border-cyber/20">
5788
+ <div className="theme-card p-5 border-cyber/20">
5334
5789
  <h4 className="font-mono text-sm text-cyber tracking-wider mb-3">{t('help.syncWithGit')}</h4>
5335
5790
  <p className="font-mono text-[11px] text-gray-500 mb-3">{t('help.afterCommits')}</p>
5336
5791
  <div className="bg-void-100 border border-white/5 p-3">
@@ -5346,7 +5801,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5346
5801
  {/* AI Workflow */}
5347
5802
  {activeSection === 'ai' && (
5348
5803
  <div className="space-y-6">
5349
- <div className="terminal-card p-5">
5804
+ <div className="theme-card p-5">
5350
5805
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4">{t('help.recommendedWorkflow')}</h3>
5351
5806
  <div className="space-y-2">
5352
5807
  {[
@@ -5363,7 +5818,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5363
5818
  </div>
5364
5819
 
5365
5820
  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
5366
- <div className="terminal-card p-5 border-matrix/20">
5821
+ <div className="theme-card p-5 border-matrix/20">
5367
5822
  <h4 className="font-mono text-xs text-matrix tracking-wider mb-4 flex items-center gap-2">
5368
5823
  <CheckCircle2 className="w-4 h-4" /> {t('help.aiMustDo')}
5369
5824
  </h4>
@@ -5376,7 +5831,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5376
5831
  </ul>
5377
5832
  </div>
5378
5833
 
5379
- <div className="terminal-card p-5 border-alert/20">
5834
+ <div className="theme-card p-5 border-alert/20">
5380
5835
  <h4 className="font-mono text-xs text-alert tracking-wider mb-4 flex items-center gap-2">
5381
5836
  <X className="w-4 h-4" /> {t('help.aiMustNot')}
5382
5837
  </h4>
@@ -5395,7 +5850,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5395
5850
  {/* Troubleshooting */}
5396
5851
  {activeSection === 'troubleshooting' && (
5397
5852
  <div className="space-y-4">
5398
- <div className="terminal-card p-5">
5853
+ <div className="theme-card p-5">
5399
5854
  <h3 className="font-mono text-sm text-signal tracking-wider mb-4">{t('help.troubleshooting')}</h3>
5400
5855
  <div className="space-y-4">
5401
5856
  {[
@@ -5415,7 +5870,7 @@ Then help me create/improve the roadmap.json for my project following that forma
5415
5870
  </div>
5416
5871
  </div>
5417
5872
 
5418
- <div className="terminal-card p-5">
5873
+ <div className="theme-card p-5">
5419
5874
  <h4 className="font-mono text-xs text-gray-400 mb-4">{t('help.fileSummary')}</h4>
5420
5875
  <div className="overflow-x-auto">
5421
5876
  <table className="w-full font-mono text-[11px]">
@@ -5716,7 +6171,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5716
6171
  return (
5717
6172
  <div className="space-y-6 animate-fade-in">
5718
6173
  {/* Setup Complete Header */}
5719
- <div className="terminal-card p-8 border-matrix/50 text-center">
6174
+ <div className="theme-card p-8 border-matrix/50 text-center">
5720
6175
  <div className="w-20 h-20 mx-auto border-2 border-matrix/50 flex items-center justify-center mb-6 glow-matrix">
5721
6176
  <CheckCircle2 className="w-10 h-10 text-matrix" />
5722
6177
  </div>
@@ -5729,7 +6184,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5729
6184
  </div>
5730
6185
 
5731
6186
  {/* Roadmap Status Card */}
5732
- <div className="terminal-card p-5">
6187
+ <div className="theme-card p-5">
5733
6188
  <h3 className="font-mono text-sm text-white tracking-wider mb-4">
5734
6189
  {t ? t('setup.roadmapStatus') : 'ROADMAP STATUS'}
5735
6190
  </h3>
@@ -5772,7 +6227,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5772
6227
  <div className="flex gap-3">
5773
6228
  <button
5774
6229
  onClick={() => window.location.hash = '#features'}
5775
- className="btn-terminal flex-1 py-3 flex items-center justify-center gap-2"
6230
+ className="theme-btn-primary flex-1 py-3 flex items-center justify-center gap-2"
5776
6231
  >
5777
6232
  <Zap className="w-4 h-4" />
5778
6233
  {t ? t('setup.goToDashboard') : 'GO TO DASHBOARD'}
@@ -5788,7 +6243,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5788
6243
 
5789
6244
  {/* Project Info Summary */}
5790
6245
  {roadmap?.project_info && (
5791
- <div className="terminal-card p-5">
6246
+ <div className="theme-card p-5">
5792
6247
  <h3 className="font-mono text-sm text-cyber tracking-wider mb-4"># {roadmap.project_info.name || 'PROJECT'}</h3>
5793
6248
  {roadmap.project_info.description && (
5794
6249
  <p className="font-mono text-xs text-gray-400 mb-4">{roadmap.project_info.description}</p>
@@ -5811,7 +6266,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5811
6266
  return (
5812
6267
  <div className="space-y-6 animate-fade-in">
5813
6268
  {/* Header */}
5814
- <div className="terminal-card p-5 border-matrix/30">
6269
+ <div className="theme-card p-5 border-matrix/30">
5815
6270
  <div className="flex items-center gap-4">
5816
6271
  <div className="w-14 h-14 border border-matrix/50 flex items-center justify-center glow-matrix">
5817
6272
  <Sparkles className="w-7 h-7 text-matrix" />
@@ -5864,7 +6319,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5864
6319
  {/* Step 1: Choose Connection Mode */}
5865
6320
  {activeStep === 1 && (
5866
6321
  <div className="space-y-4">
5867
- <div className="terminal-card p-6">
6322
+ <div className="theme-card p-6">
5868
6323
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4"># {t ? t('setup.chooseConnection') : 'CHOOSE CONNECTION MODE'}</h3>
5869
6324
  <p className="font-mono text-xs text-gray-500 mb-6">
5870
6325
  {t ? t('setup.chooseConnectionDesc') : 'Choose how to connect with Claude to generate your project configuration.'}
@@ -5881,7 +6336,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5881
6336
  }`}
5882
6337
  >
5883
6338
  <div className="flex items-center gap-3 mb-3">
5884
- <div className={`led ${claudeCodeStatus.available ? 'led-green' : claudeCodeStatus.checking ? 'led-amber' : 'led-red'}`} />
6339
+ <div className={`led ${claudeCodeStatus.available ? 'theme-led theme-led-success' : claudeCodeStatus.checking ? 'theme-led theme-led-warning' : 'theme-led theme-led-danger'}`} />
5885
6340
  <span className="font-mono text-sm text-white">CLAUDE CODE</span>
5886
6341
  <span className="font-mono text-[9px] px-2 py-0.5 bg-matrix/20 text-matrix border border-matrix/30">
5887
6342
  {t ? t('setup.recommended') : 'RECOMMENDED'}
@@ -5918,7 +6373,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5918
6373
  }`}
5919
6374
  >
5920
6375
  <div className="flex items-center gap-3 mb-3">
5921
- <div className={`led ${apiKeyStatus.hasKey ? 'led-green' : 'led-gray'}`} />
6376
+ <div className={`led ${apiKeyStatus.hasKey ? 'theme-led theme-led-success' : 'led-gray'}`} />
5922
6377
  <span className="font-mono text-sm text-white">API KEY</span>
5923
6378
  </div>
5924
6379
  <p className="font-mono text-[11px] text-gray-500 mb-3">
@@ -5941,7 +6396,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5941
6396
 
5942
6397
  {/* Claude Code selected but not available */}
5943
6398
  {generationMode === 'claude-code' && !claudeCodeStatus.checking && !claudeCodeStatus.available && (
5944
- <div className="terminal-card p-5 border-signal/30">
6399
+ <div className="theme-card p-5 border-signal/30">
5945
6400
  <h4 className="font-mono text-xs text-signal tracking-wider mb-3">INSTALAR CLAUDE CODE</h4>
5946
6401
  <p className="font-mono text-[11px] text-gray-500 mb-4">
5947
6402
  Para usar tu suscripción, necesitas tener Claude Code instalado y autenticado.
@@ -5965,7 +6420,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5965
6420
 
5966
6421
  {/* API mode selected - show key input */}
5967
6422
  {generationMode === 'api' && (
5968
- <div className="terminal-card p-5">
6423
+ <div className="theme-card p-5">
5969
6424
  <h4 className="font-mono text-xs text-cyber tracking-wider mb-3">CONFIGURAR API KEY</h4>
5970
6425
  <p className="font-mono text-[11px] text-gray-500 mb-4">
5971
6426
  Obtén una API key en{' '}
@@ -5981,7 +6436,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5981
6436
  <span className="text-matrix">{apiKeyStatus.maskedKey}</span>
5982
6437
  </div>
5983
6438
  <div className="flex gap-3">
5984
- <button onClick={() => setActiveStep(2)} className="btn-terminal flex-1">
6439
+ <button onClick={() => setActiveStep(2)} className="theme-btn-primary flex-1">
5985
6440
  CONTINUE →
5986
6441
  </button>
5987
6442
  <button
@@ -5999,12 +6454,12 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
5999
6454
  placeholder="sk-ant-api03-..."
6000
6455
  value={apiKey}
6001
6456
  onChange={(e) => setApiKey(e.target.value)}
6002
- className="input-terminal w-full px-4 py-3 text-sm"
6457
+ className="theme-input w-full px-4 py-3 text-sm"
6003
6458
  />
6004
6459
  <button
6005
6460
  onClick={saveApiKey}
6006
6461
  disabled={!apiKey.trim()}
6007
- className="btn-terminal w-full py-3 disabled:opacity-50"
6462
+ className="theme-btn-primary w-full py-3 disabled:opacity-50"
6008
6463
  >
6009
6464
  SAVE API KEY
6010
6465
  </button>
@@ -6015,7 +6470,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6015
6470
 
6016
6471
  {/* Continue button for Claude Code mode */}
6017
6472
  {generationMode === 'claude-code' && claudeCodeStatus.available && (
6018
- <button onClick={() => setActiveStep(2)} className="btn-terminal w-full py-4">
6473
+ <button onClick={() => setActiveStep(2)} className="theme-btn-primary w-full py-4">
6019
6474
  CONTINUE WITH CLAUDE CODE →
6020
6475
  </button>
6021
6476
  )}
@@ -6027,7 +6482,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6027
6482
  <div className="space-y-4">
6028
6483
  {/* Roadmap Validation Status */}
6029
6484
  {hasExistingRoadmap && (
6030
- <div className={`terminal-card p-5 ${validateRoadmap.valid ? 'border-matrix/50' : validateRoadmap.issues.length > 0 ? 'border-alert/30' : 'border-signal/30'}`}>
6485
+ <div className={`theme-card p-5 ${validateRoadmap.valid ? 'border-matrix/50' : validateRoadmap.issues.length > 0 ? 'border-alert/30' : 'border-signal/30'}`}>
6031
6486
  <div className="flex items-start gap-4">
6032
6487
  <div className={`w-12 h-12 border flex items-center justify-center ${
6033
6488
  validateRoadmap.valid ? 'border-matrix/50 bg-matrix/10' :
@@ -6105,7 +6560,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6105
6560
  <div className="flex gap-3">
6106
6561
  <button
6107
6562
  onClick={() => setActiveStep(4)}
6108
- className="btn-terminal px-6 py-2 flex items-center gap-2"
6563
+ className="theme-btn-primary px-6 py-2 flex items-center gap-2"
6109
6564
  >
6110
6565
  <CheckCircle2 className="w-4 h-4" />
6111
6566
  CONTINUE TO DASHBOARD
@@ -6149,10 +6604,13 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6149
6604
  )}
6150
6605
 
6151
6606
  {/* Project Scan Results */}
6152
- <div className="terminal-card">
6153
- <button
6607
+ <div className="theme-card">
6608
+ <div
6154
6609
  onClick={() => setScanExpanded(!scanExpanded)}
6155
- className="w-full p-4 flex items-center justify-between hover:bg-white/[0.01] transition-colors"
6610
+ className="w-full p-4 flex items-center justify-between hover:bg-white/[0.01] transition-colors cursor-pointer"
6611
+ role="button"
6612
+ tabIndex={0}
6613
+ onKeyDown={(e) => e.key === 'Enter' && setScanExpanded(!scanExpanded)}
6156
6614
  >
6157
6615
  <div className="flex items-center gap-3">
6158
6616
  <FolderOpen className="w-4 h-4 text-cyber" />
@@ -6173,7 +6631,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6173
6631
  </button>
6174
6632
  <ChevronDown className={`w-4 h-4 text-gray-600 transition-transform ${scanExpanded ? 'rotate-180' : ''}`} />
6175
6633
  </div>
6176
- </button>
6634
+ </div>
6177
6635
 
6178
6636
  {scanExpanded && projectScan && (
6179
6637
  <div className="px-4 pb-4 border-t border-white/5">
@@ -6229,7 +6687,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6229
6687
  </div>
6230
6688
 
6231
6689
  {/* Requirements Input */}
6232
- <div className="terminal-card p-6">
6690
+ <div className="theme-card p-6">
6233
6691
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-2"># REQUIREMENTS</h3>
6234
6692
  <p className="font-mono text-[10px] text-gray-500 mb-4">
6235
6693
  Describe las características, funcionalidades o mejoras que quieres implementar. Claude analizará tu proyecto y generará un roadmap estructurado.
@@ -6247,13 +6705,13 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6247
6705
  value={requirements}
6248
6706
  onChange={(e) => setRequirements(e.target.value)}
6249
6707
  rows={10}
6250
- className="input-terminal w-full px-4 py-3 text-sm resize-none mb-4"
6708
+ className="theme-input w-full px-4 py-3 text-sm resize-none mb-4"
6251
6709
  />
6252
6710
 
6253
6711
  <button
6254
6712
  onClick={analyzeWithAI}
6255
6713
  disabled={generating || !requirements.trim()}
6256
- className="btn-terminal w-full py-3 flex items-center justify-center gap-2 disabled:opacity-50"
6714
+ className="theme-btn-primary w-full py-3 flex items-center justify-center gap-2 disabled:opacity-50"
6257
6715
  >
6258
6716
  {generating ? (
6259
6717
  <>
@@ -6280,7 +6738,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6280
6738
  <div className="space-y-4">
6281
6739
  {/* Analysis Summary */}
6282
6740
  {generatedResult.analysis && (
6283
- <div className="terminal-card p-4 border-cyber/30">
6741
+ <div className="theme-card p-4 border-cyber/30">
6284
6742
  <h4 className="font-mono text-xs text-cyber tracking-wider mb-3 flex items-center gap-2">
6285
6743
  <Info className="w-4 h-4" /> ANALYSIS SUMMARY
6286
6744
  </h4>
@@ -6312,7 +6770,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6312
6770
  </div>
6313
6771
  )}
6314
6772
 
6315
- <div className="terminal-card p-6">
6773
+ <div className="theme-card p-6">
6316
6774
  <h3 className="font-mono text-sm text-matrix tracking-wider mb-4"># GENERATED ROADMAP</h3>
6317
6775
 
6318
6776
  <div className="grid grid-cols-2 gap-4 mb-6">
@@ -6373,14 +6831,14 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6373
6831
  <button onClick={() => setActiveStep(2)} className="px-4 py-2 border border-white/10 text-gray-500 font-mono text-xs hover:text-white transition-all">
6374
6832
  ← BACK
6375
6833
  </button>
6376
- <button onClick={applyGenerated} className="btn-terminal flex-1 py-3">
6834
+ <button onClick={applyGenerated} className="theme-btn-primary flex-1 py-3">
6377
6835
  APPLY & DEPLOY
6378
6836
  </button>
6379
6837
  </div>
6380
6838
  </div>
6381
6839
 
6382
6840
  {/* JSON Preview */}
6383
- <div className="terminal-card p-4">
6841
+ <div className="theme-card p-4">
6384
6842
  <details>
6385
6843
  <summary className="font-mono text-xs text-gray-500 cursor-pointer hover:text-white">
6386
6844
  VIEW GENERATED JSON
@@ -6395,7 +6853,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6395
6853
 
6396
6854
  {/* Step 4: Complete */}
6397
6855
  {activeStep === 4 && (
6398
- <div className="terminal-card p-8 text-center">
6856
+ <div className="theme-card p-8 text-center">
6399
6857
  <div className="w-20 h-20 mx-auto mb-6 border-2 border-matrix flex items-center justify-center glow-matrix">
6400
6858
  <CheckCircle2 className="w-10 h-10 text-matrix" />
6401
6859
  </div>
@@ -6407,7 +6865,7 @@ function SetupTab({ roadmap, setRoadmap, setHasChanges, loadRoadmap, t, language
6407
6865
  <button onClick={() => { setActiveStep(1); setGeneratedResult(null); }} className="px-4 py-2 border border-white/10 text-gray-500 font-mono text-xs hover:text-white transition-all">
6408
6866
  START OVER
6409
6867
  </button>
6410
- <button onClick={() => window.location.reload()} className="btn-terminal px-6 py-2">
6868
+ <button onClick={() => window.location.reload()} className="theme-btn-primary px-6 py-2">
6411
6869
  VIEW DASHBOARD
6412
6870
  </button>
6413
6871
  </div>
@@ -6445,7 +6903,7 @@ function AddTaskForm({ onAdd, onCancel, team = [], t, language }) {
6445
6903
  placeholder={t ? t('features.taskName') : "Task name"}
6446
6904
  value={name}
6447
6905
  onChange={(e) => setName(e.target.value)}
6448
- className="input-terminal w-full px-3 py-2 text-sm"
6906
+ className="theme-input w-full px-3 py-2 text-sm"
6449
6907
  autoFocus
6450
6908
  />
6451
6909
  <textarea
@@ -6453,10 +6911,10 @@ function AddTaskForm({ onAdd, onCancel, team = [], t, language }) {
6453
6911
  value={description}
6454
6912
  onChange={(e) => setDescription(e.target.value)}
6455
6913
  rows={2}
6456
- className="input-terminal w-full px-3 py-2 text-sm resize-none"
6914
+ className="theme-input w-full px-3 py-2 text-sm resize-none"
6457
6915
  />
6458
6916
  <div className="flex items-center gap-3 flex-wrap">
6459
- <select value={priority} onChange={(e) => setPriority(e.target.value)} className="input-terminal px-3 py-2 text-sm">
6917
+ <select value={priority} onChange={(e) => setPriority(e.target.value)} className="theme-input px-3 py-2 text-sm">
6460
6918
  <option value="high">{t ? t('common.high').toUpperCase() : 'HIGH'}</option>
6461
6919
  <option value="medium">{t ? t('common.medium').toUpperCase() : 'MEDIUM'}</option>
6462
6920
  <option value="low">{t ? t('common.low').toUpperCase() : 'LOW'}</option>
@@ -6465,7 +6923,7 @@ function AddTaskForm({ onAdd, onCancel, team = [], t, language }) {
6465
6923
  <select
6466
6924
  value={assignedTo}
6467
6925
  onChange={(e) => setAssignedTo(e.target.value)}
6468
- className="input-terminal px-3 py-2 text-sm"
6926
+ className="theme-input px-3 py-2 text-sm"
6469
6927
  >
6470
6928
  <option value="">{t ? t('features.unassigned') : 'Unassigned'}</option>
6471
6929
  {team.map(member => (
@@ -6477,7 +6935,7 @@ function AddTaskForm({ onAdd, onCancel, team = [], t, language }) {
6477
6935
  <button type="button" onClick={onCancel} className="px-4 py-2 font-mono text-xs text-gray-500 hover:text-white transition-all">
6478
6936
  {t ? t('common.cancel').toUpperCase() : 'CANCEL'}
6479
6937
  </button>
6480
- <button type="submit" disabled={!name.trim()} className="btn-terminal px-4 py-2 disabled:opacity-50">
6938
+ <button type="submit" disabled={!name.trim()} className="theme-btn-primary px-4 py-2 disabled:opacity-50">
6481
6939
  {t ? t('common.add').toUpperCase() : 'ADD'}
6482
6940
  </button>
6483
6941
  </div>
@@ -6518,7 +6976,7 @@ function AddFeatureForm({ onAdd, onClose, team = [], t, language }) {
6518
6976
  placeholder="e.g. user-auth"
6519
6977
  value={id}
6520
6978
  onChange={(e) => setId(e.target.value)}
6521
- className="input-terminal w-full px-4 py-2.5 mt-2 text-sm"
6979
+ className="theme-input w-full px-4 py-2.5 mt-2 text-sm"
6522
6980
  />
6523
6981
  </div>
6524
6982
  <div>
@@ -6528,7 +6986,7 @@ function AddFeatureForm({ onAdd, onClose, team = [], t, language }) {
6528
6986
  placeholder={t ? t('features.featureName') : "Feature name"}
6529
6987
  value={name}
6530
6988
  onChange={(e) => setName(e.target.value)}
6531
- className="input-terminal w-full px-4 py-2.5 mt-2 text-sm"
6989
+ className="theme-input w-full px-4 py-2.5 mt-2 text-sm"
6532
6990
  autoFocus
6533
6991
  />
6534
6992
  </div>
@@ -6539,12 +6997,12 @@ function AddFeatureForm({ onAdd, onClose, team = [], t, language }) {
6539
6997
  value={description}
6540
6998
  onChange={(e) => setDescription(e.target.value)}
6541
6999
  rows={3}
6542
- className="input-terminal w-full px-4 py-2.5 mt-2 text-sm resize-none"
7000
+ className="theme-input w-full px-4 py-2.5 mt-2 text-sm resize-none"
6543
7001
  />
6544
7002
  </div>
6545
7003
  <div>
6546
7004
  <label className="font-mono text-[10px] text-gray-500 tracking-wider">{t ? t('features.priority').toUpperCase() : 'PRIORITY'}</label>
6547
- <select value={priority} onChange={(e) => setPriority(e.target.value)} className="input-terminal w-full px-4 py-2.5 mt-2 text-sm">
7005
+ <select value={priority} onChange={(e) => setPriority(e.target.value)} className="theme-input w-full px-4 py-2.5 mt-2 text-sm">
6548
7006
  <option value="high">{t ? t('common.high').toUpperCase() : 'HIGH'}</option>
6549
7007
  <option value="medium">{t ? t('common.medium').toUpperCase() : 'MEDIUM'}</option>
6550
7008
  <option value="low">{t ? t('common.low').toUpperCase() : 'LOW'}</option>
@@ -6556,7 +7014,7 @@ function AddFeatureForm({ onAdd, onClose, team = [], t, language }) {
6556
7014
  <select
6557
7015
  value={assignedTo}
6558
7016
  onChange={(e) => setAssignedTo(e.target.value)}
6559
- className="input-terminal w-full px-4 py-2.5 mt-2 text-sm"
7017
+ className="theme-input w-full px-4 py-2.5 mt-2 text-sm"
6560
7018
  >
6561
7019
  <option value="">{t ? t('features.unassigned') : 'Unassigned'}</option>
6562
7020
  {team.map(member => (
@@ -6569,7 +7027,7 @@ function AddFeatureForm({ onAdd, onClose, team = [], t, language }) {
6569
7027
  <button type="button" onClick={onClose} className="flex-1 py-2.5 border border-white/20 text-gray-500 font-mono text-xs hover:bg-white/5 transition-all">
6570
7028
  {t ? t('common.cancel').toUpperCase() : 'CANCEL'}
6571
7029
  </button>
6572
- <button type="submit" disabled={!name.trim()} className="btn-terminal flex-1 py-2.5 disabled:opacity-50">
7030
+ <button type="submit" disabled={!name.trim()} className="theme-btn-primary flex-1 py-2.5 disabled:opacity-50">
6573
7031
  {language === 'es' ? 'CREAR' : 'CREATE'}
6574
7032
  </button>
6575
7033
  </div>
@@ -6581,7 +7039,7 @@ function AddFeatureForm({ onAdd, onClose, team = [], t, language }) {
6581
7039
  function Modal({ children, onClose }) {
6582
7040
  return (
6583
7041
  <div className="fixed inset-0 z-50 flex items-center justify-center p-4 modal-overlay animate-fade-in" onClick={onClose}>
6584
- <div className="terminal-card p-6 max-w-md w-full" onClick={e => e.stopPropagation()}>
7042
+ <div className="theme-card p-6 max-w-md w-full" onClick={e => e.stopPropagation()}>
6585
7043
  {children}
6586
7044
  </div>
6587
7045
  </div>
@@ -6618,7 +7076,7 @@ function ThemeModal({ roadmap, setRoadmap, setHasChanges, onClose }) {
6618
7076
 
6619
7077
  return (
6620
7078
  <div className="fixed inset-0 z-50 flex items-center justify-center p-4 modal-overlay animate-fade-in" onClick={onClose}>
6621
- <div className="terminal-card p-6 max-w-lg w-full" onClick={e => e.stopPropagation()}>
7079
+ <div className="theme-card p-6 max-w-lg w-full" onClick={e => e.stopPropagation()}>
6622
7080
  {/* Header */}
6623
7081
  <div className="flex items-center justify-between mb-6">
6624
7082
  <div className="flex items-center gap-3">
@@ -6683,14 +7141,14 @@ function ThemeModal({ roadmap, setRoadmap, setHasChanges, onClose }) {
6683
7141
  }
6684
7142
  }}
6685
7143
  placeholder="#00ff88"
6686
- className="input-terminal px-3 py-2 text-sm w-32 font-mono"
7144
+ className="theme-input px-3 py-2 text-sm w-32 font-mono"
6687
7145
  />
6688
7146
  <input
6689
7147
  type="text"
6690
7148
  value={currentTheme.name}
6691
7149
  onChange={(e) => updateTheme({ ...currentTheme, name: e.target.value })}
6692
7150
  placeholder="Theme name"
6693
- className="input-terminal px-3 py-2 text-sm flex-1 font-mono"
7151
+ className="theme-input px-3 py-2 text-sm flex-1 font-mono"
6694
7152
  />
6695
7153
  </div>
6696
7154
  </div>
@@ -6707,7 +7165,7 @@ function ThemeModal({ roadmap, setRoadmap, setHasChanges, onClose }) {
6707
7165
  </div>
6708
7166
  <div className="flex-1">
6709
7167
  <div className="font-mono text-xs text-white">{roadmap?.project_info?.name || 'Project'}</div>
6710
- <div className="progress-brutal mt-2 h-2">
7168
+ <div className="theme-progress mt-2 h-2">
6711
7169
  <div
6712
7170
  className="h-full transition-all"
6713
7171
  style={{
@@ -6761,9 +7219,9 @@ function LoginScreen({ onLogin, error }) {
6761
7219
  </div>
6762
7220
 
6763
7221
  {/* Login Form */}
6764
- <div className="terminal-card p-6">
7222
+ <div className="theme-card p-6">
6765
7223
  <div className="flex items-center gap-3 mb-6">
6766
- <div className="led led-amber" />
7224
+ <div className="led theme-led theme-led-warning" />
6767
7225
  <span className="font-mono text-xs text-signal tracking-wider">AUTHENTICATION REQUIRED</span>
6768
7226
  </div>
6769
7227
 
@@ -6777,7 +7235,7 @@ function LoginScreen({ onLogin, error }) {
6777
7235
  value={email}
6778
7236
  onChange={(e) => setEmail(e.target.value)}
6779
7237
  placeholder="admin@localhost"
6780
- className="input-terminal w-full pl-10 pr-4 py-3 text-sm"
7238
+ className="theme-input w-full pl-10 pr-4 py-3 text-sm"
6781
7239
  autoComplete="email"
6782
7240
  autoFocus
6783
7241
  />
@@ -6793,7 +7251,7 @@ function LoginScreen({ onLogin, error }) {
6793
7251
  value={password}
6794
7252
  onChange={(e) => setPassword(e.target.value)}
6795
7253
  placeholder="••••••••"
6796
- className="input-terminal w-full pl-10 pr-4 py-3 text-sm"
7254
+ className="theme-input w-full pl-10 pr-4 py-3 text-sm"
6797
7255
  autoComplete="current-password"
6798
7256
  />
6799
7257
  </div>
@@ -6806,7 +7264,7 @@ function LoginScreen({ onLogin, error }) {
6806
7264
  </div>
6807
7265
  )}
6808
7266
 
6809
- <button type="submit" disabled={loading || !email.trim() || !password.trim()} className="btn-terminal w-full py-3 flex items-center justify-center gap-2 disabled:opacity-50">
7267
+ <button type="submit" disabled={loading || !email.trim() || !password.trim()} className="theme-btn-primary w-full py-3 flex items-center justify-center gap-2 disabled:opacity-50">
6810
7268
  {loading ? (
6811
7269
  <>
6812
7270
  <Loader2 className="w-4 h-4 animate-spin" />
@@ -6968,11 +7426,13 @@ Update \`roadmap.json\` with:
6968
7426
  // Wrap App with providers
6969
7427
  function AppWithProviders() {
6970
7428
  return (
6971
- <ToastProvider>
6972
- <ActivityProvider>
6973
- <App />
6974
- </ActivityProvider>
6975
- </ToastProvider>
7429
+ <ThemeProvider>
7430
+ <ToastProvider>
7431
+ <ActivityProvider>
7432
+ <App />
7433
+ </ActivityProvider>
7434
+ </ToastProvider>
7435
+ </ThemeProvider>
6976
7436
  );
6977
7437
  }
6978
7438