Counted from the modules rather than estimated. Customers carry three statuses, enquiries six, quotations five, bookings six. Nineteen distinct labels, and they all appear in registers that sit one click apart, so they have to belong to one another.
Nineteen separate badge designs is a legend nobody learns and a maintenance job nobody wants. So the badge is built from two independent dimensions instead: fill says whether a clock is running, colour says whose move it is. Five marks, learned once, and every one of the nineteen reads exactly.
Drawn fresh from the Untitled kit and the system’s ruled tokens, not restyled from the originals.
Each stage measured against the first, never against itself; an empty stage draws an outline, never nought per cent.
Fill inherits the rule you already adopted, solid for settled and hatched for open, and extends it with an outline for records where no clock is running at all. Colour is doing one job only, and it is the job an operator actually asks a register.
This is what a screenshot, a printed report and a colour-blind reader get. Fill still carries the whole "is a clock running" dimension, so the sheet does not collapse, but "Sent" and "Qualifying" become indistinguishable without reading them. That gap is exactly what colour is buying, and it is worth knowing the size of it.
Thirty-one pixel rows, unchanged from R1. The badge sits in a 17 pixel box so the row height never moves. E, Q and B have collapsed from three columns into one, because the funnel bar carries the shape and the mono numerals carry the exactness. That is two columns of width recovered, spent on making the register readable rather than longer.
You ruled it a primitive, so here is the whole family. The rule that keeps it honest: the first segment is always the whole, so the bar is a share of what came in and never of the widest bar on screen. Two funnels in different rows are directly comparable, which is the entire point.
Every other split I tried collapsed. Grouping by record type gives four families that mean nothing to a reader. Grouping by good and bad puts "Sent" nowhere. Grouping by lifecycle position makes "Active" and "Confirmed" look identical when one is a relationship and the other is a contract. Whose move it is, is the only question that survives all nineteen and it is the question an agent actually has.
Deep azure for ours, ochre for theirs, forest for won, brick for ended, graphite for resting. Five hues at low saturation, chosen so that a register with forty rows of badges does not look like a christmas tree, and so that a booking that is genuinely on fire can still shout above them later. The bright end of every hue is deliberately unspent, because severity, drift and breach still need somewhere louder to live.
One, badges do not cost row height: the row is still thirty-one pixels. Two, the register now scans on colour, which is what you wanted, and the eight Active and Inactive customers separate at a glance without reading a word. Three, the private row is a problem the badge system just solved by accident. It used to read three asterisks in a status column, which looks like broken data. Now it reads "Withheld" in a dimmed resting badge, which looks deliberate.
Quoted to issued to delivered on a booking. Raised to in progress to resolved on the service desk. Invoiced to received to settled on a customer balance. Searched to attached to sold on the marketplace. Every one of those is three stages that narrow, and every one of them is currently three unrelated numbers on a row.