Just Sold as an engine shape

The Round 2 reference card, built as a shape the render-html Worker draws from fields. These four renders came out of the engine module, not the reference builder. Same numbers, same fonts, same mark, so the reference page and the pipeline can no longer drift apart.

No sold price. The reference cards carried a dummy price as the hero. The Sold lane doctrine Dave ratified on 8/17 says no sold price appears in Legacy marketing, ever, so the shape has no price field. The hero is the outcome: days on the market. A stat that looks like a price throws before it renders.
Engine Just Sold, square
legacy-just-sold1080 x 1080. The approved JS-photo composition, drawn from fields.
Engine Just Sold, square, agent in black and white
legacy-just-sold, bw: trueThe JS-photo-bw variant. One flag, the sky ring and the black and white agent.
Engine Just Sold, portrait
legacy-just-sold-portrait1080 x 1350. Same composition opened up the way the formats pass approved.
Engine Just Sold, overlong copy clamped
Overlong copyA long address and a 240-character line, clamped by the shape. The ring never touches the text no matter what the words engine sends.

Where it lives

Moduleengine/card-html/legacy-just-sold.js, zero imports, generated from reference-cards/engine-template/legacy-just-sold.template.js by _make-module.mjs (edit the template, not the module)
Registryengine/workers/render-html/src/templates.js: shapes legacy-just-sold and legacy-just-sold-portrait
Fontsengine/card-html/fonts/archivo-800-latin.woff2 and source-sans-3-{400,600,700}-latin.woff2, bundled as bytes like Open Sans
Previewnode reference-cards/engine-template/preview.mjs then render-fmt.ps1 on out-square (1080) and out-portrait (1350)

The fields and their caps

Caps were measured off the approved render. The shape clamps to them so it never overflows; legacyJustSoldFits(fields) reports what is over so the words engine can rewrite before rendering.

FieldCapNote
photo, photoKindrequiredhouse, interior, or aerial. A headshot or lifestyle shot is refused.
stat8required. "9 days". A dollar figure throws.
statLabel22default "on the market"
tag14default "Just Sold"
address30one line
city26
facts3 x 18chips, no money figures
whyHead26default "What this means for you"
why190required. The plain-language line. A <br> in the copy sets the break.
name22required. Set in caps by the card.
footer48required. Credential and employing broker.
phone18
portraitthe agent's transparent cutout or headshot for the ring. This is the picker's field name; agentPhoto, cutout and headshot are accepted too.
bwtrue for the black and white agent, at least half the time

A call

POST /render   { "shape": "legacy-just-sold", "fields": {
  "photo": "https://...house.jpg", "photoKind": "house",
  "stat": "9 days", "address": "1428 Lakeshore Drive", "city": "Norton Shores, MI",
  "facts": ["3 offers", "Over asking", "Closed Sept 5"],
  "why": "Priced right and photographed well, a Norton Shores home still draws multiple offers in under two weeks.",
  "name": "Dave Manley", "footer": "REALTOR® · Legacy Real Estate Partners", "phone": "(616) 935-6511",
  "portrait": "https://...dave-cutout.png", "bw": true
} }

Next shapes in the same pattern: Market Stat, Tip, Review, Open House, then the story format. One module each, generated from the reference builder, registered under a legacy- name.