@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
package/src/components/nav.css
CHANGED
|
@@ -14,10 +14,67 @@
|
|
|
14
14
|
* </ul>
|
|
15
15
|
* </nav>
|
|
16
16
|
*
|
|
17
|
+
* The bar is the page's other scheme by default (_docs/defaults.md): a dark
|
|
18
|
+
* bar on a light page, a light bar on a dark one; tokens.css flips every
|
|
19
|
+
* colour role on it. Content on the .container edges, no hairline unless
|
|
20
|
+
* sticky. Links: sans 500 in the text colour, underlined on hover; the
|
|
21
|
+
* current page gets a 2px underline. No pills, no blur, no lift.
|
|
22
|
+
*
|
|
23
|
+
* Small screens (a bar under 40rem), every nav without the 1.x .nav__toggle
|
|
24
|
+
* (that one folds its menu behind the button): the links take their own row
|
|
25
|
+
* under the brand; the space between them and their tracking tighten first,
|
|
26
|
+
* then they wrap in balanced rows (4 links: 2 + 2, never 3 + 1). Both only
|
|
27
|
+
* ever remove orphans. data-nav="fit" is accepted and does nothing extra.
|
|
28
|
+
*
|
|
17
29
|
* Variants:
|
|
18
|
-
* data-
|
|
19
|
-
* data-variant="
|
|
20
|
-
* data-
|
|
30
|
+
* data-sticky - sticky, with a hairline under it
|
|
31
|
+
* data-variant="transparent" - no background, the page's colours
|
|
32
|
+
* data-bg="plain" - the page's colours on the page's background
|
|
33
|
+
* data-bg="inverse" - the default; forces the flipped bar on a transparent nav
|
|
34
|
+
*
|
|
35
|
+
* Alignment follows the page (_docs/defaults.md): wrapped link rows inherit
|
|
36
|
+
* text-align, so <body data-align="center"> centres them; data-align="center"
|
|
37
|
+
* on the .nav, on the body or header it is a direct child of, or on the body
|
|
38
|
+
* of that header, also centres the masthead (the brand on its own row, the rest under it). The
|
|
39
|
+
* nearest setting wins.
|
|
40
|
+
*
|
|
41
|
+
* Modes, in the opt-in module nav-modes.css (dist/fluid-nav.min.css; link it
|
|
42
|
+
* after core, as the TOC module is). Without it each falls back to the plain nav.
|
|
43
|
+
* data-sticky="links" - two rows: the brand row scrolls away, the links stick
|
|
44
|
+
* data-nav="icon" - the brand shrinks to its .nav__brand-mark; the links
|
|
45
|
+
* share its row: <a class="nav__brand"><span class="nav__brand-mark"
|
|
46
|
+
* aria-hidden="true">NE</span><span class="nav__brand-name">Name</span></a>
|
|
47
|
+
* data-nav="compact" - a "+" button opens the links in a panel that slides
|
|
48
|
+
* over from the end edge; the "+" turns into a close "×". No JS (popover):
|
|
49
|
+
* <button class="nav__more" type="button" popovertarget="nav-panel">
|
|
50
|
+
* <span class="sr-only">Menu</span></button>
|
|
51
|
+
* <div class="nav__panel" id="nav-panel" popover>
|
|
52
|
+
* <button class="nav__more" type="button" popovertarget="nav-panel"
|
|
53
|
+
* popovertargetaction="hide"><span class="sr-only">Close menu</span></button>
|
|
54
|
+
* <ul class="nav__menu" role="list">…</ul>
|
|
55
|
+
* </div>
|
|
56
|
+
* Without popover support, or on a wide bar, the panel is invisible to
|
|
57
|
+
* layout and the links show as usual, so the markup is safe on every nav.
|
|
58
|
+
* data-nav="compact drop" - the panel drops under the bar instead
|
|
59
|
+
*
|
|
60
|
+
* Tokens (a theme sets them on :root; the fallbacks are the defaults):
|
|
61
|
+
* --nav-gap link side padding, half the space between links (--space-3)
|
|
62
|
+
* --nav-gap-min the squeeze stops here (--space-2, 8px)
|
|
63
|
+
* --nav-tracking link letter-spacing (0em)
|
|
64
|
+
* --nav-tracking-min the squeeze stops here (= --nav-tracking)
|
|
65
|
+
* --nav-wrap-align start | center | end, for wrapped rows (unset: the
|
|
66
|
+
* page's alignment)
|
|
67
|
+
* --nav-bg, --nav-ink a bar colour and the colour of what is on it (text,
|
|
68
|
+
* links, toggles, marks, focus ring; not the CTA,
|
|
69
|
+
* button, badge or logo-mark fills); set both, on
|
|
70
|
+
* :root: --nav-bg: var(--accent-fill);
|
|
71
|
+
* --nav-ink: var(--on-accent-fill) (_docs/defaults.md)
|
|
72
|
+
* --nav-glyph the compact button's glyph ("+")
|
|
73
|
+
* --nav-glyph-turn how far it turns when open (45deg: + to ×)
|
|
74
|
+
* --nav-panel-size width of the compact side panel (min(20rem, 85vw))
|
|
75
|
+
* --nav-stick-offset how far a data-sticky="links" bar hides (set by the module)
|
|
76
|
+
* --nav-sticky-size jump-link clearance under a sticky bar (5rem; 13rem
|
|
77
|
+
* under 64rem, where the links may wrap)
|
|
21
78
|
*/
|
|
22
79
|
|
|
23
80
|
@layer components {
|
|
@@ -26,152 +83,155 @@
|
|
|
26
83
|
======================================== */
|
|
27
84
|
|
|
28
85
|
.nav {
|
|
29
|
-
/* Layout */
|
|
30
86
|
display: flex;
|
|
87
|
+
/* Wrap here, not in the container query below: an element cannot query
|
|
88
|
+
its own container. */
|
|
89
|
+
flex-wrap: wrap;
|
|
31
90
|
align-items: center;
|
|
32
|
-
gap: var(--space-
|
|
33
|
-
padding-block: var(--space-
|
|
34
|
-
padding-inline: var(--
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
background-color: var(--_nav-bg, var(--color-background));
|
|
38
|
-
border-block-end: 1px solid var(--_nav-border, var(--color-border-subtle));
|
|
39
|
-
|
|
40
|
-
/* Container for responsive behavior */
|
|
91
|
+
gap: var(--space-2) var(--space-m);
|
|
92
|
+
padding-block: var(--space-s);
|
|
93
|
+
padding-inline: max(var(--page-edge), (100% - var(--container-content)) / 2);
|
|
94
|
+
background-color: var(--_nav-bg, var(--nav-bg, var(--color-background)));
|
|
95
|
+
border-block-end: var(--border-width) solid var(--_nav-border, transparent);
|
|
41
96
|
container-type: inline-size;
|
|
42
97
|
container-name: nav;
|
|
98
|
+
--color-focus: var(--nav-ink, var(--accent-ink));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* A nav that is also a .container already sits on the content edges; the
|
|
102
|
+
edge padding (a % of the body, not of the nav) would take its width. */
|
|
103
|
+
.nav.container { padding-inline: 0; }
|
|
104
|
+
|
|
105
|
+
/* As the page's top bar, its paint still reaches the screen edges: a
|
|
106
|
+
border image outset paints past the box without adding scroll,
|
|
107
|
+
hairline included. Paint only, so content scrolled under a sticky
|
|
108
|
+
bar's sides stays clickable; forced colours keep the system Canvas. */
|
|
109
|
+
:is(body, body > header) > .nav.container {
|
|
110
|
+
--_p: var(--_nav-bg, var(--nav-bg, var(--color-background)));
|
|
111
|
+
border-image: linear-gradient(0deg, var(--_nav-border, var(--_p)) var(--border-width), var(--_p) 0) fill 0 / 0 / 0 100vmax;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@media (forced-colors: active) {
|
|
115
|
+
/* -source: lightningcss minifies the border-image shorthand "none" to
|
|
116
|
+
an empty, invalid declaration (CLAUDE.md Exceptions). */
|
|
117
|
+
:is(body, body > header) > .nav.container { border-image-source: none; }
|
|
43
118
|
}
|
|
44
119
|
|
|
45
|
-
/* Sticky navigation */
|
|
46
120
|
.nav[data-sticky] {
|
|
47
121
|
position: sticky;
|
|
48
122
|
inset-block-start: 0;
|
|
49
123
|
z-index: var(--z-sticky);
|
|
50
|
-
|
|
51
|
-
|
|
124
|
+
--_nav-border: var(--color-border);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* A jump to #section must land below a sticky bar (WCAG 2.4.11). CSS
|
|
128
|
+
cannot read the bar's height (72px on one row; up to about 210px when
|
|
129
|
+
the links wrap on a phone), so the clearance is generous: too much
|
|
130
|
+
leaves a gap, too little hides the heading. A site with a known bar
|
|
131
|
+
sets --nav-sticky-size. Targets add their own scroll margin on top. */
|
|
132
|
+
:root:has(.nav[data-sticky]) { scroll-padding-block-start: var(--nav-sticky-size, 5rem); }
|
|
133
|
+
|
|
134
|
+
@media (width < 64rem) {
|
|
135
|
+
:root:has(.nav[data-sticky]) { scroll-padding-block-start: var(--nav-sticky-size, 13rem); }
|
|
52
136
|
}
|
|
53
137
|
|
|
54
|
-
/* Transparent variant */
|
|
55
138
|
.nav[data-variant="transparent"] {
|
|
56
139
|
--_nav-bg: transparent;
|
|
57
140
|
--_nav-border: transparent;
|
|
58
141
|
}
|
|
59
142
|
|
|
60
|
-
/*
|
|
61
|
-
.nav[data-variant="
|
|
62
|
-
--_nav-border: transparent;
|
|
63
|
-
box-shadow: var(--shadow-sm);
|
|
64
|
-
}
|
|
143
|
+
/* Over a hero, everything on it takes the hero's text colour. */
|
|
144
|
+
.nav[data-variant="transparent"]:not([data-bg="inverse"]) { --nav-ink: currentColor; }
|
|
65
145
|
|
|
146
|
+
/* After transparent on purpose: a forced inverse bar needs its paint. */
|
|
147
|
+
.nav[data-bg="inverse"] { --_nav-bg: var(--nav-bg, var(--color-background)); }
|
|
66
148
|
|
|
67
|
-
/* Brand / Logo - adopts active preset's font */
|
|
68
149
|
.nav__brand {
|
|
69
|
-
font-family: var(--font-heading, var(--font-body, var(--font-system)));
|
|
70
|
-
font-size: var(--font-size-lg);
|
|
71
|
-
font-weight: var(--weight-semibold);
|
|
72
|
-
color: var(--color-text);
|
|
73
|
-
text-decoration: none;
|
|
74
150
|
display: flex;
|
|
75
151
|
align-items: center;
|
|
76
152
|
gap: var(--space-2);
|
|
77
153
|
flex-shrink: 0;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
opacity: 0.8;
|
|
154
|
+
font-family: var(--font-heading);
|
|
155
|
+
font-size: var(--step-1);
|
|
156
|
+
font-weight: calc(500 + var(--_dark-weight));
|
|
157
|
+
letter-spacing: -0.01em;
|
|
158
|
+
color: var(--nav-ink, var(--color-text));
|
|
159
|
+
text-decoration: none;
|
|
85
160
|
}
|
|
86
161
|
|
|
87
|
-
.nav__brand img,
|
|
88
|
-
.nav__brand svg {
|
|
162
|
+
.nav__brand :is(img, svg) {
|
|
89
163
|
block-size: 2rem;
|
|
90
164
|
inline-size: auto;
|
|
91
165
|
}
|
|
92
166
|
|
|
93
|
-
/* Active preset name indicator */
|
|
94
|
-
.nav__preset-name {
|
|
95
|
-
font-family: var(--font-heading, var(--font-body, var(--font-system)));
|
|
96
|
-
font-size: var(--font-size-xs);
|
|
97
|
-
font-weight: var(--weight-medium);
|
|
98
|
-
color: var(--accent);
|
|
99
|
-
letter-spacing: var(--tracking-wide);
|
|
100
|
-
text-transform: uppercase;
|
|
101
|
-
white-space: nowrap;
|
|
102
|
-
flex-shrink: 0;
|
|
103
|
-
transition:
|
|
104
|
-
color var(--duration-normal) var(--ease-fluid),
|
|
105
|
-
font-family var(--duration-normal) var(--ease-fluid);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.nav__preset-name:empty {
|
|
109
|
-
display: none;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
/* Menu container */
|
|
114
167
|
.nav__menu {
|
|
115
168
|
display: flex;
|
|
169
|
+
flex-wrap: wrap;
|
|
116
170
|
align-items: center;
|
|
117
|
-
gap: var(--space-1);
|
|
171
|
+
gap: 0 var(--space-1);
|
|
118
172
|
margin: 0;
|
|
119
|
-
margin-inline-start: auto;
|
|
173
|
+
margin-inline-start: auto;
|
|
120
174
|
padding: 0;
|
|
121
175
|
list-style: none;
|
|
122
|
-
overflow: visible;
|
|
176
|
+
overflow: visible;
|
|
123
177
|
}
|
|
124
178
|
|
|
125
|
-
/* Menu items - ensure alignment and reset base styles */
|
|
126
179
|
.nav__menu > li {
|
|
127
180
|
display: flex;
|
|
128
181
|
align-items: center;
|
|
129
|
-
margin: 0;
|
|
130
|
-
position: relative;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/* Keep menu at start (next to brand) */
|
|
134
|
-
.nav__menu[data-align="start"] {
|
|
135
|
-
margin-inline-start: 0;
|
|
182
|
+
margin: 0;
|
|
183
|
+
position: relative;
|
|
136
184
|
}
|
|
137
185
|
|
|
138
|
-
|
|
139
|
-
.nav__menu[data-align="center"] {
|
|
140
|
-
margin-inline: auto;
|
|
141
|
-
}
|
|
186
|
+
.nav__menu[data-align="start"] { margin-inline-start: 0; --nav-wrap-align: start; }
|
|
187
|
+
.nav__menu[data-align="center"] { margin-inline: auto; --nav-wrap-align: center; }
|
|
142
188
|
|
|
189
|
+
/* Centred masthead: data-align="center" on the nav, its header or the
|
|
190
|
+
body (unless a nearer header or the nav sets its own), the brand on
|
|
191
|
+
its own row. */
|
|
192
|
+
:is(.nav[data-align="center"], :is(body, header)[data-align="center"] > .nav:not([data-align]), body[data-align="center"] > header:not([data-align]) > .nav:not([data-align])) { justify-content: center; }
|
|
193
|
+
:is(.nav[data-align="center"], :is(body, header)[data-align="center"] > .nav:not([data-align]), body[data-align="center"] > header:not([data-align]) > .nav:not([data-align])) > .nav__brand { flex-basis: 100%; justify-content: center; }
|
|
194
|
+
:is(.nav[data-align="center"], :is(body, header)[data-align="center"] > .nav:not([data-align]), body[data-align="center"] > header:not([data-align]) > .nav:not([data-align])) > .nav__actions { margin-inline: 0; }
|
|
195
|
+
/* :where(): the small-screen menu keeps its own (negative) margins. */
|
|
196
|
+
:where(.nav[data-align="center"], :is(body, header)[data-align="center"] > .nav:not([data-align]), body[data-align="center"] > header:not([data-align]) > .nav:not([data-align])) > :is(.nav__menu, .nav__panel) { margin-inline: 0; }
|
|
143
197
|
|
|
144
|
-
/*
|
|
145
|
-
.nav__link {
|
|
198
|
+
/* --_nav-pad and --_nav-track are the small-screen squeeze (below). */
|
|
199
|
+
:is(.nav__link, .nav__dropdown-trigger, .nav__dropdown-link) {
|
|
146
200
|
display: flex;
|
|
147
201
|
align-items: center;
|
|
148
|
-
gap: var(--space-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
font-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
202
|
+
gap: var(--space-1);
|
|
203
|
+
min-block-size: 2.75rem;
|
|
204
|
+
padding-inline: var(--_nav-pad, var(--nav-gap, var(--space-3)));
|
|
205
|
+
font-family: var(--font-body);
|
|
206
|
+
font-size: 0.9375rem;
|
|
207
|
+
font-weight: calc(500 + var(--_dark-weight));
|
|
208
|
+
line-height: 1;
|
|
209
|
+
letter-spacing: var(--_nav-track, var(--nav-tracking, 0em));
|
|
210
|
+
color: var(--nav-ink, var(--color-text));
|
|
211
|
+
white-space: nowrap;
|
|
212
|
+
text-decoration-line: none;
|
|
213
|
+
text-decoration-thickness: 0.06em;
|
|
214
|
+
text-underline-offset: 0.4em;
|
|
215
|
+
background: none;
|
|
216
|
+
border: 0;
|
|
217
|
+
border-radius: var(--radius-control);
|
|
218
|
+
cursor: pointer;
|
|
160
219
|
}
|
|
161
220
|
|
|
162
|
-
.nav__link:hover {
|
|
163
|
-
|
|
164
|
-
|
|
221
|
+
:is(.nav__link, .nav__dropdown-trigger, .nav__dropdown-link):hover {
|
|
222
|
+
text-decoration-line: underline;
|
|
223
|
+
text-decoration-color: var(--nav-ink, var(--accent-ink));
|
|
165
224
|
}
|
|
166
225
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
226
|
+
/* The accent as ink, not fill: it flips with the scheme, so the mark
|
|
227
|
+
clears 3:1 on a dark band or an inverse bar too. */
|
|
228
|
+
:is(.nav__link, .nav__dropdown-link):is([aria-current], [data-active]),
|
|
229
|
+
.nav__dropdown-trigger[data-active] {
|
|
230
|
+
text-decoration-line: underline;
|
|
231
|
+
text-decoration-thickness: 2px;
|
|
232
|
+
text-decoration-color: var(--nav-ink, var(--accent-ink));
|
|
171
233
|
}
|
|
172
234
|
|
|
173
|
-
|
|
174
|
-
/* Actions area (buttons, search, etc.) */
|
|
175
235
|
.nav__actions {
|
|
176
236
|
display: flex;
|
|
177
237
|
align-items: center;
|
|
@@ -179,198 +239,172 @@
|
|
|
179
239
|
margin-inline-start: auto;
|
|
180
240
|
}
|
|
181
241
|
|
|
242
|
+
/* The links always hang at the end edge: with a CTA after them, the CTA
|
|
243
|
+
takes the bar's gap, not a second auto margin (the menu may sit in a
|
|
244
|
+
compact .nav__panel). */
|
|
245
|
+
:is(.nav__menu, .nav__panel) ~ .nav__actions { margin-inline-start: 0; }
|
|
246
|
+
|
|
182
247
|
|
|
183
248
|
/* ========================================
|
|
184
249
|
DROPDOWN MENUS
|
|
185
250
|
======================================== */
|
|
186
251
|
|
|
187
|
-
.nav__dropdown {
|
|
188
|
-
position: relative;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.nav__dropdown-trigger {
|
|
192
|
-
display: flex;
|
|
193
|
-
align-items: center;
|
|
194
|
-
gap: var(--space-1);
|
|
195
|
-
padding: var(--space-2) var(--space-3);
|
|
196
|
-
font-size: var(--font-size-sm);
|
|
197
|
-
font-weight: var(--weight-medium);
|
|
198
|
-
color: var(--color-text-muted);
|
|
199
|
-
text-decoration: none;
|
|
200
|
-
background: none;
|
|
201
|
-
border: none;
|
|
202
|
-
border-radius: var(--radius-md);
|
|
203
|
-
cursor: pointer;
|
|
204
|
-
transition:
|
|
205
|
-
color var(--duration-normal) var(--ease-fluid),
|
|
206
|
-
background-color var(--duration-normal) var(--ease-fluid);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.nav__dropdown-trigger:hover,
|
|
210
|
-
.nav__dropdown:hover .nav__dropdown-trigger,
|
|
211
|
-
.nav__dropdown:focus-within .nav__dropdown-trigger {
|
|
212
|
-
color: var(--color-text);
|
|
213
|
-
background-color: var(--color-surface);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.nav__dropdown-trigger[data-active] {
|
|
217
|
-
color: var(--accent);
|
|
218
|
-
}
|
|
252
|
+
.nav__dropdown { position: relative; }
|
|
219
253
|
|
|
220
254
|
.nav__dropdown-trigger svg {
|
|
221
255
|
inline-size: 1em;
|
|
222
256
|
block-size: 1em;
|
|
223
|
-
transition: transform var(--duration-normal) var(--ease-fluid);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
.nav__dropdown:hover .nav__dropdown-trigger svg,
|
|
227
|
-
.nav__dropdown:focus-within .nav__dropdown-trigger svg {
|
|
228
|
-
transform: rotate(180deg);
|
|
229
257
|
}
|
|
230
258
|
|
|
231
259
|
.nav__dropdown-menu {
|
|
232
260
|
position: absolute;
|
|
233
261
|
inset-block-start: 100%;
|
|
234
262
|
inset-inline-start: 0;
|
|
263
|
+
z-index: var(--z-dropdown);
|
|
235
264
|
min-inline-size: 12rem;
|
|
236
|
-
padding: var(--space-
|
|
265
|
+
padding: var(--space-1) 0;
|
|
237
266
|
margin: 0;
|
|
238
|
-
margin-block-start: var(--space-1);
|
|
239
267
|
list-style: none;
|
|
240
|
-
background-color: var(--color-background);
|
|
241
|
-
border:
|
|
242
|
-
border-radius: var(--radius-
|
|
243
|
-
box-shadow: var(--shadow-lg);
|
|
268
|
+
background-color: var(--nav-bg, var(--color-background));
|
|
269
|
+
border: var(--border-width) solid var(--color-border-strong);
|
|
270
|
+
border-radius: var(--radius-card);
|
|
244
271
|
opacity: 0;
|
|
245
272
|
visibility: hidden;
|
|
246
|
-
transform: translateY(-0.5rem);
|
|
247
273
|
transition:
|
|
248
|
-
opacity var(--duration-
|
|
249
|
-
visibility var(--duration-
|
|
250
|
-
transform var(--duration-normal) var(--ease-fluid);
|
|
251
|
-
z-index: var(--z-dropdown);
|
|
274
|
+
opacity var(--duration-fast) var(--ease-fluid),
|
|
275
|
+
visibility var(--duration-fast) var(--ease-fluid);
|
|
252
276
|
}
|
|
253
277
|
|
|
254
|
-
.nav__dropdown:hover .nav__dropdown-menu
|
|
255
|
-
.nav__dropdown:focus-within .nav__dropdown-menu {
|
|
278
|
+
.nav__dropdown:is(:hover, :focus-within) .nav__dropdown-menu {
|
|
256
279
|
opacity: 1;
|
|
257
280
|
visibility: visible;
|
|
258
|
-
transform: translateY(0);
|
|
259
281
|
}
|
|
260
282
|
|
|
261
|
-
.nav__dropdown-menu li {
|
|
262
|
-
margin: 0;
|
|
263
|
-
}
|
|
283
|
+
.nav__dropdown-menu li { margin: 0; }
|
|
264
284
|
|
|
265
|
-
.
|
|
266
|
-
|
|
267
|
-
padding: var(--space-2) var(--space-3);
|
|
268
|
-
font-size: var(--font-size-sm);
|
|
269
|
-
color: var(--color-text-muted);
|
|
270
|
-
text-decoration: none;
|
|
271
|
-
border-radius: var(--radius-md);
|
|
272
|
-
transition:
|
|
273
|
-
color var(--duration-normal) var(--ease-fluid),
|
|
274
|
-
background-color var(--duration-normal) var(--ease-fluid);
|
|
275
|
-
}
|
|
285
|
+
/* Inset, so the ring stays on the panel's colour, not the page's. */
|
|
286
|
+
.nav__dropdown-link:focus-visible { outline-offset: calc(-1 * var(--focus-ring-width)); }
|
|
276
287
|
|
|
277
|
-
.nav__dropdown-link:hover {
|
|
278
|
-
color: var(--color-text);
|
|
279
|
-
background-color: var(--color-surface);
|
|
280
|
-
}
|
|
281
288
|
|
|
282
|
-
.
|
|
283
|
-
color: var(--accent);
|
|
284
|
-
background-color: var(--accent-subtle);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/* CTA Button in nav */
|
|
289
|
+
/* CTA in the bar: a primary button, no lift. */
|
|
288
290
|
.nav__cta {
|
|
289
291
|
display: inline-flex;
|
|
290
292
|
align-items: center;
|
|
291
293
|
gap: var(--space-2);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
font-
|
|
295
|
-
|
|
294
|
+
min-block-size: 2.75rem;
|
|
295
|
+
padding-inline: 1.2em;
|
|
296
|
+
font-size: 0.9375rem;
|
|
297
|
+
font-weight: calc(var(--weight-semibold) + var(--_dark-weight));
|
|
298
|
+
color: var(--on-accent-fill);
|
|
296
299
|
text-decoration: none;
|
|
297
|
-
background-color: var(--accent);
|
|
298
|
-
border-radius: var(--radius-
|
|
299
|
-
transition:
|
|
300
|
-
background-color var(--duration-normal) var(--ease-fluid),
|
|
301
|
-
transform var(--duration-fast) var(--ease-settle);
|
|
300
|
+
background-color: var(--accent-fill);
|
|
301
|
+
border-radius: var(--radius-control);
|
|
302
|
+
transition: background-color var(--duration-fast) var(--ease-fluid);
|
|
302
303
|
}
|
|
303
304
|
|
|
304
|
-
.nav__cta:hover {
|
|
305
|
-
background-color: var(--accent-hover);
|
|
306
|
-
transform: translateY(-1px);
|
|
307
|
-
}
|
|
305
|
+
.nav__cta:hover { background-color: var(--accent-fill-hover); }
|
|
308
306
|
|
|
309
307
|
|
|
310
308
|
/* ========================================
|
|
311
|
-
|
|
312
|
-
|
|
309
|
+
TOGGLES
|
|
310
|
+
.nav__toggle is the 1.x JS menu button (aria-expanded, or data-open on
|
|
311
|
+
the menu), kept so existing markup works. data-nav="compact" (below) is
|
|
312
|
+
its no-JS successor: use that for new sites.
|
|
313
313
|
======================================== */
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
.nav__toggle {
|
|
317
|
-
display: none;
|
|
318
|
-
padding: var(--space-2);
|
|
319
|
-
background: none;
|
|
320
|
-
border: none;
|
|
321
|
-
color: var(--color-text);
|
|
322
|
-
cursor: pointer;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
.nav__toggle svg {
|
|
326
|
-
inline-size: 1.5rem;
|
|
327
|
-
block-size: 1.5rem;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/* Theme Toggle Button */
|
|
331
|
-
.nav__theme-toggle {
|
|
315
|
+
:is(.nav__toggle, .nav__theme-toggle) {
|
|
332
316
|
display: flex;
|
|
333
317
|
align-items: center;
|
|
334
318
|
justify-content: center;
|
|
319
|
+
flex-shrink: 0;
|
|
320
|
+
min-inline-size: 2.75rem;
|
|
321
|
+
min-block-size: 2.75rem;
|
|
335
322
|
padding: var(--space-2);
|
|
323
|
+
color: var(--nav-ink, var(--color-text));
|
|
336
324
|
background: none;
|
|
337
|
-
border:
|
|
338
|
-
border-radius: var(--radius-md);
|
|
339
|
-
color: var(--color-text-muted);
|
|
325
|
+
border: 0;
|
|
340
326
|
cursor: pointer;
|
|
341
|
-
transition:
|
|
342
|
-
color var(--duration-normal) var(--ease-fluid),
|
|
343
|
-
background-color var(--duration-normal) var(--ease-fluid);
|
|
344
327
|
}
|
|
345
328
|
|
|
346
|
-
.
|
|
347
|
-
color: var(--color-text);
|
|
348
|
-
background-color: var(--color-surface);
|
|
349
|
-
}
|
|
329
|
+
.nav__toggle { display: none; }
|
|
350
330
|
|
|
351
|
-
.
|
|
352
|
-
|
|
353
|
-
|
|
331
|
+
.nav__toggle svg { inline-size: 1.5rem; block-size: 1.5rem; }
|
|
332
|
+
.nav__theme-toggle svg { inline-size: 1.25rem; block-size: 1.25rem; }
|
|
333
|
+
|
|
334
|
+
/* Icon buttons in the bar stay quiet on hover and press (the generic
|
|
335
|
+
button fill is for calls to action). */
|
|
336
|
+
.nav :is(.nav__toggle, .nav__theme-toggle, .nav__more, .nav__dropdown-trigger):is(:hover, :active):not(:disabled) {
|
|
337
|
+
color: var(--nav-ink, var(--color-text));
|
|
338
|
+
background-color: transparent;
|
|
354
339
|
}
|
|
355
340
|
|
|
356
|
-
/* Show appropriate icon based on theme */
|
|
357
341
|
.nav__theme-toggle .icon-sun { display: none; }
|
|
358
342
|
.nav__theme-toggle .icon-moon { display: block; }
|
|
359
|
-
|
|
360
343
|
[data-theme="dark"] .nav__theme-toggle .icon-sun { display: block; }
|
|
361
344
|
[data-theme="dark"] .nav__theme-toggle .icon-moon { display: none; }
|
|
362
345
|
|
|
363
346
|
|
|
364
|
-
/*
|
|
347
|
+
/* ========================================
|
|
348
|
+
NARROW: brand and CTA share the top row. With a .nav__toggle the menu
|
|
349
|
+
folds under it; without one the links wrap in a row under the brand,
|
|
350
|
+
so a bar with no toggle never loses its links.
|
|
351
|
+
======================================== */
|
|
352
|
+
|
|
365
353
|
@container nav (max-width: 40rem) {
|
|
366
|
-
.
|
|
367
|
-
|
|
354
|
+
.nav__brand { min-inline-size: 0; }
|
|
355
|
+
|
|
356
|
+
.nav > .nav__actions {
|
|
357
|
+
order: 1;
|
|
358
|
+
margin-inline-start: auto;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.nav__cta {
|
|
362
|
+
min-block-size: 2.75rem;
|
|
363
|
+
padding-inline: 1em;
|
|
364
|
+
font-size: var(--step--1);
|
|
368
365
|
}
|
|
369
366
|
|
|
367
|
+
/* The links' own row. First the squeeze: from full at a 40rem bar to the
|
|
368
|
+
minimum at 20rem, 1px of padding per 80px of bar and 1px of tracking
|
|
369
|
+
per 300px. Then the balance: inline items in a block, so text-wrap can
|
|
370
|
+
even the rows (4: 2 + 2, 3: 2 + 1, 5: 3 + 2). The link padding is the
|
|
371
|
+
gap, so the spaces between items are zeroed (font-size 0). Without
|
|
372
|
+
text-wrap: balance the links wrap as before. */
|
|
373
|
+
.nav:not(:has(.nav__toggle)) .nav__menu {
|
|
374
|
+
--_nav-pad: clamp(var(--nav-gap-min, var(--space-2)),
|
|
375
|
+
calc(var(--nav-gap-min, var(--space-2)) + (100cqi - 20rem) / 80),
|
|
376
|
+
var(--nav-gap, var(--space-3)));
|
|
377
|
+
--_nav-track: clamp(var(--nav-tracking-min, var(--nav-tracking, 0em)),
|
|
378
|
+
calc(var(--nav-tracking-min, var(--nav-tracking, 0em)) + (100cqi - 20rem) / 300),
|
|
379
|
+
var(--nav-tracking, 0em));
|
|
380
|
+
display: block;
|
|
381
|
+
flex-basis: 100%;
|
|
382
|
+
order: 3;
|
|
383
|
+
margin-inline: calc(-1 * var(--_nav-pad));
|
|
384
|
+
font-size: 0;
|
|
385
|
+
/* No fallback: unset, the declaration is invalid at computed-value
|
|
386
|
+
time and text-align inherits, so the rows follow the page. */
|
|
387
|
+
text-align: var(--nav-wrap-align);
|
|
388
|
+
text-wrap: balance;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.nav:not(:has(.nav__toggle)) .nav__menu > li {
|
|
392
|
+
display: inline-flex;
|
|
393
|
+
vertical-align: top;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* With a toggle, the brand takes the row beside it and wraps. */
|
|
397
|
+
.nav__brand:has(~ .nav__toggle) {
|
|
398
|
+
flex: 1 1 0;
|
|
399
|
+
min-inline-size: 0;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* Top row: brand, CTA (order 1), toggle (order 2); the menu is the
|
|
403
|
+
next row (order 3). */
|
|
370
404
|
.nav__toggle {
|
|
371
405
|
display: flex;
|
|
372
406
|
margin-inline-start: auto;
|
|
373
|
-
order:
|
|
407
|
+
order: 2;
|
|
374
408
|
}
|
|
375
409
|
|
|
376
410
|
.nav__theme-toggle {
|
|
@@ -378,15 +412,11 @@
|
|
|
378
412
|
margin-inline-start: auto;
|
|
379
413
|
}
|
|
380
414
|
|
|
381
|
-
|
|
382
|
-
.nav__menu {
|
|
415
|
+
.nav:has(.nav__toggle) .nav__menu {
|
|
383
416
|
flex-basis: 100%;
|
|
384
417
|
flex-direction: column;
|
|
385
418
|
align-items: stretch;
|
|
386
|
-
|
|
387
|
-
padding-block-start: var(--space-4);
|
|
388
|
-
order: 2;
|
|
389
|
-
/* Hidden state */
|
|
419
|
+
order: 3;
|
|
390
420
|
display: flex;
|
|
391
421
|
visibility: hidden;
|
|
392
422
|
opacity: 0;
|
|
@@ -398,79 +428,39 @@
|
|
|
398
428
|
max-block-size var(--duration-normal) var(--ease-fluid);
|
|
399
429
|
}
|
|
400
430
|
|
|
401
|
-
|
|
402
|
-
.nav__menu[data-open],
|
|
431
|
+
.nav .nav__menu[data-open],
|
|
403
432
|
.nav:has(.nav__toggle[aria-expanded="true"]) .nav__menu {
|
|
433
|
+
padding-block-start: var(--space-2);
|
|
404
434
|
visibility: visible;
|
|
405
435
|
opacity: 1;
|
|
406
|
-
max-block-size: 100vh;
|
|
436
|
+
max-block-size: 100vh;
|
|
407
437
|
}
|
|
408
438
|
|
|
409
|
-
.nav__menu > li {
|
|
410
|
-
display: block;
|
|
411
|
-
opacity: 0;
|
|
412
|
-
transform: translateY(-0.5rem);
|
|
413
|
-
transition:
|
|
414
|
-
opacity var(--duration-fast) var(--ease-fluid),
|
|
415
|
-
transform var(--duration-fast) var(--ease-settle);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/* Animate items in when menu opens */
|
|
419
|
-
.nav__menu[data-open] > li,
|
|
420
|
-
.nav:has(.nav__toggle[aria-expanded="true"]) .nav__menu > li {
|
|
421
|
-
opacity: 1;
|
|
422
|
-
transform: translateY(0);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
/* Stagger the item animations */
|
|
426
|
-
.nav__menu > li:nth-child(1) { transition-delay: 50ms; }
|
|
427
|
-
.nav__menu > li:nth-child(2) { transition-delay: 100ms; }
|
|
428
|
-
.nav__menu > li:nth-child(3) { transition-delay: 150ms; }
|
|
429
|
-
.nav__menu > li:nth-child(4) { transition-delay: 200ms; }
|
|
430
|
-
.nav__menu > li:nth-child(5) { transition-delay: 250ms; }
|
|
431
|
-
.nav__menu > li:nth-child(6) { transition-delay: 300ms; }
|
|
432
|
-
|
|
433
|
-
.nav__link {
|
|
439
|
+
.nav:has(.nav__toggle) .nav__menu > li {
|
|
434
440
|
display: block;
|
|
435
|
-
|
|
441
|
+
border-block-start: var(--border-width) solid var(--color-border);
|
|
436
442
|
}
|
|
437
443
|
|
|
438
|
-
/* Mobile dropdowns - always visible, stacked */
|
|
439
444
|
.nav__dropdown-menu {
|
|
440
445
|
position: static;
|
|
441
446
|
opacity: 1;
|
|
442
447
|
visibility: visible;
|
|
443
|
-
|
|
444
|
-
box-shadow: none;
|
|
445
|
-
border: none;
|
|
448
|
+
border: 0;
|
|
446
449
|
padding-inline-start: var(--space-4);
|
|
447
|
-
margin-block-start: 0;
|
|
448
450
|
background-color: transparent;
|
|
449
451
|
}
|
|
450
452
|
|
|
451
|
-
.nav__dropdown-trigger svg {
|
|
452
|
-
display: none;
|
|
453
|
-
}
|
|
453
|
+
.nav__dropdown-trigger svg { display: none; }
|
|
454
454
|
|
|
455
|
-
.
|
|
456
|
-
|
|
457
|
-
font-weight: var(--weight-semibold);
|
|
458
|
-
color: var(--color-text);
|
|
459
|
-
}
|
|
455
|
+
.nav:has(.nav__actions) .nav__toggle { margin-inline-start: 0; }
|
|
456
|
+
}
|
|
460
457
|
|
|
461
|
-
.nav__cta {
|
|
462
|
-
margin-block-start: var(--space-3);
|
|
463
|
-
justify-content: center;
|
|
464
|
-
}
|
|
465
458
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
order: 3;
|
|
472
|
-
}
|
|
473
|
-
}
|
|
459
|
+
/* The data-nav="compact" markup (fluid-nav.min.css) is safe without that
|
|
460
|
+
file: the panel wrapper is invisible to layout and its buttons hidden,
|
|
461
|
+
so the links show as usual. */
|
|
462
|
+
.nav__panel { display: contents; }
|
|
463
|
+
.nav__more { display: none; }
|
|
474
464
|
|
|
475
465
|
|
|
476
466
|
/* ========================================
|
|
@@ -485,13 +475,14 @@
|
|
|
485
475
|
padding: 0;
|
|
486
476
|
margin: 0;
|
|
487
477
|
list-style: none;
|
|
488
|
-
font-size: var(--
|
|
478
|
+
font-size: var(--step--1);
|
|
489
479
|
}
|
|
490
480
|
|
|
491
481
|
.breadcrumb__item {
|
|
492
482
|
display: inline-flex;
|
|
493
483
|
align-items: center;
|
|
494
484
|
gap: var(--space-2);
|
|
485
|
+
margin: 0;
|
|
495
486
|
line-height: 1;
|
|
496
487
|
}
|
|
497
488
|
|
|
@@ -500,21 +491,19 @@
|
|
|
500
491
|
color: var(--color-text-subtle);
|
|
501
492
|
}
|
|
502
493
|
|
|
503
|
-
.breadcrumb__item:last-child::after {
|
|
504
|
-
content: none;
|
|
505
|
-
}
|
|
494
|
+
.breadcrumb__item:last-child::after { content: none; }
|
|
506
495
|
|
|
507
496
|
.breadcrumb__link {
|
|
508
497
|
display: inline-flex;
|
|
509
498
|
align-items: center;
|
|
510
499
|
color: var(--color-text-muted);
|
|
511
|
-
text-decoration: none;
|
|
500
|
+
text-decoration-line: none;
|
|
512
501
|
line-height: 1;
|
|
513
|
-
transition: color var(--duration-normal) var(--ease-fluid);
|
|
514
502
|
}
|
|
515
503
|
|
|
516
504
|
.breadcrumb__link:hover {
|
|
517
|
-
color: var(--
|
|
505
|
+
color: var(--color-text);
|
|
506
|
+
text-decoration-line: underline;
|
|
518
507
|
}
|
|
519
508
|
|
|
520
509
|
.breadcrumb__item:last-child .breadcrumb__link,
|
|
@@ -525,32 +514,22 @@
|
|
|
525
514
|
|
|
526
515
|
/* Mobile: collapse to "← Back to [Parent]" */
|
|
527
516
|
@media (max-width: 40rem) {
|
|
528
|
-
.breadcrumb .breadcrumb__item {
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/* Show only the second-to-last item (parent) as a back link */
|
|
533
|
-
.breadcrumb .breadcrumb__item:nth-last-child(2) {
|
|
534
|
-
display: inline-flex;
|
|
535
|
-
}
|
|
517
|
+
.breadcrumb .breadcrumb__item { display: none; }
|
|
518
|
+
.breadcrumb .breadcrumb__item:nth-last-child(2) { display: inline-flex; }
|
|
536
519
|
|
|
537
520
|
.breadcrumb .breadcrumb__item:nth-last-child(2)::before {
|
|
538
521
|
content: "← ";
|
|
539
522
|
color: var(--color-text-muted);
|
|
540
523
|
}
|
|
541
524
|
|
|
542
|
-
.breadcrumb .breadcrumb__item:nth-last-child(2)::after {
|
|
543
|
-
content: none;
|
|
544
|
-
}
|
|
525
|
+
.breadcrumb .breadcrumb__item:nth-last-child(2)::after { content: none; }
|
|
545
526
|
|
|
546
527
|
.breadcrumb .breadcrumb__item:nth-last-child(2) .breadcrumb__link {
|
|
547
528
|
color: var(--color-text-muted);
|
|
548
529
|
pointer-events: auto;
|
|
549
530
|
}
|
|
550
531
|
|
|
551
|
-
.breadcrumb .breadcrumb__item:nth-last-child(2) .breadcrumb__link::before {
|
|
552
|
-
content: "Back to ";
|
|
553
|
-
}
|
|
532
|
+
.breadcrumb .breadcrumb__item:nth-last-child(2) .breadcrumb__link::before { content: "Back to "; }
|
|
554
533
|
}
|
|
555
534
|
|
|
556
535
|
|
|
@@ -567,32 +546,35 @@
|
|
|
567
546
|
list-style: none;
|
|
568
547
|
}
|
|
569
548
|
|
|
549
|
+
.pagination > li { margin: 0; }
|
|
550
|
+
|
|
570
551
|
.pagination__link {
|
|
571
552
|
display: inline-flex;
|
|
572
553
|
align-items: center;
|
|
573
554
|
justify-content: center;
|
|
574
|
-
|
|
575
|
-
min-
|
|
555
|
+
gap: var(--space-2);
|
|
556
|
+
min-inline-size: 2.75rem;
|
|
557
|
+
min-block-size: 2.75rem;
|
|
576
558
|
padding: var(--space-2);
|
|
577
|
-
font-size: var(--
|
|
578
|
-
font-weight: var(--weight
|
|
559
|
+
font-size: var(--step--1);
|
|
560
|
+
font-weight: calc(500 + var(--_dark-weight));
|
|
561
|
+
font-variant-numeric: lining-nums tabular-nums;
|
|
579
562
|
color: var(--color-text-muted);
|
|
580
|
-
text-decoration: none;
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
color var(--duration-normal) var(--ease-fluid),
|
|
584
|
-
background-color var(--duration-normal) var(--ease-fluid);
|
|
563
|
+
text-decoration-line: none;
|
|
564
|
+
text-underline-offset: 0.4em;
|
|
565
|
+
border-radius: var(--radius-control);
|
|
585
566
|
}
|
|
586
567
|
|
|
587
568
|
.pagination__link:hover {
|
|
588
569
|
color: var(--color-text);
|
|
589
|
-
|
|
570
|
+
text-decoration-line: underline;
|
|
590
571
|
}
|
|
591
572
|
|
|
592
|
-
.pagination__link[aria-current="page"],
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
573
|
+
.pagination__link:is([aria-current="page"], [data-active]) {
|
|
574
|
+
color: var(--color-text);
|
|
575
|
+
text-decoration-line: underline;
|
|
576
|
+
text-decoration-thickness: 2px;
|
|
577
|
+
text-decoration-color: var(--accent-ink);
|
|
596
578
|
}
|
|
597
579
|
|
|
598
580
|
.pagination__link[data-disabled] {
|
|
@@ -600,12 +582,6 @@
|
|
|
600
582
|
pointer-events: none;
|
|
601
583
|
}
|
|
602
584
|
|
|
603
|
-
/* Prev/Next buttons */
|
|
604
|
-
.pagination__link[data-prev],
|
|
605
|
-
.pagination__link[data-next] {
|
|
606
|
-
gap: var(--space-2);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
585
|
.pagination__ellipsis {
|
|
610
586
|
padding: var(--space-2);
|
|
611
587
|
color: var(--color-text-subtle);
|
|
@@ -618,79 +594,59 @@
|
|
|
618
594
|
|
|
619
595
|
.tabs {
|
|
620
596
|
display: flex;
|
|
621
|
-
gap: var(--space-
|
|
622
|
-
border-block-end:
|
|
597
|
+
gap: var(--space-m);
|
|
598
|
+
border-block-end: var(--border-width) solid var(--color-border);
|
|
623
599
|
}
|
|
624
600
|
|
|
625
601
|
.tabs__tab {
|
|
626
602
|
position: relative;
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
font-
|
|
603
|
+
min-block-size: 2.75rem;
|
|
604
|
+
padding: var(--space-2) 0;
|
|
605
|
+
font-family: var(--font-body);
|
|
606
|
+
font-size: var(--step--1);
|
|
607
|
+
font-weight: calc(500 + var(--_dark-weight));
|
|
630
608
|
color: var(--color-text-muted);
|
|
631
609
|
text-decoration: none;
|
|
632
610
|
background: none;
|
|
633
|
-
border:
|
|
634
|
-
border-radius:
|
|
611
|
+
border: 0;
|
|
612
|
+
border-radius: 0;
|
|
635
613
|
cursor: pointer;
|
|
636
|
-
|
|
637
|
-
transition:
|
|
638
|
-
color var(--duration-normal) var(--ease-fluid),
|
|
639
|
-
background-color var(--duration-normal) var(--ease-fluid);
|
|
614
|
+
transition: color var(--duration-fast) var(--ease-fluid);
|
|
640
615
|
}
|
|
641
616
|
|
|
642
|
-
/* Focus state - subtle ring */
|
|
643
617
|
.tabs__tab:focus-visible {
|
|
644
|
-
|
|
645
|
-
|
|
618
|
+
outline: var(--focus-ring-width) solid var(--color-focus);
|
|
619
|
+
outline-offset: 2px;
|
|
646
620
|
}
|
|
647
621
|
|
|
648
622
|
.tabs__tab::after {
|
|
649
623
|
content: "";
|
|
650
624
|
position: absolute;
|
|
651
|
-
inset-inline:
|
|
625
|
+
inset-inline: 0;
|
|
652
626
|
inset-block-end: -1px;
|
|
653
|
-
block-size:
|
|
627
|
+
block-size: 2px;
|
|
654
628
|
background-color: transparent;
|
|
655
|
-
border-radius: var(--radius-full);
|
|
656
|
-
transition: background-color var(--duration-normal) var(--ease-fluid);
|
|
657
629
|
}
|
|
658
630
|
|
|
659
|
-
.tabs__tab:hover {
|
|
660
|
-
color: var(--color-text);
|
|
661
|
-
background-color: var(--color-surface);
|
|
662
|
-
}
|
|
631
|
+
.tabs__tab:hover { color: var(--color-text); background: none; }
|
|
663
632
|
|
|
664
|
-
.tabs__tab[aria-selected="true"],
|
|
665
|
-
.tabs__tab[data-active] {
|
|
666
|
-
color: var(--accent);
|
|
667
|
-
}
|
|
633
|
+
.tabs__tab:is([aria-selected="true"], [data-active]) { color: var(--color-text); }
|
|
668
634
|
|
|
669
|
-
.tabs__tab[aria-selected="true"]::after
|
|
670
|
-
.tabs__tab[data-active]::after {
|
|
671
|
-
background-color: var(--accent);
|
|
672
|
-
}
|
|
635
|
+
.tabs__tab:is([aria-selected="true"], [data-active])::after { background-color: var(--accent-ink); }
|
|
673
636
|
|
|
674
|
-
/* Contained
|
|
637
|
+
/* Contained: a segmented control on the surface tint. */
|
|
675
638
|
.tabs[data-variant="contained"] {
|
|
639
|
+
gap: 0;
|
|
676
640
|
background-color: var(--color-surface);
|
|
677
|
-
border
|
|
678
|
-
border: none;
|
|
641
|
+
border: 0;
|
|
679
642
|
padding: var(--space-1);
|
|
680
643
|
}
|
|
681
644
|
|
|
682
|
-
.tabs[data-variant="contained"] .tabs__tab {
|
|
683
|
-
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
.tabs[data-variant="contained"] .tabs__tab::after {
|
|
687
|
-
display: none;
|
|
688
|
-
}
|
|
645
|
+
.tabs[data-variant="contained"] .tabs__tab { padding-inline: var(--space-4); }
|
|
646
|
+
.tabs[data-variant="contained"] .tabs__tab::after { display: none; }
|
|
689
647
|
|
|
690
|
-
.tabs[data-variant="contained"] .tabs__tab[aria-selected="true"],
|
|
691
|
-
.tabs[data-variant="contained"] .tabs__tab[data-active] {
|
|
648
|
+
.tabs[data-variant="contained"] .tabs__tab:is([aria-selected="true"], [data-active]) {
|
|
692
649
|
background-color: var(--color-background);
|
|
693
|
-
box-shadow: var(--shadow-xs);
|
|
694
650
|
}
|
|
695
651
|
|
|
696
652
|
|
|
@@ -698,29 +654,5 @@
|
|
|
698
654
|
REDUCED MOTION
|
|
699
655
|
======================================== */
|
|
700
656
|
|
|
701
|
-
|
|
702
|
-
.nav__menu > li {
|
|
703
|
-
transition: none;
|
|
704
|
-
opacity: 1;
|
|
705
|
-
transform: none;
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
.nav__menu > li:nth-child(1),
|
|
709
|
-
.nav__menu > li:nth-child(2),
|
|
710
|
-
.nav__menu > li:nth-child(3),
|
|
711
|
-
.nav__menu > li:nth-child(4),
|
|
712
|
-
.nav__menu > li:nth-child(5),
|
|
713
|
-
.nav__menu > li:nth-child(6) {
|
|
714
|
-
transition-delay: 0ms;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
.nav__link,
|
|
718
|
-
.nav__dropdown-menu,
|
|
719
|
-
.breadcrumb__link,
|
|
720
|
-
.pagination__link,
|
|
721
|
-
.tabs__tab,
|
|
722
|
-
.tabs__tab::after {
|
|
723
|
-
transition: none;
|
|
724
|
-
}
|
|
725
|
-
}
|
|
657
|
+
/* Reduced motion: the reset shortens every transition. */
|
|
726
658
|
}
|