The social share card that shows up when someone pastes a link into Slack, X, or iMessage is a
generated PNG, not a hand-drawn image. `bin/rails og:images` builds one per coding-agent landing
page, and `bin/rails og:images:docs` builds one per docs category and page, including the one this
guide is talking about right now.

## How it works

Each task renders an ERB template to a local HTML file, using the site's own design tokens copied
inline (Propshaft-bundled CSS isn't sized for a 1200x630 card, so the template carries its own
copy of the relevant `:root` variables), then screenshots that file with headless Chrome at 2x
device-scale-factor, landing on a 2400x1260 PNG. A browser renders the card rather than an SVG
rasterizer, because the card *is* the Terminal design system at a larger size, and the only
renderer that draws `oklch()` colors and loads IBM Plex the way the live site does is the engine
the live site runs in.

This needs Chrome and network access locally (Selenium Manager fetches a matching driver the first
time, and the card pulls IBM Plex from Google Fonts, the same stylesheet the layout itself loads).
Both are build-time only: the generated PNGs are committed to the repository, and nothing at
runtime or in CI depends on Selenium being available.

## Generating cards

```bash
bin/rails og:images                    # every coding-agent page
bin/rails 'og:images[claude]'          # just one, while tuning the layout

bin/rails og:images:docs               # every docs category and page
bin/rails 'og:images:docs[mobile-apps]' # just one category
```

Docs cards land in `public/og/docs/`, named `<category>--<slug>.png` for an article and
`<category>.png` for a category's own index page. Both tasks share the same underlying renderer, so
adding a new docs page and running `og:images:docs` is the entire workflow; there's no design tool
involved.

## Why a missing card fails loudly

If a page's card hasn't been generated, the site doesn't show a broken image; `ApplicationHelper`
falls back to the site-wide default card (`/og.png`) automatically, so nothing looks obviously
wrong in a browser. That silent fallback is exactly why a spec exists that checks every real page
and category has its own generated file, and fails the build if one is missing. See
`spec/requests/docs_og_cards_spec.rb`. Run the relevant `og:images` task, commit the new PNGs, and
the spec passes again.

## Adding your own custom card

If a specific page wants a hand-supplied image instead of a generated one, blog posts support this
today through the `image` front-matter field, which overrides the generated fallback entirely. Docs
pages follow the same `image` field for the rare page that needs it, though most docs pages are
better served by the generated card, since it stays visually consistent with every other page in
the category automatically.

## Next

You've now covered the whole content and SEO layer. See how the mobile apps reuse these same web
views: [Mobile Overview](/docs/mobile-apps/mobile-overview).
