Shell anatomy

The shared CreationPipeline chrome every staged flow renders into — annotated.

Reference
One component frames every pipeline. Social posts, ad variants, and future studios all pass the same props and only swap the stage content in the middle. The four numbered regions below map 1:1 to the props in the Props / API card at the bottom.
The anatomy
1 Header row

Editable title

Type Status
Saved

Left: inline-editable .h1 + the item's type & status badges. Right: a .savestate that reads "Saved" (check) or "Saving…" while autosave is in flight.

2 Sticky stepper
Brief
Research
3 Plan
4 Produce
Schedule Locked

One .step per stage from stages[], joined by .arr chevrons. Done (check in .n, from doneness) · Active (indigo fill, the active stage shows its number) · plain reachable · Locked (dimmed + lock chip, from locked). Clicking a non-locked step fires onSelect.

3 Stage content
Stage content renders here
The only region that differs page-to-page. Each pipeline stage drops its own form, generate→select cards, or preview into this slot — the chrome around it stays identical.

Rendered as {children} for the active stage. Header, stepper, and footer are the framework; everything between them is the page.

4 Sticky stage footer
Select an approach to continue.

Left: a one-line .hint from footer.hint. Right: Back (ghost — omitted on stage 1, fires onBack), an optional Skip (ghost, when footer.canSkip), and the screen's one pink CTAContinue → {next} (.btn acc lg), disabled until footer.canContinue is met.

One pink CTA per screen. The accent (.btn acc) is reserved for the single primary action — almost always the footer's Continue. Steps, Back, Skip, and in-stage controls stay indigo/neutral, keeping hot pink at ~10% of the surface.
Props / API

<CreationPipeline />

props
stages[]
Ordered stage descriptors — { id, label, icon }. Drives the stepper and the Continue label. e.g. Brief · Research · Plan · Produce · Schedule.
active
The current stage id. Renders on in the stepper and decides which children stage body shows.
doneness{}
Map of stageId → boolean. true renders the step as done with a check — derived from saved artifacts, not visited-state.
locked{}
Map of stageId → boolean. Soft-gates not-yet-reachable stages (dim + lock chip, non-clickable). No auto-advance — progression is explicit.
header{}
{ title, badges[], savestate } — the editable title, type/status badges, and 'saved' | 'saving' indicator.
footer{}
{ hint, canContinue, continueLabel, canSkip } — the hint line, Continue gate + its label, and whether a Skip appears.
onSelect(id)
Fired when a non-locked step is clicked — caller navigates to that stage.
onContinue()
Fired by the primary CTA when canContinue is true — persists the stage and advances.
onBack()
Fired by the Back button — returns to the previous stage. Button is hidden on the first stage.
onSkip()
Fired by the optional Skip button when footer.canSkip — advances past an optional stage without persisting it.
Reused across the suite
Social posts
Brief → Research → Plan → Produce → Schedule. Five stages, same chrome.
Ad variants
Overview → Hook → Copy → Media → Review, nested under a campaign.
Studios Future
Video, image & carousel studios adopt the same staged shell when they land.

Same component, same gating rules, same single-CTA discipline — only stages[] and the stage body change between flows.