diff --git a/website/docs/case-studies/docusaurus.md b/website/docs/case-studies/docusaurus.md
new file mode 100644
index 00000000..1006eea7
--- /dev/null
+++ b/website/docs/case-studies/docusaurus.md
@@ -0,0 +1,203 @@
+# Docusaurus Case Study
+
+> Verified baseline scan — CVE Lite CLI v1.25.0 · 2026-06-26
+
+
+
+
+
+## Summary
+
+- **Project:** Docusaurus — open-source static-site generator by Meta, widely used for technical documentation
+- **Repository:** [github.com/facebook/docusaurus](https://github.com/facebook/docusaurus)
+- **Revision:** `5d162a4654b105aa9cc66dc38ddbc367d81be230`
+- **Lockfile:** `pnpm-lock.yaml` (2,590 resolved packages)
+- **Package manager:** pnpm (monorepo)
+- **Baseline findings:** 14 unique vulnerable packages (0 critical · 6 high · 7 medium · 1 low)
+- **Direct vs transitive:** 1 direct / 13 transitive
+- **CVEs matched:** 20
+- **Fix commands generated:** 4 command groups covering 7 of 14 findings
+- **Remaining after fix plan:** 6 findings (structural blockers — no fix available or advisory hint only)
+
+---
+
+## What this case study demonstrates
+
+Docusaurus is a professionally maintained pnpm monorepo used by hundreds of thousands of documentation sites worldwide. It has active maintainers and automated dependency tooling — yet CVE Lite CLI surfaced 14 vulnerable packages across 2,590 resolved dependencies, 13 of them transitive and invisible in the root `package.json`.
+
+This case study highlights two things that matter for real-world monorepos:
+
+**1. The direct/transitive split tells you where to start.** Only 1 of 14 findings (`webpack-dev-server`) is a direct dependency the project controls outright. The other 13 require parent-chain decisions. Without that separation, a developer looking at a flat list of findings cannot tell which ones are actionable today.
+
+**2. The `⊘` advisory-hint marker is honest signal, not a gap.** Several packages (`vite`, `tmp`, `js-yaml`, `uuid`, `@tootallnate/once`) show a fixed-version hint from OSV but no validated copy-and-run command. CVE Lite flags these explicitly rather than generating a command it cannot confirm. That distinction matters: a false fix command that silently introduces a breaking change is worse than no command at all.
+
+---
+
+## Comparison Note: CVE Lite CLI vs pnpm audit
+
+Both tools were run against the same `pnpm-lock.yaml` on the same machine.
+
+| Metric | pnpm audit | CVE Lite CLI v1.25.0 |
+|---|---:|---:|
+| Total reported findings | 25 | 14 |
+| Critical | 0 | 0 |
+| High | 8 | 6 |
+| Medium | 10 | 7 |
+| Low | 7 | 1 |
+| Direct vs transitive breakdown | ✗ | ✔ (1 / 13) |
+| Validated fix targets | ✗ | ✔ |
+| Breaking change awareness | ✗ | ✔ |
+| Advisory-hint-only marker (⊘) | ✗ | ✔ |
+| Specific copy-and-run commands | ✗ | ✔ (4 groups) |
+
+**Why CVE Lite reports fewer findings — and why that is not a coverage gap:**
+
+`pnpm audit` counts vulnerability paths, not packages. A single vulnerable package reached via multiple dependency paths contributes multiple entries. CVE Lite counts each unique vulnerable package once regardless of how many paths reach it. That is why the totals differ: 25 vs 14.
+
+This deduplication is intentional. A developer looking at 25 findings cannot tell how many distinct packages need attention. CVE Lite's 14 is the true exposure surface: 14 packages, each needing exactly one decision.
+
+---
+
+## Before vs After
+
+| Stage | Findings | Critical | High | Medium | Low | Direct | Transitive | Command groups |
+|---|---:|---:|---:|---:|---:|---:|---:|---:|
+| Baseline | 14 | 0 | 6 | 7 | 1 | 1 | 13 | 0 |
+| After all fix commands | 7 | 0 | 2 | 4 | 1 | 0 | 7 | 4 |
+
+---
+
+## Fix Journey
+
+CVE Lite generated 4 command groups covering 7 of 14 findings in a single pass.
+
+The only direct dependency in the findings is `webpack-dev-server` — one command clears it. The remaining fixable findings are transitive: `ws` is reached through `@rsdoctor/rspack-plugin`, while `form-data`, `undici`, `dompurify`, `http-proxy-middleware`, and `launch-editor` can all be refreshed within their current parent ranges without a version bump to the declaring package.
+
+The 6 remaining findings after the fix pass are all structural blockers: `tmp`, `vite`, `js-yaml`, and `@tootallnate/once` have advisory hints only with no validated fix target; `uuid` and `js-yaml` require major version jumps with breaking changes; these require tracking upstream releases rather than a local install command today.
+
+### High severity — direct parent upgrade
+
+```bash
+pnpm add @rsdoctor/rspack-plugin@1.5.13
+```
+
+Resolves `ws@8.20.1` (high) through the path:
+`@rsdoctor/rspack-plugin → @rsdoctor/sdk → socket.io → engine.io → ws`
+
+### High severity — within-range parent updates
+
+```bash
+pnpm update --no-save form-data && pnpm update --recursive --no-save undici
+```
+
+Both `form-data@4.0.5` and `undici@6.26.0 / 7.26.0` can be refreshed without a parent upgrade — the current declared ranges already permit safe versions.
+
+### Medium severity — direct fix
+
+```bash
+pnpm add --filter ./packages/docusaurus webpack-dev-server@5.2.5
+```
+
+`webpack-dev-server` is the only direct dependency in the findings. Upgrading from `5.2.4` to `5.2.5` (published 2026-06-12) clears `GHSA-mx8g-39q3-5c79`. CVE Lite validated the target version as non-vulnerable before generating this command.
+
+### Medium severity — within-range parent updates
+
+```bash
+pnpm -C packages/docusaurus-theme-mermaid update --no-save dompurify && pnpm -C packages/docusaurus update --no-save http-proxy-middleware && pnpm -C packages/docusaurus update --no-save launch-editor
+```
+
+Three medium-severity transitive packages (`dompurify`, `http-proxy-middleware`, `launch-editor`) can be refreshed within their current parent ranges.
+
+---
+
+## Why this matters
+
+Docusaurus is not a neglected project. It is actively maintained, widely deployed, and has automated tooling. Yet 13 of 14 vulnerable packages are invisible to anyone reading the root `package.json` — they only appear in the fully resolved lockfile.
+
+This is the normal state of a healthy pnpm monorepo: the surface that matters for security is not the manifest a developer edits, but the 2,590-package graph the lockfile resolves. CVE Lite reads that graph directly and separates what a developer can act on today from what requires upstream decisions.
+
+For a project of this scale, the operational value is not just finding vulnerabilities — it is knowing which of the 14 findings produce a copy-and-run command, which require a parent-chain decision, and which are blocked on upstream releases. That triage happens in seconds rather than hours.
+
+---
+
+## Scan command
+
+```bash
+cve-lite . --verbose --all
+```
+
+| Field | Value |
+|---|---|
+| Scan date | 2026-06-26 |
+| CLI version | v1.25.0 |
+| Revision | `5d162a4654b105aa9cc66dc38ddbc367d81be230` |
+| Lockfile | pnpm-lock.yaml |
+| Resolved packages | 2,590 |
+| Findings | 14 |
+| CVEs matched | 20 |
+| Fix commands generated | 4 groups (7 of 14 findings) |
+
+Reproduce from a local clone at the pinned revision:
+
+```bash
+git clone https://github.com/facebook/docusaurus
+cd docusaurus
+git checkout 5d162a4654b105aa9cc66dc38ddbc367d81be230
+cve-lite . --verbose --all
+```
+
+---
+
+## Remaining risk after fix plan
+
+6 findings remain after applying all 4 command groups:
+
+| Package | Version | Severity | Type | Note |
+|---|---|---|---|---|
+| tmp | 0.2.6 | high | transitive · dev | ⊘ advisory hint only — no validated fix command |
+| vite | 8.0.14 | high | transitive · dev | ⊘ advisory hint only — no validated fix command |
+| js-yaml | 3.14.2 | medium | transitive · dev | ⊘ major version jump (3 → 4), breaking change |
+| js-yaml | 4.1.1 | medium | transitive · dev | ⊘ advisory hint only — no validated fix command |
+| uuid | 8.3.2 | medium | transitive | ⊘ major version jump (8 → 11), breaking change |
+| @tootallnate/once | 1.1.2 | low | transitive · dev | ⊘ advisory hint only — no validated fix command |
+
+All 6 remaining findings are either dev-only transitive packages or advisory-hint-only cases where no automated fix could be validated.
+
+---
+
+## Baseline findings
+
+Full vulnerable package list at scan time:
+
+| Package | Version | Severity | Relationship | Fixed | Advisory IDs |
+|---|---|---|---|---|---|
+| form-data | 4.0.5 | high | transitive | 4.0.6 | GHSA-hmw2-7cc7-3qxx |
+| tmp | 0.2.6 | high | transitive · dev | 0.2.7 ⊘ | GHSA-7c78-jf6q-g5cm |
+| undici | 6.26.0 | high | transitive · dev | 6.27.0 | GHSA-35p6-xmwp-9g52, GHSA-g8m3-5g58-fq7… |
+| undici | 7.26.0 | high | transitive | 7.28.0 | GHSA-35p6-xmwp-9g52, GHSA-g8m3-5g58-fq7… |
+| vite | 8.0.14 | high | transitive · dev | 8.0.16 ⊘ | GHSA-fx2h-pf6j-xcff, GHSA-v6wh-96g9-6wx3 |
+| ws | 8.20.1 | high | transitive | 8.21.0 | GHSA-96hv-2xvq-fx4p |
+| webpack-dev-server | 5.2.4 | medium | direct | 5.2.5 | GHSA-mx8g-39q3-5c79 |
+| dompurify | 3.4.7 | medium | transitive | 3.4.11 | GHSA-cmwh-pvxp-8882, GHSA-gvmj-g25r-r7w… |
+| http-proxy-middleware | 2.0.9 | medium | transitive | 2.0.10 | GHSA-64mm-vxmg-q3vj |
+| js-yaml | 3.14.2 | medium | transitive · dev | 4.2.0 ⊘ | GHSA-h67p-54hq-rp68 |
+| js-yaml | 4.1.1 | medium | transitive · dev | 4.2.0 ⊘ | GHSA-h67p-54hq-rp68 |
+| launch-editor | 2.13.2 | medium | transitive | 2.14.1 | GHSA-v6wh-96g9-6wx3 |
+| uuid | 8.3.2 | medium | transitive | 11.1.1 ⊘ | GHSA-w5hq-g745-h8pq |
+| @tootallnate/once | 1.1.2 | low | transitive · dev | 2.0.1 ⊘ | GHSA-vpq2-c234-7xj6 |
+
+⊘ Advisory hint only — no automated fix command could be generated.
+
+---
+
+## Want your project reviewed?
+
+If you maintain an interesting JavaScript or TypeScript project and want CVE Lite CLI considered for a public case study, open an issue in the [CVE Lite CLI repository](https://github.com/OWASP/cve-lite-cli/issues).
+
+Please include:
+
+- the repository link
+- why the project would make a useful case study
+- whether the dependency graph is publicly reproducible
+
+Not every project will be selected. Preference will go to projects that are publicly useful, technically interesting, and strong examples of realistic dependency remediation workflows.
\ No newline at end of file
diff --git a/website/static/img/docusaurus-logo.png b/website/static/img/docusaurus-logo.png
new file mode 100644
index 00000000..f458149e
Binary files /dev/null and b/website/static/img/docusaurus-logo.png differ