Design reference
The Praktikal design system
The values behind the look — colour, type, spacing, shape, depth and motion — with enough detail to build a page, a deck or a product surface that sits comfortably beside ours.
Representing the brand rather than building with it? The brandbook has the logo files, colours and voice.
Principles
Green marks; it does not cover
Both greens mark the one thing that matters on a surface — the primary action, a highlighted word. A layout that is mostly green has no accent left, so keep each to small, deliberate areas against paper and ink.
Stay on the 4px grid
Every margin, padding and gap is a step on the spacing scale. Consistent rhythm is most of what makes a layout read as ours, and it is the easiest thing to get right.
Generous measure, tight headings
Body text is set at a comfortable line height and a readable line length. Headings are the opposite: heavy, tightly tracked, and allowed to wrap in balance rather than run edge to edge.
One idea per surface
A card, a band, a panel carries a single point. When a surface needs a second, it wants to be two surfaces, separated by a step from the spacing scale rather than a divider.
Motion is feedback, not decoration
Movement confirms something happened — a hover, a state change, content arriving. It never runs on a loop, and it always respects a reduced-motion preference.
Colour tokens
The full palette with the name each colour is known by. Use the named role rather than picking a shade by eye, so the same decision lands the same way twice.
Core
Praktikal Green
- HEX
- #008243
- RGB
- 0 130 67
- CMYK
- 100 0 48 49
The primary. Every primary button, in the product and on this site. Deep enough to carry white text, which is the whole reason it and not the accent does this job.
--color-dark-greenAccent green
- HEX
- #77c043
- RGB
- 119 192 67
- CMYK
- 38 0 65 25
The logo is drawn in it, and so are marker highlights and small accents. It is a fill behind ink, never a background for white text — see the pairings below.
--color-greenInk
- HEX
- #414042
- RGB
- 65 64 66
- CMYK
- 2 3 0 74
Body text, headings, and the dark outline on cards and buttons. Also the full-bleed dark band on the public site.
--color-neutral-90Paper
- HEX
- #fafafa
- RGB
- 250 250 250
- CMYK
- 0 0 0 2
The base surface behind everything. Not pure white.
--whiteSupporting
Blue
- HEX
- #24a8de
- RGB
- 36 168 222
- CMYK
- 84 24 0 13
Section accent on the public site. Informational states.
--color-blueOrange
- HEX
- #ea780e
- RGB
- 234 120 14
- CMYK
- 0 49 94 8
Section accent. Warning states in the product.
--color-orangeMagenta
- HEX
- #e85d9c
- RGB
- 232 93 156
- CMYK
- 0 60 33 9
Section accent on the public site. Decorative only.
--color-decorative-magentaRed
- HEX
- #e00000
- RGB
- 224 0 0
- CMYK
- 0 100 100 12
Destructive and error states only. Never decorative.
--color-redNeutrals
Secondary text
- HEX
- #757575
- RGB
- 117 117 117
- CMYK
- 0 0 0 54
Supporting copy, footer links, captions.
--color-neutral-70Border
- HEX
- #e0e0e0
- RGB
- 224 224 224
- CMYK
- 0 0 0 12
Default borders and dividers in the product.
--color-neutral-40Surface
- HEX
- #f5f5f5
- RGB
- 245 245 245
- CMYK
- 0 0 0 4
Raised and inset surfaces against Paper.
--color-neutral-10Legible pairs
Which token may carry text on which. The accent is a fill behind ink, so the primary button uses the deeper Praktikal Green instead.
Ink on paper
9.9:1Passes AA
The default. Every long passage of text on our surfaces is this pair.
Ink on accent green
4.6:1Passes AA
The correct way to use the accent behind type: a highlight, a marker bar, a small filled panel.
Paper on accent green
2.1:1 Fails AA
Do not use. The accent is too light to carry white text, which is why the primary is a different green.
Paper on Praktikal Green
4.7:1Passes AA
The primary button. Use this pair wherever you need white text on green.
Paper on ink
9.9:1Passes AA
The dark band. Green stays an accent on it, never the text colour.
Ratios are measured against WCAG 2.1 AA for body text (4.5:1), and computed from the same values the swatches above publish.
Type scale
| Step | Token | Value | Used for |
|---|---|---|---|
| Display large | --font-size-display-large | clamp(2rem, 1rem + 3.5vw, 3.5rem) | Page titles and the opening statement. |
| Display medium | --font-size-display-medium | clamp(1.75rem, 1rem + 2.5vw, 2.5rem) | Section headings. |
| Heading 1 | --font-size-xxx-large | 28px | The main heading on a screen inside the product. |
| Heading 2 | --font-size-xx-large | 24px | Subsection headings. |
| Heading 3 | --font-size-x-large | 20px | Card, panel, and dialog titles. |
| Heading 4 | --font-size-large | 16px | The smallest heading, and long-form reading text. |
| Body | --font-size-medium | 14px | Default interface text. |
| Small | --font-size-small | 12px | Captions, metadata, and helper text. |
| Hero | --font-size-hero | clamp(2rem, 4.6vw, 3.5rem) | The marketing hero. Shares its bounds with display large, and differs only in how it scales between them. |
| Lead | --font-size-lead | clamp(1rem, 0.9rem + 0.5vw, 1.25rem) | Standfirst under a marketing heading. Settles at the same size as heading 3. |
| Face | Token | Weights |
|---|---|---|
| Montserrat | --font-family-display | Regular 400, Medium 500, SemiBold 600, Bold 700 |
| Nunito Sans | --font-family-body | Regular 400, SemiBold 600 |
Components
How the values above come together on the controls people actually use.
Button variants
Button sizes
Card
A content surface
A content surface: light border, small soft shadow, generous padding.
Marker shadows
Hard, zero-blur offset shadows give a surface a printed, stuck-on lift. They are a deliberate graphic effect rather than depth, so they are never combined with the soft shadows above on the same element.
Marker green
--shadow-marker-greenMarker green, medium
--shadow-marker-green-mdMarker green, small
--shadow-marker-green-smMarker pink
--shadow-marker-pinkMeasurements
Spacing
A 4px grid. Every margin, padding and gap comes from this scale — a literal pixel value in a component is a defect, not a shortcut.
| Token | Value | Preview |
|---|---|---|
--spacing-0 | 0 | |
--spacing-half | 2px | |
--spacing-1 | 4px | |
--spacing-2 | 8px | |
--spacing-3 | 12px | |
--spacing-4 | 16px | |
--spacing-5 | 20px | |
--spacing-6 | 24px | |
--spacing-8 | 32px | |
--spacing-9 | 36px | |
--spacing-12 | 48px |
Corner radius
Small radii for controls, larger ones for surfaces. Pick one step and hold it across a layout rather than mixing several.
| Token | Value | Preview |
|---|---|---|
--border-radius-xs | 2px | |
--border-radius-small | 4px | |
--border-radius-small-medium | 6px | |
--border-radius-medium | 8px | |
--border-radius-large | 12px | |
--border-radius-xlarge | 16px | |
--border-radius-pill | 999px |
Elevation
Soft, blurred shadows for depth. The offset shadows further down are a separate, deliberately graphic effect and the two are not mixed on one surface.
| Token | Value | Preview |
|---|---|---|
--box-shadow-xs | 0px 1px 2px rgba(0, 0, 0, 0.2) | |
--box-shadow-sm | 0px 2px 4px rgba(0, 0, 0, 0.2) | |
--box-shadow-md | 0px 2px 8px rgba(0, 0, 0, 0.2) | |
--box-shadow-lg | 0px 4px 12px rgba(0, 0, 0, 0.25) | |
--box-shadow-xl | 0px 8px 16px rgba(0, 0, 0, 0.25) | |
--focus-shadow | 0px 0px 2px 2px color-mix(in srgb, var(--color-accent), transparent 60%) |
Motion
Three durations, and no others. Motion is a short colour shift or a small lift, never a long or elastic movement, and it is dropped entirely when a visitor asks for reduced motion.
| Token | Value |
|---|---|
--transition-duration-fast | 0.15s |
--transition-duration-normal | 0.2s |
--transition-duration-slow | 0.3s |