@navecss/core 0.4.0 → 0.5.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/CONSUMER-ATOMS.md CHANGED
@@ -122,20 +122,22 @@ Compiles to:
122
122
  user-select: none;
123
123
  -webkit-tap-highlight-color: transparent;
124
124
  outline: none;
125
- transition-property: color, background-color, border-color, opacity, box-shadow;
126
- transition-duration: var(--nave-motion-duration-base);
127
- transition-timing-function: var(--nave-motion-easing-standard);
128
- background: var(--nave-color-action-primary);
129
- color: var(--nave-color-on-action-primary);
130
- padding: var(--nave-spacing-control-md) var(--nave-spacing-control-lg);
131
- border-radius: var(--nave-radius-control);
132
- font-weight: var(--nave-font-weight-medium);
133
125
  &:focus-visible {
134
126
  outline-style: solid;
135
127
  outline-width: var(--nave-border-width-focus, 2px);
136
128
  outline-color: var(--nave-color-border-focus, currentColor);
137
129
  outline-offset: 2px;
138
130
  }
131
+ & {
132
+ transition-property: color, background-color, border-color, opacity, box-shadow;
133
+ transition-duration: var(--nave-motion-duration-base);
134
+ transition-timing-function: var(--nave-motion-easing-standard);
135
+ background: var(--nave-color-action-primary);
136
+ color: var(--nave-color-on-action-primary);
137
+ padding: var(--nave-spacing-control-md) var(--nave-spacing-control-lg);
138
+ border-radius: var(--nave-radius-control);
139
+ font-weight: var(--nave-font-weight-medium);
140
+ }
139
141
  &:hover {
140
142
  background: var(--nave-color-action-primary-hover);
141
143
  }
@@ -293,15 +295,17 @@ Compiles to:
293
295
  display: flex;
294
296
  flex-direction: column;
295
297
  gap: var(--nave-spacing-content-md);
296
- background: var(--nave-color-surface-raised);
297
- border-radius: var(--nave-radius-card);
298
- padding: var(--nave-spacing-content-md);
299
298
  @container (width >= 28rem) {
300
299
  & {
301
300
  flex-direction: row;
302
301
  align-items: center;
303
302
  }
304
303
  }
304
+ & {
305
+ background: var(--nave-color-surface-raised);
306
+ border-radius: var(--nave-radius-card);
307
+ padding: var(--nave-spacing-content-md);
308
+ }
305
309
  }
306
310
  }
307
311
  ```
package/LICENSE CHANGED
@@ -55,3 +55,25 @@ JavaScript under dist/: the member names of a version 3 source map, the
55
55
  layout of its mappings string, the base64 VLQ encoding of each field in it,
56
56
  and the base64 alphabet. The code implementing them is this package's own, and
57
57
  everything in this package is offered under the MIT licence above.
58
+
59
+ This package also includes material copied from or derived from mdn-data
60
+ (css/properties.json in the mdn/data repository, version 2.37.2,
61
+ https://github.com/mdn/data), which its authors dedicated to the public domain
62
+ under CC0 1.0 Universal (https://creativecommons.org/publicdomain/zero/1.0/),
63
+ and from CSS Logical Properties and Values Module Level 1, CSS Overflow Module
64
+ Level 3, CSS Overscroll Behavior Module Level 1, CSS Scroll Snap Module Level 1,
65
+ CSS Box Sizing Module Level 4, CSS Fonts Module Level 4, CSS Text Module Level
66
+ 4, CSS Gaps Module Level 1, CSS Fragmentation Module Level 4, CSS Backgrounds
67
+ and Borders Module Level 3, and CSS Cascading and Inheritance Module Level 5 (in
68
+ the w3c/csswg-drafts repository, at commit
69
+ 40527902c4d0840cdb7a808c8cd42302be1c3bc8). Copyright (c) 2026 World Wide Web
70
+ Consortium. Those specifications, and the repository carrying them, are
71
+ published under the W3C Software and Document License
72
+ (https://www.w3.org/copyright/software-license-2023/).
73
+
74
+ What is copied or derived is implemented in
75
+ src/directive/property-table.generated.ts, built into the JavaScript under
76
+ dist/: the names of CSS properties, the properties each shorthand sets, which
77
+ names are legacy name aliases of another property, and which logical and
78
+ physical properties belong to one group. The code using them is this package's
79
+ own, and everything in this package is offered under the MIT licence above.
package/README.md CHANGED
@@ -107,10 +107,141 @@ Requires the Vite plugin or the PostCSS plugin. Everything stays in CSS files.
107
107
  ```
108
108
 
109
109
  Declarations are inlined at build time, and nothing of `@nave` is left at run time.
110
- Pseudo-class rules (`:focus-visible` from `focusRing`), `@media` and
111
- `@container` blocks are emitted as native CSS nesting inside your rule, so they
112
- apply to every selector in a selector list. Native nesting is inside the browser
113
- floor under [Requirements](#requirements).
110
+ Pseudo-class rules (`:focus-visible` from `focusRing`), `@media` and `@container` blocks are
111
+ emitted as native CSS nesting inside your rule, each right after its own atom's declarations, so
112
+ they apply to every selector in a selector list. Native nesting is inside the browser floor under
113
+ [Requirements](#requirements), and [Order inside a rule](#order-inside-a-rule) says what wins when
114
+ your rule sets the same property.
115
+
116
+ #### Order inside a rule
117
+
118
+ `@nave a b;` expands where you write it, in the order CSS mixins will apply
119
+ `@apply --a; @apply --b;`: the declarations of `a`, then the pseudo-class,
120
+ `@media` and `@container` blocks of `a`, then the same for `b`. Whatever your rule
121
+ says after the directive comes after all of it. So of two declarations of one
122
+ property that both apply, the later one wins, unless the earlier one has the more
123
+ specific selector (an atom's pseudo-class block, such as the `:focus-visible` of
124
+ `focusRing`, does), as anywhere else in CSS.
125
+
126
+ ```css
127
+ .panel {
128
+ @nave flex hideDesktopUp;
129
+ gap: var(--nave-spacing-content-md);
130
+ }
131
+ ```
132
+
133
+ expands to:
134
+
135
+ ```css
136
+ .panel {
137
+ display: flex;
138
+ @media (width >= 75em) {
139
+ & {
140
+ display: none;
141
+ }
142
+ }
143
+ & {
144
+ gap: var(--nave-spacing-content-md);
145
+ }
146
+ }
147
+ ```
148
+
149
+ A declaration that follows a nested block is written inside `& { }`, the wrapper
150
+ Nave already uses for a directive written after a nested rule. Under a selector
151
+ list, `&` matches with the specificity of the list's most specific selector, so a
152
+ wrapped declaration can win over a rule elsewhere that a bare one would lose to;
153
+ write it above the directive if that matters.
154
+
155
+ The order you write is the order that wins:
156
+
157
+ | You write | From 75em up |
158
+ | ------------------------------------- | ---------------- |
159
+ | `@nave flex hideDesktopUp;` | hidden |
160
+ | `@nave hideDesktopUp flex;` | shown, as flex |
161
+ | `display: grid; @nave hideDesktopUp;` | hidden |
162
+ | `@nave hideDesktopUp; display: grid;` | shown, as a grid |
163
+
164
+ Name a responsive or state atom after the atoms it adjusts, and write a declaration
165
+ that should give way to an atom's variants above the directive. A declaration or a
166
+ nested block below the directive is how you customize an atom inside your own rule.
167
+
168
+ The same order applies to the focus atoms. After `@nave focusRing;`, a later
169
+ `&:focus-visible { outline-color: var(--brand) }` recolours the ring, and a later
170
+ `&:focus { outline: none }` or `&:focus-visible { outline: none }` removes it,
171
+ which leaves the element with no focus indicator from `focusRing` under keyboard
172
+ focus. After `@nave srOnlyFocusable;`, a later `&:focus-visible { position: fixed }`
173
+ places the revealed element, and a later `clip-path: inset(50%)` in the same state
174
+ hides it again, so a skip link stays hidden when it has focus. To keep the atom's
175
+ result, write the block above the directive. The order warning below reports each
176
+ of these, and says so when the ring or the reveal is lost.
177
+
178
+ **The order warning.** Where something later in the rule overrides one of an atom's
179
+ pseudo-class, `@media` or `@container` blocks with a different value, the build
180
+ prints a warning at the later content. Where moving something lets the atom win
181
+ without a new warning, it says what to move, and it always shows how to mark the
182
+ directive if the later value is meant to win:
183
+
184
+ ```text
185
+ src/panel.css:3:3: @nave: display: grid comes after "hideDesktopUp", so under @media (width >= 75em) display is grid, not none. Before @navecss/core 0.5.0 "hideDesktopUp" won, because an atom's blocks were placed last in the rule. To let "hideDesktopUp" win, move display: grid above the directive. If it is meant to win, mark the directive that names "hideDesktopUp": `@nave /* nave-allow-override: display */ hideDesktopUp;`
186
+ ```
187
+
188
+ Where no move clears the warning, as when the later value comes from another atom's
189
+ block and moving either only turns the pair round, it prints only the marker. Write
190
+ the atom that should win last, and mark the directive the warning then names.
191
+
192
+ It never fails the build, and `onUnknown` does not change it. The Vite plugin prints
193
+ it through Vite's logger, the PostCSS plugin as a PostCSS warning (and with `console.warn` on
194
+ Next.js under Turbopack, which does not print PostCSS warnings), the Lightning CSS
195
+ adapter with `console.warn`, and `navecss-core expand` on standard error, without
196
+ changing its exit code. No option turns it off for the whole project.
197
+
198
+ A directive written inside a nested rule that applies to the same element, such as
199
+ `.card { & { @nave hideDesktopUp } display: flex; }`, is checked the same way: its atoms' blocks
200
+ are compared with what follows the directive inside that nested rule, and with what each
201
+ enclosing rule holds after the nested rule. A warning of the second kind says nothing about
202
+ earlier releases, because that later content already won in them.
203
+
204
+ **Marking an override you mean.** Name the property in a comment inside the
205
+ directive:
206
+
207
+ ```css
208
+ .panel {
209
+ @nave /* nave-allow-override: display */ hideDesktopUp;
210
+ display: grid;
211
+ }
212
+ ```
213
+
214
+ The comment says that what comes after this directive's atoms (a later atom in it,
215
+ or your rule's own content) is meant to win for the properties it names. It
216
+ silences the warning for those properties on this directive and nothing else: an
217
+ override of another property, or of another directive's atoms, still warns. A
218
+ shorthand covers its longhands (`outline` covers `outline-color`). You can add a
219
+ reason after `--`: `/* nave-allow-override: display -- a grid on wide screens */`.
220
+ The head `nave-allow-override:` is matched in lower case only, as `eslint-disable`
221
+ is, so a comment that writes it in another case is not a marker: it allows nothing,
222
+ and the warning it was meant to silence still prints.
223
+ The comment never reaches your CSS. Only a comment inside the directive is read,
224
+ because some build steps remove the others before Nave sees the stylesheet (Vite
225
+ under `css.transformer: 'lightningcss'`, for one). A marker naming a property that
226
+ nothing overrides any more is reported, so remove it when you reorder. The Vite plugin under
227
+ `css.transformer: 'lightningcss'` does not report one, at any targets, because it cannot tell
228
+ whether Lightning CSS has already moved what follows the directive.
229
+
230
+ #### Output size
231
+
232
+ `@nave` copies an atom's declarations into every rule that uses it. That is the design: the directive is a build-time stand-in for native CSS mixins, whose `@apply` puts a mixin's declarations into the rule that applies it ([why](https://github.com/navecss/navecss/blob/main/docs/04-adr/0006-nave-directive-stands-in-for-css-mixins.md)). A browser that supports native mixins does that expansion itself, so such a stylesheet carries each mixin's body once, plus a short `@apply` where it is used; a build step has to write the copies out.
233
+
234
+ What the copies cost, in a model of a large app (10,000 component rules using a 25-atom design system and class names of about 20 characters, minified): about 70 percent of the raw CSS, 40 percent after gzip and 30 percent after brotli at level 11. Your app will differ, so measure your own bundle. What reduces it:
235
+
236
+ - **Compress CSS ahead of time with brotli at its highest level (11)**, instead of compressing on the fly at a lower one. In the model, level 11 sent 260 KB where level 5 sent 330 KB, which saves more than any way of removing the copies that was tried (below).
237
+ - **Split CSS by route**, so a page loads a shared part and its own rules rather than the whole app's. Split into one shared part and 40 routes, a page in the model loaded 65 KB at level 11, about a quarter, though all the parts together came to 348 KB, a third more than the single bundle.
238
+
239
+ What Nave does not do, and why:
240
+
241
+ - **It does not merge the copies into shared rules with combined selector lists.** In the model that saved 0.3 percent under brotli at level 11 and made gzip output 19 percent larger, because each selector then repeats once per atom, far apart. With 7-character class names the same merge saved 2 percent under gzip, 4 under brotli at level 11 and 12 under brotli at level 5, still less than level 11 saves over level 5. It also changed the computed style of 4 to 6 percent of the elements sampled: two atoms that set the same property stop resolving in the order you wrote them, and an atom's `@media` blocks move relative to your own declarations.
242
+ - **It does not turn your `@nave` atoms into shared classes for your markup to carry** (`cx()` does that for Nave's built-in atoms, where you choose it). That would move them into the `atomic` layer, below your component CSS, so your other rules and Nave's own component styles start beating them, and the class names it would add to your JavaScript and HTML cost about as much as the CSS it would remove under brotli, and about half as much under gzip.
243
+
244
+ The lasting fix is native CSS mixins. Once they ship in a browser and the specification settles, Nave adds a flag that writes `@mixin` and `@apply`, and once all three engines support them that becomes the default.
114
245
 
115
246
  ### Escape hatch — cx() utility
116
247
 
@@ -193,7 +324,8 @@ Every custom property Nave declares is in the stylesheet you already installed,
193
324
 
194
325
  ## Setting up `@nave`
195
326
 
196
- On Vite, use the Vite plugin: it is the one route this package teaches for Vite. On
327
+ On Vite, use the Vite plugin: it is the one route this package teaches for Vite, and for Astro,
328
+ which builds with Vite ([Astro](#astro) has its config). On
197
329
  Next.js, webpack, or any other pipeline that runs PostCSS plugins, use the PostCSS plugin. A host
198
330
  that runs Lightning CSS directly uses [the Lightning CSS adapter](#lightning-css-adapter-setup),
199
331
  and a project with no bundler uses [`navecss-core expand`](#navecss-core-expand).
@@ -218,8 +350,8 @@ It has no dependency and no peer. It expands `@nave` after Vite's own CSS step h
218
350
  through `@import`, a Sass file (including a `@mixin` that holds a directive), a CSS Module, an
219
351
  `?inline` or `?url` import, a Vue or Svelte style block and a `.css` inside `node_modules` are all
220
352
  read as the CSS they compile to, in `vite build` and in the dev server, under either
221
- `css.transformer`. A `?raw` import returns the file's text as it is. Astro is not covered: it was
222
- not measured at this release, and no fixture of it runs.
353
+ `css.transformer`. A `?raw` import returns the file's text as it is. Astro has its own setup and
354
+ its own measured list: [Astro](#astro).
223
355
 
224
356
  **It also chooses which atoms ship.** A `cx()` call in your code whose atoms the build cannot read,
225
357
  such as `cx(variant)` with a prop, is an error in the dev server and fails `vite build`.
@@ -242,10 +374,15 @@ Nave class it cannot see has no rule unless its atom is listed in `keep`.
242
374
 
243
375
  **Under `css.transformer: 'lightningcss'`** the plugin expands exactly as it does under the default
244
376
  transformer once both floor keys below are set. At Vite's default targets, which sit below the
245
- floor, Lightning CSS lowers CSS nesting before any plugin runs, and two things change.
377
+ floor, Lightning CSS lowers CSS nesting before any plugin runs, and three things change.
246
378
  A directive written after a declaration that follows a nested rule can be moved ahead of that
247
379
  declaration: in `.a { &:hover { color: red; } display: grid; @nave block; }`, `grid` wins with no
248
- message, where the default transformer makes `block` win. A directive in a group rule nested in a
380
+ message, where the default transformer makes `block` win.
381
+ What a rule says after a directive becomes a rule of its own, after the directive's, so it
382
+ already resolves in the order [Order inside a rule](#order-inside-a-rule) describes, but no order
383
+ warning is printed for it: a later `&:focus { outline: none }` after `focusRing`, for one, removes
384
+ the ring there with no message.
385
+ A directive in a group rule nested in a
249
386
  style rule (`.a { @media (...) { @nave flex; } }`) still fails the build, but the message no longer
250
387
  names the `& { @nave ...; }` workaround, and its position is in the CSS as Lightning CSS rewrote
251
388
  it, not in your file. The plugin also drops one message and only that one: Lightning CSS's
@@ -310,8 +447,9 @@ newest 8.x at the time of each release.
310
447
  The Vite plugin also chooses which of Nave's atoms reach your stylesheet. It reads the `cx()` calls
311
448
  in the code the build compiles, dependencies included, and ships the rules for the atoms those calls
312
449
  name, for the atom of each Nave class written as text (`nave-grid` in `index.html` or in a string in
313
- your code, say), and for the atoms you list in `keep` and `keepFor`; `srOnlyFocusable` also ships
314
- whenever `srOnly` does. The dev server serves the same atoms, from the code it has read. This is
450
+ your code, say) and each Nave class a CSS Module composes from global (`composes: nave-flex from global`),
451
+ and for the atoms you list in `keep` and `keepFor`; `srOnlyFocusable` also ships whenever `srOnly`
452
+ does. The dev server serves the same atoms, from the code it has read. This is
315
453
  what `navePlugin()` does with no options. On the CSS-first path, where `@nave` copies an atom's
316
454
  declarations into your own rule, a project that never calls `cx()` and writes no Nave class ships no
317
455
  rule from the atom layer.
@@ -562,6 +700,82 @@ their own code, and `keepFor` does not reach it.
562
700
 
563
701
  List every atom your components can apply at run time, `focusRing`, `srOnly`, `srOnlyFocusable`, `hidden` and the `hide*` atoms included where you use them: a consumer passes them to `keepFor` under your package's name, and one left out renders as if the class were absent in their production build.
564
702
 
703
+ #### Astro
704
+
705
+ Astro builds with Vite, so the Vite plugin is the route there too. Add it under `vite` in your
706
+ Astro config, which is where Astro takes Vite plugins, and put the floor key under `vite` as well:
707
+ Astro's own `build` has no `cssTarget`, and drops one written there without an error.
708
+
709
+ ```js
710
+ // astro.config.mjs
711
+ import { defineConfig } from 'astro/config'
712
+ import { navePlugin } from '@navecss/core/vite'
713
+
714
+ export default defineConfig({
715
+ vite: {
716
+ plugins: [navePlugin()],
717
+ build: { cssTarget: ['chrome125', 'edge125', 'firefox128', 'safari18', 'ios18'] },
718
+ },
719
+ })
720
+ ```
721
+
722
+ The build chooses which atoms ship, so run your checks, keyboard, screen-reader and automated
723
+ accessibility checks included, against a production build as well as in dev: `astro build`, then
724
+ `astro preview` or however you serve production.
725
+
726
+ Put Nave's order statement first in the `<head>` of every layout, as an inline style, ahead of
727
+ anything that can bring a style, `<ClientRouter />` included:
728
+
729
+ ```astro
730
+ ---
731
+ // src/layouts/Layout.astro
732
+ import '../styles/app.css'
733
+ ---
734
+ <html lang="en">
735
+ <head>
736
+ <style is:inline>@layer tokens.defaults, tokens.presets, reset, atomic, components.nave, components.consumer, overrides;</style>
737
+ <meta charset="utf-8" />
738
+ <!-- the rest of your head, <ClientRouter /> included -->
739
+ </head>
740
+ <body><slot /></body>
741
+ </html>
742
+ ```
743
+
744
+ Astro can place a page's or a component's own style ahead of your layout's stylesheet, and with
745
+ `<ClientRouter />` it does so whatever the page imports first. A `@layer` in that style then fixes
746
+ its layer's place before Nave's order statement does, and the order inverts with no error. Astro
747
+ leaves an `is:inline` style where you write it, so this one is the first `@layer` the page sees.
748
+ `astro dev` does not show the inversion a build makes, so check the order in a build. The statement
749
+ is the one `@navecss/core/layers` holds, and the two must stay identical. Write the rules of a
750
+ `<style>` block inside `@layer components.consumer`, as for any CSS of yours: Astro leaves them
751
+ outside every layer otherwise, where they beat all of them.
752
+
753
+ The build chooses atoms as [Which atoms the build ships](#which-atoms-the-build-ships) says, with
754
+ three things particular to Astro. Astro writes its CSS in its server build, before the browser's
755
+ build runs, so an atom named only by code the browser runs, such as a `client:only` component or a
756
+ `<script>` in an `.astro` file, fails the build: list it in `keep`. A dependency the server build
757
+ leaves external is read just as late: add it to `resolve.noExternal` under `vite`, which reaches
758
+ every environment Astro builds, where `ssr.noExternal` does not. And in `output: 'server'` with
759
+ prerendered pages, the stylesheet the on-demand pages share ships every atom.
760
+
761
+ Both end-of-build checks, the `@nave` scan and the check that the atom layer holds exactly the atoms
762
+ the build chose, also read the stylesheets Astro writes into the page instead of as files (those
763
+ under 4 kB, by default). The file a message names for one of those is the name the stylesheet had
764
+ before Astro inlined it, so no file of that name is in `dist`. In an `.astro` file, the line of a
765
+ `@nave` error counts from the start of the `<style>` block that holds it, not from the top of the
766
+ file, and its column can differ from your file's, because Astro rewrites the block's whitespace.
767
+
768
+ In `astro dev`, the first paint holds the stylesheet as Vite's own CSS step left it, every atom and
769
+ every `@nave` unexpanded, until the page's scripts load; after that the dev server serves what the
770
+ build would, as far as it has read. The build is unaffected. As on any Vite project, run your
771
+ checks, keyboard, screen-reader and automated accessibility checks included, against a production
772
+ build as well as in dev: `astro build`, then `astro preview` or however you serve production.
773
+
774
+ A fixture measures this on Astro 7.4.0, with Vite 8.3.5 underneath: `@nave` expanded in `.css`
775
+ files and in `<style>` and `<style is:global>` blocks, and `cx()` read in frontmatter, in templates
776
+ and in React islands, in `astro build` for a static site and for `output: 'server'`, and in
777
+ `astro dev`. Islands in Vue, Svelte or Solid were not measured.
778
+
565
779
  ### PostCSS plugin setup
566
780
 
567
781
  For Next.js, webpack under `postcss-loader`, and any other pipeline that runs PostCSS plugins.
@@ -618,6 +832,11 @@ Without it, Turbopack compiles for older browsers and rewrites every `light-dark
618
832
  Nave's colours included, into `--lightningcss-light` and `--lightningcss-dark` variables. Spell
619
833
  the floor out as above: Next 15 rejects the shorter `baseline 2024` with `Unknown browser baseline`.
620
834
 
835
+ **Where Nave's warnings show.** With webpack (`next build --webpack`), `next build` prints them under `Compiled with warnings`, once for each compilation that reads the stylesheet, so a CSS Module imported from a Server Component can show the same warning twice; `next dev --webpack` may not print a global stylesheet's, so read them from `next build`. Turbopack does not print PostCSS warnings, so under Turbopack the plugin prints them itself on standard error, with the file, line and column, in `next build` and `next dev` alike. Neither bundler shows them in the browser console or Next's error overlay.
836
+ A problem that [`onUnknown`](#options) covers is a warning only under `'warn'`; under the
837
+ default, `'error'`, it fails the build on either bundler. Where the warnings show was measured
838
+ on Next 16.4.1, not on Next 15.
839
+
621
840
  **If your Vite config sets `css.transformer: 'lightningcss'`, this plugin never
622
841
  runs.** That option replaces Vite's CSS pipeline with Lightning CSS, which does
623
842
  not run PostCSS plugins at all: the build stays green, `@nave` reaches the
@@ -667,7 +886,8 @@ Nave's own messages, with the file's path and the line and column of each proble
667
886
  and the map as a string, ready for `transform()`'s `code` and `inputSourceMap`. `resolver.read` reads each file
668
887
  `bundleAsync()` asks for and returns its expanded text, so a file reached through `@import` is
669
888
  covered too. It takes `extend` (an object of your own atoms) and `onUnknown` as the other plugins
670
- do ([Options](#options)); under `'warn'` it prints each problem with `console.warn`.
889
+ do ([Options](#options)); under `'warn'` it prints each problem with `console.warn`, and prints
890
+ the [order warning](#order-inside-a-rule) the same way under every `onUnknown`.
671
891
 
672
892
  The adapter imports nothing from `lightningcss`, types included, and declares no peer: you bring
673
893
  your own copy. The supported range is documented, not declared: `lightningcss` 1.24.1 and later.
@@ -696,6 +916,21 @@ in one error, positioned at the first: its message, then
696
916
  others. The report covers one stylesheet, so a bundler that stops at the first
697
917
  failing file reports one file per build. Under `'warn'`, each problem is a
698
918
  warning of its own.
919
+ The [order warning](#order-inside-a-rule) is not one of these problems: it is printed as a
920
+ warning whatever `onUnknown` says. On Turbopack, Next 16's default bundler, which shows no
921
+ PostCSS warning, the PostCSS plugin prints each problem under `'warn'` and each order warning
922
+ to the terminal instead, as `file:line:column:` and the message
923
+ ([where Next.js shows them](#nextjs)). It knows Turbopack by the `TURBOPACK` environment
924
+ variable, which Next.js sets for it, so wherever that variable is set and not empty, under Vite
925
+ or the PostCSS CLI as well, it does the same and raises no PostCSS warning. The Vite plugin and
926
+ the Lightning CSS adapter do not read the variable. The PostCSS plugin also takes
927
+ `printWarnings` (default `true`): with `printWarnings: false` it raises each problem under
928
+ `'warn'` and each order warning as a PostCSS warning and prints none of them, whatever
929
+ `TURBOPACK` holds, for a tool that runs the plugin itself and reports the warnings it raises.
930
+ Such a tool can import `isOrderWarning(warning)` from `@navecss/core/postcss` to tell them
931
+ apart: it is `true` for an order warning and `false` for each of these problems, so the tool
932
+ can report an order warning as the plugin does, whatever `onUnknown` says, and never fail a
933
+ build on one.
699
934
 
700
935
  To add atoms of your own to `@nave`, pass them as `extend`: see
701
936
  [CONSUMER-ATOMS.md](./CONSUMER-ATOMS.md). An `extend` object written inline in
@@ -795,6 +1030,9 @@ across every file is printed in one run, one report per stylesheet. Exit codes:
795
1030
  `--watch`, a directory that could not be watched. Nothing is written, except that files written
796
1031
  before an `--out` that failed stay written.
797
1032
 
1033
+ An order warning is printed and is not a problem here: it changes neither the exit code nor what is
1034
+ written.
1035
+
798
1036
  It does not resolve or inline `@import`; that would make it a CSS bundler. It
799
1037
  expands only the files you name with `--source`, so a stylesheet you import that
800
1038
  holds `@nave` needs a pair of its own. An `@import` of a relative or absolute URL
@@ -881,18 +1119,18 @@ Consumers of `@navecss/tokens` alone get no guide: it ships only in this package
881
1119
 
882
1120
  ## Exports
883
1121
 
884
- | Export | Description |
885
- | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
886
- | `@navecss/core` | CSS entry point — `@import url('@navecss/core')` |
887
- | `@navecss/core/layers` | The `@layer` order statement alone. Import it first, before any other stylesheet |
888
- | `@navecss/core/no-tokens` | Entry point for projects that generate their own Nave token layer; see the header comment in the file |
889
- | `@navecss/core/reset` | Reset stylesheet only. It reads Nave's custom properties, so it needs a token layer beside it |
890
- | `@navecss/core/atomic` | Generated atomic CSS (global `nave-` classes) |
891
- | `@navecss/core/cx` | `cx()` / `cx.raw()` utilities + `AtomName` type |
892
- | `@navecss/core/atoms` | Atom definitions + `atomClassMap` |
893
- | `@navecss/core/vite` | Vite plugin — `navePlugin()` |
894
- | `@navecss/core/lightningcss` | Lightning CSS adapter — `navePlugin()`, returning `expand` and `resolver` |
895
- | `@navecss/core/standalone` | The whole stylesheet in one file, with no `@import`, for projects with no bundler |
896
- | `@navecss/core/postcss` | PostCSS plugin — `navePlugin()` |
897
- | `@navecss/core/check` | The survival check as a function — `check({ source })` |
898
- | `@navecss/core/collect` | Reads which atoms a module uses, for build tools; not meant for application code |
1122
+ | Export | Description |
1123
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------- |
1124
+ | `@navecss/core` | CSS entry point — `@import url('@navecss/core')` |
1125
+ | `@navecss/core/layers` | The `@layer` order statement alone. Import it first, before any other stylesheet |
1126
+ | `@navecss/core/no-tokens` | Entry point for projects that generate their own Nave token layer; see the header comment in the file |
1127
+ | `@navecss/core/reset` | Reset stylesheet only. It reads Nave's custom properties, so it needs a token layer beside it |
1128
+ | `@navecss/core/atomic` | Generated atomic CSS (global `nave-` classes) |
1129
+ | `@navecss/core/cx` | `cx()` / `cx.raw()` utilities + `AtomName` type |
1130
+ | `@navecss/core/atoms` | Atom definitions + `atomClassMap` |
1131
+ | `@navecss/core/vite` | Vite plugin — `navePlugin()` |
1132
+ | `@navecss/core/lightningcss` | Lightning CSS adapter — `navePlugin()`, returning `expand` and `resolver` |
1133
+ | `@navecss/core/standalone` | The whole stylesheet in one file, with no `@import`, for projects with no bundler |
1134
+ | `@navecss/core/postcss` | PostCSS plugin — `navePlugin()` |
1135
+ | `@navecss/core/check` | The survival check as a function — `check({ source })` |
1136
+ | `@navecss/core/collect` | Reads which atoms a module uses and trims the atom layer to them, for build tools; not meant for application code |
@@ -24,4 +24,5 @@ declare const toClassName: (name: AtomName) => string;
24
24
  */
25
25
  declare const atomClassMap: Record<AtomName, string>;
26
26
 
27
- export { type AtomName as A, atomClassMap as a, toClassName as t };
27
+ export { atomClassMap as a, toClassName as t };
28
+ export type { AtomName as A };
package/dist/atoms.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AtomName, a as atomClassMap, t as toClassName } from './atom-names-2OreuBx9.js';
1
+ export { A as AtomName, a as atomClassMap, t as toClassName } from './atom-names-B8Ud-7zD.js';
2
2
 
3
3
  type CSSDeclarations = Record<string, string>;
4
4
  type PseudoMap = Record<string, CSSDeclarations>;
@@ -406,4 +406,5 @@ declare const atoms: {
406
406
  };
407
407
  };
408
408
 
409
- export { type AtomDefinition, atoms };
409
+ export { atoms };
410
+ export type { AtomDefinition };