Skip to main content

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 4px in 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:

AreaClasses
Layoutnt-app, nt-page, nt-pane, nt-stack, nt-grid, nt-section
Typographynt-title, nt-subtitle, nt-text, nt-meta, nt-code
Controlsnt-button, nt-icon-button, nt-segmented, nt-tab
Formsnt-field, nt-input, nt-textarea, nt-select, nt-checkbox, nt-radio
Datant-table, nt-table-wrap, nt-copy-field, nt-json, nt-pre, nt-kv
Operationalnt-detail-grid, nt-settings-list, nt-settings-row, nt-disclosure
Statusnt-metric, nt-tag, nt-tag-list, nt-alert, nt-state
Overlaynt-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-label or hidden text.
  • Native elements do the work. nt-button is a real <button>, nt-checkbox wraps a real input, nt-dialog is a native <dialog> or a named grouped panel with aria-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.