Design scarecrow · campaign engine

Campaign editor v1

A working port of Julia's Campaign Designer Figma page — three formats deep rather than all seven. The form on the left derives itself from the chosen format; the surface on the right is really rendered from that state, so every field, colour, countdown and art preset you touch is live. Nothing here is a screenshot.

figma: Tangible Cloud › Campaign Designer spec: onplatform-marketing-campaigns.md §3 §5 scope: topbar · banner · welcome mat skipped on purpose: sidebar card · inline card · slide-in · modal

01

The editor

Julia drew two header treatments (v01 Cancel / Save campaign, v02 Save draft / Publish with a big preview canvas). This takes v02's canvas and caption — the thing that makes the editor feel like a design tool — and keeps v01's compact field column.

Tangible One
Dashboard
Catalog
Customers
Marketing
Settings

Campaigns

Black Friday: Creators Club

Draft

Preview

Format derives the form. Switching format doesn't grey controls out — they leave, and one muted line at the foot of the group says what left and why. Values are kept, so you can fill everything in once and move between formats. That's Julia's rule; the interesting part is that it makes the format registry a real object rather than a convention, because the same table has to drive the validator, this form, the renderer and bulk edit's shared-field intersection.

02

Sizes subtract whole blocks

Every specimen below is the campaign you're editing above — same document, different size. Nothing restyles: blocks come off, and the heading steps down the ramp. Julia's field matrix, rendered rather than tabulated.

03

Topbar — layout is a placement choice

Split, centred, left. Plus the two content variations: a single countdown pill (never the banner's four cells — there is no vertical room), and rotation with a pause control, because auto-advancing text without one fails reduced-motion users.

04

Eyebrow styles

Chip, spinwheel, text. The spinwheel is the one component Julia flagged as missing from Tangible UI — so here it is in about forty lines of CSS (repeating-conic-gradient + color-mix), taking its fill from Accent 2 as her note requires. Hover one. It is not a blocker; it is a TUI pull request.

05

Background art, without an uploader

Julia's open question was "background art waits on an upload control; Tangible UI has no file field yet, so the form uses a select of presets." Presets don't have to mean placeholder — these are CSS, they tint themselves from Accent 2, they cost no bytes, and they cannot arrive at the wrong aspect ratio. An uploader can land later as one more entry in the same list.

06

What gets stored, what gets delivered

Left: the campaign as authored — every field, including the ones this format can't show. Right: what delivery hands the renderer for the current format. The difference between the two columns is the format registry.

Authored document


        

Delivered payload


        

07

Found while building it

Things the drawings can leave implicit and an implementation cannot. Each one is a question for Julia or a decision for us — not a defect in the design.

Resolved here, needs a nod

  • Copy colour is derived, not authored. The field set has Accent 1/2 and a colour for each, but nothing for the heading and description. So the surface has to derive ink from the background's luminance. It does that here, and the editor shows you what it derived. If a marketer should be able to override it, that's a new field.
  • Accent 1 is the CTA, not the surface. The anatomy lists "Surface fill → Accent 1", but v01 pairs a #EEF1FE surface with a #2942D1 Accent 1 and a matching button. Read as: background colour fills the surface, Accent 1 carries the emphatic element. Worth confirming, because it changes what a colour preset means.
  • Contrast belongs in the editor. Four free-form hex fields will produce an unreadable campaign on a Friday afternoon. The pairs carry a live AA/AAA readout instead of a swatch.

Still open

  • Which slot class is Banner? It is 1080 wide with a radius, so it lives in the content column like the inline card — but it has a dismiss control, and inline placements are specified as static. Drawn here as inline-with-a-named-slot; if a banner can be dismissed it needs suppression, and then it isn't static.
  • Rotation breaks "one bar per page". Topbar Rotating has several eligible campaigns sharing the slot. Delivery returning at most one bar can't express that. Either it returns an ordered bar set and the renderer rotates, or rotation is one campaign's own list of messages. This changes the query signature, so it wants deciding before the query is written.
  • Mat trigger and cap. On-load with a delay is the obvious default, exit intent the alternative — but a mat blocks the page, so its suppression cap matters more than anywhere else. Not drawn, not specified.
  • Where the reward lives. The editor notes put opt-in capture and the reward in this form; the workshop carved the Bento opt-in into its own vertical. The consent chain (marketingOptIns + reconciler + public opt-in) is already built and assumes the second reading.

Not carried over from the earlier kitchen sink, deliberately: the rotating letter-by-letter strip, the navbar-absorbing placement, and the hero-collapses-on-scroll study. They were fun and they are not v1.

Painted 6:43 PM EST all artifacts