Console — the system
One set of markup, two palettes. Every colour below is a token, so the light and dark artboards on this canvas are byte-identical except for the twelve lines that define the palette. Status hues and the violet accent are the values already shipping in ClickPay’s token file.
Surfaces and ink
bg
surf
surf2
surf3
ink
ink2
ink3
ink4
accent
ok
warn
bad
accent-soft
ok-soft
warn-soft
bad-soft
Type
Screen title Restock 17 / 600 / -1.5%
Section Inventory 14 / 600
Nav item Marketplaces 12.5 / 400
Table cell Coil Spring Toy, jumbo 12 / 400
Figure 4,000   $7,120   28.1% Plex Mono, tabular
Column head Order qty 10 / 500 / 6% caps
Band label Decision 9.5 / 10% caps
Controls — 28px, one step tighter than today’s 32
Create PO
Export
Disabled
Delete
cover < 45d
supplier: any
+ filter
All
Amazon
Walmart
Temu
Received Landed 138d late Staged Dismissed ⌘K esc g i
Table
Identity
Risk
Decision
UID Product Cover Runway Order qty Value
PB038 Coil Spring Toy — selected row 6d 4,000 $7,120
PB224 Therapy Putty — default row 34d
SW043 Baby Scale Tray — healthy row 128d
row 26pxcell pad 0 / 10head 10px capsdivider edge2band divider on group changefigures right, tabular
A column is never narrower than the value it holds A figure that renders as 184,2… is worse than no figure at all: it reads as data while being unreadable. Column widths are therefore derived, not chosen by eye — each one is sized from the widest string its formatter can produce, plus the 10px padding either side, plus the uppercase header label, which is often the widest thing in the column. When the derived widths will not fit the window, columns come out — they stay reachable through the Columns control and the horizontal scroll — rather than every column shrinking until the numbers break. Only free text may ever truncate, and it truncates with the full value on hover.
What the density buys
today, 36px rows18 rows
console, 26px rows27 rows
Half again as many products in view before scrolling, on the same 900px window — and the column bands mean 42 columns can stay available without reading as one undifferentiated run.
Token values
Token Dark Light Used for Token Dark Light Used for
bg#0f1217#f9fafbchrome: header, rail, nav accent#a78bfa#7c3aedprimary action, active tab
surf#161a21#ffffffcontent area, table accent-soft#2b2350#f5f3ffactive rail, staged pill
surf2#1c212a#f9fafbselected row, footer bar ok#34d399#047857healthy cover, good ACoS
edge#262d38#e5e7ebpanel hairline warn#fbbf24#d97706tightening, above target
edge2#1f2530#f3f4f6row divider, band divider bad#fb7185#e11d48stockout, waste, late
ink#e9edf4#111827primary text, figures info#38bdf8#0284c7in transit, neutral state
ink3#8a94a6#6b7280column heads, captions ink4#5d6878#9ca3afempty values, key hints
The light column is ClickPay’s current shipped palette unchanged; the dark column is the dark block already in the token file. Console does not introduce a new colour — it changes what the density and the navigation do with them.
Added after the first round
Six rounds of revision added five controls and four patterns that appear on more than one screen. Anything used twice belongs here, or the next screen invents its own version of it.
The two filter exits
where The filter bar of all 22 tables, immediately after the last chip.
save as view Keeps the filter. Appears in the context column under Saved views with a live count. Writes nothing, ever.
make a rule The same filter, but it acts. Arrives pre-filled and stays bound to the filter — edit one, the other follows.
A filter you cannot keep is a filter you retype. One fork, one place, every table.
Three temporal controls, not one
window A measurement over a span. Always carries what it is compared against, and an amber dot while the range includes days whose fees have not settled.
event date A record with several dates of its own. Asks WHICH date before the range, because a PO is ordered, expected, received and closed.
basis window Changes a computed figure rather than filtering rows. Move Restock’s velocity window and the reorder quantity moves with it.
21 screens carry one of the three. Rules, the tab map and this sheet carry none, because nothing on them is a measurement.
The sidebar is yours
resize Drag the right edge: 148px to 320px. Remembered per person, not per screen — a navigation width that changes as you move screens is worse than no setting at all.
collapse The chevron in the heading folds it to the 56px rail. The content area takes the 188px, which on a 1440 board is the difference between scrolling a table and not.
peek While collapsed, hovering the rail slides the column out at the width you dragged it to — overlaying the content, never pushing it.
Peek overlays on purpose. If it reflowed, the table would jump sideways every time the cursor crossed the rail and the row under the pointer would move out from under it.
When a row opens
aligned sub-rows Only when the children are the same shape as the parent — a purchase order’s lines, a run’s actions. They sit under the parent’s own columns and are part of the same table.
a detail panel When they are not. Restock’s velocity derivation, a per-marketplace grid and a 21-month forecast have no business pretending to be columns, so the panel breaks the grid completely and the parent stays a row.
never a nested table A nested <table> silently breaks every column measurement in the repo, so the guard refuses to build one.
Getting this wrong is what made the first Restock panel unreadable.
What the AI is allowed to do
it proposes An agent reads and proposes. Not one of the eight has write access to a marketplace, and the permission columns exist so that can be checked rather than believed.
a rule writes Every path to Amazon runs through the same rule, the same read-back and the same three gates as a hand edit. There is no second path.
it shows its evidence Every answer carries the rows it came from, every rewrite arrives as a diff, and what it refused to do is listed next to what it did.
An AI that never says no is one you have to check line by line anyway.
An empty table
four causes Nothing yet, nothing matched, something broke, not permitted. Only the first is benign, so they must not look alike.
name the filter An empty result is a fact about the filter. The condition doing the excluding is named.
a red zero A dead feed returns 0, and a grey blank would read as “no shipping”. It is drawn in red.
A number you do not have
skeleton Real column heads, unknown values, real row height so nothing jumps.
stale Fourteen-minute-old values beat a spinner — but only labelled. An unlabelled stale number is worse than none.
partial A partial total is a wrong total, so it is withheld rather than shown.
A bulk action
per row Before and after for every selected row, plus the total change. A count is not a consequence.
the exception Rows where the action means something different — the only active campaign for an ASIN — are flagged in the list.
A failure
what survived Six of nine applied and kept. Calling that “failed” would be a lie about six of them.
success is not enough A 200 with an empty payload and no change on read-back is recorded as a failure. It is the worst error class there is.
Brief
ClickPay against SellerboardBrief Command CenterBrief Daily BriefBrief Getting startedBrief Profit and lossBrief Where a number comes fromBrief
Advertising
Ad GroupsAdvertising Advertising — launchesAdvertising After you press the buttonAdvertising Ask the tableAdvertising AudiencesAdvertising Bulk selectionAdvertising CampaignsAdvertising ClickPay SuggestsAdvertising Empty statesAdvertising Filter builderAdvertising HourlyAdvertising Loading statesAdvertising PlacementsAdvertising Search TermsAdvertising ShapesAdvertising StrategiesAdvertising Targets › KeywordsAdvertising Why did this move?Advertising Window pickerAdvertising
Inventory
AI listing rewriteInventory Container planInventory Container plan — mid-dragInventory Listing editor + keyword optimiserInventory Listings — changesInventory Listings — competitorsInventory Listings — variation familiesInventory MarketplacesInventory Marketplaces — profit by productInventory Marketplaces › ListingsInventory Marketplaces › ProductsInventory Marketplaces › RestockInventory Marketplaces › Search TermsInventory Marketplaces › SQPInventory Marketplaces › Temu PricesInventory One purchase orderInventory Orders — returnsInventory Orders › FBA ShipmentsInventory Orders › PaymentsInventory Orders › ShipmentsInventory Orders › TimelineInventory Orders › Timeline, groupedInventory Payments — the next 13 weeksInventory Product › KeywordsInventory Product detailInventory Purchasing coverageInventory Receiving a containerInventory Restock — where the stock isInventory Restock at 1280Inventory Restock, a line openedInventory Search catalog performanceInventory Shell + command paletteInventory SuppliersInventory Suppliers — purchase ordersInventory
Automations
ApprovalsAutomations Automation draftsAutomations Automations › RunsAutomations Failure statesAutomations RulesAutomations Save a view, or make a ruleAutomations TagsAutomations WorkflowsAutomations
AI & System
AI AssistantAI & System AI layer › AgentsAI & System Asking for somethingAI & System Audit logAI & System Data freshnessAI & System Feedback, turned into a build orderAI & System Listing agentAI & System NotificationsAI & System Ops healthAI & System Settings v6AI & System System › Ops HubAI & System Users and what they can spendAI & System Writes and gatesAI & System
Reference
Console systemReference Every tab and sub-tabReference Packing list — as it printsReference Phone layoutsReference Width rulesReference