## ADDED Requirements

### Requirement: 输入聚焦时抑制背景按键

当某个文本输入框处于编辑态、或某个独占模态处于打开态时,TRNovel SHALL 把按键独占给该输入框/模态;背景页面的导航键与应用级快捷键 MUST NOT 响应。该抑制 MUST 由框架输入层自动完成,不依赖任何全局输入标志(如旧 `is_inputting` context)。

#### Scenario: 搜索框编辑中字符不触发背景命令

- **WHEN** 用户激活搜索框(如按 `s`)进入编辑,并键入字符——包括 `q`/`j`/`k` 等本身是命令的字母
- **THEN** 这些字符 MUST 进入搜索框文本;背景列表 MUST NOT 翻页或选中;应用 MUST NOT 退出

#### Scenario: 模态打开时背景不响应

- **WHEN** 任一独占模态(确认 / 告警 / 快捷键帮助 / 浏览器验证)打开
- **THEN** 背景页面 MUST NOT 响应导航或命令键;仅模态自身的键(`Esc`/`Enter`/`y`/`n` 等)生效

### Requirement: 退出输入后背景按键立即恢复且无跨帧竞态

当输入框退出编辑或模态关闭后,背景按键 MUST 在下一帧立即恢复响应。提交或退出输入的那一次按键 MUST NOT 被背景组件在同一次分发中误当作命令处理(消除旧广播模型下的跨帧门控竞态)。

#### Scenario: 提交搜索不误触进入阅读

- **WHEN** 用户在章节搜索框中按 `Enter` 提交搜索
- **THEN** 该 `Enter` MUST 仅由搜索框处理(提交并退出编辑);背景章节列表 MUST NOT 把同一次 `Enter` 当作「选中章节 → 进入阅读」

#### Scenario: 关闭模态后命令键恢复

- **WHEN** 用户关闭快捷键帮助模态
- **THEN** 下一帧背景页面的导航与命令键 MUST 重新生效

### Requirement: 全局快捷键在无活跃输入层时可用并在有活跃输入层时让位

退出(`q`)、前进(`g`)、后退(`b`)等应用级快捷键 MUST 在没有活跃输入框/模态时于任意页面可用;在有活跃输入框/模态时 MUST 让位(被抑制),不得劫持文本输入。这些键 MUST NOT 被注册为真全局(不受输入层截断)的处理器。

#### Scenario: 普通浏览时 q 退出

- **WHEN** 用户在任意非编辑、无打开模态的页面按 `q`
- **THEN** 应用退出

#### Scenario: 编辑时 q 进入文本而非退出

- **WHEN** 搜索框处于编辑态,用户键入 `q`
- **THEN** `q` MUST 进入搜索框文本,应用 MUST NOT 退出

### Requirement: 嵌套模态只有栈顶接收输入

当多个独占模态/输入层叠加时,只有最顶层 MUST 接收输入;其下各层(含背景)MUST 被截断。纯展示型非阻塞浮层 MUST NOT 截断其下层。

#### Scenario: 弹窗叠加只响应栈顶

- **WHEN** 在一个打开的模态之上再打开第二个模态
- **THEN** 仅栈顶(第二个)模态响应按键;第一个模态与背景 MUST NOT 响应

### Requirement: 同层多个可聚焦组件仅 focused 者消费共享键

当同一层内多个可聚焦子组件绑定了相同按键(如 TTS 设置面板的语速/音量/声音子项都用 `h`/`l`)时,只有当前 focused 的子组件 MUST 消费该键;非 focused 的同层子组件 MUST 放行(返回未消费),避免一次按键被多个子组件重复响应。

#### Scenario: TTS 面板 h/l 只改当前项

- **WHEN** TTS 设置面板中焦点在「语速」子项,用户按 `l`
- **THEN** 仅「语速」被调整;「音量」「声音」等同层子项 MUST NOT 同时被改动
