## ADDED Requirements

### Requirement: CapsuleSafeArea component calculates safe margin
The system SHALL provide a `CapsuleSafeArea` component that computes the minimum right-side margin needed to avoid the WeChat mini-program capsule button, and wraps its default slot with that left margin.

#### Scenario: WeChat environment
- **WHEN** the app runs in WeChat mini-program
- **THEN** the component uses `uni.getMenuButtonBoundingClientRect()` and `uni.getSystemInfoSync()` to compute `safeWidth = screenWidth - menuButton.left + 8px`, and applies `margin-left: safeWidth` to the wrapped content

#### Scenario: Non-WeChat environment
- **WHEN** the app runs on H5 or App
- **THEN** the component returns a safe width of `0` so the layout remains unchanged

#### Scenario: API failure fallback
- **WHEN** `uni.getMenuButtonBoundingClientRect()` fails or returns invalid data
- **THEN** the component falls back to a conservative estimate based on `screenWidth` (approximately 28% of screen width) so the layout remains safe on common devices

### Requirement: TopBar right slot is protected by capsule safe area
The system SHALL wrap the `TopBar` right slot inside `CapsuleSafeArea` so any right-side action buttons are shifted left of the capsule automatically. Pages using `TopBar` shall not need to manually add capsule-safe spacing.

#### Scenario: Right slot contains a button
- **WHEN** a page places a button in the `TopBar` right slot
- **THEN** the button is rendered with a left margin equal to the capsule safe width and remains fully clickable

### Requirement: Home page notification bell avoids capsule
The system SHALL ensure the notification bell on `pages/home/home` (all roles) does not overlap the WeChat capsule by rendering the home header with `TopBar` and placing the bell inside the `TopBar` right slot.

#### Scenario: Dispatch home renders notification icon
- **WHEN** `DispatchHome.vue` renders the top-right notification bell
- **THEN** the header uses `TopBar`, the left slot keeps the existing avatar/greeting, and the bell is placed inside the `TopBar` right slot and is not covered by the capsule

### Requirement: Task page add button avoids capsule
The system SHALL ensure the "新增/发布" button on `pages/task/task` does not overlap the WeChat capsule by rendering the task list header with `TopBar` and placing the button inside the `TopBar` right slot.

#### Scenario: TaskListView renders add button
- **WHEN** `TaskListView.vue` renders the top-right add button
- **THEN** the header uses `TopBar` with the page title, and the button is placed inside the `TopBar` right slot and is not covered by the capsule

### Requirement: Schedule page actions avoid capsule
The system SHALL ensure the "今天" and "新增排班" buttons on `pages/schedule/schedule` do not overlap the WeChat capsule by placing both buttons inside the `TopBar` right slot.

#### Scenario: ScheduleView renders top actions
- **WHEN** `ScheduleView.vue` renders the top-right action buttons
- **THEN** both "今天" and "新增排班" buttons are placed inside the `TopBar` right slot and are not covered by the capsule, and the month-switching row below `TopBar` only keeps the month navigation on the left

### Requirement: Build passes and layout remains valid on non-WeChat platforms
The system SHALL keep `npm run build:mp-weixin` and `npm run type-check` passing, and non-WeChat layouts must not regress.

#### Scenario: Build verification
- **WHEN** the project is built for WeChat or type-checked
- **THEN** no TypeScript or template errors are introduced
