diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index b233d662..c2889c9e 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -4966,7 +4966,7 @@ - 根因:BUG-328 把窄屏盘面改成工作区第二行(约 46% 高)且未设叠层;输入框 `.composer-wrap` 仍是 `position: relative; z-index: 2`。盘面与输入框在同一工作区网格里重叠时,输入框画在盘面标题之上。 - 修复:仅在视口宽度小于 768px 的移动端,把盘面改成工作区内 `z-index: 20` 的底部 sheet 覆盖层;桌面网页仍是右侧分栏,不出现底部弹出。遮罩点击、Escape、44px 关闭按钮可关;聊天列在打开时 `inert`。 - 验证:`frontend/tests/rectification-agentic-entry.test.ts`。 -- 防复发:底部 sheet 只允许 `matchMedia(max-width: 767px)` 触发,不得用聊天区 `clientWidth` 把桌面侧栏挤窄误判成移动端;桌面必须保持 `grid-template-columns: minmax(0, 1fr) minmax(18rem, 22.5rem)`。窄屏盘面必须是覆盖层(absolute、高于输入框的 z-index、不透明背景)。 +- 防复发:底部 sheet 只允许 `matchMedia(max-width: 767px)` 触发;工作区必须 `isolation: isolate` 且 `z-index: 0`,打开时隐藏 composer(含 `backdrop-filter`),覆盖层 z-index 必须高于输入框。不得用聊天区 `clientWidth` 把桌面侧栏挤窄误判成移动端。 - 相关记录:BUG-322、BUG-326、BUG-328 - 复发自:BUG-328(当时为了露出聊天改成下半屏分栏,叠层低于输入框) - 修复版本:9670b661 @@ -5019,6 +5019,54 @@ - 复发自:无 - 修复版本:9c4b64c9 +## BUG-334 | 移动端盘面覆盖层仍被输入框 backdrop-filter 盖住 + +- 状态:resolved +- 首次发现:2026-08-20 +- 最近更新:2026-08-20 +- 影响面:生时纠正窄屏盘面、`.composer-wrap`、`.rectification-board-overlay` +- 用户现象:打开“当前盘面”后,输入区预览条仍叠在弹层标题上;覆盖层和输入框像同一层,聊天列表也被挡住看不清。 +- 触发条件:移动端视口打开宫位表。iOS Safari 上更明显。 +- 根因:`.composer-wrap` 带 `z-index: 2` 和 `backdrop-filter`。iOS 会把该滤镜层合成到覆盖层之上。BUG-330 只把 overlay 设为 `z-index: 20`,工作区没有独立层叠上下文,也没有在打开时关掉输入框滤镜。 +- 修复:工作区 `isolation: isolate; z-index: 0` 锁住输入框层叠;覆盖层 `z-index: 50`。打开盘面时隐藏 composer(`visibility: hidden`、关掉 `backdrop-filter`),并收起预览条。sheet 高度改为 72%,上方聊天列表可从遮罩后看见。 +- 验证:`frontend/tests/rectification-agentic-entry.test.ts`。 +- 防复发:窄屏覆盖层必须高于 composer;打开时 composer 不得再带 `backdrop-filter`。源码合同锁定 `isolation: isolate`、overlay `z-index: 50`、`visibility: hidden`。展开入口不得放在输入框上方,必须挂在页头右上角。 +- 相关记录:BUG-328、BUG-330、BUG-335 +- 复发自:BUG-330(覆盖层 z-index 未锁住 iOS backdrop-filter 合成层) +- 修复版本:待发布 + +## BUG-335 | 移动端当前盘面入口仍在输入框上方 + +- 状态:resolved +- 首次发现:2026-08-20 +- 最近更新:2026-08-20 +- 影响面:生时纠正窄屏盘面入口、`.chat-header-actions`、`.rectification-board-peek` +- 用户现象:点开盘面的按钮在输入框上方,占掉打字区;希望放到右上角。 +- 触发条件:窄屏生时纠正会话。 +- 根因:`RectificationBoardPeek` 渲染在 `.composer-wrap` 里,输入框上方整条通栏。 +- 修复:页头 `chat-header-actions` 增加挂载点;窄屏未打开盘面时把预览按钮 portal 到余额按钮左侧。输入框上方不再放展开入口。 +- 验证:`frontend/tests/rectification-agentic-entry.test.ts`。 +- 防复发:源码合同锁定 `createPortal`、`data-rectification-header-slot`,并禁止 composer 内出现 `RectificationBoardPeek`。 +- 相关记录:BUG-330、BUG-334 +- 复发自:BUG-330(窄屏入口一开始就放在输入区) +- 修复版本:待发布 + +## BUG-336 | 初始化对话列表与资料卡不在同一栏 + +- 状态:resolved +- 首次发现:2026-08-20 +- 最近更新:2026-08-20 +- 影响面:首页 onboarding `.welcome`、出生资料卡、输入框 +- 用户现象:新用户初始化时,对话气泡和出生日期卡片左右对不齐;称呼阶段输入框也比上面的对话更窄。 +- 触发条件:未完成资料的新会话,尤其是填写出生日期与时间的步骤。 +- 根因:`.welcome` 被后续规则拉到 1040px 且无水平居中;资料卡 `max-width: 680/760px` 靠左。会话正文和输入框已经收成 760px 栏,初始化没有走同一套栏宽。 +- 修复:未完成资料时给会话加上 `is-onboarding`。欢迎区和资料卡使用 `--session-column-width`,与正式会话、输入框同一栏。 +- 验证:`frontend/tests/session-conversation-layout.test.ts`。 +- 防复发:源码合同锁定 `is-onboarding`、欢迎区栏宽和资料卡 `width: 100%; max-width: none`。 +- 相关记录:无 +- 复发自:无 +- 修复版本:待发布 + ## BUG-329 | 生时纠正 Agent 回答在结算后一次性出现,推理中无法停止 - 状态:resolved diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 9dca3ade..239a9477 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -1763,8 +1763,24 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class .onboarding-card-heading b { font-size: clamp(22px, 2.6vw, 30px); letter-spacing: -.03em; } .onboarding-card-heading small { max-width: 260px; color: var(--color-ink-secondary); line-height: 1.55; font-size: var(--type-caption); text-wrap: pretty; } .birth-time-intake { gap: var(--space-6); } +.conversation.is-onboarding .welcome { + box-sizing: border-box; + width: min(calc(var(--session-column-width) + (var(--session-column-gutter) * 2)), 100%); + margin-inline: auto; +} +.conversation.is-onboarding.is-empty .welcome { + width: min(var(--session-column-width), 100%); +} +.conversation.is-onboarding .onboarding-card, +.conversation.is-onboarding .onboarding-card.birth-time-transition-card { + width: 100%; + max-width: none; + margin-inline: 0; +} .conversation.is-onboarding-form { align-content: start; padding-bottom: var(--space-8); } -.conversation.is-onboarding-form .welcome { padding-top: var(--space-6); padding-bottom: var(--space-8); } +.conversation.is-onboarding-form .welcome { + padding: var(--space-6) var(--session-column-gutter) var(--space-8); +} .conversation.is-onboarding-form .welcome > .onboarding-message:first-child { padding-bottom: var(--space-3); } .conversation.is-onboarding-form .welcome > .onboarding-message:first-child .message-bubble p { max-width: 680px; @@ -1876,6 +1892,8 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class .rectification-workspace { position: relative; + z-index: 0; + isolation: isolate; min-width: 0; min-height: 0; height: 100%; @@ -1908,6 +1926,12 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class position: relative; z-index: 2; } +.rectification-workspace.is-compact.is-board-open .rectification-workspace__chat .composer-wrap { + z-index: 0; + visibility: hidden; + pointer-events: none; + backdrop-filter: none; +} .rectification-board { min-width: 0; min-height: 0; @@ -1920,10 +1944,9 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class .rectification-workspace.is-compact .rectification-board-overlay { position: absolute; inset: 0; - z-index: 20; + z-index: 50; display: grid; align-items: end; - isolation: isolate; } .rectification-board-scrim { position: absolute; @@ -1937,7 +1960,7 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class position: relative; z-index: 1; width: 100%; - height: 92%; + height: 72%; max-height: 100%; min-height: 0; overflow: hidden; @@ -2102,6 +2125,33 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class color: var(--color-ink); font-size: var(--type-caption); } +.chat-header-rectification:empty { + display: none; +} +.chat-header-rectification .rectification-board-peek { + display: inline-flex; + align-items: center; + justify-content: flex-end; + width: auto; + max-width: min(11.5rem, 42vw); + min-height: 44px; + margin: 0; + padding: 0 var(--space-3); + gap: var(--space-2); +} +.chat-header-rectification .rectification-board-peek strong, +.chat-header-rectification .rectification-board-peek span { + display: inline; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +@media (max-width: 480px) { + .chat-header-rectification .rectification-board-peek span { + display: none; + } +} .rectification-board-peek { display: flex; align-items: center; diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index ae7792f4..cff7d144 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -3559,6 +3559,7 @@ export default function Home() { {activeSession?.title || "新对话"}
+