jekyll-theme-zer0 1.24.0 → 1.26.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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +124 -0
  3. data/README.md +4 -4
  4. data/_data/authors.yml +1 -0
  5. data/_data/backlog.yml +26 -1
  6. data/_data/features.yml +73 -45
  7. data/_data/feedback_types.yml +148 -0
  8. data/_data/navigation/README.md +16 -6
  9. data/_data/navigation/main.yml +0 -8
  10. data/_data/roadmap.yml +1 -0
  11. data/_includes/README.md +10 -7
  12. data/_includes/analytics/google-analytics.html +1 -0
  13. data/_includes/analytics/google-tag-manager-body.html +1 -0
  14. data/_includes/analytics/google-tag-manager-head.html +1 -0
  15. data/_includes/analytics/posthog.html +1 -0
  16. data/_includes/components/README.md +3 -1
  17. data/_includes/components/admin-links.html +63 -0
  18. data/_includes/components/admin-tabs.html +1 -0
  19. data/_includes/components/ai-chat.html +27 -5
  20. data/_includes/components/author-eeat.html +1 -0
  21. data/_includes/components/background-customizer.html +1 -0
  22. data/_includes/components/background-settings.html +36 -37
  23. data/_includes/components/component-showcase.html +1 -0
  24. data/_includes/components/cookie-consent.html +1 -0
  25. data/_includes/components/dev-shortcuts.html +1 -8
  26. data/_includes/components/env-switcher.html +90 -138
  27. data/_includes/components/feature-card.html +1 -1
  28. data/_includes/components/halfmoon.html +22 -41
  29. data/_includes/components/info-section.html +127 -130
  30. data/_includes/components/mermaid.html +1 -0
  31. data/_includes/components/nanobar.html +1 -0
  32. data/_includes/components/page-feedback.html +252 -0
  33. data/_includes/components/post-type-badge.html +1 -0
  34. data/_includes/components/preview-image.html +1 -0
  35. data/_includes/components/search-modal.html +1 -0
  36. data/_includes/components/searchbar.html +1 -0
  37. data/_includes/components/shortcuts-modal.html +1 -0
  38. data/_includes/components/theme-info.html +21 -30
  39. data/_includes/components/theme-preview-gallery.html +1 -0
  40. data/_includes/content/backlinks.html +1 -0
  41. data/_includes/content/giscus.html +1 -0
  42. data/_includes/content/intro.html +20 -62
  43. data/_includes/content/jsonld-faq.html +1 -0
  44. data/_includes/content/seo.html +1 -0
  45. data/_includes/content/sitemap.html +1 -0
  46. data/_includes/content/toc.html +1 -0
  47. data/_includes/core/color-mode-init.html +1 -0
  48. data/_includes/core/console-capture.html +89 -0
  49. data/_includes/core/footer.html +1 -0
  50. data/_includes/core/head.html +5 -0
  51. data/_includes/core/header.html +5 -15
  52. data/_includes/navigation/admin-nav.html +1 -0
  53. data/_includes/navigation/breadcrumbs.html +1 -0
  54. data/_includes/navigation/local-graph-fab.html +3 -9
  55. data/_includes/navigation/local-graph.html +4 -9
  56. data/_includes/navigation/navbar.html +1 -0
  57. data/_includes/navigation/sidebar-categories.html +56 -14
  58. data/_includes/navigation/sidebar-config.html +115 -0
  59. data/_includes/navigation/sidebar-folders.html +168 -62
  60. data/_includes/navigation/sidebar-left.html +29 -52
  61. data/_includes/navigation/sidebar-nav.html +30 -0
  62. data/_includes/navigation/sidebar-right.html +1 -0
  63. data/_includes/navigation/toc-fab.html +3 -9
  64. data/_includes/navigation/unified-drawer.html +7 -14
  65. data/_includes/obsidian/full-graph.html +1 -0
  66. data/_includes/setup/wizard.html +1 -0
  67. data/_includes/stats/stats-categories.html +1 -0
  68. data/_includes/stats/stats-header.html +1 -0
  69. data/_includes/stats/stats-metrics.html +1 -0
  70. data/_includes/stats/stats-overview.html +1 -0
  71. data/_includes/stats/stats-tags.html +1 -0
  72. data/_layouts/admin.html +1 -0
  73. data/_layouts/article.html +1 -0
  74. data/_layouts/author.html +1 -0
  75. data/_layouts/authors.html +1 -0
  76. data/_layouts/collection.html +1 -0
  77. data/_layouts/default.html +14 -37
  78. data/_layouts/home.html +1 -0
  79. data/_layouts/index.html +1 -0
  80. data/_layouts/landing.html +1 -0
  81. data/_layouts/news.html +1 -0
  82. data/_layouts/note.html +1 -0
  83. data/_layouts/notebook.html +1 -0
  84. data/_layouts/root.html +6 -2
  85. data/_layouts/search.html +1 -0
  86. data/_layouts/section.html +1 -0
  87. data/_layouts/setup.html +1 -0
  88. data/_layouts/sitemap-collection.html +1 -0
  89. data/_layouts/stats.html +1 -0
  90. data/_layouts/tag.html +1 -0
  91. data/_layouts/welcome.html +1 -0
  92. data/_plugins/author_pages_generator.rb +1 -0
  93. data/_plugins/obsidian_links.rb +1 -0
  94. data/_plugins/preview_image_generator.rb +1 -0
  95. data/_plugins/search_and_sitemap_generator.rb +1 -0
  96. data/_plugins/theme_version.rb +1 -0
  97. data/_sass/components/_author.scss +12 -1
  98. data/_sass/components/_footer.scss +22 -0
  99. data/_sass/components/_page-feedback.scss +276 -0
  100. data/_sass/components/_ui-enhancements.scss +9 -0
  101. data/_sass/core/_docs-layout.scss +3 -78
  102. data/_sass/core/_navbar.scss +10 -27
  103. data/_sass/core/_obsidian.scss +2 -2
  104. data/_sass/core/code-copy.scss +10 -0
  105. data/_sass/custom.scss +1 -0
  106. data/_sass/notebooks.scss +1 -0
  107. data/_sass/theme/_backgrounds.scss +7 -2
  108. data/_sass/tokens/_layers.scss +4 -0
  109. data/_sass/utilities/_layout.scss +11 -0
  110. data/assets/css/main.scss +3 -1
  111. data/assets/js/ai-chat.js +1 -0
  112. data/assets/js/author-profile.js +1 -0
  113. data/assets/js/auto-hide-nav.js +1 -0
  114. data/assets/js/back-to-top.js +1 -0
  115. data/assets/js/background-customizer.js +1 -0
  116. data/assets/js/code-copy.js +1 -0
  117. data/assets/js/halfmoon.js +23 -22
  118. data/assets/js/modules/navigation/gestures.js +1 -0
  119. data/assets/js/modules/navigation/keyboard.js +1 -0
  120. data/assets/js/modules/navigation/scroll-spy.js +1 -0
  121. data/assets/js/modules/navigation/sidebar-state.js +1 -0
  122. data/assets/js/modules/navigation/sidebar-visibility.js +1 -0
  123. data/assets/js/modules/navigation/smooth-scroll.js +1 -0
  124. data/assets/js/modules/theme/appearance.js +52 -16
  125. data/assets/js/nanobar-init.js +1 -0
  126. data/assets/js/navigation.js +1 -0
  127. data/assets/js/obsidian-graph.js +1 -0
  128. data/assets/js/obsidian-wiki-links.js +1 -0
  129. data/assets/js/page-feedback.js +660 -0
  130. data/assets/js/palette-generator.js +1 -0
  131. data/assets/js/particles-source.js +1 -0
  132. data/assets/js/search-modal.js +1 -0
  133. data/assets/js/setup-wizard.js +1 -0
  134. data/assets/js/share-actions.js +1 -0
  135. data/assets/js/skin-editor.js +1 -0
  136. data/assets/js/table-copy.js +1 -0
  137. data/assets/js/theme-customizer.js +1 -0
  138. data/scripts/analyze-commits.sh +1 -0
  139. data/scripts/bin/giscus-discussions +1 -0
  140. data/scripts/bin/install +1 -0
  141. data/scripts/bin/validate +1 -0
  142. data/scripts/build +1 -0
  143. data/scripts/content-review.rb +1 -0
  144. data/scripts/convert-notebooks.sh +4 -3
  145. data/scripts/fix-markdown-format.sh +1 -0
  146. data/scripts/generate-preview-images.sh +1 -0
  147. data/scripts/generate-roadmap.sh +1 -0
  148. data/scripts/install-preview-generator.sh +1 -0
  149. data/scripts/release +1 -0
  150. data/scripts/requirements.txt +11 -0
  151. data/scripts/setup.sh +1 -0
  152. data/scripts/tag-features +136 -0
  153. data/scripts/validate-features.rb +7 -0
  154. data/scripts/vendor-install.sh +1 -0
  155. metadata +13 -4
  156. data/_data/prompts.yml +0 -302
  157. data/_plugins/admin_page_urls.rb +0 -16
@@ -0,0 +1,148 @@
1
+ # _data/feedback_types.yml
2
+ #
3
+ # Request types for the page-feedback capture widget:
4
+ # _includes/components/page-feedback.html + assets/js/page-feedback.js
5
+ #
6
+ # This REPLACES the build-time "Copilot Agent" dropdown that baked
7
+ # _data/prompts.yml into every <a href> at build time. The widget now injects
8
+ # this list as JSON and assembles the GitHub issue at RUNTIME, so it can also
9
+ # attach live page context and a captured console-log buffer — things a
10
+ # build-time Liquid link can never see.
11
+ #
12
+ # ─── Schema (per entry) ──────────────────────────────────────────────────────
13
+ # id unique slug — used in the issue title tag ([id]) and analytics
14
+ # label short text shown in the type selector
15
+ # icon Bootstrap Icons class (https://icons.getbootstrap.com/)
16
+ # group section header in the selector ("This page" | "The site")
17
+ # scope page | site — targets this page, or the theme as a whole
18
+ # description one-line helper shown under the label
19
+ # labels GitHub labels applied to the issue. MUST already exist in the
20
+ # repo: GitHub SILENTLY DROPS unknown labels from a prefilled URL
21
+ # (this was the old feature's `labels=ai-agent` bug). Verify with
22
+ # `gh label list`. The marker label from
23
+ # site.page_feedback.default_labels is added on top of these.
24
+ # agent true → assign @copilot and attach `directive` for autonomous work
25
+ # false → human triage only (no assignee, no directive)
26
+ # directive compact agent instruction. Kept SHORT on purpose — it rides in
27
+ # the prefilled issue URL, and long bodies blow the URL-length
28
+ # budget. The full context table + logs are added by the widget.
29
+ # placeholder textarea placeholder tailored to this request type
30
+ # ─────────────────────────────────────────────────────────────────────────────
31
+
32
+ # ─── This page — scoped to the page the widget was opened from ───────────────
33
+
34
+ - id: fix-page
35
+ label: Report a problem
36
+ icon: bi-bug
37
+ group: This page
38
+ scope: page
39
+ description: A typo, broken link, wrong information, or something rendering badly
40
+ labels: [bug]
41
+ agent: true
42
+ directive: >-
43
+ Reproduce and fix the reported defect on the page identified in Page
44
+ Context. Keep the change minimal and surgical; verify with a Jekyll build.
45
+ placeholder: What is wrong, where on the page, and what did you expect instead?
46
+
47
+ - id: improve-page
48
+ label: Improve this page
49
+ icon: bi-stars
50
+ group: This page
51
+ scope: page
52
+ description: Polish the copy, structure, or presentation
53
+ labels: [enhancement, "area:docs"]
54
+ agent: true
55
+ directive: >-
56
+ Act as a content editor for the page in Page Context. Tighten copy, fix
57
+ grammar, improve heading hierarchy and visual rhythm — without changing the
58
+ core message or breaking links.
59
+ placeholder: What would make this page clearer, tighter, or more useful?
60
+
61
+ - id: expand-page
62
+ label: Add missing detail
63
+ icon: bi-arrows-angle-expand
64
+ group: This page
65
+ scope: page
66
+ description: Add depth, examples, or a section a reader would expect
67
+ labels: [enhancement, "area:docs"]
68
+ agent: true
69
+ directive: >-
70
+ Expand the page in Page Context with concrete examples, prerequisites, and
71
+ any expected-but-missing sections. Preserve tone and front matter.
72
+ placeholder: What is missing? Which examples or sections would help?
73
+
74
+ - id: update-page
75
+ label: Flag outdated content
76
+ icon: bi-arrow-clockwise
77
+ group: This page
78
+ scope: page
79
+ description: Stale versions, dead links, or old screenshots
80
+ labels: [documentation, "area:docs"]
81
+ agent: true
82
+ directive: >-
83
+ Audit the page in Page Context for stale versions, dead links, and outdated
84
+ screenshots; refresh them and bump `lastmod`.
85
+ placeholder: What is out of date? Paste the stale value or link if you can.
86
+
87
+ - id: accessibility
88
+ label: Accessibility issue
89
+ icon: bi-universal-access
90
+ group: This page
91
+ scope: page
92
+ description: Contrast, keyboard, screen-reader, or focus problems
93
+ labels: ["area:a11y"]
94
+ agent: true
95
+ directive: >-
96
+ Audit the page in Page Context against WCAG 2.1 AA for the reported barrier
97
+ (contrast, keyboard, focus, ARIA, alt text) and propose concrete fixes.
98
+ placeholder: What barrier did you hit? Which assistive tech or input method?
99
+
100
+ # ─── The site — theme-wide UI, components, features, performance ──────────────
101
+
102
+ - id: ui-ux
103
+ label: UI / UX improvement
104
+ icon: bi-palette
105
+ group: The site
106
+ scope: site
107
+ description: A design or usability refinement for the theme
108
+ labels: [enhancement, "area:feat"]
109
+ agent: true
110
+ directive: >-
111
+ Propose a Bootstrap-first UI/UX refinement, using the page in Page Context
112
+ as the starting example. Cover responsive behaviour, dark mode, and a11y.
113
+ placeholder: What feels off, and how might it look or behave instead?
114
+
115
+ - id: performance
116
+ label: Performance
117
+ icon: bi-speedometer2
118
+ group: The site
119
+ scope: site
120
+ description: Slow load, layout shift, or heavy assets
121
+ labels: ["area:perf"]
122
+ agent: true
123
+ directive: >-
124
+ Profile the page in Page Context (LCP, CLS, INP), identify the bottleneck,
125
+ and propose GitHub Pages-safe fixes.
126
+ placeholder: What felt slow? On what device / connection?
127
+
128
+ - id: feature
129
+ label: Feature request
130
+ icon: bi-lightbulb
131
+ group: The site
132
+ scope: site
133
+ description: Propose a new site-wide capability
134
+ labels: [enhancement, "area:feat"]
135
+ agent: false
136
+ directive: ""
137
+ placeholder: What should it do, and who benefits?
138
+
139
+ - id: question
140
+ label: Ask a question
141
+ icon: bi-question-circle
142
+ group: The site
143
+ scope: site
144
+ description: Something unclear — not necessarily a bug
145
+ labels: [question]
146
+ agent: false
147
+ directive: ""
148
+ placeholder: What are you trying to do, and where did you get stuck?
@@ -19,11 +19,18 @@
19
19
  #
20
20
  # ## Navigation Modes
21
21
  #
22
- # The sidebar supports three navigation modes set via `page.sidebar.nav`:
23
- #
24
- # 1. **auto** - Auto-generates from collection documents
25
- # 2. **tree** - Uses YAML data from this directory
26
- # 3. **categories** - Groups by Jekyll categories
22
+ # The sidebar supports these navigation modes set via `page.sidebar.nav`
23
+ # (resolved by _includes/navigation/sidebar-config.html; page front matter →
24
+ # collection `sidebar:` metadata site.sidebar nothing):
25
+ #
26
+ # 1. **auto** - Best mode for the page's collection: a curated
27
+ # _data/navigation/<collection>.yml wins, then the live "collection"
28
+ # folder tree, then post "categories"
29
+ # 2. **collection** - Live folder tree of the page's (or a named) collection
30
+ # 3. **categories** - Posts grouped by Jekyll category
31
+ # 4. **tags** - Posts grouped by Jekyll tag
32
+ # 5. **<file name>** - Any other value renders _data/navigation/<value>.yml
33
+ # as a curated tree (e.g. `nav: docs` → docs.yml)
27
34
  #
28
35
  # ## Available Files
29
36
  #
@@ -42,6 +49,9 @@
42
49
  # nav: docs # Uses _data/navigation/docs.yml
43
50
  # ```
44
51
  #
52
+ # Collections named like a file here get it automatically under `nav: auto`
53
+ # (docs.yml, about.yml, quickstart.yml, posts.yml ↔ the matching collection).
54
+ #
45
55
  # ## Navbar capacity & responsive constraints (main.yml)
46
56
  #
47
57
  # The top navbar adapts the `main.yml` items to the viewport automatically:
@@ -64,7 +74,7 @@
64
74
  # - The theme also clips stray horizontal page overflow at the root, so an
65
75
  # over-stuffed nav or wide content can never make the fixed navbar look "cut
66
76
  # off". Wide tables/code keep their own local scroll. Regression-guarded by
67
- # test/visual/navbar-responsive.spec.js.
77
+ # test/visual/features/navbar.spec.js.
68
78
  #
69
79
  # ## Schema Validation
70
80
  #
@@ -18,8 +18,6 @@
18
18
  icon: bi-newspaper
19
19
  url: /news/
20
20
  children:
21
- - title: All News
22
- url: /news/
23
21
  - title: Categories
24
22
  url: /categories/
25
23
  - title: Tags
@@ -29,8 +27,6 @@
29
27
  icon: bi-journal-text
30
28
  url: /notes/
31
29
  children:
32
- - title: All Notes
33
- url: /notes/
34
30
  - title: Git Cheatsheet
35
31
  url: /notes/git-cheatsheet/
36
32
  - title: Docker Commands
@@ -46,8 +42,6 @@
46
42
  icon: bi-journal-code
47
43
  url: /notebooks/
48
44
  children:
49
- - title: All Notebooks
50
- url: /notebooks/
51
45
  - title: Test Notebook
52
46
  url: /notebooks/test-notebook/
53
47
 
@@ -55,8 +49,6 @@
55
49
  icon: bi-journal-bookmark
56
50
  url: /docs/
57
51
  children:
58
- - title: Documentation Home
59
- url: /docs/
60
52
  - title: Installation
61
53
  url: /docs/installation/
62
54
  - title: Jekyll Guide
data/_data/roadmap.yml CHANGED
@@ -1,3 +1,4 @@
1
+ # Feature: ZER0-052
1
2
  # =============================================================================
2
3
  # zer0-mistakes Roadmap — Single Source of Truth
3
4
  # =============================================================================
data/_includes/README.md CHANGED
@@ -18,10 +18,12 @@ Essential layout components that form the foundation of the site:
18
18
  All navigation-related components:
19
19
 
20
20
  - `navbar.html` - Main navigation menu
21
- - `sidebar-left.html` - Left sidebar with dynamic navigation
21
+ - `sidebar-left.html` - Left sidebar panel (offcanvas shell around the resolved nav)
22
+ - `sidebar-config.html` - Resolves the effective sidebar mode/title/icon (page → collection → site); shared by layout, header, sidebar, and drawer
23
+ - `sidebar-nav.html` - Renders the resolved sidebar mode (dispatches to the includes below)
22
24
  - `sidebar-right.html` - Right sidebar content
23
- - `sidebar-folders.html` - Dynamic folder structure generation
24
- - `sidebar-categories.html` - Category-based navigation
25
+ - `sidebar-folders.html` - "collection" mode: collapsible folder tree of a collection's documents
26
+ - `sidebar-categories.html` - "categories"/"tags" modes: posts grouped by taxonomy term
25
27
  - `nav_list.html` - Manual navigation list rendering
26
28
  - `breadcrumbs.html` - Navigation breadcrumbs
27
29
 
@@ -37,12 +39,13 @@ Analytics and tracking integrations:
37
39
 
38
40
  Reusable UI components and widgets:
39
41
 
40
- - `searchbar.html` - Search functionality
42
+ - `searchbar.html` - Deprecated search stub (superseded by `search-modal.html`)
41
43
  - `powered-by.html` - "Powered by" credits display
42
44
  - `quick-index.html` - Quick page index
43
45
  - `dev-shortcuts.html` - Developer shortcuts
44
- - `info-section.html` - Settings/info modal
45
- - `halfmoon.html` - Dark mode toggle
46
+ - `info-section.html` - Settings offcanvas (Appearance / Site / Developer tabs)
47
+ - `admin-links.html` - Cached admin quick links for the settings offcanvas
48
+ - `halfmoon.html` - Light/dark/auto color-mode segmented control
46
49
  - `zer0-env-var.html` - Environment variable configuration
47
50
  - `svg.html` - SVG icon definitions
48
51
  - `js-cdn.html` - CDN JavaScript libraries
@@ -79,7 +82,7 @@ When including files in layouts or other templates, use the full path:
79
82
  ```liquid
80
83
  {% include core/head.html %}
81
84
  {% include navigation/sidebar-left.html %}
82
- {% include components/searchbar.html %}
85
+ {% include components/search-modal.html %}
83
86
  {% include analytics/google-analytics.html %}
84
87
  ```
85
88
 
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-038 {% endcomment %}
1
2
  <!-- Global site tag (gtag.js) - Google Analytics -->
2
3
  <script>
3
4
  (function () {
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-039 {% endcomment %}
1
2
  <!-- Google Tag Manager (noscript) -->
2
3
  <noscript>
3
4
  <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NN8P7RZ"
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-039 {% endcomment %}
1
2
  <!--
2
3
  title: Google Tag Manager
3
4
  file:
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-006 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  POSTHOG ANALYTICS - Privacy-First Web Analytics Integration
@@ -87,9 +87,11 @@ If a component needs a token that doesn't exist yet, propose it in `_sass/tokens
87
87
  | Component | Purpose |
88
88
  |--------------------------|------------------------------------------------------|
89
89
  | `author-eeat.html` | E-E-A-T author bio with Schema.org markup. |
90
- | `info-section.html` | Settings offcanvas with theme/appearance controls. |
90
+ | `admin-links.html` | Cached admin quick links (settings offcanvas Site tab). |
91
+ | `info-section.html` | Settings offcanvas — Appearance / Site / Developer. |
91
92
  | `js-cdn.html` | Body-end script bundle. |
92
93
  | `search-modal.html` | Global search modal. |
94
+ | `page-feedback.html` | "Improve this page" capture widget — request type + live page context + captured console logs → GitHub issue (base prefill + optional AI enrichment). Pairs with `assets/js/page-feedback.js` and `core/console-capture.html`; types from `_data/feedback_types.yml`. |
93
95
 
94
96
  ## Adding a new component
95
97
 
@@ -0,0 +1,63 @@
1
+ {% comment %} Feature: ZER0-077 {% endcomment %}
2
+ {%- comment -%}
3
+ Component: admin-links
4
+ Path: _includes/components/admin-links.html
5
+ Purpose: "Admin" section of the settings offcanvas — quick links to the
6
+ built-in admin pages, each rendered only when the target page
7
+ exists in the build (prevents 404s on bare-minimum /
8
+ remote-theme sites that haven't created the admin pages).
9
+ Params: none — site-scoped only. Include with {% include_cached %} so
10
+ the URL scan below runs once per build, not once per page.
11
+ Depends on: site.pages, the `about` collection, Bootstrap list-group.
12
+ Notes: Pure Liquid on purpose: local _plugins never load under the
13
+ github-pages gem (it forces safe mode and randomizes
14
+ plugins_dir), so a plugin-computed lookup is dead on GitHub
15
+ Pages and in the Docker dev server. Keep page.* out of this
16
+ file — it would poison the include cache.
17
+ {%- endcomment -%}
18
+
19
+ {%- assign _page_urls = site.pages | map: "url" | join: "|" -%}
20
+ {%- assign _about_urls = "" -%}
21
+ {%- if site.about -%}
22
+ {%- assign _about_urls = site.about | map: "url" | join: "|" -%}
23
+ {%- endif -%}
24
+ {%- capture _admin_urls -%}|{{ _page_urls }}|{{ _about_urls }}|{%- endcapture -%}
25
+
26
+ {%- assign _cfg_page = false -%}
27
+ {%- assign _theme_page = false -%}
28
+ {%- assign _nav_page = false -%}
29
+ {%- assign _env_page = false -%}
30
+ {%- if _admin_urls contains "|/about/config/|" -%}{% assign _cfg_page = true %}{%- endif -%}
31
+ {%- if _admin_urls contains "|/about/settings/theme/|" -%}{% assign _theme_page = true %}{%- endif -%}
32
+ {%- if _admin_urls contains "|/about/settings/navigation/|" -%}{% assign _nav_page = true %}{%- endif -%}
33
+ {%- if _admin_urls contains "|/about/settings/environment/|" -%}{% assign _env_page = true %}{%- endif -%}
34
+
35
+ {% if _cfg_page or _theme_page or _nav_page or _env_page %}
36
+ <div class="mb-3">
37
+ <h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
38
+ <i class="bi bi-speedometer2 me-1" aria-hidden="true"></i>Admin
39
+ </h6>
40
+ <div class="list-group list-group-flush small">
41
+ {% if _cfg_page %}
42
+ <a href="{{ '/about/config/' | relative_url }}" class="list-group-item list-group-item-action d-flex align-items-center px-0">
43
+ <i class="bi bi-gear me-2 text-body-secondary" aria-hidden="true"></i>Configuration
44
+ </a>
45
+ {% endif %}
46
+ {% if _theme_page %}
47
+ <a href="{{ '/about/settings/theme/' | relative_url }}" class="list-group-item list-group-item-action d-flex align-items-center px-0">
48
+ <i class="bi bi-palette me-2 text-body-secondary" aria-hidden="true"></i>Theme Customizer
49
+ </a>
50
+ {% endif %}
51
+ {% if _nav_page %}
52
+ <a href="{{ '/about/settings/navigation/' | relative_url }}" class="list-group-item list-group-item-action d-flex align-items-center px-0">
53
+ <i class="bi bi-signpost-2 me-2 text-body-secondary" aria-hidden="true"></i>Navigation Editor
54
+ </a>
55
+ {% endif %}
56
+ {% if _env_page %}
57
+ <a href="{{ '/about/settings/environment/' | relative_url }}" class="list-group-item list-group-item-action d-flex align-items-center px-0">
58
+ <i class="bi bi-hdd-network me-2 text-body-secondary" aria-hidden="true"></i>Environment Dashboard
59
+ </a>
60
+ {% endif %}
61
+ </div>
62
+ </div>
63
+ {% endif %}
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-050 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  ADMIN TABS — Reusable tabbed interface for admin pages
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-060 {% endcomment %}
1
2
  {%- comment -%}
2
3
  Component: ai-chat
3
4
  Path: _includes/components/ai-chat.html
@@ -351,14 +352,35 @@
351
352
  @media (max-width: 576px) {
352
353
  #aiChatPanel {
353
354
  width: calc(100vw - 2rem);
354
- right: 1rem;
355
- bottom: 8rem;
355
+ right: var(--zer0-space-fab-offset, 1rem);
356
+ /* One gap above the toggle's slot (toggle is 3rem tall). */
357
+ bottom: calc(var(--zer0-space-fab-offset, 1rem) + var(--zer0-space-fab-size, 3.5rem) + var(--zer0-space-fab-gap, 0.75rem) + 3rem + var(--zer0-space-fab-gap, 0.75rem));
356
358
  max-height: 60vh;
357
359
  }
360
+ }
361
+
362
+ /* Below lg, pages with a sidebar/TOC render the mobile TOC FAB in this
363
+ same right-edge slot (offset + size + gap — see .bd-toc-fab in
364
+ _sass/layouts/_navbar-extras.scss). Step the chat toggle and panel one
365
+ slot higher there so the two buttons never overlap. */
366
+ @media (max-width: 991.98px) {
367
+ /* Cap the panel to the space between its anchored bottom (worst case:
368
+ the stepped-up slot below) and the fixed header — a 540px panel pokes
369
+ above short tablet/landscape viewports. */
370
+ #aiChatPanel {
371
+ max-height: min(60vh, calc(100vh
372
+ - var(--zer0-space-fab-offset, 1rem)
373
+ - 2 * (var(--zer0-space-fab-size, 3.5rem) + var(--zer0-space-fab-gap, 0.75rem))
374
+ - 3rem - var(--zer0-space-fab-gap, 0.75rem)
375
+ - 4rem));
376
+ }
377
+
378
+ body:has(#tocFab) #aiChatToggle {
379
+ bottom: calc(var(--zer0-space-fab-offset, 1rem) + 2 * (var(--zer0-space-fab-size, 3.5rem) + var(--zer0-space-fab-gap, 0.75rem)));
380
+ }
358
381
 
359
- #aiChatToggle {
360
- bottom: 4.5rem;
361
- right: 1rem;
382
+ body:has(#tocFab) #aiChatPanel {
383
+ bottom: calc(var(--zer0-space-fab-offset, 1rem) + 2 * (var(--zer0-space-fab-size, 3.5rem) + var(--zer0-space-fab-gap, 0.75rem)) + 3rem + var(--zer0-space-fab-gap, 0.75rem));
362
384
  }
363
385
  }
364
386
 
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-054 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  AUTHOR E-E-A-T BLOCK - Experience, Expertise, Authority, Trust
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-065 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  BACKGROUND CUSTOMIZER — fffuel-style background settings panel
@@ -1,17 +1,21 @@
1
+ {% comment %} Feature: ZER0-077 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  BACKGROUND SETTINGS — fffuel-style background controls (tab content)
4
5
  ===================================================================
5
-
6
+
6
7
  File: background-settings.html
7
8
  Path: _includes/components/background-settings.html
8
- Purpose: Background skin selector and opacity controls, rendered
9
- inside the Settings offcanvas Background tab.
10
-
9
+ Purpose: Theme-skin selector and SVG-background controls, rendered
10
+ inside the Settings offcanvas Appearance tab.
11
+
11
12
  Dependencies:
12
13
  - assets/js/background-customizer.js (zer0Bg API)
13
14
  - _sass/theme/_backgrounds.scss (CSS custom properties)
14
15
  - Bootstrap 5 form components
16
+
17
+ Section headings match the h6 pattern used by the parent
18
+ info-section.html so the Appearance tab reads as one surface.
15
19
  ===================================================================
16
20
  -->
17
21
 
@@ -21,9 +25,9 @@
21
25
  <!-- Skin selector -->
22
26
  <div class="mb-4">
23
27
  <h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
24
- <i class="bi bi-palette2 me-1"></i>Theme Skin
28
+ <i class="bi bi-palette2 me-1" aria-hidden="true"></i>Theme Skin
25
29
  </h6>
26
- <div class="d-flex flex-wrap gap-2" id="zer0SkinButtons">
30
+ <div class="d-flex flex-wrap gap-2" id="zer0SkinButtons" role="group" aria-label="Theme skin">
27
31
  {% for skin in skins %}
28
32
  <button class="btn btn-sm btn-outline-primary{% if skin == current_skin %} active{% endif %}"
29
33
  data-skin="{{ skin }}"
@@ -34,51 +38,48 @@
34
38
  </div>
35
39
  </div>
36
40
 
37
- <!-- Background toggle -->
41
+ <!-- SVG background toggle + layer opacity -->
38
42
  <div class="mb-4">
39
43
  <h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
40
- <i class="bi bi-image me-1"></i>SVG Backgrounds
44
+ <i class="bi bi-image me-1" aria-hidden="true"></i>Background
41
45
  </h6>
42
- <div class="d-flex align-items-center justify-content-between p-3 bg-body-tertiary rounded">
43
- <label class="form-check-label" for="zer0BgToggle">Enable SVG backgrounds</label>
46
+
47
+ <div class="d-flex align-items-center justify-content-between p-3 bg-body-tertiary rounded mb-3">
48
+ <label class="form-check-label" for="zer0BgToggle">SVG backgrounds</label>
44
49
  <div class="form-check form-switch mb-0">
45
50
  <input class="form-check-input" type="checkbox" id="zer0BgToggle" checked>
46
51
  </div>
47
52
  </div>
48
- </div>
49
-
50
- <!-- Opacity sliders -->
51
- <div class="mb-4">
52
- <h6 class="text-body-secondary small text-uppercase fw-semibold mb-2">
53
- <i class="bi bi-sliders2 me-1"></i>Layer Opacity
54
- </h6>
55
53
 
56
54
  <div class="mb-3">
57
- <label class="form-label small" for="zer0GradientOpacity">Gradient opacity</label>
55
+ <label class="form-label small d-flex justify-content-between mb-1" for="zer0GradientOpacity">
56
+ <span>Gradient opacity</span>
57
+ <span class="text-body-secondary" id="zer0GradientOpacityVal">0.6</span>
58
+ </label>
58
59
  <input type="range" class="form-range" id="zer0GradientOpacity"
59
60
  min="0" max="1" step="0.05" value="0.6">
60
- <small class="text-body-secondary"><span id="zer0GradientOpacityVal">0.6</span></small>
61
61
  </div>
62
62
 
63
63
  <div class="mb-3">
64
- <label class="form-label small" for="zer0TextureOpacity">Texture opacity</label>
64
+ <label class="form-label small d-flex justify-content-between mb-1" for="zer0TextureOpacity">
65
+ <span>Texture opacity</span>
66
+ <span class="text-body-secondary" id="zer0TextureOpacityVal">0.04</span>
67
+ </label>
65
68
  <input type="range" class="form-range" id="zer0TextureOpacity"
66
69
  min="0" max="0.2" step="0.005" value="0.04">
67
- <small class="text-body-secondary"><span id="zer0TextureOpacityVal">0.04</span></small>
68
70
  </div>
69
71
 
70
72
  <div class="mb-3">
71
- <label class="form-label small" for="zer0PatternOpacity">Pattern opacity</label>
73
+ <label class="form-label small d-flex justify-content-between mb-1" for="zer0PatternOpacity">
74
+ <span>Pattern opacity</span>
75
+ <span class="text-body-secondary" id="zer0PatternOpacityVal">0.08</span>
76
+ </label>
72
77
  <input type="range" class="form-range" id="zer0PatternOpacity"
73
78
  min="0" max="0.3" step="0.01" value="0.08">
74
- <small class="text-body-secondary"><span id="zer0PatternOpacityVal">0.08</span></small>
75
79
  </div>
76
- </div>
77
80
 
78
- <!-- Reset -->
79
- <div>
80
- <button class="btn btn-sm btn-outline-danger" id="zer0BgReset" type="button">
81
- <i class="bi bi-arrow-counterclockwise me-1"></i>Reset to defaults
81
+ <button class="btn btn-sm btn-outline-secondary" id="zer0BgReset" type="button">
82
+ <i class="bi bi-arrow-counterclockwise me-1" aria-hidden="true"></i>Reset background
82
83
  </button>
83
84
  </div>
84
85
 
@@ -119,15 +120,13 @@ document.addEventListener("DOMContentLoaded", function () {
119
120
  document.getElementById("zer0BgReset").addEventListener("click", function () {
120
121
  zer0Bg.setSkin("{{ current_skin }}");
121
122
  zer0Bg.toggle(true);
122
- zer0Bg.setOpacity("gradient", 0.6);
123
- zer0Bg.setOpacity("texture", 0.04);
124
- zer0Bg.setOpacity("pattern", 0.08);
125
- document.getElementById("zer0GradientOpacity").value = 0.6;
126
- document.getElementById("zer0TextureOpacity").value = 0.04;
127
- document.getElementById("zer0PatternOpacity").value = 0.08;
128
- document.getElementById("zer0GradientOpacityVal").textContent = "0.6";
129
- document.getElementById("zer0TextureOpacityVal").textContent = "0.04";
130
- document.getElementById("zer0PatternOpacityVal").textContent = "0.08";
123
+ var defaults = { zer0GradientOpacity: "0.6", zer0TextureOpacity: "0.04", zer0PatternOpacity: "0.08" };
124
+ var layers = { zer0GradientOpacity: "gradient", zer0TextureOpacity: "texture", zer0PatternOpacity: "pattern" };
125
+ Object.keys(defaults).forEach(function (id) {
126
+ zer0Bg.setOpacity(layers[id], defaults[id]);
127
+ document.getElementById(id).value = defaults[id];
128
+ document.getElementById(id + "Val").textContent = defaults[id];
129
+ });
131
130
  toggle.checked = true;
132
131
  document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) { b.classList.remove("active"); });
133
132
  var active = document.querySelector('#zer0SkinButtons [data-skin="{{ current_skin }}"]');
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-071 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  COMPONENT SHOWCASE - Live Bootstrap 5 demo gallery
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-007 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  COOKIE CONSENT - GDPR/CCPA Compliant Privacy Management
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-077 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  DEV SHORTCUTS - Source Code Quick Access Links
@@ -46,8 +47,6 @@
46
47
  target="_blank"
47
48
  rel="noopener"
48
49
  class="btn btn-outline-secondary btn-sm d-flex align-items-center justify-content-between"
49
- data-bs-toggle="tooltip"
50
- data-bs-placement="left"
51
50
  title="View source file on GitHub">
52
51
  <span>
53
52
  <i class="bi bi-github me-2"></i>
@@ -61,8 +60,6 @@
61
60
  target="_blank"
62
61
  rel="noopener"
63
62
  class="btn btn-outline-secondary btn-sm d-flex align-items-center justify-content-between"
64
- data-bs-toggle="tooltip"
65
- data-bs-placement="left"
66
63
  title="Open in browser-based VS Code editor">
67
64
  <span>
68
65
  <i class="bi bi-cloud me-2"></i>
@@ -76,8 +73,6 @@
76
73
  {% if git_home != "" %}
77
74
  <a href="vscode://file{{ vscode_full_path }}"
78
75
  class="btn btn-outline-secondary btn-sm d-flex align-items-center justify-content-between"
79
- data-bs-toggle="tooltip"
80
- data-bs-placement="left"
81
76
  title="Open in local VS Code (requires local clone at this path)">
82
77
  <span>
83
78
  <i class="bi bi-code-square me-2"></i>
@@ -102,8 +97,6 @@
102
97
  target="_blank"
103
98
  rel="noopener"
104
99
  class="btn btn-outline-secondary btn-sm d-flex align-items-center justify-content-between"
105
- data-bs-toggle="tooltip"
106
- data-bs-placement="left"
107
100
  title="View Jekyll site configuration">
108
101
  <span>
109
102
  <i class="bi bi-gear me-2"></i>