Published surface · Design Office

Silent Protocol IncDesign office

Brandbook

A working register of design systems, the rules that make each one itself, and the honest limits that decide where it belongs.

Holdings 0 systems House system Signal DS v1 Registry state Measured · current
Accession registerGround × acting colour
Every holding, drawn from the registry

How to read itEach column is one system. Height records accession order; colour records its ground and acting channel. The plate redraws when the registry changes.

The catalogue

Preview in place, or open the live site

The house run

The catalogue, held to its own rules

Every site in the catalogue above demonstrates the sixteen governing artifacts in its own paint. This page did not — which made the brandbook the one page in the repository that described the system it belongs to instead of showing it. Below is the office system doing the same work: one section per artifact, in bone and plum, each closing with the clause it evidences.

A03 · Tokens

Every value has one home

Nothing on this page is styled outside this block. The office palette is generated from tokens/tokens.json and inlined; the swatch beside each name is painted by the token itself, so a drifted value shows here first.

--sp-office-bgground
--sp-office-surfaceraised
--sp-office-sunkenrecessed
--sp-office-linehairline
--sp-office-textprimary
--sp-office-text-2secondary
--sp-office-text-dimquiet
--sp-brandcontrol
--sp-brand-softcontrol wash
--sp-brand-hovercontrol hover

Ten tokens, and a dark pair for each under prefers-color-scheme plus an explicit data-theme override, so a chosen theme beats the system default in both directions. A semantic name says the job — there is no --plum here, only --sp-brand.

The block itself
:root {
  --sp-office-bg:      #F3EFEE;
  --sp-office-surface: #FFFFFF;
  --sp-office-sunken:  #E3DEDC;
  --sp-office-line:    #CFC9C6;
  --sp-office-text:    #161013;
  --sp-office-text-2:  #3E3539;
  --sp-office-text-dim:#6E6368;
  --sp-brand:          #6B3D5B;
  --sp-brand-soft:     #FFF5FB;
  --sp-brand-hover:    #512742;
}

A03 §4 — a semantic name says the job, never the appearance

A04 · Typography

One ratio, applied

Three families and six steps. Each step below is the size this page actually uses for that job — the specimen is not a mock-up of the ramp, it is the ramp.

MastheadBrandbook
SectionThe catalogue
Sub-headHow this catalogue grows
BodyEvery entry carries what is wrong with it as well as what works.
SmallPreview in place, or open the live site.
Label · monoAccession SIG–01

Display is a grotesk, body is a humanist sans, and mono carries every accession number and token name on the page. Three roles, three families — a fourth would have no job to do.

A04 §4.3 — the scale is generated, never chosen per use

A05 · Colour

One chromatic channel, on purpose

A catalogue must not compete with what it holds. The office palette therefore reserves a single chromatic channel — plum, for anything you can press — and carries status with shape and words instead of hue.

press
--sp-brandInteractive. Never decorative, never a background for prose.
chosen
--sp-brand-softThe wash behind a pressed filter, and nothing else.
ground
--sp-office-bgThe page. Every contrast ratio is measured against it.
raised
--sp-office-surfaceA card. One step up, no shadow.
sunken
--sp-office-sunkenA toolbar or a code block. One step down.
text
--sp-office-textPrimary. Secondary and quiet are steps off it.

Status without a status colour

House system Evaluated Retired

Three states, one hue. The house entry earns the chromatic channel because it is the only one that is also a decision; the rest separate by label. The honest note: this buys restraint at the cost of a fast scan — a reader must read the chip rather than glance at it, which is the wrong trade for a dashboard and the right one for a shelf.

A05 §4.2 — a reserved channel is never borrowed for decoration

A26 · Surface

One separation strategy, everywhere

Three ways to say “this is a different thing”, and a rule for which to use. The page spends the third one exactly once.

hairline

Separates peers. Every card and every table row in this catalogue.

weight

Carries meaning. A recessed ground marks chrome that is not content.

elevation

Reserved for what is genuinely above the page. Here: the record sheet, and nothing else.

Radius is 3px throughout — enough to read as drawn rather than cut, small enough that a 1px hairline still meets it cleanly. Nothing flat on this page carries a shadow.

A26 §4.1 — nothing flat carries a shadow

A06 · Layout

The grid is load-bearing

Twelve tracks, and five widths that each exist for a reason. The catalogue grid does not pick a column count — it names a minimum card width and lets the container decide, which is why it survives being read on a phone.

Twelve tracks

Eight tracks is the widest a column of prose is allowed to be.

Widths, and what each is for

1180px
page
62ch
prose
44ch
notice

Gutter is clamp(1.25rem, 4.5vw, 3.5rem): it grows with the viewport and then stops, so a wide monitor does not push the margins into the text.

A06 §4.4 — width is earned, not taken

A07 · Motion

Motion means something, or it is off

Six durations on one easing. Press the button and every track below runs at once, so the difference between a state change and an entrance is visible rather than asserted.

90ms
140ms
180ms
240ms
320ms
560ms

One easing, cubic-bezier(.2,.7,.3,1), held in --tap. The index plate at the top of this page and the marks on every card obey the same block, and all of it — including this demonstration — resolves instantly under prefers-reduced-motion. The animation is removed, not merely shortened.

A07 §4.5 — reduced motion is a designed state, not an absence

A10 · Assets

Icons are constructed, not drawn

One 24-unit grid, one stroke weight, butt caps, and currentColor throughout, so an icon takes its control’s colour in every state without a second asset.

search
plate
accept
open
add
record
16 · 20 · 24

Never filled, never a second weight. The grid behind each cell is the construction grid, at 0.5rem — every terminal above lands on it.

A10 §4.1 — never filled, never a second weight

A08 · Content

One word per concept

The catalogue names things once. A system is a system, its identifier is an accession, and the thing you open is a record — never an entry, an ID or a page depending on where you happen to be standing.

Not thisThisBecause
Oops! Nothing foundNo systems match “dense”.States the fact, names the term.
Entry / item / tileSystemOne word for one concept.
ID / number / refAccessionThe register already named it.
Utilise, leverageUseShorter is not less serious.

The shape of an error sentence

What brokeThe registry could not be read.
WhyThe embedded JSON is malformed at record 12.
What nextRun python3 audit.py to find the record, then rebuild.

Three parts, always in that order, never an apology. Formatting is fixed too: tabular numerals for every count, dates as 06 Aug 2026, accessions as SIG–01 with an en dash.

A08 §4.5 — a synonym for something already named is a defect

A09 · States

Five states, all designed

The same region, in every state it can be in. Switch between them — the point is that none of these is an accident of a missing branch.

Empty is not loading and a refresh is stale, not loading: the catalogue keeps showing the last good count while it re-reads, because blanking a list a reader is already using is a worse answer than an old number with a note on it.

A09 §4.2 — a refresh is stale, never loading

A11 · Components

Everything the catalogue ships

Six controls, and that is the whole inventory. Press them, focus them, tab through them — every one is painted by the token block above and by nothing else.

Buttons

A pressed filter carries a border and a wash, not colour alone.

Fields

Filters below two characters are ignored.

Select

Status

House Evaluated

Chips

Tabs

Each control documents its props, its required label, and what it does not do.

A11 — each component carries an API, states, keyboard and QA criteria

A13 · Forms

A rule is a declaration

Propose a system for the catalogue. Submit it empty: the summary appears, takes focus, and links to the field that caused it — the browser’s own bubble is turned off because it disappears the moment you look away.

The system’s display name, e.g. Marginalia.
Three letters, a dash, two digits.

Submit disables itself while the proposal is in flight and re-enables on the answer, so the same record cannot be filed twice by an impatient second click.

A13 §6.2 — the error summary is focused, not merely rendered

A12 · Patterns

Several components, one problem

A pattern is an agreement no single component owns. The catalogue runs three of them, and the first one is the toolbar you scrolled past.

Filtering

Search, ground and showcase compose — they narrow together and never reset one another. The count is live, the empty state names which filter did the hiding, and one button clears all three.

systems match the filters set above.

Machine-written text

Generated · build_sites.py

This thesis line, the swatch strip on every card and the index plate were produced from the registry, not written by hand.

A person can always tell what a machine wrote: a rule, a label, and the tool that made it.

Annotation

Honest noteon Kiosk KSK–09

Reads across a room and badly at arm’s length. Not a documentation system.

Reply06 Aug 2026

Kept as written. The limit is the point of the entry.

A12 §15 — a person can always tell what a machine wrote

A14 · Data

Four series, one chroma

The index plate at the top of this page is drawn from the registry. Here is the rule behind it: with a single chromatic channel, series separate by lightness, and four is where that stops working.

Dashboard Editorial Commerce Docs
Dashboard Editorial Commerce Docs

Every step is a lightness step in oklab, so the order survives greyscale and every form of colour-vision deficiency — the series are ranked, and the chart says so. The honest note: a fifth step would sit inside the just-noticeable difference of the fourth. At five categories the answer here is a different chart, not a fifth tint.

A14 §4.3 — at six categories the answer is a different chart, not a sixth colour

A15 · Navigation

Every place has an address

A filtered catalogue is a place. Set a search or a ground filter above and watch the address below change — that string is what a reader pastes to someone else, and it arrives filtered.

Address/brandbook

Search, ground, showcase and sort each write one parameter, and the page reads them back on load. Nothing is stored that is not in the address, so there is no hidden state that a reload could disagree with.

A15 §9.2 — filter state lives in the URL or it does not exist

A16 · Archetypes

Ten page shapes, and no eleventh

The selection rule is ordered and first-match. This page is an Index: its job is to let a reader find one of many things, and everything on it either narrows the set or describes a member of it.

Landing
Index
Detail
Dashboard
Task
Reference
Settings
Empty shell
Error
Authentication

The record sheet that opens over the grid is a Detail, which is why it is a dialog and not a section: two archetypes in one place would mean two pages, and the catalogue is not willing to spend a navigation on it. The honest note: that is a deliberate breach of the one-archetype-per-page reading, taken because the alternative — leaving the grid to read one record — is worse for browsing.

A16 §4.1 — the selection rule is ordered and first-match

A17 · Flows

A journey is a record

Adding a system to this catalogue is a flow with an entry, four steps, one decision and four exits — two of which are failures with a named cause and a way out.

EntryA system is designed and its skill is written.
Step 1Append one record to the embedded registry. brandbook.html — script#registry
Step 2Generate its site. python3 build_sites.py
Step 3Generate its skill. python3 build_skills.py
Step 4Verify the whole corpus. verify.py · audit.py · coverage.py
DecisionDoes the registry record carry an honest note? The default is no publish — an entry without one cannot be chosen against.
ExitPublished. The card, the site and the index plate all redraw from the same record.
ExitHeld. The system is real but the note is missing.cause: incomplete-record — write the note and re-run
ExitRejected. Two records claim the same accession.cause: conflict — audit.py names both; renumber the newer
ExitAbandoned. The reader left before filing.cause: withdrawn — no state was written, nothing to clean up

A17 §9 — the failure taxonomy is closed: seven causes, each with a recovery