Add depth and light: glow, tiles, avatars, stats, steps, decks, skeletons, reveal

Tokens
- --nv-color-glow role (light and dark) and a glow scale: --nv-glow-sm/md/lg,
  --nv-glow-blur-*, --nv-glow-spread-*, --nv-glow-strength
- --nv-stagger (0ms under reduced motion) and --nv-duration-shimmer

Components
- Card: --lit (lit top edge in --nv-card-tint), --glow, --spotlight
  (light follows the pointer); light layers combine with every elevation
- Tile: small raised key for a glyph or product mark; --solid, --glow, sizes
- Avatar: raised disc with --ring / --glow, sizes, __status, avatar group
- Stat: readings set into one recessed well (.nv-stat-group)
- Steps: markers set into a rail; done steps light their stretch; vertical
- Deck: one surface in front of stacked layers of its kind
- Skeleton: recessed placeholder with a slow sweep, still under reduced motion
- Text: .nv-text-lit and .nv-text-lit--accent

Continuity
- .nv-reveal / .nv-reveal-group: content arrives once as it scrolls into view
  (nv-arrive keyframe); niveus.js marks pending state, so nothing is hidden
  without the script or under reduced motion
- niveus.js tracks the pointer for .nv-card--spotlight

README and REFERENCE document every new class, token and attribute;
tools/check.py passes and dist/ is rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-10-18 22:59:25 +02:00
commit 7908c55245
19 changed files with 1619 additions and 14 deletions

View file

@ -0,0 +1,74 @@
/* ==========================================================================
Niveus — Stat
--------------------------------------------------------------------------
<dl class="nv-stat-group">
<div class="nv-stat">
<dt class="nv-stat__label">Servers</dt>
<dd class="nv-stat__value">1,204</dd>
</div>
</dl>
A number the user is meant to read at a glance. A group of stats is set into
one shallow well, like the readout panel of an instrument: the figures sit
behind the surface, separated by hairlines, so a row of numbers reads as one
display instead of as four loose labels.
.nv-stat-group the readout well; wraps without a media query
.nv-stat one reading
.nv-stat__label what is measured
.nv-stat__value the figure, in tabular numerals
.nv-stat__delta change since last time; --up / --down
========================================================================== */
.nv-stat-group {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(8rem, 100%), 1fr));
/* The hairlines between readings are the well itself showing through a
one-pixel gap, so they stay continuous however the row wraps. */
gap: var(--nv-border-width);
margin: 0;
background-color: var(--nv-color-border-subtle);
border: var(--nv-border-width) solid var(--nv-color-border-subtle);
border-radius: var(--nv-radius-lg);
box-shadow: var(--nv-elevation-inset-md), var(--nv-ledge);
overflow: hidden;
}
.nv-stat {
display: flex;
flex-direction: column;
gap: var(--nv-space-1);
min-inline-size: 0;
padding: var(--nv-space-4) var(--nv-space-5);
}
.nv-stat-group > .nv-stat {
background-color: var(--nv-color-surface-inset);
}
.nv-stat__label {
font: var(--nv-font-caption);
color: var(--nv-color-text-tertiary);
}
.nv-stat__value {
margin: 0;
font: var(--nv-font-heading);
font-variant-numeric: tabular-nums;
letter-spacing: var(--nv-letter-spacing-tight);
color: var(--nv-color-text-primary);
}
.nv-stat__delta {
font: var(--nv-font-caption);
font-variant-numeric: tabular-nums;
color: var(--nv-color-text-secondary);
}
.nv-stat__delta--up {
color: var(--nv-color-success);
}
.nv-stat__delta--down {
color: var(--nv-color-danger);
}