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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +79 -0
- data/_includes/components/dev-shortcuts.html +97 -50
- data/_includes/components/env-switcher.html +212 -0
- data/_includes/components/info-section.html +173 -32
- data/_includes/components/js-cdn.html +3 -0
- data/_includes/components/theme-info.html +65 -273
- data/_includes/core/header.html +36 -32
- data/_includes/navigation/navbar.html +11 -272
- data/_sass/core/_navbar.scss +390 -0
- data/_sass/custom.scss +3 -0
- data/assets/js/navigation.js +206 -0
- data/scripts/docker-publish +238 -0
- data/scripts/lib/common.sh +55 -0
- data/scripts/lib/gem.sh +7 -0
- data/scripts/lib/git.sh +3 -1
- data/scripts/lib/validation.sh +9 -1
- data/scripts/lib/version.sh +34 -0
- metadata +6 -2
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// NAVBAR STYLES - Zer0-Mistakes Theme Navigation
|
|
3
|
+
// ==============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Extracted from navbar.html inline styles for better maintainability
|
|
6
|
+
// Breakpoints:
|
|
7
|
+
// - Desktop XL >= 1200px (full labels)
|
|
8
|
+
// - Desktop LG 992px-1199px (icons only, labels hidden)
|
|
9
|
+
// - Mobile < 992px (offcanvas)
|
|
10
|
+
// ==============================================================================
|
|
11
|
+
|
|
12
|
+
// -----------------------------------------------------------------------------
|
|
13
|
+
// Compact Desktop Navigation (992px - 1199px)
|
|
14
|
+
// Hide labels, show icons only to prevent overflow
|
|
15
|
+
// -----------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
@media (min-width: 992px) and (max-width: 1199.98px) {
|
|
18
|
+
// Hide nav link text labels, keep icons visible
|
|
19
|
+
#bdNavbar .nav-link .nav-link-text {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Adjust icon margin when text is hidden
|
|
24
|
+
#bdNavbar .nav-link i {
|
|
25
|
+
margin-right: 0 !important;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Compact nav item spacing
|
|
29
|
+
#bdNavbar .navbar-nav {
|
|
30
|
+
gap: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#bdNavbar .nav-link {
|
|
34
|
+
padding: 0.5rem 0.5rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Dropdown toggle needs less space
|
|
38
|
+
.nav-hover-dropdown .dropdown-toggle-split {
|
|
39
|
+
padding-left: 0;
|
|
40
|
+
padding-right: 0.25rem;
|
|
41
|
+
|
|
42
|
+
&::after {
|
|
43
|
+
font-size: 0.65em;
|
|
44
|
+
margin-left: 0;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Keep Search button label hidden
|
|
49
|
+
.nav-search-button .d-lg-inline {
|
|
50
|
+
display: none !important;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.nav-search-button {
|
|
54
|
+
padding: 0.5rem 0.5rem !important;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Hide site subtitle at compact breakpoint
|
|
58
|
+
.site-subtitle {
|
|
59
|
+
display: none !important;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Reduce brand group spacing
|
|
63
|
+
.navbar-brand-group {
|
|
64
|
+
gap: 0.5rem !important;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Compact home links
|
|
68
|
+
.navbar-home-links .btn {
|
|
69
|
+
padding: 0.375rem 0.5rem;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// -----------------------------------------------------------------------------
|
|
74
|
+
// Full Desktop Navigation (>= 1200px)
|
|
75
|
+
// Show full labels with icons
|
|
76
|
+
// -----------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
@media (min-width: 1200px) {
|
|
79
|
+
#bdNavbar .nav-link .nav-link-text {
|
|
80
|
+
display: inline;
|
|
81
|
+
margin-left: 0.5rem;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
#bdNavbar .nav-link i {
|
|
85
|
+
margin-right: 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// -----------------------------------------------------------------------------
|
|
90
|
+
// Utility Controls (Search, Settings)
|
|
91
|
+
// -----------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
.navbar-utility-controls {
|
|
94
|
+
gap: 0.25rem;
|
|
95
|
+
margin-left: auto;
|
|
96
|
+
|
|
97
|
+
.nav-search-button,
|
|
98
|
+
.nav-settings-button {
|
|
99
|
+
display: inline-flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: center;
|
|
102
|
+
padding: 0.5rem 0.75rem;
|
|
103
|
+
border: none;
|
|
104
|
+
background: transparent;
|
|
105
|
+
color: var(--bs-body-color);
|
|
106
|
+
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out;
|
|
107
|
+
|
|
108
|
+
&:hover {
|
|
109
|
+
color: var(--bs-primary);
|
|
110
|
+
background-color: var(--bs-tertiary-bg);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
i {
|
|
114
|
+
font-size: 1.1rem;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (min-width: 992px) and (max-width: 1199.98px) {
|
|
120
|
+
.navbar-utility-controls {
|
|
121
|
+
gap: 0;
|
|
122
|
+
|
|
123
|
+
.nav-search-button,
|
|
124
|
+
.nav-settings-button {
|
|
125
|
+
padding: 0.5rem;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.nav-link-text {
|
|
129
|
+
display: none !important;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@media (max-width: 991.98px) {
|
|
135
|
+
.navbar-utility-controls {
|
|
136
|
+
gap: 0;
|
|
137
|
+
|
|
138
|
+
.nav-search-button {
|
|
139
|
+
padding: 0.5rem;
|
|
140
|
+
width: 2.5rem;
|
|
141
|
+
height: 2.5rem;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.nav-link-text {
|
|
145
|
+
display: none !important;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// -----------------------------------------------------------------------------
|
|
151
|
+
// Desktop Navigation (>= 992px) - Common styles
|
|
152
|
+
// -----------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
@media (min-width: 992px) {
|
|
155
|
+
// Convert offcanvas to inline navigation on desktop
|
|
156
|
+
#bdNavbar {
|
|
157
|
+
position: static !important;
|
|
158
|
+
transform: none !important;
|
|
159
|
+
visibility: visible !important;
|
|
160
|
+
background: transparent !important;
|
|
161
|
+
border: none !important;
|
|
162
|
+
width: auto !important;
|
|
163
|
+
flex-grow: 0 !important;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
#bdNavbar .offcanvas-header {
|
|
167
|
+
display: none !important;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
#bdNavbar .offcanvas-body {
|
|
171
|
+
padding: 0 !important;
|
|
172
|
+
overflow: visible !important;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
#bdNavbar .navbar-nav {
|
|
176
|
+
flex-direction: row !important;
|
|
177
|
+
gap: 0.25rem;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Dropdown positioning
|
|
181
|
+
.nav-hover-dropdown {
|
|
182
|
+
position: relative;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.nav-hover-dropdown > .dropdown-menu {
|
|
186
|
+
position: absolute;
|
|
187
|
+
top: 100% !important;
|
|
188
|
+
left: 0;
|
|
189
|
+
margin-top: 0.125rem !important;
|
|
190
|
+
min-width: 12rem;
|
|
191
|
+
z-index: 1050;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Hover behavior
|
|
195
|
+
.nav-hover-dropdown:hover > .dropdown-menu {
|
|
196
|
+
display: block;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.nav-hover-dropdown .dropdown-menu {
|
|
200
|
+
opacity: 0;
|
|
201
|
+
visibility: hidden;
|
|
202
|
+
transition: opacity 0.15s ease-in-out, visibility 0.15s ease-in-out;
|
|
203
|
+
display: block !important;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.nav-hover-dropdown:hover .dropdown-menu,
|
|
207
|
+
.nav-hover-dropdown .dropdown-menu.show {
|
|
208
|
+
opacity: 1;
|
|
209
|
+
visibility: visible;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.nav-hover-dropdown .dropdown-toggle-split {
|
|
213
|
+
padding-left: 0.25rem;
|
|
214
|
+
padding-right: 0.5rem;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.nav-hover-dropdown .dropdown-toggle-split::after {
|
|
218
|
+
vertical-align: 0.15em;
|
|
219
|
+
font-size: 0.75em;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// -----------------------------------------------------------------------------
|
|
224
|
+
// Mobile Navigation (< 992px)
|
|
225
|
+
// -----------------------------------------------------------------------------
|
|
226
|
+
|
|
227
|
+
@media (max-width: 991.98px) {
|
|
228
|
+
#bdNavbar .navbar-nav {
|
|
229
|
+
flex-direction: column !important;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.nav-hover-dropdown {
|
|
233
|
+
flex-wrap: wrap !important;
|
|
234
|
+
justify-content: flex-start !important;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.nav-hover-dropdown > .nav-link:first-child {
|
|
238
|
+
flex: 0 0 auto !important;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.nav-hover-dropdown > .dropdown-toggle-split {
|
|
242
|
+
flex: 0 0 auto;
|
|
243
|
+
// Minimum touch target (44px WCAG recommendation)
|
|
244
|
+
min-width: 44px;
|
|
245
|
+
min-height: 44px;
|
|
246
|
+
display: flex;
|
|
247
|
+
align-items: center;
|
|
248
|
+
justify-content: center;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.nav-hover-dropdown > .dropdown-toggle-split::after {
|
|
252
|
+
transition: transform 0.25s ease;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.nav-hover-dropdown > .dropdown-toggle-split.show::after {
|
|
256
|
+
transform: rotate(180deg);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.nav-hover-dropdown .dropdown-menu {
|
|
260
|
+
position: static !important;
|
|
261
|
+
float: none;
|
|
262
|
+
flex-basis: 100% !important;
|
|
263
|
+
width: 100%;
|
|
264
|
+
margin-top: 0;
|
|
265
|
+
border: none;
|
|
266
|
+
box-shadow: none;
|
|
267
|
+
background-color: var(--bs-tertiary-bg);
|
|
268
|
+
padding-left: 1rem;
|
|
269
|
+
max-height: 0;
|
|
270
|
+
overflow: hidden;
|
|
271
|
+
opacity: 0;
|
|
272
|
+
transition: max-height 0.3s ease, opacity 0.25s ease, padding 0.3s ease;
|
|
273
|
+
padding-top: 0;
|
|
274
|
+
padding-bottom: 0;
|
|
275
|
+
display: block !important;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.nav-hover-dropdown .dropdown-menu.show {
|
|
279
|
+
max-height: 500px;
|
|
280
|
+
opacity: 1;
|
|
281
|
+
padding-top: 0.5rem;
|
|
282
|
+
padding-bottom: 0.5rem;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Larger touch targets for nav items
|
|
286
|
+
#bdNavbar .nav-link {
|
|
287
|
+
padding: 0.75rem 1rem;
|
|
288
|
+
min-height: 48px;
|
|
289
|
+
display: flex;
|
|
290
|
+
align-items: center;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Better close button
|
|
294
|
+
#bdNavbar .offcanvas-header .btn-close {
|
|
295
|
+
width: 44px;
|
|
296
|
+
height: 44px;
|
|
297
|
+
padding: 0;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// -----------------------------------------------------------------------------
|
|
302
|
+
// Active States
|
|
303
|
+
// -----------------------------------------------------------------------------
|
|
304
|
+
|
|
305
|
+
.dropdown-item[aria-current="page"] {
|
|
306
|
+
background-color: var(--bs-primary);
|
|
307
|
+
color: var(--bs-white);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.dropdown-item[aria-current="page"]:hover {
|
|
311
|
+
background-color: var(--bs-primary);
|
|
312
|
+
filter: brightness(0.9);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// -----------------------------------------------------------------------------
|
|
316
|
+
// Dropdown Styling
|
|
317
|
+
// -----------------------------------------------------------------------------
|
|
318
|
+
|
|
319
|
+
.nav-hover-dropdown .dropdown-menu {
|
|
320
|
+
border-radius: 0.375rem;
|
|
321
|
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.nav-hover-dropdown .dropdown-item {
|
|
325
|
+
padding: 0.5rem 1rem;
|
|
326
|
+
min-height: 44px;
|
|
327
|
+
display: flex;
|
|
328
|
+
align-items: center;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.nav-hover-dropdown .dropdown-item:hover {
|
|
332
|
+
background-color: var(--bs-tertiary-bg);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// -----------------------------------------------------------------------------
|
|
336
|
+
// Site Title Responsiveness
|
|
337
|
+
// -----------------------------------------------------------------------------
|
|
338
|
+
|
|
339
|
+
.site-title-text {
|
|
340
|
+
display: inline-block;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@media (max-width: 767.98px) {
|
|
344
|
+
.site-title-text {
|
|
345
|
+
max-width: 55vw;
|
|
346
|
+
overflow: hidden;
|
|
347
|
+
text-overflow: ellipsis;
|
|
348
|
+
white-space: nowrap;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
@media (max-width: 575.98px) {
|
|
353
|
+
.site-title-text {
|
|
354
|
+
max-width: 45vw;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// -----------------------------------------------------------------------------
|
|
359
|
+
// Info Section Modal Tabs
|
|
360
|
+
// -----------------------------------------------------------------------------
|
|
361
|
+
|
|
362
|
+
#info-section {
|
|
363
|
+
.nav-tabs {
|
|
364
|
+
border-bottom: 2px solid var(--bs-border-color);
|
|
365
|
+
|
|
366
|
+
.nav-link {
|
|
367
|
+
border: none;
|
|
368
|
+
border-bottom: 3px solid transparent;
|
|
369
|
+
color: var(--bs-secondary-color);
|
|
370
|
+
padding: 0.75rem 1rem;
|
|
371
|
+
font-weight: 500;
|
|
372
|
+
transition: color 0.2s ease, border-color 0.2s ease;
|
|
373
|
+
|
|
374
|
+
&:hover {
|
|
375
|
+
color: var(--bs-primary);
|
|
376
|
+
border-bottom-color: var(--bs-primary-bg-subtle);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
&.active {
|
|
380
|
+
color: var(--bs-primary);
|
|
381
|
+
border-bottom-color: var(--bs-primary);
|
|
382
|
+
background: transparent;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.tab-content {
|
|
388
|
+
padding-top: 1rem;
|
|
389
|
+
}
|
|
390
|
+
}
|
data/_sass/custom.scss
CHANGED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ==============================================================================
|
|
3
|
+
* NAVIGATION SCRIPTS - Zer0-Mistakes Theme
|
|
4
|
+
* ==============================================================================
|
|
5
|
+
*
|
|
6
|
+
* Handles offcanvas navigation, dropdowns, and mobile interactions
|
|
7
|
+
* Extracted from navbar.html inline scripts
|
|
8
|
+
* ==============================================================================
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
(function() {
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const MOBILE_BREAKPOINT = 992;
|
|
15
|
+
|
|
16
|
+
function isMobile() {
|
|
17
|
+
return window.innerWidth < MOBILE_BREAKPOINT;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Initialize navigation when DOM is ready
|
|
22
|
+
*/
|
|
23
|
+
function initNavigation() {
|
|
24
|
+
setupOffcanvasLinkClose();
|
|
25
|
+
setupKeyboardAccessibility();
|
|
26
|
+
setupMobileDropdowns();
|
|
27
|
+
setupOutsideClickClose();
|
|
28
|
+
setupOffcanvasReset();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Close offcanvas when navigation link is clicked
|
|
33
|
+
*/
|
|
34
|
+
function setupOffcanvasLinkClose() {
|
|
35
|
+
const offcanvasEl = document.getElementById('bdNavbar');
|
|
36
|
+
if (!offcanvasEl) return;
|
|
37
|
+
|
|
38
|
+
const navLinks = offcanvasEl.querySelectorAll(
|
|
39
|
+
'.nav-link[href]:not(.dropdown-toggle), .dropdown-item[href]'
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
navLinks.forEach(link => {
|
|
43
|
+
link.addEventListener('click', () => {
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
const offcanvas = bootstrap.Offcanvas.getInstance(offcanvasEl);
|
|
46
|
+
if (offcanvas) {
|
|
47
|
+
offcanvas.hide();
|
|
48
|
+
}
|
|
49
|
+
}, 100);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Desktop keyboard accessibility for hover dropdowns
|
|
56
|
+
*/
|
|
57
|
+
function setupKeyboardAccessibility() {
|
|
58
|
+
const dropdowns = document.querySelectorAll('.nav-hover-dropdown');
|
|
59
|
+
|
|
60
|
+
dropdowns.forEach(dropdown => {
|
|
61
|
+
const toggle = dropdown.querySelector('.dropdown-toggle');
|
|
62
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
63
|
+
|
|
64
|
+
if (!toggle || !menu) return;
|
|
65
|
+
|
|
66
|
+
// Show on focus
|
|
67
|
+
toggle.addEventListener('focus', () => {
|
|
68
|
+
if (!isMobile()) {
|
|
69
|
+
menu.classList.add('show');
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Hide when focus leaves dropdown
|
|
74
|
+
dropdown.addEventListener('focusout', (e) => {
|
|
75
|
+
if (!dropdown.contains(e.relatedTarget)) {
|
|
76
|
+
menu.classList.remove('show');
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Arrow key navigation
|
|
81
|
+
dropdown.addEventListener('keydown', (e) => {
|
|
82
|
+
if (!menu.classList.contains('show')) return;
|
|
83
|
+
|
|
84
|
+
const items = menu.querySelectorAll('.dropdown-item:not(:disabled)');
|
|
85
|
+
const currentIndex = Array.from(items).indexOf(document.activeElement);
|
|
86
|
+
|
|
87
|
+
if (e.key === 'ArrowDown') {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
items[(currentIndex + 1) % items.length]?.focus();
|
|
90
|
+
} else if (e.key === 'ArrowUp') {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
items[(currentIndex - 1 + items.length) % items.length]?.focus();
|
|
93
|
+
} else if (e.key === 'Escape') {
|
|
94
|
+
e.preventDefault();
|
|
95
|
+
menu.classList.remove('show');
|
|
96
|
+
toggle.focus();
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Mobile dropdown toggle handling
|
|
104
|
+
*/
|
|
105
|
+
function setupMobileDropdowns() {
|
|
106
|
+
const dropdowns = document.querySelectorAll('.nav-hover-dropdown');
|
|
107
|
+
|
|
108
|
+
dropdowns.forEach(dropdown => {
|
|
109
|
+
const toggle = dropdown.querySelector('.dropdown-toggle-split');
|
|
110
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
111
|
+
|
|
112
|
+
if (!toggle || !menu) return;
|
|
113
|
+
|
|
114
|
+
toggle.addEventListener('click', function(e) {
|
|
115
|
+
if (!isMobile()) return;
|
|
116
|
+
|
|
117
|
+
e.preventDefault();
|
|
118
|
+
e.stopPropagation();
|
|
119
|
+
|
|
120
|
+
const isOpen = menu.classList.contains('show');
|
|
121
|
+
|
|
122
|
+
if (isOpen) {
|
|
123
|
+
menu.classList.remove('show');
|
|
124
|
+
toggle.classList.remove('show');
|
|
125
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
126
|
+
} else {
|
|
127
|
+
menu.classList.add('show');
|
|
128
|
+
toggle.classList.add('show');
|
|
129
|
+
toggle.setAttribute('aria-expanded', 'true');
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Close dropdowns when clicking outside on mobile
|
|
137
|
+
*/
|
|
138
|
+
function setupOutsideClickClose() {
|
|
139
|
+
document.addEventListener('click', (e) => {
|
|
140
|
+
if (!isMobile()) return;
|
|
141
|
+
|
|
142
|
+
const clickedDropdown = e.target.closest('.nav-hover-dropdown');
|
|
143
|
+
if (clickedDropdown) return;
|
|
144
|
+
|
|
145
|
+
document.querySelectorAll('.nav-hover-dropdown').forEach(dropdown => {
|
|
146
|
+
const toggle = dropdown.querySelector('.dropdown-toggle-split');
|
|
147
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
148
|
+
if (menu && toggle) {
|
|
149
|
+
menu.classList.remove('show');
|
|
150
|
+
toggle.classList.remove('show');
|
|
151
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Reset dropdowns when offcanvas closes
|
|
159
|
+
*/
|
|
160
|
+
function setupOffcanvasReset() {
|
|
161
|
+
const offcanvasEl = document.getElementById('bdNavbar');
|
|
162
|
+
if (!offcanvasEl) return;
|
|
163
|
+
|
|
164
|
+
offcanvasEl.addEventListener('hide.bs.offcanvas', () => {
|
|
165
|
+
document.querySelectorAll('.nav-hover-dropdown').forEach(dropdown => {
|
|
166
|
+
const toggle = dropdown.querySelector('.dropdown-toggle-split');
|
|
167
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
168
|
+
if (menu && toggle) {
|
|
169
|
+
menu.classList.remove('show');
|
|
170
|
+
toggle.classList.remove('show');
|
|
171
|
+
toggle.setAttribute('aria-expanded', 'false');
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Initialize Bootstrap tooltips for nav links
|
|
179
|
+
* Shows link title on hover when labels are hidden (992px-1199px)
|
|
180
|
+
*/
|
|
181
|
+
function setupNavTooltips() {
|
|
182
|
+
const navLinks = document.querySelectorAll('#bdNavbar .nav-link[title]');
|
|
183
|
+
navLinks.forEach(link => {
|
|
184
|
+
// Only initialize tooltip if Bootstrap is available
|
|
185
|
+
if (typeof bootstrap !== 'undefined' && bootstrap.Tooltip) {
|
|
186
|
+
new bootstrap.Tooltip(link, {
|
|
187
|
+
trigger: 'hover',
|
|
188
|
+
placement: 'bottom',
|
|
189
|
+
delay: { show: 300, hide: 0 }
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Initialize
|
|
196
|
+
if (document.readyState === 'loading') {
|
|
197
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
198
|
+
initNavigation();
|
|
199
|
+
setupNavTooltips();
|
|
200
|
+
});
|
|
201
|
+
} else {
|
|
202
|
+
initNavigation();
|
|
203
|
+
setupNavTooltips();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
})();
|