rails_onboarding 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +1351 -0
  4. data/Rakefile +6 -0
  5. data/app/assets/javascripts/rails_onboarding/admin/chart_controller.js +25 -0
  6. data/app/assets/javascripts/rails_onboarding/admin/filter_controller.js +49 -0
  7. data/app/assets/javascripts/rails_onboarding/admin/flash_controller.js +21 -0
  8. data/app/assets/javascripts/rails_onboarding/admin/flow_editor_controller.js +86 -0
  9. data/app/assets/javascripts/rails_onboarding/application.js +231 -0
  10. data/app/assets/javascripts/rails_onboarding/milestone_celebration_controller.js +177 -0
  11. data/app/assets/javascripts/rails_onboarding/milestone_dashboard_controller.js +132 -0
  12. data/app/assets/javascripts/rails_onboarding/milestone_detail_controller.js +34 -0
  13. data/app/assets/javascripts/rails_onboarding/navigation_controller.js +277 -0
  14. data/app/assets/javascripts/rails_onboarding/onboarding_controller.js +326 -0
  15. data/app/assets/javascripts/rails_onboarding/progress_controller.js +203 -0
  16. data/app/assets/javascripts/rails_onboarding/progressive_disclosure_controller.js +218 -0
  17. data/app/assets/javascripts/rails_onboarding/tooltip_controller.js +1237 -0
  18. data/app/assets/javascripts/rails_onboarding/tooltip_scheduler_controller.js +511 -0
  19. data/app/assets/javascripts/rails_onboarding/tour_controller.js +763 -0
  20. data/app/assets/stylesheets/rails_onboarding/accessibility.css +536 -0
  21. data/app/assets/stylesheets/rails_onboarding/admin.css +816 -0
  22. data/app/assets/stylesheets/rails_onboarding/application.css +1145 -0
  23. data/app/assets/stylesheets/rails_onboarding/flash_messages.css +237 -0
  24. data/app/assets/stylesheets/rails_onboarding/milestones.css +545 -0
  25. data/app/assets/stylesheets/rails_onboarding/mobile.css +856 -0
  26. data/app/assets/stylesheets/rails_onboarding/progressive_disclosure.css +299 -0
  27. data/app/assets/stylesheets/rails_onboarding/tooltips.css +468 -0
  28. data/app/assets/stylesheets/rails_onboarding/tour.css +495 -0
  29. data/app/assets/stylesheets/rails_onboarding/utilities.css +393 -0
  30. data/app/controllers/concerns/rails_onboarding/admin_authorization.rb +98 -0
  31. data/app/controllers/concerns/rails_onboarding/rate_limitable.rb +104 -0
  32. data/app/controllers/rails_onboarding/ab_tests_controller.rb +257 -0
  33. data/app/controllers/rails_onboarding/admin/ab_tests_controller.rb +121 -0
  34. data/app/controllers/rails_onboarding/admin/base_controller.rb +68 -0
  35. data/app/controllers/rails_onboarding/admin/dashboard_controller.rb +189 -0
  36. data/app/controllers/rails_onboarding/admin/flows_controller.rb +175 -0
  37. data/app/controllers/rails_onboarding/admin/users_controller.rb +366 -0
  38. data/app/controllers/rails_onboarding/application_controller.rb +9 -0
  39. data/app/controllers/rails_onboarding/milestones_controller.rb +126 -0
  40. data/app/controllers/rails_onboarding/onboarding_controller.rb +409 -0
  41. data/app/controllers/rails_onboarding/progressive_features_controller.rb +134 -0
  42. data/app/controllers/rails_onboarding/templates_controller.rb +162 -0
  43. data/app/controllers/rails_onboarding/test_sessions_controller.rb +16 -0
  44. data/app/controllers/rails_onboarding/tooltips_controller.rb +92 -0
  45. data/app/helpers/rails_onboarding/application_helper.rb +4 -0
  46. data/app/helpers/rails_onboarding/i18n_helper.rb +137 -0
  47. data/app/helpers/rails_onboarding/personalization_helper.rb +184 -0
  48. data/app/helpers/rails_onboarding/templates_helper.rb +253 -0
  49. data/app/jobs/rails_onboarding/application_job.rb +4 -0
  50. data/app/mailers/rails_onboarding/application_mailer.rb +6 -0
  51. data/app/mailers/rails_onboarding/onboarding_mailer.rb +72 -0
  52. data/app/models/concerns/rails_onboarding/ab_testable.rb +149 -0
  53. data/app/models/concerns/rails_onboarding/onboardable.rb +649 -0
  54. data/app/models/concerns/rails_onboarding/personalizable.rb +211 -0
  55. data/app/models/concerns/rails_onboarding/progressive_disclosure.rb +276 -0
  56. data/app/models/rails_onboarding/analytics.rb +255 -0
  57. data/app/models/rails_onboarding/analytics_event.rb +168 -0
  58. data/app/models/rails_onboarding/application_record.rb +5 -0
  59. data/app/models/rails_onboarding/flow.rb +41 -0
  60. data/app/services/rails_onboarding/milestone_service.rb +105 -0
  61. data/app/views/layouts/rails_onboarding/admin.html.erb +106 -0
  62. data/app/views/layouts/rails_onboarding/application.html.erb +65 -0
  63. data/app/views/rails_onboarding/ab_tests/index.html.erb +209 -0
  64. data/app/views/rails_onboarding/ab_tests/results.html.erb +253 -0
  65. data/app/views/rails_onboarding/admin/ab_tests/_ab_test_card.html.erb +24 -0
  66. data/app/views/rails_onboarding/admin/ab_tests/index.html.erb +57 -0
  67. data/app/views/rails_onboarding/admin/ab_tests/show.html.erb +41 -0
  68. data/app/views/rails_onboarding/admin/dashboard/index.html.erb +224 -0
  69. data/app/views/rails_onboarding/admin/flows/_form.html.erb +147 -0
  70. data/app/views/rails_onboarding/admin/flows/edit.html.erb +7 -0
  71. data/app/views/rails_onboarding/admin/flows/index.html.erb +125 -0
  72. data/app/views/rails_onboarding/admin/flows/new.html.erb +7 -0
  73. data/app/views/rails_onboarding/admin/flows/preview.html.erb +40 -0
  74. data/app/views/rails_onboarding/admin/flows/show.html.erb +114 -0
  75. data/app/views/rails_onboarding/admin/users/index.html.erb +180 -0
  76. data/app/views/rails_onboarding/admin/users/show.html.erb +187 -0
  77. data/app/views/rails_onboarding/milestones/index.html.erb +64 -0
  78. data/app/views/rails_onboarding/milestones/show.html.erb +57 -0
  79. data/app/views/rails_onboarding/onboarding/_custom_footer.html.erb +2 -0
  80. data/app/views/rails_onboarding/onboarding/_progress_indicator.html.erb +56 -0
  81. data/app/views/rails_onboarding/onboarding/_step_navigation.html.erb +44 -0
  82. data/app/views/rails_onboarding/onboarding/step.html.erb +38 -0
  83. data/app/views/rails_onboarding/onboarding/welcome.html.erb +37 -0
  84. data/app/views/rails_onboarding/onboarding_mailer/completion_email.html.erb +109 -0
  85. data/app/views/rails_onboarding/onboarding_mailer/completion_email.text.erb +29 -0
  86. data/app/views/rails_onboarding/onboarding_mailer/reminder_email.html.erb +99 -0
  87. data/app/views/rails_onboarding/onboarding_mailer/reminder_email.text.erb +20 -0
  88. data/app/views/rails_onboarding/onboarding_mailer/step_completed_email.html.erb +105 -0
  89. data/app/views/rails_onboarding/onboarding_mailer/step_completed_email.text.erb +19 -0
  90. data/app/views/rails_onboarding/onboarding_mailer/welcome_email.html.erb +74 -0
  91. data/app/views/rails_onboarding/onboarding_mailer/welcome_email.text.erb +17 -0
  92. data/app/views/rails_onboarding/shared/_flash.html.erb +25 -0
  93. data/app/views/rails_onboarding/shared/_milestone_badge.html.erb +22 -0
  94. data/app/views/rails_onboarding/shared/_milestone_celebration.html.erb +44 -0
  95. data/app/views/rails_onboarding/shared/_onboarding_banner.html.erb +48 -0
  96. data/app/views/rails_onboarding/templates/index.html.erb +255 -0
  97. data/config/importmap.rb +33 -0
  98. data/config/locales/en.yml +62 -0
  99. data/config/locales/es.yml +62 -0
  100. data/config/locales/fr.yml +62 -0
  101. data/config/routes.rb +79 -0
  102. data/lib/generators/rails_onboarding/install_generator.rb +124 -0
  103. data/lib/generators/rails_onboarding/templates/README +120 -0
  104. data/lib/generators/rails_onboarding/templates/add_analytics_to_rails_onboarding.rb +33 -0
  105. data/lib/generators/rails_onboarding/templates/add_milestone_tracking_to_users.rb +38 -0
  106. data/lib/generators/rails_onboarding/templates/add_onboarding_indexes.rb +93 -0
  107. data/lib/generators/rails_onboarding/templates/add_onboarding_to_users.rb +51 -0
  108. data/lib/generators/rails_onboarding/templates/add_robustness_fields_to_users.rb.tt +20 -0
  109. data/lib/generators/rails_onboarding/templates/create_rails_onboarding_flows.rb +18 -0
  110. data/lib/generators/rails_onboarding/templates/onboarding.css +18 -0
  111. data/lib/generators/rails_onboarding/templates/rails_onboarding.rb +75 -0
  112. data/lib/generators/rails_onboarding/update_generator.rb +73 -0
  113. data/lib/rails_onboarding/api_mode.rb +367 -0
  114. data/lib/rails_onboarding/backfill.rb +130 -0
  115. data/lib/rails_onboarding/background_jobs.rb +412 -0
  116. data/lib/rails_onboarding/caching.rb +180 -0
  117. data/lib/rails_onboarding/cdn_support.rb +202 -0
  118. data/lib/rails_onboarding/configuration/ab_testing.rb +24 -0
  119. data/lib/rails_onboarding/configuration/analytics.rb +29 -0
  120. data/lib/rails_onboarding/configuration/integrations.rb +31 -0
  121. data/lib/rails_onboarding/configuration/milestones.rb +92 -0
  122. data/lib/rails_onboarding/configuration/personalization.rb +25 -0
  123. data/lib/rails_onboarding/configuration/progressive_disclosure.rb +41 -0
  124. data/lib/rails_onboarding/configuration/rate_limiting.rb +18 -0
  125. data/lib/rails_onboarding/configuration/steps.rb +121 -0
  126. data/lib/rails_onboarding/configuration/templates.rb +85 -0
  127. data/lib/rails_onboarding/configuration/tooltips.rb +32 -0
  128. data/lib/rails_onboarding/configuration.rb +133 -0
  129. data/lib/rails_onboarding/configuration_errors.rb +19 -0
  130. data/lib/rails_onboarding/configuration_validator.rb +477 -0
  131. data/lib/rails_onboarding/controller_helpers.rb +153 -0
  132. data/lib/rails_onboarding/current.rb +13 -0
  133. data/lib/rails_onboarding/deprecation.rb +64 -0
  134. data/lib/rails_onboarding/devise_integration.rb +122 -0
  135. data/lib/rails_onboarding/engine.rb +245 -0
  136. data/lib/rails_onboarding/error_recovery.rb +173 -0
  137. data/lib/rails_onboarding/lazy_loading.rb +155 -0
  138. data/lib/rails_onboarding/multi_tenant.rb +306 -0
  139. data/lib/rails_onboarding/requirements_validator.rb +315 -0
  140. data/lib/rails_onboarding/responsive_helper.rb +218 -0
  141. data/lib/rails_onboarding/session_manager.rb +187 -0
  142. data/lib/rails_onboarding/skip_logic.rb +159 -0
  143. data/lib/rails_onboarding/turbo_compatibility.rb +229 -0
  144. data/lib/rails_onboarding/version.rb +3 -0
  145. data/lib/rails_onboarding.rb +44 -0
  146. data/lib/tasks/rails_onboarding_analytics.rake +136 -0
  147. data/lib/tasks/rails_onboarding_tasks.rake +162 -0
  148. metadata +303 -0
@@ -0,0 +1,816 @@
1
+ /* Admin Interface Styles */
2
+
3
+ /* Variables */
4
+ :root {
5
+ --admin-primary: #3b82f6;
6
+ --admin-primary-dark: #2563eb;
7
+ --admin-success: #10b981;
8
+ --admin-warning: #f59e0b;
9
+ --admin-danger: #ef4444;
10
+ --admin-info: #06b6d4;
11
+ --admin-secondary: #6b7280;
12
+
13
+ --admin-bg: #f9fafb;
14
+ --admin-sidebar-bg: #1f2937;
15
+ --admin-sidebar-text: #d1d5db;
16
+ --admin-card-bg: #ffffff;
17
+ --admin-border: #e5e7eb;
18
+
19
+ --admin-text-primary: #111827;
20
+ --admin-text-secondary: #6b7280;
21
+ --admin-text-muted: #9ca3af;
22
+
23
+ --admin-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
24
+ --admin-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
25
+
26
+ --admin-radius: 0.375rem;
27
+ --admin-radius-lg: 0.5rem;
28
+
29
+ --admin-sidebar-width: 260px;
30
+ }
31
+
32
+ /* Layout */
33
+ .admin-layout {
34
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
35
+ background: var(--admin-bg);
36
+ color: var(--admin-text-primary);
37
+ min-height: 100vh;
38
+ }
39
+
40
+ .admin-container {
41
+ display: flex;
42
+ min-height: 100vh;
43
+ }
44
+
45
+ /* Sidebar */
46
+ .admin-sidebar {
47
+ width: var(--admin-sidebar-width);
48
+ background: var(--admin-sidebar-bg);
49
+ color: var(--admin-sidebar-text);
50
+ display: flex;
51
+ flex-direction: column;
52
+ position: fixed;
53
+ left: 0;
54
+ top: 0;
55
+ bottom: 0;
56
+ z-index: 100;
57
+ }
58
+
59
+ .admin-sidebar-header {
60
+ padding: 1.5rem 1rem;
61
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
62
+ }
63
+
64
+ .admin-logo {
65
+ font-size: 1.25rem;
66
+ font-weight: 700;
67
+ margin: 0;
68
+ color: #ffffff;
69
+ display: flex;
70
+ align-items: center;
71
+ gap: 0.5rem;
72
+ }
73
+
74
+ .admin-logo-icon {
75
+ font-size: 1.5rem;
76
+ }
77
+
78
+ .admin-nav {
79
+ flex: 1;
80
+ padding: 1rem 0;
81
+ overflow-y: auto;
82
+ }
83
+
84
+ .admin-nav-item {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 0.75rem;
88
+ padding: 0.75rem 1rem;
89
+ color: var(--admin-sidebar-text);
90
+ text-decoration: none;
91
+ transition: all 0.2s;
92
+ border-left: 3px solid transparent;
93
+ }
94
+
95
+ .admin-nav-item:hover {
96
+ background: rgba(255, 255, 255, 0.05);
97
+ color: #ffffff;
98
+ }
99
+
100
+ .admin-nav-item.onboarding-active {
101
+ background: rgba(59, 130, 246, 0.1);
102
+ color: #60a5fa;
103
+ border-left-color: #3b82f6;
104
+ }
105
+
106
+ .admin-nav-icon {
107
+ font-size: 1.25rem;
108
+ }
109
+
110
+ /* Separated from the admin sections above - this one leaves the admin area */
111
+ .admin-nav-item-home {
112
+ margin-top: 1rem;
113
+ padding-top: 1.25rem;
114
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
115
+ }
116
+
117
+ .admin-sidebar-footer {
118
+ padding: 1rem;
119
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
120
+ }
121
+
122
+ .admin-user-info {
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 0.75rem;
126
+ }
127
+
128
+ .admin-user-avatar {
129
+ width: 2.5rem;
130
+ height: 2.5rem;
131
+ border-radius: 50%;
132
+ background: var(--admin-primary);
133
+ color: white;
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ font-weight: 600;
138
+ }
139
+
140
+ .admin-user-details {
141
+ flex: 1;
142
+ min-width: 0;
143
+ }
144
+
145
+ .admin-user-name {
146
+ font-size: 0.875rem;
147
+ font-weight: 500;
148
+ color: #ffffff;
149
+ white-space: nowrap;
150
+ overflow: hidden;
151
+ text-overflow: ellipsis;
152
+ }
153
+
154
+ .admin-user-role {
155
+ font-size: 0.75rem;
156
+ color: var(--admin-sidebar-text);
157
+ }
158
+
159
+ /* Main Content */
160
+ .admin-main {
161
+ flex: 1;
162
+ margin-left: var(--admin-sidebar-width);
163
+ display: flex;
164
+ flex-direction: column;
165
+ }
166
+
167
+ .admin-header {
168
+ background: white;
169
+ border-bottom: 1px solid var(--admin-border);
170
+ position: sticky;
171
+ top: 0;
172
+ z-index: 50;
173
+ }
174
+
175
+ .admin-header-content {
176
+ padding: 1.5rem 2rem;
177
+ display: flex;
178
+ justify-content: space-between;
179
+ align-items: center;
180
+ }
181
+
182
+ .admin-page-title {
183
+ font-size: 1.5rem;
184
+ font-weight: 700;
185
+ margin: 0;
186
+ color: var(--admin-text-primary);
187
+ }
188
+
189
+ .admin-header-actions {
190
+ display: flex;
191
+ gap: 0.75rem;
192
+ align-items: center;
193
+ }
194
+
195
+ .admin-content {
196
+ padding: 2rem;
197
+ flex: 1;
198
+ }
199
+
200
+ /* Flash Messages */
201
+ .admin-flash-messages {
202
+ padding: 1rem 2rem 0;
203
+ }
204
+
205
+ .admin-flash-message {
206
+ padding: 1rem;
207
+ border-radius: var(--admin-radius);
208
+ margin-bottom: 1rem;
209
+ display: flex;
210
+ align-items: center;
211
+ gap: 0.75rem;
212
+ box-shadow: var(--admin-shadow);
213
+ }
214
+
215
+ .admin-flash-notice {
216
+ background: #d1fae5;
217
+ color: #065f46;
218
+ border: 1px solid #6ee7b7;
219
+ }
220
+
221
+ .admin-flash-alert {
222
+ background: #fee2e2;
223
+ color: #991b1b;
224
+ border: 1px solid #fca5a5;
225
+ }
226
+
227
+ .admin-flash-icon {
228
+ font-size: 1.25rem;
229
+ }
230
+
231
+ .admin-flash-text {
232
+ flex: 1;
233
+ }
234
+
235
+ .admin-flash-close {
236
+ background: none;
237
+ border: none;
238
+ font-size: 1.5rem;
239
+ cursor: pointer;
240
+ opacity: 0.5;
241
+ transition: opacity 0.2s;
242
+ }
243
+
244
+ .admin-flash-close:hover {
245
+ opacity: 1;
246
+ }
247
+
248
+ /* Cards */
249
+ .admin-card {
250
+ background: var(--admin-card-bg);
251
+ border-radius: var(--admin-radius-lg);
252
+ box-shadow: var(--admin-shadow);
253
+ margin-bottom: 1.5rem;
254
+ }
255
+
256
+ .admin-card-header {
257
+ padding: 1.25rem 1.5rem;
258
+ border-bottom: 1px solid var(--admin-border);
259
+ display: flex;
260
+ justify-content: space-between;
261
+ align-items: center;
262
+ }
263
+
264
+ .admin-card-title {
265
+ font-size: 1.125rem;
266
+ font-weight: 600;
267
+ margin: 0;
268
+ color: var(--admin-text-primary);
269
+ }
270
+
271
+ .admin-card-action {
272
+ color: var(--admin-primary);
273
+ text-decoration: none;
274
+ font-size: 0.875rem;
275
+ font-weight: 500;
276
+ transition: color 0.2s;
277
+ }
278
+
279
+ .admin-card-action:hover {
280
+ color: var(--admin-primary-dark);
281
+ }
282
+
283
+ .admin-card-body {
284
+ padding: 1.5rem;
285
+ }
286
+
287
+ .admin-card-body.admin-card-no-padding {
288
+ padding: 0;
289
+ }
290
+
291
+ .admin-card-footer {
292
+ padding: 1.25rem 1.5rem;
293
+ border-top: 1px solid var(--admin-border);
294
+ display: flex;
295
+ gap: 0.75rem;
296
+ }
297
+
298
+ /* Stats Grid */
299
+ .admin-stats-grid {
300
+ display: grid;
301
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
302
+ gap: 1.5rem;
303
+ margin-bottom: 2rem;
304
+ }
305
+
306
+ .admin-stats-grid.admin-stats-compact {
307
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
308
+ gap: 1rem;
309
+ margin-bottom: 1.5rem;
310
+ }
311
+
312
+ .admin-stat-card {
313
+ background: var(--admin-card-bg);
314
+ border-radius: var(--admin-radius-lg);
315
+ padding: 1.5rem;
316
+ box-shadow: var(--admin-shadow);
317
+ display: flex;
318
+ align-items: flex-start;
319
+ gap: 1rem;
320
+ }
321
+
322
+ .admin-stat-icon {
323
+ font-size: 2rem;
324
+ width: 3rem;
325
+ height: 3rem;
326
+ display: flex;
327
+ align-items: center;
328
+ justify-content: center;
329
+ background: var(--admin-bg);
330
+ border-radius: var(--admin-radius);
331
+ }
332
+
333
+ .admin-stat-content {
334
+ flex: 1;
335
+ }
336
+
337
+ .admin-stat-label {
338
+ font-size: 0.875rem;
339
+ color: var(--admin-text-secondary);
340
+ margin-bottom: 0.25rem;
341
+ font-weight: 500;
342
+ }
343
+
344
+ .admin-stat-value {
345
+ font-size: 1.875rem;
346
+ font-weight: 700;
347
+ color: var(--admin-text-primary);
348
+ }
349
+
350
+ .admin-stat-change {
351
+ font-size: 0.875rem;
352
+ color: var(--admin-text-muted);
353
+ margin-top: 0.25rem;
354
+ }
355
+
356
+ .admin-stat-change.onboarding-positive {
357
+ color: var(--admin-success);
358
+ }
359
+
360
+ .admin-stat-change.onboarding-negative {
361
+ color: var(--admin-danger);
362
+ }
363
+
364
+ /* Buttons */
365
+ .admin-btn {
366
+ display: inline-flex;
367
+ align-items: center;
368
+ justify-content: center;
369
+ gap: 0.5rem;
370
+ padding: 0.5rem 1rem;
371
+ font-size: 0.875rem;
372
+ font-weight: 500;
373
+ border-radius: var(--admin-radius);
374
+ border: 1px solid transparent;
375
+ cursor: pointer;
376
+ transition: all 0.2s;
377
+ text-decoration: none;
378
+ white-space: nowrap;
379
+ }
380
+
381
+ .admin-btn-primary {
382
+ background: var(--admin-primary);
383
+ color: white;
384
+ }
385
+
386
+ .admin-btn-primary:hover {
387
+ background: var(--admin-primary-dark);
388
+ }
389
+
390
+ .admin-btn-secondary {
391
+ background: white;
392
+ color: var(--admin-text-primary);
393
+ border-color: var(--admin-border);
394
+ }
395
+
396
+ .admin-btn-secondary:hover {
397
+ background: var(--admin-bg);
398
+ }
399
+
400
+ .admin-btn-success {
401
+ background: var(--admin-success);
402
+ color: white;
403
+ }
404
+
405
+ .admin-btn-warning {
406
+ background: var(--admin-warning);
407
+ color: white;
408
+ }
409
+
410
+ .admin-btn-danger {
411
+ background: var(--admin-danger);
412
+ color: white;
413
+ }
414
+
415
+ .admin-btn-sm {
416
+ padding: 0.375rem 0.75rem;
417
+ font-size: 0.8125rem;
418
+ }
419
+
420
+ .admin-btn-block {
421
+ width: 100%;
422
+ margin-top: 1rem;
423
+ }
424
+
425
+ /* Forms */
426
+ .admin-form-group {
427
+ margin-bottom: 1.5rem;
428
+ }
429
+
430
+ .admin-label {
431
+ display: block;
432
+ font-size: 0.875rem;
433
+ font-weight: 500;
434
+ color: var(--admin-text-primary);
435
+ margin-bottom: 0.5rem;
436
+ }
437
+
438
+ .admin-input,
439
+ .admin-textarea,
440
+ .admin-select {
441
+ width: 100%;
442
+ padding: 0.5rem 0.75rem;
443
+ font-size: 0.875rem;
444
+ border: 1px solid var(--admin-border);
445
+ border-radius: var(--admin-radius);
446
+ transition: all 0.2s;
447
+ }
448
+
449
+ .admin-input:focus,
450
+ .admin-textarea:focus,
451
+ .admin-select:focus {
452
+ outline: none;
453
+ border-color: var(--admin-primary);
454
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
455
+ }
456
+
457
+ .admin-textarea {
458
+ resize: vertical;
459
+ min-height: 100px;
460
+ }
461
+
462
+ /* Tables */
463
+ .admin-table {
464
+ width: 100%;
465
+ border-collapse: collapse;
466
+ }
467
+
468
+ .admin-table thead {
469
+ background: var(--admin-bg);
470
+ }
471
+
472
+ .admin-table th {
473
+ padding: 0.75rem 1rem;
474
+ text-align: left;
475
+ font-size: 0.75rem;
476
+ font-weight: 600;
477
+ color: var(--admin-text-secondary);
478
+ text-transform: uppercase;
479
+ letter-spacing: 0.05em;
480
+ border-bottom: 1px solid var(--admin-border);
481
+ }
482
+
483
+ .admin-table td {
484
+ padding: 1rem;
485
+ border-bottom: 1px solid var(--admin-border);
486
+ font-size: 0.875rem;
487
+ }
488
+
489
+ .admin-table tbody tr:hover {
490
+ background: var(--admin-bg);
491
+ }
492
+
493
+ .admin-table-checkbox {
494
+ width: 3rem;
495
+ }
496
+
497
+ .admin-table-actions {
498
+ width: 10rem;
499
+ text-align: right;
500
+ }
501
+
502
+ .admin-table-empty {
503
+ padding: 3rem;
504
+ text-align: center;
505
+ color: var(--admin-text-muted);
506
+ }
507
+
508
+ /* Badges */
509
+ .admin-badge {
510
+ display: inline-flex;
511
+ align-items: center;
512
+ padding: 0.25rem 0.625rem;
513
+ font-size: 0.75rem;
514
+ font-weight: 500;
515
+ border-radius: 9999px;
516
+ background: var(--admin-bg);
517
+ color: var(--admin-text-secondary);
518
+ }
519
+
520
+ .admin-badge-success {
521
+ background: #d1fae5;
522
+ color: #065f46;
523
+ }
524
+
525
+ .admin-badge-warning {
526
+ background: #fef3c7;
527
+ color: #92400e;
528
+ }
529
+
530
+ .admin-badge-danger {
531
+ background: #fee2e2;
532
+ color: #991b1b;
533
+ }
534
+
535
+ .admin-badge-info {
536
+ background: #cffafe;
537
+ color: #164e63;
538
+ }
539
+
540
+ .admin-badge-secondary {
541
+ background: #f3f4f6;
542
+ color: #4b5563;
543
+ }
544
+
545
+ /* Progress Bar */
546
+ .admin-progress-bar {
547
+ height: 0.5rem;
548
+ background: var(--admin-bg);
549
+ border-radius: 9999px;
550
+ overflow: hidden;
551
+ display: inline-block;
552
+ width: 100px;
553
+ vertical-align: middle;
554
+ margin-right: 0.5rem;
555
+ }
556
+
557
+ .admin-progress-fill {
558
+ height: 100%;
559
+ width: var(--admin-progress-width, 0%);
560
+ background: var(--admin-primary);
561
+ transition: width 0.3s;
562
+ }
563
+
564
+ .admin-progress-text {
565
+ font-size: 0.75rem;
566
+ color: var(--admin-text-secondary);
567
+ }
568
+
569
+ .admin-alert-preview {
570
+ margin-bottom: 1.5rem;
571
+ }
572
+
573
+ /* Charts */
574
+ .admin-charts-grid {
575
+ display: grid;
576
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
577
+ gap: 1.5rem;
578
+ margin-bottom: 2rem;
579
+ }
580
+
581
+ .admin-bar-chart {
582
+ display: flex;
583
+ align-items: flex-end;
584
+ justify-content: space-around;
585
+ height: 200px;
586
+ gap: 0.5rem;
587
+ }
588
+
589
+ .admin-bar-item {
590
+ flex: 1;
591
+ display: flex;
592
+ flex-direction: column;
593
+ align-items: center;
594
+ }
595
+
596
+ .admin-bar {
597
+ width: 100%;
598
+ height: var(--admin-bar-height, 0%);
599
+ background: var(--admin-primary);
600
+ border-radius: var(--admin-radius) var(--admin-radius) 0 0;
601
+ display: flex;
602
+ align-items: flex-start;
603
+ justify-content: center;
604
+ padding-top: 0.5rem;
605
+ min-height: 20px;
606
+ transition: all 0.3s;
607
+ }
608
+
609
+ .admin-bar-value {
610
+ color: white;
611
+ font-size: 0.75rem;
612
+ font-weight: 600;
613
+ }
614
+
615
+ .admin-bar-label {
616
+ margin-top: 0.5rem;
617
+ font-size: 0.75rem;
618
+ color: var(--admin-text-secondary);
619
+ }
620
+
621
+ /* Funnel */
622
+ .admin-funnel {
623
+ display: flex;
624
+ flex-direction: column;
625
+ gap: 0.5rem;
626
+ }
627
+
628
+ .admin-funnel-step {
629
+ display: flex;
630
+ flex-direction: column;
631
+ gap: 0.375rem;
632
+ }
633
+
634
+ .admin-funnel-track {
635
+ position: relative;
636
+ height: 3rem;
637
+ border-radius: var(--admin-radius);
638
+ background: var(--admin-border);
639
+ overflow: hidden;
640
+ }
641
+
642
+ .admin-funnel-bar {
643
+ position: absolute;
644
+ inset: 0;
645
+ width: var(--admin-funnel-width, 0%);
646
+ background: var(--admin-primary);
647
+ border-radius: var(--admin-radius);
648
+ transition: width 0.3s;
649
+ }
650
+
651
+ .admin-funnel-label {
652
+ display: flex;
653
+ justify-content: space-between;
654
+ width: 100%;
655
+ color: var(--admin-text-primary);
656
+ font-size: 0.875rem;
657
+ }
658
+
659
+ .admin-funnel-arrow {
660
+ align-self: center;
661
+ font-size: 1.5rem;
662
+ color: var(--admin-text-muted);
663
+ margin: 0.25rem 0;
664
+ }
665
+
666
+ /* Empty States */
667
+ .admin-empty-state {
668
+ text-align: center;
669
+ padding: 2rem;
670
+ color: var(--admin-text-muted);
671
+ }
672
+
673
+ .admin-empty-state-large {
674
+ text-align: center;
675
+ padding: 4rem 2rem;
676
+ }
677
+
678
+ .admin-empty-icon {
679
+ font-size: 4rem;
680
+ margin-bottom: 1rem;
681
+ }
682
+
683
+ /* Timeline */
684
+ .admin-timeline {
685
+ position: relative;
686
+ }
687
+
688
+ .admin-timeline-item {
689
+ display: flex;
690
+ gap: 1rem;
691
+ margin-bottom: 1rem;
692
+ }
693
+
694
+ .admin-timeline-dot {
695
+ width: 0.75rem;
696
+ height: 0.75rem;
697
+ border-radius: 50%;
698
+ background: var(--admin-primary);
699
+ margin-top: 0.25rem;
700
+ }
701
+
702
+ .admin-timeline-content {
703
+ flex: 1;
704
+ }
705
+
706
+ .admin-timeline-title {
707
+ font-weight: 500;
708
+ color: var(--admin-text-primary);
709
+ margin-bottom: 0.25rem;
710
+ }
711
+
712
+ .admin-timeline-meta {
713
+ font-size: 0.875rem;
714
+ color: var(--admin-text-secondary);
715
+ }
716
+
717
+ /* Pagination. The markup comes from pagy (`.pagy.info` and `.pagy.series-nav`),
718
+ so these class names are pagy's, not ours - they must NOT be namespaced with
719
+ an onboarding- prefix or the rules stop matching what pagy renders. */
720
+ .admin-pagination {
721
+ display: flex;
722
+ align-items: center;
723
+ justify-content: space-between;
724
+ flex-wrap: wrap;
725
+ gap: 0.75rem;
726
+ margin-top: 1.5rem;
727
+ }
728
+
729
+ .admin-pagination .info {
730
+ font-size: 0.875rem;
731
+ color: var(--admin-text-secondary);
732
+ }
733
+
734
+ .admin-pagination .series-nav {
735
+ display: flex;
736
+ align-items: center;
737
+ gap: 0.25rem;
738
+ margin-left: auto;
739
+ }
740
+
741
+ .admin-pagination .series-nav a {
742
+ display: inline-flex;
743
+ align-items: center;
744
+ justify-content: center;
745
+ min-width: 2.25rem;
746
+ padding: 0.375rem 0.625rem;
747
+ font-size: 0.875rem;
748
+ font-weight: 500;
749
+ line-height: 1.25;
750
+ border: 1px solid var(--admin-border);
751
+ border-radius: var(--admin-radius);
752
+ background: var(--admin-card-bg);
753
+ color: var(--admin-text-primary);
754
+ text-decoration: none;
755
+ transition: all 0.2s;
756
+ }
757
+
758
+ .admin-pagination .series-nav a[href]:hover {
759
+ background: var(--admin-bg);
760
+ border-color: var(--admin-primary);
761
+ color: var(--admin-primary);
762
+ }
763
+
764
+ /* Current page: pagy renders it as a non-link <a aria-current="page"> */
765
+ .admin-pagination .series-nav a[aria-current] {
766
+ background: var(--admin-primary);
767
+ border-color: var(--admin-primary);
768
+ color: white;
769
+ }
770
+
771
+ .admin-pagination .series-nav a:not([href]) {
772
+ cursor: default;
773
+ }
774
+
775
+ /* Disabled prev/next on the first and last page */
776
+ .admin-pagination .series-nav a[role="link"]:not([aria-current]) {
777
+ opacity: 0.45;
778
+ }
779
+
780
+ /* The "…" gap between page ranges */
781
+ .admin-pagination .series-nav a[role="separator"] {
782
+ min-width: auto;
783
+ padding: 0.375rem 0.25rem;
784
+ border-color: transparent;
785
+ background: transparent;
786
+ color: var(--admin-text-muted);
787
+ }
788
+
789
+ /* Responsive */
790
+ @media (max-width: 768px) {
791
+ .admin-sidebar {
792
+ transform: translateX(-100%);
793
+ }
794
+
795
+ .admin-main {
796
+ margin-left: 0;
797
+ }
798
+
799
+ .admin-stats-grid {
800
+ grid-template-columns: 1fr;
801
+ }
802
+
803
+ .admin-charts-grid {
804
+ grid-template-columns: 1fr;
805
+ }
806
+
807
+ .admin-pagination {
808
+ justify-content: center;
809
+ }
810
+
811
+ .admin-pagination .series-nav {
812
+ margin-left: 0;
813
+ flex-wrap: wrap;
814
+ justify-content: center;
815
+ }
816
+ }