@nexgrid/react 0.1.0 → 0.2.1

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,809 +233,1442 @@
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);
430
+ }
431
+
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;
233
463
  }
234
464
 
235
- .nxg-icon {
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;
653
+ .tbx-table thead tr {
654
+ background: var(--tbx-card-2);
655
+ }
656
+
657
+ .tbx-th {
658
+ position: relative;
659
+ padding: 10px 10px 10px 14px;
660
+ font-size: 13px;
376
661
  font-weight: 600;
377
- color: var(--nxg-muted-fg);
662
+ color: var(--tbx-fg);
663
+ border-bottom: 1px solid var(--tbx-border);
664
+ user-select: none;
378
665
  white-space: nowrap;
666
+ background: var(--tbx-card-2);
379
667
  }
380
668
 
381
- .nxg-th {
382
- padding: 12px 16px;
669
+ .tbx-th--serial {
670
+ width: 56px;
671
+ padding: 10px 8px;
672
+ text-align: center;
383
673
  font-weight: 600;
384
- user-select: none;
674
+ font-size: 13px;
675
+ color: var(--tbx-fg);
385
676
  }
386
677
 
387
- .nxg-th--serial {
388
- width: 48px;
389
- padding: 12px;
678
+ .tbx-th--select {
679
+ width: 44px;
680
+ padding: 10px 8px;
681
+ text-align: center;
682
+ }
683
+
684
+ /* Multi-level column header grouping */
685
+ .tbx-th--group {
390
686
  text-align: center;
391
687
  font-weight: 700;
392
- font-size: 12px;
688
+ letter-spacing: 0.02em;
689
+ background: var(--tbx-card-2);
690
+ border-bottom: 1px solid var(--tbx-border);
691
+ border-right: 1px solid var(--tbx-border);
692
+ padding: 8px 12px;
693
+ }
694
+
695
+ .tbx-th-group-title {
696
+ display: inline-block;
697
+ font-size: 11px;
698
+ font-weight: 700;
699
+ letter-spacing: 0.05em;
393
700
  text-transform: uppercase;
701
+ color: var(--tbx-muted-fg);
394
702
  }
395
703
 
396
- .nxg-th--select {
397
- width: 40px;
398
- padding: 12px;
399
- text-align: center;
704
+ .tbx-th--grouped-child {
705
+ border-bottom: 1px solid var(--tbx-border);
400
706
  }
401
707
 
402
- .nxg-th--sortable {
708
+ .tbx-th--sortable {
403
709
  cursor: pointer;
404
- transition: background-color 120ms ease, color 120ms ease;
405
710
  }
406
711
 
407
- .nxg-th--sortable:hover {
408
- color: var(--nxg-fg);
409
- background: var(--nxg-muted);
712
+ .tbx-th--sortable:hover {
713
+ background: var(--tbx-muted);
410
714
  }
411
715
 
412
- .nxg-th-inner {
413
- display: inline-flex;
716
+ .tbx-th--sortable:focus-visible {
717
+ outline: none;
718
+ box-shadow: var(--tbx-focus-ring);
719
+ }
720
+
721
+ .tbx-th-inner {
722
+ display: flex;
414
723
  align-items: center;
415
724
  gap: 6px;
725
+ width: 100%;
726
+ box-sizing: border-box;
416
727
  }
417
728
 
418
- .nxg-th-inner--center {
729
+ .tbx-th-inner--center {
419
730
  justify-content: center;
420
731
  }
421
732
 
422
- .nxg-th-inner--right {
733
+ .tbx-th-inner--right {
423
734
  justify-content: flex-end;
424
735
  }
425
736
 
426
- .nxg-sort-icon {
737
+ .tbx-th-inner > span:first-child {
738
+ display: inline-flex;
739
+ align-items: center;
740
+ min-width: 0;
741
+ }
742
+
743
+ .tbx-sort-icon-wrap {
744
+ display: inline-flex;
745
+ align-items: center;
746
+ gap: 3px;
747
+ flex-shrink: 0;
748
+ }
749
+
750
+ .tbx-sort-icon {
427
751
  width: 14px;
428
752
  height: 14px;
753
+ color: var(--tbx-primary);
429
754
  flex-shrink: 0;
430
- color: var(--nxg-primary);
431
755
  }
432
756
 
433
- .nxg-sort-icon--idle {
757
+ .tbx-sort-icon--idle {
758
+ color: var(--tbx-muted-fg);
434
759
  opacity: 0.4;
435
760
  }
436
761
 
437
- .nxg-th--sortable:hover .nxg-sort-icon--idle {
438
- opacity: 1;
439
- }
440
-
441
- .nxg-table tbody {
442
- background: var(--nxg-card);
762
+ .tbx-sort-order {
763
+ display: inline-flex;
764
+ align-items: center;
765
+ justify-content: center;
766
+ min-width: 16px;
767
+ height: 16px;
768
+ padding: 0 4px;
769
+ font-size: 10px;
770
+ font-weight: 700;
771
+ font-family: var(--tbx-font-mono);
772
+ color: var(--tbx-primary);
773
+ background: color-mix(in srgb, var(--tbx-primary) 15%, transparent);
774
+ border-radius: 4px;
443
775
  }
444
776
 
445
- .nxg-row {
446
- border-bottom: 1px solid var(--nxg-border);
447
- white-space: nowrap;
448
- transition: background-color 120ms ease;
777
+ /* ---- Column filter popover ---- */
778
+ .tbx-col-filter-wrap {
779
+ position: relative;
780
+ display: inline-flex;
781
+ margin-left: auto;
782
+ flex-shrink: 0;
449
783
  }
450
784
 
451
- .nxg-row:last-child {
452
- border-bottom: 0;
785
+ .tbx-col-filter-btn {
786
+ display: inline-flex;
787
+ align-items: center;
788
+ justify-content: center;
789
+ width: 20px;
790
+ height: 20px;
791
+ padding: 0;
792
+ margin-right: -4px;
793
+ border: 1px solid transparent;
794
+ border-radius: 4px;
795
+ background: transparent;
796
+ color: var(--tbx-muted-fg);
797
+ cursor: pointer;
798
+ opacity: 0.6;
799
+ transition: opacity 120ms ease, background-color 120ms ease, color 120ms ease, border-color 120ms ease;
453
800
  }
454
801
 
455
- .nxg-row:hover {
456
- background: color-mix(in srgb, var(--nxg-muted) 50%, transparent);
802
+ .tbx-th:hover .tbx-col-filter-btn,
803
+ .tbx-col-filter-btn:focus-visible,
804
+ .tbx-col-filter-btn--active {
805
+ opacity: 1;
457
806
  }
458
807
 
459
- .nxg-row--selected {
460
- background: color-mix(in srgb, var(--nxg-primary) 10%, transparent);
808
+ .tbx-col-filter-btn:hover {
809
+ opacity: 1;
810
+ background: var(--tbx-muted);
811
+ color: var(--tbx-fg);
461
812
  }
462
813
 
463
- .nxg-row--selected:hover {
464
- background: color-mix(in srgb, var(--nxg-primary) 15%, transparent);
814
+ .tbx-col-filter-btn--active {
815
+ color: var(--tbx-primary);
816
+ background: color-mix(in srgb, var(--tbx-primary) 15%, transparent);
817
+ border-color: color-mix(in srgb, var(--tbx-primary) 30%, transparent);
465
818
  }
466
819
 
467
- .nxg-row--clickable {
468
- cursor: pointer;
820
+ .tbx-filter-popover {
821
+ position: absolute;
822
+ top: calc(100% + 6px);
823
+ right: 0;
824
+ z-index: 50;
825
+ min-width: 200px;
826
+ max-width: min(280px, calc(100vw - 24px));
827
+ background: var(--tbx-card);
828
+ border: 1px solid var(--tbx-border);
829
+ border-radius: var(--tbx-radius-sm);
830
+ box-shadow: 0 10px 25px -5px rgb(0 0 0 / 0.15), 0 8px 10px -6px rgb(0 0 0 / 0.1);
831
+ padding: 8px;
832
+ text-align: left;
469
833
  }
470
834
 
471
- .nxg-td {
472
- padding: 12px 16px;
835
+ .tbx-filter-popover-input {
836
+ width: 100%;
837
+ padding: 6px 8px;
838
+ font-size: 13px;
839
+ font-family: inherit;
840
+ color: var(--tbx-fg);
841
+ background: var(--tbx-card-2);
842
+ border: 1px solid var(--tbx-border);
843
+ border-radius: 6px;
844
+ outline: none;
845
+ box-sizing: border-box;
473
846
  }
474
847
 
475
- .nxg-td--serial {
476
- width: 48px;
477
- padding: 0 12px;
478
- text-align: center;
479
- font-weight: 700;
480
- font-size: 12px;
481
- color: var(--nxg-muted-fg);
482
- font-family: var(--nxg-font-mono);
483
- user-select: none;
848
+ .tbx-filter-popover-input:focus {
849
+ border-color: var(--tbx-primary);
850
+ box-shadow: var(--tbx-focus-ring);
484
851
  }
485
852
 
486
- .nxg-td--select {
487
- width: 40px;
488
- padding: 12px;
489
- text-align: center;
853
+ .tbx-filter-popover-options {
854
+ max-height: 180px;
855
+ overflow-y: auto;
856
+ margin: 6px 0;
857
+ display: flex;
858
+ flex-direction: column;
859
+ gap: 2px;
490
860
  }
491
861
 
492
- /* Density: padding + font-size on data cells */
493
- .nxg-root[data-density="compact"] .nxg-td {
494
- padding-top: 8px;
495
- padding-bottom: 8px;
862
+ .tbx-filter-option {
863
+ display: flex;
864
+ align-items: center;
865
+ gap: 6px;
866
+ padding: 6px 8px;
496
867
  font-size: 12px;
868
+ color: var(--tbx-fg);
869
+ border-radius: 4px;
870
+ cursor: pointer;
497
871
  }
498
872
 
499
- .nxg-root[data-density="default"] .nxg-td {
500
- padding-top: 12px;
501
- padding-bottom: 12px;
502
- font-size: 14px;
873
+ .tbx-filter-option:hover {
874
+ background: var(--tbx-muted);
503
875
  }
504
876
 
505
- .nxg-root[data-density="comfortable"] .nxg-td {
506
- padding-top: 16px;
507
- padding-bottom: 16px;
508
- font-size: 14px;
877
+ .tbx-filter-option--selected {
878
+ font-weight: 600;
879
+ color: var(--tbx-primary);
880
+ background: color-mix(in srgb, var(--tbx-primary) 10%, transparent);
509
881
  }
510
882
 
511
- /* ---- Checkbox ---- */
883
+ .tbx-filter-popover-actions {
884
+ display: flex;
885
+ justify-content: flex-end;
886
+ gap: 6px;
887
+ margin-top: 8px;
888
+ padding-top: 6px;
889
+ border-top: 1px solid var(--tbx-border);
890
+ }
512
891
 
513
- .nxg-checkbox {
514
- appearance: none;
515
- width: 16px;
516
- height: 16px;
517
- margin: 0;
518
- border: 1px solid var(--nxg-border);
892
+ .tbx-filter-popover-btn {
893
+ display: inline-flex;
894
+ align-items: center;
895
+ gap: 5px;
896
+ padding: 4px 10px;
897
+ font-size: 12px;
898
+ font-weight: 500;
899
+ font-family: inherit;
900
+ color: var(--tbx-fg);
901
+ background: var(--tbx-card);
902
+ border: 1px solid var(--tbx-border);
519
903
  border-radius: 4px;
520
- background: var(--nxg-bg);
521
904
  cursor: pointer;
522
- display: inline-block;
523
- vertical-align: middle;
524
- position: relative;
905
+ transition: all 120ms ease;
525
906
  }
526
907
 
527
- .nxg-checkbox:checked {
528
- background: var(--nxg-primary);
529
- border-color: var(--nxg-primary);
908
+ .tbx-filter-popover-btn .tbx-icon {
909
+ width: 12px;
910
+ height: 12px;
530
911
  }
531
912
 
532
- .nxg-checkbox:checked::after {
533
- content: "";
534
- position: absolute;
535
- left: 4.5px;
536
- top: 1.5px;
537
- width: 4px;
538
- height: 8px;
539
- border: solid var(--nxg-primary-fg);
540
- border-width: 0 2px 2px 0;
541
- transform: rotate(45deg);
913
+ .tbx-filter-popover-btn:hover {
914
+ background: var(--tbx-card-2);
915
+ border-color: #94a3b8;
542
916
  }
543
917
 
544
- .nxg-checkbox:focus-visible {
545
- outline: none;
546
- box-shadow: var(--nxg-focus-ring);
918
+ .tbx-filter-popover-btn--primary {
919
+ color: #ffffff;
920
+ background: var(--tbx-primary-active);
921
+ border-color: var(--tbx-primary-active);
547
922
  }
548
923
 
549
- /* ==========================================================================
550
- Empty / loading / error states
551
- ========================================================================== */
924
+ .tbx-filter-popover-btn--primary:hover {
925
+ opacity: 0.9;
926
+ }
552
927
 
553
- .nxg-state {
554
- padding: 48px 16px;
555
- text-align: center;
556
- color: var(--nxg-muted-fg);
557
- font-size: 14px;
928
+ .tbx-filter-popover.tbx-btn--primary:hover {
929
+ opacity: 0.9;
558
930
  }
559
931
 
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);
565
- padding: 32px;
566
- text-align: center;
932
+ /* ---- Active Filter Pills Bar ---- */
933
+ .tbx-filter-pills-bar {
934
+ display: flex;
935
+ flex-wrap: wrap;
936
+ align-items: center;
937
+ gap: 8px;
938
+ padding: 8px 16px;
939
+ background: var(--tbx-card-2, #f8fafc);
940
+ border-bottom: 1px solid var(--tbx-border-subtle, #f1f5f9);
941
+ font-size: 12px;
567
942
  }
568
943
 
569
- .nxg-state-card .nxg-state-text {
570
- font-size: 14px;
571
- font-weight: 500;
572
- color: var(--nxg-muted-fg);
573
- margin: 0;
944
+ .tbx-dark .tbx-filter-pills-bar {
945
+ background: rgba(30, 41, 59, 0.5);
946
+ border-bottom-color: var(--tbx-border);
574
947
  }
575
948
 
576
- .nxg-state-card .nxg-btn {
577
- margin-top: 12px;
949
+ .tbx-filter-pills-title {
950
+ font-weight: 600;
951
+ color: var(--tbx-muted-fg);
952
+ text-transform: uppercase;
953
+ font-size: 11px;
954
+ letter-spacing: 0.04em;
955
+ margin-right: 4px;
578
956
  }
579
957
 
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);
958
+ .tbx-filter-pill {
959
+ display: inline-flex;
960
+ align-items: center;
961
+ gap: 6px;
962
+ padding: 3px 8px 3px 10px;
963
+ background: var(--tbx-card);
964
+ border: 1px solid var(--tbx-border);
965
+ border-radius: 9999px;
966
+ color: var(--tbx-fg);
967
+ font-size: 12px;
968
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
969
+ transition: border-color 120ms ease, background-color 120ms ease;
970
+ }
971
+
972
+ .tbx-filter-pill:hover {
973
+ border-color: var(--tbx-primary);
974
+ }
975
+
976
+ .tbx-filter-pill-label {
977
+ font-weight: 500;
978
+ color: var(--tbx-muted-fg);
979
+ }
980
+
981
+ .tbx-filter-pill-val {
982
+ font-weight: 600;
983
+ color: var(--tbx-fg);
984
+ }
985
+
986
+ .tbx-filter-pill-remove {
987
+ display: inline-flex;
988
+ align-items: center;
989
+ justify-content: center;
990
+ width: 16px;
991
+ height: 16px;
992
+ padding: 0;
993
+ margin-left: 2px;
994
+ background: transparent;
995
+ border: none;
587
996
  border-radius: 50%;
588
- animation: nxg-spin 700ms linear infinite;
997
+ color: var(--tbx-muted-fg);
998
+ cursor: pointer;
999
+ transition: background-color 120ms ease, color 120ms ease;
589
1000
  }
590
1001
 
591
- @keyframes nxg-spin {
592
- to {
593
- transform: rotate(360deg);
594
- }
1002
+ .tbx-filter-pill-remove:hover {
1003
+ background: rgba(239, 68, 68, 0.15);
1004
+ color: #ef4444;
1005
+ }
1006
+
1007
+ .tbx-filter-pill-clear-all {
1008
+ display: inline-flex;
1009
+ align-items: center;
1010
+ padding: 3px 8px;
1011
+ background: transparent;
1012
+ border: none;
1013
+ color: var(--tbx-primary);
1014
+ font-size: 12px;
1015
+ font-weight: 500;
1016
+ cursor: pointer;
1017
+ text-decoration: underline;
1018
+ text-underline-offset: 2px;
1019
+ transition: opacity 120ms ease;
1020
+ }
1021
+
1022
+ .tbx-filter-pill-clear-all:hover {
1023
+ opacity: 0.8;
1024
+ }
1025
+
1026
+ .tbx-menu-item--reset {
1027
+ color: var(--tbx-muted-fg);
1028
+ font-size: 12px;
1029
+ border-top: 1px solid var(--tbx-border);
1030
+ margin-top: 4px;
1031
+ padding-top: 8px;
1032
+ }
1033
+
1034
+ .tbx-menu-item--reset:hover {
1035
+ color: var(--tbx-fg);
1036
+ }
1037
+
1038
+
1039
+ /* ---- Column resize handles ---- */
1040
+ .tbx-resize-handle {
1041
+ position: absolute;
1042
+ top: 0;
1043
+ right: 0;
1044
+ bottom: 0;
1045
+ width: 8px;
1046
+ cursor: col-resize;
1047
+ user-select: none;
1048
+ touch-action: none;
1049
+ z-index: 10;
1050
+ }
1051
+
1052
+ .tbx-resize-handle::after {
1053
+ content: "";
1054
+ position: absolute;
1055
+ top: 20%;
1056
+ bottom: 20%;
1057
+ right: 3px;
1058
+ width: 2px;
1059
+ background: var(--tbx-border);
1060
+ opacity: 0;
1061
+ transition: opacity 120ms ease, background-color 120ms ease;
1062
+ }
1063
+
1064
+ .tbx-th:hover .tbx-resize-handle::after,
1065
+ .tbx-resize-handle:hover::after,
1066
+ .tbx-resize-handle--active::after {
1067
+ opacity: 1;
1068
+ background: var(--tbx-primary);
1069
+ }
1070
+
1071
+ .tbx-resizing {
1072
+ cursor: col-resize !important;
1073
+ user-select: none !important;
1074
+ }
1075
+
1076
+ .tbx-table tbody {
1077
+ background: var(--tbx-card);
1078
+ }
1079
+
1080
+ .tbx-row {
1081
+ white-space: nowrap;
1082
+ transition: background-color 100ms ease;
1083
+ background: var(--tbx-card);
1084
+ }
1085
+
1086
+ .tbx-row:hover:not(.tbx-row--selected) {
1087
+ background: var(--tbx-card-2);
1088
+ }
1089
+
1090
+ .tbx-row--selected {
1091
+ background-color: var(--tbx-selected-bg) !important;
1092
+ }
1093
+
1094
+ .tbx-row--selected:hover {
1095
+ background-color: color-mix(in srgb, var(--tbx-primary) 20%, var(--tbx-selected-bg)) !important;
1096
+ }
1097
+
1098
+ .tbx-row--clickable {
1099
+ cursor: pointer;
1100
+ }
1101
+
1102
+ .tbx-td {
1103
+ padding: 12px 14px;
1104
+ color: var(--tbx-fg);
1105
+ font-size: 13px;
1106
+ border-bottom: 1px solid var(--tbx-border);
1107
+ vertical-align: middle;
1108
+ }
1109
+
1110
+ .tbx-row:last-child .tbx-td {
1111
+ border-bottom: none;
1112
+ }
1113
+
1114
+ .tbx-td--serial {
1115
+ width: 56px;
1116
+ padding: 12px 10px;
1117
+ text-align: center;
1118
+ font-weight: 600;
1119
+ font-size: 13px;
1120
+ color: var(--tbx-fg);
1121
+ user-select: none;
1122
+ }
1123
+
1124
+ .tbx-td--select {
1125
+ width: 44px;
1126
+ padding: 12px 8px;
1127
+ text-align: center;
1128
+ }
1129
+
1130
+ /* Density: padding + font-size on data cells */
1131
+ .tbx-root[data-density="compact"] .tbx-td {
1132
+ padding-top: 8px;
1133
+ padding-bottom: 8px;
1134
+ font-size: 12px;
1135
+ }
1136
+
1137
+ .tbx-root[data-density="default"] .tbx-td {
1138
+ padding-top: 12px;
1139
+ padding-bottom: 12px;
1140
+ font-size: 13px;
1141
+ }
1142
+
1143
+ .tbx-root[data-density="comfortable"] .tbx-td {
1144
+ padding-top: 16px;
1145
+ padding-bottom: 16px;
1146
+ font-size: 14px;
1147
+ }
1148
+
1149
+ /* ---- Checkbox ---- */
1150
+
1151
+ .tbx-checkbox {
1152
+ appearance: none;
1153
+ width: 18px;
1154
+ height: 18px;
1155
+ margin: 0;
1156
+ border: 1.5px solid #d1d5db;
1157
+ border-radius: 4px;
1158
+ background: #ffffff;
1159
+ cursor: pointer;
1160
+ display: inline-block;
1161
+ vertical-align: middle;
1162
+ position: relative;
1163
+ transition: all 120ms ease;
1164
+ }
1165
+
1166
+ .tbx-dark .tbx-checkbox {
1167
+ border-color: #64748b;
1168
+ background: #1e293b;
1169
+ }
1170
+
1171
+ .tbx-checkbox[type="radio"] {
1172
+ border-radius: 50%;
1173
+ }
1174
+
1175
+ .tbx-checkbox:checked {
1176
+ background: var(--tbx-primary);
1177
+ border-color: var(--tbx-primary);
1178
+ }
1179
+
1180
+ .tbx-checkbox:checked::after {
1181
+ content: "";
1182
+ position: absolute;
1183
+ left: 5px;
1184
+ top: 2px;
1185
+ width: 5px;
1186
+ height: 9px;
1187
+ border: solid var(--tbx-primary-fg);
1188
+ border-width: 0 2px 2px 0;
1189
+ transform: rotate(45deg);
1190
+ }
1191
+
1192
+ .tbx-checkbox[type="radio"]:checked::after {
1193
+ left: 4px;
1194
+ top: 4px;
1195
+ width: 6px;
1196
+ height: 6px;
1197
+ border-radius: 50%;
1198
+ background: var(--tbx-primary-fg);
1199
+ border: none;
1200
+ transform: none;
1201
+ }
1202
+
1203
+ .tbx-checkbox:focus-visible {
1204
+ outline: none;
1205
+ box-shadow: var(--tbx-focus-ring);
595
1206
  }
596
1207
 
597
1208
  /* ==========================================================================
598
- Card list (< 768px)
1209
+ Empty / loading / error states
599
1210
  ========================================================================== */
600
1211
 
601
- .nxg-cards {
602
- display: flex;
603
- flex-direction: column;
604
- gap: 10px;
1212
+ .tbx-state {
1213
+ padding: 48px 16px;
1214
+ text-align: center;
1215
+ color: var(--tbx-muted-fg);
1216
+ font-size: 14px;
605
1217
  }
606
1218
 
607
- @media (min-width: 768px) {
608
- .nxg-cards {
609
- display: none;
1219
+ .tbx-state-card {
1220
+ background: var(--tbx-card);
1221
+ border: 1px solid var(--tbx-border);
1222
+ border-radius: var(--tbx-radius);
1223
+ box-shadow: var(--tbx-shadow);
1224
+ padding: 32px;
1225
+ text-align: center;
1226
+ }
1227
+
1228
+ .tbx-state-card .tbx-state-text {
1229
+ font-size: 14px;
1230
+ font-weight: 500;
1231
+ color: var(--tbx-muted-fg);
1232
+ margin: 0;
1233
+ }
1234
+
1235
+ .tbx-state-card .tbx-btn {
1236
+ margin-top: 12px;
1237
+ }
1238
+
1239
+ /* Crisp linear dotted loader */
1240
+ .tbx-dotted-loader {
1241
+ display: inline-flex;
1242
+ align-items: center;
1243
+ justify-content: center;
1244
+ gap: 6px;
1245
+ margin-bottom: 12px;
1246
+ }
1247
+
1248
+ .tbx-dot {
1249
+ width: 7px;
1250
+ height: 7px;
1251
+ border-radius: 50%;
1252
+ background-color: var(--tbx-primary);
1253
+ display: inline-block;
1254
+ animation: tbx-dot-pulse 1.3s infinite ease-in-out both;
1255
+ }
1256
+
1257
+ .tbx-dot:nth-child(1) {
1258
+ animation-delay: -0.36s;
1259
+ }
1260
+
1261
+ .tbx-dot:nth-child(2) {
1262
+ animation-delay: -0.18s;
1263
+ }
1264
+
1265
+ .tbx-dot:nth-child(3) {
1266
+ animation-delay: 0s;
1267
+ }
1268
+
1269
+ .tbx-dot:nth-child(4) {
1270
+ animation-delay: 0.18s;
1271
+ }
1272
+
1273
+ @keyframes tbx-dot-pulse {
1274
+ 0%, 80%, 100% {
1275
+ transform: scale(0.65);
1276
+ opacity: 0.3;
610
1277
  }
1278
+ 40% {
1279
+ transform: scale(1.2);
1280
+ opacity: 1;
1281
+ }
1282
+ }
1283
+
1284
+ .tbx-loading-text {
1285
+ font-size: 13px;
1286
+ font-weight: 500;
1287
+ color: var(--tbx-muted-fg);
1288
+ letter-spacing: 0.01em;
1289
+ }
1290
+
1291
+ .tbx-spinner {
1292
+ display: none;
1293
+ }
1294
+
1295
+ /* ==========================================================================
1296
+ Card list (< 768px)
1297
+ ========================================================================== */
1298
+
1299
+ .tbx-card {
1300
+ background: var(--tbx-card);
1301
+ border: 1px solid var(--tbx-border);
1302
+ border-radius: 10px;
1303
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
1304
+ padding: 12px;
1305
+ transition: background-color 140ms ease, border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
1306
+ overflow: hidden;
611
1307
  }
612
1308
 
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;
1309
+ .tbx-card:hover {
1310
+ border-color: color-mix(in srgb, var(--tbx-border) 80%, var(--tbx-primary));
620
1311
  }
621
1312
 
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));
1313
+ .tbx-card--selected {
1314
+ border-color: var(--tbx-primary);
1315
+ background: var(--tbx-selected-bg);
625
1316
  }
626
1317
 
627
- .nxg-card--clickable {
1318
+ .tbx-card--clickable {
628
1319
  cursor: pointer;
629
1320
  }
630
1321
 
631
- .nxg-card--clickable:active {
632
- background: color-mix(in srgb, var(--nxg-muted) 50%, var(--nxg-card));
1322
+ .tbx-card--clickable:active {
1323
+ transform: scale(0.995);
1324
+ background: var(--tbx-muted);
633
1325
  }
634
1326
 
635
- .nxg-card-head {
1327
+ .tbx-card-head {
636
1328
  display: flex;
637
1329
  align-items: center;
1330
+ justify-content: space-between;
638
1331
  gap: 8px;
639
- margin-bottom: 10px;
640
- padding-bottom: 8px;
641
- border-bottom: 1px solid color-mix(in srgb, var(--nxg-border) 70%, transparent);
1332
+ margin-bottom: 8px;
1333
+ padding: 2px 4px 8px 4px;
1334
+ border-bottom: 1px solid var(--tbx-border);
642
1335
  }
643
1336
 
644
- .nxg-card-serial {
645
- font-family: var(--nxg-font-mono);
1337
+ .tbx-card-serial {
1338
+ font-family: var(--tbx-font-mono);
646
1339
  font-size: 12px;
647
1340
  font-weight: 700;
648
- color: var(--nxg-muted-fg);
1341
+ color: var(--tbx-primary);
1342
+ background: color-mix(in srgb, var(--tbx-primary) 10%, transparent);
1343
+ padding: 2px 8px;
1344
+ border-radius: 4px;
649
1345
  }
650
1346
 
651
- .nxg-card-select {
1347
+ .tbx-card-select {
652
1348
  margin-inline-start: auto;
1349
+ display: flex;
1350
+ align-items: center;
653
1351
  }
654
1352
 
655
- .nxg-card-rows {
1353
+ .tbx-card-rows {
656
1354
  display: flex;
657
1355
  flex-direction: column;
658
- gap: 8px;
1356
+ gap: 2px;
659
1357
  margin: 0;
1358
+ padding: 0;
660
1359
  }
661
1360
 
662
- .nxg-card-row {
1361
+ .tbx-card-row {
663
1362
  display: flex;
664
- align-items: flex-start;
1363
+ align-items: center;
665
1364
  justify-content: space-between;
666
1365
  gap: 12px;
1366
+ min-width: 0;
1367
+ padding: 7px 10px;
1368
+ border-radius: 6px;
1369
+ transition: background-color 100ms ease;
1370
+ }
1371
+
1372
+ /* Striped styling for mobile cards */
1373
+ .tbx-card-row:nth-child(odd) {
1374
+ background-color: #f8fafc;
1375
+ }
1376
+
1377
+ .tbx-card-row:nth-child(even) {
1378
+ background-color: transparent;
1379
+ }
1380
+
1381
+ .tbx-dark .tbx-card-row:nth-child(odd) {
1382
+ background-color: rgba(255, 255, 255, 0.035);
1383
+ }
1384
+
1385
+ .tbx-dark .tbx-card-row:nth-child(even) {
1386
+ background-color: transparent;
1387
+ }
1388
+
1389
+ .tbx-card-row:hover {
1390
+ background-color: #f1f5f9;
1391
+ }
1392
+
1393
+ .tbx-dark .tbx-card-row:hover {
1394
+ background-color: rgba(255, 255, 255, 0.07);
667
1395
  }
668
1396
 
669
- .nxg-card-row dt {
1397
+ .tbx-card-row dt {
670
1398
  flex-shrink: 0;
671
- font-size: 12px;
672
- font-weight: 500;
673
- color: var(--nxg-muted-fg);
1399
+ font-size: 11px;
1400
+ font-weight: 600;
1401
+ text-transform: uppercase;
1402
+ letter-spacing: 0.04em;
1403
+ color: #64748b;
1404
+ padding-top: 0;
674
1405
  }
675
1406
 
676
- .nxg-card-row dd {
1407
+ .tbx-dark .tbx-card-row dt {
1408
+ color: #94a3b8;
1409
+ }
1410
+
1411
+ .tbx-card-row dd {
677
1412
  min-width: 0;
678
1413
  margin: 0;
679
1414
  overflow-wrap: break-word;
680
1415
  text-align: end;
681
- font-size: 14px;
682
- color: var(--nxg-fg);
1416
+ font-size: 13px;
1417
+ font-weight: 500;
1418
+ color: var(--tbx-fg);
683
1419
  }
684
1420
 
685
1421
  /* ==========================================================================
686
1422
  Footer / pagination
687
1423
  ========================================================================== */
688
1424
 
689
- .nxg-footer {
1425
+ .tbx-footer {
690
1426
  display: flex;
691
1427
  flex-direction: column;
692
1428
  align-items: center;
693
1429
  justify-content: space-between;
694
1430
  gap: 14px;
695
1431
  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;
1432
+ padding: 4px 0 0 0;
1433
+ background: transparent;
1434
+ border: none;
1435
+ box-shadow: none;
1436
+ font-size: 13px;
702
1437
  font-weight: 500;
703
1438
  }
704
1439
 
705
1440
  @media (min-width: 768px) {
706
- .nxg-footer {
1441
+ .tbx-footer {
707
1442
  flex-direction: row;
708
1443
  }
709
1444
  }
710
1445
 
711
- .nxg-range {
1446
+ .tbx-range {
712
1447
  display: flex;
713
1448
  flex-wrap: wrap;
714
1449
  align-items: center;
715
1450
  justify-content: center;
716
- gap: 8px;
717
- color: var(--nxg-muted-fg);
1451
+ gap: 4px;
1452
+ color: #374151;
1453
+ font-size: 13px;
1454
+ font-weight: 500;
718
1455
  text-align: center;
719
1456
  }
720
1457
 
1458
+ .tbx-dark .tbx-range {
1459
+ color: var(--tbx-muted-fg);
1460
+ }
1461
+
721
1462
  @media (min-width: 768px) {
722
- .nxg-range {
1463
+ .tbx-range {
723
1464
  justify-content: flex-start;
724
1465
  text-align: left;
725
1466
  }
726
1467
  }
727
1468
 
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);
1469
+ .tbx-range strong {
1470
+ font-weight: 600;
1471
+ color: var(--tbx-fg);
1472
+ padding: 0 1px;
1473
+ background: transparent;
1474
+ border: none;
1475
+ box-shadow: none;
742
1476
  }
743
1477
 
744
- .nxg-selected-badge {
1478
+ .tbx-selected-badge {
745
1479
  display: inline-flex;
746
1480
  align-items: center;
1481
+ margin-left: 8px;
747
1482
  padding: 2px 8px;
748
1483
  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);
1484
+ font-size: 12px;
1485
+ font-weight: 600;
1486
+ color: var(--tbx-primary);
1487
+ background: color-mix(in srgb, var(--tbx-primary) 12%, transparent);
753
1488
  }
754
1489
 
755
- .nxg-pagination {
1490
+ .tbx-pagination {
756
1491
  display: flex;
757
1492
  flex-wrap: wrap;
758
1493
  align-items: center;
759
1494
  justify-content: center;
760
- gap: 10px;
1495
+ gap: 14px;
761
1496
  max-width: 100%;
762
1497
  }
763
1498
 
764
1499
  @media (min-width: 768px) {
765
- .nxg-pagination {
1500
+ .tbx-pagination {
766
1501
  justify-content: flex-end;
767
1502
  }
768
1503
  }
769
1504
 
770
- .nxg-rows-per-page {
1505
+ .tbx-rows-per-page {
771
1506
  display: flex;
772
1507
  align-items: center;
773
- gap: 6px;
774
- font-size: 12px;
775
- color: var(--nxg-muted-fg);
1508
+ gap: 8px;
1509
+ font-size: 13px;
1510
+ color: #374151;
776
1511
  font-weight: 500;
777
1512
  }
778
1513
 
779
- .nxg-rows-select {
1514
+ .tbx-dark .tbx-rows-per-page {
1515
+ color: var(--tbx-muted-fg);
1516
+ }
1517
+
1518
+ .tbx-rows-select {
780
1519
  height: 32px;
781
- min-width: 64px;
1520
+ min-width: 72px;
782
1521
  padding: 0 8px;
783
- font-size: 12px;
784
- font-weight: 700;
1522
+ font-size: 13px;
1523
+ font-weight: 500;
785
1524
  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);
1525
+ color: var(--tbx-fg);
1526
+ background: var(--tbx-bg);
1527
+ border: 1px solid #d1d5db;
1528
+ border-radius: var(--tbx-radius-xs);
791
1529
  cursor: pointer;
792
1530
  outline: none;
1531
+ transition: border-color 120ms ease;
793
1532
  }
794
1533
 
795
- .nxg-rows-select:focus {
796
- border-color: var(--nxg-primary);
797
- box-shadow: var(--nxg-focus-ring);
1534
+ .tbx-dark .tbx-rows-select {
1535
+ border-color: var(--tbx-border);
798
1536
  }
799
1537
 
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);
1538
+ .tbx-rows-select:focus {
1539
+ border-color: var(--tbx-primary);
1540
+ box-shadow: var(--tbx-focus-ring);
809
1541
  }
810
1542
 
811
- .nxg-pager > * + * {
812
- border-left: 1px solid var(--nxg-border);
1543
+ .tbx-pager {
1544
+ display: inline-flex;
1545
+ align-items: center;
1546
+ gap: 4px;
1547
+ background: transparent;
1548
+ border: none;
1549
+ box-shadow: none;
813
1550
  }
814
1551
 
815
- .nxg-page-btn,
816
- .nxg-page-nav {
817
- padding: 6px 12px;
1552
+ .tbx-page-btn,
1553
+ .tbx-page-nav {
818
1554
  min-width: 32px;
819
- font-size: 12px;
820
- font-weight: 700;
1555
+ height: 32px;
1556
+ padding: 0 6px;
1557
+ font-size: 13px;
1558
+ font-weight: 500;
821
1559
  font-family: inherit;
822
1560
  text-align: center;
823
- color: var(--nxg-fg);
824
- background: transparent;
825
- border: 0;
1561
+ color: #374151;
1562
+ background: #ffffff;
1563
+ border: 1px solid var(--tbx-border);
1564
+ border-radius: var(--tbx-radius-xs);
826
1565
  cursor: pointer;
827
1566
  flex-shrink: 0;
828
- transition: background-color 120ms ease, color 120ms ease;
829
- }
830
-
831
- .nxg-page-nav {
832
1567
  display: inline-flex;
833
1568
  align-items: center;
834
- padding: 6px 10px;
835
- color: var(--nxg-muted-fg);
1569
+ justify-content: center;
1570
+ transition: all 120ms ease;
836
1571
  }
837
1572
 
838
- .nxg-page-btn:hover,
839
- .nxg-page-nav:hover {
840
- background: var(--nxg-muted);
841
- color: var(--nxg-fg);
1573
+ .tbx-dark .tbx-page-btn,
1574
+ .tbx-dark .tbx-page-nav {
1575
+ background: #1e293b;
1576
+ color: var(--tbx-fg);
842
1577
  }
843
1578
 
844
- .nxg-page-btn--current {
845
- background: var(--nxg-primary);
846
- color: var(--nxg-primary-fg);
847
- box-shadow: var(--nxg-shadow);
1579
+ .tbx-page-nav {
1580
+ color: #6b7280;
848
1581
  }
849
1582
 
850
- .nxg-page-btn--current:hover {
851
- background: var(--nxg-primary);
852
- color: var(--nxg-primary-fg);
1583
+ .tbx-page-btn:hover:not(.tbx-page-btn--current),
1584
+ .tbx-page-nav:hover:not(:disabled) {
1585
+ background: #f3f4f6;
1586
+ border-color: #d1d5db;
1587
+ color: #111827;
853
1588
  }
854
1589
 
855
- .nxg-page-nav:disabled {
856
- opacity: 0.3;
1590
+ .tbx-dark .tbx-page-btn:hover:not(.tbx-page-btn--current),
1591
+ .tbx-dark .tbx-page-nav:hover:not(:disabled) {
1592
+ background: #334155;
1593
+ border-color: #475569;
1594
+ color: #ffffff;
1595
+ }
1596
+
1597
+ .tbx-page-btn--current {
1598
+ background: var(--tbx-primary-active) !important;
1599
+ border-color: var(--tbx-primary-active) !important;
1600
+ color: #ffffff !important;
1601
+ font-weight: 600;
1602
+ box-shadow: 0 1px 2px rgba(29, 78, 216, 0.2);
1603
+ }
1604
+
1605
+ .tbx-page-nav:disabled {
1606
+ opacity: 0.35;
857
1607
  cursor: not-allowed;
858
1608
  background: transparent;
859
1609
  }
860
1610
 
861
- .nxg-page-ellipsis {
862
- padding: 6px 10px;
863
- color: var(--nxg-muted-fg);
1611
+ .tbx-page-ellipsis {
1612
+ padding: 0 4px;
1613
+ color: #9ca3af;
1614
+ font-size: 13px;
864
1615
  user-select: none;
865
1616
  flex-shrink: 0;
866
1617
  }
867
1618
 
868
- .nxg-jump {
1619
+ .tbx-jump {
869
1620
  display: flex;
870
1621
  align-items: center;
871
1622
  gap: 6px;
872
1623
  }
873
1624
 
874
- .nxg-jump-label {
875
- font-size: 12px;
876
- font-weight: 700;
877
- color: var(--nxg-fg);
1625
+ .tbx-jump-label {
1626
+ font-size: 13px;
1627
+ font-weight: 500;
1628
+ color: #374151;
878
1629
  cursor: pointer;
879
1630
  white-space: nowrap;
880
1631
  }
881
1632
 
882
- .nxg-jump-input {
1633
+ .tbx-dark .tbx-jump-label {
1634
+ color: var(--tbx-muted-fg);
1635
+ }
1636
+
1637
+ .tbx-jump-input {
883
1638
  width: 48px;
884
1639
  height: 32px;
885
1640
  text-align: center;
886
- font-size: 12px;
887
- font-weight: 700;
1641
+ font-size: 13px;
1642
+ font-weight: 600;
888
1643
  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);
1644
+ color: var(--tbx-primary);
1645
+ background: var(--tbx-bg);
1646
+ border: 1px solid #d1d5db;
1647
+ border-radius: var(--tbx-radius-xs);
894
1648
  outline: none;
895
1649
  -moz-appearance: textfield;
896
1650
  }
897
1651
 
898
- .nxg-jump-input::-webkit-outer-spin-button,
899
- .nxg-jump-input::-webkit-inner-spin-button {
1652
+ .tbx-dark .tbx-jump-input {
1653
+ border-color: var(--tbx-border);
1654
+ }
1655
+
1656
+ .tbx-jump-input::-webkit-outer-spin-button,
1657
+ .tbx-jump-input::-webkit-inner-spin-button {
900
1658
  -webkit-appearance: none;
901
1659
  margin: 0;
902
1660
  }
903
1661
 
904
- .nxg-jump-input:focus {
905
- border-color: var(--nxg-primary);
906
- box-shadow: var(--nxg-focus-ring);
1662
+ .tbx-jump-input:focus {
1663
+ border-color: var(--tbx-primary);
1664
+ box-shadow: var(--tbx-focus-ring);
907
1665
  }
908
1666
 
909
1667
  /* ==========================================================================
910
- Utilities
1668
+ Utilities & Cells (Avatars, Badges, Cell-stack, Actions)
911
1669
  ========================================================================== */
912
1670
 
913
- .nxg-sr-only {
1671
+ .tbx-sr-only {
914
1672
  position: absolute;
915
1673
  width: 1px;
916
1674
  height: 1px;
@@ -922,10 +1680,531 @@
922
1680
  border: 0;
923
1681
  }
924
1682
 
925
- .nxg-align-center {
1683
+ .tbx-align-center {
926
1684
  text-align: center;
927
1685
  }
928
1686
 
929
- .nxg-align-right {
1687
+ .tbx-align-right {
930
1688
  text-align: right;
931
1689
  }
1690
+
1691
+ .cell-user,
1692
+ .tbx-cell-user {
1693
+ display: inline-flex;
1694
+ align-items: center;
1695
+ gap: 10px;
1696
+ text-align: left;
1697
+ }
1698
+
1699
+ .avatar,
1700
+ .tbx-avatar {
1701
+ width: 32px;
1702
+ height: 32px;
1703
+ border-radius: 50%;
1704
+ object-fit: cover;
1705
+ background: #e5e7eb;
1706
+ border: 1px solid var(--tbx-border);
1707
+ flex-shrink: 0;
1708
+ }
1709
+
1710
+ .cell-stack,
1711
+ .tbx-cell-stack {
1712
+ display: inline-flex;
1713
+ flex-direction: column;
1714
+ line-height: 1.3;
1715
+ text-align: left;
1716
+ }
1717
+
1718
+ .cell-stack strong,
1719
+ .tbx-cell-stack strong {
1720
+ font-size: 13.5px;
1721
+ font-weight: 600;
1722
+ color: var(--tbx-fg);
1723
+ }
1724
+
1725
+ .cell-stack small,
1726
+ .tbx-cell-stack small {
1727
+ font-size: 12px;
1728
+ color: var(--tbx-muted-fg);
1729
+ }
1730
+
1731
+ .badge,
1732
+ .tbx-badge {
1733
+ display: inline-flex;
1734
+ align-items: center;
1735
+ justify-content: center;
1736
+ padding: 3px 12px;
1737
+ border-radius: 9999px;
1738
+ font-size: 12px;
1739
+ font-weight: 600;
1740
+ line-height: 1.35;
1741
+ white-space: nowrap;
1742
+ background: #e5e7eb;
1743
+ color: #374151;
1744
+ }
1745
+
1746
+ .badge--active,
1747
+ .tbx-badge--active {
1748
+ background: #bbf7d0;
1749
+ color: #166534;
1750
+ }
1751
+
1752
+ .badge--pending,
1753
+ .tbx-badge--pending {
1754
+ background: #fed7aa;
1755
+ color: #9a3412;
1756
+ }
1757
+
1758
+ .badge--suspended,
1759
+ .tbx-badge--suspended {
1760
+ background: #fecaca;
1761
+ color: #991b1b;
1762
+ }
1763
+
1764
+ .badge--alumni,
1765
+ .tbx-badge--alumni {
1766
+ background: #e9d5ff;
1767
+ color: #6b21a8;
1768
+ }
1769
+
1770
+ .badge--scholarship,
1771
+ .tbx-badge--scholarship {
1772
+ background: #e5e7eb;
1773
+ color: #374151;
1774
+ }
1775
+
1776
+ .tbx-dark .badge--active,
1777
+ .tbx-dark .tbx-badge--active {
1778
+ background: rgba(22, 101, 52, 0.4);
1779
+ color: #4ade80;
1780
+ }
1781
+
1782
+ .tbx-dark .badge--pending,
1783
+ .tbx-dark .tbx-badge--pending {
1784
+ background: rgba(180, 83, 9, 0.4);
1785
+ color: #fbbf24;
1786
+ }
1787
+
1788
+ .tbx-dark .badge--suspended,
1789
+ .tbx-dark .tbx-badge--suspended {
1790
+ background: rgba(185, 28, 28, 0.4);
1791
+ color: #f87171;
1792
+ }
1793
+
1794
+ .tbx-dark .badge--alumni,
1795
+ .tbx-dark .tbx-badge--alumni {
1796
+ background: rgba(126, 34, 206, 0.4);
1797
+ color: #c084fc;
1798
+ }
1799
+
1800
+ .tbx-dark .badge--scholarship,
1801
+ .tbx-dark .tbx-badge--scholarship {
1802
+ background: rgba(100, 116, 139, 0.4);
1803
+ color: #cbd5e1;
1804
+ }
1805
+
1806
+ .score {
1807
+ font-variant-numeric: tabular-nums;
1808
+ font-weight: 600;
1809
+ color: var(--tbx-fg);
1810
+ font-size: 13px;
1811
+ }
1812
+
1813
+ .score--high {
1814
+ font-weight: 600;
1815
+ color: var(--tbx-fg);
1816
+ }
1817
+
1818
+ .row-actions {
1819
+ display: inline-flex;
1820
+ align-items: center;
1821
+ gap: 6px;
1822
+ }
1823
+
1824
+ .row-actions .tbx-btn,
1825
+ .btn-action {
1826
+ width: 28px;
1827
+ height: 28px;
1828
+ padding: 0;
1829
+ display: inline-flex;
1830
+ align-items: center;
1831
+ justify-content: center;
1832
+ border-radius: 6px;
1833
+ border: 1px solid #d1d5db;
1834
+ background: #ffffff;
1835
+ color: #6b7280;
1836
+ cursor: pointer;
1837
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
1838
+ }
1839
+
1840
+ .tbx-dark .row-actions .tbx-btn,
1841
+ .tbx-dark .btn-action {
1842
+ background: #1e293b;
1843
+ border-color: #475569;
1844
+ color: #94a3b8;
1845
+ }
1846
+
1847
+ .row-actions .tbx-btn:hover,
1848
+ .btn-action:hover {
1849
+ background: #f3f4f6;
1850
+ color: #111827;
1851
+ border-color: #9ca3af;
1852
+ }
1853
+
1854
+ .tbx-dark .row-actions .tbx-btn:hover,
1855
+ .tbx-dark .btn-action:hover {
1856
+ background: #334155;
1857
+ color: #ffffff;
1858
+ }
1859
+
1860
+ /* ==========================================================================
1861
+ Enterprise Features
1862
+ ========================================================================== */
1863
+
1864
+ /* ---- Pinned / Sticky Columns ---- */
1865
+ .tbx-th--pinned-left,
1866
+ .tbx-td--pinned-left {
1867
+ position: sticky !important;
1868
+ left: 0;
1869
+ z-index: 2;
1870
+ background-color: var(--tbx-card);
1871
+ }
1872
+
1873
+ .tbx-th--pinned-right,
1874
+ .tbx-td--pinned-right {
1875
+ position: sticky !important;
1876
+ right: 0;
1877
+ z-index: 2;
1878
+ background-color: var(--tbx-card);
1879
+ }
1880
+
1881
+ .tbx-th.tbx-th--pinned-left,
1882
+ .tbx-th.tbx-th--pinned-right {
1883
+ z-index: 4;
1884
+ background-color: var(--tbx-card-2);
1885
+ }
1886
+
1887
+ .tbx-pinned-border-left {
1888
+ box-shadow: inset -1px 0 0 var(--tbx-border), 4px 0 8px -3px rgba(0, 0, 0, 0.08);
1889
+ }
1890
+
1891
+ .tbx-pinned-border-right {
1892
+ box-shadow: inset 1px 0 0 var(--tbx-border), -4px 0 8px -3px rgba(0, 0, 0, 0.08);
1893
+ }
1894
+
1895
+ /* ---- Bulk Actions Floating Bar ---- */
1896
+ .tbx-bulk-bar {
1897
+ position: sticky;
1898
+ bottom: 16px;
1899
+ margin: -48px auto 0 auto;
1900
+ width: fit-content;
1901
+ max-width: calc(100% - 32px);
1902
+ z-index: 30;
1903
+ display: flex;
1904
+ align-items: center;
1905
+ gap: 10px;
1906
+ padding: 6px 14px;
1907
+ background: #0f172a;
1908
+ color: #f8fafc;
1909
+ border-radius: 9999px;
1910
+ box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -4px rgba(0, 0, 0, 0.2);
1911
+ font-size: 13px;
1912
+ font-weight: 500;
1913
+ animation: tbx-slide-up 180ms cubic-bezier(0.16, 1, 0.3, 1);
1914
+ }
1915
+
1916
+ @keyframes tbx-slide-up {
1917
+ from {
1918
+ opacity: 0;
1919
+ transform: translateY(12px) scale(0.96);
1920
+ }
1921
+ to {
1922
+ opacity: 1;
1923
+ transform: translateY(0) scale(1);
1924
+ }
1925
+ }
1926
+
1927
+ .tbx-dark .tbx-bulk-bar {
1928
+ background: #1e293b;
1929
+ border: 1px solid #334155;
1930
+ color: #f1f5f9;
1931
+ }
1932
+
1933
+ .tbx-bulk-badge {
1934
+ display: inline-flex;
1935
+ align-items: center;
1936
+ padding: 2px 8px;
1937
+ border-radius: 9999px;
1938
+ background: var(--tbx-primary);
1939
+ color: white;
1940
+ font-size: 12px;
1941
+ font-weight: 700;
1942
+ }
1943
+
1944
+ .tbx-bulk-actions {
1945
+ display: inline-flex;
1946
+ align-items: center;
1947
+ gap: 6px;
1948
+ }
1949
+
1950
+ .tbx-bulk-btn {
1951
+ display: inline-flex;
1952
+ align-items: center;
1953
+ gap: 5px;
1954
+ height: 28px;
1955
+ padding: 0 10px;
1956
+ border-radius: 9999px;
1957
+ border: 1px solid rgba(255, 255, 255, 0.18);
1958
+ background: rgba(255, 255, 255, 0.1);
1959
+ color: #ffffff;
1960
+ font-size: 12px;
1961
+ font-weight: 500;
1962
+ cursor: pointer;
1963
+ transition: background 120ms ease;
1964
+ }
1965
+
1966
+ .tbx-bulk-btn:hover {
1967
+ background: rgba(255, 255, 255, 0.22);
1968
+ }
1969
+
1970
+ .tbx-bulk-btn--close {
1971
+ padding: 0 6px;
1972
+ border: none;
1973
+ background: transparent;
1974
+ opacity: 0.7;
1975
+ }
1976
+
1977
+ .tbx-bulk-btn--close:hover {
1978
+ opacity: 1;
1979
+ background: rgba(255, 255, 255, 0.15);
1980
+ }
1981
+
1982
+ /* ---- Row Expansion / Detail Rows ---- */
1983
+ .tbx-expand-btn {
1984
+ display: inline-flex;
1985
+ align-items: center;
1986
+ justify-content: center;
1987
+ width: 22px;
1988
+ height: 22px;
1989
+ padding: 0;
1990
+ border: none;
1991
+ border-radius: 4px;
1992
+ background: transparent;
1993
+ color: var(--tbx-muted-fg);
1994
+ cursor: pointer;
1995
+ transition: transform 150ms ease, background-color 120ms ease, color 120ms ease;
1996
+ }
1997
+
1998
+ .tbx-expand-btn:hover {
1999
+ background: var(--tbx-muted);
2000
+ color: var(--tbx-fg);
2001
+ }
2002
+
2003
+ .tbx-expand-btn--open {
2004
+ transform: rotate(90deg);
2005
+ }
2006
+
2007
+ .tbx-expanded-row {
2008
+ background-color: #f8fafc;
2009
+ }
2010
+
2011
+ .tbx-dark .tbx-expanded-row {
2012
+ background-color: rgba(255, 255, 255, 0.02);
2013
+ }
2014
+
2015
+ .tbx-expanded-cell {
2016
+ padding: 16px 20px !important;
2017
+ border-bottom: 1px solid var(--tbx-border);
2018
+ }
2019
+
2020
+ .tbx-detail-panel {
2021
+ animation: tbx-fade-in 140ms ease;
2022
+ }
2023
+
2024
+ /* ---- Summary / Aggregation Footer Row ---- */
2025
+ .tbx-table tfoot {
2026
+ border-top: 2px solid var(--tbx-border);
2027
+ }
2028
+
2029
+ .tbx-summary-row {
2030
+ background: var(--tbx-card-2);
2031
+ }
2032
+
2033
+ .tbx-summary-cell {
2034
+ padding: 10px 14px;
2035
+ font-size: 13px;
2036
+ font-weight: 600;
2037
+ color: var(--tbx-fg);
2038
+ border-top: 2px solid var(--tbx-border);
2039
+ border-bottom: 1px solid var(--tbx-border);
2040
+ }
2041
+
2042
+ .tbx-summary-label {
2043
+ font-size: 11px;
2044
+ text-transform: uppercase;
2045
+ letter-spacing: 0.04em;
2046
+ color: var(--tbx-muted-fg);
2047
+ margin-right: 4px;
2048
+ }
2049
+
2050
+ /* ---- Range Filters ---- */
2051
+ .tbx-range-inputs {
2052
+ display: flex;
2053
+ align-items: center;
2054
+ gap: 6px;
2055
+ margin-bottom: 8px;
2056
+ }
2057
+
2058
+ .tbx-range-input {
2059
+ flex: 1;
2060
+ min-width: 0;
2061
+ height: 30px;
2062
+ padding: 0 6px;
2063
+ font-size: 12px;
2064
+ border: 1px solid var(--tbx-border);
2065
+ border-radius: 4px;
2066
+ background: var(--tbx-card);
2067
+ color: var(--tbx-fg);
2068
+ }
2069
+
2070
+ .tbx-range-input:focus {
2071
+ outline: none;
2072
+ border-color: var(--tbx-primary);
2073
+ }
2074
+
2075
+ .tbx-range-sep {
2076
+ font-size: 12px;
2077
+ color: var(--tbx-muted-fg);
2078
+ flex-shrink: 0;
2079
+ }
2080
+
2081
+ /* ---- Column Drag-and-Drop Reordering ---- */
2082
+ .tbx-th--draggable {
2083
+ cursor: grab;
2084
+ }
2085
+
2086
+ .tbx-th--dragging {
2087
+ opacity: 0.4;
2088
+ cursor: grabbing;
2089
+ }
2090
+
2091
+ .tbx-th--drag-over-left {
2092
+ box-shadow: inset 3px 0 0 var(--tbx-primary) !important;
2093
+ }
2094
+
2095
+ .tbx-th--drag-over-right {
2096
+ box-shadow: inset -3px 0 0 var(--tbx-primary) !important;
2097
+ }
2098
+
2099
+ /* ---- Inline Cell Editing ---- */
2100
+ .tbx-cell--editable {
2101
+ cursor: pointer;
2102
+ position: relative;
2103
+ }
2104
+
2105
+ .tbx-cell--editable:hover::after {
2106
+ content: "";
2107
+ position: absolute;
2108
+ inset: 2px;
2109
+ border: 1px dashed color-mix(in srgb, var(--tbx-primary) 50%, transparent);
2110
+ border-radius: 4px;
2111
+ pointer-events: none;
2112
+ }
2113
+
2114
+ .tbx-cell-edit-wrap {
2115
+ display: flex;
2116
+ align-items: center;
2117
+ gap: 4px;
2118
+ width: 100%;
2119
+ }
2120
+
2121
+ .tbx-cell-edit-input {
2122
+ width: 100%;
2123
+ height: 28px;
2124
+ padding: 0 6px;
2125
+ font-size: 13px;
2126
+ border: 1px solid var(--tbx-primary);
2127
+ border-radius: 4px;
2128
+ background: var(--tbx-card);
2129
+ color: var(--tbx-fg);
2130
+ }
2131
+
2132
+ .tbx-cell-edit-input:focus {
2133
+ outline: none;
2134
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--tbx-primary) 20%, transparent);
2135
+ }
2136
+
2137
+ .tbx-cell-edit-actions {
2138
+ display: inline-flex;
2139
+ align-items: center;
2140
+ gap: 2px;
2141
+ flex-shrink: 0;
2142
+ }
2143
+
2144
+ .tbx-cell-edit-btn {
2145
+ display: inline-flex;
2146
+ align-items: center;
2147
+ justify-content: center;
2148
+ width: 24px;
2149
+ height: 24px;
2150
+ padding: 0;
2151
+ border: none;
2152
+ border-radius: 4px;
2153
+ background: transparent;
2154
+ cursor: pointer;
2155
+ }
2156
+
2157
+ .tbx-cell-edit-btn--save {
2158
+ color: #10b981;
2159
+ }
2160
+
2161
+ .tbx-cell-edit-btn--save:hover {
2162
+ background: rgba(16, 185, 129, 0.1);
2163
+ }
2164
+
2165
+ .tbx-cell-edit-btn--cancel {
2166
+ color: #ef4444;
2167
+ }
2168
+
2169
+ .tbx-cell-edit-btn--cancel:hover {
2170
+ background: rgba(239, 68, 68, 0.1);
2171
+ }
2172
+
2173
+ /* ---- Print Optimization ---- */
2174
+ @media print {
2175
+ .tbx-toolbar,
2176
+ .tbx-bulk-bar,
2177
+ .tbx-footer,
2178
+ .tbx-col-filter-wrap,
2179
+ .tbx-cards,
2180
+ .row-actions {
2181
+ display: none !important;
2182
+ }
2183
+
2184
+ .tbx-table-wrap {
2185
+ border: none !important;
2186
+ overflow: visible !important;
2187
+ }
2188
+
2189
+ .tbx-table {
2190
+ width: 100% !important;
2191
+ border-collapse: collapse !important;
2192
+ }
2193
+
2194
+ .tbx-th,
2195
+ .tbx-td,
2196
+ .tbx-summary-cell {
2197
+ border: 1px solid #94a3b8 !important;
2198
+ color: #000000 !important;
2199
+ background: transparent !important;
2200
+ page-break-inside: avoid;
2201
+ }
2202
+ }
2203
+
2204
+
2205
+ .row-actions .tbx-btn .tbx-icon,
2206
+ .btn-action .tbx-icon {
2207
+ width: 14px;
2208
+ height: 14px;
2209
+ color: currentColor;
2210
+ }