nalarx-ui

Foundations

The product UI rules every item follows, condensed from nalarx-frontend DESIGN.md.

Condensed from nalarx-frontend/DESIGN.md at 6ece50f98 (2026-11-12). That file is the owner of these rules; when the two disagree, it wins and this page gets updated.

Who we design for

Business people: owners, finance, sales and operations leads. They do not know the technology and do not like reading.

  • Use their words. "Net sales", never "metric", "source" or "schema".
  • One decision per step, 2 to 4 options, the recommended one marked.
  • Show the outcome before saving, and make every answer reversible.
  • A number never stands alone. Say what it is compared with and what that means.
  • Before adding anything, ask whether the user would act differently because of it.

Principles

  1. Neutral first. Ink and surfaces carry almost every screen. Colour means an action, a status or a data series.
  2. Orange once. One primary action per screen, dialog or step uses the accent. Selected tabs, pills, progress and links stay neutral.
  3. One way per role. One type size per role, one control height per context, one radius per kind of surface.
  4. Hierarchy from tone. Surfaces separate by bg, bg-elev, bg-sunken and a 0.5px hairline. Shadows only on overlays.
  5. Dense but readable. Body text 13px, rows 32 to 36px, tabular numbers, WCAG AA everywhere.
  6. Compose from atoms. A new feature arranges existing items. A genuinely new pattern becomes an item here.

Colour

A typical screen is 60% or more surface, about 20% ink, 10% or less data colour, 5% or less status, and 2% or less action. The selected state is an ink border plus bg-hover, never orange. Links are ink with an underline. A status label is a neutral chip with a coloured dot. Destructive buttons use --danger-bg, because --err is tuned as text and is too light for white text. Literal hex is allowed only for logos, email, generated images, global-error, mask gradients, the themeColor meta, and charts reading a token with a hex fallback. See Tokens for every value.

Type

Manrope for all UI, IBM Plex Serif Light only for the display role. Weights are 400, 500 and 600, plus 300 for display. Hierarchy comes from size, weight and ink level, never colour.

  • Multi-line text uses text-wrap: pretty (set once on body by base).
  • Chips, buttons, tabs, labels, numbers and dates stay on one line and truncate with a tooltip.
  • Titles clamp at 2 lines. Inputs wrap normally.
  • Every flex or grid column holding text gets min-width: 0.

Spacing, radius, elevation

Spacing follows a 4px grid (4, 8, 12, 16, 20, 24, 32, 48): 4 to 8 inside controls, 12 to 16 inside cards, 12 between cards, 32 to 48 between sections. A shape inside a shape stays concentric. Borders are 0.5px --line; inputs and active outlines use --line-strong. A scrolling row needs at least 2px of inner padding so focus rings are not clipped.

Motion

Motion explains a change; it never decorates. 120ms for hover and press, 220ms for indicators and entrances, 340ms for larger panels, one --ease-out curve, nothing over 350ms, no bounce, no loops. Every duration drops to 0 under reduced motion. Buttons dip to 0.97 while pressed (.nx-press), and a row the user just changed gets .nx-flash for one cycle.

Icons

One outline set at stroke 1.5, sizes 12, 14, 16 and 20. Colour follows the text. Brand logos only for connectors and channels. No sparkle icons for AI and no icons in coloured circles.

Accessibility

Text meets 4.5:1 on every surface in both themes; controls and focus rings meet 3:1. Every control works with Tab, Enter, Space and Esc and has an accessible name. Focus is visible, trapped in dialogs and returned on close. Nothing is shown only on hover.

Done means

A non-technical person can explain the screen in one sentence. At most one orange button. Loading, empty and failed states exist and the failed state offers a way out. Only tokens and items are used. Checked in light, dark and at narrow widths.

On this page