jekyll-theme-zer0 1.29.0 → 1.30.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +715 -2
- data/_data/README.md +2 -0
- data/_data/ai.yml +5 -3
- data/_data/ai_pricing.yml +36 -0
- data/_data/backlog.yml +169 -18
- data/_data/consumers.yml +48 -5
- data/_data/features.yml +146 -20
- data/_data/feedback_types.yml +17 -12
- data/_data/landing.yml +5 -2
- data/_data/navigation/quickstart.yml +4 -0
- data/_data/site_builder.yml +874 -0
- data/_data/theme-manifest.yml +122 -114
- data/_data/ui-text.yml +18 -0
- data/_includes/README.md +11 -1
- data/_includes/analytics/posthog.html +2 -2
- data/_includes/components/admin-links.html +2 -2
- data/_includes/components/admin-tabs.html +2 -2
- data/_includes/components/ai-chat.html +14 -11
- data/_includes/components/analytics-dashboard.html +8 -8
- data/_includes/components/author-bio.html +1 -1
- data/_includes/components/author-card.html +10 -2
- data/_includes/components/author-eeat.html +4 -4
- data/_includes/components/background-customizer.html +8 -8
- data/_includes/components/background-image.html +114 -0
- data/_includes/components/background-settings.html +28 -15
- data/_includes/components/collection-manager.html +5 -5
- data/_includes/components/component-showcase.html +13 -13
- data/_includes/components/config-editor.html +12 -12
- data/_includes/components/config-viewer.html +8 -8
- data/_includes/components/cookie-consent.html +11 -11
- data/_includes/components/cta-button.html +7 -2
- data/_includes/components/dev-shortcuts.html +7 -7
- data/_includes/components/env-dashboard.html +8 -8
- data/_includes/components/env-switcher.html +9 -9
- data/_includes/components/feature-card.html +2 -2
- data/_includes/components/halfmoon.html +2 -2
- data/_includes/components/info-section.html +36 -36
- data/_includes/components/js-cdn.html +15 -15
- data/_includes/components/language-toggle.html +4 -4
- data/_includes/components/mermaid.html +72 -435
- data/_includes/components/nanobar.html +5 -5
- data/_includes/components/nav-editor.html +2 -2
- data/_includes/components/nav-export.html +2 -2
- data/_includes/components/nav-overview.html +2 -2
- data/_includes/components/page-feedback.html +45 -30
- data/_includes/components/page-views-init.html +1 -1
- data/_includes/components/post-card.html +22 -22
- data/_includes/components/post-type-badge.html +2 -2
- data/_includes/components/powered-by.html +2 -2
- data/_includes/components/preview-image.html +6 -0
- data/_includes/components/quick-index.html +2 -2
- data/_includes/components/search-modal.html +27 -2
- data/_includes/components/searchbar.html +2 -2
- data/_includes/components/svg-background.html +2 -2
- data/_includes/components/theme-customizer.html +2 -2
- data/_includes/components/theme-info.html +6 -6
- data/_includes/components/theme-preview-gallery.html +22 -22
- data/_includes/content/giscus.html +2 -2
- data/_includes/content/intro.html +8 -8
- data/_includes/content/jsonld-faq.html +2 -2
- data/_includes/content/jsonld-software.html +2 -2
- data/_includes/content/seo.html +4 -4
- data/_includes/content/sitemap.html +27 -27
- data/_includes/content/toc.html +183 -183
- data/_includes/core/branding.html +6 -6
- data/_includes/core/console-capture.html +32 -74
- data/_includes/core/favicon.html +49 -7
- data/_includes/core/footer-fabs.html +17 -3
- data/_includes/core/footer.html +31 -18
- data/_includes/core/head.html +102 -90
- data/_includes/core/header.html +71 -52
- data/_includes/docs/bootstrap-docs.html +8 -8
- data/_includes/landing/landing-install-cards.html +2 -2
- data/_includes/landing/landing-quick-links.html +1 -1
- data/_includes/navigation/admin-nav.html +2 -2
- data/_includes/navigation/nav-tree.html +8 -8
- data/_includes/navigation/navbar.html +12 -12
- data/_includes/navigation/section-sidebar.html +16 -16
- data/_includes/navigation/sidebar-config.html +36 -2
- data/_includes/navigation/sidebar-left.html +15 -15
- data/_includes/navigation/sidebar-right.html +6 -6
- data/_includes/obsidian/full-graph.html +2 -2
- data/_includes/setup/claude-session.html +72 -0
- data/_includes/setup/prereq-checklist.html +90 -0
- data/_includes/setup/wizard.html +906 -291
- data/_includes/stats/stats-categories.html +8 -8
- data/_includes/stats/stats-header.html +14 -14
- data/_includes/stats/stats-metrics.html +12 -12
- data/_includes/stats/stats-no-data.html +12 -12
- data/_includes/stats/stats-overview.html +6 -6
- data/_includes/stats/stats-tags.html +8 -8
- data/_layouts/404.html +38 -24
- data/_layouts/admin.html +22 -22
- data/_layouts/article.html +39 -34
- data/_layouts/author.html +20 -20
- data/_layouts/authors.html +2 -2
- data/_layouts/book-abc.html +12 -12
- data/_layouts/book-story.html +15 -15
- data/_layouts/book.html +12 -12
- data/_layouts/collection.html +33 -33
- data/_layouts/cookbook.html +12 -12
- data/_layouts/default.html +27 -24
- data/_layouts/home.html +23 -23
- data/_layouts/index.html +10 -10
- data/_layouts/landing.html +17 -17
- data/_layouts/news.html +44 -44
- data/_layouts/note.html +38 -38
- data/_layouts/notebook.html +34 -34
- data/_layouts/recipe.html +24 -24
- data/_layouts/root.html +73 -55
- data/_layouts/section.html +23 -23
- data/_layouts/setup.html +3 -3
- data/_layouts/sitemap-collection.html +49 -49
- data/_layouts/stats.html +40 -40
- data/_layouts/tag.html +12 -12
- data/_layouts/welcome.html +21 -21
- data/_sass/components/_mermaid.scss +375 -0
- data/_sass/components/_setup-wizard.scss +569 -40
- data/_sass/core/_navbar.scss +11 -31
- data/_sass/layouts/_navbar-extras.scss +14 -4
- data/assets/css/main.scss +1 -0
- data/assets/js/ai-chat.js +47 -5
- data/assets/js/fleet-feedback-capture.js +124 -0
- data/assets/js/fleet-feedback.js +853 -0
- data/assets/js/mermaid-diagrams.js +1267 -0
- data/assets/js/modules/navigation/config.js +9 -6
- data/assets/js/modules/navigation/scroll-spy.js +315 -80
- data/assets/js/modules/theme/appearance.js +8 -2
- data/assets/js/obsidian-wiki-links.js +8 -3
- data/assets/js/page-feedback.js +125 -192
- data/assets/js/search-modal.js +26 -0
- data/assets/js/setup-wizard.js +2112 -361
- data/assets/js/site-builder.js +1834 -0
- data/assets/js/ui-enhancements.js +11 -3
- data/scripts/README.md +15 -0
- data/scripts/ai/README.md +38 -0
- data/scripts/ai/api_call.rb +124 -0
- data/scripts/ai/usage.rb +314 -0
- data/scripts/ai/usage_report.rb +225 -0
- data/scripts/ci/test_visual_evidence_autogen.py +341 -0
- data/scripts/ci/visual_evidence_autogen.py +1060 -0
- data/scripts/content-review.rb +20 -1
- data/scripts/test/integration/mermaid +22 -8
- data/scripts/test/lib/run_tests.sh +1 -0
- data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
- data/scripts/translate.rb +23 -1
- metadata +19 -2
data/_includes/core/footer.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-046 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
FOOTER - Comprehensive Site Footer with Branding & Navigation
|
|
5
5
|
===================================================================
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
- Guard optional fields (address/phone/email) to avoid empty output
|
|
34
34
|
- Use relative_url for internal links to respect baseurl
|
|
35
35
|
===================================================================
|
|
36
|
-
|
|
36
|
+
{% endcomment %}
|
|
37
37
|
|
|
38
38
|
{%- include core/i18n.html lang=include.lang -%}
|
|
39
39
|
<footer class="bd-footer border-top" role="contentinfo">
|
|
40
40
|
{% assign footer_page_urls = site.html_pages | map: "url" | join: "|" | prepend: "|" | append: "|" %}
|
|
41
|
-
|
|
41
|
+
{% comment %} Powered by Row {% endcomment %}
|
|
42
42
|
<div class="container-xl footer-powered-by">
|
|
43
43
|
<p class="footer-powered-by-copyright text-center mb-0">
|
|
44
44
|
© {{ site.time | date: "%Y" }} {{ site.name | default: site.title }}
|
|
@@ -110,12 +110,12 @@
|
|
|
110
110
|
</div>
|
|
111
111
|
</div>
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
{% comment %} Branding and Navigation Block — full-width dark background {% endcomment %}
|
|
114
114
|
<div class="bg-dark text-light footer-dark-block">
|
|
115
115
|
<div class="container-xl">
|
|
116
|
-
|
|
116
|
+
{% comment %} Top: Site info + Quick Links + Social {% endcomment %}
|
|
117
117
|
<div class="row mb-3 mb-lg-4 g-2 g-lg-3 footer-nav-columns justify-content-center">
|
|
118
|
-
|
|
118
|
+
{% comment %} Site Info {% endcomment %}
|
|
119
119
|
<div class="col-12 col-md-3 col-lg-3 mb-2 mb-lg-3 order-0 order-md-1 order-lg-1">
|
|
120
120
|
<h2 class="footer-section-title text-uppercase h6 mb-0">{{ site.title }}</h2>
|
|
121
121
|
{% if site.address %}<p class="mb-1">{{ site.address }}</p>{% endif %}
|
|
@@ -123,12 +123,12 @@
|
|
|
123
123
|
{% if site.email %}<p class="mb-0"><a href="mailto:{{ site.email }}" class="text-light text-decoration-none">{{ site.email }}</a></p>{% endif %}
|
|
124
124
|
</div>
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
{% comment %} Quick Links
|
|
127
127
|
Resolution order:
|
|
128
128
|
1. site.footer_quick_links (array of {label, url}) — explicit override
|
|
129
129
|
2. Auto-detection: only render links whose target pages
|
|
130
130
|
actually exist in the build. Prevents 404s on bare-minimum
|
|
131
|
-
sites that haven't created /about/, /services/, etc.
|
|
131
|
+
sites that haven't created /about/, /services/, etc. {% endcomment %}
|
|
132
132
|
<div class="col-6 col-md-3 col-lg-3 mb-2 mb-lg-3 order-2 order-md-2 order-lg-2">
|
|
133
133
|
<h2 class="footer-section-title text-uppercase h6 mb-0">Quick Links</h2>
|
|
134
134
|
<ul class="list-unstyled" aria-label="Footer quick links">
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
</ul>
|
|
172
172
|
</div>
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
{% comment %} Latest Posts (dynamic) {% endcomment %}
|
|
175
175
|
{% assign posts_count = site.posts | size %}
|
|
176
176
|
{% if posts_count and posts_count > 0 %}
|
|
177
177
|
<div class="col-12 col-md-3 col-lg-3 mb-2 mb-lg-3 order-4 order-md-3 order-lg-3">
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
</div>
|
|
187
187
|
{% endif %}
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
{% comment %} Social & RSS {% endcomment %}
|
|
190
190
|
<div class="col-6 col-md-3 col-lg-3 mb-2 mb-lg-3 order-3 order-md-4 order-lg-4">
|
|
191
191
|
<h2 class="footer-section-title text-uppercase h6 mb-0">Follow Us</h2>
|
|
192
192
|
<ul class="list-inline mb-0" aria-label="Social links">
|
|
@@ -194,7 +194,17 @@
|
|
|
194
194
|
{% if link.url %}
|
|
195
195
|
<li class="list-inline-item">
|
|
196
196
|
{% capture link_icon_classes %}{{ site.default_icon }} {{ link.icon | default: "bi-link-45deg" }}{% endcapture %}
|
|
197
|
-
|
|
197
|
+
{%- comment -%}
|
|
198
|
+
aria-label is load-bearing below the md breakpoint (issue
|
|
199
|
+
#435): the icon is aria-hidden and the label span is
|
|
200
|
+
d-none there, so without it the link had NO accessible
|
|
201
|
+
name at all on mobile — a screen reader announced bare
|
|
202
|
+
"link". It matches the visible text exactly, so the
|
|
203
|
+
accessible name still contains the visible label at md+
|
|
204
|
+
(WCAG 2.5.3 Label in Name).
|
|
205
|
+
{%- endcomment -%}
|
|
206
|
+
<a href="{{ link.url }}" rel="nofollow" class="text-light text-decoration-none"
|
|
207
|
+
aria-label="{{ link.label }}">
|
|
198
208
|
<i class="{{ link_icon_classes }}" aria-hidden="true"></i>
|
|
199
209
|
<span class="d-none d-md-inline">{{ link.label }}</span>
|
|
200
210
|
</a>
|
|
@@ -202,16 +212,19 @@
|
|
|
202
212
|
{% endif %}
|
|
203
213
|
{% endfor %}
|
|
204
214
|
<li class="list-inline-item">
|
|
205
|
-
|
|
215
|
+
{%- comment -%} Same as the social links above (#435). {%- endcomment -%}
|
|
216
|
+
{%- assign _feed_label = ui.feed_label | default: "Feed" -%}
|
|
217
|
+
<a class="text-light text-decoration-none" href="{{ '/feed.xml' | relative_url }}"
|
|
218
|
+
aria-label="{{ _feed_label }}">
|
|
206
219
|
<i class="{{ site.default_icon }} bi-rss" aria-hidden="true"></i>
|
|
207
|
-
<span class="d-none d-md-inline">{{
|
|
220
|
+
<span class="d-none d-md-inline">{{ _feed_label }}</span>
|
|
208
221
|
</a>
|
|
209
222
|
</li>
|
|
210
223
|
</ul>
|
|
211
224
|
</div>
|
|
212
225
|
</div>
|
|
213
226
|
|
|
214
|
-
|
|
227
|
+
{% comment %} Middle: Subscribe + Policies {% endcomment %}
|
|
215
228
|
<div class="row mb-3 mb-lg-4 align-items-center justify-content-center g-2 footer-subscribe-row">
|
|
216
229
|
<div class="col-12 col-md-8 col-lg-8">
|
|
217
230
|
<form class="row g-2 footer-subscribe-form" aria-label="Newsletter signup" onsubmit="return false;">
|
|
@@ -249,7 +262,7 @@
|
|
|
249
262
|
</div>
|
|
250
263
|
</div>
|
|
251
264
|
|
|
252
|
-
|
|
265
|
+
{% comment %} Bottom: Copyright {% endcomment %}
|
|
253
266
|
<div class="text-center">
|
|
254
267
|
<p class="mb-0">© {{ site.time | date: "%Y" }} {{ site.title | default: site.name }}. All Rights Reserved.</p>
|
|
255
268
|
</div>
|
|
@@ -265,9 +278,9 @@
|
|
|
265
278
|
immediately after </footer> is visually identical to nesting them inside.
|
|
266
279
|
{%- endcomment -%}
|
|
267
280
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
via the FAB tokens (bottom-up: back-to-top → chat toggle → TOC FAB)
|
|
281
|
+
{% comment %} Back to Top Button (controlled by assets/js/back-to-top.js) {% endcomment %}
|
|
282
|
+
{% comment %} Positioning/stacking handled by _sass/components/_back-to-top.scss
|
|
283
|
+
via the FAB tokens (bottom-up: back-to-top → chat toggle → TOC FAB) {% endcomment %}
|
|
271
284
|
<a
|
|
272
285
|
id="backToTopBtn"
|
|
273
286
|
href="#"
|
data/_includes/core/head.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-001 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
HEAD - HTML Document Head Section
|
|
5
5
|
===================================================================
|
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
- MathJax loaded asynchronously to prevent render blocking
|
|
27
27
|
- Nanobar provides visual loading feedback (see components/nanobar.html)
|
|
28
28
|
===================================================================
|
|
29
|
-
|
|
29
|
+
{% endcomment %}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
{% comment %} ================================ {% endcomment %}
|
|
32
|
+
{% comment %} ANALYTICS AND TRACKING {% endcomment %}
|
|
33
|
+
{% comment %} ================================ {% endcomment %}
|
|
34
|
+
{% comment %} Google Tag Manager - Must be in head section for proper tracking {% endcomment %}
|
|
35
|
+
{% comment %} Only load in production builds (JEKYLL_ENV=production); the include also guards against dev hostnames {% endcomment %}
|
|
36
36
|
{% if jekyll.environment == "production" %}{% include analytics/google-tag-manager-head.html %}{% endif %}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
scripts below so a report can include the logs that led up to it.
|
|
38
|
+
{% comment %} Page-feedback: early console/error capture — must run before the theme
|
|
39
|
+
scripts below so a report can include the logs that led up to it. {% endcomment %}
|
|
40
40
|
{% include core/console-capture.html %}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
{% comment %} ================================ {% endcomment %}
|
|
43
|
+
{% comment %} JAVASCRIPT LIBRARIES {% endcomment %}
|
|
44
|
+
{% comment %} ================================ {% endcomment %}
|
|
45
|
+
{% comment %} Custom theme JavaScript - Deferred for performance {% endcomment %}
|
|
46
46
|
<script defer src="{{ '/assets/js/auto-hide-nav.js' | relative_url }}"></script>
|
|
47
47
|
<script defer src="{{ '/assets/js/back-to-top.js' | relative_url }}"></script>
|
|
48
48
|
<script defer src="{{ '/assets/js/halfmoon.js' | relative_url }}"></script>
|
|
@@ -51,34 +51,34 @@
|
|
|
51
51
|
<script defer src="{{ '/assets/js/table-copy.js' | relative_url }}"></script>
|
|
52
52
|
<script defer src="{{ '/assets/js/ui-enhancements.js' | relative_url }}"></script>
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
{% comment %} Page-view counter — injects its config and loads assets/js/page-views.js.
|
|
55
55
|
Renders nothing on its own; components/page-views.html places the badge.
|
|
56
|
-
Gated on site.page_views.enabled inside the include.
|
|
56
|
+
Gated on site.page_views.enabled inside the include. {% endcomment %}
|
|
57
57
|
{% include components/page-views-init.html %}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
{% comment %} ================================ {% endcomment %}
|
|
60
|
+
{% comment %} THIRD PARTY INTEGRATIONS {% endcomment %}
|
|
61
|
+
{% comment %} ================================ {% endcomment %}
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
{% comment %} Recipe scaling & unit conversion - Only on pages that render recipe
|
|
64
64
|
quantities: the `recipe` layout, or any page that opts in with
|
|
65
|
-
`recipe_tools: true` (e.g. a post embedding components/recipe-*.html).
|
|
65
|
+
`recipe_tools: true` (e.g. a post embedding components/recipe-*.html). {% endcomment %}
|
|
66
66
|
{% if page.layout == "recipe" or page.recipe_tools %}
|
|
67
67
|
<script defer src="{{ '/assets/js/recipe-scaler.js' | relative_url }}"></script>
|
|
68
68
|
{% endif %}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
{% comment %} Mermaid Diagrams - Conditional loading based on page front matter {% endcomment %}
|
|
71
71
|
{% if page.mermaid %}
|
|
72
72
|
{% include components/mermaid.html %}
|
|
73
73
|
{% endif %}
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
{% comment %} Nano Progress Bar - Visual loading indicator (config-driven) — page-invariant, cached. {% endcomment %}
|
|
76
76
|
{% include_cached components/nanobar.html %}
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
{% comment %} MathJax - Conditional loading based on page front matter (like Mermaid) {% endcomment %}
|
|
79
79
|
{% if page.mathjax %}
|
|
80
|
-
|
|
81
|
-
Enables $...$ inline math (off by default in MathJax 3).
|
|
80
|
+
{% comment %} MathJax 3 configuration — must appear before the script tag.
|
|
81
|
+
Enables $...$ inline math (off by default in MathJax 3). {% endcomment %}
|
|
82
82
|
<script>
|
|
83
83
|
window.MathJax = {
|
|
84
84
|
tex: {
|
|
@@ -91,33 +91,45 @@ window.MathJax = {
|
|
|
91
91
|
<script id="MathJax-script" async src="{{ '/assets/vendor/mathjax/es5/tex-mml-chtml.js' | relative_url }}"></script>
|
|
92
92
|
{% endif %}
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
{% comment %} ================================ {% endcomment %}
|
|
95
|
+
{% comment %} HTML DOCUMENT META DATA {% endcomment %}
|
|
96
|
+
{% comment %} ================================ {% endcomment %}
|
|
97
|
+
{%- comment -%} NOTE: the charset meta is NOT here — it lives at the very top
|
|
98
|
+
of _layouts/root.html so it lands inside the spec's 1024-byte window
|
|
99
|
+
(issue #372). Do not re-add it here. {%- endcomment -%}
|
|
99
100
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
100
101
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
/favicon.ico fallback so baseurl deployments resolve) — page-invariant, cached.
|
|
103
|
+
{% comment %} Favicon + browser identity (config-driven via `favicon:`; explicit
|
|
104
|
+
/favicon.ico fallback so baseurl deployments resolve) — page-invariant, cached. {% endcomment %}
|
|
104
105
|
{% include_cached core/favicon.html %}
|
|
105
106
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
{%- comment -%} Feed autodiscovery. jekyll-feed generates /feed.xml but emits
|
|
108
|
+
no link element unless feed_meta is called, so the feed was undiscoverable
|
|
109
|
+
to readers and crawlers even though the footer links it (issue #371).
|
|
110
|
+
Written out by hand rather than via feed_meta so the theme does not
|
|
111
|
+
hard-fail with "Unknown tag" on a consumer site that has not enabled the
|
|
112
|
+
plugin; the path matches the footer's own /feed.xml link. {%- endcomment -%}
|
|
113
|
+
{%- assign _feed_path = site.feed.path | default: 'feed.xml' -%}
|
|
114
|
+
<link rel="alternate" type="application/atom+xml"
|
|
115
|
+
title="{{ site.title | default: site.name | escape }}"
|
|
116
|
+
href="{{ _feed_path | relative_url }}">
|
|
117
|
+
|
|
118
|
+
{% comment %} ================================ {% endcomment %}
|
|
119
|
+
{% comment %} SEO SUPPLEMENT {% endcomment %}
|
|
120
|
+
{% comment %} ================================ {% endcomment %}
|
|
121
|
+
{% comment %} Additional SEO tags not covered by jekyll-seo-tag plugin ( in root.html).
|
|
122
|
+
Outputs custom og:image with assets_prefix normalisation and non-Google site verification. {% endcomment %}
|
|
111
123
|
{% include content/seo.html %}
|
|
112
124
|
|
|
113
|
-
|
|
114
|
-
page has none) — see _data/i18n/manifest.yml + scripts/translate.rb
|
|
125
|
+
{% comment %} hreflang alternates for machine-generated translations (no-op when the
|
|
126
|
+
page has none) — see _data/i18n/manifest.yml + scripts/translate.rb {% endcomment %}
|
|
115
127
|
{% include core/hreflang.html %}
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
129
|
+
{% comment %} ========================== {% endcomment %}
|
|
130
|
+
{% comment %} STRUCTURED DATA MARKUP {% endcomment %}
|
|
131
|
+
{% comment %} ========================== {% endcomment %}
|
|
132
|
+
{% comment %} Enhanced meta data for rich snippets and social media {% endcomment %}
|
|
121
133
|
{% if page.title %}
|
|
122
134
|
<meta itemprop="headline" content="{{ page.title | markdownify | strip_html | strip_newlines | escape_once }}">
|
|
123
135
|
{% endif %}
|
|
@@ -135,84 +147,84 @@ window.MathJax = {
|
|
|
135
147
|
<meta itemprop="dateModified" content="{{ page.lastmod | date_to_xmlschema }}">
|
|
136
148
|
{% endif %}
|
|
137
149
|
|
|
138
|
-
|
|
150
|
+
{% comment %} JSON-LD SoftwareApplication schema (homepage only) {% endcomment %}
|
|
139
151
|
{% include content/jsonld-software.html %}
|
|
140
152
|
|
|
141
|
-
|
|
153
|
+
{% comment %} JSON-LD FAQ schema (pages with faq_items front matter) {% endcomment %}
|
|
142
154
|
{% include content/jsonld-faq.html %}
|
|
143
155
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
156
|
+
{% comment %} ========================== {% endcomment %}
|
|
157
|
+
{% comment %} ANALYTICS INTEGRATION {% endcomment %}
|
|
158
|
+
{% comment %} ========================== {% endcomment %}
|
|
159
|
+
{% comment %} Google Analytics tracking - Configured in _config.yml {% endcomment %}
|
|
160
|
+
{% comment %} Only load in production AND when an ID is configured; the include also guards against dev hostnames {% endcomment %}
|
|
149
161
|
{% if jekyll.environment == "production" and site.google_analytics %}{% include analytics/google-analytics.html %}{% endif %}
|
|
150
162
|
|
|
151
|
-
|
|
152
|
-
|
|
163
|
+
{% comment %} PostHog analytics - Configured via the `posthog:` block in _config.yml {% endcomment %}
|
|
164
|
+
{% comment %} Only load in production AND when explicitly enabled; the include itself also respects Do Not Track {% endcomment %}
|
|
153
165
|
{% if jekyll.environment == "production" and site.posthog.enabled %}{% include analytics/posthog.html %}{% endif %}
|
|
154
166
|
|
|
155
167
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
168
|
+
{% comment %} ================================ {% endcomment %}
|
|
169
|
+
{% comment %} CSS FRAMEWORKS AND LIBRARIES {% endcomment %}
|
|
170
|
+
{% comment %} ================================ {% endcomment %}
|
|
159
171
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
172
|
+
{% comment %} ========================== {% endcomment %}
|
|
173
|
+
{% comment %} COLOR MODE INIT (FOUC FIX) {% endcomment %}
|
|
174
|
+
{% comment %} ========================== {% endcomment %}
|
|
175
|
+
{% comment %} Must run BEFORE Bootstrap CSS so the correct data-bs-theme is applied
|
|
164
176
|
when [data-bs-theme=dark/light] selectors are first evaluated.
|
|
165
177
|
Reads site.color_mode_default (via data-color-mode-default attr on <html>)
|
|
166
|
-
and falls back to localStorage["theme"] for the user's explicit preference.
|
|
178
|
+
and falls back to localStorage["theme"] for the user's explicit preference. {% endcomment %}
|
|
167
179
|
{% include core/color-mode-init.html %}
|
|
168
180
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
181
|
+
{% comment %} ========================== {% endcomment %}
|
|
182
|
+
{% comment %} BOOTSTRAP 5 FRAMEWORK {% endcomment %}
|
|
183
|
+
{% comment %} ========================== {% endcomment %}
|
|
184
|
+
{% comment %} Bootstrap 5.3.3 - bundled locally (GitHub Pages–safe; refresh via scripts/vendor-install.sh) {% endcomment %}
|
|
173
185
|
<link href="{{ '/assets/vendor/bootstrap/css/bootstrap.min.css' | relative_url }}" rel="stylesheet">
|
|
174
186
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
187
|
+
{% comment %} ========================== {% endcomment %}
|
|
188
|
+
{% comment %} ICON LIBRARIES {% endcomment %}
|
|
189
|
+
{% comment %} ========================== {% endcomment %}
|
|
190
|
+
{% comment %} Bootstrap Icons (bundled with theme; fonts use relative paths in CSS) {% endcomment %}
|
|
179
191
|
<link rel="stylesheet" href="{{ '/assets/vendor/bootstrap-icons/font/bootstrap-icons.css' | relative_url }}">
|
|
180
192
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
193
|
+
{% comment %} ========================== {% endcomment %}
|
|
194
|
+
{% comment %} CUSTOM THEME STYLES {% endcomment %}
|
|
195
|
+
{% comment %} ========================== {% endcomment %}
|
|
196
|
+
{% comment %} Primary theme stylesheet - Core styling and layout (SCSS pipeline) {% endcomment %}
|
|
185
197
|
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}">
|
|
186
198
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
and any per-user Appearance overrides win over compiled defaults.
|
|
199
|
+
{% comment %} ========================== {% endcomment %}
|
|
200
|
+
{% comment %} DESIGN TOKEN OVERRIDES {% endcomment %}
|
|
201
|
+
{% comment %} ========================== {% endcomment %}
|
|
202
|
+
{% comment %} Inline <style> block emitted AFTER main.css so site-config `theme_color` keys
|
|
203
|
+
and any per-user Appearance overrides win over compiled defaults. {% endcomment %}
|
|
192
204
|
{% include core/tokens-inline.html %}
|
|
193
205
|
|
|
194
|
-
|
|
195
|
-
Loaded LAST so consumer rules win over both main.css and tokens-inline.
|
|
206
|
+
{% comment %} Optional fork overrides: opt-in via `site.user_overrides: true` in _config.yml.
|
|
207
|
+
Loaded LAST so consumer rules win over both main.css and tokens-inline. {% endcomment %}
|
|
196
208
|
{% if site.user_overrides %}
|
|
197
209
|
<link rel="stylesheet" href="{{ '/assets/css/user-overrides.css' | relative_url }}">
|
|
198
210
|
{% endif %}
|
|
199
211
|
|
|
200
|
-
|
|
212
|
+
{% comment %} Statistics page specific styles {% endcomment %}
|
|
201
213
|
{% if page.layout == 'stats' or page.permalink == '/about/stats/' %}
|
|
202
214
|
<link rel="stylesheet" href="{{ '/assets/css/stats.css' | relative_url }}">
|
|
203
215
|
{% endif %}
|
|
204
216
|
|
|
205
|
-
|
|
217
|
+
{% comment %} Consumer hook: end of <head>. Inject JSON-LD, font preloads, verification
|
|
206
218
|
tags, or extra meta by shadowing _includes/custom/head.html in your site —
|
|
207
|
-
no fork of this file needed. The theme ships the stub empty.
|
|
219
|
+
no fork of this file needed. The theme ships the stub empty. {% endcomment %}
|
|
208
220
|
{% include custom/head.html %}
|
|
209
221
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
222
|
+
{% comment %} ========================== {% endcomment %}
|
|
223
|
+
{% comment %} EXPERIMENTAL FRAMEWORKS {% endcomment %}
|
|
224
|
+
{% comment %} ========================== {% endcomment %}
|
|
225
|
+
{% comment %} Tailwind CSS - Currently disabled, enable for utility-first styling {% endcomment %}
|
|
226
|
+
{% comment %} <script src="https://cdn.tailwindcss.com"></script> {% endcomment %}
|
|
215
227
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
228
|
+
{% comment %} Docs CSS - Alternative stylesheet, currently disabled due to scroll spy issues {% endcomment %}
|
|
229
|
+
{% comment %} TODO: Replace with compiled Sass when scroll spy functionality is fixed {% endcomment %}
|
|
230
|
+
{% comment %} Optional docs.css link removed; use _sass/core/_docs-layout.scss → main.css {% endcomment %}
|
data/_includes/core/header.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-011 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
HEADER - Main Navigation and Site Header
|
|
5
5
|
===================================================================
|
|
@@ -36,48 +36,67 @@
|
|
|
36
36
|
- When `position: navbar`, the bar mounts inside `#top-progress-target` below
|
|
37
37
|
- Otherwise it floats fixed to the viewport (top or bottom)
|
|
38
38
|
===================================================================
|
|
39
|
-
|
|
39
|
+
{% endcomment %}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
{% comment %} ================================ {% endcomment %}
|
|
42
|
+
{% comment %} SKIP TO CONTENT LINK {% endcomment %}
|
|
43
|
+
{% comment %} ================================ {% endcomment %}
|
|
44
|
+
{% comment %} UI strings resolve per page language (core/i18n.html sets `ui`) {% endcomment %}
|
|
45
45
|
{%- include core/i18n.html -%}
|
|
46
|
-
|
|
46
|
+
{% comment %} Accessibility: allows keyboard users to skip navigation {% endcomment %}
|
|
47
47
|
<a href="#main-content" class="visually-hidden-focusable position-absolute top-0 start-0 z-3 m-3 btn btn-primary">
|
|
48
48
|
{{ ui.skip_main_content | default: "Skip to main content" }}
|
|
49
49
|
</a>
|
|
50
50
|
|
|
51
51
|
<header id="navbar" class="container-fluid text-center fixed-top" role="banner">
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
{% comment %} ================================ {% endcomment %}
|
|
54
|
+
{% comment %} TOP NAVIGATION BAR {% endcomment %}
|
|
55
|
+
{% comment %} ================================ {% endcomment %}
|
|
56
56
|
<div class="navbar navbar-expand-lg bg-body-tertiary flex-nowrap w-100 bottom-shadow">
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
{% comment %} ========================== {% endcomment %}
|
|
59
|
+
{% comment %} MAIN NAVIGATION CONTAINER {% endcomment %}
|
|
60
|
+
{% comment %} ========================== {% endcomment %}
|
|
61
61
|
<nav class="container-fluid order-2 order-lg-1 d-flex align-items-center gap-1 flex-nowrap navbar-main w-100" aria-label="Primary navigation">
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
{% comment %} Leading cluster: sidebar toggle + brand + titles (grid column 1 on lg+) {% endcomment %}
|
|
64
64
|
<div class="navbar-main-start d-flex align-items-center gap-1 gap-lg-2 min-w-0 flex-shrink-1 flex-grow-1">
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
{% comment %} ========================== {% endcomment %}
|
|
67
|
+
{% comment %} MOBILE MENU CONTROLS {% endcomment %}
|
|
68
|
+
{% comment %} ========================== {% endcomment %}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
{% comment %} Left Sidebar Toggle - Mobile view only. Uses the shared
|
|
71
71
|
resolver (navigation/sidebar-config.html) so this gate can
|
|
72
|
-
never drift from the default layout's aside.
|
|
72
|
+
never drift from the default layout's aside. {% endcomment %}
|
|
73
73
|
{% include navigation/sidebar-config.html %}
|
|
74
74
|
|
|
75
|
-
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
{%- comment -%}
|
|
76
|
+
Two conditions, and BOTH are required (issue #373).
|
|
77
|
+
|
|
78
|
+
`sidebar_has_content` asks "is there nav content to show". It is
|
|
79
|
+
not enough on its own: this include is pulled in by
|
|
80
|
+
_layouts/root.html, so it renders on EVERY layout, while
|
|
81
|
+
`#bdSidebar` is emitted by _layouts/default.html alone. On a
|
|
82
|
+
layout that inherits root directly — admin, stats, 404, section,
|
|
83
|
+
home … — the toggle rendered pointing at an offcanvas that was
|
|
84
|
+
never in the document: a dead control, and aria-controls
|
|
85
|
+
dangling into nothing for assistive tech. Measured before the
|
|
86
|
+
fix: 37 of 415 built pages.
|
|
87
|
+
|
|
88
|
+
The unified drawer is exempt because #zer0UnifiedDrawer IS
|
|
89
|
+
emitted from root.html, so it exists on every layout — that
|
|
90
|
+
target is always real and the toggle is always live.
|
|
91
|
+
{%- endcomment -%}
|
|
92
|
+
{% if sidebar_has_content and site.navigation.unified_mobile_drawer %}
|
|
93
|
+
{%- assign _sidebar_toggle_ok = true -%}
|
|
94
|
+
{% elsif sidebar_has_content and sidebar_offcanvas_rendered %}
|
|
95
|
+
{%- assign _sidebar_toggle_ok = true -%}
|
|
96
|
+
{% else %}
|
|
97
|
+
{%- assign _sidebar_toggle_ok = false -%}
|
|
98
|
+
{% endif %}
|
|
99
|
+
{% if _sidebar_toggle_ok %}
|
|
81
100
|
{%- if site.navigation.unified_mobile_drawer -%}
|
|
82
101
|
{%- assign _sidebar_target = "#zer0UnifiedDrawer" -%}
|
|
83
102
|
{%- assign _sidebar_controls = "zer0UnifiedDrawer" -%}
|
|
@@ -98,11 +117,11 @@
|
|
|
98
117
|
</div>
|
|
99
118
|
{% endif %}
|
|
100
119
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
{% comment %} ========================== {% endcomment %}
|
|
121
|
+
{% comment %} BRAND AND HOME NAVIGATION {% endcomment %}
|
|
122
|
+
{% comment %} ========================== {% endcomment %}
|
|
104
123
|
<div class="navbar-brand-group d-inline-flex align-items-center gap-2">
|
|
105
|
-
|
|
124
|
+
{% comment %} Home Navigation Button (Desktop only) {% endcomment %}
|
|
106
125
|
<div class="navbar-home-links d-none" role="navigation" aria-label="Quick navigation">
|
|
107
126
|
{%- assign nav_home = site.data.navigation.home -%}
|
|
108
127
|
{%- if nav_home and nav_home.size > 0 -%}
|
|
@@ -118,18 +137,18 @@
|
|
|
118
137
|
{%- endif -%}
|
|
119
138
|
</div>
|
|
120
139
|
|
|
121
|
-
|
|
122
|
-
|
|
140
|
+
{% comment %} Brand Logo Link to Root {% endcomment %}
|
|
141
|
+
{% comment %} Logo path configured in _config.yml {% endcomment %}
|
|
123
142
|
{% capture logo_path %}{{ site.logo }}{% endcapture %}
|
|
124
143
|
<a class="navbar-brand" href="{{ site.baseurl }}/" aria-label="Home - {{ site.title }}" {% if page.url == '/' %}aria-current="page"{% endif %}>
|
|
125
144
|
<img src="{{ logo_path | relative_url }}" alt="{{ site.title }} logo" width="30" height="30">
|
|
126
145
|
</a>
|
|
127
146
|
</div>
|
|
128
147
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
148
|
+
{% comment %} ========================== {% endcomment %}
|
|
149
|
+
{% comment %} SITE BRANDING SECTION {% endcomment %}
|
|
150
|
+
{% comment %} ========================== {% endcomment %}
|
|
151
|
+
{% comment %} Site title and subtitle display {% endcomment %}
|
|
133
152
|
{% include core/branding.html %}
|
|
134
153
|
|
|
135
154
|
</div>
|
|
@@ -141,21 +160,21 @@
|
|
|
141
160
|
{%- endcomment -%}
|
|
142
161
|
{% include navigation/navbar-mobile-quicklinks.html %}
|
|
143
162
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
163
|
+
{% comment %} ========================== {% endcomment %}
|
|
164
|
+
{% comment %} MAIN NAVIGATION MENU {% endcomment %}
|
|
165
|
+
{% comment %} ========================== {% endcomment %}
|
|
166
|
+
{% comment %} Primary navigation items from _data/navigation.yml {% endcomment %}
|
|
148
167
|
{% include navigation/navbar.html %}
|
|
149
168
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
169
|
+
{% comment %} ========================== {% endcomment %}
|
|
170
|
+
{% comment %} UTILITY CONTROLS {% endcomment %}
|
|
171
|
+
{% comment %} ========================== {% endcomment %}
|
|
153
172
|
<div class="navbar-utility-controls d-flex align-items-center flex-shrink-0" role="group" aria-label="Utility controls">
|
|
154
|
-
|
|
173
|
+
{% comment %} Language selection lives in the Settings offcanvas
|
|
155
174
|
(components/info-section.html, Appearance tab) so the bar
|
|
156
|
-
keeps its width for the main navigation items.
|
|
175
|
+
keeps its width for the main navigation items. {% endcomment %}
|
|
157
176
|
|
|
158
|
-
|
|
177
|
+
{% comment %} Search Modal Toggle {% endcomment %}
|
|
159
178
|
<button
|
|
160
179
|
class="btn nav-search-button"
|
|
161
180
|
type="button"
|
|
@@ -170,7 +189,7 @@
|
|
|
170
189
|
<kbd class="nav-search-kbd d-none d-xl-inline-flex" aria-hidden="true">/</kbd>
|
|
171
190
|
</button>
|
|
172
191
|
|
|
173
|
-
|
|
192
|
+
{% comment %} Settings Offcanvas Toggle {% endcomment %}
|
|
174
193
|
<button
|
|
175
194
|
class="btn nav-settings-button d-none d-lg-inline-flex"
|
|
176
195
|
type="button"
|
|
@@ -183,7 +202,7 @@
|
|
|
183
202
|
<i class="{{site.default_icon}} bi-gear" aria-hidden="true"></i>
|
|
184
203
|
</button>
|
|
185
204
|
|
|
186
|
-
|
|
205
|
+
{% comment %} Navigation Menu Toggle - Mobile view {% endcomment %}
|
|
187
206
|
{%- if site.navigation.unified_mobile_drawer -%}
|
|
188
207
|
{%- assign _menu_target = "#zer0UnifiedDrawer" -%}
|
|
189
208
|
{%- assign _menu_controls = "zer0UnifiedDrawer" -%}
|
|
@@ -206,12 +225,12 @@
|
|
|
206
225
|
</nav>
|
|
207
226
|
</div>
|
|
208
227
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
228
|
+
{% comment %} ========================== {% endcomment %}
|
|
229
|
+
{% comment %} PROGRESS BAR MOUNT POINT {% endcomment %}
|
|
230
|
+
{% comment %} ========================== {% endcomment %}
|
|
231
|
+
{% comment %} Nanobar mounts here when site.nanobar.position == "navbar" so the bar
|
|
213
232
|
renders as a thin strip directly under the header. For "top" / "bottom"
|
|
214
|
-
the bar floats fixed to the viewport and no mount is needed.
|
|
233
|
+
the bar floats fixed to the viewport and no mount is needed. {% endcomment %}
|
|
215
234
|
{%- assign _nb_pos = site.nanobar.position | default: "top" -%}
|
|
216
235
|
{%- if site.nanobar.enabled != false and _nb_pos == "navbar" -%}
|
|
217
236
|
<div id="top-progress-target" class="nanobar-mount" aria-hidden="true"></div>
|