The jixoai design language, distributed as a shadcn registry. Terminal / neo-brutalist, mono-first, OKLCH token law with one brand hue per project. Everything here graduated from production work on unipty and openspecui.
Orthogonal intents (2026-08-20): design-language registry; consumer ergonomics; Owner hosting. The registry is the source of truth; the docs site (later,
apps/) only browses it.
Add the namespace to your components.json, then add items:
npx shadcn add @jixoai/press-buttonregistry:ui items are utility-authored against Tailwind v4 and the
jixoai token sheet. Your project needs ONE css entry in this exact
order (the theme arrives automatically via each item's
registryDependencies):
@import 'tailwindcss';
@import './lib/jixoai.css'; /* delivered by @jixoai/jixoai-theme */
/* optional: @import './lib/jx-pure.css'; — the componentless face */Plus tailwindcss + @tailwindcss/vite (v4) in your devDependencies
and the vite plugin wired. The check script lives in this repo
(scripts/check-tw4-prereq.mjs) — copy it or run it from a checkout
inside your project; it fails with named fixes for each missing piece.
Installed layout is FOLDER-shaped: every ui item lands under
src/lib/ui/<name>/** with a pure-barrel index.ts
(import X from '$lib/ui/<name>') and, where the design law requires
authored css, a colocated <name>.css (standard CSS only —
@layer components + :where(), order-independent via the canonical
layer prologue; consumer utilities always win over component paint).
The engine and theme items stay framework-free.
Component markup carries css-OWNED selector names as classes (state
machines, surfaces — e.g. .jx-toggle-track, .jx-sheet) and every
css-less semantic anchor as a data-jx-* attribute. Breaking
change (2026-08-25, data-jx-hooks): the old css-less .jx-* hook
classes are gone — no compatibility classes are kept. Query migration:
// before (hook-class era) // after
document.querySelector('.jx-kbd') document.querySelector('[data-jx-kbd]')
'.jx-badge-destructive' '[data-jx-badge="tonal"]' // ladder variant = valued attribute
el.classList.add('jx-foo') el.setAttribute('data-jx-foo', '')
el.classList.contains('jx-foo') el.hasAttribute('data-jx-foo')Variant families collapse into ONE valued attribute
(data-jx-badge={variant} — the ladder: fill | tonal | outline,
never a semantic hue name; error status = variant="tonal" +
jx-hue-error injection) — when a bare base hook
coexists with the family (jx-alert jx-alert-${variant}) they MERGE
into that single valued attribute ([data-jx-alert] still matches by
presence); part anchors stay boolean (data-jx-badge-title). The repo's own auditors:
scripts/jx-inventory.mjs (structured scan) and
scripts/verify-hook-law.mjs --post (fails on any css-less jx-*
token or namespace shadow).
| Item | Type | What it is |
|---|---|---|
jixoai-theme |
registry:theme |
The full OKLCH token sheet (light/dark, hard shadows, radius law, fonts) with the --brand-hue law — change ONE number per project |
toc-engine |
registry:lib |
Framework-free ToC geometry engine: IoM weights (intersection / min(block, viewport)), line pick (viewport-top line, margin resolves DOWNWARD), 76px mobile line offset |
reveal |
registry:lib |
Scroll-reveal action: static data-reveal hook law, delay/rise staggering, reduced-motion safety |
press-button |
registry:ui |
The brutalist press-physics button |
section-card |
registry:ui |
Eyebrow/title/summary content card (site grammar atom) |
terminal-header |
registry:ui |
Terminal-bar site header (brand + nav pills + theme slot) |
terminal-footer |
registry:ui |
Ghost wordmark footer |
theme-toggle |
registry:ui |
light / dark / system switcher with no-flash bootstrap |
toc |
registry:ui |
The Combo ToC: Rule Tracker desktop (spine + weight-driven nodes) + Terminal Rail mobile (glass single-row viewport, expand = height only, line-driven) |
Components are Svelte 5 first (all jixoai sites are SvelteKit); the engine
and theme are framework-free. Non-Svelte consumers can still install
jixoai-theme and toc-engine.
pnpm install
pnpm dev # the site + live registry development:
# registry/files ⇄ apps/www/src/lib mirror sync
# (edit either side, the other receives the bytes,
# vite HMR picks it up) + vite dev on :5199
pnpm dev --prod # dev server in production mode + the
# experimental client bundle strategy (single;
# JIXOAI_BUNDLE=split|single|inline to pick)
pnpm build # full deployable artifact → public/ (site +
# /r/*.json registry payloads + llms.txt exports)
pnpm build:registry # just the shadcn payloads → public/r/*.json
bun run --bun dev # the whole chain under bun instead of node
# (runtime-transparent scripts: children spawn
# from process.execPath, nothing hardcodes node)Item sources live under registry/files/…; registry.json is the index.
Dependencies between items use registryDependencies.
- Create the GitHub repo
jixoai/ui(brand name jixoai-ui) and push (public; the central registry index only lists public namespaces, but decentralized hosting works either way — private repos need Pages on a paid plan) - Point
ui.jixoai.comCNAME at GitHub Pages (same DNS flow asunipty.jixoai.com), enable Pages on thepublic/rartifact - Decide the default
--brand-hueshipped injixoai-theme(default0, jixoai red; unipty uses165幽绿) — consumers change one number or runjixoai-ui hue <n>