diff --git a/monoline_telescope_icon.html b/design/monoline_telescope_icon.html
similarity index 100%
rename from monoline_telescope_icon.html
rename to design/monoline_telescope_icon.html
diff --git a/rotated_wings_svg.svg b/design/rotated_wings_svg.svg
similarity index 100%
rename from rotated_wings_svg.svg
rename to design/rotated_wings_svg.svg
diff --git a/js/web/package.json b/js/web/package.json
index 26c8139a..4f1cd2af 100644
--- a/js/web/package.json
+++ b/js/web/package.json
@@ -49,7 +49,6 @@
"sonare": "^0.0.1",
"sonner": "^2.0.7",
"streamplace": "workspace:*",
- "tiptap": "^1.32.2",
"tus-js-client": "^4.3.1",
"tw-animate-css": "^1.4.0",
"viem": "^2.47.2",
@@ -64,7 +63,7 @@
"@types/react-dom": "^19.2.0",
"@vitejs/plugin-react": "^4.3.0",
"emojibase-data": "^17.0.0",
- "prettier": "3.4.2",
+ "prettier": "3.8.4",
"prettier-plugin-tailwindcss": "^0.8.0",
"tailwindcss": "^4.3.0",
"typescript": "^5.8.3",
diff --git a/js/web/plan.md b/js/web/plan.md
deleted file mode 100644
index 8896acd3..00000000
--- a/js/web/plan.md
+++ /dev/null
@@ -1,558 +0,0 @@
-# Streamplace Web App: Migration Plan
-
-## What We're Doing
-
-The existing React Native app (`js/app`) is the source of truth. The new web app (`js/web`) is a fresh Vite + TanStack Router SPA built with true DOM, Tailwind, and Base UI. It's already a solid foundation but has explicit Phase 3/4 stubs for core streaming features. This plan prioritizes reaching full feature parity with the RN app, then layering on web-native advantages.
-
-## Where We Are Today
-
-### Web App: What Works (Phase 1-2)
-
-- Home feed with live user grid
-- Single live stream viewer (HLS + WebRTC)
-- Single VOD viewer
-- VOD browse
-- VOD upload (tus-js-client, metadata, thumbnails, progress)
-- OAuth login/registration
-- Chat (send/receive, mentions, emoji)
-- Settings: account, streaming (keys with create/delete), recommendations, webhooks, multistream, privacy, backup, branding, badges, languages, advanced, about
-- Player with stats overlay, keyboard shortcuts, quality selector
-- i18n (7 locales via `@streamplace/i18n`)
-
-### Web App: Explicitly Stubbed (Phase 3/4)
-
-From `blueskySlice.ts` header comments:
-
-- `createLivestreamRecord` - throws
-- `updateLivestreamRecord` - throws
-- `golivePost` - throws
-- `createBlockRecord` - throws (low priority, not in RN either)
-
-### Web App: Missing Entirely
-
-- Go-live flow (no route, no UI, no broadcaster backend)
-- Following feed (sidebar "Following" is disabled)
-- Notifications surface (no route, no header bell)
-- Multi-stream viewer (grid of multiple live streams; `dashboard/multistream/` is for RTMP target management, not viewing)
-- Popout windows (livestream, multistream, stream monitor, info widget)
-- Download screen
-- Support screen
-- "What is Streamplace?" about screen (web has `/settings/about` but that's settings-scoped, not a public landing page)
-
-### RN App: Feature Inventory
-
-All screens in `js/app/src/screens/`:
-
-| Screen | Purpose |
-| --------------------------- | ------------------------------------------ |
-| `home.tsx` | Live stream grid with pull-to-refresh |
-| `mobile-stream.tsx` | Live stream viewer (full-screen on mobile) |
-| `mobile-go-live.tsx` | Go-live with ingest player |
-| `launch-go-live.tsx` | "Ready to go live?" prompt |
-| `live-dashboard.tsx` | BentoGrid broadcaster dashboard |
-| `video-list.tsx` | VOD browse |
-| `video.tsx` | Single VOD playback |
-| `vod.tsx` | VOD screen |
-| `upload.tsx` | VOD upload (1484 lines, tus-js-client) |
-| `chat-popout.tsx` | Popout chat window |
-| `multi.tsx` | Multi-stream viewer |
-| `about.tsx` | "What is Streamplace?" |
-| `download.tsx` | Download app |
-| `embed.tsx` | Stream embed |
-| `vod-embed.tsx` | VOD embed |
-| `danmu-obs.tsx` | Danmu OBS overlay |
-| `info-widget-embed.tsx` | Info widget embed |
-| `popout-livestream.tsx` | Popout livestream window |
-| `popout-multistream.tsx` | Popout multistream window |
-| `popout-stream-monitor.tsx` | Stream monitor popout |
-| `popout-info-widget.tsx` | Info widget popout |
-| `support.tsx` | Support page |
-| `app-return.tsx` | OAuth return handling |
-
-### Screen-by-Screen Comparison
-
-| RN Screen | Web Equivalent | Status | Notes |
-| --------------------------- | ------------------------------ | ---------- | ---------------------------------------------------------------------------------------- |
-| `home.tsx` | `$user/index.tsx`, `index.tsx` | ✅ Parity | Web has infinite scroll instead of pull-to-refresh. Both show live grid + viewer counts. |
-| `mobile-stream.tsx` | `$user/index.tsx` | ⚠️ Partial | Web is desktop-focused. No dedicated mobile-optimized live view. |
-| `mobile-go-live.tsx` | — | ❌ Missing | Mobile camera ingest, no web equivalent. |
-| `launch-go-live.tsx` | — | ❌ Missing | "Ready to go live?" prompt, no web equivalent. |
-| `live-dashboard.tsx` | `dashboard/stream/index.tsx` | ✅ Parity | Web has additional metadata/moderation sections. |
-| `video-list.tsx` | `videos.tsx` | ✅ Parity | Both use same API, infinite scroll, responsive grid. |
-| `video.tsx` | `$user/video/$tid.tsx` | ✅ Parity | Single VOD playback. |
-| `vod.tsx` | `$user/video/$tid.tsx` | ✅ Merged | RN has separate vod.tsx and video.tsx; web combines into one route. |
-| `upload.tsx` | `dashboard/upload.tsx` | ✅ Done | tus upload, metadata form, thumbnail, progress. In creator dashboard. |
-| `chat-popout.tsx` | `chat-popout.$user.tsx` | ✅ Done | Standalone chat window. |
-| `multi.tsx` | — | ❌ Missing | Grid of multiple simultaneous live streams. Not the same as dashboard/multistream. |
-| `about.tsx` | `settings/about.tsx` | ⚠️ Partial | Web version is settings-scoped. RN has a public "What is Streamplace?" page. |
-| `download.tsx` | — | ❌ Missing | App download/promo page with store links. |
-| `embed.tsx` | `embed/$user/index.tsx` | ✅ Done | Minimal-chrome stream embed. |
-| `vod-embed.tsx` | `embed/$user/video/$tid.tsx` | ✅ Done | VOD embed. |
-| `danmu-obs.tsx` | `embed/danmu-obs/$user.tsx` | ✅ Done | Danmu OBS overlay, full feature parity. |
-| `info-widget-embed.tsx` | `embed/info-widget/$user.tsx` | ✅ Done | Info widget embed. |
-| `popout-livestream.tsx` | — | ❌ Missing | Popout livestream player window. |
-| `popout-multistream.tsx` | — | ❌ Missing | Popout multistream window. |
-| `popout-stream-monitor.tsx` | — | ❌ Missing | Popout stream monitor. |
-| `popout-info-widget.tsx` | — | ❌ Missing | Covered by `/embed/info-widget/$user` but no dedicated popout route. |
-| `support.tsx` | — | ❌ Missing | Redirects to Google Form. |
-| `app-return.tsx` | Handled by `login.tsx` | ✅ Done | OAuth callback handled differently on web. |
-
-### Web Features Beyond RN Parity
-
-| Feature | Status | Notes |
-| ---------------------------------- | ------- | ------------------------------------------------------------ |
-| Search (header bar + popover) | ✅ Done | RN has no equivalent search UI. |
-| Danmu overlay | ✅ Done | Bullet comments with lane assignment, mobile parity. |
-| Theatre mode | ✅ Done | Sidebar + header hidden, `T` shortcut. RN has no equivalent. |
-| Picture-in-Picture | ✅ Done | Web-native PiP API. RN has no equivalent. |
-| Dashboard webhooks/branding/badges | ✅ Done | Advanced settings panels not in RN. |
-| Keyboard shortcuts | ✅ Done | Space, m, f, T shortcuts. RN has no equivalent. |
-
-### RN App: Navigation Tree
-
-```
-RootStack
-├── MainTabs
-│ ├── HomeTab → HomeNavigator
-│ │ ├── HomeMain (home.tsx)
-│ │ ├── About
-│ │ ├── Download
-│ │ ├── LiveDashboard
-│ │ ├── Login
-│ │ ├── Multi
-│ │ ├── Support
-│ │ └── Upload (web only)
-│ ├── VideosTab → VideosNavigator
-│ │ ├── VideoList
-│ │ └── UserVideoList
-│ ├── GoLiveTab → LaunchGoLive
-│ └── SettingsTab → SettingsNavigator
-│ ├── MainSettings
-│ ├── AboutCategory
-│ ├── AccountCategory
-│ ├── StreamingCategory
-│ ├── WebhooksSettings
-│ ├── BackupSettings
-│ ├── RecommendationsSettings
-│ ├── PrivacyCategory
-│ ├── DanmuCategory
-│ ├── AdvancedCategory
-│ ├── MultistreamCategory
-│ ├── LanguagesCategory
-│ ├── KeyManagement
-│ ├── BadgeSelection
-│ ├── BadgeIssuer
-│ └── BrandingAdmin
-├── Stream (MobileStream)
-├── MobileGoLive
-├── Video
-├── Vod
-├── PopoutChat
-├── Embed / VodEmbed / InfoWidgetEmbed / DanmuOBS
-├── PopoutStreamMonitor / PopoutInfoWidget / PopoutMultistream / PopoutLivestream
-└── AppReturn
-```
-
-### Shared Packages
-
-| Package | Web Safe? | Used by Web? | Notes |
-| ------------------------------- | ------------ | ------------ | -------------------------------------------------------------------------------------- |
-| `@streamplace/core` | Mostly yes | Yes | LivestreamStore, handleWebSocketMessages, reduceChat, segmentize, Facet |
-| `@streamplace/i18n` | Yes | Yes | manifest, createI18nextConfig, locale resources |
-| `@streamplace/components` | No (RN deps) | No | Contains Player, settings panels, hooks, but depends on react-native, expo-video, etc. |
-| `streamplace` | Yes | Yes | PlaceStream\* types, agent methods |
-| `js/playback-router` | Likely yes | No | Not imported by web, worker-specific |
-| `js/config-react-native-webrtc` | No | No | RN-specific |
-
-### RN Platform Dependencies in Active Use
-
-| Dependency | Used In (RN) | Web Equivalent |
-| --------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- |
-| `expo-video` | Player components | Native `