Niveus/niveus/tokens/color.css
Nexoniarz 369d1cd8f7 Add Glaze material, pickers, slider and design guidelines
Glaze is glass with a dial: --nv-glass-frost (0 clear .. 1 heavy) moves
backdrop blur, tint and saturation together, read where the surface is
drawn so any subtree or slider can change it. A masked rim and a specular
bloom follow the pointer via niveus.js; without it the light sits at its
default and the material still reads. Falls back to the elevated solid
under reduced transparency or without backdrop-filter.

New components: .nv-slider (binds to a token with data-nv-var),
.nv-calendar, .nv-timepicker (24-hour by default, optional 24H / AM/PM
switch, value always HH:MM), and .nv-picker with .nv-menu--listbox (search,
type-ahead, keys). All render without niveus.js except where noted.

GUIDELINES.md is the normative rulebook for people and AI agents.

check.py, build.py and build.py --check pass.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 09:24:24 +01:00

269 lines
16 KiB
CSS

/* ==========================================================================
Niveus — Color
--------------------------------------------------------------------------
Two levels of tokens live here:
1. Palette Raw, appearance-agnostic values. Never referenced by
components. Prefixed --nv-palette-*.
2. Semantic The roles components actually consume (background, surface,
text-primary, accent, danger, …). Each role resolves with
light-dark(), pulling its value from the matching appearance
file: themes/light.css (--nv-light-*) or themes/dark.css
(--nv-dark-*).
The appearance is chosen by `color-scheme`, which themes/*.css bind to the
[data-theme] attribute. A component therefore never knows — and must never
ask — which appearance is active.
========================================================================== */
/* ==========================================================================
Brand
--------------------------------------------------------------------------
The whole color system has one input. Set --nv-brand and the accent, its
hover and active states, the text that lands on it, the focus ring, the
selection highlight, the tint in the greys and the lean of the status colors
are all re-derived from it — in both appearances, with no second value to
keep in sync.
:root { --nv-brand: #d92e3f; }
Set it on any element with [data-nv-brand] to re-brand a subtree.
========================================================================== */
:root {
--nv-brand: #4f6cff;
/* How much of the brand bleeds into the greys. Enough that the neutrals
belong to the same family as the accent; not enough to read as colored.
0% gives strictly neutral greys. */
--nv-brand-tint: 4%;
/* How far the status colors lean towards the brand. Red still reads as
danger and green still reads as success — they just stop looking borrowed
from another system. 0% keeps them literal. */
--nv-brand-harmony: 12%;
/* Where "too mid-toned to carry a label" begins, and how far either side a
color is pushed to escape it. Raising the pivot sends more brands dark
(white labels); lowering it sends more of them light (dark labels). */
--nv-contrast-pivot: 0.7;
--nv-contrast-dark: 0.53;
--nv-contrast-light: 0.78;
}
:root {
/* --- Neutral ----------------------------------------------------------
Warm graphite to warm paper. A grey that leans very slightly towards
yellow reads as a material (metal, enamel, paper); a grey that leans blue
reads as a screen. The lean is small enough that the brand tint still
decides the family. */
--nv-palette-neutral-0: #ffffff;
--nv-palette-neutral-25: #fcfcfb;
--nv-palette-neutral-50: #f8f8f6;
--nv-palette-neutral-100: #f2f1ee;
--nv-palette-neutral-150: #eae9e5;
--nv-palette-neutral-200: #e1e0db;
--nv-palette-neutral-300: #cfcec8;
--nv-palette-neutral-400: #aeada7;
--nv-palette-neutral-500: #87867f;
--nv-palette-neutral-600: #63625d;
--nv-palette-neutral-700: #4a4945;
--nv-palette-neutral-800: #343337;
--nv-palette-neutral-850: #2a2a2d;
--nv-palette-neutral-900: #1d1d20;
--nv-palette-neutral-925: #18181a;
--nv-palette-neutral-950: #131315;
--nv-palette-neutral-975: #0e0e10;
--nv-palette-neutral-1000: #08080a;
/* --- Window controls ----------------------------------------------------
The three lights at the start of a titlebar. They are the one place the
system uses fixed colors instead of the brand: their meaning is learned
from position and color together, and re-coloring them would unteach it. */
--nv-palette-window-close: #ff5f57;
--nv-palette-window-minimize: #febc2e;
--nv-palette-window-zoom: #28c840;
/* --- Accent (indigo) --------------------------------------------------- */
--nv-palette-accent-50: #eef2ff;
--nv-palette-accent-100: #dfe6ff;
--nv-palette-accent-200: #c4d0ff;
--nv-palette-accent-300: #9fb3ff;
--nv-palette-accent-400: #7691ff;
--nv-palette-accent-500: #4f6cff;
--nv-palette-accent-600: #3f5cf0;
--nv-palette-accent-700: #3450d6;
--nv-palette-accent-800: #2a3fa8;
--nv-palette-accent-900: #22347f;
/* --- Success (green) --------------------------------------------------- */
--nv-palette-success-50: #e8f9ef;
--nv-palette-success-100: #ccf0dc;
--nv-palette-success-200: #9ee2bc;
--nv-palette-success-300: #62cd96;
--nv-palette-success-400: #33b478;
--nv-palette-success-500: #189a60;
--nv-palette-success-600: #0f7d4d;
--nv-palette-success-700: #0c6440;
--nv-palette-success-800: #0a5034;
--nv-palette-success-900: #08412b;
/* --- Warning (amber) --------------------------------------------------- */
--nv-palette-warning-50: #fff6e6;
--nv-palette-warning-100: #ffe9c2;
--nv-palette-warning-200: #ffd68d;
--nv-palette-warning-300: #fbbe52;
--nv-palette-warning-400: #eda520;
--nv-palette-warning-500: #cf8809;
--nv-palette-warning-600: #a96d05;
--nv-palette-warning-700: #855505;
--nv-palette-warning-800: #6a4406;
--nv-palette-warning-900: #563806;
/* --- Danger (red) ------------------------------------------------------ */
--nv-palette-danger-50: #ffeff1;
--nv-palette-danger-100: #ffdbde;
--nv-palette-danger-200: #ffb9bf;
--nv-palette-danger-300: #ff8b96;
--nv-palette-danger-400: #f95b6c;
--nv-palette-danger-500: #e2334a;
--nv-palette-danger-600: #c01f36;
--nv-palette-danger-700: #9c172b;
--nv-palette-danger-800: #7e1524;
--nv-palette-danger-900: #67141f;
}
/* ==========================================================================
Semantic roles
========================================================================== */
/* The subtree selector has to be repeated here, not just on the theme files:
var() inside a custom property is substituted where that property is
*declared*, so a --nv-color-* declared only on :root would bake in the root
brand and inherit the result unchanged. Re-declaring on [data-nv-brand]
re-runs the substitution against the subtree's own brand. */
:root,
[data-nv-brand] {
/* --- Canvas and surfaces ----------------------------------------------- */
--nv-color-background: light-dark(var(--nv-light-background), var(--nv-dark-background));
--nv-color-background-subtle: light-dark(var(--nv-light-background-subtle), var(--nv-dark-background-subtle));
--nv-color-surface: light-dark(var(--nv-light-surface), var(--nv-dark-surface));
--nv-color-surface-elevated: light-dark(var(--nv-light-surface-elevated), var(--nv-dark-surface-elevated));
--nv-color-surface-inset: light-dark(var(--nv-light-surface-inset), var(--nv-dark-surface-inset));
--nv-color-surface-hover: light-dark(var(--nv-light-surface-hover), var(--nv-dark-surface-hover));
--nv-color-surface-active: light-dark(var(--nv-light-surface-active), var(--nv-dark-surface-active));
--nv-color-scrim: light-dark(var(--nv-light-scrim), var(--nv-dark-scrim));
/* --- Text --------------------------------------------------------------- */
--nv-color-text-primary: light-dark(var(--nv-light-text-primary), var(--nv-dark-text-primary));
--nv-color-text-secondary: light-dark(var(--nv-light-text-secondary), var(--nv-dark-text-secondary));
--nv-color-text-tertiary: light-dark(var(--nv-light-text-tertiary), var(--nv-dark-text-tertiary));
--nv-color-text-disabled: light-dark(var(--nv-light-text-disabled), var(--nv-dark-text-disabled));
--nv-color-text-inverted: light-dark(var(--nv-light-text-inverted), var(--nv-dark-text-inverted));
/* --- Borders ------------------------------------------------------------ */
--nv-color-border-subtle: light-dark(var(--nv-light-border-subtle), var(--nv-dark-border-subtle));
--nv-color-border: light-dark(var(--nv-light-border), var(--nv-dark-border));
--nv-color-border-strong: light-dark(var(--nv-light-border-strong), var(--nv-dark-border-strong));
/* --- Accent ------------------------------------------------------------- */
--nv-color-accent: light-dark(var(--nv-light-accent), var(--nv-dark-accent));
--nv-color-accent-hover: light-dark(var(--nv-light-accent-hover), var(--nv-dark-accent-hover));
--nv-color-accent-active: light-dark(var(--nv-light-accent-active), var(--nv-dark-accent-active));
--nv-color-accent-subtle: light-dark(var(--nv-light-accent-subtle), var(--nv-dark-accent-subtle));
--nv-color-accent-subtle-hover: light-dark(var(--nv-light-accent-subtle-hover), var(--nv-dark-accent-subtle-hover));
--nv-color-accent-border: light-dark(var(--nv-light-accent-border), var(--nv-dark-accent-border));
--nv-color-accent-text: light-dark(var(--nv-light-accent-text), var(--nv-dark-accent-text));
--nv-color-on-accent: light-dark(var(--nv-light-on-accent), var(--nv-dark-on-accent));
/* --- Success ------------------------------------------------------------ */
--nv-color-success: light-dark(var(--nv-light-success), var(--nv-dark-success));
--nv-color-success-hover: light-dark(var(--nv-light-success-hover), var(--nv-dark-success-hover));
--nv-color-success-subtle: light-dark(var(--nv-light-success-subtle), var(--nv-dark-success-subtle));
--nv-color-success-border: light-dark(var(--nv-light-success-border), var(--nv-dark-success-border));
--nv-color-success-text: light-dark(var(--nv-light-success-text), var(--nv-dark-success-text));
--nv-color-on-success: light-dark(var(--nv-light-on-success), var(--nv-dark-on-success));
/* --- Warning ------------------------------------------------------------ */
--nv-color-warning: light-dark(var(--nv-light-warning), var(--nv-dark-warning));
--nv-color-warning-hover: light-dark(var(--nv-light-warning-hover), var(--nv-dark-warning-hover));
--nv-color-warning-subtle: light-dark(var(--nv-light-warning-subtle), var(--nv-dark-warning-subtle));
--nv-color-warning-border: light-dark(var(--nv-light-warning-border), var(--nv-dark-warning-border));
--nv-color-warning-text: light-dark(var(--nv-light-warning-text), var(--nv-dark-warning-text));
--nv-color-on-warning: light-dark(var(--nv-light-on-warning), var(--nv-dark-on-warning));
/* --- Danger ------------------------------------------------------------- */
--nv-color-danger: light-dark(var(--nv-light-danger), var(--nv-dark-danger));
--nv-color-danger-hover: light-dark(var(--nv-light-danger-hover), var(--nv-dark-danger-hover));
--nv-color-danger-active: light-dark(var(--nv-light-danger-active), var(--nv-dark-danger-active));
--nv-color-danger-subtle: light-dark(var(--nv-light-danger-subtle), var(--nv-dark-danger-subtle));
--nv-color-danger-border: light-dark(var(--nv-light-danger-border), var(--nv-dark-danger-border));
--nv-color-danger-text: light-dark(var(--nv-light-danger-text), var(--nv-dark-danger-text));
--nv-color-on-danger: light-dark(var(--nv-light-on-danger), var(--nv-dark-on-danger));
/* --- Depth and material ------------------------------------------------- */
--nv-color-shadow-ambient: light-dark(var(--nv-light-shadow-ambient), var(--nv-dark-shadow-ambient));
--nv-color-shadow-penumbra: light-dark(var(--nv-light-shadow-penumbra), var(--nv-dark-shadow-penumbra));
--nv-color-shadow-umbra: light-dark(var(--nv-light-shadow-umbra), var(--nv-dark-shadow-umbra));
--nv-color-shadow-inset: light-dark(var(--nv-light-shadow-inset), var(--nv-dark-shadow-inset));
--nv-color-highlight: light-dark(var(--nv-light-highlight), var(--nv-dark-highlight));
--nv-color-highlight-strong: light-dark(var(--nv-light-highlight-strong), var(--nv-dark-highlight-strong));
/* The bevel's other half: the shade along a raised surface's bottom edge,
and the contact line around anything that sits on another surface. Light
along the top and shade along the bottom is what makes a control read as
something pressable instead of a painted rectangle. */
--nv-color-lowlight: light-dark(var(--nv-light-lowlight), var(--nv-dark-lowlight));
--nv-color-outline: light-dark(var(--nv-light-outline), var(--nv-dark-outline));
/* Sheen: the light falling across a raised face, top to bottom. The plain
pair is for neutral controls and surfaces; the strong pair is for filled
color (primary buttons, checked marks), where it has to read through a
saturated fill. Both are laid over a surface's own color, never instead
of it. */
--nv-color-sheen-top: light-dark(var(--nv-light-sheen-top), var(--nv-dark-sheen-top));
--nv-color-sheen-bottom: light-dark(var(--nv-light-sheen-bottom), var(--nv-dark-sheen-bottom));
--nv-color-sheen-strong-top: light-dark(var(--nv-light-sheen-strong-top), var(--nv-dark-sheen-strong-top));
--nv-color-sheen-strong-bottom: light-dark(var(--nv-light-sheen-strong-bottom), var(--nv-dark-sheen-strong-bottom));
/* Glow: light a surface gives off, as opposed to the shade it casts. It is
the accent seen through air — strong enough in dark to read as a lit
edge, faint in light, where paper does not emit. */
--nv-color-glow: light-dark(var(--nv-light-glow), var(--nv-dark-glow));
/* A knob: the thumb of a switch or a slider. It stays light in both
appearances, the way a physical knob does not change color with the room. */
--nv-color-knob: light-dark(var(--nv-light-knob), var(--nv-dark-knob));
--nv-color-knob-shade: light-dark(var(--nv-light-knob-shade), var(--nv-dark-knob-shade));
/* Elevation tint: on a dark canvas a shadow has nothing to darken, so a
raised surface also has to gain light. Transparent in light, where the
shadow does all the work. */
--nv-color-elevation-tint-1: light-dark(var(--nv-light-elevation-tint-1), var(--nv-dark-elevation-tint-1));
--nv-color-elevation-tint-2: light-dark(var(--nv-light-elevation-tint-2), var(--nv-dark-elevation-tint-2));
--nv-color-elevation-tint-3: light-dark(var(--nv-light-elevation-tint-3), var(--nv-dark-elevation-tint-3));
--nv-color-elevation-tint-4: light-dark(var(--nv-light-elevation-tint-4), var(--nv-dark-elevation-tint-4));
--nv-color-elevation-tint-5: light-dark(var(--nv-light-elevation-tint-5), var(--nv-dark-elevation-tint-5));
--nv-color-material-frosted: light-dark(var(--nv-light-material-frosted), var(--nv-dark-material-frosted));
--nv-color-material-glass: light-dark(var(--nv-light-material-glass), var(--nv-dark-material-glass));
--nv-color-material-border: light-dark(var(--nv-light-material-border), var(--nv-dark-material-border));
--nv-color-material-glaze: light-dark(var(--nv-light-material-glaze), var(--nv-dark-material-glaze));
--nv-color-glaze-rim-lit: light-dark(var(--nv-light-glaze-rim-lit), var(--nv-dark-glaze-rim-lit));
--nv-color-glaze-rim-far: light-dark(var(--nv-light-glaze-rim-far), var(--nv-dark-glaze-rim-far));
--nv-color-glaze-specular: light-dark(var(--nv-light-glaze-specular), var(--nv-dark-glaze-specular));
/* --- Window controls ------------------------------------------------------- */
--nv-color-window-close: light-dark(var(--nv-light-window-close), var(--nv-dark-window-close));
--nv-color-window-minimize: light-dark(var(--nv-light-window-minimize), var(--nv-dark-window-minimize));
--nv-color-window-zoom: light-dark(var(--nv-light-window-zoom), var(--nv-dark-window-zoom));
--nv-color-window-inactive: light-dark(var(--nv-light-window-inactive), var(--nv-dark-window-inactive));
--nv-color-window-control-ring: light-dark(var(--nv-light-window-control-ring), var(--nv-dark-window-control-ring));
--nv-color-window-glyph: light-dark(var(--nv-light-window-glyph), var(--nv-dark-window-glyph));
/* --- Interaction --------------------------------------------------------- */
--nv-color-focus-ring: light-dark(var(--nv-light-focus-ring), var(--nv-dark-focus-ring));
--nv-color-focus-ring-contrast: light-dark(var(--nv-light-focus-ring-contrast), var(--nv-dark-focus-ring-contrast));
--nv-color-selection: light-dark(var(--nv-light-selection), var(--nv-dark-selection));
}