openyida 2026.9.19 → 2026.9.21

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 (195) hide show
  1. package/README.md +4 -4
  2. package/lib/app/application-style.js +69 -0
  3. package/lib/app/create-form/args.js +37 -12
  4. package/lib/app/create-form/batch.js +32 -5
  5. package/lib/app/create-form.js +94 -57
  6. package/lib/app/form-field-validator.js +0 -36
  7. package/lib/app/services/form-compiler.js +0 -2
  8. package/lib/app/theme-from-design.js +40 -14
  9. package/lib/app/update-app.js +63 -13
  10. package/lib/core/command-manifest.js +81 -25
  11. package/lib/core/locales/en.js +20 -3
  12. package/lib/core/locales/zh.js +20 -3
  13. package/lib/core/sample.js +36 -14
  14. package/lib/design/document.js +1 -0
  15. package/lib/design-plan/confirmation.js +13 -0
  16. package/lib/design-plan/design-plan.js +44 -2
  17. package/lib/design-plan/entry-navigation.js +10 -2
  18. package/lib/design-plan/init.js +16 -9
  19. package/lib/design-plan/materialize.js +85 -45
  20. package/lib/design-plan/normalize.js +13 -14
  21. package/lib/design-plan/parallel.js +62 -13
  22. package/lib/design-plan/patch.js +21 -7
  23. package/lib/design-plan/rebase.js +60 -0
  24. package/lib/design-plan/themes.js +16 -1
  25. package/lib/design-plan/validate.js +16 -1
  26. package/lib/design-plan/visual-policy.js +29 -4
  27. package/lib/samples/openyida-scaffold/canvas-form-drawer.canvas.jsx +3 -3
  28. package/lib/samples/openyida-scaffold/canvas-nav/mixed.jsx +6 -4
  29. package/lib/samples/openyida-scaffold/canvas-nav/shared.jsx +5 -5
  30. package/lib/samples/openyida-scaffold/canvas-nav/side.jsx +1 -2
  31. package/lib/samples/openyida-scaffold/canvas-nav/sidebar.jsx +1 -1
  32. package/lib/samples/openyida-scaffold/canvas-nav/top.jsx +5 -4
  33. package/package.json +1 -1
  34. package/yida-skills/SKILL.md +2 -2
  35. package/yida-skills/references/official-example-schema-patterns.md +1 -1
  36. package/yida-skills/references/yida-api.md +4 -0
  37. package/yida-skills/skills/yida-app/SKILL.md +15 -4
  38. package/yida-skills/skills/yida-app/references/entry-navigation.md +11 -9
  39. package/yida-skills/skills/yida-app/workflow/plan/step-4-deliver.md +1 -1
  40. package/yida-skills/skills/yida-app/workflow/plan/workflow.md +11 -4
  41. package/yida-skills/skills/yida-app/workflow/step-2-design.md +3 -3
  42. package/yida-skills/skills/yida-app/workflow/step-3-create-or-reuse-app.md +2 -2
  43. package/yida-skills/skills/yida-app/workflow/step-8-publish-navigation.md +3 -3
  44. package/yida-skills/skills/yida-app/workflow/step-9-output-finish.md +3 -2
  45. package/yida-skills/skills/yida-canvas-custom-page/SKILL.md +2 -2
  46. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-style-implementation-guide.md +1 -1
  47. package/yida-skills/skills/yida-canvas-custom-page/references/canvas-theme-provider.md +1 -1
  48. package/yida-skills/skills/yida-canvas-custom-page/references/data-bridge-guide.md +140 -1
  49. package/yida-skills/skills/yida-canvas-custom-page/references/navigation-and-entry-guide.md +1 -1
  50. package/yida-skills/skills/yida-canvas-custom-page/scripts/canvas-theme-provider.template.jsx +1 -1
  51. package/yida-skills/skills/yida-canvas-data-binding/SKILL.md +7 -0
  52. package/yida-skills/skills/yida-create-form-page/SKILL.md +34 -43
  53. package/yida-skills/skills/yida-create-form-page/references/advanced-form-modes.md +5 -5
  54. package/yida-skills/skills/yida-create-form-page/references/association-form-field.md +4 -4
  55. package/yida-skills/skills/yida-create-form-page/references/batch-forms.md +2 -2
  56. package/yida-skills/skills/yida-create-form-page/references/field-definition-guide.md +4 -16
  57. package/yida-skills/skills/yida-create-form-page/references/form-field-properties.md +14 -37
  58. package/yida-skills/skills/yida-design/SKILL.md +7 -5
  59. package/yida-skills/skills/yida-design/references/application-style-library.md +93 -0
  60. package/yida-skills/skills/yida-design/references/application-theme-consistency.md +48 -7
  61. package/yida-skills/skills/yida-design/references/ask-human-interaction-contract.md +1 -1
  62. package/yida-skills/skills/yida-design/references/native-form-styles.md +208 -0
  63. package/yida-skills/skills/yida-design/references/navigation-decision.md +6 -4
  64. package/yida-skills/skills/yida-design/references/theme/app-custom-theme-template.css +110 -1
  65. package/yida-skills/skills/yida-design/references/theme/application-style-recipes.css +58 -0
  66. package/yida-skills/skills/yida-design/references/theme-selection.md +12 -11
  67. package/yida-skills/skills/yida-design/references/visual-decision-engine.md +1 -1
  68. package/yida-skills/skills/yida-design/scripts/validate_design_themes.py +49 -6
  69. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/SKILL.md +13 -3
  70. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/build-plan-compact-schema.md +6 -2
  71. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/build-plan-schema.md +5 -3
  72. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-design.md +3 -1
  73. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/references/visual-theme-selection.md +22 -23
  74. package/yida-skills/skills/yida-design/sub_skill/yida-design-plan/scripts/render_build_plan.py +2 -0
  75. package/yida-skills/skills/yida-design/templates/application-styles.json +398 -0
  76. package/yida-skills/skills/yida-design/templates/design-themes/README.md +15 -10
  77. package/yida-skills/skills/yida-design/templates/design-themes/app-amber/app_theme.css +748 -0
  78. package/yida-skills/skills/yida-design/templates/design-themes/app-amber/design.md +274 -0
  79. package/yida-skills/skills/yida-design/templates/design-themes/app-amber/form-layout.json +15 -0
  80. package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/app_theme.css +748 -0
  81. package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/design.md +274 -0
  82. package/yida-skills/skills/yida-design/templates/design-themes/app-editorial/form-layout.json +14 -0
  83. package/yida-skills/skills/yida-design/templates/design-themes/app-executive/app_theme.css +748 -0
  84. package/yida-skills/skills/yida-design/templates/design-themes/app-executive/design.md +274 -0
  85. package/yida-skills/skills/yida-design/templates/design-themes/app-executive/form-layout.json +13 -0
  86. package/yida-skills/skills/yida-design/templates/design-themes/app-finance/app_theme.css +748 -0
  87. package/yida-skills/skills/yida-design/templates/design-themes/app-finance/design.md +274 -0
  88. package/yida-skills/skills/yida-design/templates/design-themes/app-finance/form-layout.json +14 -0
  89. package/yida-skills/skills/yida-design/templates/design-themes/app-glass/app_theme.css +748 -0
  90. package/yida-skills/skills/yida-design/templates/design-themes/app-glass/design.md +274 -0
  91. package/yida-skills/skills/yida-design/templates/design-themes/app-glass/form-layout.json +14 -0
  92. package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/app_theme.css +748 -0
  93. package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/design.md +274 -0
  94. package/yida-skills/skills/yida-design/templates/design-themes/app-graphite/form-layout.json +14 -0
  95. package/yida-skills/skills/yida-design/templates/design-themes/app-line/app_theme.css +748 -0
  96. package/yida-skills/skills/yida-design/templates/design-themes/app-line/design.md +274 -0
  97. package/yida-skills/skills/yida-design/templates/design-themes/app-line/form-layout.json +13 -0
  98. package/yida-skills/skills/yida-design/templates/design-themes/app-neon/app_theme.css +748 -0
  99. package/yida-skills/skills/yida-design/templates/design-themes/app-neon/design.md +274 -0
  100. package/yida-skills/skills/yida-design/templates/design-themes/app-neon/form-layout.json +14 -0
  101. package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/app_theme.css +754 -0
  102. package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/design.md +279 -0
  103. package/yida-skills/skills/yida-design/templates/design-themes/app-nordic/form-layout.json +13 -0
  104. package/yida-skills/skills/yida-design/templates/design-themes/app-paper/app_theme.css +748 -0
  105. package/yida-skills/skills/yida-design/templates/design-themes/app-paper/design.md +274 -0
  106. package/yida-skills/skills/yida-design/templates/design-themes/app-paper/form-layout.json +13 -0
  107. package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/app_theme.css +748 -0
  108. package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/design.md +274 -0
  109. package/yida-skills/skills/yida-design/templates/design-themes/app-platinum/form-layout.json +14 -0
  110. package/yida-skills/skills/yida-design/templates/design-themes/app-plum/app_theme.css +748 -0
  111. package/yida-skills/skills/yida-design/templates/design-themes/app-plum/design.md +274 -0
  112. package/yida-skills/skills/yida-design/templates/design-themes/app-plum/form-layout.json +14 -0
  113. package/yida-skills/skills/yida-design/templates/design-themes/app-pop/app_theme.css +758 -0
  114. package/yida-skills/skills/yida-design/templates/design-themes/app-pop/design.md +281 -0
  115. package/yida-skills/skills/yida-design/templates/design-themes/app-pop/form-layout.json +14 -0
  116. package/yida-skills/skills/yida-design/templates/design-themes/app-sage/app_theme.css +748 -0
  117. package/yida-skills/skills/yida-design/templates/design-themes/app-sage/design.md +274 -0
  118. package/yida-skills/skills/yida-design/templates/design-themes/app-sage/form-layout.json +14 -0
  119. package/yida-skills/skills/yida-design/templates/design-themes/app-teal/app_theme.css +748 -0
  120. package/yida-skills/skills/yida-design/templates/design-themes/app-teal/design.md +274 -0
  121. package/yida-skills/skills/yida-design/templates/design-themes/app-teal/form-layout.json +14 -0
  122. package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/app_theme.css +754 -0
  123. package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/design.md +279 -0
  124. package/yida-skills/skills/yida-design/templates/design-themes/app-terminal/form-layout.json +14 -0
  125. package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/app_theme.css +752 -0
  126. package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/design.md +278 -0
  127. package/yida-skills/skills/yida-design/templates/design-themes/app-ticket/form-layout.json +13 -0
  128. package/yida-skills/skills/yida-design/templates/design-themes/app-wire/app_theme.css +748 -0
  129. package/yida-skills/skills/yida-design/templates/design-themes/app-wire/design.md +274 -0
  130. package/yida-skills/skills/yida-design/templates/design-themes/app-wire/form-layout.json +14 -0
  131. package/yida-skills/skills/yida-design/templates/design-themes/basic-tokens.json +2 -1
  132. package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/app_theme.css +690 -0
  133. package/yida-skills/skills/yida-design/templates/design-themes/{dark-inset-hairline.md → dark-inset-hairline/design.md} +107 -58
  134. package/yida-skills/skills/yida-design/templates/design-themes/dark-inset-hairline/form-layout.json +13 -0
  135. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/app_theme.css +691 -0
  136. package/yida-skills/skills/yida-design/templates/design-themes/{dark-rail-fine-lines.md → dark-rail-fine-lines/design.md} +106 -50
  137. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-fine-lines/form-layout.json +13 -0
  138. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/app_theme.css +696 -0
  139. package/yida-skills/skills/yida-design/templates/design-themes/{dark-rail-signal-panels.md → dark-rail-signal-panels/design.md} +66 -12
  140. package/yida-skills/skills/yida-design/templates/design-themes/dark-rail-signal-panels/form-layout.json +13 -0
  141. package/yida-skills/skills/yida-design/templates/design-themes/free-creative/app_theme.css +689 -0
  142. package/yida-skills/skills/yida-design/templates/design-themes/free-creative/design.md +238 -0
  143. package/yida-skills/skills/yida-design/templates/design-themes/free-creative/form-layout.json +13 -0
  144. package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/app_theme.css +692 -0
  145. package/yida-skills/skills/yida-design/templates/design-themes/{graphite-bevel-grid.md → graphite-bevel-grid/design.md} +64 -10
  146. package/yida-skills/skills/yida-design/templates/design-themes/graphite-bevel-grid/form-layout.json +13 -0
  147. package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/app_theme.css +691 -0
  148. package/yida-skills/skills/yida-design/templates/design-themes/{hairline-shared-bands.md → hairline-shared-bands/design.md} +66 -12
  149. package/yida-skills/skills/yida-design/templates/design-themes/hairline-shared-bands/form-layout.json +13 -0
  150. package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/app_theme.css +691 -0
  151. package/yida-skills/skills/yida-design/templates/design-themes/{hairline-soft-blocks.md → hairline-soft-blocks/design.md} +61 -9
  152. package/yida-skills/skills/yida-design/templates/design-themes/hairline-soft-blocks/form-layout.json +13 -0
  153. package/yida-skills/skills/yida-design/templates/design-themes/index.json +399 -31
  154. package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/app_theme.css +701 -0
  155. package/yida-skills/skills/yida-design/templates/design-themes/{ink-glow-soft-panels.md → ink-glow-soft-panels/design.md} +62 -8
  156. package/yida-skills/skills/yida-design/templates/design-themes/ink-glow-soft-panels/form-layout.json +13 -0
  157. package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/app_theme.css +691 -0
  158. package/yida-skills/skills/yida-design/templates/design-themes/{inset-frame-pixel-rhythm.md → inset-frame-pixel-rhythm/design.md} +63 -9
  159. package/yida-skills/skills/yida-design/templates/design-themes/inset-frame-pixel-rhythm/form-layout.json +13 -0
  160. package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/app_theme.css +698 -0
  161. package/yida-skills/skills/yida-design/templates/design-themes/{outlined-texture-duotone.md → outlined-texture-duotone/design.md} +66 -12
  162. package/yida-skills/skills/yida-design/templates/design-themes/outlined-texture-duotone/form-layout.json +13 -0
  163. package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/app_theme.css +691 -0
  164. package/yida-skills/skills/yida-design/templates/design-themes/{soft-inset-surfaces.md → soft-inset-surfaces/design.md} +63 -11
  165. package/yida-skills/skills/yida-design/templates/design-themes/soft-inset-surfaces/form-layout.json +13 -0
  166. package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/app_theme.css +690 -0
  167. package/yida-skills/skills/yida-design/templates/design-themes/{soft-outline-rhythm.md → soft-outline-rhythm/design.md} +64 -26
  168. package/yida-skills/skills/yida-design/templates/design-themes/soft-outline-rhythm/form-layout.json +13 -0
  169. package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/app_theme.css +698 -0
  170. package/yida-skills/skills/yida-design/templates/design-themes/{soft-rail-bold-band.md → soft-rail-bold-band/design.md} +103 -49
  171. package/yida-skills/skills/yida-design/templates/design-themes/soft-rail-bold-band/form-layout.json +13 -0
  172. package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/app_theme.css +692 -0
  173. package/yida-skills/skills/yida-design/templates/design-themes/{soft-spectral-panels.md → soft-spectral-panels/design.md} +67 -13
  174. package/yida-skills/skills/yida-design/templates/design-themes/soft-spectral-panels/form-layout.json +13 -0
  175. package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/app_theme.css +711 -0
  176. package/yida-skills/skills/yida-design/templates/design-themes/{warm-canvas-contrast-panels.md → warm-canvas-contrast-panels/design.md} +64 -10
  177. package/yida-skills/skills/yida-design/templates/design-themes/warm-canvas-contrast-panels/form-layout.json +13 -0
  178. package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/app_theme.css +692 -0
  179. package/yida-skills/skills/yida-design/templates/design-themes/{warm-rail-muted-panels.md → warm-rail-muted-panels/design.md} +102 -50
  180. package/yida-skills/skills/yida-design/templates/design-themes/warm-rail-muted-panels/form-layout.json +13 -0
  181. package/yida-skills/skills/yida-design/templates/navigation-styles.json +769 -0
  182. package/yida-skills/skills/yida-design/workflow/output-design.md +9 -6
  183. package/yida-skills/skills/yida-design/workflow/step-2-theme-system.md +12 -4
  184. package/yida-skills/skills/yida-design/workflow/step-6-handoff.md +1 -1
  185. package/yida-skills/skills/yida-form-permission/SKILL.md +6 -0
  186. package/yida-skills/skills/yida-nav-shell/SKILL.md +1 -1
  187. package/yida-skills/skills/yida-nav-shell/references/nav-shell-patterns.md +6 -0
  188. package/yida-skills/skills/yida-page-config/SKILL.md +9 -0
  189. package/yida-skills/skills/yida-prd/SKILL.md +1 -0
  190. package/yida-skills/skills/yida-prd/workflow/output-prd.md +2 -2
  191. package/yida-skills/skills/yida-prd/workflow/step-2-information-architecture.md +1 -1
  192. package/yida-skills/skills/yida-requirement-analysis/references/experience-groups.md +45 -9
  193. package/yida-skills/skills/yida-requirement-analysis/references/handoff.md +5 -5
  194. package/yida-skills/skills/yida-requirement-analysis/workflow/prepare-brief.md +17 -4
  195. package/yida-skills/skills-index.json +2 -2
@@ -1,11 +1,11 @@
1
1
  # 平台导航与自定义导航决策
2
2
 
3
- 首轮需求澄清完成后读取本文。Fast 与 Plan 均由 AI 根据 brief 中的有效任务和入口建议确定导航方式、布局和菜单样式;入口尚待判断时,先按 [使用关系与入口](../../yida-requirement-analysis/references/experience-groups.md) 补齐。
3
+ 首轮需求澄清完成后读取本文。Fast 与 Plan 均由 AI 根据 brief 中的有效任务和入口建议确定导航方式、布局和菜单样式;入口尚待判断时,先按 [判断是否分前后台](../../yida-requirement-analysis/references/experience-groups.md) 补齐。
4
4
 
5
5
  ## 先判断入口,再分别选择菜单
6
6
 
7
7
  - 服务前台:默认在一个自定义页面内完成已选任务,并设计自己的菜单;只有一个任务时可不设菜单。用户明确要求使用原生页面时优先沿用。
8
- - 管理端或共用工作区:按操作效率选择自定义页面或宜搭原生页面;默认由平台导航组织跨模块入口。自定义页面只实现业务内容,同任务分类使用页内 Tab,不因此再生成一套管理菜单。
8
+ - 业务后台或不分前后台的系统:按操作效率选择自定义页面或宜搭原生页面;默认由平台导航组织跨模块入口。自定义页面只实现业务内容,同任务分类使用页内 Tab,不因此再生成一套管理菜单。
9
9
  - 首页承载按 [首页按任务选择](../../yida-requirement-analysis/references/experience-groups.md#首页按任务选择) 决定:可用门户式业务工作台或直接进入原生业务页;驾驶舱需要独立的分析任务依据。
10
10
  - 为每个入口写出用户、任务、访问方式和菜单,并按下表确定配置范围。
11
11
 
@@ -17,7 +17,7 @@
17
17
 
18
18
  执行时按 [导航壳配置](../../yida-nav-shell/SKILL.md#必做配置) 应用对应范围,并打开各入口链接验证实际效果。
19
19
 
20
- 按 [访问态入口契约](../../yida-app/references/entry-navigation.md#每个入口都确定首页与菜单顺序) 分别保存前台、后台和共用工作区的菜单顺序、默认页面及首屏任务。平台导航与自定义导航都必须落实排序;管理端不强制创建首页,前台页面不自动进入管理菜单。隐藏设置、入口路径、实际默认页面和权限分别验证。
20
+ 按 [访问态入口契约](../../yida-app/references/entry-navigation.md#每个入口都确定首页与菜单顺序) 保存每个业务入口的菜单顺序、默认页面及首屏任务。平台导航与自定义导航都必须落实排序;管理端不强制创建首页,前台页面不自动进入管理菜单。隐藏设置、入口路径、实际默认页面和权限分别验证。
21
21
 
22
22
  ## 应用工作区的选择依据
23
23
 
@@ -25,6 +25,8 @@
25
25
  2. 已有业务应用的局部增改沿用现有导航;显式窄范围按 `explicitScope.allowInferredResources=false` 执行,只处理用户指定的资源和设置。
26
26
  3. 新建完整应用默认采用宜搭原生导航,组织表单、审批、数据管理等业务入口。只有明确的应用级品牌菜单或特殊导航交互需求时才采用自定义导航,并在 `reason` 写明具体需求依据。保留筛选、分页、草稿或做同任务 Tab 不是替换平台导航的理由。
27
27
 
28
+ 菜单与布局明确后,按 [导航与应用框架](application-theme-consistency.md#导航与应用框架) 将外观纳入整体应用设计。模板提供导航 token 和导航明暗,业务规划决定菜单结构和布局;前台、后台、表单、详情与自定义页面保持同一设计语言。
29
+
28
30
  ## 根据场景确定导航布局
29
31
 
30
32
  AI 在已确定的导航方式内,结合业务模块数量、层级、切换频率、内容宽度和目标设备确定布局;用户已明确布局或提供参考时优先沿用。
@@ -40,7 +42,7 @@ AI 在已确定的导航方式内,结合业务模块数量、层级、切换
40
42
 
41
43
  ## 方案讨论与确认
42
44
 
43
- 导航作为业务方案的一部分说明:例如“访客在独立前台办理,管理员使用平台菜单处理商品、资讯和预约”。默认方案明确时不另设“平台还是自绘”的强制技术选择题;用户主动讨论或明确选择时,保留其要求并说明影响范围。
45
+ 导航作为业务方案的一部分说明:例如“客户在前台预约,员工通过后台菜单维护商品、资讯和处理预约”。默认方案明确时不另设“平台还是自绘”的强制技术选择题;用户主动讨论或明确选择时,保留其要求并说明影响范围。
44
46
 
45
47
  - Plan:在整体方案中展示各入口的导航归属与管理页只实现业务内容的边界,随整体方案确认;已展示方案的导航归属发生实质变更时,按现有修订与确认流程处理。
46
48
  - Fast:说明并实施已记录的选择,不新增导航审批环节;保留既有明确要求和局部修改范围。
@@ -201,6 +201,7 @@
201
201
  --pod-page-title-font-size: 16px;
202
202
  --pod-page-title-font-weight: 500;
203
203
  --pod-page-data-manage-top-padding: 16px;
204
+ /* 管理页表单视图 / DATA_MANAGE:控制底栏外层,不由导航显隐决定。 */
204
205
  --pod-formView-stickyFooter: 0 0 var(--pod-page-border-radius, 20px)
205
206
  var(--pod-page-border-radius, 20px);
206
207
  --pod-formView-stickyFooter-border: none;
@@ -216,7 +217,22 @@
216
217
  --pod-formView-stickyFooter-height: 50px;
217
218
  --pod-formView-stickyFooter-bottom: var(--pod-page-auto-width-margin, 8px);
218
219
  --pod-page-header-bg-color: var(--color-white, #fff);
219
- --pod-form-label-color: var(--color-text1-10, #606060);
220
+
221
+ /* 原生表单:按项目设计调整控件形状、密度和填充,不通过全局 input 选择器覆盖状态。 */
222
+ --form-element-medium-corner: var(--corner-2, 8px);
223
+ --form-element-medium-height: 32px;
224
+ --form-element-medium-font-size: 14px;
225
+ --input-bg-color: var(--pod-card-bg-color, #fff);
226
+ --input-border-width: 1px;
227
+ --input-border-color: var(--color-line1-2, rgba(24, 28, 31, .12));
228
+ --input-hover-border-color: var(--color-brand1-6, #0089ff);
229
+ --input-focus-border-color: var(--color-brand1-6, #006dcc);
230
+ --input-focus-bg-color: var(--input-bg-color, #fff);
231
+ /* DeepContainer 的 inline backgroundColor 通过此变量接入应用页面表面。 */
232
+ --yida-form-content-bgcolor: var(--pod-page-bg-color, #fff);
233
+ --pod-form-label-color: var(--color-text1-10, rgba(24, 28, 31, .8));
234
+ --form-top-label-margin-b: 0px;
235
+
220
236
  --pod-data-manager-title-padding: 12px 8px 0;
221
237
  --pod-data-manager-container-padding: 16px 20px 20px;
222
238
  --pod-detail-container-padding: 8px;
@@ -238,6 +254,8 @@
238
254
  --pod-card-border-radius: var(--pod-xl-border-radius, 20px);
239
255
  --pod-card-border: none;
240
256
  --pod-card-spacing: var(--pod-md-gap-pad-margin);
257
+ /* 普通提交(含有导航页面)、iframe 抽屉提交及详情:控制内层按钮容器。
258
+ * 阴影使用 --pod-sticky-footer-box-shadow;与上面的 formView 外层分别设计。 */
241
259
  --pod-page-footer-bg-color: var(
242
260
  --pod-card-bg-color,
243
261
  var(--color-white, #fff)
@@ -316,8 +334,12 @@
316
334
  --pod-nav-menu-item-height: 36px;
317
335
  --pod-nav-menu-item-padding: 8px;
318
336
  --pod-nav-menu-item-radius: var(--pod-sm-border-radius, 8px);
337
+ --pod-nav-menu-item-border: none;
338
+ --pod-nav-menu-item-hover-border: var(--pod-nav-menu-item-border);
339
+ --pod-nav-menu-item-selected-border: var(--pod-nav-menu-item-border);
319
340
  --pod-nav-menu-font-size: 14px;
320
341
  --pod-nav-menu-item-selected-font-weight: 400;
342
+ --pod-nav-menu-item-selected-shadow: none;
321
343
  --pod-nav-menu-line-height: 20px;
322
344
  --pod-nav-menu-icon-size: 16px;
323
345
  --pod-nav-menu-arrow-icon-size: 12px;
@@ -347,6 +369,51 @@
347
369
  --popup-bg: var(--color-fill1-5, #fff);
348
370
  }
349
371
 
372
+ /* 独立提交页(含抽屉 iframe)使用应用外衬;平台默认壳层取导航背景且不消费背景图。 */
373
+ body.pod-premium.page-type-submit .vc-shell-without-nav.pod-premium {
374
+ background-color: var(--pod-app-root-bg-color, var(--pod-page-bg-color, #fff));
375
+ background-image: var(--pod-app-root-bg-image, none);
376
+ background-position: center top;
377
+ background-repeat: no-repeat;
378
+ background-size: cover;
379
+ }
380
+
381
+ /* 原生详情属于内容区,独立页面和抽屉内都沿用内容画布与前景。 */
382
+ body.pod-premium.page-type-detail .vc-shell-without-nav.pod-premium {
383
+ background-color: var(--pod-page-bg-color, var(--color-white, #fff));
384
+ --pod-theme-text-color: var(--color-text1-4, #202020);
385
+ }
386
+
387
+ /* 详情顶栏的独立图标使用内容文字色,保留按钮自身的禁用状态。 */
388
+ body.pod-premium.page-type-detail .top-banner-area
389
+ .next-yida-button-iconOnly:not([disabled]):not(.disabled) .next-icon {
390
+ color: var(--color-text1-3, #737373);
391
+ }
392
+ body.pod-premium.page-type-detail .top-banner-area
393
+ .next-yida-button-iconOnly:not([disabled]):not(.disabled):hover .next-icon {
394
+ color: var(--color-text1-4, #202020);
395
+ }
396
+
397
+ /* 按实际底栏类型适配 PC 固定提交栏,不按有无导航判断。
398
+ * 排除 DATA_MANAGE 和容器内 sticky 模式;抽屉提交标记按平台规则优先。
399
+ * 管理页、旧主题、移动端继续由各自布局负责占位。 */
400
+ body.pod-premium.page-type-submit
401
+ .vc-page-yida-page:not(.yida-legacy-theme):has(
402
+ > .vc-rootcontent > .deep-form.desktop
403
+ > .stickyFooter.is-sticky:not(.is-sticky-v2):not(.is-data-manage-footer)
404
+ ),
405
+ body.pod-premium.page-type-submit
406
+ .vc-page-yida-page:not(.yida-legacy-theme):has(
407
+ > .vc-rootcontent > .deep-form.desktop
408
+ > .stickyFooter.is-sticky.is-in-drawer-submit-footer:not(.is-sticky-v2)
409
+ ) {
410
+ margin-bottom: 0;
411
+ padding-bottom: calc(
412
+ var(--pod-formView-stickyFooter-height, 50px) +
413
+ var(--pod-formView-stickyFooter-bottom, var(--pod-page-auto-width-margin, 8px))
414
+ );
415
+ }
416
+
350
417
  /* 白色导航背景与白色卡片相邻时,用描边保留卡片层级。 */
351
418
  .pod-premium.nav-white,
352
419
  .pod-premium.nav-theme-white {
@@ -476,3 +543,45 @@
476
543
  --pod-nav-action-bg-hover-color: rgba(255, 255, 255, 0.12);
477
544
  --pod-nav-action-bg-active-color: rgba(255, 255, 255, 0.16);
478
545
  }
546
+
547
+ /* openyida-navigation-shape:start */
548
+ /* Side/L navigation and top tabs share the same theme-defined menu shape.
549
+ * Border widths stay constant between states; border-box keeps row height stable. */
550
+ .pod-premium .deep-shell-nav-menu-content .next-nav-item,
551
+ .pod-premium .deep-shell-nav-tab-list .next-nav-item {
552
+ box-sizing: border-box;
553
+ border-radius: var(--pod-nav-menu-item-radius, 8px);
554
+ border: var(--pod-nav-menu-item-border, none);
555
+ }
556
+ /* Native inner rows also have a fixed minimum height. Fit them inside the
557
+ * bordered item instead of letting a thick outline push content below it. */
558
+ .vc-shell.pod-premium .next-nav.next-line.next-ver.deep-shell-nav-menu-content:not(.next-icon-only) .next-nav-item.next-menu-item > .next-menu-item-inner,
559
+ .vc-shell.pod-premium .next-shell-header .next-shell-navigation .next-nav.next-line.next-hoz.deep-shell-nav-tab-list .next-nav-item.next-menu-item > .next-menu-item-inner {
560
+ box-sizing: border-box;
561
+ height: 100% !important;
562
+ min-height: 0 !important;
563
+ }
564
+ .pod-premium .deep-shell-nav-menu-content .next-nav-item:hover,
565
+ .pod-premium .deep-shell-nav-tab-list .next-nav-item:hover {
566
+ border: var(--pod-nav-menu-item-hover-border, var(--pod-nav-menu-item-border, none));
567
+ }
568
+ /* Platform top tabs use transparent backgrounds and zero margin !important.
569
+ * Match the header scope so theme surfaces and spacing can reveal their shape. */
570
+ .vc-shell.pod-premium .next-shell-header .next-shell-navigation .next-nav.next-line.next-hoz.deep-shell-nav-tab-list .next-nav-item.next-menu-item {
571
+ margin-inline: calc(var(--pod-nav-menu-gap, 8px) / 2) !important;
572
+ }
573
+ .vc-shell.pod-premium .next-shell-header .next-shell-navigation .next-nav.next-line.next-hoz.deep-shell-nav-tab-list .next-nav-item.next-menu-item:hover {
574
+ background: var(--pod-nav-menu-bg-hover-color) !important;
575
+ color: var(--pod-nav-item-text-hover-color) !important;
576
+ }
577
+ .vc-shell.pod-premium .next-shell-header .next-shell-navigation .next-nav.next-line.next-hoz.deep-shell-nav-tab-list .next-nav-item.next-menu-item.next-selected {
578
+ background: var(--pod-nav-menu-bg-selected-color) !important;
579
+ color: var(--pod-nav-item-text-selected-color) !important;
580
+ }
581
+ /* Selected state wins over hover, retaining the original inset-shadow marker. */
582
+ .pod-premium .deep-shell-nav-menu-content .next-nav-item.next-selected,
583
+ .pod-premium .deep-shell-nav-tab-list .next-nav-item.next-selected {
584
+ border: var(--pod-nav-menu-item-selected-border, var(--pod-nav-menu-item-border, none));
585
+ box-shadow: var(--pod-nav-menu-item-selected-shadow, none);
586
+ }
587
+ /* openyida-navigation-shape:end */
@@ -0,0 +1,58 @@
1
+ /* OPENYIDA APPLICATION STYLE RECIPES START
2
+ * Opt-in semantic classes for custom pages. Native form structure stays in Schema.
3
+ * Never target platform field wrappers to impose a fake grid or fixed height.
4
+ */
5
+ .pod-premium .oyd-style-workspace {
6
+ container-type: inline-size;
7
+ max-width: var(--oyd-content-width);
8
+ margin-inline: auto;
9
+ padding: var(--oyd-content-padding);
10
+ color: var(--oyd-ink);
11
+ font-family: var(--font-family-base);
12
+ background-color: var(--oyd-page-bg);
13
+ background-image: var(--oyd-canvas-image);
14
+ }
15
+ .pod-premium .oyd-style-layout {
16
+ display: grid;
17
+ grid-template-columns: var(--oyd-layout-columns);
18
+ gap: var(--oyd-field-gap);
19
+ align-items: start;
20
+ }
21
+ .pod-premium .oyd-style-layout > * { min-width: 0; }
22
+ .pod-premium .oyd-style-wide { grid-column: 1 / -1; }
23
+ .pod-premium .oyd-style-layout > .oyd-style-intro {
24
+ padding-inline-end: var(--oyd-field-gap);
25
+ }
26
+ .pod-premium .oyd-style-intro {
27
+ color: var(--oyd-ink);
28
+ border-block-end: 1px var(--oyd-rule-style) var(--oyd-border);
29
+ padding-block-end: var(--oyd-field-gap);
30
+ margin-block-end: var(--oyd-section-gap);
31
+ }
32
+ .pod-premium .oyd-style-intro h1 {
33
+ font-family: var(--oyd-heading-font);
34
+ font-size: var(--oyd-heading-size);
35
+ line-height: 1.2;
36
+ overflow-wrap: anywhere;
37
+ }
38
+ .pod-premium .oyd-style-section {
39
+ padding: var(--oyd-content-padding);
40
+ margin-block-end: var(--oyd-section-gap);
41
+ background: var(--oyd-surface);
42
+ border: var(--input-border-width) var(--oyd-rule-style) var(--oyd-border);
43
+ border-radius: var(--oyd-radius);
44
+ box-shadow: var(--oyd-surface-shadow);
45
+ }
46
+ .pod-premium .oyd-style-section > h2::after {
47
+ content: "";
48
+ display: block;
49
+ width: 3rem;
50
+ margin-block-start: .5rem;
51
+ border-block-end: 2px var(--oyd-rule-style) var(--oyd-accent);
52
+ }
53
+ @container (max-width: 640px) {
54
+ .pod-premium .oyd-style-layout { grid-template-columns: minmax(0, 1fr); }
55
+ .pod-premium .oyd-style-section { padding: 16px; }
56
+ .pod-premium .oyd-style-intro h1 { font-size: min(32px, var(--oyd-heading-size)); }
57
+ }
58
+ /* OPENYIDA APPLICATION STYLE RECIPES END */
@@ -1,6 +1,6 @@
1
1
  # 共享主题选择与项目化规则
2
2
 
3
- Fast、Plan 和单页设计共用 [主题索引](../templates/design-themes/index.json) 与其中列出的完整主题。这是唯一主题库;各流程只保留自己的交互和产物生成方式。
3
+ Fast、Plan 和单页设计共用 [主题索引](../templates/design-themes/index.json) 与其中列出的完整主题。命名模板共用这一主题库;另有独立的自由创意路径,不要求匹配模板。详见[应用风格模板与自由创意](application-style-library.md)。
4
4
 
5
5
  ## 输入与优先级
6
6
 
@@ -13,7 +13,7 @@ Fast、Plan 和单页设计共用 [主题索引](../templates/design-themes/inde
13
13
  > AI 补齐
14
14
  ```
15
15
 
16
- 将“简洁、专业”等描述落实为表面层次、边界强度、形状分工、文字节奏、色彩强调和组件状态。行业、颜色、主题名称或“有图表/表格/右栏”等公共组件不能单独决定主题。默认浅色内容画布;已明确暗色、夜间或同等视觉要求时选择对应暗色主题,导航明暗独立判断。
16
+ 将“简洁、专业”等描述落实为导航、应用框架、表单、记录详情和自定义页面的表面层次、边界强度、形状分工、文字节奏、色彩强调和组件状态。行业、颜色、主题名称或“有图表/表格/右栏”等公共组件不能单独决定主题。索引摘要用“深色/浅色导航”和“深色/浅色内容界面”自然描述明暗关系;默认选择浅色内容主题,已明确暗色、夜间或同等视觉要求时选择对应暗色内容主题。导航明暗采用最终主题模板的 `navTheme`,用户明确的导航明暗作为主题筛选约束,不在主题选定后独立猜测或覆盖。
17
17
 
18
18
  ## 先读摘要,再读选中主题
19
19
 
@@ -21,21 +21,21 @@ Fast、Plan 和单页设计共用 [主题索引](../templates/design-themes/inde
21
21
  2. 对照摘要中的表面、轮廓、形状、文字、强调方式及偏离风险,选择最符合当前视觉要求的主题。不按关键词数量打分,不维护另一套权重或风格注册表。
22
22
  3. 保留摘要中的适用条件。图表、量表、记录栈等仅按真实内容启用;没有某种内容不代表主题不适用,也不能为体现风格新增业务模块。未写明的实现细节留到主题确定后处理。
23
23
  4. 选定后通过该索引记录的 `templatePath`,相对 `yida-design/` 读取一份完整主题。沿用已确认选择,不再重新推荐;用户要求比较时,按所在流程完成选择后再读全文。
24
- 5. 项目要求与主题核心特征冲突时,重新匹配摘要中的其他主题;品牌色、导航明暗等允许的项目输入不构成更换主题的理由。
24
+ 5. 项目要求与主题核心特征冲突时,可以选择自由创意,也可重新匹配摘要中的其他主题;品牌色等允许的项目输入不构成更换主题的理由。用户明确的导航明暗与候选主题 `navTheme` 冲突时,改选符合要求的主题,不覆盖模板的导航明暗。
25
25
 
26
- 主题 ID、模板路径和候选比较保留在内部实施记录;Plan 写 `visualStyle.internal.selectedTheme`,Fast 沿用 brief 的视觉选择。最终 `prd.md`、`design.md` 和用户可见方案只写当前项目的视觉效果、配色和使用理由,不展示主题模板名称、ID、路径或选择过程。
26
+ 主题 ID、模板路径和候选比较保留在内部实施记录;Plan 写 `visualStyle.internal.selectedTheme`,Fast 沿用 brief 的视觉选择。最终文档正文和用户可见方案只写当前项目的视觉效果、配色和使用理由,不展示模板路径或内部选择过程;design.md frontmatter 只保留 applicationStyle 配方版本与模式,不携带模板身份。
27
27
 
28
28
  ## 设计方向比较
29
29
 
30
30
  比较过程只使用索引摘要,遵守上述完整模板读取边界。
31
31
 
32
- 在 Fast / Plan 前置规划中完成一次内部比较,再确定应用主色和视觉方向。已有明确风格、品牌规范或应用主题时保留它们,在其范围内完善构图与细节。
32
+ Fast 与 Plan 使用下面同一套三方向生成规则和候选字段,不得分别发明候选。已有明确完整风格、可信品牌规范、参考材料或应用主题时直接在其范围内完善构图与细节,不生成无意义的替代项;否则恰好生成三套完整方向:两个命名模板方向和一个独立自由创意方向。
33
33
 
34
- 1. **第一直觉作参照**:识别最容易套用的常规方案,例如“蓝色管理后台+等宽指标卡+表格”,找出它缺少的业务重点和视觉特点。
35
- 2. **发展两个新方向**:围绕相同业务任务,分别提出可实现的方案。每个方向在构图、字体层级、表面层次、色彩关系中至少两项有明显差异;用已有内容建立重点,保留字段、操作、权限和状态。
36
- 3. **选出并完善一个方向**:先检查操作效率、信息密度、可读性和对比度,再比较识别度与整体协调性。把更合适的新方向完善到可用,记录具体选择依据。
34
+ 1. **形成三套方向**:第一套以最直接、稳妥的业务解法为参照,另外两套围绕相同业务任务发展更有表现力但仍可实现的方案。每套都写 `directionId`、`directionLabel`、`description`、`recommendationReason`、`themeId`、`primaryColor` 和 `primaryColorName`;导航结构沿用业务规划,命名模板的导航明暗不作为候选输入;自由创意选定后按项目设计明确填写导航明暗与配套 Token。
35
+ 2. **保证真实差异**:每个方向在构图、字体层级、表面层次、色彩关系中至少两项有明显差异;用已有内容建立重点,保留字段、操作、权限和状态。三套方向分别绑定三个不同的合法主题,其中第三项使用 free-creative 独立推演,主题索引摘要负责说明导航和内容界面的明暗。
36
+ 3. **按流程选择**:Fast 在内部比较三套方向并选择更适合的一套;Plan 在用户没有明确完整风格时必须展示同样三套方向并通过 `ask_human` 选择。
37
37
  4. **把质感写成具体做法**:说明主次区域、数字与标题层级、背景与容器关系、间距与对齐、主操作与状态色的用法。高级感来自这些细节的一致性;表格、批量操作和异常识别保持清晰高效。
38
- 5. **一次交接**:将选定风格及业务理由写入 `visualDirection.description`,主色、背景和强调色的关系写入 `colorStrategy.usage`;AI 决定标记 `ai_default`。比较在本轮规划内完成,后续直接复用。用户看到选定风格和适用场景;用户要求比较时再展示候选。
38
+ 5. **一次交接**:将选定风格及业务理由写入 `visualDirection.description`,主色、背景和强调色的关系写入 `colorStrategy.usage`;AI 决定标记 `ai_default`。比较在本轮规划内完成,后续直接复用。Fast 只对用户展示选定风格和适用场景;Plan 在无明确完整风格时展示三套候选并请用户选择。
39
39
 
40
40
  主色优先采用用户要求、品牌和参考图中的依据。缺少明确依据时,结合使用环境和整体构图确定配色;业务类型用于判断任务和密度,具体颜色由本项目设计确定。已确认的主色可以保留,创意也可通过构图、层级和材质表达。
41
41
 
@@ -43,8 +43,8 @@ Fast、Plan 和单页设计共用 [主题索引](../templates/design-themes/inde
43
43
 
44
44
  | 流程 | 选择与执行 |
45
45
  | --- | --- |
46
- | Fast | 沿用 brief 中已确认或已委托 AI 确定的方向,按摘要绑定一个主题;读取选中模板,直接维护项目 `design.md`,不增加 Plan 的方案确认步骤 |
47
- | Plan | 按 [Plan 视觉候选规则](../sub_skill/yida-design-plan/references/visual-theme-selection.md) 维护已选方向、配色、导航和内部主题绑定;需要比较时给出三套方案,由 CLI 派生项目文档 |
46
+ | Fast | 按上面的共用规则生成三套方向,在内部选出推荐项并写入 brief;命名模板读取选中模板,自由创意独立编写设计与 Token,直接维护项目 `design.md`,不增加方案确认步骤 |
47
+ | Plan | 按 [Plan 视觉候选规则](../sub_skill/yida-design-plan/references/visual-theme-selection.md) 展示同一组三套方向(两个模板方向和一个独立自由创意选项);没有明确完整风格时固定通过 `ask_human` 选择;由 CLI 派生项目文档 |
48
48
  | 单页设计 | 先读当前应用 `design.md` 和主题证据;沿用已确认主题,只补当前页面。尚无主题契约且需选型时读取同一索引,保持现有业务功能与应用主题 |
49
49
 
50
50
  ## 将主题写成项目设计
@@ -55,6 +55,7 @@ Fast、Plan 和单页设计共用 [主题索引](../templates/design-themes/inde
55
55
  - `tokens.application-global` 提供平台与页面共享的基础变量;保留 `tokens.custom-page` 中已有的独立页面语义变量,不能清空。分组仅用于组织,CSS 变量取递归叶子的原名。
56
56
  - 字号、字重、行高与间距的默认值及 Tooltip 等基础契约按 [基础变量契约](../templates/design-themes/basic-tokens.json) 执行;组件选择哪些变量、圆角档位、表面和留白节奏由选中主题决定。
57
57
  - 品牌色与整体氛围按 [主题与 token](../workflow/step-2-theme-system.md) 和 [用户配色优先级](../workflow/output-design.md#用户配色与模板的优先级) 处理。保留主题中可复用的层次、形状与组件机制,不能以固定灰阶覆盖用户整体配色。
58
+ - 导航按 [整体主题规则](application-theme-consistency.md#导航与应用框架) 保留完整 token、状态和消费关系;命名模板的导航明暗随模板派生,自由创意明确设计。
58
59
  - 页面任务和布局来自当前业务事实,主题负责呈现。没有真实内容支撑的图形、指标、侧栏或特色配方不启用;同一应用通过页面局部变体保持统一基础语言。
59
60
  - 按[指标卡与按钮配色](application-theme-consistency.md#指标卡与按钮配色)决定信息和操作的主次,将搭配写入项目组件规则。按钮和指标可用与品牌不同但协调的颜色;主题里的深色面板、近黑按钮都是可选表达,不能覆盖项目配色决定。
60
61
  - 按 [视觉结构配方](visual-scaffold-recipes.md) 把真实区块映射为页面布局与八项设计要点,按 [页面质量门禁](page-quality-gates.md) 写验收条件。配方是交接辅助,不能覆盖主题节奏或生成新的业务模块。
@@ -8,7 +8,7 @@
8
8
  2. 不依赖 `fonts.googleapis.com`。使用主题字体角色与可用系统字体回退,中文字体可用 `-apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif`;远程字体仅使用已验证的 `g.alicdn.com` 资源。
9
9
  3. 数据页、列表、工具和详情以业务内容与操作为主,装饰不干扰信息阅读。
10
10
  4. 本文件不产出 JSX,也不替代 `design.md`;实现阶段读取项目设计与实现技能。
11
- 5. 默认浅色内容画布;暗色需要用户明确要求或已确认方向。导航明暗独立,不因深色导航把内容画布一并变暗。
11
+ 5. 默认浅色内容画布;暗色需要用户明确要求或已确认方向。导航和内容界面的明暗分别描述,导航明暗采用所选主题模板的 `navTheme`,不因深色导航把内容画布一并变暗。
12
12
 
13
13
  ## 五项应用检查
14
14
 
@@ -23,8 +23,8 @@ CANDIDATE_RULE_FILES = (
23
23
  "sub_skill/yida-design-plan/references/visual-theme-selection.md",
24
24
  "sub_skill/yida-design-plan/references/build-plan-schema.md",
25
25
  )
26
- TOKEN_NAME = re.compile(r"--[a-z][a-z0-9-]*\Z")
27
- TOKEN_REFERENCE = re.compile(r"--[a-z][a-z0-9-]*")
26
+ TOKEN_NAME = re.compile(r"--[a-z][a-zA-Z0-9-]*\Z")
27
+ TOKEN_REFERENCE = re.compile(r"--[a-z][a-zA-Z0-9-]*")
28
28
  TOKEN_SUFFIX_SHORTHAND = re.compile(r"--[a-z0-9-]+/(?!\s*--)")
29
29
  TOKEN_WILDCARD = re.compile(r"--[a-z0-9-]*\*")
30
30
 
@@ -193,16 +193,45 @@ def validate(skill_root: Path) -> list[str]:
193
193
  seen[field].add(value)
194
194
  theme_id = theme.get("themeId")
195
195
  template_path = theme.get("templatePath")
196
+ mode = theme.get("mode")
197
+ if mode == "creative":
198
+ if "contentTone" in theme or "navTheme" in theme:
199
+ errors.append(f"{label} 自由创意不能预设 contentTone 或 navTheme")
200
+ else:
201
+ if theme.get("contentTone") not in {"light", "dark"}:
202
+ errors.append(f"{label} contentTone 必须是 light 或 dark")
203
+ if theme.get("navTheme") not in {"light", "dark"}:
204
+ errors.append(f"{label} navTheme 必须是 light 或 dark")
205
+ if not isinstance(theme.get("navigationSummary"), str) or not theme["navigationSummary"].strip():
206
+ errors.append(f"{label} navigationSummary 必须说明导航与应用整体风格的关系")
196
207
  if not isinstance(theme_id, str) or not re.fullmatch(r"[a-z][a-z0-9]*(?:-[a-z0-9]+)*", theme_id):
197
208
  errors.append(f"{label} themeId 格式非法")
198
209
  continue
199
- if template_path != f"templates/design-themes/{theme_id}.md":
210
+ if template_path != f"templates/design-themes/{theme_id}/design.md":
200
211
  errors.append(f"{label} templatePath 必须指向公共主题目录中的同名模板")
201
212
  continue
202
213
  full_path = (skill_root / template_path).resolve()
203
- if full_path.parent != template_dir.resolve():
214
+ if full_path.parent != (template_dir / theme_id).resolve():
204
215
  errors.append(f"{label} templatePath 不得越出公共主题目录")
205
216
  continue
217
+ if theme.get("mode") not in ("template", "creative"):
218
+ errors.append(f"{label} mode 必须是 template 或 creative")
219
+ for field, filename in (("cssTemplatePath", "app_theme.css"), ("formLayoutPath", "form-layout.json")):
220
+ expected = f"templates/design-themes/{theme_id}/{filename}"
221
+ if theme.get(field) != expected or not (skill_root / expected).is_file():
222
+ errors.append(f"{label} 缺少配对资产 {field}: {expected}")
223
+ if full_path.parent.is_dir() and {p.name for p in full_path.parent.iterdir()} != {"design.md", "app_theme.css", "form-layout.json"}:
224
+ errors.append(f"{label} 主题目录必须只包含 design.md、app_theme.css、form-layout.json 三个文件")
225
+ try:
226
+ css = (full_path.parent / "app_theme.css").read_text(encoding="utf-8")
227
+ for name, pattern in (("--color-brand1-6", r"\{\{PRIMARY_COLOR\}\}"), ("--color-brand1-1", r"<生成实际色值:--color-brand1-6 [^;\n]+>")):
228
+ if not re.search(r"^\s*" + re.escape(name) + r":\s*" + pattern + r";", css, re.M):
229
+ errors.append(f"{label} app_theme.css {name} 必须保留项目颜色占位")
230
+ layout = json.loads((full_path.parent / "form-layout.json").read_text(encoding="utf-8"))
231
+ if not isinstance(layout, list) or not layout:
232
+ errors.append(f"{label} form-layout.json 必须是非空组件数组")
233
+ except (OSError, ValueError) as exc:
234
+ errors.append(f"{label} 主题配对资产不可读:{exc}")
206
235
  try:
207
236
  text = full_path.read_text(encoding="utf-8")
208
237
  frontmatter = parse_frontmatter(text)
@@ -211,6 +240,19 @@ def validate(skill_root: Path) -> list[str]:
211
240
  continue
212
241
  if frontmatter.get("themeId") != theme_id:
213
242
  errors.append(f"{template_path} 的 themeId 与索引不一致")
243
+ if theme.get("mode") != "creative":
244
+ nav_theme = frontmatter.get("themeProfile", {}).get("navTheme", frontmatter.get("navTheme"))
245
+ if nav_theme not in {"light", "dark"}:
246
+ errors.append(f"{template_path} 的 navTheme 必须是 light 或 dark")
247
+ style_summary = theme.get("styleSummary", "")
248
+ nav_match = re.search(r"(深色|浅色)导航", style_summary)
249
+ content_match = re.search(r"(深色|浅色)内容界面", style_summary)
250
+ if not nav_match or not content_match:
251
+ errors.append(f"{label} styleSummary 必须用自然语言说明深色或浅色导航,以及深色或浅色内容界面")
252
+ elif nav_theme in {"light", "dark"} and nav_match.group(1) != {"light": "浅色", "dark": "深色"}[nav_theme]:
253
+ errors.append(f"{label} styleSummary 的导航明暗与主题模板 navTheme 不一致")
254
+ if theme.get("navTheme") != nav_theme:
255
+ errors.append(f"{label} navTheme 与主题模板不一致")
214
256
  validate_tokens(frontmatter, text, template_path, contract, errors)
215
257
  headings = re.findall(r"^## (.+)$", text, re.M)
216
258
  if headings != list(REQUIRED_HEADINGS):
@@ -221,7 +263,8 @@ def validate(skill_root: Path) -> list[str]:
221
263
  if TOKEN_SUFFIX_SHORTHAND.search(text) or TOKEN_WILDCARD.search(text):
222
264
  errors.append(f"{template_path} 含未展开的 Token 后缀缩写或通配写法")
223
265
 
224
- actual_files = {f"templates/design-themes/{p.name}" for p in template_dir.glob("*.md") if p.name != "README.md"}
266
+ # Catalog paths use forward slashes on every OS, including nested theme bundles.
267
+ actual_files = {f"templates/design-themes/{p.relative_to(template_dir).as_posix()}" for p in template_dir.rglob("*.md") if p.name != "README.md"}
225
268
  for name in sorted(actual_files - seen["templatePath"]):
226
269
  errors.append(f"主题模板未登记到索引:{name}")
227
270
  for name in sorted(seen["templatePath"] - actual_files):
@@ -233,7 +276,7 @@ def validate(skill_root: Path) -> list[str]:
233
276
  errors.append(f"无法读取候选规则 {relative_path}: {exc}")
234
277
  continue
235
278
  for field in ("themeId", "label"):
236
- for value in seen[field]:
279
+ for value in seen[field] - {item.get(field) for item in themes if item.get("mode") == "creative"}:
237
280
  if value in rule_text:
238
281
  errors.append(f"{relative_path} 硬编码了主题 {field}:{value}")
239
282
  return errors
@@ -13,7 +13,7 @@ description: Plan 模式的视觉设计分支。基于需求选择视觉方向
13
13
 
14
14
  输入为共享的 `.cache/openyida/<项目名>/requirement-brief.json`。
15
15
 
16
- 已有明确的完整视觉方向时直接采用;无明确偏好且不影响业务范围时,由 AI 按[设计方向比较](../../references/theme-selection.md#设计方向比较)完成一次内部比较,选定方向并记录依据;保持原有首轮提问范围。用户明确要求比较或选择风格时,按 [视觉方向选择](references/visual-theme-selection.md) 准备三套应用风格方案,交给 `yida-app` 统一呈现。用户确认主题前只读主题索引中的精简风格摘要,不读取候选模板全文;确认后写入一致的 `visualDirection`、`selectedTheme`、`colorStrategy` 和 `navigationStyle`,再读取选中的一份完整模板。
16
+ 已有明确的完整视觉方向、可信品牌规范、参考材料或应用主题时直接采用。除此之外,按[设计方向比较](../../references/theme-selection.md#设计方向比较)生成恰好三套完整方向(两个模板方向和一个独立自由创意选项),并按[视觉方向选择](references/visual-theme-selection.md)交给 `yida-app` 通过 `ask_human` 统一呈现;不再以“用户是否主动要求比较”作为触发条件。用户确认主题前只读主题索引中的精简风格摘要,不读取候选模板全文;确认后写入一致的 `visualDirection`、`selectedTheme`、`colorStrategy` 和导航结构,再读取选中的一份完整模板;模板方向的导航明暗由模板 `navTheme` 派生;自由创意按业务独立编写设计决策、导航明暗和 Token,不要求匹配模板。
17
17
 
18
18
  ## 阶段二:完成页面视觉应用
19
19
 
@@ -21,10 +21,20 @@ description: Plan 模式的视觉设计分支。基于需求选择视觉方向
21
21
 
22
22
  1. 读取 CLI 返回的 `authoring-context.md` 与 [紧凑计划契约](references/build-plan-compact-schema.md),沿用 pageId 和 sceneKey。
23
23
  2. 为每个真实自定义页填写 `firstScreenFocus`、`layout`、`primaryAction`、`responsive` 与 `acceptanceChecks`;前四项为具体非空说明,验收为非空字符串数组。公共主题不能代替这些决定。纯原生表单应用不增加虚构页记录。
24
- 3. 按实际内容补 `visualMemoryApplications`、页面局部差异与素材策略。完整主题由 CLI 注入,复杂组件定制时再读模板对应章节。
24
+ 3. 按 [整体主题规则](../../references/application-theme-consistency.md#导航与应用框架) 核对导航、应用框架、原生表单、记录详情与自定义页面的配色、形状、文字、间距和状态。每项必须保留 `visualMemoryApplications` 数组;没有匹配的主题记忆点时填写 `[]`,不要省略或写成字符串。按实际内容补页面局部差异与素材策略。完整主题由 CLI 注入,复杂组件定制时再读模板对应章节。
25
25
  4. 全局和局部 token 遵守 [基础变量契约](../../templates/design-themes/basic-tokens.json),明确项目差异写 `visualStyle.tokens`,主色写 `forUser.colorStrategy.primaryColor`;沿用主题的字号、间距和组件圆角。
26
26
  5. CLI 按 [公共输出契约](../../workflow/output-design.md) 生成 frontmatter、anchor 索引和五章正文,并调用同一 `check-design` 校验。缺少逐页决定时只保留可预览草稿,补齐后再生成最终产物;旧计划同样不得以继承主题套话补过门槛。
27
27
 
28
- 用户选择整体暗色或黑色主题时,按 [暗色主题浮层适配](../../references/theme/theme-token-presets.md#暗色主题浮层适配) 补齐 `visualStyle.tokens`;导航明暗保持独立。
28
+ 用户选择整体暗色或黑色主题时,按 [暗色主题浮层适配](../../references/theme/theme-token-presets.md#暗色主题浮层适配) 补齐 `visualStyle.tokens`;内容界面明暗与导航明暗分别描述,导航明暗仍由所选主题模板确定。
29
29
 
30
30
  首版提交前,将基础视觉与 `pageApplications` 一次补齐到已有 `visual.json`。仅超大需求需要中间展示时才按 [按模块更新方案](../../../yida-app/workflow/incremental-preview.md) 提交。主流程负责生成方案、展示和确认,主题 CSS 使用 CLI 返回的 `outputs.theme`。
31
+
32
+ ## 校验失败时定点修复
33
+
34
+ 遇到 `DESIGN_PLAN_PAGE_BINDINGS_REQUIRED` 时,保留现有计划和预览,按以下顺序修复:
35
+
36
+ 1. **定位**:读取错误 `details.issues` 中每项的 `sourcePath`、`path` 和 `code`,修改对应源文件。若问题来自 `business.json`,先按已确认需求修正页面事实,再核对视觉绑定。
37
+ 2. **修改**:以 `business.json` 的 `facts.pages.customPageDetails` 为准,让 `visual.json` 的 `facts.visualStyle.forUser.pageApplications` 与自定义页一一对应;原生表单和数据模型不加入。按 `missing_page` 补项、`unexpected_page` 移除多余绑定、`duplicate_page` 合并重复项;按 `expected_array`、`expected_object`、`expected_nonempty_string` 修正指定字段。每项 `visualMemoryApplications` 必须为数组,无适用内容填 `[]`。
38
+ 3. **回读并重试**:确认修改已写入源文件,再重试原 `materialize` 命令。写入失败、跳过或结果未知时,先回读核实,不能仅凭发起过工具调用认定修复完成。
39
+
40
+ 修复仅涉及错误字段,保留 `build-plan.json`、`business.json`、`visual.json` 和已有预览;不因字段校验失败删除目录、重新 `init`、重写整份 PRD 或扩大需求范围。
@@ -85,6 +85,8 @@ CLI 校验源事实,使用预置模板整批生成 `prd.md`、`design.md` 和
85
85
 
86
86
  `visualStyle` 保存项目选择和差异:
87
87
 
88
+ 应用风格可选择目录中的模板,也可使用 `catalog.creativeOption` 的独立创意入口。后者必须补齐 `visualStyle.creativeDirection`(业务推演、构图、字体、材质、表单布局)与显式设计 Token;详见[应用风格模板与自由创意](../../../references/application-style-library.md)。初始化不会把缺失创意决策标成已完成。
89
+
88
90
  在 `visual.json` 中它位于 `facts.visualStyle`。沿用 init 生成的 `forUser.visualDirection` 和 `forUser.navigationStyle` 对象,只编辑内部字段,不改成字符串或数组。`DESIGN_PLAN_VISUAL_FIELD_TYPE_INVALID` 会给出字段路径与对象示例;示例只说明结构,实际值沿用已确认的视觉选择。
89
91
 
90
92
  ```json
@@ -92,7 +94,7 @@ CLI 校验源事实,使用预置模板整批生成 `prd.md`、`design.md` 和
92
94
  "forUser": {
93
95
  "visualDirection": {"label":"清晰柔和","description":"突出待办与业务状态,浅色界面搭配暖棕色重点操作","source":"user_selected"},
94
96
  "colorStrategy": {"primaryColor":"#6F4E37","primaryColorName":"暖棕色","source":"user_selected","usage":"暖棕浅底、白色卡片与品牌焦点协调"},
95
- "navigationStyle": {"structure":"side","tone":"light","source":"user_selected","selectionReason":"沿用已选的左侧导航"},
97
+ "navigationStyle": {"structure":"side","tone":"light","toneSource":"theme_derived","source":"user_selected","selectionReason":"沿用已选的左侧导航;浅色导航由主题模板派生"},
96
98
  "iconSystem": {"library":"lucide-react","mappings":{"新建采购":"Plus"}},
97
99
  "pageApplications": [
98
100
  {"pageId":"page-1","primaryAction":"列表标题右侧的新建采购按钮打开原生采购表单,成功后刷新列表","firstScreenFocus":"先看到待处理采购数量与最紧急记录,主操作紧邻列表标题","layout":"顶部单行筛选与主操作,下方连续采购列表;必要提示放列表右侧窄栏,列表随记录自然增长","responsive":"窄屏筛选换行,提示移到列表下方,表格保留关键列并允许横向滚动","acceptanceChecks":["首屏可找到待处理记录与新建采购操作","窄屏主操作和错误恢复入口可用"],"visualMemoryApplications":[{"name":"摘要拼接组","renderPolicy":"prd_match_only","target":"采购待办摘要","reason":"页面已有并列的待办状态"}]}
@@ -104,7 +106,7 @@ CLI 校验源事实,使用预置模板整批生成 `prd.md`、`design.md` 和
104
106
  }
105
107
  ```
106
108
 
107
- - 已选主题取当前上下文;主色为 6 位 HEX。导航 structure 为 top/side,tone 为 light/dark;它与整页暗色风格分开记录。
109
+ - 已选主题取当前上下文;主色为 6 位 HEX。导航 `structure` 为模型维护的 top/side;`tone` 为 CLI 从所选主题模板 `navTheme` 派生的 light/dark,并带 `toneSource=theme_derived`,模型不得修改。导航与内容界面的明暗分开记录。
108
110
  - 每个实际自定义页使用相同 pageId,最终物化前必须填写 firstScreenFocus、layout、primaryAction、responsive 四项具体说明和 acceptanceChecks 非空字符串数组;内容须具体到当前页,不能只写继承主题。纯原生页无需增加记录。
109
111
  - 视觉记忆点按适用条件绑定真实区块,无匹配时保留空数组。草稿缺逐页决定可预览,最终产物拒绝缺项;旧计划沿用同一规则,补齐后再物化。
110
112
  - `visualStyle.evidence/constraints` 保留实际视觉依据和约束。
@@ -156,3 +158,5 @@ PRD 实施交接中的 `pages[].navigationPolicy` 与 `pageSpecHandoff` 同级
156
158
  ## 可选字段 patch 与完成校验
157
159
 
158
160
  CLI 集中返回可独立检查的问题及字段路径,再执行完整业务、主题和 HTML 校验。按问题清单一次补齐源事实后重试;草稿空值表示待规划,全部校验通过才写入派生产物。仅做诊断时使用 `--check`。
161
+
162
+ 自由创意(`free-creative`)没有模板导航默认值:在 `navigationStyle.tone` 明确填写项目设计的 `light` 或 `dark`,CLI 标记 `toneSource=project_defined`;此路径可通过 patch 调整 tone,并同步配套导航 Token。命名模板仍按模板派生导航明暗。
@@ -149,7 +149,7 @@
149
149
  - 只有宽泛应用名称且缺少模块、场景、任务、流程和可读需求时才问应用范围。
150
150
  - 审批、角色权限、字段、首页、看板、页面和常规流程细节不进入 `ask_human`;用户已提供时承接,未提供时基于业务推断并在最终计划统一呈现。
151
151
  - 来源不可读时只生成来源补齐问题。
152
- - 视觉问题生成恰好三套完整方向;选中后原子写入 `visualDirection`、`internal.selectedTheme`、`colorStrategy` 和 `navigationStyle`,未选候选不写入最终 JSON。
152
+ - 需要视觉比较时提供两个具体方向与一个自由创意选项;自由创意从业务独立推演。选中后原子写入 `visualDirection`、`internal.selectedTheme`、`colorStrategy` 和 `navigationStyle`,自由创意还须补 `visualStyle.creativeDirection` 与显式 Token;未选候选不写入最终 JSON。详见[应用风格模板与自由创意](../../../references/application-style-library.md)。
153
153
 
154
154
  `askhuman` 保留为 `build-plan.json` 的存储字段名;技能动作和用户交互统一称为 `ask_human`。
155
155
 
@@ -317,10 +317,10 @@
317
317
  | constraints | 保留 brandColors、preferredTone、forbiddenColors、avoidPatterns、referenceMaterials、accessibilityLevel |
318
318
  | forUser.visualDirection | 已选方向的 label、description、source |
319
319
  | forUser.colorStrategy | 项目主色、来源与用法;格式沿用紧凑契约 |
320
- | forUser.navigationStyle | structure=top/side、tone=light/dark、source、selectionReason |
320
+ | forUser.navigationStyle | structure=top/side 由业务导航决定;tone=light/dark 与 toneSource=theme_derived 由 CLI 从所选主题模板派生;另含 source、selectionReason |
321
321
  | internal.selectedTheme | themeId、source、customText;label、templatePath 和 summary 由主题索引补齐 |
322
322
  | forUser.themeProfile | 由选中主题 token、正文规则和项目视觉选择派生的只读摘要 |
323
- | forUser.pageApplications | 按 pageId 对应实际页面;最终物化必填 firstScreenFocus/primaryAction/layout/responsive 非空字符串与 acceptanceChecks 非空字符串数组,按需补局部差异和 visualMemoryApplications;记忆点含 name、renderPolicy、target、reason |
323
+ | forUser.pageApplications | 按 pageId 对应实际页面;最终物化必填 firstScreenFocus/primaryAction/layout/responsive 非空字符串与 acceptanceChecks 非空字符串数组,按需补局部差异;visualMemoryApplications 必须为数组,无适用项填 [];记忆点含 name、renderPolicy、target、reason |
324
324
  | forUser.iconSystem | 可选,library 为 lucide-react 或 @ant-design/icons,mappings 记录实际语义到具体组件;沿用 brief,未配置才用默认空映射 |
325
325
  | forUser.assetStrategy | 页面图片用途、槽位与缺口,沿用[素材交接契约](../../../../yida-image-assets/references/manifest-contract.md);保留 materialStatus、pages、missingAssets、notes |
326
326
  | forUser 的各项 Summary、styleSource、designMdReady | 从主题、项目选择和生成状态派生;已有项目差异保留 |
@@ -348,3 +348,5 @@
348
348
  ### 紧凑区块输入(schemaVersion 2.0)
349
349
 
350
350
  `blocks` 支持按优先顺序填写 `{name,purpose}` 数组,两项均为非空文本,每个区块只使用这两个键。CLI 将其转换为区块说明,并在省略时派生 contentPriority 和 contentRichness.contentLayers;明确填写的内容原样保留。旧版字符串数组继续沿用原字段。业务验收条件写入 execution.acceptanceCriteria,与按资源生成的通用检查合并去重。
351
+
352
+ 自由创意(`free-creative`)没有模板导航默认值:在 `navigationStyle.tone` 明确填写项目设计的 `light` 或 `dark`,CLI 标记 `toneSource=project_defined`;此路径可通过 patch 调整 tone,并同步配套导航 Token。命名模板仍按模板派生导航明暗。
@@ -45,7 +45,7 @@ PRD 决定页面任务、操作和内容优先级;主题决定这些内容如
45
45
 
46
46
  颜色推导与 Fast 相同,直接使用所选主题的公式和项目 token,不增加 Plan 专用染色规则。应用根渐变写 `--pod-app-root-bg-image`;单页渐变与装饰在页面设计中说明作用区域,按 [背景规则](../../../workflow/output-design.md#背景颜色渐变与图片) 实现。
47
47
 
48
- 整体配色与主题的冲突按公共输出契约处理。导航明暗独立于内容画布,既定入口范围保持不变;前台与后台可改变表达强度,但共享基础变量、字体、状态和组件语言。无法保留已选主题核心特征时回到主题选择,不在页面阶段另建主题。
48
+ 整体配色与主题的冲突按公共输出契约处理。导航和内容界面的明暗分别描述,导航明暗采用所选主题模板的 `navTheme`,既定入口范围保持不变;前台与后台可改变表达强度,但共享基础变量、字体、状态和组件语言。无法保留已选主题核心特征时回到主题选择,不在页面阶段另建主题。
49
49
 
50
50
  ## 物化与交接
51
51
 
@@ -54,3 +54,5 @@ CLI 校验主题绑定、解析变量与项目覆盖,生成正文五章,将
54
54
  `build-plan.json`、PRD、设计与 HTML 对应同一 revision。CLI 调用公共 `check-design` 检查格式、变量和引用后,主题 CSS 使用返回的 `outputs.theme`。页面实现只读取最终 PRD 与 design.md;HTML 按 [展示规范](../assets/README.md#需求确认内容范围) 呈现整体风格、主色、导航与需用户补充的素材,详细逐页视觉规则保留在 design.md。
55
55
 
56
56
  页面任务变化时同步逐页应用,主题差异变化时更新 tokens;旧输出不能手改后假装与当前计划一致。普通页面设计不重新发起一轮视觉选择提问,只有新证据造成已选方向冲突时才回到选择阶段。
57
+
58
+ 自由创意(`free-creative`)没有模板导航默认值:在 `navigationStyle.tone` 明确填写项目设计的 `light` 或 `dark`,CLI 标记 `toneSource=project_defined`;此路径可通过 patch 调整 tone,并同步配套导航 Token。命名模板仍按模板派生导航明暗。