diff --git a/docs/superpowers/plans/2026-04-27-devices-admin.md b/docs/superpowers/plans/2026-04-27-devices-admin.md
index 060b78a..0007fb4 100644
--- a/docs/superpowers/plans/2026-04-27-devices-admin.md
+++ b/docs/superpowers/plans/2026-04-27-devices-admin.md
@@ -1580,4 +1580,414 @@ git commit -m "feat: add per-device OG image generator for device detail pages
- Renders device name, type badge, and stats on branded dark background
- Uses Edge runtime for fast generation
- References OG image in device detail page metadata"
-```
\ No newline at end of file
+```
+---
+
+### Task 7: Admin Layout, Sidebar & Auth Guard
+
+**Files:**
+- Create: `app/(admin)/layout.tsx`
+- Create: `app/(admin)/admin/page.tsx`
+- Create: `components/admin/admin-sidebar.tsx`
+- Modify: `components/navbar.tsx`
+- Modify: `lib/routes.ts`
+
+- [ ] **Step 1: Create the admin sidebar component**
+
+Create `components/admin/admin-sidebar.tsx`:
+
+```tsx
+"use client"
+
+import Link from "next/link"
+import { usePathname } from "next/navigation"
+import { UsersIcon, CpuIcon, Gamepad2Icon } from "lucide-react"
+
+const adminNavItems = [
+ { href: "/admin/users", label: "Users", icon: UsersIcon },
+ { href: "/admin/hardware", label: "Hardware", icon: CpuIcon },
+ { href: "/admin/games", label: "Games", icon: Gamepad2Icon },
+]
+
+export function AdminSidebar() {
+ const pathname = usePathname()
+
+ return (
+
+ )
+}
+```
+
+- [ ] **Step 2: Create the admin layout with server-side auth guard**
+
+Create `app/(admin)/layout.tsx`:
+
+```tsx
+import { redirect } from "next/navigation"
+import { headers } from "next/headers"
+import { auth } from "@/lib/auth"
+import { AdminSidebar } from "@/components/admin/admin-sidebar"
+import type { Metadata } from "next"
+
+export const metadata: Metadata = {
+ title: { template: "%s | Admin — DeckyVault", default: "Admin — DeckyVault" },
+ robots: { index: false, follow: false },
+}
+
+export default async function AdminLayout({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ const session = await auth.api.getSession({
+ headers: await headers(),
+ })
+
+ if (!session || session.user.role !== "admin") {
+ redirect("/")
+ }
+
+ return (
+
+ {/* Header */}
+
+
+
Admin
+
+ Manage users, hardware, and games
+
+
+
+
+ {/* Sidebar + Content */}
+
+
+ )
+}
+```
+
+- [ ] **Step 3: Create the admin redirect page**
+
+Create `app/(admin)/admin/page.tsx`:
+
+```tsx
+import { redirect } from "next/navigation"
+
+export default function AdminPage() {
+ redirect("/admin/users")
+}
+```
+
+- [ ] **Step 4: Add admin link to navbar profile dropdown**
+
+In `components/navbar.tsx`:
+
+1. Add `ShieldIcon` to the lucide imports:
+```tsx
+import {
+ Bookmark,
+ CircleXIcon,
+ Gamepad2Icon,
+ LogOut,
+ MenuIcon,
+ ShieldIcon,
+ User,
+ XIcon,
+} from "lucide-react"
+```
+
+2. In the **desktop profile dropdown** — right after the `{authRoutes.map(...)}` block and before the `
` sign-out divider, add:
+```tsx
+{session.user.role === "admin" && (
+ <>
+
+ setUserMenuOpen(false)}
+ className="w-full flex items-center gap-2 px-3 py-2 text-sm text-primary/80 hover:text-primary hover:bg-primary/5 transition-colors cursor-pointer"
+ >
+
+ Admin
+
+ >
+)}
+```
+
+3. In the **mobile sidebar** — after `{authRoutes.map(...)}` in the mobile auth section, add:
+```tsx
+{session.user.role === "admin" && (
+ setMobileMenuOpen(false)}
+ className="flex items-center gap-2 px-3 py-2 rounded-lg text-sm text-primary/80 hover:text-primary hover:bg-primary/5 transition-colors cursor-pointer"
+ >
+
+ Admin
+
+)}
+```
+
+- [ ] **Step 5: Add admin routes to routes file**
+
+In `lib/routes.ts`, append an `adminRoutes` export (not in the main `routes` nav — admin link only appears in the profile dropdown):
+
+```ts
+export const adminRoutes = [
+ {
+ title: "Users",
+ href: "/admin/users",
+ icon: "Users",
+ },
+ {
+ title: "Hardware",
+ href: "/admin/hardware",
+ icon: "Cpu",
+ },
+ {
+ title: "Games",
+ href: "/admin/games",
+ icon: "Gamepad2",
+ },
+]
+```
+
+- [ ] **Step 6: Build to verify**
+
+Run: `cd /Users/adrianbonpin/Documents/Code/personal/deckyvault && bun run build --no-lint 2>&1 | tail -20`
+Expected: Build succeeds.
+
+- [ ] **Step 7: Commit**
+
+```bash
+git add app/(admin)/ components/admin/admin-sidebar.tsx components/navbar.tsx lib/routes.ts
+git commit -m "feat: add admin layout with sidebar, auth guard, and navbar link
+
+- Admin layout with server-side auth guard (redirects non-admins)
+- Reusable sidebar component with active state detection
+- Navbar profile dropdown shows admin link for admin users
+- Admin routes are noindexed (robots: false)
+- /admin redirects to /admin/users"
+```
+
+---
+
+### Task 8: Admin Users Page
+
+**Files:**
+- Create: `app/(admin)/admin/users/page.tsx`
+- Create: `app/(admin)/admin/users/users-client.tsx`
+
+- [ ] **Step 1: Create the users server component**
+
+Create `app/(admin)/admin/users/page.tsx`:
+
+```tsx
+import type { Metadata } from "next"
+import { UsersClient } from "./users-client"
+
+export const metadata: Metadata = {
+ title: "Users",
+}
+
+export default function UsersPage() {
+ return
+}
+```
+
+- [ ] **Step 2: Create the users client component**
+
+Create `app/(admin)/admin/users/users-client.tsx` — a full user management table with search, role changing (user/contributor/admin), and ban/unban functionality using better-auth's admin plugin client methods (`authClient.admin.listUsers`, `authClient.admin.setRole`, `authClient.admin.banUser`/`unbanUser`). The component should:
+
+- Fetch users on mount via `authClient.admin.listUsers({ query: { limit: 100 } })`
+- Filter users client-side based on a search input
+- Render a table with columns: User (avatar initial + name + email), Role (dropdown select), Status (active/banned dot), Actions (ban/unban button)
+- Role dropdown uses `handleRoleChange` calling `authClient.admin.setRole({ userId, role })`
+- Ban button calls `authClient.admin.banUser({ userId })` / `authClient.admin.unbanUser({ userId })`
+- Style: rounded-xl border, table with text-sm, header row `bg-text/[0.03]`, status dots (green/red), role select with colored borders
+
+Use the same Tailwind patterns as the rest of the app: `px-4 py-2.5`, `rounded-lg border border-border bg-text/5`, `text-text/50`, focus rings, etc.
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add app/(admin)/admin/users/
+git commit -m "feat: add admin users management page
+
+- User list with search by name/email
+- Change role (user/contributor/admin) via dropdown
+- Ban/unban users with status indicators
+- Uses better-auth admin plugin client methods"
+```
+
+---
+
+### Task 9: Admin Hardware Page
+
+**Files:**
+- Create: `app/(admin)/admin/hardware/page.tsx`
+- Create: `app/(admin)/admin/hardware/hardware-client.tsx`
+
+- [ ] **Step 1: Create the hardware server component**
+
+Create `app/(admin)/admin/hardware/page.tsx`:
+
+```tsx
+import type { Metadata } from "next"
+import { HardwareClient } from "./hardware-client"
+
+export const metadata: Metadata = {
+ title: "Hardware",
+}
+
+export default function HardwarePage() {
+ return
+}
+```
+
+- [ ] **Step 2: Create the hardware client component with CRUD**
+
+Create `app/(admin)/admin/hardware/hardware-client.tsx` — a hardware management page with:
+
+- **List**: Fetches from `/api/hardware/stats`, renders device cards (icon + name + slug + type badge + benchmark count) with edit/delete buttons
+- **Add Device** button at top opens a modal form
+- **Edit modal**: Pre-filled form for name, slug (readonly on edit), device type (select handheld/console), sort order, image URL
+- **Delete**: Confirmation via `confirm()`, calls `DELETE /api/hardware/:slug`
+- **Create**: Modal form, calls `POST /api/hardware` with body `{ slug, name, deviceType, image, sortOrder }`
+- **Update**: Modal form, calls `PATCH /api/hardware/:slug` with body `{ name, deviceType, image, sortOrder }`
+- Card grid uses same pattern as devices list page
+- Modal styled: `fixed inset-0 z-50`, backdrop `bg-black/50`, form `bg-background border border-border rounded-xl p-6 max-w-md`
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add app/(admin)/admin/hardware/
+git commit -m "feat: add admin hardware management page with CRUD
+
+- Device list fetched from /api/hardware/stats
+- Create/edit devices via modal form
+- Delete with confirmation dialog
+- Uses existing hardware CRUD API endpoints"
+```
+
+---
+
+### Task 10: Admin Games Page
+
+**Files:**
+- Create: `app/(admin)/admin/games/page.tsx`
+- Create: `app/(admin)/admin/games/games-client.tsx`
+
+- [ ] **Step 1: Create the games server component**
+
+Create `app/(admin)/admin/games/page.tsx`:
+
+```tsx
+import type { Metadata } from "next"
+import { GamesClient } from "./games-client"
+
+export const metadata: Metadata = {
+ title: "Games",
+}
+
+export default function GamesPage() {
+ return
+}
+```
+
+- [ ] **Step 2: Create the games client component**
+
+Create `app/(admin)/admin/games/games-client.tsx` — a games management page with:
+
+- **List**: Fetches from `/api/games?limit=50` (existing CRUD endpoint with search support), renders a table
+- **Search**: Debounced input, passes `?search=query` to the API
+- **Table columns**: Cover image (small thumbnail via `next/image`), Title, Developer, Source (Steam/manual badge), Sync Status (badge), Actions
+- **Actions**: "View" link to `/game/:id` (external-link icon), "Delete" button (admin only, calls `DELETE /api/games/:gameId`)
+- **Pagination**: "Load more" button or offset-based pagination controls (`?offset=N&limit=50`)
+- Style: same table pattern as users page
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add app/(admin)/admin/games/
+git commit -m "feat: add admin games management page
+
+- Game list with search and pagination
+- Source and sync status badges
+- View on site link and delete action
+- Uses existing games CRUD API"
+```
+
+---
+
+### Task 11: Sitemap Update & Final SEO
+
+**Files:**
+- Modify: `app/sitemap.ts`
+
+- [ ] **Step 1: Remove /search from sitemap since it's noindexed**
+
+In `app/sitemap.ts`, find and remove any entry for `/search` (it's noindexed in its layout metadata, so including it in the sitemap is contradictory).
+
+- [ ] **Step 2: Commit**
+
+```bash
+git add app/sitemap.ts
+git commit -m "fix: remove noindexed /search page from sitemap"
+```
+
+---
+
+### Task 12: Build, Lint & Cleanup
+
+**Files:** All modified/created files
+
+- [ ] **Step 1: Run full build**
+
+Run: `cd /Users/adrianbonpin/Documents/Code/personal/deckyvault && bun run build 2>&1`
+Expected: Build succeeds with zero errors.
+
+- [ ] **Step 2: Fix any build errors**
+
+If the build fails, read the error messages, fix them, and re-run.
+
+- [ ] **Step 3: Run linter**
+
+Run: `cd /Users/adrianbonpin/Documents/Code/personal/deckyvault && bun run lint 2>&1`
+Expected: No errors.
+
+- [ ] **Step 4: Fix any lint warnings**
+
+If lint issues exist, fix them and re-run.
+
+- [ ] **Step 5: Final commit**
+
+```bash
+git add -A
+git commit -m "chore: fix build errors and lint warnings from devices/admin implementation"
+```