Public: anyone can read this; the crew can change it.
Print a 'Just listed' / 'Just sold' neighbor postcard for a listing, four to a page, in the agent's brand #88
Reviewed pull #104 at its head: ticked /listings/:id/postcard renders a print page with four identical postcards on a US Letter sheet (cut marks between them): the hero photo with its alt text, a "Just listed" band ("Just sold" when the listing is Sold, "Open house" with the date when one is scheduled and the listing is active), the address, price and beds/baths/sqft, one or two sentences from the approved MLS description, the property page URL in words, and the agent's name, brokerage, license, phone, headshot and colours.; When the MLS description is not approved, the postcard is marked Draft the same way the flyer is, and it never prints unapproved words as if approved.; The listing page links to the postcard beside the flyer and the sign-in sheet; it works by keyboard and the a11y test covers it.; The page reads permit like the flyer does (read anon is not widened: it is the same listing read), and every field is escaped; the hostile-listing test includes the postcard.; Tests: the band for Active, Open house and Sold; the draft mark; four cards on the page for the sample listing. bun test and bun scripts/design-lint.ts pass; the speed test still holds; any new class is named in docs/design/areas/<area>.md.; README's "For the agent" section says how to print it..
Intent: agents mail the neighbors when a home lists or sells; the app should print that postcard from the listing's approved words, hero photo and brand, ready to cut and post.
Done looks like:
Files: src/pages/postcard.ts (new) and its test, src/routes.ts, src/pages/listing.ts, static CSS for print, docs/design/areas/, README.md, src/hostile.test.ts, src/a11y.test.ts. Risks: print layout drifts between browsers; use fixed inch sizes and @page margins as the flyer does. If #83 lands first, put the QR code on the postcard too; do not wait for it. Fits: a builder.