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

60
niveus/components/skeleton.css vendored Normal file
View file

@ -0,0 +1,60 @@
/* ==========================================================================
Niveus — Skeleton
--------------------------------------------------------------------------
<span class="nv-skeleton nv-skeleton--text"></span>
The shape of content that has not arrived yet. A skeleton is a shallow well
cut where the content will sit, with a slow band of light crossing it — the
surface is recessed and waiting, not broken.
.nv-skeleton a block; size it with the layout
.nv-skeleton--text one line of body text
.nv-skeleton--circle an avatar or a tile
Under reduced motion the light stops crossing and the well stays: the state
is still legible, it just does not move.
========================================================================== */
.nv-skeleton {
display: block;
min-block-size: var(--nv-space-4);
border-radius: var(--nv-radius-md);
background-color: var(--nv-color-surface-inset);
background-image: linear-gradient(
100deg,
transparent 30%,
var(--nv-color-sheen-top) 50%,
transparent 70%
);
background-size: 220% 100%;
box-shadow: var(--nv-elevation-inset-sm), var(--nv-ledge);
animation: nv-shimmer var(--nv-duration-shimmer) var(--nv-ease-linear) infinite;
}
.nv-skeleton--text {
inline-size: 100%;
min-block-size: 0;
block-size: 0.75em;
border-radius: var(--nv-radius-full);
}
/* A paragraph of skeleton lines ends short, like the paragraph it stands for. */
.nv-skeleton--text:last-child:not(:first-child) {
inline-size: 60%;
}
.nv-skeleton--circle {
aspect-ratio: 1;
border-radius: var(--nv-radius-full);
}
@keyframes nv-shimmer {
from { background-position: 100% 0; }
to { background-position: -120% 0; }
}
@media (prefers-reduced-motion: reduce) {
.nv-skeleton {
animation: none;
}
}