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.
Files changed (148) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +715 -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 +169 -18
  7. data/_data/consumers.yml +48 -5
  8. data/_data/features.yml +146 -20
  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 +122 -114
  14. data/_data/ui-text.yml +18 -0
  15. data/_includes/README.md +11 -1
  16. data/_includes/analytics/posthog.html +2 -2
  17. data/_includes/components/admin-links.html +2 -2
  18. data/_includes/components/admin-tabs.html +2 -2
  19. data/_includes/components/ai-chat.html +14 -11
  20. data/_includes/components/analytics-dashboard.html +8 -8
  21. data/_includes/components/author-bio.html +1 -1
  22. data/_includes/components/author-card.html +10 -2
  23. data/_includes/components/author-eeat.html +4 -4
  24. data/_includes/components/background-customizer.html +8 -8
  25. data/_includes/components/background-image.html +114 -0
  26. data/_includes/components/background-settings.html +28 -15
  27. data/_includes/components/collection-manager.html +5 -5
  28. data/_includes/components/component-showcase.html +13 -13
  29. data/_includes/components/config-editor.html +12 -12
  30. data/_includes/components/config-viewer.html +8 -8
  31. data/_includes/components/cookie-consent.html +11 -11
  32. data/_includes/components/cta-button.html +7 -2
  33. data/_includes/components/dev-shortcuts.html +7 -7
  34. data/_includes/components/env-dashboard.html +8 -8
  35. data/_includes/components/env-switcher.html +9 -9
  36. data/_includes/components/feature-card.html +2 -2
  37. data/_includes/components/halfmoon.html +2 -2
  38. data/_includes/components/info-section.html +36 -36
  39. data/_includes/components/js-cdn.html +15 -15
  40. data/_includes/components/language-toggle.html +4 -4
  41. data/_includes/components/mermaid.html +72 -435
  42. data/_includes/components/nanobar.html +5 -5
  43. data/_includes/components/nav-editor.html +2 -2
  44. data/_includes/components/nav-export.html +2 -2
  45. data/_includes/components/nav-overview.html +2 -2
  46. data/_includes/components/page-feedback.html +45 -30
  47. data/_includes/components/page-views-init.html +1 -1
  48. data/_includes/components/post-card.html +22 -22
  49. data/_includes/components/post-type-badge.html +2 -2
  50. data/_includes/components/powered-by.html +2 -2
  51. data/_includes/components/preview-image.html +6 -0
  52. data/_includes/components/quick-index.html +2 -2
  53. data/_includes/components/search-modal.html +27 -2
  54. data/_includes/components/searchbar.html +2 -2
  55. data/_includes/components/svg-background.html +2 -2
  56. data/_includes/components/theme-customizer.html +2 -2
  57. data/_includes/components/theme-info.html +6 -6
  58. data/_includes/components/theme-preview-gallery.html +22 -22
  59. data/_includes/content/giscus.html +2 -2
  60. data/_includes/content/intro.html +8 -8
  61. data/_includes/content/jsonld-faq.html +2 -2
  62. data/_includes/content/jsonld-software.html +2 -2
  63. data/_includes/content/seo.html +4 -4
  64. data/_includes/content/sitemap.html +27 -27
  65. data/_includes/content/toc.html +183 -183
  66. data/_includes/core/branding.html +6 -6
  67. data/_includes/core/console-capture.html +32 -74
  68. data/_includes/core/favicon.html +49 -7
  69. data/_includes/core/footer-fabs.html +17 -3
  70. data/_includes/core/footer.html +31 -18
  71. data/_includes/core/head.html +102 -90
  72. data/_includes/core/header.html +71 -52
  73. data/_includes/docs/bootstrap-docs.html +8 -8
  74. data/_includes/landing/landing-install-cards.html +2 -2
  75. data/_includes/landing/landing-quick-links.html +1 -1
  76. data/_includes/navigation/admin-nav.html +2 -2
  77. data/_includes/navigation/nav-tree.html +8 -8
  78. data/_includes/navigation/navbar.html +12 -12
  79. data/_includes/navigation/section-sidebar.html +16 -16
  80. data/_includes/navigation/sidebar-config.html +36 -2
  81. data/_includes/navigation/sidebar-left.html +15 -15
  82. data/_includes/navigation/sidebar-right.html +6 -6
  83. data/_includes/obsidian/full-graph.html +2 -2
  84. data/_includes/setup/claude-session.html +72 -0
  85. data/_includes/setup/prereq-checklist.html +90 -0
  86. data/_includes/setup/wizard.html +906 -291
  87. data/_includes/stats/stats-categories.html +8 -8
  88. data/_includes/stats/stats-header.html +14 -14
  89. data/_includes/stats/stats-metrics.html +12 -12
  90. data/_includes/stats/stats-no-data.html +12 -12
  91. data/_includes/stats/stats-overview.html +6 -6
  92. data/_includes/stats/stats-tags.html +8 -8
  93. data/_layouts/404.html +38 -24
  94. data/_layouts/admin.html +22 -22
  95. data/_layouts/article.html +39 -34
  96. data/_layouts/author.html +20 -20
  97. data/_layouts/authors.html +2 -2
  98. data/_layouts/book-abc.html +12 -12
  99. data/_layouts/book-story.html +15 -15
  100. data/_layouts/book.html +12 -12
  101. data/_layouts/collection.html +33 -33
  102. data/_layouts/cookbook.html +12 -12
  103. data/_layouts/default.html +27 -24
  104. data/_layouts/home.html +23 -23
  105. data/_layouts/index.html +10 -10
  106. data/_layouts/landing.html +17 -17
  107. data/_layouts/news.html +44 -44
  108. data/_layouts/note.html +38 -38
  109. data/_layouts/notebook.html +34 -34
  110. data/_layouts/recipe.html +24 -24
  111. data/_layouts/root.html +73 -55
  112. data/_layouts/section.html +23 -23
  113. data/_layouts/setup.html +3 -3
  114. data/_layouts/sitemap-collection.html +49 -49
  115. data/_layouts/stats.html +40 -40
  116. data/_layouts/tag.html +12 -12
  117. data/_layouts/welcome.html +21 -21
  118. data/_sass/components/_mermaid.scss +375 -0
  119. data/_sass/components/_setup-wizard.scss +569 -40
  120. data/_sass/core/_navbar.scss +11 -31
  121. data/_sass/layouts/_navbar-extras.scss +14 -4
  122. data/assets/css/main.scss +1 -0
  123. data/assets/js/ai-chat.js +47 -5
  124. data/assets/js/fleet-feedback-capture.js +124 -0
  125. data/assets/js/fleet-feedback.js +853 -0
  126. data/assets/js/mermaid-diagrams.js +1267 -0
  127. data/assets/js/modules/navigation/config.js +9 -6
  128. data/assets/js/modules/navigation/scroll-spy.js +315 -80
  129. data/assets/js/modules/theme/appearance.js +8 -2
  130. data/assets/js/obsidian-wiki-links.js +8 -3
  131. data/assets/js/page-feedback.js +125 -192
  132. data/assets/js/search-modal.js +26 -0
  133. data/assets/js/setup-wizard.js +2112 -361
  134. data/assets/js/site-builder.js +1834 -0
  135. data/assets/js/ui-enhancements.js +11 -3
  136. data/scripts/README.md +15 -0
  137. data/scripts/ai/README.md +38 -0
  138. data/scripts/ai/api_call.rb +124 -0
  139. data/scripts/ai/usage.rb +314 -0
  140. data/scripts/ai/usage_report.rb +225 -0
  141. data/scripts/ci/test_visual_evidence_autogen.py +341 -0
  142. data/scripts/ci/visual_evidence_autogen.py +1060 -0
  143. data/scripts/content-review.rb +20 -1
  144. data/scripts/test/integration/mermaid +22 -8
  145. data/scripts/test/lib/run_tests.sh +1 -0
  146. data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
  147. data/scripts/translate.rb +23 -1
  148. metadata +19 -2
@@ -61,24 +61,34 @@
61
61
  {%- assign pf_theme = site.theme | default: site.remote_theme | default: "" -%}
62
62
 
63
63
  {%- if pf_show_fab -%}
64
- <!-- Global feedback FAB (page-invariant; opens the modal) -->
65
- <button type="button"
66
- id="pageFeedbackFab"
67
- class="pf-fab btn shadow-lg position-fixed"
68
- data-pf-open
69
- aria-haspopup="dialog"
70
- aria-controls="pageFeedbackModal"
71
- title="{{ site.page_feedback.fab_label | default: 'Improve this page' | escape }}"
72
- aria-label="{{ site.page_feedback.fab_label | default: 'Improve this page' | escape }}">
64
+ {% comment %} Global feedback FAB (page-invariant; opens the modal) {% endcomment %}
65
+ {%- comment -%}
66
+ An anchor, not a button, and the href is load-bearing: the widget now
67
+ delegates issue assembly to assets/js/fleet-feedback.js, so if that script
68
+ fails to load (or JavaScript is off entirely) the FAB still reaches the
69
+ issue form instead of becoming a decorative circle. page-feedback.js
70
+ intercepts [data-pf-open] and opens the richer modal when it is running.
71
+ {%- endcomment -%}
72
+ <a id="pageFeedbackFab"
73
+ class="pf-fab btn shadow-lg position-fixed"
74
+ href="https://github.com/{{ pf_repo }}/issues/new?template=page_improvement.yml&labels=page-feedback"
75
+ role="button"
76
+ data-pf-open
77
+ target="_blank"
78
+ rel="noopener noreferrer"
79
+ aria-haspopup="dialog"
80
+ aria-controls="pageFeedbackModal"
81
+ title="{{ site.page_feedback.fab_label | default: 'Improve this page' | escape }}"
82
+ aria-label="{{ site.page_feedback.fab_label | default: 'Improve this page' | escape }}">
73
83
  <i class="bi {{ site.page_feedback.fab_icon | default: 'bi-megaphone' }}" aria-hidden="true"></i>
74
- </button>
84
+ </a>
75
85
  {%- endif -%}
76
86
 
77
- <!-- Feedback modal (self-contained overlay; controlled by page-feedback.js).
87
+ {% comment %} Feedback modal (self-contained overlay; controlled by page-feedback.js).
78
88
  `position-fixed` is required, not cosmetic: it opts this <body> child out of
79
89
  the .zer0-bg-body flattening rule (_sass/theme/_backgrounds.scss) that would
80
90
  otherwise force position:relative; z-index:1 and let the cookie banner steal
81
- the dialog's clicks. -->
91
+ the dialog's clicks. {% endcomment %}
82
92
  <div class="pf-overlay position-fixed" id="pageFeedbackModal" role="dialog" aria-modal="true"
83
93
  aria-labelledby="pfTitle" aria-describedby="pfIntro" hidden>
84
94
  <div class="pf-dialog shadow-lg" role="document">
@@ -100,16 +110,18 @@
100
110
 
101
111
  <form id="pfForm" class="pf-body" novalidate>
102
112
 
103
- <!-- Step 1 — request type -->
113
+ {% comment %} Step 1 — request type {% endcomment %}
104
114
  <fieldset class="pf-field pf-types">
105
115
  <legend class="pf-legend">What kind of feedback?</legend>
106
116
  {%- comment -%}
107
117
  _data/feedback_types.yml is optional for consumers (remote_theme
108
118
  cannot ship _data). Without it the widget falls back to a minimal
109
119
  generic taxonomy (see pf_fallback_types below) instead of rendering
110
- an empty selector. The fallback entries carry no GitHub labels and
111
- no agent directive — labels must exist in the target repo or GitHub
112
- silently drops them from prefilled issue URLs.
120
+ an empty selector. The fallback carries the four fleet-taxonomy
121
+ labels (bug/docs/feature/question) and no agent directive: a label
122
+ the consumer repo does not have is silently dropped by GitHub, so
123
+ naming them costs nothing and makes the issue pipeline-eligible the
124
+ moment the feedback fan-out creates them.
113
125
  {%- endcomment -%}
114
126
  {%- assign pf_group = "" -%}
115
127
  {%- for t in site.data.feedback_types -%}
@@ -138,8 +150,7 @@
138
150
  cannot ship _data). Without it, render this minimal generic
139
151
  taxonomy instead of an empty selector. Ids/markup must stay in
140
152
  sync with the fallback JSON in the #pageFeedbackTypes script
141
- below. Fallback entries carry no GitHub labels (labels must exist
142
- in the target repo or GitHub silently drops them) and no agent
153
+ below, which carries the fleet-taxonomy labels and no agent
143
154
  directive.
144
155
  {%- endcomment -%}
145
156
  <p class="pf-types-group">This page</p>
@@ -183,7 +194,7 @@
183
194
  {%- endfor -%}
184
195
  </fieldset>
185
196
 
186
- <!-- Step 2 — description -->
197
+ {% comment %} Step 2 — description {% endcomment %}
187
198
  <div class="pf-field">
188
199
  <label for="pfDescription" class="pf-label">Describe it</label>
189
200
  <textarea id="pfDescription" class="form-control" rows="4"
@@ -194,14 +205,14 @@
194
205
  </p>
195
206
  </div>
196
207
 
197
- <!-- Step 3 — what gets attached -->
208
+ {% comment %} Step 3 — what gets attached {% endcomment %}
198
209
  <details class="pf-field pf-context" id="pfContextWrap">
199
210
  <summary class="pf-summary">
200
211
  <i class="bi bi-paperclip me-1" aria-hidden="true"></i>What gets attached
201
212
  <span class="pf-context-count" id="pfContextCount"></span>
202
213
  </summary>
203
214
  <ul class="pf-context-list" id="pfContextList" aria-live="polite">
204
- <!-- page title / url / path filled in by JS -->
215
+ {% comment %} page title / url / path filled in by JS {% endcomment %}
205
216
  </ul>
206
217
 
207
218
  {%- if site.page_feedback.capture_logs -%}
@@ -221,7 +232,7 @@
221
232
  </details>
222
233
 
223
234
  {%- if pf_ai_available -%}
224
- <!-- Step 4 — optional AI review (proxy + Claude Code OAuth) -->
235
+ {% comment %} Step 4 — optional AI review (proxy + Claude Code OAuth) {% endcomment %}
225
236
  <div class="pf-field pf-ai" id="pfAiWrap">
226
237
  <div class="pf-ai-head">
227
238
  <button type="button" class="btn btn-sm btn-outline-primary" id="pfAnalyze">
@@ -253,7 +264,7 @@
253
264
  </div>
254
265
  </div>
255
266
 
256
- <!-- Widget configuration consumed by assets/js/page-feedback.js -->
267
+ {% comment %} Widget configuration consumed by assets/js/page-feedback.js {% endcomment %}
257
268
  <script id="pageFeedbackConfig" type="application/json">
258
269
  {
259
270
  "enabled": true,
@@ -275,19 +286,19 @@
275
286
  }
276
287
  </script>
277
288
 
278
- <!-- Request-type taxonomy (from _data/feedback_types.yml; generic fallback
289
+ {% comment %} Request-type taxonomy (from _data/feedback_types.yml; generic fallback
279
290
  when the site ships no data file — keep in sync with the fallback markup
280
- in the pf-types fieldset above) -->
291
+ in the pf-types fieldset above) {% endcomment %}
281
292
  <script id="pageFeedbackTypes" type="application/json">
282
293
  {% if site.data.feedback_types %}{{ site.data.feedback_types | jsonify }}{% else %}[
283
- {"id":"fix-page","label":"Report a problem","icon":"bi-bug","group":"This page","scope":"page","description":"A typo, broken link, wrong information, or something rendering badly","labels":[],"agent":false,"placeholder":"What is wrong, where on the page, and what did you expect instead?"},
284
- {"id":"improve-page","label":"Improve this page","icon":"bi-stars","group":"This page","scope":"page","description":"Polish the copy, structure, or presentation","labels":[],"agent":false,"placeholder":"What would make this page clearer, tighter, or more useful?"},
285
- {"id":"feature","label":"Suggest a feature","icon":"bi-lightbulb","group":"The site","scope":"site","description":"An idea that would make the site more useful","labels":[],"agent":false,"placeholder":"Describe the feature and the problem it would solve."},
286
- {"id":"question","label":"Ask a question","icon":"bi-question-circle","group":"The site","scope":"site","description":"Something unclear that is not exactly a bug","labels":[],"agent":false,"placeholder":"What would you like to know?"}
294
+ {"id":"fix-page","label":"Report a problem","icon":"bi-bug","group":"This page","scope":"page","description":"A typo, broken link, wrong information, or something rendering badly","labels":["bug"],"agent":false,"placeholder":"What is wrong, where on the page, and what did you expect instead?"},
295
+ {"id":"improve-page","label":"Improve this page","icon":"bi-stars","group":"This page","scope":"page","description":"Polish the copy, structure, or presentation","labels":["docs"],"agent":false,"placeholder":"What would make this page clearer, tighter, or more useful?"},
296
+ {"id":"feature","label":"Suggest a feature","icon":"bi-lightbulb","group":"The site","scope":"site","description":"An idea that would make the site more useful","labels":["feature"],"agent":false,"placeholder":"Describe the feature and the problem it would solve."},
297
+ {"id":"question","label":"Ask a question","icon":"bi-question-circle","group":"The site","scope":"site","description":"Something unclear that is not exactly a bug","labels":["question"],"agent":false,"placeholder":"What would you like to know?"}
287
298
  ]{% endif %}
288
299
  </script>
289
300
 
290
- <!-- Live page context (build-time front matter; runtime detail added by JS) -->
301
+ {% comment %} Live page context (build-time front matter; runtime detail added by JS) {% endcomment %}
291
302
  <script id="pageFeedbackContext" type="application/json">
292
303
  {
293
304
  "title": {{ page.title | default: site.title | jsonify }},
@@ -310,6 +321,10 @@
310
321
  }
311
322
  </script>
312
323
 
324
+ {% comment %} The shared fleet builder must be parsed before the widget: page-feedback.js
325
+ reads window.FleetFeedbackCore at load and bails without it. Both are `defer`, and
326
+ deferred scripts execute in document order, so this ordering is the dependency. {% endcomment %}
327
+ <script defer src="{{ '/assets/js/fleet-feedback.js' | relative_url }}"></script>
313
328
  <script defer src="{{ '/assets/js/page-feedback.js' | relative_url }}"></script>
314
329
 
315
330
  {%- endunless -%}
@@ -31,7 +31,7 @@
31
31
  {%- assign pv_fallback = false -%}
32
32
  {%- if site.page_views.fallback_local -%}{%- assign pv_fallback = true -%}{%- endif -%}
33
33
 
34
- <!-- Page-view counter configuration consumed by assets/js/page-views.js -->
34
+ {% comment %} Page-view counter configuration consumed by assets/js/page-views.js {% endcomment %}
35
35
  <script id="pageViewsConfig" type="application/json">
36
36
  {
37
37
  "enabled": true,
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  POST CARD COMPONENT - Reusable blog post card
4
4
  ===================================================================
@@ -41,7 +41,7 @@
41
41
  - site.public_folder for image paths
42
42
  - site.teaser for fallback image
43
43
  ===================================================================
44
- -->
44
+ {% endcomment %}
45
45
 
46
46
  {% comment %} Parameter defaults {% endcomment %}
47
47
  {% assign show_category = include.show_category | default: true %}
@@ -70,44 +70,44 @@
70
70
  {% if render_col %}<div class="col">{% endif %}
71
71
  <div class="card h-100 post-card border-0 shadow-sm {{ card_class }}">
72
72
 
73
- <!-- ====================== -->
74
- <!-- CARD IMAGE & BADGES -->
75
- <!-- ====================== -->
73
+ {% comment %} ====================== {% endcomment %}
74
+ {% comment %} CARD IMAGE & BADGES {% endcomment %}
75
+ {% comment %} ====================== {% endcomment %}
76
76
  <div class="position-relative">
77
- <!-- Breaking News Badge -->
77
+ {% comment %} Breaking News Badge {% endcomment %}
78
78
  {% if include.post.breaking %}
79
79
  <span class="badge bg-danger position-absolute top-0 start-0 m-2 z-1">
80
80
  <i class="bi bi-lightning-fill me-1"></i>Breaking
81
81
  </span>
82
82
  {% endif %}
83
83
 
84
- <!-- Featured Badge -->
84
+ {% comment %} Featured Badge {% endcomment %}
85
85
  {% if include.post.featured %}
86
86
  <span class="badge bg-warning text-dark position-absolute top-0 end-0 m-2 z-1">
87
87
  <i class="bi bi-star-fill me-1"></i>Featured
88
88
  </span>
89
89
  {% endif %}
90
90
 
91
- <!-- Post Type Badge -->
91
+ {% comment %} Post Type Badge {% endcomment %}
92
92
  {% if show_post_type and include.post.post_type and include.post.post_type != "standard" and include.post.post_type != "featured" and include.post.post_type != "breaking" %}
93
93
  <span class="position-absolute bottom-0 start-0 m-2 z-1">
94
94
  {% include components/post-type-badge.html post_type=include.post.post_type %}
95
95
  </span>
96
96
  {% endif %}
97
97
 
98
- <!-- Preview Image -->
98
+ {% comment %} Preview Image {% endcomment %}
99
99
  <a href="{{ include.post.url | relative_url }}" class="text-decoration-none">
100
100
  {% assign card_img = include.post.preview | default: site.teaser %}
101
101
  {% include components/preview-image.html src=card_img alt=include.post.title class="card-img-top" %}
102
102
  </a>
103
103
  </div>
104
104
 
105
- <!-- ====================== -->
106
- <!-- CARD BODY -->
107
- <!-- ====================== -->
105
+ {% comment %} ====================== {% endcomment %}
106
+ {% comment %} CARD BODY {% endcomment %}
107
+ {% comment %} ====================== {% endcomment %}
108
108
  <div class="card-body d-flex flex-column">
109
109
 
110
- <!-- Category Badge -->
110
+ {% comment %} Category Badge {% endcomment %}
111
111
  {% comment %} Category base is configurable (`category_base`, default `/news`).
112
112
  Only link the badge when that category index page exists in the build;
113
113
  otherwise render a plain badge so remote-theme consumers (whose category
@@ -135,7 +135,7 @@
135
135
  </div>
136
136
  {% endif %}
137
137
 
138
- <!-- Post Title -->
138
+ {% comment %} Post Title {% endcomment %}
139
139
  <h5 class="card-title mb-2">
140
140
  <a href="{{ include.post.url | relative_url }}"
141
141
  class="text-decoration-none text-body-emphasis stretched-link">
@@ -143,14 +143,14 @@
143
143
  </a>
144
144
  </h5>
145
145
 
146
- <!-- Subtitle if available -->
146
+ {% comment %} Subtitle if available {% endcomment %}
147
147
  {% if include.post.sub-title %}
148
148
  <p class="card-subtitle text-muted small mb-2">
149
149
  {{ include.post.sub-title }}
150
150
  </p>
151
151
  {% endif %}
152
152
 
153
- <!-- Post Excerpt -->
153
+ {% comment %} Post Excerpt {% endcomment %}
154
154
  {% if show_excerpt %}
155
155
  <p class="card-text text-muted small flex-grow-1">
156
156
  {{ include.post.excerpt | strip_html | truncate: 120 }}
@@ -159,13 +159,13 @@
159
159
 
160
160
  </div>
161
161
 
162
- <!-- ====================== -->
163
- <!-- CARD FOOTER -->
164
- <!-- ====================== -->
162
+ {% comment %} ====================== {% endcomment %}
163
+ {% comment %} CARD FOOTER {% endcomment %}
164
+ {% comment %} ====================== {% endcomment %}
165
165
  <div class="card-footer bg-transparent border-top-0">
166
166
  <div class="d-flex justify-content-between align-items-center small text-muted">
167
167
 
168
- <!-- Left: Author & Date -->
168
+ {% comment %} Left: Author & Date {% endcomment %}
169
169
  <div>
170
170
  {% if show_author and include.post.author %}
171
171
  <span class="me-2">
@@ -177,7 +177,7 @@
177
177
  </span>
178
178
  </div>
179
179
 
180
- <!-- Right: Reading Time -->
180
+ {% comment %} Right: Reading Time {% endcomment %}
181
181
  {% if show_reading_time %}
182
182
  <span>
183
183
  <i class="bi bi-clock me-1"></i>{{ reading_time }}
@@ -186,7 +186,7 @@
186
186
 
187
187
  </div>
188
188
 
189
- <!-- Tags (compact) -->
189
+ {% comment %} Tags (compact) {% endcomment %}
190
190
  {% if include.post.tags.size > 0 %}
191
191
  <div class="mt-2">
192
192
  {% for tag in include.post.tags limit: 3 %}
@@ -1,5 +1,5 @@
1
1
  {% comment %} Feature: ZER0-064 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  ===================================================================
4
4
  POST TYPE BADGE COMPONENT - Visual indicator for article types
5
5
  ===================================================================
@@ -29,7 +29,7 @@
29
29
  - Bootstrap 5 badge component
30
30
  - Bootstrap Icons
31
31
  ===================================================================
32
- -->
32
+ {% endcomment %}
33
33
 
34
34
  {% assign type = include.post_type | default: "standard" %}
35
35
 
@@ -1,8 +1,8 @@
1
- <!--
1
+ {% comment %}
2
2
  file: powered-by.html
3
3
  path:_includes/powered-by.html
4
4
  description: This file is used to display the powered by section on the home page.
5
- -->
5
+ {% endcomment %}
6
6
 
7
7
  <div class="row row-cols-1 row-cols-md-3 g-4">
8
8
  {% for power in site.powered_by %}
@@ -10,6 +10,12 @@
10
10
  style="height: 180px; object-fit: cover;"
11
11
  -%}
12
12
 
13
+ WHICH INCLUDE: this one renders an <img> in the content flow. For cover art
14
+ painted as a CSS background on an otherwise empty box, use the sibling
15
+ components/background-image.html -- a background image is invisible to
16
+ assistive tech, so that case needs role="img" + aria-label (or aria-hidden
17
+ when purely decorative) rather than an alt attribute.
18
+
13
19
  Convention: Preview paths can omit the /assets/ prefix.
14
20
  The component will auto-prepend the assets_prefix from _config.yml.
15
21
  Examples:
@@ -1,4 +1,4 @@
1
- <!-- Quick index of pages in the collection -->
1
+ {% comment %} Quick index of pages in the collection {% endcomment %}
2
2
  {% if site.collections.pages %}
3
3
  <ul>
4
4
  <p>Quick Index</p>
@@ -10,7 +10,7 @@
10
10
  </ul>
11
11
  {% endif %}
12
12
 
13
- <!-- Post Categories -->
13
+ {% comment %} Post Categories {% endcomment %}
14
14
  {% if page.sidebar == "searchCats" %}
15
15
  <div id="categories">
16
16
  </div>
@@ -1,5 +1,5 @@
1
1
  {% comment %} Feature: ZER0-032 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  ===================================================================
4
4
  SEARCH MODAL - Site-wide Search Popup
5
5
  ===================================================================
@@ -16,7 +16,7 @@
16
16
  prevents a dead link on remote-theme Pages builds that lack /sitemap/.
17
17
  - Keyboard shortcut handled by navigation keyboard module ("/")
18
18
  ===================================================================
19
- -->
19
+ {% endcomment %}
20
20
 
21
21
  {%- include core/i18n.html lang=include.lang -%}
22
22
  {%- assign search_placeholder = ui.search_placeholder_text | default: "Enter your search term..." -%}
@@ -72,6 +72,31 @@
72
72
  Press <kbd>/</kbd> or <kbd>⌘</kbd>/<kbd>Ctrl</kbd>+<kbd>K</kbd> to open search, <kbd>Esc</kbd> to close.
73
73
  </div>
74
74
  </form>
75
+ {%- comment -%}
76
+ Results were never announced (issue #279): search rewrites the
77
+ container below without moving focus, so a screen-reader user
78
+ got silence — the visible list changed with nothing entering
79
+ the accessibility tree's notification queue.
80
+
81
+ The live region is this dedicated, visually-hidden element
82
+ rather than the results container itself. Marking the
83
+ container live would announce all eight result titles and
84
+ their snippets on every keystroke, which is unusable; a
85
+ screen-reader user wants "7 results for jekyll", then to
86
+ navigate the list on their own terms.
87
+
88
+ polite, not assertive: results land on each keystroke and an
89
+ assertive region would interrupt the user mid-word, cutting
90
+ off the query they are still typing.
91
+
92
+ aria-atomic so the summary is read as one message even when
93
+ only part of the string changes (8 results -> 7 results).
94
+ {%- endcomment -%}
95
+ <div class="visually-hidden"
96
+ role="status"
97
+ aria-live="polite"
98
+ aria-atomic="true"
99
+ data-search-status></div>
75
100
  <div class="search-results mt-3" data-search-results>
76
101
  <div class="text-muted small" data-search-empty>Start typing to see results.</div>
77
102
  </div>
@@ -1,9 +1,9 @@
1
1
  {% comment %} Feature: ZER0-032 {% endcomment %}
2
2
 
3
- <!--
3
+ {% comment %}
4
4
  title: Searchbar and hits
5
5
  source: Theme component
6
- -->
6
+ {% endcomment %}
7
7
  <div class="container order-1">
8
8
  <div id="searchbox" class="" ></div>
9
9
  <div id="hits" class="text-start"></div>
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  SVG-BACKGROUND — Apply fffuel-style SVG background to a zone
4
4
  ===================================================================
@@ -20,7 +20,7 @@
20
20
  - _data/theme_backgrounds.yml (asset paths)
21
21
  - _config.yml theme_background (opacity / blend settings)
22
22
  ===================================================================
23
- -->
23
+ {% endcomment %}
24
24
 
25
25
  {% assign zone = include.zone | default: "body" %}
26
26
  {% assign skin = site.theme_skin | default: "dark" %}
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  THEME CUSTOMIZER — Skin preview grid with live class swapping
4
4
  ===================================================================
@@ -12,7 +12,7 @@
12
12
  Dependencies: Bootstrap 5 grid/card, Bootstrap Icons
13
13
  Used by: pages/_about/settings/theme.md (Skin Preview tab)
14
14
  ===================================================================
15
- -->
15
+ {% endcomment %}
16
16
 
17
17
  {%- comment -%}
18
18
  _data/theme_skins.yml is optional for consumers (remote_theme cannot ship
@@ -1,5 +1,5 @@
1
1
  {% comment %} Feature: ZER0-021 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  ===================================================================
4
4
  THEME INFO - Compact Theme and Build Information
5
5
  ===================================================================
@@ -15,12 +15,12 @@
15
15
  Note: environment (Prod/Dev) is shown by env-switcher.html in the
16
16
  same Site tab — not duplicated here.
17
17
  ===================================================================
18
- -->
18
+ {% endcomment %}
19
19
 
20
20
  <div class="theme-info-compact">
21
21
  <div class="row g-2">
22
22
 
23
- <!-- Theme -->
23
+ {% comment %} Theme {% endcomment %}
24
24
  <div class="col-12">
25
25
  <div class="d-flex align-items-center justify-content-between p-2 bg-body-tertiary rounded">
26
26
  <div class="d-flex align-items-center">
@@ -44,7 +44,7 @@
44
44
  </div>
45
45
  </div>
46
46
 
47
- <!-- Jekyll & Last Build -->
47
+ {% comment %} Jekyll & Last Build {% endcomment %}
48
48
  <div class="col-6">
49
49
  <div class="p-2 bg-body-tertiary rounded text-center">
50
50
  <small class="text-body-secondary d-block">Jekyll</small>
@@ -66,7 +66,7 @@
66
66
  </div>
67
67
 
68
68
  {% if site.repository %}
69
- <!-- Repository -->
69
+ {% comment %} Repository {% endcomment %}
70
70
  <div class="col-12">
71
71
  <div class="d-flex align-items-center justify-content-between p-2 bg-body-tertiary rounded">
72
72
  <div class="d-flex align-items-center">
@@ -81,7 +81,7 @@
81
81
  </div>
82
82
  {% endif %}
83
83
 
84
- <!-- Quick Links -->
84
+ {% comment %} Quick Links {% endcomment %}
85
85
  <div class="col-12 mt-2">
86
86
  <div class="d-flex flex-wrap gap-2 justify-content-center">
87
87
  {% if site.remote_theme %}