main
css 466 lines 9.88 KB
Raw
1 /* ==========================================================================
2 Tables CSS - Shared styles for data tables and list views
3 Used by: Memory Dashboard, Task Scheduler, and similar components
4 ========================================================================== */
5
6 /* ==========================================================================
7 FILTER HEADER
8 Flex-based filter layout for search/filter controls
9 ========================================================================== */
10 .filters-header {
11 display: flex;
12 flex-wrap: wrap;
13 gap: 0.75rem;
14 align-items: center;
15 padding: 1rem;
16 background: var(--color-panel);
17 border: 1px solid var(--color-border);
18 border-radius: 8px;
19 margin-bottom: 0;
20 }
21
22 .filter-group-inline {
23 display: flex;
24 align-items: center;
25 gap: 0.5rem;
26 }
27
28 .filter-group-inline label {
29 font-size: 0.85rem;
30 font-weight: 600;
31 color: var(--color-text);
32 opacity: 0.8;
33 white-space: nowrap;
34 }
35
36 .filter-group-inline select,
37 .filter-group-inline input {
38 border: 1px solid var(--color-border);
39 min-width: 0;
40 }
41
42 .filter-group-inline select:focus,
43 .filter-group-inline input:focus {
44 outline: none;
45 border-color: var(--color-primary);
46 background: var(--color-input-focus);
47 }
48
49 /* Filter threshold (range slider with label) */
50 .filter-threshold {
51 display: flex;
52 flex-direction: column;
53 gap: 0.25rem;
54 }
55
56 .filter-threshold label {
57 font-size: 0.85rem;
58 opacity: 0.8;
59 }
60
61 /* ==========================================================================
62 STATUS BAR
63 Status info and pagination controls
64 ========================================================================== */
65 .data-status-bar {
66 display: flex;
67 justify-content: space-between;
68 align-items: center;
69 padding: 0.75rem 1rem;
70 background: var(--color-panel);
71 border: 1px solid var(--color-border);
72 border-top: none;
73 font-size: 0.9rem;
74 }
75
76 .data-status-bar-top {
77 border-top: 1px solid var(--color-border);
78 border-bottom: none;
79 border-radius: 8px 8px 0 0;
80 }
81
82 .data-status-bar-bottom {
83 border-top: 1px solid var(--color-border);
84 border-radius: 0 0 8px 8px;
85 }
86
87 .data-status-bar-standalone {
88 border: 1px solid var(--color-border);
89 border-radius: 8px;
90 }
91
92 .status-info {
93 display: flex;
94 align-items: center;
95 gap: 0.5rem;
96 flex-wrap: wrap;
97 }
98
99 .status-item {
100 display: flex;
101 align-items: center;
102 gap: 0.25rem;
103 }
104
105 .status-item strong {
106 color: var(--color-primary);
107 font-weight: 600;
108 }
109
110 .status-item .material-symbols-outlined {
111 font-size: 18px;
112 opacity: 0.6;
113 }
114
115 .status-separator {
116 color: var(--color-border);
117 margin: 0 0.25rem;
118 }
119
120 /* ==========================================================================
121 PAGINATION
122 Page navigation controls
123 ========================================================================== */
124 .status-pagination {
125 display: flex;
126 align-items: center;
127 gap: 0.5rem;
128 }
129
130 .page-input-group {
131 display: flex;
132 align-items: center;
133 gap: 0.5rem;
134 }
135
136 .page-input-group label {
137 opacity: 0.8;
138 }
139
140 .page-total {
141 color: var(--color-text);
142 opacity: 0.8;
143 font-size: 0.85rem;
144 white-space: nowrap;
145 }
146
147 .page-total strong {
148 color: var(--color-primary);
149 font-weight: 600;
150 }
151
152 .page-input {
153 width: 60px;
154 padding: 0.25rem 0.5rem;
155 text-align: center;
156 border: 1px solid var(--color-border);
157 background: var(--color-input);
158 color: var(--color-text);
159 border-radius: 4px;
160 font-size: 0.85rem;
161 height: 28px;
162 }
163
164 .page-input:focus {
165 outline: none;
166 border-color: var(--color-primary);
167 background: var(--color-input-focus);
168 }
169
170 /* Remove spinner arrows from number input */
171 .page-input::-webkit-inner-spin-button,
172 .page-input::-webkit-outer-spin-button {
173 -webkit-appearance: none;
174 margin: 0;
175 }
176
177 .page-input[type=number] {
178 -moz-appearance: textfield;
179 appearance: textfield;
180 }
181
182 /* ==========================================================================
183 TABLE CONTAINER & BASE STYLES
184 Wrapper and base table styling
185 ========================================================================== */
186 .data-table-container {
187 border: 1px solid var(--color-border);
188 border-top: none;
189 border-radius: 0 0 8px 8px;
190 overflow: hidden;
191 }
192
193 .data-table-container-standalone {
194 border-top: 1px solid var(--color-border);
195 border-radius: 8px;
196 }
197
198 .table-wrapper {
199 overflow-x: auto;
200 }
201
202 .data-table {
203 width: 100%;
204 border-collapse: collapse;
205 table-layout: auto;
206 font-size: 0.9rem;
207 }
208
209 .data-table th,
210 .data-table td {
211 padding: 0.75rem;
212 text-align: left;
213 border-bottom: 1px solid var(--color-border);
214 vertical-align: middle;
215 overflow: hidden;
216 text-overflow: ellipsis;
217 white-space: nowrap;
218 }
219
220 .data-table th {
221 background: var(--color-panel);
222 font-weight: 600;
223 color: var(--color-text);
224 }
225
226 .data-table th.sortable {
227 cursor: pointer;
228 user-select: none;
229 }
230
231 .data-table th.sortable:hover {
232 background: var(--color-bg-tertiary);
233 }
234
235 .data-table tbody tr {
236 cursor: pointer;
237 transition: background-color 0.2s ease;
238 }
239
240 .data-table tbody tr:hover {
241 background-color: rgba(255, 255, 255, 0.03);
242 }
243
244 .light-mode .data-table tbody tr:hover {
245 background-color: rgba(0, 0, 0, 0.02);
246 }
247
248 .data-table tbody tr:last-child td {
249 border-bottom: none;
250 }
251
252 /* Sticky header for scrollable tables */
253 .data-table th.sticky {
254 position: sticky;
255 top: 0;
256 z-index: 10;
257 border-bottom: 2px solid var(--color-border);
258 }
259
260 /* ==========================================================================
261 SORT INDICATOR
262 Arrow indicator for sortable columns
263 ========================================================================== */
264 .sort-indicator {
265 display: inline-block;
266 margin-left: 4px;
267 transition: transform 0.2s ease;
268 }
269
270 .sort-indicator.desc {
271 transform: rotate(180deg);
272 }
273
274 /* ==========================================================================
275 EMPTY & LOADING STATES
276 Empty results and loading indicators
277 ========================================================================== */
278 .data-empty-state {
279 text-align: center;
280 padding: 3rem 1rem;
281 color: var(--color-text);
282 opacity: 0.8;
283 background: var(--color-panel);
284 border: 1px solid var(--color-border);
285 border-top: none;
286 border-radius: 0 0 8px 8px;
287 }
288
289 .data-empty-state-standalone {
290 border-top: 1px solid var(--color-border);
291 border-radius: 8px;
292 }
293
294 .data-empty-state .btn {
295 display: inline-flex;
296 align-items: center;
297 gap: 0.5rem;
298 margin-top: 1rem;
299 }
300
301 .loading-state {
302 text-align: center;
303 padding: 2rem;
304 color: var(--color-text);
305 opacity: 0.8;
306 margin: 1rem 0;
307 display: grid;
308 align-items: center;
309 }
310
311 .error-state {
312 text-align: center;
313 padding: 2rem;
314 color: var(--color-accent);
315 border: 1px solid var(--color-accent);
316 background: var(--color-panel);
317 border-radius: 8px;
318 margin: 1rem 0;
319 }
320
321 .init-message {
322 text-align: center;
323 padding: 2rem;
324 color: var(--color-primary);
325 border: 1px solid var(--color-primary);
326 background: var(--color-panel);
327 border-radius: 8px;
328 margin: 1rem 0;
329 }
330
331 .loading-spinner {
332 width: 24px;
333 height: 24px;
334 min-width: 24px;
335 min-height: 24px;
336 max-width: 24px;
337 max-height: 24px;
338 border: 3px solid var(--color-border);
339 border-top-color: var(--color-primary);
340 border-radius: 50%;
341 animation: spin 1s linear infinite;
342 margin: 0 auto 0.5rem;
343 flex-shrink: 0;
344 flex-grow: 0;
345 display: inline-block;
346 position: relative;
347 box-sizing: border-box;
348 }
349
350 @keyframes spin {
351 to {
352 transform: rotate(360deg);
353 }
354 }
355
356 /* ==========================================================================
357 MASS ACTION TOOLBAR
358 Bulk action controls for selected items
359 ========================================================================== */
360 .mass-action-toolbar {
361 display: flex;
362 justify-content: space-between;
363 align-items: center;
364 padding: 1rem;
365 background: var(--color-panel);
366 margin: 0;
367 animation: slideDown 0.3s ease;
368 }
369
370 .selection-info {
371 font-weight: 600;
372 }
373
374 .mass-actions {
375 display: flex;
376 gap: 0.5rem;
377 }
378
379 .btn-mass {
380 align-items: center;
381 border: 1px solid var(--color-border);
382 gap: 0.25rem;
383 display: flex;
384 background: var(--color-background);
385 color: var(--color-text);
386 }
387
388 .btn-mass .material-symbols-outlined {
389 font-size: 18px;
390 }
391
392 .btn-mass:hover {
393 border-color: var(--color-primary);
394 color: var(--color-primary);
395 background: var(--color-panel);
396 }
397
398 .btn-mass.delete:hover {
399 border-color: var(--color-accent);
400 color: var(--color-accent);
401 }
402
403 @keyframes slideDown {
404 from {
405 opacity: 0;
406 transform: translateY(-10px);
407 }
408 to {
409 opacity: 1;
410 transform: translateY(0);
411 }
412 }
413
414 /* ==========================================================================
415 RESPONSIVE STYLES
416 Mobile breakpoints for tables and status bars
417 ========================================================================== */
418 @media (max-width: 870px) {
419 .filters-header {
420 flex-direction: column;
421 align-items: stretch;
422 }
423
424 .filter-group-inline {
425 width: 100%;
426 }
427
428 .filter-group-inline select,
429 .filter-group-inline input {
430 flex: 1;
431 }
432
433 .data-status-bar {
434 flex-direction: column;
435 gap: 0.75rem;
436 }
437
438 .status-info {
439 width: 100%;
440 justify-content: center;
441 }
442
443 .status-pagination {
444 width: 100%;
445 justify-content: center;
446 padding-top: 0.5rem;
447 border-top: 1px solid var(--color-border);
448 }
449
450 .data-table th,
451 .data-table td {
452 padding: 0.5rem 0.25rem;
453 font-size: 0.85rem;
454 }
455
456 .mass-action-toolbar {
457 flex-direction: column;
458 gap: 0.75rem;
459 }
460
461 .mass-actions {
462 flex-wrap: wrap;
463 justify-content: center;
464 }
465 }
466