Loom Alpha · Sprint L3 polish — templates, duplicate, cost preview, empty state.
- Prefab workflow catalogue: 4 templates (Concept brief · Texture base · Reference variations · Style sheet · save 4 angles) accessible from a new 'From template' picker in the canvas toolbar. Endpoint: GET /api/v1/loom/templates + POST /api/v1/projects/{id}/workflows/from-template/{slug}.
- Duplicate workflow: POST /api/v1/workflows/{id}/duplicate clones into the same project under '<name> (copy)'. UI button appears in the toolbar once a workflow is loaded.
- Cost preview: POST /api/v1/loom/estimate-cost walks the graph and sums estimated USD per image_generator node from the per-model price table in ai_providers._MODEL_ESTIMATED_USD. Canvas calls it on every node / connection / data change with a 200ms debounce. Result shown in the status strip ('Estimated next run: $0.003') plus a chip embedded in the Run button.
- Empty state hero overlaid on the canvas when no nodes exist: gradient sparkles icon, 'Bring your idea to a canvas.' copy, two CTAs ('Pick a template' opens the picker, 'Start blank' seeds a 3-node starter graph).
- Toolbar gains the From template / Duplicate / cost chip controls without breaking the existing Drawflow event wiring (mutation handlers debounce-schedule the estimate refresh).
- 8 new tests in test_v019_loom — template catalogue shape, create-from-template persists the prefab graph, unknown slug 404, duplicate flow, estimate for concept_brief + reference_variations + empty graph + per-model price ordering.
- Suite 214/220 (6 preexisting failures untouched).