diff --git a/docs/plans/workbench-cards-migration.md b/docs/plans/workbench-cards-migration.md
new file mode 100644
index 000000000..309204021
--- /dev/null
+++ b/docs/plans/workbench-cards-migration.md
@@ -0,0 +1,160 @@
+# Workbench cards over subroutes — migration plan
+
+_Started 2026-04-21._
+
+## Why
+
+User preference (2026-04-21):
+> *"wir wollen möglichst alles als cards darstellen statt unterrouten"*
+
+The unified Mana app has a workbench that lets users compose scenes
+from draggable cards. Every module already registers itself as a card
+via `registerApp()` in `apps/mana/apps/web/src/lib/app-registry/apps.ts`
+so the list/detail view shows up when the user drops the app into a
+scene.
+
+Secondary surfaces — admin panels, per-module settings, filtered
+lists (archive/favorites), preference editors — were historically
+built as dedicated subroutes (`/admin/users`, `/broadcasts/settings`,
+`/news/preferences`, …). That forces a URL round-trip and fragments
+the UX: you can't have "members" and "broadcast settings" side-by-side
+in the same scene without flipping tabs.
+
+**Convention going forward:** secondary surfaces ship as workbench
+cards first. If a subroute already exists and should stay navigable by
+URL, we keep the route as a thin wrapper that renders the same
+ListView the workbench uses.
+
+## Pattern
+
+For every surface being migrated:
+
+```
+apps/mana/apps/web/src/
+├── lib/modules/{id}/
+│ └── ListView.svelte # self-contained pane
+├── lib/app-registry/apps.ts # registerApp({ id, views: { list } })
+└── routes/(app)/{path}/+page.svelte # thin wrapper: ``
+```
+
+Rules of thumb:
+
+- **Pane chrome:** ListView wraps its own content in a `.pane`
+ container with `max-width: 720px` (or similar) and theme tokens
+ (`hsl(var(--color-foreground))`, `hsl(var(--color-card))`,
+ `hsl(var(--color-border))`). No `` — the workbench
+ provides scene chrome, and the route wrapper works without one.
+- **No MANA_APPS entry** for power-user cards (admin/settings).
+ MANA_APPS is the app-drawer; admin panels shouldn't appear there.
+ Only add a MANA_APPS entry when the surface is user-facing
+ (e.g. `spaces`).
+- **Admin-role guard inline** for admin cards: the workbench doesn't
+ run the `/admin/+layout.svelte` guard, so each admin ListView
+ checks `authStore.user?.role === 'admin'` and renders a fallback
+ `Admin-only` gate-screen for non-admins.
+- **Wrap existing form components** where the subroute was already
+ thin (e.g. `/broadcasts/settings` delegated to `SettingsForm`); the
+ ListView just wraps that component + a small bar heading.
+- **Route wrapper is 10 lines:**
+ ```svelte
+
+
+ ```
+
+## Out of scope (stay as routes)
+
+- Detail pages with `[id]` parameters — the URL is the entity
+ identifier (`notes/[id]`, `contacts/[id]`, `events/[id]`,
+ `admin/user-data/[userId]`, `broadcasts/[id]/edit`, …).
+- Deeply nested flows — `citycorners/cities/[slug]/locations/[id]`
+ etc. Every level as a card would explode the registry and break
+ deep-linking.
+- Auth-critical pages needing SSR redirects — login/register/recovery.
+
+## Shipped batches
+
+### Batch 1 — Spaces (commit `88eca8a75`, 2026-04-21)
+
+| Card id | Route | Module folder |
+| -------- | ------------------ | -------------------- |
+| `spaces` | `/spaces` (new canonical) + `/spaces/members` (legacy alias) | `lib/modules/spaces/` |
+
+Also: `APP_ICONS.spaces` + MANA_APPS entry + `SpaceSwitcher` link
+updated to `/spaces`.
+
+### Batch 2 — Admin + Module Settings (commit `92fe23d46`, 2026-04-21)
+
+Admin cards (role-gated inline):
+
+| Card id | Route | Source |
+| ------------------- | ---------------------- | ----------------------------------- |
+| `admin-users` | `/admin/users` | extracted from route |
+| `admin-system` | `/admin/system` | extracted from route |
+| `admin-user-data` | `/admin/user-data` | extracted from route |
+| _(existing)_ | `/admin/complexity` | route now wraps `complexity` module |
+
+Module settings cards:
+
+| Card id | Route | Source |
+| -------------------- | ----------------------- | ----------------------------------------- |
+| `broadcast-settings` | `/broadcasts/settings` | wraps `broadcast/components/SettingsForm` |
+| `invoices-settings` | `/invoices/settings` | wraps `invoices/components/SenderProfileForm` |
+| `uload-settings` | `/uload/settings` | extracted from route |
+| `news-preferences` | `/news/preferences` | extracted from route |
+
+## Backlog
+
+### High-value next batch (archive/filtered-list surfaces)
+
+All of these are single-view pages inside existing modules — the
+content is self-contained and benefits from being scene-composable
+next to the module's main ListView.
+
+- `chat/archive`, `chat/templates`
+- `memoro/archive`, `memoro/tags`
+- `picture/archive`, `picture/board`
+- `storage/favorites`, `storage/trash`, `storage/search`
+- `photos/favorites`, `photos/albums`, `photos/upload`
+- `quotes/categories`, `quotes/favorites`, `quotes/lists`
+- `news/saved`, `news/sources`, `news/add`
+- `meditate/history`, `food/history`, `food/goals`, `food/add`
+- `plants/tags`, `plants/add`
+- `moodlit/moods`, `moodlit/sequences`
+- `cards/decks`, `cards/explore`, `cards/progress`
+- `music/library`, `music/playlists`, `music/projects`
+- `inventory/categories`, `inventory/locations`, `inventory/search`,
+ `inventory/collections`
+- `skilltree/achievements`, `skilltree/tree`
+- `calendar/calendars`
+- `uload/tags`, `uload/links`, `uload/analytics/[id]` _(detail — skip)_
+- `times/clients`, `times/projects`, `times/reports`,
+ `times/templates`, `times/entries`, `times/clock`
+- `agents/templates`
+- `timeline/analytics`
+- `research-lab/keys`
+
+### Second-tier (settings-style, likely worth migrating)
+
+- `todo/settings` (367 lines — non-trivial, worth a separate batch)
+
+### Admin-adjacent (not yet migrated)
+
+- `organizations`, `teams` — technically post-Spaces these routes are
+ dead ends (users are told to use Spaces instead). Either migrate
+ to cards or delete.
+- `gifts`, `gifts/redeem` — probably keep as routes (shareable)
+- `feedback`, `observatory`, `llm-test`, `tags` — already registered
+ as cards or thin enough to leave.
+
+## Open questions
+
+- Should the `/admin/+layout.svelte` nav tabs be removed once every
+ sub-page is a card? Cards make the sidebar nav redundant, but the
+ admin role guard still lives in the layout so removing it means
+ moving that guard somewhere else. _Decision deferred until the
+ full admin batch is shipped._
+- Do we want a convention for registering _sibling_ views of the
+ same module (e.g. `chat-archive` alongside `chat`)? Current pattern
+ uses separate ids. Works, but clutters the registry.