Gold
#C8882B
200, 136, 43
Primary accent. Buttons, links, active states, the one word highlighted in a headline. Locked.
We build what you run on.
This is the whole brand in one place: the crest, the three colours, the three typefaces, the voice, and the one motion curve. Everything here is already live in the code that renders this page, so nothing on it is a proposal. It is a record.
VDM Digital carries a coat of arms, not a wordmark. It is the van der Merwe arms: a maroon shield with gold bezants under a knight's helm, mantling on both sides, and two banners. The brand is a family name before it is a company, and the mark says so.
#0A0A0A. The primary lockup on dark.
#FAFAFA, where its white field disappears into the page. This is the file the nav and the footer use.
npm run crest:emboss, never
re-lit by hand.
Two families of file, and they are not interchangeable. The crest and shield rasters the site has shipped since launch carry an opaque white field, so they read correctly on the light sections and become a white box on the dark ones. The knockout files carry real transparency and are cut from the same master the struck-metal bake uses. Reach for the knockout on anything dark, and check the file before assuming, because both look identical in a folder thumbnail.
| Asset | File | Pixels | Use |
|---|---|---|---|
| Full crest | images/vdm-crest.webp | 600 × 730 | Hero, about, print |
| Full crest (PNG) | images/vdm-crest.png | 600 × 730 | Where WebP is not accepted |
| Crest, knockout | images/vdm-crest-knockout.webp | 572 × 711 | Dark grounds. Real transparency |
| Crest, knockout, medium | images/vdm-crest-knockout-md.webp | 300 × 373 | Dark grounds, smaller |
| Crest, medium | images/vdm-crest-md.webp | 300 × 365 | Footers, cards |
| Crest, struck metal | images/vdm-crest-emboss.webp | 460 × 560 | Sign-in panel only |
| Roundel | images/vdm-logo.webp | 640 × 640 | Avatars, social profiles |
| Shield | images/vdm-shield.webp | 39 × 48 | Navigation bar |
| Shield, large | images/vdm-shield-lg.png | 79 × 96 | Small badges |
| Favicon | favicon.png | 32 × 32 | Browser tab |
| Touch icon | apple-touch-icon.png | 180 × 180 | iOS home screen |
Gold, red, black. That is the whole palette, and it is the coat of arms read for a screen. There is no fourth brand hue by design. If something is reaching for another colour to separate itself, the layout is the problem and not the palette.
Gold carries emphasis. Red carries heritage and edge. Black carries everything else.
#C8882B
200, 136, 43
Primary accent. Buttons, links, active states, the one word highlighted in a headline. Locked.
#E8B44A
232, 180, 74
Highlight, small text on dark, top stop of a metallic gradient.
#A8721F
168, 114, 31
Hover and pressed states for gold.
#9D691A
157, 105, 26
The gold substitute on light sections, where the primary gold fails contrast. Do not lighten it.
#EBD698
235, 214, 152
Metallic highlight stop inside crest and emboss gradients only. Never a flat fill, never text.
#8B1A2C
139, 26, 44
Heritage accent. Borders, edges, rare emphasis. Never a large flat field. Locked.
#6B1422
107, 20, 34
Hover and pressed states for red.
#72051B
114, 5, 27
Sampled from the crest artwork. For crest fidelity, print and foil work. Not for interface.
#0A0A0A
10, 10, 10
Primary screen background. Near-black on purpose: pure black halates against light text on OLED. Locked.
#000000
0, 0, 0
Print and crest reproduction only. Never a screen background.
#141414
Raised surface on dark.
#1C1C1C
Cards and modals on dark.
#F5F5F5
Primary text on dark.
#A3A3A3
Secondary text on dark.
#8A8A8A
The muted rung on dark. Raised from a darker value that failed AA on every surface it sat on.
#FAFAFA
Background of every light section.
The ladder is surface dependent, and it inverts. Measured against the two page backgrounds:
| Colour | On black #0A0A0A | On light #FAFAFA |
|---|---|---|
Gold #C8882B | 6.61:1 | 2.87:1 |
Gold light #E8B44A | 10.43:1 | below AA |
Gold on light #9D691A | not used there | 4.50:1 |
Red #8B1A2C | 2.15:1 | 8.82:1 |
Red is never a foreground on dark. At 2.15:1 it is
unreadable as an icon or a label there, so on dark it is a border, an edge,
or a rule and nothing else. On light the ladder flips: red becomes the
strong foreground and gold has to step down to #9D691A before
it clears AA. Anything lighter than that value reopens a hole that already
shipped once, across four element classes on nine pages.
Imagery is part of the palette. A colour lock that stops at the stylesheet is not a colour lock. Photography and video carry far more screen area than any accent chip, so a picture with a cyan sky or a purple neon sign breaks the palette more thoroughly than a button ever could.
Banned outright: purple and generic blue as accents in any brand surface. Six decorative card hues were deleted on 8 August 2026 for the same reason. They meant VDM's own chrome changed colour six times down a single page. Error and success colours exist for state only, never for decoration.
Three families, self-hosted, all under the SIL Open Font License. Together they weigh 83,120 bytes, which is less than the single family they replaced.
Display and body. One variable file, weight 300 to 900.
We build what you run on.
The third voice. Eyebrows, captions, chips, form labels. Weight 400 to 600.
QUOTES / INVOICES / CLIENTS
The positioning line, once per page, and nothing else. That scarcity is why it reads as a statement. The only true italic in the stack.
We build what you run on.
Inter is banned, permanently. It is the single most recognisable tell of a generated interface, and it was the site default until 8 August 2026. The ban does not depend on which family is locked above. A typeface swap replaces the family, never this rule.
Everything is fluid through clamp(), so there is not one font-size
media query anywhere in the site. The two ends are a 375px phone and a 1440px
monitor.
| Token | Small | Large | Use |
|---|---|---|---|
--display-hero | 44px | 104px | The positioning line |
--display-xl | 34px | 64px | Page titles |
--display-lg | 28px | 44px | Section titles |
--display-md | 22px | 30px | Card and block titles |
--text-base | 14px | 16px | Body |
--text-xs | 12px | 13px | Captions, chips, labels |
Display tightens, meta opens. That single contrast is most of what reads as Swiss, and it costs nothing.
| Token | Value | Applies to |
|---|---|---|
--track-display | -0.04em | Display sizes |
--track-tight | -0.015em | Headings |
--track-tag | 0.08em | Section tags |
--track-meta | 0.14em | Eyebrows, small caps |
--leading-display | 0.94 | Display sizes |
--leading-body | 1.65 | Body copy |
No family in this stack carries a width axis, so width is always
normal. A percentage width would ask the browser to synthesise a
stretch, which is what makes good type look cheap. Weight separates display
from body, never width.
Direct, specific, and outcome first. VDM sells to owner-operators, a farmer and a DJ and a vehicle-subscription founder, not to CTOs. Every line has to survive being said out loud on a phone call.
We build what you run on.
Under it: Quotes, invoices, clients, leads, documents, reporting. One system, built around how your business already works. The named framework is The Crest Standard.
One curve does almost everything. It is fast off the mark and settles long, which is the blade of the homepage film expressed as a bezier. No bounce, no overshoot, no elastic. Those read playful, and the brand is not.
--ease-bladecubic-bezier(0.16, 1, 0.3, 1)| Token | Value | Use |
|---|---|---|
--dur-fast | 150ms | Hover, focus, colour change |
--dur-base | 320ms | Reveals, panels, most transitions |
--dur-slow | 640ms | Large surfaces entering |
--dur-film | 1200ms | Cinematic beats only |
--stagger | 60ms | Between siblings, four items maximum |
Transform and opacity only. Every animation on the site
moves or fades. There is not one filter: blur() anywhere,
because a blur is a per-frame raster pass and it is the first thing to
drop frames on a phone.
Reduced motion is a contract, not a courtesy. With
prefers-reduced-motion: reduce set, reveals apply instantly
and the homepage film fetches no video at all. It serves the poster with
the closing statement already in place.
An eight pixel grid, one content width, and four radii. Spacing is never an arbitrary value, because the moment one component invents its own the grid stops being a grid.
--space-1 4px--space-2 8px--space-4 16px--space-6 24px--space-8 32px--space-12 48px--space-16 64px--space-24 96px| Token | Value | Meaning |
|---|---|---|
--max-width | 1200px | Content column, every page |
--nav-height | 72px | Fixed navigation bar |
--radius-sm | 8px | Inputs, chips |
--radius-md | 12px | Cards |
--radius-lg | 16px | Large panels |
--radius-full | 9999px | Pills, avatars |
Sections alternate dark and light by cascading a different set of the same
variables, through .section--dark and .section--light.
No component hardcodes a colour, so a section can change side without a single
component being touched.
The premise of the brand is that VDM Digital does not produce corporate nonsense. That obliges the brand's own surfaces first.
Every number on a public page has to be verifiable. If it cannot be verified it does not ship. Say what we can do instead of inventing evidence that we have done it.
This is not a principle recovered after the fact. The rebuild deleted invented testimonials from people who were never clients, a statistics block claiming a project count and a satisfaction percentage, eight fictional names in the logo bar, and an aggregate rating handed to search engines with no reviews behind it. The counter helper that animated those numbers was deleted with them, so there is nothing left sitting around inviting them back.
What replaced them can only ever show something real. A client records a video, an admin approves it, and only then does it reach the site. Star ratings are typed by the client, are optional, are never defaulted, and an unrated video shows no stars and is left out of the average. The figures on the homepage are counted from what is on screen at render time, so none of them can drift from what a visitor can count themselves.
One consequence worth stating plainly: there is still no aggregate rating in the structured data, even now that the ratings are real. An admin only approves testimonials worth showing, so the published average is selected by construction. That is honest as an on-page display of what clients said, and dishonest as a number handed to a search engine.
This book is a rendering of decisions that live in code. When it disagrees with one of these, the code wins and this page is what needs fixing.
| Source | Owns |
|---|---|
brand-dna.json | Palette and voice. The canonical brand source. Every renderer, template, invoice and deck derives from it. |
styles/main.css | The live token block. Colour, type, spacing, motion, as the browser actually resolves them. |
docs/design-system.md | The reasoning: contrast tables, the locked decisions, component status. |
assets/brand/crest-full.png | The crest master, with real transparency. It never ships to the web. |
Locked decisions, with the dates they were locked: the positioning line and the palette on 8 August 2026, the typeface stack on 11 August 2026. Pricing is never public. The framework is called The Crest Standard.
VDM Digital (Pty) Ltd · Reg. No. 2026/179981/07 · Issued 10 September 2026