repo-wrapped 0.0.2

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