jekyll-theme-zer0 1.30.0 → 1.31.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +748 -571
- data/README.md +17 -3
- data/_data/backlog.yml +33 -10
- data/_data/consumers.yml +99 -0
- data/_data/features.yml +1 -1
- data/_data/i18n/fr.yml +30 -14
- data/_data/i18n/manifest.yml +63 -45
- data/_data/theme-manifest.yml +41 -39
- data/_data/ui-text.yml +1 -0
- data/_includes/README.md +1 -1
- data/_includes/analytics/posthog.html +28 -9
- data/_includes/components/README.md +1 -1
- data/_includes/components/background-image.html +7 -1
- data/_includes/components/cookie-consent.html +30 -30
- data/_includes/components/halfmoon.html +5 -3
- data/_includes/components/mermaid.html +14 -7
- data/_includes/components/preview-image.html +22 -3
- data/_includes/components/theme-preview-gallery.html +1 -1
- data/_includes/content/intro.html +21 -3
- data/_includes/content/seo.html +8 -0
- data/_includes/content/sitemap.html +220 -263
- data/_includes/core/branding.html +8 -15
- data/_includes/core/footer.html +3 -1
- data/_includes/core/head.html +33 -22
- data/_includes/core/header.html +14 -2
- data/_includes/core/tokens-inline.html +16 -1
- data/_includes/navigation/breadcrumbs.html +21 -15
- data/_includes/navigation/navbar.html +9 -6
- data/_includes/setup/wizard.html +5 -1
- data/_layouts/article.html +15 -3
- data/_layouts/home.html +13 -1
- data/_layouts/note.html +2 -1
- data/_layouts/notebook.html +2 -1
- data/_layouts/root.html +22 -0
- data/_sass/components/_cookie-banner.scss +48 -0
- data/_sass/components/_setup-wizard.scss +19 -1
- data/_sass/components/_ui-enhancements.scss +11 -0
- data/_sass/core/_navbar.scss +163 -70
- data/_sass/core/_sidebar-extras.scss +2 -14
- data/_sass/core/code-copy.scss +27 -8
- data/_sass/theme/_skins.scss +6 -2
- data/assets/css/extension-points-demo.css +27 -0
- data/assets/data/wiki-index.json +19 -0
- data/assets/js/auto-hide-nav.js +53 -13
- data/assets/js/code-copy.js +72 -1
- data/assets/js/extension-points-demo.js +48 -0
- data/assets/js/halfmoon.js +11 -1
- data/assets/js/mermaid-diagrams.js +128 -22
- data/assets/js/obsidian-local-graph.js +27 -5
- data/assets/js/search-modal.js +35 -3
- data/assets/js/setup-wizard.js +7 -2
- data/scripts/bin/validate +1 -0
- data/scripts/ci/test_visual_evidence_autogen.py +64 -2
- data/scripts/ci/visual_evidence_autogen.py +14 -4
- data/scripts/features/install-preview-generator +1 -1
- data/scripts/lib/README.md +12 -0
- data/scripts/lib/preview_generator.py +2 -2
- data/scripts/validate-features.rb +5 -8
- metadata +4 -2
data/CHANGELOG.md
CHANGED
|
@@ -12,130 +12,27 @@ hand-written prose covering the same releases in more depth; they sit below
|
|
|
12
12
|
their version because release-please inserts each new release at the top of the
|
|
13
13
|
file. Only `## [Unreleased]` describes work that has not shipped yet.
|
|
14
14
|
|
|
15
|
-
## [1.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
### Features
|
|
19
|
-
|
|
20
|
-
* **ci:** produce visual evidence and baselines on PRs, not just verify them ([#462](https://github.com/bamr87/zer0-mistakes/issues/462)) ([a377fae](https://github.com/bamr87/zer0-mistakes/commit/a377fae6ea31a0bb015479dea6d1a7c41e141c3f))
|
|
21
|
-
* **includes:** add background-image.html for CSS-painted cover art ([#451](https://github.com/bamr87/zer0-mistakes/issues/451)) ([9b15a67](https://github.com/bamr87/zer0-mistakes/commit/9b15a673f57b8f7f1f9dae9262191742d99d8080))
|
|
22
|
-
* **includes:** Claude or Grok sessions in the Site Builder ([#473](https://github.com/bamr87/zer0-mistakes/issues/473)) ([e1c5753](https://github.com/bamr87/zer0-mistakes/commit/e1c57531fc23be8d071757cd1941e1ae15285da7))
|
|
23
|
-
* **includes:** file the fleet issue contract from the feedback widget ([#472](https://github.com/bamr87/zer0-mistakes/issues/472)) ([24d4e2c](https://github.com/bamr87/zer0-mistakes/commit/24d4e2c6380541a894e9e671f0f0b0b859a29b05))
|
|
24
|
-
* **includes:** make theme-color track the page surface, not the accent ([#447](https://github.com/bamr87/zer0-mistakes/issues/447)) ([f1fda85](https://github.com/bamr87/zer0-mistakes/commit/f1fda857bb0cf5bd64bebfc1215ba0a906f05e5c))
|
|
25
|
-
* **includes:** themed Mermaid figures + toolbar ([#455](https://github.com/bamr87/zer0-mistakes/issues/455)) ([96776fa](https://github.com/bamr87/zer0-mistakes/commit/96776fa48bbe7b63058d1d246962019c745d7b93))
|
|
26
|
-
* **scripts:** adopt the shared ai-runner kit for claude-run; consumers registry fixes; hub baseline ([#475](https://github.com/bamr87/zer0-mistakes/issues/475)) ([feb4133](https://github.com/bamr87/zer0-mistakes/commit/feb41332eb15d2c13fe0c0f6d15b61007e14daa3))
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
### Bug Fixes
|
|
30
|
-
|
|
31
|
-
* **a11y:** decouple heading size from heading level in theme chrome ([#450](https://github.com/bamr87/zer0-mistakes/issues/450)) ([bb92eb5](https://github.com/bamr87/zer0-mistakes/commit/bb92eb583c955e76339a9c7ab98532b35e226b36))
|
|
32
|
-
* **a11y:** give footer icon links an accessible name, announce search results ([#441](https://github.com/bamr87/zer0-mistakes/issues/441)) ([a1811e8](https://github.com/bamr87/zer0-mistakes/commit/a1811e81ac0c17b0836994be7c48eba51252bae7))
|
|
33
|
-
* **a11y:** stop emitting sidebar/TOC controls on layouts that render no offcanvas ([#443](https://github.com/bamr87/zer0-mistakes/issues/443)) ([619322d](https://github.com/bamr87/zer0-mistakes/commit/619322d8fd7c6e2a700ba154e065bf65caf67461))
|
|
34
|
-
* **ci:** run the autogen lane's tooling from the base branch, not the PR ([#464](https://github.com/bamr87/zer0-mistakes/issues/464)) ([8473050](https://github.com/bamr87/zer0-mistakes/commit/8473050be2b4ddfd994c7bea8a8c35e37a66b7f8))
|
|
35
|
-
* **ci:** stop the UI audit reporting a measurement blackout as a clean run ([#471](https://github.com/bamr87/zer0-mistakes/issues/471)) ([ab92619](https://github.com/bamr87/zer0-mistakes/commit/ab9261946e088417dabe4291590da1c7a964d4fa))
|
|
36
|
-
* **content:** raw-protect Liquid that is written as documentation ([#446](https://github.com/bamr87/zer0-mistakes/issues/446)) ([6123c1f](https://github.com/bamr87/zer0-mistakes/commit/6123c1f1e6ffd167376d4ef421b0a9f78af3985e))
|
|
37
|
-
* **includes:** declare charset inside the 1024-byte window, make the feed discoverable ([#440](https://github.com/bamr87/zer0-mistakes/issues/440)) ([4025205](https://github.com/bamr87/zer0-mistakes/commit/40252050ec21c70aa1d84820fdcde6d564e03478)), closes [#372](https://github.com/bamr87/zer0-mistakes/issues/372) [#371](https://github.com/bamr87/zer0-mistakes/issues/371)
|
|
38
|
-
* **includes:** expose skin-button selected state via aria-pressed ([#469](https://github.com/bamr87/zer0-mistakes/issues/469)) ([6579b16](https://github.com/bamr87/zer0-mistakes/commit/6579b1621a5eff147e224977633728aadc960505)), closes [#467](https://github.com/bamr87/zer0-mistakes/issues/467)
|
|
39
|
-
* **install:** stop seeding the theme's own navigation into consumers ([#449](https://github.com/bamr87/zer0-mistakes/issues/449)) ([232857c](https://github.com/bamr87/zer0-mistakes/commit/232857c66d7c3abccb166b5151a7f80a74dd17ca))
|
|
40
|
-
* **navigation:** scroll spy bolds the section actually being read ([#456](https://github.com/bamr87/zer0-mistakes/issues/456)) ([5ff38bf](https://github.com/bamr87/zer0-mistakes/commit/5ff38bf98faf96cdc3bf63ea3f0e7b10e21f3aab))
|
|
41
|
-
* **sass:** stop navbar controls flickering under a stationary pointer ([#453](https://github.com/bamr87/zer0-mistakes/issues/453)) ([fc84b9a](https://github.com/bamr87/zer0-mistakes/commit/fc84b9a4c714f8e04b8a0f940bed9e3795c144bc)), closes [#404](https://github.com/bamr87/zer0-mistakes/issues/404)
|
|
42
|
-
* **scripts:** restore nested translation placeholders instead of leaking them ([#452](https://github.com/bamr87/zer0-mistakes/issues/452)) ([00cab73](https://github.com/bamr87/zer0-mistakes/commit/00cab73d915f4e116040ef6ca4c0381669ae4eb2))
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
### Performance Improvements
|
|
46
|
-
|
|
47
|
-
* **ci:** run the critical PR gate on 3 workers instead of 1 ([#481](https://github.com/bamr87/zer0-mistakes/issues/481)) ([b3fcbc7](https://github.com/bamr87/zer0-mistakes/commit/b3fcbc76a1af2a3a5e43eb28fbff7b3057751de6))
|
|
48
|
-
* **includes:** strip developer doc banners from delivered HTML ([#445](https://github.com/bamr87/zer0-mistakes/issues/445)) ([89b10f1](https://github.com/bamr87/zer0-mistakes/commit/89b10f1ff361c919fd631d0e7e664ed6d7c28a14))
|
|
49
|
-
|
|
50
|
-
## [Unreleased]
|
|
51
|
-
|
|
52
|
-
### Changed
|
|
53
|
-
|
|
54
|
-
- **`claude-run` is now the fleet's shared `ai-runner` kit.** The composite
|
|
55
|
-
action and its new `scripts/ai/run.sh` are byte-identical copies of
|
|
56
|
-
lifehacker.dev's (the kit source of truth) instead of a hand-rolled variant.
|
|
57
|
-
What changes for the two callers (`issue-autopilot.yml`,
|
|
58
|
-
`visual-evidence-autogen.yml`): an AI call that was attempted and rejected —
|
|
59
|
-
revoked credential, exhausted quota, `is_error` payload, CLI install failure
|
|
60
|
-
— now fails the step with the reason as a `::error::` annotation, where the
|
|
61
|
-
old action exited 0 and a dead run read green; the OAuth-first rule is
|
|
62
|
-
enforced with `env -u ANTHROPIC_API_KEY`; the model override is the canonical
|
|
63
|
-
`AI_MODEL` (or the new `model` input) rather than `ZER0_AI_MODEL`, and
|
|
64
|
-
`max-turns` is a new input. Metering (`scripts/ai/usage.rb`,
|
|
65
|
-
`usage_report.rb`, prices in `_data/ai_pricing.yml`) and the Claude API
|
|
66
|
-
fallback (`scripts/ai/api_call.rb`) ride along as optional companions. The
|
|
67
|
-
exit-code contract is pinned by `scripts/ci/test_ai_runner.sh`, wired into
|
|
68
|
-
`./scripts/bin/test`. The action's six existing inputs are unchanged.
|
|
69
|
-
- **`claude-run` is consumed by reference from the hub.** `issue-autopilot.yml` and `visual-evidence-autogen.yml` now call `bamr87/bamr87/.github/actions/claude-run@main` (identical inputs) instead of a vendored `./.github/actions/claude-run`; the local action, `scripts/ai/run.sh`, and the vendored contract test (`scripts/ci/test_ai_runner.sh` + its `scripts/test/lib/` bridge) are deleted, while the consumer companions the hub runner probes for — `scripts/ai/usage.rb`, `usage_report.rb`, `api_call.rb`, `_data/ai.yml`, `_data/ai_pricing.yml`, `tools/unwrap-prose.py` — stay ([bamr87/bamr87#254](https://github.com/bamr87/bamr87/pull/254)).
|
|
70
|
-
- **Consumer registry corrections.** `ai-world-view/ai-world-view.github.io`
|
|
71
|
-
is `remote_theme_floating` (both its `_config.yml` and `hub.yml` pins are
|
|
72
|
-
untagged), not `remote_theme_pinned`; `amr-bash/bash-365.com` is registered
|
|
73
|
-
as a consumer (floating `remote_theme`, unconstrained gem on Azure, path gem
|
|
74
|
-
for dev).
|
|
75
|
-
|
|
76
|
-
### Fixed
|
|
77
|
-
|
|
78
|
-
- **The weekly UI/UX audit was blind, and reported it as clean.** `sweep.mjs`
|
|
79
|
-
built its pages with `browser.newPage()`, which `@axe-core/playwright`
|
|
80
|
-
refuses; the throw was caught by a single per-route `try` that also discarded
|
|
81
|
-
the overflow, console-error and link-collection data already gathered for
|
|
82
|
-
that route. Screenshots still succeeded, so the harness looked alive while
|
|
83
|
-
every accessibility, console, overflow and broken-link result on every route
|
|
84
|
-
was silently dropped — and the report rendered the absence as "0 axe
|
|
85
|
-
violations / 0 broken links". Pages are now built from `browser.newContext()`,
|
|
86
|
-
each measurement fails independently, a scan that errored is reported as
|
|
87
|
-
UNKNOWN rather than clean, and a measurement that fails on every route turns
|
|
88
|
-
the sweep red the way a total capture failure already did. On the demo site
|
|
89
|
-
the sweep goes from 18/21 captured with 21 blackout entries to **21/21
|
|
90
|
-
captured, 0 harness errors, 191 links crawled and 8 genuinely broken links
|
|
91
|
-
found** ([#468](https://github.com/bamr87/zer0-mistakes/issues/468)).
|
|
92
|
-
- **Theme-skin buttons now announce which skin is applied.** The Theme Skin
|
|
93
|
-
group in Settings → Appearance conveyed selection only through the Bootstrap
|
|
94
|
-
`.active` class, which carries no accessibility semantics, so screen readers
|
|
95
|
-
announced nine identical unlabelled buttons — WCAG 2.1 SC 4.1.2 (Name, Role,
|
|
96
|
-
Value). Each button now ships `aria-pressed`, and the click and "Reset
|
|
97
|
-
background" handlers keep it in sync with `.active` through one shared
|
|
98
|
-
helper, matching the sibling color-mode group
|
|
99
|
-
([#467](https://github.com/bamr87/zer0-mistakes/issues/467)).
|
|
100
|
-
|
|
101
|
-
## [1.29.0](https://github.com/bamr87/zer0-mistakes/compare/v1.28.0...v1.29.0) (2026-09-01)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
### Features
|
|
105
|
-
|
|
106
|
-
* **analytics:** track and display per-page view counts ([#413](https://github.com/bamr87/zer0-mistakes/issues/413)) ([e488c4c](https://github.com/bamr87/zer0-mistakes/commit/e488c4c3101da78e98eecbf8299ce7c8705ed281))
|
|
107
|
-
* **design:** fill Fab, PostCard, Skeleton + motion/layers gaps in the design-system mirror ([#391](https://github.com/bamr87/zer0-mistakes/issues/391)) ([3b49741](https://github.com/bamr87/zer0-mistakes/commit/3b497417564b4c5e3d71eaa113cb136d2cdaf15c))
|
|
108
|
-
* **includes:** icon-only language trigger and a compact, positive menu ([#431](https://github.com/bamr87/zer0-mistakes/issues/431)) ([353bfa5](https://github.com/bamr87/zer0-mistakes/commit/353bfa5f3a8dd949ca6e513213a155d648218642)), closes [#406](https://github.com/bamr87/zer0-mistakes/issues/406)
|
|
109
|
-
* **includes:** live preview, vertical stepper and draft persistence in the setup wizard ([#432](https://github.com/bamr87/zer0-mistakes/issues/432)) ([73bdc55](https://github.com/bamr87/zer0-mistakes/commit/73bdc5547350c448e1617ec6cf5b9f49b10d65fb)), closes [#408](https://github.com/bamr87/zer0-mistakes/issues/408)
|
|
110
|
-
* **layouts:** add cookbook collection with recipe scaling and unit conversion ([#414](https://github.com/bamr87/zer0-mistakes/issues/414)) ([bb8eefa](https://github.com/bamr87/zer0-mistakes/commit/bb8eefa2beea0104fec28d173a1e57f369acada8))
|
|
111
|
-
* **pages:** publish the design system and page canvas on the live site ([#392](https://github.com/bamr87/zer0-mistakes/issues/392)) ([6cf73cd](https://github.com/bamr87/zer0-mistakes/commit/6cf73cdf2cca9ec02394b6ae1ba7e39c19969134))
|
|
112
|
-
* **sass:** align design tokens with the Claude Design system ([#389](https://github.com/bamr87/zer0-mistakes/issues/389)) ([7fc2fe0](https://github.com/bamr87/zer0-mistakes/commit/7fc2fe02683d652c0326536158bd48b3690df51f))
|
|
15
|
+
## [1.31.1](https://github.com/bamr87/zer0-mistakes/compare/v1.31.0...v1.31.1) (2026-10-17)
|
|
113
16
|
|
|
114
17
|
|
|
115
18
|
### Bug Fixes
|
|
116
19
|
|
|
117
|
-
* **a11y:**
|
|
118
|
-
* **
|
|
119
|
-
* **
|
|
120
|
-
* **
|
|
121
|
-
* **
|
|
122
|
-
* **
|
|
123
|
-
* **cookie-consent:** text-dark on bg-body made privacy rights invisible in dark mode ([#386](https://github.com/bamr87/zer0-mistakes/issues/386)) ([9bde7df](https://github.com/bamr87/zer0-mistakes/commit/9bde7dfa13f426908e00e53f8e4013a049fd928d))
|
|
124
|
-
* **giscus:** comments were broken sitewide — add an end-to-end health check and correct the docs ([#378](https://github.com/bamr87/zer0-mistakes/issues/378)) ([45e222c](https://github.com/bamr87/zer0-mistakes/commit/45e222c3c2c5b7c507af4df2f5f0b48bc783801e))
|
|
125
|
-
* **includes:** footer Info/Cookie Preferences are buttons, not anchors ([#427](https://github.com/bamr87/zer0-mistakes/issues/427)) ([f9041b9](https://github.com/bamr87/zer0-mistakes/commit/f9041b98b8a267be59f560724821fd941090f52d)), closes [#320](https://github.com/bamr87/zer0-mistakes/issues/320)
|
|
126
|
-
* **layouts:** match section topic filters on whole tags, not substrings ([#420](https://github.com/bamr87/zer0-mistakes/issues/420)) ([338ad1d](https://github.com/bamr87/zer0-mistakes/commit/338ad1ddfb71c8d1dd9c48b36fb4634daf93f2de))
|
|
127
|
-
* **layouts:** move keyboard focus to the skip-link target (tabindex="-1") ([#395](https://github.com/bamr87/zer0-mistakes/issues/395)) ([f5db650](https://github.com/bamr87/zer0-mistakes/commit/f5db65048e48ca71eedebc04d02d051e0b3152a6)), closes [#278](https://github.com/bamr87/zer0-mistakes/issues/278)
|
|
128
|
-
* **layouts:** stop emitting dead sub-topic anchors in section sidebars ([#402](https://github.com/bamr87/zer0-mistakes/issues/402)) ([f50e790](https://github.com/bamr87/zer0-mistakes/commit/f50e790c4bfd56fefa4a74d7876de90c9776c689))
|
|
129
|
-
* **layouts:** upgrade the no-js class to "js" so the hook works ([#428](https://github.com/bamr87/zer0-mistakes/issues/428)) ([a2d31f5](https://github.com/bamr87/zer0-mistakes/commit/a2d31f5533a4fb4793042e32326c1a78c9954268)), closes [#319](https://github.com/bamr87/zer0-mistakes/issues/319)
|
|
130
|
-
* **navigation:** fit all nav items, full-bleed bar, language into Settings ([#423](https://github.com/bamr87/zer0-mistakes/issues/423)) ([689006e](https://github.com/bamr87/zer0-mistakes/commit/689006e7654e900a4509c30539fcf12bd7f397c6))
|
|
131
|
-
* **scripts:** correct consumer auditor, plugin contract, and JSON-LD scope ([#400](https://github.com/bamr87/zer0-mistakes/issues/400)) ([b466cad](https://github.com/bamr87/zer0-mistakes/commit/b466cad526501e7e7a0eef5f24a12c5bbd181dc7))
|
|
132
|
-
* **scripts:** recover from a rejected Anthropic credential, and link the cookbook ([#419](https://github.com/bamr87/zer0-mistakes/issues/419)) ([fac6bee](https://github.com/bamr87/zer0-mistakes/commit/fac6beeb7af7dcae96f727bf0cf581b080e95f15))
|
|
133
|
-
* **ui-audit:** serve without --detach so the sweep can capture, and fail loudly when it cannot ([#434](https://github.com/bamr87/zer0-mistakes/issues/434)) ([fac6415](https://github.com/bamr87/zer0-mistakes/commit/fac641574c951b2887d94f8b39561fb8b6f8fe8c)), closes [#321](https://github.com/bamr87/zer0-mistakes/issues/321)
|
|
20
|
+
* **a11y:** name mobile intro actions, 24px nav chevrons, badge links ([#507](https://github.com/bamr87/zer0-mistakes/issues/507)) ([59963a9](https://github.com/bamr87/zer0-mistakes/commit/59963a958fb08cff9d49c00eac9e4c430d70a5c5))
|
|
21
|
+
* **color-mode:** mark the selected mode pressed on first paint ([#521](https://github.com/bamr87/zer0-mistakes/issues/521)) ([#526](https://github.com/bamr87/zer0-mistakes/issues/526)) ([2a60e73](https://github.com/bamr87/zer0-mistakes/commit/2a60e7328709f9902721fb83f7d2923d0c3f204a))
|
|
22
|
+
* **footer:** keep newsletter hint in the a11y tree below md ([#522](https://github.com/bamr87/zer0-mistakes/issues/522)) ([#525](https://github.com/bamr87/zer0-mistakes/issues/525)) ([90489d3](https://github.com/bamr87/zer0-mistakes/commit/90489d36a73bdb7f7182219efed6a399a145b388))
|
|
23
|
+
* **includes:** drop orphaned itemprop metas from <head> ([#517](https://github.com/bamr87/zer0-mistakes/issues/517)) ([47f4ff8](https://github.com/bamr87/zer0-mistakes/commit/47f4ff8f8f44933d65a7d38e6b0552d2288f8180)), closes [#513](https://github.com/bamr87/zer0-mistakes/issues/513)
|
|
24
|
+
* **navigation:** keep unlinked crumbs out of the BreadcrumbList ([#518](https://github.com/bamr87/zer0-mistakes/issues/518)) ([4fda7ab](https://github.com/bamr87/zer0-mistakes/commit/4fda7ab63a31c3614df30a13d38453568a7d5ff5))
|
|
25
|
+
* **tests:** serve the Visual Snapshots stack without LiveReload ([#530](https://github.com/bamr87/zer0-mistakes/issues/530)) ([6f61421](https://github.com/bamr87/zer0-mistakes/commit/6f6142182654b09a15c6460bf1643d2b6719a5b2))
|
|
134
26
|
|
|
135
27
|
## [Unreleased]
|
|
136
28
|
|
|
137
29
|
### Added
|
|
138
30
|
|
|
31
|
+
- **Four consumer extension points** ([#412](https://github.com/bamr87/zer0-mistakes/issues/412)), documented at [`/docs/customization/extension-points/`](pages/_docs/customization/extension-points.md) and [`docs/development/extension-points.md`](docs/development/extension-points.md):
|
|
32
|
+
- `zer0:code-block-ready` — a bubbling `CustomEvent` dispatched once per code block carrying `{ wrapper, header, pre, code, lang }`, plus `window.zer0OnCodeBlock(fn)`, which **replays** already-decorated blocks before subscribing, and `window.__zer0CodeBlocks`. This replaces the `MutationObserver` and wrapper-shape guessing a consumer previously needed — the guess is what silently rendered two buttons on every block downstream.
|
|
33
|
+
- `styles:` / `scripts:` frontmatter — per-page CSS and JS resolved through `relative_url`, with `scripts:` deferred after the theme bundle. A page that declares neither emits nothing at all.
|
|
34
|
+
- `lastmod` and `description` on every `/assets/data/wiki-index.json` entry — ISO-8601 and the authored subtitle, always defined (`null` when the document has neither), no new traversal.
|
|
35
|
+
|
|
139
36
|
- **Bring your own AI provider — Claude or Grok — and an open, coding-session-style
|
|
140
37
|
Site Builder (ZER0-087)** — the chat proxy gains a provider layer
|
|
141
38
|
(`templates/deploy/chat-proxy/providers.js`): xAI's Grok is a first-class
|
|
@@ -279,102 +176,326 @@ file. Only `## [Unreleased]` describes work that has not shipped yet.
|
|
|
279
176
|
screen); page overflow 0px at 320/390px; 11/12 docs diagrams rendered, 1
|
|
280
177
|
shown as an error card with its source kept).
|
|
281
178
|
|
|
282
|
-
|
|
179
|
+
- **Cookbook & recipes collection (ZER0-084)** — a `recipes` collection that
|
|
180
|
+
renders structured front matter as a working recipe page: `layout: recipe`
|
|
181
|
+
builds a fact bar (prep/cook/rest/total, yield, difficulty, cuisine, oven),
|
|
182
|
+
a grouped ingredient checklist, a numbered method with per-step timings and
|
|
183
|
+
temperatures, a baker's-percentage ratio table computed at build time, a
|
|
184
|
+
per-serving nutrition panel, and one `schema.org/Recipe` JSON-LD block.
|
|
185
|
+
`assets/js/recipe-scaler.js` adds serving scaling and live US↔metric
|
|
186
|
+
conversion — including volume↔weight via `_data/ingredient_densities.yml`
|
|
187
|
+
— as progressive enhancement, so every amount is still rendered exactly as
|
|
188
|
+
authored with JavaScript disabled. `layout: cookbook` indexes recipes into
|
|
189
|
+
course sections from `_data/recipe_courses.yml`. Twelve new
|
|
190
|
+
`components/recipe-*.html` includes, `_sass/components/_recipe.scss` (with
|
|
191
|
+
print styles), a demo cookbook at `/recipes/`, and docs at
|
|
192
|
+
[Cookbook collection](pages/_docs/features/cookbook-collection.md). Regression
|
|
193
|
+
coverage: `test/visual/features/recipes.spec.js` (smoke tier) and "Cookbook
|
|
194
|
+
Recipe Collection" in `test/test_core.sh` (evidence:
|
|
195
|
+
[`test/visual/evidence/recipes-collection/`](test/visual/evidence/recipes-collection/README.md)
|
|
196
|
+
— 0px page overflow across 320–1440px; 1 cup butter → 227 g, 500 g flour →
|
|
197
|
+
4 cups; ratio percentages identical at 1× and 3×).
|
|
283
198
|
|
|
284
|
-
- **
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
`
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
`
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
-
|
|
301
|
-
`components/
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
The theme's own homepage hero is `bg-primary text-white`, so its two
|
|
307
|
-
outlined buttons moved to `outline-light` and render exactly as before —
|
|
308
|
-
a consumer who copied `_data/landing.yml` into a site with a dark hero
|
|
309
|
-
should make the same one-word change.
|
|
310
|
-
- **A planned `landing.hero.image` was accepted and then thrown away** — the
|
|
311
|
-
site plan's schema has offered `landing.hero.image` since the Site Builder
|
|
312
|
-
shipped, but the landing engine it generates never rendered it, so an agent
|
|
313
|
-
(or a human) could set a hero image, see it validated, watch it land in
|
|
314
|
-
`_data/landing.yml`, and get a landing page with no picture. `index.md` now
|
|
315
|
-
renders it inside the hero, decorative (empty `alt`) so a screen reader does
|
|
316
|
-
not hear the headline twice. Found by building a site end to end through the
|
|
317
|
-
new Grok path, where the "Hero image with …" shortcut pointed straight at the
|
|
318
|
-
dead field.
|
|
319
|
-
- **A partial hero patch silently wiped the rest of the hero** —
|
|
320
|
-
`set_site_plan` replaced `landing.hero` wholesale, so the natural agent move
|
|
321
|
-
of "write the copy now, add the artwork two turns later"
|
|
322
|
-
(`{landing: {hero: {image}}}`) discarded the headline, subheadline and every
|
|
323
|
-
call to action, and the landing page quietly reverted to the site title and
|
|
324
|
-
the default buttons. The hero now merges field by field; `sections`,
|
|
325
|
-
`navigation.items` and `pages` still replace, because a shorter list has to
|
|
326
|
-
mean a shorter list. The tool description says so, and the regression test
|
|
327
|
-
pins both halves.
|
|
199
|
+
- **Page-view counter (ZER0-083)** — the theme now tracks a view for the page
|
|
200
|
+
being read and displays the count in the article meta row, next to the
|
|
201
|
+
reading time (`👁 12 views`). Two providers, configured under `page_views:`
|
|
202
|
+
in `_config.yml`: `local` (the default — counts live in the visitor's
|
|
203
|
+
`localStorage`, so it works on GitHub Pages with no server, no network, and
|
|
204
|
+
no third party) and `remote` (counts come from an HTTP counter endpoint you
|
|
205
|
+
control, with `{path}` substitution, a configurable method, and a dotted
|
|
206
|
+
`count_key` for the response shape). Privacy gates mirror the `posthog:`
|
|
207
|
+
block — Do Not Track, Global Privacy Control, and an optional
|
|
208
|
+
`require_consent` tie-in to the cookie-consent "analytics" category — and
|
|
209
|
+
they suppress *recording* only, never the display of a count that is already
|
|
210
|
+
known; a view blocked pending consent is recorded when consent arrives.
|
|
211
|
+
`dedupe: session` counts one view per page per browser session so reloads do
|
|
212
|
+
not inflate it. The badge include (`components/page-views.html`) ships hidden
|
|
213
|
+
and is revealed only once a count exists, carrying its own leading separator
|
|
214
|
+
so a page with no data leaves no dangling bullet. New:
|
|
215
|
+
`_includes/components/page-views.html`,
|
|
216
|
+
`_includes/components/page-views-init.html`, `assets/js/page-views.js`,
|
|
217
|
+
`_sass/components/_page-views.scss`. Regression spec:
|
|
218
|
+
`test/visual/features/page-views.spec.js`. Docs:
|
|
219
|
+
[`docs/features/page-views.md`](docs/features/page-views.md)
|
|
220
|
+
(evidence: [`test/visual/evidence/page-views/`](test/visual/evidence/page-views/README.md)).
|
|
328
221
|
|
|
329
|
-
- **
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
222
|
+
- **Search shortcut affordances (ZER0-032)** — the navbar search button now
|
|
223
|
+
advertises its keyboard shortcuts, matching the design-system navbar
|
|
224
|
+
pattern: a quiet `/` kbd chip (xl-up), a hover title ("Search — press / or
|
|
225
|
+
Ctrl+K", shown as `⌘K` on macOS), and `aria-keyshortcuts`; the sidebar (`b`)
|
|
226
|
+
and table-of-contents (`t`) hide toggles gained shortcut hover hints, and
|
|
227
|
+
the keyboard-shortcuts modal now lists `⌘/Ctrl+K`
|
|
228
|
+
(evidence: [`test/visual/evidence/search-shortcut-hint/`](test/visual/evidence/search-shortcut-hint/README.md)).
|
|
336
229
|
|
|
337
|
-
- **
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
with no explanation. `write_project_file` now says so in its result and
|
|
347
|
-
offers a restart, and `run_compose` gained a `restart` action.
|
|
230
|
+
- **Live design-system pages (ZER0-082)** — the design system is now
|
|
231
|
+
part of the site itself: `_design-system/` is force-included in the Jekyll
|
|
232
|
+
build so `styles.css`, every token file, specimen cards, and component
|
|
233
|
+
sources get real URLs under `/_design-system/`; a new `/design/` hub page
|
|
234
|
+
renders the foundation specimens in live iframes (colors, skins, type,
|
|
235
|
+
spacing, radii, motion, layers, iconography), catalogs the component twins,
|
|
236
|
+
and links the Claude Design page canvas (all 24 layouts as a browsable
|
|
237
|
+
presentation). Navbar: About → Design System. Regression spec:
|
|
238
|
+
`test/visual/features/design-hub.spec.js`.
|
|
348
239
|
|
|
349
|
-
- **
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
`
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
`
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
240
|
+
- **Claude Design system round-trip (ZER0-081)** — the design-token layer is now
|
|
241
|
+
aligned with the zer0-mistakes Claude Design project
|
|
242
|
+
(`claude.ai/design/p/e75121c0-9210-42d1-ade3-2c8af9111cbe`): new
|
|
243
|
+
`--zer0-radius-*`, `--zer0-logo-*`, and `--zer0-text-display-*` tokens in
|
|
244
|
+
`_sass/tokens/`; the design project vendored as a git mirror under
|
|
245
|
+
`_design-system/` (plain-CSS tokens, React component specs, guideline cards,
|
|
246
|
+
website UI kit — sync contract in `_design-system/SYNC.md`); and
|
|
247
|
+
`scripts/design-system-check.rb` wired into the core test suite so the theme
|
|
248
|
+
and the mirror cannot drift silently. Callouts, landing feature cards, mobile
|
|
249
|
+
nav, tables, and focus rings now consume the radius tokens (value-preserving —
|
|
250
|
+
rendered output unchanged, pinned by a new runtime token assertion in
|
|
251
|
+
`test/visual/core/styling.spec.js`).
|
|
252
|
+
- **Design-system component twins (PR #391)** — `Fab`/`FabStack`, `PostCard`,
|
|
253
|
+
and `Skeleton` join Button/Badge/Card/FeatureCard/Callout/Input in
|
|
254
|
+
`_design-system/components/`, plus new Motion and Layers foundation cards;
|
|
255
|
+
all pushed live to the Claude Design project. The feature registry is
|
|
256
|
+
re-synced (`features/features.yml` ↔ `_data/features.yml` — #389's ZER0-081
|
|
257
|
+
entry had landed in the `_data` mirror only, which the registry validator
|
|
258
|
+
rejects) and `docs/ui/components.md` gains a theme-source →
|
|
259
|
+
design-system-twin map.
|
|
260
|
+
|
|
261
|
+
- **`giscus-discussions doctor`** — a new subcommand that verifies the entire
|
|
262
|
+
comment chain end-to-end: repository public, Discussions enabled, `giscus.enabled: true`, `data-repo-id` actually belonging to this repo (the fork trap), `data-category-id` resolving to a real category, and — the part nothing else could check — whether the giscus GitHub App is installed, by asking the Giscus API itself. Exits non-zero with a specific remediation line per failure.
|
|
263
|
+
- **Giscus health check in CI** — `.github/workflows/giscus-digest.yml` (already
|
|
264
|
+
scheduled weekly) now runs `doctor` and fails the job with a summary when comments are down, so a sitewide comment outage surfaces on its own instead of waiting for a reader to report it.
|
|
265
|
+
- **Troubleshooting: "The giscus app is not installed"** — a new section in the
|
|
266
|
+
feature docs with captured screenshots of both the broken widget and the giscus.app configurator rejecting the repo, an explanation of why this step is uniquely easy to skip, a fork-specific warning, and a copy-pasteable `curl` health check.
|
|
267
|
+
- **Obsidian graph frontend revamp** — the graph views now mirror the Obsidian
|
|
268
|
+
desktop experience. The full graph page gains a floating **Graph settings**
|
|
269
|
+
card (Filters / Display / Forces): search with `tag:`/`path:` operators,
|
|
270
|
+
per-collection toggles generated from the wiki-index (count badge + color
|
|
271
|
+
swatch, doubling as the legend), show-orphans and show-unresolved switches,
|
|
272
|
+
node-size / link-thickness / label-fade sliders, repel-force and
|
|
273
|
+
link-distance sliders with animated re-layout, plus a zoom / fit / fullscreen
|
|
274
|
+
button stack, an Obsidian-style hover preview card, live dark-mode restyling,
|
|
275
|
+
and localStorage persistence. The local graph panel gains a depth selector
|
|
276
|
+
(1–3) and outgoing/incoming direction switches that re-render the subgraph in
|
|
277
|
+
place. Same vendored cytoscape.js, unchanged `wiki-index.json` contract
|
|
278
|
+
(evidence:
|
|
279
|
+
[`test/visual/evidence/obsidian-graph-revamp/`](test/visual/evidence/obsidian-graph-revamp/README.md);
|
|
280
|
+
regression: `test/visual/features/obsidian-graph.spec.js`).
|
|
281
|
+
|
|
282
|
+
- **Theme-canary reporting contract** (`docs/systems/theme-canary-contract.md`) —
|
|
283
|
+
the canonical upstream bug-intake protocol for downstream theme-scout agents
|
|
284
|
+
(it-journey, lifehacker.dev): required `theme-canary` + `from-<consumer>`
|
|
285
|
+
labels, a deterministic 12-hex dedupe key + hidden body marker, the mandated
|
|
286
|
+
open-AND-closed pre-filing search, a 5-issues-per-consumer-per-run cap, and a
|
|
287
|
+
required evidence format that records the theme version/commit observed (so
|
|
288
|
+
fixed-in-release triage is mechanical). Ships with the matching
|
|
289
|
+
`theme-canary.yml` issue form.
|
|
290
|
+
|
|
291
|
+
- **`examples/` — self-contained demo sites built on the theme.** New top-level
|
|
292
|
+
directory (excluded from the theme's own site build and from the gem) for
|
|
293
|
+
complete Jekyll sites that show the theme configured for a particular kind of
|
|
294
|
+
site. Each has its own `_config.yml`, `Gemfile`, and content, and builds
|
|
295
|
+
against the local theme sources via `_config_dev.yml`.
|
|
296
|
+
- `examples/swerve-of-shore/` — **Swerve of Shore**, a serialized literary
|
|
297
|
+
reading blog rebuilt from
|
|
298
|
+
[swerveofshore.com](https://www.swerveofshore.com/) with the site owner's
|
|
299
|
+
permission. 52 pages, 0 broken internal links. Exercises a `series` output
|
|
300
|
+
collection with nested per-section paths, a data-driven taxonomy
|
|
301
|
+
(`_data/episodes.yml`) that generates the sidebar rail, the episode
|
|
302
|
+
schedule with live entry counts, and a section page for every node — so a
|
|
303
|
+
nav target resolves even where nothing is written yet. Also covers article
|
|
304
|
+
hero images (`show_hero`), entries ordered by number rather than date, the
|
|
305
|
+
shared `post-card` component in a single-column feed, and a full editorial
|
|
306
|
+
light-mode restyle done entirely through `assets/css/user-overrides.css` —
|
|
307
|
+
no theme files touched. The site's identity, taxonomy, entry titles/dates,
|
|
308
|
+
and featured images are reproduced, along with a short quoted excerpt per
|
|
309
|
+
entry (the opening the original publishes in its own RSS feed), attributed
|
|
310
|
+
and linked back. The essays themselves are not reproduced.
|
|
311
|
+
- `examples/README.md` — how to run one and the conventions for adding
|
|
312
|
+
another.
|
|
313
|
+
- **Theme propagation system — releases now reach the sites built on them.**
|
|
314
|
+
Releasing ended at RubyGems; nothing told the five downstream consumers a new
|
|
315
|
+
version existed, so all three pinned sites were still on v1.26.0 when v1.27.0
|
|
316
|
+
shipped and the two unpinned ones had been silently tracking `main`.
|
|
317
|
+
- `_data/consumers.yml` — registry of every consumer, its consumption mode
|
|
318
|
+
(`remote_theme_pinned` / `remote_theme_floating` / `gem` / `path`), and every
|
|
319
|
+
file that holds a version pin.
|
|
320
|
+
- `scripts/propagate.rb` — reports pin drift across the registry
|
|
321
|
+
(`--format text|json|github`, `--strict`) or dispatches a `theme-release`
|
|
322
|
+
event to each consumer (`--dispatch`).
|
|
323
|
+
- `.github/workflows/propagate-theme.yml` — dispatches on release publish;
|
|
324
|
+
weekly drift report. Never pushes to a consumer: each one opens its own PR so
|
|
325
|
+
its own CI gates the bump.
|
|
326
|
+
- `templates/consumer/` — the consumer's half of the contract:
|
|
327
|
+
`bump-theme-pins.sh` (rewrites `remote_theme`, `theme_repo`, and Gemfile gem
|
|
328
|
+
constraints in one pass; `--check`, `--dry-run`, `--latest`, `--pin`),
|
|
329
|
+
`theme-bump.yml` (dispatch + weekly schedule + manual), and a
|
|
330
|
+
`.theme-overrides.yml` starter. The schedule matters most for gem-mode
|
|
331
|
+
consumers, which have no `remote_theme` and so pick up nothing automatically.
|
|
332
|
+
- `docs/systems/theme-propagation.md` — how the whole flow fits together.
|
|
333
|
+
- **`./scripts/bin/manifest --check`** — verifies the committed theme manifest
|
|
334
|
+
matches the working tree, ignoring `generated_at`. `--dry-run` now emits only
|
|
335
|
+
YAML on stdout (progress logs moved to stderr) so its output can be diffed
|
|
336
|
+
directly.
|
|
337
|
+
- **Consumer extension hooks (`_includes/custom/`).** Four empty stubs the
|
|
338
|
+
chrome now includes at fixed points — `custom/head.html` (end of `<head>`),
|
|
339
|
+
`custom/body-start.html` (right after `<body>`, e.g. GTM noscript),
|
|
340
|
+
`custom/footer.html` (after the theme footer), `custom/body-end.html` (last
|
|
341
|
+
thing before `</body>`). A consumer site shadows just the stub to inject
|
|
342
|
+
JSON-LD, fonts, verification tags, or scripts — no more forking
|
|
343
|
+
`core/head.html`/`root.html` and drifting from the theme. Documented in
|
|
344
|
+
`_includes/README.md`.
|
|
345
|
+
- **`components/card-grid.html` + `components/data-card.html`.** A generic,
|
|
346
|
+
data-driven card grid (title/url/icon/badge/meta-pills/buttons schema) for
|
|
347
|
+
org hub dashboards, fleet registries, service grids, and link boards —
|
|
348
|
+
the markup consumer sites have been hand-rolling per page. Includes an
|
|
349
|
+
optional empty-state message.
|
|
350
|
+
- **`_layouts/404.html` — the 404 page as a theme layout.** The full 404
|
|
351
|
+
experience (including the unconfigured-site setup guide) now lives in the
|
|
352
|
+
theme; a consumer's `/404.html` shrinks from a 224-line vendored copy to a
|
|
353
|
+
4-line front-matter stub (`layout: "404"`). Setup mode is branded with
|
|
354
|
+
`site.title` instead of a hardcoded theme welcome, and the stub page's body
|
|
355
|
+
renders below the standard content for site-specific additions.
|
|
356
|
+
- **`color_mode_lock` config.** Pin the site to one color mode: visitor
|
|
357
|
+
preference and OS scheme are ignored, the light/dark/auto switcher is
|
|
358
|
+
removed, and `core/color-mode-init.html` + `halfmoon.js` enforce the lock
|
|
359
|
+
pre-paint. Replaces consumer JS workarounds that re-asserted a mode on every
|
|
360
|
+
`matchMedia` change.
|
|
361
|
+
- **PostHog privacy options** (`posthog.privacy.*`): `respect_gpc` (honor the
|
|
362
|
+
Global Privacy Control signal alongside DNT, default on), `require_consent`
|
|
363
|
+
(start opted out with memory-only persistence until the visitor accepts the
|
|
364
|
+
cookie-consent "analytics" category), and `geoip_disable` (no IP→location
|
|
365
|
+
resolution). Upstreams the deltas consumer sites were maintaining in a
|
|
366
|
+
full fork of `analytics/posthog.html`.
|
|
367
|
+
- **`news:` config surface for the news/section layouts.** `category_base`
|
|
368
|
+
(e.g. `/categories/` instead of the hardcoded `/news/`), `index_url`,
|
|
369
|
+
`hero: false`, `archives_url`, and a `newsletter` block (endpoint-or-mailto,
|
|
370
|
+
or hidden entirely — the old markup shipped a form that submitted nowhere).
|
|
371
|
+
|
|
372
|
+
- **ABC board books (`book-abc` layout) — the "ABC & Language" series.** A new
|
|
373
|
+
immersive, single-scroll toddler alphabet layout (`_layouts/book-abc.html`)
|
|
374
|
+
driven entirely by an `alphabet:` front-matter list — one big letter, one
|
|
375
|
+
word, one picture per card, with A–Z quick-jump anchors and a cover hero.
|
|
376
|
+
The big letter is HTML typography (never baked into the art), and a card
|
|
377
|
+
whose plate is still `planned` shows a tinted "illustration coming soon"
|
|
378
|
+
placeholder so a book reads end-to-end before any art renders. New
|
|
379
|
+
`_includes/components/abc-letter.html` renders each card; `_sass/components/_book.scss`
|
|
380
|
+
gains `.abc-board` / `.abc-letter-*` styles plus a `.abc-style--<id>` skin per
|
|
381
|
+
shared art-style id. `components/bookshelf.html` now lists both `book` and
|
|
382
|
+
`book-abc` books, grouped into series shelves from `_data/series.yml`;
|
|
383
|
+
`book-card.html` shows a letter count for ABC books. Ships a demo book
|
|
384
|
+
(`pages/_books/abc-demo/`) + default series metadata (`_data/series.yml`).
|
|
385
|
+
Regression test [`test/visual/features/book-abc.spec.js`](test/visual/features/book-abc.spec.js)
|
|
386
|
+
and before/after evidence in
|
|
387
|
+
[`test/visual/evidence/book-abc/`](test/visual/evidence/book-abc/). Docs:
|
|
388
|
+
[`docs/features/abc-books.md`](docs/features/abc-books.md).
|
|
389
|
+
- **`nav: pages` sidebar mode — auto-build the left tree from page URLs.** A new
|
|
390
|
+
sidebar mode (`_includes/navigation/sidebar-pagetree.html`) derives a
|
|
391
|
+
collapsible section tree purely from page permalinks under a `sidebar.base`
|
|
392
|
+
prefix — no curated `_data/navigation/*.yml` file to write or keep in sync.
|
|
393
|
+
Enable per page / collection / site with `sidebar: {nav: pages, base: /docs/,
|
|
394
|
+
order_by: nav_order, title: …}`. It covers plain pages (`site.html_pages`) and
|
|
395
|
+
collection documents (`site.documents`) alike, groups them by first path
|
|
396
|
+
segment, humanizes section labels from the URL (never leaking a generic
|
|
397
|
+
"Index" title), sorts each section by a numeric `order_by` (natural order),
|
|
398
|
+
supports per-page `sidebar_label` / `sidebar_exclude`, and marks only the
|
|
399
|
+
current page active with its section expanded server-side — pure Liquid, so
|
|
400
|
+
it is GitHub Pages / `remote_theme` safe. Documented at
|
|
401
|
+
`/docs/features/sidebar-page-tree/`.
|
|
402
|
+
- **Claude Code OAuth in the AI installer** — the spec-driven installer
|
|
403
|
+
(`scripts/bin/install`) is now multi-provider. `scripts/install/ai/client.sh`
|
|
404
|
+
resolves a provider via `ZER0_AI_PROVIDER` (default `auto`), preferring the
|
|
405
|
+
logged-in `claude` CLI (**Claude Code OAuth** — zero key handling), then the
|
|
406
|
+
Anthropic Messages API (`CLAUDE_CODE_OAUTH_TOKEN` OAuth bearer or
|
|
407
|
+
`ANTHROPIC_API_KEY`), then OpenAI. `install doctor` reports the active
|
|
408
|
+
provider; `--ai-provider` / `--ai-model` / `ZER0_AI_MODEL` tune it; `--no-ai`
|
|
409
|
+
/ `ZER0_NO_AI=1` disable it. User context is sanitized before every call.
|
|
410
|
+
- **Config-file layer for the installer** — new `scripts/install/config.sh`
|
|
411
|
+
discovers and merges `~/.config/zer0/install.yml`, `<target>/zer0.install.yml`,
|
|
412
|
+
`<target>/.zer0/config.yml`, and `--config FILE` (precedence:
|
|
413
|
+
defaults < profile < config < env < flags). Recognises site / github / theme /
|
|
414
|
+
deploy / agents / tasks / ai keys; API keys stay environment-only.
|
|
415
|
+
- **`install suggest`** subcommand — recommend a profile + deploy target
|
|
416
|
+
(AI-assisted with rule-based fallback) — plus `--yes` as an alias for
|
|
417
|
+
`--auto-accept`.
|
|
418
|
+
- Installer regression matrix (`test/test_installer.sh`) now covers AI
|
|
419
|
+
provider resolution, text extraction across provider shapes, the config-file
|
|
420
|
+
layer + precedence, and the `doctor` AI check (all offline).
|
|
375
421
|
|
|
376
422
|
### Changed
|
|
377
423
|
|
|
424
|
+
- **Navbar label tiers reduced from three to two** ([#405](https://github.com/bamr87/zer0-mistakes/issues/405)).
|
|
425
|
+
Top-level nav items now render as icon + full label above 51rem of centre
|
|
426
|
+
track and icon-only below it; `text-overflow: ellipsis` is gone, so a label
|
|
427
|
+
is never cut to "Quicksta…". Icons now survive in **both** tiers — the old
|
|
428
|
+
41–50.99rem tier dropped them to buy width for bare labels. **Behaviour
|
|
429
|
+
change:** centre-track widths between 41rem and 51rem (roughly 992–1200px
|
|
430
|
+
viewports) previously showed bare labels and now show icons, with the
|
|
431
|
+
existing `.nav-tooltip` carrying the name on hover.
|
|
432
|
+
- **Dropdown chevrons merged into their parent row** ([#405](https://github.com/bamr87/zer0-mistakes/issues/405)).
|
|
433
|
+
The split toggle is now absolutely positioned inside padding the parent link
|
|
434
|
+
reserves, and hover applies to the whole row, so there is no dead zone
|
|
435
|
+
between the label and its chevron. It remains a real `<button>` with
|
|
436
|
+
`aria-expanded`, `aria-haspopup` and its visually-hidden label unchanged.
|
|
437
|
+
(evidence: [`test/visual/evidence/navbar-tiers-405/`](test/visual/evidence/navbar-tiers-405/README.md) — chevron dead zone up to 4px → overlapping; 0 truncated labels across 6 widths)
|
|
438
|
+
- **The navbar carries logo + title only** ([#405](https://github.com/bamr87/zer0-mistakes/issues/405)).
|
|
439
|
+
`site.subtitle` moved out of `_includes/core/branding.html` and onto the home
|
|
440
|
+
hero (`_layouts/home.html`), returning its width to the menubar. It renders
|
|
441
|
+
under the page heading on pages that use the `home` layout, and is hidden
|
|
442
|
+
with it by `hide_title` or `hide_intro`. A homepage on another layout, such
|
|
443
|
+
as `landing`, no longer shows the subtitle at all; add `site.subtitle` to
|
|
444
|
+
that layout's hero to keep it.
|
|
445
|
+
- **The below-`lg` menu toggle is labelled "Menu"** ([#405](https://github.com/bamr87/zer0-mistakes/issues/405)),
|
|
446
|
+
so it is distinguishable from the sidebar hamburger beside it. Override the
|
|
447
|
+
string with `ui.nav_menu_toggle_label`.
|
|
448
|
+
- The desktop navbar grid gives its two side tracks a shared minimum
|
|
449
|
+
(`--zer0-navbar-side-min`, default `9rem`) so the menubar is optically
|
|
450
|
+
centred in the bar rather than only within its own track.
|
|
451
|
+
|
|
452
|
+
- The stable-height spec now walks Connect **first and last** and records
|
|
453
|
+
`#wizardTabContent`'s document-y **top** beside each Back/Next offset. The
|
|
454
|
+
contract itself (`spread ≤ 1`) is unchanged; what is new is that a shift
|
|
455
|
+
*above* the panes now fails as a shift above the panes instead of looking
|
|
456
|
+
like one step with bad CSS. The companion `heights` assertion keeps a comment
|
|
457
|
+
saying it is step-invariant by construction, so it is never again read as
|
|
458
|
+
evidence about anything above the container.
|
|
459
|
+
- **Exactly one `main` landmark again on post, notebook and note pages.**
|
|
460
|
+
`_layouts/{article,notebook,note}.html` each rendered
|
|
461
|
+
`<article id="main" role="main">` *inside* root.html's
|
|
462
|
+
`<main id="main-content">`, so every such page exposed two `main` landmarks —
|
|
463
|
+
ambiguous "skip to main content" and landmark-rotor navigation in
|
|
464
|
+
NVDA/JAWS/VoiceOver (WCAG 2.1 SC 1.3.1) — and the `role` additionally
|
|
465
|
+
overrode the element's native `article` landmark, so the post was no longer
|
|
466
|
+
announced as an article. This is the same class of defect as #299, arriving on
|
|
467
|
+
a `role` attribute instead of a nested `<main>` element. The generic
|
|
468
|
+
`id="main"` is gone with it: nothing in the theme referenced it, and the skip
|
|
469
|
+
link targets `#main-content`. Microdata (`h-entry`, `itemscope`,
|
|
470
|
+
`BlogPosting`/`TechArticle`/`Article`) is unchanged, and the rendered pixels
|
|
471
|
+
are identical. Pinned by `test/visual/core/landmarks.spec.js`
|
|
472
|
+
([#484](https://github.com/bamr87/zer0-mistakes/issues/484)) (evidence:
|
|
473
|
+
[`test/visual/evidence/agent-issue-484/`](test/visual/evidence/agent-issue-484/README.md)
|
|
474
|
+
— base vs head on a post and a note page, page overflow 0px → 0px across 6
|
|
475
|
+
widths, 9 pixel baselines unchanged).
|
|
476
|
+
|
|
477
|
+
- **`claude-run` is now the fleet's shared `ai-runner` kit.** The composite
|
|
478
|
+
action and its new `scripts/ai/run.sh` are byte-identical copies of
|
|
479
|
+
lifehacker.dev's (the kit source of truth) instead of a hand-rolled variant.
|
|
480
|
+
What changes for the two callers (`issue-autopilot.yml`,
|
|
481
|
+
`visual-evidence-autogen.yml`): an AI call that was attempted and rejected —
|
|
482
|
+
revoked credential, exhausted quota, `is_error` payload, CLI install failure
|
|
483
|
+
— now fails the step with the reason as a `::error::` annotation, where the
|
|
484
|
+
old action exited 0 and a dead run read green; the OAuth-first rule is
|
|
485
|
+
enforced with `env -u ANTHROPIC_API_KEY`; the model override is the canonical
|
|
486
|
+
`AI_MODEL` (or the new `model` input) rather than `ZER0_AI_MODEL`, and
|
|
487
|
+
`max-turns` is a new input. Metering (`scripts/ai/usage.rb`,
|
|
488
|
+
`usage_report.rb`, prices in `_data/ai_pricing.yml`) and the Claude API
|
|
489
|
+
fallback (`scripts/ai/api_call.rb`) ride along as optional companions. The
|
|
490
|
+
exit-code contract is pinned by `scripts/ci/test_ai_runner.sh`, wired into
|
|
491
|
+
`./scripts/bin/test`. The action's six existing inputs are unchanged.
|
|
492
|
+
- **`claude-run` is consumed by reference from the hub.** `issue-autopilot.yml` and `visual-evidence-autogen.yml` now call `bamr87/bamr87/.github/actions/claude-run@main` (identical inputs) instead of a vendored `./.github/actions/claude-run`; the local action, `scripts/ai/run.sh`, and the vendored contract test (`scripts/ci/test_ai_runner.sh` + its `scripts/test/lib/` bridge) are deleted, while the consumer companions the hub runner probes for — `scripts/ai/usage.rb`, `usage_report.rb`, `api_call.rb`, `_data/ai.yml`, `_data/ai_pricing.yml`, `tools/unwrap-prose.py` — stay ([bamr87/bamr87#254](https://github.com/bamr87/bamr87/pull/254)).
|
|
493
|
+
- **Consumer registry corrections.** `ai-world-view/ai-world-view.github.io`
|
|
494
|
+
is `remote_theme_floating` (both its `_config.yml` and `hub.yml` pins are
|
|
495
|
+
untagged), not `remote_theme_pinned`; `amr-bash/bash-365.com` is registered
|
|
496
|
+
as a consumer (floating `remote_theme`, unconstrained gem on Azure, path gem
|
|
497
|
+
for dev).
|
|
498
|
+
|
|
378
499
|
- **The page-feedback widget now files the fleet's issue contract, not its own
|
|
379
500
|
(UPS-FB).** The theme built its own issue body, its own escaping, and its own
|
|
380
501
|
URL-length trimming — and so did the 404 page and the AI chat, three builders
|
|
@@ -416,28 +537,6 @@ file. Only `## [Unreleased]` describes work that has not shipped yet.
|
|
|
416
537
|
which also *shrinks* `<head>` and buys back room for the charset meta that has
|
|
417
538
|
to land in the first 1024 bytes (#372).
|
|
418
539
|
|
|
419
|
-
### Fixed
|
|
420
|
-
|
|
421
|
-
- **The 404 page files a report a maintainer can act on.** "Submit an Issue on
|
|
422
|
-
GitHub" opened a hand-built form containing two sentences of boilerplate — no
|
|
423
|
-
page context, no environment, no captured errors. It now opens the feedback
|
|
424
|
-
widget pre-typed as `fix-page` with the URL that failed (and the page that
|
|
425
|
-
linked to it) already in the description.
|
|
426
|
-
|
|
427
|
-
- **The feedback FAB survives its script failing to load.** It was a `<button>`
|
|
428
|
-
whose only behaviour came from JavaScript; with the widget now depending on a
|
|
429
|
-
second script, a 404 on either one would have left a decorative circle in the
|
|
430
|
-
corner. It is an anchor to the issue form, upgraded in place when the script
|
|
431
|
-
runs — the same progressive enhancement the inline "Improve" link already had.
|
|
432
|
-
|
|
433
|
-
- **The page-feedback Playwright spec dismisses the cookie-consent banner.** The
|
|
434
|
-
banner is a full-width bar on a layer above the FAB stack, so it swallowed
|
|
435
|
-
every click aimed at the FAB. Every other spec that touches lower-screen chrome
|
|
436
|
-
already seeded the consent choice through the shared fixture; this one never
|
|
437
|
-
did.
|
|
438
|
-
|
|
439
|
-
### Changed
|
|
440
|
-
|
|
441
540
|
- **TOC scroll spy now bolds the section you are actually reading** — the
|
|
442
541
|
highlighted entry in the right-hand Table of Contents jumped around and sat
|
|
443
542
|
one to three sections ahead of the viewport. Measured on `/docs/features/toc/`
|
|
@@ -566,7 +665,6 @@ file. Only `## [Unreleased]` describes work that has not shipped yet.
|
|
|
566
665
|
constant, plus `test_theme_color_fallback_without_config` covering the
|
|
567
666
|
no-config consumer case.
|
|
568
667
|
|
|
569
|
-
|
|
570
668
|
- **Consumers no longer inherit the theme's own navigation (#332)** — `install.sh`
|
|
571
669
|
copied the theme's entire `_data/` into every consumer, so each site's *own*
|
|
572
670
|
`_data/navigation/*.yml` was a verbatim copy of the theme's and carried the
|
|
@@ -731,105 +829,309 @@ file. Only `## [Unreleased]` describes work that has not shipped yet.
|
|
|
731
829
|
translated page and `_data/i18n/<lang>.yml` will not have them until
|
|
732
830
|
`scripts/translate.rb` next runs.
|
|
733
831
|
|
|
734
|
-
|
|
832
|
+
- **Language selector moved from the navbar into Settings → Appearance** — the
|
|
833
|
+
header utility cluster is now Search + Settings only, returning ~70px to the
|
|
834
|
+
menubar. `components/language-toggle.html` grew a `variant` parameter: the new
|
|
835
|
+
`panel` variant (shipped) renders a self-contained **Language** section — an
|
|
836
|
+
always-visible list of languages with the active one checked and
|
|
837
|
+
untranslated targets disabled — as the first block of the Settings
|
|
838
|
+
Appearance tab, next to Color Mode and Theme Skin. The original header
|
|
839
|
+
dropdown remains available as `variant="navbar"` for consumers that prefer
|
|
840
|
+
it. Same data, same `localStorage("zer0-lang")` preference, same
|
|
841
|
+
never-a-dead-link contract; `test/visual/features/language-toggle.spec.js`
|
|
842
|
+
was updated to exercise it through the Settings panel.
|
|
735
843
|
|
|
736
|
-
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
`
|
|
743
|
-
|
|
744
|
-
— as progressive enhancement, so every amount is still rendered exactly as
|
|
745
|
-
authored with JavaScript disabled. `layout: cookbook` indexes recipes into
|
|
746
|
-
course sections from `_data/recipe_courses.yml`. Twelve new
|
|
747
|
-
`components/recipe-*.html` includes, `_sass/components/_recipe.scss` (with
|
|
748
|
-
print styles), a demo cookbook at `/recipes/`, and docs at
|
|
749
|
-
[Cookbook collection](pages/_docs/features/cookbook-collection.md). Regression
|
|
750
|
-
coverage: `test/visual/features/recipes.spec.js` (smoke tier) and "Cookbook
|
|
751
|
-
Recipe Collection" in `test/test_core.sh` (evidence:
|
|
752
|
-
[`test/visual/evidence/recipes-collection/`](test/visual/evidence/recipes-collection/README.md)
|
|
753
|
-
— 0px page overflow across 320–1440px; 1 cup butter → 227 g, 500 g flour →
|
|
754
|
-
4 cups; ratio percentages identical at 1× and 3×).
|
|
844
|
+
- **`_data/consumers.yml` now covers the whole fleet** — added `zer0-pages`,
|
|
845
|
+
`irony-works`, `wargames` and `zer0-pages-remote`, which were unregistered and
|
|
846
|
+
therefore invisible to `propagate.rb` in both directions (no release dispatch,
|
|
847
|
+
never in the drift report). The `it-journey` risk note was corrected: its
|
|
848
|
+
"~55 shadowed files / ~75 lines of !important CSS working around #338" claim
|
|
849
|
+
is not supported by `audit-consumer` — only 2 files shadow a theme file, the
|
|
850
|
+
CSS is 31 lines in this theme's own documented `user_overrides` hook, and no
|
|
851
|
+
fix numbered #338 could be substantiated in that repo.
|
|
755
852
|
|
|
756
|
-
- **
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
`
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
853
|
+
- **The news/section layouts work with zero `_data`.** Section navigation
|
|
854
|
+
falls back from `_data/navigation/posts.yml` to `site.categories`; the hero
|
|
855
|
+
falls back to the newest post when nothing is marked `breaking`/`featured`;
|
|
856
|
+
tags links render only when a tags page exists (honoring `site.tags_page`);
|
|
857
|
+
archive month links render only when an archives page exists. A data-less
|
|
858
|
+
consumer now gets a fully working magazine homepage instead of empty chrome
|
|
859
|
+
and 404 links.
|
|
860
|
+
- **Zero-`_data` resilience across components.** The skin quick-select and
|
|
861
|
+
theme customizer fall back to the compiled skin registry when
|
|
862
|
+
`_data/theme_skins.yml` is absent; the page-feedback widget falls back to a
|
|
863
|
+
generic four-type taxonomy when `_data/feedback_types.yml` is absent; the
|
|
864
|
+
landing get-started band (theme install cards) renders only when the site
|
|
865
|
+
ships a `landing.get_started` block — a data-less consumer no longer
|
|
866
|
+
advertises the theme's own install methods.
|
|
867
|
+
- **`home` layout accepts `hide_intro` as an alias of `hide_title`**, matching
|
|
868
|
+
the flag other layouts use for "suppress the generated page header".
|
|
869
|
+
- **`halfmoon.js` honors `color_mode_default`.** The switcher no longer
|
|
870
|
+
overrides the configured default with the OS preference on first visit
|
|
871
|
+
(previously the page could flip modes right after load).
|
|
872
|
+
- The default skin fallback is now `air` everywhere (`root.html`,
|
|
873
|
+
controls bar, customizer) — `dark` was never a compiled skin, so the old
|
|
874
|
+
fallback selected a skin that doesn't exist.
|
|
778
875
|
|
|
779
|
-
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
876
|
+
- Installer spec default `ai.provider` is now `auto` (was `openai`); the AI
|
|
877
|
+
wizard records the provider that actually served the run.
|
|
878
|
+
- **CI workflows now honor `CLAUDE_CODE_OAUTH_TOKEN`** — `ui-audit.yml`,
|
|
879
|
+
`ai-content-review.yml`, and `ci-self-repair.yml` previously gated their
|
|
880
|
+
Claude Code agent tier on `ANTHROPIC_API_KEY` alone, silently ignoring a
|
|
881
|
+
configured OAuth token. They now follow the same house convention as
|
|
882
|
+
`claude.yml` / `issue-autopilot.yml`: `CLAUDE_CODE_OAUTH_TOKEN` preferred,
|
|
883
|
+
`ANTHROPIC_API_KEY` used only when it's absent.
|
|
786
884
|
|
|
787
|
-
|
|
788
|
-
part of the site itself: `_design-system/` is force-included in the Jekyll
|
|
789
|
-
build so `styles.css`, every token file, specimen cards, and component
|
|
790
|
-
sources get real URLs under `/_design-system/`; a new `/design/` hub page
|
|
791
|
-
renders the foundation specimens in live iframes (colors, skins, type,
|
|
792
|
-
spacing, radii, motion, layers, iconography), catalogs the component twins,
|
|
793
|
-
and links the Claude Design page canvas (all 24 layouts as a browsable
|
|
794
|
-
presentation). Navbar: About → Design System. Regression spec:
|
|
795
|
-
`test/visual/features/design-hub.spec.js`.
|
|
885
|
+
### Fixed
|
|
796
886
|
|
|
797
|
-
- **
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
`
|
|
803
|
-
|
|
804
|
-
`
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
`
|
|
809
|
-
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
887
|
+
- **Color-mode toggle exposes the selected mode** ([#521](https://github.com/bamr87/zer0-mistakes/issues/521)).
|
|
888
|
+
`_includes/components/halfmoon.html` server-rendered Light/Dark/Auto all
|
|
889
|
+
`aria-pressed="false"`, and on load `assets/js/halfmoon.js` marked the
|
|
890
|
+
*resolved* OS scheme pressed, so a first visit on an `auto` site announced
|
|
891
|
+
"Dark, pressed" (WCAG 4.1.2). The configured mode is now server-rendered
|
|
892
|
+
`.active` + `aria-pressed="true"`, and the script marks the selected *mode*
|
|
893
|
+
(stored preference, else the site default) while still applying the
|
|
894
|
+
resolved scheme to `data-bs-theme`. Pinned by `test/visual/features/settings-panel.spec.js`.
|
|
895
|
+
- **Footer newsletter hint reaches screen readers on phones** ([#522](https://github.com/bamr87/zer0-mistakes/issues/522)).
|
|
896
|
+
The disabled `#footer-email` input's `aria-describedby` pointed at a
|
|
897
|
+
`d-none d-md-block` paragraph, so below `md` its only explanation was
|
|
898
|
+
`display:none`. The describedby target is now an always-present
|
|
899
|
+
`visually-hidden` span, and the visible paragraph is an `aria-hidden` duplicate.
|
|
900
|
+
The sighted layout is unchanged at every width. Pinned by `test/visual/core/accessibility.spec.js`.
|
|
901
|
+
- **Visual Snapshots no longer reload mid-test** ([#461](https://github.com/bamr87/zer0-mistakes/issues/461)).
|
|
902
|
+
`test/update-snapshots.sh` ran `npm ci` into the bind mount Jekyll was already
|
|
903
|
+
watching, and LiveReload reloaded the page under test ("Execution context was
|
|
904
|
+
destroyed"), hidden by `retries: 1`. The snapshot stack now starts with
|
|
905
|
+
`JEKYLL_LIVERELOAD=0` (no `--livereload`, plus `_config_snapshots.yml`, since
|
|
906
|
+
`_config_dev.yml` turns LiveReload on), and `test/lib/assert_no_livereload.sh`
|
|
907
|
+
fails the run if anything can still reload the page. Plain `docker compose up`
|
|
908
|
+
keeps LiveReload.
|
|
909
|
+
- **Mobile offcanvas TOC scroll spy is now under test** ([#457](https://github.com/bamr87/zer0-mistakes/issues/457)).
|
|
910
|
+
`test/visual/features/scroll-spy.spec.js` gains a 375px block that opens the
|
|
911
|
+
`#tocContents` offcanvas and asserts the active entry tracks the page and stays
|
|
912
|
+
visible inside `.offcanvas-body`. The no-op `gotoBeforeScrollSpy` fixture is
|
|
913
|
+
removed (the `data-bs-spy` it stripped is no longer rendered); its admin call
|
|
914
|
+
site uses `waitForJekyll`.
|
|
915
|
+
- **No orphaned microdata in `<head>`** ([#513](https://github.com/bamr87/zer0-mistakes/issues/513)).
|
|
916
|
+
`_includes/core/head.html` emitted `<meta itemprop="headline|description|datePublished|dateModified">`
|
|
917
|
+
with no `itemscope` ancestor, so every parser discarded them. The block is
|
|
918
|
+
removed; jekyll-seo-tag's JSON-LD and the article layouts' `BlogPosting` item
|
|
919
|
+
already publish the same facts. Pinned by `test/visual/core/head-contract.spec.js`.
|
|
920
|
+
- **Valid breadcrumb `BreadcrumbList` when a section has no index page** ([#512](https://github.com/bamr87/zer0-mistakes/issues/512)).
|
|
921
|
+
Since #204, an unlinked crumb ("Posts" on a site without `/posts/`, or a deep
|
|
922
|
+
middle segment) rendered as a `ListItem` with no `item`. That invalidated the
|
|
923
|
+
whole list, and Google dropped the breadcrumb rich result. Such crumbs now stay
|
|
924
|
+
visible as plain text outside the structured list, and `position` is renumbered
|
|
925
|
+
`1..n`. Every remaining `item` resolves. Pinned by `test/visual/features/breadcrumbs.spec.js`
|
|
926
|
+
(evidence: [`test/visual/evidence/breadcrumbs/`](test/visual/evidence/breadcrumbs/README.md):
|
|
927
|
+
the visible trail is unchanged, with 0px overflow before and after).
|
|
928
|
+
|
|
929
|
+
- **Intro action buttons keep their names on phones, nav chevrons meet the 24px target, and badge links are legible on every skin.** Below 576px the Share button and "Edit on GitHub" link in `_includes/content/intro.html` showed only an icon, so axe reported `button-name`/`link-name`; both now carry an `aria-label` matching their visible text. The edit and "View source" URLs no longer contain a double slash (`blob/main//pages/tags.md`) for pages outside a collection. The merged desktop split-toggle chevron (`_sass/core/_navbar.scss`) grows from 20px to 24px wide (WCAG 2.2 SC 2.5.8 `target-size`). Skin link colours (`_sass/theme/_skins.scss`) no longer apply to `a.badge`, which had turned tag/category chips purple-on-purple on neon (1.45:1, now 5.61:1). Regression test: `test/visual/features/intro-actions-a11y.spec.js`.
|
|
930
|
+
- **Closing the search modal returns focus to where it came from.** The modal is opened from code ("/", Ctrl/Cmd+K, the toggle's click handler), so Bootstrap's data-api focus restore never ran and Escape left focus on `<body>` (WCAG 2.4.3). `assets/js/search-modal.js` now remembers the opener (the clicked Search button, or the focused element) and falls back to the visible `[data-search-toggle]` when a shortcut opened it from the document. Two new tests in `test/visual/features/search.spec.js`.
|
|
931
|
+
- **The navbar brand title no longer truncates on phones.** Next to the sidebar toggle, logo, search and the labelled Menu toggle, a 14-character title at the 20px `.navbar-brand` size lost its tail ("Lifehacker.dev" → "Lifehacker…" on lifehacker.dev post pages at 400px: 121px for 133px of text). Below 576px `#navbar .site-title-text` steps down to 1rem (0.9375rem below 375px), and the logo drops Bootstrap's 1rem `margin-end`, which stacked on the brand group's 0.5rem gap. That title now fits from 375px up on pages with the sidebar toggle and from 320px up without it. Two new tests in `test/visual/features/intro-actions-a11y.spec.js`.
|
|
932
|
+
- **The cookie banner no longer covers the first screen.** Below 768px `components/cookie-consent.html` stacked a heading, a long sentence and three full-width buttons (the shim in `_sass/core/_sidebar-extras.scss`): 324px of an 850px-tall 400px viewport on it-journey.dev and lifehacker.dev, hiding most of the hero or article; on desktop it was 94px and sat over the lower hero copy. It is now a compact bar: a two-line summary over one row of three equal buttons on phones, and a single row from 768px up. The layout lives in `_sass/components/_cookie-banner.scss` and the stacking shim is gone. The banner is a labelled `region` ("Cookie consent"), and the button ids, the modal and the consent logic are unchanged. Height at 400px drops from 324px to 107px, and at 1366px from 94px to 48px. Pinned by `test/visual/features/cookie-banner-compact.spec.js`.
|
|
933
|
+
- **The active skin now moves the whole `--zer0-color-*` layer, not just Bootstrap's** ([#459](https://github.com/bamr87/zer0-mistakes/issues/459)). `_includes/core/tokens-inline.html` re-set `--zer0-color-primary`, `-link` and `-accent` from `theme_color` on `:root` after `main.css`. `:root` and `[data-theme-skin]` have the same specificity, so the config value won on source order. On any site that sets `theme_color`, components reading the theme layer therefore kept the config color in every skin, and `--zer0-color-primary` disagreed with its own `-rgb` companion. The skin now wins: those three keys are emitted only when no palette skin is active, as with `dark` and `contrast`. `theme_color` still sets `secondary`, `danger`, `warning`, `success` and `info`, and the Appearance-panel override still beats both. The rule is documented in [`docs/ui/design-tokens.md`](docs/ui/design-tokens.md#precedence-skin-vs-theme_color) and checked by `test/visual/features/appearance.spec.js` (evidence: [`test/visual/evidence/agent-issue-459/`](test/visual/evidence/agent-issue-459/README.md) — page overflow 0px at six widths; the nine skin baselines are unchanged).
|
|
934
|
+
- **A preview path without a leading slash no longer 404s.** `preview: images/previews/x.webp` was appended straight onto `assets_prefix`, so `components/preview-image.html`, `components/background-image.html`, `content/intro.html` and `content/seo.html` emitted `/assetsimages/previews/x.webp` for the card image, the hero background and `og:image` (165 it-journey content files use that form). All four now prepend `/` to a site-relative path before joining; URLs and `data:` URIs are left alone, and already-slashed or `/assets/`-prefixed paths render byte-identically. `preview-image.html` also gained optional `width`/`height` parameters (emitted only when passed); the article layout's related-post cards pass 1536×1024 so their box is reserved before the lazy image arrives (0px → 217px at 1366px). Pinned by the `Preview Path Join` unit test in `test/test_core.sh` and `test/visual/features/preview-path-join.spec.js`.
|
|
935
|
+
- **The sitemap index no longer puts every page in the DOM twice.** `content/sitemap.html` (the `/sitemap/` page, the search modal's "View all results" target, and it-journey.dev's `/search/`) kept all rows attached. Its script also eagerly built a second copy of every row as a card for the hidden card view: about 19,900 elements on it-journey's `/search/` (431 entries), with Lighthouse mobile TBT at 9.7 s. Rows are still rendered server-side, so the page works without JS and with `?q=`. The script now keeps only one page of 50 matches in the document and appends the next page with **Show more**. Search, filters and sorting work across every row, and cards are built on the first switch to card view, one page at a time. Card text is set through `textContent` rather than interpolated HTML. On the theme's own `/sitemap/` (386 entries), elements after load drop from 23,063 to 8,086, and local Lighthouse mobile TBT drops from 1,662 ms to 181 ms. Badge contrast is fixed too: the collection pill is `text-bg-info` (was white on `#0dcaf0`, 1.96:1), tag chips use `--bs-primary-text-emphasis`, and `+N` overflow chips (white on transparent) get body text and a border. Pinned by `test/visual/features/sitemap-pagination.spec.js`.
|
|
936
|
+
- **The xAI preview-image renderer defaults to `grok-imagine-image-2.0`** ([#474](https://github.com/bamr87/zer0-mistakes/issues/474)). `XAIProvider.default_model()` in `scripts/lib/preview_generator.py` still returned the retired `grok-2-image`, so a site with `preview_images.provider: xai` and no explicit `model:` sent a retired model upstream. An explicitly configured `grok-2-image` is still accepted as an xAI-family model.
|
|
937
|
+
- **A code-copy partial no longer restyles every button on the site** ([#412](https://github.com/bamr87/zer0-mistakes/issues/412)). `_sass/core/code-copy.scss` shipped a bare `.button, button:not(.copy)` rule — an element selector at specificity (0,1,1) that out-ranked `.btn` and any consumer's own class, applying `padding: 0 20px`, `font-size: 11px` and a hardcoded `#bbb` border site-wide. It is scoped to `.code-block-header` / `pre.highlight` now and uses `--zer0-*` tokens, so `#bbb` is gone from the compiled stylesheet. Every button on the site — the theme's own chrome included — gets its intended metrics back (evidence: [`test/visual/evidence/agent-issue-412/`](test/visual/evidence/agent-issue-412/README.md) — page overflow 0px at six widths; the nine skin baselines moved, and every red region in their diffs is a `<button>`).
|
|
938
|
+
- **The article hero no longer lazy-loads its LCP image or shoves the article down when it arrives** ([#485](https://github.com/bamr87/zer0-mistakes/issues/485)). `figure.featured-hero` inherited `components/preview-image.html`'s `loading="lazy"` default and had no reserved box. It now passes `loading="eager" fetchpriority="high" decoding="async"`, and its box is pinned by `.featured-hero img { aspect-ratio: 3 / 2 }`. The box is set in CSS rather than with `width`/`height` attributes, because preview assets vary in shape and `object-fit: cover` crops a portrait instead of stretching it. `preview-image.html` gained optional `fetchpriority`/`decoding` parameters that are emitted only when passed, so every other consumer renders byte-identically (evidence: [`test/visual/evidence/hero-lcp/`](test/visual/evidence/hero-lcp/README.md) — hero loading lazy → eager + fetchpriority=high; content shift when the hero lands 476px → 0px across 2 widths × landscape/portrait).
|
|
939
|
+
- **Mermaid, cytoscape and PostHog no longer load up front, and the auto-hide navbar stops forcing reflows.** `assets/js/mermaid-diagrams.js` now converts fences into figures straight away but injects the ~1 MB Mermaid bundle only when a diagram exists and the first one comes within 400px of the viewport (IntersectionObserver); `components/mermaid.html` passes the bundle URL as `window.zer0MermaidSrc` (a script global, not DOM text, and only http(s) URLs are injected) instead of a `<script defer>`. The local-graph panel loads cytoscape on first open instead of on every indexed page. `analytics/posthog.html` keeps the queueing stub but fetches `array.js` after `load` + idle, and `core/head.html` no longer includes it a second time (`root.html` already did, so every production page called `posthog.init()` twice). `auto-hide-nav.js` measures the navbar with a ResizeObserver (rAF read/next-frame write fallback) and caches the height instead of reading `offsetHeight` at DOMContentLoaded and on resize. Lighthouse mobile, local static build: home TBT 1,705 → 651 ms and weight 5,581 → 2,327 KiB; `/docs/features/mermaid-diagrams/` TBT 2,017 → 243 ms; `auto-hide-nav.js` gone from forced-reflow. New lazy-load test in `test/visual/features/mermaid.spec.js`.
|
|
940
|
+
|
|
941
|
+
- **The Site Builder no longer jumps the first time it saves a draft.**
|
|
942
|
+
`showDraftChip()` cleared the "Draft saved" chip's `hidden` attribute, and the
|
|
943
|
+
2s timer that follows only removes `is-visible` — an opacity class — so the
|
|
944
|
+
first debounced save moved the chip from `display: none` into layout *for
|
|
945
|
+
good*. Its box is 26px against the 19px "Start over" button beside it, so
|
|
946
|
+
`.wizard-header` grew and took `#wizardTabContent` and every Back/Next row
|
|
947
|
+
below it down with it: 7px where the header's right-hand block had already
|
|
948
|
+
wrapped, a whole wrapped line where those 7px were what tipped it over. The
|
|
949
|
+
chip now holds its box from first paint and is hidden with `visibility`,
|
|
950
|
+
which is what `_setup-wizard.scss` said it did all along ("Kept in the layout
|
|
951
|
+
(no display toggling) so its appearance never shifts the header") and still
|
|
952
|
+
keeps it out of the accessibility tree when it has nothing to say. This is
|
|
953
|
+
what failed the `@critical` stable-height spec on every push to `main`
|
|
954
|
+
(`2029, 2036, 2036, …`), and with it the retry that spec's failure forced
|
|
955
|
+
([bamr87/bamr87#265](https://github.com/bamr87/bamr87/issues/265)) (evidence:
|
|
956
|
+
[`test/visual/evidence/agent-issue-265/`](test/visual/evidence/agent-issue-265/README.md)
|
|
957
|
+
— first draft save moved the wizard 42px on the base branch, 0px here).
|
|
958
|
+
|
|
959
|
+
- **Two `test_core.sh` checks could never fail, and one shouted on every clean
|
|
960
|
+
run (#460).** The Liquid nested-tag check grepped for
|
|
961
|
+
{% raw %}`{{.*{{`{% endraw %}, which matches
|
|
962
|
+
any two *sibling* output tags on one line — it flagged 64 of the theme's
|
|
963
|
+
includes, starting with `navigation/sidebar-pagetree.html`'s valid
|
|
964
|
+
{% raw %}`{{ _base }}{{ _section }}`{% endraw %} — and its `return 1` sat inside a `find | while`
|
|
965
|
+
pipeline, i.e. a subshell, so the function printed `[ERROR]` and then reported
|
|
966
|
+
the check as passed. The gem-content check ran `tar -tzf` on the built `.gem`,
|
|
967
|
+
but a gem is an *uncompressed* tar wrapping `metadata.gz`, `data.tar.gz` and
|
|
968
|
+
`checksums.yaml.gz`, so gzip printed `stdin: not in gzip format` four times
|
|
969
|
+
and both branches fell through to "Gem may not contain…" without ever
|
|
970
|
+
inspecting the payload — a gem shipped with no `_layouts/` would have passed.
|
|
971
|
+
The nested-tag pattern is now {% raw %}`{{[^}]*{{`{% endraw %} (cannot cross the first `}`, so
|
|
972
|
+
siblings do not match), both loops read from a process substitution so a
|
|
973
|
+
failure propagates, and the gem check extracts `data.tar.gz` and asserts
|
|
974
|
+
`_layouts/` and `assets/` are really in it. The layout balance check, now
|
|
975
|
+
live, blanks Liquid comment bodies before counting, so prose in a comment that
|
|
976
|
+
quotes a closing delimiter (as `_layouts/root.html`'s per-page-scripts note
|
|
977
|
+
does) is no longer read as an unbalanced tag. New `test/test_core_checks.sh`
|
|
978
|
+
drives both checks against known-good and known-bad fixtures, so a check that
|
|
979
|
+
stops being able to fail is itself a test failure. `./test/test_core.sh` now
|
|
980
|
+
runs clean: 26/26, no `[ERROR]` line, no gzip/tar noise.
|
|
981
|
+
- **Every navbar link emitted invalid HTML — attributes glued together with no
|
|
982
|
+
separating whitespace (#465)** — the Liquid whitespace-trim markers around the
|
|
983
|
+
conditional `aria-current` in `_includes/navigation/navbar.html` ate the
|
|
984
|
+
newlines that separated the surrounding attributes, so the primary nav
|
|
985
|
+
rendered `aria-label="News"aria-current="page"title="News"` (the WHATWG
|
|
986
|
+
`missing-whitespace-between-attributes` parse error). The leading {% raw %}`{%-`{% endraw %}
|
|
987
|
+
stripped the newline after `aria-label` and the trailing {% raw %}`-%}`{% endraw %} the whitespace
|
|
988
|
+
before `title`, which means **two of the four sites were broken on every page,
|
|
989
|
+
not just the current one**: where the conditional sits between two
|
|
990
|
+
unconditional attributes both markers fire even when the `if` emits nothing.
|
|
991
|
+
Parsers recover, so nothing looked broken — but the attributes affected are
|
|
992
|
+
exactly `aria-label`, `aria-current` and `title`, and a stricter parser is
|
|
993
|
+
entitled to drop the "you are here" announcement for screen-reader users. All
|
|
994
|
+
four sites now use the non-trimming {% raw %}`{% if %}`{% endraw %} form already present at line 26
|
|
995
|
+
of the same file, with the separator outside the tag. Two guards in
|
|
996
|
+
`test/test_core.sh`: `test_navbar_attribute_whitespace` renders the real
|
|
997
|
+
include through Liquid across both `aria-current` branches and both nav modes
|
|
998
|
+
(6 of 8 rendered variants were invalid before the fix), and
|
|
999
|
+
`test_attribute_whitespace_in_markup` models the trim rules over every include
|
|
1000
|
+
and layout with no gem dependency — it found a second live instance, a literal
|
|
1001
|
+
missing space in `components/theme-preview-gallery.html`, fixed here too.
|
|
1002
|
+
`test_jekyll_build` re-checks the delivered `_site` bytes. No visual change.
|
|
1003
|
+
- **The weekly UI/UX audit was blind, and reported it as clean.** `sweep.mjs`
|
|
1004
|
+
built its pages with `browser.newPage()`, which `@axe-core/playwright`
|
|
1005
|
+
refuses; the throw was caught by a single per-route `try` that also discarded
|
|
1006
|
+
the overflow, console-error and link-collection data already gathered for
|
|
1007
|
+
that route. Screenshots still succeeded, so the harness looked alive while
|
|
1008
|
+
every accessibility, console, overflow and broken-link result on every route
|
|
1009
|
+
was silently dropped — and the report rendered the absence as "0 axe
|
|
1010
|
+
violations / 0 broken links". Pages are now built from `browser.newContext()`,
|
|
1011
|
+
each measurement fails independently, a scan that errored is reported as
|
|
1012
|
+
UNKNOWN rather than clean, and a measurement that fails on every route turns
|
|
1013
|
+
the sweep red the way a total capture failure already did. On the demo site
|
|
1014
|
+
the sweep goes from 18/21 captured with 21 blackout entries to **21/21
|
|
1015
|
+
captured, 0 harness errors, 191 links crawled and 8 genuinely broken links
|
|
1016
|
+
found** ([#468](https://github.com/bamr87/zer0-mistakes/issues/468)).
|
|
1017
|
+
- **Theme-skin buttons now announce which skin is applied.** The Theme Skin
|
|
1018
|
+
group in Settings → Appearance conveyed selection only through the Bootstrap
|
|
1019
|
+
`.active` class, which carries no accessibility semantics, so screen readers
|
|
1020
|
+
announced nine identical unlabelled buttons — WCAG 2.1 SC 4.1.2 (Name, Role,
|
|
1021
|
+
Value). Each button now ships `aria-pressed`, and the click and "Reset
|
|
1022
|
+
background" handlers keep it in sync with `.active` through one shared
|
|
1023
|
+
helper, matching the sibling color-mode group
|
|
1024
|
+
([#467](https://github.com/bamr87/zer0-mistakes/issues/467)).
|
|
817
1025
|
|
|
818
|
-
|
|
1026
|
+
- **Generated posts and notes were invisible on GitHub Pages** — every dated
|
|
1027
|
+
document the wizard wrote was stamped `T09:00:00.000Z` on the day it was
|
|
1028
|
+
generated. Jekyll refuses to publish future-dated documents unless
|
|
1029
|
+
`future: true`, and GitHub Pages builds with the default, so a site generated
|
|
1030
|
+
before 09:00 UTC went live with its posts and notes missing: linked from the
|
|
1031
|
+
collection index and listed in the sitemap, but 404 when clicked. Generated
|
|
1032
|
+
content is now stamped with the actual moment it was written, and a
|
|
1033
|
+
regression test fails if any generated document carries a future date.
|
|
1034
|
+
Found by publishing two example sites and clicking the links.
|
|
1035
|
+
- **Every page of every generated site 404'd on `user-overrides.js`** — the
|
|
1036
|
+
Site Builder writes `user_overrides: true` so the theme loads the palette and
|
|
1037
|
+
font overrides it generates, but that same flag also makes the theme load
|
|
1038
|
+
`assets/js/user-overrides.js`, which the wizard never created. Generated
|
|
1039
|
+
sites now ship a commented stub, so the request resolves and site owners have
|
|
1040
|
+
an obvious place to put their own JavaScript. Found while publishing example
|
|
1041
|
+
sites built by the wizard.
|
|
1042
|
+
- **Every generated landing page shipped an invisible button** —
|
|
1043
|
+
`components/cta-button.html` mapped `variant: outline` to `btn-outline-light`,
|
|
1044
|
+
which is white text on a white border, and the Site Builder's own default
|
|
1045
|
+
call to action uses `outline` on a light hero. `outline` is now an outlined
|
|
1046
|
+
*primary* button; `outline-light` is the explicit variant for a dark surface,
|
|
1047
|
+
and the generated landing engine picks between them from `hero.variant`.
|
|
1048
|
+
The theme's own homepage hero is `bg-primary text-white`, so its two
|
|
1049
|
+
outlined buttons moved to `outline-light` and render exactly as before —
|
|
1050
|
+
a consumer who copied `_data/landing.yml` into a site with a dark hero
|
|
1051
|
+
should make the same one-word change.
|
|
1052
|
+
- **A planned `landing.hero.image` was accepted and then thrown away** — the
|
|
1053
|
+
site plan's schema has offered `landing.hero.image` since the Site Builder
|
|
1054
|
+
shipped, but the landing engine it generates never rendered it, so an agent
|
|
1055
|
+
(or a human) could set a hero image, see it validated, watch it land in
|
|
1056
|
+
`_data/landing.yml`, and get a landing page with no picture. `index.md` now
|
|
1057
|
+
renders it inside the hero, decorative (empty `alt`) so a screen reader does
|
|
1058
|
+
not hear the headline twice. Found by building a site end to end through the
|
|
1059
|
+
new Grok path, where the "Hero image with …" shortcut pointed straight at the
|
|
1060
|
+
dead field.
|
|
1061
|
+
- **A partial hero patch silently wiped the rest of the hero** —
|
|
1062
|
+
`set_site_plan` replaced `landing.hero` wholesale, so the natural agent move
|
|
1063
|
+
of "write the copy now, add the artwork two turns later"
|
|
1064
|
+
(`{landing: {hero: {image}}}`) discarded the headline, subheadline and every
|
|
1065
|
+
call to action, and the landing page quietly reverted to the site title and
|
|
1066
|
+
the default buttons. The hero now merges field by field; `sections`,
|
|
1067
|
+
`navigation.items` and `pages` still replace, because a shorter list has to
|
|
1068
|
+
mean a shorter list. The tool description says so, and the regression test
|
|
1069
|
+
pins both halves.
|
|
819
1070
|
|
|
820
|
-
- **
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
dropdown remains available as `variant="navbar"` for consumers that prefer
|
|
828
|
-
it. Same data, same `localStorage("zer0-lang")` preference, same
|
|
829
|
-
never-a-dead-link contract; `test/visual/features/language-toggle.spec.js`
|
|
830
|
-
was updated to exercise it through the Settings panel.
|
|
1071
|
+
- **A new post appeared at its own URL but on no index** — the generated
|
|
1072
|
+
`_config_dev.yml` turned on Jekyll's experimental incremental regeneration,
|
|
1073
|
+
which rebuilds only documents whose own source changed. Adding a post left
|
|
1074
|
+
the collection index, the home page's latest-posts list and the feed showing
|
|
1075
|
+
the old set, with the post reachable only by typing its URL. New sites are
|
|
1076
|
+
now generated with `incremental: false`; a full rebuild of a fresh site takes
|
|
1077
|
+
about a second and is always right.
|
|
831
1078
|
|
|
832
|
-
|
|
1079
|
+
- **The 15-second status poll handed the composer back mid-turn** — the Site
|
|
1080
|
+
Builder's proxy poll rebuilt the panel's enabled state from the connection
|
|
1081
|
+
alone, so during a long action (a Docker build, an image render) the input
|
|
1082
|
+
and Send button re-enabled themselves and the Stop button vanished, while
|
|
1083
|
+
tools were still running. A second message could then interleave with the
|
|
1084
|
+
first. The poll now respects the busy state.
|
|
1085
|
+
- **A newly added post never appeared on the running site** — Jekyll's
|
|
1086
|
+
`--watch` only tracks collection documents that existed when `serve` started,
|
|
1087
|
+
so a page or post the assistant added to a running project stayed invisible
|
|
1088
|
+
with no explanation. `write_project_file` now says so in its result and
|
|
1089
|
+
offers a restart, and `run_compose` gained a `restart` action.
|
|
1090
|
+
|
|
1091
|
+
- **Switching colour mode destroyed every Mermaid diagram** — the old include's
|
|
1092
|
+
`MutationObserver` re-render emptied each `.mermaid` div and refilled it with
|
|
1093
|
+
the div's *current* text, which after the first render is the SVG's own
|
|
1094
|
+
stylesheet, and never cleared Mermaid's `data-processed` flag, so
|
|
1095
|
+
`mermaid.run()` skipped the div. Toggling dark mode on `/quickstart/`,
|
|
1096
|
+
`/about/` or `/docs/ruby-101/` replaced the diagram with a wall of
|
|
1097
|
+
`#mermaid-… {font-family: …}` text and a permanent "Loading diagram…" label
|
|
1098
|
+
(reproduced headlessly on `main`: `svgs: 1 → 0` after the toggle). Sources are
|
|
1099
|
+
now kept per figure and every render goes through `mermaid.render()`, so a
|
|
1100
|
+
mode or skin change re-renders from the original definition — asserted by the
|
|
1101
|
+
regression test in `test/visual/features/mermaid.spec.js`.
|
|
1102
|
+
- **The Obsidian wiki-link resolver rewrote the inside of inline SVGs** —
|
|
1103
|
+
`assets/js/obsidian-wiki-links.js` skips text under `CODE`/`PRE`/`A`/
|
|
1104
|
+
`SCRIPT`/`STYLE` by comparing `nodeName`, but elements in the SVG namespace
|
|
1105
|
+
report it in lower case (`style`, `text`), so a Mermaid diagram's own
|
|
1106
|
+
`<style>` was walked and every `#id` selector in it was turned into a
|
|
1107
|
+
`<a class="obsidian-tag">` link. The stylesheet lost its scoping: one
|
|
1108
|
+
diagram's `#arrowhead path { fill }` became a bare `path { fill }` for the
|
|
1109
|
+
whole page, and pie slices rendered dark grey while their legend showed the
|
|
1110
|
+
right colours. The old include escaped it only because the resolver
|
|
1111
|
+
special-cases the `.mermaid` class. The name check is now case-insensitive
|
|
1112
|
+
and any `<svg>` subtree (graphics, never prose) is skipped, with
|
|
1113
|
+
`.zer0-diagram` added to the class exemptions. `test/test_resolver.js` gains
|
|
1114
|
+
a fixture with a lower-case `style`/`text` inside `<svg>`, and the Mermaid
|
|
1115
|
+
spec asserts a pie slice's computed fill equals its own attribute and that no
|
|
1116
|
+
unscoped `path` rule exists on the page.
|
|
1117
|
+
|
|
1118
|
+
- **The 404 page files a report a maintainer can act on.** "Submit an Issue on
|
|
1119
|
+
GitHub" opened a hand-built form containing two sentences of boilerplate — no
|
|
1120
|
+
page context, no environment, no captured errors. It now opens the feedback
|
|
1121
|
+
widget pre-typed as `fix-page` with the URL that failed (and the page that
|
|
1122
|
+
linked to it) already in the description.
|
|
1123
|
+
|
|
1124
|
+
- **The feedback FAB survives its script failing to load.** It was a `<button>`
|
|
1125
|
+
whose only behaviour came from JavaScript; with the widget now depending on a
|
|
1126
|
+
second script, a 404 on either one would have left a decorative circle in the
|
|
1127
|
+
corner. It is an anchor to the issue form, upgraded in place when the script
|
|
1128
|
+
runs — the same progressive enhancement the inline "Improve" link already had.
|
|
1129
|
+
|
|
1130
|
+
- **The page-feedback Playwright spec dismisses the cookie-consent banner.** The
|
|
1131
|
+
banner is a full-width bar on a layer above the FAB stack, so it swallowed
|
|
1132
|
+
every click aimed at the FAB. Every other spec that touches lower-screen chrome
|
|
1133
|
+
already seeded the consent choice through the shared fixture; this one never
|
|
1134
|
+
did.
|
|
833
1135
|
|
|
834
1136
|
- **Finished work kept reopening its own issues** — `scripts/sync-backlog.rb`
|
|
835
1137
|
treats `_data/backlog.yml` as the source of truth and **reopens** any issue whose
|
|
@@ -1007,7 +1309,6 @@ worse than none.
|
|
|
1007
1309
|
`#info-section` above it, for browsers without `:has()`. Covered by "Settings
|
|
1008
1310
|
opened from the nav menu paints ABOVE it" in
|
|
1009
1311
|
`test/visual/features/mobile-overlay-stacking.spec.js` (evidence:
|
|
1010
|
-
[`test/visual/evidence/navbar-fit/`](test/visual/evidence/navbar-fit/README.md)
|
|
1011
1312
|
— `03-settings-stacking.png`: top element at the panel centre `a.nav-link`
|
|
1012
1313
|
→ the panel's own content; header `z-index` 1046 → 1030).
|
|
1013
1314
|
|
|
@@ -1106,49 +1407,6 @@ worse than none.
|
|
|
1106
1407
|
builds in safe mode and loads no local plugins, so nothing the theme ships is
|
|
1107
1408
|
mandatory; `required_plugin_paths` is now empty and the plugin is optional.
|
|
1108
1409
|
|
|
1109
|
-
### Changed
|
|
1110
|
-
|
|
1111
|
-
- **`_data/consumers.yml` now covers the whole fleet** — added `zer0-pages`,
|
|
1112
|
-
`irony-works`, `wargames` and `zer0-pages-remote`, which were unregistered and
|
|
1113
|
-
therefore invisible to `propagate.rb` in both directions (no release dispatch,
|
|
1114
|
-
never in the drift report). The `it-journey` risk note was corrected: its
|
|
1115
|
-
"~55 shadowed files / ~75 lines of !important CSS working around #338" claim
|
|
1116
|
-
is not supported by `audit-consumer` — only 2 files shadow a theme file, the
|
|
1117
|
-
CSS is 31 lines in this theme's own documented `user_overrides` hook, and no
|
|
1118
|
-
fix numbered #338 could be substantiated in that repo.
|
|
1119
|
-
|
|
1120
|
-
## [1.28.0](https://github.com/bamr87/zer0-mistakes/compare/v1.27.0...v1.28.0) (2026-08-09)
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
### Features
|
|
1124
|
-
|
|
1125
|
-
* **books:** children's picture-book collection with immersive layouts and components ([#328](https://github.com/bamr87/zer0-mistakes/issues/328)) ([e059d1a](https://github.com/bamr87/zer0-mistakes/commit/e059d1afdc95073c5ce5bf9d1516b362979ad402))
|
|
1126
|
-
* **ci:** deploy the site via Actions so examples reach the live domain ([#353](https://github.com/bamr87/zer0-mistakes/issues/353)) ([959243c](https://github.com/bamr87/zer0-mistakes/commit/959243c0e8e504fe5d8dba44b89016b413bc88da))
|
|
1127
|
-
* **docs:** theme-canary reporting contract for downstream theme-scouts (FF-0019) ([#358](https://github.com/bamr87/zer0-mistakes/issues/358)) ([c1c1b30](https://github.com/bamr87/zer0-mistakes/commit/c1c1b309c5504b014602982fc96ec80c3f8f70de))
|
|
1128
|
-
* **examples:** add serialized reading-blog example site ([#339](https://github.com/bamr87/zer0-mistakes/issues/339)) ([aca0b53](https://github.com/bamr87/zer0-mistakes/commit/aca0b53b88067bda80fb299f9d5148ccb185d618))
|
|
1129
|
-
* **includes:** config-driven favicon, GTM gating, og:image fallback fix, sidebar nav aliases ([#327](https://github.com/bamr87/zer0-mistakes/issues/327)) ([fe8aacc](https://github.com/bamr87/zer0-mistakes/commit/fe8aacc234003f9f170fcb3b8b29c60ac18ed94b))
|
|
1130
|
-
* **install:** Claude Code OAuth + multi-provider AI + config-file layer ([#330](https://github.com/bamr87/zer0-mistakes/issues/330)) ([fde414c](https://github.com/bamr87/zer0-mistakes/commit/fde414cce5286f90de1ad02ca6ca40d634be5611))
|
|
1131
|
-
* **layouts:** book-abc board-book layout + ABC art-style skins ([#336](https://github.com/bamr87/zer0-mistakes/issues/336)) ([d88038e](https://github.com/bamr87/zer0-mistakes/commit/d88038e806e0d1a492e5d12b4e10e55fd240d692))
|
|
1132
|
-
* **navigation:** nav: pages sidebar mode — auto-build the tree from page URLs ([#333](https://github.com/bamr87/zer0-mistakes/issues/333)) ([c0c627d](https://github.com/bamr87/zer0-mistakes/commit/c0c627d5f50051e8f5eb4f0d6681244acaaa8d85))
|
|
1133
|
-
* **obsidian:** revamp graph frontend with Obsidian-style controls ([#366](https://github.com/bamr87/zer0-mistakes/issues/366)) ([7143d9c](https://github.com/bamr87/zer0-mistakes/commit/7143d9cd137408ad82981c9f9835204bab3a3db5))
|
|
1134
|
-
* **theme:** consumer-adoption hardening — mobile overlay fixes, zero-data resilience, extension hooks ([#338](https://github.com/bamr87/zer0-mistakes/issues/338)) ([84bcce1](https://github.com/bamr87/zer0-mistakes/commit/84bcce15e66b0bc312f513cef4a9dd11f972a049))
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
### Bug Fixes
|
|
1138
|
-
|
|
1139
|
-
* **books:** pin abc-demo permalink so its cover lands at /books/abc-demo/ ([#345](https://github.com/bamr87/zer0-mistakes/issues/345)) ([943f463](https://github.com/bamr87/zer0-mistakes/commit/943f463c73081e7cc3d914c28a2ec2eea3d1b5ae))
|
|
1140
|
-
* **ci:** give the Dependabot label job an explicit GH_REPO ([#370](https://github.com/bamr87/zer0-mistakes/issues/370)) ([808b20e](https://github.com/bamr87/zer0-mistakes/commit/808b20ebbdcd5b0bc139b90947297cec6d226787))
|
|
1141
|
-
* **ci:** prefer CLAUDE_CODE_OAUTH_TOKEN over ANTHROPIC_API_KEY in all AI workflows ([#334](https://github.com/bamr87/zer0-mistakes/issues/334)) ([043848e](https://github.com/bamr87/zer0-mistakes/commit/043848eb84222240efc121e8112ddc12ab959a64))
|
|
1142
|
-
* **ci:** unbreak the production Pages build, frozen since 2026-08-05 ([#356](https://github.com/bamr87/zer0-mistakes/issues/356)) ([05465cf](https://github.com/bamr87/zer0-mistakes/commit/05465cfd5480a6bdfb0d164d56a892f2825ec1cf))
|
|
1143
|
-
* **i18n:** exclude admin config page from translation to unbreak Pages deploy ([#349](https://github.com/bamr87/zer0-mistakes/issues/349)) ([3f4890c](https://github.com/bamr87/zer0-mistakes/commit/3f4890cee3dd59b7f1cbc6ec235a863017b075fb))
|
|
1144
|
-
* **i18n:** normalise generated prose so translation runs keep CI green ([#342](https://github.com/bamr87/zer0-mistakes/issues/342)) ([70a7234](https://github.com/bamr87/zer0-mistakes/commit/70a723425b8cc6a77e1b845b212a8a7d127a7779))
|
|
1145
|
-
* **navigation:** mark only the current page active in the sidebar nav-tree ([#331](https://github.com/bamr87/zer0-mistakes/issues/331)) ([3f1b723](https://github.com/bamr87/zer0-mistakes/commit/3f1b723169258993d4530dd5817740e62734ccd4))
|
|
1146
|
-
* **sass:** restore mobile navigation in the example, collapsed to a 60px sliver ([#363](https://github.com/bamr87/zer0-mistakes/issues/363)) ([8c7d87a](https://github.com/bamr87/zer0-mistakes/commit/8c7d87af4fd476f06c16ce58ca4d4cd0e2c4169d))
|
|
1147
|
-
|
|
1148
|
-
## [Unreleased]
|
|
1149
|
-
|
|
1150
|
-
### Fixed
|
|
1151
|
-
|
|
1152
1410
|
- **The skip link never moved keyboard focus (#278)** — `_layouts/root.html`
|
|
1153
1411
|
rendered `<main id="main-content">` with no `tabindex`, and `<main>` is not natively focusable, so activating "Skip to main content" scrolled the page while focus stayed on `<body>`: the next `Tab` returned the user to the header nav they had just skipped. That defeats WCAG 2.4.1 (Bypass Blocks) on every consuming site, and the theme's own docs already prescribed the fix (`skip-to-content.md` → *Focus Not Moving* → "Add `tabindex=\"-1\"` to target") while the shipped layout omitted it. Now `<main id="main-content" tabindex="-1">`, paired with `#main-content:focus { outline: none; }` in `_sass/utilities/_focus.scss` so the container does not paint a ring — descendants keep theirs, and the rule is safe only because `-1` keeps the container out of the sequential `Tab` order. Measured across all three engines: focus lands on `#main-content` in Chromium, Firefox **and WebKit** (the engine the report named), where before it moved in none of them. The stale `<div id="main-content">` example in the English and French docs now matches the shipped markup.
|
|
1154
1412
|
- **Seven theme dialogs labelled themselves with a bare `<h5>`** — the search
|
|
@@ -1166,40 +1424,6 @@ widget showed `An error occurred: giscus is not installed on this repository` in
|
|
|
1166
1424
|
- **Docs claimed the widget "won't load on localhost"** — it does. Giscus keys
|
|
1167
1425
|
off the `data-repo` attribute, not the page origin, so the iframe renders and reports real errors locally. The false claim told developers to expect a non-working widget in dev, which is precisely what hid this bug. `pages/_docs/features/giscus-comments.md` now documents localhost as a genuine end-to-end check, with a table mapping each rendered state to its cause.
|
|
1168
1426
|
|
|
1169
|
-
### Added
|
|
1170
|
-
|
|
1171
|
-
- **`giscus-discussions doctor`** — a new subcommand that verifies the entire
|
|
1172
|
-
comment chain end-to-end: repository public, Discussions enabled, `giscus.enabled: true`, `data-repo-id` actually belonging to this repo (the fork trap), `data-category-id` resolving to a real category, and — the part nothing else could check — whether the giscus GitHub App is installed, by asking the Giscus API itself. Exits non-zero with a specific remediation line per failure.
|
|
1173
|
-
- **Giscus health check in CI** — `.github/workflows/giscus-digest.yml` (already
|
|
1174
|
-
scheduled weekly) now runs `doctor` and fails the job with a summary when comments are down, so a sitewide comment outage surfaces on its own instead of waiting for a reader to report it.
|
|
1175
|
-
- **Troubleshooting: "The giscus app is not installed"** — a new section in the
|
|
1176
|
-
feature docs with captured screenshots of both the broken widget and the giscus.app configurator rejecting the repo, an explanation of why this step is uniquely easy to skip, a fork-specific warning, and a copy-pasteable `curl` health check.
|
|
1177
|
-
- **Obsidian graph frontend revamp** — the graph views now mirror the Obsidian
|
|
1178
|
-
desktop experience. The full graph page gains a floating **Graph settings**
|
|
1179
|
-
card (Filters / Display / Forces): search with `tag:`/`path:` operators,
|
|
1180
|
-
per-collection toggles generated from the wiki-index (count badge + color
|
|
1181
|
-
swatch, doubling as the legend), show-orphans and show-unresolved switches,
|
|
1182
|
-
node-size / link-thickness / label-fade sliders, repel-force and
|
|
1183
|
-
link-distance sliders with animated re-layout, plus a zoom / fit / fullscreen
|
|
1184
|
-
button stack, an Obsidian-style hover preview card, live dark-mode restyling,
|
|
1185
|
-
and localStorage persistence. The local graph panel gains a depth selector
|
|
1186
|
-
(1–3) and outgoing/incoming direction switches that re-render the subgraph in
|
|
1187
|
-
place. Same vendored cytoscape.js, unchanged `wiki-index.json` contract
|
|
1188
|
-
(evidence:
|
|
1189
|
-
[`test/visual/evidence/obsidian-graph-revamp/`](test/visual/evidence/obsidian-graph-revamp/README.md);
|
|
1190
|
-
regression: `test/visual/features/obsidian-graph.spec.js`).
|
|
1191
|
-
|
|
1192
|
-
- **Theme-canary reporting contract** (`docs/systems/theme-canary-contract.md`) —
|
|
1193
|
-
the canonical upstream bug-intake protocol for downstream theme-scout agents
|
|
1194
|
-
(it-journey, lifehacker.dev): required `theme-canary` + `from-<consumer>`
|
|
1195
|
-
labels, a deterministic 12-hex dedupe key + hidden body marker, the mandated
|
|
1196
|
-
open-AND-closed pre-filing search, a 5-issues-per-consumer-per-run cap, and a
|
|
1197
|
-
required evidence format that records the theme version/commit observed (so
|
|
1198
|
-
fixed-in-release triage is mechanical). Ships with the matching
|
|
1199
|
-
`theme-canary.yml` issue form.
|
|
1200
|
-
|
|
1201
|
-
### Fixed
|
|
1202
|
-
|
|
1203
1427
|
- **Mobile navigation opened as an unusable 60px sliver in the Swerve of Shore
|
|
1204
1428
|
example.** Its skin set `backdrop-filter` on `.navbar` for a frosted sticky
|
|
1205
1429
|
header, which — per the CSS spec, alongside `transform`/`filter`/`perspective`
|
|
@@ -1279,116 +1503,6 @@ feature docs with captured screenshots of both the broken widget and the giscus.
|
|
|
1279
1503
|
provider that soft-wraps at 40 columns. Asserting "output is unwrapped"
|
|
1280
1504
|
against the plain stub would have passed whether or not normalisation ran.
|
|
1281
1505
|
|
|
1282
|
-
### Added
|
|
1283
|
-
|
|
1284
|
-
- **`examples/` — self-contained demo sites built on the theme.** New top-level
|
|
1285
|
-
directory (excluded from the theme's own site build and from the gem) for
|
|
1286
|
-
complete Jekyll sites that show the theme configured for a particular kind of
|
|
1287
|
-
site. Each has its own `_config.yml`, `Gemfile`, and content, and builds
|
|
1288
|
-
against the local theme sources via `_config_dev.yml`.
|
|
1289
|
-
- `examples/swerve-of-shore/` — **Swerve of Shore**, a serialized literary
|
|
1290
|
-
reading blog rebuilt from
|
|
1291
|
-
[swerveofshore.com](https://www.swerveofshore.com/) with the site owner's
|
|
1292
|
-
permission. 52 pages, 0 broken internal links. Exercises a `series` output
|
|
1293
|
-
collection with nested per-section paths, a data-driven taxonomy
|
|
1294
|
-
(`_data/episodes.yml`) that generates the sidebar rail, the episode
|
|
1295
|
-
schedule with live entry counts, and a section page for every node — so a
|
|
1296
|
-
nav target resolves even where nothing is written yet. Also covers article
|
|
1297
|
-
hero images (`show_hero`), entries ordered by number rather than date, the
|
|
1298
|
-
shared `post-card` component in a single-column feed, and a full editorial
|
|
1299
|
-
light-mode restyle done entirely through `assets/css/user-overrides.css` —
|
|
1300
|
-
no theme files touched. The site's identity, taxonomy, entry titles/dates,
|
|
1301
|
-
and featured images are reproduced, along with a short quoted excerpt per
|
|
1302
|
-
entry (the opening the original publishes in its own RSS feed), attributed
|
|
1303
|
-
and linked back. The essays themselves are not reproduced.
|
|
1304
|
-
- `examples/README.md` — how to run one and the conventions for adding
|
|
1305
|
-
another.
|
|
1306
|
-
- **Theme propagation system — releases now reach the sites built on them.**
|
|
1307
|
-
Releasing ended at RubyGems; nothing told the five downstream consumers a new
|
|
1308
|
-
version existed, so all three pinned sites were still on v1.26.0 when v1.27.0
|
|
1309
|
-
shipped and the two unpinned ones had been silently tracking `main`.
|
|
1310
|
-
- `_data/consumers.yml` — registry of every consumer, its consumption mode
|
|
1311
|
-
(`remote_theme_pinned` / `remote_theme_floating` / `gem` / `path`), and every
|
|
1312
|
-
file that holds a version pin.
|
|
1313
|
-
- `scripts/propagate.rb` — reports pin drift across the registry
|
|
1314
|
-
(`--format text|json|github`, `--strict`) or dispatches a `theme-release`
|
|
1315
|
-
event to each consumer (`--dispatch`).
|
|
1316
|
-
- `.github/workflows/propagate-theme.yml` — dispatches on release publish;
|
|
1317
|
-
weekly drift report. Never pushes to a consumer: each one opens its own PR so
|
|
1318
|
-
its own CI gates the bump.
|
|
1319
|
-
- `templates/consumer/` — the consumer's half of the contract:
|
|
1320
|
-
`bump-theme-pins.sh` (rewrites `remote_theme`, `theme_repo`, and Gemfile gem
|
|
1321
|
-
constraints in one pass; `--check`, `--dry-run`, `--latest`, `--pin`),
|
|
1322
|
-
`theme-bump.yml` (dispatch + weekly schedule + manual), and a
|
|
1323
|
-
`.theme-overrides.yml` starter. The schedule matters most for gem-mode
|
|
1324
|
-
consumers, which have no `remote_theme` and so pick up nothing automatically.
|
|
1325
|
-
- `docs/systems/theme-propagation.md` — how the whole flow fits together.
|
|
1326
|
-
- **`./scripts/bin/manifest --check`** — verifies the committed theme manifest
|
|
1327
|
-
matches the working tree, ignoring `generated_at`. `--dry-run` now emits only
|
|
1328
|
-
YAML on stdout (progress logs moved to stderr) so its output can be diffed
|
|
1329
|
-
directly.
|
|
1330
|
-
- **Consumer extension hooks (`_includes/custom/`).** Four empty stubs the
|
|
1331
|
-
chrome now includes at fixed points — `custom/head.html` (end of `<head>`),
|
|
1332
|
-
`custom/body-start.html` (right after `<body>`, e.g. GTM noscript),
|
|
1333
|
-
`custom/footer.html` (after the theme footer), `custom/body-end.html` (last
|
|
1334
|
-
thing before `</body>`). A consumer site shadows just the stub to inject
|
|
1335
|
-
JSON-LD, fonts, verification tags, or scripts — no more forking
|
|
1336
|
-
`core/head.html`/`root.html` and drifting from the theme. Documented in
|
|
1337
|
-
`_includes/README.md`.
|
|
1338
|
-
- **`components/card-grid.html` + `components/data-card.html`.** A generic,
|
|
1339
|
-
data-driven card grid (title/url/icon/badge/meta-pills/buttons schema) for
|
|
1340
|
-
org hub dashboards, fleet registries, service grids, and link boards —
|
|
1341
|
-
the markup consumer sites have been hand-rolling per page. Includes an
|
|
1342
|
-
optional empty-state message.
|
|
1343
|
-
- **`_layouts/404.html` — the 404 page as a theme layout.** The full 404
|
|
1344
|
-
experience (including the unconfigured-site setup guide) now lives in the
|
|
1345
|
-
theme; a consumer's `/404.html` shrinks from a 224-line vendored copy to a
|
|
1346
|
-
4-line front-matter stub (`layout: "404"`). Setup mode is branded with
|
|
1347
|
-
`site.title` instead of a hardcoded theme welcome, and the stub page's body
|
|
1348
|
-
renders below the standard content for site-specific additions.
|
|
1349
|
-
- **`color_mode_lock` config.** Pin the site to one color mode: visitor
|
|
1350
|
-
preference and OS scheme are ignored, the light/dark/auto switcher is
|
|
1351
|
-
removed, and `core/color-mode-init.html` + `halfmoon.js` enforce the lock
|
|
1352
|
-
pre-paint. Replaces consumer JS workarounds that re-asserted a mode on every
|
|
1353
|
-
`matchMedia` change.
|
|
1354
|
-
- **PostHog privacy options** (`posthog.privacy.*`): `respect_gpc` (honor the
|
|
1355
|
-
Global Privacy Control signal alongside DNT, default on), `require_consent`
|
|
1356
|
-
(start opted out with memory-only persistence until the visitor accepts the
|
|
1357
|
-
cookie-consent "analytics" category), and `geoip_disable` (no IP→location
|
|
1358
|
-
resolution). Upstreams the deltas consumer sites were maintaining in a
|
|
1359
|
-
full fork of `analytics/posthog.html`.
|
|
1360
|
-
- **`news:` config surface for the news/section layouts.** `category_base`
|
|
1361
|
-
(e.g. `/categories/` instead of the hardcoded `/news/`), `index_url`,
|
|
1362
|
-
`hero: false`, `archives_url`, and a `newsletter` block (endpoint-or-mailto,
|
|
1363
|
-
or hidden entirely — the old markup shipped a form that submitted nowhere).
|
|
1364
|
-
|
|
1365
|
-
### Changed
|
|
1366
|
-
|
|
1367
|
-
- **The news/section layouts work with zero `_data`.** Section navigation
|
|
1368
|
-
falls back from `_data/navigation/posts.yml` to `site.categories`; the hero
|
|
1369
|
-
falls back to the newest post when nothing is marked `breaking`/`featured`;
|
|
1370
|
-
tags links render only when a tags page exists (honoring `site.tags_page`);
|
|
1371
|
-
archive month links render only when an archives page exists. A data-less
|
|
1372
|
-
consumer now gets a fully working magazine homepage instead of empty chrome
|
|
1373
|
-
and 404 links.
|
|
1374
|
-
- **Zero-`_data` resilience across components.** The skin quick-select and
|
|
1375
|
-
theme customizer fall back to the compiled skin registry when
|
|
1376
|
-
`_data/theme_skins.yml` is absent; the page-feedback widget falls back to a
|
|
1377
|
-
generic four-type taxonomy when `_data/feedback_types.yml` is absent; the
|
|
1378
|
-
landing get-started band (theme install cards) renders only when the site
|
|
1379
|
-
ships a `landing.get_started` block — a data-less consumer no longer
|
|
1380
|
-
advertises the theme's own install methods.
|
|
1381
|
-
- **`home` layout accepts `hide_intro` as an alias of `hide_title`**, matching
|
|
1382
|
-
the flag other layouts use for "suppress the generated page header".
|
|
1383
|
-
- **`halfmoon.js` honors `color_mode_default`.** The switcher no longer
|
|
1384
|
-
overrides the configured default with the OS preference on first visit
|
|
1385
|
-
(previously the page could flip modes right after load).
|
|
1386
|
-
- The default skin fallback is now `air` everywhere (`root.html`,
|
|
1387
|
-
controls bar, customizer) — `dark` was never a compiled skin, so the old
|
|
1388
|
-
fallback selected a skin that doesn't exist.
|
|
1389
|
-
|
|
1390
|
-
### Fixed
|
|
1391
|
-
|
|
1392
1506
|
- **`_data/theme-manifest.yml` was 13 minors stale.** It sat at `1.14.0` while
|
|
1393
1507
|
the theme shipped to `1.27.0`, so every SHA-256 in it was wrong and
|
|
1394
1508
|
`scripts/bin/audit-consumer` — which reads it to classify consumer files —
|
|
@@ -1422,71 +1536,6 @@ feature docs with captured screenshots of both the broken widget and the giscus.
|
|
|
1422
1536
|
`:root` (set by `auto-hide-nav.js`), so stylesheets can align overlays with
|
|
1423
1537
|
the real header instead of hard-coding its pixel height.
|
|
1424
1538
|
|
|
1425
|
-
### Added
|
|
1426
|
-
|
|
1427
|
-
- **ABC board books (`book-abc` layout) — the "ABC & Language" series.** A new
|
|
1428
|
-
immersive, single-scroll toddler alphabet layout (`_layouts/book-abc.html`)
|
|
1429
|
-
driven entirely by an `alphabet:` front-matter list — one big letter, one
|
|
1430
|
-
word, one picture per card, with A–Z quick-jump anchors and a cover hero.
|
|
1431
|
-
The big letter is HTML typography (never baked into the art), and a card
|
|
1432
|
-
whose plate is still `planned` shows a tinted "illustration coming soon"
|
|
1433
|
-
placeholder so a book reads end-to-end before any art renders. New
|
|
1434
|
-
`_includes/components/abc-letter.html` renders each card; `_sass/components/_book.scss`
|
|
1435
|
-
gains `.abc-board` / `.abc-letter-*` styles plus a `.abc-style--<id>` skin per
|
|
1436
|
-
shared art-style id. `components/bookshelf.html` now lists both `book` and
|
|
1437
|
-
`book-abc` books, grouped into series shelves from `_data/series.yml`;
|
|
1438
|
-
`book-card.html` shows a letter count for ABC books. Ships a demo book
|
|
1439
|
-
(`pages/_books/abc-demo/`) + default series metadata (`_data/series.yml`).
|
|
1440
|
-
Regression test [`test/visual/features/book-abc.spec.js`](test/visual/features/book-abc.spec.js)
|
|
1441
|
-
and before/after evidence in
|
|
1442
|
-
[`test/visual/evidence/book-abc/`](test/visual/evidence/book-abc/). Docs:
|
|
1443
|
-
[`docs/features/abc-books.md`](docs/features/abc-books.md).
|
|
1444
|
-
- **`nav: pages` sidebar mode — auto-build the left tree from page URLs.** A new
|
|
1445
|
-
sidebar mode (`_includes/navigation/sidebar-pagetree.html`) derives a
|
|
1446
|
-
collapsible section tree purely from page permalinks under a `sidebar.base`
|
|
1447
|
-
prefix — no curated `_data/navigation/*.yml` file to write or keep in sync.
|
|
1448
|
-
Enable per page / collection / site with `sidebar: {nav: pages, base: /docs/,
|
|
1449
|
-
order_by: nav_order, title: …}`. It covers plain pages (`site.html_pages`) and
|
|
1450
|
-
collection documents (`site.documents`) alike, groups them by first path
|
|
1451
|
-
segment, humanizes section labels from the URL (never leaking a generic
|
|
1452
|
-
"Index" title), sorts each section by a numeric `order_by` (natural order),
|
|
1453
|
-
supports per-page `sidebar_label` / `sidebar_exclude`, and marks only the
|
|
1454
|
-
current page active with its section expanded server-side — pure Liquid, so
|
|
1455
|
-
it is GitHub Pages / `remote_theme` safe. Documented at
|
|
1456
|
-
`/docs/features/sidebar-page-tree/`.
|
|
1457
|
-
- **Claude Code OAuth in the AI installer** — the spec-driven installer
|
|
1458
|
-
(`scripts/bin/install`) is now multi-provider. `scripts/install/ai/client.sh`
|
|
1459
|
-
resolves a provider via `ZER0_AI_PROVIDER` (default `auto`), preferring the
|
|
1460
|
-
logged-in `claude` CLI (**Claude Code OAuth** — zero key handling), then the
|
|
1461
|
-
Anthropic Messages API (`CLAUDE_CODE_OAUTH_TOKEN` OAuth bearer or
|
|
1462
|
-
`ANTHROPIC_API_KEY`), then OpenAI. `install doctor` reports the active
|
|
1463
|
-
provider; `--ai-provider` / `--ai-model` / `ZER0_AI_MODEL` tune it; `--no-ai`
|
|
1464
|
-
/ `ZER0_NO_AI=1` disable it. User context is sanitized before every call.
|
|
1465
|
-
- **Config-file layer for the installer** — new `scripts/install/config.sh`
|
|
1466
|
-
discovers and merges `~/.config/zer0/install.yml`, `<target>/zer0.install.yml`,
|
|
1467
|
-
`<target>/.zer0/config.yml`, and `--config FILE` (precedence:
|
|
1468
|
-
defaults < profile < config < env < flags). Recognises site / github / theme /
|
|
1469
|
-
deploy / agents / tasks / ai keys; API keys stay environment-only.
|
|
1470
|
-
- **`install suggest`** subcommand — recommend a profile + deploy target
|
|
1471
|
-
(AI-assisted with rule-based fallback) — plus `--yes` as an alias for
|
|
1472
|
-
`--auto-accept`.
|
|
1473
|
-
- Installer regression matrix (`test/test_installer.sh`) now covers AI
|
|
1474
|
-
provider resolution, text extraction across provider shapes, the config-file
|
|
1475
|
-
layer + precedence, and the `doctor` AI check (all offline).
|
|
1476
|
-
|
|
1477
|
-
### Changed
|
|
1478
|
-
|
|
1479
|
-
- Installer spec default `ai.provider` is now `auto` (was `openai`); the AI
|
|
1480
|
-
wizard records the provider that actually served the run.
|
|
1481
|
-
- **CI workflows now honor `CLAUDE_CODE_OAUTH_TOKEN`** — `ui-audit.yml`,
|
|
1482
|
-
`ai-content-review.yml`, and `ci-self-repair.yml` previously gated their
|
|
1483
|
-
Claude Code agent tier on `ANTHROPIC_API_KEY` alone, silently ignoring a
|
|
1484
|
-
configured OAuth token. They now follow the same house convention as
|
|
1485
|
-
`claude.yml` / `issue-autopilot.yml`: `CLAUDE_CODE_OAUTH_TOKEN` preferred,
|
|
1486
|
-
`ANTHROPIC_API_KEY` used only when it's absent.
|
|
1487
|
-
|
|
1488
|
-
### Fixed
|
|
1489
|
-
|
|
1490
1539
|
- **Left-sidebar nav highlighted every item as "active".** `nav-tree.html`
|
|
1491
1540
|
used {% raw %}`{% assign is_active = page.url == item.url %}`{% endraw %}, but Liquid `assign`
|
|
1492
1541
|
does not evaluate `==` — it stored `page.url` (always truthy), so every link
|
|
@@ -1517,6 +1566,134 @@ feature docs with captured screenshots of both the broken widget and the giscus.
|
|
|
1517
1566
|
`_config.yml` template add `jekyll-include-cache` (required by the theme's
|
|
1518
1567
|
layouts).
|
|
1519
1568
|
|
|
1569
|
+
## [1.31.0](https://github.com/bamr87/zer0-mistakes/compare/v1.30.0...v1.31.0) (2026-10-07)
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
### Features
|
|
1573
|
+
|
|
1574
|
+
* **navigation:** two clean navbar label tiers, merged chevron, centred grid ([#495](https://github.com/bamr87/zer0-mistakes/issues/495)) ([9ebb29a](https://github.com/bamr87/zer0-mistakes/commit/9ebb29a4662fbc4c62d3fdd8df9c282bdd181204))
|
|
1575
|
+
* **theme:** four consumer extension points for notes/knowledge-base builds ([#492](https://github.com/bamr87/zer0-mistakes/issues/492)) ([1e2b228](https://github.com/bamr87/zer0-mistakes/commit/1e2b2283303012b28b9e81209fb66d0344aa0597))
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
### Bug Fixes
|
|
1579
|
+
|
|
1580
|
+
* **article:** eager-load the hero LCP image and reserve its box ([#498](https://github.com/bamr87/zer0-mistakes/issues/498)) ([529b84b](https://github.com/bamr87/zer0-mistakes/commit/529b84bd0f5ea8e79b7711187b52b2bb80c5b134)), closes [#485](https://github.com/bamr87/zer0-mistakes/issues/485)
|
|
1581
|
+
* **ci:** keep a LiveReload push from crashing the generic evidence generator ([#500](https://github.com/bamr87/zer0-mistakes/issues/500)) ([eb1b5ae](https://github.com/bamr87/zer0-mistakes/commit/eb1b5ae201ed0829e0c3fac05e629e55a6ea1040))
|
|
1582
|
+
* **ci:** Playwright 1.58 attachment names, docs front matter, test race ([#497](https://github.com/bamr87/zer0-mistakes/issues/497)) ([f1bdc7e](https://github.com/bamr87/zer0-mistakes/commit/f1bdc7ef22091f0506617b11a95e357c439cfa94))
|
|
1583
|
+
* **ci:** stop auto-merge guard failing on Dependabot Actions bumps ([#503](https://github.com/bamr87/zer0-mistakes/issues/503)) ([a998b2d](https://github.com/bamr87/zer0-mistakes/commit/a998b2dd9cf96bb1fd09ac3a95644908713afc37))
|
|
1584
|
+
* **features:** escape `<en-url>` in the translation card so the Features page renders ([#505](https://github.com/bamr87/zer0-mistakes/issues/505)) ([8e4345f](https://github.com/bamr87/zer0-mistakes/commit/8e4345f28dfc675b5efe95ba66ec72af613cbcf5))
|
|
1585
|
+
* **includes:** join preview paths without a leading slash under assets_prefix ([#509](https://github.com/bamr87/zer0-mistakes/issues/509)) ([406250c](https://github.com/bamr87/zer0-mistakes/commit/406250c2b5b94469cae9a0b6f93e8782cb8509f9))
|
|
1586
|
+
* **includes:** stop the draft chip shifting the Site Builder on first save ([#489](https://github.com/bamr87/zer0-mistakes/issues/489)) ([d472aa2](https://github.com/bamr87/zer0-mistakes/commit/d472aa267e164212cf8b844e701cfcdad08e4d8d))
|
|
1587
|
+
* **layouts:** one main landmark per page on post, notebook and note ([#487](https://github.com/bamr87/zer0-mistakes/issues/487)) ([78b0910](https://github.com/bamr87/zer0-mistakes/commit/78b0910fb2258591eab9ba13efb5ac037eee80c5))
|
|
1588
|
+
* **navigation:** stop Liquid whitespace-trim gluing navbar attributes ([#477](https://github.com/bamr87/zer0-mistakes/issues/477)) ([4349ea1](https://github.com/bamr87/zer0-mistakes/commit/4349ea17d690e5e6b8585f1d3a33b3ea4d3bf4fe))
|
|
1589
|
+
* **scripts:** default xAI preview renderer to grok-imagine-image-2.0 ([#499](https://github.com/bamr87/zer0-mistakes/issues/499)) ([95cebdb](https://github.com/bamr87/zer0-mistakes/commit/95cebdb535799544f05ed5929e528a074448ef63)), closes [#474](https://github.com/bamr87/zer0-mistakes/issues/474)
|
|
1590
|
+
* **tests:** make the Liquid nested-tag and gem-content checks able to fail ([#478](https://github.com/bamr87/zer0-mistakes/issues/478)) ([8510d08](https://github.com/bamr87/zer0-mistakes/commit/8510d0824f79823f66f765f12db9be9b67fff3ae))
|
|
1591
|
+
* **tokens:** let the active skin win over site theme_color for skin-owned tokens ([#502](https://github.com/bamr87/zer0-mistakes/issues/502)) ([af468e0](https://github.com/bamr87/zer0-mistakes/commit/af468e072543a448e7be80230f3d3a246b5e758e))
|
|
1592
|
+
* **ui:** make the cookie consent banner a compact bottom bar ([#510](https://github.com/bamr87/zer0-mistakes/issues/510)) ([2d7d0db](https://github.com/bamr87/zer0-mistakes/commit/2d7d0db7f9f6b1433b63d8be76103cce2fd7fb05))
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
### Performance Improvements
|
|
1596
|
+
|
|
1597
|
+
* **js:** lazy-load Mermaid and cytoscape, defer PostHog, stop nav reflows ([#508](https://github.com/bamr87/zer0-mistakes/issues/508)) ([702789c](https://github.com/bamr87/zer0-mistakes/commit/702789cecf93d8e9b9f7013168ca47f0294064eb))
|
|
1598
|
+
* **sitemap:** keep one page of the index in the DOM and build cards lazily ([#511](https://github.com/bamr87/zer0-mistakes/issues/511)) ([9e42fcb](https://github.com/bamr87/zer0-mistakes/commit/9e42fcbd9421a994fd22a347bbef95573ce340a9))
|
|
1599
|
+
|
|
1600
|
+
## [1.30.0](https://github.com/bamr87/zer0-mistakes/compare/v1.29.0...v1.30.0) (2026-09-12)
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
### Features
|
|
1604
|
+
|
|
1605
|
+
* **ci:** produce visual evidence and baselines on PRs, not just verify them ([#462](https://github.com/bamr87/zer0-mistakes/issues/462)) ([a377fae](https://github.com/bamr87/zer0-mistakes/commit/a377fae6ea31a0bb015479dea6d1a7c41e141c3f))
|
|
1606
|
+
* **includes:** add background-image.html for CSS-painted cover art ([#451](https://github.com/bamr87/zer0-mistakes/issues/451)) ([9b15a67](https://github.com/bamr87/zer0-mistakes/commit/9b15a673f57b8f7f1f9dae9262191742d99d8080))
|
|
1607
|
+
* **includes:** Claude or Grok sessions in the Site Builder ([#473](https://github.com/bamr87/zer0-mistakes/issues/473)) ([e1c5753](https://github.com/bamr87/zer0-mistakes/commit/e1c57531fc23be8d071757cd1941e1ae15285da7))
|
|
1608
|
+
* **includes:** file the fleet issue contract from the feedback widget ([#472](https://github.com/bamr87/zer0-mistakes/issues/472)) ([24d4e2c](https://github.com/bamr87/zer0-mistakes/commit/24d4e2c6380541a894e9e671f0f0b0b859a29b05))
|
|
1609
|
+
* **includes:** make theme-color track the page surface, not the accent ([#447](https://github.com/bamr87/zer0-mistakes/issues/447)) ([f1fda85](https://github.com/bamr87/zer0-mistakes/commit/f1fda857bb0cf5bd64bebfc1215ba0a906f05e5c))
|
|
1610
|
+
* **includes:** themed Mermaid figures + toolbar ([#455](https://github.com/bamr87/zer0-mistakes/issues/455)) ([96776fa](https://github.com/bamr87/zer0-mistakes/commit/96776fa48bbe7b63058d1d246962019c745d7b93))
|
|
1611
|
+
* **scripts:** adopt the shared ai-runner kit for claude-run; consumers registry fixes; hub baseline ([#475](https://github.com/bamr87/zer0-mistakes/issues/475)) ([feb4133](https://github.com/bamr87/zer0-mistakes/commit/feb41332eb15d2c13fe0c0f6d15b61007e14daa3))
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
### Bug Fixes
|
|
1615
|
+
|
|
1616
|
+
* **a11y:** decouple heading size from heading level in theme chrome ([#450](https://github.com/bamr87/zer0-mistakes/issues/450)) ([bb92eb5](https://github.com/bamr87/zer0-mistakes/commit/bb92eb583c955e76339a9c7ab98532b35e226b36))
|
|
1617
|
+
* **a11y:** give footer icon links an accessible name, announce search results ([#441](https://github.com/bamr87/zer0-mistakes/issues/441)) ([a1811e8](https://github.com/bamr87/zer0-mistakes/commit/a1811e81ac0c17b0836994be7c48eba51252bae7))
|
|
1618
|
+
* **a11y:** stop emitting sidebar/TOC controls on layouts that render no offcanvas ([#443](https://github.com/bamr87/zer0-mistakes/issues/443)) ([619322d](https://github.com/bamr87/zer0-mistakes/commit/619322d8fd7c6e2a700ba154e065bf65caf67461))
|
|
1619
|
+
* **ci:** run the autogen lane's tooling from the base branch, not the PR ([#464](https://github.com/bamr87/zer0-mistakes/issues/464)) ([8473050](https://github.com/bamr87/zer0-mistakes/commit/8473050be2b4ddfd994c7bea8a8c35e37a66b7f8))
|
|
1620
|
+
* **ci:** stop the UI audit reporting a measurement blackout as a clean run ([#471](https://github.com/bamr87/zer0-mistakes/issues/471)) ([ab92619](https://github.com/bamr87/zer0-mistakes/commit/ab9261946e088417dabe4291590da1c7a964d4fa))
|
|
1621
|
+
* **content:** raw-protect Liquid that is written as documentation ([#446](https://github.com/bamr87/zer0-mistakes/issues/446)) ([6123c1f](https://github.com/bamr87/zer0-mistakes/commit/6123c1f1e6ffd167376d4ef421b0a9f78af3985e))
|
|
1622
|
+
* **includes:** declare charset inside the 1024-byte window, make the feed discoverable ([#440](https://github.com/bamr87/zer0-mistakes/issues/440)) ([4025205](https://github.com/bamr87/zer0-mistakes/commit/40252050ec21c70aa1d84820fdcde6d564e03478)), closes [#372](https://github.com/bamr87/zer0-mistakes/issues/372) [#371](https://github.com/bamr87/zer0-mistakes/issues/371)
|
|
1623
|
+
* **includes:** expose skin-button selected state via aria-pressed ([#469](https://github.com/bamr87/zer0-mistakes/issues/469)) ([6579b16](https://github.com/bamr87/zer0-mistakes/commit/6579b1621a5eff147e224977633728aadc960505)), closes [#467](https://github.com/bamr87/zer0-mistakes/issues/467)
|
|
1624
|
+
* **install:** stop seeding the theme's own navigation into consumers ([#449](https://github.com/bamr87/zer0-mistakes/issues/449)) ([232857c](https://github.com/bamr87/zer0-mistakes/commit/232857c66d7c3abccb166b5151a7f80a74dd17ca))
|
|
1625
|
+
* **navigation:** scroll spy bolds the section actually being read ([#456](https://github.com/bamr87/zer0-mistakes/issues/456)) ([5ff38bf](https://github.com/bamr87/zer0-mistakes/commit/5ff38bf98faf96cdc3bf63ea3f0e7b10e21f3aab))
|
|
1626
|
+
* **sass:** stop navbar controls flickering under a stationary pointer ([#453](https://github.com/bamr87/zer0-mistakes/issues/453)) ([fc84b9a](https://github.com/bamr87/zer0-mistakes/commit/fc84b9a4c714f8e04b8a0f940bed9e3795c144bc)), closes [#404](https://github.com/bamr87/zer0-mistakes/issues/404)
|
|
1627
|
+
* **scripts:** restore nested translation placeholders instead of leaking them ([#452](https://github.com/bamr87/zer0-mistakes/issues/452)) ([00cab73](https://github.com/bamr87/zer0-mistakes/commit/00cab73d915f4e116040ef6ca4c0381669ae4eb2))
|
|
1628
|
+
|
|
1629
|
+
|
|
1630
|
+
### Performance Improvements
|
|
1631
|
+
|
|
1632
|
+
* **ci:** run the critical PR gate on 3 workers instead of 1 ([#481](https://github.com/bamr87/zer0-mistakes/issues/481)) ([b3fcbc7](https://github.com/bamr87/zer0-mistakes/commit/b3fcbc76a1af2a3a5e43eb28fbff7b3057751de6))
|
|
1633
|
+
* **includes:** strip developer doc banners from delivered HTML ([#445](https://github.com/bamr87/zer0-mistakes/issues/445)) ([89b10f1](https://github.com/bamr87/zer0-mistakes/commit/89b10f1ff361c919fd631d0e7e664ed6d7c28a14))
|
|
1634
|
+
|
|
1635
|
+
## [1.29.0](https://github.com/bamr87/zer0-mistakes/compare/v1.28.0...v1.29.0) (2026-09-01)
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
### Features
|
|
1639
|
+
|
|
1640
|
+
* **analytics:** track and display per-page view counts ([#413](https://github.com/bamr87/zer0-mistakes/issues/413)) ([e488c4c](https://github.com/bamr87/zer0-mistakes/commit/e488c4c3101da78e98eecbf8299ce7c8705ed281))
|
|
1641
|
+
* **design:** fill Fab, PostCard, Skeleton + motion/layers gaps in the design-system mirror ([#391](https://github.com/bamr87/zer0-mistakes/issues/391)) ([3b49741](https://github.com/bamr87/zer0-mistakes/commit/3b497417564b4c5e3d71eaa113cb136d2cdaf15c))
|
|
1642
|
+
* **includes:** icon-only language trigger and a compact, positive menu ([#431](https://github.com/bamr87/zer0-mistakes/issues/431)) ([353bfa5](https://github.com/bamr87/zer0-mistakes/commit/353bfa5f3a8dd949ca6e513213a155d648218642)), closes [#406](https://github.com/bamr87/zer0-mistakes/issues/406)
|
|
1643
|
+
* **includes:** live preview, vertical stepper and draft persistence in the setup wizard ([#432](https://github.com/bamr87/zer0-mistakes/issues/432)) ([73bdc55](https://github.com/bamr87/zer0-mistakes/commit/73bdc5547350c448e1617ec6cf5b9f49b10d65fb)), closes [#408](https://github.com/bamr87/zer0-mistakes/issues/408)
|
|
1644
|
+
* **layouts:** add cookbook collection with recipe scaling and unit conversion ([#414](https://github.com/bamr87/zer0-mistakes/issues/414)) ([bb8eefa](https://github.com/bamr87/zer0-mistakes/commit/bb8eefa2beea0104fec28d173a1e57f369acada8))
|
|
1645
|
+
* **pages:** publish the design system and page canvas on the live site ([#392](https://github.com/bamr87/zer0-mistakes/issues/392)) ([6cf73cd](https://github.com/bamr87/zer0-mistakes/commit/6cf73cdf2cca9ec02394b6ae1ba7e39c19969134))
|
|
1646
|
+
* **sass:** align design tokens with the Claude Design system ([#389](https://github.com/bamr87/zer0-mistakes/issues/389)) ([7fc2fe0](https://github.com/bamr87/zer0-mistakes/commit/7fc2fe02683d652c0326536158bd48b3690df51f))
|
|
1647
|
+
|
|
1648
|
+
|
|
1649
|
+
### Bug Fixes
|
|
1650
|
+
|
|
1651
|
+
* **a11y:** dialog titles use a bare <h5>, skipping heading levels ([#387](https://github.com/bamr87/zer0-mistakes/issues/387)) ([98fd6f9](https://github.com/bamr87/zer0-mistakes/commit/98fd6f9e63dfb75c58efc3b15a642fb3e4c4095b))
|
|
1652
|
+
* **ci:** fail the content review when it did not actually run ([#424](https://github.com/bamr87/zer0-mistakes/issues/424)) ([f048cb2](https://github.com/bamr87/zer0-mistakes/commit/f048cb22e565b3122d6682c026e13521b6fe52d9)), closes [#418](https://github.com/bamr87/zer0-mistakes/issues/418)
|
|
1653
|
+
* **ci:** fail the Pages build on Liquid errors, unmangle two live pages ([#439](https://github.com/bamr87/zer0-mistakes/issues/439)) ([afd2ec8](https://github.com/bamr87/zer0-mistakes/commit/afd2ec83879a793d77dfac21b41d74d5204126c4))
|
|
1654
|
+
* **ci:** make the pixel gate see the data files that move pixels ([#425](https://github.com/bamr87/zer0-mistakes/issues/425)) ([02ea639](https://github.com/bamr87/zer0-mistakes/commit/02ea639b3152900682ca298bd172925133d10dea)), closes [#417](https://github.com/bamr87/zer0-mistakes/issues/417)
|
|
1655
|
+
* **ci:** stop discarding good translations when one page fails ([#388](https://github.com/bamr87/zer0-mistakes/issues/388)) ([19cea46](https://github.com/bamr87/zer0-mistakes/commit/19cea462a7822d6db536fc9c23218abd4a13d830))
|
|
1656
|
+
* **ci:** wait past the cold bundle install for Jekyll in the snapshot gate ([#426](https://github.com/bamr87/zer0-mistakes/issues/426)) ([de1d1ca](https://github.com/bamr87/zer0-mistakes/commit/de1d1ca426ce7a25d5a8548c4a696c0002877200))
|
|
1657
|
+
* **cookie-consent:** text-dark on bg-body made privacy rights invisible in dark mode ([#386](https://github.com/bamr87/zer0-mistakes/issues/386)) ([9bde7df](https://github.com/bamr87/zer0-mistakes/commit/9bde7dfa13f426908e00e53f8e4013a049fd928d))
|
|
1658
|
+
* **giscus:** comments were broken sitewide — add an end-to-end health check and correct the docs ([#378](https://github.com/bamr87/zer0-mistakes/issues/378)) ([45e222c](https://github.com/bamr87/zer0-mistakes/commit/45e222c3c2c5b7c507af4df2f5f0b48bc783801e))
|
|
1659
|
+
* **includes:** footer Info/Cookie Preferences are buttons, not anchors ([#427](https://github.com/bamr87/zer0-mistakes/issues/427)) ([f9041b9](https://github.com/bamr87/zer0-mistakes/commit/f9041b98b8a267be59f560724821fd941090f52d)), closes [#320](https://github.com/bamr87/zer0-mistakes/issues/320)
|
|
1660
|
+
* **layouts:** match section topic filters on whole tags, not substrings ([#420](https://github.com/bamr87/zer0-mistakes/issues/420)) ([338ad1d](https://github.com/bamr87/zer0-mistakes/commit/338ad1ddfb71c8d1dd9c48b36fb4634daf93f2de))
|
|
1661
|
+
* **layouts:** move keyboard focus to the skip-link target (tabindex="-1") ([#395](https://github.com/bamr87/zer0-mistakes/issues/395)) ([f5db650](https://github.com/bamr87/zer0-mistakes/commit/f5db65048e48ca71eedebc04d02d051e0b3152a6)), closes [#278](https://github.com/bamr87/zer0-mistakes/issues/278)
|
|
1662
|
+
* **layouts:** stop emitting dead sub-topic anchors in section sidebars ([#402](https://github.com/bamr87/zer0-mistakes/issues/402)) ([f50e790](https://github.com/bamr87/zer0-mistakes/commit/f50e790c4bfd56fefa4a74d7876de90c9776c689))
|
|
1663
|
+
* **layouts:** upgrade the no-js class to "js" so the hook works ([#428](https://github.com/bamr87/zer0-mistakes/issues/428)) ([a2d31f5](https://github.com/bamr87/zer0-mistakes/commit/a2d31f5533a4fb4793042e32326c1a78c9954268)), closes [#319](https://github.com/bamr87/zer0-mistakes/issues/319)
|
|
1664
|
+
* **navigation:** fit all nav items, full-bleed bar, language into Settings ([#423](https://github.com/bamr87/zer0-mistakes/issues/423)) ([689006e](https://github.com/bamr87/zer0-mistakes/commit/689006e7654e900a4509c30539fcf12bd7f397c6))
|
|
1665
|
+
* **scripts:** correct consumer auditor, plugin contract, and JSON-LD scope ([#400](https://github.com/bamr87/zer0-mistakes/issues/400)) ([b466cad](https://github.com/bamr87/zer0-mistakes/commit/b466cad526501e7e7a0eef5f24a12c5bbd181dc7))
|
|
1666
|
+
* **scripts:** recover from a rejected Anthropic credential, and link the cookbook ([#419](https://github.com/bamr87/zer0-mistakes/issues/419)) ([fac6bee](https://github.com/bamr87/zer0-mistakes/commit/fac6beeb7af7dcae96f727bf0cf581b080e95f15))
|
|
1667
|
+
* **ui-audit:** serve without --detach so the sweep can capture, and fail loudly when it cannot ([#434](https://github.com/bamr87/zer0-mistakes/issues/434)) ([fac6415](https://github.com/bamr87/zer0-mistakes/commit/fac641574c951b2887d94f8b39561fb8b6f8fe8c)), closes [#321](https://github.com/bamr87/zer0-mistakes/issues/321)
|
|
1668
|
+
|
|
1669
|
+
## [1.28.0](https://github.com/bamr87/zer0-mistakes/compare/v1.27.0...v1.28.0) (2026-08-09)
|
|
1670
|
+
|
|
1671
|
+
|
|
1672
|
+
### Features
|
|
1673
|
+
|
|
1674
|
+
* **books:** children's picture-book collection with immersive layouts and components ([#328](https://github.com/bamr87/zer0-mistakes/issues/328)) ([e059d1a](https://github.com/bamr87/zer0-mistakes/commit/e059d1afdc95073c5ce5bf9d1516b362979ad402))
|
|
1675
|
+
* **ci:** deploy the site via Actions so examples reach the live domain ([#353](https://github.com/bamr87/zer0-mistakes/issues/353)) ([959243c](https://github.com/bamr87/zer0-mistakes/commit/959243c0e8e504fe5d8dba44b89016b413bc88da))
|
|
1676
|
+
* **docs:** theme-canary reporting contract for downstream theme-scouts (FF-0019) ([#358](https://github.com/bamr87/zer0-mistakes/issues/358)) ([c1c1b30](https://github.com/bamr87/zer0-mistakes/commit/c1c1b309c5504b014602982fc96ec80c3f8f70de))
|
|
1677
|
+
* **examples:** add serialized reading-blog example site ([#339](https://github.com/bamr87/zer0-mistakes/issues/339)) ([aca0b53](https://github.com/bamr87/zer0-mistakes/commit/aca0b53b88067bda80fb299f9d5148ccb185d618))
|
|
1678
|
+
* **includes:** config-driven favicon, GTM gating, og:image fallback fix, sidebar nav aliases ([#327](https://github.com/bamr87/zer0-mistakes/issues/327)) ([fe8aacc](https://github.com/bamr87/zer0-mistakes/commit/fe8aacc234003f9f170fcb3b8b29c60ac18ed94b))
|
|
1679
|
+
* **install:** Claude Code OAuth + multi-provider AI + config-file layer ([#330](https://github.com/bamr87/zer0-mistakes/issues/330)) ([fde414c](https://github.com/bamr87/zer0-mistakes/commit/fde414cce5286f90de1ad02ca6ca40d634be5611))
|
|
1680
|
+
* **layouts:** book-abc board-book layout + ABC art-style skins ([#336](https://github.com/bamr87/zer0-mistakes/issues/336)) ([d88038e](https://github.com/bamr87/zer0-mistakes/commit/d88038e806e0d1a492e5d12b4e10e55fd240d692))
|
|
1681
|
+
* **navigation:** nav: pages sidebar mode — auto-build the tree from page URLs ([#333](https://github.com/bamr87/zer0-mistakes/issues/333)) ([c0c627d](https://github.com/bamr87/zer0-mistakes/commit/c0c627d5f50051e8f5eb4f0d6681244acaaa8d85))
|
|
1682
|
+
* **obsidian:** revamp graph frontend with Obsidian-style controls ([#366](https://github.com/bamr87/zer0-mistakes/issues/366)) ([7143d9c](https://github.com/bamr87/zer0-mistakes/commit/7143d9cd137408ad82981c9f9835204bab3a3db5))
|
|
1683
|
+
* **theme:** consumer-adoption hardening — mobile overlay fixes, zero-data resilience, extension hooks ([#338](https://github.com/bamr87/zer0-mistakes/issues/338)) ([84bcce1](https://github.com/bamr87/zer0-mistakes/commit/84bcce15e66b0bc312f513cef4a9dd11f972a049))
|
|
1684
|
+
|
|
1685
|
+
|
|
1686
|
+
### Bug Fixes
|
|
1687
|
+
|
|
1688
|
+
* **books:** pin abc-demo permalink so its cover lands at /books/abc-demo/ ([#345](https://github.com/bamr87/zer0-mistakes/issues/345)) ([943f463](https://github.com/bamr87/zer0-mistakes/commit/943f463c73081e7cc3d914c28a2ec2eea3d1b5ae))
|
|
1689
|
+
* **ci:** give the Dependabot label job an explicit GH_REPO ([#370](https://github.com/bamr87/zer0-mistakes/issues/370)) ([808b20e](https://github.com/bamr87/zer0-mistakes/commit/808b20ebbdcd5b0bc139b90947297cec6d226787))
|
|
1690
|
+
* **ci:** prefer CLAUDE_CODE_OAUTH_TOKEN over ANTHROPIC_API_KEY in all AI workflows ([#334](https://github.com/bamr87/zer0-mistakes/issues/334)) ([043848e](https://github.com/bamr87/zer0-mistakes/commit/043848eb84222240efc121e8112ddc12ab959a64))
|
|
1691
|
+
* **ci:** unbreak the production Pages build, frozen since 2026-08-05 ([#356](https://github.com/bamr87/zer0-mistakes/issues/356)) ([05465cf](https://github.com/bamr87/zer0-mistakes/commit/05465cfd5480a6bdfb0d164d56a892f2825ec1cf))
|
|
1692
|
+
* **i18n:** exclude admin config page from translation to unbreak Pages deploy ([#349](https://github.com/bamr87/zer0-mistakes/issues/349)) ([3f4890c](https://github.com/bamr87/zer0-mistakes/commit/3f4890cee3dd59b7f1cbc6ec235a863017b075fb))
|
|
1693
|
+
* **i18n:** normalise generated prose so translation runs keep CI green ([#342](https://github.com/bamr87/zer0-mistakes/issues/342)) ([70a7234](https://github.com/bamr87/zer0-mistakes/commit/70a723425b8cc6a77e1b845b212a8a7d127a7779))
|
|
1694
|
+
* **navigation:** mark only the current page active in the sidebar nav-tree ([#331](https://github.com/bamr87/zer0-mistakes/issues/331)) ([3f1b723](https://github.com/bamr87/zer0-mistakes/commit/3f1b723169258993d4530dd5817740e62734ccd4))
|
|
1695
|
+
* **sass:** restore mobile navigation in the example, collapsed to a 60px sliver ([#363](https://github.com/bamr87/zer0-mistakes/issues/363)) ([8c7d87a](https://github.com/bamr87/zer0-mistakes/commit/8c7d87af4fd476f06c16ce58ca4d4cd0e2c4169d))
|
|
1696
|
+
|
|
1520
1697
|
## [1.27.0](https://github.com/bamr87/zer0-mistakes/compare/v1.26.0...v1.27.0) (2026-07-22)
|
|
1521
1698
|
|
|
1522
1699
|
|