Design — the Roles & permissions page: the read-only permission grid for the three built-in roles
Draw the Roles & permissions page — the surface that shows a project's roles and, for each, the permissions it holds. This story ships it read-only over the three built-in roles; the custom-roles story turns the same page into an editor, so the layout must have somewhere obvious for a Create role action and a per-role edit affordance to land later without a redraw.
The asset is a three-file set under design/projects/ — roles-permissions.mock.html (the source of truth), a same-basename .png light-mode export, and a new section in design/projects/design-notes.md. Build the mockup FROM the real design system, as access-members.mock.html does: the app/globals.css token block copied 1:1 and the shipped components/ui/* primitives.
This design COMPOSES; it does not redraw. The settings-area chrome (rail, header, group ordering) is owned by design/projects/settings-area.mock.html; the Members and Access cards are owned by design/projects/access-members.mock.html. Ground in both and state in the notes that neither is re-specified here.
The access path is part of the deliverable. Draw where this page is entered from: the project-settings rail's Access group, alongside the existing Members entry — the same group lib/settings/projectSettingsNav.ts already renders. A design that draws only the destination leaves the door to be improvised.
The panels to draw
- The populated page, admin view — the three built-in roles, each a card carrying its name, a
Built-inchip, a one-line description of who it is for, and its permissions grouped by catalog domain. The permission rows show the human label and its description, not the raw key. - The grid at width — how a domain group with a dozen permissions reads without becoming a wall: grouping, spacing, and what collapses.
- The member (non-admin) view — the same page, same content. The read is browse-gated in this story, so a member sees how their project is governed. Nothing here is editable for anyone yet, so this panel differs from panel 1 only where the notes say it does.
- The room reserved for editing — where Create role and a per-role edit affordance will sit when the custom-roles story lands, drawn as the placement decision rather than as working controls.
Acceptance criteria
design/projects/roles-permissions.mock.htmlexists, opens standalone, and renders all four panels; togglingdata-theme="dark"on it keeps every surface legible (token parity, no hard-coded colour).design/projects/roles-permissions.pngis a light-mode export of the same basename.- Colour comes only from
--el-*element tokens and shape only from the element-semantic shape tokens — no Tier-0--color-*, no rawrounded-md/p-2/h-9. - Every composed control is an existing
components/ui/*primitive named in the notes (Card,Pill,Button,Tooltip, the table/list primitive chosen); the notes state that no new primitive is required, or name the one that is and why nothing shipped covers it. - The notes name the access path — the Access group of the project-settings rail — and show the rail entry in at least one panel.
- The notes cite
design/projects/settings-area.mock.htmlanddesign/projects/access-members.mock.htmlas the surfaces this page composes, and state explicitly that this asset does not redraw either. - A coloured
Built-inchip carries its hue in the tint background with--el-text-strongink (AA-safe), never colour alone conveying the state. - The
design/projects/design-notes.mdsection states which panel each future consumer builds to, so the code subtask has an unambiguous reference.
Context refs
design/projects/settings-area.mock.html— the settings-area chrome this page renders inside.design/projects/access-members.mock.html— the sibling Access-group surface; the role chip grammar and the Members card live here.design/projects/design-notes.md— where this asset's section is added; its § Roles & permissions (Story 6.4) is the shipped precedent for how such a section is written.lib/settings/projectSettingsNav.ts— the registry whose Access group carries the entry that opens this page.- The parent story — the model this page renders.
- The custom-roles story — the consumer that turns this page into an editor.