Colophon

This page is about the site itself: where its text comes from, what its date means, and the small set of colours, type sizes and shapes that every page is built from. It fits on one screen so that you can read it instead of the stylesheet, and so that the set stays small enough to remember. A set you can remember is one you reuse rather than extend.

The values below are generated from site-css/identity.css. The description beside each colour is the comment on that token's line in the stylesheet. If this page and the stylesheet disagree, the page is wrong, and so is the check that compares them.

Where the text comes from

Prose is written by hand in a file. Tables are generated by the build. You can tell the two apart by looking, and there is no third kind of content.

A page's source file is content/ plus its route: /components/button.md is written in content/components/button.md, and /writing/voice.md in content/writing/voice.md. Every page prints the path of its own source file in the footer, whether or not that file exists yet, so a page with no guidance on it tells you where to write some.

A page exists because a file asked for it, and deleting the file removes the route. Component pages are the exception. A component can appear in appsignal-server before anyone has written about it, so those pages are stamped from one template and the source file is an optional overlay. Everywhere else, the file named in the footer holds every sentence on the page.

Every list on the site is generated from the registry of pages the build wrote, so a list cannot name a missing page or leave out an existing one. This is checked, not assumed.

Hand-written prose gets one check: every component, class and token name it mentions is verified against the product's code at build time, so a page cannot refer to something that no longer exists. That is all it catches. Nothing can tell whether advice has stopped being true, and nothing on this site dates the prose. The next section explains why.

Hand-written pages do not state values. A colour or a size typed into prose would be a second copy of a fact the generated pages already carry, and the second copy is the one that goes stale. Those pages link to the value instead.

There is no full-text index. The box in the rail is a jump-to: it matches the names of pages, components and CSS classes, and the keywords authored for each component, so typing alert reaches the Message page. It does not search the prose. The lists are complete rather than paginated so that find-in-page works on whichever page you are already reading.

The date

Every page carries the same date, and it means one thing: when we last read the product. The footer line Read from appsignal-server@… on … is identical on every page. It is not the build date, not the date anyone edited the page, and not a claim that anything is current.

What it does let you do is distrust a page precisely. Every generated value was read from the product's source at that one commit, so the page is true of that commit and of nothing later. If the product has changed since, this site keeps the old answer until someone moves the pin and rebuilds. When the product and a page here disagree, trust the product. The commit is how you show the page is behind.

Whether the product has moved since is not knowable from here. The build reads a pinned commit and has no network access, so the date says when we looked and nothing about what has happened in the meantime.

Hand-written pages carry no date of their own. They used to: a last_modified: field typed by hand and printed as "last curated …", meant to warn that hand-maintained text goes stale. It was itself hand-maintained and unchecked, and nine of the twenty-one pages that carried it printed "an unrecorded date". It was removed on 2026-09-11 rather than automated. A date derived from git records the last commit that touched the file, and a mechanical pass over frontmatter would re-date every page without a word of prose changing, which would make the text look fresher than it is. No date is better than a meaningless one.

A page's edit history is one click away. The footer links to the file the page is written in, and the repository holds the commits.

What this site publishes about our own repositories

Deep links into our own repositories, and the paths they carry, are allowed. This was settled on 2026-09-11. The audience is internal, so a redaction costs the reader it was meant to protect.

The pipeline has not caught up. Paths read from the product's source are still stripped on the way in by a redactor written under the earlier, stricter rule, so a page naming a stylesheet gives you the filename but not the directory. That is a leftover, not a policy, and removing it is outstanding work.

What stays out regardless: code that is not already in the published Storybook, and anything that looks like a credential.

Colour

namevaluefor
--ground#08090bthe page itself
--paper#0e1116a recessed panel
--raised-top#13161ccard gradient, lit edge
--edge#212630a card's own border — brighter than a rule
--rule#1e232bbetween rows in a table
--rule-strong#2c333dheader from body, chrome from content
--content-default#e9edf3prose, headings, values that matter
--content-secondary#98a2b0table cells — most text on the site
--content-subtle#7b8593provenance, chrome, anything deferrable
--action-rest#3fb6cc8.32:1 on ground — a link, where links are the exception
--action-hover#4dd8ee11.74:1 — pointing at anything clickable
--action-selected#f8b88411.55:1 — where you are, and only there
--good#34d399verdict marks only — agrees, house
--warn#fbbf24verdict marks only — drifts, a gap
--bad#fb7185verdict marks only — inert, absent

Type

body -apple-system, BlinkMacSystemFont, Roboto, sans-serif

mono ui-monospace, SFMono-Regular, "Roboto Mono", monospace

Apple devices use SF and load nothing. Everyone else gets Roboto, served from this site.

Sizes: 40px · 32px · 25px · 20px · 16px · 13px. There is no seventh. Weights: 400 normal · 500 medium · 600 bold.

Roles

Every heading on the site uses one of these roles, and nothing else styles a heading. The tag says how deep the heading is; the role says what it looks like.

rolecomposition
titlebody · 40px · bold · track -0.02em · content-default
sectionbody · 25px · bold · track -0.01em · content-default
subheadbody · 20px · bold · content-secondary
eyebrowbody · 13px · bold · UPPERCASE · track 0.08em · content-secondary

Action

Hue says what kind of thing you are looking at. Cyan is something you can do, violet is where you are, and the three status hues are what we found. Brightness ranks items within a kind; it no longer distinguishes between kinds.

stateis
rest--action-rest, or unmarked where every item is a link
hover--action-hover — always the full hue
pressedopacity: 0.6 — deliberately not a colour
selected--action-selected · medium · a shape mark
selected-within--action-selected, no mark
focusa --content-default outline — deliberately not the hue

Shape

radius 3px (inline code, pills) · 16px (a block-level surface)

--fill-subtle rgba(255, 255, 255, .06) · --measure 70rem

The one control that is not a composition

The nav's current-page mark. It has two grades, "you are on this page" and "you are somewhere inside this section", and a cue that changes shape with the rail: an underline in the narrow strip, a bar in the margin in the wide rail. It is the only control on the site not built from the primitives above. If you find a second one, that is a defect.

Credits

Set in the faces below, redistributed under the SIL Open Font License 1.1. The notice the licence requires ships with the fonts at fonts/OFL.txt.

facefilecopyright
Robotofonts/roboto.woff2Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic)
Roboto Monofonts/roboto-mono.woff2Copyright 2015 The Roboto Mono Project Authors (https://github.com/googlefonts/robotomono)

The wordmark is not in that table because no font serves it. Wafel, on the front page and at the top of the rail, is outlined paths. The word was set once in Fredoka SemiBold and converted to curves, so the site requests no font for it and no stylesheet rule can restyle it. That also puts it outside the check behind this page, which credits @font-face rules and can only see faces the site actually serves. Changing the wordmark means regenerating the drawing; the recipe (face, weight, licence, subset request, geometry) is a comment at the top of site-art/wafel-lockup.svg.

What this page leaves out

This page describes the site, not the product. The product's own tokens are on the value pages, and nothing here is a claim about what AppSignal ships.

No licence is stated for the site's own content, because none has been decided. The credits above cover what is redistributed and nothing else.

Line-heights and letter-spacing are omitted on purpose. There are five of each, they are an implementation detail of the sizes above, and listing them would double the page without giving a reader anything to act on.