The series' numbers, displayed the way the grid actually bills you: pointer dials that alternate direction, an eddy disk spinning behind its slit, and the honest digits on the register. Drawn entirely in code — and skinnable the moment a rendered graphic pack lands in ./pack/.
Dials read left to right, high to low — and like the real instrument, each pointer sits between numerals mid-count while the register below carries the exact reading. Disk speed is scaled to how fast each utility's price has moved since 2019 (a stopped disk would mean a frozen rate). Motion respects your reduced-motion setting.
The framework runs with no pack at all — what you see above is the code-drawn default. To dress it in rendered art, drop files plus a pack.json into static/grid-capital/meter/pack/ and every meter re-renders in the new skin on load. Any subset works; whatever a pack omits stays code-drawn. Same two-layer contract as the theme kits: the pack out-specifies the platform, the platform never blocks the pack.
| bezel.png | 1024×1024, transparent. The outer ring, screws, housing — with an open center ≥78% of the width for the face. Rendered straight-on. |
|---|---|
| face.png | 1024×1024, transparent, clipped to the glass circle at render. The dial plate itself. Render it blank and my dials/text draw on top — or paint the full printed face and set "hideCodeScales": true to silence the code lettering (pointers, disk and register always stay live). |
| glass.png | 1024×1024, transparent. Dome glare/reflections only — pure alpha overlay, drawn above everything. |
| disk.png | 1024×1024, transparent. The aluminum disk seen from the front, its black timing mark included; I clip it to the slit and spin the whole image about its center. |
| pointer.png | 1024×1024, transparent. One needle pointing straight UP, pivot exactly at image center — I rotate it per dial. |
| pack.json | {"assets":{"bezel":"bezel.png","face":"face.png","glass":"glass.png","disk":"disk.png","pointer":"pointer.png"},"hideCodeScales":false,"css":"pack.css"} — every key optional; css lets a pack retune the --gcm-* tokens too. |
<div id="m1"></div>
<script src="/grid-capital/meter/meter.js"></script>
<script>
GCMeter.render(document.getElementById("m1"), {
value: 13.86, digits: 4, scale: 100,
unit: "cents per kilowatt-hour",
label: "EL PASO ELECTRIC · TEXAS",
badge: "EIA 2025", disk: 1.6,
trend: "+16% since the 2020 buyout"
});
GCMeter.loadPack("/grid-capital/meter/pack/pack.json"); // no-op until a pack exists
</script>
The disk parameter is a speed factor (0 stops it); digits/scale set the dial train (13.86¢ × 100 → a 1-3-8-6 read). The mount is just a div — meters drop into any page on the module, or the hub at large.
Grid & Capital · File No. 2: the national map · File No. 1: El Paso Electric · File No. 3: New Mexico