mirror of
https://github.com/Nexoniarz/Niveus.git
synced 2026-11-03 04:34:26 +00:00
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:
parent
8de6e261de
commit
7908c55245
19 changed files with 1619 additions and 14 deletions
113
niveus/components/avatar.css
Normal file
113
niveus/components/avatar.css
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* ==========================================================================
|
||||
Niveus — Avatar
|
||||
--------------------------------------------------------------------------
|
||||
<span class="nv-avatar"><img src="…" alt=""></span>
|
||||
<span class="nv-avatar">NX</span>
|
||||
|
||||
A person, as a round raised disc: an image when there is one, initials when
|
||||
there is not. The disc is lit like a knob — highlight above, shade below —
|
||||
so a face reads as something set into the interface, not pasted onto it.
|
||||
|
||||
.nv-avatar--ring a ring in the tint, set off by a gap of surface
|
||||
.nv-avatar--glow the ring gives off its tint
|
||||
.nv-avatar--sm / --lg / --xl
|
||||
.nv-avatar__status presence dot; --online lights it
|
||||
.nv-avatar-group overlapping row of avatars
|
||||
|
||||
--nv-avatar-tint picks the ring color; the accent unless set.
|
||||
========================================================================== */
|
||||
|
||||
.nv-avatar {
|
||||
--nv-avatar-tint: var(--nv-color-accent);
|
||||
--_size: 2.5rem;
|
||||
--_ring: 0 0 transparent;
|
||||
--_glow: 0 0 transparent;
|
||||
|
||||
position: relative;
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
flex: none;
|
||||
inline-size: var(--_size);
|
||||
block-size: var(--_size);
|
||||
|
||||
background-color: var(--nv-color-surface-elevated);
|
||||
background-image: var(--nv-sheen-raised);
|
||||
color: var(--nv-color-text-secondary);
|
||||
font: var(--nv-font-label);
|
||||
font-weight: var(--nv-font-weight-semibold);
|
||||
border-radius: var(--nv-radius-full);
|
||||
box-shadow: var(--_ring), var(--nv-bevel), var(--nv-outline), var(--nv-elevation-1), var(--_glow);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.nv-avatar > img {
|
||||
inline-size: 100%;
|
||||
block-size: 100%;
|
||||
border-radius: inherit;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* The gap is drawn in the surface color, so the ring reads as a separate band
|
||||
sitting around the disc rather than as a thick border painted onto it. */
|
||||
.nv-avatar--ring,
|
||||
.nv-avatar--glow {
|
||||
--_ring:
|
||||
0 0 0 2px var(--nv-color-surface),
|
||||
0 0 0 4px var(--nv-avatar-tint);
|
||||
}
|
||||
|
||||
.nv-avatar--glow {
|
||||
--_glow: 0 0 var(--nv-glow-blur-md) var(--nv-glow-spread-sm)
|
||||
color-mix(in oklab, var(--nv-avatar-tint) var(--nv-glow-strength), transparent);
|
||||
}
|
||||
|
||||
.nv-avatar--sm {
|
||||
--_size: 1.75rem;
|
||||
font: var(--nv-font-caption);
|
||||
}
|
||||
|
||||
.nv-avatar--lg {
|
||||
--_size: 4rem;
|
||||
font: var(--nv-font-title);
|
||||
}
|
||||
|
||||
.nv-avatar--xl {
|
||||
--_size: 6rem;
|
||||
font: var(--nv-font-heading);
|
||||
}
|
||||
|
||||
/* --- Status ------------------------------------------------------------------ */
|
||||
|
||||
.nv-avatar__status {
|
||||
position: absolute;
|
||||
inset-block-end: 4%;
|
||||
inset-inline-end: 4%;
|
||||
inline-size: max(0.625rem, 24%);
|
||||
block-size: max(0.625rem, 24%);
|
||||
border-radius: var(--nv-radius-full);
|
||||
background-color: var(--nv-color-text-tertiary);
|
||||
box-shadow: 0 0 0 2px var(--nv-color-surface);
|
||||
}
|
||||
|
||||
.nv-avatar__status--online {
|
||||
background-color: var(--nv-color-success);
|
||||
box-shadow:
|
||||
0 0 0 2px var(--nv-color-surface),
|
||||
0 0 var(--nv-glow-blur-sm) var(--nv-glow-spread-sm)
|
||||
color-mix(in oklab, var(--nv-color-success) var(--nv-glow-strength), transparent);
|
||||
}
|
||||
|
||||
/* --- Group ----------------------------------------------------------------------- */
|
||||
|
||||
.nv-avatar-group {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nv-avatar-group > .nv-avatar {
|
||||
box-shadow: 0 0 0 2px var(--nv-color-surface), var(--nv-bevel), var(--nv-elevation-1);
|
||||
}
|
||||
|
||||
.nv-avatar-group > .nv-avatar + .nv-avatar {
|
||||
margin-inline-start: calc(var(--_size) * -0.3);
|
||||
}
|
||||
Loading…
Reference in a new issue