@krizaka/tokens

中文文档
3.80.0发布于 2026/11/01Apache-2.0TypeScriptES Module零依赖构建来源已验证

The Krizaka semantic design tokens (--kz-*) and the brand themes (Krizaka, Orazaka, Yomizaka, Akinaza): one DTCG source compiled to CSS (dark, light, media invariants), typed constants and React Native themes.

原始使用文档
文档目录10 节
  1. The rule
  2. Install
  3. Themes
  4. Roles
  5. Colour
  6. Shape, depth, motion, type
  7. The paper (Cahier, ADR-004)
  8. The material (BRAND.md §6)
  9. Add or change a token
  10. License

@krizaka/tokens

The Krizaka semantic design tokens. One vocabulary, --kz-*, written once in DTCG JSON and compiled to CSS (dark, light, media invariants), typed constants and React Native themes. It is the vocabulary krizaka.com already runs on (1 974 usages, zero raw palette colour), now shared by every product.

npm License

The rule

A component never reads a palette colour, only a role. bg-zinc-950/70 light:bg-white → var(--kz-surface-1); text-zinc-400 light:text-slate-500 → var(--kz-text-secondary); bg-black/60 text-white on an image → var(--kz-scrim) + var(--kz-text-on-media).

A theme is a set of values, never a set of classes. A component is written once against the roles below; dark, light and a product theme (an override of --kz-accent, --kz-font-display…) only change the values. No light: variant, no dark: variant, no zinc-* / slate-* / #hex in a component.

Install

npm install @krizaka/tokens
EntryForGives
@krizaka/tokens/tokens.cssWeb (imported once, usually through @krizaka/tailwind)The --kz-* custom properties.
@krizaka/tokensTS / JS on the web (canvas, charts, e-mails, inline styles)tokens (var(--kz-…) references, camelCase keys), values.dark / values.light (raw CSS, aliases resolved), TokenName.
@krizaka/tokens/nativeReact Native / Expothemes.dark / themes.light (hex, rgba() when translucent), radius (dp), typography, motion.ease, type Theme; brands.<id> (ThemeProvider overrides); marks.<id> (the mark's emblem gradient, [offset, #rrggbb] stops).
@krizaka/tokens/brands/<id>.cssA product app (krizaka, orazaka, yomizaka, akinaza), after the tokensThe brand's accent family and section gradient, dark and light.
@krizaka/tokens/brands/scoped.cssA page showing several brands.brand-krizaka, .brand-orazaka, .brand-yomizaka, .brand-akinaza (the paused products' scopes still ship, deprecated).

Brands: one colour per brand, its marks, icons and page language are in BRAND.md.

@import "@krizaka/tokens/tokens.css";

.card { background: var(--kz-surface-1); border: 1px solid var(--kz-border-default); border-radius: var(--kz-radius-lg); }
import { tokens, values } from "@krizaka/tokens";
element.style.color = tokens.textSecondary;  // "var(--kz-text-secondary)" — follows the theme
chart.gridColor = values.dark.borderSubtle;   // "hsl(0 0% 100% / 0.06)"

import { themes, radius, type Theme } from "@krizaka/tokens/native";
const t: Theme = scheme === "light" ? themes.light : themes.dark;
<View style={{ backgroundColor: t.surface1, borderRadius: radius.lg }} />;

Themes

SelectorGets
:root, .theme-darkDark — the default. .theme-dark re-declares the dark values, so a player, an editor or a media stays dark inside a light page without one light: class in its subtree.
html.lightLight. Toggle the light class on <html>.
.theme-lightLight on a subtree (a theme preview inside a dark page): the light values and the aliases, the counterpart of .theme-dark.
:root (invariants)Identical in both themes: what sits on a media (scrims, text on media, dialog overlay), statuses, on-accent, radii, easing, font stacks.

color-scheme follows the theme, so scrollbars and native controls match.

Roles

Values are the CSS written in dist/tokens.css; → marks an alias, which follows its target in every theme and under every product override.

Colour

TokenKeyUsageDarkLight
--kz-surface-0surface0Page background: the slate (dark), the paper (light)hsl(150 12% 9.5%)hsl(100 14% 96%)
--kz-surface-1surface1Card, panelhsl(240 5% 9%)hsl(0 0% 100%)
--kz-surface-2surface2Raised element, field, hoverhsl(240 5% 13%)hsl(240 6% 95%)
--kz-surface-3surface3Active element, chip, trackhsl(240 4% 17%)hsl(240 5% 90%)
--kz-mediamediaA media's background before it loadshsl(240 5% 11%)hsl(240 6% 92%)
--kz-border-subtleborderSubtleQuiet separatorhsl(0 0% 100% / 0.06)hsl(240 6% 0% / 0.06)
--kz-border-defaultborderDefaultCard and field outlinehsl(0 0% 100% / 0.10)hsl(240 6% 0% / 0.10)
--kz-border-strongborderStrongHover outline, non-keyboard focushsl(0 0% 100% / 0.16)hsl(240 6% 0% / 0.16)
--kz-text-primarytextPrimaryHeadings, body text (≥ 4.5:1 on every surface): chalk, inkhsl(105 17% 93%)hsl(212 49% 22%)
--kz-text-secondarytextSecondarySupporting text, labels (≥ 4.5:1 on every surface)hsl(240 4% 64%)hsl(240 4% 41%)
--kz-text-mutedtextMutedMetadata, placeholders, disabled (≥ 3:1 on every surface)hsl(240 4% 47%)hsl(240 4% 52%)
--kz-text-on-mediatextOnMediaText on an image or a videohsl(0 0% 100%)= dark
--kz-accentaccentPrimary action, link, selection — the product's identityhsl(217 92% 53%)hsl(217 92% 50%)
--kz-accent-hoveraccentHoverAccent on hoverhsl(217 88% 45%)hsl(217 88% 42%)
--kz-accent-softaccentSoftTinted background (selection, badge)hsl(217 92% 53% / 0.10)hsl(217 92% 50% / 0.08)
--kz-accent-textaccentTextThe accent as text (link, active label): ≥ 4.5:1 on every surfacehsl(217 92% 68%)hsl(217 92% 42%)
--kz-accent-2accent2Second accent (gradients)→ accent→ accent
--kz-on-accentonAccentText and icon on the accent (≥ 4.5:1)hsl(0 0% 100%)= dark
--kz-ringringKeyboard focus ring→ accent→ accent
--kz-brand-gradient-from / -via / -tobrandGradientFrom…Section gradient of the brand — flat since Cahier (ADR-004): the page surface; text reads at AA on every stop. -to is an alias of surface-0: an app that changes its page surface keeps a seamless section endhsl(222 45% 10%) → hsl(232 24% 7%) → surface-0hsl(214 95% 93%) → hsl(220 60% 97%) → surface-0
--kz-successsuccessStatus: success — fills, borders, dots, icons (≥ 3:1)hsl(160 84% 39%)= dark
--kz-success-textsuccessTextSuccess as small text: ≥ 4.5:1 on every surfacehsl(158 64% 52%)hsl(160 84% 24%)
--kz-warningwarningStatus: warninghsl(38 92% 50%)= dark
--kz-warning-textwarningTextWarning as small text: ≥ 4.5:1 on every surfacehsl(38 92% 55%)hsl(32 95% 30%)
--kz-dangerdangerStatus: error, destructive actionhsl(0 84% 60%)= dark
--kz-danger-textdangerTextError as small text (a field's message, an urgent countdown): ≥ 4.5:1 on every surfacehsl(0 91% 71%)hsl(0 72% 40%)
--kz-infoinfoStatus: information→ accent→ accent
--kz-info-textinfoTextInformation as small text (a brand role)→ accent-text→ accent-text
--kz-scrimscrimVeil behind a badge or a caption on an imagehsl(0 0% 0% / 0.60)= dark
--kz-scrim-strongscrimStrongStronger veil (long text on an image)hsl(0 0% 0% / 0.80)= dark
--kz-overlayoverlayDialog backdrophsl(0 0% 0% / 0.70)= dark

Shape, depth, motion, type

TokenKeyUsageDarkLight
--kz-radius-smradiusSmField, chip2px= dark
--kz-radius-mdradiusMdButton, menu2px= dark
--kz-radius-lgradiusLgCard (square paper)0px= dark
--kz-radius-xlradiusXlDialog, sheet0px= dark
--kz-radius-fullradiusFullPill, avatar9999px= dark
--kz-shadow-smshadowSmField, button at rest (web only): a 1 px ink line, no blur0 1px 0 hsl(150 30% 3% / 0.6)0 1px 0 hsl(212 49% 24% / 0.12)
--kz-shadow-mdshadowMdMenu, popover (web only): a sheet on a sheet0 1px 0 …, 4px 5px 0 -2px hsl(150 30% 4% / 0.55)0 1px 0 …, 4px 5px 0 -2px hsl(212 40% 30% / 0.14)
--kz-shadow-lgshadowLgDialog, sheet (web only)0 1px 0 …, 6px 8px 0 -2px …0 1px 0 …, 6px 8px 0 -2px …
--kz-easeeaseThe ink stroke: the default curve (Cahier)cubic-bezier(0.45, 0, 0.2, 1)= dark
--kz-font-sansfontSansInterface and running text"Atkinson Hyperlegible Next", system-ui, sans-serif= dark
--kz-font-displayfontDisplayHeadings; a product theme may override it→ font-sans→ font-sans
--kz-font-monofontMonoTags, captions, footnotes, code"Courier Prime", "Courier New", monospace= dark

The paper (Cahier, ADR-004)

TokenNativeRoleDark (slate)Light (paper)
--kz-paper-rule-major / -minorpaperRuleMajor…The Seyès ruling: a strong line every 32 px, three fine lineschalk at 9 % / 4.5 %ink blue at 24 % / 10 %
--kz-paper-rule-marginpaperRuleMarginThe red margin line, section numbers in the margin (≥ 3:1)hsl(8 64% 66%)hsl(5 56% 47%)
--kz-paper-tag / -tag-edge / -tag-inkpaperTag…The specimen tag (manila), its edge and eyelet, its typed text (≥ 4.5:1)slate tag, chalk inkmanila, near-black ink
--kz-paper-module / --kz-paper-line—The ruling's square and line32px / 8px= dark

The material (BRAND.md §6)

TokenKeyUsageDarkLight
--kz-radius-xs, --kz-radius-2xlradiusXs, radius2xlCheckbox, key, cut badge · sheet2px, 0px= dark
--kz-shadow-raised · -floating · -overlayshadowRaised…Raised (button, card) · floating (menu, tooltip) · over the page (dialog, toast) — ink-tinted, 2–3 layers; native: shadows.<theme>.raised (boxShadow)hsl(240 30% 2% / …)hsl(232 25% 25% / …)
--kz-surface-sheensurfaceSheenThe top of a raised surface (bg-sheen)hsl(0 0% 100% / 0.045)hsl(0 0% 100% / 0.7)
--kz-fill-shadefillShadeThe bottom of an accent or status fill (bg-fill-shade)hsl(0 0% 0% / 0.12)= dark
--kz-edge-light · -on-fill · -welledgeLight…The 1-px top edge of a raised surface · of a fill · the inner shade of a well/ 0.07 · / 0.22 · ink / 0.5/ 0.9 · = · ink / 0.08
--kz-glass-bg · -border · -blurglassBg…Frosted glass: menus, popovers, dialogs, toasts (88 %: text AA over anything)hsl(240 5% 12% / 0.88)hsl(0 0% 100% / 0.88)
--kz-success-soft · warning-soft · danger-softsuccessSoft…Status tints: badges, alerts, rows/ 0.14/ 0.10–0.12
--kz-ring-width · -offset · -haloringWidth…The signature focus ring (focus-ring)2px · 2px · 4px= dark
--kz-control-sm · md · lg · fieldcontrolSm…Control heights; [data-density="compact"] tightens them32 · 40 · 48 · 44pxcompact 28 · 34 · 40 · 36px
--kz-cut-shape · --kz-cut-sizecutShape, cutSizeThe griffe: the 45° cut corner (corner-shape); round turns it off; native: cut.sizebevel · 10px= dark
--kz-ease-springeaseSpringA short spring: a press, a toggle, a selection; native motion.springcubic-bezier(0.34, 1.36, 0.64, 1)= dark
--kz-duration-instant · fast · basedurationFast…Micro-interactions ≤ 200 ms; 0 ms under prefers-reduced-motion; native motion.duration90 · 150 · 200ms= dark

Contrast is tested, not assumed: pnpm turbo run check fails if text-primary / text-secondary drop under 4.5:1 or text-muted under 3:1 on any surface, or on-accent under 4.5:1 on the accent, in either theme (WCAG 2.x). No accent can carry white text at 4.5:1 and be read at 4.5:1 as text on surface-0: the accent favours the text set on it, and accent-text (text-fg-accent) is the accent for words — tested at 4.5:1 on every surface.

Add or change a token

  1. Source — edit src/tokens/<category>.tokens.json (DTCG: $type, $value, $description).
    • $value is the dark value (the default); the light value goes in "$extensions": { "com.krizaka": { "light": … } }. No extension = the same value in both themes.
    • An alias is "{group.token}" ("{accent.$root}" for a group's own token); it compiles to var(--kz-…) and may not carry a light value — it follows its target.
    • The CSS name is the path joined with - (text.on-media → --kz-text-on-media), the JS key its camelCase (textOnMedia). Colours are hsl(); radii are px (the native output converts them to dp).
  2. Build — pnpm --filter @krizaka/tokens build writes dist/ (never edit dist/), then pnpm --filter @krizaka/tokens test: update the tokens.css snapshot only when the change is intended (vitest run -u), and keep the contrast tests green.
  3. Changeset — pnpm changeset: a new token is a minor, a changed value at least a minor (it changes every product), a removed or renamed token a major. @krizaka/tokens and @krizaka/ui are released together (fixed group).

License

Apache-2.0

版本与发布记录

@krizaka/tokens 共发布 109 个版本,首次发布于 2026/10/10;过去 12 个月发布了 109 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.80.0latest2026/11/011 天前
3.79.02026/10/312 天前
3.78.12026/10/313 天前
3.78.02026/10/313 天前
3.77.02026/10/304 天前
3.76.12026/10/304 天前

其他发布通道:beta → 2.0.0-beta.6。

关于 @krizaka/tokens 的常见问题

@krizaka/tokens 是什么?

Krizaka语义设计标记(- kz-*)和品牌主题(Krizaka, Orazaka, Yomizaka, Akinaza):一个编译为CSS的DTCG源(暗,光,媒体不变量),类型常量和React Native主题。

如何安装 @krizaka/tokens?

在项目目录运行 npm install @krizaka/tokens,或使用 pnpm add / yarn add / bun add。

@krizaka/tokens 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@krizaka/tokens 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@krizaka/tokens 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@krizaka/tokens 可以商用吗?

@krizaka/tokens 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@krizaka/tokens 还在维护吗?

最新版本 3.80.0 发布于 2026/11/01(1 天前);至今共发布 109 个版本,其中过去 12 个月发布了 109 个;首次发布于 2026/10/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。