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.
--pw-blue
--pw-blue-ink
--pw-blue-soft
--pw-accent
--pw-accent-2
--pw-accent-soft
--pw-ink
--pw-ink-2
--pw-muted
--pw-rule
--pw-paper-2
--pw-surface-2
--pw-ok
Type
General Sans for headings through .serif, Plus Jakarta Sans for everything else.
.pw-phead__title.pw-title.pw-title--sm.pw-phead__introAn intro paragraph runs to about sixty-two characters a line, which is roughly where reading speed stops improving.
bodyBody copy. Sixteen pixels, line height 1.6. Australian English, no em-dashes.
.eyebrowButtons
One .pw-btn-primary per screenful.
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.
--pw-rcards, panels, images--pw-r-sminputs, pills, small buttons--pw-r-pillchips and badges only--pw-h-sm 32px--pw-h 44px, the default--pw-h-lg 52pxForm 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.
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.
