hyperframes 0.1.15 → 0.2.0-alpha.1

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 +3968 -3297
  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,147 +0,0 @@
1
- <template id="captions-template">
2
- <div
3
- data-composition-id="captions"
4
- data-width="1920"
5
- data-height="1080"
6
- data-duration="__VIDEO_DURATION__"
7
- >
8
- <div class="captions-container">
9
- <div id="caption-box" class="caption-box">
10
- <span id="caption-text" class="caption-text"></span>
11
- </div>
12
- </div>
13
-
14
- <style>
15
- [data-composition-id="captions"] .captions-container {
16
- width: 100%;
17
- height: 100%;
18
- display: flex;
19
- justify-content: center;
20
- align-items: flex-end;
21
- padding-bottom: 230px; /* Position at y: 850 (1080 - 230 = 850) */
22
- pointer-events: none;
23
- }
24
-
25
- [data-composition-id="captions"] .caption-box {
26
- background-color: #7a6248;
27
- padding: 12px 32px;
28
- border-radius: 24px;
29
- display: flex;
30
- justify-content: center;
31
- align-items: center;
32
- min-width: 100px;
33
- max-width: 80%;
34
- opacity: 0;
35
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
36
- }
37
-
38
- [data-composition-id="captions"] .caption-text {
39
- color: #f5f0e0;
40
- font-family: "Outfit", sans-serif;
41
- font-size: 48px;
42
- font-weight: 700;
43
- text-align: center;
44
- line-height: 1.2;
45
- white-space: nowrap;
46
- }
47
- </style>
48
-
49
- <script>
50
- (function () {
51
- const script = [
52
- { text: "We", start: 0.119, end: 0.259 },
53
- { text: "asked", start: 0.319, end: 0.479 },
54
- { text: "what", start: 0.519, end: 0.659 },
55
- { text: "you", start: 0.699, end: 0.819 },
56
- { text: "needed.", start: 0.859, end: 1.819 },
57
- { text: "Forty-seven", start: 1.86, end: 2.299 },
58
- { text: "percent", start: 2.399, end: 2.679 },
59
- { text: "of", start: 2.7, end: 2.799 },
60
- { text: "you", start: 2.839, end: 2.939 },
61
- { text: "said", start: 3.039, end: 3.179 },
62
- { text: "motion", start: 3.24, end: 3.559 },
63
- { text: "graphics,", start: 3.579, end: 4.599 },
64
- { text: "sixty-two", start: 4.679, end: 5.179 },
65
- { text: "percent", start: 5.299, end: 5.759 },
66
- { text: "said", start: 5.859, end: 5.98 },
67
- { text: "static", start: 6.079, end: 6.399 },
68
- { text: "content", start: 6.46, end: 6.879 },
69
- { text: "was", start: 6.92, end: 7.079 },
70
- { text: "costing", start: 7.099, end: 7.48 },
71
- { text: "you", start: 7.5, end: 7.579 },
72
- { text: "attention,", start: 7.679, end: 8.659 },
73
- { text: "and", start: 8.699, end: 8.86 },
74
- { text: "three", start: 8.88, end: 9.06 },
75
- { text: "out", start: 9.079, end: 9.18 },
76
- { text: "of", start: 9.199, end: 9.34 },
77
- { text: "four", start: 9.38, end: 9.799 },
78
- { text: "said", start: 9.84, end: 10.0 },
79
- { text: "you", start: 10.019, end: 10.159 },
80
- { text: "know", start: 10.179, end: 10.36 },
81
- { text: "the", start: 10.38, end: 10.42 },
82
- { text: "look", start: 10.519, end: 10.699 },
83
- { text: "you", start: 10.739, end: 10.859 },
84
- { text: "want", start: 10.98, end: 11.34 },
85
- { text: "but", start: 11.359, end: 11.52 },
86
- { text: "don't", start: 11.56, end: 11.779 },
87
- { text: "have", start: 11.819, end: 11.94 },
88
- { text: "the", start: 11.96, end: 12.06 },
89
- { text: "editing", start: 12.079, end: 12.4 },
90
- { text: "skills", start: 12.52, end: 12.86 },
91
- { text: "to", start: 12.88, end: 13.0 },
92
- { text: "get", start: 13.019, end: 13.18 },
93
- { text: "there.", start: 13.22, end: 14.22 },
94
- { text: "So", start: 14.239, end: 14.399 },
95
- { text: "we", start: 14.42, end: 14.52 },
96
- { text: "built", start: 14.619, end: 14.88 },
97
- { text: "Hyperframes.", start: 15.079, end: 16.02 },
98
- ];
99
-
100
- // Group words into lines (max 5 words per line)
101
- const lines = [];
102
- for (let i = 0; i < script.length; i += 5) {
103
- const lineWords = script.slice(i, i + 5);
104
- lines.push({
105
- text: lineWords.map((w) => w.text).join(" "),
106
- start: lineWords[0].start,
107
- end: lineWords[lineWords.length - 1].end,
108
- });
109
- }
110
-
111
- const tl = gsap.timeline({ paused: true });
112
- const box = document.querySelector('[data-composition-id="captions"] #caption-box');
113
- const textEl = document.querySelector('[data-composition-id="captions"] #caption-text');
114
-
115
- lines.forEach((line, index) => {
116
- // Fade in and set text
117
- tl.to(
118
- box,
119
- {
120
- opacity: 1,
121
- duration: 0.1,
122
- ease: "power2.out",
123
- onStart: () => {
124
- textEl.textContent = line.text;
125
- },
126
- },
127
- line.start,
128
- );
129
-
130
- // Fade out at the end of the line
131
- tl.to(
132
- box,
133
- {
134
- opacity: 0,
135
- duration: 0.1,
136
- ease: "power2.in",
137
- },
138
- line.end,
139
- );
140
- });
141
-
142
- window.__timelines = window.__timelines || {};
143
- window.__timelines["captions"] = tl;
144
- })();
145
- </script>
146
- </div>
147
- </template>
@@ -1,164 +0,0 @@
1
- <template id="graphics-template">
2
- <div data-composition-id="graphics" data-width="1920" data-height="1080" data-duration="14">
3
- <!-- Moment 1: 47% Stat (1.8s - 4.5s) -->
4
- <div id="moment-1" class="moment circle-stat">
5
- <div class="stat-content">
6
- <div class="stat-text">47%</div>
7
- <div class="stat-desc">Need Motion Graphics</div>
8
- </div>
9
- </div>
10
-
11
- <!-- Moment 2: 62% Stat (4.6s - 8.6s) -->
12
- <div id="moment-2" class="moment pill-stat">
13
- <div class="stat-text">62%</div>
14
- </div>
15
-
16
- <!-- Moment 3: Editing Skills (8.8s - 14s) -->
17
- <div id="moment-3" class="moment rect-stat">
18
- <div class="icon-shape">
19
- <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
20
- <path
21
- d="M20,20 Q50,0 80,20 Q100,50 80,80 Q50,100 20,80 Q0,50 20,20"
22
- fill="currentColor"
23
- />
24
- </svg>
25
- </div>
26
- <div class="stat-text">Editing Skills</div>
27
- </div>
28
-
29
- <style>
30
- [data-composition-id="graphics"] {
31
- position: relative;
32
- width: 1920px;
33
- height: 1080px;
34
- font-family: "Outfit", sans-serif;
35
- color: white;
36
- overflow: hidden;
37
- }
38
-
39
- [data-composition-id="graphics"] .moment {
40
- position: absolute;
41
- display: flex;
42
- align-items: center;
43
- justify-content: center;
44
- opacity: 0;
45
- /* We'll use GSAP to handle the centering and drift */
46
- }
47
-
48
- /* Moment 1: Forest Green Circle */
49
- [data-composition-id="graphics"] #moment-1 {
50
- width: 500px;
51
- height: 500px;
52
- background-color: #3b5e3a;
53
- border-radius: 50%;
54
- left: 1400px;
55
- top: 540px;
56
- transform: translate(-50%, -50%);
57
- }
58
-
59
- [data-composition-id="graphics"] .stat-content {
60
- display: flex;
61
- flex-direction: column;
62
- align-items: center;
63
- text-align: center;
64
- }
65
-
66
- [data-composition-id="graphics"] .stat-desc {
67
- font-size: 36px;
68
- font-weight: 400;
69
- margin-top: 10px;
70
- max-width: 300px;
71
- line-height: 1.2;
72
- }
73
-
74
- /* Moment 2: Ochre Pill */
75
- [data-composition-id="graphics"] #moment-2 {
76
- width: 500px;
77
- height: 220px;
78
- background-color: #cc8832;
79
- border-radius: 110px;
80
- left: 960px;
81
- top: 200px;
82
- transform: translate(-50%, -50%);
83
- }
84
-
85
- /* Moment 3: Terracotta Rounded Rect */
86
- [data-composition-id="graphics"] #moment-3 {
87
- width: 550px;
88
- height: 180px;
89
- background-color: #c45d3e;
90
- border-radius: 40px;
91
- left: 400px;
92
- top: 540px;
93
- transform: translate(-50%, -50%);
94
- padding: 0 40px;
95
- justify-content: center;
96
- gap: 30px;
97
- }
98
-
99
- [data-composition-id="graphics"] .stat-text {
100
- font-size: 80px;
101
- font-weight: 700;
102
- letter-spacing: -2px;
103
- }
104
-
105
- [data-composition-id="graphics"] #moment-3 .stat-text {
106
- font-size: 54px;
107
- letter-spacing: -1px;
108
- }
109
-
110
- [data-composition-id="graphics"] .icon-shape {
111
- width: 80px;
112
- height: 80px;
113
- color: rgba(255, 255, 255, 0.9);
114
- }
115
-
116
- [data-composition-id="graphics"] .icon-shape svg {
117
- width: 100%;
118
- height: 100%;
119
- }
120
- </style>
121
-
122
- <script>
123
- (function () {
124
- const tl = gsap.timeline({ paused: true });
125
-
126
- // Moment 1: 1.8s - 4.5s
127
- // Gentle drift into place and settle
128
- tl.fromTo(
129
- "#moment-1",
130
- { opacity: 0, x: "+=40", y: "+=15", scale: 0.8 },
131
- { opacity: 1, x: 0, y: 0, scale: 1, duration: 1.2, ease: "back.out(1.7)" },
132
- 1.8,
133
- );
134
- // Hold until 4.5s, then fade out
135
- tl.to("#moment-1", { opacity: 0, scale: 0.8, duration: 0.3, ease: "power2.in" }, 4.2);
136
-
137
- // Moment 2: 4.6s - 8.6s
138
- // Gentle drift into place and settle
139
- tl.fromTo(
140
- "#moment-2",
141
- { opacity: 0, y: "-=40", x: "+=10", scale: 0.8 },
142
- { opacity: 1, y: 0, x: 0, scale: 1, duration: 1.2, ease: "back.out(1.7)" },
143
- 4.6,
144
- );
145
- // Hold until 8.6s, then fade out
146
- tl.to("#moment-2", { opacity: 0, scale: 0.8, duration: 0.3, ease: "power2.in" }, 8.3);
147
-
148
- // Moment 3: 8.8s - 14s
149
- // Gentle drift into place and settle
150
- tl.fromTo(
151
- "#moment-3",
152
- { opacity: 0, x: "-=40", y: "-=10", scale: 0.8 },
153
- { opacity: 1, x: 0, y: 0, scale: 1, duration: 1.2, ease: "back.out(1.7)" },
154
- 8.8,
155
- );
156
- // Hold until end (14s)
157
- tl.to("#moment-3", { opacity: 0, duration: 0.5, ease: "power2.in" }, 13.5);
158
-
159
- window.__timelines = window.__timelines || {};
160
- window.__timelines["graphics"] = tl;
161
- })();
162
- </script>
163
- </div>
164
- </template>
@@ -1,86 +0,0 @@
1
- <template id="intro-template">
2
- <div data-composition-id="intro" data-width="1920" data-height="1080" data-duration="3">
3
- <div class="container">
4
- <div class="title-card">
5
- <h1 class="title">Hyperframes</h1>
6
- <p class="subtitle">Design simplified.</p>
7
- </div>
8
- </div>
9
-
10
- <style>
11
- /* Import a rounded humanist sans-serif font */
12
- @import url("https://fonts.googleapis.com/css2?family=Outfit:wght@400;600&display=swap");
13
-
14
- [data-composition-id="intro"] .container {
15
- width: 100%;
16
- height: 100%;
17
- display: flex;
18
- justify-content: flex-start; /* Align to left for speaker card */
19
- align-items: center;
20
- padding-left: 5%;
21
- font-family: "Outfit", sans-serif;
22
- background: transparent;
23
- }
24
-
25
- [data-composition-id="intro"] .title-card {
26
- background-color: #3b5e3a; /* Forest Green for contrast */
27
- padding: 40px 60px;
28
- border-radius: 30px;
29
- box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
30
- text-align: left;
31
- opacity: 0;
32
- transform: translateX(-100%); /* Start off-screen left */
33
- }
34
-
35
- [data-composition-id="intro"] .title {
36
- font-size: 100px;
37
- font-weight: 600;
38
- color: #f5f0e0; /* Cream text on green card */
39
- margin: 0;
40
- line-height: 1.1;
41
- letter-spacing: -2px;
42
- }
43
-
44
- [data-composition-id="intro"] .subtitle {
45
- font-size: 50px;
46
- font-weight: 400;
47
- color: #cc8832; /* Ochre accent */
48
- margin: 10px 0 0 0;
49
- line-height: 1.2;
50
- }
51
- </style>
52
-
53
- <script>
54
- (function () {
55
- const tl = gsap.timeline({ paused: true });
56
-
57
- // Animation: Speaker card slides in from the left
58
- tl.to(
59
- '[data-composition-id="intro"] .title-card',
60
- {
61
- opacity: 1,
62
- x: 0,
63
- duration: 0.8,
64
- ease: "power2.out",
65
- },
66
- 0.2,
67
- );
68
-
69
- // Exit: Slide off left at 1.8s (synced with 47% graphic)
70
- tl.to(
71
- '[data-composition-id="intro"] .title-card',
72
- {
73
- x: "-120%",
74
- opacity: 0,
75
- duration: 0.6,
76
- ease: "power2.in",
77
- },
78
- 1.8,
79
- );
80
-
81
- window.__timelines = window.__timelines || {};
82
- window.__timelines["intro"] = tl;
83
- })();
84
- </script>
85
- </div>
86
- </template>
@@ -1,294 +0,0 @@
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>Warm Grain - Hyperframes</title>
7
- <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
8
- <style>
9
- body,
10
- html {
11
- margin: 0;
12
- padding: 0;
13
- width: 1920px;
14
- height: 1080px;
15
- overflow: hidden;
16
- background-color: #f5f0e0; /* Cream background */
17
- font-family: "Outfit", "Lexend", sans-serif;
18
- }
19
-
20
- #main-composition {
21
- position: relative;
22
- width: 1920px;
23
- height: 1080px;
24
- overflow: hidden;
25
- }
26
-
27
- /* Paper texture and Grain overlay */
28
- #grain-overlay-comp {
29
- position: absolute;
30
- top: 0;
31
- left: 0;
32
- width: 100%;
33
- height: 100%;
34
- pointer-events: none;
35
- z-index: 100;
36
- }
37
-
38
- /* Grain animation */
39
- @keyframes grain-noise {
40
- 0%,
41
- 100% {
42
- transform: translate(0, 0);
43
- }
44
- 10% {
45
- transform: translate(-5%, -5%);
46
- }
47
- 20% {
48
- transform: translate(-10%, 5%);
49
- }
50
- 30% {
51
- transform: translate(5%, -10%);
52
- }
53
- 40% {
54
- transform: translate(-5%, 15%);
55
- }
56
- 50% {
57
- transform: translate(-10%, 5%);
58
- }
59
- 60% {
60
- transform: translate(15%, 0);
61
- }
62
- 70% {
63
- transform: translate(0, 10%);
64
- }
65
- 80% {
66
- transform: translate(-15%, 0);
67
- }
68
- 90% {
69
- transform: translate(10%, 5%);
70
- }
71
- }
72
-
73
- .grain-texture {
74
- position: absolute;
75
- top: -50%;
76
- left: -50%;
77
- width: 200%;
78
- height: 200%;
79
- background: url("https://www.transparenttextures.com/patterns/natural-paper.png");
80
- opacity: 0.15;
81
- animation: grain-noise 0.5s steps(1) infinite;
82
- }
83
-
84
- #a-roll {
85
- position: absolute;
86
- border-radius: 16px;
87
- object-fit: cover;
88
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
89
- }
90
-
91
- .comp-layer {
92
- position: absolute;
93
- top: 0;
94
- left: 0;
95
- width: 100%;
96
- height: 100%;
97
- pointer-events: none;
98
- }
99
- </style>
100
- </head>
101
- <body>
102
- <div
103
- id="main-composition"
104
- data-composition-id="main-video"
105
- data-width="1920"
106
- data-height="1080"
107
- data-start="0"
108
- data-duration="__VIDEO_DURATION__"
109
- >
110
- <!-- Background Layer -->
111
- <div
112
- id="grain-overlay-comp"
113
- data-composition-id="grain-overlay"
114
- data-width="1920"
115
- data-height="1080"
116
- data-start="0"
117
- data-duration="__VIDEO_DURATION__"
118
- data-track-index="100"
119
- >
120
- <div class="grain-texture"></div>
121
- <script>
122
- const grainTl = gsap.timeline({ paused: true });
123
- window.__timelines = window.__timelines || {};
124
- window.__timelines["grain-overlay"] = grainTl;
125
- </script>
126
- </div>
127
-
128
- <!-- A-Roll Video (muted — audio is separate) -->
129
- <video
130
- id="a-roll"
131
- src="__VIDEO_SRC__"
132
- muted
133
- playsinline
134
- data-start="0"
135
- data-duration="__VIDEO_DURATION__"
136
- data-track-index="0"
137
- ></video>
138
- <audio
139
- id="a-roll-audio"
140
- src="__VIDEO_SRC__"
141
- data-start="0"
142
- data-duration="__VIDEO_DURATION__"
143
- data-track-index="5"
144
- data-volume="1"
145
- ></audio>
146
-
147
- <!-- Compositions -->
148
- <div
149
- id="intro-layer"
150
- class="comp-layer"
151
- data-composition-id="intro"
152
- data-composition-src="compositions/intro.html"
153
- data-start="0"
154
- data-duration="2.5"
155
- data-track-index="1"
156
- ></div>
157
-
158
- <div
159
- id="graphics-layer"
160
- class="comp-layer"
161
- data-composition-id="graphics"
162
- data-composition-src="compositions/graphics.html"
163
- data-start="0"
164
- data-duration="__VIDEO_DURATION__"
165
- data-track-index="2"
166
- ></div>
167
-
168
- <div
169
- id="captions-layer"
170
- class="comp-layer"
171
- data-composition-id="captions"
172
- data-composition-src="compositions/captions.html"
173
- data-start="0"
174
- data-duration="__VIDEO_DURATION__"
175
- data-track-index="3"
176
- ></div>
177
-
178
- <!-- SFX -->
179
- <audio
180
- id="sfx-swipe-1"
181
- src=""
182
- data-start="1.8"
183
- data-duration="1"
184
- data-track-index="4"
185
- ></audio>
186
- <audio
187
- id="sfx-swipe-2"
188
- src=""
189
- data-start="4.6"
190
- data-duration="1"
191
- data-track-index="4"
192
- ></audio>
193
- <audio
194
- id="sfx-swipe-3"
195
- src=""
196
- data-start="8.8"
197
- data-duration="1"
198
- data-track-index="4"
199
- ></audio>
200
-
201
- <script>
202
- const tl = gsap.timeline({ paused: true });
203
-
204
- // A-Roll Framing Strategy
205
- // 1. 0s-1.8s: Intro scale up from small (60%) to medium (80%) - Shifted right slightly to clear speaker card
206
- // 2. 1.8s-4.6s: Grid view / Shift Left (x: 600, scale: 70%) for 47% graphic
207
- // 3. 4.6s-8.8s: Shift Center-Bottom (y: 800, scale: 70%) for 62% graphic (top)
208
- // 4. 8.8s-14s: Shift Right (x: 1320, scale: 75%) for Editing Skills graphic (left)
209
- // 5. 14s-17s: Final Reveal (Center, scale: 100%)
210
-
211
- // Initial state
212
- gsap.set("#a-roll", {
213
- x: 1100,
214
- y: 540,
215
- xPercent: -50,
216
- yPercent: -50,
217
- width: 1920 * 0.6,
218
- height: 1080 * 0.6,
219
- });
220
-
221
- // 1. Intro Scale Up (0s - 1.8s)
222
- tl.to(
223
- "#a-roll",
224
- {
225
- x: 1200,
226
- width: 1920 * 0.8,
227
- height: 1080 * 0.8,
228
- duration: 1.8,
229
- ease: "power2.inOut",
230
- },
231
- 0,
232
- );
233
-
234
- // 2. Moment 1: 47% Graphic Trigger (1.8s) - Shift Left
235
- tl.to(
236
- "#a-roll",
237
- {
238
- x: 600,
239
- y: 540,
240
- width: 1920 * 0.7,
241
- height: 1080 * 0.7,
242
- duration: 0.5,
243
- ease: "power2.inOut",
244
- },
245
- 1.8,
246
- );
247
-
248
- // 3. Moment 2: 62% Graphic Trigger (4.6s) - Shift Center-Bottom
249
- tl.to(
250
- "#a-roll",
251
- {
252
- x: 960,
253
- y: 750,
254
- width: 1920 * 0.7,
255
- height: 1080 * 0.7,
256
- duration: 0.5,
257
- ease: "power2.inOut",
258
- },
259
- 4.6,
260
- );
261
-
262
- // 4. Moment 3: Editing Skills Trigger (8.8s) - Shift Right
263
- tl.to(
264
- "#a-roll",
265
- {
266
- x: 1320,
267
- y: 540,
268
- width: 1920 * 0.75,
269
- height: 1080 * 0.75,
270
- duration: 0.5,
271
- ease: "power2.inOut",
272
- },
273
- 8.8,
274
- );
275
-
276
- // 5. Final Reveal (14s - 17s)
277
- tl.to(
278
- "#a-roll",
279
- {
280
- x: 960,
281
- y: 540,
282
- width: 1920 * 1.0,
283
- height: 1080 * 1.0,
284
- duration: 1.0,
285
- ease: "power2.inOut",
286
- },
287
- 14,
288
- );
289
-
290
- window.__timelines["main-video"] = tl;
291
- </script>
292
- </div>
293
- </body>
294
- </html>