← Back to the screen

Design system portfolio

shopify-polaris, `Kiln & Co` — the record

The four direction lines behind this page, the generator command that produced its tokens, and the pairs it was measured against.

Merchant admin for a studio pottery in Victoria BC: the order index, and a bulk fulfillment gated by a typed confirmation.

Direction

Archetype: index. One list, the full width of the page frame, and a footer that states the count. No dashboard tiles sit over it, because the merchant opened this screen to work the queue.

Data stance: table-first, in Polaris's resource-list idiom. A row is an order with a status rather than a set of cells. The identifier cell carries the order number, the customer, and what is in the box. Only payment, fulfillment, and the total get columns of their own.

Density: Polaris default. 13px body text, 12px cell padding, 32px controls, and --p-space-* everywhere else. This page compresses nothing.

The bold thing: the selection state. Checking rows swaps the filter bar for the bulk-action bar in the same slot. Both occupants declare the 32px control height, so the slot is one box in either state and the table below it does not move. The destructive action in that bar opens a gate that asks for a typed phrase. Until the phrase matches, the destructive button is absent rather than disabled.

In the bar itself, cancelling is critical text on the button surface rather than a filled slab: it is the rarest action in that row, it sat four pixels from the most frequent one, and on a phone the wrap put the two side by side. The filled critical button now appears exactly once on the page, inside the gate, at the moment of commitment.

Generator

polaris_tokens.py --both

The audit that decided the theme:

polaris_tokens.py --contrast --theme light

The states on the page

  1. The index: nine orders, eight of them inside the active date filter.
  2. Selection: two or more rows checked, the header replaced in place.
  3. The typed confirmation. groundwork/packages/outcome/src/destructive.ts derives the phrase from the targets. One order gives its own number, #1046. Several give cancel 3 orders, so the phrase for a batch of one cannot clear a batch of three. The comparison trims, collapses whitespace, and lowercases.
  4. Filtered to nothing: the Refunded view under the last-30-days filter. Polaris treats this as a different empty state from "nothing yet", so it offers to clear the filters rather than to create an order. The date filter is a toggle rather than a chip that only removes: switched off it stays in place offering the window back, so the row never disappears and the table never shifts under the pointer.
  5. A name that breaks the column. Theodora Achebe-Lindqvist and Rowan Delacroix-Whitfield sit in the data on purpose.

Where focus goes

Every bulk action empties the selection, which hides the bar the button was in, so returning focus to the opener drops it on <body>. Focus lands on the banner that reports the outcome instead. After the typed gate it is handed over only once the dialog has actually closed, since focus cannot leave an open modal and closing one restores focus over anything set in the meantime.

The gate itself focuses the dialog, not the phrase field. The count, the targets and the refund total are what the screen is for, and dropping the caret into the input puts every one of them behind the reader.

Light only

Polaris ships one finished theme. In dark-experimental, color-text-brand, color-text-critical, and color-text-success are still the light values on a dark surface: 1.49:1, 1.40:1 and 1.31:1. That is why the theme's name ends in -experimental.

tokens.css applies that theme under @media (prefers-color-scheme: dark) with the guard :root:not([data-theme="light"]). The page pins data-theme="light" on <html> and declares color-scheme: light, which is the generator's own opt-out. A dark-preferring browser therefore gets the theme that passes. This is a recorded deviation from CONTRACT.md section 5.

Measured contrast

Every pair the page leans on, in WCAG 2.2:

APCA disagrees with WCAG at Polaris's 13px body size. That size is the system's published body scale and the contract's bar is WCAG 2.2 AA, so 13px stands.

Warnings kept, with the reason