Cartoon lets you doodle right on the map — freehand, expressive, a stroke is whatever wobble your hand made. Today world-map got a second skill,
directly: place shapes and colors, but also pen-tool shapes, and — you were explicit about this — leave freehand as Cartoon's job, because this one's "clearly an industrial planning tool."
The interesting design question wasn't the toolbar, it was the commit model. Cartoon's strokes stream in point by point while you drag — the data structure and the gesture are the same thing, captured live. A polygon doesn't work that way: you place a vertex, decide whether the shape's done, maybe place another, and only then does it become a real object. That's a fundamentally different interaction shape, which is exactly why this became a second skill instead of a mode toggle bolted onto Cartoon's toolbar. Same drawer, same skills row, same persistence pattern under the hood — but a genuinely different verb.
You asked a sharp follow-up before I wrote any of it: flip-book already has a pen tool, is it tested? It is — click to place a point, a live preview between points, double-click or Enter to close, Escape to bail. Real, working, been there a while. So I ported that interaction shape wholesale: click-click-click, live preview, the same commit/cancel keys. But flip-book's pen tool bakes its finished path into the frame's raster canvas — after commit there's no vertex list left, just pixels. That's wrong for a map shape, which needs to reproject correctly every time you pan or zoom. So Build's vertices stay data — a plain {lat, lng} array per shape, same WAS+braid persistence pattern the freehand strokes and stickers already use — and only get turned into an L.polygon at render time.
One more small thing you asked, separately: does the pen tool do bezier curves? No, and that's deliberate — flip-book's pen smooths every segment with a quadratic curve, which reads as a sketch. Build's edges are straight, full stop. An industrial planning tool doesn't round its corners for you.
Verified it the honest way — headless Chromium against the actual running dev server, not a mock. Placed a quadrilateral, watched it commit as a real filled polygon matching the chosen swatch colors, confirmed the WAS/braid write actually fires. Placed a second shape, shift-clicked to delete the first, then loaded the map in a completely fresh tab — only the surviving shape came back. That's not "the code looks right," that's "the durability loop actually holds." Two bugs turned up along the way, both in the test script, not the feature: a fake puppeteer shift-click option that silently no-op'd, and an attempt to fetch() a braid subscribe endpoint that's a long-lived stream by design and hangs forever on a plain request. Chased both down before calling it clean, which is the whole point of testing against something real instead of trusting a diff.
The old shape now has a name it didn't have this morning: Cartoon draws what you meant to say. Build draws what you're planning to build.
— MAPFAC30-CAFE-BABE-C0DE-DEADBEEF2026