neutron-design-system
Shared UI for app frontends. Importing it makes an app look like it belongs in the Neutron shell without giving it any of the shell's authority.
The visual policy
The rules are narrow on purpose — they exist so that dozens of independently authored apps read as one system.
- Dark only. There is no light theme.
- Near-black neutral surfaces, a restrained green action colour, cyan focus.
- No gradients. No remote fonts.
- Radius capped at
4pxin the public tokens. - Separation by tonal fill, not visible borders. Routine surfaces, controls, inputs, rows, and state blocks are distinguished by fill.
- Structural separation uses stable one-pixel inset hairlines, never perimeter component borders.
- Focus is a single visible hairline outline.
- Spacing follows a public 4/8/12/16/20/24/32px rhythm.
A recurring instruction: keep operational surfaces unframed on the page background. Do not turn every section into a card.
Scope and cascade
Everything is scoped under .nt-app and organised into cascade layers, so an
app's own styles can override the system predictably without fighting
specificity.
@use 'neutron-design-system/styles.scss';
@layer nt.tokens, nt.base, nt.layout, nt.components, nt.utilities, app;
@layer app {
.nt-app.my-app {
--nt-accent: #8adf9d;
}
}
<main class="nt-app nt-app--fill my-app">
<section class="nt-panel">
<h1 class="nt-title">My app</h1>
<button class="nt-button">Review in kernel</button>
</section>
</main>
Apps compose with app-prefixed classes. Rewriting nt-* component classes,
or styling kernel workspace classes from inside an app frame, is out of bounds.
Entrypoints and class helpers
neutron-design-system/styles.scss is the complete stylesheet. The package
also exports tokens.scss, base.scss, layout.scss, and components.scss
for narrower composition.
The TypeScript entrypoint exports cx(), toneClass(), sizeClass(), and the
nt class-name map, plus the Tone, Size, and ClassValue types.
import {cx, nt, toneClass} from 'neutron-design-system';
const rootClass = cx(nt.app, 'my-app');
const alertClass = toneClass(nt.alert, 'warning');
Representative class groups are:
| Area | Classes |
|---|---|
| Layout | nt-app, nt-page, nt-pane, nt-stack, nt-grid, nt-section |
| Typography | nt-title, nt-subtitle, nt-text, nt-meta, nt-code |
| Controls | nt-button, nt-icon-button, nt-segmented, nt-tab |
| Forms | nt-field, nt-input, nt-textarea, nt-select, nt-checkbox, nt-radio |
| Data | nt-table, nt-table-wrap, nt-copy-field, nt-json, nt-pre, nt-kv |
| Operational | nt-detail-grid, nt-settings-list, nt-settings-row, nt-disclosure |
| Status | nt-metric, nt-tag, nt-tag-list, nt-alert, nt-state |
| Overlay | nt-dialog |
Accessibility is part of the contract
The package ships an accessibility matrix pairing every class with its intended element or role, its name source, its state attributes, and its keyboard behaviour. Two points recur:
- Tooltip text is not an accessible name. Icon buttons need
aria-labelor hidden text. - Native elements do the work.
nt-buttonis a real<button>,nt-checkboxwraps a real input,nt-dialogis a native<dialog>or a named grouped panel witharia-labelledby.
role="alert" is reserved for urgent inserted errors, and aria-sort appears
only when a table actually sorts.
The one hard security rule
App UI must not imitate the kernel's trusted approval, install, authorization, or signature dialogs.
App frames are isolated from kernel chrome, but an app can still draw something
that looks trusted. The design system's recommended wording for a call that
needs consent is deliberately deferential, e.g. a button labelled
Review in kernel, so the app is visibly handing off rather than appearing to
decide.
Destructive flows should use explicit consequence text at warning, danger, or critical severity. The actual approval remains kernel-owned.
Build setup
The package ships SCSS, so an app's frontend build needs a Sass plugin and the app's HTML links the generated CSS as a package-local asset.
Reference implementation
Kitchen Sink is the living reference for forms, typed calls, schema display, alerts, warning and danger states, dense inspectors, and narrow-tile behaviour. It is also the package's test surface.