Design language Overview
Zerone Design Language
One language for this website and the Zero Door interface. Every rule says what enforces it: a test or gate that fails the pipeline when the rule breaks, or a plain label saying it is kept by review. Values are read from the code; the product's arrive through a snapshot taken from its source.
One language, two registers.
#The website speaks in an assertive register: New Black type, warm paper, one copper-green accent that means a verified signal, hairline structure and motion that explains. The Zero Door interface speaks in a calm one: a light and a dark theme, colour kept for status outside charts, short functional motion and density for data. Underneath, the language is one.
The same state, said twice.
One idea is drawn in both registers below: a change that passed its checks. The left panel is built from the website's own tokens and type. The right panel is painted with the Zero Door dark theme, the product's default, using values from the product snapshot. As in the product's Badge, each row states its status with an icon and a word; the total uses a dot and a word, a pattern in use in the product.
WebsiteAssertive
One change, checked
Verified.
Signature, publisher and package manifest agree. One verdict, kept as evidence.
- signaturematch
- publishermatch
- package manifestmatch
Website tokens in this panel
--color-paper--color-hair--color-ink--color-ink-muted--color-ink-subtle--color-accent--color-accent-deep
Zero Door interfaceCalm
| Change | Status |
|---|---|
| Package updatesignature · publisher · package manifest | Verified |
| Signed binarysignature · publisher · package manifest | Verified |
Zero Door dark theme tokens in this panel
--surface--surface-subtle--fg--fg-muted--zd-border--signal-success
What the two share.
Each row is computed while this page is built. Website values come from the token file and the stylesheet. Product values come from the product snapshot: its tokens, and facts a sync script reads from the product's source files. ‘Identical’ means the same value on both sides; ‘Close’, used for one colour, means the two differ by less than 0.05 in OKLab.
| Aspect | Relationship | Value |
|---|---|---|
| Glyph | Identical | Path of 311 characters, viewBox 0 0 101.6 134.69 |
| Ease-out curve | Identical | cubic-bezier(0.23, 1, 0.32, 1) |
| Medium radius | Identical | 8px |
| Press scale | Identical | scale(0.97) |
| Reduced-motion transition duration | Identical | 0.01ms |
| Neutral colours | Partly identical | Website6 of 11 colour tokensZero Door6 of 15 interface colour tokens |
| Ink | Close | Website#0f1c26, --color-inkZero Door#15242c, --brand in the light themeDifference in OKLab: 0.031 |
The website sets its text in ink, #0f1c26. In its light theme the product keeps a near copy of that ink, #15242c, for its primary actions, and sets its text in a warmer near-black, #221d19.
Six values, each with two names.
The website's paper, hairline and secondary text colours are not merely close to the product's light theme. They are the same values under different names. Each chip below is painted half by the website token and half by the product value; where the values match, the halves meet without a seam. The short marks at the top and bottom show where they meet.
--color-paper=--surfaceWebsite#fdfaf6Zero Dooroklch(0.985 0.006 75)--color-paper-2=--surface-subtleWebsite#f6f3eeZero Dooroklch(0.965 0.007 75)--color-hair=--zd-borderWebsite#e2dfdbZero Dooroklch(0.905 0.006 75)--color-hair-2=--zd-border-strongWebsite#cdcac6Zero Dooroklch(0.840 0.006 75)--color-ink-muted=--fg-mutedWebsite#5c5753Zero Dooroklch(0.460 0.010 60)--color-ink-subtle=--fg-subtleWebsite#736d69Zero Dooroklch(0.540 0.010 60)
Where they differ.
The differences are what make two registers rather than one. They are computed the same way.
| Aspect | Website | Zero Door interface |
|---|---|---|
| Register | Assertive | Calm |
| Typeface | New Black, with Geist Mono for machine text | Inter, with Geist Mono for machine text |
| Accent | One, #00847e, for a verified signal | None; 4 signal colours carry status and the brand tone marks primary actions |
| Text colour | Ink, #0f1c26 | --fg, #221d19, in the light theme |
| Theme | Light only | Dark by default, with a light theme |
| Small radius | 6px | 4px, plus a large 12px |
| Pure white | No pure white token; tests fail on a pure white hex value | Raised light surface, oklch(1 0 0), #ffffff; the label on filled buttons is white too |
| Duration tokens | 7 for scripted motion, from 160ms to 1800ms; CSS transitions write their own | 5, from 130ms to 400ms |
| Spacing scale | None | 12 steps, from 2px to 64px |
| Shadow tokens | 1 | 2 per theme |
One rule both keep.
Neither register lets colour carry meaning on its own. On the website, links in running text are underlined in use, not only coloured. In the product, the Badge component pairs each signal colour with an icon and a word.
Website
Read the evidence for each change.
Zero Door
Website
Read the evidence for each change.
Zero Door
Colour never carries meaning on its own, in either register.
WhyA reader who cannot tell the colours apart still has to get the meaning. Part of this is checked: axe flags a link in running text that differs from its text only by a colour too close to it. The rest, including every product screen, is held by review.
ReviewKept by review, not by a test.
Four rules underneath.
#The design language serves four rules the company holds itself to. They are quoted below exactly as the home page states them; each is a refusal or a promise that can be checked. Beside each is one decision it forces in the design. The principles page follows every rule further.
Nothing is trusted for having been there yesterday.
The first scan weighs every binary, library and package already on the host against the original. A baseline records what is there; it does not bless it.
In the designContent is visible before any script runs, apart from the second block of the home hero (see Motion). A reveal only moves what is already there: its starting pose is written under
html.motion, a class a script adds.Evidence checks out without us.
Evidence leaves as a signed bundle with its own verifier. It checks offline, with no account and no call to our servers.
In the designA rule says whether a test enforces it or review keeps it. A contrast ratio is cut to two decimals, never rounded up.
Change is a question, not an alert.
Every change is weighed first: is it the original, which package shipped it, which process wrote it, was it inside a change window. A Windows update folds into one alert per server.
In the designOne accent, and it means a verified signal. Raw, unverified change has a colour of its own, so it never borrows the accent.
Every detection runs behind your air gap.
The self-hosted build is the same product: an offline signed licence, signed updates you carry in, a local copy of the legitimacy database. What needs a route out is named and off: reputation lookups and trusted timestamping.
In the designType is self-hosted on both sides: the site ships its own font files and the product loads Inter and Geist Mono from local files.
What each page covers.
#The language continues on 13 more pages, grouped as in the navigation. Each one states its rules together with what enforces them.
Overview
- Principles
Why the language looks as it does: the four rules, the design decisions each one forces and the two registers.
Foundations
- Colour
Choosing and checking colour: the palette read from the token file, what each colour means and computed contrast.
- Typography
Setting text in two typefaces: the weights and scale in use, mono for machine text and two languages side by side.
- Layout and shape
Building a page from the container down: section rhythm, hairlines and tones, radius and elevation, reflow to 320 pixels.
- Motion
Moving only to explain: the durations and curves in use, reveals without opacity, scroll scenes, the pause control and reduced motion.
- Logo and name
Using the logo and the name: the designer’s system, the lockup in use, naming, downloads and the rules Zerone added.
- Mascot
The mascot of the Zero Door page: who he is, what his scene stands for, how he is drawn and moves and where he may appear.
- Diagrams and icons
Drawing a signature visual: what colour means in a diagram, labels, text alternatives and icons.
- Visualisation
Drawing a figure that explains one mechanism: the dam of the Zero Door page, the evidence spine, ring marks and the loop from noise to signal, all built from the glyph.
Content
- Writing and claims
Writing as the site does: voice, claim discipline, numbers and naming, and the content rules a test enforces.
Accessibility
- Accessibility
What WCAG 2.2 AA means here: what is tested and how, focus, motion, the page without JavaScript and known gaps.
Product
- Zero Door interface
The calm register in the Zero Door interface: themes, severity, type, density, shape and motion.
Resources
- Resources
Taking the language with you: downloads, the token files, the checks that hold the language and a dated change history.
How it stays true.
#A design language drifts when its documentation and its code live apart. Here they do not: the pages read their values from the code as the site is built, and the rules they state run as tests and gates on every change.
Values are read from their source.
The values on this page come from these 8 sources while the site is built. Every product value arrives through one of them: a snapshot that a sync script reads from the product source.
Where the values on this page come from
- Site token file
- 11 colours, two type stacks, the curve, two radii and the shadow of the website.Download
tokens.css - The glyph
- The glyph path and its viewBox, drawn by every glyph component on the site and in its share images. The favicon and the press downloads carry copies, which a test compares with it.
- Zero Door token snapshot
- The Zero Door interface colours in both themes (the chart ramp is left out), spacing, radii, shadows, curves and durations, and facts read from named product files. This page uses the glyph digest, the press scale, the reduced-motion duration, the two typefaces, the default theme, the Badge tint, border, size and icon, and two text sizes. A sync script writes the file from the product repository and it is committed here. The download leaves out one internal field, the repository name.Download
product-tokens.json - Site stylesheet
- The press scale of the button and the reduced-motion transition duration of the website.
- Motion durations
- The named durations every scripted motion on the website takes, counted in the duration row of the differences.
- Comparisons
- The comparisons drawn from those values: which colours share a hex value, the OKLab difference between two colours, the ranges of the product scales and the Badge tint laid over its surface.
- Colour maths
- Contrast ratios floored to two decimals and hex values converted from OKLCH.
- Change dates
- The ‘Last changed’ date at the foot of each page, taken from the last commit that touched its sources.
Contrast is computed.
These are the text colours of the specimen above, measured against their surfaces with the WCAG 2 formula while this page was built. Ratios are floored to two decimals, so a pair at 4.499:1 reads 4.49:1 and never appears to pass a threshold it misses.
| Text | Ratio | Grade |
|---|---|---|
| --color-ink | 16.61:1 | AAA |
| --color-ink-muted | 6.85:1 | AA |
| --color-ink-subtle | 4.89:1 | AA |
| --color-accent-deep | 6.65:1 | AA |
| Text | Ratio | Grade | Surface |
|---|---|---|---|
| --fg | 15.01:1 | AAA | --surface |
| --fg-muted | 6.05:1 | AA | --surface |
| --fg-muted | 5.60:1 | AA | --surface-subtle |
| --signal-success | 6.26:1 | AA | --surface |
| --signal-success | 5.50:1 | AA | its tint on --surface |
Rules say what holds them.
A rule on these pages is either enforced by a test that runs on every change or says plainly that review keeps it. These are the tests and gates the language leans on most.
Every website colour token keeps its value. Changing one is a decision made in a test, not a side effect.
WhyThe palette is small on purpose. A value that drifts quietly changes every page that uses it.
TestEnforced by a test on every change.
No pure black or white hex value in the token file.
WhyThe surfaces are warm paper and the text is a blue-black ink. Pure values would fall outside that palette.
TestEnforced by a test on every change.
No pure black or white, in any colour notation, in the stylesheets the build ships.
WhyA pure value could still reach a page through a component's own CSS. The gate reads every shipped stylesheet and every style block inside a page, catches the keywords as well as hex values and colour functions, and sets aside only one framework default, Tailwind's ring-offset colour, in the two places it is declared.
TestEnforced by a test on every change.
The website text tokens
ink,ink-muted,ink-subtleandaccent-deepreach 4.5:1 on both paper tones.WhyText tokens are used at body sizes, where WCAG asks for 4.5:1.
TestEnforced by a test on every change.
A ratio on these pages is floored, never rounded up.
WhyA pair at 4.499:1 must not read as a pass.
TestEnforced by a test on every change.
Zero Door text and status colours reach 4.5:1 on all three surfaces, in both themes.
WhyThe product is described from its snapshot. The test keeps what these pages say and the values they describe together.
TestEnforced by a test on every change.
The website side of each shared value (the glyph, the curve, the medium radius, the press scale and the reduced-motion transition duration) matches the product value in the snapshot.
WhyThe comparison above is computed, but the sentences around it are written. The test sees the product only through the snapshot, so a product change is caught when the snapshot is next synced, not before.
TestEnforced by a test on every change.
Every built page, the 404 page included, passes axe-core with the WCAG 2.2 AA tag set and no violations.
WhyA new page enters the check by being built. Nobody has to remember to add it.
TestEnforced by a test on every change.
No built page, the 404 page included, scrolls sideways at 320 CSS pixels.
WhyWCAG 1.4.10: a reader zoomed to 400 percent should not have to scroll in two directions.
TestEnforced by a test on every change.
The English and Turkish texts of a page have the same keys, fields and list lengths, and neither carries the em dash, the product name written as one word (machine names such as a domain aside) or a percentage other than 99.5.
WhyBoth languages keep the same structure, and house rules do not depend on a reviewer noticing.
TestEnforced by a test on every change.
Every internal link and every anchor resolves.
WhyA broken link in a reference sends the reader to a rule that is not there.
TestEnforced by a test on every change.
A guard for pause controls
WCAG 2.2.2 asks for a way to pause anything that moves on its own for longer than five seconds. A browser cannot tell a short intro from a loop, so each loop marks itself and the accessibility test checks that a pause control is visible on the page. The shared motion helper marks every loop it starts. The few loops written outside it, such as the canvas noise fields, the home page hero's scroll cue and the hold loops of two scroll scenes, set the same mark themselves. A build check counts the loops each component file starts (an endless timeline, an endless CSS animation or a noise canvas) against the marks it sets and stops the build when loops outnumber marks. A loop started any other way is still held by review.
The loop marks itself.
When a visual finishes its intro and starts an idle loop through the shared motion helper, the helper sets
data-ambient="on"on it. A loop outside the helper sets the same attribute itself.[data-ambient="on"]The test finds it.
The accessibility test scrolls each page through, lets its visuals play, then counts the elements marked this way.
locator('[data-ambient="on"]').count()A visible control is required.
If a loop is running, a pause control must be visible on the page or the test fails. One control pauses every loop on the site, and the choice is remembered from page to page.
[data-motion-toggle]:visible
Under reduced motion no loop starts, and the control stays hidden because there is nothing to pause. This page runs no loop.
A page that runs a marked loop shows a visible pause control.
WhyWCAG 2.2.2 Pause, Stop, Hide. An automated scan cannot judge it, so the test that runs axe on each built page makes this check after the scan. That is why this card and the axe card are held by the same test.
TestEnforced by a test on every change.
What it does not cover yet.
#These topics have no definition in the code or in a design document. They are listed so that an absence is not mistaken for a rule. Where the website already does something, the page that covers it describes it as in use, not as a standard.
Not defined Topics the language does not define
A website column grid
Pages sit in one centred container and divide it section by section. There are no column counts and no gutter tokens.
A website spacing scale
Components set their own spacing. The product has a spacing scale; the website does not use it.
Duration tokens in the website's CSS
Scripted motion takes its durations and curves from one module. CSS transitions still write each duration in their own component, and the product's duration tokens are not used here.
A dark website theme
The website is light only. The dark theme belongs to the Zero Door interface.
Photography
There is no guidance for photographs.
Pictograms
There is no pictogram set. Icons and diagrams are drawn from simple shapes and the diagrams page covers them; figures that explain a mechanism are on the visualisation page.