scrum-skills 0.3.2 → 0.3.4
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.
- package/.agents/skills/diagram-design/LICENSE +4 -0
- package/.agents/skills/diagram-design/SKILL.md +423 -0
- package/.agents/skills/diagram-design/UPSTREAM.json +88 -0
- package/.agents/skills/diagram-design/UPSTREAM.md +23 -0
- package/.agents/skills/diagram-design/assets/example-architecture-containment.html +205 -0
- package/.agents/skills/diagram-design/assets/example-architecture-delta.html +193 -0
- package/.agents/skills/diagram-design/assets/example-architecture.html +183 -0
- package/.agents/skills/diagram-design/assets/example-axonometric-plan-campus.html +108 -0
- package/.agents/skills/diagram-design/assets/example-axonometric-plan-coffee-shop.html +121 -0
- package/.agents/skills/diagram-design/assets/example-axonometric-plan-warehouse.html +127 -0
- package/.agents/skills/diagram-design/assets/example-axonometric-plan.html +114 -0
- package/.agents/skills/diagram-design/assets/example-bar.html +129 -0
- package/.agents/skills/diagram-design/assets/example-beeswarm.html +384 -0
- package/.agents/skills/diagram-design/assets/example-box-plot.html +127 -0
- package/.agents/skills/diagram-design/assets/example-bubble.html +147 -0
- package/.agents/skills/diagram-design/assets/example-bump.html +142 -0
- package/.agents/skills/diagram-design/assets/example-data-flow.html +143 -0
- package/.agents/skills/diagram-design/assets/example-datalake.html +269 -0
- package/.agents/skills/diagram-design/assets/example-db-schema.html +302 -0
- package/.agents/skills/diagram-design/assets/example-dependency.html +224 -0
- package/.agents/skills/diagram-design/assets/example-deployment.html +190 -0
- package/.agents/skills/diagram-design/assets/example-dp-integration.html +81 -0
- package/.agents/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
- package/.agents/skills/diagram-design/assets/example-er.html +202 -0
- package/.agents/skills/diagram-design/assets/example-exploded-ai-stack.html +85 -0
- package/.agents/skills/diagram-design/assets/example-exploded-keyboard.html +84 -0
- package/.agents/skills/diagram-design/assets/example-exploded-phone.html +83 -0
- package/.agents/skills/diagram-design/assets/example-exploded-unboxing.html +84 -0
- package/.agents/skills/diagram-design/assets/example-exploded.html +83 -0
- package/.agents/skills/diagram-design/assets/example-fishbone.html +152 -0
- package/.agents/skills/diagram-design/assets/example-flowchart.html +163 -0
- package/.agents/skills/diagram-design/assets/example-gantt.html +137 -0
- package/.agents/skills/diagram-design/assets/example-heatmap.html +224 -0
- package/.agents/skills/diagram-design/assets/example-high-level-vertical.html +325 -0
- package/.agents/skills/diagram-design/assets/example-high-level.html +301 -0
- package/.agents/skills/diagram-design/assets/example-import-drawio.html +185 -0
- package/.agents/skills/diagram-design/assets/example-import-excalidraw.html +70 -0
- package/.agents/skills/diagram-design/assets/example-import-mermaid.html +70 -0
- package/.agents/skills/diagram-design/assets/example-it-state.html +128 -0
- package/.agents/skills/diagram-design/assets/example-journey.html +148 -0
- package/.agents/skills/diagram-design/assets/example-kanban.html +174 -0
- package/.agents/skills/diagram-design/assets/example-layers.html +123 -0
- package/.agents/skills/diagram-design/assets/example-line.html +111 -0
- package/.agents/skills/diagram-design/assets/example-loop.html +100 -0
- package/.agents/skills/diagram-design/assets/example-marimekko.html +148 -0
- package/.agents/skills/diagram-design/assets/example-medallion.html +159 -0
- package/.agents/skills/diagram-design/assets/example-nested.html +136 -0
- package/.agents/skills/diagram-design/assets/example-org-chart.html +45 -0
- package/.agents/skills/diagram-design/assets/example-polar.html +116 -0
- package/.agents/skills/diagram-design/assets/example-process.html +64 -0
- package/.agents/skills/diagram-design/assets/example-pyramid.html +119 -0
- package/.agents/skills/diagram-design/assets/example-quadrant-consultant.html +166 -0
- package/.agents/skills/diagram-design/assets/example-quadrant.html +135 -0
- package/.agents/skills/diagram-design/assets/example-radar.html +139 -0
- package/.agents/skills/diagram-design/assets/example-ridgeline.html +104 -0
- package/.agents/skills/diagram-design/assets/example-sankey.html +150 -0
- package/.agents/skills/diagram-design/assets/example-scatter.html +141 -0
- package/.agents/skills/diagram-design/assets/example-sequence-oauth.html +227 -0
- package/.agents/skills/diagram-design/assets/example-sequence.html +222 -0
- package/.agents/skills/diagram-design/assets/example-service-blueprint.html +185 -0
- package/.agents/skills/diagram-design/assets/example-slopegraph.html +119 -0
- package/.agents/skills/diagram-design/assets/example-state-lifecycle.html +92 -0
- package/.agents/skills/diagram-design/assets/example-state.html +147 -0
- package/.agents/skills/diagram-design/assets/example-story-map.html +184 -0
- package/.agents/skills/diagram-design/assets/example-streamgraph.html +99 -0
- package/.agents/skills/diagram-design/assets/example-swimlane.html +172 -0
- package/.agents/skills/diagram-design/assets/example-timeline.html +135 -0
- package/.agents/skills/diagram-design/assets/example-tree-block-decomposition.html +151 -0
- package/.agents/skills/diagram-design/assets/example-tree.html +173 -0
- package/.agents/skills/diagram-design/assets/example-treemap.html +107 -0
- package/.agents/skills/diagram-design/assets/example-uml-class.html +188 -0
- package/.agents/skills/diagram-design/assets/example-venn.html +110 -0
- package/.agents/skills/diagram-design/assets/example-wardley.html +153 -0
- package/.agents/skills/diagram-design/assets/example-waterfall.html +129 -0
- package/.agents/skills/diagram-design/assets/template-dark.html +99 -0
- package/.agents/skills/diagram-design/assets/template-full.html +421 -0
- package/.agents/skills/diagram-design/assets/template-motion.html +448 -0
- package/.agents/skills/diagram-design/assets/template-terminal.html +188 -0
- package/.agents/skills/diagram-design/assets/template.html +100 -0
- package/.agents/skills/diagram-design/references/animation.md +143 -0
- package/.agents/skills/diagram-design/references/export-registry.md +78 -0
- package/.agents/skills/diagram-design/references/export.md +376 -0
- package/.agents/skills/diagram-design/references/import-drawio.md +181 -0
- package/.agents/skills/diagram-design/references/import-excalidraw.md +130 -0
- package/.agents/skills/diagram-design/references/import-mermaid.md +137 -0
- package/.agents/skills/diagram-design/references/layout-budget.md +97 -0
- package/.agents/skills/diagram-design/references/onboarding.md +368 -0
- package/.agents/skills/diagram-design/references/output-spec.md +277 -0
- package/.agents/skills/diagram-design/references/primitive-annotation.md +36 -0
- package/.agents/skills/diagram-design/references/primitive-icons.md +827 -0
- package/.agents/skills/diagram-design/references/primitive-sketchy.md +43 -0
- package/.agents/skills/diagram-design/references/primitive-terminal.md +76 -0
- package/.agents/skills/diagram-design/references/primitives-core.md +150 -0
- package/.agents/skills/diagram-design/references/profiles.md +183 -0
- package/.agents/skills/diagram-design/references/semantic-patterns.md +154 -0
- package/.agents/skills/diagram-design/references/style-guide.md +236 -0
- package/.agents/skills/diagram-design/references/style-vivid.md +148 -0
- package/.agents/skills/diagram-design/references/type-architecture-delta.md +143 -0
- package/.agents/skills/diagram-design/references/type-architecture.md +117 -0
- package/.agents/skills/diagram-design/references/type-axonometric-plan.md +83 -0
- package/.agents/skills/diagram-design/references/type-bar.md +108 -0
- package/.agents/skills/diagram-design/references/type-data-flow.md +371 -0
- package/.agents/skills/diagram-design/references/type-db-schema.md +48 -0
- package/.agents/skills/diagram-design/references/type-dependency.md +44 -0
- package/.agents/skills/diagram-design/references/type-deployment.md +45 -0
- package/.agents/skills/diagram-design/references/type-dp-integration.md +407 -0
- package/.agents/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
- package/.agents/skills/diagram-design/references/type-er.md +25 -0
- package/.agents/skills/diagram-design/references/type-exploded.md +115 -0
- package/.agents/skills/diagram-design/references/type-fishbone.md +75 -0
- package/.agents/skills/diagram-design/references/type-flowchart.md +23 -0
- package/.agents/skills/diagram-design/references/type-gantt.md +45 -0
- package/.agents/skills/diagram-design/references/type-heatmap.md +80 -0
- package/.agents/skills/diagram-design/references/type-high-level.md +470 -0
- package/.agents/skills/diagram-design/references/type-it-state.md +468 -0
- package/.agents/skills/diagram-design/references/type-journey.md +55 -0
- package/.agents/skills/diagram-design/references/type-kanban.md +49 -0
- package/.agents/skills/diagram-design/references/type-layers.md +26 -0
- package/.agents/skills/diagram-design/references/type-line.md +337 -0
- package/.agents/skills/diagram-design/references/type-loop.md +223 -0
- package/.agents/skills/diagram-design/references/type-medallion.md +356 -0
- package/.agents/skills/diagram-design/references/type-nested.md +22 -0
- package/.agents/skills/diagram-design/references/type-org-chart.md +44 -0
- package/.agents/skills/diagram-design/references/type-polar.md +136 -0
- package/.agents/skills/diagram-design/references/type-process.md +490 -0
- package/.agents/skills/diagram-design/references/type-pyramid.md +33 -0
- package/.agents/skills/diagram-design/references/type-quadrant.md +81 -0
- package/.agents/skills/diagram-design/references/type-radar.md +82 -0
- package/.agents/skills/diagram-design/references/type-sankey.md +75 -0
- package/.agents/skills/diagram-design/references/type-scatter.md +276 -0
- package/.agents/skills/diagram-design/references/type-sequence.md +130 -0
- package/.agents/skills/diagram-design/references/type-service-blueprint.md +103 -0
- package/.agents/skills/diagram-design/references/type-state.md +30 -0
- package/.agents/skills/diagram-design/references/type-story-map.md +46 -0
- package/.agents/skills/diagram-design/references/type-swimlane.md +22 -0
- package/.agents/skills/diagram-design/references/type-timeline.md +20 -0
- package/.agents/skills/diagram-design/references/type-tree.md +24 -0
- package/.agents/skills/diagram-design/references/type-treemap.md +137 -0
- package/.agents/skills/diagram-design/references/type-uml-class.md +65 -0
- package/.agents/skills/diagram-design/references/type-venn.md +26 -0
- package/.agents/skills/diagram-design/references/type-wardley.md +39 -0
- package/.agents/skills/diagram-design/references/type-waterfall.md +75 -0
- package/.agents/skills/scrum-meta/SKILL.md +36 -36
- package/.agents/skills/scrum-planning/SKILL.md +61 -61
- package/.agents/skills/scrum-planning/references/schema.md +384 -336
- package/.agents/skills/scrum-report/SKILL.md +42 -42
- package/.agents/skills/scrum-sprint/SKILL.md +49 -49
- package/.agents/skills/scrum-tdd/SKILL.md +140 -127
- package/README.md +24 -1
- package/assets/board/200.html +1 -1
- package/assets/board/404.html +1 -1
- package/assets/board/_nuxt/4gQF_HS3.js +1 -0
- package/assets/board/_nuxt/5okfNy5D.js +1 -0
- package/assets/board/_nuxt/{Bb3Limos.js → B0C2jsdk.js} +1 -1
- package/assets/board/_nuxt/B1j6UC4U.js +1 -0
- package/assets/board/_nuxt/B3LKy6o2.js +1 -0
- package/assets/board/_nuxt/BAQQngAq.js +13 -0
- package/assets/board/_nuxt/BE6t7Q2m.js +1 -0
- package/assets/board/_nuxt/BGwhkDRl.js +1 -0
- package/assets/board/_nuxt/BLvbupFS.js +1 -0
- package/assets/board/_nuxt/BQgzP7ur.js +1 -0
- package/assets/board/_nuxt/BRZIF_wo.js +1 -0
- package/assets/board/_nuxt/BU8vdZUs.js +95 -0
- package/assets/board/_nuxt/BW3xJdEx.js +1 -0
- package/assets/board/_nuxt/{Cm9lkUvP.js → BY36DFyj.js} +1 -1
- package/assets/board/_nuxt/BZlZD94i.js +1 -0
- package/assets/board/_nuxt/BZvXNwev.js +3 -0
- package/assets/board/_nuxt/BiWrMOsL.js +1 -0
- package/assets/board/_nuxt/BkoKCNUY.js +1 -0
- package/assets/board/_nuxt/BlKmZhhF.js +1 -0
- package/assets/board/_nuxt/BmBpmU73.js +1 -0
- package/assets/board/_nuxt/BmrSh0rL.js +1 -0
- package/assets/board/_nuxt/BrWE0up6.js +1 -0
- package/assets/board/_nuxt/Bs52qkgk.js +1 -0
- package/assets/board/_nuxt/BuBzMkFZ.js +1 -0
- package/assets/board/_nuxt/Bubk0xn-.js +1 -0
- package/assets/board/_nuxt/BxuBMtk_.js +3 -0
- package/assets/board/_nuxt/By1KXXLR.js +1 -0
- package/assets/board/_nuxt/BygIGL69.js +2 -0
- package/assets/board/_nuxt/C-fx-vFO.js +1 -0
- package/assets/board/_nuxt/C1iO5KH3.js +1 -0
- package/assets/board/_nuxt/C2YPmTzt.js +1 -0
- package/assets/board/_nuxt/C3SpAhCW.js +1 -0
- package/assets/board/_nuxt/C3ZRWz5L.js +1 -0
- package/assets/board/_nuxt/C4WdPP6K.js +1 -0
- package/assets/board/_nuxt/C6o03JHe.js +1 -0
- package/assets/board/_nuxt/C8qB5llI.js +1 -0
- package/assets/board/_nuxt/C9MgRdhu.js +1 -0
- package/assets/board/_nuxt/CCA81-4P.js +1 -0
- package/assets/board/_nuxt/{D2O8Q8x9.js → CFCM18fF.js} +1 -1
- package/assets/board/_nuxt/CGXljzd_.js +1 -0
- package/assets/board/_nuxt/CI0scS-N.js +1 -0
- package/assets/board/_nuxt/CJs9B42o.js +1 -0
- package/assets/board/_nuxt/COmtTtfB.js +1 -0
- package/assets/board/_nuxt/CPYm4J_K.js +1 -0
- package/assets/board/_nuxt/CXG7GZes.js +1 -0
- package/assets/board/_nuxt/CYGiZn-X.js +1 -0
- package/assets/board/_nuxt/CaE8VlUp.js +1 -0
- package/assets/board/_nuxt/Cajxc4Dw.js +1 -0
- package/assets/board/_nuxt/CcGiNUgA.js +1 -0
- package/assets/board/_nuxt/Ccgv3lDj.js +1 -0
- package/assets/board/_nuxt/CdPGFZyy.js +1 -0
- package/assets/board/_nuxt/{DfR3IZN_.js → Cdf_T8Xa.js} +1 -1
- package/assets/board/_nuxt/CgQ30j_6.js +1 -0
- package/assets/board/_nuxt/Ck0-FqVI.js +1 -0
- package/assets/board/_nuxt/CkWKLtjO.js +1 -0
- package/assets/board/_nuxt/CoipdpDu.js +1 -0
- package/assets/board/_nuxt/Cq7hsCKB.js +1 -0
- package/assets/board/_nuxt/D166WVUG.js +1 -0
- package/assets/board/_nuxt/D1V1gysQ.js +1 -0
- package/assets/board/_nuxt/D4Dpzo9e.js +1 -0
- package/assets/board/_nuxt/D5i92OZO.js +1 -0
- package/assets/board/_nuxt/D6dUp4Nm.js +9 -0
- package/assets/board/_nuxt/DFQDFspC.js +1 -0
- package/assets/board/_nuxt/DHX2tw9J.js +1 -0
- package/assets/board/_nuxt/DJM7u8P3.js +1 -0
- package/assets/board/_nuxt/{BPTrRhcw.js → DLr85ebo.js} +1 -1
- package/assets/board/_nuxt/DOMM1wfl.js +1 -0
- package/assets/board/_nuxt/DU6ArlUN.js +1 -0
- package/assets/board/_nuxt/{B_SlFcWp.js → DUgGsde6.js} +1 -1
- package/assets/board/_nuxt/DV4ti-Pq.js +1 -0
- package/assets/board/_nuxt/D_ct-Stz.js +2 -0
- package/assets/board/_nuxt/DbWAComO.js +1 -0
- package/assets/board/_nuxt/DbwlcHAt.js +1 -0
- package/assets/board/_nuxt/Dki9VkAL.js +3 -0
- package/assets/board/_nuxt/DlNJhOoc.js +1 -0
- package/assets/board/_nuxt/Dmg78zOY.js +3 -0
- package/assets/board/_nuxt/DqG7CtD4.js +1 -0
- package/assets/board/_nuxt/DqUSsCJ2.js +1 -0
- package/assets/board/_nuxt/Du2F4WXh.js +1 -0
- package/assets/board/_nuxt/DuRiEXn4.js +1 -0
- package/assets/board/_nuxt/DwCE3305.js +1 -0
- package/assets/board/_nuxt/DwzGxoX2.js +1 -0
- package/assets/board/_nuxt/DxBwVNyP.js +2 -0
- package/assets/board/_nuxt/DzmVW5-D.js +1 -0
- package/assets/board/_nuxt/I-sGtDIB.js +6 -0
- package/assets/board/_nuxt/JU9-x68N.js +1 -0
- package/assets/board/_nuxt/Lozm7hhE.js +1 -0
- package/assets/board/_nuxt/MMsTMkcB.js +1 -0
- package/assets/board/_nuxt/MS7CGmCB.js +1 -0
- package/assets/board/_nuxt/OKKaKILz.js +1 -0
- package/assets/board/_nuxt/{Csqgy925.js → P6qlvBHA.js} +1 -1
- package/assets/board/_nuxt/SrNUvNwO.js +1 -0
- package/assets/board/_nuxt/{DSaWoFHS.js → SywdkA98.js} +1 -1
- package/assets/board/_nuxt/TBIRpVLG.js +1 -0
- package/assets/board/_nuxt/TlTrMIMm.js +1 -0
- package/assets/board/_nuxt/Utb4TVOl.js +1 -0
- package/assets/board/_nuxt/Zv9-SOQF.js +1 -0
- package/assets/board/_nuxt/_id_.B6iqDPxe.css +1 -0
- package/assets/board/_nuxt/b7xtxFRl.js +1 -0
- package/assets/board/_nuxt/builds/latest.json +1 -1
- package/assets/board/_nuxt/builds/meta/08bebe14-0f1b-4d2a-8de4-e84e122d10e9.json +1 -0
- package/assets/board/_nuxt/diagrams.pyhqNtmr.css +1 -0
- package/assets/board/_nuxt/{entry.CKHePurH.css → entry.BBv-sBnP.css} +1 -1
- package/assets/board/_nuxt/error-404.CgJNdpB5.css +1 -0
- package/assets/board/_nuxt/error-500.WYSoH44y.css +1 -0
- package/assets/board/_nuxt/jbri6q1p.js +1 -0
- package/assets/board/_nuxt/q_8bxRMt.js +1 -0
- package/assets/board/burndown/index.html +1 -1
- package/assets/board/diagrams/index.html +1 -0
- package/assets/board/epics/index.html +1 -1
- package/assets/board/gantt/index.html +1 -1
- package/assets/board/index.html +1 -1
- package/assets/board/last-change/index.html +1 -1
- package/assets/board/milestones/index.html +1 -1
- package/assets/board/tests/index.html +1 -1
- package/bin/scrum-skills.mjs +13 -0
- package/package.json +2 -1
- package/templates/AGENTS.md +10 -0
- package/tools/diagram-import.mjs +238 -0
- package/tools/diagram-lint.mjs +518 -0
- package/tools/diagram.mjs +299 -0
- package/tools/last-change.mjs +326 -326
- package/tools/projects.mjs +29 -4
- package/tools/serve.mjs +27 -1
- package/tools/validate.mjs +781 -664
- package/assets/board/_nuxt/1eqboJxR.js +0 -1
- package/assets/board/_nuxt/2K7ag6ES.js +0 -1
- package/assets/board/_nuxt/51OWHj8c.js +0 -2
- package/assets/board/_nuxt/6gFtTBwm.js +0 -1
- package/assets/board/_nuxt/B3jkABw9.js +0 -1
- package/assets/board/_nuxt/B5n2_jZN.js +0 -1
- package/assets/board/_nuxt/BDK2Hj7B.js +0 -1
- package/assets/board/_nuxt/BDcnzXHq.js +0 -1
- package/assets/board/_nuxt/BaG8y0Wt.js +0 -1
- package/assets/board/_nuxt/BbwJq5pb.js +0 -1
- package/assets/board/_nuxt/BgLeKwx0.js +0 -1
- package/assets/board/_nuxt/Bi9Axj3V.js +0 -1
- package/assets/board/_nuxt/BmxvtaMq.js +0 -1
- package/assets/board/_nuxt/BodFvto3.js +0 -1
- package/assets/board/_nuxt/BpWeHLuN.js +0 -1
- package/assets/board/_nuxt/BuOKDFiJ.js +0 -1
- package/assets/board/_nuxt/C40iTe-x.js +0 -1
- package/assets/board/_nuxt/C7K0R7F-.js +0 -2
- package/assets/board/_nuxt/C8vL692X.js +0 -1
- package/assets/board/_nuxt/C9StZL3D.js +0 -3
- package/assets/board/_nuxt/CGI_ZV79.js +0 -1
- package/assets/board/_nuxt/CJ2mz0WY.js +0 -1
- package/assets/board/_nuxt/CJMBJQuf.js +0 -1
- package/assets/board/_nuxt/CK-lOYG9.js +0 -1
- package/assets/board/_nuxt/CK9_veoz.js +0 -1
- package/assets/board/_nuxt/CLBcBrYf.js +0 -1
- package/assets/board/_nuxt/CMUi2-Lj.js +0 -1
- package/assets/board/_nuxt/COf6E6h4.js +0 -1
- package/assets/board/_nuxt/CPCUMJnF.js +0 -1
- package/assets/board/_nuxt/CPcKlmSm.js +0 -1
- package/assets/board/_nuxt/CQTvWh4i.js +0 -1
- package/assets/board/_nuxt/CSEEUF8S.js +0 -1
- package/assets/board/_nuxt/CSSb154I.js +0 -13
- package/assets/board/_nuxt/CgDTd7jS.js +0 -1
- package/assets/board/_nuxt/ChG76uh9.js +0 -1
- package/assets/board/_nuxt/Ci0qbkgh.js +0 -1
- package/assets/board/_nuxt/CqoQ__I_.js +0 -1
- package/assets/board/_nuxt/CuJUHLl8.js +0 -1
- package/assets/board/_nuxt/CvLiA4_O.js +0 -1
- package/assets/board/_nuxt/Cvs12oA0.js +0 -3
- package/assets/board/_nuxt/CyEXFe3V.js +0 -1
- package/assets/board/_nuxt/Cz6rZcLK.js +0 -1
- package/assets/board/_nuxt/D2FhHl1o.js +0 -1
- package/assets/board/_nuxt/D3YCAmfu.js +0 -1
- package/assets/board/_nuxt/D5CE81jK.js +0 -1
- package/assets/board/_nuxt/D75vbfSb.js +0 -1
- package/assets/board/_nuxt/D99LbGfb.js +0 -9
- package/assets/board/_nuxt/DEfLc7p3.js +0 -6
- package/assets/board/_nuxt/DF-nsa1Z.js +0 -1
- package/assets/board/_nuxt/DIc8yx98.js +0 -1
- package/assets/board/_nuxt/DLkAKotw.js +0 -1
- package/assets/board/_nuxt/DRPlYvb3.js +0 -1
- package/assets/board/_nuxt/DRlQgul3.js +0 -1
- package/assets/board/_nuxt/DSLbmoWa.js +0 -1
- package/assets/board/_nuxt/DWO9c9yp.js +0 -1
- package/assets/board/_nuxt/DZo3dYLJ.js +0 -3
- package/assets/board/_nuxt/D_S6N7_b.js +0 -1
- package/assets/board/_nuxt/DajA-Tkt.js +0 -1
- package/assets/board/_nuxt/DbHiyab-.js +0 -1
- package/assets/board/_nuxt/Dc7Ql6eE.js +0 -1
- package/assets/board/_nuxt/Dd9ZukPU.js +0 -1
- package/assets/board/_nuxt/Dg2LiqmN.js +0 -1
- package/assets/board/_nuxt/DhuleNnm.js +0 -1
- package/assets/board/_nuxt/DkI1Qxpp.js +0 -95
- package/assets/board/_nuxt/DnDHGSYI.js +0 -1
- package/assets/board/_nuxt/DpXJ_tCU.js +0 -1
- package/assets/board/_nuxt/DqZgF3hU.js +0 -1
- package/assets/board/_nuxt/DqcxvfbD.js +0 -1
- package/assets/board/_nuxt/DsA2lVci.js +0 -1
- package/assets/board/_nuxt/Dtsa-1NS.js +0 -1
- package/assets/board/_nuxt/Du91iq0p.js +0 -1
- package/assets/board/_nuxt/Dx1wcYFo.js +0 -1
- package/assets/board/_nuxt/EYTShbt4.js +0 -1
- package/assets/board/_nuxt/MaXJprwN.js +0 -1
- package/assets/board/_nuxt/P9x67aq2.js +0 -1
- package/assets/board/_nuxt/S08nFESZ.js +0 -3
- package/assets/board/_nuxt/V0uynWE2.js +0 -1
- package/assets/board/_nuxt/Vo4wMbnS.js +0 -1
- package/assets/board/_nuxt/ZVTqot-_.js +0 -1
- package/assets/board/_nuxt/ZngEd3HB.js +0 -1
- package/assets/board/_nuxt/_id_.B2NDKSlX.css +0 -1
- package/assets/board/_nuxt/assMu_Wn.js +0 -1
- package/assets/board/_nuxt/builds/meta/8e23aec9-5b67-4569-b8bf-d4f07e50ffdf.json +0 -1
- package/assets/board/_nuxt/error-404.BFmXOnCT.css +0 -1
- package/assets/board/_nuxt/error-500.BZ-DdjQ6.css +0 -1
- package/assets/board/_nuxt/rlePnzpc.js +0 -1
- package/assets/board/_nuxt/uKzCKCTq.js +0 -1
- package/assets/board/_nuxt/vwxaNGfc.js +0 -1
- package/assets/board/_nuxt/yh6sf_D5.js +0 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Service Blueprint
|
|
2
|
+
|
|
3
|
+
**Best for:** showing how a service actually runs across a few stages — what the customer does, what they can see, and what stays hidden. The **line of visibility** is the load-bearing element: customer and frontstage actions sit above it, backstage and support sit below it, on one shared stage grid. Use it when the reader needs to see that a failure is a billing job, a queue, or a fraud check even though the customer row still looks like a simple retry.
|
|
4
|
+
|
|
5
|
+
**Not this type:**
|
|
6
|
+
|
|
7
|
+
- Sentiment across stages, no backstage → **User journey** (`type-journey.md`). A journey's load-bearing element is the feeling curve. If you cannot name a frontstage/backstage split, you are not drawing a blueprint.
|
|
8
|
+
- Flow with handoffs across named owners → **Swimlane** (`type-swimlane.md`). Arrows are the claim there. A blueprint is a census: stage order is the sequence, and wait times are cell text.
|
|
9
|
+
- Sequential nodes with data payloads → **Process** (`type-process.md`).
|
|
10
|
+
- One person's phases, waits, retries → **Lifecycle phase map** on State machine (`semantic-patterns.md` § 9).
|
|
11
|
+
- State census in columns, no visibility line → **Kanban** (`type-kanban.md`). Columns there are *states*, not narrative stages.
|
|
12
|
+
- Narrative backbone × release slices → **Story map** (`type-story-map.md`). The cut line is scope, not visibility.
|
|
13
|
+
- Abstraction bands with no stage columns → **Layer stack** (`type-layers.md`).
|
|
14
|
+
|
|
15
|
+
## Layout conventions
|
|
16
|
+
|
|
17
|
+
- **Orientation:** stages as equal columns (left → right in narrative order), layers as labeled rows (top → bottom). No connector arrows in this version — that is swimlane territory.
|
|
18
|
+
- **ViewBox:** `0 0 1280 720` for the minimal examples. Full editorial keeps the same SVG and adds cards.
|
|
19
|
+
- **Left margin:** 96px for layer labels. Geist Mono 8px, uppercase, horizontal, `text-anchor="end"` at x=88. **Never** `writing-mode: vertical`.
|
|
20
|
+
- **Stage grid:** 4–6 columns. The worked example is 5 × 208px with 16px gutters (`col_x = 96 + i·224`). Each header carries `data-stage` on a rect at the column origin; every cell in that column uses the same `x`.
|
|
21
|
+
- **Layer order, top to bottom:**
|
|
22
|
+
1. Physical evidence (optional) — 48px
|
|
23
|
+
2. Customer actions (required) — 64px
|
|
24
|
+
3. Line of interaction (hairline)
|
|
25
|
+
4. Frontstage actions — onstage staff or the visible product (required) — 64px
|
|
26
|
+
5. **Line of visibility** (load-bearing; heavier than the other lines)
|
|
27
|
+
6. Backstage actions (required) — 64px
|
|
28
|
+
7. Line of internal interaction (hairline)
|
|
29
|
+
8. Support processes (optional) — 48px
|
|
30
|
+
- **Hairlines:** 8px band including stroke. Interaction and internal-interaction are 1px `rule` (`data-role="interaction"` / `data-role="internal-interaction"`). Visibility is 2px `ink` at 0.55 opacity (`data-role="visibility"`), which must clear 3:1 on paper — 0.45 fails that bar on light paper, so do not go thinner.
|
|
31
|
+
- **Cells:** one action per stage per layer. Geist 12px, one line, centered on the column. A second muted mono line is allowed for a system or wait (`dunning-job · 4h`). Empty required cells are allowed only with an explicit `—` or `Not applicable` as `data-name` and as the printed text.
|
|
32
|
+
- **Fills:** customer and frontstage are paper/white with `ink` stroke. Backstage and support take a light `ink` tint so the below-the-line band reads as hidden work, not another onstage row.
|
|
33
|
+
- **Focal cell (≤1, optional):** the failure, wait, or handoff the figure exists to show — usually on or below the visibility line. Accent fill `rgba(191,69,32,0.12)` (dark: `rgba(240,138,89,0.18)`), accent stroke, `data-focal="true"`.
|
|
34
|
+
- **Legend:** horizontal strip after a hairline rule, three keys in this order — visibility line, backstage layer, focal cell.
|
|
35
|
+
|
|
36
|
+
### Machine-readable data contract
|
|
37
|
+
|
|
38
|
+
Every layer group: `data-layer="evidence|customer|frontstage|backstage|support"`.
|
|
39
|
+
|
|
40
|
+
Every cell: `data-stage="<stage-id>"` matching a header `data-stage`, plus `data-name` for the printed action.
|
|
41
|
+
|
|
42
|
+
Visibility line: `data-role="visibility"`. The two hairlines: `data-role="interaction"` and `data-role="internal-interaction"`.
|
|
43
|
+
|
|
44
|
+
Optional focal cell: `data-focal="true"` on at most one cell.
|
|
45
|
+
|
|
46
|
+
No `transform`, geometry `style`, or `<style>` rules that move marks.
|
|
47
|
+
|
|
48
|
+
`scripts/verify-service-blueprint.py` reads these and fails the build when the drawing and the declaration disagree.
|
|
49
|
+
|
|
50
|
+
### Service-blueprint element pattern
|
|
51
|
+
|
|
52
|
+
```svg
|
|
53
|
+
<!-- Stage header at column origin x=96; cells in this column reuse that x -->
|
|
54
|
+
<rect x="96" y="24" width="208" height="48" fill="none" data-stage="sign-up"/>
|
|
55
|
+
<text x="200" y="60" fill="#2d3142" font-size="12" font-weight="600"
|
|
56
|
+
font-family="'Geist', sans-serif" text-anchor="middle">Sign up</text>
|
|
57
|
+
|
|
58
|
+
<g data-layer="customer">
|
|
59
|
+
<rect x="544" y="128" width="208" height="64" rx="4" fill="#ffffff" stroke="#2d3142"
|
|
60
|
+
stroke-width="1" data-stage="hit-limit" data-name="Retry payment"/>
|
|
61
|
+
<text x="648" y="164" fill="#2d3142" font-size="12" font-family="'Geist', sans-serif"
|
|
62
|
+
text-anchor="middle">Retry payment</text>
|
|
63
|
+
</g>
|
|
64
|
+
|
|
65
|
+
<!-- Visibility line: 2px ink @ 0.55, between frontstage bottom and backstage top -->
|
|
66
|
+
<line x1="96" y1="268" x2="1200" y2="268" stroke="rgba(45,49,66,0.55)" stroke-width="2"
|
|
67
|
+
data-role="visibility"/>
|
|
68
|
+
|
|
69
|
+
<g data-layer="backstage">
|
|
70
|
+
<rect x="544" y="272" width="208" height="64" rx="4" fill="rgba(191,69,32,0.12)"
|
|
71
|
+
stroke="#bf4520" stroke-width="1" data-stage="hit-limit"
|
|
72
|
+
data-name="dunning-job timeout" data-focal="true"/>
|
|
73
|
+
<text x="648" y="300" fill="#bf4520" font-size="12" font-weight="600"
|
|
74
|
+
font-family="'Geist', sans-serif" text-anchor="middle">dunning-job timeout</text>
|
|
75
|
+
<text x="648" y="318" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace"
|
|
76
|
+
text-anchor="middle">dunning-job · 4h</text>
|
|
77
|
+
</g>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Anti-patterns
|
|
81
|
+
|
|
82
|
+
- **No visibility line**, or a line that sits in the wrong gap (not between frontstage and backstage). Without the line this is just a table of rows.
|
|
83
|
+
- **Sentiment curve on a blueprint.** That is a journey; split the figures.
|
|
84
|
+
- **Arrows crossing layers.** That is a swimlane.
|
|
85
|
+
- **Accent on every failing cell.** One focal cell; the rest of the grid is census.
|
|
86
|
+
- **Empty required layers** with no `—` / `Not applicable` mark.
|
|
87
|
+
- **More than 6 stages**; more than two lines of cell text.
|
|
88
|
+
- **`writing-mode` vertical layer labels.** Horizontal only, in the left margin.
|
|
89
|
+
|
|
90
|
+
## Honesty rules
|
|
91
|
+
|
|
92
|
+
- **The grid is a census, not a flow chart.** Stage order is the sequence. Wait times and system names are cell text, not edges.
|
|
93
|
+
- **Required layers are complete.** Every stage has a customer cell, a frontstage cell, and a backstage cell. An empty slot still occupies its column and says so.
|
|
94
|
+
- **The visibility line is checkable.** It spans the plot, sits in the frontstage/backstage gap, and its stroke clears 3:1 against paper.
|
|
95
|
+
- **Printed text matches `data-name`.** A cell that draws "Retry payment" and declares another action is two stories.
|
|
96
|
+
|
|
97
|
+
These rules are executable: `scripts/verify-service-blueprint.py` reads the declarations and fails on layer order, visibility, grid, census, focal, budget, printed-label, contrast, or CSS-moved marks. `scripts/test-verify-service-blueprint.py` proves both polarities — the shipped examples pass, and each mutation class above fails with a named finding.
|
|
98
|
+
|
|
99
|
+
## Examples
|
|
100
|
+
|
|
101
|
+
- `assets/example-service-blueprint.html` — minimal light. *Trial to paid — what the customer never sees*, 5 stages, focal backstage `dunning-job timeout` under "Hit the limit".
|
|
102
|
+
- `assets/example-service-blueprint-dark.html` — minimal dark, same data.
|
|
103
|
+
- `assets/example-service-blueprint-full.html` — full editorial: container framing + 3 varied-width summary cards + footer.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# State Machine
|
|
2
|
+
|
|
3
|
+
**Best for:** finite state logic — order status, auth state, connection lifecycle, form wizard, job queue status — and the [`Lifecycle phase map`](semantic-patterns.md#9-lifecycle-phase-map) pattern when one subject's progress, waits, retries, cancellation, and outcomes are the story.
|
|
4
|
+
|
|
5
|
+
## Routing distinctions
|
|
6
|
+
|
|
7
|
+
- Use **Sequence** for time-ordered messages between actors, including request/message lifecycles.
|
|
8
|
+
- Use ordinary **State Machine** for dense transition logic where events, guards, and legal transitions dominate.
|
|
9
|
+
- Use the **Lifecycle phase map** semantic pattern for one subject moving through 4–5 primary phases with separate wait/recovery and terminal-outcome bands.
|
|
10
|
+
|
|
11
|
+
## Layout conventions
|
|
12
|
+
- States are rounded rectangles (`rx=8`), labeled in the `node-name` role.
|
|
13
|
+
- **Start**: filled ink dot (`r=6`). **End**: ringed dot (outer `r=8` outline, inner filled `r=5`).
|
|
14
|
+
- Transitions: curved arrows labeled in the `arrow-label` role as `event [guard] / action` (omit sections you don't need).
|
|
15
|
+
- Self-loops curve above the state.
|
|
16
|
+
- Orient along the dominant flow direction (left→right or top→down); rearrange before crossing transitions.
|
|
17
|
+
- Coral on the state the reader should notice — typically the error state, or "happy completion".
|
|
18
|
+
|
|
19
|
+
## Anti-patterns
|
|
20
|
+
- More transitions than states × 2 → likely two state machines.
|
|
21
|
+
- "From any state" transitions drawn from every state — use a single annotation (`* → Error on timeout`) instead.
|
|
22
|
+
- Unlabeled transitions (the whole point is *what triggers this*).
|
|
23
|
+
|
|
24
|
+
## Examples
|
|
25
|
+
- `assets/example-state.html` — minimal light
|
|
26
|
+
- `assets/example-state-dark.html` — minimal dark
|
|
27
|
+
- `assets/example-state-full.html` — full editorial
|
|
28
|
+
- `assets/example-state-lifecycle.html` — lifecycle phase map, minimal light
|
|
29
|
+
- `assets/example-state-lifecycle-dark.html` — lifecycle phase map, minimal dark
|
|
30
|
+
- `assets/example-state-lifecycle-full.html` — lifecycle phase map, full editorial
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# User Story Map
|
|
2
|
+
|
|
3
|
+
**Best for:** the Jeff Patton user story map — it answers "what is the whole story, and where do we cut the first release?" Narrative order runs left to right; priority runs top to bottom. The **release cut** is the editorial point of the diagram: a map without one is just a backlog in a grid.
|
|
4
|
+
|
|
5
|
+
This is neither **Kanban** nor **User journey**, and the distinction is load-bearing:
|
|
6
|
+
|
|
7
|
+
- **Kanban** shows *state* — columns are Todo/Doing/Done, there is no narrative order and nothing to slice.
|
|
8
|
+
- **User journey** shows *one persona's feelings* across stages via a sentiment curve.
|
|
9
|
+
- A **story map** has neither state nor sentiment. Its columns are **narrative order** and its rows are **release slices**. If you aren't slicing releases, use one of those two instead.
|
|
10
|
+
|
|
11
|
+
## Layout conventions
|
|
12
|
+
|
|
13
|
+
Vertical stack, top to bottom:
|
|
14
|
+
|
|
15
|
+
1. **Backbone** — up to 5 activities in left-to-right narrative order, as wide header cards (200px, `rx=6`, `ink @ 0.05` fill, `muted` stroke). Each card: the activity name in the `node-name` role, 12px, weight 600, above an `eyebrow`-role 8px uppercase tracked eyebrow (`ACTIVITY 1` … `ACTIVITY 5`). 24px gutters between cards.
|
|
16
|
+
2. **Walking skeleton row** — directly under each activity, its user *steps* as smaller cards (`rx=4`, 32px tall, white fill, `ink` stroke), `node-name` family 12px. One or two per activity; reserve room for two so every activity's row bottom aligns even when it only has one step.
|
|
17
|
+
3. **Release slices** — horizontal bands below the skeleton row, each a full-width lane with an `eyebrow`-role 8px uppercase tracked label (`MVP`, `RELEASE 2`, `LATER`) sitting in a 96px left margin. Band background alternates `ink @ 0.02` / none. Inside each band, story cards (`rx=4`, 48px tall) sit in their activity's column: story title in the `node-name` role, 12px, weight 600, plus a `sublabel`-role 9px estimate/ticket sublabel (e.g. `RPT-114 · 3pt`). Whenever any slice has a gap (an activity with no card in that row), add `rule` hairline column separators (0.8px, dashed `4,4`, 0.10 opacity) running from just under the backbone down to the bottom of the last slice, drawn before the cards — without them, a gappy grid reads as scattered rather than mapped to its activity.
|
|
18
|
+
4. **The release cut line** — a full-width horizontal `accent` rule (1.5px) immediately under the MVP band, with a masked `arrow-label`-role 8px label `RELEASE CUT` at its right end. This is accent element one.
|
|
19
|
+
5. **Legend** — horizontal strip at the bottom per the global rule (hairline separator above): one swatch for the default story card, one for the highest-risk treatment, one for the release-cut line.
|
|
20
|
+
|
|
21
|
+
## Focal rule
|
|
22
|
+
|
|
23
|
+
Exactly 2 accent elements: the release cut line with its `RELEASE CUT` label (counts as one), and the single riskiest story card — drawn with `accent @ 0.05` fill, `accent` dashed `4,4` stroke, and a small rectangular `RISK` tag (`rx=2`, matching the type-tag primitive) — counts as the other. Nothing else on the map is `accent`.
|
|
24
|
+
|
|
25
|
+
## Complexity budget
|
|
26
|
+
|
|
27
|
+
- Max 5 activities, max 3 release slices, max 12 story cards total, max 4 cards per slice.
|
|
28
|
+
- Max 2 accent elements (the release cut counts as one; the riskiest card counts as the other).
|
|
29
|
+
- Over budget on a single activity or slice → split into one map per activity, or collapse a slice into a count card rather than listing every item.
|
|
30
|
+
|
|
31
|
+
## Anti-patterns
|
|
32
|
+
|
|
33
|
+
- **No release cut.** A map with no cut line is a backlog in a grid, not a map — the cut is the whole point.
|
|
34
|
+
- **Columns ordered by priority instead of narrative sequence.** The backbone is a story, left to right, in the order the user experiences it — not a ranked list.
|
|
35
|
+
- **Story cards that are features, not user-visible outcomes.** "Add a chart" is a story; "Refactor the charting service" is not — it belongs in a backlog ticket, not the map.
|
|
36
|
+
- **Slices named by date instead of by outcome.** `MVP` / `RELEASE 2` / `LATER` describe scope; `Q3` / `Q4` describe a calendar and drift the moment the schedule slips.
|
|
37
|
+
- **More than 3 slices.** Beyond MVP, next, and later, nobody believes the ordering — collapse the tail into "Later."
|
|
38
|
+
- **Mixing two personas in one map.** One map per persona, same as user journey.
|
|
39
|
+
- **Adding state columns.** That turns it into a kanban board — this type has no state.
|
|
40
|
+
- **Adding a sentiment curve.** That turns it into a user journey — this type has no feelings axis.
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
- `assets/example-story-map.html` — minimal light. *Reporting, first release*: four activities (`Find the data`, `Build the report`, `Share it`, `Trust it`), MVP/Release 2/Later slices, release cut under MVP, `Row-level permissions` flagged as the riskiest story.
|
|
45
|
+
- `assets/example-story-map-dark.html` — minimal dark, same data.
|
|
46
|
+
- `assets/example-story-map-full.html` — full editorial: container framing + 3 summary cards of varied widths + footer.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Swimlane
|
|
2
|
+
|
|
3
|
+
**Best for:** cross-functional processes, RACI-style flows, vendor handoffs, multi-team shipping workflows.
|
|
4
|
+
|
|
5
|
+
**Not this type:** what the customer sees vs what stays hidden, on one shared stage grid → **Service blueprint** (`type-service-blueprint.md`). A blueprint has no arrows; stage order is the sequence.
|
|
6
|
+
|
|
7
|
+
## Layout conventions
|
|
8
|
+
- Horizontal lanes (or vertical columns) — one per actor/team. Label each lane in the left margin (or top) with an `eyebrow`-role label.
|
|
9
|
+
- Lane dividers: 1px hairlines.
|
|
10
|
+
- Process steps are rectangles placed inside the lane of the actor performing them; arrows show flow.
|
|
11
|
+
- Handoffs (arrows crossing lane boundaries) are the most important edges — consider coral on the handoff that introduces the most coupling or latency.
|
|
12
|
+
- Don't force equal step count per lane; a lane with one step is fine.
|
|
13
|
+
|
|
14
|
+
## Anti-patterns
|
|
15
|
+
- Lanes without labels.
|
|
16
|
+
- A step drawn across two lanes (pick one owner).
|
|
17
|
+
- Arrows that snake back and forth — reorder steps so the flow is mostly straight.
|
|
18
|
+
|
|
19
|
+
## Examples
|
|
20
|
+
- `assets/example-swimlane.html` — minimal light
|
|
21
|
+
- `assets/example-swimlane-dark.html` — minimal dark
|
|
22
|
+
- `assets/example-swimlane-full.html` — full editorial
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Timeline
|
|
2
|
+
|
|
3
|
+
**Best for:** release history, project milestones, incident timelines, roadmaps, changelog visualizations.
|
|
4
|
+
|
|
5
|
+
## Layout conventions
|
|
6
|
+
- Horizontal hairline baseline across the middle (`stroke-width=1`).
|
|
7
|
+
- Tick marks at time boundaries (quarters, months, sprints) with date labels below in the `arrow-label` role.
|
|
8
|
+
- Events: small filled circles (`r=4`) on the baseline. Labels alternate above and below to prevent collision, connected to the circle with a 1px hairline drop.
|
|
9
|
+
- Major milestones: `accent` circle (`r=6`) + bold `node-name`-role label.
|
|
10
|
+
- Time scale must be honest: if intervals are non-equal, space the circles non-equally. Don't fake linear spacing for aesthetics. Break the axis visibly if a region is too dense.
|
|
11
|
+
|
|
12
|
+
## Anti-patterns
|
|
13
|
+
- Equal-spacing events that aren't equally spaced in time.
|
|
14
|
+
- Missing axis labels ("what unit is this?").
|
|
15
|
+
- Crowded labels without vertical offset — illegible.
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
- `assets/example-timeline.html` — minimal light
|
|
19
|
+
- `assets/example-timeline-dark.html` — minimal dark
|
|
20
|
+
- `assets/example-timeline-full.html` — full editorial
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Tree / Hierarchy
|
|
2
|
+
|
|
3
|
+
**Best for:** org charts, dependency trees, taxonomy, file trees, decision breakdowns, skill trees. For hierarchical, ID-addressable block decomposition with per-block I/O, constraints, and implementation traceability, load [`semantic-patterns.md`](semantic-patterns.md) § Traceable block decomposition first — it specializes this layout without changing it.
|
|
4
|
+
|
|
5
|
+
## Layout conventions
|
|
6
|
+
- Root at top, children fan out below (or root at left, children to right).
|
|
7
|
+
- Nodes are small labeled rectangles (`rx=6`), `node-name` role 12px 600 name + optional `sublabel` role 9px. Width 120–180px, height 40–52px.
|
|
8
|
+
- **Connectors are orthogonal (elbow-style), never diagonal.** Parent drops a short vertical line, then a horizontal bus connects siblings, then each child has a short vertical drop into its top edge. 1px muted stroke.
|
|
9
|
+
- Leaf indicator: thinner stroke (0.8) or different fill — OR let terminal position do the work.
|
|
10
|
+
- Max depth: 4 (root + 3 tiers). Max breadth per level: 5.
|
|
11
|
+
- Coral on **one** node: root OR critical leaf. Not both.
|
|
12
|
+
- Draw connectors before nodes.
|
|
13
|
+
|
|
14
|
+
## Anti-patterns
|
|
15
|
+
- Tree 5+ levels deep on a single page (illegible — split).
|
|
16
|
+
- Nodes of wildly varying widths — pick 2 widths max.
|
|
17
|
+
- Diagonal connector lines.
|
|
18
|
+
- Skipped levels (parent connected to grandchild with no middle).
|
|
19
|
+
- Coral on root AND a leaf.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
- `assets/example-tree.html` — minimal light
|
|
23
|
+
- `assets/example-tree-dark.html` — minimal dark
|
|
24
|
+
- `assets/example-tree-full.html` — full editorial
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Treemap
|
|
2
|
+
|
|
3
|
+
**Best for:** part-of-whole where the *relative sizes are the story* — disk and bundle usage, budget or spend breakdowns, market share, population, time allocation. Use when a single total decomposes into parts and the reader's question is "what dominates, and by how much?"
|
|
4
|
+
|
|
5
|
+
Not for: ranked lists where exact values matter more than proportion (use a **bar chart**), containment or scope relationships with no quantity (use **nested**), or a hierarchy you need to trace parent-to-child (use a **tree**).
|
|
6
|
+
|
|
7
|
+
## Layout conventions
|
|
8
|
+
|
|
9
|
+
- **Plot area:** `x` 40 → 956, `y` 40 → 420 inside a `0 0 1000 500` viewBox — the same vertical rhythm as bar, line and scatter, so the legend block sits where a reader of those types already expects it (rule at `y=462`, `LEGEND` at `478`, keys at `488`).
|
|
10
|
+
- **Squarified layout** (Bruls et al., 2000): sort descending, lay each row against the *shorter* side of the remaining rectangle. Aspect ratios stay near 1, which is what makes two areas comparable by eye. Never lay cells out in simple stripes — long thin cells cannot be compared.
|
|
11
|
+
- **Cell count:** 4–8. Past 8, the tail becomes unlabelable slivers — group the tail into a single explicit "Other" cell and name what it contains in the source line.
|
|
12
|
+
- **4px grid:** cell edges snap to the grid like everything else, with a 4px gutter between cells. Snapping and gutters both move area, so check the result — and check it as **relative** error (`(drawn − true) ÷ true`), not percentage points. A 0.1pp slip is nothing on a 59% cell and a quarter of a 0.5% cell; absolute error hides exactly the mistake you need to catch. Keep every cell within a few percent of its true share — the shipped example is within 2.7%, its worst case being the sliver, where the grid cannot do better — and state the encoding in the source line (`AREA = POPULATION`). `scripts/verify-treemap.py` gates this.
|
|
13
|
+
- **Fill:** a rank-ordered `ink` opacity ramp (e.g. `0.16 → 0.04`), so the non-focal order survives greyscale printing and colour-blind readers. One accent cell only — the editorially focal one, not automatically the largest. Note what this does *not* buy you: the focal cell is painted off-ramp, so in greyscale it lands wherever its tint happens to fall, not at its rank. Identify it by the accent stroke, and never let tone carry meaning the area doesn't already carry. `ink` is a role, not a colour: it resolves near-black on light paper and near-white on dark, so one ramp of opacities composites *darker* as it strengthens in the light skin and *lighter* in the dark one. The opacities are identical in both; only their lightness flips.
|
|
14
|
+
- **Stroke:** 1px `ink @ 0.30` hairline on every cell; the focal cell takes a 1.5px `accent` stroke.
|
|
15
|
+
- **Labels sit inside the cell**, top-left, 16px in from the edge: name in the `node-name` role 12–14px 600, value in the `sublabel` role 9px on the next line. Three tiers by cell size:
|
|
16
|
+
- large — name + value + share (`4.78B · 59% of world`)
|
|
17
|
+
- medium — name + value
|
|
18
|
+
- small — a 3-letter mono abbreviation, if one reads honestly
|
|
19
|
+
- sliver — **no text.** When the cell is at least 12×12px, use a filled `ink` disc, `r=5`, centred in the cell, carrying a paper-coloured `i`, with the cell's name and share spelled out in the legend. Below 12px on either axis, omit the in-cell mark and identify the sliver by position in the legend; a fixed-size disc must never cross the cell boundary. `scripts/verify-treemap.py` checks marker containment. Resist rotating a label to make it fit: a single sideways word among five upright ones reads as a mistake before it reads as data, and its centring is a trap — `text-anchor="middle"` centres along the *baseline*, which a quarter-turn maps to the cell's long axis, leaving nothing centring the cap-height band across the narrow one.
|
|
20
|
+
- Never shrink a cell to fit its label. The cell size is the data; the label is commentary.
|
|
21
|
+
- **Contrast:** compute the ceiling against the token you actually ship. The 9px value line is `muted`, not `ink`, and `muted` needs a lighter cell than `ink` does: measured against the composited fill, the top of the ramp can go to **0.16 on light paper and 0.14 on dark** before it drops under 4.5:1. (`ink` would tolerate 0.20 — which is exactly the number you will write down if you check the wrong token.) A mid-tone fill — solid accent, or 50% ink — fails against both light and dark text; use the tint-plus-stroke pattern instead. The source line takes `muted` too: `soft` measures 3.48:1 on paper and never reaches AA anywhere on this ramp.
|
|
22
|
+
- **Legend:** the house block (rule, `LEGEND`, keys), naming the focal cell, the direction of the ink ramp, and any cell carrying an info mark. **Name that direction by contrast against the paper — `stronger contrast is larger` — never by lightness.** `darker is larger` is true only on light paper; ship it in the dark variant and the legend states the opposite of what the reader sees, because the ramp's lightness inverts with the skin while its opacity does not. Named by contrast, one sentence serves all three variants and cannot rot apart. `scripts/verify-skin-polarity.py` gates this, checking every directional tone claim against the ramp composited on that file's own paper. HTML comments are not visible legend copy, including comments between text fragments; contradictory or unverifiable visible wording still fails. Explicit `fill-opacity` and `opacity` presentation attributes multiply the fill color's alpha before that comparison; CSS rules and inherited/group opacity are not resolved by this source checker. Ranked cells with zero effective opacity remain in the comparison at paper contrast. The source line rides the same row as `LEGEND`, right-aligned in mono 8px, stating what area encodes plus the dataset and its date. Archived closing tags inside an inline comment cannot truncate the surrounding visible claim.
|
|
23
|
+
|
|
24
|
+
Commented-out SVG geometry does not contribute to verified cell area or annotation containment.
|
|
25
|
+
|
|
26
|
+
Both matching SVG attribute quote delimiters are supported by the geometry verifier.
|
|
27
|
+
|
|
28
|
+
Parseable numeric label positions and font sizes must be finite, and font sizes must be positive, so invalid annotations cannot bypass containment comparisons. Unsupported SVG length formats retain the existing conservative skip; they are not certified by this source checker.
|
|
29
|
+
|
|
30
|
+
### Declaring the share
|
|
31
|
+
|
|
32
|
+
Printed percentages are read as complete signed numbers, including leading decimals and scientific notation; `5.9e1%` means 59%, while `-59%` contradicts a positive share. Non-finite percentage claims are findings.
|
|
33
|
+
|
|
34
|
+
**Every cell carries `data-share` — including cells too small to label.** It is the cell's percentage of the whole, and it is what makes the area checkable:
|
|
35
|
+
|
|
36
|
+
```svg
|
|
37
|
+
<rect x="X" y="Y" width="W" height="H" rx="2" data-share="18.29" fill="…" stroke="…"/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Without it, a verifier has to infer the intended share from the text inside the cell, which quietly exempts the one cell that has no text — and that is the sliver, the cell the 4px grid distorts most. A shipped treemap once had its smallest cell drawn 50% oversized with every gate green for exactly this reason. `scripts/verify-treemap.py` now fails closed on any cell without it, and cross-checks `data-share` against the percentage the label prints, because a label and the metadata are two statements of one fact.
|
|
41
|
+
|
|
42
|
+
### Cell element pattern
|
|
43
|
+
|
|
44
|
+
```svg
|
|
45
|
+
<!-- Opaque paper mask prevents the dot pattern showing through the tint -->
|
|
46
|
+
<rect x="X" y="Y" width="W" height="H" rx="2" fill="{paper}"/>
|
|
47
|
+
<!-- Cell body -->
|
|
48
|
+
<rect x="X" y="Y" width="W" height="H" rx="2" data-share="18.29" fill="{ink @ 0.16}" stroke="{ink @ 0.30}" stroke-width="1"/>
|
|
49
|
+
<text x="X+16" y="Y+28" fill="{ink}" font-size="13" font-weight="600" font-family="{node-name}">NAME</text>
|
|
50
|
+
<text x="X+16" y="Y+46" fill="{muted}" font-size="9" font-family="{sublabel}">VALUE · SHARE</text>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Focal cell: replace the fill with `accent @ 0.16` and the stroke with `accent` at 1.5px.
|
|
54
|
+
|
|
55
|
+
## Honest-data rule
|
|
56
|
+
|
|
57
|
+
**Area is the only encoding.** Never clip, floor, or log-scale a cell to make it visible, and never drop a cell because it is small — a treemap claims to show a whole, so an omitted part makes the picture a lie. A part too small to label gets a legend entry and, only when the cell can contain it, an info mark; parts too small to draw get merged into one honest, named "Other". If several cells are invisible at the target size, the data wants a bar chart.
|
|
58
|
+
|
|
59
|
+
Watch the smallest cell hardest: it is the one that grid snapping and gutters distort most, and the one nobody checks. Beware, too, the rounding you *display*: six values each rounded up can sum past the total you printed underneath them. Either carry enough precision that the parts reconcile, or say plainly in the source line that they don't (`PARTS ROUNDED, MAY NOT SUM`).
|
|
60
|
+
|
|
61
|
+
## Anti-patterns
|
|
62
|
+
|
|
63
|
+
- More than 8 cells without an "Other" bucket (unlabelable slivers).
|
|
64
|
+
- A stated total the cells contradict by more than display rounding — or rounding that is never disclosed. Rounded parts that miss the total by a hair are honest once the source line says so; silently printing figures that don't reconcile is not.
|
|
65
|
+
- Stripe layout instead of squarified — defeats area comparison.
|
|
66
|
+
- Rainbow fills: one hue per cell destroys the rank reading and the one-accent rule.
|
|
67
|
+
- Nesting more than two levels deep in a static diagram; a second level needs a heavier border and its own label tier, and a third is unreadable without interaction.
|
|
68
|
+
- 3-D or shadowed cells — area is already the message.
|
|
69
|
+
|
|
70
|
+
## Variants
|
|
71
|
+
|
|
72
|
+
- **Marimekko:** the same area encoding on a grid — column width is the category's share, segment height is the series' share within it, so area is the joint share. Full spec below.
|
|
73
|
+
|
|
74
|
+
### Marimekko
|
|
75
|
+
|
|
76
|
+
**Best for:** a **two-way part-of-whole** where both splits matter and the reader's question is "which cell of the cross-tab dominates?" — CI minutes by pipeline × runner OS, bundle bytes by package × chunk, spend by team × vendor, incidents by service × severity. The treemap above answers one question (what dominates the whole); a marimekko answers three at once: read across for the category mix, down for the series mix within a category, and by area for the joint share. A stacked bar with equal-width bars shows the within-category mix and throws the category sizes away; a treemap shows the joint sizes and throws the grid away.
|
|
77
|
+
|
|
78
|
+
Not for: a one-way split (that is the parent treemap, and a marimekko with one series is a bar chart); more than ~5 series or ~8 categories, past which the small cells become unlabelable slivers in *both* directions; series measured in different units, which cannot share one column; or a comparison of the series' totals across categories, which the height encoding deliberately hides — if that is the reading, the data wants a grouped bar.
|
|
79
|
+
|
|
80
|
+
#### Layout conventions
|
|
81
|
+
|
|
82
|
+
- **Plot area:** the treemap's — `x` 40 → 956, `y` 40 → 420 inside a `0 0 1000 500` viewBox, legend block at `y=462`/`478`/`488`. Column captions sit under the plot at `y=438`, `sublabel` role 9px, centred on their column. The shipped example spends 900px of column width across five columns with four 4px gutters.
|
|
83
|
+
- **Column width is category share** of the whole, over the sum of column widths. Column edges snap to the 4px grid, so the gutters do; keep the gutter constant — a widened gap reads as a narrower column.
|
|
84
|
+
- **Every column is the full plot height**, and its segments tile it top to bottom with no gaps and no gutters, separated by the hairline stroke alone. **Segment height is the series' share within its column**, so the same height means the same within-category share whatever the column's width. Segment boundaries are data and land on whole pixels, exempt from the 4px grid as the waterfall's bar tops are.
|
|
85
|
+
- **One series order, top to bottom, in every column** — the order of the series' overall totals, largest at the top. A series absent from a category is omitted from that column, never drawn at zero height; the rows do not align across columns and are not meant to, which is why every segment prints its own share.
|
|
86
|
+
- **Column and series budgets:** 3–8 columns, 2–5 series. Widths under ~24px cannot hold a label in either direction and take the treemap's information mark instead.
|
|
87
|
+
- **Labels sit inside the segment**, top-left, 16px in, in the treemap's tiers by height: 56px and above takes the name in the `node-name` role 12px 600 with the amount and within-column share in the `sublabel` role 9px on the next line (`2,140 min · 68%`); 32–55px takes the same pair at 11px/9px on a tighter pitch; below that, the mark or nothing. The focal segment may add what its share is *of* (`83% of mobile`) because that is the one number a reader is most likely to misread as a share of the whole. Never shrink or widen a segment to fit a label.
|
|
88
|
+
- **Column captions** print the column's name and its share of the whole (`web · 31%`), so the width can be read as a number without a ruler.
|
|
89
|
+
- **Hold the 760px canvas on narrow screens.** The SVG keeps `min-width: 760px` so its 9px labels stay readable, and sits inside a local `overflow-x: auto` wrapper (`.diagram-container`) so a phone scrolls the chart, not the page. `scripts/lint-render.py --all` renders every marimekko at 390px and fails on page-level overflow, a shrunken canvas, or a missing local scroller.
|
|
90
|
+
|
|
91
|
+
#### Colour
|
|
92
|
+
|
|
93
|
+
The treemap's colour section holds here with one change: the ramp runs **per series, not per cell**. Every segment of one series takes one `ink` opacity — strongest on the series with the largest overall total (`0.16 → 0.10 → 0.05` on light paper, `0.14 → 0.09 → 0.04` on dark) — so a row reads as one thing across the figure and the legend needs one key per series, not a direction word. One accent segment, marked by its `accent` stroke at 1.5px and the accent tint, on the editorially focal cell. Labels stay `ink` (names) and `muted` (amounts) everywhere, and the top of the ramp stays at the treemap's contrast ceiling for the same reason.
|
|
94
|
+
|
|
95
|
+
#### Honest-data rule
|
|
96
|
+
|
|
97
|
+
**Width, height and area are three statements of one table, and every one of them is checked.** A column widened to fit its label lies about the category; a segment padded for headroom lies about the series; either lies about the joint share, which is the reading the type exists to give. `scripts/verify-marimekko.py` recomputes all three from the amount every segment declares, as relative error, so the narrow column and the thin segment are held to the same standard as the giants.
|
|
98
|
+
|
|
99
|
+
- **Never drop a category or a series to tidy the grid.** A marimekko claims to show a whole; a missing column makes every other width a lie, and a missing segment makes every other height in its column one. Merge the tail into a named "Other" column or series instead.
|
|
100
|
+
- **A series absent from a category is omitted, not drawn at zero.** A zero-height rect is a cell that claims to exist; an omitted one is a gap the legend can explain.
|
|
101
|
+
- **Say what the amounts are** in the source line — the unit, the period, the total — and say when they are illustrative. The checker verifies internal consistency only; a figure wrong by the same factor everywhere is self-consistent.
|
|
102
|
+
|
|
103
|
+
#### Declaring the values
|
|
104
|
+
|
|
105
|
+
Every segment is one `<rect>` (over its paper mask, as in the parent) carrying the category, the series and the amount. Every visible string is bound to what it describes.
|
|
106
|
+
|
|
107
|
+
```svg
|
|
108
|
+
<rect x="580" y="106" width="216" height="314" rx="2" data-column="mobile" data-segment="macOS" data-amount="1980" fill="{accent @ 0.16}" stroke="{accent}" stroke-width="1.5"/>
|
|
109
|
+
<text data-column="mobile" data-segment="macOS" data-role="label" x="596" y="152" fill="{muted}" font-size="9" font-family="{sublabel}">1,980 min · 83% of mobile</text>
|
|
110
|
+
<text data-column="mobile" data-role="caption" x="688" y="438" fill="{muted}" font-size="9" font-family="{sublabel}" text-anchor="middle">mobile · 24%</text>
|
|
111
|
+
<!-- Key: the node-name family at regular weight; swap in the active skin's sans stack -->
|
|
112
|
+
<text data-segment="macOS" data-role="key" x="344" y="497" fill="{muted}" font-size="8.5" font-family="'Geist', sans-serif">macOS</text>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`data-amount` is the basis of every geometric check, and `data-segment` on a `<rect>` is this contract's scope key: the parent binds `data-share` on a `<rect>` and reads only files named for it, slopegraph binds `data-series` on a `<line>`, bump `data-ranks` and ridgeline `data-bins` on a `<path>`, bubble `data-size` and beeswarm `data-value` on a `<circle>`. No two gates read one attribute, so no two gates claim one file. A label prints the segment's amount and its within-column share and nothing else numeric; a caption prints its column's name and share of the whole; a key names its series. `scripts/verify-marimekko.py` covers the shared plot, the constant gutter, the width, height and area shares, the tiling, the series order, the accent count, every binding and the marker fit; `scripts/test-verify-marimekko.py` proves each check in both polarities and pins the scope treaty with the parent and the sibling gates.
|
|
116
|
+
|
|
117
|
+
**No `transform` on any of it**, by any carrier — the `transform` attribute, an inline `style`, or a `<style>` rule — on a segment, a bound label, or an ancestor `<g>`. The checker reads raw coordinates, and a transform moves the rendered mark away from the number that was verified.
|
|
118
|
+
|
|
119
|
+
#### Anti-patterns
|
|
120
|
+
|
|
121
|
+
- Equal-width columns — that is a 100% stacked bar, and the category sizes are gone.
|
|
122
|
+
- Columns of different heights, or a gutter between segments — height stops being a share of anything.
|
|
123
|
+
- A series in a different order in one column, or one drawn at zero height where it is absent.
|
|
124
|
+
- One hue per series instead of the ink ramp plus a single accent; a legend that names the ramp by tone instead of by series.
|
|
125
|
+
- A column widened, or a segment padded, to fit its label.
|
|
126
|
+
- A category or series silently dropped from the grid.
|
|
127
|
+
- More than 5 series or 8 categories without an "Other".
|
|
128
|
+
- A stated total the segments contradict by more than display rounding.
|
|
129
|
+
|
|
130
|
+
## Examples
|
|
131
|
+
|
|
132
|
+
- `assets/example-treemap.html` — minimal light
|
|
133
|
+
- `assets/example-treemap-dark.html` — minimal dark
|
|
134
|
+
- `assets/example-treemap-full.html` — full editorial
|
|
135
|
+
- `assets/example-marimekko.html` — marimekko, minimal light
|
|
136
|
+
- `assets/example-marimekko-dark.html` — marimekko, minimal dark
|
|
137
|
+
- `assets/example-marimekko-full.html` — marimekko, full editorial
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# UML Class Diagram
|
|
2
|
+
|
|
3
|
+
**Best for:** the static structure of an object model — classes, what they own, what they inherit, and what they merely depend on. The distinguishing content is the **operations compartment** and the **typed relationship vocabulary** (the arrowheads carry meaning). ER cannot express either — use this type only when operations or the inheritance/composition vocabulary are the point of the diagram, and `type-er.md` when the story is entities and cardinality.
|
|
4
|
+
|
|
5
|
+
**Other UML diagrams — route elsewhere.** UML is a family; only the class diagram gets its own grammar here:
|
|
6
|
+
|
|
7
|
+
| UML diagram | Use instead |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Sequence | [type-sequence.md](type-sequence.md) |
|
|
10
|
+
| State machine | [type-state.md](type-state.md) |
|
|
11
|
+
| Component | [type-architecture.md](type-architecture.md) |
|
|
12
|
+
| Deployment | [type-architecture.md](type-architecture.md) |
|
|
13
|
+
| Activity | [type-swimlane.md](type-swimlane.md) or [type-flowchart.md](type-flowchart.md) |
|
|
14
|
+
| Conceptual / domain ER | [type-er.md](type-er.md) |
|
|
15
|
+
|
|
16
|
+
## Layout conventions
|
|
17
|
+
|
|
18
|
+
- Each class is a **single box** (`rx=6`), divided by full-width hairlines into up to three compartments. Compartment heights follow content — never pad to a uniform height.
|
|
19
|
+
1. **Name** — class name in the `node-name` role, 12px, weight 600, **centered**. An interface carries an `eyebrow`-role 8px `«interface»` stereotype line above the name. An abstract class sets the name in *italic*.
|
|
20
|
+
2. **Attributes** — one line each, `sublabel` role 9px, left-aligned: `+ name: Type`. Visibility markers: `+` public, `-` private, `#` protected.
|
|
21
|
+
3. **Operations** — one line each, `sublabel` role 9px, left-aligned: `+ method(arg): Return`.
|
|
22
|
+
Omit a compartment entirely when a class has no members in it (an interface with no attributes skips that compartment).
|
|
23
|
+
- Attribute/operation lines are a single combined string, not the two-column field/type layout ER uses — that visual distinction keeps the two types from reading the same.
|
|
24
|
+
- Coral (accent) is reserved for the class being implemented or extended (the focal type) — accent-tint fill, accent stroke. Its inbound inheritance/realization edges count as **one** additional accent element (treated as a group), for 2 accent elements total per diagram.
|
|
25
|
+
|
|
26
|
+
## Relationship vocabulary
|
|
27
|
+
|
|
28
|
+
Define every marker used in `<defs>` and show all six in the legend, even the ones not used in the diagram body — the legend is this type's complete grammar reference.
|
|
29
|
+
|
|
30
|
+
| Relationship | Line | Ending (at the target/owner end) |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Inheritance (`extends`) | solid | large **hollow triangle** — `paper` fill, `ink` stroke |
|
|
33
|
+
| Realization (`implements`) | dashed `5,4` | same hollow triangle |
|
|
34
|
+
| Composition (owns, cascades) | solid | **filled diamond** at the OWNER end, `ink` fill |
|
|
35
|
+
| Aggregation (has, independent) | solid | **hollow diamond** at the OWNER end |
|
|
36
|
+
| Association | solid | plain open arrowhead, multiplicity at BOTH ends |
|
|
37
|
+
| Dependency (uses) | dashed `4,3` | plain open arrowhead |
|
|
38
|
+
|
|
39
|
+
Multiplicities (`1`, `0..*`, `1..*`) sit in the `arrow-label` role at 8px, 10–12px off the box edge, on an opaque mask over the line — same convention as ER cardinality labels.
|
|
40
|
+
|
|
41
|
+
## Connector rules
|
|
42
|
+
|
|
43
|
+
All six SKILL.md §6 connector rules apply in full — orthogonal rounded elbows (`r=8`), no diagonals, bridge/hop for unavoidable crossings, fanned attach points ≥12px apart when several relationships share an edge, masked labels with the 6–10px gap, connectors drawn before boxes. Prefer laying classes out so relationships resolve to straight lines or single-elbow routes; a class diagram with every edge bridging is over budget — split by package instead.
|
|
44
|
+
|
|
45
|
+
## Complexity budget
|
|
46
|
+
|
|
47
|
+
Max 7 classes, max 8 relationships, max 5 members per compartment (overflow becomes a `sublabel`-role `…` line), max 2 accent elements. Over budget → split by package.
|
|
48
|
+
|
|
49
|
+
Seven is the ceiling rather than the target. Three compartments per box makes a class diagram dense fast, so treat 4–5 classes as the normal size; the shipped example uses all seven only because it doubles as the legend for the full relationship vocabulary.
|
|
50
|
+
|
|
51
|
+
## Anti-patterns
|
|
52
|
+
|
|
53
|
+
- Getters and setters listed as operations — they're noise; show behavior that matters.
|
|
54
|
+
- Every attribute and method dumped in — a class diagram is an argument, not a header file.
|
|
55
|
+
- Composition and aggregation used interchangeably — the filled diamond means the part dies with the whole. Say so, or use the hollow diamond.
|
|
56
|
+
- Association arrows with no multiplicity.
|
|
57
|
+
- Drawing a class diagram when there's no inheritance and no operations — that's ER.
|
|
58
|
+
- Stereotype guillemets on everything, not just the interfaces/abstracts that need them.
|
|
59
|
+
- Boxes padded to equal height.
|
|
60
|
+
|
|
61
|
+
## Examples
|
|
62
|
+
|
|
63
|
+
- `assets/example-uml-class.html` — minimal light
|
|
64
|
+
- `assets/example-uml-class-dark.html` — minimal dark
|
|
65
|
+
- `assets/example-uml-class-full.html` — full editorial
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Venn / Set Overlap
|
|
2
|
+
|
|
3
|
+
**Best for:** intersection of concepts/domains, shared attributes between categories, "where A meets B", ikigai-style frames (desirable × feasible × viable).
|
|
4
|
+
|
|
5
|
+
## Layout conventions
|
|
6
|
+
- **Prefer 2 or 3 circles.** Avoid 4+ (unreadable — use a matrix instead).
|
|
7
|
+
- Circle stroke: 1px hairline, color per-set (ink, muted, soft).
|
|
8
|
+
- Circle fill: very low-opacity tint — `ink @ 0.04` for the ink set, `muted @ 0.05` for the muted one. Tints compound naturally in overlap regions.
|
|
9
|
+
- Radii: equal when sets are comparable in size; proportional when sets are meaningfully different. Don't fake equal sizes for aesthetics.
|
|
10
|
+
- **Set labels** placed outside the circle, NEVER crossing the stroke. `node-name` role 12–14px 600 for the set name, optional `sublabel` role 9px.
|
|
11
|
+
- **Intersection labels** placed inside the overlap region, `node-name` role 12px 600, centered. For small overlaps, use a leader line to a label in clear space.
|
|
12
|
+
- **Coral accent** on the ONE focal intersection — the "sweet spot". Either an `accent` label stroke OR a clipPath-bounded `accent @ 0.10` fill tint.
|
|
13
|
+
- Circle centers and radii divisible by 4.
|
|
14
|
+
|
|
15
|
+
## Anti-patterns
|
|
16
|
+
- Unlabeled regions — reader can't tell which set is which.
|
|
17
|
+
- Circles that don't overlap when overlap is the point.
|
|
18
|
+
- Equal-sized circles when sets are obviously different (dishonest).
|
|
19
|
+
- Coral on multiple overlap regions (focal signal dies).
|
|
20
|
+
- Labels sitting on top of circle strokes (illegible).
|
|
21
|
+
- 4+ circles where 2–3 would do.
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
- `assets/example-venn.html` — minimal light
|
|
25
|
+
- `assets/example-venn-dark.html` — minimal dark
|
|
26
|
+
- `assets/example-venn-full.html` — full editorial
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Wardley Map
|
|
2
|
+
|
|
3
|
+
**Best for:** positioning the components of a value chain against how evolved (commoditised) each one is, so a reader can see what to build, what to buy, and what is about to move. A strategy artefact, not an architecture diagram — it says nothing about how components connect at runtime, only where each one sits on the genesis-to-commodity curve.
|
|
4
|
+
|
|
5
|
+
## Layout conventions
|
|
6
|
+
|
|
7
|
+
- **Y axis — value chain.** `Visible to the user` at the top, down to `Invisible` at the bottom. Label the axis as stacked separate `<text>` lines flanking the axis endpoints — **never `writing-mode`** to rotate a label vertically. Axis line `rule-solid` at `0.20` opacity.
|
|
8
|
+
- **X axis — evolution.** Four bands separated by three vertical hairlines: `Genesis | Custom-built | Product | Commodity`. Band separators are `rule` at `0.10` opacity, dashed `4,4`. Band labels sit along the bottom axis: `eyebrow` role 8px, uppercase, tracked, `muted`. Axis line `rule-solid` at `0.20` opacity.
|
|
9
|
+
- **Components** are a small circle `r=6`, filled `paper` with an `ink` 1px stroke. Label in the `node-name` role, 12px, weight 600, placed 12px above the dot, `text-anchor="middle"`. An optional `sublabel`-role 9px `muted` sublabel can sit under the dot for a technical qualifier — use sparingly.
|
|
10
|
+
- **Dependency links** are thin `muted` 0.8px straight lines from a component down to the component it depends on. **These are the one documented exemption from §6 rule 1 (mandatory orthogonal elbows) — dependency links only.** A component's y/x position on this map *is* the data; forcing it onto an axis to make an elbow route work would misplace it. No arrowhead — the line itself states the dependency.
|
|
11
|
+
- **Movement** — a component that is evolving carries a short right-pointing arrow: `accent`, dashed `5,4`, `marker-end="url(#arrow-accent)"`, running from the dot's edge toward the next band. The arrow needs no on-arrow text label: the legend's "Evolving" swatch (accent dot + dashed accent arrow) already names what accent + dashes mean, and since arrows on this map can only ever point right (see Anti-patterns — a left-pointing movement arrow is a contradiction, not a design choice), the direction itself already says "toward commodity." A bare word like `COMMODITISING` restates what shape and color already signal — apply §1's remove test: can I remove this label, does color or shape already carry it? Here it does, so the label is the thing that goes, not its position.
|
|
12
|
+
An on-arrow label is legitimate only when it qualifies something the arrow *can't* express on its own — a timeframe (`BY Q3`), a driver (`VENDOR LOCK-IN`) — never a restatement of direction. If you add one, mask it, `arrow-label` role 8px, 6–10px clear of the stroke, same masking rule as any arrow label (§6 rule 2), and confirm there's runway for the mask first: the space directly around a component's dot is usually the most congested spot on the map, because that's also where its own dependency links fan out. Worked example — the moving component in `example-wardley.html` sits at `(420,156)` with links fanning to `(620,220)` and `(680,252)`; at the mandatory 6–10px gap band below the arrow (`y=164–176`), those two lines cross at `x=441.7–482.5` and `x=445–482.5` respectively — almost the full width of the arrow's own span (`x=428–504`), leaving no clear pocket wide enough for a label. Above the dot is no better: the component's own name label already occupies that band per the 12px-above-dot convention. Check both bands for interference before adding a movement label; if neither is clear, don't add one — the legend already covers it.
|
|
13
|
+
- **Focal rule:** the 2 accent elements on this type are the moving component's dot (`accent-tint` fill, `accent` stroke) and its movement arrow — or two moving components sharing those 2 accent slots with no other accent anywhere else on the map.
|
|
14
|
+
- **Legend:** horizontal strip at the bottom, hairline separator above it, viewBox extended ~60px — same as every other type.
|
|
15
|
+
|
|
16
|
+
## Complexity budget
|
|
17
|
+
|
|
18
|
+
| Limit | Rule |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Max components | 9 |
|
|
21
|
+
| Max dependency links | 12 |
|
|
22
|
+
| Max movement arrows | 2 |
|
|
23
|
+
| Max accent elements | 2 |
|
|
24
|
+
|
|
25
|
+
## Anti-patterns
|
|
26
|
+
|
|
27
|
+
- **Treating the x axis as a maturity score.** Evolution is four qualitative bands (genesis / custom-built / product / commodity), not a 0–10 slider. Don't plot a component at "6.5" — place it in a band.
|
|
28
|
+
- **A component with no dependency link.** If nothing in the value chain depends on it and it depends on nothing, it isn't part of the chain — delete it or wire it in.
|
|
29
|
+
- **Arrows drawn right-to-left.** Evolution only moves toward commodity. A left-pointing movement arrow is a contradiction, not a design choice.
|
|
30
|
+
- **Using the map as an architecture diagram.** No request/response direction, no protocols, no runtime topology — that's the architecture type. This type answers "what's worth building vs. buying," not "how does traffic flow."
|
|
31
|
+
- **Numbering the y axis.** Value-chain visibility is ordinal (more visible to the user, less visible), not a quantity. Numeric ticks imply a measurement that doesn't exist.
|
|
32
|
+
- **More than 2 movement arrows.** Beyond that the map stops making a single point and turns into a forecast nobody can act on.
|
|
33
|
+
- **`writing-mode` vertical axis text.** Stack the words as separate horizontal `<text>` lines instead — see Layout conventions above.
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
- `assets/example-wardley.html` — minimal light. AI assistant product, agent orchestration commoditising toward Product.
|
|
38
|
+
- `assets/example-wardley-dark.html` — minimal dark, same map.
|
|
39
|
+
- `assets/example-wardley-full.html` — full editorial: framed container + 3 varied-width cards (the moving component, a genesis-stage build, and the commodity base).
|