Design system

The rules behind this case study: the Birchway brand as it appears in the creatives, and the interface system the case study itself is built from. Every component on this page is the real one, working, and every contrast value is computed as the page loads.

Principles

Measure, don’t eyeball
Every ratio, size and weight on the site is computed from the thing itself. If a value can be checked, the page checks it.
The work sits on the proof
The interface is cool proof paper and spec ink. Colour and depth belong to the creatives, so they read as the subject.
Say it in words, then in colour
Status is always an icon and a word. Colour reinforces meaning; it never carries it alone.

Brand foundations

How Birchway appears in the creatives. These are the rules the QA checklist enforces.

Brand colour

Six colours. Two are illustration-only and never sit behind text; the QA checklist fails any CTA that uses them.

  • Birchway Spruce#23483APrimary background8.97:1, Hearth Cream headline
  • Hearth Cream#F6F0E1Headline and CTA text8.97:1, on Spruce, reversed
  • Cranberry#9B2335CTA fill6.88:1, Hearth Cream CTA label
  • Wheat#E9D9A6Supporting copy7.25:1, on Spruce, as copy
  • Pear Gold#D8B24AIllustration only, never text or fills behind textIllustration only: never carries text
  • Clementine#E07B2AIllustration onlyIllustration only: never carries text

Brand type

Young Serif for headlines, Archivo for everything else. Headline sizes are fixed per format, and QA checks each file against this table.

Aa

Young Serif
Headlines and wordmark

Aa

Archivo
Copy, CTA, legal; variable weight and width

FormatSpecHeadlineSupporting copy
Master key visual1800 × 1200124 px38 px
Medium rectangle300 × 25025 pxNone
Leaderboard728 × 9024 pxNone
Wide skyscraper160 × 60030 px13 px
Half page300 × 60042 px15 px
Feed square1080 × 108088 px28 px
Story and Reel1080 × 1920124 px40 px
Link post1200 × 62868 px23 px
DOOH static1920 × 1080150 px54 px sign-off

Interface foundations

The system this case study is built from: proof paper, spec ink and a small set of tokens.

Interface colour

Semantic tokens with light and dark values. The site follows the visitor’s system setting, with a switch in the menu.

  • --paper#EDEFE8 / #111915
  • --surface#FFFFFF / #18221D
  • --wash#E2E6DD / #1F2B25
  • --ink#17221C / #E8ECE6
  • --muted#4A554E / #A6B3AA
  • --accent#23483A / #8CCBA9
  • --spec#0B6585 / #74C2DD
  • --danger#9B2335 / #F2919F

Lowest text contrast across both themes: 5.63:1. The full pair list is on How this was built.

Interface type

A 1.25 ratio scale from a 17 px body. Page titles are fluid; everything else is fixed.

  • Home for the Holidays--t-hero clamp(40px, 1.5rem + 4.4vw, 76px). Home page title
  • Creative QA checklist--t-3xl clamp(36px, 1.6rem + 2.6vw, 56px). Page titles (h1)
  • Holiday 2026 adaptation package--t-2xl 33px. Ticket title, chapter numerals
  • Naming convention--t-xl 26px. Section headings (h2)
  • Every file gets the same checklist.--t-lg 21px. Ledes, card headings
  • Six segments, always in the same order, joined by underscores.--t-md 17px. Body text, line-height 1.55
  • Measured 300 × 250 px against a 300 × 250 px spec.--t-sm 15px. Secondary text, tables, controls
  • BWM-208 Due Nov 6--t-xs 13px. Captions, badges, meta

Layout and spacing

--gutter
clamp(16px, 4vw, 48px). Page side margin; 16 px on phones, 48 px on desktop
--measure
68ch. Maximum line length for reading text
--wide
1240px. Maximum width for galleries, boards and tables
--header-h
64px. Sticky header height; anchors and sticky toolbars offset by it
4–8 px
Inside a control: icon to label, badge padding
12–24 px
Inside a component: card padding, list rows, field groups
28–48 px
Between components in a section
72 px
Between sections on a page
88–96 px
Before the pager and footer

Breakpoints

  1. Phoneup to 559 pxSingle column, stacked tables, compact board
  2. Large phone560 to 759 pxTwo-up galleries begin, filters wrap
  3. Tablet760 to 999 pxTwo-column footer and forms, side-by-side before and after
  4. Laptop1000 to 1239 pxQA and reflection side columns, three-column board
  5. Desktop1240 px and upFive-column board, seven-step horizontal process flow

Layouts change where the content needs them to, so a few components use their own break points between these tiers. Every page is checked for horizontal overflow from 320 to 1920 px.

Shape, depth and motion

Corner radius

  • --r-sm 4px
    Every control: buttons, filters, inputs, badges
  • --r-md 8px
    Cards, panels, tables

Depth

Hairline
1px solid var(--rule)
Every UI surface: cards, tables, panels. No shadow.
Artwork lift
0 10px 30px -18px rgba(ink, .55)
Creatives only, so the work sits above the proof paper.

Motion

Sheet
260 ms, cubic-bezier(.2, .7, .2, 1)
Menu panel slide-in. Reduced motion: 150 ms fade.
Stagger
300 ms + 28 ms per item
Menu links settling in. Reduced motion: none.
Settle
180–350 ms, cubic-bezier(.16, 1, .3, 1)
Folder chevrons, sign-off meter.
Logo reveal
1.3 s, staged
Header leaf mark on page load: roundel, outline draw, fill, veins, wordmark unmask. Sways on hover.
Draw
1.1 s, cubic-bezier(.16, 1, .3, 1)
Home dimension lines drawing out, after the logo reveal.

Layering

--z-sticky 20, gallery toolbar--z-header 50, sticky header--z-overlay 80, menu scrim--z-modal 90, menu sheet--z-skip 100, skip link

Components

The working components from across the case study. Try them with a keyboard: every one is reachable with Tab and shows the focus ring.

Buttons

Use
Primary for the one main action on a view. Quiet for secondary actions. Labels name the action and never wrap. Corners are 4 px, like every control.
States
Hover darkens or fills; pressed nudges 1 px; disabled turns dashed and muted; focus shows the spec-ink ring.

Segmented filter and checkbox

Use
The segmented filter narrows a view to one option; a checkbox switches an overlay on or off.
States
aria-pressed carries the filter state; the active option inverts and shows a check mark, so it never relies on colour alone. The checkbox is a native input.

Status and priority

PassFailPlaceholderNeeds reviewMeasuringN/A
HighMediumLow
Use
Status badges report a check result; priority uses shape and word together.
States
Six statuses, three priorities. Each pairs an icon with a word.

Form fields

Use
Visible labels above every field; hints sit between label and input and are tied to it with aria-describedby.
States
Focus shows the ring and a spec-ink border; disabled checkboxes say why in their label.

Workload card

BWM-201High

Medium rectangle 300 × 250: fix CTA contrast, logo clearspace, headline size

DisplayDue tomorrow
Use
One request per card: ID, priority, title, platform, due date and a move control.
States
Urgent due dates add a warning icon and the danger colour; moving a card keeps keyboard focus on it.

Filename

BirchwayMarket_Holiday2026_Animated_300x250_v1_Backup.jpg

Use
Filenames break after underscores, never mid-segment, so long names stay readable on phones.
States
Static text; no states.

Spec frame

Scaled to fit

Use
Shows a creative at its true pixel size with spec-ink dimension lines, scaled to fit and never upscaled. Used for every creative on the site.
States
Safe zone overlay on demand; the scale note updates as the frame resizes.

Accessibility

WCAG 2.1 AA is the floor, checked by script rather than by eye.

  • PassContrast. Every text pair is at least 4.5:1 in both themes (lowest 5.63:1). npm run audit:contrast fails the build otherwise.
  • PassFocus. A 3 px spec-ink ring with a 3 px offset on light surfaces, Wheat on dark ones. Never removed.
  • PassTouch targets. Interactive controls are at least 44 px tall.
  • PassAppearance. The header button and Alt+Shift+L (⌥⇧L on Mac) cycle System, Light and Dark; System follows the device live. The tooltip shows on hover and keyboard focus, and each change is announced.
  • PassMeaning. Status, priority and urgency always pair an icon and a word with their colour.
  • PassMotion. With reduced motion on, slides become fades and the banner shows its end frame.
  • PassStructure. One h1 per page, a skip link, labelled landmarks, alt text on every creative, and focus moved to the new heading on navigation.

Tokens

The interface colour tokens as CSS custom properties, and the whole system as a JSON file.

Download tokens (JSON)
:root {
  --spruce: #23483A;
  --spruce-deep: #1B382D;
  --cranberry: #9B2335;
  --cream: #F6F0E1;
  --wheat: #E9D9A6;
  --sage-dark: #B5C6B9;
  --paper: #EDEFE8;
  --surface: #FFFFFF;
  --surface-2: #FAFBF8;
  --wash: #E2E6DD;
  --ink: #17221C;
  --muted: #4A554E;
  --accent: #23483A;
  --accent-fill: #23483A;
  --accent-fill-hover: #1B382D;
  --on-accent: #F6F0E1;
  --spec: #0B6585;
  --danger: #9B2335;
  --pass-bg: #E1ECE5;
  --pass-fg: #1E5236;
  --fail-bg: #F7E3E6;
  --fail-fg: #8C1D2E;
  --fail-tint: #FCF4F5;
  --hold-bg: #F3EBD3;
  --hold-fg: #5E4708;
}

:root[data-theme='dark'] {
  --spruce: #23483A;
  --spruce-deep: #1B382D;
  --cranberry: #9B2335;
  --cream: #F6F0E1;
  --wheat: #E9D9A6;
  --sage-dark: #B5C6B9;
  --paper: #111915;
  --surface: #18221D;
  --surface-2: #151F1A;
  --wash: #1F2B25;
  --ink: #E8ECE6;
  --muted: #A6B3AA;
  --accent: #8CCBA9;
  --accent-fill: #8CCBA9;
  --accent-fill-hover: #A8DCC0;
  --on-accent: #0F1D17;
  --spec: #74C2DD;
  --danger: #F2919F;
  --pass-bg: #173527;
  --pass-fg: #9EDDB7;
  --fail-bg: #3A1A20;
  --fail-fg: #FFB4BF;
  --fail-tint: #24161A;
  --hold-bg: #352C12;
  --hold-fg: #EED38A;
}