Niveus/niveus/tokens/elevation.css
Nexoniarz 7908c55245 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>
2026-10-18 22:59:25 +02:00

124 lines
5.7 KiB
CSS

/* ==========================================================================
Niveus — Elevation
--------------------------------------------------------------------------
Depth is a scale, not a free choice. Each level describes one relationship
between a surface and what sits behind it:
0 flush painted on the canvas, no separation
1 resting cards, list rows, static panels
2 raised buttons, controls, anything that reacts to a pointer
3 floating popovers, menus, dropdowns, tooltips
4 lifted dialogs, sheets, detached panels
5 overlay the topmost layer, used sparingly
Every level is built from the same three shadow colors so depth stays
consistent between appearances: an ambient contact shadow that keeps the
edge crisp, a soft penumbra for the spread, and an umbra that only appears
once a surface is genuinely far from the canvas.
========================================================================== */
:root {
--nv-elevation-0: none;
--nv-elevation-1:
0 1px 1px var(--nv-color-shadow-ambient),
0 2px 4px -1px var(--nv-color-shadow-penumbra),
0 6px 14px -8px var(--nv-color-shadow-umbra);
--nv-elevation-2:
0 1px 1px var(--nv-color-shadow-ambient),
0 3px 6px -2px var(--nv-color-shadow-penumbra),
0 10px 20px -10px var(--nv-color-shadow-umbra);
--nv-elevation-3:
0 1px 2px var(--nv-color-shadow-ambient),
0 6px 12px -4px var(--nv-color-shadow-penumbra),
0 18px 36px -12px var(--nv-color-shadow-umbra);
--nv-elevation-4:
0 1px 2px var(--nv-color-shadow-ambient),
0 10px 20px -6px var(--nv-color-shadow-penumbra),
0 30px 60px -16px var(--nv-color-shadow-umbra);
--nv-elevation-5:
0 2px 3px var(--nv-color-shadow-ambient),
0 16px 32px -8px var(--nv-color-shadow-penumbra),
0 44px 88px -20px var(--nv-color-shadow-umbra);
/* --- Inset ---------------------------------------------------------------
Recessed surfaces: fields, wells, tracks, pressed controls. */
--nv-elevation-inset-sm: inset 0 1px 2px var(--nv-color-shadow-inset);
--nv-elevation-inset-md:
inset 0 1px 1px var(--nv-color-shadow-inset),
inset 0 3px 6px -2px var(--nv-color-shadow-inset);
--nv-elevation-inset-lg:
inset 0 2px 3px var(--nv-color-shadow-inset),
inset 0 6px 12px -3px var(--nv-color-shadow-inset);
/* --- Highlight -----------------------------------------------------------
The thin catch of light along the top edge of a raised surface. This is
what makes Niveus read as material rather than as a rectangle with a
shadow. Always paired with an elevation, never used alone. */
--nv-highlight-top: inset 0 1px 0 var(--nv-color-highlight);
--nv-highlight-top-strong: inset 0 1px 0 var(--nv-color-highlight-strong);
--nv-highlight-edge:
inset 0 1px 0 var(--nv-color-highlight),
inset 0 0 0 1px var(--nv-color-border-subtle);
/* --- Bevel -----------------------------------------------------------------
The highlight's other half. A raised face is lit along its top edge and
shaded along its bottom one; together they are the bevel, and the bevel is
what makes a Niveus control look like something a finger could press.
Raised controls and surfaces take the full bevel; the highlight alone is
for things that sit flush. */
--nv-lowlight-bottom: inset 0 -1px 0 var(--nv-color-lowlight);
--nv-bevel:
inset 0 1px 0 var(--nv-color-highlight),
inset 0 -1px 0 var(--nv-color-lowlight);
/* --- Outline ---------------------------------------------------------------
The contact line: a hairline just outside a raised surface, where it meets
whatever it rests on. In dark it is near-black and does most of the
separating; in light it only softens the border beside it. */
--nv-outline: 0 0 0 1px var(--nv-color-outline);
/* --- Ledge -----------------------------------------------------------------
A recess catches light on its *lower* lip, the edge facing the viewer.
Paired with an inset shadow, it turns a field from a dark rectangle into
a well cut into the surface. */
--nv-ledge: 0 1px 0 var(--nv-color-highlight);
/* --- Focus ---------------------------------------------------------------
A contrast ring sits under the accent ring so focus stays visible on both
light and dark surfaces, and on accent-filled controls. */
--nv-focus-ring-width: 3px;
--nv-focus-ring:
0 0 0 1px var(--nv-color-focus-ring-contrast),
0 0 0 calc(1px + var(--nv-focus-ring-width)) var(--nv-color-focus-ring);
/* --- Glow ------------------------------------------------------------------
Light a surface emits rather than the shade it casts. Glow is for things
that are *on* — a live status, the selected item in a showcase, a lit key —
and it always sits beside an elevation, never instead of one: a glowing
surface still rests on something.
The geometry is a scale like elevation. The color is the component's: a
tinted surface glows in its own tint, mixed down to --nv-glow-strength. */
--nv-glow-strength: 40%;
--nv-glow-blur-sm: 12px;
--nv-glow-spread-sm: -2px;
--nv-glow-blur-md: 28px;
--nv-glow-spread-md: -6px;
--nv-glow-blur-lg: 64px;
--nv-glow-spread-lg: -12px;
}
/* The accent glows are declared on every branded subtree as well as the root:
a var() inside a custom property resolves where the property is declared, so
a root-only declaration would glow in the root brand everywhere. */
:root,
[data-nv-brand] {
--nv-glow-sm: 0 0 var(--nv-glow-blur-sm) var(--nv-glow-spread-sm) var(--nv-color-glow);
--nv-glow-md: 0 0 var(--nv-glow-blur-md) var(--nv-glow-spread-md) var(--nv-color-glow);
--nv-glow-lg: 0 0 var(--nv-glow-blur-lg) var(--nv-glow-spread-lg) var(--nv-color-glow);
}