# v5 Mantine Migration Plan

## Status

Planned for v5.0. This document is the migration contract for moving the web,
desktop, mobile/PWA, workflow, governance, and admin surfaces onto Mantine UI.

The goal is not a cosmetic rewrite. The goal is one coherent UI foundation for
new v5 surfaces while keeping Veritas-specific experiences where generic
component primitives are not the right abstraction.

## Current Inventory

The current web app uses React, Vite, Tailwind, Mantine-backed compatibility
wrappers, lucide icons, custom CSS tokens in `web/src/globals.css`, and
product-specific feature components.

Current shared primitive usage:

| Primitive                         | Current state                                            | Observed use |
| --------------------------------- | -------------------------------------------------------- | ------------ |
| `button`                          | Mantine Button/ActionIcon wrapper with local Slot helper | 73 imports   |
| `input`                           | Mantine Input compatibility wrapper                      | 41 imports   |
| `select`                          | Mantine Select compatibility wrapper                     | 39 imports   |
| `label`                           | Mantine Box label compatibility wrapper                  | 36 imports   |
| `badge`                           | Mantine Badge wrapper with local Slot helper             | 36 imports   |
| `textarea`                        | Mantine Textarea compatibility wrapper                   | 20 imports   |
| `skeleton`                        | Mantine Skeleton compatibility wrapper                   | 18 imports   |
| `alert-dialog`                    | Mantine Modal compatibility wrapper                      | 18 imports   |
| `scroll-area`                     | Mantine ScrollArea compatibility wrapper                 | 13 imports   |
| `dialog`                          | Mantine Modal compatibility wrapper                      | 13 imports   |
| `tabs`                            | Mantine Tabs compatibility wrapper                       | 9 imports    |
| `checkbox`                        | Mantine Checkbox compatibility wrapper                   | 9 imports    |
| `switch`                          | Mantine Switch compatibility wrapper                     | 8 imports    |
| `sheet`                           | Mantine Drawer compatibility wrapper                     | 8 imports    |
| `tooltip`                         | Mantine Tooltip compatibility wrapper                    | 4 imports    |
| `popover`                         | Mantine Popover compatibility wrapper                    | 3 imports    |
| `MarkdownEditor/MarkdownRenderer` | Custom markdown surfaces                                 | 2 imports    |
| `toast`/`toaster`                 | Mantine Notifications bridge                             | 1 import     |
| `data-table`                      | Custom table wrapper                                     | 1 import     |

Shared primitive migration progress:

- Mantine-backed compatibility wrappers are now active for `button`, `badge`,
  `input`, `textarea`, `checkbox`, `switch`, `label`, `skeleton`,
  `scroll-area`, `number-input`, `dialog`, `sheet`, `alert-dialog`, `popover`,
  `tooltip`, `tabs`, `select`, and the app-level `toaster` delivery path.
- No shared `components/ui` primitive wrapper remains backed by a Radix
  interaction primitive. A local Slot helper now preserves `asChild`
  composition while migrated feature surfaces still depend on that contract.
- Active feature/runtime surfaces no longer import the `components/ui`
  primitive compatibility wrappers. The remaining wrapper imports are confined
  to the wrapper internals that support compatibility tests and the Phase 4
  cleanup/removal gate.
- The old direct Radix primitive package dependencies, `@radix-ui/react-slot`,
  and the shadcn package have been removed.
- Feature surfaces still need visual and keyboard/focus checks before the final
  cleanup gate. New v5 surfaces should prefer Mantine primitives directly unless
  they need one of the compatibility wrappers above.

High-traffic feature surfaces:

| Area                 | Representative files                                                                 | Migration class      |
| -------------------- | ------------------------------------------------------------------------------------ | -------------------- |
| App shell/navigation | `App.tsx`, `Header.tsx`, `CommandPalette.tsx`, `UserMenu.tsx`, sidebars              | Mantine shell        |
| Board                | `KanbanBoard.tsx`, `KanbanColumn.tsx`, `TaskCard.tsx`, `FilterBar.tsx`, bulk actions | Hybrid               |
| Task work/detail     | `TaskDetailPanel.tsx`, create/apply template dialogs, comments, deliverables, review | Mantine forms        |
| Settings/admin       | `SettingsDialog.tsx`, settings tabs, managed lists, policy/config panels             | Mantine forms        |
| Dashboard/telemetry  | dashboard pages, drilldowns, grid widgets, Recharts views                            | Hybrid               |
| Workflows/governance | workflow pages, policy manager, scoring, drift, decisions                            | Mantine shell        |
| Templates            | template list, editor dialog, preview panel                                          | Mantine forms        |
| Auth/setup           | `LoginScreen.tsx`, `SetupScreen.tsx`                                                 | Mantine forms        |
| Chat/activity        | chat sheets, floating chat, activity feed                                            | Mantine overlays     |
| Archive/backlog      | archive and backlog list/filter pages                                                | Mantine tables/forms |

Legacy helper dependencies still tied to compatibility wrappers:

- `class-variance-authority`
- `tailwind-merge`
- Tailwind animation helpers used by shadcn-style primitives

Remaining removals should happen only after import counts reach zero for the
covered helper group.

## Target Foundation

Mantine becomes the primary component system for v5.0:

| Current concept      | Mantine target                                                                                         | Notes                                                                           |
| -------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
| App frame            | `AppShell`, `NavLink`, `Burger`, `ScrollArea`, `Group`                                                 | Needed for desktop/mobile shell parity                                          |
| Buttons/icon buttons | `Button`, `ActionIcon`, `Menu`, `Tooltip`                                                              | Preserve lucide icons unless a component already supplies a better affordance   |
| Forms                | `TextInput`, `Textarea`, `Select`, `MultiSelect`, `Checkbox`, `Switch`, `NumberInput`, `PasswordInput` | Use Mantine validation/error states before custom form chrome                   |
| Dialogs/sheets       | `Modal`, `Drawer`, `Alert`, `Popover`, `HoverCard`                                                     | Replace sheet-like task panels with drawers only where layout remains efficient |
| Tabs/segmented modes | `Tabs`, `SegmentedControl`, `PillsInput`                                                               | Use compact density for operational surfaces                                    |
| Tables/lists         | `Table`, `DataTable` wrapper if retained, `Pagination`, `ScrollArea`                                   | Product tables can retain custom data logic                                     |
| Notifications        | `Notifications`, `Alert`, `Loader`, `Progress`                                                         | Replace current toast wrapper after app provider lands                          |
| Theme                | `MantineProvider`, CSS variables, color scheme manager                                                 | Keep Veritas tokens as the source of product color decisions                    |
| Layout primitives    | `Stack`, `Group`, `Grid`, `SimpleGrid`, `Flex`, `Box`                                                  | Reduce repeated Tailwind layout strings in migrated surfaces                    |

Foundation files:

- `web/src/theme/MantineRoot.tsx` owns `MantineProvider`, `ModalsProvider`,
  notifications, and the Veritas color-scheme bridge.
- `web/src/theme/mantine-theme.ts` owns the Veritas Mantine theme, status
  colors, density settings, breakpoints, focus behavior, radius, shadows, and
  component defaults.
- `web/src/theme/color-scheme.ts` keeps Mantine color scheme state and the
  existing `.dark` class in sync while shadcn/Tailwind surfaces still exist.
- `web/src/components/layout/mantine-shell.tsx` contains the first Mantine app
  shell primitives for future desktop/mobile surfaces.

Retained custom surfaces:

- Kanban board column/card drag and drop built on `@dnd-kit`
- Task card metadata density and domain-specific status chips
- Diff viewer and review comment anchoring
- Recharts-based dashboard visualizations
- Workflow run timelines and replay views
- Work product previews and markdown rendering, including the retained custom
  markdown renderer
- Prompt/template markdown editing behavior, including the retained custom
  markdown editor toolbar and preview flow
- Git worktree/PR conflict-resolution logic

## Tailwind Strategy

Tailwind should stay available during v5.0, but its role changes:

1. Mantine controls core primitives, overlays, form controls, spacing in migrated
   screens, responsive app shell behavior, and color-scheme behavior.
2. Tailwind remains acceptable for product-specific layouts, chart wrappers,
   kanban board density, diff views, markdown content, and one-off utility
   styling while a surface is being migrated.
3. New v5 surfaces should not add new shadcn/Radix wrapper usage.
4. Once a primitive group has a Mantine replacement and no remaining imports,
   remove the old wrapper and related dependency.

Do not attempt a Tailwind removal in v5.0 unless the migrated app has already
settled and bundle/regression evidence says it is worth the churn.

## Theme, Density, and Icons

Theme requirements:

- Dark mode remains first-class.
- Preserve the Veritas operational feel: dense, quiet, and work-focused.
- Use Mantine radius `sm` or `md` for operational controls; avoid oversized
  marketing-style cards.
- Map existing CSS variables to a Mantine theme file before broad migrations.
- Keep Roboto-compatible fallback through the existing system font stack unless
  a desktop packaging decision provides bundled font handling.
- Maintain visible focus states and reduced-motion behavior.

Icon strategy:

- Keep `lucide-react` for product actions and navigation.
- Use `ActionIcon` for icon-only commands with accessible labels/tooltips.
- Do not replace domain icons solely for library consistency.

Breakpoints:

- Define Mantine breakpoints once in the Veritas theme.
- Treat desktop app, browser, and mobile/PWA as supported layout modes.
- Avoid viewport-scaled font sizes; use responsive layout changes instead.

## Mantine Usage Conventions

- New v5 surfaces should import Mantine components directly or use Veritas
  Mantine wrappers from `web/src/components/layout/mantine-shell.tsx` when the
  wrapper encodes a product layout convention.
- Do not add new shadcn/Radix wrapper usage for new v5 surfaces unless a
  migration PR explicitly needs a compatibility bridge.
- Use Mantine `Stack`, `Group`, `Grid`, `SimpleGrid`, `Flex`, and `Box` for
  new layout code before adding long Tailwind layout strings.
- Use Mantine `ActionIcon` for icon-only commands and keep lucide icons inside
  the control.
- Use Mantine form controls and built-in error/description props for new forms.
- Use Mantine `Modal`/`Drawer`/`Popover` for new overlays. Keep existing
  shadcn overlays only until their containing surface is migrated.
- Keep Veritas-specific board, diff, workflow timeline, chart, markdown, and
  work product components custom.
- Read status colors from `theme.other.statusColors` or from
  `veritasStatusColors`; do not scatter new one-off status hex values.
- Keep the app dark-mode first. Validate light mode, but do not let light-mode
  defaults drive density or spacing decisions.
- When adding a new Mantine dependency beyond core/hooks/forms/notifications/
  modals, document why the package is needed in the PR.

Foundation verification currently covers:

- default dark color-scheme bridge to the existing `.dark` class
- Mantine provider availability in the web app and test utility wrapper
- required v5 status semantics: blocked, needs review, running, done, failed,
  warning, policy denied, and destructive
- reduced-motion, focus ring, auto contrast, and breakpoint defaults
- Mantine-backed shared primitives for buttons, badges, text fields,
  checkbox/switch controls, labels, skeletons, scroll areas, and notifications
- Mantine-backed shared primitives for number inputs, popovers, and tabs with
  legacy compatibility coverage
- Mantine-backed tooltip compatibility wrapper with provider/trigger/content
  coverage
- Mantine-backed dialog compatibility wrapper with trigger/content/title/
  description/close coverage and Modal focus/scroll/Escape behavior
- Mantine-backed sheet compatibility wrapper with trigger/content/title/
  description/close coverage and Drawer position/focus/scroll/Escape behavior
- Mantine-backed alert dialog compatibility wrapper with trigger/content/title/
  description/action/cancel coverage and modal focus/scroll/Escape behavior
- Mantine-backed select compatibility wrapper with trigger/value/content/item
  coverage and legacy `onValueChange` behavior
- direct Radix dependency cleanup, with only the scoped Slot helper retained for
  compatibility `asChild` paths

## Migration Order

### Phase 0: Inventory and Guardrails

- Land this plan.
- Add a migration tracker issue checklist and link dependent v5 UI issues.
- Decide bundle reporting command and baseline before adding Mantine.
- Add a no-new-shadcn guidance note to frontend contribution docs when broad
  migration starts.

### Phase 1: Mantine Foundation

Target issue: `v5.0 UI: Add Mantine foundation, theme, and app shell`

- Add Mantine packages and provider wiring.
- Add `web/src/theme/mantine-theme.ts`.
- Bridge current Veritas CSS variables into Mantine colors where practical.
- Add app-level color scheme manager that respects current dark/light behavior.
- Keep existing shadcn primitives working during this phase.
- Add visual smoke coverage for app boot, auth/setup, board shell, and one modal.

### Phase 2: Shared Primitives

Target issue: `v5.0 UI: Migrate shared primitives, forms, and overlays to Mantine`

Migration batches:

1. Basic controls: button, badge, input, label, textarea, skeleton. Completed
   for the compatibility layer; feature surfaces can now use these wrappers
   while preserving current imports.
2. Form controls: checkbox and switch completed for the compatibility layer;
   number-like settings inputs now route through Mantine `NumberInput`; select
   now routes through Mantine `Select` while preserving the legacy value API.
3. Feedback: toast delivery now routes through Mantine notifications.
4. Overlays: dialog/modal, sheet/drawer, alert dialog, popover, and tooltip now
   use Mantine-backed compatibility wrappers. Destructive confirmation visual QA
   moves to the Phase 4 cleanup gate.
5. Navigation modes: tabs now use a Mantine-backed compatibility wrapper.
   Segmented controls and command/search shell remain surface-level work.

Use compatibility wrappers only when they reduce churn. Each wrapper must have a
removal target and should not hide incompatible behavior.

### Phase 3: Core Surfaces

Target issue: `v5.0 UI: Migrate core app surfaces to Mantine`

Recommended order:

1. Auth/setup screens
2. App shell/header/user menu/command palette
3. Settings dialog and settings tabs
4. Create task/apply template/task metadata forms
5. Task detail panel tabs and side surfaces
6. Templates, archive, backlog
7. Workflow, governance, scoring, drift, policy pages
8. Dashboard shell and drilldowns
9. Chat/activity overlays
10. Board filter/bulk action chrome while preserving custom board internals

Phase 3 progress:

- Auth/setup screens and the app shell/header/command palette have direct
  Mantine surface slices.
- Archive and backlog list/filter pages now use direct Mantine layout and form
  controls while preserving custom task card/list behavior.
- Create-task dialog form controls now use direct Mantine text, textarea,
  select, tabs, alert, and list primitives while preserving duplicate detection,
  template, project, sprint, agent, and subtask behavior.
- Settings dialog shell navigation, mobile section selector, loading skeleton,
  scroll area, and import/export/reset controls now use direct Mantine
  primitives while keeping lazy tab content and destructive confirmation behavior
  stable.
- Shared settings row, toggle, and section header primitives now use direct
  Mantine layout, text, switch, and button components while preserving existing
  tab APIs.
- Board, Tasks, Notifications, and Enforcement settings tab controls now use
  direct Mantine select and text input primitives where tab-specific controls
  are not covered by shared rows.
- General settings now uses direct Mantine switch, text input, select, button,
  badge, and icon action primitives for theme, profile, repository, and default
  agent controls.
- Security settings and the settings error fallback now use direct Mantine
  password input and button primitives while preserving password-change,
  visibility, reset, and retry behavior.
- Delegation settings now uses direct Mantine select, switch, badge, and button
  primitives while preserving delegation enable, revoke, scope, duration, and
  critical-priority exclusion behavior.
- Shared managed-list settings controls now use direct Mantine text input,
  button, and action icon primitives while preserving create, inline edit,
  keyboard save/cancel, drag handles, and explicit move/delete actions.
- Manage settings extra fields and template controls now use direct Mantine
  text input, textarea, select, button, badge, and action icon primitives while
  preserving managed-list metadata edits, template import/export/help, template
  create, and template delete behavior.
- Tool Policies and Shared Resources settings now use direct Mantine alert,
  modal, text input, textarea, checkbox, number input, badge, button, and action
  icon primitives while preserving policy list/edit/create/delete affordances
  and shared-resource allowed-type/max-resource controls.
- Multi-user settings now use direct Mantine select, text input, checkbox, badge,
  button, and action icon primitives while preserving workspace switching,
  member role management, invitations, scoped API token creation, rotation, and
  revocation behavior.
- Agents settings now use direct Mantine switch, select, text input, badge,
  button, action icon, and modal primitives while preserving installed-agent
  add/edit/remove/toggle behavior, Codex health refresh, routing defaults, and
  routing-rule create/edit controls.
- Board filter and bulk-selection chrome now use direct Mantine text input,
  select, badge, button, action icon, and modal primitives while preserving
  search/filter URL behavior, selection groups, move, backlog, archive, and
  delete confirmation flows.
- Search dialog controls now use direct Mantine modal, text input, select,
  checkbox, badge, button, and scroll-area primitives while preserving task/doc
  search, collection filters, backend selection, fallback status, and task-open
  callbacks.
- Setup, login, recovery, and recovery-key confirmation controls now use direct
  Mantine password input, text input, checkbox, and button primitives while
  preserving password creation, remember-me login, recovery reset, key copy, and
  key-download behavior.
- Command palette and keyboard-shortcut help overlays now use direct Mantine
  modal, text input, scroll area, stack, text, and key badge primitives while
  preserving keyboard launch, command filtering, shortcut display, and nested
  search-dialog launch behavior.
- Header action chrome, workspace switching, session menu, and WebSocket status
  now use direct Mantine button, action icon, select, badge, popover, and key
  badge primitives while preserving navigation, theme switching, workspace
  switching, settings shortcuts, session actions, and status popover behavior.
- Task detail shell, core tabs, task title editing, metadata selectors,
  description fallback editing, progress notes, checkpoint status, archive, and
  delete confirmation now use direct Mantine drawer, tabs, text input, textarea,
  select, badge, button, paper, loader, and modal primitives while preserving
  task update, progress, archive, restore, and delete behavior.
- Task detail blocked reason, done criteria, and dependency subsections now use
  direct Mantine select, textarea, checkbox, progress, text input, badge,
  button, action icon, and paper primitives while preserving blocked-reason
  updates, verification-step mutations, dependency display, add/cancel, and
  remove behavior.
- Task detail subtask, deliverable, and lessons-learned subsections now use
  direct Mantine checkbox, switch, progress, text input, textarea, select,
  badge, button, action icon, paper, theme icon, and modal primitives while
  preserving subtask and criterion mutations, auto-complete toggling,
  deliverable add/edit/delete flows, and lessons-note/tag updates.
- Task detail comments, attachments, observations, and time tracking now use
  direct Mantine text input, textarea, select, slider, badge, button, action
  icon, alert, paper, scroll area, modal, stack, group, text, avatar, and theme
  icon primitives while preserving comment add/edit/delete, attachment upload,
  text preview, download and delete confirmation, observation add/delete, and
  manual time-entry add/delete behavior.
- Task detail Git selection, worktree status/actions, pull-request creation,
  workflow run modal, and run-mode/QA gate controls now use direct Mantine
  select, text input, checkbox, switch, badge, button, alert, code, paper,
  scroll area, modal, stack, group, and text primitives while preserving Git
  updates, worktree create/rebase/merge/delete actions, PR draft creation,
  workflow start behavior, run-mode changes, and QA gate toggles.
- Task detail review decisions, inline review comments, preview drawer, and
  conflict-resolution drawer now use direct Mantine drawer, modal, tabs,
  textarea, button, action icon, code, paper, scroll area, stack, group, text,
  loader, and theme icon primitives while preserving review decision summaries,
  merge confirmation, inline comment add/remove, preview output/external/stop
  controls, manual conflict resolution, and abort behavior.
- Task detail agent controls, apply-template flow, task metrics panel, create-task
  dialog shell, blueprint preview, and template variable helpers now use direct
  Mantine modal, tabs, select, switch, text input, badge, button, action icon,
  skeleton, paper, alert, code, stack, group, text, and theme icon primitives
  while preserving agent start/stop/message flows, template merge previews,
  force-overwrite/custom-variable application, metrics expansion/export, and
  blueprint/custom-variable rendering.
- Workflow browse, dashboard, run list, active/recent run cards, summary cards,
  health metrics, and run detail/timeline surfaces now use direct Mantine
  select, text input, badge, button, skeleton, paper, progress, stack, group,
  simple grid, alert, code, text, title, and theme icon primitives while
  preserving workflow search, run start, dashboard filters, run selection, live
  status rendering, health progress, resume action, and step output expansion.
- Dashboard telemetry filter, export, drawer, task, failure, token, and duration
  drilldown surfaces now use direct Mantine select, text input, modal, drawer,
  badge, skeleton, paper, progress, stack, group, simple grid, text, title,
  theme icon, and scroll area primitives while preserving period selection,
  custom ranges, export scope/format/date controls, drawer close behavior,
  task selection, failure summaries, token summaries, duration summaries, and
  per-agent breakdowns.
- Dashboard widget and chart shells now use direct Mantine paper, skeleton,
  tooltip, action icon, progress, stack, group, simple grid, text, and theme icon
  primitives for active dashboard cards, status timeline, agent comparison,
  trends, wall-time, activity clock, and the budget widget while preserving
  existing metric queries, chart rendering, sorting, help affordances, and
  toggle behavior.
- Activity and chat overlays now use direct Mantine drawer, modal, tabs, select,
  text input, scroll area, button, action icon, skeleton, badge, paper, stack,
  group, text, and theme icon primitives while preserving activity filtering,
  status history, daily summaries, board/task chat export and clear
  confirmation, squad sender/filter controls, system-message toggling, and the
  floating chat launcher.
- Governance, policy, scoring, drift, decision, and feedback surfaces now use
  direct Mantine text input, textarea, select, tabs, scroll area, switch,
  modal, badge, button, action icon, and skeleton primitives while preserving
  policy CRUD/evaluation, drift analysis/reset, scoring profile edits,
  decision assumption validation, and feedback submission/browse/analytics
  behavior.
- Final feature-surface cleanup moved templates, board/archive suggestions,
  archive sidebar, board status chrome, task-card tooltips, desktop onboarding,
  markdown editing controls, and remaining settings confirmations off the
  compatibility wrappers and onto direct Mantine controls.

### Phase 4: QA, Cleanup, and Dependency Removal

Target issue: `v5.0 QA: Mantine migration visual, accessibility, and cleanup gate`

- Run `pnpm test:e2e -- e2e/mantine-qa-gate.spec.ts` to capture desktop
  dark/light and mobile visual smoke evidence for the current route inventory
  plus migrated overlays.
- Run keyboard/focus checks for dialog, drawer, tabs, select, command/search,
  task create/edit, settings, and auth/setup flows through the Mantine QA gate.
- Run `pnpm --filter @veritas-kanban/web build` and then `pnpm qa:mantine` to
  verify bundle output, active wrapper-import cleanup, dependency cleanup, and
  v5 GA checklist coverage.
- Remove unused Radix/shadcn dependencies only after import counts and bundle
  output prove they are unused.
- Keep a cleanup ledger of removed wrappers, accepted retained custom
  components, and planned-but-not-yet-present surfaces. Current temporary
  holdouts are unified work products, maintenance center, workflow visual
  builder, and final run replay view.

## Component Mapping

| Current file                     | Target                                                  | Priority |
| -------------------------------- | ------------------------------------------------------- | -------- |
| `components/ui/button.tsx`       | Mantine `Button`/`ActionIcon` wrapper or direct imports | High     |
| `components/ui/input.tsx`        | Mantine `TextInput`                                     | High     |
| `components/ui/textarea.tsx`     | Mantine `Textarea`                                      | High     |
| `components/ui/select.tsx`       | Mantine `Select` compatibility wrapper                  | High     |
| `components/ui/dialog.tsx`       | Mantine `Modal`                                         | High     |
| `components/ui/sheet.tsx`        | Mantine `Drawer` compatibility wrapper                  | High     |
| `components/ui/tabs.tsx`         | Mantine `Tabs`                                          | High     |
| `components/ui/alert-dialog.tsx` | Mantine `Modal` compatibility wrapper                   | High     |
| `components/ui/checkbox.tsx`     | Mantine `Checkbox`                                      | Medium   |
| `components/ui/switch.tsx`       | Mantine `Switch`                                        | Medium   |
| `components/ui/popover.tsx`      | Mantine `Popover`/`Menu`                                | Medium   |
| `components/ui/tooltip.tsx`      | Mantine `Tooltip`                                       | Medium   |
| `components/ui/scroll-area.tsx`  | Mantine `ScrollArea`                                    | Medium   |
| `components/ui/skeleton.tsx`     | Mantine `Skeleton`                                      | Medium   |
| `components/ui/toast.tsx`        | Mantine notifications                                   | Medium   |
| `components/ui/data-table.tsx`   | Retain custom or wrap Mantine `Table`                   | Low      |
| Markdown editor/renderer         | Retain custom                                           | Low      |

## Risk Areas

| Risk                         | Mitigation                                                                                             |
| ---------------------------- | ------------------------------------------------------------------------------------------------------ |
| Drag/drop regressions        | Keep `@dnd-kit` board internals stable until shell/forms are migrated                                  |
| Dialog/drawer behavior drift | Migrate one overlay family at a time and test keyboard escape/focus return                             |
| Command/search regressions   | Treat command center as its own surface with keyboard tests                                            |
| Settings form churn          | Batch settings tabs after shared form controls are stable                                              |
| Dashboard bundle growth      | Keep Recharts split and measure Mantine impact separately                                              |
| Mobile drawer overflow       | Test task detail, settings, create task, search, and chat on narrow widths                             |
| Accessibility gaps           | Verify focus, labels, reduced motion, contrast, and screen-reader names                                |
| Partial system inconsistency | Use route/surface migration PRs; avoid mixing Mantine and shadcn inside one compact form when possible |

## Rollback Strategy

- Land foundation work behind provider-level compatibility; do not remove old
  primitives in the same PR that adds Mantine.
- Migrate by primitive family or route-level surface, not by scattered one-off
  replacements.
- Keep compatibility wrappers until the migrated surface is verified.
- If a surface regresses, revert that surface PR without reverting the Mantine
  provider foundation.
- Keep dependency removals in the final cleanup phase so rollback does not
  require reinstalling packages mid-migration.

## Verification Gates

Minimum gates for foundation and shared primitive PRs:

- `pnpm --filter @veritas-kanban/web typecheck`
- `pnpm --filter @veritas-kanban/web test`
- `pnpm lint:budget`
- `pnpm build`
- `pnpm qa:mantine` after `pnpm --filter @veritas-kanban/web build`
- visual smoke screenshots for app boot, board, task detail, create task,
  settings, command/search, and one mobile viewport once browser automation is
  added to the migration branch

Minimum gates for route-level migration PRs:

- targeted component/unit tests for touched surfaces
- keyboard smoke for overlays/forms
- desktop and mobile screenshot comparison
- bundle-size note when a lazy chunk changes materially

Minimum gate for closing #418:

- `pnpm test:e2e -- e2e/mantine-qa-gate.spec.ts`
- `pnpm --filter @veritas-kanban/web build`
- `pnpm qa:mantine`
- issue and PR notes list any temporary holdouts that map to not-yet-landed v5
  feature issues

## Completion Criteria

Issue #414 is complete when:

- this plan is linked from the README documentation map
- each current shared UI primitive has a target state
- Mantine foundation work is sequenced before dependent v5 surfaces
- rollback and dependency-removal strategy are documented
- known risky areas have explicit migration/testing treatment
