Skip to content

Free UK delivery over £50 · 3–5 working days from Rugby

HALDENOSLO
NotesDesign decisions, halden.noResearch and accessibilityBack to the shop

Why this storefront looks like a formula sheet.

Written by the designer, after the build. Roughly 1,200 words on typography, hierarchy, breakpoints and the one constraint I could not design my way out of. The evidence behind the decisions, and the accessibility audit, are on the research page.

01

The brief

Halden sells six skincare products and nothing else. The hero SKU is Barrier Serum 02, 30 ml, £48, and the person buying it knows precisely what a cheap serum costs. She is 28 to 45, she has been through The Ordinary, and somewhere in that she taught herself to read an INCI list. She is not looking to be inspired. She wants to know whether the niacinamide is 4% or 10%, whether the preservative is one she reacts to, and how many days it takes to reach her.

That reader decided everything else. Someone who reads ingredient lists has been misled by packaging before, and the fastest way to lose her is to sound like packaging. Where desk research pushed back on my instincts I have written it up separately on the research page.

02

Type, and why olive instead of gold

Instrument Serif is very high contrast and slightly odd: the terminals are cut at strange angles and the italic is genuinely narrow rather than a slanted roman. Above 100px it reads as a gallery catalogue rather than a beauty brand. I set it at 0.84 to 0.92 line-height and let ascenders and descenders very nearly collide, because a face with that much contrast looks nervous given generous leading.

Inter does everything else, kept small on purpose: 13 to 15px body, 10px for the letterspaced micro-labels numbering each section. The distance between a 115px headline and a 10px label is the entire typographic system. There is no mid-size type doing friendly-subheading work, because that size is where marketing voice lives.

On colour: bone ground, ink type, olive as the only accent. Clay does two jobs and no others. It draws every hairline, and it sets the body copy inside the dark Oslo band, where it measures 9.27:1 against ink. What clay never does is set type on bone, where it would run at 1.75:1. Muted copy there is stone, a darker warm grey, at 5.20:1. What I rejected hardest was gold: warm ivory plus gold is the standard costume for anything that wants to look expensive, and it would have turned this into a spa. Olive is a colder warm; it reads pharmacy rather than treatment room.

03

Layout, and the order the objections arrive in

Nothing here is centred. Above 1024px a fixed left rail, a hairline plus a rotated running head that tracks the section you are looking at via IntersectionObserver, anchors every column. It makes the asymmetry structural rather than decorative, and gives a long single-column page a permanent sense of place.

Above the fold there are four things: the product name, one paragraph about what the serum does not do, a six-row spec table (volume, pH, actives, ceramide fraction, unit price, batch number), then price and add-to-bag. The spec table is the conversion element, not the paragraph. For this customer £1.60 per ml and pH 5.4 ± 0.2 are more persuasive than any sentence I could write.

Then objections in the order they turn up. Delivery and returns immediately, as a hairline strip, because that is what everyone checks first and because unexpected extra cost is the most cited reason people abandon a basket. Then why the range is small, because a six-product brand must justify itself before it sells anything. Then the range as an index, rows with a sticky preview image rather than a grid of cards, because a grid implies browsing and this is a list you read. Then the formulation with declared percentages, which is the real argument. Then how to use it, who made it, reviews including the three-star one, and the eight questions the inbox actually receives.

Section numbers come from a single list in the data layer. The header nav, the mobile menu, the rail and the § labels on the page all read from it, so a section cannot be 04 in one place and 07 in another. It used to be exactly that, which is why the numbering now lives in one file.

04

Four bands, three layouts

At 1440 the hero is a 5/7 split, the photograph bleeding past the right edge of the container with its caption in the left margin. The index runs two columns; hovering or focusing a row cross-fades a large sticky image alongside it.

Between 1024 and 1279 the same two-column desktop layout applies, but the rail narrows from 86px to 68px and the container padding drops with it. That band is a 13-inch laptop and an iPad Pro in landscape. It used to get the desktop grid with no rail at all, which left a wide left margin doing nothing.

At 834 the rail goes, the hero stacks, and the index drops the sticky preview: there is no room for a 400px image and a legible row at once. Each row grows a 66px thumbnail instead. Every portrait crop on the page switches to landscape across the tablet band, because at 834 a full-width 4:5 image is 993px tall and pushes everything after it off the screen.

At 390 the index restacks so price sits beside the product name rather than below the description, and the four-column delivery strip becomes four stacked rules. The sticky buy bar is a sub-1024 behaviour rather than a phone-only one: it appears at 834 as well, once the hero has scrolled past, and hides again near the FAQ so it never covers the footer. It drops out of the tab order while hidden. The mobile nav is a full-screen panel carrying the same section numbers, because those numbers are the navigation.

05

The interactions

Five that matter. The cart drawer runs a live subtotal against the £50 free-delivery threshold with a hairline progress bar and a message telling you how much is missing, which is pointed given the hero product is £48. It is a real dialog: focus moves into it on open, is trapped while it is open, Escape closes it and focus returns to whatever opened it. The AM/PM builder swaps the recommended set, the step copy and the photograph, and recalculates a total that excludes the out-of-stock sunscreen while stating the full-set price as a plain figure rather than a struck-through one, because a strikethrough reads as a savings claim and there is no saving here. The formulation accordion opens groups independently, its concentration bars scaled against a 6% ceiling. Quick view opens a dialog with focus trapped and Escape wired. The restock form validates client-side, quotes back what you typed when it fails, and reads the address out on success.

06

One thing I had to work around

Instrument Serif ships one weight and no true small caps. So every micro-label here is Inter at 10px with 0.16em tracking, which is faked small caps in a second family. I tried Instrument Serif in uppercase at those sizes and the contrast collapsed: the thin strokes vanished below about 14px on a bone ground, which on a site arguing for legibility of detail would have been embarrassing. Two families doing two separated jobs was the honest fix, and a cold neutral label face against a warm serif turned out to be the better result anyway.

Built with Next.js and Tailwind. Photography licensed from Pexels and chosen from one photographer's shoot so the light matches across the whole site, which is doing more work than any single image.