meterd on 127.0.0.1:8812 — real samples, nothing mocked.
The element is the SHAPE. The metric is a KNOB. There is no
<meter-ram>. There is <brick-fill>, which renders
any bounded level — pointed at any endpoint speaking the pipe, under any metric name
it has never heard of, with no code change. Everything below is the same seven
elements with different attributes.
One element, three renderings, switched by the density attribute — not
three elements. glance is the shape alone at a lazy 30 s poll;
detail adds a live graph and a readout at 1 s; history adds an
in-component range picker (click it, or tab to it and use the cursor keys — Enter
opens and selects, Esc closes; no native dialog anywhere).
The three cards below are the same element, <brick-fill>,
with one attribute changed. The first two are pointed at two different real metrics.
The third is pointed at a metric name this collector has never emitted and never
will, and is fed entirely through push() by the page — no fetching at
all. If a brick knew what RAM was, that third card could not exist.
meterd has never heard of flux-capacitor-charge and never
will. The brick renders it correctly anyway, in a made-up unit, because a shape
only ever asked for a bounded level. Tomorrow that same element renders a
context window, a storage quota or a battery — by changing an attribute, not code.
<brick-meter> is the only thing in the module that knows a metric
name, and it is a plain data table you can extend at runtime with
Brick.presets.register(). Given an unknown metric it picks a shape
from the payload's own structure instead — total ⇒ fill,
parts ⇒ columns, neither ⇒ curve.
Left: a metric the collector has genuinely never sampled — the server answers
{"ok":false} and the brick draws its empty frame and a muted dash.
Never a zero, which would be a lie; never a blank box, which reads as broken
layout. Right: an endpoint that does not exist at all — a network failure,
handled identically, with the label marked and a brick-error event
fired rather than console noise.
Bricks get told their bounds and adapt to them (paths/ui.md). Same
markup at 80 px, 120 px, 200 px and a box you can drag by its corner — a
ResizeObserver repaints, chrome drops out below ~110 px, and the bar
fitter walks up its unit ladder rather than drawing bars too thin to read.
Every brick above fetches for itself. These four do not: poll="0" turns
self-fetching off and the page fans a single payload out with push().
This is the Nozotros-header case — one lazy poll, six instruments — and it
needs no code change to reach, only an attribute. Driver interval is 5 s here so it
is visibly live; a header would use 30 s.
Every brick fires brick-update and brick-error, composed
and bubbling, so a host can log, aggregate or alarm without reaching into a shadow
root. Both are shown below — including the deliberate failure from the unreachable
endpoint above.