Product UI with a point of view.
Motion-native React components for SaaS — themes that change material and mood, glass that behaves, accessibility that ships with the control.
Live specimen
Real controls, not screenshots. Press one.
Identity
Themes with a point of view.
Six curated packs. Compatible modes only. No fake dark mode bolted onto a light palette.
Ember
Dark-only heat for night ops and focused editing.
Modes · dark
Live product
The same tokens, on an actual desk.
Every control on this desk is a shipped component. Switch the theme anywhere on this page and the whole surface repaints — Theme Lab is the gallery, this is the app.
Northline
Ops desk
Routed jobs · 24h
94,817
p95 latency
211ms-14ms
Error rate
0.21%-0.04pt
Jobs routed per 3h window
thousands
Live stream
4 events
Canary 9% healthy
Edge cluster · us-east
Invoice export settled
Ledger close · FY26 Q1
Ingest backlog eased
Queue 3,104 → 886
Nightly checksum
Retention window OK
Theme Studio
Guardrails are the product.
Seed an accent from a prompt, a stylesheet, or a logo. The engine derives the whole token ladder, raises anything that fails contrast, and tells you exactly what it changed. No free-form CSS, no palette that looks fine until someone tries to read it.
Derived token ladder — live on the theme you picked
- --kp-background
- Page base
- --kp-surface
- Panels
- --kp-surface-raised
- Menus, dialogs
- --kp-muted
- Quiet structure
- --kp-muted-foreground
- Secondary text
- --kp-foreground
- Body text
- --kp-accent
- Action
- --kp-accent-foreground
- On accent
- --kp-ring
- Focus
- --kp-danger
- Destructive
01
Seed
Describe it, paste a stylesheet, or drop a logo. Offline heuristics always run; bring your own key when you want a model in the loop.
02
Derive
One accent becomes surfaces, muted layers, borders, ring, and foregrounds — with every pair checked against WCAG AA before it ships.
03
Ship
Download a drop-in CSS pack. Tailwind @theme, Style Dictionary, and Figma variables come out of the same engine.
Catalog
Thirty-seven built, none of them filler.
Every entry ships docs, keyboard notes, states, registry metadata, and a generated JavaScript variant. No component lands as a screenshot.
- 01FormsText, area, number, search, password, OTP, group, upload, checkbox, radio, switch, slider, form14
- 02Data displayTable, data table, badge, sparkline, line, area, bar7
- 03OverlaysDialog, drawer, popover, tooltip, toast5
- 04PickersSelect, combobox, date picker, menu4
- 05FeedbackProgress, skeleton, spinner3
- 06ActionsButton, link2
- 07NavigationTabs, breadcrumbs2
Motion
Presence without noise.
Springs on interaction. Layout moves when order changes. Infinite loops stay isolated — and reduced motion always wins.
Motion on — perpetual demos running
Priority loop — reordering with layout transitions
Live- 01
Normalize ledger feed
Queue · 3,104 rows
- 02
Flag 12.4% drift
Ledger close · FY26 Q1
- 03
Publish ops digest
Edge cluster · us-east
Material
Glass with refraction, not a blur filter.
One global choice. Pick a half — the whole page changes with it. Tint, saturation, an inner edge light, and an opaque fallback when the browser can't blur.
States
The states other sites forget.
Loading, empty, error, and validation are not docs footnotes — they are the product people actually touch.
loading — Skeletons mirror the final layout — no spinner roulette.
- aria-busy announced
- Layout space reserved
- No cumulative shift
Accessibility
Keyboard is a first-class surface.
React Aria owns behavior. Komponents keeps focus visible, hit targets honest, and reduced motion respected — not a late audit checklist.
- Tab
- Move focus
- Shift Tab
- Move back
- Space
- Activate
- Esc
- Dismiss
- ↑ ↓
- Traverse
- Home End
- Jump to edges
Tab through this row.
The ring is intentional.
House rules
Shipping the same indigo accent and calling it a theme is a swap, not an identity. Identity changes material, density, and mood.
Ownership
One source. Two ways in.
Canonical TypeScript in the package. npm when you want speed, CLI copy when you need to own the pixels — and the same API either way.
import { Button, TextField } from "@komponents/ui";
<TextField
label="Workspace slug"
description="Lowercase letters, numbers, hyphens."
isInvalid={!valid}
errorMessage="That slug is taken."
/>
<Button onPress={save}>Save workspace</Button>Install from npm
Tree-shakeable subpaths. Keep behavior and tokens in sync.
Copy typed source
CLI drops canonical TSX into your app when you need ownership.
Next
Build with taste, ship with proof.
Read the docs, stress-test Theme Lab, or jump straight into the component gallery.