jekyll-theme-zer0 1.29.0 → 1.31.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 (163) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +886 -2
  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 +196 -22
  7. data/_data/consumers.yml +147 -5
  8. data/_data/features.yml +147 -21
  9. data/_data/feedback_types.yml +17 -12
  10. data/_data/landing.yml +5 -2
  11. data/_data/navigation/quickstart.yml +4 -0
  12. data/_data/site_builder.yml +874 -0
  13. data/_data/theme-manifest.yml +132 -122
  14. data/_data/ui-text.yml +19 -0
  15. data/_includes/README.md +11 -1
  16. data/_includes/analytics/posthog.html +30 -11
  17. data/_includes/components/README.md +1 -1
  18. data/_includes/components/admin-links.html +2 -2
  19. data/_includes/components/admin-tabs.html +2 -2
  20. data/_includes/components/ai-chat.html +14 -11
  21. data/_includes/components/analytics-dashboard.html +8 -8
  22. data/_includes/components/author-bio.html +1 -1
  23. data/_includes/components/author-card.html +10 -2
  24. data/_includes/components/author-eeat.html +4 -4
  25. data/_includes/components/background-customizer.html +8 -8
  26. data/_includes/components/background-image.html +120 -0
  27. data/_includes/components/background-settings.html +28 -15
  28. data/_includes/components/collection-manager.html +5 -5
  29. data/_includes/components/component-showcase.html +13 -13
  30. data/_includes/components/config-editor.html +12 -12
  31. data/_includes/components/config-viewer.html +8 -8
  32. data/_includes/components/cookie-consent.html +41 -41
  33. data/_includes/components/cta-button.html +7 -2
  34. data/_includes/components/dev-shortcuts.html +7 -7
  35. data/_includes/components/env-dashboard.html +8 -8
  36. data/_includes/components/env-switcher.html +9 -9
  37. data/_includes/components/feature-card.html +2 -2
  38. data/_includes/components/halfmoon.html +2 -2
  39. data/_includes/components/info-section.html +36 -36
  40. data/_includes/components/js-cdn.html +15 -15
  41. data/_includes/components/language-toggle.html +4 -4
  42. data/_includes/components/mermaid.html +79 -435
  43. data/_includes/components/nanobar.html +5 -5
  44. data/_includes/components/nav-editor.html +2 -2
  45. data/_includes/components/nav-export.html +2 -2
  46. data/_includes/components/nav-overview.html +2 -2
  47. data/_includes/components/page-feedback.html +45 -30
  48. data/_includes/components/page-views-init.html +1 -1
  49. data/_includes/components/post-card.html +22 -22
  50. data/_includes/components/post-type-badge.html +2 -2
  51. data/_includes/components/powered-by.html +2 -2
  52. data/_includes/components/preview-image.html +28 -3
  53. data/_includes/components/quick-index.html +2 -2
  54. data/_includes/components/search-modal.html +27 -2
  55. data/_includes/components/searchbar.html +2 -2
  56. data/_includes/components/svg-background.html +2 -2
  57. data/_includes/components/theme-customizer.html +2 -2
  58. data/_includes/components/theme-info.html +6 -6
  59. data/_includes/components/theme-preview-gallery.html +23 -23
  60. data/_includes/content/giscus.html +2 -2
  61. data/_includes/content/intro.html +15 -8
  62. data/_includes/content/jsonld-faq.html +2 -2
  63. data/_includes/content/jsonld-software.html +2 -2
  64. data/_includes/content/seo.html +12 -4
  65. data/_includes/content/sitemap.html +247 -290
  66. data/_includes/content/toc.html +183 -183
  67. data/_includes/core/branding.html +13 -20
  68. data/_includes/core/console-capture.html +32 -74
  69. data/_includes/core/favicon.html +49 -7
  70. data/_includes/core/footer-fabs.html +17 -3
  71. data/_includes/core/footer.html +31 -18
  72. data/_includes/core/head.html +128 -92
  73. data/_includes/core/header.html +85 -54
  74. data/_includes/core/tokens-inline.html +16 -1
  75. data/_includes/docs/bootstrap-docs.html +8 -8
  76. data/_includes/landing/landing-install-cards.html +2 -2
  77. data/_includes/landing/landing-quick-links.html +1 -1
  78. data/_includes/navigation/admin-nav.html +2 -2
  79. data/_includes/navigation/nav-tree.html +8 -8
  80. data/_includes/navigation/navbar.html +21 -18
  81. data/_includes/navigation/section-sidebar.html +16 -16
  82. data/_includes/navigation/sidebar-config.html +36 -2
  83. data/_includes/navigation/sidebar-left.html +15 -15
  84. data/_includes/navigation/sidebar-right.html +6 -6
  85. data/_includes/obsidian/full-graph.html +2 -2
  86. data/_includes/setup/claude-session.html +72 -0
  87. data/_includes/setup/prereq-checklist.html +90 -0
  88. data/_includes/setup/wizard.html +910 -291
  89. data/_includes/stats/stats-categories.html +8 -8
  90. data/_includes/stats/stats-header.html +14 -14
  91. data/_includes/stats/stats-metrics.html +12 -12
  92. data/_includes/stats/stats-no-data.html +12 -12
  93. data/_includes/stats/stats-overview.html +6 -6
  94. data/_includes/stats/stats-tags.html +8 -8
  95. data/_layouts/404.html +38 -24
  96. data/_layouts/admin.html +22 -22
  97. data/_layouts/article.html +54 -37
  98. data/_layouts/author.html +20 -20
  99. data/_layouts/authors.html +2 -2
  100. data/_layouts/book-abc.html +12 -12
  101. data/_layouts/book-story.html +15 -15
  102. data/_layouts/book.html +12 -12
  103. data/_layouts/collection.html +33 -33
  104. data/_layouts/cookbook.html +12 -12
  105. data/_layouts/default.html +27 -24
  106. data/_layouts/home.html +36 -24
  107. data/_layouts/index.html +10 -10
  108. data/_layouts/landing.html +17 -17
  109. data/_layouts/news.html +44 -44
  110. data/_layouts/note.html +40 -39
  111. data/_layouts/notebook.html +36 -35
  112. data/_layouts/recipe.html +24 -24
  113. data/_layouts/root.html +95 -55
  114. data/_layouts/section.html +23 -23
  115. data/_layouts/setup.html +3 -3
  116. data/_layouts/sitemap-collection.html +49 -49
  117. data/_layouts/stats.html +40 -40
  118. data/_layouts/tag.html +12 -12
  119. data/_layouts/welcome.html +21 -21
  120. data/_sass/components/_cookie-banner.scss +48 -0
  121. data/_sass/components/_mermaid.scss +375 -0
  122. data/_sass/components/_setup-wizard.scss +588 -41
  123. data/_sass/components/_ui-enhancements.scss +11 -0
  124. data/_sass/core/_navbar.scss +147 -100
  125. data/_sass/core/_sidebar-extras.scss +2 -14
  126. data/_sass/core/code-copy.scss +27 -8
  127. data/_sass/layouts/_navbar-extras.scss +14 -4
  128. data/assets/css/extension-points-demo.css +27 -0
  129. data/assets/css/main.scss +1 -0
  130. data/assets/data/wiki-index.json +19 -0
  131. data/assets/js/ai-chat.js +47 -5
  132. data/assets/js/auto-hide-nav.js +53 -13
  133. data/assets/js/code-copy.js +72 -1
  134. data/assets/js/extension-points-demo.js +48 -0
  135. data/assets/js/fleet-feedback-capture.js +124 -0
  136. data/assets/js/fleet-feedback.js +853 -0
  137. data/assets/js/mermaid-diagrams.js +1373 -0
  138. data/assets/js/modules/navigation/config.js +9 -6
  139. data/assets/js/modules/navigation/scroll-spy.js +315 -80
  140. data/assets/js/modules/theme/appearance.js +8 -2
  141. data/assets/js/obsidian-local-graph.js +27 -5
  142. data/assets/js/obsidian-wiki-links.js +8 -3
  143. data/assets/js/page-feedback.js +125 -192
  144. data/assets/js/search-modal.js +26 -0
  145. data/assets/js/setup-wizard.js +2119 -363
  146. data/assets/js/site-builder.js +1834 -0
  147. data/assets/js/ui-enhancements.js +11 -3
  148. data/scripts/README.md +15 -0
  149. data/scripts/ai/README.md +38 -0
  150. data/scripts/ai/api_call.rb +124 -0
  151. data/scripts/ai/usage.rb +314 -0
  152. data/scripts/ai/usage_report.rb +225 -0
  153. data/scripts/ci/test_visual_evidence_autogen.py +403 -0
  154. data/scripts/ci/visual_evidence_autogen.py +1070 -0
  155. data/scripts/content-review.rb +20 -1
  156. data/scripts/features/install-preview-generator +1 -1
  157. data/scripts/lib/README.md +12 -0
  158. data/scripts/lib/preview_generator.py +2 -2
  159. data/scripts/test/integration/mermaid +22 -8
  160. data/scripts/test/lib/run_tests.sh +1 -0
  161. data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
  162. data/scripts/translate.rb +23 -1
  163. metadata +21 -2
data/_layouts/recipe.html CHANGED
@@ -31,9 +31,9 @@ layout: default
31
31
 
32
32
  <article class="recipe" data-recipe data-recipe-id="{{ _rl_id }}">
33
33
 
34
- <!-- ================================ -->
35
- <!-- HEADER -->
36
- <!-- ================================ -->
34
+ {% comment %} ================================ {% endcomment %}
35
+ {% comment %} HEADER {% endcomment %}
36
+ {% comment %} ================================ {% endcomment %}
37
37
  <header class="recipe-header">
38
38
  {%- if _rl_cookbook or _rl_course_meta -%}
39
39
  <p class="recipe-eyebrow">
@@ -73,9 +73,9 @@ layout: default
73
73
  {%- endif -%}
74
74
  </header>
75
75
 
76
- <!-- ================================ -->
77
- <!-- HEADNOTE (the markdown body) -->
78
- <!-- ================================ -->
76
+ {% comment %} ================================ {% endcomment %}
77
+ {% comment %} HEADNOTE (the markdown body) {% endcomment %}
78
+ {% comment %} ================================ {% endcomment %}
79
79
  {%- assign _rl_body = content | strip -%}
80
80
  {%- if _rl_body != "" -%}
81
81
  <div class="recipe-headnote">
@@ -83,9 +83,9 @@ layout: default
83
83
  </div>
84
84
  {%- endif -%}
85
85
 
86
- <!-- ================================ -->
87
- <!-- FACT BAR + SCALER -->
88
- <!-- ================================ -->
86
+ {% comment %} ================================ {% endcomment %}
87
+ {% comment %} FACT BAR + SCALER {% endcomment %}
88
+ {% comment %} ================================ {% endcomment %}
89
89
  {%- include components/recipe-meta.html -%}
90
90
 
91
91
  {%- if _rl_show_scaler -%}
@@ -98,9 +98,9 @@ layout: default
98
98
  </noscript>
99
99
  {%- endif -%}
100
100
 
101
- <!-- ================================ -->
102
- <!-- INGREDIENTS + METHOD -->
103
- <!-- ================================ -->
101
+ {% comment %} ================================ {% endcomment %}
102
+ {% comment %} INGREDIENTS + METHOD {% endcomment %}
103
+ {% comment %} ================================ {% endcomment %}
104
104
  <div class="row g-4 g-lg-5 recipe-body">
105
105
  <div class="col-lg-5">
106
106
  {%- include components/recipe-ingredients.html id_prefix=_rl_id -%}
@@ -124,14 +124,14 @@ layout: default
124
124
  </div>
125
125
  </div>
126
126
 
127
- <!-- ================================ -->
128
- <!-- RATIO / FORMULA -->
129
- <!-- ================================ -->
127
+ {% comment %} ================================ {% endcomment %}
128
+ {% comment %} RATIO / FORMULA {% endcomment %}
129
+ {% comment %} ================================ {% endcomment %}
130
130
  {%- include components/recipe-ratio.html -%}
131
131
 
132
- <!-- ================================ -->
133
- <!-- NOTES -->
134
- <!-- ================================ -->
132
+ {% comment %} ================================ {% endcomment %}
133
+ {% comment %} NOTES {% endcomment %}
134
+ {% comment %} ================================ {% endcomment %}
135
135
  {%- if page.notes and page.notes.size > 0 -%}
136
136
  <section class="recipe-notes">
137
137
  <h2 class="recipe-section-heading">
@@ -145,14 +145,14 @@ layout: default
145
145
  </section>
146
146
  {%- endif -%}
147
147
 
148
- <!-- ================================ -->
149
- <!-- NUTRITION -->
150
- <!-- ================================ -->
148
+ {% comment %} ================================ {% endcomment %}
149
+ {% comment %} NUTRITION {% endcomment %}
150
+ {% comment %} ================================ {% endcomment %}
151
151
  {%- include components/recipe-nutrition.html -%}
152
152
 
153
- <!-- ================================ -->
154
- <!-- COMMENTS -->
155
- <!-- ================================ -->
153
+ {% comment %} ================================ {% endcomment %}
154
+ {% comment %} COMMENTS {% endcomment %}
155
+ {% comment %} ================================ {% endcomment %}
156
156
  {%- if page.comments and site.giscus.enabled -%}
157
157
  <section class="post-comments mt-5 pt-4 border-top" id="comments">
158
158
  <h2 class="h4 mb-4"><i class="bi bi-chat-dots me-2" aria-hidden="true"></i>Comments</h2>
data/_layouts/root.html CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  # Features: ZER0-001, ZER0-019, ZER0-031, ZER0-060
3
3
  ---
4
- <!--
4
+ {% comment %}
5
5
  ===================================================================
6
6
  ROOT LAYOUT - Base template for the Zer0 Mistakes Jekyll Theme
7
7
  ===================================================================
@@ -29,7 +29,7 @@
29
29
  Author: Amr Abdel-Motaleb
30
30
  Copyright: 2024 - it-journey.com | @bamr87
31
31
  ===================================================================
32
- -->
32
+ {% endcomment %}
33
33
 
34
34
  <!doctype html>
35
35
  {%- comment -%}
@@ -48,7 +48,20 @@
48
48
  {%- endif -%}
49
49
  <html lang="{{ page.lang | default: site.locale | slice: 0, 2 | default: 'en' }}" class="no-js" data-bs-theme="{{ _bs_theme }}" data-color-mode-default="{{ _cm }}" data-color-mode-lock="{{ site.color_mode_lock | default: false }}" data-theme-skin="{{ site.theme_skin | default: 'air' }}" data-zer0-bg="{{ site.theme_background.enabled | default: true }}">
50
50
  <head>
51
- <!-- Progressive-enhancement hook: upgrade <html class="no-js"> to "js".
51
+ {%- comment -%} Character encoding MUST be the first thing in <head>: the HTML spec
52
+ only looks for it in the first 1024 bytes of the document, and
53
+ everything below (the no-js note, core/head.html's own banner,
54
+ Google Tag Manager, console-capture, page-views, mermaid, nanobar)
55
+ pushed it to byte ~4415 (issue #372). Past the limit the browser
56
+ stops looking and falls back to its locale default, mis-decoding
57
+ every non-ASCII byte until it re-parses — and this theme ships
58
+ UTF-8 throughout (fr/** translations, em-dashes, curly quotes).
59
+ It sits here rather than in core/head.html because that include is
60
+ not, and cannot be, the first thing in <head>.
61
+ Keep it first. Nothing may be emitted above it. {%- endcomment -%}
62
+ <meta charset="utf-8">
63
+
64
+ {% comment %} Progressive-enhancement hook: upgrade <html class="no-js"> to "js".
52
65
  MUST be the first child of <head>, inline, and neither `defer` nor
53
66
  `async` — it has to run before the first stylesheet is fetched or
54
67
  `html.js` rules would flash. It cannot live in core/head.html:
@@ -56,65 +69,70 @@
56
69
  "first in that include" is not "first in <head>".
57
70
  classList.replace() is a no-op when `no-js` is absent, so this is
58
71
  safe unconditionally. The served HTML keeps `no-js` on <html> so
59
- the JS-disabled branch stays correct. -->
72
+ the JS-disabled branch stays correct. {% endcomment %}
60
73
  <script>document.documentElement.classList.replace("no-js", "js");</script>
61
74
 
62
- <!-- =============================================== -->
63
- <!-- HEAD SECTION: Meta tags, styles, and SEO setup -->
64
- <!-- =============================================== -->
75
+ {% comment %} =============================================== {% endcomment %}
76
+ {% comment %} HEAD SECTION: Meta tags, styles, and SEO setup {% endcomment %}
77
+ {% comment %} =============================================== {% endcomment %}
65
78
 
66
- <!-- Core site metadata, stylesheets, and external dependencies -->
79
+ {% comment %} Core site metadata, stylesheets, and external dependencies {% endcomment %}
67
80
  {% include core/head.html %}
68
81
 
69
- <!-- Jekyll SEO plugin for enhanced search engine optimization -->
70
- <!-- Documentation: https://github.com/jekyll/jekyll-seo-tag -->
82
+ {% comment %} Jekyll SEO plugin for enhanced search engine optimization {% endcomment %}
83
+ {% comment %} Documentation: https://github.com/jekyll/jekyll-seo-tag {% endcomment %}
71
84
  {% seo %}
72
85
 
73
- <!-- fffuel-style SVG background config overrides -->
86
+ {% comment %} fffuel-style SVG background config overrides {% endcomment %}
74
87
  {% include components/svg-background.html zone="body" %}
75
88
  </head>
76
89
 
77
- <body class="zer0-bg-body" data-bs-spy="scroll" data-bs-target="#TableOfContents">
78
- <!-- ============================================== -->
79
- <!-- BODY SECTION: Site structure and content area -->
80
- <!-- ============================================== -->
81
-
82
- <!-- Consumer hook: first thing inside <body> (e.g. GTM noscript).
83
- Empty stub shipped by the theme; shadow _includes/custom/body-start.html to use. -->
90
+ {% comment %} No `data-bs-spy` here: the theme's own scroll spy
91
+ (assets/js/modules/navigation/scroll-spy.js) owns TOC highlighting.
92
+ Bootstrap's native ScrollSpy competed with it for the `.active` class
93
+ on `#TableOfContents a` (making the bolding jump), and also stripped
94
+ server-rendered `.active` classes off sidebar nav links. {% endcomment %}
95
+ <body class="zer0-bg-body">
96
+ {% comment %} ============================================== {% endcomment %}
97
+ {% comment %} BODY SECTION: Site structure and content area {% endcomment %}
98
+ {% comment %} ============================================== {% endcomment %}
99
+
100
+ {% comment %} Consumer hook: first thing inside <body> (e.g. GTM noscript).
101
+ Empty stub shipped by the theme; shadow _includes/custom/body-start.html to use. {% endcomment %}
84
102
  {% include custom/body-start.html %}
85
103
 
86
- <!-- Inline SVG symbols for consistent iconography throughout the site -->
87
- <!-- Page-invariant: cached once per build via jekyll-include-cache. -->
104
+ {% comment %} Inline SVG symbols for consistent iconography throughout the site {% endcomment %}
105
+ {% comment %} Page-invariant: cached once per build via jekyll-include-cache. {% endcomment %}
88
106
  {% include_cached components/svg.html %}
89
107
 
90
- <!-- Google Tag Manager body code for analytics (if configured) -->
91
- <!-- Note: Currently commented out - uncomment when GTM is needed -->
108
+ {% comment %} Google Tag Manager body code for analytics (if configured) {% endcomment %}
109
+ {% comment %} Note: Currently commented out - uncomment when GTM is needed {% endcomment %}
92
110
 
93
- <!-- Main site header with navigation, branding, and search functionality -->
111
+ {% comment %} Main site header with navigation, branding, and search functionality {% endcomment %}
94
112
  {% include core/header.html %}
95
113
 
96
- <!-- Optional unified mobile drawer (Browse / Menu / Settings tabs).
97
- Enable with `navigation.unified_mobile_drawer: true` in _config.yml. -->
114
+ {% comment %} Optional unified mobile drawer (Browse / Menu / Settings tabs).
115
+ Enable with `navigation.unified_mobile_drawer: true` in _config.yml. {% endcomment %}
98
116
  {% include navigation/unified-drawer.html %}
99
117
 
100
- <!-- Search modal (site-wide) — cached once per build PER LANGUAGE
118
+ {% comment %} Search modal (site-wide) — cached once per build PER LANGUAGE
101
119
  (the lang param keys the include-cache entry; page.lang is nil
102
- on English pages, so they all still share a single render). -->
120
+ on English pages, so they all still share a single render). {% endcomment %}
103
121
  {% include_cached components/search-modal.html lang=page.lang %}
104
122
 
105
- <!-- Keyboard shortcuts help modal (triggered by `?`) — cached per language. -->
123
+ {% comment %} Keyboard shortcuts help modal (triggered by `?`) — cached per language. {% endcomment %}
106
124
  {% include_cached components/shortcuts-modal.html lang=page.lang %}
107
125
 
108
- <!-- Settings offcanvas (Appearance / Site / Developer tabs) -->
126
+ {% comment %} Settings offcanvas (Appearance / Site / Developer tabs) {% endcomment %}
109
127
  {% include components/info-section.html %}
110
128
 
111
- <!-- Setup banner for unconfigured sites — page-invariant. -->
129
+ {% comment %} Setup banner for unconfigured sites — page-invariant. {% endcomment %}
112
130
  {% include_cached components/setup-banner.html %}
113
131
 
114
- <!-- ======================== -->
115
- <!-- MAIN CONTENT AREA -->
116
- <!-- ======================== -->
117
- <!-- Skip-link target: keep a single, consistent #main-content anchor site-wide.
132
+ {% comment %} ======================== {% endcomment %}
133
+ {% comment %} MAIN CONTENT AREA {% endcomment %}
134
+ {% comment %} ======================== {% endcomment %}
135
+ {% comment %} Skip-link target: keep a single, consistent #main-content anchor site-wide.
118
136
  This is the ONE <main> landmark per page — child layouts (default/section/
119
137
  news) must use non-landmark wrappers (<div>) inside it (issue #299) — so
120
138
  assistive tech, search engines, and AI content extractors can isolate the
@@ -126,60 +144,82 @@
126
144
  the next Tab returns the user to the header nav they just skipped
127
145
  (WCAG 2.4.1 Bypass Blocks). -1 keeps it out of the sequential Tab order
128
146
  while allowing programmatic focus. The focus ring it would otherwise
129
- paint is suppressed in _sass/utilities/_focus.scss. -->
147
+ paint is suppressed in _sass/utilities/_focus.scss. {% endcomment %}
130
148
  <main id="main-content" tabindex="-1">
131
- <!-- Machine-translation disclosure — renders only on generated
132
- translations (page.machine_translated); no-op elsewhere. -->
149
+ {% comment %} Machine-translation disclosure — renders only on generated
150
+ translations (page.machine_translated); no-op elsewhere. {% endcomment %}
133
151
  {%- include components/translation-notice.html -%}
134
152
  {{ content }}
135
153
  </main>
136
154
 
137
- <!-- ======================== -->
138
- <!-- FOOTER AND SCRIPTS -->
139
- <!-- ======================== -->
155
+ {% comment %} ======================== {% endcomment %}
156
+ {% comment %} FOOTER AND SCRIPTS {% endcomment %}
157
+ {% comment %} ======================== {% endcomment %}
140
158
 
141
- <!-- Site footer with links, copyright, and additional navigation.
159
+ {% comment %} Site footer with links, copyright, and additional navigation.
142
160
  Page-invariant chrome is cached once per build; the page-dependent
143
161
  FAB/local-graph tail renders fresh per page (see core/footer-fabs.html).
144
162
  Build-time values inside (e.g. the copyright year from site.time) stay
145
163
  fresh: jekyll-include-cache stores in memory only (Jekyll 3.x has no
146
164
  Jekyll::Cache) and clears on every build's :pre_render hook — it never
147
- persists to .jekyll-cache. -->
165
+ persists to .jekyll-cache. {% endcomment %}
148
166
  {%- include_cached core/footer.html lang=page.lang -%}
149
167
  {%- include core/footer-fabs.html -%}
150
168
 
151
- <!-- Consumer hook: after the theme footer, before the consent banner.
169
+ {% comment %} Consumer hook: after the theme footer, before the consent banner.
152
170
  Empty stub shipped by the theme; shadow _includes/custom/footer.html to use.
153
171
  Deliberately OUTSIDE the cached footer include so page-dependent
154
- consumer markup renders per page. -->
172
+ consumer markup renders per page. {% endcomment %}
155
173
  {%- include custom/footer.html -%}
156
174
 
157
- <!-- Privacy-compliant cookie consent banner — page-invariant. -->
175
+ {% comment %} Privacy-compliant cookie consent banner — page-invariant. {% endcomment %}
158
176
  {%- include_cached components/cookie-consent.html -%}
159
177
 
160
- <!-- AI Chat Assistant -->
178
+ {% comment %} AI Chat Assistant {% endcomment %}
161
179
  {%- include components/ai-chat.html -%}
162
180
 
163
- <!-- Page-feedback capture widget ("Improve this page" → GitHub issue) -->
181
+ {% comment %} Page-feedback capture widget ("Improve this page" → GitHub issue) {% endcomment %}
164
182
  {%- include components/page-feedback.html -%}
165
183
 
166
- <!-- JavaScript dependencies and custom scripts -->
184
+ {% comment %} JavaScript dependencies and custom scripts {% endcomment %}
167
185
  <div>
168
- <!-- Search functionality -->
169
- <!-- Note: Currently commented out - uncomment when search is implemented -->
186
+ {% comment %} Search functionality {% endcomment %}
187
+ {% comment %} Note: Currently commented out - uncomment when search is implemented {% endcomment %}
170
188
 
171
- <!-- External JavaScript libraries and custom scripts — page-invariant.
189
+ {% comment %} External JavaScript libraries and custom scripts — page-invariant.
172
190
  The "?v=" cache-buster (site.time) in js-cdn.html stays correct:
173
191
  the include cache is in-memory and reset every build (see footer
174
- note above), so v= advances on each build, never frozen across deploys. -->
192
+ note above), so v= advances on each build, never frozen across deploys. {% endcomment %}
175
193
  {% include_cached components/js-cdn.html %}
176
194
  </div>
177
195
 
178
- <!-- Analytics Integration -->
196
+ {% comment %} Per-page scripts from frontmatter (#412):
197
+
198
+ ---
199
+ scripts:
200
+ - /assets/js/notes-clipper.js
201
+ ---
202
+
203
+ The counterpart of `styles:` in _includes/core/head.html, loaded here
204
+ so a page script runs AFTER the theme's own bundle (js-cdn.html) and
205
+ can rely on the contracts it publishes — `zer0:code-block-ready`, for
206
+ one. Deferred, so it never blocks the parse. A single string is
207
+ accepted as well as a list; site-relative paths go through
208
+ relative_url, absolute URLs pass through untouched.
209
+
210
+ Emits NOTHING when the key is absent, so a page without `scripts:`
211
+ is byte-identical to its previous build — hence the `-%}` on both
212
+ the comment and the `endif`. {% endcomment -%}
213
+ {% if page.scripts %}{% assign page_scripts = page.scripts %}{% if page_scripts.first == nil %}{% assign page_scripts = page_scripts | split: "||" %}{% endif %}{% for script_src in page_scripts %}
214
+ <script defer src="{% if script_src contains '//' %}{{ script_src }}{% else %}{{ script_src | relative_url }}{% endif %}"></script>
215
+ {%- endfor %}
216
+ {% endif -%}
217
+
218
+ {% comment %} Analytics Integration {% endcomment %}
179
219
  {%- include analytics/posthog.html -%}
180
220
 
181
- <!-- Consumer hook: last thing before </body> (site scripts, widgets).
182
- Empty stub shipped by the theme; shadow _includes/custom/body-end.html to use. -->
221
+ {% comment %} Consumer hook: last thing before </body> (site scripts, widgets).
222
+ Empty stub shipped by the theme; shadow _includes/custom/body-end.html to use. {% endcomment %}
183
223
  {%- include custom/body-end.html -%}
184
224
  </body>
185
225
  </html>
@@ -2,7 +2,7 @@
2
2
  # Features: ZER0-019, ZER0-063
3
3
  layout: root
4
4
  ---
5
- <!--
5
+ {% comment %}
6
6
  ===================================================================
7
7
  SECTION LAYOUT - News Section with Collapsible Sub-Category Sidebar
8
8
  ===================================================================
@@ -40,7 +40,7 @@ layout: root
40
40
  - Bootstrap 5 grid, card, and offcanvas components
41
41
  - Bootstrap Icons
42
42
  ===================================================================
43
- -->
43
+ {% endcomment %}
44
44
 
45
45
  {% comment %} ================================ {% endcomment %}
46
46
  {% comment %} SECTION DISCOVERY LOGIC {% endcomment %}
@@ -112,9 +112,9 @@ layout: root
112
112
  {% endfor %}
113
113
  {% assign sub_categories = sub_categories | sort %}
114
114
 
115
- <!-- ================================ -->
116
- <!-- SECTION HEADER -->
117
- <!-- ================================ -->
115
+ {% comment %} ================================ {% endcomment %}
116
+ {% comment %} SECTION HEADER {% endcomment %}
117
+ {% comment %} ================================ {% endcomment %}
118
118
  <div class="container-fluid bg-dark text-white py-3 mb-0">
119
119
  <div class="container-fluid px-4">
120
120
  <div class="row align-items-center">
@@ -147,7 +147,7 @@ layout: root
147
147
  </div>
148
148
  </div>
149
149
 
150
- <!-- Sub-navigation for other sections -->
150
+ {% comment %} Sub-navigation for other sections {% endcomment %}
151
151
  <div class="container-fluid bg-body-tertiary border-bottom py-2 mb-4">
152
152
  <div class="container-fluid px-4">
153
153
  <nav class="nav nav-pills flex-nowrap overflow-auto" style="scrollbar-width: none;">
@@ -175,9 +175,9 @@ layout: root
175
175
  <div class="container-fluid px-4">
176
176
  <div class="row g-lg-4 section-layout">
177
177
 
178
- <!-- ================================ -->
179
- <!-- FIXED SIDEBAR COMPONENT -->
180
- <!-- ================================ -->
178
+ {% comment %} ================================ {% endcomment %}
179
+ {% comment %} FIXED SIDEBAR COMPONENT {% endcomment %}
180
+ {% comment %} ================================ {% endcomment %}
181
181
  <div class="col-lg-3 col-xl-2 section-layout-sidebar">
182
182
  {% include navigation/section-sidebar.html
183
183
  section_posts=section_posts
@@ -188,14 +188,14 @@ layout: root
188
188
  %}
189
189
  </div>
190
190
 
191
- <!-- ================================ -->
192
- <!-- MAIN CONTENT AREA -->
193
- <!-- ================================ -->
194
- <!-- Not a <main>: root.html already provides the single <main id="main-content">
195
- landmark; a nested <main> here would duplicate it (issue #299). -->
191
+ {% comment %} ================================ {% endcomment %}
192
+ {% comment %} MAIN CONTENT AREA {% endcomment %}
193
+ {% comment %} ================================ {% endcomment %}
194
+ {% comment %} Not a <main>: root.html already provides the single <main id="main-content">
195
+ landmark; a nested <main> here would duplicate it (issue #299). {% endcomment %}
196
196
  <div class="col-lg-9 col-xl-10 section-layout-main">
197
197
 
198
- <!-- Section Header -->
198
+ {% comment %} Section Header {% endcomment %}
199
199
  <header class="section-header mb-4">
200
200
  <div class="d-flex align-items-center mb-3">
201
201
  {% if page.icon %}
@@ -223,7 +223,7 @@ layout: root
223
223
  {% comment %} ================================ {% endcomment %}
224
224
  {% if section_style == "magazine" %}
225
225
 
226
- <!-- Hero Section -->
226
+ {% comment %} Hero Section {% endcomment %}
227
227
  {% assign featured_in_section = section_posts | where: "featured", true | first %}
228
228
  {% unless featured_in_section %}
229
229
  {% assign featured_in_section = section_posts | first %}
@@ -274,7 +274,7 @@ layout: root
274
274
  </div>
275
275
  </section>
276
276
 
277
- <!-- Sub-Category Sections -->
277
+ {% comment %} Sub-Category Sections {% endcomment %}
278
278
  {% for subcat in sub_categories limit: 5 %}
279
279
  {% assign subcat_posts = section_posts | where_exp: "post", "post.tags contains subcat" %}
280
280
  {% assign subcat_posts_filtered = "" | split: "" %}
@@ -340,7 +340,7 @@ layout: root
340
340
  {% endif %}
341
341
  {% endfor %}
342
342
 
343
- <!-- All Posts Section -->
343
+ {% comment %} All Posts Section {% endcomment %}
344
344
  <section id="all-posts" class="all-posts-section mb-5 scroll-mt-5">
345
345
  <div class="d-flex justify-content-between align-items-center mb-4">
346
346
  <h3 class="h4 mb-0">
@@ -404,7 +404,7 @@ layout: root
404
404
  {% comment %} ================================ {% endcomment %}
405
405
  {% elsif section_style == "grid" %}
406
406
 
407
- <!-- Topic Filter Pills -->
407
+ {% comment %} Topic Filter Pills {% endcomment %}
408
408
  <div class="topic-filters mb-4">
409
409
  <div class="d-flex flex-wrap gap-2 align-items-center">
410
410
  <span class="text-muted me-2">Filter:</span>
@@ -540,7 +540,7 @@ layout: root
540
540
  {% endif %}
541
541
 
542
542
  {% else %}
543
- <!-- Empty state -->
543
+ {% comment %} Empty state {% endcomment %}
544
544
  <div class="text-center py-5">
545
545
  <i class="bi bi-inbox fs-1 text-muted"></i>
546
546
  <p class="text-muted mt-3">No articles in this section yet.</p>
@@ -550,9 +550,9 @@ layout: root
550
550
  </div>
551
551
  {% endif %}
552
552
 
553
- <!-- ========================== -->
554
- <!-- RELATED SECTIONS -->
555
- <!-- ========================== -->
553
+ {% comment %} ========================== {% endcomment %}
554
+ {% comment %} RELATED SECTIONS {% endcomment %}
555
+ {% comment %} ========================== {% endcomment %}
556
556
  <aside class="related-sections mt-5 pt-4 border-top">
557
557
  <h3 class="h5 mb-3">
558
558
  <i class="bi bi-compass me-2"></i>Explore Other Sections
data/_layouts/setup.html CHANGED
@@ -2,7 +2,7 @@
2
2
  # Features: ZER0-019, ZER0-067
3
3
  layout: root
4
4
  ---
5
- <!--
5
+ {% comment %}
6
6
  ===================================================================
7
7
  SETUP LAYOUT - Onboarding and configuration pages
8
8
  ===================================================================
@@ -24,7 +24,7 @@ layout: root
24
24
  setup_step: 2 # optional, highlights step in progress bar
25
25
  setup_total: 4 # optional, total number of steps
26
26
  ===================================================================
27
- -->
27
+ {% endcomment %}
28
28
 
29
29
  {% include components/setup-check.html %}
30
30
 
@@ -45,7 +45,7 @@ layout: root
45
45
  {% endif %}
46
46
 
47
47
  {% if page.setup_step and page.setup_total %}
48
- <!-- Progress indicator -->
48
+ {% comment %} Progress indicator {% endcomment %}
49
49
  <div class="mb-4">
50
50
  <div class="d-flex justify-content-between small text-body-secondary mb-1">
51
51
  <span>Step {{ page.setup_step }} of {{ page.setup_total }}</span>