@nexgrid/react 0.1.0 → 0.2.0

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/styles.css CHANGED
@@ -1,78 +1,204 @@
1
1
  /* ==========================================================================
2
- NexGrid — shared theme
2
+ TableX — shared theme
3
3
  ==========================================================================
4
4
  One stylesheet for every adapter (React, Angular, vanilla / ASP.NET), so a
5
5
  grid looks and behaves identically on every platform.
6
6
 
7
- Theming: every color/shape below reads a `--nxg-*` custom property, so a
7
+ Theming: every color/shape below reads a `--tbx-*` custom property, so a
8
8
  host app can re-skin the grid by overriding tokens — no class overrides
9
- needed. Dark mode: add `.nxg-dark` on the root (or any ancestor), or use
10
- `.nxg-auto` to follow the OS preference.
9
+ needed. Dark mode: add `.tbx-dark` on the root (or any ancestor), or use
10
+ `.tbx-auto` to follow the OS preference.
11
11
  ========================================================================== */
12
12
 
13
- .nxg-root {
13
+ .tbx-root {
14
14
  /* ---- Design tokens (light defaults) ---- */
15
- --nxg-font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
15
+ --tbx-font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
16
16
  "Helvetica Neue", Arial, sans-serif;
17
- --nxg-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
18
- --nxg-bg: #ffffff;
19
- --nxg-card: #ffffff;
20
- --nxg-card-2: #f8fafc;
21
- --nxg-border: #e2e8f0;
22
- --nxg-fg: #0f172a;
23
- --nxg-muted: #f1f5f9;
24
- --nxg-muted-fg: #64748b;
25
- --nxg-primary: #2563eb;
26
- --nxg-primary-fg: #ffffff;
27
- --nxg-danger: #dc2626;
28
- --nxg-radius: 12px;
29
- --nxg-radius-sm: 8px;
30
- --nxg-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
31
- --nxg-focus-ring: 0 0 0 2px color-mix(in srgb, var(--nxg-primary) 35%, transparent);
17
+ --tbx-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
18
+ --tbx-bg: #ffffff;
19
+ --tbx-card: #ffffff;
20
+ --tbx-card-2: #f9fafb;
21
+ --tbx-border: #e5e7eb;
22
+ --tbx-border-subtle: #f3f4f6;
23
+ --tbx-fg: #111827;
24
+ --tbx-muted: #f3f4f6;
25
+ --tbx-muted-fg: #6b7280;
26
+ --tbx-primary: #2563eb;
27
+ --tbx-primary-active: #1d4ed8;
28
+ --tbx-primary-fg: #ffffff;
29
+ --tbx-selected-bg: #ebf5ff;
30
+ --tbx-danger: #dc2626;
31
+ --tbx-radius-outer: 16px;
32
+ --tbx-radius: 10px;
33
+ --tbx-radius-sm: 8px;
34
+ --tbx-radius-xs: 6px;
35
+ --tbx-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
36
+ --tbx-shadow-card: 0 10px 30px -5px rgba(0, 0, 0, 0.05), 0 4px 12px -2px rgba(0, 0, 0, 0.02);
37
+ --tbx-focus-ring: 0 0 0 2px rgba(37, 99, 235, 0.35);
38
+
39
+ /* Backwards-compatibility aliases */
40
+ --nxg-font: var(--tbx-font);
41
+ --nxg-font-mono: var(--tbx-font-mono);
42
+ --nxg-bg: var(--tbx-bg);
43
+ --nxg-card: var(--tbx-card);
44
+ --nxg-card-2: var(--tbx-card-2);
45
+ --nxg-border: var(--tbx-border);
46
+ --nxg-fg: var(--tbx-fg);
47
+ --nxg-muted: var(--tbx-muted);
48
+ --nxg-muted-fg: var(--tbx-muted-fg);
49
+ --nxg-primary: var(--tbx-primary);
50
+ --nxg-primary-fg: var(--tbx-primary-fg);
51
+ --nxg-danger: var(--tbx-danger);
52
+ --nxg-radius: var(--tbx-radius);
53
+ --nxg-radius-sm: var(--tbx-radius-sm);
54
+ --nxg-shadow: var(--tbx-shadow);
55
+ --nxg-focus-ring: var(--tbx-focus-ring);
32
56
 
33
57
  display: flex;
34
58
  flex-direction: column;
35
- gap: 14px;
59
+ gap: 16px;
36
60
  width: 100%;
37
- font-family: var(--nxg-font);
38
- color: var(--nxg-fg);
61
+ padding: 24px;
62
+ background: var(--tbx-card);
63
+ border: 1px solid var(--tbx-border);
64
+ border-radius: var(--tbx-radius-outer);
65
+ box-shadow: var(--tbx-shadow-card);
66
+ font-family: var(--tbx-font);
67
+ color: var(--tbx-fg);
39
68
  box-sizing: border-box;
40
69
  }
41
70
 
42
- .nxg-root *,
43
- .nxg-root *::before,
44
- .nxg-root *::after {
71
+ .tbx-root *,
72
+ .tbx-root *::before,
73
+ .tbx-root *::after {
45
74
  box-sizing: inherit;
46
75
  }
47
76
 
77
+ /* ==========================================================================
78
+ Ultra-thin & Elegant Scrollbars (Default)
79
+ ========================================================================== */
80
+
81
+ /* Standard Firefox/CSS */
82
+ .tbx-root,
83
+ .tbx-root *,
84
+ .tbx-table-wrap,
85
+ .tbx-filter-popover-options,
86
+ .tbx-menu {
87
+ scrollbar-width: thin;
88
+ scrollbar-color: rgba(156, 163, 175, 0.45) transparent;
89
+ }
90
+
91
+ /* WebKit (Chrome, Edge, Safari, Opera) */
92
+ .tbx-root ::-webkit-scrollbar,
93
+ .tbx-table-wrap::-webkit-scrollbar,
94
+ .tbx-filter-popover-options::-webkit-scrollbar,
95
+ .tbx-menu::-webkit-scrollbar {
96
+ width: 5px;
97
+ height: 5px;
98
+ }
99
+
100
+ .tbx-root ::-webkit-scrollbar-track,
101
+ .tbx-table-wrap::-webkit-scrollbar-track,
102
+ .tbx-filter-popover-options::-webkit-scrollbar-track,
103
+ .tbx-menu::-webkit-scrollbar-track {
104
+ background: transparent;
105
+ border-radius: 9999px;
106
+ }
107
+
108
+ .tbx-root ::-webkit-scrollbar-thumb,
109
+ .tbx-table-wrap::-webkit-scrollbar-thumb,
110
+ .tbx-filter-popover-options::-webkit-scrollbar-thumb,
111
+ .tbx-menu::-webkit-scrollbar-thumb {
112
+ background: rgba(156, 163, 175, 0.4);
113
+ border-radius: 9999px;
114
+ transition: background 0.2s cubic-bezier(0.4, 0, 0.2, 1);
115
+ }
116
+
117
+ .tbx-root ::-webkit-scrollbar-thumb:hover,
118
+ .tbx-table-wrap::-webkit-scrollbar-thumb:hover,
119
+ .tbx-filter-popover-options::-webkit-scrollbar-thumb:hover,
120
+ .tbx-menu::-webkit-scrollbar-thumb:hover {
121
+ background: rgba(107, 114, 128, 0.7);
122
+ }
123
+
124
+ .tbx-root ::-webkit-scrollbar-corner,
125
+ .tbx-table-wrap::-webkit-scrollbar-corner {
126
+ background: transparent;
127
+ }
128
+
48
129
  /* ---- Dark theme ---- */
49
- .nxg-dark .nxg-root,
50
- .nxg-root.nxg-dark {
51
- --nxg-bg: #0b1220;
52
- --nxg-card: #0f172a;
53
- --nxg-card-2: #16213a;
54
- --nxg-border: #253352;
55
- --nxg-fg: #e2e8f0;
56
- --nxg-muted: #1e293b;
57
- --nxg-muted-fg: #94a3b8;
58
- --nxg-primary: #3b82f6;
59
- --nxg-primary-fg: #ffffff;
60
- --nxg-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.4);
130
+ .tbx-dark .tbx-root,
131
+ .tbx-root.tbx-dark {
132
+ --tbx-bg: #0f172a;
133
+ --tbx-card: #1e293b;
134
+ --tbx-card-2: #16213a;
135
+ --tbx-border: #334155;
136
+ --tbx-border-subtle: #1e293b;
137
+ --tbx-fg: #f8fafc;
138
+ --tbx-muted: #334155;
139
+ --tbx-muted-fg: #94a3b8;
140
+ --tbx-primary: #3b82f6;
141
+ --tbx-primary-active: #2563eb;
142
+ --tbx-primary-fg: #ffffff;
143
+ --tbx-selected-bg: rgba(59, 130, 246, 0.15);
144
+ --tbx-shadow-card: 0 10px 30px -5px rgba(0, 0, 0, 0.3);
145
+ }
146
+
147
+ /* ---- Dark theme scrollbar ---- */
148
+ .tbx-dark,
149
+ .tbx-dark .tbx-root,
150
+ .tbx-root.tbx-dark,
151
+ .tbx-dark .tbx-table-wrap,
152
+ .tbx-dark .tbx-filter-popover-options,
153
+ .tbx-dark .tbx-menu {
154
+ scrollbar-color: rgba(148, 163, 184, 0.35) transparent;
155
+ }
156
+
157
+ .tbx-dark ::-webkit-scrollbar-thumb,
158
+ .tbx-dark .tbx-root ::-webkit-scrollbar-thumb,
159
+ .tbx-root.tbx-dark ::-webkit-scrollbar-thumb,
160
+ .tbx-dark .tbx-table-wrap::-webkit-scrollbar-thumb,
161
+ .tbx-dark .tbx-filter-popover-options::-webkit-scrollbar-thumb,
162
+ .tbx-dark .tbx-menu::-webkit-scrollbar-thumb {
163
+ background: rgba(148, 163, 184, 0.3);
164
+ }
165
+
166
+ .tbx-dark ::-webkit-scrollbar-thumb:hover,
167
+ .tbx-dark .tbx-root ::-webkit-scrollbar-thumb:hover,
168
+ .tbx-root.tbx-dark ::-webkit-scrollbar-thumb:hover,
169
+ .tbx-dark .tbx-table-wrap::-webkit-scrollbar-thumb:hover,
170
+ .tbx-dark .tbx-filter-popover-options::-webkit-scrollbar-thumb:hover,
171
+ .tbx-dark .tbx-menu::-webkit-scrollbar-thumb:hover {
172
+ background: rgba(203, 213, 225, 0.6);
61
173
  }
62
174
 
63
175
  @media (prefers-color-scheme: dark) {
64
- .nxg-auto .nxg-root,
65
- .nxg-root.nxg-auto {
66
- --nxg-bg: #0b1220;
67
- --nxg-card: #0f172a;
68
- --nxg-card-2: #16213a;
69
- --nxg-border: #253352;
70
- --nxg-fg: #e2e8f0;
71
- --nxg-muted: #1e293b;
72
- --nxg-muted-fg: #94a3b8;
73
- --nxg-primary: #3b82f6;
74
- --nxg-primary-fg: #ffffff;
75
- --nxg-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.4);
176
+ .tbx-auto .tbx-root,
177
+ .tbx-root.tbx-auto {
178
+ --tbx-bg: #0f172a;
179
+ --tbx-card: #1e293b;
180
+ --tbx-card-2: #16213a;
181
+ --tbx-border: #334155;
182
+ --tbx-border-subtle: #1e293b;
183
+ --tbx-fg: #f8fafc;
184
+ --tbx-muted: #334155;
185
+ --tbx-muted-fg: #94a3b8;
186
+ --tbx-primary: #3b82f6;
187
+ --tbx-primary-active: #2563eb;
188
+ --tbx-primary-fg: #ffffff;
189
+ --tbx-selected-bg: rgba(59, 130, 246, 0.15);
190
+ --tbx-shadow-card: 0 10px 30px -5px rgba(0, 0, 0, 0.3);
191
+ scrollbar-color: rgba(148, 163, 184, 0.35) transparent;
192
+ }
193
+
194
+ .tbx-auto ::-webkit-scrollbar-thumb,
195
+ .tbx-root.tbx-auto ::-webkit-scrollbar-thumb {
196
+ background: rgba(148, 163, 184, 0.3);
197
+ }
198
+
199
+ .tbx-auto ::-webkit-scrollbar-thumb:hover,
200
+ .tbx-root.tbx-auto ::-webkit-scrollbar-thumb:hover {
201
+ background: rgba(203, 213, 225, 0.6);
76
202
  }
77
203
  }
78
204
 
@@ -80,27 +206,26 @@
80
206
  Toolbar
81
207
  ========================================================================== */
82
208
 
83
- .nxg-toolbar {
209
+ .tbx-toolbar {
84
210
  display: flex;
85
211
  flex-direction: column;
86
212
  align-items: stretch;
87
213
  justify-content: space-between;
88
214
  gap: 12px;
89
- padding: 12px;
90
- background: var(--nxg-card);
91
- border: 1px solid var(--nxg-border);
92
- border-radius: var(--nxg-radius);
93
- box-shadow: var(--nxg-shadow);
215
+ padding: 0;
216
+ background: transparent;
217
+ border: none;
218
+ box-shadow: none;
94
219
  }
95
220
 
96
221
  @media (min-width: 640px) {
97
- .nxg-toolbar {
222
+ .tbx-toolbar {
98
223
  flex-direction: row;
99
224
  align-items: center;
100
225
  }
101
226
  }
102
227
 
103
- .nxg-toolbar-group {
228
+ .tbx-toolbar-group {
104
229
  display: flex;
105
230
  align-items: center;
106
231
  gap: 8px;
@@ -108,401 +233,779 @@
108
233
  min-width: 0;
109
234
  }
110
235
 
111
- .nxg-toolbar-group--end {
236
+ .tbx-toolbar-group--end {
112
237
  justify-content: flex-end;
113
238
  }
114
239
 
240
+ @media (max-width: 639px) {
241
+ .tbx-toolbar-group {
242
+ width: 100%;
243
+ }
244
+
245
+ .tbx-toolbar-group--end {
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: flex-start;
249
+ gap: 6px;
250
+ flex-wrap: wrap;
251
+ }
252
+
253
+ .tbx-toolbar-extra,
254
+ .toolbar-extra {
255
+ display: inline-flex;
256
+ align-items: center;
257
+ gap: 6px;
258
+ }
259
+
260
+ /* Compact square icon-only buttons on narrow mobile screens */
261
+ .tbx-toolbar .tbx-btn {
262
+ width: 36px;
263
+ height: 36px;
264
+ padding: 0;
265
+ justify-content: center;
266
+ flex-shrink: 0;
267
+ }
268
+
269
+ .tbx-toolbar .tbx-btn span:not(.tbx-sr-only):not(.tbx-sort-order) {
270
+ display: none;
271
+ }
272
+
273
+ .tbx-toolbar .tbx-btn .tbx-chevron {
274
+ display: none;
275
+ }
276
+
277
+ .tbx-toolbar .tbx-select {
278
+ height: 36px;
279
+ font-size: 12px;
280
+ padding: 0 24px 0 8px;
281
+ max-width: 130px;
282
+ }
283
+ }
284
+
115
285
  /* ---- Search ---- */
116
286
 
117
- .nxg-search {
287
+ .tbx-search {
118
288
  position: relative;
119
289
  width: 100%;
120
290
  }
121
291
 
122
292
  @media (min-width: 640px) {
123
- .nxg-search {
124
- width: auto;
125
- min-width: 220px;
126
- max-width: 320px;
293
+ .tbx-search {
294
+ width: 320px;
295
+ min-width: 290px;
296
+ max-width: 420px;
297
+ flex-shrink: 0;
298
+ }
299
+ }
300
+
301
+ @media (min-width: 1024px) {
302
+ .tbx-search {
303
+ width: 340px;
127
304
  }
128
305
  }
129
306
 
130
- .nxg-search-icon {
307
+ .tbx-search-icon {
131
308
  position: absolute;
132
- left: 12px;
309
+ left: 11px;
133
310
  top: 50%;
134
311
  transform: translateY(-50%);
135
- width: 16px;
136
- height: 16px;
137
- color: var(--nxg-primary);
312
+ width: 15px;
313
+ height: 15px;
314
+ color: #94a3b8;
138
315
  pointer-events: none;
139
316
  }
140
317
 
141
- .nxg-search-input {
318
+ .tbx-search-input {
142
319
  height: 36px;
143
320
  width: 100%;
144
- padding: 0 32px 0 36px;
145
- font-size: 12px;
321
+ padding: 0 30px 0 34px;
322
+ font-size: 13px;
146
323
  font-family: inherit;
147
- color: var(--nxg-fg);
148
- background: var(--nxg-bg);
149
- border: 1px solid var(--nxg-border);
150
- border-radius: var(--nxg-radius-sm);
151
- box-shadow: var(--nxg-shadow);
324
+ color: var(--tbx-fg);
325
+ background: var(--tbx-card);
326
+ border: 1px solid #cbd5e1;
327
+ border-radius: 6px;
328
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
152
329
  outline: none;
330
+ transition: border-color 120ms ease, box-shadow 120ms ease;
153
331
  }
154
332
 
155
- .nxg-search-input::placeholder {
156
- color: var(--nxg-muted-fg);
333
+ .tbx-dark .tbx-search-input {
334
+ border-color: var(--tbx-border);
157
335
  }
158
336
 
159
- .nxg-search-input:focus {
160
- border-color: var(--nxg-primary);
161
- box-shadow: var(--nxg-focus-ring);
337
+ .tbx-search-input::placeholder {
338
+ color: #94a3b8;
339
+ font-size: 13px;
162
340
  }
163
341
 
164
- .nxg-search-clear {
342
+ .tbx-search-input:focus {
343
+ border-color: var(--tbx-primary);
344
+ box-shadow: var(--tbx-focus-ring);
345
+ }
346
+
347
+ .tbx-search-clear {
165
348
  position: absolute;
166
- right: 10px;
349
+ right: 8px;
167
350
  top: 50%;
168
351
  transform: translateY(-50%);
169
352
  display: inline-flex;
170
- padding: 2px;
353
+ align-items: center;
354
+ justify-content: center;
355
+ width: 20px;
356
+ height: 20px;
357
+ padding: 0;
171
358
  border: 0;
172
- border-radius: 6px;
359
+ border-radius: 4px;
173
360
  background: transparent;
174
- color: var(--nxg-muted-fg);
361
+ color: var(--tbx-muted-fg);
175
362
  cursor: pointer;
176
363
  }
177
364
 
178
- .nxg-search-clear:hover {
179
- color: var(--nxg-fg);
365
+ .tbx-search-clear:hover {
366
+ color: var(--tbx-fg);
180
367
  }
181
368
 
182
369
  /* ---- Buttons ---- */
183
370
 
184
- .nxg-btn {
371
+ .tbx-btn {
185
372
  display: inline-flex;
186
373
  align-items: center;
187
374
  gap: 6px;
188
375
  height: 36px;
189
376
  padding: 0 12px;
190
- font-size: 12px;
377
+ font-size: 13px;
191
378
  font-weight: 500;
192
379
  font-family: inherit;
193
- color: var(--nxg-fg);
194
- background: var(--nxg-bg);
195
- border: 1px solid var(--nxg-border);
196
- border-radius: var(--nxg-radius-sm);
197
- box-shadow: var(--nxg-shadow);
380
+ color: #334155;
381
+ background: var(--tbx-card);
382
+ border: 1px solid #cbd5e1;
383
+ border-radius: 6px;
384
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
198
385
  cursor: pointer;
199
386
  white-space: nowrap;
200
- transition: background-color 120ms ease, color 120ms ease;
387
+ transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
388
+ }
389
+
390
+ .tbx-dark .tbx-btn {
391
+ color: var(--tbx-fg);
392
+ border-color: var(--tbx-border);
201
393
  }
202
394
 
203
- .nxg-btn:hover {
204
- background: var(--nxg-muted);
395
+ .tbx-btn:hover {
396
+ background: var(--tbx-card-2);
397
+ border-color: #94a3b8;
398
+ color: var(--tbx-fg);
205
399
  }
206
400
 
207
- .nxg-btn:focus-visible {
401
+ .tbx-btn:focus-visible {
208
402
  outline: none;
209
- box-shadow: var(--nxg-focus-ring);
403
+ box-shadow: var(--tbx-focus-ring);
210
404
  }
211
405
 
212
- .nxg-btn:disabled {
406
+ .tbx-btn:disabled {
213
407
  opacity: 0.5;
214
408
  cursor: not-allowed;
215
409
  }
216
410
 
217
- .nxg-btn .nxg-icon {
218
- color: var(--nxg-primary);
411
+ .tbx-btn .tbx-icon {
412
+ color: #475569;
219
413
  }
220
414
 
221
- .nxg-btn--export {
222
- font-weight: 600;
223
- color: var(--nxg-primary);
224
- border-color: color-mix(in srgb, var(--nxg-primary) 30%, transparent);
415
+ .tbx-dark .tbx-btn .tbx-icon {
416
+ color: var(--tbx-muted-fg);
225
417
  }
226
418
 
227
- .nxg-btn--export:hover {
228
- background: color-mix(in srgb, var(--nxg-primary) 10%, transparent);
419
+ .tbx-btn--export {
420
+ font-weight: 500;
421
+ color: #334155;
229
422
  }
230
423
 
231
- .nxg-btn--export .nxg-icon {
232
- color: currentColor;
424
+ .tbx-dark .tbx-btn--export {
425
+ color: var(--tbx-fg);
426
+ }
427
+
428
+ .tbx-btn--export:hover {
429
+ background: var(--tbx-card-2);
233
430
  }
234
431
 
235
- .nxg-icon {
432
+ .tbx-select {
433
+ display: inline-flex;
434
+ align-items: center;
435
+ height: 36px;
436
+ padding: 0 28px 0 12px;
437
+ font-size: 13px;
438
+ font-weight: 500;
439
+ font-family: inherit;
440
+ color: #334155;
441
+ background-color: var(--tbx-card);
442
+ border: 1px solid #cbd5e1;
443
+ border-radius: 6px;
444
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
445
+ cursor: pointer;
446
+ outline: none;
447
+ appearance: none;
448
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
449
+ background-repeat: no-repeat;
450
+ background-position: right 8px center;
451
+ transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
452
+ }
453
+
454
+ .tbx-dark .tbx-select {
455
+ color: var(--tbx-fg);
456
+ border-color: var(--tbx-border);
457
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
458
+ }
459
+
460
+ .tbx-select:hover {
461
+ background-color: var(--tbx-card-2);
462
+ border-color: #94a3b8;
463
+ }
464
+
465
+ .btn-action,
466
+ .tbx-btn-action {
467
+ display: inline-flex;
468
+ align-items: center;
469
+ justify-content: center;
470
+ width: 32px;
471
+ height: 32px;
472
+ padding: 0;
473
+ border-radius: 6px;
474
+ border: 1px solid #cbd5e1;
475
+ background: var(--tbx-card);
476
+ color: #475569;
477
+ cursor: pointer;
478
+ transition: all 120ms ease;
479
+ }
480
+
481
+ .btn-action:hover,
482
+ .tbx-btn-action:hover {
483
+ background: var(--tbx-card-2);
484
+ border-color: #94a3b8;
485
+ color: var(--tbx-fg);
486
+ }
487
+
488
+ .tbx-dark .btn-action,
489
+ .tbx-dark .tbx-btn-action {
490
+ border-color: var(--tbx-border);
491
+ color: var(--tbx-muted-fg);
492
+ }
493
+
494
+ .tbx-icon {
236
495
  width: 14px;
237
496
  height: 14px;
238
497
  flex-shrink: 0;
239
498
  }
240
499
 
241
- .nxg-capitalize {
500
+ .tbx-capitalize {
242
501
  text-transform: capitalize;
243
502
  }
244
503
 
245
504
  /* ---- Dropdown menus ---- */
246
505
 
247
- .nxg-menu-wrap {
506
+ .tbx-menu-wrap {
248
507
  position: relative;
249
508
  display: inline-flex;
250
509
  }
251
510
 
252
- .nxg-menu {
511
+ .tbx-menu {
253
512
  position: absolute;
254
513
  top: calc(100% + 6px);
255
514
  left: 0;
256
515
  z-index: 50;
257
516
  min-width: 208px;
258
- padding: 4px;
259
- background: var(--nxg-card);
260
- border: 1px solid var(--nxg-border);
261
- border-radius: var(--nxg-radius-sm);
262
- box-shadow: 0 8px 24px rgb(0 0 0 / 0.12), var(--nxg-shadow);
517
+ padding: 6px;
518
+ background: var(--tbx-card);
519
+ border: 1px solid var(--tbx-border);
520
+ border-radius: var(--tbx-radius-sm);
521
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.05);
263
522
  }
264
523
 
265
- .nxg-menu--end {
524
+ .tbx-menu--end {
266
525
  left: auto;
267
526
  right: 0;
268
527
  min-width: 224px;
269
528
  }
270
529
 
271
- .nxg-menu-label {
530
+ .tbx-menu-label {
272
531
  padding: 6px 8px;
273
532
  font-size: 11px;
274
- color: var(--nxg-muted-fg);
533
+ font-weight: 600;
534
+ text-transform: uppercase;
535
+ letter-spacing: 0.04em;
536
+ color: var(--tbx-muted-fg);
275
537
  }
276
538
 
277
- .nxg-menu-separator {
539
+ .tbx-menu-separator {
278
540
  height: 1px;
279
541
  margin: 4px 0;
280
- background: var(--nxg-border);
542
+ background: var(--tbx-border);
281
543
  }
282
544
 
283
- .nxg-menu-item {
545
+ .tbx-menu-item {
284
546
  display: flex;
285
547
  align-items: center;
286
548
  gap: 10px;
287
549
  width: 100%;
288
- padding: 8px;
289
- font-size: 12px;
550
+ padding: 8px 10px;
551
+ font-size: 13px;
290
552
  font-family: inherit;
291
553
  text-align: left;
292
- color: var(--nxg-fg);
554
+ color: var(--tbx-fg);
293
555
  background: transparent;
294
556
  border: 0;
295
557
  border-radius: 6px;
296
558
  cursor: pointer;
559
+ transition: background-color 100ms ease;
297
560
  }
298
561
 
299
- .nxg-menu-item:hover {
300
- background: var(--nxg-muted);
562
+ .tbx-menu-item:hover {
563
+ background: var(--tbx-muted);
301
564
  }
302
565
 
303
- .nxg-menu-item .nxg-check {
566
+ .tbx-menu-item .tbx-check {
304
567
  width: 14px;
305
568
  height: 14px;
306
569
  flex-shrink: 0;
307
- color: var(--nxg-primary);
570
+ color: var(--tbx-primary);
308
571
  visibility: hidden;
309
572
  }
310
573
 
311
- .nxg-menu-item[aria-checked="true"] .nxg-check {
574
+ .tbx-menu-item[aria-checked="true"] .tbx-check {
312
575
  visibility: visible;
313
576
  }
314
577
 
315
- .nxg-menu-item-title {
578
+ .tbx-menu-item-title {
316
579
  display: flex;
317
580
  flex-direction: column;
318
581
  line-height: 1.3;
319
582
  }
320
583
 
321
- .nxg-menu-item-title strong {
584
+ .tbx-menu-item-title strong {
322
585
  font-weight: 600;
323
- color: var(--nxg-fg);
586
+ color: var(--tbx-fg);
324
587
  }
325
588
 
326
- .nxg-menu-item-title small {
327
- font-size: 10px;
328
- color: var(--nxg-muted-fg);
589
+ .tbx-menu-item-title small {
590
+ font-size: 11px;
591
+ color: var(--tbx-muted-fg);
329
592
  }
330
593
 
331
- .nxg-icon--excel {
594
+ .tbx-icon--excel {
332
595
  color: #10b981;
333
596
  width: 16px;
334
597
  height: 16px;
335
598
  }
336
599
 
337
- .nxg-icon--csv {
600
+ .tbx-icon--csv {
338
601
  color: #06b6d4;
339
602
  width: 16px;
340
603
  height: 16px;
341
604
  }
342
605
 
343
606
  /* ==========================================================================
344
- Table (>= 768px)
607
+ Table & Cards Layout
345
608
  ========================================================================== */
346
609
 
347
- .nxg-table-wrap {
610
+ .tbx-table-wrap {
348
611
  position: relative;
349
- display: none;
612
+ display: block;
350
613
  overflow-x: auto;
614
+ -webkit-overflow-scrolling: touch;
351
615
  touch-action: pan-x;
352
- background: var(--nxg-card);
353
- border: 1px solid var(--nxg-border);
354
- border-radius: var(--nxg-radius);
355
- box-shadow: var(--nxg-shadow);
616
+ background: var(--tbx-card);
617
+ border: 1px solid var(--tbx-border);
618
+ border-radius: var(--tbx-radius);
619
+ box-shadow: none;
620
+ scrollbar-width: thin;
621
+ }
622
+
623
+ .tbx-cards {
624
+ display: flex;
625
+ flex-direction: column;
626
+ gap: 12px;
627
+ }
628
+
629
+ @media (max-width: 767px) {
630
+ .tbx-root:has(.tbx-cards) .tbx-table-wrap {
631
+ display: none;
632
+ }
356
633
  }
357
634
 
358
635
  @media (min-width: 768px) {
359
- .nxg-table-wrap {
636
+ .tbx-cards {
637
+ display: none !important;
638
+ }
639
+ .tbx-root:has(.tbx-cards) .tbx-table-wrap {
360
640
  display: block;
361
641
  }
362
642
  }
363
643
 
364
- .nxg-table {
644
+ .tbx-table {
365
645
  width: 100%;
366
646
  text-align: left;
367
- border-collapse: collapse;
368
- font-size: 14px;
369
- color: var(--nxg-fg);
647
+ border-collapse: separate;
648
+ border-spacing: 0;
649
+ font-size: 13px;
650
+ color: var(--tbx-fg);
370
651
  }
371
652
 
372
- .nxg-table thead tr {
373
- border-bottom: 1px solid var(--nxg-border);
374
- background: var(--nxg-card-2);
375
- font-size: 12px;
376
- font-weight: 600;
377
- color: var(--nxg-muted-fg);
378
- white-space: nowrap;
653
+ .tbx-table thead tr {
654
+ background: var(--tbx-card-2);
379
655
  }
380
656
 
381
- .nxg-th {
382
- padding: 12px 16px;
657
+ .tbx-th {
658
+ position: relative;
659
+ padding: 10px 10px 10px 14px;
660
+ font-size: 13px;
383
661
  font-weight: 600;
662
+ color: var(--tbx-fg);
663
+ border-bottom: 1px solid var(--tbx-border);
384
664
  user-select: none;
665
+ white-space: nowrap;
666
+ background: var(--tbx-card-2);
385
667
  }
386
668
 
387
- .nxg-th--serial {
388
- width: 48px;
389
- padding: 12px;
669
+ .tbx-th--serial {
670
+ width: 56px;
671
+ padding: 10px 8px;
390
672
  text-align: center;
391
- font-weight: 700;
392
- font-size: 12px;
393
- text-transform: uppercase;
673
+ font-weight: 600;
674
+ font-size: 13px;
675
+ color: var(--tbx-fg);
394
676
  }
395
677
 
396
- .nxg-th--select {
397
- width: 40px;
398
- padding: 12px;
678
+ .tbx-th--select {
679
+ width: 44px;
680
+ padding: 10px 8px;
399
681
  text-align: center;
400
682
  }
401
683
 
402
- .nxg-th--sortable {
684
+ .tbx-th--sortable {
403
685
  cursor: pointer;
404
- transition: background-color 120ms ease, color 120ms ease;
405
686
  }
406
687
 
407
- .nxg-th--sortable:hover {
408
- color: var(--nxg-fg);
409
- background: var(--nxg-muted);
688
+ .tbx-th--sortable:hover {
689
+ background: var(--tbx-muted);
410
690
  }
411
691
 
412
- .nxg-th-inner {
413
- display: inline-flex;
692
+ .tbx-th--sortable:focus-visible {
693
+ outline: none;
694
+ box-shadow: var(--tbx-focus-ring);
695
+ }
696
+
697
+ .tbx-th-inner {
698
+ display: flex;
414
699
  align-items: center;
415
700
  gap: 6px;
701
+ width: 100%;
702
+ box-sizing: border-box;
416
703
  }
417
704
 
418
- .nxg-th-inner--center {
705
+ .tbx-th-inner--center {
419
706
  justify-content: center;
420
707
  }
421
708
 
422
- .nxg-th-inner--right {
709
+ .tbx-th-inner--right {
423
710
  justify-content: flex-end;
424
711
  }
425
712
 
426
- .nxg-sort-icon {
713
+ .tbx-th-inner > span:first-child {
714
+ display: inline-flex;
715
+ align-items: center;
716
+ min-width: 0;
717
+ }
718
+
719
+ .tbx-sort-icon-wrap {
720
+ display: inline-flex;
721
+ align-items: center;
722
+ gap: 3px;
723
+ flex-shrink: 0;
724
+ }
725
+
726
+ .tbx-sort-icon {
427
727
  width: 14px;
428
728
  height: 14px;
729
+ color: var(--tbx-primary);
429
730
  flex-shrink: 0;
430
- color: var(--nxg-primary);
431
731
  }
432
732
 
433
- .nxg-sort-icon--idle {
733
+ .tbx-sort-icon--idle {
734
+ color: var(--tbx-muted-fg);
434
735
  opacity: 0.4;
435
736
  }
436
737
 
437
- .nxg-th--sortable:hover .nxg-sort-icon--idle {
738
+ .tbx-sort-order {
739
+ display: inline-flex;
740
+ align-items: center;
741
+ justify-content: center;
742
+ min-width: 16px;
743
+ height: 16px;
744
+ padding: 0 4px;
745
+ font-size: 10px;
746
+ font-weight: 700;
747
+ font-family: var(--tbx-font-mono);
748
+ color: var(--tbx-primary);
749
+ background: color-mix(in srgb, var(--tbx-primary) 15%, transparent);
750
+ border-radius: 4px;
751
+ }
752
+
753
+ /* ---- Column filter popover ---- */
754
+ .tbx-col-filter-wrap {
755
+ position: relative;
756
+ display: inline-flex;
757
+ margin-left: auto;
758
+ flex-shrink: 0;
759
+ }
760
+
761
+ .tbx-col-filter-btn {
762
+ display: inline-flex;
763
+ align-items: center;
764
+ justify-content: center;
765
+ width: 20px;
766
+ height: 20px;
767
+ padding: 0;
768
+ margin-right: -4px;
769
+ border: 1px solid transparent;
770
+ border-radius: 4px;
771
+ background: transparent;
772
+ color: var(--tbx-muted-fg);
773
+ cursor: pointer;
774
+ opacity: 0.6;
775
+ transition: opacity 120ms ease, background-color 120ms ease, color 120ms ease, border-color 120ms ease;
776
+ }
777
+
778
+ .tbx-th:hover .tbx-col-filter-btn,
779
+ .tbx-col-filter-btn:focus-visible,
780
+ .tbx-col-filter-btn--active {
438
781
  opacity: 1;
439
782
  }
440
783
 
441
- .nxg-table tbody {
442
- background: var(--nxg-card);
784
+ .tbx-col-filter-btn:hover {
785
+ opacity: 1;
786
+ background: var(--tbx-muted);
787
+ color: var(--tbx-fg);
443
788
  }
444
789
 
445
- .nxg-row {
446
- border-bottom: 1px solid var(--nxg-border);
447
- white-space: nowrap;
448
- transition: background-color 120ms ease;
790
+ .tbx-col-filter-btn--active {
791
+ color: var(--tbx-primary);
792
+ background: color-mix(in srgb, var(--tbx-primary) 15%, transparent);
793
+ border-color: color-mix(in srgb, var(--tbx-primary) 30%, transparent);
449
794
  }
450
795
 
451
- .nxg-row:last-child {
452
- border-bottom: 0;
796
+ .tbx-filter-popover {
797
+ position: absolute;
798
+ top: calc(100% + 6px);
799
+ right: 0;
800
+ z-index: 50;
801
+ min-width: 200px;
802
+ max-width: min(280px, calc(100vw - 24px));
803
+ background: var(--tbx-card);
804
+ border: 1px solid var(--tbx-border);
805
+ border-radius: var(--tbx-radius-sm);
806
+ box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.15), 0 8px 10px -6px rgb(0 0 0 / 0.1);
807
+ padding: 8px;
808
+ text-align: left;
453
809
  }
454
810
 
455
- .nxg-row:hover {
456
- background: color-mix(in srgb, var(--nxg-muted) 50%, transparent);
811
+ .tbx-filter-popover-input {
812
+ width: 100%;
813
+ padding: 6px 8px;
814
+ font-size: 13px;
815
+ font-family: inherit;
816
+ color: var(--tbx-fg);
817
+ background: var(--tbx-card-2);
818
+ border: 1px solid var(--tbx-border);
819
+ border-radius: 6px;
820
+ outline: none;
821
+ box-sizing: border-box;
457
822
  }
458
823
 
459
- .nxg-row--selected {
460
- background: color-mix(in srgb, var(--nxg-primary) 10%, transparent);
824
+ .tbx-filter-popover-input:focus {
825
+ border-color: var(--tbx-primary);
826
+ box-shadow: var(--tbx-focus-ring);
461
827
  }
462
828
 
463
- .nxg-row--selected:hover {
464
- background: color-mix(in srgb, var(--nxg-primary) 15%, transparent);
829
+ .tbx-filter-popover-options {
830
+ max-height: 180px;
831
+ overflow-y: auto;
832
+ margin: 6px 0;
833
+ display: flex;
834
+ flex-direction: column;
835
+ gap: 2px;
465
836
  }
466
837
 
467
- .nxg-row--clickable {
838
+ .tbx-filter-option {
839
+ display: flex;
840
+ align-items: center;
841
+ gap: 6px;
842
+ padding: 6px 8px;
843
+ font-size: 12px;
844
+ color: var(--tbx-fg);
845
+ border-radius: 4px;
468
846
  cursor: pointer;
469
847
  }
470
848
 
471
- .nxg-td {
472
- padding: 12px 16px;
849
+ .tbx-filter-option:hover {
850
+ background: var(--tbx-muted);
473
851
  }
474
852
 
475
- .nxg-td--serial {
476
- width: 48px;
477
- padding: 0 12px;
478
- text-align: center;
479
- font-weight: 700;
853
+ .tbx-filter-option--selected {
854
+ font-weight: 600;
855
+ color: var(--tbx-primary);
856
+ background: color-mix(in srgb, var(--tbx-primary) 10%, transparent);
857
+ }
858
+
859
+ .tbx-filter-popover-actions {
860
+ display: flex;
861
+ justify-content: flex-end;
862
+ gap: 6px;
863
+ margin-top: 8px;
864
+ padding-top: 6px;
865
+ border-top: 1px solid var(--tbx-border);
866
+ }
867
+
868
+ .tbx-filter-popover-btn {
869
+ display: inline-flex;
870
+ align-items: center;
871
+ gap: 5px;
872
+ padding: 4px 10px;
480
873
  font-size: 12px;
481
- color: var(--nxg-muted-fg);
482
- font-family: var(--nxg-font-mono);
874
+ font-weight: 500;
875
+ font-family: inherit;
876
+ color: var(--tbx-fg);
877
+ background: var(--tbx-card);
878
+ border: 1px solid var(--tbx-border);
879
+ border-radius: 4px;
880
+ cursor: pointer;
881
+ transition: all 120ms ease;
882
+ }
883
+
884
+ .tbx-filter-popover-btn .tbx-icon {
885
+ width: 12px;
886
+ height: 12px;
887
+ }
888
+
889
+ .tbx-filter-popover-btn:hover {
890
+ background: var(--tbx-card-2);
891
+ border-color: #94a3b8;
892
+ }
893
+
894
+ .tbx-filter-popover-btn--primary {
895
+ color: #ffffff;
896
+ background: var(--tbx-primary-active);
897
+ border-color: var(--tbx-primary-active);
898
+ }
899
+
900
+ .tbx-filter-popover-btn--primary:hover {
901
+ opacity: 0.9;
902
+ }
903
+
904
+ /* ---- Column resize handles ---- */
905
+ .tbx-resize-handle {
906
+ position: absolute;
907
+ top: 0;
908
+ right: 0;
909
+ bottom: 0;
910
+ width: 8px;
911
+ cursor: col-resize;
483
912
  user-select: none;
913
+ touch-action: none;
914
+ z-index: 10;
484
915
  }
485
916
 
486
- .nxg-td--select {
487
- width: 40px;
488
- padding: 12px;
917
+ .tbx-resize-handle::after {
918
+ content: "";
919
+ position: absolute;
920
+ top: 20%;
921
+ bottom: 20%;
922
+ right: 3px;
923
+ width: 2px;
924
+ background: var(--tbx-border);
925
+ opacity: 0;
926
+ transition: opacity 120ms ease, background-color 120ms ease;
927
+ }
928
+
929
+ .tbx-th:hover .tbx-resize-handle::after,
930
+ .tbx-resize-handle:hover::after,
931
+ .tbx-resize-handle--active::after {
932
+ opacity: 1;
933
+ background: var(--tbx-primary);
934
+ }
935
+
936
+ .tbx-resizing {
937
+ cursor: col-resize !important;
938
+ user-select: none !important;
939
+ }
940
+
941
+ .tbx-table tbody {
942
+ background: var(--tbx-card);
943
+ }
944
+
945
+ .tbx-row {
946
+ white-space: nowrap;
947
+ transition: background-color 100ms ease;
948
+ background: var(--tbx-card);
949
+ }
950
+
951
+ .tbx-row:hover:not(.tbx-row--selected) {
952
+ background: var(--tbx-card-2);
953
+ }
954
+
955
+ .tbx-row--selected {
956
+ background-color: var(--tbx-selected-bg) !important;
957
+ }
958
+
959
+ .tbx-row--selected:hover {
960
+ background-color: color-mix(in srgb, var(--tbx-primary) 20%, var(--tbx-selected-bg)) !important;
961
+ }
962
+
963
+ .tbx-row--clickable {
964
+ cursor: pointer;
965
+ }
966
+
967
+ .tbx-td {
968
+ padding: 12px 14px;
969
+ color: var(--tbx-fg);
970
+ font-size: 13px;
971
+ border-bottom: 1px solid var(--tbx-border);
972
+ vertical-align: middle;
973
+ }
974
+
975
+ .tbx-row:last-child .tbx-td {
976
+ border-bottom: none;
977
+ }
978
+
979
+ .tbx-td--serial {
980
+ width: 56px;
981
+ padding: 12px 10px;
982
+ text-align: center;
983
+ font-weight: 600;
984
+ font-size: 13px;
985
+ color: var(--tbx-fg);
986
+ user-select: none;
987
+ }
988
+
989
+ .tbx-td--select {
990
+ width: 44px;
991
+ padding: 12px 8px;
489
992
  text-align: center;
490
993
  }
491
994
 
492
995
  /* Density: padding + font-size on data cells */
493
- .nxg-root[data-density="compact"] .nxg-td {
996
+ .tbx-root[data-density="compact"] .tbx-td {
494
997
  padding-top: 8px;
495
998
  padding-bottom: 8px;
496
999
  font-size: 12px;
497
1000
  }
498
1001
 
499
- .nxg-root[data-density="default"] .nxg-td {
1002
+ .tbx-root[data-density="default"] .tbx-td {
500
1003
  padding-top: 12px;
501
1004
  padding-bottom: 12px;
502
- font-size: 14px;
1005
+ font-size: 13px;
503
1006
  }
504
1007
 
505
- .nxg-root[data-density="comfortable"] .nxg-td {
1008
+ .tbx-root[data-density="comfortable"] .tbx-td {
506
1009
  padding-top: 16px;
507
1010
  padding-bottom: 16px;
508
1011
  font-size: 14px;
@@ -510,407 +1013,527 @@
510
1013
 
511
1014
  /* ---- Checkbox ---- */
512
1015
 
513
- .nxg-checkbox {
1016
+ .tbx-checkbox {
514
1017
  appearance: none;
515
- width: 16px;
516
- height: 16px;
1018
+ width: 18px;
1019
+ height: 18px;
517
1020
  margin: 0;
518
- border: 1px solid var(--nxg-border);
1021
+ border: 1.5px solid #d1d5db;
519
1022
  border-radius: 4px;
520
- background: var(--nxg-bg);
1023
+ background: #ffffff;
521
1024
  cursor: pointer;
522
1025
  display: inline-block;
523
1026
  vertical-align: middle;
524
1027
  position: relative;
1028
+ transition: all 120ms ease;
1029
+ }
1030
+
1031
+ .tbx-dark .tbx-checkbox {
1032
+ border-color: #64748b;
1033
+ background: #1e293b;
1034
+ }
1035
+
1036
+ .tbx-checkbox[type="radio"] {
1037
+ border-radius: 50%;
525
1038
  }
526
1039
 
527
- .nxg-checkbox:checked {
528
- background: var(--nxg-primary);
529
- border-color: var(--nxg-primary);
1040
+ .tbx-checkbox:checked {
1041
+ background: var(--tbx-primary);
1042
+ border-color: var(--tbx-primary);
530
1043
  }
531
1044
 
532
- .nxg-checkbox:checked::after {
1045
+ .tbx-checkbox:checked::after {
533
1046
  content: "";
534
1047
  position: absolute;
535
- left: 4.5px;
536
- top: 1.5px;
537
- width: 4px;
538
- height: 8px;
539
- border: solid var(--nxg-primary-fg);
1048
+ left: 5px;
1049
+ top: 2px;
1050
+ width: 5px;
1051
+ height: 9px;
1052
+ border: solid var(--tbx-primary-fg);
540
1053
  border-width: 0 2px 2px 0;
541
1054
  transform: rotate(45deg);
542
1055
  }
543
1056
 
544
- .nxg-checkbox:focus-visible {
545
- outline: none;
546
- box-shadow: var(--nxg-focus-ring);
1057
+ .tbx-checkbox[type="radio"]:checked::after {
1058
+ left: 4px;
1059
+ top: 4px;
1060
+ width: 6px;
1061
+ height: 6px;
1062
+ border-radius: 50%;
1063
+ background: var(--tbx-primary-fg);
1064
+ border: none;
1065
+ transform: none;
1066
+ }
1067
+
1068
+ .tbx-checkbox:focus-visible {
1069
+ outline: none;
1070
+ box-shadow: var(--tbx-focus-ring);
547
1071
  }
548
1072
 
549
1073
  /* ==========================================================================
550
1074
  Empty / loading / error states
551
1075
  ========================================================================== */
552
1076
 
553
- .nxg-state {
1077
+ .tbx-state {
554
1078
  padding: 48px 16px;
555
1079
  text-align: center;
556
- color: var(--nxg-muted-fg);
1080
+ color: var(--tbx-muted-fg);
557
1081
  font-size: 14px;
558
1082
  }
559
1083
 
560
- .nxg-state-card {
561
- background: var(--nxg-card);
562
- border: 1px solid var(--nxg-border);
563
- border-radius: var(--nxg-radius);
564
- box-shadow: var(--nxg-shadow);
1084
+ .tbx-state-card {
1085
+ background: var(--tbx-card);
1086
+ border: 1px solid var(--tbx-border);
1087
+ border-radius: var(--tbx-radius);
1088
+ box-shadow: var(--tbx-shadow);
565
1089
  padding: 32px;
566
1090
  text-align: center;
567
1091
  }
568
1092
 
569
- .nxg-state-card .nxg-state-text {
1093
+ .tbx-state-card .tbx-state-text {
570
1094
  font-size: 14px;
571
1095
  font-weight: 500;
572
- color: var(--nxg-muted-fg);
1096
+ color: var(--tbx-muted-fg);
573
1097
  margin: 0;
574
1098
  }
575
1099
 
576
- .nxg-state-card .nxg-btn {
1100
+ .tbx-state-card .tbx-btn {
577
1101
  margin-top: 12px;
578
1102
  }
579
1103
 
580
- .nxg-spinner {
581
- display: inline-block;
582
- width: 22px;
583
- height: 22px;
584
- margin-bottom: 8px;
585
- border: 2.5px solid var(--nxg-border);
586
- border-top-color: var(--nxg-primary);
1104
+ /* Crisp linear dotted loader */
1105
+ .tbx-dotted-loader {
1106
+ display: inline-flex;
1107
+ align-items: center;
1108
+ justify-content: center;
1109
+ gap: 6px;
1110
+ margin-bottom: 12px;
1111
+ }
1112
+
1113
+ .tbx-dot {
1114
+ width: 7px;
1115
+ height: 7px;
587
1116
  border-radius: 50%;
588
- animation: nxg-spin 700ms linear infinite;
1117
+ background-color: var(--tbx-primary);
1118
+ display: inline-block;
1119
+ animation: tbx-dot-pulse 1.3s infinite ease-in-out both;
589
1120
  }
590
1121
 
591
- @keyframes nxg-spin {
592
- to {
593
- transform: rotate(360deg);
1122
+ .tbx-dot:nth-child(1) {
1123
+ animation-delay: -0.36s;
1124
+ }
1125
+
1126
+ .tbx-dot:nth-child(2) {
1127
+ animation-delay: -0.18s;
1128
+ }
1129
+
1130
+ .tbx-dot:nth-child(3) {
1131
+ animation-delay: 0s;
1132
+ }
1133
+
1134
+ .tbx-dot:nth-child(4) {
1135
+ animation-delay: 0.18s;
1136
+ }
1137
+
1138
+ @keyframes tbx-dot-pulse {
1139
+ 0%, 80%, 100% {
1140
+ transform: scale(0.65);
1141
+ opacity: 0.3;
1142
+ }
1143
+ 40% {
1144
+ transform: scale(1.2);
1145
+ opacity: 1;
594
1146
  }
595
1147
  }
596
1148
 
1149
+ .tbx-loading-text {
1150
+ font-size: 13px;
1151
+ font-weight: 500;
1152
+ color: var(--tbx-muted-fg);
1153
+ letter-spacing: 0.01em;
1154
+ }
1155
+
1156
+ .tbx-spinner {
1157
+ display: none;
1158
+ }
1159
+
597
1160
  /* ==========================================================================
598
1161
  Card list (< 768px)
599
1162
  ========================================================================== */
600
1163
 
601
- .nxg-cards {
602
- display: flex;
603
- flex-direction: column;
604
- gap: 10px;
605
- }
606
-
607
- @media (min-width: 768px) {
608
- .nxg-cards {
609
- display: none;
610
- }
1164
+ .tbx-card {
1165
+ background: var(--tbx-card);
1166
+ border: 1px solid var(--tbx-border);
1167
+ border-radius: 10px;
1168
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
1169
+ padding: 12px;
1170
+ transition: background-color 140ms ease, border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
1171
+ overflow: hidden;
611
1172
  }
612
1173
 
613
- .nxg-card {
614
- background: var(--nxg-card);
615
- border: 1px solid var(--nxg-border);
616
- border-radius: var(--nxg-radius);
617
- box-shadow: var(--nxg-shadow);
618
- padding: 14px;
619
- transition: background-color 120ms ease, border-color 120ms ease;
1174
+ .tbx-card:hover {
1175
+ border-color: color-mix(in srgb, var(--tbx-border) 80%, var(--tbx-primary));
620
1176
  }
621
1177
 
622
- .nxg-card--selected {
623
- border-color: color-mix(in srgb, var(--nxg-primary) 40%, transparent);
624
- background: color-mix(in srgb, var(--nxg-primary) 5%, var(--nxg-card));
1178
+ .tbx-card--selected {
1179
+ border-color: var(--tbx-primary);
1180
+ background: var(--tbx-selected-bg);
625
1181
  }
626
1182
 
627
- .nxg-card--clickable {
1183
+ .tbx-card--clickable {
628
1184
  cursor: pointer;
629
1185
  }
630
1186
 
631
- .nxg-card--clickable:active {
632
- background: color-mix(in srgb, var(--nxg-muted) 50%, var(--nxg-card));
1187
+ .tbx-card--clickable:active {
1188
+ transform: scale(0.995);
1189
+ background: var(--tbx-muted);
633
1190
  }
634
1191
 
635
- .nxg-card-head {
1192
+ .tbx-card-head {
636
1193
  display: flex;
637
1194
  align-items: center;
1195
+ justify-content: space-between;
638
1196
  gap: 8px;
639
- margin-bottom: 10px;
640
- padding-bottom: 8px;
641
- border-bottom: 1px solid color-mix(in srgb, var(--nxg-border) 70%, transparent);
1197
+ margin-bottom: 8px;
1198
+ padding: 2px 4px 8px 4px;
1199
+ border-bottom: 1px solid var(--tbx-border);
642
1200
  }
643
1201
 
644
- .nxg-card-serial {
645
- font-family: var(--nxg-font-mono);
1202
+ .tbx-card-serial {
1203
+ font-family: var(--tbx-font-mono);
646
1204
  font-size: 12px;
647
1205
  font-weight: 700;
648
- color: var(--nxg-muted-fg);
1206
+ color: var(--tbx-primary);
1207
+ background: color-mix(in srgb, var(--tbx-primary) 10%, transparent);
1208
+ padding: 2px 8px;
1209
+ border-radius: 4px;
649
1210
  }
650
1211
 
651
- .nxg-card-select {
1212
+ .tbx-card-select {
652
1213
  margin-inline-start: auto;
1214
+ display: flex;
1215
+ align-items: center;
653
1216
  }
654
1217
 
655
- .nxg-card-rows {
1218
+ .tbx-card-rows {
656
1219
  display: flex;
657
1220
  flex-direction: column;
658
- gap: 8px;
1221
+ gap: 2px;
659
1222
  margin: 0;
1223
+ padding: 0;
660
1224
  }
661
1225
 
662
- .nxg-card-row {
1226
+ .tbx-card-row {
663
1227
  display: flex;
664
- align-items: flex-start;
1228
+ align-items: center;
665
1229
  justify-content: space-between;
666
1230
  gap: 12px;
1231
+ min-width: 0;
1232
+ padding: 7px 10px;
1233
+ border-radius: 6px;
1234
+ transition: background-color 100ms ease;
1235
+ }
1236
+
1237
+ /* Striped styling for mobile cards */
1238
+ .tbx-card-row:nth-child(odd) {
1239
+ background-color: #f8fafc;
1240
+ }
1241
+
1242
+ .tbx-card-row:nth-child(even) {
1243
+ background-color: transparent;
1244
+ }
1245
+
1246
+ .tbx-dark .tbx-card-row:nth-child(odd) {
1247
+ background-color: rgba(255, 255, 255, 0.035);
1248
+ }
1249
+
1250
+ .tbx-dark .tbx-card-row:nth-child(even) {
1251
+ background-color: transparent;
667
1252
  }
668
1253
 
669
- .nxg-card-row dt {
1254
+ .tbx-card-row:hover {
1255
+ background-color: #f1f5f9;
1256
+ }
1257
+
1258
+ .tbx-dark .tbx-card-row:hover {
1259
+ background-color: rgba(255, 255, 255, 0.07);
1260
+ }
1261
+
1262
+ .tbx-card-row dt {
670
1263
  flex-shrink: 0;
671
- font-size: 12px;
672
- font-weight: 500;
673
- color: var(--nxg-muted-fg);
1264
+ font-size: 11px;
1265
+ font-weight: 600;
1266
+ text-transform: uppercase;
1267
+ letter-spacing: 0.04em;
1268
+ color: #64748b;
1269
+ padding-top: 0;
674
1270
  }
675
1271
 
676
- .nxg-card-row dd {
1272
+ .tbx-dark .tbx-card-row dt {
1273
+ color: #94a3b8;
1274
+ }
1275
+
1276
+ .tbx-card-row dd {
677
1277
  min-width: 0;
678
1278
  margin: 0;
679
1279
  overflow-wrap: break-word;
680
1280
  text-align: end;
681
- font-size: 14px;
682
- color: var(--nxg-fg);
1281
+ font-size: 13px;
1282
+ font-weight: 500;
1283
+ color: var(--tbx-fg);
683
1284
  }
684
1285
 
685
1286
  /* ==========================================================================
686
1287
  Footer / pagination
687
1288
  ========================================================================== */
688
1289
 
689
- .nxg-footer {
1290
+ .tbx-footer {
690
1291
  display: flex;
691
1292
  flex-direction: column;
692
1293
  align-items: center;
693
1294
  justify-content: space-between;
694
1295
  gap: 14px;
695
1296
  width: 100%;
696
- padding: 14px;
697
- background: var(--nxg-card);
698
- border: 1px solid var(--nxg-border);
699
- border-radius: var(--nxg-radius);
700
- box-shadow: var(--nxg-shadow);
701
- font-size: 12px;
1297
+ padding: 4px 0 0 0;
1298
+ background: transparent;
1299
+ border: none;
1300
+ box-shadow: none;
1301
+ font-size: 13px;
702
1302
  font-weight: 500;
703
1303
  }
704
1304
 
705
1305
  @media (min-width: 768px) {
706
- .nxg-footer {
1306
+ .tbx-footer {
707
1307
  flex-direction: row;
708
1308
  }
709
1309
  }
710
1310
 
711
- .nxg-range {
1311
+ .tbx-range {
712
1312
  display: flex;
713
1313
  flex-wrap: wrap;
714
1314
  align-items: center;
715
1315
  justify-content: center;
716
- gap: 8px;
717
- color: var(--nxg-muted-fg);
1316
+ gap: 4px;
1317
+ color: #374151;
1318
+ font-size: 13px;
1319
+ font-weight: 500;
718
1320
  text-align: center;
719
1321
  }
720
1322
 
1323
+ .tbx-dark .tbx-range {
1324
+ color: var(--tbx-muted-fg);
1325
+ }
1326
+
721
1327
  @media (min-width: 768px) {
722
- .nxg-range {
1328
+ .tbx-range {
723
1329
  justify-content: flex-start;
724
1330
  text-align: left;
725
1331
  }
726
1332
  }
727
1333
 
728
- .nxg-range strong {
729
- font-weight: 700;
730
- color: var(--nxg-fg);
731
- padding: 2px 6px;
732
- border-radius: 4px;
733
- background: var(--nxg-muted);
734
- border: 1px solid var(--nxg-border);
735
- box-shadow: var(--nxg-shadow);
736
- }
737
-
738
- .nxg-range strong.nxg-range-total {
739
- color: var(--nxg-primary);
740
- background: color-mix(in srgb, var(--nxg-primary) 10%, transparent);
741
- border-color: color-mix(in srgb, var(--nxg-primary) 20%, transparent);
1334
+ .tbx-range strong {
1335
+ font-weight: 600;
1336
+ color: var(--tbx-fg);
1337
+ padding: 0 1px;
1338
+ background: transparent;
1339
+ border: none;
1340
+ box-shadow: none;
742
1341
  }
743
1342
 
744
- .nxg-selected-badge {
1343
+ .tbx-selected-badge {
745
1344
  display: inline-flex;
746
1345
  align-items: center;
1346
+ margin-left: 8px;
747
1347
  padding: 2px 8px;
748
1348
  border-radius: 6px;
749
- font-weight: 700;
750
- color: var(--nxg-primary);
751
- background: color-mix(in srgb, var(--nxg-primary) 15%, transparent);
752
- border: 1px solid color-mix(in srgb, var(--nxg-primary) 30%, transparent);
1349
+ font-size: 12px;
1350
+ font-weight: 600;
1351
+ color: var(--tbx-primary);
1352
+ background: color-mix(in srgb, var(--tbx-primary) 12%, transparent);
753
1353
  }
754
1354
 
755
- .nxg-pagination {
1355
+ .tbx-pagination {
756
1356
  display: flex;
757
1357
  flex-wrap: wrap;
758
1358
  align-items: center;
759
1359
  justify-content: center;
760
- gap: 10px;
1360
+ gap: 14px;
761
1361
  max-width: 100%;
762
1362
  }
763
1363
 
764
1364
  @media (min-width: 768px) {
765
- .nxg-pagination {
1365
+ .tbx-pagination {
766
1366
  justify-content: flex-end;
767
1367
  }
768
1368
  }
769
1369
 
770
- .nxg-rows-per-page {
1370
+ .tbx-rows-per-page {
771
1371
  display: flex;
772
1372
  align-items: center;
773
- gap: 6px;
774
- font-size: 12px;
775
- color: var(--nxg-muted-fg);
1373
+ gap: 8px;
1374
+ font-size: 13px;
1375
+ color: #374151;
776
1376
  font-weight: 500;
777
1377
  }
778
1378
 
779
- .nxg-rows-select {
1379
+ .tbx-dark .tbx-rows-per-page {
1380
+ color: var(--tbx-muted-fg);
1381
+ }
1382
+
1383
+ .tbx-rows-select {
780
1384
  height: 32px;
781
- min-width: 64px;
1385
+ min-width: 72px;
782
1386
  padding: 0 8px;
783
- font-size: 12px;
784
- font-weight: 700;
1387
+ font-size: 13px;
1388
+ font-weight: 500;
785
1389
  font-family: inherit;
786
- color: var(--nxg-fg);
787
- background: var(--nxg-bg);
788
- border: 1px solid var(--nxg-border);
789
- border-radius: var(--nxg-radius-sm);
790
- box-shadow: var(--nxg-shadow);
1390
+ color: var(--tbx-fg);
1391
+ background: var(--tbx-bg);
1392
+ border: 1px solid #d1d5db;
1393
+ border-radius: var(--tbx-radius-xs);
791
1394
  cursor: pointer;
792
1395
  outline: none;
1396
+ transition: border-color 120ms ease;
793
1397
  }
794
1398
 
795
- .nxg-rows-select:focus {
796
- border-color: var(--nxg-primary);
797
- box-shadow: var(--nxg-focus-ring);
1399
+ .tbx-dark .tbx-rows-select {
1400
+ border-color: var(--tbx-border);
798
1401
  }
799
1402
 
800
- .nxg-pager {
801
- display: inline-flex;
802
- align-items: center;
803
- max-width: 100%;
804
- overflow-x: auto;
805
- background: var(--nxg-bg);
806
- border: 1px solid var(--nxg-border);
807
- border-radius: var(--nxg-radius-sm);
808
- box-shadow: var(--nxg-shadow);
1403
+ .tbx-rows-select:focus {
1404
+ border-color: var(--tbx-primary);
1405
+ box-shadow: var(--tbx-focus-ring);
809
1406
  }
810
1407
 
811
- .nxg-pager > * + * {
812
- border-left: 1px solid var(--nxg-border);
1408
+ .tbx-pager {
1409
+ display: inline-flex;
1410
+ align-items: center;
1411
+ gap: 4px;
1412
+ background: transparent;
1413
+ border: none;
1414
+ box-shadow: none;
813
1415
  }
814
1416
 
815
- .nxg-page-btn,
816
- .nxg-page-nav {
817
- padding: 6px 12px;
1417
+ .tbx-page-btn,
1418
+ .tbx-page-nav {
818
1419
  min-width: 32px;
819
- font-size: 12px;
820
- font-weight: 700;
1420
+ height: 32px;
1421
+ padding: 0 6px;
1422
+ font-size: 13px;
1423
+ font-weight: 500;
821
1424
  font-family: inherit;
822
1425
  text-align: center;
823
- color: var(--nxg-fg);
824
- background: transparent;
825
- border: 0;
1426
+ color: #374151;
1427
+ background: #ffffff;
1428
+ border: 1px solid var(--tbx-border);
1429
+ border-radius: var(--tbx-radius-xs);
826
1430
  cursor: pointer;
827
1431
  flex-shrink: 0;
828
- transition: background-color 120ms ease, color 120ms ease;
829
- }
830
-
831
- .nxg-page-nav {
832
1432
  display: inline-flex;
833
1433
  align-items: center;
834
- padding: 6px 10px;
835
- color: var(--nxg-muted-fg);
1434
+ justify-content: center;
1435
+ transition: all 120ms ease;
836
1436
  }
837
1437
 
838
- .nxg-page-btn:hover,
839
- .nxg-page-nav:hover {
840
- background: var(--nxg-muted);
841
- color: var(--nxg-fg);
1438
+ .tbx-dark .tbx-page-btn,
1439
+ .tbx-dark .tbx-page-nav {
1440
+ background: #1e293b;
1441
+ color: var(--tbx-fg);
842
1442
  }
843
1443
 
844
- .nxg-page-btn--current {
845
- background: var(--nxg-primary);
846
- color: var(--nxg-primary-fg);
847
- box-shadow: var(--nxg-shadow);
1444
+ .tbx-page-nav {
1445
+ color: #6b7280;
848
1446
  }
849
1447
 
850
- .nxg-page-btn--current:hover {
851
- background: var(--nxg-primary);
852
- color: var(--nxg-primary-fg);
1448
+ .tbx-page-btn:hover:not(.tbx-page-btn--current),
1449
+ .tbx-page-nav:hover:not(:disabled) {
1450
+ background: #f3f4f6;
1451
+ border-color: #d1d5db;
1452
+ color: #111827;
853
1453
  }
854
1454
 
855
- .nxg-page-nav:disabled {
856
- opacity: 0.3;
1455
+ .tbx-dark .tbx-page-btn:hover:not(.tbx-page-btn--current),
1456
+ .tbx-dark .tbx-page-nav:hover:not(:disabled) {
1457
+ background: #334155;
1458
+ border-color: #475569;
1459
+ color: #ffffff;
1460
+ }
1461
+
1462
+ .tbx-page-btn--current {
1463
+ background: var(--tbx-primary-active) !important;
1464
+ border-color: var(--tbx-primary-active) !important;
1465
+ color: #ffffff !important;
1466
+ font-weight: 600;
1467
+ box-shadow: 0 1px 2px rgba(29, 78, 216, 0.2);
1468
+ }
1469
+
1470
+ .tbx-page-nav:disabled {
1471
+ opacity: 0.35;
857
1472
  cursor: not-allowed;
858
1473
  background: transparent;
859
1474
  }
860
1475
 
861
- .nxg-page-ellipsis {
862
- padding: 6px 10px;
863
- color: var(--nxg-muted-fg);
1476
+ .tbx-page-ellipsis {
1477
+ padding: 0 4px;
1478
+ color: #9ca3af;
1479
+ font-size: 13px;
864
1480
  user-select: none;
865
1481
  flex-shrink: 0;
866
1482
  }
867
1483
 
868
- .nxg-jump {
1484
+ .tbx-jump {
869
1485
  display: flex;
870
1486
  align-items: center;
871
1487
  gap: 6px;
872
1488
  }
873
1489
 
874
- .nxg-jump-label {
875
- font-size: 12px;
876
- font-weight: 700;
877
- color: var(--nxg-fg);
1490
+ .tbx-jump-label {
1491
+ font-size: 13px;
1492
+ font-weight: 500;
1493
+ color: #374151;
878
1494
  cursor: pointer;
879
1495
  white-space: nowrap;
880
1496
  }
881
1497
 
882
- .nxg-jump-input {
1498
+ .tbx-dark .tbx-jump-label {
1499
+ color: var(--tbx-muted-fg);
1500
+ }
1501
+
1502
+ .tbx-jump-input {
883
1503
  width: 48px;
884
1504
  height: 32px;
885
1505
  text-align: center;
886
- font-size: 12px;
887
- font-weight: 700;
1506
+ font-size: 13px;
1507
+ font-weight: 600;
888
1508
  font-family: inherit;
889
- color: var(--nxg-primary);
890
- background: var(--nxg-bg);
891
- border: 1px solid var(--nxg-border);
892
- border-radius: var(--nxg-radius-sm);
893
- box-shadow: var(--nxg-shadow);
1509
+ color: var(--tbx-primary);
1510
+ background: var(--tbx-bg);
1511
+ border: 1px solid #d1d5db;
1512
+ border-radius: var(--tbx-radius-xs);
894
1513
  outline: none;
895
1514
  -moz-appearance: textfield;
896
1515
  }
897
1516
 
898
- .nxg-jump-input::-webkit-outer-spin-button,
899
- .nxg-jump-input::-webkit-inner-spin-button {
1517
+ .tbx-dark .tbx-jump-input {
1518
+ border-color: var(--tbx-border);
1519
+ }
1520
+
1521
+ .tbx-jump-input::-webkit-outer-spin-button,
1522
+ .tbx-jump-input::-webkit-inner-spin-button {
900
1523
  -webkit-appearance: none;
901
1524
  margin: 0;
902
1525
  }
903
1526
 
904
- .nxg-jump-input:focus {
905
- border-color: var(--nxg-primary);
906
- box-shadow: var(--nxg-focus-ring);
1527
+ .tbx-jump-input:focus {
1528
+ border-color: var(--tbx-primary);
1529
+ box-shadow: var(--tbx-focus-ring);
907
1530
  }
908
1531
 
909
1532
  /* ==========================================================================
910
- Utilities
1533
+ Utilities & Cells (Avatars, Badges, Cell-stack, Actions)
911
1534
  ========================================================================== */
912
1535
 
913
- .nxg-sr-only {
1536
+ .tbx-sr-only {
914
1537
  position: absolute;
915
1538
  width: 1px;
916
1539
  height: 1px;
@@ -922,10 +1545,531 @@
922
1545
  border: 0;
923
1546
  }
924
1547
 
925
- .nxg-align-center {
1548
+ .tbx-align-center {
926
1549
  text-align: center;
927
1550
  }
928
1551
 
929
- .nxg-align-right {
1552
+ .tbx-align-right {
930
1553
  text-align: right;
931
1554
  }
1555
+
1556
+ .cell-user,
1557
+ .tbx-cell-user {
1558
+ display: inline-flex;
1559
+ align-items: center;
1560
+ gap: 10px;
1561
+ text-align: left;
1562
+ }
1563
+
1564
+ .avatar,
1565
+ .tbx-avatar {
1566
+ width: 32px;
1567
+ height: 32px;
1568
+ border-radius: 50%;
1569
+ object-fit: cover;
1570
+ background: #e5e7eb;
1571
+ border: 1px solid var(--tbx-border);
1572
+ flex-shrink: 0;
1573
+ }
1574
+
1575
+ .cell-stack,
1576
+ .tbx-cell-stack {
1577
+ display: inline-flex;
1578
+ flex-direction: column;
1579
+ line-height: 1.3;
1580
+ text-align: left;
1581
+ }
1582
+
1583
+ .cell-stack strong,
1584
+ .tbx-cell-stack strong {
1585
+ font-size: 13.5px;
1586
+ font-weight: 600;
1587
+ color: var(--tbx-fg);
1588
+ }
1589
+
1590
+ .cell-stack small,
1591
+ .tbx-cell-stack small {
1592
+ font-size: 12px;
1593
+ color: var(--tbx-muted-fg);
1594
+ }
1595
+
1596
+ .badge,
1597
+ .tbx-badge {
1598
+ display: inline-flex;
1599
+ align-items: center;
1600
+ justify-content: center;
1601
+ padding: 3px 12px;
1602
+ border-radius: 9999px;
1603
+ font-size: 12px;
1604
+ font-weight: 600;
1605
+ line-height: 1.35;
1606
+ white-space: nowrap;
1607
+ background: #e5e7eb;
1608
+ color: #374151;
1609
+ }
1610
+
1611
+ .badge--active,
1612
+ .tbx-badge--active {
1613
+ background: #bbf7d0;
1614
+ color: #166534;
1615
+ }
1616
+
1617
+ .badge--pending,
1618
+ .tbx-badge--pending {
1619
+ background: #fed7aa;
1620
+ color: #9a3412;
1621
+ }
1622
+
1623
+ .badge--suspended,
1624
+ .tbx-badge--suspended {
1625
+ background: #fecaca;
1626
+ color: #991b1b;
1627
+ }
1628
+
1629
+ .badge--alumni,
1630
+ .tbx-badge--alumni {
1631
+ background: #e9d5ff;
1632
+ color: #6b21a8;
1633
+ }
1634
+
1635
+ .badge--scholarship,
1636
+ .tbx-badge--scholarship {
1637
+ background: #e5e7eb;
1638
+ color: #374151;
1639
+ }
1640
+
1641
+ .tbx-dark .badge--active,
1642
+ .tbx-dark .tbx-badge--active {
1643
+ background: rgba(22, 101, 52, 0.4);
1644
+ color: #4ade80;
1645
+ }
1646
+
1647
+ .tbx-dark .badge--pending,
1648
+ .tbx-dark .tbx-badge--pending {
1649
+ background: rgba(180, 83, 9, 0.4);
1650
+ color: #fbbf24;
1651
+ }
1652
+
1653
+ .tbx-dark .badge--suspended,
1654
+ .tbx-dark .tbx-badge--suspended {
1655
+ background: rgba(185, 28, 28, 0.4);
1656
+ color: #f87171;
1657
+ }
1658
+
1659
+ .tbx-dark .badge--alumni,
1660
+ .tbx-dark .tbx-badge--alumni {
1661
+ background: rgba(126, 34, 206, 0.4);
1662
+ color: #c084fc;
1663
+ }
1664
+
1665
+ .tbx-dark .badge--scholarship,
1666
+ .tbx-dark .tbx-badge--scholarship {
1667
+ background: rgba(100, 116, 139, 0.4);
1668
+ color: #cbd5e1;
1669
+ }
1670
+
1671
+ .score {
1672
+ font-variant-numeric: tabular-nums;
1673
+ font-weight: 600;
1674
+ color: var(--tbx-fg);
1675
+ font-size: 13px;
1676
+ }
1677
+
1678
+ .score--high {
1679
+ font-weight: 600;
1680
+ color: var(--tbx-fg);
1681
+ }
1682
+
1683
+ .row-actions {
1684
+ display: inline-flex;
1685
+ align-items: center;
1686
+ gap: 6px;
1687
+ }
1688
+
1689
+ .row-actions .tbx-btn,
1690
+ .btn-action {
1691
+ width: 28px;
1692
+ height: 28px;
1693
+ padding: 0;
1694
+ display: inline-flex;
1695
+ align-items: center;
1696
+ justify-content: center;
1697
+ border-radius: 6px;
1698
+ border: 1px solid #d1d5db;
1699
+ background: #ffffff;
1700
+ color: #6b7280;
1701
+ cursor: pointer;
1702
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
1703
+ }
1704
+
1705
+ .tbx-dark .row-actions .tbx-btn,
1706
+ .tbx-dark .btn-action {
1707
+ background: #1e293b;
1708
+ border-color: #475569;
1709
+ color: #94a3b8;
1710
+ }
1711
+
1712
+ .row-actions .tbx-btn:hover,
1713
+ .btn-action:hover {
1714
+ background: #f3f4f6;
1715
+ color: #111827;
1716
+ border-color: #9ca3af;
1717
+ }
1718
+
1719
+ .tbx-dark .row-actions .tbx-btn:hover,
1720
+ .tbx-dark .btn-action:hover {
1721
+ background: #334155;
1722
+ color: #ffffff;
1723
+ }
1724
+
1725
+ /* ==========================================================================
1726
+ Enterprise Features
1727
+ ========================================================================== */
1728
+
1729
+ /* ---- Pinned / Sticky Columns ---- */
1730
+ .tbx-th--pinned-left,
1731
+ .tbx-td--pinned-left {
1732
+ position: sticky !important;
1733
+ left: 0;
1734
+ z-index: 2;
1735
+ background-color: var(--tbx-card);
1736
+ }
1737
+
1738
+ .tbx-th--pinned-right,
1739
+ .tbx-td--pinned-right {
1740
+ position: sticky !important;
1741
+ right: 0;
1742
+ z-index: 2;
1743
+ background-color: var(--tbx-card);
1744
+ }
1745
+
1746
+ .tbx-th.tbx-th--pinned-left,
1747
+ .tbx-th.tbx-th--pinned-right {
1748
+ z-index: 4;
1749
+ background-color: var(--tbx-card-2);
1750
+ }
1751
+
1752
+ .tbx-pinned-border-left {
1753
+ box-shadow: inset -1px 0 0 var(--tbx-border), 4px 0 8px -3px rgba(0, 0, 0, 0.08);
1754
+ }
1755
+
1756
+ .tbx-pinned-border-right {
1757
+ box-shadow: inset 1px 0 0 var(--tbx-border), -4px 0 8px -3px rgba(0, 0, 0, 0.08);
1758
+ }
1759
+
1760
+ /* ---- Bulk Actions Floating Bar ---- */
1761
+ .tbx-bulk-bar {
1762
+ position: sticky;
1763
+ bottom: 16px;
1764
+ margin: -48px auto 0 auto;
1765
+ width: fit-content;
1766
+ max-width: calc(100% - 32px);
1767
+ z-index: 30;
1768
+ display: flex;
1769
+ align-items: center;
1770
+ gap: 10px;
1771
+ padding: 6px 14px;
1772
+ background: #0f172a;
1773
+ color: #f8fafc;
1774
+ border-radius: 9999px;
1775
+ box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -4px rgba(0, 0, 0, 0.2);
1776
+ font-size: 13px;
1777
+ font-weight: 500;
1778
+ animation: tbx-slide-up 180ms cubic-bezier(0.16, 1, 0.3, 1);
1779
+ }
1780
+
1781
+ @keyframes tbx-slide-up {
1782
+ from {
1783
+ opacity: 0;
1784
+ transform: translateY(12px) scale(0.96);
1785
+ }
1786
+ to {
1787
+ opacity: 1;
1788
+ transform: translateY(0) scale(1);
1789
+ }
1790
+ }
1791
+
1792
+ .tbx-dark .tbx-bulk-bar {
1793
+ background: #1e293b;
1794
+ border: 1px solid #334155;
1795
+ color: #f1f5f9;
1796
+ }
1797
+
1798
+ .tbx-bulk-badge {
1799
+ display: inline-flex;
1800
+ align-items: center;
1801
+ padding: 2px 8px;
1802
+ border-radius: 9999px;
1803
+ background: var(--tbx-primary);
1804
+ color: white;
1805
+ font-size: 12px;
1806
+ font-weight: 700;
1807
+ }
1808
+
1809
+ .tbx-bulk-actions {
1810
+ display: inline-flex;
1811
+ align-items: center;
1812
+ gap: 6px;
1813
+ }
1814
+
1815
+ .tbx-bulk-btn {
1816
+ display: inline-flex;
1817
+ align-items: center;
1818
+ gap: 5px;
1819
+ height: 28px;
1820
+ padding: 0 10px;
1821
+ border-radius: 9999px;
1822
+ border: 1px solid rgba(255, 255, 255, 0.18);
1823
+ background: rgba(255, 255, 255, 0.1);
1824
+ color: #ffffff;
1825
+ font-size: 12px;
1826
+ font-weight: 500;
1827
+ cursor: pointer;
1828
+ transition: background 120ms ease;
1829
+ }
1830
+
1831
+ .tbx-bulk-btn:hover {
1832
+ background: rgba(255, 255, 255, 0.22);
1833
+ }
1834
+
1835
+ .tbx-bulk-btn--close {
1836
+ padding: 0 6px;
1837
+ border: none;
1838
+ background: transparent;
1839
+ opacity: 0.7;
1840
+ }
1841
+
1842
+ .tbx-bulk-btn--close:hover {
1843
+ opacity: 1;
1844
+ background: rgba(255, 255, 255, 0.15);
1845
+ }
1846
+
1847
+ /* ---- Row Expansion / Detail Rows ---- */
1848
+ .tbx-expand-btn {
1849
+ display: inline-flex;
1850
+ align-items: center;
1851
+ justify-content: center;
1852
+ width: 22px;
1853
+ height: 22px;
1854
+ padding: 0;
1855
+ border: none;
1856
+ border-radius: 4px;
1857
+ background: transparent;
1858
+ color: var(--tbx-muted-fg);
1859
+ cursor: pointer;
1860
+ transition: transform 150ms ease, background-color 120ms ease, color 120ms ease;
1861
+ }
1862
+
1863
+ .tbx-expand-btn:hover {
1864
+ background: var(--tbx-muted);
1865
+ color: var(--tbx-fg);
1866
+ }
1867
+
1868
+ .tbx-expand-btn--open {
1869
+ transform: rotate(90deg);
1870
+ }
1871
+
1872
+ .tbx-expanded-row {
1873
+ background-color: #f8fafc;
1874
+ }
1875
+
1876
+ .tbx-dark .tbx-expanded-row {
1877
+ background-color: rgba(255, 255, 255, 0.02);
1878
+ }
1879
+
1880
+ .tbx-expanded-cell {
1881
+ padding: 16px 20px !important;
1882
+ border-bottom: 1px solid var(--tbx-border);
1883
+ }
1884
+
1885
+ .tbx-detail-panel {
1886
+ animation: tbx-fade-in 140ms ease;
1887
+ }
1888
+
1889
+ /* ---- Summary / Aggregation Footer Row ---- */
1890
+ .tbx-table tfoot {
1891
+ border-top: 2px solid var(--tbx-border);
1892
+ }
1893
+
1894
+ .tbx-summary-row {
1895
+ background: var(--tbx-card-2);
1896
+ }
1897
+
1898
+ .tbx-summary-cell {
1899
+ padding: 10px 14px;
1900
+ font-size: 13px;
1901
+ font-weight: 600;
1902
+ color: var(--tbx-fg);
1903
+ border-top: 2px solid var(--tbx-border);
1904
+ border-bottom: 1px solid var(--tbx-border);
1905
+ }
1906
+
1907
+ .tbx-summary-label {
1908
+ font-size: 11px;
1909
+ text-transform: uppercase;
1910
+ letter-spacing: 0.04em;
1911
+ color: var(--tbx-muted-fg);
1912
+ margin-right: 4px;
1913
+ }
1914
+
1915
+ /* ---- Range Filters ---- */
1916
+ .tbx-range-inputs {
1917
+ display: flex;
1918
+ align-items: center;
1919
+ gap: 6px;
1920
+ margin-bottom: 8px;
1921
+ }
1922
+
1923
+ .tbx-range-input {
1924
+ flex: 1;
1925
+ min-width: 0;
1926
+ height: 30px;
1927
+ padding: 0 6px;
1928
+ font-size: 12px;
1929
+ border: 1px solid var(--tbx-border);
1930
+ border-radius: 4px;
1931
+ background: var(--tbx-card);
1932
+ color: var(--tbx-fg);
1933
+ }
1934
+
1935
+ .tbx-range-input:focus {
1936
+ outline: none;
1937
+ border-color: var(--tbx-primary);
1938
+ }
1939
+
1940
+ .tbx-range-sep {
1941
+ font-size: 12px;
1942
+ color: var(--tbx-muted-fg);
1943
+ flex-shrink: 0;
1944
+ }
1945
+
1946
+ /* ---- Column Drag-and-Drop Reordering ---- */
1947
+ .tbx-th--draggable {
1948
+ cursor: grab;
1949
+ }
1950
+
1951
+ .tbx-th--dragging {
1952
+ opacity: 0.4;
1953
+ cursor: grabbing;
1954
+ }
1955
+
1956
+ .tbx-th--drag-over-left {
1957
+ box-shadow: inset 3px 0 0 var(--tbx-primary) !important;
1958
+ }
1959
+
1960
+ .tbx-th--drag-over-right {
1961
+ box-shadow: inset -3px 0 0 var(--tbx-primary) !important;
1962
+ }
1963
+
1964
+ /* ---- Inline Cell Editing ---- */
1965
+ .tbx-cell--editable {
1966
+ cursor: pointer;
1967
+ position: relative;
1968
+ }
1969
+
1970
+ .tbx-cell--editable:hover::after {
1971
+ content: "";
1972
+ position: absolute;
1973
+ inset: 2px;
1974
+ border: 1px dashed color-mix(in srgb, var(--tbx-primary) 50%, transparent);
1975
+ border-radius: 4px;
1976
+ pointer-events: none;
1977
+ }
1978
+
1979
+ .tbx-cell-edit-wrap {
1980
+ display: flex;
1981
+ align-items: center;
1982
+ gap: 4px;
1983
+ width: 100%;
1984
+ }
1985
+
1986
+ .tbx-cell-edit-input {
1987
+ width: 100%;
1988
+ height: 28px;
1989
+ padding: 0 6px;
1990
+ font-size: 13px;
1991
+ border: 1px solid var(--tbx-primary);
1992
+ border-radius: 4px;
1993
+ background: var(--tbx-card);
1994
+ color: var(--tbx-fg);
1995
+ }
1996
+
1997
+ .tbx-cell-edit-input:focus {
1998
+ outline: none;
1999
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--tbx-primary) 20%, transparent);
2000
+ }
2001
+
2002
+ .tbx-cell-edit-actions {
2003
+ display: inline-flex;
2004
+ align-items: center;
2005
+ gap: 2px;
2006
+ flex-shrink: 0;
2007
+ }
2008
+
2009
+ .tbx-cell-edit-btn {
2010
+ display: inline-flex;
2011
+ align-items: center;
2012
+ justify-content: center;
2013
+ width: 24px;
2014
+ height: 24px;
2015
+ padding: 0;
2016
+ border: none;
2017
+ border-radius: 4px;
2018
+ background: transparent;
2019
+ cursor: pointer;
2020
+ }
2021
+
2022
+ .tbx-cell-edit-btn--save {
2023
+ color: #10b981;
2024
+ }
2025
+
2026
+ .tbx-cell-edit-btn--save:hover {
2027
+ background: rgba(16, 185, 129, 0.1);
2028
+ }
2029
+
2030
+ .tbx-cell-edit-btn--cancel {
2031
+ color: #ef4444;
2032
+ }
2033
+
2034
+ .tbx-cell-edit-btn--cancel:hover {
2035
+ background: rgba(239, 68, 68, 0.1);
2036
+ }
2037
+
2038
+ /* ---- Print Optimization ---- */
2039
+ @media print {
2040
+ .tbx-toolbar,
2041
+ .tbx-bulk-bar,
2042
+ .tbx-footer,
2043
+ .tbx-col-filter-wrap,
2044
+ .tbx-cards,
2045
+ .row-actions {
2046
+ display: none !important;
2047
+ }
2048
+
2049
+ .tbx-table-wrap {
2050
+ border: none !important;
2051
+ overflow: visible !important;
2052
+ }
2053
+
2054
+ .tbx-table {
2055
+ width: 100% !important;
2056
+ border-collapse: collapse !important;
2057
+ }
2058
+
2059
+ .tbx-th,
2060
+ .tbx-td,
2061
+ .tbx-summary-cell {
2062
+ border: 1px solid #94a3b8 !important;
2063
+ color: #000000 !important;
2064
+ background: transparent !important;
2065
+ page-break-inside: avoid;
2066
+ }
2067
+ }
2068
+
2069
+
2070
+ .row-actions .tbx-btn .tbx-icon,
2071
+ .btn-action .tbx-icon {
2072
+ width: 14px;
2073
+ height: 14px;
2074
+ color: currentColor;
2075
+ }