jekyll-theme-zer0 1.27.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +812 -13
- data/_data/backlog.yml +356 -2
- data/_data/consumers.yml +252 -0
- data/_data/features.yml +234 -5
- data/_data/i18n/fr.yml +103 -0
- data/_data/i18n/manifest.yml +1529 -0
- data/_data/ingredient_densities.yml +122 -0
- data/_data/navigation/docs.yml +2 -0
- data/_data/navigation/main.yml +22 -0
- data/_data/recipe_courses.yml +64 -0
- data/_data/series.yml +19 -0
- data/_data/theme-manifest.yml +387 -277
- data/_data/ui-text.yml +8 -0
- data/_includes/README.md +36 -3
- data/_includes/analytics/google-tag-manager-body.html +11 -2
- data/_includes/analytics/google-tag-manager-head.html +16 -6
- data/_includes/analytics/posthog.html +33 -4
- data/_includes/components/abc-letter.html +43 -0
- data/_includes/components/background-customizer.html +2 -2
- data/_includes/components/book-card.html +42 -0
- data/_includes/components/book-nav.html +80 -0
- data/_includes/components/book-plate.html +31 -0
- data/_includes/components/book-toc.html +47 -0
- data/_includes/components/bookshelf.html +68 -0
- data/_includes/components/card-grid.html +60 -0
- data/_includes/components/cookie-consent.html +4 -4
- data/_includes/components/data-card.html +95 -0
- data/_includes/components/halfmoon.html +5 -1
- data/_includes/components/info-section.html +8 -3
- data/_includes/components/language-toggle.html +168 -21
- data/_includes/components/page-feedback.html +65 -2
- data/_includes/components/page-views-init.html +55 -0
- data/_includes/components/page-views.html +33 -0
- data/_includes/components/recipe-card.html +67 -0
- data/_includes/components/recipe-duration.html +50 -0
- data/_includes/components/recipe-grams.html +58 -0
- data/_includes/components/recipe-index.html +96 -0
- data/_includes/components/recipe-ingredients.html +90 -0
- data/_includes/components/recipe-meta.html +96 -0
- data/_includes/components/recipe-nutrition.html +57 -0
- data/_includes/components/recipe-qty.html +73 -0
- data/_includes/components/recipe-ratio.html +151 -0
- data/_includes/components/recipe-scaler.html +73 -0
- data/_includes/components/recipe-steps.html +86 -0
- data/_includes/components/recipe-temp.html +45 -0
- data/_includes/components/search-modal.html +2 -2
- data/_includes/components/shortcuts-modal.html +3 -0
- data/_includes/components/theme-controls-bar.html +10 -2
- data/_includes/components/theme-customizer.html +8 -2
- data/_includes/components/theme-info.html +8 -1
- data/_includes/content/jsonld-software.html +22 -3
- data/_includes/content/seo.html +9 -3
- data/_includes/core/color-mode-init.html +13 -4
- data/_includes/core/favicon.html +46 -0
- data/_includes/core/footer.html +18 -16
- data/_includes/core/head.html +21 -0
- data/_includes/core/header.html +7 -4
- data/_includes/custom/body-end.html +18 -0
- data/_includes/custom/body-start.html +17 -0
- data/_includes/custom/footer.html +18 -0
- data/_includes/custom/head.html +18 -0
- data/_includes/navigation/local-graph.html +28 -2
- data/_includes/navigation/nav-tree.html +3 -3
- data/_includes/navigation/section-sidebar.html +93 -11
- data/_includes/navigation/sidebar-config.html +21 -0
- data/_includes/navigation/sidebar-left.html +2 -1
- data/_includes/navigation/sidebar-nav.html +4 -0
- data/_includes/navigation/sidebar-pagetree.html +150 -0
- data/_includes/navigation/sidebar-right.html +2 -1
- data/_includes/navigation/unified-drawer.html +8 -2
- data/_includes/obsidian/full-graph.html +165 -136
- data/_includes/setup/wizard.html +173 -86
- data/_includes/stats/stats-metrics.html +2 -2
- data/_layouts/404.html +260 -0
- data/_layouts/README.md +4 -0
- data/_layouts/admin.html +2 -2
- data/_layouts/article.html +5 -0
- data/_layouts/book-abc.html +106 -0
- data/_layouts/book-story.html +91 -0
- data/_layouts/book.html +113 -0
- data/_layouts/collection.html +17 -5
- data/_layouts/cookbook.html +88 -0
- data/_layouts/default.html +4 -4
- data/_layouts/home.html +5 -2
- data/_layouts/landing.html +9 -0
- data/_layouts/news.html +155 -31
- data/_layouts/recipe.html +274 -0
- data/_layouts/root.html +38 -5
- data/_layouts/section.html +96 -25
- data/_sass/components/_book.scss +423 -0
- data/_sass/components/_callout.scss +1 -1
- data/_sass/components/_footer.scss +37 -1
- data/_sass/components/_page-views.scss +36 -0
- data/_sass/components/_recipe.scss +506 -0
- data/_sass/components/_setup-wizard.scss +235 -0
- data/_sass/components/_ui-enhancements.scss +6 -6
- data/_sass/core/_navbar.scss +263 -15
- data/_sass/core/_obsidian.scss +286 -6
- data/_sass/layouts/_landing.scss +2 -2
- data/_sass/theme/_backgrounds.scss +21 -8
- data/_sass/tokens/_color.scss +6 -0
- data/_sass/tokens/_index.scss +2 -0
- data/_sass/tokens/_radius.scss +21 -0
- data/_sass/tokens/_typography.scss +4 -0
- data/_sass/utilities/_focus.scss +14 -0
- data/assets/css/main.scss +4 -0
- data/assets/js/auto-hide-nav.js +5 -1
- data/assets/js/halfmoon.js +26 -0
- data/assets/js/modules/navigation/navbar.js +55 -0
- data/assets/js/obsidian-graph.js +702 -264
- data/assets/js/obsidian-local-graph.js +161 -54
- data/assets/js/page-views.js +372 -0
- data/assets/js/recipe-scaler.js +501 -0
- data/assets/js/search-modal.js +14 -1
- data/assets/js/setup-wizard.js +322 -20
- data/scripts/README.md +29 -0
- data/scripts/bin/audit-consumer +39 -7
- data/scripts/bin/giscus-discussions +213 -14
- data/scripts/bin/manifest +66 -16
- data/scripts/bin/validate +5 -1
- data/scripts/ci/agent_review_result.py +164 -0
- data/scripts/ci/test_agent_review_result.py +172 -0
- data/scripts/design-system-check.rb +170 -0
- data/scripts/install/README.md +47 -6
- data/scripts/install/ai/client.sh +302 -93
- data/scripts/install/ai/prompts/spec.schema.json +1 -1
- data/scripts/install/ai/wizard.sh +10 -5
- data/scripts/install/apply.sh +7 -3
- data/scripts/install/cli.sh +54 -4
- data/scripts/install/config.sh +167 -0
- data/scripts/install/doctor.sh +38 -0
- data/scripts/install/plan.sh +10 -0
- data/scripts/install/spec.sh +15 -7
- data/scripts/install/template.sh +4 -0
- data/scripts/lib/audit.sh +42 -2
- data/scripts/lint-liquid-raw.rb +137 -0
- data/scripts/propagate.rb +277 -0
- data/scripts/test/lib/run_tests.sh +2 -1
- data/scripts/test/lib/test_agent_review_result.sh +27 -0
- data/scripts/translate.rb +161 -15
- metadata +56 -2
data/_data/backlog.yml
CHANGED
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
|
|
63
63
|
meta:
|
|
64
64
|
title: "zer0-mistakes Backlog"
|
|
65
|
-
updated: 2026-
|
|
66
|
-
next_id:
|
|
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
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# ==============================================================================
|
|
2
|
+
# _data/consumers.yml — downstream consumers of this theme
|
|
3
|
+
# ==============================================================================
|
|
4
|
+
#
|
|
5
|
+
# The registry that makes theme releases propagate instead of sitting unnoticed.
|
|
6
|
+
# Every site that renders with zer0-mistakes is listed here together with HOW it
|
|
7
|
+
# consumes the theme and WHICH files hold its version pin.
|
|
8
|
+
#
|
|
9
|
+
# Read by:
|
|
10
|
+
# - scripts/bin/propagate report pin drift; dispatch release events
|
|
11
|
+
# - .github/workflows/propagate-theme.yml release fan-out
|
|
12
|
+
#
|
|
13
|
+
# Why this exists: nothing connected a release to the sites built on it. When
|
|
14
|
+
# 1.27.0 shipped, all five consumers were still on v1.26.0 (or floating on main)
|
|
15
|
+
# and none of them knew. Bumps were a manual, five-repo chore that nobody
|
|
16
|
+
# remembered, so pins drifted until a site broke.
|
|
17
|
+
#
|
|
18
|
+
# ------------------------------------------------------------------------------
|
|
19
|
+
# Consumption modes
|
|
20
|
+
# ------------------------------------------------------------------------------
|
|
21
|
+
# remote_theme_pinned `remote_theme: bamr87/zer0-mistakes@vX.Y.Z` — GitHub
|
|
22
|
+
# Pages fetches the tagged theme at build time. Gets a
|
|
23
|
+
# bump PR on release.
|
|
24
|
+
# remote_theme_floating `remote_theme: bamr87/zer0-mistakes` with no tag —
|
|
25
|
+
# tracks main, so every push to this repo reaches
|
|
26
|
+
# production immediately. Nothing to bump; what these
|
|
27
|
+
# need is a canary, not a PR. See `risk` below.
|
|
28
|
+
# gem `gem "jekyll-theme-zer0", "~> X.Y.Z"` — the theme is
|
|
29
|
+
# resolved from RubyGems, not GitHub. Bumping means
|
|
30
|
+
# editing a Gemfile and re-locking. This is the mode the
|
|
31
|
+
# scheduled updater matters most for: no remote_theme
|
|
32
|
+
# means no automatic pickup of anything, ever.
|
|
33
|
+
# path `gem "jekyll-theme-zer0", path: ...` — a local
|
|
34
|
+
# checkout for development. Never version-pinned and
|
|
35
|
+
# never bumped; listed so audits don't flag it.
|
|
36
|
+
#
|
|
37
|
+
# ------------------------------------------------------------------------------
|
|
38
|
+
# Pin kinds (scripts/bin/propagate knows how to read/rewrite each)
|
|
39
|
+
# ------------------------------------------------------------------------------
|
|
40
|
+
# remote_theme `remote_theme: "bamr87/zer0-mistakes@vX.Y.Z"` in a config
|
|
41
|
+
# hub_registry `theme_repo: bamr87/zer0-mistakes@vX.Y.Z` in _data/hub.yml
|
|
42
|
+
# gem_constraint `gem 'jekyll-theme-zer0', '~> X.Y.Z'` in a Gemfile
|
|
43
|
+
# theme_name `theme: "jekyll-theme-zer0"` — names the gem, carries no
|
|
44
|
+
# version; tracked so a bump doesn't miss the config that
|
|
45
|
+
# activates it
|
|
46
|
+
# path_gem local path gem, unversioned (development only)
|
|
47
|
+
# ==============================================================================
|
|
48
|
+
|
|
49
|
+
version: 1
|
|
50
|
+
|
|
51
|
+
defaults:
|
|
52
|
+
branch: main
|
|
53
|
+
# repository_dispatch event type consumers listen for. Their side of the
|
|
54
|
+
# contract lives in templates/consumer/theme-bump.yml.
|
|
55
|
+
dispatch_event: theme-release
|
|
56
|
+
|
|
57
|
+
consumers:
|
|
58
|
+
# ---------------------------------------------------------------------------
|
|
59
|
+
- repo: bamr87/it-journey
|
|
60
|
+
mode: remote_theme_floating
|
|
61
|
+
site: https://it-journey.dev
|
|
62
|
+
dispatch: false
|
|
63
|
+
risk: >-
|
|
64
|
+
Unpinned. Every push to this theme's main reaches production with no gate
|
|
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.
|
|
77
|
+
pins:
|
|
78
|
+
- file: _config.yml
|
|
79
|
+
kind: remote_theme
|
|
80
|
+
note: line 36, no tag — floats main
|
|
81
|
+
|
|
82
|
+
# ---------------------------------------------------------------------------
|
|
83
|
+
- repo: bamr87/lifehacker.dev
|
|
84
|
+
mode: remote_theme_floating
|
|
85
|
+
site: https://lifehacker.dev
|
|
86
|
+
dispatch: false
|
|
87
|
+
risk: >-
|
|
88
|
+
Unpinned, same exposure as it-journey. Small override surface (2 includes).
|
|
89
|
+
Recommend pinning and joining the fan-out.
|
|
90
|
+
pins:
|
|
91
|
+
- file: _config.yml
|
|
92
|
+
kind: remote_theme
|
|
93
|
+
note: line 40, no tag — floats main
|
|
94
|
+
|
|
95
|
+
# ---------------------------------------------------------------------------
|
|
96
|
+
- repo: bamr87/bashconsultants
|
|
97
|
+
mode: gem
|
|
98
|
+
site: https://bashconsultants.com
|
|
99
|
+
dispatch: true
|
|
100
|
+
note: >-
|
|
101
|
+
Three stacks, three theme surfaces: GitHub Pages uses the pinned
|
|
102
|
+
remote_theme, Azure Static Web Apps resolves the published gem via
|
|
103
|
+
Gemfile.azure + _config.azure.yml, and local dev mounts a path gem. A bump
|
|
104
|
+
must move the remote_theme tag and the gem constraint together or the two
|
|
105
|
+
production stacks render different theme versions.
|
|
106
|
+
pins:
|
|
107
|
+
- file: _config.yml
|
|
108
|
+
kind: remote_theme
|
|
109
|
+
note: line 31
|
|
110
|
+
- file: Gemfile.azure
|
|
111
|
+
kind: gem_constraint
|
|
112
|
+
note: line 9 — must match the remote_theme tag
|
|
113
|
+
- file: _config.azure.yml
|
|
114
|
+
kind: theme_name
|
|
115
|
+
note: line 3 — activates the gem; no version of its own
|
|
116
|
+
- file: Gemfile
|
|
117
|
+
kind: path_gem
|
|
118
|
+
note: line 40 — dev checkout via ZER0_MISTAKES_PATH; never bumped
|
|
119
|
+
|
|
120
|
+
# ---------------------------------------------------------------------------
|
|
121
|
+
- repo: year-of-ai/year-of-ai.github.io
|
|
122
|
+
mode: remote_theme_pinned
|
|
123
|
+
site: https://year-of-ai.github.io
|
|
124
|
+
dispatch: true
|
|
125
|
+
fans_out_to_members: true
|
|
126
|
+
note: >-
|
|
127
|
+
An org hub, not just a site. Its _data/hub.yml theme_repo is the value
|
|
128
|
+
stamped into every member repo's _config.yml by scripts/provision-org-sites.rb,
|
|
129
|
+
so one bump here re-rolls the whole org (12 sites). The hub's own
|
|
130
|
+
_config.yml and hub.yml must move together — they are read by different
|
|
131
|
+
code paths and drift silently otherwise.
|
|
132
|
+
pins:
|
|
133
|
+
- file: _config.yml
|
|
134
|
+
kind: remote_theme
|
|
135
|
+
note: line 40
|
|
136
|
+
- file: _data/hub.yml
|
|
137
|
+
kind: hub_registry
|
|
138
|
+
note: "line 42 (pages.theme_repo) — re-roll members after bumping"
|
|
139
|
+
|
|
140
|
+
# ---------------------------------------------------------------------------
|
|
141
|
+
- repo: ai-world-view/ai-world-view.github.io
|
|
142
|
+
mode: remote_theme_pinned
|
|
143
|
+
site: https://ai-world-view.github.io
|
|
144
|
+
dispatch: true
|
|
145
|
+
fans_out_to_members: true
|
|
146
|
+
note: >-
|
|
147
|
+
Same two-file hub shape as year-of-ai; members join by auto_discover, so
|
|
148
|
+
the member count grows without this file changing.
|
|
149
|
+
pins:
|
|
150
|
+
- file: _config.yml
|
|
151
|
+
kind: remote_theme
|
|
152
|
+
note: line 35
|
|
153
|
+
- file: _data/hub.yml
|
|
154
|
+
kind: hub_registry
|
|
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
|