Stage 3a of #780.
- src/led-strip-gate.ts is the only initial-graph foothold (ТЗ §13.1): which
markers a space shows as a strip (active and bound), the half-length
anchor that replaces their icon position, and one page-wide load of the
lazy led-strip-runtime chunk (fingerprint handshake, a hashed-URL retry on
the next explicit entry, never in a loop).
- The card: a represented marker takes no auto slot, draws no icon, casts no
round pool and is placed at the anchor; two call sites render the stripe
layer and the linear field from the chunk. The space model carries the
stored strips untouched; scaling, validation and geometry are in the chunk.
- src/led-strip-runtime.ts: the stripe is two strokes of one derived path
(outline #383838 t, core t/2, round joins and caps, t = 0.08/0.12 D),
white off, white core + field on with Glow, source-colour core without
Glow, grey dashed unavailable without a field. The hit path takes the
card's own device handlers (one action path) with radius max(22 px, t/2)
and the nearest stripe as owner. The linear field is the exact distance
field with the shared falloff: opaque grey bands of a luminance mask per
piece, pieces joined by lighten (the maximum), each piece clipped to what
its own emitters see, so a hidden part never lights through another part's
visibility; buried emitters emit nothing; a failed clip is dark. A bounded
per-space cache (50) counts geometry rebuilds.
- The initial View graph had 501 B of headroom. The furniture library copy
(furn.*, 104 keys × 4 languages, editor-only) moves into a new lazy `tools`
namespace (#627 mechanism) that the editor runtime awaits; the initial
View graph is 298 686 B gzip with the LED gate in it (−1 879 B vs the base).
Tests: test/led-strip-runtime.test.mjs (6: representation, gate anchor =
geometry anchor, falloff, states and radius, per-piece clipping and buried
strips, bounded cache), bundle and i18n fixtures for the LED chunk and the
fourth namespace.
Issue: #780
User-Visible: no