ultimate-jekyll-manager 0.0.118 → 0.0.120

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 (51) hide show
  1. package/CLAUDE.md +409 -23
  2. package/README.md +171 -2
  3. package/TODO.md +10 -2
  4. package/_backup/form-manager.backup.js +1020 -0
  5. package/dist/assets/js/core/auth.js +5 -4
  6. package/dist/assets/js/core/cookieconsent.js +24 -17
  7. package/dist/assets/js/core/exit-popup.js +15 -12
  8. package/dist/assets/js/core/social-sharing.js +8 -4
  9. package/dist/assets/js/libs/auth/pages.js +78 -149
  10. package/dist/assets/js/libs/dev.js +192 -129
  11. package/dist/assets/js/libs/form-manager.js +643 -775
  12. package/dist/assets/js/pages/account/index.js +3 -2
  13. package/dist/assets/js/pages/account/sections/api-keys.js +37 -52
  14. package/dist/assets/js/pages/account/sections/connections.js +37 -46
  15. package/dist/assets/js/pages/account/sections/delete.js +57 -78
  16. package/dist/assets/js/pages/account/sections/profile.js +37 -56
  17. package/dist/assets/js/pages/account/sections/security.js +102 -125
  18. package/dist/assets/js/pages/admin/notifications/new/index.js +73 -151
  19. package/dist/assets/js/pages/blog/index.js +33 -53
  20. package/dist/assets/js/pages/contact/index.js +112 -173
  21. package/dist/assets/js/pages/download/index.js +39 -86
  22. package/dist/assets/js/pages/oauth2/index.js +17 -17
  23. package/dist/assets/js/pages/payment/checkout/index.js +23 -36
  24. package/dist/assets/js/pages/pricing/index.js +5 -2
  25. package/dist/assets/js/pages/test/libraries/form-manager/index.js +194 -0
  26. package/dist/assets/themes/classy/css/components/_cards.scss +2 -2
  27. package/dist/defaults/_.env +6 -0
  28. package/dist/defaults/_.gitignore +7 -1
  29. package/dist/defaults/dist/_includes/core/body.html +5 -13
  30. package/dist/defaults/dist/_includes/core/foot.html +1 -0
  31. package/dist/defaults/dist/_includes/themes/classy/frontend/sections/nav.html +51 -36
  32. package/dist/defaults/dist/_layouts/blueprint/admin/notifications/new.html +13 -2
  33. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/about.html +84 -42
  34. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/account/index.html +26 -21
  35. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/auth/signin.html +2 -2
  36. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/auth/signup.html +2 -2
  37. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/index.html +72 -58
  38. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/blog/post.html +46 -29
  39. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/contact.html +46 -53
  40. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/download.html +111 -73
  41. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/index.html +111 -56
  42. package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +127 -81
  43. package/dist/defaults/dist/pages/test/libraries/form-manager.html +181 -0
  44. package/dist/defaults/dist/pages/test/libraries/lazy-loading.html +1 -1
  45. package/dist/gulp/tasks/defaults.js +210 -1
  46. package/dist/gulp/tasks/serve.js +18 -0
  47. package/dist/lib/logger.js +1 -1
  48. package/firebase-debug.log +770 -0
  49. package/package.json +6 -6
  50. package/.playwright-mcp/page-2025-10-22T19-11-27-666Z.png +0 -0
  51. package/.playwright-mcp/page-2025-10-22T19-11-57-357Z.png +0 -0
@@ -5,8 +5,8 @@ layout: themes/[ site.theme.id ]/frontend/core/base
5
5
  ### PAGE CONFIG ###
6
6
  # Hero Section
7
7
  hero:
8
- headline: "The right plans, for the right"
9
- headline_accent: "price"
8
+ headline: "The right plans, "
9
+ headline_accent: "for the right price"
10
10
  subheadline: "Simple and affordable pricing. No hidden fees, no surprises."
11
11
 
12
12
  # Pricing Section
@@ -17,7 +17,7 @@ pricing:
17
17
  label: "credit" # What to call the unit (e.g., "credit", "user", "GB")
18
18
  plans:
19
19
  - id: "basic"
20
- name: Basic
20
+ name: "Basic"
21
21
  tagline: "best for getting started"
22
22
  url: "/download" # URL for free plan signup
23
23
  pricing:
@@ -26,7 +26,7 @@ pricing:
26
26
  features:
27
27
  - id: "credits"
28
28
  name: "Credits"
29
- value: 1
29
+ value: 10
30
30
  icon: "sparkles"
31
31
  - id: "exports"
32
32
  name: "Exports"
@@ -34,7 +34,7 @@ pricing:
34
34
  icon: "download"
35
35
 
36
36
  - id: "starter"
37
- name: Starter
37
+ name: "Starter"
38
38
  tagline: "best for individuals"
39
39
  pricing:
40
40
  monthly: 28
@@ -42,7 +42,7 @@ pricing:
42
42
  features:
43
43
  - id: "credits"
44
44
  name: "Credits"
45
- value: 10
45
+ value: 100
46
46
  icon: "sparkles"
47
47
  - id: "exports"
48
48
  name: "Exports"
@@ -58,7 +58,7 @@ pricing:
58
58
  icon: "headset"
59
59
 
60
60
  - id: "pro"
61
- name: Pro
61
+ name: "Pro"
62
62
  tagline: "best for small businesses"
63
63
  popular: true
64
64
  pricing:
@@ -67,7 +67,7 @@ pricing:
67
67
  features:
68
68
  - id: "credits"
69
69
  name: "Credits"
70
- value: 40
70
+ value: 200
71
71
  icon: "sparkles"
72
72
  - id: "exports"
73
73
  name: "Exports"
@@ -75,7 +75,7 @@ pricing:
75
75
  icon: "download"
76
76
 
77
77
  - id: "max"
78
- name: Max
78
+ name: "Max"
79
79
  tagline: "best for growing businesses"
80
80
  pricing:
81
81
  monthly: 100
@@ -83,7 +83,7 @@ pricing:
83
83
  features:
84
84
  - id: "credits"
85
85
  name: "Credits"
86
- value: 100
86
+ value: 500
87
87
  icon: "sparkles"
88
88
  - id: "exports"
89
89
  name: "Exports"
@@ -100,9 +100,11 @@ pricing:
100
100
 
101
101
  # Feature Comparison Section
102
102
  feature_comparison:
103
- superheadline: "{% uj_icon 'list-check' %} Features"
103
+ superheadline:
104
+ icon: "sparkles"
105
+ text: "Features"
104
106
  headline: "Compare all"
105
- headline_accent: "Plans"
107
+ headline_accent: "plans"
106
108
  subheadline: "See exactly what's included in each plan"
107
109
 
108
110
  # Social Proof Section
@@ -125,19 +127,24 @@ social_proof:
125
127
 
126
128
  # CTA Section
127
129
  cta:
128
- superheadline: "{% uj_icon 'comments' %} Support"
130
+ superheadline:
131
+ icon: "comments"
132
+ text: "Support"
129
133
  headline: "Need help finding the right plan for your"
130
134
  headline_accent: "needs?"
131
135
  subheadline: "Talk to our support team 24/7"
132
136
  button:
133
137
  text: "Talk to Us"
134
- icon: "comments"
138
+ icon: "headset"
135
139
  href: "/contact"
136
140
 
137
141
  # Testimonials Section
138
142
  testimonials:
139
- superheadline: "{% uj_icon 'comments' %} Testimonials"
140
- headline: "People {% uj_icon \"heart\", \"text-danger\" %} {{ site.brand.name }}"
143
+ superheadline:
144
+ icon: "megaphone"
145
+ text: "Testimonials"
146
+ headline: "People {% uj_icon \"heart\", \"text-danger\" %} "
147
+ headline_accent: "{{ site.brand.name }}"
141
148
  subheadline: "Hear from real people who have transformed their business with us"
142
149
  items:
143
150
  - quote: "This platform transformed my business. The support is incredible!"
@@ -158,10 +165,12 @@ testimonials:
158
165
 
159
166
  # FAQs Section
160
167
  faqs:
161
- superheadline: "{% uj_icon 'circle-question' %} FAQs"
162
- headline: "Frequently Asked"
163
- headline_accent: "Questions"
164
- subheadline: "Everything you need to know about the product and billing. Can't find the answer you're looking for? Please chat to our friendly team."
168
+ superheadline:
169
+ icon: "messages-question"
170
+ text: "FAQs"
171
+ headline: "Frequently asked"
172
+ headline_accent: "questions"
173
+ subheadline: "Everything you need to know about {{ site.brand.name }} billing & subscriptions."
165
174
  items:
166
175
  # - question: "Is {{ site.brand.name }} AI included with my existing {{ site.brand.name }} Studio plan?"
167
176
  # answer: "No, {{ site.brand.name }} AI and {{ site.brand.name }} Studio function as separate products with individual pricing plans. If you were an active lifetime deal holder of {{ site.brand.name }} Studio and had purchased it before August 15, 2023, you'll qualify for free {{ site.brand.name }} AI credits. These will be phased in gradually, and you'll be notified via email when they become available. As for other {{ site.brand.name }} Studio subscribers, we're actively exploring ways to offer some benefits to help you get started on {{ site.brand.name }} AI. Stay tuned for more announcements.<br><br>PS: This is available exclusively to users who have purchased their {{ site.brand.name }} accounts from {{ site.brand.name }}."
@@ -210,7 +219,7 @@ faqs:
210
219
  {{ page.resolved.hero.headline }} <span class="text-gradient-rainbow">{{ page.resolved.hero.headline_accent }}</span>
211
220
  </h1>
212
221
  {% iftruthy page.resolved.hero.subheadline %}
213
- <p class="fs-5 text-muted mb-0">
222
+ <p class="fs-5 text-muted">
214
223
  {{ page.resolved.hero.subheadline }}
215
224
  </p>
216
225
  {% endiftruthy %}
@@ -247,6 +256,31 @@ faqs:
247
256
 
248
257
  {% assign plan_count = page.resolved.pricing.plans | size %}
249
258
 
259
+ <!-- Automatically detect common features across ALL plans -->
260
+ {% assign common_feature_ids = "" | split: "," %}
261
+ {% if plan_count > 0 %}
262
+ {% assign first_plan = page.resolved.pricing.plans[0] %}
263
+ {% for first_feature in first_plan.features %}
264
+ {% assign is_common = true %}
265
+ {% for check_plan in page.resolved.pricing.plans %}
266
+ {% assign found_in_plan = false %}
267
+ {% for check_feature in check_plan.features %}
268
+ {% if check_feature.id == first_feature.id %}
269
+ {% assign found_in_plan = true %}
270
+ {% break %}
271
+ {% endif %}
272
+ {% endfor %}
273
+ {% unless found_in_plan %}
274
+ {% assign is_common = false %}
275
+ {% break %}
276
+ {% endunless %}
277
+ {% endfor %}
278
+ {% if is_common %}
279
+ {% assign common_feature_ids = common_feature_ids | push: first_feature.id %}
280
+ {% endif %}
281
+ {% endfor %}
282
+ {% endif %}
283
+
250
284
  <!-- Determine column classes based on number of plans -->
251
285
  {% if plan_count == 1 %}
252
286
  {% assign col_classes = "col-12 col-md-8 col-lg-6 col-xl-5" %}
@@ -287,10 +321,10 @@ faqs:
287
321
 
288
322
  <!-- Price -->
289
323
  {% if plan.pricing.monthly == 0 %}
290
- <p class="display-5 fw-bold mb-0">Free</p>
324
+ <p class="display-6 fw-bold mb-0">Free</p>
291
325
  {% else %}
292
326
  <p class="mb-0">
293
- <span class="display-5 fw-bold">
327
+ <span class="display-6 fw-bold">
294
328
  <span class="fs-3">$</span><span class="amount" data-monthly="{{ plan.pricing.monthly }}" data-annually="{{ plan.pricing.annually | divided_by: 12 | round }}">{{ plan.pricing.annually | divided_by: 12 | round }}</span>
295
329
  </span>
296
330
  <small class="text-muted">/month</small>
@@ -343,28 +377,27 @@ faqs:
343
377
  {% if plan.pricing.monthly == 0 %}
344
378
  <span>No credit card required</span>
345
379
  {% else %}
346
- <span class="billing-info" data-monthly="Billed ${{ plan.pricing.monthly }} monthly" data-annually="Billed ${{ plan.pricing.annually }} annually">
347
- Billed ${{ plan.pricing.annually }} annually
380
+ <span class="billing-info" data-monthly="Billed ${{ plan.pricing.monthly | uj_commaify }} monthly" data-annually="Billed ${{ plan.pricing.annually | uj_commaify }} annually">
381
+ Billed ${{ plan.pricing.annually | uj_commaify }} annually
348
382
  </span>
349
383
  {% endif %}
350
384
  </p>
351
385
 
352
- <hr>
386
+ <hr class="border-1">
353
387
 
354
388
  <!-- Features -->
355
389
  <div>
356
390
  <!-- Common features that vary by plan -->
357
391
  <ul class="list-unstyled mb-3">
358
- {% assign common_features = "credits,exports,video_mins" | split: "," %}
359
392
  {% for feature in plan.features %}
360
- {% if common_features contains feature.id %}
393
+ {% if common_feature_ids contains feature.id %}
361
394
  <li class="d-flex align-items-start mb-2">
362
395
  <span class="me-3">{% uj_icon feature.icon, "fa-md" %}</span>
363
396
  <span>
364
397
  {% if feature.value == "Unlimited" %}
365
398
  Unlimited {{ feature.name }}
366
399
  {% else %}
367
- {{ feature.value }} {{ feature.name }}
400
+ {{ feature.value | uj_commaify }} {{ feature.name }}
368
401
  {% endif %}
369
402
  </span>
370
403
  </li>
@@ -377,7 +410,7 @@ faqs:
377
410
  <!-- Check if there are additional features -->
378
411
  {% assign has_additional = false %}
379
412
  {% for feature in plan.features %}
380
- {% unless common_features contains feature.id %}
413
+ {% unless common_feature_ids contains feature.id %}
381
414
  {% assign has_additional = true %}
382
415
  {% break %}
383
416
  {% endunless %}
@@ -401,7 +434,7 @@ faqs:
401
434
  {% if has_additional %}
402
435
  <ul class="list-unstyled mb-0">
403
436
  {% for feature in plan.features %}
404
- {% unless common_features contains feature.id %}
437
+ {% unless common_feature_ids contains feature.id %}
405
438
  <li class="d-flex align-items-start mb-2 {% if forloop.last %}mb-0{% endif %}">
406
439
  <span class="me-3">{% uj_icon feature.icon, "fa-md" %}</span>
407
440
  <span>
@@ -410,7 +443,7 @@ faqs:
410
443
  {% elsif feature.value == "Included" or feature.value == "Available" or feature.value == "Full" %}
411
444
  {{ feature.name }}
412
445
  {% else %}
413
- {{ feature.value }} {{ feature.name }}
446
+ {{ feature.value | uj_commaify }} {{ feature.name }}
414
447
  {% endif %}
415
448
  </span>
416
449
  </li>
@@ -454,8 +487,13 @@ faqs:
454
487
  <section>
455
488
  <div class="container">
456
489
  <div class="text-center mb-5" data-lazy="@class animation-slide-up">
457
- {% iftruthy page.resolved.feature_comparison.superheadline %}
458
- <span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">{{ page.resolved.feature_comparison.superheadline }}</span>
490
+ {% iftruthy page.resolved.feature_comparison.superheadline.text %}
491
+ <span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">
492
+ {% iftruthy page.resolved.feature_comparison.superheadline.icon %}
493
+ {% uj_icon page.resolved.feature_comparison.superheadline.icon, "me-1" %}
494
+ {% endiftruthy %}
495
+ {{ page.resolved.feature_comparison.superheadline.text }}
496
+ </span>
459
497
  {% endiftruthy %}
460
498
  <h2 class="h2 mb-2">
461
499
  {{ page.resolved.feature_comparison.headline }}
@@ -597,53 +635,46 @@ faqs:
597
635
 
598
636
  <!-- CTA Section -->
599
637
  <section>
600
- <div class="container" data-lazy="@class animation-slide-up">
601
- <!-- style="background: linear-gradient(135deg, #2d2d2d 0%, #673ab7 50%, #2196f3 100%);" -->
602
- <div class="rounded-4 p-5 position-relative overflow-hidden bg-primary bg-gradient">
603
- <div class="row align-items-center py-4">
604
- <div class="col-lg-7 text-light">
605
- {% iftruthy page.resolved.cta.superheadline %}
606
- <span class="badge bg-white bg-opacity-25 text-light p-2 mb-1 fw-semibold small">{{ page.resolved.cta.superheadline }}</span>
607
- {% endiftruthy %}
608
- <h2 class="h2 mb-2">
609
- {{ page.resolved.cta.headline }}
610
- {% iftruthy page.resolved.cta.headline_accent %}
611
- <span class="text-accent">{{ page.resolved.cta.headline_accent }}</span>
638
+ <div class="container">
639
+ <div class="card border-0 bg-gradient bg-primary text-white rounded-4 p-4 p-md-5 text-center position-relative overflow-hidden" data-lazy="@class animation-slide-up">
640
+ <!-- Decorative icon - top right -->
641
+ <div class="position-absolute top-0 end-0 opacity-25" style="font-size:10rem;transform:rotate(15deg)translate(30%,-30%)">
642
+ {% uj_icon "messages-question", "text-white" %}
643
+ </div>
644
+
645
+ <!-- Decorative icon - bottom left -->
646
+ <div class="position-absolute bottom-0 start-0 opacity-25" style="font-size:8rem;transform:rotate(-20deg)translate(-30%,30%)">
647
+ {% uj_icon "shield-check", "text-white" %}
648
+ </div>
649
+
650
+ <div class="position-relative">
651
+ {% iftruthy page.resolved.cta.superheadline.text %}
652
+ <span class="badge bg-white bg-opacity-25 text-light p-2 mb-3 fw-semibold small">
653
+ {% iftruthy page.resolved.cta.superheadline.icon %}
654
+ {% uj_icon page.resolved.cta.superheadline.icon, "me-1" %}
612
655
  {% endiftruthy %}
613
- </h2>
614
- {% iftruthy page.resolved.cta.subheadline %}
615
- <p class="fs-5 mb-4 opacity-90">{{ page.resolved.cta.subheadline }}</p>
656
+ {{ page.resolved.cta.superheadline.text }}
657
+ </span>
658
+ {% endiftruthy %}
659
+
660
+ <h2 class="h3 fw-bold mb-3">
661
+ {{ page.resolved.cta.headline }}
662
+ {% iftruthy page.resolved.cta.headline_accent %}
663
+ <span class="text-accent">{{ page.resolved.cta.headline_accent }}</span>
616
664
  {% endiftruthy %}
617
- <a href="{{ page.resolved.cta.button.href }}" class="btn btn-adaptive btn-lg px-5 py-3">
665
+ </h2>
666
+
667
+ {% iftruthy page.resolved.cta.subheadline %}
668
+ <p class="lead mb-4">{{ page.resolved.cta.subheadline }}</p>
669
+ {% endiftruthy %}
670
+
671
+ <div class="d-flex flex-column flex-sm-row gap-3 justify-content-center">
672
+ <a href="{{ page.resolved.cta.button.href }}" class="btn btn-light btn-lg px-4">
618
673
  {% uj_icon page.resolved.cta.button.icon, "me-2" %}
619
674
  {{ page.resolved.cta.button.text }}
620
675
  </a>
621
676
  </div>
622
- <div class="col-lg-5 d-none d-lg-block position-relative">
623
- <div class="text-end">
624
- <div class="d-inline-block position-relative">
625
- <!-- <div class="rounded-circle bg-white bg-opacity-25 p-5" style="backdrop-filter: blur(10px);">
626
- <img src="https://via.placeholder.com/300x300/ffffff00/ffffff?text=👩‍💻"
627
- alt="Support"
628
- class="img-fluid"
629
- style="filter: drop-shadow(0 10px 30px rgba(0,0,0,0.3));">
630
- </div> -->
631
- <!-- <div class="position-absolute bottom-0 end-0 bg-white rounded-circle p-3 shadow-lg">
632
- </div> -->
633
- <div class="position-absolute bottom-0 end-0 p-3">
634
- {% uj_icon "comment-dots", "text-light display-1" %}
635
- </div>
636
- </div>
637
- </div>
638
- </div>
639
677
  </div>
640
- <!-- Decorative elements -->
641
- <!-- <div class="position-absolute top-0 end-0 opacity-25">
642
- <div class="rounded-circle" style="width: 400px; height: 400px; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); transform: translate(50%, -50%);"></div>
643
- </div>
644
- <div class="position-absolute bottom-0 start-0 opacity-25">
645
- <div class="rounded-circle" style="width: 300px; height: 300px; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); transform: translate(-50%, 50%);"></div>
646
- </div> -->
647
678
  </div>
648
679
  </div>
649
680
  </section>
@@ -652,10 +683,20 @@ faqs:
652
683
  <section>
653
684
  <div class="container">
654
685
  <div class="text-center mb-5" data-lazy="@class animation-slide-up">
655
- {% iftruthy page.resolved.testimonials.superheadline %}
656
- <span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">{{ page.resolved.testimonials.superheadline }}</span>
686
+ {% iftruthy page.resolved.testimonials.superheadline.text %}
687
+ <span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">
688
+ {% iftruthy page.resolved.testimonials.superheadline.icon %}
689
+ {% uj_icon page.resolved.testimonials.superheadline.icon, "me-1" %}
690
+ {% endiftruthy %}
691
+ {{ page.resolved.testimonials.superheadline.text }}
692
+ </span>
657
693
  {% endiftruthy %}
658
- <h2 class="h2 mb-2">{{ page.resolved.testimonials.headline }}</h2>
694
+ <h2 class="h2 mb-2">
695
+ {{ page.resolved.testimonials.headline }}
696
+ {% iftruthy page.resolved.testimonials.headline_accent %}
697
+ <span class="text-accent">{{ page.resolved.testimonials.headline_accent }}</span>
698
+ {% endiftruthy %}
699
+ </h2>
659
700
  {% iftruthy page.resolved.testimonials.subheadline %}
660
701
  <p class="fs-5 text-muted">{{ page.resolved.testimonials.subheadline }}</p>
661
702
  {% endiftruthy %}
@@ -711,9 +752,14 @@ faqs:
711
752
  <div class="container">
712
753
  <div class="row justify-content-center">
713
754
  <div class="col-lg-8">
714
- <div class="text-center mb-4" data-lazy="@class animation-slide-up">
715
- {% iftruthy page.resolved.faqs.superheadline %}
716
- <span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">{{ page.resolved.faqs.superheadline }}</span>
755
+ <div class="text-center mb-5" data-lazy="@class animation-slide-up">
756
+ {% iftruthy page.resolved.faqs.superheadline.text %}
757
+ <span class="badge bg-body-tertiary border-gradient-rainbow border-1 text-body p-2 mb-1 fw-semibold small">
758
+ {% iftruthy page.resolved.faqs.superheadline.icon %}
759
+ {% uj_icon page.resolved.faqs.superheadline.icon, "me-1" %}
760
+ {% endiftruthy %}
761
+ {{ page.resolved.faqs.superheadline.text }}
762
+ </span>
717
763
  {% endiftruthy %}
718
764
  <h2 class="h2 mb-2">
719
765
  {{ page.resolved.faqs.headline }}
@@ -722,7 +768,7 @@ faqs:
722
768
  {% endiftruthy %}
723
769
  </h2>
724
770
  {% iftruthy page.resolved.faqs.subheadline %}
725
- <p class="fs-5 text-muted mb-0">{{ page.resolved.faqs.subheadline }}</p>
771
+ <p class="fs-5 text-muted">{{ page.resolved.faqs.subheadline }}</p>
726
772
  {% endiftruthy %}
727
773
  </div>
728
774
 
@@ -0,0 +1,181 @@
1
+ ---
2
+ layout: themes/[ site.theme.id ]/frontend/core/base
3
+ title: FormManager Test
4
+ permalink: /test/libraries/form-manager
5
+ sitemap: false
6
+ ---
7
+
8
+ <div class="container py-5">
9
+ <h1 class="mb-4">FormManager Test Page</h1>
10
+ <p class="text-muted mb-5">Testing different configurations of the FormManager library.</p>
11
+
12
+ <div class="row g-4">
13
+
14
+ <!-- Test 1: Full Test (success/fail, nested, change events) -->
15
+ <div class="col-lg-8">
16
+ <div class="card">
17
+ <div class="card-header">
18
+ <h5 class="mb-0">Test 1: Full Test</h5>
19
+ <small class="text-muted">Success/failure toggle, nested dot notation, change events (check console)</small>
20
+ </div>
21
+ <div class="card-body">
22
+ <form id="test-form-main">
23
+ <div class="row">
24
+ <div class="col-md-6">
25
+ <div class="mb-3">
26
+ <label for="main-name" class="form-label">user.name</label>
27
+ <input type="text" class="form-control" id="main-name" name="user.name" value="Ian">
28
+ </div>
29
+ <div class="mb-3">
30
+ <label for="main-email" class="form-label">user.email</label>
31
+ <input type="email" class="form-control" id="main-email" name="user.email" value="ian@example.com">
32
+ </div>
33
+ <div class="mb-3">
34
+ <label for="main-city" class="form-label">user.address.city</label>
35
+ <input type="text" class="form-control" id="main-city" name="user.address.city" value="NYC">
36
+ </div>
37
+ </div>
38
+ <div class="col-md-6">
39
+ <div class="mb-3">
40
+ <label for="main-outcome" class="form-label">Simulate Outcome</label>
41
+ <select class="form-select" id="main-outcome" name="settings.outcome">
42
+ <option value="success">Success</option>
43
+ <option value="error">Error (throw Error)</option>
44
+ </select>
45
+ </div>
46
+ <div class="mb-3">
47
+ <label class="form-label d-block">preferences.notifications (radio group)</label>
48
+ <div class="form-check form-check-inline">
49
+ <input type="radio" class="form-check-input" id="notif-all" name="preferences.notifications" value="all" checked>
50
+ <label class="form-check-label" for="notif-all">All</label>
51
+ </div>
52
+ <div class="form-check form-check-inline">
53
+ <input type="radio" class="form-check-input" id="notif-important" name="preferences.notifications" value="important">
54
+ <label class="form-check-label" for="notif-important">Important</label>
55
+ </div>
56
+ <div class="form-check form-check-inline">
57
+ <input type="radio" class="form-check-input" id="notif-none" name="preferences.notifications" value="none">
58
+ <label class="form-check-label" for="notif-none">None</label>
59
+ </div>
60
+ </div>
61
+ <div class="mb-3">
62
+ <label class="form-label d-block">preferences.features (checkbox group)</label>
63
+ <div class="form-check">
64
+ <input type="checkbox" class="form-check-input" id="feat-darkmode" name="preferences.features" value="darkmode">
65
+ <label class="form-check-label" for="feat-darkmode">Dark Mode</label>
66
+ </div>
67
+ <div class="form-check">
68
+ <input type="checkbox" class="form-check-input" id="feat-analytics" name="preferences.features" value="analytics">
69
+ <label class="form-check-label" for="feat-analytics">Analytics</label>
70
+ </div>
71
+ <div class="form-check">
72
+ <input type="checkbox" class="form-check-input" id="feat-beta" name="preferences.features" value="beta">
73
+ <label class="form-check-label" for="feat-beta">Beta Features</label>
74
+ </div>
75
+ </div>
76
+ <div class="mb-3 form-check">
77
+ <input type="checkbox" class="form-check-input" id="main-subscribe" name="settings.subscribe">
78
+ <label class="form-check-label" for="main-subscribe">settings.subscribe (single checkbox)</label>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ <div class="d-flex gap-2">
83
+ <button type="submit" data-action="save" class="btn btn-primary">Save</button>
84
+ <button type="submit" data-action="draft" class="btn btn-outline-secondary">Save as Draft</button>
85
+ <button type="button" id="main-set-data" class="btn btn-outline-info">Set Data</button>
86
+ </div>
87
+ </form>
88
+ <div class="mt-3 d-flex gap-3">
89
+ <small class="text-muted" id="main-status">Status: ready</small>
90
+ <small class="text-muted" id="main-action">Action: -</small>
91
+ </div>
92
+ <div class="mt-3">
93
+ <pre id="main-output" class="bg-body-secondary p-2 rounded small" style="max-height: 200px; overflow: auto;">Submit to see collected data...</pre>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+
99
+ <!-- Test 2: Validation -->
100
+ <div class="col-lg-4">
101
+ <div class="card">
102
+ <div class="card-header d-flex justify-content-between align-items-start">
103
+ <div>
104
+ <h5 class="mb-0">Test 2: Validation</h5>
105
+ <small class="text-muted">HTML5 + custom validation event</small>
106
+ </div>
107
+ <button type="button" id="validation-set-correct" class="btn btn-sm btn-outline-success">Set Correct</button>
108
+ </div>
109
+ <div class="card-body">
110
+ <form id="test-form-validation">
111
+ <div class="mb-3">
112
+ <label for="validation-name" class="form-label">Name (required)</label>
113
+ <input type="text" class="form-control" id="validation-name" name="name" required>
114
+ </div>
115
+ <div class="mb-3">
116
+ <label for="validation-email" class="form-label">Email (required, valid format)</label>
117
+ <input type="email" class="form-control" id="validation-email" name="email" required>
118
+ </div>
119
+ <div class="mb-3">
120
+ <label for="validation-age" class="form-label">Age (required, must be 18+)</label>
121
+ <input type="number" class="form-control" id="validation-age" name="age" required min="1">
122
+ </div>
123
+ <div class="mb-3 form-check">
124
+ <input type="checkbox" class="form-check-input" id="validation-terms" name="terms" required>
125
+ <label class="form-check-label" for="validation-terms">I agree to the terms (required)</label>
126
+ </div>
127
+ <button type="submit" class="btn btn-primary">Submit</button>
128
+ </form>
129
+ <div class="mt-2">
130
+ <small class="text-muted" id="validation-status">Status: ready</small>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+
136
+ <!-- Test 3: Contact Form (one-time submit, reset on success) -->
137
+ <div class="col-lg-4">
138
+ <div class="card">
139
+ <div class="card-header">
140
+ <h5 class="mb-0">Test 3: Contact Form</h5>
141
+ <small class="text-muted">allowResubmit: false, resetOnSuccess: true</small>
142
+ </div>
143
+ <div class="card-body">
144
+ <form id="test-form-contact">
145
+ <div class="mb-3">
146
+ <label for="contact-message" class="form-label">Message</label>
147
+ <textarea class="form-control" id="contact-message" name="message" rows="2">Hello!</textarea>
148
+ </div>
149
+ <button type="submit" class="btn btn-primary">Send Message</button>
150
+ </form>
151
+ <div class="mt-2">
152
+ <small class="text-muted" id="contact-status">Status: ready</small>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ </div>
157
+
158
+ <!-- Test 4: Manual Ready -->
159
+ <div class="col-lg-4">
160
+ <div class="card">
161
+ <div class="card-header">
162
+ <h5 class="mb-0">Test 4: Manual Ready</h5>
163
+ <small class="text-muted">autoReady: false, ready after 2 seconds</small>
164
+ </div>
165
+ <div class="card-body">
166
+ <form id="test-form-manual">
167
+ <div class="mb-3">
168
+ <label for="manual-data" class="form-label">Data</label>
169
+ <input type="text" class="form-control" id="manual-data" name="data">
170
+ </div>
171
+ <button type="submit" class="btn btn-primary">Submit</button>
172
+ </form>
173
+ <div class="mt-2">
174
+ <small class="text-muted" id="manual-status">Status: initializing</small>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ </div>
181
+ </div>
@@ -42,7 +42,7 @@ meta:
42
42
  <!-- Spacer to push content below fold -->
43
43
  <div class="d-flex align-items-center justify-content-center text-muted vh-100">
44
44
  <div class="text-center">
45
- <i class="fas fa-arrow-down fa-3x mb-3"></i>
45
+ {% uj_icon "arrow-down", "fa-3x mb-3" %}
46
46
  <p class="h4">Scroll down to trigger lazy loading...</p>
47
47
  </div>
48
48
  </div>