Skip to content

Style Guide

The spacing scale, containers, section rhythm and grid utilities shared by every Harbor Coffee Roasters template.

Colour

Palette

Warm browns and cream with a roasted-copper conversion colour. Each swatch is labelled with the readable brand foreground and its measured contrast ratio.

Roasted copper (primary)

  • --color-primary-50 #fdf6f0 14.66:1 · AA text
  • --color-primary-100 #f8e5d4 12.81:1 · AA text
  • --color-primary-200 #efc7a6 10.01:1 · AA text
  • --color-primary-300 #e2a271 7.20:1 · AA text
  • --color-primary-400 #d07c42 4.96:1 · AA text
  • --color-primary-500 #b85f23 4.15:1 · large text only
  • --color-primary-600 #a34e17 5.33:1 · AA text
  • --color-primary-700 #7d3a12 7.84:1 · AA text
  • --color-primary-800 #5f2d10 10.43:1 · AA text
  • --color-primary-900 #401e0b 13.84:1 · AA text

Crema amber (accent)

  • --color-accent-100 #fbefc6 13.65:1 · AA text
  • --color-accent-200 #f6dd8c 11.69:1 · AA text
  • --color-accent-300 #f0c653 9.64:1 · AA text
  • --color-accent-400 #e3a92a 7.45:1 · AA text
  • --color-accent-500 #c98f18 5.55:1 · AA text
  • --color-accent-600 #a87214 3.84:1 · large text only
  • --color-accent-700 #8a5712 5.65:1 · AA text
  • --color-accent-800 #6b4312 8.00:1 · AA text

Warm neutrals

  • --color-neutral-50 #faf6ef 14.57:1 · AA text
  • --color-neutral-100 #f3ebdd 13.25:1 · AA text
  • --color-neutral-200 #e7dac6 11.39:1 · AA text
  • --color-neutral-300 #d5c3a8 9.12:1 · AA text
  • --color-neutral-400 #a48d74 4.96:1 · AA text
  • --color-neutral-500 #7a6450 5.18:1 · AA text
  • --color-neutral-600 #5c4733 8.11:1 · AA text
  • --color-neutral-700 #432f1f 11.71:1 · AA text
  • --color-neutral-800 #2f2015 14.57:1 · AA text
  • --color-neutral-900 #20150d 16.60:1 · AA text

Typography

Type scale

Fraunces, a serif, for headings; Source Sans 3 for body copy. Every heading step is a fluid clamp(), so type scales with the viewport instead of jumping at a breakpoint, while body copy stays at 16px with a 1.65 line-height.

  • Roasted in small batches --text-4xl — Hero headline
  • Roasted in small batches --text-3xl — Section heading
  • Roasted in small batches --text-2xl — Sub-section heading
  • Roasted in small batches --text-xl — Card title
  • Roasted in small batches --text-lg — Lead paragraph
  • Roasted in small batches --text-md — Eyebrow heading (h6)
  • Roasted in small batches --text-base — Body copy
  • Roasted in small batches --text-sm — Supporting text, nav links
  • Roasted in small batches --text-xs — Eyebrows, meta, utility bar

Accessibility

Focus states

Every interactive element shows a 3px ring on keyboard focus. The samples below render the ring permanently so it can be checked in a screenshot, on each of the three surfaces the theme uses.

Ring on page background Ring on primary button
Ring on a dark band

Measured ring contrast

  • Focus ring on page background — --focus-ring-color on --color-bg, 7.84:1 against its surface (meets the 3:1 non-text minimum).
  • Focus ring on dark bands and the footer — --focus-ring-color-inverse on --color-neutral-900, 13.32:1 against its surface (meets the 3:1 non-text minimum).
  • Focus ring on a primary button — --focus-ring-color-on-primary on --color-primary-600, 3.12:1 against its surface (meets the 3:1 non-text minimum).
  • Body text on page background — 14.57:1 (meets WCAG AA for body text).
  • Muted text on page background — 8.11:1 (meets WCAG AA for body text).
  • Primary button label — 5.33:1 (meets WCAG AA for body text).
  • Active nav link — 7.84:1 (meets WCAG AA for body text).
  • Footer body text — 10.39:1 (meets WCAG AA for body text).
  • Footer link — 15.10:1 (meets WCAG AA for body text).

Spacing

Spacing scale

An 8px-based scale. Layout utilities only ever consume these tokens — never arbitrary pixel values.

  • --space-1
    0.25rem
  • --space-2
    0.5rem
  • --space-3
    0.75rem
  • --space-4
    1rem
  • --space-5
    1.25rem
  • --space-6
    1.5rem
  • --space-7
    1.75rem
  • --space-8
    2rem
  • --space-9
    2.25rem
  • --space-10
    2.5rem
  • --space-12
    3rem
  • --space-16
    4rem
  • --space-20
    5rem
  • --space-24
    6rem
  • --space-32
    8rem

Rhythm

Containers and section padding

Every band is a .section (vertical rhythm) wrapping a .container (max-width plus adaptive gutters).

--space-section
Default section padding, clamp(4rem, 8vw, 7rem).
--space-section-sm
Compact band, clamp(2rem, 5vw, 3rem).
--space-section-lg
Feature band, clamp(5rem, 10vw, 9rem).
--container-gutter
Adapts: 1.25rem mobile, 1.5rem at 600px, 2rem at 900px, 2.5rem at 1200px.

Breakpoints

Mobile-first breakpoints

Base styles target the smallest screen. Every media query in the theme is min-width only.

min-width: 600px
Large phone / small tablet — two-column grids engage.
min-width: 900px
Tablet / small laptop — three-column grids and split layouts engage.
min-width: 1200px
Desktop — four-column grids and the widest gutters engage.

Grids

Grid utilities

All three collapse to a single column below 600px.

.grid--2

1 / 2
2 / 2

.grid--3

1 / 3
2 / 3
3 / 3

.grid--4

1 / 4
2 / 4
3 / 4
4 / 4

Buttons

Button variants and states

Copper is the only conversion colour. Every button is at least 44px tall, keeps a 3px focus ring on keyboard focus, and dims when disabled.

.btn--primary

Shop the roasts

.btn--secondary

Our story

.btn--ghost

Read the brewing guide

core/button block

Editor buttons inherit the same shape through targeted selectors, so block content never falls back to browser defaults.

Forms

Form controls

Every control is built by harbor_coffee_roasters_form_field(), which always renders a visible label tied to the input by id. Placeholders are hints only.

We only use this to reply to your enquiry.

Enter a volume of 1kg or more.

Grind

Something was missing — check the highlighted fields and try again.

Thank you — your enquiry is on its way to the roastery.

Media

Responsive images and split layout

Images are capped at max-width:100% with height:auto, so nothing overflows a 320px viewport.

Coffee beans resting after a roast at Harbor Coffee Roasters

.split

Stacked on mobile, 60/40 from 900px up. Use .split--reverse to put the media on the right, or .split--even for equal halves.

Components

Hero

template-parts/components/hero.php — full-bleed photography behind the token gradient overlay, a display heading and up to two CTAs. The hero image is the only image on a page that is not lazy-loaded.

Roasted in small batches

Coffee with a roast date, not a sell-by date

Beans sourced season by season and roasted the morning they ship.

Shop whole bean Our story

Components

Product cards

.card--product in a .grid--4: one column on mobile, two from 600px, three from 900px and four from 1200px. The whole card is a single link, so there is one tab stop per card.

Components

Article and feature cards

.card--article crops its media to 16:9 and renders the date in sentence case; .card--feature drops the border and shadow for quieter "our craft" strips.

A sack of pale green unroasted coffee beans

Sourced season by season

We buy from the same farms year after year and publish what we paid. A feature card carries no link, so it stays out of the tab order.

Components

Testimonial cards

.card--testimonial has no media: a serif-scale quote, the attribution pinned to the bottom of the card and no link at all.

The Ethiopian is the first bag that made me want to weigh my coffee. Roast dates on every label, and it arrives the next morning.

Priya N. Monthly subscriber

We pour Harbor across all three of our cafes. Consistent espresso, honest sourcing and a team that actually answers the phone.

Tom Whitfield Wholesale partner

I came in for a bag and left with a brewing lesson. The guides on the site are what finally fixed my grind size.

Marco R. Shop customer

Bands

Cards on a dark band

Cards keep their cream surface on a dark band, so cards.css restates the text colours there — never light text on a light card.

Bands

Dark feature band

Section backgrounds and text colours both come from tokens, so every band stays readable as a pair.

--color-primary-600
--color-primary-700
--color-accent-500
--color-neutral-700