Skip to content

feat(website): the social card shows the product, and the brand gets a real mark - #1047

Merged
blove merged 3 commits into
mainfrom
blove/social-card-kit
Sep 7, 2026
Merged

feat(website): the social card shows the product, and the brand gets a real mark#1047
blove merged 3 commits into
mainfrom
blove/social-card-kit

Conversation

@blove

@blove blove commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

The share card was dark, centred, and assembled from a seam and a glow that exist nowhere else on a site that is hardwired light, so the page it opened looked like a different product. It now renders on the site's own ground through a shared kit, and it shows the product instead of only asserting it.

  • A shared card kit at src/app/card/: the rail rule and mono eyebrow, the BrowserFrame chrome with its traffic lights and URL pill, the pills, and the wordmark. Both card routes render through it, which retires the near-black blue the blog card alone used.
  • The frame is drawn, not screenshotted. Three beats: the user asks to delete stale backups, the agent answers with the size and the warning, and an Approve/Decline pair waits on a human. Every screenshot we own carries a sidebar, a devtools panel, or a table of storage paths, none of which survive feed scale.
  • A real brand mark. The airplane was the system emoji, a different picture on every platform. A drawn paper plane now serves the nav and footer wordmark, the card, src/app/icon.svg as the favicon, a regenerated favicon.ico, and a square logo that lets the Organization structured data finally assert a logo.

Two constraints found while prototyping

  • Satori cannot render WebP. A WebP data URI kills the render worker: no error, no response, the connection closes while the server survives. The same image as PNG renders fine. Every screenshot in public/screenshots is WebP.
  • Two of the three fonts were fetched at render time. Inter and JetBrains Mono were scraped from Google Fonts on every render, failing silently when unreachable — a prototype rendered its mono eyebrow in serif and nothing reported it. All four faces are now bundled by scripts/build-card-fonts.py, instanced to one weight and subset to Latin; together they are 359KB, less than the single unsubsetted Garamond they replace.

Verification

  • vitest run --root apps/website: 1335 passed.
  • New card.spec.ts asserts the hand-copied palette still matches theme.css, that all four fonts are present and static rather than variable, and that the alt text quotes the positioning copy and describes the approval. Both guards were mutation-tested: breaking a token and removing a font each fail the suite.
  • New end-to-end check asserts /opengraph-image returns 200 with image/png.
  • Rendered and inspected locally: the default card, a blog card, the nav wordmark, and the app icon.

Design: docs/superpowers/specs/2026-09-07-social-card-kit-design.md.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
threadplane Ready Ready Preview Sep 7, 2026 8:32pm UTC

Request Review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

blove and others added 2 commits September 7, 2026 13:17
One card kit on the site's own light surface, showing the approval beat
inside the site's browser frame. Records two constraints found while
prototyping: Satori kills the render worker on WebP, so card art must be
generated PNG; and Inter and the mono face are fetched from Google Fonts on
every render, so they should be bundled like Garamond already is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…a real mark

The card was dark, centred, and built from a seam and a glow that exist
nowhere else, so the light page it opened looked like a different product.
It now renders on the site's own ground through a shared kit: the rail rule
and mono eyebrow, the BrowserFrame with its traffic lights, the pills, the
wordmark. Inside the frame, three beats drawn rather than screenshotted —
an ask, a proposal, and an Approve/Decline pair — so the card shows the
human-in-the-loop claim the copy makes.

The blog card moves onto the same kit, which retires the near-black blue it
alone used.

The airplane emoji is replaced by a drawn paper plane, shared by the nav and
footer wordmark, the card, src/app/icon.svg as the favicon, a regenerated
favicon.ico, and a square logo that finally lets the Organization structured
data assert a logo.

Two constraints found while prototyping and recorded in the spec: Satori kills
the render worker on WebP, which rules out every screenshot we own; and Inter
and the mono face were fetched from Google Fonts on every render, failing
silently when unreachable. All four faces are now bundled, instanced and
subset by scripts/build-card-fonts.py, and together are smaller than the one
unsubsetted Garamond they replace.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@blove
blove force-pushed the blove/social-card-kit branch from 5ac8f74 to 5fc3840 Compare September 7, 2026 20:17
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@blove
blove merged commit 7a104d8 into main Sep 7, 2026
76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant