diff --git a/docs/superpowers/specs/2026-06-11-comment-localstorage-design.md b/docs/superpowers/specs/2026-06-11-comment-localstorage-design.md
new file mode 100644
index 0000000..b73f4ff
--- /dev/null
+++ b/docs/superpowers/specs/2026-06-11-comment-localstorage-design.md
@@ -0,0 +1,205 @@
+# Comment localStorage Persistence + Pending Visibility
+
+## Problem
+
+After submitting a comment, users see only a green "评论已提交,等待审核" alert. The comment is invisible to everyone (including the author) until admin approval. Additionally, returning users must re-enter their name/email/website every time.
+
+## Solution
+
+Two localStorage-backed features:
+
+1. **Form auto-fill**: Save author info (name/email/url) to localStorage, pre-fill on subsequent visits.
+2. **Pending comment visibility**: Store pending comments locally by server-returned ID. Display them with a "审核中" badge, visible only to the submitting browser.
+
+## localStorage Keys
+
+### `yggdrasil-comment-author`
+
+Written on every successful comment submission. Read on `CommentForm` mount.
+
+```json
+{ "name": "张三", "email": "zhang@example.com", "url": "https://example.com" }
+```
+
+### `yggdrasil-pending-comments`
+
+Written on successful submission with server-returned ID. Read on `CommentSection` mount. Keyed by `post_id` (string).
+
+```json
+{
+ "42": [
+ {
+ "id": 123,
+ "parent_id": null,
+ "depth": 0,
+ "author_name": "张三",
+ "author_url": null,
+ "avatar_url": "https://cravatar.cn/avatar/xxx?d=mp&s=80",
+ "content_md": "评论内容",
+ "created_at": "2026-06-11T10:00:00Z",
+ "stored_at": "2026-06-11T10:00:00Z"
+ }
+ ]
+}
+```
+
+Design decisions:
+- **No `content_html`** — XSS safety. Render `content_md` client-side with HTML escaping + newline→`
`.
+- **No `author_email`** — Already in `yggdrasil-comment-author`. Avoid PII duplication.
+- **`avatar_url`** computed at save time from the stored author email.
+- **`stored_at`** for 7-day TTL. Pruned on every read.
+- Empty post_id arrays removed on cleanup.
+
+## Server-Side Changes
+
+### 1. `CommentResponse` — add `comment_id`
+
+```rust
+pub struct CommentResponse {
+ pub success: bool,
+ pub message: String,
+ pub error_code: Option,
+ pub comment_id: Option, // NEW: set only on success
+}
+```
+
+Backward-compatible: `Option` serde defaults to `None` for old callers.
+
+### 2. `create_comment` — extract and return ID
+
+The existing INSERT already uses `RETURNING id` but discards the row. Change to:
+
+```rust
+let row = client
+ .query_one("INSERT INTO comments ... RETURNING id", &[...])
+ .await
+ .map_err(AppError::query)?;
+let comment_id: i64 = row.get(0);
+```
+
+All existing error paths add `comment_id: None`. Only the final success path sets `comment_id: Some(comment_id)`.
+
+### 3. New server function: `CheckPendingStatus`
+
+```rust
+#[server(CheckPendingStatus, "/api")]
+pub async fn check_pending_status(ids: Vec) -> Result, ServerFnError>
+```
+
+- Early return empty vec if `ids.is_empty()`.
+- Query: `SELECT id, status FROM comments WHERE id = ANY($1)`
+- IDs not found in result → status `"gone"` (soft-deleted or hard-deleted).
+- Client uses this to prune localStorage entries that are no longer pending.
+
+## Client-Side Changes
+
+### New module: `src/hooks/comment_storage.rs`
+
+Provides `use_comment_storage()` hook with:
+
+| Function | Purpose |
+|----------|---------|
+| `save_author(name, email, url)` | Write `yggdrasil-comment-author` |
+| `load_author() -> Option` | Read author info |
+| `save_pending_comment(post_id, comment)` | Append to `yggdrasil-pending-comments` |
+| `load_pending_comments(post_id) -> Vec` | Read + prune expired (7-day TTL) |
+| `remove_pending_ids(post_id, ids)` | Remove specific IDs, clean empty post entries |
+| `prune_expired()` | Remove all entries across all posts older than 7 days |
+
+All `web_sys` calls behind `#[cfg(target_arch = "wasm32")]`. Non-WASM returns defaults (empty/None).
+
+Serialization via `serde_json` (already a project dependency).
+
+### `CommentContext` — extend with pending state
+
+```rust
+#[derive(Clone, Copy)]
+pub struct CommentContext {
+ pub active_reply: Signal