`.
+
+Add the `styles` import if not already present (it already imports from `./UserManagement.module.css` — wait, it doesn't currently. Add:
+```tsx
+import styles from './UserManagement.module.css'
+```
+
+- [ ] **Step 2: Commit**
+
+```bash
+git add src/pages/Admin/UserManagement/UserManagement.tsx
+git commit -m "refactor: replace inline style with CSS module class"
+```
+
+---
+
+### Task 6: Add toasts to all RBAC tabs
+
+**Files:**
+- Modify: `src/pages/Admin/UserManagement/UsersTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/GroupsTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/RolesTab.tsx`
+
+- [ ] **Step 1: Add useToast to UsersTab**
+
+Add import: `import { useToast } from '../../../design-system/composites/Toast/Toast'`
+
+Add `const { toast } = useToast()` at the top of the `UsersTab` function body.
+
+Add toast calls:
+- After `setSelectedId(newUser.id)` in `handleCreate`: `toast({ title: 'User created', description: newUser.displayName, variant: 'success' })`
+- After `setDeleteTarget(null)` in `handleDelete`: `toast({ title: 'User deleted', description: deleteTarget.username, variant: 'warning' })`
+
+- [ ] **Step 2: Add useToast to GroupsTab**
+
+Same pattern. Add toast calls:
+- After create: `toast({ title: 'Group created', description: newGroup.name, variant: 'success' })`
+- After delete: `toast({ title: 'Group deleted', description: deleteTarget.name, variant: 'warning' })`
+
+- [ ] **Step 3: Add useToast to RolesTab**
+
+Same pattern. Add toast calls:
+- After create: `toast({ title: 'Role created', description: newRole.name, variant: 'success' })`
+- After delete: `toast({ title: 'Role deleted', description: deleteTarget.name, variant: 'warning' })`
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add src/pages/Admin/UserManagement/UsersTab.tsx src/pages/Admin/UserManagement/GroupsTab.tsx src/pages/Admin/UserManagement/RolesTab.tsx
+git commit -m "feat: add toast notifications to all RBAC mutations"
+```
+
+---
+
+### Task 7: Rework user creation form + password management
+
+**Files:**
+- Modify: `src/pages/Admin/UserManagement/UsersTab.tsx`
+
+This is the largest single task. It covers spec items 3.2 (provider-aware create form), 3.3 (password management in detail pane), and 3.6 (remove unused password field).
+
+- [ ] **Step 1: Rework the create form section**
+
+Replace the create form state variables (lines 23-26):
+```tsx
+const [newUsername, setNewUsername] = useState('')
+const [newDisplay, setNewDisplay] = useState('')
+const [newEmail, setNewEmail] = useState('')
+const [newPassword, setNewPassword] = useState('')
+```
+with:
+```tsx
+const [newUsername, setNewUsername] = useState('')
+const [newDisplay, setNewDisplay] = useState('')
+const [newEmail, setNewEmail] = useState('')
+const [newPassword, setNewPassword] = useState('')
+const [newProvider, setNewProvider] = useState<'local' | 'oidc'>('local')
+```
+
+Add imports for RadioGroup, RadioItem, and InfoCallout:
+```tsx
+import { RadioGroup, RadioItem } from '../../../design-system/primitives/Radio/Radio'
+import { InfoCallout } from '../../../design-system/primitives/InfoCallout/InfoCallout'
+```
+
+Update `handleCreate` to use the provider selection and validate password for local:
+```tsx
+function handleCreate() {
+ if (!newUsername.trim()) return
+ if (newProvider === 'local' && !newPassword.trim()) return
+ const newUser: MockUser = {
+ id: `usr-${Date.now()}`,
+ username: newUsername.trim(),
+ displayName: newDisplay.trim() || newUsername.trim(),
+ email: newEmail.trim(),
+ provider: newProvider,
+ createdAt: new Date().toISOString(),
+ directRoles: [],
+ directGroups: [],
+ }
+ setUsers((prev) => [...prev, newUser])
+ setCreating(false)
+ setNewUsername(''); setNewDisplay(''); setNewEmail(''); setNewPassword(''); setNewProvider('local')
+ setSelectedId(newUser.id)
+ toast({ title: 'User created', description: newUser.displayName, variant: 'success' })
+}
+```
+
+Replace the create form JSX (lines 100-114) with:
+```tsx
+{creating && (
+
+)}
+```
+
+- [ ] **Step 2: Add Security section to detail pane**
+
+Add password reset state at the top of the component:
+```tsx
+const [resettingPassword, setResettingPassword] = useState(false)
+const [newPw, setNewPw] = useState('')
+```
+
+Add the Security section after the metadata grid (after the `
` closing the `.metaGrid`), before the "Group membership" SectionHeader:
+
+```tsx
+
+ {selected.provider === 'local' ? (
+ <>
+
+ Password
+ ••••••••
+ {!resettingPassword && (
+ { setResettingPassword(true); setNewPw('') }}>
+ Reset password
+
+ )}
+
+ {resettingPassword && (
+
+ setNewPw(e.target.value)}
+ className={styles.resetInput}
+ />
+ setResettingPassword(false)}>Cancel
+ { setResettingPassword(false); toast({ title: 'Password updated', description: selected.username, variant: 'success' }) }}
+ disabled={!newPw.trim()}
+ >
+ Set
+
+
+ )}
+ >
+ ) : (
+ <>
+
+ Authentication
+ OIDC ({selected.provider})
+
+
+ Password managed by the identity provider.
+
+ >
+ )}
+
+```
+
+- [ ] **Step 3: Verify build**
+
+Run: `npx vite build 2>&1 | tail -5`
+Expected: Build succeeds
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add src/pages/Admin/UserManagement/UsersTab.tsx
+git commit -m "feat: rework user creation with provider selection, add password management"
+```
+
+---
+
+### Task 8: Keyboard accessibility for entity lists
+
+**Files:**
+- Modify: `src/pages/Admin/UserManagement/UsersTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/GroupsTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/RolesTab.tsx`
+
+- [ ] **Step 1: Add keyboard support to UsersTab entity list**
+
+On the `.entityList` wrapper div, add:
+```tsx
+
+```
+
+On each `.entityItem` div, add `role`, `tabIndex`, `aria-selected`, and `onKeyDown`:
+```tsx
+
setSelectedId(user.id)}
+ role="option"
+ tabIndex={0}
+ aria-selected={selectedId === user.id}
+ onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setSelectedId(user.id) } }}
+>
+```
+
+Add empty-search state after the list map:
+```tsx
+{filtered.length === 0 && (
+
No users match your search
+)}
+```
+
+- [ ] **Step 2: Add keyboard support to GroupsTab entity list**
+
+Same pattern — add `role="listbox"` to container, `role="option"` + `tabIndex={0}` + `aria-selected` + `onKeyDown` to items, and empty-search state.
+
+- [ ] **Step 3: Add keyboard support to RolesTab entity list**
+
+Same pattern. Also replace the lock emoji on line 113:
+```tsx
+{role.system &&
🔒 }
+```
+with:
+```tsx
+{role.system &&
}
+```
+
+Add empty-search state.
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add src/pages/Admin/UserManagement/UsersTab.tsx src/pages/Admin/UserManagement/GroupsTab.tsx src/pages/Admin/UserManagement/RolesTab.tsx
+git commit -m "feat: add keyboard accessibility and empty states to entity lists"
+```
+
+---
+
+### Task 9: Add confirmation for cascading removals
+
+**Files:**
+- Modify: `src/pages/Admin/UserManagement/UsersTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/GroupsTab.tsx`
+
+- [ ] **Step 1: Add group removal confirmation in UsersTab**
+
+Add state for tracking the removal target:
+```tsx
+const [removeGroupTarget, setRemoveGroupTarget] = useState
(null)
+```
+
+Replace the direct `onRemove` on group Tags (in the "Group membership" section) with:
+```tsx
+onRemove={() => {
+ const group = MOCK_GROUPS.find((gr) => gr.id === gId)
+ if (group && group.directRoles.length > 0) {
+ setRemoveGroupTarget(gId)
+ } else {
+ updateUser(selected.id, { directGroups: selected.directGroups.filter((id) => id !== gId) })
+ toast({ title: 'Group removed', variant: 'success' })
+ }
+}}
+```
+
+Add an AlertDialog (import from composites) for the confirmation:
+```tsx
+ setRemoveGroupTarget(null)}
+ onConfirm={() => {
+ if (removeGroupTarget && selected) {
+ updateUser(selected.id, { directGroups: selected.directGroups.filter((id) => id !== removeGroupTarget) })
+ toast({ title: 'Group removed', variant: 'success' })
+ }
+ setRemoveGroupTarget(null)
+ }}
+ title="Remove group membership"
+ description={`Removing this group will also revoke inherited roles: ${MOCK_GROUPS.find((g) => g.id === removeGroupTarget)?.directRoles.join(', ') ?? ''}. Continue?`}
+ confirmLabel="Remove"
+ variant="warning"
+/>
+```
+
+Add import: `import { AlertDialog } from '../../../design-system/composites/AlertDialog/AlertDialog'`
+
+- [ ] **Step 2: Add role removal confirmation in GroupsTab**
+
+Add state:
+```tsx
+const [removeRoleTarget, setRemoveRoleTarget] = useState(null)
+```
+
+Replace direct `onRemove` on role Tags with:
+```tsx
+onRemove={() => {
+ const memberCount = MOCK_USERS.filter((u) => u.directGroups.includes(selected.id)).length
+ if (memberCount > 0) {
+ setRemoveRoleTarget(r)
+ } else {
+ updateGroup(selected.id, { directRoles: selected.directRoles.filter((role) => role !== r) })
+ toast({ title: 'Role removed', variant: 'success' })
+ }
+}}
+```
+
+Add AlertDialog:
+```tsx
+ setRemoveRoleTarget(null)}
+ onConfirm={() => {
+ if (removeRoleTarget && selected) {
+ updateGroup(selected.id, { directRoles: selected.directRoles.filter((role) => role !== removeRoleTarget) })
+ toast({ title: 'Role removed', variant: 'success' })
+ }
+ setRemoveRoleTarget(null)
+ }}
+ title="Remove role from group"
+ description={`Removing ${removeRoleTarget} from ${selected?.name} will affect ${members.length} member(s) who inherit this role. Continue?`}
+ confirmLabel="Remove"
+ variant="warning"
+/>
+```
+
+Add import: `import { AlertDialog } from '../../../design-system/composites/AlertDialog/AlertDialog'`
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add src/pages/Admin/UserManagement/UsersTab.tsx src/pages/Admin/UserManagement/GroupsTab.tsx
+git commit -m "feat: add confirmation dialogs for cascading removals"
+```
+
+---
+
+### Task 10: Add duplicate name validation to create forms
+
+**Files:**
+- Modify: `src/pages/Admin/UserManagement/UsersTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/GroupsTab.tsx`
+- Modify: `src/pages/Admin/UserManagement/RolesTab.tsx`
+
+- [ ] **Step 1: Add duplicate check in UsersTab**
+
+Add a computed `duplicateUsername`:
+```tsx
+const duplicateUsername = newUsername.trim() && users.some((u) => u.username.toLowerCase() === newUsername.trim().toLowerCase())
+```
+
+Update the Create button `disabled` to include `|| duplicateUsername`.
+
+Show error text below the username Input when duplicate:
+```tsx
+{duplicateUsername && Username already exists }
+```
+
+- [ ] **Step 2: Add duplicate check in GroupsTab**
+
+Similar pattern with `duplicateGroupName` check. Disable Create button when duplicate.
+
+- [ ] **Step 3: Add duplicate check in RolesTab**
+
+Similar pattern with `duplicateRoleName` check (compare uppercase). Disable Create button when duplicate.
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add src/pages/Admin/UserManagement/UsersTab.tsx src/pages/Admin/UserManagement/GroupsTab.tsx src/pages/Admin/UserManagement/RolesTab.tsx
+git commit -m "feat: add duplicate name validation to create forms"
+```
+
+---
+
+### Task 11: Final verification
+
+- [ ] **Step 1: Run full test suite**
+
+Run: `npx vitest run`
+Expected: All tests pass
+
+- [ ] **Step 2: Build the project**
+
+Run: `npx vite build`
+Expected: Build succeeds
+
+- [ ] **Step 3: Fix any issues**
+
+If build fails, fix TypeScript errors. Common issues:
+- Import path typos
+- Missing props on components
+- InfoCallout `variant` prop — check the actual prop name (may be `color` instead)
+
+- [ ] **Step 4: Commit fixes if needed**
+
+```bash
+git add -A
+git commit -m "fix: resolve build issues from admin redesign"
+```