diff --git a/.gitignore b/.gitignore
index 09a2363..c2c69fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,5 @@ pnpm-debug.log*
docs/designs/_ref
+.qoder/
diff --git a/bun.lock b/bun.lock
index 9db730e..8dc909d 100644
--- a/bun.lock
+++ b/bun.lock
@@ -6,6 +6,7 @@
"name": "orchids-project",
"dependencies": {
"@astrojs/sitemap": "3.7.3",
+ "@libredb/libredb": "0.1.3",
"@tailwindcss/vite": "4.3.1",
"astro": "7.0.3",
"tailwindcss": "4.3.1",
@@ -235,6 +236,8 @@
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+ "@libredb/libredb": ["@libredb/libredb@0.1.3", "", { "bin": { "libredb": "dist/cli/main.js" } }, "sha512-TuQRLz+sEIx0YJSvT9tiin4yehpqdG1kalPgVtnGhw78JmgUsLryS3/sbNMI2X3sTxE+8Gel7CvUim6s2azYDQ=="],
+
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="],
"@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
diff --git a/docs/superpowers/plans/2026-06-30-playground-opfs-editor.md b/docs/superpowers/plans/2026-06-30-playground-opfs-editor.md
new file mode 100644
index 0000000..e4e13dc
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-30-playground-opfs-editor.md
@@ -0,0 +1,1066 @@
+# /playground OPFS Editor Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Add a public `/playground` route that runs a real OPFS-backed LibreDB entirely in the browser — preloaded sample data, a clickable command cheatsheet, reset, and graceful in-memory fallback — with no backend and no login.
+
+**Architecture:** A SSR-safe Astro page reuses the site's `StudioShell` chrome and mounts a client-only island. The engine runs in a Web Worker (OPFS sync-access handles are Worker-only); the UI talks to it over `postMessage`. Pure, testable modules (`protocol`, `engine`) hold the command grammar and lens dispatch; the worker and client are thin shells around them.
+
+**Tech Stack:** Astro 7 (static, no React), TypeScript (strict), Tailwind 4, `@libredb/libredb@0.1.3` (`/browser` entry), `bun:test`, Playwright (MCP) for browser verification.
+
+## Global Constraints
+
+- Import the engine **only** from `@libredb/libredb/browser` (its import graph reaches no `node:` module). Never import the bare `@libredb/libredb`.
+- **No engine/DOM/Worker code may run during SSR.** All engine code lives in the Worker or in client `
+```
+
+- [ ] **Step 3: Create `src/pages/playground.astro`**
+
+```astro
+---
+import Layout from "../layouts/Layout.astro";
+import StudioShell from "../components/studio/StudioShell.astro";
+import Playground from "../components/studio/Playground.astro";
+---
+
+
+
+
+
+
+```
+
+- [ ] **Step 4: Add the nav link in `src/components/studio/TopBar.astro`**
+
+Read the file first. Find the existing top-bar link/menu markup and add, following the surrounding pattern, a link whose `href="/playground"` labeled `Playground`. Do **not** modify `src/data/sections.ts` (that drives the schema explorer rows and homepage nav). Keep the change to a single anchor consistent with the existing nav items.
+
+- [ ] **Step 5: Verify it builds and renders**
+
+Run: `bun run build 2>&1 | tail -25`
+Expected: build succeeds; `dist/playground/index.html` exists.
+Then revert the build-mutated compose files:
+Run: `git checkout -- src/data/docker-compose.example.yml public/docker-compose.example.yml 2>/dev/null; git status --short`
+Expected: only the new/intended files show as changes.
+
+- [ ] **Step 6: Commit**
+
+```bash
+git add src/components/studio/Cheatsheet.astro src/components/studio/Playground.astro src/pages/playground.astro src/components/studio/TopBar.astro
+git commit -m "feat(playground): editor pane, cheatsheet, route, nav link (#19)"
+```
+
+---
+
+## Task 6: Gate + browser verification (Playwright)
+
+**Files:** none created — verification only.
+
+- [ ] **Step 1: Run the full gate**
+
+Run: `bun run gate 2>&1 | tail -30`
+Expected: typecheck, format, lint, knip, and all `bun:test` pass. Fix any failures (likely knip on unused exports — ensure every new export is consumed; prettier — run `bun run format:fix`).
+
+- [ ] **Step 2: Serve the production build with caching disabled**
+
+Run (background): `bunx http-server dist -p 8081 -c-1`
+(Use a cache-disabled static server per the repo's VT runtime-testing note.)
+
+- [ ] **Step 3: Playwright — load and assert seed renders**
+
+Navigate to `http://localhost:8081/playground`. Take a snapshot. Assert:
+- The result grid shows the 3 seeded users (Ada, Linus, Grace).
+- The persistence badge reads `OPFS · persistent` (Chromium on localhost is a secure context with OPFS).
+
+- [ ] **Step 4: Playwright — click-to-run, persist, reset**
+
+- Click the cheatsheet button `insert into users {"id":"4","name":"Lin","age":29,"active":true}`, then `select * from users` → assert a 4th row `Lin` appears.
+- Reload the page → assert `Lin` is still present (OPFS persistence across reload).
+- Click `↺ Reset sandbox` → assert the grid returns to exactly the 3 seed rows.
+- Click `prefix config:` → assert key/value rows for `config:*` render.
+
+- [ ] **Step 5: Confirm no `node:` in the client bundle**
+
+Run: `grep -rl "node:fs\|require(\"fs\")\|node_fs" dist/assets/*.js | head` (or scan the playground chunk).
+Expected: no matches — the browser entry pulled no `node:` module into the client bundle.
+
+- [ ] **Step 6: Final commit (if any verification fixes were needed)**
+
+```bash
+git add -A && git commit -m "test(playground): gate fixes + browser-verified OPFS demo (#19)"
+```
+
+---
+
+## Self-Review
+
+- **Spec coverage:** Public no-login route (Task 5) ✓ · client-side OPFS Worker, no backend (Tasks 3,6) ✓ · 3-lens seed (Task 2) ✓ · clickable palette (Tasks 4,5) ✓ · persist + isolate + reset (Tasks 3,6) ✓ · no `node:fs`, marketing build unaffected (Task 6, TopBar-only nav change) ✓ · in-memory fallback + notice (Tasks 3,4,5) ✓ · `db.close()` teardown (Tasks 3,4) ✓ · no SSR engine code (Task 5 client-only `
diff --git a/src/components/studio/TopBar.astro b/src/components/studio/TopBar.astro
index 9bca776..2c80247 100644
--- a/src/components/studio/TopBar.astro
+++ b/src/components/studio/TopBar.astro
@@ -43,6 +43,9 @@ const DEMO = 'https://app.libredb.org';
data-action="notice"
data-notice="monitoring">◷ Monitoring
+
+ ▶ Playground
+