@navecss/core 0.2.0 → 0.4.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/ATOMS.md +1 -1
- package/CONSUMER-ATOMS.md +41 -8
- package/LICENSE +36 -0
- package/README.md +611 -46
- package/dist/atom-names-2OreuBx9.d.ts +27 -0
- package/dist/atomic.css +3 -1
- package/dist/atoms.d.ts +10 -14
- package/dist/atoms.js +2 -1
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +453 -0
- package/dist/check.d.ts +31 -0
- package/dist/check.js +11 -0
- package/dist/chunk-2A7IUZBH.js +31 -0
- package/dist/{chunk-BVON7XKC.js → chunk-CUL5PLPI.js} +8 -6
- package/dist/chunk-E5F6YF7A.js +2428 -0
- package/dist/chunk-GZL2VW7C.js +57 -0
- package/dist/chunk-LADFXRWQ.js +1089 -0
- package/dist/chunk-LQSGQ2OA.js +94 -0
- package/dist/chunk-NFS2REPQ.js +747 -0
- package/dist/chunk-NKUZNRF4.js +42 -0
- package/dist/chunk-SYNQJNVB.js +302 -0
- package/dist/chunk-UANF3FGO.js +115 -0
- package/dist/chunk-XQQCDUV6.js +152 -0
- package/dist/collect.d.ts +279 -0
- package/dist/collect.js +4 -0
- package/dist/cx.d.ts +23 -4
- package/dist/cx.js +19 -1
- package/dist/lightningcss.d.ts +51 -0
- package/dist/lightningcss.js +44 -0
- package/dist/no-tokens.css +7 -7
- package/dist/postcss.cjs +1 -0
- package/dist/postcss.d.cts +2 -0
- package/dist/postcss.d.ts +30 -15
- package/dist/postcss.js +237 -243
- package/dist/standalone.css +1139 -0
- package/dist/vite-options-D1-hGA9L.d.ts +86 -0
- package/dist/vite.d.ts +368 -0
- package/dist/vite.js +3318 -0
- package/package.json +55 -17
- package/skills/navecss/SKILL.md +7 -2
|
@@ -0,0 +1,1139 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Nave Design System — the @layer order statement, alone.
|
|
3
|
+
*
|
|
4
|
+
* Import this first, before any other stylesheet. CSS fixes a layer's
|
|
5
|
+
* position the first time the page declares it, so if a stylesheet of yours
|
|
6
|
+
* that declares a layer loads before this statement, that layer's position is
|
|
7
|
+
* fixed first and Nave's order inverts with no error. Imported first, this one
|
|
8
|
+
* line keeps the order wherever the rest of Nave and your own stylesheets land
|
|
9
|
+
* in the import graph. Importing '@navecss/core' afterwards is correct: its
|
|
10
|
+
* own copy of this statement is identical and changes nothing.
|
|
11
|
+
*
|
|
12
|
+
* Full contract:
|
|
13
|
+
* https://github.com/navecss/navecss/blob/main/docs/04-adr/0003-layer-cascade-contract.md
|
|
14
|
+
*/
|
|
15
|
+
@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Nave Design System — core entry point
|
|
19
|
+
* Import this once in your app, before any stylesheet of yours that
|
|
20
|
+
* declares a layer.
|
|
21
|
+
*
|
|
22
|
+
* The @layer statement below is the cascade contract: seven names across five
|
|
23
|
+
* top-level layers (tokens, reset, atomic, components, overrides), each name
|
|
24
|
+
* beating every name before it. Do not reorder. The contract holds only if
|
|
25
|
+
* this statement is the first @layer declaration the document sees: a layer
|
|
26
|
+
* your CSS declares earlier keeps that earlier position, and the order
|
|
27
|
+
* inverts. Author into a sublayer, never into a bare parent (a parent
|
|
28
|
+
* outranks its own sublayers). Unlayered CSS beats every layer. All of this
|
|
29
|
+
* is for normal declarations: !important reverses layer order, which the
|
|
30
|
+
* reset uses on purpose. Full contract:
|
|
31
|
+
* https://github.com/navecss/navecss/blob/main/docs/04-adr/0003-layer-cascade-contract.md
|
|
32
|
+
*
|
|
33
|
+
* tokens.defaults → CSS custom properties (read-only, set by @navecss/tokens)
|
|
34
|
+
* tokens.presets → RESERVED: 0.1.0 ships zero presets, but the
|
|
35
|
+
* slot is declared now so a preset always beats the defaults
|
|
36
|
+
* regardless of import order, and a consumer's `overrides`
|
|
37
|
+
* always beats a preset. Retrofitting this slot later would be
|
|
38
|
+
* a breaking change to the published cascade contract.
|
|
39
|
+
* A project's own `navecss-tokens build` output lands here too.
|
|
40
|
+
* reset → Cross-browser normalisation
|
|
41
|
+
* atomic → Global atom classes that cx() names: defaults, below
|
|
42
|
+
* component CSS (@nave inlines into your own rule instead)
|
|
43
|
+
* components.nave → Components Nave publishes
|
|
44
|
+
* components.consumer → Your component CSS: @layer components.consumer { … }
|
|
45
|
+
* overrides → Your deliberate exceptions to everything above
|
|
46
|
+
*/
|
|
47
|
+
@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;
|
|
48
|
+
|
|
49
|
+
/* Token layer — all CSS custom properties.
|
|
50
|
+
* Imported plain: tokens.css declares its own `@layer tokens.defaults` so that
|
|
51
|
+
* consumers importing @navecss/tokens/css directly are layered correctly too.
|
|
52
|
+
* Adding layer(tokens.defaults) here would nest it a second time. */
|
|
53
|
+
/* Nave Design System — generated, do not edit */
|
|
54
|
+
@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @property declarations provide:
|
|
58
|
+
* - Type safety (browsers reject invalid values)
|
|
59
|
+
* - CSS transitions on custom properties (e.g. color tokens)
|
|
60
|
+
* - IDE autocomplete in supported editors
|
|
61
|
+
*
|
|
62
|
+
* Only tokens whose initial-value is computationally independent are
|
|
63
|
+
* registered. Font-relative values (rem/em) cannot be, so those tokens
|
|
64
|
+
* ship as plain custom properties below.
|
|
65
|
+
*/
|
|
66
|
+
@property --nave-font-weight-regular {
|
|
67
|
+
syntax: '<number>';
|
|
68
|
+
inherits: true;
|
|
69
|
+
initial-value: 400;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@property --nave-font-weight-medium {
|
|
73
|
+
syntax: '<number>';
|
|
74
|
+
inherits: true;
|
|
75
|
+
initial-value: 500;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@property --nave-font-weight-semibold {
|
|
79
|
+
syntax: '<number>';
|
|
80
|
+
inherits: true;
|
|
81
|
+
initial-value: 600;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@property --nave-font-weight-bold {
|
|
85
|
+
syntax: '<number>';
|
|
86
|
+
inherits: true;
|
|
87
|
+
initial-value: 700;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@property --nave-line-height-none {
|
|
91
|
+
syntax: '<number>';
|
|
92
|
+
inherits: true;
|
|
93
|
+
initial-value: 1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@property --nave-line-height-tight {
|
|
97
|
+
syntax: '<number>';
|
|
98
|
+
inherits: true;
|
|
99
|
+
initial-value: 1.2;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@property --nave-line-height-snug {
|
|
103
|
+
syntax: '<number>';
|
|
104
|
+
inherits: true;
|
|
105
|
+
initial-value: 1.375;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@property --nave-line-height-base {
|
|
109
|
+
syntax: '<number>';
|
|
110
|
+
inherits: true;
|
|
111
|
+
initial-value: 1.5;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@property --nave-line-height-relaxed {
|
|
115
|
+
syntax: '<number>';
|
|
116
|
+
inherits: true;
|
|
117
|
+
initial-value: 1.625;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@property --nave-line-height-loose {
|
|
121
|
+
syntax: '<number>';
|
|
122
|
+
inherits: true;
|
|
123
|
+
initial-value: 2;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@property --nave-spacing-content-xs {
|
|
127
|
+
syntax: '<length>';
|
|
128
|
+
inherits: true;
|
|
129
|
+
initial-value: 4px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@property --nave-spacing-content-sm {
|
|
133
|
+
syntax: '<length>';
|
|
134
|
+
inherits: true;
|
|
135
|
+
initial-value: 8px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@property --nave-spacing-content-md {
|
|
139
|
+
syntax: '<length>';
|
|
140
|
+
inherits: true;
|
|
141
|
+
initial-value: 16px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@property --nave-spacing-content-lg {
|
|
145
|
+
syntax: '<length>';
|
|
146
|
+
inherits: true;
|
|
147
|
+
initial-value: 24px;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@property --nave-spacing-content-xl {
|
|
151
|
+
syntax: '<length>';
|
|
152
|
+
inherits: true;
|
|
153
|
+
initial-value: 32px;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@property --nave-spacing-layout-xs {
|
|
157
|
+
syntax: '<length>';
|
|
158
|
+
inherits: true;
|
|
159
|
+
initial-value: 48px;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
@property --nave-spacing-layout-sm {
|
|
163
|
+
syntax: '<length>';
|
|
164
|
+
inherits: true;
|
|
165
|
+
initial-value: 64px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@property --nave-spacing-layout-md {
|
|
169
|
+
syntax: '<length>';
|
|
170
|
+
inherits: true;
|
|
171
|
+
initial-value: 96px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@property --nave-spacing-layout-lg {
|
|
175
|
+
syntax: '<length>';
|
|
176
|
+
inherits: true;
|
|
177
|
+
initial-value: 128px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@property --nave-spacing-control-xs {
|
|
181
|
+
syntax: '<length>';
|
|
182
|
+
inherits: true;
|
|
183
|
+
initial-value: 4px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@property --nave-spacing-control-sm {
|
|
187
|
+
syntax: '<length>';
|
|
188
|
+
inherits: true;
|
|
189
|
+
initial-value: 6px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@property --nave-spacing-control-md {
|
|
193
|
+
syntax: '<length>';
|
|
194
|
+
inherits: true;
|
|
195
|
+
initial-value: 8px;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@property --nave-spacing-control-lg {
|
|
199
|
+
syntax: '<length>';
|
|
200
|
+
inherits: true;
|
|
201
|
+
initial-value: 12px;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@property --nave-border-width-none {
|
|
205
|
+
syntax: '<length>';
|
|
206
|
+
inherits: true;
|
|
207
|
+
initial-value: 0px;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@property --nave-border-width-sm {
|
|
211
|
+
syntax: '<length>';
|
|
212
|
+
inherits: true;
|
|
213
|
+
initial-value: 1px;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@property --nave-border-width-focus {
|
|
217
|
+
syntax: '<length>';
|
|
218
|
+
inherits: true;
|
|
219
|
+
initial-value: 2px;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@property --nave-border-width-mark {
|
|
223
|
+
syntax: '<length>';
|
|
224
|
+
inherits: true;
|
|
225
|
+
initial-value: 2px;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@property --nave-border-width-lg {
|
|
229
|
+
syntax: '<length>';
|
|
230
|
+
inherits: true;
|
|
231
|
+
initial-value: 4px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@property --nave-radius-none {
|
|
235
|
+
syntax: '<length>';
|
|
236
|
+
inherits: true;
|
|
237
|
+
initial-value: 0px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
@property --nave-radius-sm {
|
|
241
|
+
syntax: '<length>';
|
|
242
|
+
inherits: true;
|
|
243
|
+
initial-value: 4px;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@property --nave-radius-control {
|
|
247
|
+
syntax: '<length>';
|
|
248
|
+
inherits: true;
|
|
249
|
+
initial-value: 6px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@property --nave-radius-card {
|
|
253
|
+
syntax: '<length>';
|
|
254
|
+
inherits: true;
|
|
255
|
+
initial-value: 12px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
@property --nave-radius-overlay {
|
|
259
|
+
syntax: '<length>';
|
|
260
|
+
inherits: true;
|
|
261
|
+
initial-value: 12px;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@property --nave-radius-full {
|
|
265
|
+
syntax: '<length>';
|
|
266
|
+
inherits: true;
|
|
267
|
+
initial-value: 9999px;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@property --nave-opacity-disabled {
|
|
271
|
+
syntax: '<number>';
|
|
272
|
+
inherits: true;
|
|
273
|
+
initial-value: 0.4;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@property --nave-layer-base {
|
|
277
|
+
syntax: '<integer>';
|
|
278
|
+
inherits: true;
|
|
279
|
+
initial-value: 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
@property --nave-layer-dropdown {
|
|
283
|
+
syntax: '<integer>';
|
|
284
|
+
inherits: true;
|
|
285
|
+
initial-value: 100;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
@property --nave-layer-sticky {
|
|
289
|
+
syntax: '<integer>';
|
|
290
|
+
inherits: true;
|
|
291
|
+
initial-value: 200;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@property --nave-layer-overlay {
|
|
295
|
+
syntax: '<integer>';
|
|
296
|
+
inherits: true;
|
|
297
|
+
initial-value: 300;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
@property --nave-layer-modal {
|
|
301
|
+
syntax: '<integer>';
|
|
302
|
+
inherits: true;
|
|
303
|
+
initial-value: 400;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
@property --nave-layer-toast {
|
|
307
|
+
syntax: '<integer>';
|
|
308
|
+
inherits: true;
|
|
309
|
+
initial-value: 500;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
@property --nave-layer-tooltip {
|
|
313
|
+
syntax: '<integer>';
|
|
314
|
+
inherits: true;
|
|
315
|
+
initial-value: 600;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@property --nave-motion-duration-instant {
|
|
319
|
+
syntax: '<time>';
|
|
320
|
+
inherits: true;
|
|
321
|
+
initial-value: 0ms;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
@property --nave-motion-duration-fast {
|
|
325
|
+
syntax: '<time>';
|
|
326
|
+
inherits: true;
|
|
327
|
+
initial-value: 100ms;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
@property --nave-motion-duration-base {
|
|
331
|
+
syntax: '<time>';
|
|
332
|
+
inherits: true;
|
|
333
|
+
initial-value: 200ms;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
@property --nave-motion-duration-slow {
|
|
337
|
+
syntax: '<time>';
|
|
338
|
+
inherits: true;
|
|
339
|
+
initial-value: 400ms;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Token values scoped under @layer tokens.defaults.
|
|
344
|
+
* Override in @layer overrides — no specificity battles, ever.
|
|
345
|
+
*/
|
|
346
|
+
@layer tokens.defaults {
|
|
347
|
+
:root {
|
|
348
|
+
--nave-font-family-base: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
349
|
+
--nave-font-family-display: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
350
|
+
--nave-font-family-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, monospace;
|
|
351
|
+
--nave-font-size-xs: 0.75rem;
|
|
352
|
+
--nave-font-size-sm: 0.875rem;
|
|
353
|
+
--nave-font-size-md: 1rem;
|
|
354
|
+
--nave-font-size-lg: 1.125rem;
|
|
355
|
+
--nave-font-size-xl: 1.25rem;
|
|
356
|
+
--nave-font-size-2xl: 1.5rem;
|
|
357
|
+
--nave-font-size-3xl: 1.875rem;
|
|
358
|
+
--nave-font-size-4xl: 2.25rem;
|
|
359
|
+
--nave-font-weight-regular: 400;
|
|
360
|
+
--nave-font-weight-medium: 500;
|
|
361
|
+
--nave-font-weight-semibold: 600;
|
|
362
|
+
--nave-font-weight-bold: 700;
|
|
363
|
+
--nave-line-height-none: 1;
|
|
364
|
+
--nave-line-height-tight: 1.2;
|
|
365
|
+
--nave-line-height-snug: 1.375;
|
|
366
|
+
--nave-line-height-base: 1.5;
|
|
367
|
+
--nave-line-height-relaxed: 1.625;
|
|
368
|
+
--nave-line-height-loose: 2;
|
|
369
|
+
--nave-letter-spacing-tight: -0.025em;
|
|
370
|
+
--nave-letter-spacing-normal: 0em;
|
|
371
|
+
--nave-letter-spacing-wide: 0.075em;
|
|
372
|
+
--nave-spacing-content-xs: 4px;
|
|
373
|
+
--nave-spacing-content-sm: 8px;
|
|
374
|
+
--nave-spacing-content-md: 16px;
|
|
375
|
+
--nave-spacing-content-lg: 24px;
|
|
376
|
+
--nave-spacing-content-xl: 32px;
|
|
377
|
+
--nave-spacing-layout-xs: 48px;
|
|
378
|
+
--nave-spacing-layout-sm: 64px;
|
|
379
|
+
--nave-spacing-layout-md: 96px;
|
|
380
|
+
--nave-spacing-layout-lg: 128px;
|
|
381
|
+
--nave-spacing-control-xs: 4px;
|
|
382
|
+
--nave-spacing-control-sm: 6px;
|
|
383
|
+
--nave-spacing-control-md: 8px;
|
|
384
|
+
--nave-spacing-control-lg: 12px;
|
|
385
|
+
--nave-size-control-xs: 1.5rem;
|
|
386
|
+
--nave-size-control-sm: 2rem;
|
|
387
|
+
--nave-size-control-md: 2.5rem;
|
|
388
|
+
--nave-size-control-lg: 3rem;
|
|
389
|
+
--nave-size-icon-xs: 0.75rem;
|
|
390
|
+
--nave-size-icon-sm: 1rem;
|
|
391
|
+
--nave-size-icon-md: 1.25rem;
|
|
392
|
+
--nave-size-icon-lg: 1.5rem;
|
|
393
|
+
--nave-size-icon-xl: 2rem;
|
|
394
|
+
--nave-size-avatar-sm: 1.5rem;
|
|
395
|
+
--nave-size-avatar-md: 2rem;
|
|
396
|
+
--nave-size-avatar-lg: 3rem;
|
|
397
|
+
--nave-border-width-none: 0px;
|
|
398
|
+
--nave-border-width-sm: 1px;
|
|
399
|
+
--nave-border-width-focus: 2px;
|
|
400
|
+
--nave-border-width-mark: 2px;
|
|
401
|
+
--nave-border-width-lg: 4px;
|
|
402
|
+
--nave-radius-none: 0px;
|
|
403
|
+
--nave-radius-sm: 4px;
|
|
404
|
+
--nave-radius-control: 6px;
|
|
405
|
+
--nave-radius-card: 12px;
|
|
406
|
+
--nave-radius-overlay: 12px;
|
|
407
|
+
--nave-radius-full: 9999px;
|
|
408
|
+
--nave-shadow-none: none;
|
|
409
|
+
--nave-shadow-raised: 0px 0.0625rem 0.1875rem 0px oklch(0 0 0 / 0.08), 0px 0.0625rem 0.125rem 0px oklch(0 0 0 / 0.06);
|
|
410
|
+
--nave-shadow-overlay: 0px 0.25rem 0.75rem 0px oklch(0 0 0 / 0.1), 0px 0.125rem 0.375rem 0px oklch(0 0 0 / 0.08);
|
|
411
|
+
--nave-shadow-modal: 0px 1rem 2rem 0px oklch(0 0 0 / 0.15), 0px 0.5rem 1rem 0px oklch(0 0 0 / 0.1);
|
|
412
|
+
--nave-opacity-disabled: 0.4;
|
|
413
|
+
--nave-layer-base: 0;
|
|
414
|
+
--nave-layer-dropdown: 100;
|
|
415
|
+
--nave-layer-sticky: 200;
|
|
416
|
+
--nave-layer-overlay: 300;
|
|
417
|
+
--nave-layer-modal: 400;
|
|
418
|
+
--nave-layer-toast: 500;
|
|
419
|
+
--nave-layer-tooltip: 600;
|
|
420
|
+
--nave-motion-duration-instant: 0ms;
|
|
421
|
+
--nave-motion-duration-fast: 100ms;
|
|
422
|
+
--nave-motion-duration-base: 200ms;
|
|
423
|
+
--nave-motion-duration-slow: 400ms;
|
|
424
|
+
--nave-motion-easing-standard: cubic-bezier(0.4, 0, 0.2, 1);
|
|
425
|
+
--nave-motion-easing-decelerate: cubic-bezier(0, 0, 0.2, 1);
|
|
426
|
+
--nave-motion-easing-accelerate: cubic-bezier(0.4, 0, 1, 1);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Collapse all motion durations for users who prefer reduced motion.
|
|
431
|
+
* Any component using --nave-motion-duration-* gets this for free.
|
|
432
|
+
*/
|
|
433
|
+
@media (prefers-reduced-motion: reduce) {
|
|
434
|
+
:root {
|
|
435
|
+
--nave-motion-duration-fast: 0.01ms;
|
|
436
|
+
--nave-motion-duration-base: 0.01ms;
|
|
437
|
+
--nave-motion-duration-slow: 0.01ms;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* Nave theming — generated, do not edit. See the @navecss/tokens README ("Theming"). */
|
|
443
|
+
|
|
444
|
+
@property --nave-color-tint {
|
|
445
|
+
syntax: '<color>';
|
|
446
|
+
inherits: true;
|
|
447
|
+
initial-value: oklch(0.7859 0.1316 186.17);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
@layer tokens.defaults {
|
|
451
|
+
:root {
|
|
452
|
+
/* color-scheme lives here, not in @navecss/core's reset, so
|
|
453
|
+
* light-dark() resolves even for a tokens-only consumer. */
|
|
454
|
+
color-scheme: light dark;
|
|
455
|
+
/* Tint seed: Changing this changes everything Nave derives from it. The contrast of the resulting palette follows from what you set, and checking it is yours. */
|
|
456
|
+
--nave-color-tint: oklch(0.7859 0.1316 186.17);
|
|
457
|
+
--nave-color-surface-base: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
458
|
+
--nave-color-surface-raised: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.225 0.0067 h / 1));
|
|
459
|
+
--nave-color-surface-overlay: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.27 0.0067 h / 1));
|
|
460
|
+
--nave-color-surface-sunken: light-dark(oklch(from var(--nave-color-tint) 0.985 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.12 0.0067 h / 1));
|
|
461
|
+
--nave-color-surface-inverse: light-dark(oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.965 0.0067 h / 1));
|
|
462
|
+
--nave-color-content-primary: light-dark(oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.965 0.0067 h / 1));
|
|
463
|
+
--nave-color-content-secondary: light-dark(oklch(from var(--nave-color-tint) 0.37 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
464
|
+
--nave-color-content-tertiary: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.72 0.0067 h / 1));
|
|
465
|
+
--nave-color-content-disabled: light-dark(oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.37 0.0067 h / 1));
|
|
466
|
+
--nave-color-content-inverse: light-dark(oklch(from var(--nave-color-tint) 0.965 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
467
|
+
--nave-color-content-link: light-dark(oklch(0.47 0.0748 186.17), oklch(0.835 0.123 186.17));
|
|
468
|
+
--nave-color-border-default: light-dark(oklch(from var(--nave-color-tint) 0.905 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.37 0.0067 h / 1));
|
|
469
|
+
--nave-color-border-strong: light-dark(oklch(from var(--nave-color-tint) 0.72 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1));
|
|
470
|
+
--nave-color-border-control: light-dark(oklch(from var(--nave-color-tint) 0.59 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.59 0.0067 h / 1));
|
|
471
|
+
--nave-color-border-disabled: light-dark(oklch(from var(--nave-color-tint) 0.94 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.27 0.0067 h / 1));
|
|
472
|
+
--nave-color-border-focus: light-dark(oklch(0.59 0.0939 186.17), oklch(0.59 0.0939 186.17));
|
|
473
|
+
--nave-color-action-primary: light-dark(oklch(0.47 0.0748 186.17), oklch(0.835 0.123 186.17));
|
|
474
|
+
--nave-color-action-primary-hover: light-dark(oklch(0.37 0.0589 186.17), oklch(0.905 0.1106 186.17));
|
|
475
|
+
--nave-color-action-primary-active: light-dark(oklch(0.27 0.0398 186.17), oklch(0.94 0.0574 186.17));
|
|
476
|
+
--nave-color-on-action-primary: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
477
|
+
--nave-color-action-secondary: light-dark(oklch(from var(--nave-color-tint) 0.965 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.27 0.0067 h / 1));
|
|
478
|
+
--nave-color-action-highlight: light-dark(oklch(from var(--nave-color-tint) 0.965 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.37 0.0067 h / 1));
|
|
479
|
+
--nave-color-feedback-danger: light-dark(oklch(0.47 0.1455 15.02), oklch(0.835 0.0661 15.02));
|
|
480
|
+
--nave-color-feedback-danger-foreground: light-dark(oklch(0.47 0.1455 15.02), oklch(0.835 0.0661 15.02));
|
|
481
|
+
--nave-color-on-feedback-danger: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
482
|
+
/* Feedback tokens: warning, success and info, and their -foreground variants, resolve to one shared value here; only danger differs. Colour alone therefore cannot tell those three states apart, so wherever a feedback token carries meaning, give it a text label naming the state and a distinct icon or shape that differs per state. */
|
|
483
|
+
--nave-color-feedback-warning: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
484
|
+
--nave-color-feedback-warning-foreground: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
485
|
+
--nave-color-on-feedback-warning: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
486
|
+
--nave-color-feedback-success: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
487
|
+
--nave-color-feedback-success-foreground: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
488
|
+
--nave-color-on-feedback-success: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
489
|
+
--nave-color-feedback-info: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
490
|
+
--nave-color-feedback-info-foreground: light-dark(oklch(from var(--nave-color-tint) 0.47 0.0067 h / 1), oklch(from var(--nave-color-tint) 0.835 0.0067 h / 1));
|
|
491
|
+
--nave-color-on-feedback-info: light-dark(oklch(from var(--nave-color-tint) 1 0 h / 1), oklch(from var(--nave-color-tint) 0.18 0.0067 h / 1));
|
|
492
|
+
--nave-color-backdrop-modal: light-dark(oklch(from var(--nave-color-tint) 0.12 0.0067 h / 0.3), oklch(from var(--nave-color-tint) 0.12 0.0067 h / 0.6));
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/* Reset layer. Imported plain: dist/reset.css now declares its own
|
|
497
|
+
* `@layer reset` so that consumers importing ./reset directly are layered
|
|
498
|
+
* correctly too. Adding layer(reset) here would nest it a second time. */
|
|
499
|
+
/*
|
|
500
|
+
* Self-layered under @layer reset: this file ships as a published
|
|
501
|
+
* subpath export (./reset) and is imported directly by some consumers, so
|
|
502
|
+
* the layer guarantee has to be a property of the artifact rather than of
|
|
503
|
+
* index.css's import site.
|
|
504
|
+
*/
|
|
505
|
+
@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;
|
|
506
|
+
|
|
507
|
+
@layer reset {
|
|
508
|
+
/*
|
|
509
|
+
* Nave Reset — opinionated modern cross-browser reset.
|
|
510
|
+
* Every rule fixes a real, documented cross-browser inconsistency.
|
|
511
|
+
* Tokens are available here because @layer tokens is declared first.
|
|
512
|
+
*/
|
|
513
|
+
|
|
514
|
+
/* ── Box model ───────────────────────────────────────────────────────────────
|
|
515
|
+
* Border-box everywhere. The alternative is layout math errors.
|
|
516
|
+
*/
|
|
517
|
+
*,
|
|
518
|
+
*::before,
|
|
519
|
+
*::after {
|
|
520
|
+
box-sizing: border-box;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/* ── Root ────────────────────────────────────────────────────────────────────
|
|
524
|
+
* 1. Stop Safari on iPhone enlarging body text by itself (for example on an orientation
|
|
525
|
+
* change), so a Nave layout renders at the size it declares. Safari reads only the
|
|
526
|
+
* -webkit- prefixed property; the unprefixed one is the standard spelling. This does not
|
|
527
|
+
* take away a reader's own text-size setting in Safari, in Chrome from version 143, in
|
|
528
|
+
* Android WebView from version 145, or in Firefox: each applies that setting whatever the
|
|
529
|
+
* value here. Chrome no longer autosizes text, and Firefox for Android accepts only auto
|
|
530
|
+
* or none here, so it ignores this declaration. -moz-text-size-adjust is left out on
|
|
531
|
+
* purpose: none, its only opt-out value, would switch off Firefox's own font inflation.
|
|
532
|
+
* The value is 100%, the convention normalize.css set; on iPad and in Firefox, none
|
|
533
|
+
* would not behave the same.
|
|
534
|
+
* 2. Smooth scroll — reduced motion override is at the bottom of this file.
|
|
535
|
+
* 3. hanging-punctuation: Safari only, progressive enhancement.
|
|
536
|
+
* Punctuation hangs outside the text box correctly.
|
|
537
|
+
* 4. Font smoothing: prefer grayscale AA on macOS/iOS.
|
|
538
|
+
* subpixel-antialiased is less consistent across displays.
|
|
539
|
+
* 5. text-rendering: optimizelegibility — enables kerning and ligatures in Firefox and
|
|
540
|
+
* Safari; a no-op elsewhere. Unrelated to font-size inflation (1); kept as its own number.
|
|
541
|
+
*/
|
|
542
|
+
html {
|
|
543
|
+
-webkit-font-smoothing: antialiased; /* 4 */
|
|
544
|
+
-moz-osx-font-smoothing: grayscale; /* 4 */
|
|
545
|
+
hanging-punctuation: first last; /* 3 */
|
|
546
|
+
scroll-behavior: smooth; /* 2 */
|
|
547
|
+
text-rendering: optimizelegibility; /* 5 */
|
|
548
|
+
-webkit-text-size-adjust: 100%; /* 1 */
|
|
549
|
+
text-size-adjust: 100%; /* 1 */
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/* ── Body ────────────────────────────────────────────────────────────────────
|
|
553
|
+
* min-height: 100dvh — dynamic viewport height.
|
|
554
|
+
* Fixes iOS Safari bottom bar eating into 100vh layouts.
|
|
555
|
+
* dvh is Baseline 2023, safe for all modern browsers.
|
|
556
|
+
*/
|
|
557
|
+
body {
|
|
558
|
+
background-color: var(--nave-color-surface-base);
|
|
559
|
+
color: var(--nave-color-content-primary);
|
|
560
|
+
font-family: var(--nave-font-family-base);
|
|
561
|
+
font-size: var(--nave-font-size-md);
|
|
562
|
+
line-height: var(--nave-line-height-base);
|
|
563
|
+
margin: 0;
|
|
564
|
+
min-height: 100dvh;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/* ── Remove default margins ──────────────────────────────────────────────────
|
|
568
|
+
* Browsers apply inconsistent margins to these elements.
|
|
569
|
+
* Spacing is a layout concern, not an element default.
|
|
570
|
+
*/
|
|
571
|
+
h1,
|
|
572
|
+
h2,
|
|
573
|
+
h3,
|
|
574
|
+
h4,
|
|
575
|
+
h5,
|
|
576
|
+
h6,
|
|
577
|
+
p,
|
|
578
|
+
figure,
|
|
579
|
+
blockquote,
|
|
580
|
+
dl,
|
|
581
|
+
dd,
|
|
582
|
+
pre {
|
|
583
|
+
margin: 0;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/* ── Lists ───────────────────────────────────────────────────────────────────
|
|
587
|
+
* Only remove list styles when role="list" is present.
|
|
588
|
+
* VoiceOver (Safari) removes list semantics when list-style is removed.
|
|
589
|
+
* Adding role="list" signals intentional non-list usage to the browser.
|
|
590
|
+
* Pattern: Scott O'Hara / Andy Bell.
|
|
591
|
+
*/
|
|
592
|
+
ul[role='list'],
|
|
593
|
+
ol[role='list'] {
|
|
594
|
+
list-style: none;
|
|
595
|
+
margin: 0;
|
|
596
|
+
padding: 0;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/* ── Headings ─────────────────────────────────────────────────────────────────
|
|
600
|
+
* 1. Tighter line-height — body line-height is too loose for headings.
|
|
601
|
+
* 2. text-wrap: balance — prevents single orphan words on the last line.
|
|
602
|
+
* Baseline since May 2024 (Chrome 114, Firefox 121, Safari 17.5), so it is
|
|
603
|
+
* inside the browser floor (ADR 0005) and applies everywhere Nave supports.
|
|
604
|
+
*/
|
|
605
|
+
h1,
|
|
606
|
+
h2,
|
|
607
|
+
h3,
|
|
608
|
+
h4,
|
|
609
|
+
h5,
|
|
610
|
+
h6 {
|
|
611
|
+
font-family: var(--nave-font-family-display);
|
|
612
|
+
font-weight: var(--nave-font-weight-bold);
|
|
613
|
+
line-height: var(--nave-line-height-tight); /* 1 */
|
|
614
|
+
overflow-wrap: break-word;
|
|
615
|
+
text-wrap: balance; /* 2 */
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/* ── Paragraphs ───────────────────────────────────────────────────────────────
|
|
619
|
+
* text-wrap: pretty — optimises last 4 lines, prevents orphans.
|
|
620
|
+
* Chrome and Edge 117+, Safari 26+, not yet Firefox. Past the browser floor, so
|
|
621
|
+
* progressive enhancement: without it, paragraphs wrap normally (ADR 0005).
|
|
622
|
+
*/
|
|
623
|
+
p {
|
|
624
|
+
overflow-wrap: break-word;
|
|
625
|
+
text-wrap: pretty;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/* ── Overflow wrap ────────────────────────────────────────────────────────────
|
|
629
|
+
* Prevents long words / URLs from breaking layouts.
|
|
630
|
+
*/
|
|
631
|
+
li,
|
|
632
|
+
figcaption,
|
|
633
|
+
dt,
|
|
634
|
+
dd {
|
|
635
|
+
overflow-wrap: break-word;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/* ── Replaced elements ────────────────────────────────────────────────────────
|
|
639
|
+
* display: block removes phantom baseline space under images.
|
|
640
|
+
* Caused by inline baseline alignment — one of CSS's oldest layout bugs.
|
|
641
|
+
* height: auto maintains aspect ratio when width is constrained.
|
|
642
|
+
*/
|
|
643
|
+
img,
|
|
644
|
+
picture,
|
|
645
|
+
video,
|
|
646
|
+
canvas {
|
|
647
|
+
display: block;
|
|
648
|
+
height: auto;
|
|
649
|
+
max-width: 100%;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/* ── SVG ──────────────────────────────────────────────────────────────────────
|
|
653
|
+
* SVGs without an explicit fill inherit the parent text color.
|
|
654
|
+
* Controls icon color via CSS color — no fill attribute required.
|
|
655
|
+
*/
|
|
656
|
+
svg {
|
|
657
|
+
display: block;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
svg:not([fill]) {
|
|
661
|
+
fill: currentcolor;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/* ── Figcaption ───────────────────────────────────────────────────────────────
|
|
665
|
+
* Safari applies font-style: italic to figcaption by default.
|
|
666
|
+
*/
|
|
667
|
+
figcaption {
|
|
668
|
+
font-style: normal;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/* ── Forms ───────────────────────────────────────────────────────────────────
|
|
672
|
+
* font: inherit — all browsers apply their own font to form controls,
|
|
673
|
+
* ignoring the cascade. This is the most important form reset rule.
|
|
674
|
+
* letter-spacing / word-spacing: inherit — Safari ignores these on inputs.
|
|
675
|
+
*/
|
|
676
|
+
input,
|
|
677
|
+
button,
|
|
678
|
+
textarea,
|
|
679
|
+
select,
|
|
680
|
+
optgroup {
|
|
681
|
+
color: inherit;
|
|
682
|
+
font: inherit;
|
|
683
|
+
letter-spacing: inherit;
|
|
684
|
+
word-spacing: inherit;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/* ── Buttons ──────────────────────────────────────────────────────────────────
|
|
688
|
+
* Strip all browser button chrome, from <button> and every button-like <input>.
|
|
689
|
+
* The text-input rule below also unsets appearance/background for
|
|
690
|
+
* input[type=submit|reset|button] (it excludes only checkbox/radio/range), but leaves the
|
|
691
|
+
* UA's own outset border since it never targeted the button rule's selector; listed here too
|
|
692
|
+
* so all four get the same border: none.
|
|
693
|
+
* The three input types are wrapped in :where() so they carry zero specificity, same as a
|
|
694
|
+
* bare `button` selector: without it, `input[type='submit']` etc. sit at (0,1,1), which beats
|
|
695
|
+
* the Disabled rule's `[disabled], [aria-disabled='true']` at (0,1,0) and makes this rule's
|
|
696
|
+
* `cursor: pointer` win on a disabled button-like input even though the Disabled rule runs
|
|
697
|
+
* later in the file. :where() keeps this rule at (0,0,1), so the Disabled rule's cursor still
|
|
698
|
+
* wins, and a consumer overriding button chrome never needs a specificity escalation either.
|
|
699
|
+
* This rule is placed before the text-input rule below (rather than after, its previous
|
|
700
|
+
* position) because a (0,0,1) selector following a (0,1,1) one that can match the same element
|
|
701
|
+
* (a submit/reset/button input matches both) is a descending-specificity smell the linter
|
|
702
|
+
* flags; placing the lower-specificity rule first avoids that without changing which
|
|
703
|
+
* declaration wins for any element — specificity, not source order, still decides.
|
|
704
|
+
* Nave component styles define all button appearance explicitly.
|
|
705
|
+
*/
|
|
706
|
+
button,
|
|
707
|
+
input:where([type='button'], [type='reset'], [type='submit']) {
|
|
708
|
+
appearance: none;
|
|
709
|
+
background: none;
|
|
710
|
+
border: none;
|
|
711
|
+
color: inherit;
|
|
712
|
+
cursor: pointer;
|
|
713
|
+
font: inherit;
|
|
714
|
+
padding: 0;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/* ── Text inputs & textareas ──────────────────────────────────────────────────
|
|
718
|
+
* 1. Removes iOS Safari grey background on inputs.
|
|
719
|
+
* 2. appearance: none removes Safari's rounded pill input style. Unprefixed
|
|
720
|
+
* (Baseline) rather than -webkit-appearance.
|
|
721
|
+
* 3. border-radius: 0 — iOS Safari rounds inputs regardless of appearance.
|
|
722
|
+
* Scoped to text-like inputs and textarea only (excludes checkbox, radio,
|
|
723
|
+
* range, and select) — a bare `input` or `select` selector here would strip
|
|
724
|
+
* native rendering from checkboxes/radios (invisible empty boxes) and the
|
|
725
|
+
* select dropdown indicator.
|
|
726
|
+
*/
|
|
727
|
+
input:not([type='checkbox'], [type='radio'], [type='range']),
|
|
728
|
+
textarea {
|
|
729
|
+
/* 2 */
|
|
730
|
+
appearance: none; /* 2 */
|
|
731
|
+
background-color: transparent; /* 1 */
|
|
732
|
+
border-radius: 0; /* 3 */
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/* ── Links ────────────────────────────────────────────────────────────────────
|
|
736
|
+
* color: inherit — link color is a design decision, not a browser default.
|
|
737
|
+
* text-decoration-skip-ink: prevents underline from clipping descenders (g, y, p).
|
|
738
|
+
*/
|
|
739
|
+
a {
|
|
740
|
+
color: inherit;
|
|
741
|
+
text-decoration-skip-ink: auto;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/* ── Tables ───────────────────────────────────────────────────────────────────
|
|
745
|
+
* border-collapse: collapse removes double borders between cells.
|
|
746
|
+
* border-color: inherit — Firefox bug where table borders don't inherit color.
|
|
747
|
+
*/
|
|
748
|
+
table {
|
|
749
|
+
border-collapse: collapse;
|
|
750
|
+
border-color: inherit;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/* ── Code ─────────────────────────────────────────────────────────────────────
|
|
754
|
+
* font-size: 1em — browsers render code at ~13px by default. This overrides it.
|
|
755
|
+
*/
|
|
756
|
+
code,
|
|
757
|
+
kbd,
|
|
758
|
+
samp,
|
|
759
|
+
pre {
|
|
760
|
+
font-family: var(--nave-font-family-mono);
|
|
761
|
+
font-size: 1em;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/* ── Horizontal rule ──────────────────────────────────────────────────────────
|
|
765
|
+
* Chrome and Firefox disagree on hr height and border rendering.
|
|
766
|
+
* border: none clears the UA default first — Chrome leaves border-bottom-width: 1px,
|
|
767
|
+
* border-left-width: 1px and border-bottom-style: inset when only border-top is set,
|
|
768
|
+
* rendering a three-sided box under the token-coloured top border. border-top then
|
|
769
|
+
* normalises to a single 1px line.
|
|
770
|
+
*/
|
|
771
|
+
hr {
|
|
772
|
+
border: none;
|
|
773
|
+
border-top: var(--nave-border-width-sm) solid var(--nave-color-border-default);
|
|
774
|
+
color: inherit;
|
|
775
|
+
height: 0;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/* ── Hidden attribute ─────────────────────────────────────────────────────────
|
|
779
|
+
* display: flex / grid overrides [hidden] in some browsers.
|
|
780
|
+
* !important is correct here — [hidden] must always mean hidden — except
|
|
781
|
+
* hidden="until-found": excluded via :where() (contributes zero specificity, so the
|
|
782
|
+
* selector stays exactly as specific as plain [hidden]), so find-in-page can still reveal it.
|
|
783
|
+
* The `i` flag makes the attribute-value match case-insensitive: `hidden` is an HTML
|
|
784
|
+
* enumerated attribute, whose keywords (including "until-found") are matched ASCII
|
|
785
|
+
* case-insensitively by the spec, and a browser resolving hidden="UNTIL-FOUND" into the
|
|
786
|
+
* until-found state must not fall through to this !important display: none.
|
|
787
|
+
*/
|
|
788
|
+
[hidden]:where(:not([hidden='until-found' i])) {
|
|
789
|
+
display: none !important;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/* ── Disabled ─────────────────────────────────────────────────────────────────
|
|
793
|
+
* Consistent disabled cursor across all interactive elements.
|
|
794
|
+
*/
|
|
795
|
+
[disabled],
|
|
796
|
+
[aria-disabled='true'] {
|
|
797
|
+
cursor: not-allowed;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/* ── Focus ───────────────────────────────────────────────────────────────────
|
|
801
|
+
* The reset does not remove the user agent's focus indicator, and it does
|
|
802
|
+
* not replace it either. That is a statement about what Nave declines to
|
|
803
|
+
* do: no rule here strips outline from a selector that is not itself gated
|
|
804
|
+
* on :focus-visible, and no rule here ships an author-styled indicator at
|
|
805
|
+
* document scope. The user-agent default is the baseline. Consumers who
|
|
806
|
+
* want a different treatment override it via the @layer contract (reset
|
|
807
|
+
* sits early; every consumer layer wins over it).
|
|
808
|
+
*/
|
|
809
|
+
|
|
810
|
+
/* ── Color scheme ─────────────────────────────────────────────────────────────
|
|
811
|
+
* `color-scheme` is now emitted by the TOKENS layer (`@navecss/tokens`, which
|
|
812
|
+
* ships full light+dark values via `light-dark()`), not by this reset. A
|
|
813
|
+
* declaration here would win over anything the tokens package emits
|
|
814
|
+
* (`@layer tokens` loads before `@layer reset`), which would make
|
|
815
|
+
* `light-dark()` inert and leave a tokens-only consumer (a documented tier) with
|
|
816
|
+
* no dark mode at all. Do not reintroduce a `color-scheme` declaration here.
|
|
817
|
+
*/
|
|
818
|
+
|
|
819
|
+
/* ── Reduced motion ───────────────────────────────────────────────────────────
|
|
820
|
+
* Belt-and-suspenders alongside the token-level reduced motion in tokens.css.
|
|
821
|
+
* Catches animations not using Nave tokens (third-party, consumer code).
|
|
822
|
+
* 0.01ms, not 0ms — avoids triggering animationend event bugs in some browsers.
|
|
823
|
+
* The four !important flags are DELIBERATE. Important declarations reverse
|
|
824
|
+
* cascade-layer order, so these beat a consumer's own !important in any later
|
|
825
|
+
* layer; without them a universal-selector rule in an early layer loses to
|
|
826
|
+
* almost anything, and the collapse would be inert over exactly the
|
|
827
|
+
* third-party and consumer motion it exists to reach. The cost is accepted
|
|
828
|
+
* knowingly: a consumer who wants a GENTLER reduced-motion treatment rather
|
|
829
|
+
* than none cannot have one here, because their shorter duration is
|
|
830
|
+
* clobbered too. This is a deliberate exception to Nave's otherwise-
|
|
831
|
+
* overridable defaults, not an oversight. Do not remove the flags; if you
|
|
832
|
+
* think the trade is wrong, open an issue rather than editing them out.
|
|
833
|
+
*/
|
|
834
|
+
@media (prefers-reduced-motion: reduce) {
|
|
835
|
+
*,
|
|
836
|
+
*::before,
|
|
837
|
+
*::after {
|
|
838
|
+
animation-duration: 0.01ms !important;
|
|
839
|
+
animation-iteration-count: 1 !important;
|
|
840
|
+
scroll-behavior: auto !important;
|
|
841
|
+
transition-duration: 0.01ms !important;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/* Atomic layer. Imported plain: dist/atomic.css now declares its own
|
|
847
|
+
* `@layer atomic` so that consumers importing ./atomic directly are
|
|
848
|
+
* layered correctly too. Adding layer(atomic) here would nest it a second
|
|
849
|
+
* time. */
|
|
850
|
+
/*
|
|
851
|
+
* Nave atomic utilities — generated from src/atoms.ts
|
|
852
|
+
* Do not edit directly. Run `pnpm build` in packages/core to regenerate.
|
|
853
|
+
*
|
|
854
|
+
* Primary path: .root { @nave interactive focusRing; } (postcss plugin)
|
|
855
|
+
* Escape hatch: `${cx('interactive', 'focusRing')} ${styles.root}`
|
|
856
|
+
*
|
|
857
|
+
* Classes are global, namespaced with nave- prefix.
|
|
858
|
+
* Consumer atoms (navePlugin extend) are NOT included —
|
|
859
|
+
* they are resolved inline by the PostCSS plugin only.
|
|
860
|
+
*
|
|
861
|
+
* Self-layered under @layer atomic: this file ships as a published subpath
|
|
862
|
+
* export (./atomic) and is imported directly by some consumers, so the
|
|
863
|
+
* layer guarantee has to be a property of the artifact rather than of
|
|
864
|
+
* index.css's import site.
|
|
865
|
+
*/
|
|
866
|
+
|
|
867
|
+
@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;
|
|
868
|
+
|
|
869
|
+
@layer atomic {
|
|
870
|
+
.nave-flex {
|
|
871
|
+
display: flex;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.nave-inline-flex {
|
|
875
|
+
display: inline-flex;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.nave-grid {
|
|
879
|
+
display: grid;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.nave-block {
|
|
883
|
+
display: block;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.nave-inline-block {
|
|
887
|
+
display: inline-block;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.nave-hidden {
|
|
891
|
+
display: none;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.nave-flex-col {
|
|
895
|
+
flex-direction: column;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.nave-flex-wrap {
|
|
899
|
+
flex-wrap: wrap;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.nave-items-center {
|
|
903
|
+
align-items: center;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.nave-items-start {
|
|
907
|
+
align-items: flex-start;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.nave-items-end {
|
|
911
|
+
align-items: flex-end;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
.nave-justify-center {
|
|
915
|
+
justify-content: center;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.nave-justify-between {
|
|
919
|
+
justify-content: space-between;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.nave-justify-end {
|
|
923
|
+
justify-content: flex-end;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
.nave-flex-grow {
|
|
927
|
+
flex-grow: 1;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
.nave-flex-shrink0 {
|
|
931
|
+
flex-shrink: 0;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
.nave-gap {
|
|
935
|
+
gap: var(--nave-spacing-content-md);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
.nave-relative {
|
|
939
|
+
position: relative;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
.nave-absolute {
|
|
943
|
+
position: absolute;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.nave-inset-full {
|
|
947
|
+
inset: 0;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.nave-w-full {
|
|
951
|
+
width: 100%;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
.nave-h-full {
|
|
955
|
+
height: 100%;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
.nave-min-w0 {
|
|
959
|
+
min-width: 0;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
.nave-truncate {
|
|
963
|
+
overflow: hidden;
|
|
964
|
+
text-overflow: ellipsis;
|
|
965
|
+
white-space: nowrap;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
.nave-sr-only {
|
|
969
|
+
position: absolute;
|
|
970
|
+
width: 1px;
|
|
971
|
+
height: 1px;
|
|
972
|
+
padding: 0;
|
|
973
|
+
margin: -1px;
|
|
974
|
+
overflow: hidden;
|
|
975
|
+
clip-path: inset(50%);
|
|
976
|
+
white-space: nowrap;
|
|
977
|
+
border-width: 0;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
.nave-sr-only-focusable {
|
|
981
|
+
position: absolute;
|
|
982
|
+
width: 1px;
|
|
983
|
+
height: 1px;
|
|
984
|
+
padding: 0;
|
|
985
|
+
margin: -1px;
|
|
986
|
+
overflow: hidden;
|
|
987
|
+
clip-path: inset(50%);
|
|
988
|
+
white-space: nowrap;
|
|
989
|
+
border-width: 0;
|
|
990
|
+
|
|
991
|
+
&:focus-visible {
|
|
992
|
+
position: static;
|
|
993
|
+
width: auto;
|
|
994
|
+
height: auto;
|
|
995
|
+
margin: 0;
|
|
996
|
+
overflow: visible;
|
|
997
|
+
clip-path: none;
|
|
998
|
+
white-space: normal;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
&:focus-within {
|
|
1002
|
+
position: static;
|
|
1003
|
+
width: auto;
|
|
1004
|
+
height: auto;
|
|
1005
|
+
margin: 0;
|
|
1006
|
+
overflow: visible;
|
|
1007
|
+
clip-path: none;
|
|
1008
|
+
white-space: normal;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
.nave-no-wrap {
|
|
1013
|
+
white-space: nowrap;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
.nave-break-word {
|
|
1017
|
+
overflow-wrap: break-word;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
.nave-text-left {
|
|
1021
|
+
text-align: left;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.nave-text-center {
|
|
1025
|
+
text-align: center;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.nave-text-right {
|
|
1029
|
+
text-align: right;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
.nave-interactive {
|
|
1033
|
+
cursor: pointer;
|
|
1034
|
+
-webkit-user-select: none;
|
|
1035
|
+
user-select: none;
|
|
1036
|
+
-webkit-tap-highlight-color: transparent;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.nave-focus-ring {
|
|
1040
|
+
outline: none;
|
|
1041
|
+
|
|
1042
|
+
&:focus-visible {
|
|
1043
|
+
outline-style: solid;
|
|
1044
|
+
outline-width: var(--nave-border-width-focus, 2px);
|
|
1045
|
+
outline-color: var(--nave-color-border-focus, currentColor);
|
|
1046
|
+
outline-offset: 2px;
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
.nave-disabled-state {
|
|
1051
|
+
&:disabled, &[aria-disabled="true"] {
|
|
1052
|
+
color: var(--nave-color-content-disabled);
|
|
1053
|
+
border-color: var(--nave-color-border-disabled);
|
|
1054
|
+
pointer-events: none;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.nave-rounded {
|
|
1059
|
+
border-radius: var(--nave-radius-control);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
.nave-rounded-card {
|
|
1063
|
+
border-radius: var(--nave-radius-card);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
.nave-rounded-full {
|
|
1067
|
+
border-radius: var(--nave-radius-full);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
.nave-border {
|
|
1071
|
+
border: var(--nave-border-width-sm) solid var(--nave-color-border-default);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
.nave-overflow-hidden {
|
|
1075
|
+
overflow: hidden;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
.nave-overflow-auto {
|
|
1079
|
+
overflow: auto;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
.nave-transition {
|
|
1083
|
+
transition-property: color, background-color, border-color, opacity, box-shadow;
|
|
1084
|
+
transition-duration: var(--nave-motion-duration-base);
|
|
1085
|
+
transition-timing-function: var(--nave-motion-easing-standard);
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
.nave-container {
|
|
1089
|
+
container-type: inline-size;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
.nave-hide-phone-only {
|
|
1093
|
+
@media (width < 37.5em) {
|
|
1094
|
+
& {
|
|
1095
|
+
display: none;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.nave-hide-tablet-portrait-up {
|
|
1101
|
+
@media (width >= 37.5em) {
|
|
1102
|
+
& {
|
|
1103
|
+
display: none;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
.nave-hide-tablet-landscape-up {
|
|
1109
|
+
@media (width >= 56.25em) {
|
|
1110
|
+
& {
|
|
1111
|
+
display: none;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
.nave-hide-desktop-up {
|
|
1117
|
+
@media (width >= 75em) {
|
|
1118
|
+
& {
|
|
1119
|
+
display: none;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
.nave-stack-phone-only {
|
|
1125
|
+
@media (width < 37.5em) {
|
|
1126
|
+
& {
|
|
1127
|
+
flex-direction: column;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
.nave-w-full-phone-only {
|
|
1133
|
+
@media (width < 37.5em) {
|
|
1134
|
+
& {
|
|
1135
|
+
width: 100%;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|