Design System
The tokens, typography, spacing, and components used to build principles.design.
Note: (18th Feb 2026) Work in progress, this documentation is being expanded.
Colors
Primary#f7d708
Primary Light#fdf7ce
Secondary#0015dd
Text#333
Text Muted#666
Text Subtle#777
Border#e6e6e6
Surface#fffdf8
Typographic Scale
Root size: 19px. Scale ratio derived from the baseline unit. All sizes in rem.
Step 4 — 4.2105rem
Step 3 — 2.6316rem
Step 2 — 1.6316rem
Step 1 — 1.3158rem
Step 0 — 1rem
Vertical Rhythm
All vertical spacing is based on the baseline unit: 1.5263rem (29px) — one line of body text.
3xs
0.25×
xs
0.5×
s
0.75×
m
1×
l
1.5×
xl
2×
2xl
3×
3xl
4×
Heading Rhythm
Heading margins snap to whole baseline units. This specimen demonstrates the vertical rhythm in context.
Heading 1
Body text following h1. The baseline unit (29px) governs all vertical space. Margins are always whole multiples of this unit, creating a consistent rhythm that can be felt even when not seen.
Heading 2
Body text following h2. Each heading level steps down in size but maintains the same margin logic relative to the baseline grid.
Heading 3
Body text following h3. At smaller sizes, the heading sits closer to its content, grouped visually with the paragraph it introduces.
Heading 4
Body text following h4. The smallest heading shares its size with body text but remains bold, serving as an inline section marker.
Measure
Body text has a maximum width of 40rem (~65–75 characters per line) for optimal readability. This paragraph demonstrates the measure. Long lines of text are harder to read because the eye struggles to track back to the start of the next line. Constraining the measure prevents this.
Components
Header
Site header with logo and navigation. Responsive layout with two breakpoints.
| Breakpoint | Logo | Nav |
|---|---|---|
| Small (default) | 3 baseline units (87px) | Left-aligned, wraps 2+1, vertically centered |
| Medium (700px+) | 2.5 baseline units (72.5px) | Right-aligned, single row |
States
- Hover: Underline with
--transition-fastfade-in - Active: Bold text (current page)
Accessibility
aria-label="Main"on<nav>aria-current="page"on active linksr-onlytext for logo link
Background
- Homepage:
--color-primary(yellow) - Other pages:
--color-surface(white)
Footer
Two-section footer: newsletter signup (yellow) and credit section (dark).
Newsletter Signup
| Class | Purpose |
|---|---|
.footer-signup |
Container with --color-primary background |
.footer-signup__heading |
Heading with tight line-height |
.footer-form__fields |
Flex container for input + button |
.footer-form__input |
Email input field |
.footer-form__button |
Submit button with hover scale |
.footer-form__message--success |
Success message with --color-success |
.footer-form__message--error |
Error message with --color-error |
Credit Section
| Class | Purpose |
|---|---|
.footer-credit |
Container with --color-surface-dark background |
.footer-social |
Flex row of social icon links |
.footer-meta |
Links and copyright with border-top |
.footer-meta__link |
Small muted text for meta links |
Responsive
- Mobile (<600px): Form fields stack vertically, button full width
- Desktop (600px+): Form fields inline
CTA Button
Primary call-to-action button with hover effect and optional price display.
Parameters
| Parameter | Required | Description |
|---|---|---|
url |
Yes | Button destination link |
text |
Yes | Button text (before price) |
price |
No | Optional price to display after text |
Usage
{% include components/cta-button.html url="#pricing" text="Get the field guide" price="$29" %}
{% include components/cta-button.html url="/field-guide/" text="Buy now" %}Styling
- Background:
--color-text(#333) - Text: White (#fff)
- Font: 1.15em, weight 500
- Padding: 1.15em 1.35em
- Border radius: 0.3em
- Hover: Scale to 1.03 with
--transition-fast
Component file
_includes/components/cta-button.html
Pricing Card
Pricing card with title, price, features list, and CTA button. Supports primary and secondary styles.
Parameters
| Parameter | Required | Description |
|---|---|---|
title |
Yes | Card title |
subtitle |
No | Subtitle in parentheses (e.g., "5+ seats") |
subtitle_text |
No | Descriptive subtitle text |
price |
Yes | Price amount |
features |
Yes | Comma-separated list of features |
button_text |
Yes | CTA button text |
button_url |
Yes | CTA button destination |
style |
No | Card style: primary (dark border) or secondary (light border) |
Usage
{% include components/pricing-card.html
title="Individual"
subtitle_text="For personal use."
price="$29"
features="Full PDF field guide,All worksheets,Free updates"
button_text="Buy now"
button_url="#"
style="primary"
%}Styling
- Background: White (#fff)
- Border: 2px solid #333 (primary) or #e6e6e6 (secondary)
- Border radius: 0.4em
- Padding: 1.5em
- Layout: Flex column, min-width 240px
- Features list: Grows to fill available space
Component file
_includes/components/pricing-card.html
Author Card
Author profile card with circular image and bio. Responsive layout with mobile-specific alignment.
Parameters
| Parameter | Required | Description |
|---|---|---|
name |
Yes | Author name (displayed in bold) |
bio |
Yes | Author bio/description |
image |
Yes | Profile image filename (in /images/) |
image_alt |
No | Alt text for image (defaults to name) |
image_size |
No | Image size in pixels (default: 80) |
Usage
{% include components/author-card.html
name="Ben Brignell"
bio="a design consultant who has spent 25 years helping teams make better decisions"
image="ben-brignell-profile-small.jpg"
image_alt="Ben Brignell"
image_size="80"
%}Styling
- Layout: Flex row with 1.5em gap
- Image: Circular (border-radius: 50%), object-fit: cover
- Text: "Written by [name], [bio]" format
- Mobile: Aligns to top, adds 0.5em margin to image and text
Component file
_includes/components/author-card.html
Layout
12-column CSS grid. Maximum width 1080px, 85% viewport width.
Breakpoints
| Name | Value | Effect |
|---|---|---|
| Small | 400px | Minor mobile adjustments |
| Medium | 700px | Two-column layouts |
| Large | 920px | Type scale steps up, three-column tiles |
| Extra large | 1100px | Horizontal navigation bar |
Tokens Reference
All design decisions are expressed as CSS custom properties defined in tokens.css.
Color tokens
| Token | Value | |
|---|---|---|
--color-primary |
#f7d708 | |
--color-primary-light |
#fdf7ce | |
--color-secondary |
#0015dd | |
--color-text |
#333 | |
--color-text-muted |
#666 | |
--color-text-subtle |
#777 | |
--color-border |
#e6e6e6 | |
--color-surface |
#fffdf8 | |
--color-surface-alt |
#f5f5f5 | |
--color-surface-dark |
#2c2c2c | |
--color-text-light |
#f0f0f0 | |
--color-success |
#388E3C | |
--color-error |
#d32f2f |
Spacing tokens
| Token | Multiple | Computed |
|---|---|---|
--space-4xs | 0.125× | ~3.6px |
--space-3xs | 0.25× | ~7.3px |
--space-2xs | 0.375× | ~10.9px |
--space-xs | 0.5× | ~14.5px |
--space-s | 0.75× | ~21.7px |
--space-m | 1× | 29px |
--space-l | 1.5× | ~43.4px |
--space-xl | 2× | 58px |
--space-2xl | 3× | 87px |
--space-3xl | 4× | 116px |
Transition tokens
| Token | Value | Usage |
|---|---|---|
--transition-fast | 0.2s ease-in-out | Hover states, micro-interactions |
--transition-slow | 0.3s ease-in-out | Background changes, larger state changes |