diff --git a/AGENTS.md b/AGENTS.md
index 615f10f..78b2311 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -633,6 +633,23 @@ grows (clipped controls, cramped rows, same-row controls that stop matching heig
- Every interactive control sets `cursor-pointer` (Button, Switch, segmented
item, …). Disabled flips to `cursor-not-allowed`.
+- **It must be set explicitly — there is no safety net.** Tailwind v4's
+ preflight dropped the v3-era `button, [role=button] { cursor: pointer }`
+ rule, so every clickable element falls back to the UA default (the plain
+ arrow) unless the component sets the class itself. When adding a new
+ interactive component, `cursor-pointer` is part of the base class, not an
+ afterthought — a shared trigger class (e.g. `lib/trigger.ts`
+ `selectTriggerClass`) carries it once for all consumers.
+- **Deliberate non-pointer exceptions** (do not "fix" these):
+ - **Menu rows and menu labels** (`lib/menu.ts`) use `cursor-default` — the
+ macOS menu convention: an open menu is a transient command surface the
+ pointer glides over, not a page of buttons.
+ - **Select scroll up/down buttons** — part of the menu surface, same
+ convention.
+ - **Text-field addons** (`InputGroup` inline text/icons) use `cursor-text` —
+ they belong to the field's text zone.
+ - **Resize rails** (`SidebarRail`) use the resize cursor; **the ScrollArea
+ thumb** keeps its default (drag affordance is its own vocabulary).
## Dirty patterns — anti-examples (do NOT copy)
@@ -842,3 +859,13 @@ When you lock a new cross-cutting decision (a color role, a duration, an icon
rule, a shape law): (1) add/identify the token in `style.css`, (2) document it
here, (3) add a guard check in `scripts/check-ui-contract.mjs` if it is
mechanically detectable. A decision that is not written here will be re-invented.
+
+## Nested menu alignment
+
+DropdownMenuSubContent 与 ContextMenuSubContent 默认将子菜单首个条目的垂直中心对齐父触发条目的中心,而非对齐两个矩形的顶边。共享 useSubmenuAlignment 测量条目、边框与内框,适应字体缩放和异步内容;调用层不添加补偿偏移。显式 alignOffset 仍可覆盖默认规则。碰撞处理继续由 Reka 负责:空间不足时允许翻转或移动以保持可操作,不以绝对对齐强迫内容溢出。子菜单复用锚定菜单的进入/退出动画与变换原点。
+
+## Menu leading icons
+
+菜单首图标的外框尺寸与间距由菜单组件统一管理,调用方直接传入图标,不添加 `mr-*`、`ml-*`、尺寸或偏移修正。共享样式兼容旧调用的 margin/size 类;SVG 内部几何仍由图标层负责。DropdownMenu 和 ContextMenu 的菜单项遵循同一规则;根 ContextMenu 在光标锚点使用共享淡入缩放与退出动画,不使用方向滑动。
+
+普通操作菜单与 Select 共用 `--menu-min-width`(10rem)作为舒展的基础宽度,窄屏允许收缩。Select 仍不得窄于触发器;更长内容可扩展。菜单比例通过宽度和内容组织调整,不通过压低共享行高补偿。业务确需不同宽度时使用已有 class 覆盖,不为短文案逐页设置最小宽度。
diff --git a/package.json b/package.json
index a307742..74bc7aa 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"reka-ui": "^2.10.1",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.3.3",
+ "tw-animate-css": "^1.4.0",
"vee-validate": "^4.15.1",
"vue-input-otp": "^0.3.2",
"zod": "3.25.76"
@@ -50,7 +51,6 @@
"misans-vf": "1.0.0",
"npm-run-all2": "^8.0.4",
"tsx": "^4.21.0",
- "tw-animate-css": "^1.4.0",
"typescript": "~6.0.3",
"unplugin-dts": "1.0.0-beta.6",
"vite": "^8.1.5",
diff --git a/showcase/AGENTS.md b/showcase/AGENTS.md
index b4fd68d..297dc55 100644
--- a/showcase/AGENTS.md
+++ b/showcase/AGENTS.md
@@ -103,6 +103,38 @@ spec has `usage`).
- **A spec opts into the matrix** by declaring `matrix: { rows, cols }` with
control keys — only axes a reviewer actually scans (Button: variant × size).
+## Examples pages — the example IS the page
+
+`pages/examples/` holds whole-page specimens of classic product surfaces
+(a settings page, …) — the surfaces every product has, where library-wide
+passes (cursor, motion, width) are judged on a real interface instead of
+single-component playgrounds. They are a third page kind beside component
+pages and foundation pages, with their own law:
+
+- **No doc frame.** The example fills the content area directly — its own
+ `PageShell` IS the page. Never wrap it in a documentation spine, a
+ `STAGE_FRAME_CLASS` frame, or a `CanvasStage`: the point is to feel the
+ components in a real surface, and a stage would turn them back into
+ boxed specimens.
+- **Owners only, stricter than anywhere else.** An example page is the
+ strongest copy-precedent surface in the repo — compose it exclusively
+ from owner vocabulary (`PageShell` / `SettingsSection` / `SettingsRow` /
+ the controls themselves). If a shape the page needs has no owner, that
+ is a vocabulary gap to legislate, not a class to hand-write.
+- **No width pinning, no state seeding beyond defaults.** Controls render
+ at their library defaults (`Select` at `w-fit`, `Input` at `w-full`, …)
+ so the page exposes true default behavior in real rows. If a row looks
+ wrong, the fix belongs in the library, not in a class on the page.
+- **Overlays uncontrolled, state local** (per the overlay invariants
+ below): each `Select`/`Dialog` owns its open state; page state is plain
+ refs. No fake backends, no demo data plumbing.
+- **Bilingual, generic copy.** All strings go through `tt()` and read as
+ "any product's" copy — an example names no concrete product and teaches
+ no Memoh-specific business wording.
+
+Register each page in `registry.ts` under the `examples` nav group via the
+`example()` helper (id prefix `examples/`).
+
## Overlay invariants (dead-locked three times — do not re-try)
- **Overlay specs render UNCONTROLLED — `interactive: true`, NO `open`
diff --git a/showcase/pages/examples/SettingsPageExample.vue b/showcase/pages/examples/SettingsPageExample.vue
new file mode 100644
index 0000000..a2a3b42
--- /dev/null
+++ b/showcase/pages/examples/SettingsPageExample.vue
@@ -0,0 +1,221 @@
+
+
+
+
+