Design system

This is not a summary of how the site looks. It is the stylesheet itself, read out and shown.

Colours, per theme

Every token has two values. That is the whole point of a token: `--accent` is orange on dark and considerably darker on light, because the same colour on a light ground would not reach readable contrast. Same role, different value.

Vlakken

--surface
Dark
#08090c
Light
#e7e9ef
--surface-2
Dark
#0b0d12
Light
#dbdee6

Tekst

--ink
Dark
#f2f4f7
Light
#0c0f15
--ink-2
Dark
#a6adb8
Light
#4a525e
--ink-3
Dark
#8a929d
Light
#59616d

Glas

--glass-fill
Dark
rgba(255, 255, 255, 0.055)
Light
rgba(255, 255, 255, 0.55)
--glass-fill-2
Dark
rgba(255, 255, 255, 0.03)
Light
rgba(255, 255, 255, 0.38)
--glass-fill-hi
Dark
rgba(255, 255, 255, 0.085)
Light
rgba(255, 255, 255, 0.72)

Lijnen

--line
Dark
rgba(255, 255, 255, 0.12)
Light
rgba(12, 15, 21, 0.13)
--line-2
Dark
rgba(255, 255, 255, 0.07)
Light
rgba(12, 15, 21, 0.08)

Diepte

--shadow-card
Dark
none
Light
0 1px 2px rgba(12, 15, 21, 0.07), 0 12px 28px -16px rgba(12, 15, 21, 0.34)
--shadow-deep
Dark
0 30px 80px -30px rgba(0, 0, 0, 0.85)
Light
0 18px 44px -22px rgba(20, 24, 34, 0.22)
--spec
Dark
rgba(255, 255, 255, 0.18)
Light
rgba(255, 255, 255, 0)

Overig

--podium
Dark
#0e1014
Light
#0e1014
--podium-marge
Dark
10px
Light
10px
--podium-schaduw
Dark
none
Light
0 1px 2px rgba(12, 15, 21, 0.10), 0 18px 40px -20px rgba(12, 15, 21, 0.45)
--panel
Dark
rgba(18, 21, 27, 0.93)
Light
rgba(255, 255, 255, 0.95)

Accenten

--accent
Dark
#e8843b
Light
#9c4a0d
--accent-ink
Dark
#f0954f
Light
#8a400a
--accent-2
Dark
#9b7dff
Light
#5b3cc9
--accent-2-ink
Dark
#ae95ff
Light
#4e32b4
--ok
Dark
#4ade9e
Light
#0a7047
--on-accent
Dark
#0a0b0d
Light
#ffffff

Sfeer

--mesh
Dark
0.5
Light
0.24
--mesh-1
Dark
rgba(155, 125, 255, 0.24)
Light
rgba(91, 60, 201, 0.34)
--mesh-2
Dark
rgba(232, 132, 59, 0.22)
Light
rgba(156, 74, 13, 0.3)
--mesh-3
Dark
rgba(74, 222, 158, 0.18)
Light
rgba(10, 112, 71, 0.26)
--mesh-4
Dark
rgba(255, 255, 255, 0.16)
Light
rgba(12, 15, 21, 0.14)

Contrast, calculated

These numbers are not written down here — they are computed as the page is built. A written-down number goes stale the first time a colour changes, and nobody notices.

Role Pair Dark Light Required
Lopende tekst --ink on --surface 18,07 15,80 4,5
Gedempte tekst --ink-2 on --surface 8,81 6,50 4,5
Bijschrift --ink-3 on --surface 6,33 5,16 4,5
Accent als tekst --accent-ink on --surface 8,64 6,14 4,5
Tekst op accentvlak --on-accent on --accent 7,31 6,18 4,5
Bevestiging --ok on --surface 11,60 5,06 4,5
Scheidslijn --line on --surface 1,33 1,31 —

Translucent values are composited over the surface behind them first, because a border of 12% white is not 12% white but whatever you end up seeing. The requirement is 4.5:1 for text and 3:1 for the boundary of a control.

Scales

Three scales, and the rule underneath each is the same: a step nobody can see buys no hierarchy and costs the sense that things belong together.

Type sizes

  • Ag --text-xs 0.8rem
  • Ag --text-sm 0.889rem
  • Ag --text-base 1rem
  • Ag --text-lg 1.125rem
  • Ag --text-xl 1.25rem
  • Ag --text-2xl 1.5rem
  • Ag --text-3xl 1.875rem
  • Ag --text-4xl 2.25rem
  • Ag --text-5xl 3rem
  • Ag --text-6xl 3.75rem

Typefaces

Three faces, and until 29 August 2026 none of them existed as a token — thirty literal occurrences of "Space Grotesk" and thirty-six of "JetBrains Mono" scattered through the stylesheet. The bottom two belong to the older layer and still point at Inter; the site no longer uses it, the admin does, and that is why they are still here.

  • Ag
    --font-body "Inter", system-ui, -apple-system, sans-serif
    older layer
  • Ag
    --font-heading "Space Grotesk", "Inter", system-ui, sans-serif
    older layer
  • Ag
    --font-kop "Space Grotesk", system-ui, sans-serif
  • Ag
    --font-tekst "Hanken Grotesk", system-ui, sans-serif
  • Ag
    --font-mono "JetBrains Mono", ui-monospace, monospace

Corner radii

  • --radius-sm 0.375rem
  • --radius-md 0.75rem
  • --radius-lg 1rem
  • --radius-xl 1.5rem
  • --radius-full 9999px

Spacing

  • --space-1 0.5rem
  • --space-2 1rem
  • --space-3 1.5rem
  • --space-4 2rem
  • --space-5 2.5rem
  • --space-6 3rem
  • --space-8 4rem
  • --space-10 5rem
  • --space-12 6rem
  • --space-16 8rem

Components

Not pictures of buttons — the real components, styled exactly as they are everywhere else on the site.

Buttons and labels
Primary Secondary Status label
Card

On dark, depth comes from a step in value; on light, from shadow. Equal ratio is not equal perception: against near-white the same step reads as nothing.

Imagery

Imagery is not decoration and it is not separate from the system. This block is the same mount every render on the site sits in — flip the theme and watch the ground stay put.

Example of one of our own renders in its mount: the cross-section of an audit
Two gears side by side: the left one with intact teeth, the right one with worn and broken teeth and a bent spoke
The same component an article page uses, not a rebuild. On a narrow screen and under reduced motion this is a still image.
  • Build it, do not generate it Imagery that depicts an object is built in Blender. That buys four things at once: no image credits, real work and therefore within the content-truth rule, a demonstration of the service we sell, and a visual language nobody can copy because it is not a stock style.
  • One idea per image Navy ground, side light, and one thing carrying the frame. The brand seed fixes a palette — amber, cyan, navy — and not a material. When everything turned to brass the material stopped meaning anything: you start choosing objects that render well in brass instead of objects that are true.
  • The cross-section is the proof Beside the finished image stands the same scene in clay, edges in amber. A generated image has no cross-section, so there is nothing to explain and nothing to refute. A caption saying "rendered in Blender" is a claim, and claims get checked.
  • Imagery gets its own ground A render can be re-lit; footage cannot — a night flight will not grade light without becoming a bad night flight. So the mount does not follow the theme. On a light page dark imagery then reads as a mounted photograph rather than as a hole.
  • Motion only where it is true Three of the twenty-three article images move: the scale hunts, the gears turn one revolution so the wear comes past, and on the stamp only the camera moves — the impression has been struck, so any movement of the object itself would be invented. The loop closes to the pixel, so you never see a jump. The still stays the element that decides load time; the clip fades in over it once it can play. Below 768 pixels and under reduced motion it is never fetched at all.

Where the design was silent

The design file has been executed, but it did not answer everything. These are the three places we filled in — written down, because a filled-in silence nobody records is later mistaken for a mistake.

  • A button without a palette The design has two theme buttons, but `dark` determines exactly two values in it: the icon and the label. No colours change. The entire light palette is ours, including the darker accent — orange will not reach 4.5:1 on a light ground.
  • Image slots without images The design reserves the space and shows a placeholder. What belongs there, how it survives two themes and where it comes from was written nowhere. That became the previous section.
  • A scale nobody used The corner radii and the typefaces existed as tokens and were ignored: eighteen hard-coded values for five tokens, and sixty-six literal font names. Faithful transfer was right at the time — cleaning up was part of the job and happened later.
What is not in here

This page shows what exists, not what ought to. The ambient layers are decorative and carry no meaning. Imagery is deliberately absent: it is not yet one language, and a system page that smoothed that over would make exactly the mistake the previous version made for four months.

Curious what is possible?

One conversation is usually enough to tell whether it fits. A reply within 24 hours, and no middlemen.

  • A reply within 24 hours, always personal
  • Half an hour on the phone gets you the order of magnitude
  • A first conversation without obligation
  • Including software originally built by someone else