Style guide

The components this storefront is built from, drawn with the live stylesheet. The written contract is docs/styleguide.md in the repository.

Colour

Tokens only. A hex code in a section is a bug. Yellow means "act here", so two yellow buttons in one view means neither is the primary action.

Blue / navy --pw-blue
Deep blue --pw-blue-ink
Soft blue --pw-blue-soft
Accent --pw-accent
Accent hover --pw-accent-2
Accent soft --pw-accent-soft
Ink --pw-ink
Ink 2 --pw-ink-2
Muted --pw-muted
Rule --pw-rule
Paper 2 --pw-paper-2
Surface 2 --pw-surface-2
OK --pw-ok

Type

General Sans for headings through .serif, Plus Jakarta Sans for everything else.

.pw-phead__title
Ceiling insulation
.pw-title
Section heading
.pw-title--sm
Smaller section heading
.pw-phead__intro

An intro paragraph runs to about sixty-two characters a line, which is roughly where reading speed stops improving.

body

Body copy. Sixteen pixels, line height 1.6. Australian English, no em-dashes.

.eyebrow
Trade & bulk

Buttons

One .pw-btn-primary per screenful.

Primary, large Primary Blue Default Ghost Small
On a navy band

Shape

A frame means "this is a thing apart from the page": something you pick, fill in or act on. It does not mean "this is a new subject". If in doubt, no frame.

12px--pw-rcards, panels, images
8px--pw-r-sminputs, pills, small buttons
999px--pw-r-pillchips and badges only
--pw-h-sm 32px
--pw-h 44px, the default
--pw-h-lg 52px

Form controls

Every control is --pw-h tall, so a row of them lines up without anyone nudging it. A required field is marked on its label, not in a legend.

4 digits

The page heading contract

Every page that is not the homepage opens the same way. The h1 lands 107px from the left and 231px from the top on every template. One h1 per page, no inline styles: npm run validate fails the build on either.

<div class="pw">
  <div class="pw-container pw-phead">
    {% render 'pricewise-breadcrumb' %}
    <h1 class="pw-phead__title">{{ section.settings.title }}</h1>
    <p class="pw-phead__intro">{{ section.settings.intro }}</p>
  </div>
</div>

.pw-phead owns its own top padding. Adding more in the section drops the heading below the line every other page sits on, which has now been fixed twice.

Audience

A visitor answers the home-or-business pop-up once and it is kept in the pw_business cookie. Anything for one audience carries the attribute and starts hidden; the header script unhides what matches.

<div class="pw-nav-item" data-pw-aud="trade" hidden> ... </div>

Every branch that can render the element needs it, not just the one with a drop-down. And verify by reading the rendered page, not by counting attributes: an audit of [data-pw-aud] elements once reported everything correct while the homepage trade block was leaking to consumers, because that block carried no attribute at all.