jekyll-theme-zer0 1.28.0 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1143 -13
  3. data/_data/README.md +2 -0
  4. data/_data/ai.yml +5 -3
  5. data/_data/ai_pricing.yml +36 -0
  6. data/_data/backlog.yml +507 -2
  7. data/_data/consumers.yml +157 -9
  8. data/_data/features.yml +303 -20
  9. data/_data/feedback_types.yml +17 -12
  10. data/_data/i18n/fr.yml +12 -7
  11. data/_data/i18n/manifest.yml +39 -12
  12. data/_data/ingredient_densities.yml +122 -0
  13. data/_data/landing.yml +5 -2
  14. data/_data/navigation/main.yml +16 -0
  15. data/_data/navigation/quickstart.yml +4 -0
  16. data/_data/recipe_courses.yml +64 -0
  17. data/_data/site_builder.yml +874 -0
  18. data/_data/theme-manifest.yml +160 -124
  19. data/_data/ui-text.yml +26 -0
  20. data/_includes/README.md +26 -2
  21. data/_includes/analytics/posthog.html +2 -2
  22. data/_includes/components/admin-links.html +2 -2
  23. data/_includes/components/admin-tabs.html +2 -2
  24. data/_includes/components/ai-chat.html +14 -11
  25. data/_includes/components/analytics-dashboard.html +8 -8
  26. data/_includes/components/author-bio.html +1 -1
  27. data/_includes/components/author-card.html +10 -2
  28. data/_includes/components/author-eeat.html +4 -4
  29. data/_includes/components/background-customizer.html +10 -10
  30. data/_includes/components/background-image.html +114 -0
  31. data/_includes/components/background-settings.html +28 -15
  32. data/_includes/components/collection-manager.html +5 -5
  33. data/_includes/components/component-showcase.html +13 -13
  34. data/_includes/components/config-editor.html +12 -12
  35. data/_includes/components/config-viewer.html +8 -8
  36. data/_includes/components/cookie-consent.html +15 -15
  37. data/_includes/components/cta-button.html +7 -2
  38. data/_includes/components/dev-shortcuts.html +7 -7
  39. data/_includes/components/env-dashboard.html +8 -8
  40. data/_includes/components/env-switcher.html +9 -9
  41. data/_includes/components/feature-card.html +2 -2
  42. data/_includes/components/halfmoon.html +2 -2
  43. data/_includes/components/info-section.html +42 -37
  44. data/_includes/components/js-cdn.html +15 -15
  45. data/_includes/components/language-toggle.html +168 -21
  46. data/_includes/components/mermaid.html +72 -435
  47. data/_includes/components/nanobar.html +5 -5
  48. data/_includes/components/nav-editor.html +2 -2
  49. data/_includes/components/nav-export.html +2 -2
  50. data/_includes/components/nav-overview.html +2 -2
  51. data/_includes/components/page-feedback.html +45 -30
  52. data/_includes/components/page-views-init.html +55 -0
  53. data/_includes/components/page-views.html +33 -0
  54. data/_includes/components/post-card.html +22 -22
  55. data/_includes/components/post-type-badge.html +2 -2
  56. data/_includes/components/powered-by.html +2 -2
  57. data/_includes/components/preview-image.html +6 -0
  58. data/_includes/components/quick-index.html +2 -2
  59. data/_includes/components/recipe-card.html +67 -0
  60. data/_includes/components/recipe-duration.html +50 -0
  61. data/_includes/components/recipe-grams.html +58 -0
  62. data/_includes/components/recipe-index.html +96 -0
  63. data/_includes/components/recipe-ingredients.html +90 -0
  64. data/_includes/components/recipe-meta.html +96 -0
  65. data/_includes/components/recipe-nutrition.html +57 -0
  66. data/_includes/components/recipe-qty.html +73 -0
  67. data/_includes/components/recipe-ratio.html +151 -0
  68. data/_includes/components/recipe-scaler.html +73 -0
  69. data/_includes/components/recipe-steps.html +86 -0
  70. data/_includes/components/recipe-temp.html +45 -0
  71. data/_includes/components/search-modal.html +29 -4
  72. data/_includes/components/searchbar.html +2 -2
  73. data/_includes/components/shortcuts-modal.html +3 -0
  74. data/_includes/components/svg-background.html +2 -2
  75. data/_includes/components/theme-customizer.html +2 -2
  76. data/_includes/components/theme-info.html +14 -7
  77. data/_includes/components/theme-preview-gallery.html +22 -22
  78. data/_includes/content/giscus.html +2 -2
  79. data/_includes/content/intro.html +8 -8
  80. data/_includes/content/jsonld-faq.html +2 -2
  81. data/_includes/content/jsonld-software.html +24 -5
  82. data/_includes/content/seo.html +4 -4
  83. data/_includes/content/sitemap.html +27 -27
  84. data/_includes/content/toc.html +183 -183
  85. data/_includes/core/branding.html +6 -6
  86. data/_includes/core/console-capture.html +32 -74
  87. data/_includes/core/favicon.html +49 -7
  88. data/_includes/core/footer-fabs.html +17 -3
  89. data/_includes/core/footer.html +49 -34
  90. data/_includes/core/head.html +110 -86
  91. data/_includes/core/header.html +76 -54
  92. data/_includes/docs/bootstrap-docs.html +8 -8
  93. data/_includes/landing/landing-install-cards.html +2 -2
  94. data/_includes/landing/landing-quick-links.html +1 -1
  95. data/_includes/navigation/admin-nav.html +2 -2
  96. data/_includes/navigation/nav-tree.html +8 -8
  97. data/_includes/navigation/navbar.html +12 -12
  98. data/_includes/navigation/section-sidebar.html +109 -27
  99. data/_includes/navigation/sidebar-config.html +36 -2
  100. data/_includes/navigation/sidebar-left.html +17 -16
  101. data/_includes/navigation/sidebar-right.html +8 -7
  102. data/_includes/obsidian/full-graph.html +2 -2
  103. data/_includes/setup/claude-session.html +72 -0
  104. data/_includes/setup/prereq-checklist.html +90 -0
  105. data/_includes/setup/wizard.html +924 -222
  106. data/_includes/stats/stats-categories.html +8 -8
  107. data/_includes/stats/stats-header.html +14 -14
  108. data/_includes/stats/stats-metrics.html +14 -14
  109. data/_includes/stats/stats-no-data.html +12 -12
  110. data/_includes/stats/stats-overview.html +6 -6
  111. data/_includes/stats/stats-tags.html +8 -8
  112. data/_layouts/404.html +38 -24
  113. data/_layouts/README.md +2 -0
  114. data/_layouts/admin.html +24 -24
  115. data/_layouts/article.html +43 -33
  116. data/_layouts/author.html +20 -20
  117. data/_layouts/authors.html +2 -2
  118. data/_layouts/book-abc.html +12 -12
  119. data/_layouts/book-story.html +15 -15
  120. data/_layouts/book.html +12 -12
  121. data/_layouts/collection.html +33 -33
  122. data/_layouts/cookbook.html +88 -0
  123. data/_layouts/default.html +31 -28
  124. data/_layouts/home.html +23 -23
  125. data/_layouts/index.html +10 -10
  126. data/_layouts/landing.html +17 -17
  127. data/_layouts/news.html +44 -44
  128. data/_layouts/note.html +38 -38
  129. data/_layouts/notebook.html +34 -34
  130. data/_layouts/recipe.html +274 -0
  131. data/_layouts/root.html +92 -55
  132. data/_layouts/section.html +62 -33
  133. data/_layouts/setup.html +3 -3
  134. data/_layouts/sitemap-collection.html +49 -49
  135. data/_layouts/stats.html +40 -40
  136. data/_layouts/tag.html +12 -12
  137. data/_layouts/welcome.html +21 -21
  138. data/_sass/components/_callout.scss +1 -1
  139. data/_sass/components/_footer.scss +37 -1
  140. data/_sass/components/_mermaid.scss +375 -0
  141. data/_sass/components/_page-views.scss +36 -0
  142. data/_sass/components/_recipe.scss +506 -0
  143. data/_sass/components/_setup-wizard.scss +764 -0
  144. data/_sass/components/_ui-enhancements.scss +6 -6
  145. data/_sass/core/_navbar.scss +261 -46
  146. data/_sass/layouts/_landing.scss +2 -2
  147. data/_sass/layouts/_navbar-extras.scss +14 -4
  148. data/_sass/tokens/_color.scss +6 -0
  149. data/_sass/tokens/_index.scss +2 -0
  150. data/_sass/tokens/_radius.scss +21 -0
  151. data/_sass/tokens/_typography.scss +4 -0
  152. data/_sass/utilities/_focus.scss +14 -0
  153. data/assets/css/main.scss +4 -0
  154. data/assets/js/ai-chat.js +47 -5
  155. data/assets/js/fleet-feedback-capture.js +124 -0
  156. data/assets/js/fleet-feedback.js +853 -0
  157. data/assets/js/mermaid-diagrams.js +1267 -0
  158. data/assets/js/modules/navigation/config.js +9 -6
  159. data/assets/js/modules/navigation/navbar.js +55 -0
  160. data/assets/js/modules/navigation/scroll-spy.js +315 -80
  161. data/assets/js/modules/theme/appearance.js +8 -2
  162. data/assets/js/obsidian-wiki-links.js +8 -3
  163. data/assets/js/page-feedback.js +125 -192
  164. data/assets/js/page-views.js +372 -0
  165. data/assets/js/recipe-scaler.js +501 -0
  166. data/assets/js/search-modal.js +36 -0
  167. data/assets/js/setup-wizard.js +2279 -226
  168. data/assets/js/site-builder.js +1834 -0
  169. data/assets/js/ui-enhancements.js +11 -3
  170. data/scripts/README.md +44 -0
  171. data/scripts/ai/README.md +38 -0
  172. data/scripts/ai/api_call.rb +124 -0
  173. data/scripts/ai/usage.rb +314 -0
  174. data/scripts/ai/usage_report.rb +225 -0
  175. data/scripts/bin/audit-consumer +39 -7
  176. data/scripts/bin/giscus-discussions +213 -14
  177. data/scripts/bin/manifest +35 -12
  178. data/scripts/ci/agent_review_result.py +164 -0
  179. data/scripts/ci/test_agent_review_result.py +172 -0
  180. data/scripts/ci/test_visual_evidence_autogen.py +341 -0
  181. data/scripts/ci/visual_evidence_autogen.py +1060 -0
  182. data/scripts/content-review.rb +20 -1
  183. data/scripts/design-system-check.rb +170 -0
  184. data/scripts/lib/audit.sh +42 -2
  185. data/scripts/lint-liquid-raw.rb +137 -0
  186. data/scripts/test/integration/mermaid +22 -8
  187. data/scripts/test/lib/run_tests.sh +3 -1
  188. data/scripts/test/lib/test_agent_review_result.sh +27 -0
  189. data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
  190. data/scripts/translate.rb +94 -16
  191. metadata +48 -2
@@ -0,0 +1,874 @@
1
+ # Feature: ZER0-086
2
+ # Feature: ZER0-087
3
+ # =============================================================================
4
+ # _data/site_builder.yml — one source for the guided Site Builder
5
+ # -----------------------------------------------------------------------------
6
+ # Read by:
7
+ # _includes/setup/wizard.html step list, prerequisites, catalogs
8
+ # _includes/setup/prereq-checklist.html per-OS install + verify commands
9
+ # _includes/setup/claude-session.html serialised as JSON for the browser
10
+ # assets/js/setup-wizard.js catalogs (skins, tones, collections)
11
+ # assets/js/site-builder.js the AI session's framework brief,
12
+ # provider catalog, session modes and
13
+ # suggested prompts
14
+ #
15
+ # Everything the wizard "knows" about the framework lives here so the form,
16
+ # the generated files, and the AI brief cannot drift apart. Prerequisite
17
+ # commands mirror pages/_quickstart/machine-setup.md — keep them in sync.
18
+ # =============================================================================
19
+
20
+ # ── Steps ─────────────────────────────────────────────────────────────────────
21
+ # Order is the stepper order. `prompts` are the suggested asks shown as chips
22
+ # in the Claude panel while that step is active.
23
+ steps:
24
+ - id: connect
25
+ label: "Connect"
26
+ icon: bi-plug
27
+ summary: "Connect Claude or Grok through the local dev proxy — your own token, your choice of model and session style — or continue without AI."
28
+ prompts:
29
+ - "What do I need to run locally so you can help me build this site?"
30
+ - "Explain what the Site Builder will generate for me."
31
+ - "What can you do in an open session that the guided steps don't cover?"
32
+ - id: prereqs
33
+ label: "Prerequisites"
34
+ icon: bi-laptop
35
+ summary: "Docker, Git, GitHub CLI and an editor — checked live where possible."
36
+ prompts:
37
+ - "Run the prerequisite checks and tell me what is missing."
38
+ - "Which install commands should I run on my operating system?"
39
+ - id: identity
40
+ label: "Identity"
41
+ icon: bi-person-badge
42
+ summary: "Title, description, author and the story behind the site."
43
+ prompts:
44
+ - "Here is what my site is about — draft a title, tagline and description."
45
+ - "Suggest three title options with a one-line rationale each."
46
+ - id: urls
47
+ label: "URLs"
48
+ icon: bi-link-45deg
49
+ summary: "GitHub user, repository, deployment URL and base path."
50
+ prompts:
51
+ - "Work out my url and baseurl from my GitHub user and repo name."
52
+ - "Should this be a user site or a project site?"
53
+ - id: structure
54
+ label: "Structure"
55
+ icon: bi-diagram-3
56
+ summary: "Collections to enable and the main navigation."
57
+ prompts:
58
+ - "Design the site plan: landing page template and sections, navigation style, and 5–6 example pages with real content — then apply it."
59
+ - "Recommend collections and a navigation menu for this kind of site."
60
+ - "Explain the difference between posts, docs and notes in this theme."
61
+ - id: appearance
62
+ label: "Appearance"
63
+ icon: bi-palette
64
+ summary: "Skin, colour mode, hero and background layers."
65
+ prompts:
66
+ - "Pick a skin, palette, font pairing and corner style that suit the site's tone, and apply them."
67
+ - "What does each skin look like and which fits a technical blog?"
68
+ - id: voice
69
+ label: "Voice"
70
+ icon: bi-chat-quote
71
+ summary: "Tone, audience, and the first post + about page drafts."
72
+ prompts:
73
+ - "Write the welcome post and about page in the tone I selected."
74
+ - "Rewrite the about page draft to be shorter and warmer."
75
+ - id: integrations
76
+ label: "Integrations"
77
+ icon: bi-plugin
78
+ summary: "Analytics, comments, the AI assistant and page feedback."
79
+ prompts:
80
+ - "Which integrations make sense for a small personal site?"
81
+ - "How do I get Giscus IDs for my repository?"
82
+ - id: build
83
+ label: "Build"
84
+ icon: bi-rocket-takeoff
85
+ summary: "Review every generated file, write the project, start Docker — or open an existing site and modify it."
86
+ prompts:
87
+ - "Review the generated files for mistakes before I write them."
88
+ - "Write the project to my target folder and start the dev server."
89
+ - "The build failed — read the logs and tell me what to fix."
90
+ - "Open the site I already wrote and add a post about my first week with it."
91
+
92
+ # ── AI providers the Connect step offers ─────────────────────────────────────
93
+ # The dev proxy (templates/deploy/chat-proxy/providers.js) is authoritative for
94
+ # what is configured, which models exist and what a token looks like; this is
95
+ # the UI copy. Order = card order.
96
+ providers:
97
+ - id: anthropic
98
+ label: "Claude"
99
+ vendor: "Anthropic"
100
+ icon: bi-stars
101
+ description: "Claude Code OAuth token (Pro/Max, from `claude setup-token`) or an Anthropic API key."
102
+ token_placeholder: "sk-ant-oat01-… or sk-ant-api…"
103
+ token_hint: "Mint one with `claude setup-token`, or create an API key at console.anthropic.com."
104
+ console: "https://console.anthropic.com/"
105
+ env: "CLAUDE_CODE_OAUTH_TOKEN"
106
+ models: [claude-opus-4-8, claude-opus-5, claude-sonnet-5, claude-haiku-4-5]
107
+ - id: xai
108
+ label: "Grok"
109
+ vendor: "xAI"
110
+ icon: bi-x-diamond
111
+ description: "xAI API key — Grok for the session, Grok Imagine for images."
112
+ token_placeholder: "xai-…"
113
+ token_hint: "Create a key at console.x.ai (API keys)."
114
+ console: "https://console.x.ai/"
115
+ env: "XAI_API_KEY"
116
+ models: [grok-4.6, grok-4.5, grok-4.3]
117
+
118
+ # Image renderers the session can use (generate_image) and the generated site
119
+ # can be pre-configured for (preview_images in _config.yml).
120
+ image_providers:
121
+ - id: xai
122
+ label: "Grok Imagine"
123
+ vendor: "xAI"
124
+ env: "XAI_API_KEY"
125
+ model: "grok-imagine-image-2.0"
126
+ - id: openai
127
+ label: "OpenAI Images"
128
+ vendor: "OpenAI"
129
+ env: "OPENAI_API_KEY"
130
+ model: "gpt-image-2"
131
+
132
+ # How the session works. `guided` follows the nine steps; `open` is chat-driven
133
+ # and any order — create, open an existing site, edit files, generate images,
134
+ # rebuild — like a coding session in a terminal.
135
+ session_modes:
136
+ - id: guided
137
+ label: "Guided steps"
138
+ icon: bi-signpost-2
139
+ description: "Walk the nine steps; the assistant suggests values and fills each one in."
140
+ - id: open
141
+ label: "Open session"
142
+ icon: bi-terminal
143
+ description: "Just talk: build from a brief, open an existing site, edit files, generate images, rebuild — in any order."
144
+
145
+ open_session:
146
+ prompts:
147
+ - "Build me a complete site from this brief: {brief}"
148
+ - "Open my existing site and tell me what you would improve first."
149
+ - "Generate a hero image for the landing page in the site's palette and wire it in."
150
+ - "Add a new post about the project's first milestone and rebuild the site."
151
+ - "Run jekyll build and fix anything that fails."
152
+
153
+ # ── Prerequisites ─────────────────────────────────────────────────────────────
154
+ # `check` is the id of an allow-listed command in
155
+ # templates/deploy/chat-proxy/wizard-store.mjs (dev proxy only). The install
156
+ # and verify commands are shown per OS and mirror machine-setup.md.
157
+ prerequisites:
158
+ - id: docker
159
+ label: "Docker Desktop"
160
+ required: true
161
+ icon: bi-box-seam
162
+ why: "Runs Jekyll in a container so you never fight Ruby versions."
163
+ check: docker
164
+ verify: "docker --version && docker compose version"
165
+ install:
166
+ macos: "brew install --cask docker"
167
+ windows: "winget install Docker.DockerDesktop"
168
+ linux: "curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER"
169
+ docs: "https://docs.docker.com/get-docker/"
170
+ - id: docker-daemon
171
+ label: "Docker engine running"
172
+ required: true
173
+ icon: bi-play-circle
174
+ why: "The compose commands need the engine up, not just installed."
175
+ check: docker-daemon
176
+ verify: "docker info --format '{{.ServerVersion}}'"
177
+ install:
178
+ macos: "open -a Docker"
179
+ windows: "Start Docker Desktop from the Start menu"
180
+ linux: "sudo systemctl start docker"
181
+ docs: "https://docs.docker.com/config/daemon/start/"
182
+ - id: git
183
+ label: "Git"
184
+ required: true
185
+ icon: bi-git
186
+ why: "Version control for your site and the theme's release flow."
187
+ check: git
188
+ verify: "git --version"
189
+ install:
190
+ macos: "brew install git"
191
+ windows: "winget install Git.Git"
192
+ linux: "sudo apt install git"
193
+ docs: "https://git-scm.com/downloads"
194
+ - id: git-config
195
+ label: "Git identity configured"
196
+ required: true
197
+ icon: bi-person-vcard
198
+ why: "Commits need a name and email; use your GitHub no-reply address."
199
+ check: git-config
200
+ verify: "git config --global --list | grep user"
201
+ install:
202
+ macos: "git config --global user.name \"YourGitHubUsername\" && git config --global user.email \"ID+username@users.noreply.github.com\""
203
+ windows: "git config --global user.name \"YourGitHubUsername\" ; git config --global user.email \"ID+username@users.noreply.github.com\""
204
+ linux: "git config --global user.name \"YourGitHubUsername\" && git config --global user.email \"ID+username@users.noreply.github.com\""
205
+ docs: "https://github.com/settings/emails"
206
+ - id: gh
207
+ label: "GitHub CLI"
208
+ required: true
209
+ icon: bi-github
210
+ why: "Creates the repository and enables GitHub Pages from the terminal."
211
+ check: gh
212
+ verify: "gh --version"
213
+ install:
214
+ macos: "brew install gh"
215
+ windows: "winget install GitHub.cli"
216
+ linux: "sudo apt install gh"
217
+ docs: "https://cli.github.com/manual/installation"
218
+ - id: gh-auth
219
+ label: "GitHub CLI signed in"
220
+ required: false
221
+ icon: bi-shield-check
222
+ why: "Needed to push and to turn on Pages; the local build works without it."
223
+ check: gh-auth
224
+ verify: "gh auth status"
225
+ install:
226
+ macos: "gh auth login"
227
+ windows: "gh auth login"
228
+ linux: "gh auth login"
229
+ docs: "https://cli.github.com/manual/gh_auth_login"
230
+ - id: code
231
+ label: "VS Code"
232
+ required: false
233
+ icon: bi-code-square
234
+ why: "Recommended editor with Jekyll, Liquid and Docker extensions."
235
+ check: code
236
+ verify: "code --version"
237
+ install:
238
+ macos: "brew install --cask visual-studio-code"
239
+ windows: "winget install Microsoft.VisualStudioCode"
240
+ linux: "sudo snap install code --classic"
241
+ docs: "https://code.visualstudio.com/"
242
+ - id: node
243
+ label: "Node.js 20.6+"
244
+ required: false
245
+ icon: bi-hexagon
246
+ why: "Runs the local Claude dev proxy (node --env-file) that powers this wizard's AI."
247
+ check: node
248
+ verify: "node --version"
249
+ install:
250
+ macos: "brew install node"
251
+ windows: "winget install OpenJS.NodeJS.LTS"
252
+ linux: "sudo apt install nodejs"
253
+ docs: "https://nodejs.org/"
254
+ - id: claude
255
+ label: "Claude Code CLI"
256
+ required: false
257
+ icon: bi-stars
258
+ why: "`claude setup-token` mints a Claude OAuth token for the session (an xAI key from console.x.ai works instead)."
259
+ check: claude
260
+ verify: "claude --version"
261
+ install:
262
+ macos: "npm install -g @anthropic-ai/claude-code"
263
+ windows: "npm install -g @anthropic-ai/claude-code"
264
+ linux: "npm install -g @anthropic-ai/claude-code"
265
+ docs: "https://docs.anthropic.com/en/docs/claude-code"
266
+
267
+ # ── Catalogs the form and the generators share ───────────────────────────────
268
+ collections:
269
+ - id: posts
270
+ label: "Posts"
271
+ icon: bi-journal-text
272
+ layout: article
273
+ permalink: "/posts/:title/"
274
+ default: true
275
+ description: "Dated articles listed newest-first; the blog."
276
+ - id: docs
277
+ label: "Docs"
278
+ icon: bi-book
279
+ layout: default
280
+ permalink: "/docs/:path/"
281
+ default: true
282
+ description: "Evergreen guides with a sidebar tree."
283
+ - id: about
284
+ label: "About"
285
+ icon: bi-info-circle
286
+ layout: default
287
+ permalink: "/about/:path/"
288
+ default: true
289
+ description: "Who you are, contact, and site settings pages."
290
+ - id: notes
291
+ label: "Notes"
292
+ icon: bi-sticky
293
+ layout: note
294
+ permalink: "/notes/:path/"
295
+ default: false
296
+ description: "Short Obsidian-style notes with [[wiki-links]] and backlinks."
297
+ - id: quickstart
298
+ label: "Quickstart"
299
+ icon: bi-flag
300
+ layout: default
301
+ permalink: "/quickstart/:path/"
302
+ default: false
303
+ description: "Ordered onboarding steps with prev/next navigation."
304
+ - id: notebooks
305
+ label: "Notebooks"
306
+ icon: bi-journal-code
307
+ layout: notebook
308
+ permalink: "/notebooks/:path/"
309
+ default: false
310
+ description: "Rendered Jupyter notebooks."
311
+ - id: quests
312
+ label: "Quests"
313
+ icon: bi-controller
314
+ layout: default
315
+ permalink: "/quests/:path/"
316
+ default: false
317
+ description: "Gamified learning paths with levels and badges."
318
+ - id: recipes
319
+ label: "Recipes"
320
+ icon: bi-egg-fried
321
+ layout: recipe
322
+ permalink: "/recipes/:path/"
323
+ default: false
324
+ description: "A cookbook: structured recipes with serving scaling and unit conversion."
325
+
326
+ skins:
327
+ - id: air
328
+ label: "Air"
329
+ mood: "Light, calm, airy blues"
330
+ primary: "#e8f4f8"
331
+ accent: "#6fa8dc"
332
+ - id: aqua
333
+ label: "Aqua"
334
+ mood: "Deep ocean blue with bright cyan"
335
+ primary: "#0077b6"
336
+ accent: "#90e0ef"
337
+ - id: dirt
338
+ label: "Dirt"
339
+ mood: "Earthy browns and sand"
340
+ primary: "#5c4033"
341
+ accent: "#d4a574"
342
+ - id: neon
343
+ label: "Neon"
344
+ mood: "Hot pink and electric blue"
345
+ primary: "#ff006e"
346
+ accent: "#3a86ff"
347
+ - id: mint
348
+ label: "Mint"
349
+ mood: "Forest green and fresh mint"
350
+ primary: "#2d6a4f"
351
+ accent: "#95d5b2"
352
+ - id: plum
353
+ label: "Plum"
354
+ mood: "Royal purple and violet"
355
+ primary: "#4a0e4e"
356
+ accent: "#c77dff"
357
+ - id: sunrise
358
+ label: "Sunrise"
359
+ mood: "Warm orange and cream"
360
+ primary: "#ff6b35"
361
+ accent: "#efefd0"
362
+
363
+ color_modes:
364
+ - id: auto
365
+ label: "Follow the visitor's system"
366
+ - id: light
367
+ label: "Always light"
368
+ - id: dark
369
+ label: "Always dark"
370
+
371
+ tones:
372
+ - id: friendly
373
+ label: "Friendly"
374
+ description: "Warm, second person, plain words, the occasional aside."
375
+ - id: technical
376
+ label: "Technical"
377
+ description: "Precise, direct, code-first; assumes a developer reader."
378
+ - id: editorial
379
+ label: "Editorial"
380
+ description: "Considered long-form prose with a point of view."
381
+ - id: playful
382
+ label: "Playful"
383
+ description: "Light, witty, energetic; fine for hobby and creative sites."
384
+ - id: formal
385
+ label: "Formal"
386
+ description: "Measured and neutral; suits documentation and portfolios."
387
+
388
+ audiences:
389
+ - id: developers
390
+ label: "Developers"
391
+ - id: general
392
+ label: "General readers"
393
+ - id: students
394
+ label: "Students and learners"
395
+ - id: clients
396
+ label: "Clients and employers"
397
+ - id: community
398
+ label: "A community or team"
399
+
400
+ site_types:
401
+ - id: blog
402
+ label: "Blog"
403
+ collections: [posts, about]
404
+ - id: docs
405
+ label: "Documentation"
406
+ collections: [docs, about, quickstart]
407
+ - id: portfolio
408
+ label: "Portfolio"
409
+ collections: [posts, about]
410
+ - id: notes
411
+ label: "Digital garden"
412
+ collections: [notes, posts, about]
413
+ - id: mixed
414
+ label: "Blog + docs"
415
+ collections: [posts, docs, about]
416
+ - id: cookbook
417
+ label: "Cookbook"
418
+ collections: [recipes, posts, about]
419
+
420
+ deploy_targets:
421
+ - id: github-pages
422
+ label: "GitHub Pages (remote theme)"
423
+ description: "Zero-install hosting; the theme is pulled from GitHub at build time."
424
+ - id: gem
425
+ label: "Ruby gem + Docker"
426
+ description: "Pins jekyll-theme-zer0 in the Gemfile; builds anywhere Docker runs."
427
+
428
+ integrations:
429
+ - id: ai_chat
430
+ label: "AI chat assistant"
431
+ icon: bi-robot
432
+ description: "Page assistant answered by Claude or Grok through the chat proxy. Needs the proxy deployed before it shows."
433
+ default: false
434
+ - id: page_feedback
435
+ label: "Improve-this-page widget"
436
+ icon: bi-megaphone
437
+ description: "Readers file well-formed GitHub issues from any page. No token needed."
438
+ default: true
439
+ - id: giscus
440
+ label: "Giscus comments"
441
+ icon: bi-chat-dots
442
+ description: "Comments stored as GitHub Discussions. Needs repo + category IDs from giscus.app."
443
+ default: false
444
+ - id: posthog
445
+ label: "PostHog analytics"
446
+ icon: bi-graph-up
447
+ description: "Consent-gated, production-only analytics."
448
+ default: false
449
+ - id: obsidian
450
+ label: "Obsidian wiki-links"
451
+ icon: bi-diagram-2
452
+ description: "[[wiki-links]], embeds, callouts and a local graph on every page."
453
+ default: true
454
+
455
+ # ── Files the Build step generates ────────────────────────────────────────────
456
+ # `path` may contain {slug} and {date}. Order is the preview-tab order.
457
+ generated_files:
458
+ - path: "_config.yml"
459
+ label: "_config.yml"
460
+ description: "Production configuration — identity, URLs, collections, integrations."
461
+ required: true
462
+ - path: "_config_dev.yml"
463
+ label: "_config_dev.yml"
464
+ description: "Local overrides — localhost URL, livereload, analytics off."
465
+ required: true
466
+ - path: "Gemfile"
467
+ label: "Gemfile"
468
+ description: "Jekyll plus the theme (remote plugin or gem)."
469
+ required: true
470
+ - path: "docker-compose.yml"
471
+ label: "docker-compose.yml"
472
+ description: "One-command dev server on your chosen port."
473
+ required: true
474
+ - path: "index.md"
475
+ label: "index.md"
476
+ description: "Home page; the welcome layout until the site is configured."
477
+ required: true
478
+ - path: "_data/navigation/main.yml"
479
+ label: "navigation/main.yml"
480
+ description: "Top navigation, generated from your Structure choices."
481
+ required: true
482
+ - path: "pages/_about/index.md"
483
+ label: "about/index.md"
484
+ description: "About page, drafted in your voice."
485
+ required: false
486
+ - path: "pages/_posts/{date}-welcome.md"
487
+ label: "posts/welcome.md"
488
+ description: "First post, drafted in your voice."
489
+ required: false
490
+ - path: ".gitignore"
491
+ label: ".gitignore"
492
+ description: "Jekyll build output, caches and secrets."
493
+ required: true
494
+ - path: "zer0.install.yml"
495
+ label: "zer0.install.yml"
496
+ description: "Your answers, replayable by scripts/bin/install."
497
+ required: false
498
+ - path: ".env.example"
499
+ label: ".env.example"
500
+ description: "Where credentials go (never in _config.yml)."
501
+ required: false
502
+ - path: "README.md"
503
+ label: "README.md"
504
+ description: "How to run, edit and deploy this site."
505
+ required: false
506
+
507
+ # ── Framework brief for the Claude session ───────────────────────────────────
508
+ # Short, factual, and safe to send on every request. Deeper answers come from
509
+ # the read_theme_file / search_theme_docs tools, which read the real source.
510
+ framework:
511
+ name: "zer0-mistakes"
512
+ gem: "jekyll-theme-zer0"
513
+ remote_theme: "bamr87/zer0-mistakes"
514
+ repository: "https://github.com/bamr87/zer0-mistakes"
515
+ docs_root: "/docs/"
516
+ summary: >-
517
+ Docker-first Jekyll theme on Bootstrap 5.3.3. Layout hierarchy is
518
+ _layouts/root.html → default.html → content layouts (article, home, note,
519
+ notebook, recipe, book, section, landing, welcome, setup). Includes are
520
+ modular under _includes/{core,components,navigation,content,analytics}.
521
+ Content lives in collections under pages/ (_posts, _docs, _about, _notes,
522
+ _quickstart, _notebooks, _quests, _cookbook). Front matter drives behaviour
523
+ (title, description, layout, categories, tags, date, lastmod, permalink,
524
+ sidebar.nav, mermaid, preview). Styling is SCSS design tokens in _sass/tokens
525
+ with seven named skins (data-theme-skin) and light/dark/auto colour modes.
526
+ Consumers use remote_theme on GitHub Pages or the gem with Docker; the theme
527
+ never needs to be forked to customise — shadow an include, add
528
+ assets/css/user-overrides.css, or set config keys.
529
+ key_config:
530
+ - "site_configured: true hides the welcome/setup screens"
531
+ - "title, subtitle, description, founder, email — identity and SEO"
532
+ - "github_user, repository_name, url, baseurl — user site has baseurl '' ; project site has '/repo'"
533
+ - "remote_theme: bamr87/zer0-mistakes (GitHub Pages) or theme: jekyll-theme-zer0 (gem)"
534
+ - "collections.<name>.output/permalink plus a matching defaults: scope"
535
+ - "theme_skin: air|aqua|dirt|neon|mint|plum|sunrise ; color_mode_default: auto|light|dark ; color_mode_lock"
536
+ - "theme_background.enabled toggles the SVG gradient/pattern/noise layers"
537
+ - "posthog.enabled/api_key ; google_analytics ; cookie_consent.enabled"
538
+ - "giscus.enabled + data-repo-id + data-category-id"
539
+ - "ai_chat.enabled/auth_mode/proxy_ready/endpoint — the widget hides until a proxy exists; ai_chat.provider: anthropic|xai picks Claude or Grok (the proxy's CHAT_PROVIDER wins)"
540
+ - "preview_images.provider/model — renderer for post preview images: xai → grok-imagine-image-2.0, openai → gpt-image-2 (keys in .env, never in config)"
541
+ - "page_feedback.enabled/mode/default_labels"
542
+ - "obsidian.enabled — wiki-links, embeds, callouts, local graph"
543
+ customisation:
544
+ - "Override any include by creating the same path under your site's _includes/"
545
+ - "assets/css/user-overrides.css is loaded last for style tweaks"
546
+ - "_includes/custom/{head,body-start,footer,body-end}.html are empty hooks"
547
+ - "_data/navigation/*.yml drives navbar, sidebars and footers"
548
+ - "Skins: data-theme-skin on <html>; add a skin by extending _sass/theme/_skins.scss in a fork"
549
+ guardrails:
550
+ - "Never put a credential in _config.yml or any generated file; point to .env"
551
+ - "Generated files must be valid YAML/Markdown; keep _config.yml keys the theme understands"
552
+ - "Ask before overwriting an existing file in the target folder"
553
+
554
+ # ── Site plan: the schema the AI agent fills, and the catalogs it picks from ──
555
+ # The plan is a structured description of the site beyond the form fields —
556
+ # landing page, navigation shape, theme overrides, example pages. Claude
557
+ # submits it with the set_site_plan tool; assets/js/setup-wizard.js validates
558
+ # it against `plan_schema` (a JSON-Schema subset: type, properties, required,
559
+ # additionalProperties, enum, enumFrom (a catalog below), items, maxItems,
560
+ # maxLength, pattern) and the generators turn it into files:
561
+ # landing → index.md (landing engine) + _data/landing.yml
562
+ # navigation → _data/navigation/main.yml (flat or grouped),
563
+ # _data/navigation/docs.yml + collection sidebar config
564
+ # theme → assets/css/user-overrides.css (+ _includes/custom/head.html
565
+ # for web fonts) layered over the chosen skin
566
+ # pages → one Markdown file per planned example page
567
+ plan_schema:
568
+ type: object
569
+ additionalProperties: false
570
+ properties:
571
+ landing:
572
+ type: object
573
+ additionalProperties: false
574
+ properties:
575
+ template: { type: string, enumFrom: landing_templates }
576
+ hero:
577
+ type: object
578
+ additionalProperties: false
579
+ properties:
580
+ eyebrow: { type: string, maxLength: 40 }
581
+ headline: { type: string, maxLength: 90 }
582
+ subheadline: { type: string, maxLength: 220 }
583
+ align: { type: string, enum: [start, center] }
584
+ variant: { type: string, enum: [default, muted, inverse] }
585
+ image: { type: string, maxLength: 200 }
586
+ ctas:
587
+ type: array
588
+ maxItems: 3
589
+ items:
590
+ type: object
591
+ additionalProperties: false
592
+ required: [label, url]
593
+ properties:
594
+ label: { type: string, maxLength: 40 }
595
+ url: { type: string, maxLength: 200 }
596
+ variant: { type: string, enum: [primary, secondary, outline, outline-light, light] }
597
+ icon: { type: string, maxLength: 40 }
598
+ sections:
599
+ type: array
600
+ maxItems: 8
601
+ items:
602
+ type: object
603
+ additionalProperties: false
604
+ required: [type]
605
+ properties:
606
+ type: { type: string, enumFrom: section_types }
607
+ id: { type: string, maxLength: 40, pattern: "^[a-z][a-z0-9-]*$" }
608
+ heading: { type: string, maxLength: 90 }
609
+ lead: { type: string, maxLength: 220 }
610
+ variant: { type: string, enum: [default, muted, inverse] }
611
+ limit: { type: integer }
612
+ body: { type: string, maxLength: 4000 }
613
+ cta:
614
+ type: object
615
+ additionalProperties: false
616
+ properties:
617
+ label: { type: string, maxLength: 40 }
618
+ url: { type: string, maxLength: 200 }
619
+ items:
620
+ type: array
621
+ maxItems: 12
622
+ items:
623
+ type: object
624
+ additionalProperties: false
625
+ properties:
626
+ title: { type: string, maxLength: 80 }
627
+ text: { type: string, maxLength: 400 }
628
+ icon: { type: string, maxLength: 40 }
629
+ url: { type: string, maxLength: 200 }
630
+ value: { type: string, maxLength: 24 }
631
+ label: { type: string, maxLength: 60 }
632
+ quote: { type: string, maxLength: 400 }
633
+ author: { type: string, maxLength: 80 }
634
+ navigation:
635
+ type: object
636
+ additionalProperties: false
637
+ properties:
638
+ style: { type: string, enumFrom: navigation_styles }
639
+ sidebar: { type: string, enumFrom: sidebar_modes }
640
+ items:
641
+ type: array
642
+ maxItems: 8
643
+ items:
644
+ type: object
645
+ additionalProperties: false
646
+ required: [title, url]
647
+ properties:
648
+ title: { type: string, maxLength: 30 }
649
+ url: { type: string, maxLength: 200 }
650
+ icon: { type: string, maxLength: 40 }
651
+ children:
652
+ type: array
653
+ maxItems: 8
654
+ items:
655
+ type: object
656
+ additionalProperties: false
657
+ required: [title, url]
658
+ properties:
659
+ title: { type: string, maxLength: 40 }
660
+ url: { type: string, maxLength: 200 }
661
+ icon: { type: string, maxLength: 40 }
662
+ theme:
663
+ type: object
664
+ additionalProperties: false
665
+ properties:
666
+ palette:
667
+ type: object
668
+ additionalProperties: false
669
+ properties:
670
+ preset: { type: string, enumFrom: palettes }
671
+ primary: { type: string, pattern: "^#[0-9a-fA-F]{6}$" }
672
+ secondary: { type: string, pattern: "^#[0-9a-fA-F]{6}$" }
673
+ accent: { type: string, pattern: "^#[0-9a-fA-F]{6}$" }
674
+ fonts: { type: string, enumFrom: font_pairings }
675
+ radius: { type: string, enumFrom: radius_options }
676
+ pages:
677
+ type: array
678
+ maxItems: 12
679
+ items:
680
+ type: object
681
+ additionalProperties: false
682
+ required: [collection, title]
683
+ properties:
684
+ collection: { type: string, enum: [posts, docs, about, notes, quickstart, notebooks, quests, recipes] }
685
+ slug: { type: string, maxLength: 60, pattern: "^[a-z0-9][a-z0-9-]*$" }
686
+ title: { type: string, maxLength: 90 }
687
+ description: { type: string, maxLength: 220 }
688
+ date: { type: string, pattern: "^\\d{4}-\\d{2}-\\d{2}$" }
689
+ categories: { type: array, maxItems: 4, items: { type: string, maxLength: 30 } }
690
+ tags: { type: array, maxItems: 8, items: { type: string, maxLength: 30 } }
691
+ body: { type: string, maxLength: 20000 }
692
+
693
+ landing_templates:
694
+ - id: minimal
695
+ label: "Minimal"
696
+ description: "Title, one paragraph, latest posts. No hero."
697
+ sections: [latest_posts]
698
+ - id: hero
699
+ label: "Hero + features"
700
+ description: "Big headline with calls to action, three feature cards, a closing CTA."
701
+ sections: [features, latest_posts, cta]
702
+ - id: showcase
703
+ label: "Showcase"
704
+ description: "Hero, a card grid of highlights, a pull quote, and a CTA. Portfolios and cookbooks."
705
+ sections: [cards, quote, cta]
706
+ - id: docs-hub
707
+ label: "Docs hub"
708
+ description: "Hero with a primary Read-the-docs CTA, three getting-started steps, topic cards, FAQ."
709
+ sections: [steps, cards, faq]
710
+ - id: editorial
711
+ label: "Editorial"
712
+ description: "Left-aligned hero, the latest writing, a short manifesto, a subscribe CTA."
713
+ sections: [latest_posts, text, cta]
714
+
715
+ section_types:
716
+ - id: features
717
+ label: "Feature cards"
718
+ fields: "items[title, text, icon]"
719
+ - id: cards
720
+ label: "Link cards"
721
+ fields: "items[title, text, icon, url]"
722
+ - id: steps
723
+ label: "Numbered steps"
724
+ fields: "items[title, text]"
725
+ - id: stats
726
+ label: "Stats"
727
+ fields: "items[value, label]"
728
+ - id: faq
729
+ label: "FAQ accordion"
730
+ fields: "items[title, text]"
731
+ - id: cta
732
+ label: "Call to action"
733
+ fields: "heading, lead, cta{label, url}"
734
+ - id: latest_posts
735
+ label: "Latest posts"
736
+ fields: "heading, limit"
737
+ - id: quote
738
+ label: "Pull quote"
739
+ fields: "items[quote, author] (first item)"
740
+ - id: text
741
+ label: "Prose"
742
+ fields: "heading, body (Markdown)"
743
+
744
+ navigation_styles:
745
+ - id: flat
746
+ label: "Flat"
747
+ description: "One link per collection plus your extras."
748
+ - id: grouped
749
+ label: "Grouped"
750
+ description: "Collections become dropdowns listing their planned pages."
751
+
752
+ sidebar_modes:
753
+ - id: none
754
+ label: "No sidebar"
755
+ description: "Full-width reading on every page."
756
+ - id: auto
757
+ label: "Automatic"
758
+ description: "The theme picks the best tree for each collection."
759
+ - id: docs
760
+ label: "Docs tree"
761
+ description: "A curated _data/navigation/docs.yml built from the planned docs pages."
762
+
763
+ # Palettes layer over the skin: they replace the primary/link/accent colours
764
+ # only, so the skin's surfaces and backgrounds stay intact.
765
+ palettes:
766
+ - id: skin
767
+ label: "Skin colours"
768
+ description: "No override — the skin's own palette."
769
+ - id: ocean
770
+ label: "Ocean"
771
+ primary: "#0b6e99"
772
+ secondary: "#5c7a89"
773
+ accent: "#00b4d8"
774
+ - id: forest
775
+ label: "Forest"
776
+ primary: "#2d6a4f"
777
+ secondary: "#6c757d"
778
+ accent: "#95d5b2"
779
+ - id: sunset
780
+ label: "Sunset"
781
+ primary: "#d9480f"
782
+ secondary: "#7a5c58"
783
+ accent: "#ffb703"
784
+ - id: graphite
785
+ label: "Graphite"
786
+ primary: "#343a40"
787
+ secondary: "#6c757d"
788
+ accent: "#adb5bd"
789
+ - id: berry
790
+ label: "Berry"
791
+ primary: "#7b2cbf"
792
+ secondary: "#6c5b7b"
793
+ accent: "#e0aaff"
794
+ - id: sand
795
+ label: "Sand"
796
+ primary: "#8a6d3b"
797
+ secondary: "#a0937d"
798
+ accent: "#e9c46a"
799
+ - id: midnight
800
+ label: "Midnight"
801
+ primary: "#1d3557"
802
+ secondary: "#457b9d"
803
+ accent: "#a8dadc"
804
+ - id: citrus
805
+ label: "Citrus"
806
+ primary: "#2b9348"
807
+ secondary: "#55a630"
808
+ accent: "#ffd60a"
809
+
810
+ # Web-font pairings load from Google Fonts through the site's own
811
+ # _includes/custom/head.html hook; `system` keeps the theme's system stack.
812
+ font_pairings:
813
+ - id: system
814
+ label: "System stack"
815
+ heading: ""
816
+ body: ""
817
+ google: ""
818
+ description: "Fast, no external requests."
819
+ - id: inter
820
+ label: "Inter"
821
+ heading: "'Inter', system-ui, sans-serif"
822
+ body: "'Inter', system-ui, sans-serif"
823
+ google: "family=Inter:wght@400;500;600;700"
824
+ description: "Neutral, technical, very legible."
825
+ - id: playfair-lato
826
+ label: "Playfair Display + Lato"
827
+ heading: "'Playfair Display', Georgia, serif"
828
+ body: "'Lato', system-ui, sans-serif"
829
+ google: "family=Playfair+Display:wght@600;700&family=Lato:wght@400;700"
830
+ description: "Editorial headlines over a clean body."
831
+ - id: space-plex
832
+ label: "Space Grotesk + IBM Plex Sans"
833
+ heading: "'Space Grotesk', system-ui, sans-serif"
834
+ body: "'IBM Plex Sans', system-ui, sans-serif"
835
+ google: "family=Space+Grotesk:wght@500;700&family=IBM+Plex+Sans:wght@400;600"
836
+ description: "Geometric, modern, product-like."
837
+ - id: merriweather-source
838
+ label: "Merriweather + Source Sans 3"
839
+ heading: "'Merriweather', Georgia, serif"
840
+ body: "'Source Sans 3', system-ui, sans-serif"
841
+ google: "family=Merriweather:wght@700&family=Source+Sans+3:wght@400;600"
842
+ description: "Warm serif headings, friendly body."
843
+ - id: nunito
844
+ label: "Nunito"
845
+ heading: "'Nunito', system-ui, sans-serif"
846
+ body: "'Nunito', system-ui, sans-serif"
847
+ google: "family=Nunito:wght@400;600;800"
848
+ description: "Rounded and approachable — hobby and community sites."
849
+ - id: fraunces-work
850
+ label: "Fraunces + Work Sans"
851
+ heading: "'Fraunces', Georgia, serif"
852
+ body: "'Work Sans', system-ui, sans-serif"
853
+ google: "family=Fraunces:wght@600;700&family=Work+Sans:wght@400;600"
854
+ description: "Characterful display serif for food, craft, culture."
855
+
856
+ radius_options:
857
+ - id: sharp
858
+ label: "Sharp"
859
+ sm: "0.125rem"
860
+ base: "0.2rem"
861
+ lg: "0.25rem"
862
+ xl: "0.375rem"
863
+ - id: soft
864
+ label: "Soft"
865
+ sm: "0.25rem"
866
+ base: "0.375rem"
867
+ lg: "0.5rem"
868
+ xl: "0.75rem"
869
+ - id: round
870
+ label: "Round"
871
+ sm: "0.5rem"
872
+ base: "0.75rem"
873
+ lg: "1rem"
874
+ xl: "1.25rem"