Design system

Surfaces you could press.

Niveus is a tactile, adaptive interface language. Controls are bevelled keys with light falling across them, fields are wells cut into the surface, and glass is kept for the chrome that floats over everything else. The same components carry their hierarchy from light to dark, because nothing below is defined in terms of an appearance — only in terms of a role.

Browse components

Materials

A material answers what light does when it hits a surface. Translucency is a tool for chrome that sits over content — it is not a finish to apply everywhere.

Solid Content lives here
Elevated Separated from context
Inset Fields, wells, tracks
Frosted Bars and toolbars
Glass Contextual layers

Depth

Six levels, each describing one relationship between a surface and the canvas. A shadow outside this scale is a shadow that means nothing.

0 · Flush Painted on the canvas
1 · Resting Cards, rows, panels
2 · Raised Anything that reacts
3 · Floating Popovers and menus
4 · Lifted Dialogs and sheets
5 · Overlay The topmost layer

Color

The whole system has one input. Set a brand color and the accent, its hover and press states, the text that lands on it, the focus ring, the tint in the greys and the lean of the status colors are all re-derived — in both appearances, with nothing else to set. Try it: the page below is not reloading, and no component knows it happened.

#4f6cff
A link, too

The label on a filled control is derived, not chosen: below a lightness threshold it resolves to near-white, above it to near-black — so the yellow brand gets dark labels and the violet one light ones. The color is also nudged away from the middle of the range until its own label clears 4.5:1, which is why a mid-tone green arrives slightly deeper than the swatch you picked.

One page, several brands

data-nv-brand re-derives the set for a subtree, so a region can carry its own color without a second theme and without leaving the system.

Incidents

Its own brand

Same components, same tokens, same spacing. Only the input changed.

Billing

Its own brand

The greys inside each card carry a trace of its brand, which is what stops the accent from looking stuck on.

Labs

Its own brand

A light brand flips its own labels to dark. Nothing here asked for that.

Roles

Typography

One scale, seven roles. Sizes are in rem so the user's own font size is respected; tracking tightens as the type grows.

Display --nv-font-display · 38px
Heading --nv-font-heading · 24px
Title --nv-font-title · 17px
Body — the default reading size --nv-font-body · 15px
Label --nv-font-label · 13px
Caption — secondary and supporting --nv-font-caption · 12px
Overline --nv-font-engraved · mono, uppercase

Components

Interaction is defined once and inherited by everything: a lift on hover, a sink on press, the same focus ring on every surface.

Button

Input

Visible to everyone in the workspace.
@
Used for sign-in and recovery.
Use lowercase letters, numbers and hyphens.

Card

Resting

Elevation 1

The default container. Sits on the canvas with just enough separation to be read as its own surface.

Elevated

Elevation 2

New
Separated from its context. Use when a card needs to be read before the content around it.

Interactive

Hover and press me

Rises on hover and sinks on press, using the same displacement tokens as a button.

Inset

Recessed

For regions that belong to their parent rather than floating above it — summaries, wells, empty states.

Navigation

  1. Workspace
  2. Projects
  3. Northern Light

Overview

A sidebar scrolls with its frame, so it is not chrome and drops the translucency. The bar at the top of this page is chrome, and keeps it.

Window

Appearance

Style

Inactive — hover the lights

A window without focus greys its lights and steps back one elevation. The lights take their color back the moment the pointer reaches them.

Dialog

Continuity

Every change should read as a continuation of the state before it. When something moves, grows, collapses or changes appearance, the change itself should be perceptible — where it came from, where it went, and why. The goal is not to animate everything; it is that nothing pops into a new state the user could have watched it reach.

Emphasis travels

The selected item does not lose its material so another can gain it. The marker itself moves. Click through these — and watch the bar at the top of the page do the same thing.

Moving through one surface

Switching tabs should feel like moving along a surface, not replacing the interface. The panels travel in the direction you are going — forward to the right, back to the left — so the strip has a geography you can remember.

Activity

The outgoing panel leaves towards where you came from while the incoming one arrives from where you are going. Both happen inside the same box, so the surface never appears to be rebuilt.

Content expands from where it is

Revealed content grows out of the row that revealed it, at its own position, instead of appearing at full height somewhere below.

How is the height animated?
The content animates to block-size: auto directly, because the continuity layer turns on interpolate-size. Nothing is measured, no height is cached, and content that changes while open stays correct.
What happens on the way back?
Collapsing is the same transition in reverse. The content stays rendered while it shrinks rather than disappearing on the first frame, so closing is as readable as opening.

Surfaces come from what opened them

A menu is anchored to its trigger and scales out of its edge. A dialog expands away from the control you pressed rather than from the middle of the screen — open the two dialogs below from buttons at opposite ends of the row and watch where each one comes from.

This project

States resolve rather than switch

Hover lifts, press sinks, focus rings fade in, marks grow out of their centre, and the switch thumb travels the track. Every one of these is a state the user can watch arrive.

Patterns

Components are the vocabulary; patterns are the sentences. Each of these is built only from what the system already ships — no new colors, no new shadows, no new spacing. If a pattern needs something the system does not have, that is a finding about the system, not a reason to write a one-off.

A row that continues past its frame

The edges fade instead of cutting, so the row reads as running underneath them, and each card snaps to the same place every time — moving left and right returns you to positions you have already seen. Scroll it with a trackpad or use the controls.

Northern Light

12 projects

Snap points make a row navigable without a scrollbar.

Harbour

4 projects

Cards keep their own elevation and lift on hover.

Greenhouse

9 projects

The track itself carries no styling of its own.

Quarry

2 projects

Wheel, trackpad, touch and keyboard are the browser's.

Signal

7 projects

The buttons exist for pointers with no horizontal axis.

Ledger

1 project

At either end the control has nothing to do, and says so.

Ground that is not ordinary background

A bed marks a region as different in kind — something being shown off, previewed, or explained. It also gives translucent materials something to be translucent against: the card below is frosted, and on a flat grey that would prove nothing.

Preview

Frosted over a bed

The hatch and the blooms read through it

Use a bed for regions the user should look at. Content they have to work through — a form, a table — belongs on a plain surface, because the calm is the point.

A settings list

Rows, switches and per-row menus, composed from the same parts as everything above. Each menu names its own anchor, so it opens from its own row.

Weekly digest

A summary every Monday morning.



Frosted chrome

Translucent bars over scrolling content.


Audit log

Not available on this plan.

Using the system

An application links one stylesheet and states an appearance. It never needs to know the values behind either.

<link rel="stylesheet" href="dist/niveus.css"> <html data-theme="dark"> <!-- omit to follow the system --> .thing { background: var(--nv-color-surface-elevated); border-radius: var(--nv-radius-lg); padding: var(--nv-space-4) var(--nv-space-5); box-shadow: var(--nv-highlight-top), var(--nv-elevation-2); }

A surface above the page

The dialog rises and settles; the scrim blurs what is behind it. Both are motion tokens, not per-component choices.

Escape closes it, focus is trapped inside it and the page behind is inert — all of that comes from the native <dialog> element rather than from script.

Sheet

Anchored to the block end, entering from the same direction.

The right form on a small screen for anything with more than two actions.

Delete workspace?

This removes every project inside it. It cannot be undone.