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,856 @@
1
+ /* ======================
2
+ Advanced Mobile Responsive Design
3
+ ====================== */
4
+
5
+ /* Mobile-First CSS Variables */
6
+ :root {
7
+ /* Mobile-specific spacing (smaller on mobile) */
8
+ --mobile-space-xs: 0.25rem;
9
+ --mobile-space-sm: 0.375rem;
10
+ --mobile-space-md: 0.75rem;
11
+ --mobile-space-lg: 1rem;
12
+ --mobile-space-xl: 1.5rem;
13
+
14
+ /* Mobile-specific typography (optimized for smaller screens) */
15
+ --mobile-text-xs: 0.6875rem; /* 11px */
16
+ --mobile-text-sm: 0.8125rem; /* 13px */
17
+ --mobile-text-base: 0.9375rem; /* 15px */
18
+ --mobile-text-lg: 1.0625rem; /* 17px */
19
+ --mobile-text-xl: 1.1875rem; /* 19px */
20
+ --mobile-text-2xl: 1.375rem; /* 22px */
21
+ --mobile-text-3xl: 1.625rem; /* 26px */
22
+
23
+ /* Safe area insets for modern devices (notches, home indicator) */
24
+ --safe-area-inset-top: env(safe-area-inset-top);
25
+ --safe-area-inset-right: env(safe-area-inset-right);
26
+ --safe-area-inset-bottom: env(safe-area-inset-bottom);
27
+ --safe-area-inset-left: env(safe-area-inset-left);
28
+ }
29
+
30
+ /* ======================
31
+ Enhanced Breakpoints
32
+ ====================== */
33
+
34
+ /* Extra Small: 320px - 479px (Small phones portrait) */
35
+ @media screen and (max-width: 29.9375em) {
36
+ .onboarding-container {
37
+ font-size: var(--mobile-text-base);
38
+ }
39
+
40
+ .onboarding-content {
41
+ padding: var(--mobile-space-md);
42
+ padding-top: max(var(--mobile-space-md), var(--safe-area-inset-top));
43
+ padding-bottom: max(var(--mobile-space-md), var(--safe-area-inset-bottom));
44
+ padding-left: max(var(--mobile-space-md), var(--safe-area-inset-left));
45
+ padding-right: max(var(--mobile-space-md), var(--safe-area-inset-right));
46
+ }
47
+
48
+ .step-title {
49
+ font-size: var(--mobile-text-2xl);
50
+ line-height: 1.2;
51
+ margin-bottom: var(--mobile-space-md);
52
+ }
53
+
54
+ .step-intro {
55
+ font-size: var(--mobile-text-base);
56
+ margin-bottom: var(--mobile-space-lg);
57
+ }
58
+
59
+ /* Margin is handled by .welcome-step's flex `gap` (see application.css) -
60
+ only font-size/line-height need setting here. */
61
+ .step-heading {
62
+ font-size: var(--mobile-text-2xl);
63
+ line-height: 1.2;
64
+ }
65
+
66
+ .step-subheading {
67
+ font-size: var(--mobile-text-base);
68
+ }
69
+
70
+ .step-icon {
71
+ font-size: 2rem;
72
+ margin-bottom: var(--mobile-space-md);
73
+ }
74
+ }
75
+
76
+ /* Small: 480px - 767px (Large phones, small tablets portrait) */
77
+ @media screen and (min-width: 30em) and (max-width: 47.9375em) {
78
+ .onboarding-content {
79
+ padding: var(--mobile-space-lg) var(--mobile-space-md);
80
+ }
81
+
82
+ .step-title,
83
+ .step-heading {
84
+ font-size: var(--mobile-text-3xl);
85
+ }
86
+ }
87
+
88
+ /* Medium: 768px - 1023px (Tablets portrait, small laptops) */
89
+ @media screen and (min-width: 48em) and (max-width: 63.9375em) {
90
+ .onboarding-content {
91
+ padding: var(--onboarding-space-xl) var(--onboarding-space-lg);
92
+ }
93
+ }
94
+
95
+ /* ======================
96
+ Landscape Orientation
97
+ ====================== */
98
+
99
+ /* Small phones landscape */
100
+ @media screen and (max-width: 47.9375em) and (orientation: landscape) and (max-height: 30em) {
101
+ .onboarding-container {
102
+ min-height: auto;
103
+ }
104
+
105
+ .onboarding-content {
106
+ padding: var(--mobile-space-sm) var(--mobile-space-md);
107
+ align-items: flex-start;
108
+ }
109
+
110
+ .step-content {
111
+ padding: var(--mobile-space-md) 0;
112
+ }
113
+
114
+ .step-icon {
115
+ font-size: 1.5rem;
116
+ margin-bottom: var(--mobile-space-sm);
117
+ }
118
+
119
+ .step-title {
120
+ font-size: var(--mobile-text-xl);
121
+ margin-bottom: var(--mobile-space-sm);
122
+ }
123
+
124
+ .step-intro {
125
+ font-size: var(--mobile-text-sm);
126
+ margin-bottom: var(--mobile-space-md);
127
+ }
128
+
129
+ .step-heading {
130
+ font-size: var(--mobile-text-xl);
131
+ }
132
+
133
+ .step-subheading {
134
+ font-size: var(--mobile-text-sm);
135
+ }
136
+
137
+ /* Reduce progress indicator size in landscape */
138
+ .step-marker {
139
+ width: 1.75rem;
140
+ height: 1.75rem;
141
+ font-size: 0.625rem;
142
+ }
143
+
144
+ .step-label {
145
+ font-size: 0.5625rem;
146
+ }
147
+
148
+ /* Make action buttons horizontal in landscape */
149
+ .onboarding-actions {
150
+ flex-direction: row;
151
+ gap: var(--mobile-space-sm);
152
+ }
153
+
154
+ .primary-action,
155
+ .secondary-action {
156
+ padding: var(--mobile-space-sm) var(--mobile-space-md);
157
+ min-width: auto;
158
+ font-size: var(--mobile-text-sm);
159
+ }
160
+ }
161
+
162
+ /* ======================
163
+ Touch-Friendly Enhancements
164
+ ====================== */
165
+
166
+ @media (hover: none) and (pointer: coarse) {
167
+ /* Increase touch target sizes */
168
+ :where(.onboarding-container) button,
169
+ :where(.onboarding-container) input[type="button"],
170
+ :where(.onboarding-container) input[type="submit"],
171
+ :where(.onboarding-container) input[type="reset"],
172
+ :where(.onboarding-container) a.primary-action,
173
+ :where(.onboarding-container) a.secondary-action,
174
+ :where(.onboarding-container) .skip-action,
175
+ :where(.onboarding-container) .feature-button,
176
+ :where(.onboarding-container) .tooltip-action,
177
+ :where(.onboarding-container) .tour-btn {
178
+ min-height: 3rem; /* 48px minimum for better touch */
179
+ min-width: 3rem;
180
+ padding: var(--mobile-space-md) var(--mobile-space-lg);
181
+ }
182
+
183
+ /* Increase spacing between interactive elements */
184
+ .onboarding-actions {
185
+ gap: var(--mobile-space-lg);
186
+ }
187
+
188
+ .navigation-buttons {
189
+ gap: var(--mobile-space-lg);
190
+ }
191
+
192
+ /* Larger checkbox and radio inputs */
193
+ :where(.onboarding-container) input[type="checkbox"],
194
+ :where(.onboarding-container) input[type="radio"] {
195
+ width: 1.5rem;
196
+ height: 1.5rem;
197
+ min-width: 1.5rem;
198
+ min-height: 1.5rem;
199
+ }
200
+
201
+ /* Better spacing for form fields */
202
+ .onboarding-form-group {
203
+ margin-bottom: var(--mobile-space-xl);
204
+ }
205
+
206
+ :where(.onboarding-container) input[type="text"],
207
+ :where(.onboarding-container) input[type="email"],
208
+ :where(.onboarding-container) select,
209
+ :where(.onboarding-container) textarea {
210
+ padding: var(--mobile-space-md) var(--mobile-space-lg);
211
+ font-size: var(--mobile-text-base);
212
+ min-height: 3rem;
213
+ }
214
+
215
+ /* Increase touch targets for action choices */
216
+ .action-choice {
217
+ padding: var(--mobile-space-xl);
218
+ margin-bottom: var(--mobile-space-md);
219
+ }
220
+
221
+ .action-radio {
222
+ width: 1.5rem;
223
+ height: 1.5rem;
224
+ top: var(--mobile-space-xl);
225
+ right: var(--mobile-space-xl);
226
+ }
227
+
228
+ /* Better touch targets for feature cards */
229
+ .feature-card {
230
+ padding: var(--mobile-space-xl);
231
+ min-height: 12rem;
232
+ }
233
+
234
+ /* Remove hover effects on touch devices */
235
+ .action-choice:hover,
236
+ .feature-card:hover,
237
+ .feature-button:hover,
238
+ .primary-action:hover,
239
+ .secondary-action:hover {
240
+ transform: none;
241
+ }
242
+
243
+ /* Use active states instead */
244
+ .action-choice:active,
245
+ .feature-card:active,
246
+ .feature-button:active,
247
+ .primary-action:active:not(:disabled),
248
+ .secondary-action:active {
249
+ transform: scale(0.98);
250
+ opacity: 0.9;
251
+ }
252
+ }
253
+
254
+ /* ======================
255
+ Mobile Navigation Patterns
256
+ ====================== */
257
+
258
+ @media screen and (max-width: 47.9375em) {
259
+ /* Stack navigation vertically on mobile */
260
+ .navigation-buttons {
261
+ flex-direction: column-reverse;
262
+ gap: var(--mobile-space-md);
263
+ }
264
+
265
+ .navigation-previous,
266
+ .navigation-center,
267
+ .navigation-help,
268
+ .navigation-spacer {
269
+ width: 100%;
270
+ min-width: auto;
271
+ text-align: center;
272
+ }
273
+
274
+ .navigation-center {
275
+ order: -1;
276
+ }
277
+
278
+ /* Full-width action buttons on mobile */
279
+ .onboarding-actions {
280
+ flex-direction: column;
281
+ width: 100%;
282
+ }
283
+
284
+ .primary-action,
285
+ .secondary-action,
286
+ .skip-action {
287
+ width: 100%;
288
+ min-width: auto;
289
+ justify-content: center;
290
+ }
291
+
292
+ /* Mobile-optimized progress indicator */
293
+ .progress-steps {
294
+ gap: var(--mobile-space-xs);
295
+ overflow-x: auto;
296
+ -webkit-overflow-scrolling: touch;
297
+ scrollbar-width: none;
298
+ -ms-overflow-style: none;
299
+ }
300
+
301
+ .progress-steps::-webkit-scrollbar {
302
+ display: none;
303
+ }
304
+
305
+ .progress-step {
306
+ min-width: 3.5rem;
307
+ flex-shrink: 0;
308
+ }
309
+
310
+ .step-label {
311
+ font-size: 0.625rem;
312
+ overflow: hidden;
313
+ text-overflow: ellipsis;
314
+ white-space: nowrap;
315
+ max-width: 4rem;
316
+ }
317
+
318
+ /* Compact step markers */
319
+ .step-marker {
320
+ width: 2rem;
321
+ height: 2rem;
322
+ font-size: 0.625rem;
323
+ }
324
+ }
325
+
326
+ /* ======================
327
+ Responsive Typography
328
+ ====================== */
329
+
330
+ /* Fluid typography for better scaling */
331
+ @media screen and (max-width: 47.9375em) {
332
+ .step-title,
333
+ .step-heading {
334
+ font-size: clamp(1.375rem, 5vw, 1.875rem);
335
+ }
336
+
337
+ .step-intro,
338
+ .step-subheading {
339
+ font-size: clamp(0.9375rem, 3.5vw, 1.125rem);
340
+ }
341
+
342
+ .feature-card .feature-title {
343
+ font-size: clamp(1rem, 4vw, 1.125rem);
344
+ }
345
+
346
+ .choice-title {
347
+ font-size: clamp(1.0625rem, 4vw, 1.25rem);
348
+ }
349
+
350
+ .welcome-features h2,
351
+ .next-steps h2 {
352
+ font-size: clamp(1.125rem, 4.5vw, 1.5rem);
353
+ }
354
+ }
355
+
356
+ /* ======================
357
+ Mobile Layout Optimizations
358
+ ====================== */
359
+
360
+ @media screen and (max-width: 47.9375em) {
361
+ /* Single column layout for forms */
362
+ .profile-settings {
363
+ padding: var(--mobile-space-lg);
364
+ }
365
+
366
+ /* Stack feature grid on mobile */
367
+ .feature-grid {
368
+ grid-template-columns: 1fr;
369
+ gap: var(--mobile-space-md);
370
+ }
371
+
372
+ /* Mobile-optimized feature list */
373
+ .feature-list {
374
+ gap: var(--mobile-space-sm);
375
+ }
376
+
377
+ .feature-item {
378
+ padding: var(--mobile-space-md);
379
+ gap: var(--mobile-space-sm);
380
+ }
381
+
382
+ .feature-icon {
383
+ font-size: var(--mobile-text-lg);
384
+ }
385
+
386
+ .feature-text {
387
+ font-size: var(--mobile-text-sm);
388
+ }
389
+
390
+ /* Optimize action choices for mobile */
391
+ .action-choices {
392
+ gap: var(--mobile-space-md);
393
+ }
394
+
395
+ .choice-content {
396
+ gap: var(--mobile-space-sm);
397
+ }
398
+
399
+ .choice-icon {
400
+ font-size: 2rem;
401
+ }
402
+
403
+ .choice-description {
404
+ font-size: var(--mobile-text-sm);
405
+ }
406
+
407
+ /* Mobile-friendly help tooltip */
408
+ .help-tooltip {
409
+ position: fixed;
410
+ top: 50%;
411
+ left: 50%;
412
+ right: auto;
413
+ bottom: auto;
414
+ transform: translate(-50%, -50%);
415
+ max-width: calc(100vw - 2rem);
416
+ width: calc(100vw - 2rem);
417
+ margin: 0;
418
+ z-index: 10002;
419
+ }
420
+
421
+ .help-tooltip::after {
422
+ display: none;
423
+ }
424
+
425
+ /* Add backdrop for mobile tooltips */
426
+ .help-tooltip::before {
427
+ content: '';
428
+ position: fixed;
429
+ top: 0;
430
+ left: 0;
431
+ width: 100vw;
432
+ height: 100vh;
433
+ background: rgba(0, 0, 0, 0.5);
434
+ z-index: -1;
435
+ }
436
+ }
437
+
438
+ /* ======================
439
+ Safe Area Support
440
+ ====================== */
441
+
442
+ @supports (padding: max(0px)) {
443
+ @media screen and (max-width: 47.9375em) {
444
+ .onboarding-container {
445
+ padding-top: max(0px, var(--safe-area-inset-top));
446
+ padding-bottom: max(0px, var(--safe-area-inset-bottom));
447
+ padding-left: max(0px, var(--safe-area-inset-left));
448
+ padding-right: max(0px, var(--safe-area-inset-right));
449
+ }
450
+
451
+ .onboarding-content {
452
+ padding-left: max(var(--mobile-space-md), var(--safe-area-inset-left));
453
+ padding-right: max(var(--mobile-space-md), var(--safe-area-inset-right));
454
+ padding-bottom: max(var(--mobile-space-lg), var(--safe-area-inset-bottom));
455
+ }
456
+
457
+ .onboarding-footer {
458
+ padding-bottom: max(var(--onboarding-space-lg), var(--safe-area-inset-bottom));
459
+ }
460
+
461
+ /* Modal/Tour safe areas */
462
+ .tour-popup {
463
+ bottom: max(1rem, var(--safe-area-inset-bottom));
464
+ left: max(1rem, var(--safe-area-inset-left));
465
+ right: max(1rem, var(--safe-area-inset-right));
466
+ }
467
+ }
468
+ }
469
+
470
+ /* ======================
471
+ Performance Optimizations
472
+ ====================== */
473
+
474
+ @media screen and (max-width: 47.9375em) {
475
+ /* Reduce animation complexity on mobile */
476
+ .onboarding-container[data-step-changed] .step-content {
477
+ animation: onboarding-mobileFadeIn 0.2s ease-out;
478
+ }
479
+
480
+ @keyframes onboarding-mobileFadeIn {
481
+ from {
482
+ opacity: 0;
483
+ }
484
+ to {
485
+ opacity: 1;
486
+ }
487
+ }
488
+
489
+ /* Simplify gradient animations */
490
+ .onboarding-progress-fill,
491
+ .time-estimate,
492
+ .milestone-points {
493
+ background: var(--onboarding-primary);
494
+ }
495
+
496
+ /* Disable hover animations on mobile */
497
+ @media (hover: none) {
498
+ .feature-card:hover,
499
+ .action-choice:hover {
500
+ box-shadow: var(--onboarding-shadow-md);
501
+ transform: none;
502
+ }
503
+ }
504
+ }
505
+
506
+ /* ======================
507
+ Swipe Gesture Support
508
+ ====================== */
509
+
510
+ @media screen and (max-width: 47.9375em) {
511
+ /* Enable smooth scrolling for swipeable content */
512
+ .progress-steps,
513
+ .feature-grid,
514
+ .action-choices {
515
+ scroll-behavior: smooth;
516
+ -webkit-overflow-scrolling: touch;
517
+ }
518
+
519
+ /* Add visual cue for scrollable content */
520
+ .progress-steps::after {
521
+ content: '';
522
+ position: absolute;
523
+ right: 0;
524
+ top: 0;
525
+ bottom: 0;
526
+ width: 2rem;
527
+ background: linear-gradient(to left, var(--onboarding-background), transparent);
528
+ pointer-events: none;
529
+ }
530
+ }
531
+
532
+ /* ======================
533
+ Mobile-Specific Utilities
534
+ ====================== */
535
+
536
+ /* Hide on mobile */
537
+ @media screen and (max-width: 47.9375em) {
538
+ .mobile-hidden {
539
+ display: none !important;
540
+ }
541
+
542
+ .mobile-visible {
543
+ display: block !important;
544
+ }
545
+
546
+ /* Stack vertically on mobile */
547
+ .mobile-stack {
548
+ flex-direction: column !important;
549
+ }
550
+
551
+ /* Full width on mobile */
552
+ .mobile-full {
553
+ width: 100% !important;
554
+ }
555
+
556
+ /* Center on mobile */
557
+ .mobile-center {
558
+ text-align: center !important;
559
+ }
560
+
561
+ /* Compact padding on mobile */
562
+ .mobile-compact {
563
+ padding: var(--mobile-space-sm) !important;
564
+ }
565
+ }
566
+
567
+ /* Show only on mobile */
568
+ .mobile-only {
569
+ display: none;
570
+ }
571
+
572
+ @media screen and (max-width: 47.9375em) {
573
+ .mobile-only {
574
+ display: block;
575
+ }
576
+ }
577
+
578
+ /* ======================
579
+ Tablet-Specific Styles
580
+ ====================== */
581
+
582
+ @media screen and (min-width: 48em) and (max-width: 63.9375em) {
583
+ /* 2-column layout for tablets */
584
+ .feature-grid {
585
+ grid-template-columns: repeat(2, 1fr);
586
+ }
587
+
588
+ /* Tablet-optimized typography */
589
+ .step-title,
590
+ .step-heading {
591
+ font-size: var(--onboarding-text-3xl);
592
+ }
593
+
594
+ /* Compact action buttons for tablets */
595
+ .onboarding-actions {
596
+ flex-direction: row;
597
+ justify-content: center;
598
+ }
599
+
600
+ .primary-action,
601
+ .secondary-action {
602
+ min-width: 10rem;
603
+ }
604
+ }
605
+
606
+ /* Tablet landscape */
607
+ @media screen and (min-width: 48em) and (max-width: 63.9375em) and (orientation: landscape) {
608
+ .onboarding-content {
609
+ padding: var(--onboarding-space-lg) var(--onboarding-space-xl);
610
+ }
611
+
612
+ /* Optimize for wider viewport */
613
+ .feature-grid {
614
+ grid-template-columns: repeat(3, 1fr);
615
+ }
616
+ }
617
+
618
+ /* ======================
619
+ Mobile Dark Mode
620
+ ====================== */
621
+
622
+ @media screen and (max-width: 47.9375em) and (prefers-color-scheme: dark) {
623
+ .onboarding-container {
624
+ background: #000000;
625
+ }
626
+
627
+ /* Increase contrast for mobile dark mode */
628
+ .step-title,
629
+ .step-heading {
630
+ color: #ffffff;
631
+ }
632
+
633
+ .step-intro,
634
+ .step-subheading {
635
+ color: #d1d5db;
636
+ }
637
+
638
+ /* Better visibility for cards in dark mode */
639
+ .feature-card,
640
+ .action-choice,
641
+ .profile-settings {
642
+ border-color: #374151;
643
+ background: #1f2937;
644
+ }
645
+ }
646
+
647
+ /* ======================
648
+ Print Optimization for Mobile
649
+ ====================== */
650
+
651
+ @media print {
652
+ @page {
653
+ margin: 1cm;
654
+ size: A4 portrait;
655
+ }
656
+
657
+ .onboarding-container {
658
+ min-height: auto;
659
+ }
660
+
661
+ .step-content {
662
+ page-break-inside: avoid;
663
+ }
664
+
665
+ .feature-grid {
666
+ grid-template-columns: 1fr;
667
+ }
668
+
669
+ .onboarding-actions,
670
+ .navigation-buttons {
671
+ display: none;
672
+ }
673
+ }
674
+
675
+ /* ======================
676
+ Mobile Accessibility
677
+ ====================== */
678
+
679
+ @media screen and (max-width: 47.9375em) {
680
+ /* Larger focus indicators for mobile */
681
+ .onboarding-container *:focus-visible {
682
+ outline-width: 3px;
683
+ outline-offset: 3px;
684
+ }
685
+
686
+ /* Better contrast for mobile screens in bright light */
687
+ @media (prefers-contrast: high) {
688
+ .step-title,
689
+ .step-heading,
690
+ .feature-title,
691
+ .choice-title {
692
+ font-weight: 700;
693
+ color: #000000;
694
+ }
695
+
696
+ .primary-action,
697
+ .secondary-action {
698
+ border-width: 3px;
699
+ font-weight: 700;
700
+ }
701
+ }
702
+ }
703
+
704
+ /* ======================
705
+ Mobile Loading States
706
+ ====================== */
707
+
708
+ @media screen and (max-width: 47.9375em) {
709
+ .onboarding-loading::after {
710
+ width: 2rem;
711
+ height: 2rem;
712
+ margin: -1rem 0 0 -1rem;
713
+ border-width: 3px;
714
+ }
715
+
716
+ /* Mobile-friendly skeleton screens */
717
+ .onboarding-skeleton {
718
+ background: linear-gradient(
719
+ 90deg,
720
+ var(--onboarding-surface) 0%,
721
+ var(--onboarding-border) 50%,
722
+ var(--onboarding-surface) 100%
723
+ );
724
+ background-size: 200% 100%;
725
+ animation: onboarding-skeleton 1.5s ease-in-out infinite;
726
+ }
727
+
728
+ @keyframes onboarding-skeleton {
729
+ 0% {
730
+ background-position: 200% 0;
731
+ }
732
+ 100% {
733
+ background-position: -200% 0;
734
+ }
735
+ }
736
+ }
737
+
738
+ /* ======================
739
+ Mobile Input Enhancements
740
+ ====================== */
741
+
742
+ @media screen and (max-width: 47.9375em) {
743
+ /* Prevent zoom on input focus (iOS) */
744
+ :where(.onboarding-container) input[type="text"],
745
+ :where(.onboarding-container) input[type="email"],
746
+ :where(.onboarding-container) input[type="tel"],
747
+ :where(.onboarding-container) input[type="number"],
748
+ :where(.onboarding-container) select,
749
+ :where(.onboarding-container) textarea {
750
+ font-size: 16px; /* Prevents iOS zoom */
751
+ }
752
+
753
+ /* Better mobile keyboard handling */
754
+ .onboarding-container:has(input:focus),
755
+ .onboarding-container:has(textarea:focus),
756
+ .onboarding-container:has(select:focus) {
757
+ /* Account for keyboard overlay */
758
+ min-height: 100vh;
759
+ }
760
+
761
+ /* Larger select dropdowns on mobile */
762
+ :where(.onboarding-container) select {
763
+ background-size: 1.5rem;
764
+ padding-right: 2.5rem;
765
+ }
766
+
767
+ /* Better textarea sizing */
768
+ :where(.onboarding-container) textarea {
769
+ min-height: 8rem;
770
+ resize: vertical;
771
+ }
772
+ }
773
+
774
+ /* ======================
775
+ Mobile Error States
776
+ ====================== */
777
+
778
+ @media screen and (max-width: 47.9375em) {
779
+ .onboarding-error-message {
780
+ padding: var(--mobile-space-md);
781
+ font-size: var(--mobile-text-sm);
782
+ margin-top: var(--mobile-space-sm);
783
+ }
784
+
785
+ .step-error {
786
+ padding: var(--mobile-space-lg);
787
+ font-size: var(--mobile-text-sm);
788
+ }
789
+
790
+ /* Mobile-friendly validation messages */
791
+ :where(.onboarding-container) input:invalid,
792
+ :where(.onboarding-container) select:invalid,
793
+ :where(.onboarding-container) textarea:invalid {
794
+ border-width: 2px;
795
+ }
796
+ }
797
+
798
+ /* ======================
799
+ Foldable Device Support
800
+ ====================== */
801
+
802
+ @media (horizontal-viewport-segments: 2) {
803
+ /* Dual-screen / foldable device support */
804
+ .onboarding-content {
805
+ display: grid;
806
+ grid-template-columns: env(viewport-segment-width 0 0) env(viewport-segment-width 1 0);
807
+ gap: env(viewport-segment-right 0 0);
808
+ }
809
+ }
810
+
811
+ /* ======================
812
+ Mobile Milestone Display
813
+ ====================== */
814
+
815
+ @media screen and (max-width: 47.9375em) {
816
+ .milestone-progress {
817
+ flex-direction: column;
818
+ align-items: center;
819
+ gap: var(--mobile-space-sm);
820
+ }
821
+
822
+ .milestone-points,
823
+ .recent-milestone {
824
+ font-size: var(--mobile-text-xs);
825
+ padding: var(--mobile-space-xs) var(--mobile-space-md);
826
+ }
827
+ }
828
+
829
+ /* ======================
830
+ Mobile Tour/Modal Adjustments
831
+ ====================== */
832
+
833
+ @media screen and (max-width: 47.9375em) {
834
+ .tour-popup {
835
+ max-width: calc(100vw - 2rem);
836
+ width: calc(100vw - 2rem);
837
+ margin: 1rem;
838
+ }
839
+
840
+ .tour-popup-content {
841
+ padding: var(--mobile-space-lg);
842
+ }
843
+
844
+ .tour-popup-title {
845
+ font-size: var(--mobile-text-xl);
846
+ }
847
+
848
+ .tour-popup-body {
849
+ font-size: var(--mobile-text-sm);
850
+ }
851
+
852
+ .tour-btn {
853
+ padding: var(--mobile-space-md) var(--mobile-space-lg);
854
+ font-size: var(--mobile-text-base);
855
+ }
856
+ }