@indorania/tokens
v0.1.1
Published
In view — the ecosystem's design tokens: the grammar (not themeable) and one dialect per member, as DTCG, CSS, TypeScript and React Native, with the colour floor as a build gate (ECOSYSTEM decision 51).
Readme
@indorania/tokens
The ecosystem's design tokens — In view (ECOSYSTEM decision 51; INDORANIA-DESIGN-LANGUAGE-2026-09-24.md). It holds one grammar, which no member may restyle, and one dialect per member. The colour floor is a build gate that every member can run in its own CI.
Status: version 0.1.1. 0.1.0 is on npm (published 2026-09-25) without the portal's capability tier, which 0.1.1 adds; @indorania/ui needs 0.1.1 or later. Today only Indorania's own site consumes it; no other member has adopted it yet.
Two tiers
| Tier | File | Themeable | What |
|---|---|---|---|
| Grammar (L1) | tokens/grammar.tokens.json | no | The measure (space, type sizes, time, touch 48 / counter 64, corners). The band in day, night and sunlight. The four state colours: verified, failure, awaiting, data. The type roles and the width rule. The motion verbs. The floor. |
| Grammar, portal (L1) | color.capability.{visits,money,work} in grammar.tokens.json | no | The portal's capability lines, V · M · W (§6): a colour and a letter, never a member. Day is solved at 4.5 · 3 · 7:1 so the three part under colour-blindness; night takes each dialect's night hue, so the split is not computed and the letter carries the meaning; sunlight is the day's. CSS: --in-capability-visits … by theme. Gated by the floor like an identity hue (PL-G) |
| Dialect (L3) | tokens/<dialect>.tokens.json | yes | Seam (Indorania: the pattern book, unchanged) · Parallax (Indusland: the water, shared by declaration) · Indigo (Duedale) · Temper (Oreoasis) · Specimen (KashScript: ink only) |
The two-tier rule is enforced, not documented. A dialect file that sets a grammar token fails the build and the CLI (exit 2). So does a dialect whose names would shadow a grammar CSS name, or one that reads another dialect. Token names are logical: start/end, never left/right/top/bottom.
The files are DTCG (Design Tokens Format Module 2025.10). Colours are {colorSpace: "oklch", components, hex} at full precision.
Outputs
| Import | What |
|---|---|
| @indorania/tokens/css/grammar.css, …/css/<dialect>.css | Custom properties: --in-color-day-verified, --in-seam-color-identity-flour-day, … Grammar CSS also sets --in-ground … --in-data by [data-in-theme="day\|night\|sunlight"], and --in-touch (64 under [data-in-counter]) |
| @indorania/tokens, …/grammar, …/seam, … | TypeScript constants, as const. Also FLOOR and LINEAR (the river easing), plus SEAM_TABLE, MARK and MARK_SMALL |
| @indorania/tokens/rn | React Native: unitless numbers (dp), hex, milliseconds, bezier arrays, one family name |
| @indorania/tokens/tokens/*.tokens.json | The DTCG tier files |
| @indorania/tokens/fonts.json | The font manifest. No font files ship here: each surface self-hosts its own subset with the OFL text beside it, and fonts never touch the network at build |
Every output is generated by pnpm build and committed. The tests fail if a committed file differs from the derivation, so a hand-edited hex fails too.
The floor
npx indorania-floor my-member.tokens.json # exit 0 pass · 1 under the floor · 2 a tier rule broken
npx indorania-floor my-member.tokens.json --json # or --report floor.md- The rule: every identity hue keeps ΔE ≥ 0.057 (OKLab) from every state colour of its register, under normal vision and Machado-2009 protanopia, deuteranopia and tritanopia at full severity.
- The floor is computed: it is the pattern book's own worst state pair (0.056503). The literal 0.057 would fail the pattern book's own water.
- Colour roles:
- A chromatic colour is an identity hue, and gated, unless tagged
$extensions["org.indorania"].role = "palette". Palette colours belong on the member's own products: categories, charts, fills, hover steps. They are measured and reported, never gated. - Neutrals are decided by measured chroma (< 0.04), never by tag.
- A chromatic colour is an identity hue, and gated, unless tagged
- Registers: a colour is measured in its register, from a
day/nightpath segment or$extensions["org.indorania"].register. With neither, it is measured against both.
FLOOR.md is the report, regenerated on every build. It covers:
- every dialect's hues
- the palette colours inside the floor (Seam's map palette has 12)
- the reproduction of §7.6 and of the dated note of 2026-09-24, which finds Parallax's alpenglow failing by day and poplar by day and night
- the materials
Materials
Hues come from physical spectra, lightness is solved for contrast, and chroma is shared (0.0808).
- Temper: derived, not adopted. A thin-film model uses magnetite on iron, with optical constants from Querry 1985 and Johnson & Christy 1974 (CC0, via refractiveindex.info). It gives a blue–violet band that contains the nominal 312°. Its most saturated point, 292.7°, sits 0.035 from indigo. 312° stays until the founder decides otherwise.
- Indigo: nominal, not derived. No citable tabulated indigotin spectrum could be sourced, and a band shape drawn around a published λmax would be invented (d11). FLOOR.md lists the sources searched.
Develop
pnpm --filter @indorania/tokens build # validate · gate · write outputs and FLOOR.md
pnpm --filter @indorania/tokens check # the same, writing nothing; exit 1 if an output is stale
pnpm --filter @indorania/tokens test # node --test: parity with derive.mjs, tiers, the floor, the outputs
pnpm --filter @indorania/tokens typecheck # the generated .d.ts filessrc/engine/ is ported verbatim from design/pattern-book/derive.mjs. The pattern book's text is never edited (d51(b)), and test/parity.test.mjs runs derive.mjs to prove Seam unchanged. No runtime dependencies; Node 22.
Licence: Apache-2.0, matching the kernel packages. The founder may change it before the first publish. The material tables are public domain (CC0).
