@qilitt-mickey/vue3-temp-skill 1.1.71 → 1.1.74

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 (86) hide show
  1. package/SKILL.md +137 -136
  2. package/bin/cli.js +1 -1
  3. package/dist/theme-vars.js +1 -1
  4. package/dist/theme.css +1 -1
  5. package/mapping/basic/color.json +35 -35
  6. package/mapping/basic/radius.json +17 -17
  7. package/mapping/basic/semantic-values.json +72 -72
  8. package/mapping/basic/spacing.json +21 -21
  9. package/mapping/basic/typography.json +21 -21
  10. package/mapping/component/button.json +90 -90
  11. package/mapping/component/card.json +31 -31
  12. package/mapping/component/input.json +42 -42
  13. package/mapping/component/overlay.json +79 -79
  14. package/mapping/component/pagination.json +34 -34
  15. package/mapping/component/table.json +42 -42
  16. package/mapping/component/tag.json +48 -48
  17. package/mapping/layout/breakpoint.json +20 -20
  18. package/mapping/layout/shell-geometry.json +26 -26
  19. package/mapping/scenes/admin/content.json +494 -494
  20. package/mapping/scenes/admin/layout.json +574 -574
  21. package/package.json +1 -1
  22. package/parser/fixtures/changeset-fullpage-restore.json +259 -138
  23. package/parser/fixtures/changeset-gap-block.json +24 -0
  24. package/parser/fixtures/changeset-legacy.json +11 -11
  25. package/parser/fixtures/changeset-neg1.json +8 -8
  26. package/parser/fixtures/changeset-neg2.json +10 -10
  27. package/parser/fixtures/changeset-neg3.json +22 -22
  28. package/parser/fixtures/changeset-neg4-g8.json +15 -15
  29. package/parser/fixtures/changeset-neg5-g8-stub.json +26 -26
  30. package/parser/fixtures/changeset-neg6-g9-identity.json +39 -39
  31. package/parser/fixtures/changeset-neg7-g10-dims.json +57 -57
  32. package/parser/fixtures/changeset-neg8-g11-oracle.json +57 -57
  33. package/parser/fixtures/changeset-pos-theme-neutral.json +264 -264
  34. package/parser/fixtures/changeset-pos-theme-nometa.json +260 -260
  35. package/parser/fixtures/changeset-pos.json +50 -43
  36. package/parser/fixtures/changeset-registry-gap.json +29 -29
  37. package/parser/fixtures/changeset-v32-fields.json +71 -63
  38. package/parser/fixtures/fake-project/src/styles/app.scss +5 -5
  39. package/parser/fixtures/fake-project/src/views/list.vue +13 -13
  40. package/parser/fixtures/registry-bad.json +11 -11
  41. package/parser/fixtures/registry-sample.json +15 -15
  42. package/parser/fixtures/verify/actual-clean.json +35 -35
  43. package/parser/fixtures/verify/actual.json +33 -33
  44. package/parser/fixtures/verify/mockup-baseline-admin-list.html +27 -0
  45. package/parser/fixtures/verify/mockup-neutral.html +26 -26
  46. package/parser/fixtures/verify/mockup-nometa.html +26 -26
  47. package/parser/fixtures/verify/oracle.json +37 -37
  48. package/parser/fixtures/verify/snapshot-latest.json +102 -102
  49. package/parser/generator.js +178 -178
  50. package/parser/index.js +2675 -2605
  51. package/parser/loader.js +66 -66
  52. package/parser/override.js +119 -119
  53. package/parser/regression.js +301 -293
  54. package/parser/validator.js +206 -206
  55. package/parser/watch.js +103 -103
  56. package/references/auth-pages.md +217 -217
  57. package/references/base-code-dict.md +56 -56
  58. package/references/code-quality.md +3 -2
  59. package/references/data-compare.md +509 -509
  60. package/references/data-writeback.md +124 -124
  61. package/references/design-apply.md +167 -167
  62. package/references/detail-page.md +119 -119
  63. package/references/download-export.md +97 -97
  64. package/references/feedback-loading.md +104 -104
  65. package/references/feedback-ui.md +134 -134
  66. package/references/i18n-localization.md +230 -230
  67. package/references/project-inventory.md +438 -438
  68. package/references/rich-text.md +94 -94
  69. package/references/seamless-scroll.md +47 -47
  70. package/references/steps/maintenance.md +31 -31
  71. package/references/steps/regression.md +49 -49
  72. package/references/steps/step0-preflight.md +58 -58
  73. package/references/steps/step1-match.md +64 -64
  74. package/references/steps/step1b-audit.md +23 -23
  75. package/references/steps/step1c-registry.md +29 -29
  76. package/references/steps/step2-structure.md +73 -73
  77. package/references/steps/step3-style.md +33 -33
  78. package/references/steps/step3b-shell.md +61 -61
  79. package/references/steps/step3c-priority.md +26 -26
  80. package/references/steps/step4-l3.md +14 -14
  81. package/references/steps/step5-gates.md +63 -63
  82. package/references/steps/step6-verify.md +77 -77
  83. package/references/verify-captcha.md +119 -119
  84. package/scripts/apply-final-gate.mjs +170 -170
  85. package/scripts/check.mjs +38 -5
  86. package/scripts/design-audit.mjs +1502 -1498
@@ -1,574 +1,574 @@
1
- {
2
- "$comment": "admin 场景 · 布局模块语义 ID 全属性映射(vue3-web-temp 框架组件实证)。每条含结构定位(selector/file)、形态切换(forms)、样式映射(css_vars 优先 + custom_style_map 兜底)。style_scope 为样式必须包裹的容器类名;:root 表示全局令牌层。版本恒 1.0.0(由 SKILL.md 体系版本统一管理,不单独演进)。",
3
- "meta": {
4
- "layer": "scene",
5
- "scene": "admin",
6
- "domain": "layout",
7
- "version": "1.0.0",
8
- "tech_stack": "vue3 + element-plus + vue3-web-temp"
9
- },
10
- "mappings": {
11
- "admin.layout.sidebar": {
12
- "type": "module",
13
- "selector": ".sidebar-container",
14
- "file": "src/layout/components/lay-sidebar/NavVertical.vue",
15
- "style_scope": ".sidebar-container",
16
- "default_props": { "width": "var(--sidebar-width, 208px)" },
17
- "children": [
18
- "admin.layout.sidebar.logo_area",
19
- "admin.layout.sidebar.menu",
20
- "admin.layout.sidebar.collapse_trigger"
21
- ],
22
- "css_vars": {
23
- "width": "--sidebar-width",
24
- "collapsed_width": "--sidebar-collapsed-width",
25
- "collapse_bar_height": "--sidebar-collapse-bar-height",
26
- "menu_item_height": "--el-menu-item-height"
27
- },
28
- "custom_style_map": {
29
- "bg": "background-color",
30
- "border_right": "border-right",
31
- "box_shadow": "box-shadow"
32
- }
33
- },
34
- "admin.layout.sidebar.logo_area": {
35
- "type": "element",
36
- "selector": ".sidebar-logo",
37
- "file": "src/layout/components/lay-sidebar/components/SidebarLogo.vue",
38
- "style_scope": ".sidebar-container",
39
- "visible_prop": "ShowLogo(platform-config.json / emitter logoChange)",
40
- "css_vars": {
41
- "height": "--vts-bar-height",
42
- "bg": "--vts-theme-sidebar-logo",
43
- "title_color": "--vts-theme-sub-menu-active-text"
44
- },
45
- "custom_style_map": {
46
- "title_font_size": "font-size",
47
- "title_font_weight": "font-weight"
48
- }
49
- },
50
- "admin.layout.sidebar.menu": {
51
- "type": "component",
52
- "component": "ElMenu",
53
- "selector": ".sidebar-container .el-menu",
54
- "file": "src/layout/components/lay-sidebar/NavVertical.vue",
55
- "style_scope": ".sidebar-container",
56
- "forms": {
57
- "pill": "整块胶囊底色高亮(sidebar.scss 消费 --vts-theme-menu-active-bg,带 !important)。suppress 必含 right_indicator_legacy——出厂 element-plus.scss 的 .el-menu-item.is-active{border-right:var(--menu-active-border-right)} 是活通道,不收口会出现左右两根竖条并存",
58
- "indicator_left": "仅左竖条指示、无胶囊:先在本作用域覆写 --vts-theme-menu-active-bg: transparent 关胶囊,再于设计层新建 ::after 竖条消费 --vts-theme-menu-active-before。suppress 必含 right_indicator_legacy",
59
- "indicator_right": "仅右竖条指示、无胶囊:同上关胶囊后 ::after 挂 right:0。出厂右竖条通道 --menu-active-border-right(element-plus.scss 消费、design-tokens.scss 定义为 3px solid 品牌色)是活通道,可复用也可收口后自建,二选一必须显式声明",
60
- "indicator_underline": "仅底部横线指示、无胶囊:关胶囊后 ::after 挂 bottom:0(宽取 100% 或指定宽度,厚取 indicator_thickness)。suppress 必含 right_indicator_legacy",
61
- "none": "无指示:胶囊与竖条均关闭,仅文字变色。suppress 必含 right_indicator_legacy",
62
- "pill_indicator_left": "胶囊底色 + 左竖条**并存**复合形态(设计实证:效果图 .menu-item.active 同时声明 background:var(--primary) 与 ::before 竖条):胶囊照 pill 走 --vts-theme-menu-active-bg;竖条照 indicator_left 走 --vts-theme-menu-active-before(设计层新建 ::after/::before 消费者)。suppress 必含 right_indicator_legacy(出厂右竖条必须收口)。⚠菜单项宿主盒必须声明 margin 横向内缩(custom_style_map margin_x),否则竖条负偏移落进容器外被 overflow 裁掉——竖条偏移值以「容器 padding − 竖条 left 偏移」为语境换算,禁止照搬外部效果图常量"
63
- },
64
- "suppress_rules": {
65
- "pill": ["right_indicator_legacy"],
66
- "indicator_left": ["right_indicator_legacy"],
67
- "indicator_right": ["right_indicator_legacy"],
68
- "indicator_underline": ["right_indicator_legacy"],
69
- "none": ["right_indicator_legacy"],
70
- "pill_indicator_left": ["right_indicator_legacy"]
71
- },
72
- "field_forms": {
73
- "active_indicator_width": ["indicator_left", "indicator_right", "indicator_underline", "pill_indicator_left"],
74
- "active_indicator_thickness": ["indicator_left", "indicator_right", "indicator_underline", "pill_indicator_left"],
75
- "active_indicator_style": ["indicator_left", "indicator_right", "indicator_underline", "pill_indicator_left"],
76
- "menu_active_bg": ["pill", "pill_indicator_left"]
77
- },
78
- "css_vars": {
79
- "menu_bg": "--vts-theme-menu-bg",
80
- "menu_text": "--vts-theme-menu-text",
81
- "menu_hover_bg": "--vts-theme-menu-hover",
82
- "menu_title_hover": "--vts-theme-menu-title-hover",
83
- "sub_menu_bg": "--vts-theme-sub-menu-bg",
84
- "sub_menu_active_text": "--vts-theme-sub-menu-active-text",
85
- "menu_active_bg": "--vts-theme-menu-active-bg",
86
- "menu_active_indicator": "--vts-theme-menu-active-before",
87
- "right_indicator_legacy": "--menu-active-border-right",
88
- "sidebar_border": "--vts-sidebar-border-color",
89
- "item_height": "--el-menu-item-height"
90
- },
91
- "custom_style_map": {
92
- "active_indicator_width": "width",
93
- "active_indicator_thickness": "height",
94
- "active_indicator_style": "border-radius",
95
- "padding_y": "padding-block",
96
- "margin_x": "margin-inline",
97
- "font_size": "font-size",
98
- "font_weight": "font-weight",
99
- "text_color": "color"
100
- },
101
- "anchors": [
102
- { "kind": "class", "layer": "host", "target": ".sidebar-container .el-menu-item" },
103
- { "kind": "class", "layer": "inner", "target": ".sidebar-container .el-menu-item > .el-menu-item__content" },
104
- { "kind": "css_var", "target": "--vts-theme-menu-active-bg" },
105
- { "kind": "css_var", "target": "--vts-theme-menu-active-before" }
106
- ],
107
- "preconditions": [
108
- "出厂菜单项盒模型是「无横向 margin(margin: 4px 0)+ 胶囊用 inset 内缩」;指示条几何必须以这个宿主盒为基准计算偏移。照搬外部效果图上「依赖菜单项横向 margin」的负偏移量会落进容器外并被 overflow 裁掉(这是指示条「映射了却没效果」的根因:值搬了、让该值成立的宿主盒模型没搬)。",
109
- "--vts-theme-menu-active-before 出厂为透明且全项目无消费者;声明 indicator_* 形态必须成对落地「关胶囊令牌 + 新建消费者」,只改色值不建消费者 = 未施工。",
110
- "激活态作用层级(active_scope,默认 leaf):胶囊与指示条**只作用于叶子菜单项**(.el-menu-item.is-active)。可展开分组的标题(.el-sub-menu__title)在「其下有激活子项」时会被 EP 打上 is-active,**不得**继承胶囊与指示条——否则分组标题同时长出胶囊、竖条并与右侧展开箭头叠压。设计层写激活态时必须把选择器锚定叶子项,禁止把 .el-sub-menu.is-active > .el-sub-menu__title 与 .el-menu-item.is-active 并列写成同一组激活声明。"
111
- ],
112
- "priority": {
113
- "strategy": "deep_qualified",
114
- "reason": "出厂 sidebar.scss 的胶囊规则用 !important,设计层需以同等或更高权重覆盖。"
115
- },
116
- "$note": "侧栏配色挂载点为 html[data-theme='xxx'](theme.scss 8 套预设);设计输出深色侧栏 → Theme=default + Version++(useTheme 规则),浅色 → Theme=light。⚠文本完整性红线:菜单项名称必须完整显示(el-menu 自带 ellipsis 折叠溢出菜单),禁止改 menu 文本截断/隐藏策略;item_height 加大时确认行高不挤压文字。宽度类改动(--sidebar-width)后必须目视验证长菜单名显示。⚠激活态出厂中性基线(禁止把某张图的结论写进源码):出厂形态 = pill 胶囊高亮;--vts-theme-menu-active-before 出厂默认 transparent 且**全项目无消费者**(死通道)。因此 form=indicator_* / pill_indicator_left 时必须在本条目 style_scope 内成对落地两件事才算施工完成——① 竖条消费者(form 不含 pill 时另需覆写 --vts-theme-menu-active-bg: transparent 关胶囊);② 在设计层文件(不可写出厂 sidebar.scss)新建 ::after/::before 消费者引用 var(--vts-theme-menu-active-before)。缺任一项 = 「映射了却没效果」。所有几何参数(方位/粗细/长度/圆角/内缩)取自变更集 style 字段,禁止写死 left:0 / 3px 等常量。⚠field_forms 硬闸(parser G7 机检):style 声明的字段必须被当前 form 消费——如 active_indicator_* 只在 indicator_* / pill_indicator_left 形态下有消费者,声明 pill 却带竖条字段 = 字段被静默丢弃(如声明 pill 却带 active_indicator_* 竖条字段,竖条令牌会被设计层置透明 → 效果图要求的左竖条消失)。"
117
- },
118
- "admin.layout.sidebar.menu_item_icon": {
119
- "type": "element",
120
- "selector": ".sidebar-container .el-menu-item .el-icon, .sidebar-container .el-menu-item .el-menu-item__icon",
121
- "file": "src/layout/components/lay-sidebar/NavVertical.vue(菜单图标,el-menu-item 内 svg-icon)",
122
- "style_scope": ".sidebar-container",
123
- "css_vars": {},
124
- "custom_style_map": {
125
- "icon_size": "font-size",
126
- "icon_color": "color"
127
- },
128
- "anchors": [
129
- { "kind": "class", "layer": "inner", "target": ".sidebar-container .el-menu-item .el-icon" }
130
- ],
131
- "$note": "菜单图标 16×16px(unified-framework §6.17 / §1 导航栏「图标 16×16px」)。图标为 font-icon,尺寸经 font-size 承载、颜色经 color 承载,落 inner 层(图标元素本身)。"
132
- },
133
- "admin.layout.sidebar.collapse_trigger": {
134
- "type": "element",
135
- "selector": ".left-collapse / .center-collapse",
136
- "file": "src/layout/components/lay-sidebar/components/SidebarLeftCollapse.vue + SidebarCenterCollapse.vue",
137
- "style_scope": ".sidebar-container",
138
- "forms": {
139
- "bottom_bar": "SidebarLeftCollapse(底部条,出厂默认)",
140
- "center_edge": "SidebarCenterCollapse(侧缘中点,折叠/悬停时显示)"
141
- },
142
- "suppress_rules": {
143
- "center_edge": ["bottom_bar"],
144
- "bottom_bar": ["center_edge"]
145
- },
146
- "css_vars": {
147
- "bar_height": "--sidebar-collapse-bar-height"
148
- },
149
- "custom_style_map": {
150
- "trigger_width": "width",
151
- "trigger_height": "height",
152
- "trigger_color": "color"
153
- }
154
- },
155
- "admin.layout.header": {
156
- "type": "module",
157
- "selector": ".navbar",
158
- "file": "src/layout/components/lay-navbar/index.vue",
159
- "style_scope": ".navbar",
160
- "default_props": { "height": "var(--vts-bar-height)" },
161
- "children": [
162
- "admin.layout.header.collapse_trigger",
163
- "admin.layout.header.logo_area",
164
- "admin.layout.header.breadcrumb",
165
- "admin.layout.header.lang_switch",
166
- "admin.layout.header.fullscreen",
167
- "admin.layout.header.setting_button",
168
- "admin.layout.header.user_profile"
169
- ],
170
- "css_vars": {
171
- "height": "--header-height",
172
- "padding_x": "--header-padding-x"
173
- },
174
- "custom_style_map": {
175
- "bg": "background-color",
176
- "box_shadow": "box-shadow",
177
- "gap": "gap",
178
- "border_color": "border-color",
179
- "align_items": "align-items"
180
- },
181
- "preconditions": [
182
- "顶栏内容垂直居中:--header-height 变更(如 54px)后,宿主 .navbar 必须显式 align-items: center——出厂顶栏内元素高度不一(折叠钮 40px / 文字行 / 头像),不显式声明会整体偏上。"
183
- ]
184
- },
185
- "admin.layout.header.logo_area": {
186
- "type": "element",
187
- "selector": ".navbar .siderLogo",
188
- "file": "src/layout/components/lay-sidebar/components/SidebarLogo.vue(navbar 内复用)",
189
- "style_scope": ".navbar",
190
- "visible_note": "仅 horizontal 布局在顶栏渲染 logo(v-if layout==='horizontal' && showLogo)",
191
- "css_vars": {},
192
- "custom_style_map": {
193
- "min_width": "min-width",
194
- "height": "height"
195
- }
196
- },
197
- "admin.layout.header.breadcrumb": {
198
- "type": "component",
199
- "component": "SidebarBreadCrumb",
200
- "selector": ".navbar-breadcrumb-wrap",
201
- "file": "src/layout/components/lay-sidebar/components/SidebarBreadCrumb.vue",
202
- "style_scope": ".navbar",
203
- "visible_note": "v-if layout!=='mix' && layout!=='horizontal' && device!=='mobile'",
204
- "css_vars": {
205
- "text_color": "--el-text-color-regular"
206
- },
207
- "custom_style_map": {
208
- "font_size": "font-size"
209
- },
210
- "anchors": [
211
- { "kind": "class", "layer": "host", "target": ".navbar .navbar-breadcrumb-wrap" }
212
- ],
213
- "priority": {
214
- "strategy": "deep_qualified",
215
- "reason": "出厂组件自身 scoped 规则与设计层同权重,仅靠后置加载顺序不可靠;显隐收口与样式覆盖都必须显式提权(面包屑 display:none 被同权重 scoped 规则反压即属此类)。"
216
- },
217
- "$note": "分隔符为结构属性(breadcrumb separator 字符),不在样式映射范围"
218
- },
219
- "admin.layout.header.lang_switch": {
220
- "type": "component",
221
- "component": "ReLanguageSwitch(ElDropdown 包裹)",
222
- "selector": ".navbar .language-trigger",
223
- "file": "src/components/ReLanguageSwitch/src/index.vue",
224
- "style_scope": ".navbar",
225
- "forms": {
226
- "icon_only": "出厂现状:纯图标触发器(.language-trigger > .language-icon),下拉菜单选语言",
227
- "inline_switch": "并排切换形态:中 / EN 平铺在触发器内,点击即切换。**落地必须成套三件事**——① 显并排文字(.language-text 由隐藏改可见);② 收口图标(suppress icon_only);③ **收口下拉浮层**(suppress dropdown_popper:出厂 ElDropdown 的 popper 必须不再弹出,否则点触发器会从下方展开 English/中文 浮层遮挡页签栏)。缺③ = 形态未落地(只加了文字、交互仍是下拉)"
228
- },
229
- "suppress_rules": {
230
- "inline_switch": ["icon_only", "dropdown_popper"]
231
- },
232
- "structure_ops_required": {
233
- "inline_switch": ["收口 ElDropdown 触发(改 trigger 为不可弹出 / 移除 dropdown 插槽消费 / 用保形 v-if 切换为直选按钮任一),使点击不再产生浮层"]
234
- },
235
- "preconditions": [
236
- "语言切换的形态由 form 决定,且 form 是「加法 + 减法」成对语义:inline_switch 不仅要新增并排文字,还必须收口出厂的下拉浮层与图标形态。只加不减时,浮层仍会弹出(触发器与浮层二者并存),视觉上从触发器下方展开的浮层会压住页签栏。",
237
- "浮层属 teleport 到 body 的 popper,样式层无法收口(.language-trigger 上的规则管不到 popper);必须从结构层收口 ElDropdown 的触发行为。"
238
- ],
239
- "css_vars": {
240
- "icon_color": "--el-text-color-regular",
241
- "hover_bg": "--el-fill-color-light"
242
- },
243
- "sub_selectors": {
244
- "icon": ".language-trigger .language-icon",
245
- "text": ".language-trigger .language-text"
246
- },
247
- "custom_style_map": {
248
- "icon_size": "font-size",
249
- "gap": "gap",
250
- "text_font_size": "font-size",
251
- "text_color": "color"
252
- },
253
- "$note": "inline_switch 并排切换形态:下拉项平铺为触发器旁切换组,按 v-if 保形切换增量插入,不删原代码;同时收口图标形态与下拉浮层(浮层属 teleport popper,样式层管不到,必须结构收口)。"
254
- },
255
- "admin.layout.header.collapse_trigger": {
256
- "type": "element",
257
- "selector": ".navbar .header-collapse-btn",
258
- "file": "src/layout/components/lay-navbar/index.vue(顶栏内嵌形态为增量插入;出厂折叠按钮位于侧栏,见 admin.layout.sidebar.collapse_trigger)",
259
- "style_scope": ".navbar",
260
- "forms": {
261
- "header_inline": "顶栏内嵌折叠按钮:40×40 纯图标、与首页页签左对齐、hover 仅文字加深(出厂无此元素,v-if 保形插入机制落地)",
262
- "sidebar_bottom": "出厂现状:侧栏底部折叠条(SidebarLeftCollapse)",
263
- "sidebar_center": "侧栏侧缘中点(SidebarCenterCollapse)"
264
- },
265
- "suppress_rules": {
266
- "header_inline": ["sidebar_bottom", "sidebar_center"]
267
- },
268
- "css_vars": {
269
- "icon_color": "--el-text-color-regular",
270
- "hover_bg": "--el-fill-color-light"
271
- },
272
- "custom_style_map": {
273
- "btn_width": "width",
274
- "btn_height": "height",
275
- "icon_size": "font-size",
276
- "border_radius": "border-radius"
277
- },
278
- "$note": "form=header_inline 时 AI 增量插入顶栏按钮片段(useApp isCollapse 切换),样式全部走 custom_style_map 生成的 :deep 隔离规则;出厂 sidebar_bottom 形态代码保留不删(显隐≠删除),设计侧 visible:false 时隐藏侧栏折叠条避免双按钮并存"
279
- },
280
- "admin.layout.header.fullscreen": {
281
- "type": "component",
282
- "component": "SidebarFullScreen",
283
- "selector": "#full-screen",
284
- "file": "src/layout/components/lay-sidebar/components/SidebarFullScreen.vue",
285
- "style_scope": ".navbar",
286
- "css_vars": {
287
- "text_color": "--el-text-color-primary",
288
- "hover_bg": "--el-fill-color-light"
289
- },
290
- "custom_style_map": {
291
- "icon_size": "font-size",
292
- "width": "width"
293
- }
294
- },
295
- "admin.layout.header.setting_button": {
296
- "type": "element",
297
- "selector": ".set-icon",
298
- "file": "src/layout/components/lay-navbar/index.vue",
299
- "style_scope": ".navbar",
300
- "visible_prop": "无出厂配置开关(出厂常显)",
301
- "css_vars": {
302
- "height": "--vts-bar-height"
303
- },
304
- "custom_style_map": {
305
- "icon_size": "font-size",
306
- "width": "width",
307
- "hover_bg": "background-color",
308
- "text_color": "color"
309
- },
310
- "$note": "存在性收口默认对象:效果图未出现该按钮时,变更集以 visible:false 声明 → 落地为设计层文件内 .navbar .set-icon { display:none }(禁止删出厂代码行、禁止直接改 lay-navbar/index.vue 表达「这张图不要按钮」)。反向:设计需要该按钮时不声明即可(出厂已常显)。同一 DOM(含 v-tippy 提示)通用,图标/尺寸经本条目 style 字段动态覆盖。"
311
- },
312
- "admin.layout.header.user_profile": {
313
- "type": "component",
314
- "component": "ElDropdown",
315
- "selector": ".navbar-right .el-dropdown-link",
316
- "file": "src/layout/components/lay-navbar/index.vue",
317
- "style_scope": ".navbar",
318
- "forms": {
319
- "avatar_name": "出厂默认:22×22 头像 + 用户名(window.userName),无问候语",
320
- "greeting_avatar_name": "问候语 + 用户名 + 头像(问候节点出厂不存在 → 由 AI 按本 form 在 lay-navbar 用户区增量插入,属结构通道施工)",
321
- "greeting_name": "问候语 + 用户名,无头像",
322
- "avatar_only": "仅头像",
323
- "name_only": "仅用户名"
324
- },
325
- "suppress_rules": {
326
- "greeting_name": ["avatar_name"],
327
- "avatar_only": ["avatar_name"],
328
- "name_only": ["avatar_name"]
329
- },
330
- "sub_selectors": {
331
- "$comment": "avatar/name 为点位内部部件,不设独立语义 ID(符合 4 段 ID 上限);样式字段按前缀路由到对应选择器。form 含 greeting 时新增节点统一用 class 前缀 vts-header-greeting / vts-header-username(插入前先查重名)",
332
- "avatar": ".navbar-right .el-dropdown-link img",
333
- "name": ".navbar-right .el-dropdown-link p"
334
- },
335
- "css_vars": {
336
- "height": "--vts-bar-height",
337
- "text_color": "--el-text-color-primary"
338
- },
339
- "custom_style_map": {
340
- "avatar_width": "width",
341
- "avatar_height": "height",
342
- "avatar_radius": "border-radius",
343
- "name_font_size": "font-size",
344
- "name_font_weight": "font-weight",
345
- "greeting_font_size": "font-size",
346
- "greeting_font_weight": "font-weight",
347
- "gap": "gap"
348
- },
349
- "anchors": [
350
- { "kind": "class", "layer": "host", "target": ".navbar .navbar-right .el-dropdown-link" },
351
- { "kind": "class", "layer": "inner", "target": ".navbar .navbar-right .el-dropdown-link img" },
352
- { "kind": "class", "layer": "inner", "target": ".navbar .navbar-right .el-dropdown-link p" }
353
- ],
354
- "preconditions": [
355
- "出厂 DOM 只有「头像 img + 用户名 p」,任何 greeting 组合都必须**先做结构增量**再谈样式;未新增节点时 greeting_* 样式字段无落点(这是「欢迎区没出现」的根因)。",
356
- "组合形态由 form 决定,样式字段按 sub_selectors 前缀路由到对应部件选择器。"
357
- ],
358
- "$note": "⚠出厂中性基线:出厂 DOM 只有「头像 img + 用户名 p」,**没有任何问候语节点**(词典曾误记 .header-welcome 已实现,属虚假前提)。因此 form 含 greeting 时必须走结构增量新增 DOM,且节点文案模板(时段问候语 + 用户名)由业务层提供,本点位只承载组合形态与样式——禁止把具体问候文案写进组件。反向同理:设计只要纯头像/纯用户名时以 form=avatar_only/name_only 声明,出厂多余节点同样按收口处理(隐藏不删)。"
359
- },
360
- "admin.layout.tabs": {
361
- "type": "module",
362
- "selector": ".tags-view",
363
- "file": "src/layout/components/lay-tag/index.vue",
364
- "style_scope": ".tags-view",
365
- "visible_prop": "HideTabs(platform-config.json)",
366
- "children": ["admin.layout.tabs.home_tab", "admin.layout.tabs.item", "admin.layout.tabs.context_menu"],
367
- "forms": {
368
- "chrome": "谷歌页签(出厂 ShowModel=chrome):SVG 梯形外形 + .chrome-tab-divider(1px×14px 深色)+ 关闭钮 16px 主色;激活态白字 + box-shadow",
369
- "card": "卡片页签(ShowModel=card):圆角卡片底 + --vts-tag-card-* 整组令牌 + 关闭钮 hover 才显现(出厂 opacity:0)",
370
- "flat": "平面页签(设计规范口径,出厂无此形态):ShowModel 仍设 card(复用 card 结构 = 图标槽 + 关闭钮 + resolveCardTabIcon 数据驱动),平面观感全部由设计层覆写达成 —— ① --vts-tag-card-idle-bg/hover-bg/active-bg 置 transparent;② --vts-tag-card-radius 与 --vts-tag-card-gap 置 0;③ 激活态仅文字/图标变主色 + font-weight 500,不加 border-bottom / box-shadow;④ 关闭钮 opacity 覆写为常显值(出厂 card 为 0);⑤ 首页页签项宽=高=--vts-tag-card-height 居中呈方块;⑥ 页签间 1px×100% 贯穿分割线(card 无该元素,需设计层 ::after/::before 新建)。几何与色值一律取自变更集 style 字段,禁止写死常量"
371
- },
372
- "suppress_rules": {
373
- "flat": [
374
- "card_idle_bg",
375
- "card_active_bg",
376
- "card_hover_bg",
377
- "card_radius",
378
- "card_gap",
379
- "card_active_text",
380
- "card_idle_text",
381
- "card_close_color"
382
- ]
383
- },
384
- "css_vars": {
385
- "height": "--tabs-height",
386
- "chrome_inset_top": "--vts-tag-chrome-inset-top",
387
- "card_height": "--vts-tag-card-height",
388
- "card_radius": "--vts-tag-card-radius",
389
- "card_gap": "--vts-tag-card-gap",
390
- "card_idle_bg": "--vts-tag-card-idle-bg",
391
- "card_active_bg": "--vts-tag-card-active-bg",
392
- "card_hover_bg": "--vts-tag-card-hover-bg",
393
- "card_active_text": "--vts-tag-card-active-text",
394
- "card_idle_text": "--vts-tag-card-idle-text",
395
- "card_close_color": "--vts-tag-card-close-color"
396
- },
397
- "custom_style_map": {
398
- "bg": "background-color",
399
- "border_bottom": "border-bottom",
400
- "padding_inline": "padding-inline",
401
- "padding_block": "padding-block"
402
- },
403
- "anchors": [
404
- { "kind": "class", "layer": "host", "target": ".tags-view" },
405
- { "kind": "class", "layer": "inner", "target": ".tags-view .scroll-container" }
406
- ],
407
- "preconditions": [
408
- "容器内边距出厂由组件样式给出(非 0),设计要求「内边距归零、首页页签与折叠按钮左对齐」时必须显式声明 padding_inline,不声明即保留出厂值(这是「首页页签不贴左缘」的根因)。",
409
- "⚠ShowModel 运行时缓存坑:showModel 经 responsive-storage 持久化于 localStorage(命名空间 responsive-),platform-config.json 改 ShowModel 后**旧缓存仍生效**——项目侧施工 ShowModel 时必须同步清 localStorage(或 Version++ 触发响应式存储失效),否则模板代码已换、运行时仍渲染旧形态,页签「样式完全不对」多半是缓存残留而非映射失败。施工后验证口径:浏览器 DevTools Application→Local Storage 清 responsive-* 键后刷新再比对。",
410
- "⚠ShowModel 三分支运行时兜底:useTags.ts 实证 showModel 读取链 = localStorage → fallback **'smart'**(platform-config 的 ShowModel 只在 storage 初始化时生效);而模板 DOM 只实现 chrome / card 两分支(v-if / v-else-if),smart 落入 v-else 裸分支——**无 .card-item / .card-tab 类**,锚定 card 结构的设计层规则全部不命中,仅锚定 .scroll-item 的规则(分割线等)命中 → 同一页签栏「半新半旧」混合观感(如底色块残留 + 分割线在)。因此 form=flat 施工必须**三分支全覆盖**:① 锚定 .card-item / .card-tab 的规则之外,同步给出锚定 .scroll-item 直系(不限形态类)的兜底规则(盒几何/底色透明/激活态),或在词典 preconditions 声明「ShowModel 须确保运行时为 card」(清缓存 + platform-config 双写)——二选一必须做,只写 card 锚点 = smart 残余分支裸奔。",
411
- "⚠ShowModel 三件套硬闸(G4 T 通道施工必须项):仅改 platform-config.ShowModel **不生效**——showModel 读 localStorage,而 localStorage 只在 platform-config.Version 变化时经 responsive.ts invalidateStorageIfConfigVersionChanged 重灌(只改 ShowModel=card 而 Version 未变,浏览器会残留 chrome 形态缓存 → card/smart 兜底规则双双不命中、页签零变化)。form 涉及页签形态时施工三件套缺一不可:① platform-config.ShowModel = form 对应值(flat→card);② platform-config.Version 自增一位(0.0.5→0.0.6,触发缓存失效重灌);③ 渲染取证断言 .scroll-item.card-item 实际挂载(DevTools 或 DOM 断言),不许只看代码改没改。漏②=代码对但运行时仍旧形态;漏③=无渲染证据自嗨绿。"
412
- ],
413
- "priority": {
414
- "strategy": "deep_qualified",
415
- "reason": "容器内边距规则写在组件 scoped 内,与设计层同权重,需显式提权。"
416
- },
417
- "$note": "showModel 由 platform-config.json ShowModel 字段声明、但运行时实值由 localStorage 决定(Version++ 才重灌)——施工按 preconditions 三件套执行;smart/line 模板未实现,映射层按 chrome/card 两形态处理"
418
- },
419
- "admin.layout.tabs.home_tab": {
420
- "type": "element",
421
- "selector": ".tags-view .scroll-item:nth-child(1)",
422
- "file": "src/layout/components/lay-tag/index.vue(首页页签 = multiTags 首项;真实 DOM 无 .home-item 类)",
423
- "style_scope": ".tags-view",
424
- "forms": {
425
- "icon_only": "出厂默认:首位渲染 home 图标(meta.icon 缺省回退 'home'),无标题文字。**落地必须成对:显图标 + 隐标题**——项宽固定 40px,图标与标题共存时标题会被挤成截断(如「工作台」→「工…」)。隐标题经 text_visible 字段(display)落 .card-tab 标题元素;只显图标不收标题 = 形态未落地",
426
- "text": "纯文字首位页签(隐藏图标且不占位)"
427
- },
428
- "$comment": "真实 DOM:.scroll-item(首项)> .card-tab,图标经 resolveCardTabIcon 渲染 svg-icon.card-tab-icon。出厂解析规则是数据驱动的:index===0 回退 'home',其余按 meta.icon 有无渲染(空则不渲染不占位)——因此「有无图标」是-menu 数据/变更集可动态决定的,不是源码常量。尺寸类意图(如 40×40)由变更集 style 字段给出,词典不预设具体设计值。",
429
- "css_vars": {
430
- "width": "--vts-tag-card-height",
431
- "height": "--vts-tag-card-height"
432
- },
433
- "sub_selectors": {
434
- "icon": ".card-tab .card-tab-icon",
435
- "title": ".card-tab .tag-title"
436
- },
437
- "custom_style_map": {
438
- "icon_size": "font-size",
439
- "icon_color": "color",
440
- "divider_color": "border-left-color",
441
- "text_visible": "display"
442
- },
443
- "$note": "divider(首页页签与首个业务页签间的 1px 竖线分割)属子元素结构样式,设计侧通过 divider_color 表达视觉意图。落地口径:首页页签项宽=高=--vts-tag-card-height(40px) 居中,经 .tags-view .scroll-item:nth-child(1) 覆写 padding 实现正方形图标钮;icon_only 形态必须同时把标题收口(text_visible=none),否则 40px 内图标+标题并存、标题被截断。"
444
- },
445
- "admin.layout.tabs.item": {
446
- "type": "element",
447
- "selector": ".tags-view .scroll-item:not(:nth-child(1))",
448
- "file": "src/layout/components/lay-tag/index.vue(业务页签 = multiTags 非首项;真实 DOM 无 .tags-view-item 类)",
449
- "style_scope": ".tags-view",
450
- "forms": {
451
- "text_only": "出厂默认:业务页签纯文字(meta.icon 为空 → 不渲染不占位)",
452
- "with_icon": "业务页签带图标(由路由 meta.icon 驱动显示)"
453
- },
454
- "$comment": "真实 DOM:.scroll-item.is-closable > .card-tab(title + el-icon-close),激活态类 .is-active。⚠出厂中性基线:图标显隐由 resolveCardTabIcon 按 meta.icon 数据驱动,不是源码写死;「某张图要求业务页签无图标」必须以 form=text_only 显式声明后由变更集落地(隐藏 .card-tab-icon 且不占位),词典不预置任何设计的结论。间距/关闭钮尺寸/激活态表现等参数一律由当次变更集 style 字段给出。",
455
- "css_vars": {
456
- "card_height": "--vts-tag-card-height",
457
- "card_radius": "--vts-tag-card-radius",
458
- "card_gap": "--vts-tag-card-gap",
459
- "card_idle_bg": "--vts-tag-card-idle-bg",
460
- "card_active_bg": "--vts-tag-card-active-bg",
461
- "card_hover_bg": "--vts-tag-card-hover-bg",
462
- "card_active_text": "--vts-tag-card-active-text",
463
- "card_idle_text": "--vts-tag-card-idle-text",
464
- "card_close_color": "--vts-tag-card-close-color"
465
- },
466
- "custom_style_map": {
467
- "padding_x": "padding-inline",
468
- "divider_color": "border-left-color",
469
- "title_gap": "gap",
470
- "close_size": "font-size",
471
- "close_opacity": "opacity",
472
- "close_hover_color": "color"
473
- },
474
- "anchors": [
475
- { "kind": "class", "layer": "host", "target": ".tags-view .scroll-item .card-tab" },
476
- { "kind": "class", "layer": "inner", "target": ".tags-view .scroll-item .card-tab .el-icon-close" }
477
- ],
478
- "priority": {
479
- "strategy": "deep_qualified",
480
- "reason": "关闭钮透明度等出厂规则写在组件 scoped 内且权重与设计层相当,仅靠后置加载顺序不可靠(声明 0.45 常显会被 scoped 的 opacity:0 反压、只在 hover 才显),必须显式提权。"
481
- },
482
- "$note": "card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换);本条目为页签项级字段补充。chrome 形态梯形样式为模板结构样式,不走样式映射"
483
- },
484
- "admin.layout.tabs.item_active": {
485
- "type": "element",
486
- "selector": ".tags-view .scroll-item.is-active",
487
- "file": "src/layout/components/lay-tag/index.vue",
488
- "style_scope": ".tags-view",
489
- "forms": {
490
- "text_color_only": "仅文字/图标变色 + 字重加重(设计规范口径,unified-framework §6.46:font-weight 500、无下划线、无 border-bottom、无 box-shadow)",
491
- "with_bg": "带底色块(出厂 card 形态即此:--vts-tag-card-active-bg)",
492
- "with_underline": "带下划线/底线(出厂未实现,需设计层 ::after 新建并取变更集几何字段)"
493
- },
494
- "sub_selectors": {
495
- "title": ".tags-view .scroll-item.is-active .tag-title",
496
- "icon": ".tags-view .scroll-item.is-active .card-tab-icon"
497
- },
498
- "css_vars": {
499
- "active_text": "--vts-tag-card-active-text",
500
- "active_bg": "--vts-tag-card-active-bg"
501
- },
502
- "custom_style_map": {
503
- "text_color": "color",
504
- "font_weight": "font-weight",
505
- "underline_height": "height",
506
- "underline_color": "background-color"
507
- },
508
- "$note": "⚠出厂中性基线:chrome 形态激活态 = 白字 + box-shadow + 主色底(.scroll-item.is-active:not(.card-item)),card 形态 = --vts-tag-card-active-bg 底 + active-text 文字;**两者都不等于设计规范的「仅文字变色 + 字重 500、无下划线」**。form=text_color_only 时必须在设计层显式覆写出厂的 box-shadow / 背景块,缺任一项 = 激活态样式不对。card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换)。"
509
- },
510
- "admin.layout.tabs.divider": {
511
- "type": "element",
512
- "selector": "chrome 形态:.chrome-tab .chrome-tab-divider;card / flat 形态:无独立元素(需设计层新建)",
513
- "file": "src/layout/components/lay-tag/index.vue",
514
- "style_scope": ".tags-view",
515
- "$comment": "真实 DOM:chrome 形态有 .chrome-tab-divider(position:absolute; right:7px; width:1px; height:14px; background-color:#2b2d2f;激活时 opacity:0),card 形态无分割线元素、用 --vts-tag-card-gap 间距代替。设计规范要求页签之间 1px×100% 贯穿分割线(unified-framework §6.47),与出厂两种形态都不符。",
516
- "css_vars": {},
517
- "custom_style_map": {
518
- "width": "width",
519
- "height": "height",
520
- "bg": "background-color",
521
- "opacity": "opacity"
522
- },
523
- "anchors": [
524
- { "kind": "class", "layer": "host", "target": ".tags-view .chrome-tab .chrome-tab-divider" },
525
- { "kind": "class", "layer": "inner", "target": ".tags-view .scroll-item:not(:first-child)::before" }
526
- ],
527
- "preconditions": [
528
- "chrome 形态自带分割线元素;card / flat 形态没有该元素,须先由结构/样式层新建 —— 元素不存在时 width / height / bg 全部无落点(这是「页签分割线声明了却不见」的根因)。"
529
- ],
530
- "$note": "落地口径:chrome 形态可直接覆写 .chrome-tab-divider 的 background-color / height(含激活态 opacity 还原);card / flat 形态须在设计层用 .tags-view .scroll-item:not(:first-child)::before 新建竖线并消费变更集 width/height/bg。禁止把某张图的分割线参数(如 1px×100% #F0F0F0)写进出厂源码——那是单张图的结论。"
531
- },
532
- "admin.layout.tabs.context_menu": {
533
- "type": "element",
534
- "selector": ".tags-view .el-dropdown-menu(页签栏右侧 arrow-down 触发的下拉菜单;el-dropdown 挂 body)",
535
- "file": "src/layout/components/lay-tag/index.vue(右侧功能按钮 el-dropdown @command=handleCommand)",
536
- "style_scope": ":global(popper 挂 body,需全局作用域 + .translation 类限定)",
537
- "$comment": "真实 DOM:el-dropdown(trigger=click placement=bottom-end)+ el-dropdown-menu(class=translation)。设计意图:宽 160px、圆角 8px",
538
- "css_vars": {
539
- "radius": "--el-popper-border-radius",
540
- "item_height": "--el-dropdown-menuItem-height"
541
- },
542
- "custom_style_map": {
543
- "width": "width",
544
- "bg": "background-color",
545
- "item_font_size": "font-size"
546
- },
547
- "$note": "item_height 若 EP 未暴露 popper 级变量,AI 施工时以 .translation.el-dropdown-menu li { height } 自定义实现并回写本条目——两层机制天然兜底。作用域注意:dropdown 挂 body,样式不得写 scoped,需全局样式 + .translation 类限定防泄漏"
548
- },
549
- "admin.layout.content": {
550
- "type": "module",
551
- "selector": ".app-main",
552
- "file": "src/layout/components/lay-content/index.vue",
553
- "style_scope": ".app-main",
554
- "css_vars": {
555
- "padding": "--layout-content-padding"
556
- },
557
- "custom_style_map": {
558
- "bg": "background-color"
559
- },
560
- "$note": "内容区高度链为壳层定高体系(vts-page-card/vts-page-fill),业务页面布局语义见 content.* 语义 ID"
561
- },
562
- "admin.layout.footer": {
563
- "type": "module",
564
- "selector": ".main-content 之后的 footer 区(出厂未常驻渲染)",
565
- "file": "—",
566
- "style_scope": ":root",
567
- "visible_prop": "HideFooter(platform-config.json)",
568
- "css_vars": {
569
- "height": "--layout-footer-height"
570
- },
571
- "custom_style_map": {}
572
- }
573
- }
574
- }
1
+ {
2
+ "$comment": "admin 场景 · 布局模块语义 ID 全属性映射(vue3-web-temp 框架组件实证)。每条含结构定位(selector/file)、形态切换(forms)、样式映射(css_vars 优先 + custom_style_map 兜底)。style_scope 为样式必须包裹的容器类名;:root 表示全局令牌层。版本恒 1.0.0(由 SKILL.md 体系版本统一管理,不单独演进)。",
3
+ "meta": {
4
+ "layer": "scene",
5
+ "scene": "admin",
6
+ "domain": "layout",
7
+ "version": "1.0.0",
8
+ "tech_stack": "vue3 + element-plus + vue3-web-temp"
9
+ },
10
+ "mappings": {
11
+ "admin.layout.sidebar": {
12
+ "type": "module",
13
+ "selector": ".sidebar-container",
14
+ "file": "src/layout/components/lay-sidebar/NavVertical.vue",
15
+ "style_scope": ".sidebar-container",
16
+ "default_props": { "width": "var(--sidebar-width, 208px)" },
17
+ "children": [
18
+ "admin.layout.sidebar.logo_area",
19
+ "admin.layout.sidebar.menu",
20
+ "admin.layout.sidebar.collapse_trigger"
21
+ ],
22
+ "css_vars": {
23
+ "width": "--sidebar-width",
24
+ "collapsed_width": "--sidebar-collapsed-width",
25
+ "collapse_bar_height": "--sidebar-collapse-bar-height",
26
+ "menu_item_height": "--el-menu-item-height"
27
+ },
28
+ "custom_style_map": {
29
+ "bg": "background-color",
30
+ "border_right": "border-right",
31
+ "box_shadow": "box-shadow"
32
+ }
33
+ },
34
+ "admin.layout.sidebar.logo_area": {
35
+ "type": "element",
36
+ "selector": ".sidebar-logo",
37
+ "file": "src/layout/components/lay-sidebar/components/SidebarLogo.vue",
38
+ "style_scope": ".sidebar-container",
39
+ "visible_prop": "ShowLogo(platform-config.json / emitter logoChange)",
40
+ "css_vars": {
41
+ "height": "--vts-bar-height",
42
+ "bg": "--vts-theme-sidebar-logo",
43
+ "title_color": "--vts-theme-sub-menu-active-text"
44
+ },
45
+ "custom_style_map": {
46
+ "title_font_size": "font-size",
47
+ "title_font_weight": "font-weight"
48
+ }
49
+ },
50
+ "admin.layout.sidebar.menu": {
51
+ "type": "component",
52
+ "component": "ElMenu",
53
+ "selector": ".sidebar-container .el-menu",
54
+ "file": "src/layout/components/lay-sidebar/NavVertical.vue",
55
+ "style_scope": ".sidebar-container",
56
+ "forms": {
57
+ "pill": "整块胶囊底色高亮(sidebar.scss 消费 --vts-theme-menu-active-bg,带 !important)。suppress 必含 right_indicator_legacy——出厂 element-plus.scss 的 .el-menu-item.is-active{border-right:var(--menu-active-border-right)} 是活通道,不收口会出现左右两根竖条并存",
58
+ "indicator_left": "仅左竖条指示、无胶囊:先在本作用域覆写 --vts-theme-menu-active-bg: transparent 关胶囊,再于设计层新建 ::after 竖条消费 --vts-theme-menu-active-before。suppress 必含 right_indicator_legacy",
59
+ "indicator_right": "仅右竖条指示、无胶囊:同上关胶囊后 ::after 挂 right:0。出厂右竖条通道 --menu-active-border-right(element-plus.scss 消费、design-tokens.scss 定义为 3px solid 品牌色)是活通道,可复用也可收口后自建,二选一必须显式声明",
60
+ "indicator_underline": "仅底部横线指示、无胶囊:关胶囊后 ::after 挂 bottom:0(宽取 100% 或指定宽度,厚取 indicator_thickness)。suppress 必含 right_indicator_legacy",
61
+ "none": "无指示:胶囊与竖条均关闭,仅文字变色。suppress 必含 right_indicator_legacy",
62
+ "pill_indicator_left": "胶囊底色 + 左竖条**并存**复合形态(设计实证:效果图 .menu-item.active 同时声明 background:var(--primary) 与 ::before 竖条):胶囊照 pill 走 --vts-theme-menu-active-bg;竖条照 indicator_left 走 --vts-theme-menu-active-before(设计层新建 ::after/::before 消费者)。suppress 必含 right_indicator_legacy(出厂右竖条必须收口)。⚠菜单项宿主盒必须声明 margin 横向内缩(custom_style_map margin_x),否则竖条负偏移落进容器外被 overflow 裁掉——竖条偏移值以「容器 padding − 竖条 left 偏移」为语境换算,禁止照搬外部效果图常量"
63
+ },
64
+ "suppress_rules": {
65
+ "pill": ["right_indicator_legacy"],
66
+ "indicator_left": ["right_indicator_legacy"],
67
+ "indicator_right": ["right_indicator_legacy"],
68
+ "indicator_underline": ["right_indicator_legacy"],
69
+ "none": ["right_indicator_legacy"],
70
+ "pill_indicator_left": ["right_indicator_legacy"]
71
+ },
72
+ "field_forms": {
73
+ "active_indicator_width": ["indicator_left", "indicator_right", "indicator_underline", "pill_indicator_left"],
74
+ "active_indicator_thickness": ["indicator_left", "indicator_right", "indicator_underline", "pill_indicator_left"],
75
+ "active_indicator_style": ["indicator_left", "indicator_right", "indicator_underline", "pill_indicator_left"],
76
+ "menu_active_bg": ["pill", "pill_indicator_left"]
77
+ },
78
+ "css_vars": {
79
+ "menu_bg": "--vts-theme-menu-bg",
80
+ "menu_text": "--vts-theme-menu-text",
81
+ "menu_hover_bg": "--vts-theme-menu-hover",
82
+ "menu_title_hover": "--vts-theme-menu-title-hover",
83
+ "sub_menu_bg": "--vts-theme-sub-menu-bg",
84
+ "sub_menu_active_text": "--vts-theme-sub-menu-active-text",
85
+ "menu_active_bg": "--vts-theme-menu-active-bg",
86
+ "menu_active_indicator": "--vts-theme-menu-active-before",
87
+ "right_indicator_legacy": "--menu-active-border-right",
88
+ "sidebar_border": "--vts-sidebar-border-color",
89
+ "item_height": "--el-menu-item-height"
90
+ },
91
+ "custom_style_map": {
92
+ "active_indicator_width": "width",
93
+ "active_indicator_thickness": "height",
94
+ "active_indicator_style": "border-radius",
95
+ "padding_y": "padding-block",
96
+ "margin_x": "margin-inline",
97
+ "font_size": "font-size",
98
+ "font_weight": "font-weight",
99
+ "text_color": "color"
100
+ },
101
+ "anchors": [
102
+ { "kind": "class", "layer": "host", "target": ".sidebar-container .el-menu-item" },
103
+ { "kind": "class", "layer": "inner", "target": ".sidebar-container .el-menu-item > .el-menu-item__content" },
104
+ { "kind": "css_var", "target": "--vts-theme-menu-active-bg" },
105
+ { "kind": "css_var", "target": "--vts-theme-menu-active-before" }
106
+ ],
107
+ "preconditions": [
108
+ "出厂菜单项盒模型是「无横向 margin(margin: 4px 0)+ 胶囊用 inset 内缩」;指示条几何必须以这个宿主盒为基准计算偏移。照搬外部效果图上「依赖菜单项横向 margin」的负偏移量会落进容器外并被 overflow 裁掉(这是指示条「映射了却没效果」的根因:值搬了、让该值成立的宿主盒模型没搬)。",
109
+ "--vts-theme-menu-active-before 出厂为透明且全项目无消费者;声明 indicator_* 形态必须成对落地「关胶囊令牌 + 新建消费者」,只改色值不建消费者 = 未施工。",
110
+ "激活态作用层级(active_scope,默认 leaf):胶囊与指示条**只作用于叶子菜单项**(.el-menu-item.is-active)。可展开分组的标题(.el-sub-menu__title)在「其下有激活子项」时会被 EP 打上 is-active,**不得**继承胶囊与指示条——否则分组标题同时长出胶囊、竖条并与右侧展开箭头叠压。设计层写激活态时必须把选择器锚定叶子项,禁止把 .el-sub-menu.is-active > .el-sub-menu__title 与 .el-menu-item.is-active 并列写成同一组激活声明。"
111
+ ],
112
+ "priority": {
113
+ "strategy": "deep_qualified",
114
+ "reason": "出厂 sidebar.scss 的胶囊规则用 !important,设计层需以同等或更高权重覆盖。"
115
+ },
116
+ "$note": "侧栏配色挂载点为 html[data-theme='xxx'](theme.scss 8 套预设);设计输出深色侧栏 → Theme=default + Version++(useTheme 规则),浅色 → Theme=light。⚠文本完整性红线:菜单项名称必须完整显示(el-menu 自带 ellipsis 折叠溢出菜单),禁止改 menu 文本截断/隐藏策略;item_height 加大时确认行高不挤压文字。宽度类改动(--sidebar-width)后必须目视验证长菜单名显示。⚠激活态出厂中性基线(禁止把某张图的结论写进源码):出厂形态 = pill 胶囊高亮;--vts-theme-menu-active-before 出厂默认 transparent 且**全项目无消费者**(死通道)。因此 form=indicator_* / pill_indicator_left 时必须在本条目 style_scope 内成对落地两件事才算施工完成——① 竖条消费者(form 不含 pill 时另需覆写 --vts-theme-menu-active-bg: transparent 关胶囊);② 在设计层文件(不可写出厂 sidebar.scss)新建 ::after/::before 消费者引用 var(--vts-theme-menu-active-before)。缺任一项 = 「映射了却没效果」。所有几何参数(方位/粗细/长度/圆角/内缩)取自变更集 style 字段,禁止写死 left:0 / 3px 等常量。⚠field_forms 硬闸(parser G7 机检):style 声明的字段必须被当前 form 消费——如 active_indicator_* 只在 indicator_* / pill_indicator_left 形态下有消费者,声明 pill 却带竖条字段 = 字段被静默丢弃(如声明 pill 却带 active_indicator_* 竖条字段,竖条令牌会被设计层置透明 → 效果图要求的左竖条消失)。"
117
+ },
118
+ "admin.layout.sidebar.menu_item_icon": {
119
+ "type": "element",
120
+ "selector": ".sidebar-container .el-menu-item .el-icon, .sidebar-container .el-menu-item .el-menu-item__icon",
121
+ "file": "src/layout/components/lay-sidebar/NavVertical.vue(菜单图标,el-menu-item 内 svg-icon)",
122
+ "style_scope": ".sidebar-container",
123
+ "css_vars": {},
124
+ "custom_style_map": {
125
+ "icon_size": "font-size",
126
+ "icon_color": "color"
127
+ },
128
+ "anchors": [
129
+ { "kind": "class", "layer": "inner", "target": ".sidebar-container .el-menu-item .el-icon" }
130
+ ],
131
+ "$note": "菜单图标 16×16px(unified-framework §6.17 / §1 导航栏「图标 16×16px」)。图标为 font-icon,尺寸经 font-size 承载、颜色经 color 承载,落 inner 层(图标元素本身)。"
132
+ },
133
+ "admin.layout.sidebar.collapse_trigger": {
134
+ "type": "element",
135
+ "selector": ".left-collapse / .center-collapse",
136
+ "file": "src/layout/components/lay-sidebar/components/SidebarLeftCollapse.vue + SidebarCenterCollapse.vue",
137
+ "style_scope": ".sidebar-container",
138
+ "forms": {
139
+ "bottom_bar": "SidebarLeftCollapse(底部条,出厂默认)",
140
+ "center_edge": "SidebarCenterCollapse(侧缘中点,折叠/悬停时显示)"
141
+ },
142
+ "suppress_rules": {
143
+ "center_edge": ["bottom_bar"],
144
+ "bottom_bar": ["center_edge"]
145
+ },
146
+ "css_vars": {
147
+ "bar_height": "--sidebar-collapse-bar-height"
148
+ },
149
+ "custom_style_map": {
150
+ "trigger_width": "width",
151
+ "trigger_height": "height",
152
+ "trigger_color": "color"
153
+ }
154
+ },
155
+ "admin.layout.header": {
156
+ "type": "module",
157
+ "selector": ".navbar",
158
+ "file": "src/layout/components/lay-navbar/index.vue",
159
+ "style_scope": ".navbar",
160
+ "default_props": { "height": "var(--vts-bar-height)" },
161
+ "children": [
162
+ "admin.layout.header.collapse_trigger",
163
+ "admin.layout.header.logo_area",
164
+ "admin.layout.header.breadcrumb",
165
+ "admin.layout.header.lang_switch",
166
+ "admin.layout.header.fullscreen",
167
+ "admin.layout.header.setting_button",
168
+ "admin.layout.header.user_profile"
169
+ ],
170
+ "css_vars": {
171
+ "height": "--header-height",
172
+ "padding_x": "--header-padding-x"
173
+ },
174
+ "custom_style_map": {
175
+ "bg": "background-color",
176
+ "box_shadow": "box-shadow",
177
+ "gap": "gap",
178
+ "border_color": "border-color",
179
+ "align_items": "align-items"
180
+ },
181
+ "preconditions": [
182
+ "顶栏内容垂直居中:--header-height 变更(如 54px)后,宿主 .navbar 必须显式 align-items: center——出厂顶栏内元素高度不一(折叠钮 40px / 文字行 / 头像),不显式声明会整体偏上。"
183
+ ]
184
+ },
185
+ "admin.layout.header.logo_area": {
186
+ "type": "element",
187
+ "selector": ".navbar .siderLogo",
188
+ "file": "src/layout/components/lay-sidebar/components/SidebarLogo.vue(navbar 内复用)",
189
+ "style_scope": ".navbar",
190
+ "visible_note": "仅 horizontal 布局在顶栏渲染 logo(v-if layout==='horizontal' && showLogo)",
191
+ "css_vars": {},
192
+ "custom_style_map": {
193
+ "min_width": "min-width",
194
+ "height": "height"
195
+ }
196
+ },
197
+ "admin.layout.header.breadcrumb": {
198
+ "type": "component",
199
+ "component": "SidebarBreadCrumb",
200
+ "selector": ".navbar-breadcrumb-wrap",
201
+ "file": "src/layout/components/lay-sidebar/components/SidebarBreadCrumb.vue",
202
+ "style_scope": ".navbar",
203
+ "visible_note": "v-if layout!=='mix' && layout!=='horizontal' && device!=='mobile'",
204
+ "css_vars": {
205
+ "text_color": "--el-text-color-regular"
206
+ },
207
+ "custom_style_map": {
208
+ "font_size": "font-size"
209
+ },
210
+ "anchors": [
211
+ { "kind": "class", "layer": "host", "target": ".navbar .navbar-breadcrumb-wrap" }
212
+ ],
213
+ "priority": {
214
+ "strategy": "deep_qualified",
215
+ "reason": "出厂组件自身 scoped 规则与设计层同权重,仅靠后置加载顺序不可靠;显隐收口与样式覆盖都必须显式提权(面包屑 display:none 被同权重 scoped 规则反压即属此类)。"
216
+ },
217
+ "$note": "分隔符为结构属性(breadcrumb separator 字符),不在样式映射范围"
218
+ },
219
+ "admin.layout.header.lang_switch": {
220
+ "type": "component",
221
+ "component": "ReLanguageSwitch(ElDropdown 包裹)",
222
+ "selector": ".navbar .language-trigger",
223
+ "file": "src/components/ReLanguageSwitch/src/index.vue",
224
+ "style_scope": ".navbar",
225
+ "forms": {
226
+ "icon_only": "出厂现状:纯图标触发器(.language-trigger > .language-icon),下拉菜单选语言",
227
+ "inline_switch": "并排切换形态:中 / EN 平铺在触发器内,点击即切换。**落地必须成套三件事**——① 显并排文字(.language-text 由隐藏改可见);② 收口图标(suppress icon_only);③ **收口下拉浮层**(suppress dropdown_popper:出厂 ElDropdown 的 popper 必须不再弹出,否则点触发器会从下方展开 English/中文 浮层遮挡页签栏)。缺③ = 形态未落地(只加了文字、交互仍是下拉)"
228
+ },
229
+ "suppress_rules": {
230
+ "inline_switch": ["icon_only", "dropdown_popper"]
231
+ },
232
+ "structure_ops_required": {
233
+ "inline_switch": ["收口 ElDropdown 触发(改 trigger 为不可弹出 / 移除 dropdown 插槽消费 / 用保形 v-if 切换为直选按钮任一),使点击不再产生浮层"]
234
+ },
235
+ "preconditions": [
236
+ "语言切换的形态由 form 决定,且 form 是「加法 + 减法」成对语义:inline_switch 不仅要新增并排文字,还必须收口出厂的下拉浮层与图标形态。只加不减时,浮层仍会弹出(触发器与浮层二者并存),视觉上从触发器下方展开的浮层会压住页签栏。",
237
+ "浮层属 teleport 到 body 的 popper,样式层无法收口(.language-trigger 上的规则管不到 popper);必须从结构层收口 ElDropdown 的触发行为。"
238
+ ],
239
+ "css_vars": {
240
+ "icon_color": "--el-text-color-regular",
241
+ "hover_bg": "--el-fill-color-light"
242
+ },
243
+ "sub_selectors": {
244
+ "icon": ".language-trigger .language-icon",
245
+ "text": ".language-trigger .language-text"
246
+ },
247
+ "custom_style_map": {
248
+ "icon_size": "font-size",
249
+ "gap": "gap",
250
+ "text_font_size": "font-size",
251
+ "text_color": "color"
252
+ },
253
+ "$note": "inline_switch 并排切换形态:下拉项平铺为触发器旁切换组,按 v-if 保形切换增量插入,不删原代码;同时收口图标形态与下拉浮层(浮层属 teleport popper,样式层管不到,必须结构收口)。"
254
+ },
255
+ "admin.layout.header.collapse_trigger": {
256
+ "type": "element",
257
+ "selector": ".navbar .header-collapse-btn",
258
+ "file": "src/layout/components/lay-navbar/index.vue(顶栏内嵌形态为增量插入;出厂折叠按钮位于侧栏,见 admin.layout.sidebar.collapse_trigger)",
259
+ "style_scope": ".navbar",
260
+ "forms": {
261
+ "header_inline": "顶栏内嵌折叠按钮:40×40 纯图标、与首页页签左对齐、hover 仅文字加深(出厂无此元素,v-if 保形插入机制落地)",
262
+ "sidebar_bottom": "出厂现状:侧栏底部折叠条(SidebarLeftCollapse)",
263
+ "sidebar_center": "侧栏侧缘中点(SidebarCenterCollapse)"
264
+ },
265
+ "suppress_rules": {
266
+ "header_inline": ["sidebar_bottom", "sidebar_center"]
267
+ },
268
+ "css_vars": {
269
+ "icon_color": "--el-text-color-regular",
270
+ "hover_bg": "--el-fill-color-light"
271
+ },
272
+ "custom_style_map": {
273
+ "btn_width": "width",
274
+ "btn_height": "height",
275
+ "icon_size": "font-size",
276
+ "border_radius": "border-radius"
277
+ },
278
+ "$note": "form=header_inline 时 AI 增量插入顶栏按钮片段(useApp isCollapse 切换),样式全部走 custom_style_map 生成的 :deep 隔离规则;出厂 sidebar_bottom 形态代码保留不删(显隐≠删除),设计侧 visible:false 时隐藏侧栏折叠条避免双按钮并存"
279
+ },
280
+ "admin.layout.header.fullscreen": {
281
+ "type": "component",
282
+ "component": "SidebarFullScreen",
283
+ "selector": "#full-screen",
284
+ "file": "src/layout/components/lay-sidebar/components/SidebarFullScreen.vue",
285
+ "style_scope": ".navbar",
286
+ "css_vars": {
287
+ "text_color": "--el-text-color-primary",
288
+ "hover_bg": "--el-fill-color-light"
289
+ },
290
+ "custom_style_map": {
291
+ "icon_size": "font-size",
292
+ "width": "width"
293
+ }
294
+ },
295
+ "admin.layout.header.setting_button": {
296
+ "type": "element",
297
+ "selector": ".set-icon",
298
+ "file": "src/layout/components/lay-navbar/index.vue",
299
+ "style_scope": ".navbar",
300
+ "visible_prop": "无出厂配置开关(出厂常显)",
301
+ "css_vars": {
302
+ "height": "--vts-bar-height"
303
+ },
304
+ "custom_style_map": {
305
+ "icon_size": "font-size",
306
+ "width": "width",
307
+ "hover_bg": "background-color",
308
+ "text_color": "color"
309
+ },
310
+ "$note": "存在性收口默认对象:效果图未出现该按钮时,变更集以 visible:false 声明 → 落地为设计层文件内 .navbar .set-icon { display:none }(禁止删出厂代码行、禁止直接改 lay-navbar/index.vue 表达「这张图不要按钮」)。反向:设计需要该按钮时不声明即可(出厂已常显)。同一 DOM(含 v-tippy 提示)通用,图标/尺寸经本条目 style 字段动态覆盖。"
311
+ },
312
+ "admin.layout.header.user_profile": {
313
+ "type": "component",
314
+ "component": "ElDropdown",
315
+ "selector": ".navbar-right .el-dropdown-link",
316
+ "file": "src/layout/components/lay-navbar/index.vue",
317
+ "style_scope": ".navbar",
318
+ "forms": {
319
+ "avatar_name": "出厂默认:22×22 头像 + 用户名(window.userName),无问候语",
320
+ "greeting_avatar_name": "问候语 + 用户名 + 头像(问候节点出厂不存在 → 由 AI 按本 form 在 lay-navbar 用户区增量插入,属结构通道施工)",
321
+ "greeting_name": "问候语 + 用户名,无头像",
322
+ "avatar_only": "仅头像",
323
+ "name_only": "仅用户名"
324
+ },
325
+ "suppress_rules": {
326
+ "greeting_name": ["avatar_name"],
327
+ "avatar_only": ["avatar_name"],
328
+ "name_only": ["avatar_name"]
329
+ },
330
+ "sub_selectors": {
331
+ "$comment": "avatar/name 为点位内部部件,不设独立语义 ID(符合 4 段 ID 上限);样式字段按前缀路由到对应选择器。form 含 greeting 时新增节点统一用 class 前缀 vts-header-greeting / vts-header-username(插入前先查重名)",
332
+ "avatar": ".navbar-right .el-dropdown-link img",
333
+ "name": ".navbar-right .el-dropdown-link p"
334
+ },
335
+ "css_vars": {
336
+ "height": "--vts-bar-height",
337
+ "text_color": "--el-text-color-primary"
338
+ },
339
+ "custom_style_map": {
340
+ "avatar_width": "width",
341
+ "avatar_height": "height",
342
+ "avatar_radius": "border-radius",
343
+ "name_font_size": "font-size",
344
+ "name_font_weight": "font-weight",
345
+ "greeting_font_size": "font-size",
346
+ "greeting_font_weight": "font-weight",
347
+ "gap": "gap"
348
+ },
349
+ "anchors": [
350
+ { "kind": "class", "layer": "host", "target": ".navbar .navbar-right .el-dropdown-link" },
351
+ { "kind": "class", "layer": "inner", "target": ".navbar .navbar-right .el-dropdown-link img" },
352
+ { "kind": "class", "layer": "inner", "target": ".navbar .navbar-right .el-dropdown-link p" }
353
+ ],
354
+ "preconditions": [
355
+ "出厂 DOM 只有「头像 img + 用户名 p」,任何 greeting 组合都必须**先做结构增量**再谈样式;未新增节点时 greeting_* 样式字段无落点(这是「欢迎区没出现」的根因)。",
356
+ "组合形态由 form 决定,样式字段按 sub_selectors 前缀路由到对应部件选择器。"
357
+ ],
358
+ "$note": "⚠出厂中性基线:出厂 DOM 只有「头像 img + 用户名 p」,**没有任何问候语节点**(词典曾误记 .header-welcome 已实现,属虚假前提)。因此 form 含 greeting 时必须走结构增量新增 DOM,且节点文案模板(时段问候语 + 用户名)由业务层提供,本点位只承载组合形态与样式——禁止把具体问候文案写进组件。反向同理:设计只要纯头像/纯用户名时以 form=avatar_only/name_only 声明,出厂多余节点同样按收口处理(隐藏不删)。"
359
+ },
360
+ "admin.layout.tabs": {
361
+ "type": "module",
362
+ "selector": ".tags-view",
363
+ "file": "src/layout/components/lay-tag/index.vue",
364
+ "style_scope": ".tags-view",
365
+ "visible_prop": "HideTabs(platform-config.json)",
366
+ "children": ["admin.layout.tabs.home_tab", "admin.layout.tabs.item", "admin.layout.tabs.context_menu"],
367
+ "forms": {
368
+ "chrome": "谷歌页签(出厂 ShowModel=chrome):SVG 梯形外形 + .chrome-tab-divider(1px×14px 深色)+ 关闭钮 16px 主色;激活态白字 + box-shadow",
369
+ "card": "卡片页签(ShowModel=card):圆角卡片底 + --vts-tag-card-* 整组令牌 + 关闭钮 hover 才显现(出厂 opacity:0)",
370
+ "flat": "平面页签(设计规范口径,出厂无此形态):ShowModel 仍设 card(复用 card 结构 = 图标槽 + 关闭钮 + resolveCardTabIcon 数据驱动),平面观感全部由设计层覆写达成 —— ① --vts-tag-card-idle-bg/hover-bg/active-bg 置 transparent;② --vts-tag-card-radius 与 --vts-tag-card-gap 置 0;③ 激活态仅文字/图标变主色 + font-weight 500,不加 border-bottom / box-shadow;④ 关闭钮 opacity 覆写为常显值(出厂 card 为 0);⑤ 首页页签项宽=高=--vts-tag-card-height 居中呈方块;⑥ 页签间 1px×100% 贯穿分割线(card 无该元素,需设计层 ::after/::before 新建)。几何与色值一律取自变更集 style 字段,禁止写死常量"
371
+ },
372
+ "suppress_rules": {
373
+ "flat": [
374
+ "card_idle_bg",
375
+ "card_active_bg",
376
+ "card_hover_bg",
377
+ "card_radius",
378
+ "card_gap",
379
+ "card_active_text",
380
+ "card_idle_text",
381
+ "card_close_color"
382
+ ]
383
+ },
384
+ "css_vars": {
385
+ "height": "--tabs-height",
386
+ "chrome_inset_top": "--vts-tag-chrome-inset-top",
387
+ "card_height": "--vts-tag-card-height",
388
+ "card_radius": "--vts-tag-card-radius",
389
+ "card_gap": "--vts-tag-card-gap",
390
+ "card_idle_bg": "--vts-tag-card-idle-bg",
391
+ "card_active_bg": "--vts-tag-card-active-bg",
392
+ "card_hover_bg": "--vts-tag-card-hover-bg",
393
+ "card_active_text": "--vts-tag-card-active-text",
394
+ "card_idle_text": "--vts-tag-card-idle-text",
395
+ "card_close_color": "--vts-tag-card-close-color"
396
+ },
397
+ "custom_style_map": {
398
+ "bg": "background-color",
399
+ "border_bottom": "border-bottom",
400
+ "padding_inline": "padding-inline",
401
+ "padding_block": "padding-block"
402
+ },
403
+ "anchors": [
404
+ { "kind": "class", "layer": "host", "target": ".tags-view" },
405
+ { "kind": "class", "layer": "inner", "target": ".tags-view .scroll-container" }
406
+ ],
407
+ "preconditions": [
408
+ "容器内边距出厂由组件样式给出(非 0),设计要求「内边距归零、首页页签与折叠按钮左对齐」时必须显式声明 padding_inline,不声明即保留出厂值(这是「首页页签不贴左缘」的根因)。",
409
+ "⚠ShowModel 运行时缓存坑:showModel 经 responsive-storage 持久化于 localStorage(命名空间 responsive-),platform-config.json 改 ShowModel 后**旧缓存仍生效**——项目侧施工 ShowModel 时必须同步清 localStorage(或 Version++ 触发响应式存储失效),否则模板代码已换、运行时仍渲染旧形态,页签「样式完全不对」多半是缓存残留而非映射失败。施工后验证口径:浏览器 DevTools Application→Local Storage 清 responsive-* 键后刷新再比对。",
410
+ "⚠ShowModel 三分支运行时兜底:useTags.ts 实证 showModel 读取链 = localStorage → fallback **'smart'**(platform-config 的 ShowModel 只在 storage 初始化时生效);而模板 DOM 只实现 chrome / card 两分支(v-if / v-else-if),smart 落入 v-else 裸分支——**无 .card-item / .card-tab 类**,锚定 card 结构的设计层规则全部不命中,仅锚定 .scroll-item 的规则(分割线等)命中 → 同一页签栏「半新半旧」混合观感(如底色块残留 + 分割线在)。因此 form=flat 施工必须**三分支全覆盖**:① 锚定 .card-item / .card-tab 的规则之外,同步给出锚定 .scroll-item 直系(不限形态类)的兜底规则(盒几何/底色透明/激活态),或在词典 preconditions 声明「ShowModel 须确保运行时为 card」(清缓存 + platform-config 双写)——二选一必须做,只写 card 锚点 = smart 残余分支裸奔。",
411
+ "⚠ShowModel 三件套硬闸(G4 T 通道施工必须项):仅改 platform-config.ShowModel **不生效**——showModel 读 localStorage,而 localStorage 只在 platform-config.Version 变化时经 responsive.ts invalidateStorageIfConfigVersionChanged 重灌(只改 ShowModel=card 而 Version 未变,浏览器会残留 chrome 形态缓存 → card/smart 兜底规则双双不命中、页签零变化)。form 涉及页签形态时施工三件套缺一不可:① platform-config.ShowModel = form 对应值(flat→card);② platform-config.Version 自增一位(0.0.5→0.0.6,触发缓存失效重灌);③ 渲染取证断言 .scroll-item.card-item 实际挂载(DevTools 或 DOM 断言),不许只看代码改没改。漏②=代码对但运行时仍旧形态;漏③=无渲染证据自嗨绿。"
412
+ ],
413
+ "priority": {
414
+ "strategy": "deep_qualified",
415
+ "reason": "容器内边距规则写在组件 scoped 内,与设计层同权重,需显式提权。"
416
+ },
417
+ "$note": "showModel 由 platform-config.json ShowModel 字段声明、但运行时实值由 localStorage 决定(Version++ 才重灌)——施工按 preconditions 三件套执行;smart/line 模板未实现,映射层按 chrome/card 两形态处理"
418
+ },
419
+ "admin.layout.tabs.home_tab": {
420
+ "type": "element",
421
+ "selector": ".tags-view .scroll-item:nth-child(1)",
422
+ "file": "src/layout/components/lay-tag/index.vue(首页页签 = multiTags 首项;真实 DOM 无 .home-item 类)",
423
+ "style_scope": ".tags-view",
424
+ "forms": {
425
+ "icon_only": "出厂默认:首位渲染 home 图标(meta.icon 缺省回退 'home'),无标题文字。**落地必须成对:显图标 + 隐标题**——项宽固定 40px,图标与标题共存时标题会被挤成截断(如「工作台」→「工…」)。隐标题经 text_visible 字段(display)落 .card-tab 标题元素;只显图标不收标题 = 形态未落地",
426
+ "text": "纯文字首位页签(隐藏图标且不占位)"
427
+ },
428
+ "$comment": "真实 DOM:.scroll-item(首项)> .card-tab,图标经 resolveCardTabIcon 渲染 svg-icon.card-tab-icon。出厂解析规则是数据驱动的:index===0 回退 'home',其余按 meta.icon 有无渲染(空则不渲染不占位)——因此「有无图标」是-menu 数据/变更集可动态决定的,不是源码常量。尺寸类意图(如 40×40)由变更集 style 字段给出,词典不预设具体设计值。",
429
+ "css_vars": {
430
+ "width": "--vts-tag-card-height",
431
+ "height": "--vts-tag-card-height"
432
+ },
433
+ "sub_selectors": {
434
+ "icon": ".card-tab .card-tab-icon",
435
+ "title": ".card-tab .tag-title"
436
+ },
437
+ "custom_style_map": {
438
+ "icon_size": "font-size",
439
+ "icon_color": "color",
440
+ "divider_color": "border-left-color",
441
+ "text_visible": "display"
442
+ },
443
+ "$note": "divider(首页页签与首个业务页签间的 1px 竖线分割)属子元素结构样式,设计侧通过 divider_color 表达视觉意图。落地口径:首页页签项宽=高=--vts-tag-card-height(40px) 居中,经 .tags-view .scroll-item:nth-child(1) 覆写 padding 实现正方形图标钮;icon_only 形态必须同时把标题收口(text_visible=none),否则 40px 内图标+标题并存、标题被截断。"
444
+ },
445
+ "admin.layout.tabs.item": {
446
+ "type": "element",
447
+ "selector": ".tags-view .scroll-item:not(:nth-child(1))",
448
+ "file": "src/layout/components/lay-tag/index.vue(业务页签 = multiTags 非首项;真实 DOM 无 .tags-view-item 类)",
449
+ "style_scope": ".tags-view",
450
+ "forms": {
451
+ "text_only": "出厂默认:业务页签纯文字(meta.icon 为空 → 不渲染不占位)",
452
+ "with_icon": "业务页签带图标(由路由 meta.icon 驱动显示)"
453
+ },
454
+ "$comment": "真实 DOM:.scroll-item.is-closable > .card-tab(title + el-icon-close),激活态类 .is-active。⚠出厂中性基线:图标显隐由 resolveCardTabIcon 按 meta.icon 数据驱动,不是源码写死;「某张图要求业务页签无图标」必须以 form=text_only 显式声明后由变更集落地(隐藏 .card-tab-icon 且不占位),词典不预置任何设计的结论。间距/关闭钮尺寸/激活态表现等参数一律由当次变更集 style 字段给出。",
455
+ "css_vars": {
456
+ "card_height": "--vts-tag-card-height",
457
+ "card_radius": "--vts-tag-card-radius",
458
+ "card_gap": "--vts-tag-card-gap",
459
+ "card_idle_bg": "--vts-tag-card-idle-bg",
460
+ "card_active_bg": "--vts-tag-card-active-bg",
461
+ "card_hover_bg": "--vts-tag-card-hover-bg",
462
+ "card_active_text": "--vts-tag-card-active-text",
463
+ "card_idle_text": "--vts-tag-card-idle-text",
464
+ "card_close_color": "--vts-tag-card-close-color"
465
+ },
466
+ "custom_style_map": {
467
+ "padding_x": "padding-inline",
468
+ "divider_color": "border-left-color",
469
+ "title_gap": "gap",
470
+ "close_size": "font-size",
471
+ "close_opacity": "opacity",
472
+ "close_hover_color": "color"
473
+ },
474
+ "anchors": [
475
+ { "kind": "class", "layer": "host", "target": ".tags-view .scroll-item .card-tab" },
476
+ { "kind": "class", "layer": "inner", "target": ".tags-view .scroll-item .card-tab .el-icon-close" }
477
+ ],
478
+ "priority": {
479
+ "strategy": "deep_qualified",
480
+ "reason": "关闭钮透明度等出厂规则写在组件 scoped 内且权重与设计层相当,仅靠后置加载顺序不可靠(声明 0.45 常显会被 scoped 的 opacity:0 反压、只在 hover 才显),必须显式提权。"
481
+ },
482
+ "$note": "card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换);本条目为页签项级字段补充。chrome 形态梯形样式为模板结构样式,不走样式映射"
483
+ },
484
+ "admin.layout.tabs.item_active": {
485
+ "type": "element",
486
+ "selector": ".tags-view .scroll-item.is-active",
487
+ "file": "src/layout/components/lay-tag/index.vue",
488
+ "style_scope": ".tags-view",
489
+ "forms": {
490
+ "text_color_only": "仅文字/图标变色 + 字重加重(设计规范口径,unified-framework §6.46:font-weight 500、无下划线、无 border-bottom、无 box-shadow)",
491
+ "with_bg": "带底色块(出厂 card 形态即此:--vts-tag-card-active-bg)",
492
+ "with_underline": "带下划线/底线(出厂未实现,需设计层 ::after 新建并取变更集几何字段)"
493
+ },
494
+ "sub_selectors": {
495
+ "title": ".tags-view .scroll-item.is-active .tag-title",
496
+ "icon": ".tags-view .scroll-item.is-active .card-tab-icon"
497
+ },
498
+ "css_vars": {
499
+ "active_text": "--vts-tag-card-active-text",
500
+ "active_bg": "--vts-tag-card-active-bg"
501
+ },
502
+ "custom_style_map": {
503
+ "text_color": "color",
504
+ "font_weight": "font-weight",
505
+ "underline_height": "height",
506
+ "underline_color": "background-color"
507
+ },
508
+ "$note": "⚠出厂中性基线:chrome 形态激活态 = 白字 + box-shadow + 主色底(.scroll-item.is-active:not(.card-item)),card 形态 = --vts-tag-card-active-bg 底 + active-text 文字;**两者都不等于设计规范的「仅文字变色 + 字重 500、无下划线」**。form=text_color_only 时必须在设计层显式覆写出厂的 box-shadow / 背景块,缺任一项 = 激活态样式不对。card 形态专属令牌挂在父级 admin.layout.tabs 的 css_vars(整组切换)。"
509
+ },
510
+ "admin.layout.tabs.divider": {
511
+ "type": "element",
512
+ "selector": "chrome 形态:.chrome-tab .chrome-tab-divider;card / flat 形态:无独立元素(需设计层新建)",
513
+ "file": "src/layout/components/lay-tag/index.vue",
514
+ "style_scope": ".tags-view",
515
+ "$comment": "真实 DOM:chrome 形态有 .chrome-tab-divider(position:absolute; right:7px; width:1px; height:14px; background-color:#2b2d2f;激活时 opacity:0),card 形态无分割线元素、用 --vts-tag-card-gap 间距代替。设计规范要求页签之间 1px×100% 贯穿分割线(unified-framework §6.47),与出厂两种形态都不符。",
516
+ "css_vars": {},
517
+ "custom_style_map": {
518
+ "width": "width",
519
+ "height": "height",
520
+ "bg": "background-color",
521
+ "opacity": "opacity"
522
+ },
523
+ "anchors": [
524
+ { "kind": "class", "layer": "host", "target": ".tags-view .chrome-tab .chrome-tab-divider" },
525
+ { "kind": "class", "layer": "inner", "target": ".tags-view .scroll-item:not(:first-child)::before" }
526
+ ],
527
+ "preconditions": [
528
+ "chrome 形态自带分割线元素;card / flat 形态没有该元素,须先由结构/样式层新建 —— 元素不存在时 width / height / bg 全部无落点(这是「页签分割线声明了却不见」的根因)。"
529
+ ],
530
+ "$note": "落地口径:chrome 形态可直接覆写 .chrome-tab-divider 的 background-color / height(含激活态 opacity 还原);card / flat 形态须在设计层用 .tags-view .scroll-item:not(:first-child)::before 新建竖线并消费变更集 width/height/bg。禁止把某张图的分割线参数(如 1px×100% #F0F0F0)写进出厂源码——那是单张图的结论。"
531
+ },
532
+ "admin.layout.tabs.context_menu": {
533
+ "type": "element",
534
+ "selector": ".tags-view .el-dropdown-menu(页签栏右侧 arrow-down 触发的下拉菜单;el-dropdown 挂 body)",
535
+ "file": "src/layout/components/lay-tag/index.vue(右侧功能按钮 el-dropdown @command=handleCommand)",
536
+ "style_scope": ":global(popper 挂 body,需全局作用域 + .translation 类限定)",
537
+ "$comment": "真实 DOM:el-dropdown(trigger=click placement=bottom-end)+ el-dropdown-menu(class=translation)。设计意图:宽 160px、圆角 8px",
538
+ "css_vars": {
539
+ "radius": "--el-popper-border-radius",
540
+ "item_height": "--el-dropdown-menuItem-height"
541
+ },
542
+ "custom_style_map": {
543
+ "width": "width",
544
+ "bg": "background-color",
545
+ "item_font_size": "font-size"
546
+ },
547
+ "$note": "item_height 若 EP 未暴露 popper 级变量,AI 施工时以 .translation.el-dropdown-menu li { height } 自定义实现并回写本条目——两层机制天然兜底。作用域注意:dropdown 挂 body,样式不得写 scoped,需全局样式 + .translation 类限定防泄漏"
548
+ },
549
+ "admin.layout.content": {
550
+ "type": "module",
551
+ "selector": ".app-main",
552
+ "file": "src/layout/components/lay-content/index.vue",
553
+ "style_scope": ".app-main",
554
+ "css_vars": {
555
+ "padding": "--layout-content-padding"
556
+ },
557
+ "custom_style_map": {
558
+ "bg": "background-color"
559
+ },
560
+ "$note": "内容区高度链为壳层定高体系(vts-page-card/vts-page-fill),业务页面布局语义见 content.* 语义 ID"
561
+ },
562
+ "admin.layout.footer": {
563
+ "type": "module",
564
+ "selector": ".main-content 之后的 footer 区(出厂未常驻渲染)",
565
+ "file": "—",
566
+ "style_scope": ":root",
567
+ "visible_prop": "HideFooter(platform-config.json)",
568
+ "css_vars": {
569
+ "height": "--layout-footer-height"
570
+ },
571
+ "custom_style_map": {}
572
+ }
573
+ }
574
+ }