diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md
index ee81750..cf8d2ef 100644
--- a/docs/getting-started/overview.md
+++ b/docs/getting-started/overview.md
@@ -40,8 +40,9 @@ behind that connection — the thing the gateway actually talks to.
headers and bodies, the resolved identity, the response status and
size, and the duration.
- **Portal**: React 19 SPA embedded in the binary; Dashboard,
- Endpoints with Try-It, Audit, API Keys, Config, Discovery (Redoc/Swagger
- UI over `/openapi.json`).
+ Endpoints with Try-It, Audit, API Keys, Config, Discovery (native
+ OpenAPI 3.1 reference rendered from `/openapi.json`, with `/docs`
+ Redoc available as a sibling).
- **OpenAPI document** at `/openapi.{json,yaml}`, generated in-tree
from the registered endpoint metadata so it can't drift from the
served routes.
diff --git a/docs/images/portal/about-dark.png b/docs/images/portal/about-dark.png
index dd22518..3c5039c 100644
Binary files a/docs/images/portal/about-dark.png and b/docs/images/portal/about-dark.png differ
diff --git a/docs/images/portal/about-light.png b/docs/images/portal/about-light.png
index ddc3c16..4f83fc5 100644
Binary files a/docs/images/portal/about-light.png and b/docs/images/portal/about-light.png differ
diff --git a/docs/images/portal/audit-dark.png b/docs/images/portal/audit-dark.png
index 2909e59..93d3b99 100644
Binary files a/docs/images/portal/audit-dark.png and b/docs/images/portal/audit-dark.png differ
diff --git a/docs/images/portal/audit-detail-dark.png b/docs/images/portal/audit-detail-dark.png
index 8ad5368..38c5a3c 100644
Binary files a/docs/images/portal/audit-detail-dark.png and b/docs/images/portal/audit-detail-dark.png differ
diff --git a/docs/images/portal/audit-detail-light.png b/docs/images/portal/audit-detail-light.png
index 1fe4892..1cb62d6 100644
Binary files a/docs/images/portal/audit-detail-light.png and b/docs/images/portal/audit-detail-light.png differ
diff --git a/docs/images/portal/audit-light.png b/docs/images/portal/audit-light.png
index 6974f1a..249321b 100644
Binary files a/docs/images/portal/audit-light.png and b/docs/images/portal/audit-light.png differ
diff --git a/docs/images/portal/config-dark.png b/docs/images/portal/config-dark.png
index 7c9a226..e39c09f 100644
Binary files a/docs/images/portal/config-dark.png and b/docs/images/portal/config-dark.png differ
diff --git a/docs/images/portal/config-light.png b/docs/images/portal/config-light.png
index 565c8de..216d61a 100644
Binary files a/docs/images/portal/config-light.png and b/docs/images/portal/config-light.png differ
diff --git a/docs/images/portal/dashboard-dark.png b/docs/images/portal/dashboard-dark.png
index 8f049f6..26e3fb7 100644
Binary files a/docs/images/portal/dashboard-dark.png and b/docs/images/portal/dashboard-dark.png differ
diff --git a/docs/images/portal/dashboard-light.png b/docs/images/portal/dashboard-light.png
index bfa5f56..5e01ebf 100644
Binary files a/docs/images/portal/dashboard-light.png and b/docs/images/portal/dashboard-light.png differ
diff --git a/docs/images/portal/discovery-dark.png b/docs/images/portal/discovery-dark.png
new file mode 100644
index 0000000..58a8fa9
Binary files /dev/null and b/docs/images/portal/discovery-dark.png differ
diff --git a/docs/images/portal/discovery-light.png b/docs/images/portal/discovery-light.png
new file mode 100644
index 0000000..02503f2
Binary files /dev/null and b/docs/images/portal/discovery-light.png differ
diff --git a/docs/images/portal/endpoints-dark.png b/docs/images/portal/endpoints-dark.png
index 4a05795..e416f14 100644
Binary files a/docs/images/portal/endpoints-dark.png and b/docs/images/portal/endpoints-dark.png differ
diff --git a/docs/images/portal/endpoints-detail-dark.png b/docs/images/portal/endpoints-detail-dark.png
index dc4e570..1560c7c 100644
Binary files a/docs/images/portal/endpoints-detail-dark.png and b/docs/images/portal/endpoints-detail-dark.png differ
diff --git a/docs/images/portal/endpoints-detail-light.png b/docs/images/portal/endpoints-detail-light.png
index ca71010..bc4b944 100644
Binary files a/docs/images/portal/endpoints-detail-light.png and b/docs/images/portal/endpoints-detail-light.png differ
diff --git a/docs/images/portal/endpoints-light.png b/docs/images/portal/endpoints-light.png
index 6c70e10..569dd54 100644
Binary files a/docs/images/portal/endpoints-light.png and b/docs/images/portal/endpoints-light.png differ
diff --git a/docs/images/portal/keys-dark.png b/docs/images/portal/keys-dark.png
index 8f27093..664e64b 100644
Binary files a/docs/images/portal/keys-dark.png and b/docs/images/portal/keys-dark.png differ
diff --git a/docs/images/portal/keys-light.png b/docs/images/portal/keys-light.png
index 5715af4..5c0c612 100644
Binary files a/docs/images/portal/keys-light.png and b/docs/images/portal/keys-light.png differ
diff --git a/docs/operations/portal.md b/docs/operations/portal.md
index e25bbfc..0addf96 100644
--- a/docs/operations/portal.md
+++ b/docs/operations/portal.md
@@ -22,7 +22,7 @@ operator session cookie established via OIDC PKCE.
| **Audit** | Filterable, paginated event view; click a row for the full request/response drawer with redaction overlays. |
| **API Keys** | Create / revoke Postgres-backed bcrypt keys. Plaintext shown once. |
| **Config** | Read-only YAML of the running server, with secrets masked. |
-| **Discovery** | Redoc/Swagger UI iframe over `/openapi.json`; click-to-copy connection-registration YAML for the Plexara admin API. |
+| **Discovery** | Native OpenAPI 3.1 reference rendered from `/openapi.json` (groups, operations, parameters, schemas, response samples; full dark/light parity with the portal). Links out to `/docs` (Redoc) for the canonical view. |
| **About** | Build info + "test against Plexara" cheat sheet. |
## Authentication
@@ -53,6 +53,23 @@ and a curl hint for invoking the route directly.


+## Discovery
+
+A native OpenAPI 3.1 reference rendered directly from
+[/openapi.json](../reference/http-api.md#discovery), with full
+light / dark parity against the portal's design tokens. Operations are
+grouped by tag in a left rail; each card expands to show parameters,
+request body schema, responses, and a minimal example synthesized from
+the schema. The page-level filter searches path, summary, and
+operationId across every operation.
+
+The canonical Redoc view at `/docs` is still served by the binary and
+is linked from the page header (top right) for operators who prefer
+it.
+
+
+
+
## Audit log
The Audit page is the filterable, paginated event view. Filters cover
diff --git a/docs/overrides/home.html b/docs/overrides/home.html
index 87dcbef..9ed23a7 100644
--- a/docs/overrides/home.html
+++ b/docs/overrides/home.html
@@ -84,7 +84,8 @@
Inspect every request from the browser
["audit", "Audit log", "Every request, filterable by method, path, and success / error. Auto-refreshing on a 5-second interval; click a row to inspect the full request and response."],
["audit-detail", "Inspection panel", "Side-pane detail card with timestamp, duration, request id, identity, remote address, byte counts, and the full headers / query / body trees for both sides of the call."],
["endpoints", "Endpoints", "Catalog of every registered route, grouped by behavior — identity, deterministic data, echo, controlled failure modes."],
- ["endpoints-detail", "Endpoint detail", "Method, path, group, auth requirement, and an inline curl hint per route. Try-It panel arrives with the OpenAPI generator in."],
+ ["endpoints-detail", "Endpoint detail", "Method, path, group, auth requirement, and an inline curl hint per route, plus a Try-It panel that dispatches a real call through the portal API."],
+ ["discovery", "Discovery", "Native OpenAPI 3.1 reference rendered from /openapi.json — groups, operations, parameters, schemas, examples — with full light / dark parity against the portal's design tokens."],
["keys", "API keys", "Create or revoke Postgres-backed bcrypt keys. Plaintext is shown once, then never again."],
["config", "Config", "Read-only view of the running server config, with secrets masked. Useful for sanity-checking what's actually loaded."],
["about", "About", "Build info plus the same well-known metadata an MCP / API client sees: api endpoint, OIDC issuer, audience."]
diff --git a/docs/reference/http-api.md b/docs/reference/http-api.md
index 18be160..c6c97e4 100644
--- a/docs/reference/http-api.md
+++ b/docs/reference/http-api.md
@@ -39,7 +39,10 @@ GET /docs
```
Renders a Redoc / Swagger UI view of `/openapi.json` for human
-inspection. The portal's Discovery page iframes this.
+inspection. The portal's Discovery page renders its own native
+reference against the same `/openapi.json` document (for full
+light/dark parity with the portal); `/docs` is still served as the
+canonical Redoc view and is linked from the portal header.
## Well-known metadata
diff --git a/scripts/screenshots/screenshots.mjs b/scripts/screenshots/screenshots.mjs
index f7f26fa..bfc2fbc 100644
--- a/scripts/screenshots/screenshots.mjs
+++ b/scripts/screenshots/screenshots.mjs
@@ -68,6 +68,21 @@ const PAGES = [
await page.waitForTimeout(400);
} },
+ // discovery: native OpenAPI 3.1 reference rendered from /openapi.json.
+ // Capture an expanded operation so the screenshot communicates what the
+ // page actually does (parameter tables, response schema, examples) and
+ // not just the closed-card list.
+ { slug: "discovery",
+ path: "/portal/discovery",
+ requiresAuth: true,
+ prep: async (page) => {
+ await page.waitForSelector('section button code', { timeout: 5000 });
+ // Click the first operation card so its parameter/response/schema
+ // detail expands.
+ await page.locator('section button').first().click();
+ await page.waitForTimeout(400);
+ } },
+
// audit-detail: click the first row so the right-pane EventDetail card
// (timestamp, duration, request_id, auth, user, remote, bytes, plus
// request/response headers / query / body trees) is rendered.
diff --git a/ui/src/App.tsx b/ui/src/App.tsx
index 42cadc4..376e38d 100644
--- a/ui/src/App.tsx
+++ b/ui/src/App.tsx
@@ -43,8 +43,15 @@ export default function App() {
}
return (
-