A purchasing manager at a two-plant manufacturer clears the queue of requisitions waiting on their signature.
Direction
Floorplan. List Report → Object Page, held together by a Flexible Column Layout. Fiori's default pairing, and the one floorplans.md says to reach for first.
Archetype. Split. Both halves stay live, so the queue never disappears behind whichever record the manager is deciding.
Data stance. Table-first. The queue is the product; the object page answers the one question a row raises.
Density. Cozy, at a 36px control and a 44px row. Not Condensed.
The one bold thing. The text/element split, shown side by side: a budget bar in --sapNegativeElementColor with its label beside it in --sapNegativeTextColor.
Generator
sap_tokens.py --both # produced tokens.css
sap_tokens.py --density
sap_tokens.py --semantic
sap_tokens.py --grep Duration
tokens.css is unedited: re-running --both reproduces it byte for byte (diff -q clean).
Why Cozy
--density reports Condensed at 22px control / 24px row and exits 1 while that stands, against SC 2.5.8's 24×24 floor. 2.5.8's Spacing exception wants a 24px-diameter circle on each undersized target's bounding box to clear its neighbours; in a packed queue with a checkbox in the first cell, it does not. Cozy clears the floor outright and serves touch as well as a mouse.
Measured in Chromium at 1440×900: control 36px, the single-line Items rows 44px, the queue's two-line item 52px (Cozy's two-line ceiling is 80px). Every target passes wcag_check.py --target at AA.
The two states
- The queue. Nine requisitions, with the first one open in the object page.
- A bulk approval that only partly lands. Check every row → Approve → a confirmation naming the count and the total → "6 of 9 requisitions approved. 3 need a second approver", each of the three named with what to do about it, the three remaining rows marked Held, and the object page switched to the first of them carrying its own reason and a changed primary action. This is the state
patterns.mdsays an enterprise bulk action owes the user, and the one a split floorplan makes hardest, because both halves have to agree afterwards. - The queue empty. Each held row's primary action names its own destination — the CFO office, 4712-FAC, Legal — routes it there and takes it off this desk, so three more clicks reach nothing. The list says Queue clear rather than reusing the search's copy, and the object column empties with it: a split whose right half keeps a live Approve on a record that has left the queue is telling the manager two different things at once.
Reject and Ask for information are real on both the toolbar and the object page; nothing on the page is an inert control.
Deviations from CONTRACT.md §1
- No web font. SAP licenses the 72 typeface and Google Fonts does not serve it. The page takes
--sapFontFamilyas published, which falls through to Arial and Helvetica. - No icon font. SAP licenses that one too; every icon is inline SVG at
--sapContent_IconHeight. - This page authors its motion. Horizon's 1,537 parameters carry no duration, easing or transition (
--grep Durationprints an empty rule; Transition, Animation and Easing do the same). 100ms for a pointer state, 160ms enter, 120ms exit; reduced motion shortens all three to 1ms rather than deleting them. - This page authors its spacing on a 0.25rem grid, which Horizon does not tokenize either.
- Two attributes carry a hex because neither can hold a
var(): the favicon'sdata:URI (mirrors--sapBrandColor) and the initialtheme-color(mirrors--sapShell_Background, and script rewrites it from the live token on every appearance change).