ultimate-jekyll-manager 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/scheduled_tasks.lock +1 -0
- package/CHANGELOG.md +68 -1
- package/CLAUDE.md +36 -15
- package/README.md +4 -2
- package/TODO-AUTH-TESTING.md +1 -1
- package/dist/assets/js/libs/form-manager.js +4 -1
- package/dist/assets/js/pages/payment/confirmation/index.js +9 -0
- package/dist/assets/themes/newsflash/README.md +58 -0
- package/dist/assets/themes/newsflash/_config.scss +138 -0
- package/dist/assets/themes/newsflash/_theme.js +27 -0
- package/dist/assets/themes/newsflash/_theme.scss +37 -0
- package/dist/assets/themes/newsflash/css/base/_mixins.scss +50 -0
- package/dist/assets/themes/newsflash/css/base/_root.scss +134 -0
- package/dist/assets/themes/newsflash/css/base/_typography.scss +49 -0
- package/dist/assets/themes/newsflash/css/base/_utilities.scss +58 -0
- package/dist/assets/themes/newsflash/css/components/_badges.scss +65 -0
- package/dist/assets/themes/newsflash/css/components/_buttons.scss +139 -0
- package/dist/assets/themes/newsflash/css/components/_cards.scss +52 -0
- package/dist/assets/themes/newsflash/css/components/_editorial.scss +182 -0
- package/dist/assets/themes/newsflash/css/components/_forms.scss +75 -0
- package/dist/assets/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
- package/dist/assets/themes/newsflash/css/components/_panels.scss +91 -0
- package/dist/assets/themes/newsflash/css/components/_ticker.scss +70 -0
- package/dist/assets/themes/newsflash/css/layout/_general.scss +264 -0
- package/dist/assets/themes/newsflash/css/layout/_navigation.scss +164 -0
- package/dist/assets/themes/newsflash/js/initialize-tooltips.js +20 -0
- package/dist/assets/themes/newsflash/js/masthead-scroll.js +29 -0
- package/dist/assets/themes/newsflash/pages/404/index.scss +27 -0
- package/dist/assets/themes/newsflash/pages/about/index.scss +70 -0
- package/dist/assets/themes/newsflash/pages/blog/index.scss +17 -0
- package/dist/assets/themes/newsflash/pages/blog/post.js +29 -0
- package/dist/assets/themes/newsflash/pages/blog/post.scss +164 -0
- package/dist/assets/themes/newsflash/pages/index.scss +159 -0
- package/dist/assets/themes/newsflash/pages/pricing/index.scss +194 -0
- package/dist/assets/themes/newsflash/pages/test/libraries/layers/index.js +9 -0
- package/dist/assets/themes/newsflash/pages/test/libraries/layers/index.scss +7 -0
- package/dist/commands/blogify.js +6 -3
- package/dist/commands/test.js +34 -5
- package/dist/defaults/CLAUDE.md +17 -4
- package/dist/defaults/dist/_includes/core/pricing/resolve-plan.html +59 -0
- package/dist/defaults/dist/_includes/themes/classy/frontend/sections/footer.html +20 -3
- package/dist/defaults/dist/_layouts/themes/classy/admin/core/minimal-viewport-locked.html +1 -1
- package/dist/defaults/dist/_layouts/themes/classy/admin/core/minimal.html +1 -1
- package/dist/defaults/dist/_layouts/themes/classy/frontend/pages/pricing.html +5 -40
- package/dist/defaults/dist/_layouts/themes/neobrutalism/frontend/pages/pricing.html +33 -34
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/core/base.html +61 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/404.html +86 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/about.html +353 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/categories/category.html +105 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/categories/index.html +93 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/index.html +373 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/post.html +289 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/tags/index.html +90 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/blog/tags/tag.html +107 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/contact.html +340 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/index.html +522 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/pricing.html +485 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/team/index.html +207 -0
- package/dist/defaults/dist/_layouts/themes/newsflash/frontend/pages/team/member.html +134 -0
- package/dist/defaults/test/README.md +4 -0
- package/dist/gulp/tasks/jekyll.js +4 -2
- package/dist/test/runner.js +50 -3
- package/dist/test/suites/build/attach-log-file.test.js +102 -0
- package/dist/test/suites/build/theme-contract.test.js +173 -0
- package/dist/test/utils/extended-mode-warning.js +13 -0
- package/dist/utils/attach-log-file.js +70 -43
- package/docs/appearance.md +1 -0
- package/docs/assets.md +9 -0
- package/docs/audit.md +27 -7
- package/docs/build-system.md +57 -0
- package/docs/common-mistakes.md +15 -0
- package/docs/{project-structure.md → directory-structure.md} +1 -1
- package/docs/environment-detection.md +1 -1
- package/docs/javascript-libraries.md +38 -1
- package/docs/layouts-and-pages.md +146 -0
- package/docs/local-development.md +1 -8
- package/docs/logging.md +30 -0
- package/docs/migration.md +131 -0
- package/docs/no-inline-scripts.md +304 -0
- package/docs/purgecss.md +164 -0
- package/docs/seo.md +131 -4
- package/docs/templating.md +23 -0
- package/docs/test-boot-layer.md +1 -1
- package/docs/test-framework.md +56 -8
- package/docs/themes.md +254 -13
- package/logs/test.log +111 -0
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{% comment %}
|
|
2
|
+
Shared plan-pricing resolution — the SSOT for the pricing math every theme's
|
|
3
|
+
pricing layout uses. Jekyll includes share the caller's variable scope, so
|
|
4
|
+
the assigns below land in the calling template.
|
|
5
|
+
|
|
6
|
+
In: include.plan — a page.resolved.pricing.plans item
|
|
7
|
+
|
|
8
|
+
Out: _config_product — matching site.web_manager.payment.products entry (or nil)
|
|
9
|
+
_plan_monthly — monthly price (frontmatter pricing → config prices → 0)
|
|
10
|
+
_plan_annually — annual price (frontmatter pricing → config prices → 0)
|
|
11
|
+
_ppu_value — per-unit feature value (nil unless price_per_unit enabled and plan is paid)
|
|
12
|
+
monthly_price_per_unit — $/unit at monthly billing (nil unless _ppu_value > 0)
|
|
13
|
+
annual_price_per_unit — $/unit at annual billing, monthly-equivalent (nil unless _ppu_value > 0)
|
|
14
|
+
|
|
15
|
+
Every output is (re)assigned on every call so loop iterations never see a
|
|
16
|
+
previous plan's values.
|
|
17
|
+
{% endcomment %}
|
|
18
|
+
|
|
19
|
+
{% assign _config_product = nil %}
|
|
20
|
+
{% for p in site.web_manager.payment.products %}
|
|
21
|
+
{% if p.id == include.plan.id %}{% assign _config_product = p %}{% break %}{% endif %}
|
|
22
|
+
{% endfor %}
|
|
23
|
+
|
|
24
|
+
{% comment %} Prices: frontmatter pricing takes precedence, then config, then 0 {% endcomment %}
|
|
25
|
+
{% if include.plan.pricing.monthly or include.plan.pricing.monthly == 0 %}
|
|
26
|
+
{% assign _plan_monthly = include.plan.pricing.monthly %}
|
|
27
|
+
{% elsif _config_product.prices.monthly or _config_product.prices.monthly == 0 %}
|
|
28
|
+
{% assign _plan_monthly = _config_product.prices.monthly %}
|
|
29
|
+
{% else %}
|
|
30
|
+
{% assign _plan_monthly = 0 %}
|
|
31
|
+
{% endif %}
|
|
32
|
+
|
|
33
|
+
{% if include.plan.pricing.annually or include.plan.pricing.annually == 0 %}
|
|
34
|
+
{% assign _plan_annually = include.plan.pricing.annually %}
|
|
35
|
+
{% elsif _config_product.prices.annually or _config_product.prices.annually == 0 %}
|
|
36
|
+
{% assign _plan_annually = _config_product.prices.annually %}
|
|
37
|
+
{% else %}
|
|
38
|
+
{% assign _plan_annually = 0 %}
|
|
39
|
+
{% endif %}
|
|
40
|
+
|
|
41
|
+
{% comment %} Per-unit value: frontmatter feature value, falling back to config product limits. Per-unit prices only compute when the value is a usable positive number (guards the divided_by) {% endcomment %}
|
|
42
|
+
{% assign _ppu_value = nil %}
|
|
43
|
+
{% assign monthly_price_per_unit = nil %}
|
|
44
|
+
{% assign annual_price_per_unit = nil %}
|
|
45
|
+
{% if page.resolved.pricing.price_per_unit.enabled and _plan_monthly > 0 %}
|
|
46
|
+
{% for feature in include.plan.features %}
|
|
47
|
+
{% if feature.id == page.resolved.pricing.price_per_unit.feature_id %}
|
|
48
|
+
{% assign _ppu_value = feature.value %}
|
|
49
|
+
{% if _config_product and _ppu_value == nil %}
|
|
50
|
+
{% for _lim in _config_product.limits %}{% if _lim[0] == feature.id %}{% assign _ppu_value = _lim[1] %}{% break %}{% endif %}{% endfor %}
|
|
51
|
+
{% endif %}
|
|
52
|
+
{% endif %}
|
|
53
|
+
{% endfor %}
|
|
54
|
+
{% if _ppu_value and _ppu_value > 0 %}
|
|
55
|
+
{% assign monthly_price_per_unit = _plan_monthly | times: 1.0 | divided_by: _ppu_value | round: 2 %}
|
|
56
|
+
{% assign annual_monthly_price = _plan_annually | divided_by: 12.0 %}
|
|
57
|
+
{% assign annual_price_per_unit = annual_monthly_price | divided_by: _ppu_value | round: 2 %}
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% endif %}
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
{% capture logo_src %}{% if data.logo.src %}{{ data.logo.src }}{% else %}{{ site.brand.images.brandmark | default: null }}{% endif %}{% endcapture %}
|
|
9
9
|
{% capture logo_text %}{{ data.logo.text | default: site.brand.name | uj_liquify }}{% endcapture %}
|
|
10
10
|
{% capture logo_description %}{{ data.logo.description | default: site.brand.description | uj_liquify }}{% endcapture %}
|
|
11
|
+
{% assign logo_description = logo_description | strip %}
|
|
12
|
+
{% comment %} A data value that LIQUIFIES to empty (e.g. '{{ site.meta.description }}' with no meta.description set) still needs the brand fallback — `default:` only sees the raw string {% endcomment %}
|
|
13
|
+
{% if logo_description == '' or logo_description == 'null' %}{% assign logo_description = site.brand.description %}{% endif %}
|
|
11
14
|
{% capture logo_class %}{{ data.logo.class }}{% endcapture %}
|
|
12
15
|
|
|
13
16
|
<div class="h5 mb-3">
|
|
@@ -76,9 +79,7 @@
|
|
|
76
79
|
<div class="d-flex align-items-center me-3">
|
|
77
80
|
<div class="dropup uj-language-dropdown">
|
|
78
81
|
<button class="btn btn-sm btn-outline-adaptive dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
79
|
-
|
|
80
|
-
<?xml version="1.0" encoding="iso-8859-1"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1em" height="1em" fill="currentColor" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> <path style="fill:#DAE2F2;" d="M467,91H237.25l-34.528,415.796c6.068,3.034,12.594,5.204,19.763,5.204H467c24.814,0,45-20.186,45-45 V136C512,111.186,491.814,91,467,91z"/> <path style="fill:#4D97FF;" d="M169.867,407.86l7.969,64.721c1.6,12.854,10.3,26.922,24.886,34.215 c29.167-31.374,9.614-11.341,78.829-85.796L169.867,407.86z"/> <path style="fill:#4DB5FF;" d="M281.551,421c4.907-5.608,9.211-9.373,8.053-17.095l-45.44-364.486 C241.366,16.948,222.162,0,199.516,0H45C20.186,0,0,20.186,0,45v331c0,24.814,20.186,45,45,45C123.402,421,202.898,421,281.551,421z "/> <path style="fill:#E6EEFF;" d="M165.707,118.056C164.301,111.054,158.148,106,151,106h-30c-7.148,0-13.301,5.054-14.707,12.056 l-30,150c-1.626,8.13,3.647,16.025,11.763,17.651c8.218,1.685,16.04-3.647,17.651-11.763L115.294,226h41.411l9.587,47.944 c1.641,8.237,9.697,13.4,17.651,11.763c8.115-1.626,13.389-9.521,11.763-17.651L165.707,118.056z M121.293,196l11.997-60h5.42 l11.997,60H121.293z"/> <path style="fill:#53565C;" d="M436,226h-45v-15c0-8.291-6.709-15-15-15s-15,6.709-15,15v15h-45c-8.291,0-15,6.709-15,15 s6.709,15,15,15h4.006c8.535,27.383,21.07,48.81,35.136,65.702c-11.019,10.074-21.802,18.339-33.518,27.594 c-6.459,5.171-7.514,14.604-2.328,21.079c5.162,6.465,14.632,7.514,21.078,2.329c12.73-10.047,23.679-18.456,35.626-29.421 c11.947,10.966,22.896,19.375,35.624,29.421c6.448,5.185,15.918,4.136,21.08-2.329c5.186-6.475,4.131-15.908-2.33-21.079 c-11.715-9.255-22.498-17.52-33.517-27.594c14.066-16.891,26.602-38.318,35.136-65.702H436c8.291,0,15-6.709,15-15 S444.291,226,436,226z M376,299.467c-9.534-11.984-18.149-26.069-24.626-43.467h49.252C394.149,273.399,385.534,287.483,376,299.467 z"/> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </svg>
|
|
81
|
-
</i>
|
|
82
|
+
{% uj_icon "language", "fa-sm me-1" %}
|
|
82
83
|
<span class="_text-body">
|
|
83
84
|
Language
|
|
84
85
|
</span>
|
|
@@ -103,6 +104,22 @@
|
|
|
103
104
|
</div>
|
|
104
105
|
</div>
|
|
105
106
|
|
|
107
|
+
<!-- Appearance Dropdown (logic handled framework-side via data-appearance-* attributes — see docs/appearance.md) -->
|
|
108
|
+
<div class="d-flex align-items-center me-3">
|
|
109
|
+
<div class="dropup uj-appearance-dropdown">
|
|
110
|
+
<button class="btn btn-sm btn-outline-adaptive dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Appearance">
|
|
111
|
+
<span data-appearance-icon="light" hidden>{% uj_icon "sun", "fa-sm" %}</span>
|
|
112
|
+
<span data-appearance-icon="dark" hidden>{% uj_icon "moon-stars", "fa-sm" %}</span>
|
|
113
|
+
<span data-appearance-icon="system" hidden>{% uj_icon "circle-half-stroke", "fa-sm" %}</span>
|
|
114
|
+
</button>
|
|
115
|
+
<ul class="dropdown-menu">
|
|
116
|
+
<li><button class="dropdown-item" type="button" data-appearance-set="light">{% uj_icon "sun", "fa-sm me-2" %}Light</button></li>
|
|
117
|
+
<li><button class="dropdown-item" type="button" data-appearance-set="dark">{% uj_icon "moon-stars", "fa-sm me-2" %}Dark</button></li>
|
|
118
|
+
<li><button class="dropdown-item" type="button" data-appearance-set="system">{% uj_icon "circle-half-stroke", "fa-sm me-2" %}System</button></li>
|
|
119
|
+
</ul>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
106
123
|
<!-- Social Links -->
|
|
107
124
|
{% if data.socials.enabled %}
|
|
108
125
|
<div class="d-flex align-items-center">
|
|
@@ -304,31 +304,8 @@ faqs:
|
|
|
304
304
|
|
|
305
305
|
<div class="row g-4 mb-5 justify-content-center">
|
|
306
306
|
{% for plan in page.resolved.pricing.plans %}
|
|
307
|
-
{% comment %}
|
|
308
|
-
{%
|
|
309
|
-
{% for p in site.web_manager.payment.products %}
|
|
310
|
-
{% if p.id == plan.id %}
|
|
311
|
-
{% assign _config_product = p %}
|
|
312
|
-
{% break %}
|
|
313
|
-
{% endif %}
|
|
314
|
-
{% endfor %}
|
|
315
|
-
|
|
316
|
-
{% comment %} Resolve prices: frontmatter pricing takes precedence, then config prices {% endcomment %}
|
|
317
|
-
{% if plan.pricing.monthly or plan.pricing.monthly == 0 %}
|
|
318
|
-
{% assign _plan_monthly = plan.pricing.monthly %}
|
|
319
|
-
{% elsif _config_product.prices.monthly or _config_product.prices.monthly == 0 %}
|
|
320
|
-
{% assign _plan_monthly = _config_product.prices.monthly %}
|
|
321
|
-
{% else %}
|
|
322
|
-
{% assign _plan_monthly = 0 %}
|
|
323
|
-
{% endif %}
|
|
324
|
-
|
|
325
|
-
{% if plan.pricing.annually or plan.pricing.annually == 0 %}
|
|
326
|
-
{% assign _plan_annually = plan.pricing.annually %}
|
|
327
|
-
{% elsif _config_product.prices.annually or _config_product.prices.annually == 0 %}
|
|
328
|
-
{% assign _plan_annually = _config_product.prices.annually %}
|
|
329
|
-
{% else %}
|
|
330
|
-
{% assign _plan_annually = 0 %}
|
|
331
|
-
{% endif %}
|
|
307
|
+
{% comment %} Shared pricing math (assigns _plan_monthly/_plan_annually/per-unit into this scope) {% endcomment %}
|
|
308
|
+
{% include core/pricing/resolve-plan.html plan=plan %}
|
|
332
309
|
|
|
333
310
|
{% if plan.popular %}
|
|
334
311
|
{% assign border_classes = "border-gradient-rainbow border-3" %}
|
|
@@ -365,21 +342,9 @@ faqs:
|
|
|
365
342
|
<!-- Price per unit (only shown when enabled) -->
|
|
366
343
|
{% if page.resolved.pricing.price_per_unit.enabled %}
|
|
367
344
|
<p class="text-muted small mb-4">
|
|
368
|
-
{% if
|
|
369
|
-
{
|
|
370
|
-
|
|
371
|
-
{% comment %} Resolve feature value from config limits if not set in frontmatter {% endcomment %}
|
|
372
|
-
{% assign _ppu_value = feature.value %}
|
|
373
|
-
{% if _config_product and _ppu_value == nil %}
|
|
374
|
-
{% for _lim in _config_product.limits %}{% if _lim[0] == feature.id %}{% assign _ppu_value = _lim[1] %}{% break %}{% endif %}{% endfor %}
|
|
375
|
-
{% endif %}
|
|
376
|
-
{% assign monthly_price_per_unit = _plan_monthly | times: 1.0 | divided_by: _ppu_value | round: 2 %}
|
|
377
|
-
{% assign annual_monthly_price = _plan_annually | divided_by: 12.0 %}
|
|
378
|
-
{% assign annual_price_per_unit = annual_monthly_price | divided_by: _ppu_value | round: 2 %}
|
|
379
|
-
<span class="price-per-unit" data-monthly="${{ monthly_price_per_unit }}" data-annually="${{ annual_price_per_unit }}">${{ annual_price_per_unit }}</span> per {{ page.resolved.pricing.price_per_unit.label }}
|
|
380
|
-
{% endif %}
|
|
381
|
-
{% endfor %}
|
|
382
|
-
{% else %}
|
|
345
|
+
{% if monthly_price_per_unit %}
|
|
346
|
+
<span class="price-per-unit" data-monthly="${{ monthly_price_per_unit }}" data-annually="${{ annual_price_per_unit }}">${{ annual_price_per_unit }}</span> per {{ page.resolved.pricing.price_per_unit.label }}
|
|
347
|
+
{% elsif _plan_monthly == 0 %}
|
|
383
348
|
<!-- Placeholder text for free plan to maintain consistent height -->
|
|
384
349
|
Perfect for trying out
|
|
385
350
|
{% endif %}
|
|
@@ -153,6 +153,33 @@ faqs:
|
|
|
153
153
|
social-proof, and a full-bleed CTA. See docs/themes.md.
|
|
154
154
|
{% endcomment %}
|
|
155
155
|
|
|
156
|
+
<!-- ============================================ -->
|
|
157
|
+
<!-- PROMO BANNER — revealed + populated by the framework pricing JS
|
|
158
|
+
(sale name, countdown, navbar offset). The ids are the contract;
|
|
159
|
+
ship it hidden and let the JS do the rest. -->
|
|
160
|
+
<!-- ============================================ -->
|
|
161
|
+
<div id="pricing-promo-banner" class="position-fixed top-0 start-0 w-100 text-center animation-slide-down" style="z-index: 1050;" hidden>
|
|
162
|
+
<div class="bg-primary text-white py-2 position-relative">
|
|
163
|
+
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 mt-2 me-2" aria-label="Close" onclick="this.closest('#pricing-promo-banner').hidden=true;document.querySelector('.navbar-wrapper').style.marginTop='';document.querySelector('main > section:first-of-type').style.paddingTop=''"></button>
|
|
164
|
+
<div class="container-fluid">
|
|
165
|
+
<div class="d-flex align-items-center justify-content-center gap-3 flex-wrap pe-4">
|
|
166
|
+
<span id="pricing-promo-badge" class="badge bg-warning text-dark px-2 py-1 fs-6 animation-wiggle">
|
|
167
|
+
15% OFF!
|
|
168
|
+
</span>
|
|
169
|
+
<span id="pricing-promo-text" class="fw-bold">
|
|
170
|
+
Flash sale
|
|
171
|
+
</span>
|
|
172
|
+
<span class="text-white-50">
|
|
173
|
+
Ending in <span id="pricing-promo-countdown" class="fw-semibold text-white">--</span>
|
|
174
|
+
</span>
|
|
175
|
+
<span class="text-white-50">
|
|
176
|
+
Use code <span id="pricing-promo-code" class="badge bg-white bg-opacity-25 px-2 py-1 fs-6">WELCOME15</span>
|
|
177
|
+
</span>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
156
183
|
<!-- ============================================ -->
|
|
157
184
|
<!-- HERO -->
|
|
158
185
|
<!-- ============================================ -->
|
|
@@ -208,30 +235,17 @@ faqs:
|
|
|
208
235
|
|
|
209
236
|
<div class="pricing-plan-grid">
|
|
210
237
|
{% for plan in page.resolved.pricing.plans %}
|
|
211
|
-
{% comment %}
|
|
212
|
-
{%
|
|
213
|
-
{% for p in site.web_manager.payment.products %}
|
|
214
|
-
{% if p.id == plan.id %}{% assign _config_product = p %}{% break %}{% endif %}
|
|
215
|
-
{% endfor %}
|
|
216
|
-
|
|
217
|
-
{% if plan.pricing.monthly or plan.pricing.monthly == 0 %}
|
|
218
|
-
{% assign _plan_monthly = plan.pricing.monthly %}
|
|
219
|
-
{% elsif _config_product.prices.monthly or _config_product.prices.monthly == 0 %}
|
|
220
|
-
{% assign _plan_monthly = _config_product.prices.monthly %}
|
|
221
|
-
{% else %}{% assign _plan_monthly = 0 %}{% endif %}
|
|
222
|
-
|
|
223
|
-
{% if plan.pricing.annually or plan.pricing.annually == 0 %}
|
|
224
|
-
{% assign _plan_annually = plan.pricing.annually %}
|
|
225
|
-
{% elsif _config_product.prices.annually or _config_product.prices.annually == 0 %}
|
|
226
|
-
{% assign _plan_annually = _config_product.prices.annually %}
|
|
227
|
-
{% else %}{% assign _plan_annually = 0 %}{% endif %}
|
|
238
|
+
{% comment %} Shared pricing math (assigns _plan_monthly/_plan_annually/per-unit into this scope) {% endcomment %}
|
|
239
|
+
{% include core/pricing/resolve-plan.html plan=plan %}
|
|
228
240
|
|
|
229
241
|
<article class="card pricing-plan {% if plan.popular %}pricing-plan--popular{% endif %}">
|
|
230
242
|
{% if plan.popular %}
|
|
231
243
|
<span class="pricing-plan-flag">Most Popular</span>
|
|
232
244
|
{% endif %}
|
|
233
245
|
|
|
234
|
-
|
|
246
|
+
<!-- .card-title is load-bearing: the framework pricing JS reads the plan
|
|
247
|
+
name for analytics via `.h3, .h2, .card-title` inside the card. -->
|
|
248
|
+
<h3 class="card-title pricing-plan-name">{{ plan.name }}</h3>
|
|
235
249
|
<p class="pricing-plan-tagline">{{ plan.tagline }}</p>
|
|
236
250
|
|
|
237
251
|
<!-- Price -->
|
|
@@ -244,23 +258,8 @@ faqs:
|
|
|
244
258
|
</div>
|
|
245
259
|
|
|
246
260
|
{% if page.resolved.pricing.price_per_unit.enabled %}
|
|
247
|
-
{% comment %} Resolve the per-unit value; only render if it's a usable positive number {% endcomment %}
|
|
248
|
-
{% assign _ppu_value = nil %}
|
|
249
|
-
{% if _plan_monthly > 0 %}
|
|
250
|
-
{% for feature in plan.features %}
|
|
251
|
-
{% if feature.id == page.resolved.pricing.price_per_unit.feature_id %}
|
|
252
|
-
{% assign _ppu_value = feature.value %}
|
|
253
|
-
{% if _config_product and _ppu_value == nil %}
|
|
254
|
-
{% for _lim in _config_product.limits %}{% if _lim[0] == feature.id %}{% assign _ppu_value = _lim[1] %}{% break %}{% endif %}{% endfor %}
|
|
255
|
-
{% endif %}
|
|
256
|
-
{% endif %}
|
|
257
|
-
{% endfor %}
|
|
258
|
-
{% endif %}
|
|
259
261
|
<p class="pricing-plan-ppu">
|
|
260
|
-
{% if
|
|
261
|
-
{% assign monthly_price_per_unit = _plan_monthly | times: 1.0 | divided_by: _ppu_value | round: 2 %}
|
|
262
|
-
{% assign annual_monthly_price = _plan_annually | divided_by: 12.0 %}
|
|
263
|
-
{% assign annual_price_per_unit = annual_monthly_price | divided_by: _ppu_value | round: 2 %}
|
|
262
|
+
{% if monthly_price_per_unit %}
|
|
264
263
|
<span class="price-per-unit" data-monthly="${{ monthly_price_per_unit }}" data-annually="${{ annual_price_per_unit }}">${{ annual_price_per_unit }}</span> per {{ page.resolved.pricing.price_per_unit.label }}
|
|
265
264
|
{% elsif _plan_monthly == 0 %}
|
|
266
265
|
Perfect for trying out
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
### ALL PAGES ###
|
|
3
|
+
layout: core/root
|
|
4
|
+
|
|
5
|
+
### THEME CONFIG ###
|
|
6
|
+
theme:
|
|
7
|
+
# html:
|
|
8
|
+
# class: ""
|
|
9
|
+
head:
|
|
10
|
+
content: |
|
|
11
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..900;1,9..144,300..900&family=Schibsted+Grotesk:ital,wght@0,400..900;1,400..900&display=swap" media="print" onload="this.media='all'">
|
|
12
|
+
body:
|
|
13
|
+
class: "d-flex flex-column min-vh-100"
|
|
14
|
+
# main:
|
|
15
|
+
# class: "flex-fill"
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<!-- News ticker — the latest headlines marquee above the masthead.
|
|
19
|
+
Pure CSS animation; the track is duplicated once (aria-hidden) so the
|
|
20
|
+
-50% keyframe loops seamlessly. Absent when the site has no posts. -->
|
|
21
|
+
{% if site.posts.size > 0 %}
|
|
22
|
+
<div class="ticker">
|
|
23
|
+
<div class="ticker-track">
|
|
24
|
+
{% for post in site.posts limit: 5 %}
|
|
25
|
+
<span class="ticker-item">
|
|
26
|
+
{% if forloop.first %}
|
|
27
|
+
<span class="live-dot"></span><b>LATEST</b>
|
|
28
|
+
{% else %}
|
|
29
|
+
{% uj_icon "bolt" %}
|
|
30
|
+
{% endif %}
|
|
31
|
+
<a href="{{ site.url }}{{ post.url }}">{{ post.post.title }}</a>
|
|
32
|
+
</span>
|
|
33
|
+
{% endfor %}
|
|
34
|
+
{% for post in site.posts limit: 5 %}
|
|
35
|
+
<span class="ticker-item" aria-hidden="true">
|
|
36
|
+
{% if forloop.first %}
|
|
37
|
+
<span class="live-dot"></span><b>LATEST</b>
|
|
38
|
+
{% else %}
|
|
39
|
+
{% uj_icon "bolt" %}
|
|
40
|
+
{% endif %}
|
|
41
|
+
<a href="{{ site.url }}{{ post.url }}" tabindex="-1">{{ post.post.title }}</a>
|
|
42
|
+
</span>
|
|
43
|
+
{% endfor %}
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
{% endif %}
|
|
47
|
+
|
|
48
|
+
<!-- Nav (controlled by page/layout front matter) -->
|
|
49
|
+
{% unless page.resolved.theme.nav.enabled == false %}
|
|
50
|
+
{%- include /frontend/sections/nav.html -%}
|
|
51
|
+
{% endunless %}
|
|
52
|
+
|
|
53
|
+
<!-- Main Content -->
|
|
54
|
+
<main id="main-content" class="flex-fill {{ page.resolved.theme.main.class | uj_liquify }}" aria-label="Main content">
|
|
55
|
+
{{ content | uj_content_format }}
|
|
56
|
+
</main>
|
|
57
|
+
|
|
58
|
+
<!-- Footer (controlled by page/layout front matter) -->
|
|
59
|
+
{% unless page.resolved.theme.footer.enabled == false %}
|
|
60
|
+
{%- include /frontend/sections/footer.html -%}
|
|
61
|
+
{% endunless %}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
### ALL PAGES ###
|
|
3
|
+
layout: themes/[ site.theme.id ]/frontend/core/cover
|
|
4
|
+
|
|
5
|
+
### PAGE CONFIG ###
|
|
6
|
+
suggested_pages:
|
|
7
|
+
- title: "Home"
|
|
8
|
+
description: "Return to our homepage"
|
|
9
|
+
icon: "house"
|
|
10
|
+
link: "/"
|
|
11
|
+
- title: "Pricing"
|
|
12
|
+
description: "View our plans and pricing"
|
|
13
|
+
icon: "tag"
|
|
14
|
+
link: "/pricing"
|
|
15
|
+
- title: "Contact"
|
|
16
|
+
description: "Get in touch with us"
|
|
17
|
+
icon: "envelope"
|
|
18
|
+
link: "/contact"
|
|
19
|
+
- title: "Team"
|
|
20
|
+
description: "Meet our amazing team"
|
|
21
|
+
icon: "users"
|
|
22
|
+
link: "/team"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
{% comment %}
|
|
26
|
+
NEWSFLASH 404
|
|
27
|
+
A correction notice from the desk: rotated "Correction" chip, oversized
|
|
28
|
+
stroked 404 numerals, the requested URL in a framed notice, and the
|
|
29
|
+
suggested_pages contract rendered as pill links.
|
|
30
|
+
{% endcomment %}
|
|
31
|
+
|
|
32
|
+
<section class="col-12 col-md-10 col-lg-8 col-xl-6 mw-md">
|
|
33
|
+
<div class="card shadow position-relative">
|
|
34
|
+
<span class="badge bg-body-tertiary error-stamp">Correction</span>
|
|
35
|
+
<div class="card-body p-3 p-md-5">
|
|
36
|
+
<!-- Header -->
|
|
37
|
+
<div class="text-center mb-4">
|
|
38
|
+
<h1 class="error-code mb-3">404</h1>
|
|
39
|
+
<p class="text-body-secondary mb-0">
|
|
40
|
+
This page never went to print. It may have been moved, retracted, or it never existed — our editors regret the error.
|
|
41
|
+
</p>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<!-- URL Display -->
|
|
45
|
+
<div class="alert alert-warning text-center mb-4" role="alert">
|
|
46
|
+
<small class="text-body">
|
|
47
|
+
<strong>Requested URL:</strong> <span id="page-url" class="text-break">{{ page.canonical.url }}</span>
|
|
48
|
+
</small>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<!-- Primary Actions -->
|
|
52
|
+
<div class="d-grid gap-2 d-sm-block text-center mb-4">
|
|
53
|
+
<a href="{{ site.url }}" class="btn btn-adaptive btn-lg mb-2 mb-sm-0 me-sm-2">
|
|
54
|
+
{% uj_icon "house", "me-2" %}
|
|
55
|
+
Back to home
|
|
56
|
+
</a>
|
|
57
|
+
<button class="btn btn-outline-dark btn-lg mb-2 mb-sm-0" onclick="window.history.back()">
|
|
58
|
+
{% uj_icon "arrow-left", "me-2" %}
|
|
59
|
+
Go back
|
|
60
|
+
</button>
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<!-- Suggested pages -->
|
|
64
|
+
{% iftruthy page.resolved.suggested_pages %}
|
|
65
|
+
<div class="text-center mb-4">
|
|
66
|
+
{% for suggestion in page.resolved.suggested_pages %}
|
|
67
|
+
<a href="{{ suggestion.link }}" class="btn btn-outline-dark btn-sm me-1 mb-2" title="{{ suggestion.description }}">
|
|
68
|
+
{% uj_icon suggestion.icon, "me-1" %}{{ suggestion.title }}
|
|
69
|
+
</a>
|
|
70
|
+
{% endfor %}
|
|
71
|
+
</div>
|
|
72
|
+
{% endiftruthy %}
|
|
73
|
+
|
|
74
|
+
<!-- Help Section -->
|
|
75
|
+
<div class="text-center pt-4 border-top">
|
|
76
|
+
<p class="text-body-secondary mb-0">
|
|
77
|
+
Still can't find what you're looking for?
|
|
78
|
+
<a href="/contact" class="text-decoration-none fw-semibold">Contact our support team</a>
|
|
79
|
+
and we'll help you out!
|
|
80
|
+
</p>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</section>
|
|
85
|
+
|
|
86
|
+
{{ content | uj_content_format }}
|