mirror of
https://github.com/Nexoniarz/Niveus.git
synced 2026-11-03 20:54:25 +00:00
Theme: light is a dimmer brand-tinted stone with deeper shade, so it reads as the same material as dark; every neutral now carries --nv-brand in both appearances. Native controls (accent-color, caret-color) take the brand. Time picker: 24-hour by default; data-nv-format-toggle adds a third wheel of 24H / AM / PM. Swiping it rebuilds the hour wheel for the new format. The selection lens is a raised glass bar, not a flat band. Motion: drum effect on the wheels as a scroll-driven animation, with a script fallback for engines without it (Firefox); rubber-band at both ends of a wheel that springs back; calendar months slide locally instead of via a page-wide transition; a chosen day springs into place. Firefox: wheel notches arrive in lines, not pixels, which made the rubber-band invisible; deltaMode is now normalised. The selected-day pop no longer plays on page load. Also: hover only inside @media (hover: hover) on the slider, the Glaze inner glow is a token, and the focus note in GUIDELINES.md is corrected (popovers do not trap focus). SPDX identifier added to niveus.js. check.py, build.py and build.py --check pass. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
117 lines
6.2 KiB
CSS
117 lines
6.2 KiB
CSS
/* ==========================================================================
|
|
Niveus — Materials
|
|
--------------------------------------------------------------------------
|
|
A material is a surface treatment: what it is made of, not where it sits.
|
|
Elevation answers "how far from the canvas"; material answers "what does
|
|
light do when it hits this".
|
|
|
|
solid opaque, stable. The default. Content lives here.
|
|
elevated solid with depth and a top highlight. Separated from context.
|
|
inset recessed into its parent. Fields, wells, tracks.
|
|
frosted translucent, moderately blurred, bevelled. Chrome that sits
|
|
over content: bars, docks, launchers, notifications, menus.
|
|
glass more translucent, lightly blurred. Contextual layers where the
|
|
content behind should stay legible: overlays, hover cards.
|
|
glaze glass with a dial. How frosted it is belongs to whoever is
|
|
looking at it, so it is one number (--nv-glass-frost) rather
|
|
than a fixed recipe, and it carries a rim that catches the
|
|
light and follows the pointer.
|
|
|
|
Niveus is a solid system with glass used sparingly. Windows, cards, dialogs
|
|
and everything that holds content are solid; translucency is reserved for
|
|
the chrome that floats over them. Translucency has a cost — it tints
|
|
whatever is behind it and forces the GPU to composite — and used everywhere
|
|
it stops meaning "this floats".
|
|
|
|
Sheen is the light falling across a raised face. It is laid over a
|
|
surface's own color as background-image, so a surface keeps its role color
|
|
and gains the gradient; anything that does not draw gradients simply shows
|
|
the role color.
|
|
========================================================================== */
|
|
|
|
:root {
|
|
/* --- Blur ---------------------------------------------------------------- */
|
|
--nv-blur-sm: 12px;
|
|
--nv-blur-md: 24px;
|
|
--nv-blur-lg: 36px;
|
|
--nv-blur-xl: 56px;
|
|
|
|
/* Backdrops lose saturation when blurred; a touch of saturate() puts the
|
|
color back so frosted surfaces do not read as gray films. Moderate on
|
|
purpose: the blur says "this floats", it is not the look itself. */
|
|
--nv-backdrop-saturate: 180%;
|
|
--nv-backdrop-frosted: blur(var(--nv-blur-md)) saturate(var(--nv-backdrop-saturate));
|
|
--nv-backdrop-glass: blur(var(--nv-blur-sm)) saturate(var(--nv-backdrop-saturate));
|
|
|
|
/* --- Frost ------------------------------------------------------------------
|
|
The one input the glaze material derives from: 0 is clear glass, 1 is
|
|
nearly opaque frost. Set it on :root for the whole site, on a subtree to
|
|
change just that region, or bind a slider to it with data-nv-var and let
|
|
the person looking choose. The glaze recipe reads it where it is used,
|
|
so a subtree override always reaches the surfaces inside it. */
|
|
--nv-glass-frost: 0.5;
|
|
--nv-glaze-blur-max: 56px; /* blur at frost 1 */
|
|
--nv-glaze-tint-min: 4%; /* tint opacity at frost 0 */
|
|
--nv-glaze-tint-max: 78%; /* tint opacity at frost 1 */
|
|
--nv-glaze-rim: 1.5px;
|
|
/* The light a pane holds just inside its edge, so it reads as a thick lens
|
|
rather than a flat film. */
|
|
--nv-glaze-glow: inset 0 0 1.5rem -0.5rem var(--nv-color-glaze-specular);
|
|
|
|
/* --- Sheen ------------------------------------------------------------------
|
|
raised neutral controls: buttons, the selected tab, a titlebar
|
|
filled saturated fills: primary and danger buttons, checked marks
|
|
surface large surfaces: windows, dialogs, cards. Brightest along the
|
|
top edge, easing through the middle and settling into a faint
|
|
shade at the foot, so a panel reads as a curved, lit body
|
|
rather than as a flat sheet.
|
|
knob a round thumb: lit from above, shaded towards its rim */
|
|
--nv-sheen-raised: linear-gradient(var(--nv-color-sheen-top), var(--nv-color-sheen-bottom));
|
|
--nv-sheen-filled: linear-gradient(var(--nv-color-sheen-strong-top), var(--nv-color-sheen-strong-bottom));
|
|
--nv-sheen-surface: linear-gradient(var(--nv-color-sheen-top), transparent 7rem, transparent 55%, var(--nv-color-sheen-bottom));
|
|
--nv-sheen-knob: radial-gradient(circle at 50% 22%, var(--nv-color-highlight-strong), transparent 45%), radial-gradient(circle at 50% 30%, transparent 40%, var(--nv-color-knob-shade));
|
|
--nv-backdrop-scrim: blur(var(--nv-blur-sm)) saturate(140%);
|
|
|
|
/* --- Material recipes -----------------------------------------------------
|
|
Each recipe is the full set of properties that defines the material.
|
|
Applied by the .nv-material-* classes in components/surface.css. */
|
|
--nv-material-solid-bg: var(--nv-color-surface);
|
|
--nv-material-solid-border: var(--nv-color-border);
|
|
--nv-material-solid-shadow: var(--nv-elevation-0);
|
|
|
|
--nv-material-elevated-bg: var(--nv-color-surface-elevated);
|
|
--nv-material-elevated-border: var(--nv-color-border-subtle);
|
|
--nv-material-elevated-shadow: var(--nv-bevel), var(--nv-outline), var(--nv-elevation-2);
|
|
|
|
--nv-material-inset-bg: var(--nv-color-surface-inset);
|
|
--nv-material-inset-border: var(--nv-color-border-subtle);
|
|
--nv-material-inset-shadow: var(--nv-elevation-inset-md), var(--nv-ledge);
|
|
|
|
--nv-material-frosted-bg: var(--nv-color-material-frosted);
|
|
--nv-material-frosted-border: var(--nv-color-material-border);
|
|
--nv-material-frosted-shadow: var(--nv-bevel), var(--nv-outline), var(--nv-elevation-3);
|
|
|
|
--nv-material-glass-bg: var(--nv-color-material-glass);
|
|
--nv-material-glass-border: var(--nv-color-material-border);
|
|
--nv-material-glass-shadow: var(--nv-highlight-top-strong), var(--nv-outline), var(--nv-elevation-4);
|
|
}
|
|
|
|
/* Where translucency cannot be honoured — reduced transparency, or a browser
|
|
without backdrop-filter — materials fall back to their solid equivalents
|
|
rather than becoming unreadable washes. */
|
|
@media (prefers-reduced-transparency: reduce) {
|
|
:root {
|
|
--nv-material-frosted-bg: var(--nv-color-surface-elevated);
|
|
--nv-material-glass-bg: var(--nv-color-surface-elevated);
|
|
--nv-backdrop-frosted: none;
|
|
--nv-backdrop-glass: none;
|
|
--nv-backdrop-scrim: none;
|
|
}
|
|
}
|
|
|
|
@supports not (backdrop-filter: blur(1px)) {
|
|
:root {
|
|
--nv-material-frosted-bg: var(--nv-color-surface-elevated);
|
|
--nv-material-glass-bg: var(--nv-color-surface-elevated);
|
|
}
|
|
}
|