diff --git a/FORK.md b/FORK.md
new file mode 100644
index 0000000..3ea847f
--- /dev/null
+++ b/FORK.md
@@ -0,0 +1,113 @@
+# Work — notes for whoever picks this up
+
+A macOS desktop app that is a browser for one thing: the web tools you work in. A left
+nav lists them, clicking one shows it, links between them navigate inside the app, and
+everything else opens in your real browser. No address bar, no tab strip, no way to reach
+a site that is not on the list. That last part is the point, not a limitation.
+
+Tauri 2 · Rust · React 19 · TypeScript · Tailwind 4 · macOS only.
+
+```bash
+npm install
+npm run tauri dev # develop
+npm run ship # build, replace /Applications/Work.app, relaunch
+npm run ship -- --dmg # …and put an installer on the Desktop
+cd src-tauri && cargo test # 26 tests, all pure logic
+```
+
+Read `README.md` for what it does and
+`docs/superpowers/specs/2026-09-01-work-app-design.md` for why it is built this way. The
+git history is included and the commit messages carry the reasoning — most of them
+document a wrong turn before the fix.
+
+## The shape of it
+
+`src/` is the **shell**: the window's own webview, drawing the nav, dialogs, and an empty
+`
`. `src-tauri/src/` is Rust. Each configured app is its **own child
+webview** (`Window::add_child`, behind Tauri's `unstable` feature) positioned into the
+stage rect the shell measures and reports.
+
+| File | What it owns |
+|---|---|
+| `src-tauri/src/routing.rs` | Pure URL → stay / switch app / open externally. Unit-tested. |
+| `src-tauri/src/config.rs` | `apps.json`: apps, groups, hidden selectors, zoom, settings. |
+| `src-tauri/src/webviews.rs` | The child webviews, and every message from a page. |
+| `src-tauri/src/inject.js` | Runs inside every app: routing, hiding, notifications, unread, passwords. |
+| `src-tauri/src/downloads.rs` | Where downloads go and how they are announced. |
+| `src-tauri/src/commands.rs` | The command surface and all shared state. |
+
+**Pages talk to Rust over a made-up URL scheme**, not Tauri IPC — `workapp-route:`,
+`workapp-notify:`, `workapp-hide:` and friends. `on_navigation` answers them and cancels
+the navigation, so nothing ever loads. This is deliberate: IPC to a remote origin would
+mean granting google.com the ability to call into the app, and routing a link does not
+need anything that dangerous.
+
+## Things that cost real time here
+
+Every one of these was found the hard way. None is obvious from the docs.
+
+**A child webview is a native view painted above everything the shell draws.** A dialog
+cannot simply sit on a higher z-index — the app has to be moved out of the way first. A
+toast floating over the page is a toast *behind* the page. Anything the shell draws must
+either live in the nav, or the webviews must be moved aside for it.
+
+**Never `hide()` an inactive webview.** WebKit reads a hidden `NSView` as a page that is
+not visible, throttles its timers, and eventually suspends it — a backgrounded Gmail then
+stops fetching mail. Nothing is hidden; the active view is ordered on top and the rest
+stay full-size behind it.
+
+**Do not tell a background page it is hidden either.** Spoofing `document.visibilityState`
+seemed like the way to make it notify rather than stay quiet. It made Gmail throttle its
+*own* syncing instead: its unread count sat unchanged for two and a half minutes. Pages are
+told nothing. Instead every background app is poked every 45s with the events a page uses
+to catch up after you return to a tab.
+
+**Emit events from a spawned task, never from a webview callback.** `on_download` and
+friends run on the main thread inside WebKit's delegate, and delivering a Tauri event means
+running JavaScript in a webview — which cannot happen from in there. Emitted directly, the
+event is silently lost.
+
+**Anything that waits on a main-thread answer must not run on the main thread.** Snapshots,
+the traffic-light geometry, the title bar height: each deadlocks until its timeout and
+returns a fallback, silently, if called straight from a sync command. Measure once at
+startup or use `spawn_blocking`.
+
+**Tauri cannot tell you the title bar height on macOS.** `inner_position`/`outer_position`
+return the same point and `inner_size`/`outer_size` the same size, against a window whose
+content is plainly a title bar shorter than its frame. `NSWindow.contentLayoutRect` knows.
+The window's content also runs the *full* height underneath the bar, so the shell insets
+itself — and those inset strips must be `data-tauri-drag-region` or the window cannot be
+dragged.
+
+**WKWebView defines `window.Notification` and it does nothing.** No error, no banner — a
+page believes it notified you. It is replaced outright. Notifications are raised through
+`mac-notification-sys` rather than Tauri's plugin, because the plugin cannot report a
+click; `set_application` must be called or they arrive as `com.apple.Finder`; and the
+delegate needs a `shouldPresentNotification:` added at runtime or macOS suppresses the
+banner whenever the app is frontmost.
+
+**Icons come from the page, not an icon service.** A service asked about a domain can only
+guess — it returns a marketing site's icon for anything behind a login and nothing for a
+private host. The injected script reads `link[rel~="icon"]` instead, which is how Gmail's
+unread badge ends up in the nav.
+
+**Scope is the exact host.** `mail.google.com`, not `google.com`, or Gmail and Drive
+swallow each other's links. Longest match wins, and the app you are in gets first refusal.
+
+## Deliberately not built
+
+- **Browser cookie import.** It was built, measured, and removed: 43 cookies decrypted
+ from Arc and verifiably visible to the page, and Google, Microsoft and Odoo all refused
+ the imported sessions anyway. Signing in once inside the app is simpler and works.
+- **Windows and Linux.** Every hard-won thing above is AppKit-specific.
+- **Tabs, history, bookmarks, an address bar.** Not a general browser.
+- **Password autofill on page load.** Saving and an explicit right-click fill exist;
+ filling automatically is a much larger surface and was left as its own decision.
+
+## Known gaps
+
+- Service-worker push notifications are not covered — only what a page raises while open.
+- Downloads report a start and a finish and no progress; the file is polled as it grows.
+- One saved login per app; a second account on the same tool overwrites the first.
+- Ad-hoc signed, not notarised: a first launch elsewhere needs right-click → Open.
+- Apple Silicon only as configured.