Generating a press kit straight off the running game
Twelve social cards built from HTML and CSS templates, loaded with real captures off the running game, rebuilt with one command instead of a design tool.
The Cozy Coast press kit is twelve images. Six Instagram stories at 1080 by 1920, six LinkedIn cards at 1200 by 627, covering the Early Access launch and the multiplayer hub drop.
No design tool was opened to make any of them, choom. They are HTML and CSS, rendered by a small Python script, and the shots inside them are captures of the game actually running.
Three commands
npm run press:capture # real screenshots from the running game
.venv/bin/python scripts/press-assets.py # cut them into build/presskit/assets/
.venv/bin/python build/presskit/render.py # every card, launch kit and hub kit
The first one boots the game and captures it. That distinction matters more than it sounds. The other anglers in the hub cards are genuine remote avatars reacting to real session events, so the party list, the name plates, the emote pops and the join notice are all live UI rather than mock-ups.
A press kit built from mock-ups is a promise. A press kit built from captures is evidence. If the UI shifts and the cards stop matching the game, I find out when I regenerate, not when some angler does.
Why HTML and CSS beat a design file
Every template lives in build/presskit/templates/ and shares one stylesheet, kit.css, which mirrors the site design system. That buys four things a binary design file never will.
I can diff it. A change to a card shows up in a pull request as changed lines, not as a blob that is simply different now.
I can restyle the lot at once. When the site palette flipped, the press kit flipped with it, because the cards were already reading the same tokens rather than colours some gonk eyedroppered a year back.
I can crack one open in a browser, tweak it live, then rerun the render. The authoring loop is the one I already run every day.
And there is no seat, no licence, and no file that only opens on one rig.
The sizes are the whole job
Most of the real work in a press kit is not visual. It is fitting text inside the strip a platform will not cover or crop.
Instagram stories are 1080 by 1920, and the platform slaps its own furniture over the top and bottom. The profile row covers the top. The reply bar covers the bottom. So every word in the story cards sits inside the safe area, which means the stories carry their own text and can go out with no caption at all. Slap a link sticker on the store page and they are done.
LinkedIn cards are 1200 by 627, the 1.91 to 1 landscape slot the feed crops to. Hand it anything else and the feed decides what to trim, usually the part with the title on it.
Baking those constraints into CSS means they hold. A card cannot drift into the reply bar between releases, because the layout is a rule rather than a call somebody made once with a ruler.
Steam patch notes are a different animal
Steam’s news editor eats BBCode, so the hub release announcement lives as steam-patchnotes-hub.bbcode.txt and gets pasted in.
Its image tags point at copies served off the marketing site rather than at uploads, because the news editor does not reliably hand you an upload. So the press images get copied into the site’s public folder and deployed, where they resolve at a stable URL:
cp build/presskit/out/{li,ig}-*.png docs/website/public/press/
Those files are deliberately unlinked. Nothing on the site navigates to them. They exist to resolve, a slightly odd category of asset and worth writing down somewhere so future me does not scrap them as orphans.
The part that is still manual
The tally numbers on the stat cards are baked in as text. There are 160,966 fish and 50,418 seagulls sitting in a template as literal characters, and if the tally has moved they have to be pulled fresh from https://cozycoast.website/api/global before a rerun.
I could fetch them at render time. I have not, and I am not sure I should. A press card is a claim about a moment, and a card that quietly rewrites itself with new numbers every time the script runs is harder to reason about than one where updating the figures is a call I made. The note in the README is holding the line for now.
That is the straight state of it: a pipeline fully automatic where automation is obviously right, and deliberately manual at the one point where a number turns into a public claim.
The game those cards are selling is at cozycoast.website, on Steam for Windows and macOS.