Signals sidebar — how far to indent

Type untouched in every column. Shipped theme CSS inlined verbatim, data-platform="desktop" so this is the SF Pro ladder. Nine locations, thirteen rows, the 280px panel — the real navigation. Each column measures itself on load, so the costs below it cannot go stale.

Commentary — the grid question, answered

No — it is not an 8px grid, and 4 is not a half-step. The ladder is rem-round and roughly doubling:

tokenrempx @16÷8÷4step
--bn-space-xs0.152.4nono—
--bn-space-sm0.355.6nono×2.33
--bn-space-md0.7512noyes×2.14
--bn-space-lg1.524yesyes×2.00
--bn-space-xl2.032yesyes×1.33

Only lg and xl land on 8. md is a multiple of 4; sm and xs are multiples of neither — they are round in rem (0.35, 0.15), not in pixels, which is what lets the whole scale honour a changed root font size. So there is no 8px token, and no step at all between 5.6 and 12. The next size down from L is N, at 5.6px.

And it has no macOS derivation. The scale landed on 30 January 2026 in v0.2.0 (15c1a125, the original atomic-CSS extraction) and no value has changed since — five and a half months before the Mac app existed. Type was aligned to AppKit later and deliberately (tokens-desktop.css is width-matched to measured native styles via the Type Parity Inspector); colour too (design-native-colour-alignment.md, which names the grid as one of the four things to align across the seam). Spacing never got that pass.

The native sidebar does have an indent unit, though, and it is 14pt. ProjectSidebarOutline.swift:378 sets outlineView.indentationPerLevel = 14, and CloudImportOutlineView repeats it in its Metrics block. Not AppKit’s own default of 16 — a chosen 14. The rest of that sidebar is 2pt-granular and font-derived, not gridded: singleLineHeight 32, titleToSubtitle 1, iconToText 6, iconWidth 20, subtitleInternal 4, and a verticalInset computed from the title font’s own bounding box. Its comment says as much: the numbers that get nudged against a real window.

One thing the native sidebar does differently, worth knowing before picking the air. It does not separate its groups with whitespace at all — floatsGroupRows = true, so a group row sticks to the top of the scroll while its children pass under it. Indentation carries the hierarchy; the sticky header carries the grouping. That is a third option neither L nor M is.

Baseline · 0px
no indent, air --bn-space-sm
N · 5.6px
indent + air --bn-space-sm — the real next token down
L · 12px
indent + air --bn-space-md
Native · 14px invents a value
the Mac app’s own indentationPerLevel — no token
M · 24px
indent + air --bn-space-lg