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
@@ -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 %}
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  NAV TREE - Flat YAML Navigation Renderer
4
4
  ===================================================================
@@ -28,7 +28,7 @@
28
28
  Usage:
29
29
  include navigation/nav-tree.html nav="docs"
30
30
  ===================================================================
31
- -->
31
+ {% endcomment %}
32
32
 
33
33
  {% assign navigation = site.data.navigation[include.nav] %}
34
34
 
@@ -42,7 +42,7 @@
42
42
 
43
43
  <li class="mb-1 nav-tree-item" data-depth="0">
44
44
  {% if has_children %}
45
- <!-- Parent item with children - collapsible -->
45
+ {% comment %} Parent item with children - collapsible {% endcomment %}
46
46
  <div class="d-flex align-items-center">
47
47
  {% if item.url %}
48
48
  <a href="{{ item.url | relative_url }}"
@@ -73,7 +73,7 @@
73
73
  {% endif %}
74
74
  </div>
75
75
 
76
- <!-- Children container (Level 1) -->
76
+ {% comment %} Children container (Level 1) {% endcomment %}
77
77
  <div class="collapse{% if is_expanded %} show{% endif %}" id="{{ item_id }}">
78
78
  <ul class="list-unstyled fw-normal ps-3 nav-tree-children">
79
79
  {% for child in item.children %}
@@ -84,7 +84,7 @@
84
84
 
85
85
  <li class="mb-1 nav-tree-item" data-depth="1">
86
86
  {% if child_has_children %}
87
- <!-- Level 1 parent with children -->
87
+ {% comment %} Level 1 parent with children {% endcomment %}
88
88
  <div class="d-flex align-items-center">
89
89
  {% if child.url %}
90
90
  <a href="{{ child.url | relative_url }}"
@@ -114,7 +114,7 @@
114
114
  {% endif %}
115
115
  </div>
116
116
 
117
- <!-- Children container (Level 2) -->
117
+ {% comment %} Children container (Level 2) {% endcomment %}
118
118
  <div class="collapse{% if child_expanded %} show{% endif %}" id="{{ child_id }}">
119
119
  <ul class="list-unstyled fw-normal ps-3 nav-tree-children">
120
120
  {% for grandchild in child.children %}
@@ -137,7 +137,7 @@
137
137
  </ul>
138
138
  </div>
139
139
  {% else %}
140
- <!-- Level 1 leaf item -->
140
+ {% comment %} Level 1 leaf item {% endcomment %}
141
141
  {% if child.url %}
142
142
  <a href="{{ child.url | relative_url }}"
143
143
  class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if child_active %} active{% endif %}">
@@ -156,7 +156,7 @@
156
156
  </ul>
157
157
  </div>
158
158
  {% else %}
159
- <!-- Root level leaf item -->
159
+ {% comment %} Root level leaf item {% endcomment %}
160
160
  {% if item.url %}
161
161
  <a href="{{ item.url | relative_url }}"
162
162
  class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if is_active %} active{% endif %}">
@@ -1,25 +1,25 @@
1
1
  {% comment %} Features: ZER0-049, ZER0-055 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  file: navbar.html
4
4
  path: /includes/navbar.html
5
5
  includes:
6
6
  purpose: Offcanvas main navigation following Bootstrap 5 best practices
7
7
  with hover-activated dropdowns for desktop and accessible interactions
8
- -->
8
+ {% endcomment %}
9
9
 
10
- <!-- Navigation Links - Responsive Offcanvas (inline at lg+, offcanvas below) -->
10
+ {% comment %} Navigation Links - Responsive Offcanvas (inline at lg+, offcanvas below) {% endcomment %}
11
11
  {%- include core/i18n.html -%}
12
12
  <div class="offcanvas-lg offcanvas-end" tabindex="-1" id="bdNavbar" aria-labelledby="mainNavOffcanvasLabel">
13
13
 
14
- <!-- Main Navigation Header - Offcanvas -->
14
+ {% comment %} Main Navigation Header - Offcanvas {% endcomment %}
15
15
  <div class="offcanvas-header border-bottom">
16
16
  <h2 class="offcanvas-title h5 mb-0" id="mainNavOffcanvasLabel">{{ ui.main_nav_label | default: "Main Navigation" }}</h2>
17
17
  <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close navigation menu" data-bs-target="#bdNavbar"></button>
18
18
  </div>
19
19
 
20
- <!-- Main Navigation Body - Offcanvas -->
20
+ {% comment %} Main Navigation Body - Offcanvas {% endcomment %}
21
21
  <div class="offcanvas-body">
22
- <!-- Desktop: width is the grid middle track; labels ellipsis or icon-only via container query -->
22
+ {% comment %} Desktop: width is the grid middle track; labels ellipsis or icon-only via container query {% endcomment %}
23
23
  <div class="bd-navbar-nav-viewport">
24
24
  <ul class="navbar-nav justify-content-lg-center text-start flex-grow-1">
25
25
  <li class="nav-item d-lg-none">
@@ -44,7 +44,7 @@
44
44
 
45
45
  {%- if has_children -%}
46
46
  <li class="nav-item dropdown d-flex align-items-center nav-hover-dropdown">
47
- <!-- Parent link navigates directly -->
47
+ {% comment %} Parent link navigates directly {% endcomment %}
48
48
  <a
49
49
  class="nav-link"
50
50
  href="{{ link.url | relative_url }}"
@@ -58,9 +58,9 @@
58
58
  <span class="nav-link-text">{{ link.title }}</span>
59
59
  </a>
60
60
 
61
- <!-- Split toggle opens the dropdown (click on mobile, hover on desktop) -->
62
- <!-- Note: No data-bs-toggle="dropdown" — custom JS handles all interactions
63
- to avoid Bootstrap's native handler conflicting with our toggle logic -->
61
+ {% comment %} Split toggle opens the dropdown (click on mobile, hover on desktop) {% endcomment %}
62
+ {% comment %} Note: No data-bs-toggle="dropdown" — custom JS handles all interactions
63
+ to avoid Bootstrap's native handler conflicting with our toggle logic {% endcomment %}
64
64
  <button
65
65
  class="nav-link dropdown-toggle dropdown-toggle-split ms-1"
66
66
  type="button"
@@ -165,8 +165,8 @@
165
165
  </div>
166
166
  </div>
167
167
 
168
- <!--
168
+ {% comment %}
169
169
  Navigation styles are now in _sass/core/_navbar.scss
170
170
  Navigation scripts are now in assets/js/navigation.js
171
171
  These are loaded automatically via the theme's asset pipeline
172
- -->
172
+ {% endcomment %}
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  SECTION SIDEBAR - Fixed Topic Navigation
4
4
  ===================================================================
@@ -28,7 +28,7 @@
28
28
  - Bootstrap 5 offcanvas component
29
29
  - Bootstrap Icons
30
30
  ===================================================================
31
- -->
31
+ {% endcomment %}
32
32
 
33
33
  {% assign sidebar_id = include.sidebar_id | default: "sectionSidebar" %}
34
34
  {% assign section_posts = include.section_posts %}
@@ -71,13 +71,13 @@
71
71
  {% endfor %}
72
72
  {% endif %}
73
73
 
74
- <!-- ================================ -->
75
- <!-- DESKTOP SIDEBAR (Fixed Sticky) -->
76
- <!-- ================================ -->
74
+ {% comment %} ================================ {% endcomment %}
75
+ {% comment %} DESKTOP SIDEBAR (Fixed Sticky) {% endcomment %}
76
+ {% comment %} ================================ {% endcomment %}
77
77
  <aside class="section-sidebar-desktop d-none d-lg-block w-100">
78
78
  <div class="position-sticky" style="top: 80px;">
79
79
 
80
- <!-- Topics Card -->
80
+ {% comment %} Topics Card {% endcomment %}
81
81
  <div class="card border-0 shadow-sm">
82
82
  <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
83
83
  <h5 class="mb-0">
@@ -134,7 +134,7 @@
134
134
  {% endif %}
135
135
  </div>
136
136
 
137
- <!-- Section Stats -->
137
+ {% comment %} Section Stats {% endcomment %}
138
138
  <div class="card border-0 shadow-sm mt-3">
139
139
  <div class="card-body">
140
140
  <h6 class="text-muted mb-3">
@@ -158,9 +158,9 @@
158
158
  </div>
159
159
  </aside>
160
160
 
161
- <!-- ================================ -->
162
- <!-- MOBILE OFFCANVAS SIDEBAR -->
163
- <!-- ================================ -->
161
+ {% comment %} ================================ {% endcomment %}
162
+ {% comment %} MOBILE OFFCANVAS SIDEBAR {% endcomment %}
163
+ {% comment %} ================================ {% endcomment %}
164
164
  <div class="offcanvas offcanvas-start" tabindex="-1" id="{{ sidebar_id }}" aria-labelledby="{{ sidebar_id }}Label">
165
165
  <div class="offcanvas-header bg-primary text-white">
166
166
  <h2 class="offcanvas-title h5" id="{{ sidebar_id }}Label">
@@ -208,9 +208,9 @@
208
208
  </div>
209
209
  </div>
210
210
 
211
- <!-- ================================ -->
212
- <!-- SIDEBAR STYLES -->
213
- <!-- ================================ -->
211
+ {% comment %} ================================ {% endcomment %}
212
+ {% comment %} SIDEBAR STYLES {% endcomment %}
213
+ {% comment %} ================================ {% endcomment %}
214
214
  <style>
215
215
  /* Sidebar Navigation */
216
216
  .sidebar-nav .nav-link {
@@ -258,9 +258,9 @@
258
258
  }
259
259
  </style>
260
260
 
261
- <!-- ================================ -->
262
- <!-- SIDEBAR JAVASCRIPT -->
263
- <!-- ================================ -->
261
+ {% comment %} ================================ {% endcomment %}
262
+ {% comment %} SIDEBAR JAVASCRIPT {% endcomment %}
263
+ {% comment %} ================================ {% endcomment %}
264
264
  <script>
265
265
  (function() {
266
266
  // Smooth scroll for sidebar links
@@ -16,8 +16,13 @@
16
16
  "categories", "tags", or the name of a
17
17
  _data/navigation/*.yml file (nil = none)
18
18
  sidebar_has_content — true only when sidebar_nav will actually
19
- render items (gates the left column and
20
- the mobile toggle)
19
+ render items (gates the left column)
20
+ sidebar_offcanvas_rendered
21
+ — true only when the CURRENT LAYOUT emits
22
+ the #bdSidebar / #tocContents offcanvases
23
+ at all. sidebar_has_content is not enough
24
+ to gate a toggle: see the note at the
25
+ bottom of this file (issue #373).
21
26
  sidebar_title — heading text for the sidebar panel
22
27
  sidebar_icon — Bootstrap Icons class for the heading
23
28
  Config precedence (most specific wins):
@@ -134,3 +139,32 @@
134
139
  {%- if page.sidebar.icon -%}
135
140
  {%- assign sidebar_icon = page.sidebar.icon -%}
136
141
  {%- endif -%}
142
+
143
+ {%- comment -%}
144
+ 7. Does THIS LAYOUT actually render the offcanvas panels? (issue #373)
145
+
146
+ `sidebar_has_content` answers "is there nav content", which is what gates the
147
+ left column inside _layouts/default.html. It is NOT sufficient to gate the
148
+ TOGGLES, because core/header.html and core/footer-fabs.html are included from
149
+ _layouts/root.html — so they render on every layout, while `#bdSidebar`
150
+ (navigation/sidebar-left.html) and `#tocContents` (navigation/sidebar-right.html)
151
+ are emitted by _layouts/default.html alone.
152
+
153
+ The result was a dead control plus a dangling ARIA reference on every page
154
+ whose layout inherits `root` directly: measured at 37 pages of a 415-page
155
+ build, including all of `/about/**` (layout: admin) and 404/CHANGELOG.
156
+ Clicking did nothing, and assistive tech followed aria-controls to an element
157
+ that was not there.
158
+
159
+ There is no Liquid API for "resolve the layout inheritance chain", so the set
160
+ of layouts that reach default.html is listed here explicitly. It is pinned by
161
+ a test (test/test_core.sh :: test_sidebar_offcanvas_layout_gate) that reads
162
+ the front matter of every _layouts/*.html and fails if reality drifts from
163
+ this list — the same invariant pattern #425 used for the pixel-gate filter.
164
+ Add a layout here when, and only when, its `layout:` chain reaches default.
165
+ {%- endcomment -%}
166
+ {%- assign _sidebar_offcanvas_layouts = "default,article,author,authors,collection,cookbook,note,notebook,recipe,tag" | split: "," -%}
167
+ {%- assign sidebar_offcanvas_rendered = false -%}
168
+ {%- if _sidebar_offcanvas_layouts contains page.layout -%}
169
+ {%- assign sidebar_offcanvas_rendered = true -%}
170
+ {%- endif -%}
@@ -1,5 +1,5 @@
1
1
  {% comment %} Feature: ZER0-008 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  ===================================================================
4
4
  SIDEBAR LEFT - Dynamic Navigation Sidebar
5
5
  ===================================================================
@@ -27,14 +27,14 @@
27
27
  - Heading text/icon: page.sidebar.title/icon → collection metadata →
28
28
  site.sidebar.title/icon → "Browse docs"
29
29
  ===================================================================
30
- -->
30
+ {% endcomment %}
31
31
 
32
32
  {% include navigation/sidebar-config.html %}
33
33
 
34
- <!-- ================================ -->
35
- <!-- SIDEBAR NAVIGATION CONTAINER -->
36
- <!-- ================================ -->
37
- <!-- Responsive offcanvas sidebar - full-width on mobile, fixed on desktop -->
34
+ {% comment %} ================================ {% endcomment %}
35
+ {% comment %} SIDEBAR NAVIGATION CONTAINER {% endcomment %}
36
+ {% comment %} ================================ {% endcomment %}
37
+ {% comment %} Responsive offcanvas sidebar - full-width on mobile, fixed on desktop {% endcomment %}
38
38
  <script>
39
39
  try {
40
40
  if (localStorage.getItem('zer0-nav-sidebar-visible') === 'false') {
@@ -44,10 +44,10 @@
44
44
  </script>
45
45
  <div class="offcanvas-lg offcanvas-start" tabindex="-1" id="bdSidebar" aria-labelledby="bdSidebarOffcanvasLabel">
46
46
 
47
- <!-- ========================== -->
48
- <!-- SIDEBAR HEADER -->
49
- <!-- ========================== -->
50
- <!-- Mobile-only header with close button -->
47
+ {% comment %} ========================== {% endcomment %}
48
+ {% comment %} SIDEBAR HEADER {% endcomment %}
49
+ {% comment %} ========================== {% endcomment %}
50
+ {% comment %} Mobile-only header with close button {% endcomment %}
51
51
  <div class="offcanvas-header">
52
52
  <h2 class="offcanvas-title h5 mb-0" id="bdSidebarOffcanvasLabel">{{ sidebar_title }}</h2>
53
53
  <div class="d-flex align-items-center gap-1">
@@ -63,10 +63,10 @@
63
63
  </div>
64
64
  </div>
65
65
 
66
- <!-- ========================== -->
67
- <!-- SIDEBAR CONTENT AREA -->
68
- <!-- ========================== -->
69
- <!-- Scrollable content area with dynamic navigation options -->
66
+ {% comment %} ========================== {% endcomment %}
67
+ {% comment %} SIDEBAR CONTENT AREA {% endcomment %}
68
+ {% comment %} ========================== {% endcomment %}
69
+ {% comment %} Scrollable content area with dynamic navigation options {% endcomment %}
70
70
  <div class="offcanvas-body overflow-auto">
71
71
 
72
72
  <div class="bd-sidebar-desktop-header mb-3 d-none d-lg-flex align-items-center justify-content-between gap-2 w-100">
@@ -86,7 +86,7 @@
86
86
  </button>
87
87
  </div>
88
88
 
89
- <!-- Resolved navigation content (see navigation/sidebar-nav.html) -->
89
+ {% comment %} Resolved navigation content (see navigation/sidebar-nav.html) {% endcomment %}
90
90
  {% include navigation/sidebar-nav.html id="sidebar-content" %}
91
91
 
92
92
  </div>
@@ -1,12 +1,12 @@
1
1
  {% comment %} Features: ZER0-008, ZER0-010 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  file: sidebar-right.html
4
4
  path: _includes/sidebar-right.html
5
5
  includes: nav_list.html, content/toc.html
6
- -->
6
+ {% endcomment %}
7
7
 
8
8
  {%- include core/i18n.html -%}
9
- <!-- FOUC guard: apply hidden TOC preference before paint -->
9
+ {% comment %} FOUC guard: apply hidden TOC preference before paint {% endcomment %}
10
10
  <script>
11
11
  try {
12
12
  if (localStorage.getItem('zer0-nav-toc-visible') === 'false') {
@@ -15,7 +15,7 @@
15
15
  } catch (e) {}
16
16
  </script>
17
17
 
18
- <!-- Right sidebar container -->
18
+ {% comment %} Right sidebar container {% endcomment %}
19
19
  <div class="offcanvas-lg offcanvas-end" tabindex="-1" id="tocContents" aria-labelledby="tocLabel">
20
20
  <div class="offcanvas-header">
21
21
  <h2 class="offcanvas-title h5 mb-0" id="tocLabel">{{ ui.toc_title | default: "Table of Contents" }}</h2>
@@ -32,9 +32,9 @@
32
32
  </div>
33
33
  </div>
34
34
  <div class="offcanvas-body">
35
- <!-- Table of contents -->
35
+ {% comment %} Table of contents {% endcomment %}
36
36
  <nav id="TableOfContents" role="navigation" aria-label="Table of Contents">
37
- <!-- TOC title -->
37
+ {% comment %} TOC title {% endcomment %}
38
38
  <div class="mb-3 d-flex align-items-center justify-content-between gap-2">
39
39
  <strong class="d-flex align-items-center mb-0">
40
40
  <i class="bi bi-file-text me-2" aria-hidden="true"></i>
@@ -197,9 +197,9 @@ unresolved targets show up as dashed red nodes so you can find dangling
197
197
  links at a glance. The graph is regenerated every Jekyll build; nothing
198
198
  runs client-side except cytoscape's force layout.
199
199
 
200
- <!-- Cytoscape.js is vendored (no runtime CDN) and lazy-loaded by
200
+ {% comment %} Cytoscape.js is vendored (no runtime CDN) and lazy-loaded by
201
201
  obsidian-graph.js from window.OBSIDIAN_CONFIG.cytoscapeUrl, only on this
202
- page, with an in-page recovery message if the fetch fails. -->
202
+ page, with an in-page recovery message if the fetch fails. {% endcomment %}
203
203
  {% if site.obsidian.enabled != false %}
204
204
  <script src="{{ '/assets/js/obsidian-graph.js' | relative_url }}?v={{ site.time | date: '%s' }}" defer></script>
205
205
  {% endif %}
@@ -0,0 +1,72 @@
1
+ {% comment %} Feature: ZER0-086, ZER0-087 {% endcomment %}
2
+ {%- comment -%}
3
+ Component: setup/claude-session
4
+ Path: _includes/setup/claude-session.html
5
+ Purpose: The embedded AI session that rides alongside every Site
6
+ Builder step: connection state, provider + mode badges,
7
+ transcript, suggested prompts, and the composer with a Stop
8
+ button for long tool runs. The assistant (Claude or Grok —
9
+ whichever the Connect step connected) sees the whole wizard
10
+ state on every turn and acts on it through tools (fill fields,
11
+ run checks, read theme source, write or modify the project,
12
+ generate images, run Docker).
13
+ Params: none — configured by #siteBuilderConfig in setup/wizard.html
14
+ Depends on: Bootstrap 5.3 + Icons, assets/js/site-builder.js,
15
+ _sass/components/_setup-wizard.scss
16
+ Notes:
17
+ - Proxy-only. Nothing renders a credential; the panel shows a connect
18
+ prompt until GET {endpoint}/status answers AND the chosen provider has
19
+ a key (data-ready="true"), then goes live.
20
+ - Rendering is escape-first (a limited Markdown subset); action cards are
21
+ built with createElement/textContent — see ai-chat.instructions.md.
22
+ - role="log" + aria-live so screen readers hear replies; Escape does not
23
+ close the panel (it is a page region, not a dialog).
24
+ {%- endcomment -%}
25
+
26
+ <section class="sb-panel card" id="siteBuilderPanel" aria-labelledby="sb-title" data-state="offline" data-ready="false" data-mode="guided">
27
+ <div class="card-header d-flex align-items-center justify-content-between gap-2 py-2">
28
+ <div class="d-flex align-items-center gap-2 min-w-0">
29
+ <i class="bi bi-stars" aria-hidden="true"></i>
30
+ <h2 class="h6 mb-0 text-truncate" id="sb-title">AI session</h2>
31
+ <span class="badge rounded-pill text-bg-light border sb-mode-badge" id="sb-mode-badge" hidden>guided</span>
32
+ </div>
33
+ <div class="d-flex align-items-center gap-2">
34
+ <span class="sb-status-badge badge rounded-pill text-bg-secondary" id="sb-status-badge" aria-live="polite">offline</span>
35
+ <button class="btn btn-sm btn-link text-body p-0" type="button" id="sb-clear" title="Clear the conversation" aria-label="Clear the conversation">
36
+ <i class="bi bi-eraser" aria-hidden="true"></i>
37
+ </button>
38
+ <button class="btn btn-sm btn-link text-body p-0" type="button" id="sb-collapse" aria-expanded="true" aria-controls="sb-body" title="Collapse">
39
+ <i class="bi bi-chevron-up" aria-hidden="true"></i>
40
+ </button>
41
+ </div>
42
+ </div>
43
+
44
+ <div class="sb-body" id="sb-body">
45
+ <div class="sb-messages p-3" id="sb-messages" role="log" aria-live="polite" aria-relevant="additions">
46
+ <div class="sb-offline text-body-secondary small" id="sb-offline">
47
+ <p class="mb-1"><strong>Not connected.</strong> Start the dev proxy and connect Claude or Grok on step 1. The assistant can then read your answers, fill in the forms, check your machine, read the theme's source, write or modify your project, generate images and run the build.</p>
48
+ <p class="mb-0">Everything else on this page works without it.</p>
49
+ </div>
50
+ </div>
51
+
52
+ <div class="sb-chips px-3 pb-2 d-flex gap-2 flex-wrap" id="sb-chips" aria-label="Suggested prompts"></div>
53
+
54
+ <form class="sb-composer p-3 pt-0" id="sb-form" autocomplete="off">
55
+ <label for="sb-input" class="visually-hidden">Message the assistant</label>
56
+ <div class="input-group">
57
+ <textarea class="form-control" id="sb-input" rows="1" maxlength="6000"
58
+ placeholder="Connect a provider to start chatting" disabled></textarea>
59
+ <button class="btn btn-primary" type="submit" id="sb-send" aria-label="Send" disabled>
60
+ <i class="bi bi-send" aria-hidden="true"></i>
61
+ </button>
62
+ <button class="btn btn-outline-danger" type="button" id="sb-stop" aria-label="Stop the current run" hidden disabled>
63
+ <i class="bi bi-stop-fill" aria-hidden="true"></i> Stop
64
+ </button>
65
+ </div>
66
+ <div class="d-flex justify-content-between align-items-center mt-1">
67
+ <small class="text-body-secondary sb-disclaimer" id="sb-disclaimer">The assistant sees every answer on this page. Actions ask for confirmation first.</small>
68
+ <small class="text-body-secondary" id="sb-context-note"></small>
69
+ </div>
70
+ </form>
71
+ </div>
72
+ </section>