The canonical design document for the root canon. It governs every surface that claims the mark — the shipped scroll surface, static pieces, Claude Design canvases, Claude artifacts, decks, documents — and every agent or person producing one, whatever tool the design arrives from. The system is small and strict on purpose: good integration work is mapping into these rules, not inventing alongside them.
Part I is portable — it holds anywhere the brand appears. Part II binds Part I to this repository. Part III is the integration appendix, per design source.
Every rule below ships with its reason. A rule without one is obeyed until the first inconvenience.
Conformance — the DESIGN.md nine
This file sits at the repository root under the conventional name so that any agent looking for DESIGN.md finds the canon rather than inferring one from the code. It carries the nine sections of the Stitch DESIGN.md format, in that order, so an agent trained on the format can navigate it without being told:
| # | DESIGN.md section | Here |
|---|---|---|
| 1 | Visual theme & atmosphere | §0 Doctrine |
| 2 | Colour palette & roles | §1 Colour |
| 3 | Typography rules | §2 Typography |
| 4 | Component stylings | §3 Components |
| 5 | Layout principles | §4 Space & layout |
| 6 | Depth & elevation | §5 Elevation |
| 7 | Do's and don'ts | §11 Guardrails |
| 8 | Responsive behaviour | §10 Responsive |
| 9 | Agent prompt guide | §14 Agent quick reference |
| + | Product context | Part 0 |
| + | Accessibility | §15 Accessibility |
| + | Code mapping | §14 & Part II |
| ++ | Evidence & negative space | §16 |
| ++ | The constraint ladder | Part 0 |
The last five rows are not in the nine. The first three come from Joshua Guo's *DESIGN.md Is a Starting Point, Not a Design System*, whose argument is that a borrowed DESIGN.md is research material rather than implementation instructions — and the sections he adds are exactly the ones the format omits. Conforming to a structure means inheriting its blind spots; those three were this canon's, and adding them found four real defects rather than four missing paragraphs.
The last two come from the wider V2SPACE corpus, where every technical note names what it did not establish. §16 applies that to a design system, and the constraint ladder in Part 0 names the method the rest of this document is the output of.
The nine are otherwise the floor, not the ceiling. Sections §6–§9 and §13 are this canon's own: a system whose background is an algorithm, whose imagery passes a dither gate, and whose extension surface is exactly five tokens cannot be described by the nine alone.
Part 0 · Product context
A design system that never states who it serves quietly becomes the strategy. These are the facts the design has to serve; every rule after this one is accountable to them, and a rule that stops serving them should be deleted rather than defended.
| Who uses it | Agents and operators building surfaces for the organisation — rarely the same one twice, often with no prior exposure to the brand. The reader is usually mid-task. |
| The task | Produce a surface that is recognisably of this organisation on the first attempt, without a review cycle to correct drift. |
| What it governs | A holding layer above every namespace: marketing surfaces, applications, documentation, canvases, artifacts, print. Not one product — the container of them. |
| Constraints | Offline-capable (fonts bundled, backgrounds procedural). Desktop-first, degrading honestly. Two typefaces, licence-clean. No component kit, no icon library, no build step a static page cannot perform. |
| What it must never become | A skin. If a surface reads as this brand only because the colours were copied, the system has failed — the character has to survive being described in words. |
The constraint ladder
The working method, and the order matters — each rung is only as good as the one under it:
- Product context defines what the system must serve (above).
- References supply vocabulary and candidate decisions, never identity. A reference design is research material; handing one to an agent unchanged hands over another product's assumptions with it.
- A reviewed contract constrains implementation — this document, short enough that a person actually reads it.
- One representative surface tests whether the constraints survive contact with real content, interaction, accessibility and a narrow viewport. A rule that fails there fails everywhere; fix the system before spreading it across ten screens.
- The agent gets a bounded build — named surface, real content, existing components, required states, validation criteria — and judgment stays with a person.
- The constraints are re-checked by script, not by memory (§16). Rungs 1–5 are the method; this rung is why the method holds. Every defect this canon has shipped was a rule everybody believed.
Rungs 1–5 restate Joshua Guo's sequence in *DESIGN.md Is a Starting Point, Not a Design System*; rung 6 is this canon's addition.
The north star. A dotfile is hidden by convention, not by lock: present to anyone who knows to look. The system renders that idea literally — a ground you have to attend to before it resolves, instrumentation that shows its own workings, and exactly one thing alive on the screen at a time. It fits because this layer is infrastructure: it should feel measured and legible rather than persuasive, since nothing here is being sold.
Part I · The system
00 · Doctrine
Seven laws. Everything else in this document is their consequence — when a rule below and a law here disagree, the law wins and the rule is a bug.
-
The dot is the through-line.
/.at the meta layer (the dot hides — dotfile, index);[[. ]]at the vessel layer (the dot lives — essence). Every mark contains a period. - Grey is a lie told by dots. The native depth is one bit; a mid-tone is a density of marks, never a shade. Where a surface goes continuous (the solid field), the grain moves into the objects on it.
- Essence marks the dot and live elements only. Never a fill, background, or border.
- Sigil is instrumentation. Lines and labels — evidence about the work, never the work.
- Chromatic split is a ghost. Remove the red/cyan channels and the text must still read; the core carries the message.
- Two faces, no third. The meta layer speaks in a neutral grotesque because the container of all brands must not itself look branded; the system layer speaks in the pixel mono.
-
Heartbeats and sweeps. Nothing bounces. The pointer perturbs a field, never drives it; motion honors
prefers-reduced-motionwith a static, correct page.
Atmosphere. Dense, instrumented, unlit. The ground is near-black and the type sits directly on it; there is no card-on-grey softening and no glow that is not a live element. Surfaces read as measurement apparatus — ruled, ticked, labelled in tracked monospace — rather than as marketing. Restraint is the house style: one bold move per view, everything around it quiet.
The manifesto. Four lines, the operator's, in their orthography, which is the measure:
Slovo je vibrácia.
Zvuk je commitment k ďalšej sfére.
Nie je to látka a hmota.
Ale konštelácia.
The word is a vibration. Sound is a commitment to the next sphere. It is not fabric and matter, but a constellation. The seven laws were written before it and it reads as their reason. Law 2 in one line: a word is not matter, it is a pattern of relations between marks. Law 6 and the figure played: a word vibrates, and sounding it is an act, not a decoration — a commitment, irreversible, to the sphere above. And it names what the canon must not become: látka, cloth. The cloth hero hangs the laws as fabric; the manifesto says the word is not fabric. Both stay, and the tension is recorded rather than resolved: the cloth is a way of showing the laws, the constellation is what a word is. The surface that carries the manifesto is /matra/ (§9); mātrā is the measure of a syllable, the unit the lines are counted in.
Appended 2026-10-03.
The family invariant (appended 2026-10-02, R7). The estate holds surfaces outside this canon by lock — the holding lawbook (site/BRAND.md, exempt 2026-08-07), the codex surfaces (/INIT, Ydefix) — and one sentence is true of every controlled surface with no exception clause:
The address is set in type.
/.metanomicon in Departure on the canon rail and its phone bar; /.metanomicon in Departure on the gallery's identity anchor; METANOMICON in IBM Plex Serif on the holding's h1; init lowercase by CHARTER §5. On the three rendered surfaces, a text node in a declared face and no drawn asset carrying the name; init is read from CHARTER §5's wording, not from a rendered surface. Status: derived from three rendered surfaces and one charter line as set on 2026-10-02, artifact/strata4/address-in-type/probe.mjs. "Every mark contains a period" is law 1's sentence and holds on 2 of those 4; law 1 is scoped to this canon, not contradicted, and is not the family's sentence. No builder adds a period or a sigil to the exempt surface. "Address" here is the name as set, not the ?date= address of §9.
01 · Colour
| Token | Value | Law |
|---|---|---|
| void | #050505 | the dark ground (raised: #0a0a0b, #111113) |
| paper | #f2f0e9 | the light ground (ink on it: #0b0b0c) |
| signal | #e6e6e6 | text on void (on paper: #14141a) |
| essence | #00f0ff | the dot & live elements only (on paper: #056a75) |
| sigil | #c2333d | instrumentation lines — 3.72:1, not for text |
| sigil-text | #cd5860 | instrumentation text — sigil + 18% white, 5.00:1 (void only) |
| split-r / split-c | rgb(255,55,55) / rgb(60,220,230) | chromatic ghosts, never solo carriers |
| witness | rgb(226,228,230) | dot/halftone testimony |
Hierarchy is the opacity ladder, never weight or new greys: 1.00 · 0.85 · 0.70 · 0.55 · 0.40 · 0.25 · 0.15 · 0.08 (--o-1 … --o-8). Body prose sits at o-3, emphasis at o-1, labels at o-4, hairlines at o-7–o-8.
o-4 is the floor for text. Below it the ladder is for borders, hairlines and disabled states only — o-5 measures 3.19:1 against void and o-6 measures 1.88:1, so a 10px label set there is not dim, it is unreadable. §15 carries the computed table.
A colour arriving from any design source maps to the nearest token or is rejected. New hexes, gradient stops, and shadows are never imported. Status is encoded by brightness, never hue — because red is already spoken for by the sigil reservation, and a red error state would read as an annotation rather than a failure. Urgency ascends with brightness: [OK] (o-3) · [WARN] (o-2) · [FAIL] (o-1). An earlier version of this rule ran the other way, which gave the most urgent state the least legible value.
Field tinting (the one sanctioned colour field): the substrate may tint its cells cyan-led shifting crimson-ward with depth, channels mixed by a slow spatial mask — approved on the shipped surface, never exceeding ~50% saturation toward the witness core, past which the field competes with the type it exists to carry.
Appended 2026-10-03. The floor's number is falsified on pixels, the floor itself is not. The table §15 carries was composited in float and rounded; Chromium/Skia quantises the alpha to 8 bits and truncates the blend, so o-4 on void renders as rgb(128) = 5.16:1, not rgb(129) = 5.23:1, and o-3 as rgb(162) = 7.98:1 (artifact/strata4/front-door/review.json, PIXEL CHECK, 2026-10-03). The o-5 3.19:1 and o-6 1.88:1 stated above hold. o-4 stays the floor for text and stays above AA (4.5:1); which number the law states is the open ruling written out at the end of §15.
02 · Typography
| Face | Layer | Carries | Weights |
|---|---|---|---|
| Geist | meta | wordmark, headings, prose | 400, 500 only |
| Departure Mono | system | labels, data, chrome, terminal | single |
| Role | Face | Size | Leading | Tracking |
|---|---|---|---|---|
| hero | Geist 500 | clamp(4rem, 15vw, 317px) | 0.92–0.94 | -0.022em |
| section | Geist 500 | clamp(1.4rem, 3.1vw, 2.05rem) | 1.16 | -0.018em |
| subhead | Geist 500 | 16–17px | 1.4 | -0.006em |
| lede | Geist 400 | 19px | 1.66 | 0 |
| body | Geist 400 | 13–16px | 1.6–1.75 | 0 |
| data | Departure | 12–14px | 1.5–2.05 | 0.02em |
| label | Departure | 9–11px | 1.4 | 0.14em–0.32em, uppercase |
| code | Departure | 12.5px | 1.72 | 0 |
- The face-switch is this system's italic: an accent word inside a Geist heading is set in Departure at ~0.85em — never italics, never colour.
-
Measure runs 62–70 characters. Headings take
text-wrap: balance. -
Digits that align in columns take
font-variant-numeric: tabular-nums. - Fonts are bundled, never CDN'd (both faces are SIL OFL) — a silent fallback is a brand failure nobody notices. Where a host only admits Google Fonts, Geist may load from there; Departure embeds as a data: URI.
Appended 2026-10-03. --ns-face is the face of a namespace's identity — its name and its mark, where the canon page sets .ns-title in var(--ns-face) (design-system.src.html:405) — and nothing else, because §13 lets a namespace change five tokens and nothing else; a vessel's headings and prose keep the roles of this table (Geist 500 / 400), and its labels, data and chrome keep Departure. Status: derived from §2, §13 and tokens.css:100 ("vessel-level identity"); whether a vessel may set headings in the system face is the operator's ruling and the document is silent on it. artifact/strata4/agent-trial/evidence.md.
Appended 2026-10-04. Beside the hero row of the scale table above: falsified as a shipped value, 2026-10-04 — its clamp computes on no surface (R9; artifact/strata4/hero-rows/evidence.md). Doctrine is appended, not rewritten, so the row stands and the four rows the surfaces compute follow it here; whether a falsified table row may instead be replaced when a dated note records what it said is the ruling the builder asked for, and it is the operator's (artifact/strata4/INTEGRATION-2026-10-03.md).
| Role | Face | Size | Leading | Tracking |
|---|---|---|---|---|
wordmark (/) | Geist 500 | clamp(2.5rem, 12.5vw, 317px) | 0.85 | -0.02em |
cloth hero (/canon/) | Geist 500 | clamp(2.6rem, 8.4vw, 7.4rem) | 0.94 | -0.025em |
phantom (/canon/) | Geist 500 | clamp(180px, 30vw, 440px); ≤ 700 px clamp(140px, 44vw, 260px) | 1 | -0.022em |
document h1 (/doctrine/ and every document page) | Geist 500 | clamp(34px, 5.6vw, 68px) | 1.02 | -0.022em |
2026-10-04: the single hero row, a clamp from 4rem to 317px on a fifteen-hundredths-of-viewport middle term, shipped on no surface (R9) and is retired; its literal is not repeated here so that grep -rc '15vw' public/ dist/ reads 0, as the falsifier asks. The four rows above are what the surfaces compute: 180 / 118.4 / 432 / 68 px at 1440 × 900, 128 / 86.016 / 307.2 / 57.344 at 1024, 96 / 64.512 / 230.4 / 43.008 at 768, 48.75 / 41.6 / 171.6 / 34 px at 390 × 844, read by getComputedStyle on each surface (artifact/strata4/hero-rows/probe.json, artifact/strata4/mark-block/review-probe.json). A display size enters this table only when a live surface computes it.
Before this pass the grep read 2 (public/doctrine/index.html:1, dist/doctrine/index.html:1, both this file's render; every other file under public/ and dist/ counted 0, and the /canon/ DOM carries no such literal at either frame). It cannot reach 0 by an append to this file: the retired row stands above, and the builder's note itself names the grep command, which carries the string into /doctrine/ whether or not the row is replaced — the note's own claim that it repeats no literal is falsified by its grep clause, 2026-10-04. What is true now and measured is the builder's re-wording (b): the literal ships on no surface's stylesheet. Leading and tracking in the four rows are read from the stylesheets, not measured.
Appended 2026-10-04. Beside the data, label and code rows of the scale table above (Departure 12–14px, 9–11px, 12.5px): retired 2026-10-04 (R4, ruling 5; artifact/strata4/mono-grid/evidence.md). The sizes they name render on no surface now — the text nodes rendering Departure on /canon/ at 1440 × 900 are 11 px × 840, 22 px × 15 and the face-switch accents (14 × 2, 14.5 × 1, 15 × 16, 16 × 1, 39.44 × 2), no other size — and the premise that a larger Departure size buys legibility is falsified by measurement: 12 and 13 px render 29.8 and 29.5 % grey at 1× against 24.1 % at 11 px on the same label at normal tracking, 10 px 36.9 % (the injected label, mono-grid/probe.json). The rows stand, as the lock requires; the builder wrote the three below to replace them, and the ruling on replacing a retired row is the operator's (above, the hero row).
| Role | Face | Size | Leading | Tracking |
|---|---|---|---|---|
| data | Departure | 11px | 1.5–2.05 | 0 |
| label | Departure | 11px (22px display mono) | 1.4 | 0.14em, uppercase |
| code | Departure | 11px | 1.72 | 0 |
2026-10-04 (R4, artifact/strata4/mono-grid/): Departure is an 11 px bitmap (unitsPerEm 550, every metric a multiple of 50): one drawn pixel is one device pixel at 11 px and two at 22 px, and at any other size the drawn pixels straddle device pixels. The 9–11 px range, the 12–14 px data row and the 12.5 px code row are retired for two sizes, 11 and 22. Measured in Chromium at 1×, 1.5× and 2×, grey as a proportion of the glyph box (the 11 px box is up to 1.31 times the 10 px box, so counts are not compared): on a label whose glyph origins the renderer snaps, 11 px renders 0–0.9 % grey where 10 px renders 27–37 % (five of eleven strings in one construction at 1×); on Chromium's LCD-subpixel path, which the other six strings and 23 of 26 live labels on /canon/ take, every size is grey and 11 is the least of 10–13 on 5 of 5 live labels at 1× and 4 of 5 at 2×; at 1.5× no size is least across labels. The text content selects the path along with the paint context; the size is necessary and not sufficient; the renderer's glyph positioning decides the rest, and review.mjs checks the size only. The 12–13 px data and code roles are moved, not kept: a larger off-grid size measured more grey, not more legibility (ruling 5). The face-switch accent stays in em and off the grid by this doctrine's own rule above; review.mjs lists as a face-switch only an inline Departure node at 0.8–0.9 of a Geist parent's size that is not an uppercase tracked label.
Appended 2026-10-04. Beside the section, subhead, lede and body rows above and the tracking column of the whole table: the trackings -0.018em (section), -0.006em (subhead) and 0.02em (data) and the body range 13–16px are retired 2026-10-04 with the argument below (R8, the refuters' condition 1; artifact/strata4/type-scale/evidence.md, Derived), not silently: the section and subhead values differ from the display and prose values they join by 0.13 px and 0.10 px per glyph at 32.8 and 17 px, under one device pixel at 1×; 14 and 14.5 px render on no surface after this pass. The rows stand. The tracking column of the four display rows appended above the same day (-0.02em, -0.025em, -0.022em) is what the stylesheets read before this half: .hero h1 and header.doc h1 now read -0.022em (−2.605 px at 118.4 px, −1.496 px at 68 px; artifact/strata4/type-scale/table.md); the wordmark on / is src/'s and consumes none of the variables, so its row is not moved here; the phantom's tracking is not in the table. The builder's table, which it wrote to replace the role table and the integrator sets beside it:
| Role | Face | Size | Leading | Tracking |
|---|---|---|---|---|
| wordmark · cloth hero · phantom · document h1 | Geist 500 | the four display rows above (W14) | as read | var(--tracking-display) −0.022em |
title (.ns-title, article h1) | Geist 500 | clamp(1.5rem, 4vw, 2.3rem) | 1.1 | -0.022em |
section (.sec-head h2, article h2) | Geist 500 | clamp(1.4rem, 3.1vw, 2.05rem) | 1.16 | -0.022em |
specimen (.spec-geist) | Geist 500 | clamp(1.7rem, 4.4vw, 2.9rem) | 1.1 | -0.022em |
| standfirst | Geist 400 | 19px --text-xl | 1.66 | 0 |
| subhead · document lede | Geist 500 / 400 | 17px --text-lg | 1.4–1.7 | 0 |
| body | Geist 400 | 15px --text-md | 1.72–1.75 | 0 |
| captions · tables · secondary | Geist 400 | 13px --text-sm | 1.5–1.65 | 0 |
| data · code · chrome | Departure | 11px --text-mono | 1.5–2.05 | 0 |
| label | Departure | 11px --text-mono (22px --text-mono-2x display) | 1.4 | 0.14em uppercase; the brand line 0.32em |
2026-10-04 (R8, artifact/strata4/type-scale/): the scale is one scale, written in public/tokens.css and read from the surfaces: every value above has a row in the measurement table with the surface and selector it was read from, at 1440 and 390 (128 rows, 128 hold). The artifact's inline token block is generated from tokens.css by scripts/tokens-mirror.mjs and is never typed, which is the mechanism §14's warning asked for. Retired by this entry, with the argument in the evidence file: the section −0.018em and subhead −0.006em trackings (under one device pixel from the display and prose values they join at these sizes), the data 0.02em (measured as grey as 0 at 11 px), the 13–16px body range (14 and 14.5 render on no surface), the 12–14px data and 12.5px code sizes (R4). Four trackings: −0.022em display, 0 prose, 0.14em label, 0.32em brand. The old --text-3xs…5xl, three --leading-* and --tracking-tight/normal/wide/wider/widest are gone from tokens.css except four aliases the preview pages still name. --signal and --witness now exist in tokens.css as the channel triplets §14 writes.
Until this append landed, /doctrine/ printed the old rows alone; /doctrine/ is this file's render, so once rebuilt it prints the old rows and these beside them, and the builder's note that it "prints a scale this file does not ship" holds for the old rows as long as they stand.
03 · Components
There is no component kit, and the canon does not import one. What follows is derived from the laws, not borrowed: every state below is a consequence of §0–§2, which is why a component that needs a new colour or a new radius is a signal that the design is wrong rather than that the canon is short.
Buttons. Departure, 11–12px, tracked 0.08em–0.10em, uppercase. Square, except pill controls (§4). Three ranks only:
| Rank | Rest | Hover | Focus | Active | Loading | Error | Disabled |
|---|---|---|---|---|---|---|---|
| primary | signal fill, void text | fill to #fff | 1px sigil outline, offset 2px | fill drops to o-2 | label pulses on the beat | [FAIL] beside, at o-1 | o-6, no pointer |
| secondary | 1px border o-7, text o-2 | border o-5, text o-1 | as above | border o-4 | as above | as above | o-6 |
| ghost | text o-3, no border | text o-1 | as above | text o-4 | as above | as above | o-6 |
Never an essence or sigil fill — laws 3 and 4. Nothing translates on press; the fill moves instead, because nothing bounces. A loading button pulses its label on the canonical beat rather than spinning.
Inputs. Ground void-3, 1px border at o-7, square, no inner shadow. The value is data, so it sets in Departure; help text is prose, so it sets in Geist at o-4. On focus the border rises to o-4 and a sigil tick marks the leading corner — the instrumentation says which field is live. caret-color: var(--essence): the caret is the one live element in a form, and is the only place essence belongs there. Errors never turn red — the message sets at o-1 behind a [FAIL] bracket and the border rises to o-4, per the brightness law.
Plates and cards. Ground void-2, 1px border at o-7, square, with 6–8px sigil corner ticks on the leading and trailing corners. A ruled cap row (1px at o-7) carries a tracked label left and a status or coordinate right. Plates butt against each other on a 1px rule rather than floating apart on shadow.
Navigation. Pill controls at 50px radius on a #000 track with a 1px border at o-7; the active pill is a signal fill with void text. This is the only earned radius in the system.
Panels (glass). rgba(10,10,11,0.38–0.40) plus blur, 1px border, sigil corner ticks — permitted only over a live field and only on a panel with a reason to float. Blur over a flat colour is decoration.
Tables. Header row on void-3, Departure 9.5px tracked uppercase at o-5; body rows separated by 1px rules at o-8; first column in Departure at o-1; numeric columns tabular. No zebra striping — the rules already do that work, and striping invents a grey.
Status. Bracketed, in Departure, encoded by brightness: [OK] [WARN] [FAIL]. No badges, no pills, no colour chips.
Appended 2026-10-04. Beside "Tables" above, the header row "at o-5": falsified, 2026-10-04 — §1 puts o-5 below the text floor at 3.19:1, and no header row ships at it. The builder's correction, from artifact/strata4/hero-rows/evidence.md:
Header row on
void-3, Departure 9.5px tracked uppercase ato-4(2026-10-04: was writteno-5, which §1 puts below the text floor at 3.19:1; the artifact'sthrule and the document shell both measureo-4, rgba(230,230,230,.55),artifact/strata4/hero-rows/probe.json).
Appended 2026-10-04. Beside "Tables" above and the corrected sentence, "Departure 9.5px": no longer what ships, 2026-10-04 — 9.5 px is off Departure's 11/22 grid (R4), and the artifact's th and the document shell's article th both compute 11 px at 0.14em (1.54 px at 11 px) at 1440 and 390 (artifact/strata4/type-scale/table.md; artifact/strata4/mono-grid/evidence.md). The header row reads "Departure 11px, .14em" from this date, for the reason the §2 append of the same day gives; W14's o-4 correction above stands. Citation, same day: the shell's article th is the table.md row at both frames; the artifact's th is 11 px in table.md at both frames and 1.54 px in artifact/strata4/mono-grid/probe.json's survey at 1440, its tracking otherwise read from the stylesheet (var(--tracking-label)).
04 · Space & layout
-
Base unit 4px. The ramp:
4 · 8 · 12 · 16 · 24 · 32 · 48 · 72 · 96. Sibling groups are laid out with flex/grid andgap, never with per-element margins that collapse or double. - Plates use 42–46px margins and a 74px section rhythm on the shipped surface; both predate the ramp and converge on 44 and 72 when next touched.
- Content column caps at 1180px; prose measure 62–70ch; canvas artboards are 1440×900 with 1180×760 inner plates.
- Corners are square. Radius must be earned; currently only pill controls (50px). Panels take 1px borders plus sigil corner ticks instead of rounding. The rule governs containers and controls — a mark is not a box. The marks have always been circles: the lattice draws arcs, and so does the Bayer plate in §8.
-
Wide content — tables, code, diagrams — scrolls inside its own
overflow-x: autocontainer. The page body never scrolls sideways.
05 · Elevation
There are no shadows. Depth is carried by three things instead, because a shadow implies a light source and this ground has none:
-
Surface ladder —
void #050505→void-2 #0a0a0b(plates) →void-3 #111113(insets: code, table headers, inputs). Three steps, no fourth. -
Hairlines — a 1px rule at
o-7/o-8separates planes. An edge, not a blur. - Blur, over a live field only — the glass panel, which reads as depth precisely because the field behind it is moving.
Stacking map for fixed layers on the shipped surface: field 0 · signal band 5 · plates 7 · hero 10 · panel 20 · nav 100. New layers claim a gap; a layer that cannot name its gap does not ship, and nothing floats above nav.
06 · Motion
-
Primary beat
--beat: 1.6s; the canonical pulse issin⁴(t·1.55)— sharp systole, long diastole. -
Sweeps re-fire on
--sweep: 10s; ease iscubic-bezier(0,0,.2,1)or linear scrub. No elastic, no overshoot, no bounce. -
--lunation: 29.530588861d— the synodic month, the canon's third period and the only one measured in days. The field's warm/cold balance is bound to it (§9). A period that long cannot be perceived as motion; it is perceived as a calendar, which is the point. - Scroll is a scrubber: it advances a process (field time, destruction, revelation), it does not trigger fire-and-forget tweens.
-
Every animated surface ships a real
prefers-reduced-motionstate — static and correct, not degraded. - Budget: ≤7ms/frame at 1440×900.
Appended 2026-10-03. Beside the first bullet above, "the canonical pulse is sin⁴(t·1.55)": falsified 2026-10-03; that formula's period is 2.0268 s, not --beat. The two notes below are the builders' texts (artifact/strata4/phantom-gate/evidence.md, artifact/strata4/one-beat/evidence.md); the ledger rows are in §16.
-
2026-10-03 · one beat. The bullet above once read "the canonical pulse is
sin⁴(t·1.55)". That formula has period π/1.55 = 2.0268 s, 1.267 beats, so the canvases beat at one rate and.mn-anim-beatat another. The pulse is now writtensin⁴(π·(t + 5/8·--beat) / --beat), ω = 1.9635 rad/s, one maximum per 1.6 s, with the beat read once:BEAT = 1.6andBEAT_PHASE = BEAT·5/8insrc/canon/chroma.jsfor the React surface,--beatread from the document at every canvas site (artifact/design-system.src.html,artifact/strata2/figure-played/stratum.js,artifact/strata3/matra/). The origin is chosen so that t = 3.0, the held frame of §15, is exactly a systole, stated, not accidental. The mātrā stays 200 ms = beat/8. Measured:artifact/strata4/one-beat/probe.mjsreads the living dot's pulse directly from the page for three 10 s runs on the served/canon/; dot period 1.600 / 1.600 / 1.600 s, plot 1.600 s in each run, within one frame at 60 Hz of 1.6 s. The gallery'score.jspulse()onmainstill carries 1.55 and is named, not touched.--cyclewas deleted (0 consumers);--beat-faststays (.mn-anim-blinkconsumes it);.mn-anim-beathas no consumer in this repository and is a candidate for deletion. -
2026-10-03 · the beat's origin. The pulse is
sin⁴(π·(t + 5/8·--beat) / --beat), period 1.6 s; the origin is chosen so that t = 3.0, the held frame of §15, is exactly a systole (2.5 beats from the origin), stated, not accidental (artifact/strata4/one-beat/hold.json,probe.json).
07 · Iconography
There is no icon set, and none may be added. The vocabulary: the marks (/., [[. ]]), type glyphs (→ · — # ×), ASCII/box-drawing (┌─┐│└─┘), bracketed status. Icons arriving from any source are replaced with a glyph or dropped — a "home" icon becomes /., a close button becomes ×, an index control becomes #.
A glyph joins this vocabulary only once both faces are confirmed to carry it — verified, not assumed. The index mark was ⌗ (U+2317) until Departure Mono was actually measured and found not to have it, at which point every control using it rendered a tofu box. ≡, ☰ and ⋮ are absent too. # → · — × [ ] ┌ ─ ┐ │ └ ┘ / . are all present; artifact/contrast-audit.mjs carries the coverage probe.
08 · Imagery — the dither gate
Bitmaps do not ship raw. Photographic material passes through the ordered dither: Rec.709 luma against a Bayer-8 threshold, lit cells in a channel tint, unlit cells transparent so the ground breathes through. Dither buffers render at an integer cell scale and upscale with image-rendering: pixelated — a scaled dither is a blur.
Ordered, not error-diffused, and the reason is not aesthetic. Floyd–Steinberg renders a photograph more faithfully — it carries quantisation error forward and holds detail an ordered matrix throws away. Bayer is chosen because it is deterministic, stateless and tileable: same input, same output; every cell computable without knowing any other; a region renderable alone and still matching its neighbours. Error diffusion is serial, depends on scan order, cannot be tiled or resumed or evaluated per-cell on a GPU, and two crops of one image will not agree at the seam. That is the same seed discipline the substrate runs on. A gate that produced a slightly different image each time it ran would be prettier and wrong.
09 · The generative substrate (Dot Doctrine)
The background is an algorithm, and its settled ratios are tokens: lattice pitch 8px · radius pow(shaped f, 1.35) × 0.62 × pitch · shaping (f−0.18)/0.72 · two-stage domain warp (weather 1.9, warp 1.05×2.4) · disagreement threshold |df| > 0.10 (warm leads rising contours, cold trails falling) · revelation gate M × pow(r,1.8) × 0.55 × (0.30+0.85f), peak legibility at scroll 0.41 · exactly one living dot, beating on the canonical pulse, never accumulating into the record. Same seed, same climate, always.
The field is a fragment shader, not a cached image. It was rendered once into a 2D canvas and cached, with only the living dot moving over it — a climate that never changed weather. It now runs live: the domain drifts slowly (a climate, not a plasma), the --sweep: 10s token finally does work as a band crossing the field, and the pointer perturbs the sampling domain on the profile x(1−x)² — zero at the cursor, peaking in a ring, dead by ~220px. Zero at the centre is the point: a peak under the cursor is a spotlight and has a direction singularity. The field keeps evolving with the pointer held still, because law 7 says perturb, not drive.
Three strata stand on the substrate. Each is a real technique with a reason a reader can repeat, and each was built by its own agent, verified in a real browser, and salvaged from disk across three container restarts rather than regenerated.
-
The cloth hero — the operator's own effect, ported from ZeSign's
HeroCompositionandClothManifestoline by line. The seven laws are hung as a Verlet cloth over the live field, one character to a cell, pinned at the top row, ten relaxation passes; the display-scale/.stands behind it, resolved from dots rather than typeset — tone by radius, never by alpha — breathing on the pulse and leaning into the split on hover. The pointer perturbs and the cloth settles on its own; there is no grab, because a dragged particle is authored, not disturbed. A hidden layer marks every period woven into the doctrine and lights them in essence only while pressed — a dormant secret is not a live element.artifact/strata/cloth-hero/evidence.md. -
The third axis — the flat lattice is a slice of a solid: thirteen unit spheres in cuboctahedral close pack, the flat ring of six around one being the flower of life from this canon's founding references. One key light, the primary hit solved rather than marched, through the same Bayer-8 gate as the imagery. It does not shimmer because it renders one fragment per dither cell, so each cell takes exactly one threshold decision — measured at 0.47% of cells flipping per frame against 4.94% for the naive build. Eighty-four seconds per revolution, so a surface point crosses one Bayer level per ~19 frames. The construction's occult history is named and declined: it is here because hexagonal close packing is the densest arrangement of equal spheres.
artifact/strata/onebit-3d/evidence.md. -
The ephemeris seed — the field was reproducible from
1147, a constant somebody typed. It is now derived from where the sky is: Julian day (Meeus ch. 7), moon phase and age, lunar mansion, and the unequal planetary hour at the Royal Observatory, 51.4779°N 0.0015°W, in UTC — the meridian's own fixed point, because a seed computed for the viewer's own sunrise would differ on every machine and break the one promise the substrate makes. Every step is printed so the number can be recomputed. The six-bit figure beside it and the 8×8 Bayer matrix are the same shape — three bits of row and three of column, built by the same recursive halving — so the figure's coordinates are its address in the dither matrix. No names or judgements are attached; the system does not borrow authority it has not earned. It is a calendar, not a horoscope.
The tide is the moon. The ephemeris publishes the sky as one object (window.MN_EPHEMERIS) and one event (mn:ephemeris); the field reads it each frame. Illumination seasons the agreement cells — cold-led at new moon, warm-led at full — and the quarter breathes the asymmetry: waxing lowers the warm threshold, waning raises it. Defaults reproduce the unbound field exactly, verified by hash. Measured at one instant across the four phases: warm/cold energy 0.23 at new moon, 4.89 at full, 2.61 waxing against 0.50 waning at the same illumination. artifact/strata2/tide-moon/evidence.md.
The mark is made of today's weather. The phantom /. behind the cloth is no longer a typeset glyph at 52% opacity — that was a shade, and the copy had always claimed otherwise. The glyph is rasterised once as a mask from its own computed style, and what survives is the list of 8px lattice cells inside it, each a witness mark whose radius is the field at today's seed. The weather's share of the radius is held to a 55–100% band so the silhouette reads on a quiet day, proven across 30 offsets spanning the whole noise domain: 309 cells identical on every one, 30 distinct renders, spread 1.85×, byte-identical on repeat. Same date, same mark. The identity is a dated instance of the same law. artifact/strata2/mark-weather/evidence.md.
The phase disc, a primitive. The moon-through-the-gate is now one function — a 0..1 quantity as the lit fraction of a dithered disc with a real terminator, the phase solved from the value — used exactly three times: the reader's position (the rail), the machine's state (how much of the display ratio the field is holding), the reader's control (how open the gate is) — and the almanac as a fourth: one grid whose cell happens to be the disc. The cap counts instruments, not calls; what it forbids is the disc as an ornament beside something that did not need it. A primitive, not a motif. No grey pixel in any disc. artifact/strata2/phase-disc/evidence.md.
The seed as an address. ?date=<ISO> opens the page at that climate — a day can be sent. The ephemeris writes its state into <meta name="metanomicon:date|seed|citation"> so a machine reads the day without running a frame, and "cite this frame" copies the citation Part III demands. Two fresh contexts opening the same address rendered a byte-identical field — the first time the page itself has demonstrated same seed, same output rather than asserted it. artifact/strata2/address/evidence.md.
Found on the way, and corrected. The disagreement palette — warm leads a rising contour, cold trails a falling one — documented above and in every evidence file since the field shipped, had never fired. Its thresholds, 0.10 and 0.055, belong to p5's noise; against this shader's value-noise |df| never reaches 0.05 (15,147 cells: p50 0.0088, p85 0.0201, max 0.0500). Every tint on screen had come through the agreement path, and at neutral it was warm-biased. The thresholds are now the measured 85th and 72nd percentiles, the same method the 1-bit solid uses for its occlusion cut-offs, and the tint is capped at half saturation so cold never impersonates essence. The documented behaviour is now the behaviour, and §16 records the correction.
The King Wen dither — the I Ching gate as evidence. The ephemeris argues a six-bit figure's trigram coordinates are its address in the 8×8 Bayer matrix. So the sixty-four thresholds can be re-ordered by any complete ordering of the sixty-four figures without moving one out of its cell, and the received sequence is such an ordering: threshold at cell (upper, lower) is that figure's position in it. The table is checked structurally — 28 of 32 consecutive pairs joined by inversion, the eight self-inverse figures in the four remaining pairs joined by complement, none neither. The prediction was written before the run: the received order will clump. Half right. Raw 4×4 lit-density variance barely moves (+2.3%) because the photograph's own contrast dominates it; the residual variance is 3.5–5× higher under King Wen at every gain, and the share of residual power at scales coarser than the tile is 13.27% against 0.80%. Spectral flatness pointed the wrong way and is left on the plate with the reason. No name, no judgement, no reading: the sequence is a permutation of 0–63 and nothing else. King Wen is as deterministic and tileable as Bayer, which is what makes it a legitimate rival; it loses on the measurement, and the measurement is now the reason to keep Bayer. artifact/strata2/kingwen-dither/evidence.md.
The almanac — a year of weather at one bit per day. Every day of the UTC year derived at 12:00 by the same routine that seeds the field, its patch sampled at 288 points, drawn as one phase disc at twelve cells. Three statistics were prototyped and drawn: moon illumination (the control — a cosine by construction), the field's mean density (a calendar of static: lag-1 autocorrelation −0.009), and the warm-minus- cold balance the tide gives the day. Kept: the balance. Lunations appear as bands — lag-29 autocorrelation 0.907 against 0.915 for the moon itself — and 13.8% of its variation survives regressing the moon out: that share is this page's terrain, the rest is the sky. The cursor is a one-cell sigil ring, Bresenham not stroked, because a stroked arc antialiases and antialiasing is grey; it is sigil whether the date is today or travelled-to, because the page's essence budget is one dot. Columns are ceil((offset + days) / 7), not 53 — a leap year starting on a Sunday needs 54. Nothing animates; the reduced-motion picture is the default picture by construction. artifact/strata2/almanac/evidence.md.
The figure, played. The six-bit figure is six one-bit pulse trains, one per line: a solid line plays its train whole, a broken line half of it, the gap you see in the drawn line the gap you hear. Line six is the exception and it is stated: its train is one unbroken block, so broken it halves the block instead of dropping pairs. The tempo is the planetary hour — 64 steps per hour, so a step is 1/4096 of an hour that is not sixty minutes long; over 2026 the step runs 539.8–1218.2 ms and the same figure is 2.26× faster on a midsummer night than afternoon. The fundamental is the lunar mansion dividing an octave from 55 Hz. A one-bit stream carries a tone by pulse density through a low-pass — the dither doctrine in the time domain. Nothing exists before the gesture: no context, no worklet, no node until listen is pressed; pressing again closes the context and the readout says so. Gain-staged below −18 dBFS. Reduced motion holds the strip at t = 3.0 while the audio still plays. artifact/strata2/figure-played/evidence.md.
Matra — the manifesto as a constellation. The four lines of §0, each glyph resolved from lattice dots the way the mark is, every dot moved off its cell by the day's seed by up to 0.16 of a pitch, so the word is a figure of stars that reads from where you stand and is not matter. A wave runs through each line, sin⁴, one wavelength per mātrā of that line, so the vibration is the line's own measure. The measure is derived from the orthography, not chosen: a nucleus is a vowel, a diphthong or a syllabic liquid; the acute makes it long; a short syllable is one mātrā and a long one two; commitment is scanned by the same rule because the manifesto put it there in English. The four lines scan 8 · 10 · 10 · 8. Pressed, a line sounds at one bit — a square wave, two values — in the key of the day (110 Hz raised by the six-bit figure's residue mod 12 in twelfths of an octave), one mātrā 200 ms, an eighth of --beat, so the first line lasts exactly one beat. While it sounds the one living dot walks the line; nothing else on the page is essence. When it has sounded the line has committed: its dots let go of the glyph to 0.45 of a pitch and the constellation is drawn between sparse nodes in sigil, lines only. It does not come back; a second press sounds it again. Nothing exists before the gesture and the context is closed after it, printed. On a phone the type grows to 34px and the pitch drops to 3, because a glyph needs six cells of height to survive being a constellation. There is no cloth on the page. artifact/strata3/matra/evidence.md; live at /matra/ and at metanomicon.org/matra.
Three strata from the first round remain briefed and not built — text-mode rendering, a sigil engine, a steganographic layer — recorded in §16 rather than quietly dropped, with their briefs banked under artifact/.
It measures itself. The page starts at the display's own pixel ratio, watches its own frame interval — not the time around drawArrays, which only queues work and reads ~0.05ms on any device — and gives up resolution rather than frame rate when a device cannot hold the budget. Degrade only, never climb back: interval is vsync-capped near 16.7ms, so a "fast" reading is indistinguishable from a merely adequate one and a step-up rule would oscillate.
Reference the noise domain to the short canvas edge. Referencing the long edge under-samples a wide viewport into two lobes: the field goes flat and the warm/cold disagreement never crosses its threshold.
Appended 2026-10-03, from the agent trial (artifact/strata4/agent-trial/).
What f is. The field's noise is fbm4 in artifact/field.glsl: four octaves of vnoise (value noise on hash21, cubic fade), lacunarity 2.0, gain 0.5, the sum multiplied by 1.0666667 so it spans 0..1. warpq takes two fbm4 samples at p × 1.71 (weather 1.9 × 0.9) with offsets (13.7, 41.3) and (87.1, 5.9); climateF is fbm4(p × 1.9 + (q − 0.5) × 2.52), 2.52 being 1.05 × 2.4; p is the cell centre over the short canvas edge. The remap is shape(f) = clamp((f − 0.18) / 0.72, 0, 1) ^ 1.35, which puts v in [0, 1]; the radius is v × 0.62 × pitch. Measured over 400,000 cells: f has median 0.503, 10th percentile 0.329, 90th 0.674, 99th 0.787, maximum 0.943; a cell at the median has v = 0.34 and a radius of 1.7 px. A noise with a different range needs a different remap, and a remap invented to fit the constants is the field the trial built, not this one.
The density the field holds. Status: measured, artifact/strata4/agent-trial/ field-density.mjs, reduced motion, 1440×900, DPR 1, two dates. By the rule "a cell is lit when its centre pixel is more than 24/255 above the void", the hero field lights 0.9983 of its 15,145 cells at ?date=2026-09-03T12:00:00Z and the same 0.9983 at ?date=2026-10-03T12:00:00Z (the same bytes: the hero's geometry has no seed input, and under reduced motion it draws at t = 3.0 before the ephemeris publishes); 0.9977 at t = 0 with the sweep off-screen. Pixel coverage above the void is 44%, above half witness 29%. The density is in the radii, not the count: median 0.28 of a pitch (0.35 at t = 0), 90th percentile 0.40, 99th 0.47–0.51, maximum 0.55 of a pitch, 0 cells at the 0.62 cap. The seeded field of the ephemeris stratum lights 0.933 and 0.949 of its cells on the two dates, with coverage 31% and 17%: the seed moves the domain, and the density moves with it inside that band.
Discs never merge into a fill. The radius is capped at 0.62 × pitch (diameter 1.24 pitch), so two neighbours can only touch when v > 0.806, which is f > 0.794, and fbm4's upper tail crosses 0.794 in 0.8% of cells and 0.90 (v = 1) in 0.01%. The bound is the noise's distribution set against the cap. Measured at rest: 87 of 15,143 cells (0.57%) with radius ≥ 4 px, 0 at the cap, 0 horizontal runs of solid witness ≥ 24 px (longest 6 px). The sweep lifts its band (v + sweep × (0.055 + 0.16v)): at the shipped reduced-motion frame, t = 3.0, 393 cells (2.6%) touch and 46 solid runs appear, the longest 112 px, inside the band. A field whose cells fuse outside the sweep has the wrong noise or the wrong remap.
How a surface reaches the field and the seed. A surface outside the shipped one mounts the field through public/lib/gl.js: mountShader(canvas, frag, { uniforms }) mounts one quad with u_res, u_time, u_mouse, u_hover, and field.glsl is the fragment, with u_pitch, u_tide, u_wax, u_probe passed as extra uniforms. field.glsl is under artifact/, not served (no .glsl under public/), and the shipped page does not use mountShader for it: design-system.src.html inlines the fragment as a JS string and mounts it with its own mountField. An outside surface carries the fragment text, as it carries stratum.js, until both are promoted to public/lib/. gl.js's GLSL_NOISE and GLSL_WARP (mnFbm, lacunarity 2.03; mnWarp 1.8 / 2.5 / 3.0) are a vocabulary for other pieces and are not this field. The seed comes only through the ephemeris core, artifact/strata/ephemeris/stratum.js (inlined into /canon/ by design-system.src.html): window.MN_derive(date) returns { seed, off, illum, phase, … }, FNV-1a over year, day of year, moon age, planetary hour, mansion and figure, and off (each 16-bit half / 65535 × 48) goes into u_off; window.MN_EPHEMERIS and the mn:ephemeris event publish the same object. Never a hash of the date: the string a page would hash is not the sky, and two pages that hash differently disagree on the same day. The core is not yet under public/lib/; an outside surface carries the file until it is promoted.
Beside "Same seed, same climate, always" above: falsified for the hero substrate as shipped, 2026-10-03. The hero #lattice has no seed uniform and reads MN_EPHEMERIS for u_tide / u_wax only, so its geometry is the same bytes at two dates (a592120f); the ephemeris stratum's #ephField takes u_off and differs (fb919b17 / 5e0e6629). The sentence holds for the seeded field. artifact/strata4/agent-trial/evidence.md, §16 row.
Appended 2026-10-03. On the React root / the living dot is the wordmark's period: span.period inside the .char the scroll owns, breathing scale(1 + 0.2·sin⁴(π·t/BEAT)) about the ink's centre (origin 0.133 em above the box bottom, derived from the face's metrics) with the halo alpha on 0.35·(0.35 + 0.65·pulse), both written as the custom properties --period-scale and --period-halo on span.period and read by src/index.css, BEAT read from src/canon/chroma.js. The nav's period rests in signal and lights only as the hovered or focused door's period; while the nav's period is lit the hero's period rests; carriers 1 in every state. Under reduced motion the period rests in signal; the t = 3.0 held frame belongs to the lattice, where the dot is the field's reading. Measured period 1.598 s (computed, 65 frames) and 1.601 s (rendered, 113 screencast frames) after the fixes of 2026-10-03 (1.599 s and 1.602 s before them); artifact/strata4/period-live/evidence.md.
Appended 2026-10-03, from artifact/strata4/field-lib/. public/lib/gl.js now exports the shipped field: GLSL_FIELD is artifact/field.glsl byte for byte, GLSL_FIELD_SEEDED adds u_off to it in two lines, and mountField(canvas, { off, tide, wax, hold, probe, preserve }) mounts it the way the canon page does — one triangle, u_pitch = 8 × scale, resolution that only degrades, one held frame at t = 3.0 under reduced motion. A surface that mounts it with MN_derive(date).off draws the frame field.glsl draws, by pixel hash, at two dates and two canvas sizes (bc720fb2, 75a6407f, 0a1a25ad, 257ceb80); the library-mounted field at the canonical seed lights 0.9329 of its cells in the 784×300 box and 1.0000 of 20,154 at 1440×900 (coverage 31.8% / 42.6% above the void), at 2026-10-03 0.9492 and 0.9753 (17.4% / 17.2%), 0 cells at the 0.62 cap at both dates. The paragraph above that says an outside surface carries the fragment text is closed for the field; it still holds for stratum.js, which is not under public/lib/. The canon's #ephField is not this program's frame (its tint path and dot differ; geometry agrees 3,611 of 3,614 cells) and the hero differs only at the dot's pulse.
10 · Responsive
| Breakpoint | Width | What changes |
|---|---|---|
| sm | 640px | single column; plates lose their cap row's right slot |
| md | 900px | nav pills collapse to the mark plus a menu control |
| lg | 1080px | the instrumentation rail appears |
| xl | 1440px | reference width — canvases and captures are authored here |
Below lg the rail leaves, so its instrumentation has to arrive somewhere else — not disappear. A 54px fixed bar carries the mark, the scroll coordinate, and a # control opening the full section index; the index is mirrored from the rail at runtime rather than duplicated in markup, so a new section can never appear in one and not the other. The control glyphs are # and × from §7, because a hamburger would be an icon and there is no icon set.
-
The sheet locks page scroll while open, moves focus to its first entry, closes on
Escapewith focus returned to the control, and closes itself if the viewport is resized past lg — otherwise a desktop reader inherits a scroll lock behind a hidden panel. -
Sections carry
scroll-margin-topso an anchor never lands beneath the bar. - A table that scrolls inside its container says so, in a sigil label. Not a fade — that would be a gradient, and §11 forbids one. The hint is added only when the table actually overflows, and re-evaluated on resize, since the same table scrolls on a phone and does not on a desktop.
-
Hero and section type scale with
clamp()and need no breakpoint; the breakpoints above exist for structure, not for size. - Touch targets are 44px minimum — measured, not assumed. The pill controls were 33px and the buttons 39px until the measurement was actually taken; padding, not the claim, is what makes it true.
- The canon surface is desktop-first. Static plates and canvas artboards are fixed-size pieces and do not respond — they paginate or scale as a whole.
- Canvases resize by re-deriving their bitmap from the CSS box, never by stretching. Cell-based work (dither, lattice) keeps pitch in CSS pixels and scales it by dpr so density is device-independent.
11 · Guardrails
Most of this list is machine-checkable, so it is checked rather than trusted. artifact/review.mjs loads a surface in a real browser and reports: the typefaces and weights actually rendering, every non-zero border radius, every use of essence and sigil with how it is applied, the computed contrast of every text node against its true composited background, heading order, landmarks, lang, and any SVG or emoji that crept in. artifact/contrast-audit.mjs recomputes the ladder and the glyph-coverage probe.
Two notes from running it, both of which cost a false result before being fixed: a contrast checker must resolve color-mix() — Chromium serialises it as color(srgb 0.80 0.31 0.34) in 0–1 floats, and reading those as 8-bit invents failures that are not there — and it must walk up for the nearest opaque background rather than reading the element's own, which is usually transparent.
Do
- Map every incoming colour to a token, or reject it.
- Use the opacity ladder for hierarchy.
- Set the accent word in the other face.
- Make backgrounds procedural and reproducible from a seed.
- Put the grain in the objects when the ground goes continuous.
- Ship the reduced-motion state in the same commit as the motion.
- Give every rule its reason.
Don't
- Don't fill anything with essence or sigil.
- Don't introduce a third typeface, a fifth weight, or a new grey.
- Don't round a corner that isn't a pill control.
- Don't add a shadow, an icon set, or a gradient that is not the hero veil (§15 — the one sanctioned exception, and it carries no colour).
- Don't encode status in hue.
- Don't ship a raw photograph, or upscale a dither.
- Don't animate with bounce, elastic, or overshoot.
- Don't let a chromatic ghost carry meaning on its own.
-
Don't override anything outside the five
--ns-*tokens.
12 · Voice
The canon states constraints; the namespaces have voices. Sentence case in prose; lowercase or tracked-uppercase in chrome; no marketing verbs about one's own work; every rule ships with its reason. See VOICE.md.
13 · Extending — the namespace contract
A child brand overrides exactly five tokens — --ns-name, --ns-accent, --ns-sigil, --ns-mark, --ns-face — via a [data-ns] block, plus a registry row. Nothing else changes, ever. The mark must contain a period; the face must be one of the two. A design needing more is a fork, not a namespace.
An extension point that can change anything is not an extension point, it is a rewrite.
The five tokens also carry legibility floors, because the contract used to constrain only two of them and that was a hole:
| Token | Constraint |
|---|---|
--ns-name | lowercase |
--ns-mark | contains a period (· is not a period) |
--ns-face | one of the two faces — no third family |
--ns-accent | ≥ 4.5:1 on void, and a paper value ≥ 4.5:1 on paper |
--ns-sigil | ≥ 3:1 on void as a line; lifted 18%, ≥ 4.5:1 as text |
artifact/namespace-check.mjs is the gate — run it before adding a registry row.
What was claimed, and what is actually true. This section used to say five tokens mean a component "renders correctly under every namespace that will ever exist, without being tested against any of them." Rendering the whole surface at document scope under each namespace showed the first half holds and the second does not: the three registered namespaces pass with zero contrast failures, and a contract-legal namespace with a dark accent renders the period in the mark at 1.79:1 — the one glyph law 1 is about, invisible. The generalisation is real, but it is a property of the floors, not of the token count. Without them the contract permits its own violation.
14 · Agent quick reference & code mapping
This block is a mirror, not the source. Inside the repository the canonical token layer is public/tokens.css, and code points at it rather than copying from here — a design document that restates tokens has invented a second source of truth and will disagree with the code within a month. The block below exists for surfaces with no token layer to point at: artifacts, canvases, a deck, a page in someone else's stack. Component sources live in src/components/, the shared renderers in src/canon/, and the Tailwind mirror in src/index.css.
Paste-ready. This block is the whole colour and motion surface:
:root{
color-scheme:dark;
--void:#050505; --void-2:#0a0a0b; --void-3:#111113;
--paper:#f2f0e9; --ink:#0b0b0c;
--signal:230,230,230; /* rgba(var(--signal), <ladder>) */
--essence:#00f0ff; /* the dot & live elements ONLY */
--sigil:#c2333d; /* instrumentation lines & labels ONLY */
--witness:226,228,230;
--split-r:255,55,55; --split-c:60,220,230;
--o-1:1.00; --o-2:.85; --o-3:.70; --o-4:.55;
--o-5:.40; --o-6:.25; --o-7:.15; --o-8:.08;
--font-meta:"Geist",ui-sans-serif,system-ui,sans-serif;
--font-system:"Departure","SF Mono","Courier New",monospace;
--beat:1.6s; --sweep:10s; --ease:cubic-bezier(0,0,.2,1);
--ns-name:"metanomicon"; --ns-accent:var(--essence);
--ns-sigil:var(--sigil); --ns-mark:"/."; --ns-face:var(--font-meta);
}
Prompts that work.
-
Build a surface: "Follow
DESIGN.md. Void ground, Geist for prose and Departure for all labels and data, hierarchy by the opacity ladder only. Square corners. No icons — typographic glyphs. Essence only on live elements, sigil only on instrumentation. Procedural background, no image. Ship the reduced-motion state." -
Translate an incoming design: "Map every fill and stroke to a
DESIGN.mdtoken or reject it; replace foreign fonts with the two faces; icons become glyphs; photos go through the dither gate; rounded corners become square plus a border; rewrite the copy into the voice inVOICE.md." -
Review: "Check this against
DESIGN.md§11 and report each violation with the law it breaks."
The three-question check for anything claiming the mark: Does it contain a period? Could you remove the chromatic ghosts and still read it? Is the only cyan thing on screen alive?
15 · Accessibility
A system built on an opacity ladder over near-black has to know where that ladder stops being legible. It was measured, not estimated — and the measurement moved three rules.
| Rung | Alpha | Composite | Ratio vs #050505 | Legal for |
|---|---|---|---|---|
o-1 | 1.00 | rgb(230) | 16.33 | anything |
o-2 | 0.85 | rgb(196) | 11.69 | anything |
o-3 | 0.70 | rgb(163) | 8.08 | anything — body prose |
o-4 | 0.55 | rgb(129) | 5.23 | the floor for text — all labels |
o-5 | 0.40 | rgb(95) | 3.19 | UI borders and large type only |
o-6 | 0.25 | rgb(61) | 1.88 | non-text; disabled states |
o-7 | 0.15 | rgb(39) | 1.36 | hairlines |
o-8 | 0.08 | rgb(23) | 1.14 | hairlines |
-
o-4is the floor for text. This canon previously set labels ato-5and chrome ato-6— below 4.5:1 at the 9–11px sizes labels actually use.o-5–o-8stay in the ladder because borders, hairlines and disabled states legitimately live there; they are simply not text. -
Sigil is a line colour; sigil text is a lifted one.
#c2333don void is 3.72:1 — correct for a rule or a tick, below the bar for text, and at the 0.85 opacity this canon used it fell to 2.94:1. So lines keep--sigiland text takes--sigil-text, which is sigil lifted 18% toward white:#cd5860, 5.00:1. The percentage is derived, not chosen — it is the minimum that clears 4.5:1 with margin. The lift is void-only; on paper it would fall to 3.58:1 and plain sigil already passes at 4.80:1, so the paper block resolves it back. A namespace overriding--ns-sigilgets the same lift throughcolor-mix(), so the contract stays at five tokens. - Sigil text is still never a sole carrier: because it is instrumentation, it sits beside the thing it annotates.
- Reserved colours clear their bars. Essence 14.47:1, split-cyan 12.20:1, split-red 5.68:1 against void. On paper, ink is 17.25:1 and the deep teal essence 5.54:1 — which is why essence shifts hue between substrates rather than keeping its cyan.
-
Focus, keyboard, targets. Every interactive element takes a visible
:focus-visible— a 1px sigil outline at 2px offset, which is instrumentation marking the live target, not a new colour. Tab order follows document order; navigation is a real<nav>of anchors. Targets are 44px minimum (§10). - One sanctioned gradient. §11 forbids gradient stops, and the hero veil is one — so the rule needed the carve-out rather than the design needing a change. Type over a live field cannot rely on a flat contrast measurement, because the ground moves underneath it; the veil is a legibility device carrying no colour and no decoration, and it is the only gradient in the system. Anything else claiming the same exemption is decoration.
-
Motion.
prefers-reduced-motionyields a static, correct page: the lattice renders one frame with the living dot held att=3.0, the pulse plot draws the same curve without advancing. Nothing is merely slowed.
Appended 2026-10-03. Falsified → measured (artifact/strata4/front-door/evidence.md, R3). The table above composites the ladder in float and rounds. Chromium/Skia quantises the alpha to 8 bits and truncates the blend, so four of the eight rungs land one value lower than the table says. Measured on pixels for o-4 and o-3 (artifact/strata4/front-door/review.json, PIXEL CHECK, 2026-10-03); the other rungs follow the same arithmetic (ladder.json) and are derived.
| Rung | Alpha | a8 | Table (composite / ratio) | Pixel (composite / ratio) | Status |
|---|---|---|---|---|---|
o-1 | 1.00 | 255 | rgb(230) / 16.33 | rgb(230) / 16.33 | holds |
o-2 | 0.85 | 217 | rgb(196) / 11.69 | rgb(196) / 11.69 | holds |
o-3 | 0.70 | 179 | rgb(163) / 8.08 | rgb(162) / 7.98 | measured |
o-4 | 0.55 | 140 | rgb(129) / 5.23 | rgb(128) / 5.16 | measured |
o-5 | 0.40 | 102 | rgb(95) / 3.19 | rgb(95) / 3.19 | holds |
o-6 | 0.25 | 64 | rgb(61) / 1.88 | rgb(61) / 1.88 | holds |
o-7 | 0.15 | 38 | rgb(39) / 1.36 | rgb(38) / 1.35 | derived |
o-8 | 0.08 | 20 | rgb(23) / 1.14 | rgb(22) / 1.13 | derived |
The composites above were derived in float and rounded. The rasteriser quantises alpha to 8 bits (a8 = round(α·255)) and truncates (floor((a8·230 + (255−a8)·5)/255)), so on the screen o-3 is rgb(162) = 7.98:1, o-4 is rgb(128) = 5.16:1, o-7 rgb(38), o-8 rgb(22); o-1, o-2, o-5, o-6 hold. Measured on Chromium/Skia with swiftshader at dpr 1 (artifact/strata4/front-door/review.json); other rasterisers untested. The floor for text stays o-4 and stays above AA (4.5:1). The number the law states is one of two, and the operator rules which: (a) restate the floor as 5.16:1, the pixel; or (b) move --o-4 to 0.56, which quantises to a8 143 and composites to rgb(131) = 5.38:1 (ladder.json; the backlog's 5.35 is not reproduced), and restate the table. Option (b) moves every o-4 label in the estate by one value and is the only option that keeps a stated floor above 5.23. Until the ruling, src/index.css keeps --color-o-4 at 55% and public/tokens.css:84-89 keeps the float figures.
Appended 2026-10-03. From artifact/strata4/one-beat/evidence.md, after the "Motion" bullet above:
-
2026-10-03 · the held frame. t = 3.0 stays. The still was first taken there because
sin⁴(1.55·t)happened to be 0.99 at 3.0; undersin⁴(π·t/--beat)the same frame fell to 0.021 of the beat (the first pass of 2026-10-03,artifact/strata4/one-beat/hold.json). The beat's origin is now five eighths of a beat, so 3.0 is a systole by law:mnPulse(3.0) = 1, the living dot at full radius (field 14.0·scale px, 1-bit solid 13.0/pitch cells), the sweep head at 0.232 of its run, on screen (review-reduced.json). Everydraw(3.0)/T0 = 3.0/paint(3.0)in the strata holds unchanged; the onebit-3d byte-identity captures will differ from the 2026-09 ones by the dot's radius.
16 · Evidence
Every rule in this document ships with its reason. That is not the same as shipping with its evidence, and the difference is where this canon has been wrong. The 44px touch target, the ⌗ index glyph, the o-5 label, the namespace generalisation — all four were reasoned, plausible, written down, believed, and false. None of them survived being measured.
So every load-bearing claim carries a status:
| Status | Means |
|---|---|
| measured | A number a script in this repository produces. The script is named. |
| derived | Computed from another rule rather than chosen (e.g. the 18% sigil lift). |
| asserted | A deliberate choice. No measurement is possible or wanted — but it is marked, so nobody mistakes taste for evidence. |
| inherited | Comes from outside: WCAG, a font licence, the host. |
| falsified | Was asserted, tested, found false, and the rule changed. Kept visible, because a canon that hides its corrections invites them again. |
| untested | Stated and never verified. The honest default. |
The ledger
| Claim | Status | Established by |
|---|---|---|
Opacity ladder ratios; o-4 floor for text | measured | contrast-audit.mjs |
--sigil-text = sigil +18% → 5.00:1 | derived | contrast-audit.mjs |
| Reserved colours clear their bars on both substrates | measured | contrast-audit.mjs |
| Glyph vocabulary present in both faces | measured | coverage probe, contrast-audit.mjs |
| Two faces, weights 400/500, square corners, no icons | measured | review.mjs |
| ≤7ms/frame | measured — desktop, software GL | review.mjs |
| Reduced motion is static and correct | measured | review.mjs |
| 44px touch targets; no h-scroll 390–1440 | measured | review.mjs |
| Namespace contract holds across the registry | measured | namespace-check.mjs + document-scope render |
| Namespace contract holds for any legal namespace | falsified → floors added (§13) | same |
WCAG thresholds, SIL OFL, prefers-reduced-motion | inherited | — |
| The dot lineage; two faces; square corners; essence reserved | asserted | doctrine (§0) |
| Dither gate on real photographs | measured | §8 runs one live against three other algorithms |
| Any surface in paper mode | untested | the ratios are computed; nothing ships on paper |
| Print: 12pt floor, pagination | untested | nothing has been printed |
| Peak legibility at scroll 0.41 | untested here | inherited from the shipped surface |
| Frame budget on real mobile silicon | derived | no longer asserted — the field measures its own interval and degrades |
| Cloth hero: perturbs, does not drive; static & reproducible under reduced motion | measured | strata/cloth-hero/evidence.md — recovery to 0.12 mean Δ at 8s, byte-identical reload |
| 1-bit solid does not shimmer | measured | 0.47% cells/frame vs 4.94% control, strata/onebit-3d/evidence.md |
| Ephemeris seed is deterministic and instrumented | measured | strata/ephemeris/report.json — every step printed, seed changes with date |
| Tide bound to the moon; unbound page hash-identical to neutral | measured | strata2/tide-moon/evidence.md — four phases at one instant |
| Disagreement palette fires (warm leads rising, cold trails falling) | falsified → measured | thresholds never reached in this noise; reset to p85/p72 of 15,147 cells |
| The phantom mark is resolved from dots, never a shade | falsified → measured | it was a DOM glyph at 52% opacity; now 309 lattice cells, strata2/mark-weather/evidence.md |
| The mark reads on every date (radius band 0.55–1.0) | measured | 30 offsets over the domain, silhouette cells constant, spread 1.85× |
| Same seed, same output — demonstrated by the page, not asserted | measured | two contexts at one ?date=, field hash identical, strata2/address/evidence.md |
| Phase disc: three instruments, no grey | measured | 3 discs, 0 grey pixels, values track scroll / scale / gain |
| King Wen table is the received sequence | measured | 28 inversion pairs + 4 complement pairs, 8 self-inverse at 1 2 27 28 29 30 61 62, strata2/kingwen-dither/kingwen-check.txt |
| King Wen dither clumps (prediction stated first) | measured — half right | raw 4×4 variance +2.3% only; residual variance 3.5–5×, power below tile 13.27% vs 0.80% |
| Almanac: lunations appear as bands in the balance | measured | lag-29 autocorrelation 0.907 vs 0.915 for the moon; 13.8% of variation is the page's own terrain |
| Almanac paints no essence and no grey at any raster | measured | two colours in the bitmap at dpr 1, dpr 2 and 2040px: witness and one sigil ring |
| Figure played: no audio node before the gesture; closes cleanly | measured | wrapped constructors, 0 before press, 1 after, 0 after second press; double-press and 8-click hammer: 0 errors |
| Matra: the metre is derived from the orthography and scans 8 · 10 · 10 · 8 | measured | strata3/matra/probe.json prints every syllable with its length |
| Matra: Geist covers every glyph of the four lines; Departure covers the labels | measured | document.fonts.check per line, all true |
| Matra: same address, same constellation; another date, another one | measured | lattice hash identical across two contexts at one ?date=, different a month later |
| Matra: the only essence is the sounding dot | measured | 0 essence pixels before, 64 during, 0 after; sigil 0 before commitment, 867 after |
| Matra: nothing exists before the gesture, the context closes after | measured | 0 contexts before; 1 context, 1 oscillator, 1 gain during; closed and printed after; recite plus an eight-click hammer opens exactly five contexts, one per line |
| Matra: dots are marks, not shades — but their edges are antialiased | asserted, measured | 4.5% of canvas pixels are neither void nor witness: the arc edges. Tone is radius only; the edge is not 1-bit and this row says so |
| Matra: reduced motion static and non-blank; 44px targets; no h-scroll 390–1440 | measured | two frames byte-identical, 46,344 witness pixels; every press ≥ 44px; probe.json |
| Matra: frame budget on real silicon | untested | 16.7 ms p50 in software GL is the vsync floor, not a measurement of a phone |
| The ephemeris computes at 0°N 0°E | falsified → measured | it computes at the Royal Observatory (51.4779°N 0.0015°W); §9 and the round-one review page repeated the wrong point; the figure-player's builder caught it |
| Text-mode · sigil engine · steganography | briefed, not built | briefs banked under artifact/ |
| I Ching gate · text-mode · 1-bit sound · sigil engine · steganography | briefed in round one | the gate became the King Wen dither and the sound the figure played, both measured below; three remain briefed |
README index resolves (37 of 37 paths with ls -d; 0 gitignored; 37 of 37 on a fresh clone of HEAD plus the item's files); README Colour rows = §1 data rows (8 = 8, token column equal row for row); the three collisions present in ## Status (3 of 3); SKILL.md:16 names DESIGN.md | measured | strata4/readme-door/probe.mjs — 17 checks, exit 0; whether §1's eight rows are the palette design-system.src.html:1275 means ("Seven values") is not settled there |
/matra/ text nodes under their language: 37 walked (5 Slovak, 19 English, 13 neutral), 7 lang attributes, 5 aria-labels (4 Slovak on the press buttons), 0 mismatches | measured | strata4/matra-lang/probe.mjs, served dist, 1440×900 |
/matra/ holding copy (site/matra/index.html) differs from the rebuilt output by 3 hunks, 4 lines (the root lang, the h1, #manifesto, the setAttribute("lang","sk") line) until the operator copies it; /doctrine/ (2 Slovak nodes) and the two /explore/ pages still carry the lines under lang="en" | measured | same; strata4/matra-lang/fix-probe.mjs |
Front door / text at or above o-4; the 5.23:1 floor as a pixel | falsified → measured — AA holds, 5.23 does not | artifact/review.mjs against served dist/ (1440×900; 390×844 with the sheet open): 18–19 nodes ≤ 14 px at 1440 (the count moves with the marquee's strip at walk time — 19, 19, 18 across three runs; 19 in review.json as on disk, 19:42Z, floorChecked 44), 13 at 390, all o-4 at rgb(128,128,128) = 5.161:1, 0 below 4.5:1; the 24 marquee · separators excluded by selector ([data-sep]); strata4/front-door/review.json, PIXEL CHECK |
review.mjs audits / as a second target (three targets: the artifact from file://, served dist/ at 1440, served dist/ at 390 with the sheet open) | measured | artifact/review.mjs; the artifact target prints 246 ladder nodes below 5.23 and 135 sigil-text nodes, printed, not fixed |
| Home on a phone: wordmark inside the frame, one plate below 700 px | measured | strata4/front-door/probe.mjs, wordmark-sweep.mjs — clamp(2.5rem, 12.5vw, 317px); right edge 328.4 / 356.4 / 393.2 ≤ 344 / 374 / 414 at 360 / 390 / 430; sweep 12 of 12 widths 320–430 pass, 0 gutter px, smallest margin 8.359 px at 320; one plate (β) below 700 px; panel top above a visible caption's bottom 0 of 11 steps over 0.80–0.90 |
Root radii only on pill controls; sub-lg toggle is #; the sheet focuses its first row on open | measured (the radius and glyph halves of R15; the rail / doctrine-TOC numeral half is another item's) | review.mjs + strata4/front-door/probe.mjs — non-pill radii 0, .rounded-2xl 0 in the DOM and in src/; toggle # 44×44 radius 0, open ×; activeIsFirstRow: true; Escape returns focus to the toggle |
| React root eases are the token ease; pointer perturbs, never drives | measured | review.mjs ease guard over src/ (11 files): 0 hits; MoshScrub dot period T = 1.602 s (rmse 0.0178; the old 2.0268 s pulse fits at rmse 0.3134); wrapper and panel transform Δ 0 px over a 200 px mousemove; strata4/front-door/probe.json |
Family invariants per surface, day-one statuses as printed: canon / 2 families / 1 mono holds · holding site/index.html as built 3 / 2 fails (IBM Plex Mono 853 g + IBM Plex Serif 664 g + DejaVu Sans Mono 8 g, the glyphs → ─ └ ├ falling out of the self-hosted Plex Mono) · archive gallery/src/index.html 2 / 1 holds; six numbers canon [2,2,5,0,0,4], holding [3,0,0,0,0,2], archive [2,0,0,0,0,2]; /.well-known/metanomicon.json absent · absent · present (register and law keys absent), informational | measured | artifact/register-check.mjs, strata4/register-check/run.mjs → out-2026-10-03T1240Z.json; the builder worded no row (condition 4); this is the brief's W8 wording filled from the dated run, and its category word waits on ruling 3 |
| The explore plates are 1-bit files (two colours, 272×170) rendered at an integer cell pitch in the card (1 device px at 1×, 2 at 2×), status line one line box at 1440 and 390 | measured | strata4/plates/probe.mjs — 11 plates × 2 decoders, 33 card regions, 44 line-box counts |
| The plates reproduce from the pages at the seed | measured twice | strata4/plates/reshoot-check.mjs — 11 of 11 masters byte-identical on each re-shoot |
A cell that is --void on the page is unlit in its plate | measured | strata4/plates/fix-check.mjs — 0 of 151,099 uniformly-void cells lit |
| The address is set in type on every controlled surface (canon rail, gallery anchor, holding h1, init wordmark) | derived (three rendered surfaces, one charter line) | strata4/address-in-type/probe.mjs — grep of the period forms on the holding template: 0; period present on 2 of 4; three surfaces rendered at 1440 and 390; init read from CHARTER.md:76 prose, no surface on this disk |
| The dot of law 1 ascends to the family | untested — operator's | ruling 1 in artifact/briefs/critique-2026-09-30.md; the lawbook sets no period today |
| Lattice mark: one cell list, three renderers, same cells (block, disc and SVG path light the same nine cells; the 16 and 32 rasters are the 8×8 bitmap ×2 and ×4 byte for byte; 14 of 14 hashes equal across two builds) | measured | scripts/mark.mjs, probe artifact/strata4/mark-figure/probe.mjs — 129 checks, 0 failed |
| Vessel figure is Departure's 11 px bitmap (frozen bitmap = live canvas raster, 0 px differ at two frames; cap 8 rows; DOM raster equal at threshold 50 %, 134 grey px before thresholding; the box is 42×10, the brief's 42×11 falsified) | measured (raster) | same; public/brand/mark.json → vessel.box |
| Diagonal joint gap: derived 1.3 px at 64, measured 0 (the discs touch at p = 8); derived 10.5 at 512, measured 8.5 | measured | same |
Brand rasters equal lib/mark.js (node scripts/mark.mjs --check, 18 checks offline, 35 served); wired into the build | measured; untested until package.json or verify-pages.mjs calls it | scripts/mark.mjs |
| Glossary: 15 of 16 terms have a listed sense on disk; 3 of 22 listed senses (archive/register; figure/figure-ground; figure/mark) have none in the five files; 49 of 294 prose uses fit no listed sense (mark 11, root 8, substrate 8, plate 8, surface 7, others 7) | measured | strata4/words/grep.mjs, out.txt 2026-10-02 |
An unfamiliar agent given only this document, the skill, tokens.css and the fonts lands in the brand | measured — once, 2026-10-03, HORCRX #003: instrument [2,1,5,0,0,0], invariants 1 2 4 5 hold, 3 (five radii, no permit) and 6 (address in type: 0 nodes) fail; 0 errors, no h-scroll, flat contrast 0 below 4.5:1, pixel contrast 3 nodes below (1.03:1 at the eyebrow); judge 1 conformance 6 · placement 7 · craft 7, judge 2 5 · 6 · 6 | artifact/strata4/agent-trial/ — notes.md, measure.json, judge-1.md, judge-2.md; builder's read set asserted, not transcript-verified |
| The field's density at rest: lit fraction 0.998 of cells (centre > void + 24/255) at two dates, pixel coverage 44%, radius p50 0.28–0.35 pitch, p99 ≤ 0.51, max 0.55, 0 cells at the 0.62 cap; discs touch in 0.57% of cells at t = 0 and 2.6% inside the sweep at t = 3.0; 0 solid runs ≥ 24 px at rest, 46 in the sweep band | measured | strata4/agent-trial/field-density.mjs → field-density.json; readPixels through the page's own contexts with ?probe=1; the shader's own mask (MN_PROBE_DF) gives the same numbers |
| §9 teaches the field: the noise, its range, the remap, the density, that discs do not merge, and how a surface reaches field and seed | falsified → appended | three readers (two judges, one builder) named the same gap; the builder reinvented the noise, remapped it to a range of −0.9..1.3, saturated 7.2% of pixels into 166 solid runs and hashed the date for a seed; §9 append 2026-10-03 |
The hero field's geometry moves with ?date= | falsified → measured | hero #lattice has no seed uniform and reads MN_EPHEMERIS for tint only; same bytes at two dates (a592120f); the ephemeris stratum's #ephField takes u_off and differs (fb919b17 / 5e0e6629); §9's "seed as an address" row holds for the seeded field |
lib/gl.js's GLSL_NOISE / GLSL_WARP is the field's noise | falsified | mnFbm lacunarity 2.03 on a sine hash against fbm4 lacunarity 2.0 on hash21; the shipped field is field.glsl mounted whole |
| Which face a vessel's headings take | derived → §2 append; the vessel-heading case is the operator's | §2 + §13 + tokens.css:100 |
sin⁴(t·1.55) beats on --beat | falsified → measured, period was 2.0268 s; now 1.600 s dot (three runs, direct readback, spread 0.000 s), 1.600 s plot; maxima clause withdrawn (no phase lock by design) | strata4/one-beat/probe.mjs → probe.json |
| The held frame at t = 3.0 is a systole | falsified by the first pass (0.021 of the beat) → measured: the origin 5/8·--beat makes it one, mnPulse(3.0) = 1, field 102 essence px against live 21..110 | strata4/one-beat/hold.json, review-reduced.json |
| Clock table reproduces from four constants | measured — 10 of 12 rows; three brief cells are typos (11,055→11,056; 24,951→24,950; 2,551,442.877→.878) | strata4/one-beat/table.mjs |
| The mark shows through the weave | falsified → lede rewritten 2026-10-03; composite gate pending | strata4/phantom-gate/evidence.md |
Signature probe: 1000 seeded signed plates decode 1000/1000 (distance 0 on all 1000), 1000 unsigned 0/1000 (distance min 8, max 37, mean 19.58; polarity 507 light-on-dark, 493 dark-on-light); the eleven shipped explore plates signed 11/11 PASS d = 0, unsigned 11/11 ABSENT (19, 9, 26, 9, 20, 18, 9, 15, 9, 9, 9); colours 2 on 1011/1011; tEXt metanomicon round-trips 11/11; pixels changed outside the box 0; option off leaves the plates byte-identical (sha256 11/11 against plates-before.json, in public/ and as served from dist/); downscaled 2× ABSENT 11/11 (half-size file: the probe's box and the signature's image share 0 cells; 2× box + 2× nearest round trip d = 9 on 11/11); the shipped plates are unsigned | measured | scripts/signature.mjs, strata4/signature/probe.mjs → probe.json — 105 assertions, 0 FAIL; the cells are set after the Bayer pass (not the brief's thresholds 0 and 63), polarity from the ring's lit density; the builder worded no row, this is the brief's W15 wording filled from the evidence |
| False-positive bound Σ C(64, k ≤ 2) = 2081 / 2⁶⁴ = 1.128 × 10⁻¹⁶ | derived — for 64 independent fair cells, which no plate here has; the measured floor is ≥ 8 on 1000 synthetic unsigned plates and ≥ 9 on the eleven real ones (a void window reads 9, the figure's lit count) against a PASS at ≤ 2 | strata4/signature/probe.mjs (BigInt), §E; evidence §What was not established |
The front door's period is the page's one living dot; nothing still on / is essence | measured | register-check invariant 2 on served /: live 1 (the period, changed over 1 s), still 0; was still 2. Period by computed scale 1.598 s / 65 frames, by rendered pixels 1.601 s / 113 screencast frames (after the fixes of 2026-10-03; 1.599 s / 58 and 1.602 s / 112 before them); the breath written as --period-scale and --period-halo on span.period, swelling 20 % about the ink's centre (origin 0.133 em above the box bottom, derived from the face's metrics; centroid travel 0.06 px at 1440, 0 px at 390); while the nav's period is lit the hero's period rests, carriers 1 in every state; reduced motion: period in signal, essence carriers 0 (artifact/strata4/period-live/) |
| Social plate survives a 2× downscale at one bit | measured | scripts/plate-social.mjs, strata4/social-plate/probe.mjs (2 colours before and after, 0 non-uniform blocks, 2 plates) |
Social plate ground: the field's climate at the canonical seed, doubles port of field.glsl with the stratum's offset wiring; lit 0.0864 at gain 3/8 | measured; gain · asserted | same, probe.mjs §C (--stats: 0.2136 at gain 1, 0.0863 at 0.375) |
| Doubles port vs swiftshader float32: 0.32 % of Bayer decisions differ; a float32 emulation agrees on 100 % of cells within 1/255 | measured | strata4/social-plate/probe.mjs G |
Signature on the social plate reads PASS at one pixel per cell: node scripts/plate-social.mjs --probe on the shipped file, distance 0, exit 0 | measured; scripts/signature.mjs probe on the same file reads cells as pixels and prints ABSENT; a --cell option there · untested | strata4/social-plate/fix-check.mjs |
| Signature on the social plate survives the 2× downscale by construction (cell 2: one pixel per cell, distance 0); gone at 4× (two cells per pixel, distance 9, box mean) | measured; other resamplers · untested | strata4/social-plate/fix-check.mjs 4 |
Social plate sha256 identity across builds (f26e4d21… ×3, 24f1cc2b… ×3) | measured on one Chromium (swiftshader, 1× DPR); another rasteriser · untested | strata4/social-plate/probe.mjs F; the threshold reduces the address to the font's 11 px bitmap (0 grey), the reason it is expected to hold |
Four surfaces through one gate at one cell: the same gate(), GAIN, ON/OFF, Bayer-8, CELL = 2 page px as the eleven; 272×170, two colours, 4 device px per cell | measured | strata4/family-plates/probe.mjs §A, §F; scripts/plates.mjs |
| Family plates: each plate signed by the gate (option on) and readable: Hamming 0 ×4, option-off control ABSENT ×4 | measured | same, §B |
Family plates: signature.mjs sign and the gate's option write the same 64 cells (0 changed on re-sign) | measured | same, §B |
Family plates: tEXt provenance present with the five keys; source_sha256 names the gated raster, masterSha256 beside it in the manifest | measured | same, §B |
| The holding's plate is built from the read-only template; the period forms count 0 before and after; the file and the worktree untouched | measured | same, §C, §E |
The served template renders IBM Plex: the four markers mapped to the four files build.py inlines, which are the bytes in site/index.html | measured (base64 inclusion ×4; faces loaded ×4) | same, §C |
The holding's ground #0c0b09 lights 3 of 64 cells under the canon's gate (4.73 % of its flat cells) | measured; predicted 4.69 % from the normalisation and the Bayer-8 thresholds | same, §G |
| The archive is served from the overlay, not a dist; placeholders literal; one 404 outside the window | measured | same, §D |
| The four windows re-shoot byte-identical under reduced motion on swiftshader (the root's field and the archive's hero included) | measured, one re-shoot | same, §E |
Family plates: the clip rects frame what the what strings say | asserted (chosen by eye from survey.mjs's frames) | strata4/family-plates/survey.mjs, survey.json |
| W9's eleven plates are unchanged by this item | measured (11 sha256 equal to W15's banked manifest) | strata4/family-plates/probe.mjs §A |
Family plates: verify-pages.mjs passes after the rebuild | measured | same, §H and the bare run |
public/lib/gl.js carries the shipped field: GLSL_FIELD is artifact/field.glsl byte for byte (8,163 bytes), GLSL_FIELD_SEEDED adds u_off in two lines with the seven function bodies unchanged, and mountField mounts it with u_res u_time u_mouse u_hover u_pitch u_tide u_wax u_probe u_off; mountShader, GLSL_NOISE, GLSL_WARP unchanged (449 lines appended, 0 removed) | measured | strata4/field-lib/probe.mjs → probe.json offline; promote.mjs |
A surface that builds the field on the library draws the shipped frame: library = inlined field.glsl by pixel hash at two dates and two boxes (bc720fb2, 75a6407f, 0a1a25ad, 257ceb80), and at u_off = (0,0) the seeded program, GLSL_FIELD itself, the file unpatched and patched agree (87400386); against the hero the geometry agrees 15,139 of 15,139 cells and the 0.52% of pixels that differ are the dot's pulse (1.55 vs BEAT_W, radius 13.942 vs 14.000 px) | measured | same, dates.*.compare, zero; diff.mjs → diff.json |
The library field equals the canon's #ephField at the same u_off | falsified — by design of the variant, not the library: geometry agrees 3,611 of 3,614 cells, 38% / 28% of pixels differ by the older tint path (0.10 / 0.055), u_dot, the 5 + 6·beat dot | same; agent-trial/evidence.md fix 5 |
Library field density at rest, t = 3.0, u_tide 0.5 / u_wax 0: at the canonical seed (2026-09-03, off 6.235 / 22.423) lit 0.9329 in the 784×300 box and 1.0000 of 20,154 cells at 1440×900, coverage 31.8% / 42.6% above the void; at 2026-10-03 (off 36.409 / 18.133) lit 0.9492 and 0.9753, coverage 17.4% / 17.2%; mask channel 0 cells at the 0.62 cap at both dates | measured | same, dates.*.libraryBox, libraryFull, *Mask |
mountField holds under reduced motion (same bytes 800 ms apart) and degrades resolution only: sampled every 500 ms for 11.5 s, the scale steps 1.0 → 0.75 → 0.5 within 10 s of software GL and never rises; the buffer follows each step (final 720×450 = round(1440 × 0.5) × round(900 × 0.5)) | measured — swiftshader; the step's direction and the buffer following it, not a frame budget on silicon | same, hold, degrade |
| Period contrast at 12 px, root and atlas, void and paper | measured (14.47 / 5.54 / 11.73 / 5.54 by colour; by pixel the vessel on paper 1.98–3.41, step raised to 18) | artifact/namespace-render-test.mjs, strata4/mark-block/probe.mjs |
| 30/18/12 ramp, one-cap clearspace | asserted; the vessel's bottom step on paper is 18 · measured (by pixel) | strata4/mark-block/vessel-steps.mjs |
Lattice study drawn by lib/mark.js, 2 colours, 36 / 144 / 732 lit | measured | strata4/mark-block/probe.mjs |
Wordmark zone against the cloth band at ≤ 700 px (band ∩ h1 and band ∩ .hero-meta) | falsified → measured at the frames measured, not "every frame": ∩ 0 px at 390 × 844, 375 × 667, 360 × 780 (with and without reduced motion, pressed, scripting off) and at 393 × 852, 412 × 915, 414 × 896, 430 × 932, 700 × 900; 320 × 568 falsified 2026-10-04 (∩ meta 39.47 px, the clamp standing) → fixed (band hidden, ∩ 0). Other frames, real devices, other browsers: untested | strata4/hero-band/probe.mjs (the three frames and 320 × 568); strata4/mark-block/review-probe.mjs (the five further frames); strata4/mark-block/review-320.mjs |
| Hero rows are what the surfaces compute | measured (4 rows × 2 frames, 8 of 8 equal; 768 and 1024 added by the reviewer, 4 of 4) | strata4/hero-rows/probe.mjs, strata4/mark-block/review-probe.mjs check D; the 15vw literal remains only in DESIGN.md:251's render until the §2 append lands — it landed 2026-10-04 as rows beside the old one, not in its place; the row and the note that names the grep command both render into /doctrine/, so the grep stays non-zero (2 measured before this pass) and the clause that holds is (b), the literal ships on no surface's stylesheet (§2 append) |
| Departure at 11 px, by proportion of the glyph box, renders 0–0.9 % grey where glyph origins are snapped (five of eleven strings at 1×; 10 px: 27–37 %) and 19.9–20.9 % where the renderer subpixel-positions them (the other six; 10 px: 26.6–36.9 %); on live labels 11 is the least grey of 10–13 on 5 of 5 at 1× and 4 of 5 at 2×, and by absolute count reduces grey against 10 px on 0 of 5 at 2× (the 11 px box is larger); the size is necessary, not sufficient | measured (1× and 2×, swiftshader); the brief's W17 wording "reduces the grey count" does not hold by count at 2× — the measure is the proportion | strata4/mono-grid/probe.mjs, review-probe.mjs, review-probe-strings.mjs, fixes.json |
| Every Departure text node on the artifact computes 11 or 22 px except the §2 face-switch accents (22, inline at 0.85 of a Geist parent; the rule reads the ratio) | measured | artifact/review.mjs DEPARTURE ON GRID (823 on · 0 off · 22 face-switch) |
23 of 26 live Departure labels on /canon/ render on the LCD-subpixel path with 2.9–22.4 % grey at 1× | measured | strata4/mono-grid/probe.json → survey |
| Fractional DPR (1.5×): no size of 10–13 is the least grey across five live labels; the size rule does not hold there | measured (swiftshader); the brief's W17 row read "untested" | strata4/mono-grid/review-probe.json → grey, fixes.json |
| Type scale is one scale, measured from the surfaces | measured (px font-size literals in the artifact source and the document shell: 0; 26 tokens, 128 of 128 rows hold at 1440 and 390) | strata4/type-scale/probe.mjs, table.md |
The artifact's token block is generated from tokens.css, never typed; 55 typed tokens compared, 0 disagree | measured | scripts/tokens-mirror.mjs --check, artifact/review.mjs |
--signal and --witness exist in tokens.css and read back from /canon/ and /doctrine/ | measured | strata4/type-scale/probe.json |
| §2's intermediate trackings and the 13–16 body range retired with a dated argument, not silently | derived | strata4/type-scale/evidence.md, Derived; §2 append 2026-10-04 |
src/ and the five unwalked preview pages consume none of the variables | untested / named | strata4/type-scale/evidence.md, Not established — src/index.css carries its own --color-signal and --color-witness; three of the eight alias pages walked |
What this canon has not established
Naming the negative space is the practice this canon took from the V2SPACE corpus, where every technical note states what it did not show — a reference file is not a design system, a routed model is not automatically compatible, a successful demo is not a benchmark.
- That it works on paper. The paper substrate is specified and its contrast computed; no surface has been built on it. Treat paper as designed, not proven.
- That it survives print. No plate has left a screen.
- That it is fast on a phone. Still not measured on real mobile silicon — but no longer asserted either: the field measures its own frame interval and gives up resolution rather than frames. The claim moved from untested to self-correcting, which is not the same as proven.
- That an agent using it produces conforming work. The rules are checkable; whether an unfamiliar agent given only this document lands in the brand has not been trialled. That is the whole purpose, and it is the least evidenced claim here.
- That the character survives being described in words — Part 0's own line for what this must never become. Untestable as written, which makes it an aspiration, not a rule.
Appended 2026-10-03.
-
Fractional DPR (1.5×). (2026-10-03) Every probe of stratum four ran in headless Chromium under swiftshader at DPR 1 and 2. At 1.5× the explore plates have no integer pitch: nearest-neighbour match 0.80684–0.99877, 2×2 block uniformity 0.47004–0.95074, 3×3 0.01339–0.91005, 10 of 11 card boxes hold 3–8 colours (
strata4/plates/fix2-check.mjs§B) — falsified there, measured at 1× and 2×; no mitigation built (2 device px per cell is 362.67 CSS px, 3 is 544 CSS px, neither fits the 272.66 px box). The 8-bit truncation of the ladder (§15), the mark's cells and Departure's grid at 1.5× are untested (strata4/front-door/,strata4/mark-figure/). -
Whether the dot ascends. (2026-10-02) Whether the dot of law 1 ascends from the instrument to the family, the lawbook sets no period today, is the operator's ruling. Until it is ruled, the family invariant is worded without the dot (§0), the mark work designs for surfaces that carry no dot, and
grep -c '/\.\|\[\[\.'onsite/template.htmlstays 0. -
That the glossary names what the files say. (2026-10-03)
strata4/words/grep.mjsoverDESIGN.md,VOICE.md,REGISTRY.md,BRAND.md,DESIGN-CANON.md: 341 occurrences (294 prose, 47 identifiers) of 16 terms; collisions A = 49 (a prose use that fits no listed sense: mark 11, root 8, substrate 8, plate 8, surface 7, others 7), B = 3 (a listed sense no audited file uses: archive/register, figure/figure-ground, figure/mark), total 52. The commonest sense of plate in this document (8 of 13 prose uses) is the layout container of §§3–5, which the glossary does not list; mark carries law 2's dither marks 6 times in this document (7 across the five files:DESIGN.md6,VOICE.md1) beside the address glyph. The VOICE.md## Wordsappend is held until the audit prints zero; the rest of the repository is unaudited. -
That an agent using it produces conforming work — the bullet above is falsified as written. (2026-10-03) It has now been trialled once, on 2026-10-03, HORCRX #003: one builder, one brief, one namespace, one run; the row moves from untested to measured and the numbers are in the ledger (instrument
[2,1,5,0,0,0]; judge 1 6 · 7 · 7, judge 2 5 · 6 · 6). A sample of one does not generalise to "an agent". What the trial did not establish (artifact/strata4/agent-trial/evidence.md, §Not established here): whether the builder's read set was exactly the permitted one (the transcript is not in that directory; the builder's statement is asserted); the hero field in motion (every number is the reduced-motion frame at t = 3.0 or a redraw at t = 0 through the page's own program; the drift, the gate's breath and the sweep move the density over 17 s and 10 s and were not sampled over time); the field at DPR 2 and at 390×844 (one viewport, one ratio); whether promotingstratum.jstopublic/lib/keeps/canon/byte-identical (not tried). -
One beat on every surface. (2026-10-03) The period is measured on
/canon/(the living dot, the beat plot,.mn-anim-beat) and on/(the wordmark's period, the MoshScrub dot). Not frame-sampled: the 2D fallbacklivingDot(samemnPulse; the reviewer sampled it under origin 0 at 1.5991 s), the figure-played sub pulse and the matra dot swell (changed in code;strata2/figure-played/evidence.md's bitstream hashes predate the change), the king-wen stratum's held frame (nowebglcontext to the reduced read). The gallery'score.js:19onmainstill beats at 2.0268 s;public/lib/chroma.js:152andpublic/preview/index-constellation.html:403carry 1.55 and are named, not touched..mn-anim-beathas no consumer in this repository; whether a namespace outside it consumes the class is not known from here. The falsifier's maxima clause ("cross their maxima together") is withdrawn, not met: no phase lock by design, offsets +34 / +36 / +34.8 frames in one set of runs and +1.5 / +20 / +14.6 in the next. Software GL only; the field degraded itself to 614×396 at 10.5–16.9 fps.strata/onebit-3d/evidence.md:76still reads "0.99 of systole"; the value is 1.00 now and the file is that stratum's. (artifact/strata4/one-beat/evidence.md) -
That the mark shows through the weave. (2026-10-03) The lede on
/canon/now says it does not yet read: Michelson −0.034 over the glyph bbox at 1440×900, reduced motion, swiftshader (92.5 vs 98.9 Rec.709 luminance inside the mark's cells vs the rest of the bbox), inherited from the critique's refuter and not re-measured; the 0.20 floor is chosen, not derived; the composite gate (R1 steps 2 to 5) is not built; the no-canvas fallback still paints a 0.38-opacity solid glyph; real silicon untested. (artifact/strata4/phantom-gate/evidence.md) -
The signature on a shipped plate. (2026-10-03) The explore plates ship unsigned (served sha256 11/11 equal to
plates-before.json, ABSENT 11/11, notEXt); signing them, the family plates and the social plates is a brand act under ruling 9 and changes eleven committed-manifest hashes. The margin on uniform ground is 9 bits, not 30: eight of the eleven plates have a void or near-void window and read 9 unsigned; the synthetic floor was 8 (3 of 1000); the 2081/2⁶⁴ bound describes a random region, which no plate has. Dark on light was exercised only synthetically (493 of 1000; all eleven shipped plates read light-on-dark, ring density 0 to 0.31). The polarity rule is the ring's output lit density, not the brief's pre-gate mean of the 24×24 window, and the cells are set, not the brief's thresholds 0 and 63 (which do not write on a tone-0 ground); where the two polarity rules would disagree was not measured. Every decode is the Node decoder inplates.mjs; no signed plate was opened in Chromium; the downscale is one 2× box filter and its 2× nearest-neighbour inverse, no browser's resampler; "nearly hidden … texture at reading distance" has had no viewer;src/canon/dither.jsis a stale copy of the old file. (artifact/strata4/signature/evidence.md) -
The front door's period at 60 fps and off Chromium. (2026-10-03) Every timing of the period is swiftshader at 5.6–5.8 fps; the breath is wall-clock, so the period does not depend on frame rate, but the visual at 60 fps was not seen, nor the bottom row's 2 px travel at 1440.
:has()in Safari below 15.4 and Firefox below 121: the door rule does not apply and the hover state returns to two carriers; not measured. The hand-over when the budget passes is a snap, neither the one ease nor linear; not ruled on. The period's contrast at the 40 px floor against the live field is R11'snamespace-render-test.mjs, not measured here; the frame cost of the two property writes is not measured and §6's 7 ms budget is not re-proved; whether the 600 px hand-over (both dots under 0.01; the 650 px row 0.046) is one dot or two is a reading the probe does not decide. (artifact/strata4/period-live/evidence.md) -
The social plate off this machine. (2026-10-03) The signature is read at one pixel per cell:
scripts/signature.mjs probereads cells as pixels and prints ABSENT, distance 9, on the shipped 2 px plate at pixel inset 8; PASS, distance 0, is measured on the 2× downscale (the platform's 600 × 315) and bynode scripts/plate-social.mjs --probeon the shipped file; a--celloption on the CLI is W15's file and untested. Byte identity across rasterisers: measured on one Chromium (swiftshader, 1× DPR, three builds, one sha256 per plate); another rasteriser or font stack is untested — expected to hold because the 50 % threshold leaves the 22 px address as the pixel font's 11 px bitmap with 0 grey pixels, which is an expectation, not a measurement. Real GPUs: the port is compared with swiftshader only, where 0.32 % of the ground's Bayer decisions differ (max |Δv| 0.1997); a visitor's GPU differs on an unmeasured fraction. The ring's size (§3.5's one figure height at p = 32 empties the left 576 px; whether eight dither cells, 16 px, was meant was not asked), y = 186 not the brief's 187 (off the cell grid, not ruled), no link-preview renderer run (the 2× box filter is the probe's own; bilinear, Lanczos, a crawler's resampler and crops to other aspects untested), paper and void grounds accepted by the script but not built, other registers' plates theirs to build, ruling 8's seed still the proposal, no page carryingog:image(ruling 9). (artifact/strata4/social-plate/evidence.md) -
The family plates against the deployed archive, and on a lighter ground. (2026-10-03)
gallery.metanomicon.orgwas not fetched;gallery/distdoes not exist onmain; the archive plate is ofgallery/src/index.htmlserved from an overlay with its{{…}}placeholders literal and the hero still 404ing (/hq2/undertow/wide-preview.webp, outside the window), so whether the deployed hero region at 1440×900 matches this window is untested. The four clip rects are a choice, not the windows/language/§1 must show. "Nearly hidden" (§3.7) does not hold where the box sits on flat void: the archive ring is 0/512 lit, the matra window's 3 signature cells land on flat void, the canon's and holding's rings are sparse (0.068, 0.053). One gate on a lighter ground: the holding's#0c0b09comes out as a 4.73 % dither texture because the canon's normalisation sets#050505to 0; whether the lawbook's plate should be normalised to its own ground (two gates) is for/language/. Software GL only; pitch measured at DPR 1 and 2, and at 1.5× W9's finding (no integer pitch) holds by construction and was not re-measured. What the archive's hero canvas draws at its reduced-motion frame was not examined (intersection with the window now 0 × 340 CSS px). Named, not fixed, other items' files:strata4/signature/probe.mjs§A compares against an eleven-entryplates-before.jsonand would print the four as new;scripts/site-pages.mjslogs 11 plates through the gate while 15 are built;revisionin thetEXtis the short HEAD at build time, so the file's sha256 changes with every commit whilerasterSha256does not. (artifact/strata4/family-plates/evidence.md) -
The library field in motion and on silicon. (2026-10-03) Every hash is the reduced-motion frame at t = 3.0 or a redraw at t = 0; the 10 s sweep, the 17 s gate and the pointer's perturbation were not sampled over time, and
u_hover > 0was never set in any compared frame. DPR 2 and 390×844: one viewport, DPR 1, scale 1.0; the array's 1.5 / 1.25 rungs are unreachable (the index starts at 1.0 and only increments). The degrade step on silicon: the rule (median > 20 ms over a 40-frame window, step down, never up) was watched twice in software GL and never on a GPU. That the one "cell at the cap" in colour-mode rows is the dot's0.72 × ESSENCEring is derived from the filter threshold and the mask rows' 0, not isolated pixel by pixel; whether the 3–4 cells that disagree with#ephFieldsit in the two dots' halos was not located.u_tide/u_waxfromwindow.MN_EPHEMERISon a page that publishes it is the canon's code copied, not exercised (the test page has no ephemeris; the 0.5 / 0 default is the path measured).mountField'snullpaths (no WebGL, compile failure) were not exercised.stratum.js(MN_derive) is still not underpublic/lib/. (artifact/strata4/field-lib/evidence.md) -
The period's pixel at 12 px off swiftshader. (2026-10-04) Every pixel number of the mark block is Chromium/Skia under swiftshader; at 1× the vessel mark's period on paper peaks 3.41:1 at 1440 × 900 and 1.98:1 at 390 × 844 and the bottom step is raised to 18 px, at 2× every tile's 12 px peak equals its named colour and the raise is not needed, so the raise is a 1× rule for this rasteriser; real silicon and other rasterisers untested. The 96 / 30 / 18 / 12 ramp and the one-cap clearspace stay asserted (brandkit values). "By pixel" is the peak pixel, a chosen statistic that decides the outcome: by the mean of the period's own pixels no 12 px step clears 4.5 on any tile at either DPR (1×: root void 2.45, root paper 2.00, atlas void 3.23, atlas paper 1.92; the raised 18 px atlas paper 2.12). Named, not ruled: the five-token contract has no paper accent, so on paper every namespace's period is the canon's
--essence-ink(#056a75) at 5.54:1 andnamespace-check.mjscarriesaccentPaper(#1f6b5a for atlas) as data only (§13);tokens.cssbinds--dotto--essence, not to--ns-accent, and the block binds its own per tile; the artifact remains void-only, so "paper" is a tile, not a[data-mode=paper]surface. (artifact/strata4/mark-block/evidence.md) -
The cloth band on a short frame. (2026-10-04) The band's height is what the frame leaves: 204 px at 390 × 844, 133 px at 360 × 780, 51 px at 375 × 667 (hero 627 px, the bottom-anchored block 410 px of it), and at 320 × 568 none — the block fills the hero (529.67 of 533.91 px), the band is hidden and the hero carries the wordmark, meta, lede and chrome alone. Whether a short frame should get a taller hero, a shorter lede or no cloth is not ruled; the falsifier is the overlap, and it is 0. The field lattice still runs under the wordmark zone on every frame (the veil's job, unchanged). Frames other than 390 × 844, 375 × 667, 360 × 780, 320 × 568 and the 1440 control, real devices and browsers other than Chromium: untested. The page's horizontal overflow at 320 (
scrollWidth339:.ch-phantom325 px,.ch-phantom-cv330 px, a 520 px table) is pre-existing and outside R13. (artifact/strata4/hero-band/evidence.md) -
The hero rows beyond the frames measured. (2026-10-04) Equality with the live surfaces is measured at 1440 × 900 and 390 × 844 (8 of 8) and at 768 and 1024 (4 of 4); the
/canon/page computes the wordmark and document rows in its own viewport from the same clamp, not by reading the other surface. Leading and tracking per row are read from the stylesheets, not measured. The grep clause of the falsifier (0 overpublic/anddist/) read 2 before this pass, both this file's render into/doctrine/; the row atDESIGN.md:251still stands, and the dated note beside it names the grep command itself, so the clause cannot be met by any append to this file and the builder's re-wording (b) — the literal ships on no surface's stylesheet — is the one that holds (§2 append). The five strata harness copies (artifact/strata/{ephemeris,cloth-hero}/harness.html,artifact/strata2/{figure-played,almanac,kingwen-dither}/harness.html),artifact/strata2/almanac/proto.htmlandartifact/strata4/agent-trial/{evidence.md,notes.md,surface.html}carry the literal and are frozen: a stratum's harness records the page it measured. (artifact/strata4/hero-rows/evidence.md) -
Fractional DPR (1.5×), Departure's grid. (2026-10-04) The bullet above names "Departure's grid at 1.5×" untested; that clause is falsified as written — measured 2026-10-04 on five live labels (
nav.top a,article th, the kicker on/doctrine/;.rail-suband the injected label on/canon/): 11 px is the least grey of 10–13 by proportion on 0 of 5 and reduces grey against 10 px by count on 0 of 5; at 1.5× no size is least across labels and the size rule does not hold. The 8-bit truncation of the ladder (§15) and the mark's cells at 1.5× stay untested; real silicon is untested at every ratio. (artifact/strata4/mono-grid/review-probe.json,fixes.json) -
Departure's grid where the renderer decides. (2026-10-04) Which property of the rail's paint context selects the LCD-subpixel path for text in flow, and why
letter-spacingof .01px, 1.54px and 1.98px snap origins on the injected label while normal, .1px, .25px, .5px and 1px do not: measured as behaviour, mechanism not identified; the text content selects the path as well (five of eleven strings snap, six do not, same class, position, colour and tracking). The 22-device-pixel residual (1412–1416 grey with fringe 0 at 11 px 2× and 22 px 1×) on the snapped path. Paper mode: the probe runs on void only. The/front door's 63 off-grid Departure nodes at 9 / 10 / 12 / 14 / 16 px (src/, served 1440). Whether labels ato-4that never reach their ink in situ (peak 124 against 128) still clear the floor by pixel: at 124 the ratio to void is 4.97:1, under the 5.23:1 the ladder derives and over 4.5:1 AA; W1's pixel check measured the fill, not the glyph in flow. That the 11 px data roles (code, pre, table first column, readouts, the text input) read on a real display: the operator's eye;.fieldat 11 px is below the 16 px at which mobile Safari stops zooming on focus, named, not tested.will-change:transformon every label would put the artifact's labels on the snapped path in this renderer (0 grey at 1× on the rail label): a measured remedy, named, not applied. (artifact/strata4/mono-grid/evidence.md) -
The scale beyond the surfaces walked. (2026-10-04)
src/(the front door/,src/index.css,src/App.tsx) consumes none of the variables: the wordmark row holds becauseApp.tsxsets the same clamp, compared across pages;src/index.cssstill carries its own--color-signaland--color-witness.public/preview/*.htmlandpublic/applications/index.htmlrender through the four aliases; their sizes changed from 9 / 10 px to 11 px and their trackings from .04 / .10 / .24em to .14em by the alias; measured on three of the eight pages, the other five not walked. Paper mode:--signal: 20,20,26under[data-mode=paper]is written, not read on any surface. 768 and 1024 px frames: not read (1440 and 390 only). Leading is not tokenised (line-heightstays typed per rule; the three dead--leading-*tokens are removed, not measured). §2's old rows stand beside the appended ones, so/doctrine/prints both; §14's code-mapping block names--signaland--witness, whichtokens.cssnow has. Real mobile silicon, fractional DPR, print: untested. (artifact/strata4/type-scale/evidence.md)
Keeping it alive
This document changes when the design decisions change — not after every screenshot, and never as a frozen moodboard. It needs enough detail to constrain an implementation and it has to stay short enough for a person to review, which are in tension; the tiebreaker is the reason. If nobody here can explain why a rule exists, it does not belong, and an agent will not honour it either. That is also the deletion test: rules leave this document the same way they arrive.
Three documents, three jobs, and they should not absorb each other. This is the visual contract. SKILL.md explains how to work in the repository — build steps, traps, conventions. Product requirements say what has to exist. When this file starts explaining how to run the dev server, it has stopped being a design system.
Part II · This repository
The code mapping: where the visual contract binds to real files. Build workflow, agent traps and repository conventions belong in SKILL.md, not here.
Branch proposal/optical-canon of chipoto69/metanomicon.
├── src/ the shipped surface
│ ├── App.tsx fixed layers over a 500vh scroll container
│ ├── components/ ScrollField · MoshScrub · VesselPlates ·
│ │ ScrollFloat · GlassPanel · PillNav
│ ├── canon/ gl.js · dither.js · chroma.js · sigil.js
│ └── index.css Tailwind v4 @theme (token mirror)
├── public/ tokens.css (canonical) · fonts/ · vessels/ ·
│ lib/ · preview/ (the living component docs)
├── brandkit/ Claude Design canvas sources
├── artifact/ design-system.src.html + build.mjs (fonts inlined)
│ ├── strata/ cloth-hero · onebit-3d · ephemeris — each with evidence.md
│ ├── strata2/ tide-moon · mark-weather · phase-disc · address ·
│ │ kingwen-dither · almanac · figure-played — each with evidence.md
│ ├── compare2/ the seed-identity review page source + plates
│ └── workflows/ banked squad scripts, resumable
├── scripts/ site-pages.mjs (generates /canon/ and /review/ into public/,
│ runs as prebuild) · verify-pages.mjs (checks dist/ or a live URL)
└── VOICE.md · REGISTRY.md · SKILL.md · HANDOFF.md · DESIGN.md
The site ships six routes: / (the scroll surface), /matra/ (the manifesto as a constellation, §0 and §9), /canon/ (this document rendered in the canon — the same file the Claude artifact publishes), /review/ (the before/after review with its evidence statuses), /doctrine/ (this file, rendered) and /explore/ (every stratum's evidence and adversarial reviews, the living pieces, the research briefs, the notes, the ideas). All of it is generated at build time from artifact/ and this file by scripts/site-pages.mjs, never committed. /matra/ is also copied into the holding repository as site/matra/index.html, which is how it reaches metanomicon.org. The agent skill lives at .claude/skills/metanomicon-design/.
-
Tokens live twice:
public/tokens.css(canonical — substrates, ladder,--ns-*contract) and the@themeinsrc/index.css(Tailwind v4 mirror; notailwind.config.*exists or should). When they disagree, fix the mirror. - Stack: React 19 + Vite 7 + Tailwind v4 + GSAP 3 (ScrollTrigger/ScrollToPlugin only). No router, no state library, no component kit, no other animation library.
-
React/GSAP pattern: all GSAP work inside
useLayoutEffectin agsap.context(...)withctx.revert()— StrictMode double-mounts. -
Rule: build on
src/canon/, never reimplement — a dither or split effect that bypasses the lib is drift; extend the lib. -
public/preview/*.htmlare the living component docs. There is no Storybook; a new technique gets a preview piece first. - The scroll map is the feature organization (page progress 0–1): hero flies 0→0.25 · signal band 0.16–0.66, readable at 0.41 · vessel plates 0.60–0.88 · panel 0.875→1. New beats claim a window and clear it.
-
Deploys: Vercel
metanomicon-optical-canon, auto on push to this branch;npm run buildrunsscripts/site-pages.mjsfirst, andnpm run verify:pages [url]checks the build or the live deploy. -
Known traps (full list in
SKILL.md): canvas bitmap must match its CSS box;inset:0does not stretch a canvas; naive large-int hashing biases noise thresholds; pixel-sorting text needs a directional smear to streak.
Appended 2026-10-03. import { mountField } from '/lib/gl.js' and mountField(canvas, { off: MN_derive(date).off }) draws the shipped field: measured equal, by pixel hash, to artifact/field.glsl mounted whole at two dates and two canvas sizes (artifact/strata4/field-lib/probe.json). The seed still comes from MN_derive, which is not yet in the library.
Part III · Integration appendix
From Figma (MCP). Map every fill/stroke to a Part I token or reject it. Replace foreign fonts with the two faces; icons per §7; photos through the dither gate; rounded corners become square + border. A Figma background is a reference for field parameters, not an asset — backgrounds ship procedural. Copy is rewritten into the voice.
From a Claude Design canvas. Canvases are mockups; the contract board (settled ratios) is the implementation spec. Backgrounds on canvases should be captures from the real algorithm, marked with seed and parameters so implementation reproduces them live. Artboards embed both faces as data: URIs.
Claude artifacts in this brand. The worked example is artifact/design-system.src.html — this document rendered as a brand surface in the brand (node artifact/build.mjs), live at https://claude.ai/code/artifact/b4a8d70e-83f2-42e9-8493-1a63de644844. Commit to the void substrate as a single deliberate theme: paint body background #050505 and every colour explicitly (no prefers-color-scheme dependence), and set color-scheme: dark so UA chrome follows. Bundle Departure as a data: URI; Geist may use Google Fonts where the host admits only that. Respect the icon and colour law exactly — an artifact is a brand surface, not an exception. Interactive pieces keep the seed discipline: same seed, same output.
Documents, decks, print. Paper substrate is first-class: ink #0b0b0c on #f2f0e9, essence goes deep teal #056a75. Plates are fixed single pages; flowing documents paginate. 12pt body floor for print; the dither gate still governs imagery.
Code from any agent. Read SKILL.md first; obey the scroll map, the stacking map, and the frame budget; ship the reduced-motion state; verify in a real browser before handover (two frames apart to prove motion; zero console errors).