@howssatoshi/quantumcss 1.4.0 → 1.4.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howssatoshi/quantumcss",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Advanced utility-first CSS framework with JIT generation and modern components",
5
5
  "main": "dist/quantum.min.css",
6
6
  "bin": {
package/src/defaults.js CHANGED
@@ -62,6 +62,24 @@ const utilityMaps = {
62
62
  'overflow-visible': { property: 'overflow', value: 'visible' },
63
63
  'border-none': { property: 'border-width', value: '0' },
64
64
  'bg-transparent': { property: 'background-color', value: 'transparent' },
65
+ 'relative': { property: 'position', value: 'relative' },
66
+ 'absolute': { property: 'position', value: 'absolute' },
67
+ 'top-1/2': { property: 'top', value: '50%' },
68
+ 'left-4': { property: 'left', value: '1rem' },
69
+ 'pl-12': { property: 'padding-left', value: '3rem' },
70
+ '-translate-y-1/2': { property: 'transform', value: 'translateY(-50%)' },
71
+ 'pointer-events-none': { property: 'pointer-events', value: 'none' },
72
+ 'w-5': { property: 'width', value: '1.25rem' },
73
+ 'h-5': { property: 'height', value: '1.25rem' },
74
+ 'z-10': { property: 'z-index', value: '10' },
75
+ 'form-row': {
76
+ property: ['display', 'justify-content', 'align-items', 'gap'],
77
+ value: ['flex', 'space-between', 'center', '1rem']
78
+ },
79
+ 'dialog-close': {
80
+ property: ['position', 'top', 'right', 'width', 'height', 'border-radius', 'display', 'align-items', 'justify-content', 'cursor'],
81
+ value: ['absolute', '1.5rem', '1.5rem', '2rem', '2rem', '50%', 'flex', 'center', 'center', 'pointer']
82
+ },
65
83
  'glass': {
66
84
  property: ['background-color', 'backdrop-filter', '-webkit-backdrop-filter', 'border-width', 'border-color'],
67
85
  value: ['rgba(255, 255, 255, 0.03)', 'blur(16px)', 'blur(16px)', '1px', 'rgba(255, 255, 255, 0.1)']
@@ -74,11 +92,11 @@ const utilityMaps = {
74
92
  },
75
93
  'btn-starlight': {
76
94
  property: ['background', 'color', 'border', 'box-shadow', 'font-weight', 'transition', 'height', 'padding', 'display', 'align-items', 'justify-content', 'border-radius', 'cursor'],
77
- value: ['linear-gradient(135deg, #ffb38a 0%, #00d4ff 100%)', '#000', 'none', '0 0 20px rgba(0, 212, 255, 0.3)', '700', 'all 0.2s ease', '3rem', '0 1.5rem', 'inline-flex', 'center', 'center', '0.75rem', 'pointer']
95
+ value: ['linear-gradient(135deg, #ffb38a 0%, #00d4ff 100%)', '#000', 'none', '0 0 20px rgba(0, 212, 255, 0.3)', '700', 'all 0.2s ease', '3rem', '0 1.5rem', 'inline-flex', 'center', 'center', '0.5rem', 'pointer']
78
96
  },
79
97
  'btn-secondary': {
80
98
  property: ['background', 'color', 'border', 'font-weight', 'transition', 'height', 'padding', 'display', 'align-items', 'justify-content', 'border-radius', 'cursor', 'backdrop-filter', '-webkit-backdrop-filter'],
81
- value: ['rgba(255, 255, 255, 0.05)', '#ffffff', '1px solid rgba(255, 255, 255, 0.15)', '700', 'all 0.2s ease', '3rem', '0 1.5rem', 'inline-flex', 'center', 'center', '0.75rem', 'pointer', 'blur(12px)', 'blur(12px)']
99
+ value: ['rgba(255, 255, 255, 0.05)', '#ffffff', '1px solid rgba(255, 255, 255, 0.15)', '700', 'all 0.2s ease', '3rem', '0 1.5rem', 'inline-flex', 'center', 'center', '0.5rem', 'pointer', 'blur(12px)', 'blur(12px)']
82
100
  },
83
101
  'input-starlight': {
84
102
  property: ['background-color', 'border', 'color', 'border-radius', 'padding', 'appearance', 'transition', 'height'],
@@ -88,10 +106,23 @@ const utilityMaps = {
88
106
  property: ['background-color', 'border', 'color', 'border-radius', 'padding', 'appearance', 'transition', 'min-height', 'width', 'display'],
89
107
  value: ['rgba(255, 255, 255, 0.04)', '1px solid rgba(255, 255, 255, 0.15)', 'inherit', '0.75rem', '1rem', 'none', 'all 0.2s ease', '8rem', '100%', 'block']
90
108
  },
91
- 'checkbox-starlight': {
92
- property: ['appearance', 'width', 'height', 'background', 'border', 'border-radius', 'cursor', 'transition', 'position', 'display', 'align-items', 'justify-content'],
93
- value: ['none', '1.25rem', '1.25rem', 'rgba(255, 255, 255, 0.05)', '1px solid rgba(255, 255, 255, 0.2)', '0.375rem', 'pointer', 'all 0.2s ease', 'relative', 'inline-flex', 'center', 'center']
94
- }
95
- };
96
-
97
- module.exports = { defaultTheme, utilityMaps };
109
+ 'checkbox-starlight': {
110
+ property: ['appearance', 'width', 'height', 'background', 'border', 'border-radius', 'cursor', 'transition', 'position', 'display', 'align-items', 'justify-content'],
111
+ value: ['none', '1.25rem', '1.25rem', 'rgba(255, 255, 255, 0.05)', '1px solid rgba(255, 255, 255, 0.2)', '0.375rem', 'pointer', 'all 0.2s ease', 'relative', 'inline-flex', 'center', 'center']
112
+ },
113
+ 'search-container': 'relative block w-full',
114
+ 'search-input': 'pl-12 w-full',
115
+ 'search-icon': 'absolute left-4 top-1/2 -translate-y-1/2 pointer-events-none z-10 w-5 h-5',
116
+ 'nav-glass': {
117
+ property: ['background', 'backdrop-filter', '-webkit-backdrop-filter', 'border-bottom', 'width', 'display', 'flex-direction', 'padding', 'position', 'top', 'z-index'],
118
+ value: ['rgba(255, 255, 255, 0.05)', 'blur(24px)', 'blur(24px)', '1px solid rgba(255, 255, 255, 0.1)', '100%', 'flex', 'column', '0', 'sticky', '0', '1000']
119
+ },
120
+ 'starlight-nav': 'nav-glass w-full sticky top-0 z-[1000]',
121
+ 'starlight-search': 'search-container w-full max-w-144',
122
+ 'starlight-dashboard': 'dashboard-grid grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8',
123
+ 'starlight-gallery': 'starlight-gallery grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4',
124
+ 'starlight-form': 'starlight-card grid grid-cols-1 md:grid-cols-2 gap-8',
125
+ 'starlight-dialog': 'starlight-dialog ani-scale-in'
126
+ };
127
+
128
+ module.exports = { defaultTheme, utilityMaps };
package/src/generator.js CHANGED
@@ -77,7 +77,7 @@ function generateCSS(configPath) {
77
77
  gap: 'gap', 'gap-x': 'column-gap', 'gap-y': 'row-gap'
78
78
  };
79
79
 
80
- function getRulesForClass(fullCls) {
80
+ function getRulesForClass(fullCls, processedPresets = new Set()) {
81
81
  let cls = fullCls, variant = null, breakpoint = null, isNeg = false;
82
82
  if (cls.startsWith('-')) { isNeg = true; cls = cls.substring(1); }
83
83
  const parts = cls.split(':');
@@ -86,22 +86,23 @@ function generateCSS(configPath) {
86
86
  const p = parts[currentPart];
87
87
  if (breakpoints[p]) { breakpoint = p; }
88
88
  else if (p === 'dark') { breakpoint = 'dark'; }
89
+ else if (p === 'light') { breakpoint = 'light'; }
89
90
  else if (['hover', 'focus', 'placeholder', 'group-hover'].includes(p)) { variant = p; }
90
91
  else { cls = parts.slice(currentPart).join(':'); break; }
91
92
  currentPart++;
92
93
  }
93
94
 
94
- // Check Presets
95
- if (config.componentPresets && config.componentPresets[cls]) {
96
- const presetClasses = config.componentPresets[cls].split(/\s+/);
95
+ // Check Presets (User Config & Defaults)
96
+ const presetValue = (config.componentPresets && config.componentPresets[cls]) || (utilityMaps[cls] && typeof utilityMaps[cls] === 'string' ? utilityMaps[cls] : null);
97
+
98
+ if (presetValue && !processedPresets.has(cls)) {
99
+ processedPresets.add(cls);
100
+ const presetClasses = presetValue.split(/\s+/);
97
101
  let allGroups = [];
98
102
  presetClasses.forEach(pCls => {
99
- const subGroups = getRulesForClass(pCls);
103
+ const subGroups = getRulesForClass(pCls, new Set(processedPresets));
100
104
  if (subGroups) {
101
105
  subGroups.forEach(group => {
102
- // Apply the preset's own breakpoint/variant to sub-groups if they don't have one?
103
- // Actually, usually presets are used as base classes.
104
- // If someone does md:btn-primary, we want the md: to apply to all rules in the preset.
105
106
  allGroups.push({
106
107
  breakpoint: breakpoint || group.breakpoint,
107
108
  variant: variant || group.variant,
@@ -114,9 +115,9 @@ function generateCSS(configPath) {
114
115
  }
115
116
 
116
117
  let property = null, value = null, customSelector = null;
117
- if (utilityMaps[cls]) {
118
+ if (utilityMaps[cls] && typeof utilityMaps[cls] === 'object') {
118
119
  const entry = utilityMaps[cls];
119
- if (typeof entry === 'object' && !Array.isArray(entry)) { property = entry.property; value = entry.value; }
120
+ if (!Array.isArray(entry)) { property = entry.property; value = entry.value; }
120
121
  else { property = entry; }
121
122
  }
122
123
 
@@ -135,7 +136,16 @@ function generateCSS(configPath) {
135
136
  if (theme.fontSize[valKey]) { property = ['font-size', 'line-height']; value = [theme.fontSize[valKey], (valKey.includes('xl') || parseInt(valKey) >= 3) ? '1.2' : '1.5']; }
136
137
  else { const color = resolveColor(valKey); if (color) { property = 'color'; value = color; } }
137
138
  } else if (prefix === 'bg') { const color = resolveColor(valKey); if (color) { property = 'background-color'; value = color; } }
138
- else if (prefix === 'z') { property = 'z-index'; value = isNeg ? `-${valKey}` : valKey; }
139
+ else if (prefix === 'z') {
140
+ if (valKey.startsWith('[') && valKey.endsWith(']')) value = valKey.slice(1, -1);
141
+ else value = isNeg ? `-${valKey}` : valKey;
142
+ property = 'z-index';
143
+ }
144
+ else if (prefix === 'top') {
145
+ property = 'top';
146
+ if (valKey.startsWith('[') && valKey.endsWith(']')) value = valKey.slice(1, -1);
147
+ else value = theme.spacing[valKey] || valKey;
148
+ }
139
149
  else if (prefix === 'aspect') {
140
150
  property = ['aspect-ratio', 'width', 'height'];
141
151
  let ratio = 'auto';
@@ -186,7 +196,11 @@ function generateCSS(configPath) {
186
196
  else if (v.includes('/')) v = `${(parseInt(v.split('/')[0])/parseInt(v.split('/')[1])*100).toFixed(2)}%`;
187
197
  else v = theme.spacing[v] || v;
188
198
  value = isNeg ? (Array.isArray(v) ? v.map(x => `-${x}`) : `-${v}`) : v;
189
- } else if (prefix === 'border') {
199
+ } else if (prefix === 'shadow') {
200
+ if (theme.shadows[valKey]) { property = 'box-shadow'; value = theme.shadows[valKey]; }
201
+ else if (valKey === '') { property = 'box-shadow'; value = theme.shadows.md || '0 4px 6px -1px rgb(0 0 0 / 0.1)'; }
202
+ }
203
+ else if (prefix === 'border') {
190
204
  const color = resolveColor(valKey);
191
205
  if (color) { property = 'border-color'; value = color; }
192
206
  else if (['l', 'r', 't', 'b'].includes(cParts[1])) {
@@ -225,11 +239,19 @@ function generateCSS(configPath) {
225
239
  let selector = customSelector || `.${escapedFull}`;
226
240
  if (variant) { if (variant === 'group-hover') selector = `.group:hover ${selector}`; else selector += `:${variant}`}
227
241
 
228
- const block = `${selector} {
242
+ if (breakpoint === 'light') {
243
+ const block = `body.light-mode ${selector} {
229
244
  ${rules.join('\n')}
230
245
  }
231
246
  `;
232
- if (breakpoint) responsiveUtils[breakpoint].add(block); else utilities.add(block);
247
+ utilities.add(block);
248
+ } else {
249
+ const block = `${selector} {
250
+ ${rules.join('\n')}
251
+ }
252
+ `;
253
+ if (breakpoint) responsiveUtils[breakpoint].add(block); else utilities.add(block);
254
+ }
233
255
  });
234
256
  }
235
257
 
package/src/starlight.js CHANGED
@@ -35,6 +35,137 @@ const Starlight = {
35
35
  container.appendChild(star);
36
36
  }
37
37
  });
38
+ },
39
+
40
+ /**
41
+ * Initializes navigation menu toggles for mobile view.
42
+ * Expects a toggle element with class '.hamburger' and a menu with class '.nav-menu-mobile'.
43
+ */
44
+ initNavigation() {
45
+ const toggles = document.querySelectorAll('.hamburger');
46
+
47
+ toggles.forEach(toggle => {
48
+ // Find the closest navigation container or parent
49
+ const nav = toggle.closest('nav') || toggle.closest('.starlight-nav') || toggle.parentElement;
50
+ if (!nav) return;
51
+
52
+ // Find the menu - it might be inside the nav or a sibling
53
+ let menu = nav.querySelector('.nav-menu-mobile');
54
+ if (!menu && nav.nextElementSibling && nav.nextElementSibling.classList.contains('nav-menu-mobile')) {
55
+ menu = nav.nextElementSibling;
56
+ }
57
+
58
+ if (menu) {
59
+ toggle.addEventListener('click', (e) => {
60
+ e.stopPropagation();
61
+ const isActive = toggle.classList.toggle('active');
62
+ menu.classList.toggle('active', isActive);
63
+ });
64
+
65
+ // Close menu when clicking outside
66
+ document.addEventListener('click', (e) => {
67
+ if (!menu.contains(e.target) && !toggle.contains(e.target)) {
68
+ menu.classList.remove('active');
69
+ toggle.classList.remove('active');
70
+ }
71
+ });
72
+ }
73
+ });
74
+ },
75
+
76
+ /**
77
+ * Initializes dropdown menus.
78
+ * Toggles '.active' class on '.dropdown' elements when clicked.
79
+ */
80
+ initDropdowns() {
81
+ const dropdowns = document.querySelectorAll('.dropdown');
82
+
83
+ dropdowns.forEach(dropdown => {
84
+ const toggle = dropdown.querySelector('.dropdown-toggle') || dropdown.querySelector('button') || dropdown.querySelector('a');
85
+
86
+ if (toggle) {
87
+ toggle.addEventListener('click', (e) => {
88
+ // If it's a link that points somewhere, let it work normally
89
+ if (toggle.tagName === 'A' && toggle.getAttribute('href') && toggle.getAttribute('href') !== '#') {
90
+ return;
91
+ }
92
+
93
+ e.preventDefault();
94
+ e.stopPropagation();
95
+
96
+ const isActive = dropdown.classList.contains('active');
97
+
98
+ // Close all other dropdowns
99
+ document.querySelectorAll('.dropdown.active').forEach(d => {
100
+ if (d !== dropdown) d.classList.remove('active');
101
+ });
102
+
103
+ dropdown.classList.toggle('active', !isActive);
104
+ });
105
+ }
106
+ });
107
+
108
+ // Close dropdowns when clicking outside
109
+ document.addEventListener('click', (e) => {
110
+ if (!e.target.closest('.dropdown')) {
111
+ document.querySelectorAll('.dropdown.active').forEach(d => {
112
+ d.classList.remove('active');
113
+ });
114
+ }
115
+ });
116
+ },
117
+
118
+ /**
119
+ * Initializes accordion components.
120
+ * Toggles '.active' class on '.accordion-item' when header is clicked.
121
+ */
122
+ initAccordions() {
123
+ const headers = document.querySelectorAll('.accordion-header');
124
+
125
+ headers.forEach(header => {
126
+ header.addEventListener('click', () => {
127
+ const item = header.parentElement;
128
+ const group = item.closest('.accordion-group');
129
+ const isActive = item.classList.contains('active');
130
+
131
+ // If in a group, close others
132
+ if (group) {
133
+ group.querySelectorAll('.accordion-item').forEach(i => i.classList.remove('active'));
134
+ }
135
+
136
+ item.classList.toggle('active', !isActive);
137
+ });
138
+ });
139
+ },
140
+
141
+ /**
142
+ * Initializes tab components.
143
+ * Switches '.active' class on buttons and panels.
144
+ */
145
+ initTabs() {
146
+ const tabLists = document.querySelectorAll('.tab-list');
147
+
148
+ tabLists.forEach(list => {
149
+ const buttons = list.querySelectorAll('.tab-button');
150
+ const container = list.parentElement;
151
+
152
+ buttons.forEach(button => {
153
+ button.addEventListener('click', () => {
154
+ const targetId = button.getAttribute('data-tab');
155
+ if (!targetId) return;
156
+
157
+ // Update buttons
158
+ buttons.forEach(btn => btn.classList.remove('active'));
159
+ button.classList.add('active');
160
+
161
+ // Update panels
162
+ const panels = container.querySelectorAll('.tab-panel');
163
+ panels.forEach(panel => {
164
+ panel.classList.toggle('active', panel.id === targetId);
165
+ });
166
+ });
167
+ });
168
+ });
38
169
  }
39
170
  };
40
171
 
@@ -45,5 +176,9 @@ if (typeof window !== 'undefined') {
45
176
  if (document.querySelector('.starlight-stars')) {
46
177
  Starlight.initStars();
47
178
  }
179
+ Starlight.initNavigation();
180
+ Starlight.initDropdowns();
181
+ Starlight.initAccordions();
182
+ Starlight.initTabs();
48
183
  });
49
184
  }
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * QuantumCSS + Starlight UI
3
3
  * Advanced utility-first framework with ethereal cosmic aesthetics
4
- * Version: 1.4.0
4
+ * Version: 1.4.2
5
5
  * Features: Modern CSS, JIT Engine, Starlight Components, Dark Mode
6
6
  */
7
7
 
@@ -350,8 +350,8 @@ textarea {
350
350
  .bg-warning { background-color: var(--color-warning); }
351
351
  .bg-error { background-color: var(--color-error); }
352
352
  .bg-neutral { background-color: var(--color-neutral); }
353
- .bg-white { background-color: #ffffff; }
354
- .bg-black { background-color: #000000; }
353
+ .bg-white { background-color: #ffffff; color: #0f172a; }
354
+ .bg-black { background-color: #000000; color: #ffffff; }
355
355
 
356
356
  /* Border Utilities */
357
357
  .border-0 { border-width: 0px; }
@@ -158,12 +158,18 @@ body.light-mode .btn-secondary {
158
158
  /* Card Component */
159
159
  .card {
160
160
  background-color: white;
161
+ color: #1e293b;
161
162
  border-radius: var(--radius-lg);
162
163
  box-shadow: var(--shadow-md);
163
164
  overflow: hidden;
164
165
  transition: all var(--duration-200) var(--ease-in-out);
165
166
  }
166
167
 
168
+ body.light-mode .card {
169
+ background-color: white;
170
+ color: #1e293b;
171
+ }
172
+
167
173
  .card:hover {
168
174
  box-shadow: var(--shadow-lg);
169
175
  transform: translateY(-2px);
@@ -182,6 +188,12 @@ body.light-mode .btn-secondary {
182
188
  padding: var(--space-6);
183
189
  border-top: 1px solid #e5e7eb;
184
190
  background-color: #f9fafb;
191
+ color: #1e293b;
192
+ }
193
+
194
+ body.light-mode .card-footer {
195
+ background-color: #f9fafb;
196
+ color: #1e293b;
185
197
  }
186
198
 
187
199
  /* Input Component */
@@ -192,10 +204,16 @@ body.light-mode .btn-secondary {
192
204
  border: 1px solid #d1d5db;
193
205
  border-radius: var(--radius-md);
194
206
  background-color: white;
207
+ color: #1e293b;
195
208
  font-size: 1rem;
196
209
  transition: all var(--duration-150) var(--ease-in-out);
197
210
  }
198
211
 
212
+ body.light-mode .input {
213
+ background-color: white;
214
+ color: #1e293b;
215
+ }
216
+
199
217
  textarea.input {
200
218
  min-height: 100px;
201
219
  }
@@ -237,6 +255,11 @@ input[type="date"]::-webkit-calendar-picker-indicator {
237
255
  cursor: not-allowed;
238
256
  }
239
257
 
258
+ body.light-mode .input:disabled {
259
+ background-color: #f3f4f6;
260
+ color: #6b7280;
261
+ }
262
+
240
263
  .input-error {
241
264
  border-color: var(--color-error);
242
265
  }
@@ -366,6 +389,7 @@ body.light-mode .badge-error {
366
389
 
367
390
  .modal-content {
368
391
  background-color: white;
392
+ color: #1e293b;
369
393
  border-radius: var(--radius-lg);
370
394
  box-shadow: var(--shadow-2xl);
371
395
  max-width: 90vw;
@@ -373,6 +397,11 @@ body.light-mode .badge-error {
373
397
  overflow-y: auto;
374
398
  }
375
399
 
400
+ body.light-mode .modal-content {
401
+ background-color: white;
402
+ color: #1e293b;
403
+ }
404
+
376
405
  /* Loading Spinner */
377
406
  .spinner {
378
407
  display: inline-block;
@@ -445,6 +474,7 @@ body.light-mode .skeleton {
445
474
  top: 100%;
446
475
  left: 0;
447
476
  background-color: white;
477
+ color: #1e293b;
448
478
  border: 1px solid #e5e7eb;
449
479
  border-radius: var(--radius-md);
450
480
  box-shadow: var(--shadow-lg);
@@ -456,6 +486,11 @@ body.light-mode .skeleton {
456
486
  transition: all var(--duration-150) var(--ease-in-out);
457
487
  }
458
488
 
489
+ body.light-mode .dropdown-content {
490
+ background-color: white;
491
+ color: #1e293b;
492
+ }
493
+
459
494
  .dropdown.active .dropdown-content {
460
495
  opacity: 1;
461
496
  visibility: visible;
@@ -470,11 +505,22 @@ body.light-mode .skeleton {
470
505
  background: none;
471
506
  border: none;
472
507
  cursor: pointer;
508
+ color: #1e293b;
473
509
  transition: background-color var(--duration-150) var(--ease-in-out);
474
510
  }
475
511
 
476
512
  .dropdown-item:hover {
477
513
  background-color: #f3f4f6;
514
+ color: #1e293b;
515
+ }
516
+
517
+ body.light-mode .dropdown-item {
518
+ color: #1e293b;
519
+ }
520
+
521
+ body.light-mode .dropdown-item:hover {
522
+ background-color: #f3f4f6;
523
+ color: #1e293b;
478
524
  }
479
525
 
480
526
  /* Accordion Component */
@@ -488,6 +534,7 @@ body.light-mode .skeleton {
488
534
  .accordion-header {
489
535
  padding: var(--space-4);
490
536
  background-color: #f9fafb;
537
+ color: #1e293b;
491
538
  cursor: pointer;
492
539
  display: flex;
493
540
  justify-content: space-between;
@@ -497,16 +544,33 @@ body.light-mode .skeleton {
497
544
 
498
545
  .accordion-header:hover {
499
546
  background-color: #f3f4f6;
547
+ color: #1e293b;
500
548
  }
501
549
 
502
550
  .accordion-content {
503
551
  padding: var(--space-4);
504
552
  background-color: white;
553
+ color: #1e293b;
505
554
  max-height: 0;
506
555
  overflow: hidden;
507
556
  transition: max-height var(--duration-300) var(--ease-in-out);
508
557
  }
509
558
 
559
+ body.light-mode .accordion-header {
560
+ background-color: #f9fafb;
561
+ color: #1e293b;
562
+ }
563
+
564
+ body.light-mode .accordion-header:hover {
565
+ background-color: #f3f4f6;
566
+ color: #1e293b;
567
+ }
568
+
569
+ body.light-mode .accordion-content {
570
+ background-color: white;
571
+ color: #1e293b;
572
+ }
573
+
510
574
  .accordion-item.active .accordion-content {
511
575
  max-height: 500px;
512
576
  }
@@ -522,23 +586,44 @@ body.light-mode .skeleton {
522
586
  /* Tab Component */
523
587
  .tab-list {
524
588
  display: flex;
525
- border-bottom: 1px solid #e5e7eb;
589
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
526
590
  }
527
591
 
528
592
  .tab-button {
529
- padding: var(--space-2) var(--space-4);
593
+ padding: var(--space-3) var(--space-4);
530
594
  background: none;
531
595
  border: none;
532
596
  cursor: pointer;
533
597
  border-bottom: 2px solid transparent;
598
+ color: var(--text-secondary);
599
+ font-weight: 500;
534
600
  transition: all var(--duration-150) var(--ease-in-out);
535
601
  }
536
602
 
537
603
  .tab-button:hover {
538
- background-color: #f3f4f6;
604
+ background-color: rgba(255, 255, 255, 0.05);
605
+ color: var(--text-primary);
539
606
  }
540
607
 
541
608
  .tab-button.active {
609
+ border-bottom-color: var(--color-starlight-blue);
610
+ color: var(--color-starlight-blue);
611
+ }
612
+
613
+ body.light-mode .tab-list {
614
+ border-bottom-color: #e2e8f0;
615
+ }
616
+
617
+ body.light-mode .tab-button {
618
+ color: #64748b;
619
+ }
620
+
621
+ body.light-mode .tab-button:hover {
622
+ background-color: #f1f5f9;
623
+ color: #0f172a;
624
+ }
625
+
626
+ body.light-mode .tab-button.active {
542
627
  border-bottom-color: var(--color-primary);
543
628
  color: var(--color-primary);
544
629
  }
@@ -657,4 +742,80 @@ body.light-mode .skeleton {
657
742
  @keyframes slideDown {
658
743
  from { transform: translateY(-20px); opacity: 0; }
659
744
  to { transform: translateY(0); opacity: 1; }
745
+ }
746
+
747
+ /* Table Component */
748
+ .table-wrapper {
749
+ width: 100%;
750
+ overflow-x: auto;
751
+ -webkit-overflow-scrolling: touch;
752
+ }
753
+
754
+ .table-wrapper::-webkit-scrollbar {
755
+ height: 8px;
756
+ }
757
+
758
+ .table-wrapper::-webkit-scrollbar-track {
759
+ background: rgba(255, 255, 255, 0.05);
760
+ border-radius: 4px;
761
+ }
762
+
763
+ .table-wrapper::-webkit-scrollbar-thumb {
764
+ background: var(--color-starlight-blue, #3b82f6);
765
+ border-radius: 4px;
766
+ }
767
+
768
+ body.light-mode .table-wrapper::-webkit-scrollbar-track {
769
+ background: rgba(0, 0, 0, 0.05);
770
+ }
771
+
772
+ .table {
773
+ width: 100%;
774
+ border-collapse: collapse;
775
+ font-size: 0.875rem;
776
+ text-align: left;
777
+ color: var(--text-primary);
778
+ }
779
+
780
+ .table th {
781
+ padding: var(--space-3) var(--space-4);
782
+ font-weight: 600;
783
+ background-color: rgba(255, 255, 255, 0.05);
784
+ border-bottom: 2px solid rgba(255, 255, 255, 0.1);
785
+ color: var(--text-primary);
786
+ }
787
+
788
+ .table td {
789
+ padding: var(--space-3) var(--space-4);
790
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
791
+ color: var(--text-secondary);
792
+ }
793
+
794
+ .table tbody tr:hover {
795
+ background-color: rgba(255, 255, 255, 0.03);
796
+ }
797
+
798
+ /* Light Mode Table Styles */
799
+ body.light-mode .table th {
800
+ background-color: #f8fafc;
801
+ border-bottom-color: #e2e8f0;
802
+ color: #0f172a;
803
+ }
804
+
805
+ body.light-mode .table td {
806
+ border-bottom-color: #e2e8f0;
807
+ color: #334155;
808
+ }
809
+
810
+ body.light-mode .table tbody tr:hover {
811
+ background-color: #f1f5f9;
812
+ }
813
+
814
+ /* Overflow Utility */
815
+ .overflow-x-auto {
816
+ overflow-x: auto;
817
+ }
818
+
819
+ .overflow-y-auto {
820
+ overflow-y: auto;
660
821
  }