diff --git a/apps/ai-game-creator-shell/src/styles.css b/apps/ai-game-creator-shell/src/styles.css
index fdbfe9e32..31fc74cd2 100644
--- a/apps/ai-game-creator-shell/src/styles.css
+++ b/apps/ai-game-creator-shell/src/styles.css
@@ -13471,11 +13471,11 @@ details.design-agent-reasoning[open]
队列 chip 与提示段落的 `margin` 都写回前文各自那条规则。 */
/* ④ 思维强度**并入模型菜单**:底行只留模型触发钮一颗控件,强度区嵌在菜单顶部。
- 菜单外壳(`.conversation-model-menu-shell`)沿用原来模型菜单的定位 / 描边 / 底色 /
- 阴影(向上展开、贴触发钮右缘),强度和模型列表共用同一张卡;强度区里是原生
- ``,自带 `role="slider"`、`aria-valuemin/max/now` 与
- ←/→/Home/End,`aria-valuetext` 报中文档位名,点轨道或拖拽按 `step` 吸附到档位。
- 颜色全部走 `--platform-*`(不引入新色值)。 */
+ 菜单外壳(`.conversation-model-menu-shell`)沿用原来模型菜单的锚点与朝向(贴触发钮
+ 右缘、向上展开、距输入区 8px),观感按 Codex 参考图重做:大圆角、松内边距、柔和阴影 +
+ 极淡描边,颜色全部取 `--platform-*` 暖色 token(不引入新色值)。
+ 强度区里是原生 ``,自带 `role="slider"`、`aria-valuemin/max/now`
+ 与 ←/→/Home/End,`aria-valuetext` 报中文档位名,点轨道或拖拽按 `step` 吸附到档位。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
@@ -13484,20 +13484,24 @@ details.design-agent-reasoning[open]
right: 0;
bottom: calc(100% + 8px);
z-index: 20;
- display: grid;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
width: max-content;
- min-width: 216px;
+ min-width: 260px;
max-width: min(320px, calc(100vw - 24px));
- border: 1px solid var(--platform-surface-border);
- border-radius: 12px;
+ padding: 12px;
+ border: 1px solid var(--platform-line-soft);
+ border-radius: 16px;
background: var(--platform-input-fill);
box-shadow:
- 0 14px 30px rgb(31 41 55 / 13%),
- 0 2px 6px rgb(31 41 55 / 5%);
+ 0 18px 40px rgb(112 57 30 / 14%),
+ 0 2px 8px rgb(112 57 30 / 6%);
pointer-events: auto;
}
-/* 里层菜单回到文档流:外壳已经有位置 / 描边 / 底色,列表只负责滚动与截断。 */
+/* 里层菜单回到文档流:外壳已经有位置 / 描边 / 底色,列表只负责滚动与截断。
+ 行高更舒展(34px)、行圆角 9px、滚动条细且平时透明(悬停卡片才显形)。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
@@ -13507,12 +13511,90 @@ details.design-agent-reasoning[open]
width: 100%;
min-width: 0;
max-width: none;
- max-height: 260px;
+ /* 170 = 5 行 × 34px:不会停在半行上;再长就滚动(细滚动条,悬停显形)。 */
+ max-height: 170px;
overflow: auto;
+ padding: 0;
border: 0;
- border-radius: 0;
+ border-radius: 12px;
background: transparent;
box-shadow: none;
+ scrollbar-width: thin;
+ scrollbar-color: var(--platform-subpanel-border) transparent;
+}
+
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu::-webkit-scrollbar {
+ width: 6px;
+}
+
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+/* 静止时不画滚动条,鼠标进卡片才显形("细 + 自动隐藏")。 */
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu::-webkit-scrollbar-thumb {
+ border-radius: 999px;
+ background: transparent;
+}
+
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell:hover
+ .conversation-model-menu::-webkit-scrollbar-thumb {
+ background: var(--platform-subpanel-border);
+}
+
+/* 行:34px 高、9px 圆角、hover 极淡暖底,选中是轻量 pill(不做重色块)。
+ 前文那几条 `!important` 的同属性规则在这里按同一档 `!important` + 更高特异性盖回。 */
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu
+ button {
+ min-height: 34px !important;
+ padding: 0 10px !important;
+ border-radius: 9px !important;
+}
+
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu
+ button:hover:not(:disabled),
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu
+ button:focus-visible {
+ background: var(--platform-nav-item-icon-fill) !important;
+ color: var(--platform-text-strong) !important;
+}
+
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .conversation-model-menu-shell
+ .conversation-model-menu
+ button[aria-selected='true'] {
+ background: var(--platform-warm-bg) !important;
+ color: var(--platform-text-strong) !important;
+ font-weight: 600 !important;
}
/* 列表宽度由外壳限定,超长模型名走省略号(原来靠 `width: max-content` 不截断)。 */
@@ -13536,16 +13618,30 @@ details.design-agent-reasoning[open]
white-space: nowrap;
}
-/* 强度区:菜单顶部、与模型列表用一条分隔线分开(分隔线是最后一个子属性的
- `border-bottom`,列表首项自带 padding,不会显得挤)。 */
+/* 强度区:菜单顶部,与列表之间只用留白分开(不画横贯分隔线),标题左右层级分明。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-reasoning-effort.is-section {
display: grid;
- gap: 6px;
- padding: 9px 9px 7px;
- border-bottom: 1px solid var(--platform-line-soft);
+ /* 单列铺满:`auto` 轨道在这里只按 max-content 定尺,滑块会被压回固有宽度。 */
+ grid-template-columns: minmax(0, 1fr);
+ justify-items: stretch;
+ width: 100%;
+ align-self: stretch;
+ gap: 10px;
+ padding: 4px 6px 2px;
+}
+
+/* 滑块与档位点是一个整体:点绝对定位叠在轨道中线上(不受字号 / 行高变化影响)。 */
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .project-chat-composer-strength-slider {
+ position: relative;
+ display: grid;
+ grid-template-columns: minmax(0, 1fr);
+ width: 100%;
}
.game-workbench-chat
@@ -13553,7 +13649,7 @@ details.design-agent-reasoning[open]
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-head {
display: flex;
- align-items: center;
+ align-items: baseline;
justify-content: space-between;
gap: 8px;
min-width: 0;
@@ -13563,9 +13659,9 @@ details.design-agent-reasoning[open]
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-title {
- color: var(--platform-text-base);
+ color: var(--platform-text-strong);
font-size: 12px;
- font-weight: 700;
+ font-weight: 600;
}
.game-workbench-chat
@@ -13573,7 +13669,7 @@ details.design-agent-reasoning[open]
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-range {
width: 100%;
- height: 24px;
+ height: 26px;
margin: 0;
appearance: none;
border: 0;
@@ -13587,21 +13683,26 @@ details.design-agent-reasoning[open]
.project-chat-composer-strength-range::-webkit-slider-runnable-track {
height: 6px;
border-radius: 999px;
- background: var(--platform-button-ghost-fill);
+ /* 已选段用主色、未选段用暖灰:进度由组件写进来的 `--strength-progress` 决定。 */
+ background: linear-gradient(
+ to right,
+ var(--platform-accent) 0 var(--strength-progress, 0%),
+ var(--platform-subpanel-border) var(--strength-progress, 0%) 100%
+ );
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-range::-webkit-slider-thumb {
- width: 18px;
- height: 18px;
- margin-top: -6px;
+ width: 20px;
+ height: 20px;
+ margin-top: -7px;
appearance: none;
- border: 2px solid var(--platform-button-primary-fill);
+ border: 2px solid var(--platform-accent);
border-radius: 999px;
- background: var(--platform-input-fill);
- box-shadow: 0 1px 2px rgb(0 0 0 / 18%);
+ background: var(--platform-input-highlight);
+ box-shadow: 0 2px 6px rgb(112 57 30 / 22%);
}
.game-workbench-chat
@@ -13651,19 +13752,28 @@ details.design-agent-reasoning[open]
.project-chat-composer-strength-range::-moz-range-track {
height: 6px;
border-radius: 999px;
- background: var(--platform-button-ghost-fill);
+ background: var(--platform-subpanel-border);
+}
+
+.game-workbench-chat
+ .project-chat-surface.is-direct-codex
+ .project-chat-composer.is-direct-codex
+ .project-chat-composer-strength-range::-moz-range-progress {
+ height: 6px;
+ border-radius: 999px;
+ background: var(--platform-accent);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-range::-moz-range-thumb {
- width: 18px;
- height: 18px;
- border: 2px solid var(--platform-button-primary-fill);
+ width: 20px;
+ height: 20px;
+ border: 2px solid var(--platform-accent);
border-radius: 999px;
- background: var(--platform-input-fill);
- box-shadow: 0 1px 2px rgb(0 0 0 / 18%);
+ background: var(--platform-input-highlight);
+ box-shadow: 0 2px 6px rgb(112 57 30 / 22%);
}
/* 档位点:纯装饰(命中与吸附由原生 range 负责),个数跟着档位契约走,
@@ -13672,11 +13782,17 @@ details.design-agent-reasoning[open]
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-stops {
+ position: absolute;
+ top: 50%;
+ right: 0;
+ left: 0;
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
+ align-items: center;
justify-items: center;
- margin-top: -12px;
+ height: 6px;
+ transform: translateY(-50%);
pointer-events: none;
}
@@ -13685,10 +13801,11 @@ details.design-agent-reasoning[open]
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-stops
span {
- width: 5px;
- height: 5px;
+ width: 7px;
+ height: 7px;
+ border: 1.5px solid var(--platform-input-highlight);
border-radius: 999px;
- background: var(--platform-surface-border);
+ background: var(--platform-text-muted);
}
.game-workbench-chat
@@ -13696,7 +13813,7 @@ details.design-agent-reasoning[open]
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-stops
span.is-active {
- background: var(--platform-button-primary-fill);
+ background: var(--platform-accent);
}
.game-workbench-chat
@@ -13704,6 +13821,6 @@ details.design-agent-reasoning[open]
.project-chat-composer.is-direct-codex
.project-chat-composer-strength-value {
color: var(--platform-text-soft);
- font-size: 12px;
+ font-size: 11px;
text-align: right;
}
diff --git a/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectComposer/ComposerControls.tsx b/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectComposer/ComposerControls.tsx
index ef71def98..31dcecd5a 100644
--- a/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectComposer/ComposerControls.tsx
+++ b/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectComposer/ComposerControls.tsx
@@ -17,7 +17,7 @@ import {
Square,
X,
} from 'lucide-react';
-import type { RefObject } from 'react';
+import type { CSSProperties, RefObject } from 'react';
import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
@@ -476,35 +476,47 @@ export function ComposerReasoningEffortSelect({
{`当前:${activeLabel}`}
- {/* 原生 range 的 role/值域本来就成立,这里再显式写一遍:`aria-valuetext` 是
- 中文档位名,读屏念的是「最高」而不是「4」。 */}
- {
- const next = options[Number(event.currentTarget.value)];
- if (next && next.value !== effort) {
- selectEffort(next.value);
+
+ {/* 原生 range 的 role/值域本来就成立,这里再显式写一遍:`aria-valuetext` 是
+ 中文档位名,读屏念的是「最高」而不是「4」。 */}
+
-
- {options.map((option, index) => (
-
- ))}
+ aria-label="思维强度"
+ aria-valuemin={0}
+ aria-valuemax={options.length - 1}
+ aria-valuenow={activeIndex}
+ aria-valuetext={activeLabel}
+ disabled={disabled || saving}
+ onChange={(event) => {
+ const next = options[Number(event.currentTarget.value)];
+ if (next && next.value !== effort) {
+ selectEffort(next.value);
+ }
+ }}
+ />
+ {/* 档位点叠在轨道上(纯装饰,命中与吸附由原生 range 负责)。 */}
+
+ {options.map((option, index) => (
+
+ ))}
+
);
diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md
index 1bcc9dbbb..9ea23bd01 100644
--- a/docs/project-memory/shared-memory/pitfalls.md
+++ b/docs/project-memory/shared-memory/pitfalls.md
@@ -18,6 +18,9 @@
- 关掉旧的独立触发钮(底行元素 2 → 1);浮层的开合、Esc 与点击外部关闭都由模型菜单既有行为负责,强度区不再自带浮层。
- **取舍**:强度区随菜单挂载,打开时先显示「默认」再回读成落盘档位(一次 IPC 往返),测试里要 `waitFor`;换掉这一点需要把档位状态提到宿主,暂不做。
- **判据/取证**:`tests/appSurface/chat-composer.suite.ts`(底行不再有第二颗控件、菜单里改档落同一条持久化通道、Esc/点外部关闭、滑块不在 listbox 内)+ `tests/chatDialogFrameLayout.test.ts`(外壳向上展开 / 强度区网格 / 底行高度不增)+ `tests/appSurface/design-agent.suite.ts`(策划菜单里没有滑块)。
+- **视觉口径(用户复核二次要求)**:卡片与滑块的观感照 Codex 参考图,颜色只取我们自己的暖色 token——卡片圆角 16px、内边距 12px、极淡描边(`--platform-line-soft`)+ 柔和暖色投影(`rgb(112 57 30 / …)`,不用纯黑)、**不画横贯分隔线**(只靠留白);强度区标题 `--platform-text-strong` 12/600、右侧当前档位 `--platform-text-soft` 11px;轨道 6px 圆头,已选段 `--platform-accent`、未选段 `--platform-subpanel-border`(进度由组件写进来的 `--strength-progress` 驱动渐变),圆钮 20px(`--platform-input-highlight` 底 + `--platform-accent` 2px 描边 + 柔影),档位点 7px 绝对定位叠在轨道中线(`pointer-events: none`,不挡命中);模型列表行高 34px、行圆角 9px、hover `--platform-nav-item-icon-fill`、选中 `--platform-warm-bg` 轻量 pill + 右侧对勾;列表 `max-height: 170px`(=5×34,不出现半行),滚动条 6px 且平时透明、悬停卡片才显形。
+- **实测(无头 Chromium 夹具,447px / 900px)**:卡片 260×263(圆角 16 / 内边距 12)、强度区 234×61、滑块 222×26、档位点 7px 且中心与轨道中线重合(点 270 / 轨道 269)、列表行高 34、`max-height` 170(内容 315 → 滚动)、默认档进度 0%,按 `End` 到 100% 且文案变「当前:最高」;卡片右缘未溢出视口。
+
- **关联**:`features/project-workspace/ConversationModelSelect.tsx`、`view/project-development/chat/components/DirectProjectComposer/{DirectProjectComposer.tsx,ComposerControls.tsx}`、`src/styles.css`。
## 2026-10-03 AGC 输入区控件叠在一起:输入区内的操作排与状态提示不能用绝对定位