diff --git a/docs/superpowers/specs/2026-04-09-tag-search-design.md b/docs/superpowers/specs/2026-04-09-tag-search-design.md
index 5d452763..04af3775 100644
--- a/docs/superpowers/specs/2026-04-09-tag-search-design.md
+++ b/docs/superpowers/specs/2026-04-09-tag-search-design.md
@@ -19,14 +19,14 @@ Two patch scripts that wire up autocomplete end-to-end with no new endpoints and
**What it does:**
-Inserts a `case "categories":` block before the existing `default:` case in `queryController`. When `q=category` is requested, instead of falling through to `config.categories` (which is empty), this case:
+Inserts a `case "categories":` block before the existing `default:` case in `queryController`. When `q=category` is requested, instead of falling through to `config.categories` (which is an empty array — truthy, so the `default:` branch does not throw, it just returns `{categories:[]}`), this case:
-1. Calls `postsCollection.distinct("properties.category")` to get every unique tag used across all published posts.
+1. Calls `postsCollection.distinct("properties.category")` to get every unique tag used across all published posts. MongoDB `distinct()` on an array field correctly unwraps array values, so `["photography","travel"]` per-post becomes individual distinct entries.
2. Filters out falsy values (`Boolean` filter) and sorts alphabetically.
-3. Passes the result through the existing `queryConfig(cats, { filter, limit, offset })` so the `filter=` query param works for substring matching.
+3. Passes the result through `queryConfig(cats, { filter: filter?.toLowerCase(), limit, offset })` — note: `filter` is lowercased before passing to match `queryConfig`'s internal lowercase comparison, making search case-insensitive end-to-end.
4. Returns `{ categories: [...] }`.
-If `postsCollection` is not available, returns an empty array gracefully.
+If `postsCollection` is not available, returns `{ categories: [] }` gracefully.
**Example request/response:**
```
@@ -34,30 +34,45 @@ GET /micropub?q=category&filter=pho
→ { "categories": ["photography"] }
```
+**OLD_SNIPPET anchor:** The patch uses the closing `break;` of the preceding `source:` case plus the `default: {` line as context for the OLD_SNIPPET, since the `default:` block itself does not contain error-throwing logic for the `categories` query (empty array is truthy).
+
---
## Patch 2 — Frontend: `patch-tag-input-autocomplete.mjs`
**Target:** `node_modules/@indiekit/frontend/components/tag-input/index.js`
+**Micropub endpoint URL discovery:**
+
+The patch reads the Micropub endpoint URL using the standard IndieWeb discovery selector:
+
+```js
+const micropubHref = document.querySelector('link[rel="micropub"]')?.href ?? "/micropub";
+```
+
+This is resolved once per component instantiation. On admin pages Indiekit does not inject the `` element, so the fallback `/micropub` is always used in practice — which is correct for this deployment.
+
**What it does:**
After the `$tagInputInput` reference is obtained inside `TagInputFieldComponent.connectedCallback()`, appends the following behaviour:
-1. Creates a `