@umituz/web-dashboard 3.2.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +202 -14
  2. package/package.json +21 -29
  3. package/src/domains/analytics/components/AnalyticsCard.tsx +23 -21
  4. package/src/domains/analytics/components/AnalyticsChart.tsx +345 -149
  5. package/src/domains/analytics/components/AnalyticsLayout.tsx +93 -112
  6. package/src/domains/analytics/components/MetricCard.tsx +42 -64
  7. package/src/domains/analytics/hooks/index.ts +7 -1
  8. package/src/domains/analytics/hooks/useAnalytics.ts +144 -139
  9. package/src/domains/analytics/index.ts +11 -0
  10. package/src/domains/analytics/services/AnalyticsEngineService.ts +103 -55
  11. package/src/domains/analytics/services/PerformanceService.ts +117 -69
  12. package/src/domains/analytics/types/analytics.ts +20 -6
  13. package/src/domains/analytics/types/index.ts +3 -0
  14. package/src/domains/analytics/utils/analytics.test.ts +183 -0
  15. package/src/domains/analytics/utils/analytics.ts +26 -9
  16. package/src/domains/analytics/utils/i18nKeys.ts +40 -0
  17. package/src/domains/analytics/utils/index.ts +2 -0
  18. package/src/domains/auth/components/AuthLayout.tsx +63 -54
  19. package/src/domains/auth/components/ForgotPasswordForm.tsx +96 -98
  20. package/src/domains/auth/components/LoginForm.tsx +167 -226
  21. package/src/domains/auth/components/RegisterForm.tsx +202 -272
  22. package/src/domains/auth/components/ResetPasswordForm.tsx +105 -151
  23. package/src/domains/auth/components/shared/AuthErrorBanner.tsx +35 -0
  24. package/src/domains/auth/components/shared/EmailInput.tsx +91 -0
  25. package/src/domains/auth/components/shared/PasswordInput.tsx +119 -0
  26. package/src/domains/auth/components/shared/PasswordStrengthIndicator.tsx +75 -0
  27. package/src/domains/auth/components/shared/SocialLoginButtons.tsx +58 -0
  28. package/src/domains/auth/components/shared/SocialProviderIcons.tsx +48 -0
  29. package/src/domains/auth/components/shared/index.ts +20 -0
  30. package/src/domains/auth/hooks/index.ts +1 -0
  31. package/src/domains/auth/hooks/useAuth.ts +151 -232
  32. package/src/domains/auth/index.ts +8 -4
  33. package/src/domains/auth/types/auth.ts +26 -5
  34. package/src/domains/auth/types/index.ts +1 -0
  35. package/src/domains/auth/utils/auth.test.ts +182 -0
  36. package/src/domains/auth/utils/auth.ts +71 -130
  37. package/src/domains/auth/utils/i18nKeys.ts +127 -0
  38. package/src/domains/auth/utils/index.ts +7 -1
  39. package/src/domains/auth/utils/secureToken.ts +33 -0
  40. package/src/domains/auth/utils/validationKeys.ts +23 -0
  41. package/src/domains/calendar/hooks/useCalendar.ts +145 -151
  42. package/src/domains/calendar/index.ts +0 -1
  43. package/src/domains/calendar/services/CalendarService.ts +122 -179
  44. package/src/domains/calendar/utils/contentItemMapper.test.ts +108 -0
  45. package/src/domains/calendar/utils/contentItemMapper.ts +99 -0
  46. package/src/domains/calendar/utils/index.ts +33 -30
  47. package/src/domains/layouts/components/BrandLogo.tsx +12 -9
  48. package/src/domains/layouts/components/DashboardHeader.tsx +78 -80
  49. package/src/domains/layouts/components/DashboardLayout.tsx +45 -21
  50. package/src/domains/layouts/components/DashboardSidebar.tsx +48 -51
  51. package/src/domains/layouts/types/layout.ts +7 -1
  52. package/src/domains/layouts/types/user.ts +3 -1
  53. package/src/domains/modules/build.test.tsx +97 -0
  54. package/src/domains/modules/build.tsx +71 -0
  55. package/src/domains/modules/index.ts +2 -0
  56. package/src/domains/modules/types.ts +29 -0
  57. package/src/domains/onboarding/components/AppFocusStep.tsx +99 -68
  58. package/src/domains/onboarding/components/OnboardingWizard.tsx +109 -183
  59. package/src/domains/onboarding/components/PlanStep.tsx +156 -123
  60. package/src/domains/onboarding/components/PlatformsStep.tsx +74 -54
  61. package/src/domains/onboarding/components/StepNavigation.tsx +108 -0
  62. package/src/domains/onboarding/components/StepProgress.tsx +62 -0
  63. package/src/domains/onboarding/components/UserTypeStep.tsx +59 -80
  64. package/src/domains/onboarding/components/index.ts +4 -0
  65. package/src/domains/onboarding/hooks/useOnboarding.ts +76 -66
  66. package/src/domains/onboarding/index.ts +1 -0
  67. package/src/domains/onboarding/types/onboarding.ts +57 -17
  68. package/src/domains/onboarding/utils/i18nKeys.ts +72 -0
  69. package/src/domains/onboarding/utils/index.ts +2 -0
  70. package/src/domains/permissions/PermissionsContext.tsx +103 -0
  71. package/src/domains/permissions/hasPermission.test.ts +50 -0
  72. package/src/domains/permissions/hasPermission.ts +38 -0
  73. package/src/domains/permissions/index.ts +19 -0
  74. package/src/domains/permissions/types.ts +35 -0
  75. package/src/domains/permissions/utils/i18nKeys.ts +11 -0
  76. package/src/domains/session/DemoLogin.tsx +50 -0
  77. package/src/domains/session/OrgSwitcher.tsx +110 -0
  78. package/src/domains/session/SessionContext.tsx +150 -0
  79. package/src/domains/session/inMemoryAuthAdapter.ts +53 -0
  80. package/src/domains/session/index.ts +18 -0
  81. package/src/domains/session/types.ts +47 -0
  82. package/src/domains/session/utils/i18nKeys.ts +12 -0
  83. package/src/domains/settings/components/AuditLogList.tsx +59 -0
  84. package/src/domains/settings/components/PermissionMatrixScreen.tsx +80 -0
  85. package/src/domains/settings/components/SettingsLayout.tsx +75 -60
  86. package/src/domains/settings/components/SettingsSection.tsx +35 -22
  87. package/src/domains/settings/components/UserManagementTable.tsx +87 -0
  88. package/src/domains/settings/components/index.ts +10 -0
  89. package/src/domains/settings/hooks/useSettings.ts +77 -52
  90. package/src/domains/settings/types/settings.ts +2 -0
  91. package/src/domains/settings/utils/i18nKeys.ts +18 -0
  92. package/src/domains/settings/utils/settings.ts +11 -4
  93. package/src/i18n/I18nContext.tsx +33 -0
  94. package/src/i18n/defaultT.test.ts +43 -0
  95. package/src/i18n/defaultT.ts +34 -0
  96. package/src/i18n/index.ts +7 -0
  97. package/src/i18n/types.ts +13 -0
  98. package/src/index.ts +1 -7
  99. package/src/primitives/Button.tsx +30 -0
  100. package/src/primitives/Checkbox.tsx +40 -0
  101. package/src/primitives/Input.tsx +19 -0
  102. package/src/primitives/Skeleton.tsx +26 -0
  103. package/src/primitives/cn.ts +15 -0
  104. package/src/primitives/index.ts +23 -0
  105. package/src/styles/dashboard.css +3045 -0
  106. package/src/styles/tokens.contract.test.ts +66 -0
  107. package/src/styles/tokens.css +124 -0
  108. package/src/domains/billing/components/BillingLayout.tsx +0 -63
  109. package/src/domains/billing/components/BillingPage.tsx +0 -49
  110. package/src/domains/billing/components/BillingPortal.tsx +0 -198
  111. package/src/domains/billing/components/InvoiceCard.tsx +0 -143
  112. package/src/domains/billing/components/PaymentMethodsList.tsx +0 -116
  113. package/src/domains/billing/components/PlanComparison.tsx +0 -199
  114. package/src/domains/billing/components/UsageCard.tsx +0 -103
  115. package/src/domains/billing/components/index.ts +0 -13
  116. package/src/domains/billing/constants/billing.ts +0 -69
  117. package/src/domains/billing/hooks/index.ts +0 -7
  118. package/src/domains/billing/hooks/useBilling.ts +0 -385
  119. package/src/domains/billing/index.ts +0 -73
  120. package/src/domains/billing/types/billing.ts +0 -342
  121. package/src/domains/billing/types/index.ts +0 -30
  122. package/src/domains/billing/utils/billing.ts +0 -360
  123. package/src/domains/billing/utils/index.ts +0 -31
  124. package/src/domains/billing/utils/polar.ts +0 -63
  125. package/src/domains/calendar/components/index.ts +0 -7
@@ -0,0 +1,3045 @@
1
+ /**
2
+ * @umituz/web-dashboard — component stylesheet (udb-* BEM)
3
+ *
4
+ * Camp-agnostic by construction:
5
+ * - Every rule sets its own box-sizing / background / border explicitly,
6
+ * so a host's Tailwind preflight (or any other reset) cannot leak in.
7
+ * - Load order still matters with resets that use `*` selectors: import
8
+ * this file AFTER your base layer.
9
+ * - Colors, spacing and typography come exclusively from the `--u-*`
10
+ * tokens (see `tokens.css`); override them for theming and dark mode.
11
+ *
12
+ * Sections:
13
+ * 1. Scope & reset 5. Sidebar 9. Onboarding
14
+ * 2. Primitives 6. Header / menus 10. Settings
15
+ * 3. Layout helpers 7. Auth 11. Analytics
16
+ * 4. App shell 8. Forms (auth) 12. Shared blocks
17
+ */
18
+
19
+ /* ============================================================
20
+ * 1. Scope & reset
21
+ * ============================================================ */
22
+
23
+ .udb-root,
24
+ .udb-root *,
25
+ .udb-root *::before,
26
+ .udb-root *::after {
27
+ box-sizing: border-box;
28
+ }
29
+
30
+ .udb-root {
31
+ font-family: var(--u-font-sans);
32
+ color: var(--u-color-text);
33
+ background: var(--u-color-bg);
34
+ font-size: var(--u-font-size-md);
35
+ line-height: 1.5;
36
+ -webkit-font-smoothing: antialiased;
37
+ }
38
+
39
+ /* Screen-reader-only helper (replaces utility-framework sr-only). */
40
+ .udb-sr-only {
41
+ position: absolute;
42
+ width: 1px;
43
+ height: 1px;
44
+ padding: 0;
45
+ margin: -1px;
46
+ overflow: hidden;
47
+ clip: rect(0 0 0 0);
48
+ white-space: nowrap;
49
+ border: 0;
50
+ }
51
+
52
+ /* ============================================================
53
+ * 2. Primitives — Button
54
+ * ============================================================ */
55
+
56
+ .udb-btn {
57
+ display: inline-flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ gap: var(--u-space-2);
61
+ white-space: nowrap;
62
+ border: 1px solid transparent;
63
+ border-radius: var(--u-radius-md);
64
+ font-family: inherit;
65
+ font-size: var(--u-font-size-md);
66
+ font-weight: var(--u-font-weight-medium);
67
+ line-height: 1;
68
+ cursor: pointer;
69
+ text-decoration: none;
70
+ transition: background-color 0.15s ease, color 0.15s ease,
71
+ border-color 0.15s ease, transform 0.1s ease;
72
+ }
73
+
74
+ .udb-btn:focus-visible {
75
+ outline: none;
76
+ box-shadow: 0 0 0 2px var(--u-color-surface), 0 0 0 4px var(--u-color-ring);
77
+ }
78
+
79
+ .udb-btn:disabled {
80
+ pointer-events: none;
81
+ opacity: 0.55;
82
+ }
83
+
84
+ .udb-btn:active:not(:disabled) {
85
+ transform: scale(0.97);
86
+ }
87
+
88
+ .udb-btn svg {
89
+ pointer-events: none;
90
+ width: 1em;
91
+ height: 1em;
92
+ flex-shrink: 0;
93
+ }
94
+
95
+ /* Variants */
96
+ .udb-btn--default {
97
+ background: var(--u-color-primary);
98
+ color: var(--u-color-primary-contrast);
99
+ }
100
+
101
+ .udb-btn--default:hover:not(:disabled) {
102
+ background: var(--u-color-primary-hover);
103
+ }
104
+
105
+ .udb-btn--destructive {
106
+ background: var(--u-color-danger);
107
+ color: var(--u-color-danger-contrast);
108
+ }
109
+
110
+ .udb-btn--destructive:hover:not(:disabled) {
111
+ background: var(--u-color-danger-hover);
112
+ }
113
+
114
+ .udb-btn--outline {
115
+ background: var(--u-color-surface);
116
+ color: var(--u-color-text);
117
+ border-color: var(--u-color-border-strong);
118
+ }
119
+
120
+ .udb-btn--outline:hover:not(:disabled) {
121
+ background: var(--u-color-surface-muted);
122
+ }
123
+
124
+ .udb-btn--ghost {
125
+ background: transparent;
126
+ color: var(--u-color-text);
127
+ }
128
+
129
+ .udb-btn--ghost:hover:not(:disabled) {
130
+ background: var(--u-color-surface-muted);
131
+ }
132
+
133
+ /* Sizes */
134
+ .udb-btn--default {
135
+ height: 40px;
136
+ padding: 0 var(--u-space-4);
137
+ }
138
+
139
+ .udb-btn--sm {
140
+ height: 32px;
141
+ padding: 0 var(--u-space-3);
142
+ font-size: var(--u-font-size-sm);
143
+ }
144
+
145
+ .udb-btn--icon {
146
+ height: 36px;
147
+ width: 36px;
148
+ padding: 0;
149
+ }
150
+
151
+ /* ============================================================
152
+ * 2. Primitives — Input / Checkbox / Skeleton
153
+ * ============================================================ */
154
+
155
+ .udb-input {
156
+ display: block;
157
+ width: 100%;
158
+ height: 40px;
159
+ padding: 0 var(--u-space-3);
160
+ background: var(--u-color-surface);
161
+ border: 1px solid var(--u-color-border-strong);
162
+ border-radius: var(--u-radius-md);
163
+ color: var(--u-color-text);
164
+ font-family: inherit;
165
+ font-size: var(--u-font-size-md);
166
+ }
167
+
168
+ .udb-input::placeholder {
169
+ color: var(--u-color-muted);
170
+ }
171
+
172
+ .udb-input:focus-visible {
173
+ outline: none;
174
+ border-color: var(--u-color-primary);
175
+ box-shadow: 0 0 0 3px var(--u-color-ring);
176
+ }
177
+
178
+ .udb-input:disabled {
179
+ cursor: not-allowed;
180
+ opacity: 0.55;
181
+ background: var(--u-color-surface-muted);
182
+ }
183
+
184
+ .udb-checkbox {
185
+ width: 18px;
186
+ height: 18px;
187
+ margin: 0;
188
+ accent-color: var(--u-color-primary);
189
+ cursor: pointer;
190
+ flex-shrink: 0;
191
+ }
192
+
193
+ .udb-checkbox:disabled {
194
+ cursor: not-allowed;
195
+ opacity: 0.55;
196
+ }
197
+
198
+ .udb-checkbox:focus-visible {
199
+ outline: none;
200
+ box-shadow: 0 0 0 3px var(--u-color-ring);
201
+ border-radius: var(--u-radius-sm);
202
+ }
203
+
204
+ .udb-skeleton {
205
+ background: var(--u-color-surface-muted);
206
+ animation: udb-pulse 1.6s ease-in-out infinite;
207
+ border-radius: var(--u-radius-md);
208
+ }
209
+
210
+ .udb-skeleton--text {
211
+ height: 16px;
212
+ width: 100%;
213
+ }
214
+
215
+ .udb-skeleton--circular {
216
+ height: 48px;
217
+ width: 48px;
218
+ border-radius: 50%;
219
+ }
220
+
221
+ .udb-skeleton--rectangular {
222
+ height: 96px;
223
+ width: 100%;
224
+ }
225
+
226
+ @keyframes udb-pulse {
227
+ 0%,
228
+ 100% {
229
+ opacity: 1;
230
+ }
231
+ 50% {
232
+ opacity: 0.55;
233
+ }
234
+ }
235
+
236
+ /* ============================================================
237
+ * 3. Layout helpers
238
+ * ============================================================ */
239
+
240
+ .udb-stack {
241
+ display: flex;
242
+ flex-direction: column;
243
+ gap: var(--u-space-5);
244
+ }
245
+
246
+ .udb-row {
247
+ display: flex;
248
+ align-items: center;
249
+ }
250
+
251
+ .udb-grid {
252
+ display: grid;
253
+ gap: var(--u-space-5);
254
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
255
+ }
256
+
257
+ .udb-card {
258
+ background: var(--u-color-surface);
259
+ border: 1px solid var(--u-color-border);
260
+ border-radius: var(--u-radius-lg);
261
+ padding: var(--u-space-6);
262
+ box-shadow: var(--u-shadow-sm);
263
+ }
264
+
265
+ .udb-card--sm {
266
+ padding: var(--u-space-4);
267
+ }
268
+
269
+ .udb-card--lg {
270
+ padding: var(--u-space-8);
271
+ }
272
+
273
+ /* ============================================================
274
+ * 4. App shell
275
+ * ============================================================ */
276
+
277
+ .udb-layout {
278
+ display: flex;
279
+ height: 100vh;
280
+ width: 100%;
281
+ overflow: hidden;
282
+ }
283
+
284
+ .udb-layout__sidebar {
285
+ display: none;
286
+ flex-direction: column;
287
+ flex-shrink: 0;
288
+ width: var(--u-sidebar-width);
289
+ border-right: 1px solid var(--u-sidebar-border);
290
+ background: var(--u-sidebar-bg);
291
+ transition: width 0.3s ease;
292
+ }
293
+
294
+ .udb-layout__sidebar--collapsed {
295
+ width: var(--u-sidebar-width-collapsed);
296
+ }
297
+
298
+ .udb-layout__mobile {
299
+ position: fixed;
300
+ inset: 0;
301
+ z-index: 50;
302
+ }
303
+
304
+ .udb-layout__backdrop {
305
+ position: absolute;
306
+ inset: 0;
307
+ background: rgba(15, 23, 42, 0.45);
308
+ }
309
+
310
+ .udb-layout__mobile-sidebar {
311
+ position: absolute;
312
+ left: 0;
313
+ top: 0;
314
+ height: 100%;
315
+ width: var(--u-sidebar-width);
316
+ border-right: 1px solid var(--u-sidebar-border);
317
+ background: var(--u-sidebar-bg);
318
+ box-shadow: var(--u-shadow-lg);
319
+ }
320
+
321
+ .udb-layout__main {
322
+ display: flex;
323
+ flex: 1;
324
+ flex-direction: column;
325
+ overflow: hidden;
326
+ min-width: 0;
327
+ }
328
+
329
+ .udb-layout__content {
330
+ flex: 1;
331
+ overflow-y: auto;
332
+ padding: var(--u-space-4);
333
+ }
334
+
335
+ /* Full desktop behavior from 768px up. */
336
+ @media (min-width: 768px) {
337
+ .udb-layout__sidebar {
338
+ display: flex;
339
+ }
340
+
341
+ .udb-layout__content {
342
+ padding: var(--u-space-7);
343
+ }
344
+ }
345
+
346
+ /* Route-transition skeleton page. */
347
+ .udb-page-skeleton {
348
+ margin: 0 auto;
349
+ width: 100%;
350
+ max-width: 1280px;
351
+ display: flex;
352
+ flex-direction: column;
353
+ gap: var(--u-space-6);
354
+ }
355
+
356
+ .udb-skeleton--title {
357
+ height: 32px;
358
+ width: 33%;
359
+ border-radius: var(--u-radius-lg);
360
+ }
361
+
362
+ .udb-skeleton-grid {
363
+ display: grid;
364
+ gap: var(--u-space-4);
365
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
366
+ }
367
+
368
+ .udb-skeleton--card {
369
+ height: 112px;
370
+ border-radius: var(--u-radius-xl);
371
+ }
372
+
373
+ .udb-skeleton--section {
374
+ height: 256px;
375
+ border-radius: var(--u-radius-xl);
376
+ }
377
+
378
+ /* ============================================================
379
+ * 5. Sidebar
380
+ * ============================================================ */
381
+
382
+ .udb-sidebar {
383
+ display: flex;
384
+ flex-direction: column;
385
+ height: 100%;
386
+ width: 100%;
387
+ color: var(--u-sidebar-text);
388
+ }
389
+
390
+ .udb-sidebar__brand {
391
+ display: flex;
392
+ height: var(--u-header-height);
393
+ align-items: center;
394
+ gap: var(--u-space-3);
395
+ border-bottom: 1px solid var(--u-sidebar-border);
396
+ padding: 0 var(--u-space-4);
397
+ }
398
+
399
+ .udb-brand-logo {
400
+ flex-shrink: 0;
401
+ }
402
+
403
+ .udb-sidebar__brand-text {
404
+ display: flex;
405
+ flex-direction: column;
406
+ min-width: 0;
407
+ }
408
+
409
+ .udb-sidebar__brand-name {
410
+ font-size: var(--u-font-size-2xl);
411
+ font-weight: 900;
412
+ letter-spacing: -0.04em;
413
+ line-height: 1;
414
+ color: var(--u-sidebar-text);
415
+ }
416
+
417
+ .udb-sidebar__brand-tagline {
418
+ margin-top: var(--u-space-2);
419
+ margin-left: var(--u-space-1);
420
+ font-size: var(--u-font-size-xs);
421
+ font-weight: var(--u-font-weight-bold);
422
+ text-transform: lowercase;
423
+ letter-spacing: -0.02em;
424
+ color: var(--u-color-primary);
425
+ opacity: 0.75;
426
+ user-select: none;
427
+ }
428
+
429
+ .udb-sidebar__create {
430
+ padding: var(--u-space-4) var(--u-space-3);
431
+ border-bottom: 1px solid var(--u-sidebar-border);
432
+ }
433
+
434
+ .udb-sidebar__create-btn {
435
+ width: 100%;
436
+ height: 44px;
437
+ justify-content: flex-start;
438
+ padding: 0 var(--u-space-4);
439
+ border-radius: var(--u-radius-lg);
440
+ box-shadow: var(--u-shadow-md);
441
+ }
442
+
443
+ .udb-sidebar__create-btn--collapsed {
444
+ width: 40px;
445
+ height: 40px;
446
+ padding: 0;
447
+ margin: 0 auto;
448
+ justify-content: center;
449
+ }
450
+
451
+ .udb-sidebar__create-icon {
452
+ width: 16px;
453
+ height: 16px;
454
+ flex-shrink: 0;
455
+ }
456
+
457
+ .udb-sidebar__create-label {
458
+ font-weight: var(--u-font-weight-bold);
459
+ letter-spacing: -0.02em;
460
+ }
461
+
462
+ .udb-sidebar__nav {
463
+ flex: 1;
464
+ overflow-y: auto;
465
+ padding: var(--u-space-3) var(--u-space-2);
466
+ }
467
+
468
+ .udb-sidebar__groups {
469
+ display: flex;
470
+ flex-direction: column;
471
+ gap: var(--u-space-6);
472
+ }
473
+
474
+ .udb-sidebar__group {
475
+ display: flex;
476
+ flex-direction: column;
477
+ gap: var(--u-space-1);
478
+ }
479
+
480
+ .udb-sidebar__group-toggle {
481
+ display: flex;
482
+ width: 100%;
483
+ align-items: center;
484
+ justify-content: space-between;
485
+ margin-bottom: var(--u-space-1);
486
+ padding: var(--u-space-2) var(--u-space-3);
487
+ border: none;
488
+ border-radius: var(--u-radius-md);
489
+ background: transparent;
490
+ cursor: pointer;
491
+ }
492
+
493
+ .udb-sidebar__group-toggle:hover {
494
+ background: var(--u-sidebar-accent);
495
+ }
496
+
497
+ .udb-sidebar__group-title {
498
+ font-size: 10px;
499
+ font-weight: var(--u-font-weight-bold);
500
+ text-transform: uppercase;
501
+ letter-spacing: 0.12em;
502
+ color: var(--u-sidebar-muted);
503
+ opacity: 0.75;
504
+ }
505
+
506
+ .udb-sidebar__group-chevron {
507
+ display: flex;
508
+ flex-shrink: 0;
509
+ }
510
+
511
+ .udb-sidebar__chevron-icon {
512
+ width: 14px;
513
+ height: 14px;
514
+ color: var(--u-sidebar-muted);
515
+ }
516
+
517
+ .udb-sidebar__item {
518
+ display: flex;
519
+ align-items: center;
520
+ gap: var(--u-space-3);
521
+ padding: 10px var(--u-space-3);
522
+ border-radius: var(--u-radius-md);
523
+ font-size: var(--u-font-size-md);
524
+ font-weight: var(--u-font-weight-medium);
525
+ color: var(--u-sidebar-text);
526
+ opacity: 0.75;
527
+ text-decoration: none;
528
+ transition: background-color 0.2s ease, color 0.2s ease;
529
+ }
530
+
531
+ .udb-sidebar__item:hover {
532
+ background: var(--u-sidebar-accent);
533
+ color: var(--u-sidebar-accent-text);
534
+ opacity: 1;
535
+ }
536
+
537
+ .udb-sidebar__item--active {
538
+ background: var(--u-sidebar-accent);
539
+ color: var(--u-sidebar-accent-text);
540
+ opacity: 1;
541
+ box-shadow: var(--u-shadow-sm);
542
+ }
543
+
544
+ .udb-sidebar__item-icon {
545
+ width: 16px;
546
+ height: 16px;
547
+ flex-shrink: 0;
548
+ }
549
+
550
+ .udb-sidebar--collapsed .udb-sidebar__item {
551
+ justify-content: center;
552
+ }
553
+
554
+ .udb-sidebar--collapsed .udb-sidebar__brand,
555
+ .udb-sidebar--collapsed .udb-sidebar__create {
556
+ justify-content: center;
557
+ padding-left: 0;
558
+ padding-right: 0;
559
+ }
560
+
561
+ .udb-sidebar__footer {
562
+ border-top: 1px solid var(--u-sidebar-border);
563
+ padding: var(--u-space-3);
564
+ display: flex;
565
+ align-items: center;
566
+ justify-content: space-between;
567
+ }
568
+
569
+ .udb-sidebar--collapsed .udb-sidebar__footer {
570
+ justify-content: center;
571
+ }
572
+
573
+ .udb-sidebar__footer-label {
574
+ padding: 0 var(--u-space-2);
575
+ font-size: 10px;
576
+ font-weight: var(--u-font-weight-bold);
577
+ text-transform: uppercase;
578
+ letter-spacing: 0.1em;
579
+ color: var(--u-sidebar-muted);
580
+ }
581
+
582
+ .udb-sidebar__footer-btn {
583
+ color: var(--u-sidebar-text);
584
+ }
585
+
586
+ .udb-sidebar__footer-icon {
587
+ width: 16px;
588
+ height: 16px;
589
+ }
590
+
591
+ /* ============================================================
592
+ * 6. Header / menus / notifications / profile
593
+ * ============================================================ */
594
+
595
+ .udb-header {
596
+ display: flex;
597
+ height: var(--u-header-height);
598
+ align-items: center;
599
+ justify-content: space-between;
600
+ flex-shrink: 0;
601
+ gap: var(--u-space-3);
602
+ border-bottom: 1px solid var(--u-color-border);
603
+ background: var(--u-color-surface);
604
+ padding: 0 var(--u-space-4);
605
+ z-index: 30;
606
+ }
607
+
608
+ .udb-header__lead {
609
+ display: flex;
610
+ align-items: center;
611
+ gap: var(--u-space-3);
612
+ min-width: 0;
613
+ }
614
+
615
+ .udb-header__title {
616
+ margin: 0;
617
+ font-size: var(--u-font-size-md);
618
+ font-weight: 600;
619
+ color: var(--u-color-text);
620
+ overflow: hidden;
621
+ text-overflow: ellipsis;
622
+ white-space: nowrap;
623
+ }
624
+
625
+ .udb-header__mobile-toggle {
626
+ display: inline-flex;
627
+ }
628
+
629
+ .udb-header__desktop-toggle {
630
+ display: none;
631
+ }
632
+
633
+ @media (min-width: 768px) {
634
+ .udb-header__mobile-toggle {
635
+ display: none;
636
+ }
637
+
638
+ .udb-header__desktop-toggle {
639
+ display: inline-flex;
640
+ }
641
+ }
642
+
643
+ .udb-header__actions {
644
+ display: flex;
645
+ align-items: center;
646
+ gap: var(--u-space-2);
647
+ }
648
+
649
+ .udb-header__icon-btn {
650
+ height: 36px;
651
+ width: 36px;
652
+ color: var(--u-color-muted);
653
+ }
654
+
655
+ .udb-header__icon {
656
+ width: 16px;
657
+ height: 16px;
658
+ }
659
+
660
+ .udb-header__toggle-icon {
661
+ width: 20px;
662
+ height: 20px;
663
+ }
664
+
665
+ .udb-header__anchor {
666
+ position: relative;
667
+ display: inline-flex;
668
+ }
669
+
670
+ .udb-header__unread {
671
+ position: absolute;
672
+ top: 6px;
673
+ right: 6px;
674
+ display: flex;
675
+ width: 8px;
676
+ height: 8px;
677
+ }
678
+
679
+ .udb-header__unread-core {
680
+ position: relative;
681
+ display: inline-flex;
682
+ width: 8px;
683
+ height: 8px;
684
+ border-radius: 50%;
685
+ background: var(--u-color-danger);
686
+ }
687
+
688
+ .udb-header__unread-core::before {
689
+ content: "";
690
+ position: absolute;
691
+ inset: 0;
692
+ border-radius: 50%;
693
+ background: var(--u-color-danger);
694
+ animation: udb-ping 1.2s cubic-bezier(0, 0, 0.2, 1) infinite;
695
+ }
696
+
697
+ @keyframes udb-ping {
698
+ 0% {
699
+ transform: scale(1);
700
+ opacity: 0.7;
701
+ }
702
+ 75%,
703
+ 100% {
704
+ transform: scale(2.2);
705
+ opacity: 0;
706
+ }
707
+ }
708
+
709
+ .udb-header__divider {
710
+ width: 1px;
711
+ height: 24px;
712
+ margin: 0 var(--u-space-1);
713
+ background: var(--u-color-border);
714
+ }
715
+
716
+ /* Click-outside layer for popover menus. */
717
+ .udb-overlay {
718
+ position: fixed;
719
+ inset: 0;
720
+ z-index: 40;
721
+ }
722
+
723
+ /* Generic popover menu. */
724
+ .udb-menu {
725
+ position: absolute;
726
+ top: 48px;
727
+ right: 0;
728
+ min-width: 224px;
729
+ background: var(--u-color-surface);
730
+ border: 1px solid var(--u-color-border);
731
+ border-radius: var(--u-radius-lg);
732
+ box-shadow: var(--u-shadow-lg);
733
+ overflow: hidden;
734
+ z-index: 50;
735
+ animation: udb-pop 0.18s ease;
736
+ }
737
+
738
+ @keyframes udb-pop {
739
+ from {
740
+ opacity: 0;
741
+ transform: scale(0.96) translateY(-4px);
742
+ }
743
+ to {
744
+ opacity: 1;
745
+ transform: none;
746
+ }
747
+ }
748
+
749
+ .udb-menu__header {
750
+ display: flex;
751
+ align-items: center;
752
+ justify-content: space-between;
753
+ padding: var(--u-space-3) var(--u-space-4);
754
+ border-bottom: 1px solid var(--u-color-border);
755
+ background: var(--u-color-surface-muted);
756
+ }
757
+
758
+ .udb-menu__heading {
759
+ margin: 0;
760
+ font-size: var(--u-font-size-sm);
761
+ font-weight: var(--u-font-weight-bold);
762
+ text-transform: uppercase;
763
+ letter-spacing: 0.08em;
764
+ color: var(--u-color-text);
765
+ }
766
+
767
+ .udb-menu__action {
768
+ border: none;
769
+ background: transparent;
770
+ padding: 0;
771
+ font-size: 10px;
772
+ font-weight: var(--u-font-weight-bold);
773
+ text-transform: uppercase;
774
+ color: var(--u-color-primary);
775
+ cursor: pointer;
776
+ }
777
+
778
+ .udb-menu__action:hover {
779
+ text-decoration: underline;
780
+ }
781
+
782
+ .udb-menu__item {
783
+ display: flex;
784
+ width: 100%;
785
+ align-items: center;
786
+ gap: 10px;
787
+ padding: var(--u-space-2) var(--u-space-3);
788
+ border: none;
789
+ border-radius: var(--u-radius-md);
790
+ background: transparent;
791
+ font-family: inherit;
792
+ font-size: var(--u-font-size-md);
793
+ color: var(--u-color-text);
794
+ cursor: pointer;
795
+ text-align: left;
796
+ }
797
+
798
+ .udb-menu__item:hover {
799
+ background: var(--u-color-surface-muted);
800
+ }
801
+
802
+ .udb-menu__item--danger {
803
+ color: var(--u-color-danger);
804
+ font-weight: var(--u-font-weight-medium);
805
+ }
806
+
807
+ .udb-menu__item--danger:hover {
808
+ background: var(--u-color-danger-soft);
809
+ }
810
+
811
+ .udb-menu__item-icon {
812
+ width: 16px;
813
+ height: 16px;
814
+ color: var(--u-color-muted);
815
+ flex-shrink: 0;
816
+ }
817
+
818
+ .udb-menu__item--danger .udb-menu__item-icon {
819
+ color: var(--u-color-danger);
820
+ }
821
+
822
+ /* Notifications popover. */
823
+ .udb-notif {
824
+ width: 320px;
825
+ }
826
+
827
+ .udb-notif__list {
828
+ max-height: 400px;
829
+ overflow-y: auto;
830
+ }
831
+
832
+ .udb-notif__item {
833
+ display: flex;
834
+ align-items: flex-start;
835
+ gap: var(--u-space-3);
836
+ padding: var(--u-space-3) var(--u-space-4);
837
+ border-bottom: 1px solid var(--u-color-border);
838
+ }
839
+
840
+ .udb-notif__item:last-child {
841
+ border-bottom: none;
842
+ }
843
+
844
+ .udb-notif__item:hover {
845
+ background: var(--u-color-surface-muted);
846
+ }
847
+
848
+ .udb-notif__item--unread {
849
+ background: var(--u-color-primary-soft);
850
+ }
851
+
852
+ .udb-notif__body {
853
+ flex: 1;
854
+ min-width: 0;
855
+ }
856
+
857
+ .udb-notif__text {
858
+ margin: 0;
859
+ font-size: var(--u-font-size-md);
860
+ line-height: 1.35;
861
+ color: var(--u-color-text);
862
+ }
863
+
864
+ .udb-notif__meta {
865
+ display: flex;
866
+ align-items: center;
867
+ gap: var(--u-space-1);
868
+ margin: var(--u-space-1) 0 0;
869
+ font-size: 10px;
870
+ color: var(--u-color-muted);
871
+ }
872
+
873
+ .udb-notif__dot {
874
+ display: inline-block;
875
+ width: 4px;
876
+ height: 4px;
877
+ border-radius: 50%;
878
+ background: var(--u-color-muted);
879
+ opacity: 0.5;
880
+ }
881
+
882
+ .udb-notif__dismiss {
883
+ display: flex;
884
+ flex-shrink: 0;
885
+ border: none;
886
+ padding: 0;
887
+ background: transparent;
888
+ color: var(--u-color-muted);
889
+ cursor: pointer;
890
+ }
891
+
892
+ .udb-notif__dismiss:hover {
893
+ color: var(--u-color-text);
894
+ }
895
+
896
+ .udb-notif__dismiss-icon {
897
+ width: 12px;
898
+ height: 12px;
899
+ }
900
+
901
+ .udb-notif__empty {
902
+ padding: var(--u-space-8) var(--u-space-4);
903
+ text-align: center;
904
+ }
905
+
906
+ .udb-notif__empty-icon {
907
+ display: flex;
908
+ width: 40px;
909
+ height: 40px;
910
+ align-items: center;
911
+ justify-content: center;
912
+ margin: 0 auto var(--u-space-3);
913
+ border-radius: 50%;
914
+ background: var(--u-color-surface-muted);
915
+ }
916
+
917
+ .udb-notif__empty-bell {
918
+ width: 20px;
919
+ height: 20px;
920
+ color: var(--u-color-muted);
921
+ opacity: 0.6;
922
+ }
923
+
924
+ .udb-notif__empty-text {
925
+ margin: 0;
926
+ font-size: var(--u-font-size-md);
927
+ color: var(--u-color-muted);
928
+ }
929
+
930
+ /* Profile trigger & menu. */
931
+ .udb-profile-btn {
932
+ display: flex;
933
+ align-items: center;
934
+ gap: var(--u-space-2);
935
+ padding: var(--u-space-1);
936
+ border: none;
937
+ border-radius: var(--u-radius-pill);
938
+ background: transparent;
939
+ cursor: pointer;
940
+ }
941
+
942
+ .udb-profile-btn:hover {
943
+ background: var(--u-color-surface-muted);
944
+ }
945
+
946
+ .udb-avatar {
947
+ display: flex;
948
+ width: 32px;
949
+ height: 32px;
950
+ align-items: center;
951
+ justify-content: center;
952
+ border-radius: 50%;
953
+ border: 1px solid var(--u-color-primary);
954
+ background: var(--u-color-primary-soft);
955
+ color: var(--u-color-primary);
956
+ font-size: 10px;
957
+ font-weight: var(--u-font-weight-bold);
958
+ overflow: hidden;
959
+ }
960
+
961
+ .udb-avatar__img {
962
+ width: 100%;
963
+ height: 100%;
964
+ object-fit: cover;
965
+ display: block;
966
+ }
967
+
968
+ .udb-profile-btn__chevron {
969
+ width: 16px;
970
+ height: 16px;
971
+ color: var(--u-color-muted);
972
+ transition: transform 0.2s ease;
973
+ }
974
+
975
+ .udb-profile-btn__chevron--open {
976
+ transform: rotate(180deg);
977
+ }
978
+
979
+ .udb-profile-menu {
980
+ width: 224px;
981
+ padding: var(--u-space-2);
982
+ }
983
+
984
+ .udb-profile-menu__id {
985
+ padding: var(--u-space-2) var(--u-space-3);
986
+ border-bottom: 1px solid var(--u-color-border);
987
+ margin-bottom: var(--u-space-1);
988
+ }
989
+
990
+ .udb-profile-menu__name {
991
+ margin: 0;
992
+ font-size: var(--u-font-size-md);
993
+ font-weight: var(--u-font-weight-bold);
994
+ color: var(--u-color-text);
995
+ }
996
+
997
+ .udb-profile-menu__email {
998
+ margin: 0;
999
+ font-size: var(--u-font-size-sm);
1000
+ color: var(--u-color-muted);
1001
+ overflow: hidden;
1002
+ text-overflow: ellipsis;
1003
+ white-space: nowrap;
1004
+ }
1005
+
1006
+ .udb-profile-menu__items {
1007
+ display: flex;
1008
+ flex-direction: column;
1009
+ }
1010
+
1011
+ .udb-profile-menu__separator {
1012
+ height: 1px;
1013
+ margin: var(--u-space-2) 0;
1014
+ background: var(--u-color-border);
1015
+ }
1016
+
1017
+ /* ============================================================
1018
+ * 7. Auth pages
1019
+ * ============================================================ */
1020
+
1021
+ .udb-auth {
1022
+ display: flex;
1023
+ flex-direction: column;
1024
+ min-height: 100dvh;
1025
+ background: var(--u-color-bg);
1026
+ }
1027
+
1028
+ .udb-auth__header {
1029
+ display: flex;
1030
+ align-items: center;
1031
+ justify-content: space-between;
1032
+ gap: var(--u-space-3);
1033
+ padding: var(--u-space-4) var(--u-space-6);
1034
+ }
1035
+
1036
+ .udb-auth__brand {
1037
+ display: flex;
1038
+ align-items: center;
1039
+ gap: var(--u-space-2);
1040
+ }
1041
+
1042
+ .udb-auth__brand-name {
1043
+ font-size: var(--u-font-size-lg);
1044
+ font-weight: var(--u-font-weight-bold);
1045
+ letter-spacing: -0.02em;
1046
+ color: var(--u-color-text);
1047
+ }
1048
+
1049
+ .udb-auth__home-link {
1050
+ font-size: var(--u-font-size-md);
1051
+ color: var(--u-color-muted);
1052
+ text-decoration: none;
1053
+ }
1054
+
1055
+ .udb-auth__home-link:hover {
1056
+ color: var(--u-color-text);
1057
+ text-decoration: underline;
1058
+ }
1059
+
1060
+ .udb-auth__main {
1061
+ display: flex;
1062
+ flex: 1;
1063
+ align-items: center;
1064
+ justify-content: center;
1065
+ padding: var(--u-space-6) var(--u-space-4);
1066
+ }
1067
+
1068
+ .udb-auth__column {
1069
+ display: flex;
1070
+ flex-direction: column;
1071
+ width: 100%;
1072
+ max-width: 420px;
1073
+ }
1074
+
1075
+ .udb-auth__card {
1076
+ background: var(--u-color-surface);
1077
+ border: 1px solid var(--u-color-border);
1078
+ border-radius: var(--u-radius-xl);
1079
+ box-shadow: var(--u-shadow-lg);
1080
+ padding: var(--u-space-8) var(--u-space-7);
1081
+ }
1082
+
1083
+ .udb-auth__tagline {
1084
+ margin: 0 0 var(--u-space-5);
1085
+ text-align: center;
1086
+ font-size: var(--u-font-size-xs);
1087
+ font-weight: var(--u-font-weight-bold);
1088
+ text-transform: uppercase;
1089
+ letter-spacing: 0.1em;
1090
+ color: var(--u-color-primary);
1091
+ }
1092
+
1093
+ .udb-auth__social {
1094
+ margin-top: var(--u-space-5);
1095
+ }
1096
+
1097
+ .udb-auth__footer {
1098
+ padding: var(--u-space-4) var(--u-space-6);
1099
+ }
1100
+
1101
+ .udb-auth__footer-inner {
1102
+ display: flex;
1103
+ flex-direction: column;
1104
+ align-items: center;
1105
+ gap: var(--u-space-2);
1106
+ text-align: center;
1107
+ font-size: var(--u-font-size-xs);
1108
+ color: var(--u-color-muted);
1109
+ }
1110
+
1111
+ .udb-auth__footer-inner > p {
1112
+ margin: 0;
1113
+ }
1114
+
1115
+ .udb-auth__footer-links {
1116
+ display: flex;
1117
+ align-items: center;
1118
+ justify-content: center;
1119
+ flex-wrap: wrap;
1120
+ gap: var(--u-space-4);
1121
+ }
1122
+
1123
+ .udb-auth__footer-link {
1124
+ font-size: var(--u-font-size-xs);
1125
+ color: var(--u-color-muted);
1126
+ text-decoration: none;
1127
+ }
1128
+
1129
+ .udb-auth__footer-link:hover {
1130
+ color: var(--u-color-text);
1131
+ text-decoration: underline;
1132
+ }
1133
+
1134
+ /* "Or continue with" divider. */
1135
+ .udb-divider-row {
1136
+ display: flex;
1137
+ align-items: center;
1138
+ gap: var(--u-space-3);
1139
+ margin: var(--u-space-5) 0;
1140
+ }
1141
+
1142
+ .udb-divider-row::before,
1143
+ .udb-divider-row::after {
1144
+ content: "";
1145
+ flex: 1;
1146
+ height: 1px;
1147
+ background: var(--u-color-border);
1148
+ }
1149
+
1150
+ .udb-divider-row__label {
1151
+ font-size: var(--u-font-size-xs);
1152
+ font-weight: var(--u-font-weight-medium);
1153
+ text-transform: uppercase;
1154
+ letter-spacing: 0.06em;
1155
+ color: var(--u-color-muted);
1156
+ white-space: nowrap;
1157
+ }
1158
+
1159
+ /* Social provider buttons. */
1160
+ .udb-social-grid {
1161
+ display: grid;
1162
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1163
+ gap: var(--u-space-3);
1164
+ }
1165
+
1166
+ .udb-social-grid__btn {
1167
+ width: 100%;
1168
+ }
1169
+
1170
+ .udb-social-grid__icon {
1171
+ width: 16px;
1172
+ height: 16px;
1173
+ flex-shrink: 0;
1174
+ }
1175
+
1176
+ /* Standalone social button (AuthLayout provider grid). */
1177
+ .udb-social-btn {
1178
+ display: inline-flex;
1179
+ align-items: center;
1180
+ justify-content: center;
1181
+ gap: var(--u-space-2);
1182
+ height: 40px;
1183
+ padding: 0 var(--u-space-3);
1184
+ border: 1px solid var(--u-color-border-strong);
1185
+ border-radius: var(--u-radius-md);
1186
+ background: var(--u-color-surface);
1187
+ color: var(--u-color-text);
1188
+ font-family: inherit;
1189
+ font-size: var(--u-font-size-md);
1190
+ font-weight: var(--u-font-weight-medium);
1191
+ cursor: pointer;
1192
+ }
1193
+
1194
+ .udb-social-btn:hover {
1195
+ background: var(--u-color-surface-muted);
1196
+ }
1197
+
1198
+ .udb-social-btn__icon {
1199
+ display: inline-flex;
1200
+ align-items: center;
1201
+ justify-content: center;
1202
+ flex-shrink: 0;
1203
+ }
1204
+
1205
+ .udb-social-btn__icon svg {
1206
+ width: 16px;
1207
+ height: 16px;
1208
+ }
1209
+
1210
+ /* ============================================================
1211
+ * 8. Forms (auth + generic fields)
1212
+ * ============================================================ */
1213
+
1214
+ /* Shared spinner (also used by onboarding/analytics icons). */
1215
+ @keyframes udb-spin {
1216
+ to {
1217
+ transform: rotate(360deg);
1218
+ }
1219
+ }
1220
+
1221
+ .udb-spin {
1222
+ animation: udb-spin 1s linear infinite;
1223
+ }
1224
+
1225
+ .udb-form {
1226
+ display: flex;
1227
+ flex-direction: column;
1228
+ gap: var(--u-space-4);
1229
+ width: 100%;
1230
+ }
1231
+
1232
+ .udb-form__header {
1233
+ display: flex;
1234
+ flex-direction: column;
1235
+ gap: var(--u-space-1);
1236
+ text-align: center;
1237
+ }
1238
+
1239
+ .udb-form__title {
1240
+ margin: 0;
1241
+ font-size: var(--u-font-size-2xl);
1242
+ font-weight: var(--u-font-weight-bold);
1243
+ letter-spacing: -0.02em;
1244
+ line-height: 1.2;
1245
+ color: var(--u-color-text);
1246
+ }
1247
+
1248
+ .udb-form__title--lg {
1249
+ font-size: var(--u-font-size-3xl);
1250
+ }
1251
+
1252
+ .udb-form__subtitle {
1253
+ margin: 0;
1254
+ font-size: var(--u-font-size-md);
1255
+ color: var(--u-color-muted);
1256
+ }
1257
+
1258
+ .udb-form__subtitle-strong {
1259
+ color: var(--u-color-text);
1260
+ font-weight: var(--u-font-weight-medium);
1261
+ }
1262
+
1263
+ .udb-form__row {
1264
+ display: flex;
1265
+ align-items: center;
1266
+ justify-content: space-between;
1267
+ gap: var(--u-space-3);
1268
+ font-size: var(--u-font-size-md);
1269
+ }
1270
+
1271
+ .udb-form__footer-text {
1272
+ margin: 0;
1273
+ text-align: center;
1274
+ font-size: var(--u-font-size-md);
1275
+ color: var(--u-color-muted);
1276
+ }
1277
+
1278
+ /* Tighter group inside a form (e.g. password + strength meter). */
1279
+ .udb-form__group {
1280
+ display: flex;
1281
+ flex-direction: column;
1282
+ gap: var(--u-space-3);
1283
+ }
1284
+
1285
+ /* Single labeled field. */
1286
+ .udb-field {
1287
+ display: flex;
1288
+ flex-direction: column;
1289
+ gap: 6px;
1290
+ }
1291
+
1292
+ .udb-field__label {
1293
+ font-size: var(--u-font-size-md);
1294
+ font-weight: var(--u-font-weight-medium);
1295
+ color: var(--u-color-text);
1296
+ }
1297
+
1298
+ .udb-field__required {
1299
+ margin-left: 2px;
1300
+ color: var(--u-color-danger);
1301
+ }
1302
+
1303
+ .udb-field__error {
1304
+ margin: 0;
1305
+ font-size: var(--u-font-size-sm);
1306
+ color: var(--u-color-danger);
1307
+ }
1308
+
1309
+ /* Inline error banner. */
1310
+ .udb-form-alert {
1311
+ display: flex;
1312
+ align-items: flex-start;
1313
+ gap: var(--u-space-2);
1314
+ padding: 10px var(--u-space-3);
1315
+ border-radius: var(--u-radius-md);
1316
+ background: var(--u-color-danger-soft);
1317
+ color: var(--u-color-danger);
1318
+ font-size: var(--u-font-size-md);
1319
+ }
1320
+
1321
+ .udb-form-alert__icon {
1322
+ width: 16px;
1323
+ height: 16px;
1324
+ flex-shrink: 0;
1325
+ margin-top: 2px;
1326
+ }
1327
+
1328
+ /* Checkbox line (remember me, terms). */
1329
+ .udb-check-label {
1330
+ display: flex;
1331
+ align-items: center;
1332
+ gap: var(--u-space-2);
1333
+ font-size: var(--u-font-size-md);
1334
+ color: var(--u-color-muted);
1335
+ cursor: pointer;
1336
+ }
1337
+
1338
+ .udb-check-label--multiline {
1339
+ align-items: flex-start;
1340
+ }
1341
+
1342
+ .udb-check-label__text {
1343
+ flex: 1;
1344
+ line-height: 1.45;
1345
+ }
1346
+
1347
+ /* Inline text buttons ("Forgot password?", "Sign up"). */
1348
+ .udb-link-btn {
1349
+ display: inline;
1350
+ border: none;
1351
+ padding: 0;
1352
+ background: transparent;
1353
+ font-family: inherit;
1354
+ font-size: var(--u-font-size-md);
1355
+ color: var(--u-color-primary);
1356
+ cursor: pointer;
1357
+ }
1358
+
1359
+ .udb-link-btn:hover {
1360
+ text-decoration: underline;
1361
+ }
1362
+
1363
+ .udb-link-btn:disabled {
1364
+ pointer-events: none;
1365
+ opacity: 0.55;
1366
+ }
1367
+
1368
+ .udb-link-btn--strong {
1369
+ font-weight: 600;
1370
+ }
1371
+
1372
+ .udb-text-link {
1373
+ color: var(--u-color-primary);
1374
+ text-decoration: none;
1375
+ }
1376
+
1377
+ .udb-text-link:hover {
1378
+ text-decoration: underline;
1379
+ }
1380
+
1381
+ /* Full-width submit button. */
1382
+ .udb-submit-btn {
1383
+ width: 100%;
1384
+ height: 44px;
1385
+ }
1386
+
1387
+ .udb-submit-btn--pill {
1388
+ height: 48px;
1389
+ border-radius: var(--u-radius-pill);
1390
+ }
1391
+
1392
+ .udb-btn__spinner {
1393
+ animation: udb-spin 1s linear infinite;
1394
+ }
1395
+
1396
+ /* Password field with visibility toggle. */
1397
+ .udb-password-wrap {
1398
+ position: relative;
1399
+ width: 100%;
1400
+ }
1401
+
1402
+ .udb-input--with-toggle {
1403
+ padding-right: 44px;
1404
+ }
1405
+
1406
+ .udb-password-toggle {
1407
+ position: absolute;
1408
+ right: 2px;
1409
+ top: 50%;
1410
+ transform: translateY(-50%);
1411
+ }
1412
+
1413
+ .udb-password-toggle__icon {
1414
+ width: 16px;
1415
+ height: 16px;
1416
+ color: var(--u-color-muted);
1417
+ }
1418
+
1419
+ .udb-input--error {
1420
+ border-color: var(--u-color-danger);
1421
+ }
1422
+
1423
+ .udb-input--error:focus-visible {
1424
+ border-color: var(--u-color-danger);
1425
+ box-shadow: 0 0 0 3px var(--u-color-danger-soft);
1426
+ }
1427
+
1428
+ /* Password strength meter. */
1429
+ .udb-strength {
1430
+ display: flex;
1431
+ flex-direction: column;
1432
+ gap: 6px;
1433
+ margin-top: var(--u-space-1);
1434
+ }
1435
+
1436
+ .udb-strength__bars {
1437
+ display: grid;
1438
+ grid-template-columns: repeat(4, minmax(0, 1fr));
1439
+ gap: var(--u-space-2);
1440
+ }
1441
+
1442
+ .udb-strength__bar {
1443
+ height: 4px;
1444
+ border-radius: var(--u-radius-pill);
1445
+ background: var(--u-color-border-strong);
1446
+ transition: background-color 0.2s ease;
1447
+ }
1448
+
1449
+ .udb-strength__bar--weak {
1450
+ background: var(--u-color-danger);
1451
+ }
1452
+
1453
+ .udb-strength__bar--fair {
1454
+ background: var(--u-color-warning);
1455
+ }
1456
+
1457
+ .udb-strength__bar--good {
1458
+ background: var(--u-color-primary);
1459
+ }
1460
+
1461
+ .udb-strength__bar--strong {
1462
+ background: var(--u-color-success);
1463
+ }
1464
+
1465
+ .udb-strength__label {
1466
+ margin: 0;
1467
+ font-size: var(--u-font-size-xs);
1468
+ color: var(--u-color-muted);
1469
+ }
1470
+
1471
+ .udb-strength__label--weak {
1472
+ color: var(--u-color-danger);
1473
+ }
1474
+
1475
+ .udb-strength__label--fair {
1476
+ color: var(--u-color-warning);
1477
+ }
1478
+
1479
+ .udb-strength__label--good {
1480
+ color: var(--u-color-primary);
1481
+ }
1482
+
1483
+ .udb-strength__label--strong {
1484
+ color: var(--u-color-success);
1485
+ }
1486
+
1487
+ /* Success badge + ordered steps (forgot-password done state). */
1488
+ .udb-success-badge {
1489
+ display: flex;
1490
+ align-items: center;
1491
+ justify-content: center;
1492
+ width: 48px;
1493
+ height: 48px;
1494
+ margin: 0 auto var(--u-space-4);
1495
+ border-radius: 50%;
1496
+ background: var(--u-color-success-soft);
1497
+ }
1498
+
1499
+ .udb-success-badge__icon {
1500
+ width: 24px;
1501
+ height: 24px;
1502
+ color: var(--u-color-success);
1503
+ }
1504
+
1505
+ .udb-steps-list {
1506
+ display: flex;
1507
+ flex-direction: column;
1508
+ gap: var(--u-space-3);
1509
+ margin: var(--u-space-4) 0 0;
1510
+ padding: 0;
1511
+ list-style: none;
1512
+ }
1513
+
1514
+ .udb-steps-list__item {
1515
+ display: flex;
1516
+ align-items: flex-start;
1517
+ gap: var(--u-space-2);
1518
+ font-size: var(--u-font-size-md);
1519
+ color: var(--u-color-text);
1520
+ }
1521
+
1522
+ .udb-steps-list__icon {
1523
+ width: 16px;
1524
+ height: 16px;
1525
+ flex-shrink: 0;
1526
+ margin-top: 2px;
1527
+ color: var(--u-color-success);
1528
+ }
1529
+
1530
+ .udb-back-link {
1531
+ display: inline-flex;
1532
+ align-items: center;
1533
+ gap: 6px;
1534
+ margin-top: var(--u-space-4);
1535
+ border: none;
1536
+ padding: 0;
1537
+ background: transparent;
1538
+ font-family: inherit;
1539
+ font-size: var(--u-font-size-md);
1540
+ color: var(--u-color-muted);
1541
+ cursor: pointer;
1542
+ }
1543
+
1544
+ .udb-back-link:hover {
1545
+ color: var(--u-color-text);
1546
+ }
1547
+
1548
+ .udb-back-link__icon {
1549
+ width: 14px;
1550
+ height: 14px;
1551
+ }
1552
+
1553
+ /* ============================================================
1554
+ * 9. Onboarding wizard
1555
+ * ============================================================ */
1556
+
1557
+ .udb-onboarding {
1558
+ display: flex;
1559
+ flex-direction: column;
1560
+ min-height: 100dvh;
1561
+ background: var(--u-color-bg);
1562
+ }
1563
+
1564
+ .udb-onboarding__header {
1565
+ display: flex;
1566
+ align-items: center;
1567
+ justify-content: space-between;
1568
+ gap: var(--u-space-3);
1569
+ padding: var(--u-space-3) var(--u-space-5);
1570
+ border-bottom: 1px solid var(--u-color-border);
1571
+ background: var(--u-color-surface);
1572
+ }
1573
+
1574
+ .udb-onboarding__brand {
1575
+ display: flex;
1576
+ align-items: center;
1577
+ gap: var(--u-space-2);
1578
+ }
1579
+
1580
+ .udb-onboarding__brand-name {
1581
+ font-size: var(--u-font-size-lg);
1582
+ font-weight: var(--u-font-weight-bold);
1583
+ letter-spacing: -0.02em;
1584
+ color: var(--u-color-text);
1585
+ }
1586
+
1587
+ .udb-onboarding__header-actions {
1588
+ display: flex;
1589
+ align-items: center;
1590
+ gap: var(--u-space-2);
1591
+ }
1592
+
1593
+ .udb-onboarding__main {
1594
+ display: flex;
1595
+ flex: 1;
1596
+ justify-content: center;
1597
+ align-items: flex-start;
1598
+ overflow-y: auto;
1599
+ padding: var(--u-space-6) var(--u-space-4);
1600
+ }
1601
+
1602
+ .udb-onboarding__content {
1603
+ display: flex;
1604
+ flex-direction: column;
1605
+ gap: var(--u-space-6);
1606
+ width: 100%;
1607
+ }
1608
+
1609
+ .udb-onboarding__error {
1610
+ display: flex;
1611
+ align-items: flex-start;
1612
+ gap: var(--u-space-2);
1613
+ padding: 10px var(--u-space-3);
1614
+ border-radius: var(--u-radius-md);
1615
+ background: var(--u-color-danger-soft);
1616
+ color: var(--u-color-danger);
1617
+ font-size: var(--u-font-size-md);
1618
+ }
1619
+
1620
+ .udb-onboarding__error svg {
1621
+ width: 16px;
1622
+ height: 16px;
1623
+ flex-shrink: 0;
1624
+ margin-top: 2px;
1625
+ }
1626
+
1627
+ .udb-onboarding__empty {
1628
+ padding: var(--u-space-8) var(--u-space-6);
1629
+ text-align: center;
1630
+ color: var(--u-color-muted);
1631
+ }
1632
+
1633
+ .udb-onboarding__footer {
1634
+ display: flex;
1635
+ align-items: center;
1636
+ justify-content: space-between;
1637
+ gap: var(--u-space-3);
1638
+ padding: var(--u-space-4) var(--u-space-5);
1639
+ border-top: 1px solid var(--u-color-border);
1640
+ background: var(--u-color-surface);
1641
+ }
1642
+
1643
+ .udb-onboarding__footer-actions {
1644
+ display: flex;
1645
+ align-items: center;
1646
+ gap: var(--u-space-2);
1647
+ }
1648
+
1649
+ .udb-onboarding__footer-icon {
1650
+ width: 16px;
1651
+ height: 16px;
1652
+ }
1653
+
1654
+ .udb-onboarding__footer-btn,
1655
+ .udb-onboarding__footer-next {
1656
+ min-width: 96px;
1657
+ }
1658
+
1659
+ /* Step progress rail (node + connector per segment). */
1660
+ .udb-progress {
1661
+ display: flex;
1662
+ align-items: center;
1663
+ width: 100%;
1664
+ max-width: 420px;
1665
+ margin: 0 auto;
1666
+ }
1667
+
1668
+ .udb-progress__segment {
1669
+ display: flex;
1670
+ align-items: center;
1671
+ flex: 1;
1672
+ min-width: 0;
1673
+ }
1674
+
1675
+ .udb-progress__segment:last-child {
1676
+ flex: 0;
1677
+ }
1678
+
1679
+ .udb-progress__node {
1680
+ display: flex;
1681
+ align-items: center;
1682
+ justify-content: center;
1683
+ width: 28px;
1684
+ height: 28px;
1685
+ flex-shrink: 0;
1686
+ border: 2px solid var(--u-color-border-strong);
1687
+ border-radius: 50%;
1688
+ background: var(--u-color-surface);
1689
+ color: var(--u-color-muted);
1690
+ font-size: var(--u-font-size-sm);
1691
+ font-weight: var(--u-font-weight-bold);
1692
+ transition: background-color 0.2s ease, border-color 0.2s ease,
1693
+ color 0.2s ease;
1694
+ }
1695
+
1696
+ .udb-progress__node--on {
1697
+ border-color: var(--u-color-primary);
1698
+ background: var(--u-color-primary);
1699
+ color: var(--u-color-primary-contrast);
1700
+ }
1701
+
1702
+ .udb-progress__check {
1703
+ width: 14px;
1704
+ height: 14px;
1705
+ }
1706
+
1707
+ .udb-progress__connector {
1708
+ flex: 1;
1709
+ height: 2px;
1710
+ min-width: 12px;
1711
+ margin: 0 var(--u-space-2);
1712
+ border-radius: var(--u-radius-pill);
1713
+ background: var(--u-color-border-strong);
1714
+ transition: background-color 0.2s ease;
1715
+ }
1716
+
1717
+ .udb-progress__connector--on {
1718
+ background: var(--u-color-primary);
1719
+ }
1720
+
1721
+ /* Single step card. Width modifiers keep wide option grids readable. */
1722
+ .udb-step {
1723
+ display: flex;
1724
+ flex-direction: column;
1725
+ gap: var(--u-space-5);
1726
+ width: 100%;
1727
+ max-width: 560px;
1728
+ margin: 0 auto;
1729
+ }
1730
+
1731
+ .udb-step--wide {
1732
+ max-width: 720px;
1733
+ }
1734
+
1735
+ .udb-step--widest {
1736
+ max-width: 840px;
1737
+ }
1738
+
1739
+ .udb-step__header {
1740
+ display: flex;
1741
+ flex-direction: column;
1742
+ gap: 6px;
1743
+ text-align: center;
1744
+ }
1745
+
1746
+ .udb-step__title {
1747
+ margin: 0;
1748
+ font-size: var(--u-font-size-3xl);
1749
+ font-weight: var(--u-font-weight-bold);
1750
+ letter-spacing: -0.02em;
1751
+ line-height: 1.2;
1752
+ color: var(--u-color-text);
1753
+ }
1754
+
1755
+ .udb-step__description {
1756
+ margin: 0;
1757
+ font-size: var(--u-font-size-md);
1758
+ color: var(--u-color-muted);
1759
+ }
1760
+
1761
+ .udb-step__description--lg {
1762
+ font-size: var(--u-font-size-lg);
1763
+ }
1764
+
1765
+ .udb-step__options {
1766
+ display: grid;
1767
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
1768
+ gap: var(--u-space-3);
1769
+ }
1770
+
1771
+ .udb-step__options--list {
1772
+ grid-template-columns: 1fr;
1773
+ }
1774
+
1775
+ .udb-step__hint {
1776
+ display: flex;
1777
+ align-items: flex-start;
1778
+ gap: var(--u-space-2);
1779
+ margin-top: var(--u-space-1);
1780
+ font-size: var(--u-font-size-sm);
1781
+ color: var(--u-color-muted);
1782
+ }
1783
+
1784
+ .udb-step__hint-icon {
1785
+ width: 16px;
1786
+ height: 16px;
1787
+ flex-shrink: 0;
1788
+ margin-top: 2px;
1789
+ }
1790
+
1791
+ /* Selectable option card (user type, focus area...). */
1792
+ .udb-choice {
1793
+ position: relative;
1794
+ display: flex;
1795
+ align-items: flex-start;
1796
+ gap: var(--u-space-3);
1797
+ padding: var(--u-space-4);
1798
+ border: 1px solid var(--u-color-border-strong);
1799
+ border-radius: var(--u-radius-lg);
1800
+ background: var(--u-color-surface);
1801
+ font-family: inherit;
1802
+ text-align: left;
1803
+ cursor: pointer;
1804
+ transition: border-color 0.15s ease, background-color 0.15s ease,
1805
+ box-shadow 0.15s ease;
1806
+ }
1807
+
1808
+ .udb-choice:hover {
1809
+ border-color: var(--u-color-primary);
1810
+ }
1811
+
1812
+ .udb-choice--selected {
1813
+ border-color: var(--u-color-primary);
1814
+ background: var(--u-color-primary-soft);
1815
+ box-shadow: inset 0 0 0 1px var(--u-color-primary);
1816
+ }
1817
+
1818
+ .udb-choice__check {
1819
+ position: absolute;
1820
+ top: var(--u-space-3);
1821
+ right: var(--u-space-3);
1822
+ display: flex;
1823
+ align-items: center;
1824
+ justify-content: center;
1825
+ width: 20px;
1826
+ height: 20px;
1827
+ border: 1px solid var(--u-color-border-strong);
1828
+ border-radius: 50%;
1829
+ background: var(--u-color-surface);
1830
+ transition: background-color 0.15s ease, border-color 0.15s ease;
1831
+ }
1832
+
1833
+ .udb-choice__check--on {
1834
+ border-color: var(--u-color-primary);
1835
+ background: var(--u-color-primary);
1836
+ }
1837
+
1838
+ .udb-choice__check-icon {
1839
+ width: 12px;
1840
+ height: 12px;
1841
+ color: var(--u-color-primary-contrast);
1842
+ }
1843
+
1844
+ .udb-choice__icon-box {
1845
+ display: flex;
1846
+ align-items: center;
1847
+ justify-content: center;
1848
+ width: 40px;
1849
+ height: 40px;
1850
+ flex-shrink: 0;
1851
+ border-radius: var(--u-radius-md);
1852
+ background: var(--u-color-surface-muted);
1853
+ }
1854
+
1855
+ .udb-choice__icon-box--lg {
1856
+ width: 48px;
1857
+ height: 48px;
1858
+ }
1859
+
1860
+ .udb-choice__icon-box--on {
1861
+ background: var(--u-color-primary-soft);
1862
+ }
1863
+
1864
+ .udb-choice__icon {
1865
+ width: 20px;
1866
+ height: 20px;
1867
+ color: var(--u-color-text);
1868
+ }
1869
+
1870
+ .udb-choice__icon--lg {
1871
+ width: 24px;
1872
+ height: 24px;
1873
+ }
1874
+
1875
+ .udb-choice__body {
1876
+ display: flex;
1877
+ flex-direction: column;
1878
+ gap: 4px;
1879
+ flex: 1;
1880
+ min-width: 0;
1881
+ }
1882
+
1883
+ .udb-choice__label-row {
1884
+ display: flex;
1885
+ align-items: center;
1886
+ justify-content: space-between;
1887
+ gap: var(--u-space-2);
1888
+ }
1889
+
1890
+ .udb-choice__label {
1891
+ font-size: var(--u-font-size-md);
1892
+ font-weight: var(--u-font-weight-medium);
1893
+ color: var(--u-color-text);
1894
+ }
1895
+
1896
+ .udb-choice__label--lg {
1897
+ font-size: var(--u-font-size-lg);
1898
+ font-weight: 600;
1899
+ }
1900
+
1901
+ .udb-choice__badge {
1902
+ padding: 2px var(--u-space-2);
1903
+ border-radius: var(--u-radius-pill);
1904
+ background: var(--u-color-surface-muted);
1905
+ font-size: var(--u-font-size-xs);
1906
+ font-weight: var(--u-font-weight-medium);
1907
+ color: var(--u-color-muted);
1908
+ white-space: nowrap;
1909
+ }
1910
+
1911
+ .udb-choice__description {
1912
+ margin: 0;
1913
+ font-size: var(--u-font-size-sm);
1914
+ color: var(--u-color-muted);
1915
+ }
1916
+
1917
+ /* Platform connection grid. */
1918
+ .udb-platforms {
1919
+ display: grid;
1920
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
1921
+ gap: var(--u-space-3);
1922
+ }
1923
+
1924
+ .udb-platform {
1925
+ display: flex;
1926
+ align-items: center;
1927
+ gap: var(--u-space-3);
1928
+ padding: var(--u-space-3);
1929
+ border: 1px solid var(--u-color-border-strong);
1930
+ border-radius: var(--u-radius-lg);
1931
+ background: var(--u-color-surface);
1932
+ font-family: inherit;
1933
+ text-align: left;
1934
+ cursor: pointer;
1935
+ transition: border-color 0.15s ease, background-color 0.15s ease;
1936
+ }
1937
+
1938
+ .udb-platform:hover {
1939
+ border-color: var(--u-color-primary);
1940
+ }
1941
+
1942
+ .udb-platform--connected {
1943
+ border-color: var(--u-color-primary);
1944
+ background: var(--u-color-primary-soft);
1945
+ }
1946
+
1947
+ .udb-platform__icon-box {
1948
+ display: flex;
1949
+ align-items: center;
1950
+ justify-content: center;
1951
+ width: 40px;
1952
+ height: 40px;
1953
+ flex-shrink: 0;
1954
+ border-radius: 50%;
1955
+ background: var(--u-color-surface-muted);
1956
+ }
1957
+
1958
+ .udb-platform__icon {
1959
+ width: 20px;
1960
+ height: 20px;
1961
+ }
1962
+
1963
+ .udb-platform__meta {
1964
+ display: flex;
1965
+ flex-direction: column;
1966
+ gap: 2px;
1967
+ flex: 1;
1968
+ min-width: 0;
1969
+ }
1970
+
1971
+ .udb-platform__name {
1972
+ font-size: var(--u-font-size-md);
1973
+ font-weight: var(--u-font-weight-medium);
1974
+ color: var(--u-color-text);
1975
+ }
1976
+
1977
+ .udb-platform__state {
1978
+ font-size: var(--u-font-size-xs);
1979
+ color: var(--u-color-muted);
1980
+ }
1981
+
1982
+ .udb-platform__state--on {
1983
+ color: var(--u-color-success);
1984
+ font-weight: var(--u-font-weight-medium);
1985
+ }
1986
+
1987
+ /* Billing cycle switch (monthly / yearly + save badge). */
1988
+ .udb-cycle-toggle-row {
1989
+ display: flex;
1990
+ align-items: center;
1991
+ justify-content: space-between;
1992
+ flex-wrap: wrap;
1993
+ gap: var(--u-space-2);
1994
+ }
1995
+
1996
+ .udb-cycle-toggle {
1997
+ display: inline-flex;
1998
+ align-items: center;
1999
+ gap: 2px;
2000
+ padding: 3px;
2001
+ border: 1px solid var(--u-color-border);
2002
+ border-radius: var(--u-radius-pill);
2003
+ background: var(--u-color-surface-muted);
2004
+ }
2005
+
2006
+ .udb-cycle-toggle__pill {
2007
+ display: inline-flex;
2008
+ align-items: center;
2009
+ gap: var(--u-space-1);
2010
+ border: none;
2011
+ padding: 6px var(--u-space-4);
2012
+ border-radius: var(--u-radius-pill);
2013
+ background: transparent;
2014
+ font-family: inherit;
2015
+ font-size: var(--u-font-size-sm);
2016
+ font-weight: var(--u-font-weight-medium);
2017
+ color: var(--u-color-muted);
2018
+ cursor: pointer;
2019
+ transition: background-color 0.15s ease, color 0.15s ease,
2020
+ box-shadow 0.15s ease;
2021
+ }
2022
+
2023
+ .udb-cycle-toggle__pill--on {
2024
+ background: var(--u-color-surface);
2025
+ color: var(--u-color-text);
2026
+ box-shadow: var(--u-shadow-sm);
2027
+ }
2028
+
2029
+ /* Yearly pill hosts the save badge; keep it on one line when it appears. */
2030
+ .udb-cycle-toggle__pill--with-badge {
2031
+ white-space: nowrap;
2032
+ }
2033
+
2034
+ .udb-cycle-toggle__save {
2035
+ display: none;
2036
+ font-size: 10px;
2037
+ font-weight: var(--u-font-weight-bold);
2038
+ color: var(--u-color-success);
2039
+ }
2040
+
2041
+ .udb-cycle-toggle__save--on {
2042
+ display: inline;
2043
+ }
2044
+
2045
+ /* Plan cards. */
2046
+ .udb-plans {
2047
+ display: grid;
2048
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
2049
+ gap: var(--u-space-4);
2050
+ align-items: stretch;
2051
+ }
2052
+
2053
+ .udb-plan {
2054
+ position: relative;
2055
+ display: flex;
2056
+ flex-direction: column;
2057
+ gap: var(--u-space-3);
2058
+ padding: var(--u-space-5);
2059
+ border: 1px solid var(--u-color-border-strong);
2060
+ border-radius: var(--u-radius-lg);
2061
+ background: var(--u-color-surface);
2062
+ font-family: inherit;
2063
+ text-align: left;
2064
+ cursor: pointer;
2065
+ transition: border-color 0.15s ease, background-color 0.15s ease,
2066
+ box-shadow 0.15s ease;
2067
+ }
2068
+
2069
+ .udb-plan:hover {
2070
+ border-color: var(--u-color-primary);
2071
+ }
2072
+
2073
+ .udb-plan--selected {
2074
+ border-color: var(--u-color-primary);
2075
+ background: var(--u-color-primary-soft);
2076
+ box-shadow: inset 0 0 0 1px var(--u-color-primary);
2077
+ }
2078
+
2079
+ .udb-plan--highlight {
2080
+ border-color: var(--u-color-primary);
2081
+ box-shadow: var(--u-shadow-md);
2082
+ }
2083
+
2084
+ .udb-plan__recommended {
2085
+ position: absolute;
2086
+ top: calc(-1 * var(--u-space-3));
2087
+ left: 50%;
2088
+ transform: translateX(-50%);
2089
+ padding: 2px var(--u-space-3);
2090
+ border-radius: var(--u-radius-pill);
2091
+ background: var(--u-color-primary);
2092
+ color: var(--u-color-primary-contrast);
2093
+ font-size: 10px;
2094
+ font-weight: var(--u-font-weight-bold);
2095
+ text-transform: uppercase;
2096
+ letter-spacing: 0.06em;
2097
+ white-space: nowrap;
2098
+ }
2099
+
2100
+ .udb-plan__heading {
2101
+ display: flex;
2102
+ align-items: center;
2103
+ justify-content: space-between;
2104
+ gap: var(--u-space-2);
2105
+ }
2106
+
2107
+ .udb-plan__name {
2108
+ margin: 0;
2109
+ font-size: var(--u-font-size-lg);
2110
+ font-weight: var(--u-font-weight-bold);
2111
+ color: var(--u-color-text);
2112
+ }
2113
+
2114
+ .udb-plan__badge {
2115
+ padding: 2px var(--u-space-2);
2116
+ border-radius: var(--u-radius-pill);
2117
+ font-size: var(--u-font-size-xs);
2118
+ font-weight: var(--u-font-weight-medium);
2119
+ white-space: nowrap;
2120
+ }
2121
+
2122
+ .udb-plan__badge--muted {
2123
+ background: var(--u-color-surface-muted);
2124
+ color: var(--u-color-muted);
2125
+ }
2126
+
2127
+ .udb-plan__badge--primary {
2128
+ background: var(--u-color-primary-soft);
2129
+ color: var(--u-color-primary);
2130
+ }
2131
+
2132
+ .udb-plan__badge--accent {
2133
+ background: var(--u-color-success-soft);
2134
+ color: var(--u-color-success);
2135
+ }
2136
+
2137
+ .udb-plan__description {
2138
+ margin: 0;
2139
+ font-size: var(--u-font-size-sm);
2140
+ color: var(--u-color-muted);
2141
+ }
2142
+
2143
+ .udb-plan__price-row {
2144
+ display: flex;
2145
+ align-items: baseline;
2146
+ gap: var(--u-space-1);
2147
+ }
2148
+
2149
+ .udb-plan__price {
2150
+ font-size: var(--u-font-size-3xl);
2151
+ font-weight: var(--u-font-weight-bold);
2152
+ letter-spacing: -0.02em;
2153
+ color: var(--u-color-text);
2154
+ }
2155
+
2156
+ .udb-plan__price-unit {
2157
+ font-size: var(--u-font-size-sm);
2158
+ color: var(--u-color-muted);
2159
+ }
2160
+
2161
+ .udb-plan__features {
2162
+ display: flex;
2163
+ flex-direction: column;
2164
+ gap: var(--u-space-2);
2165
+ margin: 0;
2166
+ padding: 0;
2167
+ list-style: none;
2168
+ }
2169
+
2170
+ .udb-plan__feature {
2171
+ display: flex;
2172
+ align-items: flex-start;
2173
+ gap: var(--u-space-2);
2174
+ font-size: var(--u-font-size-sm);
2175
+ color: var(--u-color-text);
2176
+ }
2177
+
2178
+ .udb-plan__feature-check {
2179
+ display: flex;
2180
+ align-items: center;
2181
+ justify-content: center;
2182
+ width: 16px;
2183
+ height: 16px;
2184
+ flex-shrink: 0;
2185
+ margin-top: 2px;
2186
+ border-radius: 50%;
2187
+ background: var(--u-color-success-soft);
2188
+ }
2189
+
2190
+ .udb-plan__feature-check-icon {
2191
+ width: 10px;
2192
+ height: 10px;
2193
+ color: var(--u-color-success);
2194
+ }
2195
+
2196
+ .udb-plan__feature-text {
2197
+ line-height: 1.4;
2198
+ }
2199
+
2200
+ .udb-plan__feature-text--bold {
2201
+ font-weight: var(--u-font-weight-medium);
2202
+ }
2203
+
2204
+ /* ============================================================
2205
+ * 10. Settings
2206
+ * ============================================================ */
2207
+
2208
+ .udb-settings {
2209
+ display: flex;
2210
+ width: 100%;
2211
+ height: 100vh;
2212
+ overflow: hidden;
2213
+ background: var(--u-color-bg);
2214
+ }
2215
+
2216
+ .udb-settings__sidebar {
2217
+ display: none;
2218
+ flex-direction: column;
2219
+ flex-shrink: 0;
2220
+ width: 280px;
2221
+ border-right: 1px solid var(--u-color-border);
2222
+ background: var(--u-color-surface);
2223
+ transition: width 0.3s ease;
2224
+ }
2225
+
2226
+ .udb-settings__sidebar--collapsed {
2227
+ width: 72px;
2228
+ overflow: hidden;
2229
+ }
2230
+
2231
+ .udb-settings__sidebar-header {
2232
+ display: flex;
2233
+ align-items: center;
2234
+ justify-content: space-between;
2235
+ gap: var(--u-space-2);
2236
+ padding: var(--u-space-4);
2237
+ border-bottom: 1px solid var(--u-color-border);
2238
+ }
2239
+
2240
+ .udb-settings__sidebar-title {
2241
+ margin: 0;
2242
+ font-size: var(--u-font-size-lg);
2243
+ font-weight: var(--u-font-weight-bold);
2244
+ color: var(--u-color-text);
2245
+ white-space: nowrap;
2246
+ overflow: hidden;
2247
+ text-overflow: ellipsis;
2248
+ }
2249
+
2250
+ .udb-settings__sidebar-toggle {
2251
+ display: inline-flex;
2252
+ flex-shrink: 0;
2253
+ }
2254
+
2255
+ .udb-settings__toggle-icon {
2256
+ width: 20px;
2257
+ height: 20px;
2258
+ }
2259
+
2260
+ .udb-settings__toggle-icon-lg {
2261
+ width: 24px;
2262
+ height: 24px;
2263
+ }
2264
+
2265
+ .udb-settings__nav {
2266
+ flex: 1;
2267
+ overflow-y: auto;
2268
+ padding: var(--u-space-3) var(--u-space-2);
2269
+ }
2270
+
2271
+ .udb-settings__mobile {
2272
+ position: fixed;
2273
+ inset: 0;
2274
+ z-index: 50;
2275
+ }
2276
+
2277
+ .udb-settings__mobile-sidebar {
2278
+ position: absolute;
2279
+ left: 0;
2280
+ top: 0;
2281
+ height: 100%;
2282
+ width: 280px;
2283
+ overflow-y: auto;
2284
+ border-right: 1px solid var(--u-color-border);
2285
+ background: var(--u-color-surface);
2286
+ box-shadow: var(--u-shadow-lg);
2287
+ }
2288
+
2289
+ .udb-backdrop {
2290
+ position: absolute;
2291
+ inset: 0;
2292
+ background: rgba(15, 23, 42, 0.45);
2293
+ }
2294
+
2295
+ .udb-settings__main {
2296
+ display: flex;
2297
+ flex: 1;
2298
+ flex-direction: column;
2299
+ overflow: hidden;
2300
+ min-width: 0;
2301
+ }
2302
+
2303
+ .udb-settings__mobile-header {
2304
+ display: flex;
2305
+ align-items: center;
2306
+ justify-content: space-between;
2307
+ gap: var(--u-space-3);
2308
+ padding: var(--u-space-3) var(--u-space-4);
2309
+ border-bottom: 1px solid var(--u-color-border);
2310
+ background: var(--u-color-surface);
2311
+ }
2312
+
2313
+ .udb-settings__mobile-lead {
2314
+ display: flex;
2315
+ align-items: center;
2316
+ gap: var(--u-space-2);
2317
+ min-width: 0;
2318
+ }
2319
+
2320
+ .udb-settings__mobile-title {
2321
+ margin: 0;
2322
+ font-size: var(--u-font-size-md);
2323
+ font-weight: 600;
2324
+ color: var(--u-color-text);
2325
+ white-space: nowrap;
2326
+ overflow: hidden;
2327
+ text-overflow: ellipsis;
2328
+ }
2329
+
2330
+ .udb-settings__content {
2331
+ flex: 1;
2332
+ overflow-y: auto;
2333
+ padding: var(--u-space-5) var(--u-space-4);
2334
+ }
2335
+
2336
+ .udb-settings__skeleton {
2337
+ display: flex;
2338
+ flex-direction: column;
2339
+ gap: var(--u-space-4);
2340
+ max-width: 640px;
2341
+ }
2342
+
2343
+ .udb-settings__skeleton-list {
2344
+ display: flex;
2345
+ flex-direction: column;
2346
+ gap: var(--u-space-2);
2347
+ }
2348
+
2349
+ .udb-settings__skeleton-row {
2350
+ height: 14px;
2351
+ width: 100%;
2352
+ border-radius: var(--u-radius-sm);
2353
+ }
2354
+
2355
+ @media (min-width: 768px) {
2356
+ .udb-settings__sidebar {
2357
+ display: flex;
2358
+ }
2359
+
2360
+ .udb-settings__mobile,
2361
+ .udb-settings__mobile-header {
2362
+ display: none;
2363
+ }
2364
+
2365
+ .udb-settings__content {
2366
+ padding: var(--u-space-8);
2367
+ }
2368
+ }
2369
+
2370
+ /* Settings nav sections (shared by desktop & mobile drawers). */
2371
+ .udb-settings-nav {
2372
+ display: flex;
2373
+ flex-direction: column;
2374
+ gap: var(--u-space-5);
2375
+ }
2376
+
2377
+ .udb-settings-nav__title {
2378
+ margin: 0;
2379
+ padding: 0 var(--u-space-3);
2380
+ font-size: 10px;
2381
+ font-weight: var(--u-font-weight-bold);
2382
+ text-transform: uppercase;
2383
+ letter-spacing: 0.1em;
2384
+ color: var(--u-color-muted);
2385
+ }
2386
+
2387
+ .udb-settings-nav__items {
2388
+ display: flex;
2389
+ flex-direction: column;
2390
+ gap: 2px;
2391
+ }
2392
+
2393
+ .udb-settings-nav__item {
2394
+ display: flex;
2395
+ width: 100%;
2396
+ align-items: center;
2397
+ gap: var(--u-space-3);
2398
+ padding: var(--u-space-2) var(--u-space-3);
2399
+ border: none;
2400
+ border-radius: var(--u-radius-md);
2401
+ background: transparent;
2402
+ font-family: inherit;
2403
+ font-size: var(--u-font-size-md);
2404
+ color: var(--u-color-text);
2405
+ opacity: 0.75;
2406
+ text-align: left;
2407
+ text-decoration: none;
2408
+ cursor: pointer;
2409
+ transition: background-color 0.15s ease, color 0.15s ease;
2410
+ }
2411
+
2412
+ .udb-settings-nav__item:hover {
2413
+ background: var(--u-color-surface-muted);
2414
+ opacity: 1;
2415
+ }
2416
+
2417
+ .udb-settings-nav__item--active {
2418
+ background: var(--u-color-primary-soft);
2419
+ color: var(--u-color-primary);
2420
+ opacity: 1;
2421
+ font-weight: var(--u-font-weight-medium);
2422
+ }
2423
+
2424
+ .udb-settings-nav__item-icon {
2425
+ width: 16px;
2426
+ height: 16px;
2427
+ flex-shrink: 0;
2428
+ }
2429
+
2430
+ .udb-settings-nav__item-label {
2431
+ flex: 1;
2432
+ min-width: 0;
2433
+ white-space: nowrap;
2434
+ overflow: hidden;
2435
+ text-overflow: ellipsis;
2436
+ }
2437
+
2438
+ .udb-settings-nav__badge {
2439
+ padding: 1px var(--u-space-2);
2440
+ border-radius: var(--u-radius-pill);
2441
+ background: var(--u-color-primary-soft);
2442
+ color: var(--u-color-primary);
2443
+ font-size: 10px;
2444
+ font-weight: var(--u-font-weight-bold);
2445
+ }
2446
+
2447
+ .udb-settings-nav__chevron {
2448
+ width: 14px;
2449
+ height: 14px;
2450
+ color: var(--u-color-muted);
2451
+ flex-shrink: 0;
2452
+ }
2453
+
2454
+ /* ============================================================
2455
+ * 11. Analytics
2456
+ * ============================================================ */
2457
+
2458
+ .udb-analytics {
2459
+ display: flex;
2460
+ flex-direction: column;
2461
+ gap: var(--u-space-6);
2462
+ width: 100%;
2463
+ }
2464
+
2465
+ .udb-analytics__header {
2466
+ display: flex;
2467
+ align-items: center;
2468
+ justify-content: space-between;
2469
+ flex-wrap: wrap;
2470
+ gap: var(--u-space-3);
2471
+ }
2472
+
2473
+ .udb-analytics__heading {
2474
+ min-width: 0;
2475
+ }
2476
+
2477
+ .udb-analytics__title {
2478
+ margin: 0;
2479
+ font-size: var(--u-font-size-3xl);
2480
+ font-weight: var(--u-font-weight-bold);
2481
+ letter-spacing: -0.02em;
2482
+ line-height: 1.2;
2483
+ color: var(--u-color-text);
2484
+ }
2485
+
2486
+ .udb-analytics__description {
2487
+ margin: var(--u-space-1) 0 0;
2488
+ font-size: var(--u-font-size-md);
2489
+ color: var(--u-color-muted);
2490
+ }
2491
+
2492
+ .udb-analytics__actions {
2493
+ display: flex;
2494
+ align-items: center;
2495
+ flex-wrap: wrap;
2496
+ gap: var(--u-space-2);
2497
+ }
2498
+
2499
+ .udb-analytics__action-icon {
2500
+ width: 16px;
2501
+ height: 16px;
2502
+ }
2503
+
2504
+ .udb-analytics__loading {
2505
+ display: flex;
2506
+ align-items: center;
2507
+ justify-content: center;
2508
+ padding: var(--u-space-8) 0;
2509
+ }
2510
+
2511
+ .udb-analytics__loading-spinner {
2512
+ width: 48px;
2513
+ height: 48px;
2514
+ color: var(--u-color-muted);
2515
+ }
2516
+
2517
+ .udb-analytics__metrics {
2518
+ display: grid;
2519
+ grid-template-columns: 1fr;
2520
+ gap: var(--u-space-4);
2521
+ }
2522
+
2523
+ .udb-analytics__charts {
2524
+ display: grid;
2525
+ grid-template-columns: 1fr;
2526
+ gap: var(--u-space-6);
2527
+ }
2528
+
2529
+ @media (min-width: 640px) {
2530
+ .udb-analytics__metrics {
2531
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2532
+ }
2533
+ }
2534
+
2535
+ @media (min-width: 1024px) {
2536
+ .udb-analytics__metrics--wide {
2537
+ grid-template-columns: repeat(4, minmax(0, 1fr));
2538
+ }
2539
+
2540
+ .udb-analytics__charts {
2541
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2542
+ }
2543
+ }
2544
+
2545
+ /* Period selector chip. */
2546
+ .udb-period-select {
2547
+ display: flex;
2548
+ align-items: center;
2549
+ gap: var(--u-space-2);
2550
+ height: 36px;
2551
+ padding: 0 var(--u-space-3);
2552
+ border: 1px solid var(--u-color-border-strong);
2553
+ border-radius: var(--u-radius-md);
2554
+ background: var(--u-color-surface);
2555
+ }
2556
+
2557
+ .udb-period-select__icon {
2558
+ width: 16px;
2559
+ height: 16px;
2560
+ color: var(--u-color-muted);
2561
+ flex-shrink: 0;
2562
+ }
2563
+
2564
+ .udb-period-select__select {
2565
+ height: 100%;
2566
+ border: none;
2567
+ background: transparent;
2568
+ font-family: inherit;
2569
+ font-size: var(--u-font-size-sm);
2570
+ color: var(--u-color-text);
2571
+ outline: none;
2572
+ cursor: pointer;
2573
+ }
2574
+
2575
+ /* KPI tile. */
2576
+ .udb-metric {
2577
+ background: var(--u-color-surface);
2578
+ border: 1px solid var(--u-color-border);
2579
+ border-radius: var(--u-radius-lg);
2580
+ padding: var(--u-space-6);
2581
+ box-shadow: var(--u-shadow-sm);
2582
+ }
2583
+
2584
+ .udb-metric--sm {
2585
+ padding: var(--u-space-4);
2586
+ }
2587
+
2588
+ .udb-metric--lg {
2589
+ padding: var(--u-space-8);
2590
+ }
2591
+
2592
+ .udb-metric--interactive {
2593
+ cursor: pointer;
2594
+ transition: border-color 0.15s ease, box-shadow 0.15s ease;
2595
+ }
2596
+
2597
+ .udb-metric--interactive:hover {
2598
+ border-color: var(--u-color-primary);
2599
+ }
2600
+
2601
+ .udb-metric--interactive:focus-visible {
2602
+ outline: none;
2603
+ box-shadow: 0 0 0 3px var(--u-color-ring);
2604
+ }
2605
+
2606
+ .udb-metric__head {
2607
+ display: flex;
2608
+ align-items: flex-start;
2609
+ justify-content: space-between;
2610
+ gap: var(--u-space-3);
2611
+ }
2612
+
2613
+ .udb-metric__body {
2614
+ flex: 1;
2615
+ min-width: 0;
2616
+ }
2617
+
2618
+ .udb-metric__name {
2619
+ margin: 0 0 var(--u-space-1);
2620
+ font-size: var(--u-font-size-md);
2621
+ font-weight: var(--u-font-weight-medium);
2622
+ color: var(--u-color-muted);
2623
+ }
2624
+
2625
+ .udb-metric__value {
2626
+ font-size: var(--u-font-size-3xl);
2627
+ font-weight: var(--u-font-weight-bold);
2628
+ letter-spacing: -0.02em;
2629
+ line-height: 1.2;
2630
+ color: var(--u-color-text);
2631
+ }
2632
+
2633
+ .udb-metric--sm .udb-metric__name {
2634
+ font-size: var(--u-font-size-sm);
2635
+ }
2636
+
2637
+ .udb-metric--sm .udb-metric__value {
2638
+ font-size: var(--u-font-size-xl);
2639
+ }
2640
+
2641
+ .udb-metric--lg .udb-metric__name {
2642
+ font-size: var(--u-font-size-lg);
2643
+ }
2644
+
2645
+ .udb-metric--lg .udb-metric__value {
2646
+ font-size: var(--u-font-size-4xl);
2647
+ }
2648
+
2649
+ /* Trend row: one modifier tones the icon + value together;
2650
+ * the "vs last period" label stays muted. */
2651
+ .udb-metric__trend {
2652
+ display: flex;
2653
+ align-items: center;
2654
+ gap: var(--u-space-1);
2655
+ margin-top: var(--u-space-2);
2656
+ color: var(--u-color-muted);
2657
+ }
2658
+
2659
+ .udb-metric__trend--up {
2660
+ color: var(--u-color-success);
2661
+ }
2662
+
2663
+ .udb-metric__trend--down {
2664
+ color: var(--u-color-danger);
2665
+ }
2666
+
2667
+ .udb-metric__trend-icon {
2668
+ width: 16px;
2669
+ height: 16px;
2670
+ flex-shrink: 0;
2671
+ }
2672
+
2673
+ .udb-metric__trend-value {
2674
+ font-size: var(--u-font-size-md);
2675
+ font-weight: var(--u-font-weight-medium);
2676
+ }
2677
+
2678
+ .udb-metric__trend-period {
2679
+ font-size: var(--u-font-size-md);
2680
+ color: var(--u-color-muted);
2681
+ }
2682
+
2683
+ .udb-metric__icon-box {
2684
+ display: flex;
2685
+ align-items: center;
2686
+ justify-content: center;
2687
+ width: 48px;
2688
+ height: 48px;
2689
+ flex-shrink: 0;
2690
+ border-radius: var(--u-radius-md);
2691
+ background: var(--u-color-primary-soft);
2692
+ }
2693
+
2694
+ .udb-metric__icon {
2695
+ width: 24px;
2696
+ height: 24px;
2697
+ color: var(--u-color-primary);
2698
+ }
2699
+
2700
+ /* Chart card internals. */
2701
+ .udb-analytics-card__status {
2702
+ display: flex;
2703
+ align-items: center;
2704
+ justify-content: center;
2705
+ gap: var(--u-space-3);
2706
+ min-height: 192px;
2707
+ }
2708
+
2709
+ .udb-analytics-card__status--error {
2710
+ color: var(--u-color-danger);
2711
+ }
2712
+
2713
+ .udb-analytics-card__spinner {
2714
+ width: 32px;
2715
+ height: 32px;
2716
+ color: var(--u-color-muted);
2717
+ }
2718
+
2719
+ .udb-analytics-card__error-icon {
2720
+ width: 20px;
2721
+ height: 20px;
2722
+ flex-shrink: 0;
2723
+ }
2724
+
2725
+ .udb-analytics-card__error-text {
2726
+ margin: 0;
2727
+ font-size: var(--u-font-size-md);
2728
+ }
2729
+
2730
+ .udb-analytics-card__header {
2731
+ margin-bottom: var(--u-space-6);
2732
+ }
2733
+
2734
+ .udb-analytics-card__title {
2735
+ margin: 0;
2736
+ font-size: var(--u-font-size-lg);
2737
+ font-weight: 600;
2738
+ color: var(--u-color-text);
2739
+ }
2740
+
2741
+ .udb-analytics-card__description {
2742
+ margin: var(--u-space-1) 0 0;
2743
+ font-size: var(--u-font-size-sm);
2744
+ color: var(--u-color-muted);
2745
+ }
2746
+
2747
+ .udb-analytics-card__metrics {
2748
+ display: grid;
2749
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
2750
+ gap: var(--u-space-4);
2751
+ margin-top: var(--u-space-4);
2752
+ }
2753
+
2754
+ /* Chart container + dependency-free SVG renderer surfaces. */
2755
+ .udb-chart {
2756
+ position: relative;
2757
+ width: 100%;
2758
+ }
2759
+
2760
+ .udb-chart__empty {
2761
+ display: flex;
2762
+ align-items: center;
2763
+ justify-content: center;
2764
+ height: 100%;
2765
+ min-height: 192px;
2766
+ padding: var(--u-space-6);
2767
+ text-align: center;
2768
+ font-size: var(--u-font-size-md);
2769
+ color: var(--u-color-muted);
2770
+ }
2771
+
2772
+ .udb-chart__axis {
2773
+ font-size: var(--u-font-size-sm);
2774
+ fill: var(--u-color-muted);
2775
+ }
2776
+
2777
+ .udb-chart__grid {
2778
+ stroke: var(--u-color-border);
2779
+ }
2780
+
2781
+ .udb-chart__svg {
2782
+ display: block;
2783
+ width: 100%;
2784
+ height: 100%;
2785
+ overflow: visible;
2786
+ }
2787
+
2788
+ .udb-chart__legend {
2789
+ display: flex;
2790
+ align-items: center;
2791
+ justify-content: center;
2792
+ flex-wrap: wrap;
2793
+ gap: var(--u-space-3);
2794
+ margin-top: var(--u-space-3);
2795
+ }
2796
+
2797
+ .udb-chart__chip {
2798
+ display: inline-flex;
2799
+ align-items: center;
2800
+ gap: var(--u-space-2);
2801
+ font-size: var(--u-font-size-sm);
2802
+ color: var(--u-color-muted);
2803
+ }
2804
+
2805
+ .udb-chart__chip-dot {
2806
+ width: 8px;
2807
+ height: 8px;
2808
+ border-radius: 50%;
2809
+ flex-shrink: 0;
2810
+ }
2811
+
2812
+ /* ============================================================
2813
+ * 12. Shared blocks — empty state, tables, org switcher, matrix,
2814
+ * audit list (used by guards, session and settings skeletons)
2815
+ * ============================================================ */
2816
+
2817
+ /* Generic empty / forbidden state. */
2818
+ .udb-empty {
2819
+ display: flex;
2820
+ flex-direction: column;
2821
+ align-items: center;
2822
+ justify-content: center;
2823
+ gap: var(--u-space-3);
2824
+ padding: var(--u-space-8) var(--u-space-6);
2825
+ text-align: center;
2826
+ color: var(--u-color-muted);
2827
+ }
2828
+
2829
+ .udb-empty__icon {
2830
+ display: flex;
2831
+ align-items: center;
2832
+ justify-content: center;
2833
+ width: 40px;
2834
+ height: 40px;
2835
+ border-radius: 50%;
2836
+ background: var(--u-color-surface-muted);
2837
+ }
2838
+
2839
+ .udb-empty__glyph {
2840
+ width: 20px;
2841
+ height: 20px;
2842
+ color: var(--u-color-muted);
2843
+ opacity: 0.7;
2844
+ }
2845
+
2846
+ .udb-empty__text {
2847
+ margin: 0;
2848
+ font-size: var(--u-font-size-md);
2849
+ font-weight: var(--u-font-weight-medium);
2850
+ color: var(--u-color-text);
2851
+ }
2852
+
2853
+ .udb-empty__hint {
2854
+ margin: 0;
2855
+ font-size: var(--u-font-size-sm);
2856
+ color: var(--u-color-muted);
2857
+ }
2858
+
2859
+ /* Data tables (user management, permission matrix). */
2860
+ .udb-table__wrap {
2861
+ width: 100%;
2862
+ overflow-x: auto;
2863
+ border: 1px solid var(--u-color-border);
2864
+ border-radius: var(--u-radius-lg);
2865
+ background: var(--u-color-surface);
2866
+ }
2867
+
2868
+ .udb-table {
2869
+ width: 100%;
2870
+ border-collapse: collapse;
2871
+ font-size: var(--u-font-size-md);
2872
+ }
2873
+
2874
+ .udb-table__th {
2875
+ padding: var(--u-space-2) var(--u-space-3);
2876
+ border-bottom: 1px solid var(--u-color-border-strong);
2877
+ text-align: left;
2878
+ font-size: var(--u-font-size-xs);
2879
+ font-weight: var(--u-font-weight-bold);
2880
+ text-transform: uppercase;
2881
+ letter-spacing: 0.06em;
2882
+ color: var(--u-color-muted);
2883
+ white-space: nowrap;
2884
+ }
2885
+
2886
+ .udb-table__th--code {
2887
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
2888
+ text-transform: none;
2889
+ letter-spacing: 0;
2890
+ }
2891
+
2892
+ .udb-table__td {
2893
+ padding: var(--u-space-3);
2894
+ border-bottom: 1px solid var(--u-color-border);
2895
+ color: var(--u-color-text);
2896
+ }
2897
+
2898
+ .udb-table__row:last-child .udb-table__td {
2899
+ border-bottom: none;
2900
+ }
2901
+
2902
+ .udb-table__row:hover .udb-table__td {
2903
+ background: var(--u-color-surface-muted);
2904
+ }
2905
+
2906
+ .udb-table__td--strong {
2907
+ font-weight: var(--u-font-weight-medium);
2908
+ white-space: nowrap;
2909
+ }
2910
+
2911
+ .udb-table__td--center {
2912
+ text-align: center;
2913
+ }
2914
+
2915
+ /* Org switcher (reuses udb-profile-btn / udb-avatar / udb-menu). */
2916
+ .udb-org {
2917
+ display: flex;
2918
+ flex-direction: column;
2919
+ align-items: flex-start;
2920
+ line-height: 1.2;
2921
+ }
2922
+
2923
+ .udb-org__name {
2924
+ font-size: var(--u-font-size-md);
2925
+ font-weight: var(--u-font-weight-medium);
2926
+ color: var(--u-color-text);
2927
+ }
2928
+
2929
+ .udb-org__meta {
2930
+ font-size: 10px;
2931
+ text-transform: capitalize;
2932
+ color: var(--u-color-muted);
2933
+ }
2934
+
2935
+ .udb-org-menu {
2936
+ padding: var(--u-space-2);
2937
+ }
2938
+
2939
+ .udb-org-menu__label {
2940
+ flex: 1;
2941
+ min-width: 0;
2942
+ overflow: hidden;
2943
+ text-overflow: ellipsis;
2944
+ white-space: nowrap;
2945
+ }
2946
+
2947
+ .udb-org-menu__check {
2948
+ width: 14px;
2949
+ height: 14px;
2950
+ color: var(--u-color-primary);
2951
+ }
2952
+
2953
+ .udb-menu__item--active {
2954
+ background: var(--u-color-primary-soft);
2955
+ color: var(--u-color-primary);
2956
+ font-weight: var(--u-font-weight-medium);
2957
+ }
2958
+
2959
+ /* Permission matrix cells. */
2960
+ .udb-matrix__cell {
2961
+ display: inline-flex;
2962
+ align-items: center;
2963
+ justify-content: center;
2964
+ width: 28px;
2965
+ height: 28px;
2966
+ border: 1px solid var(--u-color-border-strong);
2967
+ border-radius: var(--u-radius-sm);
2968
+ background: var(--u-color-surface);
2969
+ cursor: pointer;
2970
+ }
2971
+
2972
+ .udb-matrix__cell:hover {
2973
+ border-color: var(--u-color-primary);
2974
+ }
2975
+
2976
+ .udb-matrix__cell--on {
2977
+ border-color: var(--u-color-primary);
2978
+ background: var(--u-color-primary-soft);
2979
+ }
2980
+
2981
+ .udb-matrix__check {
2982
+ width: 14px;
2983
+ height: 14px;
2984
+ color: var(--u-color-success);
2985
+ }
2986
+
2987
+ .udb-matrix__deny {
2988
+ width: 14px;
2989
+ height: 14px;
2990
+ color: var(--u-color-muted);
2991
+ opacity: 0.5;
2992
+ }
2993
+
2994
+ /* Audit log rows. */
2995
+ .udb-audit {
2996
+ display: flex;
2997
+ flex-direction: column;
2998
+ margin: 0;
2999
+ padding: 0;
3000
+ list-style: none;
3001
+ border: 1px solid var(--u-color-border);
3002
+ border-radius: var(--u-radius-lg);
3003
+ background: var(--u-color-surface);
3004
+ overflow: hidden;
3005
+ }
3006
+
3007
+ .udb-audit__item {
3008
+ display: flex;
3009
+ align-items: baseline;
3010
+ gap: var(--u-space-4);
3011
+ padding: var(--u-space-3) var(--u-space-4);
3012
+ border-bottom: 1px solid var(--u-color-border);
3013
+ font-size: var(--u-font-size-md);
3014
+ }
3015
+
3016
+ .udb-audit__item:last-child {
3017
+ border-bottom: none;
3018
+ }
3019
+
3020
+ .udb-audit__at {
3021
+ flex-shrink: 0;
3022
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
3023
+ font-size: var(--u-font-size-sm);
3024
+ color: var(--u-color-muted);
3025
+ }
3026
+
3027
+ .udb-audit__actor {
3028
+ flex-shrink: 0;
3029
+ font-weight: var(--u-font-weight-medium);
3030
+ color: var(--u-color-text);
3031
+ }
3032
+
3033
+ .udb-audit__action {
3034
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
3035
+ font-size: var(--u-font-size-sm);
3036
+ color: var(--u-color-primary);
3037
+ }
3038
+
3039
+ .udb-audit__target {
3040
+ min-width: 0;
3041
+ overflow: hidden;
3042
+ text-overflow: ellipsis;
3043
+ white-space: nowrap;
3044
+ color: var(--u-color-muted);
3045
+ }