The values
behind the roles.
Colour, type, space, motion, and icons. Then the four surfaces that consume them, and the full token reference. If you are about to type a hex, the answer is on this page.
Colour
Two families: a nine-step neutral ramp from --ink to --paper, and a single brand accent --signal. Signal is never used as body text — only buttons, accents, and graphic highlights.
The neutral ramp traces Rift Valley light: deep basalt of Mount Longonot at dusk → bleached silt of Lake Naivasha at noon. Signal is East African sunrise — deployed only where attention is earned.
Signal is never used as text colour. Use it for buttons, decorative dots, top-border accents, hover glows, and the selection highlight. Body copy stays --paper, --light, or --mid.
rgba(255,255,255,0.08) — default borders, dividers
rgba(255,255,255,0.14) — scrolled nav, active card borders
Typography
Two typefaces only. Space Grotesk for all editorial and display text. JetBrains Mono for labels, metadata, code, and eyebrows — never for body paragraphs.
One sovereign stack.
Italic + signal weight 400 is used for the highlighted line in section titles. .accent class on a <span> inside .section-title or .page-title.
Space Grotesk carries Swahili copy without modification — clean Latin-Supplement coverage supports the full Kenyan and East African character set. All Navon display headlines work bilingually. Secondary test words: Ujenzi · Mazingira · Baadaye (construction · environment · future).
Spacing & Layout
All spacing is token-driven. The two most important are --px (horizontal page padding) and --section-y (vertical section rhythm) — both are fluid clamps.
Full-width
Hero sections, photography, maps. No max-width constraint below 1280px.
Section header
Title left, lede/meta right. Collapses to 1-col at 820px. Used in .section-head.
Feature grids
.numbered.cols-3 / cols-5. Collapses to 2-col at 1100px, 1-col at 640px.
Motion
All transitions use a single shared easing curve. Motion is purposeful and restrained — it guides attention, not decorates.
Smooth deceleration — fast in, eases out. Used for nav, buttons, dropdowns, hero reveals, and card transitions.
Standard durations: 0.2s for hover states, 0.4–0.5s for structural transitions (nav slide, card reveals), 0.8s for scroll-reveal animations.
Elements enter with opacity: 0 → 1 and translateY(16px → 0). Stagger delays available via .d1–.d6 (0.08s increments). Triggered by IntersectionObserver in shared.js.
Scope rule: .reveal is for section-level elements only — .section-title, .section-lede, and the delivery banner. Never on individual child items (.pillar, .delivery-card, .phase). Animate-on-scroll on every child card is an AI-slop tell.
SVG paths on technical illustrations animate from stroke-dashoffset: 1200 → 0 over 2.2s. Used for the fin.ai-style orthographic diagrams on product detail pages. Staggered with .d2, .d3, .d4 classes.
Icons & Diagrams
No icon library. All illustration is hand-coded inline SVG following a strict three-layer grammar: .line for primary form, .hair for structure, .signal for the single active element. The same vocabulary scales from a 24px mark to a full-page schematic.
Signal active zone renders first — context before structure. The .d2–.d4 stagger (0.3s increments) builds the diagram layer by layer: outer shell → internal structure → annotation callout.
All marks and diagrams are hand-coded inline SVG. No Lucide, Heroicons, or any external library — this keeps visual weight consistent with the diagram grammar and eliminates a dependency axis.
Each diagram highlights exactly one active zone in signal yellow. If multiple elements compete for .signal, the diagram is carrying too many ideas. Split it.
All geometry uses fill="none". Fills are reserved for .signal highlights and text. No gradients, no pattern fills, no drop shadows.
The stroke hierarchy (0.6 → 0.7 → 0.8 → 1.2) only holds if strokes don't scale with the SVG. Without this attribute, a thin line on a large viewBox becomes a hairline on mobile. Apply it to every line, rect, path, polyline, and polygon.
The .tech text CSS rule sets JetBrains Mono and --mid fill automatically. Use class="label-signal" for signal-yellow text. For map city names use class="city-label" (Space Grotesk, --paper, weight 600) and class="city-phase" (--slate, mono) for sub-labels. Never write font-family="Space Grotesk" or fill="#FFFFFF" directly on SVG elements — that bypasses the token system.
Products, Platform, Quantum Security, Hell's Gate detail. On customer-facing pages (Home, About, Who We Serve, Futures) replace diagrams with photography of Kenyan faces and landscape. The diagram language is a signal of depth — not decoration.
SVG <animate> elements do not respect prefers-reduced-motion. The CSS .pulse class uses a keyframe animation guarded by @media (prefers-reduced-motion: reduce). Always write <circle class="signal pulse" opacity="0.4"/> — never nest <animate> children.
Surfaces & Modes
Four media, one contract. Core owns the 16 required roles. Each surface supplies the values that make sense for its medium, and may add extension tokens, but may never drop a required role.
Website
Uses the core values unchanged.
public/assets/shared.css
- default The default. Body is --ink, text is --paper.
- .section--light A light band inside a dark page. Flips text and wordmark by cascade, and inverts the whole foreground ramp: --paper becomes near-black. Panels inside it use --card and --on-card.
- body.theme-light Whole light page. Used for legal, docs, and dense product surfaces. Supplies --card and --on-card the same way a light band does.
Deck
A deck has no site nav or footer. It supplies its own fixed nav, scroll-spy, and progress hairline.
public/<deck>/assets/deck.css (standalone) · src/styles/deck.css (in-site)
Document / PDF
Print inverts the default. The tonal rhythm on paper comes from hairlines and white space, not from bands.
.claude/skills/navon-brand-doc/assets/style.css
Email cannot use CSS custom properties reliably. Inline the resolved hex values from the primitives above.
newsletters/dispatch-01-investor.html
npm run ds -- --check reads every surface's
stylesheet and fails if one has dropped a required role. Run it before you ship
a change to any of the four.
Token Reference
The required semantic roles, their web values, and what each one is for.
Generated from design-system/tokens.json. Never
hardcode a value that has a token.
| Role | Web value | What it is for |
|---|---|---|
| --ink | #0b0b07 | Page background on dark surfaces. |
| --ink-2 | #07080A | Deeper background for ink bands and always-dark cards. |
| --charcoal | #3F4157 | Secondary text on light surfaces. |
| --slate | #6F7287 | Mono label and meta text colour. |
| --mid | #9E9F9B | Description and eyebrow text on dark. |
| --light | #E2E3DE | Body text on dark. |
| --vlight | #F3F4F4 | Light band background. |
| --paper | #FFFFFF | Headline colour on dark; page background on light. Inverts on a light band, so never a panel background. |
| --signal | #E7FF00 | The accent. One per view. |
| --font-display | 'Space Grotesk', system-ui, sans-serif | Display and body typeface. |
| --font-mono | 'JetBrains Mono', ui-monospace, monospace | Label and figure typeface. |
| --line | rgba(255,255,255,0.08) | Default hairline colour. |
| --line-2 | rgba(255,255,255,0.14) | Emphasised hairline: active cards, scrolled nav. |
| --px | clamp(20px, 4vw, 56px) | Horizontal page padding on every section. |
| --section-y | clamp(96px, 12vw, 160px) | Vertical section rhythm. |
| --easing | cubic-bezier(0.65, 0, 0.35, 1) | The one transition curve. |
| Step | Size | Weight | Tracking | Use |
|---|---|---|---|---|
| h-xl | clamp(38px, 6.2vw, 78px) | 600 | -0.025em | Deck cover, page hero. |
| h-lg | clamp(28px, 3.6vw, 50px) | 600 | -0.025em | Section headline. |
| h-md | clamp(22px, 2.4vw, 32px) | 600 | -0.02em | Card and slide sub-head. |
| lede | clamp(17px, 1.7vw, 21px) | 400 | 0 | Standfirst under a headline. Max 60ch. |
| body | 16px | 400 | 0 | Default paragraph. |
| small | 13px | 500 | 0.01em | Buttons, nav links, dense UI. |
| eyebrow | 11px | 500 | 0.24em | Mono uppercase section label. |
| mono | 11px | 400 | 0.18em | Mono uppercase meta label. |
One line-icon set: 24×24 viewBox, 1.5 stroke, currentColor, round caps and joins, no fill. Icons inherit theme colour and are structural signposts, not decoration.
New glyphs are drawn to match, or adapted from Heroicons or Tabler. Duotone and soft-filled sets (Phosphor, Solar, Iconoir) are rejected — they break the single-accent rule and the tonal rhythm.