Documentdocs/og/README.md
SurveyStream — Open Graph card
1200 × 630, dark slate, dual-audience. Self-contained: the three webfonts are embedded as base64, so the file renders identically on any machine with no network and no font installs. That matters — an OG card rendered with a fallback face is a different design.
Files
| File | Size | Notes |
|---|---|---|
og-card.html | 291 KB | The card. Open it and screenshot, or use the commands below. |
og-card.png | 425 KB | 1200 × 630, exported. |
og-card@2x.png | 1232 KB | 2400 × 1260, for retina previews. |
Exporting
Chrome headless gives a pixel-exact export with no cropping:
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
# 1× — 1200 × 630, the canonical OG size
"$CHROME" --headless --disable-gpu --hide-scrollbars \
--window-size=1200,630 \
--screenshot=og-card.png \
"file://$PWD/og-card.html"
# 2× — 2400 × 1260
"$CHROME" --headless --disable-gpu --hide-scrollbars \
--window-size=1200,630 --force-device-scale-factor=2 \
--screenshot=og-card@2x.png \
"file://$PWD/og-card.html"
--hide-scrollbars is not optional: without it Chrome reserves gutter width and the card is
cropped a few pixels on the right.
Markup
<meta property="og:image" content="https://surveystream.com/og-card.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:title" content="Turn Real-Time Feedback Into Instant Value">
<meta property="og:description" content="Survey takers cash out in minutes. Research teams get a verified, live data stream they can build on.">
<meta name="twitter:card" content="summary_large_image">
Serve the 1× PNG as og:image. Most platforms re-encode anyway, and the 2× file mainly costs
bandwidth. Keep it under 1 MB — several scrapers refuse larger images outright.
Composition notes
- The scrim is doing the real work. The stream visualisation lives on the right and is masked
out of the left third; on top of that a
linear-gradient(96deg, …)scrim holds a clean field under the headline. Without it the waves run straight through the type — I built that version first and the headline was unreadable. - Tested at feed size. Rendered down to 504 px wide, which is roughly what a timeline shows.
The headline,
12,480and$1,284.50all still read; the mono footer row is at the edge of legibility, which is why nothing load-bearing lives there. - Numerals follow the type system:
tabular-numsthroughout, and the payout amount carries"tnum" 1, "lnum" 1, "zero" 0— slashed zero explicitly off, because inside money it reads as a correction mark. - Colours use the brand accents (Stream / Signal / Pulse) on the specified
#0F172Aground.
Two honest caveats
1. The logo mark is below its own small-size threshold. The lockup renders at 44 px, which puts
the mark at roughly 33 px — under the 40 px floor documented in ../logo/interlock/README.md, and
far under it once a feed scales the card to half size. It degrades gracefully: the solid base still
reads as an S and only the thin accent softens. That is an acceptable trade for a card that is
mostly viewed large, but if you would rather be strict, swap the lockup for
../logo/interlock/lockup-horizontal-mono.svg (base only) and tint it Mist.
2. backdrop-filter does not survive server-side OG rendering. The glass panel depends on it.
Satori and @vercel/og do not implement backdrop-filter, so generating this card at request time
in that stack would render the panel as a flat translucent rectangle — losing the effect but not
breaking the layout. Options, in order of preference: ship the exported PNG (what this folder does);
or if you need per-page dynamic cards, replace the glass with an explicit gradient fill that
approximates the blur.
Tailwind mapping
Written as plain CSS with custom properties so it works with or without a framework. If you port it:
| Here | Tailwind |
|---|---|
.og | relative w-[1200px] h-[630px] overflow-hidden bg-[#0F172A] |
.panel | w-[356px] rounded-[22px] border border-white/[.16] backdrop-blur-[22px] backdrop-saturate-150 |
.scrim | absolute inset-0 z-[2] bg-[linear-gradient(96deg,…)] |
h1 .lit | bg-gradient-to-r from-[#5FE3EC] to-[#2FE3A2] bg-clip-text text-transparent |
The inset box-shadows on .panel have no clean utility equivalent — keep them as an arbitrary
shadow-[…] value or a small component class.