diff --git a/COOKIE_AUTH_IMPLEMENTATION.md b/COOKIE_AUTH_IMPLEMENTATION.md
new file mode 100644
index 0000000..e06f356
--- /dev/null
+++ b/COOKIE_AUTH_IMPLEMENTATION.md
@@ -0,0 +1,338 @@
+# Cookie-Based Authentication Implementation
+
+**Date**: 2025-11-27
+**Status**: Complete
+
+This document captures the full implementation of HttpOnly cookie-based authentication, including all issues encountered and their solutions.
+
+---
+
+## Architecture Overview
+
+```
+Browser → Nginx Proxy Manager → Nuxt SSR → Backend API
+ (gameplay-demo.manticorum.com)
+```
+
+### Authentication Flow
+
+1. User clicks "Continue with Discord" (anchor tag, NOT JavaScript)
+2. Browser navigates to `/api/auth/discord/login`
+3. Backend creates state in Redis, redirects to Discord OAuth
+4. User authorizes on Discord
+5. Discord redirects to `/api/auth/discord/callback/server`
+6. Backend validates, creates JWT, sets HttpOnly cookies with `path="/"`
+7. Backend redirects to frontend `/games`
+8. Nuxt SSR middleware forwards cookies to `/api/auth/me`
+9. Backend validates cookie, returns user info
+10. Page renders with authenticated state
+
+---
+
+## Critical Implementation Details
+
+### 1. Cookie Configuration (Backend)
+
+**File**: `backend/app/utils/cookies.py`
+
+```python
+response.set_cookie(
+ key="pd_access_token",
+ value=access_token,
+ max_age=3600, # 1 hour
+ httponly=True,
+ secure=is_secure_context(), # True for HTTPS even in dev
+ samesite="lax",
+ path="/", # CRITICAL: Must be "/" not "/api"
+)
+```
+
+**Why `is_secure_context()` instead of `is_production()`?**
+- Safari/iOS requires `Secure=true` for cookies over HTTPS connections
+- Even in development, if accessed via HTTPS (through proxy), cookies need `Secure=true`
+- `is_secure_context()` returns `True` if `APP_ENV=production` OR `FRONTEND_URL` starts with `https://`
+
+**Why `path="/"`?**
+- Cookies with `path="/api"` are only sent to `/api/*` routes
+- When browser requests `/games`, cookie isn't sent
+- SSR server receives no cookie to forward
+- Auth check fails → redirect loop
+
+### 2. Login Button (Frontend)
+
+**File**: `frontend-sba/pages/auth/login.vue`
+
+**MUST use anchor tag, NOT JavaScript button:**
+
+```vue
+
+
+ Continue with Discord
+
+
+
+
+```
+
+**Why?**
+- iPad Safari blocks async JavaScript on certain pages
+- Nginx Proxy Manager may interfere with JS execution
+- Anchor tags work reliably in all scenarios
+
+### 3. Auth Middleware (Frontend)
+
+**File**: `frontend-sba/middleware/auth.ts`
+
+```typescript
+export default defineNuxtRouteMiddleware(async (to, from) => {
+ const authStore = useAuthStore()
+
+ if (authStore.isAuthenticated) {
+ return // Already authenticated
+ }
+
+ // Call backend to verify cookies
+ const isAuthed = await authStore.checkAuth()
+
+ if (!isAuthed) {
+ return navigateTo('/auth/login')
+ }
+})
+```
+
+### 4. Auth Store - Cookie Forwarding for SSR
+
+**File**: `frontend-sba/store/auth.ts`
+
+```typescript
+async function checkAuth(): Promise {
+ const headers: Record = {}
+
+ // SSR: Forward cookies from incoming request
+ if (import.meta.server) {
+ const event = useRequestEvent()
+ const cookieHeader = event?.node.req.headers.cookie
+ if (cookieHeader) {
+ headers['Cookie'] = cookieHeader
+ }
+ }
+
+ const response = await $fetch('/api/auth/me', {
+ credentials: 'include', // Client-side
+ headers, // Server-side cookie forwarding
+ })
+
+ // ... handle response
+}
+```
+
+### 5. API Calls - Use Cookies, Not Tokens
+
+**All API calls must use `credentials: 'include'`:**
+
+```typescript
+// CORRECT
+const response = await $fetch('/api/games/', {
+ credentials: 'include',
+})
+
+// WRONG - authStore.token no longer exists
+const response = await $fetch('/api/games/', {
+ headers: {
+ Authorization: `Bearer ${authStore.token}`
+ }
+})
+```
+
+---
+
+## Common Issues & Solutions
+
+### Issue 1: "Continue with Discord" Does Nothing
+
+**Symptom**: Clicking login button has no effect
+
+**Cause**: Using `