diff --git a/dashboard/app/api/auth/delete-account/route.ts b/dashboard/app/api/auth/delete-account/route.ts
new file mode 100644
index 0000000..855c102
--- /dev/null
+++ b/dashboard/app/api/auth/delete-account/route.ts
@@ -0,0 +1,16 @@
+import { NextResponse } from "next/server";
+import { getCurrentUser } from "@/server/current-user";
+import { prisma } from "@/server/db";
+import { SESSION_COOKIE, clearedCookieOptions } from "@/server/cookies";
+
+export async function DELETE() {
+ const user = await getCurrentUser();
+ if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
+
+ // Cascade in schema handles Sessions → Events/Tracks, and UserSetting
+ await prisma.user.delete({ where: { id: user.id } });
+
+ const res = NextResponse.json({ ok: true });
+ res.cookies.set(SESSION_COOKIE, "", clearedCookieOptions());
+ return res;
+}
diff --git a/dashboard/app/dashboard/account-menu.tsx b/dashboard/app/dashboard/account-menu.tsx
new file mode 100644
index 0000000..183a24a
--- /dev/null
+++ b/dashboard/app/dashboard/account-menu.tsx
@@ -0,0 +1,207 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { createPortal } from "react-dom";
+import { AnimatePresence, motion } from "framer-motion";
+import { useRouter } from "next/navigation";
+import { useQueryClient } from "@tanstack/react-query";
+
+type Menu = null | "account" | "delete-confirm";
+
+const backdrop = {
+ initial: { opacity: 0 },
+ animate: { opacity: 1 },
+ exit: { opacity: 0 },
+ transition: { duration: 0.2 },
+};
+
+const panel = {
+ initial: { opacity: 0, scale: 0.92, y: 16 },
+ animate: { opacity: 1, scale: 1, y: 0 },
+ exit: { opacity: 0, scale: 0.95, y: 8 },
+ transition: { type: "spring" as const, stiffness: 400, damping: 28, mass: 0.8 },
+};
+
+// Remove all cached report keys for a given email (or all wt:report:* keys)
+function clearReportCache(email: string) {
+ try {
+ const prefix = `wt:report:${email.toLowerCase().trim()}:`;
+ Object.keys(localStorage)
+ .filter((k) => k.startsWith(prefix))
+ .forEach((k) => localStorage.removeItem(k));
+ } catch { /* localStorage unavailable */ }
+}
+
+export function AccountMenu({ userEmail }: { userEmail: string }) {
+ const router = useRouter();
+ const queryClient = useQueryClient();
+ const [menu, setMenu] = useState