@node-k/tokens (0.2.6)
Installation
@node-k:registry=npm config set @node-k:registry=npm install @node-k/tokens@0.2.6"@node-k/tokens": "0.2.6"About this package
node-K · Design Tokens (@node-k/tokens)
Was sich zwischen den Versionen geändert hat — und was davon ein Bruch war — steht im Changelog aller vier Pakete:
CHANGELOG.md.
Geteilt werden nur Werte — Farben, Typografie, Raster, Kanten, Effekte und Formen. Komponenten bleiben in jeder App eigenständig: die Nuxt-UI-App (Tailwind) und die Angular-App (Bootstrap) besitzen ihr eigenes Markup und ihre eigenen Styles und ziehen ausschließlich Werte aus diesem Paket.
tokens/
source/ ← EINZIGE Quelle der Wahrheit (DTCG-JSON)
color/brand.json Neutrale, Marke, DNA-Aliase
color/semantic.json Text-Rampe, Semantik, Rollen-Aliase
font/family.json Familien-Stacks
font/scale.json Größe · Gewicht · Breite · Zeilenhöhe · Laufweite
size/space.json 8px-Skala, Layout, Icon-Ausgabegrößen
size/radius.json Radien, Rahmenstärken
shape/geometry.json u-Raster, Fasen-Ratios, Strichstaffel, Icon-Raster
shape/clip.json benannte Formen (clip-path) — strukturiert, nicht als CSS
effect/shadow.json Schatten, Glow
effect/motion.json Easing, Dauer, Fokus, Punktraster-Gradienten
asset/font.json Tektur- + JetBrains-Mono-Dateien (selbst gehostet)
build/ ← Style-Dictionary-Toolchain
shape.mjs Fasen-Renderer: {cut,corners,size} → polygon(…)
tailwind-css.mjs Namensgebung + @theme-Ausgabe für Tailwind v4
transforms.mjs Namens- und Form-Transforms + Transform-Groups
formats.mjs SCSS-Maps, Tailwind-@theme, @font-face, flaches JSON
style-dictionary.config.mjs
copy-static.mjs Nachbereitung: kopiert build/static/* nach dist/scss/,
assets/fonts/* nach dist/assets/fonts/ und setzt die
@kind-Marker in nodek-tokens.css
sync-duplicates.mjs läuft zuerst: bewusste Kopien (net-device.js …) byte-gleich?
kinds.mjs Token-Art je CSS-Name (@kind) für den Compiler
static/
_nodek-bootstrap.scss KURIERT · Bootstrap-Variablen-Brücke, nie generiert
dist/ ← GENERIERT durch `npm run build`, bzw. automatisch
beim `npm install` dieses Pakets (prepare-Hook).
Im Designsystem selbst eingecheckt (die Karten
laden sie direkt), in Apps ungetrackt.
css/nodek-tokens.css :root{--nk-…} dunkel + :root[data-theme="light"]{…} hell
· dieselben 174 Namen je Block, Referenzen bleiben live
css/nodek-tokens-auto.css optional: helles Theme nach prefers-color-scheme,
solange keine explizite Wahl am Wurzelelement steht
css/nodek-fonts.css @font-face · url('../assets/fonts/…'), gerechnet ab dist/css/
assets/fonts/ 25 TTF + Tektur-OFL.txt + JetBrainsMono-OFL.txt (kopiert)
scss/_nodek-tokens.scss $nk-…: value !default
scss/_nodek-maps.scss $nk-color, $nk-space, $nk-shape … als SCSS-Maps
scss/_nodek-bootstrap.scss KURIERT (kopiert aus build/static/)
tailwind/theme.css @theme-Block + --shape-*-Properties + @utility
nodek-tokens.json flach aufgelöst, für Tests und Doku
handoff/ ← Integrations-Kit für die Nuxt-UI-App (reist im Paket mit)
design-tokens.md Referenztabelle + Gestaltungsregeln (Maschinenform: dist/nodek-tokens.json)
newsletter-component.md Beispiel-Komponente mit den Tokens
nuxt-ui.md / nuxt-ui.css / nuxt-ui.ts Mapping-Layer auf Nuxt UI 4
tailwind-v4.md CSS-first Tailwind-v4-Einbindung
package.json npm-Paket "@node-k/tokens"
Bauen: von der Wurzel npm install && npm run build -w tokens (das Paket ist
ein Workspace der Wurzel-package.json, siehe ARBEITSBEREICH.md). Paketmanager
ist npm; das Lockfile liegt an der Wurzel und wird committet. Der
prepare-Hook baut automatisch bei jedem npm install — auch wenn eine App
dieses Paket als Git- oder Pfad-Abhängigkeit installiert, entsteht dist/ dort mit.
Token-Schema
DTCG-Notation ($value / $type / $description), Style Dictionary 4.
{
"color": {
"brand": {
"orange": { "$type": "color", "$value": "#fbaa2b" }
},
"role": {
"accent": { "$type": "color", "$value": "{color.brand.orange}",
"$extensions": { "nodek": { "cssVar": "nk-accent" } } }
}
}
}
Pfad = Bedeutung. <kategorie>.<gruppe>.<name>; erste Ebene ist die
Kategorie (color, font, space, radius, border, shape, shadow,
motion, focus, gradient, size, layout, asset).
Referenzen ({pfad}) statt Wiederholung. Basiswerte liegen in
color.neutral / color.brand; alles Bedeutungstragende (color.role.accent,
color.dna.gelb) ist ein Alias. Im CSS-Output bleiben Referenzen als var()
erhalten — ein Theme-Wechsel wirkt zur Laufzeit.
$extensions.nodek.cssVar friert den gewachsenen CSS-Namen ein
(--nk-orange statt --nk-color-brand-orange). Damit ist der CSS-Output
1:1 kompatibel mit dem bestehenden Designsystem; SCSS und Tailwind benutzen
die saubere Pfad-Notation.
$extensions.nodek.light ist der zweite Wert desselben Tokens für das
helle Theme (P9). Ein Token, zwei Werte — nie zwei Tokens: die Zahl der Namen
bleibt gleich (174), Komponenten kennen nur einen Fall. Tokens ohne light gelten in
beiden Modi (Marke, Form, Raster, Schrift) und werden im hellen Block mit
demselben Wert wiederholt, damit beide Blöcke dieselben Namen tragen. light
darf eine Referenz sein ("{color.brand.paper}" → var(--nk-paper)).
Maßgeblich für jeden Hellwert ist korrekturen/farbsystem.md.
Umschalter. Verbindlich ist das Attribut am Wurzelelement:
<html data-theme="light"> bzw. "dark". :root.light bleibt als Alias.
Ohne explizite Wahl gilt dunkel; wer der Systemvoreinstellung folgen will,
lädt zusätzlich nodek-tokens-auto.css (Export ./css-auto) — dessen
prefers-color-scheme-Block greift nur, solange weder data-theme="dark"
noch .dark gesetzt ist. Der Block liegt in einer eigenen Datei, weil sein
:not()-Selektor vom Design-System-Compiler nicht als Token-Scope gelesen wird.
für alles, was DTCG nicht abbildet:
nk.clipPath, nk.transform, nk.transition, nk.border, nk.gradient,
nk.percentage, nk.fontFace. Schatten liegen als CSS-String
statt als zerlegtes DTCG-Objekt — bewusste Abweichung, weil beide Apps sie
unverändert durchreichen.
Formen als Tokens
Das prägende Merkmal der Marke ist die 45°-Fase. Sie darf nicht als
polygon(…)-String in zwei Codebasen liegen. Deshalb ist eine Form ein
strukturiertes Token:
"shape": {
"frame": {
"clip": {
"btn-aktiv": {
"$type": "nk.clipPath",
"$value": { "cut": "chamfer", "corners": ["tr", "bl"], "size": "{shape.frame.chamfer.btn}" }
}
}
}
}
build/shape.mjs rendert daraus im Uhrzeigersinn ab oben links — für
jede Plattform dieselbe Geometrie, mit der Fasengröße als eigener Variable:
/* dist/css/nodek-tokens.css */
--nk-frame-clip-btn-aktiv: polygon(0 0, calc(100% - var(--nk-frame-chamfer-btn)) 0, …);
/* dist/tailwind/theme.css — gleicher Name, im :root-Block */
--nk-frame-clip-btn-aktiv: polygon(0 0, calc(100% - var(--nk-frame-chamfer-btn)) 0, …);
Die Formfamilie folgt einem Schema (korrekturen/formen-und-rahmen.md §7):
--nk-<familie>-<eigenschaft>-<klasse>[-in].
| Familie | Eigenschaft | Klasse |
|---|---|---|
frame — der gefaste Rahmen |
chamfer · line · pad · clip · ring |
xs · chip · btn · card · panel |
asset — die Zeichnung |
stroke · ratio |
hair · reg · bold bzw. module · finder · form |
oct — die Marken-Silhouette |
chamfer · half · frame · clip |
— |
| Klasse | Fase | Innenfase | Linie | Innenabstand | Einsatz |
|---|---|---|---|---|---|
xs |
4px | 3.5px | 1px | 8px | Marker, kleine Tags |
chip |
6px | 5.5px | 1.5px | 12px | Chips, Tags, Badges |
btn |
8px | 7px | 2px | 16px | Schaltflächen, Felder |
card |
12px | 11px | 3px | 24px | Karten, Container |
panel |
16px | 14.5px | 4px | 32px | Großflächen, Modale |
--nk-gutter: 8vw ist die Marketing-Vorgabe fürs Layout-Raster. Anwendungen überschreiben sie lokal —
in Inventar auf 1rem.
Funktionale Apps · der Flächenstapel
Die Rollen sagen, welcher Neutralton welche Fläche trägt; für eine App-Shell ergibt das genau einen Stapel. Festgehalten, weil ihn sonst jede App neu herleitet:
| Fläche | Token | dunkel · hell |
|---|---|---|
| Seite, Hauptbereich — die Bühne | --nk-black |
#171717 · #f5f2ec |
| Chrome: Sidebar, Kopfzeile, Wells, abgesetzte Abschnitte | --nk-black-deep |
#0e0e0e · #eae6dd |
| Karten und Panels — die eine erhöhte Fläche | --nk-surface |
#1c1c1c · #faf8f3 |
| Trennlinien darin | --nk-border / --nk-border-strong |
#2a2a2a · #d8d4cd |
Navigation hebt beim Überfahren und im aktiven Zustand auf --nk-surface — eine Stufe
nach oben, nicht in eine Akzentfarbe. Es gibt keine vierte Ebene: wer eine braucht,
hat eine Schachtelung zu viel.
Dichte bleibt bei der App. --nk-gutter und --nk-maxwidth sind Marketing-Werte;
eine Anwendung setzt stattdessen ihre eigenen (Inventar: --nk-gutter: 1rem,
--nk-content-max: 72rem). Das ist keine Abweichung, sondern die vorgesehene Teilung —
geteilt werden Farben, Formen und Raster, nicht Layout-Entscheidungen (siehe
Grenze: was geteilt wird, was nicht).
Richtung (Entscheidung 11): Die Clip-Token tragen eine Richtungsachse —
--nk-frame-clip-<klasse>-aktiv|passiv[-in], zwanzig Token, erzeugt statt
gepflegt. aktiv = das Element bekommt Tastaturfokus → Fase oben rechts +
unten links (die Markensignatur). passiv = alles Übrige → oben links +
unten rechts. Die Zeichnung selbst (assets/svg/**, QR) schneidet weiter nur
oben rechts. --nk-oct-clip (alle vier Ecken) bleibt die Markenform.
Regel: Fase = 0.3 · kürzere Kante, gerundet, auf die fünf Klassen
geklammert. Rahmen einer gefasten Fläche ist nie border + clip-path,
sondern ein Ring: --nk-frame-ring-<klasse>-<richtung> zeichnet außen die
Fase und innen dieselbe Fase um --nk-frame-line-<klasse> versetzt, dazwischen
Farbe, in der Mitte durchsichtig (evenodd). Zehn Token. Die Füllung darin
nimmt die -in-Fase, damit sie an der Innenkontur endet. Der Ring gehört in ein
::before, nicht ans Element selbst — dann bleibt die Trefferfläche rechteckig.
Begründung und Messung: korrekturen/formen-und-rahmen.md §9. (Bis 28.9. war das
eine Doppelebene aus zwei Flächen; sie ist ersetzt.)
Konsumieren
Das Paket veröffentlicht seine generierten Dateien über exports-Subpfade
(siehe package.json) — kein tiefer Import in dist/** nötig.
Nuxt UI / Tailwind v4 — CSS-first, kein JS-Plugin
/* app.css / main.css */
@import "tailwindcss";
@import "@node-k/tokens/fonts";
@import "@node-k/tokens/tailwind";
Gültige Subpfade: ./css ./fonts ./tailwind ./scss ./scss-maps
./scss-bootstrap ./tokens.json — und ./dist/* für jeden Pfad unter
dist/ (z. B. @node-k/tokens/dist/css/nodek-fonts.css).
Details und die vollständige Mapping-Anleitung für Nuxt UI 4 stehen in
handoff/tailwind-v4.md und
handoff/nuxt-ui.md.
theme.css (Export ./tailwind) besteht aus drei Teilen:
@theme { … }— alles, was einem Tailwind-v4-Namespace entspricht, und damit Utilities erzeugt:--color-nk-*→bg-nk-orange,--font-nk-*→font-nk-display,--text-nk-*→text-nk-h1,--spacing-nk-*,--radius-nk-*,--shadow-nk-*,--font-weight-nk-*,--leading-nk-*,--tracking-nk-*,--ease-nk,--container-nk.:root { … }— alles ohne Namespace, unter demselben Namen wie im CSS-Paket, direkt pervar()nutzbar:--nk-frame-clip-btn-aktiv,--nk-frame-chamfer-btn,--nk-frame-line-card,--nk-asset-stroke-reg,--nk-icon-box,--nk-bw,--nk-dur-fast,--nk-transition,--nk-focus-width,--nk-focus-offset,--nk-dots-orange.@utility …— Tailwinds nativer Utility-Mechanismus für die Formen:nk-clip-<klasse>-aktiv|passiv[-in]fürxschipbtncardpanel,nk-clip-oct, plusnk-focus.
<button class="nk-clip-btn-aktiv bg-nk-orange font-nk-display text-nk-body px-6 py-3">
Mitglied werden
</button>
@theme erweitert die Tailwind-Defaults. Wer ausschließlich node-K-Werte
zulassen will, setzt vor dem Import @theme { --*: initial; }.
Nuxt UI erwartet für ui.primary eine 50–950-Palette. node-K hat bewusst
keine Tint-Rampe (Schwarz ist die Bühne, Akzente sind gesetzt). Entweder
ui: { primary: 'amber' } mit --color-amber-500: var(--color-nk-orange), oder
die Nuxt-UI-Farbrollen direkt auf --color-nk-* zeigen lassen. Keine neuen
Tints erfinden.
Bootstrap / Angular
@use 'pkg:@node-k/tokens/scss' as *;
@use 'pkg:@node-k/tokens/scss-bootstrap' as *;
@import 'bootstrap/scss/bootstrap';
.btn-primary { clip-path: $nk-shape-frame-clip-btn-aktiv; border-radius: 0; }
pkg:-URLs setzen Dart Sass ≥ 1.71 voraus und fallen in Angular-CLI-Builds aus (paketierung.md§1). Dortnode_modulesalsstylePreprocessorOptions.includePathseintragen und@use 'nodek-tokens' as *;schreiben.
Beliebige Umgebung (Web Components, E-Mail, Doku)
<link rel="stylesheet" href="/node_modules/@node-k/tokens/dist/css/nodek-fonts.css">
<link rel="stylesheet" href="/node_modules/@node-k/tokens/dist/css/nodek-tokens.css">
<!-- optional: Systemvoreinstellung, solange kein data-theme gesetzt ist -->
<link rel="stylesheet" href="/node_modules/@node-k/tokens/dist/css/nodek-tokens-auto.css">
Die @font-face-Regeln zeigen auf ../assets/fonts/…, gerechnet ab dist/css/ —
die TTF liegen im Paket unter dist/assets/fonts/ und werden mit ausgeliefert.
Angular
nodek-fonts.css zeigt relativ auf ../assets/fonts/…. Das trägt, wenn die CSS aus node_modules gebündelt
wird. Sobald etwas vor dem Bündel Schrift braucht (Splash-Screen), müssen die Fonts zusätzlich nach
/assets/fonts/ kopiert werden — derselbe styles-Eintrag wie beim Einbinden, plus ein assets-Glob:
"assets": [
{ "glob": "**/*", "input": "node_modules/@node-k/tokens/dist/assets/fonts", "output": "assets/fonts" }
]
Auth in der .npmrc — nur wenn ein Token existiert. Die Zeile _authToken=${NODE_AUTH_TOKEN} mit leerer
Variablen ergibt einen leeren Bearer, und die Registry antwortet 401. Ohne diese Zeile — nur der Registry-Eintrag —
lädt das Paket auch ohne Auth.
Grenze: was geteilt wird, was nicht
Geteilt — Farben, Typografie, 8px-Raster, Radien, Rahmenstärken, Fasen und Formen, Schatten, Glow, Easing/Dauer, Fokus-Werte, Icon-Raster und Ausgabegrößen, Font-Dateien.
Nicht geteilt — Komponenten-Markup, Klassennamen, Zustandslogik, Layout-
Entscheidungen, Bootstrap-Utilities, Nuxt-UI-Slots, Breakpoints (beide
Frameworks haben eigene und inkompatible Definitionen), Icon-SVGs (die liegen
weiterhin in assets/svg/ und werden als Dateien kopiert, nicht als Token).
Verboten: einen Wert in einer App hart schreiben, der schon Token ist — und ein Token anlegen, das nur eine App braucht.
Änderungen
0.2.0 — neue Herkunft, geänderte Namen
Die 0.1.0 bis 0.1.3 in der Registry stammen aus dem alten Token-Repo vom 15. August, nicht aus diesem
Monorepo — verglichen werden also zwei Herkünfte unter demselben Namen. Deshalb der Sprung auf 0.2.0 statt
0.1.4. Fünf Namen aus 0.1.3 haben in diesem Stand keinen Treffer mehr; zwei davon sind echte Ersetzungen,
keine Aliase, gemessen gegen den Tarball @node-k/tokens@0.1.3 (35,8 kB, 17 Dateien, shasum
00c360d3779256a9038915bd4dfec24dceb5ee3d):
| alter Name (0.1.3) | Wert 0.1.3 | heutiges Token | Wert heute (dunkel) | Urteil |
|---|---|---|---|---|
--nk-bg |
var(--nk-black) |
--nk-black |
#171717 |
echter Alias — war schon in 0.1.3 nur ein zweiter Name |
--nk-border-3 |
#333333 |
--nk-border-strong |
#333333 |
wertgleich |
$nk-color-role-bg |
#171717 |
$nk-color-neutral-black |
#171717 |
wertgleich |
--nk-border-2 |
#232323 |
--nk-border |
#2a2a2a |
Ersatz, nicht wertgleich — #232323 existiert heute nirgends, --nk-border ist der nächste, etwas hellere Wert |
--nk-dur-mid |
.25s |
--nk-dur-fast |
.15s |
Ersatz, nicht wertgleich — es gibt nur noch eine Dauer im System |
Eine Kompatibilitätsdatei bildet die vier CSS-Namen auf die heutigen ab:
dist/css/nodek-compat-0.1.css, generiert (nicht von Hand gepflegt) und
von npm run check -w tokens mitverglichen. Nach nodek-tokens.css einbinden; entfällt mit 0.3.0. Wer über
sie --nk-border-2 bezieht, bekommt eine etwas hellere Linie als 0.1.3; wer --nk-dur-mid bezieht, eine um
100 ms kürzere Bewegung — beides vertretbar, beides eine Änderung.
- Wert in
source/**ändern oder anlegen (mit$description). npm run build -w tokensvon der Wurzel.npm run check -w tokensbaut danach in ein temporäres Verzeichnis und vergleicht byteweise gegendist/, ohne es anzufassen — derselbe Schritt läuft in CI (npm run verify).dist/mitliefern — im Designsystem selbst ist die generierte Ausgabe eingecheckt, weilstyles.cssund jede Specimen-Karte sie direkt laden. Konsumierende Apps installieren@node-k/tokens(Git- oder Pfad-Abhängigkeit); dort entstehtdist/über denprepare-Hook aus derselben Quelle und bleibt ungetrackt.- Bei neuem CSS-Namen:
$extensions.nodek.cssVarnur setzen, wenn ein bestehender Name erhalten bleiben muss.
Root-styles.css importiert dist/css/nodek-fonts.css und
dist/css/nodek-tokens.css direkt — das ist die einzige Werte-Quelle für das
Designsystem selbst, es gibt keine parallele handgeschriebene CSS-Ebene mehr.
Dependencies
Development dependencies
| ID | Version |
|---|---|
| style-dictionary | 4.4.0 |
| typescript | 5.9.3 |