repo-wrapped 0.0.6 → 0.0.9

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 (176) hide show
  1. package/.github/agents/complete.agent.md +257 -0
  2. package/.github/agents/feature-scaffold.agent.md +248 -0
  3. package/.github/agents/jsdoc.agent.md +243 -0
  4. package/.github/agents/plan.agent.md +202 -0
  5. package/.github/agents/spec-writer.agent.md +169 -0
  6. package/.github/agents/test-writer.agent.md +169 -0
  7. package/.stylelintrc.json +27 -0
  8. package/README.md +94 -94
  9. package/coverage/base.css +224 -0
  10. package/coverage/block-navigation.js +87 -0
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/index.html +446 -0
  13. package/coverage/lcov-report/base.css +224 -0
  14. package/coverage/lcov-report/block-navigation.js +87 -0
  15. package/coverage/lcov-report/favicon.png +0 -0
  16. package/coverage/lcov-report/index.html +446 -0
  17. package/coverage/lcov-report/prettify.css +1 -0
  18. package/coverage/lcov-report/prettify.js +2 -0
  19. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  20. package/coverage/lcov-report/sorter.js +210 -0
  21. package/coverage/lcov.info +7039 -0
  22. package/coverage/prettify.css +1 -0
  23. package/coverage/prettify.js +2 -0
  24. package/coverage/sort-arrow-sprite.png +0 -0
  25. package/coverage/sorter.js +210 -0
  26. package/dist/commands/generate.js +262 -5
  27. package/dist/config/defaults.js +158 -0
  28. package/dist/config/index.js +10 -0
  29. package/dist/features/achievements/data/achievements.json +284 -0
  30. package/dist/features/achievements/engine.js +140 -0
  31. package/dist/features/achievements/evaluators.js +246 -0
  32. package/dist/features/achievements/helpers.js +58 -0
  33. package/dist/features/achievements/index.js +57 -0
  34. package/dist/features/achievements/loader.js +88 -0
  35. package/dist/features/achievements/template.js +155 -0
  36. package/dist/features/achievements/types.js +7 -0
  37. package/dist/features/commit-quality/analyzer.js +378 -0
  38. package/dist/features/commit-quality/analyzer.test.js +484 -0
  39. package/dist/features/commit-quality/index.js +28 -0
  40. package/dist/features/commit-quality/template.js +114 -0
  41. package/dist/features/commit-quality/types.js +2 -0
  42. package/dist/features/comparison/analyzer.js +222 -0
  43. package/dist/features/comparison/index.js +28 -0
  44. package/dist/features/comparison/template.js +119 -0
  45. package/dist/features/comparison/types.js +2 -0
  46. package/dist/features/contribution-graph/index.js +9 -0
  47. package/dist/features/contribution-graph/template.js +89 -0
  48. package/dist/features/events/index.js +31 -0
  49. package/dist/features/events/parser.js +253 -0
  50. package/dist/features/events/template.js +113 -0
  51. package/dist/features/events/types.js +2 -0
  52. package/dist/features/executive-summary/generator.js +275 -0
  53. package/dist/features/executive-summary/index.js +27 -0
  54. package/dist/features/executive-summary/template.js +80 -0
  55. package/dist/features/executive-summary/types.js +2 -0
  56. package/dist/features/gaps/analyzer.js +298 -0
  57. package/dist/features/gaps/analyzer.test.js +517 -0
  58. package/dist/features/gaps/index.js +27 -0
  59. package/dist/features/gaps/template.js +190 -0
  60. package/dist/features/gaps/types.js +2 -0
  61. package/dist/features/impact/analyzer.js +248 -0
  62. package/dist/features/impact/index.js +26 -0
  63. package/dist/features/impact/template.js +118 -0
  64. package/dist/features/impact/types.js +2 -0
  65. package/dist/features/index.js +40 -0
  66. package/dist/features/knowledge/analyzer.js +385 -0
  67. package/dist/features/knowledge/index.js +26 -0
  68. package/dist/features/knowledge/template.js +239 -0
  69. package/dist/features/knowledge/types.js +2 -0
  70. package/dist/features/streaks/calculator.js +184 -0
  71. package/dist/features/streaks/calculator.test.js +366 -0
  72. package/dist/features/streaks/index.js +36 -0
  73. package/dist/features/streaks/template.js +41 -0
  74. package/dist/features/streaks/types.js +9 -0
  75. package/dist/features/team/analyzer.js +316 -0
  76. package/dist/features/team/index.js +30 -0
  77. package/dist/features/team/template.js +146 -0
  78. package/dist/features/team/types.js +2 -0
  79. package/dist/features/time-patterns/analyzer.js +319 -0
  80. package/dist/features/time-patterns/analyzer.test.js +278 -0
  81. package/dist/features/time-patterns/index.js +37 -0
  82. package/dist/features/time-patterns/template.js +109 -0
  83. package/dist/features/time-patterns/types.js +9 -0
  84. package/dist/features/velocity/analyzer.js +257 -0
  85. package/dist/features/velocity/analyzer.test.js +383 -0
  86. package/dist/features/velocity/index.js +27 -0
  87. package/dist/features/velocity/template.js +189 -0
  88. package/dist/features/velocity/types.js +2 -0
  89. package/dist/generators/html/scripts/knowledge.js +17 -0
  90. package/dist/generators/html/styles/base.css +10 -6
  91. package/dist/generators/html/styles/components.css +121 -1
  92. package/dist/generators/html/styles/knowledge.css +21 -0
  93. package/dist/generators/html/styles/leaddev.css +1335 -0
  94. package/dist/generators/html/styles/strategic-insights.css +1337 -0
  95. package/dist/generators/html/templates/commitQualitySection.js +28 -2
  96. package/dist/generators/html/templates/comparisonSection.js +119 -0
  97. package/dist/generators/html/templates/eventsSection.js +113 -0
  98. package/dist/generators/html/templates/executiveSummarySection.js +80 -0
  99. package/dist/generators/html/templates/gapSection.js +190 -0
  100. package/dist/generators/html/templates/impactSection.js +8 -6
  101. package/dist/generators/html/templates/knowledgeSection.js +16 -2
  102. package/dist/generators/html/templates/teamSection.js +146 -0
  103. package/dist/generators/html/templates/velocitySection.js +189 -0
  104. package/dist/generators/html/types.js +7 -0
  105. package/dist/generators/html/utils/analysisRunner.js +93 -0
  106. package/dist/generators/html/utils/cardBuilder.js +47 -0
  107. package/dist/generators/html/utils/contextBuilder.js +54 -0
  108. package/dist/generators/html/utils/htmlDocumentBuilder.js +396 -0
  109. package/dist/generators/html/utils/kpiBuilder.js +76 -0
  110. package/dist/generators/html/utils/sectionWrapper.js +71 -0
  111. package/dist/generators/html/utils/styleLoader.js +2 -1
  112. package/dist/html/analysisRunner.js +93 -0
  113. package/dist/html/htmlDocumentBuilder.js +396 -0
  114. package/dist/html/index.js +29 -0
  115. package/dist/html/shared/colorUtils.js +61 -0
  116. package/dist/html/shared/commitMapBuilder.js +23 -0
  117. package/dist/html/shared/components/cardBuilder.js +47 -0
  118. package/dist/html/shared/components/index.js +18 -0
  119. package/dist/html/shared/components/kpiBuilder.js +76 -0
  120. package/dist/html/shared/components/sectionWrapper.js +71 -0
  121. package/dist/html/shared/contextBuilder.js +54 -0
  122. package/dist/html/shared/dateRangeCalculator.js +56 -0
  123. package/dist/html/shared/developerStatsCalculator.js +28 -0
  124. package/dist/html/shared/index.js +39 -0
  125. package/dist/html/shared/scriptLoader.js +15 -0
  126. package/dist/html/shared/scripts/export.js +125 -0
  127. package/dist/html/shared/scripts/knowledge.js +137 -0
  128. package/dist/html/shared/scripts/modal.js +68 -0
  129. package/dist/html/shared/scripts/navigation.js +156 -0
  130. package/dist/html/shared/scripts/tabs.js +18 -0
  131. package/dist/html/shared/scripts/tooltip.js +21 -0
  132. package/dist/html/shared/styleLoader.js +18 -0
  133. package/dist/html/shared/styles/achievements.css +387 -0
  134. package/dist/html/shared/styles/base.css +822 -0
  135. package/dist/html/shared/styles/components.css +1511 -0
  136. package/dist/html/shared/styles/knowledge.css +242 -0
  137. package/dist/html/shared/styles/strategic-insights.css +1337 -0
  138. package/dist/html/shared/weekGrouper.js +27 -0
  139. package/dist/html/types.js +7 -0
  140. package/dist/index.js +54 -21
  141. package/dist/test/helpers/commitFactory.js +166 -0
  142. package/dist/test/helpers/dateUtils.js +101 -0
  143. package/dist/test/helpers/index.js +29 -0
  144. package/dist/test/setup.js +17 -0
  145. package/dist/test/smoke.test.js +94 -0
  146. package/dist/types/achievements.js +7 -0
  147. package/dist/types/analysis.js +7 -0
  148. package/dist/types/core.js +7 -0
  149. package/dist/types/index.js +38 -0
  150. package/dist/types/options.js +7 -0
  151. package/dist/types/shared.js +7 -0
  152. package/dist/types/strategic.js +7 -0
  153. package/dist/types/summary.js +7 -0
  154. package/dist/utils/achievementDefinitions.js +22 -22
  155. package/dist/utils/analyzerContextBuilder.js +124 -0
  156. package/dist/utils/commitQualityAnalyzer.js +13 -2
  157. package/dist/utils/emptyResults.js +95 -0
  158. package/dist/utils/eventAnnotationParser.js +253 -0
  159. package/dist/utils/executiveSummaryGenerator.js +275 -0
  160. package/dist/utils/fileHotspotAnalyzer.js +4 -12
  161. package/dist/utils/gapAnalyzer.js +298 -0
  162. package/dist/utils/gitParser.test.js +363 -0
  163. package/dist/utils/htmlGenerator.js +126 -450
  164. package/dist/utils/impactAnalyzer.js +20 -19
  165. package/dist/utils/knowledgeDistributionAnalyzer.js +32 -27
  166. package/dist/utils/matrixGenerator.js +13 -13
  167. package/dist/utils/rangeComparisonAnalyzer.js +222 -0
  168. package/dist/utils/streakCalculator.js +77 -27
  169. package/dist/utils/teamAnalyzer.js +316 -0
  170. package/dist/utils/timePatternAnalyzer.js +18 -3
  171. package/dist/utils/velocityAnalyzer.js +257 -0
  172. package/dist/utils/wrappedGenerator.js +8 -8
  173. package/package.json +74 -55
  174. package/vitest.config.ts +46 -0
  175. package/dist/cli.js +0 -24
  176. package/dist/commands/index.js +0 -24
@@ -0,0 +1,822 @@
1
+ /* Base styles and GitHub Dark theme - Enterprise Edition */
2
+
3
+ /* === Design Tokens === */
4
+ :root {
5
+ /* Background Colors */
6
+ --bg-primary: #0d1117;
7
+ --bg-secondary: #161b22;
8
+ --bg-tertiary: #1c2128;
9
+ --bg-elevated: #21262d;
10
+
11
+ /* Border Colors */
12
+ --border-default: #30363d;
13
+ --border-subtle: #21262d;
14
+ --border-emphasis: #3d444d;
15
+
16
+ /* Text Colors */
17
+ --text-primary: #e6edf3;
18
+ --text-secondary: #8b949e;
19
+ --text-muted: #6e7681;
20
+ --text-link: #58a6ff;
21
+
22
+ /* Accent Colors */
23
+ --accent-blue: #58a6ff;
24
+ --accent-blue-muted: #388bfd;
25
+ --accent-green: #3fb950;
26
+ --accent-green-light: #69db7c;
27
+ --accent-green-muted: #238636;
28
+ --accent-gold: #d4a72c;
29
+ --accent-gold-muted: #9e7a1f;
30
+ --accent-purple: #8b5cf6;
31
+ --accent-orange: #ff922b;
32
+ --accent-orange-light: #ffa94d;
33
+
34
+ /* Status Colors */
35
+ --status-success: #238636;
36
+ --status-warning: #ffd43b;
37
+ --status-warning-muted: #9e6a03;
38
+ --status-danger: #ff6b6b;
39
+ --status-info: #58a6ff;
40
+
41
+ /* Tier Colors (Muted) */
42
+ --tier-bronze: #a67c52;
43
+ --tier-silver: #9ca3af;
44
+ --tier-gold: #d4a72c;
45
+ --tier-platinum: #94a3b8;
46
+ --tier-legendary: #8b5cf6;
47
+
48
+ /* Spacing */
49
+ --spacing-xs: 4px;
50
+ --spacing-sm: 8px;
51
+ --spacing-md: 16px;
52
+ --spacing-lg: 24px;
53
+ --spacing-xl: 32px;
54
+ --spacing-2xl: 48px;
55
+
56
+ /* Border Radius */
57
+ --radius-sm: 2px;
58
+ --radius-md: 4px;
59
+ --radius-lg: 6px;
60
+ --radius-xl: 12px;
61
+
62
+ /* Shadows */
63
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
64
+ --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
65
+ --shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.15);
66
+
67
+ /* Typography */
68
+ --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
69
+ --font-mono: 'SF Mono', 'Consolas', 'Liberation Mono', Menlo, monospace;
70
+ --font-size-xs: 11px;
71
+ --font-size-sm: 12px;
72
+ --font-size-md: 14px;
73
+ --font-size-lg: 16px;
74
+ --font-size-xl: 18px;
75
+ --font-size-2xl: 20px;
76
+ --font-weight-normal: 400;
77
+ --font-weight-medium: 500;
78
+ --font-weight-semibold: 600;
79
+
80
+ /* Transitions */
81
+ --transition-fast: 0.15s ease;
82
+ --transition-normal: 0.2s ease;
83
+ }
84
+
85
+ /* === Reset === */
86
+ * {
87
+ margin: 0;
88
+ padding: 0;
89
+ box-sizing: border-box;
90
+ }
91
+
92
+ /* === Custom Scrollbar === */
93
+ ::-webkit-scrollbar {
94
+ width: 8px;
95
+ height: 8px;
96
+ }
97
+
98
+ ::-webkit-scrollbar-track {
99
+ background: var(--bg-secondary);
100
+ border-radius: 4px;
101
+ }
102
+
103
+ ::-webkit-scrollbar-thumb {
104
+ background: var(--border-default);
105
+ border-radius: 4px;
106
+ }
107
+
108
+ ::-webkit-scrollbar-thumb:hover {
109
+ background: var(--text-muted);
110
+ }
111
+
112
+ /* Firefox scrollbar */
113
+ * {
114
+ scrollbar-width: thin;
115
+ scrollbar-color: var(--border-default) var(--bg-secondary);
116
+ }
117
+
118
+ /* === Base Layout === */
119
+ body {
120
+ font-family: var(--font-family);
121
+ font-size: var(--font-size-md);
122
+ font-weight: var(--font-weight-normal);
123
+ line-height: 1.5;
124
+ background: var(--bg-primary);
125
+ color: var(--text-primary);
126
+ padding: var(--spacing-xl);
127
+ display: flex;
128
+ justify-content: center;
129
+ align-items: flex-start;
130
+ min-height: 100vh;
131
+ }
132
+
133
+ .container {
134
+ background: var(--bg-secondary);
135
+ border: 1px solid var(--border-default);
136
+ border-radius: var(--radius-lg);
137
+ padding: var(--spacing-lg);
138
+ min-width: 70vw;
139
+ box-shadow: var(--shadow-md);
140
+ }
141
+
142
+ /* === Typography === */
143
+ h1 {
144
+ font-size: var(--font-size-2xl);
145
+ font-weight: var(--font-weight-semibold);
146
+ color: var(--text-primary);
147
+ margin-bottom: var(--spacing-xs);
148
+ letter-spacing: -0.01em;
149
+ }
150
+
151
+ h2 {
152
+ font-size: var(--font-size-xl);
153
+ font-weight: var(--font-weight-semibold);
154
+ color: var(--text-primary);
155
+ margin-bottom: var(--spacing-md);
156
+ }
157
+
158
+ h3 {
159
+ font-size: var(--font-size-lg);
160
+ font-weight: var(--font-weight-medium);
161
+ color: var(--text-primary);
162
+ margin-bottom: var(--spacing-sm);
163
+ }
164
+
165
+ .repo-url {
166
+ font-size: var(--font-size-sm);
167
+ color: var(--text-secondary);
168
+ margin-bottom: var(--spacing-md);
169
+ word-break: break-all;
170
+ }
171
+
172
+ .repo-url a {
173
+ color: var(--text-secondary);
174
+ text-decoration: none;
175
+ transition: color var(--transition-fast);
176
+ }
177
+
178
+ .repo-url a:hover {
179
+ color: var(--text-link);
180
+ text-decoration: underline;
181
+ }
182
+
183
+ .stats {
184
+ margin-bottom: var(--spacing-md);
185
+ font-size: var(--font-size-md);
186
+ color: var(--text-secondary);
187
+ }
188
+
189
+ /* === Tab Navigation === */
190
+ .tab-nav {
191
+ display: flex;
192
+ gap: 0;
193
+ margin-bottom: var(--spacing-lg);
194
+ border-bottom: 1px solid var(--border-default);
195
+ }
196
+
197
+ .tab-button {
198
+ padding: var(--spacing-sm) var(--spacing-md);
199
+ background: transparent;
200
+ border: none;
201
+ border-bottom: 2px solid transparent;
202
+ color: var(--text-secondary);
203
+ font-size: var(--font-size-md);
204
+ font-weight: var(--font-weight-medium);
205
+ cursor: pointer;
206
+ transition: color var(--transition-fast), border-color var(--transition-fast);
207
+ position: relative;
208
+ top: 1px;
209
+ min-height: 44px;
210
+ }
211
+
212
+ .tab-button:hover {
213
+ color: var(--text-primary);
214
+ }
215
+
216
+ .tab-button:focus-visible {
217
+ outline: 2px solid var(--accent-blue);
218
+ outline-offset: -2px;
219
+ }
220
+
221
+ .tab-button.active {
222
+ color: var(--text-primary);
223
+ border-bottom-color: var(--accent-blue);
224
+ }
225
+
226
+ .tab-content {
227
+ display: none;
228
+ }
229
+
230
+ .tab-content.active {
231
+ display: block;
232
+ }
233
+
234
+ /* === Badges & Labels === */
235
+ .user-badge {
236
+ display: inline-block;
237
+ padding: 2px var(--spacing-sm);
238
+ background: var(--accent-blue-muted);
239
+ border-radius: var(--radius-md);
240
+ font-size: var(--font-size-xs);
241
+ font-weight: var(--font-weight-medium);
242
+ margin-left: var(--spacing-sm);
243
+ color: white;
244
+ }
245
+
246
+ /* === Empty State === */
247
+ .no-data {
248
+ text-align: center;
249
+ color: var(--text-secondary);
250
+ padding: var(--spacing-xl);
251
+ font-size: var(--font-size-md);
252
+ }
253
+
254
+ /* === Utility Classes === */
255
+ .text-muted {
256
+ color: var(--text-muted);
257
+ }
258
+
259
+ .text-secondary {
260
+ color: var(--text-secondary);
261
+ }
262
+
263
+ .text-primary {
264
+ color: var(--text-primary);
265
+ }
266
+
267
+ .text-link {
268
+ color: var(--text-link);
269
+ }
270
+
271
+ .uppercase {
272
+ text-transform: uppercase;
273
+ letter-spacing: 0.5px;
274
+ }
275
+
276
+ .font-mono {
277
+ font-family: var(--font-mono);
278
+ }
279
+
280
+ /* === Button Styles === */
281
+ .btn {
282
+ display: inline-flex;
283
+ align-items: center;
284
+ justify-content: center;
285
+ gap: var(--spacing-sm);
286
+ padding: var(--spacing-sm) var(--spacing-md);
287
+ font-size: var(--font-size-md);
288
+ font-weight: var(--font-weight-medium);
289
+ font-family: inherit;
290
+ border-radius: var(--radius-md);
291
+ cursor: pointer;
292
+ transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
293
+ min-height: 36px;
294
+ text-decoration: none;
295
+ }
296
+
297
+ .btn:focus-visible {
298
+ outline: 2px solid var(--accent-blue);
299
+ outline-offset: 2px;
300
+ }
301
+
302
+ /* Primary Button */
303
+ .btn-primary {
304
+ background: var(--accent-blue-muted);
305
+ border: 1px solid var(--accent-blue-muted);
306
+ color: white;
307
+ }
308
+
309
+ .btn-primary:hover {
310
+ background: var(--accent-blue);
311
+ border-color: var(--accent-blue);
312
+ }
313
+
314
+ /* Secondary Button */
315
+ .btn-secondary {
316
+ background: transparent;
317
+ border: 1px solid var(--border-default);
318
+ color: var(--text-primary);
319
+ }
320
+
321
+ .btn-secondary:hover {
322
+ background: var(--bg-tertiary);
323
+ border-color: var(--border-emphasis);
324
+ }
325
+
326
+ /* Ghost Button */
327
+ .btn-ghost {
328
+ background: transparent;
329
+ border: 1px solid transparent;
330
+ color: var(--text-secondary);
331
+ }
332
+
333
+ .btn-ghost:hover {
334
+ color: var(--text-primary);
335
+ background: var(--bg-tertiary);
336
+ }
337
+
338
+ /* Small Button */
339
+ .btn-sm {
340
+ padding: 6px 12px;
341
+ font-size: var(--font-size-sm);
342
+ min-height: 32px;
343
+ }
344
+
345
+ .btn-icon {
346
+ font-size: var(--font-size-md);
347
+ }
348
+
349
+ /* === Filter Bar === */
350
+ .filter-bar {
351
+ display: flex;
352
+ gap: var(--spacing-lg);
353
+ padding: 12px var(--spacing-md);
354
+ background: var(--bg-tertiary);
355
+ border: 1px solid var(--border-default);
356
+ border-radius: var(--radius-md);
357
+ margin-bottom: var(--spacing-lg);
358
+ flex-wrap: wrap;
359
+ align-items: center;
360
+ }
361
+
362
+ .filter-group {
363
+ display: flex;
364
+ align-items: baseline;
365
+ gap: var(--spacing-sm);
366
+ }
367
+
368
+ .filter-label {
369
+ font-size: var(--font-size-xs);
370
+ font-weight: var(--font-weight-medium);
371
+ color: var(--text-muted);
372
+ text-transform: uppercase;
373
+ letter-spacing: 0.5px;
374
+ }
375
+
376
+ .filter-value {
377
+ font-size: var(--font-size-md);
378
+ color: var(--text-primary);
379
+ }
380
+
381
+ /* === Export Controls === */
382
+ .export-controls {
383
+ display: flex;
384
+ gap: var(--spacing-sm);
385
+ margin-left: auto;
386
+ }
387
+
388
+ /* === Dashboard Header === */
389
+ .dashboard-header {
390
+ display: flex;
391
+ align-items: center;
392
+ justify-content: space-between;
393
+ margin-bottom: var(--spacing-md);
394
+ flex-wrap: wrap;
395
+ gap: var(--spacing-md);
396
+ }
397
+
398
+ .dashboard-header .repo-name {
399
+ margin: 0;
400
+ }
401
+
402
+ .header-left,
403
+ .header-right {
404
+ display: flex;
405
+ align-items: center;
406
+ gap: var(--spacing-md);
407
+ }
408
+
409
+ /* === KPI Header === */
410
+ .kpi-header {
411
+ display: flex;
412
+ gap: var(--spacing-md);
413
+ padding: var(--spacing-md);
414
+ background: var(--bg-tertiary);
415
+ border: 1px solid var(--border-default);
416
+ border-radius: var(--radius-md);
417
+ margin-bottom: var(--spacing-lg);
418
+ flex-wrap: wrap;
419
+ }
420
+
421
+ .kpi-card {
422
+ flex: 1;
423
+ min-width: 120px;
424
+ text-align: center;
425
+ padding: var(--spacing-sm) var(--spacing-md);
426
+ }
427
+
428
+ .kpi-label {
429
+ display: block;
430
+ font-size: var(--font-size-xs);
431
+ color: var(--text-muted);
432
+ text-transform: uppercase;
433
+ letter-spacing: 0.5px;
434
+ font-weight: var(--font-weight-medium);
435
+ margin-bottom: var(--spacing-xs);
436
+ }
437
+
438
+ .kpi-value {
439
+ display: block;
440
+ font-size: 24px;
441
+ font-weight: var(--font-weight-semibold);
442
+ color: var(--text-primary);
443
+ }
444
+
445
+ .kpi-trend {
446
+ display: inline-block;
447
+ font-size: var(--font-size-xs);
448
+ font-weight: var(--font-weight-medium);
449
+ margin-top: var(--spacing-xs);
450
+ }
451
+
452
+ .kpi-trend.trend-up {
453
+ color: var(--accent-green);
454
+ }
455
+
456
+ .kpi-trend.trend-down {
457
+ color: var(--status-danger);
458
+ }
459
+
460
+ .kpi-trend.trend-neutral {
461
+ color: var(--text-muted);
462
+ }
463
+
464
+ /* === Dashboard Layout === */
465
+ .dashboard-layout {
466
+ display: flex;
467
+ gap: var(--spacing-lg);
468
+ }
469
+
470
+ /* === Sidebar Navigation === */
471
+ .sidebar {
472
+ width: 200px;
473
+ flex-shrink: 0;
474
+ position: sticky;
475
+ top: var(--spacing-lg);
476
+ height: fit-content;
477
+ max-height: calc(100vh - var(--spacing-2xl));
478
+ display: flex;
479
+ flex-direction: column;
480
+ background: var(--bg-secondary);
481
+ border: 1px solid var(--border-default);
482
+ border-radius: var(--radius-lg);
483
+ overflow: hidden;
484
+ }
485
+
486
+ .nav-list {
487
+ list-style: none;
488
+ display: flex;
489
+ flex-direction: column;
490
+ gap: var(--spacing-xs);
491
+ }
492
+
493
+ .nav-item {
494
+ display: flex;
495
+ align-items: center;
496
+ gap: var(--spacing-sm);
497
+ padding: var(--spacing-sm) var(--spacing-md);
498
+ border-radius: var(--radius-md);
499
+ cursor: pointer;
500
+ transition: background-color var(--transition-fast);
501
+ color: var(--text-secondary);
502
+ font-size: var(--font-size-sm);
503
+ font-weight: var(--font-weight-medium);
504
+ }
505
+
506
+ .nav-item:hover {
507
+ background: var(--bg-tertiary);
508
+ color: var(--text-primary);
509
+ }
510
+
511
+ .nav-item.active {
512
+ background: var(--bg-tertiary);
513
+ color: var(--text-link);
514
+ }
515
+
516
+ .nav-icon {
517
+ font-size: var(--font-size-lg);
518
+ }
519
+
520
+ .nav-label {
521
+ flex: 1;
522
+ }
523
+
524
+ .nav-badge {
525
+ font-size: var(--font-size-xs);
526
+ padding: 2px 6px;
527
+ background: var(--accent-blue-muted);
528
+ border-radius: var(--radius-sm);
529
+ color: white;
530
+ }
531
+
532
+ .nav-item-small {
533
+ padding: var(--spacing-xs) var(--spacing-md) var(--spacing-xs) calc(var(--spacing-md) + var(--spacing-lg));
534
+ font-size: var(--font-size-xs);
535
+ }
536
+
537
+ .nav-section {
538
+ margin-bottom: var(--spacing-md);
539
+ }
540
+
541
+ .nav-section-title {
542
+ font-size: var(--font-size-xs);
543
+ font-weight: var(--font-weight-semibold);
544
+ text-transform: uppercase;
545
+ letter-spacing: 0.5px;
546
+ color: var(--text-muted);
547
+ padding: var(--spacing-xs) var(--spacing-md);
548
+ margin-bottom: var(--spacing-xs);
549
+ }
550
+
551
+ /* Sidebar Header & Footer */
552
+ .sidebar-header {
553
+ padding: var(--spacing-md);
554
+ margin-bottom: var(--spacing-md);
555
+ display: flex;
556
+ align-items: center;
557
+ justify-content: space-between;
558
+ }
559
+
560
+ .sidebar-header h2 {
561
+ margin: 0;
562
+ font-size: var(--font-size-md);
563
+ font-weight: var(--font-weight-semibold);
564
+ }
565
+
566
+ .sidebar-header .version {
567
+ font-size: var(--font-size-xs);
568
+ color: var(--text-muted);
569
+ background: var(--bg-tertiary);
570
+ padding: 2px 6px;
571
+ border-radius: var(--radius-sm);
572
+ }
573
+
574
+ .sidebar-footer {
575
+ margin-top: auto;
576
+ padding: var(--spacing-md);
577
+ border-top: 1px solid var(--border-default);
578
+ }
579
+
580
+ .repo-info {
581
+ display: flex;
582
+ flex-direction: column;
583
+ gap: var(--spacing-xs);
584
+ }
585
+
586
+ .repo-info .repo-name {
587
+ font-size: var(--font-size-sm);
588
+ font-weight: var(--font-weight-medium);
589
+ color: var(--text-primary);
590
+ overflow: hidden;
591
+ text-overflow: ellipsis;
592
+ white-space: nowrap;
593
+ }
594
+
595
+ .repo-info .repo-link {
596
+ font-size: var(--font-size-xs);
597
+ color: var(--text-link);
598
+ text-decoration: none;
599
+ }
600
+
601
+ .repo-info .repo-link:hover {
602
+ text-decoration: underline;
603
+ }
604
+
605
+ /* Page Header */
606
+ .page-header {
607
+ margin-bottom: var(--spacing-lg);
608
+ }
609
+
610
+ /* Mobile Navigation Toggle */
611
+ .mobile-nav-toggle {
612
+ display: none;
613
+ position: fixed;
614
+ top: var(--spacing-md);
615
+ left: var(--spacing-md);
616
+ z-index: 1001;
617
+ width: 44px;
618
+ height: 44px;
619
+ background: var(--bg-secondary);
620
+ border: 1px solid var(--border-default);
621
+ border-radius: var(--radius-md);
622
+ cursor: pointer;
623
+ justify-content: center;
624
+ align-items: center;
625
+ }
626
+
627
+ .hamburger-icon {
628
+ display: block;
629
+ width: 20px;
630
+ height: 2px;
631
+ background: var(--text-primary);
632
+ position: relative;
633
+ }
634
+
635
+ .hamburger-icon::before,
636
+ .hamburger-icon::after {
637
+ content: '';
638
+ position: absolute;
639
+ width: 20px;
640
+ height: 2px;
641
+ background: var(--text-primary);
642
+ left: 0;
643
+ transition: transform var(--transition-fast);
644
+ }
645
+
646
+ .hamburger-icon::before {
647
+ top: -6px;
648
+ }
649
+
650
+ .hamburger-icon::after {
651
+ bottom: -6px;
652
+ }
653
+
654
+ .mobile-nav-toggle.open .hamburger-icon {
655
+ background: transparent;
656
+ }
657
+
658
+ .mobile-nav-toggle.open .hamburger-icon::before {
659
+ transform: rotate(45deg) translate(4px, 4px);
660
+ }
661
+
662
+ .mobile-nav-toggle.open .hamburger-icon::after {
663
+ transform: rotate(-45deg) translate(4px, -4px);
664
+ }
665
+
666
+ /* === Main Content === */
667
+ .main-content {
668
+ flex: 1;
669
+ min-width: 70vw;
670
+ }
671
+
672
+ /* === Dashboard Section (Collapsible) === */
673
+ .dashboard-section {
674
+ margin-bottom: var(--spacing-lg);
675
+ }
676
+
677
+ .section-header {
678
+ display: flex;
679
+ align-items: center;
680
+ justify-content: space-between;
681
+ padding: var(--spacing-md);
682
+ background: var(--bg-tertiary);
683
+ border: 1px solid var(--border-default);
684
+ border-radius: var(--radius-md);
685
+ margin-bottom: var(--spacing-md);
686
+ cursor: pointer;
687
+ transition: background-color var(--transition-fast);
688
+ }
689
+
690
+ .section-header:hover {
691
+ background: var(--bg-elevated);
692
+ }
693
+
694
+ .section-header h2 {
695
+ margin: 0;
696
+ font-size: var(--font-size-lg);
697
+ }
698
+
699
+ .collapse-icon {
700
+ color: var(--text-muted);
701
+ font-size: var(--font-size-sm);
702
+ transition: transform var(--transition-fast);
703
+ }
704
+
705
+ .section-content {
706
+ overflow: hidden;
707
+ transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
708
+ }
709
+
710
+ .section-content.collapsed {
711
+ max-height: 0;
712
+ opacity: 0;
713
+ margin: 0;
714
+ padding: 0;
715
+ }
716
+
717
+ /* === Hamburger Menu (Mobile) === */
718
+ .hamburger-menu {
719
+ display: none;
720
+ position: fixed;
721
+ top: var(--spacing-md);
722
+ left: var(--spacing-md);
723
+ z-index: 1001;
724
+ width: 40px;
725
+ height: 40px;
726
+ background: var(--bg-secondary);
727
+ border: 1px solid var(--border-default);
728
+ border-radius: var(--radius-md);
729
+ cursor: pointer;
730
+ flex-direction: column;
731
+ justify-content: center;
732
+ align-items: center;
733
+ gap: 4px;
734
+ }
735
+
736
+ .hamburger-line {
737
+ width: 20px;
738
+ height: 2px;
739
+ background: var(--text-primary);
740
+ transition: transform var(--transition-fast);
741
+ }
742
+
743
+ .hamburger-menu.open .hamburger-line:nth-child(1) {
744
+ transform: rotate(45deg) translateY(6px);
745
+ }
746
+
747
+ .hamburger-menu.open .hamburger-line:nth-child(2) {
748
+ opacity: 0;
749
+ }
750
+
751
+ .hamburger-menu.open .hamburger-line:nth-child(3) {
752
+ transform: rotate(-45deg) translateY(-6px);
753
+ }
754
+
755
+ /* === Responsive Design === */
756
+ @media (max-width: 1024px) {
757
+ .mobile-nav-toggle {
758
+ display: flex;
759
+ }
760
+
761
+ .hamburger-menu {
762
+ display: flex;
763
+ }
764
+
765
+ body {
766
+ padding-left: var(--spacing-md);
767
+ }
768
+
769
+ .sidebar {
770
+ position: fixed;
771
+ top: 0;
772
+ left: -250px;
773
+ width: 250px;
774
+ height: 100vh;
775
+ background: var(--bg-secondary);
776
+ border-right: 1px solid var(--border-default);
777
+ padding: var(--spacing-xl) var(--spacing-md);
778
+ padding-top: 70px;
779
+ z-index: 1000;
780
+ transition: left var(--transition-normal);
781
+ overflow-y: auto;
782
+ }
783
+
784
+ .sidebar.open {
785
+ left: 0;
786
+ }
787
+
788
+ .dashboard-layout {
789
+ flex-direction: column;
790
+ }
791
+
792
+ .kpi-header {
793
+ flex-wrap: wrap;
794
+ }
795
+
796
+ .kpi-card {
797
+ min-width: 100px;
798
+ }
799
+
800
+ .tab-nav {
801
+ margin-left: 50px;
802
+ }
803
+ }
804
+
805
+ @media (max-width: 640px) {
806
+ body {
807
+ padding: var(--spacing-md);
808
+ }
809
+
810
+ .container {
811
+ padding: var(--spacing-md);
812
+ }
813
+
814
+ .kpi-card {
815
+ min-width: 80px;
816
+ flex-basis: calc(50% - var(--spacing-sm));
817
+ }
818
+
819
+ .kpi-value {
820
+ font-size: 20px;
821
+ }
822
+ }