All work

// Case study 05 · Retail commerce · Design system

The unhappy
path

A US activewear retailer briefed six page templates. What the pages kept running into was not layout — it was : the size nobody picked, the filter row with every chip in it, the hero image the merchandising team had not shipped yet. So the deliverable stopped being screens and became the component and state library the screens were assembled from. Below, the four artifacts that made the argument — rebuilt in code, and yours to break.

My role
Design system & templatesBegan on comps, ended on the system
Client
US activewear retailerOne line inside a five-brand house
Surfaces
PDP · PLP · HomepagePlus the component and state library
Shown here
RecreationsNo logos, no client photography
4
States on one button
27
Filter chips at max load(the row the grid had to survive)
5
Sister brands in one header

No performance metrics appear on this page. I do not have them, and I will not estimate them.

01 · The brief was pages

Six templates. Then the reason they broke.

The engagement started the way retail engagements usually start: design the product detail page, the listing page, the homepage, and the supporting templates around them. Comps. Redlines. Ship.

The pages were not the hard part. The hard part showed up the first time somebody asked a question the comps could not answer — what does the add-to-bag button say when no size is selected? There were four plausible answers and no rule, and the same shape of question was waiting behind every other component. A page is one answer to that question. A system is the answer to all of them.

So the scope moved. I kept delivering templates, and underneath them I defined the thing the templates were actually made of: a component library, a state taxonomy for each component, and a colour system where every value carried a job description instead of a mood.

Asked for
Six page templates, desktop and mobile, ready for build.
Delivered
The templates, plus the system they exposed the need for — components, states, semantic colour, and the redlines that made the handoff arguable rather than interpretive.
Why it mattered
The line sits inside a house of five sister brands sharing one global header. A decision made once on a page gets made five more times by somebody else. A decision made once in a system does not.
02 · The unhappy path

The button that had to say four things.

This product page is long. Details, sizing, shipping, recommendations, paired products, ratings, a wall of customer photos, two more carousels. By the time a shopper has read enough to decide, the thing they decide with is a thousand pixels above them.

So the add-to-bag action detaches and follows — and once it follows, it has to carry the whole variant transaction with it, including the ways that transaction fails. The most common add-to-bag failure is not a server error. It is an unselected size. Which makes the error state the most important state on the most important control on the highest-value page on the site.

Sticky add-to-bag · state machine Recreation — interactive

Speed Tank
$25.99 $59.95
Colour
Size
XS
Rule

Product name and prices are invented. The states, and the rule attached to each one, are the deliverable.

State 02 is the one worth arguing about. The obvious solution is a toast: leave the button saying Add to bag, and throw an error somewhere when it fails. We put the instruction in the button itself, because a toast is a message about a failure and a label is a description of what the control will do next. The shopper never gets told they did something wrong — the button simply tells them what it needs. Same information, no blame, nothing to dismiss, and it survives on a phone where a toast can land under a thumb.

A disabled button is a designer refusing to say why.
Djoaniel Hernandez · System note № 05
03 · The worst case

I designed the listing page with every filter on.

Filter chips are the easiest component in retail to design and one of the easiest to ship broken, because the comp always shows two or three of them. Nobody selects three filters. People select a colour family, then a couple of sizes, then a sleeve length, then change their mind and leave the old ones on.

So the specimen I designed against was the maximum: every colour, every size, every sleeve length, all applied at once. Push the chips yourself and watch the readout — the number that matters is not the chip count, it is the height of the row, because that height is subtracted from the products.

Listing page · filter row at load Recreation — interactive

New Arrivals 1,010 results Sort by ▾
Product name
$59.95
Product name
$79.95
Product name
$169.95
Product name
$69.95
Measured

Result count and product names are placeholder values, exactly as they were in the spec. The row height is measured live in your browser.

Three rules came out of that specimen. Chips wrap rather than scroll horizontally, because a horizontal chip rail hides the filters a shopper most wants to remove. Clear all is pinned first and never wraps away from the row, so the escape hatch cannot leave the screen when the mess is at its worst. And the grid keeps a fixed minimum above the fold regardless of chip count — the filters are allowed to get ugly, the products are not allowed to disappear.

04 · The gray homepage

The version nobody frames is the real deliverable.

The homepage went out twice: once dressed in campaign imagery, and once as gray boxes. The second one is the one I actually designed.

Because the person who touches this page every week is not the shopper. It is a swapping a hero, three promo tiles, a five-product rail and a give-back banner on a campaign cadence, through a CMS, with no designer in the room. If the layout only holds when the photography is beautiful, it does not hold. Every slot has to declare its ratio, its safe area, its character budget and what it does when it is empty — or the page degrades a little every week until somebody calls it a redesign.

Homepage template Recreation — toggle the fill

Welcome
Summer
Shop summer
Short
and sweet
Shop bottoms
Up
lifted
Shop bras
Top
it all
Shop tops
Summer's easiest picks
The
accessories shop
Shop accessories
Give back
Full width × 330px banner
Slot

Campaign photography belongs to the client and is not reproduced. In the populated state the palette itself stands in for the imagery — which is, conveniently, the point being made.

05 · Every colour has a job

A palette is not a mood board. It is an assignment sheet.

The colour documentation does not describe how the colours feel. Each value carries the job it is allowed to do, so that a developer, a merchandiser or the next designer can resolve a question without a taste debate. Two of the entries are arguments rather than choices.

Hex values on this page are shifted from the source palette. The assignments are the subject; the exact values are the client's.

Peacock
#7FAEAB
Attention, highlighted information, and calls to action. The identity colour — so it is rationed, not spread.
CTA
Meadow
#BDC690
Second in the palette. Pairs with peacock without competing with it.
Secondary
Tidal
#C2E0E8
Pop accent. Large fields and category moments, never type.
Accent
Peony
#FAC5C0
Accent that coordinates with the neutrals and provides a warm pop where fitting.
Accent
Dandelion
#DFB587
Complementary to peacock. The warm counterweight in a cool palette.
Support
Pink Sands
#F9DBD7
Neutral, not accent. Sits under content as a background tint.
Ground
Stone
#E9E6E1
The branded white. Backgrounds and supporting elements. Pure #FFFFFF was reserved for surfaces that need to read as raised against it — so "white" became a decision instead of a default.
Ground
Dusk
#3C4B54
The text black, and the only entry justified on legibility rather than taste. Softer and warmer than #000 to suit the brand, but held dark enough to clear contrast at 14px body copy. Every text colour is a contrast decision first and a brand decision second.
Text
Error / Success
System pair
Deliberately outside the brand palette. If failure and confirmation are drawn from brand colours, the brand starts meaning "something went wrong."
Semantic

The palette also shipped with PMS numbers, because this brand exists in stores. A colour that only resolves on a screen is half a colour system — the same peacock has to survive a printed tag, a window graphic and an OLED phone, and the one that governs all three is the one worth writing down.

And every field has seven.

The same discipline, one level down. A text input is not a rectangle; it is seven rectangles a developer has to be told about before they guess.

Default
Field label
 
With icon
Password
With button
Email address
Helper textSubmit
Hover / focus
Field label
Text entered
Error
Phone
(XXX) XXX-XX
Error message
Success
Field label
Text entered
Looks good
Empty-field highlight
Field label
Text entered
Inactive
Field label
 

Buttons carried the same treatment — four hierarchies, desktop and mobile, redlined to a 47px target.

06 · What I cannot show you

The honest edges of this one.

The client
Named nowhere on this page, by choice. No logos, no wordmarks, no store photography, no campaign imagery.
The screens
Every artifact above is a recreation I coded for this site, set in my own typefaces, from my own working files. Nothing here is a lifted screenshot.
The numbers
There are none. I do not hold post-launch analytics for this engagement, so there is no conversion lift quoted, no error-rate reduction, no time-on-task. An invented number would be worth less than the blank.
What is mine
The state taxonomy, the component and colour system, the template specs and the redlines. The photography, the merchandising and the brand identity were not.

The reason this project sits in a portfolio next to a banking data standard and a chatbot architecture is that it is the same job. Find the moment the system is asked a question it has no answer for, and answer it once, in a place where the answer survives the next person. In banking that moment was a missing valuation. Here it was a shopper who had not picked a size.