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.
Files changed (365) hide show
  1. package/.agents/skills/diagram-design/LICENSE +4 -0
  2. package/.agents/skills/diagram-design/SKILL.md +423 -0
  3. package/.agents/skills/diagram-design/UPSTREAM.json +88 -0
  4. package/.agents/skills/diagram-design/UPSTREAM.md +23 -0
  5. package/.agents/skills/diagram-design/assets/example-architecture-containment.html +205 -0
  6. package/.agents/skills/diagram-design/assets/example-architecture-delta.html +193 -0
  7. package/.agents/skills/diagram-design/assets/example-architecture.html +183 -0
  8. package/.agents/skills/diagram-design/assets/example-axonometric-plan-campus.html +108 -0
  9. package/.agents/skills/diagram-design/assets/example-axonometric-plan-coffee-shop.html +121 -0
  10. package/.agents/skills/diagram-design/assets/example-axonometric-plan-warehouse.html +127 -0
  11. package/.agents/skills/diagram-design/assets/example-axonometric-plan.html +114 -0
  12. package/.agents/skills/diagram-design/assets/example-bar.html +129 -0
  13. package/.agents/skills/diagram-design/assets/example-beeswarm.html +384 -0
  14. package/.agents/skills/diagram-design/assets/example-box-plot.html +127 -0
  15. package/.agents/skills/diagram-design/assets/example-bubble.html +147 -0
  16. package/.agents/skills/diagram-design/assets/example-bump.html +142 -0
  17. package/.agents/skills/diagram-design/assets/example-data-flow.html +143 -0
  18. package/.agents/skills/diagram-design/assets/example-datalake.html +269 -0
  19. package/.agents/skills/diagram-design/assets/example-db-schema.html +302 -0
  20. package/.agents/skills/diagram-design/assets/example-dependency.html +224 -0
  21. package/.agents/skills/diagram-design/assets/example-deployment.html +190 -0
  22. package/.agents/skills/diagram-design/assets/example-dp-integration.html +81 -0
  23. package/.agents/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
  24. package/.agents/skills/diagram-design/assets/example-er.html +202 -0
  25. package/.agents/skills/diagram-design/assets/example-exploded-ai-stack.html +85 -0
  26. package/.agents/skills/diagram-design/assets/example-exploded-keyboard.html +84 -0
  27. package/.agents/skills/diagram-design/assets/example-exploded-phone.html +83 -0
  28. package/.agents/skills/diagram-design/assets/example-exploded-unboxing.html +84 -0
  29. package/.agents/skills/diagram-design/assets/example-exploded.html +83 -0
  30. package/.agents/skills/diagram-design/assets/example-fishbone.html +152 -0
  31. package/.agents/skills/diagram-design/assets/example-flowchart.html +163 -0
  32. package/.agents/skills/diagram-design/assets/example-gantt.html +137 -0
  33. package/.agents/skills/diagram-design/assets/example-heatmap.html +224 -0
  34. package/.agents/skills/diagram-design/assets/example-high-level-vertical.html +325 -0
  35. package/.agents/skills/diagram-design/assets/example-high-level.html +301 -0
  36. package/.agents/skills/diagram-design/assets/example-import-drawio.html +185 -0
  37. package/.agents/skills/diagram-design/assets/example-import-excalidraw.html +70 -0
  38. package/.agents/skills/diagram-design/assets/example-import-mermaid.html +70 -0
  39. package/.agents/skills/diagram-design/assets/example-it-state.html +128 -0
  40. package/.agents/skills/diagram-design/assets/example-journey.html +148 -0
  41. package/.agents/skills/diagram-design/assets/example-kanban.html +174 -0
  42. package/.agents/skills/diagram-design/assets/example-layers.html +123 -0
  43. package/.agents/skills/diagram-design/assets/example-line.html +111 -0
  44. package/.agents/skills/diagram-design/assets/example-loop.html +100 -0
  45. package/.agents/skills/diagram-design/assets/example-marimekko.html +148 -0
  46. package/.agents/skills/diagram-design/assets/example-medallion.html +159 -0
  47. package/.agents/skills/diagram-design/assets/example-nested.html +136 -0
  48. package/.agents/skills/diagram-design/assets/example-org-chart.html +45 -0
  49. package/.agents/skills/diagram-design/assets/example-polar.html +116 -0
  50. package/.agents/skills/diagram-design/assets/example-process.html +64 -0
  51. package/.agents/skills/diagram-design/assets/example-pyramid.html +119 -0
  52. package/.agents/skills/diagram-design/assets/example-quadrant-consultant.html +166 -0
  53. package/.agents/skills/diagram-design/assets/example-quadrant.html +135 -0
  54. package/.agents/skills/diagram-design/assets/example-radar.html +139 -0
  55. package/.agents/skills/diagram-design/assets/example-ridgeline.html +104 -0
  56. package/.agents/skills/diagram-design/assets/example-sankey.html +150 -0
  57. package/.agents/skills/diagram-design/assets/example-scatter.html +141 -0
  58. package/.agents/skills/diagram-design/assets/example-sequence-oauth.html +227 -0
  59. package/.agents/skills/diagram-design/assets/example-sequence.html +222 -0
  60. package/.agents/skills/diagram-design/assets/example-service-blueprint.html +185 -0
  61. package/.agents/skills/diagram-design/assets/example-slopegraph.html +119 -0
  62. package/.agents/skills/diagram-design/assets/example-state-lifecycle.html +92 -0
  63. package/.agents/skills/diagram-design/assets/example-state.html +147 -0
  64. package/.agents/skills/diagram-design/assets/example-story-map.html +184 -0
  65. package/.agents/skills/diagram-design/assets/example-streamgraph.html +99 -0
  66. package/.agents/skills/diagram-design/assets/example-swimlane.html +172 -0
  67. package/.agents/skills/diagram-design/assets/example-timeline.html +135 -0
  68. package/.agents/skills/diagram-design/assets/example-tree-block-decomposition.html +151 -0
  69. package/.agents/skills/diagram-design/assets/example-tree.html +173 -0
  70. package/.agents/skills/diagram-design/assets/example-treemap.html +107 -0
  71. package/.agents/skills/diagram-design/assets/example-uml-class.html +188 -0
  72. package/.agents/skills/diagram-design/assets/example-venn.html +110 -0
  73. package/.agents/skills/diagram-design/assets/example-wardley.html +153 -0
  74. package/.agents/skills/diagram-design/assets/example-waterfall.html +129 -0
  75. package/.agents/skills/diagram-design/assets/template-dark.html +99 -0
  76. package/.agents/skills/diagram-design/assets/template-full.html +421 -0
  77. package/.agents/skills/diagram-design/assets/template-motion.html +448 -0
  78. package/.agents/skills/diagram-design/assets/template-terminal.html +188 -0
  79. package/.agents/skills/diagram-design/assets/template.html +100 -0
  80. package/.agents/skills/diagram-design/references/animation.md +143 -0
  81. package/.agents/skills/diagram-design/references/export-registry.md +78 -0
  82. package/.agents/skills/diagram-design/references/export.md +376 -0
  83. package/.agents/skills/diagram-design/references/import-drawio.md +181 -0
  84. package/.agents/skills/diagram-design/references/import-excalidraw.md +130 -0
  85. package/.agents/skills/diagram-design/references/import-mermaid.md +137 -0
  86. package/.agents/skills/diagram-design/references/layout-budget.md +97 -0
  87. package/.agents/skills/diagram-design/references/onboarding.md +368 -0
  88. package/.agents/skills/diagram-design/references/output-spec.md +277 -0
  89. package/.agents/skills/diagram-design/references/primitive-annotation.md +36 -0
  90. package/.agents/skills/diagram-design/references/primitive-icons.md +827 -0
  91. package/.agents/skills/diagram-design/references/primitive-sketchy.md +43 -0
  92. package/.agents/skills/diagram-design/references/primitive-terminal.md +76 -0
  93. package/.agents/skills/diagram-design/references/primitives-core.md +150 -0
  94. package/.agents/skills/diagram-design/references/profiles.md +183 -0
  95. package/.agents/skills/diagram-design/references/semantic-patterns.md +154 -0
  96. package/.agents/skills/diagram-design/references/style-guide.md +236 -0
  97. package/.agents/skills/diagram-design/references/style-vivid.md +148 -0
  98. package/.agents/skills/diagram-design/references/type-architecture-delta.md +143 -0
  99. package/.agents/skills/diagram-design/references/type-architecture.md +117 -0
  100. package/.agents/skills/diagram-design/references/type-axonometric-plan.md +83 -0
  101. package/.agents/skills/diagram-design/references/type-bar.md +108 -0
  102. package/.agents/skills/diagram-design/references/type-data-flow.md +371 -0
  103. package/.agents/skills/diagram-design/references/type-db-schema.md +48 -0
  104. package/.agents/skills/diagram-design/references/type-dependency.md +44 -0
  105. package/.agents/skills/diagram-design/references/type-deployment.md +45 -0
  106. package/.agents/skills/diagram-design/references/type-dp-integration.md +407 -0
  107. package/.agents/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
  108. package/.agents/skills/diagram-design/references/type-er.md +25 -0
  109. package/.agents/skills/diagram-design/references/type-exploded.md +115 -0
  110. package/.agents/skills/diagram-design/references/type-fishbone.md +75 -0
  111. package/.agents/skills/diagram-design/references/type-flowchart.md +23 -0
  112. package/.agents/skills/diagram-design/references/type-gantt.md +45 -0
  113. package/.agents/skills/diagram-design/references/type-heatmap.md +80 -0
  114. package/.agents/skills/diagram-design/references/type-high-level.md +470 -0
  115. package/.agents/skills/diagram-design/references/type-it-state.md +468 -0
  116. package/.agents/skills/diagram-design/references/type-journey.md +55 -0
  117. package/.agents/skills/diagram-design/references/type-kanban.md +49 -0
  118. package/.agents/skills/diagram-design/references/type-layers.md +26 -0
  119. package/.agents/skills/diagram-design/references/type-line.md +337 -0
  120. package/.agents/skills/diagram-design/references/type-loop.md +223 -0
  121. package/.agents/skills/diagram-design/references/type-medallion.md +356 -0
  122. package/.agents/skills/diagram-design/references/type-nested.md +22 -0
  123. package/.agents/skills/diagram-design/references/type-org-chart.md +44 -0
  124. package/.agents/skills/diagram-design/references/type-polar.md +136 -0
  125. package/.agents/skills/diagram-design/references/type-process.md +490 -0
  126. package/.agents/skills/diagram-design/references/type-pyramid.md +33 -0
  127. package/.agents/skills/diagram-design/references/type-quadrant.md +81 -0
  128. package/.agents/skills/diagram-design/references/type-radar.md +82 -0
  129. package/.agents/skills/diagram-design/references/type-sankey.md +75 -0
  130. package/.agents/skills/diagram-design/references/type-scatter.md +276 -0
  131. package/.agents/skills/diagram-design/references/type-sequence.md +130 -0
  132. package/.agents/skills/diagram-design/references/type-service-blueprint.md +103 -0
  133. package/.agents/skills/diagram-design/references/type-state.md +30 -0
  134. package/.agents/skills/diagram-design/references/type-story-map.md +46 -0
  135. package/.agents/skills/diagram-design/references/type-swimlane.md +22 -0
  136. package/.agents/skills/diagram-design/references/type-timeline.md +20 -0
  137. package/.agents/skills/diagram-design/references/type-tree.md +24 -0
  138. package/.agents/skills/diagram-design/references/type-treemap.md +137 -0
  139. package/.agents/skills/diagram-design/references/type-uml-class.md +65 -0
  140. package/.agents/skills/diagram-design/references/type-venn.md +26 -0
  141. package/.agents/skills/diagram-design/references/type-wardley.md +39 -0
  142. package/.agents/skills/diagram-design/references/type-waterfall.md +75 -0
  143. package/.agents/skills/scrum-meta/SKILL.md +36 -36
  144. package/.agents/skills/scrum-planning/SKILL.md +61 -61
  145. package/.agents/skills/scrum-planning/references/schema.md +384 -336
  146. package/.agents/skills/scrum-report/SKILL.md +42 -42
  147. package/.agents/skills/scrum-sprint/SKILL.md +49 -49
  148. package/.agents/skills/scrum-tdd/SKILL.md +140 -127
  149. package/README.md +24 -1
  150. package/assets/board/200.html +1 -1
  151. package/assets/board/404.html +1 -1
  152. package/assets/board/_nuxt/4gQF_HS3.js +1 -0
  153. package/assets/board/_nuxt/5okfNy5D.js +1 -0
  154. package/assets/board/_nuxt/{Bb3Limos.js → B0C2jsdk.js} +1 -1
  155. package/assets/board/_nuxt/B1j6UC4U.js +1 -0
  156. package/assets/board/_nuxt/B3LKy6o2.js +1 -0
  157. package/assets/board/_nuxt/BAQQngAq.js +13 -0
  158. package/assets/board/_nuxt/BE6t7Q2m.js +1 -0
  159. package/assets/board/_nuxt/BGwhkDRl.js +1 -0
  160. package/assets/board/_nuxt/BLvbupFS.js +1 -0
  161. package/assets/board/_nuxt/BQgzP7ur.js +1 -0
  162. package/assets/board/_nuxt/BRZIF_wo.js +1 -0
  163. package/assets/board/_nuxt/BU8vdZUs.js +95 -0
  164. package/assets/board/_nuxt/BW3xJdEx.js +1 -0
  165. package/assets/board/_nuxt/{Cm9lkUvP.js → BY36DFyj.js} +1 -1
  166. package/assets/board/_nuxt/BZlZD94i.js +1 -0
  167. package/assets/board/_nuxt/BZvXNwev.js +3 -0
  168. package/assets/board/_nuxt/BiWrMOsL.js +1 -0
  169. package/assets/board/_nuxt/BkoKCNUY.js +1 -0
  170. package/assets/board/_nuxt/BlKmZhhF.js +1 -0
  171. package/assets/board/_nuxt/BmBpmU73.js +1 -0
  172. package/assets/board/_nuxt/BmrSh0rL.js +1 -0
  173. package/assets/board/_nuxt/BrWE0up6.js +1 -0
  174. package/assets/board/_nuxt/Bs52qkgk.js +1 -0
  175. package/assets/board/_nuxt/BuBzMkFZ.js +1 -0
  176. package/assets/board/_nuxt/Bubk0xn-.js +1 -0
  177. package/assets/board/_nuxt/BxuBMtk_.js +3 -0
  178. package/assets/board/_nuxt/By1KXXLR.js +1 -0
  179. package/assets/board/_nuxt/BygIGL69.js +2 -0
  180. package/assets/board/_nuxt/C-fx-vFO.js +1 -0
  181. package/assets/board/_nuxt/C1iO5KH3.js +1 -0
  182. package/assets/board/_nuxt/C2YPmTzt.js +1 -0
  183. package/assets/board/_nuxt/C3SpAhCW.js +1 -0
  184. package/assets/board/_nuxt/C3ZRWz5L.js +1 -0
  185. package/assets/board/_nuxt/C4WdPP6K.js +1 -0
  186. package/assets/board/_nuxt/C6o03JHe.js +1 -0
  187. package/assets/board/_nuxt/C8qB5llI.js +1 -0
  188. package/assets/board/_nuxt/C9MgRdhu.js +1 -0
  189. package/assets/board/_nuxt/CCA81-4P.js +1 -0
  190. package/assets/board/_nuxt/{D2O8Q8x9.js → CFCM18fF.js} +1 -1
  191. package/assets/board/_nuxt/CGXljzd_.js +1 -0
  192. package/assets/board/_nuxt/CI0scS-N.js +1 -0
  193. package/assets/board/_nuxt/CJs9B42o.js +1 -0
  194. package/assets/board/_nuxt/COmtTtfB.js +1 -0
  195. package/assets/board/_nuxt/CPYm4J_K.js +1 -0
  196. package/assets/board/_nuxt/CXG7GZes.js +1 -0
  197. package/assets/board/_nuxt/CYGiZn-X.js +1 -0
  198. package/assets/board/_nuxt/CaE8VlUp.js +1 -0
  199. package/assets/board/_nuxt/Cajxc4Dw.js +1 -0
  200. package/assets/board/_nuxt/CcGiNUgA.js +1 -0
  201. package/assets/board/_nuxt/Ccgv3lDj.js +1 -0
  202. package/assets/board/_nuxt/CdPGFZyy.js +1 -0
  203. package/assets/board/_nuxt/{DfR3IZN_.js → Cdf_T8Xa.js} +1 -1
  204. package/assets/board/_nuxt/CgQ30j_6.js +1 -0
  205. package/assets/board/_nuxt/Ck0-FqVI.js +1 -0
  206. package/assets/board/_nuxt/CkWKLtjO.js +1 -0
  207. package/assets/board/_nuxt/CoipdpDu.js +1 -0
  208. package/assets/board/_nuxt/Cq7hsCKB.js +1 -0
  209. package/assets/board/_nuxt/D166WVUG.js +1 -0
  210. package/assets/board/_nuxt/D1V1gysQ.js +1 -0
  211. package/assets/board/_nuxt/D4Dpzo9e.js +1 -0
  212. package/assets/board/_nuxt/D5i92OZO.js +1 -0
  213. package/assets/board/_nuxt/D6dUp4Nm.js +9 -0
  214. package/assets/board/_nuxt/DFQDFspC.js +1 -0
  215. package/assets/board/_nuxt/DHX2tw9J.js +1 -0
  216. package/assets/board/_nuxt/DJM7u8P3.js +1 -0
  217. package/assets/board/_nuxt/{BPTrRhcw.js → DLr85ebo.js} +1 -1
  218. package/assets/board/_nuxt/DOMM1wfl.js +1 -0
  219. package/assets/board/_nuxt/DU6ArlUN.js +1 -0
  220. package/assets/board/_nuxt/{B_SlFcWp.js → DUgGsde6.js} +1 -1
  221. package/assets/board/_nuxt/DV4ti-Pq.js +1 -0
  222. package/assets/board/_nuxt/D_ct-Stz.js +2 -0
  223. package/assets/board/_nuxt/DbWAComO.js +1 -0
  224. package/assets/board/_nuxt/DbwlcHAt.js +1 -0
  225. package/assets/board/_nuxt/Dki9VkAL.js +3 -0
  226. package/assets/board/_nuxt/DlNJhOoc.js +1 -0
  227. package/assets/board/_nuxt/Dmg78zOY.js +3 -0
  228. package/assets/board/_nuxt/DqG7CtD4.js +1 -0
  229. package/assets/board/_nuxt/DqUSsCJ2.js +1 -0
  230. package/assets/board/_nuxt/Du2F4WXh.js +1 -0
  231. package/assets/board/_nuxt/DuRiEXn4.js +1 -0
  232. package/assets/board/_nuxt/DwCE3305.js +1 -0
  233. package/assets/board/_nuxt/DwzGxoX2.js +1 -0
  234. package/assets/board/_nuxt/DxBwVNyP.js +2 -0
  235. package/assets/board/_nuxt/DzmVW5-D.js +1 -0
  236. package/assets/board/_nuxt/I-sGtDIB.js +6 -0
  237. package/assets/board/_nuxt/JU9-x68N.js +1 -0
  238. package/assets/board/_nuxt/Lozm7hhE.js +1 -0
  239. package/assets/board/_nuxt/MMsTMkcB.js +1 -0
  240. package/assets/board/_nuxt/MS7CGmCB.js +1 -0
  241. package/assets/board/_nuxt/OKKaKILz.js +1 -0
  242. package/assets/board/_nuxt/{Csqgy925.js → P6qlvBHA.js} +1 -1
  243. package/assets/board/_nuxt/SrNUvNwO.js +1 -0
  244. package/assets/board/_nuxt/{DSaWoFHS.js → SywdkA98.js} +1 -1
  245. package/assets/board/_nuxt/TBIRpVLG.js +1 -0
  246. package/assets/board/_nuxt/TlTrMIMm.js +1 -0
  247. package/assets/board/_nuxt/Utb4TVOl.js +1 -0
  248. package/assets/board/_nuxt/Zv9-SOQF.js +1 -0
  249. package/assets/board/_nuxt/_id_.B6iqDPxe.css +1 -0
  250. package/assets/board/_nuxt/b7xtxFRl.js +1 -0
  251. package/assets/board/_nuxt/builds/latest.json +1 -1
  252. package/assets/board/_nuxt/builds/meta/08bebe14-0f1b-4d2a-8de4-e84e122d10e9.json +1 -0
  253. package/assets/board/_nuxt/diagrams.pyhqNtmr.css +1 -0
  254. package/assets/board/_nuxt/{entry.CKHePurH.css → entry.BBv-sBnP.css} +1 -1
  255. package/assets/board/_nuxt/error-404.CgJNdpB5.css +1 -0
  256. package/assets/board/_nuxt/error-500.WYSoH44y.css +1 -0
  257. package/assets/board/_nuxt/jbri6q1p.js +1 -0
  258. package/assets/board/_nuxt/q_8bxRMt.js +1 -0
  259. package/assets/board/burndown/index.html +1 -1
  260. package/assets/board/diagrams/index.html +1 -0
  261. package/assets/board/epics/index.html +1 -1
  262. package/assets/board/gantt/index.html +1 -1
  263. package/assets/board/index.html +1 -1
  264. package/assets/board/last-change/index.html +1 -1
  265. package/assets/board/milestones/index.html +1 -1
  266. package/assets/board/tests/index.html +1 -1
  267. package/bin/scrum-skills.mjs +13 -0
  268. package/package.json +2 -1
  269. package/templates/AGENTS.md +10 -0
  270. package/tools/diagram-import.mjs +238 -0
  271. package/tools/diagram-lint.mjs +518 -0
  272. package/tools/diagram.mjs +299 -0
  273. package/tools/last-change.mjs +326 -326
  274. package/tools/projects.mjs +29 -4
  275. package/tools/serve.mjs +27 -1
  276. package/tools/validate.mjs +781 -664
  277. package/assets/board/_nuxt/1eqboJxR.js +0 -1
  278. package/assets/board/_nuxt/2K7ag6ES.js +0 -1
  279. package/assets/board/_nuxt/51OWHj8c.js +0 -2
  280. package/assets/board/_nuxt/6gFtTBwm.js +0 -1
  281. package/assets/board/_nuxt/B3jkABw9.js +0 -1
  282. package/assets/board/_nuxt/B5n2_jZN.js +0 -1
  283. package/assets/board/_nuxt/BDK2Hj7B.js +0 -1
  284. package/assets/board/_nuxt/BDcnzXHq.js +0 -1
  285. package/assets/board/_nuxt/BaG8y0Wt.js +0 -1
  286. package/assets/board/_nuxt/BbwJq5pb.js +0 -1
  287. package/assets/board/_nuxt/BgLeKwx0.js +0 -1
  288. package/assets/board/_nuxt/Bi9Axj3V.js +0 -1
  289. package/assets/board/_nuxt/BmxvtaMq.js +0 -1
  290. package/assets/board/_nuxt/BodFvto3.js +0 -1
  291. package/assets/board/_nuxt/BpWeHLuN.js +0 -1
  292. package/assets/board/_nuxt/BuOKDFiJ.js +0 -1
  293. package/assets/board/_nuxt/C40iTe-x.js +0 -1
  294. package/assets/board/_nuxt/C7K0R7F-.js +0 -2
  295. package/assets/board/_nuxt/C8vL692X.js +0 -1
  296. package/assets/board/_nuxt/C9StZL3D.js +0 -3
  297. package/assets/board/_nuxt/CGI_ZV79.js +0 -1
  298. package/assets/board/_nuxt/CJ2mz0WY.js +0 -1
  299. package/assets/board/_nuxt/CJMBJQuf.js +0 -1
  300. package/assets/board/_nuxt/CK-lOYG9.js +0 -1
  301. package/assets/board/_nuxt/CK9_veoz.js +0 -1
  302. package/assets/board/_nuxt/CLBcBrYf.js +0 -1
  303. package/assets/board/_nuxt/CMUi2-Lj.js +0 -1
  304. package/assets/board/_nuxt/COf6E6h4.js +0 -1
  305. package/assets/board/_nuxt/CPCUMJnF.js +0 -1
  306. package/assets/board/_nuxt/CPcKlmSm.js +0 -1
  307. package/assets/board/_nuxt/CQTvWh4i.js +0 -1
  308. package/assets/board/_nuxt/CSEEUF8S.js +0 -1
  309. package/assets/board/_nuxt/CSSb154I.js +0 -13
  310. package/assets/board/_nuxt/CgDTd7jS.js +0 -1
  311. package/assets/board/_nuxt/ChG76uh9.js +0 -1
  312. package/assets/board/_nuxt/Ci0qbkgh.js +0 -1
  313. package/assets/board/_nuxt/CqoQ__I_.js +0 -1
  314. package/assets/board/_nuxt/CuJUHLl8.js +0 -1
  315. package/assets/board/_nuxt/CvLiA4_O.js +0 -1
  316. package/assets/board/_nuxt/Cvs12oA0.js +0 -3
  317. package/assets/board/_nuxt/CyEXFe3V.js +0 -1
  318. package/assets/board/_nuxt/Cz6rZcLK.js +0 -1
  319. package/assets/board/_nuxt/D2FhHl1o.js +0 -1
  320. package/assets/board/_nuxt/D3YCAmfu.js +0 -1
  321. package/assets/board/_nuxt/D5CE81jK.js +0 -1
  322. package/assets/board/_nuxt/D75vbfSb.js +0 -1
  323. package/assets/board/_nuxt/D99LbGfb.js +0 -9
  324. package/assets/board/_nuxt/DEfLc7p3.js +0 -6
  325. package/assets/board/_nuxt/DF-nsa1Z.js +0 -1
  326. package/assets/board/_nuxt/DIc8yx98.js +0 -1
  327. package/assets/board/_nuxt/DLkAKotw.js +0 -1
  328. package/assets/board/_nuxt/DRPlYvb3.js +0 -1
  329. package/assets/board/_nuxt/DRlQgul3.js +0 -1
  330. package/assets/board/_nuxt/DSLbmoWa.js +0 -1
  331. package/assets/board/_nuxt/DWO9c9yp.js +0 -1
  332. package/assets/board/_nuxt/DZo3dYLJ.js +0 -3
  333. package/assets/board/_nuxt/D_S6N7_b.js +0 -1
  334. package/assets/board/_nuxt/DajA-Tkt.js +0 -1
  335. package/assets/board/_nuxt/DbHiyab-.js +0 -1
  336. package/assets/board/_nuxt/Dc7Ql6eE.js +0 -1
  337. package/assets/board/_nuxt/Dd9ZukPU.js +0 -1
  338. package/assets/board/_nuxt/Dg2LiqmN.js +0 -1
  339. package/assets/board/_nuxt/DhuleNnm.js +0 -1
  340. package/assets/board/_nuxt/DkI1Qxpp.js +0 -95
  341. package/assets/board/_nuxt/DnDHGSYI.js +0 -1
  342. package/assets/board/_nuxt/DpXJ_tCU.js +0 -1
  343. package/assets/board/_nuxt/DqZgF3hU.js +0 -1
  344. package/assets/board/_nuxt/DqcxvfbD.js +0 -1
  345. package/assets/board/_nuxt/DsA2lVci.js +0 -1
  346. package/assets/board/_nuxt/Dtsa-1NS.js +0 -1
  347. package/assets/board/_nuxt/Du91iq0p.js +0 -1
  348. package/assets/board/_nuxt/Dx1wcYFo.js +0 -1
  349. package/assets/board/_nuxt/EYTShbt4.js +0 -1
  350. package/assets/board/_nuxt/MaXJprwN.js +0 -1
  351. package/assets/board/_nuxt/P9x67aq2.js +0 -1
  352. package/assets/board/_nuxt/S08nFESZ.js +0 -3
  353. package/assets/board/_nuxt/V0uynWE2.js +0 -1
  354. package/assets/board/_nuxt/Vo4wMbnS.js +0 -1
  355. package/assets/board/_nuxt/ZVTqot-_.js +0 -1
  356. package/assets/board/_nuxt/ZngEd3HB.js +0 -1
  357. package/assets/board/_nuxt/_id_.B2NDKSlX.css +0 -1
  358. package/assets/board/_nuxt/assMu_Wn.js +0 -1
  359. package/assets/board/_nuxt/builds/meta/8e23aec9-5b67-4569-b8bf-d4f07e50ffdf.json +0 -1
  360. package/assets/board/_nuxt/error-404.BFmXOnCT.css +0 -1
  361. package/assets/board/_nuxt/error-500.BZ-DdjQ6.css +0 -1
  362. package/assets/board/_nuxt/rlePnzpc.js +0 -1
  363. package/assets/board/_nuxt/uKzCKCTq.js +0 -1
  364. package/assets/board/_nuxt/vwxaNGfc.js +0 -1
  365. package/assets/board/_nuxt/yh6sf_D5.js +0 -1
@@ -0,0 +1,384 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Per-request latency, one dot per request · Beeswarm</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
8
+ <style>
9
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
10
+ :root {
11
+ --color-paper: #f5f5f5;
12
+ --color-ink: #2d3142;
13
+ --color-muted: #4f5d75;
14
+ --color-accent: #bf4520;
15
+ --font-sans: 'Geist', system-ui, sans-serif;
16
+ --font-serif: 'Instrument Serif', serif;
17
+ --font-mono: 'Geist Mono', ui-monospace, monospace;
18
+ }
19
+ body { font-family: var(--font-sans); background: var(--color-paper); color: var(--color-ink); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 3rem 2rem; }
20
+ .frame { max-width: 1200px; width: 100%; }
21
+ .eyebrow { font-family: var(--font-mono); font-size: 0.66rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
22
+ h1 { font-family: var(--font-serif); font-size: clamp(1.5rem, 2.4vw + 0.75rem, 2rem); font-weight: 400; letter-spacing: -0.02em; line-height: 1.15; margin-bottom: 1.5rem; }
23
+ svg { width: 100%; min-width: 760px; display: block; }
24
+ </style>
25
+ </head>
26
+ <body>
27
+ <div class="frame">
28
+ <p class="eyebrow">Beeswarm · Diagram Design</p>
29
+ <h1>The median hides the tail</h1>
30
+
31
+ <!-- Value axis: 0-440ms over 880px, x = 80 + 2*ms, linear from zero.
32
+ The vertical (swarm) axis carries NO meaning: each dot's y offset is
33
+ greedy packing at pitch 10 (2r+2) around the y=230 midline, first
34
+ free slot alternating above/below, and overlap is never resolved by
35
+ moving a dot along the value axis. scripts/verify-beeswarm.py derives
36
+ the value scale from the dots themselves and flags any dot that
37
+ disagrees with its peers, any overlapping pair, and any second dot
38
+ radius or non-focal fill. -->
39
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="beeswarm-title beeswarm-desc">
40
+ <title id="beeswarm-title">The median hides the tail</title>
41
+ <desc id="beeswarm-desc">Beeswarm of 138 per-request latency samples for one checkout endpoint on a shared linear value axis from zero; vertical spread is packing only and carries no value, and three requests past 380 ms form the p99 tail.</desc>
42
+ <defs>
43
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
44
+ <circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
45
+ </pattern>
46
+ </defs>
47
+
48
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
49
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
50
+
51
+ <!-- Axis caption -->
52
+ <text x="520" y="492" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" letter-spacing="0.14em" text-anchor="middle">PER-REQUEST LATENCY, MS</text>
53
+
54
+ <!-- Vertical gridlines only: the swarm axis has no scale to grid.
55
+ A horizontal rule through the band would invite reading the
56
+ packing offsets as values, which they are not. -->
57
+ <line x1="280" y1="40" x2="280" y2="420" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
58
+ <line x1="480" y1="40" x2="480" y2="420" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
59
+ <line x1="680" y1="40" x2="680" y2="420" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
60
+ <line x1="880" y1="40" x2="880" y2="420" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
61
+
62
+ <!-- Value axis, from zero. -->
63
+ <line x1="80" y1="420" x2="960" y2="420" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
64
+
65
+ <!-- Tick labels are BOUND: data-tick names the (one) value axis and
66
+ data-value the number the tick claims to sit at. verify-beeswarm.py
67
+ cross-checks each against the scale the dots themselves describe. -->
68
+ <text data-tick="x" data-value="0" x="80" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">0</text>
69
+ <text data-tick="x" data-value="100" x="280" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">100</text>
70
+ <text data-tick="x" data-value="200" x="480" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">200</text>
71
+ <text data-tick="x" data-value="300" x="680" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">300</text>
72
+ <text data-tick="x" data-value="400" x="880" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">400</text>
73
+
74
+ <!-- ─── THE SWARM. One dot = one request, every dot exactly at its
75
+ value on the shared axis; the vertical offset is the greedy dodge
76
+ and states nothing. One radius for every dot (size as a second
77
+ encoding is a bubble chart) and one ink fill for every non-focal
78
+ dot (opacity as a value encoding is banned while dodging). Each
79
+ dot sits on a paper underlay so gridlines do not show through
80
+ the translucent fill. -->
81
+ <circle cx="184" cy="230" r="4" fill="#f5f5f5"/>
82
+ <circle data-value="52" cx="184" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
83
+ <circle cx="186" cy="220" r="4" fill="#f5f5f5"/>
84
+ <circle data-value="53" cx="186" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
85
+ <circle cx="190" cy="240" r="4" fill="#f5f5f5"/>
86
+ <circle data-value="55" cx="190" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
87
+ <circle cx="192" cy="210" r="4" fill="#f5f5f5"/>
88
+ <circle data-value="56" cx="192" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
89
+ <circle cx="200" cy="230" r="4" fill="#f5f5f5"/>
90
+ <circle data-value="60" cx="200" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
91
+ <circle cx="202" cy="220" r="4" fill="#f5f5f5"/>
92
+ <circle data-value="61" cx="202" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
93
+ <circle cx="202" cy="240" r="4" fill="#f5f5f5"/>
94
+ <circle data-value="61" cx="202" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
95
+ <circle cx="214" cy="230" r="4" fill="#f5f5f5"/>
96
+ <circle data-value="67" cx="214" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
97
+ <circle cx="218" cy="220" r="4" fill="#f5f5f5"/>
98
+ <circle data-value="69" cx="218" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
99
+ <circle cx="226" cy="230" r="4" fill="#f5f5f5"/>
100
+ <circle data-value="73" cx="226" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
101
+ <circle cx="232" cy="220" r="4" fill="#f5f5f5"/>
102
+ <circle data-value="76" cx="232" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
103
+ <circle cx="232" cy="240" r="4" fill="#f5f5f5"/>
104
+ <circle data-value="76" cx="232" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
105
+ <circle cx="234" cy="210" r="4" fill="#f5f5f5"/>
106
+ <circle data-value="77" cx="234" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
107
+ <circle cx="240" cy="230" r="4" fill="#f5f5f5"/>
108
+ <circle data-value="80" cx="240" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
109
+ <circle cx="240" cy="250" r="4" fill="#f5f5f5"/>
110
+ <circle data-value="80" cx="240" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
111
+ <circle cx="244" cy="220" r="4" fill="#f5f5f5"/>
112
+ <circle data-value="82" cx="244" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
113
+ <circle cx="244" cy="240" r="4" fill="#f5f5f5"/>
114
+ <circle data-value="82" cx="244" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
115
+ <circle cx="246" cy="210" r="4" fill="#f5f5f5"/>
116
+ <circle data-value="83" cx="246" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
117
+ <circle cx="248" cy="200" r="4" fill="#f5f5f5"/>
118
+ <circle data-value="84" cx="248" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
119
+ <circle cx="248" cy="260" r="4" fill="#f5f5f5"/>
120
+ <circle data-value="84" cx="248" cy="260" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
121
+ <circle cx="248" cy="190" r="4" fill="#f5f5f5"/>
122
+ <circle data-value="84" cx="248" cy="190" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
123
+ <circle cx="250" cy="230" r="4" fill="#f5f5f5"/>
124
+ <circle data-value="85" cx="250" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
125
+ <circle cx="250" cy="250" r="4" fill="#f5f5f5"/>
126
+ <circle data-value="85" cx="250" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
127
+ <circle cx="252" cy="270" r="4" fill="#f5f5f5"/>
128
+ <circle data-value="86" cx="252" cy="270" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
129
+ <circle cx="254" cy="220" r="4" fill="#f5f5f5"/>
130
+ <circle data-value="87" cx="254" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
131
+ <circle cx="256" cy="240" r="4" fill="#f5f5f5"/>
132
+ <circle data-value="88" cx="256" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
133
+ <circle cx="256" cy="210" r="4" fill="#f5f5f5"/>
134
+ <circle data-value="88" cx="256" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
135
+ <circle cx="256" cy="180" r="4" fill="#f5f5f5"/>
136
+ <circle data-value="88" cx="256" cy="180" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
137
+ <circle cx="258" cy="200" r="4" fill="#f5f5f5"/>
138
+ <circle data-value="89" cx="258" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
139
+ <circle cx="258" cy="260" r="4" fill="#f5f5f5"/>
140
+ <circle data-value="89" cx="258" cy="260" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
141
+ <circle cx="260" cy="230" r="4" fill="#f5f5f5"/>
142
+ <circle data-value="90" cx="260" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
143
+ <circle cx="260" cy="250" r="4" fill="#f5f5f5"/>
144
+ <circle data-value="90" cx="260" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
145
+ <circle cx="260" cy="190" r="4" fill="#f5f5f5"/>
146
+ <circle data-value="90" cx="260" cy="190" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
147
+ <circle cx="262" cy="270" r="4" fill="#f5f5f5"/>
148
+ <circle data-value="91" cx="262" cy="270" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
149
+ <circle cx="268" cy="220" r="4" fill="#f5f5f5"/>
150
+ <circle data-value="94" cx="268" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
151
+ <circle cx="270" cy="230" r="4" fill="#f5f5f5"/>
152
+ <circle data-value="95" cx="270" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
153
+ <circle cx="278" cy="220" r="4" fill="#f5f5f5"/>
154
+ <circle data-value="99" cx="278" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
155
+ <circle cx="278" cy="240" r="4" fill="#f5f5f5"/>
156
+ <circle data-value="99" cx="278" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
157
+ <circle cx="278" cy="210" r="4" fill="#f5f5f5"/>
158
+ <circle data-value="99" cx="278" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
159
+ <circle cx="286" cy="230" r="4" fill="#f5f5f5"/>
160
+ <circle data-value="103" cx="286" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
161
+ <circle cx="286" cy="250" r="4" fill="#f5f5f5"/>
162
+ <circle data-value="103" cx="286" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
163
+ <circle cx="290" cy="220" r="4" fill="#f5f5f5"/>
164
+ <circle data-value="105" cx="290" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
165
+ <circle cx="290" cy="240" r="4" fill="#f5f5f5"/>
166
+ <circle data-value="105" cx="290" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
167
+ <circle cx="292" cy="210" r="4" fill="#f5f5f5"/>
168
+ <circle data-value="106" cx="292" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
169
+ <circle cx="292" cy="200" r="4" fill="#f5f5f5"/>
170
+ <circle data-value="106" cx="292" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
171
+ <circle cx="292" cy="260" r="4" fill="#f5f5f5"/>
172
+ <circle data-value="106" cx="292" cy="260" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
173
+ <circle cx="292" cy="190" r="4" fill="#f5f5f5"/>
174
+ <circle data-value="106" cx="292" cy="190" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
175
+ <circle cx="292" cy="270" r="4" fill="#f5f5f5"/>
176
+ <circle data-value="106" cx="292" cy="270" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
177
+ <circle cx="294" cy="180" r="4" fill="#f5f5f5"/>
178
+ <circle data-value="107" cx="294" cy="180" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
179
+ <circle cx="294" cy="280" r="4" fill="#f5f5f5"/>
180
+ <circle data-value="107" cx="294" cy="280" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
181
+ <circle cx="296" cy="230" r="4" fill="#f5f5f5"/>
182
+ <circle data-value="108" cx="296" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
183
+ <circle cx="298" cy="250" r="4" fill="#f5f5f5"/>
184
+ <circle data-value="109" cx="298" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
185
+ <circle cx="300" cy="220" r="4" fill="#f5f5f5"/>
186
+ <circle data-value="110" cx="300" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
187
+ <circle cx="300" cy="240" r="4" fill="#f5f5f5"/>
188
+ <circle data-value="110" cx="300" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
189
+ <circle cx="300" cy="170" r="4" fill="#f5f5f5"/>
190
+ <circle data-value="110" cx="300" cy="170" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
191
+ <circle cx="306" cy="230" r="4" fill="#f5f5f5"/>
192
+ <circle data-value="113" cx="306" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
193
+ <circle cx="308" cy="210" r="4" fill="#f5f5f5"/>
194
+ <circle data-value="114" cx="308" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
195
+ <circle cx="308" cy="250" r="4" fill="#f5f5f5"/>
196
+ <circle data-value="114" cx="308" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
197
+ <circle cx="310" cy="220" r="4" fill="#f5f5f5"/>
198
+ <circle data-value="115" cx="310" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
199
+ <circle cx="310" cy="240" r="4" fill="#f5f5f5"/>
200
+ <circle data-value="115" cx="310" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
201
+ <circle cx="312" cy="200" r="4" fill="#f5f5f5"/>
202
+ <circle data-value="116" cx="312" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
203
+ <circle cx="314" cy="260" r="4" fill="#f5f5f5"/>
204
+ <circle data-value="117" cx="314" cy="260" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
205
+ <circle cx="314" cy="190" r="4" fill="#f5f5f5"/>
206
+ <circle data-value="117" cx="314" cy="190" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
207
+ <circle cx="314" cy="270" r="4" fill="#f5f5f5"/>
208
+ <circle data-value="117" cx="314" cy="270" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
209
+ <circle cx="316" cy="230" r="4" fill="#f5f5f5"/>
210
+ <circle data-value="118" cx="316" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
211
+ <circle cx="316" cy="180" r="4" fill="#f5f5f5"/>
212
+ <circle data-value="118" cx="316" cy="180" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
213
+ <circle cx="318" cy="210" r="4" fill="#f5f5f5"/>
214
+ <circle data-value="119" cx="318" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
215
+ <circle cx="320" cy="220" r="4" fill="#f5f5f5"/>
216
+ <circle data-value="120" cx="320" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
217
+ <circle cx="324" cy="240" r="4" fill="#f5f5f5"/>
218
+ <circle data-value="122" cx="324" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
219
+ <circle cx="326" cy="230" r="4" fill="#f5f5f5"/>
220
+ <circle data-value="123" cx="326" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
221
+ <circle cx="326" cy="250" r="4" fill="#f5f5f5"/>
222
+ <circle data-value="123" cx="326" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
223
+ <circle cx="334" cy="220" r="4" fill="#f5f5f5"/>
224
+ <circle data-value="127" cx="334" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
225
+ <circle cx="334" cy="240" r="4" fill="#f5f5f5"/>
226
+ <circle data-value="127" cx="334" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
227
+ <circle cx="334" cy="210" r="4" fill="#f5f5f5"/>
228
+ <circle data-value="127" cx="334" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
229
+ <circle cx="334" cy="200" r="4" fill="#f5f5f5"/>
230
+ <circle data-value="127" cx="334" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
231
+ <circle cx="336" cy="230" r="4" fill="#f5f5f5"/>
232
+ <circle data-value="128" cx="336" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
233
+ <circle cx="342" cy="250" r="4" fill="#f5f5f5"/>
234
+ <circle data-value="131" cx="342" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
235
+ <circle cx="344" cy="220" r="4" fill="#f5f5f5"/>
236
+ <circle data-value="132" cx="344" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
237
+ <circle cx="350" cy="230" r="4" fill="#f5f5f5"/>
238
+ <circle data-value="135" cx="350" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
239
+ <circle cx="354" cy="220" r="4" fill="#f5f5f5"/>
240
+ <circle data-value="137" cx="354" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
241
+ <circle cx="362" cy="230" r="4" fill="#f5f5f5"/>
242
+ <circle data-value="141" cx="362" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
243
+ <circle cx="366" cy="220" r="4" fill="#f5f5f5"/>
244
+ <circle data-value="143" cx="366" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
245
+ <circle cx="370" cy="240" r="4" fill="#f5f5f5"/>
246
+ <circle data-value="145" cx="370" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
247
+ <circle cx="370" cy="210" r="4" fill="#f5f5f5"/>
248
+ <circle data-value="145" cx="370" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
249
+ <circle cx="372" cy="230" r="4" fill="#f5f5f5"/>
250
+ <circle data-value="146" cx="372" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
251
+ <circle cx="376" cy="220" r="4" fill="#f5f5f5"/>
252
+ <circle data-value="148" cx="376" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
253
+ <circle cx="380" cy="240" r="4" fill="#f5f5f5"/>
254
+ <circle data-value="150" cx="380" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
255
+ <circle cx="382" cy="230" r="4" fill="#f5f5f5"/>
256
+ <circle data-value="151" cx="382" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
257
+ <circle cx="384" cy="210" r="4" fill="#f5f5f5"/>
258
+ <circle data-value="152" cx="384" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
259
+ <circle cx="384" cy="250" r="4" fill="#f5f5f5"/>
260
+ <circle data-value="152" cx="384" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
261
+ <circle cx="386" cy="220" r="4" fill="#f5f5f5"/>
262
+ <circle data-value="153" cx="386" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
263
+ <circle cx="390" cy="240" r="4" fill="#f5f5f5"/>
264
+ <circle data-value="155" cx="390" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
265
+ <circle cx="390" cy="200" r="4" fill="#f5f5f5"/>
266
+ <circle data-value="155" cx="390" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
267
+ <circle cx="394" cy="230" r="4" fill="#f5f5f5"/>
268
+ <circle data-value="157" cx="394" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
269
+ <circle cx="394" cy="210" r="4" fill="#f5f5f5"/>
270
+ <circle data-value="157" cx="394" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
271
+ <circle cx="402" cy="220" r="4" fill="#f5f5f5"/>
272
+ <circle data-value="161" cx="402" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
273
+ <circle cx="404" cy="230" r="4" fill="#f5f5f5"/>
274
+ <circle data-value="162" cx="404" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
275
+ <circle cx="408" cy="240" r="4" fill="#f5f5f5"/>
276
+ <circle data-value="164" cx="408" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
277
+ <circle cx="428" cy="230" r="4" fill="#f5f5f5"/>
278
+ <circle data-value="174" cx="428" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
279
+ <circle cx="444" cy="230" r="4" fill="#f5f5f5"/>
280
+ <circle data-value="182" cx="444" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
281
+ <circle cx="454" cy="230" r="4" fill="#f5f5f5"/>
282
+ <circle data-value="187" cx="454" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
283
+ <circle cx="458" cy="220" r="4" fill="#f5f5f5"/>
284
+ <circle data-value="189" cx="458" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
285
+ <circle cx="460" cy="240" r="4" fill="#f5f5f5"/>
286
+ <circle data-value="190" cx="460" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
287
+ <circle cx="468" cy="230" r="4" fill="#f5f5f5"/>
288
+ <circle data-value="194" cx="468" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
289
+ <circle cx="470" cy="220" r="4" fill="#f5f5f5"/>
290
+ <circle data-value="195" cx="470" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
291
+ <circle cx="470" cy="240" r="4" fill="#f5f5f5"/>
292
+ <circle data-value="195" cx="470" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
293
+ <circle cx="472" cy="210" r="4" fill="#f5f5f5"/>
294
+ <circle data-value="196" cx="472" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
295
+ <circle cx="472" cy="250" r="4" fill="#f5f5f5"/>
296
+ <circle data-value="196" cx="472" cy="250" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
297
+ <circle cx="474" cy="200" r="4" fill="#f5f5f5"/>
298
+ <circle data-value="197" cx="474" cy="200" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
299
+ <circle cx="482" cy="230" r="4" fill="#f5f5f5"/>
300
+ <circle data-value="201" cx="482" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
301
+ <circle cx="488" cy="220" r="4" fill="#f5f5f5"/>
302
+ <circle data-value="204" cx="488" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
303
+ <circle cx="492" cy="230" r="4" fill="#f5f5f5"/>
304
+ <circle data-value="206" cx="492" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
305
+ <circle cx="494" cy="240" r="4" fill="#f5f5f5"/>
306
+ <circle data-value="207" cx="494" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
307
+ <circle cx="508" cy="230" r="4" fill="#f5f5f5"/>
308
+ <circle data-value="214" cx="508" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
309
+ <circle cx="510" cy="220" r="4" fill="#f5f5f5"/>
310
+ <circle data-value="215" cx="510" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
311
+ <circle cx="514" cy="240" r="4" fill="#f5f5f5"/>
312
+ <circle data-value="217" cx="514" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
313
+ <circle cx="518" cy="230" r="4" fill="#f5f5f5"/>
314
+ <circle data-value="219" cx="518" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
315
+ <circle cx="530" cy="230" r="4" fill="#f5f5f5"/>
316
+ <circle data-value="225" cx="530" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
317
+ <circle cx="538" cy="220" r="4" fill="#f5f5f5"/>
318
+ <circle data-value="229" cx="538" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
319
+ <circle cx="546" cy="230" r="4" fill="#f5f5f5"/>
320
+ <circle data-value="233" cx="546" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
321
+ <circle cx="546" cy="240" r="4" fill="#f5f5f5"/>
322
+ <circle data-value="233" cx="546" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
323
+ <circle cx="556" cy="230" r="4" fill="#f5f5f5"/>
324
+ <circle data-value="238" cx="556" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
325
+ <circle cx="578" cy="230" r="4" fill="#f5f5f5"/>
326
+ <circle data-value="249" cx="578" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
327
+ <circle cx="590" cy="230" r="4" fill="#f5f5f5"/>
328
+ <circle data-value="255" cx="590" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
329
+ <circle cx="592" cy="220" r="4" fill="#f5f5f5"/>
330
+ <circle data-value="256" cx="592" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
331
+ <circle cx="608" cy="230" r="4" fill="#f5f5f5"/>
332
+ <circle data-value="264" cx="608" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
333
+ <circle cx="616" cy="220" r="4" fill="#f5f5f5"/>
334
+ <circle data-value="268" cx="616" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
335
+ <circle cx="634" cy="230" r="4" fill="#f5f5f5"/>
336
+ <circle data-value="277" cx="634" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
337
+ <circle cx="640" cy="220" r="4" fill="#f5f5f5"/>
338
+ <circle data-value="280" cx="640" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
339
+ <circle cx="646" cy="230" r="4" fill="#f5f5f5"/>
340
+ <circle data-value="283" cx="646" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
341
+ <circle cx="650" cy="220" r="4" fill="#f5f5f5"/>
342
+ <circle data-value="285" cx="650" cy="220" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
343
+ <circle cx="652" cy="240" r="4" fill="#f5f5f5"/>
344
+ <circle data-value="286" cx="652" cy="240" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
345
+ <circle cx="658" cy="230" r="4" fill="#f5f5f5"/>
346
+ <circle data-value="289" cx="658" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
347
+ <circle cx="658" cy="210" r="4" fill="#f5f5f5"/>
348
+ <circle data-value="289" cx="658" cy="210" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
349
+ <circle cx="704" cy="230" r="4" fill="#f5f5f5"/>
350
+ <circle data-value="312" cx="704" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
351
+ <circle cx="856" cy="230" r="4" fill="#f5f5f5"/>
352
+ <circle data-value="388" data-name="req-77d3" cx="856" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
353
+ <circle cx="884" cy="230" r="4" fill="#f5f5f5"/>
354
+ <circle data-value="402" data-name="req-09aa" cx="884" cy="230" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
355
+ <circle cx="942" cy="230" r="4" fill="#f5f5f5"/>
356
+ <circle data-value="431" data-name="req-4c1f" cx="942" cy="230" r="4" fill="rgba(191,69,32,0.55)" stroke="#bf4520" stroke-width="1.2"/>
357
+
358
+ <!-- Labels: the p99 tail only, one tier per label, alternating sides,
359
+ each bound to its dot by data-name and tied to it by a hairline
360
+ leader. verify-beeswarm.py proves each label sits nearer its own
361
+ dot than any other named dot along the value axis. -->
362
+ <line x1="856" y1="222" x2="856" y2="158" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
363
+ <rect x="826" y="141" width="60" height="12" rx="2" fill="#f5f5f5"/>
364
+ <text data-name="req-77d3" data-role="label" x="856" y="150" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">REQ-77D3</text>
365
+ <line x1="884" y1="238" x2="884" y2="298" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
366
+ <rect x="854" y="301" width="60" height="12" rx="2" fill="#f5f5f5"/>
367
+ <text data-name="req-09aa" data-role="label" x="884" y="310" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">REQ-09AA</text>
368
+ <line x1="942" y1="222" x2="942" y2="128" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
369
+ <rect x="912" y="111" width="60" height="12" rx="2" fill="#f5f5f5"/>
370
+ <text data-name="req-4c1f" data-role="label" x="942" y="120" fill="#2d3142" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">REQ-4C1F</text>
371
+
372
+ <!-- Legend -->
373
+ <line x1="40" y1="462" x2="960" y2="462" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
374
+ <text x="40" y="478" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
375
+ <text x="960" y="478" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em" text-anchor="end">ONE DOT = ONE REQUEST · VALUE AXIS 0–440 MS, LINEAR FROM ZERO · VERTICAL SPREAD IS PACKING, NOT A VALUE · ILLUSTRATIVE FIGURES, NOT MEASURED TRAFFIC</text>
376
+
377
+ <circle cx="52" cy="490" r="4" fill="rgba(191,69,32,0.55)" stroke="#bf4520" stroke-width="1.2"/>
378
+ <text x="68" y="494" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">req-4c1f · focal, the slowest request in the window</text>
379
+ <circle cx="660" cy="490" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
380
+ <text x="676" y="494" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">request · vertical offset is packing only</text>
381
+ </svg>
382
+ </div>
383
+ </body>
384
+ </html>
@@ -0,0 +1,127 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Checkout's box is the incident · Box plot</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500;600&display=swap" rel="stylesheet">
8
+ <style>
9
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
10
+ :root {
11
+ --color-paper: #f5f5f5;
12
+ --color-ink: #2d3142;
13
+ --color-muted: #4f5d75;
14
+ --color-accent: #bf4520;
15
+ --font-sans: 'Geist', system-ui, sans-serif;
16
+ --font-serif: 'Instrument Serif', serif;
17
+ --font-mono: 'Geist Mono', ui-monospace, monospace;
18
+ }
19
+ body { font-family: var(--font-sans); background: var(--color-paper); color: var(--color-ink); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 3rem 2rem; }
20
+ .frame { max-width: 1200px; width: 100%; }
21
+ .eyebrow { font-family: var(--font-mono); font-size: 0.66rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
22
+ h1 { font-family: var(--font-serif); font-size: clamp(1.5rem, 2.4vw + 0.75rem, 2rem); font-weight: 400; letter-spacing: -0.02em; line-height: 1.15; margin-bottom: 1.5rem; }
23
+ svg { width: 100%; min-width: 760px; display: block; }
24
+ </style>
25
+ </head>
26
+ <body>
27
+ <div class="frame">
28
+ <p class="eyebrow">Box plot · Diagram Design</p>
29
+ <h1>Checkout's box is the incident</h1>
30
+
31
+ <!-- Value axis: 0–400 ms over 800px, x = 160 + 2·ms, linear from zero.
32
+ Each series is a five-number summary on that shared scale; category y
33
+ is a label rail and carries no value. scripts/verify-box-plot.py
34
+ derives the scale from the declared quartiles and flags any mark
35
+ that disagrees with its peers. -->
36
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="box-plot-title box-plot-desc">
37
+ <title id="box-plot-title">Checkout's box is the incident</title>
38
+ <desc id="box-plot-desc">Horizontal box plots of per-request latency for five services on a shared linear axis from zero; Checkout's interquartile range runs from 80 to 200 ms with outliers at 388 and 396 ms.</desc>
39
+ <defs>
40
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
41
+ <circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
42
+ </pattern>
43
+ </defs>
44
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
45
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
46
+ <text x="560" y="456" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" letter-spacing="0.14em" text-anchor="middle">PER-REQUEST LATENCY, MS</text>
47
+ <line x1="160" y1="56" x2="160" y2="400" stroke="rgba(45,49,66,0.06)" stroke-width="0.8"/>
48
+ <line x1="360" y1="56" x2="360" y2="400" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
49
+ <line x1="560" y1="56" x2="560" y2="400" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
50
+ <line x1="760" y1="56" x2="760" y2="400" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
51
+ <line x1="960" y1="56" x2="960" y2="400" stroke="rgba(45,49,66,0.06)" stroke-width="0.8"/>
52
+ <line x1="160" y1="420" x2="960" y2="420" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
53
+ <text data-tick="x" data-value="0" x="160" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">0</text>
54
+ <text data-tick="x" data-value="100" x="360" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">100</text>
55
+ <text data-tick="x" data-value="200" x="560" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">200</text>
56
+ <text data-tick="x" data-value="300" x="760" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">300</text>
57
+ <text data-tick="x" data-value="400" x="960" y="440" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">400</text>
58
+ <!-- x = 160 + 2·ms over a 0–400 domain. Category y is a label rail.
59
+ scripts/verify-box-plot.py derives the value scale from the
60
+ declared five-number summaries and flags any mark that disagrees. -->
61
+ <g data-name="Auth" data-q1="18" data-q2="22" data-q3="28" data-wlo="12" data-whi="40">
62
+ <line data-role="whisker-lo" x1="184" y1="80" x2="196" y2="80" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
63
+ <line data-role="whisker-hi" x1="216" y1="80" x2="240" y2="80" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
64
+ <line data-role="cap" x1="184" y1="72" x2="184" y2="88" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
65
+ <line data-role="cap" x1="240" y1="72" x2="240" y2="88" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
66
+ <rect x="196" y="64.0" width="20" height="32" rx="2" fill="#f5f5f5"/>
67
+ <rect data-role="box" x="196" y="64.0" width="20" height="32" rx="2" fill="rgba(45,49,66,0.15)" stroke="#4f5d75" stroke-width="1"/>
68
+ <line data-role="median" x1="204" y1="64.0" x2="204" y2="96.0" stroke="#2d3142" stroke-width="1.5"/>
69
+ <text data-name="Auth" x="148" y="84" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Auth</text>
70
+ </g>
71
+ <g data-name="Catalog" data-q1="30" data-q2="46" data-q3="70" data-wlo="16" data-whi="90">
72
+ <line data-role="whisker-lo" x1="192" y1="148" x2="220" y2="148" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
73
+ <line data-role="whisker-hi" x1="300" y1="148" x2="340" y2="148" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
74
+ <line data-role="cap" x1="192" y1="140" x2="192" y2="156" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
75
+ <line data-role="cap" x1="340" y1="140" x2="340" y2="156" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
76
+ <rect x="220" y="132.0" width="80" height="32" rx="2" fill="#f5f5f5"/>
77
+ <rect data-role="box" x="220" y="132.0" width="80" height="32" rx="2" fill="rgba(45,49,66,0.15)" stroke="#4f5d75" stroke-width="1"/>
78
+ <line data-role="median" x1="252" y1="132.0" x2="252" y2="164.0" stroke="#2d3142" stroke-width="1.5"/>
79
+ <text data-name="Catalog" x="148" y="152" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Catalog</text>
80
+ </g>
81
+ <g data-name="Checkout" data-q1="80" data-q2="120" data-q3="200" data-wlo="40" data-whi="280">
82
+ <line data-role="whisker-lo" x1="240" y1="216" x2="320" y2="216" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
83
+ <line data-role="whisker-hi" x1="560" y1="216" x2="720" y2="216" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
84
+ <line data-role="cap" x1="240" y1="208" x2="240" y2="224" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
85
+ <line data-role="cap" x1="720" y1="208" x2="720" y2="224" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
86
+ <rect x="320" y="200.0" width="240" height="32" rx="2" fill="#f5f5f5"/>
87
+ <rect data-role="box" x="320" y="200.0" width="240" height="32" rx="2" fill="rgba(191,69,32,0.12)" stroke="#bf4520" stroke-width="1.2"/>
88
+ <line data-role="median" x1="400" y1="200.0" x2="400" y2="232.0" stroke="#2d3142" stroke-width="1.5"/>
89
+ <circle cx="936" cy="216" r="4" fill="#f5f5f5"/>
90
+ <circle data-outlier="Checkout" data-x="388" cx="936" cy="216" r="4" fill="rgba(191,69,32,0.55)" stroke="#bf4520" stroke-width="0.75"/>
91
+ <circle cx="952" cy="216" r="4" fill="#f5f5f5"/>
92
+ <circle data-outlier="Checkout" data-x="396" cx="952" cy="216" r="4" fill="rgba(191,69,32,0.55)" stroke="#bf4520" stroke-width="0.75"/>
93
+ <text data-name="Checkout" x="148" y="220" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Checkout</text>
94
+ </g>
95
+ <g data-name="Search" data-q1="22" data-q2="28" data-q3="40" data-wlo="8" data-whi="64">
96
+ <line data-role="whisker-lo" x1="176" y1="284" x2="204" y2="284" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
97
+ <line data-role="whisker-hi" x1="240" y1="284" x2="288" y2="284" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
98
+ <line data-role="cap" x1="176" y1="276" x2="176" y2="292" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
99
+ <line data-role="cap" x1="288" y1="276" x2="288" y2="292" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
100
+ <rect x="204" y="268.0" width="36" height="32" rx="2" fill="#f5f5f5"/>
101
+ <rect data-role="box" x="204" y="268.0" width="36" height="32" rx="2" fill="rgba(45,49,66,0.15)" stroke="#4f5d75" stroke-width="1"/>
102
+ <line data-role="median" x1="216" y1="268.0" x2="216" y2="300.0" stroke="#2d3142" stroke-width="1.5"/>
103
+ <text data-name="Search" x="148" y="288" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Search</text>
104
+ </g>
105
+ <g data-name="Billing" data-q1="36" data-q2="42" data-q3="50" data-wlo="20" data-whi="70">
106
+ <line data-role="whisker-lo" x1="200" y1="352" x2="232" y2="352" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
107
+ <line data-role="whisker-hi" x1="260" y1="352" x2="300" y2="352" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
108
+ <line data-role="cap" x1="200" y1="344" x2="200" y2="360" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
109
+ <line data-role="cap" x1="300" y1="344" x2="300" y2="360" stroke="rgba(45,49,66,0.55)" stroke-width="1"/>
110
+ <rect x="232" y="336.0" width="28" height="32" rx="2" fill="#f5f5f5"/>
111
+ <rect data-role="box" x="232" y="336.0" width="28" height="32" rx="2" fill="rgba(45,49,66,0.15)" stroke="#4f5d75" stroke-width="1"/>
112
+ <line data-role="median" x1="244" y1="336.0" x2="244" y2="368.0" stroke="#2d3142" stroke-width="1.5"/>
113
+ <circle cx="352" cy="352" r="4" fill="#f5f5f5"/>
114
+ <circle data-outlier="Billing" data-x="96" cx="352" cy="352" r="4" fill="rgba(45,49,66,0.55)" stroke="#4f5d75" stroke-width="0.75"/>
115
+ <text data-name="Billing" x="148" y="356" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Billing</text>
116
+ </g>
117
+ <line x1="40" y1="462" x2="960" y2="462" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
118
+ <text x="40" y="478" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
119
+ <text x="960" y="478" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.06em" text-anchor="end">BOX = IQR · LINE = MEDIAN · DOT = OUTLIER</text>
120
+ <rect x="44" y="484" width="16" height="10" rx="2" fill="rgba(191,69,32,0.12)" stroke="#bf4520" stroke-width="1.2"/>
121
+ <text x="68" y="494" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Checkout · focal, the IQR that will page</text>
122
+ <rect x="360" y="484" width="16" height="10" rx="2" fill="rgba(45,49,66,0.15)" stroke="#4f5d75" stroke-width="1"/>
123
+ <text x="384" y="494" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">service · box is q1–q3, whisker to the last inlier</text>
124
+ </svg>
125
+ </div>
126
+ </body>
127
+ </html>