A single collaborative board (/admin/boards/:id).
Renders a <Fresco.canvas> (infinite) + <Etcher.layer> and wires three
real-time channels over one PubSub topic (phoenix_kit_boards:<id>):
- Shapes — the client emits
etcher:annotations-changed(full list) on every edit; we diff, persist, and broadcast. Peers diff against their own state and push a create/update/delete delta toBoardSync, which applies it viawindow.Etcher.layerFor(id)— no canvas remount. Echo is broken server-side (an unchanged list diffs to empty). - Presence — a roster of who's viewing, via join/hello/leave messages.
- Cursors — pointer positions in canvas coordinates, so each viewer
maps them through their own pan/zoom (
BoardCursors).