Workshop Kit · widget reference
Shippedpersona-card-builder
Structured persona capture for L4. The operator sketches one specific archetypal customer — name, age, role, up to six trait chips, and a narrative paragraph — and watches a live "customer card" build alongside the form. Dual-writes to customerCard (structured) and customerParagraph (the existing prose wire downstream lessons already read), so nothing in the existing rail + L14 generator + L9/L10/L12 reads has to change.
Live demo
Type a name, age, role; add up to six traits as chips; write a paragraph. The card on the right updates live. The avatar derives initials from the name; no image upload, no remote fetch — matches the suite's no-fetch posture.
No config block — defaults are correct
Contract
| Behavior | Notes |
|---|---|
Reads customerCard |
Pre-fills name + age + role + traits[] from prior commits. |
Reads customerParagraph |
Pre-fills the narrative textarea — preserves anything the operator wrote with the older text-input widget that this replaces. |
Writes customerCard |
{ name, age, role, traits: [string, …] } — the new structured wire. L9, L13, the L14 About-page template can opt into this for richer rendering. |
Writes customerParagraph |
Unchanged prose wire. L10 (hours), L12 (keyword-builder), the L14 About template all keep reading this. |
| Traits cap | Maximum 6 chips. Adding a 7th triggers a polite-region announcement; the existing 6 don't shift. |
| Avatar | 1–2 initials derived from name (first + last word, uppercased). Background colored by palette[0] when available — the operator's accent. |
Markup
No config block. Defaults are correct because the field set is fixed — name, age, role, traits, paragraph.
Accessibility
- Labeled inputs for name, age, role, traits. The traits chip-list is a
role="list"with each chip a<button>that announces "remove: <trait>" viaaria-label. - Adding a trait: type, press Enter or click the Add button. The Add button is keyboard-reachable and announces success via a polite live region.
- Character counter for the paragraph announces remaining characters politely.
- Card preview is marked
aria-hidden="true"on the visual avatar and labeled with the heading so screen readers don't read the initials twice.
Why dual-write
The plan's "persona-card-builder" upgrades a freeform paragraph to structured fields. But the existing rail iframe, the L14 About-page template, and downstream lessons (L9, L10, L12) all read customerParagraph as prose. Rewriting all of them to read a structured card is a bigger refactor than this widget warrants. The dual-write resolves the tension: the widget owns the structure, the prose stays the canonical downstream wire, the structured side is available the moment a consumer wants to read it.
Where it ships
Source
/tools/_shared/workshop/persona-card-builder.js — ~250 LOC. Exports { tag, contextKeys, mount, serialize } per the Workshop Kit widget contract. Defines its own bilingual string set inline — no i18n.es.json round-trip needed because the strings are widget-internal labels.