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,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
{% comment %}
|
|
2
2
|
===================================================================
|
|
3
3
|
NAV TREE - Flat YAML Navigation Renderer
|
|
4
4
|
===================================================================
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
Usage:
|
|
29
29
|
include navigation/nav-tree.html nav="docs"
|
|
30
30
|
===================================================================
|
|
31
|
-
|
|
31
|
+
{% endcomment %}
|
|
32
32
|
|
|
33
33
|
{% assign navigation = site.data.navigation[include.nav] %}
|
|
34
34
|
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
<li class="mb-1 nav-tree-item" data-depth="0">
|
|
44
44
|
{% if has_children %}
|
|
45
|
-
|
|
45
|
+
{% comment %} Parent item with children - collapsible {% endcomment %}
|
|
46
46
|
<div class="d-flex align-items-center">
|
|
47
47
|
{% if item.url %}
|
|
48
48
|
<a href="{{ item.url | relative_url }}"
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
{% endif %}
|
|
74
74
|
</div>
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
{% comment %} Children container (Level 1) {% endcomment %}
|
|
77
77
|
<div class="collapse{% if is_expanded %} show{% endif %}" id="{{ item_id }}">
|
|
78
78
|
<ul class="list-unstyled fw-normal ps-3 nav-tree-children">
|
|
79
79
|
{% for child in item.children %}
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
|
|
85
85
|
<li class="mb-1 nav-tree-item" data-depth="1">
|
|
86
86
|
{% if child_has_children %}
|
|
87
|
-
|
|
87
|
+
{% comment %} Level 1 parent with children {% endcomment %}
|
|
88
88
|
<div class="d-flex align-items-center">
|
|
89
89
|
{% if child.url %}
|
|
90
90
|
<a href="{{ child.url | relative_url }}"
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
{% endif %}
|
|
115
115
|
</div>
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
{% comment %} Children container (Level 2) {% endcomment %}
|
|
118
118
|
<div class="collapse{% if child_expanded %} show{% endif %}" id="{{ child_id }}">
|
|
119
119
|
<ul class="list-unstyled fw-normal ps-3 nav-tree-children">
|
|
120
120
|
{% for grandchild in child.children %}
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
</ul>
|
|
138
138
|
</div>
|
|
139
139
|
{% else %}
|
|
140
|
-
|
|
140
|
+
{% comment %} Level 1 leaf item {% endcomment %}
|
|
141
141
|
{% if child.url %}
|
|
142
142
|
<a href="{{ child.url | relative_url }}"
|
|
143
143
|
class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if child_active %} active{% endif %}">
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
</ul>
|
|
157
157
|
</div>
|
|
158
158
|
{% else %}
|
|
159
|
-
|
|
159
|
+
{% comment %} Root level leaf item {% endcomment %}
|
|
160
160
|
{% if item.url %}
|
|
161
161
|
<a href="{{ item.url | relative_url }}"
|
|
162
162
|
class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if is_active %} active{% endif %}">
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{% comment %} Features: ZER0-049, ZER0-055 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
file: navbar.html
|
|
4
4
|
path: /includes/navbar.html
|
|
5
5
|
includes:
|
|
6
6
|
purpose: Offcanvas main navigation following Bootstrap 5 best practices
|
|
7
7
|
with hover-activated dropdowns for desktop and accessible interactions
|
|
8
|
-
|
|
8
|
+
{% endcomment %}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
{% comment %} Navigation Links - Responsive Offcanvas (inline at lg+, offcanvas below) {% endcomment %}
|
|
11
11
|
{%- include core/i18n.html -%}
|
|
12
12
|
<div class="offcanvas-lg offcanvas-end" tabindex="-1" id="bdNavbar" aria-labelledby="mainNavOffcanvasLabel">
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
{% comment %} Main Navigation Header - Offcanvas {% endcomment %}
|
|
15
15
|
<div class="offcanvas-header border-bottom">
|
|
16
16
|
<h2 class="offcanvas-title h5 mb-0" id="mainNavOffcanvasLabel">{{ ui.main_nav_label | default: "Main Navigation" }}</h2>
|
|
17
17
|
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close navigation menu" data-bs-target="#bdNavbar"></button>
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
{% comment %} Main Navigation Body - Offcanvas {% endcomment %}
|
|
21
21
|
<div class="offcanvas-body">
|
|
22
|
-
|
|
22
|
+
{% comment %} Desktop: width is the grid middle track; labels ellipsis or icon-only via container query {% endcomment %}
|
|
23
23
|
<div class="bd-navbar-nav-viewport">
|
|
24
24
|
<ul class="navbar-nav justify-content-lg-center text-start flex-grow-1">
|
|
25
25
|
<li class="nav-item d-lg-none">
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
{%- if has_children -%}
|
|
46
46
|
<li class="nav-item dropdown d-flex align-items-center nav-hover-dropdown">
|
|
47
|
-
|
|
47
|
+
{% comment %} Parent link navigates directly {% endcomment %}
|
|
48
48
|
<a
|
|
49
49
|
class="nav-link"
|
|
50
50
|
href="{{ link.url | relative_url }}"
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
<span class="nav-link-text">{{ link.title }}</span>
|
|
59
59
|
</a>
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
to avoid Bootstrap's native handler conflicting with our toggle logic
|
|
61
|
+
{% comment %} Split toggle opens the dropdown (click on mobile, hover on desktop) {% endcomment %}
|
|
62
|
+
{% comment %} Note: No data-bs-toggle="dropdown" — custom JS handles all interactions
|
|
63
|
+
to avoid Bootstrap's native handler conflicting with our toggle logic {% endcomment %}
|
|
64
64
|
<button
|
|
65
65
|
class="nav-link dropdown-toggle dropdown-toggle-split ms-1"
|
|
66
66
|
type="button"
|
|
@@ -165,8 +165,8 @@
|
|
|
165
165
|
</div>
|
|
166
166
|
</div>
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
{% comment %}
|
|
169
169
|
Navigation styles are now in _sass/core/_navbar.scss
|
|
170
170
|
Navigation scripts are now in assets/js/navigation.js
|
|
171
171
|
These are loaded automatically via the theme's asset pipeline
|
|
172
|
-
|
|
172
|
+
{% endcomment %}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
{% comment %}
|
|
2
2
|
===================================================================
|
|
3
3
|
SECTION SIDEBAR - Fixed Topic Navigation
|
|
4
4
|
===================================================================
|
|
@@ -12,32 +12,72 @@
|
|
|
12
12
|
- sub_categories: Array of unique tags/topics from section posts
|
|
13
13
|
- page_title: Title of the current section
|
|
14
14
|
- sidebar_id: Unique ID for the sidebar (default: "sectionSidebar")
|
|
15
|
-
|
|
15
|
+
- section_style: The parent layout's display style, one of grid | list |
|
|
16
|
+
magazine (default: "grid"). Decides whether topics render as scroll
|
|
17
|
+
anchors or as filter buttons — see the Topic controls note below.
|
|
18
|
+
|
|
16
19
|
Features:
|
|
17
20
|
- Desktop: Fixed sticky sidebar on the left
|
|
18
21
|
- Mobile: Offcanvas drawer
|
|
19
22
|
- Topic navigation with article counts
|
|
20
23
|
- Section statistics
|
|
21
|
-
- Smooth scroll to sections
|
|
24
|
+
- Smooth scroll to sections (magazine style, where scroll targets exist)
|
|
25
|
+
- Card filtering via [data-filter] (grid/list styles)
|
|
22
26
|
|
|
23
27
|
Dependencies:
|
|
24
28
|
- Bootstrap 5 offcanvas component
|
|
25
29
|
- Bootstrap Icons
|
|
26
30
|
===================================================================
|
|
27
|
-
|
|
31
|
+
{% endcomment %}
|
|
28
32
|
|
|
29
33
|
{% assign sidebar_id = include.sidebar_id | default: "sectionSidebar" %}
|
|
30
34
|
{% assign section_posts = include.section_posts %}
|
|
31
35
|
{% assign sub_categories = include.sub_categories %}
|
|
32
36
|
{% assign page_title = include.page_title | default: page.title %}
|
|
37
|
+
{% assign section_style = include.section_style | default: "grid" %}
|
|
38
|
+
|
|
39
|
+
{% comment %}
|
|
40
|
+
Topic controls: link vs filter.
|
|
41
|
+
|
|
42
|
+
Only the `magazine` branch of _layouts/section.html emits per-subcategory
|
|
43
|
+
`<section id="{{ subcat | slugify }}">` scroll targets, and only for the first
|
|
44
|
+
5 sub-categories that still have a post once the featured hero is excluded.
|
|
45
|
+
The `grid` and `list` branches emit no sub-topic ids at all — they filter
|
|
46
|
+
`[data-tags]` cards through `[data-filter]` buttons instead.
|
|
33
47
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
So an <a href="#slug"> here is only ever valid under magazine, and only for
|
|
49
|
+
that exact set. Emitting one anywhere else produced guaranteed-dead anchors:
|
|
50
|
+
invalid markup, a dead click for keyboard/AT users, and a scrollspy that could
|
|
51
|
+
never activate. `_linkable_subcats` below reproduces the layout's set exactly;
|
|
52
|
+
every other style renders filter buttons, which the layout's existing
|
|
53
|
+
`[data-filter]` handler already wires up with no extra JS.
|
|
54
|
+
{% endcomment %}
|
|
55
|
+
{% assign _anchors_resolve = false %}
|
|
56
|
+
{% if section_style == "magazine" %}{% assign _anchors_resolve = true %}{% endif %}
|
|
57
|
+
|
|
58
|
+
{% assign _linkable_subcats = "" | split: "" %}
|
|
59
|
+
{% if _anchors_resolve %}
|
|
60
|
+
{% assign _featured = section_posts | where: "featured", true | first %}
|
|
61
|
+
{% unless _featured %}{% assign _featured = section_posts | first %}{% endunless %}
|
|
62
|
+
{% for subcat in sub_categories limit: 5 %}
|
|
63
|
+
{% assign _subcat_posts = section_posts | where_exp: "post", "post.tags contains subcat" %}
|
|
64
|
+
{% assign _remaining = 0 %}
|
|
65
|
+
{% for p in _subcat_posts %}
|
|
66
|
+
{% unless p.url == _featured.url %}{% assign _remaining = _remaining | plus: 1 %}{% endunless %}
|
|
67
|
+
{% endfor %}
|
|
68
|
+
{% if _remaining > 0 %}
|
|
69
|
+
{% assign _linkable_subcats = _linkable_subcats | push: subcat %}
|
|
70
|
+
{% endif %}
|
|
71
|
+
{% endfor %}
|
|
72
|
+
{% endif %}
|
|
73
|
+
|
|
74
|
+
{% comment %} ================================ {% endcomment %}
|
|
75
|
+
{% comment %} DESKTOP SIDEBAR (Fixed Sticky) {% endcomment %}
|
|
76
|
+
{% comment %} ================================ {% endcomment %}
|
|
37
77
|
<aside class="section-sidebar-desktop d-none d-lg-block w-100">
|
|
38
78
|
<div class="position-sticky" style="top: 80px;">
|
|
39
79
|
|
|
40
|
-
|
|
80
|
+
{% comment %} Topics Card {% endcomment %}
|
|
41
81
|
<div class="card border-0 shadow-sm">
|
|
42
82
|
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
|
|
43
83
|
<h5 class="mb-0">
|
|
@@ -47,21 +87,37 @@
|
|
|
47
87
|
</div>
|
|
48
88
|
<div class="card-body p-0">
|
|
49
89
|
<nav class="nav flex-column sidebar-nav">
|
|
90
|
+
{% if _anchors_resolve %}
|
|
50
91
|
<a class="nav-link active" href="#all-posts" data-section="all-posts">
|
|
51
92
|
<i class="bi bi-grid me-2"></i>
|
|
52
93
|
<span class="nav-text">All Articles</span>
|
|
53
94
|
<span class="badge bg-secondary ms-auto">{{ section_posts.size }}</span>
|
|
54
95
|
</a>
|
|
55
|
-
{% for subcat in
|
|
96
|
+
{% for subcat in _linkable_subcats %}
|
|
56
97
|
{% assign subcat_posts = section_posts | where_exp: "post", "post.tags contains subcat" %}
|
|
57
|
-
{% if subcat_posts.size > 0 %}
|
|
58
98
|
<a class="nav-link" href="#{{ subcat | slugify }}" data-section="{{ subcat | slugify }}">
|
|
59
99
|
<i class="bi bi-tag me-2"></i>
|
|
60
100
|
<span class="nav-text">{{ subcat | capitalize }}</span>
|
|
61
101
|
<span class="badge bg-light text-dark ms-auto">{{ subcat_posts.size }}</span>
|
|
62
102
|
</a>
|
|
103
|
+
{% endfor %}
|
|
104
|
+
{% else %}
|
|
105
|
+
<button type="button" class="nav-link text-start active" data-filter="all">
|
|
106
|
+
<i class="bi bi-grid me-2"></i>
|
|
107
|
+
<span class="nav-text">All Articles</span>
|
|
108
|
+
<span class="badge bg-secondary ms-auto">{{ section_posts.size }}</span>
|
|
109
|
+
</button>
|
|
110
|
+
{% for subcat in sub_categories limit: 15 %}
|
|
111
|
+
{% assign subcat_posts = section_posts | where_exp: "post", "post.tags contains subcat" %}
|
|
112
|
+
{% if subcat_posts.size > 0 %}
|
|
113
|
+
<button type="button" class="nav-link text-start" data-filter="{{ subcat | slugify }}">
|
|
114
|
+
<i class="bi bi-tag me-2"></i>
|
|
115
|
+
<span class="nav-text">{{ subcat | capitalize }}</span>
|
|
116
|
+
<span class="badge bg-light text-dark ms-auto">{{ subcat_posts.size }}</span>
|
|
117
|
+
</button>
|
|
63
118
|
{% endif %}
|
|
64
119
|
{% endfor %}
|
|
120
|
+
{% endif %}
|
|
65
121
|
</nav>
|
|
66
122
|
</div>
|
|
67
123
|
{% comment %} Existence-gate the tags index: a remote-theme consumer without
|
|
@@ -78,7 +134,7 @@
|
|
|
78
134
|
{% endif %}
|
|
79
135
|
</div>
|
|
80
136
|
|
|
81
|
-
|
|
137
|
+
{% comment %} Section Stats {% endcomment %}
|
|
82
138
|
<div class="card border-0 shadow-sm mt-3">
|
|
83
139
|
<div class="card-body">
|
|
84
140
|
<h6 class="text-muted mb-3">
|
|
@@ -102,31 +158,45 @@
|
|
|
102
158
|
</div>
|
|
103
159
|
</aside>
|
|
104
160
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
161
|
+
{% comment %} ================================ {% endcomment %}
|
|
162
|
+
{% comment %} MOBILE OFFCANVAS SIDEBAR {% endcomment %}
|
|
163
|
+
{% comment %} ================================ {% endcomment %}
|
|
108
164
|
<div class="offcanvas offcanvas-start" tabindex="-1" id="{{ sidebar_id }}" aria-labelledby="{{ sidebar_id }}Label">
|
|
109
165
|
<div class="offcanvas-header bg-primary text-white">
|
|
110
|
-
<
|
|
166
|
+
<h2 class="offcanvas-title h5" id="{{ sidebar_id }}Label">
|
|
111
167
|
<i class="bi bi-bookmark me-2"></i>{{ page_title }} Topics
|
|
112
|
-
</
|
|
168
|
+
</h2>
|
|
113
169
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
|
114
170
|
</div>
|
|
115
171
|
<div class="offcanvas-body p-0">
|
|
116
172
|
<nav class="nav flex-column">
|
|
173
|
+
{% if _anchors_resolve %}
|
|
117
174
|
<a class="nav-link active bg-light py-3 border-bottom" href="#all-posts" data-bs-dismiss="offcanvas">
|
|
118
175
|
<i class="bi bi-grid me-2"></i>All Articles
|
|
119
176
|
<span class="badge bg-secondary float-end">{{ section_posts.size }}</span>
|
|
120
177
|
</a>
|
|
121
|
-
{% for subcat in
|
|
178
|
+
{% for subcat in _linkable_subcats %}
|
|
122
179
|
{% assign subcat_posts = section_posts | where_exp: "post", "post.tags contains subcat" %}
|
|
123
|
-
{% if subcat_posts.size > 0 %}
|
|
124
180
|
<a class="nav-link text-body-secondary py-3 border-bottom" href="#{{ subcat | slugify }}" data-bs-dismiss="offcanvas">
|
|
125
181
|
<i class="bi bi-tag me-2"></i>{{ subcat | capitalize }}
|
|
126
182
|
<span class="badge bg-light text-dark float-end">{{ subcat_posts.size }}</span>
|
|
127
183
|
</a>
|
|
184
|
+
{% endfor %}
|
|
185
|
+
{% else %}
|
|
186
|
+
<button type="button" class="nav-link text-start active bg-light py-3 border-bottom w-100" data-filter="all" data-bs-dismiss="offcanvas">
|
|
187
|
+
<i class="bi bi-grid me-2"></i>All Articles
|
|
188
|
+
<span class="badge bg-secondary float-end">{{ section_posts.size }}</span>
|
|
189
|
+
</button>
|
|
190
|
+
{% for subcat in sub_categories %}
|
|
191
|
+
{% assign subcat_posts = section_posts | where_exp: "post", "post.tags contains subcat" %}
|
|
192
|
+
{% if subcat_posts.size > 0 %}
|
|
193
|
+
<button type="button" class="nav-link text-start text-body-secondary py-3 border-bottom w-100" data-filter="{{ subcat | slugify }}" data-bs-dismiss="offcanvas">
|
|
194
|
+
<i class="bi bi-tag me-2"></i>{{ subcat | capitalize }}
|
|
195
|
+
<span class="badge bg-light text-dark float-end">{{ subcat_posts.size }}</span>
|
|
196
|
+
</button>
|
|
128
197
|
{% endif %}
|
|
129
198
|
{% endfor %}
|
|
199
|
+
{% endif %}
|
|
130
200
|
</nav>
|
|
131
201
|
{% if _tags_page %}
|
|
132
202
|
<div class="p-3">
|
|
@@ -138,9 +208,9 @@
|
|
|
138
208
|
</div>
|
|
139
209
|
</div>
|
|
140
210
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
211
|
+
{% comment %} ================================ {% endcomment %}
|
|
212
|
+
{% comment %} SIDEBAR STYLES {% endcomment %}
|
|
213
|
+
{% comment %} ================================ {% endcomment %}
|
|
144
214
|
<style>
|
|
145
215
|
/* Sidebar Navigation */
|
|
146
216
|
.sidebar-nav .nav-link {
|
|
@@ -169,6 +239,16 @@
|
|
|
169
239
|
overflow: hidden;
|
|
170
240
|
text-overflow: ellipsis;
|
|
171
241
|
}
|
|
242
|
+
|
|
243
|
+
/* In grid/list styles the topic controls are <button data-filter> (there is
|
|
244
|
+
no per-topic scroll target to link to). Bootstrap's .nav-link already
|
|
245
|
+
clears button background/border; these are the two properties a <button>
|
|
246
|
+
still needs to render identically to the anchor form. */
|
|
247
|
+
.sidebar-nav button.nav-link,
|
|
248
|
+
.offcanvas button.nav-link {
|
|
249
|
+
width: 100%;
|
|
250
|
+
text-align: left;
|
|
251
|
+
}
|
|
172
252
|
|
|
173
253
|
/* Offcanvas mobile styling */
|
|
174
254
|
.offcanvas .nav-link {
|
|
@@ -178,9 +258,9 @@
|
|
|
178
258
|
}
|
|
179
259
|
</style>
|
|
180
260
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
261
|
+
{% comment %} ================================ {% endcomment %}
|
|
262
|
+
{% comment %} SIDEBAR JAVASCRIPT {% endcomment %}
|
|
263
|
+
{% comment %} ================================ {% endcomment %}
|
|
184
264
|
<script>
|
|
185
265
|
(function() {
|
|
186
266
|
// Smooth scroll for sidebar links
|
|
@@ -194,8 +274,10 @@
|
|
|
194
274
|
if (target) {
|
|
195
275
|
target.scrollIntoView({ behavior: 'smooth' });
|
|
196
276
|
|
|
197
|
-
// Update active state in sidebar
|
|
198
|
-
|
|
277
|
+
// Update active state in sidebar. Scoped to anchors: in grid/list
|
|
278
|
+
// styles the topic controls are <button data-filter> elements whose
|
|
279
|
+
// active state belongs to the layout's filter handler, not here.
|
|
280
|
+
document.querySelectorAll('.sidebar-nav a.nav-link').forEach(link => {
|
|
199
281
|
link.classList.remove('active');
|
|
200
282
|
});
|
|
201
283
|
|
|
@@ -220,7 +302,7 @@
|
|
|
220
302
|
entries.forEach(entry => {
|
|
221
303
|
if (entry.isIntersecting) {
|
|
222
304
|
const id = entry.target.getAttribute('id');
|
|
223
|
-
document.querySelectorAll('.sidebar-nav .nav-link').forEach(link => {
|
|
305
|
+
document.querySelectorAll('.sidebar-nav a.nav-link').forEach(link => {
|
|
224
306
|
link.classList.remove('active');
|
|
225
307
|
if (link.getAttribute('href') === `#${id}`) {
|
|
226
308
|
link.classList.add('active');
|
|
@@ -16,8 +16,13 @@
|
|
|
16
16
|
"categories", "tags", or the name of a
|
|
17
17
|
_data/navigation/*.yml file (nil = none)
|
|
18
18
|
sidebar_has_content — true only when sidebar_nav will actually
|
|
19
|
-
render items (gates the left column
|
|
20
|
-
|
|
19
|
+
render items (gates the left column)
|
|
20
|
+
sidebar_offcanvas_rendered
|
|
21
|
+
— true only when the CURRENT LAYOUT emits
|
|
22
|
+
the #bdSidebar / #tocContents offcanvases
|
|
23
|
+
at all. sidebar_has_content is not enough
|
|
24
|
+
to gate a toggle: see the note at the
|
|
25
|
+
bottom of this file (issue #373).
|
|
21
26
|
sidebar_title — heading text for the sidebar panel
|
|
22
27
|
sidebar_icon — Bootstrap Icons class for the heading
|
|
23
28
|
Config precedence (most specific wins):
|
|
@@ -134,3 +139,32 @@
|
|
|
134
139
|
{%- if page.sidebar.icon -%}
|
|
135
140
|
{%- assign sidebar_icon = page.sidebar.icon -%}
|
|
136
141
|
{%- endif -%}
|
|
142
|
+
|
|
143
|
+
{%- comment -%}
|
|
144
|
+
7. Does THIS LAYOUT actually render the offcanvas panels? (issue #373)
|
|
145
|
+
|
|
146
|
+
`sidebar_has_content` answers "is there nav content", which is what gates the
|
|
147
|
+
left column inside _layouts/default.html. It is NOT sufficient to gate the
|
|
148
|
+
TOGGLES, because core/header.html and core/footer-fabs.html are included from
|
|
149
|
+
_layouts/root.html — so they render on every layout, while `#bdSidebar`
|
|
150
|
+
(navigation/sidebar-left.html) and `#tocContents` (navigation/sidebar-right.html)
|
|
151
|
+
are emitted by _layouts/default.html alone.
|
|
152
|
+
|
|
153
|
+
The result was a dead control plus a dangling ARIA reference on every page
|
|
154
|
+
whose layout inherits `root` directly: measured at 37 pages of a 415-page
|
|
155
|
+
build, including all of `/about/**` (layout: admin) and 404/CHANGELOG.
|
|
156
|
+
Clicking did nothing, and assistive tech followed aria-controls to an element
|
|
157
|
+
that was not there.
|
|
158
|
+
|
|
159
|
+
There is no Liquid API for "resolve the layout inheritance chain", so the set
|
|
160
|
+
of layouts that reach default.html is listed here explicitly. It is pinned by
|
|
161
|
+
a test (test/test_core.sh :: test_sidebar_offcanvas_layout_gate) that reads
|
|
162
|
+
the front matter of every _layouts/*.html and fails if reality drifts from
|
|
163
|
+
this list — the same invariant pattern #425 used for the pixel-gate filter.
|
|
164
|
+
Add a layout here when, and only when, its `layout:` chain reaches default.
|
|
165
|
+
{%- endcomment -%}
|
|
166
|
+
{%- assign _sidebar_offcanvas_layouts = "default,article,author,authors,collection,cookbook,note,notebook,recipe,tag" | split: "," -%}
|
|
167
|
+
{%- assign sidebar_offcanvas_rendered = false -%}
|
|
168
|
+
{%- if _sidebar_offcanvas_layouts contains page.layout -%}
|
|
169
|
+
{%- assign sidebar_offcanvas_rendered = true -%}
|
|
170
|
+
{%- endif -%}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% comment %} Feature: ZER0-008 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
===================================================================
|
|
4
4
|
SIDEBAR LEFT - Dynamic Navigation Sidebar
|
|
5
5
|
===================================================================
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
- Heading text/icon: page.sidebar.title/icon → collection metadata →
|
|
28
28
|
site.sidebar.title/icon → "Browse docs"
|
|
29
29
|
===================================================================
|
|
30
|
-
|
|
30
|
+
{% endcomment %}
|
|
31
31
|
|
|
32
32
|
{% include navigation/sidebar-config.html %}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
{% comment %} ================================ {% endcomment %}
|
|
35
|
+
{% comment %} SIDEBAR NAVIGATION CONTAINER {% endcomment %}
|
|
36
|
+
{% comment %} ================================ {% endcomment %}
|
|
37
|
+
{% comment %} Responsive offcanvas sidebar - full-width on mobile, fixed on desktop {% endcomment %}
|
|
38
38
|
<script>
|
|
39
39
|
try {
|
|
40
40
|
if (localStorage.getItem('zer0-nav-sidebar-visible') === 'false') {
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
</script>
|
|
45
45
|
<div class="offcanvas-lg offcanvas-start" tabindex="-1" id="bdSidebar" aria-labelledby="bdSidebarOffcanvasLabel">
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
{% comment %} ========================== {% endcomment %}
|
|
48
|
+
{% comment %} SIDEBAR HEADER {% endcomment %}
|
|
49
|
+
{% comment %} ========================== {% endcomment %}
|
|
50
|
+
{% comment %} Mobile-only header with close button {% endcomment %}
|
|
51
51
|
<div class="offcanvas-header">
|
|
52
52
|
<h2 class="offcanvas-title h5 mb-0" id="bdSidebarOffcanvasLabel">{{ sidebar_title }}</h2>
|
|
53
53
|
<div class="d-flex align-items-center gap-1">
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
{% comment %} ========================== {% endcomment %}
|
|
67
|
+
{% comment %} SIDEBAR CONTENT AREA {% endcomment %}
|
|
68
|
+
{% comment %} ========================== {% endcomment %}
|
|
69
|
+
{% comment %} Scrollable content area with dynamic navigation options {% endcomment %}
|
|
70
70
|
<div class="offcanvas-body overflow-auto">
|
|
71
71
|
|
|
72
72
|
<div class="bd-sidebar-desktop-header mb-3 d-none d-lg-flex align-items-center justify-content-between gap-2 w-100">
|
|
@@ -79,13 +79,14 @@
|
|
|
79
79
|
aria-controls="bdSidebar"
|
|
80
80
|
aria-expanded="true"
|
|
81
81
|
aria-label="Hide documentation sidebar"
|
|
82
|
-
|
|
82
|
+
aria-keyshortcuts="b"
|
|
83
|
+
title="Hide documentation sidebar (b)">
|
|
83
84
|
<i class="bi bi-layout-sidebar-inset" aria-hidden="true"></i>
|
|
84
85
|
<span class="visually-hidden">Hide documentation sidebar</span>
|
|
85
86
|
</button>
|
|
86
87
|
</div>
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
{% comment %} Resolved navigation content (see navigation/sidebar-nav.html) {% endcomment %}
|
|
89
90
|
{% include navigation/sidebar-nav.html id="sidebar-content" %}
|
|
90
91
|
|
|
91
92
|
</div>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{% comment %} Features: ZER0-008, ZER0-010 {% endcomment %}
|
|
2
|
-
|
|
2
|
+
{% comment %}
|
|
3
3
|
file: sidebar-right.html
|
|
4
4
|
path: _includes/sidebar-right.html
|
|
5
5
|
includes: nav_list.html, content/toc.html
|
|
6
|
-
|
|
6
|
+
{% endcomment %}
|
|
7
7
|
|
|
8
8
|
{%- include core/i18n.html -%}
|
|
9
|
-
|
|
9
|
+
{% comment %} FOUC guard: apply hidden TOC preference before paint {% endcomment %}
|
|
10
10
|
<script>
|
|
11
11
|
try {
|
|
12
12
|
if (localStorage.getItem('zer0-nav-toc-visible') === 'false') {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
} catch (e) {}
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
{% comment %} Right sidebar container {% endcomment %}
|
|
19
19
|
<div class="offcanvas-lg offcanvas-end" tabindex="-1" id="tocContents" aria-labelledby="tocLabel">
|
|
20
20
|
<div class="offcanvas-header">
|
|
21
21
|
<h2 class="offcanvas-title h5 mb-0" id="tocLabel">{{ ui.toc_title | default: "Table of Contents" }}</h2>
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
<div class="offcanvas-body">
|
|
35
|
-
|
|
35
|
+
{% comment %} Table of contents {% endcomment %}
|
|
36
36
|
<nav id="TableOfContents" role="navigation" aria-label="Table of Contents">
|
|
37
|
-
|
|
37
|
+
{% comment %} TOC title {% endcomment %}
|
|
38
38
|
<div class="mb-3 d-flex align-items-center justify-content-between gap-2">
|
|
39
39
|
<strong class="d-flex align-items-center mb-0">
|
|
40
40
|
<i class="bi bi-file-text me-2" aria-hidden="true"></i>
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
aria-controls="tocContents"
|
|
46
46
|
aria-expanded="true"
|
|
47
47
|
aria-label="Hide table of contents"
|
|
48
|
-
|
|
48
|
+
aria-keyshortcuts="t"
|
|
49
|
+
title="Hide table of contents (t)">
|
|
49
50
|
<i class="bi bi-layout-sidebar-inset-reverse" aria-hidden="true"></i>
|
|
50
51
|
<span class="visually-hidden">Hide table of contents</span>
|
|
51
52
|
</button>
|
|
@@ -197,9 +197,9 @@ unresolved targets show up as dashed red nodes so you can find dangling
|
|
|
197
197
|
links at a glance. The graph is regenerated every Jekyll build; nothing
|
|
198
198
|
runs client-side except cytoscape's force layout.
|
|
199
199
|
|
|
200
|
-
|
|
200
|
+
{% comment %} Cytoscape.js is vendored (no runtime CDN) and lazy-loaded by
|
|
201
201
|
obsidian-graph.js from window.OBSIDIAN_CONFIG.cytoscapeUrl, only on this
|
|
202
|
-
page, with an in-page recovery message if the fetch fails.
|
|
202
|
+
page, with an in-page recovery message if the fetch fails. {% endcomment %}
|
|
203
203
|
{% if site.obsidian.enabled != false %}
|
|
204
204
|
<script src="{{ '/assets/js/obsidian-graph.js' | relative_url }}?v={{ site.time | date: '%s' }}" defer></script>
|
|
205
205
|
{% endif %}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{% comment %} Feature: ZER0-086, ZER0-087 {% endcomment %}
|
|
2
|
+
{%- comment -%}
|
|
3
|
+
Component: setup/claude-session
|
|
4
|
+
Path: _includes/setup/claude-session.html
|
|
5
|
+
Purpose: The embedded AI session that rides alongside every Site
|
|
6
|
+
Builder step: connection state, provider + mode badges,
|
|
7
|
+
transcript, suggested prompts, and the composer with a Stop
|
|
8
|
+
button for long tool runs. The assistant (Claude or Grok —
|
|
9
|
+
whichever the Connect step connected) sees the whole wizard
|
|
10
|
+
state on every turn and acts on it through tools (fill fields,
|
|
11
|
+
run checks, read theme source, write or modify the project,
|
|
12
|
+
generate images, run Docker).
|
|
13
|
+
Params: none — configured by #siteBuilderConfig in setup/wizard.html
|
|
14
|
+
Depends on: Bootstrap 5.3 + Icons, assets/js/site-builder.js,
|
|
15
|
+
_sass/components/_setup-wizard.scss
|
|
16
|
+
Notes:
|
|
17
|
+
- Proxy-only. Nothing renders a credential; the panel shows a connect
|
|
18
|
+
prompt until GET {endpoint}/status answers AND the chosen provider has
|
|
19
|
+
a key (data-ready="true"), then goes live.
|
|
20
|
+
- Rendering is escape-first (a limited Markdown subset); action cards are
|
|
21
|
+
built with createElement/textContent — see ai-chat.instructions.md.
|
|
22
|
+
- role="log" + aria-live so screen readers hear replies; Escape does not
|
|
23
|
+
close the panel (it is a page region, not a dialog).
|
|
24
|
+
{%- endcomment -%}
|
|
25
|
+
|
|
26
|
+
<section class="sb-panel card" id="siteBuilderPanel" aria-labelledby="sb-title" data-state="offline" data-ready="false" data-mode="guided">
|
|
27
|
+
<div class="card-header d-flex align-items-center justify-content-between gap-2 py-2">
|
|
28
|
+
<div class="d-flex align-items-center gap-2 min-w-0">
|
|
29
|
+
<i class="bi bi-stars" aria-hidden="true"></i>
|
|
30
|
+
<h2 class="h6 mb-0 text-truncate" id="sb-title">AI session</h2>
|
|
31
|
+
<span class="badge rounded-pill text-bg-light border sb-mode-badge" id="sb-mode-badge" hidden>guided</span>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="d-flex align-items-center gap-2">
|
|
34
|
+
<span class="sb-status-badge badge rounded-pill text-bg-secondary" id="sb-status-badge" aria-live="polite">offline</span>
|
|
35
|
+
<button class="btn btn-sm btn-link text-body p-0" type="button" id="sb-clear" title="Clear the conversation" aria-label="Clear the conversation">
|
|
36
|
+
<i class="bi bi-eraser" aria-hidden="true"></i>
|
|
37
|
+
</button>
|
|
38
|
+
<button class="btn btn-sm btn-link text-body p-0" type="button" id="sb-collapse" aria-expanded="true" aria-controls="sb-body" title="Collapse">
|
|
39
|
+
<i class="bi bi-chevron-up" aria-hidden="true"></i>
|
|
40
|
+
</button>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="sb-body" id="sb-body">
|
|
45
|
+
<div class="sb-messages p-3" id="sb-messages" role="log" aria-live="polite" aria-relevant="additions">
|
|
46
|
+
<div class="sb-offline text-body-secondary small" id="sb-offline">
|
|
47
|
+
<p class="mb-1"><strong>Not connected.</strong> Start the dev proxy and connect Claude or Grok on step 1. The assistant can then read your answers, fill in the forms, check your machine, read the theme's source, write or modify your project, generate images and run the build.</p>
|
|
48
|
+
<p class="mb-0">Everything else on this page works without it.</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="sb-chips px-3 pb-2 d-flex gap-2 flex-wrap" id="sb-chips" aria-label="Suggested prompts"></div>
|
|
53
|
+
|
|
54
|
+
<form class="sb-composer p-3 pt-0" id="sb-form" autocomplete="off">
|
|
55
|
+
<label for="sb-input" class="visually-hidden">Message the assistant</label>
|
|
56
|
+
<div class="input-group">
|
|
57
|
+
<textarea class="form-control" id="sb-input" rows="1" maxlength="6000"
|
|
58
|
+
placeholder="Connect a provider to start chatting" disabled></textarea>
|
|
59
|
+
<button class="btn btn-primary" type="submit" id="sb-send" aria-label="Send" disabled>
|
|
60
|
+
<i class="bi bi-send" aria-hidden="true"></i>
|
|
61
|
+
</button>
|
|
62
|
+
<button class="btn btn-outline-danger" type="button" id="sb-stop" aria-label="Stop the current run" hidden disabled>
|
|
63
|
+
<i class="bi bi-stop-fill" aria-hidden="true"></i> Stop
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="d-flex justify-content-between align-items-center mt-1">
|
|
67
|
+
<small class="text-body-secondary sb-disclaimer" id="sb-disclaimer">The assistant sees every answer on this page. Actions ask for confirmation first.</small>
|
|
68
|
+
<small class="text-body-secondary" id="sb-context-note"></small>
|
|
69
|
+
</div>
|
|
70
|
+
</form>
|
|
71
|
+
</div>
|
|
72
|
+
</section>
|