Rework light theme, add format wheel and motion, fix Firefox paths

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>
This commit is contained in:
Nexoniarz 2026-10-28 09:34:08 +01:00
commit 5d435c4f49
12 changed files with 410 additions and 157 deletions

View file

@ -32,16 +32,18 @@
:root,
[data-nv-brand] {
/* --- Canvas and surfaces -----------------------------------------------
Paper stays paper: the two surfaces that hold content are left untinted so
text keeps its contrast. Everything the surfaces sit *in* picks up a trace
of the brand, which is what stops an accent from looking stuck on. */
--nv-light-background: color-mix(in oklab, #e8e5de, var(--nv-brand) var(--nv-brand-tint));
--nv-light-background-subtle: color-mix(in oklab, #eeece6, var(--nv-brand) var(--nv-brand-tint));
--nv-light-surface: #fbfbfa;
--nv-light-surface-elevated: #f8f8f6;
--nv-light-surface-inset: color-mix(in oklab, #eeede8, var(--nv-brand) var(--nv-brand-tint));
--nv-light-surface-hover: color-mix(in oklab, #f1f0ec, var(--nv-brand) var(--nv-brand-tint));
--nv-light-surface-active: color-mix(in oklab, #e6e5e0, var(--nv-brand) var(--nv-brand-tint));
Every neutral carries a trace of the brand, content surfaces included, the
way dark does: that is what stops an accent from looking stuck on, and what
makes the two appearances read as one material. The paper is a soft
grey-stone, not white — a bright field glares, and flattens the bevels that
are meant to shape it. Text keeps its contrast: the primary is neutral. */
--nv-light-background: color-mix(in oklab, #d8d5ce, var(--nv-brand) calc(var(--nv-brand-tint) * 2));
--nv-light-background-subtle: color-mix(in oklab, #dedbd4, var(--nv-brand) calc(var(--nv-brand-tint) * 2));
--nv-light-surface: color-mix(in oklab, #eeede9, var(--nv-brand) var(--nv-brand-tint));
--nv-light-surface-elevated: color-mix(in oklab, #f2f1ed, var(--nv-brand) var(--nv-brand-tint));
--nv-light-surface-inset: color-mix(in oklab, #dddbd4, var(--nv-brand) calc(var(--nv-brand-tint) * 2));
--nv-light-surface-hover: color-mix(in oklab, #e6e4de, var(--nv-brand) var(--nv-brand-tint));
--nv-light-surface-active: color-mix(in oklab, #dad8d1, var(--nv-brand) var(--nv-brand-tint));
--nv-light-scrim: rgb(28 24 18 / 0.34);
/* --- Text ---------------------------------------------------------------
@ -50,7 +52,7 @@
loss of legibility. */
--nv-light-text-primary: var(--nv-palette-neutral-900);
--nv-light-text-secondary: color-mix(in oklab, var(--nv-palette-neutral-600), var(--nv-brand) 8%);
--nv-light-text-tertiary: color-mix(in oklab, var(--nv-palette-neutral-500), var(--nv-brand) 8%);
--nv-light-text-tertiary: color-mix(in oklab, color-mix(in oklab, var(--nv-palette-neutral-500), var(--nv-palette-neutral-600) 40%), var(--nv-brand) 8%);
--nv-light-text-disabled: var(--nv-palette-neutral-400);
--nv-light-text-inverted: var(--nv-palette-neutral-0);
@ -135,20 +137,20 @@
/* --- Depth and material -------------------------------------------------
Three shadow colors build every elevation level: an ambient contact
shadow, a soft penumbra, and a deeper umbra for high elevations. */
--nv-light-shadow-ambient: rgb(40 32 20 / 0.08);
--nv-light-shadow-penumbra: rgb(40 32 20 / 0.1);
--nv-light-shadow-umbra: rgb(40 32 20 / 0.16);
--nv-light-shadow-inset: rgb(40 32 20 / 0.14);
--nv-light-highlight: rgb(255 255 255 / 0.9);
--nv-light-highlight-strong: rgb(255 255 255 / 1);
--nv-light-shadow-ambient: rgb(32 28 22 / 0.12);
--nv-light-shadow-penumbra: rgb(32 28 22 / 0.15);
--nv-light-shadow-umbra: rgb(32 28 22 / 0.24);
--nv-light-shadow-inset: rgb(32 28 22 / 0.2);
--nv-light-highlight: rgb(255 255 255 / 0.7);
--nv-light-highlight-strong: rgb(255 255 255 / 0.85);
/* Paper already has a border doing the contact work, so the outline only
softens it; the bottom shade is faint for the same reason. */
--nv-light-lowlight: rgb(40 32 20 / 0.09);
--nv-light-outline: rgb(40 32 20 / 0.05);
--nv-light-lowlight: rgb(32 28 22 / 0.14);
--nv-light-outline: rgb(32 28 22 / 0.08);
--nv-light-sheen-top: rgb(255 255 255 / 0.9);
--nv-light-sheen-bottom: rgb(40 32 20 / 0.07);
--nv-light-sheen-top: rgb(255 255 255 / 0.55);
--nv-light-sheen-bottom: rgb(32 28 22 / 0.11);
--nv-light-sheen-strong-top: rgb(255 255 255 / 0.32);
--nv-light-sheen-strong-bottom: rgb(20 16 10 / 0.16);
--nv-light-glow: oklch(from var(--nv-light-accent) l c h / 0.3);
@ -164,16 +166,16 @@
--nv-light-elevation-tint-4: transparent;
--nv-light-elevation-tint-5: transparent;
--nv-light-material-frosted: rgb(252 252 250 / 0.56);
--nv-light-material-glass: rgb(252 252 250 / 0.4);
--nv-light-material-border: rgb(255 255 255 / 0.72);
--nv-light-material-frosted: color-mix(in oklab, rgb(228 227 222 / 0.6), var(--nv-brand) var(--nv-brand-tint));
--nv-light-material-glass: color-mix(in oklab, rgb(228 227 222 / 0.44), var(--nv-brand) var(--nv-brand-tint));
--nv-light-material-border: rgb(255 255 255 / 0.5);
/* Glaze: the tint it is made of, the rim that catches light on the side
facing the pointer, the rim on the far side, and the specular bloom. */
--nv-light-material-glaze: rgb(255 255 255 / 1);
--nv-light-glaze-rim-lit: rgb(255 255 255 / 1);
--nv-light-glaze-rim-far: rgb(255 255 255 / 0.5);
--nv-light-glaze-specular: rgb(255 255 255 / 0.6);
--nv-light-material-glaze: color-mix(in oklab, rgb(232 231 226 / 1), var(--nv-brand) calc(var(--nv-brand-tint) * 2));
--nv-light-glaze-rim-lit: rgb(255 255 255 / 0.9);
--nv-light-glaze-rim-far: rgb(255 255 255 / 0.4);
--nv-light-glaze-specular: rgb(255 255 255 / 0.4);
/* --- Window controls --------------------------------------------------------- */
--nv-light-window-close: var(--nv-palette-window-close);