fastapi-admin-kit 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. fastapi_admin_kit/__init__.py +73 -0
  2. fastapi_admin_kit/actions/__init__.py +63 -0
  3. fastapi_admin_kit/actions/base.py +68 -0
  4. fastapi_admin_kit/actions/registry.py +43 -0
  5. fastapi_admin_kit/admin/__init__.py +17 -0
  6. fastapi_admin_kit/admin/admin_config.py +95 -0
  7. fastapi_admin_kit/admin/admin_database.py +138 -0
  8. fastapi_admin_kit/admin/admin_router.py +74 -0
  9. fastapi_admin_kit/admin/admin_template.py +203 -0
  10. fastapi_admin_kit/admin/builtin_models.py +284 -0
  11. fastapi_admin_kit/admin/core.py +1036 -0
  12. fastapi_admin_kit/admin/decorators.py +70 -0
  13. fastapi_admin_kit/admin/state.py +76 -0
  14. fastapi_admin_kit/admin.py +728 -0
  15. fastapi_admin_kit/api/__init__.py +44 -0
  16. fastapi_admin_kit/api/auth.py +342 -0
  17. fastapi_admin_kit/api/crud.py +128 -0
  18. fastapi_admin_kit/api/deps.py +79 -0
  19. fastapi_admin_kit/api/roles.py +128 -0
  20. fastapi_admin_kit/api/schema_generator.py +171 -0
  21. fastapi_admin_kit/api/schemas.py +81 -0
  22. fastapi_admin_kit/api/search.py +132 -0
  23. fastapi_admin_kit/audit/__init__.py +36 -0
  24. fastapi_admin_kit/audit/context.py +62 -0
  25. fastapi_admin_kit/audit/diff.py +77 -0
  26. fastapi_admin_kit/audit/event_bus.py +96 -0
  27. fastapi_admin_kit/audit/events.py +48 -0
  28. fastapi_admin_kit/audit/listener.py +159 -0
  29. fastapi_admin_kit/audit/logger.py +28 -0
  30. fastapi_admin_kit/audit/middleware.py +39 -0
  31. fastapi_admin_kit/audit/models.py +53 -0
  32. fastapi_admin_kit/audit/sqlalchemy_logger.py +58 -0
  33. fastapi_admin_kit/auth/__init__.py +34 -0
  34. fastapi_admin_kit/auth/backend.py +95 -0
  35. fastapi_admin_kit/auth/csrf.py +240 -0
  36. fastapi_admin_kit/auth/dependencies.py +150 -0
  37. fastapi_admin_kit/auth/identity.py +181 -0
  38. fastapi_admin_kit/auth/models.py +246 -0
  39. fastapi_admin_kit/auth/password.py +35 -0
  40. fastapi_admin_kit/auth/permissions.py +205 -0
  41. fastapi_admin_kit/auth/protocol.py +22 -0
  42. fastapi_admin_kit/auth/ratelimit.py +88 -0
  43. fastapi_admin_kit/auth/router.py +10 -0
  44. fastapi_admin_kit/auth/session.py +79 -0
  45. fastapi_admin_kit/auth/totp.py +83 -0
  46. fastapi_admin_kit/auth/views.py +165 -0
  47. fastapi_admin_kit/cli.py +229 -0
  48. fastapi_admin_kit/config/__init__.py +19 -0
  49. fastapi_admin_kit/config/audit.py +18 -0
  50. fastapi_admin_kit/config/auth.py +54 -0
  51. fastapi_admin_kit/config/behavior.py +27 -0
  52. fastapi_admin_kit/config/nav.py +32 -0
  53. fastapi_admin_kit/config/storage.py +22 -0
  54. fastapi_admin_kit/config/theme.py +215 -0
  55. fastapi_admin_kit/config/ui.py +147 -0
  56. fastapi_admin_kit/dashboard/__init__.py +64 -0
  57. fastapi_admin_kit/db.py +133 -0
  58. fastapi_admin_kit/exceptions.py +5 -0
  59. fastapi_admin_kit/field_types.py +81 -0
  60. fastapi_admin_kit/filters/__init__.py +21 -0
  61. fastapi_admin_kit/filters/base.py +170 -0
  62. fastapi_admin_kit/filters/registry.py +68 -0
  63. fastapi_admin_kit/flash.py +45 -0
  64. fastapi_admin_kit/form/__init__.py +1 -0
  65. fastapi_admin_kit/form/pipeline.py +106 -0
  66. fastapi_admin_kit/inspection/__init__.py +117 -0
  67. fastapi_admin_kit/inspection/registry.py +253 -0
  68. fastapi_admin_kit/inspection.py +115 -0
  69. fastapi_admin_kit/modeladmin.py +375 -0
  70. fastapi_admin_kit/models/__init__.py +7 -0
  71. fastapi_admin_kit/models/base.py +7 -0
  72. fastapi_admin_kit/nav.py +208 -0
  73. fastapi_admin_kit/pagination/__init__.py +14 -0
  74. fastapi_admin_kit/pagination/base.py +40 -0
  75. fastapi_admin_kit/pagination/cursor.py +97 -0
  76. fastapi_admin_kit/pagination/dynamic.py +48 -0
  77. fastapi_admin_kit/pagination/offset.py +42 -0
  78. fastapi_admin_kit/plugins/__init__.py +1 -0
  79. fastapi_admin_kit/py.typed +0 -0
  80. fastapi_admin_kit/registry/__init__.py +5 -0
  81. fastapi_admin_kit/registry/core.py +287 -0
  82. fastapi_admin_kit/registry/validation.py +107 -0
  83. fastapi_admin_kit/registry.py +15 -0
  84. fastapi_admin_kit/router.py +335 -0
  85. fastapi_admin_kit/static/css/admin.css +4736 -0
  86. fastapi_admin_kit/static/css/presets.css +317 -0
  87. fastapi_admin_kit/static/css/tokens.css +217 -0
  88. fastapi_admin_kit/static/css/variables.css +74 -0
  89. fastapi_admin_kit/static/icons/heroicons.svg +160 -0
  90. fastapi_admin_kit/static/js/admin.js +692 -0
  91. fastapi_admin_kit/static/js/htmx-config.js +42 -0
  92. fastapi_admin_kit/storage/__init__.py +6 -0
  93. fastapi_admin_kit/storage/base.py +48 -0
  94. fastapi_admin_kit/storage/local.py +73 -0
  95. fastapi_admin_kit/templates/base.html +142 -0
  96. fastapi_admin_kit/templates/macros/form_fields.html +660 -0
  97. fastapi_admin_kit/templates/macros/icons.html +50 -0
  98. fastapi_admin_kit/templates/macros/table.html +108 -0
  99. fastapi_admin_kit/templates/macros/widgets.html +159 -0
  100. fastapi_admin_kit/templates/pages/2fa/setup.html +122 -0
  101. fastapi_admin_kit/templates/pages/2fa/verify.html +55 -0
  102. fastapi_admin_kit/templates/pages/audit_detail.html +122 -0
  103. fastapi_admin_kit/templates/pages/audit_log.html +102 -0
  104. fastapi_admin_kit/templates/pages/dashboard.html +295 -0
  105. fastapi_admin_kit/templates/pages/detail.html +183 -0
  106. fastapi_admin_kit/templates/pages/form.html +119 -0
  107. fastapi_admin_kit/templates/pages/list.html +277 -0
  108. fastapi_admin_kit/templates/pages/login.html +85 -0
  109. fastapi_admin_kit/templates/pages/profile/password.html +78 -0
  110. fastapi_admin_kit/templates/pages/profile/profile.html +73 -0
  111. fastapi_admin_kit/templates/pages/role_form.html +75 -0
  112. fastapi_admin_kit/templates/pages/roles/form.html +117 -0
  113. fastapi_admin_kit/templates/pages/roles/list.html +69 -0
  114. fastapi_admin_kit/templates/pages/roles.html +77 -0
  115. fastapi_admin_kit/templates/pages/settings/theme.html +255 -0
  116. fastapi_admin_kit/templates/pages/users/form.html +229 -0
  117. fastapi_admin_kit/templates/pages/users/list.html +83 -0
  118. fastapi_admin_kit/templates/partials/command_palette.html +52 -0
  119. fastapi_admin_kit/templates/partials/field_wrapper.html +2 -0
  120. fastapi_admin_kit/templates/partials/flash_messages.html +39 -0
  121. fastapi_admin_kit/templates/partials/head.html +21 -0
  122. fastapi_admin_kit/templates/partials/head_minimal.html +18 -0
  123. fastapi_admin_kit/templates/partials/list_table.html +178 -0
  124. fastapi_admin_kit/templates/partials/mobile_backdrop.html +2 -0
  125. fastapi_admin_kit/templates/partials/pagination.html +82 -0
  126. fastapi_admin_kit/templates/partials/permission_widget.html +86 -0
  127. fastapi_admin_kit/templates/partials/scripts.html +13 -0
  128. fastapi_admin_kit/templates/partials/sidebar.html +94 -0
  129. fastapi_admin_kit/templates/partials/topbar.html +95 -0
  130. fastapi_admin_kit/types.py +145 -0
  131. fastapi_admin_kit/validation.py +43 -0
  132. fastapi_admin_kit/views/__init__.py +78 -0
  133. fastapi_admin_kit/views/audit.py +134 -0
  134. fastapi_admin_kit/views/bulk.py +28 -0
  135. fastapi_admin_kit/views/class_views.py +1040 -0
  136. fastapi_admin_kit/views/context.py +588 -0
  137. fastapi_admin_kit/views/dashboard.py +162 -0
  138. fastapi_admin_kit/views/delete.py +31 -0
  139. fastapi_admin_kit/views/extra.py +65 -0
  140. fastapi_admin_kit/views/factory.py +667 -0
  141. fastapi_admin_kit/views/form.py +159 -0
  142. fastapi_admin_kit/views/list.py +28 -0
  143. fastapi_admin_kit/views/profile.py +219 -0
  144. fastapi_admin_kit/views/protocols.py +54 -0
  145. fastapi_admin_kit/views/renderers.py +634 -0
  146. fastapi_admin_kit/views/roles.py +230 -0
  147. fastapi_admin_kit/views/search.py +31 -0
  148. fastapi_admin_kit/views/settings.py +31 -0
  149. fastapi_admin_kit/views/sidebar.py +101 -0
  150. fastapi_admin_kit/views/totp.py +249 -0
  151. fastapi_admin_kit/views/users.py +347 -0
  152. fastapi_admin_kit/views.py +117 -0
  153. fastapi_admin_kit/widgets/__init__.py +44 -0
  154. fastapi_admin_kit/widgets/base.py +44 -0
  155. fastapi_admin_kit/widgets/inputs.py +363 -0
  156. fastapi_admin_kit/widgets/registry.py +110 -0
  157. fastapi_admin_kit/widgets/relation.py +70 -0
  158. fastapi_admin_kit/widgets/resolver.py +102 -0
  159. fastapi_admin_kit-0.1.0.dist-info/METADATA +210 -0
  160. fastapi_admin_kit-0.1.0.dist-info/RECORD +163 -0
  161. fastapi_admin_kit-0.1.0.dist-info/WHEEL +4 -0
  162. fastapi_admin_kit-0.1.0.dist-info/entry_points.txt +3 -0
  163. fastapi_admin_kit-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,4736 @@
1
+ /* ═══════════════════════════════════════════════════════════════════════════
2
+ FastAPI Admin Kit — Component Styles
3
+ Warm Editorial Brutalism — paper texture meets computational precision
4
+ ═══════════════════════════════════════════════════════════════════════════ */
5
+
6
+ /* ── Fonts ───────────────────────────────────────────────────────────────── */
7
+
8
+ .google-sans-flex-regular {
9
+ font-family: "Google Sans Flex", sans-serif;
10
+ font-optical-sizing: auto;
11
+ font-weight: 400;
12
+ font-style: normal;
13
+ font-variation-settings:
14
+ "slnt" 0,
15
+ "wdth" 100,
16
+ "GRAD" 0,
17
+ "ROND" 0;
18
+ }
19
+
20
+ /* ── Material Symbols ─────────────────────────────────────────────────────── */
21
+
22
+ .material-symbols-outlined {
23
+ font-family: 'Material Symbols Outlined';
24
+ font-weight: normal;
25
+ font-style: normal;
26
+ font-size: 24px;
27
+ line-height: 1;
28
+ letter-spacing: normal;
29
+ text-transform: none;
30
+ display: inline-block;
31
+ white-space: nowrap;
32
+ word-wrap: normal;
33
+ direction: ltr;
34
+ -webkit-font-smoothing: antialiased;
35
+ font-feature-settings: 'liga';
36
+ -webkit-font-feature-settings: 'liga';
37
+ vertical-align: middle;
38
+ user-select: none;
39
+ pointer-events: none;
40
+ flex-shrink: 0;
41
+ }
42
+
43
+ /* Replace all svg icon rules with material-symbols-outlined equivalents */
44
+ .nav-link .material-symbols-outlined { font-size: 18px; opacity: 0.6; }
45
+ .nav-link:hover .material-symbols-outlined { opacity: 1; }
46
+ .nav-link.active .material-symbols-outlined { opacity: 1; color: var(--primary-500); }
47
+ .btn .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
48
+ .btn-sm .material-symbols-outlined { width: 14px; height: 14px; font-size: 14px; }
49
+ .filter-chip .material-symbols-outlined { width: 14px; height: 14px; font-size: 14px; }
50
+ .filter-bar-clear .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
51
+ .filter-bar-action .material-symbols-outlined { width: 18px; height: 18px; font-size: 18px; }
52
+ .actions-trigger .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
53
+ .actions-menu-item .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
54
+ .actions-menu-item--danger .material-symbols-outlined { color: var(--color-danger); }
55
+ .status-badge .material-symbols-outlined { width: 14px; height: 14px; font-size: 14px; }
56
+ .topbar-search .material-symbols-outlined { color: var(--text-disabled); flex-shrink: 0; }
57
+ .topbar-logo-icon .material-symbols-outlined { width: 24px; height: 24px; font-size: 24px; }
58
+ .pagination .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
59
+ .flash-message .material-symbols-outlined { width: 20px; height: 20px; font-size: 20px; flex-shrink: 0; }
60
+ .stat-icon .material-symbols-outlined { font-size: 24px; }
61
+ .breadcrumb .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
62
+ .back-link .material-symbols-outlined { width: 20px; height: 20px; font-size: 20px; }
63
+ .page-header-back .material-symbols-outlined { width: 16px; height: 16px; font-size: 16px; }
64
+ .empty-state .material-symbols-outlined { font-size: 48px; color: var(--text-disabled); }
65
+
66
+ /* ── Reset ───────────────────────────────────────────────────────────────── */
67
+
68
+ *, *::before, *::after {
69
+ box-sizing: border-box;
70
+ }
71
+
72
+ body {
73
+ margin: 0;
74
+ font-family: var(--font-body);
75
+ font-size: var(--text-base);
76
+ line-height: 1.6;
77
+ color: var(--text-primary);
78
+ background: var(--surface-base);
79
+ -webkit-font-smoothing: antialiased;
80
+ -moz-osx-font-smoothing: grayscale;
81
+ }
82
+
83
+ /* Subtle grain texture overlay on body */
84
+ body::before {
85
+ content: '';
86
+ position: fixed;
87
+ inset: 0;
88
+ pointer-events: none;
89
+ z-index: 9999;
90
+ opacity: var(--admin-grain-opacity, 0.025);
91
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
92
+ }
93
+
94
+ a { text-decoration: none; color: inherit; }
95
+ ul, ol { list-style: none; margin: 0; padding: 0; }
96
+ img { max-width: 100%; display: block; }
97
+
98
+ /* ── Selection ───────────────────────────────────────────────────────────── */
99
+
100
+ ::selection {
101
+ background: var(--primary-200);
102
+ color: var(--text-primary);
103
+ }
104
+
105
+ [data-theme="dark"] ::selection {
106
+ background: var(--primary-800);
107
+ }
108
+
109
+ /* ── Scrollbar ───────────────────────────────────────────────────────────── */
110
+
111
+ ::-webkit-scrollbar {
112
+ width: 6px;
113
+ height: 6px;
114
+ }
115
+
116
+ ::-webkit-scrollbar-track {
117
+ background: transparent;
118
+ }
119
+
120
+ ::-webkit-scrollbar-thumb {
121
+ background: var(--surface-border);
122
+ border-radius: var(--radius-full);
123
+ }
124
+
125
+ ::-webkit-scrollbar-thumb:hover {
126
+ background: var(--text-disabled);
127
+ }
128
+
129
+ /* ═══════════════════════════════════════════════════════════════════════════
130
+ SHELL LAYOUT
131
+ ═══════════════════════════════════════════════════════════════════════════ */
132
+
133
+ .admin-shell {
134
+ display: flex;
135
+ flex-direction: column;
136
+ height: 100vh;
137
+ overflow: hidden;
138
+ }
139
+
140
+ .admin-topbar {
141
+ height: var(--topbar-height);
142
+ flex-shrink: 0;
143
+ background: var(--surface-raised);
144
+ border-bottom: 1px solid var(--surface-border);
145
+ display: flex;
146
+ align-items: center;
147
+ padding: 0 var(--content-padding);
148
+ z-index: 30;
149
+ position: relative;
150
+ }
151
+
152
+ /* Decorative bottom accent line on topbar */
153
+ .admin-topbar::after {
154
+ content: '';
155
+ position: absolute;
156
+ bottom: -1px;
157
+ left: 0;
158
+ right: 0;
159
+ height: 2px;
160
+ background: linear-gradient(90deg, var(--primary-500), var(--primary-300), var(--primary-500));
161
+ opacity: var(--admin-accent-line-opacity, 0.4);
162
+ }
163
+
164
+ .admin-body {
165
+ display: flex;
166
+ flex: 1;
167
+ overflow: hidden;
168
+ }
169
+
170
+ /* ── Sidebar ─────────────────────────────────────────────────────────────── */
171
+
172
+ .admin-sidebar {
173
+ width: var(--sidebar-width);
174
+ flex-shrink: 0;
175
+ background: var(--surface-raised);
176
+ border-right: 1px solid var(--surface-border);
177
+ display: flex;
178
+ flex-direction: column;
179
+ overflow: hidden;
180
+ transition: width var(--duration-slow) var(--easing-out);
181
+ z-index: 20;
182
+ text-align: left;
183
+ }
184
+
185
+ .admin-sidebar__logo {
186
+ height: var(--topbar-height);
187
+ display: flex;
188
+ align-items: center;
189
+ padding: 0 var(--space-5);
190
+ border-bottom: 1px solid var(--surface-border);
191
+ flex-shrink: 0;
192
+ gap: var(--space-3);
193
+ }
194
+
195
+ .admin-sidebar__logo-text {
196
+ font-family: var(--font-display);
197
+ font-size: var(--text-lg);
198
+ color: var(--text-primary);
199
+ white-space: nowrap;
200
+ overflow: hidden;
201
+ }
202
+
203
+ .admin-sidebar__nav {
204
+ flex: 1;
205
+ overflow-y: auto;
206
+ padding: var(--space-3) var(--space-3);
207
+ }
208
+
209
+ /* Section labels */
210
+ .nav-section-label {
211
+ font-family: var(--font-body);
212
+ font-size: var(--text-2xs);
213
+ font-weight: var(--font-medium);
214
+ text-transform: uppercase;
215
+ letter-spacing: 0.1em;
216
+ color: var(--text-disabled);
217
+ padding: var(--space-4) var(--space-3) var(--space-2);
218
+ }
219
+
220
+ /* Nav items */
221
+ .nav-link {
222
+ display: flex;
223
+ align-items: center;
224
+ gap: var(--space-3);
225
+ padding: var(--space-2) 0;
226
+ font-size: var(--text-sm);
227
+ font-weight: var(--font-medium);
228
+ color: var(--text-primary);
229
+ border-radius: var(--radius-md);
230
+ transition: all var(--duration-fast) var(--easing-out);
231
+ position: relative;
232
+ cursor: pointer;
233
+ border: none;
234
+ background: none;
235
+ width: 100%;
236
+ text-align: left;
237
+ line-height: 1.5;
238
+ }
239
+
240
+ .nav-link svg {
241
+ width: 18px;
242
+ height: 18px;
243
+ flex-shrink: 0;
244
+ opacity: 0.6;
245
+ }
246
+
247
+ .nav-link:hover {
248
+ background: var(--surface-inset);
249
+ color: var(--primary-600);
250
+ }
251
+
252
+ .nav-link:hover svg {
253
+ opacity: 1;
254
+ }
255
+
256
+ .nav-link.active {
257
+ background: var(--primary-50);
258
+ color: var(--primary-600);
259
+ font-weight: var(--font-semibold);
260
+ }
261
+
262
+ .nav-link.active svg {
263
+ opacity: 1;
264
+ color: var(--primary-500);
265
+ }
266
+
267
+ /* Active indicator — left accent bar */
268
+ .nav-link.active::before {
269
+ content: '';
270
+ position: absolute;
271
+ left: 0;
272
+ top: 6px;
273
+ bottom: 6px;
274
+ width: 3px;
275
+ background: var(--primary-500);
276
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
277
+ }
278
+
279
+ .nav-link__icon {
280
+ width: 16px;
281
+ height: 16px;
282
+ flex-shrink: 0;
283
+ opacity: 0.7;
284
+ }
285
+
286
+ .nav-link.active .nav-link__icon {
287
+ opacity: 1;
288
+ }
289
+
290
+ .nav-link__badge {
291
+ margin-left: auto;
292
+ font-family: var(--font-mono);
293
+ font-size: var(--text-2xs);
294
+ padding: 1px 6px;
295
+ background: var(--surface-inset);
296
+ color: var(--text-secondary);
297
+ border-radius: var(--radius-full);
298
+ border: 1px solid var(--surface-border);
299
+ }
300
+
301
+ /* Collapsible nav groups */
302
+ .nav-group-toggle {
303
+ display: flex;
304
+ align-items: center;
305
+ gap: var(--space-3);
306
+ padding: var(--space-2) var(--space-3);
307
+ font-size: var(--text-sm);
308
+ font-weight: var(--font-medium);
309
+ color: var(--text-secondary);
310
+ cursor: pointer;
311
+ background: none;
312
+ border: none;
313
+ width: 100%;
314
+ text-align: left;
315
+ border-radius: var(--radius-md);
316
+ transition: all var(--duration-fast);
317
+ }
318
+
319
+ .nav-group-toggle:hover {
320
+ background: var(--surface-inset);
321
+ color: var(--text-primary);
322
+ }
323
+
324
+ .nav-group-chevron {
325
+ width: 14px;
326
+ height: 14px;
327
+ margin-left: auto;
328
+ transition: transform var(--duration-base) var(--easing-out);
329
+ opacity: 0.5;
330
+ }
331
+
332
+ .nav-group-toggle[aria-expanded="false"] .nav-group-chevron {
333
+ transform: rotate(-90deg);
334
+ }
335
+
336
+ .nav-group-items {
337
+ padding-left: var(--space-5);
338
+ }
339
+
340
+ /* Collapsible nav groups */
341
+ .nav-group-toggle {
342
+ display: flex;
343
+ align-items: center;
344
+ gap: var(--space-3);
345
+ padding: var(--space-2) var(--space-3);
346
+ font-size: var(--text-sm);
347
+ font-weight: var(--font-medium);
348
+ color: var(--text-primary);
349
+ cursor: pointer;
350
+ background: none;
351
+ border: none;
352
+ width: 100%;
353
+ text-align: left;
354
+ border-radius: var(--radius-md);
355
+ transition: all var(--duration-fast);
356
+ }
357
+
358
+ .nav-group-toggle:hover {
359
+ background: var(--surface-inset);
360
+ color: var(--primary-600);
361
+ }
362
+
363
+ .nav-group-chevron {
364
+ width: 14px;
365
+ height: 14px;
366
+ margin-left: auto;
367
+ transition: transform var(--duration-base) var(--easing-out);
368
+ opacity: 0.5;
369
+ }
370
+
371
+ .nav-group-toggle[aria-expanded="false"] .nav-group-chevron {
372
+ transform: rotate(-90deg);
373
+ }
374
+
375
+ .nav-group-items {
376
+ padding-left: var(--space-5);
377
+ overflow: hidden;
378
+ }
379
+
380
+ .nav-link--child {
381
+ padding: var(--space-1) var(--space-3);
382
+ font-size: var(--text-xs);
383
+ font-weight: var(--font-normal);
384
+ color: var(--text-secondary);
385
+ }
386
+
387
+ .nav-link--child:hover {
388
+ color: var(--primary-600);
389
+ background: var(--surface-inset);
390
+ }
391
+
392
+ .nav-link--child.active {
393
+ color: var(--primary-600);
394
+ background: var(--primary-50);
395
+ font-weight: var(--font-medium);
396
+ }
397
+
398
+ /* Sidebar bottom section */
399
+ .admin-sidebar__footer {
400
+ border-top: 1px solid var(--surface-border);
401
+ padding: var(--space-3);
402
+ flex-shrink: 0;
403
+ }
404
+
405
+ /* ── Content Area ────────────────────────────────────────────────────────── */
406
+
407
+ .admin-content {
408
+ flex: 1;
409
+ overflow-y: auto;
410
+ overflow-x: hidden;
411
+ background: var(--surface-base);
412
+ }
413
+
414
+ .admin-content__inner {
415
+ max-width: var(--content-max-width);
416
+ margin: 0 auto;
417
+ padding: var(--space-8) var(--content-padding);
418
+ }
419
+
420
+ /* ── Page Header ─────────────────────────────────────────────────────────── */
421
+
422
+ .page-header {
423
+ display: flex;
424
+ align-items: flex-start;
425
+ justify-content: space-between;
426
+ padding-bottom: var(--space-5);
427
+ border-bottom: 2px solid var(--text-primary);
428
+ margin-bottom: var(--space-6);
429
+ }
430
+
431
+ .page-header__left {
432
+ flex: 1;
433
+ min-width: 0;
434
+ }
435
+
436
+ .page-header__title {
437
+ font-family: var(--font-display);
438
+ font-size: var(--text-2xl);
439
+ font-weight: var(--font-normal);
440
+ color: var(--text-primary);
441
+ margin: 0;
442
+ line-height: 1.2;
443
+ letter-spacing: -0.01em;
444
+ }
445
+
446
+ .page-header__subtitle {
447
+ font-size: var(--text-sm);
448
+ color: var(--text-secondary);
449
+ margin: var(--space-1) 0 0;
450
+ }
451
+
452
+ .page-header__subtitle--mono {
453
+ font-family: var(--font-mono);
454
+ color: var(--mono-accent);
455
+ }
456
+
457
+ .page-header__actions {
458
+ display: flex;
459
+ align-items: center;
460
+ gap: var(--space-2);
461
+ flex-shrink: 0;
462
+ }
463
+
464
+ /* Back link */
465
+ .back-link {
466
+ display: inline-flex;
467
+ align-items: center;
468
+ gap: var(--space-1);
469
+ font-size: var(--text-sm);
470
+ color: var(--text-secondary);
471
+ margin-bottom: var(--space-3);
472
+ transition: color var(--duration-fast);
473
+ }
474
+
475
+ .back-link:hover {
476
+ color: var(--primary-500);
477
+ }
478
+
479
+ .back-link svg {
480
+ width: 14px;
481
+ height: 14px;
482
+ }
483
+
484
+ /* ═══════════════════════════════════════════════════════════════════════════
485
+ BUTTONS
486
+ ═══════════════════════════════════════════════════════════════════════════ */
487
+
488
+ .btn {
489
+ display: inline-flex;
490
+ align-items: center;
491
+ justify-content: center;
492
+ gap: var(--space-2);
493
+ font-family: var(--font-body);
494
+ font-size: var(--text-sm);
495
+ font-weight: var(--font-medium);
496
+ line-height: 1;
497
+ padding: 8px 16px;
498
+ border-radius: var(--radius-md);
499
+ border: 1px solid transparent;
500
+ cursor: pointer;
501
+ transition: all var(--duration-fast) var(--easing-out);
502
+ white-space: nowrap;
503
+ text-decoration: none;
504
+ }
505
+
506
+ .btn:focus-visible {
507
+ outline: none;
508
+ box-shadow: var(--shadow-focus);
509
+ }
510
+
511
+ .btn:disabled {
512
+ opacity: 0.5;
513
+ cursor: not-allowed;
514
+ }
515
+
516
+ .btn svg {
517
+ width: 15px;
518
+ height: 15px;
519
+ flex-shrink: 0;
520
+ }
521
+
522
+ /* Primary — emerald fill */
523
+ .btn-primary {
524
+ background: var(--primary-500);
525
+ color: var(--text-inverse);
526
+ border-color: var(--primary-500);
527
+ }
528
+
529
+ .btn-primary:hover:not(:disabled) {
530
+ background: var(--primary-600);
531
+ border-color: var(--primary-600);
532
+ }
533
+
534
+ .btn-primary:active:not(:disabled) {
535
+ background: var(--primary-700);
536
+ }
537
+
538
+ /* Secondary — outlined */
539
+ .btn-secondary {
540
+ background: var(--surface-raised);
541
+ color: var(--text-primary);
542
+ border-color: var(--surface-border);
543
+ }
544
+
545
+ .btn-secondary:hover:not(:disabled) {
546
+ background: var(--surface-inset);
547
+ border-color: var(--text-disabled);
548
+ }
549
+
550
+ /* Danger — shows outline, fills on hover */
551
+ .btn-danger {
552
+ background: var(--surface-raised);
553
+ color: var(--danger-500);
554
+ border-color: var(--surface-border);
555
+ }
556
+
557
+ .btn-danger:hover:not(:disabled) {
558
+ background: var(--danger-500);
559
+ color: var(--text-inverse);
560
+ border-color: var(--danger-500);
561
+ }
562
+
563
+ /* Ghost — no border, no fill */
564
+ .btn-ghost {
565
+ background: transparent;
566
+ color: var(--text-secondary);
567
+ border-color: transparent;
568
+ }
569
+
570
+ .btn-ghost:hover:not(:disabled) {
571
+ background: var(--surface-inset);
572
+ color: var(--text-primary);
573
+ }
574
+
575
+ /* Sizes */
576
+ .btn-sm {
577
+ padding: 5px 10px;
578
+ font-size: var(--text-xs);
579
+ }
580
+
581
+ .btn-sm svg {
582
+ width: 13px;
583
+ height: 13px;
584
+ }
585
+
586
+ .btn-lg {
587
+ padding: 10px 20px;
588
+ font-size: var(--text-base);
589
+ }
590
+
591
+ /* Loading state */
592
+ .btn--loading {
593
+ position: relative;
594
+ color: transparent !important;
595
+ pointer-events: none;
596
+ }
597
+
598
+ .btn--loading::after {
599
+ content: '';
600
+ position: absolute;
601
+ width: 16px;
602
+ height: 16px;
603
+ border: 2px solid currentColor;
604
+ border-right-color: transparent;
605
+ border-radius: 50%;
606
+ animation: btn-spin 0.6s linear infinite;
607
+ }
608
+
609
+ .btn-primary.btn--loading::after {
610
+ border-color: var(--text-inverse);
611
+ border-right-color: transparent;
612
+ }
613
+
614
+ @keyframes btn-spin {
615
+ to { transform: rotate(360deg); }
616
+ }
617
+
618
+ /* ═══════════════════════════════════════════════════════════════════════════
619
+ FORM INPUTS
620
+ ═══════════════════════════════════════════════════════════════════════════ */
621
+
622
+ .form-input,
623
+ .form-select,
624
+ .form-textarea {
625
+ width: 100%;
626
+ height: 38px;
627
+ padding: 0 var(--space-3);
628
+ font-family: var(--font-body);
629
+ font-size: var(--text-sm);
630
+ color: var(--text-primary);
631
+ background: var(--surface-raised);
632
+ border: 1px solid var(--surface-border);
633
+ border-radius: var(--radius-md);
634
+ outline: none;
635
+ transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
636
+ }
637
+
638
+ .form-input::placeholder,
639
+ .form-textarea::placeholder {
640
+ color: var(--text-disabled);
641
+ }
642
+
643
+ .form-input:focus,
644
+ .form-select:focus,
645
+ .form-textarea:focus {
646
+ border-color: var(--primary-500);
647
+ box-shadow: var(--shadow-focus);
648
+ }
649
+
650
+ .form-input:read-only {
651
+ background: var(--surface-inset);
652
+ cursor: default;
653
+ }
654
+
655
+ .form-input.has-error,
656
+ .form-input[aria-invalid="true"] {
657
+ border-color: var(--danger-500);
658
+ box-shadow: var(--shadow-focus-error);
659
+ }
660
+
661
+ .form-textarea {
662
+ height: auto;
663
+ min-height: 80px;
664
+ padding: var(--space-3);
665
+ resize: vertical;
666
+ line-height: 1.6;
667
+ }
668
+
669
+ .form-select {
670
+ appearance: none;
671
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2378716C' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
672
+ background-position: right 8px center;
673
+ background-repeat: no-repeat;
674
+ background-size: 18px;
675
+ padding-right: 36px;
676
+ cursor: pointer;
677
+ }
678
+
679
+ /* ── Field Wrapper ───────────────────────────────────────────────────────── */
680
+
681
+ .field-wrapper {
682
+ display: flex;
683
+ flex-direction: column;
684
+ gap: 6px;
685
+ }
686
+
687
+ .field-wrapper.has-error .form-input,
688
+ .field-wrapper.has-error .form-select,
689
+ .field-wrapper.has-error .form-textarea {
690
+ border-color: var(--danger-500);
691
+ }
692
+
693
+ .field-label {
694
+ display: flex;
695
+ align-items: center;
696
+ gap: var(--space-1);
697
+ font-size: var(--text-sm);
698
+ font-weight: var(--font-medium);
699
+ color: var(--text-primary);
700
+ }
701
+
702
+ .required-star {
703
+ color: var(--danger-500);
704
+ font-weight: var(--font-normal);
705
+ }
706
+
707
+ .field-help {
708
+ font-size: var(--text-xs);
709
+ color: var(--text-secondary);
710
+ line-height: 1.5;
711
+ }
712
+
713
+ .field-errors {
714
+ margin: 0;
715
+ padding: 0;
716
+ }
717
+
718
+ .field-errors li {
719
+ display: flex;
720
+ align-items: center;
721
+ gap: var(--space-1);
722
+ font-size: var(--text-xs);
723
+ color: var(--danger-500);
724
+ }
725
+
726
+ .field-errors li::before {
727
+ content: '!';
728
+ display: inline-flex;
729
+ align-items: center;
730
+ justify-content: center;
731
+ width: 14px;
732
+ height: 14px;
733
+ border-radius: 50%;
734
+ background: var(--danger-500);
735
+ color: var(--text-inverse);
736
+ font-size: 9px;
737
+ font-weight: var(--font-semibold);
738
+ flex-shrink: 0;
739
+ }
740
+
741
+ /* ═══════════════════════════════════════════════════════════════════════════
742
+ FIELDSETS (Form sections)
743
+ ═══════════════════════════════════════════════════════════════════════════ */
744
+
745
+ .fieldset {
746
+ background: var(--surface-raised);
747
+ border: 1px solid var(--surface-border);
748
+ border-radius: var(--radius-lg);
749
+ padding: var(--space-5);
750
+ }
751
+
752
+ .fieldset__header {
753
+ display: flex;
754
+ align-items: center;
755
+ justify-content: space-between;
756
+ padding-bottom: var(--space-4);
757
+ border-bottom: 1px solid var(--surface-border);
758
+ margin-bottom: var(--space-5);
759
+ }
760
+
761
+ .fieldset__title {
762
+ font-family: var(--font-body);
763
+ font-size: var(--text-2xs);
764
+ font-weight: var(--font-medium);
765
+ text-transform: uppercase;
766
+ letter-spacing: 0.1em;
767
+ color: var(--text-secondary);
768
+ margin: 0;
769
+ }
770
+
771
+ .fieldset__toggle {
772
+ background: none;
773
+ border: none;
774
+ cursor: pointer;
775
+ padding: var(--space-1);
776
+ color: var(--text-disabled);
777
+ display: flex;
778
+ align-items: center;
779
+ justify-content: center;
780
+ border-radius: var(--radius-sm);
781
+ transition: color var(--duration-fast), background var(--duration-fast);
782
+ }
783
+
784
+ .fieldset__toggle:hover {
785
+ color: var(--text-primary);
786
+ background: var(--surface-inset);
787
+ }
788
+
789
+ .fieldset__toggle svg {
790
+ width: 16px;
791
+ height: 16px;
792
+ transition: transform var(--duration-base) var(--easing-out);
793
+ }
794
+
795
+ .fieldset__fields {
796
+ display: grid;
797
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
798
+ gap: var(--space-4);
799
+ }
800
+
801
+ .fieldset__fields > .field-wrapper--full {
802
+ grid-column: 1 / -1;
803
+ }
804
+
805
+ /* ═══════════════════════════════════════════════════════════════════════════
806
+ BADGES
807
+ ═══════════════════════════════════════════════════════════════════════════ */
808
+
809
+ .badge {
810
+ display: inline-flex;
811
+ align-items: center;
812
+ gap: 4px;
813
+ padding: 2px 8px;
814
+ font-family: var(--font-body);
815
+ font-size: var(--text-2xs);
816
+ font-weight: var(--font-medium);
817
+ line-height: 1.5;
818
+ border-radius: var(--radius-sm);
819
+ letter-spacing: 0.02em;
820
+ }
821
+
822
+ .badge-success {
823
+ background: var(--success-50);
824
+ color: var(--success-700);
825
+ }
826
+
827
+ .badge-warning {
828
+ background: var(--warning-50);
829
+ color: var(--warning-700);
830
+ }
831
+
832
+ .badge-danger {
833
+ background: var(--danger-50);
834
+ color: var(--danger-700);
835
+ }
836
+
837
+ .badge-info {
838
+ background: var(--info-50);
839
+ color: var(--info-700);
840
+ }
841
+
842
+ .badge-primary {
843
+ background: var(--primary-50);
844
+ color: var(--primary-700);
845
+ }
846
+
847
+ /* Mono badge — for counts and data */
848
+ .badge-mono {
849
+ font-family: var(--font-mono);
850
+ font-size: var(--text-2xs);
851
+ background: var(--surface-inset);
852
+ color: var(--mono-accent);
853
+ border: 1px solid var(--surface-border);
854
+ }
855
+
856
+ /* ═══════════════════════════════════════════════════════════════════════════
857
+ TOGGLE SWITCH
858
+ ═══════════════════════════════════════════════════════════════════════════ */
859
+
860
+ .toggle-switch {
861
+ position: relative;
862
+ display: inline-flex;
863
+ align-items: center;
864
+ width: 38px;
865
+ height: 22px;
866
+ border-radius: var(--radius-full);
867
+ background: var(--surface-border);
868
+ cursor: pointer;
869
+ transition: background var(--duration-fast);
870
+ flex-shrink: 0;
871
+ }
872
+
873
+ .toggle-switch[aria-checked="true"],
874
+ .toggle-switch.active {
875
+ background: var(--primary-500);
876
+ }
877
+
878
+ .toggle-knob {
879
+ position: absolute;
880
+ left: 3px;
881
+ width: 16px;
882
+ height: 16px;
883
+ border-radius: 50%;
884
+ background: var(--text-inverse);
885
+ box-shadow: var(--shadow-xs);
886
+ transition: transform var(--duration-fast) var(--easing-spring);
887
+ }
888
+
889
+ .toggle-switch[aria-checked="true"] .toggle-knob,
890
+ .toggle-switch.active .toggle-knob {
891
+ transform: translateX(16px);
892
+ }
893
+
894
+ /* ═══════════════════════════════════════════════════════════════════════════
895
+ TABLE
896
+ ═══════════════════════════════════════════════════════════════════════════ */
897
+
898
+ .table-container {
899
+ background: var(--surface-raised);
900
+ border: 1px solid var(--surface-border);
901
+ border-radius: var(--radius-lg);
902
+ overflow: hidden;
903
+ }
904
+
905
+ .table-wrapper {
906
+ width: 100%;
907
+ border-collapse: collapse;
908
+ }
909
+
910
+ /* Header */
911
+ .table-wrapper thead {
912
+ background: var(--surface-inset);
913
+ }
914
+
915
+ .table-wrapper thead tr {
916
+ border-bottom: 2px solid var(--surface-border);
917
+ }
918
+
919
+ .table-wrapper th {
920
+ padding: var(--space-3) var(--space-4);
921
+ text-align: left;
922
+ font-family: var(--font-body);
923
+ font-size: var(--text-2xs);
924
+ font-weight: var(--font-medium);
925
+ color: var(--text-secondary);
926
+ text-transform: uppercase;
927
+ letter-spacing: 0.08em;
928
+ white-space: nowrap;
929
+ user-select: none;
930
+ }
931
+
932
+ .table__th--sortable {
933
+ cursor: pointer;
934
+ transition: color var(--duration-fast);
935
+ }
936
+
937
+ .table__th--sortable:hover {
938
+ color: var(--text-primary);
939
+ }
940
+
941
+ .table__th--checkbox {
942
+ width: 44px;
943
+ }
944
+
945
+ .table__th--actions {
946
+ text-align: right;
947
+ }
948
+
949
+ /* Body rows */
950
+ .table-wrapper tbody tr {
951
+ border-bottom: 1px solid var(--surface-border);
952
+ transition: background var(--duration-fast);
953
+ }
954
+
955
+ .table-wrapper tbody tr:last-child {
956
+ border-bottom: none;
957
+ }
958
+
959
+ .table-wrapper tbody tr:hover {
960
+ background: var(--primary-50);
961
+ }
962
+
963
+ .table-wrapper td {
964
+ padding: var(--space-3) var(--space-4);
965
+ font-size: var(--text-sm);
966
+ color: var(--text-primary);
967
+ white-space: nowrap;
968
+ vertical-align: middle;
969
+ }
970
+
971
+ .table__cell--checkbox {
972
+ width: 44px;
973
+ }
974
+
975
+ .table-checkbox {
976
+ width: 16px;
977
+ height: 16px;
978
+ border: 1.5px solid var(--surface-border);
979
+ border-radius: var(--radius-sm);
980
+ cursor: pointer;
981
+ appearance: none;
982
+ background: var(--surface-raised);
983
+ transition: all var(--duration-fast);
984
+ position: relative;
985
+ }
986
+
987
+ .table-checkbox:checked {
988
+ background: var(--primary-500);
989
+ border-color: var(--primary-500);
990
+ }
991
+
992
+ .table-checkbox:checked::after {
993
+ content: '';
994
+ position: absolute;
995
+ left: 4px;
996
+ top: 1px;
997
+ width: 5px;
998
+ height: 9px;
999
+ border: solid var(--text-inverse);
1000
+ border-width: 0 2px 2px 0;
1001
+ transform: rotate(45deg);
1002
+ }
1003
+
1004
+ .table-checkbox:indeterminate {
1005
+ background: var(--primary-500);
1006
+ border-color: var(--primary-500);
1007
+ }
1008
+
1009
+ .table-checkbox:indeterminate::after {
1010
+ content: '';
1011
+ position: absolute;
1012
+ left: 3px;
1013
+ top: 6px;
1014
+ width: 8px;
1015
+ height: 0;
1016
+ border-bottom: 2px solid var(--text-inverse);
1017
+ }
1018
+
1019
+ .table__cell--mono {
1020
+ font-family: var(--font-mono);
1021
+ font-size: var(--text-xs);
1022
+ color: var(--mono-accent);
1023
+ }
1024
+
1025
+ .table__cell--actions {
1026
+ text-align: right;
1027
+ white-space: nowrap;
1028
+ }
1029
+
1030
+ /* Actions in table */
1031
+ .table-actions {
1032
+ display: flex;
1033
+ align-items: center;
1034
+ justify-content: flex-end;
1035
+ gap: var(--space-1);
1036
+ }
1037
+
1038
+ .table-actions__separator {
1039
+ width: 3px;
1040
+ height: 3px;
1041
+ border-radius: 50%;
1042
+ background: var(--text-disabled);
1043
+ flex-shrink: 0;
1044
+ }
1045
+
1046
+ .table-action {
1047
+ font-size: var(--text-xs);
1048
+ color: var(--text-secondary);
1049
+ cursor: pointer;
1050
+ transition: color var(--duration-fast);
1051
+ background: none;
1052
+ border: none;
1053
+ padding: 2px 4px;
1054
+ font-family: var(--font-body);
1055
+ }
1056
+
1057
+ .table-action:hover {
1058
+ color: var(--text-primary);
1059
+ }
1060
+
1061
+ .table-action--danger:hover {
1062
+ color: var(--danger-500);
1063
+ }
1064
+
1065
+ /* Inline delete confirmation */
1066
+ .table-delete-confirm {
1067
+ display: flex;
1068
+ align-items: center;
1069
+ gap: var(--space-2);
1070
+ font-size: var(--text-xs);
1071
+ color: var(--danger-500);
1072
+ }
1073
+
1074
+ /* ═══════════════════════════════════════════════════════════════════════════
1075
+ SEARCH & FILTER BAR
1076
+ ═══════════════════════════════════════════════════════════════════════════ */
1077
+
1078
+ .filter-bar {
1079
+ display: flex;
1080
+ align-items: center;
1081
+ gap: var(--space-2);
1082
+ padding-bottom: var(--space-4);
1083
+ flex-wrap: wrap;
1084
+ }
1085
+
1086
+ .filter-bar__search-wrap {
1087
+ position: relative;
1088
+ flex: 1;
1089
+ max-width: 360px;
1090
+ min-width: 200px;
1091
+ }
1092
+
1093
+ .filter-bar__search-icon {
1094
+ position: absolute;
1095
+ left: 10px;
1096
+ top: 50%;
1097
+ transform: translateY(-50%);
1098
+ width: 15px;
1099
+ height: 15px;
1100
+ color: var(--text-disabled);
1101
+ pointer-events: none;
1102
+ }
1103
+
1104
+ .filter-bar__search {
1105
+ height: 36px;
1106
+ padding: 0 var(--space-3) 0 32px;
1107
+ font-size: var(--text-sm);
1108
+ }
1109
+
1110
+ .filter-chip {
1111
+ display: inline-flex;
1112
+ align-items: center;
1113
+ gap: var(--space-1);
1114
+ height: 36px;
1115
+ padding: 0 var(--space-3);
1116
+ background: var(--surface-raised);
1117
+ border: 1px solid var(--surface-border);
1118
+ border-radius: var(--radius-md);
1119
+ font-size: var(--text-sm);
1120
+ color: var(--text-secondary);
1121
+ cursor: pointer;
1122
+ transition: all var(--duration-fast);
1123
+ font-family: var(--font-body);
1124
+ }
1125
+
1126
+ .filter-chip:hover {
1127
+ border-color: var(--text-disabled);
1128
+ color: var(--text-primary);
1129
+ }
1130
+
1131
+ .filter-chip--active {
1132
+ background: var(--primary-50);
1133
+ border-color: var(--primary-200);
1134
+ color: var(--primary-700);
1135
+ }
1136
+
1137
+ .filter-chip svg {
1138
+ width: 14px;
1139
+ height: 14px;
1140
+ }
1141
+
1142
+ .filter-bar__clear {
1143
+ font-size: var(--text-xs);
1144
+ color: var(--text-secondary);
1145
+ cursor: pointer;
1146
+ background: none;
1147
+ border: none;
1148
+ font-family: var(--font-body);
1149
+ padding: var(--space-2);
1150
+ transition: color var(--duration-fast);
1151
+ }
1152
+
1153
+ .filter-bar__clear:hover {
1154
+ color: var(--danger-500);
1155
+ }
1156
+
1157
+ .filter-bar__divider {
1158
+ width: 1px;
1159
+ height: 24px;
1160
+ background: var(--surface-border);
1161
+ flex-shrink: 0;
1162
+ }
1163
+
1164
+ /* Date / DateTime / Time filter inputs */
1165
+ .filter-chip-wrap {
1166
+ display: inline-flex;
1167
+ align-items: center;
1168
+ gap: var(--space-1);
1169
+ height: 36px;
1170
+ background: var(--surface-raised);
1171
+ border: 1px solid var(--surface-border);
1172
+ border-radius: var(--radius-md);
1173
+ transition: all var(--duration-fast);
1174
+ }
1175
+
1176
+ .filter-chip-wrap:hover {
1177
+ border-color: var(--text-disabled);
1178
+ }
1179
+
1180
+ .filter-chip-wrap.filter-chip--active {
1181
+ background: var(--primary-50);
1182
+ border-color: var(--primary-200);
1183
+ }
1184
+
1185
+ .filter-chip-label {
1186
+ padding-left: var(--space-3);
1187
+ font-size: var(--text-sm);
1188
+ color: var(--text-secondary);
1189
+ white-space: nowrap;
1190
+ pointer-events: none;
1191
+ user-select: none;
1192
+ }
1193
+
1194
+ .filter-input-date,
1195
+ .filter-input-datetime,
1196
+ .filter-input-time {
1197
+ height: 34px;
1198
+ padding: 0 var(--space-2);
1199
+ border: none;
1200
+ background: transparent;
1201
+ font-size: var(--text-sm);
1202
+ font-family: var(--font-body);
1203
+ color: var(--text-primary);
1204
+ cursor: pointer;
1205
+ outline: none;
1206
+ }
1207
+
1208
+ .filter-input-date:focus,
1209
+ .filter-input-datetime:focus,
1210
+ .filter-input-time:focus {
1211
+ outline: none;
1212
+ }
1213
+
1214
+ .filter-clear-btn {
1215
+ display: inline-flex;
1216
+ align-items: center;
1217
+ justify-content: center;
1218
+ width: 20px;
1219
+ height: 20px;
1220
+ margin-right: var(--space-1);
1221
+ border-radius: var(--radius-sm);
1222
+ font-size: 14px;
1223
+ line-height: 1;
1224
+ color: var(--text-secondary);
1225
+ text-decoration: none;
1226
+ transition: all var(--duration-fast);
1227
+ }
1228
+
1229
+ .filter-clear-btn:hover {
1230
+ background: var(--danger-50);
1231
+ color: var(--danger-500);
1232
+ }
1233
+
1234
+ /* ═══════════════════════════════════════════════════════════════════════════
1235
+ BULK ACTION BAR
1236
+ ═══════════════════════════════════════════════════════════════════════════ */
1237
+
1238
+ .bulk-action-bar {
1239
+ display: flex;
1240
+ align-items: center;
1241
+ gap: var(--space-3);
1242
+ height: 48px;
1243
+ padding: 0 var(--space-4);
1244
+ background: var(--primary-50);
1245
+ border: 1px solid var(--primary-200);
1246
+ border-radius: var(--radius-lg);
1247
+ margin-bottom: var(--space-4);
1248
+ }
1249
+
1250
+ .bulk-action-bar__count {
1251
+ font-size: var(--text-sm);
1252
+ font-weight: var(--font-medium);
1253
+ color: var(--primary-700);
1254
+ }
1255
+
1256
+ /* ═══════════════════════════════════════════════════════════════════════════
1257
+ PAGINATION
1258
+ ═══════════════════════════════════════════════════════════════════════════ */
1259
+
1260
+ .pagination {
1261
+ display: flex;
1262
+ align-items: center;
1263
+ justify-content: space-between;
1264
+ padding: var(--space-3) var(--space-4);
1265
+ border-top: 1px solid var(--surface-border);
1266
+ }
1267
+
1268
+ .pagination__info {
1269
+ font-size: var(--text-xs);
1270
+ color: var(--text-secondary);
1271
+ }
1272
+
1273
+ .pagination__info strong {
1274
+ font-family: var(--font-mono);
1275
+ color: var(--mono-accent);
1276
+ font-weight: var(--font-normal);
1277
+ }
1278
+
1279
+ .pagination__links {
1280
+ display: flex;
1281
+ align-items: center;
1282
+ gap: 3px;
1283
+ }
1284
+
1285
+ .pagination__link {
1286
+ display: inline-flex;
1287
+ align-items: center;
1288
+ justify-content: center;
1289
+ min-width: 30px;
1290
+ height: 30px;
1291
+ padding: 0 var(--space-2);
1292
+ border-radius: var(--radius-sm);
1293
+ font-size: var(--text-xs);
1294
+ font-family: var(--font-mono);
1295
+ color: var(--text-secondary);
1296
+ cursor: pointer;
1297
+ transition: all var(--duration-fast);
1298
+ border: none;
1299
+ background: none;
1300
+ }
1301
+
1302
+ .pagination__link:hover {
1303
+ background: var(--surface-inset);
1304
+ color: var(--text-primary);
1305
+ }
1306
+
1307
+ .pagination__link--active {
1308
+ background: var(--primary-500);
1309
+ color: var(--text-inverse);
1310
+ font-weight: var(--font-medium);
1311
+ }
1312
+
1313
+ .pagination__link--disabled {
1314
+ opacity: 0.4;
1315
+ cursor: not-allowed;
1316
+ }
1317
+
1318
+ /* ═══════════════════════════════════════════════════════════════════════════
1319
+ MODAL
1320
+ ═══════════════════════════════════════════════════════════════════════════ */
1321
+
1322
+ .modal-backdrop {
1323
+ position: fixed;
1324
+ inset: 0;
1325
+ background: rgba(20, 18, 16, 0.6);
1326
+ backdrop-filter: blur(4px);
1327
+ z-index: 50;
1328
+ animation: modal-fade-in var(--duration-base) var(--easing-out);
1329
+ }
1330
+
1331
+ .modal {
1332
+ position: fixed;
1333
+ top: 50%;
1334
+ left: 50%;
1335
+ transform: translate(-50%, -50%);
1336
+ z-index: 51;
1337
+ background: var(--surface-raised);
1338
+ border: 1px solid var(--surface-border);
1339
+ border-radius: var(--radius-lg);
1340
+ box-shadow: var(--shadow-lg);
1341
+ width: 520px;
1342
+ max-width: calc(100vw - 32px);
1343
+ max-height: 85vh;
1344
+ display: flex;
1345
+ flex-direction: column;
1346
+ animation: modal-scale-in var(--duration-slow) var(--easing-out);
1347
+ }
1348
+
1349
+ .modal--sm { width: 420px; }
1350
+ .modal--lg { width: 720px; }
1351
+
1352
+ .modal__header {
1353
+ padding: var(--space-5) var(--space-6);
1354
+ border-bottom: 1px solid var(--surface-border);
1355
+ display: flex;
1356
+ align-items: center;
1357
+ justify-content: space-between;
1358
+ }
1359
+
1360
+ .modal__title {
1361
+ font-family: var(--font-display);
1362
+ font-size: var(--text-lg);
1363
+ color: var(--text-primary);
1364
+ margin: 0;
1365
+ }
1366
+
1367
+ .modal__close {
1368
+ background: none;
1369
+ border: none;
1370
+ cursor: pointer;
1371
+ padding: var(--space-1);
1372
+ color: var(--text-disabled);
1373
+ border-radius: var(--radius-sm);
1374
+ display: flex;
1375
+ align-items: center;
1376
+ justify-content: center;
1377
+ transition: all var(--duration-fast);
1378
+ }
1379
+
1380
+ .modal__close:hover {
1381
+ color: var(--text-primary);
1382
+ background: var(--surface-inset);
1383
+ }
1384
+
1385
+ .modal__close svg {
1386
+ width: 18px;
1387
+ height: 18px;
1388
+ }
1389
+
1390
+ .modal__body {
1391
+ padding: var(--space-6);
1392
+ overflow-y: auto;
1393
+ flex: 1;
1394
+ font-size: var(--text-sm);
1395
+ line-height: 1.6;
1396
+ }
1397
+
1398
+ .modal__footer {
1399
+ padding: var(--space-4) var(--space-6);
1400
+ border-top: 1px solid var(--surface-border);
1401
+ display: flex;
1402
+ justify-content: flex-end;
1403
+ gap: var(--space-2);
1404
+ }
1405
+
1406
+ @keyframes modal-fade-in {
1407
+ from { opacity: 0; }
1408
+ to { opacity: 1; }
1409
+ }
1410
+
1411
+ @keyframes modal-scale-in {
1412
+ from {
1413
+ opacity: 0;
1414
+ transform: translate(-50%, -50%) scale(0.96);
1415
+ }
1416
+ to {
1417
+ opacity: 1;
1418
+ transform: translate(-50%, -50%) scale(1);
1419
+ }
1420
+ }
1421
+
1422
+ /* ═══════════════════════════════════════════════════════════════════════════
1423
+ TOAST / FLASH MESSAGES
1424
+ ═══════════════════════════════════════════════════════════════════════════ */
1425
+
1426
+ .toast-container {
1427
+ position: fixed;
1428
+ top: calc(var(--topbar-height) + var(--space-4));
1429
+ right: var(--space-4);
1430
+ z-index: 100;
1431
+ display: flex;
1432
+ flex-direction: column;
1433
+ gap: var(--space-2);
1434
+ pointer-events: none;
1435
+ }
1436
+
1437
+ .toast {
1438
+ max-width: 380px;
1439
+ width: 100%;
1440
+ background: var(--surface-raised);
1441
+ border: 1px solid var(--surface-border);
1442
+ border-radius: var(--radius-md);
1443
+ box-shadow: var(--shadow-lg);
1444
+ padding: var(--space-3) var(--space-4);
1445
+ display: flex;
1446
+ align-items: flex-start;
1447
+ gap: var(--space-3);
1448
+ pointer-events: auto;
1449
+ animation: toast-slide-in var(--duration-slow) var(--easing-out);
1450
+ }
1451
+
1452
+ .toast__icon {
1453
+ width: 18px;
1454
+ height: 18px;
1455
+ flex-shrink: 0;
1456
+ margin-top: 1px;
1457
+ }
1458
+
1459
+ .toast__content {
1460
+ flex: 1;
1461
+ min-width: 0;
1462
+ }
1463
+
1464
+ .toast__message {
1465
+ font-size: var(--text-sm);
1466
+ color: var(--text-primary);
1467
+ line-height: 1.5;
1468
+ }
1469
+
1470
+ .toast__close {
1471
+ background: none;
1472
+ border: none;
1473
+ cursor: pointer;
1474
+ padding: 2px;
1475
+ color: var(--text-disabled);
1476
+ flex-shrink: 0;
1477
+ display: flex;
1478
+ border-radius: var(--radius-sm);
1479
+ transition: all var(--duration-fast);
1480
+ }
1481
+
1482
+ .toast__close:hover {
1483
+ color: var(--text-primary);
1484
+ background: var(--surface-inset);
1485
+ }
1486
+
1487
+ .toast-success {
1488
+ border-left: 3px solid var(--success-500);
1489
+ }
1490
+
1491
+ .toast-success .toast__icon {
1492
+ color: var(--success-500);
1493
+ }
1494
+
1495
+ .toast-error {
1496
+ border-left: 3px solid var(--danger-500);
1497
+ }
1498
+
1499
+ .toast-error .toast__icon {
1500
+ color: var(--danger-500);
1501
+ }
1502
+
1503
+ .toast-warning {
1504
+ border-left: 3px solid var(--warning-500);
1505
+ }
1506
+
1507
+ .toast-warning .toast__icon {
1508
+ color: var(--warning-500);
1509
+ }
1510
+
1511
+ .toast-info {
1512
+ border-left: 3px solid var(--info-500);
1513
+ }
1514
+
1515
+ .toast-info .toast__icon {
1516
+ color: var(--info-500);
1517
+ }
1518
+
1519
+ @keyframes toast-slide-in {
1520
+ from {
1521
+ opacity: 0;
1522
+ transform: translateX(100%);
1523
+ }
1524
+ to {
1525
+ opacity: 1;
1526
+ transform: translateX(0);
1527
+ }
1528
+ }
1529
+
1530
+ /* ═══════════════════════════════════════════════════════════════════════════
1531
+ SAVE BAR (sticky bottom for forms)
1532
+ ═══════════════════════════════════════════════════════════════════════════ */
1533
+
1534
+ .form-save-bar {
1535
+ position: sticky;
1536
+ bottom: 0;
1537
+ background: var(--surface-raised);
1538
+ border-top: 1px solid var(--surface-border);
1539
+ padding: var(--space-3) var(--content-padding);
1540
+ z-index: 20;
1541
+ display: flex;
1542
+ align-items: center;
1543
+ justify-content: space-between;
1544
+ box-shadow: 0 -2px 8px rgba(28, 25, 23, 0.04);
1545
+ }
1546
+
1547
+ .form-save-bar__left {
1548
+ display: flex;
1549
+ align-items: center;
1550
+ }
1551
+
1552
+ .form-save-bar__right {
1553
+ display: flex;
1554
+ align-items: center;
1555
+ gap: var(--space-2);
1556
+ }
1557
+
1558
+ /* ═══════════════════════════════════════════════════════════════════════════
1559
+ EMPTY STATE
1560
+ ═══════════════════════════════════════════════════════════════════════════ */
1561
+
1562
+ .empty-state {
1563
+ display: flex;
1564
+ flex-direction: column;
1565
+ align-items: center;
1566
+ justify-content: center;
1567
+ padding: var(--space-16) var(--space-4);
1568
+ text-align: center;
1569
+ }
1570
+
1571
+ .empty-state__icon {
1572
+ width: 48px;
1573
+ height: 48px;
1574
+ color: var(--text-disabled);
1575
+ margin-bottom: var(--space-4);
1576
+ opacity: 0.5;
1577
+ }
1578
+
1579
+ .empty-state__title {
1580
+ font-family: var(--font-display);
1581
+ font-size: var(--text-lg);
1582
+ color: var(--text-secondary);
1583
+ margin: 0 0 var(--space-2);
1584
+ }
1585
+
1586
+ .empty-state__text {
1587
+ font-size: var(--text-sm);
1588
+ color: var(--text-disabled);
1589
+ margin: 0 0 var(--space-5);
1590
+ }
1591
+
1592
+ /* ═══════════════════════════════════════════════════════════════════════════
1593
+ TAG CHIPS
1594
+ ═══════════════════════════════════════════════════════════════════════════ */
1595
+
1596
+ .tag-chip {
1597
+ display: inline-flex;
1598
+ align-items: center;
1599
+ gap: var(--space-1);
1600
+ padding: 2px 10px;
1601
+ border-radius: var(--radius-full);
1602
+ background: var(--primary-50);
1603
+ color: var(--primary-700);
1604
+ font-size: var(--text-xs);
1605
+ font-weight: var(--font-medium);
1606
+ }
1607
+
1608
+ .tag-chip__remove {
1609
+ display: inline-flex;
1610
+ cursor: pointer;
1611
+ color: var(--primary-400);
1612
+ transition: color var(--duration-fast);
1613
+ }
1614
+
1615
+ .tag-chip__remove:hover {
1616
+ color: var(--danger-500);
1617
+ }
1618
+
1619
+ /* ═══════════════════════════════════════════════════════════════════════════
1620
+ RELATION PICKER
1621
+ ═══════════════════════════════════════════════════════════════════════════ */
1622
+
1623
+ .relation-picker {
1624
+ position: relative;
1625
+ }
1626
+
1627
+ .relation-picker-dropdown {
1628
+ position: absolute;
1629
+ top: 100%;
1630
+ left: 0;
1631
+ right: 0;
1632
+ z-index: 15;
1633
+ margin-top: var(--space-1);
1634
+ background: var(--surface-overlay);
1635
+ border: 1px solid var(--surface-border);
1636
+ border-radius: var(--radius-md);
1637
+ box-shadow: var(--shadow-md);
1638
+ max-height: 240px;
1639
+ overflow-y: auto;
1640
+ animation: dropdown-enter var(--duration-base) var(--easing-out);
1641
+ }
1642
+
1643
+ .relation-option {
1644
+ padding: var(--space-2) var(--space-3);
1645
+ font-size: var(--text-sm);
1646
+ cursor: pointer;
1647
+ transition: background var(--duration-fast);
1648
+ }
1649
+
1650
+ .relation-option:hover {
1651
+ background: var(--primary-50);
1652
+ }
1653
+
1654
+ .relation-option--selected {
1655
+ background: var(--primary-50);
1656
+ color: var(--primary-700);
1657
+ font-weight: var(--font-medium);
1658
+ }
1659
+
1660
+ @keyframes dropdown-enter {
1661
+ from {
1662
+ opacity: 0;
1663
+ transform: translateY(-4px);
1664
+ }
1665
+ to {
1666
+ opacity: 1;
1667
+ transform: translateY(0);
1668
+ }
1669
+ }
1670
+
1671
+ /* ═══════════════════════════════════════════════════════════════════════════
1672
+ JSON EDITOR
1673
+ ═══════════════════════════════════════════════════════════════════════════ */
1674
+
1675
+ .json-editor-wrapper {
1676
+ min-height: 200px;
1677
+ border: 1px solid var(--surface-border);
1678
+ border-radius: var(--radius-md);
1679
+ overflow: hidden;
1680
+ background: var(--surface-inset);
1681
+ }
1682
+
1683
+ .json-editor-wrapper .cm-editor {
1684
+ min-height: 200px;
1685
+ }
1686
+
1687
+ /* ═══════════════════════════════════════════════════════════════════════════
1688
+ DASHBOARD — Stat Cards
1689
+ ═══════════════════════════════════════════════════════════════════════════ */
1690
+
1691
+ .stat-cards {
1692
+ display: grid;
1693
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
1694
+ gap: var(--space-4);
1695
+ margin-bottom: var(--space-8);
1696
+ }
1697
+
1698
+ .stat-card {
1699
+ background: var(--surface-raised);
1700
+ border: 1px solid var(--surface-border);
1701
+ border-radius: var(--radius-lg);
1702
+ padding: var(--space-5);
1703
+ transition: all var(--duration-fast);
1704
+ cursor: pointer;
1705
+ text-decoration: none;
1706
+ display: block;
1707
+ }
1708
+
1709
+ .stat-card:hover {
1710
+ box-shadow: var(--shadow-sm);
1711
+ border-color: var(--text-disabled);
1712
+ }
1713
+
1714
+ .stat-card__label {
1715
+ font-size: var(--text-2xs);
1716
+ font-weight: var(--font-medium);
1717
+ text-transform: uppercase;
1718
+ letter-spacing: 0.08em;
1719
+ color: var(--text-secondary);
1720
+ margin-bottom: var(--space-2);
1721
+ }
1722
+
1723
+ .stat-card__value {
1724
+ font-family: var(--font-display);
1725
+ font-size: var(--text-3xl);
1726
+ color: var(--text-primary);
1727
+ line-height: 1;
1728
+ margin-bottom: var(--space-2);
1729
+ }
1730
+
1731
+ .stat-card__change {
1732
+ font-family: var(--font-mono);
1733
+ font-size: var(--text-2xs);
1734
+ }
1735
+
1736
+ .stat-card__change--positive {
1737
+ color: var(--success-500);
1738
+ }
1739
+
1740
+ .stat-card__change--negative {
1741
+ color: var(--danger-500);
1742
+ }
1743
+
1744
+ /* ═══════════════════════════════════════════════════════════════════════════
1745
+ DASHBOARD — Activity Feed
1746
+ ═══════════════════════════════════════════════════════════════════════════ */
1747
+
1748
+ .activity-feed {
1749
+ background: var(--surface-raised);
1750
+ border: 1px solid var(--surface-border);
1751
+ border-radius: var(--radius-lg);
1752
+ overflow: hidden;
1753
+ }
1754
+
1755
+ .activity-feed__header {
1756
+ padding: var(--space-4) var(--space-5);
1757
+ border-bottom: 1px solid var(--surface-border);
1758
+ }
1759
+
1760
+ .activity-feed__title {
1761
+ font-family: var(--font-display);
1762
+ font-size: var(--text-lg);
1763
+ margin: 0;
1764
+ }
1765
+
1766
+ .activity-item {
1767
+ display: flex;
1768
+ align-items: center;
1769
+ gap: var(--space-3);
1770
+ padding: var(--space-3) var(--space-5);
1771
+ border-bottom: 1px solid var(--surface-border);
1772
+ transition: background var(--duration-fast);
1773
+ }
1774
+
1775
+ .activity-item:last-child {
1776
+ border-bottom: none;
1777
+ }
1778
+
1779
+ .activity-item:hover {
1780
+ background: var(--surface-inset);
1781
+ }
1782
+
1783
+ .activity-item__dot {
1784
+ width: 8px;
1785
+ height: 8px;
1786
+ border-radius: 50%;
1787
+ flex-shrink: 0;
1788
+ }
1789
+
1790
+ .activity-item__dot--create { background: var(--success-500); }
1791
+ .activity-item__dot--update { background: var(--warning-500); }
1792
+ .activity-item__dot--delete { background: var(--danger-500); }
1793
+
1794
+ .activity-item__content {
1795
+ flex: 1;
1796
+ min-width: 0;
1797
+ font-size: var(--text-sm);
1798
+ }
1799
+
1800
+ .activity-item__time {
1801
+ font-family: var(--font-mono);
1802
+ font-size: var(--text-2xs);
1803
+ color: var(--text-secondary);
1804
+ flex-shrink: 0;
1805
+ }
1806
+
1807
+ /* ═══════════════════════════════════════════════════════════════════════════
1808
+ AUDIT LOG — Timeline
1809
+ ═══════════════════════════════════════════════════════════════════════════ */
1810
+
1811
+ .audit-timeline {
1812
+ display: flex;
1813
+ flex-direction: column;
1814
+ gap: var(--space-3);
1815
+ }
1816
+
1817
+ .audit-entry {
1818
+ background: var(--surface-raised);
1819
+ border: 1px solid var(--surface-border);
1820
+ border-radius: var(--radius-md);
1821
+ border-left: 3px solid var(--surface-border);
1822
+ padding: var(--space-4) var(--space-5);
1823
+ cursor: pointer;
1824
+ transition: all var(--duration-fast);
1825
+ }
1826
+
1827
+ .audit-entry:hover {
1828
+ box-shadow: var(--shadow-xs);
1829
+ }
1830
+
1831
+ .audit-entry--create { border-left-color: var(--success-500); }
1832
+ .audit-entry--update { border-left-color: var(--warning-500); }
1833
+ .audit-entry--delete { border-left-color: var(--danger-500); }
1834
+
1835
+ .audit-entry__header {
1836
+ display: flex;
1837
+ align-items: center;
1838
+ gap: var(--space-3);
1839
+ font-size: var(--text-sm);
1840
+ }
1841
+
1842
+ .audit-entry__time {
1843
+ font-family: var(--font-mono);
1844
+ font-size: var(--text-xs);
1845
+ color: var(--text-secondary);
1846
+ }
1847
+
1848
+ .audit-entry__user {
1849
+ color: var(--text-secondary);
1850
+ }
1851
+
1852
+ .audit-entry__model {
1853
+ font-family: var(--font-mono);
1854
+ color: var(--mono-accent);
1855
+ font-size: var(--text-xs);
1856
+ }
1857
+
1858
+ /* ═══════════════════════════════════════════════════════════════════════════
1859
+ PERMISSIONS MATRIX (Roles)
1860
+ ═══════════════════════════════════════════════════════════════════════════ */
1861
+
1862
+ .permissions-matrix {
1863
+ background: var(--surface-raised);
1864
+ border: 1px solid var(--surface-border);
1865
+ border-radius: var(--radius-lg);
1866
+ overflow: hidden;
1867
+ }
1868
+
1869
+ .permissions-matrix table {
1870
+ width: 100%;
1871
+ border-collapse: collapse;
1872
+ }
1873
+
1874
+ .permissions-matrix th {
1875
+ padding: var(--space-3) var(--space-4);
1876
+ font-size: var(--text-2xs);
1877
+ font-weight: var(--font-medium);
1878
+ text-transform: uppercase;
1879
+ letter-spacing: 0.08em;
1880
+ color: var(--text-secondary);
1881
+ text-align: center;
1882
+ background: var(--surface-inset);
1883
+ border-bottom: 2px solid var(--surface-border);
1884
+ }
1885
+
1886
+ .permissions-matrix th:first-child {
1887
+ text-align: left;
1888
+ }
1889
+
1890
+ .permissions-matrix td {
1891
+ padding: var(--space-3) var(--space-4);
1892
+ text-align: center;
1893
+ border-bottom: 1px solid var(--surface-border);
1894
+ font-size: var(--text-sm);
1895
+ }
1896
+
1897
+ .permissions-matrix td:first-child {
1898
+ text-align: left;
1899
+ font-weight: var(--font-medium);
1900
+ }
1901
+
1902
+ .permissions-matrix tr:last-child td {
1903
+ border-bottom: none;
1904
+ }
1905
+
1906
+ .permissions-matrix tr:hover {
1907
+ background: var(--surface-inset);
1908
+ }
1909
+
1910
+ /* Custom checkbox for matrix */
1911
+ .matrix-checkbox {
1912
+ width: 18px;
1913
+ height: 18px;
1914
+ border: 1.5px solid var(--surface-border);
1915
+ border-radius: var(--radius-sm);
1916
+ cursor: pointer;
1917
+ appearance: none;
1918
+ background: var(--surface-raised);
1919
+ transition: all var(--duration-fast);
1920
+ position: relative;
1921
+ }
1922
+
1923
+ .matrix-checkbox:checked {
1924
+ background: var(--primary-500);
1925
+ border-color: var(--primary-500);
1926
+ }
1927
+
1928
+ .matrix-checkbox:checked::after {
1929
+ content: '';
1930
+ position: absolute;
1931
+ left: 5px;
1932
+ top: 2px;
1933
+ width: 5px;
1934
+ height: 9px;
1935
+ border: solid var(--text-inverse);
1936
+ border-width: 0 2px 2px 0;
1937
+ transform: rotate(45deg);
1938
+ }
1939
+
1940
+ /* ═══════════════════════════════════════════════════════════════════════════
1941
+ HTMX INDICATORS
1942
+ ═══════════════════════════════════════════════════════════════════════════ */
1943
+
1944
+ .htmx-indicator {
1945
+ display: none;
1946
+ }
1947
+
1948
+ .htmx-request .htmx-indicator {
1949
+ display: inline-flex;
1950
+ }
1951
+
1952
+ .htmx-request.htmx-indicator {
1953
+ display: inline-flex;
1954
+ }
1955
+
1956
+ .htmx-swapping {
1957
+ opacity: 0;
1958
+ transition: opacity var(--duration-fast);
1959
+ }
1960
+
1961
+ .htmx-settling {
1962
+ opacity: 1;
1963
+ transition: opacity var(--duration-fast);
1964
+ }
1965
+
1966
+ /* HTMX loading bar */
1967
+ .htmx-indicator-loading {
1968
+ position: fixed;
1969
+ top: 0;
1970
+ left: 0;
1971
+ right: 0;
1972
+ height: 2px;
1973
+ background: var(--primary-500);
1974
+ z-index: 1000;
1975
+ transform-origin: left;
1976
+ transform: scaleX(0);
1977
+ transition: transform 300ms var(--easing-out);
1978
+ }
1979
+
1980
+ .htmx-request > .htmx-indicator-loading {
1981
+ transform: scaleX(0.3);
1982
+ }
1983
+
1984
+ /* ═══════════════════════════════════════════════════════════════════════════
1985
+ UTILITIES
1986
+ ═══════════════════════════════════════════════════════════════════════════ */
1987
+
1988
+ .sr-only {
1989
+ position: absolute;
1990
+ width: 1px;
1991
+ height: 1px;
1992
+ padding: 0;
1993
+ margin: -1px;
1994
+ overflow: hidden;
1995
+ clip: rect(0, 0, 0, 0);
1996
+ white-space: nowrap;
1997
+ border-width: 0;
1998
+ }
1999
+
2000
+ .truncate {
2001
+ overflow: hidden;
2002
+ text-overflow: ellipsis;
2003
+ white-space: nowrap;
2004
+ }
2005
+
2006
+ /* ═══════════════════════════════════════════════════════════════════════════
2007
+ TOPBAR — inner layout zones
2008
+ ═══════════════════════════════════════════════════════════════════════════ */
2009
+
2010
+ .topbar-left { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
2011
+ .topbar-center { flex: 1; display: flex; justify-content: center; }
2012
+ .topbar-right { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
2013
+
2014
+ .topbar-logo {
2015
+ display: flex; align-items: center; gap: var(--space-2);
2016
+ font-family: var(--font-display); font-size: var(--text-lg);
2017
+ color: var(--text-primary); white-space: nowrap; text-decoration: none;
2018
+ }
2019
+ .topbar-logo img { height: 28px; max-width: 120px; }
2020
+
2021
+ .topbar-logo-icon {
2022
+ display: flex; align-items: center; justify-content: center;
2023
+ color: var(--primary-500);
2024
+ }
2025
+
2026
+ .topbar-search {
2027
+ display: flex; align-items: center; gap: var(--space-2);
2028
+ padding: var(--space-2) var(--space-3);
2029
+ background: var(--surface-inset); border: 1px solid var(--surface-border);
2030
+ border-radius: var(--radius-lg); cursor: pointer;
2031
+ transition: all var(--duration-fast);
2032
+ min-width: 280px;
2033
+ }
2034
+ .topbar-search:hover { border-color: var(--primary-300); }
2035
+ .topbar-search svg { color: var(--text-disabled); flex-shrink: 0; }
2036
+ .topbar-search-placeholder { color: var(--text-disabled); font-size: var(--text-sm); flex: 1; }
2037
+ .topbar-search-shortcut { display: flex; gap: 4px; }
2038
+ .topbar-search-shortcut kbd {
2039
+ display: inline-flex; align-items: center; justify-content: center;
2040
+ padding: 2px 6px; font-size: var(--text-2xs); font-family: var(--font-mono);
2041
+ background: var(--surface-raised); border: 1px solid var(--surface-border);
2042
+ border-radius: var(--radius-xs); color: var(--text-secondary);
2043
+ }
2044
+
2045
+ .topbar-user { position: relative; }
2046
+ .topbar-user-btn {
2047
+ display: flex; align-items: center; gap: var(--space-2);
2048
+ padding: var(--space-1); border-radius: var(--radius-md);
2049
+ background: none; border: none; cursor: pointer;
2050
+ transition: all var(--duration-fast);
2051
+ }
2052
+ .topbar-user-btn:hover { background: var(--surface-inset); }
2053
+ .topbar-user-info { display: flex; flex-direction: column; text-align: left; }
2054
+ .topbar-user-name { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--text-primary); line-height: 1.2; }
2055
+ .topbar-user-role { font-size: var(--text-2xs); color: var(--text-secondary); line-height: 1.2; }
2056
+
2057
+ .topbar-divider { width: 1px; height: 24px; background: var(--surface-border); margin: 0 var(--space-2); }
2058
+
2059
+ .collapse-toggle, .icon-btn {
2060
+ display: inline-flex; align-items: center; justify-content: center;
2061
+ width: 32px; height: 32px; border-radius: var(--radius-md);
2062
+ background: none; border: none; color: var(--text-secondary);
2063
+ cursor: pointer; transition: all var(--duration-fast) var(--easing-out);
2064
+ }
2065
+ .collapse-toggle svg, .icon-btn svg { width: 18px; height: 18px; }
2066
+ .collapse-toggle:hover, .icon-btn:hover { background: var(--surface-inset); color: var(--text-primary); }
2067
+
2068
+ /* Breadcrumb */
2069
+ .breadcrumb { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
2070
+ .breadcrumb-segment { color: var(--text-secondary); display: flex; align-items: center; }
2071
+ .breadcrumb-separator { color: var(--text-disabled); }
2072
+ .breadcrumb-current { color: var(--text-primary); font-weight: var(--font-medium); }
2073
+
2074
+ /* User avatar & dropdown */
2075
+ .user-avatar {
2076
+ width: 32px; height: 32px; border-radius: var(--radius-full);
2077
+ background: var(--primary-100); color: var(--primary-700);
2078
+ display: flex; align-items: center; justify-content: center;
2079
+ font-size: var(--text-xs); font-weight: var(--font-semibold);
2080
+ }
2081
+
2082
+ .user-dropdown {
2083
+ position: absolute; right: 0; top: calc(100% + 4px);
2084
+ min-width: 200px; background: var(--surface-raised);
2085
+ border: 1px solid var(--surface-border); border-radius: var(--radius-lg);
2086
+ box-shadow: var(--shadow-lg); z-index: 50; padding: var(--space-1) 0;
2087
+ }
2088
+ .user-dropdown-header { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--surface-border); }
2089
+ .user-dropdown-name { font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--text-primary); }
2090
+ .user-dropdown-email { font-size: var(--text-xs); color: var(--text-secondary); margin-top: 2px; }
2091
+ .user-dropdown-item {
2092
+ display: block; width: 100%; text-align: left; padding: var(--space-2) var(--space-4);
2093
+ font-size: var(--text-sm); color: var(--text-secondary); background: none; border: none;
2094
+ cursor: pointer; transition: all var(--duration-fast);
2095
+ }
2096
+ .user-dropdown-item:hover { background: var(--surface-inset); color: var(--text-primary); }
2097
+ .user-dropdown-item.danger { color: var(--danger-500); }
2098
+ .user-dropdown-item.danger:hover { background: var(--danger-50); }
2099
+
2100
+ /* ═══════════════════════════════════════════════════════════════════════════
2101
+ SIDEBAR — inner structure
2102
+ ═══════════════════════════════════════════════════════════════════════════ */
2103
+
2104
+ .sidebar-nav { flex: 1; overflow-y: auto; padding: var(--space-3); text-align: left; }
2105
+ .sidebar-nav-list { list-style: none; margin: 0; padding: 0; text-align: left; }
2106
+ .sidebar-nav-item { margin-bottom: 2px; text-align: left; }
2107
+
2108
+ .sidebar-section { padding: var(--space-4) 0 var(--space-2); text-align: left; }
2109
+ .sidebar-section-label {
2110
+ font-size: var(--text-2xs); font-weight: var(--font-medium);
2111
+ text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-disabled);
2112
+ text-align: left;
2113
+ }
2114
+
2115
+ .sidebar-section-toggle {
2116
+ display: flex; align-items: center; justify-content: space-between;
2117
+ width: 100%; padding: 0; margin: 0; background: none; border: none;
2118
+ cursor: pointer; color: inherit; text-align: left;
2119
+ }
2120
+ .sidebar-section-toggle:hover { color: var(--text-secondary); }
2121
+ .sidebar-section-toggle .sidebar-section-label { flex: 1; }
2122
+
2123
+ .sidebar-section-chevron {
2124
+ transition: transform 0.2s ease; color: var(--text-disabled); flex-shrink: 0;
2125
+ }
2126
+ .sidebar-section-chevron.collapsed { transform: rotate(0deg); }
2127
+ .sidebar-section-chevron:not(.collapsed) { transform: rotate(90deg); }
2128
+
2129
+ .sidebar-section-items { list-style: none; margin: 0; padding: 0; text-align: left; }
2130
+
2131
+ .sidebar-bottom { border-top: 1px solid var(--surface-border); padding: var(--space-3); flex-shrink: 0; text-align: left; }
2132
+
2133
+ .nav-link-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2134
+ .nav-link--no-icon .nav-link-label { padding-left: 0; }
2135
+ .nav-link--no-icon { gap: 0; }
2136
+ .nav-link-badge {
2137
+ margin-left: auto; font-family: var(--font-mono); font-size: var(--text-2xs);
2138
+ padding: 1px 6px; background: var(--surface-inset); color: var(--text-secondary);
2139
+ border-radius: var(--radius-full); border: 1px solid var(--surface-border);
2140
+ }
2141
+ .nav-tooltip {
2142
+ display: none; position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%);
2143
+ background: var(--surface-raised); border: 1px solid var(--surface-border); border-radius: var(--radius-md);
2144
+ padding: var(--space-1) var(--space-3); font-size: var(--text-xs); white-space: nowrap;
2145
+ box-shadow: var(--shadow-md); z-index: 50; color: var(--text-primary);
2146
+ }
2147
+ .sidebar.collapsed .nav-tooltip { display: block; }
2148
+
2149
+ .admin-sidebar-overlay {
2150
+ display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: 35;
2151
+ }
2152
+ .admin-sidebar-overlay.open { display: block; }
2153
+
2154
+ /* ═══════════════════════════════════════════════════════════════════════════
2155
+ PAGE HEADER
2156
+ ═══════════════════════════════════════════════════════════════════════════ */
2157
+
2158
+ .page-header {
2159
+ display: flex; align-items: flex-start; justify-content: space-between;
2160
+ gap: var(--space-4); margin-bottom: var(--space-6);
2161
+ }
2162
+ .page-header-left { display: flex; flex-direction: column; gap: var(--space-1); }
2163
+ .page-header-right { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
2164
+ .page-header-title {
2165
+ font-family: var(--font-display); font-size: var(--text-2xl);
2166
+ color: var(--text-primary); margin: 0; line-height: 1.2;
2167
+ }
2168
+ .page-header-subtitle { font-size: var(--text-sm); color: var(--text-secondary); margin: 0; }
2169
+ .page-header-back {
2170
+ display: inline-flex; align-items: center; gap: var(--space-1);
2171
+ font-size: var(--text-sm); color: var(--text-secondary); text-decoration: none;
2172
+ margin-bottom: var(--space-1);
2173
+ }
2174
+ .page-header-back:hover { color: var(--primary-500); }
2175
+
2176
+ /* ═══════════════════════════════════════════════════════════════════════════
2177
+ BUTTONS
2178
+ ═══════════════════════════════════════════════════════════════════════════ */
2179
+
2180
+ .btn {
2181
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
2182
+ padding: var(--space-2) var(--space-4); font-size: var(--text-sm); font-weight: var(--font-medium);
2183
+ border-radius: var(--radius-lg); border: 1px solid transparent;
2184
+ cursor: pointer; transition: all var(--duration-fast) var(--easing-out);
2185
+ text-decoration: none; white-space: nowrap; line-height: 1.5;
2186
+ }
2187
+ .btn-primary { background: var(--primary-500); color: var(--text-inverse); border-color: var(--primary-500); }
2188
+ .btn-primary:hover { background: var(--primary-600); }
2189
+ .btn-secondary { background: var(--surface-raised); color: var(--text-primary); border-color: var(--surface-border); }
2190
+ .btn-secondary:hover { background: var(--surface-inset); }
2191
+ .btn-ghost { background: none; color: var(--text-secondary); }
2192
+ .btn-ghost:hover { background: var(--surface-inset); color: var(--text-primary); }
2193
+ .btn-danger { background: var(--danger-500); color: white; border-color: var(--danger-500); }
2194
+ .btn-danger:hover { background: var(--danger-700); }
2195
+ .btn-sm { padding: var(--space-1) var(--space-3); font-size: var(--text-xs); }
2196
+
2197
+ /* ═══════════════════════════════════════════════════════════════════════════
2198
+ BADGES
2199
+ ═══════════════════════════════════════════════════════════════════════════ */
2200
+
2201
+ .badge {
2202
+ display: inline-flex; align-items: center; gap: var(--space-1);
2203
+ padding: 2px var(--space-3); font-size: var(--text-xs); font-weight: var(--font-medium);
2204
+ border-radius: var(--radius-full); line-height: 1.5;
2205
+ }
2206
+ .badge-success { background: var(--success-50); color: var(--success-700); }
2207
+ .badge-warning { background: var(--warning-50); color: var(--warning-700); }
2208
+ .badge-danger { background: var(--danger-50); color: var(--danger-700); }
2209
+ .badge-info { background: var(--info-50); color: var(--info-700); }
2210
+
2211
+ /* ═══════════════════════════════════════════════════════════════════════════
2212
+ STAT CARDS (dashboard)
2213
+ ═══════════════════════════════════════════════════════════════════════════ */
2214
+
2215
+ .stat-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-4); }
2216
+ .stat-card {
2217
+ display: flex; flex-direction: column; gap: var(--space-1);
2218
+ padding: var(--space-5); background: var(--surface-raised);
2219
+ border: 1px solid var(--surface-border); border-radius: var(--radius-lg);
2220
+ text-decoration: none; transition: all var(--duration-fast) var(--easing-out);
2221
+ }
2222
+ .stat-card:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
2223
+ .stat-card--outlined { background: transparent; border: 2px solid var(--surface-border); }
2224
+ .stat-card--flat { box-shadow: none; border: none; background: var(--surface-inset); }
2225
+ .stat-card--small .stat-card__value { font-size: var(--text-xl); }
2226
+ .stat-card--large .stat-card__value { font-size: 3.5rem; }
2227
+ .stat-card__label { font-size: var(--text-sm); color: var(--text-secondary); }
2228
+ .stat-card__value { font-family: var(--font-display); font-size: var(--text-3xl); color: var(--text-primary); }
2229
+
2230
+ /* ═══════════════════════════════════════════════════════════════════════════
2231
+ FILTER BAR
2232
+ ═══════════════════════════════════════════════════════════════════════════ */
2233
+
2234
+ .filter-bar {
2235
+ display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
2236
+ padding: var(--space-3) var(--space-4); background: var(--surface-raised);
2237
+ border: 1px solid var(--surface-border); border-radius: var(--radius-lg);
2238
+ }
2239
+ .filter-bar-search { position: relative; flex: 1; min-width: 200px; }
2240
+ .filter-bar-search-icon {
2241
+ position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%);
2242
+ width: 16px; height: 16px; color: var(--text-disabled); pointer-events: none;
2243
+ }
2244
+ .filter-bar-search-input {
2245
+ width: 100%; padding: var(--space-2) var(--space-3) var(--space-2) var(--space-10);
2246
+ border: 1px solid var(--surface-border); border-radius: var(--radius-md);
2247
+ background: var(--surface-base); font-size: var(--text-sm); color: var(--text-primary);
2248
+ outline: none; transition: border-color var(--duration-fast);
2249
+ }
2250
+ .filter-bar-search-input:focus { border-color: var(--primary-500); box-shadow: var(--shadow-focus); }
2251
+ .filter-bar-clear {
2252
+ position: absolute; right: var(--space-2); top: 50%; transform: translateY(-50%);
2253
+ background: none; border: none; cursor: pointer; color: var(--text-disabled); padding: var(--space-1);
2254
+ }
2255
+ .filter-bar-chips { display: flex; gap: var(--space-2); flex-wrap: wrap; }
2256
+ .filter-bar-right { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
2257
+ .filter-bar-action {
2258
+ display: inline-flex; align-items: center; justify-content: center;
2259
+ width: 32px; height: 32px; border-radius: var(--radius-md); background: none;
2260
+ border: 1px solid var(--surface-border); cursor: pointer; color: var(--text-secondary);
2261
+ }
2262
+ .filter-bar-action:hover { background: var(--surface-inset); }
2263
+ .filter-bar-clear-all { font-size: var(--text-xs); color: var(--text-secondary); background: none; border: none; cursor: pointer; }
2264
+ .filter-bar-clear-all:hover { color: var(--danger-500); }
2265
+ .filter-bar-divider { width: 1px; height: 20px; background: var(--surface-border); }
2266
+
2267
+ .filter-chip {
2268
+ display: inline-flex; align-items: center; gap: var(--space-1);
2269
+ padding: var(--space-1) var(--space-3); font-size: var(--text-xs);
2270
+ border: 1px solid var(--surface-border); border-radius: var(--radius-full);
2271
+ background: var(--surface-raised); color: var(--text-secondary); cursor: pointer;
2272
+ }
2273
+ .filter-chip:hover, .filter-chip.active { border-color: var(--primary-500); color: var(--primary-500); }
2274
+ .filter-chip-count {
2275
+ display: inline-flex; align-items: center; justify-content: center;
2276
+ width: 16px; height: 16px; border-radius: var(--radius-full);
2277
+ background: var(--primary-500); color: white; font-size: 10px;
2278
+ }
2279
+ .filter-chip-wrap { display: flex; align-items: center; gap: var(--space-2); }
2280
+ .filter-chip-label { font-size: var(--text-xs); color: var(--text-secondary); }
2281
+ .filter-chip--active .filter-chip-label { color: var(--primary-500); font-weight: var(--font-medium); }
2282
+
2283
+ .filter-dropdown {
2284
+ position: absolute; top: calc(100% + 4px); left: 0; min-width: 200px;
2285
+ background: var(--surface-raised); border: 1px solid var(--surface-border);
2286
+ border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); z-index: 50;
2287
+ padding: var(--space-2) 0;
2288
+ }
2289
+ .filter-dropdown-header {
2290
+ display: flex; align-items: center; justify-content: space-between;
2291
+ padding: var(--space-2) var(--space-3); font-size: var(--text-xs); font-weight: var(--font-medium);
2292
+ }
2293
+ .filter-dropdown-clear { font-size: var(--text-xs); color: var(--primary-500); background: none; border: none; cursor: pointer; }
2294
+ .filter-dropdown-item {
2295
+ display: flex; align-items: center; gap: var(--space-2);
2296
+ padding: var(--space-2) var(--space-3); font-size: var(--text-sm); cursor: pointer;
2297
+ }
2298
+ .filter-dropdown-item:hover { background: var(--surface-inset); }
2299
+ .filter-dropdown-item input[type="radio"] { accent-color: var(--primary-500); }
2300
+ .filter-clear-btn {
2301
+ background: none; border: none; color: var(--text-disabled); cursor: pointer; font-size: var(--text-lg);
2302
+ }
2303
+ .filter-clear-btn:hover { color: var(--danger-500); }
2304
+ .filter-input-date, .filter-input-datetime, .filter-input-time {
2305
+ padding: var(--space-1) var(--space-2); border: 1px solid var(--surface-border);
2306
+ border-radius: var(--radius-md); font-size: var(--text-xs); background: var(--surface-base);
2307
+ }
2308
+
2309
+ /* ═══════════════════════════════════════════════════════════════════════════
2310
+ TABLE
2311
+ ═══════════════════════════════════════════════════════════════════════════ */
2312
+
2313
+ .table-wrapper { background: var(--surface-raised); border: 1px solid var(--surface-border); border-radius: var(--radius-lg); overflow: hidden; }
2314
+ .table-wrapper table { width: 100%; border-collapse: collapse; }
2315
+ .table-wrapper table { border-collapse: collapse; }
2316
+ .table-wrapper th { font-size: var(--text-xs); font-weight: var(--font-medium); color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; }
2317
+ .table-wrapper td, .table-wrapper th { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--surface-border); }
2318
+ .table-wrapper tbody tr:hover { background: var(--surface-inset); }
2319
+
2320
+ .table-sort-btn { display: flex; align-items: center; gap: var(--space-1); color: inherit; text-decoration: none; }
2321
+ .table-sort-btn:hover { color: var(--primary-500); }
2322
+ .table-sort-btn.active { color: var(--primary-500); font-weight: var(--font-medium); }
2323
+
2324
+ /* List footer — bulk actions + pagination */
2325
+ .list-footer {
2326
+ display: flex;
2327
+ align-items: center;
2328
+ justify-content: space-between;
2329
+ padding: var(--space-3) var(--space-4);
2330
+ border-top: 1px solid var(--surface-border);
2331
+ flex-wrap: wrap;
2332
+ gap: var(--space-3);
2333
+ }
2334
+ .list-footer-left {
2335
+ display: flex;
2336
+ align-items: center;
2337
+ gap: var(--space-3);
2338
+ }
2339
+ .btn-danger-outline {
2340
+ background: var(--surface-raised);
2341
+ color: var(--danger-500);
2342
+ border: 1px solid var(--danger-500);
2343
+ }
2344
+ .btn-danger-outline:hover {
2345
+ background: var(--danger-50);
2346
+ }
2347
+ [data-theme="dark"] .btn-danger-outline {
2348
+ border-color: var(--danger-700);
2349
+ }
2350
+ [data-theme="dark"] .btn-danger-outline:hover {
2351
+ background: rgba(248, 113, 113, 0.1);
2352
+ }
2353
+
2354
+ /* ═══════════════════════════════════════════════════════════════════════════
2355
+ FORM ELEMENTS
2356
+ ═══════════════════════════════════════════════════════════════════════════ */
2357
+
2358
+ .form-input, .form-select {
2359
+ width: 100%; padding: var(--space-2) var(--space-3);
2360
+ border: 1px solid var(--surface-border); border-radius: var(--radius-md);
2361
+ background: var(--surface-raised); font-size: var(--text-sm); color: var(--text-primary);
2362
+ outline: none; transition: all var(--duration-fast);
2363
+ }
2364
+ .form-input:focus, .form-select:focus { border-color: var(--primary-500); box-shadow: var(--shadow-focus); }
2365
+ .form-input[readonly] { background: var(--surface-inset); color: var(--text-secondary); cursor: not-allowed; }
2366
+
2367
+ .field-wrapper { margin-bottom: var(--space-4); }
2368
+ .field-label { display: block; font-size: var(--text-sm); font-weight: var(--font-medium); color: var(--text-primary); margin-bottom: var(--space-1); }
2369
+ .required-star { color: var(--danger-500); margin-left: 2px; }
2370
+ .field-errors { margin-top: var(--space-1); }
2371
+ .field-errors li { font-size: var(--text-xs); color: var(--danger-500); }
2372
+ .field-help { font-size: var(--text-xs); color: var(--text-secondary); margin-top: var(--space-1); }
2373
+ .has-error .form-input, .has-error .form-select { border-color: var(--danger-500); }
2374
+
2375
+ /* Toggle switch */
2376
+ .toggle-switch {
2377
+ display: inline-flex; align-items: center; width: 40px; height: 22px;
2378
+ border-radius: var(--radius-full); cursor: pointer; position: relative;
2379
+ transition: background var(--duration-fast); border: none; padding: 0;
2380
+ background: var(--surface-border);
2381
+ }
2382
+ .toggle-switch--on { background: var(--primary-500); }
2383
+ .toggle-switch__thumb {
2384
+ position: absolute; top: 2px; left: 2px; width: 18px; height: 18px;
2385
+ border-radius: var(--radius-full); background: white;
2386
+ transition: transform var(--duration-fast) var(--easing-out);
2387
+ box-shadow: var(--shadow-sm);
2388
+ }
2389
+ .toggle-switch--on .toggle-switch__thumb { transform: translateX(18px); }
2390
+
2391
+ /* ═══════════════════════════════════════════════════════════════════════════
2392
+ TOAST NOTIFICATIONS
2393
+ ═══════════════════════════════════════════════════════════════════════════ */
2394
+
2395
+ .toast { border-radius: var(--radius-lg); }
2396
+ .toast-success { border-left: 4px solid var(--success-500); }
2397
+ .toast-error { border-left: 4px solid var(--danger-500); }
2398
+ .toast-warning { border-left: 4px solid var(--warning-500); }
2399
+ .toast-info { border-left: 4px solid var(--info-500); }
2400
+
2401
+ /* ═══════════════════════════════════════════════════════════════════════════
2402
+ UTILITY CLASSES (Tailwind-like)
2403
+ ═══════════════════════════════════════════════════════════════════════════ */
2404
+
2405
+ .flex { display: flex; }
2406
+ .flex-col { flex-direction: column; }
2407
+ .flex-wrap { flex-wrap: wrap; }
2408
+ .flex-1 { flex: 1 1 0%; }
2409
+ .shrink-0 { flex-shrink: 0; }
2410
+ .items-center { align-items: center; }
2411
+ .items-start { align-items: flex-start; }
2412
+ .items-end { align-items: flex-end; }
2413
+ .justify-between { justify-content: space-between; }
2414
+ .justify-end { justify-content: flex-end; }
2415
+ .justify-center { justify-content: center; }
2416
+
2417
+ .gap-1 { gap: var(--space-1); }
2418
+ .gap-2 { gap: var(--space-2); }
2419
+ .gap-3 { gap: var(--space-3); }
2420
+ .gap-4 { gap: var(--space-4); }
2421
+ .gap-6 { gap: var(--space-6); }
2422
+
2423
+ .space-x-2 > * + * { margin-left: var(--space-2); }
2424
+ .space-y-2 > * + * { margin-top: var(--space-2); }
2425
+ .space-y-3 > * + * { margin-top: var(--space-3); }
2426
+ .space-y-6 > * + * { margin-top: var(--space-6); }
2427
+
2428
+ .mt-1 { margin-top: var(--space-1); }
2429
+ .mt-2 { margin-top: var(--space-2); }
2430
+ .mt-4 { margin-top: var(--space-4); }
2431
+ .mt-6 { margin-top: var(--space-6); }
2432
+ .mb-1 { margin-bottom: var(--space-1); }
2433
+ .mb-2 { margin-bottom: var(--space-2); }
2434
+ .mb-3 { margin-bottom: var(--space-3); }
2435
+ .mb-4 { margin-bottom: var(--space-4); }
2436
+ .mb-6 { margin-bottom: var(--space-6); }
2437
+ .mb-8 { margin-bottom: var(--space-8); }
2438
+ .ml-2 { margin-left: var(--space-2); }
2439
+ .ml-auto { margin-left: auto; }
2440
+
2441
+ .p-2 { padding: var(--space-2); }
2442
+ .p-3 { padding: var(--space-3); }
2443
+ .p-4 { padding: var(--space-4); }
2444
+ .p-6 { padding: var(--space-6); }
2445
+ .p-8 { padding: var(--space-8); }
2446
+ .px-2 { padding-left: var(--space-2); padding-right: var(--space-2); }
2447
+ .px-3 { padding-left: var(--space-3); padding-right: var(--space-3); }
2448
+ .px-4 { padding-left: var(--space-4); padding-right: var(--space-4); }
2449
+ .px-6 { padding-left: var(--space-6); padding-right: var(--space-6); }
2450
+ .py-1 { padding-top: var(--space-1); padding-bottom: var(--space-1); }
2451
+ .py-2 { padding-top: var(--space-2); padding-bottom: var(--space-2); }
2452
+ .py-3 { padding-top: var(--space-3); padding-bottom: var(--space-3); }
2453
+ .py-4 { padding-top: var(--space-4); padding-bottom: var(--space-4); }
2454
+ .py-12 { padding-top: var(--space-12); padding-bottom: var(--space-12); }
2455
+
2456
+ .w-full { width: 100%; }
2457
+ .w-3 { width: var(--space-3); }
2458
+ .w-4 { width: 1rem; }
2459
+ .w-5 { width: 1.25rem; }
2460
+ .w-11 { width: 2.75rem; }
2461
+ .w-14 { width: 3.5rem; }
2462
+ .w-16 { width: 4rem; }
2463
+ .w-32 { width: 8rem; }
2464
+ .w-48 { width: 12rem; }
2465
+ .max-w-sm { max-width: 24rem; }
2466
+ .max-w-md { max-width: 28rem; }
2467
+ .min-w-0 { min-width: 0; }
2468
+
2469
+ .h-3 { height: var(--space-3); }
2470
+ .h-4 { height: 1rem; }
2471
+ .h-5 { height: 1.25rem; }
2472
+ .h-6 { height: 1.5rem; }
2473
+ .h-10 { height: 2.5rem; }
2474
+ .h-12 { height: 3rem; }
2475
+ .h-16 { height: 4rem; }
2476
+ .h-32 { height: 8rem; }
2477
+ .min-h-200px { min-height: 200px; }
2478
+
2479
+ .text-center { text-align: center; }
2480
+ .text-right { text-align: right; }
2481
+ .text-left { text-align: left; }
2482
+ .inline { display: inline; }
2483
+ .inline-flex { display: inline-flex; }
2484
+ .inline-block { display: inline-block; }
2485
+ .block { display: block; }
2486
+ .hidden { display: none; }
2487
+ .relative { position: relative; }
2488
+ .absolute { position: absolute; }
2489
+ .fixed { position: fixed; }
2490
+ .sticky { position: sticky; }
2491
+ .inset-0 { inset: 0; }
2492
+ .left-0 { left: 0; }
2493
+ .right-0 { right: 0; }
2494
+ .top-0 { top: 0; }
2495
+ .top-4 { top: var(--space-4); }
2496
+ .bottom-0 { bottom: 0; }
2497
+ .z-10 { z-index: 10; }
2498
+ .z-50 { z-index: 50; }
2499
+ .pointer-events-none { pointer-events: none; }
2500
+
2501
+ .grid { display: grid; }
2502
+ .grid-cols-1 { grid-template-columns: repeat(1, 1fr); }
2503
+ .grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
2504
+ .grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
2505
+ .col-span-2 { grid-column: span 2; }
2506
+ .col-span-3 { grid-column: span 3; }
2507
+
2508
+ .overflow-hidden { overflow: hidden; }
2509
+ .overflow-auto { overflow: auto; }
2510
+ .overflow-x-auto { overflow-x: auto; }
2511
+ .break-all { word-break: break-all; }
2512
+ .whitespace-nowrap { white-space: nowrap; }
2513
+ .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2514
+ .object-cover { object-fit: cover; }
2515
+ .select-none { user-select: none; }
2516
+ .cursor-pointer { cursor: pointer; }
2517
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
2518
+
2519
+ .font-sans { font-family: var(--font-body); }
2520
+ .font-mono { font-family: var(--font-mono); }
2521
+ .font-display { font-family: var(--font-display); }
2522
+ .font-normal { font-weight: var(--font-normal); }
2523
+ .font-medium { font-weight: var(--font-medium); }
2524
+ .font-semibold { font-weight: var(--font-semibold); }
2525
+ .font-bold { font-weight: 700; }
2526
+ .uppercase { text-transform: uppercase; }
2527
+ .tracking-wider { letter-spacing: 0.05em; }
2528
+ .antialiased { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
2529
+
2530
+ .text-xs { font-size: var(--text-xs); }
2531
+ .text-sm { font-size: var(--text-sm); }
2532
+ .text-base { font-size: var(--text-base); }
2533
+ .text-lg { font-size: var(--text-lg); }
2534
+ .text-xl { font-size: var(--text-xl); }
2535
+ .text-2xl { font-size: var(--text-2xl); }
2536
+ .text-secondary { color: var(--text-secondary); }
2537
+ .text-primary-color { color: var(--primary-500); }
2538
+ .mono { font-family: var(--font-mono); }
2539
+
2540
+ .rounded { border-radius: var(--radius-sm); }
2541
+ .rounded-lg { border-radius: var(--radius-lg); }
2542
+ .rounded-xl { border-radius: calc(var(--radius-lg) + 4px); }
2543
+ .rounded-full { border-radius: var(--radius-full); }
2544
+
2545
+ .bg-white { background: var(--surface-raised); }
2546
+ .bg-red-50 { background: var(--danger-50); }
2547
+ .bg-green-50 { background: var(--success-50); }
2548
+ .bg-yellow-50 { background: var(--warning-50); }
2549
+ .bg-blue-50 { background: var(--info-50); }
2550
+ .bg-green-100 { background: #dcfce7; }
2551
+ .bg-yellow-100 { background: #fef9c3; }
2552
+ .bg-red-100 { background: #fee2e2; }
2553
+ .bg-gray-100 { background: var(--surface-inset); }
2554
+
2555
+ .text-red-700 { color: var(--danger-700); }
2556
+ .text-green-700 { color: #15803d; }
2557
+ .text-green-800 { color: #166534; }
2558
+ .text-yellow-700 { color: #b45309; }
2559
+ .text-yellow-800 { color: #92400e; }
2560
+ .text-blue-700 { color: var(--info-700); }
2561
+ .text-gray-400 { color: var(--text-disabled); }
2562
+ .text-gray-500 { color: var(--text-secondary); }
2563
+ .text-gray-600 { color: #4b5563; }
2564
+ .text-gray-700 { color: #374151; }
2565
+ .text-gray-900 { color: var(--text-primary); }
2566
+
2567
+ .border { border: 1px solid var(--surface-border); }
2568
+ .border-red-200 { border-color: #fecaca; }
2569
+ .border-green-200 { border-color: #bbf7d0; }
2570
+ .border-yellow-200 { border-color: #fde68a; }
2571
+ .border-blue-200 { border-color: #bfdbfe; }
2572
+ .border-gray-200 { border-color: var(--surface-border); }
2573
+ .border-gray-300 { border-color: #d1d5db; }
2574
+
2575
+ [data-theme="dark"] .border-red-200 { border-color: var(--danger-500); }
2576
+ [data-theme="dark"] .border-green-200 { border-color: var(--success-500); }
2577
+ [data-theme="dark"] .border-yellow-200 { border-color: var(--warning-500); }
2578
+ [data-theme="dark"] .border-blue-200 { border-color: var(--info-500); }
2579
+ [data-theme="dark"] .border-gray-300 { border-color: var(--surface-border); }
2580
+ [data-theme="dark"] .text-green-700 { color: var(--success-700); }
2581
+ [data-theme="dark"] .text-green-800 { color: var(--success-700); }
2582
+ [data-theme="dark"] .text-yellow-700 { color: var(--warning-700); }
2583
+ [data-theme="dark"] .text-yellow-800 { color: var(--warning-700); }
2584
+ [data-theme="dark"] .text-gray-600 { color: var(--text-secondary); }
2585
+ [data-theme="dark"] .text-gray-700 { color: var(--text-secondary); }
2586
+ [data-theme="dark"] .bg-green-100 { background: var(--success-50); }
2587
+ [data-theme="dark"] .bg-yellow-100 { background: var(--warning-50); }
2588
+ [data-theme="dark"] .bg-red-100 { background: var(--danger-50); }
2589
+
2590
+ .divide-y > * + * { border-top: 1px solid var(--surface-border); }
2591
+
2592
+ .transition-colors { transition: color var(--duration-fast), background-color var(--duration-fast), border-color var(--duration-fast); }
2593
+ .transition-transform { transition: transform var(--duration-fast); }
2594
+ .transition-ease-out { transition-timing-function: var(--easing-out); }
2595
+ .duration-100 { transition-duration: var(--duration-fast); }
2596
+ .duration-200 { transition-duration: var(--duration-base); }
2597
+ .duration-300 { transition-duration: var(--duration-slow); }
2598
+ .ease-out { transition-timing-function: var(--easing-out); }
2599
+ .ease-in { transition-timing-function: var(--easing-in); }
2600
+
2601
+ .rotate-90 { transform: rotate(90deg); }
2602
+ .rotate-180 { transform: rotate(180deg); }
2603
+ .-rotate-90 { transform: rotate(-90deg); }
2604
+ .translate-y-2 { transform: translateY(var(--space-2)); }
2605
+ .-translate-y-1\\/2 { transform: translateY(-50%); }
2606
+ .translate-x-1 { transform: translateX(var(--space-1)); }
2607
+ .translate-x-6 { transform: translateX(1.5rem); }
2608
+
2609
+ .hover\\:bg-gray-50:hover, [class*="hover:bg-"][class*="gray-50"]:hover { background: var(--surface-inset); }
2610
+ .hover\\:text-primary-600:hover, [class*="hover:text-primary-600"]:hover { color: var(--primary-600); }
2611
+ .hover\\:underline:hover { text-decoration: underline; }
2612
+
2613
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
2614
+
2615
+ /* ═══════════════════════════════════════════════════════════════════════════
2616
+ LOGIN PAGE
2617
+ ═══════════════════════════════════════════════════════════════════════════ */
2618
+
2619
+ .login-page {
2620
+ min-height: 100vh;
2621
+ display: flex;
2622
+ align-items: center;
2623
+ justify-content: center;
2624
+ background: var(--surface-base);
2625
+ padding: var(--space-4);
2626
+ }
2627
+
2628
+ .login-card {
2629
+ width: 100%;
2630
+ max-width: 400px;
2631
+ background: var(--surface-raised);
2632
+ border: 1px solid var(--surface-border);
2633
+ border-radius: var(--radius-lg);
2634
+ padding: var(--space-8);
2635
+ box-shadow: var(--shadow-md);
2636
+ }
2637
+
2638
+ .login-card__logo {
2639
+ text-align: center;
2640
+ margin-bottom: var(--space-6);
2641
+ }
2642
+
2643
+ .login-card__title {
2644
+ font-family: var(--font-display);
2645
+ font-size: var(--text-xl);
2646
+ color: var(--text-primary);
2647
+ margin: 0 0 var(--space-6);
2648
+ text-align: center;
2649
+ }
2650
+
2651
+ .login-card__error {
2652
+ background: var(--danger-50);
2653
+ border: 1px solid var(--danger-500);
2654
+ border-radius: var(--radius-md);
2655
+ padding: var(--space-3) var(--space-4);
2656
+ margin-bottom: var(--space-4);
2657
+ font-size: var(--text-sm);
2658
+ color: var(--danger-700);
2659
+ }
2660
+
2661
+ /* ═══════════════════════════════════════════════════════════════════════════
2662
+ SKELETON LOADING
2663
+ ═══════════════════════════════════════════════════════════════════════════ */
2664
+
2665
+ .skeleton {
2666
+ background: var(--surface-inset);
2667
+ border-radius: var(--radius-sm);
2668
+ position: relative;
2669
+ overflow: hidden;
2670
+ }
2671
+
2672
+ .skeleton::after {
2673
+ content: '';
2674
+ position: absolute;
2675
+ inset: 0;
2676
+ background: linear-gradient(
2677
+ 90deg,
2678
+ transparent,
2679
+ rgba(255, 255, 255, 0.15),
2680
+ transparent
2681
+ );
2682
+ animation: skeleton-shimmer 1.5s infinite;
2683
+ }
2684
+
2685
+ [data-theme="dark"] .skeleton::after {
2686
+ background: linear-gradient(
2687
+ 90deg,
2688
+ transparent,
2689
+ rgba(255, 255, 255, 0.04),
2690
+ transparent
2691
+ );
2692
+ }
2693
+
2694
+ @keyframes skeleton-shimmer {
2695
+ 0% { transform: translateX(-100%); }
2696
+ 100% { transform: translateX(100%); }
2697
+ }
2698
+
2699
+ .skeleton-text {
2700
+ height: 14px;
2701
+ margin-bottom: 8px;
2702
+ }
2703
+
2704
+ .skeleton-text:last-child {
2705
+ width: 60%;
2706
+ }
2707
+
2708
+ /* ═══════════════════════════════════════════════════════════════════════════
2709
+ COMPONENT STYLE VARIANTS
2710
+ ═══════════════════════════════════════════════════════════════════════════ */
2711
+
2712
+ /* Table style variants */
2713
+ .table--striped tbody tr:nth-child(even) { background: var(--surface-inset); }
2714
+ .table--bordered { border: 1px solid var(--surface-border); }
2715
+ .table--bordered td, .table--bordered th { border: 1px solid var(--surface-border); }
2716
+ .table--compact th, .table--compact td { padding: var(--space-2) var(--space-3); font-size: var(--text-xs); }
2717
+ .table--relaxed th, .table--relaxed td { padding: var(--space-4) var(--space-5); }
2718
+
2719
+ /* Form layout variants */
2720
+ .form--one-column .fieldset__fields { grid-template-columns: 1fr; }
2721
+ .form--compact .field-wrapper { gap: 4px; }
2722
+ .form--relaxed .field-wrapper { gap: 12px; }
2723
+
2724
+ /* Sidebar style variants */
2725
+ .sidebar--compact .nav-link { padding: var(--space-1) 0; font-size: var(--text-xs); }
2726
+ .sidebar--minimal .nav-link__label { display: none; }
2727
+ .sidebar--minimal .nav-link { justify-content: center; padding: var(--space-2); }
2728
+
2729
+ /* Dashboard grid variants */
2730
+ .dashboard--2col .stat-cards { grid-template-columns: repeat(2, 1fr); }
2731
+ .dashboard--3col .stat-cards { grid-template-columns: repeat(3, 1fr); }
2732
+ .dashboard--4col .stat-cards { grid-template-columns: repeat(4, 1fr); }
2733
+ .stat-card--outlined { background: transparent; border: 2px solid var(--surface-border); }
2734
+ .stat-card--flat { box-shadow: none; border: none; background: var(--surface-inset); }
2735
+ .stat-card--small .stat-card__value { font-size: var(--text-xl); }
2736
+ .stat-card--large .stat-card__value { font-size: 3.5rem; }
2737
+
2738
+ /* Topbar style variants */
2739
+ .topbar--minimal { border-bottom: none; }
2740
+ .topbar--minimal::after { display: none; }
2741
+ .topbar--transparent { background: transparent; border-bottom: none; }
2742
+ .topbar--transparent::after { display: none; }
2743
+
2744
+ /* Content width variants */
2745
+ .content--narrow .admin-content__inner { max-width: 800px; }
2746
+ .content--wide .admin-content__inner { max-width: 1600px; }
2747
+ .content--full .admin-content__inner { max-width: none; }
2748
+
2749
+ /* Sidebar position */
2750
+ .sidebar--right .admin-body { flex-direction: row-reverse; }
2751
+ .sidebar--right .admin-sidebar { border-right: none; border-left: 1px solid var(--surface-border); }
2752
+
2753
+ /* ═══════════════════════════════════════════════════════════════════════════
2754
+ RESPONSIVE
2755
+ ═══════════════════════════════════════════════════════════════════════════ */
2756
+
2757
+ @media (max-width: 1024px) {
2758
+ .admin-sidebar {
2759
+ width: var(--admin-sidebar-width, var(--sidebar-width));
2760
+ position: fixed;
2761
+ left: 0;
2762
+ top: 0;
2763
+ height: 100vh;
2764
+ z-index: 40;
2765
+ transform: translateX(-100%);
2766
+ transition: transform var(--duration-slow) var(--easing-out);
2767
+ }
2768
+
2769
+ .admin-sidebar.open {
2770
+ transform: translateX(0);
2771
+ }
2772
+
2773
+ .sidebar-backdrop {
2774
+ position: fixed;
2775
+ inset: 0;
2776
+ background: rgba(20, 18, 16, 0.5);
2777
+ z-index: 35;
2778
+ }
2779
+
2780
+ .admin-content__inner {
2781
+ padding: var(--space-5) var(--space-4);
2782
+ }
2783
+
2784
+ .page-header__title {
2785
+ font-size: var(--text-xl);
2786
+ }
2787
+ }
2788
+
2789
+ @media (max-width: 768px) {
2790
+ .page-header {
2791
+ flex-direction: column;
2792
+ gap: var(--space-3);
2793
+ }
2794
+
2795
+ .stat-cards {
2796
+ grid-template-columns: repeat(2, 1fr);
2797
+ }
2798
+
2799
+ .fieldset__fields {
2800
+ grid-template-columns: 1fr;
2801
+ }
2802
+
2803
+ .filter-bar {
2804
+ flex-direction: column;
2805
+ align-items: stretch;
2806
+ }
2807
+
2808
+ .filter-bar__search-wrap {
2809
+ max-width: none;
2810
+ }
2811
+
2812
+ .table-wrapper {
2813
+ font-size: var(--text-xs);
2814
+ }
2815
+
2816
+ .table-wrapper th,
2817
+ .table-wrapper td {
2818
+ padding: var(--space-2) var(--space-3);
2819
+ }
2820
+
2821
+ .pagination {
2822
+ flex-direction: column;
2823
+ gap: var(--space-3);
2824
+ }
2825
+
2826
+ .modal {
2827
+ width: calc(100vw - 16px);
2828
+ max-height: 90vh;
2829
+ }
2830
+ }
2831
+
2832
+ @media (max-width: 480px) {
2833
+ .admin-content__inner {
2834
+ padding: var(--space-4) var(--space-3);
2835
+ }
2836
+
2837
+ .stat-cards {
2838
+ grid-template-columns: 1fr;
2839
+ }
2840
+
2841
+ .login-card {
2842
+ padding: var(--space-5);
2843
+ }
2844
+ }
2845
+
2846
+ /* ═══════════════════════════════════════════════════════════════════════════
2847
+ REDUCED MOTION
2848
+ ═══════════════════════════════════════════════════════════════════════════ */
2849
+
2850
+ @media (prefers-reduced-motion: reduce) {
2851
+ *, *::before, *::after {
2852
+ animation-duration: 0.01ms !important;
2853
+ animation-iteration-count: 1 !important;
2854
+ transition-duration: 0.01ms !important;
2855
+ }
2856
+ }
2857
+
2858
+ /* ═══════════════════════════════════════════════════════════════════════════
2859
+ DASHBOARD STAT CARDS
2860
+ ═══════════════════════════════════════════════════════════════════════════ */
2861
+
2862
+ .dashboard-stat-card {
2863
+ display: flex;
2864
+ flex-direction: column;
2865
+ gap: 14px;
2866
+ padding: 20px;
2867
+ border-radius: var(--radius-lg);
2868
+ text-decoration: none;
2869
+ color: var(--text-primary);
2870
+ background: var(--surface-raised);
2871
+ border: 1px solid var(--surface-border);
2872
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
2873
+ position: relative;
2874
+ overflow: hidden;
2875
+ }
2876
+
2877
+ .dashboard-stat-card:hover {
2878
+ transform: translateY(-4px);
2879
+ box-shadow: var(--shadow-card-hover);
2880
+ border-color: rgba(20, 184, 166, 0.3);
2881
+ }
2882
+
2883
+ .dashboard-stat-card .stat-icon {
2884
+ width: 40px;
2885
+ height: 40px;
2886
+ border-radius: var(--radius-md);
2887
+ display: flex;
2888
+ align-items: center;
2889
+ justify-content: center;
2890
+ overflow: hidden;
2891
+ flex-shrink: 0;
2892
+ }
2893
+
2894
+ .dashboard-stat-card .stat-icon svg {
2895
+ width: 20px;
2896
+ height: 20px;
2897
+ display: block;
2898
+ flex-shrink: 0;
2899
+ }
2900
+
2901
+ .dashboard-stat-card .stat-header {
2902
+ display: flex;
2903
+ align-items: center;
2904
+ gap: 10px;
2905
+ }
2906
+
2907
+ .dashboard-stat-card .stat-label {
2908
+ font-size: var(--text-xs);
2909
+ font-weight: var(--font-semibold);
2910
+ color: var(--text-tertiary);
2911
+ }
2912
+
2913
+ .dashboard-stat-card .stat-count {
2914
+ font-family: var(--font-display);
2915
+ font-size: var(--text-3xl);
2916
+ font-weight: 700;
2917
+ color: var(--text-primary);
2918
+ line-height: 1;
2919
+ letter-spacing: -0.03em;
2920
+ }
2921
+
2922
+ .dashboard-stat-card .stat-subtitle {
2923
+ font-size: var(--text-xs);
2924
+ color: var(--text-tertiary);
2925
+ }
2926
+
2927
+ .dashboard-stat-card .stat-trend {
2928
+ display: inline-flex;
2929
+ align-items: center;
2930
+ gap: 4px;
2931
+ font-size: var(--text-2xs);
2932
+ font-weight: var(--font-semibold);
2933
+ padding: 3px 8px;
2934
+ border-radius: var(--radius-full);
2935
+ }
2936
+
2937
+ .dashboard-stat-card .stat-trend.up {
2938
+ color: #16a34a;
2939
+ background: rgba(34, 197, 94, 0.1);
2940
+ }
2941
+
2942
+ .dashboard-stat-card .stat-trend.down {
2943
+ color: #dc2626;
2944
+ background: rgba(239, 68, 68, 0.1);
2945
+ }
2946
+
2947
+ .dashboard-stat-card .stat-trend-period {
2948
+ font-size: var(--text-2xs);
2949
+ color: var(--text-tertiary);
2950
+ margin-left: 4px;
2951
+ }
2952
+
2953
+ .dashboard-stat-card .stat-wave {
2954
+ position: absolute;
2955
+ bottom: 0;
2956
+ right: 0;
2957
+ width: 80px;
2958
+ height: 30px;
2959
+ opacity: 0.15;
2960
+ }
2961
+
2962
+ /* ── Stat icon colors ─────────────────────────────────────────────────── */
2963
+ .stat-icon--teal { background: rgba(20, 184, 166, 0.12); color: #14b8a6; }
2964
+ .stat-icon--purple { background: rgba(139, 92, 246, 0.12); color: #8b5cf6; }
2965
+ .stat-icon--blue { background: rgba(59, 130, 246, 0.12); color: #3b82f6; }
2966
+ .stat-icon--orange { background: rgba(249, 115, 22, 0.12); color: #f97316; }
2967
+ .stat-icon--green { background: rgba(34, 197, 94, 0.12); color: #22c55e; }
2968
+ .stat-icon--yellow { background: rgba(234, 179, 8, 0.12); color: #eab308; }
2969
+ .stat-icon--pink { background: rgba(236, 72, 153, 0.12); color: #ec4899; }
2970
+ .stat-icon--red { background: rgba(239, 68, 68, 0.12); color: #ef4444; }
2971
+ .stat-icon--indigo { background: rgba(99, 102, 241, 0.12); color: #6366f1; }
2972
+ .stat-icon--cyan { background: rgba(6, 182, 212, 0.12); color: #06b6d4; }
2973
+
2974
+ /* ═══════════════════════════════════════════════════════════════════════════
2975
+ SYSTEM OVERVIEW (DONUT CHART)
2976
+ ═══════════════════════════════════════════════════════════════════════════ */
2977
+
2978
+ .system-overview-card {
2979
+ background: var(--surface-raised);
2980
+ border: 1px solid var(--surface-border);
2981
+ border-radius: var(--radius-lg);
2982
+ padding: 24px;
2983
+ display: flex;
2984
+ flex-direction: column;
2985
+ gap: 20px;
2986
+ }
2987
+
2988
+ .system-overview-card .overview-header {
2989
+ display: flex;
2990
+ align-items: center;
2991
+ gap: 10px;
2992
+ }
2993
+
2994
+ .system-overview-card .overview-header-icon {
2995
+ width: 36px;
2996
+ height: 36px;
2997
+ border-radius: var(--radius-md);
2998
+ background: var(--primary-50);
2999
+ display: flex;
3000
+ align-items: center;
3001
+ justify-content: center;
3002
+ }
3003
+
3004
+ .system-overview-card .overview-header-icon svg {
3005
+ width: 18px;
3006
+ height: 18px;
3007
+ color: var(--primary-600);
3008
+ }
3009
+
3010
+ .system-overview-card .overview-title {
3011
+ font-size: var(--text-md);
3012
+ font-family: var(--font-display);
3013
+ font-weight: 700;
3014
+ color: var(--text-primary);
3015
+ }
3016
+
3017
+ .system-overview-card .overview-body {
3018
+ display: flex;
3019
+ align-items: center;
3020
+ gap: 28px;
3021
+ }
3022
+
3023
+ .system-overview-card .overview-chart {
3024
+ width: 160px;
3025
+ height: 160px;
3026
+ flex-shrink: 0;
3027
+ }
3028
+
3029
+ .system-overview-card .overview-legend {
3030
+ display: flex;
3031
+ flex-direction: column;
3032
+ gap: 10px;
3033
+ flex: 1;
3034
+ }
3035
+
3036
+ .system-overview-card .overview-legend-item {
3037
+ display: flex;
3038
+ align-items: center;
3039
+ justify-content: space-between;
3040
+ gap: 10px;
3041
+ }
3042
+
3043
+ .system-overview-card .overview-legend-label {
3044
+ display: flex;
3045
+ align-items: center;
3046
+ gap: 8px;
3047
+ font-size: var(--text-sm);
3048
+ color: var(--text-secondary);
3049
+ }
3050
+
3051
+ .system-overview-card .overview-legend-dot {
3052
+ width: 10px;
3053
+ height: 10px;
3054
+ border-radius: 50%;
3055
+ flex-shrink: 0;
3056
+ }
3057
+
3058
+ .system-overview-card .overview-legend-value {
3059
+ font-size: var(--text-sm);
3060
+ font-weight: var(--font-semibold);
3061
+ font-family: var(--font-mono);
3062
+ color: var(--text-primary);
3063
+ }
3064
+
3065
+ .system-overview-card .overview-total {
3066
+ display: flex;
3067
+ align-items: center;
3068
+ justify-content: space-between;
3069
+ padding-top: 10px;
3070
+ border-top: 1px solid var(--surface-border);
3071
+ font-size: var(--text-sm);
3072
+ font-weight: var(--font-semibold);
3073
+ color: var(--text-primary);
3074
+ }
3075
+
3076
+ /* ═══════════════════════════════════════════════════════════════════════════
3077
+ QUICK ACTIONS GRID
3078
+ ═══════════════════════════════════════════════════════════════════════════ */
3079
+
3080
+ .quick-actions-grid {
3081
+ display: grid;
3082
+ grid-template-columns: repeat(2, 1fr);
3083
+ gap: 10px;
3084
+ padding: 12px;
3085
+ }
3086
+
3087
+ .quick-action-item {
3088
+ display: flex;
3089
+ align-items: center;
3090
+ gap: 12px;
3091
+ padding: 14px;
3092
+ border-radius: var(--radius-md);
3093
+ text-decoration: none;
3094
+ color: var(--text-primary);
3095
+ transition: all 0.15s;
3096
+ border: 1px solid transparent;
3097
+ }
3098
+
3099
+ .quick-action-item:hover {
3100
+ background: var(--primary-50);
3101
+ border-color: var(--primary-200);
3102
+ }
3103
+
3104
+ [data-theme="dark"] .quick-action-item:hover {
3105
+ background: rgba(20, 184, 166, 0.08);
3106
+ border-color: rgba(45, 212, 191, 0.2);
3107
+ }
3108
+
3109
+ .quick-action-item .action-icon {
3110
+ width: 36px;
3111
+ height: 36px;
3112
+ border-radius: var(--radius-md);
3113
+ display: flex;
3114
+ align-items: center;
3115
+ justify-content: center;
3116
+ flex-shrink: 0;
3117
+ overflow: hidden;
3118
+ }
3119
+
3120
+ .quick-action-item .action-icon svg {
3121
+ width: 18px;
3122
+ height: 18px;
3123
+ display: block;
3124
+ flex-shrink: 0;
3125
+ }
3126
+
3127
+ .quick-action-item .action-text {
3128
+ flex: 1;
3129
+ min-width: 0;
3130
+ }
3131
+
3132
+ .quick-action-item .action-title {
3133
+ font-size: var(--text-sm);
3134
+ font-weight: var(--font-semibold);
3135
+ color: var(--text-primary);
3136
+ }
3137
+
3138
+ .quick-action-item .action-desc {
3139
+ font-size: var(--text-xs);
3140
+ color: var(--text-tertiary);
3141
+ margin-top: 2px;
3142
+ }
3143
+
3144
+ .quick-action-item .action-chevron {
3145
+ width: 14px;
3146
+ height: 14px;
3147
+ color: var(--text-tertiary);
3148
+ flex-shrink: 0;
3149
+ }
3150
+
3151
+ @media (max-width: 640px) {
3152
+ .quick-actions-grid {
3153
+ grid-template-columns: 1fr;
3154
+ }
3155
+ }
3156
+
3157
+ /* ═══════════════════════════════════════════════════════════════════════════
3158
+ LIST PAGE — Modern Clean Design
3159
+ ═══════════════════════════════════════════════════════════════════════════ */
3160
+
3161
+ /* Breadcrumb */
3162
+ .breadcrumb {
3163
+ display: flex;
3164
+ align-items: center;
3165
+ gap: var(--space-2);
3166
+ font-size: var(--text-sm);
3167
+ margin-bottom: var(--space-4);
3168
+ }
3169
+
3170
+ .breadcrumb-link {
3171
+ color: var(--text-secondary);
3172
+ transition: color var(--duration-fast);
3173
+ }
3174
+
3175
+ .breadcrumb-link:hover {
3176
+ color: var(--primary-500);
3177
+ }
3178
+
3179
+ .breadcrumb-sep {
3180
+ color: var(--text-disabled);
3181
+ }
3182
+
3183
+ .breadcrumb-current {
3184
+ color: var(--text-primary);
3185
+ font-weight: var(--font-medium);
3186
+ }
3187
+
3188
+ /* Page Header */
3189
+ .page-header {
3190
+ display: flex;
3191
+ align-items: flex-start;
3192
+ justify-content: space-between;
3193
+ gap: var(--space-4);
3194
+ margin-bottom: var(--space-6);
3195
+ }
3196
+
3197
+ .page-header-left {
3198
+ display: flex;
3199
+ flex-direction: column;
3200
+ gap: var(--space-1);
3201
+ }
3202
+
3203
+ .page-header-right {
3204
+ display: flex;
3205
+ align-items: center;
3206
+ gap: var(--space-2);
3207
+ flex-shrink: 0;
3208
+ }
3209
+
3210
+ .page-header-title {
3211
+ font-family: var(--font-display);
3212
+ font-size: var(--text-2xl);
3213
+ font-weight: 600;
3214
+ color: var(--text-primary);
3215
+ margin: 0;
3216
+ line-height: 1.2;
3217
+ }
3218
+
3219
+ .page-header-subtitle {
3220
+ font-size: var(--text-sm);
3221
+ color: var(--text-secondary);
3222
+ margin: 0;
3223
+ }
3224
+
3225
+ /* Filter Bar */
3226
+ .filter-bar {
3227
+ display: flex;
3228
+ align-items: center;
3229
+ gap: var(--space-3);
3230
+ padding: var(--space-4);
3231
+ background: var(--surface-raised);
3232
+ border: 1px solid var(--surface-border);
3233
+ border-radius: var(--radius-lg);
3234
+ flex-wrap: wrap;
3235
+ }
3236
+
3237
+ .filter-bar-search {
3238
+ position: relative;
3239
+ flex: 1;
3240
+ min-width: 240px;
3241
+ }
3242
+
3243
+ .filter-bar-search-icon {
3244
+ position: absolute;
3245
+ left: var(--space-3);
3246
+ top: 50%;
3247
+ transform: translateY(-50%);
3248
+ width: 18px;
3249
+ height: 18px;
3250
+ color: var(--text-disabled);
3251
+ pointer-events: none;
3252
+ }
3253
+
3254
+ .filter-bar-search-input {
3255
+ width: 100%;
3256
+ padding: var(--space-2) var(--space-3) var(--space-2) var(--space-10);
3257
+ border: 1px solid var(--surface-border);
3258
+ border-radius: var(--radius-md);
3259
+ background: var(--surface-base);
3260
+ font-size: var(--text-sm);
3261
+ color: var(--text-primary);
3262
+ outline: none;
3263
+ transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
3264
+ }
3265
+
3266
+ .filter-bar-search-input::placeholder {
3267
+ color: var(--text-disabled);
3268
+ }
3269
+
3270
+ .filter-bar-search-input:focus {
3271
+ border-color: var(--primary-500);
3272
+ box-shadow: var(--shadow-focus);
3273
+ }
3274
+
3275
+ .filter-bar-clear {
3276
+ position: absolute;
3277
+ right: var(--space-2);
3278
+ top: 50%;
3279
+ transform: translateY(-50%);
3280
+ background: none;
3281
+ border: none;
3282
+ cursor: pointer;
3283
+ color: var(--text-disabled);
3284
+ padding: var(--space-1);
3285
+ border-radius: var(--radius-sm);
3286
+ transition: all var(--duration-fast);
3287
+ }
3288
+
3289
+ .filter-bar-clear:hover {
3290
+ color: var(--text-primary);
3291
+ background: var(--surface-inset);
3292
+ }
3293
+
3294
+ .filter-bar-clear svg {
3295
+ width: 16px;
3296
+ height: 16px;
3297
+ }
3298
+
3299
+ .filter-bar-chips {
3300
+ display: flex;
3301
+ gap: var(--space-2);
3302
+ flex-wrap: wrap;
3303
+ }
3304
+
3305
+ .filter-bar-right {
3306
+ display: flex;
3307
+ align-items: center;
3308
+ gap: var(--space-2);
3309
+ margin-left: auto;
3310
+ }
3311
+
3312
+ .filter-bar-action {
3313
+ display: inline-flex;
3314
+ align-items: center;
3315
+ justify-content: center;
3316
+ width: 36px;
3317
+ height: 36px;
3318
+ border-radius: var(--radius-md);
3319
+ background: none;
3320
+ border: 1px solid var(--surface-border);
3321
+ cursor: pointer;
3322
+ color: var(--text-secondary);
3323
+ transition: all var(--duration-fast);
3324
+ }
3325
+
3326
+ .filter-bar-action:hover {
3327
+ background: var(--surface-inset);
3328
+ color: var(--text-primary);
3329
+ }
3330
+
3331
+ .filter-bar-action svg {
3332
+ width: 18px;
3333
+ height: 18px;
3334
+ }
3335
+
3336
+ .filter-bar-clear-all {
3337
+ font-size: var(--text-xs);
3338
+ color: var(--text-secondary);
3339
+ background: none;
3340
+ border: none;
3341
+ cursor: pointer;
3342
+ transition: color var(--duration-fast);
3343
+ }
3344
+
3345
+ .filter-bar-clear-all:hover {
3346
+ color: var(--danger-500);
3347
+ }
3348
+
3349
+ .filter-bar-divider {
3350
+ width: 1px;
3351
+ height: 24px;
3352
+ background: var(--surface-border);
3353
+ }
3354
+
3355
+ /* Filter Chips */
3356
+ .filter-chip {
3357
+ display: inline-flex;
3358
+ align-items: center;
3359
+ gap: var(--space-1);
3360
+ padding: var(--space-1) var(--space-3);
3361
+ font-size: var(--text-sm);
3362
+ border: 1px solid var(--surface-border);
3363
+ border-radius: var(--radius-full);
3364
+ background: var(--surface-raised);
3365
+ color: var(--text-secondary);
3366
+ cursor: pointer;
3367
+ transition: all var(--duration-fast);
3368
+ height: 36px;
3369
+ }
3370
+
3371
+ .filter-chip:hover {
3372
+ border-color: var(--text-disabled);
3373
+ color: var(--text-primary);
3374
+ }
3375
+
3376
+ .filter-chip.active {
3377
+ border-color: var(--primary-500);
3378
+ color: var(--primary-600);
3379
+ background: var(--primary-50);
3380
+ }
3381
+
3382
+ .filter-chip svg {
3383
+ width: 14px;
3384
+ height: 14px;
3385
+ transition: transform var(--duration-fast);
3386
+ }
3387
+
3388
+ .filter-chip-count {
3389
+ display: inline-flex;
3390
+ align-items: center;
3391
+ justify-content: center;
3392
+ min-width: 18px;
3393
+ height: 18px;
3394
+ padding: 0 4px;
3395
+ border-radius: var(--radius-full);
3396
+ background: var(--primary-500);
3397
+ color: white;
3398
+ font-size: 10px;
3399
+ font-weight: 600;
3400
+ }
3401
+
3402
+ .filter-chip-wrap {
3403
+ display: inline-flex;
3404
+ align-items: center;
3405
+ gap: var(--space-2);
3406
+ padding: 0 var(--space-3);
3407
+ height: 36px;
3408
+ background: var(--surface-raised);
3409
+ border: 1px solid var(--surface-border);
3410
+ border-radius: var(--radius-md);
3411
+ transition: all var(--duration-fast);
3412
+ }
3413
+
3414
+ .filter-chip-wrap:hover {
3415
+ border-color: var(--text-disabled);
3416
+ }
3417
+
3418
+ .filter-chip-wrap.filter-chip--active {
3419
+ background: var(--primary-50);
3420
+ border-color: var(--primary-200);
3421
+ }
3422
+
3423
+ .filter-chip-label {
3424
+ font-size: var(--text-sm);
3425
+ color: var(--text-secondary);
3426
+ white-space: nowrap;
3427
+ }
3428
+
3429
+ .filter-chip--active .filter-chip-label {
3430
+ color: var(--primary-600);
3431
+ font-weight: var(--font-medium);
3432
+ }
3433
+
3434
+ .filter-input-date,
3435
+ .filter-input-datetime,
3436
+ .filter-input-time {
3437
+ height: 34px;
3438
+ padding: 0 var(--space-2);
3439
+ border: none;
3440
+ background: transparent;
3441
+ font-size: var(--text-sm);
3442
+ font-family: var(--font-body);
3443
+ color: var(--text-primary);
3444
+ cursor: pointer;
3445
+ outline: none;
3446
+ }
3447
+
3448
+ .filter-clear-btn {
3449
+ background: none;
3450
+ border: none;
3451
+ color: var(--text-disabled);
3452
+ cursor: pointer;
3453
+ font-size: 18px;
3454
+ line-height: 1;
3455
+ padding: 0;
3456
+ transition: color var(--duration-fast);
3457
+ }
3458
+
3459
+ .filter-clear-btn:hover {
3460
+ color: var(--danger-500);
3461
+ }
3462
+
3463
+ .filter-dropdown {
3464
+ position: absolute;
3465
+ top: calc(100% + 4px);
3466
+ left: 0;
3467
+ min-width: 200px;
3468
+ background: var(--surface-raised);
3469
+ border: 1px solid var(--surface-border);
3470
+ border-radius: var(--radius-lg);
3471
+ box-shadow: var(--shadow-lg);
3472
+ z-index: 50;
3473
+ padding: var(--space-2) 0;
3474
+ }
3475
+
3476
+ .filter-dropdown-header {
3477
+ display: flex;
3478
+ align-items: center;
3479
+ justify-content: space-between;
3480
+ padding: var(--space-2) var(--space-3);
3481
+ font-size: var(--text-xs);
3482
+ font-weight: var(--font-medium);
3483
+ color: var(--text-secondary);
3484
+ border-bottom: 1px solid var(--surface-border);
3485
+ }
3486
+
3487
+ .filter-dropdown-clear {
3488
+ font-size: var(--text-xs);
3489
+ color: var(--primary-500);
3490
+ background: none;
3491
+ border: none;
3492
+ cursor: pointer;
3493
+ transition: color var(--duration-fast);
3494
+ }
3495
+
3496
+ .filter-dropdown-clear:hover {
3497
+ color: var(--primary-600);
3498
+ }
3499
+
3500
+ .filter-dropdown-item {
3501
+ display: flex;
3502
+ align-items: center;
3503
+ gap: var(--space-2);
3504
+ padding: var(--space-2) var(--space-3);
3505
+ font-size: var(--text-sm);
3506
+ color: var(--text-primary);
3507
+ cursor: pointer;
3508
+ transition: background var(--duration-fast);
3509
+ }
3510
+
3511
+ .filter-dropdown-item:hover {
3512
+ background: var(--surface-inset);
3513
+ }
3514
+
3515
+ .filter-dropdown-item input[type="radio"] {
3516
+ width: 16px;
3517
+ height: 16px;
3518
+ accent-color: var(--primary-500);
3519
+ cursor: pointer;
3520
+ }
3521
+
3522
+ .filter-dropdown-item label {
3523
+ cursor: pointer;
3524
+ flex: 1;
3525
+ }
3526
+
3527
+ /* ═══════════════════════════════════════════════════════════════════════════
3528
+ BULK ACTIONS BAR — Django-style above table
3529
+ ═══════════════════════════════════════════════════════════════════════════ */
3530
+
3531
+ .bulk-bar {
3532
+ display: flex;
3533
+ align-items: center;
3534
+ justify-content: space-between;
3535
+ padding: var(--space-3) var(--space-4);
3536
+ background: var(--surface-raised);
3537
+ border: 1px solid var(--surface-border);
3538
+ border-radius: var(--radius-lg);
3539
+ }
3540
+
3541
+ .bulk-bar-left {
3542
+ display: flex;
3543
+ align-items: center;
3544
+ gap: var(--space-3);
3545
+ }
3546
+
3547
+ .bulk-bar-label {
3548
+ font-size: var(--text-sm);
3549
+ font-weight: 500;
3550
+ color: var(--text-primary);
3551
+ }
3552
+
3553
+ .bulk-bar-select {
3554
+ height: 36px;
3555
+ padding: 0 var(--space-8) 0 var(--space-3);
3556
+ font-size: var(--text-sm);
3557
+ font-family: var(--font-body);
3558
+ color: var(--text-primary);
3559
+ background: var(--surface-base);
3560
+ border: 1px solid var(--surface-border);
3561
+ border-radius: var(--radius-md);
3562
+ cursor: pointer;
3563
+ outline: none;
3564
+ appearance: none;
3565
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
3566
+ background-position: right 8px center;
3567
+ background-repeat: no-repeat;
3568
+ background-size: 18px;
3569
+ min-width: 180px;
3570
+ }
3571
+
3572
+ .bulk-bar-select:focus {
3573
+ border-color: var(--primary-500);
3574
+ box-shadow: var(--shadow-focus);
3575
+ }
3576
+
3577
+ .bulk-bar-right {
3578
+ display: flex;
3579
+ align-items: center;
3580
+ gap: var(--space-2);
3581
+ }
3582
+
3583
+ /* ═══════════════════════════════════════════════════════════════════════════
3584
+ DATA TABLE — Modern Clean Design
3585
+ ═══════════════════════════════════════════════════════════════════════════ */
3586
+
3587
+ .table-container {
3588
+ background: var(--surface-raised);
3589
+ border: 1px solid var(--surface-border);
3590
+ border-radius: var(--radius-lg);
3591
+ position: relative;
3592
+ }
3593
+
3594
+ .table-container .overflow-x-auto {
3595
+ overflow-x: auto;
3596
+ scrollbar-width: thin;
3597
+ scrollbar-color: var(--surface-border) transparent;
3598
+ }
3599
+
3600
+ .table-container .data-table {
3601
+ position: relative;
3602
+ }
3603
+
3604
+ /* Ensure actions dropdown can escape scrollable container */
3605
+ .actions-dropdown {
3606
+ position: relative;
3607
+ }
3608
+
3609
+ .data-table {
3610
+ width: 100%;
3611
+ border-collapse: collapse;
3612
+ }
3613
+
3614
+ .data-table thead {
3615
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
3616
+ }
3617
+
3618
+ .data-table thead tr:first-child th:first-child {
3619
+ border-top-left-radius: var(--radius-lg);
3620
+ }
3621
+
3622
+ .data-table thead tr:first-child th:last-child {
3623
+ border-top-right-radius: var(--radius-lg);
3624
+ }
3625
+
3626
+ /* Table Header */
3627
+ .data-table thead {
3628
+ background: var(--surface-base);
3629
+ border-bottom: 1px solid var(--surface-border);
3630
+ }
3631
+
3632
+ .data-table th {
3633
+ padding: var(--space-3) var(--space-4);
3634
+ text-align: left;
3635
+ font-size: var(--text-xs);
3636
+ font-weight: 600;
3637
+ color: var(--text-secondary);
3638
+ text-transform: uppercase;
3639
+ letter-spacing: 0.05em;
3640
+ white-space: nowrap;
3641
+ user-select: none;
3642
+ }
3643
+
3644
+ .data-table th.col-checkbox {
3645
+ width: 48px;
3646
+ text-align: center;
3647
+ }
3648
+
3649
+ .data-table th.col-actions {
3650
+ width: 100px;
3651
+ text-align: right;
3652
+ }
3653
+
3654
+ .col-header-link {
3655
+ display: inline-flex;
3656
+ align-items: center;
3657
+ gap: var(--space-1);
3658
+ color: inherit;
3659
+ transition: color var(--duration-fast);
3660
+ }
3661
+
3662
+ .col-header-link:hover {
3663
+ color: var(--primary-500);
3664
+ }
3665
+
3666
+ .col-header-link.active {
3667
+ color: var(--primary-600);
3668
+ font-weight: 600;
3669
+ }
3670
+
3671
+ .sort-icon {
3672
+ width: 14px;
3673
+ height: 14px;
3674
+ }
3675
+
3676
+ .sort-icon--asc {
3677
+ transform: rotate(0deg);
3678
+ }
3679
+
3680
+ .sort-icon--desc {
3681
+ transform: rotate(180deg);
3682
+ }
3683
+
3684
+ /* Table Body */
3685
+ .data-table tbody tr {
3686
+ border-bottom: 1px solid var(--surface-border);
3687
+ transition: background var(--duration-fast);
3688
+ }
3689
+
3690
+ .data-table tbody tr:last-child {
3691
+ border-bottom: none;
3692
+ }
3693
+
3694
+ .data-table tbody tr:hover {
3695
+ background: var(--surface-inset);
3696
+ }
3697
+
3698
+ .data-table td {
3699
+ padding: var(--space-3) var(--space-4);
3700
+ font-size: var(--text-sm);
3701
+ color: var(--text-primary);
3702
+ vertical-align: middle;
3703
+ }
3704
+
3705
+ .data-table td.col-checkbox {
3706
+ text-align: center;
3707
+ }
3708
+
3709
+ .data-table td.col-actions {
3710
+ text-align: right;
3711
+ }
3712
+
3713
+ /* Row Checkbox */
3714
+ .row-checkbox {
3715
+ width: 16px;
3716
+ height: 16px;
3717
+ border: 1.5px solid var(--surface-border);
3718
+ border-radius: var(--radius-sm);
3719
+ cursor: pointer;
3720
+ appearance: none;
3721
+ background: var(--surface-raised);
3722
+ transition: all var(--duration-fast);
3723
+ position: relative;
3724
+ }
3725
+
3726
+ .row-checkbox:checked {
3727
+ background: var(--primary-500);
3728
+ border-color: var(--primary-500);
3729
+ }
3730
+
3731
+ .row-checkbox:checked::after {
3732
+ content: '';
3733
+ position: absolute;
3734
+ left: 4px;
3735
+ top: 1px;
3736
+ width: 5px;
3737
+ height: 9px;
3738
+ border: solid white;
3739
+ border-width: 0 2px 2px 0;
3740
+ transform: rotate(45deg);
3741
+ }
3742
+
3743
+ /* Status Badges */
3744
+ .status-badge {
3745
+ display: inline-flex;
3746
+ align-items: center;
3747
+ gap: 4px;
3748
+ padding: 4px 10px;
3749
+ border-radius: var(--radius-full);
3750
+ font-size: var(--text-xs);
3751
+ font-weight: 500;
3752
+ }
3753
+
3754
+ .status-badge--success {
3755
+ background: var(--success-50);
3756
+ color: var(--success-700);
3757
+ }
3758
+
3759
+ .status-badge--success svg {
3760
+ color: var(--success-500);
3761
+ }
3762
+
3763
+ .status-badge--muted {
3764
+ background: var(--surface-inset);
3765
+ color: var(--text-secondary);
3766
+ }
3767
+
3768
+ .status-badge--muted svg {
3769
+ color: var(--text-disabled);
3770
+ }
3771
+
3772
+ /* Actions Dropdown */
3773
+ .actions-dropdown {
3774
+ position: relative;
3775
+ display: inline-flex;
3776
+ }
3777
+
3778
+ .actions-trigger {
3779
+ display: inline-flex;
3780
+ align-items: center;
3781
+ justify-content: center;
3782
+ width: 32px;
3783
+ height: 32px;
3784
+ border-radius: var(--radius-md);
3785
+ background: none;
3786
+ border: none;
3787
+ color: var(--text-secondary);
3788
+ cursor: pointer;
3789
+ transition: all var(--duration-fast);
3790
+ }
3791
+
3792
+ .actions-trigger:hover {
3793
+ background: var(--surface-inset);
3794
+ color: var(--text-primary);
3795
+ }
3796
+
3797
+ .actions-trigger svg {
3798
+ width: 16px;
3799
+ height: 16px;
3800
+ }
3801
+
3802
+ .actions-menu {
3803
+ position: fixed;
3804
+ right: auto;
3805
+ top: auto;
3806
+ min-width: 120px;
3807
+ background: var(--surface-raised);
3808
+ border: 1px solid var(--surface-border);
3809
+ border-radius: var(--radius-lg);
3810
+ box-shadow: var(--shadow-lg);
3811
+ z-index: 9999;
3812
+ padding: var(--space-1) 0;
3813
+ transform-origin: top right;
3814
+ }
3815
+
3816
+ .actions-menu-item {
3817
+ display: flex;
3818
+ align-items: center;
3819
+ gap: var(--space-2);
3820
+ width: 100%;
3821
+ padding: var(--space-2) var(--space-3);
3822
+ font-size: var(--text-sm);
3823
+ font-weight: 500;
3824
+ color: var(--text-primary);
3825
+ background: none;
3826
+ border: none;
3827
+ cursor: pointer;
3828
+ text-align: left;
3829
+ text-decoration: none;
3830
+ transition: background var(--duration-fast);
3831
+ }
3832
+
3833
+ .actions-menu-item:hover {
3834
+ background: var(--surface-inset);
3835
+ }
3836
+
3837
+ .actions-menu-item svg {
3838
+ width: 16px;
3839
+ height: 16px;
3840
+ color: var(--text-secondary);
3841
+ flex-shrink: 0;
3842
+ }
3843
+
3844
+ .actions-menu-item--danger {
3845
+ color: var(--danger-500);
3846
+ }
3847
+
3848
+ .actions-menu-item--danger svg {
3849
+ color: var(--danger-500);
3850
+ }
3851
+
3852
+ .actions-menu-item--danger:hover {
3853
+ background: var(--danger-50);
3854
+ }
3855
+
3856
+ /* Empty State */
3857
+ .empty-cell {
3858
+ padding: var(--space-12) var(--space-4) !important;
3859
+ text-align: center;
3860
+ }
3861
+
3862
+ .empty-state {
3863
+ display: flex;
3864
+ flex-direction: column;
3865
+ align-items: center;
3866
+ gap: var(--space-3);
3867
+ }
3868
+
3869
+ .empty-state-icon {
3870
+ width: 48px;
3871
+ height: 48px;
3872
+ color: var(--text-disabled);
3873
+ opacity: 0.5;
3874
+ }
3875
+
3876
+ .empty-state-text {
3877
+ font-size: var(--text-sm);
3878
+ color: var(--text-secondary);
3879
+ margin: 0;
3880
+ }
3881
+
3882
+ .text-muted {
3883
+ color: var(--text-disabled);
3884
+ }
3885
+
3886
+ /* Table Footer */
3887
+ .table-footer {
3888
+ display: flex;
3889
+ align-items: center;
3890
+ justify-content: flex-end;
3891
+ padding: var(--space-3) var(--space-4);
3892
+ border-top: 1px solid var(--surface-border);
3893
+ background: var(--surface-base);
3894
+ }
3895
+
3896
+ .bulk-actions {
3897
+ display: flex;
3898
+ align-items: center;
3899
+ gap: var(--space-2);
3900
+ }
3901
+
3902
+ .bulk-actions-label {
3903
+ font-size: var(--text-sm);
3904
+ color: var(--text-secondary);
3905
+ }
3906
+
3907
+ /* Pagination */
3908
+ .pagination {
3909
+ display: flex;
3910
+ align-items: center;
3911
+ gap: var(--space-4);
3912
+ }
3913
+
3914
+ .pagination-info {
3915
+ font-size: var(--text-sm);
3916
+ color: var(--text-secondary);
3917
+ }
3918
+
3919
+ .pagination-links {
3920
+ display: flex;
3921
+ align-items: center;
3922
+ gap: var(--space-1);
3923
+ }
3924
+
3925
+ .pagination-link {
3926
+ display: inline-flex;
3927
+ align-items: center;
3928
+ justify-content: center;
3929
+ min-width: 32px;
3930
+ height: 32px;
3931
+ padding: 0 var(--space-2);
3932
+ border-radius: var(--radius-md);
3933
+ font-size: var(--text-sm);
3934
+ font-weight: 500;
3935
+ color: var(--text-secondary);
3936
+ background: none;
3937
+ border: 1px solid transparent;
3938
+ cursor: pointer;
3939
+ transition: all var(--duration-fast);
3940
+ text-decoration: none;
3941
+ }
3942
+
3943
+ .pagination-link:hover:not(.pagination-link--disabled):not(.pagination-link--active) {
3944
+ background: var(--surface-inset);
3945
+ color: var(--text-primary);
3946
+ }
3947
+
3948
+ .pagination-link--active {
3949
+ background: var(--primary-500);
3950
+ color: white;
3951
+ border-color: var(--primary-500);
3952
+ }
3953
+
3954
+ .pagination-link--disabled {
3955
+ opacity: 0.4;
3956
+ cursor: not-allowed;
3957
+ }
3958
+
3959
+ .pagination-ellipsis {
3960
+ padding: 0 var(--space-2);
3961
+ color: var(--text-disabled);
3962
+ font-size: var(--text-sm);
3963
+ }
3964
+
3965
+ /* ═══════════════════════════════════════════════════════════════════════════
3966
+ BUTTONS — Modern Clean Design
3967
+ ═══════════════════════════════════════════════════════════════════════════ */
3968
+
3969
+ .btn {
3970
+ display: inline-flex;
3971
+ align-items: center;
3972
+ justify-content: center;
3973
+ gap: var(--space-2);
3974
+ padding: var(--space-2) var(--space-4);
3975
+ font-size: var(--text-sm);
3976
+ font-weight: 500;
3977
+ border-radius: var(--radius-md);
3978
+ border: 1px solid transparent;
3979
+ cursor: pointer;
3980
+ transition: all var(--duration-fast);
3981
+ text-decoration: none;
3982
+ white-space: nowrap;
3983
+ line-height: 1.5;
3984
+ }
3985
+
3986
+ .btn svg {
3987
+ width: 16px;
3988
+ height: 16px;
3989
+ }
3990
+
3991
+ .btn-primary {
3992
+ background: var(--primary-500);
3993
+ color: white;
3994
+ border-color: var(--primary-500);
3995
+ }
3996
+
3997
+ .btn-primary:hover {
3998
+ background: var(--primary-600);
3999
+ border-color: var(--primary-600);
4000
+ }
4001
+
4002
+ .btn-secondary {
4003
+ background: var(--surface-raised);
4004
+ color: var(--text-primary);
4005
+ border-color: var(--surface-border);
4006
+ }
4007
+
4008
+ .btn-secondary:hover {
4009
+ background: var(--surface-inset);
4010
+ }
4011
+
4012
+ .btn-ghost {
4013
+ background: none;
4014
+ color: var(--text-secondary);
4015
+ border-color: transparent;
4016
+ }
4017
+
4018
+ .btn-ghost:hover {
4019
+ background: var(--surface-inset);
4020
+ color: var(--text-primary);
4021
+ }
4022
+
4023
+ .btn-outline-danger {
4024
+ background: var(--surface-raised);
4025
+ color: var(--danger-500);
4026
+ border-color: var(--danger-500);
4027
+ }
4028
+
4029
+ .btn-outline-danger:hover {
4030
+ background: var(--danger-500);
4031
+ color: white;
4032
+ }
4033
+
4034
+ .btn-sm {
4035
+ padding: var(--space-1) var(--space-3);
4036
+ font-size: var(--text-xs);
4037
+ }
4038
+
4039
+ /* ═══════════════════════════════════════════════════════════════════════════
4040
+ TOPBAR — Modern Clean Design
4041
+ ═══════════════════════════════════════════════════════════════════════════ */
4042
+
4043
+ .admin-topbar {
4044
+ height: var(--topbar-height);
4045
+ flex-shrink: 0;
4046
+ background: var(--surface-raised);
4047
+ border-bottom: 1px solid var(--surface-border);
4048
+ display: flex;
4049
+ align-items: center;
4050
+ padding: 0 var(--content-padding);
4051
+ z-index: 30;
4052
+ position: relative;
4053
+ }
4054
+
4055
+ .admin-topbar::after {
4056
+ display: none;
4057
+ }
4058
+
4059
+ .topbar-left {
4060
+ display: flex;
4061
+ align-items: center;
4062
+ gap: var(--space-2);
4063
+ flex-shrink: 0;
4064
+ }
4065
+
4066
+ .topbar-center {
4067
+ flex: 1;
4068
+ display: flex;
4069
+ justify-content: center;
4070
+ }
4071
+
4072
+ .topbar-right {
4073
+ display: flex;
4074
+ align-items: center;
4075
+ gap: var(--space-2);
4076
+ flex-shrink: 0;
4077
+ }
4078
+
4079
+ .topbar-logo {
4080
+ display: flex;
4081
+ align-items: center;
4082
+ gap: var(--space-2);
4083
+ font-family: var(--font-display);
4084
+ font-size: var(--text-lg);
4085
+ font-weight: 600;
4086
+ color: var(--text-primary);
4087
+ white-space: nowrap;
4088
+ text-decoration: none;
4089
+ }
4090
+
4091
+ .topbar-logo-icon {
4092
+ display: flex;
4093
+ align-items: center;
4094
+ justify-content: center;
4095
+ width: 32px;
4096
+ height: 32px;
4097
+ background: var(--primary-500);
4098
+ border-radius: var(--radius-md);
4099
+ color: white;
4100
+ }
4101
+
4102
+ .topbar-logo-icon svg {
4103
+ width: 20px;
4104
+ height: 20px;
4105
+ }
4106
+
4107
+ .topbar-search {
4108
+ display: flex;
4109
+ align-items: center;
4110
+ gap: var(--space-2);
4111
+ padding: var(--space-2) var(--space-3);
4112
+ background: var(--surface-inset);
4113
+ border: 1px solid var(--surface-border);
4114
+ border-radius: var(--radius-lg);
4115
+ cursor: pointer;
4116
+ transition: all var(--duration-fast);
4117
+ min-width: 320px;
4118
+ }
4119
+
4120
+ .topbar-search:hover {
4121
+ border-color: var(--primary-300);
4122
+ }
4123
+
4124
+ .topbar-search svg {
4125
+ color: var(--text-disabled);
4126
+ flex-shrink: 0;
4127
+ }
4128
+
4129
+ .topbar-search-placeholder {
4130
+ color: var(--text-disabled);
4131
+ font-size: var(--text-sm);
4132
+ flex: 1;
4133
+ }
4134
+
4135
+ .topbar-search-shortcut {
4136
+ display: flex;
4137
+ gap: 4px;
4138
+ }
4139
+
4140
+ .topbar-search-shortcut kbd {
4141
+ display: inline-flex;
4142
+ align-items: center;
4143
+ justify-content: center;
4144
+ padding: 2px 6px;
4145
+ font-size: var(--text-2xs);
4146
+ font-family: var(--font-mono);
4147
+ background: var(--surface-raised);
4148
+ border: 1px solid var(--surface-border);
4149
+ border-radius: var(--radius-sm);
4150
+ color: var(--text-secondary);
4151
+ }
4152
+
4153
+ .topbar-user {
4154
+ position: relative;
4155
+ }
4156
+
4157
+ .topbar-user-btn {
4158
+ display: flex;
4159
+ align-items: center;
4160
+ gap: var(--space-2);
4161
+ padding: var(--space-1);
4162
+ border-radius: var(--radius-md);
4163
+ background: none;
4164
+ border: none;
4165
+ cursor: pointer;
4166
+ transition: all var(--duration-fast);
4167
+ }
4168
+
4169
+ .topbar-user-btn:hover {
4170
+ background: var(--surface-inset);
4171
+ }
4172
+
4173
+ .user-avatar {
4174
+ width: 36px;
4175
+ height: 36px;
4176
+ border-radius: var(--radius-full);
4177
+ background: var(--primary-100);
4178
+ color: var(--primary-700);
4179
+ display: flex;
4180
+ align-items: center;
4181
+ justify-content: center;
4182
+ font-size: var(--text-sm);
4183
+ font-weight: 600;
4184
+ }
4185
+
4186
+ .topbar-user-info {
4187
+ display: flex;
4188
+ flex-direction: column;
4189
+ text-align: left;
4190
+ }
4191
+
4192
+ .topbar-user-name {
4193
+ font-size: var(--text-sm);
4194
+ font-weight: 500;
4195
+ color: var(--text-primary);
4196
+ line-height: 1.2;
4197
+ }
4198
+
4199
+ .topbar-user-role {
4200
+ font-size: var(--text-2xs);
4201
+ color: var(--text-secondary);
4202
+ line-height: 1.2;
4203
+ }
4204
+
4205
+ .user-dropdown {
4206
+ position: absolute;
4207
+ right: 0;
4208
+ top: calc(100% + 4px);
4209
+ min-width: 200px;
4210
+ background: var(--surface-raised);
4211
+ border: 1px solid var(--surface-border);
4212
+ border-radius: var(--radius-lg);
4213
+ box-shadow: var(--shadow-lg);
4214
+ z-index: 50;
4215
+ padding: var(--space-1) 0;
4216
+ }
4217
+
4218
+ .user-dropdown-header {
4219
+ padding: var(--space-3) var(--space-4);
4220
+ border-bottom: 1px solid var(--surface-border);
4221
+ }
4222
+
4223
+ .user-dropdown-name {
4224
+ font-size: var(--text-sm);
4225
+ font-weight: 500;
4226
+ color: var(--text-primary);
4227
+ }
4228
+
4229
+ .user-dropdown-email {
4230
+ font-size: var(--text-xs);
4231
+ color: var(--text-secondary);
4232
+ margin-top: 2px;
4233
+ }
4234
+
4235
+ .user-dropdown-item {
4236
+ display: block;
4237
+ width: 100%;
4238
+ text-align: left;
4239
+ padding: var(--space-2) var(--space-4);
4240
+ font-size: var(--text-sm);
4241
+ color: var(--text-secondary);
4242
+ background: none;
4243
+ border: none;
4244
+ cursor: pointer;
4245
+ transition: all var(--duration-fast);
4246
+ }
4247
+
4248
+ .user-dropdown-item:hover {
4249
+ background: var(--surface-inset);
4250
+ color: var(--text-primary);
4251
+ }
4252
+
4253
+ .user-dropdown-item.danger {
4254
+ color: var(--danger-500);
4255
+ }
4256
+
4257
+ .user-dropdown-item.danger:hover {
4258
+ background: var(--danger-50);
4259
+ }
4260
+
4261
+ .collapse-toggle,
4262
+ .icon-btn {
4263
+ display: inline-flex;
4264
+ align-items: center;
4265
+ justify-content: center;
4266
+ width: 36px;
4267
+ height: 36px;
4268
+ border-radius: var(--radius-md);
4269
+ background: none;
4270
+ border: none;
4271
+ color: var(--text-secondary);
4272
+ cursor: pointer;
4273
+ transition: all var(--duration-fast);
4274
+ }
4275
+
4276
+ .collapse-toggle:hover,
4277
+ .icon-btn:hover {
4278
+ background: var(--surface-inset);
4279
+ color: var(--text-primary);
4280
+ }
4281
+
4282
+ .collapse-toggle svg,
4283
+ .icon-btn svg {
4284
+ width: 20px;
4285
+ height: 20px;
4286
+ }
4287
+
4288
+ /* ═══════════════════════════════════════════════════════════════════════════
4289
+ SIDEBAR — Modern Clean Design
4290
+ ═══════════════════════════════════════════════════════════════════════════ */
4291
+
4292
+ .admin-sidebar {
4293
+ width: var(--sidebar-width);
4294
+ flex-shrink: 0;
4295
+ background: var(--surface-raised);
4296
+ border-right: 1px solid var(--surface-border);
4297
+ display: flex;
4298
+ flex-direction: column;
4299
+ overflow: hidden;
4300
+ transition: width var(--duration-slow) var(--easing-out);
4301
+ z-index: 20;
4302
+ text-align: left;
4303
+ }
4304
+
4305
+ .sidebar-nav {
4306
+ flex: 1;
4307
+ overflow-y: auto;
4308
+ padding: var(--space-3);
4309
+ text-align: left;
4310
+ }
4311
+
4312
+ .sidebar-nav-list {
4313
+ list-style: none;
4314
+ margin: 0;
4315
+ padding: 0;
4316
+ text-align: left;
4317
+ }
4318
+
4319
+ .sidebar-nav-item {
4320
+ margin-bottom: 2px;
4321
+ text-align: left;
4322
+ }
4323
+
4324
+ .sidebar-section {
4325
+ padding: var(--space-4) 0 var(--space-2);
4326
+ text-align: left;
4327
+ }
4328
+
4329
+ .sidebar-section-label {
4330
+ font-size: var(--text-2xs);
4331
+ font-weight: 600;
4332
+ text-transform: uppercase;
4333
+ letter-spacing: 0.1em;
4334
+ color: var(--text-disabled);
4335
+ text-align: left;
4336
+ }
4337
+
4338
+ .sidebar-section-toggle {
4339
+ display: flex;
4340
+ align-items: center;
4341
+ justify-content: space-between;
4342
+ width: 100%;
4343
+ padding: 0;
4344
+ margin: 0;
4345
+ background: none;
4346
+ border: none;
4347
+ cursor: pointer;
4348
+ color: inherit;
4349
+ text-align: left;
4350
+ }
4351
+
4352
+ .sidebar-section-toggle:hover {
4353
+ color: var(--text-secondary);
4354
+ }
4355
+
4356
+ .sidebar-section-toggle .sidebar-section-label {
4357
+ flex: 1;
4358
+ }
4359
+
4360
+ .sidebar-section-chevron {
4361
+ transition: transform 0.2s ease;
4362
+ color: var(--text-disabled);
4363
+ flex-shrink: 0;
4364
+ }
4365
+
4366
+ .sidebar-section-chevron.collapsed {
4367
+ transform: rotate(0deg);
4368
+ }
4369
+
4370
+ .sidebar-section-chevron:not(.collapsed) {
4371
+ transform: rotate(90deg);
4372
+ }
4373
+
4374
+ .sidebar-section-items {
4375
+ list-style: none;
4376
+ margin: 0;
4377
+ padding: 0;
4378
+ text-align: left;
4379
+ }
4380
+
4381
+ .sidebar-bottom {
4382
+ border-top: 1px solid var(--surface-border);
4383
+ padding: var(--space-3);
4384
+ flex-shrink: 0;
4385
+ text-align: left;
4386
+ }
4387
+
4388
+ /* Nav Links */
4389
+ .nav-link {
4390
+ display: flex;
4391
+ align-items: center;
4392
+ gap: var(--space-3);
4393
+ padding: var(--space-2) 0;
4394
+ font-size: var(--text-sm);
4395
+ font-weight: 500;
4396
+ color: var(--text-primary);
4397
+ border-radius: var(--radius-md);
4398
+ transition: all var(--duration-fast);
4399
+ cursor: pointer;
4400
+ border: none;
4401
+ background: none;
4402
+ width: 100%;
4403
+ text-align: left;
4404
+ line-height: 1.5;
4405
+ text-decoration: none;
4406
+ }
4407
+
4408
+ .nav-link svg,
4409
+ .nav-link .material-symbols-outlined {
4410
+ width: 18px;
4411
+ height: 18px;
4412
+ flex-shrink: 0;
4413
+ opacity: 0.6;
4414
+ font-size: 18px;
4415
+ }
4416
+
4417
+ .nav-link:hover {
4418
+ background: var(--surface-inset);
4419
+ color: var(--primary-600);
4420
+ }
4421
+
4422
+ .nav-link:hover svg,
4423
+ .nav-link:hover .material-symbols-outlined {
4424
+ opacity: 1;
4425
+ }
4426
+
4427
+ .nav-link.active {
4428
+ background: var(--primary-50);
4429
+ color: var(--primary-600);
4430
+ font-weight: 600;
4431
+ }
4432
+
4433
+ .nav-link.active svg,
4434
+ .nav-link.active .material-symbols-outlined {
4435
+ opacity: 1;
4436
+ color: var(--primary-500);
4437
+ }
4438
+
4439
+ .nav-link.active::before {
4440
+ content: '';
4441
+ position: absolute;
4442
+ left: 0;
4443
+ top: 6px;
4444
+ bottom: 6px;
4445
+ width: 3px;
4446
+ background: var(--primary-500);
4447
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
4448
+ }
4449
+
4450
+ .nav-link-label {
4451
+ flex: 1;
4452
+ white-space: nowrap;
4453
+ overflow: hidden;
4454
+ text-overflow: ellipsis;
4455
+ }
4456
+
4457
+ .nav-link--no-icon .nav-link-label {
4458
+ padding-left: 0;
4459
+ }
4460
+
4461
+ .nav-link--no-icon {
4462
+ gap: 0;
4463
+ }
4464
+
4465
+ .nav-link-badge {
4466
+ margin-left: auto;
4467
+ font-family: var(--font-mono);
4468
+ font-size: var(--text-2xs);
4469
+ padding: 1px 6px;
4470
+ background: var(--surface-inset);
4471
+ color: var(--text-secondary);
4472
+ border-radius: var(--radius-full);
4473
+ border: 1px solid var(--surface-border);
4474
+ }
4475
+
4476
+ .nav-tooltip {
4477
+ display: none;
4478
+ position: absolute;
4479
+ left: calc(100% + 8px);
4480
+ top: 50%;
4481
+ transform: translateY(-50%);
4482
+ background: var(--surface-raised);
4483
+ border: 1px solid var(--surface-border);
4484
+ border-radius: var(--radius-md);
4485
+ padding: var(--space-1) var(--space-3);
4486
+ font-size: var(--text-xs);
4487
+ white-space: nowrap;
4488
+ box-shadow: var(--shadow-md);
4489
+ z-index: 50;
4490
+ color: var(--text-primary);
4491
+ }
4492
+
4493
+ .sidebar.collapsed .nav-tooltip {
4494
+ display: block;
4495
+ }
4496
+
4497
+ .admin-sidebar-overlay {
4498
+ display: none;
4499
+ position: fixed;
4500
+ inset: 0;
4501
+ background: rgba(0, 0, 0, 0.4);
4502
+ z-index: 35;
4503
+ }
4504
+
4505
+ .admin-sidebar-overlay.open {
4506
+ display: block;
4507
+ }
4508
+
4509
+ /* ═══════════════════════════════════════════════════════════════════════════
4510
+ TOGGLE SWITCH — Modern Clean Design
4511
+ ═══════════════════════════════════════════════════════════════════════════ */
4512
+
4513
+ .toggle-switch {
4514
+ display: inline-flex;
4515
+ align-items: center;
4516
+ width: 40px;
4517
+ height: 22px;
4518
+ border-radius: var(--radius-full);
4519
+ cursor: pointer;
4520
+ position: relative;
4521
+ transition: background var(--duration-fast);
4522
+ border: none;
4523
+ padding: 0;
4524
+ background: var(--surface-border);
4525
+ }
4526
+
4527
+ .toggle-switch--on {
4528
+ background: var(--primary-500);
4529
+ }
4530
+
4531
+ .toggle-switch__thumb {
4532
+ position: absolute;
4533
+ top: 2px;
4534
+ left: 2px;
4535
+ width: 18px;
4536
+ height: 18px;
4537
+ border-radius: var(--radius-full);
4538
+ background: white;
4539
+ transition: transform var(--duration-fast) var(--easing-out);
4540
+ box-shadow: var(--shadow-sm);
4541
+ }
4542
+
4543
+ .toggle-switch--on .toggle-switch__thumb {
4544
+ transform: translateX(18px);
4545
+ }
4546
+
4547
+ /* ═══════════════════════════════════════════════════════════════════════════
4548
+ RESPONSIVE — List Page
4549
+ ═══════════════════════════════════════════════════════════════════════════ */
4550
+
4551
+ @media (max-width: 1024px) {
4552
+ .admin-sidebar {
4553
+ width: var(--admin-sidebar-width, var(--sidebar-width));
4554
+ position: fixed;
4555
+ left: 0;
4556
+ top: 0;
4557
+ height: 100vh;
4558
+ z-index: 40;
4559
+ transform: translateX(-100%);
4560
+ transition: transform var(--duration-slow) var(--easing-out);
4561
+ }
4562
+
4563
+ .admin-sidebar.open {
4564
+ transform: translateX(0);
4565
+ }
4566
+
4567
+ .admin-content__inner {
4568
+ padding: var(--space-5) var(--space-4);
4569
+ }
4570
+
4571
+ .page-header-title {
4572
+ font-size: var(--text-xl);
4573
+ }
4574
+ }
4575
+
4576
+ @media (max-width: 768px) {
4577
+ .page-header {
4578
+ flex-direction: column;
4579
+ gap: var(--space-3);
4580
+ }
4581
+
4582
+ .filter-bar {
4583
+ flex-direction: column;
4584
+ align-items: stretch;
4585
+ }
4586
+
4587
+ .filter-bar-search {
4588
+ min-width: auto;
4589
+ }
4590
+
4591
+ .filter-bar-right {
4592
+ margin-left: 0;
4593
+ justify-content: flex-end;
4594
+ }
4595
+
4596
+ .table-footer {
4597
+ flex-direction: column;
4598
+ gap: var(--space-3);
4599
+ }
4600
+
4601
+ .pagination {
4602
+ flex-direction: column;
4603
+ gap: var(--space-3);
4604
+ }
4605
+
4606
+ .topbar-center {
4607
+ display: none;
4608
+ }
4609
+ }
4610
+
4611
+ @media (max-width: 480px) {
4612
+ .admin-content__inner {
4613
+ padding: var(--space-4) var(--space-3);
4614
+ }
4615
+
4616
+ .data-table th,
4617
+ .data-table td {
4618
+ padding: var(--space-2) var(--space-3);
4619
+ font-size: var(--text-xs);
4620
+ }
4621
+ }
4622
+
4623
+ /* ── Command Palette (global search) ─────────────────────────────────── */
4624
+
4625
+ .command-palette-backdrop {
4626
+ position: fixed; inset: 0; z-index: 100;
4627
+ background: rgba(0, 0, 0, 0.5);
4628
+ backdrop-filter: blur(4px);
4629
+ display: flex; align-items: flex-start; justify-content: center;
4630
+ padding-top: 15vh;
4631
+ }
4632
+
4633
+ .command-palette {
4634
+ width: 100%; max-width: 560px;
4635
+ background: var(--surface-raised);
4636
+ border: 1px solid var(--surface-border);
4637
+ border-radius: var(--radius-xl);
4638
+ box-shadow: var(--shadow-xl);
4639
+ overflow: hidden;
4640
+ }
4641
+
4642
+ .command-palette-header {
4643
+ display: flex; align-items: center; gap: var(--space-3);
4644
+ padding: var(--space-3) var(--space-4);
4645
+ border-bottom: 1px solid var(--surface-border);
4646
+ }
4647
+
4648
+ .command-palette-header svg { color: var(--text-disabled); flex-shrink: 0; }
4649
+
4650
+ .command-palette-input {
4651
+ flex: 1; border: none; outline: none; background: transparent;
4652
+ font-size: var(--text-base); color: var(--text-primary);
4653
+ font-family: var(--font-sans);
4654
+ }
4655
+ .command-palette-input::placeholder { color: var(--text-disabled); }
4656
+
4657
+ .command-palette-esc {
4658
+ display: inline-flex; align-items: center; justify-content: center;
4659
+ padding: 2px 6px; font-size: var(--text-2xs); font-family: var(--font-mono);
4660
+ background: var(--surface-inset); border: 1px solid var(--surface-border);
4661
+ border-radius: var(--radius-xs); color: var(--text-secondary);
4662
+ }
4663
+
4664
+ .command-palette-results {
4665
+ max-height: 360px; overflow-y: auto;
4666
+ padding: var(--space-2) 0;
4667
+ }
4668
+
4669
+ .command-palette-result {
4670
+ display: flex; align-items: center; gap: var(--space-3);
4671
+ padding: var(--space-2) var(--space-4);
4672
+ text-decoration: none; color: var(--text-primary);
4673
+ transition: background var(--duration-fast);
4674
+ cursor: pointer;
4675
+ }
4676
+ .command-palette-result:hover,
4677
+ .command-palette-result--active {
4678
+ background: var(--surface-inset);
4679
+ }
4680
+
4681
+ .command-palette-result-icon {
4682
+ display: flex; align-items: center; justify-content: center;
4683
+ width: 32px; height: 32px; border-radius: var(--radius-md);
4684
+ background: var(--surface-inset); color: var(--text-secondary);
4685
+ flex-shrink: 0;
4686
+ }
4687
+
4688
+ .command-palette-result-text {
4689
+ flex: 1; min-width: 0;
4690
+ display: flex; flex-direction: column;
4691
+ }
4692
+
4693
+ .command-palette-result-label {
4694
+ font-size: var(--text-sm); font-weight: var(--font-medium);
4695
+ color: var(--text-primary);
4696
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
4697
+ }
4698
+
4699
+ .command-palette-result-sublabel {
4700
+ font-size: var(--text-xs); color: var(--text-secondary);
4701
+ font-family: var(--font-mono);
4702
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
4703
+ }
4704
+
4705
+ .command-palette-result-badge {
4706
+ font-size: var(--text-2xs); font-weight: var(--font-medium);
4707
+ padding: 2px 8px; border-radius: var(--radius-full);
4708
+ text-transform: capitalize; flex-shrink: 0;
4709
+ }
4710
+ .badge-model {
4711
+ background: var(--primary-100); color: var(--primary-700);
4712
+ }
4713
+ .badge-field {
4714
+ background: var(--surface-inset); color: var(--text-secondary);
4715
+ }
4716
+
4717
+ .command-palette-empty {
4718
+ padding: var(--space-8) var(--space-4);
4719
+ text-align: center; color: var(--text-secondary);
4720
+ font-size: var(--text-sm);
4721
+ }
4722
+
4723
+ .command-palette-footer {
4724
+ display: flex; align-items: center; gap: var(--space-4);
4725
+ padding: var(--space-2) var(--space-4);
4726
+ border-top: 1px solid var(--surface-border);
4727
+ font-size: var(--text-2xs); color: var(--text-disabled);
4728
+ }
4729
+ .command-palette-footer kbd {
4730
+ display: inline-flex; align-items: center; justify-content: center;
4731
+ padding: 1px 4px; font-family: var(--font-mono);
4732
+ background: var(--surface-inset); border: 1px solid var(--surface-border);
4733
+ border-radius: var(--radius-xs);
4734
+ margin-right: 2px;
4735
+ }
4736
+