@fluid-theme/core 0.4.3 → 2.0.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.
- package/AGENTS.md +6 -29
- package/CHANGELOG.md +543 -2
- package/CLAUDE.md +193 -14
- package/GEMINI.md +6 -45
- package/README.md +17 -8
- package/assets/js/compare.js +77 -0
- package/assets/js/fit-text.js +103 -0
- package/assets/js/lightbox.js +153 -0
- package/assets/js/scroll-reveal.js +72 -0
- package/assets/js/toc-build.mjs +86 -0
- package/assets/js/toc.js +384 -0
- package/dist/fluid-1x.min.css +4 -0
- package/dist/fluid-fonts.min.css +2 -0
- package/dist/fluid-legacy-1x.css +3 -0
- package/dist/fluid-nav.min.css +3 -0
- package/dist/fluid-toc.min.css +3 -0
- package/dist/fluid-zero.min.css +3 -0
- package/dist/fluid.min.css +3 -2
- package/dist/fonts/OFL-newsreader.txt +93 -0
- package/dist/fonts/OFL-schibsted-grotesk.txt +93 -0
- package/dist/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
- package/dist/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/dist/fonts/schibsted-grotesk-latin-wght-italic.woff2 +0 -0
- package/dist/fonts/schibsted-grotesk-latin-wght-normal.woff2 +0 -0
- package/fluid-agent-kit/README.md +1 -0
- package/fluid-agent-kit/skills/accessibility.md +3 -1
- package/fluid-agent-kit/skills/css-conventions.md +22 -5
- package/fluid-agent-kit/skills/image-optimization.md +2 -0
- package/fluid-agent-kit/skills/preset-composition.md +108 -0
- package/package.json +29 -3
- package/src/animations/scroll-reveal.css +75 -193
- package/src/components/accordion.css +6 -47
- package/src/components/alert.css +47 -88
- package/src/components/avatar.css +4 -20
- package/src/components/badge.css +25 -48
- package/src/components/button.css +69 -175
- package/src/components/card.css +146 -481
- package/src/components/chip.css +46 -12
- package/src/components/compare.css +234 -0
- package/src/components/dropdown.css +10 -67
- package/src/components/empty-state.css +4 -0
- package/src/components/form.css +113 -81
- package/src/components/gallery.css +252 -0
- package/src/components/hero.css +203 -88
- package/src/components/indicator.css +23 -117
- package/src/components/loading.css +7 -29
- package/src/components/modal.css +12 -65
- package/src/components/nav-modes.css +261 -0
- package/src/components/nav.css +324 -392
- package/src/components/search-input.css +4 -2
- package/src/components/step-indicator.css +26 -27
- package/src/components/table.css +64 -171
- package/src/components/toc.css +254 -0
- package/src/components/tooltip.css +5 -46
- package/src/core/base.css +393 -547
- package/src/core/reset.css +17 -5
- package/src/core/tokens.css +426 -2276
- package/src/fluid.css +258 -17
- package/src/fonts/OFL-newsreader.txt +93 -0
- package/src/fonts/OFL-schibsted-grotesk.txt +93 -0
- package/src/fonts/fluid-fonts.css +55 -0
- package/src/fonts/newsreader-latin-opsz-italic.woff2 +0 -0
- package/src/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/src/fonts/schibsted-grotesk-latin-wght-italic.woff2 +0 -0
- package/src/fonts/schibsted-grotesk-latin-wght-normal.woff2 +0 -0
- package/src/layouts/positioning.css +6 -3
- package/src/legacy-1x.css +61 -0
- package/src/sections/cta.css +33 -101
- package/src/sections/features.css +42 -219
- package/src/sections/footer.css +53 -134
- package/src/sections/stats.css +40 -153
- package/src/sections/team.css +24 -113
- package/src/sections/testimonials.css +34 -148
- package/src/zero/base.css +166 -0
- package/src/zero/tokens.css +64 -0
- package/src/zero.css +20 -0
- package/src/components/scroll-progress.css +0 -104
- package/src/components/settings-panel.css +0 -603
- package/src/components/themed-images.css +0 -229
- package/src/components/version-badge.css +0 -70
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
* Respects prefers-reduced-motion.
|
|
7
7
|
*
|
|
8
8
|
* Spinner Usage:
|
|
9
|
-
* <div class="spinner" aria-label="Loading"></div>
|
|
10
|
-
* <div class="spinner" data-size="sm"></div>
|
|
11
|
-
* <div class="spinner" data-size="lg"></div>
|
|
9
|
+
* <div class="spinner" role="status" aria-label="Loading"></div>
|
|
10
|
+
* <div class="spinner" role="status" data-size="sm" aria-label="Loading"></div>
|
|
11
|
+
* <div class="spinner" role="status" data-size="lg" aria-label="Loading"></div>
|
|
12
12
|
*
|
|
13
13
|
* Skeleton Usage:
|
|
14
14
|
* <div class="skeleton" style="--skeleton-h: 1rem; --skeleton-w: 60%;"></div>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
.spinner {
|
|
33
33
|
--_spinner-size: 2rem;
|
|
34
34
|
--_spinner-width: 3px;
|
|
35
|
-
--_spinner-color: var(--accent);
|
|
35
|
+
--_spinner-color: var(--accent-ink);
|
|
36
36
|
|
|
37
37
|
display: inline-block;
|
|
38
38
|
inline-size: var(--_spinner-size);
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
.skeleton[data-variant="button"] {
|
|
222
222
|
--skeleton-h: 2.75rem;
|
|
223
223
|
--skeleton-w: 8rem;
|
|
224
|
-
--_skeleton-radius: var(--radius-
|
|
224
|
+
--_skeleton-radius: var(--radius-control);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
|
|
@@ -237,38 +237,16 @@
|
|
|
237
237
|
padding: var(--space-5);
|
|
238
238
|
background: var(--color-surface-raised);
|
|
239
239
|
border: var(--border-width) solid var(--color-border-subtle);
|
|
240
|
-
border-radius: var(--radius-
|
|
240
|
+
border-radius: var(--radius-card);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
.skeleton-card .skeleton[data-variant="media"] {
|
|
244
244
|
margin: calc(var(--space-5) * -1);
|
|
245
245
|
margin-block-end: var(--space-3);
|
|
246
246
|
inline-size: calc(100% + var(--space-5) * 2);
|
|
247
|
-
border-radius: var(--radius-
|
|
247
|
+
border-radius: var(--radius-card) var(--radius-card) 0 0;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
|
|
251
|
-
/* ========================================
|
|
252
|
-
THEME-SPECIFIC STYLES
|
|
253
|
-
======================================== */
|
|
254
251
|
|
|
255
|
-
/* Still: no animation */
|
|
256
|
-
[data-motion="still"] .spinner {
|
|
257
|
-
animation-duration: 800ms;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
[data-motion="still"] .skeleton {
|
|
261
|
-
animation: none;
|
|
262
|
-
background: var(--color-surface);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/* Tsunami: asymmetric skeleton cards */
|
|
266
|
-
[data-motion="tsunami"] .skeleton-card {
|
|
267
|
-
border-radius: var(--radius-asymmetric, 0 24px 0 0);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/* Rapids: faster spinner */
|
|
271
|
-
[data-motion="rapids"] .spinner {
|
|
272
|
-
animation-duration: 500ms;
|
|
273
|
-
}
|
|
274
252
|
}
|
package/src/components/modal.css
CHANGED
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
/* Native backdrop */
|
|
79
79
|
.modal::backdrop {
|
|
80
80
|
background: oklch(0% 0 0 / 0.5);
|
|
81
|
-
backdrop-filter: blur(4px);
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
|
|
@@ -95,20 +94,11 @@
|
|
|
95
94
|
inline-size: var(--_modal-width);
|
|
96
95
|
max-block-size: min(90vh, 40rem);
|
|
97
96
|
|
|
98
|
-
background: var(--color-
|
|
99
|
-
|
|
100
|
-
border
|
|
101
|
-
|
|
97
|
+
background: var(--color-background);
|
|
98
|
+
color: var(--color-text);
|
|
99
|
+
border: var(--border-width) solid var(--color-border-strong);
|
|
100
|
+
border-radius: var(--radius-card);
|
|
102
101
|
overflow: hidden;
|
|
103
|
-
|
|
104
|
-
/* Entry animation */
|
|
105
|
-
transform: translateY(var(--space-5)) scale(0.97);
|
|
106
|
-
transition:
|
|
107
|
-
transform var(--duration-normal) var(--ease-settle);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.modal[open] .modal__content {
|
|
111
|
-
transform: translateY(0) scale(1);
|
|
112
102
|
}
|
|
113
103
|
|
|
114
104
|
|
|
@@ -127,6 +117,7 @@
|
|
|
127
117
|
}
|
|
128
118
|
|
|
129
119
|
.modal__title {
|
|
120
|
+
font-family: var(--font-heading);
|
|
130
121
|
font-size: var(--font-size-lg);
|
|
131
122
|
font-weight: var(--weight-semibold);
|
|
132
123
|
line-height: var(--leading-tight);
|
|
@@ -135,7 +126,7 @@
|
|
|
135
126
|
|
|
136
127
|
.modal__close {
|
|
137
128
|
--_btn-bg: transparent;
|
|
138
|
-
--_btn-
|
|
129
|
+
--_btn-bg-hover: var(--color-surface);
|
|
139
130
|
|
|
140
131
|
position: relative;
|
|
141
132
|
flex-shrink: 0;
|
|
@@ -145,7 +136,7 @@
|
|
|
145
136
|
inline-size: 2.75rem;
|
|
146
137
|
block-size: 2.75rem;
|
|
147
138
|
padding: 0;
|
|
148
|
-
border-radius: var(--radius-
|
|
139
|
+
border-radius: var(--radius-control);
|
|
149
140
|
font-size: var(--font-size-xl);
|
|
150
141
|
line-height: 1;
|
|
151
142
|
color: var(--color-text-muted);
|
|
@@ -214,7 +205,7 @@
|
|
|
214
205
|
--_modal-width: min(90vw, 28rem);
|
|
215
206
|
max-block-size: 100vh;
|
|
216
207
|
block-size: 100vh;
|
|
217
|
-
border-radius: var(--radius-
|
|
208
|
+
border-radius: var(--radius-card) 0 0 var(--radius-card);
|
|
218
209
|
transform: translateX(100%);
|
|
219
210
|
}
|
|
220
211
|
|
|
@@ -232,7 +223,7 @@
|
|
|
232
223
|
--_modal-width: min(90vw, 28rem);
|
|
233
224
|
max-block-size: 100vh;
|
|
234
225
|
block-size: 100vh;
|
|
235
|
-
border-radius: 0 var(--radius-
|
|
226
|
+
border-radius: 0 var(--radius-card) var(--radius-card) 0;
|
|
236
227
|
transform: translateX(-100%);
|
|
237
228
|
}
|
|
238
229
|
|
|
@@ -261,43 +252,6 @@
|
|
|
261
252
|
}
|
|
262
253
|
|
|
263
254
|
|
|
264
|
-
/* ========================================
|
|
265
|
-
THEME-SPECIFIC MODAL STYLES
|
|
266
|
-
======================================== */
|
|
267
|
-
|
|
268
|
-
/* Still: sharp, no animation */
|
|
269
|
-
[data-motion="still"] .modal__content {
|
|
270
|
-
border-radius: var(--radius-md);
|
|
271
|
-
transform: none;
|
|
272
|
-
transition: none;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
[data-motion="still"] .modal {
|
|
276
|
-
transition: none;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/* Serene: gentle, pillowy */
|
|
280
|
-
[data-motion="serene"] .modal__content {
|
|
281
|
-
border-radius: var(--radius-2xl);
|
|
282
|
-
box-shadow: var(--shadow-lg);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/* Cascade: bouncy entry */
|
|
286
|
-
[data-motion="cascade"] .modal__content {
|
|
287
|
-
border-radius: var(--radius-2xl);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/* Rapids: hard offset shadow */
|
|
291
|
-
[data-motion="rapids"] .modal__content {
|
|
292
|
-
box-shadow: var(--shadow-offset-hover);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/* Tsunami: dramatic, asymmetric corners */
|
|
296
|
-
[data-motion="tsunami"] .modal__content {
|
|
297
|
-
border-radius: var(--radius-asymmetric-lg, 0 48px 0 0);
|
|
298
|
-
box-shadow: var(--shadow-xl);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
255
|
|
|
302
256
|
/* ========================================
|
|
303
257
|
RESPONSIVE
|
|
@@ -312,7 +266,7 @@
|
|
|
312
266
|
.modal__content {
|
|
313
267
|
--_modal-width: 100%;
|
|
314
268
|
max-block-size: 85vh;
|
|
315
|
-
border-radius: var(--radius-
|
|
269
|
+
border-radius: var(--radius-card) var(--radius-card) 0 0;
|
|
316
270
|
transform: translateY(100%);
|
|
317
271
|
}
|
|
318
272
|
|
|
@@ -332,7 +286,7 @@
|
|
|
332
286
|
.modal[data-variant="drawer-left"] .modal__content {
|
|
333
287
|
block-size: auto;
|
|
334
288
|
max-block-size: 85vh;
|
|
335
|
-
border-radius: var(--radius-
|
|
289
|
+
border-radius: var(--radius-card) var(--radius-card) 0 0;
|
|
336
290
|
transform: translateY(100%);
|
|
337
291
|
}
|
|
338
292
|
|
|
@@ -348,14 +302,7 @@
|
|
|
348
302
|
======================================== */
|
|
349
303
|
|
|
350
304
|
@media (prefers-reduced-motion: reduce) {
|
|
351
|
-
.
|
|
352
|
-
transition: none;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
.modal__content {
|
|
356
|
-
transform: none;
|
|
357
|
-
transition: none;
|
|
358
|
-
}
|
|
305
|
+
.modal__content { transform: none; }
|
|
359
306
|
|
|
360
307
|
.modal[open] .modal__content {
|
|
361
308
|
transform: none;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluid Framework - Navigation modes (opt-in module)
|
|
3
|
+
* @layer components
|
|
4
|
+
*
|
|
5
|
+
* dist/fluid-nav.min.css (package export "./nav"). Link it after core, as
|
|
6
|
+
* fluid-toc.min.css is. Its own file because core has no room for it under
|
|
7
|
+
* the 24,400 B gzip budget (spec _docs/plans/base-v2.md §11). The markup,
|
|
8
|
+
* the tokens and the default small-screen behaviour (squeeze, then balanced
|
|
9
|
+
* wrap) are in nav.css, in core; this file adds the modes a site opts into:
|
|
10
|
+
*
|
|
11
|
+
* data-nav="icon" the brand shrinks to its mark, the links share its row
|
|
12
|
+
* data-nav="compact" a "+" opens the links in a panel that slides over
|
|
13
|
+
* from the end edge, with a 25% backdrop; no JS
|
|
14
|
+
* data-nav="compact drop" the panel drops under the bar instead
|
|
15
|
+
* data-sticky="links" two rows: the brand row scrolls away, the links stick
|
|
16
|
+
*
|
|
17
|
+
* Without this file each falls back to the plain nav: the links wrap under
|
|
18
|
+
* the brand, and data-sticky="links" keeps the whole bar.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
@layer components {
|
|
22
|
+
/* ========================================
|
|
23
|
+
ICON: data-nav="icon"
|
|
24
|
+
======================================== */
|
|
25
|
+
|
|
26
|
+
.nav__brand-mark {
|
|
27
|
+
display: inline-grid;
|
|
28
|
+
place-items: center;
|
|
29
|
+
flex: none;
|
|
30
|
+
inline-size: 2.25rem;
|
|
31
|
+
block-size: 2.25rem;
|
|
32
|
+
font: 600 0.9375rem/1 var(--font-heading);
|
|
33
|
+
letter-spacing: 0.02em;
|
|
34
|
+
color: var(--on-accent-fill);
|
|
35
|
+
background: var(--accent-fill);
|
|
36
|
+
border-radius: var(--radius-control);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@container nav (max-width: 40rem) {
|
|
40
|
+
/* data-nav="icon": the name is read but not shown; the links share the
|
|
41
|
+
mark's row and hang at the end edge. */
|
|
42
|
+
.nav[data-nav~="icon"] .nav__brand-name {
|
|
43
|
+
position: absolute;
|
|
44
|
+
inline-size: 1px;
|
|
45
|
+
block-size: 1px;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
clip-path: inset(50%);
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.nav[data-nav~="icon"]:not(:has(.nav__toggle)) .nav__menu {
|
|
52
|
+
--nav-wrap-align: end;
|
|
53
|
+
flex: 1 1 0;
|
|
54
|
+
order: 0;
|
|
55
|
+
min-inline-size: 0;
|
|
56
|
+
margin-inline-end: calc(-1 * var(--_nav-pad));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
/* ========================================
|
|
62
|
+
COMPACT: data-nav="compact" (markup in nav.css). The links move into a
|
|
63
|
+
popover on a narrow bar. The panel wrapper stays invisible to layout
|
|
64
|
+
(nav.css) on wide bars and without popover support, so the links
|
|
65
|
+
behave as usual there.
|
|
66
|
+
======================================== */
|
|
67
|
+
|
|
68
|
+
/* Outside the container query: a nav cannot style itself from its own query. */
|
|
69
|
+
.nav[data-nav~="drop"] { anchor-name: --fluid-nav; }
|
|
70
|
+
|
|
71
|
+
@supports selector(:popover-open) {
|
|
72
|
+
@container nav (max-width: 40rem) {
|
|
73
|
+
.nav[data-nav~="compact"] .nav__more {
|
|
74
|
+
display: inline-grid;
|
|
75
|
+
place-items: center;
|
|
76
|
+
min-inline-size: 2.75rem;
|
|
77
|
+
min-block-size: 2.75rem;
|
|
78
|
+
padding: 0;
|
|
79
|
+
color: var(--nav-ink, var(--color-text));
|
|
80
|
+
background: none;
|
|
81
|
+
border: 0;
|
|
82
|
+
border-radius: var(--radius-control);
|
|
83
|
+
cursor: pointer;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.nav[data-nav~="compact"] > .nav__more {
|
|
87
|
+
order: 2;
|
|
88
|
+
margin-inline: auto calc(-1 * var(--space-2));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.nav[data-nav~="compact"]:has(.nav__actions) > .nav__more { margin-inline-start: 0; }
|
|
92
|
+
|
|
93
|
+
/* One row: the brand gives way (and wraps) before the + would. */
|
|
94
|
+
.nav[data-nav~="compact"] > .nav__brand {
|
|
95
|
+
flex: 1 1 0;
|
|
96
|
+
min-inline-size: 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* The glyph is a character of the text face, so it matches the links. */
|
|
100
|
+
.nav[data-nav~="compact"] .nav__more::before {
|
|
101
|
+
content: var(--nav-glyph, "+"); /* browsers without alt text for content */
|
|
102
|
+
content: var(--nav-glyph, "+") / "";
|
|
103
|
+
font: 300 2rem/1 var(--font-body);
|
|
104
|
+
transition: rotate var(--duration-normal) var(--ease-fluid);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.nav[data-nav~="compact"]:has(.nav__panel:popover-open) .nav__more::before,
|
|
108
|
+
.nav[data-nav~="compact"] .nav__panel .nav__more::before {
|
|
109
|
+
rotate: var(--nav-glyph-turn, 45deg);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.nav[data-nav~="compact"] .nav__panel[popover] {
|
|
113
|
+
display: none;
|
|
114
|
+
position: fixed;
|
|
115
|
+
inset: 0 0 0 auto;
|
|
116
|
+
inline-size: var(--nav-panel-size, min(20rem, 85vw));
|
|
117
|
+
block-size: 100dvh;
|
|
118
|
+
max-block-size: none;
|
|
119
|
+
margin: 0;
|
|
120
|
+
padding: var(--space-s) var(--page-edge) var(--space-l);
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
color: var(--nav-ink, var(--color-text));
|
|
123
|
+
background: var(--nav-bg, var(--color-background));
|
|
124
|
+
border: 0;
|
|
125
|
+
border-inline-start: var(--border-width) solid var(--color-border);
|
|
126
|
+
overflow: auto;
|
|
127
|
+
translate: 100% 0;
|
|
128
|
+
transition:
|
|
129
|
+
translate var(--duration-normal) var(--ease-fluid),
|
|
130
|
+
display var(--duration-normal) allow-discrete,
|
|
131
|
+
overlay var(--duration-normal) allow-discrete;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.nav[data-nav~="compact"] .nav__panel:popover-open {
|
|
135
|
+
display: flex;
|
|
136
|
+
translate: 0 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.nav[data-nav~="compact"] .nav__panel::backdrop {
|
|
140
|
+
background: oklch(0% 0 0 / 0);
|
|
141
|
+
transition:
|
|
142
|
+
background var(--duration-normal) var(--ease-fluid),
|
|
143
|
+
display var(--duration-normal) allow-discrete,
|
|
144
|
+
overlay var(--duration-normal) allow-discrete;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.nav[data-nav~="compact"] .nav__panel:popover-open::backdrop {
|
|
148
|
+
background: oklch(0% 0 0 / 0.25);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@starting-style {
|
|
152
|
+
.nav[data-nav~="compact"] .nav__panel:popover-open { translate: 100% 0; }
|
|
153
|
+
.nav[data-nav~="compact"] .nav__panel:popover-open .nav__more::before { rotate: 0deg; }
|
|
154
|
+
.nav[data-nav~="compact"] .nav__panel:popover-open::backdrop { background: oklch(0% 0 0 / 0); }
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* In the panel: the close × sits where the + was, the links stack at
|
|
158
|
+
full size, without the bar's squeeze. */
|
|
159
|
+
.nav[data-nav~="compact"] .nav__panel > .nav__more {
|
|
160
|
+
align-self: flex-end;
|
|
161
|
+
margin-inline-end: calc(-1 * var(--space-2));
|
|
162
|
+
margin-block-end: var(--space-m);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.nav[data-nav~="compact"] .nav__panel .nav__menu {
|
|
166
|
+
--_nav-track: initial;
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-direction: column;
|
|
169
|
+
align-items: stretch;
|
|
170
|
+
flex-basis: auto;
|
|
171
|
+
margin: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.nav[data-nav~="compact"] .nav__panel .nav__menu > li {
|
|
175
|
+
display: block;
|
|
176
|
+
border-block-start: var(--border-width) solid var(--color-border);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.nav[data-nav~="compact"] .nav__panel .nav__link {
|
|
180
|
+
min-block-size: 3.25rem;
|
|
181
|
+
padding-inline: 0;
|
|
182
|
+
font-size: var(--step-1);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Drop: the panel hangs under the bar and fades in; the bar's + turns
|
|
186
|
+
to × and stays the toggle. Needs anchor positioning; without it the
|
|
187
|
+
panel covers the bar from the top and shows its own ×. */
|
|
188
|
+
.nav[data-nav~="drop"] .nav__panel[popover] {
|
|
189
|
+
inset: 0 0 auto 0;
|
|
190
|
+
inline-size: auto;
|
|
191
|
+
block-size: auto;
|
|
192
|
+
max-block-size: 100dvh;
|
|
193
|
+
padding-block: 0 var(--space-m);
|
|
194
|
+
border: 0;
|
|
195
|
+
border-block-end: var(--border-width) solid var(--color-border);
|
|
196
|
+
translate: 0 0;
|
|
197
|
+
opacity: 0;
|
|
198
|
+
transition:
|
|
199
|
+
opacity var(--duration-normal) var(--ease-fluid),
|
|
200
|
+
translate var(--duration-normal) var(--ease-fluid),
|
|
201
|
+
display var(--duration-normal) allow-discrete,
|
|
202
|
+
overlay var(--duration-normal) allow-discrete;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.nav[data-nav~="drop"] .nav__panel:popover-open { opacity: 1; }
|
|
206
|
+
|
|
207
|
+
@starting-style {
|
|
208
|
+
.nav[data-nav~="drop"] .nav__panel:popover-open { opacity: 0; translate: 0 -0.5rem; }
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
@supports (anchor-name: --a) {
|
|
212
|
+
.nav[data-nav~="drop"] .nav__panel[popover] {
|
|
213
|
+
position-anchor: --fluid-nav;
|
|
214
|
+
inset: anchor(bottom) 0 auto 0;
|
|
215
|
+
max-block-size: calc(100dvh - anchor-size(height));
|
|
216
|
+
}
|
|
217
|
+
.nav[data-nav~="drop"] .nav__panel > .nav__more { display: none; }
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.nav[data-nav~="drop"] .nav__panel:is(*, :popover-open)::backdrop { background: transparent; }
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Reduced motion: no slide or turn (the reset already cuts transition
|
|
225
|
+
durations to near zero). */
|
|
226
|
+
@media (prefers-reduced-motion: reduce) {
|
|
227
|
+
.nav[data-nav~="compact"] .nav__panel[popover] { translate: none; }
|
|
228
|
+
@starting-style {
|
|
229
|
+
.nav[data-nav~="compact"] .nav__panel:popover-open { translate: none; }
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
/* ========================================
|
|
235
|
+
STICKY LINKS: data-sticky="links". data-sticky keeps the whole bar;
|
|
236
|
+
this pulls the bar up by its brand row once the links have a row of
|
|
237
|
+
their own, so only the links stay. A nav cannot query its own width,
|
|
238
|
+
so this uses the viewport: below 46rem the links always take their own
|
|
239
|
+
row in this mode, so the offset never hides a one-row bar.
|
|
240
|
+
======================================== */
|
|
241
|
+
|
|
242
|
+
.nav[data-sticky="links"] {
|
|
243
|
+
--nav-stick-offset: 0px;
|
|
244
|
+
inset-block-start: calc(-1 * var(--nav-stick-offset));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* A fixed brand row height, so the offset is exact. */
|
|
248
|
+
.nav[data-sticky="links"] .nav__brand { min-block-size: 2.75rem; }
|
|
249
|
+
|
|
250
|
+
@media (width < 46rem) {
|
|
251
|
+
.nav[data-sticky="links"]:not([data-nav~="icon"], [data-nav~="compact"]) {
|
|
252
|
+
/* top padding + brand row (a 2.75rem control) + the row gap */
|
|
253
|
+
--nav-stick-offset: calc(var(--space-s) + 2.75rem + var(--space-2));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.nav[data-sticky="links"]:not([data-nav~="icon"], [data-nav~="compact"]) .nav__menu {
|
|
257
|
+
flex-basis: 100%;
|
|
258
|
+
order: 3;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|