Skip to content

docs: add a social preview card and a comparison table - #190

Merged
vishr merged 6 commits into
mainfrom
docs/repository-presentation
Aug 24, 2026
Merged

docs: add a social preview card and a comparison table#190
vishr merged 6 commits into
mainfrom
docs/repository-presentation

Conversation

@vishr

@vishr vishr commented Aug 24, 2026

Copy link
Copy Markdown
Member

What this changes

A social preview card. Links to this repository unfurled as a generic grey box on GitHub and in every chat client. docs/media/social-card.png is the image to upload as the repository's social preview.

It is generated rather than hand-drawn. just social-card renders docs/media/social-card.typ at 960pt × 480pt, which is exactly 1280 × 640 px at 96 ppi, the size GitHub expects. The recipe does three things a hand-typed typst compile does not: it pins the typst version (0.15.1, for the same reason just diagrams pins d2 0.7.1), it requires Inter on a font path and fails when the face is missing — typst only warns and exits 0, so the alternative is silently shipping a card in a substitute face — and it renders to a temporary directory, installing the PNG only once the render is known good.

The mark is read from ui/host/public/favicon.svg, the canonical asset internal/brand tracks, rather than copied into docs/media/. A fourth hand-copy of the ribbons would have sat outside that drift guard and kept the old geometry through the next revision.

The footer is pushed down by flexible space rather than placed out of flow. Placed, a longer headline drew the divider straight through the body copy with typst reporting nothing; in flow, the same overflow spills onto a second page and fails the PNG export outright.

A comparison table. The README never contained the words Grafana, Loki, Tempo, Mimir, SigNoz, Jaeger, Prometheus, Datadog, Honeycomb, or ClickHouse, which is what someone types when they are shopping in this space. Each row states the boundary difference rather than a feature score, and the section closes by saying outright that a deployment which outgrows one machine's disk and CPU has outgrown Fanout.

Claims were checked against the code rather than written from memory: the "traces, logs, and metrics into the same store" row rests on RegisterOTLP in internal/ingest/server.go registering all three collector services.

Still manual after this

The social preview image itself is uploaded through Settings → General → Social preview; GitHub exposes no API for it. Use docs/media/social-card.png.

What I ran, and what I did not

Rendering only — this is documentation plus one binary asset, and no Go, browser, or embedded-asset path is touched. Verified that the card renders byte-identically from the canonical favicon, that the recipe fails against an empty font directory and leaves the committed PNG untouched, and that a deliberately overlong headline fails the export rather than overlapping.

The pre-push gate was skipped deliberately. The branch was built in a separate worktree with no node_modules of its own, so just check cannot run there without a fresh install; linking a different checkout's node_modules in made ui-check report every committed browser-asset hash as stale, which is an artifact of a mismatched dependency tree rather than real staleness. CI's Gate passed on the first commit of this branch and is the authority here.

Note: CI has not re-run since 956a449c — the two later pushes triggered only CLA and CodeQL, with no paths filter in ci.yml to explain it. Worth a re-trigger before merge.

@vishr vishr closed this Aug 24, 2026
@vishr vishr reopened this Aug 24, 2026
vishr and others added 5 commits August 24, 2026 06:54
Two gaps in how the repository meets someone who has just found it.

Links to this repository unfurled as a generic grey box on GitHub and in
every chat client. `docs/media/social-card.png` is the image to upload as
the repository's social preview; it is generated from the `.typ` beside it
rather than hand-drawn, so the next edit is a text edit. The header comment
carries the render command, including the font path the card needs — Inter
is not installed system-wide, and without it the card silently falls back
to a substitute face.

The README never contained the words Grafana, Loki, Tempo, SigNoz, Jaeger,
Prometheus, Datadog, Honeycomb, or ClickHouse, which is what someone types
when they are shopping in this space. Each row states the boundary
difference rather than a feature score, and the section closes by saying
outright that a deployment which outgrows one machine has outgrown Fanout.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review of the first commit found three ways the card could go wrong quietly.

The mark was a fourth hand-copy of the ribbons, sitting outside the guard
that internal/brand keeps against ui/host/public/favicon.svg. A ribbon
revision would have updated MarkSVG and its testdata under test pressure
while this copy kept the old geometry indefinitely. Typst reads the
canonical favicon directly now; the render is unchanged.

The PNG had no recipe. `just social-card` renders it and does the part a
hand-typed command cannot: typst warns about an unknown font family and
still exits 0, so the recipe reads the warning back and fails, and renders
to a temporary file so a fallback-face card is never left in the tree. The
typst version is pinned for the same reason d2 0.7.1 is.

The footer was placed out of flow at a fixed offset, so a longer headline
would have drawn the divider straight through the body copy with typst
reporting nothing. It is pushed down by flexible space instead: the same
overflow now spills onto a second page, and a two-page render fails the PNG
export outright.

Verified by rendering: the card from the canonical favicon is identical to
the committed one, the recipe fails against an empty font directory and
leaves the committed PNG untouched, and a deliberately overlong headline
fails the export rather than overlapping.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The managed-services row said those products carry per-gigabyte pricing.
Their pricing models differ from one another and change without notice, so
the claim was both a swipe and a fact this repository cannot keep true. The
row now says what is actually different: someone else runs the system, and
the telemetry leaves the network to reach it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The header still gave a bare `typst compile` line, which no longer works:
the mark now comes from ui/host/public/favicon.svg, and typst sandboxes an
input to its own directory, so the documented command fails on the image
unless `--root .` is passed. It points at `just social-card` instead, which
passes the root, pins the version, and fails on a missing font — none of
which a hand-typed command does.

`mktemp -t social-card` also reserved a name and the recipe appended `.png`
to it, so typst wrote to a path nothing had reserved and the reserved file
was left behind on every run. A temporary directory reserves the whole name.

Verified: `just social-card` re-renders the committed PNG byte-identically.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rebasing onto main brought the documentation site with it, and the site has
the same gap the card was made for: Starlight emits
`twitter:card: summary_large_image` and never an image to pair with it, so
links to fanout.run unfurled as an empty large card.

The card moves from docs/media to site/public, where GitHub still takes it as
the repository preview and the site can serve it at /social-card.png. The
recipe writes there now, and `site-build` runs a check beside check-tables
that asserts every built page carries an og:image, that the target is in the
build, and that its real PNG dimensions match the hand-typed width and
height — CI has no font path to re-render the card with, so that is the part
a gate can honestly do.

Ran `npm run build` in site: 33 pages, both checks pass, and the built head
carries og:image pointing at https://fanout.run/social-card.png.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vishr
vishr force-pushed the docs/repository-presentation branch from 4a1b278 to 7f12f38 Compare August 24, 2026 13:56
@vishr
vishr merged commit fc3abc1 into main Aug 24, 2026
8 checks passed
@vishr
vishr deleted the docs/repository-presentation branch August 24, 2026 14:35
vishr added a commit that referenced this pull request Aug 24, 2026
* docs: add a social preview card and a comparison table

Two gaps in how the repository meets someone who has just found it.

Links to this repository unfurled as a generic grey box on GitHub and in
every chat client. `docs/media/social-card.png` is the image to upload as
the repository's social preview; it is generated from the `.typ` beside it
rather than hand-drawn, so the next edit is a text edit. The header comment
carries the render command, including the font path the card needs — Inter
is not installed system-wide, and without it the card silently falls back
to a substitute face.

The README never contained the words Grafana, Loki, Tempo, SigNoz, Jaeger,
Prometheus, Datadog, Honeycomb, or ClickHouse, which is what someone types
when they are shopping in this space. Each row states the boundary
difference rather than a feature score, and the section closes by saying
outright that a deployment which outgrows one machine has outgrown Fanout.


* docs: gate the social card instead of trusting it

Review of the first commit found three ways the card could go wrong quietly.

The mark was a fourth hand-copy of the ribbons, sitting outside the guard
that internal/brand keeps against ui/host/public/favicon.svg. A ribbon
revision would have updated MarkSVG and its testdata under test pressure
while this copy kept the old geometry indefinitely. Typst reads the
canonical favicon directly now; the render is unchanged.

The PNG had no recipe. `just social-card` renders it and does the part a
hand-typed command cannot: typst warns about an unknown font family and
still exits 0, so the recipe reads the warning back and fails, and renders
to a temporary file so a fallback-face card is never left in the tree. The
typst version is pinned for the same reason d2 0.7.1 is.

The footer was placed out of flow at a fixed offset, so a longer headline
would have drawn the divider straight through the body copy with typst
reporting nothing. It is pushed down by flexible space instead: the same
overflow now spills onto a second page, and a two-page render fails the PNG
export outright.

Verified by rendering: the card from the canonical favicon is identical to
the committed one, the recipe fails against an empty font directory and
leaves the committed PNG untouched, and a deliberately overlong headline
fails the export rather than overlapping.


* docs: drop a pricing claim about other vendors

The managed-services row said those products carry per-gigabyte pricing.
Their pricing models differ from one another and change without notice, so
the claim was both a swipe and a fact this repository cannot keep true. The
row now says what is actually different: someone else runs the system, and
the telemetry leaves the network to reach it.


* docs: correct the card's own instructions

The header still gave a bare `typst compile` line, which no longer works:
the mark now comes from ui/host/public/favicon.svg, and typst sandboxes an
input to its own directory, so the documented command fails on the image
unless `--root .` is passed. It points at `just social-card` instead, which
passes the root, pins the version, and fails on a missing font — none of
which a hand-typed command does.

`mktemp -t social-card` also reserved a name and the recipe appended `.png`
to it, so typst wrote to a path nothing had reserved and the reserved file
was left behind on every run. A temporary directory reserves the whole name.

Verified: `just social-card` re-renders the committed PNG byte-identically.


* docs: give the new site the card as its og:image

Rebasing onto main brought the documentation site with it, and the site has
the same gap the card was made for: Starlight emits
`twitter:card: summary_large_image` and never an image to pair with it, so
links to fanout.run unfurled as an empty large card.

The card moves from docs/media to site/public, where GitHub still takes it as
the repository preview and the site can serve it at /social-card.png. The
recipe writes there now, and `site-build` runs a check beside check-tables
that asserts every built page carries an og:image, that the target is in the
build, and that its real PNG dimensions match the hand-typed width and
height — CI has no font path to re-render the card with, so that is the part
a gate can honestly do.

Ran `npm run build` in site: 33 pages, both checks pass, and the built head
carries og:image pointing at https://fanout.run/social-card.png.


---------
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