` 404s in the dev server but the file exists under `/workspace/assets/foo.gif`
+- An e2e test inspects images and the page returns a broken image (no `naturalWidth`, axe `image-alt`/`image-redundant-alt` flapping)
+- You are scaffolding a new homepage scenario and need to be sure the scenario's component can actually render its image
+- Scaffold rule #6 (Asset References) is in play
+
+## Core Capabilities
+
+### 1. Identify which public/ assets the page references
+
+Grep the homepage source for `src="/"` and `url(/...)`:
+
+```bash
+grep -rn 'src="/' homepage/src/
+grep -rn 'url(/' homepage/src/
+```
+
+Each unique `/foo.gif` / `/bar.png` is a candidate that must exist under `homepage/public/`.
+
+### 2. Copy from shared `/workspace/assets/`
+
+```bash
+cp /workspace/assets/logo.gif homepage/public/logo.gif
+cp /workspace/assets/usage.gif homepage/public/usage.gif
+```
+
+This is intentionally a copy, not a symlink — the homepage Next.js build (especially the `output: 'export'` static path) needs concrete files under `public/`.
+
+### 3. Verify the dev server serves them
+
+```bash
+curl -sI http://localhost:3000/usage.gif | head -1 # expect 200, not 404
+```
+
+If the dev server is already running, no restart is needed — Next.js serves `public/` files dynamically.
+
+## Best Practices
+
+- Treat `homepage/public/` as **bootstrap territory**, not a per-scenario folder. Copying an asset here is appropriate even if your scenario only owns `tests/`.
+- Do not modify or rename the original under `/workspace/assets/`. Other scenarios reference it by name.
+- After copying, commit both the copy and any test that depends on it in the same commit so reviewers see the dependency in one diff.
+
+## Reference Implementation
+
+`homepage/public/usage.gif`, `homepage/public/logo.gif` (copies of `/workspace/assets/usage.gif`, `/workspace/assets/logo.gif`).
+
+## Resources
+
+### references/
+
+- `README.md` — This documentation
diff --git a/.claude/skills/playwright-axe-a11y-testing/SKILL.md b/.claude/skills/playwright-axe-a11y-testing/SKILL.md
new file mode 100644
index 000000000..9586e4ae6
--- /dev/null
+++ b/.claude/skills/playwright-axe-a11y-testing/SKILL.md
@@ -0,0 +1,8 @@
+---
+name: playwright-axe-a11y-testing
+description: Run WCAG 2.1 AA audits inside Playwright tests using @axe-core/playwright with a Lighthouse-style pass-rate gate. Use when adding accessibility tests for a Next.js homepage, when a scenario requires zero critical violations plus a 90 or higher score, or when you need an axe audit that produces assertable JSON instead of a Lighthouse HTML report.
+metadata:
+ scope: project
+---
+
+See [README.md](references/README.md) for full documentation.
diff --git a/.claude/skills/playwright-axe-a11y-testing/references/README.md b/.claude/skills/playwright-axe-a11y-testing/references/README.md
new file mode 100644
index 000000000..4190384e4
--- /dev/null
+++ b/.claude/skills/playwright-axe-a11y-testing/references/README.md
@@ -0,0 +1,82 @@
+# Playwright Axe A11y Testing
+
+## Overview
+
+This skill captures the pattern used in `homepage/tests/e2e/accessibility.spec.ts` for running an in-test WCAG 2.1 AA audit using `@axe-core/playwright`. Instead of spinning up the Lighthouse CLI (heavy, HTML report, requires headful Chrome), we run the same WCAG rule set inside a Playwright test, return a structured violations array, and reproduce Lighthouse's rule-pass-rate scoring with assertable JSON.
+
+## When to Use This Skill
+
+Use this skill when:
+
+- A scenario or PRD asks for "Lighthouse accessibility score >= 90 with zero critical violations"
+- You need a deterministic, sub-second accessibility check that runs in CI without extra browser binaries
+- You want to filter axe violations by impact level (`minor` / `moderate` / `serious` / `critical`) to scope a gate
+- A page has color-contrast issues owned by other components/teams that you do not want to block on, but still want logged
+
+## Core Capabilities
+
+### 1. Tagged WCAG audit via AxeBuilder
+
+```ts
+import AxeBuilder from '@axe-core/playwright';
+
+const results = await new AxeBuilder({ page })
+ .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
+ .analyze();
+```
+
+The four tags select WCAG 2.0 Level A + AA and WCAG 2.1 Level A + AA — the exact surface called out by PRD NFR-3.
+
+### 2. Critical-only gate
+
+```ts
+const critical = results.violations.filter((v) => v.impact === 'critical');
+expect(critical).toHaveLength(0);
+```
+
+`critical` issues are the ones that actually block assistive tech (missing accessible names, broken landmark structure). `serious` issues like color-contrast are real WCAG failures but often live in design-token territory owned by other scenarios — log them but do not gate on them here.
+
+### 3. Lighthouse-style rule pass-rate
+
+```ts
+const totalRulesEvaluated =
+ results.violations.length + results.passes.length + results.incomplete.length;
+const violationCount = results.violations.length;
+const passRate =
+ totalRulesEvaluated === 0
+ ? 100
+ : ((totalRulesEvaluated - violationCount) / totalRulesEvaluated) * 100;
+expect(passRate).toBeGreaterThanOrEqual(90);
+```
+
+Counts rule TYPES (not flagged DOM nodes). One failing rule with 12 nodes is one failed audit, mirroring how Lighthouse computes its 0–100 score. A single offending rule cannot tank the score, but multiple distinct accessibility problems will.
+
+### 4. Surfacing failures in the test log
+
+Always print the violations summary before asserting so a failing CI run includes the offending rule IDs:
+
+```ts
+if (critical.length > 0) {
+ console.log('Critical violations:', JSON.stringify(
+ critical.map((v) => ({ id: v.id, impact: v.impact, help: v.help })),
+ null, 2,
+ ));
+}
+```
+
+## Best Practices
+
+- Always `await page.waitForLoadState('networkidle')` in `beforeEach` so axe sees the final DOM.
+- Filter on `impact === 'critical'` only when the test_case wording uses that word — if the wording is "AA conformance", consider including `serious` too.
+- Prefer the rule-pass-rate formula above over a flagged-node penalty: it matches Lighthouse semantics and is more stable across runs.
+- Add `@axe-core/playwright` and `axe-core` as **devDependencies** of the homepage package, not the root.
+
+## Reference Implementation
+
+`homepage/tests/e2e/accessibility.spec.ts` lines 10–46 (Test Case 1).
+
+## Resources
+
+### references/
+
+- `README.md` — This documentation
diff --git a/.claude/skills/playwright-cross-browser-projects/SKILL.md b/.claude/skills/playwright-cross-browser-projects/SKILL.md
new file mode 100644
index 000000000..1f7a97ab8
--- /dev/null
+++ b/.claude/skills/playwright-cross-browser-projects/SKILL.md
@@ -0,0 +1,7 @@
+---
+name: playwright-cross-browser-projects
+description: Configure Playwright projects for Chrome, Firefox, Safari (WebKit), and Edge with selective testMatch scoping so cross-browser tests run on all engines while other suites stay on chromium. Use when adding cross-browser coverage to a Next.js or web project that already uses Playwright.
+scope: project
+---
+
+See [README.md](references/README.md) for full documentation.
diff --git a/.claude/skills/playwright-cross-browser-projects/references/README.md b/.claude/skills/playwright-cross-browser-projects/references/README.md
new file mode 100644
index 000000000..55d20402c
--- /dev/null
+++ b/.claude/skills/playwright-cross-browser-projects/references/README.md
@@ -0,0 +1,72 @@
+# Playwright Cross-Browser Projects
+
+How the MirDB homepage runs cross-browser e2e tests on Chrome, Firefox, Safari (WebKit), and Edge while keeping the rest of the e2e suite scoped to chromium for CI cost.
+
+## When to use
+
+- Adding a new e2e spec that must validate engine-specific behavior (CSS, layout, font fallbacks).
+- Verifying that cross-browser regressions show up in CI without quadrupling the runtime of unrelated specs.
+
+## The pattern
+
+In `homepage/playwright.config.ts`:
+
+```ts
+projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ {
+ name: 'firefox',
+ testMatch: /cross-browser\.spec\.ts/,
+ use: { ...devices['Desktop Firefox'] },
+ },
+ {
+ name: 'webkit',
+ testMatch: /cross-browser\.spec\.ts/,
+ use: { ...devices['Desktop Safari'] },
+ },
+ {
+ name: 'edge',
+ testMatch: /cross-browser\.spec\.ts/,
+ use: { ...devices['Desktop Edge'] },
+ },
+]
+```
+
+Key points:
+
+1. **`chromium` has no `testMatch`** so it runs every spec under `tests/e2e/` (the default). All non-cross-browser tests still execute.
+2. **Firefox / WebKit / Edge each set `testMatch: /cross-browser\.spec\.ts/`** which restricts that project to a single file.
+3. **Edge uses `Desktop Edge`** rather than a separate channel install. Modern Edge is Chromium-based and Playwright's Desktop Edge device exercises that engine through the Edge channel — matches reality, keeps CI hermetic.
+4. **Run all four engines on the cross-browser file**: `npx playwright test tests/e2e/cross-browser.spec.ts` runs the spec on each project (~72 tests for the suite documented here).
+5. **Run a single engine for debugging**: `npx playwright test --project=webkit tests/e2e/cross-browser.spec.ts`.
+
+## Browser install (for fresh hosts)
+
+Firefox and WebKit need system libs. The flow that worked on this Ubuntu 22.04 host:
+
+```bash
+npx playwright install chromium # ok without sudo
+sudo -n npx playwright install-deps chromium # apt deps
+sudo -n npx playwright install --with-deps firefox webkit
+```
+
+The `--with-deps` form of `install` runs `apt-get install` for the required X/GTK libraries before downloading the browser binaries. Without sudo, Firefox/WebKit downloads still succeed but launching fails with the host validation banner.
+
+## Test patterns that worked across all four engines
+
+In the cross-browser spec, every assertion includes `${browserName}` in the message so a CI failure tells you which engine regressed:
+
+```ts
+expect(consoleErrors, `${browserName}: page should load without console errors`).toEqual([]);
+```
+
+For features with engine-specific prefixes (e.g. `backdrop-filter`), accept either the standard property OR a documented graceful fallback (background-color), so the test stays green on engines that lawfully lack the property without weakening the contract on engines that have it.
+
+## Reference: this scenario
+
+- `homepage/playwright.config.ts` lines 20–40
+- `homepage/tests/e2e/cross-browser.spec.ts` (18 tests, all engines)
+- All 4 projects pass: chromium 18/18, firefox 18/18, webkit 18/18, edge 18/18.
diff --git a/.claude/skills/status-tagged-list-section/SKILL.md b/.claude/skills/status-tagged-list-section/SKILL.md
new file mode 100644
index 000000000..755b28d4e
--- /dev/null
+++ b/.claude/skills/status-tagged-list-section/SKILL.md
@@ -0,0 +1,8 @@
+---
+name: status-tagged-list-section
+description: Render a homepage section that splits a single tagged data array (e.g. status='implemented'|'planned') into two visually distinct columns - implemented in green with checkmark icons, planned in amber with clock icons - in the MirDB Next.js homepage. Use whenever a section needs to compare "shipped" vs "upcoming" items sourced from src/lib/constants.ts.
+metadata:
+ scope: project
+---
+
+See [README.md](references/README.md) for full documentation.
diff --git a/.claude/skills/status-tagged-list-section/references/README.md b/.claude/skills/status-tagged-list-section/references/README.md
new file mode 100644
index 000000000..9e4f6b1c5
--- /dev/null
+++ b/.claude/skills/status-tagged-list-section/references/README.md
@@ -0,0 +1,101 @@
+# Status Tagged List Section
+
+## Overview
+
+This skill captures the pattern used by the MirDB homepage `RoadmapSection` (and similar sections) to render a single status-tagged data array as two side-by-side columns with distinct visual styling. The data lives in `src/lib/constants.ts` as one array, the type lives in `src/types/index.ts`, and the section component derives the two groups via `Array.filter`.
+
+## When to Use This Skill
+
+Use this skill when:
+
+- A homepage section needs to compare "completed/shipped" items vs "planned/in-progress" items.
+- Items share the same shape but differ by a single status tag.
+- You want both color-based and icon-based differentiation (for accessibility / colorblind users).
+- The data should be addressable by other sections (status indicator, sitemap, future analytics) without duplication.
+
+## Core Capabilities
+
+### 1. Single-array, status-tagged data shape
+
+Define the type in `src/types/index.ts`:
+
+```ts
+export interface RoadmapItem {
+ title: string;
+ status: 'implemented' | 'planned';
+}
+```
+
+Place the data in `src/lib/constants.ts` as one tagged array:
+
+```ts
+export const ROADMAP_ITEMS = [
+ { title: 'Tokio-based async networking with memcached protocol', status: 'implemented' as const },
+ { title: 'Memtable with skip list data structure', status: 'implemented' as const },
+ { title: 'Minor compaction (memtable to SSTable)', status: 'implemented' as const },
+ { title: 'Major compaction (SSTable level compaction)', status: 'implemented' as const },
+ { title: 'Raft consensus for distributed operation', status: 'planned' as const },
+];
+```
+
+### 2. Two-column responsive layout with distinct styling
+
+In the component (`src/components/RoadmapSection.tsx`):
+
+```tsx
+const implemented = ROADMAP_ITEMS.filter((item) => item.status === 'implemented');
+const planned = ROADMAP_ITEMS.filter((item) => item.status === 'planned');
+```
+
+Layout grid: `grid md:grid-cols-2 gap-12` (stacks on mobile, side-by-side at md+).
+
+Color tokens used:
+
+| Status | Background | Icon badge | Border |
+|-------------|-------------------------------------------|-------------------|------------------------------------------|
+| implemented | bg-green-50 dark:bg-green-900/20 | bg-green-500 | border-green-200 dark:border-green-800 |
+| planned | bg-amber-50 dark:bg-amber-900/20 | bg-amber-500 | border-amber-200 dark:border-amber-800 |
+
+Inline SVG icons (Heroicons paths) — no runtime icon dependency. `aria-hidden="true"` on the decorative icon span.
+
+### 3. Stable test hooks
+
+Add `data-testid` attributes that the unit tests rely on:
+
+- `data-testid="roadmap-section"` on the `+ LSM-tree based storage engine with efficient compaction and crash recovery. +
++ In-memory skip-list data structure for fast writes. All mutations are first written to the memtable and WAL for durability. +
++ Immutable sorted string tables stored on disk across multiple levels. Each level has a target size threshold. +
++ Background process merges overlapping SSTables to reclaim space and maintain read performance. +
++ Default configuration options for MirDB server. +
+| Setting | +Default | +Description | +
|---|---|---|
| {opt.name} | +{opt.default} | +{opt.description} | +
+ Watch how MirDB handles basic CRUD operations through the memcached + text protocol. +
+
+ + Terminal session showing MirDB CRUD operations +
++ Everything you need for high-performance persistent key-value storage. +
++ {feature.description} +
++ A Persistent Key-Value Store with Memcached Protocol Compatibility +
++ Built in Rust with LSM-tree architecture for high-performance, + durable data storage. Drop-in replacement for memcached with + automatic persistence to disk. +
++ MirDB supports the standard memcached text protocol. Use existing clients without modification. +
+
+ {cmd.syntax}
+
+ {cmd.description}
+
+ {cmd.example}
+
+ + Get MirDB running locally in minutes. Follow these simple steps to + clone, build, and start the server. +
++ {step.description} +
+
+ Default settings:{' '}
+ The server listens on{' '}
+
+ 0.0.0.0:12333
+ {' '}
+ and uses{' '}
+
+ /tmp/mirdb
+ {' '}
+ as the working directory. Customize these in{' '}
+
+ etc/mirdb.toml
+
+ .
+
+ Build health and project statistics. +
+ +
+ {highlightCode(code)}
+
+