Colour, typography, components, motion, iconography and voice, plus the rules that keep them consistent. Everything below is rendered from the same files the site is built from, so it cannot drift from what actually ships.
Generated from design/tokens.json01 / Foundations
One wordmark, one tagline pill. The pill is the most distinctive thing the brand owns and it is finished: do not restyle it, move it, or drop it.
Canopy. Capital C, full stop in leaf green. The full stop is part of the mark, not punctuation.canopy. or the full Canopy Digital as the mark. Both existed across the site and have been retired.02 / Colour
Three surfaces, because the product genuinely has three. They agree on the greens and the cream and differ only in their neutrals. Click any swatch to copy its value.
Computed live against WCAG 2.1. Anything below 4.5:1 fails AA for body text; 3:1 is the floor for large text and UI boundaries.
.btn-primary, the "Say Hello" CTA) is white text on leaf green, which
measures 2.08:1. That fails AA for body text (4.5:1) and also fails the
3:1 floor for large text and UI boundaries.
03 / Typography
Space Grotesk for anything that carries structure: headings, the wordmark, buttons, prices, numbers. DM Sans for everything a person reads in sentences.
04 / Space and shape
Corner radius carries hierarchy: the bigger the surface, the rounder it is.
| Token | Value | Used for |
|---|---|---|
--radius-sm | 10px | Buttons, inputs, small controls |
--radius | 12px marketing · 16px wizard | Cards, panels, plan tiles |
| pill | 100px | Chips, badges, the tagline pill |
| phone | 44px | The hero device only |
05 / Components
Rendered from the real CSS, not screenshots. Everything here is interactive.
A disabled button always names the single next thing it needs. Type below to watch it change.
06 / Motion
Short, eased, and never decorative for its own sake. Press replay on any of these.
prefers-reduced-motion path. The hero typewriter, the underline draw, the icon spinner and the chips all honour it. Anything new must too.
| Duration | Use |
|---|---|
| 0.1s | Press feedback, :active scale |
| 0.2s | Hover, focus, colour changes. The default. |
| 0.3s | State transitions, stepper progress |
| 0.4s | Element entry, message bubbles |
| 0.65s | Scroll reveal |
07 / Iconography
Stroke-based, 24×24, 2px round caps. Sized in em and coloured with currentColor, so an icon always matches the text beside it and works on light and dark surfaces without variants.
Decorative, where the text already says it:
<svg class="icon" aria-hidden="true"><use href="#i-check"></use></svg>
Meaningful, where the icon is the only label:
<svg class="icon" role="img"><title>Verified</title><use href="#i-check"></use></svg>
content: value and a textContent assignment both render as literal text, so the user sees the string <svg class=…. Use the character in CSS, and innerHTML in JS. Two tests enforce this.
08 / Voice
Plain, direct, a little dry. Texts read like a competent person, not a bot and not a cheerleader. No exclamation-point enthusiasm. Short sentences.
You're invisible in your own city.
The felt problem. SEO, AEO and GBP are machinery. Never lead with machinery.
Do
"A marketing partner that handles everything for you."
"Your site is yours. Download the code anytime."
Don't
"Your AI marketing employee!"
"We'll get you to #1 on Google."
09 / Rules
These are settled. They are not preferences.
The mechanics that keep the above true.
public/index.html is generated. Edit public/sections-html/* and run npm run build:homepage. A test fails if it is stale.design/tokens.json. Change one there and every page follows. Hand-editing a hex in a page gets reverted on the next build.<use href="#i-name">. The sprite prunes itself to what is referenced..npmrc enforces a release-age floor and the site ships no frontend dependencies.