docs/Website: Niveus at upstream f340d56; fonts are binary

The vendored copy of Niveus, the site's design system, brought up to
the current upstream (github.com/Nexoniarz/Niveus, 2026-10-18). The
tree under docs/Website/niveus is upstream's byte for byte.

.gitattributes says `* text eol=lf` and listed the binary types it
knew, and woff2 was not one of them: Niveus's InstrumentSans-Italic
had a CR LF pair in its compressed data, and committing it turned that
into LF and the font into garbage. woff, woff2, otf, ico, gif, webp,
pdf and wasm are binary now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-23 15:10:40 +02:00
commit a8215149a3
56 changed files with 8139 additions and 279 deletions

View file

@ -1,16 +1,28 @@
# Niveus
A calm, adaptive interface language built around clarity, depth, material and
consistency.
A tactile, adaptive interface language. Controls are bevelled keys with light
falling across them, fields are wells cut into the surface, windows are solid,
and glass is kept for the chrome that floats over everything else. Warm
graphite in dark, soft paper in light, one brand color driving both.
Niveus is a **design-system layer**, not a component library bolted onto an
application. Applications consume it; they do not redefine it. The visual rules
live here and can change without touching a line of application logic.
```html
<link rel="stylesheet" href="dist/niveus.css">
<link rel="stylesheet" href="dist/niveus.css"> <!-- with fonts/ beside dist/ -->
```
Niveus ships its own faces in `fonts/`: Instrument Sans for the interface and
JetBrains Mono for code and engraved labels, both under the SIL Open Font
License. Copy `fonts/` alongside `dist/` (or `niveus/`) and they load by
themselves.
The stylesheet uses the variable `.woff2` files. `fonts/static/` holds the
same faces as plain TrueType files at the four weights Niveus uses (400, 500,
600, 700, plus Instrument Sans italics), for native toolkits and font
configurations that pick a weight by name rather than by variable axis.
```html
<html data-theme="dark"> <!-- omit data-theme to follow the system -->
```
@ -137,6 +149,27 @@ answers how far that surface is from the canvas. They are independent.
Applied as classes: `.nv-material-frosted`, `.nv-elevation-3`. A shadow that is
on neither scale is a shadow that means nothing.
### Light
Elevation is the shade a surface casts. **Glow** is the light it gives off —
and it is reserved for things that are *on*: a live status, the plan you are
on, a finished step, the selected item in a showcase. Glow never replaces an
elevation; a glowing surface still rests on something.
| Where | How |
| ----- | --- |
| A card that belongs to something with a color | `.nv-card--lit` — a lit top edge in `--nv-card-tint` |
| The one card that is on | `.nv-card--glow` |
| A showcase card | `.nv-card--spotlight` — light follows the pointer |
| A feature icon or product mark | `.nv-tile`, `--glow` to light it |
| A person | `.nv-avatar--glow` |
| A display line | `.nv-text-lit` — type cut from the same lit material |
Glows come in the same steps as everything else (`--nv-glow-sm/md/lg`), and a
tinted surface glows in its own tint, mixed down to `--nv-glow-strength`. Two
glowing things side by side cancel each other out: if everything is lit,
nothing is.
## Continuity
Every interaction should read as a continuation of the state before it. When
@ -170,6 +203,11 @@ works; changes simply arrive rather than travel. It also wires
`[data-nv-theme]`, `[data-nv-dialog]`, `[data-nv-tabs]` and `[data-nv-close]`
so the common cases need no code at all.
Long pages can arrive in the order they were written: `.nv-reveal` rises into
place once as it scrolls into view, and `.nv-reveal-group` brings its children
in one after another, `--nv-stagger` apart. Only the script marks anything as
waiting, so without it — and under reduced motion — nothing is ever hidden.
### One rule worth knowing
A `view-transition-name` must be unique among all rendered elements, or the
@ -379,7 +417,7 @@ probably not the problem the system has.
| -------------- | --------------------------------------------------------- |
| `.nv-button` | `--primary` `--subtle` `--ghost` `--danger` `--frosted` `--float`, `--sm`/`--lg`, `--icon`, `--pill`, `--block`, `.nv-button-group` |
| `.nv-input` | with `.nv-field`, `.nv-input-group`, `.nv-select`, `.nv-checkbox`, `.nv-radio`, `.nv-switch`, `.nv-choice` |
| `.nv-card` | `--elevated` `--floating` `--inset` `--frosted` `--interactive`, `.nv-card-grid` |
| `.nv-card` | `--elevated` `--floating` `--inset` `--frosted` `--interactive`, light: `--lit` `--glow` `--spotlight`, `.nv-card-grid` |
| `.nv-dialog` | native `<dialog>`; `--sheet` `--compact` `--wide` |
| `.nv-nav` | `--vertical` `--plain` `--inline`, plus `.nv-nav-tabs`, `.nv-tab-panel` and `.nv-breadcrumbs` |
| `.nv-menu` | anchored popover with `.nv-menu-trigger`, `__item`, `__separator`, `__label`, `__shortcut` |
@ -388,6 +426,12 @@ probably not the problem the system has.
| `.nv-bed` | ground that is visibly not ordinary background; `--quiet` `--vivid` `--single` `--flush` |
| `.nv-badge` | state, not an action; `--accent` `--success` `--warning` `--danger`, `--solid` `--count` `--square` |
| `.nv-table` | inside `.nv-table-frame`; `__number` `__actions`, `--compact` `--interactive` |
| `.nv-tile` | a small raised key holding one glyph; `--solid` `--glow`, `--sm` `--lg` `--xl` |
| `.nv-avatar` | round raised disc; `--ring` `--glow`, sizes, `__status`, `.nv-avatar-group` |
| `.nv-stat` | readings set into one recessed well with `.nv-stat-group`; `__label` `__value` `__delta` |
| `.nv-steps` | markers set into a rail; `data-state="done"` lights the way, `--vertical` |
| `.nv-deck` | one surface in front of others of its kind, with `__layer` |
| `.nv-skeleton` | a waiting well with a slow sweep of light; `--text` `--circle` |
| `.nv-surface` | materials and elevation as utilities |
Variants are defined by reassigning private `--_*` properties. Interaction —
@ -413,6 +457,14 @@ python3 tools/build.py --check # fail if dist/ is stale (for CI)
python3 tools/check.py # enforce the system's own rules
```
`tools/niveus_css.py` is not a command: it is an evaluator for the subset of
CSS the token layer is written in (`oklch(from …)`, `color-mix()`,
`light-dark()`, `calc()`), with CSS Color 4 gamut mapping, plus `read_rules()`
for the component layer (which role a button's background is in each state).
Every port that cannot read CSS — Android, Qt — imports it from here to
generate its tokens and control recipes, so no platform restates a value by
hand.
`check.py` catches the failures that do not look broken: a role defined for one
appearance but not the other, a token referenced but never defined, and a
hard-coded color in a component.
@ -435,9 +487,16 @@ to the state change simply happening rather than travelling:
---
> Niveus is not about making interfaces look physical. It is about making
> digital surfaces feel understandable.
> Niveus borrows from physical things only what makes a surface easier to
> understand: a key looks pressable, a well looks like a place to put
> something, and glass means something is floating.
---
## License
Niveus is licensed under the [Apache License 2.0](LICENSE). The fonts in
`fonts/` keep their own license, the SIL Open Font License 1.1
(`fonts/OFL-*.txt`), which allows bundling them with anything.
Made by **Nexoniarz**.