jekyll-theme-zer0 1.28.0 → 1.30.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 +1143 -13
- data/_data/README.md +2 -0
- data/_data/ai.yml +5 -3
- data/_data/ai_pricing.yml +36 -0
- data/_data/backlog.yml +507 -2
- data/_data/consumers.yml +157 -9
- data/_data/features.yml +303 -20
- data/_data/feedback_types.yml +17 -12
- data/_data/i18n/fr.yml +12 -7
- data/_data/i18n/manifest.yml +39 -12
- data/_data/ingredient_densities.yml +122 -0
- data/_data/landing.yml +5 -2
- data/_data/navigation/main.yml +16 -0
- data/_data/navigation/quickstart.yml +4 -0
- data/_data/recipe_courses.yml +64 -0
- data/_data/site_builder.yml +874 -0
- data/_data/theme-manifest.yml +160 -124
- data/_data/ui-text.yml +26 -0
- data/_includes/README.md +26 -2
- data/_includes/analytics/posthog.html +2 -2
- data/_includes/components/admin-links.html +2 -2
- data/_includes/components/admin-tabs.html +2 -2
- data/_includes/components/ai-chat.html +14 -11
- data/_includes/components/analytics-dashboard.html +8 -8
- data/_includes/components/author-bio.html +1 -1
- data/_includes/components/author-card.html +10 -2
- data/_includes/components/author-eeat.html +4 -4
- data/_includes/components/background-customizer.html +10 -10
- data/_includes/components/background-image.html +114 -0
- data/_includes/components/background-settings.html +28 -15
- data/_includes/components/collection-manager.html +5 -5
- data/_includes/components/component-showcase.html +13 -13
- data/_includes/components/config-editor.html +12 -12
- data/_includes/components/config-viewer.html +8 -8
- data/_includes/components/cookie-consent.html +15 -15
- data/_includes/components/cta-button.html +7 -2
- data/_includes/components/dev-shortcuts.html +7 -7
- data/_includes/components/env-dashboard.html +8 -8
- data/_includes/components/env-switcher.html +9 -9
- data/_includes/components/feature-card.html +2 -2
- data/_includes/components/halfmoon.html +2 -2
- data/_includes/components/info-section.html +42 -37
- data/_includes/components/js-cdn.html +15 -15
- data/_includes/components/language-toggle.html +168 -21
- data/_includes/components/mermaid.html +72 -435
- data/_includes/components/nanobar.html +5 -5
- data/_includes/components/nav-editor.html +2 -2
- data/_includes/components/nav-export.html +2 -2
- data/_includes/components/nav-overview.html +2 -2
- data/_includes/components/page-feedback.html +45 -30
- data/_includes/components/page-views-init.html +55 -0
- data/_includes/components/page-views.html +33 -0
- data/_includes/components/post-card.html +22 -22
- data/_includes/components/post-type-badge.html +2 -2
- data/_includes/components/powered-by.html +2 -2
- data/_includes/components/preview-image.html +6 -0
- data/_includes/components/quick-index.html +2 -2
- 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 +29 -4
- data/_includes/components/searchbar.html +2 -2
- data/_includes/components/shortcuts-modal.html +3 -0
- data/_includes/components/svg-background.html +2 -2
- data/_includes/components/theme-customizer.html +2 -2
- data/_includes/components/theme-info.html +14 -7
- data/_includes/components/theme-preview-gallery.html +22 -22
- data/_includes/content/giscus.html +2 -2
- data/_includes/content/intro.html +8 -8
- data/_includes/content/jsonld-faq.html +2 -2
- data/_includes/content/jsonld-software.html +24 -5
- data/_includes/content/seo.html +4 -4
- data/_includes/content/sitemap.html +27 -27
- data/_includes/content/toc.html +183 -183
- data/_includes/core/branding.html +6 -6
- data/_includes/core/console-capture.html +32 -74
- data/_includes/core/favicon.html +49 -7
- data/_includes/core/footer-fabs.html +17 -3
- data/_includes/core/footer.html +49 -34
- data/_includes/core/head.html +110 -86
- data/_includes/core/header.html +76 -54
- data/_includes/docs/bootstrap-docs.html +8 -8
- data/_includes/landing/landing-install-cards.html +2 -2
- data/_includes/landing/landing-quick-links.html +1 -1
- data/_includes/navigation/admin-nav.html +2 -2
- data/_includes/navigation/nav-tree.html +8 -8
- data/_includes/navigation/navbar.html +12 -12
- data/_includes/navigation/section-sidebar.html +109 -27
- data/_includes/navigation/sidebar-config.html +36 -2
- data/_includes/navigation/sidebar-left.html +17 -16
- data/_includes/navigation/sidebar-right.html +8 -7
- data/_includes/obsidian/full-graph.html +2 -2
- data/_includes/setup/claude-session.html +72 -0
- data/_includes/setup/prereq-checklist.html +90 -0
- data/_includes/setup/wizard.html +924 -222
- data/_includes/stats/stats-categories.html +8 -8
- data/_includes/stats/stats-header.html +14 -14
- data/_includes/stats/stats-metrics.html +14 -14
- data/_includes/stats/stats-no-data.html +12 -12
- data/_includes/stats/stats-overview.html +6 -6
- data/_includes/stats/stats-tags.html +8 -8
- data/_layouts/404.html +38 -24
- data/_layouts/README.md +2 -0
- data/_layouts/admin.html +24 -24
- data/_layouts/article.html +43 -33
- data/_layouts/author.html +20 -20
- data/_layouts/authors.html +2 -2
- data/_layouts/book-abc.html +12 -12
- data/_layouts/book-story.html +15 -15
- data/_layouts/book.html +12 -12
- data/_layouts/collection.html +33 -33
- data/_layouts/cookbook.html +88 -0
- data/_layouts/default.html +31 -28
- data/_layouts/home.html +23 -23
- data/_layouts/index.html +10 -10
- data/_layouts/landing.html +17 -17
- data/_layouts/news.html +44 -44
- data/_layouts/note.html +38 -38
- data/_layouts/notebook.html +34 -34
- data/_layouts/recipe.html +274 -0
- data/_layouts/root.html +92 -55
- data/_layouts/section.html +62 -33
- data/_layouts/setup.html +3 -3
- data/_layouts/sitemap-collection.html +49 -49
- data/_layouts/stats.html +40 -40
- data/_layouts/tag.html +12 -12
- data/_layouts/welcome.html +21 -21
- data/_sass/components/_callout.scss +1 -1
- data/_sass/components/_footer.scss +37 -1
- data/_sass/components/_mermaid.scss +375 -0
- data/_sass/components/_page-views.scss +36 -0
- data/_sass/components/_recipe.scss +506 -0
- data/_sass/components/_setup-wizard.scss +764 -0
- data/_sass/components/_ui-enhancements.scss +6 -6
- data/_sass/core/_navbar.scss +261 -46
- data/_sass/layouts/_landing.scss +2 -2
- data/_sass/layouts/_navbar-extras.scss +14 -4
- 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/ai-chat.js +47 -5
- data/assets/js/fleet-feedback-capture.js +124 -0
- data/assets/js/fleet-feedback.js +853 -0
- data/assets/js/mermaid-diagrams.js +1267 -0
- data/assets/js/modules/navigation/config.js +9 -6
- data/assets/js/modules/navigation/navbar.js +55 -0
- data/assets/js/modules/navigation/scroll-spy.js +315 -80
- data/assets/js/modules/theme/appearance.js +8 -2
- data/assets/js/obsidian-wiki-links.js +8 -3
- data/assets/js/page-feedback.js +125 -192
- data/assets/js/page-views.js +372 -0
- data/assets/js/recipe-scaler.js +501 -0
- data/assets/js/search-modal.js +36 -0
- data/assets/js/setup-wizard.js +2279 -226
- data/assets/js/site-builder.js +1834 -0
- data/assets/js/ui-enhancements.js +11 -3
- data/scripts/README.md +44 -0
- data/scripts/ai/README.md +38 -0
- data/scripts/ai/api_call.rb +124 -0
- data/scripts/ai/usage.rb +314 -0
- data/scripts/ai/usage_report.rb +225 -0
- data/scripts/bin/audit-consumer +39 -7
- data/scripts/bin/giscus-discussions +213 -14
- data/scripts/bin/manifest +35 -12
- data/scripts/ci/agent_review_result.py +164 -0
- data/scripts/ci/test_agent_review_result.py +172 -0
- data/scripts/ci/test_visual_evidence_autogen.py +341 -0
- data/scripts/ci/visual_evidence_autogen.py +1060 -0
- data/scripts/content-review.rb +20 -1
- data/scripts/design-system-check.rb +170 -0
- data/scripts/lib/audit.sh +42 -2
- data/scripts/lint-liquid-raw.rb +137 -0
- data/scripts/test/integration/mermaid +22 -8
- data/scripts/test/lib/run_tests.sh +3 -1
- data/scripts/test/lib/test_agent_review_result.sh +27 -0
- data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
- data/scripts/translate.rb +94 -16
- metadata +48 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-050 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
ADMIN TABS — Reusable tabbed interface for admin pages
|
|
5
5
|
===================================================================
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
Dependencies: Bootstrap 5 tab/nav components, Bootstrap Icons
|
|
31
31
|
Used by: Admin pages (config.md, theme.md, navigation.md, etc.)
|
|
32
32
|
===================================================================
|
|
33
|
-
|
|
33
|
+
{% endcomment %}
|
|
34
34
|
|
|
35
35
|
{% assign tab_prefix = include.id | default: "admin" %}
|
|
36
36
|
{% assign tab_list = include.tabs | split: "|" %}
|
|
@@ -14,9 +14,11 @@
|
|
|
14
14
|
- Renders nothing unless ai_chat.enabled AND a usable auth path
|
|
15
15
|
exists: proxy mode with a deployed proxy (proxy_ready: true,
|
|
16
16
|
recommended) or direct mode with a non-empty api_key.
|
|
17
|
-
- Proxy mode keeps the
|
|
18
|
-
templates/deploy/chat-proxy/)
|
|
19
|
-
|
|
17
|
+
- Proxy mode keeps the provider key server-side (see
|
|
18
|
+
templates/deploy/chat-proxy/) and can answer with Claude or Grok
|
|
19
|
+
(ai_chat.provider; the proxy's CHAT_PROVIDER wins). Direct mode
|
|
20
|
+
sends an Anthropic key from the browser (visible in page source) —
|
|
21
|
+
local development only, Claude only.
|
|
20
22
|
- GitHub actions: github.mode "url" opens pre-filled github.com
|
|
21
23
|
forms (no token anywhere); "proxy" creates issues/PRs through the
|
|
22
24
|
proxy's GitHub endpoints with a server-side token. Creation always
|
|
@@ -63,7 +65,7 @@
|
|
|
63
65
|
{% assign local_edit_flag = true %}
|
|
64
66
|
{% endif %}
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
{% comment %} AI Chat Toggle Button {% endcomment %}
|
|
67
69
|
<button id="aiChatToggle"
|
|
68
70
|
class="ai-chat-toggle btn btn-primary rounded-circle shadow-lg"
|
|
69
71
|
type="button"
|
|
@@ -74,14 +76,14 @@
|
|
|
74
76
|
<i class="bi bi-x-lg ai-chat-icon-close d-none" aria-hidden="true"></i>
|
|
75
77
|
</button>
|
|
76
78
|
|
|
77
|
-
|
|
79
|
+
{% comment %} AI Chat Panel {% endcomment %}
|
|
78
80
|
<div id="aiChatPanel"
|
|
79
81
|
class="ai-chat-panel shadow-lg rounded-3"
|
|
80
82
|
role="dialog"
|
|
81
83
|
aria-labelledby="aiChatTitle"
|
|
82
84
|
aria-hidden="true">
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
{% comment %} Chat Header {% endcomment %}
|
|
85
87
|
<div class="ai-chat-header d-flex align-items-center justify-content-between p-3">
|
|
86
88
|
<div class="d-flex align-items-center gap-2">
|
|
87
89
|
<i class="bi {{ site.ai_chat.icon | default: 'bi-robot' }} fs-5" aria-hidden="true"></i>
|
|
@@ -95,13 +97,13 @@
|
|
|
95
97
|
</button>
|
|
96
98
|
</div>
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
{% comment %} Chat Messages {% endcomment %}
|
|
99
101
|
<div id="aiChatMessages" class="ai-chat-messages p-3" role="log" aria-live="polite">
|
|
100
|
-
|
|
102
|
+
{% comment %} Welcome message inserted by JS {% endcomment %}
|
|
101
103
|
</div>
|
|
102
104
|
|
|
103
105
|
{% if gh_enabled %}
|
|
104
|
-
|
|
106
|
+
{% comment %} Quick actions (GitHub-backed flows) {% endcomment %}
|
|
105
107
|
<div class="ai-chat-chips px-3 pb-2 d-flex gap-2 flex-wrap">
|
|
106
108
|
<button type="button"
|
|
107
109
|
class="ai-chat-chip btn btn-sm btn-outline-secondary rounded-pill"
|
|
@@ -123,7 +125,7 @@
|
|
|
123
125
|
</div>
|
|
124
126
|
{% endif %}
|
|
125
127
|
|
|
126
|
-
|
|
128
|
+
{% comment %} Chat Input {% endcomment %}
|
|
127
129
|
<div class="ai-chat-input p-3">
|
|
128
130
|
<form id="aiChatForm" class="d-flex gap-2" autocomplete="off">
|
|
129
131
|
<label for="aiChatInput" class="visually-hidden">Chat message</label>
|
|
@@ -146,7 +148,7 @@
|
|
|
146
148
|
</div>
|
|
147
149
|
</div>
|
|
148
150
|
|
|
149
|
-
|
|
151
|
+
{% comment %} Page Context Data (generated by Jekyll at build time) {% endcomment %}
|
|
150
152
|
<script id="aiChatPageContext" type="application/json">
|
|
151
153
|
{
|
|
152
154
|
"page_title": {{ page.title | default: site.title | jsonify }},
|
|
@@ -179,6 +181,7 @@
|
|
|
179
181
|
<script id="aiChatConfig" type="application/json">
|
|
180
182
|
{
|
|
181
183
|
"endpoint": {{ site.ai_chat.endpoint | default: "/api/chat" | jsonify }},
|
|
184
|
+
"provider": {{ site.ai_chat.provider | default: "anthropic" | jsonify }},
|
|
182
185
|
"authMode": {{ ai_auth_mode | jsonify }},
|
|
183
186
|
"apiKey": {{ site.ai_chat.api_key | jsonify }},
|
|
184
187
|
"anthropicVersion": {{ site.ai_chat.anthropic_version | default: "2023-06-01" | jsonify }},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
{% comment %}
|
|
2
2
|
===================================================================
|
|
3
3
|
ANALYTICS DASHBOARD — PostHog & tracking configuration overview
|
|
4
4
|
===================================================================
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
Dependencies: Bootstrap 5 card/table/badge, site.posthog config
|
|
12
12
|
Used by: pages/_about/settings/analytics.md
|
|
13
13
|
===================================================================
|
|
14
|
-
|
|
14
|
+
{% endcomment %}
|
|
15
15
|
|
|
16
16
|
{% assign ph = site.posthog %}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
{% comment %} Status cards {% endcomment %}
|
|
19
19
|
<div class="row g-3 mb-4">
|
|
20
20
|
<div class="col-6 col-lg-3">
|
|
21
21
|
<div class="card text-center h-100 {% if ph.enabled %}border-success{% else %}border-warning{% endif %}">
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
{% comment %} Configuration Details {% endcomment %}
|
|
59
59
|
<div class="row g-4">
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
{% comment %} PostHog Settings {% endcomment %}
|
|
62
62
|
<div class="col-lg-6">
|
|
63
63
|
<div class="card h-100">
|
|
64
64
|
<div class="card-header"><i class="bi bi-gear me-1"></i> PostHog Configuration</div>
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
</div>
|
|
106
106
|
</div>
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
{% comment %} Privacy & Compliance {% endcomment %}
|
|
109
109
|
<div class="col-lg-6">
|
|
110
110
|
<div class="card h-100">
|
|
111
111
|
<div class="card-header"><i class="bi bi-shield-lock me-1"></i> Privacy & Compliance</div>
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
</div>
|
|
163
163
|
</div>
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
{% comment %} Custom Events {% endcomment %}
|
|
166
166
|
{% if ph.custom_events %}
|
|
167
167
|
<h5 class="mt-4 mb-3"><i class="bi bi-lightning me-1"></i> Custom Event Tracking</h5>
|
|
168
168
|
<div class="row g-3">
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
</div>
|
|
222
222
|
{% endif %}
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
{% comment %} External Links {% endcomment %}
|
|
225
225
|
<div class="mt-4">
|
|
226
226
|
<a href="https://us.posthog.com" target="_blank" rel="noopener" class="btn btn-outline-primary btn-sm me-2">
|
|
227
227
|
<i class="bi bi-box-arrow-up-right me-1"></i> Open PostHog Dashboard
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
<i class="bi bi-person-badge me-2" aria-hidden="true"></i>{{ bio_heading }}
|
|
74
74
|
</h2>
|
|
75
75
|
|
|
76
|
-
{% include components/author-card.html author=include.author style="full" %}
|
|
76
|
+
{% include components/author-card.html author=include.author style="full" heading_level=3 %}
|
|
77
77
|
|
|
78
78
|
{% if show_profile_link and bio_profile_url %}
|
|
79
79
|
<div class="mt-3">
|
|
@@ -192,10 +192,18 @@
|
|
|
192
192
|
{% endif %}
|
|
193
193
|
{% endif %}
|
|
194
194
|
<div class="flex-grow-1">
|
|
195
|
-
|
|
195
|
+
{%- comment -%}
|
|
196
|
+
Level is a PARAMETER, size is not. This card renders under an <h2> in
|
|
197
|
+
author-bio.html and under different ancestors elsewhere, so a
|
|
198
|
+
hardcoded level cannot be correct everywhere -- picking <h5> for its
|
|
199
|
+
font-size is what produced the h2 -> h5 skip in issue #436. The
|
|
200
|
+
default keeps the historic level for any caller that does not say.
|
|
201
|
+
{%- endcomment -%}
|
|
202
|
+
{%- assign _ac_level = include.heading_level | default: 5 -%}
|
|
203
|
+
<h{{ _ac_level }} class="h5 card-title mb-1" itemprop="name">
|
|
196
204
|
{%- if profile_url -%}<a href="{{ profile_url }}" class="text-decoration-none text-reset" itemprop="url">{{ author_name }}</a>{%- else -%}{{ author_name }}{%- endif -%}
|
|
197
205
|
{%- if author_data.ai -%} <span class="badge author-ai-badge align-middle" title="AI author persona"><i class="bi bi-robot me-1" aria-hidden="true"></i>AI</span>{%- endif -%}
|
|
198
|
-
</
|
|
206
|
+
</h{{ _ac_level }}>
|
|
199
207
|
{% if author_data.role %}<p class="text-primary mb-2" itemprop="jobTitle">{{ author_data.role }}</p>{% endif %}
|
|
200
208
|
{% if author_data.tagline %}<p class="author-tagline fst-italic text-body-secondary mb-2">{{ author_data.tagline }}</p>{% endif %}
|
|
201
209
|
{% if show_bio and author_data.bio %}<p class="card-text text-muted" itemprop="description">{{ author_data.bio }}</p>{% endif %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-054 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
AUTHOR E-E-A-T BLOCK - Experience, Expertise, Authority, Trust
|
|
5
5
|
===================================================================
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- _data/authors.yml: Author data
|
|
22
22
|
- Bootstrap 5 utility classes
|
|
23
23
|
===================================================================
|
|
24
|
-
|
|
24
|
+
{% endcomment %}
|
|
25
25
|
|
|
26
26
|
{% assign author_key = include.author_key | default: "bamr87" %}
|
|
27
27
|
{% assign author = site.data.authors[author_key] %}
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
{% if author %}
|
|
37
37
|
|
|
38
38
|
{% if eeat_style == "banner" %}
|
|
39
|
-
|
|
39
|
+
{% comment %} E-E-A-T Author Banner {% endcomment %}
|
|
40
40
|
<div class="bg-body-secondary border-top border-bottom py-4 mt-5" itemscope itemtype="https://schema.org/Person">
|
|
41
41
|
<div class="container-xl px-4 px-md-5">
|
|
42
42
|
<div class="row align-items-center g-3">
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
</div>
|
|
92
92
|
|
|
93
93
|
{% elsif eeat_style == "card" %}
|
|
94
|
-
|
|
94
|
+
{% comment %} E-E-A-T Author Card {% endcomment %}
|
|
95
95
|
<div class="card border-0 shadow-sm" itemscope itemtype="https://schema.org/Person">
|
|
96
96
|
<div class="card-body p-4">
|
|
97
97
|
<div class="d-flex align-items-start">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-065 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
BACKGROUND CUSTOMIZER — fffuel-style background settings panel
|
|
5
5
|
===================================================================
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
- _sass/theme/_backgrounds.scss (CSS custom properties)
|
|
15
15
|
- Bootstrap 5 offcanvas + form components
|
|
16
16
|
===================================================================
|
|
17
|
-
|
|
17
|
+
{% endcomment %}
|
|
18
18
|
|
|
19
19
|
{% assign skins = "air,aqua,contrast,dark,dirt,neon,mint,plum,sunrise" | split: "," %}
|
|
20
20
|
{% assign current_skin = site.theme_skin | default: "dark" %}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
{% comment %} Floating toggle button {% endcomment %}
|
|
23
23
|
<button class="btn btn-sm btn-outline-secondary position-fixed bottom-0 end-0 m-3 rounded-circle"
|
|
24
24
|
style="z-index: 1090; width: 40px; height: 40px;"
|
|
25
25
|
type="button"
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
<i class="bi bi-palette2"></i>
|
|
31
31
|
</button>
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
{% comment %} Offcanvas panel {% endcomment %}
|
|
34
34
|
<div class="offcanvas offcanvas-end" tabindex="-1" id="zer0BgCustomizer" aria-labelledby="zer0BgCustomizerLabel">
|
|
35
35
|
<div class="offcanvas-header">
|
|
36
|
-
<
|
|
36
|
+
<h2 class="offcanvas-title h5" id="zer0BgCustomizerLabel">
|
|
37
37
|
<i class="bi bi-palette2 me-2"></i>Background Settings
|
|
38
|
-
</
|
|
38
|
+
</h2>
|
|
39
39
|
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
40
40
|
</div>
|
|
41
41
|
|
|
42
42
|
<div class="offcanvas-body">
|
|
43
|
-
|
|
43
|
+
{% comment %} Skin selector {% endcomment %}
|
|
44
44
|
<div class="mb-4">
|
|
45
45
|
<label class="form-label fw-semibold">Theme Skin</label>
|
|
46
46
|
<div class="d-flex flex-wrap gap-2" id="zer0SkinButtons">
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
|
|
57
57
|
<hr>
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
{% comment %} Background toggle {% endcomment %}
|
|
60
60
|
<div class="mb-3">
|
|
61
61
|
<div class="form-check form-switch">
|
|
62
62
|
<input class="form-check-input" type="checkbox" id="zer0BgToggle" checked>
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
|
|
67
67
|
<hr>
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
{% comment %} Opacity sliders {% endcomment %}
|
|
70
70
|
<div class="mb-3">
|
|
71
71
|
<label class="form-label" for="zer0GradientOpacity">Gradient opacity</label>
|
|
72
72
|
<input type="range" class="form-range" id="zer0GradientOpacity"
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
</div>
|
|
97
97
|
</div>
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
{% comment %} Customizer interaction logic {% endcomment %}
|
|
100
100
|
<script>
|
|
101
101
|
document.addEventListener("DOMContentLoaded", function () {
|
|
102
102
|
if (typeof zer0Bg === "undefined") return;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
{% comment %} Feature: ZER0-004 {% endcomment %}
|
|
2
|
+
{% comment %}
|
|
3
|
+
BACKGROUND IMAGE - Cover art painted as a CSS background, announced correctly
|
|
4
|
+
|
|
5
|
+
Sibling to components/preview-image.html. Reach for THIS one when the art is
|
|
6
|
+
painted as a CSS background on an otherwise empty box; reach for
|
|
7
|
+
preview-image.html when the art is an <img> in the content flow.
|
|
8
|
+
|
|
9
|
+
WHY THIS EXISTS. A CSS background is invisible to assistive technology. A box
|
|
10
|
+
painted with cover art and nothing else announces nothing at all, so the
|
|
11
|
+
reader is told there is an element and never told what it shows. The fix is
|
|
12
|
+
role="img" plus an aria-label, which makes the box a single graphic with a
|
|
13
|
+
name. The theme already did this by hand in three places
|
|
14
|
+
(components/abc-letter.html, layouts/article.html rating stars,
|
|
15
|
+
components/theme-customizer.html) without it being a named convention.
|
|
16
|
+
|
|
17
|
+
TWO BRANCHES, and the second is not optional:
|
|
18
|
+
|
|
19
|
+
real image -> role="img" aria-label="..." (a graphic with a name)
|
|
20
|
+
decorative -> aria-hidden="true", and NO role and NO aria-label
|
|
21
|
+
|
|
22
|
+
Combining aria-hidden with role="img" is worse than either alone: it
|
|
23
|
+
announces a graphic and then hides it. A gradient placeholder carries no
|
|
24
|
+
information the surrounding text does not already carry, so it is hidden.
|
|
25
|
+
|
|
26
|
+
Usage:
|
|
27
|
+
{%- include components/background-image.html
|
|
28
|
+
src=post.preview
|
|
29
|
+
alt=post.title
|
|
30
|
+
class="card-cover"
|
|
31
|
+
style="height: 180px;"
|
|
32
|
+
-%}
|
|
33
|
+
|
|
34
|
+
{%- comment -%} decorative fallback: omit alt, or pass decorative=true {%- endcomment -%}
|
|
35
|
+
{%- include components/background-image.html class="card-cover card-cover-empty" -%}
|
|
36
|
+
|
|
37
|
+
Params:
|
|
38
|
+
src - image path (optional; omit for the decorative branch)
|
|
39
|
+
alt - accessible name; REQUIRED for the real-image branch
|
|
40
|
+
class - CSS classes on the box (default: "bg-cover")
|
|
41
|
+
style - extra inline style, appended after the background shorthand
|
|
42
|
+
decorative - force the decorative branch even when src is present
|
|
43
|
+
tag - element name (default: div)
|
|
44
|
+
|
|
45
|
+
Path convention is preview-image.html's, duplicated rather than extracted:
|
|
46
|
+
it is ~14 lines of Liquid, and a third shared include to save them buys less
|
|
47
|
+
than it costs in indirection. preview-image.html remains the source of the
|
|
48
|
+
convention -- change it there first.
|
|
49
|
+
- /images/previews/x.png -> /assets/images/previews/x.png
|
|
50
|
+
- /assets/images/previews/x.png -> unchanged
|
|
51
|
+
- https://example.com/x.png -> unchanged (external URL)
|
|
52
|
+
|
|
53
|
+
DO NOT apply this to a box that wraps text. role="img" makes the element a
|
|
54
|
+
single graphic and its descendants stop being exposed -- so putting it on
|
|
55
|
+
_includes/content/intro.html, which paints a background AND wraps the page
|
|
56
|
+
<h1>, would delete the heading from the accessibility tree.
|
|
57
|
+
{% endcomment %}
|
|
58
|
+
{%- assign bgi_src = include.src -%}
|
|
59
|
+
{%- assign bgi_alt = include.alt -%}
|
|
60
|
+
{%- assign bgi_class = include.class | default: "bg-cover" -%}
|
|
61
|
+
{%- assign bgi_style = include.style -%}
|
|
62
|
+
{%- assign bgi_tag = include.tag | default: "div" -%}
|
|
63
|
+
|
|
64
|
+
{%- comment -%} Decorative is the DEFAULT, and the real-image branch has to earn
|
|
65
|
+
it: an image AND a name AND no explicit decorative flag. Written as a
|
|
66
|
+
positive test on purpose -- the failure mode of getting this backwards is
|
|
67
|
+
role="img" aria-label="", an unnamed graphic, which is worse for a screen
|
|
68
|
+
reader than either branch done right. Falling back to aria-hidden is safe.
|
|
69
|
+
|
|
70
|
+
NOTE: `x == blank` does NOT match nil in Liquid 4 -- blank matches empty
|
|
71
|
+
strings and collections only. An earlier version of this file tested
|
|
72
|
+
`bgi_src == blank` and every decorative call rendered as an unnamed
|
|
73
|
+
graphic. Test truthiness AND emptiness, both. {%- endcomment -%}
|
|
74
|
+
{%- assign bgi_decorative = true -%}
|
|
75
|
+
{%- if include.decorative != true -%}
|
|
76
|
+
{%- if bgi_src and bgi_src != "" -%}
|
|
77
|
+
{%- if bgi_alt and bgi_alt != "" -%}
|
|
78
|
+
{%- assign bgi_decorative = false -%}
|
|
79
|
+
{%- endif -%}
|
|
80
|
+
{%- endif -%}
|
|
81
|
+
{%- endif -%}
|
|
82
|
+
|
|
83
|
+
{%- comment -%} Path resolution -- see preview-image.html {%- endcomment -%}
|
|
84
|
+
{%- assign bgi_assets_prefix = site.preview_images.assets_prefix | default: '/assets' -%}
|
|
85
|
+
{%- assign bgi_auto_prefix = site.preview_images.auto_prefix | default: true -%}
|
|
86
|
+
{%- if bgi_src == nil or bgi_src == "" -%}
|
|
87
|
+
{%- assign bgi_final_src = nil -%}
|
|
88
|
+
{%- elsif bgi_src contains '://' -%}
|
|
89
|
+
{%- assign bgi_final_src = bgi_src -%}
|
|
90
|
+
{%- elsif bgi_auto_prefix and bgi_src != blank -%}
|
|
91
|
+
{%- if bgi_src contains bgi_assets_prefix -%}
|
|
92
|
+
{%- assign bgi_final_src = bgi_src | relative_url -%}
|
|
93
|
+
{%- else -%}
|
|
94
|
+
{%- assign bgi_final_src = bgi_assets_prefix | append: bgi_src | relative_url -%}
|
|
95
|
+
{%- endif -%}
|
|
96
|
+
{%- elsif bgi_src != blank -%}
|
|
97
|
+
{%- assign bgi_final_src = bgi_src | relative_url -%}
|
|
98
|
+
{%- endif -%}
|
|
99
|
+
|
|
100
|
+
{%- comment -%} One capture for the whole attribute value, so "is there a style
|
|
101
|
+
at all" is a single test. `!= blank` would not do here: a capture that
|
|
102
|
+
produced nothing is an empty string, and "" == blank is true, but the
|
|
103
|
+
surrounding whitespace control makes that fragile to edit. Compare to ""
|
|
104
|
+
explicitly. {%- endcomment -%}
|
|
105
|
+
{%- capture bgi_background -%}
|
|
106
|
+
{%- if bgi_final_src %}background-image: url('{{ bgi_final_src }}'); background-size: cover; background-position: center;{% endif %}{{ bgi_style }}
|
|
107
|
+
{%- endcapture -%}
|
|
108
|
+
{%- assign bgi_background = bgi_background | strip -%}
|
|
109
|
+
|
|
110
|
+
{%- if bgi_decorative -%}
|
|
111
|
+
<{{ bgi_tag }} class="{{ bgi_class }}" aria-hidden="true"{% if bgi_background != "" %} style="{{ bgi_background }}"{% endif %}></{{ bgi_tag }}>
|
|
112
|
+
{%- else -%}
|
|
113
|
+
<{{ bgi_tag }} class="{{ bgi_class }}" role="img" aria-label="{{ bgi_alt | escape }}"{% if bgi_background != "" %} style="{{ bgi_background }}"{% endif %}></{{ bgi_tag }}>
|
|
114
|
+
{%- endif -%}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-077 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
BACKGROUND SETTINGS — fffuel-style background controls (tab content)
|
|
5
5
|
===================================================================
|
|
@@ -17,32 +17,33 @@
|
|
|
17
17
|
Section headings match the h6 pattern used by the parent
|
|
18
18
|
info-section.html so the Appearance tab reads as one surface.
|
|
19
19
|
===================================================================
|
|
20
|
-
|
|
20
|
+
{% endcomment %}
|
|
21
21
|
|
|
22
22
|
{% assign skins = "air,aqua,contrast,dark,dirt,neon,mint,plum,sunrise" | split: "," %}
|
|
23
23
|
{% assign current_skin = site.theme_skin | default: "dark" %}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
{% comment %} Skin selector {% endcomment %}
|
|
26
26
|
<div class="mb-4">
|
|
27
|
-
<
|
|
27
|
+
<h3 class="h6 text-body-secondary small text-uppercase fw-semibold mb-2">
|
|
28
28
|
<i class="bi bi-palette2 me-1" aria-hidden="true"></i>Theme Skin
|
|
29
|
-
</
|
|
29
|
+
</h3>
|
|
30
30
|
<div class="d-flex flex-wrap gap-2" id="zer0SkinButtons" role="group" aria-label="Theme skin">
|
|
31
31
|
{% for skin in skins %}
|
|
32
32
|
<button class="btn btn-sm btn-outline-primary{% if skin == current_skin %} active{% endif %}"
|
|
33
33
|
data-skin="{{ skin }}"
|
|
34
|
-
type="button"
|
|
34
|
+
type="button"
|
|
35
|
+
aria-pressed="{% if skin == current_skin %}true{% else %}false{% endif %}">
|
|
35
36
|
{{ skin | capitalize }}
|
|
36
37
|
</button>
|
|
37
38
|
{% endfor %}
|
|
38
39
|
</div>
|
|
39
40
|
</div>
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
{% comment %} SVG background toggle + layer opacity {% endcomment %}
|
|
42
43
|
<div class="mb-4">
|
|
43
|
-
<
|
|
44
|
+
<h3 class="h6 text-body-secondary small text-uppercase fw-semibold mb-2">
|
|
44
45
|
<i class="bi bi-image me-1" aria-hidden="true"></i>Background
|
|
45
|
-
</
|
|
46
|
+
</h3>
|
|
46
47
|
|
|
47
48
|
<div class="d-flex align-items-center justify-content-between p-3 bg-body-tertiary rounded mb-3">
|
|
48
49
|
<label class="form-check-label" for="zer0BgToggle">SVG backgrounds</label>
|
|
@@ -83,18 +84,32 @@
|
|
|
83
84
|
</button>
|
|
84
85
|
</div>
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
{% comment %} Customizer interaction logic {% endcomment %}
|
|
87
88
|
<script>
|
|
88
89
|
document.addEventListener("DOMContentLoaded", function () {
|
|
89
90
|
if (typeof zer0Bg === "undefined") return;
|
|
90
91
|
|
|
91
92
|
// Skin buttons
|
|
93
|
+
// `.active` is a Bootstrap visual class and carries no accessibility
|
|
94
|
+
// semantics, so selection is also exposed via aria-pressed (WCAG 4.1.2),
|
|
95
|
+
// matching the sibling color-mode group. Both are set in one place so no
|
|
96
|
+
// code path can leave them disagreeing.
|
|
97
|
+
function markActiveSkinButton(btn) {
|
|
98
|
+
document.querySelectorAll("#zer0SkinButtons .btn").forEach(function (b) {
|
|
99
|
+
b.classList.remove("active");
|
|
100
|
+
b.setAttribute("aria-pressed", "false");
|
|
101
|
+
});
|
|
102
|
+
if (btn) {
|
|
103
|
+
btn.classList.add("active");
|
|
104
|
+
btn.setAttribute("aria-pressed", "true");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
92
108
|
document.querySelectorAll("#zer0SkinButtons [data-skin]").forEach(function (btn) {
|
|
93
109
|
btn.addEventListener("click", function () {
|
|
94
110
|
var skin = this.getAttribute("data-skin");
|
|
95
111
|
zer0Bg.setSkin(skin);
|
|
96
|
-
|
|
97
|
-
this.classList.add("active");
|
|
112
|
+
markActiveSkinButton(this);
|
|
98
113
|
});
|
|
99
114
|
});
|
|
100
115
|
|
|
@@ -128,9 +143,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
|
128
143
|
document.getElementById(id + "Val").textContent = defaults[id];
|
|
129
144
|
});
|
|
130
145
|
toggle.checked = true;
|
|
131
|
-
document.
|
|
132
|
-
var active = document.querySelector('#zer0SkinButtons [data-skin="{{ current_skin }}"]');
|
|
133
|
-
if (active) active.classList.add("active");
|
|
146
|
+
markActiveSkinButton(document.querySelector('#zer0SkinButtons [data-skin="{{ current_skin }}"]'));
|
|
134
147
|
});
|
|
135
148
|
});
|
|
136
149
|
</script>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
{% comment %}
|
|
2
2
|
===================================================================
|
|
3
3
|
COLLECTION MANAGER — Jekyll collections overview
|
|
4
4
|
===================================================================
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
Dependencies: Bootstrap 5 table/card/badge, site.collections
|
|
12
12
|
Used by: pages/_about/settings/collections.md
|
|
13
13
|
===================================================================
|
|
14
|
-
|
|
14
|
+
{% endcomment %}
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
{% comment %} Summary cards {% endcomment %}
|
|
17
17
|
<div class="row g-3 mb-4">
|
|
18
18
|
<div class="col-6 col-lg-3">
|
|
19
19
|
<div class="card text-center h-100 border-primary">
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
</div>
|
|
62
62
|
</div>
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
{% comment %} Collections table {% endcomment %}
|
|
65
65
|
<div class="table-responsive">
|
|
66
66
|
<table class="table table-hover align-middle">
|
|
67
67
|
<thead class="table-dark">
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
</table>
|
|
105
105
|
</div>
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
{% comment %} Collection defaults from _config.yml {% endcomment %}
|
|
108
108
|
<h5 class="mt-4 mb-3"><i class="bi bi-sliders me-1"></i> Collection Defaults</h5>
|
|
109
109
|
<div class="accordion" id="collDefaultsAccordion">
|
|
110
110
|
{% for collection in site.collections %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-071 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
COMPONENT SHOWCASE - Live Bootstrap 5 demo gallery
|
|
5
5
|
===================================================================
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
showcase safe for remote-theme consumers who may lack /docs/, /posts/,
|
|
34
34
|
/categories/, /tags/, or /docs/customization/.
|
|
35
35
|
===================================================================
|
|
36
|
-
|
|
36
|
+
{% endcomment %}
|
|
37
37
|
{% assign sections = include.sections | default: "alerts,buttons,badges,cards,accordion,tabs,progress,breadcrumbs,table,tooltips,list-group" %}
|
|
38
38
|
{% assign section_list = sections | split: "," %}
|
|
39
39
|
|
|
40
40
|
{% if section_list contains "alerts" %}
|
|
41
|
-
|
|
41
|
+
{% comment %} ===== ALERTS ===== {% endcomment %}
|
|
42
42
|
<h3 id="showcase-alerts">Alerts</h3>
|
|
43
43
|
<p>Contextual feedback messages for user actions and system status:</p>
|
|
44
44
|
<div class="row g-3 mb-4">
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
{% endif %}
|
|
71
71
|
|
|
72
72
|
{% if section_list contains "buttons" %}
|
|
73
|
-
|
|
73
|
+
{% comment %} ===== BUTTONS ===== {% endcomment %}
|
|
74
74
|
<h3 id="showcase-buttons">Buttons</h3>
|
|
75
75
|
<p>A complete button system with contextual colors, outlines, and sizes:</p>
|
|
76
76
|
<div class="mb-4">
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
{% endif %}
|
|
103
103
|
|
|
104
104
|
{% if section_list contains "badges" %}
|
|
105
|
-
|
|
105
|
+
{% comment %} ===== BADGES ===== {% endcomment %}
|
|
106
106
|
<h3 id="showcase-badges">Badges</h3>
|
|
107
107
|
<p>Contextual labels, status indicators, and notification counters:</p>
|
|
108
108
|
<div class="mb-4">
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
{% endif %}
|
|
133
133
|
|
|
134
134
|
{% if section_list contains "cards" %}
|
|
135
|
-
|
|
135
|
+
{% comment %} ===== CARDS ===== {% endcomment %}
|
|
136
136
|
<h3 id="showcase-cards">Cards</h3>
|
|
137
137
|
<p>Responsive card layouts — the building block of post listings, feature displays, and documentation:</p>
|
|
138
138
|
<div class="row row-cols-1 row-cols-md-3 g-4 mb-4">
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
{% endif %}
|
|
192
192
|
|
|
193
193
|
{% if section_list contains "accordion" %}
|
|
194
|
-
|
|
194
|
+
{% comment %} ===== ACCORDION ===== {% endcomment %}
|
|
195
195
|
<h3 id="showcase-accordion">Accordion</h3>
|
|
196
196
|
<p>Collapsible content sections — ideal for FAQs and detailed documentation:</p>
|
|
197
197
|
<div class="accordion mb-4" id="showcaseAccordion">
|
|
@@ -235,7 +235,7 @@
|
|
|
235
235
|
{% endif %}
|
|
236
236
|
|
|
237
237
|
{% if section_list contains "tabs" %}
|
|
238
|
-
|
|
238
|
+
{% comment %} ===== TABS ===== {% endcomment %}
|
|
239
239
|
<h3 id="showcase-tabs">Tabs</h3>
|
|
240
240
|
<p>Tabbed content panels for organizing related information:</p>
|
|
241
241
|
<ul class="nav nav-tabs mb-0" id="showcaseTabs" role="tablist">
|
|
@@ -281,7 +281,7 @@ theme: jekyll-theme-zer0</code></pre>
|
|
|
281
281
|
{% endif %}
|
|
282
282
|
|
|
283
283
|
{% if section_list contains "progress" %}
|
|
284
|
-
|
|
284
|
+
{% comment %} ===== PROGRESS BARS ===== {% endcomment %}
|
|
285
285
|
<h3 id="showcase-progress">Progress Bars</h3>
|
|
286
286
|
<p>Visual indicators for build status, completion tracking, and loading states:</p>
|
|
287
287
|
<div class="mb-4">
|
|
@@ -325,7 +325,7 @@ theme: jekyll-theme-zer0</code></pre>
|
|
|
325
325
|
{% endif %}
|
|
326
326
|
|
|
327
327
|
{% if section_list contains "breadcrumbs" %}
|
|
328
|
-
|
|
328
|
+
{% comment %} ===== BREADCRUMBS ===== {% endcomment %}
|
|
329
329
|
<h3 id="showcase-breadcrumbs">Breadcrumbs</h3>
|
|
330
330
|
<p>Hierarchical navigation trail showing current page position:</p>
|
|
331
331
|
{% comment %} Existence-guard the demo breadcrumb links so they never 404 on
|
|
@@ -357,7 +357,7 @@ theme: jekyll-theme-zer0</code></pre>
|
|
|
357
357
|
{% endif %}
|
|
358
358
|
|
|
359
359
|
{% if section_list contains "table" %}
|
|
360
|
-
|
|
360
|
+
{% comment %} ===== TABLE ===== {% endcomment %}
|
|
361
361
|
<h3 id="showcase-table">Responsive Table</h3>
|
|
362
362
|
<p>Styled tables with Bootstrap — all Markdown tables automatically receive Bootstrap styling:</p>
|
|
363
363
|
<div class="table-responsive mb-4">
|
|
@@ -407,7 +407,7 @@ theme: jekyll-theme-zer0</code></pre>
|
|
|
407
407
|
{% endif %}
|
|
408
408
|
|
|
409
409
|
{% if section_list contains "tooltips" %}
|
|
410
|
-
|
|
410
|
+
{% comment %} ===== TOOLTIPS ===== {% endcomment %}
|
|
411
411
|
<h3 id="showcase-tooltips">Tooltips</h3>
|
|
412
412
|
<p>Interactive hints and contextual information on hover:</p>
|
|
413
413
|
<div class="d-flex flex-wrap gap-3 mb-4">
|
|
@@ -436,7 +436,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
436
436
|
{% endif %}
|
|
437
437
|
|
|
438
438
|
{% if section_list contains "list-group" %}
|
|
439
|
-
|
|
439
|
+
{% comment %} ===== LIST GROUP ===== {% endcomment %}
|
|
440
440
|
<h3 id="showcase-list-group">List Group</h3>
|
|
441
441
|
<p>Organized content lists with icons, badges, and action states:</p>
|
|
442
442
|
{% comment %} Existence-guard the demo list-group links (issue #219). Each target
|