Ines Keller

Logistics design system

Poster of six stepped pixel marks on a two by three grid in graphite, off-white and safety orange: ring BOOKED, triangle IN TRANSIT, square AT HUB, disc DELIVERED, diamond HOLD, warning triangle DAMAGED. A footer reads KESSEL NORM.

One design system for a Swiss freight forwarder: 60 legacy screens, four teams, gloves, 1-bit labels, 40 rows on one screen, and no rewrite allowed.

Brief

Kessel Freight runs pallet networks between Basel, Milan and Rotterdam. Four teams maintain dispatch software, warehouse handhelds, a customer portal and label printing. Together that was 60 screens, three button styles and no shared word for a held consignment: dispatch said "gesperrt", the portal said "on hold", and the handhelds showed a red row.

I was asked for a design system. The actual request was that a dispatcher, a forklift driver and a customer should be able to talk about the same pallet.

Dispatch board on Tuesday 17.10.2023 at 14:32. Forty rows of consignments on twelve trips between Basel, Milan and Rotterdam, each with a status mark and word, consignment number such as KF23-104204, route, customer, pallets, kilograms, ETD and ETA. Six status counts sit above it; the footer totals 250 pallets and 100'754 kg.
Dispatch board, compact density. 40 rows at 20 px, 12 trips, one selected.

Constraint

Each surface fails in a different way. Handhelds are used with gloves in loading bays with low sun, so anything under 56 px gets missed. Thermal printers have 8 dots per mm and one bit per dot, so a colour-coded status does not survive the label. Dispatchers wanted 40 rows on one screen and had 26.

No rewrite was allowed. There was no migration budget and no freeze on delivery, so every screen had to change inside a ticket that was already open for another reason.

Black and white 1-bit shipping label, 100 by 150 mm at 800 by 1200 dots, for pallet 03/06 of consignment KF23-104204, 356 kg, from Birs Feinmechanik AG in Reinach BL to Merwede Hydrauliek B.V. in Schiedam. RTM routing block, four handling marks with German and Italian words, BOOKED status mark, and a GS1-128 barcode for SSCC 3 7640187 010420403 8. An orange band carries a millimetre ruler and print specification.
Pallet label KN-11. Pure black and white, 1 dot = 3 image pixels.
Handheld load scan screen, trip L4406 from BSL to RTM at dock B07. An orange band reads SCAN PALLET 4 OF 6, a large figure shows 3/6, and rows list pallets 03 and 02 as AT HUB and pallet 04 as BOOKED, with weights. Two 72 dp buttons read DAMAGE and TYPE SSCC.
Load scan, same consignment at 14:32. Handheld density, no target under 56 dp.

Decisions

Density became a token. A screen sets compact, comfortable or handheld once, and row height, control size, padding, type and mark size follow. I tried a separate handheld library first and dropped it after two weeks, because the same table was being specified twice with different numbers.

The status language starts from the worst output, the label. If a status cannot print as black dots at 12 mm it is not a status. So there are six marks, drawn on a pixel grid, each always paired with its word. Colour only adds urgency: orange is reserved for HOLD and DAMAGED, and the other four are graphite. White on orange fails at 3.1:1, so text on orange is graphite at 5.4:1.

Density sheet: bands drawn at 8× with numerals 20, 32 and 56 on off-white, graphite and orange, the same row at 1× beside each, a spacing scale from 4 to 56, and a token table for compact, comfortable and handheld.
Density and spacing.
Colour tokens: large slabs of signal.orange #FF5A00 and graphite.900 #1B1E21 with ratios 5.4:1 and 14.7:1, six smaller swatches, and a nine by nine matrix of computed WCAG contrast ratios graded AAA, AA or L.
Colour and contrast, computed.
Twelve marks on a 24 pixel grid: status marks BOOKED, IN TRANSIT, AT HUB, DELIVERED, HOLD and DAMAGED, each also shown at 24, 16 and 12 px, and handling marks THIS WAY UP, FRAGILE, KEEP DRY, DO NOT STACK, NO HOOKS and CENTRE OF GRAVITY in white on graphite.
Status and handling marks.
Migration tracker dated 15.12.2023 headed 52/60, with counts of 52 migrated, 5 in progress and 3 not started, a stepped chart climbing from 3 in February to 52 in December, and all 60 screens listed by team with density and month.
Migration tracker, 60 screens.
Engineering-style specification sheet KN-03 at scale 2:1 with orange dimension lines: table, status marks and buttons in three columns for compact, comfortable and handheld, measuring rows of 20, 32 and 56 px and buttons of 24, 32 and 56 px. A title block lists revision C, 14.03.2023, and notes that rev. B with an 18 px row failed.
Sheet KN-03 rev. C. Drawn at 2:1, measured at 1×.

One table

The audit found 37 screens that were a table with a toolbar, built five different ways. I put most of the design effort into one Table component and left forms for later. It carries sorting, grouping rules, status cells and tabular figures, and takes its numbers from the density token.

The first compact row was 18 px. It fit 44 rows, and the type fell below 11 px, so dispatchers zoomed the browser and lost the gain. At 20 px it holds 40 rows with 12 px type, which was the request. Rev. B of the sheet records the failure.

Documentation page Tokens / Density on the Kessel Norm site, version 2.4.0. A token table sits above four graphite code panels showing the same values as tokens.css for dispatch, _tokens.scss for the portal, Tokens.kt for handhelds and label_tokens.py for label printing, which notes that no colour tokens exist.
One source, four outputs. norm-tokens 2.4.0.

Adoption

Tokens are published to the four codebases as CSS, SCSS, Kotlin and Python from one source file. I rejected a shared component library across all four, because the stacks have nothing in common and the handheld team would have been waiting on web releases.

A screen moves when a delivery ticket already touches it, and the team closes the row itself once the lint finds no raw colour or size value. The tracker uses the status marks for its own states. Three screens have not started: telematics import, label download and API keys. Nobody has had a reason to open them.

“We stopped phoning the dock to ask what a red row meant. It says HOLD now, on the board, on the scanner and on the pallet.”
Regula StöckliHead of Operations, Kessel Freight

Result

By 15 December 2023, 52 of 60 screens had moved, with no rewrite and no migration sprint. Missed taps on the load scan screen fell from 1 in 14 to 1 in 61 between the February and October handheld logs. The dispatch stylesheet went from 214 kB to 38 kB, mostly by deletion.

The handling marks are still weak at 24 px on screen. They were drawn for the label at 96 dots, and I would redraw three of them if I went back.

52/60
Screens migrated in eleven months
40
Rows in view on the board, up from 26
37
Screens built on one Table component
1
Button style, down from three

Credits

Design
Ines Keller
Token pipeline and dispatch
Marco Aebi
Handheld engineering
Tomasz Wrona
Customer portal
Giulia Ferrante
Label printing
Pieter de Graaf
Dispatch research
Sandra Brunner

Next project

Specialty food packaging

Sauerhof, 2022