jekyll-theme-zer0 0.20.3 → 0.21.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.
@@ -126,40 +126,44 @@
126
126
  <!-- ========================== -->
127
127
  <!-- UTILITY CONTROLS -->
128
128
  <!-- ========================== -->
129
-
130
- <!-- Search Modal Toggle -->
131
- <button
132
- class="btn nav-search-button"
133
- type="button"
134
- data-bs-toggle="modal"
135
- data-bs-target="#siteSearchModal"
136
- data-search-toggle
137
- aria-label="Open search"
138
- >
139
- <i class="{{site.default_icon}} bi-search"></i>
140
- <span class="d-none d-lg-inline ms-1">Search</span>
141
- </button>
142
-
143
- <!-- Settings Modal Toggle -->
144
- <div class="btn d-none d-lg-flex nav-settings"
145
- data-bs-toggle="modal"
146
- data-bs-target="#info-section"
147
- aria-expanded="false"
148
- aria-controls="#info-section"
149
- role="button">
150
- <i type="button" class="{{site.default_icon}} bi-gear"></i>
151
- </div>
129
+ <div class="navbar-utility-controls d-flex align-items-center">
130
+ <!-- Search Modal Toggle -->
131
+ <button
132
+ class="btn nav-search-button"
133
+ type="button"
134
+ data-bs-toggle="modal"
135
+ data-bs-target="#siteSearchModal"
136
+ data-search-toggle
137
+ aria-label="Open search"
138
+ title="Search"
139
+ >
140
+ <i class="{{site.default_icon}} bi-search"></i>
141
+ <span class="nav-link-text d-none d-xl-inline ms-1">Search</span>
142
+ </button>
152
143
 
153
- <!-- Navigation Menu Toggle - Mobile view -->
154
- <div class="bd-navbar-toggle">
155
- <button class="navbar-toggler p-2"
156
- type="button"
157
- data-bs-toggle="offcanvas"
158
- data-bs-target="#bdNavbar"
159
- aria-controls="bdNavbar"
160
- aria-label="Toggle navigation">
161
- <span class="bi bi-three-dots"></span>
144
+ <!-- Settings Modal Toggle -->
145
+ <button
146
+ class="btn nav-settings-button d-none d-lg-inline-flex"
147
+ type="button"
148
+ data-bs-toggle="modal"
149
+ data-bs-target="#info-section"
150
+ aria-label="Settings"
151
+ title="Settings"
152
+ >
153
+ <i class="{{site.default_icon}} bi-gear"></i>
162
154
  </button>
155
+
156
+ <!-- Navigation Menu Toggle - Mobile view -->
157
+ <div class="bd-navbar-toggle d-lg-none">
158
+ <button class="navbar-toggler p-2"
159
+ type="button"
160
+ data-bs-toggle="offcanvas"
161
+ data-bs-target="#bdNavbar"
162
+ aria-controls="bdNavbar"
163
+ aria-label="Toggle navigation">
164
+ <span class="bi bi-three-dots"></span>
165
+ </button>
166
+ </div>
163
167
  </div>
164
168
  </nav>
165
169
  </div>
@@ -34,11 +34,12 @@
34
34
  class="nav-link"
35
35
  href="{{ link.url | relative_url }}"
36
36
  {%- if link.url == page.url -%} aria-current="page"{%- endif -%}
37
+ title="{{ link.title }}"
37
38
  >
38
39
  {%- if link.icon -%}
39
- <i class="{{site.default_icon}} {{ link.icon }} me-2"></i>
40
+ <i class="{{site.default_icon}} {{ link.icon }}"></i>
40
41
  {%- endif -%}
41
- {{ link.title }}
42
+ <span class="nav-link-text">{{ link.title }}</span>
42
43
  </a>
43
44
 
44
45
  <!-- Split toggle opens the dropdown (click on mobile, hover on desktop) -->
@@ -78,11 +79,12 @@
78
79
  class="nav-link"
79
80
  href="{{ link.url | relative_url }}"
80
81
  {%- if link.url == page.url -%} aria-current="page"{%- endif -%}
82
+ title="{{ link.title }}"
81
83
  >
82
84
  {%- if link.icon -%}
83
- <i class="{{site.default_icon}} {{ link.icon }} me-2"></i>
85
+ <i class="{{site.default_icon}} {{ link.icon }}"></i>
84
86
  {%- endif -%}
85
- {{ link.title }}
87
+ <span class="nav-link-text">{{ link.title }}</span>
86
88
  </a>
87
89
  </li>
88
90
  {%- endif -%}
@@ -116,271 +118,8 @@
116
118
  </div>
117
119
  </div>
118
120
 
119
- <!-- Styles for hover-activated dropdowns on desktop -->
120
- <style>
121
- /* Desktop: Show navigation inline in header (not offcanvas) */
122
- @media (min-width: 992px) {
123
- /* Make offcanvas behave as regular inline content on desktop */
124
- #bdNavbar {
125
- position: static !important;
126
- transform: none !important;
127
- visibility: visible !important;
128
- background: transparent !important;
129
- border: none !important;
130
- width: auto !important;
131
- flex-grow: 0 !important;
132
- }
133
-
134
- #bdNavbar .offcanvas-header {
135
- display: none !important;
136
- }
137
-
138
- #bdNavbar .offcanvas-body {
139
- padding: 0 !important;
140
- overflow: visible !important;
141
- }
142
-
143
- /* Horizontal nav layout */
144
- #bdNavbar .navbar-nav {
145
- flex-direction: row !important;
146
- gap: 0.25rem;
147
- }
148
-
149
- /* Dropdown positioning - ensure it appears BELOW the nav item */
150
- .nav-hover-dropdown {
151
- position: relative;
152
- }
153
-
154
- .nav-hover-dropdown > .dropdown-menu {
155
- position: absolute;
156
- top: 100% !important;
157
- left: 0;
158
- margin-top: 0.125rem !important;
159
- min-width: 12rem;
160
- z-index: 1050;
161
- }
162
-
163
- /* Hover behavior for dropdowns */
164
- .nav-hover-dropdown:hover > .dropdown-menu {
165
- display: block;
166
- }
167
-
168
- /* Smooth fade-in animation */
169
- .nav-hover-dropdown .dropdown-menu {
170
- opacity: 0;
171
- visibility: hidden;
172
- transition: opacity 0.15s ease-in-out, visibility 0.15s ease-in-out;
173
- display: block !important;
174
- }
175
-
176
- .nav-hover-dropdown:hover .dropdown-menu,
177
- .nav-hover-dropdown .dropdown-menu.show {
178
- opacity: 1;
179
- visibility: visible;
180
- }
181
-
182
- /* Ensure dropdown toggle caret is subtle */
183
- .nav-hover-dropdown .dropdown-toggle-split {
184
- padding-left: 0.25rem;
185
- padding-right: 0.5rem;
186
- }
187
-
188
- .nav-hover-dropdown .dropdown-toggle-split::after {
189
- vertical-align: 0.15em;
190
- font-size: 0.75em;
191
- }
192
- }
193
-
194
- /* Mobile: Standard offcanvas behavior with stacked dropdowns */
195
- @media (max-width: 991.98px) {
196
- #bdNavbar .navbar-nav {
197
- flex-direction: column !important;
198
- }
199
-
200
- /* Fix mobile nav item layout - keep toggle next to link text */
201
- .nav-hover-dropdown {
202
- flex-wrap: wrap !important;
203
- justify-content: flex-start !important;
204
- }
205
-
206
- /* Parent link should not stretch - stay with its content width */
207
- .nav-hover-dropdown > .nav-link:first-child {
208
- flex: 0 0 auto !important;
209
- }
210
-
211
- /* Toggle button stays next to link */
212
- .nav-hover-dropdown > .dropdown-toggle-split {
213
- flex: 0 0 auto;
214
- }
215
-
216
- /* Rotate caret on open */
217
- .nav-hover-dropdown > .dropdown-toggle-split::after {
218
- transition: transform 0.25s ease;
219
- }
220
-
221
- .nav-hover-dropdown > .dropdown-toggle-split.show::after {
222
- transform: rotate(180deg);
223
- }
224
-
225
- /* Stack dropdown below parent in mobile offcanvas - full width on new row */
226
- .nav-hover-dropdown .dropdown-menu {
227
- position: static !important;
228
- float: none;
229
- flex-basis: 100% !important;
230
- width: 100%;
231
- margin-top: 0;
232
- border: none;
233
- box-shadow: none;
234
- background-color: var(--bs-tertiary-bg);
235
- padding-left: 1rem;
236
- /* Transition for smooth open/close */
237
- max-height: 0;
238
- overflow: hidden;
239
- opacity: 0;
240
- transition: max-height 0.3s ease, opacity 0.25s ease, padding 0.3s ease;
241
- padding-top: 0;
242
- padding-bottom: 0;
243
- display: block !important;
244
- }
245
-
246
- /* Show dropdown on click with animation */
247
- .nav-hover-dropdown .dropdown-menu.show {
248
- max-height: 500px;
249
- opacity: 1;
250
- padding-top: 0.5rem;
251
- padding-bottom: 0.5rem;
252
- }
253
- }
254
-
255
- /* Active dropdown item styling */
256
- .dropdown-item[aria-current="page"] {
257
- background-color: var(--bs-primary);
258
- color: var(--bs-white);
259
- }
260
-
261
- .dropdown-item[aria-current="page"]:hover {
262
- background-color: var(--bs-primary);
263
- filter: brightness(0.9);
264
- }
265
-
266
- /* Dropdown menu styling */
267
- .nav-hover-dropdown .dropdown-menu {
268
- border-radius: 0.375rem;
269
- box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
270
- }
271
-
272
- .nav-hover-dropdown .dropdown-item {
273
- padding: 0.5rem 1rem;
274
- }
275
-
276
- .nav-hover-dropdown .dropdown-item:hover {
277
- background-color: var(--bs-tertiary-bg);
278
- }
279
- </style>
280
-
281
- <!-- Script to handle offcanvas navigation -->
282
- <script>
283
- document.addEventListener('DOMContentLoaded', function() {
284
- // Get all navigation links in the offcanvas
285
- const offcanvasLinks = document.querySelectorAll('#bdNavbar .nav-link[href]:not(.dropdown-toggle), #bdNavbar .dropdown-item[href]');
286
-
287
- offcanvasLinks.forEach(link => {
288
- link.addEventListener('click', function(e) {
289
- // Allow the navigation to happen
290
- // Then close the offcanvas after a brief delay
291
- setTimeout(() => {
292
- const offcanvas = bootstrap.Offcanvas.getInstance(document.getElementById('bdNavbar'));
293
- if (offcanvas) {
294
- offcanvas.hide();
295
- }
296
- }, 100);
297
- });
298
- });
299
-
300
- // Desktop: Add keyboard accessibility for hover dropdowns
301
- const hoverDropdowns = document.querySelectorAll('.nav-hover-dropdown');
302
- hoverDropdowns.forEach(dropdown => {
303
- const toggle = dropdown.querySelector('.dropdown-toggle');
304
- const menu = dropdown.querySelector('.dropdown-menu');
305
-
306
- // Show on focus (keyboard navigation)
307
- toggle?.addEventListener('focus', () => {
308
- menu?.classList.add('show');
309
- });
310
-
311
- // Hide when focus leaves the dropdown entirely
312
- dropdown.addEventListener('focusout', (e) => {
313
- if (!dropdown.contains(e.relatedTarget)) {
314
- menu?.classList.remove('show');
315
- }
316
- });
317
- });
318
-
319
- // Mobile: Custom dropdown handling to prevent glitches
320
- // Only apply on mobile breakpoint
321
- const isMobile = () => window.innerWidth < 992;
322
-
323
- hoverDropdowns.forEach(dropdown => {
324
- const toggle = dropdown.querySelector('.dropdown-toggle-split');
325
- const menu = dropdown.querySelector('.dropdown-menu');
326
-
327
- if (!toggle || !menu) return;
328
-
329
- // Prevent Bootstrap's default dropdown behavior on mobile
330
- toggle.addEventListener('click', function(e) {
331
- if (!isMobile()) return; // Let desktop use default behavior
332
-
333
- e.preventDefault();
334
- e.stopPropagation();
335
-
336
- // Toggle this dropdown
337
- const isOpen = menu.classList.contains('show');
338
-
339
- if (isOpen) {
340
- // Close this dropdown
341
- menu.classList.remove('show');
342
- toggle.classList.remove('show');
343
- toggle.setAttribute('aria-expanded', 'false');
344
- } else {
345
- // Open this dropdown (don't close others - allow multiple open)
346
- menu.classList.add('show');
347
- toggle.classList.add('show');
348
- toggle.setAttribute('aria-expanded', 'true');
349
- }
350
- });
351
- });
352
-
353
- // Close dropdowns when clicking outside on mobile
354
- document.addEventListener('click', function(e) {
355
- if (!isMobile()) return;
356
-
357
- // If click is outside all dropdowns, close them all
358
- const clickedInsideDropdown = e.target.closest('.nav-hover-dropdown');
359
- if (!clickedInsideDropdown) {
360
- hoverDropdowns.forEach(dropdown => {
361
- const toggle = dropdown.querySelector('.dropdown-toggle-split');
362
- const menu = dropdown.querySelector('.dropdown-menu');
363
- if (menu && toggle) {
364
- menu.classList.remove('show');
365
- toggle.classList.remove('show');
366
- toggle.setAttribute('aria-expanded', 'false');
367
- }
368
- });
369
- }
370
- });
371
-
372
- // Reset dropdowns when offcanvas closes
373
- const offcanvasEl = document.getElementById('bdNavbar');
374
- offcanvasEl?.addEventListener('hide.bs.offcanvas', function() {
375
- hoverDropdowns.forEach(dropdown => {
376
- const toggle = dropdown.querySelector('.dropdown-toggle-split');
377
- const menu = dropdown.querySelector('.dropdown-menu');
378
- if (menu && toggle) {
379
- menu.classList.remove('show');
380
- toggle.classList.remove('show');
381
- toggle.setAttribute('aria-expanded', 'false');
382
- }
383
- });
384
- });
385
- });
386
- </script>
121
+ <!--
122
+ Navigation styles are now in _sass/core/_navbar.scss
123
+ Navigation scripts are now in assets/js/navigation.js
124
+ These are loaded automatically via the theme's asset pipeline
125
+ -->