dsh-leafy-skin 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +79 -2
- package/README.zh.md +68 -0
- package/cordis.patch.yml +5 -0
- package/lib/client.js +374 -0
- package/lib/index.js +41 -0
- package/package.json +42 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 badai147
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,80 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-leafy-skin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An eye-friendly green skin: a leafy palette layered over the official DSH web GUI theme, in a
|
|
4
|
+
light emerald and a dark mint variant.
|
|
5
|
+
|
|
6
|
+
> I wanted the effect of a Minecraft resource pack.
|
|
7
|
+
|
|
8
|
+
**English** | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Screenshot
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Layered greens** — a mist-green canvas, raised panels, and a deeper sidebar, with emerald
|
|
17
|
+
accents in light mode and mint in dark, instead of one flat wash of green.
|
|
18
|
+
- **Comfortable by construction** — no pure white or pure black, a single green hue family, and
|
|
19
|
+
all body text at WCAG AA (≥ 4.5:1).
|
|
20
|
+
- **Texture** — softer corner radii, green-tinted diffuse shadows, low-contrast hairlines, and
|
|
21
|
+
glassy menu surfaces.
|
|
22
|
+
- **Details** — mint text selection, Inter / Noto Sans SC / Cascadia Code font stacks, slim
|
|
23
|
+
scrollbars, and restrained hover and menu motion.
|
|
24
|
+
- **Tunable** — the palette is one commented table, a self-check script guards contrast, and the
|
|
25
|
+
style layer has a single on/off switch.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
dsh plugin --profile web add dsh-leafy-skin
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Restart DSH once afterwards so the profile recomposes. After that, colour edits only need a page
|
|
34
|
+
refresh (client changes hot-reload within about a second).
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
Install the plugin and load the app. The skin layers itself over the active theme, so light, dark,
|
|
39
|
+
and follow-system each pick up their own variant automatically.
|
|
40
|
+
|
|
41
|
+
## Customize
|
|
42
|
+
|
|
43
|
+
- **Colours** — the `TOKENS` table in `lib/client.js`, grouped and commented by area.
|
|
44
|
+
- **Radii, shadows, fonts, motion** — the same file, plus the small style layer below it.
|
|
45
|
+
- **Palette only** — set `ENABLE_CSS_LAYER` to `false` in `lib/client.js` to drop the style layer
|
|
46
|
+
entirely.
|
|
47
|
+
- **Check your work** — `node tools/check-palette.mjs` validates token shape, text and syntax
|
|
48
|
+
contrast, and the style layer's three constraints.
|
|
49
|
+
|
|
50
|
+
## Uninstall
|
|
51
|
+
|
|
52
|
+
Any one of these, then restart DSH:
|
|
53
|
+
|
|
54
|
+
1. Comment out the `insert` entry in `cordis.patch.yml`;
|
|
55
|
+
2. Drop `dsh-leafy-skin` from `dsh.profile.bundles` in `~/.dsh/profiles/<profile>/package.json`;
|
|
56
|
+
3. Run `dsh plugin --profile web remove dsh-leafy-skin`.
|
|
57
|
+
|
|
58
|
+
## Known limitations
|
|
59
|
+
|
|
60
|
+
- The native window title bar belongs to the DSH desktop shell, not to this plugin, so it stays
|
|
61
|
+
DSH grey for the instant before the page paints.
|
|
62
|
+
- Real see-through glass is impossible on Windows — the sidebar depth and translucent menus are
|
|
63
|
+
colour layering, not blur through the window.
|
|
64
|
+
- Components hard-code font sizes and layout in hashed CSS modules, so this skin deliberately
|
|
65
|
+
leaves them alone.
|
|
66
|
+
|
|
67
|
+
## Changelog
|
|
68
|
+
|
|
69
|
+
See [CHANGELOG.md](CHANGELOG.md)
|
|
70
|
+
|
|
71
|
+
## Contributing
|
|
72
|
+
|
|
73
|
+
Issues are welcome: bug reports, colour suggestions, screenshots of anything that looks off.
|
|
74
|
+
|
|
75
|
+
**Pull requests are not accepted** — this is a personal skin, and reviewing patches would cost more
|
|
76
|
+
than it returns. Please open an issue instead.
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
[MIT](LICENSE)
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# dsh-leafy-skin
|
|
2
|
+
|
|
3
|
+
护眼绿色皮肤:在 DSH Web GUI 的官方主题之上叠一层叶绿调色板,浅色翡翠 / 深色薄荷两套。
|
|
4
|
+
|
|
5
|
+
> 我想做一个类似于我的世界的材质包一样的效果。
|
|
6
|
+
|
|
7
|
+
[English](README.md) | **中文**
|
|
8
|
+
|
|
9
|
+
## 截图展示
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## 特性
|
|
14
|
+
|
|
15
|
+
- **分层绿**——雾绿画布、抬起的面板、深一档的侧栏,浅色用翡翠、深色用薄荷做强调色,
|
|
16
|
+
不是平铺的一整块绿。
|
|
17
|
+
- **护眼是结构性的**——不用纯白纯黑、色相统一在一个绿系、正文全部守住 WCAG AA(≥ 4.5:1)。
|
|
18
|
+
- **质感**——更柔和的圆角、带绿意的弥散阴影、低对比发丝描边、通透的菜单材质。
|
|
19
|
+
- **细节**——薄荷色文本选区、Inter / Noto Sans SC / Cascadia Code 字体栈、纤细滚动条,
|
|
20
|
+
以及克制的悬停与菜单动效。
|
|
21
|
+
- **可调**——调色板就是一张带分组注释的表,自检脚本守住对比度,样式层有一个总开关。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
dsh plugin --profile web add dsh-leafy-skin
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
装完重启一次 DSH,让 profile 重新组合。之后只改颜色的话刷新页面即可
|
|
30
|
+
(客户端改动约 1 秒内热更新)。
|
|
31
|
+
|
|
32
|
+
## 使用
|
|
33
|
+
|
|
34
|
+
安装插件后加载即可。皮肤叠在当前主题之上,切浅色 / 深色 / 跟随系统都会自动取对应那一档。
|
|
35
|
+
|
|
36
|
+
## 自定义
|
|
37
|
+
|
|
38
|
+
- **颜色**——`lib/client.js` 里的 `TOKENS` 表,按部位分组并带注释。
|
|
39
|
+
- **圆角、阴影、字体、动效**——同一个文件,以及它下面的那一小块样式层。
|
|
40
|
+
- **只想要调色板**——把 `lib/client.js` 里的 `ENABLE_CSS_LAYER` 改成 `false`,样式层整个关掉。
|
|
41
|
+
- **改完自检**——`node tools/check-palette.mjs` 会校验 token 形状、文字与语法高亮的对比度,
|
|
42
|
+
以及样式层的三条约束。
|
|
43
|
+
|
|
44
|
+
## 卸载
|
|
45
|
+
|
|
46
|
+
任选其一,然后重启 DSH:
|
|
47
|
+
|
|
48
|
+
1. 注释掉 `cordis.patch.yml` 里的 `insert` 行;
|
|
49
|
+
2. 从 `~/.dsh/profiles/<profile>/package.json` 的 `dsh.profile.bundles` 里删掉 `dsh-leafy-skin`;
|
|
50
|
+
3. 执行 `dsh plugin --profile web remove dsh-leafy-skin`。
|
|
51
|
+
|
|
52
|
+
## 已知限制
|
|
53
|
+
|
|
54
|
+
- 原生窗口标题栏属于 DSH 桌面外壳、不归插件管,所以页面画出来之前那一瞬仍是 DSH 的灰白。
|
|
55
|
+
- Windows 上做不出真的透视毛玻璃——侧栏的层次与半透明菜单是颜色分层,不是透过窗口的模糊。
|
|
56
|
+
- 组件把字号与布局写死在哈希 CSS module 里,本皮肤刻意不去碰它们。
|
|
57
|
+
|
|
58
|
+
## 更新日志
|
|
59
|
+
|
|
60
|
+
见 [CHANGELOG.md](CHANGELOG.md)
|
|
61
|
+
|
|
62
|
+
## 贡献
|
|
63
|
+
|
|
64
|
+
有问题或者建议欢迎提 issue。本仓库不接受 PR。
|
|
65
|
+
|
|
66
|
+
## 许可证
|
|
67
|
+
|
|
68
|
+
[MIT](LICENSE)
|
package/cordis.patch.yml
ADDED
package/lib/client.js
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
// dsh-leafy-skin client bundle —— 把 leafy 调色板叠到当前 DSH 主题之上。
|
|
2
|
+
//
|
|
3
|
+
// 手写 __ModuleLoader__ 工厂(无构建步骤、无 react 依赖)。
|
|
4
|
+
// 机制:ctx.theme.overrideTokens(source, tokens)。token 值必须是
|
|
5
|
+
// { light, dark } 成对字符串;ui-layout 的展示转换器会把它们作为 inline
|
|
6
|
+
// style 写到 <body> 上(body.style.setProperty),因此优先级高于任何样式表,
|
|
7
|
+
// 且切浅色/深色/跟随系统时自动取对应那一档。
|
|
8
|
+
//
|
|
9
|
+
// token 命名与官方 @deepseek-ai/dsh-client-ui-theme 的 design-platform.css 一一对应:
|
|
10
|
+
// --dsw-static-neutral-bluish-* 结构色阶(表面、文字、hover、边框的骨架)
|
|
11
|
+
// --dsw-static-deepseek-* 强调色族(链接、业务态、信息按钮、气泡)
|
|
12
|
+
// --dsw-alias-* / --dsw-specific-* 语义别名(组件只读这一层)
|
|
13
|
+
// 覆盖色阶能让所有派生别名自动跟着变绿;少数一个色阶被两种角色共用的地方
|
|
14
|
+
// (例如浅色当文字、深色当表面)用显式别名覆盖拆开。
|
|
15
|
+
window.__ModuleLoader__.load({ id: "dsh-leafy-skin", factory: () => {
|
|
16
|
+
|
|
17
|
+
var module = { exports: {} };
|
|
18
|
+
var exports = module.exports;
|
|
19
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
20
|
+
|
|
21
|
+
const PLUGIN_ID = "dsh-leafy-skin";
|
|
22
|
+
const inject = ["theme"];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 3D 样式层总开关。
|
|
26
|
+
*
|
|
27
|
+
* token 层之外的样式细节都挂在这里;改成 false 就只剩 token 层(等于 3C 的状态),
|
|
28
|
+
* 不用动别的代码。
|
|
29
|
+
*/
|
|
30
|
+
const ENABLE_CSS_LAYER = true;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* leafy 调色板:token -> { light, dark }。
|
|
34
|
+
* 调色原则:① 不纯白不纯黑(大面积降到 L*≈96,减少眩光)
|
|
35
|
+
* ② 色相统一在绿系,避免蓝绿混杂
|
|
36
|
+
* ③ 正文/次要文字守 WCAG AA,说明文字沿用官方的弱化惯例
|
|
37
|
+
* 改完可用 `node tools/check-palette.mjs` 复核形状与对比度。
|
|
38
|
+
*/
|
|
39
|
+
const TOKENS = {
|
|
40
|
+
|
|
41
|
+
// ── 1. 结构色阶:偏蓝的 neutral-bluish → 绿灰 ──────────────────────
|
|
42
|
+
// 浅色档是浅绿灰(表面/文字),深色档是深苔绿(深色模式的表面/文字)。
|
|
43
|
+
"--dsw-static-neutral-bluish-00": { light: "#FFFFFF", dark: "#FFFFFF" },
|
|
44
|
+
"--dsw-static-neutral-bluish-50": { light: "#F6FAF3", dark: "#F4F8F0" },
|
|
45
|
+
"--dsw-static-neutral-bluish-60": { light: "#EFF5EA", dark: "#EEF4E9" },
|
|
46
|
+
"--dsw-static-neutral-bluish-75": { light: "#E9F1E3", dark: "#E7EFE1" },
|
|
47
|
+
"--dsw-static-neutral-bluish-100": { light: "#E1EBD9", dark: "#E1EBD9" },
|
|
48
|
+
"--dsw-static-neutral-bluish-150": { light: "#DAE6D2", dark: "#D8E4D0" },
|
|
49
|
+
"--dsw-static-neutral-bluish-200": { light: "#D0DEC7", dark: "#D0DEC7" },
|
|
50
|
+
"--dsw-static-neutral-bluish-300": { light: "#B7C9AC", dark: "#B7C9AC" },
|
|
51
|
+
"--dsw-static-neutral-bluish-400": { light: "#93A78A", dark: "#93A78A" },
|
|
52
|
+
"--dsw-static-neutral-bluish-500": { light: "#7C9074", dark: "#7C9074" },
|
|
53
|
+
"--dsw-static-neutral-bluish-600": { light: "#64775D", dark: "#64775D" },
|
|
54
|
+
"--dsw-static-neutral-bluish-700": { light: "#57694F", dark: "#57694F" },
|
|
55
|
+
"--dsw-static-neutral-bluish-750": { light: "#3C4938", dark: "#3C4938" },
|
|
56
|
+
"--dsw-static-neutral-bluish-800": { light: "#2E392B", dark: "#2E392B" },
|
|
57
|
+
"--dsw-static-neutral-bluish-850": { light: "#263024", dark: "#263024" },
|
|
58
|
+
"--dsw-static-neutral-bluish-875": { light: "#1F2820", dark: "#1F2820" },
|
|
59
|
+
"--dsw-static-neutral-bluish-900": { light: "#182018", dark: "#182018" },
|
|
60
|
+
"--dsw-static-neutral-bluish-950": { light: "#131A12", dark: "#131A12" },
|
|
61
|
+
"--dsw-static-neutral-bluish-1000": { light: "#0E140C", dark: "#0E140C" },
|
|
62
|
+
|
|
63
|
+
// ── 2. 强调色阶:deepseek 蓝族 → 翡翠/薄荷族 ───────────────────────
|
|
64
|
+
// 链接、业务态、焦点环、信息按钮、气泡高亮都从这一族派生。
|
|
65
|
+
// 浅色走翡翠(偏蓝的绿,饱和度略高做视觉焦点),深色走薄荷(更亮更清透)。
|
|
66
|
+
"--dsw-static-deepseek-50": { light: "#E4F4EC", dark: "#12261C" },
|
|
67
|
+
"--dsw-static-deepseek-100": { light: "#D2EDDD", dark: "#173023" },
|
|
68
|
+
"--dsw-static-deepseek-200": { light: "#BAE5CE", dark: "#1D3B2B" },
|
|
69
|
+
"--dsw-static-deepseek-300": { light: "#8FD3AE", dark: "#3F8F6A" },
|
|
70
|
+
"--dsw-static-deepseek-400": { light: "#5FC492", dark: "#8CE4B4" },
|
|
71
|
+
"--dsw-static-deepseek-450": { light: "#3FA878", dark: "#63D9A0" },
|
|
72
|
+
"--dsw-static-deepseek-500": { light: "#1A774F", dark: "#4FC894" },
|
|
73
|
+
"--dsw-static-deepseek-600": { light: "#176B48", dark: "#3FA97C" },
|
|
74
|
+
"--dsw-static-deepseek-700-delete": { light: "#12573A", dark: "#338C67" },
|
|
75
|
+
"--dsw-static-deepseek-800": { light: "#0E4830", dark: "#276B4C" },
|
|
76
|
+
"--dsw-static-deepseek-900": { light: "#0A3524", dark: "#1B4634" },
|
|
77
|
+
|
|
78
|
+
// ── 3. 表面:雾绿画布 + 抬升面板 + 深一档的侧栏 ────────────────────
|
|
79
|
+
// 画布(内容底)退后、面板抬起、侧栏再深一档形成 chrome 层,三档拉开层次;
|
|
80
|
+
// 深色模式同一逻辑:画布最亮的面板抬起,侧栏比画布更深。
|
|
81
|
+
"--dsw-alias-bg-base": { light: "#EDF3E6", dark: "#121810" },
|
|
82
|
+
"--dsw-alias-bg-document-preview": { light: "#E2ECD9", dark: "#0D120C" },
|
|
83
|
+
"--dsw-alias-bg-layer-1": { light: "#F8FBF2", dark: "#182018" },
|
|
84
|
+
"--dsw-alias-bg-layer-2": { light: "#FDFEFB", dark: "#212B21" },
|
|
85
|
+
"--dsw-alias-bg-layer-3": { light: "#FFFFFF", dark: "#2A362A" },
|
|
86
|
+
"--dsw-alias-bg-overlay": { light: "#E7EFDF", dark: "#26312A" },
|
|
87
|
+
"--dsw-alias-bg-module-platform": { light: "#E8F0E0", dark: "#2A362A" },
|
|
88
|
+
"--dsw-alias-bg-multi-select": { light: "#E2ECD9", dark: "#1E2820" },
|
|
89
|
+
"--dsw-specific-sidebar-fill": { light: "#E4EDDA", dark: "#0D120C" },
|
|
90
|
+
"--dsw-specific-sidebar-nav-item-active": { light: "#D8E6CD", dark: "#263024" },
|
|
91
|
+
"--dsw-specific-sidebar-nav-item-hover": { light: "#DEE9D4", dark: "#1B2318" },
|
|
92
|
+
"--dsw-specific-sidebar-nav-item-active-accent": { light: "#C4E9D2", dark: "#2E5B44" },
|
|
93
|
+
"--dsw-specific-selector": { light: "#E8F0E0", dark: "#2A362A" },
|
|
94
|
+
"--dsw-specific-tip": { light: "#E8F0E0", dark: "#2A362A" },
|
|
95
|
+
"--dsw-specific-input-major": { light: "#FFFFFF", dark: "#1E2820" },
|
|
96
|
+
"--dsw-specific-login-input": { light: "#F2F7EC", dark: "#141A12" },
|
|
97
|
+
"--dsw-specific-bubble": { light: "#DFF0E6", dark: "#172E22" },
|
|
98
|
+
"--dsw-specific-bubble-highlight": { light: "#C2E9D3", dark: "#24402E" },
|
|
99
|
+
"--dsw-menu-surface-fill": { light: "#FBFDF794", dark: "#24302480" },
|
|
100
|
+
"--dsw-alias-menu-group-header-fill": { light: "#FBFDF7F0", dark: "#26332AF0" },
|
|
101
|
+
"--dsw-specific-menu": { light: "#FBFDF794", dark: "#24302480" },
|
|
102
|
+
"--dsw-alias-settings-card-fill": { light: "#FBFDF8", dark: "#1E2A1E" },
|
|
103
|
+
"--dsw-alias-settings-card-stroke": { light: "#122C1A14", dark: "#FFFFFF17" },
|
|
104
|
+
|
|
105
|
+
// ── 4. 文字:分级对比度(说明文字保持官方的弱化惯例) ──────────────
|
|
106
|
+
"--dsw-alias-label-secondary": { light: "#56654F", dark: "#AAB9A6" },
|
|
107
|
+
"--dsw-alias-label-tertiary": { light: "#5F7159", dark: "#8A9985" },
|
|
108
|
+
"--dsw-alias-label-caption": { light: "#93A78A", dark: "#8FA386" },
|
|
109
|
+
"--dsw-alias-label-primary-bluish": { light: "#143D24", dark: "#D3E8C9" },
|
|
110
|
+
"--dsw-alias-label-deep-diving": { light: "#14724E", dark: "#9BE8C0" },
|
|
111
|
+
"--dsw-alias-label-deep-diving-shimmer": { light: "#2E9A72", dark: "#B8F2D2" },
|
|
112
|
+
|
|
113
|
+
// ── 5. 品牌与选中 ────────────────────────────────────────────────
|
|
114
|
+
// brand-primary:浅色主按钮用翡翠绿(白字),深色用亮薄荷(配深色字)。
|
|
115
|
+
"--dsw-alias-brand-primary": { light: "#14724E", dark: "#63D9A0" },
|
|
116
|
+
"--dsw-alias-bg-document-selection": {
|
|
117
|
+
light: "color-mix(in srgb, #5FCB9B 45%, transparent)",
|
|
118
|
+
dark: "color-mix(in srgb, #5FCB9B 45%, transparent)"
|
|
119
|
+
},
|
|
120
|
+
"--dsw-alias-onboarding-accent": { light: "#14724E", dark: "#63D9A0" },
|
|
121
|
+
|
|
122
|
+
// ── 6. 代码块与滚动条(走的是纯 neutral 家族,不随色阶变绿) ───────
|
|
123
|
+
// 代码块底色比画布再深一档,和正文拉开;行内代码只轻一档不抢眼。
|
|
124
|
+
"--dsw-alias-markdown-inline-code": { light: "#E7F0E0", dark: "#1C2620" },
|
|
125
|
+
"--dsw-alias-markdown-code-block": { light: "#E4EEDC", dark: "#1A241A" },
|
|
126
|
+
"--dsw-alias-markdown-code-block-banner": { light: "#DCE8D3", dark: "#212D20" },
|
|
127
|
+
"--dsw-alias-markdown-code-segment-unselected": { light: "#E1EBD9", dark: "#182018" },
|
|
128
|
+
"--dsw-alias-markdown-code-segment-selected": { light: "#F8FBF2", dark: "#232E22" },
|
|
129
|
+
"--dsw-alias-scrollbar-bg-l1": { light: "#C3D3BA", dark: "#46543F" },
|
|
130
|
+
"--dsw-alias-scrollbar-bg-l2": { light: "#BCCEB2", dark: "#52614A" },
|
|
131
|
+
"--dsw-alias-scrollbar-hover-l1": { light: "#AFC1A5", dark: "#566A4E" },
|
|
132
|
+
"--dsw-alias-scrollbar-hover-l2": { light: "#A6B99C", dark: "#5F7256" },
|
|
133
|
+
|
|
134
|
+
// ── 7. 交互叠色(浅色原来是偏蓝的 #263148 系 alpha;强度比官方再明确一档) ──
|
|
135
|
+
"--dsw-alias-interactive-bg-hover": { light: "#1E3A2414", dark: "#FFFFFF17" },
|
|
136
|
+
"--dsw-alias-interactive-bg-active": { light: "#1E3A2424", dark: "#FFFFFF29" },
|
|
137
|
+
"--dsw-alias-interactive-bg-hover-accent": { light: "#1E3A242E", dark: "#FFFFFF42" },
|
|
138
|
+
|
|
139
|
+
// ── 8. 思考块顶部渐变(原来是纯白/冷灰,绿底上会发白) ─────────────
|
|
140
|
+
"--dsw-linear-gradient-think": {
|
|
141
|
+
light: "linear-gradient(180deg, #F1F6ED 20.19%, #F1F6ED00 100%)",
|
|
142
|
+
dark: "linear-gradient(180deg, #131A12 20.19%, #131A1200 100%)"
|
|
143
|
+
},
|
|
144
|
+
"--dsw-linear-think-select": {
|
|
145
|
+
light: "linear-gradient(180deg, #E9F1E3 20.19%, #E9F1E300 100%)",
|
|
146
|
+
dark: "linear-gradient(180deg, #232C21 20.19%, #232C2100 100%)"
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
// ── 9. 状态点与引导页(引导页三组渐变原来是蓝紫/蓝/青,改成翡翠/薄荷/青绿) ──
|
|
150
|
+
"--dsw-alias-state-idle-primary": { light: "#B7C9AC", dark: "#5A6B52" },
|
|
151
|
+
"--dsw-alias-onboarding-secondary-fill": { light: "#F8FBF2", dark: "#2C4033" },
|
|
152
|
+
"--dsw-alias-onboarding-checkbox-border": {
|
|
153
|
+
light: "color-mix(in srgb, #0E140C 20%, transparent)",
|
|
154
|
+
dark: "#FFFFFF1F"
|
|
155
|
+
},
|
|
156
|
+
"--dsw-gradient-onboarding-violet-stops": {
|
|
157
|
+
light: "#0E4830 33.102%, #2E9A72 50.954%, #C2E9D3 85.326%, #0E4830",
|
|
158
|
+
dark: "#0E4830 33.102%, #2E9A72 50.954%, #C2E9D3 85.326%, #0E4830"
|
|
159
|
+
},
|
|
160
|
+
"--dsw-gradient-onboarding-blue-stops": {
|
|
161
|
+
light: "#14724E 18.75%, #35A87C 51.78%, #A9E8CB 86.252%, #14724E",
|
|
162
|
+
dark: "#14724E 18.75%, #35A87C 51.78%, #A9E8CB 86.252%, #14724E"
|
|
163
|
+
},
|
|
164
|
+
"--dsw-gradient-onboarding-cyan-stops": {
|
|
165
|
+
light: "#125E5A 21.154%, #2E9E8E 50.954%, #B0EEDD 85.326%, #125E5A",
|
|
166
|
+
dark: "#125E5A 21.154%, #2E9E8E 50.954%, #B0EEDD 85.326%, #125E5A"
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
// ── 10. 代码语法高亮(shiki,原来是蓝/紫/粉的冷色,改成与绿底和谐的暖绿系) ──
|
|
170
|
+
// 保留色相差异(常量/字符串/关键字/函数各自可辨),只把冷暖调过来;
|
|
171
|
+
// 注释沿用弱化惯例,对比度低于正文门槛是刻意的。
|
|
172
|
+
"--shiki-token-constant": { light: "#1C6E8C", dark: "#6FC3DD" },
|
|
173
|
+
"--shiki-token-string": { light: "#2A7248", dark: "#8CDCA6" },
|
|
174
|
+
"--shiki-token-comment": { light: "#7C8F76", dark: "#8FA386" },
|
|
175
|
+
"--shiki-token-keyword": { light: "#9C4E26", dark: "#E0A06A" },
|
|
176
|
+
"--shiki-token-parameter": { light: "#9A560F", dark: "#E8B472" },
|
|
177
|
+
"--shiki-token-function": { light: "#5C6B2F", dark: "#C7D08A" },
|
|
178
|
+
"--shiki-token-string-expression": { light: "#35734B", dark: "#9ADFAF" },
|
|
179
|
+
"--shiki-token-punctuation": { light: "#5A6A57", dark: "#A9B7A4" },
|
|
180
|
+
"--shiki-token-link": { light: "#276F44", dark: "#8CDDA8" },
|
|
181
|
+
|
|
182
|
+
// ── 11. 空间与质感:圆角尺度、绿墨阴影、低对比描边 ────────────────
|
|
183
|
+
// 圆角从官方的 4/8/12/16/20/28 收到 6/8/10/14/18/18:12→10、16→14 更接近
|
|
184
|
+
// Linear 那种克制的圆角,输入框/按钮仍是 8–10px 的"柔和"档。
|
|
185
|
+
"--dsw-radius-xs": { light: "6px", dark: "6px" },
|
|
186
|
+
"--dsw-radius-sm": { light: "8px", dark: "8px" },
|
|
187
|
+
"--dsw-radius-md": { light: "10px", dark: "10px" },
|
|
188
|
+
"--dsw-radius-lg": { light: "14px", dark: "14px" },
|
|
189
|
+
"--dsw-radius-xl": { light: "18px", dark: "18px" },
|
|
190
|
+
"--dsw-radius-panel": { light: "18px", dark: "18px" },
|
|
191
|
+
|
|
192
|
+
// 阴影:把官方的中性黑 alpha 换成"绿墨"(#122C1A / #040A05),
|
|
193
|
+
// 在绿底上不显脏;同时加大扩散半径、降低单层不透明度 → 弥散而非硬边。
|
|
194
|
+
"--dsw-shadow-lv1": {
|
|
195
|
+
light: "0 1px 2px 0 #122C1A0A, 0 4px 12px 0 #122C1A08",
|
|
196
|
+
dark: "0 1px 2px 0 #040A0514, 0 4px 12px 0 #040A0512"
|
|
197
|
+
},
|
|
198
|
+
"--dsw-shadow-lv1-blur": {
|
|
199
|
+
light: "0 6px 18px 0 #122C1A0A",
|
|
200
|
+
dark: "0 6px 18px 0 #040A0514"
|
|
201
|
+
},
|
|
202
|
+
"--dsw-shadow-lv2": {
|
|
203
|
+
light: "0 2px 6px 0 #122C1A0A, 0 10px 28px 0 #122C1A0D",
|
|
204
|
+
dark: "0 2px 6px 0 #040A0517, 0 10px 28px 0 #040A051C"
|
|
205
|
+
},
|
|
206
|
+
"--dsw-shadow-lv3": {
|
|
207
|
+
light: "0 0 0 .5px #122C1A0F, 0 10px 28px 0 #122C1A0F, 0 28px 56px 0 #122C1A14",
|
|
208
|
+
dark: "0 0 0 .5px #FFFFFF14, 0 10px 28px 0 #040A051F, 0 28px 56px 0 #040A0524"
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
// 描边:四档低对比绿墨阶梯(替掉纯黑 alpha)。浅色 4/8/10/14%,
|
|
212
|
+
// 深色 5/9/12.5/16%,整体比官方再轻一档,减少"框感"。
|
|
213
|
+
"--dsw-alias-border-l1": { light: "#122C1A0A", dark: "#FFFFFF0D" },
|
|
214
|
+
"--dsw-alias-border-l2": { light: "#122C1A14", dark: "#FFFFFF17" },
|
|
215
|
+
"--dsw-alias-border-l2-darkmode-thin": { light: "#122C1A14", dark: "#FFFFFF0F" },
|
|
216
|
+
"--dsw-alias-border-l3": { light: "#122C1A1A", dark: "#FFFFFF20" },
|
|
217
|
+
"--dsw-alias-border-l4": { light: "#122C1A24", dark: "#FFFFFF29" },
|
|
218
|
+
|
|
219
|
+
// 高层级表面的发丝描边(elevation 的 0.5px 描边层取它)压到 7%/8%。
|
|
220
|
+
// 注意 geometry(--dsw-elevation-panel/soft 的模糊与层次)在官方是
|
|
221
|
+
// `body,body *` 逐元素重声明,token 层改不动,只能改这个描边色。
|
|
222
|
+
"--dsw-elevation-stroke-color": { light: "#122C1A12", dark: "#FFFFFF14" },
|
|
223
|
+
|
|
224
|
+
// ── 12. 排版与动效:字体栈、滚动条几何、过渡时长与缓动 ────────────
|
|
225
|
+
// 字体栈:Latin 走 Inter(有则用)/ Segoe UI Variable,中文优先 Noto Sans SC
|
|
226
|
+
// (本机已安装,比微软雅黑更现代),再退回官方原有回退链。
|
|
227
|
+
"--dsw-font-family": {
|
|
228
|
+
light: 'Inter, "Segoe UI Variable Text", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
229
|
+
dark: 'Inter, "Segoe UI Variable Text", "Noto Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif'
|
|
230
|
+
},
|
|
231
|
+
// 代码字体:把本机已装的 Cascadia Code 提到 Consolas 之前。
|
|
232
|
+
"--ds-font-family-code": {
|
|
233
|
+
light: '"Cascadia Code", "JetBrains Mono", "SF Mono", "Fira Code", Consolas, "Liberation Mono", Menlo, Courier, "PingFang SC", "Microsoft YaHei"',
|
|
234
|
+
dark: '"Cascadia Code", "JetBrains Mono", "SF Mono", "Fira Code", Consolas, "Liberation Mono", Menlo, Courier, "PingFang SC", "Microsoft YaHei"'
|
|
235
|
+
},
|
|
236
|
+
// 滚动条:5px → 8px 更好抓,2px 透明边做视觉内缩(看起来仍是细圆条),
|
|
237
|
+
// 轨道两端留 4px 避免顶到圆角。
|
|
238
|
+
"--dsh-scrollbar-width": { light: "8px", dark: "8px" },
|
|
239
|
+
"--dsh-scrollbar-thumb-border": { light: "2px", dark: "2px" },
|
|
240
|
+
"--dsh-scrollbar-track-margin": { light: "4px", dark: "4px" }
|
|
241
|
+
// 注意:官方动效变量(--ds-transition-duration* / --ds-ease-in-out)不再覆盖。
|
|
242
|
+
// 试过改快并换成 cubic-bezier(.2,0,0,1),手感反而"先不动再猛走"更生硬——
|
|
243
|
+
// 那几个变量是给侧栏收放这类尺寸动画用的,官方取值本来就是为它们调的。
|
|
244
|
+
// 过渡手感改由下面的样式层负责(那是"变色反馈"层,两者职责不同)。
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* 3D 样式层的 CSS。只做 token 层够不到的三件事:文本选中高亮、全局过渡兜底、
|
|
249
|
+
* 菜单/浮层入场。
|
|
250
|
+
*
|
|
251
|
+
* 设计要点:DSH 里"只写了 :hover 没写 transition"的元素很多(尤其是一堆 div 行、
|
|
252
|
+
* 卡片、菜单项),所以过渡必须做成**零特异性的全局兜底**(:where(*)),
|
|
253
|
+
* 而不是点名几个表单控件——点名的那版被验证为"手感依旧生硬"。
|
|
254
|
+
*
|
|
255
|
+
* 三条硬约束(tools/check-palette.mjs 会机械校验):
|
|
256
|
+
* ① 不用哈希类名(`.BynINW_frame` 这种升级即失效),只用元素与官方公开钩子;
|
|
257
|
+
* ② 一律套 :where() 归零特异性,组件自己写的 transition/animation 永远优先,
|
|
258
|
+
* 我们只在组件没写的地方补,避免打架;
|
|
259
|
+
* ③ 不用 !important。
|
|
260
|
+
*
|
|
261
|
+
* 为什么内联成字符串而不是外置 lib/skin.css:外置文件要引入打包/取资源的步骤,
|
|
262
|
+
* 与"零构建"原则冲突(官方 ui-theme 也是这么内联它的样式表的)。
|
|
263
|
+
*/
|
|
264
|
+
const CSS_LAYER = [
|
|
265
|
+
// ① 文本选中高亮:官方全包只有 PDF 文本层与 xterm 无障碍树定义了 ::selection,
|
|
266
|
+
// 普通文本选区一直是 Chromium 默认的浅蓝——皮肤里最后一块非绿。
|
|
267
|
+
"::selection{background:#B9E8CE;color:#0E140C}",
|
|
268
|
+
"body[data-ds-dark-theme] ::selection{background:#2E5B44;color:#E9F1E6}",
|
|
269
|
+
|
|
270
|
+
// ② 全局默认过渡(兜底层):DSH 里大量可点区域是 div(行、卡片、菜单项),
|
|
271
|
+
// 它们大多只写了 :hover 没写 transition,只兜表单控件根本不够。
|
|
272
|
+
// 曲线用 easeOutQuad(起步快、收尾柔)——比 Material 强调曲线的
|
|
273
|
+
// "先不动再猛走"顺滑得多;时长 .2s 比 .16s 更能看出过渡而不是"闪一下"。
|
|
274
|
+
// 只动变色/淡入类属性,绝不碰尺寸与位移(那是布局,抖起来更难看)。
|
|
275
|
+
":where(*){transition:" +
|
|
276
|
+
"background-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
277
|
+
"border-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
278
|
+
"color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
279
|
+
"fill .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
280
|
+
"stroke .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
281
|
+
"opacity .2s cubic-bezier(.25,.46,.45,.94)}",
|
|
282
|
+
|
|
283
|
+
// ③ 交互控件:再补阴影(悬浮浮起感)与 transform(按下回弹),
|
|
284
|
+
// 这两样只给控件,不给通用元素——通用元素上的 transform 可能是
|
|
285
|
+
// 拖拽时用 inline style 逐帧写的,加过渡会拖出滞后感。
|
|
286
|
+
":where(button,a,[role=\"button\"],[role=\"tab\"],[role=\"menuitem\"],label,summary){" +
|
|
287
|
+
"transition:background-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
288
|
+
"border-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
289
|
+
"color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
290
|
+
"fill .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
291
|
+
"stroke .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
292
|
+
"opacity .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
293
|
+
"box-shadow .24s cubic-bezier(.25,.46,.45,.94)," +
|
|
294
|
+
"transform .16s cubic-bezier(.25,.46,.45,.94)}",
|
|
295
|
+
":where(input,textarea,select){" +
|
|
296
|
+
"transition:background-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
297
|
+
"border-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
298
|
+
"color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
299
|
+
"box-shadow .24s cubic-bezier(.25,.46,.45,.94)}",
|
|
300
|
+
|
|
301
|
+
// ④ 菜单/浮层:入场只做"位移 + 微缩",**全程 opacity 保持 1**。
|
|
302
|
+
// 为什么不用透明度淡入:菜单底色是独立子层(.material)上的
|
|
303
|
+
// var(--dsw-menu-surface-fill)(浅色仅 58% 不透明)+ backdrop blur,
|
|
304
|
+
// 按透明度淡入时中间帧是"模糊按全强度算、却按半透明合成",
|
|
305
|
+
// 观感就是"先透一层糊、再变实"——实测被一眼看出来。
|
|
306
|
+
// 只动 translate/scale 则每一帧都是实心的,物理上不存在"透"的过程。
|
|
307
|
+
// 两点安全性:① 菜单定位走 inline top/left(.portal),不用 transform;
|
|
308
|
+
// ② 用独立的 translate/scale 属性而不是 transform 简写,即使某个调用方
|
|
309
|
+
// 真传了 inline transform,也只会叠加、不会把定位顶掉。
|
|
310
|
+
// 代价:动画期间会新建包含块(官方为此特意把模糊隔离在子层里),
|
|
311
|
+
// 窗口只有 160ms,且嵌套子菜单用的是 absolute,不受影响。
|
|
312
|
+
":where([data-menu-material],[role=\"dialog\"],[role=\"menu\"],[role=\"listbox\"]){" +
|
|
313
|
+
"transition:background-color .2s cubic-bezier(.25,.46,.45,.94)," +
|
|
314
|
+
"box-shadow .24s cubic-bezier(.25,.46,.45,.94)}",
|
|
315
|
+
"@keyframes leafy-surface-in{from{translate:0 -3px;scale:.985}to{translate:0 0;scale:1}}",
|
|
316
|
+
":where([data-menu-material]){animation:leafy-surface-in .16s cubic-bezier(.25,.46,.45,.94)}",
|
|
317
|
+
|
|
318
|
+
// ⑤ 输入框(composer):光标色 + 聚焦时的柔光"抬升"。
|
|
319
|
+
// composer 不是 textarea,是 Lexical 的 contenteditable,官方给了两个稳定属性:
|
|
320
|
+
// [data-composer-card](带底色/圆角/阴影的卡片)与 [data-composer-input](编辑区)。
|
|
321
|
+
// 抬升感用**阴影**表达而不是位移:卡片里可能挂 position:fixed 的浮层(提示条、
|
|
322
|
+
// 下拉),给卡片加 translate/transform 会让它们改用卡片当参照系、坐标整块飞掉,
|
|
323
|
+
// 为 1px 的位移冒这个险不值当;阴影在视觉上同样是"浮起来"。
|
|
324
|
+
// 光圈走 ::after 而不是直接改卡片的 box-shadow:卡片那条 class 规则特异性更高,
|
|
325
|
+
// 零特异性的我们赢不了它(这正是我们想要的——不跟组件抢属性)。
|
|
326
|
+
// 颜色取自 --dsw-alias-state-business-primary(浅色翡翠 / 深色薄荷),跟随主题。
|
|
327
|
+
":where([data-composer-input],input,textarea){caret-color:var(--dsw-alias-state-business-primary)}",
|
|
328
|
+
":where([data-composer-card])::after{" +
|
|
329
|
+
"content:\"\";position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;" +
|
|
330
|
+
"transition:opacity .18s cubic-bezier(.25,.46,.45,.94);" +
|
|
331
|
+
"box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary) 12%, transparent)," +
|
|
332
|
+
"0 6px 16px -6px color-mix(in srgb, var(--dsw-alias-state-business-primary) 16%, transparent)}",
|
|
333
|
+
":where([data-composer-card]):has([data-composer-input]:focus)::after{opacity:1}",
|
|
334
|
+
|
|
335
|
+
// ⑥ 尊重系统的"减少动态效果":只关掉我们兜底的那些(组件自己写的特异性更高,
|
|
336
|
+
// 仍按官方自己的无障碍处理走)。输入框光圈只是透明度淡入、不含位移,
|
|
337
|
+
// 与官方 Toast 的处理一致,保留。
|
|
338
|
+
"@media (prefers-reduced-motion:reduce){:where(*){transition:none;animation:none}}",
|
|
339
|
+
].join("");
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* 挂上 3D 样式层。样式由本次 effect 持有,插件卸载/热更新时随标签一起移除。
|
|
343
|
+
* @param ctx - client cordis 上下文。
|
|
344
|
+
*/
|
|
345
|
+
function installCssLayer(ctx) {
|
|
346
|
+
if (!ENABLE_CSS_LAYER || typeof document === "undefined") {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
ctx.effect(() => {
|
|
350
|
+
const tag = document.createElement("style");
|
|
351
|
+
tag.dataset.plugin = PLUGIN_ID;
|
|
352
|
+
tag.dataset.pluginCss = `${PLUGIN_ID}/skin.css`;
|
|
353
|
+
tag.textContent = CSS_LAYER;
|
|
354
|
+
document.head.appendChild(tag);
|
|
355
|
+
return () => {
|
|
356
|
+
tag.remove();
|
|
357
|
+
};
|
|
358
|
+
}, "leafy-skin: css layer");
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* 叠上 leafy 调色板层 + 可选的样式层。两层都由 effect 持有,
|
|
363
|
+
* 插件卸载/热更新时自动摘除,因此停用插件即可回到官方配色与官方细节。
|
|
364
|
+
* @param ctx - client cordis 上下文。
|
|
365
|
+
*/
|
|
366
|
+
function apply(ctx) {
|
|
367
|
+
ctx.effect(() => ctx.theme.overrideTokens(PLUGIN_ID, TOKENS), "leafy-skin: palette layer");
|
|
368
|
+
installCssLayer(ctx);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
exports.apply = apply;
|
|
372
|
+
exports.inject = inject;
|
|
373
|
+
return module.exports;
|
|
374
|
+
}});
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-leafy-skin host entry(Host 侧)。
|
|
3
|
+
*
|
|
4
|
+
* 皮肤本体是客户端的 token 覆盖层,Host 侧只做一件事:在 index 响应里补一段
|
|
5
|
+
* 首帧 CSS。ui-theme 的引导样式把画布底色与 --dsh-boot-bg 写死成 #fff/#151517,
|
|
6
|
+
* 插件起来之前的第一帧还是官方灰白,所以这里追加一条同结构的样式行(排在
|
|
7
|
+
* ui-theme 之后,同等特异性下后写者胜)把首帧也染成叶绿。
|
|
8
|
+
*/
|
|
9
|
+
export const name = 'leafy-skin'
|
|
10
|
+
|
|
11
|
+
/** 浅色画布 / 深色画布,与 lib/client.js 里 --dsw-alias-bg-base 的取值保持一致。 */
|
|
12
|
+
const LIGHT_BG = '#F1F6ED'
|
|
13
|
+
const DARK_BG = '#131A12'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 首帧引导 CSS。
|
|
17
|
+
*
|
|
18
|
+
* 规则顺序即优先级(同一特异性下后写者胜),覆盖六种组合:
|
|
19
|
+
* 1. 脚本未运行前:浅色系统 → 浅色;深色系统 → 深色(规则 2 猜一把)。
|
|
20
|
+
* 2. body 脚本写入 html[data-ds-theme-source] 与 body[data-ds-dark-theme] 后:
|
|
21
|
+
* light → 浅色;dark → 深色;system → 跟随系统(规则 5 覆盖规则 3)。
|
|
22
|
+
* 3. body[data-ds-dark-theme] 作为兜底(属性被别处切换时也正确)。
|
|
23
|
+
*/
|
|
24
|
+
const BOOT_CSS = [
|
|
25
|
+
`body{background-color:${LIGHT_BG};--dsh-boot-bg:${LIGHT_BG}}`,
|
|
26
|
+
`@media (prefers-color-scheme:dark){body:not([data-ds-dark-theme]){background-color:${DARK_BG};--dsh-boot-bg:${DARK_BG}}}`,
|
|
27
|
+
`html[data-ds-theme-source="light"] body,html[data-ds-theme-source="system"] body{background-color:${LIGHT_BG};--dsh-boot-bg:${LIGHT_BG}}`,
|
|
28
|
+
`html[data-ds-theme-source="dark"] body{background-color:${DARK_BG};--dsh-boot-bg:${DARK_BG}}`,
|
|
29
|
+
`@media (prefers-color-scheme:dark){html[data-ds-theme-source="system"] body{background-color:${DARK_BG};--dsh-boot-bg:${DARK_BG}}}`,
|
|
30
|
+
`body[data-ds-dark-theme]{background-color:${DARK_BG};--dsh-boot-bg:${DARK_BG}}`,
|
|
31
|
+
].join('')
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 把首帧样式追加进 index 注入表。
|
|
35
|
+
* @param ctx - Host 插件上下文。
|
|
36
|
+
*/
|
|
37
|
+
export function apply(ctx) {
|
|
38
|
+
ctx.on('webserver/index-inject', (table) => {
|
|
39
|
+
table.push({ kind: 'style', text: BOOT_CSS })
|
|
40
|
+
})
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-leafy-skin",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Leafy — 护眼绿色皮肤:把 DSH Web GUI 的 --dsw-* 调色板叠成叶绿系(浅色 + 深色)。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"dsh",
|
|
10
|
+
"dsh-plugin",
|
|
11
|
+
"deepseek-harness",
|
|
12
|
+
"theme",
|
|
13
|
+
"skin",
|
|
14
|
+
"green"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/badai147/dsh-leafy-skin.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/badai147/dsh-leafy-skin#readme",
|
|
21
|
+
"dsh": {
|
|
22
|
+
"bundle": {
|
|
23
|
+
"patch": "./cordis.patch.yml"
|
|
24
|
+
},
|
|
25
|
+
"client": {
|
|
26
|
+
"inject": [
|
|
27
|
+
"@deepseek-ai/dsh-client-ui-theme"
|
|
28
|
+
],
|
|
29
|
+
"platform": "web"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"default": "./lib/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./client": "./lib/client.js",
|
|
37
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
38
|
+
"./package.json": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"lib",
|
|
42
|
+
"cordis.patch.yml"
|
|
43
|
+
]
|
|
44
|
+
}
|