mirror of
https://github.com/Nexoniarz/Niveus.git
synced 2026-11-03 04:34:26 +00:00
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>
124 lines
5.7 KiB
CSS
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);
|
|
}
|