dsh-theme-palette 1.13.2 → 1.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README-es.md +1 -1
- package/README-hi.md +1 -1
- package/README-ja.md +1 -1
- package/README-pt.md +1 -1
- package/README-zh.md +1 -1
- package/README.md +1 -1
- package/assets/screenshot-settings-custom.png +0 -0
- package/assets/screenshot-settings-dark.png +0 -0
- package/assets/screenshot-settings-hc.png +0 -0
- package/assets/screenshot-settings-light.png +0 -0
- package/assets/screenshots.meta.json +13 -13
- package/client.js +129 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,43 @@
|
|
|
8
8
|
> 1.13.2 起逐节标注 —— 此前 27 个版本节看起来都能装,用户按 CHANGELOG 钉版本会撞 404
|
|
9
9
|
> (2026-10-29 审计 P2-9)。
|
|
10
10
|
|
|
11
|
+
### 1.13.4
|
|
12
|
+
用户第二次回执:同一张悬停卡「还是深灰底色」。这次**明暗两套截图对比**把 1.13.3 的方向证伪了 ——
|
|
13
|
+
浅色模式下(画布 `#f8fcf6`)卡片仍是 `#2c2c2e` + 白字,颜色一个像素都没变:
|
|
14
|
+
它根本不读调色板,所以改多少条 token 都碰不到。
|
|
15
|
+
|
|
16
|
+
逐文件扫宿主 asar 后定位到根因:**`dsh-web-frontend` 把悬停卡底色写死在卡片元素上** ——
|
|
17
|
+
`._card_38jqx_9{--dsw-hovercard-bg:#2C2C2E;background:var(--dsw-hovercard-bg)}`。
|
|
18
|
+
这是全站唯一的大写手写 hex:既不读色阶、也不读别名,与主题完全无关(连浅色模式也是深灰)。
|
|
19
|
+
|
|
20
|
+
- **修法**:`buildTokens` 新增专用 token `--dsh-tp-hovercard-bg`(明暗两档都取色阶 **850 的暗面**),
|
|
21
|
+
并注入第三条样式 `dsh-theme-palette/host-patch.css`:
|
|
22
|
+
`*{--dsw-hovercard-bg:var(--dsh-tp-hovercard-bg,#2c2c2e)!important}`。
|
|
23
|
+
宿主的声明在卡片元素**自身**,普通声明压不过它,必须 `!important`;只改这一个自定义属性,
|
|
24
|
+
其它元素即使命中也没有副作用。卡片保持**暗底白字**(对比度不变),但从此带上配色色相。
|
|
25
|
+
黑白档没有色阶可接,回落到宿主原色(行为不变)。
|
|
26
|
+
- **断言**:`check-audit` 第 28 组 —— 明暗同值 / = 850 暗面 / 补丁样式的形态 / 黑白档不产出。
|
|
27
|
+
- 复核:`npm run check` 8/8;两档报表 exit 0。
|
|
28
|
+
|
|
29
|
+
### 1.13.3
|
|
30
|
+
用户实测反馈:**左侧会话行的悬停卡(会话标题 / 时间 / 状态)底色不跟随主题色** —— 卡片背景停在
|
|
31
|
+
`#2c2c2e`、标题近白,而旁边的侧栏与画布都是染过色的。
|
|
32
|
+
|
|
33
|
+
核实(像素取样 + 宿主构建对账):卡片背景正好是宿主 **原始**色阶 `--dsw-static-neutral-bluish-850`
|
|
34
|
+
(`#2c2c2e`)、标题是原始 `50`(`#f9fafb`);而宿主把这些表面别名声明成
|
|
35
|
+
`var(--dsw-static-neutral-bluish-NN)` 的**引用**,插件过去只覆盖色阶、指望浏览器在 `body` 上完成替换 ——
|
|
36
|
+
这条链在浮层里没有生效,于是卡片拿到了宿主原色。
|
|
37
|
+
|
|
38
|
+
- **修法**:把宿主里**全部 47 个**「纯粹是色阶引用」的别名(`bg-base` / `bg-layer-1..3` / `tooltip-bg` /
|
|
39
|
+
`label-primary` / `toast-bg` / `switch-thumb` / `specific-tip` / `specific-input-major` …)在覆盖层里
|
|
40
|
+
**直接写成色阶值**,不再依赖任何中间引用。已经由求解器给值的键(`label-secondary` / `label-tertiary` /
|
|
41
|
+
`link` / `brand` / `bubble` / `sidebar-fill` / `markdown-code-block` 等)一律跳过,保持求解结果。
|
|
42
|
+
能正常替换的地方结果完全一致(同一档),链不生效的地方就是修复。
|
|
43
|
+
- **防回退**:`check-audit` 新增第 27 组 —— 每个别名都必须在覆盖表里、且值等于它声明的色阶档;
|
|
44
|
+
`check-host-contract` 改为从**宿主真实构建**里解出这 47 条映射并与插件对表(宿主改映射会红,不会静默错色)。
|
|
45
|
+
- 覆盖的 token 数从 122 增至 **158**(黑白档 17 → 19),六语 README 同步。
|
|
46
|
+
- 复核:`npm run check` 8/8;两档报表 exit 0;`npm pack` 28 文件。
|
|
47
|
+
|
|
11
48
|
### 1.13.2
|
|
12
49
|
对 2026-10-29 全量审计(**34 条**,报告与反哺回执在仓库根目录的 `AUDIT-2026-10-29.md` /
|
|
13
50
|
`AUDIT-2026-10-29-FEEDBACK.md`)的修订。审计的核心判断成立:**引擎正确,缺的是"防回归"的工程能力** ——
|
package/README-es.md
CHANGED
|
@@ -28,7 +28,7 @@ El plugin solo apila tokens de color mediante `ctx.theme.overrideTokens`; no reg
|
|
|
28
28
|
|
|
29
29
|
- **4 preajustadas + personalizada** — Mono, Arena cálida, Índigo, Musgo (cada una adaptada de forma independiente a claro y oscuro), más una paleta personalizada derivada de tres colores;
|
|
30
30
|
- la escala se **recalcula** completa: reconstrucción OKLCH → croma por rol → **ajuste al gamut sRGB** → contraste resuelto sobre superficies reales;
|
|
31
|
-
- se cubren todos los tokens de color del host (
|
|
31
|
+
- se cubren todos los tokens de color del host (158 tokens en paletas con tinte, 19 en mono; 1080 combinaciones de ajuste escaneadas): texto, secundario, terciario, notas, enlaces, barras laterales, tarjetas, burbuja del usuario, botón primario, barras de desplazamiento, interruptores, títulos/negritas de Markdown, bloques de código;
|
|
32
32
|
- ajustable: intensidad del texto (3), profundidad de la barra lateral (3), énfasis de Markdown, barras de desplazamiento, color de interruptores;
|
|
33
33
|
- **paleta personalizada** (elige superficie / texto / acento — el motor mantiene sus garantías de contraste), **exportación/importación de configuración** con un código `dshs1.`, **modo de alto contraste** y **4 idiomas de interfaz**;
|
|
34
34
|
- **autorreparable**: si el host descarta la capa de override, la paleta se vuelve a aplicar; tras fallos repetidos la autorreparación se pausa y la página de ajustes ofrece un botón para reactivarla;
|
package/README-hi.md
CHANGED
|
@@ -28,7 +28,7 @@ DeepSeek Harness (वेब और डेस्कटॉप) के लिए
|
|
|
28
28
|
|
|
29
29
|
- **4 प्रीसेट + कस्टम** — मोनो, वार्म सैंड, इंडिगो, मॉस (हर एक लाइट और डार्क दोनों के लिए अलग से अनुकूलित), साथ ही तीन रंगों से निकली कस्टम पैलेट;
|
|
30
30
|
- पूरी रैंप **दोबारा गणना** होती है, बदली नहीं जाती: OKLCH पुनर्निर्माण → भूमिका-आधारित क्रोमा → **sRGB गैमट क्लैंप** → वास्तविक सतहों पर कंट्रास्ट हल;
|
|
31
|
-
- होस्ट के सभी रंग टोकन शामिल (रंगीन पैलेट में
|
|
31
|
+
- होस्ट के सभी रंग टोकन शामिल (रंगीन पैलेट में 158 टोकन, मोनो में 19; 1080 सेटिंग संयोजन पूरी तरह स्कैन किए गए): मुख्य टेक्स्ट, द्वितीयक, तृतीयक, कैप्शन, लिंक, साइडबार, कार्ड, उपयोगकर्ता बबल, प्राइमरी बटन, स्क्रॉलबार, स्विच, Markdown शीर्षक/बोल्ड, कोड ब्लॉक;
|
|
32
32
|
- समायोज्य: टेक्स्ट की तीव्रता (3), साइडबार की गहराई (3), Markdown ज़ोर, स्क्रॉलबार, स्विच का रंग;
|
|
33
33
|
- **कस्टम पैलेट** (सतह / टेक्स्ट / एक्सेंट चुनें — इंजन अपने कंट्रास्ट वादे बनाए रखता है), `dshs1.` कोड से **कॉन्फ़िगरेशन निर्यात/आयात**, **हाई-कॉन्ट्रास्ट** मोड, और **4 UI भाषाएँ**;
|
|
34
34
|
- **स्व-उपचार**: यदि होस्ट ओवरराइड परत हटा दे, पैलेट फिर से लगा दी जाती है; बार-बार विफलता पर स्व-उपचार रुक जाता है और सेटिंग्स पेज पर इसे दोबारा चालू करने का बटन मिलता है;
|
package/README-ja.md
CHANGED
|
@@ -28,7 +28,7 @@ package.json の `engines` は `^22.19.0 || >=24.0.0` —— 上の表と同じ
|
|
|
28
28
|
|
|
29
29
|
- **4 プリセット + カスタム** —— モノクロ / ウォームサンド / インディゴ / モスグリーンがライトとダークをそれぞれ独立に適応し、さらに 3 色から派生するカスタム配色;
|
|
30
30
|
- 色階は置き換えではなく**全体を再計算**:OKLCH 再構築 → 役割ごとの彩度 → **sRGB ガマット・クランプ** → 実際の面でコントラストを解く;
|
|
31
|
-
- ホストの全色トークンを網羅(着色パレットで
|
|
31
|
+
- ホストの全色トークンを網羅(着色パレットで 158、モノクロで 19。1080 通りの設定を全走査):本文、二次、三次、注記、リンク、サイドバー、カード、ユーザー吹き出し、プライマリボタン、スクロールバー、スイッチ、Markdown 見出し/太字、コードブロック;
|
|
32
32
|
- 調整可:テキストの着色 3 段、サイドバー 3 段、Markdown 強調、スクロールバー、スイッチの配色;
|
|
33
33
|
- **カスタム配色**(背景 / テキスト / アクセントの 3 色。極端に明るい・暗いアクセントは正規化されます)、**設定のエクスポート/インポート**(`dshs1.` ショートコードに 3 色を含む)、**ハイコントラスト**、UI 4 言語;
|
|
34
34
|
- **自己修復**:ホストがオーバーライド層を破棄すると自動で再適用。連続失敗すると自動再適用を停止し、設定ページに「再有効化」の入口を出します;
|
package/README-pt.md
CHANGED
|
@@ -28,7 +28,7 @@ O plugin apenas empilha tokens de cor via `ctx.theme.overrideTokens`; não regis
|
|
|
28
28
|
|
|
29
29
|
- **4 predefinidas + personalizada** — Mono, Areia quente, Índigo, Musgo (cada uma adaptada de forma independente ao claro e ao escuro), mais uma paleta personalizada derivada de três cores;
|
|
30
30
|
- a escala é **recalculada** por completo: reconstrução OKLCH → croma por papel → **limite de gamut sRGB** → contraste resolvido sobre superfícies reais;
|
|
31
|
-
- todos os tokens de cor do host são cobertos (
|
|
31
|
+
- todos os tokens de cor do host são cobertos (158 tokens nas paletas com tinta, 19 na mono; 1080 combinações de ajuste escaneadas): texto, secundário, terciário, legendas, links, barras laterais, cartões, balão do usuário, botão primário, barras de rolagem, interruptores, títulos/negrito de Markdown, blocos de código;
|
|
32
32
|
- ajustável: intensidade do texto (3), profundidade da barra lateral (3), ênfase de Markdown, barras de rolagem, cor dos interruptores;
|
|
33
33
|
- **paleta personalizada** (escolha superfície / texto / acento — o motor mantém as garantias de contraste), **exportação/importação de configuração** por um código `dshs1.`, **modo de alto contraste** e **4 idiomas de interface**;
|
|
34
34
|
- **autorrecuperação**: se o host descartar a camada de override, a paleta é reaplicada; após falhas repetidas a autorrecuperação pausa e a página de ajustes oferece um botão para reativá-la;
|
package/README-zh.md
CHANGED
|
@@ -28,7 +28,7 @@ package.json 的 `engines` 字段写的是 `^22.19.0 || >=24.0.0`——与上表
|
|
|
28
28
|
|
|
29
29
|
- **4 套预设 + 自定义** —— 黑白 / 暖砂 / 靛蓝 / 苔绿各自独立适配明暗两侧,另加由三色派生的自定义配色;
|
|
30
30
|
- 色阶**整体重算**而不是替换:OKLCH 重建 → 角色化色度 → **sRGB 色域钳位** → 在真实承载面上求解对比度;
|
|
31
|
-
- 覆盖宿主全部颜色 token(自定义/染色档
|
|
31
|
+
- 覆盖宿主全部颜色 token(自定义/染色档 158 个、黑白档 19 个;1080 组设置全扫描):正文、次级、三级、注释、链接、侧栏、卡片、主人气泡、主按钮、滚动条、开关、Markdown 标题/加粗、代码块;
|
|
32
32
|
- 可调:文字着色三档、侧栏三档、Markdown 强调、滚动条、开关配色;
|
|
33
33
|
- **自定义配色**(给 底色/文字/强调 三色,文字色相也参与派生;过亮/过暗的强调色会归一化)、**配置导入导出**(`dshs1.` 短码含三色)、**高对比**档、4 种界面语言;
|
|
34
34
|
- **自愈**:宿主丢弃 override 层时自动重放;自动重放连续失败后会停用,并在设置页给出「重新启用」入口;
|
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ The plugin only stacks colour tokens through `ctx.theme.overrideTokens`; it does
|
|
|
28
28
|
|
|
29
29
|
- **4 presets + custom** — Mono, Warm sand, Indigo, Moss (each adapting to light *and* dark independently), plus a custom palette derived from three colours;
|
|
30
30
|
- the whole ramp is **recomputed**, not swapped: OKLCH rebuild → role-based chroma → **sRGB gamut clamp** → contrast solved on real surfaces;
|
|
31
|
-
- every host colour token is covered (
|
|
31
|
+
- every host colour token is covered (158 tokens for tinted palettes, 19 for mono; 1080 setting combinations fully scanned): body, secondary, tertiary, captions, links, sidebars, cards, user bubble, primary button, scrollbars, switches, Markdown headings/bold, code blocks;
|
|
32
32
|
- adjustable: text tint (3), sidebar depth (3), Markdown emphasis, scrollbars, switch colour;
|
|
33
33
|
- **custom palette** (pick surface / text / accent — the engine keeps its contrast guarantees), **config export/import** via a `dshs1.` code, **high-contrast** mode, and 4 UI languages;
|
|
34
34
|
- **self-healing**: if the host drops the override layer, the palette is re-applied; after repeated failures auto-restore pauses and the settings page offers a re-enable button;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-10-
|
|
3
|
-
"pluginVersion": "1.13.
|
|
2
|
+
"generatedAt": "2026-10-29T11:56:54.301Z",
|
|
3
|
+
"pluginVersion": "1.13.4",
|
|
4
4
|
"chrome": "Chrome/156.0.8078.49",
|
|
5
5
|
"width": 620,
|
|
6
6
|
"scale": 1,
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
"--adv",
|
|
15
15
|
"0"
|
|
16
16
|
],
|
|
17
|
-
"htmlSha256": "
|
|
17
|
+
"htmlSha256": "54916add6cedff817044eaf0eee2297265f8ff5b2fb336d3e201dad504bf2b35",
|
|
18
18
|
"cssWidth": 620,
|
|
19
19
|
"cssHeight": 888,
|
|
20
20
|
"width": 620,
|
|
21
21
|
"height": 888,
|
|
22
|
-
"bytes":
|
|
23
|
-
"sha256": "
|
|
22
|
+
"bytes": 47498,
|
|
23
|
+
"sha256": "d5fc7fe7a3a5012fc0e3947038e6faf69e3df23b5897d346fc3381da655b0fa0"
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
"file": "assets/screenshot-settings-dark.png",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"--adv",
|
|
32
32
|
"0"
|
|
33
33
|
],
|
|
34
|
-
"htmlSha256": "
|
|
34
|
+
"htmlSha256": "0348f7373871e7d430cf07615cfcd481476bc62478c0a57ba7918e6611b6dd98",
|
|
35
35
|
"cssWidth": 620,
|
|
36
36
|
"cssHeight": 888,
|
|
37
37
|
"width": 620,
|
|
38
38
|
"height": 888,
|
|
39
39
|
"bytes": 47810,
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "ba07e44099f33978f5f7d62563b96e999f240aed4971e0657a145aa5188a452b"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"file": "assets/screenshot-settings-custom.png",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"--out",
|
|
51
51
|
"customadv"
|
|
52
52
|
],
|
|
53
|
-
"htmlSha256": "
|
|
53
|
+
"htmlSha256": "5929bc3227c1c53bd6264bb9f3be23557b481a77271e204e77676ac526edc530",
|
|
54
54
|
"cssWidth": 620,
|
|
55
55
|
"cssHeight": 1753,
|
|
56
56
|
"width": 620,
|
|
57
57
|
"height": 1753,
|
|
58
|
-
"bytes":
|
|
59
|
-
"sha256": "
|
|
58
|
+
"bytes": 116566,
|
|
59
|
+
"sha256": "b7853a193d0be58f3284c363f379cc66fa9f490b83a49fd5abd6780cc70fa728"
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"file": "assets/screenshot-settings-hc.png",
|
|
@@ -69,13 +69,13 @@
|
|
|
69
69
|
"--out",
|
|
70
70
|
"hcadv"
|
|
71
71
|
],
|
|
72
|
-
"htmlSha256": "
|
|
72
|
+
"htmlSha256": "5b68173af9cf81d3586c1ed4a206475427a7f266174420da1df22f1f1d84277d",
|
|
73
73
|
"cssWidth": 620,
|
|
74
74
|
"cssHeight": 1463,
|
|
75
75
|
"width": 620,
|
|
76
76
|
"height": 1463,
|
|
77
|
-
"bytes":
|
|
78
|
-
"sha256": "
|
|
77
|
+
"bytes": 94792,
|
|
78
|
+
"sha256": "e021a907dd32378591b0e5198027bd4ba2d19da112ccf3e4bf6fbb1929796c0e"
|
|
79
79
|
}
|
|
80
80
|
]
|
|
81
81
|
}
|
package/client.js
CHANGED
|
@@ -27,7 +27,7 @@ window.__ModuleLoader__.load({
|
|
|
27
27
|
const React = require('react')
|
|
28
28
|
const h = React.createElement
|
|
29
29
|
|
|
30
|
-
const PLUGIN_VERSION = '1.13.
|
|
30
|
+
const PLUGIN_VERSION = '1.13.4'
|
|
31
31
|
const STORE_KEY = 'dsh-theme-palette.v1'
|
|
32
32
|
const OVERRIDE_SOURCE = 'dsh-theme-palette'
|
|
33
33
|
|
|
@@ -1492,6 +1492,68 @@ window.__ModuleLoader__.load({
|
|
|
1492
1492
|
// (低于自己声明的 0.006),而上面的注释还宣称"整条色阶单调"。
|
|
1493
1493
|
const RAMP_ORDER = ['00', '50', '60', '75', '100', '150', '200', '300', '400', '500', '600', '700', '750', '800', '850', '875', '900', '950', '1000']
|
|
1494
1494
|
|
|
1495
|
+
/**
|
|
1496
|
+
* 宿主里所有「只是 `var(--dsw-static-neutral-bluish-NN)` 引用」的别名 → 色阶档位。
|
|
1497
|
+
*
|
|
1498
|
+
* 为什么要在插件侧再落一遍(2026-10-29,用户实测:左侧会话行的悬停卡不跟随主题色):
|
|
1499
|
+
* 插件过去只覆盖色阶,指望浏览器在 `body` 上把这些引用替换掉。实测那张卡拿到的仍是
|
|
1500
|
+
* **宿主原始色阶**(背景 #2c2c2e = 宿主 850,标题近白 = 宿主 50),说明这条链在浮层里不生效。
|
|
1501
|
+
* 这里把 47 个别名**直接写成色阶值**,不再依赖中间引用 —— 链正常时结果完全一致(同一档),
|
|
1502
|
+
* 链不生效时就是修复。表由宿主构建逐条导出,`tools/check-host-contract.mjs` 会核对映射没漂。
|
|
1503
|
+
*
|
|
1504
|
+
* 只补**插件没有专门求解过**的键:label-secondary / tertiary / link / brand / bubble /
|
|
1505
|
+
* markdown-code-block / sidebar-fill 等由求解器给值,循环里遇到已存在的一律跳过。
|
|
1506
|
+
*/
|
|
1507
|
+
const SURFACE_ALIAS_STEPS = {
|
|
1508
|
+
'--dsw-alias-bg-base': { light: '00', dark: '950' },
|
|
1509
|
+
'--dsw-alias-bg-document-preview': { light: '100', dark: '950' },
|
|
1510
|
+
'--dsw-alias-bg-layer-1': { light: '00', dark: '875' },
|
|
1511
|
+
'--dsw-alias-bg-layer-2': { light: '00', dark: '850' },
|
|
1512
|
+
'--dsw-alias-bg-layer-3': { light: '00', dark: '800' },
|
|
1513
|
+
'--dsw-alias-bg-module-platform': { light: '60', dark: '800' },
|
|
1514
|
+
'--dsw-alias-bg-overlay': { light: '150', dark: '700' },
|
|
1515
|
+
'--dsw-alias-brand-primary': { light: '1000', dark: '50' },
|
|
1516
|
+
'--dsw-alias-brand-primary-invert': { light: '1000', dark: '50' },
|
|
1517
|
+
'--dsw-alias-brand-text': { light: '1000', dark: '50' },
|
|
1518
|
+
'--dsw-alias-button-contrast-fill': { light: '700', dark: '50' },
|
|
1519
|
+
'--dsw-alias-button-elevated-fill': { light: '00', dark: '750' },
|
|
1520
|
+
'--dsw-alias-button-floating-fill': { light: '00', dark: '850' },
|
|
1521
|
+
'--dsw-alias-button-floating-hover': { light: '75', dark: '800' },
|
|
1522
|
+
'--dsw-alias-button-ghost-active-border': { light: '500', dark: '600' },
|
|
1523
|
+
'--dsw-alias-button-ghost-active-fill': { light: '100', dark: '750' },
|
|
1524
|
+
'--dsw-alias-button-ghost-active-hover': { light: '150', dark: '700' },
|
|
1525
|
+
'--dsw-alias-button-primary-dimmed': { light: '100', dark: '750' },
|
|
1526
|
+
'--dsw-alias-button-primary-hover': { light: '750', dark: '100' },
|
|
1527
|
+
'--dsw-alias-interactive-bg-hover-solid': { light: '75', dark: '800' },
|
|
1528
|
+
'--dsw-alias-label-caption': { light: '400', dark: '600' },
|
|
1529
|
+
'--dsw-alias-label-dimmed': { light: '200', dark: '750' },
|
|
1530
|
+
'--dsw-alias-label-document-preview': { light: '700', dark: '300' },
|
|
1531
|
+
'--dsw-alias-label-primary': { light: '1000', dark: '50' },
|
|
1532
|
+
'--dsw-alias-label-primary-dimmed': { light: '950', dark: '100' },
|
|
1533
|
+
'--dsw-alias-label-primary-foreground': { light: '00', dark: '1000' },
|
|
1534
|
+
'--dsw-alias-label-primary-inverted': { light: '00', dark: '800' },
|
|
1535
|
+
'--dsw-alias-label-secondary': { light: '700', dark: '300' },
|
|
1536
|
+
'--dsw-alias-label-tertiary': { light: '600', dark: '400' },
|
|
1537
|
+
'--dsw-alias-markdown-citation': { light: '100', dark: '800' },
|
|
1538
|
+
'--dsw-alias-markdown-code-block': { light: '50', dark: '900' },
|
|
1539
|
+
'--dsw-alias-markdown-code-block-banner': { light: '50', dark: '850' },
|
|
1540
|
+
'--dsw-alias-markdown-code-segment-selected': { light: '00', dark: '800' },
|
|
1541
|
+
'--dsw-alias-markdown-code-segment-unselected': { light: '75', dark: '900' },
|
|
1542
|
+
'--dsw-alias-markdown-placeholder': { light: '60', dark: '850' },
|
|
1543
|
+
'--dsw-alias-markdown-tag': { light: '75', dark: '850' },
|
|
1544
|
+
'--dsw-alias-switch-thumb': { light: '00', dark: '400' },
|
|
1545
|
+
'--dsw-alias-toast-bg': { light: '800', dark: '750' },
|
|
1546
|
+
'--dsw-alias-toast-label': { light: '00', dark: '00' },
|
|
1547
|
+
'--dsw-alias-tooltip-bg': { light: '850', dark: '750' },
|
|
1548
|
+
'--dsw-specific-input-major': { light: '00', dark: '850' },
|
|
1549
|
+
'--dsw-specific-login-input': { light: '50', dark: '900' },
|
|
1550
|
+
'--dsw-specific-selector': { light: '60', dark: '800' },
|
|
1551
|
+
'--dsw-specific-sidebar-fill': { light: '50', dark: '900' },
|
|
1552
|
+
'--dsw-specific-sidebar-nav-item-active': { light: '100', dark: '750' },
|
|
1553
|
+
'--dsw-specific-sidebar-nav-item-hover': { light: '75', dark: '850' },
|
|
1554
|
+
'--dsw-specific-tip': { light: '60', dark: '800' },
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1495
1557
|
/**
|
|
1496
1558
|
* 把色阶压回「序号越大越深」。**没有返回值**(审计 2026-10-29 P3-6):
|
|
1497
1559
|
* 原来返回一个 `changed` 布尔,但唯一调用点丢弃它 —— 看起来像是打算用来触发重解或提示,
|
|
@@ -1860,6 +1922,26 @@ window.__ModuleLoader__.load({
|
|
|
1860
1922
|
// 色阶排序归一化(审计 3.2):放在最后 —— 前面的求解与参考墨色对齐都可能把某一档
|
|
1861
1923
|
// 推出反序,收尾统一压一次,保证「序号越大越深」在整条色阶上成立。
|
|
1862
1924
|
if (params.tinted) enforceRampOrder(pairs)
|
|
1925
|
+
// 表面别名**显式落地**(2026-10-29 用户实测:左侧会话行的悬停卡没跟随主题色)。
|
|
1926
|
+
//
|
|
1927
|
+
// 宿主在 `body` / `body[data-ds-dark-theme]` 上把这一批别名写成
|
|
1928
|
+
// `var(--dsw-static-neutral-bluish-NN)` 的**引用**;插件过去只覆盖色阶,指望浏览器
|
|
1929
|
+
// 在 body 上完成 var 替换。实测那张悬停卡拿到的仍是宿主原始色阶值(#2c2c2e =
|
|
1930
|
+
// 宿主 850),说明这条链在某些浮层里不生效。这里把别名**直接写成色阶值**,
|
|
1931
|
+
// 不再依赖任何中间引用 —— 对能正常替换的地方结果完全一致(同一档),对不生效的地方是修复。
|
|
1932
|
+
// 已由求解器给值的键(label-secondary / link / brand / bubble / sidebar-fill …)一律保留,不覆盖。
|
|
1933
|
+
for (const [name, steps] of Object.entries(SURFACE_ALIAS_STEPS)) {
|
|
1934
|
+
if (pairs[name]) continue
|
|
1935
|
+
const light = pairs['--dsw-static-neutral-bluish-' + steps.light]
|
|
1936
|
+
const dark = pairs['--dsw-static-neutral-bluish-' + steps.dark]
|
|
1937
|
+
if (light && dark) pairs[name] = { light: light.light, dark: dark.dark }
|
|
1938
|
+
}
|
|
1939
|
+
// 宿主悬停卡的专用底色(配合 HOST_PATCH_CSS):宿主把卡片底色写死成 #2C2C2E,
|
|
1940
|
+
// 这里给一个**两档都取暗面**的 token —— 卡片始终是暗底白字(对比度不变),但带上配色色相。
|
|
1941
|
+
if (pairs['--dsw-static-neutral-bluish-850']) {
|
|
1942
|
+
const hoverBg = pairs['--dsw-static-neutral-bluish-850'].dark
|
|
1943
|
+
pairs['--dsh-tp-hovercard-bg'] = { light: hoverBg, dark: hoverBg }
|
|
1944
|
+
}
|
|
1863
1945
|
// 覆盖层标记(自愈判据用):宿主撤销这一层时它会一起消失。
|
|
1864
1946
|
pairs[LAYER_MARK] = { light: '1', dark: '1' }
|
|
1865
1947
|
return pairs
|
|
@@ -1920,7 +2002,25 @@ return pairs
|
|
|
1920
2002
|
'[class*="_markdown_"] :not(pre) > code{background:var(--dshtp-code-inline,inherit)}',
|
|
1921
2003
|
].join('')
|
|
1922
2004
|
|
|
1923
|
-
/* =================
|
|
2005
|
+
/* ================= 宿主补丁样式(head 里第三条 CSS) =================
|
|
2006
|
+
*
|
|
2007
|
+
* 为什么需要它(2026-10-29 用户实测,第二轮回执):
|
|
2008
|
+
* 宿主的「悬停卡」(hover card,会话行悬停时弹出的小卡)把底色**写死在卡片元素上**:
|
|
2009
|
+
* dsh-web-frontend 的 `._card_38jqx_9{--dsw-hovercard-bg:#2C2C2E;background:var(--dsw-hovercard-bg)}`。
|
|
2010
|
+
* 这是一个**手写字面量**(全站唯一的大写 hex),既不读色阶也不读别名 ——
|
|
2011
|
+
* 所以浅色模式下它也是深灰、明暗两套主题下颜色一模一样。改多少条 token 都碰不到它。
|
|
2012
|
+
*
|
|
2013
|
+
* 修法:给一个**专用 token**(`--dsh-tp-hovercard-bg`,见 buildTokens:两档都取色阶 850 的暗色值),
|
|
2014
|
+
* 再用 `*` + `!important` 把它接到宿主的 `--dsw-hovercard-bg` 上 —— 宿主的声明在卡片元素自身,
|
|
2015
|
+
* 普通声明压不过它,必须 important。白字保持不变(暗底白字,对比度不受影响),
|
|
2016
|
+
* 卡片从此带上配色的色相,而不是一块中性的深灰。
|
|
2017
|
+
*/
|
|
2018
|
+
const HOST_PATCH_STYLE_ID = 'dsh-theme-palette/host-patch.css'
|
|
2019
|
+
const HOST_PATCH_CSS = `
|
|
2020
|
+
/* 宿主悬停卡:--dsw-hovercard-bg 是宿主写死的 #2C2C2E;这里接回配色的暗面(见 buildTokens 的 --dsh-tp-hovercard-bg) */
|
|
2021
|
+
*{--dsw-hovercard-bg:var(--dsh-tp-hovercard-bg,#2c2c2e)!important}
|
|
2022
|
+
`
|
|
2023
|
+
/* ================= 设置页样式(head 里第四条 CSS) ================= */
|
|
1924
2024
|
const SETTINGS_STYLE_ID = 'dsh-theme-palette/settings.css'
|
|
1925
2025
|
const SETTINGS_CSS = `
|
|
1926
2026
|
.dsh-tp{display:flex;flex-direction:column;gap:14px;width:100%;color:var(--dsw-alias-label-primary);box-sizing:border-box}
|
|
@@ -2051,8 +2151,7 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
2051
2151
|
}
|
|
2052
2152
|
}
|
|
2053
2153
|
|
|
2054
|
-
function installSettingsStyle() {
|
|
2055
|
-
try {
|
|
2154
|
+
function installSettingsStyle() { try {
|
|
2056
2155
|
if (typeof document === 'undefined' || !document.head) return () => {}
|
|
2057
2156
|
let tag = document.querySelector('style[data-plugin-css="' + SETTINGS_STYLE_ID + '"]')
|
|
2058
2157
|
if (!tag) {
|
|
@@ -2070,6 +2169,25 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
2070
2169
|
}
|
|
2071
2170
|
}
|
|
2072
2171
|
|
|
2172
|
+
/** 宿主补丁(悬停卡写死的底色)——与另外两条样式同构:覆盖写 + 卸载移除。 */
|
|
2173
|
+
function installHostPatchStyle() {
|
|
2174
|
+
try {
|
|
2175
|
+
if (typeof document === 'undefined' || !document.head) return () => {}
|
|
2176
|
+
let tag = document.querySelector('style[data-plugin-css="' + HOST_PATCH_STYLE_ID + '"]')
|
|
2177
|
+
if (!tag) {
|
|
2178
|
+
tag = document.createElement('style')
|
|
2179
|
+
tag.dataset.plugin = 'dsh-theme-palette'
|
|
2180
|
+
tag.dataset.pluginCss = HOST_PATCH_STYLE_ID
|
|
2181
|
+
document.head.appendChild(tag)
|
|
2182
|
+
}
|
|
2183
|
+
tag.textContent = HOST_PATCH_CSS
|
|
2184
|
+
return () => { if (tag.parentNode) tag.remove() }
|
|
2185
|
+
} catch (err) {
|
|
2186
|
+
console.warn('[dsh-theme-palette] 宿主补丁样式注入失败:', err)
|
|
2187
|
+
return () => {}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2073
2191
|
/* ================= 运行时自检 ================= */
|
|
2074
2192
|
/**
|
|
2075
2193
|
* 宿主若改了 token 名,插件会**静默失效**(overrideTokens 照收,样式不生效)。
|
|
@@ -2379,7 +2497,7 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
2379
2497
|
derive: '由主色派生',
|
|
2380
2498
|
deriveHint: '用当前强调色的色相与色度推导底色与文字(明暗跟随当前模式)',
|
|
2381
2499
|
deriveNote: '「由主色派生」以强调色为唯一输入,自动算出底色与文字 —— 会覆盖你手动设置的底色与文字;派生之后仍可逐项手改。',
|
|
2382
|
-
notice: '1.13.
|
|
2500
|
+
notice: '1.13.4:悬停卡底色不再被宿主写死成中性深灰 —— 接到配色的暗面,白字与对比度不变。',
|
|
2383
2501
|
dismiss: '知道了',
|
|
2384
2502
|
explainClamp: '强调色已归一化:{from} → {to}(保证按钮与勾选可读)',
|
|
2385
2503
|
explainLink: '链接已为可读性压暗:{ratio}:1(目标 {target}:1)',
|
|
@@ -2452,7 +2570,7 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
2452
2570
|
derive: '由主色派生',
|
|
2453
2571
|
deriveHint: '用目前強調色的色相與彩度推導底色與文字(明暗跟隨目前模式)',
|
|
2454
2572
|
deriveNote: '「由主色派生」以強調色為唯一輸入,自動算出底色與文字 —— 會覆蓋你手動設置的底色與文字;派生之後仍可逐項手改。',
|
|
2455
|
-
notice: '1.13.
|
|
2573
|
+
notice: '1.13.4:懸停卡底色不再被宿主寫死成中性深灰 —— 接到配色的暗面,白字與對比度不變。',
|
|
2456
2574
|
dismiss: '知道了',
|
|
2457
2575
|
explainClamp: '強調色已正規化:{from} → {to}(確保按鈕與勾選可讀)',
|
|
2458
2576
|
explainLink: '連結已為可讀性壓暗:{ratio}:1(目標 {target}:1)',
|
|
@@ -2525,7 +2643,7 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
2525
2643
|
derive: 'Derive from accent',
|
|
2526
2644
|
deriveHint: 'Derive background and text from the current accent hue and chroma (follows the current light/dark mode)',
|
|
2527
2645
|
deriveNote: '"Derive from accent" takes the accent as its only input and computes background and text from it — this overwrites the background and text you set by hand; you can still edit each of them afterwards.',
|
|
2528
|
-
notice: '1.13.
|
|
2646
|
+
notice: '1.13.4: the hover card background is no longer the hardcoded neutral dark from the host — it now follows the palette dark surface, keeping white text and contrast.',
|
|
2529
2647
|
dismiss: 'Got it',
|
|
2530
2648
|
explainClamp: 'Accent normalised: {from} → {to} (keeps buttons and checks readable)',
|
|
2531
2649
|
explainLink: 'Link darkened for readability: {ratio}:1 (target {target}:1)',
|
|
@@ -2598,7 +2716,7 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
2598
2716
|
derive: 'メイン色から生成',
|
|
2599
2717
|
deriveHint: '現在のアクセント色の色相と彩度から背景色と文字色を生成します(明暗は現在のモードに従います)',
|
|
2600
2718
|
deriveNote: '「メイン色から生成」はアクセント色だけを入力として背景色と文字色を自動計算します。手動で設定した背景色と文字色は上書きされます(生成後に個別に変更できます)。',
|
|
2601
|
-
notice: '1.13.
|
|
2719
|
+
notice: '1.13.4:ホバーカードの背景がホスト固定の中立ダークから配色の暗面に切り替わりました(白文字とコントラストはそのまま)。',
|
|
2602
2720
|
dismiss: '了解',
|
|
2603
2721
|
explainClamp: 'アクセント色を正規化しました:{from} → {to}(ボタンとチェックの可読性のため)',
|
|
2604
2722
|
explainLink: 'リンクを可読性のため暗くしました:{ratio}:1(目標 {target}:1)',
|
|
@@ -3249,7 +3367,7 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
3249
3367
|
// 必须能在测试里读到"实现里的那个数"。此前测试拿 floors() 的返回值当期望值 ——
|
|
3250
3368
|
// 常量一改、期望值跟着改,那道门就是空转的(变异实测:CONTRAST_FLOOR 4.5→1.0 全绿)。
|
|
3251
3369
|
if (DEV_OPT_IN && typeof window !== 'undefined' && typeof window.__DSH_THEME_PALETTE_DEV__ === 'function') {
|
|
3252
|
-
window.__DSH_THEME_PALETTE_DEV__({ buildTokens, SCHEMES, SIDEBAR_MODES, TEXT_MODES, SCROLL_MODES, CONTROL_MODES, MD_MODES, HC_MODES, contrast, toOklch, fromOklch, flatten, luminance, withAlpha, mixHex, harmonize, deltaE, simulateCvd, rampsFor, floors, floorsDark, apcaContrast, raiseToLc, solveForeground, pickLocale, hostLocale, encodeConfig, decodeConfig, customScheme, deriveCustomFromAccent, readCustom, writeCustom, CONTRAST_SURFACES, CONTRAST_ROLES, buildContrastReport, devContrastReport, CONTRAST_TARGETS, CONTRAST_EXEMPT, CONTRAST_FLOOR, CONTRAST_SOLVER_MARGIN, MIN_MAIN, MIN_SECONDARY, MIN_TERTIARY, MIN_LINK, MIN_LINK_DARK, MIN_SECONDARY_DARK, MIN_TERTIARY_DARK, FLOORS_HC, FLOORS_HC_DARK, RAMP_MIN_GAP, RAMP_ORDER, hexToRgb, LAYER_MARK, settingsCss: SETTINGS_CSS, markdownCss: MARKDOWN_CSS, cardColors })
|
|
3370
|
+
window.__DSH_THEME_PALETTE_DEV__({ buildTokens, SCHEMES, SIDEBAR_MODES, TEXT_MODES, SCROLL_MODES, CONTROL_MODES, MD_MODES, HC_MODES, contrast, toOklch, fromOklch, flatten, luminance, withAlpha, mixHex, harmonize, deltaE, simulateCvd, rampsFor, floors, floorsDark, apcaContrast, raiseToLc, solveForeground, pickLocale, hostLocale, encodeConfig, decodeConfig, customScheme, deriveCustomFromAccent, readCustom, writeCustom, CONTRAST_SURFACES, CONTRAST_ROLES, buildContrastReport, devContrastReport, CONTRAST_TARGETS, CONTRAST_EXEMPT, CONTRAST_FLOOR, CONTRAST_SOLVER_MARGIN, MIN_MAIN, MIN_SECONDARY, MIN_TERTIARY, MIN_LINK, MIN_LINK_DARK, MIN_SECONDARY_DARK, MIN_TERTIARY_DARK, FLOORS_HC, FLOORS_HC_DARK, RAMP_MIN_GAP, RAMP_ORDER, SURFACE_ALIAS_STEPS, hexToRgb, LAYER_MARK, hostPatchCss: HOST_PATCH_CSS, settingsCss: SETTINGS_CSS, markdownCss: MARKDOWN_CSS, cardColors })
|
|
3253
3371
|
}
|
|
3254
3372
|
|
|
3255
3373
|
return {
|
|
@@ -3865,10 +3983,12 @@ body[data-ds-dark-theme] .dsh-tp{color-scheme:dark}
|
|
|
3865
3983
|
applyAll('boot')
|
|
3866
3984
|
const removeStyle = installMarkdownStyle()
|
|
3867
3985
|
const removeSettings = installSettingsStyle()
|
|
3986
|
+
const removeHostPatch = installHostPatchStyle()
|
|
3868
3987
|
return () => {
|
|
3869
3988
|
disposeLayer()
|
|
3870
3989
|
removeStyle()
|
|
3871
3990
|
removeSettings()
|
|
3991
|
+
removeHostPatch()
|
|
3872
3992
|
try {
|
|
3873
3993
|
document.removeEventListener('visibilitychange', healOnVisible)
|
|
3874
3994
|
window.removeEventListener('focus', healOnFocus)
|