git-history-ui 1.0.0

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.
Files changed (64) hide show
  1. package/.eslintrc.js +21 -0
  2. package/README.md +304 -0
  3. package/demo.js +45 -0
  4. package/dist/__tests__/gitService.test.d.ts +2 -0
  5. package/dist/__tests__/gitService.test.d.ts.map +1 -0
  6. package/dist/__tests__/gitService.test.js +32 -0
  7. package/dist/__tests__/gitService.test.js.map +1 -0
  8. package/dist/backend/dev-server.d.ts +2 -0
  9. package/dist/backend/dev-server.d.ts.map +1 -0
  10. package/dist/backend/dev-server.js +16 -0
  11. package/dist/backend/dev-server.js.map +1 -0
  12. package/dist/backend/gitService.d.ts +45 -0
  13. package/dist/backend/gitService.d.ts.map +1 -0
  14. package/dist/backend/gitService.js +239 -0
  15. package/dist/backend/gitService.js.map +1 -0
  16. package/dist/backend/server.d.ts +9 -0
  17. package/dist/backend/server.d.ts.map +1 -0
  18. package/dist/backend/server.js +118 -0
  19. package/dist/backend/server.js.map +1 -0
  20. package/dist/cli.d.ts +3 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +49 -0
  23. package/dist/cli.js.map +1 -0
  24. package/frontend/.editorconfig +17 -0
  25. package/frontend/.vscode/extensions.json +4 -0
  26. package/frontend/.vscode/launch.json +20 -0
  27. package/frontend/.vscode/tasks.json +42 -0
  28. package/frontend/README.md +59 -0
  29. package/frontend/angular.json +99 -0
  30. package/frontend/package-lock.json +10566 -0
  31. package/frontend/package.json +55 -0
  32. package/frontend/proxy.conf.json +7 -0
  33. package/frontend/public/favicon.ico +0 -0
  34. package/frontend/src/app/app.component.ts +598 -0
  35. package/frontend/src/app/app.config.ts +12 -0
  36. package/frontend/src/app/app.css +0 -0
  37. package/frontend/src/app/app.html +342 -0
  38. package/frontend/src/app/app.routes.ts +3 -0
  39. package/frontend/src/app/app.spec.ts +23 -0
  40. package/frontend/src/app/app.ts +12 -0
  41. package/frontend/src/app/components/color-palette-selector/color-palette-selector.component.ts +137 -0
  42. package/frontend/src/app/components/commit-detail/commit-detail.component.ts +327 -0
  43. package/frontend/src/app/components/commit-graph/commit-graph.component.ts +294 -0
  44. package/frontend/src/app/components/commit-list/commit-list.component.ts +199 -0
  45. package/frontend/src/app/components/diff-viewer/diff-viewer.component.ts +311 -0
  46. package/frontend/src/app/models/color-palette.models.ts +229 -0
  47. package/frontend/src/app/models/git.models.ts +39 -0
  48. package/frontend/src/app/services/git.service.ts +43 -0
  49. package/frontend/src/index.html +13 -0
  50. package/frontend/src/main.ts +6 -0
  51. package/frontend/src/styles.css +397 -0
  52. package/frontend/tsconfig.app.json +15 -0
  53. package/frontend/tsconfig.json +34 -0
  54. package/frontend/tsconfig.spec.json +14 -0
  55. package/jest.config.js +13 -0
  56. package/package.json +70 -0
  57. package/public/app.js +403 -0
  58. package/public/index.html +172 -0
  59. package/src/__tests__/gitService.test.ts +35 -0
  60. package/src/backend/dev-server.ts +14 -0
  61. package/src/backend/gitService.ts +277 -0
  62. package/src/backend/server.ts +132 -0
  63. package/src/cli.ts +56 -0
  64. package/tsconfig.json +25 -0
@@ -0,0 +1,229 @@
1
+ export interface ColorPalette {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ colors: {
6
+ primary: string;
7
+ secondary: string;
8
+ accent: string;
9
+ background: string;
10
+ text: string;
11
+ border: string;
12
+ link: string;
13
+ nodeFill: string;
14
+ nodeStroke: string;
15
+ graphText: string;
16
+ };
17
+ }
18
+
19
+ export type ColorPaletteId = 'default' | 'ocean' | 'forest' | 'sunset' | 'monochrome' | 'neon';
20
+
21
+ export const COLOR_PALETTES: Record<ColorPaletteId, ColorPalette> = {
22
+ default: {
23
+ id: 'default',
24
+ name: 'Default',
25
+ description: 'Classic blue theme',
26
+ colors: {
27
+ primary: '#3b82f6',
28
+ secondary: '#6b7280',
29
+ accent: '#1e40af',
30
+ background: '#ffffff',
31
+ text: '#111827',
32
+ border: '#e5e7eb',
33
+ link: '#cbd5e0',
34
+ nodeFill: '#3b82f6',
35
+ nodeStroke: '#1e40af',
36
+ graphText: '#6b7280'
37
+ }
38
+ },
39
+ ocean: {
40
+ id: 'ocean',
41
+ name: 'Ocean',
42
+ description: 'Deep blue ocean theme',
43
+ colors: {
44
+ primary: '#0ea5e9',
45
+ secondary: '#64748b',
46
+ accent: '#0369a1',
47
+ background: '#ffffff',
48
+ text: '#0f172a',
49
+ border: '#e2e8f0',
50
+ link: '#94a3b8',
51
+ nodeFill: '#0ea5e9',
52
+ nodeStroke: '#0369a1',
53
+ graphText: '#475569'
54
+ }
55
+ },
56
+ forest: {
57
+ id: 'forest',
58
+ name: 'Forest',
59
+ description: 'Green nature theme',
60
+ colors: {
61
+ primary: '#10b981',
62
+ secondary: '#6b7280',
63
+ accent: '#059669',
64
+ background: '#ffffff',
65
+ text: '#111827',
66
+ border: '#e5e7eb',
67
+ link: '#d1fae5',
68
+ nodeFill: '#10b981',
69
+ nodeStroke: '#059669',
70
+ graphText: '#6b7280'
71
+ }
72
+ },
73
+ sunset: {
74
+ id: 'sunset',
75
+ name: 'Sunset',
76
+ description: 'Warm orange theme',
77
+ colors: {
78
+ primary: '#f59e0b',
79
+ secondary: '#6b7280',
80
+ accent: '#d97706',
81
+ background: '#ffffff',
82
+ text: '#111827',
83
+ border: '#e5e7eb',
84
+ link: '#fed7aa',
85
+ nodeFill: '#f59e0b',
86
+ nodeStroke: '#d97706',
87
+ graphText: '#6b7280'
88
+ }
89
+ },
90
+ monochrome: {
91
+ id: 'monochrome',
92
+ name: 'Monochrome',
93
+ description: 'Black and white theme',
94
+ colors: {
95
+ primary: '#374151',
96
+ secondary: '#6b7280',
97
+ accent: '#111827',
98
+ background: '#ffffff',
99
+ text: '#111827',
100
+ border: '#e5e7eb',
101
+ link: '#d1d5db',
102
+ nodeFill: '#374151',
103
+ nodeStroke: '#111827',
104
+ graphText: '#6b7280'
105
+ }
106
+ },
107
+ neon: {
108
+ id: 'neon',
109
+ name: 'Neon',
110
+ description: 'Bright neon theme',
111
+ colors: {
112
+ primary: '#ec4899',
113
+ secondary: '#8b5cf6',
114
+ accent: '#06b6d4',
115
+ background: '#ffffff',
116
+ text: '#111827',
117
+ border: '#e5e7eb',
118
+ link: '#f0abfc',
119
+ nodeFill: '#ec4899',
120
+ nodeStroke: '#be185d',
121
+ graphText: '#6b7280'
122
+ }
123
+ }
124
+ };
125
+
126
+ export const DARK_COLOR_PALETTES: Record<ColorPaletteId, ColorPalette> = {
127
+ default: {
128
+ id: 'default',
129
+ name: 'Default Dark',
130
+ description: 'Classic dark theme',
131
+ colors: {
132
+ primary: '#3b82f6',
133
+ secondary: '#6b7280',
134
+ accent: '#1e40af',
135
+ background: '#1a1a1a',
136
+ text: '#e0e0e0',
137
+ border: '#404040',
138
+ link: '#4b5563',
139
+ nodeFill: '#3b82f6',
140
+ nodeStroke: '#1e40af',
141
+ graphText: '#9ca3af'
142
+ }
143
+ },
144
+ ocean: {
145
+ id: 'ocean',
146
+ name: 'Ocean Dark',
147
+ description: 'Deep ocean dark theme',
148
+ colors: {
149
+ primary: '#0ea5e9',
150
+ secondary: '#64748b',
151
+ accent: '#0369a1',
152
+ background: '#0f172a',
153
+ text: '#f1f5f9',
154
+ border: '#334155',
155
+ link: '#475569',
156
+ nodeFill: '#0ea5e9',
157
+ nodeStroke: '#0369a1',
158
+ graphText: '#94a3b8'
159
+ }
160
+ },
161
+ forest: {
162
+ id: 'forest',
163
+ name: 'Forest Dark',
164
+ description: 'Dark green theme',
165
+ colors: {
166
+ primary: '#10b981',
167
+ secondary: '#6b7280',
168
+ accent: '#059669',
169
+ background: '#064e3b',
170
+ text: '#ecfdf5',
171
+ border: '#065f46',
172
+ link: '#065f46',
173
+ nodeFill: '#10b981',
174
+ nodeStroke: '#059669',
175
+ graphText: '#6ee7b7'
176
+ }
177
+ },
178
+ sunset: {
179
+ id: 'sunset',
180
+ name: 'Sunset Dark',
181
+ description: 'Dark orange theme',
182
+ colors: {
183
+ primary: '#f59e0b',
184
+ secondary: '#6b7280',
185
+ accent: '#d97706',
186
+ background: '#451a03',
187
+ text: '#fef3c7',
188
+ border: '#92400e',
189
+ link: '#92400e',
190
+ nodeFill: '#f59e0b',
191
+ nodeStroke: '#d97706',
192
+ graphText: '#fbbf24'
193
+ }
194
+ },
195
+ monochrome: {
196
+ id: 'monochrome',
197
+ name: 'Monochrome Dark',
198
+ description: 'Pure black and white',
199
+ colors: {
200
+ primary: '#e5e7eb',
201
+ secondary: '#9ca3af',
202
+ accent: '#f9fafb',
203
+ background: '#000000',
204
+ text: '#ffffff',
205
+ border: '#374151',
206
+ link: '#4b5563',
207
+ nodeFill: '#e5e7eb',
208
+ nodeStroke: '#f9fafb',
209
+ graphText: '#9ca3af'
210
+ }
211
+ },
212
+ neon: {
213
+ id: 'neon',
214
+ name: 'Neon Dark',
215
+ description: 'Bright neon on dark',
216
+ colors: {
217
+ primary: '#ec4899',
218
+ secondary: '#8b5cf6',
219
+ accent: '#06b6d4',
220
+ background: '#0f0f23',
221
+ text: '#ffffff',
222
+ border: '#312e81',
223
+ link: '#581c87',
224
+ nodeFill: '#ec4899',
225
+ nodeStroke: '#be185d',
226
+ graphText: '#f0abfc'
227
+ }
228
+ }
229
+ };
@@ -0,0 +1,39 @@
1
+ export interface Commit {
2
+ hash: string;
3
+ author: string;
4
+ date: string;
5
+ message: string;
6
+ files: string[];
7
+ parents: string[];
8
+ branches: string[];
9
+ tags: string[];
10
+ }
11
+
12
+ export interface DiffFile {
13
+ file: string;
14
+ additions: number;
15
+ deletions: number;
16
+ changes: string;
17
+ }
18
+
19
+ export interface BlameLine {
20
+ line: number;
21
+ hash: string;
22
+ author: string;
23
+ date: string;
24
+ content: string;
25
+ }
26
+
27
+ export interface GitOptions {
28
+ file?: string;
29
+ since?: string;
30
+ author?: string;
31
+ limit?: number;
32
+ }
33
+
34
+ export interface CommitNode {
35
+ id: string;
36
+ x: number;
37
+ y: number;
38
+ commit: Commit;
39
+ }
@@ -0,0 +1,43 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { HttpClient } from '@angular/common/http';
3
+ import { Observable } from 'rxjs';
4
+ import { Commit, DiffFile, BlameLine, GitOptions } from '../models/git.models';
5
+
6
+ @Injectable({
7
+ providedIn: 'root'
8
+ })
9
+ export class GitService {
10
+ private apiUrl = '/api';
11
+
12
+ constructor(private http: HttpClient) { }
13
+
14
+ getCommits(options: GitOptions = {}): Observable<Commit[]> {
15
+ const params = new URLSearchParams();
16
+ if (options.file) params.set('file', options.file);
17
+ if (options.since) params.set('since', options.since);
18
+ if (options.author) params.set('author', options.author);
19
+ if (options.limit) params.set('limit', options.limit.toString());
20
+
21
+ return this.http.get<Commit[]>(`${this.apiUrl}/commits?${params.toString()}`);
22
+ }
23
+
24
+ getCommit(hash: string): Observable<Commit> {
25
+ return this.http.get<Commit>(`${this.apiUrl}/commit/${hash}`);
26
+ }
27
+
28
+ getDiff(hash: string): Observable<DiffFile[]> {
29
+ return this.http.get<DiffFile[]>(`${this.apiUrl}/diff/${hash}`);
30
+ }
31
+
32
+ getBlame(filePath: string): Observable<BlameLine[]> {
33
+ return this.http.get<BlameLine[]>(`${this.apiUrl}/blame/${encodeURIComponent(filePath)}`);
34
+ }
35
+
36
+ getTags(): Observable<string[]> {
37
+ return this.http.get<string[]>(`${this.apiUrl}/tags`);
38
+ }
39
+
40
+ getBranches(): Observable<string[]> {
41
+ return this.http.get<string[]>(`${this.apiUrl}/branches`);
42
+ }
43
+ }
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Frontend</title>
6
+ <base href="/">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1">
8
+ <link rel="icon" type="image/x-icon" href="favicon.ico">
9
+ </head>
10
+ <body>
11
+ <app-root></app-root>
12
+ </body>
13
+ </html>
@@ -0,0 +1,6 @@
1
+ import { bootstrapApplication } from '@angular/platform-browser';
2
+ import { appConfig } from './app/app.config';
3
+ import { AppComponent } from './app/app.component';
4
+
5
+ bootstrapApplication(AppComponent, appConfig)
6
+ .catch((err) => console.error(err));
@@ -0,0 +1,397 @@
1
+ /* You can add global styles to this file, and also import other style files */
2
+
3
+ /* Modern CSS Reset */
4
+ * {
5
+ margin: 0;
6
+ padding: 0;
7
+ box-sizing: border-box;
8
+ }
9
+
10
+ /* Base styles */
11
+ body {
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ line-height: 1.6;
14
+ color: #333;
15
+ background-color: #f8f9fa;
16
+ }
17
+
18
+ /* Dark mode support */
19
+ @media (prefers-color-scheme: dark) {
20
+ body {
21
+ background-color: #1a1a1a;
22
+ color: #e0e0e0;
23
+ }
24
+ }
25
+
26
+ /* Manual dark mode toggle */
27
+ .dark {
28
+ background-color: #1a1a1a !important;
29
+ color: #e0e0e0 !important;
30
+ }
31
+
32
+ .dark body {
33
+ background-color: #1a1a1a !important;
34
+ color: #e0e0e0 !important;
35
+ }
36
+
37
+ .dark * {
38
+ border-color: #404040 !important;
39
+ }
40
+
41
+ .dark .app-container {
42
+ background-color: #1a1a1a;
43
+ color: #e0e0e0;
44
+ }
45
+
46
+ .dark .header {
47
+ background-color: #2d2d2d;
48
+ border-bottom-color: #404040;
49
+ }
50
+
51
+ .dark .app-title {
52
+ color: #e0e0e0;
53
+ }
54
+
55
+ .dark .search-input {
56
+ background-color: #404040;
57
+ color: #e0e0e0;
58
+ border-color: #555;
59
+ }
60
+
61
+ .dark .search-input::placeholder {
62
+ color: #9ca3af;
63
+ }
64
+
65
+ .dark .filters {
66
+ background-color: #2d2d2d;
67
+ border-bottom-color: #404040;
68
+ }
69
+
70
+ .dark .filter-select,
71
+ .dark .filter-input {
72
+ background-color: #404040;
73
+ color: #e0e0e0;
74
+ border-color: #555;
75
+ }
76
+
77
+ .dark .main-content {
78
+ background-color: #1a1a1a;
79
+ }
80
+
81
+ .dark .commit-item {
82
+ background-color: #2d2d2d;
83
+ border-color: #404040;
84
+ }
85
+
86
+ .dark .commit-hash {
87
+ color: #9ca3af;
88
+ }
89
+
90
+ .dark .commit-author {
91
+ color: #d1d5db;
92
+ }
93
+
94
+ .dark .commit-date {
95
+ color: #9ca3af;
96
+ }
97
+
98
+ .dark .commit-message {
99
+ color: #e0e0e0;
100
+ }
101
+
102
+ /* Date picker dark mode support */
103
+ .dark input[type="date"] {
104
+ background-color: #404040 !important;
105
+ color: #e0e0e0 !important;
106
+ border-color: #555 !important;
107
+ }
108
+
109
+ .dark .date-picker {
110
+ background-color: #404040 !important;
111
+ color: #e0e0e0 !important;
112
+ border-color: #555 !important;
113
+ }
114
+
115
+ .dark .filter-input.date-picker {
116
+ background-color: #404040 !important;
117
+ color: #e0e0e0 !important;
118
+ border-color: #555 !important;
119
+ }
120
+
121
+ .dark input[type="date"]::-webkit-calendar-picker-indicator {
122
+ filter: invert(1) !important;
123
+ }
124
+
125
+ .dark input[type="date"]::-webkit-datetime-edit {
126
+ color: #e0e0e0 !important;
127
+ }
128
+
129
+ .dark input[type="date"]::-webkit-datetime-edit-fields-wrapper {
130
+ color: #e0e0e0 !important;
131
+ }
132
+
133
+ .dark input[type="date"]::-webkit-datetime-edit-text {
134
+ color: #e0e0e0 !important;
135
+ }
136
+
137
+ .dark input[type="date"]::-webkit-datetime-edit-month-field,
138
+ .dark input[type="date"]::-webkit-datetime-edit-day-field,
139
+ .dark input[type="date"]::-webkit-datetime-edit-year-field {
140
+ color: #e0e0e0 !important;
141
+ }
142
+
143
+ .dark .loading {
144
+ color: #e0e0e0;
145
+ }
146
+
147
+ /* Graph container dark mode */
148
+ .dark .graph-container {
149
+ background-color: #2d2d2d !important;
150
+ color: #e0e0e0 !important;
151
+ }
152
+
153
+ /* SVG dark mode support */
154
+ .dark svg {
155
+ background-color: transparent !important;
156
+ }
157
+
158
+ /* Modal dark mode support */
159
+ .dark .modal-title,
160
+ .dark .modal-header .modal-title,
161
+ .dark .modal-container .modal-title {
162
+ color: #e0e0e0 !important;
163
+ }
164
+
165
+ /* Header dark mode support */
166
+ .dark .header {
167
+ background-color: #2d2d2d !important;
168
+ border-bottom-color: #404040 !important;
169
+ }
170
+
171
+ .dark .app-title {
172
+ color: #e0e0e0 !important;
173
+ }
174
+
175
+ .dark .filters {
176
+ background-color: #2d2d2d !important;
177
+ border-bottom-color: #404040 !important;
178
+ }
179
+
180
+ /* Input placeholder dark mode */
181
+ .dark input::placeholder {
182
+ color: #9ca3af !important;
183
+ }
184
+
185
+ .dark select {
186
+ color: #e0e0e0 !important;
187
+ }
188
+
189
+ /* Ensure all elements transition smoothly */
190
+ * {
191
+ transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
192
+ }
193
+
194
+ /* Specific transitions for form elements */
195
+ input, select, button {
196
+ transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
197
+ }
198
+
199
+ /* Additional dark mode styles for cards and other elements */
200
+ .dark .card,
201
+ .dark .commit-item,
202
+ .dark .modal-container,
203
+ .dark .diff-viewer {
204
+ background-color: #2d2d2d !important;
205
+ color: #e0e0e0 !important;
206
+ border-color: #404040 !important;
207
+ }
208
+
209
+ .dark .btn {
210
+ background-color: #404040 !important;
211
+ color: #e0e0e0 !important;
212
+ border-color: #555 !important;
213
+ }
214
+
215
+ .dark .btn:hover {
216
+ background-color: #555 !important;
217
+ }
218
+
219
+ .dark .btn-primary {
220
+ background-color: #3b82f6 !important;
221
+ color: white !important;
222
+ }
223
+
224
+ .dark .btn-primary:hover {
225
+ background-color: #2563eb !important;
226
+ }
227
+
228
+ .dark .btn-secondary {
229
+ background-color: #6b7280 !important;
230
+ color: white !important;
231
+ }
232
+
233
+ .dark .btn-secondary:hover {
234
+ background-color: #4b5563 !important;
235
+ }
236
+
237
+ .dark .file-item,
238
+ .dark .diff-item {
239
+ background-color: #404040 !important;
240
+ border-color: #555 !important;
241
+ }
242
+
243
+ .dark .section-title {
244
+ color: #e0e0e0 !important;
245
+ }
246
+
247
+ .dark .commit-meta,
248
+ .dark .commit-info {
249
+ color: #e0e0e0 !important;
250
+ }
251
+
252
+ .dark .commit-hash {
253
+ color: #9ca3af !important;
254
+ }
255
+
256
+ .dark .commit-author {
257
+ color: #d1d5db !important;
258
+ }
259
+
260
+ .dark .commit-date {
261
+ color: #9ca3af !important;
262
+ }
263
+
264
+ .dark .commit-message {
265
+ color: #e0e0e0 !important;
266
+ }
267
+
268
+ .dark .file-name,
269
+ .dark .diff-file-name {
270
+ color: #d1d5db !important;
271
+ }
272
+
273
+ .dark .diff-stats {
274
+ color: #9ca3af !important;
275
+ }
276
+
277
+ /* Utility classes */
278
+ .container {
279
+ max-width: 1200px;
280
+ margin: 0 auto;
281
+ padding: 0 1rem;
282
+ }
283
+
284
+ .flex {
285
+ display: flex;
286
+ }
287
+
288
+ .flex-col {
289
+ flex-direction: column;
290
+ }
291
+
292
+ .items-center {
293
+ align-items: center;
294
+ }
295
+
296
+ .justify-between {
297
+ justify-content: space-between;
298
+ }
299
+
300
+ .space-x-4 > * + * {
301
+ margin-left: 1rem;
302
+ }
303
+
304
+ .space-y-4 > * + * {
305
+ margin-top: 1rem;
306
+ }
307
+
308
+ /* Button styles */
309
+ .btn {
310
+ padding: 0.5rem 1rem;
311
+ border: none;
312
+ border-radius: 0.375rem;
313
+ cursor: pointer;
314
+ font-size: 0.875rem;
315
+ transition: all 0.2s;
316
+ margin-right: 0.5rem;
317
+ }
318
+
319
+ .btn:last-child {
320
+ margin-right: 0;
321
+ }
322
+
323
+ /* Button container spacing */
324
+ .flex.items-center {
325
+ gap: 0.5rem;
326
+ }
327
+
328
+ .btn-primary {
329
+ background-color: #3b82f6;
330
+ color: white;
331
+ }
332
+
333
+ .btn-primary:hover {
334
+ background-color: #2563eb;
335
+ }
336
+
337
+ .btn-secondary {
338
+ background-color: #6b7280;
339
+ color: white;
340
+ }
341
+
342
+ .btn-secondary:hover {
343
+ background-color: #4b5563;
344
+ }
345
+
346
+ /* Card styles */
347
+ .card {
348
+ background-color: white;
349
+ border-radius: 0.5rem;
350
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
351
+ padding: 1.5rem;
352
+ }
353
+
354
+ .dark .card {
355
+ background-color: #2d2d2d;
356
+ color: #e0e0e0;
357
+ }
358
+
359
+ /* Custom styles for git history UI */
360
+ .commit-node {
361
+ cursor: pointer;
362
+ transition: all 0.2s ease;
363
+ }
364
+
365
+ .commit-node:hover {
366
+ stroke-width: 3px;
367
+ }
368
+
369
+ .branch-line {
370
+ stroke-width: 2px;
371
+ }
372
+
373
+ .diff-line {
374
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
375
+ font-size: 12px;
376
+ line-height: 1.4;
377
+ }
378
+
379
+ .diff-line.added {
380
+ background-color: #dcfce7;
381
+ color: #166534;
382
+ }
383
+
384
+ .diff-line.removed {
385
+ background-color: #fee2e2;
386
+ color: #991b1b;
387
+ }
388
+
389
+ .dark .diff-line.added {
390
+ background-color: #14532d;
391
+ color: #bbf7d0;
392
+ }
393
+
394
+ .dark .diff-line.removed {
395
+ background-color: #7f1d1d;
396
+ color: #fecaca;
397
+ }