@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,126 @@
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>AI app stack · Layer hierarchy</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; --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 0.9fr; gap: 1rem; margin-top: 1.5rem; }
20
+ @media (max-width: 820px) { .cards { grid-template-columns: 1fr; } }
21
+ .card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
22
+ .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; }
23
+ .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); }
24
+ .card-dot { width: 7px; height: 7px; border-radius: 50%; }
25
+ .card-dot.ink { background: var(--color-ink); } .card-dot.muted { background: var(--color-muted); } .card-dot.coral { background: var(--color-accent); }
26
+ .card h3 { font-size: 0.875rem; font-weight: 600; }
27
+ .card p, .card ul { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; list-style: none; }
28
+ .card li { margin-bottom: 0.3rem; padding-left: 0.875rem; position: relative; }
29
+ .card li::before { content: '—'; position: absolute; left: 0; color: rgba(45,49,66,0.25); font-size: 0.75rem; }
30
+ .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; }
31
+ </style>
32
+ </head>
33
+ <body>
34
+ <div class="container">
35
+ <div class="header">
36
+ <p class="header-eyebrow">Layer stack · Diagram Design</p>
37
+ <h1>AI app stack · Where the work actually happens</h1>
38
+ <p class="subtitle">Five layers between silicon and the user. Most teams over-invest in the model and under-invest in the harness — which is the layer that decides whether the app feels magical or flaky.</p>
39
+ </div>
40
+
41
+ <div class="diagram-container">
42
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="layers-full-title layers-full-desc">
43
+ <title id="layers-full-title">AI app stack · Where the work actually happens</title>
44
+ <desc id="layers-full-desc">Layer stack showing model weights, SDK, prompts, agent harness, and UI surface, with the agent harness highlighted as the focal layer.</desc>
45
+ <defs>
46
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
47
+ <circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
48
+ </pattern>
49
+ </defs>
50
+
51
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
52
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
53
+
54
+ <!-- Direction column (left margin) -->
55
+ <text x="60" y="68" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
56
+ <line x1="80" y1="80" x2="80" y2="400" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
57
+ <polygon points="76,80 84,80 80,72" fill="#4f5d75"/>
58
+ <text x="60" y="416" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
59
+
60
+ <!-- Stack container hairlines (top + bottom edges) -->
61
+ <line x1="120" y1="80" x2="960" y2="80" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
62
+ <line x1="120" y1="400" x2="960" y2="400" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
63
+
64
+ <!-- L5 — UI (top layer, near-white fill) -->
65
+ <rect x="120" y="80" width="840" height="64" fill="#ffffff"/>
66
+ <line x1="120" y1="144" x2="960" y2="144" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
67
+ <text x="140" y="116" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
68
+ <text x="260" y="118" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
69
+ <text x="940" y="118" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
70
+
71
+ <!-- L4 — Agent harness (FOCAL, coral tint + coral stroke) -->
72
+ <rect x="120" y="144" width="840" height="64" fill="rgba(235,108,54,0.08)"/>
73
+ <rect x="120" y="144" width="840" height="64" fill="none" stroke="#eb6c36" stroke-width="1"/>
74
+ <text x="140" y="180" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
75
+ <text x="260" y="182" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
76
+ <text x="940" y="182" fill="#eb6c36" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
77
+
78
+ <!-- L3 — Prompt layer -->
79
+ <rect x="120" y="208" width="840" height="64" fill="#f5f5f5"/>
80
+ <line x1="120" y1="272" x2="960" y2="272" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
81
+ <text x="140" y="244" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
82
+ <text x="260" y="246" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
83
+ <text x="940" y="246" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
84
+
85
+ <!-- L2 — SDK -->
86
+ <rect x="120" y="272" width="840" height="64" fill="#ececec"/>
87
+ <line x1="120" y1="336" x2="960" y2="336" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
88
+ <text x="140" y="308" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
89
+ <text x="260" y="310" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
90
+ <text x="940" y="310" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
91
+
92
+ <!-- L1 — Model -->
93
+ <rect x="120" y="336" width="840" height="64" fill="#ececec"/>
94
+ <text x="140" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
95
+ <text x="260" y="374" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
96
+ <text x="940" y="374" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
97
+
98
+ <!-- Caption -->
99
+ <text x="120" y="456" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
100
+ <text x="240" y="456" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
101
+ </svg>
102
+ </div>
103
+
104
+ <div class="cards">
105
+ <div class="card">
106
+ <p class="eyebrow">THE HEADLINE</p>
107
+ <div class="card-header"><span class="card-dot coral"></span><h3>Coral marks the layer that pays rent</h3></div>
108
+ <p>Swapping models is a knob. Rewriting the harness is a product decision. The coral band says: this is the layer where you out-execute the competition, not the one where you chase leaderboards.</p>
109
+ </div>
110
+ <div class="card">
111
+ <div class="card-header"><span class="card-dot ink"></span><h3>Reading the stack</h3></div>
112
+ <ul><li>Abstraction rises up the left column</li><li>L-index on the left, note on the right</li><li>Hairlines between layers, no shadows</li><li>Fill shade shifts from paper-2 to white</li></ul>
113
+ </div>
114
+ <div class="card">
115
+ <div class="card-header"><span class="card-dot muted"></span><h3>Why only five</h3></div>
116
+ <p>Six-plus layers become a legend, not a diagram. Five holds the whole thing on one screen — every band readable without squinting, every note a scan away.</p>
117
+ </div>
118
+ </div>
119
+
120
+ <div class="footer">
121
+ <span>ai app stack · layer hierarchy</span>
122
+ <span>example · schematic skill</span>
123
+ </div>
124
+ </div>
125
+ </body>
126
+ </html>
@@ -0,0 +1,123 @@
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>AI app stack · Layer hierarchy</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">Layer stack · Diagram Design</p>
59
+ <h1>AI app stack · Where the work actually happens</h1>
60
+
61
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="layers-title layers-desc">
62
+ <title id="layers-title">AI app stack · Where the work actually happens</title>
63
+ <desc id="layers-desc">Layer stack showing model weights, SDK, prompts, agent harness, and UI surface, with the agent harness highlighted as the focal layer.</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
+ <!-- Direction column (left margin) -->
74
+ <text x="60" y="68" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">ABSTRACTION</text>
75
+ <line x1="80" y1="80" x2="80" y2="400" stroke="rgba(45,49,66,0.30)" stroke-width="1"/>
76
+ <polygon points="76,80 84,80 80,72" fill="#4f5d75"/>
77
+ <text x="60" y="416" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">SILICON</text>
78
+
79
+ <!-- Stack container hairlines (top + bottom edges) -->
80
+ <line x1="120" y1="80" x2="960" y2="80" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
81
+ <line x1="120" y1="400" x2="960" y2="400" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
82
+
83
+ <!-- L5 — UI (top layer, near-white fill) -->
84
+ <rect x="120" y="80" width="840" height="64" fill="#ffffff"/>
85
+ <line x1="120" y1="144" x2="960" y2="144" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
86
+ <text x="140" y="116" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L5</text>
87
+ <text x="260" y="118" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">UI surface</text>
88
+ <text x="940" y="118" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">chat, editor, canvas</text>
89
+
90
+ <!-- L4 — Agent harness (FOCAL, coral tint + coral stroke) -->
91
+ <rect x="120" y="144" width="840" height="64" fill="rgba(235,108,54,0.08)"/>
92
+ <rect x="120" y="144" width="840" height="64" fill="none" stroke="#eb6c36" stroke-width="1"/>
93
+ <text x="140" y="180" fill="#eb6c36" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em" font-weight="600">L4</text>
94
+ <text x="260" y="182" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Agent harness</text>
95
+ <text x="940" y="182" fill="#eb6c36" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">tools, memory, loop</text>
96
+
97
+ <!-- L3 — Prompt layer -->
98
+ <rect x="120" y="208" width="840" height="64" fill="#f5f5f5"/>
99
+ <line x1="120" y1="272" x2="960" y2="272" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
100
+ <text x="140" y="244" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L3</text>
101
+ <text x="260" y="246" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Prompt layer</text>
102
+ <text x="940" y="246" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">system, few-shot, caching</text>
103
+
104
+ <!-- L2 — SDK -->
105
+ <rect x="120" y="272" width="840" height="64" fill="#ececec"/>
106
+ <line x1="120" y1="336" x2="960" y2="336" stroke="rgba(45,49,66,0.12)" stroke-width="1"/>
107
+ <text x="140" y="308" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L2</text>
108
+ <text x="260" y="310" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">SDK / client</text>
109
+ <text x="940" y="310" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">auth, retries, streaming</text>
110
+
111
+ <!-- L1 — Model -->
112
+ <rect x="120" y="336" width="840" height="64" fill="#ececec"/>
113
+ <text x="140" y="372" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.14em">L1</text>
114
+ <text x="260" y="374" fill="#2d3142" font-size="16" font-weight="600" font-family="'Geist', sans-serif">Model weights</text>
115
+ <text x="940" y="374" fill="#4f5d75" font-size="10" font-family="'Geist Mono', monospace" text-anchor="end" letter-spacing="0.08em">opus, sonnet, haiku</text>
116
+
117
+ <!-- Caption -->
118
+ <text x="120" y="456" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">FOCAL LAYER</text>
119
+ <text x="240" y="456" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif" font-style="italic">The harness is where most product differentiation actually lives — tools, memory, and the loop that stitches model calls into useful work.</text>
120
+ </svg>
121
+ </div>
122
+ </body>
123
+ </html>
@@ -0,0 +1,111 @@
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>Weekly signups · Line chart · 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">Line · Diagram Design</p>
21
+ <h1>Weekly signups · Organic leads the growth</h1>
22
+
23
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="line-dark-title line-dark-desc">
24
+ <title id="line-dark-title">Weekly signups · Organic leads the growth</title>
25
+ <desc id="line-dark-desc">Line chart showing weekly signups from organic, direct, and referral channels across weeks W1 through W8.</desc>
26
+ <defs>
27
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
28
+ <circle cx="1" cy="1" r="0.9" fill="rgba(245,245,245,0.10)"/>
29
+ </pattern>
30
+ </defs>
31
+
32
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
33
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
34
+
35
+ <!-- Y-axis rotated label -->
36
+ <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">SIGNUPS / WEEK</text>
37
+
38
+ <!-- Gridlines -->
39
+ <line x1="80" y1="357" x2="960" y2="357" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
40
+ <line x1="80" y1="293" x2="960" y2="293" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
41
+ <line x1="80" y1="230" x2="960" y2="230" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
42
+ <line x1="80" y1="167" x2="960" y2="167" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
43
+ <line x1="80" y1="103" x2="960" y2="103" stroke="rgba(245,245,245,0.08)" stroke-width="0.8"/>
44
+ <line x1="80" y1="40" x2="960" y2="40" stroke="rgba(245,245,245,0.06)" stroke-width="0.8"/>
45
+
46
+ <!-- Axes -->
47
+ <line x1="80" y1="40" x2="80" y2="420" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
48
+ <line x1="80" y1="420" x2="960" y2="420" stroke="rgba(245,245,245,0.20)" stroke-width="1"/>
49
+
50
+ <!-- Y-axis labels -->
51
+ <text x="72" y="361" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">40</text>
52
+ <text x="72" y="297" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">80</text>
53
+ <text x="72" y="234" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">120</text>
54
+ <text x="72" y="171" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">160</text>
55
+ <text x="72" y="107" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">200</text>
56
+ <text x="72" y="44" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">240</text>
57
+
58
+ <!-- ─── SERIES (non-focal drawn first) ─── -->
59
+ <!-- Referral: [45,52,48,60,55,68,62,75] series-2 dusty-blue -->
60
+ <polyline points="80,349 200,338 320,344 440,325 560,333 680,312 800,322 920,301"
61
+ fill="none" stroke="#82a0c0" stroke-width="1.2" stroke-linejoin="round"/>
62
+
63
+ <!-- Direct: [80,82,88,90,86,92,95,98] series-1 sage -->
64
+ <polyline points="80,293 200,290 320,281 440,278 560,284 680,274 800,270 920,265"
65
+ fill="none" stroke="#9caf8f" stroke-width="1.2" stroke-linejoin="round"/>
66
+
67
+ <!-- Organic FOCAL area fill (subtle) -->
68
+ <polygon points="80,230 200,206 320,186 440,164 560,175 680,138 800,111 920,88 920,420 80,420"
69
+ fill="rgba(240,138,89,0.08)"/>
70
+
71
+ <!-- Organic FOCAL line: [120,135,148,162,155,178,195,210] accent -->
72
+ <polyline points="80,230 200,206 320,186 440,164 560,175 680,138 800,111 920,88"
73
+ fill="none" stroke="#f08a59" stroke-width="1.8" stroke-linejoin="round"/>
74
+
75
+ <!-- Focal vertex dots -->
76
+ <circle cx="80" cy="230" r="4" fill="#f08a59"/>
77
+ <circle cx="200" cy="206" r="4" fill="#f08a59"/>
78
+ <circle cx="320" cy="186" r="4" fill="#f08a59"/>
79
+ <circle cx="440" cy="164" r="4" fill="#f08a59"/>
80
+ <circle cx="560" cy="175" r="4" fill="#f08a59"/>
81
+ <circle cx="680" cy="138" r="4" fill="#f08a59"/>
82
+ <circle cx="800" cy="111" r="4" fill="#f08a59"/>
83
+ <circle cx="920" cy="88" r="4" fill="#f08a59"/>
84
+
85
+ <!-- X-axis labels -->
86
+ <text x="80" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W1</text>
87
+ <text x="200" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W2</text>
88
+ <text x="320" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W3</text>
89
+ <text x="440" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W4</text>
90
+ <text x="560" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W5</text>
91
+ <text x="680" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W6</text>
92
+ <text x="800" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W7</text>
93
+ <text x="920" y="440" fill="#bfc0c0" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W8</text>
94
+
95
+ <!-- Legend -->
96
+ <line x1="40" y1="462" x2="960" y2="462" stroke="rgba(245,245,245,0.10)" stroke-width="0.8"/>
97
+ <text x="40" y="478" fill="#bfc0c0" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
98
+
99
+ <line x1="40" y1="492" x2="64" y2="492" stroke="#f08a59" stroke-width="1.8"/>
100
+ <circle cx="52" cy="492" r="4" fill="#f08a59"/>
101
+ <text x="72" y="496" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Organic · focal</text>
102
+
103
+ <line x1="200" y1="492" x2="224" y2="492" stroke="#9caf8f" stroke-width="1.2"/>
104
+ <text x="232" y="496" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Direct</text>
105
+
106
+ <line x1="316" y1="492" x2="340" y2="492" stroke="#82a0c0" stroke-width="1.2"/>
107
+ <text x="348" y="496" fill="#bfc0c0" font-size="8.5" font-family="'Geist', sans-serif">Referral</text>
108
+ </svg>
109
+ </div>
110
+ </body>
111
+ </html>
@@ -0,0 +1,105 @@
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>Weekly signups · Line chart</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; --series-1:#7c8f6f; --series-2:#5e7a9b; --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: 760px; display: block; }
19
+ .cards { display: grid; grid-template-columns: 1.1fr 1fr 0.9fr; gap: 1rem; margin-top: 1.5rem; }
20
+ @media (max-width: 720px) { .cards { grid-template-columns: 1fr; } }
21
+ .card { background: #fff; border-radius: 6px; border: 1px solid var(--color-rule); padding: 1.25rem; }
22
+ .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; }
23
+ .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); }
24
+ .card-dot { width: 7px; height: 7px; border-radius: 50%; }
25
+ .card-dot.coral { background: var(--color-accent); } .card-dot.sage { background: var(--series-1); } .card-dot.dusty { background: var(--series-2); }
26
+ .card h3 { font-size: 0.875rem; font-weight: 600; }
27
+ .card p { color: var(--color-muted); font-size: 0.8125rem; line-height: 1.55; }
28
+ .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; }
29
+ </style>
30
+ </head>
31
+ <body>
32
+ <div class="container">
33
+ <div class="header">
34
+ <p class="header-eyebrow">Line · Diagram Design</p>
35
+ <h1>Weekly signups · Organic leads the growth</h1>
36
+ <p class="subtitle">Signup volume by acquisition channel over eight weeks. Organic search is both the largest and fastest-growing channel; Direct is the stable baseline.</p>
37
+ </div>
38
+ <div class="diagram-container">
39
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="line-full-title line-full-desc">
40
+ <title id="line-full-title">Weekly signups · Organic leads the growth</title>
41
+ <desc id="line-full-desc">Line chart showing weekly signups from organic, direct, and referral channels across weeks W1 through W8.</desc>
42
+ <defs><pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse"><circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/></pattern></defs>
43
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
44
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
45
+ <text transform="rotate(-90 24 230)" x="24" y="230" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" letter-spacing="0.14em" text-anchor="middle">SIGNUPS / WEEK</text>
46
+ <line x1="80" y1="357" x2="960" y2="357" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
47
+ <line x1="80" y1="293" x2="960" y2="293" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
48
+ <line x1="80" y1="230" x2="960" y2="230" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
49
+ <line x1="80" y1="167" x2="960" y2="167" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
50
+ <line x1="80" y1="103" x2="960" y2="103" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
51
+ <line x1="80" y1="40" x2="960" y2="40" stroke="rgba(45,49,66,0.06)" stroke-width="0.8"/>
52
+ <line x1="80" y1="40" x2="80" y2="420" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
53
+ <line x1="80" y1="420" x2="960" y2="420" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
54
+ <text x="72" y="361" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">40</text>
55
+ <text x="72" y="297" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">80</text>
56
+ <text x="72" y="234" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">120</text>
57
+ <text x="72" y="171" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">160</text>
58
+ <text x="72" y="107" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">200</text>
59
+ <text x="72" y="44" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">240</text>
60
+ <polyline points="80,349 200,338 320,344 440,325 560,333 680,312 800,322 920,301" fill="none" stroke="#5e7a9b" stroke-width="1.2" stroke-linejoin="round"/>
61
+ <polyline points="80,293 200,290 320,281 440,278 560,284 680,274 800,270 920,265" fill="none" stroke="#7c8f6f" stroke-width="1.2" stroke-linejoin="round"/>
62
+ <polygon points="80,230 200,206 320,186 440,164 560,175 680,138 800,111 920,88 920,420 80,420" fill="rgba(235,108,54,0.06)"/>
63
+ <polyline points="80,230 200,206 320,186 440,164 560,175 680,138 800,111 920,88" fill="none" stroke="#eb6c36" stroke-width="1.8" stroke-linejoin="round"/>
64
+ <circle cx="80" cy="230" r="4" fill="#eb6c36"/><circle cx="200" cy="206" r="4" fill="#eb6c36"/><circle cx="320" cy="186" r="4" fill="#eb6c36"/><circle cx="440" cy="164" r="4" fill="#eb6c36"/>
65
+ <circle cx="560" cy="175" r="4" fill="#eb6c36"/><circle cx="680" cy="138" r="4" fill="#eb6c36"/><circle cx="800" cy="111" r="4" fill="#eb6c36"/><circle cx="920" cy="88" r="4" fill="#eb6c36"/>
66
+ <text x="80" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W1</text>
67
+ <text x="200" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W2</text>
68
+ <text x="320" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W3</text>
69
+ <text x="440" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W4</text>
70
+ <text x="560" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W5</text>
71
+ <text x="680" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W6</text>
72
+ <text x="800" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W7</text>
73
+ <text x="920" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W8</text>
74
+ <line x1="40" y1="462" x2="960" y2="462" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
75
+ <text x="40" y="478" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
76
+ <line x1="40" y1="492" x2="64" y2="492" stroke="#eb6c36" stroke-width="1.8"/><circle cx="52" cy="492" r="4" fill="#eb6c36"/>
77
+ <text x="72" y="496" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Organic · focal</text>
78
+ <line x1="200" y1="492" x2="224" y2="492" stroke="#7c8f6f" stroke-width="1.2"/>
79
+ <text x="232" y="496" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Direct</text>
80
+ <line x1="316" y1="492" x2="340" y2="492" stroke="#5e7a9b" stroke-width="1.2"/>
81
+ <text x="348" y="496" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Referral</text>
82
+ </svg>
83
+ </div>
84
+ <div class="cards">
85
+ <div class="card">
86
+ <p class="eyebrow">FOCAL · ORGANIC</p>
87
+ <div class="card-header"><span class="card-dot coral"></span><h3>Organic search driving 55% of new signups</h3></div>
88
+ <p>75% week-over-week growth over 8 weeks — from 120 to 210 signups. Two long-form guides published in W4 account for the step change. The W5 dip is a weekday holiday effect.</p>
89
+ </div>
90
+ <div class="card">
91
+ <div class="card-header"><span class="card-dot sage"></span><h3>Direct: stable core</h3></div>
92
+ <p>22% growth (80→98) — this is mostly returning users and brand-aware discovery. The near-flat slope is a healthy baseline, not stagnation. It means the product retains its direct audience while organic expands.</p>
93
+ </div>
94
+ <div class="card">
95
+ <div class="card-header"><span class="card-dot dusty"></span><h3>Referral: early signal</h3></div>
96
+ <p>67% growth (45→75), driven by one integration partner. Volatile week-to-week but directionally positive. Worth a dedicated channel review before investing further in partner programmes.</p>
97
+ </div>
98
+ </div>
99
+ <div class="footer">
100
+ <span>weekly signups · acquisition channels</span>
101
+ <span>example · diagram design</span>
102
+ </div>
103
+ </div>
104
+ </body>
105
+ </html>
@@ -0,0 +1,111 @@
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>Weekly signups · Line chart</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">Line · Diagram Design</p>
21
+ <h1>Weekly signups · Organic leads the growth</h1>
22
+
23
+ <svg viewBox="0 0 1000 500" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="line-title line-desc">
24
+ <title id="line-title">Weekly signups · Organic leads the growth</title>
25
+ <desc id="line-desc">Line chart showing weekly signups from organic, direct, and referral channels across weeks W1 through W8.</desc>
26
+ <defs>
27
+ <pattern id="dots" width="22" height="22" patternUnits="userSpaceOnUse">
28
+ <circle cx="1" cy="1" r="0.9" fill="rgba(45,49,66,0.10)"/>
29
+ </pattern>
30
+ </defs>
31
+
32
+ <rect width="100%" height="100%" fill="#f5f5f5"/>
33
+ <rect width="100%" height="100%" fill="url(#dots)" opacity="0.55"/>
34
+
35
+ <!-- Y-axis rotated label -->
36
+ <text transform="rotate(-90 24 230)" x="24" y="230" fill="#4f5d75" font-size="7" font-family="'Geist Mono', monospace" letter-spacing="0.14em" text-anchor="middle">SIGNUPS / WEEK</text>
37
+
38
+ <!-- Gridlines -->
39
+ <line x1="80" y1="357" x2="960" y2="357" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
40
+ <line x1="80" y1="293" x2="960" y2="293" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
41
+ <line x1="80" y1="230" x2="960" y2="230" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
42
+ <line x1="80" y1="167" x2="960" y2="167" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
43
+ <line x1="80" y1="103" x2="960" y2="103" stroke="rgba(45,49,66,0.08)" stroke-width="0.8"/>
44
+ <line x1="80" y1="40" x2="960" y2="40" stroke="rgba(45,49,66,0.06)" stroke-width="0.8"/>
45
+
46
+ <!-- Axes -->
47
+ <line x1="80" y1="40" x2="80" y2="420" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
48
+ <line x1="80" y1="420" x2="960" y2="420" stroke="rgba(45,49,66,0.25)" stroke-width="1"/>
49
+
50
+ <!-- Y-axis labels -->
51
+ <text x="72" y="361" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">40</text>
52
+ <text x="72" y="297" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">80</text>
53
+ <text x="72" y="234" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">120</text>
54
+ <text x="72" y="171" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">160</text>
55
+ <text x="72" y="107" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">200</text>
56
+ <text x="72" y="44" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" text-anchor="end">240</text>
57
+
58
+ <!-- ─── SERIES (non-focal drawn first) ─── -->
59
+ <!-- Referral: [45,52,48,60,55,68,62,75] series-2 dusty-blue -->
60
+ <polyline points="80,349 200,338 320,344 440,325 560,333 680,312 800,322 920,301"
61
+ fill="none" stroke="#5e7a9b" stroke-width="1.2" stroke-linejoin="round"/>
62
+
63
+ <!-- Direct: [80,82,88,90,86,92,95,98] series-1 sage -->
64
+ <polyline points="80,293 200,290 320,281 440,278 560,284 680,274 800,270 920,265"
65
+ fill="none" stroke="#7c8f6f" stroke-width="1.2" stroke-linejoin="round"/>
66
+
67
+ <!-- Organic FOCAL area fill (subtle) -->
68
+ <polygon points="80,230 200,206 320,186 440,164 560,175 680,138 800,111 920,88 920,420 80,420"
69
+ fill="rgba(235,108,54,0.06)"/>
70
+
71
+ <!-- Organic FOCAL line: [120,135,148,162,155,178,195,210] accent -->
72
+ <polyline points="80,230 200,206 320,186 440,164 560,175 680,138 800,111 920,88"
73
+ fill="none" stroke="#eb6c36" stroke-width="1.8" stroke-linejoin="round"/>
74
+
75
+ <!-- Focal vertex dots -->
76
+ <circle cx="80" cy="230" r="4" fill="#eb6c36"/>
77
+ <circle cx="200" cy="206" r="4" fill="#eb6c36"/>
78
+ <circle cx="320" cy="186" r="4" fill="#eb6c36"/>
79
+ <circle cx="440" cy="164" r="4" fill="#eb6c36"/>
80
+ <circle cx="560" cy="175" r="4" fill="#eb6c36"/>
81
+ <circle cx="680" cy="138" r="4" fill="#eb6c36"/>
82
+ <circle cx="800" cy="111" r="4" fill="#eb6c36"/>
83
+ <circle cx="920" cy="88" r="4" fill="#eb6c36"/>
84
+
85
+ <!-- X-axis labels -->
86
+ <text x="80" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W1</text>
87
+ <text x="200" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W2</text>
88
+ <text x="320" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W3</text>
89
+ <text x="440" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W4</text>
90
+ <text x="560" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W5</text>
91
+ <text x="680" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W6</text>
92
+ <text x="800" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W7</text>
93
+ <text x="920" y="440" fill="#4f5d75" font-size="9" font-family="'Geist Mono', monospace" text-anchor="middle">W8</text>
94
+
95
+ <!-- Legend -->
96
+ <line x1="40" y1="462" x2="960" y2="462" stroke="rgba(45,49,66,0.10)" stroke-width="0.8"/>
97
+ <text x="40" y="478" fill="#4f5d75" font-size="8" font-family="'Geist Mono', monospace" letter-spacing="0.18em">LEGEND</text>
98
+
99
+ <line x1="40" y1="492" x2="64" y2="492" stroke="#eb6c36" stroke-width="1.8"/>
100
+ <circle cx="52" cy="492" r="4" fill="#eb6c36"/>
101
+ <text x="72" y="496" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Organic · focal</text>
102
+
103
+ <line x1="200" y1="492" x2="224" y2="492" stroke="#7c8f6f" stroke-width="1.2"/>
104
+ <text x="232" y="496" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Direct</text>
105
+
106
+ <line x1="316" y1="492" x2="340" y2="492" stroke="#5e7a9b" stroke-width="1.2"/>
107
+ <text x="348" y="496" fill="#4f5d75" font-size="8.5" font-family="'Geist', sans-serif">Referral</text>
108
+ </svg>
109
+ </div>
110
+ </body>
111
+ </html>