9e590b959e
The "edit role" dialog in admin.tsx was hand-rolled as a bespoke <div role-less wrapper> with its own close button, sticky footer and full-width split buttons. That made it look different from every other admin dialog (add role, add/edit group, add user), and on iPad the action buttons floated mid-dialog because the content exceeded max-h-[92vh]. The custom wrapper also lacked role="dialog", so the new `:has(:focus)` CSS keyboard rule (index.css:492) never applied to it. Replaced the wrapper with AdminFormDialog (maxWidth="lg", KeyRound icon, same title key). All inner content — name/desc fields, rename warning, permissions list, removal impact, RolePermissionHistory, RecentActivityForTarget — moved verbatim as children. Removed the custom sticky footer; AdminFormDialog provides the unified footer with cancel/save buttons. Preserved testIds `edit-role-dialog` and `edit-role-submit`. Disabled logic translated 1:1 into submitDisabled + isPending props (note: `impactError` coerced to boolean via `!!` to satisfy the prop type). No behavior change: same handlers (closeEditDialog, handleEdit), same loading spinner, same disabled conditions. Bonus: the keyboard override CSS now applies because AdminFormDialog already sets role="dialog". `tsc --noEmit` clean.