Design Lounge
Install

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

Open full size
390 × 844 · 11.8 KB · 287 lines

Use it

Free to use · credit appreciated

1 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.

Brief

268 lines

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
+--------------------------------------+
| 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.view that scrolls. The detail is a second section.view positioned absolute, hidden and inert and aria-hidden on the first frame.
  • Each order is a button inside an li. The whole card is the hit target. data-status is way, delivered, or cancelled.
  • The detail back control is a button. The order id is the detail h1 with tabindex="-1".
  • Items are a ul. The receipt is a div of three paragraphs. Section labels Items and Receipt are h2 at 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 time elements with datetime 2026-10-02, 2026-09-18, and 2026-09-03.
  • No images. The card has no side stripe and no box-shadow. The dot is an empty i with aria-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

RoleFamilySizeWeightLine heightTrackingColour
BrandBesley12px6001.40.16em--moss, uppercase
List titleBesley34px6001-0.03em--ink
Lede, dateBesley14px to 15px5001.40--ink-2
StatusBesley14px6001.40status colour
Price, line amountIBM Plex Mono14px5001.40--ink
Order id on the cardIBM Plex Mono13px4001.40.02em--ink-2
Cancelled whyBesley14px5001.350--brick
BackBesley17px60010--moss
Detail idIBM Plex Mono26px5001.1-0.03em--ink
Status sentenceBesley italic18px5001.350--ink
Section labelBesley13px6001.40--ink-2
Item nameBesley16px6001.40--ink
VariantBesley13px5001.40--ink-2
Receipt total figureIBM Plex Mono18px5001.40--ink
FootnoteBesley13px5001.40--ink-2

Besley is the voice of the mill. Mono is only ids and amounts. Do not set the status word in mono.

Motion

ThingTriggerPropertyFromToDurationEasingReduced motion
Open detailcard taptransformtranslateX(100%)translateX(0)320mscubic-bezier(.32,.72,0,1)instant, no wait
Close detailBack or EscapetransformtranslateX(0)translateX(100%)320mssameinstant, hide immediately
Card pressactivetransformscale(1)scale(0.985)browser activen/ano scale
Card hoverhover, fine pointerbackground--surface#eaf0eainstantn/aunchanged

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 --brick under 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 h1 is Orders. The detail h1 is the order id, for example SC-1904. Section labels Items and Receipt are h2.
  • 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 second aria-label that 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 inert and removes aria-hidden from the detail. Closing reverses that and returns focus to the card.
  • Escape closes the detail only while is-open is 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 time elements.
  • Hit targets: the card is the full row, well above 44px. Back is 44px tall.
  • Contrast: #17211c on #f3f6f2 is about 15.2:1. #3e4a42 on #f3f6f2 is about 8.5:1. #1b4f3e on #f3f6f2 is about 8.6:1. #7a4510 on #f3f6f2 is about 7.2:1. #7c332c on #f3f6f2 is 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. hidden plus inert does 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 use max(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 8em and the price has margin-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 8em on the name, margin-left: auto on the amount, variant at flex-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 hidden and inert, so it cannot widen the page or take focus.
  • Reduced motion shows the detail without the 320ms slide.

This demo

  • Brand Sablecroft. h1 Orders. 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%) without hidden, 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
Designed bySusan AcharyaKathmandu

Studied

Abel

A catalogue. One product at a time.

All sources