Setting the file. One moment. Template · Embedded Captions · heygen-com/hyperframes · Skills Docs14.43
Hershey Script Med
(opens in a new tab)
modes/cinematic/_archive/memory-wall/template.html
HTML·179 lines·5 KB
- {{ROTATE_Y}} {{ROTATE_X}} (perspective angle on the wall)
16 - --font-scale CSS var (multiplies all cap-N sizes — agent tunes for frame)
17 - GROUPS array (transcript groups, slot assignment 1/2/3/4, in/out/words)
18
19 Style typography is keyed to "slots", semantic positions in the arc:
20 cap-1: opener (italic, soft entry)
21 cap-2: continuation (smaller italic, hanging indent — ragged poem feel)
22 cap-3: pivot (upright, no italic, syntactic turn)
23 cap-4: climax (UPPERCASE 900, the payoff line)
24-->
25<html lang="en">
26 <head>
27 <meta charset="UTF-8" />
28 <meta name="viewport" content="width={{WIDTH}}, height={{HEIGHT}}" />
29 <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
30 <style>
31 :root { --font-scale: {{FONT_SCALE}}; }
32
33 * { margin: 0; padding: 0; box-sizing: border-box; }
34 html, body {
35 margin: 0;
36 width: {{WIDTH}}px; height: {{HEIGHT}}px;
37 overflow: hidden;
38 background: #000;
39 font-family: "Inter", system-ui, sans-serif;
40 }
41
42 #a-roll {
43 position: absolute; inset: 0;
44 width: 100%; height: 100%;
45 object-fit: cover;
46 }
47
48 #stage {
49 position: absolute;
50 top: 0; left: 0;
51 width: {{WIDTH}}px; height: {{HEIGHT}}px;
52 perspective: 1400px;
53 perspective-origin: 30% 40%;
54 pointer-events: none;
55 z-index: 2;
56 }
57
58 /* LAYOUT (agent-tunable via plan.json) */
59 .wall-plane {
60 position: absolute;
61 top: {{PLANE_TOP}}px;
62 right: {{PLANE_RIGHT}}px;
63 width: {{PLANE_WIDTH}}px;
64 height: {{PLANE_HEIGHT}}px;
65 transform-style: preserve-3d;
66 transform: rotateY({{ROTATE_Y}}deg) rotateX({{ROTATE_X}}deg);
67 transform-origin: right center;
68 padding: 24px 32px;
69 display: flex;
70 flex-direction: column;
71 justify-content: center;
72 align-items: flex-end;
73 text-align: right;
74 gap: 14px;
75 }
76
77 /* STYLE (locked) */
78 .cap {
79 display: block;
80 position: relative;
81 line-height: 1.05;
82 opacity: 0;
83 mix-blend-mode: {{BLEND_MODE}};
84 color: {{CAP_COLOR}};
85 text-shadow: {{TEXT_SHADOW}};
86 filter: {{TEXT_FILTER}};
87 will-change: transform, opacity;
88 }
89 .cap .w { display: inline-block; opacity: 0; will-change: opacity, transform; }
90
91 .cap-1 { font-size: calc(78px * var(--font-scale));
92 font-weight: 600; font-style: italic;
93 letter-spacing: -0.01em; }
94 .cap-2 { font-size: calc(66px * var(--font-scale));
95 font-weight: 500; font-style: italic;
96 letter-spacing: -0.005em;
97 padding-right: calc(44px * var(--font-scale)); }
98 .cap-3 { font-size: calc(72px * var(--font-scale));
99 font-weight: 700;
100 letter-spacing: -0.015em; }
101 .cap-4 { font-size: calc(90px * var(--font-scale));
102 font-weight: 900;
103 letter-spacing: -0.03em;
104 text-transform: uppercase;
105 line-height: 1.0; }
106 </style>
107 </head>
108 <body>
109 <div
110 id="root"
111 data-composition-id="main"
112 data-start="0"
113 data-duration="{{DURATION}}"
114 data-width="{{WIDTH}}"
115 data-height="{{HEIGHT}}"
116 >
117 <video
118 id="a-roll"
119 src="source.mp4"
120 muted
121 playsinline
122 data-duration="{{DURATION}}"
123 data-track-index="0"
124 style="z-index: 1"
125 ></video>
126
127 <div id="stage">
128 <div class="wall-plane">{{GROUPS_HTML}}</div>
129 </div>
130
131 <audio
132 id="a-roll-audio"
133 src="source.mp4"
134 data-start="0"
135 data-duration="{{DURATION}}"
136 data-track-index="3"
137 data-volume="1"
138 ></audio>
139 </div>
140
141 <script>
142 window.__timelines = window.__timelines || {};
143 const tl = gsap.timeline({ paused: true });
144 const DUR = {{DURATION}};
145 const GROUPS = {{GROUPS_JSON}};
146
147 GROUPS.forEach(function (g) {
148 var sel = "#" + g.id;
149 var isSoft = g.tone === "soft";
150 tl.set(sel, { opacity: 1, y: 0 }, Math.max(0, g.in - 0.01));
151
152 g.words.forEach(function (w, i) {
153 var wsel = sel + " .w[data-i='" + i + "']";
154 if (isSoft) {
155 tl.fromTo(wsel,
156 { opacity: 0, y: 8 },
157 { opacity: 1, y: 0, duration: 0.45, ease: "power2.out", overwrite: "auto" },
158 w.start);
159 } else {
160 tl.fromTo(wsel,
161 { opacity: 0, y: 6, scale: 1.04 },
162 { opacity: 1, y: 0, scale: 1.0, duration: 0.22,
163 ease: "power3.out", overwrite: "auto", transformOrigin: "100% 50%" },
164 w.start);
165 }
166 });
167
168 if (g.out < DUR) {
169 tl.to(sel, { opacity: 0, duration: 0.5, ease: "power2.in", overwrite: "auto" },
170 g.out - 0.5);
171 }
172 tl.set(sel, { opacity: 0, visibility: "hidden" }, g.out);
173 });
174
175 tl.seek(0);
176 window.__timelines["main"] = tl;
177 </script>
178 </body>
179</html>