## Context

清道夫微信小程序使用 `navigationStyle: custom` 实现自定义导航栏。所有页面顶部的标题、返回按钮、功能按钮（通知、新增、筛选等）都由组件自行渲染。然而微信小程序右上角存在系统胶囊按钮（菜单 + 关闭），在 iPhone 上宽度约 87px、安卓上约 96px，且距离屏幕右侧有一定边距。当前部分页面把操作按钮直接放在右上角，导致真机运行时胶囊遮挡按钮。

已有组件：`StatusBar.vue` 负责状态栏占位，`TopBar.vue` 负责标题栏。两者均未考虑胶囊区域。

## Goals / Non-Goals

**Goals:**
- 提供可在任何页面/组件复用的胶囊安全区方案。
- 改造 `TopBar.vue`，使其右侧插槽内容自动避让胶囊。
- 修复 `pages/home/home`、`pages/schedule/schedule`、`pages/task/task` 的遮挡问题。
- 保持 H5/App 等非微信环境下的正常显示（ graceful fallback）。

**Non-Goals:**
- 不调整底部 tabBar 结构。
- 不改页面整体布局风格。
- 不处理胶囊以外的系统 UI（如灵动岛、底部横条）。

## Decisions

### 1. 新增 `CapsuleSafeArea.vue` 组件
- 通过 `uni.getMenuButtonBoundingClientRect()` 获取胶囊坐标与宽度。
- 通过 `uni.getSystemInfoSync()` 获取屏幕宽度。
- 计算右侧需要避让的最小宽度：`screenWidth - menuButton.left + 8px`（额外 8px 缓冲）。
- 在微信小程序下渲染一个占位 view；在其他平台返回 0 或固定值，避免影响布局。
- 提供 `width` 插槽 prop 或默认 slot，方便 `TopBar` 直接使用。

### 2. `TopBar.vue` 集成安全区
- 右侧 `<slot name="right" />` 外层用 `CapsuleSafeArea` 包裹，使右侧内容左侧平移。
- 保持标题居左或根据左侧内容自适应，不改动标题样式。
- 为避免标题被挤压过窄，标题区使用 `flex-1 min-w-0 truncate`。

### 3. 页面顶部操作按钮统一使用 `TopBar`
- `pages/home/home` 三个首页当前直接在页面内写 header，需把右上角通知铃铛移入 `TopBar` 的 right slot，或给按钮加 `mr-[safeWidth]`。
- `pages/task/task` 的 `TaskListView` 顶部「新增」按钮纳入 `TopBar` right slot。
- `pages/schedule/schedule` 的 `ScheduleView` 顶部「今天」「新增排班」按钮纳入 `TopBar` right slot。

### 4. 策略选择：右侧按钮整体左移
- 对比方案：
  - 按钮换行：改动大，破坏视觉一致性。
  - 右侧留空白：浪费空间且用户看不到原因。
  - 按钮整体左移：改动最小，符合微信小程序主流做法，保留按钮可点击区域。
- 选定「按钮整体左移」。

## Risks / Trade-offs

- **[Risk]** `uni.getMenuButtonBoundingClientRect()` 在小程序初始化后可能异步变化（如旋转屏幕）。
  - **Mitigation:** 在 `onMounted` 获取并监听窗口尺寸变化；如获取失败则使用基于屏幕宽度的默认估算值。
- **[Risk]** 不同机型胶囊尺寸差异大。
  - **Mitigation:** 使用动态 API 获取真实尺寸，而非写死 px。
- **[Risk]** 顶部标题栏空间被压缩，标题可能显示不全。
  - **Mitigation:** 标题使用 `truncate` 截断，并确保左侧返回按钮只在需要时显示。
- **[Trade-off]** H5/App 下无胶囊，安全区宽度为 0，布局与之前一致。

## Migration Plan

- 新增 `CapsuleSafeArea.vue`。
- 修改 `TopBar.vue`，集成安全区。
- 修改三个页面/视图组件，使右上角按钮通过 `TopBar` right slot 渲染。
- 构建 `npm run build:mp-weixin` 验证无编译错误。
- 在微信开发者工具真机调试中检查胶囊未遮挡按钮。

## Open Questions

- 是否需要在每个页面单独处理 `StatusBar + TopBar`，还是统一封装一个 `PageHeader`？本次保持最小改动，只改 `TopBar`。
