From 7db58230ad71222234e57f6ef91d21c8371a68f9 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Mon, 28 Sep 2026 16:53:02 +0800 Subject: [PATCH] docs(tasks): site-wide solid button contrast and disabled state (BUG-1079), with contrast harness Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8 --- docs/tasks/README.md | 1 + .../TASK-site-button-contrast-20260928.md | 122 ++++++++++++++++++ docs/testing/button-contrast-harness.cjs | 59 +++++++++ 3 files changed, 182 insertions(+) create mode 100644 docs/tasks/TASK-site-button-contrast-20260928.md create mode 100644 docs/testing/button-contrast-harness.cjs diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 3cbf281f..e22e2428 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -247,6 +247,7 @@ | `TASK-consult-answer-the-question-20260927.md` | `PROGRESS-consult-answer-the-question-20260927.md` | **普通对话回答问的那句话**:反差只写盘上、删「按我的理解答」、禁写动机句;追问轮 ≤ 200 字直接回答不重开四标题骨架(服务端按「本会话已有解读」切指令,不用正则);清单是核对项不是段落大纲;步骤栏「先抓住你真正在问的事」改「先回答你问的这件事」 | 已实现待验收(Claude 子代理直接执行) | 分支 `codex/consult-answer-the-question-20260927`(未推送);基线 `2ce3c216`;BUG-1070~1073;Skill 不 bump;真机清单 `docs/testing/consult-answer-the-question-20260927.md` | | `TASK-consult-first-frame-and-pacing-20260928.md` | `PROGRESS-consult-first-frame-and-pacing-20260928.md` | **普通对话发出即有反馈、正文按打字节奏放出**:客户端分类前静默(BUG-976 副作用)+ 服务端分类后才开流 → 发出后一两秒空白;服务端 160 字截留 + 客户端 settle 一帧全放 → 追问轮正文一下全出。D1 首帧「收到,正在看你的问题…」、D2 先建流、D3 每帧上限 + 限时收尾、D4 160 字阈值不动 | 已验收并部署 staging(真机欠) | 分支 `codex/consult-first-frame-and-pacing-20260928`(未推送);进度 `PROGRESS-consult-first-frame-and-pacing-20260928.md`;BUG-1074 / BUG-1075 | | `TASK-chart-types-and-report-buttons-20260928.md` | `PROGRESS-chart-types-and-report-buttons-20260928.md`、`PROGRESS-ayanamsa-report-buttons-20260928.md` | **星盘盘型扩充 + 表格随盘换 + 七政隐藏 + 岁差 6 项 + 我的报告按钮配色**:分盘表一直显示 D1 数据(BUG-1076);盘型条 + 「星盘类型」面板共 23 种(加 月亮盘 / Bhava / 行运 / D40 / D45 / D60);Bhava 端点缺 MC 静默等宫(BUG-1077);报告深色主按钮黑字深红、禁用半透明(BUG-1078,只改报告范围) | 已验收、已部署 staging `6a4e312c`(真机欠) | `af27709d`…`4189750c`(子代理实现 + Claude 验收补丁);BUG-1076~1078;含迁移 `20260928010000_profile_ayanamsa_six` | +| `TASK-site-button-contrast-20260928.md` | `PROGRESS-site-button-contrast-20260928.md` | **全站实心按钮配色与禁用态统一**:层外 `button { color: inherit }` 压掉 Tailwind 文字色(61 个 ``], + ["Button 默认 · 禁用", ``], + ["Button 描边", ``], + ["Button 描边 · 禁用", ``], + [".button-primary", ``], + [".button-primary · 禁用", ``], + [".danger-primary", ``], + [".danger-primary · 禁用", ``], + [".button-secondary", ``], + ["输入框发送键", `
`], + ["输入框发送键 · 禁用", `
`], + ["报告页 Button 默认(BUG-1078 后)", `
`], + ["报告页 Button 默认 · 禁用", `
`], +]; +function lum([r,g,b]) { const f = c => { c/=255; return c<=0.03928?c/12.92:((c+0.055)/1.055)**2.4; }; return 0.2126*f(r)+0.7152*f(g)+0.0722*f(b); } +function parse(c) { const m = c.match(/[\d.]+/g).map(Number); return { rgb: m.slice(0,3), a: m.length>3?m[3]:1 }; } +function over(fg, bg, a) { return fg.map((v,i)=>v*a+bg[i]*(1-a)); } +function ratio(a,b){ const [x,y]=[lum(a),lum(b)].sort((p,q)=>q-p); return (x+0.05)/(y+0.05); } +const hex = c => "#" + c.map(v=>Math.round(v).toString(16).padStart(2,"0")).join(""); +(async () => { + const browser = await chromium.launch({ executablePath: process.env.CHROME || "/usr/bin/google-chrome", args: ["--no-sandbox"] }); + const page = await browser.newPage(); + const rows = []; + for (const theme of ["light", "dark"]) { + const html = `${cssFiles.map(f=>``).join("")}${samples.map(([n,h],i)=>`
${h}
`).join("")}`; + fs.writeFileSync(path.join(dir, `h-${theme}.html`), html); + await page.goto("file://" + path.join(dir, `h-${theme}.html`)); + for (let i=0;i { const b = document.querySelector(`#s${i} button`); const s = getComputedStyle(b); + const bodyBg = getComputedStyle(document.body).backgroundColor; return { color: s.color, bg: s.backgroundColor, op: s.opacity, bodyBg }; }, i); + const page0 = parse(r.bodyBg).rgb; const bgc = parse(r.bg); const fgc = parse(r.color); const op = Number(r.op); + const bgSolid = over(bgc.rgb, page0, bgc.a); const fgSolid = over(fgc.rgb, bgSolid, fgc.a); + const bgFinal = over(bgSolid, page0, op), fgFinal = over(fgSolid, page0, op); + rows.push({ theme, name: samples[i][0], text: hex(fgFinal), bg: hex(bgFinal), opacity: op, contrast: ratio(fgFinal,bgFinal).toFixed(2) }); + } + } + await browser.close(); + console.table(rows); + fs.writeFileSync(path.join(dir,"contrast.json"), JSON.stringify(rows,null,1)); +})();