TOKENS: add role-based spacing and layer roles #307

Open
opened 2026-09-28 07:32:06 +00:00 by kayg · 3 comments
Owner

Evidence

A source scan of apps/web/src, packages/ui/src and packages/editor/src found 1,062 non-zero spacing declarations with numeric values and no var() token. The largest files are apps/web/src/lib/files/PublicLinkPage.svelte (46), apps/web/src/lib/components/search-dialog.svelte (33), apps/web/src/lib/notifications/InboxPanel.svelte (31), and apps/web/src/lib/components/analytics/BklitAnalytics.tsx (28). This is a candidate count; it does not mean every local drawing measurement should become a token.

The same scan found 68 numeric z-index declarations. packages/ui/src/tokens.css:853 sets the shared floating surface to 201, packages/ui/src/components/menu/FloatingSurface.svelte:572 sets its scrim to 200, packages/ui/src/components/tooltip/TooltipLayer.svelte:344 uses 1000, and apps/web/src/routes/layout.css:96 uses 18. tokens.css has no named layer roles.

Rule

The design system uses shared tokens. The reuse gate says duplicated logic is a defect. Shared shell and overlay layers need one readable order.

Fix

Add a small role-based spacing scale for repeated layouts and named layer roles for the shell, scrims, surfaces, menus and tooltips. Move shared uses to those roles. Keep local spacing for one-off drawings when it has no shared role. Keep local stacking only inside a component that owns the full stack.

Owner

packages/ui/src/tokens.css owns the shared spacing and layer roles. Shared components should use those roles.

## Evidence A source scan of `apps/web/src`, `packages/ui/src` and `packages/editor/src` found 1,062 non-zero spacing declarations with numeric values and no `var()` token. The largest files are `apps/web/src/lib/files/PublicLinkPage.svelte` (46), `apps/web/src/lib/components/search-dialog.svelte` (33), `apps/web/src/lib/notifications/InboxPanel.svelte` (31), and `apps/web/src/lib/components/analytics/BklitAnalytics.tsx` (28). This is a candidate count; it does not mean every local drawing measurement should become a token. The same scan found 68 numeric `z-index` declarations. `packages/ui/src/tokens.css:853` sets the shared floating surface to 201, `packages/ui/src/components/menu/FloatingSurface.svelte:572` sets its scrim to 200, `packages/ui/src/components/tooltip/TooltipLayer.svelte:344` uses 1000, and `apps/web/src/routes/layout.css:96` uses 18. `tokens.css` has no named layer roles. ## Rule The design system uses shared tokens. The reuse gate says duplicated logic is a defect. Shared shell and overlay layers need one readable order. ## Fix Add a small role-based spacing scale for repeated layouts and named layer roles for the shell, scrims, surfaces, menus and tooltips. Move shared uses to those roles. Keep local spacing for one-off drawings when it has no shared role. Keep local stacking only inside a component that owns the full stack. ## Owner `packages/ui/src/tokens.css` owns the shared spacing and layer roles. Shared components should use those roles.
Author
Owner

Consistency-hunt update from dev at dfb5964a2fcf13dc8b9a50a319eee09bc386f322 (2026-09-30). The source scan found 1,088 non-zero spacing declarations with no var() token (previous report: 1,062, +26). Top files are PublicLinkPage.svelte (46), Calendar AgendaList.svelte (29), Analytics BklitAnalytics.tsx (27), search-dialog.svelte (26), and InboxPanel.svelte (26). Numeric z-index declarations fell from 68 to 60 (-8); GridColumn.svelte has 10 and search-dialog.svelte has 4.

Rule: use role tokens for repeated spacing and shared layer order. packages/ui/src/tokens.css owns those shared roles. Keep one-off drawing measurements local when no shared role fits. These are grep-level candidates, not a request to replace every measurement.

Consistency-hunt update from `dev` at `dfb5964a2fcf13dc8b9a50a319eee09bc386f322` (2026-09-30). The source scan found 1,088 non-zero spacing declarations with no `var()` token (previous report: 1,062, +26). Top files are `PublicLinkPage.svelte` (46), Calendar `AgendaList.svelte` (29), Analytics `BklitAnalytics.tsx` (27), `search-dialog.svelte` (26), and `InboxPanel.svelte` (26). Numeric z-index declarations fell from 68 to 60 (-8); `GridColumn.svelte` has 10 and `search-dialog.svelte` has 4. Rule: use role tokens for repeated spacing and shared layer order. `packages/ui/src/tokens.css` owns those shared roles. Keep one-off drawing measurements local when no shared role fits. These are grep-level candidates, not a request to replace every measurement.
Author
Owner

Updated size-token evidence for #307 from rev-consistency (#427), origin/dev at c4a61e8cf090170f35b1bed3350d9de20c83ecd5:

Repeated control sizes remain outside the shared roles:

  • apps/web/src/lib/notifications/InboxPanel.svelte:498-500: .icon-action has a literal 44 px width/height.
  • apps/web/src/lib/files/PublicLinkPage.svelte:1160-1162: .actions .row-action has a literal 44 px width/height.
  • apps/web/src/lib/notifications/InboxPanel.svelte:615-616: the dismiss control has a literal 32 px width/height.
  • packages/ui/src/components/SettingRow.svelte:37,42,44,74: row height, gap and padding remain local rem values with a separate phone gap.

DESIGN §35 maps repeated control sizes to --hit, --control-h and the size roles in packages/ui/src/tokens.css. Use roles for repeated controls and spacing, keeping local drawing measurements only when their purpose is documented. A 44 px source value is not itself evidence of a failed touch target. Test pointer/coarse-pointer sizes and User text/UI scaling after migration; capture both input types. No duplicate issue was filed.

Updated size-token evidence for #307 from rev-consistency (#427), `origin/dev` at `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`: Repeated control sizes remain outside the shared roles: - `apps/web/src/lib/notifications/InboxPanel.svelte:498-500`: `.icon-action` has a literal 44 px width/height. - `apps/web/src/lib/files/PublicLinkPage.svelte:1160-1162`: `.actions .row-action` has a literal 44 px width/height. - `apps/web/src/lib/notifications/InboxPanel.svelte:615-616`: the dismiss control has a literal 32 px width/height. - `packages/ui/src/components/SettingRow.svelte:37,42,44,74`: row height, gap and padding remain local rem values with a separate phone gap. DESIGN §35 maps repeated control sizes to `--hit`, `--control-h` and the size roles in `packages/ui/src/tokens.css`. Use roles for repeated controls and spacing, keeping local drawing measurements only when their purpose is documented. A 44 px source value is not itself evidence of a failed touch target. Test pointer/coarse-pointer sizes and User text/UI scaling after migration; capture both input types. No duplicate issue was filed.
Author
Owner

Corrected size-token evidence (supersedes the selector names in my previous review comment):

  • InboxPanel.svelte:579-580: .nt-reminder-action has literal 44 px minimum width/height.
  • PublicLinkPage.svelte:1159-1162: .icon is the action button with literal 44 px width/height.
  • InboxPanel.svelte:691-692,704-709: .nt-delete has a literal 28 px box with its own 8 px invisible hit halo. It duplicates the shared control/touch-hit sizing mechanism. It is not evidence of a target below 44 px.
  • InboxPanel.svelte:499-500 is the decorative empty-state icon, and lines 615-616 are the decorative item icon. They are not action or dismiss controls.
  • SettingRow.svelte:37,42,44,74 still supplies repeated row height/spacing values locally.

Use the existing shared control/hit/spacing roles for the repeated interaction geometry. Keep decorative artwork sizes distinct. Review snapshot: c4a61e8cf090170f35b1bed3350d9de20c83ecd5.

Corrected size-token evidence (supersedes the selector names in my previous review comment): - `InboxPanel.svelte:579-580`: `.nt-reminder-action` has literal 44 px minimum width/height. - `PublicLinkPage.svelte:1159-1162`: `.icon` is the action button with literal 44 px width/height. - `InboxPanel.svelte:691-692,704-709`: `.nt-delete` has a literal 28 px box with its own 8 px invisible hit halo. It duplicates the shared control/touch-hit sizing mechanism. It is not evidence of a target below 44 px. - `InboxPanel.svelte:499-500` is the decorative empty-state icon, and lines 615-616 are the decorative item icon. They are not action or dismiss controls. - `SettingRow.svelte:37,42,44,74` still supplies repeated row height/spacing values locally. Use the existing shared control/hit/spacing roles for the repeated interaction geometry. Keep decorative artwork sizes distinct. Review snapshot: `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#307
No description provided.