diff --git a/01_content/src/client/index.tsx b/01_content/src/client/index.tsx
index 3a41013..8941814 100644
--- a/01_content/src/client/index.tsx
+++ b/01_content/src/client/index.tsx
@@ -1963,7 +1963,6 @@ function buildCustomLayoutPrompt(req: string): string {
{bindPick &&
{ setBindPick(null); setBindListOpen(false) }} />}
{bindPick && (
-
{t('bind.title')}
{/* 项目文件夹框(格式基准):第一行 emoji+标题,第二行路径;可随时更改 */}
@@ -1974,23 +1973,26 @@ function buildCustomLayoutPrompt(req: string): string {
{projects.folders[bindPick.id] ?? t('bind.folderNone')}
- {/* 绑定对话框(与项目文件夹同格式):第一行 💬+标题;第二行 分组 | 对话名(点击右侧弹列表);框内下方:说明 + 解绑 */}
+ {/* 绑定对话框(与项目文件夹同格式):第一行 💬+标题(最右解绑);第二行 分组 | 对话名(点击右侧弹列表,再点反选收起);框内下方:说明 */}
💬 {t('bind.title')}
+ {projects.bindings[bindPick.id] && (
+
+ )}
{(() => {
const sid = projects.bindings[bindPick.id]
if (!sid) {
return (
-
)}
diff --git a/01_content/src/client/styles.ts b/01_content/src/client/styles.ts
index 474543a..67fbdf9 100644
--- a/01_content/src/client/styles.ts
+++ b/01_content/src/client/styles.ts
@@ -276,7 +276,7 @@ export const css = xtermCss + '\n' + [
'.dsh-wt_bindHint{margin:6px 0 2px;font-size:11px;line-height:16px;color:var(--dsw-alias-label-secondary,#9aa4b2)}',
// 自定义窗完成页:自动绑定提示
'.dsh-wt_customDoneBind{margin:6px 0 0;font-size:11px;line-height:16px;color:var(--dsw-alias-state-accent-primary,#4f8ef7)}',
- '.dsh-wt_bindUnbind{display:inline-flex;align-items:center;gap:4px;margin:4px 0 0;padding:3px 8px;border:1px solid var(--dsw-alias-border-l1,#262b36);border-radius:6px;background:transparent;color:var(--dsw-alias-label-secondary,#9aa4b2);font:inherit;font-size:11px;line-height:16px;cursor:pointer}',
+ '.dsh-wt_bindUnbind{flex:none;display:inline-flex;align-items:center;gap:4px;padding:1px 8px;border:1px solid var(--dsw-alias-border-l1,#262b36);border-radius:5px;background:transparent;color:var(--dsw-alias-label-secondary,#9aa4b2);font:inherit;font-size:11px;line-height:16px;cursor:pointer}',
'.dsh-wt_bindUnbind:hover{color:var(--dsw-alias-state-danger,#f85149);border-color:var(--dsw-alias-state-danger,#f85149)}',
'.dsh-wt_bindList{max-height:280px;overflow:auto;position:static}',
'.dsh-wt_bindListPop{display:flex;flex-direction:column;padding:6px}',
diff --git a/02_process/worklogs/2026-08-16_worktable-v2.md b/02_process/worklogs/2026-08-16_worktable-v2.md
index d059d24..1ffe7e5 100644
--- a/02_process/worklogs/2026-08-16_worktable-v2.md
+++ b/02_process/worklogs/2026-08-16_worktable-v2.md
@@ -1119,3 +1119,17 @@
点行右侧弹列表(listOnRight、23 项)✓;选后列表收起、主弹窗显示新绑定(名称/▾/解绑)✓;
解绑回未绑定态 ✓;backdrop 关闭 ✓;functional-diag 全 20 STEP ERROR_COUNT: 0。
- 备注:纯客户端改动,F5 即生效。
+
+## 补记(绑定弹窗微调:去弹窗标题 + 解绑入行右对齐 + 列表反选收起)
+
+- 用户反馈:① 两个框标题字号是否一致——实测两处同为 12px(同一 .dsh-wt_bindFolderLabel
+ 类),探针加 fontSame 断言锁定;② 弹窗左上角「绑定对话」四字标题去掉(弹窗不止绑定
+ 对话,还有项目文件夹);③ 点「绑定对话」行弹出右侧列表后,再点一下反选收起(toggle);
+ ④ 解绑按钮放到 💬 绑定对话第一行最右(与 更改 同排右对齐格式)。
+- 实现:bindPop 删 menuLabel;bindUnbind 移入绑定框第一行(flex:none、与 folderChange 同款
+ 紧凑样式,保留 danger hover);两处 bindConvRow onClick 改 setBindListOpen(v => !v);
+ 解绑按钮不再占用框内下方。
+- 验证(probe-batch15.cjs 更新):popTitleGone ✓、fontSame(12px/12px)✓、列表开→再点
+ 收起(toggledClosed)且主弹窗保持 ✓、unbindInRow1/RightAligned ✓;functional-diag
+ 全 20 STEP ERROR_COUNT: 0。
+- 备注:纯客户端改动,F5 即生效。
diff --git a/04_test/probe-batch15.cjs b/04_test/probe-batch15.cjs
index ea646e9..c1ebd27 100644
--- a/04_test/probe-batch15.cjs
+++ b/04_test/probe-batch15.cjs
@@ -61,12 +61,18 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
out.box1Label = boxes[1] ? boxes[1].querySelector('.dsh-wt_bindFolderLabel').textContent : null;
out.box0Path = boxes[0] ? boxes[0].querySelector('.dsh-wt_bindFolderPath').textContent : null;
out.box0Change = !!(boxes[0] && boxes[0].querySelector('.dsh-wt_bindFolderChange'));
+ // 弹窗左上角不再有「绑定对话」标题;两个框标题字号一致
+ out.popTitleGone = !pop.querySelector('.dsh-wt_menuLabel');
+ var lb0 = boxes[0] && boxes[0].querySelector('.dsh-wt_bindFolderLabel');
+ var lb1 = boxes[1] && boxes[1].querySelector('.dsh-wt_bindFolderLabel');
+ out.fontSizes = { folder: lb0 ? getComputedStyle(lb0).fontSize : null, bind: lb1 ? getComputedStyle(lb1).fontSize : null };
+ out.fontSame = !!(lb0 && lb1 && getComputedStyle(lb0).fontSize === getComputedStyle(lb1).fontSize);
// 未绑定态:行显示 未绑定对话·点击选择;无解绑;无右侧列表
var rowNone = boxes[1] && boxes[1].querySelector('.dsh-wt_bindConvRow');
out.unboundRow = rowNone ? rowNone.textContent : null;
out.unbindAbsent = !pop.querySelector('.dsh-wt_bindUnbind');
out.listClosed0 = !vis('.dsh-wt_bindListPop');
- // 点击行 → 右侧弹列表
+ // 点击行 → 右侧弹列表;再点一下 → 反选收起
if (rowNone) { rowNone.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
await sleep(400);
var lpop = vis('.dsh-wt_bindListPop');
@@ -76,7 +82,15 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
out.debug = { prLeft: Math.round(pr.left), prRight: Math.round(pr.right), lrLeft: Math.round(lr.left), innerW: window.innerWidth };
out.listOnRight = lr.left >= pr.right - 1;
out.itemCount = lpop.querySelectorAll('.dsh-wt_selectItem').length;
- var item = lpop.querySelector('.dsh-wt_selectItem');
+ var rowNow = vis('.dsh-wt_bindPop .dsh-wt_bindConvRow');
+ if (rowNow) { rowNow.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
+ await sleep(400);
+ out.toggledClosed = !vis('.dsh-wt_bindListPop');
+ out.mainOpenAfterToggle = !!vis('.dsh-wt_bindPop');
+ if (rowNow) { rowNow.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
+ await sleep(400);
+ lpop = vis('.dsh-wt_bindListPop');
+ var item = lpop && lpop.querySelector('.dsh-wt_selectItem');
if (item) { item.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
await sleep(400);
}
@@ -87,6 +101,14 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
out.boundFolderText = vis('.dsh-wt_bindPop .dsh-wt_bindFolder') ? vis('.dsh-wt_bindPop .dsh-wt_bindFolder').textContent : null;
out.chevron = !!vis('.dsh-wt_bindPop .dsh-wt_bindConvChevron');
out.unbindPresent = !!vis('.dsh-wt_bindPop .dsh-wt_bindUnbind');
+ // 解绑按钮在第一行最右(与 💬 绑定对话 同一行右对齐)
+ var ubRow = vis('.dsh-wt_bindPop .dsh-wt_bindUnbind');
+ if (ubRow) {
+ var row1 = boxes[1].querySelector('.dsh-wt_bindFolderRow');
+ var rr = row1.getBoundingClientRect(); var ur = ubRow.getBoundingClientRect();
+ out.unbindInRow1 = row1.contains(ubRow);
+ out.unbindRightAligned = (rr.right - ur.right) < 16;
+ }
var saved = JSON.parse(localStorage.getItem('dsh.worktable.projects.v1'));
out.savedBinding = saved.bindings['t-bind'];
// 解绑 → 恢复未绑定