okchroma 0.6.0 → 0.7.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/README.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # OKChroma
2
2
 
3
- **A color-system engine.** Give it one brand hex, or two, and it resolves a complete
4
- light and dark token system whose contrast requirements are solved during generation,
5
- then emits it as CSS custom properties or Figma variables.
3
+ **A color-system engine.** Give it one brand hex, or two, and it resolves a complete set
4
+ of light and dark color primitives whose contrast requirements are solved during
5
+ generation, then emits it as CSS custom properties, as DTCG documents, and as Figma
6
+ variables, every token spelled the same way in each.
6
7
 
7
8
  Every family (neutral, brand, brand-alt, critical, warning, positive, info) carries the
8
9
  same scale: 3 papers, 4 chalks, 1 highlighter, 1 pencil, 2 pens, plus the stamp (the
9
10
  solid fill with its hover and pressed states, its edge, and its text). The neutral adds
10
- the two poles. Light and dark resolve together and ship on the same names, so a token is
11
- mapped once and holds for any brand.
11
+ the two poles. Two link trios and the two brand seeds complete the set. Light and dark
12
+ resolve together and ship on the same names, so a token is mapped once and holds for any
13
+ brand.
12
14
 
13
15
  Contrast is built into the math, not checked afterwards: highlighter reads on every paper at
14
16
  3:1 (the non-text bar), pencil at 4.5:1, pen at 4.5:1 on every paper and chalk in
@@ -16,6 +18,10 @@ both directions; the stamp's text passes 4.5:1 on its fill. APCA is used once, a
16
18
  that nudges the stamp fill until its text reads at Lc 65. Each claim, its scope, and the audit that
17
19
  proves it: [Guarantees](https://egerrity.github.io/okchroma/#/docs/guarantees).
18
20
 
21
+ The engine emits primitives only: values it calculates from the seed. Elevation planes,
22
+ shadows, opacity ladders and state layers are a design system's to author on top of these,
23
+ and [docs/agents.md](docs/agents.md) says which primitive each of those decisions reads.
24
+
19
25
  > The reserved-role-per-stop model is a conceptual nod to
20
26
  > [Radix Colors](https://www.radix-ui.com/colors/docs/palette-composition/understanding-the-scale).
21
27
  > It is not a dependency and does not touch the math; the color computation is original.
@@ -27,22 +33,77 @@ npm install okchroma
27
33
  ```
28
34
 
29
35
  ESM and CommonJS builds with TypeScript declarations; no runtime dependencies (the one
30
- perceptual-distance library the engine uses is bundled in).
36
+ perceptual-distance library the engine uses is bundled in). Node 18 or later; no DOM.
31
37
 
32
38
  ```ts
33
- import { resolveTheme, brandCss, signalsCss, neutralTintHue } from 'okchroma'
39
+ import { resolveTheme, brandCss, signalsCss, themeTokens, tokensToDtcg, neutralTintHue } from 'okchroma'
34
40
 
35
41
  const theme = resolveTheme({ primaryHex: '#E93D82', name: 'acme', deriveSecondary: true })
36
42
  const neutralH = neutralTintHue(theme.themed.scale.brandH)
43
+
44
+ // CSS custom properties: a light and a dark block per brand, the signal block once
37
45
  const css = brandCss('acme', 'Acme', theme.themed, theme.secondary?.scale ?? null,
38
46
  '', 'default', undefined, theme.secondary?.style, false, null, true, neutralH)
39
47
  + '\n' + signalsCss()
40
48
  // put css in a stylesheet; set data-brand="acme" on the themed root,
41
49
  // and data-theme="dark" on it for dark mode
50
+
51
+ // the same values as one object per mode, every var() resolved
52
+ const tokens = themeTokens({ slug: 'acme', brand: theme.themed, secondary: theme.secondary?.scale ?? null, secondaryStyle: theme.secondary?.style, neutralH })
53
+
54
+ // the DTCG documents: one per mode, every token with its description
55
+ const { light, dark } = tokensToDtcg(tokens)
42
56
  ```
43
57
 
44
- The same values as one object per mode come from `themeTokens`, and the state layer as named rows from `interactionCss` and `interactionTokens` (`docs/agents.md` lists the rows). The Figma tree comes from `themeToFigma`. Signatures, the full input, and an end-to-end example:
45
- [Install and API](https://egerrity.github.io/okchroma/#/docs/install).
58
+ The Figma tree comes from `themeToFigma`. Signatures, the full input, and an end-to-end
59
+ example: [Install and API](https://egerrity.github.io/okchroma/#/docs/install).
60
+
61
+ ## What it emits
62
+
63
+ Every token has one path, and every output spells it: `brand/stamp/fill`,
64
+ `neutral/paper-0`, `link/default/enabled`, `absolute/brand`. Joined with hyphens it is the
65
+ CSS custom property (`--brand-stamp-fill`); joined with slashes it is the Figma variable
66
+ and the DTCG token path.
67
+
68
+ | Group | Tokens |
69
+ |---|---|
70
+ | `neutral` | `paper-0`, `paper-1`, `paper-3`, `paper-5`, `chalk-8`, `chalk-11`, `chalk-15`, `chalk-20`, `highlighter-26`, `pencil-47`, `pen-58`, `pen-70`, `pen-100`, and the stamp: `stamp/fill`, `stamp/fill-hover`, `stamp/fill-pressed`, `stamp/edge`, `stamp/on` |
71
+ | `brand`, `brand-alt`, `critical`, `warning`, `positive`, `info` | the same eleven stops and the same five stamp tokens |
72
+ | `link` | `default/enabled`, `default/hover`, `default/pressed` for text on the papers; `inverse/enabled`, `inverse/hover`, `inverse/pressed` for text on the pen ground |
73
+ | `absolute` | `brand`, `brand-alt`: the seeds as given, reference values |
74
+
75
+ What each name means, which stop to read for which job, and the rules for an agent
76
+ writing UI against these: [docs/agents.md](docs/agents.md). The scale and its declared
77
+ targets: [docs/scale.md](docs/scale.md).
78
+
79
+ **The stops.** The instrument word is the job, the number is 100 minus the light-mode
80
+ lightness target, and bigger is stronger. Papers are backgrounds; chalks are decorative
81
+ borders and illustration, never text; the highlighter is the non-text contrast stop (focus
82
+ rings, icons, large text, and the one stop to build translucent state layers on); the
83
+ pencil and the pens are text, and the pencil doubles as the emphasis fill.
84
+
85
+ **The stamp.** `stamp/fill` is the call-to-action fill, re-solved per family and theme;
86
+ `fill-hover` and `fill-pressed` are its states; `stamp/on` is the text over it, the pole
87
+ that passes (the pole at alpha on a quiet fill); `stamp/edge` is a stroke that resolves to
88
+ a visible offset only where the fill sits close to the page, else transparent, so a
89
+ component renders the border unconditionally and layout never shifts.
90
+
91
+ **The outputs.**
92
+
93
+ - CSS: `brandCss` writes `[data-brand="acme"]` and `[data-brand="acme"][data-theme="dark"]`
94
+ blocks, `signalsCss` the brand-independent signal block at `:root`. Values are sRGB
95
+ hexes (or `rgba()` where a token carries alpha); stops whose chroma exceeds sRGB get a
96
+ `color(display-p3 …)` override behind a browser gate. The repo's `npm run generate`
97
+ writes the signal block to `dist/signals.css`.
98
+ - The structured emit: `themeTokens` reads the CSS emission back into one object per
99
+ mode with every reference resolved, for consumers with no cascade.
100
+ - DTCG: `tokensToDtcg` returns one Design Tokens Format Module 2025.10 document per mode,
101
+ every token with `$type`, an sRGB `$value` whose components and hex are the same 8-bit
102
+ color (or an alias where the CSS writes a reference), and a `$description`. The two join
103
+ through a resolver document. The format: [docs/schema.md](docs/schema.md). The repo's
104
+ `npm run tokens:emit -- '#E93D82' acme` writes both files.
105
+ - Figma: `themeToFigma` returns a light and a dark group tree on the same paths; the
106
+ extended plugin writes it into a file.
46
107
 
47
108
  ## Run from source
48
109
 
@@ -54,13 +115,14 @@ npm run dev # watch mode
54
115
  ```
55
116
 
56
117
  `npm run typecheck` runs the compiler; the audit gates (`npm run req:audit`,
57
- `npm run audit:guarantee`, and the rest of `package.json`) each sweep agnostic seeds and
58
- fail on the worst case. What each proves:
118
+ `npm run audit:guarantee`, `npm run audit:dtcg`, and the rest of `package.json`) each
119
+ sweep agnostic seeds and fail on the worst case. What each proves:
59
120
  [How it is verified](https://egerrity.github.io/okchroma/#/docs/guarantees/how-it-is-verified).
60
121
 
61
122
  ## Documentation
62
123
 
63
- The docs site is the source: [egerrity.github.io/okchroma/#/docs](https://egerrity.github.io/okchroma/#/docs).
124
+ The docs site renders the mechanisms with live values from the engine:
125
+ [egerrity.github.io/okchroma/#/docs](https://egerrity.github.io/okchroma/#/docs).
64
126
 
65
127
  - [Overview](https://egerrity.github.io/okchroma/#/docs/overview): what goes in, what comes out, the token roster.
66
128
  - [Output contract](https://egerrity.github.io/okchroma/#/docs/output): the naming grammar, families and prefixes, modes and selectors, a live CSS block and Figma tree.
@@ -68,12 +130,12 @@ The docs site is the source: [egerrity.github.io/okchroma/#/docs](https://egerri
68
130
  - [How the theme is generated](https://egerrity.github.io/okchroma/#/docs/generation): the pipeline in execution order, with the constants and the code that runs each step.
69
131
  - [Signals and companions](https://egerrity.github.io/okchroma/#/docs/signals) and the [Reference](https://egerrity.github.io/okchroma/#/docs/reference): glossary, constants, option types.
70
132
 
71
- In the repo: [docs/architecture.md](docs/architecture.md) (the maintainer's map: modules,
72
- pipeline stages, data structures, the extended plugin's zones),
133
+ In the repo: [docs/agents.md](docs/agents.md) (the consumer contract: what every token
134
+ means and the rules for using it), [docs/schema.md](docs/schema.md) (the DTCG documents),
73
135
  [docs/scale.md](docs/scale.md) (the scale and its declared targets),
74
- [docs/schema.md](docs/schema.md) (the format of the experimental DTCG export),
75
- [docs/agents.md](docs/agents.md) (how a coding agent consuming the tokens should read
76
- them), and [CHANGELOG.md](CHANGELOG.md).
136
+ [docs/architecture.md](docs/architecture.md) (the maintainer's map: modules, pipeline
137
+ stages, data structures, the extended plugin's write path), and
138
+ [CHANGELOG.md](CHANGELOG.md).
77
139
 
78
140
  ## The Figma plugins
79
141