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
@@ -1,438 +1,82 @@
1
1
  {% comment %} Feature: ZER0-013 {% endcomment %}
2
- <!--
3
- ===================================================================
4
- MERMAID DIAGRAM INTEGRATION (v2.1 - GitHub Pages Compatible)
5
- ===================================================================
6
-
7
- File: mermaid.html
8
- Path: _includes/components/mermaid.html
9
- Purpose: Load and initialize Mermaid.js for diagram rendering
10
-
11
- Usage (Two syntaxes supported):
12
-
13
- 1. Native Markdown Code Blocks (Recommended):
14
- ```mermaid
15
- graph TD
16
- A[Start] -> B[End]
17
- ```
18
-
19
- 2. HTML Div Syntax:
20
- <div class="mermaid">
21
- graph TD
22
- A[Start] -- > B[End]
23
- </div>
24
-
25
- Requirements:
26
- - Set 'mermaid: true' in page front matter
27
- - Supports all Mermaid diagram types (flowcharts, sequence, gantt, etc.)
28
-
29
- Configuration:
30
- - Mermaid v10 bundled locally (_config.yml mermaid.src)
31
- - Adaptive light/dark theme following Bootstrap's data-bs-theme
32
- - Client-side code block conversion for GitHub Pages compatibility
33
-
34
- GitHub Pages Compatibility:
35
- - No custom plugins required (jekyll-mermaid is optional)
36
- - All processing done client-side via JavaScript
37
- - Works with remote_theme on GitHub Pages
38
-
39
- Documentation:
40
- - https://mermaid.js.org/
41
- - https://github.com/mermaid-js/mermaid
42
- ===================================================================
43
- -->
2
+ {%- comment -%}
3
+ Component: mermaid
4
+ Path: _includes/components/mermaid.html
5
+ Purpose: Load Mermaid and the theme's diagram-figure behaviour on pages
6
+ that opt in with `mermaid: true` (gated in core/head.html).
7
+ Emits a config block and one deferred script; renders no
8
+ markup itself — every ```mermaid fence (and legacy
9
+ <div class="mermaid">) becomes an accessible <figure> with a
10
+ toolbar (zoom, fullscreen, copy source, download SVG), a
11
+ caption from `accTitle`, and an error state that keeps the
12
+ source on the page.
13
+ Params: none — configured via site.mermaid:
14
+ src (path, default /assets/vendor/mermaid/mermaid.min.js)
15
+ security_level (strict | loose, default strict — `loose` is
16
+ needed only for `click` callbacks / HTML labels)
17
+ toolbar (bool, default true)
18
+ fullscreen (bool, default true)
19
+ download (bool, default true)
20
+ Labels come from _data/ui-text.yml via core/i18n.html so the
21
+ toolbar is translated with the rest of the UI.
22
+ Depends on: assets/vendor/mermaid/mermaid.min.js (vendored, no CDN —
23
+ GitHub Pages-safe), assets/js/mermaid-diagrams.js,
24
+ _sass/components/_mermaid.scss
25
+ Notes: The Mermaid bundle (~1 MB) is NOT emitted as a <script> any
26
+ more. mermaid-diagrams.js (deferred) converts fences into
27
+ figures at execution time, before code-copy.js's
28
+ DOMContentLoaded pass decorates <pre> blocks, and injects the
29
+ bundle from `src` below only when the page has a diagram and
30
+ the first one nears the viewport (IntersectionObserver). A
31
+ `mermaid: true` page without fences never downloads it. It used
32
+ to be a parse-time `defer` script on every opted-in page, and
33
+ before that a synchronous one in <head>. Diagram colours
34
+ are not configured here: the script derives them from the live
35
+ --zer0-*/--bs-* tokens so light/dark/wizard modes and skins
36
+ work without per-mode overrides.
37
+ {%- endcomment -%}
38
+ {%- include core/i18n.html -%}
39
+ {%- assign mm = site.mermaid -%}
40
+ {%- comment -%}
41
+ Liquid's `default` filter treats `false` as missing, so boolean flags are
42
+ resolved with if-tags — an explicit `toolbar: false` must stay false.
43
+ {%- endcomment -%}
44
+ {%- assign mm_toolbar = true -%}
45
+ {%- if mm.toolbar == false -%}{%- assign mm_toolbar = false -%}{%- endif -%}
46
+ {%- assign mm_fullscreen = true -%}
47
+ {%- if mm.fullscreen == false -%}{%- assign mm_fullscreen = false -%}{%- endif -%}
48
+ {%- assign mm_download = true -%}
49
+ {%- if mm.download == false -%}{%- assign mm_download = false -%}{%- endif -%}
50
+ {%- assign mm_src = mm.src | default: '/assets/vendor/mermaid/mermaid.min.js' -%}
44
51
 
45
- <!-- Load Mermaid.js (bundled locally) -->
46
- <script type="text/javascript" src="{{ site.mermaid.src | relative_url }}"></script>
47
-
48
- <!-- Initialize Mermaid with custom configuration -->
49
- <script>
50
- document.addEventListener('DOMContentLoaded', function() {
51
- // ============================================================
52
- // Helper function to detect Bootstrap theme
53
- // ============================================================
54
- function getBootstrapTheme() {
55
- // Check data-bs-theme attribute on html element
56
- var htmlTheme = document.documentElement.getAttribute('data-bs-theme');
57
- if (htmlTheme === 'dark' || htmlTheme === 'wizard') {
58
- return 'dark';
59
- }
60
- if (htmlTheme === 'light') {
61
- return 'light';
62
- }
63
- // Fallback to prefers-color-scheme
64
- if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
65
- return 'dark';
66
- }
67
- return 'light';
68
- }
69
-
70
- // ============================================================
71
- // Helper function to get Mermaid theme configuration
72
- // ============================================================
73
- function getMermaidConfig(theme) {
74
- var isDark = theme === 'dark';
75
-
76
- if (isDark) {
77
- // Dark mode configuration
78
- return {
79
- theme: 'dark',
80
- themeVariables: {
81
- primaryColor: '#0d6efd',
82
- primaryTextColor: '#ffffff',
83
- primaryBorderColor: '#0a58ca',
84
- lineColor: '#6c757d',
85
- secondaryColor: '#6c757d',
86
- tertiaryColor: '#212529',
87
- background: '#212529',
88
- mainBkg: '#212529',
89
- secondBkg: '#343a40',
90
- tertiaryBkg: '#495057',
91
- textColor: '#ffffff',
92
- secondaryTextColor: '#adb5bd',
93
- tertiaryTextColor: '#6c757d',
94
- lineColor: '#6c757d',
95
- border1: '#495057',
96
- border2: '#6c757d',
97
- noteBkgColor: '#343a40',
98
- noteTextColor: '#ffffff',
99
- noteBorderColor: '#6c757d',
100
- actorBkg: '#0d6efd',
101
- actorBorder: '#0a58ca',
102
- actorTextColor: '#ffffff',
103
- actorLineColor: '#ffffff',
104
- signalColor: '#ffffff',
105
- signalTextColor: '#ffffff',
106
- labelBoxBkgColor: '#343a40',
107
- labelBoxBorderColor: '#6c757d',
108
- labelTextColor: '#ffffff',
109
- loopTextColor: '#ffffff',
110
- activationBorderColor: '#0d6efd',
111
- activationBkgColor: '#0d6efd',
112
- sequenceNumberColor: '#ffffff',
113
- sectionBkgColor: '#343a40',
114
- altSectionBkgColor: '#495057',
115
- excludeBkgColor: '#495057',
116
- taskBorderColor: '#0d6efd',
117
- taskBkgColor: '#0d6efd',
118
- taskTextLightColor: '#ffffff',
119
- taskTextColor: '#ffffff',
120
- taskTextDarkColor: '#000000',
121
- taskTextOutsideColor: '#ffffff',
122
- taskTextClickableColor: '#0d6efd',
123
- activeTaskBorderColor: '#0a58ca',
124
- activeTaskBkgColor: '#0a58ca',
125
- gridColor: '#6c757d',
126
- doneTaskBkgColor: '#198754',
127
- doneTaskBorderColor: '#146c43',
128
- critBorderColor: '#dc3545',
129
- critBkgColor: '#dc3545',
130
- todayLineColor: '#ffc107'
131
- }
132
- };
133
- } else {
134
- // Light mode configuration
135
- return {
136
- theme: 'default',
137
- themeVariables: {
138
- primaryColor: '#007bff',
139
- primaryTextColor: '#fff',
140
- primaryBorderColor: '#0056b3',
141
- lineColor: '#6c757d',
142
- secondaryColor: '#6c757d',
143
- tertiaryColor: '#f8f9fa',
144
- background: '#ffffff',
145
- mainBkg: '#ffffff',
146
- secondBkg: '#f8f9fa',
147
- tertiaryBkg: '#e9ecef',
148
- textColor: '#212529',
149
- secondaryTextColor: '#6c757d',
150
- tertiaryTextColor: '#adb5bd'
151
- }
152
- };
153
- }
154
- }
155
-
156
- // ============================================================
157
- // Step 1: Convert native markdown code blocks to mermaid divs
158
- // This enables ```mermaid syntax to work with GitHub Pages
159
- // ============================================================
160
-
161
- // Find all code blocks with language-mermaid class (from ```mermaid)
162
- var codeBlocks = document.querySelectorAll('pre > code.language-mermaid, code.language-mermaid');
163
-
164
- codeBlocks.forEach(function(codeBlock) {
165
- // Get the mermaid content (decode HTML entities)
166
- var content = codeBlock.textContent || codeBlock.innerText;
167
-
168
- // Create a new mermaid div
169
- var mermaidDiv = document.createElement('div');
170
- mermaidDiv.className = 'mermaid';
171
- mermaidDiv.textContent = content;
172
-
173
- // Replace the pre/code block with the mermaid div
174
- var preElement = codeBlock.closest('pre');
175
- if (preElement && preElement.parentNode) {
176
- preElement.parentNode.replaceChild(mermaidDiv, preElement);
177
- } else if (codeBlock.parentNode) {
178
- codeBlock.parentNode.replaceChild(mermaidDiv, codeBlock);
179
- }
180
- });
181
-
182
- // Also handle pre elements that might have data-language="mermaid"
183
- var preBlocks = document.querySelectorAll('pre[data-language="mermaid"]');
184
- preBlocks.forEach(function(preBlock) {
185
- var content = preBlock.textContent || preBlock.innerText;
186
- var mermaidDiv = document.createElement('div');
187
- mermaidDiv.className = 'mermaid';
188
- mermaidDiv.textContent = content;
189
- if (preBlock.parentNode) {
190
- preBlock.parentNode.replaceChild(mermaidDiv, preBlock);
191
- }
192
- });
193
-
194
- // ============================================================
195
- // Step 2: Initialize Mermaid with theme-aware configuration
196
- // ============================================================
197
-
198
- var bootstrapTheme = getBootstrapTheme();
199
- var mermaidThemeConfig = getMermaidConfig(bootstrapTheme);
200
-
201
- mermaid.initialize({
202
- startOnLoad: false, // We'll manually run after conversion
203
- theme: mermaidThemeConfig.theme,
204
- themeVariables: mermaidThemeConfig.themeVariables,
205
- flowchart: {
206
- useMaxWidth: true,
207
- // SVG labels avoid foreignObject clipping/position bugs with theme CSS
208
- htmlLabels: false,
209
- curve: 'basis'
210
- },
211
- sequence: {
212
- diagramMarginX: 50,
213
- diagramMarginY: 10,
214
- actorMargin: 50,
215
- width: 150,
216
- height: 65,
217
- boxMargin: 10,
218
- boxTextMargin: 5,
219
- noteMargin: 10,
220
- messageMargin: 35,
221
- mirrorActors: true,
222
- bottomMarginAdj: 1,
223
- useMaxWidth: true
224
- },
225
- gantt: {
226
- titleTopMargin: 25,
227
- barHeight: 20,
228
- barGap: 4,
229
- topPadding: 50,
230
- leftPadding: 75,
231
- gridLineStartPadding: 35,
232
- fontSize: 11,
233
- numberSectionStyles: 4,
234
- axisFormat: '%Y-%m-%d'
235
- },
236
- securityLevel: 'loose' // Required for some advanced features
237
- });
238
-
239
- // ============================================================
240
- // Step 3: Render all mermaid diagrams
241
- // ============================================================
242
-
243
- // Run mermaid to render all .mermaid divs
244
- mermaid.run().then(function() {
245
- console.log('Mermaid.js: All diagrams rendered successfully with theme:', bootstrapTheme);
246
- }).catch(function(error) {
247
- console.warn('Mermaid.js: Some diagrams failed to render', error);
248
- });
249
-
250
- // ============================================================
251
- // Step 4: Watch for theme changes and re-render diagrams
252
- // ============================================================
253
-
254
- // Create a MutationObserver to watch for theme changes
255
- var themeObserver = new MutationObserver(function(mutations) {
256
- mutations.forEach(function(mutation) {
257
- if (mutation.type === 'attributes' && mutation.attributeName === 'data-bs-theme') {
258
- var newTheme = getBootstrapTheme();
259
- var newMermaidConfig = getMermaidConfig(newTheme);
260
-
261
- // Update Mermaid configuration
262
- mermaid.initialize({
263
- startOnLoad: false,
264
- theme: newMermaidConfig.theme,
265
- themeVariables: newMermaidConfig.themeVariables,
266
- flowchart: {
267
- useMaxWidth: true,
268
- htmlLabels: false,
269
- curve: 'basis'
270
- },
271
- sequence: {
272
- diagramMarginX: 50,
273
- diagramMarginY: 10,
274
- actorMargin: 50,
275
- width: 150,
276
- height: 65,
277
- boxMargin: 10,
278
- boxTextMargin: 5,
279
- noteMargin: 10,
280
- messageMargin: 35,
281
- mirrorActors: true,
282
- bottomMarginAdj: 1,
283
- useMaxWidth: true
284
- },
285
- gantt: {
286
- titleTopMargin: 25,
287
- barHeight: 20,
288
- barGap: 4,
289
- topPadding: 50,
290
- leftPadding: 75,
291
- gridLineStartPadding: 35,
292
- fontSize: 11,
293
- numberSectionStyles: 4,
294
- axisFormat: '%Y-%m-%d'
295
- },
296
- securityLevel: 'loose'
297
- });
298
-
299
- // Re-render all diagrams with new theme
300
- var mermaidDivs = document.querySelectorAll('.mermaid');
301
- mermaidDivs.forEach(function(div) {
302
- var content = div.textContent || div.innerText;
303
- div.innerHTML = '';
304
- div.textContent = content;
305
- });
306
-
307
- mermaid.run().then(function() {
308
- console.log('Mermaid.js: Diagrams re-rendered with theme:', newTheme);
309
- }).catch(function(error) {
310
- console.warn('Mermaid.js: Some diagrams failed to re-render', error);
311
- });
312
- }
313
- });
314
- });
315
-
316
- // Start observing the html element for theme changes
317
- themeObserver.observe(document.documentElement, {
318
- attributes: true,
319
- attributeFilter: ['data-bs-theme']
320
- });
321
- });
52
+ {% comment %} Diagram configuration consumed by assets/js/mermaid-diagrams.js {% endcomment %}
53
+ <script id="mermaidConfig" type="application/json">
54
+ {
55
+ "securityLevel": {{ mm.security_level | default: "strict" | jsonify }},
56
+ "toolbar": {{ mm_toolbar | jsonify }},
57
+ "fullscreen": {{ mm_fullscreen | jsonify }},
58
+ "download": {{ mm_download | jsonify }},
59
+ "labels": {
60
+ "diagram": {{ ui.diagram_label | default: "Diagram" | jsonify }},
61
+ "tools": {{ ui.diagram_tools_label | default: "Diagram tools" | jsonify }},
62
+ "zoomIn": {{ ui.diagram_zoom_in | default: "Zoom in" | jsonify }},
63
+ "zoomOut": {{ ui.diagram_zoom_out | default: "Zoom out" | jsonify }},
64
+ "zoomReset": {{ ui.diagram_zoom_reset | default: "Reset zoom" | jsonify }},
65
+ "fullscreen": {{ ui.diagram_fullscreen | default: "View fullscreen" | jsonify }},
66
+ "close": {{ ui.diagram_fullscreen_close | default: "Close fullscreen view" | jsonify }},
67
+ "copy": {{ ui.diagram_copy_source | default: "Copy diagram source" | jsonify }},
68
+ "copied": {{ ui.diagram_copied | default: "Copied" | jsonify }},
69
+ "copyFailed": {{ ui.diagram_copy_failed | default: "Copy failed" | jsonify }},
70
+ "download": {{ ui.diagram_download | default: "Download as SVG" | jsonify }},
71
+ "errorTitle": {{ ui.diagram_error_title | default: "This diagram could not be rendered" | jsonify }},
72
+ "errorHint": {{ ui.diagram_error_hint | default: "Check the syntax in the Mermaid Live Editor. The source is shown below so nothing is lost." | jsonify }},
73
+ "showSource": {{ ui.diagram_source_label | default: "Diagram source" | jsonify }},
74
+ "loading": {{ ui.diagram_loading | default: "Loading diagram" | jsonify }}
75
+ }
76
+ }
322
77
  </script>
323
-
324
- <!-- Custom CSS for Mermaid diagrams -->
325
- <style>
326
- /* Mermaid container styling */
327
- .mermaid {
328
- text-align: center;
329
- margin: 2rem auto;
330
- background-color: transparent;
331
- overflow-x: auto;
332
- padding: 1rem;
333
- border-radius: 0.5rem;
334
- transition: background-color 0.3s ease;
335
- }
336
-
337
- /* Ensure diagrams are responsive */
338
- .mermaid svg {
339
- max-width: 100%;
340
- height: auto;
341
- display: block;
342
- margin: 0 auto;
343
- }
344
-
345
- /* Hide code blocks before conversion (prevent flash of unstyled content) */
346
- pre > code.language-mermaid,
347
- code.language-mermaid {
348
- display: block;
349
- opacity: 0;
350
- transition: opacity 0.2s;
351
- }
352
-
353
- /* Dark mode compatibility - Bootstrap theme aware */
354
- [data-bs-theme="dark"] .mermaid {
355
- background-color: rgba(33, 37, 41, 0.5);
356
- border: 1px solid rgba(108, 117, 125, 0.2);
357
- }
358
-
359
- [data-bs-theme="dark"] .mermaid svg {
360
- /* Ensure SVG elements are visible in dark mode */
361
- color-scheme: dark;
362
- }
363
-
364
- [data-bs-theme="dark"] .mermaid svg text {
365
- fill: #ffffff !important;
366
- }
367
-
368
- [data-bs-theme="dark"] .mermaid svg .node rect,
369
- [data-bs-theme="dark"] .mermaid svg .node polygon,
370
- [data-bs-theme="dark"] .mermaid svg .cluster rect {
371
- fill: #343a40 !important;
372
- stroke: #6c757d !important;
373
- }
374
-
375
- [data-bs-theme="dark"] .mermaid svg .edgePath .path {
376
- stroke: #6c757d !important;
377
- }
378
-
379
- [data-bs-theme="dark"] .mermaid svg .edgeLabel {
380
- background-color: #212529 !important;
381
- color: #ffffff !important;
382
- }
383
-
384
- [data-bs-theme="dark"] .mermaid svg .edgeLabel text {
385
- fill: #ffffff !important;
386
- }
387
-
388
- /* Light mode styling */
389
- [data-bs-theme="light"] .mermaid {
390
- background-color: rgba(248, 249, 250, 0.5);
391
- border: 1px solid rgba(0, 0, 0, 0.1);
392
- }
393
-
394
- [data-bs-theme="light"] .mermaid svg text {
395
- fill: #212529 !important;
396
- }
397
-
398
- /* Fallback for prefers-color-scheme if data-bs-theme is not set */
399
- @media (prefers-color-scheme: dark) {
400
- html:not([data-bs-theme]) .mermaid {
401
- background-color: rgba(33, 37, 41, 0.5);
402
- border: 1px solid rgba(108, 117, 125, 0.2);
403
- }
404
- }
405
-
406
- /* Smooth theme transition */
407
- .mermaid svg {
408
- transition: opacity 0.3s ease;
409
- }
410
-
411
- /* Loading state */
412
- .mermaid:not(:has(svg)) {
413
- min-height: 100px;
414
- display: flex;
415
- align-items: center;
416
- justify-content: center;
417
- }
418
-
419
- .mermaid:not(:has(svg))::after {
420
- content: 'Loading diagram...';
421
- color: var(--bs-secondary);
422
- font-size: 0.875rem;
423
- }
424
-
425
- /* Print styles */
426
- @media print {
427
- .mermaid {
428
- background-color: transparent !important;
429
- border: none !important;
430
- page-break-inside: avoid;
431
- }
432
-
433
- .mermaid svg {
434
- max-width: 100% !important;
435
- page-break-inside: avoid;
436
- }
437
- }
438
- </style>
78
+ {% comment %} Bundle URL for the lazy loader. Passed as a script global rather than
79
+ through the JSON block above: a URL read back out of DOM text and assigned
80
+ to script.src is a script-injection sink (CodeQL js/xss-through-dom). {% endcomment %}
81
+ <script>window.zer0MermaidSrc = {{ mm_src | relative_url | jsonify }};</script>
82
+ <script defer src="{{ '/assets/js/mermaid-diagrams.js' | relative_url }}"></script>
@@ -1,5 +1,5 @@
1
1
  {% comment %} Feature: ZER0-066 {% endcomment %}
2
- <!--
2
+ {% comment %}
3
3
  ===================================================================
4
4
  NANOBAR - Config-Driven Page Loading Progress Bar
5
5
  ===================================================================
@@ -42,7 +42,7 @@
42
42
 
43
43
  Library: https://github.com/jacoborus/nanobar
44
44
  ===================================================================
45
- -->
45
+ {% endcomment %}
46
46
 
47
47
  {%- assign nb = site.nanobar | default: empty -%}
48
48
  {%- if nb == empty or nb.enabled != false -%}
@@ -62,7 +62,7 @@
62
62
  {%- assign nb_steps = "30,76,100" | split: "," -%}
63
63
  {%- endif -%}
64
64
 
65
- <!-- ── Nanobar theme CSS (config-driven custom properties) ── -->
65
+ {% comment %} ── Nanobar theme CSS (config-driven custom properties) ── {% endcomment %}
66
66
  <style id="nanobar-theme">
67
67
  :root {
68
68
  --nanobar-color: {{ nb_color }};
@@ -99,11 +99,11 @@
99
99
  }
100
100
  </style>
101
101
 
102
- <!-- ── Nanobar scripts ── -->
102
+ {% comment %} ── Nanobar scripts ── {% endcomment %}
103
103
  <script defer src="{{ '/assets/js/nanobar.min.js' | relative_url }}"></script>
104
104
  <script defer src="{{ '/assets/js/nanobar-init.js' | relative_url }}"></script>
105
105
 
106
- <!-- ── Bridge _config.yml values to JS ── -->
106
+ {% comment %} ── Bridge _config.yml values to JS ── {% endcomment %}
107
107
  <script>
108
108
  window.zer0Nanobar = {
109
109
  classname: {{ nb_classname | jsonify }},
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  NAV EDITOR — Read-only navigation tree view
4
4
  ===================================================================
@@ -12,7 +12,7 @@
12
12
  _data/navigation/*.yml
13
13
  Used by: pages/_about/settings/navigation.md
14
14
  ===================================================================
15
- -->
15
+ {% endcomment %}
16
16
 
17
17
  {% assign nav_files = "main,home,about,docs,posts,quickstart,admin" | split: "," %}
18
18
 
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  NAV EXPORT — Export navigation data as YAML
4
4
  ===================================================================
@@ -12,7 +12,7 @@
12
12
  _data/navigation/*.yml
13
13
  Used by: pages/_about/settings/navigation.md
14
14
  ===================================================================
15
- -->
15
+ {% endcomment %}
16
16
 
17
17
  {% assign nav_files = "main,home,about,docs,posts,quickstart,admin" | split: "," %}
18
18
 
@@ -1,4 +1,4 @@
1
- <!--
1
+ {% comment %}
2
2
  ===================================================================
3
3
  NAV OVERVIEW — Navigation structure summary
4
4
  ===================================================================
@@ -12,7 +12,7 @@
12
12
  _data/navigation/*.yml
13
13
  Used by: pages/_about/settings/navigation.md
14
14
  ===================================================================
15
- -->
15
+ {% endcomment %}
16
16
 
17
17
  {% assign nav_files = "main,home,about,docs,posts,quickstart,admin" | split: "," %}
18
18