create-yss-spec 3.5.2 → 3.5.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 (438) hide show
  1. package/package.json +1 -1
  2. package/src/template/asset-runtime.js +3 -1
  3. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  4. package/template/.agents/skills/codebase-design/SKILL.md +4 -0
  5. package/template/{.codex/skills/improve-codebase-architecture/SKILL.md → .agents/skills/codebase-design/references/architecture-audit.md} +3 -9
  6. package/template/.agents/skills/frontend-commit/SKILL.md +4 -93
  7. package/template/.agents/skills/git-commit-core/SKILL.md +18 -0
  8. package/template/.agents/skills/java-backend-commit/SKILL.md +4 -96
  9. package/template/.agents/skills/llm-wiki/SKILL.md +12 -13
  10. package/template/.agents/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  11. package/template/.agents/skills/llm-wiki/references/compile.md +21 -114
  12. package/template/.agents/skills/llm-wiki/references/ingest.md +8 -33
  13. package/template/.agents/skills/llm-wiki/references/lint.md +9 -46
  14. package/template/.agents/skills/llm-wiki/references/query.md +9 -18
  15. package/template/.agents/skills/llm-wiki/references/schema.md +56 -29
  16. package/template/.agents/skills/llm-wiki/references/transactions.md +48 -0
  17. package/template/.agents/skills/llm-wiki/references/writing.md +4 -4
  18. package/template/.agents/skills/llm-wiki/scripts/advise.mjs +46 -58
  19. package/template/.agents/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  20. package/template/.agents/skills/llm-wiki/scripts/core.mjs +262 -0
  21. package/template/.agents/skills/llm-wiki/scripts/extract.mjs +35 -18
  22. package/template/.agents/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  23. package/template/.agents/skills/llm-wiki/scripts/feedback.mjs +51 -0
  24. package/template/.agents/skills/llm-wiki/scripts/inventory.mjs +43 -171
  25. package/template/.agents/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  26. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  27. package/template/.agents/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  28. package/template/.agents/skills/llm-wiki/scripts/migrate.mjs +51 -0
  29. package/template/.agents/skills/llm-wiki/scripts/query.mjs +149 -0
  30. package/template/.agents/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  31. package/template/.agents/skills/llm-wiki/scripts/sources.mjs +166 -0
  32. package/template/.agents/skills/llm-wiki/scripts/transaction.mjs +384 -0
  33. package/template/.agents/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  34. package/template/.agents/skills/prototype/LOGIC.md +1 -1
  35. package/template/.agents/skills/prototype/SKILL.md +5 -19
  36. package/template/.agents/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  37. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  38. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  39. package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  40. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +8 -8
  41. package/template/.agents/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  42. package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  43. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  44. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  45. package/template/.agents/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  46. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +1 -1
  47. package/template/.agents/skills/yss-research/SKILL.md +4 -0
  48. package/template/.codex/skills/codebase-design/SKILL.md +4 -0
  49. package/template/{.pi/skills/improve-codebase-architecture/SKILL.md → .codex/skills/codebase-design/references/architecture-audit.md} +3 -9
  50. package/template/.codex/skills/frontend-commit/SKILL.md +4 -93
  51. package/template/.codex/skills/git-commit-core/SKILL.md +18 -0
  52. package/template/.codex/skills/java-backend-commit/SKILL.md +4 -96
  53. package/template/.codex/skills/llm-wiki/SKILL.md +12 -13
  54. package/template/.codex/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  55. package/template/.codex/skills/llm-wiki/references/compile.md +21 -114
  56. package/template/.codex/skills/llm-wiki/references/ingest.md +8 -33
  57. package/template/.codex/skills/llm-wiki/references/lint.md +9 -46
  58. package/template/.codex/skills/llm-wiki/references/query.md +9 -18
  59. package/template/.codex/skills/llm-wiki/references/schema.md +56 -29
  60. package/template/.codex/skills/llm-wiki/references/transactions.md +48 -0
  61. package/template/.codex/skills/llm-wiki/references/writing.md +4 -4
  62. package/template/.codex/skills/llm-wiki/scripts/advise.mjs +46 -58
  63. package/template/.codex/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  64. package/template/.codex/skills/llm-wiki/scripts/core.mjs +262 -0
  65. package/template/.codex/skills/llm-wiki/scripts/extract.mjs +35 -18
  66. package/template/.codex/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  67. package/template/.codex/skills/llm-wiki/scripts/feedback.mjs +51 -0
  68. package/template/.codex/skills/llm-wiki/scripts/inventory.mjs +43 -171
  69. package/template/.codex/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  70. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  71. package/template/.codex/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  72. package/template/.codex/skills/llm-wiki/scripts/migrate.mjs +51 -0
  73. package/template/.codex/skills/llm-wiki/scripts/query.mjs +149 -0
  74. package/template/.codex/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  75. package/template/.codex/skills/llm-wiki/scripts/sources.mjs +166 -0
  76. package/template/.codex/skills/llm-wiki/scripts/transaction.mjs +384 -0
  77. package/template/.codex/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  78. package/template/.codex/skills/prototype/LOGIC.md +1 -1
  79. package/template/.codex/skills/prototype/SKILL.md +5 -19
  80. package/template/.codex/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  81. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  82. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  83. package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  84. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +8 -8
  85. package/template/.codex/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  86. package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  87. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  88. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  89. package/template/.codex/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  90. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +1 -1
  91. package/template/.codex/skills/yss-research/SKILL.md +4 -0
  92. package/template/.cursor/skills/codebase-design/SKILL.md +4 -0
  93. package/template/.cursor/skills/{improve-codebase-architecture/SKILL.md → codebase-design/references/architecture-audit.md} +3 -9
  94. package/template/.cursor/skills/frontend-commit/SKILL.md +4 -93
  95. package/template/.cursor/skills/git-commit-core/SKILL.md +18 -0
  96. package/template/.cursor/skills/java-backend-commit/SKILL.md +4 -96
  97. package/template/.cursor/skills/llm-wiki/SKILL.md +12 -13
  98. package/template/.cursor/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  99. package/template/.cursor/skills/llm-wiki/references/compile.md +21 -114
  100. package/template/.cursor/skills/llm-wiki/references/ingest.md +8 -33
  101. package/template/.cursor/skills/llm-wiki/references/lint.md +9 -46
  102. package/template/.cursor/skills/llm-wiki/references/query.md +9 -18
  103. package/template/.cursor/skills/llm-wiki/references/schema.md +56 -29
  104. package/template/.cursor/skills/llm-wiki/references/transactions.md +48 -0
  105. package/template/.cursor/skills/llm-wiki/references/writing.md +4 -4
  106. package/template/.cursor/skills/llm-wiki/scripts/advise.mjs +46 -58
  107. package/template/.cursor/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  108. package/template/.cursor/skills/llm-wiki/scripts/core.mjs +262 -0
  109. package/template/.cursor/skills/llm-wiki/scripts/extract.mjs +35 -18
  110. package/template/.cursor/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  111. package/template/.cursor/skills/llm-wiki/scripts/feedback.mjs +51 -0
  112. package/template/.cursor/skills/llm-wiki/scripts/inventory.mjs +43 -171
  113. package/template/.cursor/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  114. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  115. package/template/.cursor/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  116. package/template/.cursor/skills/llm-wiki/scripts/migrate.mjs +51 -0
  117. package/template/.cursor/skills/llm-wiki/scripts/query.mjs +149 -0
  118. package/template/.cursor/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  119. package/template/.cursor/skills/llm-wiki/scripts/sources.mjs +166 -0
  120. package/template/.cursor/skills/llm-wiki/scripts/transaction.mjs +384 -0
  121. package/template/.cursor/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  122. package/template/.cursor/skills/prototype/LOGIC.md +1 -1
  123. package/template/.cursor/skills/prototype/SKILL.md +5 -19
  124. package/template/.cursor/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  125. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  126. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  127. package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  128. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +8 -8
  129. package/template/.cursor/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  130. package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  131. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  132. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  133. package/template/.cursor/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  134. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +1 -1
  135. package/template/.cursor/skills/yss-research/SKILL.md +4 -0
  136. package/template/.pi/skills/codebase-design/SKILL.md +4 -0
  137. package/template/{.agents/skills/improve-codebase-architecture/SKILL.md → .pi/skills/codebase-design/references/architecture-audit.md} +3 -9
  138. package/template/.pi/skills/frontend-commit/SKILL.md +4 -93
  139. package/template/.pi/skills/git-commit-core/SKILL.md +18 -0
  140. package/template/.pi/skills/java-backend-commit/SKILL.md +4 -96
  141. package/template/.pi/skills/llm-wiki/SKILL.md +12 -13
  142. package/template/.pi/skills/llm-wiki/assets/CLAUDE.md.template +7 -1
  143. package/template/.pi/skills/llm-wiki/references/compile.md +21 -114
  144. package/template/.pi/skills/llm-wiki/references/ingest.md +8 -33
  145. package/template/.pi/skills/llm-wiki/references/lint.md +9 -46
  146. package/template/.pi/skills/llm-wiki/references/query.md +9 -18
  147. package/template/.pi/skills/llm-wiki/references/schema.md +56 -29
  148. package/template/.pi/skills/llm-wiki/references/transactions.md +48 -0
  149. package/template/.pi/skills/llm-wiki/references/writing.md +4 -4
  150. package/template/.pi/skills/llm-wiki/scripts/advise.mjs +46 -58
  151. package/template/.pi/skills/llm-wiki/scripts/advise.test.mjs +11 -16
  152. package/template/.pi/skills/llm-wiki/scripts/core.mjs +262 -0
  153. package/template/.pi/skills/llm-wiki/scripts/extract.mjs +35 -18
  154. package/template/.pi/skills/llm-wiki/scripts/extract.test.mjs +5 -8
  155. package/template/.pi/skills/llm-wiki/scripts/feedback.mjs +51 -0
  156. package/template/.pi/skills/llm-wiki/scripts/inventory.mjs +43 -171
  157. package/template/.pi/skills/llm-wiki/scripts/inventory.test.mjs +25 -18
  158. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.mjs +69 -92
  159. package/template/.pi/skills/llm-wiki/scripts/lint-wikilinks.test.mjs +25 -37
  160. package/template/.pi/skills/llm-wiki/scripts/migrate.mjs +51 -0
  161. package/template/.pi/skills/llm-wiki/scripts/query.mjs +149 -0
  162. package/template/.pi/skills/llm-wiki/scripts/regressions.test.mjs +101 -0
  163. package/template/.pi/skills/llm-wiki/scripts/sources.mjs +166 -0
  164. package/template/.pi/skills/llm-wiki/scripts/transaction.mjs +384 -0
  165. package/template/.pi/skills/llm-wiki/scripts/v2.test.mjs +354 -0
  166. package/template/.pi/skills/prototype/LOGIC.md +1 -1
  167. package/template/.pi/skills/prototype/SKILL.md +5 -19
  168. package/template/.pi/skills/setup-matt-pocock-skills/SKILL.md +3 -3
  169. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +2 -0
  170. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +2 -3
  171. package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +14 -0
  172. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +8 -8
  173. package/template/.pi/skills/yss-product-lifecycle/references/external-input-questionnaire.md +19 -0
  174. package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +5 -5
  175. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +20 -4
  176. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
  177. package/template/.pi/skills/yss-product-lifecycle/references/plan-requirements.md +10 -0
  178. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +1 -1
  179. package/template/.pi/skills/yss-research/SKILL.md +4 -0
  180. package/template/.template-spec/agents/README.md +1 -1
  181. package/template/.template-spec/agents/digital-human-roles.yaml +1 -1
  182. package/template/.template-spec/agents/skill-migrations.md +15 -0
  183. package/template/.template-spec/agents/yss-skill-registry.yaml +10 -29
  184. package/template/.template-spec/architecture/README.md +3 -34
  185. package/template/.template-spec/plan/templates/competitive-analysis-template.md +2 -2
  186. package/template/.template-spec/process/contract-reading.md +24 -0
  187. package/template/.template-spec/process/lifecycle-registry-baseline.json +3 -1
  188. package/template/.template-spec/process/lifecycle-registry.yaml +6 -0
  189. package/template/.template-spec/process/research-completion.md +23 -0
  190. package/template/.template-spec/process/schemas/digital-human-task-package.schema.json +202 -12
  191. package/template/.template-spec/process/schemas/frontend-implementation-evidence.schema.json +7 -15
  192. package/template/.template-spec/process/subagent-collaboration.md +8 -0
  193. package/template/.template-spec/process/templates/frontend-implementation-verification-template.yaml +15 -1
  194. package/template/AGENTS.md +1 -1
  195. package/template/CONTEXT.md +5 -1
  196. package/template/README.md +12 -24
  197. package/template/scripts/contract +5 -5
  198. package/template/scripts/lib/contract-views.mjs +57 -2
  199. package/template/scripts/lib/execution-evidence.mjs +51 -0
  200. package/template/scripts/lib/harness-execution-scope.mjs +1 -1
  201. package/template/scripts/lib/implementation-contract-compiler.mjs +2 -0
  202. package/template/scripts/lib/lifecycle-context-query.mjs +15 -3
  203. package/template/scripts/lib/lifecycle-status.mjs +32 -6
  204. package/template/scripts/lib/lifecycle-transition.mjs +19 -1
  205. package/template/scripts/lib/maintenance-research.mjs +63 -0
  206. package/template/scripts/lib/read-only-intake.mjs +132 -0
  207. package/template/scripts/lib/skill-registry.mjs +2 -1
  208. package/template/scripts/lib/skill-supply-chain.mjs +4 -0
  209. package/template/scripts/lib/slice-task-package.mjs +1 -1
  210. package/template/scripts/lib/task-package.mjs +9 -2
  211. package/template/scripts/lifecycle-status +2 -2
  212. package/template/scripts/prepare-read-only-intake +16 -0
  213. package/template/scripts/run-read-only-intake +14 -0
  214. package/template/scripts/verify-digital-human-task-package +2 -2
  215. package/template/scripts/verify-frontend-implementation-evidence +24 -1
  216. package/template/scripts/verify-maintenance-research +13 -0
  217. package/template/skills-lock.json +19 -76
  218. package/template.manifest.json +118 -29
  219. package/template.snapshot.json +5 -6
  220. package/template/.agents/skills/grill-with-docs/SKILL.md +0 -20
  221. package/template/.agents/skills/grill-with-docs/agents/openai.yaml +0 -5
  222. package/template/.agents/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  223. package/template/.agents/skills/prototype/UI.md +0 -112
  224. package/template/.agents/skills/setup-matt-pocock-skills/domain.md +0 -37
  225. package/template/.agents/skills/to-questionnaire/SKILL.md +0 -55
  226. package/template/.agents/skills/to-questionnaire/agents/openai.yaml +0 -5
  227. package/template/.agents/skills/wait-what/SKILL.md +0 -7
  228. package/template/.agents/skills/wait-what/agents/openai.yaml +0 -5
  229. package/template/.codex/skills/data-analytics/.app.json +0 -84
  230. package/template/.codex/skills/data-analytics/.codex-plugin/plugin.json +0 -66
  231. package/template/.codex/skills/data-analytics/.mcp.json +0 -30
  232. package/template/.codex/skills/data-analytics/AGENTS.md +0 -20
  233. package/template/.codex/skills/data-analytics/DEPENDENCIES.MD +0 -27
  234. package/template/.codex/skills/data-analytics/README.md +0 -60
  235. package/template/.codex/skills/data-analytics/__yss_dotfile__.gitignore +0 -2
  236. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html +0 -16
  237. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part001 +0 -1
  238. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part002 +0 -1
  239. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part003 +0 -1
  240. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part004 +0 -1
  241. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part005 +0 -1
  242. package/template/.codex/skills/data-analytics/assets/datascience-artifact-widget.html.gz.b64.part006 +0 -1
  243. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html +0 -16
  244. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part001 +0 -1
  245. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part002 +0 -1
  246. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part003 +0 -1
  247. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part004 +0 -1
  248. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part005 +0 -1
  249. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part006 +0 -1
  250. package/template/.codex/skills/data-analytics/assets/datascience-chart-widget.html.gz.b64.part007 +0 -1
  251. package/template/.codex/skills/data-analytics/assets/datascience-small.svg +0 -5
  252. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html +0 -16
  253. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part001 +0 -1
  254. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part002 +0 -1
  255. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part003 +0 -1
  256. package/template/.codex/skills/data-analytics/assets/datascience-table-widget.html.gz.b64.part004 +0 -1
  257. package/template/.codex/skills/data-analytics/assets/datascience.png +0 -0
  258. package/template/.codex/skills/data-analytics/assets/datascience.svg +0 -10
  259. package/template/.codex/skills/data-analytics/mcp/server.cjs +0 -2964
  260. package/template/.codex/skills/data-analytics/package-lock.json +0 -3048
  261. package/template/.codex/skills/data-analytics/package.json +0 -43
  262. package/template/.codex/skills/data-analytics/scripts/normalize-widget-assets.mjs +0 -75
  263. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +0 -137
  264. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/agents/openai.yaml +0 -6
  265. package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +0 -29
  266. package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +0 -148
  267. package/template/.codex/skills/data-analytics/skills/build-dashboard/agents/openai.yaml +0 -6
  268. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/bi-platform-dashboard.md +0 -18
  269. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/html-dashboard.md +0 -24
  270. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/mcp-artifact-dashboard.md +0 -71
  271. package/template/.codex/skills/data-analytics/skills/build-dashboard/specifications/streamlit-dashboard.md +0 -85
  272. package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +0 -207
  273. package/template/.codex/skills/data-analytics/skills/build-report/agents/openai.yaml +0 -6
  274. package/template/.codex/skills/data-analytics/skills/build-report/assets/executive-report-shell.html +0 -70
  275. package/template/.codex/skills/data-analytics/skills/build-report/assets/technical-report-shell.html +0 -66
  276. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +0 -108
  277. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/agents/openai.yaml +0 -6
  278. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/__init__.py +0 -1
  279. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +0 -52
  280. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/constants.py +0 -61
  281. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/docx_writer.py +0 -362
  282. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/html_parser.py +0 -829
  283. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/model.py +0 -30
  284. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +0 -127
  285. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/quality.py +0 -374
  286. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/rendering.py +0 -613
  287. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/table_utils.py +0 -54
  288. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/utils.py +0 -16
  289. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc_plan.py +0 -9
  290. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +0 -45
  291. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +0 -77
  292. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/agents/openai.yaml +0 -6
  293. package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/scripts/report_to_google_slides.py +0 -2379
  294. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +0 -88
  295. package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/agents/openai.yaml +0 -6
  296. package/template/.codex/skills/data-analytics/skills/build-report/specifications/executive-report.md +0 -97
  297. package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +0 -59
  298. package/template/.codex/skills/data-analytics/skills/build-report/specifications/technical-report.md +0 -75
  299. package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +0 -103
  300. package/template/.codex/skills/data-analytics/skills/design-kpis/agents/openai.yaml +0 -6
  301. package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +0 -68
  302. package/template/.codex/skills/data-analytics/skills/gather-business-context/agents/openai.yaml +0 -6
  303. package/template/.codex/skills/data-analytics/skills/index/SKILL.md +0 -251
  304. package/template/.codex/skills/data-analytics/skills/index/agents/openai.yaml +0 -6
  305. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +0 -131
  306. package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/agents/openai.yaml +0 -6
  307. package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +0 -141
  308. package/template/.codex/skills/data-analytics/skills/kpi-reporting/agents/openai.yaml +0 -6
  309. package/template/.codex/skills/data-analytics/skills/kpi-reporting/references/report-templates.md +0 -32
  310. package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +0 -106
  311. package/template/.codex/skills/data-analytics/skills/market-sizing/agents/openai.yaml +0 -6
  312. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +0 -130
  313. package/template/.codex/skills/data-analytics/skills/metric-diagnostics/agents/openai.yaml +0 -6
  314. package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +0 -141
  315. package/template/.codex/skills/data-analytics/skills/product-business-analysis/agents/openai.yaml +0 -6
  316. package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +0 -178
  317. package/template/.codex/skills/data-analytics/skills/spreadsheets/agents/openai.yaml +0 -9
  318. package/template/.codex/skills/data-analytics/skills/spreadsheets/assets/file-spreadsheet.png +0 -0
  319. package/template/.codex/skills/data-analytics/skills/spreadsheets/charts.md +0 -31
  320. package/template/.codex/skills/data-analytics/skills/spreadsheets/references/artifact_tool_api.md +0 -466
  321. package/template/.codex/skills/data-analytics/skills/spreadsheets/style_guidelines.md +0 -99
  322. package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +0 -197
  323. package/template/.codex/skills/data-analytics/skills/user-context/agents/openai.yaml +0 -6
  324. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +0 -26
  325. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/source-category-config.json +0 -51
  326. package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/user-context-config.md +0 -66
  327. package/template/.codex/skills/data-analytics/skills/user-context/references/automation.md +0 -69
  328. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +0 -204
  329. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-state-template.json +0 -87
  330. package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +0 -497
  331. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/connector-playbook.md +0 -74
  332. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/setup.md +0 -65
  333. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/skill-template.md +0 -160
  334. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/source-intake.md +0 -75
  335. package/template/.codex/skills/data-analytics/skills/user-context/references/semantic-layer/weekly-polling-automation.md +0 -96
  336. package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +0 -263
  337. package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +0 -1462
  338. package/template/.codex/skills/data-analytics/skills/user-context/scripts/init_user_context_state.py +0 -128
  339. package/template/.codex/skills/data-analytics/skills/user-context/scripts/reset_user_context_state.py +0 -101
  340. package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +0 -499
  341. package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +0 -978
  342. package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +0 -126
  343. package/template/.codex/skills/data-analytics/skills/validate-data/agents/openai.yaml +0 -6
  344. package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +0 -70
  345. package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +0 -157
  346. package/template/.codex/skills/data-analytics/skills/visualize-data/agents/openai.yaml +0 -6
  347. package/template/.codex/skills/data-analytics/skills/visualize-data/references/seaborn-templates.md +0 -774
  348. package/template/.codex/skills/data-analytics/src/DESIGN.md +0 -222
  349. package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +0 -3666
  350. package/template/.codex/skills/data-analytics/src/analytics-app/analytics-layout.test.mjs +0 -136
  351. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartFrame.tsx +0 -54
  352. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartLegend.tsx +0 -96
  353. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartRenderer.tsx +0 -1647
  354. package/template/.codex/skills/data-analytics/src/analytics-app/charting/ChartTooltip.tsx +0 -245
  355. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-app-helpers.tsx +0 -462
  356. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-capabilities.ts +0 -107
  357. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-compatibility.ts +0 -164
  358. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-contract.ts +0 -192
  359. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-theme.ts +0 -203
  360. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-tokens.css +0 -619
  361. package/template/.codex/skills/data-analytics/src/analytics-app/charting/chart-transforms.ts +0 -402
  362. package/template/.codex/skills/data-analytics/src/analytics-app/fonts/SystemSansVariableVF.woff2 +0 -0
  363. package/template/.codex/skills/data-analytics/src/analytics-app/imageExport.ts +0 -370
  364. package/template/.codex/skills/data-analytics/src/analytics-app/layout/AnalyticsLayoutCanvas.tsx +0 -536
  365. package/template/.codex/skills/data-analytics/src/analytics-app/layout/RichMarkdown.tsx +0 -681
  366. package/template/.codex/skills/data-analytics/src/analytics-app/layout/analyticsLayoutCore.ts +0 -164
  367. package/template/.codex/skills/data-analytics/src/analytics-app/main.tsx +0 -21
  368. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/chart_contract.py +0 -472
  369. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/check_analytics_app_runtime_links.py +0 -75
  370. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/design_contract.py +0 -142
  371. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/package_utils.py +0 -142
  372. package/template/.codex/skills/data-analytics/src/analytics-app/scripts/tests/test_package_utils.py +0 -377
  373. package/template/.codex/skills/data-analytics/src/analytics-app/styles.css +0 -3468
  374. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.d.ts +0 -44
  375. package/template/.codex/skills/data-analytics/src/analytics-app/tables/DataTable.jsx +0 -639
  376. package/template/.codex/skills/data-analytics/src/analytics-app/tables/data-table.css +0 -327
  377. package/template/.codex/skills/data-analytics/src/analytics-app/tokens.css +0 -225
  378. package/template/.codex/skills/data-analytics/src/analytics-app/types.ts +0 -204
  379. package/template/.codex/skills/data-analytics/src/analytics-app-core.md +0 -85
  380. package/template/.codex/skills/data-analytics/src/codex-style-contract.md +0 -30
  381. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.html +0 -12
  382. package/template/.codex/skills/data-analytics/src/datascience-artifact-widget.jsx +0 -1008
  383. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.css +0 -2117
  384. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.html +0 -122
  385. package/template/.codex/skills/data-analytics/src/datascience-chart-widget.js +0 -3588
  386. package/template/.codex/skills/data-analytics/src/datascience-table-widget.css +0 -483
  387. package/template/.codex/skills/data-analytics/src/datascience-table-widget.html +0 -32
  388. package/template/.codex/skills/data-analytics/src/datascience-table-widget.js +0 -333
  389. package/template/.codex/skills/data-analytics/src/mcp-host.js +0 -153
  390. package/template/.codex/skills/data-analytics/src/recharts-config.js +0 -315
  391. package/template/.codex/skills/data-analytics/src/recharts-renderer.jsx +0 -294
  392. package/template/.codex/skills/data-analytics/src/sql-source-view.css +0 -33
  393. package/template/.codex/skills/data-analytics/src/sql-source-view.js +0 -157
  394. package/template/.codex/skills/data-analytics/src/styles/codex-theme.css +0 -121
  395. package/template/.codex/skills/data-analytics/src/table-renderer.jsx +0 -28
  396. package/template/.codex/skills/data-analytics/tests/chart-transforms.test.mjs +0 -87
  397. package/template/.codex/skills/data-analytics/tests/funnel-smoke.html +0 -105
  398. package/template/.codex/skills/data-analytics/tests/inline-widget-compare.html +0 -233
  399. package/template/.codex/skills/data-analytics/tests/mcp-server.test.mjs +0 -1500
  400. package/template/.codex/skills/data-analytics/tests/native-style-contract.test.mjs +0 -219
  401. package/template/.codex/skills/data-analytics/tests/recharts-config.test.mjs +0 -144
  402. package/template/.codex/skills/data-analytics/tests/recharts-renderer.test.mjs +0 -11
  403. package/template/.codex/skills/data-analytics/tests/rich-markdown.test.mjs +0 -54
  404. package/template/.codex/skills/data-analytics/tests/widget-render-harness.html +0 -321
  405. package/template/.codex/skills/data-analytics/tsconfig.json +0 -19
  406. package/template/.codex/skills/data-analytics/vite.config.ts +0 -46
  407. package/template/.codex/skills/grill-with-docs/SKILL.md +0 -20
  408. package/template/.codex/skills/grill-with-docs/agents/openai.yaml +0 -5
  409. package/template/.codex/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  410. package/template/.codex/skills/prototype/UI.md +0 -112
  411. package/template/.codex/skills/setup-matt-pocock-skills/domain.md +0 -37
  412. package/template/.codex/skills/to-questionnaire/SKILL.md +0 -55
  413. package/template/.codex/skills/to-questionnaire/agents/openai.yaml +0 -5
  414. package/template/.codex/skills/wait-what/SKILL.md +0 -7
  415. package/template/.codex/skills/wait-what/agents/openai.yaml +0 -5
  416. package/template/.cursor/skills/grill-with-docs/SKILL.md +0 -20
  417. package/template/.cursor/skills/grill-with-docs/agents/openai.yaml +0 -5
  418. package/template/.cursor/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  419. package/template/.cursor/skills/prototype/UI.md +0 -112
  420. package/template/.cursor/skills/setup-matt-pocock-skills/domain.md +0 -37
  421. package/template/.cursor/skills/to-questionnaire/SKILL.md +0 -55
  422. package/template/.cursor/skills/to-questionnaire/agents/openai.yaml +0 -5
  423. package/template/.cursor/skills/wait-what/SKILL.md +0 -7
  424. package/template/.cursor/skills/wait-what/agents/openai.yaml +0 -5
  425. package/template/.pi/skills/grill-with-docs/SKILL.md +0 -20
  426. package/template/.pi/skills/grill-with-docs/agents/openai.yaml +0 -5
  427. package/template/.pi/skills/improve-codebase-architecture/agents/openai.yaml +0 -5
  428. package/template/.pi/skills/prototype/UI.md +0 -112
  429. package/template/.pi/skills/setup-matt-pocock-skills/domain.md +0 -37
  430. package/template/.pi/skills/to-questionnaire/SKILL.md +0 -55
  431. package/template/.pi/skills/to-questionnaire/agents/openai.yaml +0 -5
  432. package/template/.pi/skills/wait-what/SKILL.md +0 -7
  433. package/template/.pi/skills/wait-what/agents/openai.yaml +0 -5
  434. package/template/.template-spec/agents/domain.md +0 -31
  435. /package/template/.agents/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  436. /package/template/.codex/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  437. /package/template/.cursor/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
  438. /package/template/.pi/skills/{improve-codebase-architecture → codebase-design/references}/HTML-REPORT.md +0 -0
@@ -1,774 +0,0 @@
1
- # Seaborn Templates
2
-
3
- Use this when implementing static charts in Python. Seaborn owns marks;
4
- Matplotlib owns layout, axes, annotations, and export.
5
-
6
- ## How To Use This File
7
-
8
- 1. Choose the family from `../SKILL.md` `Chart Selection`.
9
- 2. Pick the lightest variant below that answers the question.
10
- 3. Apply shared style before chart-specific tweaks.
11
- 4. Export SVG and PNG.
12
- 5. Inspect in the final notebook, report, dashboard, or slide.
13
-
14
- ## Canonical Family Map
15
-
16
- - `Tables & Scorecards`: HTML layer, not Seaborn.
17
- - `Trend`: Trend Line, Highlighted Multi-Series Trend, Stacked Area,
18
- Overlapping Area, Small Multiples.
19
- - `Comparison & Ranking`: Grouped Column Bars, Ranked Horizontal Bars,
20
- Diverging Horizontal Bars, Dot Reference Comparison, Concentration / Pareto.
21
- - `Composition`: Stacked Horizontal Bars, Pie Chart.
22
- - `Distribution`: Histogram / KDE, Grouped Distribution Comparison.
23
- - `Relationship`: Scatter, Bubble Chart, Scatter / Density.
24
- - `Uncertainty & Benchmark`: Ordered Line & Dot, Faceted Dot & Interval,
25
- Experiment Lift With Confidence Intervals.
26
- - `Matrix & Cohort`: Heatmap.
27
- - `Decomposition & Progression`: Funnel Stage Bars, Waterfall Bridge.
28
-
29
- ## Shared Style Guidance
30
-
31
- Use this section for every chart. The recipes name form; this section owns visual decisions.
32
-
33
- ### Build Sequence
34
-
35
- Use this order:
36
-
37
- 1. `Format`: family and delivery surface.
38
- 2. `Structure`: title, subtitle, axes, labels, annotations, removals.
39
- 3. `Colors`: smallest readable set of palette roots.
40
-
41
- If the chart feels busy, revisit `Format` or `Structure`; do not add colors,
42
- heavier strokes, or extra decoration.
43
-
44
- ### Palette
45
-
46
- Choose a palette policy before plotting. Use only approved roots, explicit maps, neutrals, and shades. Never use default categorical colors for shipped charts.
47
-
48
- Policy classes:
49
-
50
- - `Single-root preferred`: one non-neutral root plus shades and neutrals. Use for simple trends, ranks, distributions, relationships,
51
- heatmaps, intervals, experiment lift, and comparable small multiples.
52
- - `Hard two-root cap`: at most two non-neutral roots plus neutrals. Use for binary, signed, focal-vs-context, benchmark, Pareto, overlapping area,
53
- highlighted trend, ordered line-dot, and waterfall charts.
54
- - `Relaxed multi-category`: up to five approved roots when category identity matters. Use for pie, stacked bars/area, grouped bars, and stage bars.
55
- With more than five categories, group to top-N plus Other or change form.
56
-
57
- Shades and neutral comparator fills do not count as roots. Separate series with tone, open fill, marker fill, line style, direct labels, ordering, or faceting.
58
- Do not ship visually identical fills for adjacent or overlapping marks.
59
- Use each selected root's `base` tone, the middle swatch of the five-color row,
60
- as the default non-neutral mark color for shipped charts. Use `dark` for keylines, outlines, labels, or reference strokes; use `light`, `xlight`, or `open` for supporting fills.
61
-
62
- | Family | XLight | Light | Base | Mid | Dark |
63
- |---|---|---|---|---|---|
64
- | Blue | `#EAF1FE` | `#CEDFFE` | `#A3BEFA` | `#5477C4` | `#2E4780` |
65
- | Gold | `#FFF4C2` | `#FFEA8F` | `#FFE15B` | `#B8A037` | `#736422` |
66
- | Orange | `#FFEDDE` | `#FFBDA1` | `#F0986E` | `#CC6F47` | `#804126` |
67
- | Olive | `#D8ECBD` | `#BEEB96` | `#A3D576` | `#71B436` | `#386411` |
68
- | Pink | `#FCDAD6` | `#F5BACC` | `#F390CA` | `#BD569B` | `#8A3A6F` |
69
-
70
- - Use `Blue` for general product or KPI charts.
71
- - Use `Gold` for model/eval examples with no subject color.
72
- - Use `Orange`, `Olive`, or `Pink` when the subject or report points there.
73
- - Calls with `hue`, grouped marks, multiple lines, `stackplot`, `pie`, grouped distributions, or colormaps must pass explicit palette/color maps.
74
- - Prefer `base` for primary fills, lines, dots, and legend swatches. Treat `mid` as an exception for cases that need extra contrast.
75
- - For positive/negative states, use dark vs open/light fills, signed labels,
76
- and zero-line context; use green/red only for documented domain semantics.
77
-
78
- ### Semantic Tokens
79
-
80
- | Token | Value | Use |
81
- |---|---:|---|
82
- | `surface` | `#FCFCFD` | page or figure background |
83
- | `panel` | `#FFFFFF` | chart panel and axes background |
84
- | `ink` | `#1F2430` | titles, primary labels, reference lines |
85
- | `muted` | `#6F768A` | subtitles, notes, secondary ticks |
86
- | `grid` | `#E6E8F0` | quiet grid lines and dotted plot areas |
87
- | `axis` | `#D7DBE7` | visible left/bottom axis bars |
88
-
89
- Use dark-neutral calibration, benchmark, reference, and ideal lines.
90
-
91
- Neutral comparator fills:
92
-
93
- | Token | Value | Use |
94
- |---|---:|---|
95
- | `neutral_xlight` | `#F4F5F7` | open comparator fills |
96
- | `neutral_light` | `#E2E5EA` | secondary comparator fills |
97
- | `neutral_base` | `#C5CAD3` | dense comparator fills or disabled states |
98
- | `neutral_mid` | `#7A828F` | comparator outlines and labels |
99
- | `neutral_dark` | `#464C55` | high-contrast comparator keylines |
100
-
101
- ### Typography And Naming
102
-
103
- - Use a sans stack for titles, subtitles, axis titles, legends, and notes.
104
- - Use a mono stack for numeric tick labels, direct value labels, benchmark labels, and compact callouts.
105
- - Every shipped chart must have a visible title and subtitle.
106
- - Use sentence case for short takeaway titles.
107
- - Put metric scope in subtitles: unit, denominator, date range, cohort, filters,
108
- confidence level, or benchmark.
109
- - Use title case for short axis labels.
110
- - Use sentence case for subtitles, notes, and analytical questions.
111
- - Preserve model names exactly: `GPT-4o`, `o3-mini`, `o1`, `o1-mini`, `Sora`.
112
- - Do not shrink type to fix layout. Widen, wrap, facet, or split.
113
-
114
- ### Labels, Legends, And Callouts
115
-
116
- - Align title, subtitle, and top legend to the same left edge.
117
- - Prefer direct labels when they reduce lookup.
118
- - Use a compact top legend when direct labels collide.
119
- - Keep value labels near marks with a clear gutter.
120
- - Put pie labels outside. If labels collide, use a right-side list.
121
- - Use callouts sparingly; anchor them to data points.
122
-
123
- ### Axes, Grids, And Plot Area
124
-
125
- - Use one stroke width per chart; do not encode emphasis with thickness.
126
- - Web/static chart default: `1px` visual stroke.
127
- - Deck export default: `1.5px` visual stroke.
128
- - Keep keylines on filled marks and shapes.
129
- - Do not use gradients inside chart marks.
130
- - Use white or near-white backgrounds unless the whole artifact is dark.
131
- - For line, area, and line-dot charts, keep left and bottom axis bars visible.
132
- - Use dotted plot areas only for line, area, or line-dot charts.
133
- - For bar charts, keep grid lines quiet and only on the value axis.
134
- - For datetime x-axes, use `format_date_axis(ax)` after plotting so tick labels stay concise and do not overlap.
135
-
136
- ### Mark Styling
137
-
138
- - Bars: filled marks with keylines; sort unless order matters; use horizontal bars for long labels.
139
- - Use the root `base` tone for primary fills and line marks. Use `dark` as the keyline or high-contrast reference stroke, not as the default fill.
140
- - Diverging bars: reserve separate zones for category labels, negative value labels, zero line, positive bars, and positive value labels.
141
- - Lines: use declared roots, line style, tone, or labels; remove extra guides.
142
- - Line-dot and interval charts: make dots and whiskers primary; keep connector lines quiet; use dark-neutral benchmark lines.
143
- - Bubbles: area-encode size only when the third metric materially changes the interpretation; include a compact size legend.
144
- - Areas: keep boundary lines above fills, but do not outline the sides or bottom of filled area polygons.
145
- - Pie charts: sort slices, use outside labels, avoid tiny inside labels, and keep labels readable.
146
- - Heatmaps: use a declared sequential scale; annotate only readable cells.
147
-
148
- ### Layout And Export
149
-
150
- - Reserve header space for title and subtitle plus label gutters before plotting.
151
- - Use `add_chart_header(fig, ax, title, subtitle)` for every shipped static chart. Do not mix `ax.set_title(...)` with separate subtitle text.
152
- - Use an 8-column footprint for most standalone HTML charts; widen to 10 or 12 for long labels, dense series, or annotations. Treat 6 columns as the minimum.
153
- - Stack side-by-side charts on mobile; do not invent off-grid widths.
154
- - For shipped branded web outputs, inspect light and dark variants.
155
- - Never compress a chart into a narrow card if labels clip.
156
- - Inspect the exported PNG and final embedded context, not only the raw SVG.
157
-
158
- ## Minimal Implementation Skeleton
159
-
160
- Adapt this skeleton.
161
-
162
- ```python
163
- import matplotlib.pyplot as plt
164
- import matplotlib.dates as mdates
165
- import matplotlib.ticker as mticker
166
- import numpy as np
167
- import seaborn as sns
168
- import textwrap
169
- from matplotlib.patches import Patch
170
-
171
- FONT_FAMILY = ["Aptos", "Inter", "Segoe UI", "DejaVu Sans", "Arial", "sans-serif"]
172
- MONO_FONT_FAMILY = ["SF Mono", "Menlo", "Consolas", "DejaVu Sans Mono", "monospace"]
173
-
174
- TOKENS = {
175
- "surface": "#FCFCFD",
176
- "panel": "#FFFFFF",
177
- "ink": "#1F2430",
178
- "muted": "#6F768A",
179
- "grid": "#E6E8F0",
180
- "axis": "#D7DBE7",
181
- }
182
-
183
- NEUTRAL_MARKS = {
184
- "open": TOKENS["panel"],
185
- "xlight": "#F4F5F7",
186
- "light": "#E2E5EA",
187
- "base": "#C5CAD3",
188
- "mid": "#7A828F",
189
- "dark": "#464C55",
190
- }
191
-
192
- COLOR_FAMILIES = {
193
- "blue": {
194
- "open": TOKENS["panel"],
195
- "xlight": "#EAF1FE",
196
- "light": "#CEDFFE",
197
- "base": "#A3BEFA",
198
- "mid": "#5477C4",
199
- "dark": "#2E4780",
200
- },
201
- "gold": {
202
- "open": TOKENS["panel"],
203
- "xlight": "#FFF4C2",
204
- "light": "#FFEA8F",
205
- "base": "#FFE15B",
206
- "mid": "#B8A037",
207
- "dark": "#736422",
208
- },
209
- "orange": {
210
- "open": TOKENS["panel"],
211
- "xlight": "#FFEDDE",
212
- "light": "#FFBDA1",
213
- "base": "#F0986E",
214
- "mid": "#CC6F47",
215
- "dark": "#804126",
216
- },
217
- "olive": {
218
- "open": TOKENS["panel"],
219
- "xlight": "#D8ECBD",
220
- "light": "#BEEB96",
221
- "base": "#A3D576",
222
- "mid": "#71B436",
223
- "dark": "#386411",
224
- },
225
- "pink": {
226
- "open": TOKENS["panel"],
227
- "xlight": "#FCDAD6",
228
- "light": "#F5BACC",
229
- "base": "#F390CA",
230
- "mid": "#BD569B",
231
- "dark": "#8A3A6F",
232
- },
233
- }
234
-
235
- def palette_from_family(labels, family, tones=("base", "light", "xlight", "open", "base")):
236
- """Return an explicit palette map from one declared palette root."""
237
- labels = list(labels)
238
- tone_list = list(tones)
239
- return {
240
- label: family[tone_list[i % len(tone_list)]]
241
- for i, label in enumerate(labels)
242
- }
243
-
244
-
245
- def add_chart_header(fig, ax, title, subtitle, *, title_width=78, subtitle_width=112) -> None:
246
- """Add a wrapped figure-level title/subtitle and reserve plot space."""
247
- title = str(title).strip()
248
- subtitle = str(subtitle).strip()
249
- if not title or not subtitle:
250
- raise ValueError("Every shipped chart needs a non-empty title and subtitle.")
251
-
252
- title = textwrap.fill(title, width=title_width, break_long_words=False)
253
- subtitle = textwrap.fill(subtitle, width=subtitle_width, break_long_words=False)
254
- title_lines = title.count("\n") + 1
255
- subtitle_lines = subtitle.count("\n") + 1
256
-
257
- ax.set_title("")
258
- fig.subplots_adjust(top=max(0.62, 0.86 - 0.045 * (title_lines - 1) - 0.032 * (subtitle_lines - 1)))
259
-
260
- left = ax.get_position().x0
261
- fig.text(left, 0.985, title, ha="left", va="top", fontsize=13, fontweight="semibold", color=TOKENS["ink"], linespacing=1.08)
262
- fig.text(left, 0.93 - 0.045 * (title_lines - 1), subtitle, ha="left", va="top", fontsize=9, color=TOKENS["muted"], linespacing=1.18)
263
- sns.despine(ax=ax)
264
-
265
-
266
- def format_date_axis(ax, *, max_ticks=6) -> None:
267
- """Keep time axes readable by limiting ticks and using concise labels."""
268
- locator = mdates.AutoDateLocator(minticks=3, maxticks=max_ticks)
269
- ax.xaxis.set_major_locator(locator)
270
- ax.xaxis.set_major_formatter(mdates.ConciseDateFormatter(locator))
271
- ax.tick_params(axis="x", labelrotation=0)
272
-
273
-
274
- def use_chart_theme() -> None:
275
- sns.set_theme(
276
- style="whitegrid",
277
- rc={
278
- "figure.facecolor": TOKENS["surface"],
279
- "figure.edgecolor": "none",
280
- "savefig.facecolor": "none",
281
- "savefig.edgecolor": "none",
282
- "axes.facecolor": TOKENS["panel"],
283
- "axes.edgecolor": TOKENS["axis"],
284
- "axes.labelcolor": TOKENS["ink"],
285
- "axes.grid": True,
286
- "axes.spines.top": False,
287
- "axes.spines.right": False,
288
- "grid.color": TOKENS["grid"],
289
- "grid.linewidth": 0.8,
290
- "font.family": "sans-serif",
291
- "font.sans-serif": FONT_FAMILY,
292
- "font.monospace": MONO_FONT_FAMILY,
293
- "patch.linewidth": 1.0,
294
- },
295
- )
296
- ```
297
-
298
- ## Visualization Templates
299
-
300
- Each template inherits shared style. Snippets assume `fig`, `ax`, `family`,
301
- `title`, `subtitle`, and labels exist; adapt names and sizing. Finish every shipped chart with `add_chart_header(fig, ax, title, subtitle)`. For FacetGrid or multi-axis charts, pass the figure and first primary axis.
302
-
303
- ### Trend Line
304
-
305
- - Use: continuous metric over ordered x.
306
- - Data: sorted x, y.
307
- - Snippet:
308
- ```python
309
- plot_df = df.sort_values(x_col)
310
- sns.lineplot(data=plot_df, x=x_col, y=y_col, ax=ax, color=family["base"], linewidth=1.0)
311
- if np.issubdtype(plot_df[x_col].dtype, np.datetime64):
312
- format_date_axis(ax)
313
- add_chart_header(fig, ax, title, subtitle)
314
- ```
315
-
316
- ### Highlighted Multi-Series Trend
317
-
318
- - Use: focal series with peer context.
319
- - Data: x, y, series, focal flag.
320
- - Snippet:
321
- ```python
322
- peer_families = [NEUTRAL_MARKS, COLOR_FAMILIES["gold"], NEUTRAL_MARKS]
323
- for i, (series, part) in enumerate(df.loc[~df[focal_col]].groupby(series_col)):
324
- peer_family = peer_families[i % len(peer_families)]
325
- sns.lineplot(data=part, x=x_col, y=y_col, ax=ax, color=peer_family["base"], linewidth=1.0, linestyle=["--", ":", "-."][i % 3], label=series)
326
- focal_label = str(df.loc[df[focal_col], series_col].drop_duplicates().iloc[0])
327
- sns.lineplot(data=df.loc[df[focal_col]], x=x_col, y=y_col, ax=ax, color=family["base"], linewidth=1.0, label=focal_label)
328
- if np.issubdtype(df[x_col].dtype, np.datetime64):
329
- format_date_axis(ax)
330
- ax.legend(loc="lower left", bbox_to_anchor=(0, 1.02), frameon=False, ncol=min(df[series_col].nunique(), 4), borderaxespad=0)
331
- add_chart_header(fig, ax, title, subtitle)
332
- ```
333
-
334
- ### Stacked Area
335
-
336
- - Use: additive composition over time.
337
- - Data: x plus additive components, or long data pivoted wide.
338
- - Snippet:
339
- ```python
340
- wide = df.pivot(index=x_col, columns=segment_col, values=value_col).fillna(0).sort_index()
341
- family_cycle = [COLOR_FAMILIES[name] for name in ["blue", "gold", "olive", "pink", "orange"]]
342
- area_families = [family_cycle[i % len(family_cycle)] for i in range(wide.shape[1])]
343
- fills = [area_families[i]["base"] for i in range(wide.shape[1])]
344
- areas = ax.stackplot(wide.index, wide.T.to_numpy(), labels=list(wide.columns), colors=fills, linewidth=0)
345
- lower = np.zeros(len(wide), dtype=float)
346
- for area, values, area_family in zip(areas, wide.T.to_numpy(), area_families):
347
- area.set_edgecolor("none")
348
- area.set_linewidth(0)
349
- upper = lower + values
350
- lower = upper
351
- cumulative = wide.T.to_numpy().cumsum(axis=0)
352
- for boundary, area_family in zip(cumulative, area_families):
353
- ax.plot(wide.index, boundary, color=area_family["dark"], linewidth=1.0, zorder=3.2)
354
- ax.legend(loc="lower left", bbox_to_anchor=(0, 1.02), frameon=False, ncol=min(wide.shape[1], 4), borderaxespad=0)
355
- add_chart_header(fig, ax, title, subtitle)
356
- ```
357
-
358
- ### Overlapping Area
359
-
360
- - Use: overlapping continuous envelopes.
361
- - Data: x plus 2-3 y series.
362
- - Snippet:
363
- ```python
364
- if not 2 <= len(y_cols) <= 3:
365
- raise ValueError("Overlapping area expects two or three y series.")
366
- area_styles = [
367
- # Draw rear envelopes first and the low/base envelope last.
368
- (str(y_cols[1]), y_cols[1], COLOR_FAMILIES["olive"]["base"], COLOR_FAMILIES["olive"]["dark"], COLOR_FAMILIES["olive"]["base"], "-", 0.36, 1.1),
369
- ]
370
- if len(y_cols) == 3:
371
- area_styles.append(
372
- (str(y_cols[2]), y_cols[2], COLOR_FAMILIES["blue"]["base"], COLOR_FAMILIES["blue"]["dark"], COLOR_FAMILIES["blue"]["base"], "-", 0.66, 1.8)
373
- )
374
- area_styles.append(
375
- (str(y_cols[0]), y_cols[0], COLOR_FAMILIES["olive"]["base"], COLOR_FAMILIES["olive"]["dark"], COLOR_FAMILIES["olive"]["base"], "-", 0.72, 3.0)
376
- )
377
- for name, y, fill_color, edge_color, line_color, line_style, fill_alpha, zorder in area_styles:
378
- area = ax.fill_between(
379
- df[x_col], 0, df[y],
380
- color=fill_color, alpha=fill_alpha,
381
- edgecolor="none",
382
- linewidth=0,
383
- zorder=zorder,
384
- )
385
- for name, y, _, _, line_color, line_style, _, _ in area_styles:
386
- ax.plot(df[x_col], df[y], color=line_color, linestyle=line_style, linewidth=1.05, label=name, zorder=5.2)
387
- ax.legend(loc="lower left", bbox_to_anchor=(0, 1.02), frameon=False, ncol=min(len(area_styles), 4), borderaxespad=0)
388
- add_chart_header(fig, ax, title, subtitle)
389
- ```
390
-
391
- ### Small Multiples
392
-
393
- - Use: many trend lines.
394
- - Data: x, y, facet.
395
- - Snippet:
396
- ```python
397
- g = sns.FacetGrid(df, col=facet_col, col_wrap=3, sharex=True, sharey=True)
398
- facet_order = list(df[facet_col].drop_duplicates())
399
- facet_palette = {facet: COLOR_FAMILIES["blue"]["base"] for facet in facet_order}
400
- g.map_dataframe(sns.lineplot, x=x_col, y=y_col, hue=facet_col, palette=facet_palette, legend=False, linewidth=1.0)
401
- g.set_titles("{col_name}", size=8.5)
402
- add_chart_header(g.figure, g.axes.flat[0], title, subtitle)
403
- ```
404
-
405
- ### Grouped Column Bars
406
-
407
- - Use: side-by-side category comparison.
408
- - Data: category, series, value; few categories.
409
- - Snippet:
410
- ```python
411
- series_order = list(df[series_col].drop_duplicates())
412
- category_order = list(df[category_col].drop_duplicates())
413
- x = np.arange(len(category_order))
414
- width = min(0.24, 0.72 / max(len(series_order), 1))
415
- series_families = [COLOR_FAMILIES[name] for name in ["orange", "blue", "olive", "gold", "pink"]]
416
- for i, series in enumerate(series_order):
417
- series_family = series_families[i % len(series_families)]
418
- values = df.loc[df[series_col] == series].set_index(category_col).loc[category_order, value_col].to_numpy()
419
- offset = (i - (len(series_order) - 1) / 2) * width
420
- bars = ax.bar(
421
- x + offset,
422
- values,
423
- width=width,
424
- label=series,
425
- color=series_family["base"],
426
- edgecolor=series_family["dark"],
427
- linewidth=1.0,
428
- )
429
- ax.set_xticks(x, category_order)
430
- ax.legend(loc="lower left", bbox_to_anchor=(0, 1.02), frameon=False, ncol=min(len(series_order), 4), borderaxespad=0)
431
- add_chart_header(fig, ax, title, subtitle)
432
- ```
433
-
434
- ### Ranked Horizontal Bars
435
-
436
- - Use: rank, top-N, long labels.
437
- - Data: category, value; sort unless order matters.
438
- - Snippet:
439
- ```python
440
- plot_df = df.sort_values(value_col, ascending=True)
441
- bar_family = COLOR_FAMILIES["orange"]
442
- palette = palette_from_family(plot_df[category_col], bar_family, tones=("base", "light", "xlight", "open", "base"))
443
- edge_colors = {category: bar_family["dark"] for category in plot_df[category_col]}
444
- sns.barplot(data=plot_df, x=value_col, y=category_col, hue=category_col, palette=palette, legend=False, dodge=False, ax=ax, edgecolor=TOKENS["ink"], linewidth=1.0)
445
- for patch, category in zip(ax.patches, plot_df[category_col]):
446
- patch.set_edgecolor(edge_colors[category])
447
- add_chart_header(fig, ax, title, subtitle)
448
- ```
449
-
450
- ### Diverging Horizontal Bars
451
-
452
- - Use: signed deltas or drivers around zero.
453
- - Data: category, signed value.
454
- - Snippet:
455
- ```python
456
- plot_df = df.sort_values(value_col)
457
- positive_family = COLOR_FAMILIES["olive"]
458
- negative_family = COLOR_FAMILIES["orange"]
459
- colors = np.where(plot_df[value_col] >= 0, positive_family["base"], negative_family["base"])
460
- edge_colors = np.where(plot_df[value_col] >= 0, positive_family["dark"], negative_family["dark"])
461
- bars = ax.barh(plot_df[category_col], plot_df[value_col], color=colors, edgecolor=edge_colors, linewidth=1.0)
462
- neg_min = plot_df.loc[plot_df[value_col] < 0, value_col].min()
463
- pos_max = plot_df.loc[plot_df[value_col] > 0, value_col].max()
464
- neg_label_x = neg_min * 0.74
465
- ax.set_xlim(neg_min * 1.36, pos_max * 1.12)
466
- for bar, value in zip(bars, plot_df[value_col]):
467
- bar.set_edgecolor(positive_family["dark"] if value >= 0 else negative_family["dark"])
468
- label_x = value + 0.25 if value >= 0 else neg_label_x
469
- ax.text(label_x, bar.get_y() + bar.get_height() / 2, f"{value:+.1f}", ha="left", va="center", fontsize=8, color=TOKENS["ink"])
470
- ax.axvline(0, color=TOKENS["ink"], linewidth=1.0)
471
- ax.legend(
472
- handles=[
473
- Patch(facecolor=positive_family["base"], edgecolor=positive_family["dark"], label="Positive"),
474
- Patch(facecolor=negative_family["base"], edgecolor=negative_family["dark"], label="Negative"),
475
- ],
476
- loc="lower left",
477
- bbox_to_anchor=(0, 1.02),
478
- frameon=False,
479
- ncol=2,
480
- borderaxespad=0,
481
- )
482
- add_chart_header(fig, ax, title, subtitle)
483
- ```
484
-
485
- ### Dot Reference Comparison
486
-
487
- - Use: compact target, before/after, or benchmark comparison.
488
- - Data: category, value, optional reference.
489
- - Snippet:
490
- ```python
491
- value_family = COLOR_FAMILIES["orange"]
492
- ax.hlines(df[category_col], df[reference_col], df[value_col], color=NEUTRAL_MARKS["base"], linewidth=1.0, label="Reference gap")
493
- ax.scatter(df[value_col], df[category_col], facecolors=value_family["base"], edgecolors=value_family["dark"], linewidths=1.0, label="Actual")
494
- ax.legend(loc="lower left", bbox_to_anchor=(0, 1.02), frameon=False, ncol=2, borderaxespad=0)
495
- add_chart_header(fig, ax, title, subtitle)
496
- ```
497
-
498
- ### Concentration / Pareto
499
-
500
- - Use: concentration of volume or impact.
501
- - Data: entity, value; derive cumulative share.
502
- - Snippet:
503
- ```python
504
- plot_df = df.sort_values(value_col, ascending=False).head(top_n).assign(cum_share=lambda d: d[value_col].cumsum() / d[value_col].sum())
505
- bar_family = COLOR_FAMILIES["orange"]
506
- line_family = COLOR_FAMILIES["blue"]
507
- sns.barplot(data=plot_df, x=category_col, y=value_col, ax=ax, color=bar_family["base"], edgecolor=bar_family["dark"], linewidth=1.0)
508
- ax2 = ax.twinx()
509
- ax2.grid(False)
510
- ax2.plot(plot_df[category_col], plot_df["cum_share"], color=line_family["base"], linewidth=1.0, marker="o", label="Cumulative share")
511
- ax2.set_ylim(0, 1.05)
512
- ax2.yaxis.set_major_formatter(mticker.PercentFormatter(1.0))
513
- ax2.tick_params(axis="y", colors=TOKENS["muted"], labelsize=8, length=0)
514
- ax2.spines["right"].set_visible(False)
515
- ax.legend(
516
- handles=[
517
- Patch(facecolor=bar_family["base"], edgecolor=bar_family["dark"], label=str(value_col).replace("_", " ").title()),
518
- ax2.lines[0],
519
- ],
520
- loc="lower left",
521
- bbox_to_anchor=(0, 1.02),
522
- frameon=False,
523
- ncol=2,
524
- borderaxespad=0,
525
- )
526
- add_chart_header(fig, ax, title, subtitle)
527
- ```
528
-
529
- ### Stacked Horizontal Bars
530
-
531
- - Use: share-of-total, survey, or Likert buckets.
532
- - Data: group, ordered segment, value or percent.
533
- - Snippet:
534
- ```python
535
- wide = df.pivot_table(index=group_col, columns=segment_col, values=value_col, fill_value=0).reindex(index=group_order, columns=segment_order)
536
- left = np.zeros(len(wide))
537
- segment_families = [COLOR_FAMILIES[name] for name in ["blue", "gold", "olive", "pink", "orange"]]
538
- for i, segment in enumerate(segment_order):
539
- segment_family = segment_families[i % len(segment_families)]
540
- bars = ax.barh(wide.index, wide[segment], left=left, label=segment, color=segment_family["base"], edgecolor=segment_family["dark"], linewidth=1.0)
541
- left += wide[segment].to_numpy()
542
- ax.xaxis.set_major_formatter(mticker.PercentFormatter(100))
543
- ax.legend(loc="lower left", bbox_to_anchor=(0, 1.04), frameon=False, ncol=min(len(segment_order), 4), borderaxespad=0)
544
- add_chart_header(fig, ax, title, subtitle)
545
- ```
546
-
547
- ### Pie Chart
548
-
549
- - Use: rough part-to-whole with few slices.
550
- - Data: category, value.
551
- - Snippet:
552
- ```python
553
- plot_df = df.sort_values(value_col, ascending=False)
554
- slice_families = [COLOR_FAMILIES[name] for name in ["olive", "gold", "blue", "pink", "orange"]]
555
- colors = [slice_families[i % len(slice_families)]["base"] for i in range(len(plot_df))]
556
- wedges, _ = ax.pie(plot_df[value_col], startangle=90, counterclock=False, colors=colors, wedgeprops={"edgecolor": TOKENS["ink"], "linewidth": 1.0})
557
- for i, (wedge, label, value) in enumerate(zip(wedges, plot_df[category_col], plot_df[value_col])):
558
- slice_family = slice_families[i % len(slice_families)]
559
- wedge.set_edgecolor(slice_family["dark"])
560
- angle = np.deg2rad((wedge.theta1 + wedge.theta2) / 2)
561
- ax.text(1.08 * np.cos(angle), 1.08 * np.sin(angle), f"{label}: {value:,.0f}", ha="left" if np.cos(angle) > 0 else "right", va="center")
562
- add_chart_header(fig, ax, title, subtitle)
563
- ```
564
-
565
- ### Histogram / KDE
566
-
567
- - Use: spread, skew, tail, or threshold.
568
- - Data: one numeric value.
569
- - Snippet:
570
- ```python
571
- sns.histplot(data=df, x=value_col, bins=bins, ax=ax, color=family["base"], edgecolor=family["dark"], linewidth=1.0)
572
- ax.axvline(df[value_col].median(), color=TOKENS["ink"], linestyle=":", linewidth=1.0)
573
- add_chart_header(fig, ax, title, subtitle)
574
- ```
575
-
576
- ### Grouped Distribution Comparison
577
-
578
- - Use: spread, skew, or outliers across cohorts.
579
- - Data: group, numeric value.
580
- - Snippet:
581
- ```python
582
- group_order = list(df[group_col].drop_duplicates())
583
- group_family = COLOR_FAMILIES["pink"]
584
- box_tones = ["base", "light", "xlight"]
585
- point_tones = ["base", "base", "base"]
586
- box_palette = {group: group_family[box_tones[i % len(box_tones)]] for i, group in enumerate(group_order)}
587
- point_palette = {group: group_family[point_tones[i % len(point_tones)]] for i, group in enumerate(group_order)}
588
- edge_colors = {group: group_family["dark"] for group in group_order}
589
- sns.boxplot(data=df, x=group_col, y=value_col, hue=group_col, palette=box_palette, legend=False, linewidth=1.0)
590
- for patch, group in zip(ax.patches, group_order):
591
- patch.set_edgecolor(edge_colors[group])
592
- sns.stripplot(data=df.sample(min(len(df), 500)), x=group_col, y=value_col, hue=group_col, palette=point_palette, legend=False, alpha=0.25, size=2)
593
- add_chart_header(fig, ax, title, subtitle)
594
- ```
595
-
596
- ### Scatter
597
-
598
- - Use: two-variable relationship.
599
- - Data: numeric x/y, optional small group.
600
- - Snippet:
601
- ```python
602
- sns.scatterplot(data=df, x=x_col, y=y_col, ax=ax, color=family["base"], edgecolor=family["dark"], linewidth=0.6, alpha=0.65)
603
- add_chart_header(fig, ax, title, subtitle)
604
- ```
605
-
606
- ### Bubble Chart
607
-
608
- - Use: two-variable relationship where a third numeric metric materially changes interpretation.
609
- - Data: numeric x/y, numeric size.
610
- - Snippet:
611
- ```python
612
- size_min = df[size_col].min()
613
- size_max = df[size_col].max()
614
- size_values = np.quantile(df[size_col], [0.25, 0.5, 0.75])
615
-
616
- def marker_size(value):
617
- if size_max == size_min:
618
- return 240
619
- return 80 + (value - size_min) / (size_max - size_min) * 420
620
-
621
- sns.scatterplot(
622
- data=df,
623
- x=x_col,
624
- y=y_col,
625
- size=size_col,
626
- sizes=(80, 500),
627
- legend=False,
628
- ax=ax,
629
- color=family["base"],
630
- edgecolor=family["dark"],
631
- linewidth=0.8,
632
- alpha=0.55,
633
- )
634
- handles = [
635
- ax.scatter([], [], s=marker_size(value), facecolors=family["base"], edgecolors=family["dark"], linewidths=0.8, alpha=0.55, label=f"{value:,.0f}")
636
- for value in size_values
637
- ]
638
- ax.legend(handles=handles, title=str(size_col).replace("_", " ").title(), loc="lower left", bbox_to_anchor=(0, 1.02), frameon=False, ncol=len(handles), borderaxespad=0)
639
- add_chart_header(fig, ax, title, subtitle)
640
- ```
641
-
642
- ### Scatter / Density
643
-
644
- - Use: dense point cloud.
645
- - Data: numeric x/y.
646
- - Snippet:
647
- ```python
648
- ax.hexbin(df[x_col], df[y_col], gridsize=28, mincnt=1, cmap=sns.blend_palette([TOKENS["panel"], family["light"], family["base"]], as_cmap=True))
649
- fit = np.polyfit(df[x_col], df[y_col], deg=1)
650
- x_fit = np.linspace(df[x_col].min(), df[x_col].max(), 100)
651
- sns.lineplot(x=x_fit, y=fit[0] * x_fit + fit[1], ax=ax, color=family["base"], linewidth=1.0)
652
- add_chart_header(fig, ax, title, subtitle)
653
- ```
654
-
655
- ### Ordered Line & Dot
656
-
657
- - Use: ordered bins, calibration, or uncertainty comparisons.
658
- - Data: ordered x/bin, estimate, optional bounds/series.
659
- - Snippet:
660
- ```python
661
- ax.errorbar(
662
- df[x_col], df[estimate_col],
663
- yerr=[df[estimate_col] - df[lower_col], df[upper_col] - df[estimate_col]],
664
- fmt="o", color=family["base"], linewidth=1.0, capsize=3,
665
- )
666
- ax.plot(df[x_col], df[estimate_col], color=family["light"], linewidth=1.0)
667
- add_chart_header(fig, ax, title, subtitle)
668
- ```
669
-
670
- ### Faceted Dot & Interval
671
-
672
- - Use: subgroup estimates against benchmark.
673
- - Data: facet, estimate, lower, upper, label.
674
- - Snippet:
675
- ```python
676
- for ax, (facet, part) in zip(axes, df.groupby(facet_col)):
677
- facet_order = list(df[facet_col].drop_duplicates())
678
- facet_tones = ["base", "light", "base"]
679
- facet_color = COLOR_FAMILIES["gold"][facet_tones[facet_order.index(facet) % len(facet_tones)]]
680
- ax.errorbar(
681
- part[estimate_col], part[label_col],
682
- xerr=[part[estimate_col] - part[lower_col], part[upper_col] - part[estimate_col]],
683
- fmt="o", color=facet_color, linewidth=1.0,
684
- )
685
- ax.axvline(benchmark, color=TOKENS["ink"], linestyle=":", linewidth=1.0)
686
- add_chart_header(fig, axes[0], title, subtitle)
687
- ```
688
-
689
- ### Experiment Lift With Confidence Intervals
690
-
691
- - Use: lift, treatment effects, or model intervals.
692
- - Data: label, estimate, lower, upper.
693
- - Snippet:
694
- ```python
695
- ax.axvline(0, color=TOKENS["ink"], linestyle=":", linewidth=1.0)
696
- metric_family = COLOR_FAMILIES["gold"]
697
- for _, row in df.iterrows():
698
- marker_face = TOKENS["panel"] if row[estimate_col] < 0 else metric_family["base"]
699
- ax.errorbar(
700
- row[estimate_col], row[label_col],
701
- xerr=np.array([[row[estimate_col] - row[lower_col]], [row[upper_col] - row[estimate_col]]]),
702
- fmt="o", color=metric_family["base"], markerfacecolor=marker_face, markeredgecolor=metric_family["dark"], linewidth=1.0, capsize=3,
703
- )
704
- add_chart_header(fig, ax, title, subtitle)
705
- ```
706
-
707
- ### Heatmap
708
-
709
- - Use: two-dimensional structure or cohort matrix.
710
- - Data: ordered pivot matrix.
711
- - Snippet:
712
- ```python
713
- cmap = sns.blend_palette([TOKENS["panel"], family["xlight"], family["light"], family["base"]], as_cmap=True)
714
- sns.heatmap(matrix, ax=ax, cmap=cmap, linewidths=1.0, linecolor=TOKENS["panel"], annot=annot, fmt=value_format)
715
- add_chart_header(fig, ax, title, subtitle)
716
- ```
717
-
718
- ### Funnel Stage Bars
719
-
720
- - Use: ordered stages, counts, conversion.
721
- - Data: stage order, count, optional rate.
722
- - Snippet:
723
- ```python
724
- plot_df = df.set_index(stage_col).loc[stage_order].reset_index()
725
- stage_families = [COLOR_FAMILIES[name] for name in ["olive", "gold", "blue", "pink", "orange"]]
726
- palette = {stage: stage_families[i % len(stage_families)]["base"] for i, stage in enumerate(stage_order)}
727
- edge_colors = {stage: stage_families[i % len(stage_families)]["dark"] for i, stage in enumerate(stage_order)}
728
- sns.barplot(data=plot_df, x=stage_col, y=count_col, hue=stage_col, palette=palette, legend=False, dodge=False, ax=ax, edgecolor=TOKENS["ink"], linewidth=1.0)
729
- for patch, stage in zip(ax.patches, plot_df[stage_col]):
730
- patch.set_edgecolor(edge_colors[stage])
731
- add_chart_header(fig, ax, title, subtitle)
732
- ```
733
-
734
- ### Waterfall Bridge
735
-
736
- - Use: additive bridge from start to end.
737
- - Data: ordered drivers, signed deltas, start/end.
738
- - Snippet:
739
- ```python
740
- positive_family = COLOR_FAMILIES["olive"]
741
- negative_family = COLOR_FAMILIES["orange"]
742
- positive_fill = positive_family["base"]
743
- negative_fill = negative_family["base"]
744
- total_fill = NEUTRAL_MARKS["light"]
745
- total_edge = NEUTRAL_MARKS["dark"]
746
- x = np.arange(len(df) + 2)
747
- driver_labels = ["Start", *df[label_col], "End"]
748
- running = start_value + df[delta_col].cumsum().shift(fill_value=0)
749
- ending = start_value + df[delta_col].cumsum()
750
- end_value = ending.iloc[-1]
751
- bottom = np.minimum(running, ending)
752
- colors = np.where(df[delta_col] >= 0, positive_fill, negative_fill)
753
- edge_colors = np.where(df[delta_col] >= 0, positive_family["dark"], negative_family["dark"])
754
- ax.bar(x[0], start_value, color=total_fill, edgecolor=total_edge, linewidth=1.0)
755
- bars = ax.bar(x[1:-1], df[delta_col].abs(), bottom=bottom, color=colors, edgecolor=edge_colors, linewidth=1.0)
756
- for bar, delta in zip(bars, df[delta_col]):
757
- bar.set_edgecolor(positive_family["dark"] if delta >= 0 else negative_family["dark"])
758
- ax.text(bar.get_x() + bar.get_width() / 2, bar.get_y() + bar.get_height() + 2, f"{delta:+.0f}", ha="center", fontsize=8, color=TOKENS["ink"])
759
- ax.bar(x[-1], end_value, color=total_fill, edgecolor=total_edge, linewidth=1.0)
760
- ax.set_xticks(x, driver_labels)
761
- ax.legend(
762
- handles=[
763
- Patch(facecolor=total_fill, edgecolor=total_edge, label="Start/end"),
764
- Patch(facecolor=positive_fill, edgecolor=positive_family["dark"], label="Positive delta"),
765
- Patch(facecolor=negative_fill, edgecolor=negative_family["dark"], label="Negative delta"),
766
- ],
767
- loc="lower left",
768
- bbox_to_anchor=(0, 1.02),
769
- frameon=False,
770
- ncol=3,
771
- borderaxespad=0,
772
- )
773
- add_chart_header(fig, ax, title, subtitle)
774
- ```