diff --git a/docs/archive/postcss.config.mjs.experimental b/docs/archive/postcss.config.mjs.experimental
new file mode 100644
index 0000000..a34a3d5
--- /dev/null
+++ b/docs/archive/postcss.config.mjs.experimental
@@ -0,0 +1,5 @@
+export default {
+ plugins: {
+ '@tailwindcss/postcss': {},
+ },
+};
diff --git a/docs/archive/stashes/stash-0-root-leftovers.patch b/docs/archive/stashes/stash-0-root-leftovers.patch
new file mode 100644
index 0000000..fd7babd
--- /dev/null
+++ b/docs/archive/stashes/stash-0-root-leftovers.patch
@@ -0,0 +1,166 @@
+diff --git a/.gitignore b/.gitignore
+index eb35607..596f42a 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -3,3 +3,6 @@ node_modules/
+ *.tsbuildinfo
+ .worktrees/
+ worktrees/
++
++# bv (beads viewer) local config and caches
++.bv/
+diff --git a/src/app/globals.css b/src/app/globals.css
+index d17e938..a474080 100644
+--- a/src/app/globals.css
++++ b/src/app/globals.css
+@@ -3,15 +3,15 @@
+ @tailwind utilities;
+
+ :root {
+- --color-bg: #090c14;
+- --color-surface: #101827;
+- --color-surface-muted: #192336;
+- --color-surface-raised: #22314a;
+- --color-text-strong: #f6f8ff;
+- --color-text-body: #d8e0f1;
+- --color-text-muted: #9caccc;
+- --color-border-soft: rgba(145, 166, 204, 0.3);
+- --color-border-strong: rgba(187, 209, 246, 0.62);
++ --color-bg: #090909;
++ --color-surface: #161616;
++ --color-surface-muted: #212121;
++ --color-surface-raised: #2a2a2a;
++ --color-text-strong: #f5f5f5;
++ --color-text-body: #d0d0d0;
++ --color-text-muted: #9a9a9a;
++ --color-border-soft: rgba(255, 255, 255, 0.15);
++ --color-border-strong: rgba(255, 255, 255, 0.3);
+
+ --status-open: #60a5fa;
+ --status-progress: #fbbf24;
+@@ -38,10 +38,9 @@ body {
+
+ body {
+ background:
+- radial-gradient(circle at 10% 12%, rgba(12, 138, 215, 0.34), transparent 36%),
+- radial-gradient(circle at 84% 20%, rgba(250, 122, 91, 0.18), transparent 30%),
+- radial-gradient(circle at 68% 88%, rgba(57, 189, 154, 0.14), transparent 36%),
+- linear-gradient(155deg, #05070d 0%, #0b1322 42%, #121e34 100%);
++ radial-gradient(circle at 14% 12%, rgba(255, 255, 255, 0.05), transparent 36%),
++ radial-gradient(circle at 84% 18%, rgba(255, 180, 80, 0.06), transparent 32%),
++ linear-gradient(160deg, #070707 0%, #101010 48%, #161616 100%);
+ color: var(--color-text-body);
+- font-family: 'Segoe UI', 'Aptos', Inter, system-ui, sans-serif;
++ font-family: 'DM Sans', 'Segoe UI', Inter, system-ui, sans-serif;
+ }
+diff --git a/src/app/layout.tsx b/src/app/layout.tsx
+index ff1ad90..1417e77 100644
+--- a/src/app/layout.tsx
++++ b/src/app/layout.tsx
+@@ -1,7 +1,18 @@
+ import type { Metadata } from 'next';
++import { DM_Sans, JetBrains_Mono } from 'next/font/google';
+ import type { ReactNode } from 'react';
+ import './globals.css';
+
++const dmSans = DM_Sans({
++ subsets: ['latin'],
++ variable: '--font-ui',
++});
++
++const jetbrainsMono = JetBrains_Mono({
++ subsets: ['latin'],
++ variable: '--font-mono',
++});
++
+ export const metadata: Metadata = {
+ title: 'BeadBoard',
+ description: 'Windows-native Beads dashboard',
+@@ -10,7 +21,7 @@ export const metadata: Metadata = {
+ export default function RootLayout({ children }: { children: ReactNode }) {
+ return (
+
+-
{children}
++ {children}
+
+ );
+ }
+diff --git a/src/components/kanban/kanban-controls.tsx b/src/components/kanban/kanban-controls.tsx
+index 78b09f4..e1e04f9 100644
+--- a/src/components/kanban/kanban-controls.tsx
++++ b/src/components/kanban/kanban-controls.tsx
+@@ -14,7 +14,7 @@ interface KanbanControlsProps {
+
+ export function KanbanControls({ filters, stats, onFiltersChange }: KanbanControlsProps) {
+ const inputClass =
+- 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-cyan-300/70 focus:ring-2 focus:ring-cyan-300/20';
++ 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-border-strong focus:ring-2 focus:ring-white/10';
+
+ return (
+
+@@ -57,7 +57,7 @@ export function KanbanControls({ filters, stats, onFiltersChange }: KanbanContro
+ type="checkbox"
+ checked={filters.showClosed ?? false}
+ onChange={(event) => onFiltersChange({ ...filters, showClosed: event.target.checked })}
+- className="h-4 w-4 accent-cyan-400"
++ className="h-4 w-4 accent-amber-400"
+ />
+ Show closed
+
+diff --git a/src/components/shared/chip.tsx b/src/components/shared/chip.tsx
+index c1637e6..e29d49d 100644
+--- a/src/components/shared/chip.tsx
++++ b/src/components/shared/chip.tsx
+@@ -7,7 +7,7 @@ interface ChipProps {
+
+ const CHIP_TONE_CLASS: Record, string> = {
+ default: 'border-border-soft bg-surface-muted/75 text-text-body',
+- status: 'border-cyan-300/30 bg-cyan-500/20 text-cyan-50',
++ status: 'border-zinc-300/30 bg-zinc-500/20 text-zinc-100',
+ priority: 'border-amber-300/30 bg-amber-500/20 text-amber-50',
+ };
+
+diff --git a/tailwind.config.ts b/tailwind.config.ts
+index 5ad9067..953965c 100644
+--- a/tailwind.config.ts
++++ b/tailwind.config.ts
+@@ -5,8 +5,8 @@ const config: Config = {
+ theme: {
+ extend: {
+ fontFamily: {
+- ui: ['Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
+- mono: ['JetBrains Mono', 'Consolas', 'monospace'],
++ ui: ['var(--font-ui)', 'Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
++ mono: ['var(--font-mono)', 'Consolas', 'monospace'],
+ },
+ colors: {
+ bg: 'var(--color-bg)',
+diff --git a/tests/guards/kanban-responsive-contract.test.mjs b/tests/guards/kanban-responsive-contract.test.mjs
+index 4e02f28..3efabf4 100644
+--- a/tests/guards/kanban-responsive-contract.test.mjs
++++ b/tests/guards/kanban-responsive-contract.test.mjs
+@@ -9,11 +9,12 @@ async function read(relativePath) {
+ return fs.readFile(path.join(ROOT, relativePath), 'utf8');
+ }
+
+-test('kanban board uses intentional horizontal scroll affordances', async () => {
++test('kanban board uses expandable vertical swimlanes', async () => {
+ const board = await read('src/components/kanban/kanban-board.tsx');
+
+- assert.match(board, /snap-x/);
+- assert.match(board, /overflow-x-auto/);
++ assert.match(board, /aria-expanded/);
++ assert.match(board, /onActivateStatus/);
++ assert.match(board, /max-h-\[50vh\]/);
+ });
+
+ test('kanban page defines mobile detail drawer behavior', async () => {
+@@ -21,6 +22,8 @@ test('kanban page defines mobile detail drawer behavior', async () => {
+
+ assert.match(page, /fixed inset-0/);
+ assert.match(page, /lg:hidden/);
++ assert.match(page, /lg:grid-cols-\[minmax\(0,1fr\)_minmax\(22rem,26rem\)\]/);
++ assert.match(page, /lg:border-l/);
+ });
+
+ test('kanban controls use fluid full-width sizing on small viewports', async () => {
diff --git a/docs/archive/stashes/stash-1-agent-b-backlog.patch b/docs/archive/stashes/stash-1-agent-b-backlog.patch
new file mode 100644
index 0000000..fbaedf1
--- /dev/null
+++ b/docs/archive/stashes/stash-1-agent-b-backlog.patch
@@ -0,0 +1,1087 @@
+diff --git a/package-lock.json b/package-lock.json
+index 7a082ab..e0c00b5 100644
+--- a/package-lock.json
++++ b/package-lock.json
+@@ -14,13 +14,29 @@
+ "react-dom": "19.2.1"
+ },
+ "devDependencies": {
++ "@tailwindcss/postcss": "^4.1.18",
+ "@types/node": "^22.10.0",
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
++ "lightningcss-win32-x64-msvc": "^1.30.2",
++ "tailwindcss": "^4.1.18",
+ "tsx": "^4.21.0",
+ "typescript": "^5.7.2"
+ }
+ },
++ "node_modules/@alloc/quick-lru": {
++ "version": "5.2.0",
++ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
++ "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
++ "dev": true,
++ "license": "MIT",
++ "engines": {
++ "node": ">=10"
++ },
++ "funding": {
++ "url": "https://github.com/sponsors/sindresorhus"
++ }
++ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
+@@ -939,6 +955,56 @@
+ "url": "https://opencollective.com/libvips"
+ }
+ },
++ "node_modules/@jridgewell/gen-mapping": {
++ "version": "0.3.13",
++ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
++ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "@jridgewell/sourcemap-codec": "^1.5.0",
++ "@jridgewell/trace-mapping": "^0.3.24"
++ }
++ },
++ "node_modules/@jridgewell/remapping": {
++ "version": "2.3.5",
++ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
++ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "@jridgewell/gen-mapping": "^0.3.5",
++ "@jridgewell/trace-mapping": "^0.3.24"
++ }
++ },
++ "node_modules/@jridgewell/resolve-uri": {
++ "version": "3.1.2",
++ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
++ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
++ "dev": true,
++ "license": "MIT",
++ "engines": {
++ "node": ">=6.0.0"
++ }
++ },
++ "node_modules/@jridgewell/sourcemap-codec": {
++ "version": "1.5.5",
++ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
++ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
++ "dev": true,
++ "license": "MIT"
++ },
++ "node_modules/@jridgewell/trace-mapping": {
++ "version": "0.3.31",
++ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
++ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "@jridgewell/resolve-uri": "^3.1.0",
++ "@jridgewell/sourcemap-codec": "^1.4.14"
++ }
++ },
+ "node_modules/@next/env": {
+ "version": "15.5.7",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.7.tgz",
+@@ -1082,6 +1148,546 @@
+ "tslib": "^2.8.0"
+ }
+ },
++ "node_modules/@tailwindcss/node": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz",
++ "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "@jridgewell/remapping": "^2.3.4",
++ "enhanced-resolve": "^5.18.3",
++ "jiti": "^2.6.1",
++ "lightningcss": "1.30.2",
++ "magic-string": "^0.30.21",
++ "source-map-js": "^1.2.1",
++ "tailwindcss": "4.1.18"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
++ "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
++ "dev": true,
++ "license": "MPL-2.0",
++ "dependencies": {
++ "detect-libc": "^2.0.3"
++ },
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ },
++ "optionalDependencies": {
++ "lightningcss-android-arm64": "1.30.2",
++ "lightningcss-darwin-arm64": "1.30.2",
++ "lightningcss-darwin-x64": "1.30.2",
++ "lightningcss-freebsd-x64": "1.30.2",
++ "lightningcss-linux-arm-gnueabihf": "1.30.2",
++ "lightningcss-linux-arm64-gnu": "1.30.2",
++ "lightningcss-linux-arm64-musl": "1.30.2",
++ "lightningcss-linux-x64-gnu": "1.30.2",
++ "lightningcss-linux-x64-musl": "1.30.2",
++ "lightningcss-win32-arm64-msvc": "1.30.2",
++ "lightningcss-win32-x64-msvc": "1.30.2"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-android-arm64": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
++ "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "android"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-arm64": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
++ "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "darwin"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-x64": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
++ "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "darwin"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-freebsd-x64": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
++ "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "freebsd"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm-gnueabihf": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
++ "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
++ "cpu": [
++ "arm"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-gnu": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
++ "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-musl": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
++ "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-gnu": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
++ "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-musl": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
++ "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/node/node_modules/lightningcss-win32-arm64-msvc": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
++ "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "optional": true,
++ "os": [
++ "win32"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/@tailwindcss/oxide": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
++ "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
++ "dev": true,
++ "license": "MIT",
++ "engines": {
++ "node": ">= 10"
++ },
++ "optionalDependencies": {
++ "@tailwindcss/oxide-android-arm64": "4.1.18",
++ "@tailwindcss/oxide-darwin-arm64": "4.1.18",
++ "@tailwindcss/oxide-darwin-x64": "4.1.18",
++ "@tailwindcss/oxide-freebsd-x64": "4.1.18",
++ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
++ "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
++ "@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
++ "@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
++ "@tailwindcss/oxide-linux-x64-musl": "4.1.18",
++ "@tailwindcss/oxide-wasm32-wasi": "4.1.18",
++ "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
++ "@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-android-arm64": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
++ "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "android"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-darwin-arm64": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
++ "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "darwin"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-darwin-x64": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
++ "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "darwin"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-freebsd-x64": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
++ "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "freebsd"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
++ "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
++ "cpu": [
++ "arm"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
++ "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
++ "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
++ "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
++ "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "linux"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
++ "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
++ "bundleDependencies": [
++ "@napi-rs/wasm-runtime",
++ "@emnapi/core",
++ "@emnapi/runtime",
++ "@tybys/wasm-util",
++ "@emnapi/wasi-threads",
++ "tslib"
++ ],
++ "cpu": [
++ "wasm32"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "dependencies": {
++ "@emnapi/core": "^1.7.1",
++ "@emnapi/runtime": "^1.7.1",
++ "@emnapi/wasi-threads": "^1.1.0",
++ "@napi-rs/wasm-runtime": "^1.1.0",
++ "@tybys/wasm-util": "^0.10.1",
++ "tslib": "^2.4.0"
++ },
++ "engines": {
++ "node": ">=14.0.0"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
++ "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
++ "cpu": [
++ "arm64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "win32"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
++ "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MIT",
++ "optional": true,
++ "os": [
++ "win32"
++ ],
++ "engines": {
++ "node": ">= 10"
++ }
++ },
++ "node_modules/@tailwindcss/postcss": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz",
++ "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "@alloc/quick-lru": "^5.2.0",
++ "@tailwindcss/node": "4.1.18",
++ "@tailwindcss/oxide": "4.1.18",
++ "postcss": "^8.4.41",
++ "tailwindcss": "4.1.18"
++ }
++ },
++ "node_modules/@tailwindcss/postcss/node_modules/postcss": {
++ "version": "8.5.6",
++ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
++ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
++ "dev": true,
++ "funding": [
++ {
++ "type": "opencollective",
++ "url": "https://opencollective.com/postcss/"
++ },
++ {
++ "type": "tidelift",
++ "url": "https://tidelift.com/funding/github/npm/postcss"
++ },
++ {
++ "type": "github",
++ "url": "https://github.com/sponsors/ai"
++ }
++ ],
++ "license": "MIT",
++ "dependencies": {
++ "nanoid": "^3.3.11",
++ "picocolors": "^1.1.1",
++ "source-map-js": "^1.2.1"
++ },
++ "engines": {
++ "node": "^10 || ^12 || >=14"
++ }
++ },
+ "node_modules/@types/node": {
+ "version": "22.19.11",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz",
+@@ -1149,12 +1755,26 @@
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
++ "devOptional": true,
+ "license": "Apache-2.0",
+- "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
++ "node_modules/enhanced-resolve": {
++ "version": "5.19.0",
++ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
++ "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "graceful-fs": "^4.2.4",
++ "tapable": "^2.3.0"
++ },
++ "engines": {
++ "node": ">=10.13.0"
++ }
++ },
+ "node_modules/esbuild": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
+@@ -1225,6 +1845,53 @@
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
++ "node_modules/graceful-fs": {
++ "version": "4.2.11",
++ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
++ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
++ "dev": true,
++ "license": "ISC"
++ },
++ "node_modules/jiti": {
++ "version": "2.6.1",
++ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
++ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
++ "dev": true,
++ "license": "MIT",
++ "bin": {
++ "jiti": "lib/jiti-cli.mjs"
++ }
++ },
++ "node_modules/lightningcss-win32-x64-msvc": {
++ "version": "1.30.2",
++ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
++ "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
++ "cpu": [
++ "x64"
++ ],
++ "dev": true,
++ "license": "MPL-2.0",
++ "os": [
++ "win32"
++ ],
++ "engines": {
++ "node": ">= 12.0.0"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/parcel"
++ }
++ },
++ "node_modules/magic-string": {
++ "version": "0.30.21",
++ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
++ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
++ "dev": true,
++ "license": "MIT",
++ "dependencies": {
++ "@jridgewell/sourcemap-codec": "^1.5.5"
++ }
++ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+@@ -1457,6 +2124,27 @@
+ }
+ }
+ },
++ "node_modules/tailwindcss": {
++ "version": "4.1.18",
++ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
++ "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
++ "dev": true,
++ "license": "MIT"
++ },
++ "node_modules/tapable": {
++ "version": "2.3.0",
++ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
++ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
++ "dev": true,
++ "license": "MIT",
++ "engines": {
++ "node": ">=6"
++ },
++ "funding": {
++ "type": "opencollective",
++ "url": "https://opencollective.com/webpack"
++ }
++ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+diff --git a/package.json b/package.json
+index d74369c..f4adadb 100644
+--- a/package.json
++++ b/package.json
+@@ -9,7 +9,7 @@
+ "start": "next start",
+ "lint": "next lint",
+ "typecheck": "tsc --noEmit",
+- "test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/lib/kanban.test.ts && node --import tsx --test tests/lib/read-issues.test.ts && node --test tests/guards/no-direct-jsonl-write.test.mjs"
++ "test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/lib/kanban.test.ts && node --import tsx --test tests/lib/read-issues.test.ts && node --test tests/guards/no-direct-jsonl-write.test.mjs && node --test tests/guards/no-inline-style-in-kanban.test.mjs"
+ },
+ "dependencies": {
+ "next": "15.5.7",
+@@ -17,9 +17,12 @@
+ "react-dom": "19.2.1"
+ },
+ "devDependencies": {
++ "@tailwindcss/postcss": "^4.1.18",
+ "@types/node": "^22.10.0",
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
++ "lightningcss-win32-x64-msvc": "^1.30.2",
++ "tailwindcss": "^4.1.18",
+ "tsx": "^4.21.0",
+ "typescript": "^5.7.2"
+ }
+diff --git a/src/app/layout.tsx b/src/app/layout.tsx
+index dd3008b..1d731f8 100644
+--- a/src/app/layout.tsx
++++ b/src/app/layout.tsx
+@@ -1,5 +1,18 @@
+ import type { Metadata } from 'next';
+ import type { ReactNode } from 'react';
++import { DM_Sans, JetBrains_Mono } from 'next/font/google';
++
++import './globals.css';
++
++const sans = DM_Sans({
++ subsets: ['latin'],
++ variable: '--font-sans',
++});
++
++const mono = JetBrains_Mono({
++ subsets: ['latin'],
++ variable: '--font-mono',
++});
+
+ export const metadata: Metadata = {
+ title: 'BeadBoard',
+@@ -9,7 +22,7 @@ export const metadata: Metadata = {
+ export default function RootLayout({ children }: { children: ReactNode }) {
+ return (
+
+- {children}
++ {children}
+
+ );
+ }
+diff --git a/src/components/kanban/kanban-board.tsx b/src/components/kanban/kanban-board.tsx
+index 34eea9d..8d61fa0 100644
+--- a/src/components/kanban/kanban-board.tsx
++++ b/src/components/kanban/kanban-board.tsx
+@@ -12,22 +12,23 @@ interface KanbanBoardProps {
+ }
+
+ export function KanbanBoard({ columns, selectedIssueId, onSelect }: KanbanBoardProps) {
++ const statusTone: Record<(typeof KANBAN_STATUSES)[number], string> = {
++ open: 'text-status-open',
++ in_progress: 'text-status-in-progress',
++ blocked: 'text-status-blocked',
++ deferred: 'text-status-deferred',
++ closed: 'text-status-closed',
++ };
++
+ return (
+-
++
+ {KANBAN_STATUSES.map((status) => (
+-
+-
+-
{status}
+-
{columns[status].length}
++
++
++ {status.replace('_', ' ')}
++ {columns[status].length}
+
+-
++
+ {columns[status].map((issue) => (
+
+ ))}
+diff --git a/src/components/kanban/kanban-card.tsx b/src/components/kanban/kanban-card.tsx
+index 04df80b..51b5924 100644
+--- a/src/components/kanban/kanban-card.tsx
++++ b/src/components/kanban/kanban-card.tsx
+@@ -11,32 +11,32 @@ interface KanbanCardProps {
+ }
+
+ export function KanbanCard({ issue, selected, onSelect }: KanbanCardProps) {
++ const priorityTone: Record
= {
++ 0: 'text-priority-0',
++ 1: 'text-priority-1',
++ 2: 'text-priority-2',
++ 3: 'text-priority-3',
++ 4: 'text-priority-4',
++ };
++
+ return (
+