scrum-skills 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/.agents/skills/diagram-design/LICENSE +4 -0
  2. package/.agents/skills/diagram-design/SKILL.md +413 -0
  3. package/.agents/skills/diagram-design/UPSTREAM.json +76 -0
  4. package/.agents/skills/diagram-design/UPSTREAM.md +23 -0
  5. package/.agents/skills/diagram-design/assets/example-architecture-containment.html +205 -0
  6. package/.agents/skills/diagram-design/assets/example-architecture-delta.html +193 -0
  7. package/.agents/skills/diagram-design/assets/example-architecture.html +183 -0
  8. package/.agents/skills/diagram-design/assets/example-axonometric-plan-campus.html +108 -0
  9. package/.agents/skills/diagram-design/assets/example-axonometric-plan-coffee-shop.html +121 -0
  10. package/.agents/skills/diagram-design/assets/example-axonometric-plan-warehouse.html +127 -0
  11. package/.agents/skills/diagram-design/assets/example-axonometric-plan.html +114 -0
  12. package/.agents/skills/diagram-design/assets/example-bar.html +129 -0
  13. package/.agents/skills/diagram-design/assets/example-beeswarm.html +384 -0
  14. package/.agents/skills/diagram-design/assets/example-box-plot.html +127 -0
  15. package/.agents/skills/diagram-design/assets/example-bubble.html +147 -0
  16. package/.agents/skills/diagram-design/assets/example-bump.html +142 -0
  17. package/.agents/skills/diagram-design/assets/example-data-flow.html +143 -0
  18. package/.agents/skills/diagram-design/assets/example-datalake.html +269 -0
  19. package/.agents/skills/diagram-design/assets/example-db-schema.html +302 -0
  20. package/.agents/skills/diagram-design/assets/example-dependency.html +224 -0
  21. package/.agents/skills/diagram-design/assets/example-deployment.html +190 -0
  22. package/.agents/skills/diagram-design/assets/example-dp-integration.html +81 -0
  23. package/.agents/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
  24. package/.agents/skills/diagram-design/assets/example-er.html +202 -0
  25. package/.agents/skills/diagram-design/assets/example-exploded-ai-stack.html +85 -0
  26. package/.agents/skills/diagram-design/assets/example-exploded-keyboard.html +84 -0
  27. package/.agents/skills/diagram-design/assets/example-exploded-phone.html +83 -0
  28. package/.agents/skills/diagram-design/assets/example-exploded-unboxing.html +84 -0
  29. package/.agents/skills/diagram-design/assets/example-exploded.html +83 -0
  30. package/.agents/skills/diagram-design/assets/example-fishbone.html +152 -0
  31. package/.agents/skills/diagram-design/assets/example-flowchart.html +163 -0
  32. package/.agents/skills/diagram-design/assets/example-gantt.html +137 -0
  33. package/.agents/skills/diagram-design/assets/example-heatmap.html +224 -0
  34. package/.agents/skills/diagram-design/assets/example-high-level-vertical.html +325 -0
  35. package/.agents/skills/diagram-design/assets/example-high-level.html +301 -0
  36. package/.agents/skills/diagram-design/assets/example-import-drawio.html +185 -0
  37. package/.agents/skills/diagram-design/assets/example-import-excalidraw.html +70 -0
  38. package/.agents/skills/diagram-design/assets/example-import-mermaid.html +70 -0
  39. package/.agents/skills/diagram-design/assets/example-it-state.html +128 -0
  40. package/.agents/skills/diagram-design/assets/example-journey.html +148 -0
  41. package/.agents/skills/diagram-design/assets/example-kanban.html +174 -0
  42. package/.agents/skills/diagram-design/assets/example-layers.html +123 -0
  43. package/.agents/skills/diagram-design/assets/example-line.html +111 -0
  44. package/.agents/skills/diagram-design/assets/example-loop.html +100 -0
  45. package/.agents/skills/diagram-design/assets/example-marimekko.html +148 -0
  46. package/.agents/skills/diagram-design/assets/example-medallion.html +159 -0
  47. package/.agents/skills/diagram-design/assets/example-nested.html +136 -0
  48. package/.agents/skills/diagram-design/assets/example-org-chart.html +45 -0
  49. package/.agents/skills/diagram-design/assets/example-polar.html +116 -0
  50. package/.agents/skills/diagram-design/assets/example-process.html +64 -0
  51. package/.agents/skills/diagram-design/assets/example-pyramid.html +119 -0
  52. package/.agents/skills/diagram-design/assets/example-quadrant-consultant.html +166 -0
  53. package/.agents/skills/diagram-design/assets/example-quadrant.html +135 -0
  54. package/.agents/skills/diagram-design/assets/example-radar.html +139 -0
  55. package/.agents/skills/diagram-design/assets/example-ridgeline.html +104 -0
  56. package/.agents/skills/diagram-design/assets/example-sankey.html +150 -0
  57. package/.agents/skills/diagram-design/assets/example-scatter.html +141 -0
  58. package/.agents/skills/diagram-design/assets/example-sequence-oauth.html +227 -0
  59. package/.agents/skills/diagram-design/assets/example-sequence.html +222 -0
  60. package/.agents/skills/diagram-design/assets/example-service-blueprint.html +185 -0
  61. package/.agents/skills/diagram-design/assets/example-slopegraph.html +119 -0
  62. package/.agents/skills/diagram-design/assets/example-state-lifecycle.html +92 -0
  63. package/.agents/skills/diagram-design/assets/example-state.html +147 -0
  64. package/.agents/skills/diagram-design/assets/example-story-map.html +184 -0
  65. package/.agents/skills/diagram-design/assets/example-streamgraph.html +99 -0
  66. package/.agents/skills/diagram-design/assets/example-swimlane.html +172 -0
  67. package/.agents/skills/diagram-design/assets/example-timeline.html +135 -0
  68. package/.agents/skills/diagram-design/assets/example-tree-block-decomposition.html +151 -0
  69. package/.agents/skills/diagram-design/assets/example-tree.html +173 -0
  70. package/.agents/skills/diagram-design/assets/example-treemap.html +107 -0
  71. package/.agents/skills/diagram-design/assets/example-uml-class.html +188 -0
  72. package/.agents/skills/diagram-design/assets/example-venn.html +110 -0
  73. package/.agents/skills/diagram-design/assets/example-wardley.html +153 -0
  74. package/.agents/skills/diagram-design/assets/example-waterfall.html +129 -0
  75. package/.agents/skills/diagram-design/assets/template-dark.html +99 -0
  76. package/.agents/skills/diagram-design/assets/template-full.html +421 -0
  77. package/.agents/skills/diagram-design/assets/template-motion.html +448 -0
  78. package/.agents/skills/diagram-design/assets/template-terminal.html +188 -0
  79. package/.agents/skills/diagram-design/assets/template.html +100 -0
  80. package/.agents/skills/diagram-design/references/animation.md +143 -0
  81. package/.agents/skills/diagram-design/references/export-registry.md +78 -0
  82. package/.agents/skills/diagram-design/references/export.md +376 -0
  83. package/.agents/skills/diagram-design/references/import-drawio.md +181 -0
  84. package/.agents/skills/diagram-design/references/import-excalidraw.md +130 -0
  85. package/.agents/skills/diagram-design/references/import-mermaid.md +137 -0
  86. package/.agents/skills/diagram-design/references/layout-budget.md +97 -0
  87. package/.agents/skills/diagram-design/references/onboarding.md +368 -0
  88. package/.agents/skills/diagram-design/references/output-spec.md +277 -0
  89. package/.agents/skills/diagram-design/references/primitive-annotation.md +36 -0
  90. package/.agents/skills/diagram-design/references/primitive-icons.md +827 -0
  91. package/.agents/skills/diagram-design/references/primitive-sketchy.md +43 -0
  92. package/.agents/skills/diagram-design/references/primitive-terminal.md +76 -0
  93. package/.agents/skills/diagram-design/references/primitives-core.md +146 -0
  94. package/.agents/skills/diagram-design/references/profiles.md +183 -0
  95. package/.agents/skills/diagram-design/references/semantic-patterns.md +154 -0
  96. package/.agents/skills/diagram-design/references/style-guide.md +236 -0
  97. package/.agents/skills/diagram-design/references/style-vivid.md +148 -0
  98. package/.agents/skills/diagram-design/references/type-architecture-delta.md +143 -0
  99. package/.agents/skills/diagram-design/references/type-architecture.md +117 -0
  100. package/.agents/skills/diagram-design/references/type-axonometric-plan.md +83 -0
  101. package/.agents/skills/diagram-design/references/type-bar.md +108 -0
  102. package/.agents/skills/diagram-design/references/type-data-flow.md +371 -0
  103. package/.agents/skills/diagram-design/references/type-db-schema.md +48 -0
  104. package/.agents/skills/diagram-design/references/type-dependency.md +44 -0
  105. package/.agents/skills/diagram-design/references/type-deployment.md +45 -0
  106. package/.agents/skills/diagram-design/references/type-dp-integration.md +407 -0
  107. package/.agents/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
  108. package/.agents/skills/diagram-design/references/type-er.md +25 -0
  109. package/.agents/skills/diagram-design/references/type-exploded.md +115 -0
  110. package/.agents/skills/diagram-design/references/type-fishbone.md +75 -0
  111. package/.agents/skills/diagram-design/references/type-flowchart.md +23 -0
  112. package/.agents/skills/diagram-design/references/type-gantt.md +45 -0
  113. package/.agents/skills/diagram-design/references/type-heatmap.md +80 -0
  114. package/.agents/skills/diagram-design/references/type-high-level.md +470 -0
  115. package/.agents/skills/diagram-design/references/type-it-state.md +468 -0
  116. package/.agents/skills/diagram-design/references/type-journey.md +55 -0
  117. package/.agents/skills/diagram-design/references/type-kanban.md +49 -0
  118. package/.agents/skills/diagram-design/references/type-layers.md +26 -0
  119. package/.agents/skills/diagram-design/references/type-line.md +337 -0
  120. package/.agents/skills/diagram-design/references/type-loop.md +223 -0
  121. package/.agents/skills/diagram-design/references/type-medallion.md +356 -0
  122. package/.agents/skills/diagram-design/references/type-nested.md +22 -0
  123. package/.agents/skills/diagram-design/references/type-org-chart.md +44 -0
  124. package/.agents/skills/diagram-design/references/type-polar.md +136 -0
  125. package/.agents/skills/diagram-design/references/type-process.md +490 -0
  126. package/.agents/skills/diagram-design/references/type-pyramid.md +33 -0
  127. package/.agents/skills/diagram-design/references/type-quadrant.md +81 -0
  128. package/.agents/skills/diagram-design/references/type-radar.md +82 -0
  129. package/.agents/skills/diagram-design/references/type-sankey.md +75 -0
  130. package/.agents/skills/diagram-design/references/type-scatter.md +276 -0
  131. package/.agents/skills/diagram-design/references/type-sequence.md +130 -0
  132. package/.agents/skills/diagram-design/references/type-service-blueprint.md +103 -0
  133. package/.agents/skills/diagram-design/references/type-state.md +30 -0
  134. package/.agents/skills/diagram-design/references/type-story-map.md +46 -0
  135. package/.agents/skills/diagram-design/references/type-swimlane.md +22 -0
  136. package/.agents/skills/diagram-design/references/type-timeline.md +20 -0
  137. package/.agents/skills/diagram-design/references/type-tree.md +24 -0
  138. package/.agents/skills/diagram-design/references/type-treemap.md +137 -0
  139. package/.agents/skills/diagram-design/references/type-uml-class.md +65 -0
  140. package/.agents/skills/diagram-design/references/type-venn.md +26 -0
  141. package/.agents/skills/diagram-design/references/type-wardley.md +39 -0
  142. package/.agents/skills/diagram-design/references/type-waterfall.md +75 -0
  143. package/.agents/skills/scrum-meta/SKILL.md +36 -36
  144. package/.agents/skills/scrum-planning/SKILL.md +61 -61
  145. package/.agents/skills/scrum-planning/references/schema.md +384 -336
  146. package/.agents/skills/scrum-report/SKILL.md +42 -42
  147. package/.agents/skills/scrum-sprint/SKILL.md +49 -49
  148. package/.agents/skills/scrum-tdd/SKILL.md +140 -127
  149. package/README.md +224 -201
  150. package/assets/board/200.html +1 -1
  151. package/assets/board/404.html +1 -1
  152. package/assets/board/_nuxt/1XlYaCp9.js +1 -0
  153. package/assets/board/_nuxt/4gQF_HS3.js +1 -0
  154. package/assets/board/_nuxt/5okfNy5D.js +1 -0
  155. package/assets/board/_nuxt/{Bb3Limos.js → B0C2jsdk.js} +1 -1
  156. package/assets/board/_nuxt/B1j6UC4U.js +1 -0
  157. package/assets/board/_nuxt/B3LKy6o2.js +1 -0
  158. package/assets/board/_nuxt/BAQQngAq.js +13 -0
  159. package/assets/board/_nuxt/BE6t7Q2m.js +1 -0
  160. package/assets/board/_nuxt/BLvbupFS.js +1 -0
  161. package/assets/board/_nuxt/BQgzP7ur.js +1 -0
  162. package/assets/board/_nuxt/BRZIF_wo.js +1 -0
  163. package/assets/board/_nuxt/BW3xJdEx.js +1 -0
  164. package/assets/board/_nuxt/{Cm9lkUvP.js → BY36DFyj.js} +1 -1
  165. package/assets/board/_nuxt/BZlZD94i.js +1 -0
  166. package/assets/board/_nuxt/BZvXNwev.js +3 -0
  167. package/assets/board/_nuxt/BbxmvdIF.js +1 -0
  168. package/assets/board/_nuxt/BiWrMOsL.js +1 -0
  169. package/assets/board/_nuxt/BizDeOK5.js +1 -0
  170. package/assets/board/_nuxt/BkcaOYQ_.js +95 -0
  171. package/assets/board/_nuxt/BkoKCNUY.js +1 -0
  172. package/assets/board/_nuxt/BlKmZhhF.js +1 -0
  173. package/assets/board/_nuxt/BmBpmU73.js +1 -0
  174. package/assets/board/_nuxt/BrWE0up6.js +1 -0
  175. package/assets/board/_nuxt/Bs52qkgk.js +1 -0
  176. package/assets/board/_nuxt/BtzUbHO_.js +1 -0
  177. package/assets/board/_nuxt/BuBzMkFZ.js +1 -0
  178. package/assets/board/_nuxt/Bubk0xn-.js +1 -0
  179. package/assets/board/_nuxt/BxuBMtk_.js +3 -0
  180. package/assets/board/_nuxt/By1KXXLR.js +1 -0
  181. package/assets/board/_nuxt/BygIGL69.js +2 -0
  182. package/assets/board/_nuxt/C1iO5KH3.js +1 -0
  183. package/assets/board/_nuxt/C2YPmTzt.js +1 -0
  184. package/assets/board/_nuxt/C3SpAhCW.js +1 -0
  185. package/assets/board/_nuxt/C3ZRWz5L.js +1 -0
  186. package/assets/board/_nuxt/C4WdPP6K.js +1 -0
  187. package/assets/board/_nuxt/C6o03JHe.js +1 -0
  188. package/assets/board/_nuxt/C8qB5llI.js +1 -0
  189. package/assets/board/_nuxt/C9MgRdhu.js +1 -0
  190. package/assets/board/_nuxt/CCA81-4P.js +1 -0
  191. package/assets/board/_nuxt/{D2O8Q8x9.js → CFCM18fF.js} +1 -1
  192. package/assets/board/_nuxt/CGXljzd_.js +1 -0
  193. package/assets/board/_nuxt/CI0scS-N.js +1 -0
  194. package/assets/board/_nuxt/CJs9B42o.js +1 -0
  195. package/assets/board/_nuxt/COecDWbb.js +1 -0
  196. package/assets/board/_nuxt/COmtTtfB.js +1 -0
  197. package/assets/board/_nuxt/CPYm4J_K.js +1 -0
  198. package/assets/board/_nuxt/CReA4TEB.js +3 -0
  199. package/assets/board/_nuxt/CXG7GZes.js +1 -0
  200. package/assets/board/_nuxt/CYGiZn-X.js +1 -0
  201. package/assets/board/_nuxt/CaE8VlUp.js +1 -0
  202. package/assets/board/_nuxt/CcGiNUgA.js +1 -0
  203. package/assets/board/_nuxt/Ccgv3lDj.js +1 -0
  204. package/assets/board/_nuxt/CdPGFZyy.js +1 -0
  205. package/assets/board/_nuxt/{DfR3IZN_.js → Cdf_T8Xa.js} +1 -1
  206. package/assets/board/_nuxt/CgQ30j_6.js +1 -0
  207. package/assets/board/_nuxt/ChUHb39z.js +1 -0
  208. package/assets/board/_nuxt/Ck0-FqVI.js +1 -0
  209. package/assets/board/_nuxt/CkWKLtjO.js +1 -0
  210. package/assets/board/_nuxt/Cq7hsCKB.js +1 -0
  211. package/assets/board/_nuxt/CtFknnHZ.js +1 -0
  212. package/assets/board/_nuxt/D166WVUG.js +1 -0
  213. package/assets/board/_nuxt/D4Dpzo9e.js +1 -0
  214. package/assets/board/_nuxt/D5i92OZO.js +1 -0
  215. package/assets/board/_nuxt/D6dUp4Nm.js +9 -0
  216. package/assets/board/_nuxt/DFQDFspC.js +1 -0
  217. package/assets/board/_nuxt/DHX2tw9J.js +1 -0
  218. package/assets/board/_nuxt/DJM7u8P3.js +1 -0
  219. package/assets/board/_nuxt/{BPTrRhcw.js → DLr85ebo.js} +1 -1
  220. package/assets/board/_nuxt/DOMM1wfl.js +1 -0
  221. package/assets/board/_nuxt/DU6ArlUN.js +1 -0
  222. package/assets/board/_nuxt/{B_SlFcWp.js → DUgGsde6.js} +1 -1
  223. package/assets/board/_nuxt/DV4ti-Pq.js +1 -0
  224. package/assets/board/_nuxt/DZ--fXuU.js +1 -0
  225. package/assets/board/_nuxt/D_ct-Stz.js +2 -0
  226. package/assets/board/_nuxt/DbWAComO.js +1 -0
  227. package/assets/board/_nuxt/DbwlcHAt.js +1 -0
  228. package/assets/board/_nuxt/DjzLR9Bl.js +1 -0
  229. package/assets/board/_nuxt/Dki9VkAL.js +3 -0
  230. package/assets/board/_nuxt/DlNJhOoc.js +1 -0
  231. package/assets/board/_nuxt/DqG7CtD4.js +1 -0
  232. package/assets/board/_nuxt/DqUSsCJ2.js +1 -0
  233. package/assets/board/_nuxt/Du2F4WXh.js +1 -0
  234. package/assets/board/_nuxt/DuRiEXn4.js +1 -0
  235. package/assets/board/_nuxt/DxBwVNyP.js +2 -0
  236. package/assets/board/_nuxt/DzmVW5-D.js +1 -0
  237. package/assets/board/_nuxt/I-sGtDIB.js +6 -0
  238. package/assets/board/_nuxt/JU9-x68N.js +1 -0
  239. package/assets/board/_nuxt/Lozm7hhE.js +1 -0
  240. package/assets/board/_nuxt/MMsTMkcB.js +1 -0
  241. package/assets/board/_nuxt/MS7CGmCB.js +1 -0
  242. package/assets/board/_nuxt/OKKaKILz.js +1 -0
  243. package/assets/board/_nuxt/{Csqgy925.js → P6qlvBHA.js} +1 -1
  244. package/assets/board/_nuxt/SrNUvNwO.js +1 -0
  245. package/assets/board/_nuxt/{DSaWoFHS.js → SywdkA98.js} +1 -1
  246. package/assets/board/_nuxt/TBIRpVLG.js +1 -0
  247. package/assets/board/_nuxt/TlTrMIMm.js +1 -0
  248. package/assets/board/_nuxt/Zv9-SOQF.js +1 -0
  249. package/assets/board/_nuxt/_id_.ItzoSaBL.css +1 -0
  250. package/assets/board/_nuxt/builds/latest.json +1 -1
  251. package/assets/board/_nuxt/builds/meta/2218461a-f45b-41d6-ae44-b0d2332a9511.json +1 -0
  252. package/assets/board/_nuxt/burndown.CT8fx1Ge.css +1 -0
  253. package/assets/board/_nuxt/diagrams.D1ybqBem.css +1 -0
  254. package/assets/board/_nuxt/{entry.CKHePurH.css → entry.BCuHiFgF.css} +1 -1
  255. package/assets/board/_nuxt/epics.CUeDIEa0.css +1 -0
  256. package/assets/board/_nuxt/error-404.Y9imKiDC.css +1 -0
  257. package/assets/board/_nuxt/error-500.DufSBGVC.css +1 -0
  258. package/assets/board/_nuxt/gantt.CiC2Ts1t.css +1 -0
  259. package/assets/board/_nuxt/jbri6q1p.js +1 -0
  260. package/assets/board/_nuxt/last-change.C05Vc3BF.css +1 -0
  261. package/assets/board/_nuxt/milestones.Civ3sMiQ.css +1 -0
  262. package/assets/board/_nuxt/oSJF4yHw.js +1 -0
  263. package/assets/board/_nuxt/pages.BshWbOyo.css +1 -0
  264. package/assets/board/_nuxt/q_8bxRMt.js +1 -0
  265. package/assets/board/_nuxt/tests.Ci9fBCka.css +1 -0
  266. package/assets/board/burndown/index.html +1 -1
  267. package/assets/board/diagrams/index.html +1 -0
  268. package/assets/board/epics/index.html +1 -1
  269. package/assets/board/favicon.svg +16 -16
  270. package/assets/board/gantt/index.html +1 -1
  271. package/assets/board/index.html +1 -1
  272. package/assets/board/last-change/index.html +1 -1
  273. package/assets/board/milestones/index.html +1 -1
  274. package/assets/board/tests/index.html +1 -1
  275. package/bin/scrum-skills.mjs +204 -191
  276. package/docs/ai-assistant-guide.md +1008 -1008
  277. package/package.json +42 -41
  278. package/templates/AGENTS.md +84 -74
  279. package/tools/agile-tools.mjs +510 -510
  280. package/tools/ai.mjs +464 -464
  281. package/tools/diagram-import.mjs +238 -0
  282. package/tools/diagram-lint.mjs +518 -0
  283. package/tools/diagram.mjs +299 -0
  284. package/tools/git-commit.mjs +216 -216
  285. package/tools/last-change.mjs +326 -326
  286. package/tools/projects.mjs +240 -215
  287. package/tools/serve.mjs +180 -154
  288. package/tools/validate.mjs +781 -664
  289. package/assets/board/_nuxt/1eqboJxR.js +0 -1
  290. package/assets/board/_nuxt/2K7ag6ES.js +0 -1
  291. package/assets/board/_nuxt/51OWHj8c.js +0 -2
  292. package/assets/board/_nuxt/6gFtTBwm.js +0 -1
  293. package/assets/board/_nuxt/B3jkABw9.js +0 -1
  294. package/assets/board/_nuxt/B5n2_jZN.js +0 -1
  295. package/assets/board/_nuxt/BDK2Hj7B.js +0 -1
  296. package/assets/board/_nuxt/BDcnzXHq.js +0 -1
  297. package/assets/board/_nuxt/BaG8y0Wt.js +0 -1
  298. package/assets/board/_nuxt/BbwJq5pb.js +0 -1
  299. package/assets/board/_nuxt/BgLeKwx0.js +0 -1
  300. package/assets/board/_nuxt/Bi9Axj3V.js +0 -1
  301. package/assets/board/_nuxt/BmxvtaMq.js +0 -1
  302. package/assets/board/_nuxt/BodFvto3.js +0 -1
  303. package/assets/board/_nuxt/BpWeHLuN.js +0 -1
  304. package/assets/board/_nuxt/BuOKDFiJ.js +0 -1
  305. package/assets/board/_nuxt/C40iTe-x.js +0 -1
  306. package/assets/board/_nuxt/C7K0R7F-.js +0 -2
  307. package/assets/board/_nuxt/C8vL692X.js +0 -1
  308. package/assets/board/_nuxt/C9StZL3D.js +0 -3
  309. package/assets/board/_nuxt/CGI_ZV79.js +0 -1
  310. package/assets/board/_nuxt/CJ2mz0WY.js +0 -1
  311. package/assets/board/_nuxt/CJMBJQuf.js +0 -1
  312. package/assets/board/_nuxt/CK-lOYG9.js +0 -1
  313. package/assets/board/_nuxt/CK9_veoz.js +0 -1
  314. package/assets/board/_nuxt/CLBcBrYf.js +0 -1
  315. package/assets/board/_nuxt/CMUi2-Lj.js +0 -1
  316. package/assets/board/_nuxt/COf6E6h4.js +0 -1
  317. package/assets/board/_nuxt/CPCUMJnF.js +0 -1
  318. package/assets/board/_nuxt/CPcKlmSm.js +0 -1
  319. package/assets/board/_nuxt/CQTvWh4i.js +0 -1
  320. package/assets/board/_nuxt/CSEEUF8S.js +0 -1
  321. package/assets/board/_nuxt/CSSb154I.js +0 -13
  322. package/assets/board/_nuxt/CgDTd7jS.js +0 -1
  323. package/assets/board/_nuxt/ChG76uh9.js +0 -1
  324. package/assets/board/_nuxt/Ci0qbkgh.js +0 -1
  325. package/assets/board/_nuxt/CqoQ__I_.js +0 -1
  326. package/assets/board/_nuxt/CuJUHLl8.js +0 -1
  327. package/assets/board/_nuxt/CvLiA4_O.js +0 -1
  328. package/assets/board/_nuxt/Cvs12oA0.js +0 -3
  329. package/assets/board/_nuxt/CyEXFe3V.js +0 -1
  330. package/assets/board/_nuxt/Cz6rZcLK.js +0 -1
  331. package/assets/board/_nuxt/D2FhHl1o.js +0 -1
  332. package/assets/board/_nuxt/D3YCAmfu.js +0 -1
  333. package/assets/board/_nuxt/D5CE81jK.js +0 -1
  334. package/assets/board/_nuxt/D75vbfSb.js +0 -1
  335. package/assets/board/_nuxt/D99LbGfb.js +0 -9
  336. package/assets/board/_nuxt/DEfLc7p3.js +0 -6
  337. package/assets/board/_nuxt/DF-nsa1Z.js +0 -1
  338. package/assets/board/_nuxt/DIc8yx98.js +0 -1
  339. package/assets/board/_nuxt/DLkAKotw.js +0 -1
  340. package/assets/board/_nuxt/DRPlYvb3.js +0 -1
  341. package/assets/board/_nuxt/DRlQgul3.js +0 -1
  342. package/assets/board/_nuxt/DSLbmoWa.js +0 -1
  343. package/assets/board/_nuxt/DWO9c9yp.js +0 -1
  344. package/assets/board/_nuxt/DZo3dYLJ.js +0 -3
  345. package/assets/board/_nuxt/D_S6N7_b.js +0 -1
  346. package/assets/board/_nuxt/DajA-Tkt.js +0 -1
  347. package/assets/board/_nuxt/DbHiyab-.js +0 -1
  348. package/assets/board/_nuxt/Dc7Ql6eE.js +0 -1
  349. package/assets/board/_nuxt/Dd9ZukPU.js +0 -1
  350. package/assets/board/_nuxt/Dg2LiqmN.js +0 -1
  351. package/assets/board/_nuxt/DhuleNnm.js +0 -1
  352. package/assets/board/_nuxt/DkI1Qxpp.js +0 -95
  353. package/assets/board/_nuxt/DnDHGSYI.js +0 -1
  354. package/assets/board/_nuxt/DpXJ_tCU.js +0 -1
  355. package/assets/board/_nuxt/DqZgF3hU.js +0 -1
  356. package/assets/board/_nuxt/DqcxvfbD.js +0 -1
  357. package/assets/board/_nuxt/DsA2lVci.js +0 -1
  358. package/assets/board/_nuxt/Dtsa-1NS.js +0 -1
  359. package/assets/board/_nuxt/Du91iq0p.js +0 -1
  360. package/assets/board/_nuxt/Dx1wcYFo.js +0 -1
  361. package/assets/board/_nuxt/EYTShbt4.js +0 -1
  362. package/assets/board/_nuxt/MaXJprwN.js +0 -1
  363. package/assets/board/_nuxt/P9x67aq2.js +0 -1
  364. package/assets/board/_nuxt/S08nFESZ.js +0 -3
  365. package/assets/board/_nuxt/V0uynWE2.js +0 -1
  366. package/assets/board/_nuxt/Vo4wMbnS.js +0 -1
  367. package/assets/board/_nuxt/ZVTqot-_.js +0 -1
  368. package/assets/board/_nuxt/ZngEd3HB.js +0 -1
  369. package/assets/board/_nuxt/_id_.B2NDKSlX.css +0 -1
  370. package/assets/board/_nuxt/assMu_Wn.js +0 -1
  371. package/assets/board/_nuxt/builds/meta/8e23aec9-5b67-4569-b8bf-d4f07e50ffdf.json +0 -1
  372. package/assets/board/_nuxt/burndown.Do6IbM6o.css +0 -1
  373. package/assets/board/_nuxt/epics.Dmessplu.css +0 -1
  374. package/assets/board/_nuxt/error-404.BFmXOnCT.css +0 -1
  375. package/assets/board/_nuxt/error-500.BZ-DdjQ6.css +0 -1
  376. package/assets/board/_nuxt/gantt.Dmp00GUo.css +0 -1
  377. package/assets/board/_nuxt/last-change.1Su4GrCN.css +0 -1
  378. package/assets/board/_nuxt/milestones.U0xKCsEo.css +0 -1
  379. package/assets/board/_nuxt/pages.Dbj2IVk8.css +0 -1
  380. package/assets/board/_nuxt/rlePnzpc.js +0 -1
  381. package/assets/board/_nuxt/tests.dXlUX16A.css +0 -1
  382. package/assets/board/_nuxt/uKzCKCTq.js +0 -1
  383. package/assets/board/_nuxt/vwxaNGfc.js +0 -1
  384. package/assets/board/_nuxt/yh6sf_D5.js +0 -1
@@ -0,0 +1,236 @@
1
+ # Style Guide
2
+
3
+ > **本项目有效皮肤:** [`style-vivid.md`](style-vivid.md) —— 纯白 `#ffffff` 纸面、`#0b0b0f` 墨色、
4
+ > 五个高饱和语义色(`#334155` / `#be123c` / `#047857` / `#b45309` / `#6d28d9`)+ 内联线性图标。
5
+ > 与下表的出厂默认值冲突时,以 `style-vivid.md` 为准:本项目不画米白纸,也不用单一珊瑚 accent。
6
+
7
+ **The single source of truth for colors, typography, and tokens.** Every diagram draws from this — not from hex values inlined in other reference files. If you want to change the visual skin of Diagram Design, change this file.
8
+
9
+ Default skin is a cool editorial palette — white-smoke paper, jet-black ink, burnt-tangerine accent, blue-slate muted. It's designed to look good out of the box; swap these values (or run [`onboarding.md`](onboarding.md)) and every new diagram inherits the new skin without touching any type-specific logic.
10
+
11
+ To generate your own from a website URL, see [`onboarding.md`](onboarding.md).
12
+
13
+ ---
14
+
15
+ ## Tokens
16
+
17
+ ### Semantic roles
18
+
19
+ Every token is referred to by **semantic role**, not by its hex value. Type references (`type-*.md`) and SKILL.md say `accent`, not `#bf4520`.
20
+
21
+ | Role | Purpose | Default (light) | Default (dark) |
22
+ |---|---|---|---|
23
+ | `paper` | Page background, default node fill | `#f5f5f5` (white-smoke) | `#2d3142` (jet-black) |
24
+ | `paper-2` | Diagram container bg, secondary fill | `#ececec` | `#393e53` |
25
+ | `ink` | Primary text, primary stroke | `#2d3142` (jet-black) | `#f5f5f5` (white-smoke) |
26
+ | `ink-strong` | High-contrast text on warm accent fills | `#111111` | `#111111` |
27
+ | `muted` | Secondary text, default arrow stroke | `#4f5d75` (blue-slate) | `#bfc0c0` (silver) |
28
+ | `soft` | Sublabels, boundary labels | `#5a6580` | `#949eb2` |
29
+ | `rule` | Hairline borders | `rgba(45,49,66,0.12)` | `rgba(245,245,245,0.12)` |
30
+ | `rule-solid` | Stronger borders, baselines | `#bfc0c0` (silver) | `rgba(191,192,192,0.25)` |
31
+ | `accent` | Focal / 1–2 max per diagram | `#bf4520` (burnt-tangerine) | `#f08a59` |
32
+ | `accent-tint` | Fill for accent-bordered boxes | `rgba(191,69,32,0.08)` | `rgba(240,138,89,0.10)` |
33
+ | `link` | HTTP/API calls, external arrows | `#2e5aa8` | `#739fdf` |
34
+
35
+ > **Brand palette source:** this skin maps to a five-color brand palette: `jet-black #2d3142`, `silver #bfc0c0`, `white-smoke #f5f5f5`, `atomic-tangerine`, `blue-slate #4f5d75`. The light `accent` is not the raw brand tangerine. Raw atomic-tangerine reads 2.86:1 on `paper`, too faint for an arrow or a label, so the skin uses `#bf4520`, the same hue darkened until it clears 4.5:1 as text. The `soft`, `rule`, and `link` tokens are derived (a darker slate, ink at opacity, and a saturated variant in the blue-slate hue family) to cover roles the brand palette doesn't name directly. Every derived value is held to the contrast contract below.
36
+
37
+ ### Contrast contract
38
+
39
+ Every token must clear the threshold for each role it plays, against the background it actually sits on, in both skins. `scripts/verify-contrast.py` computes the WCAG 2.x ratio for every row above against the `paper` of its skin (`ink-strong` against the 0.85 `accent` fill it labels) and fails CI when one falls short.
40
+
41
+ | Use | Minimum vs. its actual background |
42
+ |---|---|
43
+ | Regular text, including any `soft`, `link`, or `accent` used as text | 4.5:1 |
44
+ | Large text (24px+, or 18.7px+ at weight 600+) | 3:1 |
45
+ | Essential non-text marks: lines, arrows, borders, focus outlines, data points | 3:1 against the adjacent color |
46
+ | Decorative rules and translucent tints (`rule`, `rule-solid`, `paper-2`, `accent-tint`, fills at opacity) | No minimum, but never the only carrier of meaning |
47
+
48
+ - **A token used in several roles must pass each one.** `accent` is a stroke in one place and a label in another, so it is held to 4.5:1, not the 3:1 its strokes alone would need. Don't assume a token is non-text because it usually is.
49
+ - **Translucent colors are composited first.** An `rgba()` fill or stroke is blended over `paper` before its ratio is measured. A value that clears the bar at full strength can fail at 0.5 opacity.
50
+ - **Surfaces other than `paper` cost contrast.** Inside an `accent-tint` box or on `paper-2` every ratio drops. Measure text placed there against that surface, not against `paper`.
51
+ - **Current defaults:** light `accent` 4.71:1, `soft` 5.34:1, `link` 6.13:1, `muted` 6.11:1 on `#f5f5f5`; dark `accent` 5.21:1, `soft` 4.78:1, `link` 4.76:1 on `#2d3142`.
52
+
53
+ ### Inversion rule (light → dark)
54
+
55
+ Any `rgba(45,49,66, X)` in light becomes `rgba(245,245,245, X)` in dark. Same opacities, RGB flipped. The accent gets a slight hue-shift brighter to read on dark paper.
56
+
57
+ ### Series palette (multi-series chart types only)
58
+
59
+ A small set of desaturated, editorial-tone colors for chart types that genuinely need to distinguish multiple overlapping entities (currently: **radar**). The "1-focal" rule still holds — `accent` is reserved for the focal series; the palette below covers the rest.
60
+
61
+ | Token | Light | Dark | Notes |
62
+ |---|---|---|---|
63
+ | `series-1` | `#7c8f6f` (sage) | `#9caf8f` | Non-focal series |
64
+ | `series-2` | `#5e7a9b` (dusty-blue) | `#82a0c0` | Non-focal series |
65
+ | `series-3` | `#b8915a` (mustard) | `#d3ad7a` | Non-focal series |
66
+ | `series-4` | `#9c6b50` (rust-brown) | `#b88670` | Non-focal series |
67
+ | `series-5` | `#6e6479` (slate) | `#8d8298` | Non-focal series |
68
+
69
+ Fills sit at `0.18` opacity light, `0.22` dark; strokes use the full color. **Don't backfill these tokens to non-chart types** — architecture, swimlane, etc. continue to use muted-ink variants. The series palette is opt-in for diagrams where overlapping shapes demand distinguishable color, not a license to add color elsewhere.
70
+
71
+ ### Terminal skin (opt-in alternate)
72
+
73
+ A self-contained palette for the terminal-window primitive (see [primitive-terminal.md](primitive-terminal.md)) — a CLI-chrome register for dev-tool posts and technical social cards. It does not replace the default skin above and isn't affected by onboarding; it's a second, fixed skin you opt into per-diagram.
74
+
75
+ | Token | Hex | Purpose |
76
+ |---|---|---|
77
+ | `terminal-page` | `#0a0a0a` | Page background behind the window |
78
+ | `terminal-paper` | `#141414` | Window body, node fill |
79
+ | `terminal-bar` | `#1b1b1b` | Titlebar strip |
80
+ | `terminal-border` | `#2b2b2b` | Window border, hairlines |
81
+ | `terminal-ink` | `#f5f5f5` | Primary text, primary stroke (same white-smoke as default `ink`) |
82
+ | `terminal-muted` | `#9a9a9a` | Secondary text, sublabels, ring stroke |
83
+ | `terminal-soft` | `#5c5c5c` | Tertiary — inactive dots, spokes |
84
+ | `terminal-accent` | `#ff5a36` | The one accent — focal station, prompt sign, active dot |
85
+ | `terminal-accent-tint` | `rgba(255,90,54,0.12)` | Fill for accent-bordered boxes |
86
+
87
+ **1-accent rule still holds.** Everything that isn't `terminal-ink` or `terminal-muted`/`terminal-soft` should be `terminal-accent` — never introduce a second hue.
88
+
89
+ ---
90
+
91
+ ## Typography
92
+
93
+ | Role | Family | Size | Weight | Usage |
94
+ |---|---|---|---|---|
95
+ | `title` | Instrument Serif | 1.75rem | 400 | Page H1 |
96
+ | `node-name` | Geist (sans) | 12px | 600 | Human-readable labels |
97
+ | `sublabel` | Geist Mono | 9px | 400 | Port, protocol, URL, field type |
98
+ | `eyebrow` | Geist Mono | 7–8px | 500, tracked 0.18em, uppercase | Type tags, axis labels |
99
+ | `arrow-label` | Geist Mono | 8px | 400, tracked 0.06em | Arrow annotations |
100
+ | `callout` | Instrument Serif *italic* | 14px | 400 | Editorial asides only |
101
+
102
+ ### Font stack
103
+
104
+ ```html
105
+ <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&family=Noto+Serif:ital@0;1&family=Noto+Sans+KR:wght@400;500;600&family=Noto+Serif+KR:wght@400&family=Noto+Sans+TC:wght@400;500;600&family=Noto+Serif+TC:wght@400&display=swap" rel="stylesheet">
106
+ ```
107
+
108
+ ### Font source
109
+
110
+ The font source decides whether a diagram makes any network request. It is a skin setting, so a saved profile carries it too.
111
+
112
+ Font source: `web`
113
+
114
+ | Value | What ships | Network |
115
+ |---|---|---|
116
+ | `web` (default) | The Google Fonts `<link>` above; text renders in Instrument Serif, Geist, and Geist Mono | One stylesheet request to `fonts.googleapis.com`, plus the font files |
117
+ | `system` | No font `<link>`; every family stack falls through to the platform's own serif, sans, and monospace faces | None |
118
+
119
+ Use `system` when the user asks for offline output, system fonts, or no Google Fonts, or when this line says `system`. In `system` mode:
120
+
121
+ - Omit the font `<link>` (and the export `@import`) entirely. Keep every `font-family` stack as written: each one already ends in a generic family (`serif`, `system-ui, sans-serif`, `ui-monospace, monospace`), so a viewer who has Geist installed still gets it and everyone else gets their system face.
122
+ - Fallback faces have different metrics from Geist, so keep the 8px label padding intact rather than trimming boxes to the Geist measurement.
123
+ - Export with `(导出由看板完成:从产物 HTML 抽取 SVG,PNG 在浏览器端渲染)
124
+
125
+ The render linter's default run (`lint-render.py` with network blocked) measures exactly this fallback rendering, so every shipped template and example is already checked in system-font mode.
126
+
127
+ To keep the editorial faces with no network at all, install Instrument Serif, Geist, and Geist Mono locally (all three are SIL Open Font License) and use `system`: the stacks resolve to the installed faces first.
128
+
129
+ ### Korean labels
130
+
131
+ Geist and Instrument Serif carry no Hangul. A Korean `<text>` element extends its own family — never swap the skin:
132
+
133
+ ```svg
134
+ <text font-family="'Geist', 'Noto Sans KR', 'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif">결제 서비스</text>
135
+ ```
136
+
137
+ Both Noto faces ship in the font link above, so the web font resolves before any locally installed one and the same file renders identically on macOS, Windows, and a reviewer's browser. The local families follow it for offline viewing. Page titles need the serif equivalent — `'Instrument Serif', 'Noto Serif KR', serif` — or a mixed Latin/Korean title resolves Hangul through the platform's generic serif and the two halves disagree. Google's `css2` endpoint slices Korean by unicode-range, so a diagram with a handful of Korean labels downloads only the slices it touches. The four templates carry both faces because a new diagram may contain Hangul; the shipped Latin-only examples keep the shorter link, since a file with no Hangul has nothing to resolve.
138
+
139
+ **Width budget.** Measure per character, not per script: **every Unicode wide or full-width character costs 1em, every other character costs its face's Latin advance** (0.60em sans, 0.62em mono), and nonspacing/enclosing marks cost nothing. Sum over the string and multiply by the font size for the text width, then add padding and round the box up to the next multiple of 4. `verify-treemap.py` enforces exactly this text width for treemap cell labels; the padding and rounding are authoring convention, and no other type carries an automatic check, so on those the budget is yours to hold.
140
+
141
+ Counting by script is the trap. `주문 v2.1` is two full-width syllables and five narrow characters; a formula that tallies Hangul, Latin letters, and spaces silently drops `2`, `.`, and `1` and sizes the box for four of its seven characters. Every rendered character costs something — measure per character, never per script.
142
+
143
+ Three rules follow from Hangul metrics:
144
+
145
+ - **Sublabels stay Latin.** Ports, protocols, field types, and URLs are Latin anyway — keep `Geist Mono` there and don't translate them. Hangul in a 9px mono sublabel is unreadable and has no mono face to fall back to.
146
+ - **Floor of 12px.** Hangul goes muddy below 12px. If a Korean name doesn't fit at 12px, cut the name — don't shrink the type.
147
+ - **Arrow labels, eyebrows, and legend text switch register.** Those slots are 7–8px Geist Mono, uppercase and tracked, which Hangul has neither a face nor legibility for. A Korean label in one of those slots becomes 12px sans at weight 500 with no tracking and no uppercase transform, and its mask rect grows to match (16px tall, width from the budget above, still rounded to a multiple of 4). Latin labels in the same diagram keep the mono treatment.
148
+
149
+ **Load-bearing rule:** Mono is for *technical* content (ports, commands, URLs, field types). Names go in Geist sans. Page title is Instrument Serif. Italic Instrument Serif is reserved for annotation callouts (see [primitive-annotation.md](primitive-annotation.md)). **Never JetBrains Mono** as a blanket "dev" font.
150
+
151
+ ### Traditional Chinese labels
152
+
153
+ Geist and Instrument Serif carry no Han. A Traditional Chinese `<text>` element extends its own family — never swap the skin:
154
+
155
+ ```svg
156
+ <text font-family="'Geist', 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei', sans-serif">請求項比對</text>
157
+ ```
158
+
159
+ Both Noto TC faces ship in the font link above, so the web font resolves before any locally installed one and the same file renders identically on macOS, Windows, and a reviewer's browser. The local families follow it for offline viewing. Page titles need the serif equivalent — `'Instrument Serif', 'Noto Serif TC', serif` — or a mixed Latin/Han title resolves Han through the platform's generic serif and the two halves disagree. Google's `css2` endpoint slices Chinese by unicode-range, so a diagram with a handful of Chinese labels downloads only the slices it touches.
160
+
161
+ **Width budget.** The per-character contract above is unchanged: every Unicode wide or full-width character costs 1em, every other character costs its face's Latin advance, and nonspacing marks cost nothing. Full-width punctuation — `()「」,。:` — is wide and costs 1em as well, which is the part most often dropped.
162
+
163
+ Counting by script is the trap. `請求項 v2.1` is three full-width characters and five narrow ones; a formula that tallies Han and Latin letters silently drops `2`, `.`, and `1` and sizes the box for six of its nine characters.
164
+
165
+ Three rules follow from Han metrics, mirroring the Hangul ones:
166
+
167
+ - **Sublabels stay Latin.** Ports, protocols, field types, and URLs are Latin anyway — keep `Geist Mono` there and don't translate them. Han in a 9px mono sublabel is unreadable and has no mono face to fall back to. A sublabel that is prose rather than a value may be Chinese, but it then switches register by the third rule below.
168
+ - **Floor of 12px.** Han packs more strokes than Hangul into the same em box, so the 12px floor binds at least as hard here. If a Chinese name doesn't fit at 12px, cut the name — don't shrink the type.
169
+ - **Arrow labels, eyebrows, and legend text switch register.** Those slots are 7–8px Geist Mono, uppercase and tracked, which Han has neither a face nor legibility for. A Chinese label in one of those slots becomes 12px sans at weight 500 with no tracking and no uppercase transform, and its mask rect grows to match (16px tall, width from the budget above, still rounded to a multiple of 4). Latin labels in the same diagram keep the mono treatment.
170
+
171
+ Simplified Chinese takes the same three rules with the Simplified stack (`'Noto Sans SC'`, `'PingFang SC'`, `'Microsoft YaHei'`). That face does not ship in the link, so Simplified labels still resolve through whatever the viewer has locally.
172
+
173
+ ### Cyrillic labels
174
+
175
+ Geist and Geist Mono ship Cyrillic (`cyrillic` and `cyrillic-ext` on Google Fonts), so names, sublabels, arrow labels, eyebrows, and legend text in Bulgarian, Russian, Ukrainian, or Serbian keep the Latin treatment: same faces, sizes, tracking, and uppercase. There is no register switch: Hangul and Han switch register because Geist Mono has no face for them, and Geist Mono does cover Cyrillic.
176
+
177
+ Instrument Serif carries no Cyrillic. A page title extends its family — `'Instrument Serif', 'Noto Serif', serif` — or a mixed Latin/Cyrillic title resolves Cyrillic through whatever face comes next and the two halves disagree. Noto Serif ships in the font link above, upright and italic, so an italic callout in Cyrillic takes the same stack.
178
+
179
+ **Noto Serif goes ahead of the CJK serifs.** When a stack also lists `'Noto Serif KR'` or `'Noto Serif TC'`, put `'Noto Serif'` ahead of them. Google Fonts slices Cyrillic into those faces as well, so a stack that reaches a CJK face first draws its Cyrillic from it. That is why the templates put `'Noto Serif'` between `'Instrument Serif'` and `'Noto Serif KR'`; Noto Serif has no Hangul or Han, so Korean and Chinese titles pass straight through it.
180
+
181
+ **Width budget.** The per-character contract above is unchanged: every character costs its face's Latin advance (0.60em sans, 0.62em mono). It fits Geist Mono exactly and Geist sans only on average. Geist Mono is monospaced: a Cyrillic glyph advances exactly as far as a Latin one, so sublabels, arrow labels, eyebrows, legend text, and their mask rects are sized as for Latin. Geist sans is not. Its wide Cyrillic letters, capitals and lowercase alike (such as `Ж Ш Щ Ю Ы`, `ж ш щ ы ю`), run well past the 0.60em average: `Шкаф ODF-2` at 12px is budgeted at 72px and draws at about 76. Rounding the box up to a multiple of 4 recovers at most 3px, so it is not the remedy. Leave the overshoot in the box padding and measure a Cyrillic sans name in the browser — `verify-treemap.py` holds the budget, not the drawn width, so it will not catch the overshoot.
182
+
183
+ Counting by script is still the trap. `Шкаф ODF-2` is four Cyrillic letters, a space, three Latin letters, a hyphen, and a digit; a formula that tallies Cyrillic letters, Latin letters, and spaces silently drops `-` and `2` and sizes the box for eight of its ten characters.
184
+
185
+ **Preserve printed labels.** A label the reader matches against a physical thing — a cabinet, a splice closure, a port map — carries the exact printed string. Don't transliterate it and don't re-case it; if one has to sit in an uppercase slot such as an eyebrow, drop the transform for that label rather than re-case the printed string. `Шкаф ODF-2` stays `Шкаф ODF-2`, not `Shkaf ODF-2`.
186
+
187
+ ---
188
+
189
+ ## Stroke, radius, spacing
190
+
191
+ | Token | Value | Use |
192
+ |---|---|---|
193
+ | `stroke-thin` | `0.8` | Tag-box outlines, leaf nodes |
194
+ | `stroke-default` | `1` | Most strokes |
195
+ | `stroke-strong` | `1.2` | Emphasis strokes |
196
+ | `radius-sm` | `4` | Small tags |
197
+ | `radius-md` | `6` | Node boxes |
198
+ | `radius-lg` | `8` | Containers, rings |
199
+ | `grid` | `4` | Every coord, size, and gap is divisible by 4 (hard rule) |
200
+
201
+ ---
202
+
203
+ ## Node type → treatment
204
+
205
+ Semantic role combinations — reference these by name in type specs.
206
+
207
+ | Type | Fill | Stroke |
208
+ |---|---|---|
209
+ | `focal` (1–2 max) | `accent-tint` | `accent` |
210
+ | `backend` | `#ffffff` (white) | `ink` |
211
+ | `store` | `ink @ 0.05` | `muted` |
212
+ | `external` | `ink @ 0.03` | `ink @ 0.30` |
213
+ | `input` | `muted @ 0.10` | `soft` |
214
+ | `optional` | `ink @ 0.02` | `ink @ 0.20` dashed `4,3` |
215
+ | `security` | `accent @ 0.05` | `accent @ 0.50` dashed `4,4` |
216
+
217
+ ---
218
+
219
+ ## Customizing the skin
220
+
221
+ Four options:
222
+
223
+ 1. **Run onboarding** — see [`onboarding.md`](onboarding.md). Drop a URL; the skill extracts the palette + fonts and rewrites this file.
224
+ 2. **Edit by hand** — change the hex values in the tables above. Run the pre-output taste gate afterward to verify the accent still reads as "focal" against the new paper color.
225
+ 3. **Brand handoff** — paste your existing design-token JSON into a new section here and map its tokens to the semantic roles above.
226
+ 4. **Client profiles** — save and switch named skins, or bind one to a project, using [`profiles.md`](profiles.md).
227
+
228
+ ### Constraints (don't break these)
229
+
230
+ - **Contrast**: every text token (`ink`, `muted`, `soft`, `link`, and `accent`) must clear 4.5:1 on `paper`, in both skins. See the [contrast contract](#contrast-contract); `scripts/verify-contrast.py` checks it.
231
+ - **One accent**: pick one color for `accent`. Two accents erases the focal signal.
232
+ - **No rainbow palette**: if your brand ships 8 colors, pick 3 (paper, ink, accent). The rest become `muted` variants.
233
+ - **Serif + sans + mono**: three families, not more. If brand typography is all sans, keep Instrument Serif for `title` and `callout` anyway — the contrast is load-bearing.
234
+ - **Paper is warm-neutral, not pure white**: pure white turns the design sterile. Pick a cream, bone, or light grey with a hint of warmth.
235
+ - **Dot pattern is optional, not default**: the 22×22 dot pattern is an opt-in "dotted paper" variant (good for long-form editorial hero diagrams). The default background is a clean `paper` fill, no pattern. When the pattern is enabled, it should sit at ~10% opacity of `ink` on `paper` — visible but quiet.
236
+ - **Container is clean by default**: the diagram sits directly on the page paper, no secondary container background or border. A framed variant (`paper-2` bg + `rule` border + 8px radius + padding) is available as an opt-in for card-heavy layouts, but don't reach for it by default — the extra chrome fights the figure.
@@ -0,0 +1,148 @@
1
+ # Vivid White —— 本项目有效皮肤(覆盖 style-guide.md 的出厂默认)
2
+
3
+ > 本文件由 `scripts/sync-diagram-skill.mjs` 注入到 `.agents/skills/diagram-design/references/style-vivid.md`。
4
+ > 改皮肤改这里,不要直接改 skill 目录(同步会被覆盖)。
5
+ >
6
+ > **它优先于 `style-guide.md` 的默认 token。** 两者冲突时以本文件为准;
7
+ > 出厂默认的米白纸(`#f5f5f5`)、近黑墨(`#2d3142`)、单一珊瑚 accent(`#bf4520`)在本项目**一律不用**。
8
+
9
+ ## 0. 一句话方向
10
+
11
+ **纯白纸面 + 粗黑骨架 + 五个高饱和语义色 + 白色线性图标。**
12
+
13
+ 像一张印在铜版纸上的信息图:底色是亮的,边框是硬的,颜色是敢用的,但每个颜色都有明确归属。
14
+ 不是莫兰迪、不是暗色仪表盘、不是灰阶为主只点一抹珊瑚。
15
+
16
+ 三条不可让:
17
+
18
+ 1. **纯白**:页面与图面 `#ffffff`,不许米白、象牙、纸纹、渐变底。
19
+ 2. **高对比**:正文墨色 `#0b0b0f`(19.64:1),任何文字/图标对底色 ≥ 4.5:1。
20
+ 3. **图标区分**:每个语义节点(状态、阶段、角色、存储)必须有一个线性图标,不靠纯文字。
21
+
22
+ ## 1. 纸面与墨色
23
+
24
+ | Role | Hex | 白底对比 | 用途 |
25
+ |---|---|---|---|
26
+ | `paper` | `#ffffff` | — | 页面与图面底色,唯一背景 |
27
+ | `panel` | `#f4f4f5` | 1.10:1 | 只给「证据面板 / 数据带」这类二层容器,必须配 2px `ink` 实线边框 |
28
+ | `ink` | `#0b0b0f` | 19.64:1 | 主文字、主描边、卡片边框 |
29
+ | `muted` | `#3f3f46` | 10.44:1 | 说明文字、次要标签 |
30
+ | `soft` | `#52525b` | 7.73:1 | 出处、图例小字、刻度 |
31
+ | `rule` | `#e4e4e7` | 1.27:1 | 卡内分隔线、刻度基线(仅装饰,不承载语义) |
32
+
33
+ - 背景是**一整块白**。不要给整张图套灰底容器,不要点阵纹理。
34
+ - 分层靠**边框与色带**,不靠阴影深浅。
35
+
36
+ ## 2. 语义色板(一个色相只归属一个语义)
37
+
38
+ | Token | Hex | 白底对比 | 语义(本项目) |
39
+ |---|---|---|---|
40
+ | `state-todo` | `#334155` | 10.35:1 | todo / 待办 / 未开始 |
41
+ | `state-red` | `#be123c` | 6.29:1 | red / 失败 / 缺陷 / 阻断 |
42
+ | `state-green` | `#047857` | 5.48:1 | green / 通过 / 正常 |
43
+ | `state-refactor` | `#b45309` | 5.02:1 | refactored / 重构 / 打磨 |
44
+ | `state-done` | `#6d28d9` | 7.10:1 | done / 交付 / 焦点结论 |
45
+ | `link` | `#1d4ed8` | 6.70:1 | 旁路、外部调用、类型例外 |
46
+
47
+ 规则:
48
+
49
+ - **色相预算 5**(+ `link` 例外)。第 6 个颜色不是设计,是噪音。
50
+ - **一个色相只解释一件事**:`#be123c` 在这张图里永远是 red,下一张图里也还是「失败」。同一份数据里换色 = 读者白学一遍。
51
+ - 色块可以铺满(图标底、色带、进度段),但**彩色文字一律用上表的深色值**,不要用亮粉/亮绿那类 3:1 的糖果色。
52
+ - 反白图标/文字放在语义色实底上,对比度与上表一致(≥ 4.5:1)。
53
+ - 中性色不抢戏:结构、次要说明用 `ink` / `muted` / `soft`,不额外引入第 6 种灰蓝。
54
+
55
+ ## 3. 结构语法
56
+
57
+ | 元素 | 做法 |
58
+ |---|---|
59
+ | 节点卡 | 白底 + **2px `ink` 描边** + `rx=10`;顶部一条 **8px 高的语义色带**(沿卡宽,上两角圆角) |
60
+ | 硬投影 | 卡片背后偏移 `6px,6px` 的同色块(语义色 20% 与白混合后的实色,**0 模糊**)。这是唯一允许的「阴影」,禁止高斯模糊光晕 |
61
+ | 序号 | 右上角大号等宽数字 `01`–`05`,语义色实色,24–30px 700 |
62
+ | 图标徽章 | 左上角 40–44px 圆角方块,语义色实底 + 白色线性图标(`stroke=#ffffff`, `stroke-width=2.2`) |
63
+ | 主标题 | 页面 `h1` 28–34px,`ink`,700;左侧 8px 语义色竖条或下方 4px 色带做锚 |
64
+ | 数据带 | `panel` 底 + 2px `ink` 边 + 4px 顶部多色条;每列左侧 4px 竖色条对应语义 |
65
+ | 连接线 | 2.4px,颜色 = **目标状态**的语义色;箭头 marker 与之同色;旁路用 `link` 虚线 `6,5` |
66
+ | 进度轨 | 一条 10px 高的横向色带,按状态切成 4px 白缝的分段,每段一个语义色 |
67
+ | 图例 | 底部横条,白底无框;每项:色块/线型 + 12px `muted` 文字,绝不浮在图中间 |
68
+
69
+ 几何仍守 4px 网格;`rx` 允许 4 / 6 / 10,不用胶囊(`rx≥999`)当标签。
70
+
71
+ ## 4. 图标(必须)
72
+
73
+ - **每个语义节点一个图标**,取 Tabler Icons 的线性款(MIT),`24×24`、`stroke-width` 2–2.2、`stroke-linecap/linejoin=round`,内联进 SVG。
74
+ - 图标一律 `aria-hidden="true"`,不参与无障碍树;页面上唯一可访问的 `<svg>` 是整张图。
75
+ - 不用 emoji、不用字体图标、不引 `icons.html` 或远程 SVG。
76
+ - 状态机常用搭配:`clipboard-list`(待办)、`bug`(失败)、`circle-check`(通过)、`adjustments`(重构)、`trophy`(交付)。
77
+ - 图标与颜色**同时**编码语义:色盲读者看形状,正常读者看颜色。只靠颜色区分是失败。
78
+
79
+ ## 5. 字体
80
+
81
+ | Role | 中文 / 通用 | 尺寸 | 字重 |
82
+ |---|---|---|---|
83
+ | `title` | `PingFang SC` / `Noto Sans SC` / system-ui | 28–34px | 700 |
84
+ | `eyebrow` | `ui-monospace` + 中文字体回退 | 10–11px,字距 0.18em,大写 | 600 |
85
+ | `node-name` | 等宽(状态 id / 字段名) | 14–15px | 700 |
86
+ | `body` | `PingFang SC` / `Noto Sans SC` / system-ui | 12px(下限) | 400–500 |
87
+ | `label` | `PingFang SC` / system-ui | 12px | 600–700 |
88
+
89
+ - **中文不小于 12px**,8px 的中文在截图里就是灰块。
90
+ - 等宽只给 id、命令、字段名、状态码;中文说明一律无衬线。
91
+ - 不引 Google Fonts(中文用系统字体,离线也能看);纯白底 + 系统字体已经够锐。
92
+
93
+ ## 6. 复杂度
94
+
95
+ - 节点 ≤ 9,连线 ≤ 12,图标徽章 ≤ 9。
96
+ - 「焦点」不再靠单一 accent,而靠**色相归属 + 尺寸差**:结论节点可以更大、更粗,不必再借第 6 种颜色。
97
+ - 超过预算就拆两张:一张主流程,一张证据/明细。
98
+
99
+ ## 7. 禁止项(与出厂皮肤的差异点)
100
+
101
+ | 禁止 | 原因 |
102
+ |---|---|
103
+ | 米白 / 象牙 / 纸纹 / 暗色底 | 用户明确要纯白;杂底会把饱和色拉脏 |
104
+ | 只点一抹珊瑚,其余全灰 | 那是编辑风,不是本项目要的张扬 |
105
+ | 彩色小字用糖果色(`#16a34a`、`#f43f5e`) | 白底过不了 4.5:1 |
106
+ | 高斯模糊阴影 / 发光 / 玻璃拟态 | 廉价;硬投影才配得上粗边框 |
107
+ | 纯文字节点(没有图标) | 五个状态会长得一模一样 |
108
+ | 同一色相承担两种语义 | 读者无法建立颜色记忆 |
109
+ | emoji 当图标 | 平台字体不同,跨端会崩 |
110
+
111
+ ## 8. 可直接套用的片段
112
+
113
+ 卡片(含色带、硬投影、图标徽章):
114
+
115
+ ```svg
116
+ <!-- 硬投影:语义色 20% 与白混合后的实色,偏移 6px,无模糊 -->
117
+ <rect x="46" y="222" width="180" height="168" rx="10" fill="#f2e4e7"/>
118
+ <!-- 卡体 -->
119
+ <rect x="40" y="216" width="180" height="168" rx="10" fill="#ffffff" stroke="#0b0b0f" stroke-width="2"/>
120
+ <!-- 顶部色带(上两角圆角,下边直角) -->
121
+ <path d="M40 226 a10 10 0 0 1 10 -10 h160 a10 10 0 0 1 10 10 v8 h-180 z" fill="#be123c"/>
122
+ <!-- 图标徽章 -->
123
+ <rect x="56" y="244" width="44" height="44" rx="12" fill="#be123c"/>
124
+ <g transform="translate(66 254)" fill="none" stroke="#ffffff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round">
125
+ <svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">
126
+ <path d="M9 7a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v1h3v12h-12v-12h3z"/>
127
+ </svg>
128
+ </g>
129
+ ```
130
+
131
+ 连接线(颜色跟目标状态,标签必须有白底遮罩):
132
+
133
+ ```svg
134
+ <line x1="220" y1="300" x2="292" y2="300" stroke="#be123c" stroke-width="2.4" marker-end="url(#arrow-red)"/>
135
+ <rect x="228" y="278" width="56" height="16" fill="#ffffff"/>
136
+ <text x="256" y="290" text-anchor="middle" font-size="12" font-weight="600" fill="#be123c">先红</text>
137
+ ```
138
+
139
+ ## 9. 自检(画完逐条过)
140
+
141
+ - [ ] 底色是 `#ffffff`,没有第二层灰底盖住全图?
142
+ - [ ] 五个语义色都在规范里、各自只解释一件事?
143
+ - [ ] 每个状态/阶段卡有图标,且图标 `aria-hidden="true"`?
144
+ - [ ] 所有文字对白底 ≥ 4.5:1(彩色文字用深色值)?
145
+ - [ ] 卡片是 2px 硬边 + 硬投影,没有模糊阴影?
146
+ - [ ] 连接线是正交折线或同行直线,标签有白底遮罩且不压在线上?
147
+ - [ ] 图例在底部横条,没有飘在图中间?
148
+ - [ ] `node tools/diagram-lint.mjs <file>` 通过?
@@ -0,0 +1,143 @@
1
+ # Architecture delta
2
+
3
+ **Best for:** explaining a system migration, service extraction, infrastructure redesign, or integration change through two synchronized topology snapshots. Show which components and relationships survive, appear, disappear, change their properties, move, or reconnect.
4
+
5
+ **Not this type:**
6
+
7
+ - One system snapshot → **Architecture** (`type-architecture.md`).
8
+ - Attribute-only differences without a topology story → a **comparison table**. Two versions of a configuration do not need two node maps.
9
+ - Requests over time → **Sequence** (`type-sequence.md`); deployment phases → **Timeline** (`type-timeline.md`). A delta has exactly two states and does not establish migration order, downtime, or causality.
10
+ - Host/container placement in one environment → **Deployment** (`type-deployment.md`).
11
+
12
+ ## Layout conventions
13
+
14
+ - **Three panels, one reading order: Before · Changes · After.** Both topology panels use the same width, height, and internal grid pitch. The center panel is a short change ledger, not a third topology. Name the two snapshots with meaningful versions or dates.
15
+ - **Keep the mental map stable.** Start by copying the Before coordinates into After. Move a retained component only when its movement is part of the story and receives a `MOVED` entry. Do not independently run a layout algorithm on each panel.
16
+ - **Panel positions are not component positions.** Put each snapshot in one SVG `<g transform="translate(x y)">`; write component bounds and relationship paths in local coordinates. The Before and After origins share one y-coordinate, with the ledger occupying the horizontal gap.
17
+ - **Shared grid:** use a 4px pitch by default. Every component's local x, y, width, and height is a multiple of that pitch. The shipped example uses two `336 480 4` grids; scale the overall SVG responsively without changing their local geometry.
18
+ - **Budget:** at most **8 unique components**, **10 unique relationships**, and **8 ledger entries** across the complete comparison. A retained ID counts once, not once per snapshot. A component that is both changed and moved consumes two ledger entries. Split larger migrations into named subsystems or phases; never drop edges to fit.
19
+ - **Connectors:** use Architecture's rounded orthogonal routing and port rules. In this type, even straight connectors are `<path>` elements so relationship identity and endpoints have one grammar. Draw paths before components. A stable relationship may take a different route to meet a moved component without becoming `REWIRED`.
20
+ - **Nodes:** print the same stable ID in both states along with the human-readable name. Treat names, responsibilities, implementation versions, and protocols as semantic attributes; identities survive a rename when the underlying object survives.
21
+ - **Ledger:** one brief entry per `(object ID, change)` pair. Begin with the uppercase change word, name the object, and state the actual difference. Do not describe unchanged objects in the ledger. Keep a readable text measure, with wrapped `<tspan>` lines when needed.
22
+ - **Responsive presentation:** preserve the three-panel comparison on small screens with an accessible horizontal scroll region and a visible scroll hint. Do not compress labels until they become illegible or stack snapshots into independently scaled pictures. Print and export keep the whole comparison.
23
+
24
+ ## Change vocabulary and redundant encoding
25
+
26
+ Color is secondary. Every change is readable from text plus a shape or line treatment; unchanged objects remain quiet context. Use the existing skin tokens and reserve the accent for the editorial focus, rather than assigning five status colors.
27
+
28
+ | State | Meaning | Non-color treatment |
29
+ |---|---|---|
30
+ | `unchanged` | Same identity, semantics, position, and endpoints | Plain solid outline; no ledger entry |
31
+ | `added` / **ADDED** | Present only in After | `+` badge or plus-shaped marker; solid outline |
32
+ | `removed` / **REMOVED** | Present only in Before | `−` badge and dashed outline/path |
33
+ | `changed` / **CHANGED** | Retained object whose semantic signature differs | `Δ` badge or inset rule, plus an explicit old → new ledger description |
34
+ | `moved` / **MOVED** | Retained component whose local x or y differs | Direction/position marker and a ledger entry naming the relocation |
35
+ | `rewired` / **REWIRED** | Retained relationship whose ordered source/target IDs differ | Distinct dash treatment or endpoint marker, with old → new endpoints written in the ledger |
36
+
37
+ Do not use a missing After node to stand for a removal without a `REMOVED` entry. Do not substitute an `ADDED` edge for a `REWIRED` edge just to avoid explaining endpoint identity. A replacement component gets a new stable ID and separate removal/addition entries; its location alone cannot establish continuity.
38
+
39
+ ## Public HTML metadata contract
40
+
41
+ This is the authoring and validation surface, not a serialization inferred from visible labels. All attributes below are required where applicable; empty, boolean, duplicate, or malformed declarations are findings. IDs are case-sensitive and match `[A-Za-z][A-Za-z0-9_.:-]*`; they contain no whitespace.
42
+
43
+ ### Diagram and snapshots
44
+
45
+ The file has exactly one `<svg data-diagram="architecture-delta">`. Keep the standard accessible SVG title/description contract. Two direct child `<g>` elements declare `data-snapshot="before"` and `data-snapshot="after"`. Each has:
46
+
47
+ - `data-grid="<width> <height> <pitch>"`: the same three positive finite numbers in both panels. Width and height are multiples of pitch.
48
+ - `transform="translate(<x> <y>)"`: exactly one finite two-number translation, solely for the panel origin. Comma-separated translations are also accepted.
49
+
50
+ Snapshot membership is inherited from the enclosing group. An object cannot be outside both snapshots, in nested snapshots, or nested inside another object. Other geometry transforms, nested SVG viewports, SVG animation, `<use>`, and foreign objects are outside this static grammar. Do not put objects or ledger entries in `<defs>`, `<symbol>`, templates, or other nonrendering containers.
51
+
52
+ ### Components
53
+
54
+ Each component is a `<g>` declaring:
55
+
56
+ | Attribute | Contract |
57
+ |---|---|
58
+ | `data-kind="component"` | Identifies a component group |
59
+ | `data-object-id` | Stable object identity, unique within each snapshot |
60
+ | `data-status` | One lowercase state or the space-separated combination `changed moved` |
61
+ | `data-signature` | Nonempty semantic signature; see the signature rules below |
62
+
63
+ The group contains exactly one **direct** `<rect data-role="bounds">` with explicit finite numeric `x`, `y`, `width`, and `height`. Position is nonnegative, size is positive, and the rectangle stays inside its local grid. All four values align with grid pitch. These are the actual drawn node bounds, not a hidden proxy rectangle.
64
+
65
+ ### Relationships
66
+
67
+ Each relationship is a `<path>` with `data-kind="relationship"`, `data-object-id`, `data-status`, `data-signature`, and `data-from` / `data-to`. Its stable ID is separate from component IDs. Both endpoints resolve to component IDs in the **same snapshot**. Endpoint order is directional: swapping source and target is a rewire.
68
+
69
+ Every path inside a snapshot and outside a component is a relationship and must carry the complete metadata. Decorative paths belong inside their component, or outside the snapshot for panel rules and ledger separators. Deleting all metadata from a connector must not make it disappear from validation.
70
+
71
+ Relationship statuses are `unchanged`, `added`, `removed`, `changed`, `rewired`, or the combination `changed rewired`. `moved` applies to components only; `rewired` applies to relationships only. `unchanged`, `added`, and `removed` cannot be combined with any other token.
72
+
73
+ The `d` attribute is one absolute `M` followed by absolute `L`, `H`, `V`, `Q`, or `C` segments. Implicit repeated coordinate groups are accepted. Relative commands, additional subpaths, closed paths, arcs, missing coordinates, and non-finite coordinates fail closed. Use orthogonal lines and quadratic corners for the standard layout; cubic segments are available for a small crossing bridge. Endpoints and control points remain inside the local grid. The path's start meets the source rectangle's perimeter and its end meets the target's perimeter, within 2px for stroke/arrow-cap rounding.
74
+
75
+ ### Status and signature rules
76
+
77
+ - An ID present only in Before is exactly `removed`; an ID present only in After is exactly `added`.
78
+ - A retained ID keeps its kind and the same status set in both snapshots. Never recycle a component ID for a relationship or vice versa.
79
+ - A signature differs **if and only if** the retained object is `changed`. Construct it deterministically from the semantic attributes you want to compare, such as `orders-api:v2;mode=enqueue` or `protocol=https;operation=create-order`. Include a changed display name if renaming is part of the story. Preserve attribute order and spelling when values are unchanged.
80
+ - Signatures exclude the object ID, snapshot, status, coordinates, visual styles, and relationship endpoints. These have their own checks. A movement or rewire alone must not change the signature.
81
+ - A retained component's local `(x,y)` differs **if and only if** it is `moved`. A width/height change additionally requires `changed` and a changed signature. A changed signature alone does not require different bounds.
82
+ - A retained relationship's ordered `(data-from,data-to)` pair differs **if and only if** it is `rewired`. Its path may reroute while that pair stays the same, for example when an endpoint component moves.
83
+ - Numeric declarations are finite and have absolute values no larger than 10,000,000; unit suffixes, percentages, and CSS calculations are not coordinate declarations.
84
+
85
+ ### Ledger
86
+
87
+ Each entry is a visible SVG `<text>` outside both snapshots, with `data-change="ADDED|REMOVED|CHANGED|MOVED|REWIRED"` and `data-target="<one object ID>"`. Its rendered text begins with the same uppercase word and continues with an explanation. Descendant `<tspan>` text is included when checking the wording; put the metadata on the outer `<text>` only.
88
+
89
+ The ledger is an exact set of `(target, change)` pairs implied by object statuses. There are no missing entries, duplicate pairs, unknown targets, or entries for unchanged objects. The same target can have two entries only when it declares two changes. Every diagram contains at least one ledger entry, at least one component in each snapshot, and at least one relationship overall.
90
+
91
+ ### Worked metadata pattern
92
+
93
+ This excerpt shows one changed component; a complete diagram also needs its other components, relationships, and accessible SVG title/description.
94
+
95
+ ```svg
96
+ <svg data-diagram="architecture-delta" viewBox="0 0 1000 400">
97
+ <g data-snapshot="before" data-grid="320 320 4" transform="translate(24 64)">
98
+ <g data-kind="component" data-object-id="orders" data-status="changed"
99
+ data-signature="orders-api:v1;mode=dispatch">
100
+ <rect data-role="bounds" x="80" y="96" width="144" height="64"/>
101
+ <text x="96" y="120">orders · direct dispatch</text>
102
+ </g>
103
+ </g>
104
+ <g data-snapshot="after" data-grid="320 320 4" transform="translate(656 64)">
105
+ <g data-kind="component" data-object-id="orders" data-status="changed"
106
+ data-signature="orders-api:v2;mode=enqueue">
107
+ <rect data-role="bounds" x="80" y="96" width="144" height="64"/>
108
+ <text x="96" y="120">orders · enqueue</text>
109
+ </g>
110
+ </g>
111
+ <text data-change="CHANGED" data-target="orders" x="376" y="176">
112
+ <tspan>CHANGED orders</tspan>
113
+ <tspan x="376" dy="20">Direct dispatch → enqueue</tspan>
114
+ </text>
115
+ </svg>
116
+ ```
117
+
118
+ ## Verification and its boundaries
119
+
120
+ Run `(仓库级脚本未随包分发:越界与动画契约以 node tools/diagram-lint.mjs 为准)
121
+
122
+ The verifier enforces the declared structure, differential semantics, grid/bounds geometry, drawn relationship endpoints, budgets, and exact ledger coverage. It rejects CSS transforms/position overrides, CSS sizing that could change bounds, escaped CSS declarations, explicit hidden objects/ledger, and common CSS hiding rules. Ordinary responsive sizing of the outer SVG remains legal.
123
+
124
+ It is **not** a browser renderer or a proof of the source system. Authors remain responsible for honest signatures, labels matching those signatures, readable shape/dash treatments, and an accurate migration story. Exotic CSS cascade/variable effects, clipping and occlusion, connector crossings, intermediate segment clearance, ledger placement, and screen-reader quality still require the normal skin, accessibility, geometry, and rendered-layout gates plus desktop/mobile visual review. Keep semantic geometry in the SVG attributes instead of making CSS part of the data model.
125
+
126
+ ## Anti-patterns
127
+
128
+ - Two independently arranged snapshots that manufacture apparent movement.
129
+ - A center ledger that says only “updated” without naming the object and difference.
130
+ - Color-only statuses or a separate bright color for every kind of change.
131
+ - Unchanged node positions drifting to make room, with no `MOVED` entry.
132
+ - Semantic edits hidden behind an unchanged signature, or all signatures regenerated just because the snapshot changed.
133
+ - Redrawing an edge to a different component while keeping its endpoint metadata unchanged.
134
+ - Counting retained objects twice to justify dropping other objects from the comparison.
135
+ - Treating this comparison as an executable migration plan. Ordering, rollback, availability, and data consistency need their own explanation.
136
+
137
+ ## Examples
138
+
139
+ - `assets/example-architecture-delta.html` — minimal light order-fulfilment migration; all five change kinds.
140
+ - `assets/example-architecture-delta-dark.html` — minimal dark, identical IDs, signatures, topology, and coordinates.
141
+ - `assets/example-architecture-delta-full.html` — full editorial treatment of the same migration.
142
+
143
+ The example retains the storefront and order store, changes the order API to enqueue work, removes the legacy dispatcher, adds a durable order queue, moves the fulfilment worker, and rewires order submission. Stable relationships follow the worker's new location while preserving their IDs and endpoint semantics.