trackops 2.0.2 → 2.0.4

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 (48) hide show
  1. package/README.md +238 -0
  2. package/lib/init.js +2 -2
  3. package/lib/locale.js +41 -17
  4. package/lib/opera-bootstrap.js +68 -7
  5. package/lib/opera.js +10 -2
  6. package/lib/registry.js +18 -0
  7. package/lib/server.js +312 -207
  8. package/locales/en.json +4 -0
  9. package/locales/es.json +4 -0
  10. package/package.json +1 -1
  11. package/skills/trackops/SKILL.md +39 -4
  12. package/skills/trackops/agents/openai.yaml +2 -2
  13. package/skills/trackops/locales/en/SKILL.md +39 -4
  14. package/skills/trackops/locales/en/references/activation.md +15 -0
  15. package/skills/trackops/locales/en/references/troubleshooting.md +12 -0
  16. package/skills/trackops/references/activation.md +15 -0
  17. package/skills/trackops/references/troubleshooting.md +12 -0
  18. package/skills/trackops/skill.json +4 -4
  19. package/ui/css/base.css +19 -1
  20. package/ui/css/charts.css +106 -8
  21. package/ui/css/components.css +554 -17
  22. package/ui/css/onboarding.css +133 -0
  23. package/ui/css/panels.css +345 -406
  24. package/ui/css/terminal.css +125 -0
  25. package/ui/css/timeline.css +58 -0
  26. package/ui/css/tokens.css +170 -113
  27. package/ui/index.html +3 -0
  28. package/ui/js/api.js +49 -13
  29. package/ui/js/app.js +28 -32
  30. package/ui/js/charts.js +526 -0
  31. package/ui/js/filters.js +247 -0
  32. package/ui/js/icons.js +82 -57
  33. package/ui/js/keyboard.js +229 -0
  34. package/ui/js/onboarding.js +33 -42
  35. package/ui/js/router.js +20 -3
  36. package/ui/js/views/board.js +84 -114
  37. package/ui/js/views/dashboard.js +870 -0
  38. package/ui/js/views/projects.js +745 -0
  39. package/ui/js/views/scrum.js +476 -0
  40. package/ui/js/views/settings.js +197 -247
  41. package/ui/js/views/sidebar.js +37 -31
  42. package/ui/js/views/tasks.js +218 -101
  43. package/ui/js/views/timeline.js +265 -0
  44. package/ui/js/views/topbar.js +94 -107
  45. package/ui/app.js +0 -950
  46. package/ui/js/views/insights.js +0 -340
  47. package/ui/js/views/overview.js +0 -369
  48. package/ui/styles.css +0 -688
@@ -31,23 +31,23 @@
31
31
 
32
32
  /* Primary */
33
33
  .btn-primary {
34
- background: linear-gradient(135deg, var(--accent) 0%, #4F46E5 100%);
34
+ background: linear-gradient(135deg, #3B82F6 0%, #60A5FA 100%);
35
35
  color: white;
36
- box-shadow: var(--shadow-accent);
36
+ box-shadow: 0 4px 12px rgba(96, 165, 250, 0.3);
37
37
  }
38
38
  .btn-primary:hover {
39
39
  transform: translateY(-1px);
40
- box-shadow: 0 12px 32px rgba(99,102,241,0.35);
40
+ box-shadow: 0 12px 32px rgba(96, 165, 250, 0.35);
41
41
  }
42
42
 
43
43
  /* Ghost */
44
44
  .btn-ghost {
45
- background: var(--surface-4);
45
+ background: var(--glass-bg-subtle);
46
46
  color: var(--text-secondary);
47
- border-color: var(--border);
47
+ border: 1px solid var(--glass-border);
48
48
  }
49
49
  .btn-ghost:hover {
50
- background: var(--surface-3);
50
+ background: var(--glass-bg);
51
51
  color: var(--text-primary);
52
52
  border-color: var(--border-strong);
53
53
  }
@@ -82,11 +82,19 @@
82
82
  border-radius: var(--radius-md);
83
83
  }
84
84
 
85
- /* Small */
85
+ /* Small — min 44px touch target via padding (WCAG 2.2 AA) */
86
86
  .btn-sm {
87
87
  padding: 0.4rem 0.85rem;
88
88
  font-size: var(--text-xs);
89
- min-height: 28px;
89
+ min-height: 32px;
90
+ position: relative;
91
+ }
92
+ /* Invisible touch target expansion for small buttons */
93
+ .btn-sm::after {
94
+ content: '';
95
+ position: absolute;
96
+ inset: -6px;
97
+ pointer-events: auto;
90
98
  }
91
99
 
92
100
  /* Chip / pill */
@@ -133,7 +141,7 @@
133
141
  letter-spacing: 0.04em;
134
142
  }
135
143
 
136
- .badge-accent { background: var(--accent-light); color: var(--text-accent); border: 1px solid rgba(99,102,241,0.2); }
144
+ .badge-accent { background: var(--accent-light); color: var(--accent); border: 1px solid rgba(96,165,250,0.2); }
137
145
  .badge-success { background: var(--success-light); color: var(--success); border: 1px solid rgba(16,185,129,0.2); }
138
146
  .badge-warning { background: var(--warning-light); color: var(--warning); border: 1px solid rgba(245,158,11,0.2); }
139
147
  .badge-danger { background: var(--danger-light); color: var(--danger); border: 1px solid rgba(239,68,68,0.2); }
@@ -154,19 +162,44 @@
154
162
  .status-completed { background: var(--success-light); color: var(--success); border: 1px solid rgba(16,185,129,0.2); }
155
163
  .status-cancelled { background: var(--surface-3); color: var(--text-muted); border: 1px solid var(--border); }
156
164
 
165
+ /* ── Glass Card ── */
166
+ .glass-card {
167
+ background: var(--glass-bg);
168
+ backdrop-filter: blur(var(--glass-blur));
169
+ -webkit-backdrop-filter: blur(var(--glass-blur));
170
+ border: 1px solid var(--glass-border);
171
+ border-radius: var(--radius-xl);
172
+ box-shadow: var(--glass-shadow), var(--glass-inner);
173
+ }
174
+ .glass-card:hover {
175
+ background: var(--glass-bg-strong);
176
+ border-color: var(--glass-border-hover);
177
+ box-shadow: var(--shadow-md);
178
+ }
179
+
157
180
  /* ───────────────────────────────────
158
181
  CARDS
159
182
  ─────────────────────────────────── */
160
183
  .card {
161
- background: var(--surface-2);
162
- border: 1px solid var(--border);
184
+ background: var(--glass-bg);
185
+ backdrop-filter: blur(var(--glass-blur));
186
+ -webkit-backdrop-filter: blur(var(--glass-blur));
187
+ border: 1px solid var(--glass-border);
163
188
  border-radius: var(--radius-lg);
189
+ box-shadow: var(--glass-shadow), var(--glass-inner);
164
190
  transition:
165
191
  border-color var(--duration-base) var(--ease-out),
166
192
  box-shadow var(--duration-base) var(--ease-out),
167
193
  background var(--duration-base) var(--ease-out);
168
194
  }
169
- .card:hover { border-color: var(--border-strong); }
195
+ .card:hover { border-color: var(--glass-border-hover); box-shadow: var(--shadow-md); }
196
+
197
+ /* Fallback for browsers without backdrop-filter */
198
+ @supports not (backdrop-filter: blur(1px)) {
199
+ .card, .glass-card, .kpi-card, .chart-card, .task-card, .project-card {
200
+ background: var(--gray-800);
201
+ }
202
+ }
170
203
 
171
204
  .card-body { padding: var(--space-5); }
172
205
  .card-sm .card-body { padding: var(--space-4); }
@@ -174,8 +207,10 @@
174
207
 
175
208
  /* KPI metric card */
176
209
  .kpi-card {
177
- background: var(--surface-2);
178
- border: 1px solid var(--border);
210
+ background: var(--glass-bg);
211
+ backdrop-filter: blur(var(--glass-blur));
212
+ -webkit-backdrop-filter: blur(var(--glass-blur));
213
+ border: 1px solid var(--glass-border);
179
214
  border-radius: var(--radius-lg);
180
215
  padding: var(--space-5);
181
216
  display: flex;
@@ -257,8 +292,10 @@
257
292
 
258
293
  /* Task card (kanban) */
259
294
  .task-card {
260
- background: var(--surface-2);
261
- border: 1px solid var(--border);
295
+ background: var(--glass-bg);
296
+ backdrop-filter: blur(var(--glass-blur-sm));
297
+ -webkit-backdrop-filter: blur(var(--glass-blur-sm));
298
+ border: 1px solid var(--glass-border);
262
299
  border-radius: var(--radius-md);
263
300
  padding: var(--space-4);
264
301
  text-align: left;
@@ -272,7 +309,7 @@
272
309
  position: relative;
273
310
  }
274
311
  .task-card:hover {
275
- border-color: var(--border-strong);
312
+ border-color: var(--glass-border-hover);
276
313
  box-shadow: var(--shadow-sm);
277
314
  transform: translateY(-1px);
278
315
  }
@@ -568,3 +605,503 @@ input[type="checkbox"] {
568
605
  .theme-toggle:hover svg {
569
606
  transform: rotate(20deg) scale(1.1);
570
607
  }
608
+
609
+ /* ───────────────────────────────────
610
+ FILTER BAR
611
+ ─────────────────────────────────── */
612
+ .filter-bar {
613
+ display: flex;
614
+ flex-direction: column;
615
+ gap: var(--space-3);
616
+ margin-bottom: var(--space-4);
617
+ }
618
+ .filter-controls {
619
+ display: flex;
620
+ gap: var(--space-2);
621
+ flex-wrap: wrap;
622
+ align-items: center;
623
+ }
624
+ .filter-select {
625
+ min-width: 130px;
626
+ height: 36px;
627
+ font-size: var(--text-sm);
628
+ padding: 0 2rem 0 0.75rem;
629
+ }
630
+ .filter-search {
631
+ flex: 1;
632
+ min-width: 180px;
633
+ }
634
+ .filter-search-input {
635
+ height: 36px;
636
+ font-size: var(--text-sm);
637
+ }
638
+ .filter-active-bar {
639
+ display: flex;
640
+ align-items: center;
641
+ gap: var(--space-2);
642
+ flex-wrap: wrap;
643
+ }
644
+ .filter-clear-all {
645
+ margin-left: auto;
646
+ }
647
+
648
+ /* ───────────────────────────────────
649
+ KEYBOARD HELP PANEL
650
+ ─────────────────────────────────── */
651
+ .kb-help-group {
652
+ margin-bottom: var(--space-4);
653
+ }
654
+ .kb-help-group:last-child {
655
+ margin-bottom: 0;
656
+ }
657
+ .kb-help-group-title {
658
+ font-size: var(--text-xs);
659
+ font-weight: 700;
660
+ letter-spacing: 0.1em;
661
+ text-transform: uppercase;
662
+ color: var(--text-muted);
663
+ margin-bottom: var(--space-3);
664
+ padding-bottom: var(--space-2);
665
+ border-bottom: 1px solid var(--border);
666
+ }
667
+ .kb-help-items {
668
+ display: flex;
669
+ flex-direction: column;
670
+ gap: var(--space-2);
671
+ }
672
+ .kb-help-item {
673
+ display: flex;
674
+ align-items: center;
675
+ justify-content: space-between;
676
+ gap: var(--space-4);
677
+ padding: var(--space-1) 0;
678
+ }
679
+ .kb-help-key {
680
+ display: inline-flex;
681
+ align-items: center;
682
+ gap: var(--space-1);
683
+ padding: 0.2rem 0.5rem;
684
+ background: var(--surface-3);
685
+ border: 1px solid var(--border-strong);
686
+ border-radius: var(--radius-xs);
687
+ font-family: var(--font-mono);
688
+ font-size: var(--text-xs);
689
+ font-weight: 600;
690
+ color: var(--text-primary);
691
+ min-width: 24px;
692
+ text-align: center;
693
+ justify-content: center;
694
+ white-space: nowrap;
695
+ }
696
+ .kb-help-label {
697
+ font-size: var(--text-sm);
698
+ color: var(--text-secondary);
699
+ }
700
+
701
+ /* ───────────────────────────────────
702
+ SKELETON LOADER
703
+ ─────────────────────────────────── */
704
+ .skeleton {
705
+ background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-4) 50%, var(--surface-3) 75%);
706
+ background-size: 200% 100%;
707
+ animation: skeleton-pulse 1.5s ease-in-out infinite;
708
+ border-radius: var(--radius-sm);
709
+ }
710
+ .skeleton-text {
711
+ height: 14px;
712
+ margin-bottom: var(--space-2);
713
+ }
714
+ .skeleton-text:last-child {
715
+ width: 60%;
716
+ }
717
+ .skeleton-card {
718
+ height: 120px;
719
+ border-radius: var(--radius-lg);
720
+ }
721
+ .skeleton-circle {
722
+ border-radius: 50%;
723
+ }
724
+
725
+ @keyframes skeleton-pulse {
726
+ 0% { background-position: 200% 0; }
727
+ 100% { background-position: -200% 0; }
728
+ }
729
+
730
+ /* ───────────────────────────────────
731
+ PROJECT CARDS (vista Projects)
732
+ ─────────────────────────────────── */
733
+ .projects-grid {
734
+ display: grid;
735
+ grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
736
+ gap: var(--space-4);
737
+ }
738
+ @media (max-width: 960px) {
739
+ .projects-grid { grid-template-columns: 1fr; }
740
+ }
741
+
742
+ .project-card {
743
+ background: var(--glass-bg);
744
+ backdrop-filter: blur(var(--glass-blur));
745
+ -webkit-backdrop-filter: blur(var(--glass-blur));
746
+ border: 1px solid var(--glass-border);
747
+ border-radius: var(--radius-xl);
748
+ padding: var(--space-5);
749
+ display: flex;
750
+ flex-direction: column;
751
+ gap: var(--space-4);
752
+ box-shadow: var(--glass-shadow), var(--glass-inner);
753
+ transition:
754
+ border-color var(--duration-fast) var(--ease-out),
755
+ box-shadow var(--duration-base) var(--ease-out),
756
+ transform var(--duration-base) var(--ease-out);
757
+ }
758
+ .project-card:hover {
759
+ border-color: var(--glass-border-hover);
760
+ box-shadow: var(--shadow-md);
761
+ transform: translateY(-2px);
762
+ }
763
+ .project-card.is-current {
764
+ border-color: var(--border-accent);
765
+ background: linear-gradient(135deg, var(--surface-2), rgba(99,102,241,0.04));
766
+ }
767
+ .project-card.is-unavailable {
768
+ opacity: 0.6;
769
+ }
770
+ .project-card.is-unavailable:hover {
771
+ transform: none;
772
+ box-shadow: none;
773
+ }
774
+
775
+ .project-card-header {
776
+ display: flex;
777
+ align-items: flex-start;
778
+ justify-content: space-between;
779
+ gap: var(--space-3);
780
+ }
781
+ .project-card-info { min-width: 0; flex: 1; }
782
+ .project-card-name {
783
+ font-size: var(--text-md);
784
+ font-weight: 800;
785
+ font-family: var(--font-heading);
786
+ color: var(--text-primary);
787
+ margin: 0;
788
+ }
789
+ .project-card-path {
790
+ font-size: var(--text-xs);
791
+ font-family: var(--font-mono);
792
+ color: var(--text-muted);
793
+ overflow: hidden;
794
+ text-overflow: ellipsis;
795
+ white-space: nowrap;
796
+ margin-top: var(--space-1);
797
+ }
798
+ .project-card-badges {
799
+ display: flex;
800
+ gap: var(--space-2);
801
+ flex-wrap: wrap;
802
+ flex-shrink: 0;
803
+ }
804
+
805
+ .project-metrics-grid {
806
+ display: grid;
807
+ grid-template-columns: repeat(5, 1fr);
808
+ gap: var(--space-2);
809
+ }
810
+ .project-metric {
811
+ text-align: center;
812
+ padding: var(--space-2);
813
+ background: var(--surface-3);
814
+ border-radius: var(--radius-md);
815
+ border: 1px solid var(--border);
816
+ }
817
+ .project-metric-value {
818
+ display: block;
819
+ font-family: var(--font-heading);
820
+ font-size: var(--text-lg);
821
+ font-weight: 800;
822
+ color: var(--text-primary);
823
+ line-height: 1.2;
824
+ }
825
+ .project-metric-label {
826
+ display: block;
827
+ font-size: 0.65rem;
828
+ font-weight: 600;
829
+ color: var(--text-muted);
830
+ text-transform: uppercase;
831
+ letter-spacing: 0.08em;
832
+ margin-top: var(--space-1);
833
+ }
834
+
835
+ .project-progress-track {
836
+ width: 100%;
837
+ height: 6px;
838
+ background: var(--surface-3);
839
+ border-radius: var(--radius-full);
840
+ overflow: hidden;
841
+ }
842
+ .project-progress-fill {
843
+ height: 100%;
844
+ background: linear-gradient(90deg, var(--accent), var(--success));
845
+ border-radius: var(--radius-full);
846
+ transition: width var(--duration-slow) var(--ease-out);
847
+ }
848
+
849
+ .project-card-meta {
850
+ display: flex;
851
+ gap: var(--space-4);
852
+ flex-wrap: wrap;
853
+ }
854
+
855
+ .project-card-actions {
856
+ display: flex;
857
+ gap: var(--space-2);
858
+ flex-wrap: wrap;
859
+ padding-top: var(--space-3);
860
+ border-top: 1px solid var(--border);
861
+ }
862
+
863
+ .project-card-metrics.is-disabled {
864
+ opacity: 0.4;
865
+ pointer-events: none;
866
+ }
867
+
868
+ /* ── Project card name row + info tooltip ── */
869
+ .project-card-name-row {
870
+ display: flex;
871
+ align-items: center;
872
+ gap: var(--space-2);
873
+ position: relative;
874
+ }
875
+ .project-info-btn {
876
+ display: flex;
877
+ align-items: center;
878
+ justify-content: center;
879
+ color: var(--text-muted);
880
+ opacity: 0;
881
+ transition: opacity var(--duration-fast), color var(--duration-fast);
882
+ }
883
+ .project-card:hover .project-info-btn { opacity: 1; }
884
+ .project-info-btn:hover { color: var(--accent); }
885
+ .project-info-tooltip {
886
+ position: absolute;
887
+ top: 100%;
888
+ left: 0;
889
+ z-index: var(--z-panel);
890
+ min-width: 280px;
891
+ background: var(--glass-bg-strong);
892
+ backdrop-filter: blur(var(--glass-blur-lg));
893
+ -webkit-backdrop-filter: blur(var(--glass-blur-lg));
894
+ border: 1px solid var(--glass-border);
895
+ border-radius: var(--radius-md);
896
+ padding: var(--space-3);
897
+ box-shadow: var(--shadow-lg);
898
+ margin-top: var(--space-2);
899
+ display: flex;
900
+ flex-direction: column;
901
+ gap: var(--space-1);
902
+ }
903
+ .project-info-tooltip.is-hidden { display: none; }
904
+ .tooltip-row {
905
+ display: flex;
906
+ justify-content: space-between;
907
+ gap: var(--space-3);
908
+ font-size: var(--text-xs);
909
+ }
910
+ .tooltip-label {
911
+ color: var(--text-muted);
912
+ white-space: nowrap;
913
+ }
914
+ .tooltip-value {
915
+ color: var(--text-secondary);
916
+ font-family: var(--font-mono);
917
+ text-align: right;
918
+ overflow: hidden;
919
+ text-overflow: ellipsis;
920
+ white-space: nowrap;
921
+ max-width: 200px;
922
+ }
923
+
924
+ /* ── Card indicators (health, deadline, priority) ── */
925
+ .project-card-indicators {
926
+ display: flex;
927
+ align-items: center;
928
+ gap: var(--space-3);
929
+ flex-wrap: wrap;
930
+ }
931
+ .project-indicator {
932
+ display: flex;
933
+ align-items: center;
934
+ gap: var(--space-1);
935
+ font-size: var(--text-xs);
936
+ color: var(--text-secondary);
937
+ }
938
+ .indicator-dot {
939
+ width: 8px;
940
+ height: 8px;
941
+ border-radius: 50%;
942
+ flex-shrink: 0;
943
+ }
944
+ .indicator-label {
945
+ font-weight: 600;
946
+ }
947
+
948
+ /* ── Portfolio KPIs ── */
949
+ .portfolio-kpi-grid {
950
+ display: grid;
951
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
952
+ gap: var(--space-3);
953
+ margin-bottom: var(--space-4);
954
+ }
955
+ .portfolio-kpi {
956
+ display: flex;
957
+ align-items: center;
958
+ gap: var(--space-3);
959
+ padding: var(--space-4);
960
+ }
961
+ .portfolio-kpi-icon {
962
+ display: flex;
963
+ align-items: center;
964
+ justify-content: center;
965
+ color: var(--text-muted);
966
+ flex-shrink: 0;
967
+ }
968
+ .portfolio-kpi-value {
969
+ display: block;
970
+ font-family: var(--font-heading);
971
+ font-size: var(--text-2xl);
972
+ font-weight: 800;
973
+ line-height: 1;
974
+ color: var(--text-primary);
975
+ }
976
+ .portfolio-kpi-label {
977
+ display: block;
978
+ font-size: var(--text-xs);
979
+ color: var(--text-muted);
980
+ margin-top: 2px;
981
+ }
982
+ .portfolio-kpi.kpi-danger { border-color: rgba(248,113,113,0.3); }
983
+ .portfolio-kpi.kpi-warning { border-color: rgba(250,204,21,0.3); }
984
+
985
+ /* ── Portfolio analytics ── */
986
+ .portfolio-analytics {
987
+ display: grid;
988
+ grid-template-columns: 1fr 1fr 1fr;
989
+ gap: var(--space-4);
990
+ margin-bottom: var(--space-5);
991
+ }
992
+ @media (max-width: 1100px) {
993
+ .portfolio-analytics { grid-template-columns: 1fr; }
994
+ }
995
+ .portfolio-chart, .portfolio-attention {
996
+ padding: var(--space-4);
997
+ }
998
+ .portfolio-attention {
999
+ max-height: 260px;
1000
+ overflow-y: auto;
1001
+ }
1002
+ .attention-item {
1003
+ display: flex;
1004
+ align-items: center;
1005
+ gap: var(--space-2);
1006
+ padding: var(--space-2) 0;
1007
+ border-bottom: 1px solid var(--border);
1008
+ }
1009
+ .attention-item:last-child { border-bottom: none; }
1010
+ .attention-dot {
1011
+ width: 6px;
1012
+ height: 6px;
1013
+ border-radius: 50%;
1014
+ flex-shrink: 0;
1015
+ }
1016
+
1017
+ /* ── Donut legend ── */
1018
+ .donut-legend {
1019
+ display: flex;
1020
+ flex-direction: column;
1021
+ gap: var(--space-1);
1022
+ }
1023
+ .donut-legend-item {
1024
+ display: flex;
1025
+ align-items: center;
1026
+ gap: var(--space-2);
1027
+ font-size: var(--text-xs);
1028
+ color: var(--text-secondary);
1029
+ }
1030
+ .donut-legend-dot {
1031
+ width: 8px;
1032
+ height: 8px;
1033
+ border-radius: 50%;
1034
+ flex-shrink: 0;
1035
+ }
1036
+
1037
+ /* Section header (reusable en views) */
1038
+ .section-header {
1039
+ display: flex;
1040
+ align-items: flex-start;
1041
+ justify-content: space-between;
1042
+ gap: var(--space-4);
1043
+ margin-bottom: var(--space-5);
1044
+ flex-wrap: wrap;
1045
+ }
1046
+ .section-header-left { min-width: 0; }
1047
+ .section-header-right {
1048
+ display: flex;
1049
+ align-items: center;
1050
+ gap: var(--space-2);
1051
+ flex-shrink: 0;
1052
+ }
1053
+ .eyebrow {
1054
+ font-size: var(--text-xs);
1055
+ font-weight: 700;
1056
+ letter-spacing: 0.12em;
1057
+ text-transform: uppercase;
1058
+ color: var(--accent);
1059
+ margin-bottom: var(--space-1);
1060
+ }
1061
+
1062
+ /* ───────────────────────────────────
1063
+ TAB PILLS
1064
+ ─────────────────────────────────── */
1065
+ .tab-pills {
1066
+ display: inline-flex;
1067
+ gap: 2px;
1068
+ padding: 3px;
1069
+ background: var(--glass-bg-subtle);
1070
+ backdrop-filter: blur(var(--glass-blur-sm));
1071
+ -webkit-backdrop-filter: blur(var(--glass-blur-sm));
1072
+ border: 1px solid var(--glass-border);
1073
+ border-radius: var(--radius-full);
1074
+ }
1075
+ .tab-pill {
1076
+ padding: 0.4rem 1rem;
1077
+ border: none;
1078
+ background: transparent;
1079
+ color: var(--text-secondary);
1080
+ font-family: var(--font-ui);
1081
+ font-size: var(--text-sm);
1082
+ font-weight: 600;
1083
+ border-radius: var(--radius-full);
1084
+ cursor: pointer;
1085
+ transition: all var(--duration-fast) var(--ease-out);
1086
+ white-space: nowrap;
1087
+ }
1088
+ .tab-pill:hover {
1089
+ color: var(--text-primary);
1090
+ background: var(--surface-4);
1091
+ }
1092
+ .tab-pill.is-active {
1093
+ background: var(--accent);
1094
+ color: #fff;
1095
+ box-shadow: 0 2px 8px rgba(96, 165, 250, 0.25);
1096
+ }
1097
+
1098
+ /* ───────────────────────────────────
1099
+ CHART CARD (glass)
1100
+ ─────────────────────────────────── */
1101
+ .chart-card {
1102
+ background: var(--glass-bg);
1103
+ backdrop-filter: blur(var(--glass-blur));
1104
+ -webkit-backdrop-filter: blur(var(--glass-blur));
1105
+ border: 1px solid var(--glass-border);
1106
+ box-shadow: var(--glass-shadow), var(--glass-inner);
1107
+ }