jekyll-theme-zer0 1.23.0 → 1.25.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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +110 -0
  3. data/README.md +3 -3
  4. data/_data/authors.yml +1 -0
  5. data/_data/features.yml +882 -34
  6. data/_data/navigation/README.md +15 -5
  7. data/_data/navigation/main.yml +0 -8
  8. data/_data/roadmap.yml +1 -0
  9. data/_includes/README.md +10 -7
  10. data/_includes/analytics/google-analytics.html +1 -0
  11. data/_includes/analytics/google-tag-manager-body.html +1 -0
  12. data/_includes/analytics/google-tag-manager-head.html +1 -0
  13. data/_includes/analytics/posthog.html +1 -0
  14. data/_includes/components/README.md +2 -1
  15. data/_includes/components/admin-links.html +63 -0
  16. data/_includes/components/admin-tabs.html +1 -0
  17. data/_includes/components/ai-chat.html +27 -5
  18. data/_includes/components/author-eeat.html +1 -0
  19. data/_includes/components/background-customizer.html +1 -0
  20. data/_includes/components/background-settings.html +36 -37
  21. data/_includes/components/component-showcase.html +1 -0
  22. data/_includes/components/cookie-consent.html +1 -0
  23. data/_includes/components/dev-shortcuts.html +1 -8
  24. data/_includes/components/env-switcher.html +90 -138
  25. data/_includes/components/feature-card.html +16 -1
  26. data/_includes/components/halfmoon.html +22 -41
  27. data/_includes/components/info-section.html +127 -130
  28. data/_includes/components/mermaid.html +1 -0
  29. data/_includes/components/nanobar.html +1 -0
  30. data/_includes/components/post-type-badge.html +1 -0
  31. data/_includes/components/preview-image.html +1 -0
  32. data/_includes/components/search-modal.html +1 -0
  33. data/_includes/components/searchbar.html +1 -0
  34. data/_includes/components/shortcuts-modal.html +1 -0
  35. data/_includes/components/theme-info.html +21 -30
  36. data/_includes/components/theme-preview-gallery.html +1 -0
  37. data/_includes/components/zer0-env-var.html +7 -1
  38. data/_includes/content/backlinks.html +1 -0
  39. data/_includes/content/giscus.html +1 -0
  40. data/_includes/content/jsonld-faq.html +1 -0
  41. data/_includes/content/seo.html +1 -0
  42. data/_includes/content/sitemap.html +1 -0
  43. data/_includes/content/toc.html +1 -0
  44. data/_includes/core/color-mode-init.html +1 -0
  45. data/_includes/core/footer.html +1 -0
  46. data/_includes/core/head.html +1 -0
  47. data/_includes/core/header.html +5 -15
  48. data/_includes/navigation/admin-nav.html +1 -0
  49. data/_includes/navigation/breadcrumbs.html +1 -0
  50. data/_includes/navigation/local-graph-fab.html +3 -9
  51. data/_includes/navigation/local-graph.html +4 -9
  52. data/_includes/navigation/navbar.html +1 -0
  53. data/_includes/navigation/sidebar-categories.html +56 -14
  54. data/_includes/navigation/sidebar-config.html +115 -0
  55. data/_includes/navigation/sidebar-folders.html +168 -62
  56. data/_includes/navigation/sidebar-left.html +29 -52
  57. data/_includes/navigation/sidebar-nav.html +30 -0
  58. data/_includes/navigation/sidebar-right.html +1 -0
  59. data/_includes/navigation/toc-fab.html +3 -9
  60. data/_includes/navigation/unified-drawer.html +7 -14
  61. data/_includes/obsidian/full-graph.html +1 -0
  62. data/_includes/setup/wizard.html +1 -0
  63. data/_includes/stats/stats-categories.html +1 -0
  64. data/_includes/stats/stats-header.html +1 -0
  65. data/_includes/stats/stats-metrics.html +1 -0
  66. data/_includes/stats/stats-overview.html +1 -0
  67. data/_includes/stats/stats-tags.html +1 -0
  68. data/_layouts/admin.html +1 -0
  69. data/_layouts/article.html +1 -0
  70. data/_layouts/author.html +1 -0
  71. data/_layouts/authors.html +1 -0
  72. data/_layouts/collection.html +1 -0
  73. data/_layouts/default.html +14 -37
  74. data/_layouts/home.html +1 -0
  75. data/_layouts/index.html +1 -0
  76. data/_layouts/landing.html +1 -0
  77. data/_layouts/news.html +1 -0
  78. data/_layouts/note.html +1 -0
  79. data/_layouts/notebook.html +1 -0
  80. data/_layouts/root.html +3 -2
  81. data/_layouts/search.html +1 -0
  82. data/_layouts/section.html +1 -0
  83. data/_layouts/setup.html +1 -0
  84. data/_layouts/sitemap-collection.html +1 -0
  85. data/_layouts/stats.html +1 -0
  86. data/_layouts/tag.html +1 -0
  87. data/_layouts/welcome.html +1 -0
  88. data/_plugins/author_pages_generator.rb +1 -0
  89. data/_plugins/obsidian_links.rb +1 -0
  90. data/_plugins/preview_image_generator.rb +1 -0
  91. data/_plugins/search_and_sitemap_generator.rb +1 -0
  92. data/_plugins/theme_version.rb +1 -0
  93. data/_sass/components/_author.scss +12 -1
  94. data/_sass/components/_footer.scss +22 -0
  95. data/_sass/components/_ui-enhancements.scss +9 -0
  96. data/_sass/core/_docs-layout.scss +1 -0
  97. data/_sass/core/_navbar.scss +10 -27
  98. data/_sass/core/_obsidian.scss +2 -2
  99. data/_sass/core/code-copy.scss +10 -0
  100. data/_sass/custom.scss +1 -0
  101. data/_sass/notebooks.scss +1 -0
  102. data/_sass/theme/_backgrounds.scss +7 -2
  103. data/_sass/utilities/_layout.scss +11 -0
  104. data/assets/css/main.scss +2 -1
  105. data/assets/js/ai-chat.js +1 -0
  106. data/assets/js/author-profile.js +1 -0
  107. data/assets/js/auto-hide-nav.js +1 -0
  108. data/assets/js/back-to-top.js +1 -0
  109. data/assets/js/background-customizer.js +1 -0
  110. data/assets/js/code-copy.js +1 -0
  111. data/assets/js/halfmoon.js +23 -22
  112. data/assets/js/modules/navigation/gestures.js +1 -0
  113. data/assets/js/modules/navigation/keyboard.js +1 -0
  114. data/assets/js/modules/navigation/scroll-spy.js +1 -0
  115. data/assets/js/modules/navigation/sidebar-state.js +1 -0
  116. data/assets/js/modules/navigation/sidebar-visibility.js +1 -0
  117. data/assets/js/modules/navigation/smooth-scroll.js +1 -0
  118. data/assets/js/modules/theme/appearance.js +52 -16
  119. data/assets/js/nanobar-init.js +1 -0
  120. data/assets/js/navigation.js +1 -0
  121. data/assets/js/obsidian-graph.js +1 -0
  122. data/assets/js/obsidian-wiki-links.js +1 -0
  123. data/assets/js/palette-generator.js +1 -0
  124. data/assets/js/particles-source.js +1 -0
  125. data/assets/js/search-modal.js +1 -0
  126. data/assets/js/setup-wizard.js +1 -0
  127. data/assets/js/share-actions.js +1 -0
  128. data/assets/js/skin-editor.js +1 -0
  129. data/assets/js/table-copy.js +1 -0
  130. data/assets/js/theme-customizer.js +1 -0
  131. data/scripts/analyze-commits.sh +1 -0
  132. data/scripts/bin/giscus-discussions +1 -0
  133. data/scripts/bin/install +1 -0
  134. data/scripts/bin/validate +18 -1
  135. data/scripts/build +1 -0
  136. data/scripts/content-review.rb +1 -0
  137. data/scripts/convert-notebooks.sh +4 -3
  138. data/scripts/fix-markdown-format.sh +1 -0
  139. data/scripts/generate-preview-images.sh +1 -0
  140. data/scripts/generate-roadmap.sh +1 -0
  141. data/scripts/install-preview-generator.sh +1 -0
  142. data/scripts/release +1 -0
  143. data/scripts/requirements.txt +11 -0
  144. data/scripts/setup.sh +1 -0
  145. data/scripts/tag-features +136 -0
  146. data/scripts/validate-features.rb +149 -0
  147. data/scripts/vendor-install.sh +1 -0
  148. metadata +9 -3
  149. data/_plugins/admin_page_urls.rb +0 -16
@@ -0,0 +1,30 @@
1
+ {%- comment -%}
2
+ Component: sidebar-nav
3
+ Path: _includes/navigation/sidebar-nav.html
4
+ Purpose: Render the resolved sidebar navigation content for the current
5
+ page. Expects navigation/sidebar-config.html to have been
6
+ included first in the same render context (it sets
7
+ `sidebar_nav`). Shared by navigation/sidebar-left.html and
8
+ navigation/unified-drawer.html so desktop sidebar and mobile
9
+ drawer can never drift apart.
10
+ Params: id (string, optional) — id attribute for the content wrapper
11
+ Depends on: navigation/sidebar-config.html (resolver),
12
+ navigation/sidebar-folders.html ("collection" mode),
13
+ navigation/sidebar-categories.html ("categories"/"tags" modes),
14
+ navigation/nav-tree.html (curated _data/navigation/*.yml modes)
15
+ Notes: Renders nothing when sidebar_nav is nil or its data is empty —
16
+ callers gate the surrounding column on `sidebar_has_content`.
17
+ {%- endcomment -%}
18
+ {%- if sidebar_nav == "collection" -%}
19
+ <div class="nav-tree"{% if include.id %} id="{{ include.id }}"{% endif %} data-nav-tree>
20
+ {% include navigation/sidebar-folders.html %}
21
+ </div>
22
+ {%- elsif sidebar_nav == "categories" or sidebar_nav == "tags" -%}
23
+ <div class="nav-tree nav-tree--categories"{% if include.id %} id="{{ include.id }}"{% endif %} data-nav-tree>
24
+ {% include navigation/sidebar-categories.html taxonomy=sidebar_nav %}
25
+ </div>
26
+ {%- elsif sidebar_nav -%}
27
+ <nav class="w-100 nav-tree"{% if include.id %} id="{{ include.id }}"{% endif %} data-nav-tree aria-label="Section navigation">
28
+ {% include navigation/nav-tree.html nav=sidebar_nav %}
29
+ </nav>
30
+ {%- endif -%}
@@ -1,3 +1,4 @@
1
+ {% comment %} Features: ZER0-008, ZER0-010 {% endcomment %}
1
2
  <!--
2
3
  file: sidebar-right.html
3
4
  path: _includes/sidebar-right.html
@@ -3,15 +3,9 @@
3
3
  footer stacking context with back-to-top and does not cover the powered-by
4
4
  row when the user scrolls to the page bottom.
5
5
  {%- endcomment -%}
6
- {%- assign _effective_sidebar = page.sidebar -%}
7
- {%- if _effective_sidebar == nil -%}
8
- {%- if page.post_type == "featured" or page.post_type == "breaking" -%}
9
- {%- assign _effective_sidebar = false -%}
10
- {%- else -%}
11
- {%- assign _effective_sidebar = true -%}
12
- {%- endif -%}
13
- {%- endif -%}
14
- {%- if _effective_sidebar != false -%}
6
+ {%- comment -%} Shared visibility resolver — sets sidebar_enabled {%- endcomment -%}
7
+ {%- include navigation/sidebar-config.html -%}
8
+ {%- if sidebar_enabled -%}
15
9
  <div class="position-fixed bd-toc-fab d-lg-none" id="tocFab">
16
10
  <button class="btn btn-primary rounded-circle shadow-lg p-0 bd-toc-toggle"
17
11
  type="button"
@@ -60,20 +60,13 @@
60
60
  <div class="offcanvas-body tab-content overflow-auto">
61
61
  <div class="tab-pane fade show active" id="zer0-drawer-pane-browse"
62
62
  role="tabpanel" aria-labelledby="zer0-drawer-tab-browse">
63
- {%- if page.sidebar.nav == "auto" -%}
64
- <div class="list-group nav-tree">
65
- {% assign folders = site.pages | where_exp: "item", "item.path contains 'index.md'" | sort: 'path' %}
66
- {% include navigation/sidebar-folders.html folders=folders %}
67
- </div>
68
- {%- elsif page.sidebar.nav == "categories" -%}
69
- <div class="nav-tree nav-tree--categories">
70
- {% assign categories = site.categories | sort %}
71
- {% include navigation/sidebar-categories.html categories=categories %}
72
- </div>
73
- {%- elsif page.sidebar.nav -%}
74
- <nav aria-label="Section navigation">
75
- {% include navigation/nav-tree.html nav=page.sidebar.nav %}
76
- </nav>
63
+ {%- comment -%}
64
+ Same resolver + renderer as sidebar-left.html so the drawer's Browse
65
+ tab can never drift from the desktop sidebar.
66
+ {%- endcomment -%}
67
+ {% include navigation/sidebar-config.html %}
68
+ {%- if sidebar_has_content -%}
69
+ {% include navigation/sidebar-nav.html %}
77
70
  {%- else -%}
78
71
  <p class="text-body-secondary small mb-0">No sidebar configured for this page.</p>
79
72
  {%- endif -%}
@@ -1,3 +1,4 @@
1
+ {% comment %} Features: ZER0-044, ZER0-045 {% endcomment %}
1
2
  <style>
2
3
  /* Scoped to the graph page so we don't leak into other docs. */
3
4
  #obsidian-graph {
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-067 {% endcomment %}
1
2
  <!--
2
3
  ===================================================================
3
4
  SETUP WIZARD — Interactive _config.yml Generator
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-043 {% endcomment %}
1
2
  <!-- ================================================ -->
2
3
  <!-- CATEGORIES ANALYSIS SECTION -->
3
4
  <!-- Top categories with post counts -->
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-043 {% endcomment %}
1
2
  <!-- ================================================ -->
2
3
  <!-- STATS PAGE HEADER -->
3
4
  <!-- Title, description, and metadata display -->
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-043 {% endcomment %}
1
2
  <div id="metrics" class="row mb-5">
2
3
  <div class="col-12">
3
4
  <div class="card shadow-sm">
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-043 {% endcomment %}
1
2
  <div id="overview" class="mb-5">
2
3
  <!-- Section Header -->
3
4
  <div class="text-center mb-4">
@@ -1,3 +1,4 @@
1
+ {% comment %} Feature: ZER0-043 {% endcomment %}
1
2
  <!-- ================================================ -->
2
3
  <!-- TAGS ANALYSIS SECTION -->
3
4
  <!-- Top tags with usage counts -->
data/_layouts/admin.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-050
2
3
  layout: root
3
4
  ---
4
5
  <!--
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-035, ZER0-064
2
3
  layout: default
3
4
  ---
4
5
  <!--
data/_layouts/author.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-061
2
3
  layout: default
3
4
  hide_intro: true
4
5
  ---
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-061
2
3
  layout: default
3
4
  ---
4
5
  <!--
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Feature: ZER0-019
2
3
  layout: default
3
4
  ---
4
5
  <!--
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-001, ZER0-008, ZER0-019
2
3
  layout: root
3
4
  ---
4
5
  <!--
@@ -45,53 +46,29 @@ layout: root
45
46
  -->
46
47
 
47
48
  {%- comment -%}
48
- Resolve effective sidebar visibility. Precedence:
49
- 1. page.sidebar in front matter wins (true | false | hash)
50
- 2. Otherwise, post_type=featured|breaking → false (full-bleed reading)
51
- 3. Otherwise, default to true
52
- This is the single source of truth so child layouts (article.html, note.html)
53
- do not need to mutate page state.
49
+ Sidebar visibility + nav mode are resolved by the shared include below
50
+ (single source of truth, also used by core/header.html and the sidebar
51
+ includes). It sets:
52
+ sidebar_enabled — false when the page opts out (`sidebar: false`,
53
+ or featured/breaking post_type by default)
54
+ sidebar_has_content true only when the resolved nav mode will render;
55
+ `sidebar: true` without a resolvable nav still
56
+ enables the right TOC but must not reserve an
57
+ empty left column.
54
58
  {%- endcomment -%}
55
- {%- assign _effective_sidebar = page.sidebar -%}
56
- {%- if _effective_sidebar == nil -%}
57
- {%- if page.post_type == "featured" or page.post_type == "breaking" -%}
58
- {%- assign _effective_sidebar = false -%}
59
- {%- else -%}
60
- {%- assign _effective_sidebar = true -%}
61
- {%- endif -%}
62
- {%- endif -%}
63
-
64
- {%- comment -%}
65
- Left sidebar column is only useful when sidebar-left.html has nav to render
66
- (matches header.html mobile toggle logic). `sidebar: true` without `nav`
67
- still enables the right TOC but must not reserve an empty left column.
68
- {%- endcomment -%}
69
- {%- assign _sidebar_has_content = false -%}
70
- {%- if _effective_sidebar != false -%}
71
- {%- assign _sidebar_nav = nil -%}
72
- {%- if page.sidebar and page.sidebar.nav -%}
73
- {%- assign _sidebar_nav = page.sidebar.nav -%}
74
- {%- endif -%}
75
- {%- if _sidebar_nav -%}
76
- {%- if _sidebar_nav == "auto" or _sidebar_nav == "categories" -%}
77
- {%- assign _sidebar_has_content = true -%}
78
- {%- elsif site.data.navigation[_sidebar_nav] -%}
79
- {%- assign _sidebar_has_content = true -%}
80
- {%- endif -%}
81
- {%- endif -%}
82
- {%- endif -%}
59
+ {% include navigation/sidebar-config.html %}
83
60
 
84
61
  <!-- ================================================ -->
85
62
  <!-- MAIN LAYOUT CONTAINER -->
86
63
  <!-- Bootstrap responsive container with custom grid -->
87
64
  <!-- ================================================ -->
88
- <div class="container-xxl bd-gutter mt-3 my-md-4 bd-layout{% unless _sidebar_has_content %} bd-layout--no-sidebar{% endunless %}">
65
+ <div class="container-xxl bd-gutter mt-3 my-md-4 bd-layout{% unless sidebar_has_content %} bd-layout--no-sidebar{% endunless %}">
89
66
 
90
67
  <!-- ================================ -->
91
68
  <!-- LEFT SIDEBAR - Navigation -->
92
69
  <!-- ================================ -->
93
70
  <!-- Site navigation, content outline, and offcanvas menu for mobile -->
94
- {% if _sidebar_has_content %}
71
+ {% if sidebar_has_content %}
95
72
  <aside class="bd-sidebar">
96
73
  {% include navigation/sidebar-left.html %}
97
74
  </aside>
@@ -130,7 +107,7 @@ layout: root
130
107
  <!-- RIGHT SIDEBAR - Table of Contents -->
131
108
  <!-- =============================== -->
132
109
  <!-- Page outline, shortcuts, and related links (hidden on mobile) -->
133
- {% unless _effective_sidebar == false %}
110
+ {% unless sidebar_enabled == false %}
134
111
  <div class="bd-toc text-body-secondary">
135
112
  {% include navigation/sidebar-right.html %}
136
113
  </div>
data/_layouts/home.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Feature: ZER0-019
2
3
  layout: root
3
4
  ---
4
5
  <!--
data/_layouts/index.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Feature: ZER0-019
2
3
  layout: root
3
4
  ---
4
5
  <!--
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Feature: ZER0-019
2
3
  layout: root
3
4
  ---
4
5
  <!--
data/_layouts/news.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-062
2
3
  layout: root
3
4
  source: "https://getbootstrap.com/docs/5.3/examples/blog/#"
4
5
  ---
data/_layouts/note.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-035, ZER0-058
2
3
  layout: default
3
4
  ---
4
5
  {% assign page_absolute_url = page.url | absolute_url %}
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-012, ZER0-019, ZER0-035
2
3
  layout: default
3
4
  ---
4
5
  <!--
data/_layouts/root.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-001, ZER0-019, ZER0-031, ZER0-060
2
3
  ---
3
4
  <!--
4
5
  ===================================================================
@@ -20,7 +21,7 @@
20
21
  - head.html: Meta tags, stylesheets, and external resources
21
22
  - svg.html: Inline SVG symbols for icons
22
23
  - header.html: Main navigation and site branding
23
- - info-section.html: Site-wide announcements or notices
24
+ - info-section.html: Settings offcanvas (Appearance / Site / Developer)
24
25
  - footer.html: Site footer with links and copyright
25
26
  - js-cdn.html: JavaScript dependencies and custom scripts
26
27
 
@@ -87,7 +88,7 @@
87
88
  <!-- Keyboard shortcuts help modal (triggered by `?`) — page-invariant. -->
88
89
  {% include_cached components/shortcuts-modal.html %}
89
90
 
90
- <!-- Site-wide information banner or announcement section -->
91
+ <!-- Settings offcanvas (Appearance / Site / Developer tabs) -->
91
92
  {% include components/info-section.html %}
92
93
 
93
94
  <!-- Setup banner for unconfigured sites — page-invariant. -->
data/_layouts/search.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-042
2
3
  # Bare layout that renders the client-side search index as pure JSON.
3
4
  # Used by /search.json (see search.json in the site root); downstream
4
5
  # sites get the endpoint automatically via the theme gem.
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-063
2
3
  layout: root
3
4
  ---
4
5
  <!--
data/_layouts/setup.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-067
2
3
  layout: root
3
4
  ---
4
5
  <!--
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-042
2
3
  layout: root
3
4
  ---
4
5
  <!--
data/_layouts/stats.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-043
2
3
  layout: root
3
4
  ---
4
5
  <!--
data/_layouts/tag.html CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Feature: ZER0-019
2
3
  layout: default
3
4
  ---
4
5
  <!--
@@ -1,4 +1,5 @@
1
1
  ---
2
+ # Features: ZER0-019, ZER0-046
2
3
  layout: root
3
4
  ---
4
5
  <!--
@@ -1,3 +1,4 @@
1
+ # Feature: ZER0-061
1
2
  # frozen_string_literal: true
2
3
 
3
4
  #
@@ -1,3 +1,4 @@
1
+ # Features: ZER0-044, ZER0-059
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'digest'
@@ -1,3 +1,4 @@
1
+ # Feature: ZER0-004
1
2
  # frozen_string_literal: true
2
3
 
3
4
  #
@@ -1,3 +1,4 @@
1
+ # Feature: ZER0-042
1
2
  # frozen_string_literal: true
2
3
 
3
4
  #
@@ -1,3 +1,4 @@
1
+ # Feature: ZER0-021
1
2
  # frozen_string_literal: true
2
3
 
3
4
  #
@@ -46,9 +46,20 @@
46
46
  }
47
47
  }
48
48
 
49
- // Expertise chips
49
+ // "About the Author" card: the text column sits in a flex row next to the
50
+ // avatar. Flexbox's default `min-width: auto` propagates the widest nowrap
51
+ // child (a long expertise badge) as the column's minimum, blowing the card —
52
+ // and with it the whole page — past the viewport on small phones (≤340px).
53
+ .author-card .card-body .flex-grow-1 {
54
+ min-width: 0;
55
+ }
56
+
57
+ // Expertise chips — allow the label to wrap instead of forcing the card wide
58
+ // (Bootstrap badges are white-space: nowrap by default).
50
59
  .author-expertise .badge {
51
60
  font-weight: 500;
61
+ white-space: normal;
62
+ text-align: start;
52
63
  }
53
64
 
54
65
  // Shared tagline styling (full "About the Author" card + profile hero)
@@ -127,6 +127,28 @@
127
127
  }
128
128
  }
129
129
 
130
+ // WCAG 2.5.8 target size: the dark block's text links render ~19px tall and
131
+ // the icon-only social links (below md) ~16px wide — under the 24px minimum.
132
+ // Block padding grows the tap target without changing the visual text size;
133
+ // icon links get an explicit minimum box. (`d-block` links — e.g. the
134
+ // truncated Latest Posts titles — keep their display but gain the padding.)
135
+ .footer-dark-block {
136
+ ul.list-unstyled li > a,
137
+ p > a {
138
+ display: inline-block;
139
+ padding-block: 0.25rem;
140
+ }
141
+
142
+ ul.list-inline li > a {
143
+ display: inline-flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ gap: 0.25rem;
147
+ min-width: 1.75rem;
148
+ min-height: 1.75rem;
149
+ }
150
+ }
151
+
130
152
  .footer-post-link {
131
153
  max-width: 100%;
132
154
  }
@@ -26,6 +26,15 @@ img {
26
26
  // UI/UX ENHANCEMENTS - Modern, polished interactions
27
27
  // ==============================================================================
28
28
 
29
+ // WCAG 2.5.8 target size: breadcrumb links render as bare ~19px text lines.
30
+ // Block padding + matching negative margin grows the tap box past 24px
31
+ // without shifting the visual baseline or the bar's height.
32
+ .breadcrumbs .breadcrumb-item > a {
33
+ display: inline-block;
34
+ padding-block: 0.25rem;
35
+ margin-block: -0.25rem;
36
+ }
37
+
29
38
  // Hero Section Enhancements
30
39
  // NOTE: Exclude .zer0-bg-hero so skin-specific gradients from _backgrounds.scss take precedence
31
40
  .bg-primary:not(.zer0-bg-hero) {
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-008
1
2
  /*!
2
3
  * Docs layout — trimmed Bootstrap-docs-adjacent styles for zer0-mistakes.
3
4
  * Replaces the former full _docs.scss vendor snapshot (~3.2k lines).
@@ -804,33 +804,16 @@
804
804
  padding-top: 1rem;
805
805
  }
806
806
 
807
- // Theme switcher (halfmoon): keep dropdown positioned within offcanvas panel
808
- .bd-theme-dropdown {
809
- position: relative;
810
- }
811
-
812
- .bd-theme-menu.dropdown-menu {
813
- --bs-dropdown-min-width: 10.5rem;
814
- z-index: 1060;
815
- padding-top: 0.35rem;
816
- padding-bottom: 0.35rem;
817
- border-radius: var(--bs-border-radius, 0.375rem);
818
- border: 1px solid var(--bs-border-color-translucent);
819
- }
820
-
821
- .bd-theme-menu .dropdown-item {
822
- min-height: 0;
823
- padding: 0.45rem 0.85rem;
824
- font-size: 0.9375rem;
825
- border-radius: calc(var(--bs-border-radius, 0.375rem) - 2px);
826
- gap: 0.35rem;
827
-
828
- &.active {
829
- font-weight: 600;
830
- }
831
-
832
- .bi.ms-auto {
833
- opacity: 0.9;
807
+ // Compact tabs on narrow panels: keep the text labels (they are the
808
+ // accessible names) and drop the decorative icons instead.
809
+ @media (max-width: 575.98px) {
810
+ .nav-tabs .nav-link {
811
+ padding: 0.6rem 0.25rem;
812
+ font-size: 0.8125rem;
813
+
814
+ .bi {
815
+ display: none;
816
+ }
834
817
  }
835
818
  }
836
819
  }
@@ -204,8 +204,8 @@
204
204
  // ----------------------------------------------------------------------------
205
205
  // ID selector (not the class) is REQUIRED for the fixed position to stick:
206
206
  // the FAB is a direct child of `.zer0-bg-body`, which matches the elevation
207
- // rule `.zer0-bg-body > *:not(.fixed-top):not(.offcanvas):not(.modal)` in
208
- // _sass/theme/_backgrounds.scss (specificity 0,4,0) and forces
207
+ // rule `.zer0-bg-body > *:not(.fixed-top):not(.position-fixed):not(.offcanvas):not(.modal)`
208
+ // in _sass/theme/_backgrounds.scss (specificity 0,5,0) and forces
209
209
  // `position: relative; z-index: 1` — dropping the FAB into page flow at the
210
210
  // bottom. An id (1,0,0) wins, mirroring `#aiChatToggle`. See ai-chat.html.
211
211
  #obsidianLocalGraphFab.obsidian-local-graph-fab {
@@ -197,6 +197,12 @@
197
197
 
198
198
  // Copy button — shared base
199
199
  .copy {
200
+ display: inline-flex;
201
+ align-items: center;
202
+ justify-content: center;
203
+ // WCAG 2.5.8 target size: text metrics alone yield a ~22px-tall button;
204
+ // guarantee the 24px minimum, and a comfortable 32px on touch screens.
205
+ min-height: 1.5rem;
200
206
  flex-shrink: 0;
201
207
  color: var(--bs-light);
202
208
  opacity: 0.75;
@@ -229,6 +235,10 @@
229
235
  border-color: transparent;
230
236
  opacity: 1;
231
237
  }
238
+
239
+ @media (pointer: coarse) {
240
+ min-height: 2rem;
241
+ }
232
242
  }
233
243
 
234
244
  // Header-mounted copy button (Rouge blocks) — never overlaps code
data/_sass/custom.scss CHANGED
@@ -1,3 +1,4 @@
1
+ // Features: ZER0-001, ZER0-008, ZER0-010, ZER0-011
1
2
  // ==============================================================================
2
3
  // CUSTOM STYLES barrel — Zer0-Mistakes "custom layer"
3
4
  // ==============================================================================
data/_sass/notebooks.scss CHANGED
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-012
1
2
  // ==============================================================================
2
3
  // NOTEBOOK STYLES - Jupyter Notebook Display Styling
3
4
  // ==============================================================================
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-065
1
2
  // ==========================================================================
2
3
  // Backgrounds — fffuel-style SVG background system for zer0-mistakes theme
3
4
  // ==========================================================================
@@ -108,8 +109,12 @@
108
109
 
109
110
  // Elevate children above the ::before / ::after pseudo-element backgrounds,
110
111
  // but exclude fixed-position, offcanvas, and modal elements whose
111
- // positioning must not be overridden.
112
- > *:not(.fixed-top):not(.offcanvas):not(.modal) { position: relative; z-index: 1; }
112
+ // positioning must not be overridden. `.position-fixed` matters as much as
113
+ // `.fixed-top`: without it this rule (specificity 0,4,0) flattens the
114
+ // cookie-consent banner and the TOC FAB to z-index 1, letting the chat and
115
+ // local-graph FABs paint over — and steal taps from — the banner's buttons
116
+ // on mobile (their `--zer0-layer-*` tokens exist precisely to prevent this).
117
+ > *:not(.fixed-top):not(.position-fixed):not(.offcanvas):not(.modal) { position: relative; z-index: 1; }
113
118
  }
114
119
 
115
120
  .zer0-bg-surface {
@@ -0,0 +1,11 @@
1
+ // Feature: ZER0-077
2
+ // =============================================================================
3
+ // Layout utilities — small structural helpers Bootstrap does not ship
4
+ // =============================================================================
5
+
6
+ // Allow a flex child to shrink below its content size so text-truncate can
7
+ // work (flex items default to min-width: auto). Used by the navbar leading
8
+ // cluster, branding, and the settings panel quick-link rows.
9
+ .min-w-0 {
10
+ min-width: 0 !important;
11
+ }
data/assets/css/main.scss CHANGED
@@ -22,9 +22,10 @@
22
22
  // it so the concatenated cascade order is unchanged.
23
23
  @import "core/docs-code-examples";
24
24
 
25
- // 4. Reusable utilities (motion, focus rings) — used by components below
25
+ // 4. Reusable utilities (motion, focus rings, layout helpers) — used by components below
26
26
  @import "utilities/motion";
27
27
  @import "utilities/focus";
28
+ @import "utilities/layout";
28
29
 
29
30
  // 5. Component partials (formerly inside custom.scss + new primitives)
30
31
  @import "components/cookie-banner";
data/assets/js/ai-chat.js CHANGED
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-060
1
2
  /**
2
3
  * ===================================================================
3
4
  * AI Chat Widget — Claude Messages API client with GitHub tool use
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-061
1
2
  /*
2
3
  * author-profile.js
3
4
  * ---------------------------------------------------------------------------
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-033
1
2
  /**
2
3
  * Auto-hide navbar on scroll with enhanced UX
3
4
  *
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-029
1
2
  document.addEventListener('DOMContentLoaded', () => {
2
3
  const btn = document.getElementById('backToTopBtn');
3
4
  if (!btn) return;
@@ -1,3 +1,4 @@
1
+ // Feature: ZER0-065
1
2
  /**
2
3
  * background-customizer.js
3
4
  * Runtime switching of theme skin and fffuel-style SVG backgrounds.