Setting the file. One moment. Champion · Embedded Captions · heygen-com/hyperframes · Skills Docs14.43
Hershey Script Med
(opens in a new tab)
references/example-renders/champion.html
HTML·371 lines·11 KB
>
7 <style>
8 * {
9 margin: 0;
10 padding: 0;
11 box-sizing: border-box;
12 }
13 html,
14 body {
15 margin: 0;
16 width: 1920px;
17 height: 1080px;
18 overflow: hidden;
19 background: #000;
20 font-family: "Inter", system-ui, sans-serif;
21 }
22
23 #a-roll {
24 position: absolute;
25 inset: 0;
26 width: 100%;
27 height: 100%;
28 object-fit: cover;
29 }
30
31 /*
32 This scene has no flat wall — subject is center with a busy
33 bookshelf backdrop. So instead of a wall-plane, we place a
34 HEADER band across the top of the frame with subtle perspective
35 (slight rotateX so it lies on the bookshelf rather than floats).
36 Screen-blend picks up the shelf's darker patches.
37 */
38 #stage {
39 position: absolute;
40 top: 0;
41 left: 0;
42 width: 1920px;
43 height: 1080px;
44 perspective: 2400px;
45 perspective-origin: 25% 50%;
46 pointer-events: none;
47 z-index: 2;
48 }
49
50 /*
51 Left-column layout: subject fills x=550-1200, so the bookshelf
52 at x=0-550 is the clean zone. Captions right-align there, with
53 a mild perspective that makes them lie on the shelf.
54 */
55 .left-plane {
56 position: absolute;
57 /* Upper-left region. Hands gesture widely below y≈460, so we
58 keep the plane above that line. Head sits to the right of
59 x≈600, so x=40-720 here is the clean bookshelf zone. */
60 top: 40px;
61 left: 40px;
62 width: 720px;
63 height: 420px;
64 transform-style: preserve-3d;
65 transform: rotateY(4deg);
66 transform-origin: left center;
67 padding: 24px 36px;
68 }
69
70 /* Each cap stacks at the same absolute position within the plane
71 so hidden captions don't reserve flex space. */
72 .left-plane .cap {
73 position: absolute;
74 top: 24px;
75 right: 36px;
76 max-width: 648px; /* plane 720 - padding 36×2 */
77 }
78
79 /* A single "crown" caption placed center-stage for the payoff
80 ("A WIMBLEDON CHAMPION") — deliberately crosses the head to
81 deliver the emphasis via cinematic occlusion. */
82 .crown-plane {
83 position: absolute;
84 top: 420px;
85 left: 0;
86 right: 0;
87 text-align: center;
88 pointer-events: none;
89 }
90
91 .cap {
92 display: block;
93 position: relative;
94 line-height: 1.02;
95 opacity: 0;
96 mix-blend-mode: screen;
97 color: #fff5df;
98 text-shadow:
99 0 0 18px rgba(255, 220, 170, 0.55),
100 0 3px 8px rgba(0, 0, 0, 0.85);
101 filter: brightness(1.12) contrast(1.08);
102 will-change: transform, opacity;
103 }
104
105 .cap .w {
106 display: inline-block;
107 opacity: 0;
108 will-change: opacity, transform;
109 }
110
111 /*
112 Story beats sized to emphasize meaning:
113 - intros / fillers = smaller italic
114 - key statement phrases = bigger upright
115 - emphasis phrases (incredible things) = largest bold
116 - crown (Wimbledon Champion) = huge, center-stage, behind subject
117 */
118 .cap-intro {
119 font-size: 52px;
120 font-weight: 500;
121 font-style: italic;
122 letter-spacing: -0.005em;
123 }
124 .cap-phrase {
125 font-size: 60px;
126 font-weight: 600;
127 font-style: normal;
128 letter-spacing: -0.015em;
129 }
130 .cap-emph {
131 font-size: 70px;
132 font-weight: 800;
133 font-style: normal;
134 letter-spacing: -0.025em;
135 }
136 .cap-dream {
137 font-size: 64px;
138 font-weight: 700;
139 font-style: italic;
140 letter-spacing: -0.015em;
141 }
142 .cap-crown {
143 font-size: 140px;
144 font-weight: 900;
145 font-style: normal;
146 letter-spacing: -0.035em;
147 text-transform: uppercase;
148 line-height: 1;
149 }
150 </style>
151 </head>
152 <body>
153 <div
154 id="root"
155 data-composition-id="main"
156 data-start="0"
157 data-duration="12.08"
158 data-width="1920"
159 data-height="1080"
160 >
161 <video
162 id="a-roll"
163 class="clip"
164 src="source.mp4"
165 muted
166 playsinline
167 data-duration="12.08"
168 data-track-index="0"
169 style="z-index: 1"
170 ></video>
171
172 <div id="stage">
173 <!-- Left column: G1-G5 live here, on the clean bookshelf -->
174 <div class="left-plane">
175 <div id="cg-0" class="cap cap-intro">
176 <span class="w" data-i="0">You</span>
177 <span class="w" data-i="1">know,</span>
178 <span class="w" data-i="2">for</span>
179 <span class="w" data-i="3">me</span>
180 </div>
181 <div id="cg-1" class="cap cap-phrase">
182 <span class="w" data-i="0">I've</span>
183 <span class="w" data-i="1">had</span>
184 <span class="w" data-i="2">this</span>
185 <span class="w" data-i="3">kind</span>
186 <span class="w" data-i="4">of</span>
187 <span class="w" data-i="5">upbringing</span>
188 </div>
189 <div id="cg-2" class="cap cap-phrase">
190 <span class="w" data-i="0">the</span>
191 <span class="w" data-i="1">great</span>
192 <span class="w" data-i="2">foundation</span>
193 </div>
194 <div id="cg-3" class="cap cap-emph">
195 <span class="w" data-i="0">I've</span>
196 <span class="w" data-i="1">achieved</span>
197 <span class="w" data-i="2">incredible</span>
198 <span class="w" data-i="3">things</span>
199 </div>
200 <div id="cg-4" class="cap cap-dream">
201 <span class="w" data-i="0">dreaming</span>
202 <span class="w" data-i="1">of</span>
203 <span class="w" data-i="2">becoming</span>
204 <span class="w" data-i="3">number</span>
205 <span class="w" data-i="4">one</span>
206 </div>
207 </div>
208 <!-- Center-stage crown: the payoff. Sits where the subject is,
209 matte layering makes it *behind* him — the occlusion is the moment. -->
210 <div class="crown-plane">
211 <div id="cg-5" class="cap cap-crown">
212 <span class="w" data-i="0">Wimbledon</span>
213 <span class="w" data-i="1">Champion</span>
214 </div>
215 </div>
216 </div>
217
218 <audio
219 id="a-roll-audio"
220 src="source.mp4"
221 data-start="0"
222 data-duration="12.08"
223 data-track-index="3"
224 data-volume="1"
225 ></audio>
226 </div>
227
228 <script>
229 window.__timelines = window.__timelines || {};
230 const tl = gsap.timeline({ paused: true });
231 const DUR = 12.08;
232
233 /* Word-level transcript — ElevenLabs scribe_v2 */
234 const GROUPS = [
235 {
236 id: "cg-0",
237 in: 0.1,
238 out: 1.45,
239 tone: "soft",
240 words: [
241 { text: "You", start: 0.18, end: 0.24 },
242 { text: "know", start: 0.28, end: 0.36 },
243 { text: "for", start: 0.46, end: 0.62 },
244 { text: "me", start: 0.66, end: 0.86 },
245 ],
246 },
247 {
248 id: "cg-1",
249 in: 1.4,
250 out: 3.35,
251 tone: "soft",
252 words: [
253 { text: "I've", start: 1.5, end: 1.68 },
254 { text: "had", start: 1.76, end: 1.94 },
255 { text: "this", start: 1.98, end: 2.14 },
256 { text: "kind", start: 2.2, end: 2.34 },
257 { text: "of", start: 2.36, end: 2.44 },
258 { text: "upbringing", start: 2.48, end: 3.06 },
259 ],
260 },
261 {
262 id: "cg-2",
263 in: 3.5,
264 out: 5.35,
265 tone: "soft",
266 words: [
267 { text: "the", start: 3.56, end: 3.64 },
268 { text: "great", start: 3.7, end: 3.9 },
269 { text: "foundation", start: 3.96, end: 4.6 },
270 ],
271 },
272 {
273 id: "cg-3",
274 in: 6.05,
275 out: 8.3,
276 tone: "present",
277 words: [
278 { text: "I've", start: 6.36, end: 6.5 },
279 { text: "achieved", start: 6.62, end: 7.08 },
280 { text: "incredible", start: 7.38, end: 7.86 },
281 { text: "things", start: 7.88, end: 8.16 },
282 ],
283 },
284 {
285 id: "cg-4",
286 in: 8.5,
287 out: 10.4,
288 tone: "present",
289 words: [
290 { text: "dreaming", start: 8.54, end: 8.84 },
291 { text: "of", start: 8.88, end: 9.0 },
292 { text: "becoming", start: 9.04, end: 9.4 },
293 { text: "number", start: 9.48, end: 9.64 },
294 { text: "one", start: 9.72, end: 9.8 },
295 ],
296 },
297 {
298 id: "cg-5",
299 in: 10.8,
300 out: 12.08,
301 tone: "present",
302 words: [
303 { text: "Wimbledon", start: 10.92, end: 11.28 },
304 { text: "Champion", start: 11.38, end: 11.84 },
305 ],
306 },
307 ];
308
309 GROUPS.forEach(function (g) {
310 var sel = "#" + g.id;
311 var words = g.words.map(function (_, i) {
312 return sel + " .w[data-i='" + i + "']";
313 });
314 var isSoft = g.tone === "soft";
315
316 /* Container visible just before entrance; single-layer fade is on words. */
317 tl.set(sel, { opacity: 1, y: 0 }, Math.max(0, g.in - 0.01));
318
319 g.words.forEach(function (w, i) {
320 if (isSoft) {
321 tl.fromTo(
322 words[i],
323 { opacity: 0, y: 8 },
324 { opacity: 1, y: 0, duration: 0.42, ease: "power2.out", overwrite: "auto" },
325 w.start,
326 );
327 } else {
328 tl.fromTo(
329 words[i],
330 { opacity: 0, y: 6, scale: 1.04 },
331 {
332 opacity: 1,
333 y: 0,
334 scale: 1.0,
335 duration: 0.22,
336 ease: "power3.out",
337 transformOrigin: "50% 50%",
338 overwrite: "auto",
339 },
340 w.start,
341 );
342 }
343 });
344
345 /* Group exit — each group fades out before the next enters. */
346 if (g.out < DUR) {
347 tl.to(
348 sel,
349 { opacity: 0, duration: 0.45, ease: "power2.in", overwrite: "auto" },
350 g.out - 0.45,
351 );
352 }
353 tl.set(sel, { opacity: 0, visibility: "hidden" }, g.out);
354 });
355
356 /* Self-lint */
357 GROUPS.forEach(function (g) {
358 var el = document.getElementById(g.id);
359 if (!el) return;
360 tl.seek(g.out + 0.01);
361 var cs = window.getComputedStyle(el);
362 if (cs.opacity !== "0" && cs.visibility !== "hidden") {
363 console.warn("[caption-lint] " + g.id + " visible at t=" + (g.out + 0.01).toFixed(2));
364 }
365 });
366 tl.seek(0);
367
368 window.__timelines["main"] = tl;
369 </script>
370 </body>
371</html>