jekyll-theme-zer0 1.28.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.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1143 -13
  3. data/_data/README.md +2 -0
  4. data/_data/ai.yml +5 -3
  5. data/_data/ai_pricing.yml +36 -0
  6. data/_data/backlog.yml +507 -2
  7. data/_data/consumers.yml +157 -9
  8. data/_data/features.yml +303 -20
  9. data/_data/feedback_types.yml +17 -12
  10. data/_data/i18n/fr.yml +12 -7
  11. data/_data/i18n/manifest.yml +39 -12
  12. data/_data/ingredient_densities.yml +122 -0
  13. data/_data/landing.yml +5 -2
  14. data/_data/navigation/main.yml +16 -0
  15. data/_data/navigation/quickstart.yml +4 -0
  16. data/_data/recipe_courses.yml +64 -0
  17. data/_data/site_builder.yml +874 -0
  18. data/_data/theme-manifest.yml +160 -124
  19. data/_data/ui-text.yml +26 -0
  20. data/_includes/README.md +26 -2
  21. data/_includes/analytics/posthog.html +2 -2
  22. data/_includes/components/admin-links.html +2 -2
  23. data/_includes/components/admin-tabs.html +2 -2
  24. data/_includes/components/ai-chat.html +14 -11
  25. data/_includes/components/analytics-dashboard.html +8 -8
  26. data/_includes/components/author-bio.html +1 -1
  27. data/_includes/components/author-card.html +10 -2
  28. data/_includes/components/author-eeat.html +4 -4
  29. data/_includes/components/background-customizer.html +10 -10
  30. data/_includes/components/background-image.html +114 -0
  31. data/_includes/components/background-settings.html +28 -15
  32. data/_includes/components/collection-manager.html +5 -5
  33. data/_includes/components/component-showcase.html +13 -13
  34. data/_includes/components/config-editor.html +12 -12
  35. data/_includes/components/config-viewer.html +8 -8
  36. data/_includes/components/cookie-consent.html +15 -15
  37. data/_includes/components/cta-button.html +7 -2
  38. data/_includes/components/dev-shortcuts.html +7 -7
  39. data/_includes/components/env-dashboard.html +8 -8
  40. data/_includes/components/env-switcher.html +9 -9
  41. data/_includes/components/feature-card.html +2 -2
  42. data/_includes/components/halfmoon.html +2 -2
  43. data/_includes/components/info-section.html +42 -37
  44. data/_includes/components/js-cdn.html +15 -15
  45. data/_includes/components/language-toggle.html +168 -21
  46. data/_includes/components/mermaid.html +72 -435
  47. data/_includes/components/nanobar.html +5 -5
  48. data/_includes/components/nav-editor.html +2 -2
  49. data/_includes/components/nav-export.html +2 -2
  50. data/_includes/components/nav-overview.html +2 -2
  51. data/_includes/components/page-feedback.html +45 -30
  52. data/_includes/components/page-views-init.html +55 -0
  53. data/_includes/components/page-views.html +33 -0
  54. data/_includes/components/post-card.html +22 -22
  55. data/_includes/components/post-type-badge.html +2 -2
  56. data/_includes/components/powered-by.html +2 -2
  57. data/_includes/components/preview-image.html +6 -0
  58. data/_includes/components/quick-index.html +2 -2
  59. data/_includes/components/recipe-card.html +67 -0
  60. data/_includes/components/recipe-duration.html +50 -0
  61. data/_includes/components/recipe-grams.html +58 -0
  62. data/_includes/components/recipe-index.html +96 -0
  63. data/_includes/components/recipe-ingredients.html +90 -0
  64. data/_includes/components/recipe-meta.html +96 -0
  65. data/_includes/components/recipe-nutrition.html +57 -0
  66. data/_includes/components/recipe-qty.html +73 -0
  67. data/_includes/components/recipe-ratio.html +151 -0
  68. data/_includes/components/recipe-scaler.html +73 -0
  69. data/_includes/components/recipe-steps.html +86 -0
  70. data/_includes/components/recipe-temp.html +45 -0
  71. data/_includes/components/search-modal.html +29 -4
  72. data/_includes/components/searchbar.html +2 -2
  73. data/_includes/components/shortcuts-modal.html +3 -0
  74. data/_includes/components/svg-background.html +2 -2
  75. data/_includes/components/theme-customizer.html +2 -2
  76. data/_includes/components/theme-info.html +14 -7
  77. data/_includes/components/theme-preview-gallery.html +22 -22
  78. data/_includes/content/giscus.html +2 -2
  79. data/_includes/content/intro.html +8 -8
  80. data/_includes/content/jsonld-faq.html +2 -2
  81. data/_includes/content/jsonld-software.html +24 -5
  82. data/_includes/content/seo.html +4 -4
  83. data/_includes/content/sitemap.html +27 -27
  84. data/_includes/content/toc.html +183 -183
  85. data/_includes/core/branding.html +6 -6
  86. data/_includes/core/console-capture.html +32 -74
  87. data/_includes/core/favicon.html +49 -7
  88. data/_includes/core/footer-fabs.html +17 -3
  89. data/_includes/core/footer.html +49 -34
  90. data/_includes/core/head.html +110 -86
  91. data/_includes/core/header.html +76 -54
  92. data/_includes/docs/bootstrap-docs.html +8 -8
  93. data/_includes/landing/landing-install-cards.html +2 -2
  94. data/_includes/landing/landing-quick-links.html +1 -1
  95. data/_includes/navigation/admin-nav.html +2 -2
  96. data/_includes/navigation/nav-tree.html +8 -8
  97. data/_includes/navigation/navbar.html +12 -12
  98. data/_includes/navigation/section-sidebar.html +109 -27
  99. data/_includes/navigation/sidebar-config.html +36 -2
  100. data/_includes/navigation/sidebar-left.html +17 -16
  101. data/_includes/navigation/sidebar-right.html +8 -7
  102. data/_includes/obsidian/full-graph.html +2 -2
  103. data/_includes/setup/claude-session.html +72 -0
  104. data/_includes/setup/prereq-checklist.html +90 -0
  105. data/_includes/setup/wizard.html +924 -222
  106. data/_includes/stats/stats-categories.html +8 -8
  107. data/_includes/stats/stats-header.html +14 -14
  108. data/_includes/stats/stats-metrics.html +14 -14
  109. data/_includes/stats/stats-no-data.html +12 -12
  110. data/_includes/stats/stats-overview.html +6 -6
  111. data/_includes/stats/stats-tags.html +8 -8
  112. data/_layouts/404.html +38 -24
  113. data/_layouts/README.md +2 -0
  114. data/_layouts/admin.html +24 -24
  115. data/_layouts/article.html +43 -33
  116. data/_layouts/author.html +20 -20
  117. data/_layouts/authors.html +2 -2
  118. data/_layouts/book-abc.html +12 -12
  119. data/_layouts/book-story.html +15 -15
  120. data/_layouts/book.html +12 -12
  121. data/_layouts/collection.html +33 -33
  122. data/_layouts/cookbook.html +88 -0
  123. data/_layouts/default.html +31 -28
  124. data/_layouts/home.html +23 -23
  125. data/_layouts/index.html +10 -10
  126. data/_layouts/landing.html +17 -17
  127. data/_layouts/news.html +44 -44
  128. data/_layouts/note.html +38 -38
  129. data/_layouts/notebook.html +34 -34
  130. data/_layouts/recipe.html +274 -0
  131. data/_layouts/root.html +92 -55
  132. data/_layouts/section.html +62 -33
  133. data/_layouts/setup.html +3 -3
  134. data/_layouts/sitemap-collection.html +49 -49
  135. data/_layouts/stats.html +40 -40
  136. data/_layouts/tag.html +12 -12
  137. data/_layouts/welcome.html +21 -21
  138. data/_sass/components/_callout.scss +1 -1
  139. data/_sass/components/_footer.scss +37 -1
  140. data/_sass/components/_mermaid.scss +375 -0
  141. data/_sass/components/_page-views.scss +36 -0
  142. data/_sass/components/_recipe.scss +506 -0
  143. data/_sass/components/_setup-wizard.scss +764 -0
  144. data/_sass/components/_ui-enhancements.scss +6 -6
  145. data/_sass/core/_navbar.scss +261 -46
  146. data/_sass/layouts/_landing.scss +2 -2
  147. data/_sass/layouts/_navbar-extras.scss +14 -4
  148. data/_sass/tokens/_color.scss +6 -0
  149. data/_sass/tokens/_index.scss +2 -0
  150. data/_sass/tokens/_radius.scss +21 -0
  151. data/_sass/tokens/_typography.scss +4 -0
  152. data/_sass/utilities/_focus.scss +14 -0
  153. data/assets/css/main.scss +4 -0
  154. data/assets/js/ai-chat.js +47 -5
  155. data/assets/js/fleet-feedback-capture.js +124 -0
  156. data/assets/js/fleet-feedback.js +853 -0
  157. data/assets/js/mermaid-diagrams.js +1267 -0
  158. data/assets/js/modules/navigation/config.js +9 -6
  159. data/assets/js/modules/navigation/navbar.js +55 -0
  160. data/assets/js/modules/navigation/scroll-spy.js +315 -80
  161. data/assets/js/modules/theme/appearance.js +8 -2
  162. data/assets/js/obsidian-wiki-links.js +8 -3
  163. data/assets/js/page-feedback.js +125 -192
  164. data/assets/js/page-views.js +372 -0
  165. data/assets/js/recipe-scaler.js +501 -0
  166. data/assets/js/search-modal.js +36 -0
  167. data/assets/js/setup-wizard.js +2279 -226
  168. data/assets/js/site-builder.js +1834 -0
  169. data/assets/js/ui-enhancements.js +11 -3
  170. data/scripts/README.md +44 -0
  171. data/scripts/ai/README.md +38 -0
  172. data/scripts/ai/api_call.rb +124 -0
  173. data/scripts/ai/usage.rb +314 -0
  174. data/scripts/ai/usage_report.rb +225 -0
  175. data/scripts/bin/audit-consumer +39 -7
  176. data/scripts/bin/giscus-discussions +213 -14
  177. data/scripts/bin/manifest +35 -12
  178. data/scripts/ci/agent_review_result.py +164 -0
  179. data/scripts/ci/test_agent_review_result.py +172 -0
  180. data/scripts/ci/test_visual_evidence_autogen.py +341 -0
  181. data/scripts/ci/visual_evidence_autogen.py +1060 -0
  182. data/scripts/content-review.rb +20 -1
  183. data/scripts/design-system-check.rb +170 -0
  184. data/scripts/lib/audit.sh +42 -2
  185. data/scripts/lint-liquid-raw.rb +137 -0
  186. data/scripts/test/integration/mermaid +22 -8
  187. data/scripts/test/lib/run_tests.sh +3 -1
  188. data/scripts/test/lib/test_agent_review_result.sh +27 -0
  189. data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
  190. data/scripts/translate.rb +94 -16
  191. metadata +48 -2
@@ -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
- <!-- ANALYTICS AND TRACKING -->
33
- <!-- ================================ -->
34
- <!-- Google Tag Manager - Must be in head section for proper tracking -->
35
- <!-- Only load in production builds (JEKYLL_ENV=production); the include also guards against dev hostnames -->
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
- <!-- 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. -->
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
- <!-- JAVASCRIPT LIBRARIES -->
44
- <!-- ================================ -->
45
- <!-- Custom theme JavaScript - Deferred for performance -->
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,22 +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
- <!-- ================================ -->
55
- <!-- THIRD PARTY INTEGRATIONS -->
56
- <!-- ================================ -->
54
+ {% comment %} Page-view counter — injects its config and loads assets/js/page-views.js.
55
+ Renders nothing on its own; components/page-views.html places the badge.
56
+ Gated on site.page_views.enabled inside the include. {% endcomment %}
57
+ {% include components/page-views-init.html %}
57
58
 
58
- <!-- Mermaid Diagrams - Conditional loading based on page front matter -->
59
+ {% comment %} ================================ {% endcomment %}
60
+ {% comment %} THIRD PARTY INTEGRATIONS {% endcomment %}
61
+ {% comment %} ================================ {% endcomment %}
62
+
63
+ {% comment %} Recipe scaling & unit conversion - Only on pages that render recipe
64
+ quantities: the `recipe` layout, or any page that opts in with
65
+ `recipe_tools: true` (e.g. a post embedding components/recipe-*.html). {% endcomment %}
66
+ {% if page.layout == "recipe" or page.recipe_tools %}
67
+ <script defer src="{{ '/assets/js/recipe-scaler.js' | relative_url }}"></script>
68
+ {% endif %}
69
+
70
+ {% comment %} Mermaid Diagrams - Conditional loading based on page front matter {% endcomment %}
59
71
  {% if page.mermaid %}
60
72
  {% include components/mermaid.html %}
61
73
  {% endif %}
62
74
 
63
- <!-- Nano Progress Bar - Visual loading indicator (config-driven) — page-invariant, cached. -->
75
+ {% comment %} Nano Progress Bar - Visual loading indicator (config-driven) — page-invariant, cached. {% endcomment %}
64
76
  {% include_cached components/nanobar.html %}
65
77
 
66
- <!-- MathJax - Conditional loading based on page front matter (like Mermaid) -->
78
+ {% comment %} MathJax - Conditional loading based on page front matter (like Mermaid) {% endcomment %}
67
79
  {% if page.mathjax %}
68
- <!-- MathJax 3 configuration — must appear before the script tag.
69
- 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 %}
70
82
  <script>
71
83
  window.MathJax = {
72
84
  tex: {
@@ -79,33 +91,45 @@ window.MathJax = {
79
91
  <script id="MathJax-script" async src="{{ '/assets/vendor/mathjax/es5/tex-mml-chtml.js' | relative_url }}"></script>
80
92
  {% endif %}
81
93
 
82
- <!-- ================================ -->
83
- <!-- HTML DOCUMENT META DATA -->
84
- <!-- ================================ -->
85
- <!-- Essential meta tags for proper document rendering and mobile support -->
86
- <meta charset="utf-8">
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 -%}
87
100
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
88
101
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
89
102
 
90
- <!-- Favicon + browser identity (config-driven via `favicon:`; explicit
91
- /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 %}
92
105
  {% include_cached core/favicon.html %}
93
106
 
94
- <!-- ================================ -->
95
- <!-- SEO SUPPLEMENT -->
96
- <!-- ================================ -->
97
- <!-- Additional SEO tags not covered by jekyll-seo-tag plugin ( in root.html).
98
- Outputs custom og:image with assets_prefix normalisation and non-Google site verification. -->
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 %}
99
123
  {% include content/seo.html %}
100
124
 
101
- <!-- hreflang alternates for machine-generated translations (no-op when the
102
- 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 %}
103
127
  {% include core/hreflang.html %}
104
128
 
105
- <!-- ========================== -->
106
- <!-- STRUCTURED DATA MARKUP -->
107
- <!-- ========================== -->
108
- <!-- Enhanced meta data for rich snippets and social media -->
129
+ {% comment %} ========================== {% endcomment %}
130
+ {% comment %} STRUCTURED DATA MARKUP {% endcomment %}
131
+ {% comment %} ========================== {% endcomment %}
132
+ {% comment %} Enhanced meta data for rich snippets and social media {% endcomment %}
109
133
  {% if page.title %}
110
134
  <meta itemprop="headline" content="{{ page.title | markdownify | strip_html | strip_newlines | escape_once }}">
111
135
  {% endif %}
@@ -123,84 +147,84 @@ window.MathJax = {
123
147
  <meta itemprop="dateModified" content="{{ page.lastmod | date_to_xmlschema }}">
124
148
  {% endif %}
125
149
 
126
- <!-- JSON-LD SoftwareApplication schema (homepage only) -->
150
+ {% comment %} JSON-LD SoftwareApplication schema (homepage only) {% endcomment %}
127
151
  {% include content/jsonld-software.html %}
128
152
 
129
- <!-- JSON-LD FAQ schema (pages with faq_items front matter) -->
153
+ {% comment %} JSON-LD FAQ schema (pages with faq_items front matter) {% endcomment %}
130
154
  {% include content/jsonld-faq.html %}
131
155
 
132
- <!-- ========================== -->
133
- <!-- ANALYTICS INTEGRATION -->
134
- <!-- ========================== -->
135
- <!-- Google Analytics tracking - Configured in _config.yml -->
136
- <!-- Only load in production AND when an ID is configured; the include also guards against dev hostnames -->
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 %}
137
161
  {% if jekyll.environment == "production" and site.google_analytics %}{% include analytics/google-analytics.html %}{% endif %}
138
162
 
139
- <!-- PostHog analytics - Configured via the `posthog:` block in _config.yml -->
140
- <!-- Only load in production AND when explicitly enabled; the include itself also respects Do Not Track -->
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 %}
141
165
  {% if jekyll.environment == "production" and site.posthog.enabled %}{% include analytics/posthog.html %}{% endif %}
142
166
 
143
167
 
144
- <!-- ================================ -->
145
- <!-- CSS FRAMEWORKS AND LIBRARIES -->
146
- <!-- ================================ -->
168
+ {% comment %} ================================ {% endcomment %}
169
+ {% comment %} CSS FRAMEWORKS AND LIBRARIES {% endcomment %}
170
+ {% comment %} ================================ {% endcomment %}
147
171
 
148
- <!-- ========================== -->
149
- <!-- COLOR MODE INIT (FOUC FIX) -->
150
- <!-- ========================== -->
151
- <!-- Must run BEFORE Bootstrap CSS so the correct data-bs-theme is applied
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
152
176
  when [data-bs-theme=dark/light] selectors are first evaluated.
153
177
  Reads site.color_mode_default (via data-color-mode-default attr on <html>)
154
- 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 %}
155
179
  {% include core/color-mode-init.html %}
156
180
 
157
- <!-- ========================== -->
158
- <!-- BOOTSTRAP 5 FRAMEWORK -->
159
- <!-- ========================== -->
160
- <!-- Bootstrap 5.3.3 - bundled locally (GitHub Pages–safe; refresh via scripts/vendor-install.sh) -->
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 %}
161
185
  <link href="{{ '/assets/vendor/bootstrap/css/bootstrap.min.css' | relative_url }}" rel="stylesheet">
162
186
 
163
- <!-- ========================== -->
164
- <!-- ICON LIBRARIES -->
165
- <!-- ========================== -->
166
- <!-- Bootstrap Icons (bundled with theme; fonts use relative paths in CSS) -->
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 %}
167
191
  <link rel="stylesheet" href="{{ '/assets/vendor/bootstrap-icons/font/bootstrap-icons.css' | relative_url }}">
168
192
 
169
- <!-- ========================== -->
170
- <!-- CUSTOM THEME STYLES -->
171
- <!-- ========================== -->
172
- <!-- Primary theme stylesheet - Core styling and layout (SCSS pipeline) -->
193
+ {% comment %} ========================== {% endcomment %}
194
+ {% comment %} CUSTOM THEME STYLES {% endcomment %}
195
+ {% comment %} ========================== {% endcomment %}
196
+ {% comment %} Primary theme stylesheet - Core styling and layout (SCSS pipeline) {% endcomment %}
173
197
  <link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}">
174
198
 
175
- <!-- ========================== -->
176
- <!-- DESIGN TOKEN OVERRIDES -->
177
- <!-- ========================== -->
178
- <!-- Inline <style> block emitted AFTER main.css so site-config `theme_color` keys
179
- 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 %}
180
204
  {% include core/tokens-inline.html %}
181
205
 
182
- <!-- Optional fork overrides: opt-in via `site.user_overrides: true` in _config.yml.
183
- 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 %}
184
208
  {% if site.user_overrides %}
185
209
  <link rel="stylesheet" href="{{ '/assets/css/user-overrides.css' | relative_url }}">
186
210
  {% endif %}
187
211
 
188
- <!-- Statistics page specific styles -->
212
+ {% comment %} Statistics page specific styles {% endcomment %}
189
213
  {% if page.layout == 'stats' or page.permalink == '/about/stats/' %}
190
214
  <link rel="stylesheet" href="{{ '/assets/css/stats.css' | relative_url }}">
191
215
  {% endif %}
192
216
 
193
- <!-- Consumer hook: end of <head>. Inject JSON-LD, font preloads, verification
217
+ {% comment %} Consumer hook: end of <head>. Inject JSON-LD, font preloads, verification
194
218
  tags, or extra meta by shadowing _includes/custom/head.html in your site —
195
- 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 %}
196
220
  {% include custom/head.html %}
197
221
 
198
- <!-- ========================== -->
199
- <!-- EXPERIMENTAL FRAMEWORKS -->
200
- <!-- ========================== -->
201
- <!-- Tailwind CSS - Currently disabled, enable for utility-first styling -->
202
- <!-- <script src="https://cdn.tailwindcss.com"></script> -->
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 %}
203
227
 
204
- <!-- Docs CSS - Alternative stylesheet, currently disabled due to scroll spy issues -->
205
- <!-- TODO: Replace with compiled Sass when scroll spy functionality is fixed -->
206
- <!-- Optional docs.css link removed; use _sass/core/_docs-layout.scss → main.css -->
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 %}
@@ -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
- <!-- SKIP TO CONTENT LINK -->
43
- <!-- ================================ -->
44
- <!-- UI strings resolve per page language (core/i18n.html sets `ui`) -->
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
- <!-- Accessibility: allows keyboard users to skip navigation -->
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
- <!-- TOP NAVIGATION BAR -->
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
- <!-- MAIN NAVIGATION CONTAINER -->
60
- <!-- ========================== -->
61
- <nav class="container-xl order-2 order-lg-1 d-flex align-items-center gap-1 flex-nowrap navbar-main w-100" aria-label="Primary navigation">
58
+ {% comment %} ========================== {% endcomment %}
59
+ {% comment %} MAIN NAVIGATION CONTAINER {% endcomment %}
60
+ {% comment %} ========================== {% endcomment %}
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
- <!-- Leading cluster: sidebar toggle + brand + titles (grid column 1 on lg+) -->
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
- <!-- MOBILE MENU CONTROLS -->
68
- <!-- ========================== -->
66
+ {% comment %} ========================== {% endcomment %}
67
+ {% comment %} MOBILE MENU CONTROLS {% endcomment %}
68
+ {% comment %} ========================== {% endcomment %}
69
69
 
70
- <!-- Left Sidebar Toggle - Mobile view only. Uses the shared
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
- {% if sidebar_has_content %}
76
- {%- comment -%}
77
- When site.navigation.unified_mobile_drawer is true, the sidebar
78
- toggle opens the consolidated drawer (Browse tab pre-selected)
79
- instead of the legacy #bdSidebar offcanvas.
80
- {%- endcomment -%}
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
- <!-- BRAND AND HOME NAVIGATION -->
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
- <!-- Home Navigation Button (Desktop only) -->
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
- <!-- Brand Logo Link to Root -->
122
- <!-- Logo path configured in _config.yml -->
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
- <!-- SITE BRANDING SECTION -->
131
- <!-- ========================== -->
132
- <!-- Site title and subtitle display -->
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,33 +160,36 @@
141
160
  {%- endcomment -%}
142
161
  {% include navigation/navbar-mobile-quicklinks.html %}
143
162
 
144
- <!-- ========================== -->
145
- <!-- MAIN NAVIGATION MENU -->
146
- <!-- ========================== -->
147
- <!-- Primary navigation items from _data/navigation.yml -->
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
- <!-- UTILITY CONTROLS -->
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
- <!-- Language Toggle (renders only when translation.languages is set) -->
155
- {% include components/language-toggle.html %}
173
+ {% comment %} Language selection lives in the Settings offcanvas
174
+ (components/info-section.html, Appearance tab) so the bar
175
+ keeps its width for the main navigation items. {% endcomment %}
156
176
 
157
- <!-- Search Modal Toggle -->
177
+ {% comment %} Search Modal Toggle {% endcomment %}
158
178
  <button
159
179
  class="btn nav-search-button"
160
180
  type="button"
161
181
  data-search-toggle
162
182
  aria-label="{{ ui.shortcuts_search | default: 'Open search' }}"
163
183
  aria-haspopup="dialog"
164
- title="{{ ui.search_button_label | default: 'Search' }}"
184
+ aria-keyshortcuts="/ Meta+K Control+K"
185
+ title="{{ ui.search_button_title | default: 'Search — press / or Ctrl+K' }}"
165
186
  >
166
187
  <i class="{{site.default_icon}} bi-search" aria-hidden="true"></i>
167
188
  <span class="nav-link-text d-none d-xl-inline ms-1">{{ ui.search_button_label | default: "Search" }}</span>
189
+ <kbd class="nav-search-kbd d-none d-xl-inline-flex" aria-hidden="true">/</kbd>
168
190
  </button>
169
191
 
170
- <!-- Settings Offcanvas Toggle -->
192
+ {% comment %} Settings Offcanvas Toggle {% endcomment %}
171
193
  <button
172
194
  class="btn nav-settings-button d-none d-lg-inline-flex"
173
195
  type="button"
@@ -180,7 +202,7 @@
180
202
  <i class="{{site.default_icon}} bi-gear" aria-hidden="true"></i>
181
203
  </button>
182
204
 
183
- <!-- Navigation Menu Toggle - Mobile view -->
205
+ {% comment %} Navigation Menu Toggle - Mobile view {% endcomment %}
184
206
  {%- if site.navigation.unified_mobile_drawer -%}
185
207
  {%- assign _menu_target = "#zer0UnifiedDrawer" -%}
186
208
  {%- assign _menu_controls = "zer0UnifiedDrawer" -%}
@@ -203,12 +225,12 @@
203
225
  </nav>
204
226
  </div>
205
227
 
206
- <!-- ========================== -->
207
- <!-- PROGRESS BAR MOUNT POINT -->
208
- <!-- ========================== -->
209
- <!-- Nanobar mounts here when site.nanobar.position == "navbar" so the bar
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
210
232
  renders as a thin strip directly under the header. For "top" / "bottom"
211
- 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 %}
212
234
  {%- assign _nb_pos = site.nanobar.position | default: "top" -%}
213
235
  {%- if site.nanobar.enabled != false and _nb_pos == "navbar" -%}
214
236
  <div id="top-progress-target" class="nanobar-mount" aria-hidden="true"></div>
@@ -1,6 +1,6 @@
1
- <!-- Style.html
1
+ {% comment %} Style.html
2
2
  _includes/style.html
3
- -->
3
+ {% endcomment %}
4
4
 
5
5
  <div class="bd-cheatsheet container-fluid">
6
6
  <section id="content">
@@ -933,7 +933,7 @@
933
933
  <li><a class="dropdown-item" href="#">Another action</a></li>
934
934
  <li><a class="dropdown-item" href="#">Something else here</a></li>
935
935
  </ul>
936
- </div><!-- /btn-group -->
936
+ </div>{% comment %} /btn-group {% endcomment %}
937
937
  <div class="btn-group">
938
938
  <button type="button" class="btn btn-secondary">Secondary</button>
939
939
  <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
@@ -944,7 +944,7 @@
944
944
  <li><a class="dropdown-item" href="#">Another action</a></li>
945
945
  <li><a class="dropdown-item" href="#">Something else here</a></li>
946
946
  </ul>
947
- </div><!-- /btn-group -->
947
+ </div>{% comment %} /btn-group {% endcomment %}
948
948
  <div class="btn-group">
949
949
  <button type="button" class="btn btn-success">Success</button>
950
950
  <button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
@@ -955,7 +955,7 @@
955
955
  <li><a class="dropdown-item" href="#">Another action</a></li>
956
956
  <li><a class="dropdown-item" href="#">Something else here</a></li>
957
957
  </ul>
958
- </div><!-- /btn-group -->example-divider
958
+ </div>{% comment %} /btn-group {% endcomment %}example-divider
959
959
  <div class="btn-group">
960
960
  <button type="button" class="btn btn-info">Info</button>
961
961
  <button type="button" class="btn btn-info dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
@@ -966,7 +966,7 @@
966
966
  <li><a class="dropdown-item" href="#">Another action</a></li>
967
967
  <li><a class="dropdown-item" href="#">Something else here</a></li>
968
968
  </ul>
969
- </div><!-- /btn-group -->
969
+ </div>{% comment %} /btn-group {% endcomment %}
970
970
  <div class="btn-group">
971
971
  <button type="button" class="btn btn-warning">Warning</button>
972
972
  <button type="button" class="btn btn-warning dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
@@ -977,7 +977,7 @@
977
977
  <li><a class="dropdown-item" href="#">Another action</a></li>
978
978
  <li><a class="dropdown-item" href="#">Something else here</a></li>
979
979
  </ul>
980
- </div><!-- /btn-group -->
980
+ </div>{% comment %} /btn-group {% endcomment %}
981
981
  <div class="btn-group">
982
982
  <button type="button" class="btn btn-danger">Danger</button>
983
983
  <button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
@@ -988,7 +988,7 @@
988
988
  <li><a class="dropdown-item" href="#">Another action</a></li>
989
989
  <li><a class="dropdown-item" href="#">Something else here</a></li>
990
990
  </ul>
991
- </div><!-- /btn-group -->
991
+ </div>{% comment %} /btn-group {% endcomment %}
992
992
  </div></div>
993
993
  <div class="bd-example-snippet bd-code-snippet"><div class="bd-example">
994
994
  <div class="btn-group w-100 align-items-center justify-content-between flex-wrap">
@@ -1,4 +1,4 @@
1
- <!-- Installation method cards; uses site.resources.* and environment where helpful -->
1
+ {% comment %} Installation method cards; uses site.resources.* and environment where helpful {% endcomment %}
2
2
  <div class="row g-4 justify-content-center">
3
3
  <div class="col-12 col-sm-10 col-md-6 col-lg-4">
4
4
  <div class="card h-100 border-0 shadow-sm">
@@ -55,7 +55,7 @@ cd &lt;you&gt;.github.io
55
55
  </div>
56
56
  </div>
57
57
 
58
- <!-- Contributing guide call-to-action placed below all cards -->
58
+ {% comment %} Contributing guide call-to-action placed below all cards {% endcomment %}
59
59
  <div class="text-center mt-4">
60
60
  <a class="btn btn-outline-secondary" href="{{ site.resources.contributing | default: '' | join: '' | default: '#' }}" target="_blank" rel="noopener">
61
61
  <i class="bi bi-journal-text me-2"></i>Read the Contributing Guide
@@ -1,4 +1,4 @@
1
- <!-- Quick Links bar for landing page; uses site.resources config -->
1
+ {% comment %} Quick Links bar for landing page; uses site.resources config {% endcomment %}
2
2
  <div class="bg-dark text-white py-3">
3
3
  <div class="container-xl px-4 px-md-5">
4
4
  <div class="row g-3 justify-content-center text-center align-items-center">
@@ -1,5 +1,5 @@
1
1
  {% comment %} Feature: ZER0-050 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  ===================================================================
4
4
  ADMIN NAV — Data-driven sidebar navigation for admin/settings pages
5
5
  ===================================================================
@@ -15,7 +15,7 @@
15
15
  _data/navigation/admin.yml
16
16
  Used by: _layouts/admin.html
17
17
  ===================================================================
18
- -->
18
+ {% endcomment %}
19
19
 
20
20
  {% assign current_path = page.url %}
21
21
  {% assign admin_items = site.data.navigation.admin %}