@waveso/docs 0.1.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/LICENSE +21 -0
- package/README.md +518 -0
- package/dist/frontmatter.d.ts +55 -0
- package/dist/frontmatter.js +80 -0
- package/dist/highlighter.d.ts +99 -0
- package/dist/highlighter.js +183 -0
- package/dist/meta.d.ts +75 -0
- package/dist/meta.js +183 -0
- package/dist/next.d.ts +256 -0
- package/dist/next.js +365 -0
- package/dist/plugins/rehype-capture-toc.d.ts +18 -0
- package/dist/plugins/rehype-capture-toc.js +69 -0
- package/dist/plugins/remark-doc-links.d.ts +63 -0
- package/dist/plugins/remark-doc-links.js +122 -0
- package/dist/plugins/remark-unwrap-images.d.ts +11 -0
- package/dist/plugins/remark-unwrap-images.js +25 -0
- package/dist/plugins/remark-youtube.d.ts +22 -0
- package/dist/plugins/remark-youtube.js +84 -0
- package/dist/react/callout.d.ts +37 -0
- package/dist/react/callout.js +113 -0
- package/dist/react/doc-content.d.ts +29 -0
- package/dist/react/doc-content.js +30 -0
- package/dist/react/markdown-components.d.ts +84 -0
- package/dist/react/markdown-components.js +122 -0
- package/dist/react/search-dialog.d.ts +41 -0
- package/dist/react/search-dialog.js +404 -0
- package/dist/react/sidebar.d.ts +29 -0
- package/dist/react/sidebar.js +196 -0
- package/dist/react/skip-link.d.ts +37 -0
- package/dist/react/skip-link.js +37 -0
- package/dist/react/toc.d.ts +35 -0
- package/dist/react/toc.js +87 -0
- package/dist/react/youtube.d.ts +27 -0
- package/dist/react/youtube.js +75 -0
- package/dist/render.d.ts +72 -0
- package/dist/render.js +279 -0
- package/dist/search-index.d.ts +51 -0
- package/dist/search-index.js +274 -0
- package/dist/search-options.d.ts +18 -0
- package/dist/search-options.js +40 -0
- package/dist/source.d.ts +67 -0
- package/dist/source.js +332 -0
- package/dist/styles.css +1033 -0
- package/dist/types.d.ts +334 -0
- package/dist/types.js +0 -0
- package/package.json +166 -0
package/dist/styles.css
ADDED
|
@@ -0,0 +1,1033 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @waveso/docs — the stylesheet for the React layer.
|
|
3
|
+
*
|
|
4
|
+
* In your app's CSS entry:
|
|
5
|
+
*
|
|
6
|
+
* @import 'tailwindcss'; (optional — nothing below requires it)
|
|
7
|
+
* @import '@waveso/docs/styles.css';
|
|
8
|
+
*
|
|
9
|
+
* Everything is plain CSS driven by `--wave-docs-*` custom properties, with no
|
|
10
|
+
* `@apply` anywhere: Tailwind is an *optional* peer dependency, and a
|
|
11
|
+
* stylesheet that explodes without it would be a broken promise.
|
|
12
|
+
*
|
|
13
|
+
* Retheme by redefining the tokens in your own `:root`; restyle by overriding
|
|
14
|
+
* the classes. Both win, and NOT because of source order — everything this file
|
|
15
|
+
* declares lives in a `@layer`, and unlayered CSS beats every layer regardless
|
|
16
|
+
* of specificity. That distinction is the whole fix: the dark token block is
|
|
17
|
+
* `:root:not([data-theme='light'])`, which is (0,2,0), so an unlayered `:root`
|
|
18
|
+
* at (0,1,0) used to lose no matter where it was loaded — the cascade never got
|
|
19
|
+
* as far as order. A consumer had to write `:root:root:root` to outrank us.
|
|
20
|
+
*
|
|
21
|
+
* `@tailwindcss/typography` is deliberately not used. `.prose` pins
|
|
22
|
+
* `max-width: 65ch` — wrong inside a three-column docs shell — and styles
|
|
23
|
+
* `pre`/`code` in direct conflict with Shiki's own output. `.wave-docs-prose`
|
|
24
|
+
* below does the same job without the fight.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/* Register this package's compiled components as Tailwind sources, so a
|
|
28
|
+
* consumer using Tailwind gets any utility class we ship. It belongs here, not
|
|
29
|
+
* in the app: a consumer-side `@source "../node_modules/@waveso/docs"` hardcodes
|
|
30
|
+
* the relative depth of node_modules and breaks under pnpm's nested store. */
|
|
31
|
+
@source "./";
|
|
32
|
+
|
|
33
|
+
/* Explicit, so the order does not silently depend on which block appears
|
|
34
|
+
* first. `theme` holds the tokens, `base` the element resets, `components`
|
|
35
|
+
* the classes. A consumer's own unlayered CSS outranks all three. */
|
|
36
|
+
@layer theme, base, components;
|
|
37
|
+
|
|
38
|
+
/* ---------------------------------------------------------------------------
|
|
39
|
+
* Tokens
|
|
40
|
+
*
|
|
41
|
+
* The dark block is spelled twice on purpose: `@media` and an attribute
|
|
42
|
+
* selector cannot be combined into one selector list. `data-theme` wins over
|
|
43
|
+
* the OS in both directions — `[data-theme='light']` opts out of a dark system,
|
|
44
|
+
* `[data-theme='dark']` opts into dark on a light one.
|
|
45
|
+
* ------------------------------------------------------------------------ */
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* Every foreground/background pair these tokens compose is asserted to clear
|
|
49
|
+
* WCAG 1.4.3 (4.5:1) by `src/styles.test.ts`. None of the text this package
|
|
50
|
+
* renders is "large text" in the WCAG sense — the callout labels are 16px, the
|
|
51
|
+
* search breadcrumbs 12px, the sidebar separators 12px — so 3:1 is never
|
|
52
|
+
* enough. Retheme by all means; run that test afterwards.
|
|
53
|
+
*
|
|
54
|
+
* The light ramp reads fg (0.25) / fg-muted (0.45) / fg-subtle (0.54). The gap
|
|
55
|
+
* between the last two is small because `fg-subtle` cannot go lighter than
|
|
56
|
+
* ~0.555 and still clear 4.5:1 on `bg-subtle`; `fg-muted` moved down to keep
|
|
57
|
+
* three visibly distinct steps rather than two-and-a-half.
|
|
58
|
+
*
|
|
59
|
+
* The dark ramp is fg (0.93) / fg-muted (0.72) / fg-subtle (0.64), and its
|
|
60
|
+
* `accent-subtle` sits at 0.26 rather than 0.30 — `fg-subtle` paints the search
|
|
61
|
+
* breadcrumb, which lands on `accent-subtle` in the highlighted result, and a
|
|
62
|
+
* lighter tint there would force `fg-subtle` up into `fg-muted`.
|
|
63
|
+
*/
|
|
64
|
+
@layer theme {
|
|
65
|
+
/* Layered so a consumer's unlayered `:root` outranks these without having
|
|
66
|
+
* to out-specify `:root:not([data-theme='light'])`. Inside this layer the
|
|
67
|
+
* usual rules still apply, so the dark blocks keep beating the light one. */
|
|
68
|
+
:root {
|
|
69
|
+
--wave-docs-bg: oklch(1 0 0);
|
|
70
|
+
--wave-docs-bg-subtle: oklch(0.985 0.002 260);
|
|
71
|
+
--wave-docs-fg: oklch(0.25 0.02 262);
|
|
72
|
+
--wave-docs-fg-muted: oklch(0.45 0.02 262);
|
|
73
|
+
--wave-docs-fg-subtle: oklch(0.54 0.015 262);
|
|
74
|
+
--wave-docs-border: oklch(0.91 0.006 262);
|
|
75
|
+
--wave-docs-border-strong: oklch(0.84 0.008 262);
|
|
76
|
+
|
|
77
|
+
/* Wave Blue #0074DE, darkened to #006EC8: the brand value clears 4.5:1 on
|
|
78
|
+
* white but only 4.26:1 on `accent-subtle`, which is what the active sidebar
|
|
79
|
+
* link is painted on. */
|
|
80
|
+
--wave-docs-accent: oklch(0.53 0.17 248);
|
|
81
|
+
--wave-docs-accent-hover: oklch(0.46 0.17 248);
|
|
82
|
+
--wave-docs-accent-fg: oklch(0.99 0 0);
|
|
83
|
+
--wave-docs-accent-subtle: oklch(0.96 0.025 248);
|
|
84
|
+
|
|
85
|
+
--wave-docs-code-bg: oklch(0.97 0.003 262);
|
|
86
|
+
--wave-docs-code-fg: oklch(0.32 0.03 300);
|
|
87
|
+
--wave-docs-code-block-bg: oklch(0.985 0.002 260);
|
|
88
|
+
|
|
89
|
+
/* Each accent is the label colour on its own tinted background, so each one
|
|
90
|
+
* is a 4.5:1 pair in its own right — not merely legible against the page. */
|
|
91
|
+
--wave-docs-callout-note: oklch(0.53 0.17 248);
|
|
92
|
+
--wave-docs-callout-note-bg: oklch(0.97 0.02 248);
|
|
93
|
+
--wave-docs-callout-tip: oklch(0.52 0.13 156);
|
|
94
|
+
--wave-docs-callout-tip-bg: oklch(0.97 0.03 156);
|
|
95
|
+
--wave-docs-callout-important: oklch(0.55 0.19 300);
|
|
96
|
+
--wave-docs-callout-important-bg: oklch(0.97 0.025 300);
|
|
97
|
+
--wave-docs-callout-warning: oklch(0.53 0.14 72);
|
|
98
|
+
--wave-docs-callout-warning-bg: oklch(0.97 0.04 82);
|
|
99
|
+
--wave-docs-callout-caution: oklch(0.55 0.2 24);
|
|
100
|
+
--wave-docs-callout-caution-bg: oklch(0.97 0.025 24);
|
|
101
|
+
|
|
102
|
+
--wave-docs-radius: 0.5rem;
|
|
103
|
+
--wave-docs-radius-sm: 0.375rem;
|
|
104
|
+
--wave-docs-header-height: 4rem;
|
|
105
|
+
--wave-docs-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo,
|
|
106
|
+
Consolas, "Liberation Mono", monospace;
|
|
107
|
+
|
|
108
|
+
/* Focus ring, shared by every interactive thing in the package. */
|
|
109
|
+
--wave-docs-ring: 0 0 0 2px var(--wave-docs-bg),
|
|
110
|
+
0 0 0 4px var(--wave-docs-accent);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media (prefers-color-scheme: dark) {
|
|
114
|
+
:root:not([data-theme='light']) {
|
|
115
|
+
--wave-docs-bg: oklch(0.19 0.015 265);
|
|
116
|
+
--wave-docs-bg-subtle: oklch(0.23 0.015 265);
|
|
117
|
+
--wave-docs-fg: oklch(0.93 0.008 265);
|
|
118
|
+
--wave-docs-fg-muted: oklch(0.72 0.014 265);
|
|
119
|
+
--wave-docs-fg-subtle: oklch(0.64 0.015 265);
|
|
120
|
+
--wave-docs-border: oklch(0.31 0.014 265);
|
|
121
|
+
--wave-docs-border-strong: oklch(0.4 0.016 265);
|
|
122
|
+
|
|
123
|
+
--wave-docs-accent: oklch(0.72 0.14 248);
|
|
124
|
+
--wave-docs-accent-hover: oklch(0.8 0.12 248);
|
|
125
|
+
--wave-docs-accent-fg: oklch(0.18 0.02 265);
|
|
126
|
+
--wave-docs-accent-subtle: oklch(0.26 0.06 248);
|
|
127
|
+
|
|
128
|
+
--wave-docs-code-bg: oklch(0.26 0.016 265);
|
|
129
|
+
--wave-docs-code-fg: oklch(0.86 0.04 300);
|
|
130
|
+
--wave-docs-code-block-bg: oklch(0.17 0.015 265);
|
|
131
|
+
|
|
132
|
+
--wave-docs-callout-note: oklch(0.75 0.13 248);
|
|
133
|
+
--wave-docs-callout-note-bg: oklch(0.27 0.05 248);
|
|
134
|
+
--wave-docs-callout-tip: oklch(0.78 0.14 156);
|
|
135
|
+
--wave-docs-callout-tip-bg: oklch(0.27 0.05 156);
|
|
136
|
+
--wave-docs-callout-important: oklch(0.76 0.14 300);
|
|
137
|
+
--wave-docs-callout-important-bg: oklch(0.28 0.06 300);
|
|
138
|
+
--wave-docs-callout-warning: oklch(0.82 0.14 82);
|
|
139
|
+
--wave-docs-callout-warning-bg: oklch(0.29 0.05 72);
|
|
140
|
+
--wave-docs-callout-caution: oklch(0.72 0.16 24);
|
|
141
|
+
--wave-docs-callout-caution-bg: oklch(0.28 0.06 24);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
:root[data-theme='dark'] {
|
|
146
|
+
--wave-docs-bg: oklch(0.19 0.015 265);
|
|
147
|
+
--wave-docs-bg-subtle: oklch(0.23 0.015 265);
|
|
148
|
+
--wave-docs-fg: oklch(0.93 0.008 265);
|
|
149
|
+
--wave-docs-fg-muted: oklch(0.72 0.014 265);
|
|
150
|
+
--wave-docs-fg-subtle: oklch(0.64 0.015 265);
|
|
151
|
+
--wave-docs-border: oklch(0.31 0.014 265);
|
|
152
|
+
--wave-docs-border-strong: oklch(0.4 0.016 265);
|
|
153
|
+
|
|
154
|
+
--wave-docs-accent: oklch(0.72 0.14 248);
|
|
155
|
+
--wave-docs-accent-hover: oklch(0.8 0.12 248);
|
|
156
|
+
--wave-docs-accent-fg: oklch(0.18 0.02 265);
|
|
157
|
+
--wave-docs-accent-subtle: oklch(0.26 0.06 248);
|
|
158
|
+
|
|
159
|
+
--wave-docs-code-bg: oklch(0.26 0.016 265);
|
|
160
|
+
--wave-docs-code-fg: oklch(0.86 0.04 300);
|
|
161
|
+
--wave-docs-code-block-bg: oklch(0.17 0.015 265);
|
|
162
|
+
|
|
163
|
+
--wave-docs-callout-note: oklch(0.75 0.13 248);
|
|
164
|
+
--wave-docs-callout-note-bg: oklch(0.27 0.05 248);
|
|
165
|
+
--wave-docs-callout-tip: oklch(0.78 0.14 156);
|
|
166
|
+
--wave-docs-callout-tip-bg: oklch(0.27 0.05 156);
|
|
167
|
+
--wave-docs-callout-important: oklch(0.76 0.14 300);
|
|
168
|
+
--wave-docs-callout-important-bg: oklch(0.28 0.06 300);
|
|
169
|
+
--wave-docs-callout-warning: oklch(0.82 0.14 82);
|
|
170
|
+
--wave-docs-callout-warning-bg: oklch(0.29 0.05 72);
|
|
171
|
+
--wave-docs-callout-caution: oklch(0.72 0.16 24);
|
|
172
|
+
--wave-docs-callout-caution-bg: oklch(0.28 0.06 24);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* ---------------------------------------------------------------------------
|
|
176
|
+
* Base
|
|
177
|
+
* ------------------------------------------------------------------------ */
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@layer base {
|
|
181
|
+
html {
|
|
182
|
+
/* Without this, every `#anchor` link parks its heading underneath the
|
|
183
|
+
* sticky header. Match it to your header's height. */
|
|
184
|
+
scroll-padding-top: var(--wave-docs-header-height);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Smooth scrolling is opt-in by the reader's OS setting, never by us:
|
|
188
|
+
* animated scrolling triggers nausea and migraine in people with vestibular
|
|
189
|
+
* disorders. Declared here rather than in JavaScript so there is exactly one
|
|
190
|
+
* place that decides it. */
|
|
191
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
192
|
+
html {
|
|
193
|
+
scroll-behavior: smooth;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* ---------------------------------------------------------------------------
|
|
199
|
+
* Utilities used by the components
|
|
200
|
+
* ------------------------------------------------------------------------ */
|
|
201
|
+
|
|
202
|
+
@layer components {
|
|
203
|
+
/* Ours, not Tailwind's `sr-only` — Tailwind is optional here. */
|
|
204
|
+
.wave-docs-sr-only {
|
|
205
|
+
position: absolute;
|
|
206
|
+
width: 1px;
|
|
207
|
+
height: 1px;
|
|
208
|
+
padding: 0;
|
|
209
|
+
margin: -1px;
|
|
210
|
+
overflow: hidden;
|
|
211
|
+
clip-path: inset(50%);
|
|
212
|
+
white-space: nowrap;
|
|
213
|
+
border-width: 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.wave-docs-skip-link {
|
|
217
|
+
position: absolute;
|
|
218
|
+
top: 0;
|
|
219
|
+
left: 0;
|
|
220
|
+
z-index: 100;
|
|
221
|
+
/* Off-screen rather than `display: none`: a hidden element is not
|
|
222
|
+
* focusable, and an unfocusable skip link is no skip link. */
|
|
223
|
+
transform: translateY(-150%);
|
|
224
|
+
padding: 0.625rem 1rem;
|
|
225
|
+
border-radius: 0 0 var(--wave-docs-radius) 0;
|
|
226
|
+
background: var(--wave-docs-accent);
|
|
227
|
+
color: var(--wave-docs-accent-fg);
|
|
228
|
+
font-weight: 600;
|
|
229
|
+
text-decoration: none;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* `:focus`, not `:focus-visible`. A host that moves focus here on a
|
|
233
|
+
* client-side route change is focusing it programmatically, and
|
|
234
|
+
* `:focus-visible` does not match a programmatic focus that followed a
|
|
235
|
+
* pointer interaction — leaving a focused control parked off-screen with no
|
|
236
|
+
* indicator anywhere (WCAG 2.4.7). This element is unreachable by pointer
|
|
237
|
+
* while it is off-screen, so there is no stray-focus-ring case to avoid.
|
|
238
|
+
* Bootstrap's `.visually-hidden-focusable` and GOV.UK's skip link both use
|
|
239
|
+
* plain `:focus` for the same reason. */
|
|
240
|
+
.wave-docs-skip-link:focus {
|
|
241
|
+
transform: translateY(0);
|
|
242
|
+
outline: none;
|
|
243
|
+
box-shadow: var(--wave-docs-ring);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
247
|
+
.wave-docs-skip-link {
|
|
248
|
+
transition: transform 150ms ease-out;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* ---------------------------------------------------------------------------
|
|
254
|
+
* Prose
|
|
255
|
+
* ------------------------------------------------------------------------ */
|
|
256
|
+
|
|
257
|
+
@layer components {
|
|
258
|
+
.wave-docs-prose {
|
|
259
|
+
color: var(--wave-docs-fg);
|
|
260
|
+
font-size: 1rem;
|
|
261
|
+
line-height: 1.75;
|
|
262
|
+
/* No `max-width` on purpose — the docs shell owns column width. */
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.wave-docs-prose > * + * {
|
|
266
|
+
margin-block-start: 1.25em;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.wave-docs-prose :is(h1, h2, h3, h4, h5, h6) {
|
|
270
|
+
position: relative;
|
|
271
|
+
color: var(--wave-docs-fg);
|
|
272
|
+
font-weight: 650;
|
|
273
|
+
line-height: 1.25;
|
|
274
|
+
text-wrap: balance;
|
|
275
|
+
scroll-margin-top: var(--wave-docs-header-height);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.wave-docs-prose > :is(h2, h3, h4, h5, h6) {
|
|
279
|
+
margin-block-start: 2em;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.wave-docs-prose h1 {
|
|
283
|
+
font-size: 2.25rem;
|
|
284
|
+
letter-spacing: -0.02em;
|
|
285
|
+
}
|
|
286
|
+
.wave-docs-prose h2 {
|
|
287
|
+
font-size: 1.5rem;
|
|
288
|
+
letter-spacing: -0.015em;
|
|
289
|
+
padding-block-end: 0.3em;
|
|
290
|
+
border-block-end: 1px solid var(--wave-docs-border);
|
|
291
|
+
}
|
|
292
|
+
.wave-docs-prose h3 {
|
|
293
|
+
font-size: 1.25rem;
|
|
294
|
+
}
|
|
295
|
+
.wave-docs-prose h4 {
|
|
296
|
+
font-size: 1.0625rem;
|
|
297
|
+
}
|
|
298
|
+
.wave-docs-prose :is(h5, h6) {
|
|
299
|
+
font-size: 1rem;
|
|
300
|
+
color: var(--wave-docs-fg-muted);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.wave-docs-prose a {
|
|
304
|
+
color: var(--wave-docs-accent);
|
|
305
|
+
text-decoration: underline;
|
|
306
|
+
text-underline-offset: 0.2em;
|
|
307
|
+
text-decoration-thickness: 1px;
|
|
308
|
+
border-radius: 2px;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.wave-docs-prose a:hover {
|
|
312
|
+
color: var(--wave-docs-accent-hover);
|
|
313
|
+
text-decoration-thickness: 2px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.wave-docs-prose a:focus-visible,
|
|
317
|
+
.wave-docs-sidebar :is(a, button):focus-visible,
|
|
318
|
+
.wave-docs-toc a:focus-visible,
|
|
319
|
+
.wave-docs-youtube__facade:focus-visible {
|
|
320
|
+
outline: none;
|
|
321
|
+
box-shadow: var(--wave-docs-ring);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.wave-docs-prose :is(ul, ol) {
|
|
325
|
+
padding-inline-start: 1.5rem;
|
|
326
|
+
}
|
|
327
|
+
.wave-docs-prose ul {
|
|
328
|
+
list-style: disc;
|
|
329
|
+
}
|
|
330
|
+
.wave-docs-prose ol {
|
|
331
|
+
list-style: decimal;
|
|
332
|
+
}
|
|
333
|
+
.wave-docs-prose li + li {
|
|
334
|
+
margin-block-start: 0.4em;
|
|
335
|
+
}
|
|
336
|
+
.wave-docs-prose li > :is(ul, ol) {
|
|
337
|
+
margin-block-start: 0.4em;
|
|
338
|
+
}
|
|
339
|
+
.wave-docs-prose li::marker {
|
|
340
|
+
color: var(--wave-docs-fg-subtle);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* GFM task lists: the checkbox replaces the bullet. */
|
|
344
|
+
.wave-docs-prose li:has(> input[type='checkbox']) {
|
|
345
|
+
list-style: none;
|
|
346
|
+
margin-inline-start: -1.25rem;
|
|
347
|
+
}
|
|
348
|
+
.wave-docs-prose input[type='checkbox'] {
|
|
349
|
+
margin-inline-end: 0.5rem;
|
|
350
|
+
accent-color: var(--wave-docs-accent);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.wave-docs-prose blockquote {
|
|
354
|
+
padding-inline-start: 1rem;
|
|
355
|
+
border-inline-start: 3px solid var(--wave-docs-border-strong);
|
|
356
|
+
color: var(--wave-docs-fg-muted);
|
|
357
|
+
font-style: italic;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.wave-docs-prose hr {
|
|
361
|
+
border: 0;
|
|
362
|
+
border-block-start: 1px solid var(--wave-docs-border);
|
|
363
|
+
margin-block: 2.5em;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.wave-docs-prose :is(strong, b) {
|
|
367
|
+
font-weight: 650;
|
|
368
|
+
color: var(--wave-docs-fg);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.wave-docs-prose kbd {
|
|
372
|
+
padding: 0.15em 0.4em;
|
|
373
|
+
border: 1px solid var(--wave-docs-border-strong);
|
|
374
|
+
border-block-end-width: 2px;
|
|
375
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
376
|
+
background: var(--wave-docs-bg-subtle);
|
|
377
|
+
font-family: var(--wave-docs-font-mono);
|
|
378
|
+
font-size: 0.85em;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.wave-docs-image {
|
|
382
|
+
max-width: 100%;
|
|
383
|
+
height: auto;
|
|
384
|
+
border-radius: var(--wave-docs-radius);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/* Inline code only. `.shiki` owns everything inside a `<pre>`. */
|
|
388
|
+
.wave-docs-prose :not(pre) > code {
|
|
389
|
+
padding: 0.15em 0.35em;
|
|
390
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
391
|
+
background: var(--wave-docs-code-bg);
|
|
392
|
+
color: var(--wave-docs-code-fg);
|
|
393
|
+
font-family: var(--wave-docs-font-mono);
|
|
394
|
+
font-size: 0.875em;
|
|
395
|
+
/* Long identifiers must not push the whole column sideways. */
|
|
396
|
+
overflow-wrap: break-word;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* ---------------------------------------------------------------------------
|
|
401
|
+
* Tables
|
|
402
|
+
* ------------------------------------------------------------------------ */
|
|
403
|
+
|
|
404
|
+
@layer components {
|
|
405
|
+
.wave-docs-table-scroll {
|
|
406
|
+
overflow-x: auto;
|
|
407
|
+
border: 1px solid var(--wave-docs-border);
|
|
408
|
+
border-radius: var(--wave-docs-radius);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.wave-docs-table-scroll:focus-visible {
|
|
412
|
+
outline: none;
|
|
413
|
+
box-shadow: var(--wave-docs-ring);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.wave-docs-table {
|
|
417
|
+
width: 100%;
|
|
418
|
+
border-collapse: collapse;
|
|
419
|
+
font-size: 0.9375rem;
|
|
420
|
+
line-height: 1.6;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.wave-docs-table :is(th, td) {
|
|
424
|
+
padding: 0.625rem 0.875rem;
|
|
425
|
+
text-align: start;
|
|
426
|
+
vertical-align: top;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.wave-docs-table th {
|
|
430
|
+
background: var(--wave-docs-bg-subtle);
|
|
431
|
+
font-weight: 600;
|
|
432
|
+
white-space: nowrap;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.wave-docs-table :is(thead, tbody tr + tr) {
|
|
436
|
+
border-block-start: 1px solid var(--wave-docs-border);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/* ---------------------------------------------------------------------------
|
|
441
|
+
* Heading anchors
|
|
442
|
+
*
|
|
443
|
+
* Emitted by `rehype-autolink-headings` as
|
|
444
|
+
* `<a class="heading-anchor" aria-hidden="true" tabindex="-1">#</a>`, and
|
|
445
|
+
* therefore purely decorative: it is out of the tab order and out of the
|
|
446
|
+
* accessibility tree, so it can never be focused and has no `:focus-visible`
|
|
447
|
+
* state to style. Revealed on hover of its heading, and nowhere else. The
|
|
448
|
+
* keyboard route to a section is the table of contents, which links the same
|
|
449
|
+
* anchors with real text.
|
|
450
|
+
* ------------------------------------------------------------------------ */
|
|
451
|
+
|
|
452
|
+
@layer components {
|
|
453
|
+
.heading-anchor {
|
|
454
|
+
margin-inline-start: 0.35em;
|
|
455
|
+
color: var(--wave-docs-fg-subtle);
|
|
456
|
+
text-decoration: none;
|
|
457
|
+
opacity: 0;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
:is(h1, h2, h3, h4, h5, h6):hover > .heading-anchor {
|
|
461
|
+
opacity: 1;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.heading-anchor:hover {
|
|
465
|
+
color: var(--wave-docs-accent);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
469
|
+
.heading-anchor {
|
|
470
|
+
transition: opacity 120ms ease-out;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/* ---------------------------------------------------------------------------
|
|
476
|
+
* Shiki
|
|
477
|
+
*
|
|
478
|
+
* Dual-theme promotion. Shiki writes the light colour as an INLINE style on
|
|
479
|
+
* every token span and the dark one beside it as `--shiki-dark`, so switching
|
|
480
|
+
* themes means overriding an inline style. `!important` is the only thing in
|
|
481
|
+
* CSS that outranks one — this is a specificity requirement, not a preference,
|
|
482
|
+
* and removing it silently leaves dark mode rendering light-theme code.
|
|
483
|
+
* ------------------------------------------------------------------------ */
|
|
484
|
+
|
|
485
|
+
.shiki {
|
|
486
|
+
padding: 1rem 1.125rem;
|
|
487
|
+
border: 1px solid var(--wave-docs-border);
|
|
488
|
+
border-radius: var(--wave-docs-radius);
|
|
489
|
+
background-color: var(--wave-docs-code-block-bg);
|
|
490
|
+
overflow-x: auto;
|
|
491
|
+
font-family: var(--wave-docs-font-mono);
|
|
492
|
+
font-size: 0.875rem;
|
|
493
|
+
line-height: 1.7;
|
|
494
|
+
tab-size: 2;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.shiki code {
|
|
498
|
+
display: grid;
|
|
499
|
+
font-family: inherit;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.shiki .line {
|
|
503
|
+
min-height: 1lh;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
@media (prefers-color-scheme: dark) {
|
|
507
|
+
:root:not([data-theme='light']) .shiki,
|
|
508
|
+
:root:not([data-theme='light']) .shiki span {
|
|
509
|
+
color: var(--shiki-dark) !important;
|
|
510
|
+
}
|
|
511
|
+
:root:not([data-theme='light']) .shiki {
|
|
512
|
+
background-color: var(--shiki-dark-bg) !important;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
:root[data-theme='dark'] .shiki,
|
|
517
|
+
:root[data-theme='dark'] .shiki span {
|
|
518
|
+
color: var(--shiki-dark) !important;
|
|
519
|
+
}
|
|
520
|
+
:root[data-theme='dark'] .shiki {
|
|
521
|
+
background-color: var(--shiki-dark-bg) !important;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/* ---------------------------------------------------------------------------
|
|
525
|
+
* Callouts
|
|
526
|
+
* ------------------------------------------------------------------------ */
|
|
527
|
+
|
|
528
|
+
@layer components {
|
|
529
|
+
.wave-docs-callout {
|
|
530
|
+
--callout-accent: var(--wave-docs-callout-note);
|
|
531
|
+
--callout-bg: var(--wave-docs-callout-note-bg);
|
|
532
|
+
|
|
533
|
+
padding: 0.875rem 1rem;
|
|
534
|
+
border: 1px solid color-mix(in oklab, var(--callout-accent) 35%, transparent);
|
|
535
|
+
border-inline-start: 3px solid var(--callout-accent);
|
|
536
|
+
border-radius: var(--wave-docs-radius);
|
|
537
|
+
background: var(--callout-bg);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.wave-docs-callout--tip {
|
|
541
|
+
--callout-accent: var(--wave-docs-callout-tip);
|
|
542
|
+
--callout-bg: var(--wave-docs-callout-tip-bg);
|
|
543
|
+
}
|
|
544
|
+
.wave-docs-callout--important {
|
|
545
|
+
--callout-accent: var(--wave-docs-callout-important);
|
|
546
|
+
--callout-bg: var(--wave-docs-callout-important-bg);
|
|
547
|
+
}
|
|
548
|
+
.wave-docs-callout--warning {
|
|
549
|
+
--callout-accent: var(--wave-docs-callout-warning);
|
|
550
|
+
--callout-bg: var(--wave-docs-callout-warning-bg);
|
|
551
|
+
}
|
|
552
|
+
.wave-docs-callout--caution {
|
|
553
|
+
--callout-accent: var(--wave-docs-callout-caution);
|
|
554
|
+
--callout-bg: var(--wave-docs-callout-caution-bg);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.wave-docs-callout__label {
|
|
558
|
+
display: flex;
|
|
559
|
+
align-items: center;
|
|
560
|
+
gap: 0.5rem;
|
|
561
|
+
margin: 0 0 0.35rem;
|
|
562
|
+
color: var(--callout-accent);
|
|
563
|
+
font-weight: 650;
|
|
564
|
+
line-height: 1.4;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
.wave-docs-callout__icon {
|
|
568
|
+
flex: none;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
.wave-docs-callout__body > * {
|
|
572
|
+
margin: 0;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.wave-docs-callout__body > * + * {
|
|
576
|
+
margin-block-start: 0.75em;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* ---------------------------------------------------------------------------
|
|
581
|
+
* YouTube facade
|
|
582
|
+
* ------------------------------------------------------------------------ */
|
|
583
|
+
|
|
584
|
+
@layer components {
|
|
585
|
+
.wave-docs-youtube {
|
|
586
|
+
position: relative;
|
|
587
|
+
aspect-ratio: 16 / 9;
|
|
588
|
+
overflow: hidden;
|
|
589
|
+
border-radius: var(--wave-docs-radius);
|
|
590
|
+
background: oklch(0 0 0);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
.wave-docs-youtube__facade {
|
|
594
|
+
display: block;
|
|
595
|
+
width: 100%;
|
|
596
|
+
height: 100%;
|
|
597
|
+
padding: 0;
|
|
598
|
+
border: 0;
|
|
599
|
+
background: none;
|
|
600
|
+
cursor: pointer;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
.wave-docs-youtube__thumbnail {
|
|
604
|
+
width: 100%;
|
|
605
|
+
height: 100%;
|
|
606
|
+
/* `hqdefault` is 4:3 with letterbox bars baked in; cropping to 16:9 hides
|
|
607
|
+
* them. */
|
|
608
|
+
object-fit: cover;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.wave-docs-youtube__play {
|
|
612
|
+
position: absolute;
|
|
613
|
+
inset: 0;
|
|
614
|
+
display: grid;
|
|
615
|
+
place-items: center;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.wave-docs-youtube__play-bg {
|
|
619
|
+
fill: oklch(0.3 0 0 / 0.75);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
.wave-docs-youtube__play-arrow {
|
|
623
|
+
fill: oklch(1 0 0);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.wave-docs-youtube__facade:is(:hover, :focus-visible)
|
|
627
|
+
.wave-docs-youtube__play-bg {
|
|
628
|
+
fill: oklch(0.55 0.22 27);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.wave-docs-youtube__frame {
|
|
632
|
+
width: 100%;
|
|
633
|
+
height: 100%;
|
|
634
|
+
border: 0;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
638
|
+
.wave-docs-youtube__play-bg {
|
|
639
|
+
transition: fill 150ms ease-out;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/* ---------------------------------------------------------------------------
|
|
645
|
+
* Sidebar
|
|
646
|
+
* ------------------------------------------------------------------------ */
|
|
647
|
+
|
|
648
|
+
@layer components {
|
|
649
|
+
.wave-docs-sidebar {
|
|
650
|
+
font-size: 0.875rem;
|
|
651
|
+
line-height: 1.5;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.wave-docs-sidebar__list {
|
|
655
|
+
margin: 0;
|
|
656
|
+
padding: 0;
|
|
657
|
+
list-style: none;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/* Nested levels get a guide rail instead of raw indentation, so a deep tree
|
|
661
|
+
* stays readable at 240px wide. */
|
|
662
|
+
.wave-docs-sidebar__list:not([data-depth='0']) {
|
|
663
|
+
margin-inline-start: 0.5rem;
|
|
664
|
+
padding-inline-start: 0.5rem;
|
|
665
|
+
border-inline-start: 1px solid var(--wave-docs-border);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.wave-docs-sidebar__link,
|
|
669
|
+
.wave-docs-sidebar__group-button {
|
|
670
|
+
display: flex;
|
|
671
|
+
align-items: center;
|
|
672
|
+
justify-content: space-between;
|
|
673
|
+
gap: 0.5rem;
|
|
674
|
+
width: 100%;
|
|
675
|
+
padding: 0.3125rem 0.5rem;
|
|
676
|
+
border: 0;
|
|
677
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
678
|
+
background: none;
|
|
679
|
+
color: var(--wave-docs-fg-muted);
|
|
680
|
+
font: inherit;
|
|
681
|
+
text-align: start;
|
|
682
|
+
text-decoration: none;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.wave-docs-sidebar__group-button {
|
|
686
|
+
cursor: pointer;
|
|
687
|
+
font-weight: 600;
|
|
688
|
+
color: var(--wave-docs-fg);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
.wave-docs-sidebar__link:hover,
|
|
692
|
+
.wave-docs-sidebar__group-button:hover {
|
|
693
|
+
background: var(--wave-docs-bg-subtle);
|
|
694
|
+
color: var(--wave-docs-fg);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/* The active page. Driven by `aria-current`, so the visual state and the
|
|
698
|
+
* announced state cannot drift apart. */
|
|
699
|
+
.wave-docs-sidebar__link[aria-current='page'] {
|
|
700
|
+
background: var(--wave-docs-accent-subtle);
|
|
701
|
+
color: var(--wave-docs-accent);
|
|
702
|
+
font-weight: 600;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.wave-docs-sidebar__group-header {
|
|
706
|
+
display: flex;
|
|
707
|
+
align-items: center;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.wave-docs-sidebar__group-header .wave-docs-sidebar__link {
|
|
711
|
+
flex: 1 1 auto;
|
|
712
|
+
font-weight: 600;
|
|
713
|
+
color: var(--wave-docs-fg);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.wave-docs-sidebar__group-toggle {
|
|
717
|
+
flex: none;
|
|
718
|
+
display: grid;
|
|
719
|
+
place-items: center;
|
|
720
|
+
padding: 0.375rem;
|
|
721
|
+
border: 0;
|
|
722
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
723
|
+
background: none;
|
|
724
|
+
color: var(--wave-docs-fg-subtle);
|
|
725
|
+
cursor: pointer;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.wave-docs-sidebar__group-toggle:hover {
|
|
729
|
+
background: var(--wave-docs-bg-subtle);
|
|
730
|
+
color: var(--wave-docs-fg);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.wave-docs-sidebar__chevron {
|
|
734
|
+
flex: none;
|
|
735
|
+
color: var(--wave-docs-fg-subtle);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.wave-docs-sidebar__chevron[data-open] {
|
|
739
|
+
rotate: 90deg;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
.wave-docs-sidebar__separator-item {
|
|
743
|
+
margin-block: 1rem 0.25rem;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.wave-docs-sidebar__separator {
|
|
747
|
+
display: block;
|
|
748
|
+
padding-inline: 0.5rem;
|
|
749
|
+
color: var(--wave-docs-fg-subtle);
|
|
750
|
+
font-size: 0.75rem;
|
|
751
|
+
font-weight: 650;
|
|
752
|
+
letter-spacing: 0.06em;
|
|
753
|
+
text-transform: uppercase;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
757
|
+
.wave-docs-sidebar__chevron {
|
|
758
|
+
transition: rotate 150ms ease-out;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/* ---------------------------------------------------------------------------
|
|
764
|
+
* Table of contents
|
|
765
|
+
* ------------------------------------------------------------------------ */
|
|
766
|
+
|
|
767
|
+
@layer components {
|
|
768
|
+
.wave-docs-toc {
|
|
769
|
+
font-size: 0.8125rem;
|
|
770
|
+
line-height: 1.5;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
.wave-docs-toc__list {
|
|
774
|
+
margin: 0;
|
|
775
|
+
padding: 0;
|
|
776
|
+
list-style: none;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.wave-docs-toc__link {
|
|
780
|
+
display: block;
|
|
781
|
+
padding: 0.25rem 0.75rem;
|
|
782
|
+
/* The rail the active marker slides along. */
|
|
783
|
+
border-inline-start: 2px solid var(--wave-docs-border);
|
|
784
|
+
color: var(--wave-docs-fg-muted);
|
|
785
|
+
text-decoration: none;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
/* Indent by heading depth rather than by nesting, so an h4 under an h2 with
|
|
789
|
+
* no h3 between them still lines up. */
|
|
790
|
+
.wave-docs-toc__link[data-depth='3'] {
|
|
791
|
+
padding-inline-start: 1.5rem;
|
|
792
|
+
}
|
|
793
|
+
.wave-docs-toc__link[data-depth='4'] {
|
|
794
|
+
padding-inline-start: 2.25rem;
|
|
795
|
+
}
|
|
796
|
+
.wave-docs-toc__link[data-depth='5'],
|
|
797
|
+
.wave-docs-toc__link[data-depth='6'] {
|
|
798
|
+
padding-inline-start: 3rem;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
.wave-docs-toc__link:hover {
|
|
802
|
+
color: var(--wave-docs-fg);
|
|
803
|
+
border-inline-start-color: var(--wave-docs-border-strong);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
.wave-docs-toc__link[aria-current='location'] {
|
|
807
|
+
color: var(--wave-docs-accent);
|
|
808
|
+
border-inline-start-color: var(--wave-docs-accent);
|
|
809
|
+
font-weight: 600;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
813
|
+
.wave-docs-toc__link {
|
|
814
|
+
transition: color 120ms ease-out, border-color 120ms ease-out;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/* ---------------------------------------------------------------------------
|
|
820
|
+
* Search
|
|
821
|
+
*
|
|
822
|
+
* Classes emitted by `@waveso/docs/react/search-dialog`. The dialog is a
|
|
823
|
+
* `role="dialog"` div in a portal, not a `<dialog>` element, so the backdrop
|
|
824
|
+
* and stacking are ours to draw.
|
|
825
|
+
* ------------------------------------------------------------------------ */
|
|
826
|
+
|
|
827
|
+
@layer components {
|
|
828
|
+
.wave-docs-search-trigger {
|
|
829
|
+
display: flex;
|
|
830
|
+
align-items: center;
|
|
831
|
+
justify-content: space-between;
|
|
832
|
+
gap: 1rem;
|
|
833
|
+
width: 100%;
|
|
834
|
+
max-width: 20rem;
|
|
835
|
+
padding: 0.4375rem 0.625rem;
|
|
836
|
+
border: 1px solid var(--wave-docs-border);
|
|
837
|
+
border-radius: var(--wave-docs-radius);
|
|
838
|
+
background: var(--wave-docs-bg-subtle);
|
|
839
|
+
color: var(--wave-docs-fg-muted);
|
|
840
|
+
font: inherit;
|
|
841
|
+
font-size: 0.875rem;
|
|
842
|
+
text-align: start;
|
|
843
|
+
cursor: pointer;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
.wave-docs-search-trigger:hover {
|
|
847
|
+
border-color: var(--wave-docs-border-strong);
|
|
848
|
+
color: var(--wave-docs-fg);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.wave-docs-search-trigger:focus-visible,
|
|
852
|
+
.wave-docs-search-close:focus-visible,
|
|
853
|
+
.wave-docs-search-result-link:focus-visible {
|
|
854
|
+
outline: none;
|
|
855
|
+
box-shadow: var(--wave-docs-ring);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/* The label is the flexible half of the trigger; the shortcut hint beside it
|
|
859
|
+
* must never be the thing that gets squeezed out at narrow widths. */
|
|
860
|
+
.wave-docs-search-trigger-label {
|
|
861
|
+
overflow: hidden;
|
|
862
|
+
text-overflow: ellipsis;
|
|
863
|
+
white-space: nowrap;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
.wave-docs-search-trigger-kbd {
|
|
867
|
+
flex: none;
|
|
868
|
+
padding: 0.05rem 0.35rem;
|
|
869
|
+
border: 1px solid var(--wave-docs-border-strong);
|
|
870
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
871
|
+
color: var(--wave-docs-fg-subtle);
|
|
872
|
+
font-family: var(--wave-docs-font-mono);
|
|
873
|
+
font-size: 0.75rem;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
.wave-docs-search-backdrop {
|
|
877
|
+
position: fixed;
|
|
878
|
+
inset: 0;
|
|
879
|
+
z-index: 50;
|
|
880
|
+
display: flex;
|
|
881
|
+
justify-content: center;
|
|
882
|
+
/* Not centred: a dialog that grows downward from a fixed top does not
|
|
883
|
+
* shift under the reader as results stream in. */
|
|
884
|
+
padding: 10vh 1rem 1rem;
|
|
885
|
+
background: oklch(0.2 0.02 265 / 0.5);
|
|
886
|
+
backdrop-filter: blur(2px);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.wave-docs-search-dialog {
|
|
890
|
+
display: flex;
|
|
891
|
+
flex-direction: column;
|
|
892
|
+
width: 100%;
|
|
893
|
+
max-width: 34rem;
|
|
894
|
+
max-height: min(32rem, 80vh);
|
|
895
|
+
overflow: hidden;
|
|
896
|
+
border: 1px solid var(--wave-docs-border);
|
|
897
|
+
border-radius: var(--wave-docs-radius);
|
|
898
|
+
background: var(--wave-docs-bg);
|
|
899
|
+
box-shadow: 0 24px 48px -12px oklch(0 0 0 / 0.3);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.wave-docs-search-input-row {
|
|
903
|
+
display: flex;
|
|
904
|
+
align-items: center;
|
|
905
|
+
gap: 0.5rem;
|
|
906
|
+
padding: 0.75rem;
|
|
907
|
+
border-block-end: 1px solid var(--wave-docs-border);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.wave-docs-search-input {
|
|
911
|
+
flex: 1 1 auto;
|
|
912
|
+
min-width: 0;
|
|
913
|
+
padding: 0.375rem 0.25rem;
|
|
914
|
+
border: 0;
|
|
915
|
+
background: none;
|
|
916
|
+
color: var(--wave-docs-fg);
|
|
917
|
+
font: inherit;
|
|
918
|
+
font-size: 1rem;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.wave-docs-search-input:focus {
|
|
922
|
+
/* The dialog frame is the focus indicator here; a ring on a full-width
|
|
923
|
+
* borderless input reads as an error state. */
|
|
924
|
+
outline: none;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
.wave-docs-search-input::placeholder {
|
|
928
|
+
color: var(--wave-docs-fg-subtle);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.wave-docs-search-close {
|
|
932
|
+
flex: none;
|
|
933
|
+
padding: 0.3125rem 0.625rem;
|
|
934
|
+
border: 1px solid var(--wave-docs-border);
|
|
935
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
936
|
+
background: none;
|
|
937
|
+
color: var(--wave-docs-fg-muted);
|
|
938
|
+
font: inherit;
|
|
939
|
+
font-size: 0.8125rem;
|
|
940
|
+
cursor: pointer;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.wave-docs-search-close:hover {
|
|
944
|
+
color: var(--wave-docs-fg);
|
|
945
|
+
border-color: var(--wave-docs-border-strong);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.wave-docs-search-results {
|
|
949
|
+
flex: 1 1 auto;
|
|
950
|
+
overflow-y: auto;
|
|
951
|
+
padding: 0.375rem;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.wave-docs-search-result {
|
|
955
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
/* Driven by `aria-selected` through the active class the dialog sets — the
|
|
959
|
+
* combobox keeps focus in the input, so `:focus` never lands here. */
|
|
960
|
+
.wave-docs-search-result-active {
|
|
961
|
+
background: var(--wave-docs-accent-subtle);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
.wave-docs-search-result-link {
|
|
965
|
+
display: flex;
|
|
966
|
+
flex-direction: column;
|
|
967
|
+
gap: 0.125rem;
|
|
968
|
+
padding: 0.5rem 0.625rem;
|
|
969
|
+
border-radius: var(--wave-docs-radius-sm);
|
|
970
|
+
color: var(--wave-docs-fg);
|
|
971
|
+
text-decoration: none;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
.wave-docs-search-result-heading {
|
|
975
|
+
font-size: 0.9375rem;
|
|
976
|
+
font-weight: 600;
|
|
977
|
+
line-height: 1.4;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
.wave-docs-search-result-breadcrumb {
|
|
981
|
+
color: var(--wave-docs-fg-subtle);
|
|
982
|
+
font-size: 0.75rem;
|
|
983
|
+
line-height: 1.4;
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/* A crumb never wraps mid-title: the trail reads as a path or not at all.
|
|
987
|
+
* The breadcrumb line itself is free to wrap between crumbs. */
|
|
988
|
+
.wave-docs-search-result-crumb {
|
|
989
|
+
white-space: nowrap;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
.wave-docs-search-result-crumb-separator {
|
|
993
|
+
margin-inline: 0.25rem;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.wave-docs-search-status {
|
|
997
|
+
margin: 0;
|
|
998
|
+
padding: 1.5rem 1rem;
|
|
999
|
+
color: var(--wave-docs-fg-muted);
|
|
1000
|
+
font-size: 0.875rem;
|
|
1001
|
+
text-align: center;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/* The four status modifiers share the base rule; only two need to look
|
|
1005
|
+
* different from it. `-hint` and `-loading` are deliberately quiet — they
|
|
1006
|
+
* appear on every open, and an empty dialog should not shout. */
|
|
1007
|
+
.wave-docs-search-status-hint,
|
|
1008
|
+
.wave-docs-search-status-loading {
|
|
1009
|
+
color: var(--wave-docs-fg-subtle);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.wave-docs-search-status-empty {
|
|
1013
|
+
color: var(--wave-docs-fg);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
.wave-docs-search-status-error {
|
|
1017
|
+
color: var(--wave-docs-callout-caution);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/* The live region must stay in the accessibility tree to be announced, so it
|
|
1021
|
+
* is hidden the same way as any other visually-hidden text — never
|
|
1022
|
+
* `display: none`. */
|
|
1023
|
+
.wave-docs-search-announcer {
|
|
1024
|
+
position: absolute;
|
|
1025
|
+
width: 1px;
|
|
1026
|
+
height: 1px;
|
|
1027
|
+
padding: 0;
|
|
1028
|
+
margin: -1px;
|
|
1029
|
+
overflow: hidden;
|
|
1030
|
+
clip-path: inset(50%);
|
|
1031
|
+
white-space: nowrap;
|
|
1032
|
+
}
|
|
1033
|
+
}
|