The Fire Computer

Design system/v0/the constraints, stated for readers/Built 2026-08-12

Simple. Sharp.
Nothing decorative.

Every page of The Fire is a rendering of a public record. The design has one job: make the number legible and make its provenance impossible to lose. Everything below is a constraint, not a preference.

01 — The one rule everything else follows

The machine register means a machine made it.

The type system carries a claim. The prose register is for language a human wrote. The machine register is for anything derived from the record — counts, dates, division numbers, session IDs, hashes, percentages, sources. The reader can tell at a glance which parts of a page are argument and which parts are arithmetic, without being told.

Until 2026-08-12 the machine register was a second family, Geist Mono. It is now the same Satoshi as the prose, and the register is carried by treatment instead: small sizes, wide-tracked uppercase for labels, and tabular figures for every numeral. The claim survives the font. What separates arithmetic from argument was never the typeface — it was that the arithmetic is set like an instrument reads, not like a sentence.

Prose — Satoshi

Headlines, prose, party and member names, section titles, any sentence.

Nathaniel Erskine-Smith has broken with his own caucus more often than any other sitting member.

Machine — Satoshi · tabular figures

Every numeral. Labels. Dates. Vote IDs. Sources. Snapshot hashes.

2,691 votes · 73 dissents · 2.71%
44-1 / №348 · 2026-06-18 · aebf3673…4bc3f
Why this is not just taste

An autonomous accountability machine has to be visibly separable from its author. The typographic split is the cheapest possible version of that disclosure, and it runs on every page without anyone maintaining it.

02 — Type scale

Six sizes, one family, one weight axis.

Satoshi runs at 400 for prose and 500 for anything structural. There is no 600+, no italic, and no second family. Tight negative tracking on display sizes; wide positive tracking on uppercase labels. Nothing in between.

Display3.1rem / 500 / −.04em Party discipline
Head1.9rem / 500 / −.03em Almost nothing happens
Sub1.25rem / 500 / −.02em What was being voted on
Body1rem / 400 / −.011em Of 1,270,388 votes cast in the House of Commons since 2006, 1,814 broke with the member’s own caucus.
Small0.86rem / 400 Independents are excluded from this chart. The source database records no party position for them, so their dissent flag is an artefact.
Numeralmachine / 500 / tabular 1,270,388
Labelmachine / 500 / +.18em / caps Votes cast since 2006
Charset AÀÂÇÉÈÊËÎÏÔÙÛÜŒaàâçéèêëîïôùûüœ ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 —–’“”§№%·×→
Machine specimen 0123456789 −+×÷=%‰ ()[]{} ../:;-_ #№§ aebf3673…4bc3f

One family ships, as one variable file, from our own origin, with a one-year immutable cache. Satoshi's default figures are proportional — its 1 is half the width of its 0 — so tabular figures are switched on for the whole page; a column of figures meant to be compared down a page has to keep its digits in register. What the swap gave up: Geist Mono's slashed zero and its fixed advance disambiguated 0/O and Il1 in dense identifier columns, and Satoshi does neither. The identifiers on this site are short and contextual — session IDs, vote numbers, hash prefixes — and the trade was made with that known. Satoshi is served byte-identical to the file the foundry distributes: unsubset, unconverted, still a TrueType variable font rather than a WOFF2. That costs about 70 kB and it is deliberate — see §07. satoshi-variable.ttf 124 kB, gzipped 54 kB over the wire. geist-mono.woff2 stays in /assets, unreferenced, as the revert path.

03 — Ground and marks

Cold ground. Bone marks. One lit accent.

The palette is almost entirely neutral so that the single warm value means something when it appears. Lit amber is reserved for data that crossed a threshold — a dissent, a break, an exception. It is never used for chrome, never for a hover state on a link, never for emphasis in prose.

There is one ground, and it is this one. The riding pages shipped light first, on the argument that a reference document people cite from wants to look like paper. That was overruled on 2026-08-05 — one site, one surface, and a reader arriving at their own constituency from the essay should not feel they have changed buildings. There is no prefers-color-scheme branch anywhere on the site. The single exception is @media print, where the tokens invert wholesale: a black flood at 300 dpi is unreadable and costs a cartridge, and the riding pages are meant to be printable. Type, structure, figures and sources are otherwise identical — the printout is the same document, not a reduced one.

One token exists only because of that decision. Six rules on the riding pages were set in --ink, which was correct as near-black at 2 px on paper and became a light source at near-white on ash. --rule-strong #4A4740 carries the same structural weight without emitting light. A value that is right on one ground is not right on the other simply inverted.

ground#0A0A0BThe page. Never lighter.
ground-2#0F0F10Row hover, inset panel.
raise#141416Card, callout.
rule#232326Structural divider.
rule-2#1A1A1CTable row divider.
bone#ECE7DDHeadlines, numerals, primary text.
bone-2#B9B3A8Body prose.
muted#807B72Secondary, table headers.
dim#57544ELabels, captions, provenance.
dark#37352FUnlit data. Absence.
lit#FFCF8AA dissent. Earned, never decorative.
lit-hot#FFE6C215+ dissents on one division.

Party colour is identity, never judgement.

Each party's value is derived from its own live brand hex, lifted in lightness at constant hue so it survives a dark ground. The official value is disclosed on every page that uses it. No party is ever assigned a warmer or cooler value to imply anything about its record.

Votes cast and dissents recorded, by caucus, 2006-05-08 to 2026-06-18. Denominator excludes recorded absences and paired votes, per correction 0001; /discipline still shows the withdrawn figures and says so.
PartyDisplayOfficialVotesDissentsRate
Conservative#5C8FD6#142F52510,1838311 in 614
Liberal#E8555C#D71920479,1287751 in 618
NDP#F58220#F58220189,6811271 in 1,494
Bloc Québécois#51A5E1#08023678,220201 in 3,911
Green#3FBF63#20A2424,6850

The Bloc's own post-2021 brand colour is the deep navy #080236, not the light blue every broadcaster uses. We use a lifted version of the blue they also ship, because navy is illegible on this ground — and we say so here.

04 — The number block

A figure never appears without its denominator.

The standard component. Number in mono, label in caps mono, and a plain sentence underneath saying what the number is out of. The third line is not optional — a count without a denominator is a talking point, not a fact.

1,270,388Votes cast Every yea and nay by every member, 2006-05-08 to 2026-06-18.
1,814Broke with caucus 0.143% of all votes cast. One in every 700.
4,116Divisions with none Of 4,654 recorded divisions — 88.4% had zero dissent.

05 — Standing rules

Eight things the design may not do. Three it must.

Revised 2026-09-18, after the author read the list back and said it was overly prescriptive and mostly not his. The git history agreed with him. The original eight were written in one pass on 2026-08-05 against a four-word brief — “simple, sharp, Satoshi font and Geist Mono for numbers” — and everything beyond that was invented here and then carried for six weeks in the voice of settled law. The two that were doctrine rather than craft were both later overruled by the person who owns the project: 01 (“no flame imagery, ever”) within three hours, and 03 (“no score, rank, grade, or league table”) three days later. Nought for two. What survived is the craft — sourcing, disclosure, provenance, not lying with a picture — and that is the pattern worth knowing before reading any of it.

These are defaults with stated reasons, not law. Each one names what it protects; if the reason does not apply to what you are building, say so on the page and proceed. A rule that cannot be argued out of is a rule nobody understands.

  1. The mark never encodes data.The flame may be large, may set a page’s tone, may be the loudest thing on screen. What it may never do is sit inside a chart, beside a figure, or next to one jurisdiction and not another — because a flame placed against a number is a judgement about that number, and rule 02 covers what happens next. Scale is a design choice. Adjacency to data is a truth claim. Amended 2026-08-05, rewritten 2026-09-18. The rule first read “No flame imagery. Ever.” — overruled within hours by the author, who owns the mark and wanted it used. What replaced it capped the mark at 24px, once per page; that cap was this document managing a fear of branding rather than protecting a property, and the author had already asked twice for the flame to be bigger. The load-bearing half — no flame inside the data — is what is left, now stated as its own reason. What the mark is allowed to mean is section 06.
  2. The picture may never contradict the sentence next to it.Ten bugs of exactly this class have shipped and been caught in screenshot review: a disclosed artefact rendering as the longest bar, a matrix reading backwards, glow bloom making 11.6% look like a third of the field, a masthead dot pulsing as though the page updated live when the record arrives in a monthly bulk load. Every chart is reviewed as an image, not as source. The same applies to the type: no synthetic oblique, no faux bold. A skewed roman is the rendering claiming an italic exists when none was drawn — which is exactly what shipped on the riding pages until a screenshot caught it.
  3. The Fire ranks jurisdictions, outcomes, and itself. It never ranks people.Any ranking ships with its methodology, its source, and its snapshot hash. Countries, provinces, cities, policies and this project’s own conduct can be placed in an order, because an order over those is an argument anyone can re-run and rebut. A member of Parliament cannot. A league table of the worst MPs is a target list with a chart on it, and the machine that publishes it has stopped counting and started sentencing. Amended 2026-08-08, on the author’s instruction. This rule read “No score, rank, grade, or league table. Counting is the whole product.” It was too wide — it forbade a sourced comparison between Canada and the OECD, which is among the most useful things this site can publish, in order to prevent a harm that only ever applied to individuals. The safety property is what survived, and it is now stated by name rather than held by accident. Reaffirmed and promoted 2026-09-18 — “I don’t mind ranking things, I think it’s worth it… this should be about where does Canada rank in the list globally.” Where Canada sits in an order is frequently the finding, not a side effect, and a page holding a rank it declines to state is withholding. Print the position, the field size, the vintage and the query. #22 of 84 is a fact; 22nd — poor is a violation of rule 02.
  4. Every number links to its source.Not a methodology page — the actual division, the actual bill, the actual query. A figure the reader cannot follow home is an assertion.
  5. The disclosure travels with the thing.Caveats live beside the chart they qualify, in the same viewport, at readable size. Never in a footnote, never behind a toggle. Corollary revised 2026-09-18. This rule used to mandate stacked record-blocks below 40rem — one block per row, every field re-labelled. The author called the result “a printout of a database table” and numeric tables were rebuilt as tables. The general form of that objection is rule 11: the caveat has to stay on screen, and the way to keep it on screen is to make the page denser, not to make the row taller. Verbosity is not honesty.
  6. Motion is reveal only.Data may fade or draw in once on entry. Nothing loops, nothing pulses, nothing draws attention to itself after it has arrived. Hover changes colour, never position — a card that moves is a card asking to be liked. All of it respects prefers-reduced-motion.
  7. Assets are vendored.Fonts and libraries are served from our own origin with a one-year immutable cache. A page that claims to be independently verifiable should not require a third party to be up — and no reader looking up their own MP should have their address handed to a font CDN. This does not forbid search. It forbids Algolia. A prebuilt index shipped as a static asset and matched in the browser satisfies this rule completely, and is the better tool for the actual use anyway.
  8. Every page footer carries the snapshot date and hash.Two people comparing numbers a month apart need to be able to tell whether they disagree or whether the record moved.
  9. Every page says what could be, not only what is.A count with no future in it is a coroner’s report. This site publishes what Canada measurably is and what the same measurement would look like if the country did the thing — the target, the gap, the jurisdiction that already cleared it, the date by which the arithmetic still works. That is allowed to be aspirational. It is not allowed to be fictional: a projected line is drawn in the chart’s own grammar as a projection, its inputs are stated, and where possible its inputs are editable so a reader can disagree in place. The gap between the two registers is not a compromise to manage — the distance between the measurement and the ambition is the most useful number here. Added 2026-09-18, on the author’s instruction: “an accountability machine, but also a dream machine a little bit.” The list had, until that day, nothing in it about the point of the thing. That is how a design system ends up prescriptive and small.
  10. Every page ends with something a reader can do.Not an email capture — the Undertaking forbids collection until there is something described to join. A thing to do is the riding this affects, the member to write to, the bill at its current reading, the figure to quote and where it came from, the page that argues the other side. A reader who has just understood a number and has nowhere to put that understanding has been entertained, not equipped. The failure to watch for is a call to action that outruns its evidence: the action must be as sourced as the number above it.
  11. The phone is the design target, and density is the point.Every page and every data visualisation is designed at 390px first and allowed to expand — not designed at 1280 and made to survive. Dense is the goal, not the compromise: “it shouldn’t be huge on mobile — you should fit a lot of information on the screen. Not a crazy amount. The scale should be correct.” A chart that becomes a single number on a phone has not adapted, it has surrendered. Horizontal scroll inside a table is permitted with a sticky first column; horizontal scroll of the document never is. Measured, not asserted: scrollWidth === clientWidth at 390 on every page, every render pass, before the desktop pass rather than after.

06 — The mark doctrine

We don’t burn the leaf.

Established 2026-09-18, and the author raised it as the non-negotiable one: “It never burns the maple leaf. We never show visualisations of the flame engulfing the maple leaf — that’s sacred… the visual of fire has to be less destructive and scary. It’s not about burning, it’s about warming, or like roaring… we want this to be a symbol that gets spread far and wide, but it needs to stand for something.” A mark that spreads without a doctrine acquires one from whoever picks it up. This is here so the meaning travels with the file.

  1. The fire never consumes the leaf.No composition in which flame is eating, engulfing, charring, silhouetting or replacing a maple leaf, a flag, a map of Canada, or a province. Not as illustration, not as a share card, not as a loading state, not ironically, not once. The reason is legible in half a second, which is the whole point: a flame eating a national symbol is the visual grammar of decline — it is how you illustrate a country in crisis, a currency collapsing, a protest against the state. This project is an argument that Canada should be enormous. Putting that argument under a picture of Canada burning hands the reader the opposite thesis before they have read a word. The leaf is the country. The fire is the country’s energy. They are on the same side.
  2. The fire is doing work, not damage.Five registers are licensed, and they are the same five whether the subject is a cold country or an energy exporter. Hearth — fire that makes a cold place survivable; the winter argument, the reason anyone is here. Forge — fire that turns ore into things; manufacturing, making rather than only extracting. Refinery, turbine, reactor — fire as generation; the resource base, stated without apology. Signal fire — fire lit to be seen from far off; the project itself. Roar — fire as volume and force rather than as harm; ambition. Out: wildfire, arson, scorched earth, ash-as-aftermath, burn-it-down, the flame over the flag, anything where the fire’s subject is a victim.
  3. The record may show fire destroying. The mark may never mean it.The sharp case, because this site contains it: /firewatch counts hectares burned, and must keep doing so, because wildfire is a measurable fact about Canada. The flame in its masthead is still the hearth. A page may count a catastrophe; the identity does not get to borrow the catastrophe’s imagery for effect. The test for any new asset — share card, hero, chart furniture — is three questions, all of which must answer no. Does the fire consume anything? Is a national symbol its subject? Would it work on a placard at a protest against Canada?
  4. The ground is night, not ash.A correction that falls out of the rules above and costs nothing. This document described the palette as “cold ash” from the day it was written. Ash is what is left after a fire has consumed something — the palette was named for the wrong half of the metaphor, and it quietly agreed with the one picture rule 01 here forbids. No value changes. The ground is the cold this country sits in; the single lit accent is the fire against it. That makes the one-saturated-colour rule self-evident rather than arbitrary: there is one warm thing in a cold place, and the design is a picture of that.

07 — Grid and rhythm

One column, 940px, generous rules.

Prose is capped at 38em regardless of container width. Sections are separated by a 1px rule at --rule and 5.5rem of space, always in that order — the rule belongs to the section beginning, not the one ending. Data components go full width; sentences never do. Charts are the only elements permitted to exceed the text column.

08 — The Satoshi problem

The sans is Satoshi, and it is served in known tension with its licence.

Satoshi is distributed under the ITF Free Font License. It is free for commercial use, but §02 reads: “You are not allowed to transmit the Font Software over the Internet in font serving or for font replacement … without the prior written consent of the Licensor,” and the same section prohibits modifying the file. The licensed delivery path is the Fontshare API, from their CDN.

The CDN is a legitimate way to use the font, and for most sites it is the obvious answer. Here it costs two things: an external dependency on a page that claims to be independently verifiable, and every reader's IP address handed to a third party at the moment they look up their own MP's voting record. The second one is the real objection, and it is the one rule 07 exists to prevent.

So there is no clean option. Self-hosting is outside the licence as written; the CDN is inside the licence and outside our own rules. On 2026-08-05 the author chose to self-host, having been shown the clause, and accepted the risk. That is recorded here rather than quietly absorbed, because a project that asks members of Parliament to live with their record on a public page has to be able to do the same.

What the decision cost, and what was done to limit it

The file is served unmodified. §02 bars two separate things: serving the font, and modifying it. Subsetting it to Latin would have saved roughly 70 kB and converting it to WOFF2 another 10 kB — and both are arguably modifications. Shipping the exact bytes the foundry distributes means the arrangement is outside one clause instead of two. The 124 kB is the price of that, paid on purpose.
Written consent is still worth asking for. ITF grant it routinely. Nothing is blocked on it, and if it is refused, reverting is two CSS variables and two font files — Geist and Geist Mono both still sit in /assets for exactly that day. Since 2026-08-12 the exposure is larger, not smaller: Satoshi now carries every glyph on the site, so the licence question covers the whole page instead of the prose. Recorded, not absorbed.

The same page components set twice: on the left in Geist, on the right in Satoshi. Both use Geist Mono for numerals.
Left: Geist, which shipped first. Right: Satoshi, which is what you are reading. Same copy, same sizes, same colours, Geist Mono for numerals in both — the image dates from the 2026-08-05 comparison, before the numerals moved to Satoshi too on 2026-08-12. Rendered locally from the font files, so this page still makes no third-party request.

The two faces are not interchangeable and the swap was not free. Satoshi's x-height is 0.500 em against Geist's 0.530, so it reads about six per cent smaller at the same size; every body size on the site went up to compensate. Its advance is 4.7% wider on the same string, so tracking tightened from −.005em to −.011em. Its descender is shallower and it carries a 100-unit line gap, so leading came down from 1.62 to 1.60. Its cap-to-x ratio is 1.48 against Geist's 1.34 — bigger capitals over smaller lowercase, which is why the uppercase mono labels sit beside it without looking undersized. And it draws no italic at all, in any of its five weights, which is why rule 02 has a clause about synthetic oblique.