@telepath-computer/television 0.1.177 → 0.1.179

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 (38) hide show
  1. package/dist/canonical/v1/components.js +25 -7
  2. package/dist/canonical/v1/styles.css +17 -1
  3. package/dist/cli.cjs +1187 -392
  4. package/dist/onboarding/README.md +35 -0
  5. package/dist/onboarding/business-ops/about.html +150 -0
  6. package/dist/onboarding/business-ops/retention-vs-releases.html +572 -0
  7. package/dist/onboarding/business-ops/revenue-vs-goals.html +621 -0
  8. package/dist/onboarding/onboarding-screens.json +167 -0
  9. package/dist/onboarding/productivity/about.html +149 -0
  10. package/dist/onboarding/productivity/company-todos/index.html +121 -0
  11. package/dist/onboarding/productivity/company-todos/task.css +205 -0
  12. package/dist/onboarding/productivity/company-todos/task.js +307 -0
  13. package/dist/onboarding/productivity/meeting-prep.html +440 -0
  14. package/dist/onboarding/productivity/priorities-today.html +409 -0
  15. package/dist/onboarding/productivity/todays-calendar/calendar.css +1 -0
  16. package/dist/onboarding/productivity/todays-calendar/calendar.js +716 -0
  17. package/dist/onboarding/productivity/todays-calendar/index.html +52 -0
  18. package/dist/onboarding/research/about.html +152 -0
  19. package/dist/onboarding/research/draft-blog-post.md +30 -0
  20. package/dist/onboarding/research/open-model-research.html +542 -0
  21. package/dist/onboarding/research/todays-news.html +503 -0
  22. package/dist/onboarding/{television-onboarding → tv-guide/welcome}/index.html +5 -5
  23. package/dist/skills/television/SKILL.md +44 -0
  24. package/dist/skills/tv-tasks/SKILL.md +241 -0
  25. package/dist/skills/tv-tasks/task.css +205 -0
  26. package/dist/skills/tv-tasks/task.js +307 -0
  27. package/dist/views/markdown/index.html +1 -1
  28. package/dist/web/assets/calendar-DToAnkzj.png +0 -0
  29. package/dist/web/assets/main-5017mprd.css +1 -0
  30. package/dist/web/assets/main-C-OjKUzX.js +865 -0
  31. package/dist/web/assets/markdown-DdDrJuVK.png +0 -0
  32. package/dist/web/assets/table-oeG9uAN1.png +0 -0
  33. package/dist/web/assets/tasks-D4xqXFPl.png +0 -0
  34. package/dist/web/index.html +2 -2
  35. package/package.json +1 -1
  36. package/dist/web/assets/main-BSAIRhnY.js +0 -768
  37. package/dist/web/assets/main-o9Z-XUYA.css +0 -1
  38. /package/dist/onboarding/{television-onboarding → tv-guide/welcome}/assets/television.svg +0 -0
@@ -0,0 +1,572 @@
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">
6
+ <title>Retention vs. recent releases</title>
7
+ <link rel="stylesheet" href="/canonical/v1/styles.css">
8
+ <script type="module" src="/canonical/v1/components.js"></script>
9
+ <style>
10
+ /* Shared base for onboarding artifacts ([[../index.md]]): document padding
11
+ and the centered content shell. Typography, text color, and background
12
+ are the canonical stylesheet's — nothing in this set restates or pins
13
+ them, so artifacts follow the active theme ([[../index.md#^respect-theme]]). */
14
+
15
+ * {
16
+ box-sizing: border-box;
17
+ }
18
+
19
+ body {
20
+ margin: 0;
21
+ padding: var(--space-32, 32px) var(--space-32, 32px) var(--space-64, 64px);
22
+ }
23
+
24
+ .shell {
25
+ max-width: 720px;
26
+ margin: 0 auto;
27
+ display: grid;
28
+ /* Pin the single column to the container so a wide child (a data table)
29
+ scrolls inside its own .table-wrap instead of stretching the track and
30
+ overflowing the card. */
31
+ grid-template-columns: minmax(0, 1fr);
32
+ gap: var(--space-20, 20px);
33
+ }
34
+
35
+ /* Card-density headings ([[../index.md]]): document-scale h1 is oversized
36
+ inside a TV card. */
37
+ h1 {
38
+ margin: 0;
39
+ font-size: var(--text-xl, 17px);
40
+ font-weight: 600;
41
+ line-height: 1.25;
42
+ }
43
+
44
+ /* A lead paragraph (the .lede or .summary-deck standfirst) belongs in the
45
+ header, tight beneath the title — not a full grid-gap below it. Every
46
+ onboarding artifact places its lead this way so the spacing is uniform. */
47
+ header > .lede,
48
+ header > .summary-deck {
49
+ margin-top: var(--space-8, 8px);
50
+ }
51
+
52
+
53
+ /* The hero header idiom ([[../index.md]]): a plain document header opening a
54
+ dashboard-shaped artifact — the title with a fictional freshness line and
55
+ an optional source/meta line, sitting on the document itself rather than
56
+ inside a card. */
57
+
58
+ header.hero h1 {
59
+ margin: 0 0 var(--space-6, 6px);
60
+ }
61
+
62
+ .generated {
63
+ color: var(--color-text-muted);
64
+ font-size: var(--text-sm, 12px);
65
+ font-weight: 500;
66
+ }
67
+
68
+ .meta-line {
69
+ margin-top: var(--space-4, 4px);
70
+ color: var(--color-text-muted);
71
+ font-size: var(--text-sm, 12px);
72
+ }
73
+
74
+
75
+ /* The panel/section idioms ([[../index.md]]): a bordered surface panel with
76
+ a heading and optional note, the muted summary-box, the section-title row,
77
+ and — for artifacts that lean on headings and spacing over nested cards —
78
+ the borderless .section and the .summary-deck lead paragraph. */
79
+
80
+ /* Borderless section: a title row (or heading) then its stack, no box. */
81
+ .section {
82
+ display: grid;
83
+ gap: var(--space-16, 16px);
84
+ }
85
+
86
+ /* Summary/lead as a standfirst paragraph — the borderless counterpart to
87
+ .summary-box. */
88
+ /* Lead/standfirst paragraph — the same size as the About .lede (body text),
89
+ not enlarged; it leads by position and primary color, not scale. */
90
+ .summary-deck {
91
+ margin: 0;
92
+ line-height: 1.5;
93
+ color: var(--color-text);
94
+ }
95
+
96
+ .panel {
97
+ padding: var(--space-20, 20px);
98
+ border: 1px solid var(--color-border);
99
+ border-radius: var(--radius-12, 12px);
100
+ background: var(--color-surface);
101
+ }
102
+
103
+ .panel h2 {
104
+ margin: 0 0 var(--space-4, 4px);
105
+ font-size: var(--text-lg, 15px);
106
+ font-weight: 600;
107
+ }
108
+
109
+ .panel .note {
110
+ margin: 0 0 var(--space-16, 16px);
111
+ color: var(--color-text-muted);
112
+ font-size: var(--text-sm, 12px);
113
+ }
114
+
115
+ .summary-box {
116
+ padding: var(--space-16, 16px) var(--space-20, 20px);
117
+ border: 1px solid var(--color-border-muted);
118
+ border-radius: var(--radius-12, 12px);
119
+ background: var(--color-surface-muted);
120
+ }
121
+
122
+ .summary-box h2 {
123
+ margin: 0 0 var(--space-8, 8px);
124
+ font-size: var(--text-lg, 15px);
125
+ font-weight: 600;
126
+ }
127
+
128
+ .summary-box p {
129
+ margin: 0;
130
+ line-height: 1.45;
131
+ }
132
+
133
+ .section-title {
134
+ display: flex;
135
+ justify-content: space-between;
136
+ align-items: baseline;
137
+ gap: var(--space-12, 12px);
138
+ margin-bottom: var(--space-12, 12px);
139
+ }
140
+
141
+ .section-title h2 {
142
+ margin: 0;
143
+ font-size: var(--text-lg, 15px);
144
+ font-weight: 600;
145
+ }
146
+
147
+ .section-title .note {
148
+ margin: 0;
149
+ color: var(--color-text-muted);
150
+ font-size: var(--text-sm, 12px);
151
+ }
152
+
153
+
154
+ /* The KPI row idiom ([[../index.md]]): a wrapping row of stat cards, each
155
+ an uppercase label, a large value (accented via --kpi-accent, a ramp
156
+ token), and a delta line. */
157
+
158
+ .kpi-row {
159
+ display: flex;
160
+ flex-wrap: wrap;
161
+ gap: var(--space-12, 12px);
162
+ }
163
+
164
+ .kpi {
165
+ flex: 1;
166
+ min-width: 120px;
167
+ padding: var(--space-12, 12px) var(--space-16, 16px);
168
+ border: 1px solid var(--color-border);
169
+ border-radius: var(--radius-12, 12px);
170
+ background: var(--color-surface);
171
+ }
172
+
173
+ .kpi .label {
174
+ margin-bottom: var(--space-4, 4px);
175
+ color: var(--color-text-muted);
176
+ font-size: var(--text-sm, 12px);
177
+ letter-spacing: 0.05em;
178
+ text-transform: uppercase;
179
+ }
180
+
181
+ .kpi .value {
182
+ font-size: 24px;
183
+ font-weight: 700;
184
+ line-height: 1;
185
+ color: var(--kpi-accent, var(--color-text));
186
+ }
187
+
188
+ .kpi .delta {
189
+ margin-top: var(--space-4, 4px);
190
+ font-size: var(--text-sm, 12px);
191
+ font-weight: 600;
192
+ }
193
+
194
+ .delta.up { color: var(--green-600); }
195
+ .delta.down { color: var(--red-600); }
196
+
197
+
198
+ /* Shared chart scaffold for the dashboard artifacts ([[../index.md]]): the
199
+ wide dashboard shell, the responsive inline-SVG plumbing and common
200
+ axis/grid chrome, the legend row, and the narrow-viewport padding. Each
201
+ dashboard's own styles.css keeps only its series colors, swatch shape, and
202
+ any chart-specific chrome — SVG presentation attributes can't take var(),
203
+ so fills and strokes live in CSS. */
204
+
205
+ /* Dashboards run wider than the set's default shell. */
206
+ .shell {
207
+ max-width: 920px;
208
+ gap: var(--space-16, 16px);
209
+ }
210
+
211
+ /* Responsive inline SVG chart. */
212
+ .chart-container {
213
+ position: relative;
214
+ width: 100%;
215
+ overflow: hidden;
216
+ }
217
+
218
+ svg.chart {
219
+ display: block;
220
+ width: 100%;
221
+ height: auto;
222
+ }
223
+
224
+ svg.chart text {
225
+ font-family: var(--font-sans);
226
+ }
227
+
228
+ /* Common axis/grid chrome. */
229
+ svg.chart .grid { stroke: var(--color-border-muted); }
230
+ svg.chart .axis-line { stroke: var(--color-border); }
231
+ svg.chart .axis-y { fill: var(--color-text-muted); }
232
+
233
+ /* Legend row. */
234
+ .legend {
235
+ display: flex;
236
+ gap: var(--space-20, 20px);
237
+ flex-wrap: wrap;
238
+ margin-top: var(--space-12, 12px);
239
+ font-size: var(--text-sm, 12px);
240
+ color: var(--color-text-muted);
241
+ }
242
+
243
+ .legend-item {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: var(--space-6, 6px);
247
+ }
248
+
249
+ /* Narrow viewport (the default 528px card): tighten document padding so the
250
+ scaled-down chart keeps as much width as possible. */
251
+ @media (max-width: 600px) {
252
+ body {
253
+ padding: var(--space-16, 16px) var(--space-16, 16px) var(--space-48, 48px);
254
+ }
255
+ }
256
+
257
+
258
+ /* Retention vs. recent releases ([[index.md]]): artifact-specific styling only
259
+ — the KPI accent sequence, this chart's retention series and release-marker
260
+ colors, its legend swatches, and the release-impact list. The dashboard
261
+ shell, chart plumbing, common chrome, and legend row come from the shared
262
+ chart scaffold ([shared/chart.css](../../shared/chart.css)). */
263
+
264
+ /* KPI value accents are a positional sequence (green/orange/blue), owned
265
+ here rather than carried as ramp tokens in data. Each card sets the
266
+ --kpi-accent custom prop the shared KPI idiom reads. */
267
+ .kpi-row .kpi:nth-child(1) .value { --kpi-accent: var(--green-600); }
268
+ .kpi-row .kpi:nth-child(2) .value { --kpi-accent: var(--orange-600); }
269
+ .kpi-row .kpi:nth-child(3) .value { --kpi-accent: var(--blue-600); }
270
+
271
+ /* This chart's series and labels (SVG presentation attributes can't take
272
+ var(), so every fill/stroke lives here). */
273
+ svg.chart .axis-x { fill: var(--color-text-muted); }
274
+
275
+ /* The retention series */
276
+ svg.chart .grad-top { stop-color: var(--blue-500); stop-opacity: 0.3; }
277
+ svg.chart .grad-bottom { stop-color: var(--blue-500); stop-opacity: 0; }
278
+ svg.chart .retention-line { fill: none; stroke: var(--blue-500); }
279
+ svg.chart .points { fill: var(--blue-500); }
280
+ svg.chart .points .halo { stroke: var(--color-surface); }
281
+
282
+ /* Release markers: each group sets --mark, its parts inherit it. */
283
+ svg.chart .release-v030 { --mark: var(--orange-600); }
284
+ svg.chart .release-v035 { --mark: var(--yellow-600); }
285
+ svg.chart .release-v040 { --mark: var(--green-500); }
286
+ svg.chart .release-line { stroke: var(--mark); }
287
+ svg.chart .release-tag { fill: var(--mark); }
288
+ svg.chart .release-label { fill: var(--mark); }
289
+
290
+ /* Key data labels */
291
+ svg.chart .point-labels .muted { fill: var(--color-text-muted); }
292
+ svg.chart .point-labels .dip { fill: var(--red-500); }
293
+ svg.chart .point-labels .recovery { fill: var(--yellow-600); }
294
+ svg.chart .point-labels .peak { fill: var(--green-500); }
295
+
296
+ /* Legend swatches are short bars (the shared .legend row owns the layout). */
297
+ .legend-swatch {
298
+ width: 14px;
299
+ height: 3px;
300
+ border-radius: 2px;
301
+ }
302
+
303
+ .legend-swatch.retention { background: var(--blue-500); }
304
+ .legend-swatch.v030 { background: var(--orange-600); }
305
+ .legend-swatch.v035 { background: var(--yellow-600); }
306
+ .legend-swatch.v040 { background: var(--green-500); }
307
+
308
+ /* Release-impact list */
309
+ .release-list {
310
+ display: grid;
311
+ gap: var(--space-10, 10px);
312
+ margin-top: var(--space-16, 16px);
313
+ }
314
+
315
+ .release-item {
316
+ display: flex;
317
+ align-items: center;
318
+ gap: var(--space-12, 12px);
319
+ padding: var(--space-10, 10px) var(--space-16, 16px);
320
+ border-radius: var(--radius-12, 12px);
321
+ border: 1px solid var(--color-border);
322
+ background: var(--color-surface-muted);
323
+ }
324
+
325
+ .release-dot {
326
+ width: 12px;
327
+ height: 12px;
328
+ border-radius: 50%;
329
+ flex-shrink: 0;
330
+ }
331
+
332
+ .release-dot.v030 { background: var(--orange-600); }
333
+ .release-dot.v035 { background: var(--yellow-600); }
334
+ .release-dot.v040 { background: var(--green-500); }
335
+
336
+ .release-info {
337
+ flex: 1;
338
+ min-width: 0;
339
+ }
340
+
341
+ .release-name {
342
+ font-size: var(--text-base, 13.5px);
343
+ font-weight: 600;
344
+ color: var(--color-text);
345
+ }
346
+
347
+ .release-date {
348
+ font-size: var(--text-sm, 12px);
349
+ color: var(--color-text-muted);
350
+ }
351
+
352
+ .release-impact {
353
+ font-size: var(--text-sm, 12px);
354
+ font-weight: 600;
355
+ white-space: nowrap;
356
+ }
357
+
358
+ .release-impact.down { color: var(--red-600); }
359
+ .release-impact.partial { color: var(--orange-600); }
360
+ .release-impact.up { color: var(--green-600); }
361
+
362
+ /* Narrow viewport: let the release rows wrap (the shared scaffold handles the
363
+ body padding). */
364
+ @media (max-width: 600px) {
365
+ .release-item {
366
+ flex-wrap: wrap;
367
+ }
368
+
369
+ .release-impact {
370
+ margin-left: calc(12px + var(--space-12, 12px));
371
+ }
372
+ }
373
+
374
+ </style>
375
+ </head>
376
+ <body>
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
385
+ <main class="shell">
386
+ <header class="hero">
387
+ <h1>Retention vs. recent releases</h1>
388
+ <div class="meta-line">Source: PostHog · Weekly cohort retention (W1) · May 15 – Jul 8, 2026</div>
389
+ </header>
390
+
391
+ <div class="kpi-row">
392
+
393
+ <div class="kpi">
394
+ <div class="label">Current W1 Retention</div>
395
+ <div class="value">78%</div>
396
+ <div class="delta up">+10 pts since May</div>
397
+ </div>
398
+
399
+ <div class="kpi">
400
+ <div class="label">Pre-v0.4.0 Baseline</div>
401
+ <div class="value">68%</div>
402
+ <div class="delta down">−2 pts after v0.3.0</div>
403
+ </div>
404
+
405
+ <div class="kpi">
406
+ <div class="label">Post-v0.4.0 Peak</div>
407
+ <div class="value">81%</div>
408
+ <div class="delta up">+13 pts recovery</div>
409
+ </div>
410
+
411
+ </div>
412
+
413
+ <section class="panel">
414
+ <h2>Weekly retention with release overlays</h2>
415
+ <p class="note">Percentage of users active in week 1 after signup · Dashed lines mark product releases</p>
416
+ <div class="chart-container">
417
+ <svg class="chart" viewBox="0 0 860 360" xmlns="http://www.w3.org/2000/svg">
418
+ <!-- Background grid -->
419
+ <g class="grid" stroke-width="1">
420
+ <line x1="60" y1="40" x2="820" y2="40"/>
421
+ <line x1="60" y1="100" x2="820" y2="100"/>
422
+ <line x1="60" y1="160" x2="820" y2="160"/>
423
+ <line x1="60" y1="220" x2="820" y2="220"/>
424
+ <line x1="60" y1="280" x2="820" y2="280"/>
425
+ </g>
426
+
427
+ <!-- Y-axis labels -->
428
+ <g class="axis-y" font-size="11" text-anchor="end">
429
+ <text x="52" y="44">80%</text>
430
+ <text x="52" y="104">70%</text>
431
+ <text x="52" y="164">60%</text>
432
+ <text x="52" y="224">50%</text>
433
+ <text x="52" y="284">40%</text>
434
+ </g>
435
+
436
+ <!-- X-axis labels (weeks) -->
437
+ <g class="axis-x" font-size="11" text-anchor="middle">
438
+ <text x="60" y="310">May 15</text>
439
+ <text x="168" y="310">May 22</text>
440
+ <text x="276" y="310">May 29</text>
441
+ <text x="384" y="310">Jun 5</text>
442
+ <text x="492" y="310">Jun 12</text>
443
+ <text x="600" y="310">Jun 19</text>
444
+ <text x="708" y="310">Jun 26</text>
445
+ <text x="816" y="310">Jul 3</text>
446
+ </g>
447
+
448
+ <!-- Release overlay markers (dashed verticals with tag) -->
449
+ <g class="release release-v030">
450
+ <line class="release-line" x1="168" y1="40" x2="168" y2="290" stroke-width="1.5" stroke-dasharray="4 4" opacity="0.7"/>
451
+ <rect class="release-tag" x="140" y="24" width="56" height="16" rx="4" opacity="0.12"/>
452
+ <text class="release-label" x="168" y="36" font-size="10" font-weight="600" text-anchor="middle">v0.3.0</text>
453
+ </g>
454
+ <g class="release release-v035">
455
+ <line class="release-line" x1="492" y1="40" x2="492" y2="290" stroke-width="1.5" stroke-dasharray="4 4" opacity="0.7"/>
456
+ <rect class="release-tag" x="464" y="24" width="56" height="16" rx="4" opacity="0.12"/>
457
+ <text class="release-label" x="492" y="36" font-size="10" font-weight="600" text-anchor="middle">v0.3.5</text>
458
+ </g>
459
+ <g class="release release-v040">
460
+ <line class="release-line" x1="780" y1="40" x2="780" y2="290" stroke-width="1.5" stroke-dasharray="4 4" opacity="0.7"/>
461
+ <rect class="release-tag" x="752" y="24" width="56" height="16" rx="4" opacity="0.12"/>
462
+ <text class="release-label" x="780" y="36" font-size="10" font-weight="600" text-anchor="middle">v0.4.0</text>
463
+ </g>
464
+
465
+ <!-- Retention line — area fill -->
466
+ <defs>
467
+ <linearGradient id="retention-gradient" x1="0" y1="0" x2="0" y2="1">
468
+ <stop class="grad-top" offset="0%"/>
469
+ <stop class="grad-bottom" offset="100%"/>
470
+ </linearGradient>
471
+ </defs>
472
+ <path d="M 60,112 L 108,106 L 168,100 L 228,130 L 276,136 L 324,124 L 384,118 L 432,112 L 492,106 L 552,94 L 600,82 L 660,76 L 708,70 L 780,52 L 820,46 L 820,290 L 60,290 Z"
473
+ fill="url(#retention-gradient)"/>
474
+
475
+ <!-- Retention line -->
476
+ <polyline class="retention-line" points="60,112 108,106 168,100 228,130 276,136 324,124 384,118 432,112 492,106 552,94 600,82 660,76 708,70 780,52 820,46"
477
+ stroke-width="2.5" stroke-linejoin="round" stroke-linecap="round"/>
478
+
479
+ <!-- Data points -->
480
+ <g class="points">
481
+ <circle cx="60" cy="112" r="3"/>
482
+ <circle cx="108" cy="106" r="3"/>
483
+ <circle cx="168" cy="100" r="3"/>
484
+ <circle class="halo" cx="228" cy="130" r="4" stroke-width="2"/>
485
+ <circle class="halo" cx="276" cy="136" r="4" stroke-width="2"/>
486
+ <circle cx="324" cy="124" r="3"/>
487
+ <circle cx="384" cy="118" r="3"/>
488
+ <circle cx="432" cy="112" r="3"/>
489
+ <circle cx="492" cy="106" r="3"/>
490
+ <circle cx="552" cy="94" r="3"/>
491
+ <circle cx="600" cy="82" r="3"/>
492
+ <circle cx="660" cy="76" r="3"/>
493
+ <circle cx="708" cy="70" r="3"/>
494
+ <circle class="halo" cx="780" cy="52" r="4" stroke-width="2"/>
495
+ <circle class="halo" cx="820" cy="46" r="4" stroke-width="2"/>
496
+ </g>
497
+
498
+ <!-- Highlighted data labels at key points -->
499
+ <g class="point-labels" font-size="11" font-weight="600" text-anchor="middle">
500
+ <text class="muted" x="60" y="102">68%</text>
501
+ <text class="dip" x="228" y="146">63%</text>
502
+ <text class="recovery" x="492" y="96">69%</text>
503
+ <text class="peak" x="820" y="36">78%</text>
504
+ </g>
505
+
506
+ <!-- X-axis line -->
507
+ <line class="axis-line" x1="60" y1="290" x2="820" y2="290" stroke-width="1"/>
508
+ </svg>
509
+ </div>
510
+
511
+ <div class="legend">
512
+ <div class="legend-item">
513
+ <div class="legend-swatch retention"></div>
514
+ W1 Retention
515
+ </div>
516
+
517
+ <div class="legend-item">
518
+ <div class="legend-swatch v030"></div>
519
+ v0.3.0 release
520
+ </div>
521
+
522
+ <div class="legend-item">
523
+ <div class="legend-swatch v035"></div>
524
+ v0.3.5 release
525
+ </div>
526
+
527
+ <div class="legend-item">
528
+ <div class="legend-swatch v040"></div>
529
+ v0.4.0 release
530
+ </div>
531
+
532
+ </div>
533
+ </section>
534
+
535
+ <section class="panel">
536
+ <h2>Release impact</h2>
537
+ <p class="note">How each release affected weekly retention</p>
538
+ <div class="release-list">
539
+
540
+ <div class="release-item">
541
+ <div class="release-dot v030"></div>
542
+ <div class="release-info">
543
+ <div class="release-name">v0.3.0 — Latency optimizations + new tool-use dispatcher</div>
544
+ <div class="release-date">May 22, 2026</div>
545
+ </div>
546
+ <div class="release-impact down">−5 pts (68% → 63%)</div>
547
+ </div>
548
+
549
+ <div class="release-item">
550
+ <div class="release-dot v035"></div>
551
+ <div class="release-info">
552
+ <div class="release-name">v0.3.5 — Hotfix: rollback trace logging + CI stability</div>
553
+ <div class="release-date">June 12, 2026</div>
554
+ </div>
555
+ <div class="release-impact partial">+6 pts (63% → 69%)</div>
556
+ </div>
557
+
558
+ <div class="release-item">
559
+ <div class="release-dot v040"></div>
560
+ <div class="release-info">
561
+ <div class="release-name">v0.4.0 — Agentic eval harness, latency budgets, rollback traces</div>
562
+ <div class="release-date">July 1, 2026</div>
563
+ </div>
564
+ <div class="release-impact up">+9 pts (69% → 78%)</div>
565
+ </div>
566
+
567
+ </div>
568
+ </section>
569
+ </main>
570
+
571
+ </body>
572
+ </html>