@qilitt-mickey/vue3-temp-skill 1.2.5 → 1.2.7

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.
@@ -0,0 +1,634 @@
1
+ {
2
+ "schema": "ui.adapter/1.0",
3
+ "adapter": "vue-element-plus",
4
+ "stack": "vue3 + element-plus",
5
+ "$comment": "adapter 的机器可读部分:generate-css.mjs 与 verify-render.mjs 消费本文件。Markdown 文档(references/adapters/vue-element-plus.md)给人读,本文件给机器读——两者内容同源,改一处必须同步另一处。",
6
+
7
+ "output": {
8
+ "dir": "src/styles",
9
+ "files": ["ui-tokens.css", "ui-roles.css", "ui-layout.css"],
10
+ "entryImport": "src/main.ts",
11
+ "importOrder": ["ui-tokens.css", "ui-roles.css", "ui-layout.css"],
12
+ "importNote": "三份 CSS 必须作为 TS import 在 element-plus/dist/index.css 之后引入(main.ts 中 EP css 注释标明『一定要放在index.scss后』——EP 全量 css 是独立 <style> 标签且位于 index.scss 之后,@import 进 index.scss 会被 EP 盖住)。"
13
+ },
14
+
15
+ "innerTargets": {
16
+ "$comment": "契约 inner[] → 全局 CSS 后代选择器目标(ui-roles.css 是非 scoped 全局文件,禁止 :deep())。default = 角色类自身。",
17
+ "shell-sidebar-logo": "span, .sidebar-title",
18
+ "shell-sidebar-menu": "default",
19
+ "shell-sidebar-group": ".el-sub-menu__title span",
20
+ "shell-sidebar-item": "span",
21
+ "shell-sidebar-item-active": "span",
22
+ "shell-header": "default",
23
+ "shell-header-collapse": "default",
24
+ "shell-header-icon": "default",
25
+ "shell-header-user": "default",
26
+ "shell-tabs": "default",
27
+ "shell-tabs-item": "default",
28
+ "shell-tabs-item-active": "default",
29
+ "shell-tabs-close": "default",
30
+ "shell-content": "default",
31
+ "page-card": "default",
32
+ "page-header": "default",
33
+ "page-header-title": "default",
34
+ "filter-section": "default",
35
+ "filter-item": "default",
36
+ "filter-label": "default",
37
+ "filter-actions": "default",
38
+ "filter-input": ".el-input__wrapper",
39
+ "filter-select": ".el-select__wrapper",
40
+ "filter-date-range": ".el-input__wrapper",
41
+ "toolbar-bar": "default",
42
+ "table-wrapper": "default",
43
+ "table-header-cell": ".cell",
44
+ "table-cell": ".cell",
45
+ "table-cell-index": ".cell",
46
+ "table-cell-selection": "default",
47
+ "table-cell-amount": ".cell",
48
+ "table-cell-status": ".cell",
49
+ "table-cell-action": ".cell",
50
+ "pagination-bar": "default",
51
+ "button-primary": "default",
52
+ "button-secondary": "default",
53
+ "button-danger": "default",
54
+ "button-text": "default",
55
+ "tag-status": "default"
56
+ },
57
+
58
+ "stateChannels": {
59
+ "$comment": "契约 states.<态> → CSS 选择器片段(追加在角色类后)。{self}=角色类自身。EP 真实态类名在此统一,生成器不猜。",
60
+ "hover": ":hover",
61
+ "disabled": ".is-disabled, :disabled",
62
+ "active": ".is-active",
63
+ "focus": ".is-focus, :focus-within",
64
+ "checked": ".is-checked"
65
+ },
66
+
67
+ "extraRules": {
68
+ "$comment": "EP DOM 结构等价转换:契约声明落在 A 元素,但 EP 把视觉承载在 B 元素/用 C 机制表达。规则由 generate-css 在对应角色段后自动追加。selector 中 {role}=角色类名,{tokens}=ui-tokens.css 变量。",
69
+ "filter-input": [
70
+ {
71
+ "when": "host contains border",
72
+ "emit": [
73
+ ".role-filter-input { border: none; padding: 0; }",
74
+ ".role-filter-input:focus-within { box-shadow: none; border-color: transparent; }",
75
+ ".role-filter-input .el-input__wrapper { box-shadow: 0 0 0 1px var(--color-border-strong) inset; border: none; background-color: var(--color-surface); border-radius: var(--radius-md); padding: 0 11px; height: var(--size-control-height); }"
76
+ ],
77
+ "reason": "EP 输入框边框是 wrapper 的 box-shadow inset:契约 border/padding 声明从根元素取消(否则根+wrapper 双边框),等价转移到 wrapper"
78
+ },
79
+ {
80
+ "when": "states.hover.host contains border-color",
81
+ "emit": ".role-filter-input:hover .el-input__wrapper { box-shadow: 0 0 0 1px var(--color-brand-strong) inset; }",
82
+ "reason": "hover 边框色落到 wrapper box-shadow"
83
+ },
84
+ {
85
+ "when": "states.focus.host contains border-color",
86
+ "emit": ".role-filter-input .el-input__wrapper.is-focus { box-shadow: 0 0 0 1px var(--color-brand) inset, 0 0 0 2px var(--color-brand-subtle) !important; }",
87
+ "reason": "focus 主色 + 2px 浅阶光晕;EP is-focus 带自身 box-shadow 需提权"
88
+ }
89
+ ],
90
+ "filter-select": [
91
+ {
92
+ "when": "host contains border",
93
+ "emit": [
94
+ ".role-filter-select { border: none; padding: 0; }",
95
+ ".role-filter-select:focus-within { box-shadow: none; border-color: transparent; }",
96
+ ".role-filter-select .el-select__wrapper { box-shadow: 0 0 0 1px var(--color-border-strong) inset; border: none; background-color: var(--color-surface); border-radius: var(--radius-md); min-height: var(--size-control-height); padding: 0 11px; }"
97
+ ],
98
+ "reason": "EP 新版 select wrapper 同样 box-shadow 模拟边框;根元素 border/padding 取消"
99
+ },
100
+ {
101
+ "when": "states.hover.host contains border-color",
102
+ "emit": ".role-filter-select:hover .el-select__wrapper { box-shadow: 0 0 0 1px var(--color-brand-strong) inset; }"
103
+ },
104
+ {
105
+ "when": "states.focus.host contains border-color",
106
+ "emit": ".role-filter-select .el-select__wrapper.is-focus { box-shadow: 0 0 0 1px var(--color-brand) inset, 0 0 0 2px var(--color-brand-subtle) !important; }"
107
+ }
108
+ ],
109
+ "filter-date-range": [
110
+ {
111
+ "when": "host contains border",
112
+ "emit": [
113
+ ".role-filter-date-range { border: none; padding: 0; }",
114
+ ".role-filter-date-range:focus-within { box-shadow: none; border-color: transparent; }",
115
+ ".el-input__wrapper.role-filter-date-range { box-shadow: 0 0 0 1px var(--color-border-strong) inset; border: none; background-color: var(--color-surface); border-radius: var(--radius-md); height: var(--size-control-height); padding: 0 11px; gap: 8px; }",
116
+ ".el-input__wrapper.role-filter-date-range:hover { box-shadow: 0 0 0 1px var(--color-brand-strong) inset; }",
117
+ ".el-input__wrapper.role-filter-date-range.is-focus { box-shadow: 0 0 0 1px var(--color-brand) inset, 0 0 0 2px var(--color-brand-subtle) !important; }",
118
+ ".role-filter-date-range .el-range-input { font-size: var(--font-size-md); }",
119
+ ".role-filter-date-range .el-range-separator { color: var(--color-text-tertiary); font-size: var(--font-size-md); line-height: 1; }"
120
+ ],
121
+ "reason": "EP daterange 根元素自身就是 .el-input__wrapper(同元素复合选择器,非后代)"
122
+ }
123
+ ],
124
+ "table-header-cell": [
125
+ {
126
+ "when": "host contains height",
127
+ "emit": [
128
+ ".el-table th.role-table-header-cell { height: 48px; padding: 0 !important; background-color: #FAFAFA !important; border-bottom: 1px solid var(--color-border-base) !important; position: sticky !important; top: 0; z-index: 2; }",
129
+ ".el-table th.role-table-header-cell .cell { padding: 0 16px; font-weight: var(--font-weight-medium) !important; white-space: nowrap !important; overflow: visible !important; text-overflow: clip !important; color: var(--color-text-primary) !important; }",
130
+ ".el-table th.role-table-header-cell--index .cell, .el-table td.role-table-cell-index .cell { padding: 0 12px; justify-content: center; }",
131
+ ".el-table th.role-table-header-cell--selection .cell, .el-table td.role-table-cell-selection .cell { padding: 0; display: flex; align-items: center; justify-content: center; }"
132
+ ],
133
+ "reason": "element-plus.scss .el-table thead th{border-bottom:2px !imp} 是 (0,1,2)+!imp;本侧 .el-table th.role-… (0,2,1)+!imp 才赢;EP th.el-table__cell position:relative 也需 !imp 压"
134
+ }
135
+ ],
136
+ "table-cell": [
137
+ {
138
+ "when": "host contains height",
139
+ "emit": "td.role-table-cell { height: 55px; padding: 0 !important; }",
140
+ "reason": "同表头:td 上下 padding 归零"
141
+ },
142
+ {
143
+ "when": "host contains padding",
144
+ "emit": "td.role-table-cell .cell { padding: 0 16px; }"
145
+ },
146
+ {
147
+ "when": "variants density",
148
+ "emit": [
149
+ ".density-loose td.role-table-cell { height: 55px; }",
150
+ ".density-normal td.role-table-cell { height: 47px; }",
151
+ ".density-compact td.role-table-cell { height: 39px; }"
152
+ ],
153
+ "reason": "密度三档整份替换,由表格根容器 density-* 类驱动"
154
+ },
155
+ {
156
+ "when": "linkedStates rowHover",
157
+ "emit": ".el-table__body tr:hover > td.el-table__cell { background-color: #FAFAFA; }",
158
+ "reason": "行 hover 底色 #FAFAFA(EP hover 变量已桥接,此为兜底)"
159
+ },
160
+ {
161
+ "when": "linkedStates rowSelected",
162
+ "emit": ".el-table__body tr.row-selected > td.el-table__cell { background-color: var(--color-brand-subtle) !important; }",
163
+ "reason": "选中行底色 brand.subtle,含吸附列联动"
164
+ }
165
+ ],
166
+ "table-cell-action": [
167
+ {
168
+ "when": "sticky right",
169
+ "emit": [
170
+ ".el-table td.role-table-cell-action { text-align: center !important; }",
171
+ ".el-table td.role-table-cell-action .cell { display: inline-flex; align-items: center; justify-content: center; gap: 8px; white-space: nowrap; overflow: visible; }",
172
+ ".el-table th.role-table-header-cell--action { text-align: center !important; }",
173
+ ".el-table th.role-table-header-cell--action .cell { text-align: center; justify-content: center; }",
174
+ ".el-table td.role-table-cell-amount .cell { text-align: right; justify-content: flex-end; }",
175
+ ".role-table-cell-action .re-table-operate { justify-content: center; }",
176
+ ".role-table-cell-action .re-table-operate__slot { width: auto !important; min-width: 0 !important; }",
177
+ ".role-table-cell-action .re-table-operate__slot + .re-table-operate__slot::before { content: \"\"; display: inline-block; width: 1px; height: 14px; background: var(--color-border-base); margin: 0 8px; vertical-align: middle; }",
178
+ ".role-table-cell-action .el-button + .el-button { margin-left: 0; }",
179
+ ".el-table td.role-table-cell-action.el-table-fixed-column--right { background-color: var(--color-surface); z-index: 10 !important; box-shadow: -2px 0 4px rgba(0,0,0,0.06); }"
180
+ ],
181
+ "reason": "EP .el-table__cell 默认 text-align:left、fixed 列 z-index:2,需 .el-table 复合提权。操作列几何按基线 .op-btn-group 流式:槽宽 auto(压 ReTableOperate 等宽槽)、分割线 ::before margin 0 8px(基线 .list-table-action-divider)、.cell padding 0 16px(基线 td padding 16px 双层等价)"
182
+ },
183
+ {
184
+ "when": "linkedStates rowHover",
185
+ "emit": ".el-table__body tr:hover > td.role-table-cell-action.el-table-fixed-column--right { background-color: #FAFAFA; }"
186
+ },
187
+ {
188
+ "when": "linkedStates rowSelected",
189
+ "emit": ".el-table__body tr.row-selected > td.role-table-cell-action.el-table-fixed-column--right { background-color: var(--color-brand-subtle) !important; }"
190
+ }
191
+ ],
192
+ "table-cell-index": [
193
+ { "when": "box width", "emit": ".el-table td.role-table-cell-index { width: 56px; min-width: 56px; text-align: center !important; }" }
194
+ ],
195
+ "table-cell-selection": [
196
+ { "when": "box width", "emit": ".el-table td.role-table-cell-selection { width: 48px; min-width: 48px; text-align: center !important; }" },
197
+ { "when": "childRoles checkbox", "emit": ".role-table-cell-selection .el-checkbox__inner { width: 16px; height: 16px; border-radius: 4px; }" }
198
+ ],
199
+ "table-cell-status": [
200
+ { "when": "host padding 0", "emit": "td.role-table-cell-status .cell { padding: 0 16px; }" }
201
+ ],
202
+ "pagination-bar": [
203
+ {
204
+ "when": "childRoles pagerBtn",
205
+ "emit": [
206
+ ".role-pagination-bar .el-pager li { min-width: 32px; height: 32px; line-height: 30px; border-radius: var(--radius-md); border: 1px solid var(--color-border-strong); background-color: var(--color-surface); font-size: var(--font-size-md); color: var(--color-text-primary); margin: 0 4px; }",
207
+ ".role-pagination-bar .el-pager li.is-active { background-color: var(--color-brand); color: var(--color-text-inverse); border-color: var(--color-brand); }",
208
+ ".role-pagination-bar .el-pager li.is-disabled { color: var(--color-text-tertiary); background-color: #F5F5F5; cursor: not-allowed; }",
209
+ ".role-pagination-bar button { min-width: 32px; height: 32px; border-radius: var(--radius-md); border: 1px solid var(--color-border-strong); background-color: var(--color-surface); }",
210
+ ".role-pagination-bar button:disabled { color: var(--color-text-tertiary); background-color: #F5F5F5; cursor: not-allowed; }"
211
+ ],
212
+ "reason": "EP 分页按钮/页码/激活/禁用落到真实 DOM"
213
+ },
214
+ {
215
+ "when": "childRoles size",
216
+ "emit": ".role-pagination-bar .el-pagination__sizes .el-select__wrapper { min-height: 32px; border-radius: var(--radius-md); box-shadow: 0 0 0 1px var(--color-border-strong) inset; }"
217
+ },
218
+ {
219
+ "when": "childRoles jumpInput",
220
+ "emit": ".role-pagination-bar .el-pagination__jump .el-input__wrapper { min-height: 32px; width: 48px; border-radius: var(--radius-md); box-shadow: 0 0 0 1px var(--color-border-strong) inset; }"
221
+ }
222
+ ],
223
+ "button-primary": [
224
+ {
225
+ "when": "host",
226
+ "emit": [
227
+ "button.el-button.role-button-primary { display: inline-flex !important; font-weight: var(--font-weight-normal) !important; background-color: var(--color-brand); border-color: var(--color-brand); color: var(--color-text-inverse); border-radius: var(--radius-md); height: var(--size-control-height); padding: 0 15px; margin-left: 0 !important; }",
228
+ "button.el-button.role-button-primary:hover { background-color: var(--color-brand-hover); border-color: var(--color-brand-hover); color: var(--color-text-inverse); }",
229
+ "button.el-button.role-button-primary.is-disabled, button.el-button.role-button-primary:disabled { background-color: var(--color-brand-subtle); border-color: var(--color-brand-subtle); color: var(--color-text-inverse); cursor: not-allowed; opacity: 1; }"
230
+ ],
231
+ "reason": "EP 按钮默认色由 --el-button-* 变量驱动,角色类提权覆盖;display inline-flex 与 font-weight 400 对抗 EP .el-button{display:inline-flex→被 scoped 覆盖为 flex} 与项目按钮 500 字重;disabled 需压掉 EP 的 opacity 方案"
232
+ }
233
+ ],
234
+ "button-secondary": [
235
+ {
236
+ "when": "host",
237
+ "emit": [
238
+ "button.el-button.role-button-secondary { display: inline-flex !important; font-weight: var(--font-weight-normal) !important; background-color: var(--color-surface); border-color: var(--color-border-strong); color: var(--color-text-primary); border-radius: var(--radius-md); height: var(--size-control-height); padding: 0 15px; margin-left: 0 !important; }",
239
+ "button.el-button.role-button-secondary:hover { background-color: var(--color-surface); border-color: var(--color-brand); color: var(--color-brand); }",
240
+ "button.el-button.role-button-secondary.is-disabled, button.el-button.role-button-secondary:disabled { background-color: var(--color-surface); border-color: var(--color-border-base); color: var(--color-text-tertiary); opacity: 1; }"
241
+ ],
242
+ "reason": "契约 notes:hover 仅变边框色与文字色,背景不变(覆盖 EP 默认 hover 变底)"
243
+ }
244
+ ],
245
+ "button-danger": [
246
+ {
247
+ "when": "host",
248
+ "emit": [
249
+ "button.el-button.role-button-danger { display: inline-flex !important; font-weight: var(--font-weight-normal) !important; background-color: var(--color-state-error); border: none; color: var(--color-text-inverse); border-radius: var(--radius-md); height: var(--size-control-height); padding: 0 12px; margin-left: 0 !important; }",
250
+ "button.el-button.role-button-danger:hover { background-color: var(--color-state-error-hover); color: var(--color-text-inverse); }",
251
+ "button.el-button.role-button-danger.is-disabled, button.el-button.role-button-danger:disabled { background-color: var(--color-state-error-bg); color: var(--color-state-error); opacity: 1; cursor: not-allowed; }"
252
+ ]
253
+ }
254
+ ],
255
+ "button-text": [
256
+ {
257
+ "when": "host",
258
+ "emit": [
259
+ "button.el-button.role-button-text { display: inline-flex !important; font-weight: var(--font-weight-normal) !important; background: transparent; border: none; padding: 0; height: auto; color: var(--color-brand); }",
260
+ "button.el-button.role-button-text:hover { background: transparent; color: var(--color-brand-strong); }",
261
+ "button.el-button.role-button-text--danger { color: var(--color-state-error); }",
262
+ "button.el-button.role-button-text--danger:hover { color: var(--color-state-error-hover); }"
263
+ ],
264
+ "reason": "纯文字形态:无背景无边框无圆角;danger 变体类名后缀"
265
+ }
266
+ ],
267
+ "tag-status": [
268
+ {
269
+ "when": "variants",
270
+ "emit": [
271
+ ".role-tag-status { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px; border-radius: var(--radius-md); border: 1px solid transparent; font-size: var(--font-size-xs); font-weight: var(--font-weight-normal); line-height: 1; white-space: nowrap; flex-shrink: 0; }",
272
+ ".role-tag-status .el-icon, .role-tag-status svg { width: 14px; height: 14px; font-size: 14px; }",
273
+ ".role-tag-status--success { background-color: var(--color-state-success-bg); border-color: var(--tag-success-border); color: var(--color-state-success); }",
274
+ ".role-tag-status--processing { background-color: var(--color-brand-subtle); border-color: var(--color-brand-border); color: var(--color-brand); }",
275
+ ".role-tag-status--warning { background-color: var(--color-state-warning-bg); border-color: var(--tag-warning-border); color: var(--color-state-warning); }",
276
+ ".role-tag-status--error { background-color: var(--color-state-error-bg); border-color: var(--tag-error-border); color: var(--color-state-error); }",
277
+ ".role-tag-status--outlined { background-color: transparent; border-color: var(--color-brand-border); color: var(--color-brand); }",
278
+ ".role-tag-status--default { background-color: var(--tag-default-bg); border-color: var(--color-border-base); color: var(--color-text-secondary); }"
279
+ ],
280
+ "reason": "标签用纯 span 实现(不用 el-tag,零 EP 干扰);六变体整份替换"
281
+ }
282
+ ],
283
+ "shell-header": [
284
+ {
285
+ "when": "host padding + flatten shadow",
286
+ "emit": [
287
+ ".ui-region-header, .role-shell-header { padding: 0 var(--space-6) 0 0 !important; box-shadow: none !important; }"
288
+ ],
289
+ "reason": "lay-navbar scoped .navbar-shell 有 padding-inline(data-v 属性选择器特异性 0,2,0)与 UnoCSS shadow-sm,需提权对抗"
290
+ }
291
+ ],
292
+ "shell-sidebar-item-active": [
293
+ {
294
+ "when": "host",
295
+ "emit": [
296
+ "body .sidebar-container .el-menu--vertical .el-menu-item.is-active.role-shell-sidebar-item-active, body .sidebar-container .el-menu--vertical .el-menu-item.role-shell-sidebar-item-active { background-color: var(--color-brand) !important; color: var(--color-text-inverse) !important; }",
297
+ "body .sidebar-container .el-menu--vertical .el-menu-item.is-active.role-shell-sidebar-item-active span, body .sidebar-container .el-menu--vertical .el-menu-item.role-shell-sidebar-item-active span { color: var(--color-text-inverse) !important; }"
298
+ ],
299
+ "reason": "sidebar.scss 的 body[layout=vertical] .sidebar-container .el-menu-item{transparent !imp} 是 (0,3,1)+!imp;本侧加 .sidebar-container 复合到 (0,4,0)+!imp 才赢(!important 对决比特异性)"
300
+ }
301
+ ],
302
+ "shell-sidebar-item": [
303
+ {
304
+ "when": "host",
305
+ "emit": [
306
+ "body .sidebar-container .el-menu-item.role-shell-sidebar-item { height: 40px; line-height: 40px; padding: 0 20px !important; margin: 0 8px; border-radius: var(--radius-md); background-color: transparent; color: rgba(255,255,255,0.65) !important; box-sizing: border-box; position: relative; white-space: nowrap; }",
307
+ "body .sidebar-container .el-menu-item.role-shell-sidebar-item span, body .sidebar-container .el-menu-item.role-shell-sidebar-item .el-text { color: inherit !important; }",
308
+ "body .sidebar-container .el-menu-item.role-shell-sidebar-item:hover { background-color: rgba(255,255,255,0.08) !important; color: var(--color-text-inverse) !important; }",
309
+ ".sidebar-container .el-menu-item.role-shell-sidebar-item-active::before { content: \"\"; position: absolute; inset: auto; left: 0; right: 0; top: 0; bottom: 0; z-index: 0; margin: 0; background: var(--color-brand) !important; border-radius: var(--radius-md); }",
310
+ ".sidebar-container .el-menu-item.role-shell-sidebar-item-active::after { content: \"\"; position: absolute; left: -8px; top: 25%; bottom: 25%; width: 3px; border-radius: 0 2px 2px 0; background-color: var(--color-brand); z-index: 2; }"
311
+ ],
312
+ "reason": "EP 菜单项 padding 由 --el-menu-item-padding 驱动,!important 提权;激活竖条 = pill 变体的 ::before 伪元素(契约 notes 明示由项目侧补足);hover 对抗 sidebar.scss .el-menu-item:hover !imp"
313
+ }
314
+ ],
315
+ "shell-sidebar-group": [
316
+ {
317
+ "when": "host",
318
+ "emit": [
319
+ "li.el-sub-menu.role-shell-sidebar-group > .el-sub-menu__title { height: auto; padding: 8px 20px !important; white-space: nowrap; background-color: transparent; }",
320
+ "li.el-sub-menu.role-shell-sidebar-group > .el-sub-menu__title span { font-size: 12px; color: rgba(255,255,255,0.35) !important; text-transform: uppercase; letter-spacing: 0.5px; }",
321
+ "li.el-sub-menu.role-shell-sidebar-group > .el-sub-menu__title .el-sub-menu__icon-arrow { display: none; }",
322
+ "li.el-sub-menu.role-shell-sidebar-group > .el-sub-menu__title:hover { background-color: transparent; }",
323
+ "li.el-sub-menu.role-shell-sidebar-group > .el-sub-menu__title .sub-menu-icon { display: none; }"
324
+ ],
325
+ "reason": "分组标题:class 落在 el-sub-menu 根 li 上;隐藏展开箭头与图标(基线分组标题无图标无箭头)"
326
+ }
327
+ ],
328
+ "shell-sidebar-menu": [
329
+ {
330
+ "when": "host",
331
+ "emit": ".el-menu.role-shell-sidebar-menu { background-color: transparent; padding: 8px 0; border-right: none; }"
332
+ }
333
+ ],
334
+ "shell-sidebar-logo": [
335
+ {
336
+ "when": "childRoles icon",
337
+ "emit": [
338
+ ".role-shell-sidebar-logo .logo-badge { width: 28px; height: 28px; border-radius: 6px; background-color: var(--color-brand); color: var(--color-text-inverse); font-size: 16px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }",
339
+ ".role-shell-sidebar-logo .sidebar-title, .role-shell-sidebar-logo span:not(.logo-badge) { font-size: 16px; font-weight: var(--font-weight-medium); color: var(--color-text-inverse); }"
340
+ ]
341
+ }
342
+ ],
343
+ "shell-header-collapse": [
344
+ {
345
+ "when": "host",
346
+ "emit": [
347
+ ".role-shell-header-collapse { width: var(--size-control-width-s); height: var(--size-control-width-s); border-radius: var(--radius-md); background-color: transparent; border: none; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }",
348
+ ".role-shell-header-collapse .el-icon, .role-shell-header-collapse svg { font-size: 18px; color: var(--color-text-secondary); }",
349
+ ".role-shell-header-collapse:hover { background-color: transparent; }",
350
+ ".role-shell-header-collapse:hover .el-icon, .role-shell-header-collapse:hover svg { color: var(--color-text-primary); }"
351
+ ]
352
+ }
353
+ ],
354
+ "shell-header-icon": [
355
+ {
356
+ "when": "host",
357
+ "emit": [
358
+ ".role-shell-header-icon { width: 32px !important; height: 32px !important; border-radius: var(--radius-md); display: inline-flex !important; align-items: center; justify-content: center; cursor: pointer; }",
359
+ ".role-shell-header-icon .el-icon, .role-shell-header-icon svg, .role-shell-header-icon [class*='i-ep'] { font-size: 16px; width: 16px; height: 16px; color: var(--color-text-secondary); }",
360
+ ".role-shell-header-icon:hover { background-color: #FAFAFA; }",
361
+ ".role-shell-header-icon:hover .el-icon, .role-shell-header-icon:hover svg { color: var(--color-text-primary); }"
362
+ ],
363
+ "reason": "对抗 SidebarFullScreen scoped .fullscreen-icon 38px×54px 与 set-icon w-36/h-bar:!important 提权"
364
+ },
365
+ {
366
+ "when": "variants with_text",
367
+ "emit": [
368
+ ".role-shell-header-icon--with_text { width: auto !important; padding: 0 8px; gap: 2px; font-size: 13px; font-weight: var(--font-weight-medium); color: var(--color-text-secondary); }",
369
+ ".role-shell-header-icon--with_text .lang-seg.is-active { color: var(--color-brand); }"
370
+ ]
371
+ }
372
+ ],
373
+ "shell-header-user": [
374
+ {
375
+ "when": "childRoles",
376
+ "emit": [
377
+ ".role-shell-header-user { padding: 0 8px 0 12px; gap: var(--space-2); border-radius: var(--radius-md); display: flex; align-items: center; cursor: pointer; height: var(--size-control-width-s); }",
378
+ ".role-shell-header-user:hover { background-color: #FAFAFA; }",
379
+ ".role-shell-header-user .user-meta { display: flex; flex-direction: column; gap: 4px; }",
380
+ ".role-shell-header-user .user-greeting { font-size: var(--font-size-md); color: var(--color-text-secondary); line-height: 1; }",
381
+ ".role-shell-header-user .user-name { font-size: var(--font-size-md); font-weight: var(--font-weight-medium); color: var(--color-text-primary); line-height: 1; }",
382
+ ".role-shell-header-user .user-avatar { width: 28px; height: 28px; border-radius: 9999px; background-color: var(--color-brand-subtle); color: var(--color-brand); font-size: 13px; font-weight: var(--font-weight-medium); border: 1px solid var(--color-border-base); display: inline-flex; align-items: center; justify-content: center; }",
383
+ ".role-shell-header-user:hover .user-avatar { border-color: var(--color-brand); }"
384
+ ]
385
+ }
386
+ ],
387
+ "shell-tabs": [
388
+ {
389
+ "when": "host",
390
+ "emit": [
391
+ ".tags-view.role-shell-tabs { height: var(--tabs-height); background-color: var(--color-surface) !important; border-bottom: 1px solid var(--color-border-base); box-shadow: none !important; padding: 0; }",
392
+ ".tags-view .chrome-tab__bg { display: none; }",
393
+ ".tags-view .chrome-tab-divider { width: 1px !important; height: 100% !important; background-color: var(--color-border-base) !important; margin: 0 !important; }",
394
+ ".tags-view .scroll-item { margin-right: 0 !important; padding-right: 0 !important; }"
395
+ ],
396
+ "reason": "chrome 梯形装饰隐藏;divider 重设为基线 1px 分隔线;压平 scoped margin/padding"
397
+ }
398
+ ],
399
+ "shell-tabs-item": [
400
+ {
401
+ "when": "host",
402
+ "emit": [
403
+ ".tags-view .scroll-item.role-shell-tabs-item { height: 40px !important; line-height: normal !important; padding: 0 12px !important; background-color: transparent !important; gap: 6px; display: flex !important; align-items: center; border: none !important; outline: none !important; box-shadow: none !important; border-radius: 0 !important; margin: 0 !important; color: var(--color-text-secondary) !important; }",
404
+ ".tags-view .scroll-item.role-shell-tabs-item:focus, .tags-view .scroll-item.role-shell-tabs-item a:focus { outline: none !important; }",
405
+ ".tags-view .scroll-item.role-shell-tabs-item .tag-title { font-size: var(--font-size-md); color: var(--color-text-secondary) !important; }",
406
+ ".tags-view .scroll-item.role-shell-tabs-item:hover { background-color: rgba(0,0,0,0.03) !important; }",
407
+ ".tags-view .scroll-item.role-shell-tabs-item:hover .tag-title { color: var(--color-text-primary) !important; }",
408
+ ".tags-view .scroll-item.role-shell-tabs-item-active, .tags-view .scroll-item.role-shell-tabs-item-active:hover { background-color: transparent !important; box-shadow: none !important; border: none !important; color: var(--color-brand) !important; }",
409
+ ".tags-view .scroll-item.role-shell-tabs-item-active .tag-title, .tags-view .scroll-item.role-shell-tabs-item-active:hover .tag-title { color: var(--color-brand) !important; font-weight: var(--font-weight-medium); }"
410
+ ],
411
+ "reason": "chrome-item scoped height calc(40-4)=36px、display inline-block、is-active 白字均带 data-v 特异性,全部 !important 压平"
412
+ }
413
+ ],
414
+ "shell-tabs-close": [
415
+ {
416
+ "when": "host",
417
+ "emit": [
418
+ ".tags-view .tag-close-btn.role-shell-tabs-close, .tags-view .el-icon-close.role-shell-tabs-close { width: 12px !important; height: 12px !important; opacity: 0.45; border-radius: var(--radius-sm) !important; color: #000000 !important; font-size: 12px !important; display: inline-flex !important; align-items: center; justify-content: center; }",
419
+ ".tags-view .tag-close-btn.role-shell-tabs-close .i-ep\\:close, .tags-view .tag-close-btn.role-shell-tabs-close [class*='close'] { font-size: 12px !important; width: 12px !important; height: 12px !important; }",
420
+ ".tags-view .tag-close-btn.role-shell-tabs-close:hover, .tags-view .el-icon-close.role-shell-tabs-close:hover { background-color: var(--color-state-error-bg) !important; color: var(--color-state-error) !important; opacity: 1; }"
421
+ ],
422
+ "reason": "scoped .tag-close-btn 16px/50%/brand 带 data-v,全部提权"
423
+ }
424
+ ],
425
+ "page-card": [
426
+ {
427
+ "when": "host",
428
+ "emit": ".role-page-card { background-color: var(--color-surface); border-radius: var(--radius-lg); box-shadow: 0 2px 8px rgba(0,0,0,0.06); border: none; overflow: hidden; padding: 0; }"
429
+ }
430
+ ],
431
+ "page-header": [
432
+ { "when": "host", "emit": ".role-page-header { padding: var(--space-5); border-bottom: 1px solid var(--color-border-base); display: flex; align-items: center; justify-content: space-between; }" },
433
+ { "when": "host+childRoles", "emit": ".role-page-header .role-page-header-actions { display: flex; align-items: center; gap: 8px; }", "reason": "页头动作组流式排列:admin 基线 page.header.title.actions gap space.2=8px(契约 roles 未单列该容器角色,由 adapter 结构等价承载)" }
434
+ ],
435
+ "page-header-title": [
436
+ {
437
+ "when": "host+inner+childRoles",
438
+ "emit": [
439
+ ".role-page-header-title { display: flex; flex-direction: column; }",
440
+ ".role-page-header-title .title-text { font-size: var(--font-size-title); font-weight: var(--font-weight-bold); color: var(--color-text-primary); line-height: 28px; }",
441
+ ".role-page-header-title .subtitle-text { font-size: var(--font-size-md); font-weight: var(--font-weight-normal); color: var(--color-text-secondary); line-height: 22px; margin-top: 2px; }"
442
+ ]
443
+ }
444
+ ],
445
+ "filter-section": [
446
+ { "when": "host", "emit": ".role-filter-section { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--space-5); align-items: center; padding: var(--space-5); border-bottom: 1px solid var(--color-border-base); }" }
447
+ ],
448
+ "filter-item": [
449
+ { "when": "host+span", "emit": ".role-filter-item { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }" }
450
+ ],
451
+ "filter-label": [
452
+ { "when": "host+inner", "emit": ".role-filter-label { width: 64px; text-align: right; font-size: var(--font-size-md); color: var(--color-text-secondary); flex-shrink: 0; }" }
453
+ ],
454
+ "filter-actions": [
455
+ { "when": "host", "emit": ".role-filter-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; justify-self: end; margin-left: auto; }" }
456
+ ],
457
+ "toolbar-bar": [
458
+ { "when": "host+childRoles", "emit": [
459
+ ".role-toolbar-bar { display: flex; align-items: center; justify-content: space-between; padding: var(--space-5) var(--space-5) var(--space-2); gap: var(--space-2); }",
460
+ ".role-toolbar-bar .toolbar-group { display: flex; align-items: center; gap: 8px; }",
461
+ ".role-toolbar-bar .selection-count { font-size: var(--font-size-md); color: var(--color-text-secondary); }"
462
+ ] }
463
+ ],
464
+ "table-wrapper": [
465
+ { "when": "host", "emit": ".role-table-wrapper { padding: 0 var(--space-5); background-color: transparent; }" }
466
+ ],
467
+ "table-cell-amount": [
468
+ { "when": "host+inner", "emit": ".el-table td.role-table-cell-amount { text-align: right; } .el-table td.role-table-cell-amount .cell { text-align: right; font-variant-numeric: tabular-nums; }" }
469
+ ],
470
+ "shell-content": [
471
+ { "when": "host", "emit": ".role-shell-content { background-color: var(--color-page-bg); padding: 0; gap: var(--space-4); }" }
472
+ ]
473
+ },
474
+
475
+ "visualSanity": {
476
+ "$comment": "第二遍通用断言(UX 合理性,不是契约值比对):verify-render.mjs 消费。规则与场景/页型无关——任何 EP 项目落地后都跑这套。失败修复定向:adapter.extraRules 提权 / 契约值,禁止手改生成物。",
477
+ "noWrap": {
478
+ "selectors": [
479
+ ".role-table-header-cell .cell",
480
+ ".role-tag-status",
481
+ "button.el-button",
482
+ ".role-shell-tabs-item .tag-title"
483
+ ],
484
+ "rule": "scrollWidth <= clientWidth + 1 且(.cell 类 white-space 为 nowrap);换行/溢出即 FAIL"
485
+ },
486
+ "noEllipsis": {
487
+ "selectors": [
488
+ ".role-table-header-cell .cell",
489
+ ".role-table-cell-action .cell",
490
+ ".role-page-header-title .title-text",
491
+ ".role-filter-label"
492
+ ],
493
+ "rule": "getComputedStyle(textOverflow)!=='ellipsis' 或虽为 ellipsis 但 scrollWidth<=clientWidth+1(未实际截断);截断即 FAIL"
494
+ },
495
+ "fullVisibility": {
496
+ "selectors": [
497
+ ".role-shell-header-collapse",
498
+ ".role-shell-header-icon",
499
+ ".role-shell-header-user",
500
+ ".role-filter-actions",
501
+ ".role-toolbar-bar .toolbar-group",
502
+ ".role-table-cell-action .cell .el-button, .role-table-cell-action .cell button",
503
+ ".role-pagination-bar .el-pagination"
504
+ ],
505
+ "rule": "每个选择器至少一个实例:display!==none && visibility!==hidden && rect.width>0 && rect.height>0;缺失/隐藏即 FAIL(折叠钮消失、操作列按钮被裁即此类)。工具栏右组(刷新/密度/列)由 ReTableBar 业务组件承载,不在此断言。"
506
+ },
507
+ "paddingSanity": {
508
+ "selectors": [
509
+ ".role-table-wrapper",
510
+ ".role-page-header",
511
+ ".role-filter-section"
512
+ ],
513
+ "rule": "左右 padding 均 >= 4px(内容不贴卡片边);为 0 即 WARN(除非契约 region 显式 padding 0)。toolbar/pagination 由 ReTableBar/RePagination 委托内边距,不在此断言。"
514
+ },
515
+ "rowHeightSanity": {
516
+ "selectors": [".role-table-cell"],
517
+ "rule": "数据 td 实际 rect.height 与契约 table.cell 密度档 height 差 <= 2px;被撑高即 FAIL(实证:48→57 事故)"
518
+ },
519
+ "chipHeight": {
520
+ "selectors": [".role-tag-status", ".role-shell-tabs-close"],
521
+ "rule": "定高小件(标签/关闭钮)rect.height 与契约声明 height 差 <= 2px——换行会把高度撑大,而宽度不溢出,no-wrap 抓不到(实证:类型标签两行换行事故)"
522
+ },
523
+ "tabFlat": {
524
+ "selectors": [".role-shell-tabs-item", ".role-shell-tabs-item-active"],
525
+ "rule": "平面页签形态:borderTopWidth<=0 且 outlineStyle===none 且 boxShadow===none;出现边框/描边/阴影即 FAIL(实证:chrome 残留框事故)"
526
+ },
527
+ "wrapperPadding": {
528
+ "selectors": [".role-table-wrapper"],
529
+ "expectPx": 20,
530
+ "rule": "表格容器左右 padding 与契约 table.wrapper 声明值(0 20px)比对,容差 2px(实证:表格左右边距偏差事故)"
531
+ },
532
+ "gapGeometry": {
533
+ "groups": [
534
+ {
535
+ "name": "action-divider",
536
+ "container": ".role-table-cell-action .cell",
537
+ "itemSel": ".el-button",
538
+ "expectGap": 8,
539
+ "tol": 2,
540
+ "basis": "契约 table.cell.action gap 8px(adapter 已把 .cell flex 化承载 gap,分割线形态由 cell-action-divider 兜底)"
541
+ },
542
+ { "name": "toolbar-left", "container": ".role-toolbar-bar .toolbar-group:first-child", "itemSel": "> *", "expectGap": 8, "tol": 2, "basis": "契约 toolbar.bar group.left gap 8px" },
543
+ { "name": "header-actions", "container": ".role-page-header .role-page-header-actions", "itemSel": "> *", "expectGap": 8, "tol": 2, "basis": "契约 page.header.title.actions gap space.2=8px" }
544
+ ],
545
+ "rule": "相邻兄弟元素 rect 间距与基线/契约声明值比对——等宽槽/组件库 margin 会破坏流式间距(实证:操作列三钮间距偏差事故)"
546
+ },
547
+ "headerAlign": [
548
+ { "name": "action-center", "sel": ".el-table th.role-table-header-cell--action .cell", "expect": "center", "basis": "基线 thead .col-actions text-align:center" },
549
+ { "name": "amount-right", "sel": ".el-table td.role-table-cell-amount .cell", "expect": "right", "basis": "契约 table.cell.amount text-align:right" }
550
+ ]
551
+ },
552
+
553
+ "variableBridges": {
554
+ "$comment": "ui-tokens.css 桥接段:契约令牌 → 项目既有变量消费链(design-tokens.scss / element-plus.scss / sidebar.scss / index.scss)。generate-css 自动追加,手写会漏。",
555
+ "brand": [
556
+ { "var": "--brand-primary", "from": "--color-brand", "important": true },
557
+ { "var": "--brand-hover", "from": "--color-brand-hover", "important": true },
558
+ { "var": "--brand-active", "from": "--color-brand-strong", "important": true },
559
+ { "var": "--primary-color", "from": "--color-brand" },
560
+ { "var": "--primary-5", "from": "--color-brand" }
561
+ ],
562
+ "elPrimary": [
563
+ { "var": "--el-color-primary", "from": "--color-brand", "important": true },
564
+ { "var": "--el-color-primary-light-3", "from": "--color-brand-strong" },
565
+ { "var": "--el-color-primary-light-5", "value": "#92ADFF" },
566
+ { "var": "--el-color-primary-light-7", "value": "#BDCEFF" },
567
+ { "var": "--el-color-primary-light-8", "value": "#D3DEFF" },
568
+ { "var": "--el-color-primary-light-9", "value": "#E9EFFF" },
569
+ { "var": "--el-color-primary-dark-2", "value": "#1D49CC" }
570
+ ],
571
+ "geometry": [
572
+ { "var": "--header-height", "from": "layout:header.height", "important": true },
573
+ { "var": "--tabs-height", "from": "layout:tabs.height", "important": true },
574
+ { "var": "--sidebar-width", "from": "layout:sidebar.width", "important": true },
575
+ { "var": "--sidebar-collapsed-width", "from": "layout:sidebar.collapsedWidth", "important": true },
576
+ { "var": "--layout-content-padding", "from": "layout:content.padding", "important": true },
577
+ { "var": "--layout-header-offset", "value": "calc(var(--header-height) + var(--tabs-height))", "important": true },
578
+ { "var": "--vts-theme-menu-bg", "from": "--color-shell-bg", "important": true },
579
+ { "var": "--vts-tags-height", "value": "var(--tabs-height)" },
580
+ { "var": "--vts-bar-height", "value": "var(--header-height)" },
581
+ { "var": "--vts-tabs-height", "value": "var(--tabs-height)" },
582
+ { "var": "--vts-layout-header-offset", "value": "var(--layout-header-offset)" },
583
+ { "var": "--vts-margin", "value": "var(--layout-content-padding)" }
584
+ ],
585
+ "table": [
586
+ { "var": "--el-fill-color-light", "value": "#FAFAFA" },
587
+ { "var": "--el-table-header-bg-color", "value": "#FAFAFA" },
588
+ { "var": "--el-table-border-color", "from": "--color-border-base" },
589
+ { "var": "--el-table-row-hover-bg-color", "value": "#FAFAFA" }
590
+ ],
591
+ "text": [
592
+ { "var": "--el-text-color-primary", "from": "--color-text-primary" },
593
+ { "var": "--el-text-color-regular", "from": "--color-text-secondary" },
594
+ { "var": "--el-text-color-secondary", "from": "--color-text-tertiary" },
595
+ { "var": "--el-text-color-placeholder", "value": "#00000040" },
596
+ { "var": "--el-text-color-disabled", "value": "#00000040" }
597
+ ],
598
+ "border": [
599
+ { "var": "--el-border-color", "from": "--color-border-strong" },
600
+ { "var": "--el-border-color-light", "from": "--color-border-base" },
601
+ { "var": "--el-border-color-lighter", "from": "--color-border-base" }
602
+ ],
603
+ "bg": [
604
+ { "var": "--el-bg-color-page", "from": "--color-page-bg" },
605
+ { "var": "--el-fill-color-blank", "from": "--color-surface" }
606
+ ]
607
+ },
608
+
609
+ "roleSupplementVars": {
610
+ "$comment": "契约 role 声明中出现但 tokens 未定义的辅助变量(如 tag 变体边框色),generate-css 落进 ui-tokens.css 辅助段。",
611
+ "--tag-success-border": "#D9F7BE",
612
+ "--tag-warning-border": "#FFE58F",
613
+ "--tag-error-border": "#FFCCC2",
614
+ "--tag-default-bg": "rgba(0, 0, 0, 0.04)"
615
+ },
616
+
617
+ "layoutBridge": {
618
+ "$comment": "ui-layout.css 生成策略:项目壳层为「侧栏 fixed + 顶栏/页签 fixed-header + 内容 padding 偏移」,不是纯 grid。定位几何由 sidebar.scss(--sidebar-width 驱动)与 lay-header 承担,本文件只翻译区域视觉值。",
619
+ "shellClass": [".ui-page", ".role-shell-shell"],
620
+ "regionClasses": {
621
+ "sidebar": [".ui-region-sidebar", ".role-shell-sidebar"],
622
+ "header": [".ui-region-header", ".role-shell-header"],
623
+ "tabs": [".ui-region-tabs", ".role-shell-tabs"],
624
+ "content": [".ui-region-content", ".role-shell-content"]
625
+ },
626
+ "skipGeometry": {
627
+ "sidebar": ["width", "collapsedWidth", "position", "offset", "zIndex"],
628
+ "header": ["position", "offset", "zIndex"],
629
+ "tabs": ["position", "offset", "zIndex", "bleed"],
630
+ "content": ["padding", "gap", "display", "flex-direction", "position"]
631
+ },
632
+ "skipNote": "sidebar 宽度走 --sidebar-width 桥接;header/tabs 定位走 fixed-header;content padding 走 --vts-margin(.main-content 承担)——重复设会打架。"
633
+ }
634
+ }