@navecss/tokens 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +55 -0
- package/README.md +122 -0
- package/TOKENS.md +180 -0
- package/dist/breakpoints.d.ts +25 -0
- package/dist/breakpoints.js +44 -0
- package/dist/build-record.json +77 -0
- package/dist/core-contract.json +30 -0
- package/dist/lib/bin.d.ts +2 -0
- package/dist/lib/bin.js +113 -0
- package/dist/lib/builder.d.ts +21 -0
- package/dist/lib/builder.js +41 -0
- package/dist/lib/collision.d.ts +12 -0
- package/dist/lib/collision.js +46 -0
- package/dist/lib/composite-value.d.ts +3 -0
- package/dist/lib/composite-value.js +152 -0
- package/dist/lib/core-version.d.ts +12 -0
- package/dist/lib/core-version.js +40 -0
- package/dist/lib/dtcg-descriptions.d.ts +2 -0
- package/dist/lib/dtcg-descriptions.js +23 -0
- package/dist/lib/dtcg-malformed.d.ts +10 -0
- package/dist/lib/dtcg-malformed.js +56 -0
- package/dist/lib/dtcg-outputs.d.ts +2 -0
- package/dist/lib/dtcg-outputs.js +32 -0
- package/dist/lib/dtcg-shape.d.ts +13 -0
- package/dist/lib/dtcg-shape.js +113 -0
- package/dist/lib/errors.d.ts +23 -0
- package/dist/lib/errors.js +34 -0
- package/dist/lib/facade.d.ts +26 -0
- package/dist/lib/facade.js +97 -0
- package/dist/lib/formats.d.ts +6 -0
- package/dist/lib/formats.js +236 -0
- package/dist/lib/json-pointer.d.ts +2 -0
- package/dist/lib/json-pointer.js +28 -0
- package/dist/lib/overrides.d.ts +2 -0
- package/dist/lib/overrides.js +59 -0
- package/dist/lib/package-root.d.ts +2 -0
- package/dist/lib/package-root.js +31 -0
- package/dist/lib/reader.d.ts +8 -0
- package/dist/lib/reader.js +136 -0
- package/dist/lib/theming/adjacency-source.d.ts +20 -0
- package/dist/lib/theming/adjacency-source.js +103 -0
- package/dist/lib/theming/adjacency.d.ts +17 -0
- package/dist/lib/theming/adjacency.js +133 -0
- package/dist/lib/theming/build-record.d.ts +45 -0
- package/dist/lib/theming/build-record.js +87 -0
- package/dist/lib/theming/build-step.d.ts +14 -0
- package/dist/lib/theming/build-step.js +91 -0
- package/dist/lib/theming/color-math.d.ts +33 -0
- package/dist/lib/theming/color-math.js +125 -0
- package/dist/lib/theming/comment-open-tracker.d.ts +1 -0
- package/dist/lib/theming/comment-open-tracker.js +49 -0
- package/dist/lib/theming/consumer-build.d.ts +18 -0
- package/dist/lib/theming/consumer-build.js +29 -0
- package/dist/lib/theming/contact-sheet.d.ts +22 -0
- package/dist/lib/theming/contact-sheet.js +123 -0
- package/dist/lib/theming/contrast.d.ts +31 -0
- package/dist/lib/theming/contrast.js +133 -0
- package/dist/lib/theming/copy-lint.d.ts +13 -0
- package/dist/lib/theming/copy-lint.js +98 -0
- package/dist/lib/theming/core-contract.d.ts +29 -0
- package/dist/lib/theming/core-contract.js +71 -0
- package/dist/lib/theming/core-source.d.ts +2 -0
- package/dist/lib/theming/core-source.js +18 -0
- package/dist/lib/theming/css-color-4.d.ts +19 -0
- package/dist/lib/theming/css-color-4.js +66 -0
- package/dist/lib/theming/css-named-colours.d.ts +1 -0
- package/dist/lib/theming/css-named-colours.js +151 -0
- package/dist/lib/theming/descriptions.d.ts +1 -0
- package/dist/lib/theming/descriptions.js +21 -0
- package/dist/lib/theming/emit.d.ts +10 -0
- package/dist/lib/theming/emit.js +62 -0
- package/dist/lib/theming/feedback-signal.d.ts +11 -0
- package/dist/lib/theming/feedback-signal.js +23 -0
- package/dist/lib/theming/guard-message-probes.d.ts +6 -0
- package/dist/lib/theming/guard-message-probes.js +96 -0
- package/dist/lib/theming/ladder.d.ts +15 -0
- package/dist/lib/theming/ladder.js +81 -0
- package/dist/lib/theming/neutral.d.ts +12 -0
- package/dist/lib/theming/neutral.js +76 -0
- package/dist/lib/theming/on-star.d.ts +11 -0
- package/dist/lib/theming/on-star.js +87 -0
- package/dist/lib/theming/palette-record.d.ts +2 -0
- package/dist/lib/theming/palette-record.js +15 -0
- package/dist/lib/theming/pipeline.d.ts +43 -0
- package/dist/lib/theming/pipeline.js +104 -0
- package/dist/lib/theming/ramp.d.ts +34 -0
- package/dist/lib/theming/ramp.js +92 -0
- package/dist/lib/theming/seed-channel-split.d.ts +8 -0
- package/dist/lib/theming/seed-channel-split.js +99 -0
- package/dist/lib/theming/seed-form-parsers-css-color-4.d.ts +8 -0
- package/dist/lib/theming/seed-form-parsers-css-color-4.js +85 -0
- package/dist/lib/theming/seed-form-parsers.d.ts +6 -0
- package/dist/lib/theming/seed-form-parsers.js +155 -0
- package/dist/lib/theming/seed-ingest.d.ts +15 -0
- package/dist/lib/theming/seed-ingest.js +112 -0
- package/dist/lib/theming/seed-input.d.ts +22 -0
- package/dist/lib/theming/seed-input.js +1 -0
- package/dist/lib/theming/seed-refusal.d.ts +21 -0
- package/dist/lib/theming/seed-refusal.js +77 -0
- package/dist/lib/theming/semantics.d.ts +19 -0
- package/dist/lib/theming/semantics.js +71 -0
- package/dist/lib/theming/shipped-seeds.d.ts +2 -0
- package/dist/lib/theming/shipped-seeds.js +5 -0
- package/dist/lib/theming/step-table.d.ts +5 -0
- package/dist/lib/theming/step-table.js +26 -0
- package/dist/lib/theming/third-party-provenance.d.ts +9 -0
- package/dist/lib/theming/third-party-provenance.js +35 -0
- package/dist/lib/theming/tokens-source.d.ts +3 -0
- package/dist/lib/theming/tokens-source.js +61 -0
- package/dist/lib/token-name.d.ts +2 -0
- package/dist/lib/token-name.js +28 -0
- package/dist/lib/validate-report.d.ts +19 -0
- package/dist/lib/validate-report.js +93 -0
- package/dist/lib/validate.d.ts +16 -0
- package/dist/lib/validate.js +65 -0
- package/dist/palette-record.json +293 -0
- package/dist/tokens.css +433 -0
- package/dist/tokens.d.ts +90 -0
- package/dist/tokens.js +88 -0
- package/package.json +85 -0
- package/tokens.json +938 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nave Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
THIRD-PARTY MATERIAL
|
|
24
|
+
|
|
25
|
+
This package includes material copied from or derived from the CSS Color Module
|
|
26
|
+
Level 4 specification and its published sample code (css-color-4/conversions.js
|
|
27
|
+
in the w3c/csswg-drafts repository, at commit
|
|
28
|
+
af8661bfe903aac7dbb9c5d1e1eccb725b8c331d, and
|
|
29
|
+
https://drafts.csswg.org/css-color-4/#color-conversion-code). Copyright (c) 2026
|
|
30
|
+
World Wide Web Consortium. That specification, and the repository carrying its
|
|
31
|
+
sample code, are published under the W3C Software and Document License
|
|
32
|
+
(https://www.w3.org/copyright/software-license-2023/).
|
|
33
|
+
|
|
34
|
+
What is copied is the numeric constants used by src/theming/css-color-4.ts,
|
|
35
|
+
published as dist/lib/theming/css-color-4.js, and the order of the conversion
|
|
36
|
+
steps: the D50 white point, the CIE Lab kappa and epsilon, the Bradford D50 to
|
|
37
|
+
D65 adaptation matrix, the linear display-p3 to XYZ matrix, and the two XYZ to
|
|
38
|
+
OKLab matrices. The names, the types and the function bodies around them are
|
|
39
|
+
this package's own, and everything in this package is offered under the MIT
|
|
40
|
+
licence above.
|
|
41
|
+
|
|
42
|
+
Also copied from that specification are the names of its colour keywords, held
|
|
43
|
+
in src/theming/css-named-colours.ts and published as
|
|
44
|
+
dist/lib/theming/css-named-colours.js. What is copied there is the keyword names
|
|
45
|
+
alone, in alphabetical order, with none of the colour values the specification
|
|
46
|
+
gives for them.
|
|
47
|
+
|
|
48
|
+
This package implements the Design Tokens Format Module 2025.10 and the Design
|
|
49
|
+
Tokens Color Module 2025.10, Final Community Group Reports published 28 October
|
|
50
|
+
2025 by the Design Tokens Community Group under the W3C Community Final
|
|
51
|
+
Specification Agreement. Those documents are not W3C Standards. What this
|
|
52
|
+
package takes from them is the format's property names, type names and value
|
|
53
|
+
structures, and the Color Module's colour-space identifiers; the reader, its
|
|
54
|
+
diagnostics and everything around them are this package's own, and everything in
|
|
55
|
+
this package is offered under the MIT licence above.
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# @navecss/tokens
|
|
2
|
+
|
|
3
|
+
> DTCG 2025.10 design tokens for Nave, built by a first-party DTCG 2025.10 reader.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @navecss/tokens
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- **Browsers: Chrome and Edge 125, Firefox 128, Safari 18 (Baseline 2024).** Every semantic colour in the stylesheet is a `light-dark()` pair, and most of them are also derived with relative colour syntax. An older browser drops whichever of them it does not support, without an error: surfaces and text lose their colours. Your CSS build has to target the same floor, or it rewrites `light-dark()` into an emulation that a `color-scheme` set from script, or on part of the page, does not switch. [Why this floor, and how to set your build's target](https://github.com/navecss/navecss/blob/main/docs/04-adr/0005-browser-floor.md).
|
|
14
|
+
- **A resolver that reads `exports` maps.** Every entry point, `@navecss/tokens/css` included, is reachable only through the package's `exports` map: there is no `main` field to fall back on.
|
|
15
|
+
- **ES modules, with no CommonJS build.** The JavaScript entry points load through `import`, and also through `require()`, which Node 22.18 supports for ES modules. In TypeScript, set `moduleResolution` to `bundler`, `node16` or `nodenext`; under `node10` the types are not found.
|
|
16
|
+
- **Node 22.18 or later.**
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
```css
|
|
21
|
+
/* app.css */
|
|
22
|
+
@import url('@navecss/tokens/css');
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This emits the token layer's custom properties (`--nave-*`) inside `@layer tokens.defaults`. Keep the `/css`: unlike `@navecss/core`, whose bare package name is its stylesheet, the bare `@navecss/tokens` is the JavaScript entry point. `@navecss/core` imports this automatically; install `@navecss/tokens` on its own only if you are building without `@navecss/core` (for example, on top of Base UI or Radix UI directly).
|
|
26
|
+
|
|
27
|
+
## What ships
|
|
28
|
+
|
|
29
|
+
- **Colour** — the semantic colours consumers use (`action`, `content`, `surface`, `border`, `feedback`, and foregrounds for the primary action and the feedback roles), each with a light and a dark value through `light-dark()`. The `neutral`, `primary` and `danger` scales they are derived from stay inside the build: no step of them is emitted as a custom property. The neutral colours re-hue live from one custom property, under Theming below.
|
|
30
|
+
- **Typography, spacing, size, shape, shadow, motion, z-index, opacity** — the rest of the token taxonomy, authored once in `tokens.json` and compiled by the first-party DTCG 2025.10 reader.
|
|
31
|
+
- **Breakpoints** — a JS-only export (`@navecss/tokens/breakpoints`): custom properties cannot hold media-query ranges, so these ship as typed constants and prebuilt Level 4 media-query strings instead.
|
|
32
|
+
|
|
33
|
+
Every custom property the stylesheet declares is listed in [TOKENS.md](./TOKENS.md).
|
|
34
|
+
|
|
35
|
+
## The format this reads
|
|
36
|
+
|
|
37
|
+
`tokens.json` is written to the Design Tokens Format Module 2025.10, a Final Community Group Report published on 28 October 2025. It is a community specification rather than a standards-track one, and this package implements it without claiming conformance, certification or endorsement.
|
|
38
|
+
|
|
39
|
+
**The reader reads that one revision.** The format had a pre-stable draft for years, which wrote a dimension as `"16px"`, a font weight as `"400"` and a shadow layer's offsets as CSS strings, and that is still what most token tooling exports. A file in the draft shape is refused rather than guessed at: the refusal names every node in one run, says what the file is, and gives the edit each node needs for its own type. There is no second accepted shape, because a value that could be read either way is a value that can be read wrongly in silence.
|
|
40
|
+
|
|
41
|
+
**One stated deviation, and it is in the source too.** 90 of this package's 93 tokens conform to that revision. `letterSpacing.tight`, `.normal` and `.wide` carry the unit `em`, which the format's `dimension` unit set (`px` and `rem`) does not include. `em` is lawful CSS and is the right unit for tracking, since it resolves against the element's own font size; converting the three would change what renders, so the deviation is stated rather than the value changed. The cost is real: a strict third-party reader will reject those three.
|
|
42
|
+
|
|
43
|
+
## Exports
|
|
44
|
+
|
|
45
|
+
| Export | Description |
|
|
46
|
+
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
47
|
+
| `@navecss/tokens` | JS entry point — the typed constants described under `@navecss/tokens/js` below. Not a CSS entry: `@import url('@navecss/tokens/css')` is the stylesheet |
|
|
48
|
+
| `@navecss/tokens/css` | The generated stylesheet — `@import url('@navecss/tokens/css')` |
|
|
49
|
+
| `@navecss/tokens/js` | Typed ESM token constants — the DTCG 2025.10 token set; every `--nave-color-*` custom property ships in the stylesheet above and not through this export, the `--nave-color-tint` seed included |
|
|
50
|
+
| `@navecss/tokens/breakpoints` | Breakpoint values, em conversions, media strings |
|
|
51
|
+
| `@navecss/tokens/core-contract` | The shipped core-contract manifest, as JSON, for a token layer you generate yourself and load through `@navecss/core/no-tokens`: the `--nave-*` custom-property names `@navecss/core` reads, generated from that package's own source rather than listed by hand, and not the colour namespace alone. Import it with `with { type: 'json' }`. A clean check against it means those names are present rather than that your token set is complete; for what else it does and does not establish, read the header comment in `@navecss/core/no-tokens`. A validator reading the manifest directly should refuse a `formatVersion` higher than it understands, rather than mis-reading it. |
|
|
52
|
+
| `@navecss/tokens/build` | The token build as a JavaScript API: `build` and `validate`, the two operations the `navecss-tokens` binary wraps |
|
|
53
|
+
| `@navecss/tokens/tokens.json` | The DTCG 2025.10 token source this package ships, the one `build` reads when given no `--source` — a starting point for writing your own (`--source`, below) |
|
|
54
|
+
|
|
55
|
+
## Theming
|
|
56
|
+
|
|
57
|
+
Re-hue the neutral colours with one custom property, no build step required:
|
|
58
|
+
|
|
59
|
+
```css
|
|
60
|
+
@layer overrides {
|
|
61
|
+
:root {
|
|
62
|
+
--nave-color-tint: oklch(0.6 0.2 250);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Changing this changes everything Nave derives from it. The contrast of the resulting palette follows from what you set, and checking it is yours.
|
|
68
|
+
|
|
69
|
+
The neutral surface re-hues live, and so does the text set on the primary action and on danger (`--nave-color-on-action-primary` and `--nave-color-on-feedback-danger`), which is neutral too. The accent does not move: the primary action, links, the focus ring and the danger colours stay exactly as shipped. [TOKENS.md](./TOKENS.md) marks every colour that follows the tint. Moving the accent is a re-seed, which runs through the build below.
|
|
70
|
+
|
|
71
|
+
Re-seeding, per-step overrides and bringing your own token source all run through the build below.
|
|
72
|
+
|
|
73
|
+
## Building your own tokens
|
|
74
|
+
|
|
75
|
+
This package ships a build you run yourself. Give it a seed colour and it
|
|
76
|
+
regenerates the whole token layer from that colour, into a directory you commit.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"scripts": {
|
|
81
|
+
"tokens": "navecss-tokens build --seed=#2f6feb --out=src/styles/nave"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Changing this changes everything Nave derives from it. The contrast of the resulting palette follows from what you set, and checking it is yours.
|
|
87
|
+
|
|
88
|
+
Two subcommands, four flags, and no configuration file: the build discovers no
|
|
89
|
+
configuration — it searches no directory and reads no config file.
|
|
90
|
+
|
|
91
|
+
| flag | subcommand | what it takes |
|
|
92
|
+
| ------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
93
|
+
| `--seed` | `build` | **Required.** The colour everything is derived from, as `#rrggbb`, `rgb()`, `hsl()`, `oklch()`, `lab()`, `lch()` or `color()` (`srgb` or `display-p3`) |
|
|
94
|
+
| `--out` | `build` | **Required.** The directory the generated files are written to |
|
|
95
|
+
| `--source` | `build`, `validate` | A DTCG 2025.10 `.json` token source. `build` defaults to the one this package ships; `validate` requires it, and also accepts a stylesheet you already built |
|
|
96
|
+
| `--overrides` | `build` | A JSON file pinning individual ramp steps, keyed by scale (`primary`, `danger` or `neutral`) then step number, to a chroma: `{ "primary": { "500": 0.11 } }` |
|
|
97
|
+
|
|
98
|
+
Write `--flag=value` and not `--flag value`. A `#rrggbb` seed passed as a
|
|
99
|
+
separate word begins a shell comment, so the rest of the command is discarded
|
|
100
|
+
and you get a usage error rather than a wrong colour.
|
|
101
|
+
|
|
102
|
+
0.1.0 ships no consumer contrast-threshold input. No flag of this entry point sets one, and the build reads none. This is the absence of an input, not a limit on the consumer: a consumer may hold whatever contrast target they choose and check their palette against it with their own tooling. Where a check Nave ships runs in a consumer's build over the consumer's values, it reports and does not fail. A consumer-settable target is deliberately out of 0.1.0 rather than overlooked.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
navecss-tokens validate --source=src/styles/nave/tokens.css
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`validate` checks a token source, or a stylesheet you built yourself, against
|
|
109
|
+
the core contract: the `--nave-*` custom-property names `@navecss/core` reads,
|
|
110
|
+
not the colour ones alone. It reports the names in that contract your source
|
|
111
|
+
does not declare, and it checks nothing else, so a clean run means those names
|
|
112
|
+
are present rather than that your token set is complete.
|
|
113
|
+
|
|
114
|
+
Both operations are also a JavaScript API, exported as `@navecss/tokens/build`,
|
|
115
|
+
for a build system that would rather call a function than spawn a process.
|
|
116
|
+
|
|
117
|
+
The exit code is `0` when the run succeeded and `1` when the work failed on its
|
|
118
|
+
merits. `2` is not a verdict on your tokens at all: a run that exits `2`
|
|
119
|
+
reports none, so read `2` as no answer rather than as a bad one. `1` is also
|
|
120
|
+
where a failure the tool has no more specific code for ends up, so a `1` always
|
|
121
|
+
means the run failed and does not always mean your tokens did. Either way the
|
|
122
|
+
message says what happened, and the code is what a script branches on.
|
package/TOKENS.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# TOKENS.md
|
|
2
|
+
|
|
3
|
+
Generated from the token build; do not edit by hand.
|
|
4
|
+
|
|
5
|
+
Every custom property `@navecss/tokens` declares, grouped, with colour's own follows-tint
|
|
6
|
+
column: whether re-hueing `--nave-color-tint` moves that property. Values are not shown —
|
|
7
|
+
a colour's value is a `light-dark()` expression that informs nobody on its own, and a
|
|
8
|
+
non-colour value is exactly what its name says.
|
|
9
|
+
|
|
10
|
+
## Font
|
|
11
|
+
|
|
12
|
+
| Custom property |
|
|
13
|
+
| ----------------------------- |
|
|
14
|
+
| `--nave-font-family-base` |
|
|
15
|
+
| `--nave-font-family-display` |
|
|
16
|
+
| `--nave-font-family-mono` |
|
|
17
|
+
| `--nave-font-size-xs` |
|
|
18
|
+
| `--nave-font-size-sm` |
|
|
19
|
+
| `--nave-font-size-md` |
|
|
20
|
+
| `--nave-font-size-lg` |
|
|
21
|
+
| `--nave-font-size-xl` |
|
|
22
|
+
| `--nave-font-size-2xl` |
|
|
23
|
+
| `--nave-font-size-3xl` |
|
|
24
|
+
| `--nave-font-size-4xl` |
|
|
25
|
+
| `--nave-font-weight-regular` |
|
|
26
|
+
| `--nave-font-weight-medium` |
|
|
27
|
+
| `--nave-font-weight-semibold` |
|
|
28
|
+
| `--nave-font-weight-bold` |
|
|
29
|
+
|
|
30
|
+
## Line height
|
|
31
|
+
|
|
32
|
+
| Custom property |
|
|
33
|
+
| ---------------------------- |
|
|
34
|
+
| `--nave-line-height-none` |
|
|
35
|
+
| `--nave-line-height-tight` |
|
|
36
|
+
| `--nave-line-height-snug` |
|
|
37
|
+
| `--nave-line-height-base` |
|
|
38
|
+
| `--nave-line-height-relaxed` |
|
|
39
|
+
| `--nave-line-height-loose` |
|
|
40
|
+
|
|
41
|
+
## Letter spacing
|
|
42
|
+
|
|
43
|
+
| Custom property |
|
|
44
|
+
| ------------------------------ |
|
|
45
|
+
| `--nave-letter-spacing-tight` |
|
|
46
|
+
| `--nave-letter-spacing-normal` |
|
|
47
|
+
| `--nave-letter-spacing-wide` |
|
|
48
|
+
|
|
49
|
+
## Spacing
|
|
50
|
+
|
|
51
|
+
| Custom property |
|
|
52
|
+
| --------------------------- |
|
|
53
|
+
| `--nave-spacing-content-xs` |
|
|
54
|
+
| `--nave-spacing-content-sm` |
|
|
55
|
+
| `--nave-spacing-content-md` |
|
|
56
|
+
| `--nave-spacing-content-lg` |
|
|
57
|
+
| `--nave-spacing-content-xl` |
|
|
58
|
+
| `--nave-spacing-layout-xs` |
|
|
59
|
+
| `--nave-spacing-layout-sm` |
|
|
60
|
+
| `--nave-spacing-layout-md` |
|
|
61
|
+
| `--nave-spacing-layout-lg` |
|
|
62
|
+
| `--nave-spacing-control-xs` |
|
|
63
|
+
| `--nave-spacing-control-sm` |
|
|
64
|
+
| `--nave-spacing-control-md` |
|
|
65
|
+
| `--nave-spacing-control-lg` |
|
|
66
|
+
|
|
67
|
+
## Size
|
|
68
|
+
|
|
69
|
+
| Custom property |
|
|
70
|
+
| ------------------------ |
|
|
71
|
+
| `--nave-size-control-xs` |
|
|
72
|
+
| `--nave-size-control-sm` |
|
|
73
|
+
| `--nave-size-control-md` |
|
|
74
|
+
| `--nave-size-control-lg` |
|
|
75
|
+
| `--nave-size-icon-xs` |
|
|
76
|
+
| `--nave-size-icon-sm` |
|
|
77
|
+
| `--nave-size-icon-md` |
|
|
78
|
+
| `--nave-size-icon-lg` |
|
|
79
|
+
| `--nave-size-icon-xl` |
|
|
80
|
+
| `--nave-size-avatar-sm` |
|
|
81
|
+
| `--nave-size-avatar-md` |
|
|
82
|
+
| `--nave-size-avatar-lg` |
|
|
83
|
+
|
|
84
|
+
## Border width
|
|
85
|
+
|
|
86
|
+
| Custom property |
|
|
87
|
+
| --------------------------- |
|
|
88
|
+
| `--nave-border-width-none` |
|
|
89
|
+
| `--nave-border-width-sm` |
|
|
90
|
+
| `--nave-border-width-focus` |
|
|
91
|
+
| `--nave-border-width-lg` |
|
|
92
|
+
|
|
93
|
+
## Radius
|
|
94
|
+
|
|
95
|
+
| Custom property |
|
|
96
|
+
| ----------------------- |
|
|
97
|
+
| `--nave-radius-none` |
|
|
98
|
+
| `--nave-radius-sm` |
|
|
99
|
+
| `--nave-radius-control` |
|
|
100
|
+
| `--nave-radius-card` |
|
|
101
|
+
| `--nave-radius-overlay` |
|
|
102
|
+
| `--nave-radius-full` |
|
|
103
|
+
|
|
104
|
+
## Shadow
|
|
105
|
+
|
|
106
|
+
| Custom property |
|
|
107
|
+
| ----------------------- |
|
|
108
|
+
| `--nave-shadow-none` |
|
|
109
|
+
| `--nave-shadow-raised` |
|
|
110
|
+
| `--nave-shadow-overlay` |
|
|
111
|
+
| `--nave-shadow-modal` |
|
|
112
|
+
|
|
113
|
+
## Opacity
|
|
114
|
+
|
|
115
|
+
| Custom property |
|
|
116
|
+
| ------------------------- |
|
|
117
|
+
| `--nave-opacity-disabled` |
|
|
118
|
+
|
|
119
|
+
## Layer (z-index)
|
|
120
|
+
|
|
121
|
+
| Custom property |
|
|
122
|
+
| ----------------------- |
|
|
123
|
+
| `--nave-layer-base` |
|
|
124
|
+
| `--nave-layer-dropdown` |
|
|
125
|
+
| `--nave-layer-sticky` |
|
|
126
|
+
| `--nave-layer-overlay` |
|
|
127
|
+
| `--nave-layer-modal` |
|
|
128
|
+
| `--nave-layer-toast` |
|
|
129
|
+
| `--nave-layer-tooltip` |
|
|
130
|
+
|
|
131
|
+
## Motion
|
|
132
|
+
|
|
133
|
+
| Custom property |
|
|
134
|
+
| --------------------------------- |
|
|
135
|
+
| `--nave-motion-duration-instant` |
|
|
136
|
+
| `--nave-motion-duration-fast` |
|
|
137
|
+
| `--nave-motion-duration-base` |
|
|
138
|
+
| `--nave-motion-duration-slow` |
|
|
139
|
+
| `--nave-motion-easing-standard` |
|
|
140
|
+
| `--nave-motion-easing-decelerate` |
|
|
141
|
+
| `--nave-motion-easing-accelerate` |
|
|
142
|
+
|
|
143
|
+
## Colour
|
|
144
|
+
|
|
145
|
+
| Custom property | Follows `--nave-color-tint` |
|
|
146
|
+
| ------------------------------------------ | --------------------------- |
|
|
147
|
+
| `--nave-color-tint` | no |
|
|
148
|
+
| `--nave-color-surface-base` | yes |
|
|
149
|
+
| `--nave-color-surface-raised` | yes |
|
|
150
|
+
| `--nave-color-surface-overlay` | yes |
|
|
151
|
+
| `--nave-color-surface-sunken` | yes |
|
|
152
|
+
| `--nave-color-surface-inverse` | yes |
|
|
153
|
+
| `--nave-color-content-primary` | yes |
|
|
154
|
+
| `--nave-color-content-secondary` | yes |
|
|
155
|
+
| `--nave-color-content-tertiary` | yes |
|
|
156
|
+
| `--nave-color-content-disabled` | yes |
|
|
157
|
+
| `--nave-color-content-inverse` | yes |
|
|
158
|
+
| `--nave-color-content-link` | no |
|
|
159
|
+
| `--nave-color-border-default` | yes |
|
|
160
|
+
| `--nave-color-border-strong` | yes |
|
|
161
|
+
| `--nave-color-border-control` | yes |
|
|
162
|
+
| `--nave-color-border-disabled` | yes |
|
|
163
|
+
| `--nave-color-border-focus` | no |
|
|
164
|
+
| `--nave-color-action-primary` | no |
|
|
165
|
+
| `--nave-color-action-primary-hover` | no |
|
|
166
|
+
| `--nave-color-action-primary-active` | no |
|
|
167
|
+
| `--nave-color-on-action-primary` | yes |
|
|
168
|
+
| `--nave-color-action-secondary` | yes |
|
|
169
|
+
| `--nave-color-feedback-danger` | no |
|
|
170
|
+
| `--nave-color-feedback-danger-foreground` | no |
|
|
171
|
+
| `--nave-color-on-feedback-danger` | yes |
|
|
172
|
+
| `--nave-color-feedback-warning` | yes |
|
|
173
|
+
| `--nave-color-feedback-warning-foreground` | yes |
|
|
174
|
+
| `--nave-color-on-feedback-warning` | yes |
|
|
175
|
+
| `--nave-color-feedback-success` | yes |
|
|
176
|
+
| `--nave-color-feedback-success-foreground` | yes |
|
|
177
|
+
| `--nave-color-on-feedback-success` | yes |
|
|
178
|
+
| `--nave-color-feedback-info` | yes |
|
|
179
|
+
| `--nave-color-feedback-info-foreground` | yes |
|
|
180
|
+
| `--nave-color-on-feedback-info` | yes |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* Nave Design System — generated, do not edit */
|
|
2
|
+
|
|
3
|
+
export declare const breakpoints: {
|
|
4
|
+
readonly tabletPortrait: 600
|
|
5
|
+
readonly tabletLandscape: 900
|
|
6
|
+
readonly desktop: 1200
|
|
7
|
+
readonly wide: 1800
|
|
8
|
+
}
|
|
9
|
+
export declare type BreakpointName = keyof typeof breakpoints
|
|
10
|
+
|
|
11
|
+
export declare const em: {
|
|
12
|
+
readonly tabletPortrait: '37.5em'
|
|
13
|
+
readonly tabletLandscape: '56.25em'
|
|
14
|
+
readonly desktop: '75em'
|
|
15
|
+
readonly wide: '112.5em'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export declare const media: {
|
|
19
|
+
readonly phoneOnly: '(width < 37.5em)'
|
|
20
|
+
readonly tabletPortraitUp: '(width >= 37.5em)'
|
|
21
|
+
readonly tabletLandscapeUp: '(width >= 56.25em)'
|
|
22
|
+
readonly desktopUp: '(width >= 75em)'
|
|
23
|
+
readonly wideUp: '(width >= 112.5em)'
|
|
24
|
+
}
|
|
25
|
+
export declare type MediaName = keyof typeof media
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nave breakpoints — generated from tokens.json
|
|
3
|
+
* Do not edit directly. Run `pnpm build` in packages/tokens to regenerate.
|
|
4
|
+
*
|
|
5
|
+
* breakpoints — raw px boundary values (number, no unit)
|
|
6
|
+
* These are the design decisions. Edit tokens.json to change them.
|
|
7
|
+
*
|
|
8
|
+
* em — boundary values in em units (base: 16px)
|
|
9
|
+
* For reference. The media strings below use these values.
|
|
10
|
+
*
|
|
11
|
+
* media — pre-built Level 4 media query condition strings
|
|
12
|
+
* Use as @media keys in atoms.ts and consumer atoms.
|
|
13
|
+
* Never write breakpoint values as magic numbers in your codebase.
|
|
14
|
+
*
|
|
15
|
+
* Syntax: Level 4 range queries — (width < Xem) / (width >= Xem)
|
|
16
|
+
* phoneOnly and tabletPortraitUp share the same boundary value (37.5em).
|
|
17
|
+
* < is exclusive upper bound, >= is inclusive lower bound.
|
|
18
|
+
* No overlap, no gap, no rounding issues at any device pixel ratio.
|
|
19
|
+
*
|
|
20
|
+
* Why em: resolves against the browser's default font size, a user setting
|
|
21
|
+
* (not page zoom, which scales px and em alike).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export const breakpoints = {
|
|
25
|
+
tabletPortrait: 600,
|
|
26
|
+
tabletLandscape: 900,
|
|
27
|
+
desktop: 1200,
|
|
28
|
+
wide: 1800
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const em = {
|
|
32
|
+
tabletPortrait: '37.5em',
|
|
33
|
+
tabletLandscape: '56.25em',
|
|
34
|
+
desktop: '75em',
|
|
35
|
+
wide: '112.5em'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const media = {
|
|
39
|
+
phoneOnly: '(width < 37.5em)',
|
|
40
|
+
tabletPortraitUp: '(width >= 37.5em)',
|
|
41
|
+
tabletLandscapeUp: '(width >= 56.25em)',
|
|
42
|
+
desktopUp: '(width >= 75em)',
|
|
43
|
+
wideUp: '(width >= 112.5em)'
|
|
44
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"spec": "documented in this package's README (\"Theming\")",
|
|
3
|
+
"targetGamut": {
|
|
4
|
+
"gamut": "srgb",
|
|
5
|
+
"assumption": "sRGB is the target gamut, stated as an explicit assumption. Every generated value is expressible in sRGB and no wide-gamut colour function is emitted. Wide-gamut (display-p3) output is a deliberate v1 non-goal: a future wide-gamut output regenerates the ramp rather than reusing this one."
|
|
6
|
+
},
|
|
7
|
+
"seeds": {
|
|
8
|
+
"primary": {
|
|
9
|
+
"input": {
|
|
10
|
+
"form": "oklch",
|
|
11
|
+
"value": {
|
|
12
|
+
"l": 0.7859,
|
|
13
|
+
"c": 0.1316,
|
|
14
|
+
"h": 186.17
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"resolved": {
|
|
18
|
+
"l": 0.7859,
|
|
19
|
+
"c": 0.1316,
|
|
20
|
+
"h": 186.17
|
|
21
|
+
},
|
|
22
|
+
"intensityScalar": 0.9554792165204288,
|
|
23
|
+
"sLightness": 0.7859,
|
|
24
|
+
"substitutions": {
|
|
25
|
+
"lightnessBandClamped": {
|
|
26
|
+
"applied": false
|
|
27
|
+
},
|
|
28
|
+
"normalized": {
|
|
29
|
+
"applied": false
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"achromatic": false,
|
|
33
|
+
"seedColourAppearsInRamp": false
|
|
34
|
+
},
|
|
35
|
+
"danger": {
|
|
36
|
+
"input": {
|
|
37
|
+
"form": "oklch",
|
|
38
|
+
"value": {
|
|
39
|
+
"l": 0.6357,
|
|
40
|
+
"c": 0.2072,
|
|
41
|
+
"h": 15.02
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"resolved": {
|
|
45
|
+
"l": 0.6357,
|
|
46
|
+
"c": 0.2072,
|
|
47
|
+
"h": 15.02
|
|
48
|
+
},
|
|
49
|
+
"intensityScalar": 0.8152849011743798,
|
|
50
|
+
"sLightness": 0.6357,
|
|
51
|
+
"substitutions": {
|
|
52
|
+
"lightnessBandClamped": {
|
|
53
|
+
"applied": false
|
|
54
|
+
},
|
|
55
|
+
"normalized": {
|
|
56
|
+
"applied": false
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"achromatic": false,
|
|
60
|
+
"seedColourAppearsInRamp": false
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"achromaticBranch": {
|
|
64
|
+
"selected": false,
|
|
65
|
+
"substitutedSlots": []
|
|
66
|
+
},
|
|
67
|
+
"tint": {
|
|
68
|
+
"hue": 186.17,
|
|
69
|
+
"source": "primary-seed"
|
|
70
|
+
},
|
|
71
|
+
"openAdjacencySlots": [
|
|
72
|
+
"border.strong",
|
|
73
|
+
"feedback.warning.foreground",
|
|
74
|
+
"feedback.success.foreground",
|
|
75
|
+
"feedback.info.foreground"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"formatVersion": 1,
|
|
3
|
+
"producer": {
|
|
4
|
+
"name": "@navecss/core",
|
|
5
|
+
"version": "0.1.0"
|
|
6
|
+
},
|
|
7
|
+
"tokens": [
|
|
8
|
+
"--nave-border-width-focus",
|
|
9
|
+
"--nave-border-width-sm",
|
|
10
|
+
"--nave-color-border-default",
|
|
11
|
+
"--nave-color-border-disabled",
|
|
12
|
+
"--nave-color-border-focus",
|
|
13
|
+
"--nave-color-content-disabled",
|
|
14
|
+
"--nave-color-content-primary",
|
|
15
|
+
"--nave-color-surface-base",
|
|
16
|
+
"--nave-font-family-base",
|
|
17
|
+
"--nave-font-family-display",
|
|
18
|
+
"--nave-font-family-mono",
|
|
19
|
+
"--nave-font-size-md",
|
|
20
|
+
"--nave-font-weight-bold",
|
|
21
|
+
"--nave-line-height-base",
|
|
22
|
+
"--nave-line-height-tight",
|
|
23
|
+
"--nave-motion-duration-base",
|
|
24
|
+
"--nave-motion-easing-standard",
|
|
25
|
+
"--nave-radius-card",
|
|
26
|
+
"--nave-radius-control",
|
|
27
|
+
"--nave-radius-full",
|
|
28
|
+
"--nave-spacing-content-md"
|
|
29
|
+
]
|
|
30
|
+
}
|
package/dist/lib/bin.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from 'node:util';
|
|
3
|
+
import { build, DuplicateTokenNameRefusal, MissingContractTokensError, SeedIngestRefusal, TokenCollisionRefusal, UsageError, validate, } from "./facade.js";
|
|
4
|
+
function normalizationQualifier(seedNormalization) {
|
|
5
|
+
switch (seedNormalization) {
|
|
6
|
+
case 'chroma-reduced': {
|
|
7
|
+
return ' (chroma reduced to fit sRGB)';
|
|
8
|
+
}
|
|
9
|
+
case 'mapped-to-black': {
|
|
10
|
+
return ' (mapped to black to fit sRGB)';
|
|
11
|
+
}
|
|
12
|
+
case 'mapped-to-white': {
|
|
13
|
+
return ' (mapped to white to fit sRGB)';
|
|
14
|
+
}
|
|
15
|
+
default: {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const USAGE = 'Usage:\n' +
|
|
21
|
+
' navecss-tokens build --seed=<colour> --out=<dir> [--source=<file>] [--overrides=<file>]\n' +
|
|
22
|
+
' navecss-tokens validate --source=<file>';
|
|
23
|
+
function parseBuildArgs(args) {
|
|
24
|
+
let values;
|
|
25
|
+
try {
|
|
26
|
+
;
|
|
27
|
+
({ values } = parseArgs({
|
|
28
|
+
args,
|
|
29
|
+
options: {
|
|
30
|
+
out: { type: 'string' },
|
|
31
|
+
overrides: { type: 'string' },
|
|
32
|
+
seed: { type: 'string' },
|
|
33
|
+
source: { type: 'string' },
|
|
34
|
+
},
|
|
35
|
+
strict: true,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new UsageError(error.message);
|
|
40
|
+
}
|
|
41
|
+
if (!values.seed)
|
|
42
|
+
throw new UsageError(`build requires --seed=<colour>.\n${USAGE}`);
|
|
43
|
+
if (!values.out)
|
|
44
|
+
throw new UsageError(`build requires --out=<dir>.\n${USAGE}`);
|
|
45
|
+
return {
|
|
46
|
+
outDir: values.out,
|
|
47
|
+
seed: values.seed,
|
|
48
|
+
...(values.source !== undefined && { source: values.source }),
|
|
49
|
+
...(values.overrides !== undefined && { overrides: values.overrides }),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function parseValidateArgs(args) {
|
|
53
|
+
let values;
|
|
54
|
+
try {
|
|
55
|
+
;
|
|
56
|
+
({ values } = parseArgs({ args, options: { source: { type: 'string' } }, strict: true }));
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new UsageError(error.message);
|
|
60
|
+
}
|
|
61
|
+
if (!values.source)
|
|
62
|
+
throw new UsageError(`validate requires --source=<file>.\n${USAGE}`);
|
|
63
|
+
return { source: values.source };
|
|
64
|
+
}
|
|
65
|
+
function isHelpRequest(args) {
|
|
66
|
+
return args.includes('--help') || args.includes('-h');
|
|
67
|
+
}
|
|
68
|
+
async function main() {
|
|
69
|
+
const [subcommand, ...rest] = process.argv.slice(2);
|
|
70
|
+
if (subcommand === '--help' || subcommand === '-h') {
|
|
71
|
+
console.log(USAGE);
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
if (subcommand === 'build') {
|
|
75
|
+
if (isHelpRequest(rest)) {
|
|
76
|
+
console.log(USAGE);
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
const result = await build(parseBuildArgs(rest));
|
|
80
|
+
console.log(`Built from seed ${result.resolvedSeed}${normalizationQualifier(result.seedNormalization)}: ${result.files.join(', ')}`);
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
if (subcommand === 'validate') {
|
|
84
|
+
if (isHelpRequest(rest)) {
|
|
85
|
+
console.log(USAGE);
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
const result = await validate(parseValidateArgs(rest));
|
|
89
|
+
for (const line of result.output)
|
|
90
|
+
console.log(line);
|
|
91
|
+
return result.exitCode;
|
|
92
|
+
}
|
|
93
|
+
throw new UsageError(`unknown subcommand "${subcommand ?? ''}".\n${USAGE}`);
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
process.exitCode = await main();
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error instanceof UsageError || error instanceof SeedIngestRefusal) {
|
|
100
|
+
console.error(error.message);
|
|
101
|
+
process.exitCode = 2;
|
|
102
|
+
}
|
|
103
|
+
else if (error instanceof MissingContractTokensError ||
|
|
104
|
+
error instanceof TokenCollisionRefusal ||
|
|
105
|
+
error instanceof DuplicateTokenNameRefusal) {
|
|
106
|
+
console.error(error.message);
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
}
|
|
113
|
+
}
|