How the parts
behave together.
Components answer “what does this look like”. Patterns answer “what happens next”. Each one below is a composition that already ships in the product, with its purpose, its flow, the rules that keep it calm, and the states it has to handle.
Product browsing
Let someone find a coffee by how it tastes, not by SKU — search, roast filter and sort over one card component.
- 1Search matches name, origin and individual tasting notes.
- 2A scrolling roast rail filters, with live counts per roast level.
- 3Results announce their count to assistive tech as filters change.
- 4Cards carry overline, roast, serif name, notes, price and stock state.
- Sold-out lots stay browsable — they change the badge and CTA, never the layout.
- Tasting notes are capped at three on a card and shown in full on the product page.
- Empty results always offer a way back out, never a dead end.
Ordering & customisation
Turn a café round into about a minute on a phone: location, menu, customise, bag, checkout, confirmation.
- 1Choose collection from a café or delivery of beans by post.
- 2Build the round from the menu, quick-adding or customising in a bottom sheet.
- 3Size, milk, syrup and extra shots reprice live in the sheet footer.
- 4A sticky flow bar always shows item count, total and the next action.
- Identical configurations collapse into one line, so quantity does the counting.
- Steps already completed stay reachable; steps ahead do not.
- Nothing advances on an invalid step — the next action disables instead of failing later.
Checkout
One validated form that adapts to collection or delivery without becoming two separate checkouts.
- 1Fulfilment choice reshapes the form: collection slots, or address and postcode.
- 2Validation runs on submit, listing the count of fields needing attention in a toast.
- 3Promo codes and the free-delivery threshold resolve in the summary in real time.
- 4Placing the order awards bean stamps and issues a readable reference.
- Errors replace hints in place and are announced, never shown only as a red border.
- Every field keeps a visible label; placeholders are examples, not labels.
- Collection offers paying in café; delivery does not.
Loyalty
Make the reward legible at a glance, using the bean as the stamp rather than a points balance.
- 1Eight bean outlines fill as stamps are earned, one per drink or bag.
- 2A completed card converts to a reward held in the wallet until it is wanted.
- 3Rewards state plainly how many cards they cost and how many are still needed.
- 4Activity lists what earned or spent each stamp.
- Stamps never expire and rewards are never forced at the till.
- The card reads as one image to assistive tech: “5 of 8 stamps collected”.
- Latte fills the stamp; espresso outlines it. No third colour enters.
Location discovery
Answer the three questions people actually have: where, when is it open, and how long will it take.
- 1Each café leads with its room through an art-directed plate, then the practical detail.
- 2Hours, services, phone and what3words sit in a consistent order across all three.
- 3Prep time is shown as a badge so it can be compared at a glance.
- 4Deep links from the footer and confirmations scroll to the right café.
- Closed days are shown, not hidden, and are muted rather than removed.
- Every café ends with the same two actions: order for collection, or see the menu.
- Addresses use real address semantics, and phone numbers are dialable links.
Responsive contract
One adaptive experience across the 2025–2026 viewport matrix, not three fixed screenshots.
| Viewport | Size | Navigation | Grid | Sheets |
|---|---|---|---|---|
| Mobile compact | 360 × 800 | Tab bar + drawer | 1 column | Bottom |
| Mobile standard | 390 × 844 | Tab bar + drawer | 1 column | Bottom |
| Mobile large | 430 × 932 | Tab bar + drawer | 1 column | Bottom |
| Foldable | 600 × 960 | Tab bar + drawer | 2 columns | Bottom |
| Tablet portrait | 820 × 1180 | Drawer | 2 columns | Bottom |
| Tablet landscape | 1024 × 768 | Full header | 3 columns | Side |
| Laptop | 1366 × 768 | Full header | 3 columns | Side |
| Desktop | 1440 × 900 | Full header | 3 columns | Side |
| Wide | 1920 × 1080 | Full header | 3 columns · capped 1160px | Side |
Fluid, not stepped
Page gutters and every display size use clamp(), so type and spacing scale continuously between the fixed breakpoints.
No horizontal overflow
Horizontal rails are the only scrolling axis, and they are opt-in per component rather than a page-level accident.
Reduced motion honoured
Every transition and the bean loader collapse to near-zero duration under prefers-reduced-motion.