Charts
The data language — validated chart weights, the form set (area, line, bar, pie, radar, radial), tooltips, and LiveLine for live streams.
Series — Chart Weights
The Channel hues at chart weight — dropped into the categorical lightness band (max chroma) so adjacent series stay distinct. The chart ground follows the theme, and each theme ships its own computationally validated set: the dark values (OKLCH L 0.52–0.66) measure worst adjacent pair ΔE 15.2 under deuteranopia on Black; the light values (L 0.46–0.60) measure ΔE 14.1 on White — all marks ≥3:1 on their ground. Same eight hues, same fixed order in both — assign series 1→8 in order, never cycle, and never repaint surviving series when a filter drops one. Consume them as --lexi-chart-1…8; the values flip with the theme.
Area
The workhorse for behaviour over time — sittings, messages, installs. The panel ground follows the theme, and the series flip with it to the matching validated set. Recessive grid at the subtle border; axis ticks in the technical voice (Founders Mono, 14px); values in Inter with tabular numerals. Gradient fills run 25% → 0 so overlapping series stay readable.
Forms
The data's job picks the form: trends take line (area when the volume under the curve matters), magnitude by category takes bars (4px rounded data-ends, 2px gaps), composition takes a donut — four slices or fewer, 2px seams, legend always — a profile across dimensions takes radar, and a single headline metric takes a radial gauge. The radial is single-series, so it wears the themed chart accent — Signal on dark, signal-weight on light; every multi-series form draws from --lexi-chart-1…8 in order. Never two y-scales on one plot.
Tooltips
Every chart ships the hover layer — a crosshair on line and area, a per-mark highlight on bars and slices, this panel on both. The anatomy: dark glass (92% Black, 20px blur) with the subtle border; the label in the technical voice (mono 14, tracked); one row per series — a 10px square swatch carries identity, the name sits in muted ink, and the value is Inter with tabular numerals, right-aligned. Text never wears the series colour.
Live Line
For live behaviour: nothing jumps. Points plot by timestamp against a sliding time window, so the whole line drifts left continuously at 60fps — arrivals never shift the plot. The live endpoint eases toward each new value at 8% per frame, the range snaps outward instantly and eases back in, the path is a smooth spline, and a pulsing dot marks the live point (after benji.org/liveline). Single-series, so it wears the themed chart accent — Signal on dark, signal-weight on light. A breathing line fills the loading state; under reduced motion the endpoint snaps and the pulse is off.
Rules
A themed ground, twin sets
The chart ground follows the theme, and each theme ships its own validated series — --lexi-chart-1…8 flips with [data-theme]. Never mix sets on one ground.
Fixed order, never cycled
Series take --lexi-chart-1…8 in order. Colour follows the entity — a filter that drops series must not repaint the survivors. A 9th series folds into “Other”.
One axis
Never two y-scales. Two measures of different scale get two charts, small multiples, or a common index.
Text wears text tokens
Values, labels, and legends stay in fg / muted ink — a coloured mark beside them carries identity. Series colours are never text.
Legend from two series
≥2 series always get a legend; ≤4 are also direct-labelled. A single series needs no legend — the title names it, and it may wear a display Channel.
Motion is lerp, not jump
Live data eases toward its target; ranges snap out and ease in. prefers-reduced-motion snaps values and disables the pulse.
Last updated on 2026-09-13