@taloswork/ose-shared 0.1.8 → 0.1.9

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 (155) hide show
  1. package/package.json +3 -3
  2. package/skills/cozy-static-svg/SKILL.md +76 -0
  3. package/skills/cozy-static-svg/references/approved-preview.png +0 -0
  4. package/skills/cozy-static-svg/references/cross-platform.md +73 -0
  5. package/skills/cozy-static-svg/references/moon_keeps_watch.svg +229 -0
  6. package/skills/cozy-static-svg/references/style-anchor.md +271 -0
  7. package/skills/cozy-static-svg/scripts/artkit.py +321 -0
  8. package/skills/cozy-static-svg/scripts/to_png.py +333 -0
  9. package/skills/diagram-design/SKILL.md +568 -0
  10. package/skills/diagram-design/assets/example-architecture-dark.html +182 -0
  11. package/skills/diagram-design/assets/example-architecture-full.html +194 -0
  12. package/skills/diagram-design/assets/example-architecture.html +183 -0
  13. package/skills/diagram-design/assets/example-bar-dark.html +129 -0
  14. package/skills/diagram-design/assets/example-bar-full.html +105 -0
  15. package/skills/diagram-design/assets/example-bar.html +129 -0
  16. package/skills/diagram-design/assets/example-data-flow-dark.html +143 -0
  17. package/skills/diagram-design/assets/example-data-flow-full.html +185 -0
  18. package/skills/diagram-design/assets/example-data-flow.html +143 -0
  19. package/skills/diagram-design/assets/example-datalake-dark.html +243 -0
  20. package/skills/diagram-design/assets/example-datalake-full.html +248 -0
  21. package/skills/diagram-design/assets/example-datalake.html +269 -0
  22. package/skills/diagram-design/assets/example-dp-integration-dark.html +80 -0
  23. package/skills/diagram-design/assets/example-dp-integration-full.html +90 -0
  24. package/skills/diagram-design/assets/example-dp-integration.html +80 -0
  25. package/skills/diagram-design/assets/example-dp-security-matrix-dark.html +31 -0
  26. package/skills/diagram-design/assets/example-dp-security-matrix-full.html +32 -0
  27. package/skills/diagram-design/assets/example-dp-security-matrix.html +88 -0
  28. package/skills/diagram-design/assets/example-er-dark.html +202 -0
  29. package/skills/diagram-design/assets/example-er-full.html +205 -0
  30. package/skills/diagram-design/assets/example-er.html +202 -0
  31. package/skills/diagram-design/assets/example-flowchart-dark.html +156 -0
  32. package/skills/diagram-design/assets/example-flowchart-full.html +159 -0
  33. package/skills/diagram-design/assets/example-flowchart.html +156 -0
  34. package/skills/diagram-design/assets/example-gantt-dark.html +137 -0
  35. package/skills/diagram-design/assets/example-gantt-full.html +127 -0
  36. package/skills/diagram-design/assets/example-gantt.html +137 -0
  37. package/skills/diagram-design/assets/example-high-level-dark.html +251 -0
  38. package/skills/diagram-design/assets/example-high-level-full.html +247 -0
  39. package/skills/diagram-design/assets/example-high-level-vertical-dark.html +274 -0
  40. package/skills/diagram-design/assets/example-high-level-vertical-full.html +252 -0
  41. package/skills/diagram-design/assets/example-high-level-vertical.html +325 -0
  42. package/skills/diagram-design/assets/example-high-level.html +301 -0
  43. package/skills/diagram-design/assets/example-import-drawio.html +185 -0
  44. package/skills/diagram-design/assets/example-import-mermaid.html +70 -0
  45. package/skills/diagram-design/assets/example-it-state-dark.html +90 -0
  46. package/skills/diagram-design/assets/example-it-state-full.html +69 -0
  47. package/skills/diagram-design/assets/example-it-state.html +128 -0
  48. package/skills/diagram-design/assets/example-layers-dark.html +123 -0
  49. package/skills/diagram-design/assets/example-layers-full.html +126 -0
  50. package/skills/diagram-design/assets/example-layers.html +123 -0
  51. package/skills/diagram-design/assets/example-line-dark.html +111 -0
  52. package/skills/diagram-design/assets/example-line-full.html +105 -0
  53. package/skills/diagram-design/assets/example-line.html +111 -0
  54. package/skills/diagram-design/assets/example-loop-dark.html +100 -0
  55. package/skills/diagram-design/assets/example-loop-full.html +137 -0
  56. package/skills/diagram-design/assets/example-loop-terminal.html +347 -0
  57. package/skills/diagram-design/assets/example-loop.html +100 -0
  58. package/skills/diagram-design/assets/example-medallion-dark.html +159 -0
  59. package/skills/diagram-design/assets/example-medallion-full.html +201 -0
  60. package/skills/diagram-design/assets/example-medallion.html +159 -0
  61. package/skills/diagram-design/assets/example-nested-dark.html +132 -0
  62. package/skills/diagram-design/assets/example-nested-full.html +135 -0
  63. package/skills/diagram-design/assets/example-nested.html +136 -0
  64. package/skills/diagram-design/assets/example-org-chart-dark.html +45 -0
  65. package/skills/diagram-design/assets/example-org-chart-full.html +45 -0
  66. package/skills/diagram-design/assets/example-org-chart.html +45 -0
  67. package/skills/diagram-design/assets/example-paved-road-animated.html +546 -0
  68. package/skills/diagram-design/assets/example-policy-trace-animated.html +490 -0
  69. package/skills/diagram-design/assets/example-process-dark.html +64 -0
  70. package/skills/diagram-design/assets/example-process-full.html +74 -0
  71. package/skills/diagram-design/assets/example-process.html +64 -0
  72. package/skills/diagram-design/assets/example-pyramid-dark.html +119 -0
  73. package/skills/diagram-design/assets/example-pyramid-full.html +122 -0
  74. package/skills/diagram-design/assets/example-pyramid.html +119 -0
  75. package/skills/diagram-design/assets/example-quadrant-consultant.html +166 -0
  76. package/skills/diagram-design/assets/example-quadrant-dark.html +135 -0
  77. package/skills/diagram-design/assets/example-quadrant-full.html +138 -0
  78. package/skills/diagram-design/assets/example-quadrant.html +135 -0
  79. package/skills/diagram-design/assets/example-queue-animated.html +577 -0
  80. package/skills/diagram-design/assets/example-radar-dark.html +139 -0
  81. package/skills/diagram-design/assets/example-radar-full.html +135 -0
  82. package/skills/diagram-design/assets/example-radar.html +139 -0
  83. package/skills/diagram-design/assets/example-scatter-dark.html +141 -0
  84. package/skills/diagram-design/assets/example-scatter-full.html +116 -0
  85. package/skills/diagram-design/assets/example-scatter.html +141 -0
  86. package/skills/diagram-design/assets/example-sequence-dark.html +222 -0
  87. package/skills/diagram-design/assets/example-sequence-full.html +388 -0
  88. package/skills/diagram-design/assets/example-sequence-oauth-dark.html +188 -0
  89. package/skills/diagram-design/assets/example-sequence-oauth-full.html +350 -0
  90. package/skills/diagram-design/assets/example-sequence-oauth.html +227 -0
  91. package/skills/diagram-design/assets/example-sequence.html +222 -0
  92. package/skills/diagram-design/assets/example-state-dark.html +147 -0
  93. package/skills/diagram-design/assets/example-state-full.html +150 -0
  94. package/skills/diagram-design/assets/example-state.html +147 -0
  95. package/skills/diagram-design/assets/example-swimlane-dark.html +172 -0
  96. package/skills/diagram-design/assets/example-swimlane-full.html +175 -0
  97. package/skills/diagram-design/assets/example-swimlane.html +172 -0
  98. package/skills/diagram-design/assets/example-timeline-dark.html +135 -0
  99. package/skills/diagram-design/assets/example-timeline-full.html +138 -0
  100. package/skills/diagram-design/assets/example-timeline.html +135 -0
  101. package/skills/diagram-design/assets/example-tree-dark.html +173 -0
  102. package/skills/diagram-design/assets/example-tree-full.html +176 -0
  103. package/skills/diagram-design/assets/example-tree.html +173 -0
  104. package/skills/diagram-design/assets/example-venn-dark.html +132 -0
  105. package/skills/diagram-design/assets/example-venn-full.html +135 -0
  106. package/skills/diagram-design/assets/example-venn.html +110 -0
  107. package/skills/diagram-design/assets/icons.html +230 -0
  108. package/skills/diagram-design/assets/index.html +369 -0
  109. package/skills/diagram-design/assets/template-dark.html +85 -0
  110. package/skills/diagram-design/assets/template-full.html +413 -0
  111. package/skills/diagram-design/assets/template-motion.html +434 -0
  112. package/skills/diagram-design/assets/template-terminal.html +173 -0
  113. package/skills/diagram-design/assets/template.html +86 -0
  114. package/skills/diagram-design/references/animation.md +141 -0
  115. package/skills/diagram-design/references/export.md +136 -0
  116. package/skills/diagram-design/references/import-drawio.md +171 -0
  117. package/skills/diagram-design/references/import-mermaid.md +126 -0
  118. package/skills/diagram-design/references/onboarding.md +297 -0
  119. package/skills/diagram-design/references/output-spec.md +181 -0
  120. package/skills/diagram-design/references/primitive-annotation.md +36 -0
  121. package/skills/diagram-design/references/primitive-icons.md +827 -0
  122. package/skills/diagram-design/references/primitive-sketchy.md +43 -0
  123. package/skills/diagram-design/references/primitive-terminal.md +76 -0
  124. package/skills/diagram-design/references/semantic-patterns.md +122 -0
  125. package/skills/diagram-design/references/style-guide.md +139 -0
  126. package/skills/diagram-design/references/type-architecture.md +78 -0
  127. package/skills/diagram-design/references/type-bar.md +48 -0
  128. package/skills/diagram-design/references/type-data-flow.md +374 -0
  129. package/skills/diagram-design/references/type-dp-integration.md +410 -0
  130. package/skills/diagram-design/references/type-dp-security-matrix.md +379 -0
  131. package/skills/diagram-design/references/type-er.md +23 -0
  132. package/skills/diagram-design/references/type-flowchart.md +23 -0
  133. package/skills/diagram-design/references/type-gantt.md +45 -0
  134. package/skills/diagram-design/references/type-high-level.md +458 -0
  135. package/skills/diagram-design/references/type-it-state.md +470 -0
  136. package/skills/diagram-design/references/type-layers.md +26 -0
  137. package/skills/diagram-design/references/type-line.md +44 -0
  138. package/skills/diagram-design/references/type-loop.md +223 -0
  139. package/skills/diagram-design/references/type-medallion.md +356 -0
  140. package/skills/diagram-design/references/type-nested.md +22 -0
  141. package/skills/diagram-design/references/type-org-chart.md +44 -0
  142. package/skills/diagram-design/references/type-process.md +495 -0
  143. package/skills/diagram-design/references/type-pyramid.md +33 -0
  144. package/skills/diagram-design/references/type-quadrant.md +81 -0
  145. package/skills/diagram-design/references/type-radar.md +80 -0
  146. package/skills/diagram-design/references/type-scatter.md +39 -0
  147. package/skills/diagram-design/references/type-sequence.md +130 -0
  148. package/skills/diagram-design/references/type-state.md +21 -0
  149. package/skills/diagram-design/references/type-swimlane.md +20 -0
  150. package/skills/diagram-design/references/type-timeline.md +20 -0
  151. package/skills/diagram-design/references/type-tree.md +24 -0
  152. package/skills/diagram-design/references/type-venn.md +26 -0
  153. package/skills/diagram-design/scripts/drawio_extract.py +856 -0
  154. package/skills/diagram-design/scripts/mermaid_extract.py +1285 -0
  155. package/skills/diagram-design/scripts/self_check.py +389 -0
@@ -0,0 +1,139 @@
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>Storage backends · Capability radar</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: #2d3142;
12
+ --color-ink: #f5f5f5;
13
+ --color-muted: #bfc0c0;
14
+ --color-accent: #f08a59;
15
+ --font-sans: 'Geist', system-ui, sans-serif;
16
+ --font-serif: 'Instrument Serif', serif;
17
+ --font-mono: 'Geist Mono', ui-monospace, monospace;
18
+ }
19
+
20
+ body {
21
+ font-family: var(--font-sans);
22
+ background: var(--color-paper);
23
+ color: var(--color-ink);
24
+ min-height: 100vh;
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ padding: 3rem 2rem;
29
+ }
30
+
31
+ .frame { max-width: 1200px; width: 100%; }
32
+
33
+ .eyebrow {
34
+ font-family: var(--font-mono);
35
+ font-size: 0.66rem;
36
+ font-weight: 500;
37
+ letter-spacing: 0.18em;
38
+ text-transform: uppercase;
39
+ color: var(--color-muted);
40
+ margin-bottom: 0.5rem;
41
+ }
42
+
43
+ h1 {
44
+ font-family: var(--font-serif);
45
+ font-size: clamp(1.5rem, 2.4vw + 0.75rem, 2rem);
46
+ font-weight: 400;
47
+ letter-spacing: -0.02em;
48
+ line-height: 1.15;
49
+ color: var(--color-ink);
50
+ margin-bottom: 1.5rem;
51
+ }
52
+
53
+ svg { width: 100%; min-width: 900px; display: block; }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div class="frame">
58
+ <p class="eyebrow">Radar · Diagram Design</p>
59
+ <h1>Storage backends · Capability radar</h1>
60
+
61
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="radar-dark-title radar-dark-desc">
62
+ <title id="radar-dark-title">Storage backends · Capability radar</title>
63
+ <desc id="radar-dark-desc">Radar chart comparing MinIO, Amazon S3, Ceph, and Google Cloud Storage across five storage capabilities.</desc>
64
+ <defs>
65
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
66
+ <circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
67
+ </pattern>
68
+ </defs>
69
+
70
+ <rect width="100%" height="100%" fill="#2d3142"/>
71
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
72
+
73
+ <!-- Concentric grid rings -->
74
+ <polygon points="500,208 530,230 519,266 481,266 470,230" fill="none" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
75
+ <polygon points="500,176 561,220 538,292 462,292 439,220" fill="none" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
76
+ <polygon points="500,144 591,211 556,317 444,317 409,211" fill="none" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
77
+ <polygon points="500,112 622,201 575,343 425,343 378,201" fill="none" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
78
+ <polygon points="500,80 652,191 594,369 406,369 348,191" fill="none" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
79
+
80
+ <!-- Axis spokes -->
81
+ <line x1="500" y1="240" x2="500" y2="80" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
82
+ <line x1="500" y1="240" x2="652" y2="191" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
83
+ <line x1="500" y1="240" x2="594" y2="369" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
84
+ <line x1="500" y1="240" x2="406" y2="369" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
85
+ <line x1="500" y1="240" x2="348" y2="191" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
86
+
87
+ <!-- Axis labels -->
88
+ <text x="500" y="62" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Small-file handling</text>
89
+ <text x="669" y="189" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Large-object reads</text>
90
+ <text x="605" y="400" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Write throughput</text>
91
+ <text x="395" y="400" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Operational simplicity</text>
92
+ <text x="331" y="189" fill="#f5f5f5" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Iceberg integration</text>
93
+
94
+ <!-- Scale ticks -->
95
+ <text x="494" y="82" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">10</text>
96
+ <text x="494" y="114" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">8</text>
97
+ <text x="494" y="146" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">6</text>
98
+ <text x="494" y="178" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">4</text>
99
+ <text x="494" y="210" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">2</text>
100
+
101
+ <!-- Non-focal series -->
102
+ <!-- Ceph · series-2 dusty-blue dark -->
103
+ <polygon points="500,128 606,206 566,330 462,292 409,211" fill="rgba(130,160,192,0.22)" stroke="#82a0c0" stroke-width="1.5"/>
104
+ <!-- GCS · series-3 mustard dark -->
105
+ <polygon points="500,144 637,196 575,343 444,317 394,206" fill="rgba(211,173,122,0.22)" stroke="#d3ad7a" stroke-width="1.5"/>
106
+ <!-- Amazon S3 · series-1 sage dark -->
107
+ <polygon points="500,144 652,191 585,356 453,305 378,201" fill="rgba(156,175,143,0.22)" stroke="#9caf8f" stroke-width="1.5"/>
108
+
109
+ <!-- Focal series · MinIO -->
110
+ <polygon points="500,96 622,201 585,356 415,356 363,196" fill="rgba(240,138,89,0.22)" stroke="#f08a59" stroke-width="1.8"/>
111
+
112
+ <!-- Focal vertex dots -->
113
+ <circle cx="500" cy="96" r="4" fill="#f08a59"/>
114
+ <circle cx="622" cy="201" r="4" fill="#f08a59"/>
115
+ <circle cx="585" cy="356" r="4" fill="#f08a59"/>
116
+ <circle cx="415" cy="356" r="4" fill="#f08a59"/>
117
+ <circle cx="363" cy="196" r="4" fill="#f08a59"/>
118
+
119
+ <!-- Legend -->
120
+ <line x1="40" y1="456" x2="960" y2="456" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
121
+ <text x="40" y="472" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
122
+
123
+ <rect x="40" y="484" width="16" height="8" fill="rgba(240,138,89,0.22)" stroke="#f08a59" stroke-width="1.5"/>
124
+ <text x="64" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">MinIO · recommended</text>
125
+
126
+ <rect x="220" y="484" width="16" height="8" fill="rgba(156,175,143,0.22)" stroke="#9caf8f" stroke-width="1.5"/>
127
+ <text x="244" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Amazon S3</text>
128
+
129
+ <rect x="344" y="484" width="16" height="8" fill="rgba(130,160,192,0.22)" stroke="#82a0c0" stroke-width="1.5"/>
130
+ <text x="368" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Ceph</text>
131
+
132
+ <rect x="424" y="484" width="16" height="8" fill="rgba(211,173,122,0.22)" stroke="#d3ad7a" stroke-width="1.5"/>
133
+ <text x="448" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Google Cloud Storage</text>
134
+
135
+ <text x="608" y="492" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">One coral. Position is the signal — color reserved for the recommended option.</text>
136
+ </svg>
137
+ </div>
138
+ </body>
139
+ </html>
@@ -0,0 +1,135 @@
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>Storage backends · Capability radar</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 { --color-paper:#f5f5f5; --color-paper-2:#ececec; --color-ink:#2d3142; --color-muted:#4f5d75; --color-soft:#7a8399; --color-rule:rgba(45,49,66,0.12); --color-accent:#eb6c36; --color-link:#2e5aa8; --series-1:#7c8f6f; --series-2:#5e7a9b; --series-3:#b8915a; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
11
+ body { font-family: var(--font-sans); background: var(--color-paper); min-height: 100vh; padding: 3rem 2rem; color: var(--color-ink); }
12
+ .container { max-width: 1200px; margin: 0 auto; }
13
+ .header { margin-bottom: 2.5rem; }
14
+ .header-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.75rem; }
15
+ h1 { font-family: var(--font-serif); font-size: clamp(1.75rem, 3vw + 1rem, 2.5rem); font-weight: 400; letter-spacing: -0.02em; line-height: 1.1; margin-bottom: 0.5rem; }
16
+ .subtitle { font-size: 1rem; line-height: 1.55; color: var(--color-muted); max-width: 58ch; }
17
+ .diagram-container { background: var(--color-paper-2); border-radius: 8px; border: 1px solid var(--color-rule); padding: 1.5rem; overflow-x: auto; }
18
+ svg { width: 100%; min-width: 900px; display: block; }
19
+ .cards { display: grid; grid-template-columns: 1.1fr 1fr 1fr 0.9fr; gap: 1rem; margin-top: 1.5rem; }
20
+ @media (max-width: 980px) { .cards { grid-template-columns: 1fr 1fr; } }
21
+ @media (max-width: 600px) { .cards { grid-template-columns: 1fr; } }
22
+ .card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
23
+ .card .eyebrow { font-family: var(--font-mono); font-size: 0.5rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 0.5rem; }
24
+ .card-header { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.875rem; padding-bottom: 0.875rem; border-bottom: 1px solid rgba(45,49,66,0.08); }
25
+ .card-dot { width: 7px; height: 7px; border-radius: 50%; }
26
+ .card-dot.coral { background: var(--color-accent); }
27
+ .card-dot.sage { background: var(--series-1); }
28
+ .card-dot.dusty { background: var(--series-2); }
29
+ .card-dot.mustard { background: var(--series-3); }
30
+ .card h3 { font-size: 0.875rem; font-weight: 600; }
31
+ .card p { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; }
32
+ .footer { margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid rgba(45,49,66,0.10); font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.06em; color: var(--color-soft); display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem; }
33
+ </style>
34
+ </head>
35
+ <body>
36
+ <div class="container">
37
+ <div class="header">
38
+ <p class="header-eyebrow">Radar · Diagram Design</p>
39
+ <h1>Storage backends · Capability radar</h1>
40
+ <p class="subtitle">Four object-storage candidates scored 0–10 across five workload dimensions. The chart is a decision tool — the recommended option carries the only colored fill; everything else sits in the muted comparison palette.</p>
41
+ </div>
42
+
43
+ <div class="diagram-container">
44
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="radar-full-title radar-full-desc">
45
+ <title id="radar-full-title">Storage backends · Capability radar</title>
46
+ <desc id="radar-full-desc">Radar chart comparing MinIO, Amazon S3, Ceph, and Google Cloud Storage across five storage capabilities.</desc>
47
+ <defs>
48
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
49
+ <circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
50
+ </pattern>
51
+ </defs>
52
+
53
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
54
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
55
+
56
+ <polygon points="500,208 530,230 519,266 481,266 470,230" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
57
+ <polygon points="500,176 561,220 538,292 462,292 439,220" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
58
+ <polygon points="500,144 591,211 556,317 444,317 409,211" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
59
+ <polygon points="500,112 622,201 575,343 425,343 378,201" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
60
+ <polygon points="500,80 652,191 594,369 406,369 348,191" fill="none" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
61
+
62
+ <line x1="500" y1="240" x2="500" y2="80" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
63
+ <line x1="500" y1="240" x2="652" y2="191" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
64
+ <line x1="500" y1="240" x2="594" y2="369" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
65
+ <line x1="500" y1="240" x2="406" y2="369" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
66
+ <line x1="500" y1="240" x2="348" y2="191" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
67
+
68
+ <text x="500" y="62" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Small-file handling</text>
69
+ <text x="669" y="189" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Large-object reads</text>
70
+ <text x="605" y="400" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Write throughput</text>
71
+ <text x="395" y="400" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Operational simplicity</text>
72
+ <text x="331" y="189" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Iceberg integration</text>
73
+
74
+ <text x="494" y="82" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">10</text>
75
+ <text x="494" y="114" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">8</text>
76
+ <text x="494" y="146" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">6</text>
77
+ <text x="494" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">4</text>
78
+ <text x="494" y="210" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">2</text>
79
+
80
+ <polygon points="500,128 606,206 566,330 462,292 409,211" fill="rgba(94,122,155,0.18)" stroke="#5e7a9b" stroke-width="1.5"/>
81
+ <polygon points="500,144 637,196 575,343 444,317 394,206" fill="rgba(184,145,90,0.18)" stroke="#b8915a" stroke-width="1.5"/>
82
+ <polygon points="500,144 652,191 585,356 453,305 378,201" fill="rgba(124,143,111,0.18)" stroke="#7c8f6f" stroke-width="1.5"/>
83
+
84
+ <polygon points="500,96 622,201 585,356 415,356 363,196" fill="rgba(235,108,54,0.18)" stroke="#eb6c36" stroke-width="1.8"/>
85
+
86
+ <circle cx="500" cy="96" r="4" fill="#eb6c36"/>
87
+ <circle cx="622" cy="201" r="4" fill="#eb6c36"/>
88
+ <circle cx="585" cy="356" r="4" fill="#eb6c36"/>
89
+ <circle cx="415" cy="356" r="4" fill="#eb6c36"/>
90
+ <circle cx="363" cy="196" r="4" fill="#eb6c36"/>
91
+
92
+ <line x1="40" y1="456" x2="960" y2="456" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
93
+ <text x="40" y="472" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
94
+
95
+ <rect x="40" y="484" width="16" height="8" fill="rgba(235,108,54,0.18)" stroke="#eb6c36" stroke-width="1.5"/>
96
+ <text x="64" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">MinIO · recommended</text>
97
+
98
+ <rect x="220" y="484" width="16" height="8" fill="rgba(124,143,111,0.18)" stroke="#7c8f6f" stroke-width="1.5"/>
99
+ <text x="244" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Amazon S3</text>
100
+
101
+ <rect x="344" y="484" width="16" height="8" fill="rgba(94,122,155,0.18)" stroke="#5e7a9b" stroke-width="1.5"/>
102
+ <text x="368" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Ceph</text>
103
+
104
+ <rect x="424" y="484" width="16" height="8" fill="rgba(184,145,90,0.18)" stroke="#b8915a" stroke-width="1.5"/>
105
+ <text x="448" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Google Cloud Storage</text>
106
+ </svg>
107
+ </div>
108
+
109
+ <div class="cards">
110
+ <div class="card">
111
+ <p class="eyebrow">RECOMMENDED</p>
112
+ <div class="card-header"><span class="card-dot coral"></span><h3>MinIO</h3></div>
113
+ <p>9 across the board, weakest only on large-object reads. The clear pick when small-file performance and Iceberg integration matter and you can run the operator yourself.</p>
114
+ </div>
115
+ <div class="card">
116
+ <div class="card-header"><span class="card-dot sage"></span><h3>Amazon S3</h3></div>
117
+ <p>The reference implementation: top-class on large-object reads and write throughput, but a hard step down on operational simplicity once you factor in IAM, lifecycle, and bucket policy sprawl.</p>
118
+ </div>
119
+ <div class="card">
120
+ <div class="card-header"><span class="card-dot dusty"></span><h3>Ceph</h3></div>
121
+ <p>Capable across the board, but the lowest score on operational simplicity. Pick it when you already run Ceph or need block + object + file from one cluster — not for a fresh greenfield.</p>
122
+ </div>
123
+ <div class="card">
124
+ <div class="card-header"><span class="card-dot mustard"></span><h3>Google Cloud Storage</h3></div>
125
+ <p>Solid middle path. No standout dimension — which is itself an answer when the team optimises for "boring, managed, fine."</p>
126
+ </div>
127
+ </div>
128
+
129
+ <div class="footer">
130
+ <span>storage backends · capability radar</span>
131
+ <span>example · diagram design</span>
132
+ </div>
133
+ </div>
134
+ </body>
135
+ </html>
@@ -0,0 +1,139 @@
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>Storage backends · Capability radar</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: #eb6c36;
15
+ --font-sans: 'Geist', system-ui, sans-serif;
16
+ --font-serif: 'Instrument Serif', serif;
17
+ --font-mono: 'Geist Mono', ui-monospace, monospace;
18
+ }
19
+
20
+ body {
21
+ font-family: var(--font-sans);
22
+ background: var(--color-paper);
23
+ color: var(--color-ink);
24
+ min-height: 100vh;
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ padding: 3rem 2rem;
29
+ }
30
+
31
+ .frame { max-width: 1200px; width: 100%; }
32
+
33
+ .eyebrow {
34
+ font-family: var(--font-mono);
35
+ font-size: 0.66rem;
36
+ font-weight: 500;
37
+ letter-spacing: 0.18em;
38
+ text-transform: uppercase;
39
+ color: var(--color-muted);
40
+ margin-bottom: 0.5rem;
41
+ }
42
+
43
+ h1 {
44
+ font-family: var(--font-serif);
45
+ font-size: clamp(1.5rem, 2.4vw + 0.75rem, 2rem);
46
+ font-weight: 400;
47
+ letter-spacing: -0.02em;
48
+ line-height: 1.15;
49
+ color: var(--color-ink);
50
+ margin-bottom: 1.5rem;
51
+ }
52
+
53
+ svg { width: 100%; min-width: 900px; display: block; }
54
+ </style>
55
+ </head>
56
+ <body>
57
+ <div class="frame">
58
+ <p class="eyebrow">Radar · Diagram Design</p>
59
+ <h1>Storage backends · Capability radar</h1>
60
+
61
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="radar-title radar-desc">
62
+ <title id="radar-title">Storage backends · Capability radar</title>
63
+ <desc id="radar-desc">Radar chart comparing MinIO, Amazon S3, Ceph, and Google Cloud Storage across five storage capabilities.</desc>
64
+ <defs>
65
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
66
+ <circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
67
+ </pattern>
68
+ </defs>
69
+
70
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
71
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
72
+
73
+ <!-- Concentric grid rings (f = 0.2, 0.4, 0.6, 0.8, 1.0) -->
74
+ <polygon points="500,208 530,230 519,266 481,266 470,230" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
75
+ <polygon points="500,176 561,220 538,292 462,292 439,220" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
76
+ <polygon points="500,144 591,211 556,317 444,317 409,211" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
77
+ <polygon points="500,112 622,201 575,343 425,343 378,201" fill="none" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
78
+ <polygon points="500,80 652,191 594,369 406,369 348,191" fill="none" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
79
+
80
+ <!-- Axis spokes (center to outer vertex) -->
81
+ <line x1="500" y1="240" x2="500" y2="80" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
82
+ <line x1="500" y1="240" x2="652" y2="191" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
83
+ <line x1="500" y1="240" x2="594" y2="369" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
84
+ <line x1="500" y1="240" x2="406" y2="369" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
85
+ <line x1="500" y1="240" x2="348" y2="191" stroke="rgba(45,49,66,0.20)" stroke-width="1"/>
86
+
87
+ <!-- Axis labels (one word per spoke, Geist sans 11px 600) -->
88
+ <text x="500" y="62" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="middle">Small-file handling</text>
89
+ <text x="669" y="189" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Large-object reads</text>
90
+ <text x="605" y="400" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="start">Write throughput</text>
91
+ <text x="395" y="400" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Operational simplicity</text>
92
+ <text x="331" y="189" fill="#2d3142" font-size="11" font-weight="600" font-family="'Geist', sans-serif" text-anchor="end">Iceberg integration</text>
93
+
94
+ <!-- Scale ticks on first (top) axis only -->
95
+ <text x="494" y="82" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">10</text>
96
+ <text x="494" y="114" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">8</text>
97
+ <text x="494" y="146" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">6</text>
98
+ <text x="494" y="178" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">4</text>
99
+ <text x="494" y="210" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">2</text>
100
+
101
+ <!-- Non-focal series (smallest to largest, back to front) -->
102
+ <!-- Ceph · series-2 dusty-blue · [7,7,7,4,6] -->
103
+ <polygon points="500,128 606,206 566,330 462,292 409,211" fill="rgba(94,122,155,0.18)" stroke="#5e7a9b" stroke-width="1.5"/>
104
+ <!-- GCS · series-3 mustard · [6,9,8,6,7] -->
105
+ <polygon points="500,144 637,196 575,343 444,317 394,206" fill="rgba(184,145,90,0.18)" stroke="#b8915a" stroke-width="1.5"/>
106
+ <!-- Amazon S3 · series-1 sage · [6,10,9,5,8] -->
107
+ <polygon points="500,144 652,191 585,356 453,305 378,201" fill="rgba(124,143,111,0.18)" stroke="#7c8f6f" stroke-width="1.5"/>
108
+
109
+ <!-- Focal series · MinIO · accent · [9,8,9,9,9] -->
110
+ <polygon points="500,96 622,201 585,356 415,356 363,196" fill="rgba(235,108,54,0.18)" stroke="#eb6c36" stroke-width="1.8"/>
111
+
112
+ <!-- Focal vertex dots (only on focal series) -->
113
+ <circle cx="500" cy="96" r="4" fill="#eb6c36"/>
114
+ <circle cx="622" cy="201" r="4" fill="#eb6c36"/>
115
+ <circle cx="585" cy="356" r="4" fill="#eb6c36"/>
116
+ <circle cx="415" cy="356" r="4" fill="#eb6c36"/>
117
+ <circle cx="363" cy="196" r="4" fill="#eb6c36"/>
118
+
119
+ <!-- Legend -->
120
+ <line x1="40" y1="456" x2="960" y2="456" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
121
+ <text x="40" y="472" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
122
+
123
+ <rect x="40" y="484" width="16" height="8" fill="rgba(235,108,54,0.18)" stroke="#eb6c36" stroke-width="1.5"/>
124
+ <text x="64" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">MinIO · recommended</text>
125
+
126
+ <rect x="220" y="484" width="16" height="8" fill="rgba(124,143,111,0.18)" stroke="#7c8f6f" stroke-width="1.5"/>
127
+ <text x="244" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Amazon S3</text>
128
+
129
+ <rect x="344" y="484" width="16" height="8" fill="rgba(94,122,155,0.18)" stroke="#5e7a9b" stroke-width="1.5"/>
130
+ <text x="368" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Ceph</text>
131
+
132
+ <rect x="424" y="484" width="16" height="8" fill="rgba(184,145,90,0.18)" stroke="#b8915a" stroke-width="1.5"/>
133
+ <text x="448" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Google Cloud Storage</text>
134
+
135
+ <text x="608" y="492" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">One coral. Position is the signal — color reserved for the recommended option.</text>
136
+ </svg>
137
+ </div>
138
+ </body>
139
+ </html>
@@ -0,0 +1,141 @@
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>Deploy frequency vs lead time · Scatter · dark</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 { --color-paper:#f5f5f5; --color-ink:#2d3142; --color-muted:#4f5d75; --color-accent:#eb6c36; --font-sans:'Geist',system-ui,sans-serif; --font-serif:'Instrument Serif',serif; --font-mono:'Geist Mono',ui-monospace,monospace; }
11
+ 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; }
12
+ .frame { max-width: 1200px; width: 100%; }
13
+ .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; }
14
+ 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; }
15
+ svg { width: 100%; min-width: 760px; display: block; }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <div class="frame">
20
+ <p class="eyebrow">Scatter · Diagram Design</p>
21
+ <h1>Deploy frequency vs. lead time · 12 teams</h1>
22
+
23
+ <!-- X: 0-20 deploys/week → 880px. x = 80 + f/20*880 = 80+44*f -->
24
+ <!-- Y: 0-24 days lead time → 380px. y = 420 - lt/24*380. High lt = high y (worse) -->
25
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="scatter-dark-title scatter-dark-desc">
26
+ <title id="scatter-dark-title">Deploy frequency vs. lead time · 12 teams</title>
27
+ <desc id="scatter-dark-desc">Scatter plot showing twelve engineering teams by deploy frequency and lead time, with Platform in the best-performing quadrant.</desc>
28
+ <defs>
29
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
30
+ <circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
31
+ </pattern>
32
+ </defs>
33
+
34
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
35
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
36
+
37
+ <!-- Axis labels -->
38
+ <text transform="rotate(-90 24 230)" x="24" y="230" fill="#bfc0c0" font-size="7" font-family="'Geist Mono', monospace" letter-spacing="0.14em" text-anchor="middle">LEAD TIME (DAYS)</text>
39
+ <text x="520" y="492" fill="#bfc0c0" font-size="7" font-family="'Geist Mono', monospace" letter-spacing="0.14em" text-anchor="middle">DEPLOYS PER WEEK</text>
40
+
41
+ <!-- Gridlines -->
42
+ <!-- Horizontal (constant lead time) -->
43
+ <line x1="80" y1="325" x2="960" y2="325" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
44
+ <line x1="80" y1="230" x2="960" y2="230" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
45
+ <line x1="80" y1="135" x2="960" y2="135" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
46
+ <line x1="80" y1="40" x2="960" y2="40" stroke="rgba(245,245,245,0.06)" stroke-width="0.8"/>
47
+ <!-- Vertical (constant deploy freq) -->
48
+ <line x1="256" y1="40" x2="256" y2="420" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
49
+ <line x1="432" y1="40" x2="432" y2="420" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
50
+ <line x1="608" y1="40" x2="608" y2="420" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
51
+ <line x1="784" y1="40" x2="784" y2="420" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
52
+
53
+ <!-- Axes -->
54
+ <line x1="80" y1="40" x2="80" y2="420" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
55
+ <line x1="80" y1="420" x2="960" y2="420" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
56
+
57
+ <!-- Y-axis labels (lead time: 0 at bottom, 24 at top) -->
58
+ <text x="72" y="324" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">6</text>
59
+ <text x="72" y="234" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">12</text>
60
+ <text x="72" y="139" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">18</text>
61
+ <text x="72" y="44" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">24</text>
62
+ <text x="72" y="424" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">0</text>
63
+
64
+ <!-- X-axis labels (deploy frequency) -->
65
+ <text x="80" y="440" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">0</text>
66
+ <text x="256" y="440" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">4</text>
67
+ <text x="432" y="440" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">8</text>
68
+ <text x="608" y="440" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">12</text>
69
+ <text x="784" y="440" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">16</text>
70
+ <text x="960" y="440" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle">20</text>
71
+
72
+ <!-- Trend line (dashed, approximate) -->
73
+ <line x1="168" y1="103" x2="900" y2="388" stroke="rgba(245,245,245,0.20)" stroke-width="1" stroke-dasharray="4,3"/>
74
+
75
+ <!-- ─── DATA POINTS (non-focal first) ─── -->
76
+ <!-- (freq, lt) → (x=80+44*f, y=420-380*lt/24) -->
77
+ <!-- (2,20)→(168,103), (4,18)→(256,135), (4,16)→(256,167), (6,14)→(344,198) -->
78
+ <!-- (8,12)→(432,230), (8,10)→(432,262), (10,8)→(520,293), (12,6)→(608,325) -->
79
+ <!-- (12,10)→(608,262), (16,4)→(784,357), (18,3)→(872,372) FOCAL, (20,2)→(960,388) -->
80
+
81
+ <circle cx="168" cy="103" r="5" fill="#f5f5f5"/>
82
+ <circle cx="168" cy="103" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
83
+
84
+ <circle cx="256" cy="135" r="5" fill="#f5f5f5"/>
85
+ <circle cx="256" cy="135" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
86
+
87
+ <circle cx="256" cy="167" r="5" fill="#f5f5f5"/>
88
+ <circle cx="256" cy="167" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
89
+
90
+ <circle cx="344" cy="198" r="5" fill="#f5f5f5"/>
91
+ <circle cx="344" cy="198" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
92
+
93
+ <circle cx="432" cy="230" r="5" fill="#f5f5f5"/>
94
+ <circle cx="432" cy="230" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
95
+
96
+ <circle cx="432" cy="262" r="5" fill="#f5f5f5"/>
97
+ <circle cx="432" cy="262" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
98
+
99
+ <circle cx="520" cy="293" r="5" fill="#f5f5f5"/>
100
+ <circle cx="520" cy="293" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
101
+
102
+ <circle cx="608" cy="325" r="5" fill="#f5f5f5"/>
103
+ <circle cx="608" cy="325" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
104
+
105
+ <circle cx="608" cy="262" r="5" fill="#f5f5f5"/>
106
+ <circle cx="608" cy="262" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
107
+
108
+ <circle cx="784" cy="357" r="5" fill="#f5f5f5"/>
109
+ <circle cx="784" cy="357" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
110
+
111
+ <circle cx="960" cy="388" r="5" fill="#f5f5f5"/>
112
+ <circle cx="960" cy="388" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
113
+
114
+ <!-- FOCAL: Platform team (18,3) → (872,372) -->
115
+ <circle cx="872" cy="372" r="6" fill="#f5f5f5"/>
116
+ <circle cx="872" cy="372" r="6" fill="rgba(240,138,89,0.18)" stroke="#f08a59" stroke-width="1.2"/>
117
+
118
+ <!-- Focal label -->
119
+ <rect x="798" y="348" width="64" height="12" rx="2" fill="#f5f5f5"/>
120
+ <text x="830" y="357" fill="#f08a59" font-size="8" font-family="'Geist Mono', monospace" text-anchor="middle" letter-spacing="0.06em">PLATFORM</text>
121
+
122
+ <!-- Quadrant guides (optional) -->
123
+ <text x="88" y="56" fill="rgba(245,245,245,0.22)" font-size="8" font-family="'Geist Mono', monospace">HIGH LEAD TIME</text>
124
+ <text x="88" y="412" fill="rgba(245,245,245,0.22)" font-size="8" font-family="'Geist Mono', monospace">LOW LEAD TIME</text>
125
+
126
+ <!-- Legend -->
127
+ <line x1="40" y1="462" x2="960" y2="462" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
128
+ <text x="40" y="478" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
129
+
130
+ <circle cx="52" cy="490" r="6" fill="rgba(240,138,89,0.18)" stroke="#f08a59" stroke-width="1.2"/>
131
+ <text x="68" y="494" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Platform team · best performer</text>
132
+
133
+ <circle cx="256" cy="490" r="5" fill="rgba(191,192,192,0.20)" stroke="#bfc0c0" stroke-width="1"/>
134
+ <text x="272" y="494" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Engineering team</text>
135
+
136
+ <line x1="416" y1="490" x2="440" y2="490" stroke="rgba(245,245,245,0.20)" stroke-width="1" stroke-dasharray="4,3"/>
137
+ <text x="448" y="494" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Trend</text>
138
+ </svg>
139
+ </div>
140
+ </body>
141
+ </html>