From 6e6fae8d8424c8cca50c0c7c0092500a15b0f52e Mon Sep 17 00:00:00 2001 From: jesse-ux Date: Tue, 13 Oct 2026 14:32:25 +0800 Subject: [PATCH 1/2] fix(ui): stop the composer radius from clipping the first glyph The inner textarea kept a 12px radius after its side padding was cleared, so the first character was cut into an arc. Only .composer textarea is now border-radius 0. The outer frame is unchanged. Verified: chat-reading-load-mobile.test.ts was 7 pass / 1 fail before the CSS change, then 8 pass / 0 fail / 0 cancelled. tsc --noEmit exit 0. npm run lint 0 errors. Co-Authored-By: Grok (agent loop) --- docs/BUG_HISTORY.md | 15 +++++++++++ ...RESS-composer-first-glyph-clip-20261013.md | 27 +++++++++++++++++++ docs/tasks/README.md | 2 +- frontend/DESIGN.md | 1 + frontend/src/app/globals.css | 2 +- .../tests/chat-reading-load-mobile.test.ts | 4 +++ 6 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 2638f05d..2c6cb9d0 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -17615,3 +17615,18 @@ - 相关记录:BUG-511、BUG-1309。 - 复发自:无。 - 修复版本:已部署 staging `586561eb`(2026-10-12 核对:health gitCommit / apiGitCommit=586561eb、`requiredMigrationsPresent` true,`/login` 200,未登录 `/api/account` 401;合并后 npm test 5025 条、失败 24 逐名同 `798e15ef` 基线)。Claude 直接执行,产品 10-12 授权。 + +## BUG-1311 | 聊天输入框内层圆角把第一个字左缘裁掉 + +- 状态:fixed-pending-verify(合同测试已锁住;真机看普通聊天和生时校正两个输入框后标 resolved) +- 首次发现 / 最近更新:2026-10-13 / 2026-10-13 +- 来源:产品负责人在 issue #52 的截图。placeholder 第一个字左侧有一道圆弧,打字时第一个字左边缺一块。 +- 现象:聊天输入框里第一个字的左缘被裁成圆弧。普通聊天和生时校正共用同一个输入框,两处都有。 +- 触发条件:输入框只有一行高,左右内边距为 0,内层文本框仍带着 12px 圆角。 +- 根因:`Textarea` 原语默认 `rounded-lg`(12px)。`.composer textarea` 清掉了边框、背景和左右内边距,没有清圆角。文本框按圆角裁切内容,第一个字正好压在左上和左下两个圆角上。 +- 修复:只在 `.composer textarea` 加 `border-radius: 0`。外框 `.composer` 的圆角不动。原语不改,别的表单仍用圆角。 +- 验证:`frontend/tests/chat-reading-load-mobile.test.ts` 新增断言,规则必须含 `border-radius: 0`。改样式前该条失败(7 过 1 失败,cancelled 0);改后该文件 8 过 0 失败,cancelled 0。真机清单 `docs/testing/composer-first-glyph-clip-20261013.md` 未走。 +- 防复发:同上测试锁住内层直角。不改 `textarea.tsx`,避免别的表单丢掉圆角。 +- 相关记录:无。 +- 复发自:无。 +- 修复版本:分支 `codex/composer-first-glyph-clip-20261013`,尚未部署。推送后的 40 位 SHA 写在 issue #52 的执行回报里。 diff --git a/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md b/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md new file mode 100644 index 00000000..f69112cc --- /dev/null +++ b/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md @@ -0,0 +1,27 @@ +# 进度 · 输入框第一个字被圆角裁掉(2026-10-13) + +- 分支:`codex/composer-first-glyph-clip-20261013`(从当时的 `origin/staging` `804b6ee3f355f67015cde4d9bc42f2f79c3f267f` 新建) +- 任务书:`docs/tasks/TASK-composer-first-glyph-clip-20261013.md` +- 结论:内层输入框改为直角。外面的圆角框没动。普通聊天和生时校正共用这一个输入框。 + +## 做了什么 + +- `frontend/src/app/globals.css`:`.composer textarea` 增加 `border-radius: 0`。 +- `frontend/tests/chat-reading-load-mobile.test.ts`:锁住这条规则必须含 `border-radius: 0`。 +- `frontend/DESIGN.md`、`docs/BUG_HISTORY.md`(BUG-1311)、`docs/tasks/README.md`。 +- 开工时 `docs/BUG_HISTORY.md` 最大号是 BUG-1310,本单用 BUG-1311,没有被占用。 + +## 检查 + +| 检查 | 命令 | 结果 | +| --- | --- | --- | +| 合同测试(改样式前) | `node node_modules/tsx/dist/cli.mjs --test tests/chat-reading-load-mobile.test.ts` | 8 条,7 过,1 失败,cancelled 0。失败的就是新断言 | +| 合同测试(改样式后) | 同上 | 8 条,8 过,0 失败,cancelled 0 | +| 类型检查 | `frontend\node_modules\.bin\tsc --noEmit -p frontend` | 退出码 0 | +| lint | `npm run lint`(frontend) | 退出码 0,0 error,125 warning(原有,未改) | +| 全量前端测试 / Python 快速门 / test:db | 未跑 | 任务书不要求;未动数据库 | + +## 偏离 + +- 没有。真机还没看,清单在 `docs/testing/composer-first-glyph-clip-20261013.md`。推送后的 40 位 SHA 写在 issue #52 的执行回报里。 +- 本轮开始时评论接口在 Windows PowerShell 5.1 里把评论列表粘成一条,计划被滤掉,误发过一条「需拍板」。接口修好后读到计划,那条作废,本轮按任务书改完。标签「需拍板」已去掉。 diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 44e21796..611a7576 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -134,7 +134,7 @@ | 任务书 | 进度 | 主题 | 状态 | 落点 | | --- | --- | --- | --- | --- | -| `TASK-composer-first-glyph-clip-20261013.md` | — | **输入框第一个字被圆角裁掉(agent 循环 issue #52)**:`Textarea` 原语自带 12px 圆角,`.composer textarea` 清了边框与左右内边距却没清圆角,浏览器按圆角裁滚动内容,第一个字左缘被裁成圆弧;只在 `.composer textarea` 加 `border-radius: 0`,原语不动。执行方 Grok。BUG-1311 | 待领取 | `codex/composer-first-glyph-clip-20261013` | +| `TASK-composer-first-glyph-clip-20261013.md` | `PROGRESS-composer-first-glyph-clip-20261013.md` | **输入框第一个字被圆角裁掉(agent 循环 issue #52)**:`Textarea` 原语自带 12px 圆角,`.composer textarea` 清了边框与左右内边距却没清圆角,浏览器按圆角裁滚动内容,第一个字左缘被裁成圆弧;只在 `.composer textarea` 加 `border-radius: 0`,原语不动。执行方 Grok。BUG-1311 | 待验收 | `codex/composer-first-glyph-clip-20261013` | | `TASK-consult-card-full-source-20261007.md` | `PROGRESS-consult-card-full-source-20261007.md` | **对话数据卡与报告同源 + 领域综合判断表**:事业卡只有约 7,600 字符、无自然代表星、无大运主星关系、D10 联动只能补取、补取上限 1;全 12 领域;综合判断表、参与清单(不止 D1/D9,含精度闸)、补取 3 次、资料目录均已确认;KP 不上卡、不联网、不接书籍语料;排在 sync6 与报告单之后 | 验收未通过(`35dafd1e`,见 fix-20261009) | `codex/consult-card-full-source-20261007` | | `TASK-consult-card-full-source-fix-20261009.md` | `PROGRESS-consult-card-full-source-fix-20261009.md` | **对话卡同源修复**:缓存键无日期致当前大运冻结、整卡 37.5K(每格带内部路径)、星照整列 blocked(资料库其实有出处)、前端测试手写数据、无预热;合入前用临时 key 跑模型 A/B 与生平回测 | F1–F5 已验收,F6 未过(见 fix2) | `codex/consult-card-full-source-20261007` | | `TASK-consult-card-full-source-fix2-20261009.md` | `PROGRESS-consult-card-full-source-fix2-20261009.md` | **对话卡同源第二轮**:齐达内事业被「水星=说写算」带偏致严重冲突 1→3;事业清单加「代表星只看力量受冲、不按星性猜职业」后重跑回测(≤1 才合入);预热改为不占重计算名额 | 已验收并快进合入 staging(2026-10-09,产品按严重冲突 ≤ 1 放行;剩余 1 次见 career-type-residual) | `codex/consult-card-full-source-20261007` | diff --git a/frontend/DESIGN.md b/frontend/DESIGN.md index d9074fc8..df74c1cf 100644 --- a/frontend/DESIGN.md +++ b/frontend/DESIGN.md @@ -344,6 +344,7 @@ Radii have two visual steps. Controls use 8px (`--radius-md`; `--radius-xs` and - **Queue:** one pending card (`.composer-queue`) sits above the field while an answer is in flight. Copy: “已排队,回答结束后发出”, plus the text and a 44px “撤回”. A second Enter appends to the same card with a newline. Successful settlement sends it; stop, failure, or recovery puts the text back in the field. The send button is disabled while a card is waiting. No spinner. - **Accessibility:** persistent label where practical; composer has an explicit accessible label. - **One composer:** the rectification surface renders the same `ChatComposer` as the main chat; there is no second composer. A surface that owns its own draft passes it as `value`; the main chat reads the draft store. Both count down from the same 500-character ceiling through `CharacterRemaining`, which the composer renders inline and only once `characterRemainingVisible()` is true — it no longer has a permanent container. Controls that belong to the composer go through the `toolbar` slot; nothing is stacked below it. +- **Inner field corners:** the textarea inside `.composer` has `border-radius: 0`. Rounding stays on the outer `.composer` only. The field has no horizontal padding, so a radius on the textarea itself clips the first glyph's left edge (BUG-1311). ### Answer start anchor diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index aedc3b73..48add232 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -1857,7 +1857,7 @@ section[popover]:has(> [data-sonner-toaster]), section[popover][aria-label^="页 .composer-tools { min-width: 0; display: flex; align-items: center; gap: var(--space-2); } .composer-row-end { display: flex; flex: 1; align-items: center; justify-content: flex-end; gap: var(--space-3); } .composer:focus-within { border-color: var(--color-action); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-action) 15%, transparent); } -.composer textarea { width: 100%; min-width: 0; min-height: 28px; max-height: 148px; resize: none; padding: var(--space-1) 0 0; border: 0; outline: 0; background: transparent; color: var(--color-ink); line-height: 1.5; font-size: var(--type-body-md); } +.composer textarea { width: 100%; min-width: 0; min-height: 28px; max-height: 148px; resize: none; padding: var(--space-1) 0 0; border: 0; outline: 0; background: transparent; color: var(--color-ink); line-height: 1.5; font-size: var(--type-body-md); border-radius: 0; } .composer .composer-row-end > button { width: 36px; height: 36px; display: grid; flex: 0 0 auto; place-items: center; border: 0; color: var(--color-on-action-fill); cursor: pointer; transition: background-color 120ms ease-out, transform 120ms ease-out; border-radius: 999px; background: var(--color-action-fill); } .composer .composer-row-end > button:disabled { opacity: 1; background: var(--color-action-fill-disabled); color: var(--color-on-action-fill-disabled); } .composer .composer-stop { background: var(--color-action-fill); } diff --git a/frontend/tests/chat-reading-load-mobile.test.ts b/frontend/tests/chat-reading-load-mobile.test.ts index 5427d46e..87aba67d 100644 --- a/frontend/tests/chat-reading-load-mobile.test.ts +++ b/frontend/tests/chat-reading-load-mobile.test.ts @@ -62,6 +62,10 @@ test("otp and composer keep their existing safe sizes", () => { assert.match(ruleFor(".composer textarea {"), /font-size:\s*var\(--type-body-md\)/); }); +test("composer textarea radius is 0 because a 0 left padding clips the first glyph on rounded corners", () => { + assert.match(ruleFor(".composer textarea {"), /border-radius:\s*0/); +}); + test("personal-report tables are not retargeted by the chat wide-table rule", () => { const mobile = css.slice(css.indexOf("@media (max-width: 767px)")); const wide = mobile.match( From 606f4d3aef03a4d079f7c3b29aa39514b9b47334 Mon Sep 17 00:00:00 2001 From: jesse-ux Date: Tue, 13 Oct 2026 15:13:57 +0800 Subject: [PATCH 2/2] docs(tasks): note the composer clip branch now contains latest staging Co-Authored-By: Grok (agent loop) --- docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md b/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md index f69112cc..b956b34e 100644 --- a/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md +++ b/docs/tasks/PROGRESS-composer-first-glyph-clip-20261013.md @@ -25,3 +25,4 @@ - 没有。真机还没看,清单在 `docs/testing/composer-first-glyph-clip-20261013.md`。推送后的 40 位 SHA 写在 issue #52 的执行回报里。 - 本轮开始时评论接口在 Windows PowerShell 5.1 里把评论列表粘成一条,计划被滤掉,误发过一条「需拍板」。接口修好后读到计划,那条作废,本轮按任务书改完。标签「需拍板」已去掉。 +- 按修复单跟上最新版本,修复内容未变。已推送的提交不能改写,所以把最新版本合并进原分支,没有重写历史。任务索引两行都留着。样式、测试、设计说明、缺陷记录与上次相同。