@navecss/core 0.1.1 → 0.3.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.
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 1.1,
3
+ "atDirectives": [
4
+ {
5
+ "name": "@nave",
6
+ "description": {
7
+ "kind": "markdown",
8
+ "value": "The `@nave` at-rule applies one or more of Nave’s built-in atomic utilities to the CSS rule it appears in. Loading this file stops an editor from reporting `@nave` as an unknown at-rule and shows this description on hover; it does not complete atom names.\n\n- **Display:** `flex`, `inlineFlex`, `grid`, `block`, `inlineBlock`, `hidden`\n- **Flex:** `flexCol`, `flexWrap`, `itemsCenter`, `itemsStart`, `itemsEnd`, `justifyCenter`, `justifyBetween`, `justifyEnd`, `flexGrow`, `flexShrink0`, `gap`\n- **Position:** `relative`, `absolute`, `insetFull`\n- **Sizing:** `wFull`, `hFull`, `minW0`\n- **Typography:** `truncate`, `srOnly`, `srOnlyFocusable`, `noWrap`, `breakWord`, `textLeft`, `textCenter`, `textRight`\n- **Interaction:** `interactive`, `focusRing`, `disabledState`\n- **Visual:** `rounded`, `roundedCard`, `roundedFull`, `border`, `overflowHidden`, `overflowAuto`\n- **Transition:** `transition`\n- **Containment:** `container`\n- **Responsive:** `hidePhoneOnly`, `hideTabletPortraitUp`, `hideTabletLandscapeUp`, `hideDesktopUp`, `stackPhoneOnly`, `wFullPhoneOnly`\n\nAtoms registered through `extend` are valid and are not listed here."
9
+ }
10
+ }
11
+ ]
12
+ }
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@navecss/core",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
- "description": "Nave design system — layer architecture, reset, atomic utilities, PostCSS plugin",
6
+ "description": "Nave design system — layer architecture, reset, atomic utilities, and the Vite, PostCSS and Lightning CSS adapters and a command line for the @nave directive",
7
7
  "keywords": [
8
8
  "css",
9
9
  "design-system",
10
10
  "css-layers",
11
11
  "atomic-css",
12
12
  "postcss-plugin",
13
+ "vite-plugin",
14
+ "lightningcss",
13
15
  "zero-runtime"
14
16
  ],
15
17
  "homepage": "https://github.com/navecss/navecss/tree/main/packages/core#readme",
@@ -31,15 +33,39 @@
31
33
  "import": "./dist/atoms.js"
32
34
  },
33
35
  "./postcss": {
34
- "types": "./dist/postcss.d.ts",
35
- "import": "./dist/postcss.js"
36
+ "import": {
37
+ "types": "./dist/postcss.d.ts",
38
+ "default": "./dist/postcss.js"
39
+ },
40
+ "require": {
41
+ "types": "./dist/postcss.d.cts",
42
+ "default": "./dist/postcss.cjs"
43
+ }
44
+ },
45
+ "./vite": {
46
+ "types": "./dist/vite.d.ts",
47
+ "import": "./dist/vite.js"
48
+ },
49
+ "./lightningcss": {
50
+ "types": "./dist/lightningcss.d.ts",
51
+ "import": "./dist/lightningcss.js"
52
+ },
53
+ "./standalone": "./dist/standalone.css",
54
+ "./check": {
55
+ "types": "./dist/check.d.ts",
56
+ "import": "./dist/check.js"
36
57
  },
37
58
  "./package.json": "./package.json"
38
59
  },
60
+ "bin": {
61
+ "navecss-core": "./dist/bin.js"
62
+ },
39
63
  "files": [
40
64
  "dist",
41
65
  "CONSUMER-ATOMS.md",
42
- "ATOMS.md"
66
+ "ATOMS.md",
67
+ "nave.css-data.json",
68
+ "skills"
43
69
  ],
44
70
  "peerDependencies": {
45
71
  "postcss": "^8"
@@ -50,19 +76,31 @@
50
76
  }
51
77
  },
52
78
  "dependencies": {
53
- "@navecss/tokens": "^0.1.1"
79
+ "@navecss/tokens": "^0.3.0"
54
80
  },
55
81
  "devDependencies": {
56
- "@types/node": "^26.6.2",
57
- "@vitest/browser": "5.0.1",
58
- "@vitest/browser-playwright": "5.0.1",
59
- "@vitest/coverage-v8": "5.0.1",
82
+ "@rmenke/css-tokenizer-tests": "1.4.0",
83
+ "@sveltejs/vite-plugin-svelte": "7.3.1",
84
+ "@types/node": "^26.6.4",
85
+ "@vitejs/plugin-vue": "6.0.9",
86
+ "@vitest/browser": "5.0.3",
87
+ "@vitest/browser-playwright": "5.0.3",
88
+ "@vitest/coverage-v8": "5.0.3",
89
+ "lightningcss": "1.33.0",
90
+ "lightningcss-1-24": "npm:lightningcss@1.24.1",
60
91
  "playwright": "1.63.0",
61
92
  "postcss": "^8.5.28",
62
- "prettier": "3.9.8",
93
+ "prettier": "3.9.9",
94
+ "sass": "1.105.1",
95
+ "source-map": "^0.8.0",
96
+ "svelte": "5.57.2",
63
97
  "tsup": "^8.5.1",
64
98
  "typescript": "6.0.3",
65
- "vitest": "5.0.1"
99
+ "vite": "8.3.3",
100
+ "vite-floor": "npm:vite@8.2.1",
101
+ "vitest": "5.0.3",
102
+ "vscode-css-languageservice": "6.3.10",
103
+ "vue": "3.5.43"
66
104
  },
67
105
  "engines": {
68
106
  "node": ">=22.18"
@@ -83,11 +121,10 @@
83
121
  "dev": "tsup --watch",
84
122
  "clean": "rm -rf dist",
85
123
  "typecheck": "tsc --noEmit && tsc --noEmit -p test/browser/tsconfig.json",
86
- "lint": "eslint src scripts --max-warnings 0 && stylelint \"src/**/*.css\" --max-warnings 0",
87
- "lint:fix": "eslint src scripts --fix && stylelint \"src/**/*.css\" --fix",
88
- "test": "node scripts/generate-consumer-theming-fixtures.ts && vitest run",
89
- "test:coverage": "node scripts/generate-consumer-theming-fixtures.ts && vitest run --coverage",
90
- "test:browser": "node scripts/generate-consumer-theming-fixtures.ts && vitest run --config vitest.browser.config.ts",
91
- "check:pack": "node ../../scripts/without-dry-run.mjs publint && node ../../scripts/without-dry-run.mjs attw --pack . --profile esm-only --exclude-entrypoints . layers no-tokens reset atomic"
124
+ "lint": "eslint src scripts \"test/**/*.ts\" --max-warnings 0 && stylelint \"src/**/*.css\" --max-warnings 0",
125
+ "lint:fix": "eslint src scripts \"test/**/*.ts\" --fix && stylelint \"src/**/*.css\" --fix",
126
+ "test": "node scripts/generate-consumer-theming-fixtures.ts && node scripts/generate-vite-plugin-fixtures.ts && vitest run",
127
+ "test:browser": "node scripts/generate-consumer-theming-fixtures.ts && node scripts/generate-vite-plugin-fixtures.ts && node scripts/generate-lightningcss-fixtures.ts && node scripts/generate-no-bundler-fixture.ts && vitest run --config vitest.browser.config.ts && vitest run --config vitest.chromium.config.ts",
128
+ "check:pack": "node ../../scripts/without-dry-run.mjs publint && node ../../scripts/without-dry-run.mjs attw --pack . --profile esm-only --exclude-entrypoints . layers no-tokens reset atomic standalone"
92
129
  }
93
130
  }
@@ -0,0 +1,317 @@
1
+ ---
2
+ name: navecss
3
+ description: 'Reference for Nave — the @nave at-rule, cx()/cx.raw(), --nave-* custom
4
+ properties and the @layer order — so an agent applies existing atoms and tokens instead
5
+ of inventing new CSS.'
6
+ ---
7
+
8
+ # navecss
9
+
10
+ An index of Nave’s vocabulary for a coding agent: every built-in atom, every `--nave-*`
11
+ custom property, the layer order, and the idiom that applies them. See
12
+ [ATOMS.md](../../ATOMS.md) for the same atom table alone, and
13
+ [Theming](https://github.com/navecss/navecss/blob/main/README.md#theming) for how a project
14
+ changes the seed colour and everything derived from it.
15
+
16
+ ## Using `@nave` and `var(--nave-*)`
17
+
18
+ Apply built-in atoms with the `@nave` at-rule inside a CSS rule; read values through
19
+ `var(--nave-*)`. Both vocabularies are closed sets: the built-in atom names and the
20
+ `--nave-*` names are exactly the ones on this page.
21
+ An atom name that is neither on this page nor in the project’s own `navePlugin({ extend })`
22
+ configuration is not used, and a `--nave-*` name not on this page is not used either:
23
+ when the name you need does not exist, say so rather than invent one.
24
+ An undeclared `--nave-*` name renders nothing; `@navecss/stylelint-config` reports it.
25
+
26
+ Atoms a project registers through `navePlugin({ extend })` are not listed on this page.
27
+ They are valid in `@nave` only, never in `cx()`, and they live in that project’s own
28
+ `navePlugin({ extend })` configuration, so look for them there
29
+ (their shape is in [CONSUMER-ATOMS.md](../../CONSUMER-ATOMS.md)).
30
+ Where one shares a built-in atom’s name,
31
+ `@nave` applies the project’s atom and `cx()` still returns the built-in,
32
+ so the declarations this page shows for that name are not what `@nave` applies there.
33
+
34
+ ```css
35
+ /* button.module.css */
36
+ @layer components.consumer {
37
+ .root {
38
+ @nave interactive focusRing transition;
39
+ background: var(--nave-color-action-primary);
40
+ color: var(--nave-color-on-action-primary);
41
+ padding: var(--nave-spacing-control-md) var(--nave-spacing-control-lg);
42
+ border-radius: var(--nave-radius-control);
43
+ }
44
+ }
45
+ ```
46
+
47
+ Consumer rules go in `@layer components.consumer`, and a deliberate exception in
48
+ `@layer overrides`; never write an unlayered rule. Atom names are the camelCase keys listed
49
+ under Atoms below (`focusRing`, `justifyBetween`), never the `nave-` class they emit.
50
+
51
+ See where `@nave` is valid (nesting depth, `@media`/`@container`, `@keyframes`) in
52
+ [the package README](../../README.md#where-nave-is-valid).
53
+
54
+ ## `cx()`
55
+
56
+ The JavaScript escape hatch: `cx('interactive', 'focusRing')` returns the class of each
57
+ built-in atom it names, and `cx()` takes built-in atoms and nothing else.
58
+ Its type check is TypeScript only: a JavaScript consumer gets none of it. A type error from
59
+ `cx()` means the name is wrong: it is never a reason to reach for `cx.raw()` or a cast.
60
+
61
+ In a project whose Vite config uses `navePlugin()` from `@navecss/core/vite`, the build reads every `cx()` call and fails on one whose atoms it cannot list. Pass names it can read (a literal, a condition between literals, a `const` in the same file); to choose by a value, call `cx()` once per case and pick between the results; pass a name known only at run time to `cx.dynamic()`, with its atoms in `keep`. The build's report names its remedies, most preferred first: take the first one that fits. Never set `atomic: 'all'`, never build a `nave-` class from pieces, and never apply a class taken from `@navecss/core/atoms`, to make a report go away. The dev server serves the atoms the build would ship, chosen from the code it has read, so a `nave-*` class with no rule in dev is written where the build cannot see it: move it into code the build reads, or list its atom in `keep`.
62
+
63
+ ## `cx.raw()`
64
+
65
+ `cx.raw()` is for a class from outside any system Nave sees, the project’s own classes
66
+ included. Where a project class shares an atom’s name, `cx('container')` is Nave’s atom and
67
+ `cx.raw('container')` is the project’s class.
68
+
69
+ `cx.raw()` is also for a CSS Module class behind a condition, shown by the code span
70
+ `cx.raw(isActive && styles.active)`, because a template-literal slot interpolates a falsy
71
+ condition’s own value — naming `false`, `undefined` and `0` — as a class.
72
+
73
+ If the project runs `@navecss/eslint-plugin`, its reports name their remedies, most preferred first: take the first one that fits. Never answer a report with a disable comment, and never write a `cx.raw()` reason to make a report go away.
74
+
75
+ ## Atoms
76
+
77
+ Every built-in atom: the name as written in `@nave` and `cx()`, the declarations it
78
+ applies, and its pseudo-class, `@media` or `@container` variants.
79
+ A name not on this list is not a built-in atom.
80
+ A project’s own `navePlugin({ extend })` atoms are not listed here (see Using `@nave` above);
81
+ a name that is in neither is not used, so do not invent one.
82
+
83
+ ### Display
84
+
85
+ | Atom | Declarations | Variants |
86
+ | ------------- | ------------------------ | -------- |
87
+ | `flex` | `display: flex;` | — |
88
+ | `inlineFlex` | `display: inline-flex;` | — |
89
+ | `grid` | `display: grid;` | — |
90
+ | `block` | `display: block;` | — |
91
+ | `inlineBlock` | `display: inline-block;` | — |
92
+ | `hidden` | `display: none;` | — |
93
+
94
+ ### Flex
95
+
96
+ | Atom | Declarations | Variants |
97
+ | ---------------- | -------------------------------------- | -------- |
98
+ | `flexCol` | `flex-direction: column;` | — |
99
+ | `flexWrap` | `flex-wrap: wrap;` | — |
100
+ | `itemsCenter` | `align-items: center;` | — |
101
+ | `itemsStart` | `align-items: flex-start;` | — |
102
+ | `itemsEnd` | `align-items: flex-end;` | — |
103
+ | `justifyCenter` | `justify-content: center;` | — |
104
+ | `justifyBetween` | `justify-content: space-between;` | — |
105
+ | `justifyEnd` | `justify-content: flex-end;` | — |
106
+ | `flexGrow` | `flex-grow: 1;` | — |
107
+ | `flexShrink0` | `flex-shrink: 0;` | — |
108
+ | `gap` | `gap: var(--nave-spacing-content-md);` | — |
109
+
110
+ ### Position
111
+
112
+ | Atom | Declarations | Variants |
113
+ | ----------- | --------------------- | -------- |
114
+ | `relative` | `position: relative;` | — |
115
+ | `absolute` | `position: absolute;` | — |
116
+ | `insetFull` | `inset: 0;` | — |
117
+
118
+ ### Sizing
119
+
120
+ | Atom | Declarations | Variants |
121
+ | ------- | --------------- | -------- |
122
+ | `wFull` | `width: 100%;` | — |
123
+ | `hFull` | `height: 100%;` | — |
124
+ | `minW0` | `min-width: 0;` | — |
125
+
126
+ ### Typography
127
+
128
+ | Atom | Declarations | Variants |
129
+ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
130
+ | `truncate` | `overflow: hidden;`<br>`text-overflow: ellipsis;`<br>`white-space: nowrap;` | — |
131
+ | `srOnly` | `position: absolute;`<br>`width: 1px;`<br>`height: 1px;`<br>`padding: 0;`<br>`margin: -1px;`<br>`overflow: hidden;`<br>`clip-path: inset(50%);`<br>`white-space: nowrap;`<br>`border-width: 0;` | — |
132
+ | `srOnlyFocusable` | `position: absolute;`<br>`width: 1px;`<br>`height: 1px;`<br>`padding: 0;`<br>`margin: -1px;`<br>`overflow: hidden;`<br>`clip-path: inset(50%);`<br>`white-space: nowrap;`<br>`border-width: 0;` | `:focus-visible` — `position: static;`<br>`width: auto;`<br>`height: auto;`<br>`margin: 0;`<br>`overflow: visible;`<br>`clip-path: none;`<br>`white-space: normal;`<br>`:focus-within` — `position: static;`<br>`width: auto;`<br>`height: auto;`<br>`margin: 0;`<br>`overflow: visible;`<br>`clip-path: none;`<br>`white-space: normal;` |
133
+ | `noWrap` | `white-space: nowrap;` | — |
134
+ | `breakWord` | `overflow-wrap: break-word;` | — |
135
+ | `textLeft` | `text-align: left;` | — |
136
+ | `textCenter` | `text-align: center;` | — |
137
+ | `textRight` | `text-align: right;` | — |
138
+
139
+ ### Interaction
140
+
141
+ | Atom | Declarations | Variants |
142
+ | --------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
143
+ | `interactive` | `cursor: pointer;`<br>`-webkit-user-select: none;`<br>`user-select: none;`<br>`-webkit-tap-highlight-color: transparent;` | — |
144
+ | `focusRing` | `outline: none;` | `:focus-visible` — `outline-style: solid;`<br>`outline-width: var(--nave-border-width-focus, 2px);`<br>`outline-color: var(--nave-color-border-focus, currentColor);`<br>`outline-offset: 2px;` |
145
+ | `disabledState` | — | `:disabled, [aria-disabled="true"]` — `color: var(--nave-color-content-disabled);`<br>`border-color: var(--nave-color-border-disabled);`<br>`pointer-events: none;`<br>On the aria-disabled branch the element stays focusable by design: this atom only blocks pointer activation (pointer-events: none), so the component's own activation handler must also check the attribute and no-op on Enter and Space, since CSS cannot prevent keyboard activation. |
146
+
147
+ ### Visual
148
+
149
+ | Atom | Declarations | Variants |
150
+ | ---------------- | ----------------------------------------------------------------------------- | -------- |
151
+ | `rounded` | `border-radius: var(--nave-radius-control);` | — |
152
+ | `roundedCard` | `border-radius: var(--nave-radius-card);` | — |
153
+ | `roundedFull` | `border-radius: var(--nave-radius-full);` | — |
154
+ | `border` | `border: var(--nave-border-width-sm) solid var(--nave-color-border-default);` | — |
155
+ | `overflowHidden` | `overflow: hidden;` | — |
156
+ | `overflowAuto` | `overflow: auto;` | — |
157
+
158
+ ### Transition
159
+
160
+ | Atom | Declarations | Variants |
161
+ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
162
+ | `transition` | `transition-property: color, background-color, border-color, opacity, box-shadow;`<br>`transition-duration: var(--nave-motion-duration-base);`<br>`transition-timing-function: var(--nave-motion-easing-standard);` | — |
163
+
164
+ ### Containment
165
+
166
+ | Atom | Declarations | Variants |
167
+ | ----------- | ------------------------------ | -------- |
168
+ | `container` | `container-type: inline-size;` | — |
169
+
170
+ ### Responsive
171
+
172
+ | Atom | Declarations | Variants |
173
+ | ----------------------- | ------------ | ----------------------------------------------------- |
174
+ | `hidePhoneOnly` | — | `@media (width < 37.5em)` — `display: none;` |
175
+ | `hideTabletPortraitUp` | — | `@media (width >= 37.5em)` — `display: none;` |
176
+ | `hideTabletLandscapeUp` | — | `@media (width >= 56.25em)` — `display: none;` |
177
+ | `hideDesktopUp` | — | `@media (width >= 75em)` — `display: none;` |
178
+ | `stackPhoneOnly` | — | `@media (width < 37.5em)` — `flex-direction: column;` |
179
+ | `wFullPhoneOnly` | — | `@media (width < 37.5em)` — `width: 100%;` |
180
+
181
+ ## Custom properties
182
+
183
+ Every `--nave-*` custom property Nave declares, with its description where one exists. A
184
+ name not on this list is not declared — an undeclared `--nave-*` name passes the build and
185
+ renders nothing.
186
+
187
+ - `--nave-border-width-focus`: Focus ring indicator outline width
188
+ - `--nave-border-width-lg`
189
+ - `--nave-border-width-mark`: Strokes of glyphs drawn in CSS: check marks, indeterminate bars
190
+ - `--nave-border-width-none`
191
+ - `--nave-border-width-sm`: Default border / divider
192
+ - `--nave-color-action-primary`
193
+ - `--nave-color-action-primary-active`
194
+ - `--nave-color-action-primary-hover`
195
+ - `--nave-color-action-secondary`
196
+ - `--nave-color-border-control`: Identifying boundary for a control (inputs, form boundaries, and the secondary action control).
197
+ - `--nave-color-border-default`: Decorative dividers and card edges.
198
+ - `--nave-color-border-disabled`
199
+ - `--nave-color-border-focus`
200
+ - `--nave-color-border-strong`
201
+ - `--nave-color-content-disabled`: Text inside a disabled interactive component.
202
+ - `--nave-color-content-inverse`: Declared foreground for surface.inverse.
203
+ - `--nave-color-content-link`: Do not distinguish a link by colour alone. Nave's own examples keep a non-colour distinction wherever this token is shown.
204
+ - `--nave-color-content-primary`
205
+ - `--nave-color-content-secondary`
206
+ - `--nave-color-content-tertiary`: Placeholder and hint text only.
207
+ - `--nave-color-feedback-danger`: Solid-background role for a destructive control or error state.
208
+ - `--nave-color-feedback-danger-foreground`: Foreground role for danger text and icons.
209
+ - `--nave-color-feedback-info`: Alias of feedback.warning (shared tinted-neutral family).
210
+ - `--nave-color-feedback-info-foreground`
211
+ - `--nave-color-feedback-success`: Alias of feedback.warning (shared tinted-neutral family).
212
+ - `--nave-color-feedback-success-foreground`
213
+ - `--nave-color-feedback-warning`: Solid-background role for a warning state (shared tinted-neutral family).
214
+ - `--nave-color-feedback-warning-foreground`: Foreground role for warning text and icons.
215
+ - `--nave-color-on-action-primary`
216
+ - `--nave-color-on-feedback-danger`: Declared foreground for the solid feedback.danger background.
217
+ - `--nave-color-on-feedback-info`
218
+ - `--nave-color-on-feedback-success`
219
+ - `--nave-color-on-feedback-warning`
220
+ - `--nave-color-surface-base`
221
+ - `--nave-color-surface-inverse`
222
+ - `--nave-color-surface-overlay`
223
+ - `--nave-color-surface-raised`
224
+ - `--nave-color-surface-sunken`
225
+ - `--nave-color-tint`
226
+ - `--nave-font-family-base`: Body / UI typeface
227
+ - `--nave-font-family-display`: Heading typeface — swap for a display font when ready
228
+ - `--nave-font-family-mono`: Code / monospace typeface
229
+ - `--nave-font-size-2xl`
230
+ - `--nave-font-size-3xl`
231
+ - `--nave-font-size-4xl`
232
+ - `--nave-font-size-lg`
233
+ - `--nave-font-size-md`: Base body size (16px default)
234
+ - `--nave-font-size-sm`
235
+ - `--nave-font-size-xl`
236
+ - `--nave-font-size-xs`
237
+ - `--nave-font-weight-bold`
238
+ - `--nave-font-weight-medium`
239
+ - `--nave-font-weight-regular`
240
+ - `--nave-font-weight-semibold`
241
+ - `--nave-layer-base`: Default document flow
242
+ - `--nave-layer-dropdown`: Dropdowns, context menus, select panels
243
+ - `--nave-layer-modal`: Modal dialogs and drawers
244
+ - `--nave-layer-overlay`: Backdrop overlays behind modals
245
+ - `--nave-layer-sticky`: Sticky headers, floating toolbars
246
+ - `--nave-layer-toast`: Toast notifications and snackbars
247
+ - `--nave-layer-tooltip`: Tooltips — always on top of everything
248
+ - `--nave-letter-spacing-normal`: Default — no adjustment
249
+ - `--nave-letter-spacing-tight`: Large headings and display text
250
+ - `--nave-letter-spacing-wide`: Uppercase labels, small caps
251
+ - `--nave-line-height-base`: Default body line height
252
+ - `--nave-line-height-loose`
253
+ - `--nave-line-height-none`: Single-line / icon buttons — no extra leading
254
+ - `--nave-line-height-relaxed`
255
+ - `--nave-line-height-snug`
256
+ - `--nave-line-height-tight`: Headings
257
+ - `--nave-motion-duration-base`: Default state transitions: hover, focus
258
+ - `--nave-motion-duration-fast`: Micro-interactions: tooltips, badges
259
+ - `--nave-motion-duration-instant`: No animation — kept at 0ms even under prefers-reduced-motion
260
+ - `--nave-motion-duration-slow`: Layout shifts: accordion, drawer
261
+ - `--nave-motion-easing-accelerate`: Elements leaving the screen
262
+ - `--nave-motion-easing-decelerate`: Elements entering the screen
263
+ - `--nave-motion-easing-standard`: General-purpose — enters and exits
264
+ - `--nave-opacity-disabled`: Opacity multiplier for muting content that is inert and contains nothing focusable (e.g. a disabled icon or illustration). Nave's own interactive-disabled state is expressed through content.disabled and border.disabled instead, not this token: opacity composites everything an element paints, including a focus indicator inside it.
265
+ - `--nave-radius-card`: Cards, panels, dialogs
266
+ - `--nave-radius-control`: Inputs, buttons, tags, and the popovers, menus and select lists anchored to a control
267
+ - `--nave-radius-full`: Pill / badge shape
268
+ - `--nave-radius-none`
269
+ - `--nave-radius-overlay`: Modals, drawers, sheets
270
+ - `--nave-radius-sm`
271
+ - `--nave-shadow-modal`: Dialogs and modals — highest elevation
272
+ - `--nave-shadow-none`: No elevation
273
+ - `--nave-shadow-overlay`: Popovers, dropdowns, floating elements
274
+ - `--nave-shadow-raised`: Cards, slight elevation above base
275
+ - `--nave-size-avatar-lg`
276
+ - `--nave-size-avatar-md`
277
+ - `--nave-size-avatar-sm`
278
+ - `--nave-size-control-lg`: Large controls
279
+ - `--nave-size-control-md`: Default control height
280
+ - `--nave-size-control-sm`: Small controls
281
+ - `--nave-size-control-xs`: Compact/dense controls
282
+ - `--nave-size-icon-lg`
283
+ - `--nave-size-icon-md`: Default inline icon
284
+ - `--nave-size-icon-sm`
285
+ - `--nave-size-icon-xl`
286
+ - `--nave-size-icon-xs`
287
+ - `--nave-spacing-content-lg`
288
+ - `--nave-spacing-content-md`: Default component gap and padding
289
+ - `--nave-spacing-content-sm`
290
+ - `--nave-spacing-content-xl`
291
+ - `--nave-spacing-content-xs`
292
+ - `--nave-spacing-control-lg`
293
+ - `--nave-spacing-control-md`
294
+ - `--nave-spacing-control-sm`: No matching _primitive.space rung; authored directly
295
+ - `--nave-spacing-control-xs`
296
+ - `--nave-spacing-layout-lg`
297
+ - `--nave-spacing-layout-md`
298
+ - `--nave-spacing-layout-sm`
299
+ - `--nave-spacing-layout-xs`
300
+
301
+ ## Layers
302
+
303
+ Nave’s layer order: `@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;`
304
+
305
+ The order holds only if it is the first `@layer` declaration the page sees:
306
+ a stylesheet that declares a layer and loads earlier fixes that layer’s position first,
307
+ and the order inverts with no error.
308
+ So keep `@navecss/core/layers`, the order statement alone, as the first import of the
309
+ entry stylesheet, and load that stylesheet before anything that brings its own stylesheet,
310
+ components included.
311
+
312
+ Your own component CSS goes in `@layer components.consumer`; a deliberate exception goes in
313
+ `@layer overrides`, which beats every other layer. A rule left outside any layer beats them
314
+ all, `overrides` included, so never write unlayered CSS.
315
+ That is the order for normal declarations. `!important` reverses it: an `!important` in
316
+ `overrides` loses to one in any earlier layer, Nave’s reset included, and one outside any
317
+ layer loses to every layered one.