Nº 511 of 520
Phone past orders
A Sablecroft list of past orders with status, date, count, and total, opening in place to items, a status sentence, and a receipt.
Preview
Use it
Free to use · credit appreciated1 Once, in your project
npx skills add SusanAcharya/Design-Lounge 2 Then ask
Using the Design Lounge skill, build "Phone past orders" (piece phone-orders) in my stack. Match its brief; restyle it onto my product's theme.
No skill? Paste the brief instead. It carries the numbers, tokens and behaviour.
<!-- Design Lounge Nº 511 · "Phone past orders" · www.designlounge.live -->
# Phone past orders
> **Build brief for a coding agent.** Rebuild this piece in the reader's stack. If they haven't said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don't "improve" them. When a kit is locked, map colours onto the kit tokens. This is an iOS list of past orders. It is not a live map and it is not a tracker.
## What it is
The orders screen of Sablecroft, an invented wool mill, on a phone. The language is iOS: a large title, separate inset cards, a back chevron in the mill green, 44px targets, and 54px of clearance under the status bar. The Lounge draws the status bar. Do not draw one, and do not draw a map, a route, or a courier dot.
The first frame is a list of past orders. Each card shows a status (delivered, on the way, or cancelled), the date, the item count, and a total. The total is computed in cents from the line items plus delivery. Tapping a card pushes a summary over the list in the same file: the items, one status sentence, and a receipt. A cancelled order says why in one sentence, on the list and again in the summary. There is no second document.
Besley carries the words. IBM Plex Mono carries order ids and money, so the figures read as a mill ledger.
## Reference behaviour
1. First frame is the list. The lede is computed: "{n} orders from the Greyhaven mill." With the three orders below, it reads "3 orders from the Greyhaven mill."
2. Cards, newest first:
- SC-1904, 2 Oct 2026, status On the way. Field beanie, Moss, 2800 cents, quantity 1. Wool socks, Oat, one pair, 1600 cents, quantity 2. Delivery 400 cents. Count 3. Total 6400 cents, shown as $64.00.
- SC-1866, 18 Sep 2026, status Delivered. Merino crew, Oat, 4200 cents, quantity 1. Delivery 600 cents. Count 1. Total 4800 cents, shown as $48.00.
- SC-1791, 3 Sep 2026, status Cancelled. Indigo chore coat, Indigo, 7200 cents. Wool cap, Charcoal, 1250 cents. Twill tape, 5 metres, 700 cents. Each quantity 1. Delivery 0. Count 3. Total 9150 cents, shown as $91.50. The card also shows the sentence "The indigo dye lot failed its wash test."
3. On the way uses amber `#7a4510` for the word and the 8px dot. Delivered uses moss `#1b4f3e`. Cancelled uses brick `#7c332c`. The word always sits next to the dot. There is no coloured edge on the card. Colour is not the only signal.
4. A note under the list reads "Cancelled orders are not charged." It is not a second total. The $91.50 is the order's goods total. The note says that order was not charged.
5. Tapping a card stores that button, fills the detail from the same order object, unhides the detail, marks the list `inert`, and slides the detail in from the right over 320ms with `cubic-bezier(.32, .72, 0, 1)`. Focus moves to the back button. The live region says "Opened order SC-1904, On the way."
6. The detail shows the status word, the order id as the `h1`, the date and the item count, then the status sentence, then an Items group, then a Receipt group.
7. Status sentences, one each, not a map:
- On the way: "On the way. It left Greyhaven on Thursday and should arrive by Tuesday."
- Delivered: "Delivered on 20 Sep 2026. It was left at the side door."
- Cancelled: "The indigo dye lot failed its wash test." That is the same sentence as the list. Do not add a second reason.
8. Item rows show the name, the line amount (unit cents times quantity), and the variant. If quantity is greater than 1, the variant line also says the unit price and the quantity. Wool socks reads "Oat, one pair. $16.00 each, quantity 2." and the line amount is $32.00.
9. The receipt has three rows, all from cents: Subtotal (sum of line amounts), Delivery (the order's ship cents, including $0.00), Total (subtotal plus delivery). For SC-1904 that is $60.00, $4.00, $64.00. The list price and the receipt total are the same number.
10. Back, labelled "Back to orders" with the visible word Orders, slides the detail out, hides it, clears `inert` on the list, and focuses the card that was opened. Escape does the same while the detail is open.
11. Reduced motion: the detail appears and disappears with no slide and no 320ms wait. The content is the same.
12. There is no refresh, no map, no courier name, and no live position.
## Structure
```
390 x 844, list view fills the body
+--------------------------------------+
… 228 more lines. Copy or download for the full brief. Loading the source…Brief
268 linesBuild brief for a coding agent. Rebuild this piece in the reader’s stack. If they haven’t said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don’t “improve” them. When a kit is locked, map colours onto the kit tokens. This is an iOS list of past orders. It is not a live map and it is not a tracker.
What it is
The orders screen of Sablecroft, an invented wool mill, on a phone. The language is iOS: a large title, separate inset cards, a back chevron in the mill green, 44px targets, and 54px of clearance under the status bar. The Lounge draws the status bar. Do not draw one, and do not draw a map, a route, or a courier dot.
The first frame is a list of past orders. Each card shows a status (delivered, on the way, or cancelled), the date, the item count, and a total. The total is computed in cents from the line items plus delivery. Tapping a card pushes a summary over the list in the same file: the items, one status sentence, and a receipt. A cancelled order says why in one sentence, on the list and again in the summary. There is no second document.
Besley carries the words. IBM Plex Mono carries order ids and money, so the figures read as a mill ledger.
Reference behaviour
- First frame is the list. The lede is computed: “{n} orders from the Greyhaven mill.” With the three orders below, it reads “3 orders from the Greyhaven mill.”
- Cards, newest first:
- SC-1904, 2 Oct 2026, status On the way. Field beanie, Moss, 2800 cents, quantity 1. Wool socks, Oat, one pair, 1600 cents, quantity 2. Delivery 400 cents. Count 3. Total 6400 cents, shown as $64.00.
- SC-1866, 18 Sep 2026, status Delivered. Merino crew, Oat, 4200 cents, quantity 1. Delivery 600 cents. Count 1. Total 4800 cents, shown as $48.00.
- SC-1791, 3 Sep 2026, status Cancelled. Indigo chore coat, Indigo, 7200 cents. Wool cap, Charcoal, 1250 cents. Twill tape, 5 metres, 700 cents. Each quantity 1. Delivery 0. Count 3. Total 9150 cents, shown as $91.50. The card also shows the sentence “The indigo dye lot failed its wash test.”
- On the way uses amber
#7a4510for the word and the 8px dot. Delivered uses moss#1b4f3e. Cancelled uses brick#7c332c. The word always sits next to the dot. There is no coloured edge on the card. Colour is not the only signal. - A note under the list reads “Cancelled orders are not charged.” It is not a second total. The $91.50 is the order’s goods total. The note says that order was not charged.
- Tapping a card stores that button, fills the detail from the same order object, unhides the detail, marks the list
inert, and slides the detail in from the right over 320ms withcubic-bezier(.32, .72, 0, 1). Focus moves to the back button. The live region says “Opened order SC-1904, On the way.” - The detail shows the status word, the order id as the
h1, the date and the item count, then the status sentence, then an Items group, then a Receipt group. - Status sentences, one each, not a map:
- On the way: “On the way. It left Greyhaven on Thursday and should arrive by Tuesday.”
- Delivered: “Delivered on 20 Sep 2026. It was left at the side door.”
- Cancelled: “The indigo dye lot failed its wash test.” That is the same sentence as the list. Do not add a second reason.
- Item rows show the name, the line amount (unit cents times quantity), and the variant. If quantity is greater than 1, the variant line also says the unit price and the quantity. Wool socks reads “Oat, one pair. $16.00 each, quantity 2.” and the line amount is $32.00.
- The receipt has three rows, all from cents: Subtotal (sum of line amounts), Delivery (the order’s ship cents, including $0.00), Total (subtotal plus delivery). For SC-1904 that is $60.00, $4.00, $64.00. The list price and the receipt total are the same number.
- Back, labelled “Back to orders” with the visible word Orders, slides the detail out, hides it, clears
inerton the list, and focuses the card that was opened. Escape does the same while the detail is open. - Reduced motion: the detail appears and disappears with no slide and no 320ms wait. The content is the same.
- There is no refresh, no map, no courier name, and no live position.
Structure
390 x 844, list view fills the body
+--------------------------------------+
| padding-top max(54px, safe-area) |
| SABLECROFT 12px tracked moss |
| Orders Besley 34px |
| 3 orders from the Greyhaven mill. |
| |
| On the way $64.00 |
| SC-1904 |
| 2 Oct 2026, 3 items |
| |
| Delivered $48.00 |
| SC-1866 |
| 18 Sep 2026, 1 item |
| |
| Cancelled $91.50 |
| SC-1791 |
| 3 Sep 2026, 3 items |
| The indigo dye lot failed |
| its wash test. |
| |
| Cancelled orders are not charged. |
| padding-bottom max(34px, safe-area) |
+--------------------------------------+
Detail, absolute, inset 0, translated off to the right until open:
| < Orders 44px |
| On the way |
| SC-1904 Plex Mono 26px |
| 2 Oct 2026, 3 items |
| On the way. It left Greyhaven... | italic 18px
| Items |
| Field beanie $28.00 |
| Moss |
| Wool socks $32.00 |
| Oat, one pair. $16.00 each, qty 2. |
| Receipt |
| Subtotal $60.00 |
| Delivery $4.00 |
| Total $64.00 |
- The list is a
section.viewthat scrolls. The detail is a secondsection.viewpositioned absolute,hiddenandinertandaria-hiddenon the first frame. - Each order is a
buttoninside anli. The whole card is the hit target.data-statusisway,delivered, orcancelled. - The detail back control is a
button. The order id is the detailh1withtabindex="-1". - Items are a
ul. The receipt is adivof three paragraphs. Section labels Items and Receipt areh2at 13px. - The list note is the last child of the list view, with
margin-top: auto, so it sits at the bottom when the list is short and scrolls after the cards when the list is long. - Dates are
timeelements withdatetime2026-10-02,2026-09-18, and2026-09-03. - No images. The card has no side stripe and no box-shadow. The dot is an empty
iwitharia-hidden.
Tokens
:root {
--bg: #e3e8e2;
--surface: #f3f6f2;
--ink: #17211c;
--ink-2: #3e4a42;
--line: #d3dbd4;
--moss: #1b4f3e;
--amber: #7a4510;
--brick: #7c332c;
--focus: #1b4f3e;
--serif: "Besley", Georgia, serif;
--mono: "IBM Plex Mono", ui-monospace, monospace;
--ease: cubic-bezier(.32, .72, 0, 1);
}
Card radius 14px. Gap between cards 10px. Page padding inline 16px. Hairline 1px --line. No drop shadow and no coloured side stripe. Moss is the brand and the delivered status. Amber is only “on the way”. Brick is only “cancelled”. The status colour is the word and the 8px dot only.
Typography
| Role | Family | Size | Weight | Line height | Tracking | Colour |
|---|---|---|---|---|---|---|
| Brand | Besley | 12px | 600 | 1.4 | 0.16em | --moss, uppercase |
| List title | Besley | 34px | 600 | 1 | -0.03em | --ink |
| Lede, date | Besley | 14px to 15px | 500 | 1.4 | 0 | --ink-2 |
| Status | Besley | 14px | 600 | 1.4 | 0 | status colour |
| Price, line amount | IBM Plex Mono | 14px | 500 | 1.4 | 0 | --ink |
| Order id on the card | IBM Plex Mono | 13px | 400 | 1.4 | 0.02em | --ink-2 |
| Cancelled why | Besley | 14px | 500 | 1.35 | 0 | --brick |
| Back | Besley | 17px | 600 | 1 | 0 | --moss |
| Detail id | IBM Plex Mono | 26px | 500 | 1.1 | -0.03em | --ink |
| Status sentence | Besley italic | 18px | 500 | 1.35 | 0 | --ink |
| Section label | Besley | 13px | 600 | 1.4 | 0 | --ink-2 |
| Item name | Besley | 16px | 600 | 1.4 | 0 | --ink |
| Variant | Besley | 13px | 500 | 1.4 | 0 | --ink-2 |
| Receipt total figure | IBM Plex Mono | 18px | 500 | 1.4 | 0 | --ink |
| Footnote | Besley | 13px | 500 | 1.4 | 0 | --ink-2 |
Besley is the voice of the mill. Mono is only ids and amounts. Do not set the status word in mono.
Motion
| Thing | Trigger | Property | From | To | Duration | Easing | Reduced motion |
|---|---|---|---|---|---|---|---|
| Open detail | card tap | transform | translateX(100%) | translateX(0) | 320ms | cubic-bezier(.32,.72,0,1) | instant, no wait |
| Close detail | Back or Escape | transform | translateX(0) | translateX(100%) | 320ms | same | instant, hide immediately |
| Card press | active | transform | scale(1) | scale(0.985) | browser active | n/a | no scale |
| Card hover | hover, fine pointer | background | --surface | #eaf0ea | instant | n/a | unchanged |
The detail is display: none via the hidden attribute until open, so the off-screen copy cannot widen the page. On open, clear hidden, then on the next two animation frames add is-open so the transform can run. On close, remove is-open, then after 320ms set hidden, inert, and aria-hidden again. Under reduced motion, skip the frames and the timeout.
Do not animate a map, a pulse, or a progress line. Nothing on this screen is live.
States
- Card resting: surface
#f3f6f2, radius 14px, padding 14px 16px. No border and no inset stripe. - Card hover (fine pointer): background
#eaf0ea. - Card focus-visible: 2px outline
--focus, offset 2px. - On the way: status word and dot
--amber. - Delivered: status word and dot
--moss. - Cancelled: status word and dot
--brick, plus the why sentence in--brickunder the date. Other statuses do not show a why line on the list. - Detail closed:
hidden,inert,aria-hidden="true", not in the tab order. - Detail open: list view
inert, back button focused, detail translated to 0. - Receipt total row: 1px top rule, figure 18px mono, label weight 600.
- No loading state and no error state. The three orders are already known.
- No empty list in this demo. If a product has zero orders, replace the list with one sentence and do not invent a tracker. That state is not on this frame.
Accessibility
- The list
h1is Orders. The detailh1is the order id, for example SC-1904. Section labels Items and Receipt areh2. - Each card is a
button. Its accessible name is the text inside it: status, price, id, date, count, and, for the cancelled card, the why sentence. Do not add a secondaria-labelthat drops the why. - The status dot is
aria-hidden. The word is the status. - Back button accessible name is “Back to orders”. The visible word is Orders, beside a chevron that is
aria-hidden. Min-height 44px. - Opening sets the list
inertand removesaria-hiddenfrom the detail. Closing reverses that and returns focus to the card. - Escape closes the detail only while
is-openis set. It does not do anything on the list. - One polite live region, visually clipped. “Opened order SC-1904, On the way.” and “Back to orders.”
- Dates are real
timeelements. - Hit targets: the card is the full row, well above 44px. Back is 44px tall.
- Contrast:
#17211con#f3f6f2is about 15.2:1.#3e4a42on#f3f6f2is about 8.5:1.#1b4f3eon#f3f6f2is about 8.6:1.#7a4510on#f3f6f2is about 7.2:1.#7c332con#f3f6f2is about 8.1:1. Status text clears 4.5:1 on the card. The dot repeats the word. They are not the only signal. - Focus ring is 2px
--moss, offset 2px. - The detail must not be reachable while it is closed.
hiddenplusinertdoes that.
Responsive rules
- The frame is 390x844. List header padding-top and detail padding-top are
max(54px, env(safe-area-inset-top)). The list note and the detail pad usemax(34px, env(safe-area-inset-bottom))under the last content. - At 360 wide, card padding stays. The status row wraps: the status is
flex: 1 1 8emand the price hasmargin-left: auto. The why sentence wraps inside the card. The order id does not overflow. - At the largest text size, cards grow. The status and the price stack. Item rows stack the name and the amount the same way (
flex: 1 1 8emon the name,margin-left: autoon the amount, variant atflex-basis: 100%). Receipt rows stack the same way. The list scrolls. The detail scrolls inside its own view. Nothing scrolls sideways. - At tablet width, stay one column of cards. Do not turn this into a split list and detail. The detail still covers the phone width. This screen is a phone.
- Do not draw a status bar, a map, or a home indicator glyph.
Acceptance checklist
Always
- The first frame is a list of past orders. Each shows status, date, item count, and a total computed in cents.
- Statuses used here are delivered, on the way, and cancelled. Each has a text label, not only a colour.
- A cancelled order states why in one sentence, on the list.
- Tapping a card opens a summary in the same file: items, one status sentence, and a receipt whose total equals the list total.
- The receipt is subtotal plus delivery, both in cents, including a $0.00 delivery when ship cents are 0.
- Back and Escape return to the list and restore focus to the card that was opened.
- There is no map, no route, and no live position.
- Cards and the back button are at least 44px tall. Top clearance 54px. Bottom clearance 34px.
- The closed detail is
hiddenandinert, so it cannot widen the page or take focus. - Reduced motion shows the detail without the 320ms slide.
This demo
- Brand Sablecroft.
h1Orders. Lede “3 orders from the Greyhaven mill.” - SC-1904 is On the way, 2 Oct 2026, 3 items, $64.00. Receipt is $60.00 + $4.00.
- Wool socks are $16.00 each, quantity 2, line amount $32.00.
- SC-1866 is Delivered, 18 Sep 2026, 1 item, $48.00.
- SC-1791 is Cancelled, 3 Sep 2026, 3 items, $91.50, with the sentence “The indigo dye lot failed its wash test.”
- The footnote reads “Cancelled orders are not charged.”
- Detail heading for the first card is SC-1904 in IBM Plex Mono 26px.
- Page background is
#e3e8e2. Cards are#f3f6f2. Delivered moss is#1b4f3e.
Implementation notes
One function feeds the list price and the receipt, so they cannot disagree:
function tally(order) {
let sub = 0, count = 0;
for (const it of order.items) {
sub += it.cents * it.qty;
count += it.qty;
}
return { sub, ship: order.ship, total: sub + order.ship, count };
}
function money(cents) {
const n = Math.max(0, Math.round(cents));
const whole = Math.floor(n / 100);
const frac = String(n % 100).padStart(2, '0');
return '$' + whole + '.' + frac;
}
Write the list from the array on startup. Do not paste $64.00 into the HTML.
Keep the detail out of the scroll width until it is opened:
.view.detail { position: absolute; inset: 0; transform: translateX(100%); }
.view.detail[hidden] { display: none; }
body.is-open .view.detail { transform: translateX(0); }
Open by clearing hidden and inert, setting the list inert, then adding is-open on a double requestAnimationFrame so the 320ms slide runs. Close by removing is-open and restoring hidden after 320ms. If prefers-reduced-motion: reduce matches, add is-open immediately and hide immediately on the way back.
Item copy when quantity is above 1:
const variant = it.qty > 1
? it.variant + '. ' + money(it.cents) + ' each, quantity ' + it.qty + '.'
: it.variant;
The line amount is money(it.cents * it.qty), not the unit price repeated.
Common mistakes:
- Do not add a coloured side stripe to rounded cards. The status dot and the coloured status word already carry the status.
- Hardcoding the card total and a different receipt total.
- Putting the cancelled reason only in the detail. The list has to say it too, in one sentence.
- Adding a map because the status says “On the way”. The sentence is the whole status. There is no map in this piece.
- Leaving the detail at
translateX(100%)withouthidden, which can make the page wider than 390px. - Forgetting to return focus to the card. The back button is not the end of the task.
- Using a photo, an emoji status, or a trademarked carrier name.
- Drawing a status bar.
Details
- Palette
- Type
- Besley · IBM Plex Mono
- Motion
- Subtle motion
- Build
- One session
- Tags
On the shelves