mcp-vector-search 1.0.3__py3-none-any.whl → 1.1.22__py3-none-any.whl

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 (63) hide show
  1. mcp_vector_search/__init__.py +3 -3
  2. mcp_vector_search/analysis/__init__.py +48 -1
  3. mcp_vector_search/analysis/baseline/__init__.py +68 -0
  4. mcp_vector_search/analysis/baseline/comparator.py +462 -0
  5. mcp_vector_search/analysis/baseline/manager.py +621 -0
  6. mcp_vector_search/analysis/collectors/__init__.py +35 -0
  7. mcp_vector_search/analysis/collectors/cohesion.py +463 -0
  8. mcp_vector_search/analysis/collectors/coupling.py +1162 -0
  9. mcp_vector_search/analysis/collectors/halstead.py +514 -0
  10. mcp_vector_search/analysis/collectors/smells.py +325 -0
  11. mcp_vector_search/analysis/debt.py +516 -0
  12. mcp_vector_search/analysis/interpretation.py +685 -0
  13. mcp_vector_search/analysis/metrics.py +74 -1
  14. mcp_vector_search/analysis/reporters/__init__.py +3 -1
  15. mcp_vector_search/analysis/reporters/console.py +424 -0
  16. mcp_vector_search/analysis/reporters/markdown.py +480 -0
  17. mcp_vector_search/analysis/reporters/sarif.py +377 -0
  18. mcp_vector_search/analysis/storage/__init__.py +93 -0
  19. mcp_vector_search/analysis/storage/metrics_store.py +762 -0
  20. mcp_vector_search/analysis/storage/schema.py +245 -0
  21. mcp_vector_search/analysis/storage/trend_tracker.py +560 -0
  22. mcp_vector_search/analysis/trends.py +308 -0
  23. mcp_vector_search/analysis/visualizer/__init__.py +90 -0
  24. mcp_vector_search/analysis/visualizer/d3_data.py +534 -0
  25. mcp_vector_search/analysis/visualizer/exporter.py +484 -0
  26. mcp_vector_search/analysis/visualizer/html_report.py +2895 -0
  27. mcp_vector_search/analysis/visualizer/schemas.py +525 -0
  28. mcp_vector_search/cli/commands/analyze.py +665 -11
  29. mcp_vector_search/cli/commands/chat.py +193 -0
  30. mcp_vector_search/cli/commands/index.py +600 -2
  31. mcp_vector_search/cli/commands/index_background.py +467 -0
  32. mcp_vector_search/cli/commands/search.py +194 -1
  33. mcp_vector_search/cli/commands/setup.py +64 -13
  34. mcp_vector_search/cli/commands/status.py +302 -3
  35. mcp_vector_search/cli/commands/visualize/cli.py +26 -10
  36. mcp_vector_search/cli/commands/visualize/exporters/json_exporter.py +8 -4
  37. mcp_vector_search/cli/commands/visualize/graph_builder.py +167 -234
  38. mcp_vector_search/cli/commands/visualize/server.py +304 -15
  39. mcp_vector_search/cli/commands/visualize/templates/base.py +60 -6
  40. mcp_vector_search/cli/commands/visualize/templates/scripts.py +2100 -65
  41. mcp_vector_search/cli/commands/visualize/templates/styles.py +1297 -88
  42. mcp_vector_search/cli/didyoumean.py +5 -0
  43. mcp_vector_search/cli/main.py +16 -5
  44. mcp_vector_search/cli/output.py +134 -5
  45. mcp_vector_search/config/thresholds.py +89 -1
  46. mcp_vector_search/core/__init__.py +16 -0
  47. mcp_vector_search/core/database.py +39 -2
  48. mcp_vector_search/core/embeddings.py +24 -0
  49. mcp_vector_search/core/git.py +380 -0
  50. mcp_vector_search/core/indexer.py +445 -84
  51. mcp_vector_search/core/llm_client.py +9 -4
  52. mcp_vector_search/core/models.py +88 -1
  53. mcp_vector_search/core/relationships.py +473 -0
  54. mcp_vector_search/core/search.py +1 -1
  55. mcp_vector_search/mcp/server.py +795 -4
  56. mcp_vector_search/parsers/python.py +285 -5
  57. mcp_vector_search/utils/gitignore.py +0 -3
  58. {mcp_vector_search-1.0.3.dist-info → mcp_vector_search-1.1.22.dist-info}/METADATA +3 -2
  59. {mcp_vector_search-1.0.3.dist-info → mcp_vector_search-1.1.22.dist-info}/RECORD +62 -39
  60. mcp_vector_search/cli/commands/visualize.py.original +0 -2536
  61. {mcp_vector_search-1.0.3.dist-info → mcp_vector_search-1.1.22.dist-info}/WHEEL +0 -0
  62. {mcp_vector_search-1.0.3.dist-info → mcp_vector_search-1.1.22.dist-info}/entry_points.txt +0 -0
  63. {mcp_vector_search-1.0.3.dist-info → mcp_vector_search-1.1.22.dist-info}/licenses/LICENSE +0 -0
@@ -12,16 +12,63 @@ def get_base_styles() -> str:
12
12
  CSS string for base styling
13
13
  """
14
14
  return """
15
+ /* CSS Variables for Theme Support */
16
+ :root {
17
+ --bg-primary: #0d1117;
18
+ --bg-secondary: #161b22;
19
+ --bg-tertiary: #21262d;
20
+ --text-primary: #c9d1d9;
21
+ --text-secondary: #8b949e;
22
+ --text-tertiary: #6e7681;
23
+ --border-primary: #30363d;
24
+ --border-secondary: #21262d;
25
+ --accent: #58a6ff;
26
+ --accent-hover: #79c0ff;
27
+ --success: #238636;
28
+ --warning: #d29922;
29
+ --error: #da3633;
30
+ --shadow: rgba(0, 0, 0, 0.4);
31
+ }
32
+
33
+ [data-theme="light"] {
34
+ --bg-primary: #ffffff;
35
+ --bg-secondary: #f6f8fa;
36
+ --bg-tertiary: #eaeef2;
37
+ --text-primary: #24292f;
38
+ --text-secondary: #57606a;
39
+ --text-tertiary: #6e7781;
40
+ --border-primary: #d0d7de;
41
+ --border-secondary: #d8dee4;
42
+ --accent: #0969da;
43
+ --accent-hover: #0550ae;
44
+ --success: #1a7f37;
45
+ --warning: #9a6700;
46
+ --error: #cf222e;
47
+ --shadow: rgba(31, 35, 40, 0.15);
48
+ }
49
+
15
50
  body {
16
51
  margin: 0;
17
52
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
18
- background: #0d1117;
19
- color: #c9d1d9;
53
+ background: var(--bg-primary);
54
+ color: var(--text-primary);
20
55
  overflow: hidden;
56
+ transition: background-color 0.3s ease, color 0.3s ease;
21
57
  }
22
58
 
23
- h1 { margin: 0 0 16px 0; font-size: 18px; }
24
- h3 { margin: 16px 0 8px 0; font-size: 14px; color: #8b949e; }
59
+ h1 { margin: 0 0 4px 0; font-size: 18px; color: var(--text-primary); }
60
+ h3 { margin: 16px 0 8px 0; font-size: 14px; color: var(--text-secondary); }
61
+
62
+ .version-badge {
63
+ font-size: 10px;
64
+ color: var(--text-tertiary);
65
+ margin-bottom: 16px;
66
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
67
+ padding: 2px 6px;
68
+ background: var(--bg-tertiary);
69
+ border-radius: 4px;
70
+ display: inline-block;
71
+ }
25
72
  """
26
73
 
27
74
 
@@ -36,15 +83,16 @@ def get_controls_styles() -> str:
36
83
  position: absolute;
37
84
  top: 20px;
38
85
  left: 20px;
39
- background: rgba(13, 17, 23, 0.95);
40
- border: 1px solid #30363d;
86
+ background: var(--bg-primary);
87
+ border: 1px solid var(--border-primary);
41
88
  border-radius: 6px;
42
89
  padding: 16px;
43
90
  min-width: 250px;
44
91
  max-height: 80vh;
45
92
  overflow-y: auto;
46
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
93
+ box-shadow: 0 8px 24px var(--shadow);
47
94
  z-index: 500;
95
+ transition: background-color 0.3s ease, border-color 0.3s ease;
48
96
  }
49
97
 
50
98
  .control-group {
@@ -55,34 +103,34 @@ def get_controls_styles() -> str:
55
103
  display: block;
56
104
  margin-bottom: 4px;
57
105
  font-size: 12px;
58
- color: #8b949e;
106
+ color: var(--text-secondary);
59
107
  }
60
108
 
61
109
  input[type="file"] {
62
110
  width: 100%;
63
111
  padding: 6px;
64
- background: #161b22;
65
- border: 1px solid #30363d;
112
+ background: var(--bg-secondary);
113
+ border: 1px solid var(--border-primary);
66
114
  border-radius: 6px;
67
- color: #c9d1d9;
115
+ color: var(--text-primary);
68
116
  font-size: 12px;
69
117
  }
70
118
 
71
119
  .legend {
72
- background: #161b22;
73
- border: 1px solid #30363d;
120
+ background: var(--bg-secondary);
121
+ border: 1px solid var(--border-primary);
74
122
  border-radius: 6px;
75
123
  padding: 12px;
76
124
  font-size: 13px;
77
125
  max-width: 300px;
78
126
  margin-top: 16px;
79
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
127
+ box-shadow: 0 8px 24px var(--shadow);
80
128
  }
81
129
 
82
130
  .legend-category {
83
131
  margin-bottom: 12px;
84
132
  padding-bottom: 8px;
85
- border-bottom: 1px solid #21262d;
133
+ border-bottom: 1px solid var(--border-secondary);
86
134
  }
87
135
 
88
136
  .legend-category:last-child {
@@ -93,7 +141,7 @@ def get_controls_styles() -> str:
93
141
 
94
142
  .legend-title {
95
143
  font-weight: 600;
96
- color: #c9d1d9;
144
+ color: var(--text-primary);
97
145
  margin-bottom: 8px;
98
146
  font-size: 12px;
99
147
  text-transform: uppercase;
@@ -118,12 +166,39 @@ def get_controls_styles() -> str:
118
166
  margin-right: 8px;
119
167
  }
120
168
 
169
+ /* Report buttons in sidebar */
170
+ .report-btn {
171
+ cursor: pointer;
172
+ padding: 10px 12px !important;
173
+ background: var(--bg-tertiary);
174
+ border: 1px solid var(--border-primary);
175
+ border-radius: 6px;
176
+ margin-bottom: 8px !important;
177
+ transition: all 0.2s ease;
178
+ }
179
+
180
+ .report-btn:hover {
181
+ background: var(--accent);
182
+ border-color: var(--accent);
183
+ color: white;
184
+ transform: translateX(4px);
185
+ }
186
+
187
+ .report-btn:hover span {
188
+ color: white !important;
189
+ }
190
+
191
+ .report-icon {
192
+ margin-right: 10px;
193
+ font-size: 16px;
194
+ }
195
+
121
196
  .stats {
122
197
  margin-top: 16px;
123
198
  padding-top: 16px;
124
- border-top: 1px solid #30363d;
199
+ border-top: 1px solid var(--border-primary);
125
200
  font-size: 12px;
126
- color: #8b949e;
201
+ color: var(--text-secondary);
127
202
  }
128
203
 
129
204
  .toggle-switch-container {
@@ -132,20 +207,20 @@ def get_controls_styles() -> str:
132
207
  justify-content: center;
133
208
  gap: 12px;
134
209
  padding: 10px;
135
- background: #161b22;
136
- border: 1px solid #30363d;
210
+ background: var(--bg-secondary);
211
+ border: 1px solid var(--border-primary);
137
212
  border-radius: 6px;
138
213
  }
139
214
 
140
215
  .toggle-label {
141
216
  font-size: 13px;
142
- color: #8b949e;
217
+ color: var(--text-secondary);
143
218
  font-weight: 500;
144
219
  transition: color 0.2s ease;
145
220
  }
146
221
 
147
222
  .toggle-label.active {
148
- color: #58a6ff;
223
+ color: var(--accent);
149
224
  }
150
225
 
151
226
  .toggle-switch {
@@ -174,10 +249,10 @@ def get_controls_styles() -> str:
174
249
  left: 0;
175
250
  right: 0;
176
251
  bottom: 0;
177
- background-color: #30363d;
252
+ background-color: var(--border-primary);
178
253
  transition: 0.3s;
179
254
  border-radius: 24px;
180
- border: 1px solid #30363d;
255
+ border: 1px solid var(--border-primary);
181
256
  }
182
257
 
183
258
  .toggle-slider:before {
@@ -187,27 +262,64 @@ def get_controls_styles() -> str:
187
262
  width: 16px;
188
263
  left: 3px;
189
264
  bottom: 3px;
190
- background-color: #8b949e;
265
+ background-color: var(--text-secondary);
191
266
  transition: 0.3s;
192
267
  border-radius: 50%;
193
268
  }
194
269
 
195
270
  .toggle-switch input:checked + .toggle-slider {
196
- background-color: #238636;
197
- border-color: #2ea043;
271
+ background-color: var(--success);
272
+ border-color: var(--success);
198
273
  }
199
274
 
200
275
  .toggle-switch input:checked + .toggle-slider:before {
201
276
  transform: translateX(24px);
202
- background-color: #ffffff;
277
+ background-color: var(--bg-primary);
203
278
  }
204
279
 
205
280
  .toggle-slider:hover {
206
- background-color: #3a424d;
281
+ opacity: 0.8;
207
282
  }
208
283
 
209
284
  .toggle-switch input:checked + .toggle-slider:hover {
210
- background-color: #2ea043;
285
+ opacity: 0.9;
286
+ }
287
+
288
+ /* Filter buttons */
289
+ .filter-buttons {
290
+ display: flex;
291
+ gap: 4px;
292
+ background: var(--bg-secondary);
293
+ border: 1px solid var(--border-primary);
294
+ border-radius: 6px;
295
+ padding: 4px;
296
+ }
297
+
298
+ .filter-btn {
299
+ flex: 1;
300
+ padding: 8px 12px;
301
+ background: transparent;
302
+ border: none;
303
+ border-radius: 4px;
304
+ color: var(--text-secondary);
305
+ font-size: 12px;
306
+ font-weight: 500;
307
+ cursor: pointer;
308
+ transition: all 0.2s ease;
309
+ }
310
+
311
+ .filter-btn:hover {
312
+ background: var(--bg-tertiary);
313
+ color: var(--text-primary);
314
+ }
315
+
316
+ .filter-btn.active {
317
+ background: var(--accent);
318
+ color: var(--bg-primary);
319
+ }
320
+
321
+ .filter-btn.active:hover {
322
+ background: var(--accent-hover);
211
323
  }
212
324
  """
213
325
 
@@ -394,25 +506,26 @@ def get_tooltip_styles() -> str:
394
506
  .tooltip {
395
507
  position: absolute;
396
508
  padding: 12px;
397
- background: rgba(13, 17, 23, 0.95);
398
- border: 1px solid #30363d;
509
+ background: var(--bg-primary);
510
+ opacity: 0.95;
511
+ border: 1px solid var(--border-primary);
399
512
  border-radius: 6px;
400
513
  pointer-events: none;
401
514
  display: none;
402
515
  font-size: 12px;
403
516
  max-width: 300px;
404
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
517
+ box-shadow: 0 8px 24px var(--shadow);
405
518
  }
406
519
 
407
520
  .caller-link {
408
- color: #58a6ff;
521
+ color: var(--accent);
409
522
  text-decoration: none;
410
523
  cursor: pointer;
411
524
  transition: color 0.2s;
412
525
  }
413
526
 
414
527
  .caller-link:hover {
415
- color: #79c0ff;
528
+ color: var(--accent-hover);
416
529
  text-decoration: underline;
417
530
  }
418
531
  """
@@ -429,8 +542,8 @@ def get_breadcrumb_styles() -> str:
429
542
  .breadcrumb-nav {
430
543
  margin: 0 0 10px 0;
431
544
  padding: 8px 12px;
432
- background: #161b22;
433
- border: 1px solid #30363d;
545
+ background: var(--bg-secondary);
546
+ border: 1px solid var(--border-primary);
434
547
  border-radius: 4px;
435
548
  font-size: 12px;
436
549
  line-height: 1.6;
@@ -439,35 +552,35 @@ def get_breadcrumb_styles() -> str:
439
552
  }
440
553
 
441
554
  .breadcrumb-root {
442
- color: #58a6ff;
555
+ color: var(--accent);
443
556
  cursor: pointer;
444
557
  font-weight: 500;
445
558
  transition: color 0.2s;
446
559
  }
447
560
 
448
561
  .breadcrumb-root:hover {
449
- color: #79c0ff;
562
+ color: var(--accent-hover);
450
563
  text-decoration: underline;
451
564
  }
452
565
 
453
566
  .breadcrumb-link {
454
- color: #58a6ff;
567
+ color: var(--accent);
455
568
  cursor: pointer;
456
569
  transition: color 0.2s;
457
570
  }
458
571
 
459
572
  .breadcrumb-link:hover {
460
- color: #79c0ff;
573
+ color: var(--accent-hover);
461
574
  text-decoration: underline;
462
575
  }
463
576
 
464
577
  .breadcrumb-separator {
465
- color: #6e7681;
578
+ color: var(--text-tertiary);
466
579
  margin: 0 6px;
467
580
  }
468
581
 
469
582
  .breadcrumb-current {
470
- color: #c9d1d9;
583
+ color: var(--text-primary);
471
584
  font-weight: 600;
472
585
  }
473
586
  """
@@ -486,10 +599,11 @@ def get_content_pane_styles() -> str:
486
599
  right: 0;
487
600
  width: 450px;
488
601
  height: 100vh;
489
- background: rgba(13, 17, 23, 0.98);
490
- border-left: 1px solid #30363d;
602
+ background: var(--bg-primary);
603
+ opacity: 0.98;
604
+ border-left: 1px solid var(--border-primary);
491
605
  overflow-y: auto;
492
- box-shadow: -4px 0 24px rgba(0, 0, 0, 0.5);
606
+ box-shadow: -4px 0 24px var(--shadow);
493
607
  transform: translateX(100%);
494
608
  transition: transform 0.3s ease-in-out;
495
609
  z-index: 1000;
@@ -507,9 +621,10 @@ def get_content_pane_styles() -> str:
507
621
  .viewer-header {
508
622
  position: sticky;
509
623
  top: 0;
510
- background: rgba(13, 17, 23, 0.98);
624
+ background: var(--bg-primary);
625
+ opacity: 0.98;
511
626
  padding: 16px 20px;
512
- border-bottom: 1px solid #30363d;
627
+ border-bottom: 1px solid var(--border-primary);
513
628
  z-index: 1;
514
629
  }
515
630
 
@@ -523,11 +638,11 @@ def get_content_pane_styles() -> str:
523
638
 
524
639
  .viewer-expand-btn {
525
640
  cursor: pointer;
526
- color: #c9d1d9;
641
+ color: var(--text-primary);
527
642
  font-size: 16px;
528
643
  line-height: 1;
529
- background: #21262d;
530
- border: 1px solid #30363d;
644
+ background: var(--bg-tertiary);
645
+ border: 1px solid var(--border-primary);
531
646
  padding: 6px 8px;
532
647
  transition: color 0.2s, background 0.2s, border-color 0.2s;
533
648
  border-radius: 4px;
@@ -537,15 +652,15 @@ def get_content_pane_styles() -> str:
537
652
  }
538
653
 
539
654
  .viewer-expand-btn:hover {
540
- color: #58a6ff;
541
- background: #30363d;
542
- border-color: #58a6ff;
655
+ color: var(--accent);
656
+ background: var(--border-primary);
657
+ border-color: var(--accent);
543
658
  }
544
659
 
545
660
  .viewer-title {
546
661
  font-size: 16px;
547
662
  font-weight: bold;
548
- color: #58a6ff;
663
+ color: var(--accent);
549
664
  margin: 0 0 8px 0;
550
665
  padding-right: 80px;
551
666
  }
@@ -555,9 +670,9 @@ def get_content_pane_styles() -> str:
555
670
  }
556
671
 
557
672
  .section-nav select {
558
- background: #21262d;
559
- color: #c9d1d9;
560
- border: 1px solid #30363d;
673
+ background: var(--bg-tertiary);
674
+ color: var(--text-primary);
675
+ border: 1px solid var(--border-primary);
561
676
  border-radius: 6px;
562
677
  padding: 6px 10px;
563
678
  font-size: 12px;
@@ -567,22 +682,22 @@ def get_content_pane_styles() -> str:
567
682
  }
568
683
 
569
684
  .section-nav select:hover {
570
- border-color: #58a6ff;
685
+ border-color: var(--accent);
571
686
  }
572
687
 
573
688
  .section-nav select:focus {
574
689
  outline: none;
575
- border-color: #58a6ff;
690
+ border-color: var(--accent);
576
691
  box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.2);
577
692
  }
578
693
 
579
694
  .viewer-close-btn {
580
695
  cursor: pointer;
581
- color: #c9d1d9;
696
+ color: var(--text-primary);
582
697
  font-size: 18px;
583
698
  line-height: 1;
584
- background: #21262d;
585
- border: 1px solid #30363d;
699
+ background: var(--bg-tertiary);
700
+ border: 1px solid var(--border-primary);
586
701
  padding: 6px 10px;
587
702
  transition: color 0.2s, background 0.2s, border-color 0.2s;
588
703
  border-radius: 4px;
@@ -592,9 +707,9 @@ def get_content_pane_styles() -> str:
592
707
  }
593
708
 
594
709
  .viewer-close-btn:hover {
595
- color: #f85149;
596
- background: #30363d;
597
- border-color: #f85149;
710
+ color: var(--error);
711
+ background: var(--border-primary);
712
+ border-color: var(--error);
598
713
  }
599
714
 
600
715
  .viewer-content {
@@ -966,17 +1081,35 @@ def get_content_pane_styles() -> str:
966
1081
  font-weight: 500;
967
1082
  }
968
1083
 
969
- /* Node highlight animation */
1084
+ /* Node highlight animation - temporary focus */
970
1085
  .node-highlight circle {
971
1086
  stroke: #58a6ff !important;
972
- stroke-width: 3px !important;
973
- filter: drop-shadow(0 0 6px rgba(88, 166, 255, 0.6));
1087
+ stroke-width: 4px !important;
1088
+ filter: drop-shadow(0 0 8px rgba(88, 166, 255, 0.8));
974
1089
  }
975
1090
 
976
1091
  .node-highlight text {
977
1092
  fill: #58a6ff !important;
978
1093
  font-weight: bold !important;
979
1094
  }
1095
+
1096
+ /* Selected node - persistent highlight for node shown in viewer */
1097
+ .node-selected circle {
1098
+ stroke: #f0883e !important;
1099
+ stroke-width: 5px !important;
1100
+ filter: drop-shadow(0 0 12px rgba(240, 136, 62, 0.9));
1101
+ animation: selected-pulse 2s ease-in-out infinite;
1102
+ }
1103
+
1104
+ .node-selected text {
1105
+ fill: #f0883e !important;
1106
+ font-weight: bold !important;
1107
+ }
1108
+
1109
+ @keyframes selected-pulse {
1110
+ 0%, 100% { filter: drop-shadow(0 0 12px rgba(240, 136, 62, 0.9)); }
1111
+ 50% { filter: drop-shadow(0 0 20px rgba(240, 136, 62, 1.0)); }
1112
+ }
980
1113
  """
981
1114
 
982
1115
 
@@ -1145,6 +1278,68 @@ def get_spinner_styles() -> str:
1145
1278
  """
1146
1279
 
1147
1280
 
1281
+ def get_theme_toggle_styles() -> str:
1282
+ """Get styles for the theme toggle button.
1283
+
1284
+ Returns:
1285
+ CSS string for theme toggle styling
1286
+ """
1287
+ return """
1288
+ .theme-toggle-icon-btn {
1289
+ width: 36px;
1290
+ height: 36px;
1291
+ padding: 0;
1292
+ background: var(--bg-tertiary);
1293
+ border: 1px solid var(--border-primary);
1294
+ border-radius: 6px;
1295
+ color: var(--text-primary);
1296
+ cursor: pointer;
1297
+ display: flex;
1298
+ align-items: center;
1299
+ justify-content: center;
1300
+ transition: all 0.2s ease;
1301
+ flex-shrink: 0;
1302
+ }
1303
+
1304
+ .theme-toggle-icon-btn:hover {
1305
+ background: var(--accent);
1306
+ border-color: var(--accent-hover);
1307
+ transform: scale(1.05);
1308
+ }
1309
+
1310
+ .theme-toggle-icon-btn .theme-icon {
1311
+ font-size: 18px;
1312
+ line-height: 1;
1313
+ }
1314
+
1315
+ /* Complexity grade colors for nodes */
1316
+ .grade-A { fill: #238636 !important; stroke: #2ea043; }
1317
+ .grade-B { fill: #1f6feb !important; stroke: #388bfd; }
1318
+ .grade-C { fill: #d29922 !important; stroke: #e0ac3a; }
1319
+ .grade-D { fill: #f0883e !important; stroke: #f59f5f; }
1320
+ .grade-F { fill: #da3633 !important; stroke: #f85149; }
1321
+
1322
+ /* Code smell indicator - red border */
1323
+ .has-smells circle {
1324
+ stroke: var(--error) !important;
1325
+ stroke-width: 3px !important;
1326
+ stroke-dasharray: 5, 3;
1327
+ }
1328
+
1329
+ /* Circular dependency indicator */
1330
+ .in-cycle circle {
1331
+ stroke: #ff4444 !important;
1332
+ stroke-width: 3px !important;
1333
+ animation: pulse-border 1.5s infinite;
1334
+ }
1335
+
1336
+ @keyframes pulse-border {
1337
+ 0%, 100% { stroke-opacity: 0.8; }
1338
+ 50% { stroke-opacity: 1.0; }
1339
+ }
1340
+ """
1341
+
1342
+
1148
1343
  def get_search_styles() -> str:
1149
1344
  """Get styles for the search box and results dropdown.
1150
1345
 
@@ -1162,10 +1357,10 @@ def get_search_styles() -> str:
1162
1357
  #search-input {
1163
1358
  width: 100%;
1164
1359
  padding: 10px 12px;
1165
- background: #161b22;
1166
- border: 1px solid #30363d;
1360
+ background: var(--bg-secondary);
1361
+ border: 1px solid var(--border-primary);
1167
1362
  border-radius: 6px;
1168
- color: #c9d1d9;
1363
+ color: var(--text-primary);
1169
1364
  font-size: 13px;
1170
1365
  outline: none;
1171
1366
  transition: border-color 0.2s, box-shadow 0.2s;
@@ -1176,12 +1371,12 @@ def get_search_styles() -> str:
1176
1371
  }
1177
1372
 
1178
1373
  #search-input:focus {
1179
- border-color: #58a6ff;
1374
+ border-color: var(--accent);
1180
1375
  box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.2);
1181
1376
  }
1182
1377
 
1183
1378
  #search-input::placeholder {
1184
- color: #8b949e;
1379
+ color: var(--text-secondary);
1185
1380
  }
1186
1381
 
1187
1382
  /* Search results dropdown */
@@ -1192,13 +1387,13 @@ def get_search_styles() -> str:
1192
1387
  right: 0;
1193
1388
  max-height: 300px;
1194
1389
  overflow-y: auto;
1195
- background: #161b22;
1196
- border: 1px solid #30363d;
1390
+ background: var(--bg-secondary);
1391
+ border: 1px solid var(--border-primary);
1197
1392
  border-top: none;
1198
1393
  border-radius: 0 0 6px 6px;
1199
1394
  z-index: 1000;
1200
1395
  display: none;
1201
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
1396
+ box-shadow: 0 4px 12px var(--shadow);
1202
1397
  }
1203
1398
 
1204
1399
  .search-results.visible {
@@ -1211,7 +1406,7 @@ def get_search_styles() -> str:
1211
1406
  gap: 10px;
1212
1407
  padding: 10px 12px;
1213
1408
  cursor: pointer;
1214
- border-bottom: 1px solid #21262d;
1409
+ border-bottom: 1px solid var(--border-secondary);
1215
1410
  transition: background 0.15s;
1216
1411
  }
1217
1412
 
@@ -1221,7 +1416,7 @@ def get_search_styles() -> str:
1221
1416
 
1222
1417
  .search-result-item:hover,
1223
1418
  .search-result-item.selected {
1224
- background: #21262d;
1419
+ background: var(--bg-tertiary);
1225
1420
  }
1226
1421
 
1227
1422
  .search-result-icon {
@@ -1239,7 +1434,7 @@ def get_search_styles() -> str:
1239
1434
 
1240
1435
  .search-result-name {
1241
1436
  font-size: 13px;
1242
- color: #c9d1d9;
1437
+ color: var(--text-primary);
1243
1438
  font-weight: 500;
1244
1439
  overflow: hidden;
1245
1440
  text-overflow: ellipsis;
@@ -1248,14 +1443,14 @@ def get_search_styles() -> str:
1248
1443
 
1249
1444
  .search-result-name mark {
1250
1445
  background: rgba(88, 166, 255, 0.3);
1251
- color: #58a6ff;
1446
+ color: var(--accent);
1252
1447
  border-radius: 2px;
1253
1448
  padding: 0 2px;
1254
1449
  }
1255
1450
 
1256
1451
  .search-result-path {
1257
1452
  font-size: 11px;
1258
- color: #8b949e;
1453
+ color: var(--text-secondary);
1259
1454
  overflow: hidden;
1260
1455
  text-overflow: ellipsis;
1261
1456
  white-space: nowrap;
@@ -1264,8 +1459,8 @@ def get_search_styles() -> str:
1264
1459
 
1265
1460
  .search-result-type {
1266
1461
  font-size: 10px;
1267
- color: #8b949e;
1268
- background: #21262d;
1462
+ color: var(--text-secondary);
1463
+ background: var(--bg-tertiary);
1269
1464
  padding: 2px 6px;
1270
1465
  border-radius: 10px;
1271
1466
  text-transform: uppercase;
@@ -1275,16 +1470,1025 @@ def get_search_styles() -> str:
1275
1470
  .search-no-results {
1276
1471
  padding: 20px;
1277
1472
  text-align: center;
1278
- color: #8b949e;
1473
+ color: var(--text-secondary);
1279
1474
  font-size: 13px;
1280
1475
  }
1281
1476
 
1282
1477
  .search-hint {
1283
1478
  padding: 8px 12px;
1284
1479
  font-size: 11px;
1285
- color: #6e7681;
1286
- background: #0d1117;
1287
- border-top: 1px solid #21262d;
1480
+ color: var(--text-tertiary);
1481
+ background: var(--bg-primary);
1482
+ border-top: 1px solid var(--border-secondary);
1483
+ }
1484
+ """
1485
+
1486
+
1487
+ def get_complexity_report_styles() -> str:
1488
+ """Get styles for the complexity report.
1489
+
1490
+ Returns:
1491
+ CSS string for complexity report styling
1492
+ """
1493
+ return """
1494
+ /* Complexity Report Styles */
1495
+ .complexity-report {
1496
+ padding: 0;
1497
+ }
1498
+
1499
+ /* Summary Section */
1500
+ .complexity-summary {
1501
+ margin-bottom: 24px;
1502
+ }
1503
+
1504
+ .summary-grid {
1505
+ display: grid;
1506
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
1507
+ gap: 12px;
1508
+ margin-bottom: 20px;
1509
+ }
1510
+
1511
+ .summary-card {
1512
+ background: var(--bg-secondary);
1513
+ border: 1px solid var(--border-primary);
1514
+ border-radius: 6px;
1515
+ padding: 16px;
1516
+ text-align: center;
1517
+ }
1518
+
1519
+ .summary-label {
1520
+ font-size: 11px;
1521
+ color: var(--text-secondary);
1522
+ text-transform: uppercase;
1523
+ letter-spacing: 0.5px;
1524
+ margin-bottom: 8px;
1525
+ }
1526
+
1527
+ .summary-value {
1528
+ font-size: 24px;
1529
+ font-weight: bold;
1530
+ color: var(--accent);
1531
+ }
1532
+
1533
+ /* Grade Distribution */
1534
+ .grade-distribution {
1535
+ background: var(--bg-secondary);
1536
+ border: 1px solid var(--border-primary);
1537
+ border-radius: 6px;
1538
+ padding: 16px;
1539
+ }
1540
+
1541
+ .distribution-title {
1542
+ font-size: 13px;
1543
+ font-weight: 600;
1544
+ color: var(--text-primary);
1545
+ margin-bottom: 12px;
1546
+ text-transform: uppercase;
1547
+ letter-spacing: 0.5px;
1548
+ }
1549
+
1550
+ .distribution-bars {
1551
+ display: flex;
1552
+ flex-direction: column;
1553
+ gap: 8px;
1554
+ }
1555
+
1556
+ .distribution-row {
1557
+ display: grid;
1558
+ grid-template-columns: 40px 1fr 100px;
1559
+ gap: 12px;
1560
+ align-items: center;
1561
+ }
1562
+
1563
+ .distribution-grade {
1564
+ font-size: 14px;
1565
+ font-weight: bold;
1566
+ text-align: center;
1567
+ }
1568
+
1569
+ .distribution-bar-container {
1570
+ background: var(--bg-tertiary);
1571
+ border-radius: 4px;
1572
+ height: 24px;
1573
+ overflow: hidden;
1574
+ border: 1px solid var(--border-primary);
1575
+ }
1576
+
1577
+ .distribution-bar {
1578
+ height: 100%;
1579
+ border-radius: 3px;
1580
+ transition: width 0.3s ease;
1581
+ opacity: 0.8;
1582
+ }
1583
+
1584
+ .distribution-count {
1585
+ font-size: 12px;
1586
+ color: var(--text-secondary);
1587
+ text-align: right;
1588
+ }
1589
+
1590
+ /* Hotspots Section */
1591
+ .complexity-hotspots {
1592
+ margin-top: 24px;
1593
+ }
1594
+
1595
+ .section-title {
1596
+ font-size: 14px;
1597
+ font-weight: 600;
1598
+ color: var(--text-primary);
1599
+ margin-bottom: 12px;
1600
+ text-transform: uppercase;
1601
+ letter-spacing: 0.5px;
1602
+ }
1603
+
1604
+ .hotspots-table-container {
1605
+ background: var(--bg-secondary);
1606
+ border: 1px solid var(--border-primary);
1607
+ border-radius: 6px;
1608
+ overflow: hidden;
1609
+ }
1610
+
1611
+ .hotspots-table {
1612
+ width: 100%;
1613
+ border-collapse: collapse;
1614
+ font-size: 13px;
1615
+ }
1616
+
1617
+ .hotspots-table thead {
1618
+ background: var(--bg-tertiary);
1619
+ position: sticky;
1620
+ top: 0;
1621
+ z-index: 10;
1622
+ }
1623
+
1624
+ .hotspots-table th {
1625
+ padding: 12px;
1626
+ text-align: left;
1627
+ font-weight: 600;
1628
+ color: var(--text-secondary);
1629
+ text-transform: uppercase;
1630
+ font-size: 11px;
1631
+ letter-spacing: 0.5px;
1632
+ border-bottom: 1px solid var(--border-primary);
1633
+ }
1634
+
1635
+ .hotspots-table tbody tr {
1636
+ border-bottom: 1px solid var(--border-secondary);
1637
+ }
1638
+
1639
+ .hotspots-table tbody tr:last-child {
1640
+ border-bottom: none;
1641
+ }
1642
+
1643
+ .hotspot-row {
1644
+ cursor: pointer;
1645
+ transition: background 0.2s ease;
1646
+ }
1647
+
1648
+ .hotspot-row:hover {
1649
+ background: var(--bg-tertiary);
1650
+ }
1651
+
1652
+ .hotspots-table td {
1653
+ padding: 12px;
1654
+ color: var(--text-primary);
1655
+ }
1656
+
1657
+ .hotspot-name {
1658
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
1659
+ font-weight: 500;
1660
+ color: var(--accent);
1661
+ }
1662
+
1663
+ .hotspot-file {
1664
+ color: var(--text-secondary);
1665
+ font-size: 12px;
1666
+ max-width: 200px;
1667
+ overflow: hidden;
1668
+ text-overflow: ellipsis;
1669
+ white-space: nowrap;
1670
+ }
1671
+
1672
+ .hotspot-lines {
1673
+ text-align: center;
1674
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
1675
+ font-size: 12px;
1676
+ }
1677
+
1678
+ .hotspot-complexity {
1679
+ text-align: center;
1680
+ font-weight: bold;
1681
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
1682
+ }
1683
+
1684
+ .hotspot-grade {
1685
+ text-align: center;
1686
+ }
1687
+
1688
+ .grade-badge {
1689
+ display: inline-block;
1690
+ padding: 4px 10px;
1691
+ border-radius: 12px;
1692
+ font-weight: bold;
1693
+ font-size: 11px;
1694
+ color: white;
1695
+ min-width: 28px;
1696
+ text-align: center;
1697
+ }
1698
+ """
1699
+
1700
+
1701
+ def get_code_smells_styles() -> str:
1702
+ """Get styles for the code smells report.
1703
+
1704
+ Returns:
1705
+ CSS string for code smells styling
1706
+ """
1707
+ return """
1708
+ /* Code Smells Report Styles */
1709
+ .code-smells-report {
1710
+ padding: 0;
1711
+ }
1712
+
1713
+ /* Smell Type Filters */
1714
+ .smell-filters {
1715
+ background: var(--bg-secondary);
1716
+ border: 1px solid var(--border-primary);
1717
+ border-radius: 6px;
1718
+ padding: 16px;
1719
+ margin-bottom: 20px;
1720
+ }
1721
+
1722
+ .filter-title {
1723
+ font-size: 12px;
1724
+ font-weight: 600;
1725
+ color: var(--text-primary);
1726
+ margin-bottom: 12px;
1727
+ text-transform: uppercase;
1728
+ letter-spacing: 0.5px;
1729
+ }
1730
+
1731
+ .filter-checkboxes {
1732
+ display: grid;
1733
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
1734
+ gap: 10px;
1735
+ }
1736
+
1737
+ .filter-checkbox-item {
1738
+ display: flex;
1739
+ align-items: center;
1740
+ gap: 8px;
1741
+ padding: 8px 12px;
1742
+ background: var(--bg-tertiary);
1743
+ border: 1px solid var(--border-primary);
1744
+ border-radius: 4px;
1745
+ cursor: pointer;
1746
+ transition: all 0.2s ease;
1747
+ }
1748
+
1749
+ .filter-checkbox-item:hover {
1750
+ background: var(--bg-primary);
1751
+ border-color: var(--accent);
1752
+ }
1753
+
1754
+ .filter-checkbox-item input[type="checkbox"] {
1755
+ cursor: pointer;
1756
+ width: 16px;
1757
+ height: 16px;
1758
+ }
1759
+
1760
+ .filter-checkbox-label {
1761
+ flex: 1;
1762
+ font-size: 12px;
1763
+ color: var(--text-primary);
1764
+ cursor: pointer;
1765
+ }
1766
+
1767
+ .filter-checkbox-count {
1768
+ font-size: 11px;
1769
+ color: var(--text-secondary);
1770
+ background: var(--bg-secondary);
1771
+ padding: 2px 8px;
1772
+ border-radius: 10px;
1773
+ }
1774
+
1775
+ /* Smell Summary Cards */
1776
+ .smell-summary-grid {
1777
+ display: grid;
1778
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
1779
+ gap: 12px;
1780
+ margin-bottom: 24px;
1781
+ }
1782
+
1783
+ .smell-summary-card {
1784
+ background: var(--bg-secondary);
1785
+ border: 1px solid var(--border-primary);
1786
+ border-radius: 6px;
1787
+ padding: 16px;
1788
+ }
1789
+
1790
+ .smell-summary-card.warning {
1791
+ border-left: 3px solid var(--warning);
1792
+ }
1793
+
1794
+ .smell-summary-card.error {
1795
+ border-left: 3px solid var(--error);
1796
+ }
1797
+
1798
+ .smell-card-header {
1799
+ display: flex;
1800
+ align-items: center;
1801
+ gap: 8px;
1802
+ margin-bottom: 8px;
1803
+ }
1804
+
1805
+ .smell-card-icon {
1806
+ font-size: 18px;
1807
+ }
1808
+
1809
+ .smell-card-title {
1810
+ font-size: 11px;
1811
+ color: var(--text-secondary);
1812
+ text-transform: uppercase;
1813
+ letter-spacing: 0.5px;
1814
+ flex: 1;
1815
+ }
1816
+
1817
+ .smell-card-count {
1818
+ font-size: 24px;
1819
+ font-weight: bold;
1820
+ color: var(--text-primary);
1821
+ }
1822
+
1823
+ /* Smells Table */
1824
+ .smells-table-container {
1825
+ background: var(--bg-secondary);
1826
+ border: 1px solid var(--border-primary);
1827
+ border-radius: 6px;
1828
+ overflow: hidden;
1829
+ }
1830
+
1831
+ .smells-table {
1832
+ width: 100%;
1833
+ border-collapse: collapse;
1834
+ font-size: 13px;
1835
+ }
1836
+
1837
+ .smells-table thead {
1838
+ background: var(--bg-tertiary);
1839
+ position: sticky;
1840
+ top: 0;
1841
+ z-index: 10;
1842
+ }
1843
+
1844
+ .smells-table th {
1845
+ padding: 12px;
1846
+ text-align: left;
1847
+ font-weight: 600;
1848
+ color: var(--text-secondary);
1849
+ text-transform: uppercase;
1850
+ font-size: 11px;
1851
+ letter-spacing: 0.5px;
1852
+ border-bottom: 1px solid var(--border-primary);
1853
+ }
1854
+
1855
+ .smells-table tbody tr {
1856
+ border-bottom: 1px solid var(--border-secondary);
1857
+ }
1858
+
1859
+ .smells-table tbody tr:last-child {
1860
+ border-bottom: none;
1861
+ }
1862
+
1863
+ .smell-row {
1864
+ cursor: pointer;
1865
+ transition: background 0.2s ease;
1866
+ }
1867
+
1868
+ .smell-row:hover {
1869
+ background: var(--bg-tertiary);
1870
+ }
1871
+
1872
+ .smells-table td {
1873
+ padding: 12px;
1874
+ color: var(--text-primary);
1875
+ }
1876
+
1877
+ .smell-type-badge {
1878
+ display: inline-block;
1879
+ padding: 4px 10px;
1880
+ border-radius: 12px;
1881
+ font-weight: 500;
1882
+ font-size: 11px;
1883
+ background: var(--bg-tertiary);
1884
+ color: var(--text-primary);
1885
+ white-space: nowrap;
1886
+ }
1887
+
1888
+ .severity-badge {
1889
+ display: inline-flex;
1890
+ align-items: center;
1891
+ gap: 4px;
1892
+ padding: 4px 10px;
1893
+ border-radius: 12px;
1894
+ font-weight: bold;
1895
+ font-size: 11px;
1896
+ min-width: 70px;
1897
+ justify-content: center;
1898
+ }
1899
+
1900
+ .severity-badge.warning {
1901
+ background: rgba(210, 153, 34, 0.2);
1902
+ color: var(--warning);
1903
+ border: 1px solid var(--warning);
1904
+ }
1905
+
1906
+ .severity-badge.error {
1907
+ background: rgba(218, 54, 51, 0.2);
1908
+ color: var(--error);
1909
+ border: 1px solid var(--error);
1910
+ }
1911
+
1912
+ .smell-name {
1913
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
1914
+ font-weight: 500;
1915
+ color: var(--accent);
1916
+ }
1917
+
1918
+ .smell-file {
1919
+ color: var(--text-secondary);
1920
+ font-size: 12px;
1921
+ max-width: 200px;
1922
+ overflow: hidden;
1923
+ text-overflow: ellipsis;
1924
+ white-space: nowrap;
1925
+ }
1926
+
1927
+ .smell-details {
1928
+ font-size: 12px;
1929
+ color: var(--text-secondary);
1930
+ }
1931
+ """
1932
+
1933
+
1934
+ def get_dependencies_styles() -> str:
1935
+ """Get styles for the dependencies report.
1936
+
1937
+ Returns:
1938
+ CSS string for dependencies styling
1939
+ """
1940
+ return """
1941
+ /* Dependencies Report Styles */
1942
+ .dependencies-report {
1943
+ padding: 0;
1944
+ }
1945
+
1946
+ .dependency-summary {
1947
+ margin-bottom: 24px;
1948
+ }
1949
+
1950
+ /* Circular Dependencies Warning */
1951
+ .circular-deps-warning {
1952
+ background: rgba(218, 54, 51, 0.1);
1953
+ border: 2px solid var(--error);
1954
+ border-radius: 6px;
1955
+ padding: 16px;
1956
+ margin-bottom: 24px;
1957
+ }
1958
+
1959
+ .warning-header {
1960
+ display: flex;
1961
+ align-items: center;
1962
+ gap: 12px;
1963
+ margin-bottom: 12px;
1964
+ }
1965
+
1966
+ .warning-icon {
1967
+ font-size: 24px;
1968
+ }
1969
+
1970
+ .warning-title {
1971
+ font-size: 14px;
1972
+ font-weight: 600;
1973
+ color: var(--error);
1974
+ text-transform: uppercase;
1975
+ letter-spacing: 0.5px;
1976
+ }
1977
+
1978
+ .cycle-list {
1979
+ display: flex;
1980
+ flex-direction: column;
1981
+ gap: 8px;
1982
+ padding-left: 36px;
1983
+ }
1984
+
1985
+ .cycle-item {
1986
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
1987
+ font-size: 12px;
1988
+ color: var(--text-primary);
1989
+ padding: 8px 12px;
1990
+ background: var(--bg-secondary);
1991
+ border-left: 3px solid var(--error);
1992
+ border-radius: 4px;
1993
+ overflow: hidden;
1994
+ text-overflow: ellipsis;
1995
+ white-space: nowrap;
1996
+ }
1997
+
1998
+ /* Dependencies Table */
1999
+ .dependencies-table-section {
2000
+ margin-top: 24px;
2001
+ }
2002
+
2003
+ .dependencies-table-container {
2004
+ background: var(--bg-secondary);
2005
+ border: 1px solid var(--border-primary);
2006
+ border-radius: 6px;
2007
+ overflow: hidden;
2008
+ }
2009
+
2010
+ .dependencies-table {
2011
+ width: 100%;
2012
+ border-collapse: collapse;
2013
+ font-size: 13px;
2014
+ }
2015
+
2016
+ .dependencies-table thead {
2017
+ background: var(--bg-tertiary);
2018
+ position: sticky;
2019
+ top: 0;
2020
+ z-index: 10;
2021
+ }
2022
+
2023
+ .dependencies-table th {
2024
+ padding: 12px;
2025
+ text-align: left;
2026
+ font-weight: 600;
2027
+ color: var(--text-secondary);
2028
+ text-transform: uppercase;
2029
+ font-size: 11px;
2030
+ letter-spacing: 0.5px;
2031
+ border-bottom: 1px solid var(--border-primary);
2032
+ }
2033
+
2034
+ .dependencies-table th:nth-child(2),
2035
+ .dependencies-table th:nth-child(3),
2036
+ .dependencies-table th:nth-child(4) {
2037
+ text-align: center;
2038
+ }
2039
+
2040
+ .dependencies-table th:nth-child(5) {
2041
+ width: 50px;
2042
+ text-align: center;
2043
+ }
2044
+
2045
+ .dependencies-table tbody tr.dependency-row {
2046
+ border-bottom: 1px solid var(--border-secondary);
2047
+ transition: background 0.2s ease;
2048
+ }
2049
+
2050
+ .dependencies-table tbody tr.dependency-row:hover {
2051
+ background: var(--bg-tertiary);
2052
+ }
2053
+
2054
+ .dependencies-table tbody tr.dependency-row.in-cycle {
2055
+ background: rgba(218, 54, 51, 0.05);
2056
+ }
2057
+
2058
+ .dependencies-table tbody tr.dependency-row.in-cycle:hover {
2059
+ background: rgba(218, 54, 51, 0.1);
2060
+ }
2061
+
2062
+ .dependencies-table td {
2063
+ padding: 12px;
2064
+ color: var(--text-primary);
2065
+ }
2066
+
2067
+ .dep-file {
2068
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2069
+ font-weight: 500;
2070
+ color: var(--accent);
2071
+ }
2072
+
2073
+ .dep-count {
2074
+ text-align: center;
2075
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2076
+ color: var(--text-secondary);
2077
+ }
2078
+
2079
+ .dep-total {
2080
+ text-align: center;
2081
+ font-weight: bold;
2082
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2083
+ color: var(--text-primary);
2084
+ }
2085
+
2086
+ .dep-expand {
2087
+ text-align: center;
2088
+ }
2089
+
2090
+ .expand-btn {
2091
+ background: var(--bg-tertiary);
2092
+ border: 1px solid var(--border-primary);
2093
+ border-radius: 4px;
2094
+ padding: 4px 10px;
2095
+ cursor: pointer;
2096
+ color: var(--text-primary);
2097
+ font-size: 12px;
2098
+ transition: all 0.2s ease;
2099
+ }
2100
+
2101
+ .expand-btn:hover {
2102
+ background: var(--accent);
2103
+ border-color: var(--accent);
2104
+ color: var(--bg-primary);
2105
+ }
2106
+
2107
+ /* Dependency Details Row */
2108
+ .dependency-details {
2109
+ background: var(--bg-primary);
2110
+ }
2111
+
2112
+ .dependency-details td {
2113
+ padding: 0 !important;
2114
+ }
2115
+
2116
+ .dependency-details-content {
2117
+ padding: 16px 20px;
2118
+ display: grid;
2119
+ grid-template-columns: 1fr 1fr;
2120
+ gap: 20px;
2121
+ }
2122
+
2123
+ .dependency-section {
2124
+ background: var(--bg-secondary);
2125
+ border: 1px solid var(--border-primary);
2126
+ border-radius: 6px;
2127
+ padding: 12px;
2128
+ }
2129
+
2130
+ .dependency-section-title {
2131
+ font-size: 12px;
2132
+ font-weight: 600;
2133
+ color: var(--text-primary);
2134
+ margin-bottom: 10px;
2135
+ text-transform: uppercase;
2136
+ letter-spacing: 0.5px;
2137
+ }
2138
+
2139
+ .dependency-list {
2140
+ display: flex;
2141
+ flex-wrap: wrap;
2142
+ gap: 6px;
2143
+ }
2144
+
2145
+ .dependency-item {
2146
+ display: inline-block;
2147
+ padding: 4px 10px;
2148
+ background: var(--bg-tertiary);
2149
+ border: 1px solid var(--border-primary);
2150
+ border-radius: 12px;
2151
+ font-size: 11px;
2152
+ color: var(--text-primary);
2153
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2154
+ transition: all 0.2s ease;
2155
+ cursor: default;
2156
+ }
2157
+
2158
+ .dependency-item:hover {
2159
+ background: var(--accent);
2160
+ border-color: var(--accent);
2161
+ color: var(--bg-primary);
2162
+ }
2163
+
2164
+ .dependency-item-empty {
2165
+ color: var(--text-tertiary);
2166
+ font-size: 12px;
2167
+ font-style: italic;
2168
+ }
2169
+
2170
+ .dependency-item-more {
2171
+ color: var(--text-secondary);
2172
+ font-size: 11px;
2173
+ padding: 4px 10px;
2174
+ font-style: italic;
2175
+ }
2176
+ """
2177
+
2178
+
2179
+ def get_trends_styles() -> str:
2180
+ """Get styles for the trends/metrics snapshot report.
2181
+
2182
+ Returns:
2183
+ CSS string for trends styling
2184
+ """
2185
+ return """
2186
+ /* Trends Report Styles */
2187
+ .trends-report {
2188
+ padding: 0;
2189
+ }
2190
+
2191
+ /* Snapshot Banner */
2192
+ .snapshot-banner {
2193
+ background: var(--bg-secondary);
2194
+ border: 2px solid var(--accent);
2195
+ border-radius: 8px;
2196
+ padding: 20px;
2197
+ margin-bottom: 24px;
2198
+ }
2199
+
2200
+ .snapshot-header {
2201
+ display: flex;
2202
+ align-items: center;
2203
+ gap: 16px;
2204
+ margin-bottom: 12px;
2205
+ }
2206
+
2207
+ .snapshot-icon {
2208
+ font-size: 32px;
2209
+ flex-shrink: 0;
2210
+ }
2211
+
2212
+ .snapshot-info {
2213
+ flex: 1;
2214
+ }
2215
+
2216
+ .snapshot-title {
2217
+ font-size: 18px;
2218
+ font-weight: bold;
2219
+ color: var(--accent);
2220
+ margin-bottom: 4px;
2221
+ }
2222
+
2223
+ .snapshot-timestamp {
2224
+ font-size: 13px;
2225
+ color: var(--text-secondary);
2226
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2227
+ }
2228
+
2229
+ .snapshot-description {
2230
+ font-size: 13px;
2231
+ color: var(--text-secondary);
2232
+ line-height: 1.6;
2233
+ }
2234
+
2235
+ /* Metrics Section */
2236
+ .metrics-section {
2237
+ margin-bottom: 24px;
2238
+ }
2239
+
2240
+ .metrics-grid {
2241
+ display: grid;
2242
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
2243
+ gap: 16px;
2244
+ }
2245
+
2246
+ .metric-card {
2247
+ background: var(--bg-secondary);
2248
+ border: 1px solid var(--border-primary);
2249
+ border-radius: 8px;
2250
+ padding: 20px;
2251
+ text-align: center;
2252
+ transition: all 0.2s ease;
2253
+ }
2254
+
2255
+ .metric-card:hover {
2256
+ border-color: var(--accent);
2257
+ transform: translateY(-2px);
2258
+ box-shadow: 0 4px 12px var(--shadow);
2259
+ }
2260
+
2261
+ .metric-icon {
2262
+ font-size: 32px;
2263
+ margin-bottom: 12px;
2264
+ }
2265
+
2266
+ .metric-value {
2267
+ font-size: 32px;
2268
+ font-weight: bold;
2269
+ color: var(--accent);
2270
+ margin-bottom: 8px;
2271
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2272
+ }
2273
+
2274
+ .metric-label {
2275
+ font-size: 12px;
2276
+ color: var(--text-secondary);
2277
+ text-transform: uppercase;
2278
+ letter-spacing: 0.5px;
2279
+ }
2280
+
2281
+ /* Health Score Section */
2282
+ .health-section {
2283
+ margin-bottom: 24px;
2284
+ }
2285
+
2286
+ .health-card {
2287
+ background: var(--bg-secondary);
2288
+ border: 1px solid var(--border-primary);
2289
+ border-radius: 8px;
2290
+ padding: 24px;
2291
+ }
2292
+
2293
+ .health-score-display {
2294
+ display: flex;
2295
+ align-items: center;
2296
+ justify-content: center;
2297
+ gap: 16px;
2298
+ margin-bottom: 16px;
2299
+ }
2300
+
2301
+ .health-score-value {
2302
+ font-size: 48px;
2303
+ font-weight: bold;
2304
+ color: var(--accent);
2305
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2306
+ }
2307
+
2308
+ .health-score-label {
2309
+ font-size: 24px;
2310
+ font-weight: 600;
2311
+ color: var(--text-primary);
2312
+ }
2313
+
2314
+ .health-progress-container {
2315
+ background: var(--bg-tertiary);
2316
+ border: 1px solid var(--border-primary);
2317
+ border-radius: 12px;
2318
+ height: 32px;
2319
+ overflow: hidden;
2320
+ margin-bottom: 16px;
2321
+ }
2322
+
2323
+ .health-progress-bar {
2324
+ height: 100%;
2325
+ border-radius: 10px;
2326
+ transition: width 0.5s ease;
2327
+ opacity: 0.9;
2328
+ }
2329
+
2330
+ .health-description {
2331
+ font-size: 14px;
2332
+ color: var(--text-secondary);
2333
+ text-align: center;
2334
+ line-height: 1.6;
2335
+ }
2336
+
2337
+ /* Distribution Section */
2338
+ .distribution-section,
2339
+ .size-distribution-section {
2340
+ margin-bottom: 24px;
2341
+ }
2342
+
2343
+ .distribution-chart {
2344
+ background: var(--bg-secondary);
2345
+ border: 1px solid var(--border-primary);
2346
+ border-radius: 8px;
2347
+ padding: 20px;
2348
+ }
2349
+
2350
+ .distribution-bar-row {
2351
+ display: grid;
2352
+ grid-template-columns: 180px 1fr 80px;
2353
+ gap: 16px;
2354
+ align-items: center;
2355
+ margin-bottom: 12px;
2356
+ }
2357
+
2358
+ .distribution-bar-row:last-child {
2359
+ margin-bottom: 0;
2360
+ }
2361
+
2362
+ .distribution-bar-label {
2363
+ display: flex;
2364
+ align-items: center;
2365
+ gap: 8px;
2366
+ font-size: 13px;
2367
+ }
2368
+
2369
+ .distribution-grade {
2370
+ font-size: 16px;
2371
+ font-weight: bold;
2372
+ min-width: 24px;
2373
+ }
2374
+
2375
+ .distribution-range {
2376
+ font-size: 12px;
2377
+ color: var(--text-secondary);
2378
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2379
+ }
2380
+
2381
+ .size-label {
2382
+ font-size: 13px;
2383
+ color: var(--text-primary);
2384
+ }
2385
+
2386
+ .distribution-bar-container {
2387
+ background: var(--bg-tertiary);
2388
+ border: 1px solid var(--border-primary);
2389
+ border-radius: 6px;
2390
+ height: 28px;
2391
+ overflow: hidden;
2392
+ }
2393
+
2394
+ .distribution-bar-fill {
2395
+ height: 100%;
2396
+ border-radius: 5px;
2397
+ transition: width 0.3s ease;
2398
+ opacity: 0.8;
2399
+ }
2400
+
2401
+ .distribution-bar-value {
2402
+ font-size: 13px;
2403
+ font-weight: 600;
2404
+ color: var(--text-primary);
2405
+ text-align: right;
2406
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2407
+ }
2408
+
2409
+ /* Trends Chart Styles */
2410
+ .trends-section {
2411
+ margin-top: 32px;
2412
+ }
2413
+
2414
+ .trends-container {
2415
+ display: flex;
2416
+ flex-direction: column;
2417
+ gap: 24px;
2418
+ margin-bottom: 16px;
2419
+ }
2420
+
2421
+ .trend-chart {
2422
+ background: var(--bg-secondary);
2423
+ border: 1px solid var(--border-primary);
2424
+ border-radius: 8px;
2425
+ padding: 20px;
2426
+ overflow-x: auto;
2427
+ }
2428
+
2429
+ .trend-chart svg {
2430
+ display: block;
2431
+ margin: 0 auto;
2432
+ }
2433
+
2434
+ .trend-info {
2435
+ font-size: 12px;
2436
+ color: var(--text-secondary);
2437
+ text-align: center;
2438
+ margin-top: 8px;
2439
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2440
+ }
2441
+
2442
+ /* Future Section (fallback when no trend data) */
2443
+ .future-section {
2444
+ margin-top: 32px;
2445
+ }
2446
+
2447
+ .future-placeholder {
2448
+ background: var(--bg-secondary);
2449
+ border: 2px dashed var(--border-primary);
2450
+ border-radius: 8px;
2451
+ padding: 40px;
2452
+ text-align: center;
2453
+ }
2454
+
2455
+ .future-icon {
2456
+ font-size: 48px;
2457
+ margin-bottom: 16px;
2458
+ }
2459
+
2460
+ .future-title {
2461
+ font-size: 18px;
2462
+ font-weight: bold;
2463
+ color: var(--text-primary);
2464
+ margin-bottom: 16px;
2465
+ }
2466
+
2467
+ .future-description {
2468
+ font-size: 14px;
2469
+ color: var(--text-secondary);
2470
+ line-height: 1.8;
2471
+ max-width: 600px;
2472
+ margin: 0 auto;
2473
+ }
2474
+
2475
+ .future-description code {
2476
+ background: var(--bg-tertiary);
2477
+ padding: 2px 6px;
2478
+ border-radius: 3px;
2479
+ font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
2480
+ font-size: 12px;
2481
+ }
2482
+
2483
+ .future-description ul {
2484
+ text-align: left;
2485
+ margin: 16px auto 0;
2486
+ padding-left: 20px;
2487
+ max-width: 400px;
2488
+ }
2489
+
2490
+ .future-description li {
2491
+ margin-bottom: 8px;
1288
2492
  }
1289
2493
  """
1290
2494
 
@@ -1308,6 +2512,11 @@ def get_all_styles() -> str:
1308
2512
  get_code_chunks_styles(),
1309
2513
  get_reset_button_styles(),
1310
2514
  get_spinner_styles(),
2515
+ get_theme_toggle_styles(),
1311
2516
  get_search_styles(),
2517
+ get_complexity_report_styles(),
2518
+ get_code_smells_styles(),
2519
+ get_dependencies_styles(),
2520
+ get_trends_styles(),
1312
2521
  ]
1313
2522
  )