Incidents
Its own brand
Design system
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.
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.
Six levels, each describing one relationship between a surface and the canvas. A shadow outside this scale is a shadow that means nothing.
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.
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.
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.
Its own brand
Its own brand
Its own brand
One scale, seven roles. Sizes are in rem so the user's own font size is respected; tracking tightens as the type grows.
Interaction is defined once and inherited by everything: a lift on hover, a sink on press, the same focus ring on every surface.
Elevation 1
Elevation 2
Hover and press me
Recessed
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.
Style
A window without focus greys its lights and steps back one elevation. The lights take their color back the moment the pointer reaches them.
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.
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.
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.
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.
Arrow keys move between tabs as well — the selection follows focus, and the direction of travel follows the keys.
Jump from here back to Activity and the movement reverses, because direction is state the transition is told about rather than a fixed animation.
Revealed content grows out of the row that revealed it, at its own position, instead of appearing at full height somewhere below.
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.
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.
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.
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.
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.
12 projects
4 projects
9 projects
2 projects
7 projects
1 project
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.
The hatch and the blooms read through it
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.
A summary every Monday morning.
Translucent bars over scrolling content.
Not available on this plan.
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);
}