Foundation

Color

Nerio color starts with immutable primitives, resolves through semantic intent, and reaches components through local aliases. Choose complete foreground, background, state, and accessibility contracts—not isolated swatches.

Color architecture

LayerResponsibility
PrimitiveRaw opaque and alpha color scales. They are immutable across theme, mode, and density selectors and are inputs to semantic roles, not product UI choices.
SemanticReusable intent such as canvas, primary text, focus ring, danger status, or primary action. Product composition consumes this layer.
ComponentLocal contracts such as Button background or Input border. Components consume semantic or component aliases, never primitive palette values directly.
RuntimeTheme changes accent personality, mode changes light/dark color mappings, and density changes spacing only. Density never redefines color primitives.

The generated inventories below come from packages/tokens/src/styles.css via the accepted foundation metadata contract. Editorial recommendations remain hand-authored. See Themes for runtime-axis composition.

Primitive families

Opaque neutral and accent scales provide predictable raw values. Dark alpha neutrals adapt light-mode layers; light alpha neutrals adapt dark-mode layers. Alpha primitives composite with the surface below them, so a swatch alone cannot establish the final color or contrast.

Opaque neutral

--n-gray-0
--n-gray-50
--n-gray-100
--n-gray-200
--n-gray-300
--n-gray-400
--n-gray-500
--n-gray-600
--n-gray-700
--n-gray-800
--n-gray-900
--n-gray-950
--n-gray-1000

Dark alpha neutral

--n-gray-a-4
--n-gray-a-6
--n-gray-a-8
--n-gray-a-10
--n-gray-a-12
--n-gray-a-16
--n-gray-a-20
--n-gray-a-24

Light alpha neutral

--n-white-a-4
--n-white-a-6
--n-white-a-8
--n-white-a-10
--n-white-a-12
--n-white-a-16
--n-white-a-20
--n-white-a-24

Purple

--n-purple-50
--n-purple-100
--n-purple-200
--n-purple-300
--n-purple-400
--n-purple-500
--n-purple-600
--n-purple-700
--n-purple-800
--n-purple-900
--n-purple-950

Blue

--n-blue-50
--n-blue-100
--n-blue-200
--n-blue-300
--n-blue-400
--n-blue-500
--n-blue-600
--n-blue-700
--n-blue-800
--n-blue-900
--n-blue-950

Green

--n-green-50
--n-green-100
--n-green-200
--n-green-300
--n-green-400
--n-green-500
--n-green-600
--n-green-700
--n-green-800
--n-green-900
--n-green-950

Orange

--n-orange-50
--n-orange-100
--n-orange-200
--n-orange-300
--n-orange-400
--n-orange-500
--n-orange-600
--n-orange-700
--n-orange-800
--n-orange-900
--n-orange-950

Red

--n-red-50
--n-red-100
--n-red-200
--n-red-300
--n-red-400
--n-red-500
--n-red-600
--n-red-700
--n-red-800
--n-red-900
--n-red-950

Amber

--n-amber-50
--n-amber-100
--n-amber-200
--n-amber-300
--n-amber-400
--n-amber-500
--n-amber-600
--n-amber-700
--n-amber-800
--n-amber-900
--n-amber-950

Cyan

--n-cyan-50
--n-cyan-100
--n-cyan-200
--n-cyan-300
--n-cyan-400
--n-cyan-500
--n-cyan-600
--n-cyan-700
--n-cyan-800
--n-cyan-900
--n-cyan-950

Magenta

--n-magenta-50
--n-magenta-100
--n-magenta-200
--n-magenta-300
--n-magenta-400
--n-magenta-500
--n-magenta-600
--n-magenta-700
--n-magenta-800
--n-magenta-900
--n-magenta-950

Semantic role families

Product UI consumes semantic roles. The inventory includes canvas, default, subtle, sunken, raised, overlay, control, selected, hover, and active surfaces; text and borders; complete action and focus roles; status and trend roles; and the general chart boundary.

The shared action family implements a primary default/hover/active sequence, secondary default/hover roles, a transparent tertiary role, and an on-primary foreground. The destructive Button sequence is a component contract backed by danger status and on-danger text roles; do not invent a parallel primitive or undocumented semantic role.

FamilyCanonical roles
Surface
--n-color-surface-canvas--n-color-surface-default--n-color-surface-control--n-color-surface-control-hover--n-color-surface-control-active--n-color-surface-subtle--n-color-surface-sunken--n-color-surface-raised--n-color-surface-overlay--n-color-surface-selected--n-color-surface-muted
Text
--n-color-text-primary--n-color-text-secondary--n-color-text-tertiary--n-color-text-disabled--n-color-text-inverse--n-color-text-on-danger
Border
--n-color-border-subtle--n-color-border-default--n-color-border-strong--n-color-border-interactive--n-color-border-focus--n-color-border-danger
Action
--n-color-action-primary--n-color-action-primary-hover--n-color-action-primary-active--n-color-action-on-primary--n-color-action-secondary--n-color-action-secondary-hover--n-color-action-tertiary
Focus
--n-color-focus-ring--n-color-focus-offset--n-color-focus-ring-soft
Status
--n-color-status-success--n-color-status-success-soft--n-color-status-success-strong--n-color-status-warning--n-color-status-warning-soft--n-color-status-warning-strong--n-color-status-danger--n-color-status-danger-soft--n-color-status-danger-strong--n-color-status-info--n-color-status-info-soft--n-color-status-info-strong--n-color-status-neutral--n-color-status-neutral-soft--n-color-status-neutral-strong--n-color-danger--n-color-success
Trend
--n-color-trend-positive--n-color-trend-negative--n-color-trend-pending--n-color-trend-locked--n-color-trend-verified--n-color-trend-unverified--n-color-trend-risk
Chart
--n-chart-primary--n-chart-comparison--n-chart-grid--n-chart-axis--n-chart-tooltip--n-chart-selection--n-chart-categorical-1--n-chart-categorical-2--n-chart-categorical-3--n-chart-categorical-4--n-chart-categorical-5

Representative mode mappings

RoleSystem darklightdark
--n-color-surface-control--n-white-a-8--n-gray-a-6--n-white-a-8
--n-color-text-primary--n-gray-50--n-gray-950--n-gray-50
--n-color-border-default--n-white-a-16--n-gray-a-10--n-white-a-16
--n-color-status-success--n-green-400--n-green-600--n-green-400
--n-chart-grid--n-white-a-10--n-gray-a-10--n-white-a-10

Representative component aliases

Component contractSemantic source
--n-button-background-primary--n-color-action-primary
--n-button-foreground-primary--n-color-action-on-primary
--n-button-background-destructive--n-color-danger
--n-button-foreground-destructive--n-color-text-on-danger
--n-input-background--n-color-surface-control
--n-input-bordertransparent
--n-badge-background-success--n-color-status-success-soft
--n-badge-foreground-success--n-color-status-success

Chart series, axes, grids, tooltips, cursors, and data-specific fallback policy belong to the Chart foundation issue. This page documents only the shared color-role boundary.

Pairing and interaction states

Evaluate the rendered pair and its context. Use translucent roles for adaptive control, hover, selected, border, and grouping layers on supported surfaces. Use opaque roles when the foreground needs isolation, the background is unknown, or compositing would make the result unpredictable.

CompositionPairReview
Primary action--n-color-action-primary + --n-color-action-on-primaryReview the foreground on default, hover, and active backgrounds; keep one clear local primary action.
Neutral control--n-color-text-primary + --n-color-surface-controlAlpha-neutral control layers intentionally composite over supported surfaces. Test the pair on canvas, default, and grouped surfaces.
Status treatment--n-color-status-*-soft + neutral text + icon or labelUse soft backgrounds for routine feedback. Keep visible wording or iconography so hue is not the only carrier of meaning.
Invalid control--n-color-border-danger + associated error textCombine the visual boundary with aria-invalid and a programmatically associated error message.
Focus--n-color-focus-ring + --n-color-focus-offsetCheck the complete indicator against adjacent colors, including selected and invalid states.
StateReview expectation
DefaultEstablish the stable foreground/background pair and control boundary.
HoverIndicate pointer affordance without becoming the only discoverable state.
ActiveMake the pressed state distinct from hover while preserving foreground contrast.
Focus-visibleKeep a visible ring and offset even when hover, selected, or invalid also applies.
DisabledPreserve recognizability and semantics; reduced opacity is not a substitute for disabled behavior.
SelectedPair the selected surface with text, indicator, icon, or state semantics.
InvalidPair danger styling with an accessible error relationship and actionable copy.

Applied example

Real components resolve semantic roles through their component aliases. Visible labels keep action and status meaning available when color is unavailable or altered.

SelectedPublishedBlocked
import { Badge } from "@nerio-ui/ui";<div className="status-row">  <Badge tone="primary-soft">Selected</Badge>  <Badge tone="success">Published</Badge>  <Badge tone="danger">Blocked</Badge></div>

Use the Button and Badge component contracts for their full state, anatomy, and token guidance.

Accessibility

Contrast is a relationship between rendered foreground and background colors at a specific size and state. A token target cannot prove the final product composition. Review the full evidence boundary in the Accessibility foundation.

ConcernContract
Text contrastPrimary, secondary, inverse, and action text target 4.5:1. A 3:1 exception applies only when text qualifies as large under WCAG 2.2.
Non-text contrastMeaningful control boundaries, graphics, and focus indicators target 3:1 where WCAG 2.2 applies.
Color-independent meaningStatus, selection, validation, trend, and chart meaning require text, position, shape, iconography, pattern, or programmatic state in addition to hue.
Forced colorsCore preserves representative boundaries, state, and focus with system colors. Product compositions must still be tested with forced colors active.
Increased contrastReview real states with the platform preference enabled; the current contrast targets are tokens, not a data-contrast runtime axis.
Color visionNo categorical palette works for every user, display, background, or data task. Add redundant encoding and test the real visualization.
--n-contrast-text-primary: 4.5--n-contrast-text-secondary: 4.5--n-contrast-text-tertiary: 3--n-contrast-text-inverse: 4.5--n-contrast-action: 4.5--n-contrast-status: 3--n-contrast-focus-ring: 3

Custom themes

A custom theme supplies the same accent contract as every built-in theme. Coordinate selected surface, focus border and ring, the primary action sequence, on-primary foreground, and the primary chart role. Status colors remain semantic unless the product has separately validated replacements.

:root[data-theme="acme"] {  --n-color-surface-selected: var(--n-gray-a-8);  --n-color-border-focus: #0f766e;  --n-color-action-primary: #0f766e;  --n-color-action-primary-hover: #115e59;  --n-color-action-primary-active: #134e4a;  --n-color-action-on-primary: #ffffff;  --n-color-focus-ring: #0f766e;  --n-color-focus-ring-soft: rgb(15 118 110 / 0.24);  --n-chart-primary: #0f766e;  --n-chart-categorical-1: #0f766e;}:root[data-theme="acme"][data-mode="dark"] {  --n-color-surface-selected: var(--n-white-a-10);  --n-color-border-focus: #5eead4;  --n-color-action-primary: #5eead4;  --n-color-action-primary-hover: #2dd4bf;  --n-color-action-primary-active: #14b8a6;  --n-color-action-on-primary: #042f2e;  --n-color-focus-ring: #5eead4;  --n-color-focus-ring-soft: rgb(94 234 212 / 0.32);  --n-chart-primary: #5eead4;  --n-chart-categorical-1: #5eead4;}@media (prefers-color-scheme: dark) {  :root[data-theme="acme"][data-mode="system"] {    --n-color-surface-selected: var(--n-white-a-10);    --n-color-border-focus: #5eead4;    --n-color-action-primary: #5eead4;    --n-color-action-primary-hover: #2dd4bf;    --n-color-action-primary-active: #14b8a6;    --n-color-action-on-primary: #042f2e;    --n-color-focus-ring: #5eead4;    --n-color-focus-ring-soft: rgb(94 234 212 / 0.32);    --n-chart-primary: #5eead4;    --n-chart-categorical-1: #5eead4;  }}

Built-in accent projection

ThemeLight actionDark actionSystem-dark action
Purple--n-purple-600--n-purple-500--n-purple-500
Blue--n-blue-600--n-blue-500--n-blue-500
Green--n-green-600--n-green-600--n-green-600
Orange--n-orange-700--n-orange-700--n-orange-700
Red--n-red-600--n-red-500--n-red-500
Neutral--n-gray-950--n-gray-50--n-gray-50

Validation matrix

DimensionCoverage
ThemesDefault purple plus the custom data-theme value.
ModesExplicit light, explicit dark, system with OS light, and system with OS dark.
DensityComfortable and compact; density must not change color primitives or semantic meaning.
StatesDefault, hover, active, focus-visible, disabled, selected, invalid, and loading where applicable.
ComponentsButtons, links, fields, selection controls, overlays, status treatments, and representative chart surfaces.
PreferencesForced colors, increased contrast, reduced motion where color changes accompany motion, and real display settings.
ContentLong labels, errors, real data, icons, meaningful graphics, and empty or dense states.

Treat changed roles as a migration: document the new owner, compare before and after in real components, preserve aliases during compatibility windows, and rerun token, docs, browser, visual, and product accessibility evidence.

Do / do not

GuidanceRecommendation
DoChoose --n-color-surface-selected for selected product UI.
DoPair a danger border with an error message and invalid semantics.
Do notUse --n-purple-600 directly because it resembles the desired accent.
Do notCopy a light-mode action or chart value into dark mode without testing its pair and states.
Do notAssume categorical hue alone makes a chart or status understandable.

Review checklist

  • Choose a semantic role by intent; never select a primitive because its swatch looks close.
  • Review the foreground/background pair on every surface where it can appear.
  • Exercise default, hover, active, focus-visible, disabled, selected, and invalid states together.
  • Confirm status, validation, selection, trend, and chart meaning remains available without color.
  • Test light, dark, system-light, and system-dark modes in the default and custom themes.
  • Check focus visibility, text and non-text contrast, forced colors, and increased contrast.
  • Validate alpha-neutral layers over every supported underlying surface; use opaque roles when isolation or predictable contrast is required.
  • Record product-specific and visualization-specific evidence instead of treating Core token targets as a compliance guarantee.

Known boundary: Nerio provides shared roles, mappings, targets, forced-colors fallbacks, and representative evidence. The consumer owns brand values, custom-theme validation, product meaning, real content, and product-level compliance. Nerio does not currently expose a contrast runtime axis, theme editor, or complete visualization color policy.