# Forge Z-Index 层级体系

> 本文档记录 Forge 界面中所有层叠上下文（z-index）的使用约定。新增组件应优先复用已有层级，避免引入魔法数字。

---

## 层级总览

| 层级 | 值 | 用途 | 典型组件 |
|---|---|---|---|
| Base | `auto` / `0` | 普通文档流内容 | 页面主体、列表项、卡片 |
| Sticky | `20` | 粘性定位头部 | `TitleBar` |
| Overlay content | `10` | 模态框内部元素 | Onboarding 模态内容、Resize handle |
| Dropdown / Menu | `50` | 下拉菜单、右键菜单、工具提示 | Context menus, Select dropdowns, Slash command menu |
| Modal backdrop | `50` | 模态框遮罩层 | Project modal, Schedule view modals, Onboarding overlay |
| Toast / Tooltip | `50` | 浮动提示、拖拽提示 | Drop tooltip, Walking hint |
| Skip link | `9999` | 无障碍跳转链接 | `.skip-link`（仅键盘聚焦时显示） |

---

## 详细约定

### z-50 — 覆盖层（Overlay）

**使用场景：**
- `fixed inset-0` 的全屏遮罩（modal backdrop）
- `fixed` 定位的上下文菜单（context menu）
- `absolute` 定位的下拉选择器（dropdown select）
- 拖拽时的浮动提示（drop tooltip）

**现有实例：**
- `not-found.tsx` — 404 页面全屏背景
- `project-selection.tsx` — 项目选择页全屏背景
- `onboarding.tsx` — 引导页遮罩 + 模态内容容器
- `layout/project-modal.tsx` — 项目切换模态
- `layout/left-sidebar.tsx` — Session 右键菜单
- `layout/right-sidebar.tsx` — 文件树右键菜单 + 拖拽提示
- `layout/user-menu.tsx` — 用户下拉菜单
- `views/chat-view.tsx` — Permission/Thinking/Model 下拉菜单
- `views/schedule-view.tsx` — 确认对话框 + 下拉选择器
- `chat/slash-command-menu.tsx` — 斜杠命令自动补全
- `marketplace/*` — 模板右键菜单
- `manage/*` — Agents/MCP/Skills 面板右键菜单

**规则：**
- 所有 `fixed` 定位的覆盖层统一使用 `z-50`
- 禁止在同一视口内叠加多个 `z-50` 元素导致层叠冲突；如有需要，用 DOM 顺序控制（后渲染的在上方）

### z-40 — 次级覆盖层

**使用场景：**
- 需要高于普通内容但低于菜单/模态的浮动元素

**现有实例：**
- `right-sidebar.tsx` — 文件读取中的 "正在读取文件…" 提示

### z-10 — 局部提升

**使用场景：**
- 模态框内部的相对定位内容
- 需要略高于相邻元素的交互手柄

**现有实例：**
- `onboarding.tsx` — 模态卡片内容（确保在 backdrop 之上）
- `ui/resize-handle.tsx` — 拖拽调整宽度的手柄

### z-9999 — 无障碍专用

**使用场景：**
- `.skip-link` 仅在键盘 `focus` 时显示，必须凌驾于所有 UI 之上

**规则：**
- 仅限无障碍跳转链接使用，**禁止**其他组件使用此值

---

## 新增组件时的决策树

```
是否需要覆盖普通内容？
  ├─ 否 → 使用 auto 或 0
  └─ 是 → 是 fixed/absolute 的全屏遮罩或菜单？
        ├─ 是 → 使用 z-50
        └─ 否 → 是模态框内部元素？
              ├─ 是 → 使用 z-10
              └─ 否 → 是次级浮动提示？
                    ├─ 是 → 使用 z-40
                    └─ 否 → 重新考虑布局方案（优先用 DOM 顺序而非 z-index）
```

---

## 禁止事项

- ❌ 使用 `z-[60]`、`z-[100]`、`z-[999]` 等魔法数字
- ❌ 在同一组件树中混用 `z-50` 和 `z-[51]` 来"打赢"层叠战争
- ❌ 为普通文档流内容添加 `z-10` "以防万一"

## 最佳实践

- ✅ 优先使用 **DOM 渲染顺序** 控制层叠（后渲染的元素天然在上层）
- ✅ 使用 `position: fixed` + `inset: 0` 创建独立的层叠上下文，而非依赖 z-index
- ✅ 模态框组件使用 Portal 渲染到 `document.body`，避免被父元素的 `overflow: hidden` 裁剪
