@gyyxds/zy-ui 0.0.1 → 0.0.3

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +34 -19
  2. package/CONTRIBUTING.md +109 -99
  3. package/LICENSE +21 -0
  4. package/README.md +397 -162
  5. package/dist/zy-ui/badge/ZyBadge.vue.d.ts +4 -4
  6. package/dist/zy-ui/badge/index.d.ts +6 -6
  7. package/dist/zy-ui/button/ZyButton.vue.d.ts +3 -3
  8. package/dist/zy-ui/button/index.d.ts +9 -9
  9. package/dist/zy-ui/card/ZyCard.vue.d.ts +1 -1
  10. package/dist/zy-ui/card/index.d.ts +3 -3
  11. package/dist/zy-ui/checkbox/ZyCheckboxGroup.vue.d.ts +1 -1
  12. package/dist/zy-ui/checkbox/index.d.ts +3 -3
  13. package/dist/zy-ui/code-input/ZyCodeInput.vue.d.ts +2 -2
  14. package/dist/zy-ui/code-input/index.d.ts +2 -2
  15. package/dist/zy-ui/divider/ZyDivider.vue.d.ts +1 -1
  16. package/dist/zy-ui/divider/index.d.ts +3 -3
  17. package/dist/zy-ui/icon/ZyIcon.vue.d.ts +1 -1
  18. package/dist/zy-ui/icon/index.d.ts +1 -1
  19. package/dist/zy-ui/index.d.ts +62 -46
  20. package/dist/zy-ui/input/ZyInput.vue.d.ts +3 -3
  21. package/dist/zy-ui/input/index.d.ts +3 -3
  22. package/dist/zy-ui/loading/ZyLoading.vue.d.ts +1 -1
  23. package/dist/zy-ui/loading/index.d.ts +1 -1
  24. package/dist/zy-ui/mega-menu/ZyMegaMenu.vue.d.ts +12 -4
  25. package/dist/zy-ui/mega-menu/index.d.ts +16 -0
  26. package/dist/zy-ui/progress/ZyProgress.vue.d.ts +1 -1
  27. package/dist/zy-ui/progress/index.d.ts +3 -3
  28. package/dist/zy-ui/radio/ZyRadioGroup.vue.d.ts +3 -3
  29. package/dist/zy-ui/select/ZySelect.vue.d.ts +1 -1
  30. package/dist/zy-ui/select/index.d.ts +3 -3
  31. package/dist/zy-ui/space/ZySpace.vue.d.ts +1 -1
  32. package/dist/zy-ui/space/index.d.ts +3 -3
  33. package/dist/zy-ui/table/ZyTable.vue.d.ts +3 -3
  34. package/dist/zy-ui/tag/ZyTag.vue.d.ts +2 -2
  35. package/dist/zy-ui/tag/index.d.ts +6 -6
  36. package/dist/zy-ui/themes/basic.css +837 -832
  37. package/dist/zy-ui/themes/material.css +41 -37
  38. package/dist/zy-ui/themes/solid.css +665 -664
  39. package/dist/zy-ui/tree/ZyTree.vue.d.ts +2 -2
  40. package/dist/zy-ui/zy-ui.css +1 -1
  41. package/dist/zy-ui/zy-ui.js +299 -247
  42. package/package.json +82 -82
@@ -1,832 +1,837 @@
1
- /**
2
- * 主题「基础用法 / 图纸」(data-zy-theme="basic")的材质层。
3
- *
4
- * 基础外观主要来自语义令牌与组件自带样式;这一层只补图纸语言与默认结构不同的局部:
5
- * 卡片纸面化、标签小件圆角、控件高度、选择器禁用、树 / 表格行、分页器、日期 / 时间面板等。
6
- * 新增组件时,优先在组件自身和 Token 层完成,只有跨组件的材质差异才放这里。
7
- */
8
-
9
- html[data-zy-theme='basic'] .zy-pagination {
10
- --el-pagination-button-bg-color: var(--zy-surface);
11
- --el-pagination-bg-color: var(--zy-surface);
12
- --el-pagination-border-radius: var(--zy-radius-sm);
13
- --el-pagination-button-width: 28px;
14
- --el-pagination-button-height: 28px;
15
- --el-pagination-button-width-small: 24px;
16
- --el-pagination-button-height-small: 24px;
17
- --el-pagination-item-gap: 12px;
18
- color: var(--zy-ink);
19
- }
20
-
21
- /* 一格的形状:小正方形,键与键之间留缝 */
22
- html[data-zy-theme='basic'] .zy-pagination .el-pager li,
23
- html[data-zy-theme='basic'] .zy-pagination button.btn-prev,
24
- html[data-zy-theme='basic'] .zy-pagination button.btn-next {
25
- width: var(--el-pagination-button-width);
26
- min-width: var(--el-pagination-button-width);
27
- height: var(--el-pagination-button-height);
28
- margin: 0 5px;
29
- padding: 0;
30
- border: 1px solid var(--zy-hairline);
31
- border-radius: var(--zy-radius-sm);
32
- background-color: var(--zy-surface);
33
- color: var(--zy-ink);
34
- font-weight: var(--zy-weight-control);
35
- box-shadow: var(--zy-shadow-card);
36
- transition:
37
- color var(--zy-duration-press) var(--zy-ease-soft),
38
- border-color var(--zy-duration-press) var(--zy-ease-soft),
39
- background-color var(--zy-duration-press) var(--zy-ease-soft);
40
- }
41
-
42
- @media (hover: hover) and (pointer: fine) {
43
- html[data-zy-theme='basic'] .zy-pagination .el-pager li:hover:not(.is-active):not(.more),
44
- html[data-zy-theme='basic'] .zy-pagination button.btn-prev:hover:not(:disabled),
45
- html[data-zy-theme='basic'] .zy-pagination button.btn-next:hover:not(:disabled) {
46
- border-color: var(--zy-brand);
47
- color: var(--zy-brand);
48
- }
49
- }
50
-
51
- /* 选中 = primary 实心按钮:同一张渐变 + 上沿亮边 */
52
- html[data-zy-theme='basic'] .zy-pagination .el-pager li.is-active {
53
- background-image: var(--zy-btn-grad-primary);
54
- background-origin: border-box;
55
- border-color: transparent;
56
- border-top-color: var(--zy-btn-edge-primary);
57
- color: var(--zy-ink-inverse, #fff);
58
- }
59
-
60
- /* 省略号只是一段可点的文字,不占一颗按钮 */
61
- html[data-zy-theme='basic'] .zy-pagination .el-pager li.more {
62
- border-color: transparent;
63
- background: transparent;
64
- box-shadow: none;
65
- color: var(--zy-muted);
66
- }
67
-
68
- html[data-zy-theme='basic'] .zy-pagination button.btn-prev:disabled,
69
- html[data-zy-theme='basic'] .zy-pagination button.btn-next:disabled {
70
- color: var(--zy-placeholder);
71
- background-color: var(--zy-surface-sunken);
72
- border-color: var(--zy-hairline);
73
- box-shadow: none;
74
- }
75
-
76
- html[data-zy-theme='basic'] .zy-pagination .el-pagination__total,
77
- html[data-zy-theme='basic'] .zy-pagination .el-pagination__jump {
78
- color: var(--zy-muted);
79
- }
80
-
81
- /* 卡 = 白纸片(发丝边 + 极轻双层影),键帽只留给键帽主题 */
82
- html[data-zy-theme='basic'] .zy-card {
83
- --zy-card-fill-clr: var(--zy-surface);
84
- --zy-card-fill-ink: var(--zy-ink);
85
- --zy-card-fill-base: var(--zy-hairline);
86
- --zy-card-fill-lift: 0px;
87
- --zy-card-fill-line: var(--zy-hairline);
88
- --zy-card-fill-shadow: var(--zy-shadow-card);
89
- --zy-card-fill-shadow-press: var(--zy-shadow-card);
90
- border: 1px solid var(--zy-hairline);
91
- border-radius: var(--zy-radius);
92
- }
93
-
94
- /* ============================================================
95
- * 13 · 日期选择器(Element Plus 二次封装;单日 + 日期范围)
96
- * 触发框同输入框(白底 + 1px 发丝边;聚焦「描边转主色 + 3px 高亮光环」);
97
- * 弹层是白面板 + 1px 发丝边 + 极轻影;选中的日子是一枚蓝色实心小方块(小件 4px 圆角)。
98
- * 时间选择器有自己的 `.zy-time-picker` 规则,这里只认 --date / --daterange。
99
- * 新组件,不带 :not(.dark):深色档跟着令牌走。
100
- * ============================================================ */
101
-
102
- /* 单日是「输入框套输入框」,日期范围把 wrapper 直接穿在身上 —— 两条都按输入框处理 */
103
- html[data-zy-theme='basic'] .el-date-editor--date .el-input__wrapper,
104
- html[data-zy-theme='basic'] .el-date-editor--daterange {
105
- border-radius: var(--zy-radius);
106
- background-color: var(--zy-surface);
107
- box-shadow: 0 0 0 1px var(--zy-hairline) inset;
108
- }
109
-
110
- html[data-zy-theme='basic'] .el-date-editor--date .el-input__wrapper:hover,
111
- html[data-zy-theme='basic'] .el-date-editor--daterange:hover {
112
- box-shadow: 0 0 0 1px var(--zy-hairline-strong) inset;
113
- }
114
-
115
- /* 聚焦:与 03 输入框同一条 */
116
- html[data-zy-theme='basic'] .el-date-editor--date .el-input__wrapper.is-focus,
117
- html[data-zy-theme='basic'] .el-date-editor--daterange.is-active,
118
- html[data-zy-theme='basic'] .el-date-editor--daterange.is-focus {
119
- box-shadow:
120
- 0 0 0 1px var(--zy-brand) inset,
121
- 0 0 0 3px color-mix(in srgb, var(--zy-brand) 14%, transparent);
122
- }
123
-
124
- /* 弹层:白面板 + 1px 发丝边 + 极轻影 */
125
- html[data-zy-theme='basic'] .el-picker-panel {
126
- border: 1px solid var(--zy-hairline);
127
- border-radius: var(--zy-radius);
128
- background: var(--zy-surface);
129
- box-shadow:
130
- 0 1px 2px rgba(15, 23, 42, 0.04),
131
- 0 8px 24px rgba(15, 23, 42, 0.06);
132
- }
133
-
134
- html[data-zy-theme='basic'] .el-picker-panel .el-date-picker__header-label {
135
- color: var(--zy-ink);
136
- font-weight: 600;
137
- }
138
-
139
- html[data-zy-theme='basic'] .el-picker-panel .el-date-table th {
140
- color: var(--zy-muted);
141
- font-weight: 500;
142
- }
143
-
144
- /* 悬停:只换字色,不加厚度(平面件不靠阴影翻身);已选中的日子不参与,免得把白字染成品牌蓝 */
145
- html[data-zy-theme='basic']
146
- .el-picker-panel
147
- .el-date-table
148
- td.available:not(.current):not(.start-date):not(.end-date):hover
149
- .el-date-table-cell__text {
150
- color: var(--zy-brand);
151
- }
152
-
153
- /* 今天:品牌色字,不抢选中 */
154
- html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.today .el-date-table-cell__text {
155
- color: var(--zy-brand);
156
- font-weight: 600;
157
- }
158
-
159
- /* 范围中段:一层淡品牌底 */
160
- html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.in-range .el-date-table-cell__text {
161
- background-color: var(--zy-brand-soft);
162
- color: var(--zy-brand);
163
- }
164
-
165
- /* 选中 / 范围两端:与分页器选中键同一张上浅下深渐变 + 上沿亮边 + 小件 4px 圆角 */
166
- html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.current:not(.disabled) .el-date-table-cell__text,
167
- html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.start-date .el-date-table-cell__text,
168
- html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.end-date .el-date-table-cell__text {
169
- border: 1px solid transparent;
170
- border-top-color: var(--zy-btn-edge-primary);
171
- border-radius: var(--zy-radius-sm);
172
- background-image: var(--zy-btn-grad-primary);
173
- background-origin: border-box;
174
- color: var(--zy-ink-inverse, #fff);
175
- }
176
-
177
- /* ============================================================
178
- * 21 · 时间选择器(单日 + 时间范围,Element Plus 二次封装)
179
- * 触发框同输入框(白底 + 发丝描边;聚焦「描边转主色 + 3px 光环」);
180
- * 弹层是白面板 + 发丝边 + 极轻影;选中的时分秒用品牌色 + 淡品牌底;页脚浅灰 + 顶发丝线。
181
- * 新组件,不带 :not(.dark):深色档跟着令牌走。
182
- * ============================================================ */
183
-
184
- /* 触发框:单日是一层 wrapper,时间范围把 wrapper 穿在自己身上 —— 两条都按输入框处理 */
185
- html[data-zy-theme='basic'] .zy-time-picker .el-input__wrapper,
186
- html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper {
187
- border-radius: var(--zy-radius);
188
- background-color: var(--zy-surface);
189
- box-shadow: 0 0 0 1px var(--zy-hairline) inset;
190
- }
191
-
192
- html[data-zy-theme='basic'] .zy-time-picker .el-input__wrapper:hover,
193
- html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper:hover {
194
- box-shadow: 0 0 0 1px var(--zy-hairline-strong) inset;
195
- }
196
-
197
- html[data-zy-theme='basic'] .zy-time-picker .el-input__wrapper.is-focus,
198
- html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper.is-active,
199
- html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper.is-focus {
200
- box-shadow:
201
- 0 0 0 1px var(--zy-brand) inset,
202
- 0 0 0 3px color-mix(in srgb, var(--zy-brand) 14%, transparent);
203
- }
204
-
205
- /* 弹层:白面板 + 发丝边 + 极轻影(单日 `.el-time-panel`,范围 `.el-time-range-picker`) */
206
- html[data-zy-theme='basic'] .el-time-panel,
207
- html[data-zy-theme='basic'] .el-time-range-picker {
208
- border: 1px solid var(--zy-hairline);
209
- border-radius: var(--zy-radius);
210
- background: var(--zy-surface);
211
- box-shadow:
212
- 0 1px 2px rgba(15, 23, 42, 0.04),
213
- 0 8px 24px rgba(15, 23, 42, 0.06);
214
- }
215
-
216
- /* 选中的时分秒:品牌色 + 淡品牌底(平面件,不加厚度) */
217
- html[data-zy-theme='basic'] .el-time-panel .el-time-spinner__item.is-active,
218
- html[data-zy-theme='basic'] .el-time-range-picker .el-time-spinner__item.is-active {
219
- border-radius: var(--zy-radius-sm);
220
- background-color: var(--zy-brand-soft);
221
- color: var(--zy-brand);
222
- font-weight: 600;
223
- }
224
-
225
- @media (hover: hover) and (pointer: fine) {
226
- html[data-zy-theme='basic'] .el-time-panel .el-time-spinner__item:hover:not(.is-disabled):not(.is-active),
227
- html[data-zy-theme='basic'] .el-time-range-picker .el-time-spinner__item:hover:not(.is-disabled):not(.is-active) {
228
- border-radius: var(--zy-radius-sm);
229
- background-color: var(--zy-surface-sunken);
230
- }
231
- }
232
-
233
- /* 范围弹层的两栏表头 + 中间分隔线 */
234
- html[data-zy-theme='basic'] .el-time-range-picker__header {
235
- color: var(--zy-muted);
236
- font-weight: 600;
237
- letter-spacing: 0.02em;
238
- }
239
-
240
- html[data-zy-theme='basic'] .el-time-range-picker__cell + .el-time-range-picker__cell {
241
- border-left: 1px solid var(--zy-hairline);
242
- }
243
-
244
- /* 页脚:浅灰面 + 顶发丝线 */
245
- html[data-zy-theme='basic'] .el-time-panel__footer {
246
- border-top: 1px solid var(--zy-hairline);
247
- background: var(--zy-surface-sunken);
248
- }
249
-
250
- /* ============================================================
251
- * 15 · 树形控件 —— 补两块图纸语言里缺的:
252
- * ① 悬停的「滑行高亮」:与主题 B 同一枚元素(.zy-tree-glide,由 ZyTree 自己持有并定位),
253
- * 这里只换成图纸语言的样子 —— 一块浅灰浮层,没有厚度;行自身不再铺底色。
254
- * ② 选中态原来只有一层比背景略深的灰,几乎看不出来:改成浅品牌底 + 品牌字 + 左侧一道品牌标记,
255
- * 与表格「悬停淡蓝 + 首列半格标记」是同一套读法。
256
- * 深色档不套用:按约定深色一律现状设计,所以这一节带 :not(.dark)。
257
- * ============================================================ */
258
-
259
- html[data-zy-theme='basic']:not(.dark) .zy-tree-shell {
260
- position: relative; /* 滑行高亮那枚浮层挂在外壳上 */
261
- }
262
-
263
- html[data-zy-theme='basic']:not(.dark) .zy-tree {
264
- --zy-tree-row: 32px; /* 行高与主题 B 对齐 */
265
- }
266
-
267
- /*
268
- * 行的左右留白与行间缝也和主题 B 对齐(原来只有组件默认的 8px,图标贴着行边)。
269
- * 左侧必须 !important:Element 与组件把缩进写成行内 `padding-left: 0`。
270
- */
271
- html[data-zy-theme='basic']:not(.dark) .zy-tree .el-tree-node__content {
272
- padding-inline: 12px !important;
273
- margin-block: 3px;
274
- }
275
-
276
- html[data-zy-theme='basic']:not(.dark) .zy-tree .el-tree-node__content:hover {
277
- background: transparent;
278
- }
279
-
280
- html[data-zy-theme='basic']:not(.dark) .zy-tree-shell .zy-tree-glide {
281
- position: absolute;
282
- left: 0;
283
- top: 0;
284
- border-radius: var(--zy-radius-sm);
285
- background: var(--zy-surface-sunken);
286
- /* 这层填色在白卡上几乎看不见(#f8fafc vs #fff),按图纸语言补一道 1px 发丝边把它交代出来 */
287
- box-shadow: inset 0 0 0 1px var(--zy-hairline);
288
- opacity: 0;
289
- pointer-events: none;
290
- transition:
291
- transform 220ms var(--zy-ease-out),
292
- width 220ms var(--zy-ease-out),
293
- height 220ms var(--zy-ease-out),
294
- opacity 150ms var(--zy-ease-out);
295
- }
296
-
297
- html[data-zy-theme='basic']:not(.dark) .zy-tree .el-tree-node.is-current > .el-tree-node__content {
298
- background: var(--zy-brand-soft);
299
- color: var(--zy-brand);
300
- font-weight: 600;
301
- }
302
-
303
- /* ============================================================
304
- * 04 · 滑块拼图验证(图纸语言,方案稿):一张纸面 + 一条胶囊轨道。
305
- * 验证区是白面卡(1px 发丝边),缺口是浅灰面 + 发丝边的一块,
306
- * 拼图块 = 实心按钮那张上浅下深渐变,手柄 = 白面 + 描边 + 主色箭头;
307
- * 通过 → 缺口合上、勾与提示转品牌蓝;没对准 → 描边与提示转珊瑚红。
308
- * 新组件,不带 :not(.dark):深色档没有「现状」可沿用,跟着深色令牌走。
309
- * ============================================================ */
310
-
311
- html[data-zy-theme='basic'] .zy-verify__scene {
312
- border: 1px solid var(--zy-hairline);
313
- border-radius: var(--zy-radius);
314
- /* 只给底色:底图(插画)由版面层挂在 background-image 上,别用 background 简写把它冲掉 */
315
- background-color: var(--zy-surface);
316
- }
317
-
318
- /* 缺口 = 图片上挖掉的一块:半透明墨色剪影(图换了它也一直对) */
319
- html[data-zy-theme='basic'] .zy-verify__gap {
320
- background: color-mix(in srgb, var(--zy-ink) 58%, transparent);
321
- }
322
-
323
- html[data-zy-theme='basic'] .zy-verify__gap::after {
324
- background: color-mix(in srgb, var(--zy-ink) 58%, transparent);
325
- }
326
-
327
- /* 拼图块 = 主色实心按钮那张渐变 + 上沿亮边(与分页器选中键逐字相同) */
328
- html[data-zy-theme='basic'] .zy-verify__piece {
329
- border: 1px solid transparent;
330
- border-top-color: var(--zy-btn-edge-primary);
331
- background-image: var(--zy-btn-grad-primary);
332
- background-origin: border-box;
333
- color: var(--zy-ink-inverse, #fff);
334
- }
335
-
336
- /*
337
- * 顶上那颗圆头取渐变的**顶端色**(不是品牌色):方块上沿就是这一档,
338
- * 两者相接处才连成一块,不会出现一个深色圆疙瘩。
339
- */
340
- html[data-zy-theme='basic'] .zy-verify__piece::after {
341
- background: var(--zy-btn-edge-primary);
342
- }
343
-
344
- html[data-zy-theme='basic'] .zy-verify__track {
345
- border: 1px solid var(--zy-hairline);
346
- border-radius: var(--zy-radius);
347
- background: var(--zy-surface-sunken);
348
- color: var(--zy-muted);
349
- }
350
-
351
- html[data-zy-theme='basic'] .zy-verify__fill {
352
- background: var(--zy-brand-soft);
353
- }
354
-
355
- html[data-zy-theme='basic'] .zy-verify__handle {
356
- border: 1px solid var(--zy-hairline-strong);
357
- border-radius: var(--zy-radius-sm);
358
- background: var(--zy-surface);
359
- color: var(--zy-brand);
360
- box-shadow: var(--zy-shadow-card);
361
- transition:
362
- border-color var(--zy-duration-press) var(--zy-ease-soft),
363
- color var(--zy-duration-press) var(--zy-ease-soft);
364
- }
365
-
366
- html[data-zy-theme='basic'] .zy-verify__refresh {
367
- color: var(--zy-muted);
368
- }
369
-
370
- @media (hover: hover) and (pointer: fine) {
371
- html[data-zy-theme='basic'] .zy-verify__handle:hover,
372
- html[data-zy-theme='basic'] .zy-verify.is-dragging .zy-verify__handle {
373
- border-color: var(--zy-brand);
374
- }
375
-
376
- html[data-zy-theme='basic'] .zy-verify__refresh:hover {
377
- color: var(--zy-brand);
378
- }
379
- }
380
-
381
- /* 通过:缺口与描边转品牌蓝,勾露出来 */
382
- html[data-zy-theme='basic'] .zy-verify.is-pass .zy-verify__gap {
383
- border-color: var(--zy-brand);
384
- }
385
-
386
- html[data-zy-theme='basic'] .zy-verify.is-pass .zy-verify__track {
387
- border-color: var(--zy-brand);
388
- color: var(--zy-brand);
389
- }
390
-
391
- /* 没对准:轨道与提示转珊瑚红(danger),手柄也转红 */
392
- html[data-zy-theme='basic'] .zy-verify.is-fail .zy-verify__track {
393
- border-color: var(--zy-danger);
394
- color: var(--zy-danger);
395
- }
396
-
397
- html[data-zy-theme='basic'] .zy-verify.is-fail .zy-verify__handle {
398
- border-color: var(--zy-danger);
399
- color: var(--zy-danger);
400
- }
401
-
402
- /* ============================================================
403
- * 23 · 通用容器(图纸语言):一张纸面卡 —— 白面 + 1px 发丝边 + 极轻双层影。
404
- * 只有**有标题**的那种才分两段,读法与展示板上的卡片逐字相同(.spec-head / .spec-stage):
405
- * **标题栏白面,正文内容区那档浅灰**,两段之间压一道发丝线。
406
- * **无标题的容器通体白面**,不铺灰。
407
- * (结构与版面在 board.css)
408
- * 这一条**不带 :not(.dark)**:容器是新组件,深色档没有「现状」可沿用,
409
- * 让它跟着深色令牌走 —— 深色下自然读成一张石墨纸。
410
- * ============================================================ */
411
-
412
- html[data-zy-theme='basic'] .zy-panel {
413
- border: 1px solid var(--zy-hairline);
414
- border-radius: var(--zy-radius);
415
- background: var(--zy-surface);
416
- box-shadow:
417
- 0 1px 2px rgba(15, 23, 42, 0.04),
418
- 0 8px 24px rgba(15, 23, 42, 0.06);
419
- }
420
-
421
- html[data-zy-theme='basic'] .zy-panel__head {
422
- background: var(--zy-surface);
423
- border-bottom: 1px solid var(--zy-hairline);
424
- }
425
-
426
- /*
427
- * 正文区取的是**卡片内容区那档浅灰**(与展示板的 .spec-stage 同一个配方)。
428
- * 只对有标题的容器生效:`:has(.zy-panel__head)` 就是「有标题」那个条件,
429
- * 无标题的容器没有这一段,正文跟着容器白面走。
430
- */
431
- html[data-zy-theme='basic'] .zy-panel:has(.zy-panel__head) > .zy-panel__body {
432
- background: var(--zy-panel-body-bg);
433
- }
434
-
435
- /* ============================================================
436
- * 24 · 菜单导航(Mega Menu)—— 图纸语言
437
- *
438
- * 条就是一条发丝线(底边);开合态用主色 2px 下划线(图纸里「当前条目」用线标);
439
- * 面板 = 纸片 + 1px 线 + 一层浮影;图标是 1px 线框小方块。
440
- * 悬停不铺在条目上,交给一枚带发丝边的浅灰浮层滑过去(与树 / 下拉面板同一套)。
441
- * 全程没有厚度、没有白弧。
442
- *
443
- * 下面这层 --zy-mm-* 是方案稿里「浅色修正」的那几个值:线更实一档、次要字更深、
444
- * 浅灰台面偏冷。只落在菜单上;要不要推到全局令牌(--zy-hairline 等)等确认。
445
- * ============================================================ */
446
-
447
- html[data-zy-theme='basic'] .zy-mega-menu {
448
- --zy-mm-sunken: #f7f9fa;
449
- --zy-mm-line: #dbe2ea;
450
- --zy-mm-line-strong: #8592a1;
451
- --zy-mm-muted: #5c6b7c;
452
- --zy-mm-brand-soft: rgba(0, 102, 169, 0.08);
453
- }
454
-
455
- /* 深色档跟站点共用一套令牌,不在这里另起色板 */
456
- html.dark[data-zy-theme='basic'] .zy-mega-menu {
457
- --zy-mm-sunken: var(--zy-surface-sunken);
458
- --zy-mm-line: var(--zy-hairline);
459
- --zy-mm-line-strong: var(--zy-hairline-strong);
460
- --zy-mm-muted: var(--zy-muted);
461
- --zy-mm-brand-soft: var(--zy-brand-soft);
462
- }
463
-
464
- html[data-zy-theme='basic'] .zy-mega-menu__bar {
465
- background: var(--zy-surface);
466
- border-bottom: 1px solid var(--zy-mm-line);
467
- }
468
-
469
- html[data-zy-theme='basic'] .zy-mega-menu__mark {
470
- border: 1px solid var(--zy-mm-line-strong);
471
- border-radius: var(--zy-radius-sm);
472
- background: var(--zy-mm-sunken);
473
- color: var(--zy-brand);
474
- font-family: var(--zy-font-mono);
475
- }
476
-
477
- html[data-zy-theme='basic'] .zy-mega-menu__sub {
478
- color: var(--zy-mm-muted);
479
- }
480
-
481
- html[data-zy-theme='basic'] .zy-mega-menu__trigger,
482
- html[data-zy-theme='basic'] .zy-mega-menu__plain {
483
- color: var(--zy-ink);
484
- border-radius: var(--zy-radius-sm) var(--zy-radius-sm) 0 0;
485
- }
486
-
487
- html[data-zy-theme='basic'] .zy-mega-menu__trigger:hover,
488
- html[data-zy-theme='basic'] .zy-mega-menu__plain:hover {
489
- background: var(--zy-mm-sunken);
490
- }
491
-
492
- html[data-zy-theme='basic'] .zy-mega-menu__trigger.is-open {
493
- color: var(--zy-brand);
494
- box-shadow: inset 0 -2px 0 var(--zy-brand);
495
- }
496
-
497
- html[data-zy-theme='basic'] .zy-mega-menu__panel {
498
- background: var(--zy-surface);
499
- border: 1px solid var(--zy-mm-line);
500
- border-radius: var(--zy-radius);
501
- box-shadow: var(--zy-shadow-float);
502
- }
503
-
504
- html[data-zy-theme='basic'] .zy-mega-menu__glide {
505
- border-radius: var(--zy-radius-sm);
506
- background: var(--zy-mm-sunken);
507
- /* 浅灰落在白纸片上也几乎看不见,按图纸语言补一道 1px 发丝边把它交代出来 */
508
- box-shadow: inset 0 0 0 1px var(--zy-mm-line);
509
- }
510
-
511
- html[data-zy-theme='basic'] .zy-mega-menu__ico {
512
- border: 1px solid var(--zy-mm-line);
513
- border-radius: var(--zy-radius-sm);
514
- background: var(--zy-surface);
515
- color: var(--zy-brand);
516
- }
517
-
518
- html[data-zy-theme='basic'] .zy-mega-menu__title,
519
- html[data-zy-theme='basic'] .zy-mega-menu__group-link {
520
- color: var(--zy-ink);
521
- }
522
-
523
- html[data-zy-theme='basic'] .zy-mega-menu__desc,
524
- html[data-zy-theme='basic'] .zy-mega-menu__note {
525
- color: var(--zy-mm-muted);
526
- }
527
-
528
- html[data-zy-theme='basic'] .zy-mega-menu__badge {
529
- color: var(--zy-brand);
530
- background: var(--zy-mm-brand-soft);
531
- border: 1px solid color-mix(in srgb, var(--zy-brand) 26%, transparent);
532
- }
533
-
534
- html[data-zy-theme='basic'] .zy-mega-menu__foot {
535
- border-top: 1px solid var(--zy-mm-line);
536
- }
537
-
538
- html[data-zy-theme='basic'] .zy-mega-menu__more {
539
- color: var(--zy-brand);
540
- }
541
-
542
- html[data-zy-theme='basic'] .zy-mega-menu__card {
543
- border: 1px solid var(--zy-mm-line);
544
- border-radius: var(--zy-radius-sm);
545
- background: var(--zy-mm-sunken);
546
- }
547
-
548
- html[data-zy-theme='basic'] .zy-mega-menu__kicker,
549
- html[data-zy-theme='basic'] .zy-mega-menu__group-title,
550
- html[data-zy-theme='basic'] .zy-mega-menu__card-desc {
551
- color: var(--zy-mm-muted);
552
- }
553
-
554
- html[data-zy-theme='basic'] .zy-mega-menu__group-title {
555
- border-bottom: 1px solid var(--zy-mm-line);
556
- }
557
-
558
- html[data-zy-theme='basic'] .zy-mega-menu__card-title {
559
- color: var(--zy-ink);
560
- }
561
-
562
- html[data-zy-theme='basic'] .zy-mega-menu__group-link {
563
- border-radius: var(--zy-radius-sm);
564
- }
565
-
566
- html[data-zy-theme='basic'] .zy-mega-menu__group-ico {
567
- color: var(--zy-mm-muted);
568
- }
569
-
570
- /*
571
- * =====================================================================
572
- * 0.1 · 图纸 · 夜(data-zy-theme="basic" + html.dark)
573
- * ---------------------------------------------------------------------
574
- * 与键帽主题的 §0.1 相对:图纸只有两级阶梯(底纸 / 纸片),夜里也不补厚度、
575
- * 不加白弧。这一节只做三件事 —— 把纸压成中性石墨、把字换成中性白、
576
- * 把深色下会「读成一道缝」的发丝线与控件线分开。
577
- * 共用色板在 tokens/dark.css,这里只放图纸自己的那份。
578
- * =====================================================================
579
- */
580
- /* =====================================================================
581
- * 1 · 主题 A · 深色(图纸 · 夜)
582
- * ---------------------------------------------------------------------
583
- * 同一张纸,夜里开了一盏台灯:底纸更暗、纸片略亮、边界线比面亮。
584
- * 仍然只有两级阶梯 —— 不为深色补厚度,也不给卡片加白弧(那是 B 的语言)。
585
- * ===================================================================== */
586
-
587
- html.dark[data-zy-theme='basic'] {
588
- /* ---------- 表面:中性石墨,不是蓝黑。
589
- * 浅色档的纸是中性白(#f2f4f6),夜里也应该是中性纸 —— 底色一旦偏蓝,
590
- * 品牌蓝就再也读不出「这是标注」,整页都在发蓝。两级阶梯仍保持 1.14:1。 */
591
- --zy-paper: #0f1014; /* 底纸(页面) */
592
- --zy-surface: #1b1d23; /* 纸片(卡片 / 面板 / 弹层) */
593
- --zy-surface-sunken: #15171c; /* 正文区 / 斑马行 */
594
- --zy-panel-body-bg: #171a1f;
595
-
596
- /* ---------- 字:中性白,不偏蓝 ---------- */
597
- --zy-ink: #ecedef; /* 14.41:1 */
598
- --zy-muted: #a0a6ae; /* 6.88:1 */
599
- --zy-placeholder: #858b94; /* 4.92:1 */
600
-
601
- /* ---------- 线:深色下「发丝线」必须比面亮,否则读成一道缝;控件线要能看清(≥3:1) ---------- */
602
- --zy-hairline: #303339; /* 1.33:1 —— 装饰边界(卡片 / 容器) */
603
- --zy-hairline-strong: #69717c; /* 3.42:1 —— 控件边界 */
604
-
605
- /* ---------- 阴影:深色里影子本来就看不见,压成一层更实的暗角 ---------- */
606
- --zy-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5), 0 8px 24px rgba(0, 0, 0, 0.38);
607
- --zy-shadow-float: 0 18px 44px rgba(0, 0, 0, 0.62);
608
- --zy-shadow-deep: rgba(0, 0, 0, 0.55);
609
- --zy-shadow-press: 0 6px 18px rgba(90, 166, 228, 0.3);
610
-
611
- /* ---------- 表格:表头是台账的栏头,深色下换成深一档的纸 + 浅一档的字 ---------- */
612
- --zy-table-header-bg: #23272e;
613
- --zy-table-header-fg: #d3dae2; /* 10.4:1 */
614
- --zy-table-row-stripe: #15171c;
615
- --zy-table-row-hover: rgba(90, 166, 228, 0.1);
616
-
617
- /* ---------- 实心按钮:仍是「上浅下深」,只是把整段亮度压到白字够读的位置 ---------- */
618
- --zy-btn-grad-primary: linear-gradient(180deg, #2876af 0%, #1d5f92 100%);
619
- --zy-btn-grad-primary-hover: linear-gradient(180deg, #1d5f92 0%, #2876af 100%);
620
- --zy-btn-edge-primary: #5aa6e4;
621
-
622
- --zy-btn-grad-success: linear-gradient(180deg, #38803d 0%, #2c6631 100%);
623
- --zy-btn-grad-success-hover: linear-gradient(180deg, #2c6631 0%, #38803d 100%);
624
- --zy-btn-edge-success: #6cc24a;
625
-
626
- --zy-btn-grad-warning: linear-gradient(180deg, #e8a13a 0%, #c98a2c 100%);
627
- --zy-btn-grad-warning-hover: linear-gradient(180deg, #c98a2c 0%, #e8a13a 100%);
628
- --zy-btn-edge-warning: #ffc46b;
629
-
630
- --zy-btn-grad-info: linear-gradient(180deg, #5f6f80 0%, #46525f 100%);
631
- --zy-btn-grad-info-hover: linear-gradient(180deg, #46525f 0%, #5f6f80 100%);
632
- --zy-btn-edge-info: #9ab0c6;
633
-
634
- /* fill(键帽本体)不是 A 的语言,板上不展示;但令牌仍要给出深色下的正确值,
635
- * 免得别处一用就落回「亮品牌面 + 白字」的 2.4:1。 */
636
- --zy-btn-fill-clr: var(--zy-brand-key);
637
- --zy-btn-fill-ink: #fff;
638
- --zy-btn-fill-ink-on: #fff;
639
- --zy-btn-fill-shade: rgba(255, 255, 255, 0.18);
640
-
641
- --el-border-radius-base: var(--zy-radius);
642
- --el-component-size: var(--zy-control-h);
643
- }
644
-
645
- /* 1.1 卡片:仍是白纸片,只是纸变黑。纸面装饰层(白弧 / 铺色)属于 B 的材质,深色下必须关掉 ——
646
- * 浅色时它们在白面上看不见,深色下会变成两道弧光,等于偷偷给 A 加了厚度。 */
647
- html.dark[data-zy-theme='basic'] .zy-card-fill-wave {
648
- display: none;
649
- }
650
-
651
- /* 1.2 控件:面 = 纸片,边 = 控件档发丝线;聚焦仍是「描边转主色 + 3px 光环」,一点厚度都不加 */
652
- html.dark[data-zy-theme='basic'] .zy-input.is-focus .el-input__wrapper,
653
- html.dark[data-zy-theme='basic'] .zy-select.is-focus .el-select__wrapper {
654
- background-color: var(--zy-surface);
655
- box-shadow: 0 0 0 1px var(--zy-hairline-strong) inset;
656
- }
657
-
658
- @media (hover: hover) and (pointer: fine) {
659
- html.dark[data-zy-theme='basic'] .zy-input.is-focus .el-input__wrapper:hover,
660
- html.dark[data-zy-theme='basic'] .zy-select.is-focus .el-select__wrapper:hover {
661
- box-shadow: 0 0 0 1px var(--zy-brand) inset;
662
- }
663
- }
664
-
665
- html.dark[data-zy-theme='basic'] .zy-input.is-focus .el-input__wrapper.is-focus,
666
- html.dark[data-zy-theme='basic'] .zy-select.is-focus .el-select__wrapper.is-focused {
667
- box-shadow:
668
- 0 0 0 1px var(--zy-brand) inset,
669
- 0 0 0 3px color-mix(in srgb, var(--zy-brand) 22%, transparent);
670
- }
671
-
672
- /* 1.3 实心按钮的两个例外:
673
- * 危险是平色(不是渐变),警示是亮琥珀面 —— 一个要把面压深、一个要把字翻墨。 */
674
- html.dark[data-zy-theme='basic']
675
- .zy-btn.el-button--danger:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill, .is-disabled)) {
676
- --el-button-bg-color: var(--zy-danger-key);
677
- --el-button-border-color: var(--zy-danger-key);
678
- --el-button-hover-bg-color: var(--zy-danger-key-hover);
679
- --el-button-hover-border-color: var(--zy-danger-key-hover);
680
- --el-button-active-bg-color: var(--zy-danger-key-hover);
681
- --el-button-active-border-color: var(--zy-danger-key-hover);
682
- --el-button-text-color: #fff;
683
- --el-button-hover-text-color: #fff;
684
- --el-button-active-text-color: #fff;
685
- }
686
-
687
- html.dark[data-zy-theme='basic'] .zy-btn.el-button--warning {
688
- --el-button-text-color: var(--zy-warning-ink);
689
- --el-button-hover-text-color: var(--zy-warning-ink);
690
- --el-button-active-text-color: var(--zy-warning-ink);
691
- }
692
-
693
- /* 禁用:浅色档是「叠一层 50% 白」把键洗淡;深色下换成叠一层底纸色,才读成「按不动」而不是「在发光」 */
694
- html.dark[data-zy-theme='basic']
695
- .zy-btn.el-button--primary.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)),
696
- html.dark[data-zy-theme='basic']
697
- .zy-btn.el-button--success.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)),
698
- html.dark[data-zy-theme='basic']
699
- .zy-btn.el-button--warning.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)),
700
- html.dark[data-zy-theme='basic']
701
- .zy-btn.el-button--info.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)) {
702
- background-image: linear-gradient(rgba(10, 16, 23, 0.45), rgba(10, 16, 23, 0.45)),
703
- var(--zy-btn-grad);
704
- background-origin: border-box;
705
- }
706
-
707
- /* sweep 的字与描边取亮档品牌色(--zy-brand),在深色纸面上仍然清楚 */
708
-
709
- /* 1.4 弹层:浅色档那块「白面板 + 发丝边 + 极轻影」在深色下换成纸片 + 线 + 一层实影 */
710
- html.dark[data-zy-theme='basic'] .zy-panel {
711
- box-shadow: var(--zy-shadow-card);
712
- }
713
-
714
- html.dark[data-zy-theme='basic'] .el-picker-panel,
715
- html.dark[data-zy-theme='basic'] .el-time-panel,
716
- html.dark[data-zy-theme='basic'] .el-time-range-picker {
717
- border: 1px solid var(--zy-hairline);
718
- background: var(--zy-surface);
719
- box-shadow: var(--zy-shadow-card);
720
- }
721
-
722
- html.dark[data-zy-theme='basic'] .el-time-panel__footer {
723
- border-top: 1px solid var(--zy-hairline);
724
- background: var(--zy-surface-sunken);
725
- }
726
-
727
- /* 1.5 表格 / 树:深色档不套 `:not(.dark)`,所以把图纸语言那两块原样补回来,只换填充色 */
728
- html.dark[data-zy-theme='basic'] .zy-tree-shell {
729
- position: relative;
730
- }
731
-
732
- html.dark[data-zy-theme='basic'] .zy-tree {
733
- --zy-tree-row: 32px;
734
- }
735
-
736
- html.dark[data-zy-theme='basic'] .zy-tree .el-tree-node__content {
737
- padding-inline: 12px !important;
738
- margin-block: 3px;
739
- }
740
-
741
- html.dark[data-zy-theme='basic'] .zy-tree .el-tree-node__content:hover {
742
- background: transparent;
743
- }
744
-
745
- html.dark[data-zy-theme='basic'] .zy-tree-shell .zy-tree-glide {
746
- position: absolute;
747
- left: 0;
748
- top: 0;
749
- border-radius: var(--zy-radius-sm);
750
- /* 深色下「悬停」是提亮,不是加深:一层 6% 白 + 一圈线 */
751
- background: rgba(255, 255, 255, 0.06);
752
- box-shadow: inset 0 0 0 1px var(--zy-hairline);
753
- opacity: 0;
754
- pointer-events: none;
755
- transition:
756
- transform 220ms var(--zy-ease-out),
757
- width 220ms var(--zy-ease-out),
758
- height 220ms var(--zy-ease-out),
759
- opacity 150ms var(--zy-ease-out);
760
- }
761
-
762
- html.dark[data-zy-theme='basic'] .zy-tree .el-tree-node.is-current > .el-tree-node__content {
763
- background: var(--zy-brand-soft);
764
- color: var(--zy-brand);
765
- font-weight: 600;
766
- }
767
-
768
- /* 1.6 对话框:账本头条(品牌渐变 + 2px 线)在深色下保留;线色统一在第 0.8 节改成品牌色 */
769
- html.dark[data-zy-theme='basic'] .zy-dialog .el-dialog__header {
770
- background: linear-gradient(180deg, var(--zy-brand-soft) 0%, var(--zy-surface) 72%);
771
- }
772
-
773
- html.dark[data-zy-theme='basic'] .zy-dialog .el-dialog__footer {
774
- background: var(--zy-surface-sunken);
775
- }
776
-
777
- /* 1.7 滑块拼图验证:缺口是「图上挖掉的一块」,浅色档用墨色剪影;深色档 ink 变浅了,
778
- * 剪影必须显式回到黑,否则会变成一块发亮的补丁。 */
779
- html.dark[data-zy-theme='basic'] .zy-verify__gap,
780
- html.dark[data-zy-theme='basic'] .zy-verify__gap::after {
781
- background: color-mix(in srgb, #000 55%, transparent);
782
- }
783
-
784
- /* 1.8 复选框:勾选面取「实心键面」那一档(白勾 4.88:1)。
785
- * 浅色档这里直接用 --zy-brand #0066a9,深色下它变成亮档 #5aa6e4 —— 白勾只剩 2.4:1,
786
- * 所以面必须换回 --zy-brand-key。这一类「--zy-brand 被当面色用」的位置在深色下都要逐个换。 */
787
- html.dark[data-zy-theme='basic'] .zy-check .el-checkbox__input:not(.is-disabled).is-checked .el-checkbox__inner,
788
- html.dark[data-zy-theme='basic'] .zy-check .el-checkbox__input:not(.is-disabled).is-indeterminate .el-checkbox__inner,
789
- html.dark[data-zy-theme='basic'] .zy-tree .el-checkbox__input:not(.is-disabled).is-checked .el-checkbox__inner,
790
- html.dark[data-zy-theme='basic'] .zy-tree .el-checkbox__input:not(.is-disabled).is-indeterminate .el-checkbox__inner {
791
- background-color: var(--zy-brand-key);
792
- border-color: var(--zy-brand-key);
793
- }
794
-
795
- /* 1.9 舞台:浅色档用「底纸 70% 叠在卡片上」把舞台调灰一档;深色下这个半透明叠色会
796
- * 把舞台压到比底纸更暗(叠的是石墨卡片,不是白卡),层级方向就反了 —— 深色下直接给底纸。 */
797
-
798
- /* ---------------------------------------------------------------------
799
- * 收尾两笔(方案稿 0.8 的 A 侧)
800
- * ------------------------------------------------------------------- */
801
-
802
- /* ① 对话框抬头那道 2px 线在组件里写死成绿:A 的语言里只有「蓝墨 + 纸」,
803
- * 夜里换成品牌色压深一档的那条,读起来仍是「抬头」,不是状态条。 */
804
- html.dark[data-zy-theme='basic'] .zy-dialog .el-dialog__header {
805
- box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--zy-brand) 78%, var(--zy-surface));
806
- }
807
-
808
- /* ② 实心标签:A 的「面」取深档键面 —— 共用板把字档语义色提亮成夜间可读的亮色,
809
- * 那张亮色当「面」时白字只有 2.0–2.7:1;面换深档后 4.86–5.19:1。 */
810
- html.dark[data-zy-theme='basic'] .zy-tag.is-fill {
811
- --zy-tag-fill-clr: var(--zy-brand-key);
812
- }
813
-
814
- html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--success {
815
- --zy-tag-fill-clr: var(--zy-green-key);
816
- }
817
-
818
- html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--warning {
819
- --zy-tag-fill-clr: var(--zy-warning-key);
820
- /* 琥珀面上白字 2.19:1,字跟着面走:换深墨(9.19:1) */
821
- color: var(--zy-warning-ink);
822
- --el-tag-text-color: var(--zy-warning-ink);
823
- --el-tag-hover-color: var(--zy-warning-ink);
824
- }
825
-
826
- html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--danger {
827
- --zy-tag-fill-clr: var(--zy-danger-key);
828
- }
829
-
830
- html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--info {
831
- --zy-tag-fill-clr: var(--zy-info-key);
832
- }
1
+ /**
2
+ * 主题「基础用法 / 图纸」(data-zy-theme="basic")的材质层。
3
+ *
4
+ * 基础外观主要来自语义令牌与组件自带样式;这一层只补图纸语言与默认结构不同的局部:
5
+ * 卡片纸面化、标签小件圆角、控件高度、选择器禁用、树 / 表格行、分页器、日期 / 时间面板等。
6
+ * 新增组件时,优先在组件自身和 Token 层完成,只有跨组件的材质差异才放这里。
7
+ */
8
+
9
+ html[data-zy-theme='basic'] .zy-pagination {
10
+ --el-pagination-button-bg-color: var(--zy-surface);
11
+ --el-pagination-bg-color: var(--zy-surface);
12
+ --el-pagination-border-radius: var(--zy-radius-sm);
13
+ --el-pagination-button-width: 28px;
14
+ --el-pagination-button-height: 28px;
15
+ --el-pagination-button-width-small: 24px;
16
+ --el-pagination-button-height-small: 24px;
17
+ --el-pagination-item-gap: 12px;
18
+ color: var(--zy-ink);
19
+ }
20
+
21
+ /* 一格的形状:小正方形,键与键之间留缝 */
22
+ html[data-zy-theme='basic'] .zy-pagination .el-pager li,
23
+ html[data-zy-theme='basic'] .zy-pagination button.btn-prev,
24
+ html[data-zy-theme='basic'] .zy-pagination button.btn-next {
25
+ width: var(--el-pagination-button-width);
26
+ min-width: var(--el-pagination-button-width);
27
+ height: var(--el-pagination-button-height);
28
+ margin: 0 5px;
29
+ padding: 0;
30
+ border: 1px solid var(--zy-hairline);
31
+ border-radius: var(--zy-radius-sm);
32
+ background-color: var(--zy-surface);
33
+ color: var(--zy-ink);
34
+ font-weight: var(--zy-weight-control);
35
+ box-shadow: var(--zy-shadow-card);
36
+ transition:
37
+ color var(--zy-duration-press) var(--zy-ease-soft),
38
+ border-color var(--zy-duration-press) var(--zy-ease-soft),
39
+ background-color var(--zy-duration-press) var(--zy-ease-soft);
40
+ }
41
+
42
+ @media (hover: hover) and (pointer: fine) {
43
+ html[data-zy-theme='basic'] .zy-pagination .el-pager li:hover:not(.is-active):not(.more),
44
+ html[data-zy-theme='basic'] .zy-pagination button.btn-prev:hover:not(:disabled),
45
+ html[data-zy-theme='basic'] .zy-pagination button.btn-next:hover:not(:disabled) {
46
+ border-color: var(--zy-brand);
47
+ color: var(--zy-brand);
48
+ }
49
+ }
50
+
51
+ /* 选中 = primary 实心按钮:同一张渐变 + 上沿亮边 */
52
+ html[data-zy-theme='basic'] .zy-pagination .el-pager li.is-active {
53
+ background-image: var(--zy-btn-grad-primary);
54
+ background-origin: border-box;
55
+ border-color: transparent;
56
+ border-top-color: var(--zy-btn-edge-primary);
57
+ color: var(--zy-ink-inverse, #fff);
58
+ }
59
+
60
+ /* 省略号只是一段可点的文字,不占一颗按钮 */
61
+ html[data-zy-theme='basic'] .zy-pagination .el-pager li.more {
62
+ border-color: transparent;
63
+ background: transparent;
64
+ box-shadow: none;
65
+ color: var(--zy-muted);
66
+ }
67
+
68
+ html[data-zy-theme='basic'] .zy-pagination button.btn-prev:disabled,
69
+ html[data-zy-theme='basic'] .zy-pagination button.btn-next:disabled {
70
+ color: var(--zy-placeholder);
71
+ background-color: var(--zy-surface-sunken);
72
+ border-color: var(--zy-hairline);
73
+ box-shadow: none;
74
+ }
75
+
76
+ html[data-zy-theme='basic'] .zy-pagination .el-pagination__total,
77
+ html[data-zy-theme='basic'] .zy-pagination .el-pagination__jump {
78
+ color: var(--zy-muted);
79
+ }
80
+
81
+ /* 卡 = 白纸片(发丝边 + 极轻双层影),键帽只留给键帽主题 */
82
+ html[data-zy-theme='basic'] .zy-card {
83
+ --zy-card-fill-clr: var(--zy-surface);
84
+ --zy-card-fill-ink: var(--zy-ink);
85
+ --zy-card-fill-base: var(--zy-hairline);
86
+ --zy-card-fill-lift: 0px;
87
+ --zy-card-fill-line: var(--zy-hairline);
88
+ --zy-card-fill-shadow: var(--zy-shadow-card);
89
+ --zy-card-fill-shadow-press: var(--zy-shadow-card);
90
+ border: 1px solid var(--zy-hairline);
91
+ border-radius: var(--zy-radius);
92
+ }
93
+
94
+ /* ============================================================
95
+ * 13 · 日期选择器(Element Plus 二次封装;单日 + 日期范围)
96
+ * 触发框同输入框(白底 + 1px 发丝边;聚焦「描边转主色 + 3px 高亮光环」);
97
+ * 弹层是白面板 + 1px 发丝边 + 极轻影;选中的日子是一枚蓝色实心小方块(小件 4px 圆角)。
98
+ * 时间选择器有自己的 `.zy-time-picker` 规则,这里只认 --date / --daterange。
99
+ * 新组件,不带 :not(.dark):深色档跟着令牌走。
100
+ * ============================================================ */
101
+
102
+ /* 单日是「输入框套输入框」,日期范围把 wrapper 直接穿在身上 —— 两条都按输入框处理 */
103
+ html[data-zy-theme='basic'] .el-date-editor--date .el-input__wrapper,
104
+ html[data-zy-theme='basic'] .el-date-editor--daterange {
105
+ border-radius: var(--zy-radius);
106
+ background-color: var(--zy-surface);
107
+ box-shadow: 0 0 0 1px var(--zy-hairline) inset;
108
+ }
109
+
110
+ html[data-zy-theme='basic'] .el-date-editor--date .el-input__wrapper:hover,
111
+ html[data-zy-theme='basic'] .el-date-editor--daterange:hover {
112
+ box-shadow: 0 0 0 1px var(--zy-hairline-strong) inset;
113
+ }
114
+
115
+ /* 聚焦:与 03 输入框同一条 */
116
+ html[data-zy-theme='basic'] .el-date-editor--date .el-input__wrapper.is-focus,
117
+ html[data-zy-theme='basic'] .el-date-editor--daterange.is-active,
118
+ html[data-zy-theme='basic'] .el-date-editor--daterange.is-focus {
119
+ box-shadow:
120
+ 0 0 0 1px var(--zy-brand) inset,
121
+ 0 0 0 3px color-mix(in srgb, var(--zy-brand) 14%, transparent);
122
+ }
123
+
124
+ /* 弹层:白面板 + 1px 发丝边 + 极轻影 */
125
+ html[data-zy-theme='basic'] .el-picker-panel {
126
+ border: 1px solid var(--zy-hairline);
127
+ border-radius: var(--zy-radius);
128
+ background: var(--zy-surface);
129
+ box-shadow:
130
+ 0 1px 2px rgba(15, 23, 42, 0.04),
131
+ 0 8px 24px rgba(15, 23, 42, 0.06);
132
+ }
133
+
134
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-picker__header-label {
135
+ color: var(--zy-ink);
136
+ font-weight: 600;
137
+ }
138
+
139
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-table th {
140
+ color: var(--zy-muted);
141
+ font-weight: 500;
142
+ }
143
+
144
+ /* 悬停:只换字色,不加厚度(平面件不靠阴影翻身);已选中的日子不参与,免得把白字染成品牌蓝 */
145
+ html[data-zy-theme='basic']
146
+ .el-picker-panel
147
+ .el-date-table
148
+ td.available:not(.current):not(.start-date):not(.end-date):hover
149
+ .el-date-table-cell__text {
150
+ color: var(--zy-brand);
151
+ }
152
+
153
+ /* 今天:品牌色字,不抢选中 */
154
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.today .el-date-table-cell__text {
155
+ color: var(--zy-brand);
156
+ font-weight: 600;
157
+ }
158
+
159
+ /* 范围中段:一层淡品牌底 */
160
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.in-range .el-date-table-cell__text {
161
+ background-color: var(--zy-brand-soft);
162
+ color: var(--zy-brand);
163
+ }
164
+
165
+ /* 选中 / 范围两端:与分页器选中键同一张上浅下深渐变 + 上沿亮边 + 小件 4px 圆角 */
166
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.current:not(.disabled) .el-date-table-cell__text,
167
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.start-date .el-date-table-cell__text,
168
+ html[data-zy-theme='basic'] .el-picker-panel .el-date-table td.end-date .el-date-table-cell__text {
169
+ border: 1px solid transparent;
170
+ border-top-color: var(--zy-btn-edge-primary);
171
+ border-radius: var(--zy-radius-sm);
172
+ background-image: var(--zy-btn-grad-primary);
173
+ background-origin: border-box;
174
+ color: var(--zy-ink-inverse, #fff);
175
+ }
176
+
177
+ /* ============================================================
178
+ * 21 · 时间选择器(单日 + 时间范围,Element Plus 二次封装)
179
+ * 触发框同输入框(白底 + 发丝描边;聚焦「描边转主色 + 3px 光环」);
180
+ * 弹层是白面板 + 发丝边 + 极轻影;选中的时分秒用品牌色 + 淡品牌底;页脚浅灰 + 顶发丝线。
181
+ * 新组件,不带 :not(.dark):深色档跟着令牌走。
182
+ * ============================================================ */
183
+
184
+ /* 触发框:单日是一层 wrapper,时间范围把 wrapper 穿在自己身上 —— 两条都按输入框处理 */
185
+ html[data-zy-theme='basic'] .zy-time-picker .el-input__wrapper,
186
+ html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper {
187
+ border-radius: var(--zy-radius);
188
+ background-color: var(--zy-surface);
189
+ box-shadow: 0 0 0 1px var(--zy-hairline) inset;
190
+ }
191
+
192
+ html[data-zy-theme='basic'] .zy-time-picker .el-input__wrapper:hover,
193
+ html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper:hover {
194
+ box-shadow: 0 0 0 1px var(--zy-hairline-strong) inset;
195
+ }
196
+
197
+ html[data-zy-theme='basic'] .zy-time-picker .el-input__wrapper.is-focus,
198
+ html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper.is-active,
199
+ html[data-zy-theme='basic'] .zy-time-picker.el-input__wrapper.is-focus {
200
+ box-shadow:
201
+ 0 0 0 1px var(--zy-brand) inset,
202
+ 0 0 0 3px color-mix(in srgb, var(--zy-brand) 14%, transparent);
203
+ }
204
+
205
+ /* 弹层:白面板 + 发丝边 + 极轻影(单日 `.el-time-panel`,范围 `.el-time-range-picker`) */
206
+ html[data-zy-theme='basic'] .el-time-panel,
207
+ html[data-zy-theme='basic'] .el-time-range-picker {
208
+ border: 1px solid var(--zy-hairline);
209
+ border-radius: var(--zy-radius);
210
+ background: var(--zy-surface);
211
+ box-shadow:
212
+ 0 1px 2px rgba(15, 23, 42, 0.04),
213
+ 0 8px 24px rgba(15, 23, 42, 0.06);
214
+ }
215
+
216
+ /* 选中的时分秒:品牌色 + 淡品牌底(平面件,不加厚度) */
217
+ html[data-zy-theme='basic'] .el-time-panel .el-time-spinner__item.is-active,
218
+ html[data-zy-theme='basic'] .el-time-range-picker .el-time-spinner__item.is-active {
219
+ border-radius: var(--zy-radius-sm);
220
+ background-color: var(--zy-brand-soft);
221
+ color: var(--zy-brand);
222
+ font-weight: 600;
223
+ }
224
+
225
+ @media (hover: hover) and (pointer: fine) {
226
+ html[data-zy-theme='basic'] .el-time-panel .el-time-spinner__item:hover:not(.is-disabled):not(.is-active),
227
+ html[data-zy-theme='basic'] .el-time-range-picker .el-time-spinner__item:hover:not(.is-disabled):not(.is-active) {
228
+ border-radius: var(--zy-radius-sm);
229
+ background-color: var(--zy-surface-sunken);
230
+ }
231
+ }
232
+
233
+ /* 范围弹层的两栏表头 + 中间分隔线 */
234
+ html[data-zy-theme='basic'] .el-time-range-picker__header {
235
+ color: var(--zy-muted);
236
+ font-weight: 600;
237
+ letter-spacing: 0.02em;
238
+ }
239
+
240
+ html[data-zy-theme='basic'] .el-time-range-picker__cell + .el-time-range-picker__cell {
241
+ border-left: 1px solid var(--zy-hairline);
242
+ }
243
+
244
+ /* 页脚:浅灰面 + 顶发丝线 */
245
+ html[data-zy-theme='basic'] .el-time-panel__footer {
246
+ border-top: 1px solid var(--zy-hairline);
247
+ background: var(--zy-surface-sunken);
248
+ }
249
+
250
+ /* ============================================================
251
+ * 15 · 树形控件 —— 补两块图纸语言里缺的:
252
+ * ① 悬停的「滑行高亮」:与主题 B 同一枚元素(.zy-tree-glide,由 ZyTree 自己持有并定位),
253
+ * 这里只换成图纸语言的样子 —— 一块浅灰浮层,没有厚度;行自身不再铺底色。
254
+ * ② 选中态原来只有一层比背景略深的灰,几乎看不出来:改成浅品牌底 + 品牌字 + 左侧一道品牌标记,
255
+ * 与表格「悬停淡蓝 + 首列半格标记」是同一套读法。
256
+ * 深色档不套用:按约定深色一律现状设计,所以这一节带 :not(.dark)。
257
+ * ============================================================ */
258
+
259
+ html[data-zy-theme='basic']:not(.dark) .zy-tree-shell {
260
+ position: relative; /* 滑行高亮那枚浮层挂在外壳上 */
261
+ }
262
+
263
+ html[data-zy-theme='basic']:not(.dark) .zy-tree {
264
+ --zy-tree-row: 32px; /* 行高与主题 B 对齐 */
265
+ }
266
+
267
+ /*
268
+ * 行的左右留白与行间缝也和主题 B 对齐(原来只有组件默认的 8px,图标贴着行边)。
269
+ * 左侧必须 !important:Element 与组件把缩进写成行内 `padding-left: 0`。
270
+ */
271
+ html[data-zy-theme='basic']:not(.dark) .zy-tree .el-tree-node__content {
272
+ padding-inline: 12px !important;
273
+ margin-block: 3px;
274
+ }
275
+
276
+ html[data-zy-theme='basic']:not(.dark) .zy-tree .el-tree-node__content:hover {
277
+ background: transparent;
278
+ }
279
+
280
+ html[data-zy-theme='basic']:not(.dark) .zy-tree-shell .zy-tree-glide {
281
+ position: absolute;
282
+ left: 0;
283
+ top: 0;
284
+ border-radius: var(--zy-radius-sm);
285
+ background: var(--zy-surface-sunken);
286
+ /* 这层填色在白卡上几乎看不见(#f8fafc vs #fff),按图纸语言补一道 1px 发丝边把它交代出来 */
287
+ box-shadow: inset 0 0 0 1px var(--zy-hairline);
288
+ opacity: 0;
289
+ pointer-events: none;
290
+ transition:
291
+ transform 220ms var(--zy-ease-out),
292
+ width 220ms var(--zy-ease-out),
293
+ height 220ms var(--zy-ease-out),
294
+ opacity 150ms var(--zy-ease-out);
295
+ }
296
+
297
+ html[data-zy-theme='basic']:not(.dark) .zy-tree .el-tree-node.is-current > .el-tree-node__content {
298
+ background: var(--zy-brand-soft);
299
+ color: var(--zy-brand);
300
+ font-weight: 600;
301
+ }
302
+
303
+ /* ============================================================
304
+ * 04 · 滑块拼图验证(图纸语言,方案稿):一张纸面 + 一条胶囊轨道。
305
+ * 验证区是白面卡(1px 发丝边),缺口是浅灰面 + 发丝边的一块,
306
+ * 拼图块 = 实心按钮那张上浅下深渐变,手柄 = 白面 + 描边 + 主色箭头;
307
+ * 通过 → 缺口合上、勾与提示转品牌蓝;没对准 → 描边与提示转珊瑚红。
308
+ * 新组件,不带 :not(.dark):深色档没有「现状」可沿用,跟着深色令牌走。
309
+ * ============================================================ */
310
+
311
+ html[data-zy-theme='basic'] .zy-verify__scene {
312
+ border: 1px solid var(--zy-hairline);
313
+ border-radius: var(--zy-radius);
314
+ /* 只给底色:底图(插画)由版面层挂在 background-image 上,别用 background 简写把它冲掉 */
315
+ background-color: var(--zy-surface);
316
+ }
317
+
318
+ /* 缺口 = 图片上挖掉的一块:半透明墨色剪影(图换了它也一直对) */
319
+ html[data-zy-theme='basic'] .zy-verify__gap {
320
+ background: color-mix(in srgb, var(--zy-ink) 58%, transparent);
321
+ }
322
+
323
+ html[data-zy-theme='basic'] .zy-verify__gap::after {
324
+ background: color-mix(in srgb, var(--zy-ink) 58%, transparent);
325
+ }
326
+
327
+ /* 拼图块 = 主色实心按钮那张渐变 + 上沿亮边(与分页器选中键逐字相同) */
328
+ html[data-zy-theme='basic'] .zy-verify__piece {
329
+ border: 1px solid transparent;
330
+ border-top-color: var(--zy-btn-edge-primary);
331
+ background-image: var(--zy-btn-grad-primary);
332
+ background-origin: border-box;
333
+ color: var(--zy-ink-inverse, #fff);
334
+ }
335
+
336
+ /*
337
+ * 顶上那颗圆头取渐变的**顶端色**(不是品牌色):方块上沿就是这一档,
338
+ * 两者相接处才连成一块,不会出现一个深色圆疙瘩。
339
+ */
340
+ html[data-zy-theme='basic'] .zy-verify__piece::after {
341
+ background: var(--zy-btn-edge-primary);
342
+ }
343
+
344
+ html[data-zy-theme='basic'] .zy-verify__track {
345
+ border: 1px solid var(--zy-hairline);
346
+ border-radius: var(--zy-radius);
347
+ background: var(--zy-surface-sunken);
348
+ color: var(--zy-muted);
349
+ }
350
+
351
+ html[data-zy-theme='basic'] .zy-verify__fill {
352
+ background: var(--zy-brand-soft);
353
+ }
354
+
355
+ html[data-zy-theme='basic'] .zy-verify__handle {
356
+ border: 1px solid var(--zy-hairline-strong);
357
+ border-radius: var(--zy-radius-sm);
358
+ background: var(--zy-surface);
359
+ color: var(--zy-brand);
360
+ box-shadow: var(--zy-shadow-card);
361
+ transition:
362
+ border-color var(--zy-duration-press) var(--zy-ease-soft),
363
+ color var(--zy-duration-press) var(--zy-ease-soft);
364
+ }
365
+
366
+ html[data-zy-theme='basic'] .zy-verify__refresh {
367
+ color: var(--zy-muted);
368
+ }
369
+
370
+ @media (hover: hover) and (pointer: fine) {
371
+ html[data-zy-theme='basic'] .zy-verify__handle:hover,
372
+ html[data-zy-theme='basic'] .zy-verify.is-dragging .zy-verify__handle {
373
+ border-color: var(--zy-brand);
374
+ }
375
+
376
+ html[data-zy-theme='basic'] .zy-verify__refresh:hover {
377
+ color: var(--zy-brand);
378
+ }
379
+ }
380
+
381
+ /* 通过:缺口与描边转品牌蓝,勾露出来 */
382
+ html[data-zy-theme='basic'] .zy-verify.is-pass .zy-verify__gap {
383
+ border-color: var(--zy-brand);
384
+ }
385
+
386
+ html[data-zy-theme='basic'] .zy-verify.is-pass .zy-verify__track {
387
+ border-color: var(--zy-brand);
388
+ color: var(--zy-brand);
389
+ }
390
+
391
+ /* 没对准:轨道与提示转珊瑚红(danger),手柄也转红 */
392
+ html[data-zy-theme='basic'] .zy-verify.is-fail .zy-verify__track {
393
+ border-color: var(--zy-danger);
394
+ color: var(--zy-danger);
395
+ }
396
+
397
+ html[data-zy-theme='basic'] .zy-verify.is-fail .zy-verify__handle {
398
+ border-color: var(--zy-danger);
399
+ color: var(--zy-danger);
400
+ }
401
+
402
+ /* ============================================================
403
+ * 23 · 通用容器(图纸语言):一张纸面卡 —— 白面 + 1px 发丝边 + 极轻双层影。
404
+ * 只有**有标题**的那种才分两段,读法与展示板上的卡片逐字相同(.spec-head / .spec-stage):
405
+ * **标题栏白面,正文内容区那档浅灰**,两段之间压一道发丝线。
406
+ * **无标题的容器通体白面**,不铺灰。
407
+ * (结构与版面在 board.css)
408
+ * 这一条**不带 :not(.dark)**:容器是新组件,深色档没有「现状」可沿用,
409
+ * 让它跟着深色令牌走 —— 深色下自然读成一张石墨纸。
410
+ * ============================================================ */
411
+
412
+ html[data-zy-theme='basic'] .zy-panel {
413
+ border: 1px solid var(--zy-hairline);
414
+ border-radius: var(--zy-radius);
415
+ background: var(--zy-surface);
416
+ box-shadow:
417
+ 0 1px 2px rgba(15, 23, 42, 0.04),
418
+ 0 8px 24px rgba(15, 23, 42, 0.06);
419
+ }
420
+
421
+ html[data-zy-theme='basic'] .zy-panel__head {
422
+ background: var(--zy-surface);
423
+ border-bottom: 1px solid var(--zy-hairline);
424
+ }
425
+
426
+ /*
427
+ * 正文区取的是**卡片内容区那档浅灰**(与展示板的 .spec-stage 同一个配方)。
428
+ * 只对有标题的容器生效:`:has(.zy-panel__head)` 就是「有标题」那个条件,
429
+ * 无标题的容器没有这一段,正文跟着容器白面走。
430
+ */
431
+ html[data-zy-theme='basic'] .zy-panel:has(.zy-panel__head) > .zy-panel__body {
432
+ background: var(--zy-panel-body-bg);
433
+ }
434
+
435
+ /* ============================================================
436
+ * 24 · 菜单导航(Mega Menu)—— 图纸语言
437
+ *
438
+ * 条就是一条发丝线(底边);开合态用主色 2px 下划线(图纸里「当前条目」用线标);
439
+ * 面板 = 纸片 + 1px 线 + 一层浮影;图标是 1px 线框小方块。
440
+ * 悬停不铺在条目上,交给一枚带发丝边的浅灰浮层滑过去(与树 / 下拉面板同一套)。
441
+ * 全程没有厚度、没有白弧。
442
+ *
443
+ * 下面这层 --zy-mm-* 是方案稿里「浅色修正」的那几个值:线更实一档、次要字更深、
444
+ * 浅灰台面偏冷。只落在菜单上;要不要推到全局令牌(--zy-hairline 等)等确认。
445
+ * ============================================================ */
446
+
447
+ html[data-zy-theme='basic'] .zy-mega-menu {
448
+ --zy-mm-sunken: #f7f9fa;
449
+ --zy-mm-line: #dbe2ea;
450
+ --zy-mm-line-strong: #8592a1;
451
+ --zy-mm-muted: #5c6b7c;
452
+ --zy-mm-brand-soft: rgba(0, 102, 169, 0.08);
453
+ }
454
+
455
+ /* 深色档跟站点共用一套令牌,不在这里另起色板 */
456
+ html.dark[data-zy-theme='basic'] .zy-mega-menu {
457
+ --zy-mm-sunken: var(--zy-surface-sunken);
458
+ --zy-mm-line: var(--zy-hairline);
459
+ --zy-mm-line-strong: var(--zy-hairline-strong);
460
+ --zy-mm-muted: var(--zy-muted);
461
+ --zy-mm-brand-soft: var(--zy-brand-soft);
462
+ }
463
+
464
+ html[data-zy-theme='basic'] .zy-mega-menu__bar {
465
+ background: var(--zy-surface);
466
+ border-bottom: 1px solid var(--zy-mm-line);
467
+ }
468
+
469
+ html[data-zy-theme='basic'] .zy-mega-menu__mark {
470
+ border: 1px solid var(--zy-mm-line-strong);
471
+ border-radius: var(--zy-radius-sm);
472
+ background: var(--zy-mm-sunken);
473
+ color: var(--zy-brand);
474
+ font-family: var(--zy-font-mono);
475
+ }
476
+
477
+ html[data-zy-theme='basic'] .zy-mega-menu__sub {
478
+ color: var(--zy-mm-muted);
479
+ }
480
+
481
+ html[data-zy-theme='basic'] .zy-mega-menu__trigger,
482
+ html[data-zy-theme='basic'] .zy-mega-menu__plain {
483
+ color: var(--zy-ink);
484
+ border-radius: var(--zy-radius-sm) var(--zy-radius-sm) 0 0;
485
+ }
486
+
487
+ /* 悬停与选中共用同一套底色:选中态常亮,指针离开也留着 */
488
+ html[data-zy-theme='basic'] .zy-mega-menu__trigger:hover,
489
+ html[data-zy-theme='basic'] .zy-mega-menu__plain:hover,
490
+ html[data-zy-theme='basic'] .zy-mega-menu__trigger.is-current {
491
+ background: var(--zy-mm-sunken);
492
+ }
493
+
494
+ html[data-zy-theme='basic'] .zy-mega-menu__trigger.is-open {
495
+ color: var(--zy-brand);
496
+ box-shadow: inset 0 -2px 0 var(--zy-brand);
497
+ }
498
+
499
+ html[data-zy-theme='basic'] .zy-mega-menu__panel {
500
+ background: var(--zy-surface);
501
+ border: 1px solid var(--zy-mm-line);
502
+ border-radius: var(--zy-radius);
503
+ box-shadow: var(--zy-shadow-float);
504
+ }
505
+
506
+ /* 滑行高亮与二级选中态共用一层皮:选中的那条一直亮着 */
507
+ html[data-zy-theme='basic'] .zy-mega-menu__glide,
508
+ html[data-zy-theme='basic'] .zy-mega-menu__link.is-current,
509
+ html[data-zy-theme='basic'] .zy-mega-menu__group-link.is-current {
510
+ border-radius: var(--zy-radius-sm);
511
+ background: var(--zy-mm-sunken);
512
+ /* 浅灰落在白纸片上也几乎看不见,按图纸语言补一道 1px 发丝边把它交代出来 */
513
+ box-shadow: inset 0 0 0 1px var(--zy-mm-line);
514
+ }
515
+
516
+ html[data-zy-theme='basic'] .zy-mega-menu__ico {
517
+ border: 1px solid var(--zy-mm-line);
518
+ border-radius: var(--zy-radius-sm);
519
+ background: var(--zy-surface);
520
+ color: var(--zy-brand);
521
+ }
522
+
523
+ html[data-zy-theme='basic'] .zy-mega-menu__title,
524
+ html[data-zy-theme='basic'] .zy-mega-menu__group-link {
525
+ color: var(--zy-ink);
526
+ }
527
+
528
+ html[data-zy-theme='basic'] .zy-mega-menu__desc,
529
+ html[data-zy-theme='basic'] .zy-mega-menu__note {
530
+ color: var(--zy-mm-muted);
531
+ }
532
+
533
+ html[data-zy-theme='basic'] .zy-mega-menu__badge {
534
+ color: var(--zy-brand);
535
+ background: var(--zy-mm-brand-soft);
536
+ border: 1px solid color-mix(in srgb, var(--zy-brand) 26%, transparent);
537
+ }
538
+
539
+ html[data-zy-theme='basic'] .zy-mega-menu__foot {
540
+ border-top: 1px solid var(--zy-mm-line);
541
+ }
542
+
543
+ html[data-zy-theme='basic'] .zy-mega-menu__more {
544
+ color: var(--zy-brand);
545
+ }
546
+
547
+ html[data-zy-theme='basic'] .zy-mega-menu__card {
548
+ border: 1px solid var(--zy-mm-line);
549
+ border-radius: var(--zy-radius-sm);
550
+ background: var(--zy-mm-sunken);
551
+ }
552
+
553
+ html[data-zy-theme='basic'] .zy-mega-menu__kicker,
554
+ html[data-zy-theme='basic'] .zy-mega-menu__group-title,
555
+ html[data-zy-theme='basic'] .zy-mega-menu__card-desc {
556
+ color: var(--zy-mm-muted);
557
+ }
558
+
559
+ html[data-zy-theme='basic'] .zy-mega-menu__group-title {
560
+ border-bottom: 1px solid var(--zy-mm-line);
561
+ }
562
+
563
+ html[data-zy-theme='basic'] .zy-mega-menu__card-title {
564
+ color: var(--zy-ink);
565
+ }
566
+
567
+ html[data-zy-theme='basic'] .zy-mega-menu__group-link {
568
+ border-radius: var(--zy-radius-sm);
569
+ }
570
+
571
+ html[data-zy-theme='basic'] .zy-mega-menu__group-ico {
572
+ color: var(--zy-mm-muted);
573
+ }
574
+
575
+ /*
576
+ * =====================================================================
577
+ * 0.1 · 图纸 · 夜(data-zy-theme="basic" + html.dark)
578
+ * ---------------------------------------------------------------------
579
+ * 与键帽主题的 §0.1 相对:图纸只有两级阶梯(底纸 / 纸片),夜里也不补厚度、
580
+ * 不加白弧。这一节只做三件事 —— 把纸压成中性石墨、把字换成中性白、
581
+ * 把深色下会「读成一道缝」的发丝线与控件线分开。
582
+ * 共用色板在 tokens/dark.css,这里只放图纸自己的那份。
583
+ * =====================================================================
584
+ */
585
+ /* =====================================================================
586
+ * 1 · 主题 A · 深色(图纸 · 夜)
587
+ * ---------------------------------------------------------------------
588
+ * 同一张纸,夜里开了一盏台灯:底纸更暗、纸片略亮、边界线比面亮。
589
+ * 仍然只有两级阶梯 —— 不为深色补厚度,也不给卡片加白弧(那是 B 的语言)。
590
+ * ===================================================================== */
591
+
592
+ html.dark[data-zy-theme='basic'] {
593
+ /* ---------- 表面:中性石墨,不是蓝黑。
594
+ * 浅色档的纸是中性白(#f2f4f6),夜里也应该是中性纸 —— 底色一旦偏蓝,
595
+ * 品牌蓝就再也读不出「这是标注」,整页都在发蓝。两级阶梯仍保持 1.14:1。 */
596
+ --zy-paper: #0f1014; /* 底纸(页面) */
597
+ --zy-surface: #1b1d23; /* 纸片(卡片 / 面板 / 弹层) */
598
+ --zy-surface-sunken: #15171c; /* 正文区 / 斑马行 */
599
+ --zy-panel-body-bg: #171a1f;
600
+
601
+ /* ---------- 字:中性白,不偏蓝 ---------- */
602
+ --zy-ink: #ecedef; /* 14.41:1 */
603
+ --zy-muted: #a0a6ae; /* 6.88:1 */
604
+ --zy-placeholder: #858b94; /* 4.92:1 */
605
+
606
+ /* ---------- 线:深色下「发丝线」必须比面亮,否则读成一道缝;控件线要能看清(≥3:1) ---------- */
607
+ --zy-hairline: #303339; /* 1.33:1 —— 装饰边界(卡片 / 容器) */
608
+ --zy-hairline-strong: #69717c; /* 3.42:1 —— 控件边界 */
609
+
610
+ /* ---------- 阴影:深色里影子本来就看不见,压成一层更实的暗角 ---------- */
611
+ --zy-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5), 0 8px 24px rgba(0, 0, 0, 0.38);
612
+ --zy-shadow-float: 0 18px 44px rgba(0, 0, 0, 0.62);
613
+ --zy-shadow-deep: rgba(0, 0, 0, 0.55);
614
+ --zy-shadow-press: 0 6px 18px rgba(90, 166, 228, 0.3);
615
+
616
+ /* ---------- 表格:表头是台账的栏头,深色下换成深一档的纸 + 浅一档的字 ---------- */
617
+ --zy-table-header-bg: #23272e;
618
+ --zy-table-header-fg: #d3dae2; /* 10.4:1 */
619
+ --zy-table-row-stripe: #15171c;
620
+ --zy-table-row-hover: rgba(90, 166, 228, 0.1);
621
+
622
+ /* ---------- 实心按钮:仍是「上浅下深」,只是把整段亮度压到白字够读的位置 ---------- */
623
+ --zy-btn-grad-primary: linear-gradient(180deg, #2876af 0%, #1d5f92 100%);
624
+ --zy-btn-grad-primary-hover: linear-gradient(180deg, #1d5f92 0%, #2876af 100%);
625
+ --zy-btn-edge-primary: #5aa6e4;
626
+
627
+ --zy-btn-grad-success: linear-gradient(180deg, #38803d 0%, #2c6631 100%);
628
+ --zy-btn-grad-success-hover: linear-gradient(180deg, #2c6631 0%, #38803d 100%);
629
+ --zy-btn-edge-success: #6cc24a;
630
+
631
+ --zy-btn-grad-warning: linear-gradient(180deg, #e8a13a 0%, #c98a2c 100%);
632
+ --zy-btn-grad-warning-hover: linear-gradient(180deg, #c98a2c 0%, #e8a13a 100%);
633
+ --zy-btn-edge-warning: #ffc46b;
634
+
635
+ --zy-btn-grad-info: linear-gradient(180deg, #5f6f80 0%, #46525f 100%);
636
+ --zy-btn-grad-info-hover: linear-gradient(180deg, #46525f 0%, #5f6f80 100%);
637
+ --zy-btn-edge-info: #9ab0c6;
638
+
639
+ /* fill(键帽本体)不是 A 的语言,板上不展示;但令牌仍要给出深色下的正确值,
640
+ * 免得别处一用就落回「亮品牌面 + 白字」的 2.4:1。 */
641
+ --zy-btn-fill-clr: var(--zy-brand-key);
642
+ --zy-btn-fill-ink: #fff;
643
+ --zy-btn-fill-ink-on: #fff;
644
+ --zy-btn-fill-shade: rgba(255, 255, 255, 0.18);
645
+
646
+ --el-border-radius-base: var(--zy-radius);
647
+ --el-component-size: var(--zy-control-h);
648
+ }
649
+
650
+ /* 1.1 卡片:仍是白纸片,只是纸变黑。纸面装饰层(白弧 / 铺色)属于 B 的材质,深色下必须关掉 ——
651
+ * 浅色时它们在白面上看不见,深色下会变成两道弧光,等于偷偷给 A 加了厚度。 */
652
+ html.dark[data-zy-theme='basic'] .zy-card-fill-wave {
653
+ display: none;
654
+ }
655
+
656
+ /* 1.2 控件:面 = 纸片,边 = 控件档发丝线;聚焦仍是「描边转主色 + 3px 光环」,一点厚度都不加 */
657
+ html.dark[data-zy-theme='basic'] .zy-input.is-focus .el-input__wrapper,
658
+ html.dark[data-zy-theme='basic'] .zy-select.is-focus .el-select__wrapper {
659
+ background-color: var(--zy-surface);
660
+ box-shadow: 0 0 0 1px var(--zy-hairline-strong) inset;
661
+ }
662
+
663
+ @media (hover: hover) and (pointer: fine) {
664
+ html.dark[data-zy-theme='basic'] .zy-input.is-focus .el-input__wrapper:hover,
665
+ html.dark[data-zy-theme='basic'] .zy-select.is-focus .el-select__wrapper:hover {
666
+ box-shadow: 0 0 0 1px var(--zy-brand) inset;
667
+ }
668
+ }
669
+
670
+ html.dark[data-zy-theme='basic'] .zy-input.is-focus .el-input__wrapper.is-focus,
671
+ html.dark[data-zy-theme='basic'] .zy-select.is-focus .el-select__wrapper.is-focused {
672
+ box-shadow:
673
+ 0 0 0 1px var(--zy-brand) inset,
674
+ 0 0 0 3px color-mix(in srgb, var(--zy-brand) 22%, transparent);
675
+ }
676
+
677
+ /* 1.3 实心按钮的两个例外:
678
+ * 危险是平色(不是渐变),警示是亮琥珀面 —— 一个要把面压深、一个要把字翻墨。 */
679
+ html.dark[data-zy-theme='basic']
680
+ .zy-btn.el-button--danger:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill, .is-disabled)) {
681
+ --el-button-bg-color: var(--zy-danger-key);
682
+ --el-button-border-color: var(--zy-danger-key);
683
+ --el-button-hover-bg-color: var(--zy-danger-key-hover);
684
+ --el-button-hover-border-color: var(--zy-danger-key-hover);
685
+ --el-button-active-bg-color: var(--zy-danger-key-hover);
686
+ --el-button-active-border-color: var(--zy-danger-key-hover);
687
+ --el-button-text-color: #fff;
688
+ --el-button-hover-text-color: #fff;
689
+ --el-button-active-text-color: #fff;
690
+ }
691
+
692
+ html.dark[data-zy-theme='basic'] .zy-btn.el-button--warning {
693
+ --el-button-text-color: var(--zy-warning-ink);
694
+ --el-button-hover-text-color: var(--zy-warning-ink);
695
+ --el-button-active-text-color: var(--zy-warning-ink);
696
+ }
697
+
698
+ /* 禁用:浅色档是「叠一层 50% 白」把键洗淡;深色下换成叠一层底纸色,才读成「按不动」而不是「在发光」 */
699
+ html.dark[data-zy-theme='basic']
700
+ .zy-btn.el-button--primary.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)),
701
+ html.dark[data-zy-theme='basic']
702
+ .zy-btn.el-button--success.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)),
703
+ html.dark[data-zy-theme='basic']
704
+ .zy-btn.el-button--warning.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)),
705
+ html.dark[data-zy-theme='basic']
706
+ .zy-btn.el-button--info.is-disabled:not(:where(.is-plain, .is-dashed, .is-text, .is-link, .is-sweep, .is-fill)) {
707
+ background-image: linear-gradient(rgba(10, 16, 23, 0.45), rgba(10, 16, 23, 0.45)),
708
+ var(--zy-btn-grad);
709
+ background-origin: border-box;
710
+ }
711
+
712
+ /* sweep 的字与描边取亮档品牌色(--zy-brand),在深色纸面上仍然清楚 */
713
+
714
+ /* 1.4 弹层:浅色档那块「白面板 + 发丝边 + 极轻影」在深色下换成纸片 + 线 + 一层实影 */
715
+ html.dark[data-zy-theme='basic'] .zy-panel {
716
+ box-shadow: var(--zy-shadow-card);
717
+ }
718
+
719
+ html.dark[data-zy-theme='basic'] .el-picker-panel,
720
+ html.dark[data-zy-theme='basic'] .el-time-panel,
721
+ html.dark[data-zy-theme='basic'] .el-time-range-picker {
722
+ border: 1px solid var(--zy-hairline);
723
+ background: var(--zy-surface);
724
+ box-shadow: var(--zy-shadow-card);
725
+ }
726
+
727
+ html.dark[data-zy-theme='basic'] .el-time-panel__footer {
728
+ border-top: 1px solid var(--zy-hairline);
729
+ background: var(--zy-surface-sunken);
730
+ }
731
+
732
+ /* 1.5 表格 / 树:深色档不套 `:not(.dark)`,所以把图纸语言那两块原样补回来,只换填充色 */
733
+ html.dark[data-zy-theme='basic'] .zy-tree-shell {
734
+ position: relative;
735
+ }
736
+
737
+ html.dark[data-zy-theme='basic'] .zy-tree {
738
+ --zy-tree-row: 32px;
739
+ }
740
+
741
+ html.dark[data-zy-theme='basic'] .zy-tree .el-tree-node__content {
742
+ padding-inline: 12px !important;
743
+ margin-block: 3px;
744
+ }
745
+
746
+ html.dark[data-zy-theme='basic'] .zy-tree .el-tree-node__content:hover {
747
+ background: transparent;
748
+ }
749
+
750
+ html.dark[data-zy-theme='basic'] .zy-tree-shell .zy-tree-glide {
751
+ position: absolute;
752
+ left: 0;
753
+ top: 0;
754
+ border-radius: var(--zy-radius-sm);
755
+ /* 深色下「悬停」是提亮,不是加深:一层 6% 白 + 一圈线 */
756
+ background: rgba(255, 255, 255, 0.06);
757
+ box-shadow: inset 0 0 0 1px var(--zy-hairline);
758
+ opacity: 0;
759
+ pointer-events: none;
760
+ transition:
761
+ transform 220ms var(--zy-ease-out),
762
+ width 220ms var(--zy-ease-out),
763
+ height 220ms var(--zy-ease-out),
764
+ opacity 150ms var(--zy-ease-out);
765
+ }
766
+
767
+ html.dark[data-zy-theme='basic'] .zy-tree .el-tree-node.is-current > .el-tree-node__content {
768
+ background: var(--zy-brand-soft);
769
+ color: var(--zy-brand);
770
+ font-weight: 600;
771
+ }
772
+
773
+ /* 1.6 对话框:账本头条(品牌渐变 + 2px 线)在深色下保留;线色统一在第 0.8 节改成品牌色 */
774
+ html.dark[data-zy-theme='basic'] .zy-dialog .el-dialog__header {
775
+ background: linear-gradient(180deg, var(--zy-brand-soft) 0%, var(--zy-surface) 72%);
776
+ }
777
+
778
+ html.dark[data-zy-theme='basic'] .zy-dialog .el-dialog__footer {
779
+ background: var(--zy-surface-sunken);
780
+ }
781
+
782
+ /* 1.7 滑块拼图验证:缺口是「图上挖掉的一块」,浅色档用墨色剪影;深色档 ink 变浅了,
783
+ * 剪影必须显式回到黑,否则会变成一块发亮的补丁。 */
784
+ html.dark[data-zy-theme='basic'] .zy-verify__gap,
785
+ html.dark[data-zy-theme='basic'] .zy-verify__gap::after {
786
+ background: color-mix(in srgb, #000 55%, transparent);
787
+ }
788
+
789
+ /* 1.8 复选框:勾选面取「实心键面」那一档(白勾 4.88:1)。
790
+ * 浅色档这里直接用 --zy-brand #0066a9,深色下它变成亮档 #5aa6e4 —— 白勾只剩 2.4:1,
791
+ * 所以面必须换回 --zy-brand-key。这一类「--zy-brand 被当面色用」的位置在深色下都要逐个换。 */
792
+ html.dark[data-zy-theme='basic'] .zy-check .el-checkbox__input:not(.is-disabled).is-checked .el-checkbox__inner,
793
+ html.dark[data-zy-theme='basic'] .zy-check .el-checkbox__input:not(.is-disabled).is-indeterminate .el-checkbox__inner,
794
+ html.dark[data-zy-theme='basic'] .zy-tree .el-checkbox__input:not(.is-disabled).is-checked .el-checkbox__inner,
795
+ html.dark[data-zy-theme='basic'] .zy-tree .el-checkbox__input:not(.is-disabled).is-indeterminate .el-checkbox__inner {
796
+ background-color: var(--zy-brand-key);
797
+ border-color: var(--zy-brand-key);
798
+ }
799
+
800
+ /* 1.9 舞台:浅色档用「底纸 70% 叠在卡片上」把舞台调灰一档;深色下这个半透明叠色会
801
+ * 把舞台压到比底纸更暗(叠的是石墨卡片,不是白卡),层级方向就反了 —— 深色下直接给底纸。 */
802
+
803
+ /* ---------------------------------------------------------------------
804
+ * 收尾两笔(方案稿 0.8 的 A 侧)
805
+ * ------------------------------------------------------------------- */
806
+
807
+ /* ① 对话框抬头那道 2px 线在组件里写死成绿:A 的语言里只有「蓝墨 + 纸」,
808
+ * 夜里换成品牌色压深一档的那条,读起来仍是「抬头」,不是状态条。 */
809
+ html.dark[data-zy-theme='basic'] .zy-dialog .el-dialog__header {
810
+ box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--zy-brand) 78%, var(--zy-surface));
811
+ }
812
+
813
+ /* ② 实心标签:A 的「面」取深档键面 —— 共用板把字档语义色提亮成夜间可读的亮色,
814
+ * 那张亮色当「面」时白字只有 2.0–2.7:1;面换深档后 4.86–5.19:1。 */
815
+ html.dark[data-zy-theme='basic'] .zy-tag.is-fill {
816
+ --zy-tag-fill-clr: var(--zy-brand-key);
817
+ }
818
+
819
+ html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--success {
820
+ --zy-tag-fill-clr: var(--zy-green-key);
821
+ }
822
+
823
+ html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--warning {
824
+ --zy-tag-fill-clr: var(--zy-warning-key);
825
+ /* 琥珀面上白字 2.19:1,字跟着面走:换深墨(9.19:1) */
826
+ color: var(--zy-warning-ink);
827
+ --el-tag-text-color: var(--zy-warning-ink);
828
+ --el-tag-hover-color: var(--zy-warning-ink);
829
+ }
830
+
831
+ html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--danger {
832
+ --zy-tag-fill-clr: var(--zy-danger-key);
833
+ }
834
+
835
+ html.dark[data-zy-theme='basic'] .zy-tag.is-fill.el-tag--info {
836
+ --zy-tag-fill-clr: var(--zy-info-key);
837
+ }