hyperframes 0.1.15 → 0.2.0

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 (41) hide show
  1. package/README.md +3 -3
  2. package/dist/cli.js +4057 -3400
  3. package/dist/skills/hyperframes-captions/SKILL.md +1 -1
  4. package/dist/skills/hyperframes-compose/SKILL.md +1 -0
  5. package/dist/studio/assets/index-Bkp9HQbo.css +1 -0
  6. package/dist/studio/assets/index-DfhSlTti.js +93 -0
  7. package/dist/studio/index.html +2 -2
  8. package/dist/templates/_shared/CLAUDE.md +1 -1
  9. package/package.json +3 -2
  10. package/dist/studio/assets/index-CLmYRLY-.css +0 -1
  11. package/dist/studio/assets/index-CRvFpc0E.js +0 -84
  12. package/dist/templates/decision-tree/compositions/decision_tree.html +0 -420
  13. package/dist/templates/decision-tree/index.html +0 -56
  14. package/dist/templates/generators.ts +0 -32
  15. package/dist/templates/kinetic-type/compositions/main-graphics.html +0 -588
  16. package/dist/templates/kinetic-type/index.html +0 -61
  17. package/dist/templates/nyt-graph/compositions/nyt-chart.html +0 -450
  18. package/dist/templates/nyt-graph/index.html +0 -51
  19. package/dist/templates/play-mode/compositions/captions.html +0 -163
  20. package/dist/templates/play-mode/compositions/intro.html +0 -107
  21. package/dist/templates/play-mode/compositions/stats.html +0 -388
  22. package/dist/templates/play-mode/index.html +0 -239
  23. package/dist/templates/product-promo/assets/figma-cursors.svg +0 -30
  24. package/dist/templates/product-promo/assets/figma-logo-pieces.svg +0 -15
  25. package/dist/templates/product-promo/assets/figma-logo-pills.svg +0 -6
  26. package/dist/templates/product-promo/compositions/scene1-logo-intro.html +0 -189
  27. package/dist/templates/product-promo/compositions/scene2-4-canvas.html +0 -570
  28. package/dist/templates/product-promo/compositions/scene5-logo-outro.html +0 -226
  29. package/dist/templates/product-promo/index.html +0 -158
  30. package/dist/templates/swiss-grid/assets/swiss-grid.svg +0 -116
  31. package/dist/templates/swiss-grid/compositions/captions.html +0 -148
  32. package/dist/templates/swiss-grid/compositions/graphics.html +0 -207
  33. package/dist/templates/swiss-grid/compositions/intro.html +0 -131
  34. package/dist/templates/swiss-grid/index.html +0 -234
  35. package/dist/templates/vignelli/compositions/captions.html +0 -181
  36. package/dist/templates/vignelli/compositions/overlays.html +0 -323
  37. package/dist/templates/vignelli/index.html +0 -190
  38. package/dist/templates/warm-grain/compositions/captions.html +0 -147
  39. package/dist/templates/warm-grain/compositions/graphics.html +0 -164
  40. package/dist/templates/warm-grain/compositions/intro.html +0 -86
  41. package/dist/templates/warm-grain/index.html +0 -294
@@ -1,420 +0,0 @@
1
- <template id="decision-tree-template">
2
- <div data-composition-id="decision-tree" data-width="1920" data-height="1080" data-duration="12">
3
- <div class="canvas">
4
- <svg class="connectors" width="1920" height="1080" viewBox="0 0 1920 1080">
5
- <!-- Level 1 to 2 -->
6
- <path
7
- id="path-1-L"
8
- class="connector"
9
- d="M 960 130 L 960 200 L 600 200 L 600 270"
10
- fill="none"
11
- stroke="#333"
12
- stroke-width="4"
13
- />
14
- <path
15
- id="path-1-R"
16
- class="connector"
17
- d="M 960 130 L 960 200 L 1320 200 L 1320 270"
18
- fill="none"
19
- stroke="#333"
20
- stroke-width="4"
21
- />
22
-
23
- <!-- Level 2 to 3 (Left side) -->
24
- <path
25
- id="path-2-LL"
26
- class="connector"
27
- d="M 600 330 L 600 400 L 400 400 L 400 470"
28
- fill="none"
29
- stroke="#333"
30
- stroke-width="4"
31
- />
32
- <path
33
- id="path-2-LR"
34
- class="connector"
35
- d="M 600 330 L 600 400 L 800 400 L 800 470"
36
- fill="none"
37
- stroke="#333"
38
- stroke-width="4"
39
- />
40
-
41
- <!-- Level 2 to 3 (Right side) -->
42
- <path
43
- id="path-2-RL"
44
- class="connector"
45
- d="M 1320 330 L 1320 400 L 1120 400 L 1120 470"
46
- fill="none"
47
- stroke="#333"
48
- stroke-width="4"
49
- />
50
- <path
51
- id="path-2-RR"
52
- class="connector"
53
- d="M 1320 330 L 1320 400 L 1520 400 L 1520 470"
54
- fill="none"
55
- stroke="#333"
56
- stroke-width="4"
57
- />
58
- </svg>
59
-
60
- <div id="label-yes" class="connector-label">Yes</div>
61
- <div id="label-not-sure" class="connector-label">Not sure</div>
62
-
63
- <!-- Level 1 -->
64
- <div id="node-root" class="node sticky yellow" style="left: 960px; top: 100px">
65
- Should I learn to code?
66
- </div>
67
-
68
- <!-- Level 2 -->
69
- <div id="node-yes" class="node sticky green" style="left: 600px; top: 300px">Yes</div>
70
- <div id="node-not-sure" class="node sticky peach" style="left: 1320px; top: 300px">
71
- Not sure
72
- </div>
73
-
74
- <!-- Level 3 -->
75
- <div id="node-python" class="node sticky lavender" style="left: 400px; top: 500px">
76
- <div style="position: relative; display: inline-block">
77
- <span id="python-text">Start with Pythom</span>
78
- <svg class="squiggle-container" width="64" height="6" viewBox="0 0 64 6">
79
- <path
80
- id="squiggle"
81
- d="M 0 3 Q 2 0 4 3 T 8 3 T 12 3 T 16 3 T 20 3 T 24 3 T 28 3 T 32 3 T 36 3 T 40 3 T 44 3 T 48 3 T 52 3 T 56 3 T 60 3 T 64 3"
82
- fill="none"
83
- stroke="#E53935"
84
- stroke-width="2"
85
- />
86
- </svg>
87
- </div>
88
- </div>
89
- <div id="node-nocode" class="node sticky blue" style="left: 800px; top: 500px">
90
- Try no-code first
91
- </div>
92
- <div id="node-website" class="node sticky pink" style="left: 1120px; top: 500px">
93
- Build a personal website
94
- </div>
95
- <div id="node-course" class="node sticky yellow" style="left: 1520px; top: 500px">
96
- Take a free intro course
97
- </div>
98
-
99
- <!-- Cursor -->
100
- <div id="cursor" class="cursor-container">
101
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
102
- <path
103
- d="M5.65376 12.3673H5.46026L5.31717 12.4976L0.500002 16.8829L0.500002 1.19841L11.7841 12.3673H5.65376Z"
104
- fill="white"
105
- stroke="black"
106
- />
107
- </svg>
108
- <div class="cursor-tag">You</div>
109
- </div>
110
-
111
- <!-- Emoji -->
112
- <div id="emoji-thumb" class="emoji">👍</div>
113
-
114
- <!-- Overlay -->
115
- <div id="fade-overlay"></div>
116
- </div>
117
-
118
- <style>
119
- [data-composition-id="decision-tree"] {
120
- width: 1920px;
121
- height: 1080px;
122
- background-color: #ffffff;
123
- background-image: radial-gradient(#e5e5e5 1px, transparent 1px);
124
- background-size: 20px 20px;
125
- position: absolute;
126
- overflow: hidden;
127
- font-family: "Inter", sans-serif;
128
- }
129
-
130
- [data-composition-id="decision-tree"] .canvas {
131
- width: 100%;
132
- height: 100%;
133
- position: absolute;
134
- transform: scale(1.2);
135
- transform-origin: 960px 300px;
136
- }
137
-
138
- [data-composition-id="decision-tree"] .node {
139
- position: absolute;
140
- transform: translate(-50%, -50%) scale(0);
141
- padding: 16px 24px;
142
- border-radius: 12px;
143
- font-size: 18px;
144
- font-weight: 500;
145
- color: #333;
146
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
147
- white-space: nowrap;
148
- display: flex;
149
- flex-direction: column;
150
- align-items: center;
151
- justify-content: center;
152
- z-index: 10;
153
- }
154
-
155
- [data-composition-id="decision-tree"] .node.yellow {
156
- background-color: #e8d44d;
157
- }
158
- [data-composition-id="decision-tree"] .node.green {
159
- background-color: #c2e8a0;
160
- }
161
- [data-composition-id="decision-tree"] .node.peach {
162
- background-color: #f5c5a3;
163
- }
164
- [data-composition-id="decision-tree"] .node.lavender {
165
- background-color: #d4c5f9;
166
- }
167
- [data-composition-id="decision-tree"] .node.blue {
168
- background-color: #a8d8f0;
169
- }
170
- [data-composition-id="decision-tree"] .node.pink {
171
- background-color: #f8b4c8;
172
- }
173
-
174
- [data-composition-id="decision-tree"] .connectors {
175
- position: absolute;
176
- top: 0;
177
- left: 0;
178
- z-index: 5;
179
- pointer-events: none;
180
- }
181
-
182
- [data-composition-id="decision-tree"] .connector {
183
- stroke-dasharray: 1000;
184
- stroke-dashoffset: 1000;
185
- }
186
-
187
- [data-composition-id="decision-tree"] .connector-label {
188
- position: absolute;
189
- font-size: 14px;
190
- font-weight: 600;
191
- color: #333;
192
- background: white;
193
- padding: 2px 6px;
194
- border-radius: 4px;
195
- opacity: 0;
196
- z-index: 6;
197
- transform: translate(-50%, -50%);
198
- }
199
-
200
- #label-yes {
201
- left: 780px;
202
- top: 230px;
203
- }
204
- #label-not-sure {
205
- left: 1140px;
206
- top: 230px;
207
- }
208
-
209
- [data-composition-id="decision-tree"] .cursor-container {
210
- position: absolute;
211
- left: 1920px;
212
- top: 1080px;
213
- z-index: 100;
214
- pointer-events: none;
215
- display: flex;
216
- align-items: flex-start;
217
- }
218
-
219
- [data-composition-id="decision-tree"] .cursor-tag {
220
- background-color: #9747ff;
221
- color: white;
222
- padding: 2px 8px;
223
- border-radius: 4px;
224
- font-size: 12px;
225
- font-weight: 600;
226
- margin-left: 4px;
227
- margin-top: 12px;
228
- }
229
-
230
- [data-composition-id="decision-tree"] .squiggle-container {
231
- position: absolute;
232
- right: 0;
233
- bottom: -4px;
234
- opacity: 0;
235
- }
236
-
237
- [data-composition-id="decision-tree"] .emoji {
238
- position: absolute;
239
- font-size: 32px;
240
- left: 510px;
241
- top: 500px;
242
- transform: translate(-50%, -50%) scale(0);
243
- z-index: 20;
244
- }
245
-
246
- [data-composition-id="decision-tree"] #fade-overlay {
247
- position: absolute;
248
- top: 0;
249
- left: 0;
250
- width: 100%;
251
- height: 100%;
252
- background-color: white;
253
- opacity: 0;
254
- z-index: 1000;
255
- pointer-events: none;
256
- }
257
-
258
- .selection-border {
259
- position: absolute;
260
- top: -4px;
261
- left: -4px;
262
- right: -4px;
263
- bottom: -4px;
264
- border: 2px solid #0b84f3;
265
- border-radius: 16px;
266
- pointer-events: none;
267
- opacity: 0;
268
- }
269
-
270
- .text-highlight {
271
- background-color: #d0e4ff;
272
- }
273
- </style>
274
-
275
- <script>
276
- (function () {
277
- const tl = gsap.timeline({ paused: true });
278
-
279
- // 1. Root node scales from 0→100% over 0.4s
280
- tl.to("#node-root", { scale: 1, duration: 0.4, ease: "power2.out" });
281
-
282
- // 2. Hold 0.6s
283
- tl.addLabel("hold1", "+=0.6");
284
-
285
- // 3. Two elbow connectors draw downward-left and downward-right simultaneously (0.5s)
286
- tl.to(
287
- ".connector#path-1-L, .connector#path-1-R",
288
- {
289
- strokeDashoffset: 0,
290
- duration: 0.5,
291
- ease: "none",
292
- },
293
- "hold1",
294
- );
295
-
296
- // Labels fade in at midpoint
297
- tl.to(
298
- "#label-yes, #label-not-sure",
299
- {
300
- opacity: 1,
301
- duration: 0.2,
302
- },
303
- "hold1+=0.25",
304
- );
305
-
306
- // 4. Level 2 nodes scale in at endpoints with 0.2s stagger
307
- tl.to("#node-yes", { scale: 1, duration: 0.4, ease: "back.out(1.7)" }, "hold1+=0.4");
308
- tl.to("#node-not-sure", { scale: 1, duration: 0.4, ease: "back.out(1.7)" }, "hold1+=0.6");
309
-
310
- // 5. Hold 0.5s
311
- tl.addLabel("hold2", "+=0.5");
312
-
313
- // 6. Four connectors draw down from level 2 (0.4s)
314
- tl.to(
315
- ".connector#path-2-LL, .connector#path-2-LR, .connector#path-2-RL, .connector#path-2-RR",
316
- {
317
- strokeDashoffset: 0,
318
- duration: 0.4,
319
- ease: "none",
320
- },
321
- "hold2",
322
- );
323
-
324
- // 7. Four leaf nodes scale in with 0.15s stagger
325
- const leafNodes = ["#node-python", "#node-nocode", "#node-website", "#node-course"];
326
- leafNodes.forEach((id, i) => {
327
- tl.to(id, { scale: 1, duration: 0.4, ease: "back.out(1.7)" }, `hold2+=${0.3 + i * 0.15}`);
328
- });
329
-
330
- // Red wavy underline appears with text
331
- tl.to(".squiggle-container", { opacity: 1, duration: 0.1 }, "hold2+=0.3");
332
-
333
- // 8. Hold 0.8s
334
- tl.addLabel("hold3", "+=0.8");
335
-
336
- // 9. Cursor drifts in from bottom-right (1s) to lavender sticky
337
- tl.to(
338
- "#cursor",
339
- {
340
- left: 450,
341
- top: 540,
342
- duration: 1,
343
- ease: "power1.inOut",
344
- },
345
- "hold3",
346
- );
347
-
348
- // 10. Cursor clicks. Selection border appears.
349
- tl.add(() => {
350
- const node = document.querySelector("#node-python");
351
- if (!node) return;
352
- if (!node.querySelector(".selection-border")) {
353
- const border = document.createElement("div");
354
- border.className = "selection-border";
355
- node.appendChild(border);
356
- }
357
- gsap.set(".selection-border", { opacity: 1 });
358
- }, "hold3+=1");
359
-
360
- // Visual click feedback
361
- tl.to("#cursor", { scale: 0.8, duration: 0.05, yoyo: true, repeat: 1 }, "hold3+=1");
362
-
363
- // 11. Hold 0.3s
364
- tl.addLabel("hold4", "+=0.3");
365
-
366
- // 12. Cursor double-clicks "Pythom" — highlight in blue
367
- tl.to("#cursor", { scale: 0.8, duration: 0.05, yoyo: true, repeat: 3 }, "hold4");
368
- tl.add(() => {
369
- const textEl = document.querySelector("#python-text");
370
- if (!textEl) return;
371
- textEl.innerHTML = 'Start with <span class="text-highlight">Pythom</span>';
372
- }, "hold4+=0.1");
373
-
374
- // 13. Hold 0.2s
375
- tl.addLabel("hold5", "+=0.2");
376
-
377
- // 14. Highlighted text deletes and "Python" types in (fast)
378
- // Squiggle disappears when last char lands
379
- const typingStart = tl.labels["hold5"];
380
- const words = ["P", "Py", "Pyt", "Pyth", "Pytho", "Python"];
381
- words.forEach((word, i) => {
382
- tl.add(
383
- () => {
384
- const el = document.querySelector("#python-text");
385
- if (el) el.innerHTML = `Start with <span class="text-highlight">${word}</span>`;
386
- },
387
- typingStart + i * 0.05,
388
- );
389
- });
390
-
391
- // Remove highlight and squiggle at the end of typing
392
- const typingEnd = typingStart + words.length * 0.05;
393
- tl.add(() => {
394
- const pyEl = document.querySelector("#python-text");
395
- if (pyEl) pyEl.innerHTML = "Start with Python";
396
- gsap.set(".squiggle-container", { opacity: 0 });
397
- }, typingEnd);
398
-
399
- // 15. Hold 0.5s
400
- tl.addLabel("hold6", typingEnd + 0.5);
401
-
402
- // 16. Cursor moves slightly and clicks away to deselect
403
- tl.to("#cursor", { left: 500, top: 580, duration: 0.3 }, "hold6");
404
- tl.to("#cursor", { scale: 0.8, duration: 0.05, yoyo: true, repeat: 1 }, "hold6+=0.3");
405
- tl.to(".selection-border", { opacity: 0, duration: 0.1 }, "hold6+=0.3");
406
-
407
- // 17. 👍 emoji pops in
408
- tl.to("#emoji-thumb", { scale: 1, duration: 0.15, ease: "back.out(2)" }, "hold6+=0.4");
409
-
410
- // 18. Hold 2s
411
- tl.addLabel("hold7", "+=2");
412
-
413
- // 19. Fade entire screen to white over 0.5s
414
- tl.to("#fade-overlay", { opacity: 1, duration: 0.5 }, "hold7");
415
-
416
- window.__timelines["decision-tree"] = tl;
417
- })();
418
- </script>
419
- </div>
420
- </template>
@@ -1,56 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=1920, height=1080" />
6
- <title>Decision Tree</title>
7
- <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8
- <style>
9
- * {
10
- margin: 0;
11
- padding: 0;
12
- box-sizing: border-box;
13
- }
14
- html,
15
- body {
16
- margin: 0;
17
- width: 1920px;
18
- height: 1080px;
19
- overflow: hidden;
20
- background: #ffffff;
21
- font-family: "Inter", sans-serif;
22
- }
23
- </style>
24
- <link
25
- href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=block"
26
- rel="stylesheet"
27
- />
28
- </head>
29
- <body>
30
- <div
31
- id="root"
32
- data-composition-id="main"
33
- data-start="0"
34
- data-duration="15"
35
- data-width="1920"
36
- data-height="1080"
37
- >
38
- <div
39
- id="decision-tree-comp"
40
- data-composition-id="decision-tree"
41
- data-composition-src="compositions/decision_tree.html"
42
- data-start="0"
43
- data-duration="15"
44
- data-track-index="0"
45
- data-width="1920"
46
- data-height="1080"
47
- ></div>
48
- </div>
49
-
50
- <script>
51
- window.__timelines = window.__timelines || {};
52
- const tl = gsap.timeline({ paused: true });
53
- window.__timelines["main"] = tl;
54
- </script>
55
- </body>
56
- </html>
@@ -1,32 +0,0 @@
1
- export type TemplateId =
2
- | "blank"
3
- | "warm-grain"
4
- | "play-mode"
5
- | "swiss-grid"
6
- | "vignelli"
7
- | "decision-tree"
8
- | "kinetic-type"
9
- | "product-promo"
10
- | "nyt-graph";
11
-
12
- export interface TemplateOption {
13
- id: TemplateId;
14
- label: string;
15
- hint: string;
16
- }
17
-
18
- export const TEMPLATES: TemplateOption[] = [
19
- { id: "blank", label: "Blank", hint: "Empty composition — just the scaffolding" },
20
- { id: "warm-grain", label: "Warm Grain", hint: "Cream aesthetic with grain texture" },
21
- { id: "play-mode", label: "Play Mode", hint: "Playful elastic animations" },
22
- { id: "swiss-grid", label: "Swiss Grid", hint: "Structured grid layout" },
23
- { id: "vignelli", label: "Vignelli", hint: "Bold typography with red accents" },
24
- { id: "decision-tree", label: "Decision Tree", hint: "Animated flowchart with branching paths" },
25
- { id: "kinetic-type", label: "Kinetic Type", hint: "Bold kinetic typography promo" },
26
- {
27
- id: "product-promo",
28
- label: "Product Promo",
29
- hint: "Multi-scene product showcase with SVG assets",
30
- },
31
- { id: "nyt-graph", label: "NYT Graph", hint: "Animated data chart in print editorial style" },
32
- ];