jekyll-theme-zer0 0.16.0 → 0.17.2
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 +115 -10
- data/README.md +7 -7
- data/_data/authors.yml +2 -2
- data/_data/features.yml +676 -0
- data/_data/navigation/README.md +54 -0
- data/_data/navigation/about.yml +7 -5
- data/_data/navigation/docs.yml +77 -31
- data/_data/navigation/home.yml +4 -3
- data/_data/navigation/main.yml +16 -7
- data/_data/navigation/quickstart.yml +4 -2
- data/_includes/components/cookie-consent.html +81 -9
- data/_includes/components/js-cdn.html +2 -2
- data/_includes/components/mermaid.html +260 -14
- data/_includes/core/head.html +1 -0
- data/_includes/landing/landing-install-cards.html +8 -8
- data/_includes/landing/landing-quick-links.html +4 -4
- data/_includes/navigation/breadcrumbs.html +29 -6
- data/_includes/navigation/nav-tree.html +181 -0
- data/_includes/navigation/navbar.html +262 -9
- data/_includes/navigation/sidebar-left.html +22 -23
- data/_layouts/default.html +1 -1
- data/_layouts/landing.html +21 -21
- data/_layouts/notebook.html +4 -4
- data/_layouts/root.html +2 -2
- data/_sass/core/_nav-tree.scss +145 -0
- data/_sass/core/code-copy.scss +45 -6
- data/_sass/custom.scss +541 -1
- data/assets/js/code-copy.js +79 -13
- data/assets/js/modules/navigation/config.js +149 -0
- data/assets/js/modules/navigation/focus.js +189 -0
- data/assets/js/modules/navigation/gestures.js +179 -0
- data/assets/js/modules/navigation/index.js +227 -0
- data/assets/js/modules/navigation/keyboard.js +237 -0
- data/assets/js/modules/navigation/scroll-spy.js +219 -0
- data/assets/js/modules/navigation/sidebar-state.js +267 -0
- data/assets/js/modules/navigation/smooth-scroll.js +153 -0
- data/assets/js/ui-enhancements.js +194 -0
- data/scripts/migrate-nav-modes.sh +146 -0
- metadata +20 -7
- data/assets/js/sidebar.js +0 -511
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
path: /includes/navbar.html
|
|
4
4
|
includes:
|
|
5
5
|
purpose: Offcanvas main navigation following Bootstrap 5 best practices
|
|
6
|
+
with hover-activated dropdowns for desktop
|
|
6
7
|
-->
|
|
7
8
|
|
|
8
9
|
<!-- Navigation Links - Offcanvas -->
|
|
@@ -18,10 +19,10 @@
|
|
|
18
19
|
<div class="offcanvas-body">
|
|
19
20
|
<ul class="navbar-nav justify-content-lg-center text-start flex-grow-1">
|
|
20
21
|
{%- for link in site.data.navigation.main -%}
|
|
21
|
-
{%- assign has_children = link.
|
|
22
|
+
{%- assign has_children = link.children and link.children.size > 0 -%}
|
|
22
23
|
|
|
23
24
|
{%- if has_children -%}
|
|
24
|
-
<li class="nav-item dropdown d-flex align-items-center">
|
|
25
|
+
<li class="nav-item dropdown d-flex align-items-center nav-hover-dropdown">
|
|
25
26
|
<!-- Parent link navigates directly -->
|
|
26
27
|
<a
|
|
27
28
|
class="nav-link"
|
|
@@ -34,28 +35,32 @@
|
|
|
34
35
|
{{ link.title }}
|
|
35
36
|
</a>
|
|
36
37
|
|
|
37
|
-
<!-- Split toggle opens the dropdown -->
|
|
38
|
+
<!-- Split toggle opens the dropdown (click on mobile, hover on desktop) -->
|
|
38
39
|
<a
|
|
39
|
-
class="nav-link dropdown-toggle dropdown-toggle-split ms-
|
|
40
|
+
class="nav-link dropdown-toggle dropdown-toggle-split ms-1 px-1"
|
|
40
41
|
href="#"
|
|
41
42
|
id="dropdown-{{ link.title | slugify }}"
|
|
42
43
|
role="button"
|
|
43
44
|
data-bs-toggle="dropdown"
|
|
45
|
+
data-bs-auto-close="outside"
|
|
44
46
|
aria-expanded="false"
|
|
45
47
|
aria-label="Toggle {{ link.title }} menu"
|
|
46
48
|
>
|
|
47
49
|
<span class="visually-hidden">Toggle dropdown</span>
|
|
48
50
|
</a>
|
|
49
51
|
|
|
50
|
-
<ul class="dropdown-menu dropdown-menu-start
|
|
51
|
-
{%- for
|
|
52
|
+
<ul class="dropdown-menu dropdown-menu-start" aria-labelledby="dropdown-{{ link.title | slugify }}">
|
|
53
|
+
{%- for child in link.children -%}
|
|
52
54
|
<li>
|
|
53
55
|
<a
|
|
54
56
|
class="dropdown-item"
|
|
55
|
-
href="{{
|
|
56
|
-
{%- if
|
|
57
|
+
href="{{ child.url | relative_url }}"
|
|
58
|
+
{%- if child.url == page.url -%} aria-current="page"{%- endif -%}
|
|
57
59
|
>
|
|
58
|
-
{
|
|
60
|
+
{%- if child.icon -%}
|
|
61
|
+
<i class="{{site.default_icon}} {{ child.icon }} me-2"></i>
|
|
62
|
+
{%- endif -%}
|
|
63
|
+
{{ child.title }}
|
|
59
64
|
</a>
|
|
60
65
|
</li>
|
|
61
66
|
{%- endfor -%}
|
|
@@ -80,6 +85,168 @@
|
|
|
80
85
|
</div>
|
|
81
86
|
</div>
|
|
82
87
|
|
|
88
|
+
<!-- Styles for hover-activated dropdowns on desktop -->
|
|
89
|
+
<style>
|
|
90
|
+
/* Desktop: Show navigation inline in header (not offcanvas) */
|
|
91
|
+
@media (min-width: 992px) {
|
|
92
|
+
/* Make offcanvas behave as regular inline content on desktop */
|
|
93
|
+
#bdNavbar {
|
|
94
|
+
position: static !important;
|
|
95
|
+
transform: none !important;
|
|
96
|
+
visibility: visible !important;
|
|
97
|
+
background: transparent !important;
|
|
98
|
+
border: none !important;
|
|
99
|
+
width: auto !important;
|
|
100
|
+
flex-grow: 0 !important;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#bdNavbar .offcanvas-header {
|
|
104
|
+
display: none !important;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
#bdNavbar .offcanvas-body {
|
|
108
|
+
padding: 0 !important;
|
|
109
|
+
overflow: visible !important;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/* Horizontal nav layout */
|
|
113
|
+
#bdNavbar .navbar-nav {
|
|
114
|
+
flex-direction: row !important;
|
|
115
|
+
gap: 0.25rem;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* Dropdown positioning - ensure it appears BELOW the nav item */
|
|
119
|
+
.nav-hover-dropdown {
|
|
120
|
+
position: relative;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.nav-hover-dropdown > .dropdown-menu {
|
|
124
|
+
position: absolute;
|
|
125
|
+
top: 100% !important;
|
|
126
|
+
left: 0;
|
|
127
|
+
margin-top: 0.125rem !important;
|
|
128
|
+
min-width: 12rem;
|
|
129
|
+
z-index: 1050;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Hover behavior for dropdowns */
|
|
133
|
+
.nav-hover-dropdown:hover > .dropdown-menu {
|
|
134
|
+
display: block;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Smooth fade-in animation */
|
|
138
|
+
.nav-hover-dropdown .dropdown-menu {
|
|
139
|
+
opacity: 0;
|
|
140
|
+
visibility: hidden;
|
|
141
|
+
transition: opacity 0.15s ease-in-out, visibility 0.15s ease-in-out;
|
|
142
|
+
display: block !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.nav-hover-dropdown:hover .dropdown-menu,
|
|
146
|
+
.nav-hover-dropdown .dropdown-menu.show {
|
|
147
|
+
opacity: 1;
|
|
148
|
+
visibility: visible;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Ensure dropdown toggle caret is subtle */
|
|
152
|
+
.nav-hover-dropdown .dropdown-toggle-split {
|
|
153
|
+
padding-left: 0.25rem;
|
|
154
|
+
padding-right: 0.5rem;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.nav-hover-dropdown .dropdown-toggle-split::after {
|
|
158
|
+
vertical-align: 0.15em;
|
|
159
|
+
font-size: 0.75em;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Mobile: Standard offcanvas behavior with stacked dropdowns */
|
|
164
|
+
@media (max-width: 991.98px) {
|
|
165
|
+
#bdNavbar .navbar-nav {
|
|
166
|
+
flex-direction: column !important;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Fix mobile nav item layout - keep toggle next to link text */
|
|
170
|
+
.nav-hover-dropdown {
|
|
171
|
+
flex-wrap: wrap !important;
|
|
172
|
+
justify-content: flex-start !important;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Parent link should not stretch - stay with its content width */
|
|
176
|
+
.nav-hover-dropdown > .nav-link:first-child {
|
|
177
|
+
flex: 0 0 auto !important;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* Toggle button stays next to link */
|
|
181
|
+
.nav-hover-dropdown > .dropdown-toggle-split {
|
|
182
|
+
flex: 0 0 auto;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Rotate caret on open */
|
|
186
|
+
.nav-hover-dropdown > .dropdown-toggle-split::after {
|
|
187
|
+
transition: transform 0.25s ease;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.nav-hover-dropdown > .dropdown-toggle-split.show::after {
|
|
191
|
+
transform: rotate(180deg);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Stack dropdown below parent in mobile offcanvas - full width on new row */
|
|
195
|
+
.nav-hover-dropdown .dropdown-menu {
|
|
196
|
+
position: static !important;
|
|
197
|
+
float: none;
|
|
198
|
+
flex-basis: 100% !important;
|
|
199
|
+
width: 100%;
|
|
200
|
+
margin-top: 0;
|
|
201
|
+
border: none;
|
|
202
|
+
box-shadow: none;
|
|
203
|
+
background-color: var(--bs-tertiary-bg);
|
|
204
|
+
padding-left: 1rem;
|
|
205
|
+
/* Transition for smooth open/close */
|
|
206
|
+
max-height: 0;
|
|
207
|
+
overflow: hidden;
|
|
208
|
+
opacity: 0;
|
|
209
|
+
transition: max-height 0.3s ease, opacity 0.25s ease, padding 0.3s ease;
|
|
210
|
+
padding-top: 0;
|
|
211
|
+
padding-bottom: 0;
|
|
212
|
+
display: block !important;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* Show dropdown on click with animation */
|
|
216
|
+
.nav-hover-dropdown .dropdown-menu.show {
|
|
217
|
+
max-height: 500px;
|
|
218
|
+
opacity: 1;
|
|
219
|
+
padding-top: 0.5rem;
|
|
220
|
+
padding-bottom: 0.5rem;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Active dropdown item styling */
|
|
225
|
+
.dropdown-item[aria-current="page"] {
|
|
226
|
+
background-color: var(--bs-primary);
|
|
227
|
+
color: var(--bs-white);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.dropdown-item[aria-current="page"]:hover {
|
|
231
|
+
background-color: var(--bs-primary);
|
|
232
|
+
filter: brightness(0.9);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* Dropdown menu styling */
|
|
236
|
+
.nav-hover-dropdown .dropdown-menu {
|
|
237
|
+
border-radius: 0.375rem;
|
|
238
|
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.nav-hover-dropdown .dropdown-item {
|
|
242
|
+
padding: 0.5rem 1rem;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.nav-hover-dropdown .dropdown-item:hover {
|
|
246
|
+
background-color: var(--bs-tertiary-bg);
|
|
247
|
+
}
|
|
248
|
+
</style>
|
|
249
|
+
|
|
83
250
|
<!-- Script to handle offcanvas navigation -->
|
|
84
251
|
<script>
|
|
85
252
|
document.addEventListener('DOMContentLoaded', function() {
|
|
@@ -98,5 +265,91 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
98
265
|
}, 100);
|
|
99
266
|
});
|
|
100
267
|
});
|
|
268
|
+
|
|
269
|
+
// Desktop: Add keyboard accessibility for hover dropdowns
|
|
270
|
+
const hoverDropdowns = document.querySelectorAll('.nav-hover-dropdown');
|
|
271
|
+
hoverDropdowns.forEach(dropdown => {
|
|
272
|
+
const toggle = dropdown.querySelector('.dropdown-toggle');
|
|
273
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
274
|
+
|
|
275
|
+
// Show on focus (keyboard navigation)
|
|
276
|
+
toggle?.addEventListener('focus', () => {
|
|
277
|
+
menu?.classList.add('show');
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Hide when focus leaves the dropdown entirely
|
|
281
|
+
dropdown.addEventListener('focusout', (e) => {
|
|
282
|
+
if (!dropdown.contains(e.relatedTarget)) {
|
|
283
|
+
menu?.classList.remove('show');
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Mobile: Custom dropdown handling to prevent glitches
|
|
289
|
+
// Only apply on mobile breakpoint
|
|
290
|
+
const isMobile = () => window.innerWidth < 992;
|
|
291
|
+
|
|
292
|
+
hoverDropdowns.forEach(dropdown => {
|
|
293
|
+
const toggle = dropdown.querySelector('.dropdown-toggle-split');
|
|
294
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
295
|
+
|
|
296
|
+
if (!toggle || !menu) return;
|
|
297
|
+
|
|
298
|
+
// Prevent Bootstrap's default dropdown behavior on mobile
|
|
299
|
+
toggle.addEventListener('click', function(e) {
|
|
300
|
+
if (!isMobile()) return; // Let desktop use default behavior
|
|
301
|
+
|
|
302
|
+
e.preventDefault();
|
|
303
|
+
e.stopPropagation();
|
|
304
|
+
|
|
305
|
+
// Toggle this dropdown
|
|
306
|
+
const isOpen = menu.classList.contains('show');
|
|
307
|
+
|
|
308
|
+
if (isOpen) {
|
|
309
|
+
// Close this dropdown
|
|
310
|
+
menu.classList.remove('show');
|
|
311
|
+
toggle.classList.remove('show');
|
|
312
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
313
|
+
} else {
|
|
314
|
+
// Open this dropdown (don't close others - allow multiple open)
|
|
315
|
+
menu.classList.add('show');
|
|
316
|
+
toggle.classList.add('show');
|
|
317
|
+
toggle.setAttribute('aria-expanded', 'true');
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Close dropdowns when clicking outside on mobile
|
|
323
|
+
document.addEventListener('click', function(e) {
|
|
324
|
+
if (!isMobile()) return;
|
|
325
|
+
|
|
326
|
+
// If click is outside all dropdowns, close them all
|
|
327
|
+
const clickedInsideDropdown = e.target.closest('.nav-hover-dropdown');
|
|
328
|
+
if (!clickedInsideDropdown) {
|
|
329
|
+
hoverDropdowns.forEach(dropdown => {
|
|
330
|
+
const toggle = dropdown.querySelector('.dropdown-toggle-split');
|
|
331
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
332
|
+
if (menu && toggle) {
|
|
333
|
+
menu.classList.remove('show');
|
|
334
|
+
toggle.classList.remove('show');
|
|
335
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// Reset dropdowns when offcanvas closes
|
|
342
|
+
const offcanvasEl = document.getElementById('bdNavbar');
|
|
343
|
+
offcanvasEl?.addEventListener('hide.bs.offcanvas', function() {
|
|
344
|
+
hoverDropdowns.forEach(dropdown => {
|
|
345
|
+
const toggle = dropdown.querySelector('.dropdown-toggle-split');
|
|
346
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
347
|
+
if (menu && toggle) {
|
|
348
|
+
menu.classList.remove('show');
|
|
349
|
+
toggle.classList.remove('show');
|
|
350
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
});
|
|
101
354
|
});
|
|
102
355
|
</script>
|
|
@@ -4,27 +4,26 @@
|
|
|
4
4
|
===================================================================
|
|
5
5
|
|
|
6
6
|
File: sidebar-left.html
|
|
7
|
-
Path: _includes/sidebar-left.html
|
|
8
|
-
Purpose: Left sidebar navigation with
|
|
9
|
-
dynamic page listing, category browsing, and manual navigation
|
|
7
|
+
Path: _includes/navigation/sidebar-left.html
|
|
8
|
+
Purpose: Left sidebar navigation with three standardized content modes
|
|
10
9
|
|
|
11
10
|
Template Logic:
|
|
12
11
|
- Responsive offcanvas sidebar for mobile devices
|
|
13
12
|
- Three navigation modes based on page.sidebar.nav:
|
|
14
|
-
* "
|
|
15
|
-
* "
|
|
16
|
-
*
|
|
13
|
+
* "auto": Auto-generated folder structure from collection documents
|
|
14
|
+
* "tree": YAML-defined hierarchical navigation from _data/navigation/
|
|
15
|
+
* "categories": Category-based navigation from site categories
|
|
17
16
|
|
|
18
17
|
Dependencies:
|
|
19
|
-
- sidebar-folders.html: Dynamic folder structure generation
|
|
20
|
-
- sidebar-categories.html: Category-based navigation
|
|
21
|
-
-
|
|
18
|
+
- sidebar-folders.html: Dynamic folder structure generation (auto mode)
|
|
19
|
+
- sidebar-categories.html: Category-based navigation (categories mode)
|
|
20
|
+
- nav-tree.html: YAML-based hierarchical tree (tree mode)
|
|
22
21
|
- Bootstrap 5 offcanvas component
|
|
23
22
|
|
|
24
23
|
Navigation Modes:
|
|
25
|
-
1.
|
|
26
|
-
2.
|
|
27
|
-
3.
|
|
24
|
+
1. auto: Scans collection documents to build folder structure
|
|
25
|
+
2. tree: Uses predefined YAML navigation from _data/navigation/*.yml
|
|
26
|
+
3. categories: Groups content by Jekyll categories
|
|
28
27
|
===================================================================
|
|
29
28
|
-->
|
|
30
29
|
|
|
@@ -50,32 +49,32 @@
|
|
|
50
49
|
<div class="offcanvas-body overflow-auto">
|
|
51
50
|
|
|
52
51
|
<!-- ========================== -->
|
|
53
|
-
<!--
|
|
52
|
+
<!-- AUTO MODE: Collection Docs -->
|
|
54
53
|
<!-- ========================== -->
|
|
55
|
-
<!-- Auto-generates folder structure from
|
|
56
|
-
{% if page.sidebar.nav == "
|
|
57
|
-
<div class="list-group" id="sidebar-content">
|
|
54
|
+
<!-- Auto-generates folder structure from collection documents -->
|
|
55
|
+
{% if page.sidebar.nav == "auto" %}
|
|
56
|
+
<div class="list-group nav-tree" id="sidebar-content" data-nav-tree>
|
|
58
57
|
{% assign folders = site.pages | where_exp: "item", "item.path contains 'index.md'" | sort: 'path' %}
|
|
59
58
|
{% include navigation/sidebar-folders.html folders=folders %}
|
|
60
59
|
</div>
|
|
61
60
|
|
|
62
61
|
<!-- ========================== -->
|
|
63
|
-
<!--
|
|
62
|
+
<!-- CATEGORIES MODE -->
|
|
64
63
|
<!-- ========================== -->
|
|
65
64
|
<!-- Creates navigation from Jekyll post/page categories -->
|
|
66
|
-
{% elsif page.sidebar.nav == "
|
|
67
|
-
<div class="list-group" id="sidebar-content">
|
|
65
|
+
{% elsif page.sidebar.nav == "categories" %}
|
|
66
|
+
<div class="list-group nav-tree" id="sidebar-content" data-nav-tree>
|
|
68
67
|
{% assign categories = site.categories | sort %}
|
|
69
68
|
{% include navigation/sidebar-categories.html categories=categories %}
|
|
70
69
|
</div>
|
|
71
70
|
|
|
72
71
|
<!-- ========================== -->
|
|
73
|
-
<!--
|
|
72
|
+
<!-- TREE MODE: YAML Navigation -->
|
|
74
73
|
<!-- ========================== -->
|
|
75
|
-
<!-- Uses predefined navigation structure from _data files -->
|
|
74
|
+
<!-- Uses predefined YAML navigation structure from _data files -->
|
|
76
75
|
{% elsif page.sidebar.nav %}
|
|
77
|
-
<nav class="w-100">
|
|
78
|
-
{% include navigation/
|
|
76
|
+
<nav class="w-100 nav-tree" data-nav-tree>
|
|
77
|
+
{% include navigation/nav-tree.html nav=page.sidebar.nav %}
|
|
79
78
|
</nav>
|
|
80
79
|
{% endif %}
|
|
81
80
|
|
data/_layouts/default.html
CHANGED
|
@@ -78,7 +78,7 @@ layout: root
|
|
|
78
78
|
<!-- MAIN CONTENT BODY -->
|
|
79
79
|
<!-- =============================== -->
|
|
80
80
|
<!-- Where the actual page content is rendered -->
|
|
81
|
-
<div
|
|
81
|
+
<div class="bd-content ps-lg-2">
|
|
82
82
|
{{ content }}
|
|
83
83
|
</div>
|
|
84
84
|
</main>
|
data/_layouts/landing.html
CHANGED
|
@@ -47,29 +47,29 @@ layout: root
|
|
|
47
47
|
<!-- ================================ -->
|
|
48
48
|
<!-- HERO SECTION -->
|
|
49
49
|
<!-- ================================ -->
|
|
50
|
-
<div class="bg-primary text-white">
|
|
50
|
+
<div class="bg-primary text-white position-relative overflow-hidden">
|
|
51
51
|
<div class="container-xl py-5 px-4 px-md-5">
|
|
52
52
|
<div class="row align-items-center min-vh-50 g-4 g-lg-5">
|
|
53
|
-
<div class="col-lg-6">
|
|
54
|
-
<h1 class="display-4 fw-bold mb-3">{{ page.title }}</h1>
|
|
55
|
-
<p class="lead mb-4">{{ page.description }}</p>
|
|
56
|
-
<div class="d-flex flex-column flex-md-row gap-3">
|
|
53
|
+
<div class="col-lg-6 order-2 order-lg-1">
|
|
54
|
+
<h1 class="display-4 fw-bold mb-3 animate-on-scroll">{{ page.title }}</h1>
|
|
55
|
+
<p class="lead mb-4 animate-on-scroll" style="animation-delay: 0.1s;">{{ page.description }}</p>
|
|
56
|
+
<div class="d-flex flex-column flex-md-row gap-3 animate-on-scroll" style="animation-delay: 0.2s;">
|
|
57
57
|
<a href="#get-started" class="btn btn-light btn-lg">
|
|
58
58
|
<i class="bi bi-rocket-takeoff me-2"></i>Get Started
|
|
59
59
|
</a>
|
|
60
60
|
<a href="#features" class="btn btn-outline-light btn-lg">
|
|
61
61
|
<i class="bi bi-list-check me-2"></i>Features
|
|
62
62
|
</a>
|
|
63
|
-
<a href="{{ site.resources.github_repo }}" class="btn btn-outline-light btn-lg">
|
|
63
|
+
<a href="{{ site.resources.github_repo | default: '' | join: '' }}" class="btn btn-outline-light btn-lg" target="_blank" rel="noopener">
|
|
64
64
|
<i class="bi bi-github me-2"></i>GitHub
|
|
65
65
|
</a>
|
|
66
66
|
</div>
|
|
67
67
|
</div>
|
|
68
|
-
<div class="col-lg-6 text-center">
|
|
68
|
+
<div class="col-lg-6 text-center order-1 order-lg-2">
|
|
69
69
|
{% if page.hero_image %}
|
|
70
|
-
<img src="{{ page.hero_image }}" alt="{{ page.title }}" class="img-fluid rounded shadow-lg">
|
|
70
|
+
<img src="{{ page.hero_image }}" alt="{{ page.title }}" class="img-fluid rounded shadow-lg animate-on-scroll" loading="eager" style="animation-delay: 0.3s;">
|
|
71
71
|
{% else %}
|
|
72
|
-
<div class="bg-secondary rounded p-5 text-body">
|
|
72
|
+
<div class="bg-secondary rounded p-5 text-body animate-on-scroll">
|
|
73
73
|
<i class="bi bi-code-square display-1"></i>
|
|
74
74
|
<p class="mt-3 mb-0">Jekyll Theme</p>
|
|
75
75
|
</div>
|
|
@@ -102,37 +102,37 @@ layout: root
|
|
|
102
102
|
|
|
103
103
|
<div class="row g-4">
|
|
104
104
|
<div class="col-md-4">
|
|
105
|
-
<div class="card h-100 border-0 shadow-sm">
|
|
105
|
+
<div class="card h-100 border-0 shadow-sm feature-card">
|
|
106
106
|
<div class="card-body text-center p-4">
|
|
107
|
-
<div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
|
|
107
|
+
<div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3 feature-icon" style="width: 60px; height: 60px;">
|
|
108
108
|
<i class="bi bi-shield-check fs-4"></i>
|
|
109
109
|
</div>
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
<h5 class="card-title text-body-emphasis">Error-Free Development</h5>
|
|
111
|
+
<p class="card-text text-body-secondary">Built-in error handling and self-healing installation process ensures a smooth development experience.</p>
|
|
112
112
|
</div>
|
|
113
113
|
</div>
|
|
114
114
|
</div>
|
|
115
115
|
|
|
116
116
|
<div class="col-md-4">
|
|
117
|
-
<div class="card h-100 border-0 shadow-sm">
|
|
117
|
+
<div class="card h-100 border-0 shadow-sm feature-card">
|
|
118
118
|
<div class="card-body text-center p-4">
|
|
119
|
-
<div class="bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
|
|
119
|
+
<div class="bg-success text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3 feature-icon" style="width: 60px; height: 60px;">
|
|
120
120
|
<i class="bi bi-boxes fs-4"></i>
|
|
121
121
|
</div>
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
<h5 class="card-title text-body-emphasis">Docker-First Approach</h5>
|
|
123
|
+
<p class="card-text text-body-secondary">Cross-platform compatibility with zero local configuration. Works on Apple Silicon, Intel, and Linux.</p>
|
|
124
124
|
</div>
|
|
125
125
|
</div>
|
|
126
126
|
</div>
|
|
127
127
|
|
|
128
128
|
<div class="col-md-4">
|
|
129
|
-
<div class="card h-100 border-0 shadow-sm">
|
|
129
|
+
<div class="card h-100 border-0 shadow-sm feature-card">
|
|
130
130
|
<div class="card-body text-center p-4">
|
|
131
|
-
<div class="bg-info text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
|
|
131
|
+
<div class="bg-info text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3 feature-icon" style="width: 60px; height: 60px;">
|
|
132
132
|
<i class="bi bi-lightning-charge fs-4"></i>
|
|
133
133
|
</div>
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
<h5 class="card-title text-body-emphasis">AI-Powered Setup</h5>
|
|
135
|
+
<p class="card-text text-body-secondary">Intelligent installation automation that detects and fixes common issues automatically.</p>
|
|
136
136
|
</div>
|
|
137
137
|
</div>
|
|
138
138
|
</div>
|
data/_layouts/notebook.html
CHANGED
|
@@ -95,7 +95,7 @@ layout: default
|
|
|
95
95
|
{% if page.tags and page.tags.size > 0 %}
|
|
96
96
|
<div class="notebook-tags mb-3">
|
|
97
97
|
{% for tag in page.tags %}
|
|
98
|
-
<a href="{{
|
|
98
|
+
<a href="{{ '/tags/' | relative_url }}#{{ tag | slugify }}" class="badge bg-secondary text-decoration-none me-1">
|
|
99
99
|
{{ tag }}
|
|
100
100
|
</a>
|
|
101
101
|
{% endfor %}
|
|
@@ -107,7 +107,7 @@ layout: default
|
|
|
107
107
|
<div class="notebook-categories mb-3">
|
|
108
108
|
<i class="bi bi-folder me-1"></i>
|
|
109
109
|
{% for category in page.categories %}
|
|
110
|
-
<a href="{{
|
|
110
|
+
<a href="{{ '/categories/' | relative_url }}#{{ category | slugify }}" class="text-decoration-none">
|
|
111
111
|
{{ category }}
|
|
112
112
|
</a>
|
|
113
113
|
{% unless forloop.last %}<span class="mx-1">/</span>{% endunless %}
|
|
@@ -148,7 +148,7 @@ layout: default
|
|
|
148
148
|
class="btn btn-outline-primary btn-sm" target="_blank" rel="noopener noreferrer">
|
|
149
149
|
<i class="bi bi-linkedin"></i> LinkedIn
|
|
150
150
|
</a>
|
|
151
|
-
<a href="mailto
|
|
151
|
+
<a href="mailto:{{ site.email | escape }}?subject={{ page.title | uri_escape }}&body={{ site.url | append: page.url | uri_escape }}"
|
|
152
152
|
class="btn btn-outline-primary btn-sm">
|
|
153
153
|
<i class="bi bi-envelope"></i> Email
|
|
154
154
|
</a>
|
|
@@ -158,7 +158,7 @@ layout: default
|
|
|
158
158
|
|
|
159
159
|
<!-- Download Original Notebook -->
|
|
160
160
|
<div class="download-notebook mb-4">
|
|
161
|
-
<a href="{{ site.
|
|
161
|
+
<a href="https://raw.githubusercontent.com/{{ site.repository }}/{{ site.branch | default: 'main' }}/pages/_notebooks/{{ page.slug }}.ipynb"
|
|
162
162
|
class="btn btn-outline-secondary btn-sm" download>
|
|
163
163
|
<i class="bi bi-download"></i> Download Original Notebook
|
|
164
164
|
</a>
|
data/_layouts/root.html
CHANGED
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
<!-- ======================== -->
|
|
66
66
|
<!-- MAIN CONTENT AREA -->
|
|
67
67
|
<!-- ======================== -->
|
|
68
|
-
<!--
|
|
69
|
-
<div>
|
|
68
|
+
<!-- Skip-link target: keep a single, consistent #main-content anchor site-wide -->
|
|
69
|
+
<div id="main-content">
|
|
70
70
|
{{ content }}
|
|
71
71
|
</div>
|
|
72
72
|
|