Design languageDiagrams and icons

Design language Foundations

Diagrams and icons

Every diagram on this site is drawn by hand from SVG primitives and plain HTML, with no icon set or illustration library behind it. All 21 visuals in production share one small vocabulary of rows, wires, chips, frames and tags, so a reader who has learnt one can read the next.

One language, drawn by hand.

#

The signature visuals are built from a handful of primitives: rounded rows, hairline wires, chips, ticks, seals and small ink tags. No icon set and no illustration library is installed. Each visual is one component, and most keep their numbers in a pure module that a unit test reads.

  • Card

    One file, by its real name and its operating system.

    DamFigure

    .w font-size clamp(9px, 2.8125cqw, 11.5px)

  • Original

    The legitimate original of the same file, sealed with a tick.

    DamFigure

    .mark circle stroke accent-deep · stroke-width 0.7

  • Wire

    A connection before a signal travels it.

    FlowDiagram

    .wire stroke hair-2 · stroke-width 1.5

  • Pulse

    The signal on its way.

    FlowDiagram

    .pulse stroke accent · stroke-width 2.5 · stroke-dasharray 6 94

  • Tick

    A verified result.

    CoverageMatrix

    .cell .mk width 26px · background accent-deep · stroke-width 2

  • Seal

    Evidence that is signed.

    EvidenceChain

    .seal .ring stroke accent-deep · stroke-width 2

  • Stopped card

    A file that does not match its original: raw outline, empty raw ring.

    DamFigure

    .ring stroke raw · stroke-width 0.7

  • Verdict tag

    The decision in words, under the cards it names.

    DamFigure

    .v background ink · color paper

  • Chain

    Records linked in order.

    EvidenceChain

    .link stroke ink · stroke-width 2

  • writable + executable

    Tag

    A finding, named in words.

    MemoryMap

    .tag background ink · font-size 11px · padding 8px 10px

The vocabulary at true size, drawn with the values each source visual declares. The card, the original, the stopped card and the verdict tag are drawn at the size the dam has on the Zero Door page on a 1440 px screen. Under each primitive: the visual it comes from and the rule it is read from.

The visuals in production

The public pages carry 21 visuals that hold information. Of these, 10 are a single scaled SVG drawing and 11 are laid out in HTML and CSS, with a small inline SVG wherever a line or a tick is needed. A pure geometry module holds the numbers of 16, and 20 run a quiet loop once they have played.

Signature visuals, read from their source files
VisualFrameDrawn inGeometry modulePage
ResultsScene stageSVGyesHome
DamFigureUnframedSVGyesZero Door
LegitCompareFloating cardsHTML and CSSyesZero Door
DayOneTimelineUnframedHTML and CSSyesZero Door
DecisionSceneScene stageSVGyesZero Door
CoverageMatrixShared frameHTML and CSSnoneZero Door
UpdateCollapseShared frameSVGyesZero Door
EventTreeShared frameHTML and CSSyesZero Door
FleetSearchShared frameSVGyesZero Door
MemoryMapShared frameSVGyesZero Door
EvidenceChainShared frameSVGyesZero Door
FrameworkFanShared frameHTML and CSSnoneZero Door
AttackPathUnframedSVGyesServices
FindingsReportShared frameHTML and CSSyesServices
AttackNarrativeShared frameHTML and CSSyesServices
LabSessionShared frameHTML and CSSnoneServices
ControlMapShared frameHTML and CSSyesServices
ResidencyMapShared frameHTML and CSSnoneTrust
HexScanInk panelHTML and CSSyesResearch
FlowDiagramShared frame, paddedSVGnoneArchitecture
SignalLoopShared frameSVGyesVisualisation

Line weights in use

The SVG drawings declare their line weights in CSS, in drawing units, so a line scales with its drawing. Nothing defines this set: the table reads what the 10 SVG drawings use today from their styles, icons left out.

Stroke widths in the SVG drawings, read from their CSS
WidthDrawingsColours
0.45 unitsDamFigurehair-2, ink
0.5 unitsDamFigurehair-2
0.6 unitsDamFigurehair-2
0.7 unitsDamFigureaccent-deep, ink, ink-subtle, raw
0.75 unitsDamFigureaccent-deep
0.8 unitsDamFigureaccent-deep
1 unitDamFigure, FleetSearch, MemoryMap, FlowDiagram, SignalLoophair-2, ink
1.2 unitsAttackPathhair-2
1.5 unitsResults, DecisionScene, EvidenceChain, AttackPath, FlowDiagram, SignalLoopaccent, hair-2, ink, raw
2 unitsResults, DecisionScene, MemoryMap, EvidenceChain, AttackPath, SignalLoopaccent, accent-deep, hair-2, ink, paper, raw
2.5 unitsDecisionScene, AttackPath, FlowDiagramaccent, ink-subtle, raw
3 unitsDecisionScene, EvidenceChainaccent-deep, paper
5 unitsDecisionScenepaper
8 unitsResultsink
  • The website installs no icon or illustration library: neither the site nor its UI package depends on one. Every diagram is inline SVG or HTML in the site's own code, almost always in the component that shows it.

    WhyNothing is fetched from elsewhere, which the content security policy would refuse anyway, and a drawing made for one point carries only that point.

    TestEnforced by a test on every change.

  • Pseudo-random layouts are seeded: no signature visual and no module it imports calls Math.random, so the server and the browser draw the same scene on every build.

    WhyThe drawing a reader sees without JavaScript must be the one that animates. The one exception on the site is the noise field behind the home hero, a decorative canvas that is not a signature visual.

    TestEnforced by a test on every change.

  • Where a visual computes positions, they live in a pure module without DOM or animation code, which the server render and a unit test read, and the browser script too where it animates them.

    WhyPositions are then tested like any other code: rows do not overlap, a tag sits in its own lane, a chain fits its stage.

    ReviewKept by review, not by a test.

  • Numbers inside a visual are never invented. A measured figure comes from the dictionary that publishes it; hashes, paths and addresses are representative.

    WhyA diagram is part of the claim. The update visual counts up to the same figure the proof strip publishes, read from the same entry.

    ReviewKept by review, not by a test.

Adding a visual

The rules on this page, in the order you meet them when you draw something new. Where a test checks part of a step, the step says so.

  1. Write one component. Its figure is role="img" with a label from the page dictionary, in English and Turkish.Text alternativesChecked by a test
  2. Add it to the inventory of visuals that this page reads. Until every role="img" component in production is listed there, a test fails.One languageChecked by a test
  3. Put computed positions in a pure module, never Math.random, and test them: rows clear of each other, tags in their own lane.One languageChecked by a test
  4. Use the shared frame, .fv, and copy its declaration exactly, unless the visual is a scene or sits directly on the page.The frameChecked by a test
  5. Colour by meaning: accent for the verified signal, raw for unverified change, ink for structure, and never colour alone.What colour means
  6. Make text that must be read on a phone HTML over the drawing, or give it a larger size below the breakpoint.Labels
  7. Animate through revealMotion with transform, clip-path and stroke-dashoffset, never opacity, and take every duration and curve from the motion vocabulary. End the intro on the result and let any loop run over it. Give reduced motion and no JavaScript a final state, and put a pause control beside any loop.MotionChecked by a test

What colour means.

#

Inside a visual, colour is a claim. Accent is the verified signal; raw is unverified change, noise or the attacker; ink is structure and decision. Everything else is paper and hairline.

Colour roles in use inside visuals
TokenMeansUsed for
accentThe verified signal, mostly while it movesScan lines, pulses, signal curves, progress bars, answer rings, traces
accent-deepA verified result at restTicks, seals, matched cells, arrowheads, kind labels
accent-tintGround for verified thingsKind chips, scan bands, halos
rawUnverified change, noise, the attackerFlagged rows, falling curves, attack paths, failed evidence, critical findings
inkStructure and decisionThresholds, chain links, block outlines, decision tags
hair-2Structure not yet litWires, empty cells, outlines of rows and chips

Only accent and raw have a meaning stated in the token file. The other rows describe how the visuals use their tokens today, and there are exceptions: the host dots in the architecture diagram are accent at rest, and the home scene sets small labels in accent-tint on an accent-deep pill. Download the token file (CSS)

  • Suspicious

    Decision tag

    DamFigure

    16.61:1 paper on ink

  • Suspicious

    Bad verdict

    LegitCompare

    5.72:1 paper on raw

  • Stopped card

    DamFigure

    5.72:1 raw on paper

  • file

    Kind chip

    EventTree

    6.04:1 accent-deep on accent-tint

  • Verified tick

    CoverageMatrix

    6.65:1 paper on accent-deep

Chips and marks as the visuals draw them, in the real tokens. Each ratio is computed from the token values.
DoNoise in raw, signal in accent: the falling curve of unverified change and the rising signal read as two different things.
Do notBoth in one dark colour: the scene turns into a one-colour chart and the point is lost.

Evidence fills the verdict.

The decision scene on the Zero Door page draws one case, and the evidence draws its verdict. The pill is born as an empty ink-subtle outline. Each of the 3 failed checks lands on it and fills one more equal part from the left in raw; each of the 3 neutral checks draws a notch in ink-subtle on its top edge and fills nothing. Only a full pill gets its word, Suspicious, wiped open from left to right in paper. The scene never shows a colour or a word that the evidence has not yet earned.

  • Born

    0/3 failed · 0/3 neutral

    • outline ink-subtle
  • One check left

    2/3 failed · 3/3 neutral

    • fill raw
    • notches ink-subtle
    • outline ink-subtle
  • Decided

    3/3 failed · 3/3 neutral

    • word paper on raw
    • outline raw
The pill as DecisionScene draws it, at three moments, with the scene's geometry, line weights and tokens.

Elsewhere the same idea takes a simpler form. A chip whose only job is to carry a bad verdict is filled raw, as in the legitimacy comparison and the event tree. A tag that explains a spot the drawing has already marked stays ink: the dam turns the outline and the ring of each stopped card raw, and the ink tag under the bank says why.

Colour is never alone.

accent and raw differ mostly in hue. Measured as contrast they are only 1.30:1 apart, so no scene relies on that difference. The cards that do not match stand on the bank while the others pass through the door, an original carries a tick in its ring where a stopped card carries an empty one, the attacker has a route and stage names of its own, failed evidence carries a cross and a word names every verdict.

  • accent marks the verified signal and raw marks unverified change, noise or the attacker.

    WhyIf noise had no colour of its own, signal and noise would both be dark and the scene would read as a one-colour chart. The token file gives this as the reason raw exists.

    ReviewKept by review, not by a test.

  • raw is a muted brick, not an alarm red, and it stays readable: as text on paper and as a ground for paper text.

    WhyFlagged paths, verdict chips and critical findings put words in raw or on raw. The token file states the ratio and a test holds it.

    TestEnforced by a test on every change.

  • Colour never carries a meaning alone: position, shape or a word says the same thing.

    Whyaccent and raw are close in lightness. A reader with a colour vision deficiency, or a page printed in grey, still has the route, the cross and the word.

    ReviewKept by review, not by a test.

One frame for feature visuals.

#

A visual that explains a feature sits in the same frame wherever it appears: a hairline border, the medium radius and the second paper tone. Rows and chips inside it are raised on paper, and only objects that float over the drawing cast a shadow.

The frame, .fv, declared identically in 13 components
PropertyValue
positionrelative
margin0
widththe full width of its column
border1px solid var(--color-hair)
border-radiusvar(--radius-md)
backgroundvar(--color-paper-2)
overflowhidden
  1. Frame: hairline border, medium radius, second paper tone.
  2. Head label: Geist Mono, uppercase, subtle ink.
  3. Rows and chips: paper, raised on the frame, outlined in the stronger hairline.
  4. Decision tag: ink with paper text, laid flat over the drawing.
A frame built from the declaration above, with what usually sits inside it.

Where the frame is left off.

With no frame at all, DamFigure, DayOneTimeline and AttackPath sit directly on the page. The two scroll scenes use a full paper-2 stage with a dotted backdrop instead (Results and DecisionScene). The research hex dump is an ink panel (HexScan) and the legitimacy comparison is a pair of floating cards (LegitCompare). The architecture diagram keeps the frame and adds padding, because its drawing scrolls inside it on narrow screens (FlowDiagram).

  • Feature visuals use the shared frame, .fv, with the same values in every component that declares it.

    WhyOne frame makes different drawings read as one family. Each component declares it on its own, so a test keeps the copies identical.

    TestEnforced by a test on every change.

  • Only floating objects cast a shadow: stamps, the search bar and cards laid over a drawing. The frame itself never does, and neither does a decision tag.

    WhyA shadow says ‘above the drawing’. On the frame it would turn every section into a pile of cards.

    ReviewKept by review, not by a test.

Labels and legibility

#

Machine text inside a visual is set in Geist Mono: paths, hashes, addresses, kinds, counts and the small tags that annotate a scene. Titles inside a drawing, such as the platform name in the architecture diagram or a verdict pill, are set in New Black. Text that must stay readable on a phone should not shrink with the drawing below a readable size; the table below shows where that holds and where it does not yet.

Two ways to stay legible.

A drawing scales with its column, and SVG text scales with it. On a 320 px screen the page column is 264 px wide, so the evidence chain, 560 units across, renders its 12-unit hashes at 5.61 px. The site has two answers. Text that carries the point, such as a verdict tag or a timestamp stamp, is HTML: laid over the SVG or set with no SVG at all, and a tag that must sit at a spot in the drawing is placed in percentages of the figure. Its size is set in CSS, not in drawing units: the stamp on the evidence chain stays at 11.5 px, and the verdict tag of the dam on the Zero Door page takes its size from the width of the drawing, never below 9 px and never above 11.5 px; on a 320 px screen it stays at 9 px. The file names and operating systems on the cards of the dam are HTML too and follow the drawing the same way. Text that stays inside the SVG can instead get a larger font size below the breakpoint.

DoThe tag is HTML over the drawing and keeps its pixel size; the file path stays in the SVG and takes a larger size below the breakpoint.
Do notThe same words inside the SVG, at one size, shrink with the drawing.

Label sizes in use

Label sizes, read from the components
VisualWideNarrowBelowAt 320 pxHowSelector
AttackPath12.5 units15 units900px7.07 pxSVG text, grows.lbl
AttackPath11 units15 units900px7.07 pxSVG text, grows.zone text
FlowDiagram10.5 units12 units760px9.79 pxSVG text, grows.m
FlowDiagram14 units16 units760px13.05 pxSVG text, grows.t
EvidenceChain12 units12 unitsnone5.61 pxSVG text, scales.blk .hex
EvidenceChain10 units10 unitsnone4.68 pxSVG text, scales.blk .idx
EvidenceChain9 units9 unitsnone4.21 pxSVG text, scales.seal .alg
MemoryMap9.5 units9.5 unitsnone4.44 pxSVG text, scales.addr
MemoryMap10 units10 unitsnone4.68 pxSVG text, scales.perm
DamFigurescales with the drawing, up to 11.5 px9 pxnone9 pxHTML overlay, sized to the drawing.tag
DamFigurescales with the drawing, up to 11.5 px9 pxnone9 pxHTML overlay, sized to the drawing.w
DamFigurescales with the drawing, up to 10 px9 pxnone9 pxHTML overlay, sized to the drawing.os
DamFigurescales with the drawing, up to 11.5 px9 pxnone9 pxHTML overlay, sized to the drawing.chip
MemoryMap11 px11 pxnone11 pxHTML overlay.tag
EvidenceChain11.5 px11.5 pxnone11.5 pxHTML overlay.stamp

Not everywhere yet. In EvidenceChain and MemoryMap, some machine text stays inside the SVG at one size, so on a 320 px screen it renders between 4.21 and 5.61 px. Growing is not always enough either: text that grows renders between 7.07 and 13.05 px there, depending on how many units wide its drawing is. The smallest is in AttackPath, which is 560 units across.

The architecture diagram also keeps a minimum width of 620 px below 760 px and scrolls inside its frame, so its smallest labels never render below 9.79 px.

The two scroll scenes are not in the table: at 600 px and below they take a third route, because each step needs a different part of the picture. The decision scene frames each step with its own camera, so the region the step talks about fills the picture instead of the whole scene shrinking. The home evidence scene sets its cards in HTML and hides the labels that would fall under 11 px; what they name is already in the card and in the scene's description. A test measures every visible text in both scenes, at every step, on phones 375, 390 and 412 px wide; a 320 px screen is not in that test.

  • In the home evidence scene the mono labels grow on small screens, and the layout that keeps them clear of each other is measured at that larger size.

    WhyIf the CSS size and the layout constant drifted apart, the overlap test would check a box nobody sees.

    TestEnforced by a test on every change.

  • In the first scene of the home evidence section, a label is written away from the mark it names: above and to the right in the upper half of the scene, below and to the left in the lower half.

    WhyThe label never sits on the curve it explains. The test allows one measured exception, where the gap between the two curves is too narrow.

    TestEnforced by a test on every change.

  • A tag gets a place of its own: the verdict tag of the dam sits under the bank, right of the door, where no card passes.

    WhyAn overlay that covered a card would hide the very thing it names.

    TestEnforced by a test on every change.

  • The verdict tag on the Zero Door page never runs over a card, the door or the edge of the drawing, at any width.

    WhyThat is why its size follows the drawing. The test measures the tag against every card, the door and the frame at three window widths and on a phone, in both languages.

    TestEnforced by a test on every change.

  • On a phone, every visible text in the two scroll scenes stays above the readable floor, at every step, with the step card and the picture on screen together.

    WhyThe test sets the floor named above. It opens both scenes at three phone sizes, in English, in Turkish and with reduced motion, and measures every visible label and card at every step.

    TestEnforced by a test on every change.

One direction, from source to verdict.

#

A flow runs one way, usually left to right: the source on the left, the verdict or the destination on the right. The exceptions follow the meaning: the dam takes its files in from the top right, down the stream, looking back in time scans backwards, an event tree grows from the top, and in the residency map an air-gapped packet stops at a wall and backs off, because it may not leave.

  • Source to verdict

    Left to right. Most visuals.

  • Back in time

    Right to left, from the install to what was already there. DayOneTimeline.

  • A tree grows down

    Top to bottom, parent before child. EventTree.

Three of the directions in use, drawn with the site tokens.
Flows in the signature visuals
VisualFromToWay
DamFigureFile cards from the streamThe dam's single door; the cards that do not match stop on the bankDown the stream from the top right, then through the door
DecisionSceneThe digest card and its evidenceOne verdict, then the signed chainLeft to right
EvidenceChainRecordsThe seal and the timestampLeft to right
FrameworkFanOne piece of integrity evidence13 frameworksLeft to right
ControlMapEvidenceFramework controlsLeft to right
FlowDiagramHostsThe platformLeft to right, outbound only
ResidencyMapYour fleetThe hosted serviceLeft to right
AttackPathThe internetThe target, then out againBottom left to top right, through nested zones
DayOneTimelineThe installA change made before itRight to left
EventTreeThe user who logged inThe files a process changedTop to bottom
  • In the architecture diagram nothing travels in reverse: every wire leaves a host and ends at the platform, and every pulse moves forward along it.

    WhyThe diagram exists to say that the agent opens the connection outwards. A pulse coming back would say the opposite.

    TestEnforced by a test on every change.

  • Looking back in time runs right to left: the finding sits before the install on the line.

    WhyThe point of the scene is that the first scan looks at what was already on the host.

    TestEnforced by a test on every change.

  • An event tree grows from the top: every node comes after its parent.

    WhyReading order and causal order are then the same.

    TestEnforced by a test on every change.

  • The attack path goes from outside to the target and back out.

    WhyEach hop lands in the zone its stage belongs to, so the route itself tells the story.

    TestEnforced by a test on every change.

Motion that explains, then rests.

#

A visual plays once when it comes into view and ends on its result. Most then run a quiet loop over the finished picture: the loop never erases the result, rests between passes and stops on the result when it is paused. The attack narrative on the services page has no loop at all. The two scroll scenes are driven by the scroll instead; while a step is held, only a step whose motion says something moves. Lines draw on, marks pop and anything that carries words opens without overshoot; nothing fades. With reduced motion or without JavaScript the same visual shows a readable final state, and every continuous loop has a pause control beside it.

Live: the link draws on, the seal stamps and the tag opens, with the durations and curves the evidence chain uses. It plays once when it comes into view and does not loop.

Lines draw on.

A line that draws itself carries pathLength="1", so its length is 1 at any size. With a dash array of 1, a stroke-dashoffset of 1 means undrawn, 0 means drawn and -1 means the tail has left. Where a sliver could still show at an end, as with a round cap, the dash array is 1 2 and the undrawn offset is 1.02, one shared constant: a browser does not normalise path length exactly, and the wider gap keeps both ends clean. The tween passes autoRound: false; without it the animation library rounds the offset to whole pixels and the line appears in one jump. A pulse uses a pathLength of 100 with a short dash.

The chain links, as EvidenceChain writes them
<line class="link" data-link x1={blocks[i]!.x + CHAIN.w + 3} x2={b.x - 3} y1={cy} y2={cy} pathLength="1"></line>
.link { stroke: var(--color-ink); stroke-width: 2; stroke-dasharray: 1; stroke-dashoffset: 0; }
:global(html.motion) .chain .link { stroke-dashoffset: 1; }
const FINE = { autoRound: false } as const;
if (i > 0) t.to(links[i - 1]!, { ...FINE, ...MOTION.mark, strokeDashoffset: 0 }, at + 0.15);

One lifecycle.

Visuals that play on view share one lifecycle, and the state is written to data-state, where the end-to-end tests read it.

The states of a visual
data-stateWhenWhat shows
staticReduced motionThe final state at once, and no loop
readyThe script has run; not yet in viewThe starting state: lines undrawn, chips at scale zero
playingIn viewThe intro, once
playedThe intro has finishedThe final state. Where there is a loop, it runs over the result without erasing it, and stops off screen, in a hidden tab or at the pause control, with the result in place

Without JavaScript no state is written and the server-rendered final state stays. The starting states apply only after the site's motion script has marked the page, so with no JavaScript, or if that script fails to load, the figure shows its final state.

  • No opacity: entries and exits use transform, clip-path, stroke-dashoffset and SVG attributes.

    WhyPartial opacity lowered measured colour contrast in the middle of a transition. Content is fully visible at every moment.

    TestEnforced by a test on every change.

  • Draw-on tweens pass autoRound: false, so a line advances smoothly instead of appearing at once.

    WhyThe test scrolls through the drawing of a curve and expects many values between drawn and undrawn.

    TestEnforced by a test on every change.

  • With reduced motion every visual shows its final state at once and no loop runs; the scroll scenes jump to the end of each step.

    WhyThe visitor asked for no motion; the picture still has to say everything. The test opens every page with a signature visual.

    TestEnforced by a test on every change.

  • Without JavaScript the server-rendered state is readable and meaningful.

    WhyA visual is part of the argument, not a decoration that waits for a script. The test opens every page with a signature visual without JavaScript.

    TestEnforced by a test on every change.

  • A page that runs a loop shows a visible pause control; one press pauses every loop, and the choice holds on the next page.

    WhyAnything that moves on its own for more than five seconds must be possible to stop. The test presses the control on the home page and expects the next page to open paused. The same file checks every page: once a loop has started, a pause control must be visible.

    TestEnforced by a test on every change.

  • The pause control sits beside the loop it stops.

    WhyA reader finds the control where the motion is. The accessibility check asks only for a visible control somewhere on the page, so this placement is observed and kept by review.

    ReviewKept by review, not by a test.

  • Loops stop off screen.

    WhyNobody is watching, so nothing should run.

    TestEnforced by a test on every change.

  • Loops stop in a hidden tab and carry on when it comes back.

    WhyThe test hides the tab and expects the pulses of the architecture diagram to stay where they are.

    TestEnforced by a test on every change.

  • A loop never erases the result: it runs over the finished picture.

    WhyA picture that empties itself to play again says something different from the point it made. The test watches the dam illustration and the coverage grid through their loops and expects the result to stay in place throughout.

    TestEnforced by a test on every change.

  • A paused loop stops on the result, never halfway.

    WhyA visitor who stops the motion still gets the whole picture. The test pauses both visuals and checks that each stands at its result.

    TestEnforced by a test on every change.

  • Scripted motion takes its durations and curves from one module, the motion vocabulary.

    WhyA new visual then moves in the same few words as the rest. A guard test reads every script on the site and fails on a curve or a duration written outside that module, unless the file is on its allowlist with a written reason.

    TestEnforced by a test on every change.

Every visual has a sentence.

#

A visual that carries information is one image to assistive technology: role="img" with a short label, usually one sentence, that says what is drawn and the point it makes. The drawing inside is hidden. Decorative graphics, from the canvas behind the home hero to the icons, are hidden too.

Every one of the 21 visuals in production is one image with a label from the English and Turkish dictionaries.

The pattern, as CoverageMatrix writes it
<figure class="fv cov" data-coverage role="img" aria-label={d.label}>
<svg class="mk" viewBox="0 0 16 16" aria-hidden="true"><path d={tick}></path></svg>

Labels in use

Labels from the dictionaries
VisualLabel
DamFigureIllustration: Castor, a beaver, holds each arriving Linux or Windows file beside its legitimate original of the same name, taken from the stacks of originals in the dam, and lets the files that match through the dam's single opening; a Linux file and a Windows file that do not match their originals stand on the bank.
CoverageMatrixIllustration: a coverage grid fills in; every kind of file, on Linux and Windows, is checked against the legitimacy database.
MemoryMapIllustration: a memory map is scanned and one writable and executable region is flagged.
EvidenceChainIllustration: records lock into a chain that is signed and timestamped.
FlowDiagramA host runs the agent; the agent opens the connection outwards to the platform, which holds the stores. Nothing dials in to your hosts.

Most labels begin with ‘Illustration:’, so a listener knows a picture is being described. The two scroll scenes number their labels by step and swap them as the step changes, next to real step buttons and the step text. The dam illustration describes its beaver only as a beaver: the name of the mascot, Castor, stays in the prose of the design pages and never enters a text alternative.

  • A visual that carries information is role="img" with a label from the dictionaries, never a fixed string in the component.

    WhyThe label is translated with the page and reviewed with the copy.

    TestEnforced by a test on every change.

  • A label is a sentence, not a name.

    WhyThe test reads every visual label on the public pages and expects more than 40 characters and a full stop: ‘diagram’ describes nothing.

    TestEnforced by a test on every change.

  • A scroll scene changes its label with each step.

    WhyThe picture changes, so its description must change too.

    TestEnforced by a test on every change.

  • Decorative graphics are hidden: canvases, glyphs, icons and arrows carry aria-hidden.

    WhyA screen reader then hears the text beside them once, not a list of shapes.

    ReviewKept by review, not by a test.

Icons

#

The website draws its icons the same way it draws its diagrams: inline SVG, written by hand, usually in the component that shows it. The social marks in the footer are the one exception. Icons are decorative and hidden from assistive technology; the meaning sits in the text beside them or in the label of the control.

  • Feature grid

    MoreGrid

  • Trust cards

    TrustPage

  • Download

    CompanyPage

  • Fleet search

    FleetSearch

  • Handover

    ControlMap

  • Framework list

    FrameworkList

  • Status tick

    FindingsReport

  • Attack stage tick

    AttackNarrative

  • Lab exercise tick

    LabSession

  • Coverage tick

    CoverageMatrix

  • Evidence steps

    Results

  • Decision steps

    DecisionScene

Every icon family on the site, drawn from its own source path with its own CSS rule. A test fails if a component draws a small inline SVG outside these families.
Icon families, read from their source
FamilyDrawn atStrokeLineColourGrid
Feature grid24 px1.61.6 pxaccent-deep24
Trust cards28 px1.61.87 pxaccent-deep24
Download16 px1.61.6 pxaccent-deep16
Fleet search16 px1.61.6 pxink-subtle16
Handover20 px1.51.5 pxaccent-deep20
Framework list16 px22 pxaccent-deep16
Status tick16 px22 pxaccent-deep16
Attack stage tick16 px22 pxpaper on accent-deep16
Lab exercise tick16 px22 pxaccent-deep16
Coverage tick26 px22 pxpaper on accent-deep16
Evidence steps34 px22 pxpaper on ink34
Decision steps34 px22 pxpaper on ink34

What is not defined.

The website has no icon size ladder, no icon grid and no stroke rule. In all, 6 drawn sizes and 3 stroke weights (1.5, 1.6, 2) are in use, and nothing chooses between them; the tick is written out again in each component that draws it. Every family lands between 1.5 and 2 px of line on screen, but that is an observation, not a rule.

Other marks

The social marks in the footer are brand marks taken from Simple Icons (CC0) and kept in one module: one filled path each on a 24-unit grid, drawn at 16 px inside a 28 px link that carries the network name. They are the only icons the website did not draw itself. The pause control draws its glyph in CSS, not SVG. The Zerone glyph is the one brand mark and has rules of its own. Logo and name

  • Icons are decorative: they carry aria-hidden, and the meaning sits in the text beside them.

    WhyA screen reader then reads the words once instead of announcing shapes.

    ReviewKept by review, not by a test.

  • An icon-only control carries its name itself: the footer social links have an accessible name and no visible text.

    WhyThe icon is the only thing on the link, so the link must say where it goes.

    TestEnforced by a test on every change.

In the Zero Door interface

  • xs

  • sm

  • md

  • lg

  • xl

Each step magnified on the 24-unit grid, beside its true size. The magnified drawings share one scale, so the thicker stroke of the small steps is visible. Line on screen is size times stroke divided by 24.
Zero Door icon ladder
StepSizeStrokeLine on screen
xs12 px2.51.25 px
sm16 px2.251.5 px
md20 px21.67 px
lg24 px1.751.75 px
xl32 px1.52 px

The steps, sizes, strokes, default step, badge step and touch target above come from the product code: they are read into the product token snapshot when it is synced, not typed on this page. Only the 24-unit grid of the outline set is held by hand. The snapshot dates its product facts 2026-10-09: the last day any of the product files they are read from changed. Download the snapshot (JSON)