jekyll-theme-zer0 1.28.0 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +430 -13
  3. data/_data/backlog.yml +356 -2
  4. data/_data/consumers.yml +109 -4
  5. data/_data/features.yml +157 -0
  6. data/_data/i18n/fr.yml +12 -7
  7. data/_data/i18n/manifest.yml +39 -12
  8. data/_data/ingredient_densities.yml +122 -0
  9. data/_data/navigation/main.yml +16 -0
  10. data/_data/recipe_courses.yml +64 -0
  11. data/_data/theme-manifest.yml +68 -40
  12. data/_data/ui-text.yml +8 -0
  13. data/_includes/README.md +15 -1
  14. data/_includes/components/background-customizer.html +2 -2
  15. data/_includes/components/cookie-consent.html +4 -4
  16. data/_includes/components/info-section.html +8 -3
  17. data/_includes/components/language-toggle.html +168 -21
  18. data/_includes/components/page-views-init.html +55 -0
  19. data/_includes/components/page-views.html +33 -0
  20. data/_includes/components/recipe-card.html +67 -0
  21. data/_includes/components/recipe-duration.html +50 -0
  22. data/_includes/components/recipe-grams.html +58 -0
  23. data/_includes/components/recipe-index.html +96 -0
  24. data/_includes/components/recipe-ingredients.html +90 -0
  25. data/_includes/components/recipe-meta.html +96 -0
  26. data/_includes/components/recipe-nutrition.html +57 -0
  27. data/_includes/components/recipe-qty.html +73 -0
  28. data/_includes/components/recipe-ratio.html +151 -0
  29. data/_includes/components/recipe-scaler.html +73 -0
  30. data/_includes/components/recipe-steps.html +86 -0
  31. data/_includes/components/recipe-temp.html +45 -0
  32. data/_includes/components/search-modal.html +2 -2
  33. data/_includes/components/shortcuts-modal.html +3 -0
  34. data/_includes/components/theme-info.html +8 -1
  35. data/_includes/content/jsonld-software.html +22 -3
  36. data/_includes/core/footer.html +18 -16
  37. data/_includes/core/head.html +12 -0
  38. data/_includes/core/header.html +7 -4
  39. data/_includes/navigation/section-sidebar.html +93 -11
  40. data/_includes/navigation/sidebar-left.html +2 -1
  41. data/_includes/navigation/sidebar-right.html +2 -1
  42. data/_includes/setup/wizard.html +173 -86
  43. data/_includes/stats/stats-metrics.html +2 -2
  44. data/_layouts/README.md +2 -0
  45. data/_layouts/admin.html +2 -2
  46. data/_layouts/article.html +5 -0
  47. data/_layouts/cookbook.html +88 -0
  48. data/_layouts/default.html +4 -4
  49. data/_layouts/recipe.html +274 -0
  50. data/_layouts/root.html +22 -3
  51. data/_layouts/section.html +39 -10
  52. data/_sass/components/_callout.scss +1 -1
  53. data/_sass/components/_footer.scss +37 -1
  54. data/_sass/components/_page-views.scss +36 -0
  55. data/_sass/components/_recipe.scss +506 -0
  56. data/_sass/components/_setup-wizard.scss +235 -0
  57. data/_sass/components/_ui-enhancements.scss +6 -6
  58. data/_sass/core/_navbar.scss +250 -15
  59. data/_sass/layouts/_landing.scss +2 -2
  60. data/_sass/tokens/_color.scss +6 -0
  61. data/_sass/tokens/_index.scss +2 -0
  62. data/_sass/tokens/_radius.scss +21 -0
  63. data/_sass/tokens/_typography.scss +4 -0
  64. data/_sass/utilities/_focus.scss +14 -0
  65. data/assets/css/main.scss +3 -0
  66. data/assets/js/modules/navigation/navbar.js +55 -0
  67. data/assets/js/page-views.js +372 -0
  68. data/assets/js/recipe-scaler.js +501 -0
  69. data/assets/js/search-modal.js +10 -0
  70. data/assets/js/setup-wizard.js +322 -20
  71. data/scripts/README.md +29 -0
  72. data/scripts/bin/audit-consumer +39 -7
  73. data/scripts/bin/giscus-discussions +213 -14
  74. data/scripts/bin/manifest +35 -12
  75. data/scripts/ci/agent_review_result.py +164 -0
  76. data/scripts/ci/test_agent_review_result.py +172 -0
  77. data/scripts/design-system-check.rb +170 -0
  78. data/scripts/lib/audit.sh +42 -2
  79. data/scripts/lint-liquid-raw.rb +137 -0
  80. data/scripts/test/lib/run_tests.sh +2 -1
  81. data/scripts/test/lib/test_agent_review_result.sh +27 -0
  82. data/scripts/translate.rb +71 -15
  83. metadata +31 -2
data/_data/backlog.yml CHANGED
@@ -62,8 +62,8 @@
62
62
 
63
63
  meta:
64
64
  title: "zer0-mistakes Backlog"
65
- updated: 2026-06-29
66
- next_id: 34
65
+ updated: 2026-08-18
66
+ next_id: 46
67
67
 
68
68
  tasks:
69
69
  # --- Housekeeping (seeded so the loop has work on day one) ------------------
@@ -916,3 +916,357 @@ tasks:
916
916
  links: { issue: 302, pr: null, roadmap: null }
917
917
  created: 2026-07-12
918
918
  updated: 2026-07-16
919
+
920
+ - id: T-035
921
+ title: "Adopt --zer0-radius-* and display-size tokens across the remaining Sass partials"
922
+ status: open
923
+ priority: P2
924
+ area: feat
925
+ risk: low
926
+ effort: M
927
+ source: issue
928
+ route: theme-ui
929
+ summary: >-
930
+ The design-system alignment PR #389 (ZER0-081) introduced --zer0-radius-* and
931
+ --zer0-text-display-* tokens and adopted them in the partials the Claude
932
+ Design system names (callout, landing, ui-enhancements). Hardcoded radii
933
+ remain in _navbar.scss (~15 sites), notebooks.scss, code-copy.scss,
934
+ _docs-code-examples.scss, and others; hero .display-4 mobile overrides in
935
+ _ui-enhancements.scss (2rem and 1.75rem blocks — the two @media blocks
936
+ overlap, later wins) predate the fluid clamp tokens. Sweep them onto the
937
+ tokens value-preservingly where values match the scale, and reconcile the
938
+ duplicate hero override blocks; anything intentionally off-scale keeps a
939
+ literal plus a comment.
940
+ acceptance:
941
+ - "No border-radius literal in _sass/** that duplicates a --zer0-radius-* value (grep-clean or commented as intentional)."
942
+ - "Hero display sizing states one rule set; duplicate @media blocks reconciled."
943
+ - "scripts/design-system-check.rb still green; compiled CSS visually identical (evidence or skip-evidence rationale)."
944
+ - "regression test added"
945
+ - "before/after evidence committed"
946
+ links: { issue: null, pr: null, roadmap: null }
947
+ created: 2026-08-14
948
+ updated: 2026-08-14
949
+
950
+ # --- UI/UX fix list intake (hand-written review, 2026-08-18) ----------------
951
+
952
+ - id: T-036
953
+ title: "Remove hover transforms that cause pointer-edge flicker in the navbar"
954
+ status: open
955
+ priority: P1
956
+ area: feat
957
+ risk: standard
958
+ effort: S
959
+ source: user
960
+ route: theme-ui
961
+ summary: >-
962
+ .nav-link:hover, .nav-search-button:hover and .nav-settings-button:hover in
963
+ _sass/core/_navbar.scss apply transform: translateY(-1px) (icons scale 1.1,
964
+ chevron :hover::after translateY(2px)), so the element moves out from under
965
+ a pointer parked on its edge, hover exits, it returns — infinite flicker.
966
+ Delete every transform from :hover rules (keep background/color
967
+ transitions; a pressed cue may use :active translateY(1px) only) and audit
968
+ _sass/components/_ui-enhancements.scss and card hover styles for the same
969
+ pattern.
970
+ acceptance:
971
+ - "No transform in any :hover rule under _sass/ (grep for translateY/scale in hover context returns nothing)."
972
+ - "Pointer parked on the top edge of any nav item or utility button does not flicker."
973
+ - "regression test added"
974
+ - "before/after evidence committed"
975
+ links: { issue: null, pr: null, roadmap: null }
976
+ created: 2026-08-18
977
+ updated: 2026-08-18
978
+
979
+ - id: T-037
980
+ title: "Navbar width recovery: two clean label tiers, merged chevron, centered grid, no subtitle"
981
+ status: open
982
+ priority: P2
983
+ area: feat
984
+ risk: standard
985
+ effort: M
986
+ source: user
987
+ route: theme-ui
988
+ summary: >-
989
+ Top nav is cramped and truncates labels ("Quicksta…"). Keep per-item icons
990
+ at every tier but only two states — icon + full label (wide container) and
991
+ the existing icon-only tier (narrow) — removing the intermediate ellipsized
992
+ state (_includes/navigation/navbar.html + _sass/core/_navbar.scss container
993
+ queries). Merge each dropdown's separate 22-24px chevron button into the
994
+ parent link's padding box (position:absolute overlay, shared hover
995
+ background on the li, button kept for a11y). Use grid-template-columns:
996
+ 1fr auto 1fr on .navbar-main so the menu stays optically centered. Retire
997
+ the navbar subtitle (_includes/core/branding.html — home hero only).
998
+ Clarify the three toggles: labeled "Menu" text button below lg, gear moves
999
+ into the unified drawer on mobile so only two toggles coexist.
1000
+ acceptance:
1001
+ - "At 1024px and 1280px with 5 nav items every label is fully visible or the whole row is icon-only — no ellipses anywhere."
1002
+ - "Dropdown chevron shares the parent row's hover zone; no dead zone between link and chevron."
1003
+ - "Navbar carries logo + title only; subtitle appears on the home hero."
1004
+ - "regression test added"
1005
+ - "before/after evidence committed"
1006
+ links: { issue: null, pr: null, roadmap: null }
1007
+ created: 2026-08-18
1008
+ updated: 2026-08-18
1009
+
1010
+ - id: T-038
1011
+ title: "Language switcher: icon-only trigger and a compact, positive menu"
1012
+ status: open
1013
+ priority: P2
1014
+ area: feat
1015
+ risk: standard
1016
+ effort: S
1017
+ source: user
1018
+ route: theme-ui
1019
+ summary: >-
1020
+ _includes/components/language-toggle.html: drop the EN text span and the
1021
+ Bootstrap caret (38-40px square icon button; title + aria-label carry the
1022
+ name). In the menu, mark the current language with a check icon + tint
1023
+ (not .active primary fill); keep untranslated languages clickable
1024
+ (navigate to source page, set zer0-lang); mark machine translations with a
1025
+ small "auto" chip; replace per-row "(Not yet translated)" with one
1026
+ footnote line under a divider; menu width <= 220px.
1027
+ acceptance:
1028
+ - "Menu shows no disabled rows; widest row <= 220px; current language visually distinct without primary fill."
1029
+ - "Trigger is icon-only at all widths with an accessible name."
1030
+ - "regression test added"
1031
+ - "before/after evidence committed"
1032
+ links: { issue: null, pr: null, roadmap: null }
1033
+ created: 2026-08-18
1034
+ updated: 2026-08-18
1035
+
1036
+ - id: T-039
1037
+ title: "Eliminate page-transition layout shift (fixed-nav offset, scrollbar gutter, server-rendered slots)"
1038
+ status: open
1039
+ priority: P1
1040
+ area: perf
1041
+ risk: standard
1042
+ effort: M
1043
+ source: user
1044
+ route: theme-ui
1045
+ summary: >-
1046
+ Navigation between pages visibly bounces. Define --zer0-nav-height in
1047
+ :root, derive body padding-top and every sticky offset (admin.html's
1048
+ top: 5rem, TOC, sidebars) and scroll-margin-top from it (no JS
1049
+ measurement). Add html { scrollbar-gutter: stable }. Render banner/nanobar
1050
+ slots server-side with fixed height (nanobar 3px strip always present;
1051
+ setup banner via Liquid when site_needs_setup, not JS insert). Verify
1052
+ explicit width/height on content images and font-display: swap + preload
1053
+ for bootstrap-icons woff2. Progressive enhancement: @view-transition
1054
+ { navigation: auto } with a 120ms root fade.
1055
+ acceptance:
1056
+ - "Lighthouse CLS < 0.02 on landing, docs, and admin pages."
1057
+ - "No visible reflow when navigating between short and long pages (scrollbar gutter stable)."
1058
+ - "All sticky offsets derive from --zer0-nav-height (no hardcoded top: 5rem)."
1059
+ - "regression test added"
1060
+ - "before/after evidence committed"
1061
+ links: { issue: null, pr: null, roadmap: null }
1062
+ created: 2026-08-18
1063
+ updated: 2026-08-18
1064
+
1065
+ - id: T-040
1066
+ title: "Setup wizard: live YAML preview, vertical stepper, draft persistence, stable panel height, inline validation"
1067
+ status: open
1068
+ priority: P2
1069
+ area: feat
1070
+ risk: standard
1071
+ effort: M
1072
+ source: user
1073
+ route: theme-ui
1074
+ summary: >-
1075
+ _includes/setup/wizard.html + assets/js/setup-wizard.js: replace the
1076
+ step-5-only <pre> with a persistent sticky preview panel regenerated on
1077
+ every input (copy/download always enabled); replace nav-pills tabs with a
1078
+ left vertical stepper showing done/active/upcoming state (steps unlock on
1079
+ validation, Back always allowed, remove the "N% complete" math); persist
1080
+ the draft to localStorage under zer0-setup-draft (debounced 300ms, restore
1081
+ on load, "Draft saved" chip, clear on download); give the panel container
1082
+ a min-height equal to the tallest step so Back/Next never move vertically;
1083
+ validate email/URL on blur with is-invalid + message and list unfilled
1084
+ recommended fields as warnings on the Review step.
1085
+ acceptance:
1086
+ - "YAML preview visible and live at lg+; Back/Next buttons never shift vertically between steps."
1087
+ - "Reload mid-wizard restores the draft; invalid email/URL flagged on blur."
1088
+ - "regression test added"
1089
+ - "before/after evidence committed"
1090
+ links: { issue: null, pr: null, roadmap: null }
1091
+ created: 2026-08-18
1092
+ updated: 2026-08-18
1093
+
1094
+ - id: T-041
1095
+ title: "Admin layout: actions reachable on mobile, grouped sidebar, shared sticky offset, single heading"
1096
+ status: open
1097
+ priority: P2
1098
+ area: feat
1099
+ risk: standard
1100
+ effort: M
1101
+ source: user
1102
+ route: theme-ui
1103
+ summary: >-
1104
+ _layouts/admin.html + _includes/navigation/admin-nav.html: the
1105
+ admin_actions wrapper is d-none d-md-flex so actions are unreachable on
1106
+ phones — render the first action as a visible button at all widths with
1107
+ the rest in a "..." dropdown. Group sidebar items under small-caps headers
1108
+ (Configure / System / Links) via a group: key in
1109
+ _data/navigation/admin.yml; counts as plain numerals, statuses as colored
1110
+ dot + word; active item = tint + semibold, not solid primary fill. Replace
1111
+ style="top: 5rem" with top: calc(var(--zer0-nav-height) + 1rem) (depends
1112
+ on T-039). Keep the "Administration" heading in the offcanvas header only.
1113
+ acceptance:
1114
+ - "Every admin action reachable at 375px width."
1115
+ - "Sidebar grouped; no solid-primary active fill; sticky offset uses the shared variable."
1116
+ - "regression test added"
1117
+ - "before/after evidence committed"
1118
+ links: { issue: null, pr: null, roadmap: null }
1119
+ created: 2026-08-18
1120
+ updated: 2026-08-18
1121
+ depends_on: [T-039]
1122
+
1123
+ - id: T-042
1124
+ title: "Skin contrast sweep: AA link params, tertiary meta text, per-skin badge/button audit"
1125
+ status: open
1126
+ priority: P1
1127
+ area: a11y
1128
+ risk: standard
1129
+ effort: M
1130
+ source: user
1131
+ route: a11y
1132
+ summary: >-
1133
+ _sass/theme/_skins.scss: several skins omit the zer0-skin-palette mixin's
1134
+ $link-light/$link-dark params and fall back to $brand/$accent, which fail
1135
+ 4.5:1 (yellow/orange/cyan brands on white, saturated brands on #212529) —
1136
+ pass explicit AA-checked values for every skin with a comment table of
1137
+ measured ratios. text-body-tertiary on 11-12px meta text (admin header
1138
+ "Updated…", wizard hints) falls below AA — use --bs-secondary-color at
1139
+ small sizes, tertiary only >= 16px. Audit .btn-primary text per skin
1140
+ (auto-switch to dark text when brand luminance > 0.55 via color-contrast()
1141
+ or a precomputed token).
1142
+ acceptance:
1143
+ - "axe/Lighthouse contrast passes on light + dark for all skins."
1144
+ - "Every skin passes explicit link colors; measured-ratio table committed as comments."
1145
+ - "regression test added"
1146
+ - "before/after evidence committed"
1147
+ links: { issue: null, pr: null, roadmap: null }
1148
+ created: 2026-08-18
1149
+ updated: 2026-08-18
1150
+
1151
+ - id: T-043
1152
+ title: "Mermaid diagrams: render-in-place (no CLS), token-driven theming, figure shell, flash-free theme switch"
1153
+ status: open
1154
+ priority: P2
1155
+ area: feat
1156
+ risk: standard
1157
+ effort: L
1158
+ source: user
1159
+ route: theme-ui
1160
+ summary: >-
1161
+ _includes/components/mermaid.html: the hidden pre > code is replaced by a
1162
+ min-height:100px div that grows to 300-500px on render, shifting the page —
1163
+ render in place with the placeholder inheriting the code block's height
1164
+ and animate the swap. Delete the ~20 !important SVG overrides that fight
1165
+ JS themeVariables (forced white text breaks colored nodes; light mode uses
1166
+ #007bff vs site primary #0d6efd; skins don't affect diagrams) — build
1167
+ themeVariables at init from live tokens (getComputedStyle on --bs-primary
1168
+ / --bs-body-bg / --bs-border-color / --bs-body-color), re-run on
1169
+ data-bs-theme AND data-theme-skin change. Wrap each diagram in a
1170
+ figure.mermaid-figure with type chip, optional title, copy-source /
1171
+ download-SVG / fullscreen toolbar (reuse the code-copy button pattern) and
1172
+ figcaption. On theme switch render the new SVG off-DOM and cross-fade
1173
+ 120ms (instant under prefers-reduced-motion). Builds on T-039.
1174
+ acceptance:
1175
+ - "CLS contribution from a page with 3 diagrams < 0.01."
1176
+ - "No !important SVG overrides remain; diagrams follow theme AND skin tokens live."
1177
+ - "Theme switch shows no blank flash."
1178
+ - "regression test added"
1179
+ - "before/after evidence committed"
1180
+ links: { issue: null, pr: null, roadmap: null }
1181
+ created: 2026-08-18
1182
+ updated: 2026-08-18
1183
+ depends_on: [T-039]
1184
+
1185
+ - id: T-044
1186
+ title: "Playwright suite aborts: duplicate openDialog declaration in accessibility.spec.js"
1187
+ status: done
1188
+ priority: P1
1189
+ area: tests
1190
+ risk: low
1191
+ effort: S
1192
+ source: issue
1193
+ route: test-author
1194
+ summary: >-
1195
+ test/visual/core/accessibility.spec.js declares `async function
1196
+ openDialog` twice — at line 172 (page, selector) and again at line 425
1197
+ (page, selector, kind), the latter added by 98fd6f9 (#387) without
1198
+ removing the former. Two function declarations of the same name in one
1199
+ module scope is a SyntaxError, so Playwright fails to parse the file and
1200
+ the WHOLE run aborts before any test executes: "Identifier 'openDialog'
1201
+ has already been declared. (425:15)". This takes down the critical and
1202
+ smoke tiers together, on every branch, and has been red on main since
1203
+ 2026-08-14. Discovered during #414, whose own new spec
1204
+ (test/visual/features/recipes.spec.js) therefore cannot run in CI. The
1205
+ three-argument version is a strict superset — with `kind` undefined it
1206
+ resolves to Ctor='Modal' and 'shown.bs.modal', exactly what the
1207
+ two-argument one does — so deleting the earlier declaration (lines
1208
+ 165-184, comment included) is behaviour-preserving.
1209
+ acceptance:
1210
+ - "test/visual/core/accessibility.spec.js parses; `npx playwright test --project=critical` runs to completion."
1211
+ - "Only one openDialog declaration remains, and its callers all still pass."
1212
+ - "No behavioural change to the modal/offcanvas a11y tests."
1213
+ links: { issue: 416, pr: null, roadmap: null }
1214
+ created: 2026-08-23
1215
+ updated: 2026-08-23
1216
+
1217
+ - id: T-045
1218
+ title: "Homepage snapshot baselines were regenerated without the 1967px drift being diagnosed"
1219
+ status: open
1220
+ priority: P2
1221
+ area: tests
1222
+ risk: low
1223
+ effort: S
1224
+ source: issue
1225
+ route: test-author
1226
+ summary: >-
1227
+ The Visual Snapshots tier fails all 9 `Theme skins > homepage visual
1228
+ snapshot` cases with the SAME diff — 1967 pixels (ratio 0.01) — against
1229
+ test/visual/snapshots/features/appearance-snapshot.spec.js-snapshots/homepage-*-snapshots-linux.png,
1230
+ well over the maxDiffPixels 150 budget. The count being identical across
1231
+ air/aqua/contrast/dark/dirt/neon/mint/plum/sunrise points at one shared,
1232
+ skin-independent region rather than a palette regression. Verified during
1233
+ #414 that it is NOT that PR's doing: building origin/main and the PR
1234
+ branch and screenshotting the homepage at the spec's own 1280x720
1235
+ viewport produced BYTE-IDENTICAL PNGs (same md5), so the branch renders
1236
+ the homepage exactly as main does and the drift is between the committed
1237
+ baselines and what main itself now renders. Note while investigating:
1238
+ _includes/components/theme-info.html renders a minute-resolution build
1239
+ stamp, site.time | date "%b %d, %H:%M" — it currently sits in a collapsed
1240
+ offcanvas (measured 0x0, not in the viewport) so it is not the cause
1241
+ today, but it is a live non-determinism hazard the moment that panel is
1242
+ shown by default, and worth masking regardless. UPDATE 2026-08-23: #413
1243
+ regenerated all 9 baselines when it merged, so the check is green again —
1244
+ resolved by re-blessing rather than by diagnosis, which is what the first
1245
+ acceptance criterion was meant to prevent. Diffing the old vs new CI
1246
+ baselines (homepage-air, 2596f866 vs e488c4c) puts the whole 5016px delta
1247
+ in two bands: y21-41 (a wide navbar strip, 4688px) and y626 (328px).
1248
+ page-views does render on the homepage so part of that is legitimately
1249
+ #413, but a navbar strip is not where a view-count badge belongs.
1250
+ Separating the two needs the diff artifact from a pre-#413 failing run,
1251
+ which has rolled off. What remains is confirming the y21-41 band is
1252
+ accounted for. UPDATE 2026-08-25: the y21-41 band is the navbar
1253
+ reflowing, and the reason it RECURS is structural — a path-filter gap.
1254
+ ci.yml's `styling` filter (which gates the snapshots job) lists only code
1255
+ paths; `_data/**` appears solely under `content`, which gates no visual
1256
+ job. So #419's nav item changed the chrome of every page with Visual
1257
+ Snapshots SKIPPED on both the PR and the main push, and the drift
1258
+ surfaced on #420, an unrelated PR. The y626 band is now UNRECOVERABLE:
1259
+ both artifact uploads use 14-day retention (ci.yml, nightly-extended.yml)
1260
+ and every pre-#413 failing run is past that window. Recording that rather
1261
+ than leaving it open — no evidence survives to diagnose it from.
1262
+ acceptance:
1263
+ - "_data/** (or at minimum _data/navigation/**) is covered by the `styling` filter in ci.yml, so a nav/chrome data change runs Visual Snapshots instead of skipping it."
1264
+ - "A CI guard pins that coverage, so the gap cannot silently reopen (lint-workflows.yml)."
1265
+ - "A PR touching only _data/navigation/main.yml runs Visual Snapshots — demonstrated on the checks list, not asserted."
1266
+ - "Visual Snapshots passes on main and on a fresh branch with no source changes."
1267
+ - "Any genuinely time- or build-varying content inside the snapshot region is masked or stubbed, so the tier cannot drift again."
1268
+ - "No baseline PNG is regenerated as part of this work; any diff is diagnosed in the PR before it is blessed."
1269
+ - "The y626 band is explained, or recorded as unrecoverable with the reason. (Recorded: artifacts past 14-day retention.)"
1270
+ links: { issue: 417, pr: null, roadmap: null }
1271
+ created: 2026-08-23
1272
+ updated: 2026-08-25
data/_data/consumers.yml CHANGED
@@ -62,10 +62,18 @@ consumers:
62
62
  dispatch: false
63
63
  risk: >-
64
64
  Unpinned. Every push to this theme's main reaches production with no gate
65
- and no rollback. Shadows ~55 theme files (5 layouts, 34 includes, 8 JS, 6
66
- CSS, 2 plugins) the largest override surface in the fleet, including
67
- ~75 lines of !important CSS working around the stacking bug fixed in #338.
68
- Recommend pinning and joining the fan-out.
65
+ and no rollback that part is the real exposure. Recommend pinning and
66
+ joining the fan-out. NOTE: this entry previously claimed it "shadows ~55
67
+ theme files … ~75 lines of !important CSS working around #338", which
68
+ audit-consumer does not support. Only 2 files actually shadow a theme
69
+ file (_includes/content/giscus.html, assets/js/particles-source.js); the
70
+ other ~52 are it-journey's own quest-system layouts and includes that
71
+ share no filename with anything in this theme, so they carry no drift
72
+ risk at all. The !important CSS is real but is 31 lines in
73
+ assets/css/user-overrides.css — this theme's own documented extension
74
+ hook, enabled by `user_overrides: true`, not a shadow — and no fix
75
+ numbered #338 could be substantiated in that repo. Keep this field
76
+ derived from audit-consumer output, not hand-maintained estimates.
69
77
  pins:
70
78
  - file: _config.yml
71
79
  kind: remote_theme
@@ -145,3 +153,100 @@ consumers:
145
153
  - file: _data/hub.yml
146
154
  kind: hub_registry
147
155
  note: "line 39 (pages.theme_repo) — re-roll members after bumping"
156
+
157
+ # ---------------------------------------------------------------------------
158
+ # The four entries below were missing entirely until the 2026-08 fleet audit.
159
+ # Unregistered consumers are invisible to propagate.rb in BOTH directions: no
160
+ # release dispatch reaches them, and they never appear in the weekly drift
161
+ # report — so their pins can rot indefinitely with nothing to notice. That is
162
+ # exactly what happened to zer0-pages, which sat three minors behind on a gem
163
+ # constraint that already permitted the current release.
164
+ # ---------------------------------------------------------------------------
165
+ - repo: bamr87/zer0-pages
166
+ mode: gem
167
+ site: https://bamr87.github.io/zer0-pages/
168
+ dispatch: true
169
+ note: >-
170
+ Dual Obsidian-vault / Jekyll repo. Two things make it unlike every other
171
+ consumer. (1) It sets `source: pages`, so the whole themable tree lives
172
+ under pages/ — audit-consumer follows `source:` for this reason; auditing
173
+ the repo root reports a falsely clean result. (2) It is gem mode with no
174
+ remote_theme anywhere, so NOTHING is picked up automatically: the
175
+ scheduled bump is its only path to a new version.
176
+ risk: >-
177
+ Gemfile.lock resolved 1.25.0 while the Gemfile constraint (~> 1.25)
178
+ already permitted 1.28.0 — stale purely because nothing was nudging it.
179
+ Keeps two deliberate include forks, declared in its .theme-overrides.yml.
180
+ pins:
181
+ - file: Gemfile
182
+ kind: gem_constraint
183
+ note: 'line 11 — `gem "jekyll-theme-zer0", "~> 1.25"`'
184
+ - file: Gemfile.lock
185
+ kind: resolved_lockfile
186
+ note: "line 86 — re-lock with `bundle lock --update jekyll-theme-zer0`"
187
+ - file: _config.yml
188
+ kind: theme_name
189
+ note: "line 29 — `theme: jekyll-theme-zer0`; activates the gem, no version of its own"
190
+
191
+ # ---------------------------------------------------------------------------
192
+ - repo: bamr87/irony-works
193
+ mode: remote_theme_floating
194
+ site: https://bamr87.github.io/irony-works/
195
+ dispatch: false
196
+ note: >-
197
+ Vault + Node engine; engine/scripts/transplant.mjs converts vault/ into
198
+ the _entries/ collection before Jekyll runs. Has NO Gemfile at all — it
199
+ builds via actions/jekyll-build-pages (the github-pages image), so it can
200
+ only ever be tracked as remote_theme_floating; there is no gem constraint
201
+ surface for a bump to rewrite.
202
+ risk: >-
203
+ Unpinned, and with no local preview path a contributor cannot see a theme
204
+ break before pushing. Keeps three deliberate overrides, declared in its
205
+ .theme-overrides.yml.
206
+ pins:
207
+ - file: _config.yml
208
+ kind: remote_theme
209
+ note: line 4, no tag — floats main
210
+
211
+ # ---------------------------------------------------------------------------
212
+ - repo: bamr87/wargames
213
+ mode: remote_theme_floating
214
+ site: https://bamr87.github.io/wargames/
215
+ dispatch: false
216
+ note: >-
217
+ Content-only vendored mirror of the OverTheWire challenges. Zero local
218
+ theme files — one of the cleanest consumers in the fleet. Its _config.yml
219
+ uses column-aligned YAML (`remote_theme : "..."`), the style
220
+ that used to defeat audit-consumer's mode detection.
221
+ risk: >-
222
+ Unpinned, and its only build runs on push to main (jekyll-gh-pages.yml),
223
+ so a break ships before anyone sees it.
224
+ pins:
225
+ - file: _config.yml
226
+ kind: remote_theme
227
+ note: line 44, no tag — floats main
228
+
229
+ # ---------------------------------------------------------------------------
230
+ - repo: bamr87/zer0-pages-remote
231
+ mode: remote_theme_floating
232
+ site: https://bamr87.github.io/zer0-pages-remote/
233
+ dispatch: false
234
+ note: >-
235
+ The minimal reference consumer: _config.yml + Gemfile + index.md, no
236
+ local theme files and no _data at all, still showing the onboarding
237
+ wizard by design. Useful as the canary for what a stock remote_theme
238
+ consumer gets with zero customisation — if the theme breaks a bare site,
239
+ it breaks here first.
240
+ private: true
241
+ risk: >-
242
+ Unpinned. Low stakes (a demo, not a content site), but it has already
243
+ caught one real integration break: PR #8 fixed a Liquid `include_cached`
244
+ failure caused by a Gemfile plugin missing from the safe-mode whitelist.
245
+ This repo is PRIVATE, so an unauthenticated `propagate.rb` run reports it
246
+ "unreachable" rather than reading its pin — drift reporting needs a token
247
+ here even though it is read-only. CI already supplies one; a bare local
248
+ run will not.
249
+ pins:
250
+ - file: _config.yml
251
+ kind: remote_theme
252
+ note: line 12, no tag — floats main
data/_data/features.yml CHANGED
@@ -1037,6 +1037,7 @@ features:
1037
1037
  - "Client-side JSON search index"
1038
1038
  - "Bootstrap modal interface"
1039
1039
  - "Keyboard shortcut (/) activation"
1040
+ - "Cmd/Ctrl+K shortcut with visible navbar affordance — a / kbd chip on the search button (design-system navbar pattern), hover titles with platform-aware Cmd-K/Ctrl+K, aria-keyshortcuts, and shortcut hints on the sidebar (b) and TOC (t) toggles"
1040
1041
  - "Real-time search results"
1041
1042
  - "Accessible search input"
1042
1043
  - "No external dependency (Algolia removed v1.5.1)"
@@ -2256,3 +2257,159 @@ features:
2256
2257
  - "Immersive sidebar-free reading surface: storybook serif, responsive type scale, drop cap, plate styling for bare markdown images"
2257
2258
  - "illustrations: front matter renders a collapsed prompt colophon — the same list drives OpenAI image generation on consumer sites (drsai)"
2258
2259
  - "Demo book The Tales of Zer0 ships with the theme; reference platform: bamr87/drsai with Dodge & Reena as the test book"
2260
+
2261
+ - id: ZER0-081
2262
+ title: "Claude Design System Round-Trip"
2263
+ description: "Design-token layer aligned with the zer0-mistakes Claude Design project: corner-radius, logo-palette, and display-size tokens join _sass/tokens/; a git mirror of the design project lives under _design-system/ (plain-CSS tokens, React component specs from buttons to FABs to post cards to skeletons, foundation cards, website UI kit); and a CI parity check fails when theme and mirror drift"
2264
+ implemented: true
2265
+ version: "1.29.0"
2266
+ link: "/"
2267
+ docs: "https://github.com/bamr87/zer0-mistakes/blob/main/docs/ui/design-system.md"
2268
+ tags: [design-system, tokens, sass, ai, tooling]
2269
+ date: 2026-08-14
2270
+ provenance:
2271
+ introduced_in: "1.29.0"
2272
+ pr: 389
2273
+ commit: "7fc2fe02"
2274
+ issue: null
2275
+ tests:
2276
+ - "test/visual/core/styling.spec.js"
2277
+ - "scripts/design-system-check.rb"
2278
+ references:
2279
+ styles:
2280
+ - "_sass/tokens/_radius.scss"
2281
+ - "_sass/tokens/_index.scss"
2282
+ scripts:
2283
+ - "scripts/design-system-check.rb"
2284
+ design:
2285
+ - "_design-system/components/"
2286
+ - "_design-system/guidelines/"
2287
+ - "_design-system/tokens/"
2288
+ docs: "docs/ui/design-system.md"
2289
+ features:
2290
+ - "--zer0-radius-* corner radii, --zer0-logo-* brand palette, and --zer0-text-display-* fluid hero sizes declared once and consumed by callouts, landing cards, nav, and focus rings"
2291
+ - "_design-system/ mirrors the claude.ai/design project (id e75121c0-9210-42d1-ade3-2c8af9111cbe) so interfaces can be designed in Claude Design and folded back into the theme — contract in _design-system/SYNC.md"
2292
+ - "scripts/design-system-check.rb (core test suite) resolves var() alias chains and fails CI on token drift, plus flags fallback-less var(--zer0-*) references that are never declared"
2293
+ - "Component specs ship the theme's primitives as React twins — Button, Badge, Fab/FabStack, Card, FeatureCard, PostCard, Callout, Skeleton, Input — with foundation cards for colors, type, spacing, motion, layers, and brand (PR 391)"
2294
+ - "No webfonts, Bootstrap-first, seven skins, light+dark — the imported system and the theme now state one identical visual contract"
2295
+
2296
+ - id: ZER0-082
2297
+ title: "Live Design System Pages"
2298
+ description: "The design system published on the site itself: _design-system/ is force-included in the Jekyll build so tokens, styles.css, specimen cards, and component sources get real URLs under /_design-system/, and a /design/ hub page renders the foundation specimens in live iframes, catalogs the component twins, and links the Claude Design page canvas covering all 24 layouts"
2299
+ implemented: true
2300
+ version: "1.29.0"
2301
+ link: "/design/"
2302
+ docs: "https://github.com/bamr87/zer0-mistakes/blob/main/docs/ui/design-system.md"
2303
+ tags: [design-system, tokens, pages, navigation, ui]
2304
+ date: 2026-08-14
2305
+ provenance:
2306
+ introduced_in: "1.29.0"
2307
+ pr: 392
2308
+ commit: "6ac9f77d"
2309
+ issue: null
2310
+ tests:
2311
+ - "test/visual/features/design-hub.spec.js"
2312
+ references:
2313
+ pages:
2314
+ - "pages/_about/design.md"
2315
+ data:
2316
+ - "_data/navigation/main.yml"
2317
+ tests:
2318
+ - "test/visual/features/design-hub.spec.js"
2319
+ config: "_config.yml"
2320
+ features:
2321
+ - "Publishing is one config line — include: [_design-system] — so the mirror's plain-CSS tokens double as a hosted stylesheet any prototype can link"
2322
+ - "/design/ foundations gallery renders the actual specimen cards in iframes against the published tokens — living documentation, never screenshots"
2323
+ - "Component-twin catalog links every React spec (.jsx/.d.ts/.prompt.md) served raw from the mirror; interactive rendering stays in Claude Design"
2324
+ - "Page canvas: every layout, nav pattern, and chrome surface recreated as a Claude Design presentation, linked from the hub with a screen-to-repo-file map"
2325
+
2326
+ # ============================================================================
2327
+ # READER ENGAGEMENT (v1.29+)
2328
+ # ============================================================================
2329
+
2330
+ - id: ZER0-083
2331
+ title: "Page View Counter"
2332
+ description: "Per-page view tracking with the count shown in the article meta row — a local-first provider that needs no server, or an HTTP counter endpoint, both gated by DNT, GPC, and consent"
2333
+ implemented: true
2334
+ version: "1.29.0"
2335
+ link: "/"
2336
+ docs: "https://github.com/bamr87/zer0-mistakes/blob/main/docs/features/page-views.md"
2337
+ tags: [analytics, privacy, engagement, metrics, ui]
2338
+ date: 2026-08-23
2339
+ provenance:
2340
+ introduced_in: "1.29.0"
2341
+ pr: 413
2342
+ commit: "6ca4961b"
2343
+ issue: null
2344
+ tests:
2345
+ - "test/visual/features/page-views.spec.js"
2346
+ references:
2347
+ layouts:
2348
+ - "_layouts/article.html"
2349
+ includes:
2350
+ - "_includes/components/page-views.html"
2351
+ - "_includes/components/page-views-init.html"
2352
+ - "_includes/core/head.html"
2353
+ scripts:
2354
+ - "assets/js/page-views.js"
2355
+ styles:
2356
+ - "_sass/components/_page-views.scss"
2357
+ tests:
2358
+ - "test/visual/features/page-views.spec.js"
2359
+ config: "_config.yml"
2360
+ docs: "docs/features/page-views.md"
2361
+ features:
2362
+ - "Two providers: 'local' (default) keeps counts in the visitor's localStorage — no server, no network, GitHub-Pages safe; 'remote' reads a counter endpoint the site owns ({path} substitution, configurable method, dotted count_key)"
2363
+ - "Privacy gates mirror the posthog block (DNT, Global Privacy Control, optional cookie-consent 'analytics' tie-in) and suppress RECORDING only — a view blocked pending consent is recorded when consent arrives"
2364
+ - "dedupe: session counts one view per page per browser session, so a reload cannot inflate the number"
2365
+ - "The badge ships hidden and is revealed only once a count exists — no '0 views' flash — and carries its own leading separator so a hidden badge leaves no dangling bullet in the meta row"
2366
+ - "Every storage touch is probed and wrapped: private mode, blocked cookies, a corrupt payload, or an exceeded quota degrade to 'no count' instead of throwing"
2367
+ - "window.zer0PageViews (get/all/refresh/reset) plus a 'zer0:page-views' CustomEvent let a site build on the count without polling"
2368
+ - id: ZER0-084
2369
+ title: "Cookbook & Recipes Collection"
2370
+ description: "A `recipes` collection whose structured front matter (ingredients, steps, yield, times, ratio_basis) renders as a working recipe page: a fact bar, a serving scaler, an ingredient checklist, a numbered method, a build-time baker's-percentage table, and schema.org Recipe JSON-LD — with client-side scaling and US/metric conversion (volume↔weight via an ingredient density table) layered on as progressive enhancement"
2371
+ implemented: true
2372
+ version: "1.29.0"
2373
+ link: "/recipes/"
2374
+ docs: "/docs/features/cookbook-collection/"
2375
+ tags: [recipes, cookbook, collections, layouts, unit-conversion, structured-data]
2376
+ date: 2026-08-23
2377
+ provenance:
2378
+ introduced_in: "1.29.0"
2379
+ pr: null
2380
+ commit: "45354f34"
2381
+ issue: null
2382
+ tests:
2383
+ - "test/test_core.sh"
2384
+ references:
2385
+ layouts:
2386
+ - "_layouts/recipe.html"
2387
+ - "_layouts/cookbook.html"
2388
+ includes:
2389
+ - "_includes/components/recipe-index.html"
2390
+ - "_includes/components/recipe-card.html"
2391
+ - "_includes/components/recipe-meta.html"
2392
+ - "_includes/components/recipe-scaler.html"
2393
+ - "_includes/components/recipe-ingredients.html"
2394
+ - "_includes/components/recipe-steps.html"
2395
+ - "_includes/components/recipe-ratio.html"
2396
+ - "_includes/components/recipe-nutrition.html"
2397
+ - "_includes/components/recipe-qty.html"
2398
+ - "_includes/components/recipe-temp.html"
2399
+ - "_includes/components/recipe-grams.html"
2400
+ - "_includes/components/recipe-duration.html"
2401
+ styles: ["_sass/components/_recipe.scss"]
2402
+ scripts: ["assets/js/recipe-scaler.js"]
2403
+ data:
2404
+ - "_data/recipe_courses.yml"
2405
+ - "_data/ingredient_densities.yml"
2406
+ pages:
2407
+ - "pages/_recipes/index.md"
2408
+ - "pages/_docs/features/cookbook-collection.md"
2409
+ config: "_config.yml"
2410
+ components:
2411
+ - "Serving scaler — stepper, ½×/1×/2×/3× presets, ?servings= and ?scale= links, per-recipe scale remembered in localStorage"
2412
+ - "Unit switch — as written / metric / US, rewriting quantities, units and oven temperatures in place"
2413
+ - "Volume↔weight conversion driven by _data/ingredient_densities.yml, overridable per ingredient with grams_per_cup"
2414
+ - "Baker's-percentage ratio table computed at build time, so percentages are correct with JavaScript disabled"
2415
+ - "Progressive enhancement: quantities render as authored by Jekyll; the control bar stays hidden until the script reveals it"