Skip to content

Commit 3713785

Browse files
committed
docs: 25-second motion-graphic launch video (replaces broken screencast)
The earlier terminal-screencast attempt rendered with shell errors, cut-off headings, and 18 seconds of dead time. Replacing it with a proper motion graphic. Story arc (25s): 0-3.5s three failure modes typewriter-in red on white 3.5-7s "These have names." + Pattern #27 / Bias-Stack stamp citing Staw 1976 + Tversky-Kahneman 1974 7-11.5s Bridge: "AI agents fail like junior teammates." subhead: 70 years of OB research named these patterns 11.5-17s Catalog: 34 pattern names cascade in 3 colored columns by module (Individual / Team / Org) 17-25s Final: vstack wordmark + tagline + 34/12/2097 stats + github URL + MIT/no-telemetry/python/surfaces badges Rendered with puppeteer-core + Chrome CDP virtual-time so frames land deterministically (one Chrome instance, 500 frames at 20fps in 24s). ffmpeg encodes h264 mp4 (316KB) + 15fps gif (434KB). Files: docs/assets/launch-video.html source CSS animation docs/assets/launch.mp4 1280x720, h264, 25s, 316KB docs/assets/launch.gif 960x540, 15fps, 434KB
1 parent 57471ae commit 3713785

6 files changed

Lines changed: 370 additions & 45 deletions

File tree

docs/assets/launch-video.html

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
<!doctype html>
2+
<!--
3+
vstack launch motion graphic (25 seconds)
4+
Frame-captured via headless Chrome with --virtual-time-budget; ffmpeg
5+
combines the frames into the final MP4.
6+
-->
7+
<html>
8+
<head>
9+
<meta charset="utf-8" />
10+
<title>vstack — launch</title>
11+
<style>
12+
:root {
13+
--ink: #0b0f17;
14+
--paper: #ffffff;
15+
--muted: #475569;
16+
--soft: #94a3b8;
17+
--line: #e2e8f0;
18+
--red: #dc2626;
19+
--cyan: #0e7490;
20+
--orange: #c2410c;
21+
--purple: #6d28d9;
22+
}
23+
* { box-sizing: border-box; margin: 0; padding: 0; }
24+
html, body {
25+
width: 1280px; height: 720px; overflow: hidden;
26+
background: var(--paper); color: var(--ink);
27+
font-family: -apple-system, "SF Pro Display", "Inter", system-ui, sans-serif;
28+
-webkit-font-smoothing: antialiased;
29+
}
30+
.stage {
31+
position: absolute; inset: 0;
32+
display: flex; flex-direction: column; align-items: center; justify-content: center;
33+
padding: 80px;
34+
}
35+
.scene {
36+
position: absolute; inset: 0;
37+
display: flex; flex-direction: column; align-items: center; justify-content: center;
38+
padding: 80px;
39+
opacity: 0;
40+
}
41+
42+
/* ============================================================
43+
Scene 1 (0.0s - 3.5s) : Three failure modes typed in red
44+
============================================================ */
45+
.scene-failures {
46+
animation: showHide 3.5s linear 0s 1 normal forwards;
47+
align-items: flex-start;
48+
justify-content: flex-start;
49+
padding: 110px 140px;
50+
font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
51+
}
52+
.scene-failures .line {
53+
font-size: 36px; font-weight: 600; color: var(--red);
54+
line-height: 1.5; letter-spacing: -0.2px;
55+
width: 0; overflow: hidden; white-space: nowrap;
56+
border-right: 4px solid var(--red);
57+
}
58+
.scene-failures .line:nth-child(1) { animation: type 0.9s steps(38) 0.15s 1 normal forwards, blink 0.5s steps(2) 1.05s 2 normal forwards; }
59+
.scene-failures .line:nth-child(2) { animation: type 1.0s steps(42) 1.2s 1 normal forwards, blink 0.5s steps(2) 2.20s 2 normal forwards; }
60+
.scene-failures .line:nth-child(3) { animation: type 0.9s steps(38) 2.30s 1 normal forwards, blink 0.5s steps(2) 3.20s 2 normal forwards; }
61+
62+
@keyframes type {
63+
from { width: 0; }
64+
to { width: 100%; border-right-color: transparent; }
65+
}
66+
@keyframes blink {
67+
0%, 100% { border-right-color: var(--red); }
68+
50% { border-right-color: transparent; }
69+
}
70+
71+
/* ============================================================
72+
Scene 2 (3.5s - 7.0s) : "These have names." + citation stamp
73+
============================================================ */
74+
.scene-names { animation: showHide 3.5s linear 3.5s 1 normal forwards; }
75+
.scene-names .lead {
76+
font-size: 86px; font-weight: 800; letter-spacing: -3px;
77+
opacity: 0; transform: translateY(20px);
78+
animation: fadeUp 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.0s 1 normal forwards;
79+
}
80+
.scene-names .stamp {
81+
margin-top: 60px;
82+
border: 3px solid var(--red); padding: 18px 30px; border-radius: 14px;
83+
transform: rotate(-2.5deg) scale(0.85); opacity: 0;
84+
background: #fee2e2;
85+
font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
86+
animation: stamp 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 1.0s 1 normal forwards;
87+
}
88+
.scene-names .stamp .label {
89+
font-size: 12px; color: var(--red); font-weight: 700; letter-spacing: 2px;
90+
}
91+
.scene-names .stamp .name {
92+
font-size: 30px; color: var(--red); font-weight: 800; letter-spacing: -0.5px; margin-top: 4px;
93+
}
94+
.scene-names .stamp .cite {
95+
font-size: 14px; color: var(--red); opacity: 0.7; margin-top: 6px;
96+
}
97+
98+
@keyframes stamp {
99+
from { transform: rotate(-15deg) scale(0.6); opacity: 0; }
100+
to { transform: rotate(-2.5deg) scale(1); opacity: 1; }
101+
}
102+
@keyframes fadeUp {
103+
from { opacity: 0; transform: translateY(20px); }
104+
to { opacity: 1; transform: translateY(0); }
105+
}
106+
107+
/* ============================================================
108+
Scene 3 (7.0s - 11.5s) : The bridge sentence
109+
============================================================ */
110+
.scene-bridge { animation: showHide 4.5s linear 7.0s 1 normal forwards; }
111+
.scene-bridge .big {
112+
font-size: 72px; font-weight: 800; letter-spacing: -2.5px; line-height: 1.1;
113+
text-align: center; max-width: 980px;
114+
opacity: 0;
115+
animation: fadeUp 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s 1 normal forwards;
116+
}
117+
.scene-bridge .big .accent { color: var(--cyan); }
118+
.scene-bridge .sub {
119+
margin-top: 36px;
120+
font-size: 24px; color: var(--muted); font-weight: 500;
121+
opacity: 0;
122+
animation: fadeUp 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 1.0s 1 normal forwards;
123+
}
124+
.scene-bridge .small {
125+
margin-top: 18px;
126+
font-size: 17px; color: var(--soft); font-weight: 600; letter-spacing: 1.5px;
127+
opacity: 0;
128+
animation: fadeUp 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 1.8s 1 normal forwards;
129+
}
130+
131+
/* ============================================================
132+
Scene 4 (11.5s - 17.0s) : 34 pattern names cascade
133+
============================================================ */
134+
.scene-catalog {
135+
animation: showHide 5.5s linear 11.5s 1 normal forwards;
136+
align-items: center; justify-content: center;
137+
padding: 60px;
138+
}
139+
.scene-catalog .module-title {
140+
position: absolute;
141+
font-size: 14px; font-weight: 700; letter-spacing: 3px; color: var(--soft);
142+
opacity: 0;
143+
}
144+
.scene-catalog .mt1 { left: 60px; top: 60px; color: var(--cyan); animation: fadeUp 0.5s 0.2s 1 normal forwards; }
145+
.scene-catalog .mt2 { left: 50%; top: 60px; transform: translateX(-50%); color: var(--orange); animation: fadeUp 0.5s 1.8s 1 normal forwards; }
146+
.scene-catalog .mt3 { right: 60px; top: 60px; color: var(--purple); animation: fadeUp 0.5s 3.6s 1 normal forwards; }
147+
148+
.scene-catalog .col {
149+
position: absolute; top: 110px;
150+
display: flex; flex-direction: column; gap: 14px;
151+
font-size: 20px; font-weight: 600; letter-spacing: -0.3px;
152+
width: 360px;
153+
}
154+
.scene-catalog .col-individual { left: 60px; }
155+
.scene-catalog .col-team { left: 50%; transform: translateX(-50%); }
156+
.scene-catalog .col-org { right: 60px; }
157+
158+
.scene-catalog .col span {
159+
opacity: 0; transform: translateY(8px);
160+
padding: 8px 14px; border-radius: 8px;
161+
border-left: 3px solid currentColor;
162+
}
163+
.scene-catalog .col-individual span { color: var(--cyan); }
164+
.scene-catalog .col-team span { color: var(--orange); }
165+
.scene-catalog .col-org span { color: var(--purple); }
166+
167+
/* Stagger animation timings per pattern */
168+
.scene-catalog .col-individual span:nth-child(1) { animation: fadeUp 0.4s 0.35s 1 normal forwards; }
169+
.scene-catalog .col-individual span:nth-child(2) { animation: fadeUp 0.4s 0.45s 1 normal forwards; }
170+
.scene-catalog .col-individual span:nth-child(3) { animation: fadeUp 0.4s 0.55s 1 normal forwards; }
171+
.scene-catalog .col-individual span:nth-child(4) { animation: fadeUp 0.4s 0.65s 1 normal forwards; }
172+
.scene-catalog .col-individual span:nth-child(5) { animation: fadeUp 0.4s 0.75s 1 normal forwards; }
173+
.scene-catalog .col-individual span:nth-child(6) { animation: fadeUp 0.4s 0.85s 1 normal forwards; }
174+
.scene-catalog .col-individual span:nth-child(7) { animation: fadeUp 0.4s 0.95s 1 normal forwards; }
175+
.scene-catalog .col-individual span:nth-child(8) { animation: fadeUp 0.4s 1.05s 1 normal forwards; }
176+
177+
.scene-catalog .col-team span:nth-child(1) { animation: fadeUp 0.4s 1.95s 1 normal forwards; }
178+
.scene-catalog .col-team span:nth-child(2) { animation: fadeUp 0.4s 2.05s 1 normal forwards; }
179+
.scene-catalog .col-team span:nth-child(3) { animation: fadeUp 0.4s 2.15s 1 normal forwards; }
180+
.scene-catalog .col-team span:nth-child(4) { animation: fadeUp 0.4s 2.25s 1 normal forwards; }
181+
.scene-catalog .col-team span:nth-child(5) { animation: fadeUp 0.4s 2.35s 1 normal forwards; }
182+
.scene-catalog .col-team span:nth-child(6) { animation: fadeUp 0.4s 2.45s 1 normal forwards; }
183+
.scene-catalog .col-team span:nth-child(7) { animation: fadeUp 0.4s 2.55s 1 normal forwards; }
184+
.scene-catalog .col-team span:nth-child(8) { animation: fadeUp 0.4s 2.65s 1 normal forwards; }
185+
186+
.scene-catalog .col-org span:nth-child(1) { animation: fadeUp 0.4s 3.75s 1 normal forwards; }
187+
.scene-catalog .col-org span:nth-child(2) { animation: fadeUp 0.4s 3.85s 1 normal forwards; }
188+
.scene-catalog .col-org span:nth-child(3) { animation: fadeUp 0.4s 3.95s 1 normal forwards; }
189+
.scene-catalog .col-org span:nth-child(4) { animation: fadeUp 0.4s 4.05s 1 normal forwards; }
190+
191+
.scene-catalog .footnote {
192+
position: absolute; bottom: 60px; left: 50%; transform: translateX(-50%);
193+
font-size: 18px; font-weight: 600; color: var(--ink);
194+
opacity: 0;
195+
animation: fadeUp 0.5s 4.7s 1 normal forwards;
196+
}
197+
.scene-catalog .footnote strong { font-weight: 800; }
198+
199+
/* ============================================================
200+
Scene 5 (17.0s - 25.0s) : Wordmark + tagline + URL
201+
============================================================ */
202+
.scene-final {
203+
animation: showHide 8.0s linear 17.0s 1 normal forwards;
204+
align-items: center;
205+
}
206+
.scene-final .marker {
207+
font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
208+
font-size: 14px; font-weight: 700; letter-spacing: 3px;
209+
color: var(--soft);
210+
opacity: 0;
211+
animation: fadeUp 0.4s 0.2s 1 normal forwards;
212+
}
213+
.scene-final .wordmark {
214+
font-size: 168px; font-weight: 900; letter-spacing: -8px;
215+
line-height: 1; margin-top: 16px;
216+
opacity: 0; transform: translateY(20px);
217+
animation: fadeUp 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.5s 1 normal forwards;
218+
}
219+
.scene-final .tagline {
220+
margin-top: 22px; font-size: 26px; font-weight: 500;
221+
color: var(--muted); letter-spacing: -0.3px;
222+
opacity: 0;
223+
animation: fadeUp 0.6s 1.2s 1 normal forwards;
224+
}
225+
.scene-final .stats {
226+
margin-top: 38px; display: flex; gap: 56px;
227+
opacity: 0;
228+
animation: fadeUp 0.6s 1.9s 1 normal forwards;
229+
}
230+
.scene-final .stats .stat {
231+
display: flex; flex-direction: column; align-items: center;
232+
}
233+
.scene-final .stats .stat .num {
234+
font-size: 46px; font-weight: 900; letter-spacing: -1.5px;
235+
}
236+
.scene-final .stats .stat:nth-child(1) .num { color: var(--cyan); }
237+
.scene-final .stats .stat:nth-child(2) .num { color: var(--orange); }
238+
.scene-final .stats .stat:nth-child(3) .num { color: var(--purple); }
239+
.scene-final .stats .stat .lbl {
240+
font-size: 13px; font-weight: 700; letter-spacing: 2px;
241+
color: var(--soft); margin-top: 4px;
242+
}
243+
.scene-final .url {
244+
margin-top: 36px;
245+
font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
246+
font-size: 24px; font-weight: 700; color: var(--ink);
247+
background: #f1f5f9; padding: 14px 24px; border-radius: 12px;
248+
opacity: 0;
249+
animation: fadeUp 0.6s 2.6s 1 normal forwards;
250+
}
251+
.scene-final .badges {
252+
margin-top: 26px;
253+
display: flex; gap: 14px; flex-wrap: wrap; justify-content: center;
254+
font-family: "SF Mono", ui-monospace, Menlo, Consolas, monospace;
255+
font-size: 12px; font-weight: 700; letter-spacing: 1.5px;
256+
color: var(--soft);
257+
opacity: 0;
258+
animation: fadeUp 0.4s 3.3s 1 normal forwards;
259+
}
260+
.scene-final .badges span { padding: 7px 12px; border: 1px solid var(--line); border-radius: 8px; white-space: nowrap; }
261+
262+
/* The "showHide" pattern keeps each scene hidden before its window
263+
opens and again after its window closes. We rely on opacity 0/1
264+
at scene-window edges to crossfade cleanly. */
265+
@keyframes showHide {
266+
0%, 100% { opacity: 0; }
267+
3%, 97% { opacity: 1; }
268+
}
269+
</style>
270+
</head>
271+
<body>
272+
273+
<!-- ============================================================
274+
Scene 1: failure modes typed in red
275+
============================================================ -->
276+
<div class="stage scene scene-failures">
277+
<div class="line">> agent loops 47 times on a failing JWT fix...</div>
278+
<div class="line">> patches the test's expectation, not the code...</div>
279+
<div class="line">> reverts silently. never names what broke.</div>
280+
</div>
281+
282+
<!-- ============================================================
283+
Scene 2: these have names
284+
============================================================ -->
285+
<div class="stage scene scene-names">
286+
<div class="lead">These have names.</div>
287+
<div class="stamp">
288+
<div class="label">PATTERN #27 / BIAS-STACK</div>
289+
<div class="name">Escalation of commitment</div>
290+
<div class="cite">Staw, B. M. (1976) · Tversky & Kahneman (1974)</div>
291+
</div>
292+
</div>
293+
294+
<!-- ============================================================
295+
Scene 3: the bridge
296+
============================================================ -->
297+
<div class="stage scene scene-bridge">
298+
<div class="big">AI agents fail like <span class="accent">junior teammates.</span></div>
299+
<div class="sub">Organizational-behavior researchers named these patterns 70 years ago.</div>
300+
<div class="small">LEWIN · LENCIONI · EDMONDSON · SCHEIN · WHARTON AAR · + 29 MORE</div>
301+
</div>
302+
303+
<!-- ============================================================
304+
Scene 4: 34 pattern catalog
305+
============================================================ -->
306+
<div class="stage scene scene-catalog">
307+
<div class="module-title mt1">MODULE 1 · INDIVIDUAL</div>
308+
<div class="module-title mt2">MODULE 2 · TEAM</div>
309+
<div class="module-title mt3">MODULE 3 · ORG</div>
310+
311+
<div class="col col-individual">
312+
<span>Lewin attribution</span>
313+
<span>Goleman EI audit</span>
314+
<span>Johari window</span>
315+
<span>HEXACO personality</span>
316+
<span>SDT intrinsic reward</span>
317+
<span>Vroom expectancy</span>
318+
<span>Yerkes-Dodson workload</span>
319+
<span>+ 5 more</span>
320+
</div>
321+
322+
<div class="col col-team">
323+
<span>After-Action Review</span>
324+
<span>Lencioni 5 Dysfunctions</span>
325+
<span>Edmondson Psych Safety</span>
326+
<span>Trust Triangle</span>
327+
<span>Bias-stack detector</span>
328+
<span>Devil's-advocate separator</span>
329+
<span>Thomas-Kilmann selector</span>
330+
<span>+ 11 more</span>
331+
</div>
332+
333+
<div class="col col-org">
334+
<span>Schein iceberg culture</span>
335+
<span>Span-of-control</span>
336+
<span>Robbins-Judge 7 culture</span>
337+
<span>Org-structure matrix</span>
338+
</div>
339+
340+
<div class="footnote">
341+
<strong>34 patterns</strong> · all anchored in named papers
342+
</div>
343+
</div>
344+
345+
<!-- ============================================================
346+
Scene 5: final card
347+
============================================================ -->
348+
<div class="stage scene scene-final">
349+
<div class="marker">VSTACK · v0.7.0 · TODAY</div>
350+
<div class="wordmark">vstack</div>
351+
<div class="tagline">Organizational behavior, practiced on AI agents.</div>
352+
353+
<div class="stats">
354+
<div class="stat"><div class="num">34</div><div class="lbl">PATTERNS</div></div>
355+
<div class="stat"><div class="num">12</div><div class="lbl">SURFACES</div></div>
356+
<div class="stat"><div class="num">2,097</div><div class="lbl">TESTS PASSING</div></div>
357+
</div>
358+
359+
<div class="url">github.com/valani9/vstack</div>
360+
361+
<div class="badges">
362+
<span>MIT LICENSE</span>
363+
<span>NO TELEMETRY</span>
364+
<span>PYTHON 3.11+</span>
365+
<span>PIP · DOCKER · MCP · REST</span>
366+
</div>
367+
</div>
368+
369+
</body>
370+
</html>

docs/assets/launch.gif

424 KB
Loading

docs/assets/launch.mp4

309 KB
Binary file not shown.

docs/assets/screencast.gif

-321 KB
Binary file not shown.

docs/assets/screencast.mp4

-371 KB
Binary file not shown.

0 commit comments

Comments
 (0)