The design system that built the storefront

1dot1 began as a written spec and a design system, not a codebase. Before any of the storefront existed, the palette, the type scale, the spacing rhythm and every component were settled in a single document, and the site was then built from it.
That order is the whole argument. A component with a documented size, a documented hover and a documented disabled state is one somebody can build without stopping to ask what it should look like, and a scale with seven steps in it is a scale nobody quietly adds an eighth to. The document is kept in step with the build as details settle, so the two never disagree for long.
What follows is that system, section by section, with the reasoning behind each decision.
Colour
Thirteen tokens. Five of them carry the entire interface: white for the page, a warm grey canvas behind product art, a hairline for every border, a muted grey for secondary text, and near-black ink for everything else. The palette is near-monochrome on purpose. In a store selling wallpapers and animated loops, the products are the only things that should be shouting, and a chrome with opinions of its own would compete with them on every row of the grid.
Two pairs sit in the file that barely appear on screen. The indigo pair is used by exactly one element, the bundle sale pill. The amber pair is held in reserve and used by nothing at all right now, and the document says so rather than implying a usage that does not exist. Fixing the palette this tightly before the build started is what stops a storefront acquiring a fourth grey six months later; anything not on this list does not appear on the site.
Typography
Seven steps in Inter, and holding the line at seven is the point. Hero and Display both step down under 768px, which is written into the scale itself rather than left as a responsive afterthought somewhere in the components.
Every extra size in a scale is a decision handed to the next person, and a scale that grows a step to solve one heading rarely stops at one. Micro caps are the smallest thing on the site at 10px with wide tracking, and they carry the kind label above every product title in the catalog, which is why they get a documented line of their own rather than being treated as small body text.
Spacing
A 4px base and a scale that runs to 128. The number that actually does the work is 96, the vertical rhythm between page sections, and it appears often enough that documenting the scale without calling it out would miss the point of having one.
Radius and elevation
Both radius tokens are zero. Everything is square: cards, images, inputs, buttons, the lot. There are exactly two exceptions in the whole product, and the document names them both rather than leaving them to be discovered: the badge pill at 5px, and the quick-add button, which is fully round.
Naming the exceptions is the entire value of this section. An undocumented exception is indistinguishable from an inconsistency, and the next person to add a component has no way to tell whether the rounded thing they found was a decision or a mistake. The same logic applies to shadows, of which there are four in the entire product, listed by name.
Layout
A 1376px container, 16px of side padding that becomes 32px from 768px up, and a 72px sticky header with a single hairline underneath it. The focus ring lives here too, specified once and applied site-wide, because an accessibility affordance that gets redefined per component is one that will be missing from something.
The header
The logo and the navigation form one left-aligned group rather than the more common logo-left, nav-centred arrangement. On the right sit the currency selector, search, account and bag.
One small decision is worth pulling out: the cart count is plain tabular text beside the bag, not a coloured bubble. A badge bubble is a notification pattern, and it carries an implication of urgency that a count of items someone deliberately put in their own basket does not have.
The product card
This is the component the whole catalog is built on, so it got the most attention. The media panel is a square canvas tile with the artwork inset and centred inside a 3:2 box. The badge sits top-right. Hovering tints the panel from canvas to hairline over 200ms. Below it sits a micro kind label, the title, an optional star row, and the price.
The inset is the decision that matters. This catalog mixes 8K wallpapers with spreadsheet templates and Claude skills, and a full-bleed treatment flatters the first group while making the second look like a mistake. Insetting everything on a consistent grey tile means a code starter and a gradient wallpaper sit in the same grid without one of them looking broken.
Quick add
Collapsed it is a 36px circle pinned to the bottom-right of the card artwork. On hover it expands to reveal an Add label. On success a check pops in over 220ms and its tick draws itself over a further 260ms after a short delay.
The confirmation is the reason the component exists. Adding to a cart from a grid, without leaving the grid, only works if the buyer can tell it happened, and a check that draws itself reads as a response to the click rather than as decoration that was always going to play.
Buttons
Three variants at 48px: a solid ink primary, a white secondary with a 1px ink border, and a ghost that is really just an underlined text link. Three is the complete set, and a fourth would need a reason the other three could not cover.
Disabled is 50% opacity with pointer events off, not a grey fill. A grey fill invents a colour that exists nowhere else in the palette, and it detaches the disabled state from the button it belongs to. Opacity keeps a disabled primary recognisably the primary.
Badge pills
Four badges, plus a fifth pill for bundle sales that is the one place the indigo pair appears. Best seller and bundle are white with a hairline border; sale and free are solid ink with white text.
The split is deliberate. Sale and free are claims about the price, so they carry the same visual weight as each other. Best seller and bundle are claims about the product, and they sit back. Four is a ceiling rather than a starting point, because the card only ever shows one badge and every additional kind is another thing competing for that slot.
Inputs, and the select that is not a select
Fields are 48px, matching the buttons, with a hairline border that goes ink on focus. There is a textarea variant that is allowed to resize vertically and nothing else.
The select is a custom ARIA listbox rather than a native control, because a native select cannot be styled to match anything. That choice comes with a bill, and the document pays it in full: arrow keys move the active row, Home and End jump to the ends, Enter and Space commit, Escape closes without committing, and clicking outside dismisses. Rebuilding a native control means owning every behaviour it gave away for free, and writing them down is how that obligation survives the next refactor.
It has two trigger modes. One keeps a static label such as Sort and shows the current value only as a checkmark inside the panel. The other shows the selected option's label on the trigger. The first is for a control where the action matters more than the value; the second is for a plain value picker like the currency selector.
The catalog toolbar
Filters on the left, and on the right an item count, the sort select, and a grid-density toggle of two 40px square buttons. Below 768px the whole left side collapses into a single Filters button carrying a count of how many are active, opening a drawer from the right.
The active-filter count on the mobile button is the detail that earns its place. Once the filters are behind a drawer, the only thing standing between a buyer and an empty-looking catalog is a number telling them they narrowed it themselves.
The footer
A light trust strip, then a near-black body on a four-column grid: logo and newsletter on the left, then Shop, Studio and Help. This is the only place in the product where the palette inverts, and having exactly one such place is what stops dark sections appearing at random up the page.
The feedback widget
A floating button that opens a panel offering four things: give feedback, rate the experience, request a product, report a bug. All four land in the same admin inbox, tagged by kind.
The animation is an approximation of the macOS genie effect, and the document explains why it is built the way it is. A real genie warps a window along a curve, which CSS cannot do to a live DOM subtree. What sells the illusion is not the curve but the sense of being pulled out of the button, so the panel is two nested elements running on different timings: travel and scale on the outer one, a lagging vertical stretch on the inner one. The exit is deliberately faster and simpler, because nobody watches a panel they just dismissed.
Motion
Three motions exist in the entire product: the 200ms card hover tint, the quick-add check, and the feedback genie. Under a reduced-motion preference every one of them collapses to a plain fade or to nothing.
Listing all three in one place is what keeps the number at three. A motion section that describes principles instead of an inventory is a section that cannot tell you when a fourth animation has quietly been added.
Long-form text
Two separate treatments, and keeping them separate is the point. One styles HTML written by an admin in a rich-text editor, where the real job is defensive: capping embedded images to the column width, so a full-size image pasted into a product description cannot blow out the page. The other styles hand-written policy pages, where the job is readability at length, so it sets a 46rem measure and a taller line height.
Same site, two authors, two different failure modes. One stylesheet trying to serve both would do neither well.
What having the system first bought
Every component in the storefront was built against a written spec rather than an opinion formed at the moment it was needed. The 48px control height, the square corners, the two radius exceptions and the three permitted motions were all settled before there was a page to put them on, which is why they hold across pages built weeks apart by different passes of work.
The document is maintained rather than filed. When the build settles a detail the system did not anticipate, the system is updated to match, because a design system that stops being true is just a PDF. That is the difference between a document that gets opened and one that gets replaced by a screenshot in a chat thread.
Get the system
The full document is available as a single HTML page you open in a browser, with no build step and nothing to install. It ships with the consolidated prompt that produced it, written so it can be pointed at another project to produce the same document for a different product.