jekyll-theme-zer0 1.29.0 → 1.31.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 +886 -2
- data/_data/README.md +2 -0
- data/_data/ai.yml +5 -3
- data/_data/ai_pricing.yml +36 -0
- data/_data/backlog.yml +196 -22
- data/_data/consumers.yml +147 -5
- data/_data/features.yml +147 -21
- data/_data/feedback_types.yml +17 -12
- data/_data/landing.yml +5 -2
- data/_data/navigation/quickstart.yml +4 -0
- data/_data/site_builder.yml +874 -0
- data/_data/theme-manifest.yml +132 -122
- data/_data/ui-text.yml +19 -0
- data/_includes/README.md +11 -1
- data/_includes/analytics/posthog.html +30 -11
- data/_includes/components/README.md +1 -1
- 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 +8 -8
- data/_includes/components/background-image.html +120 -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 +41 -41
- 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 +36 -36
- data/_includes/components/js-cdn.html +15 -15
- data/_includes/components/language-toggle.html +4 -4
- data/_includes/components/mermaid.html +79 -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 +1 -1
- 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 +28 -3
- data/_includes/components/quick-index.html +2 -2
- data/_includes/components/search-modal.html +27 -2
- data/_includes/components/searchbar.html +2 -2
- data/_includes/components/svg-background.html +2 -2
- data/_includes/components/theme-customizer.html +2 -2
- data/_includes/components/theme-info.html +6 -6
- data/_includes/components/theme-preview-gallery.html +23 -23
- data/_includes/content/giscus.html +2 -2
- data/_includes/content/intro.html +15 -8
- data/_includes/content/jsonld-faq.html +2 -2
- data/_includes/content/jsonld-software.html +2 -2
- data/_includes/content/seo.html +12 -4
- data/_includes/content/sitemap.html +247 -290
- data/_includes/content/toc.html +183 -183
- data/_includes/core/branding.html +13 -20
- 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 +31 -18
- data/_includes/core/head.html +128 -92
- data/_includes/core/header.html +85 -54
- data/_includes/core/tokens-inline.html +16 -1
- 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 +21 -18
- data/_includes/navigation/section-sidebar.html +16 -16
- data/_includes/navigation/sidebar-config.html +36 -2
- data/_includes/navigation/sidebar-left.html +15 -15
- data/_includes/navigation/sidebar-right.html +6 -6
- 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 +910 -291
- data/_includes/stats/stats-categories.html +8 -8
- data/_includes/stats/stats-header.html +14 -14
- data/_includes/stats/stats-metrics.html +12 -12
- 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/admin.html +22 -22
- data/_layouts/article.html +54 -37
- 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 +12 -12
- data/_layouts/default.html +27 -24
- data/_layouts/home.html +36 -24
- data/_layouts/index.html +10 -10
- data/_layouts/landing.html +17 -17
- data/_layouts/news.html +44 -44
- data/_layouts/note.html +40 -39
- data/_layouts/notebook.html +36 -35
- data/_layouts/recipe.html +24 -24
- data/_layouts/root.html +95 -55
- data/_layouts/section.html +23 -23
- 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/_cookie-banner.scss +48 -0
- data/_sass/components/_mermaid.scss +375 -0
- data/_sass/components/_setup-wizard.scss +588 -41
- data/_sass/components/_ui-enhancements.scss +11 -0
- data/_sass/core/_navbar.scss +147 -100
- data/_sass/core/_sidebar-extras.scss +2 -14
- data/_sass/core/code-copy.scss +27 -8
- data/_sass/layouts/_navbar-extras.scss +14 -4
- data/assets/css/extension-points-demo.css +27 -0
- data/assets/css/main.scss +1 -0
- data/assets/data/wiki-index.json +19 -0
- data/assets/js/ai-chat.js +47 -5
- data/assets/js/auto-hide-nav.js +53 -13
- data/assets/js/code-copy.js +72 -1
- data/assets/js/extension-points-demo.js +48 -0
- data/assets/js/fleet-feedback-capture.js +124 -0
- data/assets/js/fleet-feedback.js +853 -0
- data/assets/js/mermaid-diagrams.js +1373 -0
- data/assets/js/modules/navigation/config.js +9 -6
- data/assets/js/modules/navigation/scroll-spy.js +315 -80
- data/assets/js/modules/theme/appearance.js +8 -2
- data/assets/js/obsidian-local-graph.js +27 -5
- data/assets/js/obsidian-wiki-links.js +8 -3
- data/assets/js/page-feedback.js +125 -192
- data/assets/js/search-modal.js +26 -0
- data/assets/js/setup-wizard.js +2119 -363
- data/assets/js/site-builder.js +1834 -0
- data/assets/js/ui-enhancements.js +11 -3
- data/scripts/README.md +15 -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/ci/test_visual_evidence_autogen.py +403 -0
- data/scripts/ci/visual_evidence_autogen.py +1070 -0
- data/scripts/content-review.rb +20 -1
- data/scripts/features/install-preview-generator +1 -1
- data/scripts/lib/README.md +12 -0
- data/scripts/lib/preview_generator.py +2 -2
- data/scripts/test/integration/mermaid +22 -8
- data/scripts/test/lib/run_tests.sh +1 -0
- data/scripts/test/lib/test_visual_evidence_autogen.sh +24 -0
- data/scripts/translate.rb +23 -1
- metadata +21 -2
|
@@ -53,6 +53,17 @@ img {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// Article hero (_layouts/article.html, figure.featured-hero) — the LCP image.
|
|
57
|
+
// Reserve its box before it loads so the text below never shifts (issue #485).
|
|
58
|
+
// A fixed ratio in CSS rather than width/height attributes: preview assets are
|
|
59
|
+
// 3:2 (1024x683) generated, but some are portrait or external, and a declared
|
|
60
|
+
// intrinsic size that disagrees with the file would itself cause the shift.
|
|
61
|
+
// object-fit: cover (inline on the <img>) crops, never distorts; the inline
|
|
62
|
+
// max-height: 500px still caps the box on wide viewports.
|
|
63
|
+
.featured-hero img {
|
|
64
|
+
aspect-ratio: 3 / 2;
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
// Hero content animations
|
|
57
68
|
.bg-primary .container-xl {
|
|
58
69
|
animation: fadeInUp 0.8s ease-out;
|
data/_sass/core/_navbar.scss
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
// Breakpoints:
|
|
7
7
|
// - Desktop >= 992px (inline nav; label density via @container bd-nav)
|
|
8
8
|
// - Mobile < 992px (offcanvas)
|
|
9
|
-
// Nav label tiers (center track / bd-nav container width):
|
|
9
|
+
// Nav label tiers (center track / bd-nav container width) — TWO, never truncating:
|
|
10
10
|
// - >= 51rem (~816px): icon + full label
|
|
11
|
-
// -
|
|
12
|
-
//
|
|
11
|
+
// - < 51rem: icon-only (tooltips on lg–xl viewports)
|
|
12
|
+
// Icons are present in BOTH tiers. The old bare-label middle tier and the
|
|
13
|
+
// `text-overflow: ellipsis` safety net were removed in #405 — a truncated
|
|
14
|
+
// label ("Quicksta…") is worse than an icon with a tooltip.
|
|
13
15
|
// ==============================================================================
|
|
14
16
|
|
|
15
17
|
// -----------------------------------------------------------------------------
|
|
@@ -92,6 +94,20 @@
|
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
// The below-lg menu toggle carries a visible "Menu" label beside its glyph, so
|
|
98
|
+
// it cannot be confused with the sidebar hamburger sitting next to it (#405).
|
|
99
|
+
.navbar-toggler.navbar-toggler-labeled {
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
gap: 0.375rem;
|
|
103
|
+
width: auto;
|
|
104
|
+
|
|
105
|
+
.navbar-toggler-text {
|
|
106
|
+
font-size: 0.9375rem;
|
|
107
|
+
line-height: 1;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
95
111
|
// Shared icon-only nav styling (applied via @container bd-nav below)
|
|
96
112
|
@mixin navbar-nav-icon-only {
|
|
97
113
|
#bdNavbar .nav-link .nav-link-text {
|
|
@@ -137,21 +153,16 @@
|
|
|
137
153
|
overflow: visible;
|
|
138
154
|
}
|
|
139
155
|
|
|
156
|
+
// No transform on :hover. A translate moves the element out from under a
|
|
157
|
+
// pointer parked on the edge it vacates, hover exits, the element returns —
|
|
158
|
+
// an infinite flicker. Nav items are thin enough for a 1px lift to do it.
|
|
140
159
|
#bdNavbar .nav-link:hover {
|
|
141
160
|
background-color: var(--bs-tertiary-bg);
|
|
142
|
-
transform: translateY(-1px);
|
|
143
161
|
}
|
|
144
162
|
|
|
145
163
|
.nav-hover-dropdown .dropdown-toggle-split {
|
|
146
164
|
padding: var(--zer0-space-1) var(--zer0-space-2);
|
|
147
165
|
|
|
148
|
-
&::after {
|
|
149
|
-
transition: transform 0.2s ease-in-out;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
&:hover::after {
|
|
153
|
-
transform: translateY(2px);
|
|
154
|
-
}
|
|
155
166
|
}
|
|
156
167
|
}
|
|
157
168
|
|
|
@@ -181,12 +192,18 @@
|
|
|
181
192
|
&:hover {
|
|
182
193
|
color: var(--bs-primary);
|
|
183
194
|
background-color: var(--bs-tertiary-bg);
|
|
184
|
-
transform: translateY(-1px);
|
|
185
195
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
196
|
+
// These are `.btn`s, and _ui-enhancements.scss lifts every button by 2px
|
|
197
|
+
// on hover. Dropping the navbar's own translateY(-1px) is not enough —
|
|
198
|
+
// the inherited lift flickers the same way. `transform: none` is the
|
|
199
|
+
// repo's existing corrective pattern (see _post-navigation.scss).
|
|
200
|
+
transform: none;
|
|
186
201
|
}
|
|
187
202
|
|
|
203
|
+
// A pressed cue is safe: :active only holds while the button is held down,
|
|
204
|
+
// so the pointer cannot leave and re-enter in a loop.
|
|
188
205
|
&:active {
|
|
189
|
-
transform: translateY(
|
|
206
|
+
transform: translateY(1px);
|
|
190
207
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
191
208
|
}
|
|
192
209
|
|
|
@@ -197,11 +214,6 @@
|
|
|
197
214
|
|
|
198
215
|
i {
|
|
199
216
|
font-size: 1.15rem;
|
|
200
|
-
transition: transform 0.15s ease-in-out;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
&:hover i {
|
|
204
|
-
transform: scale(1.1);
|
|
205
217
|
}
|
|
206
218
|
}
|
|
207
219
|
}
|
|
@@ -400,16 +412,29 @@
|
|
|
400
412
|
transform: rotate(180deg);
|
|
401
413
|
}
|
|
402
414
|
|
|
403
|
-
// Label density
|
|
404
|
-
//
|
|
415
|
+
// Label density has TWO tiers, measured on the center track (the `bd-nav`
|
|
416
|
+
// container), so items either fit whole or drop to icons — never truncate:
|
|
405
417
|
// >= 51rem (816px) icon + label — the roomy default
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
//
|
|
409
|
-
//
|
|
410
|
-
//
|
|
411
|
-
//
|
|
412
|
-
|
|
418
|
+
// < 51rem icon only — icon + label no longer fits
|
|
419
|
+
// 51rem is the MEASURED width the icon+label row needs for the theme's seven
|
|
420
|
+
// demo items (815px), so the upper tier engages exactly when its own content
|
|
421
|
+
// fits and the lower one takes over otherwise.
|
|
422
|
+
//
|
|
423
|
+
// There used to be a middle 41-50.99rem tier that dropped the ICONS to buy
|
|
424
|
+
// ~20px per item, plus `text-overflow: ellipsis` as a last-resort safety net.
|
|
425
|
+
// Both are gone (#405): the ellipsis produced "Quicksta…", and a clipped
|
|
426
|
+
// label is worse than an icon with a tooltip — the icon is at least honest
|
|
427
|
+
// about being an abbreviation. Icons now survive at every tier, and the
|
|
428
|
+
// icon-only cutoff moved 41rem -> 51rem to take over the band the middle
|
|
429
|
+
// tier used to hold. That is a deliberate behaviour change at 656-816px of
|
|
430
|
+
// center track: those widths used to show bare labels and now show icons,
|
|
431
|
+
// with `.nav-tooltip` (992-1199px) carrying the name on hover.
|
|
432
|
+
//
|
|
433
|
+
// Consumers with materially more (or longer) items than the theme's seven
|
|
434
|
+
// demo entries can exceed 51rem of content; with shrink and ellipsis both
|
|
435
|
+
// removed, the row overflows rather than truncates. A container query
|
|
436
|
+
// cannot measure content, so raise the boundary below if that happens.
|
|
437
|
+
@container bd-nav (min-width: 51rem) {
|
|
413
438
|
#bdNavbar .navbar-nav {
|
|
414
439
|
gap: 0.125rem;
|
|
415
440
|
}
|
|
@@ -418,87 +443,105 @@
|
|
|
418
443
|
padding: 0.375rem;
|
|
419
444
|
}
|
|
420
445
|
|
|
446
|
+
// No `overflow: hidden` / `text-overflow: ellipsis` here: this tier only
|
|
447
|
+
// engages once the whole icon+label row fits, so a clipped label would be
|
|
448
|
+
// a bug rather than a fallback. Labels stay whole or the row goes
|
|
449
|
+
// icon-only (#405).
|
|
421
450
|
#bdNavbar .nav-link .nav-link-text {
|
|
422
451
|
display: inline !important;
|
|
423
452
|
margin-left: 0;
|
|
424
453
|
min-width: 0;
|
|
425
|
-
overflow: hidden;
|
|
426
|
-
text-overflow: ellipsis;
|
|
427
454
|
white-space: nowrap;
|
|
428
455
|
transition: opacity 0.15s ease-in-out;
|
|
429
456
|
}
|
|
430
457
|
|
|
458
|
+
// Items do NOT shrink in this tier. Shrinking is what produced the
|
|
459
|
+
// clipped label this tier removes: the tier only engages once the full
|
|
460
|
+
// icon+label row fits, so an item that shrinks here is being cut for no
|
|
461
|
+
// reason.
|
|
431
462
|
#bdNavbar .nav-item,
|
|
432
463
|
#bdNavbar .nav-hover-dropdown {
|
|
433
|
-
flex: 0
|
|
464
|
+
flex: 0 0 auto;
|
|
434
465
|
min-width: 0;
|
|
435
466
|
}
|
|
436
467
|
|
|
437
468
|
#bdNavbar .nav-item > .nav-link:not(.dropdown-toggle-split),
|
|
438
469
|
#bdNavbar .nav-hover-dropdown > .nav-link:first-child {
|
|
439
|
-
flex:
|
|
470
|
+
flex: 0 0 auto;
|
|
440
471
|
min-width: 0;
|
|
441
472
|
max-width: 100%;
|
|
442
|
-
overflow:
|
|
473
|
+
overflow: visible;
|
|
443
474
|
gap: 0.25rem;
|
|
444
475
|
}
|
|
445
476
|
|
|
446
477
|
#bdNavbar .nav-link i {
|
|
447
478
|
margin-right: 0;
|
|
448
479
|
font-size: 1rem;
|
|
449
|
-
transition: transform 0.15s ease-in-out;
|
|
450
480
|
}
|
|
451
481
|
|
|
452
|
-
|
|
482
|
+
// Hover lives on the ROW, not on each control. With the chevron overlaying
|
|
483
|
+
// the link's padding box (below), a per-control background would light
|
|
484
|
+
// only half the row as the pointer crossed it.
|
|
485
|
+
#bdNavbar .nav-item:not(.nav-hover-dropdown) > .nav-link:hover,
|
|
486
|
+
#bdNavbar .nav-hover-dropdown:hover > .nav-link:first-child {
|
|
453
487
|
background-color: var(--bs-tertiary-bg);
|
|
454
488
|
border-radius: 0.375rem;
|
|
489
|
+
}
|
|
455
490
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
491
|
+
// Chevron merged into the parent link's box (#405). It stays a real
|
|
492
|
+
// <button> — keyboard reachable, `aria-expanded`/`aria-haspopup` intact —
|
|
493
|
+
// and is only repositioned: absolutely placed over the right end of the
|
|
494
|
+
// link's padding, which the link reserves with extra padding-right. There
|
|
495
|
+
// is no longer a gap between the two, so the dead zone between label and
|
|
496
|
+
// chevron is gone and the whole row is one hover target.
|
|
497
|
+
// Every rule below is scoped with #bdNavbar deliberately: the tier's own
|
|
498
|
+
// `#bdNavbar .nav-link { padding: 0.375rem }` above carries an id, so a
|
|
499
|
+
// class-only `padding-right` here would lose to it and the chevron would
|
|
500
|
+
// have no reserved space to sit in.
|
|
501
|
+
#bdNavbar .nav-hover-dropdown {
|
|
502
|
+
position: relative;
|
|
459
503
|
}
|
|
460
504
|
|
|
461
|
-
.nav-hover-dropdown > .nav-link {
|
|
462
|
-
border-
|
|
463
|
-
|
|
505
|
+
#bdNavbar .nav-hover-dropdown > .nav-link:first-child {
|
|
506
|
+
border-radius: 0.375rem;
|
|
507
|
+
padding-right: 1.25rem;
|
|
464
508
|
}
|
|
465
509
|
|
|
466
|
-
.nav-hover-dropdown > .dropdown-toggle-split {
|
|
467
|
-
|
|
468
|
-
|
|
510
|
+
#bdNavbar .nav-hover-dropdown > .dropdown-toggle-split {
|
|
511
|
+
position: absolute;
|
|
512
|
+
top: 0;
|
|
513
|
+
right: 0;
|
|
514
|
+
bottom: 0;
|
|
515
|
+
z-index: 1;
|
|
516
|
+
display: flex;
|
|
517
|
+
align-items: center;
|
|
518
|
+
justify-content: center;
|
|
519
|
+
width: 1.25rem;
|
|
469
520
|
min-width: 1.25rem;
|
|
470
521
|
min-height: 0;
|
|
471
|
-
|
|
472
|
-
padding
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
// Middle tier — the labels fit but the icons no longer do. Dropping the
|
|
479
|
-
// decorative icon (the label is the accessible name) and tightening the
|
|
480
|
-
// chevron buys back roughly 20px per item, which is the difference between
|
|
481
|
-
// "Notebooks" and "N…" at 992-1200px viewports.
|
|
482
|
-
@container bd-nav (min-width: 41rem) and (max-width: 50.99rem) {
|
|
483
|
-
#bdNavbar .nav-link i {
|
|
484
|
-
display: none;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
#bdNavbar .nav-item > .nav-link:not(.dropdown-toggle-split),
|
|
488
|
-
#bdNavbar .nav-hover-dropdown > .nav-link:first-child {
|
|
489
|
-
gap: 0;
|
|
522
|
+
margin: 0 !important;
|
|
523
|
+
padding: 0;
|
|
524
|
+
background-color: transparent;
|
|
525
|
+
border: 0;
|
|
526
|
+
border-radius: 0 0.375rem 0.375rem 0;
|
|
490
527
|
}
|
|
491
528
|
|
|
492
|
-
//
|
|
493
|
-
//
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
529
|
+
// The overlay must not paint its own hover background — the row already
|
|
530
|
+
// does. Without this the chevron reads as a separate control again, which
|
|
531
|
+
// is the whole defect. `!important` because the shared base block at the
|
|
532
|
+
// top of this file sets the chevron's own hover background with equal
|
|
533
|
+
// specificity and later source order.
|
|
534
|
+
#bdNavbar .nav-hover-dropdown > .dropdown-toggle-split:hover,
|
|
535
|
+
#bdNavbar .nav-hover-dropdown > .dropdown-toggle-split:focus-visible,
|
|
536
|
+
#bdNavbar .nav-hover-dropdown > .dropdown-toggle-split[aria-expanded="true"] {
|
|
537
|
+
background-color: transparent !important;
|
|
497
538
|
}
|
|
498
539
|
}
|
|
499
540
|
|
|
500
|
-
// Icon-only when the center track
|
|
501
|
-
|
|
541
|
+
// Icon-only when the center track cannot fit the icon+label row. The
|
|
542
|
+
// boundary is the complement of the tier above so the two tiers tile the
|
|
543
|
+
// whole range with no gap.
|
|
544
|
+
@container bd-nav (max-width: 50.99rem) {
|
|
502
545
|
@include navbar-nav-icon-only;
|
|
503
546
|
}
|
|
504
547
|
}
|
|
@@ -681,7 +724,6 @@
|
|
|
681
724
|
|
|
682
725
|
&:hover {
|
|
683
726
|
background-color: var(--bs-tertiary-bg);
|
|
684
|
-
transform: rotate(90deg);
|
|
685
727
|
}
|
|
686
728
|
|
|
687
729
|
&:focus-visible {
|
|
@@ -768,20 +810,10 @@
|
|
|
768
810
|
i {
|
|
769
811
|
font-size: 1rem;
|
|
770
812
|
width: 1.5rem;
|
|
771
|
-
transition: transform 0.15s ease-in-out;
|
|
772
813
|
}
|
|
773
814
|
|
|
774
815
|
&:hover {
|
|
775
816
|
background-color: var(--bs-tertiary-bg);
|
|
776
|
-
|
|
777
|
-
// translateX widens overflow; desktop menus sit inside a clipped nav track
|
|
778
|
-
@media (max-width: 991.98px) {
|
|
779
|
-
transform: translateX(4px);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
i {
|
|
783
|
-
transform: scale(1.1);
|
|
784
|
-
}
|
|
785
817
|
}
|
|
786
818
|
|
|
787
819
|
&:focus-visible {
|
|
@@ -1119,8 +1151,7 @@
|
|
|
1119
1151
|
align-items: center;
|
|
1120
1152
|
}
|
|
1121
1153
|
|
|
1122
|
-
#navbar .site-title-text
|
|
1123
|
-
#navbar .site-subtitle-text {
|
|
1154
|
+
#navbar .site-title-text {
|
|
1124
1155
|
display: inline-block;
|
|
1125
1156
|
}
|
|
1126
1157
|
|
|
@@ -1157,9 +1188,28 @@
|
|
|
1157
1188
|
|
|
1158
1189
|
// Desktop (lg+): 3-column grid — [brand/title | main nav | utilities] so nav cannot paint over Search/Settings
|
|
1159
1190
|
@media (min-width: 992px) {
|
|
1191
|
+
// Optical centering (#405) WITHOUT breaking the container queries.
|
|
1192
|
+
//
|
|
1193
|
+
// The obvious spelling — `1fr auto 1fr` — is a trap here. Track 2 must stay
|
|
1194
|
+
// a `1fr` (a DEFINITE width): `.bd-navbar-nav-viewport` inside it is
|
|
1195
|
+
// `width: 100%` + `container-type: inline-size`, and that percentage only
|
|
1196
|
+
// resolves against a definite track. Make track 2 `auto` and it becomes
|
|
1197
|
+
// content-sized, size containment hands `bd-nav` a degenerate width, and
|
|
1198
|
+
// EVERY `@container bd-nav` label tier stops firing — the bar collapses to
|
|
1199
|
+
// icon-only at all widths, which is the opposite of what #405 is for.
|
|
1200
|
+
//
|
|
1201
|
+
// So the nav keeps the elastic middle track and the two side tracks are
|
|
1202
|
+
// equalised instead, via a shared floor. Whenever the brand and the
|
|
1203
|
+
// utility cluster both fit inside it (the common case), the side tracks
|
|
1204
|
+
// are the same width and the menubar is centred in the bar, not merely
|
|
1205
|
+
// centred in its own track. The floor is deliberately small so it never
|
|
1206
|
+
// steals the width the label tier needs at 1280px.
|
|
1160
1207
|
#navbar .navbar-main {
|
|
1161
1208
|
display: grid !important;
|
|
1162
|
-
grid-template-columns:
|
|
1209
|
+
grid-template-columns:
|
|
1210
|
+
minmax(var(--zer0-navbar-side-min, 9rem), auto)
|
|
1211
|
+
minmax(0, 1fr)
|
|
1212
|
+
minmax(var(--zer0-navbar-side-min, 9rem), auto);
|
|
1163
1213
|
align-items: center;
|
|
1164
1214
|
column-gap: 0.75rem;
|
|
1165
1215
|
row-gap: 0.25rem;
|
|
@@ -1228,8 +1278,7 @@
|
|
|
1228
1278
|
display: none;
|
|
1229
1279
|
}
|
|
1230
1280
|
|
|
1231
|
-
#navbar .site-title
|
|
1232
|
-
#navbar .site-subtitle {
|
|
1281
|
+
#navbar .site-title {
|
|
1233
1282
|
flex-shrink: 1;
|
|
1234
1283
|
min-width: 0;
|
|
1235
1284
|
}
|
|
@@ -1247,15 +1296,6 @@
|
|
|
1247
1296
|
max-width: none;
|
|
1248
1297
|
}
|
|
1249
1298
|
|
|
1250
|
-
#navbar .site-subtitle .site-subtitle-text {
|
|
1251
|
-
overflow: hidden;
|
|
1252
|
-
text-overflow: ellipsis;
|
|
1253
|
-
white-space: nowrap;
|
|
1254
|
-
display: inline-block;
|
|
1255
|
-
vertical-align: bottom;
|
|
1256
|
-
max-width: none;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
1299
|
// Progressive brand degradation (container width, not viewport).
|
|
1260
1300
|
// The home-link icons add ~108px to the brand cluster, so they only appear
|
|
1261
1301
|
// once the bar is wide enough to carry them AND the full menubar
|
|
@@ -1267,12 +1307,6 @@
|
|
|
1267
1307
|
}
|
|
1268
1308
|
}
|
|
1269
1309
|
|
|
1270
|
-
@container navbar-main (max-width: 68rem) {
|
|
1271
|
-
#navbar .site-subtitle {
|
|
1272
|
-
display: none !important;
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
1310
|
@container navbar-main (max-width: 50rem) {
|
|
1277
1311
|
#navbar .site-title .site-title-text {
|
|
1278
1312
|
max-width: 100%;
|
|
@@ -1338,6 +1372,19 @@
|
|
|
1338
1372
|
height: 2.5rem;
|
|
1339
1373
|
}
|
|
1340
1374
|
|
|
1375
|
+
// The square above is for BARE-GLYPH togglers. The labelled menu toggle
|
|
1376
|
+
// (#405) also carries a "Menu" span, and 2.5rem cannot hold glyph + gap +
|
|
1377
|
+
// label — the text would escape the button box and push the page past the
|
|
1378
|
+
// viewport at every width below lg, which is exactly what makes a
|
|
1379
|
+
// fixed-top bar read as "cut off". `.navbar-toggler-labeled`'s own
|
|
1380
|
+
// `width: auto` loses to the ID selector above on specificity (0,2,0 vs
|
|
1381
|
+
// 1,1,0); re-assert it here, where it outranks.
|
|
1382
|
+
#navbar .navbar-toggler.navbar-toggler-labeled {
|
|
1383
|
+
width: auto;
|
|
1384
|
+
min-width: 2.5rem;
|
|
1385
|
+
flex-shrink: 0;
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1341
1388
|
#navbar .nav-search-button {
|
|
1342
1389
|
width: 2.5rem;
|
|
1343
1390
|
height: 2.5rem;
|
|
@@ -20,20 +20,8 @@
|
|
|
20
20
|
|
|
21
21
|
// MOVED → _sass/layouts/_navbar-extras.scss (token-aware FAB stacking)
|
|
22
22
|
// MOVED → _sass/components/_cookie-banner.scss (token-aware, dark-mode-safe)
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
.cookie-consent-banner {
|
|
26
|
-
@media (max-width: 768px) {
|
|
27
|
-
.btn {
|
|
28
|
-
width: 100%;
|
|
29
|
-
margin-bottom: 0.5rem;
|
|
30
|
-
|
|
31
|
-
&:last-child {
|
|
32
|
-
margin-bottom: 0;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
23
|
+
// The banner's internal layout (formerly a full-width stacked-button shim
|
|
24
|
+
// here) lives with the shell in _sass/components/_cookie-banner.scss.
|
|
37
25
|
|
|
38
26
|
// Active TOC link highlighting
|
|
39
27
|
.bd-toc nav a.active {
|
data/_sass/core/code-copy.scss
CHANGED
|
@@ -357,14 +357,33 @@ pre.highlight > button:focus {
|
|
|
357
357
|
opacity: 1;
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
.
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
360
|
+
// Extra actions inside a code block — SCOPED TO THIS COMPONENT (#412).
|
|
361
|
+
//
|
|
362
|
+
// This block used to read `.button, button:not(.copy)` with no scope at all.
|
|
363
|
+
// An element selector in a component partial is a site-wide rule: it restyled
|
|
364
|
+
// EVERY button on a consumer site that was not the theme's own copy button —
|
|
365
|
+
// `padding: 0 20px`, `font-size: 11px`, and a hardcoded `#bbb` border that
|
|
366
|
+
// bypassed the design tokens entirely. At specificity (0,1,1) it also outranked
|
|
367
|
+
// `.btn` and any consumer's own `.my-button`, so escaping it meant a
|
|
368
|
+
// specificity fight rather than a cascade (it-journey#634 had to scope to
|
|
369
|
+
// `.code-block-header .itj-clip-btn` to win). A component partial styles its
|
|
370
|
+
// own component and nothing else.
|
|
371
|
+
//
|
|
372
|
+
// The rule is kept, not deleted: a consumer that adds an action to the header
|
|
373
|
+
// (see the `zer0:code-block-ready` contract in assets/js/code-copy.js) should
|
|
374
|
+
// inherit the copy button's shape instead of arriving unstyled. Values are
|
|
375
|
+
// tokens now, so a skin moves them.
|
|
376
|
+
.code-block-header,
|
|
377
|
+
pre.highlight {
|
|
378
|
+
> .button,
|
|
379
|
+
> button:not(.copy) {
|
|
380
|
+
display: inline-block;
|
|
381
|
+
padding: 0 var(--zer0-space-3);
|
|
382
|
+
border-radius: var(--zer0-radius-sm);
|
|
383
|
+
border: 1px solid var(--zer0-color-border);
|
|
384
|
+
font-size: var(--zer0-text-sm);
|
|
385
|
+
cursor: pointer;
|
|
386
|
+
}
|
|
368
387
|
}
|
|
369
388
|
|
|
370
389
|
// Non-highlight fenced code blocks
|
|
@@ -53,13 +53,18 @@
|
|
|
53
53
|
display: block;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// No transform on :hover — a lift moves the FAB out from under a pointer
|
|
57
|
+
// parked on its bottom edge, hover exits, it drops back: infinite flicker.
|
|
58
|
+
// These are `.btn`s, so the 2px lift _ui-enhancements.scss puts on every
|
|
59
|
+
// button has to be cancelled explicitly, not merely not-added here.
|
|
56
60
|
&:hover,
|
|
57
61
|
&:focus-visible {
|
|
58
|
-
transform:
|
|
62
|
+
transform: none;
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
// :active is safe, because the button is held down for its whole duration.
|
|
61
66
|
&:active {
|
|
62
|
-
transform: translateY(
|
|
67
|
+
transform: translateY(1px);
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
}
|
|
@@ -112,13 +117,18 @@
|
|
|
112
117
|
display: block;
|
|
113
118
|
}
|
|
114
119
|
|
|
120
|
+
// No transform on :hover — a lift moves the FAB out from under a pointer
|
|
121
|
+
// parked on its bottom edge, hover exits, it drops back: infinite flicker.
|
|
122
|
+
// These are `.btn`s, so the 2px lift _ui-enhancements.scss puts on every
|
|
123
|
+
// button has to be cancelled explicitly, not merely not-added here.
|
|
115
124
|
&:hover,
|
|
116
125
|
&:focus-visible {
|
|
117
|
-
transform:
|
|
126
|
+
transform: none;
|
|
118
127
|
}
|
|
119
128
|
|
|
129
|
+
// :active is safe, because the button is held down for its whole duration.
|
|
120
130
|
&:active {
|
|
121
|
-
transform: translateY(
|
|
131
|
+
transform: translateY(1px);
|
|
122
132
|
}
|
|
123
133
|
}
|
|
124
134
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* ==========================================================================
|
|
2
|
+
extension-points-demo.css — a live consumer of the per-page `styles:` hook
|
|
3
|
+
==========================================================================
|
|
4
|
+
|
|
5
|
+
Loaded ONLY by /docs/customization/extension-points/, through that page's
|
|
6
|
+
`styles:` frontmatter. Its job is to prove the hook works and to mark the
|
|
7
|
+
demo action button so the page's own prose can point at it.
|
|
8
|
+
|
|
9
|
+
Note what it does NOT have to do: fight a specificity war. Before #412,
|
|
10
|
+
`_sass/core/code-copy.scss` shipped a bare `button:not(.copy)` rule at
|
|
11
|
+
specificity (0,1,1), which outranked any single class a consumer could
|
|
12
|
+
write — so downstream code had to scope to `.code-block-header .my-btn`
|
|
13
|
+
just to set its own padding. That rule is scoped to the component now, and
|
|
14
|
+
a plain class is enough again.
|
|
15
|
+
========================================================================== */
|
|
16
|
+
|
|
17
|
+
.zer0-demo-action {
|
|
18
|
+
background: transparent;
|
|
19
|
+
color: var(--zer0-color-text-muted);
|
|
20
|
+
font-family: var(--zer0-font-mono);
|
|
21
|
+
line-height: 1.8;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.zer0-demo-action:hover,
|
|
25
|
+
.zer0-demo-action:focus-visible {
|
|
26
|
+
color: inherit;
|
|
27
|
+
}
|
data/assets/css/main.scss
CHANGED
data/assets/data/wiki-index.json
CHANGED
|
@@ -142,11 +142,30 @@ sitemap: false
|
|
|
142
142
|
{%- endif -%}
|
|
143
143
|
{%- endfor -%}
|
|
144
144
|
{%- assign outgoing = outgoing | uniq -%}
|
|
145
|
+
{%- comment -%}
|
|
146
|
+
`lastmod` and `description` (#412) — both already on `doc` in this loop,
|
|
147
|
+
so neither costs a new traversal. A notes/library UI needs them:
|
|
148
|
+
`lastmod` to sort by recency or show staleness, and `description`
|
|
149
|
+
because `excerpt` is body-derived while `description` is the AUTHORED
|
|
150
|
+
subtitle, which is the better card line whenever it exists.
|
|
151
|
+
|
|
152
|
+
Source order for the date follows the rest of the theme
|
|
153
|
+
(_includes/core/head.html, _layouts/article.html): `last_modified_at`,
|
|
154
|
+
then `lastmod`, then the document's own `date`. Emitted as ISO-8601 via
|
|
155
|
+
`date_to_xmlschema` so a consumer can sort strings without parsing.
|
|
156
|
+
Both keys are always present and always defined — `null` when the
|
|
157
|
+
document carries neither — rather than being conditionally omitted,
|
|
158
|
+
because a key that sometimes disappears is a worse contract than one
|
|
159
|
+
that is sometimes null.
|
|
160
|
+
{%- endcomment -%}
|
|
161
|
+
{%- assign doc_lastmod = doc.last_modified_at | default: doc.lastmod | default: doc.date -%}
|
|
145
162
|
{
|
|
146
163
|
"title": {{ doc.title | default: basename | jsonify }},
|
|
147
164
|
"basename": {{ basename | jsonify }},
|
|
148
165
|
"url": {{ doc.url | jsonify }},
|
|
149
166
|
"collection": {{ doc.collection | default: nil | jsonify }},
|
|
167
|
+
"lastmod": {% if doc_lastmod %}{{ doc_lastmod | date_to_xmlschema | jsonify }}{% else %}null{% endif %},
|
|
168
|
+
"description": {{ doc.description | default: nil | jsonify }},
|
|
150
169
|
"tags": {{ doc.tags | default: empty | jsonify }},
|
|
151
170
|
"categories": {{ doc.categories | default: empty | jsonify }},
|
|
152
171
|
"aliases": {{ aliases | jsonify }},
|